[RS6000] rs6000_call_template for external call insn assembly output
[official-gcc.git] / gcc / config / rs6000 / rs6000.md
blobfd0ae58607049838820fcfe8732e601357a32a07
1 ;; Machine description for IBM RISC System 6000 (POWER) for GNU C compiler
2 ;; Copyright (C) 1990-2018 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    (FRAME_POINTER_REGNUM        111)
54    (TFHAR_REGNO                 112)
55    (TFIAR_REGNO                 113)
56    (TEXASR_REGNO                114)
57   ])
60 ;; UNSPEC usage
63 (define_c_enum "unspec"
64   [UNSPEC_FRSP                  ; frsp for POWER machines
65    UNSPEC_PROBE_STACK           ; probe stack memory reference
66    UNSPEC_TOCPTR                ; address of a word pointing to the TOC
67    UNSPEC_TOC                   ; address of the TOC (more-or-less)
68    UNSPEC_TOCSLOT               ; offset from r1 of toc pointer save slot
69    UNSPEC_MOVSI_GOT
70    UNSPEC_MV_CR_OV              ; move_from_CR_ov_bit
71    UNSPEC_FCTIWZ
72    UNSPEC_FRIM
73    UNSPEC_FRIN
74    UNSPEC_FRIP
75    UNSPEC_FRIZ
76    UNSPEC_XSRDPI
77    UNSPEC_LD_MPIC               ; load_macho_picbase
78    UNSPEC_RELD_MPIC             ; re-load_macho_picbase
79    UNSPEC_MPIC_CORRECT          ; macho_correct_pic
80    UNSPEC_TLSGD
81    UNSPEC_TLSLD
82    UNSPEC_MOVESI_FROM_CR
83    UNSPEC_MOVESI_TO_CR
84    UNSPEC_TLSDTPREL
85    UNSPEC_TLSDTPRELHA
86    UNSPEC_TLSDTPRELLO
87    UNSPEC_TLSGOTDTPREL
88    UNSPEC_TLSTPREL
89    UNSPEC_TLSTPRELHA
90    UNSPEC_TLSTPRELLO
91    UNSPEC_TLSGOTTPREL
92    UNSPEC_TLSTLS
93    UNSPEC_FIX_TRUNC_TF          ; fadd, rounding towards zero
94    UNSPEC_STFIWX
95    UNSPEC_POPCNTB
96    UNSPEC_FRES
97    UNSPEC_SP_SET
98    UNSPEC_SP_TEST
99    UNSPEC_SYNC
100    UNSPEC_LWSYNC
101    UNSPEC_SYNC_OP
102    UNSPEC_ATOMIC
103    UNSPEC_CMPXCHG
104    UNSPEC_XCHG
105    UNSPEC_AND
106    UNSPEC_DLMZB
107    UNSPEC_DLMZB_CR
108    UNSPEC_DLMZB_STRLEN
109    UNSPEC_RSQRT
110    UNSPEC_TOCREL
111    UNSPEC_MACHOPIC_OFFSET
112    UNSPEC_BPERM
113    UNSPEC_COPYSIGN
114    UNSPEC_PARITY
115    UNSPEC_CMPB
116    UNSPEC_FCTIW
117    UNSPEC_FCTID
118    UNSPEC_LFIWAX
119    UNSPEC_LFIWZX
120    UNSPEC_FCTIWUZ
121    UNSPEC_NOP
122    UNSPEC_GRP_END_NOP
123    UNSPEC_P8V_FMRGOW
124    UNSPEC_P8V_MTVSRWZ
125    UNSPEC_P8V_RELOAD_FROM_GPR
126    UNSPEC_P8V_MTVSRD
127    UNSPEC_P8V_XXPERMDI
128    UNSPEC_P8V_RELOAD_FROM_VSX
129    UNSPEC_ADDG6S
130    UNSPEC_CDTBCD
131    UNSPEC_CBCDTD
132    UNSPEC_DIVE
133    UNSPEC_DIVEU
134    UNSPEC_UNPACK_128BIT
135    UNSPEC_PACK_128BIT
136    UNSPEC_LSQ
137    UNSPEC_FUSION_GPR
138    UNSPEC_STACK_CHECK
139    UNSPEC_ADD_ROUND_TO_ODD
140    UNSPEC_SUB_ROUND_TO_ODD
141    UNSPEC_MUL_ROUND_TO_ODD
142    UNSPEC_DIV_ROUND_TO_ODD
143    UNSPEC_FMA_ROUND_TO_ODD
144    UNSPEC_SQRT_ROUND_TO_ODD
145    UNSPEC_TRUNC_ROUND_TO_ODD
146    UNSPEC_SIGNBIT
147    UNSPEC_SF_FROM_SI
148    UNSPEC_SI_FROM_SF
149   ])
152 ;; UNSPEC_VOLATILE usage
155 (define_c_enum "unspecv"
156   [UNSPECV_BLOCK
157    UNSPECV_LL                   ; load-locked
158    UNSPECV_SC                   ; store-conditional
159    UNSPECV_PROBE_STACK_RANGE    ; probe range of stack addresses
160    UNSPECV_EH_RR                ; eh_reg_restore
161    UNSPECV_ISYNC                ; isync instruction
162    UNSPECV_MFTB                 ; move from time base
163    UNSPECV_NLGR                 ; non-local goto receiver
164    UNSPECV_MFFS                 ; Move from FPSCR
165    UNSPECV_MFFSL                ; Move from FPSCR light instruction version
166    UNSPECV_MFFSCRN              ; Move from FPSCR float rounding mode
167    UNSPECV_MFFSCDRN             ; Move from FPSCR decimal float rounding mode
168    UNSPECV_MTFSF                ; Move to FPSCR Fields 8 to 15
169    UNSPECV_MTFSF_HI             ; Move to FPSCR Fields 0 to 7
170    UNSPECV_MTFSB0               ; Set FPSCR Field bit to 0
171    UNSPECV_MTFSB1               ; Set FPSCR Field bit to 1
172    UNSPECV_SPLIT_STACK_RETURN   ; A camouflaged return
173    UNSPECV_SPEC_BARRIER         ; Speculation barrier
174   ])
177 ;; Define an insn type attribute.  This is used in function unit delay
178 ;; computations.
179 (define_attr "type"
180   "integer,two,three,
181    add,logical,shift,insert,
182    mul,halfmul,div,
183    exts,cntlz,popcnt,isel,
184    load,store,fpload,fpstore,vecload,vecstore,
185    cmp,
186    branch,jmpreg,mfjmpr,mtjmpr,trap,isync,sync,load_l,store_c,
187    cr_logical,mfcr,mfcrf,mtcr,
188    fpcompare,fp,fpsimple,dmul,qmul,sdiv,ddiv,ssqrt,dsqrt,
189    vecsimple,veccomplex,vecdiv,veccmp,veccmpsimple,vecperm,
190    vecfloat,vecfdiv,vecdouble,mffgpr,mftgpr,crypto,
191    veclogical,veccmpfx,vecexts,vecmove,
192    htm,htmsimple,dfp"
193   (const_string "integer"))
195 ;; What data size does this instruction work on?
196 ;; This is used for insert, mul and others as necessary.
197 (define_attr "size" "8,16,32,64,128" (const_string "32"))
199 ;; What is the insn_cost for this insn?  The target hook can still override
200 ;; this.  For optimizing for size the "length" attribute is used instead.
201 (define_attr "cost" "" (const_int 0))
203 ;; Is this instruction record form ("dot", signed compare to 0, writing CR0)?
204 ;; This is used for add, logical, shift, exts, mul.
205 (define_attr "dot" "no,yes" (const_string "no"))
207 ;; Does this instruction sign-extend its result?
208 ;; This is used for load insns.
209 (define_attr "sign_extend" "no,yes" (const_string "no"))
211 ;; Does this cr_logical instruction have three operands?  That is, BT != BB.
212 (define_attr "cr_logical_3op" "no,yes" (const_string "no"))
214 ;; Does this instruction use indexed (that is, reg+reg) addressing?
215 ;; This is used for load and store insns.  If operand 0 or 1 is a MEM
216 ;; it is automatically set based on that.  If a load or store instruction
217 ;; has fewer than two operands it needs to set this attribute manually
218 ;; or the compiler will crash.
219 (define_attr "indexed" "no,yes"
220   (if_then_else (ior (match_operand 0 "indexed_address_mem")
221                      (match_operand 1 "indexed_address_mem"))
222                 (const_string "yes")
223                 (const_string "no")))
225 ;; Does this instruction use update addressing?
226 ;; This is used for load and store insns.  See the comments for "indexed".
227 (define_attr "update" "no,yes"
228   (if_then_else (ior (match_operand 0 "update_address_mem")
229                      (match_operand 1 "update_address_mem"))
230                 (const_string "yes")
231                 (const_string "no")))
233 ;; Is this instruction using operands[2] as shift amount, and can that be a
234 ;; register?
235 ;; This is used for shift insns.
236 (define_attr "maybe_var_shift" "no,yes" (const_string "no"))
238 ;; Is this instruction using a shift amount from a register?
239 ;; This is used for shift insns.
240 (define_attr "var_shift" "no,yes"
241   (if_then_else (and (eq_attr "type" "shift")
242                      (eq_attr "maybe_var_shift" "yes"))
243                 (if_then_else (match_operand 2 "gpc_reg_operand")
244                               (const_string "yes")
245                               (const_string "no"))
246                 (const_string "no")))
248 ;; Is copying of this instruction disallowed?
249 (define_attr "cannot_copy" "no,yes" (const_string "no"))
251 ;; Length of the instruction (in bytes).
252 (define_attr "length" "" (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 "(enum attr_cpu) rs6000_tune")))
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 "power9.md")
302 (include "cell.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 ; And again, for patterns that need two (potentially) different integer modes.
319 (define_mode_iterator GPR2 [SI (DI "TARGET_POWERPC64")])
321 ; Any supported integer mode.
322 (define_mode_iterator INT [QI HI SI DI TI PTI])
324 ; Any supported integer mode that fits in one register.
325 (define_mode_iterator INT1 [QI HI SI (DI "TARGET_POWERPC64")])
327 ; Integer modes supported in VSX registers with ISA 3.0 instructions
328 (define_mode_iterator INT_ISA3 [QI HI SI DI])
330 ; Everything we can extend QImode to.
331 (define_mode_iterator EXTQI [SI (DI "TARGET_POWERPC64")])
333 ; Everything we can extend HImode to.
334 (define_mode_iterator EXTHI [SI (DI "TARGET_POWERPC64")])
336 ; Everything we can extend SImode to.
337 (define_mode_iterator EXTSI [(DI "TARGET_POWERPC64")])
339 ; QImode or HImode for small integer moves and small atomic ops
340 (define_mode_iterator QHI [QI HI])
342 ; QImode, HImode, SImode for fused ops only for GPR loads
343 (define_mode_iterator QHSI [QI HI SI])
345 ; HImode or SImode for sign extended fusion ops
346 (define_mode_iterator HSI [HI SI])
348 ; SImode or DImode, even if DImode doesn't fit in GPRs.
349 (define_mode_iterator SDI [SI DI])
351 ; The size of a pointer.  Also, the size of the value that a record-condition
352 ; (one with a '.') will compare; and the size used for arithmetic carries.
353 (define_mode_iterator P [(SI "TARGET_32BIT") (DI "TARGET_64BIT")])
355 ; Iterator to add PTImode along with TImode (TImode can go in VSX registers,
356 ; PTImode is GPR only)
357 (define_mode_iterator TI2 [TI PTI])
359 ; Any hardware-supported floating-point mode
360 (define_mode_iterator FP [
361   (SF "TARGET_HARD_FLOAT")
362   (DF "TARGET_HARD_FLOAT")
363   (TF "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128")
364   (IF "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128")
365   (KF "TARGET_FLOAT128_TYPE")
366   (DD "TARGET_DFP")
367   (TD "TARGET_DFP")])
369 ; Any fma capable floating-point mode.
370 (define_mode_iterator FMA_F [
371   (SF "TARGET_HARD_FLOAT")
372   (DF "TARGET_HARD_FLOAT || VECTOR_UNIT_VSX_P (DFmode)")
373   (V4SF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)")
374   (V2DF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V2DFmode)")
375   (KF "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (KFmode)")
376   (TF "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (TFmode)")
377   ])
379 ; Floating point move iterators to combine binary and decimal moves
380 (define_mode_iterator FMOVE32 [SF SD])
381 (define_mode_iterator FMOVE64 [DF DD])
382 (define_mode_iterator FMOVE64X [DI DF DD])
383 (define_mode_iterator FMOVE128 [(TF "TARGET_LONG_DOUBLE_128")
384                                 (IF "FLOAT128_IBM_P (IFmode)")
385                                 (TD "TARGET_HARD_FLOAT")])
387 (define_mode_iterator FMOVE128_FPR [(TF "FLOAT128_2REG_P (TFmode)")
388                                     (IF "FLOAT128_2REG_P (IFmode)")
389                                     (TD "TARGET_HARD_FLOAT")])
391 ; Iterators for 128 bit types for direct move
392 (define_mode_iterator FMOVE128_GPR [TI
393                                     V16QI
394                                     V8HI
395                                     V4SI
396                                     V4SF
397                                     V2DI
398                                     V2DF
399                                     V1TI
400                                     (KF    "FLOAT128_VECTOR_P (KFmode)")
401                                     (TF    "FLOAT128_VECTOR_P (TFmode)")])
403 ; Iterator for 128-bit VSX types for pack/unpack
404 (define_mode_iterator FMOVE128_VSX [V1TI KF])
406 ; Iterators for converting to/from TFmode
407 (define_mode_iterator IFKF [IF KF])
409 ; Constraints for moving IF/KFmode.
410 (define_mode_attr IFKF_reg [(IF "d") (KF "wa")])
412 ; Whether a floating point move is ok, don't allow SD without hardware FP
413 (define_mode_attr fmove_ok [(SF "")
414                             (DF "")
415                             (SD "TARGET_HARD_FLOAT")
416                             (DD "")])
418 ; Convert REAL_VALUE to the appropriate bits
419 (define_mode_attr real_value_to_target [(SF "REAL_VALUE_TO_TARGET_SINGLE")
420                                         (DF "REAL_VALUE_TO_TARGET_DOUBLE")
421                                         (SD "REAL_VALUE_TO_TARGET_DECIMAL32")
422                                         (DD "REAL_VALUE_TO_TARGET_DECIMAL64")])
424 ; Whether 0.0 has an all-zero bit pattern
425 (define_mode_attr zero_fp [(SF "j")
426                            (DF "j")
427                            (TF "j")
428                            (IF "j")
429                            (KF "j")
430                            (SD "wn")
431                            (DD "wn")
432                            (TD "wn")])
434 ; Definitions for 64-bit VSX
435 (define_mode_attr f64_vsx [(DF "ws") (DD "wn")])
437 ; Definitions for 64-bit direct move
438 (define_mode_attr f64_dm  [(DF "wk") (DD "wh")])
440 ; Definitions for 64-bit use of altivec registers
441 (define_mode_attr f64_av  [(DF "wv") (DD "wn")])
443 ; Definitions for 64-bit access to ISA 3.0 (power9) vector
444 (define_mode_attr f64_p9  [(DF "wb") (DD "wn")])
446 ; These modes do not fit in integer registers in 32-bit mode.
447 (define_mode_iterator DIFD [DI DF DD])
449 ; Iterator for reciprocal estimate instructions
450 (define_mode_iterator RECIPF [SF DF V4SF V2DF])
452 ; Iterator for just SF/DF
453 (define_mode_iterator SFDF [SF DF])
455 ; Like SFDF, but a different name to match conditional move where the
456 ; comparison operands may be a different mode than the input operands.
457 (define_mode_iterator SFDF2 [SF DF])
459 ; Iterator for 128-bit floating point that uses the IBM double-double format
460 (define_mode_iterator IBM128 [(IF "FLOAT128_IBM_P (IFmode)")
461                               (TF "FLOAT128_IBM_P (TFmode)")])
463 ; Iterator for 128-bit floating point that uses IEEE 128-bit float
464 (define_mode_iterator IEEE128 [(KF "FLOAT128_IEEE_P (KFmode)")
465                                (TF "FLOAT128_IEEE_P (TFmode)")])
467 ; Iterator for 128-bit floating point
468 (define_mode_iterator FLOAT128 [(KF "TARGET_FLOAT128_TYPE")
469                                 (IF "TARGET_FLOAT128_TYPE")
470                                 (TF "TARGET_LONG_DOUBLE_128")])
472 ; Iterator for signbit on 64-bit machines with direct move
473 (define_mode_iterator SIGNBIT [(KF "FLOAT128_VECTOR_P (KFmode)")
474                                (TF "FLOAT128_VECTOR_P (TFmode)")])
476 ; Iterator for ISA 3.0 supported floating point types
477 (define_mode_iterator FP_ISA3 [SF DF])
479 ; SF/DF suffix for traditional floating instructions
480 (define_mode_attr Ftrad         [(SF "s") (DF "")])
482 ; SF/DF suffix for VSX instructions
483 (define_mode_attr Fvsx          [(SF "sp") (DF  "dp")])
485 ; SF/DF constraint for arithmetic on traditional floating point registers
486 (define_mode_attr Ff            [(SF "f") (DF "d") (DI "d")])
488 ; SF/DF constraint for arithmetic on VSX registers using instructions added in
489 ; ISA 2.06 (power7).  This includes instructions that normally target DF mode,
490 ; but are used on SFmode, since internally SFmode values are kept in the DFmode
491 ; format.
492 (define_mode_attr Fv            [(SF "ww") (DF "ws") (DI "wi")])
494 ; SF/DF constraint for arithmetic on VSX registers.  This is intended to be
495 ; used for DFmode instructions added in ISA 2.06 (power7) and SFmode
496 ; instructions added in ISA 2.07 (power8)
497 (define_mode_attr Fv2           [(SF "wy") (DF "ws") (DI "wi")])
499 ; SF/DF constraint for arithmetic on altivec registers
500 (define_mode_attr Fa            [(SF "wu") (DF "wv")])
502 ; s/d suffix for things like sdiv/ddiv
503 (define_mode_attr Fs            [(SF "s")  (DF "d")])
505 ; FRE/FRES support
506 (define_mode_attr Ffre          [(SF "fres") (DF "fre")])
507 (define_mode_attr FFRE          [(SF "FRES") (DF "FRE")])
509 ; Conditional returns.
510 (define_code_iterator any_return [return simple_return])
511 (define_code_attr return_pred [(return "direct_return ()")
512                                (simple_return "1")])
513 (define_code_attr return_str [(return "") (simple_return "simple_")])
515 ; Logical operators.
516 (define_code_iterator iorxor            [ior xor])
517 (define_code_iterator and_ior_xor       [and ior xor])
519 ; Signed/unsigned variants of ops.
520 (define_code_iterator any_extend        [sign_extend zero_extend])
521 (define_code_iterator any_fix           [fix unsigned_fix])
522 (define_code_iterator any_float         [float unsigned_float])
524 (define_code_attr u  [(sign_extend      "")
525                       (zero_extend      "u")
526                       (fix              "")
527                       (unsigned_fix     "u")])
529 (define_code_attr su [(sign_extend      "s")
530                       (zero_extend      "u")
531                       (fix              "s")
532                       (unsigned_fix     "u")
533                       (float            "s")
534                       (unsigned_float   "u")])
536 (define_code_attr az [(sign_extend      "a")
537                       (zero_extend      "z")
538                       (fix              "a")
539                       (unsigned_fix     "z")
540                       (float            "a")
541                       (unsigned_float   "z")])
543 (define_code_attr uns [(fix             "")
544                        (unsigned_fix    "uns")
545                        (float           "")
546                        (unsigned_float  "uns")])
548 ; Various instructions that come in SI and DI forms.
549 ; A generic w/d attribute, for things like cmpw/cmpd.
550 (define_mode_attr wd [(QI    "b")
551                       (HI    "h")
552                       (SI    "w")
553                       (DI    "d")
554                       (V16QI "b")
555                       (V8HI  "h")
556                       (V4SI  "w")
557                       (V2DI  "d")
558                       (V1TI  "q")
559                       (TI    "q")])
561 ;; How many bits in this mode?
562 (define_mode_attr bits [(QI "8") (HI "16") (SI "32") (DI "64")])
564 ; DImode bits
565 (define_mode_attr dbits [(QI "56") (HI "48") (SI "32")])
567 ;; Bitmask for shift instructions
568 (define_mode_attr hH [(SI "h") (DI "H")])
570 ;; A mode twice the size of the given mode
571 (define_mode_attr dmode [(SI "di") (DI "ti")])
572 (define_mode_attr DMODE [(SI "DI") (DI "TI")])
574 ;; Suffix for reload patterns
575 (define_mode_attr ptrsize [(SI "32bit")
576                            (DI "64bit")])
578 (define_mode_attr tptrsize [(SI "TARGET_32BIT")
579                             (DI "TARGET_64BIT")])
581 (define_mode_attr mptrsize [(SI "si")
582                             (DI "di")])
584 (define_mode_attr ptrload [(SI "lwz")
585                            (DI "ld")])
587 (define_mode_attr ptrm [(SI "m")
588                         (DI "Y")])
590 (define_mode_attr rreg [(SF   "f")
591                         (DF   "ws")
592                         (TF   "f")
593                         (TD   "f")
594                         (V4SF "wf")
595                         (V2DF "wd")])
597 (define_mode_attr rreg2 [(SF   "f")
598                          (DF   "d")])
600 (define_mode_attr SI_CONVERT_FP [(SF "TARGET_FCFIDS")
601                                  (DF "TARGET_FCFID")])
603 ;; Mode iterator for logical operations on 128-bit types
604 (define_mode_iterator BOOL_128          [TI
605                                          PTI
606                                          (V16QI "TARGET_ALTIVEC")
607                                          (V8HI  "TARGET_ALTIVEC")
608                                          (V4SI  "TARGET_ALTIVEC")
609                                          (V4SF  "TARGET_ALTIVEC")
610                                          (V2DI  "TARGET_ALTIVEC")
611                                          (V2DF  "TARGET_ALTIVEC")
612                                          (V1TI  "TARGET_ALTIVEC")])
614 ;; For the GPRs we use 3 constraints for register outputs, two that are the
615 ;; same as the output register, and a third where the output register is an
616 ;; early clobber, so we don't have to deal with register overlaps.  For the
617 ;; vector types, we prefer to use the vector registers.  For TI mode, allow
618 ;; either.
620 ;; Mode attribute for boolean operation register constraints for output
621 (define_mode_attr BOOL_REGS_OUTPUT      [(TI    "&r,r,r,wt,v")
622                                          (PTI   "&r,r,r")
623                                          (V16QI "wa,v,&?r,?r,?r")
624                                          (V8HI  "wa,v,&?r,?r,?r")
625                                          (V4SI  "wa,v,&?r,?r,?r")
626                                          (V4SF  "wa,v,&?r,?r,?r")
627                                          (V2DI  "wa,v,&?r,?r,?r")
628                                          (V2DF  "wa,v,&?r,?r,?r")
629                                          (V1TI  "wa,v,&?r,?r,?r")])
631 ;; Mode attribute for boolean operation register constraints for operand1
632 (define_mode_attr BOOL_REGS_OP1         [(TI    "r,0,r,wt,v")
633                                          (PTI   "r,0,r")
634                                          (V16QI "wa,v,r,0,r")
635                                          (V8HI  "wa,v,r,0,r")
636                                          (V4SI  "wa,v,r,0,r")
637                                          (V4SF  "wa,v,r,0,r")
638                                          (V2DI  "wa,v,r,0,r")
639                                          (V2DF  "wa,v,r,0,r")
640                                          (V1TI  "wa,v,r,0,r")])
642 ;; Mode attribute for boolean operation register constraints for operand2
643 (define_mode_attr BOOL_REGS_OP2         [(TI    "r,r,0,wt,v")
644                                          (PTI   "r,r,0")
645                                          (V16QI "wa,v,r,r,0")
646                                          (V8HI  "wa,v,r,r,0")
647                                          (V4SI  "wa,v,r,r,0")
648                                          (V4SF  "wa,v,r,r,0")
649                                          (V2DI  "wa,v,r,r,0")
650                                          (V2DF  "wa,v,r,r,0")
651                                          (V1TI  "wa,v,r,r,0")])
653 ;; Mode attribute for boolean operation register constraints for operand1
654 ;; for one_cmpl.  To simplify things, we repeat the constraint where 0
655 ;; is used for operand1 or operand2
656 (define_mode_attr BOOL_REGS_UNARY       [(TI    "r,0,0,wt,v")
657                                          (PTI   "r,0,0")
658                                          (V16QI "wa,v,r,0,0")
659                                          (V8HI  "wa,v,r,0,0")
660                                          (V4SI  "wa,v,r,0,0")
661                                          (V4SF  "wa,v,r,0,0")
662                                          (V2DI  "wa,v,r,0,0")
663                                          (V2DF  "wa,v,r,0,0")
664                                          (V1TI  "wa,v,r,0,0")])
666 ;; Reload iterator for creating the function to allocate a base register to
667 ;; supplement addressing modes.
668 (define_mode_iterator RELOAD [V16QI V8HI V4SI V2DI V4SF V2DF V1TI
669                               SF SD SI DF DD DI TI PTI KF IF TF])
671 ;; Iterate over smin, smax
672 (define_code_iterator fp_minmax [smin smax])
674 (define_code_attr     minmax    [(smin "min")
675                                  (smax "max")])
677 (define_code_attr     SMINMAX   [(smin "SMIN")
678                                  (smax "SMAX")])
680 ;; Iterator to optimize the following cases:
681 ;;      D-form load to FPR register & move to Altivec register
682 ;;      Move Altivec register to FPR register and store
683 (define_mode_iterator ALTIVEC_DFORM [DF
684                                      (SF "TARGET_P8_VECTOR")
685                                      (DI "TARGET_POWERPC64")])
688 ;; Start with fixed-point load and store insns.  Here we put only the more
689 ;; complex forms.  Basic data transfer is done later.
691 (define_insn "zero_extendqi<mode>2"
692   [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r,^wJwK,^wK")
693         (zero_extend:EXTQI (match_operand:QI 1 "reg_or_mem_operand" "m,r,Z,wK")))]
694   ""
695   "@
696    lbz%U1%X1 %0,%1
697    rlwinm %0,%1,0,0xff
698    lxsibzx %x0,%y1
699    vextractub %0,%1,7"
700   [(set_attr "type" "load,shift,fpload,vecperm")])
702 (define_insn_and_split "*zero_extendqi<mode>2_dot"
703   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
704         (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
705                     (const_int 0)))
706    (clobber (match_scratch:EXTQI 0 "=r,r"))]
707   ""
708   "@
709    andi. %0,%1,0xff
710    #"
711   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
712   [(set (match_dup 0)
713         (zero_extend:EXTQI (match_dup 1)))
714    (set (match_dup 2)
715         (compare:CC (match_dup 0)
716                     (const_int 0)))]
717   ""
718   [(set_attr "type" "logical")
719    (set_attr "dot" "yes")
720    (set_attr "length" "4,8")])
722 (define_insn_and_split "*zero_extendqi<mode>2_dot2"
723   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
724         (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
725                     (const_int 0)))
726    (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
727         (zero_extend:EXTQI (match_dup 1)))]
728   ""
729   "@
730    andi. %0,%1,0xff
731    #"
732   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
733   [(set (match_dup 0)
734         (zero_extend:EXTQI (match_dup 1)))
735    (set (match_dup 2)
736         (compare:CC (match_dup 0)
737                     (const_int 0)))]
738   ""
739   [(set_attr "type" "logical")
740    (set_attr "dot" "yes")
741    (set_attr "length" "4,8")])
744 (define_insn "zero_extendhi<mode>2"
745   [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r,^wJwK,^wK")
746         (zero_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r,Z,wK")))]
747   ""
748   "@
749    lhz%U1%X1 %0,%1
750    rlwinm %0,%1,0,0xffff
751    lxsihzx %x0,%y1
752    vextractuh %0,%1,6"
753   [(set_attr "type" "load,shift,fpload,vecperm")])
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   ""
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   ""
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,wz,wu,wj,r,wJwK")
799         (zero_extend:EXTSI (match_operand:SI 1 "reg_or_mem_operand" "m,r,Z,Z,r,wIwH,wJwK")))]
800   ""
801   "@
802    lwz%U1%X1 %0,%1
803    rldicl %0,%1,0,32
804    lfiwzx %0,%y1
805    lxsiwzx %x0,%y1
806    mtvsrwz %x0,%1
807    mfvsrwz %0,%x1
808    xxextractuw %x0,%x1,4"
809   [(set_attr "type" "load,shift,fpload,fpload,mffgpr,mftgpr,vecexts")])
811 (define_insn_and_split "*zero_extendsi<mode>2_dot"
812   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
813         (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
814                     (const_int 0)))
815    (clobber (match_scratch:EXTSI 0 "=r,r"))]
816   ""
817   "@
818    rldicl. %0,%1,0,32
819    #"
820   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
821   [(set (match_dup 0)
822         (zero_extend:DI (match_dup 1)))
823    (set (match_dup 2)
824         (compare:CC (match_dup 0)
825                     (const_int 0)))]
826   ""
827   [(set_attr "type" "shift")
828    (set_attr "dot" "yes")
829    (set_attr "length" "4,8")])
831 (define_insn_and_split "*zero_extendsi<mode>2_dot2"
832   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
833         (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
834                     (const_int 0)))
835    (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
836         (zero_extend:EXTSI (match_dup 1)))]
837   ""
838   "@
839    rldicl. %0,%1,0,32
840    #"
841   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
842   [(set (match_dup 0)
843         (zero_extend:EXTSI (match_dup 1)))
844    (set (match_dup 2)
845         (compare:CC (match_dup 0)
846                     (const_int 0)))]
847   ""
848   [(set_attr "type" "shift")
849    (set_attr "dot" "yes")
850    (set_attr "length" "4,8")])
853 (define_insn "extendqi<mode>2"
854   [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,?*wK")
855         (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,?*wK")))]
856   ""
857   "@
858    extsb %0,%1
859    vextsb2d %0,%1"
860   [(set_attr "type" "exts,vecperm")])
862 (define_insn_and_split "*extendqi<mode>2_dot"
863   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
864         (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
865                     (const_int 0)))
866    (clobber (match_scratch:EXTQI 0 "=r,r"))]
867   ""
868   "@
869    extsb. %0,%1
870    #"
871   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
872   [(set (match_dup 0)
873         (sign_extend:EXTQI (match_dup 1)))
874    (set (match_dup 2)
875         (compare:CC (match_dup 0)
876                     (const_int 0)))]
877   ""
878   [(set_attr "type" "exts")
879    (set_attr "dot" "yes")
880    (set_attr "length" "4,8")])
882 (define_insn_and_split "*extendqi<mode>2_dot2"
883   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
884         (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
885                     (const_int 0)))
886    (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
887         (sign_extend:EXTQI (match_dup 1)))]
888   ""
889   "@
890    extsb. %0,%1
891    #"
892   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
893   [(set (match_dup 0)
894         (sign_extend:EXTQI (match_dup 1)))
895    (set (match_dup 2)
896         (compare:CC (match_dup 0)
897                     (const_int 0)))]
898   ""
899   [(set_attr "type" "exts")
900    (set_attr "dot" "yes")
901    (set_attr "length" "4,8")])
904 (define_expand "extendhi<mode>2"
905   [(set (match_operand:EXTHI 0 "gpc_reg_operand")
906         (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand")))]
907   ""
908   "")
910 (define_insn "*extendhi<mode>2"
911   [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r,?*wK,?*wK")
912         (sign_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r,Z,wK")))]
913   ""
914   "@
915    lha%U1%X1 %0,%1
916    extsh %0,%1
917    #
918    vextsh2d %0,%1"
919   [(set_attr "type" "load,exts,fpload,vecperm")
920    (set_attr "sign_extend" "yes")
921    (set_attr "length" "4,4,8,4")])
923 (define_split
924   [(set (match_operand:EXTHI 0 "altivec_register_operand")
925         (sign_extend:EXTHI
926          (match_operand:HI 1 "indexed_or_indirect_operand")))]
927   "TARGET_P9_VECTOR && reload_completed"
928   [(set (match_dup 2)
929         (match_dup 1))
930    (set (match_dup 0)
931         (sign_extend:EXTHI (match_dup 2)))]
933   operands[2] = gen_rtx_REG (HImode, REGNO (operands[0]));
936 (define_insn_and_split "*extendhi<mode>2_dot"
937   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
938         (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
939                     (const_int 0)))
940    (clobber (match_scratch:EXTHI 0 "=r,r"))]
941   ""
942   "@
943    extsh. %0,%1
944    #"
945   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
946   [(set (match_dup 0)
947         (sign_extend:EXTHI (match_dup 1)))
948    (set (match_dup 2)
949         (compare:CC (match_dup 0)
950                     (const_int 0)))]
951   ""
952   [(set_attr "type" "exts")
953    (set_attr "dot" "yes")
954    (set_attr "length" "4,8")])
956 (define_insn_and_split "*extendhi<mode>2_dot2"
957   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
958         (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
959                     (const_int 0)))
960    (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
961         (sign_extend:EXTHI (match_dup 1)))]
962   ""
963   "@
964    extsh. %0,%1
965    #"
966   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
967   [(set (match_dup 0)
968         (sign_extend:EXTHI (match_dup 1)))
969    (set (match_dup 2)
970         (compare:CC (match_dup 0)
971                     (const_int 0)))]
972   ""
973   [(set_attr "type" "exts")
974    (set_attr "dot" "yes")
975    (set_attr "length" "4,8")])
978 (define_insn "extendsi<mode>2"
979   [(set (match_operand:EXTSI 0 "gpc_reg_operand"
980                      "=r, r,   wl,    wu,    wj,    wK,     wH,    wr")
982         (sign_extend:EXTSI (match_operand:SI 1 "lwa_operand"
983                      "YZ, r,   Z,     Z,     r,     wK,     wH,    ?wIwH")))]
984   ""
985   "@
986    lwa%U1%X1 %0,%1
987    extsw %0,%1
988    lfiwax %0,%y1
989    lxsiwax %x0,%y1
990    mtvsrwa %x0,%1
991    vextsw2d %0,%1
992    #
993    #"
994   [(set_attr "type" "load,exts,fpload,fpload,mffgpr,vecexts,vecperm,mftgpr")
995    (set_attr "sign_extend" "yes")
996    (set_attr "length" "4,4,4,4,4,4,8,8")])
998 (define_split
999   [(set (match_operand:EXTSI 0 "int_reg_operand")
1000         (sign_extend:EXTSI (match_operand:SI 1 "vsx_register_operand")))]
1001   "TARGET_DIRECT_MOVE_64BIT && reload_completed"
1002   [(set (match_dup 2)
1003         (match_dup 1))
1004    (set (match_dup 0)
1005         (sign_extend:DI (match_dup 2)))]
1007   operands[2] = gen_rtx_REG (SImode, reg_or_subregno (operands[0]));
1010 (define_split
1011   [(set (match_operand:DI 0 "altivec_register_operand")
1012         (sign_extend:DI (match_operand:SI 1 "altivec_register_operand")))]
1013   "TARGET_P8_VECTOR && !TARGET_P9_VECTOR && reload_completed"
1014   [(const_int 0)]
1016   rtx dest = operands[0];
1017   rtx src = operands[1];
1018   int dest_regno = REGNO (dest);
1019   int src_regno = REGNO (src);
1020   rtx dest_v2di = gen_rtx_REG (V2DImode, dest_regno);
1021   rtx src_v4si = gen_rtx_REG (V4SImode, src_regno);
1023   if (BYTES_BIG_ENDIAN)
1024     {
1025       emit_insn (gen_altivec_vupkhsw (dest_v2di, src_v4si));
1026       emit_insn (gen_vsx_xxspltd_v2di (dest_v2di, dest_v2di, const1_rtx));
1027     }
1028   else
1029     {
1030       emit_insn (gen_altivec_vupklsw (dest_v2di, src_v4si));
1031       emit_insn (gen_vsx_xxspltd_v2di (dest_v2di, dest_v2di, const0_rtx));
1032     }
1033   DONE;
1036 (define_insn_and_split "*extendsi<mode>2_dot"
1037   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1038         (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
1039                     (const_int 0)))
1040    (clobber (match_scratch:EXTSI 0 "=r,r"))]
1041   ""
1042   "@
1043    extsw. %0,%1
1044    #"
1045   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1046   [(set (match_dup 0)
1047         (sign_extend:EXTSI (match_dup 1)))
1048    (set (match_dup 2)
1049         (compare:CC (match_dup 0)
1050                     (const_int 0)))]
1051   ""
1052   [(set_attr "type" "exts")
1053    (set_attr "dot" "yes")
1054    (set_attr "length" "4,8")])
1056 (define_insn_and_split "*extendsi<mode>2_dot2"
1057   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1058         (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
1059                     (const_int 0)))
1060    (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
1061         (sign_extend:EXTSI (match_dup 1)))]
1062   ""
1063   "@
1064    extsw. %0,%1
1065    #"
1066   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1067   [(set (match_dup 0)
1068         (sign_extend:EXTSI (match_dup 1)))
1069    (set (match_dup 2)
1070         (compare:CC (match_dup 0)
1071                     (const_int 0)))]
1072   ""
1073   [(set_attr "type" "exts")
1074    (set_attr "dot" "yes")
1075    (set_attr "length" "4,8")])
1077 ;; IBM 405, 440, 464 and 476 half-word multiplication operations.
1079 (define_insn "*macchwc"
1080   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1081         (compare:CC (plus:SI (mult:SI (ashiftrt:SI
1082                                        (match_operand:SI 2 "gpc_reg_operand" "r")
1083                                        (const_int 16))
1084                                       (sign_extend:SI
1085                                        (match_operand:HI 1 "gpc_reg_operand" "r")))
1086                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1087                     (const_int 0)))
1088    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1089         (plus:SI (mult:SI (ashiftrt:SI
1090                            (match_dup 2)
1091                            (const_int 16))
1092                           (sign_extend:SI
1093                            (match_dup 1)))
1094                  (match_dup 4)))]
1095   "TARGET_MULHW"
1096   "macchw. %0,%1,%2"
1097   [(set_attr "type" "halfmul")])
1099 (define_insn "*macchw"
1100   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1101         (plus:SI (mult:SI (ashiftrt:SI
1102                            (match_operand:SI 2 "gpc_reg_operand" "r")
1103                            (const_int 16))
1104                           (sign_extend:SI
1105                            (match_operand:HI 1 "gpc_reg_operand" "r")))
1106                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1107   "TARGET_MULHW"
1108   "macchw %0,%1,%2"
1109   [(set_attr "type" "halfmul")])
1111 (define_insn "*macchwuc"
1112   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1113         (compare:CC (plus:SI (mult:SI (lshiftrt:SI
1114                                        (match_operand:SI 2 "gpc_reg_operand" "r")
1115                                        (const_int 16))
1116                                       (zero_extend:SI
1117                                        (match_operand:HI 1 "gpc_reg_operand" "r")))
1118                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1119                     (const_int 0)))
1120    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1121         (plus:SI (mult:SI (lshiftrt:SI
1122                            (match_dup 2)
1123                            (const_int 16))
1124                           (zero_extend:SI
1125                            (match_dup 1)))
1126                  (match_dup 4)))]
1127   "TARGET_MULHW"
1128   "macchwu. %0,%1,%2"
1129   [(set_attr "type" "halfmul")])
1131 (define_insn "*macchwu"
1132   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1133         (plus:SI (mult:SI (lshiftrt:SI
1134                            (match_operand:SI 2 "gpc_reg_operand" "r")
1135                            (const_int 16))
1136                           (zero_extend:SI
1137                            (match_operand:HI 1 "gpc_reg_operand" "r")))
1138                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1139   "TARGET_MULHW"
1140   "macchwu %0,%1,%2"
1141   [(set_attr "type" "halfmul")])
1143 (define_insn "*machhwc"
1144   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1145         (compare:CC (plus:SI (mult:SI (ashiftrt:SI
1146                                        (match_operand:SI 1 "gpc_reg_operand" "%r")
1147                                        (const_int 16))
1148                                       (ashiftrt:SI
1149                                        (match_operand:SI 2 "gpc_reg_operand" "r")
1150                                        (const_int 16)))
1151                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1152                     (const_int 0)))
1153    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1154         (plus:SI (mult:SI (ashiftrt:SI
1155                            (match_dup 1)
1156                            (const_int 16))
1157                           (ashiftrt:SI
1158                            (match_dup 2)
1159                            (const_int 16)))
1160                  (match_dup 4)))]
1161   "TARGET_MULHW"
1162   "machhw. %0,%1,%2"
1163   [(set_attr "type" "halfmul")])
1165 (define_insn "*machhw"
1166   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1167         (plus:SI (mult:SI (ashiftrt:SI
1168                            (match_operand:SI 1 "gpc_reg_operand" "%r")
1169                            (const_int 16))
1170                           (ashiftrt:SI
1171                            (match_operand:SI 2 "gpc_reg_operand" "r")
1172                            (const_int 16)))
1173                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1174   "TARGET_MULHW"
1175   "machhw %0,%1,%2"
1176   [(set_attr "type" "halfmul")])
1178 (define_insn "*machhwuc"
1179   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1180         (compare:CC (plus:SI (mult:SI (lshiftrt:SI
1181                                        (match_operand:SI 1 "gpc_reg_operand" "%r")
1182                                        (const_int 16))
1183                                       (lshiftrt:SI
1184                                        (match_operand:SI 2 "gpc_reg_operand" "r")
1185                                        (const_int 16)))
1186                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1187                     (const_int 0)))
1188    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1189         (plus:SI (mult:SI (lshiftrt:SI
1190                            (match_dup 1)
1191                            (const_int 16))
1192                           (lshiftrt:SI
1193                            (match_dup 2)
1194                            (const_int 16)))
1195                  (match_dup 4)))]
1196   "TARGET_MULHW"
1197   "machhwu. %0,%1,%2"
1198   [(set_attr "type" "halfmul")])
1200 (define_insn "*machhwu"
1201   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1202         (plus:SI (mult:SI (lshiftrt:SI
1203                            (match_operand:SI 1 "gpc_reg_operand" "%r")
1204                            (const_int 16))
1205                           (lshiftrt:SI
1206                            (match_operand:SI 2 "gpc_reg_operand" "r")
1207                            (const_int 16)))
1208                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1209   "TARGET_MULHW"
1210   "machhwu %0,%1,%2"
1211   [(set_attr "type" "halfmul")])
1213 (define_insn "*maclhwc"
1214   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1215         (compare:CC (plus:SI (mult:SI (sign_extend:SI
1216                                        (match_operand:HI 1 "gpc_reg_operand" "%r"))
1217                                       (sign_extend:SI
1218                                        (match_operand:HI 2 "gpc_reg_operand" "r")))
1219                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1220                     (const_int 0)))
1221    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1222         (plus:SI (mult:SI (sign_extend:SI
1223                            (match_dup 1))
1224                           (sign_extend:SI
1225                            (match_dup 2)))
1226                  (match_dup 4)))]
1227   "TARGET_MULHW"
1228   "maclhw. %0,%1,%2"
1229   [(set_attr "type" "halfmul")])
1231 (define_insn "*maclhw"
1232   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1233         (plus:SI (mult:SI (sign_extend:SI
1234                            (match_operand:HI 1 "gpc_reg_operand" "%r"))
1235                           (sign_extend:SI
1236                            (match_operand:HI 2 "gpc_reg_operand" "r")))
1237                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1238   "TARGET_MULHW"
1239   "maclhw %0,%1,%2"
1240   [(set_attr "type" "halfmul")])
1242 (define_insn "*maclhwuc"
1243   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1244         (compare:CC (plus:SI (mult:SI (zero_extend:SI
1245                                        (match_operand:HI 1 "gpc_reg_operand" "%r"))
1246                                       (zero_extend:SI
1247                                        (match_operand:HI 2 "gpc_reg_operand" "r")))
1248                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1249                     (const_int 0)))
1250    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1251         (plus:SI (mult:SI (zero_extend:SI
1252                            (match_dup 1))
1253                           (zero_extend:SI
1254                            (match_dup 2)))
1255                  (match_dup 4)))]
1256   "TARGET_MULHW"
1257   "maclhwu. %0,%1,%2"
1258   [(set_attr "type" "halfmul")])
1260 (define_insn "*maclhwu"
1261   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1262         (plus:SI (mult:SI (zero_extend:SI
1263                            (match_operand:HI 1 "gpc_reg_operand" "%r"))
1264                           (zero_extend:SI
1265                            (match_operand:HI 2 "gpc_reg_operand" "r")))
1266                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1267   "TARGET_MULHW"
1268   "maclhwu %0,%1,%2"
1269   [(set_attr "type" "halfmul")])
1271 (define_insn "*nmacchwc"
1272   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1273         (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1274                               (mult:SI (ashiftrt:SI
1275                                         (match_operand:SI 2 "gpc_reg_operand" "r")
1276                                         (const_int 16))
1277                                        (sign_extend:SI
1278                                         (match_operand:HI 1 "gpc_reg_operand" "r"))))
1279                     (const_int 0)))
1280    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1281         (minus:SI (match_dup 4)
1282                   (mult:SI (ashiftrt:SI
1283                             (match_dup 2)
1284                             (const_int 16))
1285                            (sign_extend:SI
1286                             (match_dup 1)))))]
1287   "TARGET_MULHW"
1288   "nmacchw. %0,%1,%2"
1289   [(set_attr "type" "halfmul")])
1291 (define_insn "*nmacchw"
1292   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1293         (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1294                   (mult:SI (ashiftrt:SI
1295                             (match_operand:SI 2 "gpc_reg_operand" "r")
1296                             (const_int 16))
1297                            (sign_extend:SI
1298                             (match_operand:HI 1 "gpc_reg_operand" "r")))))]
1299   "TARGET_MULHW"
1300   "nmacchw %0,%1,%2"
1301   [(set_attr "type" "halfmul")])
1303 (define_insn "*nmachhwc"
1304   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1305         (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1306                               (mult:SI (ashiftrt:SI
1307                                         (match_operand:SI 1 "gpc_reg_operand" "%r")
1308                                         (const_int 16))
1309                                        (ashiftrt:SI
1310                                         (match_operand:SI 2 "gpc_reg_operand" "r")
1311                                         (const_int 16))))
1312                     (const_int 0)))
1313    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1314         (minus:SI (match_dup 4)
1315                   (mult:SI (ashiftrt:SI
1316                             (match_dup 1)
1317                             (const_int 16))
1318                            (ashiftrt:SI
1319                             (match_dup 2)
1320                             (const_int 16)))))]
1321   "TARGET_MULHW"
1322   "nmachhw. %0,%1,%2"
1323   [(set_attr "type" "halfmul")])
1325 (define_insn "*nmachhw"
1326   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1327         (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1328                   (mult:SI (ashiftrt:SI
1329                             (match_operand:SI 1 "gpc_reg_operand" "%r")
1330                             (const_int 16))
1331                            (ashiftrt:SI
1332                             (match_operand:SI 2 "gpc_reg_operand" "r")
1333                             (const_int 16)))))]
1334   "TARGET_MULHW"
1335   "nmachhw %0,%1,%2"
1336   [(set_attr "type" "halfmul")])
1338 (define_insn "*nmaclhwc"
1339   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1340         (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1341                               (mult:SI (sign_extend:SI
1342                                         (match_operand:HI 1 "gpc_reg_operand" "%r"))
1343                                        (sign_extend:SI
1344                                         (match_operand:HI 2 "gpc_reg_operand" "r"))))
1345                     (const_int 0)))
1346    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1347         (minus:SI (match_dup 4)
1348                   (mult:SI (sign_extend:SI
1349                             (match_dup 1))
1350                            (sign_extend:SI
1351                             (match_dup 2)))))]
1352   "TARGET_MULHW"
1353   "nmaclhw. %0,%1,%2"
1354   [(set_attr "type" "halfmul")])
1356 (define_insn "*nmaclhw"
1357   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1358         (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1359                   (mult:SI (sign_extend:SI
1360                             (match_operand:HI 1 "gpc_reg_operand" "%r"))
1361                            (sign_extend:SI
1362                             (match_operand:HI 2 "gpc_reg_operand" "r")))))]
1363   "TARGET_MULHW"
1364   "nmaclhw %0,%1,%2"
1365   [(set_attr "type" "halfmul")])
1367 (define_insn "*mulchwc"
1368   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1369         (compare:CC (mult:SI (ashiftrt:SI
1370                               (match_operand:SI 2 "gpc_reg_operand" "r")
1371                               (const_int 16))
1372                              (sign_extend:SI
1373                               (match_operand:HI 1 "gpc_reg_operand" "r")))
1374                     (const_int 0)))
1375    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1376         (mult:SI (ashiftrt:SI
1377                   (match_dup 2)
1378                   (const_int 16))
1379                  (sign_extend:SI
1380                   (match_dup 1))))]
1381   "TARGET_MULHW"
1382   "mulchw. %0,%1,%2"
1383   [(set_attr "type" "halfmul")])
1385 (define_insn "*mulchw"
1386   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1387         (mult:SI (ashiftrt:SI
1388                   (match_operand:SI 2 "gpc_reg_operand" "r")
1389                   (const_int 16))
1390                  (sign_extend:SI
1391                   (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1392   "TARGET_MULHW"
1393   "mulchw %0,%1,%2"
1394   [(set_attr "type" "halfmul")])
1396 (define_insn "*mulchwuc"
1397   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1398         (compare:CC (mult:SI (lshiftrt:SI
1399                               (match_operand:SI 2 "gpc_reg_operand" "r")
1400                               (const_int 16))
1401                              (zero_extend:SI
1402                               (match_operand:HI 1 "gpc_reg_operand" "r")))
1403                     (const_int 0)))
1404    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1405         (mult:SI (lshiftrt:SI
1406                   (match_dup 2)
1407                   (const_int 16))
1408                  (zero_extend:SI
1409                   (match_dup 1))))]
1410   "TARGET_MULHW"
1411   "mulchwu. %0,%1,%2"
1412   [(set_attr "type" "halfmul")])
1414 (define_insn "*mulchwu"
1415   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1416         (mult:SI (lshiftrt:SI
1417                   (match_operand:SI 2 "gpc_reg_operand" "r")
1418                   (const_int 16))
1419                  (zero_extend:SI
1420                   (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1421   "TARGET_MULHW"
1422   "mulchwu %0,%1,%2"
1423   [(set_attr "type" "halfmul")])
1425 (define_insn "*mulhhwc"
1426   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1427         (compare:CC (mult:SI (ashiftrt:SI
1428                               (match_operand:SI 1 "gpc_reg_operand" "%r")
1429                               (const_int 16))
1430                              (ashiftrt:SI
1431                               (match_operand:SI 2 "gpc_reg_operand" "r")
1432                               (const_int 16)))
1433                     (const_int 0)))
1434    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1435         (mult:SI (ashiftrt:SI
1436                   (match_dup 1)
1437                   (const_int 16))
1438                  (ashiftrt:SI
1439                   (match_dup 2)
1440                   (const_int 16))))]
1441   "TARGET_MULHW"
1442   "mulhhw. %0,%1,%2"
1443   [(set_attr "type" "halfmul")])
1445 (define_insn "*mulhhw"
1446   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1447         (mult:SI (ashiftrt:SI
1448                   (match_operand:SI 1 "gpc_reg_operand" "%r")
1449                   (const_int 16))
1450                  (ashiftrt:SI
1451                   (match_operand:SI 2 "gpc_reg_operand" "r")
1452                   (const_int 16))))]
1453   "TARGET_MULHW"
1454   "mulhhw %0,%1,%2"
1455   [(set_attr "type" "halfmul")])
1457 (define_insn "*mulhhwuc"
1458   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1459         (compare:CC (mult:SI (lshiftrt:SI
1460                               (match_operand:SI 1 "gpc_reg_operand" "%r")
1461                               (const_int 16))
1462                              (lshiftrt:SI
1463                               (match_operand:SI 2 "gpc_reg_operand" "r")
1464                               (const_int 16)))
1465                     (const_int 0)))
1466    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1467         (mult:SI (lshiftrt:SI
1468                   (match_dup 1)
1469                   (const_int 16))
1470                  (lshiftrt:SI
1471                   (match_dup 2)
1472                   (const_int 16))))]
1473   "TARGET_MULHW"
1474   "mulhhwu. %0,%1,%2"
1475   [(set_attr "type" "halfmul")])
1477 (define_insn "*mulhhwu"
1478   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1479         (mult:SI (lshiftrt:SI
1480                   (match_operand:SI 1 "gpc_reg_operand" "%r")
1481                   (const_int 16))
1482                  (lshiftrt:SI
1483                   (match_operand:SI 2 "gpc_reg_operand" "r")
1484                   (const_int 16))))]
1485   "TARGET_MULHW"
1486   "mulhhwu %0,%1,%2"
1487   [(set_attr "type" "halfmul")])
1489 (define_insn "*mullhwc"
1490   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1491         (compare:CC (mult:SI (sign_extend:SI
1492                               (match_operand:HI 1 "gpc_reg_operand" "%r"))
1493                              (sign_extend:SI
1494                               (match_operand:HI 2 "gpc_reg_operand" "r")))
1495                     (const_int 0)))
1496    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1497         (mult:SI (sign_extend:SI
1498                   (match_dup 1))
1499                  (sign_extend:SI
1500                   (match_dup 2))))]
1501   "TARGET_MULHW"
1502   "mullhw. %0,%1,%2"
1503   [(set_attr "type" "halfmul")])
1505 (define_insn "*mullhw"
1506   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1507         (mult:SI (sign_extend:SI
1508                   (match_operand:HI 1 "gpc_reg_operand" "%r"))
1509                  (sign_extend:SI
1510                   (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1511   "TARGET_MULHW"
1512   "mullhw %0,%1,%2"
1513   [(set_attr "type" "halfmul")])
1515 (define_insn "*mullhwuc"
1516   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1517         (compare:CC (mult:SI (zero_extend:SI
1518                               (match_operand:HI 1 "gpc_reg_operand" "%r"))
1519                              (zero_extend:SI
1520                               (match_operand:HI 2 "gpc_reg_operand" "r")))
1521                     (const_int 0)))
1522    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1523         (mult:SI (zero_extend:SI
1524                   (match_dup 1))
1525                  (zero_extend:SI
1526                   (match_dup 2))))]
1527   "TARGET_MULHW"
1528   "mullhwu. %0,%1,%2"
1529   [(set_attr "type" "halfmul")])
1531 (define_insn "*mullhwu"
1532   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1533         (mult:SI (zero_extend:SI
1534                   (match_operand:HI 1 "gpc_reg_operand" "%r"))
1535                  (zero_extend:SI
1536                   (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1537   "TARGET_MULHW"
1538   "mullhwu %0,%1,%2"
1539   [(set_attr "type" "halfmul")])
1541 ;; IBM 405, 440, 464 and 476 string-search dlmzb instruction support.
1542 (define_insn "dlmzb"
1543   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1544         (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
1545                     (match_operand:SI 2 "gpc_reg_operand" "r")]
1546                    UNSPEC_DLMZB_CR))
1547    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1548         (unspec:SI [(match_dup 1)
1549                     (match_dup 2)]
1550                    UNSPEC_DLMZB))]
1551   "TARGET_DLMZB"
1552   "dlmzb. %0,%1,%2")
1554 (define_expand "strlensi"
1555   [(set (match_operand:SI 0 "gpc_reg_operand")
1556         (unspec:SI [(match_operand:BLK 1 "general_operand")
1557                     (match_operand:QI 2 "const_int_operand")
1558                     (match_operand 3 "const_int_operand")]
1559                    UNSPEC_DLMZB_STRLEN))
1560    (clobber (match_scratch:CC 4))]
1561   "TARGET_DLMZB && WORDS_BIG_ENDIAN && !optimize_size"
1563   rtx result = operands[0];
1564   rtx src = operands[1];
1565   rtx search_char = operands[2];
1566   rtx align = operands[3];
1567   rtx addr, scratch_string, word1, word2, scratch_dlmzb;
1568   rtx loop_label, end_label, mem, cr0, cond;
1569   if (search_char != const0_rtx
1570       || GET_CODE (align) != CONST_INT
1571       || INTVAL (align) < 8)
1572         FAIL;
1573   word1 = gen_reg_rtx (SImode);
1574   word2 = gen_reg_rtx (SImode);
1575   scratch_dlmzb = gen_reg_rtx (SImode);
1576   scratch_string = gen_reg_rtx (Pmode);
1577   loop_label = gen_label_rtx ();
1578   end_label = gen_label_rtx ();
1579   addr = force_reg (Pmode, XEXP (src, 0));
1580   emit_move_insn (scratch_string, addr);
1581   emit_label (loop_label);
1582   mem = change_address (src, SImode, scratch_string);
1583   emit_move_insn (word1, mem);
1584   emit_move_insn (word2, adjust_address (mem, SImode, 4));
1585   cr0 = gen_rtx_REG (CCmode, CR0_REGNO);
1586   emit_insn (gen_dlmzb (scratch_dlmzb, word1, word2, cr0));
1587   cond = gen_rtx_NE (VOIDmode, cr0, const0_rtx);
1588   emit_jump_insn (gen_rtx_SET (pc_rtx,
1589                                gen_rtx_IF_THEN_ELSE (VOIDmode,
1590                                                      cond,
1591                                                      gen_rtx_LABEL_REF
1592                                                        (VOIDmode,
1593                                                         end_label),
1594                                                      pc_rtx)));
1595   emit_insn (gen_addsi3 (scratch_string, scratch_string, GEN_INT (8)));
1596   emit_jump_insn (gen_rtx_SET (pc_rtx,
1597                                gen_rtx_LABEL_REF (VOIDmode, loop_label)));
1598   emit_barrier ();
1599   emit_label (end_label);
1600   emit_insn (gen_addsi3 (scratch_string, scratch_string, scratch_dlmzb));
1601   emit_insn (gen_subsi3 (result, scratch_string, addr));
1602   emit_insn (gen_addsi3 (result, result, constm1_rtx));
1603   DONE;
1606 ;; Fixed-point arithmetic insns.
1608 (define_expand "add<mode>3"
1609   [(set (match_operand:SDI 0 "gpc_reg_operand")
1610         (plus:SDI (match_operand:SDI 1 "gpc_reg_operand")
1611                   (match_operand:SDI 2 "reg_or_add_cint_operand")))]
1612   ""
1614   if (<MODE>mode == DImode && !TARGET_POWERPC64)
1615     {
1616       rtx lo0 = gen_lowpart (SImode, operands[0]);
1617       rtx lo1 = gen_lowpart (SImode, operands[1]);
1618       rtx lo2 = gen_lowpart (SImode, operands[2]);
1619       rtx hi0 = gen_highpart (SImode, operands[0]);
1620       rtx hi1 = gen_highpart (SImode, operands[1]);
1621       rtx hi2 = gen_highpart_mode (SImode, DImode, operands[2]);
1623       if (!reg_or_short_operand (lo2, SImode))
1624         lo2 = force_reg (SImode, lo2);
1625       if (!adde_operand (hi2, SImode))
1626         hi2 = force_reg (SImode, hi2);
1628       emit_insn (gen_addsi3_carry (lo0, lo1, lo2));
1629       emit_insn (gen_addsi3_carry_in (hi0, hi1, hi2));
1630       DONE;
1631     }
1633   if (CONST_INT_P (operands[2]) && !add_operand (operands[2], <MODE>mode))
1634     {
1635       rtx tmp = ((!can_create_pseudo_p ()
1636                   || rtx_equal_p (operands[0], operands[1]))
1637                  ? operands[0] : gen_reg_rtx (<MODE>mode));
1639       /* Adding a constant to r0 is not a valid insn, so use a different
1640          strategy in that case.  */
1641       if (reg_or_subregno (operands[1]) == 0 || reg_or_subregno (tmp) == 0)
1642         {
1643           if (operands[0] == operands[1])
1644             FAIL;
1645           rs6000_emit_move (operands[0], operands[2], <MODE>mode);
1646           emit_insn (gen_add<mode>3 (operands[0], operands[1], operands[0]));
1647           DONE;
1648         }
1650       HOST_WIDE_INT val = INTVAL (operands[2]);
1651       HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1652       HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1654       if (<MODE>mode == DImode && !satisfies_constraint_L (GEN_INT (rest)))
1655         FAIL;
1657       /* The ordering here is important for the prolog expander.
1658          When space is allocated from the stack, adding 'low' first may
1659          produce a temporary deallocation (which would be bad).  */
1660       emit_insn (gen_add<mode>3 (tmp, operands[1], GEN_INT (rest)));
1661       emit_insn (gen_add<mode>3 (operands[0], tmp, GEN_INT (low)));
1662       DONE;
1663     }
1666 (define_insn "*add<mode>3"
1667   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r,r")
1668         (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b,b")
1669                   (match_operand:GPR 2 "add_operand" "r,I,L")))]
1670   ""
1671   "@
1672    add %0,%1,%2
1673    addi %0,%1,%2
1674    addis %0,%1,%v2"
1675   [(set_attr "type" "add")])
1677 (define_insn "*addsi3_high"
1678   [(set (match_operand:SI 0 "gpc_reg_operand" "=b")
1679         (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
1680                  (high:SI (match_operand 2 "" ""))))]
1681   "TARGET_MACHO && !TARGET_64BIT"
1682   "addis %0,%1,ha16(%2)"
1683   [(set_attr "type" "add")])
1685 (define_insn_and_split "*add<mode>3_dot"
1686   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1687         (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
1688                               (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
1689                     (const_int 0)))
1690    (clobber (match_scratch:GPR 0 "=r,r"))]
1691   "<MODE>mode == Pmode"
1692   "@
1693    add. %0,%1,%2
1694    #"
1695   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1696   [(set (match_dup 0)
1697         (plus:GPR (match_dup 1)
1698                  (match_dup 2)))
1699    (set (match_dup 3)
1700         (compare:CC (match_dup 0)
1701                     (const_int 0)))]
1702   ""
1703   [(set_attr "type" "add")
1704    (set_attr "dot" "yes")
1705    (set_attr "length" "4,8")])
1707 (define_insn_and_split "*add<mode>3_dot2"
1708   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1709         (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
1710                               (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
1711                     (const_int 0)))
1712    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1713         (plus:GPR (match_dup 1)
1714                   (match_dup 2)))]
1715   "<MODE>mode == Pmode"
1716   "@
1717    add. %0,%1,%2
1718    #"
1719   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1720   [(set (match_dup 0)
1721         (plus:GPR (match_dup 1)
1722                   (match_dup 2)))
1723    (set (match_dup 3)
1724         (compare:CC (match_dup 0)
1725                     (const_int 0)))]
1726   ""
1727   [(set_attr "type" "add")
1728    (set_attr "dot" "yes")
1729    (set_attr "length" "4,8")])
1731 (define_insn_and_split "*add<mode>3_imm_dot"
1732   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1733         (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b")
1734                               (match_operand:GPR 2 "short_cint_operand" "I,I"))
1735                     (const_int 0)))
1736    (clobber (match_scratch:GPR 0 "=r,r"))
1737    (clobber (reg:GPR CA_REGNO))]
1738   "<MODE>mode == Pmode"
1739   "@
1740    addic. %0,%1,%2
1741    #"
1742   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1743   [(set (match_dup 0)
1744         (plus:GPR (match_dup 1)
1745                   (match_dup 2)))
1746    (set (match_dup 3)
1747         (compare:CC (match_dup 0)
1748                     (const_int 0)))]
1749   ""
1750   [(set_attr "type" "add")
1751    (set_attr "dot" "yes")
1752    (set_attr "length" "4,8")])
1754 (define_insn_and_split "*add<mode>3_imm_dot2"
1755   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1756         (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b")
1757                               (match_operand:GPR 2 "short_cint_operand" "I,I"))
1758                     (const_int 0)))
1759    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1760         (plus:GPR (match_dup 1)
1761                   (match_dup 2)))
1762    (clobber (reg:GPR CA_REGNO))]
1763   "<MODE>mode == Pmode"
1764   "@
1765    addic. %0,%1,%2
1766    #"
1767   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1768   [(set (match_dup 0)
1769         (plus:GPR (match_dup 1)
1770                   (match_dup 2)))
1771    (set (match_dup 3)
1772         (compare:CC (match_dup 0)
1773                     (const_int 0)))]
1774   ""
1775   [(set_attr "type" "add")
1776    (set_attr "dot" "yes")
1777    (set_attr "length" "4,8")])
1779 ;; Split an add that we can't do in one insn into two insns, each of which
1780 ;; does one 16-bit part.  This is used by combine.  Note that the low-order
1781 ;; add should be last in case the result gets used in an address.
1783 (define_split
1784   [(set (match_operand:GPR 0 "gpc_reg_operand")
1785         (plus:GPR (match_operand:GPR 1 "gpc_reg_operand")
1786                   (match_operand:GPR 2 "non_add_cint_operand")))]
1787   ""
1788   [(set (match_dup 0) (plus:GPR (match_dup 1) (match_dup 3)))
1789    (set (match_dup 0) (plus:GPR (match_dup 0) (match_dup 4)))]
1791   HOST_WIDE_INT val = INTVAL (operands[2]);
1792   HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1793   HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1795   operands[4] = GEN_INT (low);
1796   if (<MODE>mode == SImode || satisfies_constraint_L (GEN_INT (rest)))
1797     operands[3] = GEN_INT (rest);
1798   else if (can_create_pseudo_p ())
1799     {
1800       operands[3] = gen_reg_rtx (DImode);
1801       emit_move_insn (operands[3], operands[2]);
1802       emit_insn (gen_adddi3 (operands[0], operands[1], operands[3]));
1803       DONE;
1804     }
1805   else
1806     FAIL;
1810 (define_insn "add<mode>3_carry"
1811   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1812         (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1813                 (match_operand:P 2 "reg_or_short_operand" "rI")))
1814    (set (reg:P CA_REGNO)
1815         (ltu:P (plus:P (match_dup 1)
1816                        (match_dup 2))
1817                (match_dup 1)))]
1818   ""
1819   "add%I2c %0,%1,%2"
1820   [(set_attr "type" "add")])
1822 (define_insn "*add<mode>3_imm_carry_pos"
1823   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1824         (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1825                 (match_operand:P 2 "short_cint_operand" "n")))
1826    (set (reg:P CA_REGNO)
1827         (geu:P (match_dup 1)
1828                (match_operand:P 3 "const_int_operand" "n")))]
1829   "INTVAL (operands[2]) > 0
1830    && INTVAL (operands[2]) + INTVAL (operands[3]) == 0"
1831   "addic %0,%1,%2"
1832   [(set_attr "type" "add")])
1834 (define_insn "*add<mode>3_imm_carry_0"
1835   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1836         (match_operand:P 1 "gpc_reg_operand" "r"))
1837    (set (reg:P CA_REGNO)
1838         (const_int 0))]
1839   ""
1840   "addic %0,%1,0"
1841   [(set_attr "type" "add")])
1843 (define_insn "*add<mode>3_imm_carry_m1"
1844   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1845         (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1846                 (const_int -1)))
1847    (set (reg:P CA_REGNO)
1848         (ne:P (match_dup 1)
1849               (const_int 0)))]
1850   ""
1851   "addic %0,%1,-1"
1852   [(set_attr "type" "add")])
1854 (define_insn "*add<mode>3_imm_carry_neg"
1855   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1856         (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1857                 (match_operand:P 2 "short_cint_operand" "n")))
1858    (set (reg:P CA_REGNO)
1859         (gtu:P (match_dup 1)
1860                (match_operand:P 3 "const_int_operand" "n")))]
1861   "INTVAL (operands[2]) < 0
1862    && INTVAL (operands[2]) + INTVAL (operands[3]) == -1"
1863   "addic %0,%1,%2"
1864   [(set_attr "type" "add")])
1867 (define_expand "add<mode>3_carry_in"
1868   [(parallel [
1869      (set (match_operand:GPR 0 "gpc_reg_operand")
1870           (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand")
1871                               (match_operand:GPR 2 "adde_operand"))
1872                     (reg:GPR CA_REGNO)))
1873      (clobber (reg:GPR CA_REGNO))])]
1874   ""
1876   if (operands[2] == const0_rtx)
1877     {
1878       emit_insn (gen_add<mode>3_carry_in_0 (operands[0], operands[1]));
1879       DONE;
1880     }
1881   if (operands[2] == constm1_rtx)
1882     {
1883       emit_insn (gen_add<mode>3_carry_in_m1 (operands[0], operands[1]));
1884       DONE;
1885     }
1888 (define_insn "*add<mode>3_carry_in_internal"
1889   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1890         (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1891                             (match_operand:GPR 2 "gpc_reg_operand" "r"))
1892                   (reg:GPR CA_REGNO)))
1893    (clobber (reg:GPR CA_REGNO))]
1894   ""
1895   "adde %0,%1,%2"
1896   [(set_attr "type" "add")])
1898 (define_insn "*add<mode>3_carry_in_internal2"
1899   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1900         (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1901                             (reg:GPR CA_REGNO))
1902                   (match_operand:GPR 2 "gpc_reg_operand" "r")))
1903    (clobber (reg:GPR CA_REGNO))]
1904   ""
1905   "adde %0,%1,%2"
1906   [(set_attr "type" "add")])
1908 (define_insn "add<mode>3_carry_in_0"
1909   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1910         (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1911                   (reg:GPR CA_REGNO)))
1912    (clobber (reg:GPR CA_REGNO))]
1913   ""
1914   "addze %0,%1"
1915   [(set_attr "type" "add")])
1917 (define_insn "add<mode>3_carry_in_m1"
1918   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1919         (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1920                             (reg:GPR CA_REGNO))
1921                   (const_int -1)))
1922    (clobber (reg:GPR CA_REGNO))]
1923   ""
1924   "addme %0,%1"
1925   [(set_attr "type" "add")])
1928 (define_expand "one_cmpl<mode>2"
1929   [(set (match_operand:SDI 0 "gpc_reg_operand")
1930         (not:SDI (match_operand:SDI 1 "gpc_reg_operand")))]
1931   ""
1933   if (<MODE>mode == DImode && !TARGET_POWERPC64)
1934     {
1935       rs6000_split_logical (operands, NOT, false, false, false);
1936       DONE;
1937     }
1940 (define_insn "*one_cmpl<mode>2"
1941   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1942         (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
1943   ""
1944   "not %0,%1")
1946 (define_insn_and_split "*one_cmpl<mode>2_dot"
1947   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1948         (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
1949                     (const_int 0)))
1950    (clobber (match_scratch:GPR 0 "=r,r"))]
1951   "<MODE>mode == Pmode"
1952   "@
1953    not. %0,%1
1954    #"
1955   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1956   [(set (match_dup 0)
1957         (not:GPR (match_dup 1)))
1958    (set (match_dup 2)
1959         (compare:CC (match_dup 0)
1960                     (const_int 0)))]
1961   ""
1962   [(set_attr "type" "logical")
1963    (set_attr "dot" "yes")
1964    (set_attr "length" "4,8")])
1966 (define_insn_and_split "*one_cmpl<mode>2_dot2"
1967   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1968         (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
1969                     (const_int 0)))
1970    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1971         (not:GPR (match_dup 1)))]
1972   "<MODE>mode == Pmode"
1973   "@
1974    not. %0,%1
1975    #"
1976   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1977   [(set (match_dup 0)
1978         (not:GPR (match_dup 1)))
1979    (set (match_dup 2)
1980         (compare:CC (match_dup 0)
1981                     (const_int 0)))]
1982   ""
1983   [(set_attr "type" "logical")
1984    (set_attr "dot" "yes")
1985    (set_attr "length" "4,8")])
1988 (define_expand "sub<mode>3"
1989   [(set (match_operand:SDI 0 "gpc_reg_operand")
1990         (minus:SDI (match_operand:SDI 1 "reg_or_short_operand")
1991                    (match_operand:SDI 2 "gpc_reg_operand")))]
1992   ""
1994   if (<MODE>mode == DImode && !TARGET_POWERPC64)
1995     {
1996       rtx lo0 = gen_lowpart (SImode, operands[0]);
1997       rtx lo1 = gen_lowpart (SImode, operands[1]);
1998       rtx lo2 = gen_lowpart (SImode, operands[2]);
1999       rtx hi0 = gen_highpart (SImode, operands[0]);
2000       rtx hi1 = gen_highpart_mode (SImode, DImode, operands[1]);
2001       rtx hi2 = gen_highpart (SImode, operands[2]);
2003       if (!reg_or_short_operand (lo1, SImode))
2004         lo1 = force_reg (SImode, lo1);
2005       if (!adde_operand (hi1, SImode))
2006         hi1 = force_reg (SImode, hi1);
2008       emit_insn (gen_subfsi3_carry (lo0, lo2, lo1));
2009       emit_insn (gen_subfsi3_carry_in (hi0, hi2, hi1));
2010       DONE;
2011     }
2013   if (short_cint_operand (operands[1], <MODE>mode))
2014     {
2015       emit_insn (gen_subf<mode>3_imm (operands[0], operands[2], operands[1]));
2016       DONE;
2017     }
2020 (define_insn "*subf<mode>3"
2021   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2022         (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r")
2023                    (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2024   ""
2025   "subf %0,%1,%2"
2026   [(set_attr "type" "add")])
2028 (define_insn_and_split "*subf<mode>3_dot"
2029   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2030         (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
2031                                (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2032                     (const_int 0)))
2033    (clobber (match_scratch:GPR 0 "=r,r"))]
2034   "<MODE>mode == Pmode"
2035   "@
2036    subf. %0,%1,%2
2037    #"
2038   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2039   [(set (match_dup 0)
2040         (minus:GPR (match_dup 2)
2041                    (match_dup 1)))
2042    (set (match_dup 3)
2043         (compare:CC (match_dup 0)
2044                     (const_int 0)))]
2045   ""
2046   [(set_attr "type" "add")
2047    (set_attr "dot" "yes")
2048    (set_attr "length" "4,8")])
2050 (define_insn_and_split "*subf<mode>3_dot2"
2051   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2052         (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
2053                                (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2054                     (const_int 0)))
2055    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2056         (minus:GPR (match_dup 2)
2057                    (match_dup 1)))]
2058   "<MODE>mode == Pmode"
2059   "@
2060    subf. %0,%1,%2
2061    #"
2062   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2063   [(set (match_dup 0)
2064         (minus:GPR (match_dup 2)
2065                    (match_dup 1)))
2066    (set (match_dup 3)
2067         (compare:CC (match_dup 0)
2068                     (const_int 0)))]
2069   ""
2070   [(set_attr "type" "add")
2071    (set_attr "dot" "yes")
2072    (set_attr "length" "4,8")])
2074 (define_insn "subf<mode>3_imm"
2075   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2076         (minus:GPR (match_operand:GPR 2 "short_cint_operand" "I")
2077                    (match_operand:GPR 1 "gpc_reg_operand" "r")))
2078    (clobber (reg:GPR CA_REGNO))]
2079   ""
2080   "subfic %0,%1,%2"
2081   [(set_attr "type" "add")])
2083 (define_insn_and_split "subf<mode>3_carry_dot2"
2084   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2085         (compare:CC (minus:P (match_operand:P 2 "gpc_reg_operand" "r,r")
2086                                (match_operand:P 1 "gpc_reg_operand" "r,r"))
2087                     (const_int 0)))
2088    (set (match_operand:P 0 "gpc_reg_operand" "=r,r")
2089         (minus:P (match_dup 2)
2090                    (match_dup 1)))
2091    (set (reg:P CA_REGNO)
2092         (leu:P (match_dup 1)
2093                (match_dup 2)))]
2094   "<MODE>mode == Pmode"
2095   "@
2096    subfc. %0,%1,%2
2097    #"
2098   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2099   [(parallel [(set (match_dup 0)
2100                    (minus:P (match_dup 2)
2101                             (match_dup 1)))
2102               (set (reg:P CA_REGNO)
2103                    (leu:P (match_dup 1)
2104                           (match_dup 2)))])
2105    (set (match_dup 3)
2106         (compare:CC (match_dup 0)
2107                     (const_int 0)))]
2108   ""
2109   [(set_attr "type" "add")
2110    (set_attr "dot" "yes")
2111    (set_attr "length" "4,8")])
2113 (define_insn "subf<mode>3_carry"
2114   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2115         (minus:P (match_operand:P 2 "reg_or_short_operand" "rI")
2116                  (match_operand:P 1 "gpc_reg_operand" "r")))
2117    (set (reg:P CA_REGNO)
2118         (leu:P (match_dup 1)
2119                (match_dup 2)))]
2120   ""
2121   "subf%I2c %0,%1,%2"
2122   [(set_attr "type" "add")])
2124 (define_insn "*subf<mode>3_imm_carry_0"
2125   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2126         (neg:P (match_operand:P 1 "gpc_reg_operand" "r")))
2127    (set (reg:P CA_REGNO)
2128         (eq:P (match_dup 1)
2129               (const_int 0)))]
2130   ""
2131   "subfic %0,%1,0"
2132   [(set_attr "type" "add")])
2134 (define_insn "*subf<mode>3_imm_carry_m1"
2135   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2136         (not:P (match_operand:P 1 "gpc_reg_operand" "r")))
2137    (set (reg:P CA_REGNO)
2138         (const_int 1))]
2139   ""
2140   "subfic %0,%1,-1"
2141   [(set_attr "type" "add")])
2144 (define_expand "subf<mode>3_carry_in"
2145   [(parallel [
2146      (set (match_operand:GPR 0 "gpc_reg_operand")
2147           (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand"))
2148                               (reg:GPR CA_REGNO))
2149                     (match_operand:GPR 2 "adde_operand")))
2150      (clobber (reg:GPR CA_REGNO))])]
2151   ""
2153   if (operands[2] == const0_rtx)
2154     {
2155       emit_insn (gen_subf<mode>3_carry_in_0 (operands[0], operands[1]));
2156       DONE;
2157     }
2158   if (operands[2] == constm1_rtx)
2159     {
2160       emit_insn (gen_subf<mode>3_carry_in_m1 (operands[0], operands[1]));
2161       DONE;
2162     }
2165 (define_insn "*subf<mode>3_carry_in_internal"
2166   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2167         (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
2168                             (reg:GPR CA_REGNO))
2169                   (match_operand:GPR 2 "gpc_reg_operand" "r")))
2170    (clobber (reg:GPR CA_REGNO))]
2171   ""
2172   "subfe %0,%1,%2"
2173   [(set_attr "type" "add")])
2175 (define_insn "subf<mode>3_carry_in_0"
2176   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2177         (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
2178                   (reg:GPR CA_REGNO)))
2179    (clobber (reg:GPR CA_REGNO))]
2180   ""
2181   "subfze %0,%1"
2182   [(set_attr "type" "add")])
2184 (define_insn "subf<mode>3_carry_in_m1"
2185   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2186         (plus:GPR (minus:GPR (reg:GPR CA_REGNO)
2187                              (match_operand:GPR 1 "gpc_reg_operand" "r"))
2188                   (const_int -2)))
2189    (clobber (reg:GPR CA_REGNO))]
2190   ""
2191   "subfme %0,%1"
2192   [(set_attr "type" "add")])
2194 (define_insn "subf<mode>3_carry_in_xx"
2195   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2196         (plus:GPR (reg:GPR CA_REGNO)
2197                   (const_int -1)))
2198    (clobber (reg:GPR CA_REGNO))]
2199   ""
2200   "subfe %0,%0,%0"
2201   [(set_attr "type" "add")])
2204 (define_insn "neg<mode>2"
2205   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2206         (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2207   ""
2208   "neg %0,%1"
2209   [(set_attr "type" "add")])
2211 (define_insn_and_split "*neg<mode>2_dot"
2212   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2213         (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2214                     (const_int 0)))
2215    (clobber (match_scratch:GPR 0 "=r,r"))]
2216   "<MODE>mode == Pmode"
2217   "@
2218    neg. %0,%1
2219    #"
2220   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2221   [(set (match_dup 0)
2222         (neg:GPR (match_dup 1)))
2223    (set (match_dup 2)
2224         (compare:CC (match_dup 0)
2225                     (const_int 0)))]
2226   ""
2227   [(set_attr "type" "add")
2228    (set_attr "dot" "yes")
2229    (set_attr "length" "4,8")])
2231 (define_insn_and_split "*neg<mode>2_dot2"
2232   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2233         (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2234                     (const_int 0)))
2235    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2236         (neg:GPR (match_dup 1)))]
2237   "<MODE>mode == Pmode"
2238   "@
2239    neg. %0,%1
2240    #"
2241   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2242   [(set (match_dup 0)
2243         (neg:GPR (match_dup 1)))
2244    (set (match_dup 2)
2245         (compare:CC (match_dup 0)
2246                     (const_int 0)))]
2247   ""
2248   [(set_attr "type" "add")
2249    (set_attr "dot" "yes")
2250    (set_attr "length" "4,8")])
2253 (define_insn "clz<mode>2"
2254   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2255         (clz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2256   ""
2257   "cntlz<wd> %0,%1"
2258   [(set_attr "type" "cntlz")])
2260 (define_expand "ctz<mode>2"
2261    [(set (match_operand:GPR 0 "gpc_reg_operand")
2262          (ctz:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2263   ""
2265   if (TARGET_CTZ)
2266     {
2267       emit_insn (gen_ctz<mode>2_hw (operands[0], operands[1]));
2268       DONE;
2269     }
2271   rtx tmp1 = gen_reg_rtx (<MODE>mode);
2272   rtx tmp2 = gen_reg_rtx (<MODE>mode);
2273   rtx tmp3 = gen_reg_rtx (<MODE>mode);
2275   if (TARGET_POPCNTD)
2276     {
2277       emit_insn (gen_add<mode>3 (tmp1, operands[1], constm1_rtx));
2278       emit_insn (gen_one_cmpl<mode>2 (tmp2, operands[1]));
2279       emit_insn (gen_and<mode>3 (tmp3, tmp1, tmp2));
2280       emit_insn (gen_popcntd<mode>2 (operands[0], tmp3));
2281     }
2282   else
2283     {
2284       emit_insn (gen_neg<mode>2 (tmp1, operands[1]));
2285       emit_insn (gen_and<mode>3 (tmp2, operands[1], tmp1));
2286       emit_insn (gen_clz<mode>2 (tmp3, tmp2));
2287       emit_insn (gen_sub<mode>3 (operands[0], GEN_INT (<bits> - 1), tmp3));
2288     }
2290   DONE;
2293 (define_insn "ctz<mode>2_hw"
2294   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2295         (ctz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2296   "TARGET_CTZ"
2297   "cnttz<wd> %0,%1"
2298   [(set_attr "type" "cntlz")])
2300 (define_expand "ffs<mode>2"
2301   [(set (match_operand:GPR 0 "gpc_reg_operand")
2302         (ffs:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2303   ""
2305   rtx tmp1 = gen_reg_rtx (<MODE>mode);
2306   rtx tmp2 = gen_reg_rtx (<MODE>mode);
2307   rtx tmp3 = gen_reg_rtx (<MODE>mode);
2308   emit_insn (gen_neg<mode>2 (tmp1, operands[1]));
2309   emit_insn (gen_and<mode>3 (tmp2, operands[1], tmp1));
2310   emit_insn (gen_clz<mode>2 (tmp3, tmp2));
2311   emit_insn (gen_sub<mode>3 (operands[0], GEN_INT (<bits>), tmp3));
2312   DONE;
2316 (define_expand "popcount<mode>2"
2317   [(set (match_operand:GPR 0 "gpc_reg_operand")
2318         (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2319   "TARGET_POPCNTB || TARGET_POPCNTD"
2321   rs6000_emit_popcount (operands[0], operands[1]);
2322   DONE;
2325 (define_insn "popcntb<mode>2"
2326   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2327         (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")]
2328                     UNSPEC_POPCNTB))]
2329   "TARGET_POPCNTB"
2330   "popcntb %0,%1"
2331   [(set_attr "type" "popcnt")])
2333 (define_insn "popcntd<mode>2"
2334   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2335         (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2336   "TARGET_POPCNTD"
2337   "popcnt<wd> %0,%1"
2338   [(set_attr "type" "popcnt")])
2341 (define_expand "parity<mode>2"
2342   [(set (match_operand:GPR 0 "gpc_reg_operand")
2343         (parity:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2344   "TARGET_POPCNTB"
2346   rs6000_emit_parity (operands[0], operands[1]);
2347   DONE;
2350 (define_insn "parity<mode>2_cmpb"
2351   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2352         (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")] UNSPEC_PARITY))]
2353   "TARGET_CMPB && TARGET_POPCNTB"
2354   "prty<wd> %0,%1"
2355   [(set_attr "type" "popcnt")])
2357 (define_insn "cmpb<mode>3"
2358   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2359         (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")
2360                      (match_operand:GPR 2 "gpc_reg_operand" "r")] UNSPEC_CMPB))]
2361   "TARGET_CMPB"
2362   "cmpb %0,%1,%2"
2363   [(set_attr "type" "cmp")])
2365 ;; Since the hardware zeros the upper part of the register, save generating the
2366 ;; AND immediate if we are converting to unsigned
2367 (define_insn "*bswap<mode>2_extenddi"
2368   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2369         (zero_extend:DI
2370          (bswap:HSI (match_operand:HSI 1 "memory_operand" "Z"))))]
2371   "TARGET_POWERPC64"
2372   "l<wd>brx %0,%y1"
2373   [(set_attr "type" "load")])
2375 (define_insn "*bswaphi2_extendsi"
2376   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2377         (zero_extend:SI
2378          (bswap:HI (match_operand:HI 1 "memory_operand" "Z"))))]
2379   ""
2380   "lhbrx %0,%y1"
2381   [(set_attr "type" "load")])
2383 ;; Separate the bswap patterns into load, store, and gpr<-gpr.  This prevents
2384 ;; the register allocator from converting a gpr<-gpr swap into a store and then
2385 ;; load with byte swap, which can be slower than doing it in the registers.  It
2386 ;; also prevents certain failures with the RELOAD register allocator.
2388 (define_expand "bswap<mode>2"
2389   [(use (match_operand:HSI 0 "reg_or_mem_operand"))
2390    (use (match_operand:HSI 1 "reg_or_mem_operand"))]
2391   ""
2393   rtx dest = operands[0];
2394   rtx src = operands[1];
2396   if (!REG_P (dest) && !REG_P (src))
2397     src = force_reg (<MODE>mode, src);
2399   if (MEM_P (src))
2400     {
2401       src = rs6000_force_indexed_or_indirect_mem (src);
2402       emit_insn (gen_bswap<mode>2_load (dest, src));
2403     }
2404   else if (MEM_P (dest))
2405     {
2406       dest = rs6000_force_indexed_or_indirect_mem (dest);
2407       emit_insn (gen_bswap<mode>2_store (dest, src));
2408     }
2409   else
2410     emit_insn (gen_bswap<mode>2_reg (dest, src));
2411   DONE;
2414 (define_insn "bswap<mode>2_load"
2415   [(set (match_operand:HSI 0 "gpc_reg_operand" "=r")
2416         (bswap:HSI (match_operand:HSI 1 "indexed_or_indirect_operand" "Z")))]
2417   ""
2418   "l<wd>brx %0,%y1"
2419   [(set_attr "type" "load")])
2421 (define_insn "bswap<mode>2_store"
2422   [(set (match_operand:HSI 0 "indexed_or_indirect_operand" "=Z")
2423         (bswap:HSI (match_operand:HSI 1 "gpc_reg_operand" "r")))]
2424   ""
2425   "st<wd>brx %1,%y0"
2426   [(set_attr "type" "store")])
2428 (define_insn_and_split "bswaphi2_reg"
2429   [(set (match_operand:HI 0 "gpc_reg_operand" "=&r,wo")
2430         (bswap:HI
2431          (match_operand:HI 1 "gpc_reg_operand" "r,wo")))
2432    (clobber (match_scratch:SI 2 "=&r,X"))]
2433   ""
2434   "@
2435    #
2436    xxbrh %x0,%x1"
2437   "reload_completed && int_reg_operand (operands[0], HImode)"
2438   [(set (match_dup 3)
2439         (and:SI (lshiftrt:SI (match_dup 4)
2440                              (const_int 8))
2441                 (const_int 255)))
2442    (set (match_dup 2)
2443         (and:SI (ashift:SI (match_dup 4)
2444                            (const_int 8))
2445                 (const_int 65280)))             ;; 0xff00
2446    (set (match_dup 3)
2447         (ior:SI (match_dup 3)
2448                 (match_dup 2)))]
2450   operands[3] = simplify_gen_subreg (SImode, operands[0], HImode, 0);
2451   operands[4] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
2453   [(set_attr "length" "12,4")
2454    (set_attr "type" "*,vecperm")])
2456 ;; We are always BITS_BIG_ENDIAN, so the bit positions below in
2457 ;; zero_extract insns do not change for -mlittle.
2458 (define_insn_and_split "bswapsi2_reg"
2459   [(set (match_operand:SI 0 "gpc_reg_operand" "=&r,wo")
2460         (bswap:SI
2461          (match_operand:SI 1 "gpc_reg_operand" "r,wo")))]
2462   ""
2463   "@
2464    #
2465    xxbrw %x0,%x1"
2466   "reload_completed && int_reg_operand (operands[0], SImode)"
2467   [(set (match_dup 0)                                   ; DABC
2468         (rotate:SI (match_dup 1)
2469                    (const_int 24)))
2470    (set (match_dup 0)                                   ; DCBC
2471         (ior:SI (and:SI (ashift:SI (match_dup 1)
2472                                    (const_int 8))
2473                         (const_int 16711680))
2474                 (and:SI (match_dup 0)
2475                         (const_int -16711681))))
2476    (set (match_dup 0)                                   ; DCBA
2477         (ior:SI (and:SI (lshiftrt:SI (match_dup 1)
2478                                      (const_int 24))
2479                         (const_int 255))
2480                 (and:SI (match_dup 0)
2481                         (const_int -256))))]
2482   ""
2483   [(set_attr "length" "12,4")
2484    (set_attr "type" "*,vecperm")])
2486 ;; On systems with LDBRX/STDBRX generate the loads/stores directly, just like
2487 ;; we do for L{H,W}BRX and ST{H,W}BRX above.  If not, we have to generate more
2488 ;; complex code.
2490 (define_expand "bswapdi2"
2491   [(parallel [(set (match_operand:DI 0 "reg_or_mem_operand")
2492                    (bswap:DI
2493                     (match_operand:DI 1 "reg_or_mem_operand")))
2494               (clobber (match_scratch:DI 2))
2495               (clobber (match_scratch:DI 3))])]
2496   ""
2498   rtx dest = operands[0];
2499   rtx src = operands[1];
2501   if (!REG_P (dest) && !REG_P (src))
2502     operands[1] = src = force_reg (DImode, src);
2504   if (TARGET_POWERPC64 && TARGET_LDBRX)
2505     {
2506       if (MEM_P (src))
2507         {
2508           src = rs6000_force_indexed_or_indirect_mem (src);
2509           emit_insn (gen_bswapdi2_load (dest, src));
2510         }
2511       else if (MEM_P (dest))
2512         {
2513           dest = rs6000_force_indexed_or_indirect_mem (dest);
2514           emit_insn (gen_bswapdi2_store (dest, src));
2515         }
2516       else if (TARGET_P9_VECTOR)
2517         emit_insn (gen_bswapdi2_xxbrd (dest, src));
2518       else
2519         emit_insn (gen_bswapdi2_reg (dest, src));
2520       DONE;
2521     }
2523   if (!TARGET_POWERPC64)
2524     {
2525       /* 32-bit mode needs fewer scratch registers, but 32-bit addressing mode
2526          that uses 64-bit registers needs the same scratch registers as 64-bit
2527          mode.  */
2528       emit_insn (gen_bswapdi2_32bit (dest, src));
2529       DONE;
2530     }
2533 ;; Power7/cell has ldbrx/stdbrx, so use it directly
2534 (define_insn "bswapdi2_load"
2535   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2536         (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand" "Z")))]
2537   "TARGET_POWERPC64 && TARGET_LDBRX"
2538   "ldbrx %0,%y1"
2539   [(set_attr "type" "load")])
2541 (define_insn "bswapdi2_store"
2542   [(set (match_operand:DI 0 "indexed_or_indirect_operand" "=Z")
2543         (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "r")))]
2544   "TARGET_POWERPC64 && TARGET_LDBRX"
2545   "stdbrx %1,%y0"
2546   [(set_attr "type" "store")])
2548 (define_insn "bswapdi2_xxbrd"
2549   [(set (match_operand:DI 0 "gpc_reg_operand" "=wo")
2550         (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "wo")))]
2551   "TARGET_P9_VECTOR"
2552   "xxbrd %x0,%x1"
2553   [(set_attr "type" "vecperm")])
2555 (define_insn "bswapdi2_reg"
2556   [(set (match_operand:DI 0 "gpc_reg_operand" "=&r")
2557         (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "r")))
2558    (clobber (match_scratch:DI 2 "=&r"))
2559    (clobber (match_scratch:DI 3 "=&r"))]
2560   "TARGET_POWERPC64 && TARGET_LDBRX && !TARGET_P9_VECTOR"
2561   "#"
2562   [(set_attr "length" "36")])
2564 ;; Non-power7/cell, fall back to use lwbrx/stwbrx
2565 (define_insn "*bswapdi2_64bit"
2566   [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,&r")
2567         (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2568    (clobber (match_scratch:DI 2 "=&b,&b,&r"))
2569    (clobber (match_scratch:DI 3 "=&r,&r,&r"))]
2570   "TARGET_POWERPC64 && !TARGET_LDBRX
2571    && (REG_P (operands[0]) || REG_P (operands[1]))
2572    && !(MEM_P (operands[0]) && MEM_VOLATILE_P (operands[0]))
2573    && !(MEM_P (operands[1]) && MEM_VOLATILE_P (operands[1]))"
2574   "#"
2575   [(set_attr "length" "16,12,36")])
2577 (define_split
2578   [(set (match_operand:DI 0 "gpc_reg_operand")
2579         (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand")))
2580    (clobber (match_operand:DI 2 "gpc_reg_operand"))
2581    (clobber (match_operand:DI 3 "gpc_reg_operand"))]
2582   "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2583   [(const_int 0)]
2585   rtx dest   = operands[0];
2586   rtx src    = operands[1];
2587   rtx op2    = operands[2];
2588   rtx op3    = operands[3];
2589   rtx op3_32 = simplify_gen_subreg (SImode, op3, DImode,
2590                                     BYTES_BIG_ENDIAN ? 4 : 0);
2591   rtx dest_32 = simplify_gen_subreg (SImode, dest, DImode,
2592                                      BYTES_BIG_ENDIAN ? 4 : 0);
2593   rtx addr1;
2594   rtx addr2;
2595   rtx word1;
2596   rtx word2;
2598   addr1 = XEXP (src, 0);
2599   if (GET_CODE (addr1) == PLUS)
2600     {
2601       emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2602       if (TARGET_AVOID_XFORM)
2603         {
2604           emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2605           addr2 = op2;
2606         }
2607       else
2608         addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2609     }
2610   else if (TARGET_AVOID_XFORM)
2611     {
2612       emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2613       addr2 = op2;
2614     }
2615   else
2616     {
2617       emit_move_insn (op2, GEN_INT (4));
2618       addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2619     }
2621   word1 = change_address (src, SImode, addr1);
2622   word2 = change_address (src, SImode, addr2);
2624   if (BYTES_BIG_ENDIAN)
2625     {
2626       emit_insn (gen_bswapsi2 (op3_32, word2));
2627       emit_insn (gen_bswapsi2 (dest_32, word1));
2628     }
2629   else
2630     {
2631       emit_insn (gen_bswapsi2 (op3_32, word1));
2632       emit_insn (gen_bswapsi2 (dest_32, word2));
2633     }
2635   emit_insn (gen_ashldi3 (op3, op3, GEN_INT (32)));
2636   emit_insn (gen_iordi3 (dest, dest, op3));
2637   DONE;
2640 (define_split
2641   [(set (match_operand:DI 0 "indexed_or_indirect_operand")
2642         (bswap:DI (match_operand:DI 1 "gpc_reg_operand")))
2643    (clobber (match_operand:DI 2 "gpc_reg_operand"))
2644    (clobber (match_operand:DI 3 "gpc_reg_operand"))]
2645   "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2646   [(const_int 0)]
2648   rtx dest   = operands[0];
2649   rtx src    = operands[1];
2650   rtx op2    = operands[2];
2651   rtx op3    = operands[3];
2652   rtx src_si = simplify_gen_subreg (SImode, src, DImode,
2653                                     BYTES_BIG_ENDIAN ? 4 : 0);
2654   rtx op3_si = simplify_gen_subreg (SImode, op3, DImode,
2655                                     BYTES_BIG_ENDIAN ? 4 : 0);
2656   rtx addr1;
2657   rtx addr2;
2658   rtx word1;
2659   rtx word2;
2661   addr1 = XEXP (dest, 0);
2662   if (GET_CODE (addr1) == PLUS)
2663     {
2664       emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2665       if (TARGET_AVOID_XFORM)
2666         {
2667           emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2668           addr2 = op2;
2669         }
2670       else
2671         addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2672     }
2673   else if (TARGET_AVOID_XFORM)
2674     {
2675       emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2676       addr2 = op2;
2677     }
2678   else
2679     {
2680       emit_move_insn (op2, GEN_INT (4));
2681       addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2682     }
2684   word1 = change_address (dest, SImode, addr1);
2685   word2 = change_address (dest, SImode, addr2);
2687   emit_insn (gen_lshrdi3 (op3, src, GEN_INT (32)));
2689   if (BYTES_BIG_ENDIAN)
2690     {
2691       emit_insn (gen_bswapsi2 (word1, src_si));
2692       emit_insn (gen_bswapsi2 (word2, op3_si));
2693     }
2694   else
2695     {
2696       emit_insn (gen_bswapsi2 (word2, src_si));
2697       emit_insn (gen_bswapsi2 (word1, op3_si));
2698     }
2699   DONE;
2702 (define_split
2703   [(set (match_operand:DI 0 "gpc_reg_operand")
2704         (bswap:DI (match_operand:DI 1 "gpc_reg_operand")))
2705    (clobber (match_operand:DI 2 "gpc_reg_operand"))
2706    (clobber (match_operand:DI 3 "gpc_reg_operand"))]
2707   "TARGET_POWERPC64 && !TARGET_P9_VECTOR && reload_completed"
2708   [(const_int 0)]
2710   rtx dest    = operands[0];
2711   rtx src     = operands[1];
2712   rtx op2     = operands[2];
2713   rtx op3     = operands[3];
2714   int lo_off  = BYTES_BIG_ENDIAN ? 4 : 0;
2715   rtx dest_si = simplify_gen_subreg (SImode, dest, DImode, lo_off);
2716   rtx src_si  = simplify_gen_subreg (SImode, src, DImode, lo_off);
2717   rtx op2_si  = simplify_gen_subreg (SImode, op2, DImode, lo_off);
2718   rtx op3_si  = simplify_gen_subreg (SImode, op3, DImode, lo_off);
2720   emit_insn (gen_lshrdi3 (op2, src, GEN_INT (32)));
2721   emit_insn (gen_bswapsi2 (dest_si, src_si));
2722   emit_insn (gen_bswapsi2 (op3_si, op2_si));
2723   emit_insn (gen_ashldi3 (dest, dest, GEN_INT (32)));
2724   emit_insn (gen_iordi3 (dest, dest, op3));
2725   DONE;
2728 (define_insn "bswapdi2_32bit"
2729   [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,?&r")
2730         (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2731    (clobber (match_scratch:SI 2 "=&b,&b,X"))]
2732   "!TARGET_POWERPC64 && (REG_P (operands[0]) || REG_P (operands[1]))"
2733   "#"
2734   [(set_attr "length" "16,12,36")])
2736 (define_split
2737   [(set (match_operand:DI 0 "gpc_reg_operand")
2738         (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand")))
2739    (clobber (match_operand:SI 2 "gpc_reg_operand"))]
2740   "!TARGET_POWERPC64 && reload_completed"
2741   [(const_int 0)]
2743   rtx dest  = operands[0];
2744   rtx src   = operands[1];
2745   rtx op2   = operands[2];
2746   rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
2747   rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
2748   rtx addr1;
2749   rtx addr2;
2750   rtx word1;
2751   rtx word2;
2753   addr1 = XEXP (src, 0);
2754   if (GET_CODE (addr1) == PLUS)
2755     {
2756       emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2757       if (TARGET_AVOID_XFORM
2758           || REGNO (XEXP (addr1, 1)) == REGNO (dest2))
2759         {
2760           emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2761           addr2 = op2;
2762         }
2763       else
2764         addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
2765     }
2766   else if (TARGET_AVOID_XFORM
2767            || REGNO (addr1) == REGNO (dest2))
2768     {
2769       emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2770       addr2 = op2;
2771     }
2772   else
2773     {
2774       emit_move_insn (op2, GEN_INT (4));
2775       addr2 = gen_rtx_PLUS (SImode, op2, addr1);
2776     }
2778   word1 = change_address (src, SImode, addr1);
2779   word2 = change_address (src, SImode, addr2);
2781   emit_insn (gen_bswapsi2 (dest2, word1));
2782   /* The REGNO (dest2) tests above ensure that addr2 has not been trashed,
2783      thus allowing us to omit an early clobber on the output.  */
2784   emit_insn (gen_bswapsi2 (dest1, word2));
2785   DONE;
2788 (define_split
2789   [(set (match_operand:DI 0 "indexed_or_indirect_operand")
2790         (bswap:DI (match_operand:DI 1 "gpc_reg_operand")))
2791    (clobber (match_operand:SI 2 "gpc_reg_operand"))]
2792   "!TARGET_POWERPC64 && reload_completed"
2793   [(const_int 0)]
2795   rtx dest = operands[0];
2796   rtx src  = operands[1];
2797   rtx op2  = operands[2];
2798   rtx src1 = simplify_gen_subreg (SImode, src, DImode, 0);
2799   rtx src2 = simplify_gen_subreg (SImode, src, DImode, 4);
2800   rtx addr1;
2801   rtx addr2;
2802   rtx word1;
2803   rtx word2;
2805   addr1 = XEXP (dest, 0);
2806   if (GET_CODE (addr1) == PLUS)
2807     {
2808       emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2809       if (TARGET_AVOID_XFORM)
2810         {
2811           emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2812           addr2 = op2;
2813         }
2814       else
2815         addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
2816     }
2817   else if (TARGET_AVOID_XFORM)
2818     {
2819       emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2820       addr2 = op2;
2821     }
2822   else
2823     {
2824       emit_move_insn (op2, GEN_INT (4));
2825       addr2 = gen_rtx_PLUS (SImode, op2, addr1);
2826     }
2828   word1 = change_address (dest, SImode, addr1);
2829   word2 = change_address (dest, SImode, addr2);
2831   emit_insn (gen_bswapsi2 (word2, src1));
2832   emit_insn (gen_bswapsi2 (word1, src2));
2833   DONE;
2836 (define_split
2837   [(set (match_operand:DI 0 "gpc_reg_operand")
2838         (bswap:DI (match_operand:DI 1 "gpc_reg_operand")))
2839    (clobber (match_operand:SI 2 ""))]
2840   "!TARGET_POWERPC64 && reload_completed"
2841   [(const_int 0)]
2843   rtx dest  = operands[0];
2844   rtx src   = operands[1];
2845   rtx src1  = simplify_gen_subreg (SImode, src, DImode, 0);
2846   rtx src2  = simplify_gen_subreg (SImode, src, DImode, 4);
2847   rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
2848   rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
2850   emit_insn (gen_bswapsi2 (dest1, src2));
2851   emit_insn (gen_bswapsi2 (dest2, src1));
2852   DONE;
2856 (define_insn "mul<mode>3"
2857   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2858         (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
2859                   (match_operand:GPR 2 "reg_or_short_operand" "r,I")))]
2860   ""
2861   "@
2862    mull<wd> %0,%1,%2
2863    mulli %0,%1,%2"
2864    [(set_attr "type" "mul")
2865     (set (attr "size")
2866       (cond [(match_operand:GPR 2 "s8bit_cint_operand")
2867                 (const_string "8")
2868              (match_operand:GPR 2 "short_cint_operand")
2869                 (const_string "16")]
2870         (const_string "<bits>")))])
2872 (define_insn_and_split "*mul<mode>3_dot"
2873   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2874         (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2875                               (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
2876                     (const_int 0)))
2877    (clobber (match_scratch:GPR 0 "=r,r"))]
2878   "<MODE>mode == Pmode"
2879   "@
2880    mull<wd>. %0,%1,%2
2881    #"
2882   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2883   [(set (match_dup 0)
2884         (mult:GPR (match_dup 1)
2885                   (match_dup 2)))
2886    (set (match_dup 3)
2887         (compare:CC (match_dup 0)
2888                     (const_int 0)))]
2889   ""
2890   [(set_attr "type" "mul")
2891    (set_attr "size" "<bits>")
2892    (set_attr "dot" "yes")
2893    (set_attr "length" "4,8")])
2895 (define_insn_and_split "*mul<mode>3_dot2"
2896   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2897         (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2898                               (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
2899                     (const_int 0)))
2900    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2901         (mult:GPR (match_dup 1)
2902                   (match_dup 2)))]
2903   "<MODE>mode == Pmode"
2904   "@
2905    mull<wd>. %0,%1,%2
2906    #"
2907   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2908   [(set (match_dup 0)
2909         (mult:GPR (match_dup 1)
2910                   (match_dup 2)))
2911    (set (match_dup 3)
2912         (compare:CC (match_dup 0)
2913                     (const_int 0)))]
2914   ""
2915   [(set_attr "type" "mul")
2916    (set_attr "size" "<bits>")
2917    (set_attr "dot" "yes")
2918    (set_attr "length" "4,8")])
2921 (define_expand "<su>mul<mode>3_highpart"
2922   [(set (match_operand:GPR 0 "gpc_reg_operand")
2923         (subreg:GPR
2924           (mult:<DMODE> (any_extend:<DMODE>
2925                           (match_operand:GPR 1 "gpc_reg_operand"))
2926                         (any_extend:<DMODE>
2927                           (match_operand:GPR 2 "gpc_reg_operand")))
2928          0))]
2929   ""
2931   if (<MODE>mode == SImode && TARGET_POWERPC64)
2932     {
2933       emit_insn (gen_<su>mulsi3_highpart_64 (operands[0], operands[1],
2934                                              operands[2]));
2935       DONE;
2936     }
2938   if (!WORDS_BIG_ENDIAN)
2939     {
2940       emit_insn (gen_<su>mul<mode>3_highpart_le (operands[0], operands[1],
2941                                                  operands[2]));
2942       DONE;
2943     }
2946 (define_insn "*<su>mul<mode>3_highpart"
2947   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2948         (subreg:GPR
2949           (mult:<DMODE> (any_extend:<DMODE>
2950                           (match_operand:GPR 1 "gpc_reg_operand" "r"))
2951                         (any_extend:<DMODE>
2952                           (match_operand:GPR 2 "gpc_reg_operand" "r")))
2953          0))]
2954   "WORDS_BIG_ENDIAN && !(<MODE>mode == SImode && TARGET_POWERPC64)"
2955   "mulh<wd><u> %0,%1,%2"
2956   [(set_attr "type" "mul")
2957    (set_attr "size" "<bits>")])
2959 (define_insn "<su>mulsi3_highpart_le"
2960   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2961         (subreg:SI
2962           (mult:DI (any_extend:DI
2963                      (match_operand:SI 1 "gpc_reg_operand" "r"))
2964                    (any_extend:DI
2965                      (match_operand:SI 2 "gpc_reg_operand" "r")))
2966          4))]
2967   "!WORDS_BIG_ENDIAN && !TARGET_POWERPC64"
2968   "mulhw<u> %0,%1,%2"
2969   [(set_attr "type" "mul")])
2971 (define_insn "<su>muldi3_highpart_le"
2972   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2973         (subreg:DI
2974           (mult:TI (any_extend:TI
2975                      (match_operand:DI 1 "gpc_reg_operand" "r"))
2976                    (any_extend:TI
2977                      (match_operand:DI 2 "gpc_reg_operand" "r")))
2978          8))]
2979   "!WORDS_BIG_ENDIAN && TARGET_POWERPC64"
2980   "mulhd<u> %0,%1,%2"
2981   [(set_attr "type" "mul")
2982    (set_attr "size" "64")])
2984 (define_insn "<su>mulsi3_highpart_64"
2985   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2986         (truncate:SI
2987           (lshiftrt:DI
2988             (mult:DI (any_extend:DI
2989                        (match_operand:SI 1 "gpc_reg_operand" "r"))
2990                      (any_extend:DI
2991                        (match_operand:SI 2 "gpc_reg_operand" "r")))
2992             (const_int 32))))]
2993   "TARGET_POWERPC64"
2994   "mulhw<u> %0,%1,%2"
2995   [(set_attr "type" "mul")])
2997 (define_expand "<u>mul<mode><dmode>3"
2998   [(set (match_operand:<DMODE> 0 "gpc_reg_operand")
2999         (mult:<DMODE> (any_extend:<DMODE>
3000                         (match_operand:GPR 1 "gpc_reg_operand"))
3001                       (any_extend:<DMODE>
3002                         (match_operand:GPR 2 "gpc_reg_operand"))))]
3003   "!(<MODE>mode == SImode && TARGET_POWERPC64)"
3005   rtx l = gen_reg_rtx (<MODE>mode);
3006   rtx h = gen_reg_rtx (<MODE>mode);
3007   emit_insn (gen_mul<mode>3 (l, operands[1], operands[2]));
3008   emit_insn (gen_<su>mul<mode>3_highpart (h, operands[1], operands[2]));
3009   emit_move_insn (gen_lowpart (<MODE>mode, operands[0]), l);
3010   emit_move_insn (gen_highpart (<MODE>mode, operands[0]), h);
3011   DONE;
3014 (define_insn "*maddld4"
3015   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3016         (plus:DI (mult:DI (match_operand:DI 1 "gpc_reg_operand" "r")
3017                           (match_operand:DI 2 "gpc_reg_operand" "r"))
3018                  (match_operand:DI 3 "gpc_reg_operand" "r")))]
3019   "TARGET_MADDLD"
3020   "maddld %0,%1,%2,%3"
3021   [(set_attr "type" "mul")])
3023 (define_insn "udiv<mode>3"
3024   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3025         (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3026                   (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3027   ""
3028   "div<wd>u %0,%1,%2"
3029   [(set_attr "type" "div")
3030    (set_attr "size" "<bits>")])
3033 ;; For powers of two we can do sra[wd]i/addze for divide and then adjust for
3034 ;; modulus.  If it isn't a power of two, force operands into register and do
3035 ;; a normal divide.
3036 (define_expand "div<mode>3"
3037   [(set (match_operand:GPR 0 "gpc_reg_operand")
3038         (div:GPR (match_operand:GPR 1 "gpc_reg_operand")
3039                  (match_operand:GPR 2 "reg_or_cint_operand")))]
3040   ""
3042   if (CONST_INT_P (operands[2])
3043       && INTVAL (operands[2]) > 0
3044       && exact_log2 (INTVAL (operands[2])) >= 0)
3045     {
3046       emit_insn (gen_div<mode>3_sra (operands[0], operands[1], operands[2]));
3047       DONE;
3048     }
3050   operands[2] = force_reg (<MODE>mode, operands[2]);
3053 (define_insn "*div<mode>3"
3054   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3055         (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3056                  (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3057   ""
3058   "div<wd> %0,%1,%2"
3059   [(set_attr "type" "div")
3060    (set_attr "size" "<bits>")])
3062 (define_insn "div<mode>3_sra"
3063   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3064         (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3065                  (match_operand:GPR 2 "exact_log2_cint_operand" "N")))
3066    (clobber (reg:GPR CA_REGNO))]
3067   ""
3068   "sra<wd>i %0,%1,%p2\;addze %0,%0"
3069   [(set_attr "type" "two")
3070    (set_attr "length" "8")])
3072 (define_insn_and_split "*div<mode>3_sra_dot"
3073   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3074         (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3075                              (match_operand:GPR 2 "exact_log2_cint_operand" "N,N"))
3076                     (const_int 0)))
3077    (clobber (match_scratch:GPR 0 "=r,r"))
3078    (clobber (reg:GPR CA_REGNO))]
3079   "<MODE>mode == Pmode"
3080   "@
3081    sra<wd>i %0,%1,%p2\;addze. %0,%0
3082    #"
3083   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3084   [(parallel [(set (match_dup 0)
3085                    (div:GPR (match_dup 1)
3086                             (match_dup 2)))
3087               (clobber (reg:GPR CA_REGNO))])
3088    (set (match_dup 3)
3089         (compare:CC (match_dup 0)
3090                     (const_int 0)))]
3091   ""
3092   [(set_attr "type" "two")
3093    (set_attr "length" "8,12")
3094    (set_attr "cell_micro" "not")])
3096 (define_insn_and_split "*div<mode>3_sra_dot2"
3097   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3098         (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3099                              (match_operand:GPR 2 "exact_log2_cint_operand" "N,N"))
3100                     (const_int 0)))
3101    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3102         (div:GPR (match_dup 1)
3103                  (match_dup 2)))
3104    (clobber (reg:GPR CA_REGNO))]
3105   "<MODE>mode == Pmode"
3106   "@
3107    sra<wd>i %0,%1,%p2\;addze. %0,%0
3108    #"
3109   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3110   [(parallel [(set (match_dup 0)
3111                    (div:GPR (match_dup 1)
3112                             (match_dup 2)))
3113               (clobber (reg:GPR CA_REGNO))])
3114    (set (match_dup 3)
3115         (compare:CC (match_dup 0)
3116                     (const_int 0)))]
3117   ""
3118   [(set_attr "type" "two")
3119    (set_attr "length" "8,12")
3120    (set_attr "cell_micro" "not")])
3122 (define_expand "mod<mode>3"
3123   [(set (match_operand:GPR 0 "gpc_reg_operand")
3124         (mod:GPR (match_operand:GPR 1 "gpc_reg_operand")
3125                  (match_operand:GPR 2 "reg_or_cint_operand")))]
3126   ""
3128   int i;
3129   rtx temp1;
3130   rtx temp2;
3132   if (GET_CODE (operands[2]) != CONST_INT
3133       || INTVAL (operands[2]) <= 0
3134       || (i = exact_log2 (INTVAL (operands[2]))) < 0)
3135     {
3136       if (!TARGET_MODULO)
3137         FAIL;
3139       operands[2] = force_reg (<MODE>mode, operands[2]);
3140     }
3141   else
3142     {
3143       temp1 = gen_reg_rtx (<MODE>mode);
3144       temp2 = gen_reg_rtx (<MODE>mode);
3146       emit_insn (gen_div<mode>3 (temp1, operands[1], operands[2]));
3147       emit_insn (gen_ashl<mode>3 (temp2, temp1, GEN_INT (i)));
3148       emit_insn (gen_sub<mode>3 (operands[0], operands[1], temp2));
3149       DONE;
3150     }
3153 ;; In order to enable using a peephole2 for combining div/mod to eliminate the
3154 ;; mod, prefer putting the result of mod into a different register
3155 (define_insn "*mod<mode>3"
3156   [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
3157         (mod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3158                  (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3159   "TARGET_MODULO"
3160   "mods<wd> %0,%1,%2"
3161   [(set_attr "type" "div")
3162    (set_attr "size" "<bits>")])
3165 (define_insn "umod<mode>3"
3166   [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
3167         (umod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3168                   (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3169   "TARGET_MODULO"
3170   "modu<wd> %0,%1,%2"
3171   [(set_attr "type" "div")
3172    (set_attr "size" "<bits>")])
3174 ;; On machines with modulo support, do a combined div/mod the old fashioned
3175 ;; method, since the multiply/subtract is faster than doing the mod instruction
3176 ;; after a divide.
3178 (define_peephole2
3179   [(set (match_operand:GPR 0 "gpc_reg_operand")
3180         (div:GPR (match_operand:GPR 1 "gpc_reg_operand")
3181                  (match_operand:GPR 2 "gpc_reg_operand")))
3182    (set (match_operand:GPR 3 "gpc_reg_operand")
3183         (mod:GPR (match_dup 1)
3184                  (match_dup 2)))]
3185   "TARGET_MODULO
3186    && ! reg_mentioned_p (operands[0], operands[1])
3187    && ! reg_mentioned_p (operands[0], operands[2])
3188    && ! reg_mentioned_p (operands[3], operands[1])
3189    && ! reg_mentioned_p (operands[3], operands[2])"
3190   [(set (match_dup 0)
3191         (div:GPR (match_dup 1)
3192                  (match_dup 2)))
3193    (set (match_dup 3)
3194         (mult:GPR (match_dup 0)
3195                   (match_dup 2)))
3196    (set (match_dup 3)
3197         (minus:GPR (match_dup 1)
3198                    (match_dup 3)))])
3200 (define_peephole2
3201   [(set (match_operand:GPR 0 "gpc_reg_operand")
3202         (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand")
3203                   (match_operand:GPR 2 "gpc_reg_operand")))
3204    (set (match_operand:GPR 3 "gpc_reg_operand")
3205         (umod:GPR (match_dup 1)
3206                   (match_dup 2)))]
3207   "TARGET_MODULO
3208    && ! reg_mentioned_p (operands[0], operands[1])
3209    && ! reg_mentioned_p (operands[0], operands[2])
3210    && ! reg_mentioned_p (operands[3], operands[1])
3211    && ! reg_mentioned_p (operands[3], operands[2])"
3212   [(set (match_dup 0)
3213         (udiv:GPR (match_dup 1)
3214                   (match_dup 2)))
3215    (set (match_dup 3)
3216         (mult:GPR (match_dup 0)
3217                   (match_dup 2)))
3218    (set (match_dup 3)
3219         (minus:GPR (match_dup 1)
3220                    (match_dup 3)))])
3223 ;; Logical instructions
3224 ;; The logical instructions are mostly combined by using match_operator,
3225 ;; but the plain AND insns are somewhat different because there is no
3226 ;; plain 'andi' (only 'andi.'), no plain 'andis', and there are all
3227 ;; those rotate-and-mask operations.  Thus, the AND insns come first.
3229 (define_expand "and<mode>3"
3230   [(set (match_operand:SDI 0 "gpc_reg_operand")
3231         (and:SDI (match_operand:SDI 1 "gpc_reg_operand")
3232                  (match_operand:SDI 2 "reg_or_cint_operand")))]
3233   ""
3235   if (<MODE>mode == DImode && !TARGET_POWERPC64)
3236     {
3237       rs6000_split_logical (operands, AND, false, false, false);
3238       DONE;
3239     }
3241   if (CONST_INT_P (operands[2]))
3242     {
3243       if (rs6000_is_valid_and_mask (operands[2], <MODE>mode))
3244         {
3245           emit_insn (gen_and<mode>3_mask (operands[0], operands[1], operands[2]));
3246           DONE;
3247         }
3249       if (logical_const_operand (operands[2], <MODE>mode))
3250         {
3251           emit_insn (gen_and<mode>3_imm (operands[0], operands[1], operands[2]));
3252           DONE;
3253         }
3255       if (rs6000_is_valid_2insn_and (operands[2], <MODE>mode))
3256         {
3257           rs6000_emit_2insn_and (<MODE>mode, operands, true, 0);
3258           DONE;
3259         }
3261       operands[2] = force_reg (<MODE>mode, operands[2]);
3262     }
3266 (define_insn "and<mode>3_imm"
3267   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3268         (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3269                  (match_operand:GPR 2 "logical_const_operand" "n")))
3270    (clobber (match_scratch:CC 3 "=x"))]
3271   "!rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3272   "andi%e2. %0,%1,%u2"
3273   [(set_attr "type" "logical")
3274    (set_attr "dot" "yes")])
3276 (define_insn_and_split "*and<mode>3_imm_dot"
3277   [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3278         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3279                              (match_operand:GPR 2 "logical_const_operand" "n,n"))
3280                     (const_int 0)))
3281    (clobber (match_scratch:GPR 0 "=r,r"))
3282    (clobber (match_scratch:CC 4 "=X,x"))]
3283   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3284    && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3285   "@
3286    andi%e2. %0,%1,%u2
3287    #"
3288   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3289   [(parallel [(set (match_dup 0)
3290                    (and:GPR (match_dup 1)
3291                             (match_dup 2)))
3292               (clobber (match_dup 4))])
3293    (set (match_dup 3)
3294         (compare:CC (match_dup 0)
3295                     (const_int 0)))]
3296   ""
3297   [(set_attr "type" "logical")
3298    (set_attr "dot" "yes")
3299    (set_attr "length" "4,8")])
3301 (define_insn_and_split "*and<mode>3_imm_dot2"
3302   [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3303         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3304                              (match_operand:GPR 2 "logical_const_operand" "n,n"))
3305                     (const_int 0)))
3306    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3307         (and:GPR (match_dup 1)
3308                  (match_dup 2)))
3309    (clobber (match_scratch:CC 4 "=X,x"))]
3310   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3311    && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3312   "@
3313    andi%e2. %0,%1,%u2
3314    #"
3315   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3316   [(parallel [(set (match_dup 0)
3317                    (and:GPR (match_dup 1)
3318                             (match_dup 2)))
3319               (clobber (match_dup 4))])
3320    (set (match_dup 3)
3321         (compare:CC (match_dup 0)
3322                     (const_int 0)))]
3323   ""
3324   [(set_attr "type" "logical")
3325    (set_attr "dot" "yes")
3326    (set_attr "length" "4,8")])
3328 (define_insn_and_split "*and<mode>3_imm_mask_dot"
3329   [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3330         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3331                              (match_operand:GPR 2 "logical_const_operand" "n,n"))
3332                     (const_int 0)))
3333    (clobber (match_scratch:GPR 0 "=r,r"))]
3334   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3335    && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3336   "@
3337    andi%e2. %0,%1,%u2
3338    #"
3339   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3340   [(set (match_dup 0)
3341         (and:GPR (match_dup 1)
3342                  (match_dup 2)))
3343    (set (match_dup 3)
3344         (compare:CC (match_dup 0)
3345                     (const_int 0)))]
3346   ""
3347   [(set_attr "type" "logical")
3348    (set_attr "dot" "yes")
3349    (set_attr "length" "4,8")])
3351 (define_insn_and_split "*and<mode>3_imm_mask_dot2"
3352   [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3353         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3354                              (match_operand:GPR 2 "logical_const_operand" "n,n"))
3355                     (const_int 0)))
3356    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3357         (and:GPR (match_dup 1)
3358                  (match_dup 2)))]
3359   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3360    && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3361   "@
3362    andi%e2. %0,%1,%u2
3363    #"
3364   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3365   [(set (match_dup 0)
3366         (and:GPR (match_dup 1)
3367                  (match_dup 2)))
3368    (set (match_dup 3)
3369         (compare:CC (match_dup 0)
3370                     (const_int 0)))]
3371   ""
3372   [(set_attr "type" "logical")
3373    (set_attr "dot" "yes")
3374    (set_attr "length" "4,8")])
3376 (define_insn "*and<mode>3_imm_dot_shifted"
3377   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
3378         (compare:CC
3379           (and:GPR
3380             (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3381                           (match_operand:SI 4 "const_int_operand" "n"))
3382             (match_operand:GPR 2 "const_int_operand" "n"))
3383           (const_int 0)))
3384    (clobber (match_scratch:GPR 0 "=r"))]
3385   "logical_const_operand (GEN_INT (UINTVAL (operands[2])
3386                                    << INTVAL (operands[4])),
3387                           DImode)
3388    && (<MODE>mode == Pmode
3389        || (UINTVAL (operands[2]) << INTVAL (operands[4])) <= 0x7fffffff)"
3391   operands[2] = GEN_INT (UINTVAL (operands[2]) << INTVAL (operands[4]));
3392   return "andi%e2. %0,%1,%u2";
3394   [(set_attr "type" "logical")
3395    (set_attr "dot" "yes")])
3398 (define_insn "and<mode>3_mask"
3399   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3400         (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3401                  (match_operand:GPR 2 "const_int_operand" "n")))]
3402   "rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3404   return rs6000_insn_for_and_mask (<MODE>mode, operands, false);
3406   [(set_attr "type" "shift")])
3408 (define_insn_and_split "*and<mode>3_mask_dot"
3409   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3410         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3411                              (match_operand:GPR 2 "const_int_operand" "n,n"))
3412                     (const_int 0)))
3413    (clobber (match_scratch:GPR 0 "=r,r"))]
3414   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3415    && !logical_const_operand (operands[2], <MODE>mode)
3416    && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3418   if (which_alternative == 0)
3419     return rs6000_insn_for_and_mask (<MODE>mode, operands, true);
3420   else
3421     return "#";
3423   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3424   [(set (match_dup 0)
3425         (and:GPR (match_dup 1)
3426                  (match_dup 2)))
3427    (set (match_dup 3)
3428         (compare:CC (match_dup 0)
3429                     (const_int 0)))]
3430   ""
3431   [(set_attr "type" "shift")
3432    (set_attr "dot" "yes")
3433    (set_attr "length" "4,8")])
3435 (define_insn_and_split "*and<mode>3_mask_dot2"
3436   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3437         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3438                              (match_operand:GPR 2 "const_int_operand" "n,n"))
3439                     (const_int 0)))
3440    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3441         (and:GPR (match_dup 1)
3442                  (match_dup 2)))]
3443   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3444    && !logical_const_operand (operands[2], <MODE>mode)
3445    && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3447   if (which_alternative == 0)
3448     return rs6000_insn_for_and_mask (<MODE>mode, operands, true);
3449   else
3450     return "#";
3452   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3453   [(set (match_dup 0)
3454         (and:GPR (match_dup 1)
3455                  (match_dup 2)))
3456    (set (match_dup 3)
3457         (compare:CC (match_dup 0)
3458                     (const_int 0)))]
3459   ""
3460   [(set_attr "type" "shift")
3461    (set_attr "dot" "yes")
3462    (set_attr "length" "4,8")])
3465 (define_insn_and_split "*and<mode>3_2insn"
3466   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3467         (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3468                  (match_operand:GPR 2 "const_int_operand" "n")))]
3469   "rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3470    && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3471         || logical_const_operand (operands[2], <MODE>mode))"
3472   "#"
3473   "&& 1"
3474   [(pc)]
3476   rs6000_emit_2insn_and (<MODE>mode, operands, false, 0);
3477   DONE;
3479   [(set_attr "type" "shift")
3480    (set_attr "length" "8")])
3482 (define_insn_and_split "*and<mode>3_2insn_dot"
3483   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3484         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3485                              (match_operand:GPR 2 "const_int_operand" "n,n"))
3486                     (const_int 0)))
3487    (clobber (match_scratch:GPR 0 "=r,r"))]
3488   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3489    && rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3490    && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3491         || logical_const_operand (operands[2], <MODE>mode))"
3492   "#"
3493   "&& reload_completed"
3494   [(pc)]
3496   rs6000_emit_2insn_and (<MODE>mode, operands, false, 1);
3497   DONE;
3499   [(set_attr "type" "shift")
3500    (set_attr "dot" "yes")
3501    (set_attr "length" "8,12")])
3503 (define_insn_and_split "*and<mode>3_2insn_dot2"
3504   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3505         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3506                              (match_operand:GPR 2 "const_int_operand" "n,n"))
3507                     (const_int 0)))
3508    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3509         (and:GPR (match_dup 1)
3510                  (match_dup 2)))]
3511   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3512    && rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3513    && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3514         || logical_const_operand (operands[2], <MODE>mode))"
3515   "#"
3516   "&& reload_completed"
3517   [(pc)]
3519   rs6000_emit_2insn_and (<MODE>mode, operands, false, 2);
3520   DONE;
3522   [(set_attr "type" "shift")
3523    (set_attr "dot" "yes")
3524    (set_attr "length" "8,12")])
3527 (define_expand "<code><mode>3"
3528   [(set (match_operand:SDI 0 "gpc_reg_operand")
3529         (iorxor:SDI (match_operand:SDI 1 "gpc_reg_operand")
3530                     (match_operand:SDI 2 "reg_or_cint_operand")))]
3531   ""
3533   if (<MODE>mode == DImode && !TARGET_POWERPC64)
3534     {
3535       rs6000_split_logical (operands, <CODE>, false, false, false);
3536       DONE;
3537     }
3539   if (non_logical_cint_operand (operands[2], <MODE>mode))
3540     {
3541       rtx tmp = ((!can_create_pseudo_p ()
3542                   || rtx_equal_p (operands[0], operands[1]))
3543                  ? operands[0] : gen_reg_rtx (<MODE>mode));
3545       HOST_WIDE_INT value = INTVAL (operands[2]);
3546       HOST_WIDE_INT lo = value & 0xffff;
3547       HOST_WIDE_INT hi = value - lo;
3549       emit_insn (gen_<code><mode>3 (tmp, operands[1], GEN_INT (hi)));
3550       emit_insn (gen_<code><mode>3 (operands[0], tmp, GEN_INT (lo)));
3551       DONE;
3552     }
3554   if (!reg_or_logical_cint_operand (operands[2], <MODE>mode))
3555     operands[2] = force_reg (<MODE>mode, operands[2]);
3558 (define_split
3559   [(set (match_operand:GPR 0 "gpc_reg_operand")
3560         (iorxor:GPR (match_operand:GPR 1 "gpc_reg_operand")
3561                     (match_operand:GPR 2 "non_logical_cint_operand")))]
3562   ""
3563   [(set (match_dup 3)
3564         (iorxor:GPR (match_dup 1)
3565                     (match_dup 4)))
3566    (set (match_dup 0)
3567         (iorxor:GPR (match_dup 3)
3568                     (match_dup 5)))]
3570   operands[3] = ((!can_create_pseudo_p ()
3571                   || rtx_equal_p (operands[0], operands[1]))
3572                  ? operands[0] : gen_reg_rtx (<MODE>mode));
3574   HOST_WIDE_INT value = INTVAL (operands[2]);
3575   HOST_WIDE_INT lo = value & 0xffff;
3576   HOST_WIDE_INT hi = value - lo;
3578   operands[4] = GEN_INT (hi);
3579   operands[5] = GEN_INT (lo);
3582 (define_insn "*bool<mode>3_imm"
3583   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3584         (match_operator:GPR 3 "boolean_or_operator"
3585          [(match_operand:GPR 1 "gpc_reg_operand" "%r")
3586           (match_operand:GPR 2 "logical_const_operand" "n")]))]
3587   ""
3588   "%q3i%e2 %0,%1,%u2"
3589   [(set_attr "type" "logical")])
3591 (define_insn "*bool<mode>3"
3592   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3593         (match_operator:GPR 3 "boolean_operator"
3594          [(match_operand:GPR 1 "gpc_reg_operand" "r")
3595           (match_operand:GPR 2 "gpc_reg_operand" "r")]))]
3596   ""
3597   "%q3 %0,%1,%2"
3598   [(set_attr "type" "logical")])
3600 (define_insn_and_split "*bool<mode>3_dot"
3601   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3602         (compare:CC (match_operator:GPR 3 "boolean_operator"
3603          [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3604           (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
3605          (const_int 0)))
3606    (clobber (match_scratch:GPR 0 "=r,r"))]
3607   "<MODE>mode == Pmode"
3608   "@
3609    %q3. %0,%1,%2
3610    #"
3611   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3612   [(set (match_dup 0)
3613         (match_dup 3))
3614    (set (match_dup 4)
3615         (compare:CC (match_dup 0)
3616                     (const_int 0)))]
3617   ""
3618   [(set_attr "type" "logical")
3619    (set_attr "dot" "yes")
3620    (set_attr "length" "4,8")])
3622 (define_insn_and_split "*bool<mode>3_dot2"
3623   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3624         (compare:CC (match_operator:GPR 3 "boolean_operator"
3625          [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3626           (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
3627          (const_int 0)))
3628    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3629         (match_dup 3))]
3630   "<MODE>mode == Pmode"
3631   "@
3632    %q3. %0,%1,%2
3633    #"
3634   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3635   [(set (match_dup 0)
3636         (match_dup 3))
3637    (set (match_dup 4)
3638         (compare:CC (match_dup 0)
3639                     (const_int 0)))]
3640   ""
3641   [(set_attr "type" "logical")
3642    (set_attr "dot" "yes")
3643    (set_attr "length" "4,8")])
3646 (define_insn "*boolc<mode>3"
3647   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3648         (match_operator:GPR 3 "boolean_operator"
3649          [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))
3650           (match_operand:GPR 1 "gpc_reg_operand" "r")]))]
3651   ""
3652   "%q3 %0,%1,%2"
3653   [(set_attr "type" "logical")])
3655 (define_insn_and_split "*boolc<mode>3_dot"
3656   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3657         (compare:CC (match_operator:GPR 3 "boolean_operator"
3658          [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3659           (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
3660          (const_int 0)))
3661    (clobber (match_scratch:GPR 0 "=r,r"))]
3662   "<MODE>mode == Pmode"
3663   "@
3664    %q3. %0,%1,%2
3665    #"
3666   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3667   [(set (match_dup 0)
3668         (match_dup 3))
3669    (set (match_dup 4)
3670         (compare:CC (match_dup 0)
3671                     (const_int 0)))]
3672   ""
3673   [(set_attr "type" "logical")
3674    (set_attr "dot" "yes")
3675    (set_attr "length" "4,8")])
3677 (define_insn_and_split "*boolc<mode>3_dot2"
3678   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3679         (compare:CC (match_operator:GPR 3 "boolean_operator"
3680          [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3681           (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
3682          (const_int 0)))
3683    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3684         (match_dup 3))]
3685   "<MODE>mode == Pmode"
3686   "@
3687    %q3. %0,%1,%2
3688    #"
3689   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3690   [(set (match_dup 0)
3691         (match_dup 3))
3692    (set (match_dup 4)
3693         (compare:CC (match_dup 0)
3694                     (const_int 0)))]
3695   ""
3696   [(set_attr "type" "logical")
3697    (set_attr "dot" "yes")
3698    (set_attr "length" "4,8")])
3701 (define_insn "*boolcc<mode>3"
3702   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3703         (match_operator:GPR 3 "boolean_operator"
3704          [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
3705           (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))]))]
3706   ""
3707   "%q3 %0,%1,%2"
3708   [(set_attr "type" "logical")])
3710 (define_insn_and_split "*boolcc<mode>3_dot"
3711   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3712         (compare:CC (match_operator:GPR 3 "boolean_operator"
3713          [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
3714           (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
3715          (const_int 0)))
3716    (clobber (match_scratch:GPR 0 "=r,r"))]
3717   "<MODE>mode == Pmode"
3718   "@
3719    %q3. %0,%1,%2
3720    #"
3721   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3722   [(set (match_dup 0)
3723         (match_dup 3))
3724    (set (match_dup 4)
3725         (compare:CC (match_dup 0)
3726                     (const_int 0)))]
3727   ""
3728   [(set_attr "type" "logical")
3729    (set_attr "dot" "yes")
3730    (set_attr "length" "4,8")])
3732 (define_insn_and_split "*boolcc<mode>3_dot2"
3733   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3734         (compare:CC (match_operator:GPR 3 "boolean_operator"
3735          [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
3736           (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
3737          (const_int 0)))
3738    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3739         (match_dup 3))]
3740   "<MODE>mode == Pmode"
3741   "@
3742    %q3. %0,%1,%2
3743    #"
3744   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3745   [(set (match_dup 0)
3746         (match_dup 3))
3747    (set (match_dup 4)
3748         (compare:CC (match_dup 0)
3749                     (const_int 0)))]
3750   ""
3751   [(set_attr "type" "logical")
3752    (set_attr "dot" "yes")
3753    (set_attr "length" "4,8")])
3756 ;; TODO: Should have dots of this as well.
3757 (define_insn "*eqv<mode>3"
3758   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3759         (not:GPR (xor:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3760                           (match_operand:GPR 2 "gpc_reg_operand" "r"))))]
3761   ""
3762   "eqv %0,%1,%2"
3763   [(set_attr "type" "logical")])
3765 ;; Rotate-and-mask and insert.
3767 (define_insn "*rotl<mode>3_mask"
3768   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3769         (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3770                   [(match_operand:GPR 1 "gpc_reg_operand" "r")
3771                    (match_operand:SI 2 "reg_or_cint_operand" "rn")])
3772                  (match_operand:GPR 3 "const_int_operand" "n")))]
3773   "rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3775   return rs6000_insn_for_shift_mask (<MODE>mode, operands, false);
3777   [(set_attr "type" "shift")
3778    (set_attr "maybe_var_shift" "yes")])
3780 (define_insn_and_split "*rotl<mode>3_mask_dot"
3781   [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y")
3782         (compare:CC
3783           (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3784                     [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3785                      (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")])
3786                    (match_operand:GPR 3 "const_int_operand" "n,n"))
3787           (const_int 0)))
3788    (clobber (match_scratch:GPR 0 "=r,r"))]
3789   "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff)
3790    && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3792   if (which_alternative == 0)
3793     return rs6000_insn_for_shift_mask (<MODE>mode, operands, true);
3794   else
3795     return "#";
3797   "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)"
3798   [(set (match_dup 0)
3799         (and:GPR (match_dup 4)
3800                  (match_dup 3)))
3801    (set (match_dup 5)
3802         (compare:CC (match_dup 0)
3803                     (const_int 0)))]
3804   ""
3805   [(set_attr "type" "shift")
3806    (set_attr "maybe_var_shift" "yes")
3807    (set_attr "dot" "yes")
3808    (set_attr "length" "4,8")])
3810 (define_insn_and_split "*rotl<mode>3_mask_dot2"
3811   [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y")
3812         (compare:CC
3813           (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3814                     [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3815                      (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")])
3816                    (match_operand:GPR 3 "const_int_operand" "n,n"))
3817           (const_int 0)))
3818    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3819         (and:GPR (match_dup 4)
3820                  (match_dup 3)))]
3821   "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff)
3822    && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3824   if (which_alternative == 0)
3825     return rs6000_insn_for_shift_mask (<MODE>mode, operands, true);
3826   else
3827     return "#";
3829   "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)"
3830   [(set (match_dup 0)
3831         (and:GPR (match_dup 4)
3832                  (match_dup 3)))
3833    (set (match_dup 5)
3834         (compare:CC (match_dup 0)
3835                     (const_int 0)))]
3836   ""
3837   [(set_attr "type" "shift")
3838    (set_attr "maybe_var_shift" "yes")
3839    (set_attr "dot" "yes")
3840    (set_attr "length" "4,8")])
3842 ; Special case for less-than-0.  We can do it with just one machine
3843 ; instruction, but the generic optimizers do not realise it is cheap.
3844 (define_insn "*lt0_<mode>di"
3845   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3846         (lt:GPR (match_operand:DI 1 "gpc_reg_operand" "r")
3847                 (const_int 0)))]
3848   "TARGET_POWERPC64"
3849   "srdi %0,%1,63"
3850   [(set_attr "type" "shift")])
3852 (define_insn "*lt0_<mode>si"
3853   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3854         (lt:GPR (match_operand:SI 1 "gpc_reg_operand" "r")
3855                 (const_int 0)))]
3856   ""
3857   "rlwinm %0,%1,1,31,31"
3858   [(set_attr "type" "shift")])
3862 ; Two forms for insert (the two arms of the IOR are not canonicalized,
3863 ; both are an AND so are the same precedence).
3864 (define_insn "*rotl<mode>3_insert"
3865   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3866         (ior:GPR (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3867                            [(match_operand:GPR 1 "gpc_reg_operand" "r")
3868                             (match_operand:SI 2 "const_int_operand" "n")])
3869                           (match_operand:GPR 3 "const_int_operand" "n"))
3870                  (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0")
3871                           (match_operand:GPR 6 "const_int_operand" "n"))))]
3872   "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode)
3873    && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0"
3875   return rs6000_insn_for_insert_mask (<MODE>mode, operands, false);
3877   [(set_attr "type" "insert")])
3878 ; FIXME: this needs an attr "size", so that the scheduler can see the
3879 ; difference between rlwimi and rldimi.  We also might want dot forms,
3880 ; but not for rlwimi on POWER4 and similar processors.
3882 (define_insn "*rotl<mode>3_insert_2"
3883   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3884         (ior:GPR (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0")
3885                           (match_operand:GPR 6 "const_int_operand" "n"))
3886                  (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3887                            [(match_operand:GPR 1 "gpc_reg_operand" "r")
3888                             (match_operand:SI 2 "const_int_operand" "n")])
3889                           (match_operand:GPR 3 "const_int_operand" "n"))))]
3890   "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode)
3891    && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0"
3893   return rs6000_insn_for_insert_mask (<MODE>mode, operands, false);
3895   [(set_attr "type" "insert")])
3897 ; There are also some forms without one of the ANDs.
3898 (define_insn "*rotl<mode>3_insert_3"
3899   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3900         (ior:GPR (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0")
3901                           (match_operand:GPR 4 "const_int_operand" "n"))
3902                  (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3903                              (match_operand:SI 2 "const_int_operand" "n"))))]
3904   "INTVAL (operands[2]) == exact_log2 (UINTVAL (operands[4]) + 1)"
3906   if (<MODE>mode == SImode)
3907     return "rlwimi %0,%1,%h2,0,31-%h2";
3908   else
3909     return "rldimi %0,%1,%H2,0";
3911   [(set_attr "type" "insert")])
3913 (define_insn "*rotl<mode>3_insert_4"
3914   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3915         (ior:GPR (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0")
3916                           (match_operand:GPR 4 "const_int_operand" "n"))
3917                  (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3918                                (match_operand:SI 2 "const_int_operand" "n"))))]
3919   "<MODE>mode == SImode &&
3920    GET_MODE_PRECISION (<MODE>mode)
3921    == INTVAL (operands[2]) + exact_log2 (-UINTVAL (operands[4]))"
3923   operands[2] = GEN_INT (GET_MODE_PRECISION (<MODE>mode)
3924                          - INTVAL (operands[2]));
3925   if (<MODE>mode == SImode)
3926     return "rlwimi %0,%1,%h2,32-%h2,31";
3927   else
3928     return "rldimi %0,%1,%H2,64-%H2";
3930   [(set_attr "type" "insert")])
3932 (define_insn "*rotlsi3_insert_5"
3933   [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
3934         (ior:SI (and:SI (match_operand:SI 1 "gpc_reg_operand" "0,r")
3935                         (match_operand:SI 2 "const_int_operand" "n,n"))
3936                 (and:SI (match_operand:SI 3 "gpc_reg_operand" "r,0")
3937                         (match_operand:SI 4 "const_int_operand" "n,n"))))]
3938   "rs6000_is_valid_mask (operands[2], NULL, NULL, SImode)
3939    && UINTVAL (operands[2]) != 0 && UINTVAL (operands[4]) != 0
3940    && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
3941   "@
3942    rlwimi %0,%3,0,%4
3943    rlwimi %0,%1,0,%2"
3944   [(set_attr "type" "insert")])
3946 (define_insn "*rotldi3_insert_6"
3947   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3948         (ior:DI (and:DI (match_operand:DI 1 "gpc_reg_operand" "0")
3949                         (match_operand:DI 2 "const_int_operand" "n"))
3950                 (and:DI (match_operand:DI 3 "gpc_reg_operand" "r")
3951                         (match_operand:DI 4 "const_int_operand" "n"))))]
3952   "exact_log2 (-UINTVAL (operands[2])) > 0
3953    && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
3955   operands[5] = GEN_INT (64 - exact_log2 (-UINTVAL (operands[2])));
3956   return "rldimi %0,%3,0,%5";
3958   [(set_attr "type" "insert")
3959    (set_attr "size" "64")])
3961 (define_insn "*rotldi3_insert_7"
3962   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3963         (ior:DI (and:DI (match_operand:DI 3 "gpc_reg_operand" "r")
3964                         (match_operand:DI 4 "const_int_operand" "n"))
3965                 (and:DI (match_operand:DI 1 "gpc_reg_operand" "0")
3966                         (match_operand:DI 2 "const_int_operand" "n"))))]
3967   "exact_log2 (-UINTVAL (operands[2])) > 0
3968    && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
3970   operands[5] = GEN_INT (64 - exact_log2 (-UINTVAL (operands[2])));
3971   return "rldimi %0,%3,0,%5";
3973   [(set_attr "type" "insert")
3974    (set_attr "size" "64")])
3977 ; This handles the important case of multiple-precision shifts.  There is
3978 ; no canonicalization rule for ASHIFT vs. LSHIFTRT, so two patterns.
3979 (define_split
3980   [(set (match_operand:GPR 0 "gpc_reg_operand")
3981         (ior:GPR (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand")
3982                              (match_operand:SI 3 "const_int_operand"))
3983                  (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand")
3984                                (match_operand:SI 4 "const_int_operand"))))]
3985   "can_create_pseudo_p ()
3986    && INTVAL (operands[3]) + INTVAL (operands[4])
3987       >= GET_MODE_PRECISION (<MODE>mode)"
3988   [(set (match_dup 5)
3989         (lshiftrt:GPR (match_dup 2)
3990                       (match_dup 4)))
3991    (set (match_dup 0)
3992         (ior:GPR (and:GPR (match_dup 5)
3993                           (match_dup 6))
3994                  (ashift:GPR (match_dup 1)
3995                              (match_dup 3))))]
3997   unsigned HOST_WIDE_INT mask = 1;
3998   mask = (mask << INTVAL (operands[3])) - 1;
3999   operands[5] = gen_reg_rtx (<MODE>mode);
4000   operands[6] = GEN_INT (mask);
4003 (define_split
4004   [(set (match_operand:GPR 0 "gpc_reg_operand")
4005         (ior:GPR (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand")
4006                                (match_operand:SI 4 "const_int_operand"))
4007                  (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand")
4008                              (match_operand:SI 3 "const_int_operand"))))]
4009   "can_create_pseudo_p ()
4010    && INTVAL (operands[3]) + INTVAL (operands[4])
4011       >= GET_MODE_PRECISION (<MODE>mode)"
4012   [(set (match_dup 5)
4013         (lshiftrt:GPR (match_dup 2)
4014                       (match_dup 4)))
4015    (set (match_dup 0)
4016         (ior:GPR (and:GPR (match_dup 5)
4017                           (match_dup 6))
4018                  (ashift:GPR (match_dup 1)
4019                              (match_dup 3))))]
4021   unsigned HOST_WIDE_INT mask = 1;
4022   mask = (mask << INTVAL (operands[3])) - 1;
4023   operands[5] = gen_reg_rtx (<MODE>mode);
4024   operands[6] = GEN_INT (mask);
4028 ; Another important case is setting some bits to 1; we can do that with
4029 ; an insert instruction, in many cases.
4030 (define_insn_and_split "*ior<mode>_mask"
4031   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4032         (ior:GPR (match_operand:GPR 1 "gpc_reg_operand" "0")
4033                  (match_operand:GPR 2 "const_int_operand" "n")))
4034    (clobber (match_scratch:GPR 3 "=r"))]
4035   "!logical_const_operand (operands[2], <MODE>mode)
4036    && rs6000_is_valid_mask (operands[2], NULL, NULL, <MODE>mode)"
4037   "#"
4038   "&& 1"
4039   [(set (match_dup 3)
4040         (const_int -1))
4041    (set (match_dup 0)
4042         (ior:GPR (and:GPR (rotate:GPR (match_dup 3)
4043                                       (match_dup 4))
4044                           (match_dup 2))
4045                  (and:GPR (match_dup 1)
4046                           (match_dup 5))))]
4048   int nb, ne;
4049   rs6000_is_valid_mask (operands[2], &nb, &ne, <MODE>mode);
4050   if (GET_CODE (operands[3]) == SCRATCH)
4051     operands[3] = gen_reg_rtx (<MODE>mode);
4052   operands[4] = GEN_INT (ne);
4053   operands[5] = GEN_INT (~UINTVAL (operands[2]));
4055   [(set_attr "type" "two")
4056    (set_attr "length" "8")])
4059 ; Yet another case is an rldimi with the second value coming from memory.
4060 ; The zero_extend that should become part of the rldimi is merged into the
4061 ; load from memory instead.  Split things properly again.
4062 (define_split
4063   [(set (match_operand:DI 0 "gpc_reg_operand")
4064         (ior:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand")
4065                            (match_operand:SI 2 "const_int_operand"))
4066                 (zero_extend:DI (match_operand:QHSI 3 "memory_operand"))))]
4067   "INTVAL (operands[2]) == <bits>"
4068   [(set (match_dup 4)
4069         (zero_extend:DI (match_dup 3)))
4070    (set (match_dup 0)
4071         (ior:DI (and:DI (match_dup 4)
4072                         (match_dup 5))
4073                 (ashift:DI (match_dup 1)
4074                            (match_dup 2))))]
4076   operands[4] = gen_reg_rtx (DImode);
4077   operands[5] = GEN_INT ((HOST_WIDE_INT_1U << <bits>) - 1);
4080 ; rlwimi, too.
4081 (define_split
4082   [(set (match_operand:SI 0 "gpc_reg_operand")
4083         (ior:SI (ashift:SI (match_operand:SI 1 "gpc_reg_operand")
4084                            (match_operand:SI 2 "const_int_operand"))
4085                 (zero_extend:SI (match_operand:QHI 3 "memory_operand"))))]
4086   "INTVAL (operands[2]) == <bits>"
4087   [(set (match_dup 4)
4088         (zero_extend:SI (match_dup 3)))
4089    (set (match_dup 0)
4090         (ior:SI (and:SI (match_dup 4)
4091                         (match_dup 5))
4092                 (ashift:SI (match_dup 1)
4093                            (match_dup 2))))]
4095   operands[4] = gen_reg_rtx (SImode);
4096   operands[5] = GEN_INT ((HOST_WIDE_INT_1U << <bits>) - 1);
4100 ;; Now the simple shifts.
4102 (define_insn "rotl<mode>3"
4103   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4104         (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4105                     (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4106   ""
4107   "rotl<wd>%I2 %0,%1,%<hH>2"
4108   [(set_attr "type" "shift")
4109    (set_attr "maybe_var_shift" "yes")])
4111 (define_insn "*rotlsi3_64"
4112   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4113         (zero_extend:DI
4114             (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4115                        (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4116   "TARGET_POWERPC64"
4117   "rotlw%I2 %0,%1,%h2"
4118   [(set_attr "type" "shift")
4119    (set_attr "maybe_var_shift" "yes")])
4121 (define_insn_and_split "*rotl<mode>3_dot"
4122   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4123         (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4124                                 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4125                     (const_int 0)))
4126    (clobber (match_scratch:GPR 0 "=r,r"))]
4127   "<MODE>mode == Pmode"
4128   "@
4129    rotl<wd>%I2. %0,%1,%<hH>2
4130    #"
4131   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4132   [(set (match_dup 0)
4133         (rotate:GPR (match_dup 1)
4134                     (match_dup 2)))
4135    (set (match_dup 3)
4136         (compare:CC (match_dup 0)
4137                     (const_int 0)))]
4138   ""
4139   [(set_attr "type" "shift")
4140    (set_attr "maybe_var_shift" "yes")
4141    (set_attr "dot" "yes")
4142    (set_attr "length" "4,8")])
4144 (define_insn_and_split "*rotl<mode>3_dot2"
4145   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4146         (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4147                                 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4148                     (const_int 0)))
4149    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4150         (rotate:GPR (match_dup 1)
4151                     (match_dup 2)))]
4152   "<MODE>mode == Pmode"
4153   "@
4154    rotl<wd>%I2. %0,%1,%<hH>2
4155    #"
4156   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4157   [(set (match_dup 0)
4158         (rotate:GPR (match_dup 1)
4159                     (match_dup 2)))
4160    (set (match_dup 3)
4161         (compare:CC (match_dup 0)
4162                     (const_int 0)))]
4163   ""
4164   [(set_attr "type" "shift")
4165    (set_attr "maybe_var_shift" "yes")
4166    (set_attr "dot" "yes")
4167    (set_attr "length" "4,8")])
4170 (define_insn "ashl<mode>3"
4171   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4172         (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4173                     (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4174   ""
4175   "sl<wd>%I2 %0,%1,%<hH>2"
4176   [(set_attr "type" "shift")
4177    (set_attr "maybe_var_shift" "yes")])
4179 (define_insn "*ashlsi3_64"
4180   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4181         (zero_extend:DI
4182             (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4183                        (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4184   "TARGET_POWERPC64"
4185   "slw%I2 %0,%1,%h2"
4186   [(set_attr "type" "shift")
4187    (set_attr "maybe_var_shift" "yes")])
4189 (define_insn_and_split "*ashl<mode>3_dot"
4190   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4191         (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4192                                 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4193                     (const_int 0)))
4194    (clobber (match_scratch:GPR 0 "=r,r"))]
4195   "<MODE>mode == Pmode"
4196   "@
4197    sl<wd>%I2. %0,%1,%<hH>2
4198    #"
4199   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4200   [(set (match_dup 0)
4201         (ashift:GPR (match_dup 1)
4202                     (match_dup 2)))
4203    (set (match_dup 3)
4204         (compare:CC (match_dup 0)
4205                     (const_int 0)))]
4206   ""
4207   [(set_attr "type" "shift")
4208    (set_attr "maybe_var_shift" "yes")
4209    (set_attr "dot" "yes")
4210    (set_attr "length" "4,8")])
4212 (define_insn_and_split "*ashl<mode>3_dot2"
4213   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4214         (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4215                                 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4216                     (const_int 0)))
4217    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4218         (ashift:GPR (match_dup 1)
4219                     (match_dup 2)))]
4220   "<MODE>mode == Pmode"
4221   "@
4222    sl<wd>%I2. %0,%1,%<hH>2
4223    #"
4224   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4225   [(set (match_dup 0)
4226         (ashift:GPR (match_dup 1)
4227                     (match_dup 2)))
4228    (set (match_dup 3)
4229         (compare:CC (match_dup 0)
4230                     (const_int 0)))]
4231   ""
4232   [(set_attr "type" "shift")
4233    (set_attr "maybe_var_shift" "yes")
4234    (set_attr "dot" "yes")
4235    (set_attr "length" "4,8")])
4237 ;; Pretend we have a memory form of extswsli until register allocation is done
4238 ;; so that we use LWZ to load the value from memory, instead of LWA.
4239 (define_insn_and_split "ashdi3_extswsli"
4240   [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
4241         (ashift:DI
4242          (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,m"))
4243          (match_operand:DI 2 "u6bit_cint_operand" "n,n")))]
4244   "TARGET_EXTSWSLI"
4245   "@
4246    extswsli %0,%1,%2
4247    #"
4248   "&& reload_completed && MEM_P (operands[1])"
4249   [(set (match_dup 3)
4250         (match_dup 1))
4251    (set (match_dup 0)
4252         (ashift:DI (sign_extend:DI (match_dup 3))
4253                    (match_dup 2)))]
4255   operands[3] = gen_lowpart (SImode, operands[0]);
4257   [(set_attr "type" "shift")
4258    (set_attr "maybe_var_shift" "no")])
4261 (define_insn_and_split "ashdi3_extswsli_dot"
4262   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y")
4263         (compare:CC
4264          (ashift:DI
4265           (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m"))
4266           (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n"))
4267          (const_int 0)))
4268    (clobber (match_scratch:DI 0 "=r,r,r,r"))]
4269   "TARGET_EXTSWSLI"
4270   "@
4271    extswsli. %0,%1,%2
4272    #
4273    #
4274    #"
4275   "&& reload_completed
4276    && (cc_reg_not_cr0_operand (operands[3], CCmode)
4277        || memory_operand (operands[1], SImode))"
4278   [(pc)]
4280   rtx dest = operands[0];
4281   rtx src = operands[1];
4282   rtx shift = operands[2];
4283   rtx cr = operands[3];
4284   rtx src2;
4286   if (!MEM_P (src))
4287     src2 = src;
4288   else
4289     {
4290       src2 = gen_lowpart (SImode, dest);
4291       emit_move_insn (src2, src);
4292     }
4294   if (REGNO (cr) == CR0_REGNO)
4295     {
4296       emit_insn (gen_ashdi3_extswsli_dot2 (dest, src2, shift, cr));
4297       DONE;
4298     }
4300   emit_insn (gen_ashdi3_extswsli (dest, src2, shift));
4301   emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx)));
4302   DONE;
4304   [(set_attr "type" "shift")
4305    (set_attr "maybe_var_shift" "no")
4306    (set_attr "dot" "yes")
4307    (set_attr "length" "4,8,8,12")])
4309 (define_insn_and_split "ashdi3_extswsli_dot2"
4310   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y")
4311         (compare:CC
4312          (ashift:DI
4313           (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m"))
4314           (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n"))
4315          (const_int 0)))
4316    (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r")
4317         (ashift:DI (sign_extend:DI (match_dup 1))
4318                    (match_dup 2)))]
4319   "TARGET_EXTSWSLI"
4320   "@
4321    extswsli. %0,%1,%2
4322    #
4323    #
4324    #"
4325   "&& reload_completed
4326    && (cc_reg_not_cr0_operand (operands[3], CCmode)
4327        || memory_operand (operands[1], SImode))"
4328   [(pc)]
4330   rtx dest = operands[0];
4331   rtx src = operands[1];
4332   rtx shift = operands[2];
4333   rtx cr = operands[3];
4334   rtx src2;
4336   if (!MEM_P (src))
4337     src2 = src;
4338   else
4339     {
4340       src2 = gen_lowpart (SImode, dest);
4341       emit_move_insn (src2, src);
4342     }
4344   if (REGNO (cr) == CR0_REGNO)
4345     {
4346       emit_insn (gen_ashdi3_extswsli_dot2 (dest, src2, shift, cr));
4347       DONE;
4348     }
4350   emit_insn (gen_ashdi3_extswsli (dest, src2, shift));
4351   emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx)));
4352   DONE;
4354   [(set_attr "type" "shift")
4355    (set_attr "maybe_var_shift" "no")
4356    (set_attr "dot" "yes")
4357    (set_attr "length" "4,8,8,12")])
4359 (define_insn "lshr<mode>3"
4360   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4361         (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4362                       (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4363   ""
4364   "sr<wd>%I2 %0,%1,%<hH>2"
4365   [(set_attr "type" "shift")
4366    (set_attr "maybe_var_shift" "yes")])
4368 (define_insn "*lshrsi3_64"
4369   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4370         (zero_extend:DI
4371             (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4372                          (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4373   "TARGET_POWERPC64"
4374   "srw%I2 %0,%1,%h2"
4375   [(set_attr "type" "shift")
4376    (set_attr "maybe_var_shift" "yes")])
4378 (define_insn_and_split "*lshr<mode>3_dot"
4379   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4380         (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4381                                   (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4382                     (const_int 0)))
4383    (clobber (match_scratch:GPR 0 "=r,r"))]
4384   "<MODE>mode == Pmode"
4385   "@
4386    sr<wd>%I2. %0,%1,%<hH>2
4387    #"
4388   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4389   [(set (match_dup 0)
4390         (lshiftrt:GPR (match_dup 1)
4391                       (match_dup 2)))
4392    (set (match_dup 3)
4393         (compare:CC (match_dup 0)
4394                     (const_int 0)))]
4395   ""
4396   [(set_attr "type" "shift")
4397    (set_attr "maybe_var_shift" "yes")
4398    (set_attr "dot" "yes")
4399    (set_attr "length" "4,8")])
4401 (define_insn_and_split "*lshr<mode>3_dot2"
4402   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4403         (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4404                                   (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4405                     (const_int 0)))
4406    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4407         (lshiftrt:GPR (match_dup 1)
4408                       (match_dup 2)))]
4409   "<MODE>mode == Pmode"
4410   "@
4411    sr<wd>%I2. %0,%1,%<hH>2
4412    #"
4413   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4414   [(set (match_dup 0)
4415         (lshiftrt:GPR (match_dup 1)
4416                       (match_dup 2)))
4417    (set (match_dup 3)
4418         (compare:CC (match_dup 0)
4419                     (const_int 0)))]
4420   ""
4421   [(set_attr "type" "shift")
4422    (set_attr "maybe_var_shift" "yes")
4423    (set_attr "dot" "yes")
4424    (set_attr "length" "4,8")])
4427 (define_insn "ashr<mode>3"
4428   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4429         (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4430                       (match_operand:SI 2 "reg_or_cint_operand" "rn")))
4431    (clobber (reg:GPR CA_REGNO))]
4432   ""
4433   "sra<wd>%I2 %0,%1,%<hH>2"
4434   [(set_attr "type" "shift")
4435    (set_attr "maybe_var_shift" "yes")])
4437 (define_insn "*ashrsi3_64"
4438   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4439         (sign_extend:DI
4440             (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4441                          (match_operand:SI 2 "reg_or_cint_operand" "rn"))))
4442    (clobber (reg:SI CA_REGNO))]
4443   "TARGET_POWERPC64"
4444   "sraw%I2 %0,%1,%h2"
4445   [(set_attr "type" "shift")
4446    (set_attr "maybe_var_shift" "yes")])
4448 (define_insn_and_split "*ashr<mode>3_dot"
4449   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4450         (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4451                                   (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4452                     (const_int 0)))
4453    (clobber (match_scratch:GPR 0 "=r,r"))
4454    (clobber (reg:GPR CA_REGNO))]
4455   "<MODE>mode == Pmode"
4456   "@
4457    sra<wd>%I2. %0,%1,%<hH>2
4458    #"
4459   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4460   [(parallel [(set (match_dup 0)
4461                    (ashiftrt:GPR (match_dup 1)
4462                                  (match_dup 2)))
4463               (clobber (reg:GPR CA_REGNO))])
4464    (set (match_dup 3)
4465         (compare:CC (match_dup 0)
4466                     (const_int 0)))]
4467   ""
4468   [(set_attr "type" "shift")
4469    (set_attr "maybe_var_shift" "yes")
4470    (set_attr "dot" "yes")
4471    (set_attr "length" "4,8")])
4473 (define_insn_and_split "*ashr<mode>3_dot2"
4474   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4475         (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4476                                   (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4477                     (const_int 0)))
4478    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4479         (ashiftrt:GPR (match_dup 1)
4480                       (match_dup 2)))
4481    (clobber (reg:GPR CA_REGNO))]
4482   "<MODE>mode == Pmode"
4483   "@
4484    sra<wd>%I2. %0,%1,%<hH>2
4485    #"
4486   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4487   [(parallel [(set (match_dup 0)
4488                    (ashiftrt:GPR (match_dup 1)
4489                                  (match_dup 2)))
4490               (clobber (reg:GPR CA_REGNO))])
4491    (set (match_dup 3)
4492         (compare:CC (match_dup 0)
4493                     (const_int 0)))]
4494   ""
4495   [(set_attr "type" "shift")
4496    (set_attr "maybe_var_shift" "yes")
4497    (set_attr "dot" "yes")
4498    (set_attr "length" "4,8")])
4500 ;; Builtins to replace a division to generate FRE reciprocal estimate
4501 ;; instructions and the necessary fixup instructions
4502 (define_expand "recip<mode>3"
4503   [(match_operand:RECIPF 0 "gpc_reg_operand")
4504    (match_operand:RECIPF 1 "gpc_reg_operand")
4505    (match_operand:RECIPF 2 "gpc_reg_operand")]
4506   "RS6000_RECIP_HAVE_RE_P (<MODE>mode)"
4508    rs6000_emit_swdiv (operands[0], operands[1], operands[2], false);
4509    DONE;
4512 ;; Split to create division from FRE/FRES/etc. and fixup instead of the normal
4513 ;; hardware division.  This is only done before register allocation and with
4514 ;; -ffast-math.  This must appear before the divsf3/divdf3 insns.
4515 ;; We used to also check optimize_insn_for_speed_p () but problems with guessed
4516 ;; frequencies (pr68212/pr77536) yields that unreliable so it was removed.
4517 (define_split
4518   [(set (match_operand:RECIPF 0 "gpc_reg_operand")
4519         (div:RECIPF (match_operand 1 "gpc_reg_operand")
4520                     (match_operand 2 "gpc_reg_operand")))]
4521   "RS6000_RECIP_AUTO_RE_P (<MODE>mode)
4522    && can_create_pseudo_p () && flag_finite_math_only
4523    && !flag_trapping_math && flag_reciprocal_math"
4524   [(const_int 0)]
4526   rs6000_emit_swdiv (operands[0], operands[1], operands[2], true);
4527   DONE;
4530 ;; Builtins to replace 1/sqrt(x) with instructions using RSQRTE and the
4531 ;; appropriate fixup.
4532 (define_expand "rsqrt<mode>2"
4533   [(match_operand:RECIPF 0 "gpc_reg_operand")
4534    (match_operand:RECIPF 1 "gpc_reg_operand")]
4535   "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4537   rs6000_emit_swsqrt (operands[0], operands[1], 1);
4538   DONE;
4541 ;; Floating-point insns, excluding normal data motion.  We combine the SF/DF
4542 ;; modes here, and also add in conditional vsx/power8-vector support to access
4543 ;; values in the traditional Altivec registers if the appropriate
4544 ;; -mupper-regs-{df,sf} option is enabled.
4546 (define_expand "abs<mode>2"
4547   [(set (match_operand:SFDF 0 "gpc_reg_operand")
4548         (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))]
4549   "TARGET_HARD_FLOAT"
4550   "")
4552 (define_insn "*abs<mode>2_fpr"
4553   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4554         (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4555   "TARGET_HARD_FLOAT"
4556   "@
4557    fabs %0,%1
4558    xsabsdp %x0,%x1"
4559   [(set_attr "type" "fpsimple")])
4561 (define_insn "*nabs<mode>2_fpr"
4562   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4563         (neg:SFDF
4564          (abs:SFDF
4565           (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))))]
4566   "TARGET_HARD_FLOAT"
4567   "@
4568    fnabs %0,%1
4569    xsnabsdp %x0,%x1"
4570   [(set_attr "type" "fpsimple")])
4572 (define_expand "neg<mode>2"
4573   [(set (match_operand:SFDF 0 "gpc_reg_operand")
4574         (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))]
4575   "TARGET_HARD_FLOAT"
4576   "")
4578 (define_insn "*neg<mode>2_fpr"
4579   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4580         (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4581   "TARGET_HARD_FLOAT"
4582   "@
4583    fneg %0,%1
4584    xsnegdp %x0,%x1"
4585   [(set_attr "type" "fpsimple")])
4587 (define_expand "add<mode>3"
4588   [(set (match_operand:SFDF 0 "gpc_reg_operand")
4589         (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4590                    (match_operand:SFDF 2 "gpc_reg_operand")))]
4591   "TARGET_HARD_FLOAT"
4592   "")
4594 (define_insn "*add<mode>3_fpr"
4595   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4596         (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>")
4597                    (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4598   "TARGET_HARD_FLOAT"
4599   "@
4600    fadd<Ftrad> %0,%1,%2
4601    xsadd<Fvsx> %x0,%x1,%x2"
4602   [(set_attr "type" "fp")])
4604 (define_expand "sub<mode>3"
4605   [(set (match_operand:SFDF 0 "gpc_reg_operand")
4606         (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4607                     (match_operand:SFDF 2 "gpc_reg_operand")))]
4608   "TARGET_HARD_FLOAT"
4609   "")
4611 (define_insn "*sub<mode>3_fpr"
4612   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4613         (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4614                     (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4615   "TARGET_HARD_FLOAT"
4616   "@
4617    fsub<Ftrad> %0,%1,%2
4618    xssub<Fvsx> %x0,%x1,%x2"
4619   [(set_attr "type" "fp")])
4621 (define_expand "mul<mode>3"
4622   [(set (match_operand:SFDF 0 "gpc_reg_operand")
4623         (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4624                    (match_operand:SFDF 2 "gpc_reg_operand")))]
4625   "TARGET_HARD_FLOAT"
4626   "")
4628 (define_insn "*mul<mode>3_fpr"
4629   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4630         (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>")
4631                    (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4632   "TARGET_HARD_FLOAT"
4633   "@
4634    fmul<Ftrad> %0,%1,%2
4635    xsmul<Fvsx> %x0,%x1,%x2"
4636   [(set_attr "type" "dmul")])
4638 (define_expand "div<mode>3"
4639   [(set (match_operand:SFDF 0 "gpc_reg_operand")
4640         (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4641                   (match_operand:SFDF 2 "gpc_reg_operand")))]
4642   "TARGET_HARD_FLOAT"
4644   if (RS6000_RECIP_AUTO_RE_P (<MODE>mode)
4645       && can_create_pseudo_p () && flag_finite_math_only
4646       && !flag_trapping_math && flag_reciprocal_math)
4647     {
4648       rs6000_emit_swdiv (operands[0], operands[1], operands[2], true);
4649       DONE;
4650     }
4653 (define_insn "*div<mode>3_fpr"
4654   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4655         (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4656                   (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4657   "TARGET_HARD_FLOAT"
4658   "@
4659    fdiv<Ftrad> %0,%1,%2
4660    xsdiv<Fvsx> %x0,%x1,%x2"
4661   [(set_attr "type" "<Fs>div")])
4663 (define_insn "*sqrt<mode>2_internal"
4664   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4665         (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4666   "TARGET_HARD_FLOAT && TARGET_PPC_GPOPT"
4667   "@
4668    fsqrt<Ftrad> %0,%1
4669    xssqrt<Fvsx> %x0,%x1"
4670   [(set_attr "type" "<Fs>sqrt")])
4672 (define_expand "sqrt<mode>2"
4673   [(set (match_operand:SFDF 0 "gpc_reg_operand")
4674         (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))]
4675   "TARGET_HARD_FLOAT && TARGET_PPC_GPOPT"
4677   if (<MODE>mode == SFmode
4678       && TARGET_RECIP_PRECISION
4679       && RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)
4680       && !optimize_function_for_size_p (cfun)
4681       && flag_finite_math_only && !flag_trapping_math
4682       && flag_unsafe_math_optimizations)
4683     {
4684       rs6000_emit_swsqrt (operands[0], operands[1], 0);
4685       DONE;
4686     }
4689 ;; Floating point reciprocal approximation
4690 (define_insn "fre<Fs>"
4691   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4692         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")]
4693                      UNSPEC_FRES))]
4694   "TARGET_<FFRE>"
4695   "@
4696    fre<Ftrad> %0,%1
4697    xsre<Fvsx> %x0,%x1"
4698   [(set_attr "type" "fp")])
4700 (define_insn "*rsqrt<mode>2"
4701   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4702         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")]
4703                      UNSPEC_RSQRT))]
4704   "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4705   "@
4706    frsqrte<Ftrad> %0,%1
4707    xsrsqrte<Fvsx> %x0,%x1"
4708   [(set_attr "type" "fp")])
4710 ;; Floating point comparisons
4711 (define_insn "*cmp<mode>_fpr"
4712   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y,y")
4713         (compare:CCFP (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4714                       (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4715   "TARGET_HARD_FLOAT"
4716   "@
4717    fcmpu %0,%1,%2
4718    xscmpudp %0,%x1,%x2"
4719   [(set_attr "type" "fpcompare")])
4721 ;; Floating point conversions
4722 (define_expand "extendsfdf2"
4723   [(set (match_operand:DF 0 "gpc_reg_operand")
4724         (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand")))]
4725   "TARGET_HARD_FLOAT"
4727   if (HONOR_SNANS (SFmode))
4728     operands[1] = force_reg (SFmode, operands[1]);
4731 (define_insn_and_split "*extendsfdf2_fpr"
4732   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d,d,ws,?ws,wu,wb")
4733         (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand" "0,f,m,0,wy,Z,wY")))]
4734   "TARGET_HARD_FLOAT && !HONOR_SNANS (SFmode)"
4735   "@
4736    #
4737    fmr %0,%1
4738    lfs%U1%X1 %0,%1
4739    #
4740    xscpsgndp %x0,%x1,%x1
4741    lxsspx %x0,%y1
4742    lxssp %0,%1"
4743   "&& reload_completed && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1])"
4744   [(const_int 0)]
4746   emit_note (NOTE_INSN_DELETED);
4747   DONE;
4749   [(set_attr "type" "fp,fpsimple,fpload,fp,fpsimple,fpload,fpload")])
4751 (define_insn "*extendsfdf2_snan"
4752   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
4753         (float_extend:DF (match_operand:SF 1 "gpc_reg_operand" "f,wy")))]
4754   "TARGET_HARD_FLOAT && HONOR_SNANS (SFmode)"
4755   "@
4756    frsp %0,%1
4757    xsrsp %x0,%x1"
4758   [(set_attr "type" "fp")])
4760 (define_expand "truncdfsf2"
4761   [(set (match_operand:SF 0 "gpc_reg_operand")
4762         (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand")))]
4763   "TARGET_HARD_FLOAT"
4764   "")
4766 (define_insn "*truncdfsf2_fpr"
4767   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy")
4768         (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "d,ws")))]
4769   "TARGET_HARD_FLOAT"
4770   "@
4771    frsp %0,%1
4772    xsrsp %x0,%x1"
4773   [(set_attr "type" "fp")])
4775 ;; This expander is here to avoid FLOAT_WORDS_BIGENDIAN tests in
4776 ;; builtins.c and optabs.c that are not correct for IBM long double
4777 ;; when little-endian.
4778 (define_expand "signbit<mode>2"
4779   [(set (match_dup 2)
4780         (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand")))
4781    (set (match_dup 3)
4782         (subreg:DI (match_dup 2) 0))
4783    (set (match_dup 4)
4784         (match_dup 5))
4785    (set (match_operand:SI 0 "gpc_reg_operand")
4786         (match_dup 6))]
4787   "TARGET_HARD_FLOAT
4788    && (!FLOAT128_IEEE_P (<MODE>mode)
4789        || (TARGET_POWERPC64 && TARGET_DIRECT_MOVE))"
4791   if (FLOAT128_IEEE_P (<MODE>mode))
4792     {
4793       rtx dest = operands[0];
4794       rtx src = operands[1];
4795       rtx tmp = gen_reg_rtx (DImode);
4796       rtx dest_di = gen_lowpart (DImode, dest);
4798       if (<MODE>mode == KFmode)
4799         emit_insn (gen_signbitkf2_dm (tmp, src));
4800       else if (<MODE>mode == TFmode)
4801         emit_insn (gen_signbittf2_dm (tmp, src));
4802       else
4803         gcc_unreachable ();
4805       emit_insn (gen_lshrdi3 (dest_di, tmp, GEN_INT (63)));
4806       DONE;
4807     }
4808   operands[2] = gen_reg_rtx (DFmode);
4809   operands[3] = gen_reg_rtx (DImode);
4810   if (TARGET_POWERPC64)
4811     {
4812       operands[4] = gen_reg_rtx (DImode);
4813       operands[5] = gen_rtx_LSHIFTRT (DImode, operands[3], GEN_INT (63));
4814       operands[6] = gen_rtx_SUBREG (SImode, operands[4],
4815                                     WORDS_BIG_ENDIAN ? 4 : 0);
4816     }
4817   else
4818     {
4819       operands[4] = gen_reg_rtx (SImode);
4820       operands[5] = gen_rtx_SUBREG (SImode, operands[3],
4821                                     WORDS_BIG_ENDIAN ? 0 : 4);
4822       operands[6] = gen_rtx_LSHIFTRT (SImode, operands[4], GEN_INT (31));
4823     }
4826 ;; Optimize IEEE 128-bit signbit on 64-bit systems with direct move to avoid
4827 ;; multiple direct moves.  If we used a SUBREG:DI of the Floa128 type, the
4828 ;; register allocator would typically move the entire _Float128 item to GPRs (2
4829 ;; instructions on ISA 3.0, 3-4 instructions on ISA 2.07).
4831 ;; After register allocation, if the _Float128 had originally been in GPRs, the
4832 ;; split allows the post reload phases to eliminate the move, and do the shift
4833 ;; directly with the register that contains the signbit.
4834 (define_insn_and_split "signbit<mode>2_dm"
4835   [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
4836         (unspec:DI [(match_operand:SIGNBIT 1 "gpc_reg_operand" "wa,r")]
4837                    UNSPEC_SIGNBIT))]
4838   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
4839   "@
4840    mfvsrd %0,%x1
4841    #"
4842   "&& reload_completed && int_reg_operand (operands[1], <MODE>mode)"
4843   [(set (match_dup 0)
4844         (match_dup 2))]
4846   operands[2] = gen_highpart (DImode, operands[1]);
4848  [(set_attr "type" "mftgpr,*")])
4850 ;; Optimize IEEE 128-bit signbit on to avoid loading the value into a vector
4851 ;; register and then doing a direct move if the value comes from memory.  On
4852 ;; little endian, we have to load the 2nd double-word to get the sign bit.
4853 (define_insn_and_split "*signbit<mode>2_dm_mem"
4854   [(set (match_operand:DI 0 "gpc_reg_operand" "=b")
4855         (unspec:DI [(match_operand:SIGNBIT 1 "memory_operand" "m")]
4856                    UNSPEC_SIGNBIT))]
4857   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
4858   "#"
4859   "&& 1"
4860   [(set (match_dup 0)
4861         (match_dup 2))]
4863   rtx dest = operands[0];
4864   rtx src = operands[1];
4865   rtx addr = XEXP (src, 0);
4867   if (WORDS_BIG_ENDIAN)
4868     operands[2] = adjust_address (src, DImode, 0);
4870   else if (REG_P (addr) || SUBREG_P (addr))
4871     operands[2] = adjust_address (src, DImode, 8);
4873   else if (GET_CODE (addr) == PLUS && REG_P (XEXP (addr, 0))
4874            && CONST_INT_P (XEXP (addr, 1)) && mem_operand_gpr (src, DImode))
4875     operands[2] = adjust_address (src, DImode, 8);
4877   else
4878     {
4879       rtx tmp = can_create_pseudo_p () ? gen_reg_rtx (DImode) : dest;
4880       emit_insn (gen_rtx_SET (tmp, addr));
4881       operands[2] = change_address (src, DImode,
4882                                     gen_rtx_PLUS (DImode, tmp, GEN_INT (8)));
4883     }
4886 (define_expand "copysign<mode>3"
4887   [(set (match_dup 3)
4888         (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))
4889    (set (match_dup 4)
4890         (neg:SFDF (abs:SFDF (match_dup 1))))
4891    (set (match_operand:SFDF 0 "gpc_reg_operand")
4892         (if_then_else:SFDF (ge (match_operand:SFDF 2 "gpc_reg_operand")
4893                                (match_dup 5))
4894                          (match_dup 3)
4895                          (match_dup 4)))]
4896   "TARGET_HARD_FLOAT
4897    && ((TARGET_PPC_GFXOPT
4898         && !HONOR_NANS (<MODE>mode)
4899         && !HONOR_SIGNED_ZEROS (<MODE>mode))
4900        || TARGET_CMPB
4901        || VECTOR_UNIT_VSX_P (<MODE>mode))"
4903   if (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode))
4904     {
4905       emit_insn (gen_copysign<mode>3_fcpsgn (operands[0], operands[1],
4906                                              operands[2]));
4907       DONE;
4908     }
4910    operands[3] = gen_reg_rtx (<MODE>mode);
4911    operands[4] = gen_reg_rtx (<MODE>mode);
4912    operands[5] = CONST0_RTX (<MODE>mode);
4913   })
4915 ;; Use an unspec rather providing an if-then-else in RTL, to prevent the
4916 ;; compiler from optimizing -0.0
4917 (define_insn "copysign<mode>3_fcpsgn"
4918   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4919         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")
4920                       (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")]
4921                      UNSPEC_COPYSIGN))]
4922   "TARGET_HARD_FLOAT && (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode))"
4923   "@
4924    fcpsgn %0,%2,%1
4925    xscpsgndp %x0,%x2,%x1"
4926   [(set_attr "type" "fpsimple")])
4928 ;; For MIN, MAX, and conditional move, we use DEFINE_EXPAND's that involve a
4929 ;; fsel instruction and some auxiliary computations.  Then we just have a
4930 ;; single DEFINE_INSN for fsel and the define_splits to make them if made by
4931 ;; combine.
4932 ;; For MIN, MAX on non-VSX machines, and conditional move all of the time, we
4933 ;; use DEFINE_EXPAND's that involve a fsel instruction and some auxiliary
4934 ;; computations.  Then we just have a single DEFINE_INSN for fsel and the
4935 ;; define_splits to make them if made by combine.  On VSX machines we have the
4936 ;; min/max instructions.
4938 ;; On VSX, we only check for TARGET_VSX instead of checking for a vsx/p8 vector
4939 ;; to allow either DF/SF to use only traditional registers.
4941 (define_expand "s<minmax><mode>3"
4942   [(set (match_operand:SFDF 0 "gpc_reg_operand")
4943         (fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4944                         (match_operand:SFDF 2 "gpc_reg_operand")))]
4945   "TARGET_MINMAX"
4947   rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]);
4948   DONE;
4951 (define_insn "*s<minmax><mode>3_vsx"
4952   [(set (match_operand:SFDF 0 "vsx_register_operand" "=<Fv>")
4953         (fp_minmax:SFDF (match_operand:SFDF 1 "vsx_register_operand" "<Fv>")
4954                         (match_operand:SFDF 2 "vsx_register_operand" "<Fv>")))]
4955   "TARGET_VSX && TARGET_HARD_FLOAT"
4957   return (TARGET_P9_MINMAX
4958           ? "xs<minmax>cdp %x0,%x1,%x2"
4959           : "xs<minmax>dp %x0,%x1,%x2");
4961   [(set_attr "type" "fp")])
4963 ;; The conditional move instructions allow us to perform max and min operations
4964 ;; even when we don't have the appropriate max/min instruction using the FSEL
4965 ;; instruction.
4967 (define_insn_and_split "*s<minmax><mode>3_fpr"
4968   [(set (match_operand:SFDF 0 "gpc_reg_operand")
4969         (fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4970                         (match_operand:SFDF 2 "gpc_reg_operand")))]
4971   "!TARGET_VSX && TARGET_MINMAX"
4972   "#"
4973   "&& 1"
4974   [(const_int 0)]
4976   rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]);
4977   DONE;
4980 (define_expand "mov<mode>cc"
4981    [(set (match_operand:GPR 0 "gpc_reg_operand")
4982          (if_then_else:GPR (match_operand 1 "comparison_operator")
4983                            (match_operand:GPR 2 "gpc_reg_operand")
4984                            (match_operand:GPR 3 "gpc_reg_operand")))]
4985   "TARGET_ISEL"
4987   if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
4988     DONE;
4989   else
4990     FAIL;
4993 ;; We use the BASE_REGS for the isel input operands because, if rA is
4994 ;; 0, the value of 0 is placed in rD upon truth.  Similarly for rB
4995 ;; because we may switch the operands and rB may end up being rA.
4997 ;; We need 2 patterns: an unsigned and a signed pattern.  We could
4998 ;; leave out the mode in operand 4 and use one pattern, but reload can
4999 ;; change the mode underneath our feet and then gets confused trying
5000 ;; to reload the value.
5001 (define_insn "isel_signed_<mode>"
5002   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
5003         (if_then_else:GPR
5004          (match_operator 1 "scc_comparison_operator"
5005                          [(match_operand:CC 4 "cc_reg_operand" "y,y")
5006                           (const_int 0)])
5007          (match_operand:GPR 2 "reg_or_zero_operand" "O,b")
5008          (match_operand:GPR 3 "gpc_reg_operand" "r,r")))]
5009   "TARGET_ISEL"
5010   "isel %0,%2,%3,%j1"
5011   [(set_attr "type" "isel")])
5013 (define_insn "isel_unsigned_<mode>"
5014   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
5015         (if_then_else:GPR
5016          (match_operator 1 "scc_comparison_operator"
5017                          [(match_operand:CCUNS 4 "cc_reg_operand" "y,y")
5018                           (const_int 0)])
5019          (match_operand:GPR 2 "reg_or_zero_operand" "O,b")
5020          (match_operand:GPR 3 "gpc_reg_operand" "r,r")))]
5021   "TARGET_ISEL"
5022   "isel %0,%2,%3,%j1"
5023   [(set_attr "type" "isel")])
5025 ;; These patterns can be useful for combine; they let combine know that
5026 ;; isel can handle reversed comparisons so long as the operands are
5027 ;; registers.
5029 (define_insn "*isel_reversed_signed_<mode>"
5030   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
5031         (if_then_else:GPR
5032          (match_operator 1 "scc_rev_comparison_operator"
5033                          [(match_operand:CC 4 "cc_reg_operand" "y,y")
5034                           (const_int 0)])
5035          (match_operand:GPR 2 "gpc_reg_operand" "r,r")
5036          (match_operand:GPR 3 "reg_or_zero_operand" "O,b")))]
5037   "TARGET_ISEL"
5039   PUT_CODE (operands[1], reverse_condition (GET_CODE (operands[1])));
5040   return "isel %0,%3,%2,%j1";
5042   [(set_attr "type" "isel")])
5044 (define_insn "*isel_reversed_unsigned_<mode>"
5045   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
5046         (if_then_else:GPR
5047          (match_operator 1 "scc_rev_comparison_operator"
5048                          [(match_operand:CCUNS 4 "cc_reg_operand" "y,y")
5049                           (const_int 0)])
5050          (match_operand:GPR 2 "gpc_reg_operand" "r,r")
5051          (match_operand:GPR 3 "reg_or_zero_operand" "O,b")))]
5052   "TARGET_ISEL"
5054   PUT_CODE (operands[1], reverse_condition (GET_CODE (operands[1])));
5055   return "isel %0,%3,%2,%j1";
5057   [(set_attr "type" "isel")])
5059 ;; Floating point conditional move
5060 (define_expand "mov<mode>cc"
5061    [(set (match_operand:SFDF 0 "gpc_reg_operand")
5062          (if_then_else:SFDF (match_operand 1 "comparison_operator")
5063                             (match_operand:SFDF 2 "gpc_reg_operand")
5064                             (match_operand:SFDF 3 "gpc_reg_operand")))]
5065   "TARGET_HARD_FLOAT && TARGET_PPC_GFXOPT"
5067   if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
5068     DONE;
5069   else
5070     FAIL;
5073 (define_insn "*fsel<SFDF:mode><SFDF2:mode>4"
5074   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=&<SFDF:rreg2>")
5075         (if_then_else:SFDF
5076          (ge (match_operand:SFDF2 1 "gpc_reg_operand" "<SFDF2:rreg2>")
5077              (match_operand:SFDF2 4 "zero_fp_constant" "F"))
5078          (match_operand:SFDF 2 "gpc_reg_operand" "<SFDF:rreg2>")
5079          (match_operand:SFDF 3 "gpc_reg_operand" "<SFDF:rreg2>")))]
5080   "TARGET_HARD_FLOAT && TARGET_PPC_GFXOPT"
5081   "fsel %0,%1,%2,%3"
5082   [(set_attr "type" "fp")])
5084 (define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_p9"
5085   [(set (match_operand:SFDF 0 "vsx_register_operand" "=&<SFDF:Fv>,<SFDF:Fv>")
5086         (if_then_else:SFDF
5087          (match_operator:CCFP 1 "fpmask_comparison_operator"
5088                 [(match_operand:SFDF2 2 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")
5089                  (match_operand:SFDF2 3 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")])
5090          (match_operand:SFDF 4 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")
5091          (match_operand:SFDF 5 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")))
5092    (clobber (match_scratch:V2DI 6 "=0,&wa"))]
5093   "TARGET_P9_MINMAX"
5094   "#"
5095   ""
5096   [(set (match_dup 6)
5097         (if_then_else:V2DI (match_dup 1)
5098                            (match_dup 7)
5099                            (match_dup 8)))
5100    (set (match_dup 0)
5101         (if_then_else:SFDF (ne (match_dup 6)
5102                                (match_dup 8))
5103                            (match_dup 4)
5104                            (match_dup 5)))]
5106   if (GET_CODE (operands[6]) == SCRATCH)
5107     operands[6] = gen_reg_rtx (V2DImode);
5109   operands[7] = CONSTM1_RTX (V2DImode);
5110   operands[8] = CONST0_RTX (V2DImode);
5112  [(set_attr "length" "8")
5113   (set_attr "type" "vecperm")])
5115 ;; Handle inverting the fpmask comparisons.
5116 (define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_invert_p9"
5117   [(set (match_operand:SFDF 0 "vsx_register_operand" "=&<SFDF:Fv>,<SFDF:Fv>")
5118         (if_then_else:SFDF
5119          (match_operator:CCFP 1 "invert_fpmask_comparison_operator"
5120                 [(match_operand:SFDF2 2 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")
5121                  (match_operand:SFDF2 3 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")])
5122          (match_operand:SFDF 4 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")
5123          (match_operand:SFDF 5 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")))
5124    (clobber (match_scratch:V2DI 6 "=0,&wa"))]
5125   "TARGET_P9_MINMAX"
5126   "#"
5127   "&& 1"
5128   [(set (match_dup 6)
5129         (if_then_else:V2DI (match_dup 9)
5130                            (match_dup 7)
5131                            (match_dup 8)))
5132    (set (match_dup 0)
5133         (if_then_else:SFDF (ne (match_dup 6)
5134                                (match_dup 8))
5135                            (match_dup 5)
5136                            (match_dup 4)))]
5138   rtx op1 = operands[1];
5139   enum rtx_code cond = reverse_condition_maybe_unordered (GET_CODE (op1));
5141   if (GET_CODE (operands[6]) == SCRATCH)
5142     operands[6] = gen_reg_rtx (V2DImode);
5144   operands[7] = CONSTM1_RTX (V2DImode);
5145   operands[8] = CONST0_RTX (V2DImode);
5147   operands[9] = gen_rtx_fmt_ee (cond, CCFPmode, operands[2], operands[3]);
5149  [(set_attr "length" "8")
5150   (set_attr "type" "vecperm")])
5152 (define_insn "*fpmask<mode>"
5153   [(set (match_operand:V2DI 0 "vsx_register_operand" "=wa")
5154         (if_then_else:V2DI
5155          (match_operator:CCFP 1 "fpmask_comparison_operator"
5156                 [(match_operand:SFDF 2 "vsx_register_operand" "<Fv>")
5157                  (match_operand:SFDF 3 "vsx_register_operand" "<Fv>")])
5158          (match_operand:V2DI 4 "all_ones_constant" "")
5159          (match_operand:V2DI 5 "zero_constant" "")))]
5160   "TARGET_P9_MINMAX"
5161   "xscmp%V1dp %x0,%x2,%x3"
5162   [(set_attr "type" "fpcompare")])
5164 (define_insn "*xxsel<mode>"
5165   [(set (match_operand:SFDF 0 "vsx_register_operand" "=<Fv>")
5166         (if_then_else:SFDF (ne (match_operand:V2DI 1 "vsx_register_operand" "wa")
5167                                (match_operand:V2DI 2 "zero_constant" ""))
5168                            (match_operand:SFDF 3 "vsx_register_operand" "<Fv>")
5169                            (match_operand:SFDF 4 "vsx_register_operand" "<Fv>")))]
5170   "TARGET_P9_MINMAX"
5171   "xxsel %x0,%x4,%x3,%x1"
5172   [(set_attr "type" "vecmove")])
5175 ;; Conversions to and from floating-point.
5177 ; We don't define lfiwax/lfiwzx with the normal definition, because we
5178 ; don't want to support putting SImode in FPR registers.
5179 (define_insn "lfiwax"
5180   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wj,wj,wK")
5181         (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r,wK")]
5182                    UNSPEC_LFIWAX))]
5183   "TARGET_HARD_FLOAT && TARGET_LFIWAX"
5184   "@
5185    lfiwax %0,%y1
5186    lxsiwax %x0,%y1
5187    mtvsrwa %x0,%1
5188    vextsw2d %0,%1"
5189   [(set_attr "type" "fpload,fpload,mffgpr,vecexts")])
5191 ; This split must be run before register allocation because it allocates the
5192 ; memory slot that is needed to move values to/from the FPR.  We don't allocate
5193 ; it earlier to allow for the combiner to merge insns together where it might
5194 ; not be needed and also in case the insns are deleted as dead code.
5196 (define_insn_and_split "floatsi<mode>2_lfiwax"
5197   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5198         (float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r")))
5199    (clobber (match_scratch:DI 2 "=wi"))]
5200   "TARGET_HARD_FLOAT && TARGET_LFIWAX
5201    && <SI_CONVERT_FP> && can_create_pseudo_p ()"
5202   "#"
5203   ""
5204   [(pc)]
5206   rtx dest = operands[0];
5207   rtx src = operands[1];
5208   rtx tmp;
5210   if (!MEM_P (src) && TARGET_POWERPC64
5211       && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5212     tmp = convert_to_mode (DImode, src, false);
5213   else
5214     {
5215       tmp = operands[2];
5216       if (GET_CODE (tmp) == SCRATCH)
5217         tmp = gen_reg_rtx (DImode);
5218       if (MEM_P (src))
5219         {
5220           src = rs6000_force_indexed_or_indirect_mem (src);
5221           emit_insn (gen_lfiwax (tmp, src));
5222         }
5223       else
5224         {
5225           rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5226           emit_move_insn (stack, src);
5227           emit_insn (gen_lfiwax (tmp, stack));
5228         }
5229     }
5230   emit_insn (gen_floatdi<mode>2 (dest, tmp));
5231   DONE;
5233   [(set_attr "length" "12")
5234    (set_attr "type" "fpload")])
5236 (define_insn_and_split "floatsi<mode>2_lfiwax_mem"
5237   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5238         (float:SFDF
5239          (sign_extend:DI
5240           (match_operand:SI 1 "indexed_or_indirect_operand" "Z"))))
5241    (clobber (match_scratch:DI 2 "=wi"))]
5242   "TARGET_HARD_FLOAT && TARGET_LFIWAX && <SI_CONVERT_FP>"
5243   "#"
5244   ""
5245   [(pc)]
5247   operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
5248   if (GET_CODE (operands[2]) == SCRATCH)
5249     operands[2] = gen_reg_rtx (DImode);
5250   if (TARGET_P8_VECTOR)
5251     emit_insn (gen_extendsidi2 (operands[2], operands[1]));
5252   else
5253     emit_insn (gen_lfiwax (operands[2], operands[1]));
5254   emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
5255   DONE;
5257   [(set_attr "length" "8")
5258    (set_attr "type" "fpload")])
5260 (define_insn "lfiwzx"
5261   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wj,wj,wJwK")
5262         (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r,wJwK")]
5263                    UNSPEC_LFIWZX))]
5264   "TARGET_HARD_FLOAT && TARGET_LFIWZX"
5265   "@
5266    lfiwzx %0,%y1
5267    lxsiwzx %x0,%y1
5268    mtvsrwz %x0,%1
5269    xxextractuw %x0,%x1,4"
5270   [(set_attr "type" "fpload,fpload,mftgpr,vecexts")])
5272 (define_insn_and_split "floatunssi<mode>2_lfiwzx"
5273   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5274         (unsigned_float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r")))
5275    (clobber (match_scratch:DI 2 "=wi"))]
5276   "TARGET_HARD_FLOAT && TARGET_LFIWZX && <SI_CONVERT_FP>"
5277   "#"
5278   ""
5279   [(pc)]
5281   rtx dest = operands[0];
5282   rtx src = operands[1];
5283   rtx tmp;
5285   if (!MEM_P (src) && TARGET_POWERPC64
5286       && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5287     tmp = convert_to_mode (DImode, src, true);
5288   else
5289     {
5290       tmp = operands[2];
5291       if (GET_CODE (tmp) == SCRATCH)
5292         tmp = gen_reg_rtx (DImode);
5293       if (MEM_P (src))
5294         {
5295           src = rs6000_force_indexed_or_indirect_mem (src);
5296           emit_insn (gen_lfiwzx (tmp, src));
5297         }
5298       else
5299         {
5300           rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5301           emit_move_insn (stack, src);
5302           emit_insn (gen_lfiwzx (tmp, stack));
5303         }
5304     }
5305   emit_insn (gen_floatdi<mode>2 (dest, tmp));
5306   DONE;
5308   [(set_attr "length" "12")
5309    (set_attr "type" "fpload")])
5311 (define_insn_and_split "floatunssi<mode>2_lfiwzx_mem"
5312   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5313         (unsigned_float:SFDF
5314          (zero_extend:DI
5315           (match_operand:SI 1 "indexed_or_indirect_operand" "Z"))))
5316    (clobber (match_scratch:DI 2 "=wi"))]
5317   "TARGET_HARD_FLOAT && TARGET_LFIWZX && <SI_CONVERT_FP>"
5318   "#"
5319   ""
5320   [(pc)]
5322   operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
5323   if (GET_CODE (operands[2]) == SCRATCH)
5324     operands[2] = gen_reg_rtx (DImode);
5325   if (TARGET_P8_VECTOR)
5326     emit_insn (gen_zero_extendsidi2 (operands[2], operands[1]));
5327   else
5328     emit_insn (gen_lfiwzx (operands[2], operands[1]));
5329   emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
5330   DONE;
5332   [(set_attr "length" "8")
5333    (set_attr "type" "fpload")])
5335 ; For each of these conversions, there is a define_expand, a define_insn
5336 ; with a '#' template, and a define_split (with C code).  The idea is
5337 ; to allow constant folding with the template of the define_insn,
5338 ; then to have the insns split later (between sched1 and final).
5340 (define_expand "floatsidf2"
5341   [(parallel [(set (match_operand:DF 0 "gpc_reg_operand")
5342                    (float:DF (match_operand:SI 1 "nonimmediate_operand")))
5343               (use (match_dup 2))
5344               (use (match_dup 3))
5345               (clobber (match_dup 4))
5346               (clobber (match_dup 5))
5347               (clobber (match_dup 6))])]
5348   "TARGET_HARD_FLOAT"
5350   if (TARGET_LFIWAX && TARGET_FCFID)
5351     {
5352       emit_insn (gen_floatsidf2_lfiwax (operands[0], operands[1]));
5353       DONE;
5354     }
5355   else if (TARGET_FCFID)
5356     {
5357       rtx dreg = operands[1];
5358       if (!REG_P (dreg))
5359         dreg = force_reg (SImode, dreg);
5360       dreg = convert_to_mode (DImode, dreg, false);
5361       emit_insn (gen_floatdidf2 (operands[0], dreg));
5362       DONE;
5363     }
5365   if (!REG_P (operands[1]))
5366     operands[1] = force_reg (SImode, operands[1]);
5367   operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5368   operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503601774854144\", DFmode));
5369   operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5370   operands[5] = gen_reg_rtx (DFmode);
5371   operands[6] = gen_reg_rtx (SImode);
5374 (define_insn_and_split "*floatsidf2_internal"
5375   [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5376         (float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5377    (use (match_operand:SI 2 "gpc_reg_operand" "r"))
5378    (use (match_operand:DF 3 "gpc_reg_operand" "d"))
5379    (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
5380    (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))
5381    (clobber (match_operand:SI 6 "gpc_reg_operand" "=&r"))]
5382   "!TARGET_FCFID && TARGET_HARD_FLOAT"
5383   "#"
5384   ""
5385   [(pc)]
5387   rtx lowword, highword;
5388   gcc_assert (MEM_P (operands[4]));
5389   highword = adjust_address (operands[4], SImode, 0);
5390   lowword = adjust_address (operands[4], SImode, 4);
5391   if (! WORDS_BIG_ENDIAN)
5392     std::swap (lowword, highword);
5394   emit_insn (gen_xorsi3 (operands[6], operands[1],
5395                          GEN_INT (~ (HOST_WIDE_INT) 0x7fffffff)));
5396   emit_move_insn (lowword, operands[6]);
5397   emit_move_insn (highword, operands[2]);
5398   emit_move_insn (operands[5], operands[4]);
5399   emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5400   DONE;
5402   [(set_attr "length" "24")
5403    (set_attr "type" "fp")])
5405 ;; If we don't have a direct conversion to single precision, don't enable this
5406 ;; conversion for 32-bit without fast math, because we don't have the insn to
5407 ;; generate the fixup swizzle to avoid double rounding problems.
5408 (define_expand "floatunssisf2"
5409   [(set (match_operand:SF 0 "gpc_reg_operand")
5410         (unsigned_float:SF (match_operand:SI 1 "nonimmediate_operand")))]
5411   "TARGET_HARD_FLOAT
5412    && ((TARGET_FCFIDUS && TARGET_LFIWZX)
5413        || (TARGET_FCFID
5414            && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))"
5416   if (TARGET_LFIWZX && TARGET_FCFIDUS)
5417     {
5418       emit_insn (gen_floatunssisf2_lfiwzx (operands[0], operands[1]));
5419       DONE;
5420     }
5421   else
5422     {
5423       rtx dreg = operands[1];
5424       if (!REG_P (dreg))
5425         dreg = force_reg (SImode, dreg);
5426       dreg = convert_to_mode (DImode, dreg, true);
5427       emit_insn (gen_floatdisf2 (operands[0], dreg));
5428       DONE;
5429     }
5432 (define_expand "floatunssidf2"
5433   [(parallel [(set (match_operand:DF 0 "gpc_reg_operand")
5434                    (unsigned_float:DF (match_operand:SI 1 "nonimmediate_operand")))
5435               (use (match_dup 2))
5436               (use (match_dup 3))
5437               (clobber (match_dup 4))
5438               (clobber (match_dup 5))])]
5439   "TARGET_HARD_FLOAT"
5441   if (TARGET_LFIWZX && TARGET_FCFID)
5442     {
5443       emit_insn (gen_floatunssidf2_lfiwzx (operands[0], operands[1]));
5444       DONE;
5445     }
5446   else if (TARGET_FCFID)
5447     {
5448       rtx dreg = operands[1];
5449       if (!REG_P (dreg))
5450         dreg = force_reg (SImode, dreg);
5451       dreg = convert_to_mode (DImode, dreg, true);
5452       emit_insn (gen_floatdidf2 (operands[0], dreg));
5453       DONE;
5454     }
5456   if (!REG_P (operands[1]))
5457     operands[1] = force_reg (SImode, operands[1]);
5458   operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5459   operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503599627370496\", DFmode));
5460   operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5461   operands[5] = gen_reg_rtx (DFmode);
5464 (define_insn_and_split "*floatunssidf2_internal"
5465   [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5466         (unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5467    (use (match_operand:SI 2 "gpc_reg_operand" "r"))
5468    (use (match_operand:DF 3 "gpc_reg_operand" "d"))
5469    (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
5470    (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))]
5471   "!TARGET_FCFIDU && TARGET_HARD_FLOAT
5472    && !(TARGET_FCFID && TARGET_POWERPC64)"
5473   "#"
5474   ""
5475   [(pc)]
5477   rtx lowword, highword;
5478   gcc_assert (MEM_P (operands[4]));
5479   highword = adjust_address (operands[4], SImode, 0);
5480   lowword = adjust_address (operands[4], SImode, 4);
5481   if (! WORDS_BIG_ENDIAN)
5482     std::swap (lowword, highword);
5484   emit_move_insn (lowword, operands[1]);
5485   emit_move_insn (highword, operands[2]);
5486   emit_move_insn (operands[5], operands[4]);
5487   emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5488   DONE;
5490   [(set_attr "length" "20")
5491    (set_attr "type" "fp")])
5493 ;; ISA 3.0 adds instructions lxsi[bh]zx to directly load QImode and HImode to
5494 ;; vector registers.  These insns favor doing the sign/zero extension in
5495 ;; the vector registers, rather then loading up a GPR, doing a sign/zero
5496 ;; extension and then a direct move.
5498 (define_expand "float<QHI:mode><FP_ISA3:mode>2"
5499   [(parallel [(set (match_operand:FP_ISA3 0 "vsx_register_operand")
5500                    (float:FP_ISA3
5501                     (match_operand:QHI 1 "input_operand")))
5502               (clobber (match_scratch:DI 2))
5503               (clobber (match_scratch:DI 3))
5504               (clobber (match_scratch:<QHI:MODE> 4))])]
5505   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5507   if (MEM_P (operands[1]))
5508     operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
5511 (define_insn_and_split "*float<QHI:mode><FP_ISA3:mode>2_internal"
5512   [(set (match_operand:FP_ISA3 0 "vsx_register_operand" "=<Fv>,<Fv>,<Fv>")
5513         (float:FP_ISA3
5514          (match_operand:QHI 1 "reg_or_indexed_operand" "wK,r,Z")))
5515    (clobber (match_scratch:DI 2 "=wK,wi,wK"))
5516    (clobber (match_scratch:DI 3 "=X,r,X"))
5517    (clobber (match_scratch:<QHI:MODE> 4 "=X,X,wK"))]
5518   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5519   "#"
5520   "&& reload_completed"
5521   [(const_int 0)]
5523   rtx result = operands[0];
5524   rtx input = operands[1];
5525   rtx di = operands[2];
5527   if (!MEM_P (input))
5528     {
5529       rtx tmp = operands[3];
5530       if (altivec_register_operand (input, <QHI:MODE>mode))
5531         emit_insn (gen_extend<QHI:mode>di2 (di, input));
5532       else if (GET_CODE (tmp) == SCRATCH)
5533         emit_insn (gen_extend<QHI:mode>di2 (di, input));
5534       else
5535         {
5536           emit_insn (gen_extend<QHI:mode>di2 (tmp, input));
5537           emit_move_insn (di, tmp);
5538         }
5539     }
5540   else
5541     {
5542       rtx tmp = operands[4];
5543       emit_move_insn (tmp, input);
5544       emit_insn (gen_extend<QHI:mode>di2 (di, tmp));
5545     }
5547   emit_insn (gen_floatdi<FP_ISA3:mode>2 (result, di));
5548   DONE;
5551 (define_expand "floatuns<QHI:mode><FP_ISA3:mode>2"
5552   [(parallel [(set (match_operand:FP_ISA3 0 "vsx_register_operand")
5553                    (unsigned_float:FP_ISA3
5554                     (match_operand:QHI 1 "input_operand")))
5555               (clobber (match_scratch:DI 2))
5556               (clobber (match_scratch:DI 3))])]
5557   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5559   if (MEM_P (operands[1]))
5560     operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
5563 (define_insn_and_split "*floatuns<QHI:mode><FP_ISA3:mode>2_internal"
5564   [(set (match_operand:FP_ISA3 0 "vsx_register_operand" "=<Fv>,<Fv>,<Fv>")
5565         (unsigned_float:FP_ISA3
5566          (match_operand:QHI 1 "reg_or_indexed_operand" "wK,r,Z")))
5567    (clobber (match_scratch:DI 2 "=wK,wi,wJwK"))
5568    (clobber (match_scratch:DI 3 "=X,r,X"))]
5569   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5570   "#"
5571   "&& reload_completed"
5572   [(const_int 0)]
5574   rtx result = operands[0];
5575   rtx input = operands[1];
5576   rtx di = operands[2];
5578   if (MEM_P (input) || altivec_register_operand (input, <QHI:MODE>mode))
5579     emit_insn (gen_zero_extend<QHI:mode>di2 (di, input));
5580   else
5581     {
5582       rtx tmp = operands[3];
5583       if (GET_CODE (tmp) == SCRATCH)
5584         emit_insn (gen_extend<QHI:mode>di2 (di, input));
5585       else
5586         {
5587           emit_insn (gen_zero_extend<QHI:mode>di2 (tmp, input));
5588           emit_move_insn (di, tmp);
5589         }
5590     }
5592   emit_insn (gen_floatdi<FP_ISA3:mode>2 (result, di));
5593   DONE;
5596 (define_expand "fix_trunc<mode>si2"
5597   [(set (match_operand:SI 0 "gpc_reg_operand")
5598         (fix:SI (match_operand:SFDF 1 "gpc_reg_operand")))]
5599   "TARGET_HARD_FLOAT"
5601   if (!(TARGET_P8_VECTOR && TARGET_DIRECT_MOVE))
5602     {
5603       rtx src = force_reg (<MODE>mode, operands[1]);
5605       if (TARGET_STFIWX)
5606         emit_insn (gen_fix_trunc<mode>si2_stfiwx (operands[0], src));
5607       else
5608         {
5609           rtx tmp = gen_reg_rtx (DImode);
5610           rtx stack = rs6000_allocate_stack_temp (DImode, true, false);
5611           emit_insn (gen_fix_trunc<mode>si2_internal (operands[0], src,
5612                                                       tmp, stack));
5613         }
5614       DONE;
5615     }
5618 ; Like the convert to float patterns, this insn must be split before
5619 ; register allocation so that it can allocate the memory slot if it
5620 ; needed
5621 (define_insn_and_split "fix_trunc<mode>si2_stfiwx"
5622   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5623         (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
5624    (clobber (match_scratch:DI 2 "=d"))]
5625   "TARGET_HARD_FLOAT && TARGET_STFIWX && can_create_pseudo_p ()
5626    && !(TARGET_P8_VECTOR && TARGET_DIRECT_MOVE)"
5627   "#"
5628   ""
5629   [(pc)]
5631   rtx dest = operands[0];
5632   rtx src = operands[1];
5633   rtx tmp = operands[2];
5635   if (GET_CODE (tmp) == SCRATCH)
5636     tmp = gen_reg_rtx (DImode);
5638   emit_insn (gen_fctiwz_<mode> (tmp, src));
5639   if (MEM_P (dest))
5640     {
5641       dest = rs6000_force_indexed_or_indirect_mem (dest);
5642       emit_insn (gen_stfiwx (dest, tmp));
5643       DONE;
5644     }
5645   else if (TARGET_POWERPC64 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5646     {
5647       dest = gen_lowpart (DImode, dest);
5648       emit_move_insn (dest, tmp);
5649       DONE;
5650     }
5651   else
5652     {
5653       rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5654       emit_insn (gen_stfiwx (stack, tmp));
5655       emit_move_insn (dest, stack);
5656       DONE;
5657     }
5659   [(set_attr "length" "12")
5660    (set_attr "type" "fp")])
5662 (define_insn_and_split "fix_trunc<mode>si2_internal"
5663   [(set (match_operand:SI 0 "gpc_reg_operand" "=r,?r")
5664         (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d,<rreg>")))
5665    (clobber (match_operand:DI 2 "gpc_reg_operand" "=1,d"))
5666    (clobber (match_operand:DI 3 "offsettable_mem_operand" "=o,o"))]
5667   "TARGET_HARD_FLOAT
5668    && !(TARGET_P8_VECTOR && TARGET_DIRECT_MOVE)"
5669   "#"
5670   ""
5671   [(pc)]
5673   rtx lowword;
5674   gcc_assert (MEM_P (operands[3]));
5675   lowword = adjust_address (operands[3], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
5677   emit_insn (gen_fctiwz_<mode> (operands[2], operands[1]));
5678   emit_move_insn (operands[3], operands[2]);
5679   emit_move_insn (operands[0], lowword);
5680   DONE;
5682   [(set_attr "length" "16")
5683    (set_attr "type" "fp")])
5685 (define_expand "fix_trunc<mode>di2"
5686   [(set (match_operand:DI 0 "gpc_reg_operand")
5687         (fix:DI (match_operand:SFDF 1 "gpc_reg_operand")))]
5688   "TARGET_HARD_FLOAT && TARGET_FCFID"
5689   "")
5691 (define_insn "*fix_trunc<mode>di2_fctidz"
5692   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5693         (fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
5694   "TARGET_HARD_FLOAT && TARGET_FCFID"
5695   "@
5696    fctidz %0,%1
5697    xscvdpsxds %x0,%x1"
5698   [(set_attr "type" "fp")])
5700 ;; If we have ISA 3.0, QI/HImode values can go in both VSX registers and GPR
5701 ;; registers.  If we have ISA 2.07, we don't allow QI/HImode values in the
5702 ;; vector registers, so we need to do direct moves to the GPRs, but SImode
5703 ;; values can go in VSX registers.  Keeping the direct move part through
5704 ;; register allocation prevents the register allocator from doing a direct move
5705 ;; of the SImode value to a GPR, and then a store/load.
5706 (define_insn_and_split "fix<uns>_trunc<SFDF:mode><QHI:mode>2"
5707   [(set (match_operand:<QHI:MODE> 0 "gpc_reg_operand" "=wJ,wJwK,r")
5708         (any_fix:QHI (match_operand:SFDF 1 "gpc_reg_operand" "wJ,wJwK,wa")))
5709    (clobber (match_scratch:SI 2 "=X,X,wi"))]
5710   "TARGET_DIRECT_MOVE"
5711   "@
5712    fctiw<u>z %0,%1
5713    xscvdp<su>xws %x0,%x1
5714    #"
5715   "&& reload_completed && int_reg_operand (operands[0], <QHI:MODE>mode)"
5716   [(set (match_dup 2)
5717         (any_fix:SI (match_dup 1)))
5718    (set (match_dup 3)
5719         (match_dup 2))]
5721   operands[3] = gen_rtx_REG (SImode, REGNO (operands[0]));
5723   [(set_attr "length" "4,4,8")
5724    (set_attr "type" "fp")])
5726 (define_insn "*fix<uns>_trunc<SFDF:mode>si2_p8"
5727   [(set (match_operand:SI 0 "gpc_reg_operand" "=d,wa")
5728         (any_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d,wa")))]
5729   "TARGET_DIRECT_MOVE"
5730   "@
5731    fctiw<u>z %0,%1
5732    xscvdp<su>xws %x0,%x1"
5733   [(set_attr "type" "fp")])
5735 ;; Keep the convert and store together through register allocation to prevent
5736 ;; the register allocator from getting clever and doing a direct move to a GPR
5737 ;; and then store for reg+offset stores.
5738 (define_insn_and_split "*fix<uns>_trunc<SFDF:mode><QHSI:mode>2_mem"
5739   [(set (match_operand:QHSI 0 "memory_operand" "=Z")
5740         (any_fix:QHSI (match_operand:SFDF 1 "gpc_reg_operand" "wa")))
5741    (clobber (match_scratch:SI 2 "=wa"))]
5742     "(<QHSI:MODE>mode == SImode && TARGET_P8_VECTOR) || TARGET_P9_VECTOR"
5743   "#"
5744   "&& reload_completed"
5745   [(set (match_dup 2)
5746         (any_fix:SI (match_dup 1)))
5747    (set (match_dup 0)
5748         (match_dup 3))]
5750   operands[3] = (<QHSI:MODE>mode == SImode
5751                  ? operands[2]
5752                  : gen_rtx_REG (<QHSI:MODE>mode, REGNO (operands[2])));
5755 (define_expand "fixuns_trunc<mode>si2"
5756   [(set (match_operand:SI 0 "gpc_reg_operand")
5757         (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand")))]
5758   "TARGET_HARD_FLOAT && TARGET_FCTIWUZ && TARGET_STFIWX"
5760   if (!TARGET_P8_VECTOR)
5761     {
5762       emit_insn (gen_fixuns_trunc<mode>si2_stfiwx (operands[0], operands[1]));
5763       DONE;
5764     }
5767 (define_insn_and_split "fixuns_trunc<mode>si2_stfiwx"
5768   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5769         (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
5770    (clobber (match_scratch:DI 2 "=d"))]
5771   "TARGET_HARD_FLOAT && TARGET_FCTIWUZ
5772    && TARGET_STFIWX && can_create_pseudo_p ()
5773    && !TARGET_P8_VECTOR"
5774   "#"
5775   ""
5776   [(pc)]
5778   rtx dest = operands[0];
5779   rtx src = operands[1];
5780   rtx tmp = operands[2];
5782   if (GET_CODE (tmp) == SCRATCH)
5783     tmp = gen_reg_rtx (DImode);
5785   emit_insn (gen_fctiwuz_<mode> (tmp, src));
5786   if (MEM_P (dest))
5787     {
5788       dest = rs6000_force_indexed_or_indirect_mem (dest);
5789       emit_insn (gen_stfiwx (dest, tmp));
5790       DONE;
5791     }
5792   else if (TARGET_POWERPC64 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5793     {
5794       dest = gen_lowpart (DImode, dest);
5795       emit_move_insn (dest, tmp);
5796       DONE;
5797     }
5798   else
5799     {
5800       rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5801       emit_insn (gen_stfiwx (stack, tmp));
5802       emit_move_insn (dest, stack);
5803       DONE;
5804     }
5806   [(set_attr "length" "12")
5807    (set_attr "type" "fp")])
5809 (define_insn "fixuns_trunc<mode>di2"
5810   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5811         (unsigned_fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
5812   "TARGET_HARD_FLOAT && TARGET_FCTIDUZ"
5813   "@
5814    fctiduz %0,%1
5815    xscvdpuxds %x0,%x1"
5816   [(set_attr "type" "fp")])
5818 (define_insn "rs6000_mtfsb0"
5819   [(unspec_volatile [(match_operand:SI 0 "u5bit_cint_operand" "n")]
5820                     UNSPECV_MTFSB0)]
5821   "TARGET_HARD_FLOAT"
5822   "mtfsb0 %0"
5823   [(set_attr "type" "fp")])
5825 (define_insn "rs6000_mtfsb1"
5826   [(unspec_volatile [(match_operand:SI 0 "u5bit_cint_operand" "n")]
5827                     UNSPECV_MTFSB1)]
5828   "TARGET_HARD_FLOAT"
5829   "mtfsb1 %0"
5830   [(set_attr "type" "fp")])
5832 (define_insn "rs6000_mffscrn"
5833   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
5834         (unspec_volatile:DF [(match_operand:DF 1 "gpc_reg_operand" "d")]
5835                             UNSPECV_MFFSCRN))]
5836    "TARGET_P9_MISC"
5837    "mffscrn %0,%1"
5838   [(set_attr "type" "fp")])
5840 (define_insn "rs6000_mffscdrn"
5841   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
5842    (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFSCDRN))
5843    (use (match_operand:DF 1 "gpc_reg_operand" "d"))]
5844   "TARGET_P9_MISC"
5845   "mffscdrn %0,%1"
5846   [(set_attr "type" "fp")])
5848 (define_expand "rs6000_set_fpscr_rn"
5849  [(match_operand:DI 0 "reg_or_cint_operand")]
5850   "TARGET_HARD_FLOAT"
5852   rtx tmp_df = gen_reg_rtx (DFmode);
5854   /* The floating point rounding control bits are FPSCR[62:63]. Put the
5855      new rounding mode bits from operands[0][62:63] into FPSCR[62:63].  */
5856   if (TARGET_P9_MISC)
5857     {
5858       rtx src_df = force_reg (DImode, operands[0]);
5859       src_df = simplify_gen_subreg (DFmode, src_df, DImode, 0);
5860       emit_insn (gen_rs6000_mffscrn (tmp_df, src_df));
5861       DONE;
5862     }
5864   if (CONST_INT_P (operands[0]))
5865     {
5866       if ((INTVAL (operands[0]) & 0x1) == 0x1)
5867         emit_insn (gen_rs6000_mtfsb1 (GEN_INT (31)));
5868       else
5869         emit_insn (gen_rs6000_mtfsb0 (GEN_INT (31)));
5871       if ((INTVAL (operands[0]) & 0x2) == 0x2)
5872         emit_insn (gen_rs6000_mtfsb1 (GEN_INT (30)));
5873       else
5874         emit_insn (gen_rs6000_mtfsb0 (GEN_INT (30)));
5875     }
5876   else
5877     {
5878       rtx tmp_rn = gen_reg_rtx (DImode);
5879       rtx tmp_di = gen_reg_rtx (DImode);
5881       /* Extract new RN mode from operand.  */
5882       emit_insn (gen_anddi3 (tmp_rn, operands[0], GEN_INT (0x3)));
5884       /* Insert new RN mode into FSCPR.  */
5885       emit_insn (gen_rs6000_mffs (tmp_df));
5886       tmp_di = simplify_gen_subreg (DImode, tmp_df, DFmode, 0);
5887       emit_insn (gen_anddi3 (tmp_di, tmp_di, GEN_INT (-4)));
5888       emit_insn (gen_iordi3 (tmp_di, tmp_di, tmp_rn));
5890       /* Need to write to field k=15.  The fields are [0:15].  Hence with
5891          L=0, W=0, FLM_i must be equal to 8, 16 = i + 8*(1-W).  FLM is an
5892          8-bit field[0:7]. Need to set the bit that corresponds to the
5893          value of i that you want [0:7].  */
5894       tmp_df = simplify_gen_subreg (DFmode, tmp_di, DImode, 0);
5895       emit_insn (gen_rs6000_mtfsf (GEN_INT (0x01), tmp_df));
5896     }
5897   DONE;
5900 (define_expand "rs6000_set_fpscr_drn"
5901   [(match_operand:DI 0  "gpc_reg_operand")]
5902   "TARGET_HARD_FLOAT"
5904   rtx tmp_df = gen_reg_rtx (DFmode);
5906   /* The decimal floating point rounding control bits are FPSCR[29:31]. Put the
5907      new rounding mode bits from operands[0][61:63] into FPSCR[29:31].  */
5908   if (TARGET_P9_MISC)
5909     {
5910       rtx src_df = gen_reg_rtx (DFmode);
5912       emit_insn (gen_ashldi3 (operands[0], operands[0], GEN_INT (32)));
5913       src_df = simplify_gen_subreg (DFmode, operands[0], DImode, 0);
5914       emit_insn (gen_rs6000_mffscdrn (tmp_df, src_df));
5915     }
5916   else
5917     {
5918       rtx tmp_rn = gen_reg_rtx (DImode);
5919       rtx tmp_di = gen_reg_rtx (DImode);
5921       /* Extract new DRN mode from operand.  */
5922       emit_insn (gen_anddi3 (tmp_rn, operands[0], GEN_INT (0x7)));
5923       emit_insn (gen_ashldi3 (tmp_rn, tmp_rn, GEN_INT (32)));
5925       /* Insert new RN mode into FSCPR.  */
5926       emit_insn (gen_rs6000_mffs (tmp_df));
5927       tmp_di = simplify_gen_subreg (DImode, tmp_df, DFmode, 0);
5928       emit_insn (gen_anddi3 (tmp_di, tmp_di, GEN_INT (0xFFFFFFF8FFFFFFFF)));
5929       emit_insn (gen_iordi3 (tmp_di, tmp_di, tmp_rn));
5931       /* Need to write to field 7.  The fields are [0:15].  The equation to
5932          select the field is i + 8*(1-W). Hence with L=0 and W=1, need to set
5933          i to 0x1 to get field 7 where i selects the field.  */
5934       tmp_df = simplify_gen_subreg (DFmode, tmp_di, DImode, 0);
5935       emit_insn (gen_rs6000_mtfsf_hi (GEN_INT (0x01), tmp_df));
5936     }
5937   DONE;
5940 ;; Here, we use (set (reg) (unspec:DI [(fix:SI ...)] UNSPEC_FCTIWZ))
5941 ;; rather than (set (subreg:SI (reg)) (fix:SI ...))
5942 ;; because the first makes it clear that operand 0 is not live
5943 ;; before the instruction.
5944 (define_insn "fctiwz_<mode>"
5945   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5946         (unspec:DI [(fix:SI
5947                      (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
5948                    UNSPEC_FCTIWZ))]
5949   "TARGET_HARD_FLOAT"
5950   "@
5951    fctiwz %0,%1
5952    xscvdpsxws %x0,%x1"
5953   [(set_attr "type" "fp")])
5955 (define_insn "fctiwuz_<mode>"
5956   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5957         (unspec:DI [(unsigned_fix:SI
5958                      (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
5959                    UNSPEC_FCTIWUZ))]
5960   "TARGET_HARD_FLOAT && TARGET_FCTIWUZ"
5961   "@
5962    fctiwuz %0,%1
5963    xscvdpuxws %x0,%x1"
5964   [(set_attr "type" "fp")])
5966 ;; Only optimize (float (fix x)) -> frz if we are in fast-math mode, since
5967 ;; since the friz instruction does not truncate the value if the floating
5968 ;; point value is < LONG_MIN or > LONG_MAX.
5969 (define_insn "*friz"
5970   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
5971         (float:DF (fix:DI (match_operand:DF 1 "gpc_reg_operand" "d,ws"))))]
5972   "TARGET_HARD_FLOAT && TARGET_FPRND
5973    && flag_unsafe_math_optimizations && !flag_trapping_math && TARGET_FRIZ"
5974   "@
5975    friz %0,%1
5976    xsrdpiz %x0,%x1"
5977   [(set_attr "type" "fp")])
5979 ;; Opitmize converting SF/DFmode to signed SImode and back to SF/DFmode.  This
5980 ;; optimization prevents on ISA 2.06 systems and earlier having to store the
5981 ;; value from the FPR/vector unit to the stack, load the value into a GPR, sign
5982 ;; extend it, store it back on the stack from the GPR, load it back into the
5983 ;; FP/vector unit to do the rounding. If we have direct move (ISA 2.07),
5984 ;; disable using store and load to sign/zero extend the value.
5985 (define_insn_and_split "*round32<mode>2_fprs"
5986   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
5987         (float:SFDF
5988          (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
5989    (clobber (match_scratch:DI 2 "=d"))
5990    (clobber (match_scratch:DI 3 "=d"))]
5991   "TARGET_HARD_FLOAT
5992    && <SI_CONVERT_FP> && TARGET_LFIWAX && TARGET_STFIWX && TARGET_FCFID
5993    && !TARGET_DIRECT_MOVE && can_create_pseudo_p ()"
5994   "#"
5995   ""
5996   [(pc)]
5998   rtx dest = operands[0];
5999   rtx src = operands[1];
6000   rtx tmp1 = operands[2];
6001   rtx tmp2 = operands[3];
6002   rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
6004   if (GET_CODE (tmp1) == SCRATCH)
6005     tmp1 = gen_reg_rtx (DImode);
6006   if (GET_CODE (tmp2) == SCRATCH)
6007     tmp2 = gen_reg_rtx (DImode);
6009   emit_insn (gen_fctiwz_<mode> (tmp1, src));
6010   emit_insn (gen_stfiwx (stack, tmp1));
6011   emit_insn (gen_lfiwax (tmp2, stack));
6012   emit_insn (gen_floatdi<mode>2 (dest, tmp2));
6013   DONE;
6015   [(set_attr "type" "fpload")
6016    (set_attr "length" "16")])
6018 (define_insn_and_split "*roundu32<mode>2_fprs"
6019   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
6020         (unsigned_float:SFDF
6021          (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
6022    (clobber (match_scratch:DI 2 "=d"))
6023    (clobber (match_scratch:DI 3 "=d"))]
6024   "TARGET_HARD_FLOAT
6025    && TARGET_LFIWZX && TARGET_STFIWX && TARGET_FCFIDU && !TARGET_DIRECT_MOVE
6026    && can_create_pseudo_p ()"
6027   "#"
6028   ""
6029   [(pc)]
6031   rtx dest = operands[0];
6032   rtx src = operands[1];
6033   rtx tmp1 = operands[2];
6034   rtx tmp2 = operands[3];
6035   rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
6037   if (GET_CODE (tmp1) == SCRATCH)
6038     tmp1 = gen_reg_rtx (DImode);
6039   if (GET_CODE (tmp2) == SCRATCH)
6040     tmp2 = gen_reg_rtx (DImode);
6042   emit_insn (gen_fctiwuz_<mode> (tmp1, src));
6043   emit_insn (gen_stfiwx (stack, tmp1));
6044   emit_insn (gen_lfiwzx (tmp2, stack));
6045   emit_insn (gen_floatdi<mode>2 (dest, tmp2));
6046   DONE;
6048   [(set_attr "type" "fpload")
6049    (set_attr "length" "16")])
6051 ;; No VSX equivalent to fctid
6052 (define_insn "lrint<mode>di2"
6053   [(set (match_operand:DI 0 "gpc_reg_operand" "=d")
6054         (unspec:DI [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
6055                    UNSPEC_FCTID))]
6056   "TARGET_HARD_FLOAT && TARGET_FPRND"
6057   "fctid %0,%1"
6058   [(set_attr "type" "fp")])
6060 (define_insn "btrunc<mode>2"
6061   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
6062         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
6063                      UNSPEC_FRIZ))]
6064   "TARGET_HARD_FLOAT && TARGET_FPRND"
6065   "@
6066    friz %0,%1
6067    xsrdpiz %x0,%x1"
6068   [(set_attr "type" "fp")])
6070 (define_insn "ceil<mode>2"
6071   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
6072         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
6073                      UNSPEC_FRIP))]
6074   "TARGET_HARD_FLOAT && TARGET_FPRND"
6075   "@
6076    frip %0,%1
6077    xsrdpip %x0,%x1"
6078   [(set_attr "type" "fp")])
6080 (define_insn "floor<mode>2"
6081   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
6082         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
6083                      UNSPEC_FRIM))]
6084   "TARGET_HARD_FLOAT && TARGET_FPRND"
6085   "@
6086    frim %0,%1
6087    xsrdpim %x0,%x1"
6088   [(set_attr "type" "fp")])
6090 ;; No VSX equivalent to frin
6091 (define_insn "round<mode>2"
6092   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<rreg2>")
6093         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
6094                      UNSPEC_FRIN))]
6095   "TARGET_HARD_FLOAT && TARGET_FPRND"
6096   "frin %0,%1"
6097   [(set_attr "type" "fp")])
6099 (define_insn "*xsrdpi<mode>2"
6100   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
6101         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Fv>")]
6102                      UNSPEC_XSRDPI))]
6103   "TARGET_HARD_FLOAT && TARGET_VSX"
6104   "xsrdpi %x0,%x1"
6105   [(set_attr "type" "fp")])
6107 (define_expand "lround<mode>di2"
6108   [(set (match_dup 2)
6109         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand")]
6110                      UNSPEC_XSRDPI))
6111    (set (match_operand:DI 0 "gpc_reg_operand")
6112         (unspec:DI [(match_dup 2)]
6113                    UNSPEC_FCTID))]
6114   "TARGET_HARD_FLOAT && TARGET_VSX && TARGET_FPRND"
6116   operands[2] = gen_reg_rtx (<MODE>mode);
6119 ; An UNSPEC is used so we don't have to support SImode in FP registers.
6120 ; The 'wu' constraint is used for the 2nd alternative to ensure stxsiwx
6121 ; is only generated for Power8 or later.
6122 (define_insn "stfiwx"
6123   [(set (match_operand:SI 0 "memory_operand" "=Z,Z")
6124         (unspec:SI [(match_operand:DI 1 "gpc_reg_operand" "d,wu")]
6125                    UNSPEC_STFIWX))]
6126   "TARGET_PPC_GFXOPT"
6127   "@
6128    stfiwx %1,%y0
6129    stxsiwx %x1,%y0"
6130   [(set_attr "type" "fpstore")])
6132 ;; If we don't have a direct conversion to single precision, don't enable this
6133 ;; conversion for 32-bit without fast math, because we don't have the insn to
6134 ;; generate the fixup swizzle to avoid double rounding problems.
6135 (define_expand "floatsisf2"
6136   [(set (match_operand:SF 0 "gpc_reg_operand")
6137         (float:SF (match_operand:SI 1 "nonimmediate_operand")))]
6138   "TARGET_HARD_FLOAT
6139    && ((TARGET_FCFIDS && TARGET_LFIWAX)
6140        || (TARGET_FCFID
6141            && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))"
6143   if (TARGET_FCFIDS && TARGET_LFIWAX)
6144     {
6145       emit_insn (gen_floatsisf2_lfiwax (operands[0], operands[1]));
6146       DONE;
6147     }
6148   else if (TARGET_FCFID && TARGET_LFIWAX)
6149     {
6150       rtx dfreg = gen_reg_rtx (DFmode);
6151       emit_insn (gen_floatsidf2_lfiwax (dfreg, operands[1]));
6152       emit_insn (gen_truncdfsf2 (operands[0], dfreg));
6153       DONE;
6154     }
6155   else
6156     {
6157       rtx dreg = operands[1];
6158       if (!REG_P (dreg))
6159         dreg = force_reg (SImode, dreg);
6160       dreg = convert_to_mode (DImode, dreg, false);
6161       emit_insn (gen_floatdisf2 (operands[0], dreg));
6162       DONE;
6163     }
6166 (define_insn "floatdidf2"
6167   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
6168         (float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
6169   "TARGET_FCFID && TARGET_HARD_FLOAT"
6170   "@
6171    fcfid %0,%1
6172    xscvsxddp %x0,%x1"
6173   [(set_attr "type" "fp")])
6175 ; Allow the combiner to merge source memory operands to the conversion so that
6176 ; the optimizer/register allocator doesn't try to load the value too early in a
6177 ; GPR and then use store/load to move it to a FPR and suffer from a store-load
6178 ; hit.  We will split after reload to avoid the trip through the GPRs
6180 (define_insn_and_split "*floatdidf2_mem"
6181   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
6182         (float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
6183    (clobber (match_scratch:DI 2 "=d,wi"))]
6184   "TARGET_HARD_FLOAT && TARGET_FCFID"
6185   "#"
6186   "&& reload_completed"
6187   [(set (match_dup 2) (match_dup 1))
6188    (set (match_dup 0) (float:DF (match_dup 2)))]
6189   ""
6190   [(set_attr "length" "8")
6191    (set_attr "type" "fpload")])
6193 (define_expand "floatunsdidf2"
6194   [(set (match_operand:DF 0 "gpc_reg_operand")
6195         (unsigned_float:DF
6196          (match_operand:DI 1 "gpc_reg_operand")))]
6197   "TARGET_HARD_FLOAT && TARGET_FCFIDU"
6198   "")
6200 (define_insn "*floatunsdidf2_fcfidu"
6201   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
6202         (unsigned_float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
6203   "TARGET_HARD_FLOAT && TARGET_FCFIDU"
6204   "@
6205    fcfidu %0,%1
6206    xscvuxddp %x0,%x1"
6207   [(set_attr "type" "fp")])
6209 (define_insn_and_split "*floatunsdidf2_mem"
6210   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
6211         (unsigned_float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
6212    (clobber (match_scratch:DI 2 "=d,wi"))]
6213   "TARGET_HARD_FLOAT && (TARGET_FCFIDU || VECTOR_UNIT_VSX_P (DFmode))"
6214   "#"
6215   "&& reload_completed"
6216   [(set (match_dup 2) (match_dup 1))
6217    (set (match_dup 0) (unsigned_float:DF (match_dup 2)))]
6218   ""
6219   [(set_attr "length" "8")
6220    (set_attr "type" "fpload")])
6222 (define_expand "floatdisf2"
6223   [(set (match_operand:SF 0 "gpc_reg_operand")
6224         (float:SF (match_operand:DI 1 "gpc_reg_operand")))]
6225   "TARGET_FCFID && TARGET_HARD_FLOAT
6226    && (TARGET_FCFIDS || TARGET_POWERPC64 || flag_unsafe_math_optimizations)"
6228   if (!TARGET_FCFIDS)
6229     {
6230       rtx val = operands[1];
6231       if (!flag_unsafe_math_optimizations)
6232         {
6233           rtx label = gen_label_rtx ();
6234           val = gen_reg_rtx (DImode);
6235           emit_insn (gen_floatdisf2_internal2 (val, operands[1], label));
6236           emit_label (label);
6237         }
6238       emit_insn (gen_floatdisf2_internal1 (operands[0], val));
6239       DONE;
6240     }
6243 (define_insn "floatdisf2_fcfids"
6244   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy")
6245         (float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
6246   "TARGET_HARD_FLOAT && TARGET_FCFIDS"
6247   "@
6248    fcfids %0,%1
6249    xscvsxdsp %x0,%x1"
6250   [(set_attr "type" "fp")])
6252 (define_insn_and_split "*floatdisf2_mem"
6253   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy,wy")
6254         (float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
6255    (clobber (match_scratch:DI 2 "=d,d,wi"))]
6256   "TARGET_HARD_FLOAT && TARGET_FCFIDS"
6257   "#"
6258   "&& reload_completed"
6259   [(pc)]
6261   emit_move_insn (operands[2], operands[1]);
6262   emit_insn (gen_floatdisf2_fcfids (operands[0], operands[2]));
6263   DONE;
6265   [(set_attr "length" "8")])
6267 ;; This is not IEEE compliant if rounding mode is "round to nearest".
6268 ;; If the DI->DF conversion is inexact, then it's possible to suffer
6269 ;; from double rounding.
6270 ;; Instead of creating a new cpu type for two FP operations, just use fp
6271 (define_insn_and_split "floatdisf2_internal1"
6272   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
6273         (float:SF (match_operand:DI 1 "gpc_reg_operand" "d")))
6274    (clobber (match_scratch:DF 2 "=d"))]
6275   "TARGET_FCFID && TARGET_HARD_FLOAT && !TARGET_FCFIDS"
6276   "#"
6277   "&& reload_completed"
6278   [(set (match_dup 2)
6279         (float:DF (match_dup 1)))
6280    (set (match_dup 0)
6281         (float_truncate:SF (match_dup 2)))]
6282   ""
6283   [(set_attr "length" "8")
6284    (set_attr "type" "fp")])
6286 ;; Twiddles bits to avoid double rounding.
6287 ;; Bits that might be truncated when converting to DFmode are replaced
6288 ;; by a bit that won't be lost at that stage, but is below the SFmode
6289 ;; rounding position.
6290 (define_expand "floatdisf2_internal2"
6291   [(parallel [(set (match_dup 3) (ashiftrt:DI (match_operand:DI 1 "")
6292                                               (const_int 53)))
6293               (clobber (reg:DI CA_REGNO))])
6294    (set (match_operand:DI 0 "") (and:DI (match_dup 1)
6295                                         (const_int 2047)))
6296    (set (match_dup 3) (plus:DI (match_dup 3)
6297                                (const_int 1)))
6298    (set (match_dup 0) (plus:DI (match_dup 0)
6299                                (const_int 2047)))
6300    (set (match_dup 4) (compare:CCUNS (match_dup 3)
6301                                      (const_int 2)))
6302    (set (match_dup 0) (ior:DI (match_dup 0)
6303                               (match_dup 1)))
6304    (set (match_dup 0) (and:DI (match_dup 0)
6305                               (const_int -2048)))
6306    (set (pc) (if_then_else (geu (match_dup 4) (const_int 0))
6307                            (label_ref (match_operand:DI 2 ""))
6308                            (pc)))
6309    (set (match_dup 0) (match_dup 1))]
6310   "TARGET_POWERPC64 && TARGET_HARD_FLOAT && !TARGET_FCFIDS"
6312   operands[3] = gen_reg_rtx (DImode);
6313   operands[4] = gen_reg_rtx (CCUNSmode);
6316 (define_expand "floatunsdisf2"
6317   [(set (match_operand:SF 0 "gpc_reg_operand")
6318         (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand")))]
6319   "TARGET_HARD_FLOAT && TARGET_FCFIDUS"
6320   "")
6322 (define_insn "floatunsdisf2_fcfidus"
6323   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wu")
6324         (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
6325   "TARGET_HARD_FLOAT && TARGET_FCFIDUS"
6326   "@
6327    fcfidus %0,%1
6328    xscvuxdsp %x0,%x1"
6329   [(set_attr "type" "fp")])
6331 (define_insn_and_split "*floatunsdisf2_mem"
6332   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy,wy")
6333         (unsigned_float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
6334    (clobber (match_scratch:DI 2 "=d,d,wi"))]
6335   "TARGET_HARD_FLOAT && TARGET_FCFIDUS"
6336   "#"
6337   "&& reload_completed"
6338   [(pc)]
6340   emit_move_insn (operands[2], operands[1]);
6341   emit_insn (gen_floatunsdisf2_fcfidus (operands[0], operands[2]));
6342   DONE;
6344   [(set_attr "length" "8")
6345    (set_attr "type" "fpload")])
6347 ;; Define the TImode operations that can be done in a small number
6348 ;; of instructions.  The & constraints are to prevent the register
6349 ;; allocator from allocating registers that overlap with the inputs
6350 ;; (for example, having an input in 7,8 and an output in 6,7).  We
6351 ;; also allow for the output being the same as one of the inputs.
6353 (define_expand "addti3"
6354   [(set (match_operand:TI 0 "gpc_reg_operand")
6355         (plus:TI (match_operand:TI 1 "gpc_reg_operand")
6356                  (match_operand:TI 2 "reg_or_short_operand")))]
6357   "TARGET_64BIT"
6359   rtx lo0 = gen_lowpart (DImode, operands[0]);
6360   rtx lo1 = gen_lowpart (DImode, operands[1]);
6361   rtx lo2 = gen_lowpart (DImode, operands[2]);
6362   rtx hi0 = gen_highpart (DImode, operands[0]);
6363   rtx hi1 = gen_highpart (DImode, operands[1]);
6364   rtx hi2 = gen_highpart_mode (DImode, TImode, operands[2]);
6366   if (!reg_or_short_operand (lo2, DImode))
6367     lo2 = force_reg (DImode, lo2);
6368   if (!adde_operand (hi2, DImode))
6369     hi2 = force_reg (DImode, hi2);
6371   emit_insn (gen_adddi3_carry (lo0, lo1, lo2));
6372   emit_insn (gen_adddi3_carry_in (hi0, hi1, hi2));
6373   DONE;
6376 (define_expand "subti3"
6377   [(set (match_operand:TI 0 "gpc_reg_operand")
6378         (minus:TI (match_operand:TI 1 "reg_or_short_operand")
6379                   (match_operand:TI 2 "gpc_reg_operand")))]
6380   "TARGET_64BIT"
6382   rtx lo0 = gen_lowpart (DImode, operands[0]);
6383   rtx lo1 = gen_lowpart (DImode, operands[1]);
6384   rtx lo2 = gen_lowpart (DImode, operands[2]);
6385   rtx hi0 = gen_highpart (DImode, operands[0]);
6386   rtx hi1 = gen_highpart_mode (DImode, TImode, operands[1]);
6387   rtx hi2 = gen_highpart (DImode, operands[2]);
6389   if (!reg_or_short_operand (lo1, DImode))
6390     lo1 = force_reg (DImode, lo1);
6391   if (!adde_operand (hi1, DImode))
6392     hi1 = force_reg (DImode, hi1);
6394   emit_insn (gen_subfdi3_carry (lo0, lo2, lo1));
6395   emit_insn (gen_subfdi3_carry_in (hi0, hi2, hi1));
6396   DONE;
6399 ;; 128-bit logical operations expanders
6401 (define_expand "and<mode>3"
6402   [(set (match_operand:BOOL_128 0 "vlogical_operand")
6403         (and:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")
6404                       (match_operand:BOOL_128 2 "vlogical_operand")))]
6405   ""
6406   "")
6408 (define_expand "ior<mode>3"
6409   [(set (match_operand:BOOL_128 0 "vlogical_operand")
6410         (ior:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")
6411                       (match_operand:BOOL_128 2 "vlogical_operand")))]
6412   ""
6413   "")
6415 (define_expand "xor<mode>3"
6416   [(set (match_operand:BOOL_128 0 "vlogical_operand")
6417         (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")
6418                       (match_operand:BOOL_128 2 "vlogical_operand")))]
6419   ""
6420   "")
6422 (define_expand "one_cmpl<mode>2"
6423   [(set (match_operand:BOOL_128 0 "vlogical_operand")
6424         (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")))]
6425   ""
6426   "")
6428 (define_expand "nor<mode>3"
6429   [(set (match_operand:BOOL_128 0 "vlogical_operand")
6430         (and:BOOL_128
6431          (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand"))
6432          (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))))]
6433   ""
6434   "")
6436 (define_expand "andc<mode>3"
6437   [(set (match_operand:BOOL_128 0 "vlogical_operand")
6438         (and:BOOL_128
6439          (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))
6440          (match_operand:BOOL_128 1 "vlogical_operand")))]
6441   ""
6442   "")
6444 ;; Power8 vector logical instructions.
6445 (define_expand "eqv<mode>3"
6446   [(set (match_operand:BOOL_128 0 "vlogical_operand")
6447         (not:BOOL_128
6448          (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")
6449                        (match_operand:BOOL_128 2 "vlogical_operand"))))]
6450   "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6451   "")
6453 ;; Rewrite nand into canonical form
6454 (define_expand "nand<mode>3"
6455   [(set (match_operand:BOOL_128 0 "vlogical_operand")
6456         (ior:BOOL_128
6457          (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand"))
6458          (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))))]
6459   "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6460   "")
6462 ;; The canonical form is to have the negated element first, so we need to
6463 ;; reverse arguments.
6464 (define_expand "orc<mode>3"
6465   [(set (match_operand:BOOL_128 0 "vlogical_operand")
6466         (ior:BOOL_128
6467          (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))
6468          (match_operand:BOOL_128 1 "vlogical_operand")))]
6469   "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6470   "")
6472 ;; 128-bit logical operations insns and split operations
6473 (define_insn_and_split "*and<mode>3_internal"
6474   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6475         (and:BOOL_128
6476          (match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
6477          (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")))]
6478   ""
6480   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6481     return "xxland %x0,%x1,%x2";
6483   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6484     return "vand %0,%1,%2";
6486   return "#";
6488   "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6489   [(const_int 0)]
6491   rs6000_split_logical (operands, AND, false, false, false);
6492   DONE;
6494   [(set (attr "type")
6495       (if_then_else
6496         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6497         (const_string "veclogical")
6498         (const_string "integer")))
6499    (set (attr "length")
6500       (if_then_else
6501         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6502         (const_string "4")
6503         (if_then_else
6504          (match_test "TARGET_POWERPC64")
6505          (const_string "8")
6506          (const_string "16"))))])
6508 ;; 128-bit IOR/XOR
6509 (define_insn_and_split "*bool<mode>3_internal"
6510   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6511         (match_operator:BOOL_128 3 "boolean_or_operator"
6512          [(match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
6513           (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")]))]
6514   ""
6516   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6517     return "xxl%q3 %x0,%x1,%x2";
6519   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6520     return "v%q3 %0,%1,%2";
6522   return "#";
6524   "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6525   [(const_int 0)]
6527   rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, false);
6528   DONE;
6530   [(set (attr "type")
6531       (if_then_else
6532         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6533         (const_string "veclogical")
6534         (const_string "integer")))
6535    (set (attr "length")
6536       (if_then_else
6537         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6538         (const_string "4")
6539         (if_then_else
6540          (match_test "TARGET_POWERPC64")
6541          (const_string "8")
6542          (const_string "16"))))])
6544 ;; 128-bit ANDC/ORC
6545 (define_insn_and_split "*boolc<mode>3_internal1"
6546   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6547         (match_operator:BOOL_128 3 "boolean_operator"
6548          [(not:BOOL_128
6549            (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))
6550           (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")]))]
6551   "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
6553   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6554     return "xxl%q3 %x0,%x1,%x2";
6556   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6557     return "v%q3 %0,%1,%2";
6559   return "#";
6561   "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
6562    && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6563   [(const_int 0)]
6565   rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
6566   DONE;
6568   [(set (attr "type")
6569       (if_then_else
6570         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6571         (const_string "veclogical")
6572         (const_string "integer")))
6573    (set (attr "length")
6574       (if_then_else
6575         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6576         (const_string "4")
6577         (if_then_else
6578          (match_test "TARGET_POWERPC64")
6579          (const_string "8")
6580          (const_string "16"))))])
6582 (define_insn_and_split "*boolc<mode>3_internal2"
6583   [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6584         (match_operator:TI2 3 "boolean_operator"
6585          [(not:TI2
6586            (match_operand:TI2 2 "int_reg_operand" "r,0,r"))
6587           (match_operand:TI2 1 "int_reg_operand" "r,r,0")]))]
6588   "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6589   "#"
6590   "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6591   [(const_int 0)]
6593   rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
6594   DONE;
6596   [(set_attr "type" "integer")
6597    (set (attr "length")
6598         (if_then_else
6599          (match_test "TARGET_POWERPC64")
6600          (const_string "8")
6601          (const_string "16")))])
6603 ;; 128-bit NAND/NOR
6604 (define_insn_and_split "*boolcc<mode>3_internal1"
6605   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6606         (match_operator:BOOL_128 3 "boolean_operator"
6607          [(not:BOOL_128
6608            (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>"))
6609           (not:BOOL_128
6610            (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))]))]
6611   "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
6613   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6614     return "xxl%q3 %x0,%x1,%x2";
6616   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6617     return "v%q3 %0,%1,%2";
6619   return "#";
6621   "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
6622    && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6623   [(const_int 0)]
6625   rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
6626   DONE;
6628   [(set (attr "type")
6629       (if_then_else
6630         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6631         (const_string "veclogical")
6632         (const_string "integer")))
6633    (set (attr "length")
6634       (if_then_else
6635         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6636         (const_string "4")
6637         (if_then_else
6638          (match_test "TARGET_POWERPC64")
6639          (const_string "8")
6640          (const_string "16"))))])
6642 (define_insn_and_split "*boolcc<mode>3_internal2"
6643   [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6644         (match_operator:TI2 3 "boolean_operator"
6645          [(not:TI2
6646            (match_operand:TI2 1 "int_reg_operand" "r,0,r"))
6647           (not:TI2
6648            (match_operand:TI2 2 "int_reg_operand" "r,r,0"))]))]
6649   "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6650   "#"
6651   "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6652   [(const_int 0)]
6654   rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
6655   DONE;
6657   [(set_attr "type" "integer")
6658    (set (attr "length")
6659         (if_then_else
6660          (match_test "TARGET_POWERPC64")
6661          (const_string "8")
6662          (const_string "16")))])
6665 ;; 128-bit EQV
6666 (define_insn_and_split "*eqv<mode>3_internal1"
6667   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6668         (not:BOOL_128
6669          (xor:BOOL_128
6670           (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")
6671           (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))))]
6672   "TARGET_P8_VECTOR"
6674   if (vsx_register_operand (operands[0], <MODE>mode))
6675     return "xxleqv %x0,%x1,%x2";
6677   return "#";
6679   "TARGET_P8_VECTOR && reload_completed
6680    && int_reg_operand (operands[0], <MODE>mode)"
6681   [(const_int 0)]
6683   rs6000_split_logical (operands, XOR, true, false, false);
6684   DONE;
6686   [(set (attr "type")
6687       (if_then_else
6688         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6689         (const_string "veclogical")
6690         (const_string "integer")))
6691    (set (attr "length")
6692       (if_then_else
6693         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6694         (const_string "4")
6695         (if_then_else
6696          (match_test "TARGET_POWERPC64")
6697          (const_string "8")
6698          (const_string "16"))))])
6700 (define_insn_and_split "*eqv<mode>3_internal2"
6701   [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6702         (not:TI2
6703          (xor:TI2
6704           (match_operand:TI2 1 "int_reg_operand" "r,0,r")
6705           (match_operand:TI2 2 "int_reg_operand" "r,r,0"))))]
6706   "!TARGET_P8_VECTOR"
6707   "#"
6708   "reload_completed && !TARGET_P8_VECTOR"
6709   [(const_int 0)]
6711   rs6000_split_logical (operands, XOR, true, false, false);
6712   DONE;
6714   [(set_attr "type" "integer")
6715    (set (attr "length")
6716         (if_then_else
6717          (match_test "TARGET_POWERPC64")
6718          (const_string "8")
6719          (const_string "16")))])
6721 ;; 128-bit one's complement
6722 (define_insn_and_split "*one_cmpl<mode>3_internal"
6723   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6724         (not:BOOL_128
6725           (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_UNARY>")))]
6726   ""
6728   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6729     return "xxlnor %x0,%x1,%x1";
6731   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6732     return "vnor %0,%1,%1";
6734   return "#";
6736   "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6737   [(const_int 0)]
6739   rs6000_split_logical (operands, NOT, false, false, false);
6740   DONE;
6742   [(set (attr "type")
6743       (if_then_else
6744         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6745         (const_string "veclogical")
6746         (const_string "integer")))
6747    (set (attr "length")
6748       (if_then_else
6749         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6750         (const_string "4")
6751         (if_then_else
6752          (match_test "TARGET_POWERPC64")
6753          (const_string "8")
6754          (const_string "16"))))])
6757 ;; Now define ways of moving data around.
6759 ;; Set up a register with a value from the GOT table
6761 (define_expand "movsi_got"
6762   [(set (match_operand:SI 0 "gpc_reg_operand")
6763         (unspec:SI [(match_operand:SI 1 "got_operand")
6764                     (match_dup 2)] UNSPEC_MOVSI_GOT))]
6765   "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
6767   if (GET_CODE (operands[1]) == CONST)
6768     {
6769       rtx offset = const0_rtx;
6770       HOST_WIDE_INT value;
6772       operands[1] = eliminate_constant_term (XEXP (operands[1], 0), &offset);
6773       value = INTVAL (offset);
6774       if (value != 0)
6775         {
6776           rtx tmp = (!can_create_pseudo_p ()
6777                      ? operands[0]
6778                      : gen_reg_rtx (Pmode));
6779           emit_insn (gen_movsi_got (tmp, operands[1]));
6780           emit_insn (gen_addsi3 (operands[0], tmp, offset));
6781           DONE;
6782         }
6783     }
6785   operands[2] = rs6000_got_register (operands[1]);
6788 (define_insn "*movsi_got_internal"
6789   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6790         (unspec:SI [(match_operand:SI 1 "got_no_const_operand" "")
6791                     (match_operand:SI 2 "gpc_reg_operand" "b")]
6792                    UNSPEC_MOVSI_GOT))]
6793   "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
6794   "lwz %0,%a1@got(%2)"
6795   [(set_attr "type" "load")])
6797 ;; Used by sched, shorten_branches and final when the GOT pseudo reg
6798 ;; didn't get allocated to a hard register.
6799 (define_split
6800   [(set (match_operand:SI 0 "gpc_reg_operand")
6801         (unspec:SI [(match_operand:SI 1 "got_no_const_operand")
6802                     (match_operand:SI 2 "memory_operand")]
6803                    UNSPEC_MOVSI_GOT))]
6804   "DEFAULT_ABI == ABI_V4
6805     && flag_pic == 1
6806     && reload_completed"
6807   [(set (match_dup 0) (match_dup 2))
6808    (set (match_dup 0) (unspec:SI [(match_dup 1)(match_dup 0)]
6809                                  UNSPEC_MOVSI_GOT))]
6810   "")
6812 ;; For SI, we special-case integers that can't be loaded in one insn.  We
6813 ;; do the load 16-bits at a time.  We could do this by loading from memory,
6814 ;; and this is even supposed to be faster, but it is simpler not to get
6815 ;; integers in the TOC.
6816 (define_insn "movsi_low"
6817   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6818         (mem:SI (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
6819                            (match_operand 2 "" ""))))]
6820   "TARGET_MACHO && ! TARGET_64BIT"
6821   "lwz %0,lo16(%2)(%1)"
6822   [(set_attr "type" "load")])
6824 ;;              MR           LA           LWZ          LFIWZX       LXSIWZX
6825 ;;              STW          STFIWX       STXSIWX      LI           LIS
6826 ;;              #            XXLOR        XXSPLTIB 0   XXSPLTIB -1  VSPLTISW
6827 ;;              XXLXOR 0     XXLORC -1    P9 const     MTVSRWZ      MFVSRWZ
6828 ;;              MF%1         MT%0         NOP
6829 (define_insn "*movsi_internal1"
6830   [(set (match_operand:SI 0 "nonimmediate_operand"
6831                 "=r,         r,           r,           ?*wI,        ?*wH,
6832                  m,          ?Z,          ?Z,          r,           r,
6833                  r,          ?*wIwH,      ?*wJwK,      ?*wJwK,      ?*wu,
6834                  ?*wJwK,     ?*wH,        ?*wK,        ?*wIwH,      ?r,
6835                  r,          *h,          *h")
6837         (match_operand:SI 1 "input_operand"
6838                 "r,          U,           m,           Z,           Z,
6839                  r,          wI,          wH,          I,           L,
6840                  n,          wIwH,        O,           wM,          wB,
6841                  O,          wM,          wS,          r,           wIwH,
6842                  *h,         r,           0"))]
6844   "gpc_reg_operand (operands[0], SImode)
6845    || gpc_reg_operand (operands[1], SImode)"
6846   "@
6847    mr %0,%1
6848    la %0,%a1
6849    lwz%U1%X1 %0,%1
6850    lfiwzx %0,%y1
6851    lxsiwzx %x0,%y1
6852    stw%U0%X0 %1,%0
6853    stfiwx %1,%y0
6854    stxsiwx %x1,%y0
6855    li %0,%1
6856    lis %0,%v1
6857    #
6858    xxlor %x0,%x1,%x1
6859    xxspltib %x0,0
6860    xxspltib %x0,255
6861    vspltisw %0,%1
6862    xxlxor %x0,%x0,%x0
6863    xxlorc %x0,%x0,%x0
6864    #
6865    mtvsrwz %x0,%1
6866    mfvsrwz %0,%x1
6867    mf%1 %0
6868    mt%0 %1
6869    nop"
6870   [(set_attr "type"
6871                 "*,          *,           load,        fpload,      fpload,
6872                  store,      fpstore,     fpstore,     *,           *,
6873                  *,          veclogical,  vecsimple,   vecsimple,   vecsimple,
6874                  veclogical, veclogical,  vecsimple,   mffgpr,      mftgpr,
6875                  *,          *,           *")
6877    (set_attr "length"
6878                 "4,          4,           4,           4,           4,
6879                  4,          4,           4,           4,           4,
6880                  8,          4,           4,           4,           4,
6881                  4,          4,           8,           4,           4,
6882                  4,          4,           4")])
6884 ;; Like movsi, but adjust a SF value to be used in a SI context, i.e.
6885 ;; (set (reg:SI ...) (subreg:SI (reg:SF ...) 0))
6887 ;; Because SF values are actually stored as DF values within the vector
6888 ;; registers, we need to convert the value to the vector SF format when
6889 ;; we need to use the bits in a union or similar cases.  We only need
6890 ;; to do this transformation when the value is a vector register.  Loads,
6891 ;; stores, and transfers within GPRs are assumed to be safe.
6893 ;; This is a more general case of reload_gpr_from_vsxsf.  That insn must have
6894 ;; no alternatives, because the call is created as part of secondary_reload,
6895 ;; and operand #2's register class is used to allocate the temporary register.
6896 ;; This function is called before reload, and it creates the temporary as
6897 ;; needed.
6899 ;;              MR           LWZ          LFIWZX       LXSIWZX   STW
6900 ;;              STFS         STXSSP       STXSSPX      VSX->GPR  VSX->VSX
6901 ;;              MTVSRWZ
6903 (define_insn_and_split "movsi_from_sf"
6904   [(set (match_operand:SI 0 "nonimmediate_operand"
6905                 "=r,         r,           ?*wI,        ?*wH,     m,
6906                  m,          wY,          Z,           r,        ?*wIwH,
6907                  wIwH")
6909         (unspec:SI [(match_operand:SF 1 "input_operand"
6910                 "r,          m,           Z,           Z,        r,
6911                  f,          wb,          wu,          wIwH,     wIwH,
6912                  r")]
6913                     UNSPEC_SI_FROM_SF))
6915    (clobber (match_scratch:V4SF 2
6916                 "=X,         X,           X,           X,        X,
6917                  X,          X,           X,           wIwH,     X,
6918                  X"))]
6920   "TARGET_NO_SF_SUBREG
6921    && (register_operand (operands[0], SImode)
6922        || register_operand (operands[1], SFmode))"
6923   "@
6924    mr %0,%1
6925    lwz%U1%X1 %0,%1
6926    lfiwzx %0,%y1
6927    lxsiwzx %x0,%y1
6928    stw%U0%X0 %1,%0
6929    stfs%U0%X0 %1,%0
6930    stxssp %1,%0
6931    stxsspx %x1,%y0
6932    #
6933    xscvdpspn %x0,%x1
6934    mtvsrwz %x0,%1"
6935   "&& reload_completed
6936    && int_reg_operand (operands[0], SImode)
6937    && vsx_reg_sfsubreg_ok (operands[1], SFmode)"
6938   [(const_int 0)]
6940   rtx op0 = operands[0];
6941   rtx op1 = operands[1];
6942   rtx op2 = operands[2];
6943   rtx op0_di = gen_rtx_REG (DImode, reg_or_subregno (op0));
6944   rtx op2_si = gen_rtx_REG (SImode, reg_or_subregno (op2));
6946   emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
6947   emit_insn (gen_zero_extendsidi2 (op0_di, op2_si));
6948   DONE;
6950   [(set_attr "type"
6951                 "*,          load,        fpload,      fpload,   store,
6952                  fpstore,    fpstore,     fpstore,     mftgpr,   fp,
6953                  mffgpr")
6955    (set_attr "length"
6956                 "4,          4,           4,           4,        4,
6957                  4,          4,           4,           8,        4,
6958                  4")])
6960 ;; movsi_from_sf with zero extension
6962 ;;              RLDICL       LWZ          LFIWZX       LXSIWZX   VSX->GPR
6963 ;;              VSX->VSX     MTVSRWZ
6965 (define_insn_and_split "*movdi_from_sf_zero_ext"
6966   [(set (match_operand:DI 0 "gpc_reg_operand"
6967                 "=r,         r,           ?*wI,        ?*wH,     r,
6968                  ?wK,        wIwH")
6970         (zero_extend:DI
6971          (unspec:SI [(match_operand:SF 1 "input_operand"
6972                 "r,          m,           Z,           Z,        wIwH,
6973                  wIwH,       r")]
6974                     UNSPEC_SI_FROM_SF)))
6976    (clobber (match_scratch:V4SF 2
6977                 "=X,         X,           X,           X,        wa,
6978                  wIwH,       X"))]
6980   "TARGET_DIRECT_MOVE_64BIT
6981    && (register_operand (operands[0], DImode)
6982        || register_operand (operands[1], SImode))"
6983   "@
6984    rldicl %0,%1,0,32
6985    lwz%U1%X1 %0,%1
6986    lfiwzx %0,%y1
6987    lxsiwzx %x0,%y1
6988    #
6989    #
6990    mtvsrwz %x0,%1"
6991   "&& reload_completed
6992    && register_operand (operands[0], DImode)
6993    && vsx_reg_sfsubreg_ok (operands[1], SFmode)"
6994   [(const_int 0)]
6996   rtx op0 = operands[0];
6997   rtx op1 = operands[1];
6998   rtx op2 = operands[2];
6999   rtx op2_si = gen_rtx_REG (SImode, reg_or_subregno (op2));
7001   emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
7002   emit_insn (gen_zero_extendsidi2 (op0, op2_si));
7003   DONE;
7005   [(set_attr "type"
7006                 "*,          load,        fpload,      fpload,   two,
7007                  two,        mffgpr")
7009    (set_attr "length"
7010                 "4,          4,           4,           4,        8,
7011                  8,          4")])
7013 ;; Like movsi_from_sf, but combine a convert from DFmode to SFmode before
7014 ;; moving it to SImode.  We can do a SFmode store without having to do the
7015 ;; conversion explicitly.  If we are doing a register->register conversion, use
7016 ;; XSCVDPSP instead of XSCVDPSPN, since the former handles cases where the
7017 ;; input will not fit in a SFmode, and the later assumes the value has already
7018 ;; been rounded.
7019 (define_insn "*movsi_from_df"
7020   [(set (match_operand:SI 0 "nonimmediate_operand"         "=wa,m,wY,Z")
7021         (unspec:SI [(float_truncate:SF
7022                      (match_operand:DF 1 "gpc_reg_operand" "wa, f,wb,wa"))]
7023                     UNSPEC_SI_FROM_SF))]
7025   "TARGET_NO_SF_SUBREG"
7026   "@
7027    xscvdpsp %x0,%x1
7028    stfs%U0%X0 %1,%0
7029    stxssp %1,%0
7030    stxsspx %x1,%y0"
7031   [(set_attr "type"   "fp,fpstore,fpstore,fpstore")])
7033 ;; Split a load of a large constant into the appropriate two-insn
7034 ;; sequence.
7036 (define_split
7037   [(set (match_operand:SI 0 "gpc_reg_operand")
7038         (match_operand:SI 1 "const_int_operand"))]
7039   "(unsigned HOST_WIDE_INT) (INTVAL (operands[1]) + 0x8000) >= 0x10000
7040    && (INTVAL (operands[1]) & 0xffff) != 0"
7041   [(set (match_dup 0)
7042         (match_dup 2))
7043    (set (match_dup 0)
7044         (ior:SI (match_dup 0)
7045                 (match_dup 3)))]
7047   if (rs6000_emit_set_const (operands[0], operands[1]))
7048     DONE;
7049   else
7050     FAIL;
7053 ;; Split loading -128..127 to use XXSPLITB and VEXTSW2D
7054 (define_split
7055   [(set (match_operand:DI 0 "altivec_register_operand")
7056         (match_operand:DI 1 "xxspltib_constant_split"))]
7057   "TARGET_P9_VECTOR && reload_completed"
7058   [(const_int 0)]
7060   rtx op0 = operands[0];
7061   rtx op1 = operands[1];
7062   int r = REGNO (op0);
7063   rtx op0_v16qi = gen_rtx_REG (V16QImode, r);
7065   emit_insn (gen_xxspltib_v16qi (op0_v16qi, op1));
7066   emit_insn (gen_vsx_sign_extend_qi_si (operands[0], op0_v16qi));
7067   DONE;
7070 (define_insn "*mov<mode>_internal2"
7071   [(set (match_operand:CC 2 "cc_reg_operand" "=y,x,?y")
7072         (compare:CC (match_operand:P 1 "gpc_reg_operand" "0,r,r")
7073                     (const_int 0)))
7074    (set (match_operand:P 0 "gpc_reg_operand" "=r,r,r") (match_dup 1))]
7075   ""
7076   "@
7077    cmp<wd>i %2,%0,0
7078    mr. %0,%1
7079    #"
7080   [(set_attr "type" "cmp,logical,cmp")
7081    (set_attr "dot" "yes")
7082    (set_attr "length" "4,4,8")])
7084 (define_split
7085   [(set (match_operand:CC 2 "cc_reg_not_cr0_operand")
7086         (compare:CC (match_operand:P 1 "gpc_reg_operand")
7087                     (const_int 0)))
7088    (set (match_operand:P 0 "gpc_reg_operand") (match_dup 1))]
7089   "reload_completed"
7090   [(set (match_dup 0) (match_dup 1))
7091    (set (match_dup 2)
7092         (compare:CC (match_dup 0)
7093                     (const_int 0)))]
7094   "")
7096 (define_expand "mov<mode>"
7097   [(set (match_operand:INT 0 "general_operand")
7098         (match_operand:INT 1 "any_operand"))]
7099   ""
7101   rs6000_emit_move (operands[0], operands[1], <MODE>mode);
7102   DONE;
7105 ;;              MR          LHZ/LBZ    LXSI*ZX    STH/STB    STXSI*X    LI
7106 ;;              XXLOR       load 0     load -1    VSPLTI*    #          MFVSRWZ
7107 ;;              MTVSRWZ     MF%1       MT%1       NOP
7108 (define_insn "*mov<mode>_internal"
7109   [(set (match_operand:QHI 0 "nonimmediate_operand"
7110                 "=r,        r,         ?*wJwK,    m,         Z,         r,
7111                  ?*wJwK,    ?*wJwK,    ?*wJwK,    ?*wK,      ?*wK,      r,
7112                  ?*wJwK,    r,         *c*l,      *h")
7114         (match_operand:QHI 1 "input_operand"
7115                 "r,         m,         Z,         r,         wJwK,      i,
7116                  wJwK,      O,         wM,        wB,        wS,        ?*wJwK,
7117                  r,         *h,        r,         0"))]
7119   "gpc_reg_operand (operands[0], <MODE>mode)
7120    || gpc_reg_operand (operands[1], <MODE>mode)"
7121   "@
7122    mr %0,%1
7123    l<wd>z%U1%X1 %0,%1
7124    lxsi<wd>zx %x0,%y1
7125    st<wd>%U0%X0 %1,%0
7126    stxsi<wd>x %x1,%y0
7127    li %0,%1
7128    xxlor %x0,%x1,%x1
7129    xxspltib %x0,0
7130    xxspltib %x0,255
7131    vspltis<wd> %0,%1
7132    #
7133    mfvsrwz %0,%x1
7134    mtvsrwz %x0,%1
7135    mf%1 %0
7136    mt%0 %1
7137    nop"
7138   [(set_attr "type"
7139                 "*,         load,      fpload,    store,     fpstore,   *,
7140                  vecsimple, vecperm,   vecperm,   vecperm,   vecperm,   mftgpr,
7141                  mffgpr,    mfjmpr,    mtjmpr,    *")
7143    (set_attr "length"
7144                 "4,         4,         4,         4,         4,         4,
7145                  4,         4,         4,         4,         8,         4,
7146                  4,         4,         4,         4")])
7149 ;; Here is how to move condition codes around.  When we store CC data in
7150 ;; an integer register or memory, we store just the high-order 4 bits.
7151 ;; This lets us not shift in the most common case of CR0.
7152 (define_expand "movcc"
7153   [(set (match_operand:CC 0 "nonimmediate_operand")
7154         (match_operand:CC 1 "nonimmediate_operand"))]
7155   ""
7156   "")
7158 (define_insn "*movcc_internal1"
7159   [(set (match_operand:CC 0 "nonimmediate_operand"
7160                             "=y,x,?y,y,r,r,r,r, r,*c*l,r,m")
7161         (match_operand:CC 1 "general_operand"
7162                             " y,r, r,O,x,y,r,I,*h,   r,m,r"))]
7163   "register_operand (operands[0], CCmode)
7164    || register_operand (operands[1], CCmode)"
7165   "@
7166    mcrf %0,%1
7167    mtcrf 128,%1
7168    rlwinm %1,%1,%F0,0xffffffff\;mtcrf %R0,%1\;rlwinm %1,%1,%f0,0xffffffff
7169    crxor %0,%0,%0
7170    mfcr %0%Q1
7171    mfcr %0%Q1\;rlwinm %0,%0,%f1,0xf0000000
7172    mr %0,%1
7173    li %0,%1
7174    mf%1 %0
7175    mt%0 %1
7176    lwz%U1%X1 %0,%1
7177    stw%U0%X0 %1,%0"
7178   [(set_attr_alternative "type"
7179      [(const_string "cr_logical")
7180       (const_string "mtcr")
7181       (const_string "mtcr")
7182       (const_string "cr_logical")
7183       (if_then_else (match_test "TARGET_MFCRF")
7184                     (const_string "mfcrf") (const_string "mfcr"))
7185       (if_then_else (match_test "TARGET_MFCRF")
7186                     (const_string "mfcrf") (const_string "mfcr"))
7187       (const_string "integer")
7188       (const_string "integer")
7189       (const_string "mfjmpr")
7190       (const_string "mtjmpr")
7191       (const_string "load")
7192       (const_string "store")])
7193    (set_attr "length" "4,4,12,4,4,8,4,4,4,4,4,4")])
7195 ;; For floating-point, we normally deal with the floating-point registers
7196 ;; unless -msoft-float is used.  The sole exception is that parameter passing
7197 ;; can produce floating-point values in fixed-point registers.  Unless the
7198 ;; value is a simple constant or already in memory, we deal with this by
7199 ;; allocating memory and copying the value explicitly via that memory location.
7201 ;; Move 32-bit binary/decimal floating point
7202 (define_expand "mov<mode>"
7203   [(set (match_operand:FMOVE32 0 "nonimmediate_operand")
7204         (match_operand:FMOVE32 1 "any_operand"))]
7205   "<fmove_ok>"
7207   rs6000_emit_move (operands[0], operands[1], <MODE>mode);
7208   DONE;
7211 (define_split
7212   [(set (match_operand:FMOVE32 0 "gpc_reg_operand")
7213         (match_operand:FMOVE32 1 "const_double_operand"))]
7214   "reload_completed
7215    && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
7216        || (GET_CODE (operands[0]) == SUBREG
7217            && GET_CODE (SUBREG_REG (operands[0])) == REG
7218            && REGNO (SUBREG_REG (operands[0])) <= 31))"
7219   [(set (match_dup 2) (match_dup 3))]
7221   long l;
7223   <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7225   if (! TARGET_POWERPC64)
7226     operands[2] = operand_subword (operands[0], 0, 0, <MODE>mode);
7227   else
7228     operands[2] = gen_lowpart (SImode, operands[0]);
7230   operands[3] = gen_int_mode (l, SImode);
7233 ;; Originally, we tried to keep movsf and movsd common, but the differences
7234 ;; addressing was making it rather difficult to hide with mode attributes.  In
7235 ;; particular for SFmode, on ISA 2.07 (power8) systems, having the GPR store
7236 ;; before the VSX stores meant that the register allocator would tend to do a
7237 ;; direct move to the GPR (which involves conversion from scalar to
7238 ;; vector/memory formats) to save values in the traditional Altivec registers,
7239 ;; while SDmode had problems on power6 if the GPR store was not first due to
7240 ;; the power6 not having an integer store operation.
7242 ;;      LWZ          LFS        LXSSP       LXSSPX     STFS       STXSSP
7243 ;;      STXSSPX      STW        XXLXOR      LI         FMR        XSCPSGNDP
7244 ;;      MR           MT<x>      MF<x>       NOP
7246 (define_insn "movsf_hardfloat"
7247   [(set (match_operand:SF 0 "nonimmediate_operand"
7248          "=!r,       f,         wb,         wu,        m,         wY,
7249           Z,         m,         ww,         !r,        f,         ww,
7250           !r,        *c*l,      !r,         *h")
7251         (match_operand:SF 1 "input_operand"
7252          "m,         m,         wY,         Z,         f,         wb,
7253           wu,        r,         j,          j,         f,         ww,
7254           r,         r,         *h,         0"))]
7255   "(register_operand (operands[0], SFmode)
7256    || register_operand (operands[1], SFmode))
7257    && TARGET_HARD_FLOAT
7258    && (TARGET_ALLOW_SF_SUBREG
7259        || valid_sf_si_move (operands[0], operands[1], SFmode))"
7260   "@
7261    lwz%U1%X1 %0,%1
7262    lfs%U1%X1 %0,%1
7263    lxssp %0,%1
7264    lxsspx %x0,%y1
7265    stfs%U0%X0 %1,%0
7266    stxssp %1,%0
7267    stxsspx %x1,%y0
7268    stw%U0%X0 %1,%0
7269    xxlxor %x0,%x0,%x0
7270    li %0,0
7271    fmr %0,%1
7272    xscpsgndp %x0,%x1,%x1
7273    mr %0,%1
7274    mt%0 %1
7275    mf%1 %0
7276    nop"
7277   [(set_attr "type"
7278         "load,       fpload,    fpload,     fpload,    fpstore,   fpstore,
7279          fpstore,    store,     veclogical, integer,   fpsimple,  fpsimple,
7280          *,          mtjmpr,    mfjmpr,     *")])
7282 ;;      LWZ          LFIWZX     STW        STFIWX     MTVSRWZ    MFVSRWZ
7283 ;;      FMR          MR         MT%0       MF%1       NOP
7284 (define_insn "movsd_hardfloat"
7285   [(set (match_operand:SD 0 "nonimmediate_operand"
7286          "=!r,       wz,        m,         Z,         ?wh,       ?r,
7287           f,         !r,        *c*l,      !r,        *h")
7288         (match_operand:SD 1 "input_operand"
7289          "m,         Z,         r,         wx,        r,         wh,
7290           f,         r,         r,         *h,        0"))]
7291   "(register_operand (operands[0], SDmode)
7292    || register_operand (operands[1], SDmode))
7293    && TARGET_HARD_FLOAT"
7294   "@
7295    lwz%U1%X1 %0,%1
7296    lfiwzx %0,%y1
7297    stw%U0%X0 %1,%0
7298    stfiwx %1,%y0
7299    mtvsrwz %x0,%1
7300    mfvsrwz %0,%x1
7301    fmr %0,%1
7302    mr %0,%1
7303    mt%0 %1
7304    mf%1 %0
7305    nop"
7306   [(set_attr "type"
7307         "load,       fpload,    store,     fpstore,   mffgpr,    mftgpr,
7308          fpsimple,   *,         mtjmpr,    mfjmpr,    *")])
7310 ;;      MR           MT%0       MF%0       LWZ        STW        LI
7311 ;;      LIS          G-const.   F/n-const  NOP
7312 (define_insn "*mov<mode>_softfloat"
7313   [(set (match_operand:FMOVE32 0 "nonimmediate_operand"
7314         "=r,         *c*l,      r,         r,         m,         r,
7315           r,         r,         r,         *h")
7317         (match_operand:FMOVE32 1 "input_operand"
7318          "r,         r,         *h,        m,         r,         I,
7319           L,         G,         Fn,        0"))]
7321   "(gpc_reg_operand (operands[0], <MODE>mode)
7322    || gpc_reg_operand (operands[1], <MODE>mode))
7323    && TARGET_SOFT_FLOAT"
7324   "@
7325    mr %0,%1
7326    mt%0 %1
7327    mf%1 %0
7328    lwz%U1%X1 %0,%1
7329    stw%U0%X0 %1,%0
7330    li %0,%1
7331    lis %0,%v1
7332    #
7333    #
7334    nop"
7335   [(set_attr "type"
7336         "*,          mtjmpr,    mfjmpr,    load,      store,     *,
7337          *,          *,         *,         *")
7339    (set_attr "length"
7340         "4,          4,         4,         4,         4,         4,
7341          4,          4,         8,         4")])
7343 ;; Like movsf, but adjust a SI value to be used in a SF context, i.e.
7344 ;; (set (reg:SF ...) (subreg:SF (reg:SI ...) 0))
7346 ;; Because SF values are actually stored as DF values within the vector
7347 ;; registers, we need to convert the value to the vector SF format when
7348 ;; we need to use the bits in a union or similar cases.  We only need
7349 ;; to do this transformation when the value is a vector register.  Loads,
7350 ;; stores, and transfers within GPRs are assumed to be safe.
7352 ;; This is a more general case of reload_vsx_from_gprsf.  That insn must have
7353 ;; no alternatives, because the call is created as part of secondary_reload,
7354 ;; and operand #2's register class is used to allocate the temporary register.
7355 ;; This function is called before reload, and it creates the temporary as
7356 ;; needed.
7358 ;;          LWZ          LFS        LXSSP      LXSSPX     STW        STFIWX
7359 ;;          STXSIWX      GPR->VSX   VSX->GPR   GPR->GPR
7360 (define_insn_and_split "movsf_from_si"
7361   [(set (match_operand:SF 0 "nonimmediate_operand"
7362             "=!r,       f,         wb,        wu,        m,         Z,
7363              Z,         wy,        ?r,        !r")
7365         (unspec:SF [(match_operand:SI 1 "input_operand" 
7366             "m,         m,         wY,        Z,         r,         f,
7367              wu,        r,         wy,        r")]
7368                    UNSPEC_SF_FROM_SI))
7370    (clobber (match_scratch:DI 2
7371             "=X,        X,         X,         X,         X,         X,
7372              X,         r,         X,         X"))]
7374   "TARGET_NO_SF_SUBREG
7375    && (register_operand (operands[0], SFmode)
7376        || register_operand (operands[1], SImode))"
7377   "@
7378    lwz%U1%X1 %0,%1
7379    lfs%U1%X1 %0,%1
7380    lxssp %0,%1
7381    lxsspx %x0,%y1
7382    stw%U0%X0 %1,%0
7383    stfiwx %1,%y0
7384    stxsiwx %x1,%y0
7385    #
7386    mfvsrwz %0,%x1
7387    mr %0,%1"
7389   "&& reload_completed
7390    && vsx_reg_sfsubreg_ok (operands[0], SFmode)
7391    && int_reg_operand_not_pseudo (operands[1], SImode)"
7392   [(const_int 0)]
7394   rtx op0 = operands[0];
7395   rtx op1 = operands[1];
7396   rtx op2 = operands[2];
7397   rtx op1_di = gen_rtx_REG (DImode, REGNO (op1));
7399   /* Move SF value to upper 32-bits for xscvspdpn.  */
7400   emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32)));
7401   emit_insn (gen_p8_mtvsrd_sf (op0, op2));
7402   emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0));
7403   DONE;
7405   [(set_attr "length"
7406             "4,          4,         4,         4,         4,         4,
7407              4,          12,        4,         4")
7408    (set_attr "type"
7409             "load,       fpload,    fpload,    fpload,    store,     fpstore,
7410              fpstore,    vecfloat,  mffgpr,    *")])
7413 ;; Move 64-bit binary/decimal floating point
7414 (define_expand "mov<mode>"
7415   [(set (match_operand:FMOVE64 0 "nonimmediate_operand")
7416         (match_operand:FMOVE64 1 "any_operand"))]
7417   ""
7419   rs6000_emit_move (operands[0], operands[1], <MODE>mode);
7420   DONE;
7423 (define_split
7424   [(set (match_operand:FMOVE64 0 "gpc_reg_operand")
7425         (match_operand:FMOVE64 1 "const_int_operand"))]
7426   "! TARGET_POWERPC64 && reload_completed
7427    && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
7428        || (GET_CODE (operands[0]) == SUBREG
7429            && GET_CODE (SUBREG_REG (operands[0])) == REG
7430            && REGNO (SUBREG_REG (operands[0])) <= 31))"
7431   [(set (match_dup 2) (match_dup 4))
7432    (set (match_dup 3) (match_dup 1))]
7434   int endian = (WORDS_BIG_ENDIAN == 0);
7435   HOST_WIDE_INT value = INTVAL (operands[1]);
7437   operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
7438   operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
7439   operands[4] = GEN_INT (value >> 32);
7440   operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
7443 (define_split
7444   [(set (match_operand:FMOVE64 0 "gpc_reg_operand")
7445         (match_operand:FMOVE64 1 "const_double_operand"))]
7446   "! TARGET_POWERPC64 && reload_completed
7447    && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
7448        || (GET_CODE (operands[0]) == SUBREG
7449            && GET_CODE (SUBREG_REG (operands[0])) == REG
7450            && REGNO (SUBREG_REG (operands[0])) <= 31))"
7451   [(set (match_dup 2) (match_dup 4))
7452    (set (match_dup 3) (match_dup 5))]
7454   int endian = (WORDS_BIG_ENDIAN == 0);
7455   long l[2];
7457   <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7459   operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
7460   operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
7461   operands[4] = gen_int_mode (l[endian], SImode);
7462   operands[5] = gen_int_mode (l[1 - endian], SImode);
7465 (define_split
7466   [(set (match_operand:FMOVE64 0 "gpc_reg_operand")
7467         (match_operand:FMOVE64 1 "const_double_operand"))]
7468   "TARGET_POWERPC64 && reload_completed
7469    && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
7470        || (GET_CODE (operands[0]) == SUBREG
7471            && GET_CODE (SUBREG_REG (operands[0])) == REG
7472            && REGNO (SUBREG_REG (operands[0])) <= 31))"
7473   [(set (match_dup 2) (match_dup 3))]
7475   int endian = (WORDS_BIG_ENDIAN == 0);
7476   long l[2];
7477   HOST_WIDE_INT val;
7479   <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7481   operands[2] = gen_lowpart (DImode, operands[0]);
7482   /* HIGHPART is lower memory address when WORDS_BIG_ENDIAN.  */
7483   val = ((HOST_WIDE_INT)(unsigned long)l[endian] << 32
7484          | ((HOST_WIDE_INT)(unsigned long)l[1 - endian]));
7486   operands[3] = gen_int_mode (val, DImode);
7489 ;; Don't have reload use general registers to load a constant.  It is
7490 ;; less efficient than loading the constant into an FP register, since
7491 ;; it will probably be used there.
7493 ;; The move constraints are ordered to prefer floating point registers before
7494 ;; general purpose registers to avoid doing a store and a load to get the value
7495 ;; into a floating point register when it is needed for a floating point
7496 ;; operation.  Prefer traditional floating point registers over VSX registers,
7497 ;; since the D-form version of the memory instructions does not need a GPR for
7498 ;; reloading.  ISA 3.0 (power9) adds D-form addressing for scalars to Altivec
7499 ;; registers.
7501 ;; If we have FPR registers, rs6000_emit_move has moved all constants to memory,
7502 ;; except for 0.0 which can be created on VSX with an xor instruction.
7504 ;;           STFD         LFD         FMR         LXSD        STXSD
7505 ;;           LXSD         STXSD       XXLOR       XXLXOR      GPR<-0
7506 ;;           LWZ          STW         MR
7509 (define_insn "*mov<mode>_hardfloat32"
7510   [(set (match_operand:FMOVE64 0 "nonimmediate_operand"
7511             "=m,          d,          d,          <f64_p9>,   wY,
7512               <f64_av>,   Z,          <f64_vsx>,  <f64_vsx>,  !r,
7513               Y,          r,          !r")
7515         (match_operand:FMOVE64 1 "input_operand"
7516              "d,          m,          d,          wY,         <f64_p9>,
7517               Z,          <f64_av>,   <f64_vsx>,  <zero_fp>,  <zero_fp>,
7518               r,          Y,          r"))]
7520   "! TARGET_POWERPC64 && TARGET_HARD_FLOAT
7521    && (gpc_reg_operand (operands[0], <MODE>mode)
7522        || gpc_reg_operand (operands[1], <MODE>mode))"
7523   "@
7524    stfd%U0%X0 %1,%0
7525    lfd%U1%X1 %0,%1
7526    fmr %0,%1
7527    lxsd %0,%1
7528    stxsd %1,%0
7529    lxsdx %x0,%y1
7530    stxsdx %x1,%y0
7531    xxlor %x0,%x1,%x1
7532    xxlxor %x0,%x0,%x0
7533    #
7534    #
7535    #
7536    #"
7537   [(set_attr "type"
7538             "fpstore,     fpload,     fpsimple,   fpload,     fpstore,
7539              fpload,      fpstore,    veclogical, veclogical, two,
7540              store,       load,       two")
7542    (set_attr "size" "64")
7543    (set_attr "length"
7544             "4,           4,          4,          4,          4,
7545              4,           4,          4,          4,          8,
7546              8,           8,          8")])
7548 ;;           STW      LWZ     MR      G-const H-const F-const
7550 (define_insn "*mov<mode>_softfloat32"
7551   [(set (match_operand:FMOVE64 0 "nonimmediate_operand"
7552            "=Y,       r,      r,      r,      r,      r")
7554         (match_operand:FMOVE64 1 "input_operand"
7555             "r,       Y,      r,      G,      H,      F"))]
7557   "!TARGET_POWERPC64
7558    && (gpc_reg_operand (operands[0], <MODE>mode)
7559        || gpc_reg_operand (operands[1], <MODE>mode))"
7560   "#"
7561   [(set_attr "type"
7562             "store,   load,   two,    *,      *,      *")
7564    (set_attr "length"
7565              "8,      8,      8,      8,      12,     16")])
7567 ; ld/std require word-aligned displacements -> 'Y' constraint.
7568 ; List Y->r and r->Y before r->r for reload.
7570 ;;           STFD         LFD         FMR         LXSD        STXSD
7571 ;;           LXSDX        STXSDX      XXLOR       XXLXOR      LI 0
7572 ;;           STD          LD          MR          MT{CTR,LR}  MF{CTR,LR}
7573 ;;           NOP          MFTGPR      MFFGPR      MFVSRD      MTVSRD
7575 (define_insn "*mov<mode>_hardfloat64"
7576   [(set (match_operand:FMOVE64 0 "nonimmediate_operand"
7577            "=m,           d,          d,          <f64_p9>,   wY,
7578              <f64_av>,    Z,          <f64_vsx>,  <f64_vsx>,  !r,
7579              YZ,          r,          !r,         *c*l,       !r,
7580             *h,           r,          wg,         r,          <f64_dm>")
7582         (match_operand:FMOVE64 1 "input_operand"
7583             "d,           m,          d,          wY,         <f64_p9>,
7584              Z,           <f64_av>,   <f64_vsx>,  <zero_fp>,  <zero_fp>,
7585              r,           YZ,         r,          r,          *h,
7586              0,           wg,         r,          <f64_dm>,   r"))]
7588   "TARGET_POWERPC64 && TARGET_HARD_FLOAT
7589    && (gpc_reg_operand (operands[0], <MODE>mode)
7590        || gpc_reg_operand (operands[1], <MODE>mode))"
7591   "@
7592    stfd%U0%X0 %1,%0
7593    lfd%U1%X1 %0,%1
7594    fmr %0,%1
7595    lxsd %0,%1
7596    stxsd %1,%0
7597    lxsdx %x0,%y1
7598    stxsdx %x1,%y0
7599    xxlor %x0,%x1,%x1
7600    xxlxor %x0,%x0,%x0
7601    li %0,0
7602    std%U0%X0 %1,%0
7603    ld%U1%X1 %0,%1
7604    mr %0,%1
7605    mt%0 %1
7606    mf%1 %0
7607    nop
7608    mftgpr %0,%1
7609    mffgpr %0,%1
7610    mfvsrd %0,%x1
7611    mtvsrd %x0,%1"
7612   [(set_attr "type"
7613             "fpstore,     fpload,     fpsimple,   fpload,     fpstore,
7614              fpload,      fpstore,    veclogical, veclogical, integer,
7615              store,       load,       *,          mtjmpr,     mfjmpr,
7616              *,           mftgpr,     mffgpr,     mftgpr,    mffgpr")
7618    (set_attr "size" "64")
7619    (set_attr "length" "4")])
7621 ;;           STD      LD       MR      MT<SPR> MF<SPR> G-const
7622 ;;           H-const  F-const  Special
7624 (define_insn "*mov<mode>_softfloat64"
7625   [(set (match_operand:FMOVE64 0 "nonimmediate_operand"
7626            "=Y,       r,      r,      *c*l,   r,      r,
7627              r,       r,      *h")
7629         (match_operand:FMOVE64 1 "input_operand"
7630             "r,       Y,      r,      r,      *h,     G,
7631              H,       F,      0"))]
7633   "TARGET_POWERPC64 && TARGET_SOFT_FLOAT
7634    && (gpc_reg_operand (operands[0], <MODE>mode)
7635        || gpc_reg_operand (operands[1], <MODE>mode))"
7636   "@
7637    std%U0%X0 %1,%0
7638    ld%U1%X1 %0,%1
7639    mr %0,%1
7640    mt%0 %1
7641    mf%1 %0
7642    #
7643    #
7644    #
7645    nop"
7646   [(set_attr "type"
7647             "store,   load,   *,      mtjmpr, mfjmpr, *,
7648              *,       *,      *")
7650    (set_attr "length"
7651             "4,       4,      4,      4,      4,      8,
7652              12,      16,     4")])
7654 (define_expand "mov<mode>"
7655   [(set (match_operand:FMOVE128 0 "general_operand")
7656         (match_operand:FMOVE128 1 "any_operand"))]
7657   ""
7659   rs6000_emit_move (operands[0], operands[1], <MODE>mode);
7660   DONE;
7663 ;; It's important to list Y->r and r->Y before r->r because otherwise
7664 ;; reload, given m->r, will try to pick r->r and reload it, which
7665 ;; doesn't make progress.
7667 ;; We can't split little endian direct moves of TDmode, because the words are
7668 ;; not swapped like they are for TImode or TFmode.  Subregs therefore are
7669 ;; problematical.  Don't allow direct move for this case.
7671 (define_insn_and_split "*mov<mode>_64bit_dm"
7672   [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand" "=m,d,d,d,Y,r,r,r,wh")
7673         (match_operand:FMOVE128_FPR 1 "input_operand" "d,m,d,<zero_fp>,r,<zero_fp>Y,r,wh,r"))]
7674   "TARGET_HARD_FLOAT && TARGET_POWERPC64 && FLOAT128_2REG_P (<MODE>mode)
7675    && (<MODE>mode != TDmode || WORDS_BIG_ENDIAN)
7676    && (gpc_reg_operand (operands[0], <MODE>mode)
7677        || gpc_reg_operand (operands[1], <MODE>mode))"
7678   "#"
7679   "&& reload_completed"
7680   [(pc)]
7681 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7682   [(set_attr "length" "8,8,8,8,12,12,8,8,8")])
7684 (define_insn_and_split "*movtd_64bit_nodm"
7685   [(set (match_operand:TD 0 "nonimmediate_operand" "=m,d,d,Y,r,r")
7686         (match_operand:TD 1 "input_operand" "d,m,d,r,Y,r"))]
7687   "TARGET_HARD_FLOAT && TARGET_POWERPC64 && !WORDS_BIG_ENDIAN
7688    && (gpc_reg_operand (operands[0], TDmode)
7689        || gpc_reg_operand (operands[1], TDmode))"
7690   "#"
7691   "&& reload_completed"
7692   [(pc)]
7693 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7694   [(set_attr "length" "8,8,8,12,12,8")])
7696 (define_insn_and_split "*mov<mode>_32bit"
7697   [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand" "=m,d,d,d,Y,r,r")
7698         (match_operand:FMOVE128_FPR 1 "input_operand" "d,m,d,<zero_fp>,r,<zero_fp>Y,r"))]
7699   "TARGET_HARD_FLOAT && !TARGET_POWERPC64
7700    && (FLOAT128_2REG_P (<MODE>mode)
7701        || int_reg_operand_not_pseudo (operands[0], <MODE>mode)
7702        || int_reg_operand_not_pseudo (operands[1], <MODE>mode))
7703    && (gpc_reg_operand (operands[0], <MODE>mode)
7704        || gpc_reg_operand (operands[1], <MODE>mode))"
7705   "#"
7706   "&& reload_completed"
7707   [(pc)]
7708 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7709   [(set_attr "length" "8,8,8,8,20,20,16")])
7711 (define_insn_and_split "*mov<mode>_softfloat"
7712   [(set (match_operand:FMOVE128 0 "nonimmediate_operand" "=Y,r,r")
7713         (match_operand:FMOVE128 1 "input_operand" "r,YGHF,r"))]
7714   "TARGET_SOFT_FLOAT
7715    && (gpc_reg_operand (operands[0], <MODE>mode)
7716        || gpc_reg_operand (operands[1], <MODE>mode))"
7717   "#"
7718   "&& reload_completed"
7719   [(pc)]
7720 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7721   [(set_attr "length" "20,20,16")])
7723 (define_expand "extenddf<mode>2"
7724   [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
7725         (float_extend:FLOAT128 (match_operand:DF 1 "gpc_reg_operand")))]
7726   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7728   if (FLOAT128_IEEE_P (<MODE>mode))
7729     rs6000_expand_float128_convert (operands[0], operands[1], false);
7730   else if (TARGET_VSX)
7731     {
7732       if (<MODE>mode == TFmode)
7733         emit_insn (gen_extenddftf2_vsx (operands[0], operands[1]));
7734       else if (<MODE>mode == IFmode)
7735         emit_insn (gen_extenddfif2_vsx (operands[0], operands[1]));
7736       else
7737         gcc_unreachable ();
7738     }
7739    else
7740     {
7741       rtx zero = gen_reg_rtx (DFmode);
7742       rs6000_emit_move (zero, CONST0_RTX (DFmode), DFmode);
7744       if (<MODE>mode == TFmode)
7745         emit_insn (gen_extenddftf2_fprs (operands[0], operands[1], zero));
7746       else if (<MODE>mode == IFmode)
7747         emit_insn (gen_extenddfif2_fprs (operands[0], operands[1], zero));
7748       else
7749         gcc_unreachable ();
7750     }
7751   DONE;
7754 ;; Allow memory operands for the source to be created by the combiner.
7755 (define_insn_and_split "extenddf<mode>2_fprs"
7756   [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d,&d")
7757         (float_extend:IBM128
7758          (match_operand:DF 1 "nonimmediate_operand" "d,m,d")))
7759    (use (match_operand:DF 2 "nonimmediate_operand" "m,m,d"))]
7760   "!TARGET_VSX && TARGET_HARD_FLOAT
7761    && TARGET_LONG_DOUBLE_128 && FLOAT128_IBM_P (<MODE>mode)"
7762   "#"
7763   "&& reload_completed"
7764   [(set (match_dup 3) (match_dup 1))
7765    (set (match_dup 4) (match_dup 2))]
7767   const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7768   const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7770   operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
7771   operands[4] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
7774 (define_insn_and_split "extenddf<mode>2_vsx"
7775   [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d")
7776         (float_extend:IBM128
7777          (match_operand:DF 1 "nonimmediate_operand" "ws,m")))]
7778   "TARGET_LONG_DOUBLE_128 && TARGET_VSX && FLOAT128_IBM_P (<MODE>mode)"
7779   "#"
7780   "&& reload_completed"
7781   [(set (match_dup 2) (match_dup 1))
7782    (set (match_dup 3) (match_dup 4))]
7784   const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7785   const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7787   operands[2] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
7788   operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
7789   operands[4] = CONST0_RTX (DFmode);
7792 (define_expand "extendsf<mode>2"
7793   [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
7794         (float_extend:FLOAT128 (match_operand:SF 1 "gpc_reg_operand")))]
7795   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7797   if (FLOAT128_IEEE_P (<MODE>mode))
7798     rs6000_expand_float128_convert (operands[0], operands[1], false);
7799   else
7800     {
7801       rtx tmp = gen_reg_rtx (DFmode);
7802       emit_insn (gen_extendsfdf2 (tmp, operands[1]));
7803       emit_insn (gen_extenddf<mode>2 (operands[0], tmp));
7804     }
7805   DONE;
7808 (define_expand "trunc<mode>df2"
7809   [(set (match_operand:DF 0 "gpc_reg_operand")
7810         (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand")))]
7811   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7813   if (FLOAT128_IEEE_P (<MODE>mode))
7814     {
7815       rs6000_expand_float128_convert (operands[0], operands[1], false);
7816       DONE;
7817     }
7820 (define_insn_and_split "trunc<mode>df2_internal1"
7821   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d")
7822         (float_truncate:DF
7823          (match_operand:IBM128 1 "gpc_reg_operand" "0,d")))]
7824   "FLOAT128_IBM_P (<MODE>mode) && !TARGET_XL_COMPAT
7825    && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7826   "@
7827    #
7828    fmr %0,%1"
7829   "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
7830   [(const_int 0)]
7832   emit_note (NOTE_INSN_DELETED);
7833   DONE;
7835   [(set_attr "type" "fpsimple")])
7837 (define_insn "trunc<mode>df2_internal2"
7838   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
7839         (float_truncate:DF (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
7840   "FLOAT128_IBM_P (<MODE>mode) && TARGET_XL_COMPAT && TARGET_HARD_FLOAT
7841    && TARGET_LONG_DOUBLE_128"
7842   "fadd %0,%1,%L1"
7843   [(set_attr "type" "fp")])
7845 (define_expand "trunc<mode>sf2"
7846   [(set (match_operand:SF 0 "gpc_reg_operand")
7847         (float_truncate:SF (match_operand:FLOAT128 1 "gpc_reg_operand")))]
7848   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7850   if (FLOAT128_IEEE_P (<MODE>mode))
7851     rs6000_expand_float128_convert (operands[0], operands[1], false);
7852   else
7853     {
7854       rtx tmp = gen_reg_rtx (DFmode);
7855       emit_insn (gen_trunc<mode>df2 (tmp, operands[1]));
7856       emit_insn (gen_truncdfsf2 (operands[0], tmp));
7857     }
7858   DONE;
7861 (define_expand "floatsi<mode>2"
7862   [(parallel [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
7863                    (float:FLOAT128 (match_operand:SI 1 "gpc_reg_operand")))
7864               (clobber (match_scratch:DI 2))])]
7865   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7867   rtx op0 = operands[0];
7868   rtx op1 = operands[1];
7870   if (TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode))
7871     ;
7872   else if (FLOAT128_IEEE_P (<MODE>mode))
7873     {
7874       rs6000_expand_float128_convert (op0, op1, false);
7875       DONE;
7876     }
7877   else
7878     {
7879       rtx tmp = gen_reg_rtx (DFmode);
7880       expand_float (tmp, op1, false);
7881       if (<MODE>mode == TFmode)
7882         emit_insn (gen_extenddftf2 (op0, tmp));
7883       else if (<MODE>mode == IFmode)
7884         emit_insn (gen_extenddfif2 (op0, tmp));
7885       else
7886         gcc_unreachable ();
7887       DONE;
7888     }
7891 ; fadd, but rounding towards zero.
7892 ; This is probably not the optimal code sequence.
7893 (define_insn "fix_trunc_helper<mode>"
7894   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
7895         (unspec:DF [(match_operand:IBM128 1 "gpc_reg_operand" "d")]
7896                    UNSPEC_FIX_TRUNC_TF))
7897    (clobber (match_operand:DF 2 "gpc_reg_operand" "=&d"))]
7898   "TARGET_HARD_FLOAT && FLOAT128_IBM_P (<MODE>mode)"
7899   "mffs %2\n\tmtfsb1 31\n\tmtfsb0 30\n\tfadd %0,%1,%L1\n\tmtfsf 1,%2"
7900   [(set_attr "type" "fp")
7901    (set_attr "length" "20")])
7903 (define_expand "fix_trunc<mode>si2"
7904   [(set (match_operand:SI 0 "gpc_reg_operand")
7905         (fix:SI (match_operand:FLOAT128 1 "gpc_reg_operand")))]
7906   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7908   rtx op0 = operands[0];
7909   rtx op1 = operands[1];
7911   if (TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode))
7912     ;
7913   else
7914     {
7915       if (FLOAT128_IEEE_P (<MODE>mode))
7916         rs6000_expand_float128_convert (op0, op1, false);
7917       else if (<MODE>mode == TFmode)
7918         emit_insn (gen_fix_trunctfsi2_fprs (op0, op1));
7919       else if (<MODE>mode == IFmode)
7920         emit_insn (gen_fix_truncifsi2_fprs (op0, op1));
7921       else
7922         gcc_unreachable ();
7923       DONE;
7924     }
7927 (define_expand "fix_trunc<mode>si2_fprs"
7928   [(parallel [(set (match_operand:SI 0 "gpc_reg_operand")
7929                    (fix:SI (match_operand:IBM128 1 "gpc_reg_operand")))
7930               (clobber (match_dup 2))
7931               (clobber (match_dup 3))
7932               (clobber (match_dup 4))
7933               (clobber (match_dup 5))])]
7934   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7936   operands[2] = gen_reg_rtx (DFmode);
7937   operands[3] = gen_reg_rtx (DFmode);
7938   operands[4] = gen_reg_rtx (DImode);
7939   operands[5] = assign_stack_temp (DImode, GET_MODE_SIZE (DImode));
7942 (define_insn_and_split "*fix_trunc<mode>si2_internal"
7943   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
7944         (fix:SI (match_operand:IBM128 1 "gpc_reg_operand" "d")))
7945    (clobber (match_operand:DF 2 "gpc_reg_operand" "=d"))
7946    (clobber (match_operand:DF 3 "gpc_reg_operand" "=&d"))
7947    (clobber (match_operand:DI 4 "gpc_reg_operand" "=d"))
7948    (clobber (match_operand:DI 5 "offsettable_mem_operand" "=o"))]
7949   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7950   "#"
7951   ""
7952   [(pc)]
7954   rtx lowword;
7955   emit_insn (gen_fix_trunc_helper<mode> (operands[2], operands[1],
7956                                          operands[3]));
7958   gcc_assert (MEM_P (operands[5]));
7959   lowword = adjust_address (operands[5], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
7961   emit_insn (gen_fctiwz_df (operands[4], operands[2]));
7962   emit_move_insn (operands[5], operands[4]);
7963   emit_move_insn (operands[0], lowword);
7964   DONE;
7967 (define_expand "fix_trunc<mode>di2"
7968   [(set (match_operand:DI 0 "gpc_reg_operand")
7969         (fix:DI (match_operand:IEEE128 1 "gpc_reg_operand")))]
7970   "TARGET_FLOAT128_TYPE"
7972   if (!TARGET_FLOAT128_HW)
7973     {
7974       rs6000_expand_float128_convert (operands[0], operands[1], false);
7975       DONE;
7976     }
7979 (define_expand "fixuns_trunc<IEEE128:mode><SDI:mode>2"
7980   [(set (match_operand:SDI 0 "gpc_reg_operand")
7981         (unsigned_fix:SDI (match_operand:IEEE128 1 "gpc_reg_operand")))]
7982   "TARGET_FLOAT128_TYPE"
7984   rs6000_expand_float128_convert (operands[0], operands[1], true);
7985   DONE;
7988 (define_expand "floatdi<mode>2"
7989   [(set (match_operand:IEEE128 0 "gpc_reg_operand")
7990         (float:IEEE128 (match_operand:DI 1 "gpc_reg_operand")))]
7991   "TARGET_FLOAT128_TYPE"
7993   if (!TARGET_FLOAT128_HW)
7994     {
7995       rs6000_expand_float128_convert (operands[0], operands[1], false);
7996       DONE;
7997     }
8000 (define_expand "floatunsdi<IEEE128:mode>2"
8001   [(set (match_operand:IEEE128 0 "gpc_reg_operand")
8002         (unsigned_float:IEEE128 (match_operand:DI 1 "gpc_reg_operand")))]
8003   "TARGET_FLOAT128_TYPE"
8005   if (!TARGET_FLOAT128_HW)
8006     {
8007       rs6000_expand_float128_convert (operands[0], operands[1], true);
8008       DONE;
8009     }
8012 (define_expand "floatuns<IEEE128:mode>2"
8013   [(set (match_operand:IEEE128 0 "gpc_reg_operand")
8014         (unsigned_float:IEEE128 (match_operand:SI 1 "gpc_reg_operand")))]
8015   "TARGET_FLOAT128_TYPE"
8017   rtx op0 = operands[0];
8018   rtx op1 = operands[1];
8020   if (TARGET_FLOAT128_HW)
8021     emit_insn (gen_floatuns_<IEEE128:mode>si2_hw (op0, op1));
8022   else
8023     rs6000_expand_float128_convert (op0, op1, true);
8024   DONE;
8027 (define_expand "neg<mode>2"
8028   [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
8029         (neg:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand")))]
8030   "FLOAT128_IEEE_P (<MODE>mode)
8031    || (FLOAT128_IBM_P (<MODE>mode) && TARGET_HARD_FLOAT)"
8033   if (FLOAT128_IEEE_P (<MODE>mode))
8034     {
8035       if (TARGET_FLOAT128_HW)
8036         {
8037           if (<MODE>mode == TFmode)
8038             emit_insn (gen_negtf2_hw (operands[0], operands[1]));
8039           else if (<MODE>mode == KFmode)
8040             emit_insn (gen_negkf2_hw (operands[0], operands[1]));
8041           else
8042             gcc_unreachable ();
8043         }
8044       else if (TARGET_FLOAT128_TYPE)
8045         {
8046           if (<MODE>mode == TFmode)
8047             emit_insn (gen_ieee_128bit_vsx_negtf2 (operands[0], operands[1]));
8048           else if (<MODE>mode == KFmode)
8049             emit_insn (gen_ieee_128bit_vsx_negkf2 (operands[0], operands[1]));
8050           else
8051             gcc_unreachable ();
8052         }
8053       else
8054         {
8055           rtx libfunc = optab_libfunc (neg_optab, <MODE>mode);
8056           rtx target = emit_library_call_value (libfunc, operands[0], LCT_CONST,
8057                                                 <MODE>mode,
8058                                                 operands[1], <MODE>mode);
8060           if (target && !rtx_equal_p (target, operands[0]))
8061             emit_move_insn (operands[0], target);
8062         }
8063       DONE;
8064     }
8067 (define_insn "neg<mode>2_internal"
8068   [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d")
8069         (neg:IBM128 (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
8070   "TARGET_HARD_FLOAT && FLOAT128_IBM_P (<MODE>mode)"
8072   if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
8073     return "fneg %L0,%L1\;fneg %0,%1";
8074   else
8075     return "fneg %0,%1\;fneg %L0,%L1";
8077   [(set_attr "type" "fpsimple")
8078    (set_attr "length" "8")])
8080 (define_expand "abs<mode>2"
8081   [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
8082         (abs:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand")))]
8083   "FLOAT128_IEEE_P (<MODE>mode)
8084    || (FLOAT128_IBM_P (<MODE>mode) && TARGET_HARD_FLOAT)"
8086   rtx label;
8088   if (FLOAT128_IEEE_P (<MODE>mode))
8089     {
8090       if (TARGET_FLOAT128_HW)
8091         {
8092           if (<MODE>mode == TFmode)
8093             emit_insn (gen_abstf2_hw (operands[0], operands[1]));
8094           else if (<MODE>mode == KFmode)
8095             emit_insn (gen_abskf2_hw (operands[0], operands[1]));
8096           else
8097             FAIL;
8098           DONE;
8099         }
8100       else if (TARGET_FLOAT128_TYPE)
8101         {
8102           if (<MODE>mode == TFmode)
8103             emit_insn (gen_ieee_128bit_vsx_abstf2 (operands[0], operands[1]));
8104           else if (<MODE>mode == KFmode)
8105             emit_insn (gen_ieee_128bit_vsx_abskf2 (operands[0], operands[1]));
8106           else
8107             FAIL;
8108           DONE;
8109         }
8110       else
8111         FAIL;
8112     }
8114   label = gen_label_rtx ();
8115   if (<MODE>mode == TFmode)
8116     emit_insn (gen_abstf2_internal (operands[0], operands[1], label));
8117   else if (<MODE>mode == IFmode)
8118     emit_insn (gen_absif2_internal (operands[0], operands[1], label));
8119   else
8120     FAIL;
8121   emit_label (label);
8122   DONE;
8125 (define_expand "abs<mode>2_internal"
8126   [(set (match_operand:IBM128 0 "gpc_reg_operand")
8127         (match_operand:IBM128 1 "gpc_reg_operand"))
8128    (set (match_dup 3) (match_dup 5))
8129    (set (match_dup 5) (abs:DF (match_dup 5)))
8130    (set (match_dup 4) (compare:CCFP (match_dup 3) (match_dup 5)))
8131    (set (pc) (if_then_else (eq (match_dup 4) (const_int 0))
8132                            (label_ref (match_operand 2 ""))
8133                            (pc)))
8134    (set (match_dup 6) (neg:DF (match_dup 6)))]
8135   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8137   const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
8138   const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
8139   operands[3] = gen_reg_rtx (DFmode);
8140   operands[4] = gen_reg_rtx (CCFPmode);
8141   operands[5] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
8142   operands[6] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
8146 ;; Generate IEEE 128-bit -0.0 (0x80000000000000000000000000000000) in a vector
8147 ;; register
8149 (define_expand "ieee_128bit_negative_zero"
8150   [(set (match_operand:V16QI 0 "register_operand") (match_dup 1))]
8151   "TARGET_FLOAT128_TYPE"
8153   rtvec v = rtvec_alloc (16);
8154   int i, high;
8156   for (i = 0; i < 16; i++)
8157     RTVEC_ELT (v, i) = const0_rtx;
8159   high = (BYTES_BIG_ENDIAN) ? 0 : 15;
8160   RTVEC_ELT (v, high) = gen_int_mode (0x80, QImode);
8162   rs6000_expand_vector_init (operands[0], gen_rtx_PARALLEL (V16QImode, v));
8163   DONE;
8166 ;; IEEE 128-bit negate
8168 ;; We have 2 insns here for negate and absolute value.  The first uses
8169 ;; match_scratch so that phases like combine can recognize neg/abs as generic
8170 ;; insns, and second insn after the first split pass loads up the bit to
8171 ;; twiddle the sign bit.  Later GCSE passes can then combine multiple uses of
8172 ;; neg/abs to create the constant just once.
8174 (define_insn_and_split "ieee_128bit_vsx_neg<mode>2"
8175   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8176         (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8177    (clobber (match_scratch:V16QI 2 "=v"))]
8178   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8179   "#"
8180   "&& 1"
8181   [(parallel [(set (match_dup 0)
8182                    (neg:IEEE128 (match_dup 1)))
8183               (use (match_dup 2))])]
8185   if (GET_CODE (operands[2]) == SCRATCH)
8186     operands[2] = gen_reg_rtx (V16QImode);
8188   operands[3] = gen_reg_rtx (V16QImode);
8189   emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8191   [(set_attr "length" "8")
8192    (set_attr "type" "vecsimple")])
8194 (define_insn "*ieee_128bit_vsx_neg<mode>2_internal"
8195   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8196         (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8197    (use (match_operand:V16QI 2 "register_operand" "v"))]
8198   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8199   "xxlxor %x0,%x1,%x2"
8200   [(set_attr "type" "veclogical")])
8202 ;; IEEE 128-bit absolute value
8203 (define_insn_and_split "ieee_128bit_vsx_abs<mode>2"
8204   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8205         (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8206    (clobber (match_scratch:V16QI 2 "=v"))]
8207   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
8208   "#"
8209   "&& 1"
8210   [(parallel [(set (match_dup 0)
8211                    (abs:IEEE128 (match_dup 1)))
8212               (use (match_dup 2))])]
8214   if (GET_CODE (operands[2]) == SCRATCH)
8215     operands[2] = gen_reg_rtx (V16QImode);
8217   operands[3] = gen_reg_rtx (V16QImode);
8218   emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8220   [(set_attr "length" "8")
8221    (set_attr "type" "vecsimple")])
8223 (define_insn "*ieee_128bit_vsx_abs<mode>2_internal"
8224   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8225         (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8226    (use (match_operand:V16QI 2 "register_operand" "v"))]
8227   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8228   "xxlandc %x0,%x1,%x2"
8229   [(set_attr "type" "veclogical")])
8231 ;; IEEE 128-bit negative absolute value
8232 (define_insn_and_split "*ieee_128bit_vsx_nabs<mode>2"
8233   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8234         (neg:IEEE128
8235          (abs:IEEE128
8236           (match_operand:IEEE128 1 "register_operand" "wa"))))
8237    (clobber (match_scratch:V16QI 2 "=v"))]
8238   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW
8239    && FLOAT128_IEEE_P (<MODE>mode)"
8240   "#"
8241   "&& 1"
8242   [(parallel [(set (match_dup 0)
8243                    (neg:IEEE128 (abs:IEEE128 (match_dup 1))))
8244               (use (match_dup 2))])]
8246   if (GET_CODE (operands[2]) == SCRATCH)
8247     operands[2] = gen_reg_rtx (V16QImode);
8249   operands[3] = gen_reg_rtx (V16QImode);
8250   emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8252   [(set_attr "length" "8")
8253    (set_attr "type" "vecsimple")])
8255 (define_insn "*ieee_128bit_vsx_nabs<mode>2_internal"
8256   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8257         (neg:IEEE128
8258          (abs:IEEE128
8259           (match_operand:IEEE128 1 "register_operand" "wa"))))
8260    (use (match_operand:V16QI 2 "register_operand" "v"))]
8261   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8262   "xxlor %x0,%x1,%x2"
8263   [(set_attr "type" "veclogical")])
8265 ;; Float128 conversion functions.  These expand to library function calls.
8266 ;; We use expand to convert from IBM double double to IEEE 128-bit
8267 ;; and trunc for the opposite.
8268 (define_expand "extendiftf2"
8269   [(set (match_operand:TF 0 "gpc_reg_operand")
8270         (float_extend:TF (match_operand:IF 1 "gpc_reg_operand")))]
8271   "TARGET_FLOAT128_TYPE"
8273   rs6000_expand_float128_convert (operands[0], operands[1], false);
8274   DONE;
8277 (define_expand "extendifkf2"
8278   [(set (match_operand:KF 0 "gpc_reg_operand")
8279         (float_extend:KF (match_operand:IF 1 "gpc_reg_operand")))]
8280   "TARGET_FLOAT128_TYPE"
8282   rs6000_expand_float128_convert (operands[0], operands[1], false);
8283   DONE;
8286 (define_expand "extendtfkf2"
8287   [(set (match_operand:KF 0 "gpc_reg_operand")
8288         (float_extend:KF (match_operand:TF 1 "gpc_reg_operand")))]
8289   "TARGET_FLOAT128_TYPE"
8291   rs6000_expand_float128_convert (operands[0], operands[1], false);
8292   DONE;
8295 (define_expand "extendtfif2"
8296   [(set (match_operand:IF 0 "gpc_reg_operand")
8297         (float_extend:IF (match_operand:TF 1 "gpc_reg_operand")))]
8298   "TARGET_FLOAT128_TYPE"
8300   rs6000_expand_float128_convert (operands[0], operands[1], false);
8301   DONE;
8304 (define_expand "trunciftf2"
8305   [(set (match_operand:TF 0 "gpc_reg_operand")
8306         (float_truncate:TF (match_operand:IF 1 "gpc_reg_operand")))]
8307   "TARGET_FLOAT128_TYPE"
8309   rs6000_expand_float128_convert (operands[0], operands[1], false);
8310   DONE;
8313 (define_expand "truncifkf2"
8314   [(set (match_operand:KF 0 "gpc_reg_operand")
8315         (float_truncate:KF (match_operand:IF 1 "gpc_reg_operand")))]
8316   "TARGET_FLOAT128_TYPE"
8318   rs6000_expand_float128_convert (operands[0], operands[1], false);
8319   DONE;
8322 (define_expand "trunckftf2"
8323   [(set (match_operand:TF 0 "gpc_reg_operand")
8324         (float_truncate:TF (match_operand:KF 1 "gpc_reg_operand")))]
8325   "TARGET_FLOAT128_TYPE"
8327   rs6000_expand_float128_convert (operands[0], operands[1], false);
8328   DONE;
8331 (define_expand "trunctfif2"
8332   [(set (match_operand:IF 0 "gpc_reg_operand")
8333         (float_truncate:IF (match_operand:TF 1 "gpc_reg_operand")))]
8334   "TARGET_FLOAT128_TYPE"
8336   rs6000_expand_float128_convert (operands[0], operands[1], false);
8337   DONE;
8340 (define_insn_and_split "*extend<mode>tf2_internal"
8341   [(set (match_operand:TF 0 "gpc_reg_operand" "=<IFKF_reg>")
8342         (float_extend:TF
8343          (match_operand:IFKF 1 "gpc_reg_operand" "<IFKF_reg>")))]
8344    "TARGET_FLOAT128_TYPE
8345     && FLOAT128_IBM_P (TFmode) == FLOAT128_IBM_P (<MODE>mode)"
8346   "#"
8347   "&& reload_completed"
8348   [(set (match_dup 0) (match_dup 2))]
8350   operands[2] = gen_rtx_REG (TFmode, REGNO (operands[1]));
8353 (define_insn_and_split "*extendtf<mode>2_internal"
8354   [(set (match_operand:IFKF 0 "gpc_reg_operand" "=<IFKF_reg>")
8355         (float_extend:IFKF
8356          (match_operand:TF 1 "gpc_reg_operand" "<IFKF_reg>")))]
8357    "TARGET_FLOAT128_TYPE
8358     && FLOAT128_IBM_P (TFmode) == FLOAT128_IBM_P (<MODE>mode)"
8359   "#"
8360   "&& reload_completed"
8361   [(set (match_dup 0) (match_dup 2))]
8363   operands[2] = gen_rtx_REG (<MODE>mode, REGNO (operands[1]));
8367 ;; Reload helper functions used by rs6000_secondary_reload.  The patterns all
8368 ;; must have 3 arguments, and scratch register constraint must be a single
8369 ;; constraint.
8371 ;; Reload patterns to support gpr load/store with misaligned mem.
8372 ;; and multiple gpr load/store at offset >= 0xfffc
8373 (define_expand "reload_<mode>_store"
8374   [(parallel [(match_operand 0 "memory_operand" "=m")
8375               (match_operand 1 "gpc_reg_operand" "r")
8376               (match_operand:GPR 2 "register_operand" "=&b")])]
8377   ""
8379   rs6000_secondary_reload_gpr (operands[1], operands[0], operands[2], true);
8380   DONE;
8383 (define_expand "reload_<mode>_load"
8384   [(parallel [(match_operand 0 "gpc_reg_operand" "=r")
8385               (match_operand 1 "memory_operand" "m")
8386               (match_operand:GPR 2 "register_operand" "=b")])]
8387   ""
8389   rs6000_secondary_reload_gpr (operands[0], operands[1], operands[2], false);
8390   DONE;
8394 ;; Reload patterns for various types using the vector registers.  We may need
8395 ;; an additional base register to convert the reg+offset addressing to reg+reg
8396 ;; for vector registers and reg+reg or (reg+reg)&(-16) addressing to just an
8397 ;; index register for gpr registers.
8398 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_store"
8399   [(parallel [(match_operand:RELOAD 0 "memory_operand" "m")
8400               (match_operand:RELOAD 1 "gpc_reg_operand" "wa")
8401               (match_operand:P 2 "register_operand" "=b")])]
8402   "<P:tptrsize>"
8404   rs6000_secondary_reload_inner (operands[1], operands[0], operands[2], true);
8405   DONE;
8408 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_load"
8409   [(parallel [(match_operand:RELOAD 0 "gpc_reg_operand" "wa")
8410               (match_operand:RELOAD 1 "memory_operand" "m")
8411               (match_operand:P 2 "register_operand" "=b")])]
8412   "<P:tptrsize>"
8414   rs6000_secondary_reload_inner (operands[0], operands[1], operands[2], false);
8415   DONE;
8419 ;; Reload sometimes tries to move the address to a GPR, and can generate
8420 ;; invalid RTL for addresses involving AND -16.  Allow addresses involving
8421 ;; reg+reg, reg+small constant, or just reg, all wrapped in an AND -16.
8423 (define_insn_and_split "*vec_reload_and_plus_<mptrsize>"
8424   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
8425         (and:P (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
8426                        (match_operand:P 2 "reg_or_cint_operand" "rI"))
8427                (const_int -16)))]
8428   "TARGET_ALTIVEC && reload_completed"
8429   "#"
8430   "&& reload_completed"
8431   [(set (match_dup 0)
8432         (plus:P (match_dup 1)
8433                 (match_dup 2)))
8434    (set (match_dup 0)
8435         (and:P (match_dup 0)
8436                (const_int -16)))])
8438 ;; Power8 merge instructions to allow direct move to/from floating point
8439 ;; registers in 32-bit mode.  We use TF mode to get two registers to move the
8440 ;; individual 32-bit parts across.  Subreg doesn't work too well on the TF
8441 ;; value, since it is allocated in reload and not all of the flow information
8442 ;; is setup for it.  We have two patterns to do the two moves between gprs and
8443 ;; fprs.  There isn't a dependancy between the two, but we could potentially
8444 ;; schedule other instructions between the two instructions.
8446 (define_insn "p8_fmrgow_<mode>"
8447   [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
8448         (unspec:FMOVE64X [
8449                 (match_operand:DF 1 "register_operand" "d")
8450                 (match_operand:DF 2 "register_operand" "d")]
8451                          UNSPEC_P8V_FMRGOW))]
8452   "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8453   "fmrgow %0,%1,%2"
8454   [(set_attr "type" "fpsimple")])
8456 (define_insn "p8_mtvsrwz"
8457   [(set (match_operand:DF 0 "register_operand" "=d")
8458         (unspec:DF [(match_operand:SI 1 "register_operand" "r")]
8459                    UNSPEC_P8V_MTVSRWZ))]
8460   "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8461   "mtvsrwz %x0,%1"
8462   [(set_attr "type" "mftgpr")])
8464 (define_insn_and_split "reload_fpr_from_gpr<mode>"
8465   [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
8466         (unspec:FMOVE64X [(match_operand:FMOVE64X 1 "register_operand" "r")]
8467                          UNSPEC_P8V_RELOAD_FROM_GPR))
8468    (clobber (match_operand:IF 2 "register_operand" "=d"))]
8469   "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8470   "#"
8471   "&& reload_completed"
8472   [(const_int 0)]
8474   rtx dest = operands[0];
8475   rtx src = operands[1];
8476   rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0);
8477   rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8);
8478   rtx gpr_hi_reg = gen_highpart (SImode, src);
8479   rtx gpr_lo_reg = gen_lowpart (SImode, src);
8481   emit_insn (gen_p8_mtvsrwz (tmp_hi, gpr_hi_reg));
8482   emit_insn (gen_p8_mtvsrwz (tmp_lo, gpr_lo_reg));
8483   emit_insn (gen_p8_fmrgow_<mode> (dest, tmp_hi, tmp_lo));
8484   DONE;
8486   [(set_attr "length" "12")
8487    (set_attr "type" "three")])
8489 ;; Move 128 bit values from GPRs to VSX registers in 64-bit mode
8490 (define_insn "p8_mtvsrd_df"
8491   [(set (match_operand:DF 0 "register_operand" "=wa")
8492         (unspec:DF [(match_operand:DI 1 "register_operand" "r")]
8493                    UNSPEC_P8V_MTVSRD))]
8494   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8495   "mtvsrd %x0,%1"
8496   [(set_attr "type" "mftgpr")])
8498 (define_insn "p8_xxpermdi_<mode>"
8499   [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
8500         (unspec:FMOVE128_GPR [
8501                 (match_operand:DF 1 "register_operand" "wa")
8502                 (match_operand:DF 2 "register_operand" "wa")]
8503                 UNSPEC_P8V_XXPERMDI))]
8504   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8505   "xxpermdi %x0,%x1,%x2,0"
8506   [(set_attr "type" "vecperm")])
8508 (define_insn_and_split "reload_vsx_from_gpr<mode>"
8509   [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
8510         (unspec:FMOVE128_GPR
8511          [(match_operand:FMOVE128_GPR 1 "register_operand" "r")]
8512          UNSPEC_P8V_RELOAD_FROM_GPR))
8513    (clobber (match_operand:IF 2 "register_operand" "=wa"))]
8514   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8515   "#"
8516   "&& reload_completed"
8517   [(const_int 0)]
8519   rtx dest = operands[0];
8520   rtx src = operands[1];
8521   /* You might think that we could use op0 as one temp and a DF clobber
8522      as op2, but you'd be wrong.  Secondary reload move patterns don't
8523      check for overlap of the clobber and the destination.  */
8524   rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0);
8525   rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8);
8526   rtx gpr_hi_reg = gen_highpart (DImode, src);
8527   rtx gpr_lo_reg = gen_lowpart (DImode, src);
8529   emit_insn (gen_p8_mtvsrd_df (tmp_hi, gpr_hi_reg));
8530   emit_insn (gen_p8_mtvsrd_df (tmp_lo, gpr_lo_reg));
8531   emit_insn (gen_p8_xxpermdi_<mode> (dest, tmp_hi, tmp_lo));
8532   DONE;
8534   [(set_attr "length" "12")
8535    (set_attr "type" "three")])
8537 (define_split
8538   [(set (match_operand:FMOVE128_GPR 0 "nonimmediate_operand")
8539         (match_operand:FMOVE128_GPR 1 "input_operand"))]
8540   "reload_completed
8541    && (int_reg_operand (operands[0], <MODE>mode)
8542        || int_reg_operand (operands[1], <MODE>mode))
8543    && (!TARGET_DIRECT_MOVE_128
8544        || (!vsx_register_operand (operands[0], <MODE>mode)
8545            && !vsx_register_operand (operands[1], <MODE>mode)))"
8546   [(pc)]
8547 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
8549 ;; Move SFmode to a VSX from a GPR register.  Because scalar floating point
8550 ;; type is stored internally as double precision in the VSX registers, we have
8551 ;; to convert it from the vector format.
8552 (define_insn "p8_mtvsrd_sf"
8553   [(set (match_operand:SF 0 "register_operand" "=wa")
8554         (unspec:SF [(match_operand:DI 1 "register_operand" "r")]
8555                    UNSPEC_P8V_MTVSRD))]
8556   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8557   "mtvsrd %x0,%1"
8558   [(set_attr "type" "mftgpr")])
8560 (define_insn_and_split "reload_vsx_from_gprsf"
8561   [(set (match_operand:SF 0 "register_operand" "=wa")
8562         (unspec:SF [(match_operand:SF 1 "register_operand" "r")]
8563                    UNSPEC_P8V_RELOAD_FROM_GPR))
8564    (clobber (match_operand:DI 2 "register_operand" "=r"))]
8565   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8566   "#"
8567   "&& reload_completed"
8568   [(const_int 0)]
8570   rtx op0 = operands[0];
8571   rtx op1 = operands[1];
8572   rtx op2 = operands[2];
8573   rtx op1_di = simplify_gen_subreg (DImode, op1, SFmode, 0);
8575   /* Move SF value to upper 32-bits for xscvspdpn.  */
8576   emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32)));
8577   emit_insn (gen_p8_mtvsrd_sf (op0, op2));
8578   emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0));
8579   DONE;
8581   [(set_attr "length" "8")
8582    (set_attr "type" "two")])
8584 ;; Move 128 bit values from VSX registers to GPRs in 64-bit mode by doing a
8585 ;; normal 64-bit move, followed by an xxpermdi to get the bottom 64-bit value,
8586 ;; and then doing a move of that.
8587 (define_insn "p8_mfvsrd_3_<mode>"
8588   [(set (match_operand:DF 0 "register_operand" "=r")
8589         (unspec:DF [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
8590                    UNSPEC_P8V_RELOAD_FROM_VSX))]
8591   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8592   "mfvsrd %0,%x1"
8593   [(set_attr "type" "mftgpr")])
8595 (define_insn_and_split "reload_gpr_from_vsx<mode>"
8596   [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=r")
8597         (unspec:FMOVE128_GPR
8598          [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
8599          UNSPEC_P8V_RELOAD_FROM_VSX))
8600    (clobber (match_operand:FMOVE128_GPR 2 "register_operand" "=wa"))]
8601   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8602   "#"
8603   "&& reload_completed"
8604   [(const_int 0)]
8606   rtx dest = operands[0];
8607   rtx src = operands[1];
8608   rtx tmp = operands[2];
8609   rtx gpr_hi_reg = gen_highpart (DFmode, dest);
8610   rtx gpr_lo_reg = gen_lowpart (DFmode, dest);
8612   emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_hi_reg, src));
8613   emit_insn (gen_vsx_xxpermdi_<mode>_be (tmp, src, src, GEN_INT (3)));
8614   emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_lo_reg, tmp));
8615   DONE;
8617   [(set_attr "length" "12")
8618    (set_attr "type" "three")])
8620 ;; Move SFmode to a GPR from a VSX register.  Because scalar floating point
8621 ;; type is stored internally as double precision, we have to convert it to the
8622 ;; vector format.
8624 (define_insn_and_split "reload_gpr_from_vsxsf"
8625   [(set (match_operand:SF 0 "register_operand" "=r")
8626         (unspec:SF [(match_operand:SF 1 "register_operand" "ww")]
8627                    UNSPEC_P8V_RELOAD_FROM_VSX))
8628    (clobber (match_operand:V4SF 2 "register_operand" "=wIwH"))]
8629   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8630   "#"
8631   "&& reload_completed"
8632   [(const_int 0)]
8634   rtx op0 = operands[0];
8635   rtx op1 = operands[1];
8636   rtx op2 = operands[2];
8637   rtx op0_di = gen_rtx_REG (DImode, reg_or_subregno (op0));
8638   rtx op2_si = gen_rtx_REG (SImode, reg_or_subregno (op2));
8640   emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
8641   emit_insn (gen_zero_extendsidi2 (op0_di, op2_si));
8642   DONE;
8644   [(set_attr "length" "8")
8645    (set_attr "type" "two")])
8648 ;; Next come the multi-word integer load and store and the load and store
8649 ;; multiple insns.
8651 ;; List r->r after r->Y, otherwise reload will try to reload a
8652 ;; non-offsettable address by using r->r which won't make progress.
8653 ;; Use of fprs is disparaged slightly otherwise reload prefers to reload
8654 ;; a gpr into a fpr instead of reloading an invalid 'Y' address
8656 ;;        GPR store  GPR load   GPR move   FPR store  FPR load    FPR move
8657 ;;        GPR const  AVX store  AVX store  AVX load   AVX load    VSX move
8658 ;;        P9 0       P9 -1      AVX 0/-1   VSX 0      VSX -1      P9 const
8659 ;;        AVX const  
8661 (define_insn "*movdi_internal32"
8662   [(set (match_operand:DI 0 "nonimmediate_operand"
8663          "=Y,        r,         r,         m,         ^d,         ^d,
8664           r,         wY,        Z,         ^wb,       $wv,        ^wi,
8665           *wo,       *wo,       *wv,       *wi,       *wi,        *wv,
8666           *wv")
8668         (match_operand:DI 1 "input_operand"
8669          "r,         Y,         r,         ^d,        m,          ^d,
8670           IJKnGHF,   ^wb,       $wv,       wY,        Z,          ^wi,
8671           Oj,        wM,        OjwM,      Oj,        wM,         wS,
8672           wB"))]
8674   "! TARGET_POWERPC64
8675    && (gpc_reg_operand (operands[0], DImode)
8676        || gpc_reg_operand (operands[1], DImode))"
8677   "@
8678    #
8679    #
8680    #
8681    stfd%U0%X0 %1,%0
8682    lfd%U1%X1 %0,%1
8683    fmr %0,%1
8684    #
8685    stxsd %1,%0
8686    stxsdx %x1,%y0
8687    lxsd %0,%1
8688    lxsdx %x0,%y1
8689    xxlor %x0,%x1,%x1
8690    xxspltib %x0,0
8691    xxspltib %x0,255
8692    vspltisw %0,%1
8693    xxlxor %x0,%x0,%x0
8694    xxlorc %x0,%x0,%x0
8695    #
8696    #"
8697   [(set_attr "type"
8698                "store,     load,      *,         fpstore,    fpload,     fpsimple,
8699                 *,         fpstore,   fpstore,   fpload,     fpload,     veclogical,
8700                 vecsimple, vecsimple, vecsimple, veclogical, veclogical, vecsimple,
8701                 vecsimple")
8702    (set_attr "size" "64")])
8704 (define_split
8705   [(set (match_operand:DI 0 "gpc_reg_operand")
8706         (match_operand:DI 1 "const_int_operand"))]
8707   "! TARGET_POWERPC64 && reload_completed
8708    && gpr_or_gpr_p (operands[0], operands[1])
8709    && !direct_move_p (operands[0], operands[1])"
8710   [(set (match_dup 2) (match_dup 4))
8711    (set (match_dup 3) (match_dup 1))]
8713   HOST_WIDE_INT value = INTVAL (operands[1]);
8714   operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
8715                                        DImode);
8716   operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
8717                                        DImode);
8718   operands[4] = GEN_INT (value >> 32);
8719   operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
8722 (define_split
8723   [(set (match_operand:DIFD 0 "nonimmediate_operand")
8724         (match_operand:DIFD 1 "input_operand"))]
8725   "reload_completed && !TARGET_POWERPC64
8726    && gpr_or_gpr_p (operands[0], operands[1])
8727    && !direct_move_p (operands[0], operands[1])"
8728   [(pc)]
8729 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
8731 ;;              GPR store  GPR load   GPR move   GPR li     GPR lis     GPR #
8732 ;;              FPR store  FPR load   FPR move   AVX store  AVX store   AVX load
8733 ;;              AVX load   VSX move   P9 0       P9 -1      AVX 0/-1    VSX 0
8734 ;;              VSX -1     P9 const   AVX const  From SPR   To SPR      SPR<->SPR
8735 ;;              FPR->GPR   GPR->FPR   VSX->GPR   GPR->VSX
8736 (define_insn "*movdi_internal64"
8737   [(set (match_operand:DI 0 "nonimmediate_operand"
8738                "=YZ,       r,         r,         r,         r,          r,
8739                 m,         ^d,        ^d,        wY,        Z,          $wb,
8740                 $wv,       ^wi,       *wo,       *wo,       *wv,        *wi,
8741                 *wi,       *wv,       *wv,       r,         *h,         *h,
8742                 ?*r,       ?*wg,      ?*r,       ?*wj")
8744         (match_operand:DI 1 "input_operand"
8745                "r,         YZ,        r,         I,         L,          nF,
8746                 ^d,        m,         ^d,        ^wb,       $wv,        wY,
8747                 Z,         ^wi,       Oj,        wM,        OjwM,       Oj,
8748                 wM,        wS,        wB,        *h,        r,          0,
8749                 wg,        r,         wj,        r"))]
8751   "TARGET_POWERPC64
8752    && (gpc_reg_operand (operands[0], DImode)
8753        || gpc_reg_operand (operands[1], DImode))"
8754   "@
8755    std%U0%X0 %1,%0
8756    ld%U1%X1 %0,%1
8757    mr %0,%1
8758    li %0,%1
8759    lis %0,%v1
8760    #
8761    stfd%U0%X0 %1,%0
8762    lfd%U1%X1 %0,%1
8763    fmr %0,%1
8764    stxsd %1,%0
8765    stxsdx %x1,%y0
8766    lxsd %0,%1
8767    lxsdx %x0,%y1
8768    xxlor %x0,%x1,%x1
8769    xxspltib %x0,0
8770    xxspltib %x0,255
8771    #
8772    xxlxor %x0,%x0,%x0
8773    xxlorc %x0,%x0,%x0
8774    #
8775    #
8776    mf%1 %0
8777    mt%0 %1
8778    nop
8779    mftgpr %0,%1
8780    mffgpr %0,%1
8781    mfvsrd %0,%x1
8782    mtvsrd %x0,%1"
8783   [(set_attr "type"
8784                "store,      load,       *,         *,         *,         *,
8785                 fpstore,    fpload,     fpsimple,  fpstore,   fpstore,   fpload,
8786                 fpload,     veclogical, vecsimple, vecsimple, vecsimple, veclogical,
8787                 veclogical, vecsimple,  vecsimple, mfjmpr,    mtjmpr,    *,
8788                 mftgpr,     mffgpr,     mftgpr,    mffgpr")
8790    (set_attr "size" "64")
8791    (set_attr "length"
8792                "4,         4,         4,         4,         4,          20,
8793                 4,         4,         4,         4,         4,          4,
8794                 4,         4,         4,         4,         4,          8,
8795                 8,         4,         4,         4,         4,          4,
8796                 4,         4,         4,         4")])
8798 ; Some DImode loads are best done as a load of -1 followed by a mask
8799 ; instruction.
8800 (define_split
8801   [(set (match_operand:DI 0 "int_reg_operand_not_pseudo")
8802         (match_operand:DI 1 "const_int_operand"))]
8803   "TARGET_POWERPC64
8804    && num_insns_constant (operands[1], DImode) > 1
8805    && !IN_RANGE (INTVAL (operands[1]), -0x80000000, 0xffffffff)
8806    && rs6000_is_valid_and_mask (operands[1], DImode)"
8807   [(set (match_dup 0)
8808         (const_int -1))
8809    (set (match_dup 0)
8810         (and:DI (match_dup 0)
8811                 (match_dup 1)))]
8812   "")
8814 ;; Split a load of a large constant into the appropriate five-instruction
8815 ;; sequence.  Handle anything in a constant number of insns.
8816 ;; When non-easy constants can go in the TOC, this should use
8817 ;; easy_fp_constant predicate.
8818 (define_split
8819   [(set (match_operand:DI 0 "int_reg_operand_not_pseudo")
8820         (match_operand:DI 1 "const_int_operand"))]
8821   "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
8822   [(set (match_dup 0) (match_dup 2))
8823    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
8825   if (rs6000_emit_set_const (operands[0], operands[1]))
8826     DONE;
8827   else
8828     FAIL;
8831 (define_split
8832   [(set (match_operand:DI 0 "int_reg_operand_not_pseudo")
8833         (match_operand:DI 1 "const_scalar_int_operand"))]
8834   "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
8835   [(set (match_dup 0) (match_dup 2))
8836    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
8838   if (rs6000_emit_set_const (operands[0], operands[1]))
8839     DONE;
8840   else
8841     FAIL;
8844 (define_split
8845   [(set (match_operand:DI 0 "altivec_register_operand")
8846         (match_operand:DI 1 "s5bit_cint_operand"))]
8847   "TARGET_VSX && reload_completed"
8848   [(const_int 0)]
8850   rtx op0 = operands[0];
8851   rtx op1 = operands[1];
8852   int r = REGNO (op0);
8853   rtx op0_v4si = gen_rtx_REG (V4SImode, r);
8855   emit_insn (gen_altivec_vspltisw (op0_v4si, op1));
8856   if (op1 != const0_rtx && op1 != constm1_rtx)
8857     {
8858       rtx op0_v2di = gen_rtx_REG (V2DImode, r);
8859       emit_insn (gen_altivec_vupkhsw (op0_v2di, op0_v4si));
8860     }
8861   DONE;
8864 ;; Split integer constants that can be loaded with XXSPLTIB and a
8865 ;; sign extend operation.
8866 (define_split
8867   [(set (match_operand:INT_ISA3 0 "altivec_register_operand")
8868         (match_operand:INT_ISA3 1 "xxspltib_constant_split"))]
8869   "TARGET_P9_VECTOR && reload_completed"
8870   [(const_int 0)]
8872   rtx op0 = operands[0];
8873   rtx op1 = operands[1];
8874   int r = REGNO (op0);
8875   rtx op0_v16qi = gen_rtx_REG (V16QImode, r);
8877   emit_insn (gen_xxspltib_v16qi (op0_v16qi, op1));
8878   if (<MODE>mode == DImode)
8879     emit_insn (gen_vsx_sign_extend_qi_di (operands[0], op0_v16qi));
8880   else if (<MODE>mode == SImode)
8881     emit_insn (gen_vsx_sign_extend_qi_si (operands[0], op0_v16qi));
8882   else if (<MODE>mode == HImode)
8883     {
8884       rtx op0_v8hi = gen_rtx_REG (V8HImode, r);
8885       emit_insn (gen_altivec_vupkhsb (op0_v8hi, op0_v16qi));
8886     }
8887   DONE;
8891 ;; TImode/PTImode is similar, except that we usually want to compute the
8892 ;; address into a register and use lsi/stsi (the exception is during reload).
8894 (define_insn "*mov<mode>_string"
8895   [(set (match_operand:TI2 0 "reg_or_mem_operand" "=Q,Y,????r,????r,????r,r")
8896         (match_operand:TI2 1 "input_operand" "r,r,Q,Y,r,n"))]
8897   "! TARGET_POWERPC64
8898    && (<MODE>mode != TImode || VECTOR_MEM_NONE_P (TImode))
8899    && (gpc_reg_operand (operands[0], <MODE>mode)
8900        || gpc_reg_operand (operands[1], <MODE>mode))"
8901   "#"
8902   [(set_attr "type" "store,store,load,load,*,*")
8903    (set_attr "update" "yes")
8904    (set_attr "indexed" "yes")
8905    (set_attr "cell_micro" "conditional")])
8907 (define_insn "*mov<mode>_ppc64"
8908   [(set (match_operand:TI2 0 "nonimmediate_operand" "=wQ,Y,r,r,r,r")
8909         (match_operand:TI2 1 "input_operand" "r,r,wQ,Y,r,n"))]
8910   "(TARGET_POWERPC64 && VECTOR_MEM_NONE_P (<MODE>mode)
8911    && (gpc_reg_operand (operands[0], <MODE>mode)
8912        || gpc_reg_operand (operands[1], <MODE>mode)))"
8914   return rs6000_output_move_128bit (operands);
8916   [(set_attr "type" "store,store,load,load,*,*")
8917    (set_attr "length" "8")])
8919 (define_split
8920   [(set (match_operand:TI2 0 "int_reg_operand")
8921         (match_operand:TI2 1 "const_scalar_int_operand"))]
8922   "TARGET_POWERPC64
8923    && (VECTOR_MEM_NONE_P (<MODE>mode)
8924        || (reload_completed && INT_REGNO_P (REGNO (operands[0]))))"
8925   [(set (match_dup 2) (match_dup 4))
8926    (set (match_dup 3) (match_dup 5))]
8928   operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
8929                                        <MODE>mode);
8930   operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
8931                                        <MODE>mode);
8932   if (CONST_WIDE_INT_P (operands[1]))
8933     {
8934       operands[4] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 1));
8935       operands[5] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 0));
8936     }
8937   else if (CONST_INT_P (operands[1]))
8938     {
8939       operands[4] = GEN_INT (- (INTVAL (operands[1]) < 0));
8940       operands[5] = operands[1];
8941     }
8942   else
8943     FAIL;
8946 (define_split
8947   [(set (match_operand:TI2 0 "nonimmediate_operand")
8948         (match_operand:TI2 1 "input_operand"))]
8949   "reload_completed
8950    && gpr_or_gpr_p (operands[0], operands[1])
8951    && !direct_move_p (operands[0], operands[1])
8952    && !quad_load_store_p (operands[0], operands[1])"
8953   [(pc)]
8954 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
8956 (define_expand "setmemsi"
8957   [(parallel [(set (match_operand:BLK 0 "")
8958                    (match_operand 2 "const_int_operand"))
8959               (use (match_operand:SI 1 ""))
8960               (use (match_operand:SI 3 ""))])]
8961   ""
8963   /* If value to set is not zero, use the library routine.  */
8964   if (operands[2] != const0_rtx)
8965     FAIL;
8967   if (expand_block_clear (operands))
8968     DONE;
8969   else
8970     FAIL;
8973 ;; String compare N insn.
8974 ;; Argument 0 is the target (result)
8975 ;; Argument 1 is the destination
8976 ;; Argument 2 is the source
8977 ;; Argument 3 is the length
8978 ;; Argument 4 is the alignment
8980 (define_expand "cmpstrnsi"
8981   [(parallel [(set (match_operand:SI 0)
8982                (compare:SI (match_operand:BLK 1)
8983                            (match_operand:BLK 2)))
8984               (use (match_operand:SI 3))
8985               (use (match_operand:SI 4))])]
8986   "TARGET_CMPB && (BYTES_BIG_ENDIAN || TARGET_LDBRX)"
8988   if (optimize_insn_for_size_p ())
8989     FAIL;
8991   if (expand_strn_compare (operands, 0))
8992     DONE;
8993   else  
8994     FAIL;
8997 ;; String compare insn.
8998 ;; Argument 0 is the target (result)
8999 ;; Argument 1 is the destination
9000 ;; Argument 2 is the source
9001 ;; Argument 3 is the alignment
9003 (define_expand "cmpstrsi"
9004   [(parallel [(set (match_operand:SI 0)
9005                (compare:SI (match_operand:BLK 1)
9006                            (match_operand:BLK 2)))
9007               (use (match_operand:SI 3))])]
9008   "TARGET_CMPB && (BYTES_BIG_ENDIAN || TARGET_LDBRX)"
9010   if (optimize_insn_for_size_p ())
9011     FAIL;
9013   if (expand_strn_compare (operands, 1))
9014     DONE;
9015   else  
9016     FAIL;
9019 ;; Block compare insn.
9020 ;; Argument 0 is the target (result)
9021 ;; Argument 1 is the destination
9022 ;; Argument 2 is the source
9023 ;; Argument 3 is the length
9024 ;; Argument 4 is the alignment
9026 (define_expand "cmpmemsi"
9027   [(parallel [(set (match_operand:SI 0)
9028                (compare:SI (match_operand:BLK 1)
9029                            (match_operand:BLK 2)))
9030               (use (match_operand:SI 3))
9031               (use (match_operand:SI 4))])]
9032   "TARGET_POPCNTD"
9034   if (expand_block_compare (operands))
9035     DONE;
9036   else
9037     FAIL;
9040 ;; String/block move insn.
9041 ;; Argument 0 is the destination
9042 ;; Argument 1 is the source
9043 ;; Argument 2 is the length
9044 ;; Argument 3 is the alignment
9046 (define_expand "movmemsi"
9047   [(parallel [(set (match_operand:BLK 0 "")
9048                    (match_operand:BLK 1 ""))
9049               (use (match_operand:SI 2 ""))
9050               (use (match_operand:SI 3 ""))])]
9051   ""
9053   if (expand_block_move (operands))
9054     DONE;
9055   else
9056     FAIL;
9059 ;; Define insns that do load or store with update.  Some of these we can
9060 ;; get by using pre-decrement or pre-increment, but the hardware can also
9061 ;; do cases where the increment is not the size of the object.
9063 ;; In all these cases, we use operands 0 and 1 for the register being
9064 ;; incremented because those are the operands that local-alloc will
9065 ;; tie and these are the pair most likely to be tieable (and the ones
9066 ;; that will benefit the most).
9068 (define_insn "*movdi_update1"
9069   [(set (match_operand:DI 3 "gpc_reg_operand" "=r,r")
9070         (mem:DI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0,0")
9071                          (match_operand:DI 2 "reg_or_aligned_short_operand" "r,I"))))
9072    (set (match_operand:DI 0 "gpc_reg_operand" "=b,b")
9073         (plus:DI (match_dup 1) (match_dup 2)))]
9074   "TARGET_POWERPC64 && TARGET_UPDATE
9075    && (!avoiding_indexed_address_p (DImode)
9076        || !gpc_reg_operand (operands[2], DImode))"
9077   "@
9078    ldux %3,%0,%2
9079    ldu %3,%2(%0)"
9080   [(set_attr "type" "load")
9081    (set_attr "update" "yes")
9082    (set_attr "indexed" "yes,no")])
9084 (define_insn "movdi_<mode>_update"
9085   [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9086                          (match_operand:P 2 "reg_or_aligned_short_operand" "r,I")))
9087         (match_operand:DI 3 "gpc_reg_operand" "r,r"))
9088    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9089         (plus:P (match_dup 1) (match_dup 2)))]
9090   "TARGET_POWERPC64 && TARGET_UPDATE
9091    && (!avoiding_indexed_address_p (Pmode)
9092        || !gpc_reg_operand (operands[2], Pmode)
9093        || (REG_P (operands[0])
9094            && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
9095   "@
9096    stdux %3,%0,%2
9097    stdu %3,%2(%0)"
9098   [(set_attr "type" "store")
9099    (set_attr "update" "yes")
9100    (set_attr "indexed" "yes,no")])
9102 ;; This pattern is only conditional on TARGET_POWERPC64, as it is
9103 ;; needed for stack allocation, even if the user passes -mno-update.
9104 (define_insn "movdi_<mode>_update_stack"
9105   [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9106                          (match_operand:P 2 "reg_or_aligned_short_operand" "r,I")))
9107         (match_operand:DI 3 "gpc_reg_operand" "r,r"))
9108    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9109         (plus:P (match_dup 1) (match_dup 2)))]
9110   "TARGET_POWERPC64"
9111   "@
9112    stdux %3,%0,%2
9113    stdu %3,%2(%0)"
9114   [(set_attr "type" "store")
9115    (set_attr "update" "yes")
9116    (set_attr "indexed" "yes,no")])
9118 (define_insn "*movsi_update1"
9119   [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9120         (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9121                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9122    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9123         (plus:SI (match_dup 1) (match_dup 2)))]
9124   "TARGET_UPDATE
9125    && (!avoiding_indexed_address_p (SImode)
9126        || !gpc_reg_operand (operands[2], SImode))"
9127   "@
9128    lwzux %3,%0,%2
9129    lwzu %3,%2(%0)"
9130   [(set_attr "type" "load")
9131    (set_attr "update" "yes")
9132    (set_attr "indexed" "yes,no")])
9134 (define_insn "*movsi_update2"
9135   [(set (match_operand:DI 3 "gpc_reg_operand" "=r")
9136         (sign_extend:DI
9137          (mem:SI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0")
9138                           (match_operand:DI 2 "gpc_reg_operand" "r")))))
9139    (set (match_operand:DI 0 "gpc_reg_operand" "=b")
9140         (plus:DI (match_dup 1) (match_dup 2)))]
9141   "TARGET_POWERPC64 && !avoiding_indexed_address_p (DImode)"
9142   "lwaux %3,%0,%2"
9143   [(set_attr "type" "load")
9144    (set_attr "sign_extend" "yes")
9145    (set_attr "update" "yes")
9146    (set_attr "indexed" "yes")])
9148 (define_insn "movsi_update"
9149   [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9150                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9151         (match_operand:SI 3 "gpc_reg_operand" "r,r"))
9152    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9153         (plus:SI (match_dup 1) (match_dup 2)))]
9154   "TARGET_UPDATE
9155    && (!avoiding_indexed_address_p (SImode)
9156        || !gpc_reg_operand (operands[2], SImode)
9157        || (REG_P (operands[0])
9158            && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
9159   "@
9160    stwux %3,%0,%2
9161    stwu %3,%2(%0)"
9162   [(set_attr "type" "store")
9163    (set_attr "update" "yes")
9164    (set_attr "indexed" "yes,no")])
9166 ;; This is an unconditional pattern; needed for stack allocation, even
9167 ;; if the user passes -mno-update.
9168 (define_insn "movsi_update_stack"
9169   [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9170                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9171         (match_operand:SI 3 "gpc_reg_operand" "r,r"))
9172    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9173         (plus:SI (match_dup 1) (match_dup 2)))]
9174   ""
9175   "@
9176    stwux %3,%0,%2
9177    stwu %3,%2(%0)"
9178   [(set_attr "type" "store")
9179    (set_attr "update" "yes")
9180    (set_attr "indexed" "yes,no")])
9182 (define_insn "*movhi_update1"
9183   [(set (match_operand:HI 3 "gpc_reg_operand" "=r,r")
9184         (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9185                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9186    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9187         (plus:SI (match_dup 1) (match_dup 2)))]
9188   "TARGET_UPDATE
9189    && (!avoiding_indexed_address_p (SImode)
9190        || !gpc_reg_operand (operands[2], SImode))"
9191   "@
9192    lhzux %3,%0,%2
9193    lhzu %3,%2(%0)"
9194   [(set_attr "type" "load")
9195    (set_attr "update" "yes")
9196    (set_attr "indexed" "yes,no")])
9198 (define_insn "*movhi_update2"
9199   [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9200         (zero_extend:SI
9201          (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9202                           (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
9203    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9204         (plus:SI (match_dup 1) (match_dup 2)))]
9205   "TARGET_UPDATE
9206    && (!avoiding_indexed_address_p (SImode)
9207        || !gpc_reg_operand (operands[2], SImode))"
9208   "@
9209    lhzux %3,%0,%2
9210    lhzu %3,%2(%0)"
9211   [(set_attr "type" "load")
9212    (set_attr "update" "yes")
9213    (set_attr "indexed" "yes,no")])
9215 (define_insn "*movhi_update3"
9216   [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9217         (sign_extend:SI
9218          (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9219                           (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
9220    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9221         (plus:SI (match_dup 1) (match_dup 2)))]
9222   "TARGET_UPDATE
9223    && !(avoiding_indexed_address_p (SImode)
9224         && gpc_reg_operand (operands[2], SImode))"
9225   "@
9226    lhaux %3,%0,%2
9227    lhau %3,%2(%0)"
9228   [(set_attr "type" "load")
9229    (set_attr "sign_extend" "yes")
9230    (set_attr "update" "yes")
9231    (set_attr "indexed" "yes,no")])
9233 (define_insn "*movhi_update4"
9234   [(set (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9235                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9236         (match_operand:HI 3 "gpc_reg_operand" "r,r"))
9237    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9238         (plus:SI (match_dup 1) (match_dup 2)))]
9239   "TARGET_UPDATE
9240    && (!avoiding_indexed_address_p (SImode)
9241        || !gpc_reg_operand (operands[2], SImode))"
9242   "@
9243    sthux %3,%0,%2
9244    sthu %3,%2(%0)"
9245   [(set_attr "type" "store")
9246    (set_attr "update" "yes")
9247    (set_attr "indexed" "yes,no")])
9249 (define_insn "*movqi_update1"
9250   [(set (match_operand:QI 3 "gpc_reg_operand" "=r,r")
9251         (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9252                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9253    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9254         (plus:SI (match_dup 1) (match_dup 2)))]
9255   "TARGET_UPDATE
9256    && (!avoiding_indexed_address_p (SImode)
9257        || !gpc_reg_operand (operands[2], SImode))"
9258   "@
9259    lbzux %3,%0,%2
9260    lbzu %3,%2(%0)"
9261   [(set_attr "type" "load")
9262    (set_attr "update" "yes")
9263    (set_attr "indexed" "yes,no")])
9265 (define_insn "*movqi_update2"
9266   [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9267         (zero_extend:SI
9268          (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9269                           (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
9270    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9271         (plus:SI (match_dup 1) (match_dup 2)))]
9272   "TARGET_UPDATE
9273    && (!avoiding_indexed_address_p (SImode)
9274        || !gpc_reg_operand (operands[2], SImode))"
9275   "@
9276    lbzux %3,%0,%2
9277    lbzu %3,%2(%0)"
9278   [(set_attr "type" "load")
9279    (set_attr "update" "yes")
9280    (set_attr "indexed" "yes,no")])
9282 (define_insn "*movqi_update3"
9283   [(set (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9284                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9285         (match_operand:QI 3 "gpc_reg_operand" "r,r"))
9286    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9287         (plus:SI (match_dup 1) (match_dup 2)))]
9288   "TARGET_UPDATE
9289    && (!avoiding_indexed_address_p (SImode)
9290        || !gpc_reg_operand (operands[2], SImode))"
9291   "@
9292    stbux %3,%0,%2
9293    stbu %3,%2(%0)"
9294   [(set_attr "type" "store")
9295    (set_attr "update" "yes")
9296    (set_attr "indexed" "yes,no")])
9298 (define_insn "*movsf_update1"
9299   [(set (match_operand:SF 3 "gpc_reg_operand" "=f,f")
9300         (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9301                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9302    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9303         (plus:SI (match_dup 1) (match_dup 2)))]
9304   "TARGET_HARD_FLOAT && TARGET_UPDATE
9305    && (!avoiding_indexed_address_p (SImode)
9306        || !gpc_reg_operand (operands[2], SImode))"
9307   "@
9308    lfsux %3,%0,%2
9309    lfsu %3,%2(%0)"
9310   [(set_attr "type" "fpload")
9311    (set_attr "update" "yes")
9312    (set_attr "indexed" "yes,no")])
9314 (define_insn "*movsf_update2"
9315   [(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9316                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9317         (match_operand:SF 3 "gpc_reg_operand" "f,f"))
9318    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9319         (plus:SI (match_dup 1) (match_dup 2)))]
9320   "TARGET_HARD_FLOAT && TARGET_UPDATE
9321    && (!avoiding_indexed_address_p (SImode)
9322        || !gpc_reg_operand (operands[2], SImode))"
9323   "@
9324    stfsux %3,%0,%2
9325    stfsu %3,%2(%0)"
9326   [(set_attr "type" "fpstore")
9327    (set_attr "update" "yes")
9328    (set_attr "indexed" "yes,no")])
9330 (define_insn "*movsf_update3"
9331   [(set (match_operand:SF 3 "gpc_reg_operand" "=r,r")
9332         (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9333                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9334    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9335         (plus:SI (match_dup 1) (match_dup 2)))]
9336   "TARGET_SOFT_FLOAT && TARGET_UPDATE
9337    && (!avoiding_indexed_address_p (SImode)
9338        || !gpc_reg_operand (operands[2], SImode))"
9339   "@
9340    lwzux %3,%0,%2
9341    lwzu %3,%2(%0)"
9342   [(set_attr "type" "load")
9343    (set_attr "update" "yes")
9344    (set_attr "indexed" "yes,no")])
9346 (define_insn "*movsf_update4"
9347   [(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9348                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9349         (match_operand:SF 3 "gpc_reg_operand" "r,r"))
9350    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9351         (plus:SI (match_dup 1) (match_dup 2)))]
9352   "TARGET_SOFT_FLOAT && TARGET_UPDATE
9353    && (!avoiding_indexed_address_p (SImode)
9354        || !gpc_reg_operand (operands[2], SImode))"
9355   "@
9356    stwux %3,%0,%2
9357    stwu %3,%2(%0)"
9358   [(set_attr "type" "store")
9359    (set_attr "update" "yes")
9360    (set_attr "indexed" "yes,no")])
9362 (define_insn "*movdf_update1"
9363   [(set (match_operand:DF 3 "gpc_reg_operand" "=d,d")
9364         (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9365                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9366    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9367         (plus:SI (match_dup 1) (match_dup 2)))]
9368   "TARGET_HARD_FLOAT && TARGET_UPDATE
9369    && (!avoiding_indexed_address_p (SImode)
9370        || !gpc_reg_operand (operands[2], SImode))"
9371   "@
9372    lfdux %3,%0,%2
9373    lfdu %3,%2(%0)"
9374   [(set_attr "type" "fpload")
9375    (set_attr "update" "yes")
9376    (set_attr "indexed" "yes,no")
9377    (set_attr "size" "64")])
9379 (define_insn "*movdf_update2"
9380   [(set (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9381                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9382         (match_operand:DF 3 "gpc_reg_operand" "d,d"))
9383    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9384         (plus:SI (match_dup 1) (match_dup 2)))]
9385   "TARGET_HARD_FLOAT && TARGET_UPDATE
9386    && (!avoiding_indexed_address_p (SImode)
9387        || !gpc_reg_operand (operands[2], SImode))"
9388   "@
9389    stfdux %3,%0,%2
9390    stfdu %3,%2(%0)"
9391   [(set_attr "type" "fpstore")
9392    (set_attr "update" "yes")
9393    (set_attr "indexed" "yes,no")])
9396 ;; After inserting conditional returns we can sometimes have
9397 ;; unnecessary register moves.  Unfortunately we cannot have a
9398 ;; modeless peephole here, because some single SImode sets have early
9399 ;; clobber outputs.  Although those sets expand to multi-ppc-insn
9400 ;; sequences, using get_attr_length here will smash the operands
9401 ;; array.  Neither is there an early_cobbler_p predicate.
9402 ;; Also this optimization interferes with scalars going into
9403 ;; altivec registers (the code does reloading through the FPRs).
9404 (define_peephole2
9405   [(set (match_operand:DF 0 "gpc_reg_operand")
9406         (match_operand:DF 1 "any_operand"))
9407    (set (match_operand:DF 2 "gpc_reg_operand")
9408         (match_dup 0))]
9409   "!TARGET_VSX
9410    && peep2_reg_dead_p (2, operands[0])"
9411   [(set (match_dup 2) (match_dup 1))])
9413 (define_peephole2
9414   [(set (match_operand:SF 0 "gpc_reg_operand")
9415         (match_operand:SF 1 "any_operand"))
9416    (set (match_operand:SF 2 "gpc_reg_operand")
9417         (match_dup 0))]
9418   "!TARGET_P8_VECTOR
9419    && peep2_reg_dead_p (2, operands[0])"
9420   [(set (match_dup 2) (match_dup 1))])
9423 ;; TLS support.
9425 ;; Mode attributes for different ABIs.
9426 (define_mode_iterator TLSmode [(SI "! TARGET_64BIT") (DI "TARGET_64BIT")])
9427 (define_mode_attr tls_abi_suffix [(SI "32") (DI "64")])
9428 (define_mode_attr tls_sysv_suffix [(SI "si") (DI "di")])
9429 (define_mode_attr tls_insn_suffix [(SI "wz") (DI "d")])
9431 (define_insn_and_split "tls_gd_aix<TLSmode:tls_abi_suffix>"
9432   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9433         (call (mem:TLSmode (match_operand:TLSmode 3 "symbol_ref_operand" "s"))
9434               (match_operand 4 "" "g")))
9435    (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9436                     (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9437                    UNSPEC_TLSGD)
9438    (clobber (reg:SI LR_REGNO))]
9439   "HAVE_AS_TLS && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9441   if (TARGET_CMODEL != CMODEL_SMALL)
9442     output_asm_insn ("addis %0,%1,%2@got@tlsgd@ha\;"
9443                      "addi %0,%0,%2@got@tlsgd@l", operands);
9444   else
9445     output_asm_insn ("addi %0,%1,%2@got@tlsgd", operands);
9446   return rs6000_call_template (operands, 3, "");
9448   "&& TARGET_TLS_MARKERS"
9449   [(set (match_dup 0)
9450         (unspec:TLSmode [(match_dup 1)
9451                          (match_dup 2)]
9452                         UNSPEC_TLSGD))
9453    (parallel [(set (match_dup 0)
9454                    (call (mem:TLSmode (match_dup 3))
9455                          (match_dup 4)))
9456               (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGD)
9457               (clobber (reg:SI LR_REGNO))])]
9458   ""
9459   [(set_attr "type" "two")
9460    (set (attr "length")
9461      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9462                    (const_int 16)
9463                    (const_int 12)))])
9465 (define_insn_and_split "tls_gd_sysv<TLSmode:tls_sysv_suffix>"
9466   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9467         (call (mem:TLSmode (match_operand:TLSmode 3 "symbol_ref_operand" "s"))
9468               (match_operand 4 "" "g")))
9469    (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9470                     (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9471                    UNSPEC_TLSGD)
9472    (clobber (reg:SI LR_REGNO))]
9473   "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4"
9475   output_asm_insn ("addi %0,%1,%2@got@tlsgd", operands);
9476   return rs6000_call_template (operands, 3, "");
9478   "&& TARGET_TLS_MARKERS"
9479   [(set (match_dup 0)
9480         (unspec:TLSmode [(match_dup 1)
9481                          (match_dup 2)]
9482                         UNSPEC_TLSGD))
9483    (parallel [(set (match_dup 0)
9484                    (call (mem:TLSmode (match_dup 3))
9485                          (match_dup 4)))
9486               (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGD)
9487               (clobber (reg:SI LR_REGNO))])]
9488   ""
9489   [(set_attr "type" "two")
9490    (set_attr "length" "8")])
9492 (define_insn_and_split "*tls_gd<TLSmode:tls_abi_suffix>"
9493   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9494         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9495                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9496                         UNSPEC_TLSGD))]
9497   "HAVE_AS_TLS && TARGET_TLS_MARKERS"
9498   "addi %0,%1,%2@got@tlsgd"
9499   "&& TARGET_CMODEL != CMODEL_SMALL"
9500   [(set (match_dup 3)
9501         (high:TLSmode
9502             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))
9503    (set (match_dup 0)
9504         (lo_sum:TLSmode (match_dup 3)
9505             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))]
9507   operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9509   [(set (attr "length")
9510      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9511                    (const_int 8)
9512                    (const_int 4)))])
9514 (define_insn "*tls_gd_high<TLSmode:tls_abi_suffix>"
9515   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9516      (high:TLSmode
9517        (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9518                         (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9519                        UNSPEC_TLSGD)))]
9520   "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9521   "addis %0,%1,%2@got@tlsgd@ha")
9523 (define_insn "*tls_gd_low<TLSmode:tls_abi_suffix>"
9524   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9525      (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
9526        (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
9527                         (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9528                        UNSPEC_TLSGD)))]
9529   "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9530   "addi %0,%1,%2@got@tlsgd@l")
9532 (define_insn "*tls_gd_call_aix<TLSmode:tls_abi_suffix>"
9533   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9534         (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9535               (match_operand 2 "" "g")))
9536    (unspec:TLSmode [(match_operand:TLSmode 3 "rs6000_tls_symbol_ref" "")]
9537                    UNSPEC_TLSGD)
9538    (clobber (reg:SI LR_REGNO))]
9539   "HAVE_AS_TLS && TARGET_TLS_MARKERS
9540    && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9542   return rs6000_call_template (operands, 1, "(%3@tlsgd)");
9544   [(set_attr "type" "branch")
9545    (set_attr "length" "8")])
9547 (define_insn "*tls_gd_call_sysv<TLSmode:tls_abi_suffix>"
9548   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9549         (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9550               (match_operand 2 "" "g")))
9551    (unspec:TLSmode [(match_operand:TLSmode 3 "rs6000_tls_symbol_ref" "")]
9552                    UNSPEC_TLSGD)
9553    (clobber (reg:SI LR_REGNO))]
9554   "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4 && TARGET_TLS_MARKERS"
9556   return rs6000_call_template (operands, 1, "(%3@tlsgd)");
9558   [(set_attr "type" "branch")])
9560 (define_insn_and_split "tls_ld_aix<TLSmode:tls_abi_suffix>"
9561   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9562         (call (mem:TLSmode (match_operand:TLSmode 2 "symbol_ref_operand" "s"))
9563               (match_operand 3 "" "g")))
9564    (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9565                    UNSPEC_TLSLD)
9566    (clobber (reg:SI LR_REGNO))]
9567   "HAVE_AS_TLS && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9569   if (TARGET_CMODEL != CMODEL_SMALL)
9570     output_asm_insn ("addis %0,%1,%&@got@tlsld@ha\;"
9571                      "addi %0,%0,%&@got@tlsld@l", operands);
9572   else
9573     output_asm_insn ("addi %0,%1,%&@got@tlsld", operands);
9574   return rs6000_call_template (operands, 2, "");
9576   "&& TARGET_TLS_MARKERS"
9577   [(set (match_dup 0)
9578         (unspec:TLSmode [(match_dup 1)]
9579                         UNSPEC_TLSLD))
9580    (parallel [(set (match_dup 0)
9581                    (call (mem:TLSmode (match_dup 2))
9582                          (match_dup 3)))
9583               (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9584               (clobber (reg:SI LR_REGNO))])]
9585   ""
9586   [(set_attr "type" "two")
9587    (set (attr "length")
9588      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9589                    (const_int 16)
9590                    (const_int 12)))])
9592 (define_insn_and_split "tls_ld_sysv<TLSmode:tls_sysv_suffix>"
9593   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9594         (call (mem:TLSmode (match_operand:TLSmode 2 "symbol_ref_operand" "s"))
9595               (match_operand 3 "" "g")))
9596    (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9597                    UNSPEC_TLSLD)
9598    (clobber (reg:SI LR_REGNO))]
9599   "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4"
9601   output_asm_insn ("addi %0,%1,%&@got@tlsld", operands);
9602   return rs6000_call_template (operands, 2, "");
9604   "&& TARGET_TLS_MARKERS"
9605   [(set (match_dup 0)
9606         (unspec:TLSmode [(match_dup 1)]
9607                         UNSPEC_TLSLD))
9608    (parallel [(set (match_dup 0)
9609                    (call (mem:TLSmode (match_dup 2))
9610                          (match_dup 3)))
9611               (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9612               (clobber (reg:SI LR_REGNO))])]
9613   ""
9614   [(set_attr "length" "8")])
9616 (define_insn_and_split "*tls_ld<TLSmode:tls_abi_suffix>"
9617   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9618         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9619                         UNSPEC_TLSLD))]
9620   "HAVE_AS_TLS && TARGET_TLS_MARKERS"
9621   "addi %0,%1,%&@got@tlsld"
9622   "&& TARGET_CMODEL != CMODEL_SMALL"
9623   [(set (match_dup 2)
9624         (high:TLSmode
9625             (unspec:TLSmode [(const_int 0) (match_dup 1)] UNSPEC_TLSLD)))
9626    (set (match_dup 0)
9627         (lo_sum:TLSmode (match_dup 2)
9628             (unspec:TLSmode [(const_int 0) (match_dup 1)] UNSPEC_TLSLD)))]
9630   operands[2] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9632   [(set (attr "length")
9633      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9634                    (const_int 8)
9635                    (const_int 4)))])
9637 (define_insn "*tls_ld_high<TLSmode:tls_abi_suffix>"
9638   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9639      (high:TLSmode
9640        (unspec:TLSmode [(const_int 0)
9641                         (match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9642                        UNSPEC_TLSLD)))]
9643   "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9644   "addis %0,%1,%&@got@tlsld@ha")
9646 (define_insn "*tls_ld_low<TLSmode:tls_abi_suffix>"
9647   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9648      (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
9649        (unspec:TLSmode [(const_int 0)
9650                         (match_operand:TLSmode 2 "gpc_reg_operand" "b")]
9651                        UNSPEC_TLSLD)))]
9652   "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9653   "addi %0,%1,%&@got@tlsld@l")
9655 (define_insn "*tls_ld_call_aix<TLSmode:tls_abi_suffix>"
9656   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9657         (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9658               (match_operand 2 "" "g")))
9659    (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9660    (clobber (reg:SI LR_REGNO))]
9661   "HAVE_AS_TLS && TARGET_TLS_MARKERS
9662    && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9664   return rs6000_call_template (operands, 1, "(%&@tlsld)");
9666   [(set_attr "type" "branch")
9667    (set_attr "length" "8")])
9669 (define_insn "*tls_ld_call_sysv<TLSmode:tls_abi_suffix>"
9670   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9671         (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9672               (match_operand 2 "" "g")))
9673    (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9674    (clobber (reg:SI LR_REGNO))]
9675   "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4 && TARGET_TLS_MARKERS"
9677   return rs6000_call_template (operands, 1, "(%&@tlsld)");
9679   [(set_attr "type" "branch")])
9681 (define_insn "tls_dtprel_<TLSmode:tls_abi_suffix>"
9682   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9683         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9684                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9685                         UNSPEC_TLSDTPREL))]
9686   "HAVE_AS_TLS"
9687   "addi %0,%1,%2@dtprel")
9689 (define_insn "tls_dtprel_ha_<TLSmode:tls_abi_suffix>"
9690   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9691         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9692                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9693                         UNSPEC_TLSDTPRELHA))]
9694   "HAVE_AS_TLS"
9695   "addis %0,%1,%2@dtprel@ha")
9697 (define_insn "tls_dtprel_lo_<TLSmode:tls_abi_suffix>"
9698   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9699         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9700                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9701                         UNSPEC_TLSDTPRELLO))]
9702   "HAVE_AS_TLS"
9703   "addi %0,%1,%2@dtprel@l")
9705 (define_insn_and_split "tls_got_dtprel_<TLSmode:tls_abi_suffix>"
9706   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9707         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9708                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9709                         UNSPEC_TLSGOTDTPREL))]
9710   "HAVE_AS_TLS"
9711   "l<TLSmode:tls_insn_suffix> %0,%2@got@dtprel(%1)"
9712   "&& TARGET_CMODEL != CMODEL_SMALL"
9713   [(set (match_dup 3)
9714         (high:TLSmode
9715             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))
9716    (set (match_dup 0)
9717         (lo_sum:TLSmode (match_dup 3)
9718             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))]
9720   operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9722   [(set (attr "length")
9723      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9724                    (const_int 8)
9725                    (const_int 4)))])
9727 (define_insn "*tls_got_dtprel_high<TLSmode:tls_abi_suffix>"
9728   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9729      (high:TLSmode
9730        (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9731                         (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9732                        UNSPEC_TLSGOTDTPREL)))]
9733   "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9734   "addis %0,%1,%2@got@dtprel@ha")
9736 (define_insn "*tls_got_dtprel_low<TLSmode:tls_abi_suffix>"
9737   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9738      (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
9739          (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
9740                           (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9741                          UNSPEC_TLSGOTDTPREL)))]
9742   "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9743   "l<TLSmode:tls_insn_suffix> %0,%2@got@dtprel@l(%1)")
9745 (define_insn "tls_tprel_<TLSmode:tls_abi_suffix>"
9746   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9747         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9748                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9749                         UNSPEC_TLSTPREL))]
9750   "HAVE_AS_TLS"
9751   "addi %0,%1,%2@tprel")
9753 (define_insn "tls_tprel_ha_<TLSmode:tls_abi_suffix>"
9754   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9755         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9756                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9757                         UNSPEC_TLSTPRELHA))]
9758   "HAVE_AS_TLS"
9759   "addis %0,%1,%2@tprel@ha")
9761 (define_insn "tls_tprel_lo_<TLSmode:tls_abi_suffix>"
9762   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9763         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9764                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9765                         UNSPEC_TLSTPRELLO))]
9766   "HAVE_AS_TLS"
9767   "addi %0,%1,%2@tprel@l")
9769 ;; "b" output constraint here and on tls_tls input to support linker tls
9770 ;; optimization.  The linker may edit the instructions emitted by a
9771 ;; tls_got_tprel/tls_tls pair to addis,addi.
9772 (define_insn_and_split "tls_got_tprel_<TLSmode:tls_abi_suffix>"
9773   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9774         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9775                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9776                         UNSPEC_TLSGOTTPREL))]
9777   "HAVE_AS_TLS"
9778   "l<TLSmode:tls_insn_suffix> %0,%2@got@tprel(%1)"
9779   "&& TARGET_CMODEL != CMODEL_SMALL"
9780   [(set (match_dup 3)
9781         (high:TLSmode
9782             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))
9783    (set (match_dup 0)
9784         (lo_sum:TLSmode (match_dup 3)
9785             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))]
9787   operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9789   [(set (attr "length")
9790      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9791                    (const_int 8)
9792                    (const_int 4)))])
9794 (define_insn "*tls_got_tprel_high<TLSmode:tls_abi_suffix>"
9795   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9796      (high:TLSmode
9797        (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9798                         (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9799                        UNSPEC_TLSGOTTPREL)))]
9800   "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9801   "addis %0,%1,%2@got@tprel@ha")
9803 (define_insn "*tls_got_tprel_low<TLSmode:tls_abi_suffix>"
9804   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9805      (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
9806          (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
9807                           (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9808                          UNSPEC_TLSGOTTPREL)))]
9809   "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9810   "l<TLSmode:tls_insn_suffix> %0,%2@got@tprel@l(%1)")
9812 (define_insn "tls_tls_<TLSmode:tls_abi_suffix>"
9813   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9814         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9815                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9816                         UNSPEC_TLSTLS))]
9817   "TARGET_ELF && HAVE_AS_TLS"
9818   "add %0,%1,%2@tls")
9820 (define_expand "tls_get_tpointer"
9821   [(set (match_operand:SI 0 "gpc_reg_operand")
9822         (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))]
9823   "TARGET_XCOFF && HAVE_AS_TLS"
9825   emit_insn (gen_tls_get_tpointer_internal ());
9826   emit_move_insn (operands[0], gen_rtx_REG (SImode, 3));
9827   DONE;
9830 (define_insn "tls_get_tpointer_internal"
9831   [(set (reg:SI 3)
9832         (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))
9833    (clobber (reg:SI LR_REGNO))]
9834   "TARGET_XCOFF && HAVE_AS_TLS"
9835   "bla __get_tpointer")
9837 (define_expand "tls_get_addr<mode>"
9838   [(set (match_operand:P 0 "gpc_reg_operand")
9839         (unspec:P [(match_operand:P 1 "gpc_reg_operand")
9840                    (match_operand:P 2 "gpc_reg_operand")] UNSPEC_TLSTLS))]
9841   "TARGET_XCOFF && HAVE_AS_TLS"
9843   emit_move_insn (gen_rtx_REG (Pmode, 3), operands[1]);
9844   emit_move_insn (gen_rtx_REG (Pmode, 4), operands[2]);
9845   emit_insn (gen_tls_get_addr_internal<mode> ());
9846   emit_move_insn (operands[0], gen_rtx_REG (Pmode, 3));
9847   DONE;
9850 (define_insn "tls_get_addr_internal<mode>"
9851   [(set (reg:P 3)
9852         (unspec:P [(reg:P 3) (reg:P 4)] UNSPEC_TLSTLS))
9853    (clobber (reg:P 0))
9854    (clobber (reg:P 4))
9855    (clobber (reg:P 5))
9856    (clobber (reg:P 11))
9857    (clobber (reg:CC CR0_REGNO))
9858    (clobber (reg:P LR_REGNO))]
9859   "TARGET_XCOFF && HAVE_AS_TLS"
9860   "bla __tls_get_addr")
9862 ;; Next come insns related to the calling sequence.
9864 ;; First, an insn to allocate new stack space for dynamic use (e.g., alloca).
9865 ;; We move the back-chain and decrement the stack pointer.
9867 ;; Operand1 is more naturally reg_or_short_operand.  However, for a large
9868 ;; constant alloca, using that predicate will force the generic code to put
9869 ;; the constant size into a register before calling the expander.
9871 ;; As a result the expander would not have the constant size information
9872 ;; in those cases and would have to generate less efficient code.
9874 ;; Thus we allow reg_or_cint_operand instead so that the expander can see
9875 ;; the constant size.  The value is forced into a register if necessary.
9877 (define_expand "allocate_stack"
9878   [(set (match_operand 0 "gpc_reg_operand")
9879         (minus (reg 1) (match_operand 1 "reg_or_cint_operand")))
9880    (set (reg 1)
9881         (minus (reg 1) (match_dup 1)))]
9882   ""
9884   rtx chain = gen_reg_rtx (Pmode);
9885   rtx stack_bot = gen_rtx_MEM (Pmode, stack_pointer_rtx);
9886   rtx neg_op0;
9887   rtx insn, par, set, mem;
9889   /* By allowing reg_or_cint_operand as the predicate we can get
9890      better code for stack-clash-protection because we do not lose
9891      size information.  But the rest of the code expects the operand
9892      to be reg_or_short_operand.  If it isn't, then force it into
9893      a register.  */
9894   rtx orig_op1 = operands[1];
9895   if (!reg_or_short_operand (operands[1], Pmode))
9896     operands[1] = force_reg (Pmode, operands[1]);
9898   emit_move_insn (chain, stack_bot);
9900   /* Check stack bounds if necessary.  */
9901   if (crtl->limit_stack)
9902     {
9903       rtx available;
9904       available = expand_binop (Pmode, sub_optab,
9905                                 stack_pointer_rtx, stack_limit_rtx,
9906                                 NULL_RTX, 1, OPTAB_WIDEN);
9907       emit_insn (gen_cond_trap (LTU, available, operands[1], const0_rtx));
9908     }
9910   /* Allocate and probe if requested.
9911      This may look similar to the loop we use for prologue allocations,
9912      but it is critically different.  For the former we know the loop
9913      will iterate, but do not know that generally here.  The former
9914      uses that knowledge to rotate the loop.  Combining them would be
9915      possible with some performance cost.  */
9916   if (flag_stack_clash_protection)
9917     {
9918       rtx rounded_size, last_addr, residual;
9919       HOST_WIDE_INT probe_interval;
9920       compute_stack_clash_protection_loop_data (&rounded_size, &last_addr,
9921                                                 &residual, &probe_interval,
9922                                                 orig_op1);
9923       
9924       /* We do occasionally get in here with constant sizes, we might
9925          as well do a reasonable job when we obviously can.  */
9926       if (rounded_size != const0_rtx)
9927         {
9928           rtx loop_lab, end_loop;
9929           bool rotated = CONST_INT_P (rounded_size);
9930           rtx update = GEN_INT (-probe_interval);
9931           if (probe_interval > 32768)
9932             update = force_reg (Pmode, update);
9934           emit_stack_clash_protection_probe_loop_start (&loop_lab, &end_loop,
9935                                                         last_addr, rotated);
9937           if (Pmode == SImode)
9938             emit_insn (gen_movsi_update_stack (stack_pointer_rtx,
9939                                                stack_pointer_rtx,
9940                                                update, chain));
9941           else
9942             emit_insn (gen_movdi_di_update_stack (stack_pointer_rtx,
9943                                                   stack_pointer_rtx,
9944                                                   update, chain));
9945           emit_stack_clash_protection_probe_loop_end (loop_lab, end_loop,
9946                                                       last_addr, rotated);
9947         }
9949       /* Now handle residuals.  We just have to set operands[1] correctly
9950          and let the rest of the expander run.  */
9951       operands[1] = residual;
9952     }
9954   if (!(CONST_INT_P (operands[1])
9955         && IN_RANGE (INTVAL (operands[1]), -32767, 32768)))
9956     {
9957       operands[1] = force_reg (Pmode, operands[1]);
9958       neg_op0 = gen_reg_rtx (Pmode);
9959       if (TARGET_32BIT)
9960         emit_insn (gen_negsi2 (neg_op0, operands[1]));
9961       else
9962         emit_insn (gen_negdi2 (neg_op0, operands[1]));
9963     }
9964   else
9965     neg_op0 = GEN_INT (-INTVAL (operands[1]));
9967   insn = emit_insn ((* ((TARGET_32BIT) ? gen_movsi_update_stack
9968                                        : gen_movdi_di_update_stack))
9969                         (stack_pointer_rtx, stack_pointer_rtx, neg_op0,
9970                          chain));
9971   /* Since we didn't use gen_frame_mem to generate the MEM, grab
9972      it now and set the alias set/attributes. The above gen_*_update
9973      calls will generate a PARALLEL with the MEM set being the first
9974      operation. */
9975   par = PATTERN (insn);
9976   gcc_assert (GET_CODE (par) == PARALLEL);
9977   set = XVECEXP (par, 0, 0);
9978   gcc_assert (GET_CODE (set) == SET);
9979   mem = SET_DEST (set);
9980   gcc_assert (MEM_P (mem));
9981   MEM_NOTRAP_P (mem) = 1;
9982   set_mem_alias_set (mem, get_frame_alias_set ());
9984   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
9985   DONE;
9988 ;; These patterns say how to save and restore the stack pointer.  We need not
9989 ;; save the stack pointer at function level since we are careful to
9990 ;; preserve the backchain.  At block level, we have to restore the backchain
9991 ;; when we restore the stack pointer.
9993 ;; For nonlocal gotos, we must save both the stack pointer and its
9994 ;; backchain and restore both.  Note that in the nonlocal case, the
9995 ;; save area is a memory location.
9997 (define_expand "save_stack_function"
9998   [(match_operand 0 "any_operand")
9999    (match_operand 1 "any_operand")]
10000   ""
10001   "DONE;")
10003 (define_expand "restore_stack_function"
10004   [(match_operand 0 "any_operand")
10005    (match_operand 1 "any_operand")]
10006   ""
10007   "DONE;")
10009 ;; Adjust stack pointer (op0) to a new value (op1).
10010 ;; First copy old stack backchain to new location, and ensure that the
10011 ;; scheduler won't reorder the sp assignment before the backchain write.
10012 (define_expand "restore_stack_block"
10013   [(set (match_dup 2) (match_dup 3))
10014    (set (match_dup 4) (match_dup 2))
10015    (match_dup 5)
10016    (set (match_operand 0 "register_operand")
10017         (match_operand 1 "register_operand"))]
10018   ""
10020   rtvec p;
10022   operands[1] = force_reg (Pmode, operands[1]);
10023   operands[2] = gen_reg_rtx (Pmode);
10024   operands[3] = gen_frame_mem (Pmode, operands[0]);
10025   operands[4] = gen_frame_mem (Pmode, operands[1]);
10026   p = rtvec_alloc (1);
10027   RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
10028                                   const0_rtx);
10029   operands[5] = gen_rtx_PARALLEL (VOIDmode, p);
10032 (define_expand "save_stack_nonlocal"
10033   [(set (match_dup 3) (match_dup 4))
10034    (set (match_operand 0 "memory_operand") (match_dup 3))
10035    (set (match_dup 2) (match_operand 1 "register_operand"))]
10036   ""
10038   int units_per_word = (TARGET_32BIT) ? 4 : 8;
10040   /* Copy the backchain to the first word, sp to the second.  */
10041   operands[0] = adjust_address_nv (operands[0], Pmode, 0);
10042   operands[2] = adjust_address_nv (operands[0], Pmode, units_per_word);
10043   operands[3] = gen_reg_rtx (Pmode);
10044   operands[4] = gen_frame_mem (Pmode, operands[1]);
10047 (define_expand "restore_stack_nonlocal"
10048   [(set (match_dup 2) (match_operand 1 "memory_operand"))
10049    (set (match_dup 3) (match_dup 4))
10050    (set (match_dup 5) (match_dup 2))
10051    (match_dup 6)
10052    (set (match_operand 0 "register_operand") (match_dup 3))]
10053   ""
10055   int units_per_word = (TARGET_32BIT) ? 4 : 8;
10056   rtvec p;
10058   /* Restore the backchain from the first word, sp from the second.  */
10059   operands[2] = gen_reg_rtx (Pmode);
10060   operands[3] = gen_reg_rtx (Pmode);
10061   operands[1] = adjust_address_nv (operands[1], Pmode, 0);
10062   operands[4] = adjust_address_nv (operands[1], Pmode, units_per_word);
10063   operands[5] = gen_frame_mem (Pmode, operands[3]);
10064   p = rtvec_alloc (1);
10065   RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
10066                                   const0_rtx);
10067   operands[6] = gen_rtx_PARALLEL (VOIDmode, p);
10070 ;; TOC register handling.
10072 ;; Code to initialize the TOC register...
10074 (define_insn "load_toc_aix_si"
10075   [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10076                    (unspec:SI [(const_int 0)] UNSPEC_TOC))
10077               (use (reg:SI 2))])]
10078   "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_32BIT"
10080   char buf[30];
10081   extern int need_toc_init;
10082   need_toc_init = 1;
10083   ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
10084   operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
10085   operands[2] = gen_rtx_REG (Pmode, 2);
10086   return "lwz %0,%1(%2)";
10088   [(set_attr "type" "load")
10089    (set_attr "update" "no")
10090    (set_attr "indexed" "no")])
10092 (define_insn "load_toc_aix_di"
10093   [(parallel [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
10094                    (unspec:DI [(const_int 0)] UNSPEC_TOC))
10095               (use (reg:DI 2))])]
10096   "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_64BIT"
10098   char buf[30];
10099   extern int need_toc_init;
10100   need_toc_init = 1;
10101   ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC",
10102                                !TARGET_ELF || !TARGET_MINIMAL_TOC);
10103   if (TARGET_ELF)
10104     strcat (buf, "@toc");
10105   operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
10106   operands[2] = gen_rtx_REG (Pmode, 2);
10107   return "ld %0,%1(%2)";
10109   [(set_attr "type" "load")
10110    (set_attr "update" "no")
10111    (set_attr "indexed" "no")])
10113 (define_insn "load_toc_v4_pic_si"
10114   [(set (reg:SI LR_REGNO)
10115         (unspec:SI [(const_int 0)] UNSPEC_TOC))]
10116   "DEFAULT_ABI == ABI_V4 && flag_pic == 1 && TARGET_32BIT"
10117   "bl _GLOBAL_OFFSET_TABLE_@local-4"
10118   [(set_attr "type" "branch")])
10120 (define_expand "load_toc_v4_PIC_1"
10121   [(parallel [(set (reg:SI LR_REGNO)
10122                    (match_operand:SI 0 "immediate_operand" "s"))
10123               (use (unspec [(match_dup 0)] UNSPEC_TOC))])]
10124   "TARGET_ELF && DEFAULT_ABI == ABI_V4
10125    && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10126   "")
10128 (define_insn "load_toc_v4_PIC_1_normal"
10129   [(set (reg:SI LR_REGNO)
10130         (match_operand:SI 0 "immediate_operand" "s"))
10131    (use (unspec [(match_dup 0)] UNSPEC_TOC))]
10132   "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
10133    && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10134   "bcl 20,31,%0\n%0:"
10135   [(set_attr "type" "branch")
10136    (set_attr "cannot_copy" "yes")])
10138 (define_insn "load_toc_v4_PIC_1_476"
10139   [(set (reg:SI LR_REGNO)
10140         (match_operand:SI 0 "immediate_operand" "s"))
10141    (use (unspec [(match_dup 0)] UNSPEC_TOC))]
10142   "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
10143    && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10145   char name[32];
10146   static char templ[32];
10148   get_ppc476_thunk_name (name);
10149   sprintf (templ, "bl %s\n%%0:", name);
10150   return templ;
10152   [(set_attr "type" "branch")
10153    (set_attr "cannot_copy" "yes")])
10155 (define_expand "load_toc_v4_PIC_1b"
10156   [(parallel [(set (reg:SI LR_REGNO)
10157                    (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10158                                (label_ref (match_operand 1 ""))]
10159                            UNSPEC_TOCPTR))
10160               (match_dup 1)])]
10161   "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10162   "")
10164 (define_insn "load_toc_v4_PIC_1b_normal"
10165   [(set (reg:SI LR_REGNO)
10166         (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10167                     (label_ref (match_operand 1 "" ""))]
10168                 UNSPEC_TOCPTR))
10169    (match_dup 1)]
10170   "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10171   "bcl 20,31,$+8\;.long %0-$"
10172   [(set_attr "type" "branch")
10173    (set_attr "length" "8")])
10175 (define_insn "load_toc_v4_PIC_1b_476"
10176   [(set (reg:SI LR_REGNO)
10177         (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10178                     (label_ref (match_operand 1 "" ""))]
10179                 UNSPEC_TOCPTR))
10180    (match_dup 1)]
10181   "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10183   char name[32];
10184   static char templ[32];
10186   get_ppc476_thunk_name (name);
10187   sprintf (templ, "bl %s\;b $+8\;.long %%0-$", name);
10188   return templ;
10190   [(set_attr "type" "branch")
10191    (set_attr "length" "16")])
10193 (define_insn "load_toc_v4_PIC_2"
10194   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10195         (mem:SI (plus:SI
10196                   (match_operand:SI 1 "gpc_reg_operand" "b")
10197                   (const
10198                     (minus:SI (match_operand:SI 2 "immediate_operand" "s")
10199                               (match_operand:SI 3 "immediate_operand" "s"))))))]
10200   "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10201   "lwz %0,%2-%3(%1)"
10202   [(set_attr "type" "load")])
10204 (define_insn "load_toc_v4_PIC_3b"
10205   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10206         (plus:SI
10207           (match_operand:SI 1 "gpc_reg_operand" "b")
10208           (high:SI
10209             (const
10210               (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
10211                         (match_operand:SI 3 "symbol_ref_operand" "s"))))))]
10212   "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
10213   "addis %0,%1,%2-%3@ha")
10215 (define_insn "load_toc_v4_PIC_3c"
10216   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10217         (lo_sum:SI
10218           (match_operand:SI 1 "gpc_reg_operand" "b")
10219           (const
10220             (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
10221                       (match_operand:SI 3 "symbol_ref_operand" "s")))))]
10222   "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
10223   "addi %0,%1,%2-%3@l")
10225 ;; If the TOC is shared over a translation unit, as happens with all
10226 ;; the kinds of PIC that we support, we need to restore the TOC
10227 ;; pointer only when jumping over units of translation.
10228 ;; On Darwin, we need to reload the picbase.
10230 (define_expand "builtin_setjmp_receiver"
10231   [(use (label_ref (match_operand 0 "")))]
10232   "(DEFAULT_ABI == ABI_V4 && flag_pic == 1)
10233    || (TARGET_TOC && TARGET_MINIMAL_TOC)
10234    || (DEFAULT_ABI == ABI_DARWIN && flag_pic)"
10236 #if TARGET_MACHO
10237   if (DEFAULT_ABI == ABI_DARWIN)
10238     {
10239       rtx picrtx = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME);
10240       rtx picreg = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
10241       rtx tmplabrtx;
10242       char tmplab[20];
10244       crtl->uses_pic_offset_table = 1;
10245       ASM_GENERATE_INTERNAL_LABEL(tmplab, "LSJR",
10246                                   CODE_LABEL_NUMBER (operands[0]));
10247       tmplabrtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (tmplab));
10249       emit_insn (gen_load_macho_picbase (tmplabrtx));
10250       emit_move_insn (picreg, gen_rtx_REG (Pmode, LR_REGNO));
10251       emit_insn (gen_macho_correct_pic (picreg, picreg, picrtx, tmplabrtx));
10252     }
10253   else
10254 #endif
10255     rs6000_emit_load_toc_table (FALSE);
10256   DONE;
10259 ;; Largetoc support
10260 (define_insn "*largetoc_high"
10261   [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
10262         (high:DI
10263           (unspec [(match_operand:DI 1 "" "")
10264                    (match_operand:DI 2 "gpc_reg_operand" "b")]
10265                   UNSPEC_TOCREL)))]
10266    "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10267    "addis %0,%2,%1@toc@ha")
10269 (define_insn "*largetoc_high_aix<mode>"
10270   [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
10271         (high:P
10272           (unspec [(match_operand:P 1 "" "")
10273                    (match_operand:P 2 "gpc_reg_operand" "b")]
10274                   UNSPEC_TOCREL)))]
10275    "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10276    "addis %0,%1@u(%2)")
10278 (define_insn "*largetoc_high_plus"
10279   [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
10280         (high:DI
10281           (plus:DI
10282             (unspec [(match_operand:DI 1 "" "")
10283                      (match_operand:DI 2 "gpc_reg_operand" "b")]
10284                     UNSPEC_TOCREL)
10285             (match_operand:DI 3 "add_cint_operand" "n"))))]
10286    "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10287    "addis %0,%2,%1+%3@toc@ha")
10289 (define_insn "*largetoc_high_plus_aix<mode>"
10290   [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
10291         (high:P
10292           (plus:P
10293             (unspec [(match_operand:P 1 "" "")
10294                      (match_operand:P 2 "gpc_reg_operand" "b")]
10295                     UNSPEC_TOCREL)
10296             (match_operand:P 3 "add_cint_operand" "n"))))]
10297    "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10298    "addis %0,%1+%3@u(%2)")
10300 (define_insn "*largetoc_low"
10301   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
10302         (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b")
10303                    (match_operand:DI 2 "" "")))]
10304    "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10305    "addi %0,%1,%2@l")
10307 (define_insn "*largetoc_low_aix<mode>"
10308   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10309         (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
10310                    (match_operand:P 2 "" "")))]
10311    "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10312    "la %0,%2@l(%1)")
10314 (define_insn_and_split "*tocref<mode>"
10315   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
10316         (match_operand:P 1 "small_toc_ref" "R"))]
10317    "TARGET_TOC"
10318    "la %0,%a1"
10319    "&& TARGET_CMODEL != CMODEL_SMALL && reload_completed"
10320   [(set (match_dup 0) (high:P (match_dup 1)))
10321    (set (match_dup 0) (lo_sum:P (match_dup 0) (match_dup 1)))])
10323 ;; Elf specific ways of loading addresses for non-PIC code.
10324 ;; The output of this could be r0, but we make a very strong
10325 ;; preference for a base register because it will usually
10326 ;; be needed there.
10327 (define_insn "elf_high"
10328   [(set (match_operand:SI 0 "gpc_reg_operand" "=b*r")
10329         (high:SI (match_operand 1 "" "")))]
10330   "TARGET_ELF && !TARGET_64BIT && !flag_pic"
10331   "lis %0,%1@ha")
10333 (define_insn "elf_low"
10334   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10335         (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
10336                    (match_operand 2 "" "")))]
10337    "TARGET_ELF && !TARGET_64BIT && !flag_pic"
10338    "la %0,%2@l(%1)")
10340 ;; Call and call_value insns
10341 (define_expand "call"
10342   [(parallel [(call (mem:SI (match_operand 0 "address_operand"))
10343                     (match_operand 1 ""))
10344               (use (match_operand 2 ""))
10345               (clobber (reg:SI LR_REGNO))])]
10346   ""
10348 #if TARGET_MACHO
10349   if (MACHOPIC_INDIRECT)
10350     operands[0] = machopic_indirect_call_target (operands[0]);
10351 #endif
10353   gcc_assert (GET_CODE (operands[0]) == MEM);
10354   gcc_assert (GET_CODE (operands[1]) == CONST_INT);
10356   operands[0] = XEXP (operands[0], 0);
10358   if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10359     {
10360       rs6000_call_aix (NULL_RTX, operands[0], operands[1], operands[2]);
10361       DONE;
10362     }
10364   if (GET_CODE (operands[0]) != SYMBOL_REF
10365       || (DEFAULT_ABI != ABI_DARWIN && (INTVAL (operands[2]) & CALL_LONG) != 0))
10366     {
10367       if (INTVAL (operands[2]) & CALL_LONG)
10368         operands[0] = rs6000_longcall_ref (operands[0]);
10370       switch (DEFAULT_ABI)
10371         {
10372         case ABI_V4:
10373         case ABI_DARWIN:
10374           operands[0] = force_reg (Pmode, operands[0]);
10375           break;
10377         default:
10378           gcc_unreachable ();
10379         }
10380     }
10383 (define_expand "call_value"
10384   [(parallel [(set (match_operand 0 "")
10385                    (call (mem:SI (match_operand 1 "address_operand"))
10386                          (match_operand 2 "")))
10387               (use (match_operand 3 ""))
10388               (clobber (reg:SI LR_REGNO))])]
10389   ""
10391 #if TARGET_MACHO
10392   if (MACHOPIC_INDIRECT)
10393     operands[1] = machopic_indirect_call_target (operands[1]);
10394 #endif
10396   gcc_assert (GET_CODE (operands[1]) == MEM);
10397   gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10399   operands[1] = XEXP (operands[1], 0);
10401   if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10402     {
10403       rs6000_call_aix (operands[0], operands[1], operands[2], operands[3]);
10404       DONE;
10405     }
10407   if (GET_CODE (operands[1]) != SYMBOL_REF
10408       || (DEFAULT_ABI != ABI_DARWIN && (INTVAL (operands[3]) & CALL_LONG) != 0))
10409     {
10410       if (INTVAL (operands[3]) & CALL_LONG)
10411         operands[1] = rs6000_longcall_ref (operands[1]);
10413       switch (DEFAULT_ABI)
10414         {
10415         case ABI_V4:
10416         case ABI_DARWIN:
10417           operands[1] = force_reg (Pmode, operands[1]);
10418           break;
10420         default:
10421           gcc_unreachable ();
10422         }
10423     }
10426 ;; Call to function in current module.  No TOC pointer reload needed.
10427 ;; Operand2 is nonzero if we are using the V.4 calling sequence and
10428 ;; either the function was not prototyped, or it was prototyped as a
10429 ;; variable argument function.  It is > 0 if FP registers were passed
10430 ;; and < 0 if they were not.
10432 (define_insn "*call_local32"
10433   [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
10434          (match_operand 1 "" "g,g"))
10435    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10436    (clobber (reg:SI LR_REGNO))]
10437   "(INTVAL (operands[2]) & CALL_LONG) == 0"
10439   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10440     output_asm_insn ("crxor 6,6,6", operands);
10442   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10443     output_asm_insn ("creqv 6,6,6", operands);
10445   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z0@local" : "bl %z0";
10447   [(set_attr "type" "branch")
10448    (set_attr "length" "4,8")])
10450 (define_insn "*call_local64"
10451   [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
10452          (match_operand 1 "" "g,g"))
10453    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10454    (clobber (reg:SI LR_REGNO))]
10455   "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
10457   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10458     output_asm_insn ("crxor 6,6,6", operands);
10460   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10461     output_asm_insn ("creqv 6,6,6", operands);
10463   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z0@local" : "bl %z0";
10465   [(set_attr "type" "branch")
10466    (set_attr "length" "4,8")])
10468 (define_insn "*call_value_local32"
10469   [(set (match_operand 0 "" "")
10470         (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
10471               (match_operand 2 "" "g,g")))
10472    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10473    (clobber (reg:SI LR_REGNO))]
10474   "(INTVAL (operands[3]) & CALL_LONG) == 0"
10476   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10477     output_asm_insn ("crxor 6,6,6", operands);
10479   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10480     output_asm_insn ("creqv 6,6,6", operands);
10482   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z1@local" : "bl %z1";
10484   [(set_attr "type" "branch")
10485    (set_attr "length" "4,8")])
10488 (define_insn "*call_value_local64"
10489   [(set (match_operand 0 "" "")
10490         (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
10491               (match_operand 2 "" "g,g")))
10492    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10493    (clobber (reg:SI LR_REGNO))]
10494   "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
10496   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10497     output_asm_insn ("crxor 6,6,6", operands);
10499   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10500     output_asm_insn ("creqv 6,6,6", operands);
10502   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z1@local" : "bl %z1";
10504   [(set_attr "type" "branch")
10505    (set_attr "length" "4,8")])
10508 ;; A function pointer under System V is just a normal pointer
10509 ;; operands[0] is the function pointer
10510 ;; operands[1] is the stack size to clean up
10511 ;; operands[2] is the value FUNCTION_ARG returns for the VOID argument
10512 ;; which indicates how to set cr1
10514 (define_insn "*call_indirect_nonlocal_sysv<mode>"
10515   [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l,c,*l"))
10516          (match_operand 1 "" "g,g,g,g"))
10517    (use (match_operand:SI 2 "immediate_operand" "O,O,n,n"))
10518    (clobber (reg:SI LR_REGNO))]
10519   "DEFAULT_ABI == ABI_V4
10520    || DEFAULT_ABI == ABI_DARWIN"
10522   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10523     output_asm_insn ("crxor 6,6,6", operands);
10525   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10526     output_asm_insn ("creqv 6,6,6", operands);
10528   if (rs6000_speculate_indirect_jumps
10529       || which_alternative == 1 || which_alternative == 3)
10530     return "b%T0l";
10531   else
10532     return "crset 2\;beq%T0l-";
10534   [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg")
10535    (set_attr_alternative "length"
10536      [(if_then_else (eq (symbol_ref "rs6000_speculate_indirect_jumps")
10537                         (const_int 0))
10538                     (const_string "8")
10539                     (const_string "4"))
10540       (const_string "4")
10541       (if_then_else (eq (symbol_ref "rs6000_speculate_indirect_jumps")
10542                         (const_int 0))
10543                     (const_string "12")
10544                     (const_string "8"))
10545       (const_string "8")])])
10547 (define_insn_and_split "*call_nonlocal_sysv<mode>"
10548   [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
10549          (match_operand 1 "" "g,g"))
10550    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10551    (clobber (reg:SI LR_REGNO))]
10552   "(DEFAULT_ABI == ABI_DARWIN
10553    || (DEFAULT_ABI == ABI_V4
10554        && (INTVAL (operands[2]) & CALL_LONG) == 0))"
10556   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10557     output_asm_insn ("crxor 6,6,6", operands);
10559   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10560     output_asm_insn ("creqv 6,6,6", operands);
10562 #if TARGET_MACHO
10563   return macho_call_template (insn, operands, 0, 2);
10564 #else
10565   return rs6000_call_template (operands, 0, "");
10566 #endif
10568   "DEFAULT_ABI == ABI_V4
10569    && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0])
10570    && (INTVAL (operands[2]) & CALL_LONG) == 0"
10571   [(parallel [(call (mem:SI (match_dup 0))
10572                     (match_dup 1))
10573               (use (match_dup 2))
10574               (use (match_dup 3))
10575               (clobber (reg:SI LR_REGNO))])]
10577   operands[3] = pic_offset_table_rtx;
10579   [(set_attr "type" "branch,branch")
10580    (set_attr "length" "4,8")])
10582 (define_insn "*call_nonlocal_sysv_secure<mode>"
10583   [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
10584          (match_operand 1 "" "g,g"))
10585    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10586    (use (match_operand:SI 3 "register_operand" "r,r"))
10587    (clobber (reg:SI LR_REGNO))]
10588   "(DEFAULT_ABI == ABI_V4
10589     && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0])
10590     && (INTVAL (operands[2]) & CALL_LONG) == 0)"
10592   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10593     output_asm_insn ("crxor 6,6,6", operands);
10595   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10596     output_asm_insn ("creqv 6,6,6", operands);
10598   return rs6000_call_template (operands, 0, "");
10600   [(set_attr "type" "branch,branch")
10601    (set_attr "length" "4,8")])
10603 (define_insn "*call_value_indirect_nonlocal_sysv<mode>"
10604   [(set (match_operand 0 "" "")
10605         (call (mem:SI (match_operand:P 1 "register_operand" "c,*l,c,*l"))
10606               (match_operand 2 "" "g,g,g,g")))
10607    (use (match_operand:SI 3 "immediate_operand" "O,O,n,n"))
10608    (clobber (reg:SI LR_REGNO))]
10609   "DEFAULT_ABI == ABI_V4
10610    || DEFAULT_ABI == ABI_DARWIN"
10612   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10613     output_asm_insn ("crxor 6,6,6", operands);
10615   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10616     output_asm_insn ("creqv 6,6,6", operands);
10618   if (rs6000_speculate_indirect_jumps
10619       || which_alternative == 1 || which_alternative == 3)
10620     return "b%T1l";
10621   else
10622     return "crset 2\;beq%T1l-";
10624   [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg")
10625    (set_attr_alternative "length"
10626      [(if_then_else (eq (symbol_ref "rs6000_speculate_indirect_jumps")
10627                         (const_int 0))
10628                     (const_string "8")
10629                     (const_string "4"))
10630       (const_string "4")
10631       (if_then_else (eq (symbol_ref "rs6000_speculate_indirect_jumps")
10632                         (const_int 0))
10633                     (const_string "12")
10634                     (const_string "8"))
10635       (const_string "8")])])
10637 (define_insn_and_split "*call_value_nonlocal_sysv<mode>"
10638   [(set (match_operand 0 "" "")
10639         (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
10640               (match_operand 2 "" "g,g")))
10641    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10642    (clobber (reg:SI LR_REGNO))]
10643   "(DEFAULT_ABI == ABI_DARWIN
10644    || (DEFAULT_ABI == ABI_V4
10645        && (INTVAL (operands[3]) & CALL_LONG) == 0))"
10647   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10648     output_asm_insn ("crxor 6,6,6", operands);
10650   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10651     output_asm_insn ("creqv 6,6,6", operands);
10653 #if TARGET_MACHO
10654   return macho_call_template (insn, operands, 1, 3);
10655 #else
10656   return rs6000_call_template (operands, 1, "");
10657 #endif
10659   "DEFAULT_ABI == ABI_V4
10660    && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1])
10661    && (INTVAL (operands[3]) & CALL_LONG) == 0"
10662   [(parallel [(set (match_dup 0)
10663                    (call (mem:SI (match_dup 1))
10664                          (match_dup 2)))
10665               (use (match_dup 3))
10666               (use (match_dup 4))
10667               (clobber (reg:SI LR_REGNO))])]
10669   operands[4] = pic_offset_table_rtx;
10671   [(set_attr "type" "branch,branch")
10672    (set_attr "length" "4,8")])
10674 (define_insn "*call_value_nonlocal_sysv_secure<mode>"
10675   [(set (match_operand 0 "" "")
10676         (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
10677               (match_operand 2 "" "g,g")))
10678    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10679    (use (match_operand:SI 4 "register_operand" "r,r"))
10680    (clobber (reg:SI LR_REGNO))]
10681   "(DEFAULT_ABI == ABI_V4
10682     && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1])
10683     && (INTVAL (operands[3]) & CALL_LONG) == 0)"
10685   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10686     output_asm_insn ("crxor 6,6,6", operands);
10688   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10689     output_asm_insn ("creqv 6,6,6", operands);
10691   return rs6000_call_template (operands, 1, "");
10693   [(set_attr "type" "branch,branch")
10694    (set_attr "length" "4,8")])
10697 ;; Call to AIX abi function in the same module.
10699 (define_insn "*call_local_aix<mode>"
10700   [(call (mem:SI (match_operand:P 0 "current_file_function_operand" "s"))
10701          (match_operand 1 "" "g"))
10702    (clobber (reg:P LR_REGNO))]
10703   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10704   "bl %z0"
10705   [(set_attr "type" "branch")])
10707 (define_insn "*call_value_local_aix<mode>"
10708   [(set (match_operand 0 "" "")
10709         (call (mem:SI (match_operand:P 1 "current_file_function_operand" "s"))
10710               (match_operand 2 "" "g")))
10711    (clobber (reg:P LR_REGNO))]
10712   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10713   "bl %z1"
10714   [(set_attr "type" "branch")])
10716 ;; Call to AIX abi function which may be in another module.
10717 ;; Restore the TOC pointer (r2) after the call.
10719 (define_insn "*call_nonlocal_aix<mode>"
10720   [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s"))
10721          (match_operand 1 "" "g"))
10722    (clobber (reg:P LR_REGNO))]
10723   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10725   return rs6000_call_template (operands, 0, "");
10727   [(set_attr "type" "branch")
10728    (set_attr "length" "8")])
10730 (define_insn "*call_value_nonlocal_aix<mode>"
10731   [(set (match_operand 0 "" "")
10732         (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s"))
10733               (match_operand 2 "" "g")))
10734    (clobber (reg:P LR_REGNO))]
10735   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10737   return rs6000_call_template (operands, 1, "");
10739   [(set_attr "type" "branch")
10740    (set_attr "length" "8")])
10742 ;; Call to indirect functions with the AIX abi using a 3 word descriptor.
10743 ;; Operand0 is the addresss of the function to call
10744 ;; Operand2 is the location in the function descriptor to load r2 from
10745 ;; Operand3 is the offset of the stack location holding the current TOC pointer
10747 (define_insn "*call_indirect_aix<mode>"
10748   [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
10749          (match_operand 1 "" "g,g"))
10750    (use (match_operand:P 2 "memory_operand" "<ptrm>,<ptrm>"))
10751    (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10752    (clobber (reg:P LR_REGNO))]
10753   "DEFAULT_ABI == ABI_AIX && rs6000_speculate_indirect_jumps"
10754   "<ptrload> 2,%2\;b%T0l\;<ptrload> 2,%3(1)"
10755   [(set_attr "type" "jmpreg")
10756    (set_attr "length" "12")])
10758 (define_insn "*call_indirect_aix<mode>_nospec"
10759   [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
10760          (match_operand 1 "" "g,g"))
10761    (use (match_operand:P 2 "memory_operand" "<ptrm>,<ptrm>"))
10762    (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10763    (clobber (reg:P LR_REGNO))]
10764   "DEFAULT_ABI == ABI_AIX && !rs6000_speculate_indirect_jumps"
10765   "crset 2\;<ptrload> 2,%2\;beq%T0l-\;<ptrload> 2,%3(1)"
10766   [(set_attr "type" "jmpreg")
10767    (set_attr "length" "16")])
10769 (define_insn "*call_value_indirect_aix<mode>"
10770   [(set (match_operand 0 "" "")
10771         (call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
10772               (match_operand 2 "" "g,g")))
10773    (use (match_operand:P 3 "memory_operand" "<ptrm>,<ptrm>"))
10774    (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 4 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10775    (clobber (reg:P LR_REGNO))]
10776   "DEFAULT_ABI == ABI_AIX && rs6000_speculate_indirect_jumps"
10777   "<ptrload> 2,%3\;b%T1l\;<ptrload> 2,%4(1)"
10778   [(set_attr "type" "jmpreg")
10779    (set_attr "length" "12")])
10781 (define_insn "*call_value_indirect_aix<mode>_nospec"
10782   [(set (match_operand 0 "" "")
10783         (call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
10784               (match_operand 2 "" "g,g")))
10785    (use (match_operand:P 3 "memory_operand" "<ptrm>,<ptrm>"))
10786    (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 4 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10787    (clobber (reg:P LR_REGNO))]
10788   "DEFAULT_ABI == ABI_AIX && !rs6000_speculate_indirect_jumps"
10789   "crset 2\;<ptrload> 2,%3\;beq%T1l-\;<ptrload> 2,%4(1)"
10790   [(set_attr "type" "jmpreg")
10791    (set_attr "length" "16")])
10793 ;; Call to indirect functions with the ELFv2 ABI.
10794 ;; Operand0 is the addresss of the function to call
10795 ;; Operand2 is the offset of the stack location holding the current TOC pointer
10797 (define_insn "*call_indirect_elfv2<mode>"
10798   [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
10799          (match_operand 1 "" "g,g"))
10800    (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 2 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10801    (clobber (reg:P LR_REGNO))]
10802   "DEFAULT_ABI == ABI_ELFv2 && rs6000_speculate_indirect_jumps"
10803   "b%T0l\;<ptrload> 2,%2(1)"
10804   [(set_attr "type" "jmpreg")
10805    (set_attr "length" "8")])
10807 ;; Variant with deliberate misprediction.
10808 (define_insn "*call_indirect_elfv2<mode>_nospec"
10809   [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
10810          (match_operand 1 "" "g,g"))
10811    (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 2 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10812    (clobber (reg:P LR_REGNO))]
10813   "DEFAULT_ABI == ABI_ELFv2 && !rs6000_speculate_indirect_jumps"
10814   "crset 2\;beq%T0l-\;<ptrload> 2,%2(1)"
10815   [(set_attr "type" "jmpreg")
10816    (set_attr "length" "12")])
10818 (define_insn "*call_value_indirect_elfv2<mode>"
10819   [(set (match_operand 0 "" "")
10820         (call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
10821               (match_operand 2 "" "g,g")))
10822    (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10823    (clobber (reg:P LR_REGNO))]
10824   "DEFAULT_ABI == ABI_ELFv2 && rs6000_speculate_indirect_jumps"
10825   "b%T1l\;<ptrload> 2,%3(1)"
10826   [(set_attr "type" "jmpreg")
10827    (set_attr "length" "8")])
10829 ; Variant with deliberate misprediction.
10830 (define_insn "*call_value_indirect_elfv2<mode>_nospec"
10831   [(set (match_operand 0 "" "")
10832         (call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
10833               (match_operand 2 "" "g,g")))
10834    (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10835    (clobber (reg:P LR_REGNO))]
10836   "DEFAULT_ABI == ABI_ELFv2 && !rs6000_speculate_indirect_jumps"
10837   "crset 2\;beq%T1l-\;<ptrload> 2,%3(1)"
10838   [(set_attr "type" "jmpreg")
10839    (set_attr "length" "12")])
10841 ;; Call subroutine returning any type.
10842 (define_expand "untyped_call"
10843   [(parallel [(call (match_operand 0 "")
10844                     (const_int 0))
10845               (match_operand 1 "")
10846               (match_operand 2 "")])]
10847   ""
10849   int i;
10851   emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
10853   for (i = 0; i < XVECLEN (operands[2], 0); i++)
10854     {
10855       rtx set = XVECEXP (operands[2], 0, i);
10856       emit_move_insn (SET_DEST (set), SET_SRC (set));
10857     }
10859   /* The optimizer does not know that the call sets the function value
10860      registers we stored in the result block.  We avoid problems by
10861      claiming that all hard registers are used and clobbered at this
10862      point.  */
10863   emit_insn (gen_blockage ());
10865   DONE;
10868 ;; sibling call patterns
10869 (define_expand "sibcall"
10870   [(parallel [(call (mem:SI (match_operand 0 "address_operand"))
10871                     (match_operand 1 ""))
10872               (use (match_operand 2 ""))
10873               (simple_return)])]
10874   ""
10876 #if TARGET_MACHO
10877   if (MACHOPIC_INDIRECT)
10878     operands[0] = machopic_indirect_call_target (operands[0]);
10879 #endif
10881   gcc_assert (GET_CODE (operands[0]) == MEM);
10882   gcc_assert (GET_CODE (operands[1]) == CONST_INT);
10884   operands[0] = XEXP (operands[0], 0);
10886   if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10887     {
10888       rs6000_sibcall_aix (NULL_RTX, operands[0], operands[1], operands[2]);
10889       DONE;
10890     }
10893 (define_expand "sibcall_value"
10894   [(parallel [(set (match_operand 0 "register_operand")
10895                 (call (mem:SI (match_operand 1 "address_operand"))
10896                       (match_operand 2 "")))
10897               (use (match_operand 3 ""))
10898               (simple_return)])]
10899   ""
10901 #if TARGET_MACHO
10902   if (MACHOPIC_INDIRECT)
10903     operands[1] = machopic_indirect_call_target (operands[1]);
10904 #endif
10906   gcc_assert (GET_CODE (operands[1]) == MEM);
10907   gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10909   operands[1] = XEXP (operands[1], 0);
10911   if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10912     {
10913       rs6000_sibcall_aix (operands[0], operands[1], operands[2], operands[3]);
10914       DONE;
10915     }
10918 (define_insn "*sibcall_local32"
10919   [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
10920          (match_operand 1 "" "g,g"))
10921    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10922    (simple_return)]
10923   "(INTVAL (operands[2]) & CALL_LONG) == 0"
10925   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10926     output_asm_insn ("crxor 6,6,6", operands);
10928   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10929     output_asm_insn ("creqv 6,6,6", operands);
10931   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z0@local" : "b %z0";
10933   [(set_attr "type" "branch")
10934    (set_attr "length" "4,8")])
10936 (define_insn "*sibcall_local64"
10937   [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
10938          (match_operand 1 "" "g,g"))
10939    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10940    (simple_return)]
10941   "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
10943   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10944     output_asm_insn ("crxor 6,6,6", operands);
10946   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10947     output_asm_insn ("creqv 6,6,6", operands);
10949   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z0@local" : "b %z0";
10951   [(set_attr "type" "branch")
10952    (set_attr "length" "4,8")])
10954 (define_insn "*sibcall_value_local32"
10955   [(set (match_operand 0 "" "")
10956         (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
10957               (match_operand 2 "" "g,g")))
10958    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10959    (simple_return)]
10960   "(INTVAL (operands[3]) & CALL_LONG) == 0"
10962   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10963     output_asm_insn ("crxor 6,6,6", operands);
10965   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10966     output_asm_insn ("creqv 6,6,6", operands);
10968   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z1@local" : "b %z1";
10970   [(set_attr "type" "branch")
10971    (set_attr "length" "4,8")])
10973 (define_insn "*sibcall_value_local64"
10974   [(set (match_operand 0 "" "")
10975         (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
10976               (match_operand 2 "" "g,g")))
10977    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10978    (simple_return)]
10979   "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
10981   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10982     output_asm_insn ("crxor 6,6,6", operands);
10984   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10985     output_asm_insn ("creqv 6,6,6", operands);
10987   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z1@local" : "b %z1";
10989   [(set_attr "type" "branch")
10990    (set_attr "length" "4,8")])
10992 (define_insn "*sibcall_nonlocal_sysv<mode>"
10993   [(call (mem:SI (match_operand:P 0 "call_operand" "s,s,c,c"))
10994          (match_operand 1 "" ""))
10995    (use (match_operand 2 "immediate_operand" "O,n,O,n"))
10996    (simple_return)]
10997   "(DEFAULT_ABI == ABI_DARWIN
10998     || DEFAULT_ABI == ABI_V4)
10999    && (INTVAL (operands[2]) & CALL_LONG) == 0"
11001   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
11002     output_asm_insn ("crxor 6,6,6", operands);
11004   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
11005     output_asm_insn ("creqv 6,6,6", operands);
11007   if (which_alternative >= 2)
11008     {
11009       if (rs6000_speculate_indirect_jumps)
11010         return "b%T0";
11011       else
11012         /* Can use CR0 since it is volatile across sibcalls.  */
11013         return "crset 2\;beq%T0-\;b $";
11014     }
11015   else
11016     return rs6000_sibcall_template (operands, 0, "");
11018   [(set_attr "type" "branch")
11019    (set_attr_alternative "length"
11020      [(const_string "4")
11021       (const_string "8")
11022       (if_then_else (eq (symbol_ref "rs6000_speculate_indirect_jumps")
11023                         (const_int 0))
11024                     (const_string "12")
11025                     (const_string "4"))
11026       (if_then_else (eq (symbol_ref "rs6000_speculate_indirect_jumps")
11027                         (const_int 0))
11028                     (const_string "16")
11029                     (const_string "8"))])])
11031 (define_insn "*sibcall_value_nonlocal_sysv<mode>"
11032   [(set (match_operand 0 "" "")
11033         (call (mem:SI (match_operand:P 1 "call_operand" "s,s,c,c"))
11034               (match_operand 2 "" "")))
11035    (use (match_operand:SI 3 "immediate_operand" "O,n,O,n"))
11036    (simple_return)]
11037   "(DEFAULT_ABI == ABI_DARWIN
11038     || DEFAULT_ABI == ABI_V4)
11039    && (INTVAL (operands[3]) & CALL_LONG) == 0"
11041   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11042     output_asm_insn ("crxor 6,6,6", operands);
11044   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11045     output_asm_insn ("creqv 6,6,6", operands);
11047   if (which_alternative >= 2)
11048     {
11049       if (rs6000_speculate_indirect_jumps)
11050         return "b%T1";
11051       else
11052         /* Can use CR0 since it is volatile across sibcalls.  */
11053         return "crset 2\;beq%T1-\;b $";
11054     }
11055   else
11056     return rs6000_sibcall_template (operands, 1, "");
11058   [(set_attr "type" "branch")
11059    (set_attr_alternative "length"
11060      [(const_string "4")
11061       (const_string "8")
11062       (if_then_else (eq (symbol_ref "rs6000_speculate_indirect_jumps")
11063                         (const_int 0))
11064                     (const_string "12")
11065                     (const_string "4"))
11066       (if_then_else (eq (symbol_ref "rs6000_speculate_indirect_jumps")
11067                         (const_int 0))
11068                     (const_string "16")
11069                     (const_string "8"))])])
11071 ;; AIX ABI sibling call patterns.
11073 (define_insn "*sibcall_aix<mode>"
11074   [(call (mem:SI (match_operand:P 0 "call_operand" "s,c"))
11075          (match_operand 1 "" "g,g"))
11076    (simple_return)]
11077   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11079   if (which_alternative == 0)
11080     return rs6000_sibcall_template (operands, 0, "");
11081   else
11082     return "b%T0";
11084   [(set_attr "type" "branch")])
11086 (define_insn "*sibcall_value_aix<mode>"
11087   [(set (match_operand 0 "" "")
11088         (call (mem:SI (match_operand:P 1 "call_operand" "s,c"))
11089               (match_operand 2 "" "g,g")))
11090    (simple_return)]
11091   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11093   if (which_alternative == 0)
11094     return rs6000_sibcall_template (operands, 1, "");
11095   else
11096     return "b%T1";
11098   [(set_attr "type" "branch")])
11100 (define_expand "sibcall_epilogue"
11101   [(use (const_int 0))]
11102   ""
11104   if (!TARGET_SCHED_PROLOG)
11105     emit_insn (gen_blockage ());
11106   rs6000_emit_epilogue (TRUE);
11107   DONE;
11110 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11111 ;; all of memory.  This blocks insns from being moved across this point.
11113 (define_insn "blockage"
11114   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCK)]
11115   ""
11116   ""
11117   [(set_attr "length" "0")])
11119 (define_expand "probe_stack_address"
11120   [(use (match_operand 0 "address_operand"))]
11121   ""
11123   operands[0] = gen_rtx_MEM (Pmode, operands[0]);
11124   MEM_VOLATILE_P (operands[0]) = 1;
11126   if (TARGET_64BIT)
11127     emit_insn (gen_probe_stack_di (operands[0]));
11128   else
11129     emit_insn (gen_probe_stack_si (operands[0]));
11130   DONE;
11133 (define_insn "probe_stack_<mode>"
11134   [(set (match_operand:P 0 "memory_operand" "=m")
11135         (unspec:P [(const_int 0)] UNSPEC_PROBE_STACK))]
11136   ""
11138   operands[1] = gen_rtx_REG (Pmode, 0);
11139   return "st<wd>%U0%X0 %1,%0";
11141   [(set_attr "type" "store")
11142    (set (attr "update")
11143         (if_then_else (match_operand 0 "update_address_mem")
11144                       (const_string "yes")
11145                       (const_string "no")))
11146    (set (attr "indexed")
11147         (if_then_else (match_operand 0 "indexed_address_mem")
11148                       (const_string "yes")
11149                       (const_string "no")))])
11151 (define_insn "probe_stack_range<P:mode>"
11152   [(set (match_operand:P 0 "register_operand" "=&r")
11153         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
11154                             (match_operand:P 2 "register_operand" "r")
11155                             (match_operand:P 3 "register_operand" "r")]
11156                            UNSPECV_PROBE_STACK_RANGE))]
11157   ""
11158   "* return output_probe_stack_range (operands[0], operands[2], operands[3]);"
11159   [(set_attr "type" "three")])
11161 ;; Compare insns are next.  Note that the RS/6000 has two types of compares,
11162 ;; signed & unsigned, and one type of branch.
11164 ;; Start with the DEFINE_EXPANDs to generate the rtl for compares, scc
11165 ;; insns, and branches.
11167 (define_expand "cbranch<mode>4"
11168   [(use (match_operator 0 "comparison_operator"
11169          [(match_operand:GPR 1 "gpc_reg_operand")
11170           (match_operand:GPR 2 "reg_or_short_operand")]))
11171    (use (match_operand 3))]
11172   ""
11174   /* Take care of the possibility that operands[2] might be negative but
11175      this might be a logical operation.  That insn doesn't exist.  */
11176   if (GET_CODE (operands[2]) == CONST_INT
11177       && INTVAL (operands[2]) < 0)
11178     {
11179       operands[2] = force_reg (<MODE>mode, operands[2]);
11180       operands[0] = gen_rtx_fmt_ee (GET_CODE (operands[0]),
11181                                     GET_MODE (operands[0]),
11182                                     operands[1], operands[2]);
11183    }
11185   rs6000_emit_cbranch (<MODE>mode, operands);
11186   DONE;
11189 (define_expand "cbranch<mode>4"
11190   [(use (match_operator 0 "comparison_operator"
11191          [(match_operand:FP 1 "gpc_reg_operand")
11192           (match_operand:FP 2 "gpc_reg_operand")]))
11193    (use (match_operand 3))]
11194   ""
11196   rs6000_emit_cbranch (<MODE>mode, operands);
11197   DONE;
11200 (define_expand "cstore<mode>4_signed"
11201   [(use (match_operator 1 "signed_comparison_operator"
11202          [(match_operand:P 2 "gpc_reg_operand")
11203           (match_operand:P 3 "gpc_reg_operand")]))
11204    (clobber (match_operand:P 0 "gpc_reg_operand"))]
11205   ""
11207   enum rtx_code cond_code = GET_CODE (operands[1]);
11209   rtx op0 = operands[0];
11210   rtx op1 = operands[2];
11211   rtx op2 = operands[3];
11213   if (cond_code == GE || cond_code == LT)
11214     {
11215       cond_code = swap_condition (cond_code);
11216       std::swap (op1, op2);
11217     }
11219   rtx tmp1 = gen_reg_rtx (<MODE>mode);
11220   rtx tmp2 = gen_reg_rtx (<MODE>mode);
11221   rtx tmp3 = gen_reg_rtx (<MODE>mode);
11223   int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11224   emit_insn (gen_lshr<mode>3 (tmp1, op1, GEN_INT (sh)));
11225   emit_insn (gen_ashr<mode>3 (tmp2, op2, GEN_INT (sh)));
11227   emit_insn (gen_subf<mode>3_carry (tmp3, op1, op2));
11229   if (cond_code == LE)
11230     emit_insn (gen_add<mode>3_carry_in (op0, tmp1, tmp2));
11231   else
11232     {
11233       rtx tmp4 = gen_reg_rtx (<MODE>mode);
11234       emit_insn (gen_add<mode>3_carry_in (tmp4, tmp1, tmp2));
11235       emit_insn (gen_xor<mode>3 (op0, tmp4, const1_rtx));
11236     }
11238   DONE;
11241 (define_expand "cstore<mode>4_unsigned"
11242   [(use (match_operator 1 "unsigned_comparison_operator"
11243          [(match_operand:P 2 "gpc_reg_operand")
11244           (match_operand:P 3 "reg_or_short_operand")]))
11245    (clobber (match_operand:P 0 "gpc_reg_operand"))]
11246   ""
11248   enum rtx_code cond_code = GET_CODE (operands[1]);
11250   rtx op0 = operands[0];
11251   rtx op1 = operands[2];
11252   rtx op2 = operands[3];
11254   if (cond_code == GEU || cond_code == LTU)
11255     {
11256       cond_code = swap_condition (cond_code);
11257       std::swap (op1, op2);
11258     }
11260   if (!gpc_reg_operand (op1, <MODE>mode))
11261     op1 = force_reg (<MODE>mode, op1);
11262   if (!reg_or_short_operand (op2, <MODE>mode))
11263     op2 = force_reg (<MODE>mode, op2);
11265   rtx tmp = gen_reg_rtx (<MODE>mode);
11266   rtx tmp2 = gen_reg_rtx (<MODE>mode);
11268   emit_insn (gen_subf<mode>3_carry (tmp, op1, op2));
11269   emit_insn (gen_subf<mode>3_carry_in_xx (tmp2));
11271   if (cond_code == LEU)
11272     emit_insn (gen_add<mode>3 (op0, tmp2, const1_rtx));
11273   else
11274     emit_insn (gen_neg<mode>2 (op0, tmp2));
11276   DONE;
11279 (define_expand "cstore_si_as_di"
11280   [(use (match_operator 1 "unsigned_comparison_operator"
11281          [(match_operand:SI 2 "gpc_reg_operand")
11282           (match_operand:SI 3 "reg_or_short_operand")]))
11283    (clobber (match_operand:SI 0 "gpc_reg_operand"))]
11284   ""
11286   int uns_flag = unsigned_comparison_operator (operands[1], VOIDmode) ? 1 : 0;
11287   enum rtx_code cond_code = signed_condition (GET_CODE (operands[1]));
11289   operands[2] = force_reg (SImode, operands[2]);
11290   operands[3] = force_reg (SImode, operands[3]);
11291   rtx op1 = gen_reg_rtx (DImode);
11292   rtx op2 = gen_reg_rtx (DImode);
11293   convert_move (op1, operands[2], uns_flag);
11294   convert_move (op2, operands[3], uns_flag);
11296   if (cond_code == GT || cond_code == LE)
11297     {
11298       cond_code = swap_condition (cond_code);
11299       std::swap (op1, op2);
11300     }
11302   rtx tmp = gen_reg_rtx (DImode);
11303   rtx tmp2 = gen_reg_rtx (DImode);
11304   emit_insn (gen_subdi3 (tmp, op1, op2));
11305   emit_insn (gen_lshrdi3 (tmp2, tmp, GEN_INT (63)));
11307   rtx tmp3;
11308   switch (cond_code)
11309     {
11310     default:
11311       gcc_unreachable ();
11312     case LT:
11313       tmp3 = tmp2;
11314       break;
11315     case GE:
11316       tmp3 = gen_reg_rtx (DImode);
11317       emit_insn (gen_xordi3 (tmp3, tmp2, const1_rtx));
11318       break;
11319     }
11321   convert_move (operands[0], tmp3, 1);
11323   DONE;
11326 (define_expand "cstore<mode>4_signed_imm"
11327   [(use (match_operator 1 "signed_comparison_operator"
11328          [(match_operand:GPR 2 "gpc_reg_operand")
11329           (match_operand:GPR 3 "immediate_operand")]))
11330    (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11331   ""
11333   bool invert = false;
11335   enum rtx_code cond_code = GET_CODE (operands[1]);
11337   rtx op0 = operands[0];
11338   rtx op1 = operands[2];
11339   HOST_WIDE_INT val = INTVAL (operands[3]);
11341   if (cond_code == GE || cond_code == GT)
11342     {
11343       cond_code = reverse_condition (cond_code);
11344       invert = true;
11345     }
11347   if (cond_code == LE)
11348     val++;
11350   rtx tmp = gen_reg_rtx (<MODE>mode);
11351   emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
11352   rtx x = gen_reg_rtx (<MODE>mode);
11353   if (val < 0)
11354     emit_insn (gen_and<mode>3 (x, op1, tmp));
11355   else
11356     emit_insn (gen_ior<mode>3 (x, op1, tmp));
11358   if (invert)
11359     {
11360       rtx tmp = gen_reg_rtx (<MODE>mode);
11361       emit_insn (gen_one_cmpl<mode>2 (tmp, x));
11362       x = tmp;
11363     }
11365   int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11366   emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
11368   DONE;
11371 (define_expand "cstore<mode>4_unsigned_imm"
11372   [(use (match_operator 1 "unsigned_comparison_operator"
11373          [(match_operand:GPR 2 "gpc_reg_operand")
11374           (match_operand:GPR 3 "immediate_operand")]))
11375    (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11376   ""
11378   bool invert = false;
11380   enum rtx_code cond_code = GET_CODE (operands[1]);
11382   rtx op0 = operands[0];
11383   rtx op1 = operands[2];
11384   HOST_WIDE_INT val = INTVAL (operands[3]);
11386   if (cond_code == GEU || cond_code == GTU)
11387     {
11388       cond_code = reverse_condition (cond_code);
11389       invert = true;
11390     }
11392   if (cond_code == LEU)
11393     val++;
11395   rtx tmp = gen_reg_rtx (<MODE>mode);
11396   rtx tmp2 = gen_reg_rtx (<MODE>mode);
11397   emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
11398   emit_insn (gen_one_cmpl<mode>2 (tmp2, op1));
11399   rtx x = gen_reg_rtx (<MODE>mode);
11400   if (val < 0)
11401     emit_insn (gen_ior<mode>3 (x, tmp, tmp2));
11402   else
11403     emit_insn (gen_and<mode>3 (x, tmp, tmp2));
11405   if (invert)
11406     {
11407       rtx tmp = gen_reg_rtx (<MODE>mode);
11408       emit_insn (gen_one_cmpl<mode>2 (tmp, x));
11409       x = tmp;
11410     }
11412   int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11413   emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
11415   DONE;
11418 (define_expand "cstore<mode>4"
11419   [(use (match_operator 1 "comparison_operator"
11420          [(match_operand:GPR 2 "gpc_reg_operand")
11421           (match_operand:GPR 3 "reg_or_short_operand")]))
11422    (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11423   ""
11425   /* Expanding EQ and NE directly to some machine instructions does not help
11426      but does hurt combine.  So don't.  */
11427   if (GET_CODE (operands[1]) == EQ)
11428     emit_insn (gen_eq<mode>3 (operands[0], operands[2], operands[3]));
11429   else if (<MODE>mode == Pmode
11430            && GET_CODE (operands[1]) == NE)
11431     emit_insn (gen_ne<mode>3 (operands[0], operands[2], operands[3]));
11432   else if (GET_CODE (operands[1]) == NE)
11433     {
11434       rtx tmp = gen_reg_rtx (<MODE>mode);
11435       emit_insn (gen_eq<mode>3 (tmp, operands[2], operands[3]));
11436       emit_insn (gen_xor<mode>3 (operands[0], tmp, const1_rtx));
11437     }
11439   /* If ISEL is fast, expand to it.  */
11440   else if (TARGET_ISEL)
11441     rs6000_emit_int_cmove (operands[0], operands[1], const1_rtx, const0_rtx);
11443   /* Expanding the unsigned comparisons helps a lot: all the neg_ltu
11444      etc. combinations magically work out just right.  */
11445   else if (<MODE>mode == Pmode
11446            && unsigned_comparison_operator (operands[1], VOIDmode))
11447     emit_insn (gen_cstore<mode>4_unsigned (operands[0], operands[1],
11448                                            operands[2], operands[3]));
11450   /* For comparisons smaller than Pmode we can cheaply do things in Pmode.  */
11451   else if (<MODE>mode == SImode && Pmode == DImode)
11452     emit_insn (gen_cstore_si_as_di (operands[0], operands[1],
11453                                     operands[2], operands[3]));
11455   /* For signed comparisons against a constant, we can do some simple
11456      bit-twiddling.  */
11457   else if (signed_comparison_operator (operands[1], VOIDmode)
11458            && CONST_INT_P (operands[3]))
11459     emit_insn (gen_cstore<mode>4_signed_imm (operands[0], operands[1],
11460                                              operands[2], operands[3]));
11462   /* And similarly for unsigned comparisons.  */
11463   else if (unsigned_comparison_operator (operands[1], VOIDmode)
11464            && CONST_INT_P (operands[3]))
11465     emit_insn (gen_cstore<mode>4_unsigned_imm (operands[0], operands[1],
11466                                                operands[2], operands[3]));
11468   /* We also do not want to use mfcr for signed comparisons.  */
11469   else if (<MODE>mode == Pmode
11470            && signed_comparison_operator (operands[1], VOIDmode))
11471     emit_insn (gen_cstore<mode>4_signed (operands[0], operands[1],
11472                                          operands[2], operands[3]));
11474   /* Everything else, use the mfcr brute force.  */
11475   else
11476     rs6000_emit_sCOND (<MODE>mode, operands);
11478   DONE;
11481 (define_expand "cstore<mode>4"
11482   [(use (match_operator 1 "comparison_operator"
11483          [(match_operand:FP 2 "gpc_reg_operand")
11484           (match_operand:FP 3 "gpc_reg_operand")]))
11485    (clobber (match_operand:SI 0 "gpc_reg_operand"))]
11486   ""
11488   rs6000_emit_sCOND (<MODE>mode, operands);
11489   DONE;
11493 (define_expand "stack_protect_set"
11494   [(match_operand 0 "memory_operand")
11495    (match_operand 1 "memory_operand")]
11496   ""
11498   if (rs6000_stack_protector_guard == SSP_TLS)
11499     {
11500       rtx reg = gen_rtx_REG (Pmode, rs6000_stack_protector_guard_reg);
11501       rtx offset = GEN_INT (rs6000_stack_protector_guard_offset);
11502       rtx addr = gen_rtx_PLUS (Pmode, reg, offset);
11503       operands[1] = gen_rtx_MEM (Pmode, addr);
11504     }
11506   if (TARGET_64BIT)
11507     emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
11508   else
11509     emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
11511   DONE;
11514 (define_insn "stack_protect_setsi"
11515   [(set (match_operand:SI 0 "memory_operand" "=m")
11516         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
11517    (set (match_scratch:SI 2 "=&r") (const_int 0))]
11518   "TARGET_32BIT"
11519   "lwz%U1%X1 %2,%1\;stw%U0%X0 %2,%0\;li %2,0"
11520   [(set_attr "type" "three")
11521    (set_attr "length" "12")])
11523 (define_insn "stack_protect_setdi"
11524   [(set (match_operand:DI 0 "memory_operand" "=Y")
11525         (unspec:DI [(match_operand:DI 1 "memory_operand" "Y")] UNSPEC_SP_SET))
11526    (set (match_scratch:DI 2 "=&r") (const_int 0))]
11527   "TARGET_64BIT"
11528   "ld%U1%X1 %2,%1\;std%U0%X0 %2,%0\;li %2,0"
11529   [(set_attr "type" "three")
11530    (set_attr "length" "12")])
11532 (define_expand "stack_protect_test"
11533   [(match_operand 0 "memory_operand")
11534    (match_operand 1 "memory_operand")
11535    (match_operand 2 "")]
11536   ""
11538   rtx guard = operands[1];
11540   if (rs6000_stack_protector_guard == SSP_TLS)
11541     {
11542       rtx reg = gen_rtx_REG (Pmode, rs6000_stack_protector_guard_reg);
11543       rtx offset = GEN_INT (rs6000_stack_protector_guard_offset);
11544       rtx addr = gen_rtx_PLUS (Pmode, reg, offset);
11545       guard = gen_rtx_MEM (Pmode, addr);
11546     }
11548   operands[1] = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, guard), UNSPEC_SP_TEST);
11549   rtx test = gen_rtx_EQ (VOIDmode, operands[0], operands[1]);
11550   rtx jump = gen_cbranchsi4 (test, operands[0], operands[1], operands[2]);
11551   emit_jump_insn (jump);
11553   DONE;
11556 (define_insn "stack_protect_testsi"
11557   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
11558         (unspec:CCEQ [(match_operand:SI 1 "memory_operand" "m,m")
11559                       (match_operand:SI 2 "memory_operand" "m,m")]
11560                      UNSPEC_SP_TEST))
11561    (set (match_scratch:SI 4 "=r,r") (const_int 0))
11562    (clobber (match_scratch:SI 3 "=&r,&r"))]
11563   "TARGET_32BIT"
11564   "@
11565    lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0
11566    lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;cmplw %0,%3,%4\;li %3,0\;li %4,0"
11567   [(set_attr "length" "16,20")])
11569 (define_insn "stack_protect_testdi"
11570   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
11571         (unspec:CCEQ [(match_operand:DI 1 "memory_operand" "Y,Y")
11572                       (match_operand:DI 2 "memory_operand" "Y,Y")]
11573                      UNSPEC_SP_TEST))
11574    (set (match_scratch:DI 4 "=r,r") (const_int 0))
11575    (clobber (match_scratch:DI 3 "=&r,&r"))]
11576   "TARGET_64BIT"
11577   "@
11578    ld%U1%X1 %3,%1\;ld%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0
11579    ld%U1%X1 %3,%1\;ld%U2%X2 %4,%2\;cmpld %0,%3,%4\;li %3,0\;li %4,0"
11580   [(set_attr "length" "16,20")])
11583 ;; Here are the actual compare insns.
11584 (define_insn "*cmp<mode>_signed"
11585   [(set (match_operand:CC 0 "cc_reg_operand" "=y")
11586         (compare:CC (match_operand:GPR 1 "gpc_reg_operand" "r")
11587                     (match_operand:GPR 2 "reg_or_short_operand" "rI")))]
11588   ""
11589   "cmp<wd>%I2 %0,%1,%2"
11590   [(set_attr "type" "cmp")])
11592 (define_insn "*cmp<mode>_unsigned"
11593   [(set (match_operand:CCUNS 0 "cc_reg_operand" "=y")
11594         (compare:CCUNS (match_operand:GPR 1 "gpc_reg_operand" "r")
11595                        (match_operand:GPR 2 "reg_or_u_short_operand" "rK")))]
11596   ""
11597   "cmpl<wd>%I2 %0,%1,%2"
11598   [(set_attr "type" "cmp")])
11600 ;; If we are comparing a register for equality with a large constant,
11601 ;; we can do this with an XOR followed by a compare.  But this is profitable
11602 ;; only if the large constant is only used for the comparison (and in this
11603 ;; case we already have a register to reuse as scratch).
11605 ;; For 64-bit registers, we could only do so if the constant's bit 15 is clear:
11606 ;; otherwise we'd need to XOR with FFFFFFFF????0000 which is not available.
11608 (define_peephole2
11609   [(set (match_operand:SI 0 "register_operand")
11610         (match_operand:SI 1 "logical_const_operand"))
11611    (set (match_dup 0) (match_operator:SI 3 "boolean_or_operator"
11612                        [(match_dup 0)
11613                         (match_operand:SI 2 "logical_const_operand")]))
11614    (set (match_operand:CC 4 "cc_reg_operand")
11615         (compare:CC (match_operand:SI 5 "gpc_reg_operand")
11616                     (match_dup 0)))
11617    (set (pc)
11618         (if_then_else (match_operator 6 "equality_operator"
11619                        [(match_dup 4) (const_int 0)])
11620                       (match_operand 7 "")
11621                       (match_operand 8 "")))]
11622   "peep2_reg_dead_p (3, operands[0])
11623    && peep2_reg_dead_p (4, operands[4])
11624    && REGNO (operands[0]) != REGNO (operands[5])"
11625  [(set (match_dup 0) (xor:SI (match_dup 5) (match_dup 9)))
11626   (set (match_dup 4) (compare:CC (match_dup 0) (match_dup 10)))
11627   (set (pc) (if_then_else (match_dup 6) (match_dup 7) (match_dup 8)))]
11630   /* Get the constant we are comparing against, and see what it looks like
11631      when sign-extended from 16 to 32 bits.  Then see what constant we could
11632      XOR with SEXTC to get the sign-extended value.  */
11633   rtx cnst = simplify_const_binary_operation (GET_CODE (operands[3]),
11634                                               SImode,
11635                                               operands[1], operands[2]);
11636   HOST_WIDE_INT c = INTVAL (cnst);
11637   HOST_WIDE_INT sextc = ((c & 0xffff) ^ 0x8000) - 0x8000;
11638   HOST_WIDE_INT xorv = c ^ sextc;
11640   operands[9] = GEN_INT (xorv);
11641   operands[10] = GEN_INT (sextc);
11644 ;; Only need to compare second words if first words equal
11645 (define_insn "*cmp<mode>_internal1"
11646   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
11647         (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
11648                       (match_operand:IBM128 2 "gpc_reg_operand" "d")))]
11649   "!TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode)
11650    && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
11651   "fcmpu %0,%1,%2\;bne %0,$+8\;fcmpu %0,%L1,%L2"
11652   [(set_attr "type" "fpcompare")
11653    (set_attr "length" "12")])
11655 (define_insn_and_split "*cmp<mode>_internal2"
11656   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
11657         (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
11658                       (match_operand:IBM128 2 "gpc_reg_operand" "d")))
11659     (clobber (match_scratch:DF 3 "=d"))
11660     (clobber (match_scratch:DF 4 "=d"))
11661     (clobber (match_scratch:DF 5 "=d"))
11662     (clobber (match_scratch:DF 6 "=d"))
11663     (clobber (match_scratch:DF 7 "=d"))
11664     (clobber (match_scratch:DF 8 "=d"))
11665     (clobber (match_scratch:DF 9 "=d"))
11666     (clobber (match_scratch:DF 10 "=d"))
11667     (clobber (match_scratch:GPR 11 "=b"))]
11668   "TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode)
11669    && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
11670   "#"
11671   "&& reload_completed"
11672   [(set (match_dup 3) (match_dup 14))
11673    (set (match_dup 4) (match_dup 15))
11674    (set (match_dup 9) (abs:DF (match_dup 5)))
11675    (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 3)))
11676    (set (pc) (if_then_else (ne (match_dup 0) (const_int 0))
11677                            (label_ref (match_dup 12))
11678                            (pc)))
11679    (set (match_dup 0) (compare:CCFP (match_dup 5) (match_dup 7)))
11680    (set (pc) (label_ref (match_dup 13)))
11681    (match_dup 12)
11682    (set (match_dup 10) (minus:DF (match_dup 5) (match_dup 7)))
11683    (set (match_dup 9) (minus:DF (match_dup 6) (match_dup 8)))
11684    (set (match_dup 9) (plus:DF (match_dup 10) (match_dup 9)))
11685    (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 4)))
11686    (match_dup 13)]
11688   REAL_VALUE_TYPE rv;
11689   const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
11690   const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
11692   operands[5] = simplify_gen_subreg (DFmode, operands[1], <MODE>mode, hi_word);
11693   operands[6] = simplify_gen_subreg (DFmode, operands[1], <MODE>mode, lo_word);
11694   operands[7] = simplify_gen_subreg (DFmode, operands[2], <MODE>mode, hi_word);
11695   operands[8] = simplify_gen_subreg (DFmode, operands[2], <MODE>mode, lo_word);
11696   operands[12] = gen_label_rtx ();
11697   operands[13] = gen_label_rtx ();
11698   real_inf (&rv);
11699   operands[14] = force_const_mem (DFmode,
11700                                   const_double_from_real_value (rv, DFmode));
11701   operands[15] = force_const_mem (DFmode,
11702                                   const_double_from_real_value (dconst0,
11703                                                                 DFmode));
11704   if (TARGET_TOC)
11705     {
11706       rtx tocref;
11707       tocref = create_TOC_reference (XEXP (operands[14], 0), operands[11]);
11708       operands[14] = gen_const_mem (DFmode, tocref);
11709       tocref = create_TOC_reference (XEXP (operands[15], 0), operands[11]);
11710       operands[15] = gen_const_mem (DFmode, tocref);
11711       set_mem_alias_set (operands[14], get_TOC_alias_set ());
11712       set_mem_alias_set (operands[15], get_TOC_alias_set ());
11713     }
11716 ;; Now we have the scc insns.  We can do some combinations because of the
11717 ;; way the machine works.
11719 ;; Note that this is probably faster if we can put an insn between the
11720 ;; mfcr and rlinm, but this is tricky.  Let's leave it for now.  In most
11721 ;; cases the insns below which don't use an intermediate CR field will
11722 ;; be used instead.
11723 (define_insn ""
11724   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
11725         (match_operator:GPR 1 "scc_comparison_operator"
11726                             [(match_operand 2 "cc_reg_operand" "y")
11727                              (const_int 0)]))]
11728   ""
11729   "mfcr %0%Q2\;rlwinm %0,%0,%J1,1"
11730   [(set (attr "type")
11731      (cond [(match_test "TARGET_MFCRF")
11732                 (const_string "mfcrf")
11733            ]
11734         (const_string "mfcr")))
11735    (set_attr "length" "8")])
11737 (define_insn_and_split ""
11738   [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
11739         (compare:CC (match_operator:SI 1 "scc_comparison_operator"
11740                                        [(match_operand 2 "cc_reg_operand" "y,y")
11741                                         (const_int 0)])
11742                     (const_int 0)))
11743    (set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
11744         (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
11745   "TARGET_32BIT"
11746   "@
11747    mfcr %3%Q2\;rlwinm. %3,%3,%J1,1
11748    #"
11749   "&& reload_completed"
11750   [(set (match_dup 3)
11751         (match_op_dup 1 [(match_dup 2) (const_int 0)]))
11752    (set (match_dup 0)
11753         (compare:CC (match_dup 3)
11754                     (const_int 0)))]
11755   ""
11756   [(set_attr "type" "shift")
11757    (set_attr "dot" "yes")
11758    (set_attr "length" "8,16")])
11760 (define_insn ""
11761   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11762         (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
11763                                       [(match_operand 2 "cc_reg_operand" "y")
11764                                        (const_int 0)])
11765                    (match_operand:SI 3 "const_int_operand" "n")))]
11766   ""
11768   int is_bit = ccr_bit (operands[1], 1);
11769   int put_bit = 31 - (INTVAL (operands[3]) & 31);
11770   int count;
11772   if (is_bit >= put_bit)
11773     count = is_bit - put_bit;
11774   else
11775     count = 32 - (put_bit - is_bit);
11777   operands[4] = GEN_INT (count);
11778   operands[5] = GEN_INT (put_bit);
11780   return "mfcr %0%Q2\;rlwinm %0,%0,%4,%5,%5";
11782   [(set (attr "type")
11783      (cond [(match_test "TARGET_MFCRF")
11784                 (const_string "mfcrf")
11785            ]
11786         (const_string "mfcr")))
11787    (set_attr "length" "8")])
11789 (define_insn ""
11790   [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
11791         (compare:CC
11792          (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
11793                                        [(match_operand 2 "cc_reg_operand" "y,y")
11794                                         (const_int 0)])
11795                     (match_operand:SI 3 "const_int_operand" "n,n"))
11796          (const_int 0)))
11797    (set (match_operand:SI 4 "gpc_reg_operand" "=r,r")
11798         (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
11799                    (match_dup 3)))]
11800   ""
11802   int is_bit = ccr_bit (operands[1], 1);
11803   int put_bit = 31 - (INTVAL (operands[3]) & 31);
11804   int count;
11806   /* Force split for non-cc0 compare.  */
11807   if (which_alternative == 1)
11808      return "#";
11810   if (is_bit >= put_bit)
11811     count = is_bit - put_bit;
11812   else
11813     count = 32 - (put_bit - is_bit);
11815   operands[5] = GEN_INT (count);
11816   operands[6] = GEN_INT (put_bit);
11818   return "mfcr %4%Q2\;rlwinm. %4,%4,%5,%6,%6";
11820   [(set_attr "type" "shift")
11821    (set_attr "dot" "yes")
11822    (set_attr "length" "8,16")])
11824 (define_split
11825   [(set (match_operand:CC 0 "cc_reg_not_cr0_operand")
11826         (compare:CC
11827          (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
11828                                        [(match_operand 2 "cc_reg_operand")
11829                                         (const_int 0)])
11830                     (match_operand:SI 3 "const_int_operand"))
11831          (const_int 0)))
11832    (set (match_operand:SI 4 "gpc_reg_operand")
11833         (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
11834                    (match_dup 3)))]
11835   "reload_completed"
11836   [(set (match_dup 4)
11837         (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
11838                    (match_dup 3)))
11839    (set (match_dup 0)
11840         (compare:CC (match_dup 4)
11841                     (const_int 0)))]
11842   "")
11845 (define_code_iterator cmp [eq ne lt ltu gt gtu le leu ge geu])
11846 (define_code_attr UNS [(eq "CC")
11847                        (ne "CC")
11848                        (lt "CC") (ltu "CCUNS")
11849                        (gt "CC") (gtu "CCUNS")
11850                        (le "CC") (leu "CCUNS")
11851                        (ge "CC") (geu "CCUNS")])
11852 (define_code_attr UNSu_ [(eq "")
11853                          (ne "")
11854                          (lt "") (ltu "u_")
11855                          (gt "") (gtu "u_")
11856                          (le "") (leu "u_")
11857                          (ge "") (geu "u_")])
11858 (define_code_attr UNSIK [(eq "I")
11859                          (ne "I")
11860                          (lt "I") (ltu "K")
11861                          (gt "I") (gtu "K")
11862                          (le "I") (leu "K")
11863                          (ge "I") (geu "K")])
11865 (define_insn_and_split "<code><GPR:mode><GPR2:mode>2_isel"
11866   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
11867         (cmp:GPR (match_operand:GPR2 1 "gpc_reg_operand" "r")
11868                  (match_operand:GPR2 2 "reg_or_<cmp:UNSu_>short_operand" "r<cmp:UNSIK>")))
11869    (clobber (match_scratch:GPR 3 "=r"))
11870    (clobber (match_scratch:GPR 4 "=r"))
11871    (clobber (match_scratch:<UNS> 5 "=y"))]
11872   "TARGET_ISEL
11873    && !(<CODE> == EQ && operands[2] == const0_rtx)
11874    && !(<CODE> == NE && operands[2] == const0_rtx
11875         && <GPR:MODE>mode == Pmode && <GPR2:MODE>mode == Pmode)"
11876   "#"
11877   "&& 1"
11878   [(pc)]
11880   rtx_code code = <CODE>;
11881   if (CONST_INT_P (operands[2]) && code != EQ && code != NE)
11882     {
11883       HOST_WIDE_INT val = INTVAL (operands[2]);
11884       if (code == LT && val != -0x8000)
11885         {
11886           code = LE;
11887           val--;
11888         }
11889       if (code == GT && val != 0x7fff)
11890         {
11891           code = GE;
11892           val++;
11893         }
11894       if (code == LTU && val != 0)
11895         {
11896           code = LEU;
11897           val--;
11898         }
11899       if (code == GTU && val != 0xffff)
11900         {
11901           code = GEU;
11902           val++;
11903         }
11904       operands[2] = GEN_INT (val);
11905     }
11907   if (code == NE || code == LE || code == GE || code == LEU || code == GEU)
11908     operands[3] = const0_rtx;
11909   else
11910     {
11911       if (GET_CODE (operands[3]) == SCRATCH)
11912         operands[3] = gen_reg_rtx (<GPR:MODE>mode);
11913       emit_move_insn (operands[3], const0_rtx);
11914     }
11916   if (GET_CODE (operands[4]) == SCRATCH)
11917     operands[4] = gen_reg_rtx (<GPR:MODE>mode);
11918   emit_move_insn (operands[4], const1_rtx);
11920   if (GET_CODE (operands[5]) == SCRATCH)
11921     operands[5] = gen_reg_rtx (<UNS>mode);
11923   rtx c1 = gen_rtx_COMPARE (<UNS>mode, operands[1], operands[2]);
11924   emit_insn (gen_rtx_SET (operands[5], c1));
11926   rtx c2 = gen_rtx_fmt_ee (code, <GPR:MODE>mode, operands[5], const0_rtx);
11927   rtx x = gen_rtx_IF_THEN_ELSE (<GPR:MODE>mode, c2, operands[4], operands[3]);
11928   emit_move_insn (operands[0], x);
11930   DONE;
11932   [(set (attr "cost")
11933         (if_then_else (match_test "(CONST_INT_P (operands[2]) && <CODE> != EQ)
11934                                    || <CODE> == NE
11935                                    || <CODE> == LE || <CODE> == GE
11936                                    || <CODE> == LEU || <CODE> == GEU")
11937                       (const_string "9")
11938                       (const_string "10")))])
11940 (define_mode_attr scc_eq_op2 [(SI "rKLI")
11941                               (DI "rKJI")])
11943 (define_expand "eq<mode>3"
11944   [(parallel [
11945      (set (match_operand:GPR 0 "gpc_reg_operand" "=r")
11946           (eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
11947                   (match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>")))
11948      (clobber (match_scratch:GPR 3 "=r"))
11949      (clobber (match_scratch:GPR 4 "=r"))])]
11950   ""
11952   if (TARGET_ISEL && operands[2] != const0_rtx)
11953     {
11954       emit_insn (gen_eq<mode><mode>2_isel (operands[0], operands[1],
11955                                            operands[2]));
11956       DONE;
11957     }
11960 (define_insn_and_split "*eq<mode>3"
11961   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
11962         (eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
11963                 (match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>")))
11964    (clobber (match_scratch:GPR 3 "=r"))
11965    (clobber (match_scratch:GPR 4 "=r"))]
11966   "!(TARGET_ISEL && operands[2] != const0_rtx)"
11967   "#"
11968   "&& 1"
11969   [(set (match_dup 4)
11970         (clz:GPR (match_dup 3)))
11971    (set (match_dup 0)
11972         (lshiftrt:GPR (match_dup 4)
11973                       (match_dup 5)))]
11975   operands[3] = rs6000_emit_eqne (<MODE>mode,
11976                                   operands[1], operands[2], operands[3]);
11978   if (GET_CODE (operands[4]) == SCRATCH)
11979     operands[4] = gen_reg_rtx (<MODE>mode);
11981   operands[5] = GEN_INT (exact_log2 (GET_MODE_BITSIZE (<MODE>mode)));
11983   [(set (attr "length")
11984         (if_then_else (match_test "operands[2] == const0_rtx")
11985                       (const_string "8")
11986                       (const_string "12")))])
11988 (define_expand "ne<mode>3"
11989   [(parallel [
11990      (set (match_operand:P 0 "gpc_reg_operand" "=r")
11991           (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
11992                 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")))
11993      (clobber (match_scratch:P 3 "=r"))
11994      (clobber (match_scratch:P 4 "=r"))
11995      (clobber (reg:P CA_REGNO))])]
11996   ""
11998   if (TARGET_ISEL && operands[2] != const0_rtx)
11999     {
12000       emit_insn (gen_ne<mode><mode>2_isel (operands[0], operands[1],
12001                                            operands[2]));
12002       DONE;
12003     }
12006 (define_insn_and_split "*ne<mode>3"
12007   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12008         (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12009               (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")))
12010    (clobber (match_scratch:P 3 "=r"))
12011    (clobber (match_scratch:P 4 "=r"))
12012    (clobber (reg:P CA_REGNO))]
12013   "!(TARGET_ISEL && operands[2] != const0_rtx)"
12014   "#"
12015   "&& 1"
12016   [(parallel [(set (match_dup 4)
12017                    (plus:P (match_dup 3)
12018                            (const_int -1)))
12019               (set (reg:P CA_REGNO)
12020                    (ne:P (match_dup 3)
12021                          (const_int 0)))])
12022    (parallel [(set (match_dup 0)
12023                    (plus:P (plus:P (not:P (match_dup 4))
12024                                    (reg:P CA_REGNO))
12025                            (match_dup 3)))
12026               (clobber (reg:P CA_REGNO))])]
12028   operands[3] = rs6000_emit_eqne (<MODE>mode,
12029                                   operands[1], operands[2], operands[3]);
12031   if (GET_CODE (operands[4]) == SCRATCH)
12032     operands[4] = gen_reg_rtx (<MODE>mode);
12034   [(set (attr "length")
12035         (if_then_else (match_test "operands[2] == const0_rtx")
12036                       (const_string "8")
12037                       (const_string "12")))])
12039 (define_insn_and_split "*neg_eq_<mode>"
12040   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12041         (neg:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12042                      (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12043    (clobber (match_scratch:P 3 "=r"))
12044    (clobber (match_scratch:P 4 "=r"))
12045    (clobber (reg:P CA_REGNO))]
12046   ""
12047   "#"
12048   ""
12049   [(parallel [(set (match_dup 4)
12050                    (plus:P (match_dup 3)
12051                            (const_int -1)))
12052               (set (reg:P CA_REGNO)
12053                    (ne:P (match_dup 3)
12054                          (const_int 0)))])
12055    (parallel [(set (match_dup 0)
12056                    (plus:P (reg:P CA_REGNO)
12057                            (const_int -1)))
12058               (clobber (reg:P CA_REGNO))])]
12060   operands[3] = rs6000_emit_eqne (<MODE>mode,
12061                                   operands[1], operands[2], operands[3]);
12063   if (GET_CODE (operands[4]) == SCRATCH)
12064     operands[4] = gen_reg_rtx (<MODE>mode);
12066   [(set (attr "length")
12067         (if_then_else (match_test "operands[2] == const0_rtx")
12068                       (const_string "8")
12069                       (const_string "12")))])
12071 (define_insn_and_split "*neg_ne_<mode>"
12072   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12073         (neg:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12074                      (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12075    (clobber (match_scratch:P 3 "=r"))
12076    (clobber (match_scratch:P 4 "=r"))
12077    (clobber (reg:P CA_REGNO))]
12078   ""
12079   "#"
12080   ""
12081   [(parallel [(set (match_dup 4)
12082                    (neg:P (match_dup 3)))
12083               (set (reg:P CA_REGNO)
12084                    (eq:P (match_dup 3)
12085                          (const_int 0)))])
12086    (parallel [(set (match_dup 0)
12087                    (plus:P (reg:P CA_REGNO)
12088                            (const_int -1)))
12089               (clobber (reg:P CA_REGNO))])]
12091   operands[3] = rs6000_emit_eqne (<MODE>mode,
12092                                   operands[1], operands[2], operands[3]);
12094   if (GET_CODE (operands[4]) == SCRATCH)
12095     operands[4] = gen_reg_rtx (<MODE>mode);
12097   [(set (attr "length")
12098         (if_then_else (match_test "operands[2] == const0_rtx")
12099                       (const_string "8")
12100                       (const_string "12")))])
12102 (define_insn_and_split "*plus_eq_<mode>"
12103   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12104         (plus:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12105                       (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
12106                 (match_operand:P 3 "gpc_reg_operand" "r")))
12107    (clobber (match_scratch:P 4 "=r"))
12108    (clobber (match_scratch:P 5 "=r"))
12109    (clobber (reg:P CA_REGNO))]
12110   ""
12111   "#"
12112   ""
12113   [(parallel [(set (match_dup 5)
12114                    (neg:P (match_dup 4)))
12115               (set (reg:P CA_REGNO)
12116                    (eq:P (match_dup 4)
12117                          (const_int 0)))])
12118    (parallel [(set (match_dup 0)
12119                    (plus:P (match_dup 3)
12120                            (reg:P CA_REGNO)))
12121               (clobber (reg:P CA_REGNO))])]
12123   operands[4] = rs6000_emit_eqne (<MODE>mode,
12124                                   operands[1], operands[2], operands[4]);
12126   if (GET_CODE (operands[5]) == SCRATCH)
12127     operands[5] = gen_reg_rtx (<MODE>mode);
12129   [(set (attr "length")
12130         (if_then_else (match_test "operands[2] == const0_rtx")
12131                       (const_string "8")
12132                       (const_string "12")))])
12134 (define_insn_and_split "*plus_ne_<mode>"
12135   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12136         (plus:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12137                       (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
12138                 (match_operand:P 3 "gpc_reg_operand" "r")))
12139    (clobber (match_scratch:P 4 "=r"))
12140    (clobber (match_scratch:P 5 "=r"))
12141    (clobber (reg:P CA_REGNO))]
12142   ""
12143   "#"
12144   ""
12145   [(parallel [(set (match_dup 5)
12146                    (plus:P (match_dup 4)
12147                            (const_int -1)))
12148               (set (reg:P CA_REGNO)
12149                    (ne:P (match_dup 4)
12150                          (const_int 0)))])
12151    (parallel [(set (match_dup 0)
12152                    (plus:P (match_dup 3)
12153                            (reg:P CA_REGNO)))
12154               (clobber (reg:P CA_REGNO))])]
12156   operands[4] = rs6000_emit_eqne (<MODE>mode,
12157                                   operands[1], operands[2], operands[4]);
12159   if (GET_CODE (operands[5]) == SCRATCH)
12160     operands[5] = gen_reg_rtx (<MODE>mode);
12162   [(set (attr "length")
12163         (if_then_else (match_test "operands[2] == const0_rtx")
12164                       (const_string "8")
12165                       (const_string "12")))])
12167 (define_insn_and_split "*minus_eq_<mode>"
12168   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12169         (minus:P (match_operand:P 3 "gpc_reg_operand" "r")
12170                  (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12171                        (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12172    (clobber (match_scratch:P 4 "=r"))
12173    (clobber (match_scratch:P 5 "=r"))
12174    (clobber (reg:P CA_REGNO))]
12175   ""
12176   "#"
12177   ""
12178   [(parallel [(set (match_dup 5)
12179                    (plus:P (match_dup 4)
12180                            (const_int -1)))
12181               (set (reg:P CA_REGNO)
12182                    (ne:P (match_dup 4)
12183                          (const_int 0)))])
12184    (parallel [(set (match_dup 0)
12185                    (plus:P (plus:P (match_dup 3)
12186                                    (reg:P CA_REGNO))
12187                            (const_int -1)))
12188               (clobber (reg:P CA_REGNO))])]
12190   operands[4] = rs6000_emit_eqne (<MODE>mode,
12191                                   operands[1], operands[2], operands[4]);
12193   if (GET_CODE (operands[5]) == SCRATCH)
12194     operands[5] = gen_reg_rtx (<MODE>mode);
12196   [(set (attr "length")
12197         (if_then_else (match_test "operands[2] == const0_rtx")
12198                       (const_string "8")
12199                       (const_string "12")))])
12201 (define_insn_and_split "*minus_ne_<mode>"
12202   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12203         (minus:P (match_operand:P 3 "gpc_reg_operand" "r")
12204                  (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12205                        (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12206    (clobber (match_scratch:P 4 "=r"))
12207    (clobber (match_scratch:P 5 "=r"))
12208    (clobber (reg:P CA_REGNO))]
12209   ""
12210   "#"
12211   ""
12212   [(parallel [(set (match_dup 5)
12213                    (neg:P (match_dup 4)))
12214               (set (reg:P CA_REGNO)
12215                    (eq:P (match_dup 4)
12216                          (const_int 0)))])
12217    (parallel [(set (match_dup 0)
12218                    (plus:P (plus:P (match_dup 3)
12219                                    (reg:P CA_REGNO))
12220                            (const_int -1)))
12221               (clobber (reg:P CA_REGNO))])]
12223   operands[4] = rs6000_emit_eqne (<MODE>mode,
12224                                   operands[1], operands[2], operands[4]);
12226   if (GET_CODE (operands[5]) == SCRATCH)
12227     operands[5] = gen_reg_rtx (<MODE>mode);
12229   [(set (attr "length")
12230         (if_then_else (match_test "operands[2] == const0_rtx")
12231                       (const_string "8")
12232                       (const_string "12")))])
12234 (define_insn_and_split "*eqsi3_ext<mode>"
12235   [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
12236         (eq:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
12237                   (match_operand:SI 2 "scc_eq_operand" "rKLI")))
12238    (clobber (match_scratch:SI 3 "=r"))
12239    (clobber (match_scratch:SI 4 "=r"))]
12240   ""
12241   "#"
12242   ""
12243   [(set (match_dup 4)
12244         (clz:SI (match_dup 3)))
12245    (set (match_dup 0)
12246         (zero_extend:EXTSI
12247           (lshiftrt:SI (match_dup 4)
12248                        (const_int 5))))]
12250   operands[3] = rs6000_emit_eqne (SImode,
12251                                   operands[1], operands[2], operands[3]);
12253   if (GET_CODE (operands[4]) == SCRATCH)
12254     operands[4] = gen_reg_rtx (SImode);
12256   [(set (attr "length")
12257         (if_then_else (match_test "operands[2] == const0_rtx")
12258                       (const_string "8")
12259                       (const_string "12")))])
12261 (define_insn_and_split "*nesi3_ext<mode>"
12262   [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
12263         (ne:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
12264                   (match_operand:SI 2 "scc_eq_operand" "rKLI")))
12265    (clobber (match_scratch:SI 3 "=r"))
12266    (clobber (match_scratch:SI 4 "=r"))
12267    (clobber (match_scratch:EXTSI 5 "=r"))]
12268   "!TARGET_ISEL"
12269   "#"
12270   "&& 1"
12271   [(set (match_dup 4)
12272         (clz:SI (match_dup 3)))
12273    (set (match_dup 5)
12274         (zero_extend:EXTSI
12275           (lshiftrt:SI (match_dup 4)
12276                        (const_int 5))))
12277    (set (match_dup 0)
12278         (xor:EXTSI (match_dup 5)
12279                    (const_int 1)))]
12281   operands[3] = rs6000_emit_eqne (SImode,
12282                                   operands[1], operands[2], operands[3]);
12284   if (GET_CODE (operands[4]) == SCRATCH)
12285     operands[4] = gen_reg_rtx (SImode);
12286   if (GET_CODE (operands[5]) == SCRATCH)
12287     operands[5] = gen_reg_rtx (<MODE>mode);
12289   [(set (attr "length")
12290         (if_then_else (match_test "operands[2] == const0_rtx")
12291                       (const_string "12")
12292                       (const_string "16")))])
12294 ;; Conditional branches.
12295 ;; These either are a single bc insn, or a bc around a b.
12297 (define_insn "*cbranch"
12298   [(set (pc)
12299         (if_then_else (match_operator 1 "branch_comparison_operator"
12300                                       [(match_operand 2 "cc_reg_operand" "y")
12301                                        (const_int 0)])
12302                       (label_ref (match_operand 0))
12303                       (pc)))]
12304   ""
12306   return output_cbranch (operands[1], "%l0", 0, insn);
12308   [(set_attr "type" "branch")
12309    (set (attr "length")
12310         (if_then_else (and (ge (minus (match_dup 0) (pc))
12311                                (const_int -32768))
12312                            (lt (minus (match_dup 0) (pc))
12313                                (const_int 32764)))
12314                       (const_int 4)
12315                       (const_int 8)))])
12317 ;; Conditional return.
12318 (define_insn "*creturn"
12319   [(set (pc)
12320         (if_then_else (match_operator 0 "branch_comparison_operator"
12321                                       [(match_operand 1 "cc_reg_operand" "y")
12322                                        (const_int 0)])
12323                       (any_return)
12324                       (pc)))]
12325   "<return_pred>"
12327   return output_cbranch (operands[0], NULL, 0, insn);
12329   [(set_attr "type" "jmpreg")])
12331 ;; Logic on condition register values.
12333 ; This pattern matches things like
12334 ; (set (reg:CCEQ 68) (compare:CCEQ (ior:SI (gt:SI (reg:CCFP 68) (const_int 0))
12335 ;                                          (eq:SI (reg:CCFP 68) (const_int 0)))
12336 ;                                  (const_int 1)))
12337 ; which are generated by the branch logic.
12338 ; Prefer destructive operations where BT = BB (for crXX BT,BA,BB)
12340 (define_insn "cceq_ior_compare"
12341   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12342         (compare:CCEQ (match_operator:SI 1 "boolean_operator"
12343                         [(match_operator:SI 2
12344                                       "branch_positive_comparison_operator"
12345                                       [(match_operand 3
12346                                                       "cc_reg_operand" "y,y")
12347                                        (const_int 0)])
12348                          (match_operator:SI 4
12349                                       "branch_positive_comparison_operator"
12350                                       [(match_operand 5
12351                                                       "cc_reg_operand" "0,y")
12352                                        (const_int 0)])])
12353                       (const_int 1)))]
12354   ""
12355   "cr%q1 %E0,%j2,%j4"
12356   [(set_attr "type" "cr_logical")
12357    (set_attr "cr_logical_3op" "no,yes")])
12359 ; Why is the constant -1 here, but 1 in the previous pattern?
12360 ; Because ~1 has all but the low bit set.
12361 (define_insn "cceq_ior_compare_complement"
12362   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12363         (compare:CCEQ (match_operator:SI 1 "boolean_operator"
12364                         [(not:SI (match_operator:SI 2
12365                                       "branch_positive_comparison_operator"
12366                                       [(match_operand 3
12367                                                       "cc_reg_operand" "y,y")
12368                                        (const_int 0)]))
12369                          (match_operator:SI 4
12370                                 "branch_positive_comparison_operator"
12371                                 [(match_operand 5
12372                                                 "cc_reg_operand" "0,y")
12373                                  (const_int 0)])])
12374                       (const_int -1)))]
12375   ""
12376   "cr%q1 %E0,%j2,%j4"
12377   [(set_attr "type" "cr_logical")
12378    (set_attr "cr_logical_3op" "no,yes")])
12380 (define_insn "*cceq_rev_compare"
12381   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12382         (compare:CCEQ (match_operator:SI 1
12383                                       "branch_positive_comparison_operator"
12384                                       [(match_operand 2
12385                                                       "cc_reg_operand" "0,y")
12386                                        (const_int 0)])
12387                       (const_int 0)))]
12388   ""
12389   "crnot %E0,%j1"
12390   [(set_attr "type" "cr_logical")
12391    (set_attr "cr_logical_3op" "no,yes")])
12393 ;; If we are comparing the result of two comparisons, this can be done
12394 ;; using creqv or crxor.
12396 (define_insn_and_split ""
12397   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y")
12398         (compare:CCEQ (match_operator 1 "branch_comparison_operator"
12399                               [(match_operand 2 "cc_reg_operand" "y")
12400                                (const_int 0)])
12401                       (match_operator 3 "branch_comparison_operator"
12402                               [(match_operand 4 "cc_reg_operand" "y")
12403                                (const_int 0)])))]
12404   ""
12405   "#"
12406   ""
12407   [(set (match_dup 0) (compare:CCEQ (xor:SI (match_dup 1) (match_dup 3))
12408                                     (match_dup 5)))]
12410   int positive_1, positive_2;
12412   positive_1 = branch_positive_comparison_operator (operands[1],
12413                                                     GET_MODE (operands[1]));
12414   positive_2 = branch_positive_comparison_operator (operands[3],
12415                                                     GET_MODE (operands[3]));
12417   if (! positive_1)
12418     operands[1] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[2]),
12419                                                             GET_CODE (operands[1])),
12420                                   SImode,
12421                                   operands[2], const0_rtx);
12422   else if (GET_MODE (operands[1]) != SImode)
12423     operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), SImode,
12424                                   operands[2], const0_rtx);
12426   if (! positive_2)
12427     operands[3] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[4]),
12428                                                             GET_CODE (operands[3])),
12429                                   SImode,
12430                                   operands[4], const0_rtx);
12431   else if (GET_MODE (operands[3]) != SImode)
12432     operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SImode,
12433                                   operands[4], const0_rtx);
12435   if (positive_1 == positive_2)
12436     {
12437       operands[1] = gen_rtx_NOT (SImode, operands[1]);
12438       operands[5] = constm1_rtx;
12439     }
12440   else
12441     {
12442       operands[5] = const1_rtx;
12443     }
12446 ;; Unconditional branch and return.
12448 (define_insn "jump"
12449   [(set (pc)
12450         (label_ref (match_operand 0)))]
12451   ""
12452   "b %l0"
12453   [(set_attr "type" "branch")])
12455 (define_insn "<return_str>return"
12456   [(any_return)]
12457   "<return_pred>"
12458   "blr"
12459   [(set_attr "type" "jmpreg")])
12461 (define_expand "indirect_jump"
12462   [(set (pc) (match_operand 0 "register_operand"))]
12463  ""
12465   if (!rs6000_speculate_indirect_jumps) {
12466     rtx ccreg = gen_reg_rtx (CCmode);
12467     if (Pmode == DImode)
12468       emit_jump_insn (gen_indirect_jumpdi_nospec (operands[0], ccreg));
12469     else
12470       emit_jump_insn (gen_indirect_jumpsi_nospec (operands[0], ccreg));
12471     DONE;
12472   }
12475 (define_insn "*indirect_jump<mode>"
12476   [(set (pc)
12477         (match_operand:P 0 "register_operand" "c,*l"))]
12478   "rs6000_speculate_indirect_jumps"
12479   "b%T0"
12480   [(set_attr "type" "jmpreg")])
12482 (define_insn "indirect_jump<mode>_nospec"
12483   [(set (pc) (match_operand:P 0 "register_operand" "c,*l"))
12484    (clobber (match_operand:CC 1 "cc_reg_operand" "=y,y"))]
12485   "!rs6000_speculate_indirect_jumps"
12486   "crset %E1\;beq%T0- %1\;b $"
12487   [(set_attr "type" "jmpreg")
12488    (set_attr "length" "12")])
12490 ;; Table jump for switch statements:
12491 (define_expand "tablejump"
12492   [(use (match_operand 0))
12493    (use (label_ref (match_operand 1)))]
12494   ""
12496   if (rs6000_speculate_indirect_jumps)
12497     {
12498       if (TARGET_32BIT)
12499         emit_jump_insn (gen_tablejumpsi (operands[0], operands[1]));
12500       else
12501         emit_jump_insn (gen_tablejumpdi (operands[0], operands[1]));
12502     }
12503   else
12504     {
12505       rtx ccreg = gen_reg_rtx (CCmode);
12506       rtx jump;
12507       if (TARGET_32BIT)
12508         jump = gen_tablejumpsi_nospec (operands[0], operands[1], ccreg);
12509       else
12510         jump = gen_tablejumpdi_nospec (operands[0], operands[1], ccreg);
12511       emit_jump_insn (jump);
12512     }
12513   DONE;
12516 (define_expand "tablejumpsi"
12517   [(set (match_dup 3)
12518         (plus:SI (match_operand:SI 0)
12519                  (match_dup 2)))
12520    (parallel [(set (pc)
12521                    (match_dup 3))
12522               (use (label_ref (match_operand 1)))])]
12523   "TARGET_32BIT && rs6000_speculate_indirect_jumps"
12525   operands[0] = force_reg (SImode, operands[0]);
12526   operands[2] = force_reg (SImode, gen_rtx_LABEL_REF (SImode, operands[1]));
12527   operands[3] = gen_reg_rtx (SImode);
12530 (define_expand "tablejumpsi_nospec"
12531   [(set (match_dup 4)
12532         (plus:SI (match_operand:SI 0)
12533                  (match_dup 3)))
12534    (parallel [(set (pc)
12535                    (match_dup 4))
12536               (use (label_ref (match_operand 1)))
12537               (clobber (match_operand 2))])]
12538   "TARGET_32BIT && !rs6000_speculate_indirect_jumps"
12540   operands[0] = force_reg (SImode, operands[0]);
12541   operands[3] = force_reg (SImode, gen_rtx_LABEL_REF (SImode, operands[1]));
12542   operands[4] = gen_reg_rtx (SImode);
12545 (define_expand "tablejumpdi"
12546   [(set (match_dup 4)
12547         (sign_extend:DI (match_operand:SI 0 "lwa_operand")))
12548    (set (match_dup 3)
12549         (plus:DI (match_dup 4)
12550                  (match_dup 2)))
12551    (parallel [(set (pc)
12552                    (match_dup 3))
12553               (use (label_ref (match_operand 1)))])]
12554   "TARGET_64BIT && rs6000_speculate_indirect_jumps"
12556   operands[2] = force_reg (DImode, gen_rtx_LABEL_REF (DImode, operands[1]));
12557   operands[3] = gen_reg_rtx (DImode);
12558   operands[4] = gen_reg_rtx (DImode);
12561 (define_expand "tablejumpdi_nospec"
12562   [(set (match_dup 5)
12563         (sign_extend:DI (match_operand:SI 0 "lwa_operand")))
12564    (set (match_dup 4)
12565         (plus:DI (match_dup 5)
12566                  (match_dup 3)))
12567    (parallel [(set (pc)
12568                    (match_dup 4))
12569               (use (label_ref (match_operand 1)))
12570               (clobber (match_operand 2))])]
12571   "TARGET_64BIT && !rs6000_speculate_indirect_jumps"
12573   operands[3] = force_reg (DImode, gen_rtx_LABEL_REF (DImode, operands[1]));
12574   operands[4] = gen_reg_rtx (DImode);
12575   operands[5] = gen_reg_rtx (DImode);
12578 (define_insn "*tablejump<mode>_internal1"
12579   [(set (pc)
12580         (match_operand:P 0 "register_operand" "c,*l"))
12581    (use (label_ref (match_operand 1)))]
12582   "rs6000_speculate_indirect_jumps"
12583   "b%T0"
12584   [(set_attr "type" "jmpreg")])
12586 (define_insn "*tablejump<mode>_internal1_nospec"
12587   [(set (pc)
12588         (match_operand:P 0 "register_operand" "c,*l"))
12589    (use (label_ref (match_operand 1)))
12590    (clobber (match_operand:CC 2 "cc_reg_operand" "=y,y"))]
12591   "!rs6000_speculate_indirect_jumps"
12592   "crset %E2\;beq%T0- %2\;b $"
12593   [(set_attr "type" "jmpreg")
12594    (set_attr "length" "12")])
12596 (define_insn "nop"
12597   [(unspec [(const_int 0)] UNSPEC_NOP)]
12598   ""
12599   "nop")
12601 (define_insn "group_ending_nop"
12602   [(unspec [(const_int 0)] UNSPEC_GRP_END_NOP)]
12603   ""
12605   if (rs6000_tune == PROCESSOR_POWER6)
12606     return "ori 1,1,0";
12607   return "ori 2,2,0";
12610 (define_insn "speculation_barrier"
12611   [(unspec_volatile:BLK [(const_int 0)] UNSPECV_SPEC_BARRIER)]
12612   ""
12613   "ori 31,31,0")
12615 ;; Define the subtract-one-and-jump insns, starting with the template
12616 ;; so loop.c knows what to generate.
12618 (define_expand "doloop_end"
12619   [(use (match_operand 0))      ; loop pseudo
12620    (use (match_operand 1))]     ; label
12621   ""
12623   if (TARGET_64BIT)
12624     {
12625       if (GET_MODE (operands[0]) != DImode)
12626         FAIL;
12627       emit_jump_insn (gen_ctrdi (operands[0], operands[1]));
12628     }
12629   else
12630     {
12631       if (GET_MODE (operands[0]) != SImode)
12632         FAIL;
12633       emit_jump_insn (gen_ctrsi (operands[0], operands[1]));
12634     }
12635   DONE;
12638 (define_expand "ctr<mode>"
12639   [(parallel [(set (pc)
12640                    (if_then_else (ne (match_operand:P 0 "register_operand")
12641                                      (const_int 1))
12642                                  (label_ref (match_operand 1))
12643                                  (pc)))
12644               (set (match_dup 0)
12645                    (plus:P (match_dup 0)
12646                             (const_int -1)))
12647               (clobber (match_scratch:CC 2))
12648               (clobber (match_scratch:P 3))])]
12649   ""
12650   "")
12652 ;; We need to be able to do this for any operand, including MEM, or we
12653 ;; will cause reload to blow up since we don't allow output reloads on
12654 ;; JUMP_INSNs.
12655 ;; For the length attribute to be calculated correctly, the
12656 ;; label MUST be operand 0.
12657 ;; rs6000_legitimate_combined_insn prevents combine creating any of
12658 ;; the ctr<mode> insns.
12660 (define_code_iterator eqne [eq ne])
12661 (define_code_attr bd [(eq "bdz") (ne "bdnz")])
12662 (define_code_attr bd_neg [(eq "bdnz") (ne "bdz")])
12664 (define_insn "<bd>_<mode>"
12665   [(set (pc)
12666         (if_then_else (eqne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12667                           (const_int 1))
12668                       (label_ref (match_operand 0))
12669                       (pc)))
12670    (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
12671         (plus:P (match_dup 1)
12672                 (const_int -1)))
12673    (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
12674    (clobber (match_scratch:P 4 "=X,X,&r,r"))]
12675   ""
12677   if (which_alternative != 0)
12678     return "#";
12679   else if (get_attr_length (insn) == 4)
12680     return "<bd> %l0";
12681   else
12682     return "<bd_neg> $+8\;b %l0";
12684   [(set_attr "type" "branch")
12685    (set_attr_alternative "length"
12686      [(if_then_else (and (ge (minus (match_dup 0) (pc))
12687                              (const_int -32768))
12688                          (lt (minus (match_dup 0) (pc))
12689                              (const_int 32764)))
12690                     (const_int 4)
12691                     (const_int 8))
12692       (const_string "16")
12693       (const_string "20")
12694       (const_string "20")])])
12696 ;; Now the splitter if we could not allocate the CTR register
12697 (define_split
12698   [(set (pc)
12699         (if_then_else (match_operator 2 "comparison_operator"
12700                                       [(match_operand:P 1 "gpc_reg_operand")
12701                                        (const_int 1)])
12702                       (match_operand 5)
12703                       (match_operand 6)))
12704    (set (match_operand:P 0 "nonimmediate_operand")
12705         (plus:P (match_dup 1)
12706                 (const_int -1)))
12707    (clobber (match_scratch:CC 3))
12708    (clobber (match_scratch:P 4))]
12709   "reload_completed"
12710   [(set (pc)
12711         (if_then_else (match_dup 7)
12712                       (match_dup 5)
12713                       (match_dup 6)))]
12715   operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[2]), VOIDmode, operands[3],
12716                                 const0_rtx);
12717   emit_insn (gen_rtx_SET (operands[3],
12718                           gen_rtx_COMPARE (CCmode, operands[1], const1_rtx)));
12719   if (gpc_reg_operand (operands[0], <MODE>mode))
12720     emit_insn (gen_add<mode>3 (operands[0], operands[1], constm1_rtx));
12721   else
12722     {
12723       emit_insn (gen_add<mode>3 (operands[4], operands[1], constm1_rtx));
12724       emit_move_insn (operands[0], operands[4]);
12725     } 
12726     /* No DONE so branch comes from the pattern.  */
12729 ;; patterns for bdnzt/bdnzf/bdzt/bdzf
12730 ;; Note that in the case of long branches we have to decompose this into
12731 ;; bdnz+bc. This is because bdnzt has an implied AND between the ctr condition
12732 ;; and the CR bit, which means there is no way to conveniently invert the
12733 ;; comparison as is done with plain bdnz/bdz.
12735 (define_insn "<bd>tf_<mode>"
12736   [(set (pc)
12737         (if_then_else
12738           (and
12739              (eqne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12740                    (const_int 1))
12741              (match_operator 3 "branch_comparison_operator"
12742                       [(match_operand 4 "cc_reg_operand" "y,y,y,y")
12743                        (const_int 0)]))
12744           (label_ref (match_operand 0))
12745           (pc)))
12746    (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
12747         (plus:P (match_dup 1)
12748                 (const_int -1)))
12749    (clobber (match_scratch:P 5 "=X,X,&r,r"))
12750    (clobber (match_scratch:CC 6 "=X,&y,&y,&y"))
12751    (clobber (match_scratch:CCEQ 7 "=X,&y,&y,&y"))]
12752   ""
12754   if (which_alternative != 0)
12755     return "#";
12756   else if (get_attr_length (insn) == 4)
12757     {
12758       if (branch_positive_comparison_operator (operands[3],
12759                                                GET_MODE (operands[3])))
12760         return "<bd>t %j3,%l0";
12761       else
12762         return "<bd>f %j3,%l0";
12763     }
12764   else
12765     {
12766       static char seq[96];
12767       char *bcs = output_cbranch (operands[3], "$+8", 1, insn);
12768       sprintf(seq, "<bd_neg> $+12\;%s;b %%l0", bcs);
12769       return seq;
12770     }
12772   [(set_attr "type" "branch")
12773    (set_attr_alternative "length"
12774      [(if_then_else (and (ge (minus (match_dup 0) (pc))
12775                              (const_int -32768))
12776                          (lt (minus (match_dup 0) (pc))
12777                              (const_int 32764)))
12778                     (const_int 4)
12779                     (const_int 8))
12780       (const_string "16")
12781       (const_string "20")
12782       (const_string "20")])])
12784 ;; Now the splitter if we could not allocate the CTR register
12785 (define_split
12786   [(set (pc)
12787         (if_then_else
12788           (and
12789              (match_operator 1 "comparison_operator"
12790                              [(match_operand:P 0 "gpc_reg_operand")
12791                               (const_int 1)])
12792              (match_operator 3 "branch_comparison_operator"
12793                       [(match_operand 2 "cc_reg_operand")
12794                        (const_int 0)]))
12795           (match_operand 4)
12796           (match_operand 5)))
12797    (set (match_operand:P 6 "int_reg_operand")
12798         (plus:P (match_dup 0)
12799                 (const_int -1)))
12800    (clobber (match_scratch:P 7))
12801    (clobber (match_scratch:CC 8))
12802    (clobber (match_scratch:CCEQ 9))]
12803   "reload_completed"
12804 [(pc)]
12806   rtx ctr = operands[0];
12807   rtx ctrcmp = operands[1];
12808   rtx ccin = operands[2];
12809   rtx cccmp = operands[3];
12810   rtx dst1 = operands[4];
12811   rtx dst2 = operands[5];
12812   rtx ctrout = operands[6];
12813   rtx ctrtmp = operands[7];
12814   enum rtx_code cmpcode = GET_CODE (ctrcmp);
12815   bool ispos = branch_positive_comparison_operator (ctrcmp, GET_MODE (ctrcmp));
12816   if (!ispos)
12817     cmpcode = reverse_condition (cmpcode);
12818   /* Generate crand/crandc here.  */
12819   emit_insn (gen_rtx_SET (operands[8],
12820                           gen_rtx_COMPARE (CCmode, ctr, const1_rtx)));
12821   rtx ctrcmpcc = gen_rtx_fmt_ee (cmpcode, SImode, operands[8], const0_rtx);
12823   rtx andexpr = gen_rtx_AND (SImode, ctrcmpcc, cccmp);
12824   if (ispos)
12825      emit_insn (gen_cceq_ior_compare (operands[9], andexpr, ctrcmpcc,
12826                                       operands[8], cccmp, ccin));
12827   else
12828      emit_insn (gen_cceq_ior_compare_complement (operands[9], andexpr, ctrcmpcc,
12829                                                  operands[8], cccmp, ccin));
12830   if (gpc_reg_operand (operands[0], <MODE>mode))
12831      emit_insn (gen_add<mode>3 (ctrout, ctr, constm1_rtx));
12832   else
12833     {
12834       emit_insn (gen_add<mode>3 (ctrtmp, ctr, constm1_rtx));
12835       emit_move_insn (ctrout, ctrtmp);
12836     }
12837   rtx cmp = gen_rtx_EQ (CCEQmode, operands[9], const0_rtx);
12838   emit_jump_insn (gen_rtx_SET (pc_rtx,
12839                                gen_rtx_IF_THEN_ELSE (VOIDmode, cmp,
12840                                                      dst1, dst2)));
12841   DONE;
12845 (define_insn "trap"
12846   [(trap_if (const_int 1) (const_int 0))]
12847   ""
12848   "trap"
12849   [(set_attr "type" "trap")])
12851 (define_expand "ctrap<mode>4"
12852   [(trap_if (match_operator 0 "ordered_comparison_operator"
12853                             [(match_operand:GPR 1 "register_operand")
12854                              (match_operand:GPR 2 "reg_or_short_operand")])
12855             (match_operand 3 "zero_constant" ""))]
12856   ""
12857   "")
12859 (define_insn ""
12860   [(trap_if (match_operator 0 "ordered_comparison_operator"
12861                             [(match_operand:GPR 1 "register_operand" "r")
12862                              (match_operand:GPR 2 "reg_or_short_operand" "rI")])
12863             (const_int 0))]
12864   ""
12865   "t<wd>%V0%I2 %1,%2"
12866   [(set_attr "type" "trap")])
12868 ;; Insns related to generating the function prologue and epilogue.
12870 (define_expand "prologue"
12871   [(use (const_int 0))]
12872   ""
12874   rs6000_emit_prologue ();
12875   if (!TARGET_SCHED_PROLOG)
12876     emit_insn (gen_blockage ());
12877   DONE;
12880 (define_insn "*movesi_from_cr_one"
12881   [(match_parallel 0 "mfcr_operation"
12882                    [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
12883                          (unspec:SI [(match_operand:CC 2 "cc_reg_operand" "y")
12884                                      (match_operand 3 "immediate_operand" "n")]
12885                           UNSPEC_MOVESI_FROM_CR))])]
12886   "TARGET_MFCRF"
12888   int mask = 0;
12889   int i;
12890   for (i = 0; i < XVECLEN (operands[0], 0); i++)
12891   {
12892     mask = INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
12893     operands[4] = GEN_INT (mask);
12894     output_asm_insn ("mfcr %1,%4", operands);
12895   }
12896   return "";
12898   [(set_attr "type" "mfcrf")])
12900 ;; Don't include the volatile CRs since their values are not used wrt CR save
12901 ;; in the prologue and doing so prevents shrink-wrapping because we can't move the
12902 ;; prologue past an insn (early exit test) that defines a register used in the
12903 ;; prologue.
12904 (define_insn "prologue_movesi_from_cr"
12905   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
12906         (unspec:SI [(reg:CC CR2_REGNO) (reg:CC CR3_REGNO)
12907                     (reg:CC CR4_REGNO)]
12908                    UNSPEC_MOVESI_FROM_CR))]
12909   ""
12910   "mfcr %0"
12911   [(set_attr "type" "mfcr")])
12913 (define_insn "*crsave"
12914   [(match_parallel 0 "crsave_operation"
12915                    [(set (match_operand:SI 1 "memory_operand" "=m")
12916                          (match_operand:SI 2 "gpc_reg_operand" "r"))])]
12917   ""
12918   "stw %2,%1"
12919   [(set_attr "type" "store")])
12921 (define_insn "*stmw"
12922   [(match_parallel 0 "stmw_operation"
12923                    [(set (match_operand:SI 1 "memory_operand" "=m")
12924                          (match_operand:SI 2 "gpc_reg_operand" "r"))])]
12925   "TARGET_MULTIPLE"
12926   "stmw %2,%1"
12927   [(set_attr "type" "store")
12928    (set_attr "update" "yes")
12929    (set_attr "indexed" "yes")])
12931 ; The following comment applies to:
12932 ;     save_gpregs_*
12933 ;     save_fpregs_*
12934 ;     restore_gpregs*
12935 ;     return_and_restore_gpregs*
12936 ;     return_and_restore_fpregs*
12937 ;     return_and_restore_fpregs_aix*
12939 ; The out-of-line save / restore functions expects one input argument.
12940 ; Since those are not standard call_insn's, we must avoid using
12941 ; MATCH_OPERAND for that argument. That way the register rename
12942 ; optimization will not try to rename this register.
12943 ; Each pattern is repeated for each possible register number used in 
12944 ; various ABIs (r11, r1, and for some functions r12)
12946 (define_insn "*save_gpregs_<mode>_r11"
12947   [(match_parallel 0 "any_parallel_operand"
12948                    [(clobber (reg:P LR_REGNO))
12949                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
12950                     (use (reg:P 11))
12951                     (set (match_operand:P 2 "memory_operand" "=m")
12952                          (match_operand:P 3 "gpc_reg_operand" "r"))])]
12953   ""
12954   "bl %1"
12955   [(set_attr "type" "branch")])
12957 (define_insn "*save_gpregs_<mode>_r12"
12958   [(match_parallel 0 "any_parallel_operand"
12959                    [(clobber (reg:P LR_REGNO))
12960                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
12961                     (use (reg:P 12))
12962                     (set (match_operand:P 2 "memory_operand" "=m")
12963                          (match_operand:P 3 "gpc_reg_operand" "r"))])]
12964   ""
12965   "bl %1"
12966   [(set_attr "type" "branch")])
12968 (define_insn "*save_gpregs_<mode>_r1"
12969   [(match_parallel 0 "any_parallel_operand"
12970                    [(clobber (reg:P LR_REGNO))
12971                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
12972                     (use (reg:P 1))
12973                     (set (match_operand:P 2 "memory_operand" "=m")
12974                          (match_operand:P 3 "gpc_reg_operand" "r"))])]
12975   ""
12976   "bl %1"
12977   [(set_attr "type" "branch")])
12979 (define_insn "*save_fpregs_<mode>_r11"
12980   [(match_parallel 0 "any_parallel_operand"
12981                    [(clobber (reg:P LR_REGNO))
12982                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
12983                     (use (reg:P 11))
12984                     (set (match_operand:DF 2 "memory_operand" "=m")
12985                          (match_operand:DF 3 "gpc_reg_operand" "d"))])]
12986   ""
12987   "bl %1"
12988   [(set_attr "type" "branch")])
12990 (define_insn "*save_fpregs_<mode>_r12"
12991   [(match_parallel 0 "any_parallel_operand"
12992                    [(clobber (reg:P LR_REGNO))
12993                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
12994                     (use (reg:P 12))
12995                     (set (match_operand:DF 2 "memory_operand" "=m")
12996                          (match_operand:DF 3 "gpc_reg_operand" "d"))])]
12997   ""
12998   "bl %1"
12999   [(set_attr "type" "branch")])
13001 (define_insn "*save_fpregs_<mode>_r1"
13002   [(match_parallel 0 "any_parallel_operand"
13003                    [(clobber (reg:P LR_REGNO))
13004                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
13005                     (use (reg:P 1))
13006                     (set (match_operand:DF 2 "memory_operand" "=m")
13007                          (match_operand:DF 3 "gpc_reg_operand" "d"))])]
13008   ""
13009   "bl %1"
13010   [(set_attr "type" "branch")])
13012 ; This is to explain that changes to the stack pointer should
13013 ; not be moved over loads from or stores to stack memory.
13014 (define_insn "stack_tie"
13015   [(match_parallel 0 "tie_operand"
13016                    [(set (mem:BLK (reg 1)) (const_int 0))])]
13017   ""
13018   ""
13019   [(set_attr "length" "0")])
13021 ; Some 32-bit ABIs do not have a red zone, so the stack deallocation has to
13022 ; stay behind all restores from the stack, it cannot be reordered to before
13023 ; one.  See PR77687.  This insn is an add or mr, and a memory clobber.
13024 (define_insn "stack_restore_tie"
13025   [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
13026         (plus:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
13027                  (match_operand:SI 2 "reg_or_cint_operand" "O,rI")))
13028    (set (mem:BLK (scratch)) (const_int 0))]
13029   "TARGET_32BIT"
13030   "@
13031    mr %0,%1
13032    add%I2 %0,%1,%2"
13033   [(set_attr "type" "*,add")])
13035 (define_expand "epilogue"
13036   [(use (const_int 0))]
13037   ""
13039   if (!TARGET_SCHED_PROLOG)
13040     emit_insn (gen_blockage ());
13041   rs6000_emit_epilogue (FALSE);
13042   DONE;
13045 ; On some processors, doing the mtcrf one CC register at a time is
13046 ; faster (like on the 604e).  On others, doing them all at once is
13047 ; faster; for instance, on the 601 and 750.
13049 (define_expand "movsi_to_cr_one"
13050   [(set (match_operand:CC 0 "cc_reg_operand")
13051         (unspec:CC [(match_operand:SI 1 "gpc_reg_operand")
13052                     (match_dup 2)] UNSPEC_MOVESI_TO_CR))]
13053   ""
13054   "operands[2] = GEN_INT (1 << (75 - REGNO (operands[0])));")
13056 (define_insn "*movsi_to_cr"
13057   [(match_parallel 0 "mtcrf_operation"
13058                    [(set (match_operand:CC 1 "cc_reg_operand" "=y")
13059                          (unspec:CC [(match_operand:SI 2 "gpc_reg_operand" "r")
13060                                      (match_operand 3 "immediate_operand" "n")]
13061                                     UNSPEC_MOVESI_TO_CR))])]
13062  ""
13064   int mask = 0;
13065   int i;
13066   for (i = 0; i < XVECLEN (operands[0], 0); i++)
13067     mask |= INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
13068   operands[4] = GEN_INT (mask);
13069   return "mtcrf %4,%2";
13071   [(set_attr "type" "mtcr")])
13073 (define_insn "*mtcrfsi"
13074   [(set (match_operand:CC 0 "cc_reg_operand" "=y")
13075         (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
13076                     (match_operand 2 "immediate_operand" "n")]
13077                    UNSPEC_MOVESI_TO_CR))]
13078   "GET_CODE (operands[0]) == REG
13079    && CR_REGNO_P (REGNO (operands[0]))
13080    && GET_CODE (operands[2]) == CONST_INT
13081    && INTVAL (operands[2]) == 1 << (75 - REGNO (operands[0]))"
13082   "mtcrf %R0,%1"
13083   [(set_attr "type" "mtcr")])
13085 ; The load-multiple instructions have similar properties.
13086 ; Note that "load_multiple" is a name known to the machine-independent
13087 ; code that actually corresponds to the PowerPC load-string.
13089 (define_insn "*lmw"
13090   [(match_parallel 0 "lmw_operation"
13091                    [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
13092                          (match_operand:SI 2 "memory_operand" "m"))])]
13093   "TARGET_MULTIPLE"
13094   "lmw %1,%2"
13095   [(set_attr "type" "load")
13096    (set_attr "update" "yes")
13097    (set_attr "indexed" "yes")
13098    (set_attr "cell_micro" "always")])
13100 ; FIXME: "any_parallel_operand" is a bit flexible...
13102 ; The following comment applies to:
13103 ;     save_gpregs_*
13104 ;     save_fpregs_*
13105 ;     restore_gpregs*
13106 ;     return_and_restore_gpregs*
13107 ;     return_and_restore_fpregs*
13108 ;     return_and_restore_fpregs_aix*
13110 ; The out-of-line save / restore functions expects one input argument.
13111 ; Since those are not standard call_insn's, we must avoid using
13112 ; MATCH_OPERAND for that argument. That way the register rename
13113 ; optimization will not try to rename this register.
13114 ; Each pattern is repeated for each possible register number used in 
13115 ; various ABIs (r11, r1, and for some functions r12)
13117 (define_insn "*restore_gpregs_<mode>_r11"
13118  [(match_parallel 0 "any_parallel_operand"
13119                   [(clobber (reg:P LR_REGNO))
13120                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13121                    (use (reg:P 11))
13122                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
13123                         (match_operand:P 3 "memory_operand" "m"))])]
13124  ""
13125  "bl %1"
13126  [(set_attr "type" "branch")])
13128 (define_insn "*restore_gpregs_<mode>_r12"
13129  [(match_parallel 0 "any_parallel_operand"
13130                   [(clobber (reg:P LR_REGNO))
13131                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13132                    (use (reg:P 12))
13133                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
13134                         (match_operand:P 3 "memory_operand" "m"))])]
13135  ""
13136  "bl %1"
13137  [(set_attr "type" "branch")])
13139 (define_insn "*restore_gpregs_<mode>_r1"
13140  [(match_parallel 0 "any_parallel_operand"
13141                   [(clobber (reg:P LR_REGNO))
13142                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13143                    (use (reg:P 1))
13144                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
13145                         (match_operand:P 3 "memory_operand" "m"))])]
13146  ""
13147  "bl %1"
13148  [(set_attr "type" "branch")])
13150 (define_insn "*return_and_restore_gpregs_<mode>_r11"
13151  [(match_parallel 0 "any_parallel_operand"
13152                   [(return)
13153                    (clobber (reg:P LR_REGNO))
13154                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13155                    (use (reg:P 11))
13156                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
13157                         (match_operand:P 3 "memory_operand" "m"))])]
13158  ""
13159  "b %1"
13160  [(set_attr "type" "branch")])
13162 (define_insn "*return_and_restore_gpregs_<mode>_r12"
13163  [(match_parallel 0 "any_parallel_operand"
13164                   [(return)
13165                    (clobber (reg:P LR_REGNO))
13166                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13167                    (use (reg:P 12))
13168                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
13169                         (match_operand:P 3 "memory_operand" "m"))])]
13170  ""
13171  "b %1"
13172  [(set_attr "type" "branch")])
13174 (define_insn "*return_and_restore_gpregs_<mode>_r1"
13175  [(match_parallel 0 "any_parallel_operand"
13176                   [(return)
13177                    (clobber (reg:P LR_REGNO))
13178                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13179                    (use (reg:P 1))
13180                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
13181                         (match_operand:P 3 "memory_operand" "m"))])]
13182  ""
13183  "b %1"
13184  [(set_attr "type" "branch")])
13186 (define_insn "*return_and_restore_fpregs_<mode>_r11"
13187  [(match_parallel 0 "any_parallel_operand"
13188                   [(return)
13189                    (clobber (reg:P LR_REGNO))
13190                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13191                    (use (reg:P 11))
13192                    (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13193                         (match_operand:DF 3 "memory_operand" "m"))])]
13194  ""
13195  "b %1"
13196  [(set_attr "type" "branch")])
13198 (define_insn "*return_and_restore_fpregs_<mode>_r12"
13199  [(match_parallel 0 "any_parallel_operand"
13200                   [(return)
13201                    (clobber (reg:P LR_REGNO))
13202                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13203                    (use (reg:P 12))
13204                    (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13205                         (match_operand:DF 3 "memory_operand" "m"))])]
13206  ""
13207  "b %1"
13208  [(set_attr "type" "branch")])
13210 (define_insn "*return_and_restore_fpregs_<mode>_r1"
13211  [(match_parallel 0 "any_parallel_operand"
13212                   [(return)
13213                    (clobber (reg:P LR_REGNO))
13214                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13215                    (use (reg:P 1))
13216                    (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13217                         (match_operand:DF 3 "memory_operand" "m"))])]
13218  ""
13219  "b %1"
13220  [(set_attr "type" "branch")])
13222 (define_insn "*return_and_restore_fpregs_aix_<mode>_r11"
13223  [(match_parallel 0 "any_parallel_operand"
13224                   [(return)
13225                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13226                    (use (reg:P 11))
13227                    (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13228                         (match_operand:DF 3 "memory_operand" "m"))])]
13229  ""
13230  "b %1"
13231  [(set_attr "type" "branch")])
13233 (define_insn "*return_and_restore_fpregs_aix_<mode>_r1"
13234  [(match_parallel 0 "any_parallel_operand"
13235                   [(return)
13236                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13237                    (use (reg:P 1))
13238                    (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13239                         (match_operand:DF 3 "memory_operand" "m"))])]
13240  ""
13241  "b %1"
13242  [(set_attr "type" "branch")])
13244 ; This is used in compiling the unwind routines.
13245 (define_expand "eh_return"
13246   [(use (match_operand 0 "general_operand"))]
13247   ""
13249   if (TARGET_32BIT)
13250     emit_insn (gen_eh_set_lr_si (operands[0]));
13251   else
13252     emit_insn (gen_eh_set_lr_di (operands[0]));
13253   DONE;
13256 ; We can't expand this before we know where the link register is stored.
13257 (define_insn "eh_set_lr_<mode>"
13258   [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
13259                     UNSPECV_EH_RR)
13260    (clobber (match_scratch:P 1 "=&b"))]
13261   ""
13262   "#")
13264 (define_split
13265   [(unspec_volatile [(match_operand 0 "register_operand")] UNSPECV_EH_RR)
13266    (clobber (match_scratch 1))]
13267   "reload_completed"
13268   [(const_int 0)]
13270   rs6000_emit_eh_reg_restore (operands[0], operands[1]);
13271   DONE;
13274 (define_insn "prefetch"
13275   [(prefetch (match_operand 0 "indexed_or_indirect_address" "a")
13276              (match_operand:SI 1 "const_int_operand" "n")
13277              (match_operand:SI 2 "const_int_operand" "n"))]
13278   ""
13282   /* dcbtstt, dcbtt and TH=0b10000 support starts with ISA 2.06 (Power7).
13283      AIX does not support the dcbtstt and dcbtt extended mnemonics.
13284      The AIX assembler does not support the three operand form of dcbt
13285      and dcbtst on Power 7 (-mpwr7).  */
13286   int inst_select = INTVAL (operands[2]) || !TARGET_DIRECT_MOVE;
13288   if (REG_P (operands[0]))
13289     {
13290       if (INTVAL (operands[1]) == 0)
13291         return inst_select ? "dcbt 0,%0" : "dcbt 0,%0,16";
13292       else
13293         return inst_select ? "dcbtst 0,%0" : "dcbtst 0,%0,16";
13294     }
13295   else
13296     {
13297       if (INTVAL (operands[1]) == 0)
13298         return inst_select ? "dcbt %a0" : "dcbt %a0,16";
13299       else
13300         return inst_select ? "dcbtst %a0" : "dcbtst %a0,16";
13301     }
13303   [(set_attr "type" "load")])
13305 ;; Handle -fsplit-stack.
13307 (define_expand "split_stack_prologue"
13308   [(const_int 0)]
13309   ""
13311   rs6000_expand_split_stack_prologue ();
13312   DONE;
13315 (define_expand "load_split_stack_limit"
13316   [(set (match_operand 0)
13317         (unspec [(const_int 0)] UNSPEC_STACK_CHECK))]
13318   ""
13320   emit_insn (gen_rtx_SET (operands[0],
13321                           gen_rtx_UNSPEC (Pmode,
13322                                           gen_rtvec (1, const0_rtx),
13323                                           UNSPEC_STACK_CHECK)));
13324   DONE;
13327 (define_insn "load_split_stack_limit_di"
13328   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
13329         (unspec:DI [(const_int 0)] UNSPEC_STACK_CHECK))]
13330   "TARGET_64BIT"
13331   "ld %0,-0x7040(13)"
13332   [(set_attr "type" "load")
13333    (set_attr "update" "no")
13334    (set_attr "indexed" "no")])
13336 (define_insn "load_split_stack_limit_si"
13337   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
13338         (unspec:SI [(const_int 0)] UNSPEC_STACK_CHECK))]
13339   "!TARGET_64BIT"
13340   "lwz %0,-0x7020(2)"
13341   [(set_attr "type" "load")
13342    (set_attr "update" "no")
13343    (set_attr "indexed" "no")])
13345 ;; A return instruction which the middle-end doesn't see.
13346 ;; Use r0 to stop regrename twiddling with lr restore insns emitted
13347 ;; after the call to __morestack.
13348 (define_insn "split_stack_return"
13349   [(unspec_volatile [(reg:SI 0) (reg:SI LR_REGNO)] UNSPECV_SPLIT_STACK_RETURN)]
13350   ""
13351   "blr"
13352   [(set_attr "type" "jmpreg")])
13354 ;; If there are operand 0 bytes available on the stack, jump to
13355 ;; operand 1.
13356 (define_expand "split_stack_space_check"
13357   [(set (match_dup 2)
13358         (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
13359    (set (match_dup 3)
13360         (minus (reg STACK_POINTER_REGNUM)
13361                (match_operand 0)))
13362    (set (match_dup 4) (compare:CCUNS (match_dup 3) (match_dup 2)))
13363    (set (pc) (if_then_else
13364               (geu (match_dup 4) (const_int 0))
13365               (label_ref (match_operand 1))
13366               (pc)))]
13367   ""
13369   rs6000_split_stack_space_check (operands[0], operands[1]);
13370   DONE;
13373 (define_insn "bpermd_<mode>"
13374   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
13375         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "r")
13376                    (match_operand:P 2 "gpc_reg_operand" "r")] UNSPEC_BPERM))]
13377   "TARGET_POPCNTD"
13378   "bpermd %0,%1,%2"
13379   [(set_attr "type" "popcnt")])
13382 ;; Builtin fma support.  Handle 
13383 ;; Note that the conditions for expansion are in the FMA_F iterator.
13385 (define_expand "fma<mode>4"
13386   [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13387         (fma:FMA_F
13388           (match_operand:FMA_F 1 "gpc_reg_operand")
13389           (match_operand:FMA_F 2 "gpc_reg_operand")
13390           (match_operand:FMA_F 3 "gpc_reg_operand")))]
13391   ""
13392   "")
13394 (define_insn "*fma<mode>4_fpr"
13395   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13396         (fma:SFDF
13397           (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>,<Fv2>")
13398           (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13399           (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>")))]
13400   "TARGET_HARD_FLOAT"
13401   "@
13402    fmadd<Ftrad> %0,%1,%2,%3
13403    xsmadda<Fvsx> %x0,%x1,%x2
13404    xsmaddm<Fvsx> %x0,%x1,%x3"
13405   [(set_attr "type" "fp")])
13407 ; Altivec only has fma and nfms.
13408 (define_expand "fms<mode>4"
13409   [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13410         (fma:FMA_F
13411           (match_operand:FMA_F 1 "gpc_reg_operand")
13412           (match_operand:FMA_F 2 "gpc_reg_operand")
13413           (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand"))))]
13414   "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13415   "")
13417 (define_insn "*fms<mode>4_fpr"
13418   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13419         (fma:SFDF
13420          (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
13421          (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13422          (neg:SFDF (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>"))))]
13423   "TARGET_HARD_FLOAT"
13424   "@
13425    fmsub<Ftrad> %0,%1,%2,%3
13426    xsmsuba<Fvsx> %x0,%x1,%x2
13427    xsmsubm<Fvsx> %x0,%x1,%x3"
13428   [(set_attr "type" "fp")])
13430 ;; If signed zeros are ignored, -(a * b - c) = -a * b + c.
13431 (define_expand "fnma<mode>4"
13432   [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13433         (neg:FMA_F
13434           (fma:FMA_F
13435             (match_operand:FMA_F 1 "gpc_reg_operand")
13436             (match_operand:FMA_F 2 "gpc_reg_operand")
13437             (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand")))))]
13438   "!HONOR_SIGNED_ZEROS (<MODE>mode)"
13439   "")
13441 ;; If signed zeros are ignored, -(a * b + c) = -a * b - c.
13442 (define_expand "fnms<mode>4"
13443   [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13444         (neg:FMA_F
13445           (fma:FMA_F
13446             (match_operand:FMA_F 1 "gpc_reg_operand")
13447             (match_operand:FMA_F 2 "gpc_reg_operand")
13448             (match_operand:FMA_F 3 "gpc_reg_operand"))))]
13449   "!HONOR_SIGNED_ZEROS (<MODE>mode) && !VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13450   "")
13452 ; Not an official optab name, but used from builtins.
13453 (define_expand "nfma<mode>4"
13454   [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13455         (neg:FMA_F
13456           (fma:FMA_F
13457             (match_operand:FMA_F 1 "gpc_reg_operand")
13458             (match_operand:FMA_F 2 "gpc_reg_operand")
13459             (match_operand:FMA_F 3 "gpc_reg_operand"))))]
13460   "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13461   "")
13463 (define_insn "*nfma<mode>4_fpr"
13464   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13465         (neg:SFDF
13466          (fma:SFDF
13467           (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
13468           (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13469           (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>"))))]
13470   "TARGET_HARD_FLOAT"
13471   "@
13472    fnmadd<Ftrad> %0,%1,%2,%3
13473    xsnmadda<Fvsx> %x0,%x1,%x2
13474    xsnmaddm<Fvsx> %x0,%x1,%x3"
13475   [(set_attr "type" "fp")])
13477 ; Not an official optab name, but used from builtins.
13478 (define_expand "nfms<mode>4"
13479   [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13480         (neg:FMA_F
13481           (fma:FMA_F
13482             (match_operand:FMA_F 1 "gpc_reg_operand")
13483             (match_operand:FMA_F 2 "gpc_reg_operand")
13484             (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand")))))]
13485   ""
13486   "")
13488 (define_insn "*nfmssf4_fpr"
13489   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13490         (neg:SFDF
13491          (fma:SFDF
13492           (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
13493           (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13494           (neg:SFDF
13495            (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>")))))]
13496   "TARGET_HARD_FLOAT"
13497   "@
13498    fnmsub<Ftrad> %0,%1,%2,%3
13499    xsnmsuba<Fvsx> %x0,%x1,%x2
13500    xsnmsubm<Fvsx> %x0,%x1,%x3"
13501   [(set_attr "type" "fp")])
13504 (define_expand "rs6000_get_timebase"
13505   [(use (match_operand:DI 0 "gpc_reg_operand"))]
13506   ""
13508   if (TARGET_POWERPC64)
13509     emit_insn (gen_rs6000_mftb_di (operands[0]));
13510   else
13511     emit_insn (gen_rs6000_get_timebase_ppc32 (operands[0]));
13512   DONE;
13515 (define_insn "rs6000_get_timebase_ppc32"
13516   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
13517         (unspec_volatile:DI [(const_int 0)] UNSPECV_MFTB))
13518    (clobber (match_scratch:SI 1 "=r"))
13519    (clobber (match_scratch:CC 2 "=y"))]
13520   "!TARGET_POWERPC64"
13522   if (WORDS_BIG_ENDIAN)
13523     if (TARGET_MFCRF)
13524       {
13525         return "mfspr %0,269\;"
13526                "mfspr %L0,268\;"
13527                "mfspr %1,269\;"
13528                "cmpw %2,%0,%1\;"
13529                "bne- %2,$-16";
13530       }
13531     else
13532       {
13533         return "mftbu %0\;"
13534                "mftb %L0\;"
13535                "mftbu %1\;"
13536                "cmpw %2,%0,%1\;"
13537                "bne- %2,$-16";
13538       }
13539   else
13540     if (TARGET_MFCRF)
13541       {
13542         return "mfspr %L0,269\;"
13543                "mfspr %0,268\;"
13544                "mfspr %1,269\;"
13545                "cmpw %2,%L0,%1\;"
13546                "bne- %2,$-16";
13547       }
13548     else
13549       {
13550         return "mftbu %L0\;"
13551                "mftb %0\;"
13552                "mftbu %1\;"
13553                "cmpw %2,%L0,%1\;"
13554                "bne- %2,$-16";
13555       }
13557   [(set_attr "length" "20")])
13559 (define_insn "rs6000_mftb_<mode>"
13560   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
13561         (unspec_volatile:GPR [(const_int 0)] UNSPECV_MFTB))]
13562   ""
13564   if (TARGET_MFCRF)
13565     return "mfspr %0,268";
13566   else
13567     return "mftb %0";
13571 ;; The ISA 3.0 mffsl instruction is a lower latency instruction
13572 ;; for reading bits [29:31], [45:51] and [56:63] of the FPSCR.
13573 (define_insn "rs6000_mffsl_hw"
13574   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
13575         (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFSL))]
13576   "TARGET_HARD_FLOAT"
13577   "mffsl %0")
13579 (define_expand "rs6000_mffsl"
13580   [(set (match_operand:DF 0 "gpc_reg_operand")
13581         (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFSL))]
13582   "TARGET_HARD_FLOAT"
13584   /* If the low latency mffsl instruction (ISA 3.0) is available use it,
13585      otherwise fall back to the older mffs instruction to emulate the mffsl
13586      instruction.  */
13588   if (!TARGET_P9_MISC)
13589     {
13590        rtx tmp_di = gen_reg_rtx (DImode);
13591        rtx tmp_df = gen_reg_rtx (DFmode);
13593        /* The mffs instruction reads the entire FPSCR.  Emulate the mffsl
13594           instruction using the mffs instruction and masking off the bits
13595           the mmsl instruciton actually reads.  */
13596        emit_insn (gen_rs6000_mffs (tmp_df));
13597        tmp_di = simplify_gen_subreg (DImode, tmp_df, DFmode, 0);
13598        emit_insn (gen_anddi3 (tmp_di, tmp_di, GEN_INT (0x70007f0ffLL)));
13600        operands[0] = simplify_gen_subreg (DFmode, tmp_di, DImode, 0);
13601        DONE;
13602     }
13604     emit_insn (gen_rs6000_mffsl_hw (operands[0]));
13605     DONE;
13608 (define_insn "rs6000_mffs"
13609   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
13610         (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFS))]
13611   "TARGET_HARD_FLOAT"
13612   "mffs %0")
13614 (define_insn "rs6000_mtfsf"
13615   [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "i")
13616                      (match_operand:DF 1 "gpc_reg_operand" "d")]
13617                     UNSPECV_MTFSF)]
13618   "TARGET_HARD_FLOAT"
13619   "mtfsf %0,%1")
13621 (define_insn "rs6000_mtfsf_hi"
13622   [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "n")
13623                      (match_operand:DF 1 "gpc_reg_operand" "d")]
13624                     UNSPECV_MTFSF_HI)]
13625   "TARGET_HARD_FLOAT"
13626   "mtfsf %0,%1,0,1")
13629 ;; Power8 fusion support for fusing an addis instruction with a D-form load of
13630 ;; a GPR.  The addis instruction must be adjacent to the load, and use the same
13631 ;; register that is being loaded.  The fused ops must be physically adjacent.
13633 ;; On Power8 GPR loads, we try to use the register that is being load.  The
13634 ;; peephole2 then gathers any other fused possibilities that it can find after
13635 ;; register allocation.  If power9 fusion is selected, we also fuse floating
13636 ;; point loads/stores.
13638 ;; Find cases where the addis that feeds into a load instruction is either used
13639 ;; once or is the same as the target register, and replace it with the fusion
13640 ;; insn
13642 (define_peephole2
13643   [(set (match_operand:P 0 "base_reg_operand")
13644         (match_operand:P 1 "fusion_gpr_addis"))
13645    (set (match_operand:INT1 2 "base_reg_operand")
13646         (match_operand:INT1 3 "fusion_gpr_mem_load"))]
13647   "TARGET_P8_FUSION
13648    && fusion_gpr_load_p (operands[0], operands[1], operands[2],
13649                          operands[3])"
13650   [(const_int 0)]
13652   expand_fusion_gpr_load (operands);
13653   DONE;
13656 ;; Fusion insn, created by the define_peephole2 above (and eventually by
13657 ;; reload)
13659 (define_insn "*fusion_gpr_load_<mode>"
13660   [(set (match_operand:INT1 0 "base_reg_operand" "=b")
13661         (unspec:INT1 [(match_operand:INT1 1 "fusion_addis_mem_combo_load" "wF")]
13662                      UNSPEC_FUSION_GPR))]
13663   "TARGET_P8_FUSION"
13665   return emit_fusion_gpr_load (operands[0], operands[1]);
13667   [(set_attr "type" "load")
13668    (set_attr "length" "8")])
13671 ;; Optimize cases where we want to do a D-form load (register+offset) on
13672 ;; ISA 2.06/2.07 to an Altivec register, and the register allocator
13673 ;; has generated:
13674 ;;      LFD 0,32(3)
13675 ;;      XXLOR 32,0,0
13677 ;; and we change this to:
13678 ;;      LI 0,32
13679 ;;      LXSDX 32,3,9
13681 (define_peephole2
13682   [(match_scratch:P 0 "b")
13683    (set (match_operand:ALTIVEC_DFORM 1 "fpr_reg_operand")
13684         (match_operand:ALTIVEC_DFORM 2 "simple_offsettable_mem_operand"))
13685    (set (match_operand:ALTIVEC_DFORM 3 "altivec_register_operand")
13686         (match_dup 1))]
13687   "TARGET_VSX && !TARGET_P9_VECTOR && peep2_reg_dead_p (2, operands[1])"
13688   [(set (match_dup 0)
13689         (match_dup 4))
13690    (set (match_dup 3)
13691         (match_dup 5))]
13693   rtx tmp_reg = operands[0];
13694   rtx mem = operands[2];
13695   rtx addr = XEXP (mem, 0);
13696   rtx add_op0, add_op1, new_addr;
13698   gcc_assert (GET_CODE (addr) == PLUS || GET_CODE (addr) == LO_SUM);
13699   add_op0 = XEXP (addr, 0);
13700   add_op1 = XEXP (addr, 1);
13701   gcc_assert (REG_P (add_op0));
13702   new_addr = gen_rtx_PLUS (Pmode, add_op0, tmp_reg);
13704   operands[4] = add_op1;
13705   operands[5] = change_address (mem, <MODE>mode, new_addr);
13708 ;; Optimize cases were want to do a D-form store on ISA 2.06/2.07 from an
13709 ;; Altivec register, and the register allocator has generated:
13710 ;;      XXLOR 0,32,32
13711 ;;      STFD 0,32(3)
13713 ;; and we change this to:
13714 ;;      LI 0,32
13715 ;;      STXSDX 32,3,9
13717 (define_peephole2
13718   [(match_scratch:P 0 "b")
13719    (set (match_operand:ALTIVEC_DFORM 1 "fpr_reg_operand")
13720         (match_operand:ALTIVEC_DFORM 2 "altivec_register_operand"))
13721    (set (match_operand:ALTIVEC_DFORM 3 "simple_offsettable_mem_operand")
13722         (match_dup 1))]
13723   "TARGET_VSX && !TARGET_P9_VECTOR && peep2_reg_dead_p (2, operands[1])"
13724   [(set (match_dup 0)
13725         (match_dup 4))
13726    (set (match_dup 5)
13727         (match_dup 2))]
13729   rtx tmp_reg = operands[0];
13730   rtx mem = operands[3];
13731   rtx addr = XEXP (mem, 0);
13732   rtx add_op0, add_op1, new_addr;
13734   gcc_assert (GET_CODE (addr) == PLUS || GET_CODE (addr) == LO_SUM);
13735   add_op0 = XEXP (addr, 0);
13736   add_op1 = XEXP (addr, 1);
13737   gcc_assert (REG_P (add_op0));
13738   new_addr = gen_rtx_PLUS (Pmode, add_op0, tmp_reg);
13740   operands[4] = add_op1;
13741   operands[5] = change_address (mem, <MODE>mode, new_addr);
13743    
13745 ;; Miscellaneous ISA 2.06 (power7) instructions
13746 (define_insn "addg6s"
13747   [(set (match_operand:SI 0 "register_operand" "=r")
13748         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
13749                     (match_operand:SI 2 "register_operand" "r")]
13750                    UNSPEC_ADDG6S))]
13751   "TARGET_POPCNTD"
13752   "addg6s %0,%1,%2"
13753   [(set_attr "type" "integer")])
13755 (define_insn "cdtbcd"
13756   [(set (match_operand:SI 0 "register_operand" "=r")
13757         (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
13758                    UNSPEC_CDTBCD))]
13759   "TARGET_POPCNTD"
13760   "cdtbcd %0,%1"
13761   [(set_attr "type" "integer")])
13763 (define_insn "cbcdtd"
13764   [(set (match_operand:SI 0 "register_operand" "=r")
13765         (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
13766                    UNSPEC_CBCDTD))]
13767   "TARGET_POPCNTD"
13768   "cbcdtd %0,%1"
13769   [(set_attr "type" "integer")])
13771 (define_int_iterator UNSPEC_DIV_EXTEND [UNSPEC_DIVE
13772                                         UNSPEC_DIVEU])
13774 (define_int_attr div_extend [(UNSPEC_DIVE       "e")
13775                              (UNSPEC_DIVEU      "eu")])
13777 (define_insn "div<div_extend>_<mode>"
13778   [(set (match_operand:GPR 0 "register_operand" "=r")
13779         (unspec:GPR [(match_operand:GPR 1 "register_operand" "r")
13780                      (match_operand:GPR 2 "register_operand" "r")]
13781                     UNSPEC_DIV_EXTEND))]
13782   "TARGET_POPCNTD"
13783   "div<wd><div_extend> %0,%1,%2"
13784   [(set_attr "type" "div")
13785    (set_attr "size" "<bits>")])
13788 ;; Pack/unpack 128-bit floating point types that take 2 scalar registers
13790 ; Type of the 64-bit part when packing/unpacking 128-bit floating point types
13791 (define_mode_attr FP128_64 [(TF "DF")
13792                             (IF "DF")
13793                             (TD "DI")
13794                             (KF "DI")])
13796 (define_expand "unpack<mode>"
13797   [(set (match_operand:<FP128_64> 0 "nonimmediate_operand")
13798         (unspec:<FP128_64>
13799          [(match_operand:FMOVE128 1 "register_operand")
13800           (match_operand:QI 2 "const_0_to_1_operand")]
13801          UNSPEC_UNPACK_128BIT))]
13802   "FLOAT128_2REG_P (<MODE>mode)"
13803   "")
13805 (define_insn_and_split "unpack<mode>_dm"
13806   [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m,d,r,m")
13807         (unspec:<FP128_64>
13808          [(match_operand:FMOVE128 1 "register_operand" "d,d,r,d,r")
13809           (match_operand:QI 2 "const_0_to_1_operand" "i,i,i,i,i")]
13810          UNSPEC_UNPACK_128BIT))]
13811   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE && FLOAT128_2REG_P (<MODE>mode)"
13812   "#"
13813   "&& reload_completed"
13814   [(set (match_dup 0) (match_dup 3))]
13816   unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
13818   if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
13819     {
13820       emit_note (NOTE_INSN_DELETED);
13821       DONE;
13822     }
13824   operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
13826   [(set_attr "type" "fp,fpstore,mffgpr,mftgpr,store")])
13828 (define_insn_and_split "unpack<mode>_nodm"
13829   [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m")
13830         (unspec:<FP128_64>
13831          [(match_operand:FMOVE128 1 "register_operand" "d,d")
13832           (match_operand:QI 2 "const_0_to_1_operand" "i,i")]
13833          UNSPEC_UNPACK_128BIT))]
13834   "(!TARGET_POWERPC64 || !TARGET_DIRECT_MOVE) && FLOAT128_2REG_P (<MODE>mode)"
13835   "#"
13836   "&& reload_completed"
13837   [(set (match_dup 0) (match_dup 3))]
13839   unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
13841   if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
13842     {
13843       emit_note (NOTE_INSN_DELETED);
13844       DONE;
13845     }
13847   operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
13849   [(set_attr "type" "fp,fpstore")])
13851 (define_insn_and_split "pack<mode>"
13852   [(set (match_operand:FMOVE128 0 "register_operand" "=&d")
13853         (unspec:FMOVE128
13854          [(match_operand:<FP128_64> 1 "register_operand" "d")
13855           (match_operand:<FP128_64> 2 "register_operand" "d")]
13856          UNSPEC_PACK_128BIT))]
13857   "FLOAT128_2REG_P (<MODE>mode)"
13858   "#"
13859   "&& reload_completed"
13860   [(set (match_dup 3) (match_dup 1))
13861    (set (match_dup 4) (match_dup 2))]
13863   unsigned dest_hi = REGNO (operands[0]);
13864   unsigned dest_lo = dest_hi + 1;
13866   gcc_assert (!IN_RANGE (REGNO (operands[1]), dest_hi, dest_lo));
13867   gcc_assert (!IN_RANGE (REGNO (operands[2]), dest_hi, dest_lo));
13869   operands[3] = gen_rtx_REG (<FP128_64>mode, dest_hi);
13870   operands[4] = gen_rtx_REG (<FP128_64>mode, dest_lo);
13872   [(set_attr "type" "fp")
13873    (set_attr "length" "8")])
13875 (define_insn "unpack<mode>"
13876   [(set (match_operand:DI 0 "register_operand" "=wa,wa")
13877         (unspec:DI [(match_operand:FMOVE128_VSX 1 "register_operand" "0,wa")
13878                     (match_operand:QI 2 "const_0_to_1_operand" "O,i")]
13879          UNSPEC_UNPACK_128BIT))]
13880   "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)"
13882   if (REGNO (operands[0]) == REGNO (operands[1]) && INTVAL (operands[2]) == 0)
13883     return ASM_COMMENT_START " xxpermdi to same register";
13885   operands[3] = GEN_INT (INTVAL (operands[2]) == 0 ? 0 : 3);
13886   return "xxpermdi %x0,%x1,%x1,%3";
13888   [(set_attr "type" "vecperm")])
13890 (define_insn "pack<mode>"
13891   [(set (match_operand:FMOVE128_VSX 0 "register_operand" "=wa")
13892         (unspec:FMOVE128_VSX
13893          [(match_operand:DI 1 "register_operand" "wa")
13894           (match_operand:DI 2 "register_operand" "wa")]
13895          UNSPEC_PACK_128BIT))]
13896   "TARGET_VSX"
13897   "xxpermdi %x0,%x1,%x2,0"
13898   [(set_attr "type" "vecperm")])
13902 ;; ISA 2.08 IEEE 128-bit floating point support.
13904 (define_insn "add<mode>3"
13905   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13906         (plus:IEEE128
13907          (match_operand:IEEE128 1 "altivec_register_operand" "v")
13908          (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13909   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13910   "xsaddqp %0,%1,%2"
13911   [(set_attr "type" "vecfloat")
13912    (set_attr "size" "128")])
13914 (define_insn "sub<mode>3"
13915   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13916         (minus:IEEE128
13917          (match_operand:IEEE128 1 "altivec_register_operand" "v")
13918          (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13919   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13920   "xssubqp %0,%1,%2"
13921   [(set_attr "type" "vecfloat")
13922    (set_attr "size" "128")])
13924 (define_insn "mul<mode>3"
13925   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13926         (mult:IEEE128
13927          (match_operand:IEEE128 1 "altivec_register_operand" "v")
13928          (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13929   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13930   "xsmulqp %0,%1,%2"
13931   [(set_attr "type" "qmul")
13932    (set_attr "size" "128")])
13934 (define_insn "div<mode>3"
13935   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13936         (div:IEEE128
13937          (match_operand:IEEE128 1 "altivec_register_operand" "v")
13938          (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13939   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13940   "xsdivqp %0,%1,%2"
13941   [(set_attr "type" "vecdiv")
13942    (set_attr "size" "128")])
13944 (define_insn "sqrt<mode>2"
13945   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13946         (sqrt:IEEE128
13947          (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
13948   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13949    "xssqrtqp %0,%1"
13950   [(set_attr "type" "vecdiv")
13951    (set_attr "size" "128")])
13953 (define_expand "copysign<mode>3"
13954   [(use (match_operand:IEEE128 0 "altivec_register_operand"))
13955    (use (match_operand:IEEE128 1 "altivec_register_operand"))
13956    (use (match_operand:IEEE128 2 "altivec_register_operand"))]
13957   "FLOAT128_IEEE_P (<MODE>mode)"
13959   if (TARGET_FLOAT128_HW)
13960     emit_insn (gen_copysign<mode>3_hard (operands[0], operands[1],
13961                                          operands[2]));
13962   else
13963     emit_insn (gen_copysign<mode>3_soft (operands[0], operands[1],
13964                                          operands[2]));
13965   DONE;
13968 (define_insn "copysign<mode>3_hard"
13969   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13970         (unspec:IEEE128
13971          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
13972           (match_operand:IEEE128 2 "altivec_register_operand" "v")]
13973          UNSPEC_COPYSIGN))]
13974   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13975    "xscpsgnqp %0,%2,%1"
13976   [(set_attr "type" "vecmove")
13977    (set_attr "size" "128")])
13979 (define_insn "copysign<mode>3_soft"
13980   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13981         (unspec:IEEE128
13982          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
13983           (match_operand:IEEE128 2 "altivec_register_operand" "v")]
13984          UNSPEC_COPYSIGN))
13985    (clobber (match_scratch:IEEE128 3 "=&v"))]
13986   "!TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13987    "xscpsgndp %x3,%x2,%x1\;xxpermdi %x0,%x3,%x1,1"
13988   [(set_attr "type" "veccomplex")
13989    (set_attr "length" "8")])
13991 (define_insn "neg<mode>2_hw"
13992   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13993         (neg:IEEE128
13994          (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
13995   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13996   "xsnegqp %0,%1"
13997   [(set_attr "type" "vecmove")
13998    (set_attr "size" "128")])
14001 (define_insn "abs<mode>2_hw"
14002   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14003         (abs:IEEE128
14004          (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14005   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14006   "xsabsqp %0,%1"
14007   [(set_attr "type" "vecmove")
14008    (set_attr "size" "128")])
14011 (define_insn "*nabs<mode>2_hw"
14012   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14013         (neg:IEEE128
14014          (abs:IEEE128
14015           (match_operand:IEEE128 1 "altivec_register_operand" "v"))))]
14016   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14017   "xsnabsqp %0,%1"
14018   [(set_attr "type" "vecmove")
14019    (set_attr "size" "128")])
14021 ;; Initially don't worry about doing fusion
14022 (define_insn "fma<mode>4_hw"
14023   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14024         (fma:IEEE128
14025          (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14026          (match_operand:IEEE128 2 "altivec_register_operand" "v")
14027          (match_operand:IEEE128 3 "altivec_register_operand" "0")))]
14028   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14029   "xsmaddqp %0,%1,%2"
14030   [(set_attr "type" "qmul")
14031    (set_attr "size" "128")])
14033 (define_insn "*fms<mode>4_hw"
14034   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14035         (fma:IEEE128
14036          (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14037          (match_operand:IEEE128 2 "altivec_register_operand" "v")
14038          (neg:IEEE128
14039           (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
14040   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14041   "xsmsubqp %0,%1,%2"
14042   [(set_attr "type" "qmul")
14043    (set_attr "size" "128")])
14045 (define_insn "*nfma<mode>4_hw"
14046   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14047         (neg:IEEE128
14048          (fma:IEEE128
14049           (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14050           (match_operand:IEEE128 2 "altivec_register_operand" "v")
14051           (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
14052   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14053   "xsnmaddqp %0,%1,%2"
14054   [(set_attr "type" "qmul")
14055    (set_attr "size" "128")])
14057 (define_insn "*nfms<mode>4_hw"
14058   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14059         (neg:IEEE128
14060          (fma:IEEE128
14061           (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14062           (match_operand:IEEE128 2 "altivec_register_operand" "v")
14063           (neg:IEEE128
14064            (match_operand:IEEE128 3 "altivec_register_operand" "0")))))]
14065   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14066   "xsnmsubqp %0,%1,%2"
14067   [(set_attr "type" "qmul")
14068    (set_attr "size" "128")])
14070 (define_insn "extend<SFDF:mode><IEEE128:mode>2_hw"
14071   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14072         (float_extend:IEEE128
14073          (match_operand:SFDF 1 "altivec_register_operand" "v")))]
14074   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14075   "xscvdpqp %0,%1"
14076   [(set_attr "type" "vecfloat")
14077    (set_attr "size" "128")])
14079 ;; Conversion between KFmode and TFmode if TFmode is ieee 128-bit floating
14080 ;; point is a simple copy.
14081 (define_insn_and_split "extendkftf2"
14082   [(set (match_operand:TF 0 "vsx_register_operand" "=wa,?wa")
14083         (float_extend:TF (match_operand:KF 1 "vsx_register_operand" "0,wa")))]
14084   "TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD"
14085   "@
14086    #
14087    xxlor %x0,%x1,%x1"
14088   "&& reload_completed  && REGNO (operands[0]) == REGNO (operands[1])"
14089   [(const_int 0)]
14091   emit_note (NOTE_INSN_DELETED);
14092   DONE;
14094   [(set_attr "type" "*,veclogical")
14095    (set_attr "length" "0,4")])
14097 (define_insn_and_split "trunctfkf2"
14098   [(set (match_operand:KF 0 "vsx_register_operand" "=wa,?wa")
14099         (float_extend:KF (match_operand:TF 1 "vsx_register_operand" "0,wa")))]
14100   "TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD"
14101   "@
14102    #
14103    xxlor %x0,%x1,%x1"
14104   "&& reload_completed  && REGNO (operands[0]) == REGNO (operands[1])"
14105   [(const_int 0)]
14107   emit_note (NOTE_INSN_DELETED);
14108   DONE;
14110   [(set_attr "type" "*,veclogical")
14111    (set_attr "length" "0,4")])
14113 (define_insn "trunc<mode>df2_hw"
14114   [(set (match_operand:DF 0 "altivec_register_operand" "=v")
14115         (float_truncate:DF
14116          (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14117   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14118   "xscvqpdp %0,%1"
14119   [(set_attr "type" "vecfloat")
14120    (set_attr "size" "128")])
14122 ;; There is no KFmode -> SFmode instruction. Preserve the accuracy by doing
14123 ;; the KFmode -> DFmode conversion using round to odd rather than the normal
14124 ;; conversion
14125 (define_insn_and_split "trunc<mode>sf2_hw"
14126   [(set (match_operand:SF 0 "vsx_register_operand" "=wy")
14127         (float_truncate:SF
14128          (match_operand:IEEE128 1 "altivec_register_operand" "v")))
14129    (clobber (match_scratch:DF 2 "=v"))]
14130   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14131   "#"
14132   "&& 1"
14133   [(set (match_dup 2)
14134         (unspec:DF [(match_dup 1)]
14135                    UNSPEC_TRUNC_ROUND_TO_ODD))
14136    (set (match_dup 0)
14137         (float_truncate:SF (match_dup 2)))]
14139   if (GET_CODE (operands[2]) == SCRATCH)
14140     operands[2] = gen_reg_rtx (DFmode);
14142   [(set_attr "type" "vecfloat")
14143    (set_attr "length" "8")])
14145 ;; Conversion between IEEE 128-bit and integer types
14147 ;; The fix function for DImode and SImode was declared earlier as a
14148 ;; define_expand.  It calls into rs6000_expand_float128_convert if we don't
14149 ;; have IEEE 128-bit hardware support.  QImode and HImode are not provided
14150 ;; unless we have the IEEE 128-bit hardware.
14152 ;; Unlike the code for converting SFmode/DFmode to QImode/HImode, we don't have
14153 ;; to provide a GPR target that used direct move and a conversion in the GPR
14154 ;; which works around QImode/HImode not being allowed in vector registers in
14155 ;; ISA 2.07 (power8).
14156 (define_insn "fix<uns>_<IEEE128:mode><SDI:mode>2_hw"
14157   [(set (match_operand:SDI 0 "altivec_register_operand" "=v")
14158         (any_fix:SDI (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14159   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14160   "xscvqp<su><wd>z %0,%1"
14161   [(set_attr "type" "vecfloat")
14162    (set_attr "size" "128")])
14164 (define_insn "fix<uns>_trunc<IEEE128:mode><QHI:mode>2"
14165   [(set (match_operand:QHI 0 "altivec_register_operand" "=v")
14166         (any_fix:QHI
14167          (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14168   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14169   "xscvqp<su>wz %0,%1"
14170   [(set_attr "type" "vecfloat")
14171    (set_attr "size" "128")])
14173 ;; Combiner patterns to prevent moving the result of converting an IEEE 128-bit
14174 ;; floating point value to 8/16/32-bit integer to GPR in order to save it.
14175 (define_insn_and_split "*fix<uns>_trunc<IEEE128:mode><QHSI:mode>2_mem"
14176   [(set (match_operand:QHSI 0 "memory_operand" "=Z")
14177         (any_fix:QHSI
14178          (match_operand:IEEE128 1 "altivec_register_operand" "v")))
14179    (clobber (match_scratch:QHSI 2 "=v"))]
14180   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14181   "#"
14182   "&& reload_completed"
14183   [(set (match_dup 2)
14184         (any_fix:QHSI (match_dup 1)))
14185    (set (match_dup 0)
14186         (match_dup 2))])
14188 (define_insn "float_<mode>di2_hw"
14189   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14190         (float:IEEE128 (match_operand:DI 1 "altivec_register_operand" "v")))]
14191   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14192   "xscvsdqp %0,%1"
14193   [(set_attr "type" "vecfloat")
14194    (set_attr "size" "128")])
14196 (define_insn_and_split "float_<mode>si2_hw"
14197   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14198         (float:IEEE128 (match_operand:SI 1 "nonimmediate_operand" "vrZ")))
14199    (clobber (match_scratch:DI 2 "=v"))]
14200   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14201   "#"
14202   "&& 1"
14203   [(set (match_dup 2)
14204         (sign_extend:DI (match_dup 1)))
14205    (set (match_dup 0)
14206         (float:IEEE128 (match_dup 2)))]
14208   if (GET_CODE (operands[2]) == SCRATCH)
14209     operands[2] = gen_reg_rtx (DImode);
14211   if (MEM_P (operands[1]))
14212     operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
14215 (define_insn_and_split "float<QHI:mode><IEEE128:mode>2"
14216   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v")
14217         (float:IEEE128 (match_operand:QHI 1 "nonimmediate_operand" "v,r,Z")))
14218    (clobber (match_scratch:DI 2 "=X,r,X"))]
14219   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14220   "#"
14221   "&& reload_completed"
14222   [(const_int 0)]
14224   rtx dest = operands[0];
14225   rtx src = operands[1];
14226   rtx dest_di = gen_rtx_REG (DImode, REGNO (dest));
14228   if (altivec_register_operand (src, <QHI:MODE>mode))
14229     emit_insn (gen_extend<QHI:mode>di2 (dest_di, src));
14230   else if (int_reg_operand (src, <QHI:MODE>mode))
14231     {
14232       rtx ext_di = operands[2];
14233       emit_insn (gen_extend<QHI:mode>di2 (ext_di, src));
14234       emit_move_insn (dest_di, ext_di);
14235     }
14236   else if (MEM_P (src))
14237     {
14238       rtx dest_qhi = gen_rtx_REG (<QHI:MODE>mode, REGNO (dest));
14239       emit_move_insn (dest_qhi, src);
14240       emit_insn (gen_extend<QHI:mode>di2 (dest_di, dest_qhi));
14241     }
14242   else
14243     gcc_unreachable ();
14245   emit_insn (gen_float_<IEEE128:mode>di2_hw (dest, dest_di));
14246   DONE;
14248   [(set_attr "length" "8,12,12")
14249    (set_attr "type" "vecfloat")
14250    (set_attr "size" "128")])
14252 (define_insn "floatuns_<mode>di2_hw"
14253   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14254         (unsigned_float:IEEE128
14255          (match_operand:DI 1 "altivec_register_operand" "v")))]
14256   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14257   "xscvudqp %0,%1"
14258   [(set_attr "type" "vecfloat")
14259    (set_attr "size" "128")])
14261 (define_insn_and_split "floatuns_<mode>si2_hw"
14262   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14263         (unsigned_float:IEEE128
14264          (match_operand:SI 1 "nonimmediate_operand" "vrZ")))
14265    (clobber (match_scratch:DI 2 "=v"))]
14266   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14267   "#"
14268   "&& 1"
14269   [(set (match_dup 2)
14270         (zero_extend:DI (match_dup 1)))
14271    (set (match_dup 0)
14272         (float:IEEE128 (match_dup 2)))]
14274   if (GET_CODE (operands[2]) == SCRATCH)
14275     operands[2] = gen_reg_rtx (DImode);
14277   if (MEM_P (operands[1]))
14278     operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
14281 (define_insn_and_split "floatuns<QHI:mode><IEEE128:mode>2"
14282   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v")
14283         (unsigned_float:IEEE128
14284          (match_operand:QHI 1 "nonimmediate_operand" "v,r,Z")))
14285    (clobber (match_scratch:DI 2 "=X,r,X"))]
14286   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14287   "#"
14288   "&& reload_completed"
14289   [(const_int 0)]
14291   rtx dest = operands[0];
14292   rtx src = operands[1];
14293   rtx dest_di = gen_rtx_REG (DImode, REGNO (dest));
14295   if (altivec_register_operand (src, <QHI:MODE>mode) || MEM_P (src))
14296     emit_insn (gen_zero_extend<QHI:mode>di2 (dest_di, src));
14297   else if (int_reg_operand (src, <QHI:MODE>mode))
14298     {
14299       rtx ext_di = operands[2];
14300       emit_insn (gen_zero_extend<QHI:mode>di2 (ext_di, src));
14301       emit_move_insn (dest_di, ext_di);
14302     }
14303   else
14304     gcc_unreachable ();
14306   emit_insn (gen_floatuns_<IEEE128:mode>di2_hw (dest, dest_di));
14307   DONE;
14309   [(set_attr "length" "8,12,8")
14310    (set_attr "type" "vecfloat")
14311    (set_attr "size" "128")])
14313 ;; IEEE 128-bit round to integer built-in functions
14314 (define_insn "floor<mode>2"
14315   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14316         (unspec:IEEE128
14317          [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14318          UNSPEC_FRIM))]
14319   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14320   "xsrqpi 1,%0,%1,3"
14321   [(set_attr "type" "vecfloat")
14322    (set_attr "size" "128")])
14324 (define_insn "ceil<mode>2"
14325   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14326         (unspec:IEEE128
14327          [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14328          UNSPEC_FRIP))]
14329   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14330   "xsrqpi 1,%0,%1,2"
14331   [(set_attr "type" "vecfloat")
14332    (set_attr "size" "128")])
14334 (define_insn "btrunc<mode>2"
14335   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14336         (unspec:IEEE128
14337          [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14338          UNSPEC_FRIZ))]
14339   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14340   "xsrqpi 1,%0,%1,1"
14341   [(set_attr "type" "vecfloat")
14342    (set_attr "size" "128")])
14344 (define_insn "round<mode>2"
14345   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14346         (unspec:IEEE128
14347          [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14348          UNSPEC_FRIN))]
14349   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14350   "xsrqpi 0,%0,%1,0"
14351   [(set_attr "type" "vecfloat")
14352    (set_attr "size" "128")])
14354 ;; IEEE 128-bit instructions with round to odd semantics
14355 (define_insn "add<mode>3_odd"
14356   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14357         (unspec:IEEE128
14358          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14359           (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14360          UNSPEC_ADD_ROUND_TO_ODD))]
14361   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14362   "xsaddqpo %0,%1,%2"
14363   [(set_attr "type" "vecfloat")
14364    (set_attr "size" "128")])
14366 (define_insn "sub<mode>3_odd"
14367   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14368         (unspec:IEEE128
14369          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14370           (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14371          UNSPEC_SUB_ROUND_TO_ODD))]
14372   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14373   "xssubqpo %0,%1,%2"
14374   [(set_attr "type" "vecfloat")
14375    (set_attr "size" "128")])
14377 (define_insn "mul<mode>3_odd"
14378   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14379         (unspec:IEEE128
14380          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14381           (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14382          UNSPEC_MUL_ROUND_TO_ODD))]
14383   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14384   "xsmulqpo %0,%1,%2"
14385   [(set_attr "type" "qmul")
14386    (set_attr "size" "128")])
14388 (define_insn "div<mode>3_odd"
14389   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14390         (unspec:IEEE128
14391          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14392           (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14393          UNSPEC_DIV_ROUND_TO_ODD))]
14394   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14395   "xsdivqpo %0,%1,%2"
14396   [(set_attr "type" "vecdiv")
14397    (set_attr "size" "128")])
14399 (define_insn "sqrt<mode>2_odd"
14400   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14401         (unspec:IEEE128
14402          [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14403          UNSPEC_SQRT_ROUND_TO_ODD))]
14404   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14405    "xssqrtqpo %0,%1"
14406   [(set_attr "type" "vecdiv")
14407    (set_attr "size" "128")])
14409 (define_insn "fma<mode>4_odd"
14410   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14411         (unspec:IEEE128
14412          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14413           (match_operand:IEEE128 2 "altivec_register_operand" "v")
14414           (match_operand:IEEE128 3 "altivec_register_operand" "0")]
14415          UNSPEC_FMA_ROUND_TO_ODD))]
14416   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14417   "xsmaddqpo %0,%1,%2"
14418   [(set_attr "type" "qmul")
14419    (set_attr "size" "128")])
14421 (define_insn "*fms<mode>4_odd"
14422   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14423         (unspec:IEEE128
14424          [(match_operand:IEEE128 1 "altivec_register_operand" "%v")
14425           (match_operand:IEEE128 2 "altivec_register_operand" "v")
14426           (neg:IEEE128
14427            (match_operand:IEEE128 3 "altivec_register_operand" "0"))]
14428          UNSPEC_FMA_ROUND_TO_ODD))]
14429   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14430   "xsmsubqpo %0,%1,%2"
14431   [(set_attr "type" "qmul")
14432    (set_attr "size" "128")])
14434 (define_insn "*nfma<mode>4_odd"
14435   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14436         (neg:IEEE128
14437          (unspec:IEEE128
14438           [(match_operand:IEEE128 1 "altivec_register_operand" "%v")
14439            (match_operand:IEEE128 2 "altivec_register_operand" "v")
14440            (match_operand:IEEE128 3 "altivec_register_operand" "0")]
14441           UNSPEC_FMA_ROUND_TO_ODD)))]
14442   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14443   "xsnmaddqpo %0,%1,%2"
14444   [(set_attr "type" "qmul")
14445    (set_attr "size" "128")])
14447 (define_insn "*nfms<mode>4_odd"
14448   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14449         (neg:IEEE128
14450          (unspec:IEEE128
14451           [(match_operand:IEEE128 1 "altivec_register_operand" "%v")
14452            (match_operand:IEEE128 2 "altivec_register_operand" "v")
14453            (neg:IEEE128
14454             (match_operand:IEEE128 3 "altivec_register_operand" "0"))]
14455           UNSPEC_FMA_ROUND_TO_ODD)))]
14456   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14457   "xsnmsubqpo %0,%1,%2"
14458   [(set_attr "type" "qmul")
14459    (set_attr "size" "128")])
14461 (define_insn "trunc<mode>df2_odd"
14462   [(set (match_operand:DF 0 "vsx_register_operand" "=v")
14463         (unspec:DF [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14464                    UNSPEC_TRUNC_ROUND_TO_ODD))]
14465   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14466   "xscvqpdpo %0,%1"
14467   [(set_attr "type" "vecfloat")
14468    (set_attr "size" "128")])
14470 ;; IEEE 128-bit comparisons
14471 (define_insn "*cmp<mode>_hw"
14472   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
14473         (compare:CCFP (match_operand:IEEE128 1 "altivec_register_operand" "v")
14474                       (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14475   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14476    "xscmpuqp %0,%1,%2"
14477   [(set_attr "type" "veccmp")
14478    (set_attr "size" "128")])
14482 (include "sync.md")
14483 (include "vector.md")
14484 (include "vsx.md")
14485 (include "altivec.md")
14486 (include "dfp.md")
14487 (include "crypto.md")
14488 (include "htm.md")