[RS6000] Fix <bd>_<mode> and <bd>tf_<mode> splitters
[official-gcc.git] / gcc / config / rs6000 / rs6000.md
blob584b9da6e7174eec191ad0aeb3bfd485b7313667
1 ;; Machine description for IBM RISC System 6000 (POWER) for GNU C compiler
2 ;; Copyright (C) 1990-2019 Free Software Foundation, Inc.
3 ;; Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
5 ;; This file is part of GCC.
7 ;; GCC is free software; you can redistribute it and/or modify it
8 ;; under the terms of the GNU General Public License as published
9 ;; by the Free Software Foundation; either version 3, or (at your
10 ;; option) any later version.
12 ;; GCC is distributed in the hope that it will be useful, but WITHOUT
13 ;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 ;; or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
15 ;; License for more details.
17 ;; You should have received a copy of the GNU General Public License
18 ;; along with GCC; see the file COPYING3.  If not see
19 ;; <http://www.gnu.org/licenses/>.
21 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
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    UNSPEC_PLTSEQ
150    UNSPEC_PLT16_HA
151    UNSPEC_PLT16_LO
152   ])
155 ;; UNSPEC_VOLATILE usage
158 (define_c_enum "unspecv"
159   [UNSPECV_BLOCK
160    UNSPECV_LL                   ; load-locked
161    UNSPECV_SC                   ; store-conditional
162    UNSPECV_PROBE_STACK_RANGE    ; probe range of stack addresses
163    UNSPECV_EH_RR                ; eh_reg_restore
164    UNSPECV_ISYNC                ; isync instruction
165    UNSPECV_MFTB                 ; move from time base
166    UNSPECV_NLGR                 ; non-local goto receiver
167    UNSPECV_MFFS                 ; Move from FPSCR
168    UNSPECV_MFFSL                ; Move from FPSCR light instruction version
169    UNSPECV_MFFSCRN              ; Move from FPSCR float rounding mode
170    UNSPECV_MFFSCDRN             ; Move from FPSCR decimal float rounding mode
171    UNSPECV_MTFSF                ; Move to FPSCR Fields 8 to 15
172    UNSPECV_MTFSF_HI             ; Move to FPSCR Fields 0 to 7
173    UNSPECV_MTFSB0               ; Set FPSCR Field bit to 0
174    UNSPECV_MTFSB1               ; Set FPSCR Field bit to 1
175    UNSPECV_SPLIT_STACK_RETURN   ; A camouflaged return
176    UNSPECV_SPEC_BARRIER         ; Speculation barrier
177   ])
180 ;; Define an insn type attribute.  This is used in function unit delay
181 ;; computations.
182 (define_attr "type"
183   "integer,two,three,
184    add,logical,shift,insert,
185    mul,halfmul,div,
186    exts,cntlz,popcnt,isel,
187    load,store,fpload,fpstore,vecload,vecstore,
188    cmp,
189    branch,jmpreg,mfjmpr,mtjmpr,trap,isync,sync,load_l,store_c,
190    cr_logical,mfcr,mfcrf,mtcr,
191    fpcompare,fp,fpsimple,dmul,qmul,sdiv,ddiv,ssqrt,dsqrt,
192    vecsimple,veccomplex,vecdiv,veccmp,veccmpsimple,vecperm,
193    vecfloat,vecfdiv,vecdouble,mffgpr,mftgpr,crypto,
194    veclogical,veccmpfx,vecexts,vecmove,
195    htm,htmsimple,dfp"
196   (const_string "integer"))
198 ;; What data size does this instruction work on?
199 ;; This is used for insert, mul and others as necessary.
200 (define_attr "size" "8,16,32,64,128" (const_string "32"))
202 ;; What is the insn_cost for this insn?  The target hook can still override
203 ;; this.  For optimizing for size the "length" attribute is used instead.
204 (define_attr "cost" "" (const_int 0))
206 ;; Is this instruction record form ("dot", signed compare to 0, writing CR0)?
207 ;; This is used for add, logical, shift, exts, mul.
208 (define_attr "dot" "no,yes" (const_string "no"))
210 ;; Does this instruction sign-extend its result?
211 ;; This is used for load insns.
212 (define_attr "sign_extend" "no,yes" (const_string "no"))
214 ;; Does this cr_logical instruction have three operands?  That is, BT != BB.
215 (define_attr "cr_logical_3op" "no,yes" (const_string "no"))
217 ;; Does this instruction use indexed (that is, reg+reg) addressing?
218 ;; This is used for load and store insns.  If operand 0 or 1 is a MEM
219 ;; it is automatically set based on that.  If a load or store instruction
220 ;; has fewer than two operands it needs to set this attribute manually
221 ;; or the compiler will crash.
222 (define_attr "indexed" "no,yes"
223   (if_then_else (ior (match_operand 0 "indexed_address_mem")
224                      (match_operand 1 "indexed_address_mem"))
225                 (const_string "yes")
226                 (const_string "no")))
228 ;; Does this instruction use update addressing?
229 ;; This is used for load and store insns.  See the comments for "indexed".
230 (define_attr "update" "no,yes"
231   (if_then_else (ior (match_operand 0 "update_address_mem")
232                      (match_operand 1 "update_address_mem"))
233                 (const_string "yes")
234                 (const_string "no")))
236 ;; Is this instruction using operands[2] as shift amount, and can that be a
237 ;; register?
238 ;; This is used for shift insns.
239 (define_attr "maybe_var_shift" "no,yes" (const_string "no"))
241 ;; Is this instruction using a shift amount from a register?
242 ;; This is used for shift insns.
243 (define_attr "var_shift" "no,yes"
244   (if_then_else (and (eq_attr "type" "shift")
245                      (eq_attr "maybe_var_shift" "yes"))
246                 (if_then_else (match_operand 2 "gpc_reg_operand")
247                               (const_string "yes")
248                               (const_string "no"))
249                 (const_string "no")))
251 ;; Is copying of this instruction disallowed?
252 (define_attr "cannot_copy" "no,yes" (const_string "no"))
254 ;; Length of the instruction (in bytes).
255 (define_attr "length" "" (const_int 4))
257 ;; Processor type -- this attribute must exactly match the processor_type
258 ;; enumeration in rs6000-opts.h.
259 (define_attr "cpu"
260   "ppc601,ppc603,ppc604,ppc604e,ppc620,ppc630,
261    ppc750,ppc7400,ppc7450,
262    ppc403,ppc405,ppc440,ppc476,
263    ppc8540,ppc8548,ppce300c2,ppce300c3,ppce500mc,ppce500mc64,ppce5500,ppce6500,
264    power4,power5,power6,power7,power8,power9,
265    rs64a,mpccore,cell,ppca2,titan"
266   (const (symbol_ref "(enum attr_cpu) rs6000_tune")))
269 ;; If this instruction is microcoded on the CELL processor
270 ; The default for load extended, the recorded instructions and rotate/shifts by a variable is always microcoded
271 (define_attr "cell_micro" "not,conditional,always"
272   (if_then_else (ior (and (eq_attr "type" "shift,exts,mul")
273                           (eq_attr "dot" "yes"))
274                      (and (eq_attr "type" "load")
275                           (eq_attr "sign_extend" "yes"))
276                      (and (eq_attr "type" "shift")
277                           (eq_attr "var_shift" "yes")))
278                 (const_string "always")
279                 (const_string "not")))
281 (automata_option "ndfa")
283 (include "rs64.md")
284 (include "mpc.md")
285 (include "40x.md")
286 (include "440.md")
287 (include "476.md")
288 (include "601.md")
289 (include "603.md")
290 (include "6xx.md")
291 (include "7xx.md")
292 (include "7450.md")
293 (include "8540.md")
294 (include "e300c2c3.md")
295 (include "e500mc.md")
296 (include "e500mc64.md")
297 (include "e5500.md")
298 (include "e6500.md")
299 (include "power4.md")
300 (include "power5.md")
301 (include "power6.md")
302 (include "power7.md")
303 (include "power8.md")
304 (include "power9.md")
305 (include "cell.md")
306 (include "a2.md")
307 (include "titan.md")
309 (include "predicates.md")
310 (include "constraints.md")
312 (include "darwin.md")
315 ;; Mode iterators
317 ; This mode iterator allows :GPR to be used to indicate the allowable size
318 ; of whole values in GPRs.
319 (define_mode_iterator GPR [SI (DI "TARGET_POWERPC64")])
321 ; And again, for patterns that need two (potentially) different integer modes.
322 (define_mode_iterator GPR2 [SI (DI "TARGET_POWERPC64")])
324 ; Any supported integer mode.
325 (define_mode_iterator INT [QI HI SI DI TI PTI])
327 ; Any supported integer mode that fits in one register.
328 (define_mode_iterator INT1 [QI HI SI (DI "TARGET_POWERPC64")])
330 ; Integer modes supported in VSX registers with ISA 3.0 instructions
331 (define_mode_iterator INT_ISA3 [QI HI SI DI])
333 ; Everything we can extend QImode to.
334 (define_mode_iterator EXTQI [SI (DI "TARGET_POWERPC64")])
336 ; Everything we can extend HImode to.
337 (define_mode_iterator EXTHI [SI (DI "TARGET_POWERPC64")])
339 ; Everything we can extend SImode to.
340 (define_mode_iterator EXTSI [(DI "TARGET_POWERPC64")])
342 ; QImode or HImode for small integer moves and small atomic ops
343 (define_mode_iterator QHI [QI HI])
345 ; QImode, HImode, SImode for fused ops only for GPR loads
346 (define_mode_iterator QHSI [QI HI SI])
348 ; HImode or SImode for sign extended fusion ops
349 (define_mode_iterator HSI [HI SI])
351 ; SImode or DImode, even if DImode doesn't fit in GPRs.
352 (define_mode_iterator SDI [SI DI])
354 ; The size of a pointer.  Also, the size of the value that a record-condition
355 ; (one with a '.') will compare; and the size used for arithmetic carries.
356 (define_mode_iterator P [(SI "TARGET_32BIT") (DI "TARGET_64BIT")])
358 ; Iterator to add PTImode along with TImode (TImode can go in VSX registers,
359 ; PTImode is GPR only)
360 (define_mode_iterator TI2 [TI PTI])
362 ; Any hardware-supported floating-point mode
363 (define_mode_iterator FP [
364   (SF "TARGET_HARD_FLOAT")
365   (DF "TARGET_HARD_FLOAT")
366   (TF "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128")
367   (IF "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128")
368   (KF "TARGET_FLOAT128_TYPE")
369   (DD "TARGET_DFP")
370   (TD "TARGET_DFP")])
372 ; Any fma capable floating-point mode.
373 (define_mode_iterator FMA_F [
374   (SF "TARGET_HARD_FLOAT")
375   (DF "TARGET_HARD_FLOAT || VECTOR_UNIT_VSX_P (DFmode)")
376   (V4SF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)")
377   (V2DF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V2DFmode)")
378   (KF "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (KFmode)")
379   (TF "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (TFmode)")
380   ])
382 ; Floating point move iterators to combine binary and decimal moves
383 (define_mode_iterator FMOVE32 [SF SD])
384 (define_mode_iterator FMOVE64 [DF DD])
385 (define_mode_iterator FMOVE64X [DI DF DD])
386 (define_mode_iterator FMOVE128 [(TF "TARGET_LONG_DOUBLE_128")
387                                 (IF "FLOAT128_IBM_P (IFmode)")
388                                 (TD "TARGET_HARD_FLOAT")])
390 (define_mode_iterator FMOVE128_FPR [(TF "FLOAT128_2REG_P (TFmode)")
391                                     (IF "FLOAT128_2REG_P (IFmode)")
392                                     (TD "TARGET_HARD_FLOAT")])
394 ; Iterators for 128 bit types for direct move
395 (define_mode_iterator FMOVE128_GPR [TI
396                                     V16QI
397                                     V8HI
398                                     V4SI
399                                     V4SF
400                                     V2DI
401                                     V2DF
402                                     V1TI
403                                     (KF    "FLOAT128_VECTOR_P (KFmode)")
404                                     (TF    "FLOAT128_VECTOR_P (TFmode)")])
406 ; Iterator for 128-bit VSX types for pack/unpack
407 (define_mode_iterator FMOVE128_VSX [V1TI KF])
409 ; Iterators for converting to/from TFmode
410 (define_mode_iterator IFKF [IF KF])
412 ; Constraints for moving IF/KFmode.
413 (define_mode_attr IFKF_reg [(IF "d") (KF "wa")])
415 ; Whether a floating point move is ok, don't allow SD without hardware FP
416 (define_mode_attr fmove_ok [(SF "")
417                             (DF "")
418                             (SD "TARGET_HARD_FLOAT")
419                             (DD "")])
421 ; Convert REAL_VALUE to the appropriate bits
422 (define_mode_attr real_value_to_target [(SF "REAL_VALUE_TO_TARGET_SINGLE")
423                                         (DF "REAL_VALUE_TO_TARGET_DOUBLE")
424                                         (SD "REAL_VALUE_TO_TARGET_DECIMAL32")
425                                         (DD "REAL_VALUE_TO_TARGET_DECIMAL64")])
427 ; Whether 0.0 has an all-zero bit pattern
428 (define_mode_attr zero_fp [(SF "j")
429                            (DF "j")
430                            (TF "j")
431                            (IF "j")
432                            (KF "j")
433                            (SD "wn")
434                            (DD "wn")
435                            (TD "wn")])
437 ; Definitions for 64-bit VSX
438 (define_mode_attr f64_vsx [(DF "ws") (DD "wn")])
440 ; Definitions for 64-bit direct move
441 (define_mode_attr f64_dm  [(DF "wk") (DD "wh")])
443 ; Definitions for 64-bit use of altivec registers
444 (define_mode_attr f64_av  [(DF "wv") (DD "wn")])
446 ; Definitions for 64-bit access to ISA 3.0 (power9) vector
447 (define_mode_attr f64_p9  [(DF "wb") (DD "wn")])
449 ; These modes do not fit in integer registers in 32-bit mode.
450 (define_mode_iterator DIFD [DI DF DD])
452 ; Iterator for reciprocal estimate instructions
453 (define_mode_iterator RECIPF [SF DF V4SF V2DF])
455 ; Iterator for just SF/DF
456 (define_mode_iterator SFDF [SF DF])
458 ; Like SFDF, but a different name to match conditional move where the
459 ; comparison operands may be a different mode than the input operands.
460 (define_mode_iterator SFDF2 [SF DF])
462 ; Iterator for 128-bit floating point that uses the IBM double-double format
463 (define_mode_iterator IBM128 [(IF "FLOAT128_IBM_P (IFmode)")
464                               (TF "FLOAT128_IBM_P (TFmode)")])
466 ; Iterator for 128-bit floating point that uses IEEE 128-bit float
467 (define_mode_iterator IEEE128 [(KF "FLOAT128_IEEE_P (KFmode)")
468                                (TF "FLOAT128_IEEE_P (TFmode)")])
470 ; Iterator for 128-bit floating point
471 (define_mode_iterator FLOAT128 [(KF "TARGET_FLOAT128_TYPE")
472                                 (IF "TARGET_FLOAT128_TYPE")
473                                 (TF "TARGET_LONG_DOUBLE_128")])
475 ; Iterator for signbit on 64-bit machines with direct move
476 (define_mode_iterator SIGNBIT [(KF "FLOAT128_VECTOR_P (KFmode)")
477                                (TF "FLOAT128_VECTOR_P (TFmode)")])
479 ; Iterator for ISA 3.0 supported floating point types
480 (define_mode_iterator FP_ISA3 [SF DF])
482 ; SF/DF suffix for traditional floating instructions
483 (define_mode_attr Ftrad         [(SF "s") (DF "")])
485 ; SF/DF suffix for VSX instructions
486 (define_mode_attr Fvsx          [(SF "sp") (DF  "dp")])
488 ; SF/DF constraint for arithmetic on traditional floating point registers
489 (define_mode_attr Ff            [(SF "f") (DF "d") (DI "d")])
491 ; SF/DF constraint for arithmetic on VSX registers using instructions added in
492 ; ISA 2.06 (power7).  This includes instructions that normally target DF mode,
493 ; but are used on SFmode, since internally SFmode values are kept in the DFmode
494 ; format.
495 (define_mode_attr Fv            [(SF "ww") (DF "ws") (DI "wi")])
497 ; SF/DF constraint for arithmetic on VSX registers.  This is intended to be
498 ; used for DFmode instructions added in ISA 2.06 (power7) and SFmode
499 ; instructions added in ISA 2.07 (power8)
500 (define_mode_attr Fv2           [(SF "wy") (DF "ws") (DI "wi")])
502 ; SF/DF constraint for arithmetic on altivec registers
503 (define_mode_attr Fa            [(SF "wu") (DF "wv")])
505 ; s/d suffix for things like sdiv/ddiv
506 (define_mode_attr Fs            [(SF "s")  (DF "d")])
508 ; FRE/FRES support
509 (define_mode_attr Ffre          [(SF "fres") (DF "fre")])
510 (define_mode_attr FFRE          [(SF "FRES") (DF "FRE")])
512 ; Conditional returns.
513 (define_code_iterator any_return [return simple_return])
514 (define_code_attr return_pred [(return "direct_return ()")
515                                (simple_return "1")])
516 (define_code_attr return_str [(return "") (simple_return "simple_")])
518 ; Logical operators.
519 (define_code_iterator iorxor            [ior xor])
520 (define_code_iterator and_ior_xor       [and ior xor])
522 ; Signed/unsigned variants of ops.
523 (define_code_iterator any_extend        [sign_extend zero_extend])
524 (define_code_iterator any_fix           [fix unsigned_fix])
525 (define_code_iterator any_float         [float unsigned_float])
527 (define_code_attr u  [(sign_extend      "")
528                       (zero_extend      "u")
529                       (fix              "")
530                       (unsigned_fix     "u")])
532 (define_code_attr su [(sign_extend      "s")
533                       (zero_extend      "u")
534                       (fix              "s")
535                       (unsigned_fix     "u")
536                       (float            "s")
537                       (unsigned_float   "u")])
539 (define_code_attr az [(sign_extend      "a")
540                       (zero_extend      "z")
541                       (fix              "a")
542                       (unsigned_fix     "z")
543                       (float            "a")
544                       (unsigned_float   "z")])
546 (define_code_attr uns [(fix             "")
547                        (unsigned_fix    "uns")
548                        (float           "")
549                        (unsigned_float  "uns")])
551 ; Various instructions that come in SI and DI forms.
552 ; A generic w/d attribute, for things like cmpw/cmpd.
553 (define_mode_attr wd [(QI    "b")
554                       (HI    "h")
555                       (SI    "w")
556                       (DI    "d")
557                       (V16QI "b")
558                       (V8HI  "h")
559                       (V4SI  "w")
560                       (V2DI  "d")
561                       (V1TI  "q")
562                       (TI    "q")])
564 ;; How many bits in this mode?
565 (define_mode_attr bits [(QI "8") (HI "16") (SI "32") (DI "64")])
567 ; DImode bits
568 (define_mode_attr dbits [(QI "56") (HI "48") (SI "32")])
570 ;; Bitmask for shift instructions
571 (define_mode_attr hH [(SI "h") (DI "H")])
573 ;; A mode twice the size of the given mode
574 (define_mode_attr dmode [(SI "di") (DI "ti")])
575 (define_mode_attr DMODE [(SI "DI") (DI "TI")])
577 ;; Suffix for reload patterns
578 (define_mode_attr ptrsize [(SI "32bit")
579                            (DI "64bit")])
581 (define_mode_attr tptrsize [(SI "TARGET_32BIT")
582                             (DI "TARGET_64BIT")])
584 (define_mode_attr mptrsize [(SI "si")
585                             (DI "di")])
587 (define_mode_attr ptrload [(SI "lwz")
588                            (DI "ld")])
590 (define_mode_attr ptrm [(SI "m")
591                         (DI "Y")])
593 (define_mode_attr rreg [(SF   "f")
594                         (DF   "ws")
595                         (TF   "f")
596                         (TD   "f")
597                         (V4SF "wf")
598                         (V2DF "wd")])
600 (define_mode_attr rreg2 [(SF   "f")
601                          (DF   "d")])
603 (define_mode_attr SI_CONVERT_FP [(SF "TARGET_FCFIDS")
604                                  (DF "TARGET_FCFID")])
606 ;; Mode iterator for logical operations on 128-bit types
607 (define_mode_iterator BOOL_128          [TI
608                                          PTI
609                                          (V16QI "TARGET_ALTIVEC")
610                                          (V8HI  "TARGET_ALTIVEC")
611                                          (V4SI  "TARGET_ALTIVEC")
612                                          (V4SF  "TARGET_ALTIVEC")
613                                          (V2DI  "TARGET_ALTIVEC")
614                                          (V2DF  "TARGET_ALTIVEC")
615                                          (V1TI  "TARGET_ALTIVEC")])
617 ;; For the GPRs we use 3 constraints for register outputs, two that are the
618 ;; same as the output register, and a third where the output register is an
619 ;; early clobber, so we don't have to deal with register overlaps.  For the
620 ;; vector types, we prefer to use the vector registers.  For TI mode, allow
621 ;; either.
623 ;; Mode attribute for boolean operation register constraints for output
624 (define_mode_attr BOOL_REGS_OUTPUT      [(TI    "&r,r,r,wt,v")
625                                          (PTI   "&r,r,r")
626                                          (V16QI "wa,v,&?r,?r,?r")
627                                          (V8HI  "wa,v,&?r,?r,?r")
628                                          (V4SI  "wa,v,&?r,?r,?r")
629                                          (V4SF  "wa,v,&?r,?r,?r")
630                                          (V2DI  "wa,v,&?r,?r,?r")
631                                          (V2DF  "wa,v,&?r,?r,?r")
632                                          (V1TI  "wa,v,&?r,?r,?r")])
634 ;; Mode attribute for boolean operation register constraints for operand1
635 (define_mode_attr BOOL_REGS_OP1         [(TI    "r,0,r,wt,v")
636                                          (PTI   "r,0,r")
637                                          (V16QI "wa,v,r,0,r")
638                                          (V8HI  "wa,v,r,0,r")
639                                          (V4SI  "wa,v,r,0,r")
640                                          (V4SF  "wa,v,r,0,r")
641                                          (V2DI  "wa,v,r,0,r")
642                                          (V2DF  "wa,v,r,0,r")
643                                          (V1TI  "wa,v,r,0,r")])
645 ;; Mode attribute for boolean operation register constraints for operand2
646 (define_mode_attr BOOL_REGS_OP2         [(TI    "r,r,0,wt,v")
647                                          (PTI   "r,r,0")
648                                          (V16QI "wa,v,r,r,0")
649                                          (V8HI  "wa,v,r,r,0")
650                                          (V4SI  "wa,v,r,r,0")
651                                          (V4SF  "wa,v,r,r,0")
652                                          (V2DI  "wa,v,r,r,0")
653                                          (V2DF  "wa,v,r,r,0")
654                                          (V1TI  "wa,v,r,r,0")])
656 ;; Mode attribute for boolean operation register constraints for operand1
657 ;; for one_cmpl.  To simplify things, we repeat the constraint where 0
658 ;; is used for operand1 or operand2
659 (define_mode_attr BOOL_REGS_UNARY       [(TI    "r,0,0,wt,v")
660                                          (PTI   "r,0,0")
661                                          (V16QI "wa,v,r,0,0")
662                                          (V8HI  "wa,v,r,0,0")
663                                          (V4SI  "wa,v,r,0,0")
664                                          (V4SF  "wa,v,r,0,0")
665                                          (V2DI  "wa,v,r,0,0")
666                                          (V2DF  "wa,v,r,0,0")
667                                          (V1TI  "wa,v,r,0,0")])
669 ;; Reload iterator for creating the function to allocate a base register to
670 ;; supplement addressing modes.
671 (define_mode_iterator RELOAD [V16QI V8HI V4SI V2DI V4SF V2DF V1TI
672                               SF SD SI DF DD DI TI PTI KF IF TF])
674 ;; Iterate over smin, smax
675 (define_code_iterator fp_minmax [smin smax])
677 (define_code_attr     minmax    [(smin "min")
678                                  (smax "max")])
680 (define_code_attr     SMINMAX   [(smin "SMIN")
681                                  (smax "SMAX")])
683 ;; Iterator to optimize the following cases:
684 ;;      D-form load to FPR register & move to Altivec register
685 ;;      Move Altivec register to FPR register and store
686 (define_mode_iterator ALTIVEC_DFORM [DF
687                                      (SF "TARGET_P8_VECTOR")
688                                      (DI "TARGET_POWERPC64")])
691 ;; Start with fixed-point load and store insns.  Here we put only the more
692 ;; complex forms.  Basic data transfer is done later.
694 (define_insn "zero_extendqi<mode>2"
695   [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r,^wJwK,^wK")
696         (zero_extend:EXTQI (match_operand:QI 1 "reg_or_mem_operand" "m,r,Z,wK")))]
697   ""
698   "@
699    lbz%U1%X1 %0,%1
700    rlwinm %0,%1,0,0xff
701    lxsibzx %x0,%y1
702    vextractub %0,%1,7"
703   [(set_attr "type" "load,shift,fpload,vecperm")])
705 (define_insn_and_split "*zero_extendqi<mode>2_dot"
706   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
707         (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
708                     (const_int 0)))
709    (clobber (match_scratch:EXTQI 0 "=r,r"))]
710   ""
711   "@
712    andi. %0,%1,0xff
713    #"
714   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
715   [(set (match_dup 0)
716         (zero_extend:EXTQI (match_dup 1)))
717    (set (match_dup 2)
718         (compare:CC (match_dup 0)
719                     (const_int 0)))]
720   ""
721   [(set_attr "type" "logical")
722    (set_attr "dot" "yes")
723    (set_attr "length" "4,8")])
725 (define_insn_and_split "*zero_extendqi<mode>2_dot2"
726   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
727         (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
728                     (const_int 0)))
729    (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
730         (zero_extend:EXTQI (match_dup 1)))]
731   ""
732   "@
733    andi. %0,%1,0xff
734    #"
735   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
736   [(set (match_dup 0)
737         (zero_extend:EXTQI (match_dup 1)))
738    (set (match_dup 2)
739         (compare:CC (match_dup 0)
740                     (const_int 0)))]
741   ""
742   [(set_attr "type" "logical")
743    (set_attr "dot" "yes")
744    (set_attr "length" "4,8")])
747 (define_insn "zero_extendhi<mode>2"
748   [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r,^wJwK,^wK")
749         (zero_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r,Z,wK")))]
750   ""
751   "@
752    lhz%U1%X1 %0,%1
753    rlwinm %0,%1,0,0xffff
754    lxsihzx %x0,%y1
755    vextractuh %0,%1,6"
756   [(set_attr "type" "load,shift,fpload,vecperm")])
758 (define_insn_and_split "*zero_extendhi<mode>2_dot"
759   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
760         (compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
761                     (const_int 0)))
762    (clobber (match_scratch:EXTHI 0 "=r,r"))]
763   ""
764   "@
765    andi. %0,%1,0xffff
766    #"
767   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
768   [(set (match_dup 0)
769         (zero_extend:EXTHI (match_dup 1)))
770    (set (match_dup 2)
771         (compare:CC (match_dup 0)
772                     (const_int 0)))]
773   ""
774   [(set_attr "type" "logical")
775    (set_attr "dot" "yes")
776    (set_attr "length" "4,8")])
778 (define_insn_and_split "*zero_extendhi<mode>2_dot2"
779   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
780         (compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
781                     (const_int 0)))
782    (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
783         (zero_extend:EXTHI (match_dup 1)))]
784   ""
785   "@
786    andi. %0,%1,0xffff
787    #"
788   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
789   [(set (match_dup 0)
790         (zero_extend:EXTHI (match_dup 1)))
791    (set (match_dup 2)
792         (compare:CC (match_dup 0)
793                     (const_int 0)))]
794   ""
795   [(set_attr "type" "logical")
796    (set_attr "dot" "yes")
797    (set_attr "length" "4,8")])
800 (define_insn "zero_extendsi<mode>2"
801   [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r,wz,wu,wj,r,wJwK")
802         (zero_extend:EXTSI (match_operand:SI 1 "reg_or_mem_operand" "m,r,Z,Z,r,wIwH,wJwK")))]
803   ""
804   "@
805    lwz%U1%X1 %0,%1
806    rldicl %0,%1,0,32
807    lfiwzx %0,%y1
808    lxsiwzx %x0,%y1
809    mtvsrwz %x0,%1
810    mfvsrwz %0,%x1
811    xxextractuw %x0,%x1,4"
812   [(set_attr "type" "load,shift,fpload,fpload,mffgpr,mftgpr,vecexts")])
814 (define_insn_and_split "*zero_extendsi<mode>2_dot"
815   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
816         (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
817                     (const_int 0)))
818    (clobber (match_scratch:EXTSI 0 "=r,r"))]
819   ""
820   "@
821    rldicl. %0,%1,0,32
822    #"
823   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
824   [(set (match_dup 0)
825         (zero_extend:DI (match_dup 1)))
826    (set (match_dup 2)
827         (compare:CC (match_dup 0)
828                     (const_int 0)))]
829   ""
830   [(set_attr "type" "shift")
831    (set_attr "dot" "yes")
832    (set_attr "length" "4,8")])
834 (define_insn_and_split "*zero_extendsi<mode>2_dot2"
835   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
836         (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
837                     (const_int 0)))
838    (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
839         (zero_extend:EXTSI (match_dup 1)))]
840   ""
841   "@
842    rldicl. %0,%1,0,32
843    #"
844   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
845   [(set (match_dup 0)
846         (zero_extend:EXTSI (match_dup 1)))
847    (set (match_dup 2)
848         (compare:CC (match_dup 0)
849                     (const_int 0)))]
850   ""
851   [(set_attr "type" "shift")
852    (set_attr "dot" "yes")
853    (set_attr "length" "4,8")])
856 (define_insn "extendqi<mode>2"
857   [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,?*wK")
858         (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,?*wK")))]
859   ""
860   "@
861    extsb %0,%1
862    vextsb2d %0,%1"
863   [(set_attr "type" "exts,vecperm")])
865 (define_insn_and_split "*extendqi<mode>2_dot"
866   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
867         (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
868                     (const_int 0)))
869    (clobber (match_scratch:EXTQI 0 "=r,r"))]
870   ""
871   "@
872    extsb. %0,%1
873    #"
874   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
875   [(set (match_dup 0)
876         (sign_extend:EXTQI (match_dup 1)))
877    (set (match_dup 2)
878         (compare:CC (match_dup 0)
879                     (const_int 0)))]
880   ""
881   [(set_attr "type" "exts")
882    (set_attr "dot" "yes")
883    (set_attr "length" "4,8")])
885 (define_insn_and_split "*extendqi<mode>2_dot2"
886   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
887         (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
888                     (const_int 0)))
889    (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
890         (sign_extend:EXTQI (match_dup 1)))]
891   ""
892   "@
893    extsb. %0,%1
894    #"
895   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
896   [(set (match_dup 0)
897         (sign_extend:EXTQI (match_dup 1)))
898    (set (match_dup 2)
899         (compare:CC (match_dup 0)
900                     (const_int 0)))]
901   ""
902   [(set_attr "type" "exts")
903    (set_attr "dot" "yes")
904    (set_attr "length" "4,8")])
907 (define_expand "extendhi<mode>2"
908   [(set (match_operand:EXTHI 0 "gpc_reg_operand")
909         (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand")))]
910   ""
911   "")
913 (define_insn "*extendhi<mode>2"
914   [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r,?*wK,?*wK")
915         (sign_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r,Z,wK")))]
916   ""
917   "@
918    lha%U1%X1 %0,%1
919    extsh %0,%1
920    #
921    vextsh2d %0,%1"
922   [(set_attr "type" "load,exts,fpload,vecperm")
923    (set_attr "sign_extend" "yes")
924    (set_attr "length" "4,4,8,4")])
926 (define_split
927   [(set (match_operand:EXTHI 0 "altivec_register_operand")
928         (sign_extend:EXTHI
929          (match_operand:HI 1 "indexed_or_indirect_operand")))]
930   "TARGET_P9_VECTOR && reload_completed"
931   [(set (match_dup 2)
932         (match_dup 1))
933    (set (match_dup 0)
934         (sign_extend:EXTHI (match_dup 2)))]
936   operands[2] = gen_rtx_REG (HImode, REGNO (operands[0]));
939 (define_insn_and_split "*extendhi<mode>2_dot"
940   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
941         (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
942                     (const_int 0)))
943    (clobber (match_scratch:EXTHI 0 "=r,r"))]
944   ""
945   "@
946    extsh. %0,%1
947    #"
948   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
949   [(set (match_dup 0)
950         (sign_extend:EXTHI (match_dup 1)))
951    (set (match_dup 2)
952         (compare:CC (match_dup 0)
953                     (const_int 0)))]
954   ""
955   [(set_attr "type" "exts")
956    (set_attr "dot" "yes")
957    (set_attr "length" "4,8")])
959 (define_insn_and_split "*extendhi<mode>2_dot2"
960   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
961         (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
962                     (const_int 0)))
963    (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
964         (sign_extend:EXTHI (match_dup 1)))]
965   ""
966   "@
967    extsh. %0,%1
968    #"
969   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
970   [(set (match_dup 0)
971         (sign_extend:EXTHI (match_dup 1)))
972    (set (match_dup 2)
973         (compare:CC (match_dup 0)
974                     (const_int 0)))]
975   ""
976   [(set_attr "type" "exts")
977    (set_attr "dot" "yes")
978    (set_attr "length" "4,8")])
981 (define_insn "extendsi<mode>2"
982   [(set (match_operand:EXTSI 0 "gpc_reg_operand"
983                      "=r, r,   wl,    wu,    wj,    wK,     wH,    wr")
985         (sign_extend:EXTSI (match_operand:SI 1 "lwa_operand"
986                      "YZ, r,   Z,     Z,     r,     wK,     wH,    ?wIwH")))]
987   ""
988   "@
989    lwa%U1%X1 %0,%1
990    extsw %0,%1
991    lfiwax %0,%y1
992    lxsiwax %x0,%y1
993    mtvsrwa %x0,%1
994    vextsw2d %0,%1
995    #
996    #"
997   [(set_attr "type" "load,exts,fpload,fpload,mffgpr,vecexts,vecperm,mftgpr")
998    (set_attr "sign_extend" "yes")
999    (set_attr "length" "4,4,4,4,4,4,8,8")])
1001 (define_split
1002   [(set (match_operand:EXTSI 0 "int_reg_operand")
1003         (sign_extend:EXTSI (match_operand:SI 1 "vsx_register_operand")))]
1004   "TARGET_DIRECT_MOVE_64BIT && reload_completed"
1005   [(set (match_dup 2)
1006         (match_dup 1))
1007    (set (match_dup 0)
1008         (sign_extend:DI (match_dup 2)))]
1010   operands[2] = gen_rtx_REG (SImode, reg_or_subregno (operands[0]));
1013 (define_split
1014   [(set (match_operand:DI 0 "altivec_register_operand")
1015         (sign_extend:DI (match_operand:SI 1 "altivec_register_operand")))]
1016   "TARGET_P8_VECTOR && !TARGET_P9_VECTOR && reload_completed"
1017   [(const_int 0)]
1019   rtx dest = operands[0];
1020   rtx src = operands[1];
1021   int dest_regno = REGNO (dest);
1022   int src_regno = REGNO (src);
1023   rtx dest_v2di = gen_rtx_REG (V2DImode, dest_regno);
1024   rtx src_v4si = gen_rtx_REG (V4SImode, src_regno);
1026   if (BYTES_BIG_ENDIAN)
1027     {
1028       emit_insn (gen_altivec_vupkhsw (dest_v2di, src_v4si));
1029       emit_insn (gen_vsx_xxspltd_v2di (dest_v2di, dest_v2di, const1_rtx));
1030     }
1031   else
1032     {
1033       emit_insn (gen_altivec_vupklsw (dest_v2di, src_v4si));
1034       emit_insn (gen_vsx_xxspltd_v2di (dest_v2di, dest_v2di, const0_rtx));
1035     }
1036   DONE;
1039 (define_insn_and_split "*extendsi<mode>2_dot"
1040   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1041         (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
1042                     (const_int 0)))
1043    (clobber (match_scratch:EXTSI 0 "=r,r"))]
1044   ""
1045   "@
1046    extsw. %0,%1
1047    #"
1048   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1049   [(set (match_dup 0)
1050         (sign_extend:EXTSI (match_dup 1)))
1051    (set (match_dup 2)
1052         (compare:CC (match_dup 0)
1053                     (const_int 0)))]
1054   ""
1055   [(set_attr "type" "exts")
1056    (set_attr "dot" "yes")
1057    (set_attr "length" "4,8")])
1059 (define_insn_and_split "*extendsi<mode>2_dot2"
1060   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1061         (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
1062                     (const_int 0)))
1063    (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
1064         (sign_extend:EXTSI (match_dup 1)))]
1065   ""
1066   "@
1067    extsw. %0,%1
1068    #"
1069   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1070   [(set (match_dup 0)
1071         (sign_extend:EXTSI (match_dup 1)))
1072    (set (match_dup 2)
1073         (compare:CC (match_dup 0)
1074                     (const_int 0)))]
1075   ""
1076   [(set_attr "type" "exts")
1077    (set_attr "dot" "yes")
1078    (set_attr "length" "4,8")])
1080 ;; IBM 405, 440, 464 and 476 half-word multiplication operations.
1082 (define_insn "*macchwc"
1083   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1084         (compare:CC (plus:SI (mult:SI (ashiftrt:SI
1085                                        (match_operand:SI 2 "gpc_reg_operand" "r")
1086                                        (const_int 16))
1087                                       (sign_extend:SI
1088                                        (match_operand:HI 1 "gpc_reg_operand" "r")))
1089                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1090                     (const_int 0)))
1091    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1092         (plus:SI (mult:SI (ashiftrt:SI
1093                            (match_dup 2)
1094                            (const_int 16))
1095                           (sign_extend:SI
1096                            (match_dup 1)))
1097                  (match_dup 4)))]
1098   "TARGET_MULHW"
1099   "macchw. %0,%1,%2"
1100   [(set_attr "type" "halfmul")])
1102 (define_insn "*macchw"
1103   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1104         (plus:SI (mult:SI (ashiftrt:SI
1105                            (match_operand:SI 2 "gpc_reg_operand" "r")
1106                            (const_int 16))
1107                           (sign_extend:SI
1108                            (match_operand:HI 1 "gpc_reg_operand" "r")))
1109                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1110   "TARGET_MULHW"
1111   "macchw %0,%1,%2"
1112   [(set_attr "type" "halfmul")])
1114 (define_insn "*macchwuc"
1115   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1116         (compare:CC (plus:SI (mult:SI (lshiftrt:SI
1117                                        (match_operand:SI 2 "gpc_reg_operand" "r")
1118                                        (const_int 16))
1119                                       (zero_extend:SI
1120                                        (match_operand:HI 1 "gpc_reg_operand" "r")))
1121                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1122                     (const_int 0)))
1123    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1124         (plus:SI (mult:SI (lshiftrt:SI
1125                            (match_dup 2)
1126                            (const_int 16))
1127                           (zero_extend:SI
1128                            (match_dup 1)))
1129                  (match_dup 4)))]
1130   "TARGET_MULHW"
1131   "macchwu. %0,%1,%2"
1132   [(set_attr "type" "halfmul")])
1134 (define_insn "*macchwu"
1135   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1136         (plus:SI (mult:SI (lshiftrt:SI
1137                            (match_operand:SI 2 "gpc_reg_operand" "r")
1138                            (const_int 16))
1139                           (zero_extend:SI
1140                            (match_operand:HI 1 "gpc_reg_operand" "r")))
1141                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1142   "TARGET_MULHW"
1143   "macchwu %0,%1,%2"
1144   [(set_attr "type" "halfmul")])
1146 (define_insn "*machhwc"
1147   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1148         (compare:CC (plus:SI (mult:SI (ashiftrt:SI
1149                                        (match_operand:SI 1 "gpc_reg_operand" "%r")
1150                                        (const_int 16))
1151                                       (ashiftrt:SI
1152                                        (match_operand:SI 2 "gpc_reg_operand" "r")
1153                                        (const_int 16)))
1154                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1155                     (const_int 0)))
1156    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1157         (plus:SI (mult:SI (ashiftrt:SI
1158                            (match_dup 1)
1159                            (const_int 16))
1160                           (ashiftrt:SI
1161                            (match_dup 2)
1162                            (const_int 16)))
1163                  (match_dup 4)))]
1164   "TARGET_MULHW"
1165   "machhw. %0,%1,%2"
1166   [(set_attr "type" "halfmul")])
1168 (define_insn "*machhw"
1169   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1170         (plus:SI (mult:SI (ashiftrt:SI
1171                            (match_operand:SI 1 "gpc_reg_operand" "%r")
1172                            (const_int 16))
1173                           (ashiftrt:SI
1174                            (match_operand:SI 2 "gpc_reg_operand" "r")
1175                            (const_int 16)))
1176                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1177   "TARGET_MULHW"
1178   "machhw %0,%1,%2"
1179   [(set_attr "type" "halfmul")])
1181 (define_insn "*machhwuc"
1182   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1183         (compare:CC (plus:SI (mult:SI (lshiftrt:SI
1184                                        (match_operand:SI 1 "gpc_reg_operand" "%r")
1185                                        (const_int 16))
1186                                       (lshiftrt:SI
1187                                        (match_operand:SI 2 "gpc_reg_operand" "r")
1188                                        (const_int 16)))
1189                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1190                     (const_int 0)))
1191    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1192         (plus:SI (mult:SI (lshiftrt:SI
1193                            (match_dup 1)
1194                            (const_int 16))
1195                           (lshiftrt:SI
1196                            (match_dup 2)
1197                            (const_int 16)))
1198                  (match_dup 4)))]
1199   "TARGET_MULHW"
1200   "machhwu. %0,%1,%2"
1201   [(set_attr "type" "halfmul")])
1203 (define_insn "*machhwu"
1204   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1205         (plus:SI (mult:SI (lshiftrt:SI
1206                            (match_operand:SI 1 "gpc_reg_operand" "%r")
1207                            (const_int 16))
1208                           (lshiftrt:SI
1209                            (match_operand:SI 2 "gpc_reg_operand" "r")
1210                            (const_int 16)))
1211                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1212   "TARGET_MULHW"
1213   "machhwu %0,%1,%2"
1214   [(set_attr "type" "halfmul")])
1216 (define_insn "*maclhwc"
1217   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1218         (compare:CC (plus:SI (mult:SI (sign_extend:SI
1219                                        (match_operand:HI 1 "gpc_reg_operand" "%r"))
1220                                       (sign_extend:SI
1221                                        (match_operand:HI 2 "gpc_reg_operand" "r")))
1222                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1223                     (const_int 0)))
1224    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1225         (plus:SI (mult:SI (sign_extend:SI
1226                            (match_dup 1))
1227                           (sign_extend:SI
1228                            (match_dup 2)))
1229                  (match_dup 4)))]
1230   "TARGET_MULHW"
1231   "maclhw. %0,%1,%2"
1232   [(set_attr "type" "halfmul")])
1234 (define_insn "*maclhw"
1235   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1236         (plus:SI (mult:SI (sign_extend:SI
1237                            (match_operand:HI 1 "gpc_reg_operand" "%r"))
1238                           (sign_extend:SI
1239                            (match_operand:HI 2 "gpc_reg_operand" "r")))
1240                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1241   "TARGET_MULHW"
1242   "maclhw %0,%1,%2"
1243   [(set_attr "type" "halfmul")])
1245 (define_insn "*maclhwuc"
1246   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1247         (compare:CC (plus:SI (mult:SI (zero_extend:SI
1248                                        (match_operand:HI 1 "gpc_reg_operand" "%r"))
1249                                       (zero_extend:SI
1250                                        (match_operand:HI 2 "gpc_reg_operand" "r")))
1251                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1252                     (const_int 0)))
1253    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1254         (plus:SI (mult:SI (zero_extend:SI
1255                            (match_dup 1))
1256                           (zero_extend:SI
1257                            (match_dup 2)))
1258                  (match_dup 4)))]
1259   "TARGET_MULHW"
1260   "maclhwu. %0,%1,%2"
1261   [(set_attr "type" "halfmul")])
1263 (define_insn "*maclhwu"
1264   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1265         (plus:SI (mult:SI (zero_extend:SI
1266                            (match_operand:HI 1 "gpc_reg_operand" "%r"))
1267                           (zero_extend:SI
1268                            (match_operand:HI 2 "gpc_reg_operand" "r")))
1269                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1270   "TARGET_MULHW"
1271   "maclhwu %0,%1,%2"
1272   [(set_attr "type" "halfmul")])
1274 (define_insn "*nmacchwc"
1275   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1276         (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1277                               (mult:SI (ashiftrt:SI
1278                                         (match_operand:SI 2 "gpc_reg_operand" "r")
1279                                         (const_int 16))
1280                                        (sign_extend:SI
1281                                         (match_operand:HI 1 "gpc_reg_operand" "r"))))
1282                     (const_int 0)))
1283    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1284         (minus:SI (match_dup 4)
1285                   (mult:SI (ashiftrt:SI
1286                             (match_dup 2)
1287                             (const_int 16))
1288                            (sign_extend:SI
1289                             (match_dup 1)))))]
1290   "TARGET_MULHW"
1291   "nmacchw. %0,%1,%2"
1292   [(set_attr "type" "halfmul")])
1294 (define_insn "*nmacchw"
1295   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1296         (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1297                   (mult:SI (ashiftrt:SI
1298                             (match_operand:SI 2 "gpc_reg_operand" "r")
1299                             (const_int 16))
1300                            (sign_extend:SI
1301                             (match_operand:HI 1 "gpc_reg_operand" "r")))))]
1302   "TARGET_MULHW"
1303   "nmacchw %0,%1,%2"
1304   [(set_attr "type" "halfmul")])
1306 (define_insn "*nmachhwc"
1307   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1308         (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1309                               (mult:SI (ashiftrt:SI
1310                                         (match_operand:SI 1 "gpc_reg_operand" "%r")
1311                                         (const_int 16))
1312                                        (ashiftrt:SI
1313                                         (match_operand:SI 2 "gpc_reg_operand" "r")
1314                                         (const_int 16))))
1315                     (const_int 0)))
1316    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1317         (minus:SI (match_dup 4)
1318                   (mult:SI (ashiftrt:SI
1319                             (match_dup 1)
1320                             (const_int 16))
1321                            (ashiftrt:SI
1322                             (match_dup 2)
1323                             (const_int 16)))))]
1324   "TARGET_MULHW"
1325   "nmachhw. %0,%1,%2"
1326   [(set_attr "type" "halfmul")])
1328 (define_insn "*nmachhw"
1329   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1330         (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1331                   (mult:SI (ashiftrt:SI
1332                             (match_operand:SI 1 "gpc_reg_operand" "%r")
1333                             (const_int 16))
1334                            (ashiftrt:SI
1335                             (match_operand:SI 2 "gpc_reg_operand" "r")
1336                             (const_int 16)))))]
1337   "TARGET_MULHW"
1338   "nmachhw %0,%1,%2"
1339   [(set_attr "type" "halfmul")])
1341 (define_insn "*nmaclhwc"
1342   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1343         (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1344                               (mult:SI (sign_extend:SI
1345                                         (match_operand:HI 1 "gpc_reg_operand" "%r"))
1346                                        (sign_extend:SI
1347                                         (match_operand:HI 2 "gpc_reg_operand" "r"))))
1348                     (const_int 0)))
1349    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1350         (minus:SI (match_dup 4)
1351                   (mult:SI (sign_extend:SI
1352                             (match_dup 1))
1353                            (sign_extend:SI
1354                             (match_dup 2)))))]
1355   "TARGET_MULHW"
1356   "nmaclhw. %0,%1,%2"
1357   [(set_attr "type" "halfmul")])
1359 (define_insn "*nmaclhw"
1360   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1361         (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1362                   (mult:SI (sign_extend:SI
1363                             (match_operand:HI 1 "gpc_reg_operand" "%r"))
1364                            (sign_extend:SI
1365                             (match_operand:HI 2 "gpc_reg_operand" "r")))))]
1366   "TARGET_MULHW"
1367   "nmaclhw %0,%1,%2"
1368   [(set_attr "type" "halfmul")])
1370 (define_insn "*mulchwc"
1371   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1372         (compare:CC (mult:SI (ashiftrt:SI
1373                               (match_operand:SI 2 "gpc_reg_operand" "r")
1374                               (const_int 16))
1375                              (sign_extend:SI
1376                               (match_operand:HI 1 "gpc_reg_operand" "r")))
1377                     (const_int 0)))
1378    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1379         (mult:SI (ashiftrt:SI
1380                   (match_dup 2)
1381                   (const_int 16))
1382                  (sign_extend:SI
1383                   (match_dup 1))))]
1384   "TARGET_MULHW"
1385   "mulchw. %0,%1,%2"
1386   [(set_attr "type" "halfmul")])
1388 (define_insn "*mulchw"
1389   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1390         (mult:SI (ashiftrt:SI
1391                   (match_operand:SI 2 "gpc_reg_operand" "r")
1392                   (const_int 16))
1393                  (sign_extend:SI
1394                   (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1395   "TARGET_MULHW"
1396   "mulchw %0,%1,%2"
1397   [(set_attr "type" "halfmul")])
1399 (define_insn "*mulchwuc"
1400   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1401         (compare:CC (mult:SI (lshiftrt:SI
1402                               (match_operand:SI 2 "gpc_reg_operand" "r")
1403                               (const_int 16))
1404                              (zero_extend:SI
1405                               (match_operand:HI 1 "gpc_reg_operand" "r")))
1406                     (const_int 0)))
1407    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1408         (mult:SI (lshiftrt:SI
1409                   (match_dup 2)
1410                   (const_int 16))
1411                  (zero_extend:SI
1412                   (match_dup 1))))]
1413   "TARGET_MULHW"
1414   "mulchwu. %0,%1,%2"
1415   [(set_attr "type" "halfmul")])
1417 (define_insn "*mulchwu"
1418   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1419         (mult:SI (lshiftrt:SI
1420                   (match_operand:SI 2 "gpc_reg_operand" "r")
1421                   (const_int 16))
1422                  (zero_extend:SI
1423                   (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1424   "TARGET_MULHW"
1425   "mulchwu %0,%1,%2"
1426   [(set_attr "type" "halfmul")])
1428 (define_insn "*mulhhwc"
1429   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1430         (compare:CC (mult:SI (ashiftrt:SI
1431                               (match_operand:SI 1 "gpc_reg_operand" "%r")
1432                               (const_int 16))
1433                              (ashiftrt:SI
1434                               (match_operand:SI 2 "gpc_reg_operand" "r")
1435                               (const_int 16)))
1436                     (const_int 0)))
1437    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1438         (mult:SI (ashiftrt:SI
1439                   (match_dup 1)
1440                   (const_int 16))
1441                  (ashiftrt:SI
1442                   (match_dup 2)
1443                   (const_int 16))))]
1444   "TARGET_MULHW"
1445   "mulhhw. %0,%1,%2"
1446   [(set_attr "type" "halfmul")])
1448 (define_insn "*mulhhw"
1449   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1450         (mult:SI (ashiftrt:SI
1451                   (match_operand:SI 1 "gpc_reg_operand" "%r")
1452                   (const_int 16))
1453                  (ashiftrt:SI
1454                   (match_operand:SI 2 "gpc_reg_operand" "r")
1455                   (const_int 16))))]
1456   "TARGET_MULHW"
1457   "mulhhw %0,%1,%2"
1458   [(set_attr "type" "halfmul")])
1460 (define_insn "*mulhhwuc"
1461   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1462         (compare:CC (mult:SI (lshiftrt:SI
1463                               (match_operand:SI 1 "gpc_reg_operand" "%r")
1464                               (const_int 16))
1465                              (lshiftrt:SI
1466                               (match_operand:SI 2 "gpc_reg_operand" "r")
1467                               (const_int 16)))
1468                     (const_int 0)))
1469    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1470         (mult:SI (lshiftrt:SI
1471                   (match_dup 1)
1472                   (const_int 16))
1473                  (lshiftrt:SI
1474                   (match_dup 2)
1475                   (const_int 16))))]
1476   "TARGET_MULHW"
1477   "mulhhwu. %0,%1,%2"
1478   [(set_attr "type" "halfmul")])
1480 (define_insn "*mulhhwu"
1481   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1482         (mult:SI (lshiftrt:SI
1483                   (match_operand:SI 1 "gpc_reg_operand" "%r")
1484                   (const_int 16))
1485                  (lshiftrt:SI
1486                   (match_operand:SI 2 "gpc_reg_operand" "r")
1487                   (const_int 16))))]
1488   "TARGET_MULHW"
1489   "mulhhwu %0,%1,%2"
1490   [(set_attr "type" "halfmul")])
1492 (define_insn "*mullhwc"
1493   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1494         (compare:CC (mult:SI (sign_extend:SI
1495                               (match_operand:HI 1 "gpc_reg_operand" "%r"))
1496                              (sign_extend:SI
1497                               (match_operand:HI 2 "gpc_reg_operand" "r")))
1498                     (const_int 0)))
1499    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1500         (mult:SI (sign_extend:SI
1501                   (match_dup 1))
1502                  (sign_extend:SI
1503                   (match_dup 2))))]
1504   "TARGET_MULHW"
1505   "mullhw. %0,%1,%2"
1506   [(set_attr "type" "halfmul")])
1508 (define_insn "*mullhw"
1509   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1510         (mult:SI (sign_extend:SI
1511                   (match_operand:HI 1 "gpc_reg_operand" "%r"))
1512                  (sign_extend:SI
1513                   (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1514   "TARGET_MULHW"
1515   "mullhw %0,%1,%2"
1516   [(set_attr "type" "halfmul")])
1518 (define_insn "*mullhwuc"
1519   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1520         (compare:CC (mult:SI (zero_extend:SI
1521                               (match_operand:HI 1 "gpc_reg_operand" "%r"))
1522                              (zero_extend:SI
1523                               (match_operand:HI 2 "gpc_reg_operand" "r")))
1524                     (const_int 0)))
1525    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1526         (mult:SI (zero_extend:SI
1527                   (match_dup 1))
1528                  (zero_extend:SI
1529                   (match_dup 2))))]
1530   "TARGET_MULHW"
1531   "mullhwu. %0,%1,%2"
1532   [(set_attr "type" "halfmul")])
1534 (define_insn "*mullhwu"
1535   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1536         (mult:SI (zero_extend:SI
1537                   (match_operand:HI 1 "gpc_reg_operand" "%r"))
1538                  (zero_extend:SI
1539                   (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1540   "TARGET_MULHW"
1541   "mullhwu %0,%1,%2"
1542   [(set_attr "type" "halfmul")])
1544 ;; IBM 405, 440, 464 and 476 string-search dlmzb instruction support.
1545 (define_insn "dlmzb"
1546   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1547         (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
1548                     (match_operand:SI 2 "gpc_reg_operand" "r")]
1549                    UNSPEC_DLMZB_CR))
1550    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1551         (unspec:SI [(match_dup 1)
1552                     (match_dup 2)]
1553                    UNSPEC_DLMZB))]
1554   "TARGET_DLMZB"
1555   "dlmzb. %0,%1,%2")
1557 (define_expand "strlensi"
1558   [(set (match_operand:SI 0 "gpc_reg_operand")
1559         (unspec:SI [(match_operand:BLK 1 "general_operand")
1560                     (match_operand:QI 2 "const_int_operand")
1561                     (match_operand 3 "const_int_operand")]
1562                    UNSPEC_DLMZB_STRLEN))
1563    (clobber (match_scratch:CC 4))]
1564   "TARGET_DLMZB && WORDS_BIG_ENDIAN && !optimize_size"
1566   rtx result = operands[0];
1567   rtx src = operands[1];
1568   rtx search_char = operands[2];
1569   rtx align = operands[3];
1570   rtx addr, scratch_string, word1, word2, scratch_dlmzb;
1571   rtx loop_label, end_label, mem, cr0, cond;
1572   if (search_char != const0_rtx
1573       || !CONST_INT_P (align)
1574       || INTVAL (align) < 8)
1575         FAIL;
1576   word1 = gen_reg_rtx (SImode);
1577   word2 = gen_reg_rtx (SImode);
1578   scratch_dlmzb = gen_reg_rtx (SImode);
1579   scratch_string = gen_reg_rtx (Pmode);
1580   loop_label = gen_label_rtx ();
1581   end_label = gen_label_rtx ();
1582   addr = force_reg (Pmode, XEXP (src, 0));
1583   emit_move_insn (scratch_string, addr);
1584   emit_label (loop_label);
1585   mem = change_address (src, SImode, scratch_string);
1586   emit_move_insn (word1, mem);
1587   emit_move_insn (word2, adjust_address (mem, SImode, 4));
1588   cr0 = gen_rtx_REG (CCmode, CR0_REGNO);
1589   emit_insn (gen_dlmzb (scratch_dlmzb, word1, word2, cr0));
1590   cond = gen_rtx_NE (VOIDmode, cr0, const0_rtx);
1591   emit_jump_insn (gen_rtx_SET (pc_rtx,
1592                                gen_rtx_IF_THEN_ELSE (VOIDmode,
1593                                                      cond,
1594                                                      gen_rtx_LABEL_REF
1595                                                        (VOIDmode,
1596                                                         end_label),
1597                                                      pc_rtx)));
1598   emit_insn (gen_addsi3 (scratch_string, scratch_string, GEN_INT (8)));
1599   emit_jump_insn (gen_rtx_SET (pc_rtx,
1600                                gen_rtx_LABEL_REF (VOIDmode, loop_label)));
1601   emit_barrier ();
1602   emit_label (end_label);
1603   emit_insn (gen_addsi3 (scratch_string, scratch_string, scratch_dlmzb));
1604   emit_insn (gen_subsi3 (result, scratch_string, addr));
1605   emit_insn (gen_addsi3 (result, result, constm1_rtx));
1606   DONE;
1609 ;; Fixed-point arithmetic insns.
1611 (define_expand "add<mode>3"
1612   [(set (match_operand:SDI 0 "gpc_reg_operand")
1613         (plus:SDI (match_operand:SDI 1 "gpc_reg_operand")
1614                   (match_operand:SDI 2 "reg_or_add_cint_operand")))]
1615   ""
1617   if (<MODE>mode == DImode && !TARGET_POWERPC64)
1618     {
1619       rtx lo0 = gen_lowpart (SImode, operands[0]);
1620       rtx lo1 = gen_lowpart (SImode, operands[1]);
1621       rtx lo2 = gen_lowpart (SImode, operands[2]);
1622       rtx hi0 = gen_highpart (SImode, operands[0]);
1623       rtx hi1 = gen_highpart (SImode, operands[1]);
1624       rtx hi2 = gen_highpart_mode (SImode, DImode, operands[2]);
1626       if (!reg_or_short_operand (lo2, SImode))
1627         lo2 = force_reg (SImode, lo2);
1628       if (!adde_operand (hi2, SImode))
1629         hi2 = force_reg (SImode, hi2);
1631       emit_insn (gen_addsi3_carry (lo0, lo1, lo2));
1632       emit_insn (gen_addsi3_carry_in (hi0, hi1, hi2));
1633       DONE;
1634     }
1636   if (CONST_INT_P (operands[2]) && !add_operand (operands[2], <MODE>mode))
1637     {
1638       rtx tmp = ((!can_create_pseudo_p ()
1639                   || rtx_equal_p (operands[0], operands[1]))
1640                  ? operands[0] : gen_reg_rtx (<MODE>mode));
1642       /* Adding a constant to r0 is not a valid insn, so use a different
1643          strategy in that case.  */
1644       if (reg_or_subregno (operands[1]) == 0 || reg_or_subregno (tmp) == 0)
1645         {
1646           if (operands[0] == operands[1])
1647             FAIL;
1648           rs6000_emit_move (operands[0], operands[2], <MODE>mode);
1649           emit_insn (gen_add<mode>3 (operands[0], operands[1], operands[0]));
1650           DONE;
1651         }
1653       HOST_WIDE_INT val = INTVAL (operands[2]);
1654       HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1655       HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1657       if (<MODE>mode == DImode && !satisfies_constraint_L (GEN_INT (rest)))
1658         FAIL;
1660       /* The ordering here is important for the prolog expander.
1661          When space is allocated from the stack, adding 'low' first may
1662          produce a temporary deallocation (which would be bad).  */
1663       emit_insn (gen_add<mode>3 (tmp, operands[1], GEN_INT (rest)));
1664       emit_insn (gen_add<mode>3 (operands[0], tmp, GEN_INT (low)));
1665       DONE;
1666     }
1669 (define_insn "*add<mode>3"
1670   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r,r")
1671         (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b,b")
1672                   (match_operand:GPR 2 "add_operand" "r,I,L")))]
1673   ""
1674   "@
1675    add %0,%1,%2
1676    addi %0,%1,%2
1677    addis %0,%1,%v2"
1678   [(set_attr "type" "add")])
1680 (define_insn "*addsi3_high"
1681   [(set (match_operand:SI 0 "gpc_reg_operand" "=b")
1682         (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
1683                  (high:SI (match_operand 2 "" ""))))]
1684   "TARGET_MACHO && !TARGET_64BIT"
1685   "addis %0,%1,ha16(%2)"
1686   [(set_attr "type" "add")])
1688 (define_insn_and_split "*add<mode>3_dot"
1689   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1690         (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
1691                               (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
1692                     (const_int 0)))
1693    (clobber (match_scratch:GPR 0 "=r,r"))]
1694   "<MODE>mode == Pmode"
1695   "@
1696    add. %0,%1,%2
1697    #"
1698   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1699   [(set (match_dup 0)
1700         (plus:GPR (match_dup 1)
1701                  (match_dup 2)))
1702    (set (match_dup 3)
1703         (compare:CC (match_dup 0)
1704                     (const_int 0)))]
1705   ""
1706   [(set_attr "type" "add")
1707    (set_attr "dot" "yes")
1708    (set_attr "length" "4,8")])
1710 (define_insn_and_split "*add<mode>3_dot2"
1711   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1712         (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
1713                               (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
1714                     (const_int 0)))
1715    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1716         (plus:GPR (match_dup 1)
1717                   (match_dup 2)))]
1718   "<MODE>mode == Pmode"
1719   "@
1720    add. %0,%1,%2
1721    #"
1722   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1723   [(set (match_dup 0)
1724         (plus:GPR (match_dup 1)
1725                   (match_dup 2)))
1726    (set (match_dup 3)
1727         (compare:CC (match_dup 0)
1728                     (const_int 0)))]
1729   ""
1730   [(set_attr "type" "add")
1731    (set_attr "dot" "yes")
1732    (set_attr "length" "4,8")])
1734 (define_insn_and_split "*add<mode>3_imm_dot"
1735   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1736         (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b")
1737                               (match_operand:GPR 2 "short_cint_operand" "I,I"))
1738                     (const_int 0)))
1739    (clobber (match_scratch:GPR 0 "=r,r"))
1740    (clobber (reg:GPR CA_REGNO))]
1741   "<MODE>mode == Pmode"
1742   "@
1743    addic. %0,%1,%2
1744    #"
1745   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1746   [(set (match_dup 0)
1747         (plus:GPR (match_dup 1)
1748                   (match_dup 2)))
1749    (set (match_dup 3)
1750         (compare:CC (match_dup 0)
1751                     (const_int 0)))]
1752   ""
1753   [(set_attr "type" "add")
1754    (set_attr "dot" "yes")
1755    (set_attr "length" "4,8")])
1757 (define_insn_and_split "*add<mode>3_imm_dot2"
1758   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1759         (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b")
1760                               (match_operand:GPR 2 "short_cint_operand" "I,I"))
1761                     (const_int 0)))
1762    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1763         (plus:GPR (match_dup 1)
1764                   (match_dup 2)))
1765    (clobber (reg:GPR CA_REGNO))]
1766   "<MODE>mode == Pmode"
1767   "@
1768    addic. %0,%1,%2
1769    #"
1770   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1771   [(set (match_dup 0)
1772         (plus:GPR (match_dup 1)
1773                   (match_dup 2)))
1774    (set (match_dup 3)
1775         (compare:CC (match_dup 0)
1776                     (const_int 0)))]
1777   ""
1778   [(set_attr "type" "add")
1779    (set_attr "dot" "yes")
1780    (set_attr "length" "4,8")])
1782 ;; Split an add that we can't do in one insn into two insns, each of which
1783 ;; does one 16-bit part.  This is used by combine.  Note that the low-order
1784 ;; add should be last in case the result gets used in an address.
1786 (define_split
1787   [(set (match_operand:GPR 0 "gpc_reg_operand")
1788         (plus:GPR (match_operand:GPR 1 "gpc_reg_operand")
1789                   (match_operand:GPR 2 "non_add_cint_operand")))]
1790   ""
1791   [(set (match_dup 0) (plus:GPR (match_dup 1) (match_dup 3)))
1792    (set (match_dup 0) (plus:GPR (match_dup 0) (match_dup 4)))]
1794   HOST_WIDE_INT val = INTVAL (operands[2]);
1795   HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1796   HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1798   operands[4] = GEN_INT (low);
1799   if (<MODE>mode == SImode || satisfies_constraint_L (GEN_INT (rest)))
1800     operands[3] = GEN_INT (rest);
1801   else if (can_create_pseudo_p ())
1802     {
1803       operands[3] = gen_reg_rtx (DImode);
1804       emit_move_insn (operands[3], operands[2]);
1805       emit_insn (gen_adddi3 (operands[0], operands[1], operands[3]));
1806       DONE;
1807     }
1808   else
1809     FAIL;
1813 (define_insn "add<mode>3_carry"
1814   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1815         (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1816                 (match_operand:P 2 "reg_or_short_operand" "rI")))
1817    (set (reg:P CA_REGNO)
1818         (ltu:P (plus:P (match_dup 1)
1819                        (match_dup 2))
1820                (match_dup 1)))]
1821   ""
1822   "add%I2c %0,%1,%2"
1823   [(set_attr "type" "add")])
1825 (define_insn "*add<mode>3_imm_carry_pos"
1826   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1827         (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1828                 (match_operand:P 2 "short_cint_operand" "n")))
1829    (set (reg:P CA_REGNO)
1830         (geu:P (match_dup 1)
1831                (match_operand:P 3 "const_int_operand" "n")))]
1832   "INTVAL (operands[2]) > 0
1833    && INTVAL (operands[2]) + INTVAL (operands[3]) == 0"
1834   "addic %0,%1,%2"
1835   [(set_attr "type" "add")])
1837 (define_insn "*add<mode>3_imm_carry_0"
1838   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1839         (match_operand:P 1 "gpc_reg_operand" "r"))
1840    (set (reg:P CA_REGNO)
1841         (const_int 0))]
1842   ""
1843   "addic %0,%1,0"
1844   [(set_attr "type" "add")])
1846 (define_insn "*add<mode>3_imm_carry_m1"
1847   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1848         (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1849                 (const_int -1)))
1850    (set (reg:P CA_REGNO)
1851         (ne:P (match_dup 1)
1852               (const_int 0)))]
1853   ""
1854   "addic %0,%1,-1"
1855   [(set_attr "type" "add")])
1857 (define_insn "*add<mode>3_imm_carry_neg"
1858   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1859         (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1860                 (match_operand:P 2 "short_cint_operand" "n")))
1861    (set (reg:P CA_REGNO)
1862         (gtu:P (match_dup 1)
1863                (match_operand:P 3 "const_int_operand" "n")))]
1864   "INTVAL (operands[2]) < 0
1865    && INTVAL (operands[2]) + INTVAL (operands[3]) == -1"
1866   "addic %0,%1,%2"
1867   [(set_attr "type" "add")])
1870 (define_expand "add<mode>3_carry_in"
1871   [(parallel [
1872      (set (match_operand:GPR 0 "gpc_reg_operand")
1873           (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand")
1874                               (match_operand:GPR 2 "adde_operand"))
1875                     (reg:GPR CA_REGNO)))
1876      (clobber (reg:GPR CA_REGNO))])]
1877   ""
1879   if (operands[2] == const0_rtx)
1880     {
1881       emit_insn (gen_add<mode>3_carry_in_0 (operands[0], operands[1]));
1882       DONE;
1883     }
1884   if (operands[2] == constm1_rtx)
1885     {
1886       emit_insn (gen_add<mode>3_carry_in_m1 (operands[0], operands[1]));
1887       DONE;
1888     }
1891 (define_insn "*add<mode>3_carry_in_internal"
1892   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1893         (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1894                             (match_operand:GPR 2 "gpc_reg_operand" "r"))
1895                   (reg:GPR CA_REGNO)))
1896    (clobber (reg:GPR CA_REGNO))]
1897   ""
1898   "adde %0,%1,%2"
1899   [(set_attr "type" "add")])
1901 (define_insn "*add<mode>3_carry_in_internal2"
1902   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1903         (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1904                             (reg:GPR CA_REGNO))
1905                   (match_operand:GPR 2 "gpc_reg_operand" "r")))
1906    (clobber (reg:GPR CA_REGNO))]
1907   ""
1908   "adde %0,%1,%2"
1909   [(set_attr "type" "add")])
1911 (define_insn "add<mode>3_carry_in_0"
1912   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1913         (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1914                   (reg:GPR CA_REGNO)))
1915    (clobber (reg:GPR CA_REGNO))]
1916   ""
1917   "addze %0,%1"
1918   [(set_attr "type" "add")])
1920 (define_insn "add<mode>3_carry_in_m1"
1921   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1922         (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1923                             (reg:GPR CA_REGNO))
1924                   (const_int -1)))
1925    (clobber (reg:GPR CA_REGNO))]
1926   ""
1927   "addme %0,%1"
1928   [(set_attr "type" "add")])
1931 (define_expand "one_cmpl<mode>2"
1932   [(set (match_operand:SDI 0 "gpc_reg_operand")
1933         (not:SDI (match_operand:SDI 1 "gpc_reg_operand")))]
1934   ""
1936   if (<MODE>mode == DImode && !TARGET_POWERPC64)
1937     {
1938       rs6000_split_logical (operands, NOT, false, false, false);
1939       DONE;
1940     }
1943 (define_insn "*one_cmpl<mode>2"
1944   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1945         (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
1946   ""
1947   "not %0,%1")
1949 (define_insn_and_split "*one_cmpl<mode>2_dot"
1950   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1951         (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
1952                     (const_int 0)))
1953    (clobber (match_scratch:GPR 0 "=r,r"))]
1954   "<MODE>mode == Pmode"
1955   "@
1956    not. %0,%1
1957    #"
1958   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1959   [(set (match_dup 0)
1960         (not:GPR (match_dup 1)))
1961    (set (match_dup 2)
1962         (compare:CC (match_dup 0)
1963                     (const_int 0)))]
1964   ""
1965   [(set_attr "type" "logical")
1966    (set_attr "dot" "yes")
1967    (set_attr "length" "4,8")])
1969 (define_insn_and_split "*one_cmpl<mode>2_dot2"
1970   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1971         (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
1972                     (const_int 0)))
1973    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1974         (not:GPR (match_dup 1)))]
1975   "<MODE>mode == Pmode"
1976   "@
1977    not. %0,%1
1978    #"
1979   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1980   [(set (match_dup 0)
1981         (not:GPR (match_dup 1)))
1982    (set (match_dup 2)
1983         (compare:CC (match_dup 0)
1984                     (const_int 0)))]
1985   ""
1986   [(set_attr "type" "logical")
1987    (set_attr "dot" "yes")
1988    (set_attr "length" "4,8")])
1991 (define_expand "sub<mode>3"
1992   [(set (match_operand:SDI 0 "gpc_reg_operand")
1993         (minus:SDI (match_operand:SDI 1 "reg_or_short_operand")
1994                    (match_operand:SDI 2 "gpc_reg_operand")))]
1995   ""
1997   if (<MODE>mode == DImode && !TARGET_POWERPC64)
1998     {
1999       rtx lo0 = gen_lowpart (SImode, operands[0]);
2000       rtx lo1 = gen_lowpart (SImode, operands[1]);
2001       rtx lo2 = gen_lowpart (SImode, operands[2]);
2002       rtx hi0 = gen_highpart (SImode, operands[0]);
2003       rtx hi1 = gen_highpart_mode (SImode, DImode, operands[1]);
2004       rtx hi2 = gen_highpart (SImode, operands[2]);
2006       if (!reg_or_short_operand (lo1, SImode))
2007         lo1 = force_reg (SImode, lo1);
2008       if (!adde_operand (hi1, SImode))
2009         hi1 = force_reg (SImode, hi1);
2011       emit_insn (gen_subfsi3_carry (lo0, lo2, lo1));
2012       emit_insn (gen_subfsi3_carry_in (hi0, hi2, hi1));
2013       DONE;
2014     }
2016   if (short_cint_operand (operands[1], <MODE>mode))
2017     {
2018       emit_insn (gen_subf<mode>3_imm (operands[0], operands[2], operands[1]));
2019       DONE;
2020     }
2023 (define_insn "*subf<mode>3"
2024   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2025         (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r")
2026                    (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2027   ""
2028   "subf %0,%1,%2"
2029   [(set_attr "type" "add")])
2031 (define_insn_and_split "*subf<mode>3_dot"
2032   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2033         (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
2034                                (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2035                     (const_int 0)))
2036    (clobber (match_scratch:GPR 0 "=r,r"))]
2037   "<MODE>mode == Pmode"
2038   "@
2039    subf. %0,%1,%2
2040    #"
2041   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2042   [(set (match_dup 0)
2043         (minus:GPR (match_dup 2)
2044                    (match_dup 1)))
2045    (set (match_dup 3)
2046         (compare:CC (match_dup 0)
2047                     (const_int 0)))]
2048   ""
2049   [(set_attr "type" "add")
2050    (set_attr "dot" "yes")
2051    (set_attr "length" "4,8")])
2053 (define_insn_and_split "*subf<mode>3_dot2"
2054   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2055         (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
2056                                (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2057                     (const_int 0)))
2058    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2059         (minus:GPR (match_dup 2)
2060                    (match_dup 1)))]
2061   "<MODE>mode == Pmode"
2062   "@
2063    subf. %0,%1,%2
2064    #"
2065   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2066   [(set (match_dup 0)
2067         (minus:GPR (match_dup 2)
2068                    (match_dup 1)))
2069    (set (match_dup 3)
2070         (compare:CC (match_dup 0)
2071                     (const_int 0)))]
2072   ""
2073   [(set_attr "type" "add")
2074    (set_attr "dot" "yes")
2075    (set_attr "length" "4,8")])
2077 (define_insn "subf<mode>3_imm"
2078   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2079         (minus:GPR (match_operand:GPR 2 "short_cint_operand" "I")
2080                    (match_operand:GPR 1 "gpc_reg_operand" "r")))
2081    (clobber (reg:GPR CA_REGNO))]
2082   ""
2083   "subfic %0,%1,%2"
2084   [(set_attr "type" "add")])
2086 (define_insn_and_split "subf<mode>3_carry_dot2"
2087   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2088         (compare:CC (minus:P (match_operand:P 2 "gpc_reg_operand" "r,r")
2089                                (match_operand:P 1 "gpc_reg_operand" "r,r"))
2090                     (const_int 0)))
2091    (set (match_operand:P 0 "gpc_reg_operand" "=r,r")
2092         (minus:P (match_dup 2)
2093                    (match_dup 1)))
2094    (set (reg:P CA_REGNO)
2095         (leu:P (match_dup 1)
2096                (match_dup 2)))]
2097   "<MODE>mode == Pmode"
2098   "@
2099    subfc. %0,%1,%2
2100    #"
2101   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2102   [(parallel [(set (match_dup 0)
2103                    (minus:P (match_dup 2)
2104                             (match_dup 1)))
2105               (set (reg:P CA_REGNO)
2106                    (leu:P (match_dup 1)
2107                           (match_dup 2)))])
2108    (set (match_dup 3)
2109         (compare:CC (match_dup 0)
2110                     (const_int 0)))]
2111   ""
2112   [(set_attr "type" "add")
2113    (set_attr "dot" "yes")
2114    (set_attr "length" "4,8")])
2116 (define_insn "subf<mode>3_carry"
2117   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2118         (minus:P (match_operand:P 2 "reg_or_short_operand" "rI")
2119                  (match_operand:P 1 "gpc_reg_operand" "r")))
2120    (set (reg:P CA_REGNO)
2121         (leu:P (match_dup 1)
2122                (match_dup 2)))]
2123   ""
2124   "subf%I2c %0,%1,%2"
2125   [(set_attr "type" "add")])
2127 (define_insn "*subf<mode>3_imm_carry_0"
2128   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2129         (neg:P (match_operand:P 1 "gpc_reg_operand" "r")))
2130    (set (reg:P CA_REGNO)
2131         (eq:P (match_dup 1)
2132               (const_int 0)))]
2133   ""
2134   "subfic %0,%1,0"
2135   [(set_attr "type" "add")])
2137 (define_insn "*subf<mode>3_imm_carry_m1"
2138   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2139         (not:P (match_operand:P 1 "gpc_reg_operand" "r")))
2140    (set (reg:P CA_REGNO)
2141         (const_int 1))]
2142   ""
2143   "subfic %0,%1,-1"
2144   [(set_attr "type" "add")])
2147 (define_expand "subf<mode>3_carry_in"
2148   [(parallel [
2149      (set (match_operand:GPR 0 "gpc_reg_operand")
2150           (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand"))
2151                               (reg:GPR CA_REGNO))
2152                     (match_operand:GPR 2 "adde_operand")))
2153      (clobber (reg:GPR CA_REGNO))])]
2154   ""
2156   if (operands[2] == const0_rtx)
2157     {
2158       emit_insn (gen_subf<mode>3_carry_in_0 (operands[0], operands[1]));
2159       DONE;
2160     }
2161   if (operands[2] == constm1_rtx)
2162     {
2163       emit_insn (gen_subf<mode>3_carry_in_m1 (operands[0], operands[1]));
2164       DONE;
2165     }
2168 (define_insn "*subf<mode>3_carry_in_internal"
2169   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2170         (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
2171                             (reg:GPR CA_REGNO))
2172                   (match_operand:GPR 2 "gpc_reg_operand" "r")))
2173    (clobber (reg:GPR CA_REGNO))]
2174   ""
2175   "subfe %0,%1,%2"
2176   [(set_attr "type" "add")])
2178 (define_insn "subf<mode>3_carry_in_0"
2179   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2180         (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
2181                   (reg:GPR CA_REGNO)))
2182    (clobber (reg:GPR CA_REGNO))]
2183   ""
2184   "subfze %0,%1"
2185   [(set_attr "type" "add")])
2187 (define_insn "subf<mode>3_carry_in_m1"
2188   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2189         (plus:GPR (minus:GPR (reg:GPR CA_REGNO)
2190                              (match_operand:GPR 1 "gpc_reg_operand" "r"))
2191                   (const_int -2)))
2192    (clobber (reg:GPR CA_REGNO))]
2193   ""
2194   "subfme %0,%1"
2195   [(set_attr "type" "add")])
2197 (define_insn "subf<mode>3_carry_in_xx"
2198   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2199         (plus:GPR (reg:GPR CA_REGNO)
2200                   (const_int -1)))
2201    (clobber (reg:GPR CA_REGNO))]
2202   ""
2203   "subfe %0,%0,%0"
2204   [(set_attr "type" "add")])
2207 (define_insn "neg<mode>2"
2208   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2209         (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2210   ""
2211   "neg %0,%1"
2212   [(set_attr "type" "add")])
2214 (define_insn_and_split "*neg<mode>2_dot"
2215   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2216         (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2217                     (const_int 0)))
2218    (clobber (match_scratch:GPR 0 "=r,r"))]
2219   "<MODE>mode == Pmode"
2220   "@
2221    neg. %0,%1
2222    #"
2223   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2224   [(set (match_dup 0)
2225         (neg:GPR (match_dup 1)))
2226    (set (match_dup 2)
2227         (compare:CC (match_dup 0)
2228                     (const_int 0)))]
2229   ""
2230   [(set_attr "type" "add")
2231    (set_attr "dot" "yes")
2232    (set_attr "length" "4,8")])
2234 (define_insn_and_split "*neg<mode>2_dot2"
2235   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2236         (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2237                     (const_int 0)))
2238    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2239         (neg:GPR (match_dup 1)))]
2240   "<MODE>mode == Pmode"
2241   "@
2242    neg. %0,%1
2243    #"
2244   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2245   [(set (match_dup 0)
2246         (neg:GPR (match_dup 1)))
2247    (set (match_dup 2)
2248         (compare:CC (match_dup 0)
2249                     (const_int 0)))]
2250   ""
2251   [(set_attr "type" "add")
2252    (set_attr "dot" "yes")
2253    (set_attr "length" "4,8")])
2256 (define_insn "clz<mode>2"
2257   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2258         (clz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2259   ""
2260   "cntlz<wd> %0,%1"
2261   [(set_attr "type" "cntlz")])
2263 (define_expand "ctz<mode>2"
2264    [(set (match_operand:GPR 0 "gpc_reg_operand")
2265          (ctz:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2266   ""
2268   if (TARGET_CTZ)
2269     {
2270       emit_insn (gen_ctz<mode>2_hw (operands[0], operands[1]));
2271       DONE;
2272     }
2274   rtx tmp1 = gen_reg_rtx (<MODE>mode);
2275   rtx tmp2 = gen_reg_rtx (<MODE>mode);
2276   rtx tmp3 = gen_reg_rtx (<MODE>mode);
2278   if (TARGET_POPCNTD)
2279     {
2280       emit_insn (gen_add<mode>3 (tmp1, operands[1], constm1_rtx));
2281       emit_insn (gen_one_cmpl<mode>2 (tmp2, operands[1]));
2282       emit_insn (gen_and<mode>3 (tmp3, tmp1, tmp2));
2283       emit_insn (gen_popcntd<mode>2 (operands[0], tmp3));
2284     }
2285   else
2286     {
2287       emit_insn (gen_neg<mode>2 (tmp1, operands[1]));
2288       emit_insn (gen_and<mode>3 (tmp2, operands[1], tmp1));
2289       emit_insn (gen_clz<mode>2 (tmp3, tmp2));
2290       emit_insn (gen_sub<mode>3 (operands[0], GEN_INT (<bits> - 1), tmp3));
2291     }
2293   DONE;
2296 (define_insn "ctz<mode>2_hw"
2297   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2298         (ctz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2299   "TARGET_CTZ"
2300   "cnttz<wd> %0,%1"
2301   [(set_attr "type" "cntlz")])
2303 (define_expand "ffs<mode>2"
2304   [(set (match_operand:GPR 0 "gpc_reg_operand")
2305         (ffs:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2306   ""
2308   rtx tmp1 = gen_reg_rtx (<MODE>mode);
2309   rtx tmp2 = gen_reg_rtx (<MODE>mode);
2310   rtx tmp3 = gen_reg_rtx (<MODE>mode);
2311   emit_insn (gen_neg<mode>2 (tmp1, operands[1]));
2312   emit_insn (gen_and<mode>3 (tmp2, operands[1], tmp1));
2313   emit_insn (gen_clz<mode>2 (tmp3, tmp2));
2314   emit_insn (gen_sub<mode>3 (operands[0], GEN_INT (<bits>), tmp3));
2315   DONE;
2319 (define_expand "popcount<mode>2"
2320   [(set (match_operand:GPR 0 "gpc_reg_operand")
2321         (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2322   "TARGET_POPCNTB || TARGET_POPCNTD"
2324   rs6000_emit_popcount (operands[0], operands[1]);
2325   DONE;
2328 (define_insn "popcntb<mode>2"
2329   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2330         (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")]
2331                     UNSPEC_POPCNTB))]
2332   "TARGET_POPCNTB"
2333   "popcntb %0,%1"
2334   [(set_attr "type" "popcnt")])
2336 (define_insn "popcntd<mode>2"
2337   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2338         (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2339   "TARGET_POPCNTD"
2340   "popcnt<wd> %0,%1"
2341   [(set_attr "type" "popcnt")])
2344 (define_expand "parity<mode>2"
2345   [(set (match_operand:GPR 0 "gpc_reg_operand")
2346         (parity:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2347   "TARGET_POPCNTB"
2349   rs6000_emit_parity (operands[0], operands[1]);
2350   DONE;
2353 (define_insn "parity<mode>2_cmpb"
2354   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2355         (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")] UNSPEC_PARITY))]
2356   "TARGET_CMPB && TARGET_POPCNTB"
2357   "prty<wd> %0,%1"
2358   [(set_attr "type" "popcnt")])
2360 (define_insn "cmpb<mode>3"
2361   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2362         (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")
2363                      (match_operand:GPR 2 "gpc_reg_operand" "r")] UNSPEC_CMPB))]
2364   "TARGET_CMPB"
2365   "cmpb %0,%1,%2"
2366   [(set_attr "type" "cmp")])
2368 ;; Since the hardware zeros the upper part of the register, save generating the
2369 ;; AND immediate if we are converting to unsigned
2370 (define_insn "*bswap<mode>2_extenddi"
2371   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2372         (zero_extend:DI
2373          (bswap:HSI (match_operand:HSI 1 "memory_operand" "Z"))))]
2374   "TARGET_POWERPC64"
2375   "l<wd>brx %0,%y1"
2376   [(set_attr "type" "load")])
2378 (define_insn "*bswaphi2_extendsi"
2379   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2380         (zero_extend:SI
2381          (bswap:HI (match_operand:HI 1 "memory_operand" "Z"))))]
2382   ""
2383   "lhbrx %0,%y1"
2384   [(set_attr "type" "load")])
2386 ;; Separate the bswap patterns into load, store, and gpr<-gpr.  This prevents
2387 ;; the register allocator from converting a gpr<-gpr swap into a store and then
2388 ;; load with byte swap, which can be slower than doing it in the registers.  It
2389 ;; also prevents certain failures with the RELOAD register allocator.
2391 (define_expand "bswap<mode>2"
2392   [(use (match_operand:HSI 0 "reg_or_mem_operand"))
2393    (use (match_operand:HSI 1 "reg_or_mem_operand"))]
2394   ""
2396   rtx dest = operands[0];
2397   rtx src = operands[1];
2399   if (!REG_P (dest) && !REG_P (src))
2400     src = force_reg (<MODE>mode, src);
2402   if (MEM_P (src))
2403     {
2404       src = rs6000_force_indexed_or_indirect_mem (src);
2405       emit_insn (gen_bswap<mode>2_load (dest, src));
2406     }
2407   else if (MEM_P (dest))
2408     {
2409       dest = rs6000_force_indexed_or_indirect_mem (dest);
2410       emit_insn (gen_bswap<mode>2_store (dest, src));
2411     }
2412   else
2413     emit_insn (gen_bswap<mode>2_reg (dest, src));
2414   DONE;
2417 (define_insn "bswap<mode>2_load"
2418   [(set (match_operand:HSI 0 "gpc_reg_operand" "=r")
2419         (bswap:HSI (match_operand:HSI 1 "indexed_or_indirect_operand" "Z")))]
2420   ""
2421   "l<wd>brx %0,%y1"
2422   [(set_attr "type" "load")])
2424 (define_insn "bswap<mode>2_store"
2425   [(set (match_operand:HSI 0 "indexed_or_indirect_operand" "=Z")
2426         (bswap:HSI (match_operand:HSI 1 "gpc_reg_operand" "r")))]
2427   ""
2428   "st<wd>brx %1,%y0"
2429   [(set_attr "type" "store")])
2431 (define_insn_and_split "bswaphi2_reg"
2432   [(set (match_operand:HI 0 "gpc_reg_operand" "=&r,wo")
2433         (bswap:HI
2434          (match_operand:HI 1 "gpc_reg_operand" "r,wo")))
2435    (clobber (match_scratch:SI 2 "=&r,X"))]
2436   ""
2437   "@
2438    #
2439    xxbrh %x0,%x1"
2440   "reload_completed && int_reg_operand (operands[0], HImode)"
2441   [(set (match_dup 3)
2442         (and:SI (lshiftrt:SI (match_dup 4)
2443                              (const_int 8))
2444                 (const_int 255)))
2445    (set (match_dup 2)
2446         (and:SI (ashift:SI (match_dup 4)
2447                            (const_int 8))
2448                 (const_int 65280)))             ;; 0xff00
2449    (set (match_dup 3)
2450         (ior:SI (match_dup 3)
2451                 (match_dup 2)))]
2453   operands[3] = simplify_gen_subreg (SImode, operands[0], HImode, 0);
2454   operands[4] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
2456   [(set_attr "length" "12,4")
2457    (set_attr "type" "*,vecperm")])
2459 ;; We are always BITS_BIG_ENDIAN, so the bit positions below in
2460 ;; zero_extract insns do not change for -mlittle.
2461 (define_insn_and_split "bswapsi2_reg"
2462   [(set (match_operand:SI 0 "gpc_reg_operand" "=&r,wo")
2463         (bswap:SI
2464          (match_operand:SI 1 "gpc_reg_operand" "r,wo")))]
2465   ""
2466   "@
2467    #
2468    xxbrw %x0,%x1"
2469   "reload_completed && int_reg_operand (operands[0], SImode)"
2470   [(set (match_dup 0)                                   ; DABC
2471         (rotate:SI (match_dup 1)
2472                    (const_int 24)))
2473    (set (match_dup 0)                                   ; DCBC
2474         (ior:SI (and:SI (ashift:SI (match_dup 1)
2475                                    (const_int 8))
2476                         (const_int 16711680))
2477                 (and:SI (match_dup 0)
2478                         (const_int -16711681))))
2479    (set (match_dup 0)                                   ; DCBA
2480         (ior:SI (and:SI (lshiftrt:SI (match_dup 1)
2481                                      (const_int 24))
2482                         (const_int 255))
2483                 (and:SI (match_dup 0)
2484                         (const_int -256))))]
2485   ""
2486   [(set_attr "length" "12,4")
2487    (set_attr "type" "*,vecperm")])
2489 ;; On systems with LDBRX/STDBRX generate the loads/stores directly, just like
2490 ;; we do for L{H,W}BRX and ST{H,W}BRX above.  If not, we have to generate more
2491 ;; complex code.
2493 (define_expand "bswapdi2"
2494   [(parallel [(set (match_operand:DI 0 "reg_or_mem_operand")
2495                    (bswap:DI
2496                     (match_operand:DI 1 "reg_or_mem_operand")))
2497               (clobber (match_scratch:DI 2))
2498               (clobber (match_scratch:DI 3))])]
2499   ""
2501   rtx dest = operands[0];
2502   rtx src = operands[1];
2504   if (!REG_P (dest) && !REG_P (src))
2505     operands[1] = src = force_reg (DImode, src);
2507   if (TARGET_POWERPC64 && TARGET_LDBRX)
2508     {
2509       if (MEM_P (src))
2510         {
2511           src = rs6000_force_indexed_or_indirect_mem (src);
2512           emit_insn (gen_bswapdi2_load (dest, src));
2513         }
2514       else if (MEM_P (dest))
2515         {
2516           dest = rs6000_force_indexed_or_indirect_mem (dest);
2517           emit_insn (gen_bswapdi2_store (dest, src));
2518         }
2519       else if (TARGET_P9_VECTOR)
2520         emit_insn (gen_bswapdi2_xxbrd (dest, src));
2521       else
2522         emit_insn (gen_bswapdi2_reg (dest, src));
2523       DONE;
2524     }
2526   if (!TARGET_POWERPC64)
2527     {
2528       /* 32-bit mode needs fewer scratch registers, but 32-bit addressing mode
2529          that uses 64-bit registers needs the same scratch registers as 64-bit
2530          mode.  */
2531       emit_insn (gen_bswapdi2_32bit (dest, src));
2532       DONE;
2533     }
2536 ;; Power7/cell has ldbrx/stdbrx, so use it directly
2537 (define_insn "bswapdi2_load"
2538   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2539         (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand" "Z")))]
2540   "TARGET_POWERPC64 && TARGET_LDBRX"
2541   "ldbrx %0,%y1"
2542   [(set_attr "type" "load")])
2544 (define_insn "bswapdi2_store"
2545   [(set (match_operand:DI 0 "indexed_or_indirect_operand" "=Z")
2546         (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "r")))]
2547   "TARGET_POWERPC64 && TARGET_LDBRX"
2548   "stdbrx %1,%y0"
2549   [(set_attr "type" "store")])
2551 (define_insn "bswapdi2_xxbrd"
2552   [(set (match_operand:DI 0 "gpc_reg_operand" "=wo")
2553         (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "wo")))]
2554   "TARGET_P9_VECTOR"
2555   "xxbrd %x0,%x1"
2556   [(set_attr "type" "vecperm")])
2558 (define_insn "bswapdi2_reg"
2559   [(set (match_operand:DI 0 "gpc_reg_operand" "=&r")
2560         (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "r")))
2561    (clobber (match_scratch:DI 2 "=&r"))
2562    (clobber (match_scratch:DI 3 "=&r"))]
2563   "TARGET_POWERPC64 && TARGET_LDBRX && !TARGET_P9_VECTOR"
2564   "#"
2565   [(set_attr "length" "36")])
2567 ;; Non-power7/cell, fall back to use lwbrx/stwbrx
2568 (define_insn "*bswapdi2_64bit"
2569   [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,&r")
2570         (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2571    (clobber (match_scratch:DI 2 "=&b,&b,&r"))
2572    (clobber (match_scratch:DI 3 "=&r,&r,&r"))]
2573   "TARGET_POWERPC64 && !TARGET_LDBRX
2574    && (REG_P (operands[0]) || REG_P (operands[1]))
2575    && !(MEM_P (operands[0]) && MEM_VOLATILE_P (operands[0]))
2576    && !(MEM_P (operands[1]) && MEM_VOLATILE_P (operands[1]))"
2577   "#"
2578   [(set_attr "length" "16,12,36")])
2580 (define_split
2581   [(set (match_operand:DI 0 "gpc_reg_operand")
2582         (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand")))
2583    (clobber (match_operand:DI 2 "gpc_reg_operand"))
2584    (clobber (match_operand:DI 3 "gpc_reg_operand"))]
2585   "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2586   [(const_int 0)]
2588   rtx dest   = operands[0];
2589   rtx src    = operands[1];
2590   rtx op2    = operands[2];
2591   rtx op3    = operands[3];
2592   rtx op3_32 = simplify_gen_subreg (SImode, op3, DImode,
2593                                     BYTES_BIG_ENDIAN ? 4 : 0);
2594   rtx dest_32 = simplify_gen_subreg (SImode, dest, DImode,
2595                                      BYTES_BIG_ENDIAN ? 4 : 0);
2596   rtx addr1;
2597   rtx addr2;
2598   rtx word1;
2599   rtx word2;
2601   addr1 = XEXP (src, 0);
2602   if (GET_CODE (addr1) == PLUS)
2603     {
2604       emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2605       if (TARGET_AVOID_XFORM)
2606         {
2607           emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2608           addr2 = op2;
2609         }
2610       else
2611         addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2612     }
2613   else if (TARGET_AVOID_XFORM)
2614     {
2615       emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2616       addr2 = op2;
2617     }
2618   else
2619     {
2620       emit_move_insn (op2, GEN_INT (4));
2621       addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2622     }
2624   word1 = change_address (src, SImode, addr1);
2625   word2 = change_address (src, SImode, addr2);
2627   if (BYTES_BIG_ENDIAN)
2628     {
2629       emit_insn (gen_bswapsi2 (op3_32, word2));
2630       emit_insn (gen_bswapsi2 (dest_32, word1));
2631     }
2632   else
2633     {
2634       emit_insn (gen_bswapsi2 (op3_32, word1));
2635       emit_insn (gen_bswapsi2 (dest_32, word2));
2636     }
2638   emit_insn (gen_ashldi3 (op3, op3, GEN_INT (32)));
2639   emit_insn (gen_iordi3 (dest, dest, op3));
2640   DONE;
2643 (define_split
2644   [(set (match_operand:DI 0 "indexed_or_indirect_operand")
2645         (bswap:DI (match_operand:DI 1 "gpc_reg_operand")))
2646    (clobber (match_operand:DI 2 "gpc_reg_operand"))
2647    (clobber (match_operand:DI 3 "gpc_reg_operand"))]
2648   "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2649   [(const_int 0)]
2651   rtx dest   = operands[0];
2652   rtx src    = operands[1];
2653   rtx op2    = operands[2];
2654   rtx op3    = operands[3];
2655   rtx src_si = simplify_gen_subreg (SImode, src, DImode,
2656                                     BYTES_BIG_ENDIAN ? 4 : 0);
2657   rtx op3_si = simplify_gen_subreg (SImode, op3, DImode,
2658                                     BYTES_BIG_ENDIAN ? 4 : 0);
2659   rtx addr1;
2660   rtx addr2;
2661   rtx word1;
2662   rtx word2;
2664   addr1 = XEXP (dest, 0);
2665   if (GET_CODE (addr1) == PLUS)
2666     {
2667       emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2668       if (TARGET_AVOID_XFORM)
2669         {
2670           emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2671           addr2 = op2;
2672         }
2673       else
2674         addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2675     }
2676   else if (TARGET_AVOID_XFORM)
2677     {
2678       emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2679       addr2 = op2;
2680     }
2681   else
2682     {
2683       emit_move_insn (op2, GEN_INT (4));
2684       addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2685     }
2687   word1 = change_address (dest, SImode, addr1);
2688   word2 = change_address (dest, SImode, addr2);
2690   emit_insn (gen_lshrdi3 (op3, src, GEN_INT (32)));
2692   if (BYTES_BIG_ENDIAN)
2693     {
2694       emit_insn (gen_bswapsi2 (word1, src_si));
2695       emit_insn (gen_bswapsi2 (word2, op3_si));
2696     }
2697   else
2698     {
2699       emit_insn (gen_bswapsi2 (word2, src_si));
2700       emit_insn (gen_bswapsi2 (word1, op3_si));
2701     }
2702   DONE;
2705 (define_split
2706   [(set (match_operand:DI 0 "gpc_reg_operand")
2707         (bswap:DI (match_operand:DI 1 "gpc_reg_operand")))
2708    (clobber (match_operand:DI 2 "gpc_reg_operand"))
2709    (clobber (match_operand:DI 3 "gpc_reg_operand"))]
2710   "TARGET_POWERPC64 && !TARGET_P9_VECTOR && reload_completed"
2711   [(const_int 0)]
2713   rtx dest    = operands[0];
2714   rtx src     = operands[1];
2715   rtx op2     = operands[2];
2716   rtx op3     = operands[3];
2717   int lo_off  = BYTES_BIG_ENDIAN ? 4 : 0;
2718   rtx dest_si = simplify_gen_subreg (SImode, dest, DImode, lo_off);
2719   rtx src_si  = simplify_gen_subreg (SImode, src, DImode, lo_off);
2720   rtx op2_si  = simplify_gen_subreg (SImode, op2, DImode, lo_off);
2721   rtx op3_si  = simplify_gen_subreg (SImode, op3, DImode, lo_off);
2723   emit_insn (gen_lshrdi3 (op2, src, GEN_INT (32)));
2724   emit_insn (gen_bswapsi2 (dest_si, src_si));
2725   emit_insn (gen_bswapsi2 (op3_si, op2_si));
2726   emit_insn (gen_ashldi3 (dest, dest, GEN_INT (32)));
2727   emit_insn (gen_iordi3 (dest, dest, op3));
2728   DONE;
2731 (define_insn "bswapdi2_32bit"
2732   [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,?&r")
2733         (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2734    (clobber (match_scratch:SI 2 "=&b,&b,X"))]
2735   "!TARGET_POWERPC64 && (REG_P (operands[0]) || REG_P (operands[1]))"
2736   "#"
2737   [(set_attr "length" "16,12,36")])
2739 (define_split
2740   [(set (match_operand:DI 0 "gpc_reg_operand")
2741         (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand")))
2742    (clobber (match_operand:SI 2 "gpc_reg_operand"))]
2743   "!TARGET_POWERPC64 && reload_completed"
2744   [(const_int 0)]
2746   rtx dest  = operands[0];
2747   rtx src   = operands[1];
2748   rtx op2   = operands[2];
2749   rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
2750   rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
2751   rtx addr1;
2752   rtx addr2;
2753   rtx word1;
2754   rtx word2;
2756   addr1 = XEXP (src, 0);
2757   if (GET_CODE (addr1) == PLUS)
2758     {
2759       emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2760       if (TARGET_AVOID_XFORM
2761           || REGNO (XEXP (addr1, 1)) == REGNO (dest2))
2762         {
2763           emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2764           addr2 = op2;
2765         }
2766       else
2767         addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
2768     }
2769   else if (TARGET_AVOID_XFORM
2770            || REGNO (addr1) == REGNO (dest2))
2771     {
2772       emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2773       addr2 = op2;
2774     }
2775   else
2776     {
2777       emit_move_insn (op2, GEN_INT (4));
2778       addr2 = gen_rtx_PLUS (SImode, op2, addr1);
2779     }
2781   word1 = change_address (src, SImode, addr1);
2782   word2 = change_address (src, SImode, addr2);
2784   emit_insn (gen_bswapsi2 (dest2, word1));
2785   /* The REGNO (dest2) tests above ensure that addr2 has not been trashed,
2786      thus allowing us to omit an early clobber on the output.  */
2787   emit_insn (gen_bswapsi2 (dest1, word2));
2788   DONE;
2791 (define_split
2792   [(set (match_operand:DI 0 "indexed_or_indirect_operand")
2793         (bswap:DI (match_operand:DI 1 "gpc_reg_operand")))
2794    (clobber (match_operand:SI 2 "gpc_reg_operand"))]
2795   "!TARGET_POWERPC64 && reload_completed"
2796   [(const_int 0)]
2798   rtx dest = operands[0];
2799   rtx src  = operands[1];
2800   rtx op2  = operands[2];
2801   rtx src1 = simplify_gen_subreg (SImode, src, DImode, 0);
2802   rtx src2 = simplify_gen_subreg (SImode, src, DImode, 4);
2803   rtx addr1;
2804   rtx addr2;
2805   rtx word1;
2806   rtx word2;
2808   addr1 = XEXP (dest, 0);
2809   if (GET_CODE (addr1) == PLUS)
2810     {
2811       emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2812       if (TARGET_AVOID_XFORM)
2813         {
2814           emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2815           addr2 = op2;
2816         }
2817       else
2818         addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
2819     }
2820   else if (TARGET_AVOID_XFORM)
2821     {
2822       emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2823       addr2 = op2;
2824     }
2825   else
2826     {
2827       emit_move_insn (op2, GEN_INT (4));
2828       addr2 = gen_rtx_PLUS (SImode, op2, addr1);
2829     }
2831   word1 = change_address (dest, SImode, addr1);
2832   word2 = change_address (dest, SImode, addr2);
2834   emit_insn (gen_bswapsi2 (word2, src1));
2835   emit_insn (gen_bswapsi2 (word1, src2));
2836   DONE;
2839 (define_split
2840   [(set (match_operand:DI 0 "gpc_reg_operand")
2841         (bswap:DI (match_operand:DI 1 "gpc_reg_operand")))
2842    (clobber (match_operand:SI 2 ""))]
2843   "!TARGET_POWERPC64 && reload_completed"
2844   [(const_int 0)]
2846   rtx dest  = operands[0];
2847   rtx src   = operands[1];
2848   rtx src1  = simplify_gen_subreg (SImode, src, DImode, 0);
2849   rtx src2  = simplify_gen_subreg (SImode, src, DImode, 4);
2850   rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
2851   rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
2853   emit_insn (gen_bswapsi2 (dest1, src2));
2854   emit_insn (gen_bswapsi2 (dest2, src1));
2855   DONE;
2859 (define_insn "mul<mode>3"
2860   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2861         (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
2862                   (match_operand:GPR 2 "reg_or_short_operand" "r,I")))]
2863   ""
2864   "@
2865    mull<wd> %0,%1,%2
2866    mulli %0,%1,%2"
2867    [(set_attr "type" "mul")
2868     (set (attr "size")
2869       (cond [(match_operand:GPR 2 "s8bit_cint_operand")
2870                 (const_string "8")
2871              (match_operand:GPR 2 "short_cint_operand")
2872                 (const_string "16")]
2873         (const_string "<bits>")))])
2875 (define_insn_and_split "*mul<mode>3_dot"
2876   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2877         (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2878                               (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
2879                     (const_int 0)))
2880    (clobber (match_scratch:GPR 0 "=r,r"))]
2881   "<MODE>mode == Pmode"
2882   "@
2883    mull<wd>. %0,%1,%2
2884    #"
2885   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2886   [(set (match_dup 0)
2887         (mult:GPR (match_dup 1)
2888                   (match_dup 2)))
2889    (set (match_dup 3)
2890         (compare:CC (match_dup 0)
2891                     (const_int 0)))]
2892   ""
2893   [(set_attr "type" "mul")
2894    (set_attr "size" "<bits>")
2895    (set_attr "dot" "yes")
2896    (set_attr "length" "4,8")])
2898 (define_insn_and_split "*mul<mode>3_dot2"
2899   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2900         (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2901                               (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
2902                     (const_int 0)))
2903    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2904         (mult:GPR (match_dup 1)
2905                   (match_dup 2)))]
2906   "<MODE>mode == Pmode"
2907   "@
2908    mull<wd>. %0,%1,%2
2909    #"
2910   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2911   [(set (match_dup 0)
2912         (mult:GPR (match_dup 1)
2913                   (match_dup 2)))
2914    (set (match_dup 3)
2915         (compare:CC (match_dup 0)
2916                     (const_int 0)))]
2917   ""
2918   [(set_attr "type" "mul")
2919    (set_attr "size" "<bits>")
2920    (set_attr "dot" "yes")
2921    (set_attr "length" "4,8")])
2924 (define_expand "<su>mul<mode>3_highpart"
2925   [(set (match_operand:GPR 0 "gpc_reg_operand")
2926         (subreg:GPR
2927           (mult:<DMODE> (any_extend:<DMODE>
2928                           (match_operand:GPR 1 "gpc_reg_operand"))
2929                         (any_extend:<DMODE>
2930                           (match_operand:GPR 2 "gpc_reg_operand")))
2931          0))]
2932   ""
2934   if (<MODE>mode == SImode && TARGET_POWERPC64)
2935     {
2936       emit_insn (gen_<su>mulsi3_highpart_64 (operands[0], operands[1],
2937                                              operands[2]));
2938       DONE;
2939     }
2941   if (!WORDS_BIG_ENDIAN)
2942     {
2943       emit_insn (gen_<su>mul<mode>3_highpart_le (operands[0], operands[1],
2944                                                  operands[2]));
2945       DONE;
2946     }
2949 (define_insn "*<su>mul<mode>3_highpart"
2950   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2951         (subreg:GPR
2952           (mult:<DMODE> (any_extend:<DMODE>
2953                           (match_operand:GPR 1 "gpc_reg_operand" "r"))
2954                         (any_extend:<DMODE>
2955                           (match_operand:GPR 2 "gpc_reg_operand" "r")))
2956          0))]
2957   "WORDS_BIG_ENDIAN && !(<MODE>mode == SImode && TARGET_POWERPC64)"
2958   "mulh<wd><u> %0,%1,%2"
2959   [(set_attr "type" "mul")
2960    (set_attr "size" "<bits>")])
2962 (define_insn "<su>mulsi3_highpart_le"
2963   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2964         (subreg:SI
2965           (mult:DI (any_extend:DI
2966                      (match_operand:SI 1 "gpc_reg_operand" "r"))
2967                    (any_extend:DI
2968                      (match_operand:SI 2 "gpc_reg_operand" "r")))
2969          4))]
2970   "!WORDS_BIG_ENDIAN && !TARGET_POWERPC64"
2971   "mulhw<u> %0,%1,%2"
2972   [(set_attr "type" "mul")])
2974 (define_insn "<su>muldi3_highpart_le"
2975   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2976         (subreg:DI
2977           (mult:TI (any_extend:TI
2978                      (match_operand:DI 1 "gpc_reg_operand" "r"))
2979                    (any_extend:TI
2980                      (match_operand:DI 2 "gpc_reg_operand" "r")))
2981          8))]
2982   "!WORDS_BIG_ENDIAN && TARGET_POWERPC64"
2983   "mulhd<u> %0,%1,%2"
2984   [(set_attr "type" "mul")
2985    (set_attr "size" "64")])
2987 (define_insn "<su>mulsi3_highpart_64"
2988   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2989         (truncate:SI
2990           (lshiftrt:DI
2991             (mult:DI (any_extend:DI
2992                        (match_operand:SI 1 "gpc_reg_operand" "r"))
2993                      (any_extend:DI
2994                        (match_operand:SI 2 "gpc_reg_operand" "r")))
2995             (const_int 32))))]
2996   "TARGET_POWERPC64"
2997   "mulhw<u> %0,%1,%2"
2998   [(set_attr "type" "mul")])
3000 (define_expand "<u>mul<mode><dmode>3"
3001   [(set (match_operand:<DMODE> 0 "gpc_reg_operand")
3002         (mult:<DMODE> (any_extend:<DMODE>
3003                         (match_operand:GPR 1 "gpc_reg_operand"))
3004                       (any_extend:<DMODE>
3005                         (match_operand:GPR 2 "gpc_reg_operand"))))]
3006   "!(<MODE>mode == SImode && TARGET_POWERPC64)"
3008   rtx l = gen_reg_rtx (<MODE>mode);
3009   rtx h = gen_reg_rtx (<MODE>mode);
3010   emit_insn (gen_mul<mode>3 (l, operands[1], operands[2]));
3011   emit_insn (gen_<su>mul<mode>3_highpart (h, operands[1], operands[2]));
3012   emit_move_insn (gen_lowpart (<MODE>mode, operands[0]), l);
3013   emit_move_insn (gen_highpart (<MODE>mode, operands[0]), h);
3014   DONE;
3017 (define_insn "*maddld4"
3018   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3019         (plus:DI (mult:DI (match_operand:DI 1 "gpc_reg_operand" "r")
3020                           (match_operand:DI 2 "gpc_reg_operand" "r"))
3021                  (match_operand:DI 3 "gpc_reg_operand" "r")))]
3022   "TARGET_MADDLD"
3023   "maddld %0,%1,%2,%3"
3024   [(set_attr "type" "mul")])
3026 (define_insn "udiv<mode>3"
3027   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3028         (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3029                   (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3030   ""
3031   "div<wd>u %0,%1,%2"
3032   [(set_attr "type" "div")
3033    (set_attr "size" "<bits>")])
3036 ;; For powers of two we can do sra[wd]i/addze for divide and then adjust for
3037 ;; modulus.  If it isn't a power of two, force operands into register and do
3038 ;; a normal divide.
3039 (define_expand "div<mode>3"
3040   [(set (match_operand:GPR 0 "gpc_reg_operand")
3041         (div:GPR (match_operand:GPR 1 "gpc_reg_operand")
3042                  (match_operand:GPR 2 "reg_or_cint_operand")))]
3043   ""
3045   if (CONST_INT_P (operands[2])
3046       && INTVAL (operands[2]) > 0
3047       && exact_log2 (INTVAL (operands[2])) >= 0)
3048     {
3049       emit_insn (gen_div<mode>3_sra (operands[0], operands[1], operands[2]));
3050       DONE;
3051     }
3053   operands[2] = force_reg (<MODE>mode, operands[2]);
3056 (define_insn "*div<mode>3"
3057   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3058         (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3059                  (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3060   ""
3061   "div<wd> %0,%1,%2"
3062   [(set_attr "type" "div")
3063    (set_attr "size" "<bits>")])
3065 (define_insn "div<mode>3_sra"
3066   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3067         (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3068                  (match_operand:GPR 2 "exact_log2_cint_operand" "N")))
3069    (clobber (reg:GPR CA_REGNO))]
3070   ""
3071   "sra<wd>i %0,%1,%p2\;addze %0,%0"
3072   [(set_attr "type" "two")
3073    (set_attr "length" "8")])
3075 (define_insn_and_split "*div<mode>3_sra_dot"
3076   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3077         (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3078                              (match_operand:GPR 2 "exact_log2_cint_operand" "N,N"))
3079                     (const_int 0)))
3080    (clobber (match_scratch:GPR 0 "=r,r"))
3081    (clobber (reg:GPR CA_REGNO))]
3082   "<MODE>mode == Pmode"
3083   "@
3084    sra<wd>i %0,%1,%p2\;addze. %0,%0
3085    #"
3086   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3087   [(parallel [(set (match_dup 0)
3088                    (div:GPR (match_dup 1)
3089                             (match_dup 2)))
3090               (clobber (reg:GPR CA_REGNO))])
3091    (set (match_dup 3)
3092         (compare:CC (match_dup 0)
3093                     (const_int 0)))]
3094   ""
3095   [(set_attr "type" "two")
3096    (set_attr "length" "8,12")
3097    (set_attr "cell_micro" "not")])
3099 (define_insn_and_split "*div<mode>3_sra_dot2"
3100   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3101         (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3102                              (match_operand:GPR 2 "exact_log2_cint_operand" "N,N"))
3103                     (const_int 0)))
3104    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3105         (div:GPR (match_dup 1)
3106                  (match_dup 2)))
3107    (clobber (reg:GPR CA_REGNO))]
3108   "<MODE>mode == Pmode"
3109   "@
3110    sra<wd>i %0,%1,%p2\;addze. %0,%0
3111    #"
3112   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3113   [(parallel [(set (match_dup 0)
3114                    (div:GPR (match_dup 1)
3115                             (match_dup 2)))
3116               (clobber (reg:GPR CA_REGNO))])
3117    (set (match_dup 3)
3118         (compare:CC (match_dup 0)
3119                     (const_int 0)))]
3120   ""
3121   [(set_attr "type" "two")
3122    (set_attr "length" "8,12")
3123    (set_attr "cell_micro" "not")])
3125 (define_expand "mod<mode>3"
3126   [(set (match_operand:GPR 0 "gpc_reg_operand")
3127         (mod:GPR (match_operand:GPR 1 "gpc_reg_operand")
3128                  (match_operand:GPR 2 "reg_or_cint_operand")))]
3129   ""
3131   int i;
3132   rtx temp1;
3133   rtx temp2;
3135   if (!CONST_INT_P (operands[2])
3136       || INTVAL (operands[2]) <= 0
3137       || (i = exact_log2 (INTVAL (operands[2]))) < 0)
3138     {
3139       if (!TARGET_MODULO)
3140         FAIL;
3142       operands[2] = force_reg (<MODE>mode, operands[2]);
3143     }
3144   else
3145     {
3146       temp1 = gen_reg_rtx (<MODE>mode);
3147       temp2 = gen_reg_rtx (<MODE>mode);
3149       emit_insn (gen_div<mode>3 (temp1, operands[1], operands[2]));
3150       emit_insn (gen_ashl<mode>3 (temp2, temp1, GEN_INT (i)));
3151       emit_insn (gen_sub<mode>3 (operands[0], operands[1], temp2));
3152       DONE;
3153     }
3156 ;; In order to enable using a peephole2 for combining div/mod to eliminate the
3157 ;; mod, prefer putting the result of mod into a different register
3158 (define_insn "*mod<mode>3"
3159   [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
3160         (mod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3161                  (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3162   "TARGET_MODULO"
3163   "mods<wd> %0,%1,%2"
3164   [(set_attr "type" "div")
3165    (set_attr "size" "<bits>")])
3168 (define_insn "umod<mode>3"
3169   [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
3170         (umod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3171                   (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3172   "TARGET_MODULO"
3173   "modu<wd> %0,%1,%2"
3174   [(set_attr "type" "div")
3175    (set_attr "size" "<bits>")])
3177 ;; On machines with modulo support, do a combined div/mod the old fashioned
3178 ;; method, since the multiply/subtract is faster than doing the mod instruction
3179 ;; after a divide.
3181 (define_peephole2
3182   [(set (match_operand:GPR 0 "gpc_reg_operand")
3183         (div:GPR (match_operand:GPR 1 "gpc_reg_operand")
3184                  (match_operand:GPR 2 "gpc_reg_operand")))
3185    (set (match_operand:GPR 3 "gpc_reg_operand")
3186         (mod:GPR (match_dup 1)
3187                  (match_dup 2)))]
3188   "TARGET_MODULO
3189    && ! reg_mentioned_p (operands[0], operands[1])
3190    && ! reg_mentioned_p (operands[0], operands[2])
3191    && ! reg_mentioned_p (operands[3], operands[1])
3192    && ! reg_mentioned_p (operands[3], operands[2])"
3193   [(set (match_dup 0)
3194         (div:GPR (match_dup 1)
3195                  (match_dup 2)))
3196    (set (match_dup 3)
3197         (mult:GPR (match_dup 0)
3198                   (match_dup 2)))
3199    (set (match_dup 3)
3200         (minus:GPR (match_dup 1)
3201                    (match_dup 3)))])
3203 (define_peephole2
3204   [(set (match_operand:GPR 0 "gpc_reg_operand")
3205         (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand")
3206                   (match_operand:GPR 2 "gpc_reg_operand")))
3207    (set (match_operand:GPR 3 "gpc_reg_operand")
3208         (umod:GPR (match_dup 1)
3209                   (match_dup 2)))]
3210   "TARGET_MODULO
3211    && ! reg_mentioned_p (operands[0], operands[1])
3212    && ! reg_mentioned_p (operands[0], operands[2])
3213    && ! reg_mentioned_p (operands[3], operands[1])
3214    && ! reg_mentioned_p (operands[3], operands[2])"
3215   [(set (match_dup 0)
3216         (udiv:GPR (match_dup 1)
3217                   (match_dup 2)))
3218    (set (match_dup 3)
3219         (mult:GPR (match_dup 0)
3220                   (match_dup 2)))
3221    (set (match_dup 3)
3222         (minus:GPR (match_dup 1)
3223                    (match_dup 3)))])
3226 ;; Logical instructions
3227 ;; The logical instructions are mostly combined by using match_operator,
3228 ;; but the plain AND insns are somewhat different because there is no
3229 ;; plain 'andi' (only 'andi.'), no plain 'andis', and there are all
3230 ;; those rotate-and-mask operations.  Thus, the AND insns come first.
3232 (define_expand "and<mode>3"
3233   [(set (match_operand:SDI 0 "gpc_reg_operand")
3234         (and:SDI (match_operand:SDI 1 "gpc_reg_operand")
3235                  (match_operand:SDI 2 "reg_or_cint_operand")))]
3236   ""
3238   if (<MODE>mode == DImode && !TARGET_POWERPC64)
3239     {
3240       rs6000_split_logical (operands, AND, false, false, false);
3241       DONE;
3242     }
3244   if (CONST_INT_P (operands[2]))
3245     {
3246       if (rs6000_is_valid_and_mask (operands[2], <MODE>mode))
3247         {
3248           emit_insn (gen_and<mode>3_mask (operands[0], operands[1], operands[2]));
3249           DONE;
3250         }
3252       if (logical_const_operand (operands[2], <MODE>mode))
3253         {
3254           emit_insn (gen_and<mode>3_imm (operands[0], operands[1], operands[2]));
3255           DONE;
3256         }
3258       if (rs6000_is_valid_2insn_and (operands[2], <MODE>mode))
3259         {
3260           rs6000_emit_2insn_and (<MODE>mode, operands, true, 0);
3261           DONE;
3262         }
3264       operands[2] = force_reg (<MODE>mode, operands[2]);
3265     }
3269 (define_insn "and<mode>3_imm"
3270   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3271         (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3272                  (match_operand:GPR 2 "logical_const_operand" "n")))
3273    (clobber (match_scratch:CC 3 "=x"))]
3274   "!rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3275   "andi%e2. %0,%1,%u2"
3276   [(set_attr "type" "logical")
3277    (set_attr "dot" "yes")])
3279 (define_insn_and_split "*and<mode>3_imm_dot"
3280   [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3281         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3282                              (match_operand:GPR 2 "logical_const_operand" "n,n"))
3283                     (const_int 0)))
3284    (clobber (match_scratch:GPR 0 "=r,r"))
3285    (clobber (match_scratch:CC 4 "=X,x"))]
3286   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3287    && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3288   "@
3289    andi%e2. %0,%1,%u2
3290    #"
3291   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3292   [(parallel [(set (match_dup 0)
3293                    (and:GPR (match_dup 1)
3294                             (match_dup 2)))
3295               (clobber (match_dup 4))])
3296    (set (match_dup 3)
3297         (compare:CC (match_dup 0)
3298                     (const_int 0)))]
3299   ""
3300   [(set_attr "type" "logical")
3301    (set_attr "dot" "yes")
3302    (set_attr "length" "4,8")])
3304 (define_insn_and_split "*and<mode>3_imm_dot2"
3305   [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3306         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3307                              (match_operand:GPR 2 "logical_const_operand" "n,n"))
3308                     (const_int 0)))
3309    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3310         (and:GPR (match_dup 1)
3311                  (match_dup 2)))
3312    (clobber (match_scratch:CC 4 "=X,x"))]
3313   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3314    && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3315   "@
3316    andi%e2. %0,%1,%u2
3317    #"
3318   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3319   [(parallel [(set (match_dup 0)
3320                    (and:GPR (match_dup 1)
3321                             (match_dup 2)))
3322               (clobber (match_dup 4))])
3323    (set (match_dup 3)
3324         (compare:CC (match_dup 0)
3325                     (const_int 0)))]
3326   ""
3327   [(set_attr "type" "logical")
3328    (set_attr "dot" "yes")
3329    (set_attr "length" "4,8")])
3331 (define_insn_and_split "*and<mode>3_imm_mask_dot"
3332   [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3333         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3334                              (match_operand:GPR 2 "logical_const_operand" "n,n"))
3335                     (const_int 0)))
3336    (clobber (match_scratch:GPR 0 "=r,r"))]
3337   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3338    && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3339   "@
3340    andi%e2. %0,%1,%u2
3341    #"
3342   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3343   [(set (match_dup 0)
3344         (and:GPR (match_dup 1)
3345                  (match_dup 2)))
3346    (set (match_dup 3)
3347         (compare:CC (match_dup 0)
3348                     (const_int 0)))]
3349   ""
3350   [(set_attr "type" "logical")
3351    (set_attr "dot" "yes")
3352    (set_attr "length" "4,8")])
3354 (define_insn_and_split "*and<mode>3_imm_mask_dot2"
3355   [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3356         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3357                              (match_operand:GPR 2 "logical_const_operand" "n,n"))
3358                     (const_int 0)))
3359    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3360         (and:GPR (match_dup 1)
3361                  (match_dup 2)))]
3362   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3363    && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3364   "@
3365    andi%e2. %0,%1,%u2
3366    #"
3367   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3368   [(set (match_dup 0)
3369         (and:GPR (match_dup 1)
3370                  (match_dup 2)))
3371    (set (match_dup 3)
3372         (compare:CC (match_dup 0)
3373                     (const_int 0)))]
3374   ""
3375   [(set_attr "type" "logical")
3376    (set_attr "dot" "yes")
3377    (set_attr "length" "4,8")])
3379 (define_insn "*and<mode>3_imm_dot_shifted"
3380   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
3381         (compare:CC
3382           (and:GPR
3383             (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3384                           (match_operand:SI 4 "const_int_operand" "n"))
3385             (match_operand:GPR 2 "const_int_operand" "n"))
3386           (const_int 0)))
3387    (clobber (match_scratch:GPR 0 "=r"))]
3388   "logical_const_operand (GEN_INT (UINTVAL (operands[2])
3389                                    << INTVAL (operands[4])),
3390                           DImode)
3391    && (<MODE>mode == Pmode
3392        || (UINTVAL (operands[2]) << INTVAL (operands[4])) <= 0x7fffffff)"
3394   operands[2] = GEN_INT (UINTVAL (operands[2]) << INTVAL (operands[4]));
3395   return "andi%e2. %0,%1,%u2";
3397   [(set_attr "type" "logical")
3398    (set_attr "dot" "yes")])
3401 (define_insn "and<mode>3_mask"
3402   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3403         (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3404                  (match_operand:GPR 2 "const_int_operand" "n")))]
3405   "rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3407   return rs6000_insn_for_and_mask (<MODE>mode, operands, false);
3409   [(set_attr "type" "shift")])
3411 (define_insn_and_split "*and<mode>3_mask_dot"
3412   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3413         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3414                              (match_operand:GPR 2 "const_int_operand" "n,n"))
3415                     (const_int 0)))
3416    (clobber (match_scratch:GPR 0 "=r,r"))]
3417   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3418    && !logical_const_operand (operands[2], <MODE>mode)
3419    && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3421   if (which_alternative == 0)
3422     return rs6000_insn_for_and_mask (<MODE>mode, operands, true);
3423   else
3424     return "#";
3426   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3427   [(set (match_dup 0)
3428         (and:GPR (match_dup 1)
3429                  (match_dup 2)))
3430    (set (match_dup 3)
3431         (compare:CC (match_dup 0)
3432                     (const_int 0)))]
3433   ""
3434   [(set_attr "type" "shift")
3435    (set_attr "dot" "yes")
3436    (set_attr "length" "4,8")])
3438 (define_insn_and_split "*and<mode>3_mask_dot2"
3439   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3440         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3441                              (match_operand:GPR 2 "const_int_operand" "n,n"))
3442                     (const_int 0)))
3443    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3444         (and:GPR (match_dup 1)
3445                  (match_dup 2)))]
3446   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3447    && !logical_const_operand (operands[2], <MODE>mode)
3448    && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3450   if (which_alternative == 0)
3451     return rs6000_insn_for_and_mask (<MODE>mode, operands, true);
3452   else
3453     return "#";
3455   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3456   [(set (match_dup 0)
3457         (and:GPR (match_dup 1)
3458                  (match_dup 2)))
3459    (set (match_dup 3)
3460         (compare:CC (match_dup 0)
3461                     (const_int 0)))]
3462   ""
3463   [(set_attr "type" "shift")
3464    (set_attr "dot" "yes")
3465    (set_attr "length" "4,8")])
3468 (define_insn_and_split "*and<mode>3_2insn"
3469   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3470         (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3471                  (match_operand:GPR 2 "const_int_operand" "n")))]
3472   "rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3473    && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3474         || logical_const_operand (operands[2], <MODE>mode))"
3475   "#"
3476   "&& 1"
3477   [(pc)]
3479   rs6000_emit_2insn_and (<MODE>mode, operands, false, 0);
3480   DONE;
3482   [(set_attr "type" "shift")
3483    (set_attr "length" "8")])
3485 (define_insn_and_split "*and<mode>3_2insn_dot"
3486   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3487         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3488                              (match_operand:GPR 2 "const_int_operand" "n,n"))
3489                     (const_int 0)))
3490    (clobber (match_scratch:GPR 0 "=r,r"))]
3491   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3492    && rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3493    && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3494         || logical_const_operand (operands[2], <MODE>mode))"
3495   "#"
3496   "&& reload_completed"
3497   [(pc)]
3499   rs6000_emit_2insn_and (<MODE>mode, operands, false, 1);
3500   DONE;
3502   [(set_attr "type" "shift")
3503    (set_attr "dot" "yes")
3504    (set_attr "length" "8,12")])
3506 (define_insn_and_split "*and<mode>3_2insn_dot2"
3507   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3508         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3509                              (match_operand:GPR 2 "const_int_operand" "n,n"))
3510                     (const_int 0)))
3511    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3512         (and:GPR (match_dup 1)
3513                  (match_dup 2)))]
3514   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3515    && rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3516    && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3517         || logical_const_operand (operands[2], <MODE>mode))"
3518   "#"
3519   "&& reload_completed"
3520   [(pc)]
3522   rs6000_emit_2insn_and (<MODE>mode, operands, false, 2);
3523   DONE;
3525   [(set_attr "type" "shift")
3526    (set_attr "dot" "yes")
3527    (set_attr "length" "8,12")])
3530 (define_expand "<code><mode>3"
3531   [(set (match_operand:SDI 0 "gpc_reg_operand")
3532         (iorxor:SDI (match_operand:SDI 1 "gpc_reg_operand")
3533                     (match_operand:SDI 2 "reg_or_cint_operand")))]
3534   ""
3536   if (<MODE>mode == DImode && !TARGET_POWERPC64)
3537     {
3538       rs6000_split_logical (operands, <CODE>, false, false, false);
3539       DONE;
3540     }
3542   if (non_logical_cint_operand (operands[2], <MODE>mode))
3543     {
3544       rtx tmp = ((!can_create_pseudo_p ()
3545                   || rtx_equal_p (operands[0], operands[1]))
3546                  ? operands[0] : gen_reg_rtx (<MODE>mode));
3548       HOST_WIDE_INT value = INTVAL (operands[2]);
3549       HOST_WIDE_INT lo = value & 0xffff;
3550       HOST_WIDE_INT hi = value - lo;
3552       emit_insn (gen_<code><mode>3 (tmp, operands[1], GEN_INT (hi)));
3553       emit_insn (gen_<code><mode>3 (operands[0], tmp, GEN_INT (lo)));
3554       DONE;
3555     }
3557   if (!reg_or_logical_cint_operand (operands[2], <MODE>mode))
3558     operands[2] = force_reg (<MODE>mode, operands[2]);
3561 (define_split
3562   [(set (match_operand:GPR 0 "gpc_reg_operand")
3563         (iorxor:GPR (match_operand:GPR 1 "gpc_reg_operand")
3564                     (match_operand:GPR 2 "non_logical_cint_operand")))]
3565   ""
3566   [(set (match_dup 3)
3567         (iorxor:GPR (match_dup 1)
3568                     (match_dup 4)))
3569    (set (match_dup 0)
3570         (iorxor:GPR (match_dup 3)
3571                     (match_dup 5)))]
3573   operands[3] = ((!can_create_pseudo_p ()
3574                   || rtx_equal_p (operands[0], operands[1]))
3575                  ? operands[0] : gen_reg_rtx (<MODE>mode));
3577   HOST_WIDE_INT value = INTVAL (operands[2]);
3578   HOST_WIDE_INT lo = value & 0xffff;
3579   HOST_WIDE_INT hi = value - lo;
3581   operands[4] = GEN_INT (hi);
3582   operands[5] = GEN_INT (lo);
3585 (define_insn "*bool<mode>3_imm"
3586   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3587         (match_operator:GPR 3 "boolean_or_operator"
3588          [(match_operand:GPR 1 "gpc_reg_operand" "%r")
3589           (match_operand:GPR 2 "logical_const_operand" "n")]))]
3590   ""
3591   "%q3i%e2 %0,%1,%u2"
3592   [(set_attr "type" "logical")])
3594 (define_insn "*bool<mode>3"
3595   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3596         (match_operator:GPR 3 "boolean_operator"
3597          [(match_operand:GPR 1 "gpc_reg_operand" "r")
3598           (match_operand:GPR 2 "gpc_reg_operand" "r")]))]
3599   ""
3600   "%q3 %0,%1,%2"
3601   [(set_attr "type" "logical")])
3603 (define_insn_and_split "*bool<mode>3_dot"
3604   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3605         (compare:CC (match_operator:GPR 3 "boolean_operator"
3606          [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3607           (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
3608          (const_int 0)))
3609    (clobber (match_scratch:GPR 0 "=r,r"))]
3610   "<MODE>mode == Pmode"
3611   "@
3612    %q3. %0,%1,%2
3613    #"
3614   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3615   [(set (match_dup 0)
3616         (match_dup 3))
3617    (set (match_dup 4)
3618         (compare:CC (match_dup 0)
3619                     (const_int 0)))]
3620   ""
3621   [(set_attr "type" "logical")
3622    (set_attr "dot" "yes")
3623    (set_attr "length" "4,8")])
3625 (define_insn_and_split "*bool<mode>3_dot2"
3626   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3627         (compare:CC (match_operator:GPR 3 "boolean_operator"
3628          [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3629           (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
3630          (const_int 0)))
3631    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3632         (match_dup 3))]
3633   "<MODE>mode == Pmode"
3634   "@
3635    %q3. %0,%1,%2
3636    #"
3637   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3638   [(set (match_dup 0)
3639         (match_dup 3))
3640    (set (match_dup 4)
3641         (compare:CC (match_dup 0)
3642                     (const_int 0)))]
3643   ""
3644   [(set_attr "type" "logical")
3645    (set_attr "dot" "yes")
3646    (set_attr "length" "4,8")])
3649 (define_insn "*boolc<mode>3"
3650   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3651         (match_operator:GPR 3 "boolean_operator"
3652          [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))
3653           (match_operand:GPR 1 "gpc_reg_operand" "r")]))]
3654   ""
3655   "%q3 %0,%1,%2"
3656   [(set_attr "type" "logical")])
3658 (define_insn_and_split "*boolc<mode>3_dot"
3659   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3660         (compare:CC (match_operator:GPR 3 "boolean_operator"
3661          [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3662           (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
3663          (const_int 0)))
3664    (clobber (match_scratch:GPR 0 "=r,r"))]
3665   "<MODE>mode == Pmode"
3666   "@
3667    %q3. %0,%1,%2
3668    #"
3669   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3670   [(set (match_dup 0)
3671         (match_dup 3))
3672    (set (match_dup 4)
3673         (compare:CC (match_dup 0)
3674                     (const_int 0)))]
3675   ""
3676   [(set_attr "type" "logical")
3677    (set_attr "dot" "yes")
3678    (set_attr "length" "4,8")])
3680 (define_insn_and_split "*boolc<mode>3_dot2"
3681   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3682         (compare:CC (match_operator:GPR 3 "boolean_operator"
3683          [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3684           (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
3685          (const_int 0)))
3686    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3687         (match_dup 3))]
3688   "<MODE>mode == Pmode"
3689   "@
3690    %q3. %0,%1,%2
3691    #"
3692   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3693   [(set (match_dup 0)
3694         (match_dup 3))
3695    (set (match_dup 4)
3696         (compare:CC (match_dup 0)
3697                     (const_int 0)))]
3698   ""
3699   [(set_attr "type" "logical")
3700    (set_attr "dot" "yes")
3701    (set_attr "length" "4,8")])
3704 (define_insn "*boolcc<mode>3"
3705   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3706         (match_operator:GPR 3 "boolean_operator"
3707          [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
3708           (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))]))]
3709   ""
3710   "%q3 %0,%1,%2"
3711   [(set_attr "type" "logical")])
3713 (define_insn_and_split "*boolcc<mode>3_dot"
3714   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3715         (compare:CC (match_operator:GPR 3 "boolean_operator"
3716          [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
3717           (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
3718          (const_int 0)))
3719    (clobber (match_scratch:GPR 0 "=r,r"))]
3720   "<MODE>mode == Pmode"
3721   "@
3722    %q3. %0,%1,%2
3723    #"
3724   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3725   [(set (match_dup 0)
3726         (match_dup 3))
3727    (set (match_dup 4)
3728         (compare:CC (match_dup 0)
3729                     (const_int 0)))]
3730   ""
3731   [(set_attr "type" "logical")
3732    (set_attr "dot" "yes")
3733    (set_attr "length" "4,8")])
3735 (define_insn_and_split "*boolcc<mode>3_dot2"
3736   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3737         (compare:CC (match_operator:GPR 3 "boolean_operator"
3738          [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
3739           (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
3740          (const_int 0)))
3741    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3742         (match_dup 3))]
3743   "<MODE>mode == Pmode"
3744   "@
3745    %q3. %0,%1,%2
3746    #"
3747   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3748   [(set (match_dup 0)
3749         (match_dup 3))
3750    (set (match_dup 4)
3751         (compare:CC (match_dup 0)
3752                     (const_int 0)))]
3753   ""
3754   [(set_attr "type" "logical")
3755    (set_attr "dot" "yes")
3756    (set_attr "length" "4,8")])
3759 ;; TODO: Should have dots of this as well.
3760 (define_insn "*eqv<mode>3"
3761   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3762         (not:GPR (xor:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3763                           (match_operand:GPR 2 "gpc_reg_operand" "r"))))]
3764   ""
3765   "eqv %0,%1,%2"
3766   [(set_attr "type" "logical")])
3768 ;; Rotate-and-mask and insert.
3770 (define_insn "*rotl<mode>3_mask"
3771   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3772         (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3773                   [(match_operand:GPR 1 "gpc_reg_operand" "r")
3774                    (match_operand:SI 2 "reg_or_cint_operand" "rn")])
3775                  (match_operand:GPR 3 "const_int_operand" "n")))]
3776   "rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3778   return rs6000_insn_for_shift_mask (<MODE>mode, operands, false);
3780   [(set_attr "type" "shift")
3781    (set_attr "maybe_var_shift" "yes")])
3783 (define_insn_and_split "*rotl<mode>3_mask_dot"
3784   [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y")
3785         (compare:CC
3786           (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3787                     [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3788                      (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")])
3789                    (match_operand:GPR 3 "const_int_operand" "n,n"))
3790           (const_int 0)))
3791    (clobber (match_scratch:GPR 0 "=r,r"))]
3792   "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff)
3793    && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3795   if (which_alternative == 0)
3796     return rs6000_insn_for_shift_mask (<MODE>mode, operands, true);
3797   else
3798     return "#";
3800   "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)"
3801   [(set (match_dup 0)
3802         (and:GPR (match_dup 4)
3803                  (match_dup 3)))
3804    (set (match_dup 5)
3805         (compare:CC (match_dup 0)
3806                     (const_int 0)))]
3807   ""
3808   [(set_attr "type" "shift")
3809    (set_attr "maybe_var_shift" "yes")
3810    (set_attr "dot" "yes")
3811    (set_attr "length" "4,8")])
3813 (define_insn_and_split "*rotl<mode>3_mask_dot2"
3814   [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y")
3815         (compare:CC
3816           (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3817                     [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3818                      (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")])
3819                    (match_operand:GPR 3 "const_int_operand" "n,n"))
3820           (const_int 0)))
3821    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3822         (and:GPR (match_dup 4)
3823                  (match_dup 3)))]
3824   "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff)
3825    && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3827   if (which_alternative == 0)
3828     return rs6000_insn_for_shift_mask (<MODE>mode, operands, true);
3829   else
3830     return "#";
3832   "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)"
3833   [(set (match_dup 0)
3834         (and:GPR (match_dup 4)
3835                  (match_dup 3)))
3836    (set (match_dup 5)
3837         (compare:CC (match_dup 0)
3838                     (const_int 0)))]
3839   ""
3840   [(set_attr "type" "shift")
3841    (set_attr "maybe_var_shift" "yes")
3842    (set_attr "dot" "yes")
3843    (set_attr "length" "4,8")])
3845 ; Special case for less-than-0.  We can do it with just one machine
3846 ; instruction, but the generic optimizers do not realise it is cheap.
3847 (define_insn "*lt0_<mode>di"
3848   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3849         (lt:GPR (match_operand:DI 1 "gpc_reg_operand" "r")
3850                 (const_int 0)))]
3851   "TARGET_POWERPC64"
3852   "srdi %0,%1,63"
3853   [(set_attr "type" "shift")])
3855 (define_insn "*lt0_<mode>si"
3856   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3857         (lt:GPR (match_operand:SI 1 "gpc_reg_operand" "r")
3858                 (const_int 0)))]
3859   ""
3860   "rlwinm %0,%1,1,31,31"
3861   [(set_attr "type" "shift")])
3865 ; Two forms for insert (the two arms of the IOR are not canonicalized,
3866 ; both are an AND so are the same precedence).
3867 (define_insn "*rotl<mode>3_insert"
3868   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3869         (ior:GPR (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3870                            [(match_operand:GPR 1 "gpc_reg_operand" "r")
3871                             (match_operand:SI 2 "const_int_operand" "n")])
3872                           (match_operand:GPR 3 "const_int_operand" "n"))
3873                  (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0")
3874                           (match_operand:GPR 6 "const_int_operand" "n"))))]
3875   "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode)
3876    && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0"
3878   return rs6000_insn_for_insert_mask (<MODE>mode, operands, false);
3880   [(set_attr "type" "insert")])
3881 ; FIXME: this needs an attr "size", so that the scheduler can see the
3882 ; difference between rlwimi and rldimi.  We also might want dot forms,
3883 ; but not for rlwimi on POWER4 and similar processors.
3885 (define_insn "*rotl<mode>3_insert_2"
3886   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3887         (ior:GPR (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0")
3888                           (match_operand:GPR 6 "const_int_operand" "n"))
3889                  (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3890                            [(match_operand:GPR 1 "gpc_reg_operand" "r")
3891                             (match_operand:SI 2 "const_int_operand" "n")])
3892                           (match_operand:GPR 3 "const_int_operand" "n"))))]
3893   "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode)
3894    && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0"
3896   return rs6000_insn_for_insert_mask (<MODE>mode, operands, false);
3898   [(set_attr "type" "insert")])
3900 ; There are also some forms without one of the ANDs.
3901 (define_insn "*rotl<mode>3_insert_3"
3902   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3903         (ior:GPR (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0")
3904                           (match_operand:GPR 4 "const_int_operand" "n"))
3905                  (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3906                              (match_operand:SI 2 "const_int_operand" "n"))))]
3907   "INTVAL (operands[2]) == exact_log2 (UINTVAL (operands[4]) + 1)"
3909   if (<MODE>mode == SImode)
3910     return "rlwimi %0,%1,%h2,0,31-%h2";
3911   else
3912     return "rldimi %0,%1,%H2,0";
3914   [(set_attr "type" "insert")])
3916 (define_insn "*rotl<mode>3_insert_4"
3917   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3918         (ior:GPR (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0")
3919                           (match_operand:GPR 4 "const_int_operand" "n"))
3920                  (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3921                                (match_operand:SI 2 "const_int_operand" "n"))))]
3922   "<MODE>mode == SImode &&
3923    GET_MODE_PRECISION (<MODE>mode)
3924    == INTVAL (operands[2]) + exact_log2 (-UINTVAL (operands[4]))"
3926   operands[2] = GEN_INT (GET_MODE_PRECISION (<MODE>mode)
3927                          - INTVAL (operands[2]));
3928   if (<MODE>mode == SImode)
3929     return "rlwimi %0,%1,%h2,32-%h2,31";
3930   else
3931     return "rldimi %0,%1,%H2,64-%H2";
3933   [(set_attr "type" "insert")])
3935 (define_insn "*rotlsi3_insert_5"
3936   [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
3937         (ior:SI (and:SI (match_operand:SI 1 "gpc_reg_operand" "0,r")
3938                         (match_operand:SI 2 "const_int_operand" "n,n"))
3939                 (and:SI (match_operand:SI 3 "gpc_reg_operand" "r,0")
3940                         (match_operand:SI 4 "const_int_operand" "n,n"))))]
3941   "rs6000_is_valid_mask (operands[2], NULL, NULL, SImode)
3942    && UINTVAL (operands[2]) != 0 && UINTVAL (operands[4]) != 0
3943    && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
3944   "@
3945    rlwimi %0,%3,0,%4
3946    rlwimi %0,%1,0,%2"
3947   [(set_attr "type" "insert")])
3949 (define_insn "*rotldi3_insert_6"
3950   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3951         (ior:DI (and:DI (match_operand:DI 1 "gpc_reg_operand" "0")
3952                         (match_operand:DI 2 "const_int_operand" "n"))
3953                 (and:DI (match_operand:DI 3 "gpc_reg_operand" "r")
3954                         (match_operand:DI 4 "const_int_operand" "n"))))]
3955   "exact_log2 (-UINTVAL (operands[2])) > 0
3956    && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
3958   operands[5] = GEN_INT (64 - exact_log2 (-UINTVAL (operands[2])));
3959   return "rldimi %0,%3,0,%5";
3961   [(set_attr "type" "insert")
3962    (set_attr "size" "64")])
3964 (define_insn "*rotldi3_insert_7"
3965   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3966         (ior:DI (and:DI (match_operand:DI 3 "gpc_reg_operand" "r")
3967                         (match_operand:DI 4 "const_int_operand" "n"))
3968                 (and:DI (match_operand:DI 1 "gpc_reg_operand" "0")
3969                         (match_operand:DI 2 "const_int_operand" "n"))))]
3970   "exact_log2 (-UINTVAL (operands[2])) > 0
3971    && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
3973   operands[5] = GEN_INT (64 - exact_log2 (-UINTVAL (operands[2])));
3974   return "rldimi %0,%3,0,%5";
3976   [(set_attr "type" "insert")
3977    (set_attr "size" "64")])
3980 ; This handles the important case of multiple-precision shifts.  There is
3981 ; no canonicalization rule for ASHIFT vs. LSHIFTRT, so two patterns.
3982 (define_split
3983   [(set (match_operand:GPR 0 "gpc_reg_operand")
3984         (ior:GPR (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand")
3985                              (match_operand:SI 3 "const_int_operand"))
3986                  (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand")
3987                                (match_operand:SI 4 "const_int_operand"))))]
3988   "can_create_pseudo_p ()
3989    && INTVAL (operands[3]) + INTVAL (operands[4])
3990       >= GET_MODE_PRECISION (<MODE>mode)"
3991   [(set (match_dup 5)
3992         (lshiftrt:GPR (match_dup 2)
3993                       (match_dup 4)))
3994    (set (match_dup 0)
3995         (ior:GPR (and:GPR (match_dup 5)
3996                           (match_dup 6))
3997                  (ashift:GPR (match_dup 1)
3998                              (match_dup 3))))]
4000   unsigned HOST_WIDE_INT mask = 1;
4001   mask = (mask << INTVAL (operands[3])) - 1;
4002   operands[5] = gen_reg_rtx (<MODE>mode);
4003   operands[6] = GEN_INT (mask);
4006 (define_split
4007   [(set (match_operand:GPR 0 "gpc_reg_operand")
4008         (ior:GPR (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand")
4009                                (match_operand:SI 4 "const_int_operand"))
4010                  (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand")
4011                              (match_operand:SI 3 "const_int_operand"))))]
4012   "can_create_pseudo_p ()
4013    && INTVAL (operands[3]) + INTVAL (operands[4])
4014       >= GET_MODE_PRECISION (<MODE>mode)"
4015   [(set (match_dup 5)
4016         (lshiftrt:GPR (match_dup 2)
4017                       (match_dup 4)))
4018    (set (match_dup 0)
4019         (ior:GPR (and:GPR (match_dup 5)
4020                           (match_dup 6))
4021                  (ashift:GPR (match_dup 1)
4022                              (match_dup 3))))]
4024   unsigned HOST_WIDE_INT mask = 1;
4025   mask = (mask << INTVAL (operands[3])) - 1;
4026   operands[5] = gen_reg_rtx (<MODE>mode);
4027   operands[6] = GEN_INT (mask);
4031 ; Another important case is setting some bits to 1; we can do that with
4032 ; an insert instruction, in many cases.
4033 (define_insn_and_split "*ior<mode>_mask"
4034   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4035         (ior:GPR (match_operand:GPR 1 "gpc_reg_operand" "0")
4036                  (match_operand:GPR 2 "const_int_operand" "n")))
4037    (clobber (match_scratch:GPR 3 "=r"))]
4038   "!logical_const_operand (operands[2], <MODE>mode)
4039    && rs6000_is_valid_mask (operands[2], NULL, NULL, <MODE>mode)"
4040   "#"
4041   "&& 1"
4042   [(set (match_dup 3)
4043         (const_int -1))
4044    (set (match_dup 0)
4045         (ior:GPR (and:GPR (rotate:GPR (match_dup 3)
4046                                       (match_dup 4))
4047                           (match_dup 2))
4048                  (and:GPR (match_dup 1)
4049                           (match_dup 5))))]
4051   int nb, ne;
4052   rs6000_is_valid_mask (operands[2], &nb, &ne, <MODE>mode);
4053   if (GET_CODE (operands[3]) == SCRATCH)
4054     operands[3] = gen_reg_rtx (<MODE>mode);
4055   operands[4] = GEN_INT (ne);
4056   operands[5] = GEN_INT (~UINTVAL (operands[2]));
4058   [(set_attr "type" "two")
4059    (set_attr "length" "8")])
4062 ; Yet another case is an rldimi with the second value coming from memory.
4063 ; The zero_extend that should become part of the rldimi is merged into the
4064 ; load from memory instead.  Split things properly again.
4065 (define_split
4066   [(set (match_operand:DI 0 "gpc_reg_operand")
4067         (ior:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand")
4068                            (match_operand:SI 2 "const_int_operand"))
4069                 (zero_extend:DI (match_operand:QHSI 3 "memory_operand"))))]
4070   "INTVAL (operands[2]) == <bits>"
4071   [(set (match_dup 4)
4072         (zero_extend:DI (match_dup 3)))
4073    (set (match_dup 0)
4074         (ior:DI (and:DI (match_dup 4)
4075                         (match_dup 5))
4076                 (ashift:DI (match_dup 1)
4077                            (match_dup 2))))]
4079   operands[4] = gen_reg_rtx (DImode);
4080   operands[5] = GEN_INT ((HOST_WIDE_INT_1U << <bits>) - 1);
4083 ; rlwimi, too.
4084 (define_split
4085   [(set (match_operand:SI 0 "gpc_reg_operand")
4086         (ior:SI (ashift:SI (match_operand:SI 1 "gpc_reg_operand")
4087                            (match_operand:SI 2 "const_int_operand"))
4088                 (zero_extend:SI (match_operand:QHI 3 "memory_operand"))))]
4089   "INTVAL (operands[2]) == <bits>"
4090   [(set (match_dup 4)
4091         (zero_extend:SI (match_dup 3)))
4092    (set (match_dup 0)
4093         (ior:SI (and:SI (match_dup 4)
4094                         (match_dup 5))
4095                 (ashift:SI (match_dup 1)
4096                            (match_dup 2))))]
4098   operands[4] = gen_reg_rtx (SImode);
4099   operands[5] = GEN_INT ((HOST_WIDE_INT_1U << <bits>) - 1);
4103 ;; Now the simple shifts.
4105 (define_insn "rotl<mode>3"
4106   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4107         (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4108                     (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4109   ""
4110   "rotl<wd>%I2 %0,%1,%<hH>2"
4111   [(set_attr "type" "shift")
4112    (set_attr "maybe_var_shift" "yes")])
4114 (define_insn "*rotlsi3_64"
4115   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4116         (zero_extend:DI
4117             (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4118                        (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4119   "TARGET_POWERPC64"
4120   "rotlw%I2 %0,%1,%h2"
4121   [(set_attr "type" "shift")
4122    (set_attr "maybe_var_shift" "yes")])
4124 (define_insn_and_split "*rotl<mode>3_dot"
4125   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4126         (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4127                                 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4128                     (const_int 0)))
4129    (clobber (match_scratch:GPR 0 "=r,r"))]
4130   "<MODE>mode == Pmode"
4131   "@
4132    rotl<wd>%I2. %0,%1,%<hH>2
4133    #"
4134   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4135   [(set (match_dup 0)
4136         (rotate:GPR (match_dup 1)
4137                     (match_dup 2)))
4138    (set (match_dup 3)
4139         (compare:CC (match_dup 0)
4140                     (const_int 0)))]
4141   ""
4142   [(set_attr "type" "shift")
4143    (set_attr "maybe_var_shift" "yes")
4144    (set_attr "dot" "yes")
4145    (set_attr "length" "4,8")])
4147 (define_insn_and_split "*rotl<mode>3_dot2"
4148   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4149         (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4150                                 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4151                     (const_int 0)))
4152    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4153         (rotate:GPR (match_dup 1)
4154                     (match_dup 2)))]
4155   "<MODE>mode == Pmode"
4156   "@
4157    rotl<wd>%I2. %0,%1,%<hH>2
4158    #"
4159   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4160   [(set (match_dup 0)
4161         (rotate:GPR (match_dup 1)
4162                     (match_dup 2)))
4163    (set (match_dup 3)
4164         (compare:CC (match_dup 0)
4165                     (const_int 0)))]
4166   ""
4167   [(set_attr "type" "shift")
4168    (set_attr "maybe_var_shift" "yes")
4169    (set_attr "dot" "yes")
4170    (set_attr "length" "4,8")])
4173 (define_insn "ashl<mode>3"
4174   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4175         (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4176                     (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4177   ""
4178   "sl<wd>%I2 %0,%1,%<hH>2"
4179   [(set_attr "type" "shift")
4180    (set_attr "maybe_var_shift" "yes")])
4182 (define_insn "*ashlsi3_64"
4183   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4184         (zero_extend:DI
4185             (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4186                        (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4187   "TARGET_POWERPC64"
4188   "slw%I2 %0,%1,%h2"
4189   [(set_attr "type" "shift")
4190    (set_attr "maybe_var_shift" "yes")])
4192 (define_insn_and_split "*ashl<mode>3_dot"
4193   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4194         (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4195                                 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4196                     (const_int 0)))
4197    (clobber (match_scratch:GPR 0 "=r,r"))]
4198   "<MODE>mode == Pmode"
4199   "@
4200    sl<wd>%I2. %0,%1,%<hH>2
4201    #"
4202   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4203   [(set (match_dup 0)
4204         (ashift:GPR (match_dup 1)
4205                     (match_dup 2)))
4206    (set (match_dup 3)
4207         (compare:CC (match_dup 0)
4208                     (const_int 0)))]
4209   ""
4210   [(set_attr "type" "shift")
4211    (set_attr "maybe_var_shift" "yes")
4212    (set_attr "dot" "yes")
4213    (set_attr "length" "4,8")])
4215 (define_insn_and_split "*ashl<mode>3_dot2"
4216   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4217         (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4218                                 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4219                     (const_int 0)))
4220    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4221         (ashift:GPR (match_dup 1)
4222                     (match_dup 2)))]
4223   "<MODE>mode == Pmode"
4224   "@
4225    sl<wd>%I2. %0,%1,%<hH>2
4226    #"
4227   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4228   [(set (match_dup 0)
4229         (ashift:GPR (match_dup 1)
4230                     (match_dup 2)))
4231    (set (match_dup 3)
4232         (compare:CC (match_dup 0)
4233                     (const_int 0)))]
4234   ""
4235   [(set_attr "type" "shift")
4236    (set_attr "maybe_var_shift" "yes")
4237    (set_attr "dot" "yes")
4238    (set_attr "length" "4,8")])
4240 ;; Pretend we have a memory form of extswsli until register allocation is done
4241 ;; so that we use LWZ to load the value from memory, instead of LWA.
4242 (define_insn_and_split "ashdi3_extswsli"
4243   [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
4244         (ashift:DI
4245          (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,m"))
4246          (match_operand:DI 2 "u6bit_cint_operand" "n,n")))]
4247   "TARGET_EXTSWSLI"
4248   "@
4249    extswsli %0,%1,%2
4250    #"
4251   "&& reload_completed && MEM_P (operands[1])"
4252   [(set (match_dup 3)
4253         (match_dup 1))
4254    (set (match_dup 0)
4255         (ashift:DI (sign_extend:DI (match_dup 3))
4256                    (match_dup 2)))]
4258   operands[3] = gen_lowpart (SImode, operands[0]);
4260   [(set_attr "type" "shift")
4261    (set_attr "maybe_var_shift" "no")])
4264 (define_insn_and_split "ashdi3_extswsli_dot"
4265   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y")
4266         (compare:CC
4267          (ashift:DI
4268           (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m"))
4269           (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n"))
4270          (const_int 0)))
4271    (clobber (match_scratch:DI 0 "=r,r,r,r"))]
4272   "TARGET_EXTSWSLI"
4273   "@
4274    extswsli. %0,%1,%2
4275    #
4276    #
4277    #"
4278   "&& reload_completed
4279    && (cc_reg_not_cr0_operand (operands[3], CCmode)
4280        || memory_operand (operands[1], SImode))"
4281   [(pc)]
4283   rtx dest = operands[0];
4284   rtx src = operands[1];
4285   rtx shift = operands[2];
4286   rtx cr = operands[3];
4287   rtx src2;
4289   if (!MEM_P (src))
4290     src2 = src;
4291   else
4292     {
4293       src2 = gen_lowpart (SImode, dest);
4294       emit_move_insn (src2, src);
4295     }
4297   if (REGNO (cr) == CR0_REGNO)
4298     {
4299       emit_insn (gen_ashdi3_extswsli_dot2 (dest, src2, shift, cr));
4300       DONE;
4301     }
4303   emit_insn (gen_ashdi3_extswsli (dest, src2, shift));
4304   emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx)));
4305   DONE;
4307   [(set_attr "type" "shift")
4308    (set_attr "maybe_var_shift" "no")
4309    (set_attr "dot" "yes")
4310    (set_attr "length" "4,8,8,12")])
4312 (define_insn_and_split "ashdi3_extswsli_dot2"
4313   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y")
4314         (compare:CC
4315          (ashift:DI
4316           (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m"))
4317           (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n"))
4318          (const_int 0)))
4319    (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r")
4320         (ashift:DI (sign_extend:DI (match_dup 1))
4321                    (match_dup 2)))]
4322   "TARGET_EXTSWSLI"
4323   "@
4324    extswsli. %0,%1,%2
4325    #
4326    #
4327    #"
4328   "&& reload_completed
4329    && (cc_reg_not_cr0_operand (operands[3], CCmode)
4330        || memory_operand (operands[1], SImode))"
4331   [(pc)]
4333   rtx dest = operands[0];
4334   rtx src = operands[1];
4335   rtx shift = operands[2];
4336   rtx cr = operands[3];
4337   rtx src2;
4339   if (!MEM_P (src))
4340     src2 = src;
4341   else
4342     {
4343       src2 = gen_lowpart (SImode, dest);
4344       emit_move_insn (src2, src);
4345     }
4347   if (REGNO (cr) == CR0_REGNO)
4348     {
4349       emit_insn (gen_ashdi3_extswsli_dot2 (dest, src2, shift, cr));
4350       DONE;
4351     }
4353   emit_insn (gen_ashdi3_extswsli (dest, src2, shift));
4354   emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx)));
4355   DONE;
4357   [(set_attr "type" "shift")
4358    (set_attr "maybe_var_shift" "no")
4359    (set_attr "dot" "yes")
4360    (set_attr "length" "4,8,8,12")])
4362 (define_insn "lshr<mode>3"
4363   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4364         (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4365                       (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4366   ""
4367   "sr<wd>%I2 %0,%1,%<hH>2"
4368   [(set_attr "type" "shift")
4369    (set_attr "maybe_var_shift" "yes")])
4371 (define_insn "*lshrsi3_64"
4372   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4373         (zero_extend:DI
4374             (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4375                          (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4376   "TARGET_POWERPC64"
4377   "srw%I2 %0,%1,%h2"
4378   [(set_attr "type" "shift")
4379    (set_attr "maybe_var_shift" "yes")])
4381 (define_insn_and_split "*lshr<mode>3_dot"
4382   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4383         (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4384                                   (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4385                     (const_int 0)))
4386    (clobber (match_scratch:GPR 0 "=r,r"))]
4387   "<MODE>mode == Pmode"
4388   "@
4389    sr<wd>%I2. %0,%1,%<hH>2
4390    #"
4391   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4392   [(set (match_dup 0)
4393         (lshiftrt:GPR (match_dup 1)
4394                       (match_dup 2)))
4395    (set (match_dup 3)
4396         (compare:CC (match_dup 0)
4397                     (const_int 0)))]
4398   ""
4399   [(set_attr "type" "shift")
4400    (set_attr "maybe_var_shift" "yes")
4401    (set_attr "dot" "yes")
4402    (set_attr "length" "4,8")])
4404 (define_insn_and_split "*lshr<mode>3_dot2"
4405   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4406         (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4407                                   (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4408                     (const_int 0)))
4409    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4410         (lshiftrt:GPR (match_dup 1)
4411                       (match_dup 2)))]
4412   "<MODE>mode == Pmode"
4413   "@
4414    sr<wd>%I2. %0,%1,%<hH>2
4415    #"
4416   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4417   [(set (match_dup 0)
4418         (lshiftrt:GPR (match_dup 1)
4419                       (match_dup 2)))
4420    (set (match_dup 3)
4421         (compare:CC (match_dup 0)
4422                     (const_int 0)))]
4423   ""
4424   [(set_attr "type" "shift")
4425    (set_attr "maybe_var_shift" "yes")
4426    (set_attr "dot" "yes")
4427    (set_attr "length" "4,8")])
4430 (define_insn "ashr<mode>3"
4431   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4432         (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4433                       (match_operand:SI 2 "reg_or_cint_operand" "rn")))
4434    (clobber (reg:GPR CA_REGNO))]
4435   ""
4436   "sra<wd>%I2 %0,%1,%<hH>2"
4437   [(set_attr "type" "shift")
4438    (set_attr "maybe_var_shift" "yes")])
4440 (define_insn "*ashrsi3_64"
4441   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4442         (sign_extend:DI
4443             (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4444                          (match_operand:SI 2 "reg_or_cint_operand" "rn"))))
4445    (clobber (reg:SI CA_REGNO))]
4446   "TARGET_POWERPC64"
4447   "sraw%I2 %0,%1,%h2"
4448   [(set_attr "type" "shift")
4449    (set_attr "maybe_var_shift" "yes")])
4451 (define_insn_and_split "*ashr<mode>3_dot"
4452   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4453         (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4454                                   (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4455                     (const_int 0)))
4456    (clobber (match_scratch:GPR 0 "=r,r"))
4457    (clobber (reg:GPR CA_REGNO))]
4458   "<MODE>mode == Pmode"
4459   "@
4460    sra<wd>%I2. %0,%1,%<hH>2
4461    #"
4462   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4463   [(parallel [(set (match_dup 0)
4464                    (ashiftrt:GPR (match_dup 1)
4465                                  (match_dup 2)))
4466               (clobber (reg:GPR CA_REGNO))])
4467    (set (match_dup 3)
4468         (compare:CC (match_dup 0)
4469                     (const_int 0)))]
4470   ""
4471   [(set_attr "type" "shift")
4472    (set_attr "maybe_var_shift" "yes")
4473    (set_attr "dot" "yes")
4474    (set_attr "length" "4,8")])
4476 (define_insn_and_split "*ashr<mode>3_dot2"
4477   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4478         (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4479                                   (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4480                     (const_int 0)))
4481    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4482         (ashiftrt:GPR (match_dup 1)
4483                       (match_dup 2)))
4484    (clobber (reg:GPR CA_REGNO))]
4485   "<MODE>mode == Pmode"
4486   "@
4487    sra<wd>%I2. %0,%1,%<hH>2
4488    #"
4489   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4490   [(parallel [(set (match_dup 0)
4491                    (ashiftrt:GPR (match_dup 1)
4492                                  (match_dup 2)))
4493               (clobber (reg:GPR CA_REGNO))])
4494    (set (match_dup 3)
4495         (compare:CC (match_dup 0)
4496                     (const_int 0)))]
4497   ""
4498   [(set_attr "type" "shift")
4499    (set_attr "maybe_var_shift" "yes")
4500    (set_attr "dot" "yes")
4501    (set_attr "length" "4,8")])
4503 ;; Builtins to replace a division to generate FRE reciprocal estimate
4504 ;; instructions and the necessary fixup instructions
4505 (define_expand "recip<mode>3"
4506   [(match_operand:RECIPF 0 "gpc_reg_operand")
4507    (match_operand:RECIPF 1 "gpc_reg_operand")
4508    (match_operand:RECIPF 2 "gpc_reg_operand")]
4509   "RS6000_RECIP_HAVE_RE_P (<MODE>mode)"
4511    rs6000_emit_swdiv (operands[0], operands[1], operands[2], false);
4512    DONE;
4515 ;; Split to create division from FRE/FRES/etc. and fixup instead of the normal
4516 ;; hardware division.  This is only done before register allocation and with
4517 ;; -ffast-math.  This must appear before the divsf3/divdf3 insns.
4518 ;; We used to also check optimize_insn_for_speed_p () but problems with guessed
4519 ;; frequencies (pr68212/pr77536) yields that unreliable so it was removed.
4520 (define_split
4521   [(set (match_operand:RECIPF 0 "gpc_reg_operand")
4522         (div:RECIPF (match_operand 1 "gpc_reg_operand")
4523                     (match_operand 2 "gpc_reg_operand")))]
4524   "RS6000_RECIP_AUTO_RE_P (<MODE>mode)
4525    && can_create_pseudo_p () && flag_finite_math_only
4526    && !flag_trapping_math && flag_reciprocal_math"
4527   [(const_int 0)]
4529   rs6000_emit_swdiv (operands[0], operands[1], operands[2], true);
4530   DONE;
4533 ;; Builtins to replace 1/sqrt(x) with instructions using RSQRTE and the
4534 ;; appropriate fixup.
4535 (define_expand "rsqrt<mode>2"
4536   [(match_operand:RECIPF 0 "gpc_reg_operand")
4537    (match_operand:RECIPF 1 "gpc_reg_operand")]
4538   "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4540   rs6000_emit_swsqrt (operands[0], operands[1], 1);
4541   DONE;
4544 ;; Floating-point insns, excluding normal data motion.  We combine the SF/DF
4545 ;; modes here, and also add in conditional vsx/power8-vector support to access
4546 ;; values in the traditional Altivec registers if the appropriate
4547 ;; -mupper-regs-{df,sf} option is enabled.
4549 (define_expand "abs<mode>2"
4550   [(set (match_operand:SFDF 0 "gpc_reg_operand")
4551         (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))]
4552   "TARGET_HARD_FLOAT"
4553   "")
4555 (define_insn "*abs<mode>2_fpr"
4556   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4557         (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4558   "TARGET_HARD_FLOAT"
4559   "@
4560    fabs %0,%1
4561    xsabsdp %x0,%x1"
4562   [(set_attr "type" "fpsimple")])
4564 (define_insn "*nabs<mode>2_fpr"
4565   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4566         (neg:SFDF
4567          (abs:SFDF
4568           (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))))]
4569   "TARGET_HARD_FLOAT"
4570   "@
4571    fnabs %0,%1
4572    xsnabsdp %x0,%x1"
4573   [(set_attr "type" "fpsimple")])
4575 (define_expand "neg<mode>2"
4576   [(set (match_operand:SFDF 0 "gpc_reg_operand")
4577         (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))]
4578   "TARGET_HARD_FLOAT"
4579   "")
4581 (define_insn "*neg<mode>2_fpr"
4582   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4583         (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4584   "TARGET_HARD_FLOAT"
4585   "@
4586    fneg %0,%1
4587    xsnegdp %x0,%x1"
4588   [(set_attr "type" "fpsimple")])
4590 (define_expand "add<mode>3"
4591   [(set (match_operand:SFDF 0 "gpc_reg_operand")
4592         (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4593                    (match_operand:SFDF 2 "gpc_reg_operand")))]
4594   "TARGET_HARD_FLOAT"
4595   "")
4597 (define_insn "*add<mode>3_fpr"
4598   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4599         (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>")
4600                    (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4601   "TARGET_HARD_FLOAT"
4602   "@
4603    fadd<Ftrad> %0,%1,%2
4604    xsadd<Fvsx> %x0,%x1,%x2"
4605   [(set_attr "type" "fp")])
4607 (define_expand "sub<mode>3"
4608   [(set (match_operand:SFDF 0 "gpc_reg_operand")
4609         (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4610                     (match_operand:SFDF 2 "gpc_reg_operand")))]
4611   "TARGET_HARD_FLOAT"
4612   "")
4614 (define_insn "*sub<mode>3_fpr"
4615   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4616         (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4617                     (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4618   "TARGET_HARD_FLOAT"
4619   "@
4620    fsub<Ftrad> %0,%1,%2
4621    xssub<Fvsx> %x0,%x1,%x2"
4622   [(set_attr "type" "fp")])
4624 (define_expand "mul<mode>3"
4625   [(set (match_operand:SFDF 0 "gpc_reg_operand")
4626         (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4627                    (match_operand:SFDF 2 "gpc_reg_operand")))]
4628   "TARGET_HARD_FLOAT"
4629   "")
4631 (define_insn "*mul<mode>3_fpr"
4632   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4633         (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>")
4634                    (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4635   "TARGET_HARD_FLOAT"
4636   "@
4637    fmul<Ftrad> %0,%1,%2
4638    xsmul<Fvsx> %x0,%x1,%x2"
4639   [(set_attr "type" "dmul")])
4641 (define_expand "div<mode>3"
4642   [(set (match_operand:SFDF 0 "gpc_reg_operand")
4643         (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4644                   (match_operand:SFDF 2 "gpc_reg_operand")))]
4645   "TARGET_HARD_FLOAT"
4647   if (RS6000_RECIP_AUTO_RE_P (<MODE>mode)
4648       && can_create_pseudo_p () && flag_finite_math_only
4649       && !flag_trapping_math && flag_reciprocal_math)
4650     {
4651       rs6000_emit_swdiv (operands[0], operands[1], operands[2], true);
4652       DONE;
4653     }
4656 (define_insn "*div<mode>3_fpr"
4657   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4658         (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4659                   (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4660   "TARGET_HARD_FLOAT"
4661   "@
4662    fdiv<Ftrad> %0,%1,%2
4663    xsdiv<Fvsx> %x0,%x1,%x2"
4664   [(set_attr "type" "<Fs>div")])
4666 (define_insn "*sqrt<mode>2_internal"
4667   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4668         (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4669   "TARGET_HARD_FLOAT && TARGET_PPC_GPOPT"
4670   "@
4671    fsqrt<Ftrad> %0,%1
4672    xssqrt<Fvsx> %x0,%x1"
4673   [(set_attr "type" "<Fs>sqrt")])
4675 (define_expand "sqrt<mode>2"
4676   [(set (match_operand:SFDF 0 "gpc_reg_operand")
4677         (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))]
4678   "TARGET_HARD_FLOAT && TARGET_PPC_GPOPT"
4680   if (<MODE>mode == SFmode
4681       && TARGET_RECIP_PRECISION
4682       && RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)
4683       && !optimize_function_for_size_p (cfun)
4684       && flag_finite_math_only && !flag_trapping_math
4685       && flag_unsafe_math_optimizations)
4686     {
4687       rs6000_emit_swsqrt (operands[0], operands[1], 0);
4688       DONE;
4689     }
4692 ;; Floating point reciprocal approximation
4693 (define_insn "fre<Fs>"
4694   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4695         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")]
4696                      UNSPEC_FRES))]
4697   "TARGET_<FFRE>"
4698   "@
4699    fre<Ftrad> %0,%1
4700    xsre<Fvsx> %x0,%x1"
4701   [(set_attr "type" "fp")])
4703 (define_insn "*rsqrt<mode>2"
4704   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4705         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")]
4706                      UNSPEC_RSQRT))]
4707   "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4708   "@
4709    frsqrte<Ftrad> %0,%1
4710    xsrsqrte<Fvsx> %x0,%x1"
4711   [(set_attr "type" "fp")])
4713 ;; Floating point comparisons
4714 (define_insn "*cmp<mode>_fpr"
4715   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y,y")
4716         (compare:CCFP (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4717                       (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4718   "TARGET_HARD_FLOAT"
4719   "@
4720    fcmpu %0,%1,%2
4721    xscmpudp %0,%x1,%x2"
4722   [(set_attr "type" "fpcompare")])
4724 ;; Floating point conversions
4725 (define_expand "extendsfdf2"
4726   [(set (match_operand:DF 0 "gpc_reg_operand")
4727         (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand")))]
4728   "TARGET_HARD_FLOAT"
4730   if (HONOR_SNANS (SFmode))
4731     operands[1] = force_reg (SFmode, operands[1]);
4734 (define_insn_and_split "*extendsfdf2_fpr"
4735   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d,d,ws,?ws,wu,wb")
4736         (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand" "0,f,m,0,wy,Z,wY")))]
4737   "TARGET_HARD_FLOAT && !HONOR_SNANS (SFmode)"
4738   "@
4739    #
4740    fmr %0,%1
4741    lfs%U1%X1 %0,%1
4742    #
4743    xscpsgndp %x0,%x1,%x1
4744    lxsspx %x0,%y1
4745    lxssp %0,%1"
4746   "&& reload_completed && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1])"
4747   [(const_int 0)]
4749   emit_note (NOTE_INSN_DELETED);
4750   DONE;
4752   [(set_attr "type" "fp,fpsimple,fpload,fp,fpsimple,fpload,fpload")])
4754 (define_insn "*extendsfdf2_snan"
4755   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
4756         (float_extend:DF (match_operand:SF 1 "gpc_reg_operand" "f,wy")))]
4757   "TARGET_HARD_FLOAT && HONOR_SNANS (SFmode)"
4758   "@
4759    frsp %0,%1
4760    xsrsp %x0,%x1"
4761   [(set_attr "type" "fp")])
4763 (define_expand "truncdfsf2"
4764   [(set (match_operand:SF 0 "gpc_reg_operand")
4765         (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand")))]
4766   "TARGET_HARD_FLOAT"
4767   "")
4769 (define_insn "*truncdfsf2_fpr"
4770   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy")
4771         (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "d,ws")))]
4772   "TARGET_HARD_FLOAT"
4773   "@
4774    frsp %0,%1
4775    xsrsp %x0,%x1"
4776   [(set_attr "type" "fp")])
4778 ;; This expander is here to avoid FLOAT_WORDS_BIGENDIAN tests in
4779 ;; builtins.c and optabs.c that are not correct for IBM long double
4780 ;; when little-endian.
4781 (define_expand "signbit<mode>2"
4782   [(set (match_dup 2)
4783         (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand")))
4784    (set (match_dup 3)
4785         (subreg:DI (match_dup 2) 0))
4786    (set (match_dup 4)
4787         (match_dup 5))
4788    (set (match_operand:SI 0 "gpc_reg_operand")
4789         (match_dup 6))]
4790   "TARGET_HARD_FLOAT
4791    && (!FLOAT128_IEEE_P (<MODE>mode)
4792        || (TARGET_POWERPC64 && TARGET_DIRECT_MOVE))"
4794   if (FLOAT128_IEEE_P (<MODE>mode))
4795     {
4796       rtx dest = operands[0];
4797       rtx src = operands[1];
4798       rtx tmp = gen_reg_rtx (DImode);
4799       rtx dest_di = gen_lowpart (DImode, dest);
4801       if (<MODE>mode == KFmode)
4802         emit_insn (gen_signbitkf2_dm (tmp, src));
4803       else if (<MODE>mode == TFmode)
4804         emit_insn (gen_signbittf2_dm (tmp, src));
4805       else
4806         gcc_unreachable ();
4808       emit_insn (gen_lshrdi3 (dest_di, tmp, GEN_INT (63)));
4809       DONE;
4810     }
4811   operands[2] = gen_reg_rtx (DFmode);
4812   operands[3] = gen_reg_rtx (DImode);
4813   if (TARGET_POWERPC64)
4814     {
4815       operands[4] = gen_reg_rtx (DImode);
4816       operands[5] = gen_rtx_LSHIFTRT (DImode, operands[3], GEN_INT (63));
4817       operands[6] = gen_rtx_SUBREG (SImode, operands[4],
4818                                     WORDS_BIG_ENDIAN ? 4 : 0);
4819     }
4820   else
4821     {
4822       operands[4] = gen_reg_rtx (SImode);
4823       operands[5] = gen_rtx_SUBREG (SImode, operands[3],
4824                                     WORDS_BIG_ENDIAN ? 0 : 4);
4825       operands[6] = gen_rtx_LSHIFTRT (SImode, operands[4], GEN_INT (31));
4826     }
4829 ;; Optimize IEEE 128-bit signbit on 64-bit systems with direct move to avoid
4830 ;; multiple direct moves.  If we used a SUBREG:DI of the Floa128 type, the
4831 ;; register allocator would typically move the entire _Float128 item to GPRs (2
4832 ;; instructions on ISA 3.0, 3-4 instructions on ISA 2.07).
4834 ;; After register allocation, if the _Float128 had originally been in GPRs, the
4835 ;; split allows the post reload phases to eliminate the move, and do the shift
4836 ;; directly with the register that contains the signbit.
4837 (define_insn_and_split "signbit<mode>2_dm"
4838   [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
4839         (unspec:DI [(match_operand:SIGNBIT 1 "gpc_reg_operand" "wa,r")]
4840                    UNSPEC_SIGNBIT))]
4841   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
4842   "@
4843    mfvsrd %0,%x1
4844    #"
4845   "&& reload_completed && int_reg_operand (operands[1], <MODE>mode)"
4846   [(set (match_dup 0)
4847         (match_dup 2))]
4849   operands[2] = gen_highpart (DImode, operands[1]);
4851  [(set_attr "type" "mftgpr,*")])
4853 ;; Optimize IEEE 128-bit signbit on to avoid loading the value into a vector
4854 ;; register and then doing a direct move if the value comes from memory.  On
4855 ;; little endian, we have to load the 2nd double-word to get the sign bit.
4856 (define_insn_and_split "*signbit<mode>2_dm_mem"
4857   [(set (match_operand:DI 0 "gpc_reg_operand" "=b")
4858         (unspec:DI [(match_operand:SIGNBIT 1 "memory_operand" "m")]
4859                    UNSPEC_SIGNBIT))]
4860   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
4861   "#"
4862   "&& 1"
4863   [(set (match_dup 0)
4864         (match_dup 2))]
4866   rtx dest = operands[0];
4867   rtx src = operands[1];
4868   rtx addr = XEXP (src, 0);
4870   if (WORDS_BIG_ENDIAN)
4871     operands[2] = adjust_address (src, DImode, 0);
4873   else if (REG_P (addr) || SUBREG_P (addr))
4874     operands[2] = adjust_address (src, DImode, 8);
4876   else if (GET_CODE (addr) == PLUS && REG_P (XEXP (addr, 0))
4877            && CONST_INT_P (XEXP (addr, 1)) && mem_operand_gpr (src, DImode))
4878     operands[2] = adjust_address (src, DImode, 8);
4880   else
4881     {
4882       rtx tmp = can_create_pseudo_p () ? gen_reg_rtx (DImode) : dest;
4883       emit_insn (gen_rtx_SET (tmp, addr));
4884       operands[2] = change_address (src, DImode,
4885                                     gen_rtx_PLUS (DImode, tmp, GEN_INT (8)));
4886     }
4889 (define_expand "copysign<mode>3"
4890   [(set (match_dup 3)
4891         (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))
4892    (set (match_dup 4)
4893         (neg:SFDF (abs:SFDF (match_dup 1))))
4894    (set (match_operand:SFDF 0 "gpc_reg_operand")
4895         (if_then_else:SFDF (ge (match_operand:SFDF 2 "gpc_reg_operand")
4896                                (match_dup 5))
4897                          (match_dup 3)
4898                          (match_dup 4)))]
4899   "TARGET_HARD_FLOAT
4900    && ((TARGET_PPC_GFXOPT
4901         && !HONOR_NANS (<MODE>mode)
4902         && !HONOR_SIGNED_ZEROS (<MODE>mode))
4903        || TARGET_CMPB
4904        || VECTOR_UNIT_VSX_P (<MODE>mode))"
4906   if (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode))
4907     {
4908       emit_insn (gen_copysign<mode>3_fcpsgn (operands[0], operands[1],
4909                                              operands[2]));
4910       DONE;
4911     }
4913    operands[3] = gen_reg_rtx (<MODE>mode);
4914    operands[4] = gen_reg_rtx (<MODE>mode);
4915    operands[5] = CONST0_RTX (<MODE>mode);
4916   })
4918 ;; Use an unspec rather providing an if-then-else in RTL, to prevent the
4919 ;; compiler from optimizing -0.0
4920 (define_insn "copysign<mode>3_fcpsgn"
4921   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4922         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")
4923                       (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")]
4924                      UNSPEC_COPYSIGN))]
4925   "TARGET_HARD_FLOAT && (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode))"
4926   "@
4927    fcpsgn %0,%2,%1
4928    xscpsgndp %x0,%x2,%x1"
4929   [(set_attr "type" "fpsimple")])
4931 ;; For MIN, MAX, and conditional move, we use DEFINE_EXPAND's that involve a
4932 ;; fsel instruction and some auxiliary computations.  Then we just have a
4933 ;; single DEFINE_INSN for fsel and the define_splits to make them if made by
4934 ;; combine.
4935 ;; For MIN, MAX on non-VSX machines, and conditional move all of the time, we
4936 ;; use DEFINE_EXPAND's that involve a fsel instruction and some auxiliary
4937 ;; computations.  Then we just have a single DEFINE_INSN for fsel and the
4938 ;; define_splits to make them if made by combine.  On VSX machines we have the
4939 ;; min/max instructions.
4941 ;; On VSX, we only check for TARGET_VSX instead of checking for a vsx/p8 vector
4942 ;; to allow either DF/SF to use only traditional registers.
4944 (define_expand "s<minmax><mode>3"
4945   [(set (match_operand:SFDF 0 "gpc_reg_operand")
4946         (fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4947                         (match_operand:SFDF 2 "gpc_reg_operand")))]
4948   "TARGET_MINMAX"
4950   rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]);
4951   DONE;
4954 (define_insn "*s<minmax><mode>3_vsx"
4955   [(set (match_operand:SFDF 0 "vsx_register_operand" "=<Fv>")
4956         (fp_minmax:SFDF (match_operand:SFDF 1 "vsx_register_operand" "<Fv>")
4957                         (match_operand:SFDF 2 "vsx_register_operand" "<Fv>")))]
4958   "TARGET_VSX && TARGET_HARD_FLOAT"
4960   return (TARGET_P9_MINMAX
4961           ? "xs<minmax>cdp %x0,%x1,%x2"
4962           : "xs<minmax>dp %x0,%x1,%x2");
4964   [(set_attr "type" "fp")])
4966 ;; The conditional move instructions allow us to perform max and min operations
4967 ;; even when we don't have the appropriate max/min instruction using the FSEL
4968 ;; instruction.
4970 (define_insn_and_split "*s<minmax><mode>3_fpr"
4971   [(set (match_operand:SFDF 0 "gpc_reg_operand")
4972         (fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4973                         (match_operand:SFDF 2 "gpc_reg_operand")))]
4974   "!TARGET_VSX && TARGET_MINMAX"
4975   "#"
4976   "&& 1"
4977   [(const_int 0)]
4979   rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]);
4980   DONE;
4983 (define_expand "mov<mode>cc"
4984    [(set (match_operand:GPR 0 "gpc_reg_operand")
4985          (if_then_else:GPR (match_operand 1 "comparison_operator")
4986                            (match_operand:GPR 2 "gpc_reg_operand")
4987                            (match_operand:GPR 3 "gpc_reg_operand")))]
4988   "TARGET_ISEL"
4990   if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
4991     DONE;
4992   else
4993     FAIL;
4996 ;; We use the BASE_REGS for the isel input operands because, if rA is
4997 ;; 0, the value of 0 is placed in rD upon truth.  Similarly for rB
4998 ;; because we may switch the operands and rB may end up being rA.
5000 ;; We need 2 patterns: an unsigned and a signed pattern.  We could
5001 ;; leave out the mode in operand 4 and use one pattern, but reload can
5002 ;; change the mode underneath our feet and then gets confused trying
5003 ;; to reload the value.
5004 (define_insn "isel_signed_<mode>"
5005   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
5006         (if_then_else:GPR
5007          (match_operator 1 "scc_comparison_operator"
5008                          [(match_operand:CC 4 "cc_reg_operand" "y,y")
5009                           (const_int 0)])
5010          (match_operand:GPR 2 "reg_or_zero_operand" "O,b")
5011          (match_operand:GPR 3 "gpc_reg_operand" "r,r")))]
5012   "TARGET_ISEL"
5013   "isel %0,%2,%3,%j1"
5014   [(set_attr "type" "isel")])
5016 (define_insn "isel_unsigned_<mode>"
5017   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
5018         (if_then_else:GPR
5019          (match_operator 1 "scc_comparison_operator"
5020                          [(match_operand:CCUNS 4 "cc_reg_operand" "y,y")
5021                           (const_int 0)])
5022          (match_operand:GPR 2 "reg_or_zero_operand" "O,b")
5023          (match_operand:GPR 3 "gpc_reg_operand" "r,r")))]
5024   "TARGET_ISEL"
5025   "isel %0,%2,%3,%j1"
5026   [(set_attr "type" "isel")])
5028 ;; These patterns can be useful for combine; they let combine know that
5029 ;; isel can handle reversed comparisons so long as the operands are
5030 ;; registers.
5032 (define_insn "*isel_reversed_signed_<mode>"
5033   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
5034         (if_then_else:GPR
5035          (match_operator 1 "scc_rev_comparison_operator"
5036                          [(match_operand:CC 4 "cc_reg_operand" "y,y")
5037                           (const_int 0)])
5038          (match_operand:GPR 2 "gpc_reg_operand" "r,r")
5039          (match_operand:GPR 3 "reg_or_zero_operand" "O,b")))]
5040   "TARGET_ISEL"
5042   PUT_CODE (operands[1], reverse_condition (GET_CODE (operands[1])));
5043   return "isel %0,%3,%2,%j1";
5045   [(set_attr "type" "isel")])
5047 (define_insn "*isel_reversed_unsigned_<mode>"
5048   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
5049         (if_then_else:GPR
5050          (match_operator 1 "scc_rev_comparison_operator"
5051                          [(match_operand:CCUNS 4 "cc_reg_operand" "y,y")
5052                           (const_int 0)])
5053          (match_operand:GPR 2 "gpc_reg_operand" "r,r")
5054          (match_operand:GPR 3 "reg_or_zero_operand" "O,b")))]
5055   "TARGET_ISEL"
5057   PUT_CODE (operands[1], reverse_condition (GET_CODE (operands[1])));
5058   return "isel %0,%3,%2,%j1";
5060   [(set_attr "type" "isel")])
5062 ;; Floating point conditional move
5063 (define_expand "mov<mode>cc"
5064    [(set (match_operand:SFDF 0 "gpc_reg_operand")
5065          (if_then_else:SFDF (match_operand 1 "comparison_operator")
5066                             (match_operand:SFDF 2 "gpc_reg_operand")
5067                             (match_operand:SFDF 3 "gpc_reg_operand")))]
5068   "TARGET_HARD_FLOAT && TARGET_PPC_GFXOPT"
5070   if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
5071     DONE;
5072   else
5073     FAIL;
5076 (define_insn "*fsel<SFDF:mode><SFDF2:mode>4"
5077   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=&<SFDF:rreg2>")
5078         (if_then_else:SFDF
5079          (ge (match_operand:SFDF2 1 "gpc_reg_operand" "<SFDF2:rreg2>")
5080              (match_operand:SFDF2 4 "zero_fp_constant" "F"))
5081          (match_operand:SFDF 2 "gpc_reg_operand" "<SFDF:rreg2>")
5082          (match_operand:SFDF 3 "gpc_reg_operand" "<SFDF:rreg2>")))]
5083   "TARGET_HARD_FLOAT && TARGET_PPC_GFXOPT"
5084   "fsel %0,%1,%2,%3"
5085   [(set_attr "type" "fp")])
5087 (define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_p9"
5088   [(set (match_operand:SFDF 0 "vsx_register_operand" "=&<SFDF:Fv>,<SFDF:Fv>")
5089         (if_then_else:SFDF
5090          (match_operator:CCFP 1 "fpmask_comparison_operator"
5091                 [(match_operand:SFDF2 2 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")
5092                  (match_operand:SFDF2 3 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")])
5093          (match_operand:SFDF 4 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")
5094          (match_operand:SFDF 5 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")))
5095    (clobber (match_scratch:V2DI 6 "=0,&wa"))]
5096   "TARGET_P9_MINMAX"
5097   "#"
5098   ""
5099   [(set (match_dup 6)
5100         (if_then_else:V2DI (match_dup 1)
5101                            (match_dup 7)
5102                            (match_dup 8)))
5103    (set (match_dup 0)
5104         (if_then_else:SFDF (ne (match_dup 6)
5105                                (match_dup 8))
5106                            (match_dup 4)
5107                            (match_dup 5)))]
5109   if (GET_CODE (operands[6]) == SCRATCH)
5110     operands[6] = gen_reg_rtx (V2DImode);
5112   operands[7] = CONSTM1_RTX (V2DImode);
5113   operands[8] = CONST0_RTX (V2DImode);
5115  [(set_attr "length" "8")
5116   (set_attr "type" "vecperm")])
5118 ;; Handle inverting the fpmask comparisons.
5119 (define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_invert_p9"
5120   [(set (match_operand:SFDF 0 "vsx_register_operand" "=&<SFDF:Fv>,<SFDF:Fv>")
5121         (if_then_else:SFDF
5122          (match_operator:CCFP 1 "invert_fpmask_comparison_operator"
5123                 [(match_operand:SFDF2 2 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")
5124                  (match_operand:SFDF2 3 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")])
5125          (match_operand:SFDF 4 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")
5126          (match_operand:SFDF 5 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")))
5127    (clobber (match_scratch:V2DI 6 "=0,&wa"))]
5128   "TARGET_P9_MINMAX"
5129   "#"
5130   "&& 1"
5131   [(set (match_dup 6)
5132         (if_then_else:V2DI (match_dup 9)
5133                            (match_dup 7)
5134                            (match_dup 8)))
5135    (set (match_dup 0)
5136         (if_then_else:SFDF (ne (match_dup 6)
5137                                (match_dup 8))
5138                            (match_dup 5)
5139                            (match_dup 4)))]
5141   rtx op1 = operands[1];
5142   enum rtx_code cond = reverse_condition_maybe_unordered (GET_CODE (op1));
5144   if (GET_CODE (operands[6]) == SCRATCH)
5145     operands[6] = gen_reg_rtx (V2DImode);
5147   operands[7] = CONSTM1_RTX (V2DImode);
5148   operands[8] = CONST0_RTX (V2DImode);
5150   operands[9] = gen_rtx_fmt_ee (cond, CCFPmode, operands[2], operands[3]);
5152  [(set_attr "length" "8")
5153   (set_attr "type" "vecperm")])
5155 (define_insn "*fpmask<mode>"
5156   [(set (match_operand:V2DI 0 "vsx_register_operand" "=wa")
5157         (if_then_else:V2DI
5158          (match_operator:CCFP 1 "fpmask_comparison_operator"
5159                 [(match_operand:SFDF 2 "vsx_register_operand" "<Fv>")
5160                  (match_operand:SFDF 3 "vsx_register_operand" "<Fv>")])
5161          (match_operand:V2DI 4 "all_ones_constant" "")
5162          (match_operand:V2DI 5 "zero_constant" "")))]
5163   "TARGET_P9_MINMAX"
5164   "xscmp%V1dp %x0,%x2,%x3"
5165   [(set_attr "type" "fpcompare")])
5167 (define_insn "*xxsel<mode>"
5168   [(set (match_operand:SFDF 0 "vsx_register_operand" "=<Fv>")
5169         (if_then_else:SFDF (ne (match_operand:V2DI 1 "vsx_register_operand" "wa")
5170                                (match_operand:V2DI 2 "zero_constant" ""))
5171                            (match_operand:SFDF 3 "vsx_register_operand" "<Fv>")
5172                            (match_operand:SFDF 4 "vsx_register_operand" "<Fv>")))]
5173   "TARGET_P9_MINMAX"
5174   "xxsel %x0,%x4,%x3,%x1"
5175   [(set_attr "type" "vecmove")])
5178 ;; Conversions to and from floating-point.
5180 ; We don't define lfiwax/lfiwzx with the normal definition, because we
5181 ; don't want to support putting SImode in FPR registers.
5182 (define_insn "lfiwax"
5183   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wj,wj,wK")
5184         (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r,wK")]
5185                    UNSPEC_LFIWAX))]
5186   "TARGET_HARD_FLOAT && TARGET_LFIWAX"
5187   "@
5188    lfiwax %0,%y1
5189    lxsiwax %x0,%y1
5190    mtvsrwa %x0,%1
5191    vextsw2d %0,%1"
5192   [(set_attr "type" "fpload,fpload,mffgpr,vecexts")])
5194 ; This split must be run before register allocation because it allocates the
5195 ; memory slot that is needed to move values to/from the FPR.  We don't allocate
5196 ; it earlier to allow for the combiner to merge insns together where it might
5197 ; not be needed and also in case the insns are deleted as dead code.
5199 (define_insn_and_split "floatsi<mode>2_lfiwax"
5200   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5201         (float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r")))
5202    (clobber (match_scratch:DI 2 "=wi"))]
5203   "TARGET_HARD_FLOAT && TARGET_LFIWAX
5204    && <SI_CONVERT_FP> && can_create_pseudo_p ()"
5205   "#"
5206   ""
5207   [(pc)]
5209   rtx dest = operands[0];
5210   rtx src = operands[1];
5211   rtx tmp;
5213   if (!MEM_P (src) && TARGET_POWERPC64
5214       && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5215     tmp = convert_to_mode (DImode, src, false);
5216   else
5217     {
5218       tmp = operands[2];
5219       if (GET_CODE (tmp) == SCRATCH)
5220         tmp = gen_reg_rtx (DImode);
5221       if (MEM_P (src))
5222         {
5223           src = rs6000_force_indexed_or_indirect_mem (src);
5224           emit_insn (gen_lfiwax (tmp, src));
5225         }
5226       else
5227         {
5228           rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5229           emit_move_insn (stack, src);
5230           emit_insn (gen_lfiwax (tmp, stack));
5231         }
5232     }
5233   emit_insn (gen_floatdi<mode>2 (dest, tmp));
5234   DONE;
5236   [(set_attr "length" "12")
5237    (set_attr "type" "fpload")])
5239 (define_insn_and_split "floatsi<mode>2_lfiwax_mem"
5240   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5241         (float:SFDF
5242          (sign_extend:DI
5243           (match_operand:SI 1 "indexed_or_indirect_operand" "Z"))))
5244    (clobber (match_scratch:DI 2 "=wi"))]
5245   "TARGET_HARD_FLOAT && TARGET_LFIWAX && <SI_CONVERT_FP>"
5246   "#"
5247   ""
5248   [(pc)]
5250   operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
5251   if (GET_CODE (operands[2]) == SCRATCH)
5252     operands[2] = gen_reg_rtx (DImode);
5253   if (TARGET_P8_VECTOR)
5254     emit_insn (gen_extendsidi2 (operands[2], operands[1]));
5255   else
5256     emit_insn (gen_lfiwax (operands[2], operands[1]));
5257   emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
5258   DONE;
5260   [(set_attr "length" "8")
5261    (set_attr "type" "fpload")])
5263 (define_insn "lfiwzx"
5264   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wj,wj,wJwK")
5265         (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r,wJwK")]
5266                    UNSPEC_LFIWZX))]
5267   "TARGET_HARD_FLOAT && TARGET_LFIWZX"
5268   "@
5269    lfiwzx %0,%y1
5270    lxsiwzx %x0,%y1
5271    mtvsrwz %x0,%1
5272    xxextractuw %x0,%x1,4"
5273   [(set_attr "type" "fpload,fpload,mftgpr,vecexts")])
5275 (define_insn_and_split "floatunssi<mode>2_lfiwzx"
5276   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5277         (unsigned_float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r")))
5278    (clobber (match_scratch:DI 2 "=wi"))]
5279   "TARGET_HARD_FLOAT && TARGET_LFIWZX && <SI_CONVERT_FP>"
5280   "#"
5281   ""
5282   [(pc)]
5284   rtx dest = operands[0];
5285   rtx src = operands[1];
5286   rtx tmp;
5288   if (!MEM_P (src) && TARGET_POWERPC64
5289       && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5290     tmp = convert_to_mode (DImode, src, true);
5291   else
5292     {
5293       tmp = operands[2];
5294       if (GET_CODE (tmp) == SCRATCH)
5295         tmp = gen_reg_rtx (DImode);
5296       if (MEM_P (src))
5297         {
5298           src = rs6000_force_indexed_or_indirect_mem (src);
5299           emit_insn (gen_lfiwzx (tmp, src));
5300         }
5301       else
5302         {
5303           rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5304           emit_move_insn (stack, src);
5305           emit_insn (gen_lfiwzx (tmp, stack));
5306         }
5307     }
5308   emit_insn (gen_floatdi<mode>2 (dest, tmp));
5309   DONE;
5311   [(set_attr "length" "12")
5312    (set_attr "type" "fpload")])
5314 (define_insn_and_split "floatunssi<mode>2_lfiwzx_mem"
5315   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5316         (unsigned_float:SFDF
5317          (zero_extend:DI
5318           (match_operand:SI 1 "indexed_or_indirect_operand" "Z"))))
5319    (clobber (match_scratch:DI 2 "=wi"))]
5320   "TARGET_HARD_FLOAT && TARGET_LFIWZX && <SI_CONVERT_FP>"
5321   "#"
5322   ""
5323   [(pc)]
5325   operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
5326   if (GET_CODE (operands[2]) == SCRATCH)
5327     operands[2] = gen_reg_rtx (DImode);
5328   if (TARGET_P8_VECTOR)
5329     emit_insn (gen_zero_extendsidi2 (operands[2], operands[1]));
5330   else
5331     emit_insn (gen_lfiwzx (operands[2], operands[1]));
5332   emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
5333   DONE;
5335   [(set_attr "length" "8")
5336    (set_attr "type" "fpload")])
5338 ; For each of these conversions, there is a define_expand, a define_insn
5339 ; with a '#' template, and a define_split (with C code).  The idea is
5340 ; to allow constant folding with the template of the define_insn,
5341 ; then to have the insns split later (between sched1 and final).
5343 (define_expand "floatsidf2"
5344   [(parallel [(set (match_operand:DF 0 "gpc_reg_operand")
5345                    (float:DF (match_operand:SI 1 "nonimmediate_operand")))
5346               (use (match_dup 2))
5347               (use (match_dup 3))
5348               (clobber (match_dup 4))
5349               (clobber (match_dup 5))
5350               (clobber (match_dup 6))])]
5351   "TARGET_HARD_FLOAT"
5353   if (TARGET_LFIWAX && TARGET_FCFID)
5354     {
5355       emit_insn (gen_floatsidf2_lfiwax (operands[0], operands[1]));
5356       DONE;
5357     }
5358   else if (TARGET_FCFID)
5359     {
5360       rtx dreg = operands[1];
5361       if (!REG_P (dreg))
5362         dreg = force_reg (SImode, dreg);
5363       dreg = convert_to_mode (DImode, dreg, false);
5364       emit_insn (gen_floatdidf2 (operands[0], dreg));
5365       DONE;
5366     }
5368   if (!REG_P (operands[1]))
5369     operands[1] = force_reg (SImode, operands[1]);
5370   operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5371   operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503601774854144\", DFmode));
5372   operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5373   operands[5] = gen_reg_rtx (DFmode);
5374   operands[6] = gen_reg_rtx (SImode);
5377 (define_insn_and_split "*floatsidf2_internal"
5378   [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5379         (float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5380    (use (match_operand:SI 2 "gpc_reg_operand" "r"))
5381    (use (match_operand:DF 3 "gpc_reg_operand" "d"))
5382    (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
5383    (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))
5384    (clobber (match_operand:SI 6 "gpc_reg_operand" "=&r"))]
5385   "!TARGET_FCFID && TARGET_HARD_FLOAT"
5386   "#"
5387   ""
5388   [(pc)]
5390   rtx lowword, highword;
5391   gcc_assert (MEM_P (operands[4]));
5392   highword = adjust_address (operands[4], SImode, 0);
5393   lowword = adjust_address (operands[4], SImode, 4);
5394   if (! WORDS_BIG_ENDIAN)
5395     std::swap (lowword, highword);
5397   emit_insn (gen_xorsi3 (operands[6], operands[1],
5398                          GEN_INT (~ (HOST_WIDE_INT) 0x7fffffff)));
5399   emit_move_insn (lowword, operands[6]);
5400   emit_move_insn (highword, operands[2]);
5401   emit_move_insn (operands[5], operands[4]);
5402   emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5403   DONE;
5405   [(set_attr "length" "24")
5406    (set_attr "type" "fp")])
5408 ;; If we don't have a direct conversion to single precision, don't enable this
5409 ;; conversion for 32-bit without fast math, because we don't have the insn to
5410 ;; generate the fixup swizzle to avoid double rounding problems.
5411 (define_expand "floatunssisf2"
5412   [(set (match_operand:SF 0 "gpc_reg_operand")
5413         (unsigned_float:SF (match_operand:SI 1 "nonimmediate_operand")))]
5414   "TARGET_HARD_FLOAT
5415    && ((TARGET_FCFIDUS && TARGET_LFIWZX)
5416        || (TARGET_FCFID
5417            && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))"
5419   if (TARGET_LFIWZX && TARGET_FCFIDUS)
5420     {
5421       emit_insn (gen_floatunssisf2_lfiwzx (operands[0], operands[1]));
5422       DONE;
5423     }
5424   else
5425     {
5426       rtx dreg = operands[1];
5427       if (!REG_P (dreg))
5428         dreg = force_reg (SImode, dreg);
5429       dreg = convert_to_mode (DImode, dreg, true);
5430       emit_insn (gen_floatdisf2 (operands[0], dreg));
5431       DONE;
5432     }
5435 (define_expand "floatunssidf2"
5436   [(parallel [(set (match_operand:DF 0 "gpc_reg_operand")
5437                    (unsigned_float:DF (match_operand:SI 1 "nonimmediate_operand")))
5438               (use (match_dup 2))
5439               (use (match_dup 3))
5440               (clobber (match_dup 4))
5441               (clobber (match_dup 5))])]
5442   "TARGET_HARD_FLOAT"
5444   if (TARGET_LFIWZX && TARGET_FCFID)
5445     {
5446       emit_insn (gen_floatunssidf2_lfiwzx (operands[0], operands[1]));
5447       DONE;
5448     }
5449   else if (TARGET_FCFID)
5450     {
5451       rtx dreg = operands[1];
5452       if (!REG_P (dreg))
5453         dreg = force_reg (SImode, dreg);
5454       dreg = convert_to_mode (DImode, dreg, true);
5455       emit_insn (gen_floatdidf2 (operands[0], dreg));
5456       DONE;
5457     }
5459   if (!REG_P (operands[1]))
5460     operands[1] = force_reg (SImode, operands[1]);
5461   operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5462   operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503599627370496\", DFmode));
5463   operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5464   operands[5] = gen_reg_rtx (DFmode);
5467 (define_insn_and_split "*floatunssidf2_internal"
5468   [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5469         (unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5470    (use (match_operand:SI 2 "gpc_reg_operand" "r"))
5471    (use (match_operand:DF 3 "gpc_reg_operand" "d"))
5472    (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
5473    (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))]
5474   "!TARGET_FCFIDU && TARGET_HARD_FLOAT
5475    && !(TARGET_FCFID && TARGET_POWERPC64)"
5476   "#"
5477   ""
5478   [(pc)]
5480   rtx lowword, highword;
5481   gcc_assert (MEM_P (operands[4]));
5482   highword = adjust_address (operands[4], SImode, 0);
5483   lowword = adjust_address (operands[4], SImode, 4);
5484   if (! WORDS_BIG_ENDIAN)
5485     std::swap (lowword, highword);
5487   emit_move_insn (lowword, operands[1]);
5488   emit_move_insn (highword, operands[2]);
5489   emit_move_insn (operands[5], operands[4]);
5490   emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5491   DONE;
5493   [(set_attr "length" "20")
5494    (set_attr "type" "fp")])
5496 ;; ISA 3.0 adds instructions lxsi[bh]zx to directly load QImode and HImode to
5497 ;; vector registers.  These insns favor doing the sign/zero extension in
5498 ;; the vector registers, rather then loading up a GPR, doing a sign/zero
5499 ;; extension and then a direct move.
5501 (define_expand "float<QHI:mode><FP_ISA3:mode>2"
5502   [(parallel [(set (match_operand:FP_ISA3 0 "vsx_register_operand")
5503                    (float:FP_ISA3
5504                     (match_operand:QHI 1 "input_operand")))
5505               (clobber (match_scratch:DI 2))
5506               (clobber (match_scratch:DI 3))
5507               (clobber (match_scratch:<QHI:MODE> 4))])]
5508   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5510   if (MEM_P (operands[1]))
5511     operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
5514 (define_insn_and_split "*float<QHI:mode><FP_ISA3:mode>2_internal"
5515   [(set (match_operand:FP_ISA3 0 "vsx_register_operand" "=<Fv>,<Fv>,<Fv>")
5516         (float:FP_ISA3
5517          (match_operand:QHI 1 "reg_or_indexed_operand" "wK,r,Z")))
5518    (clobber (match_scratch:DI 2 "=wK,wi,wK"))
5519    (clobber (match_scratch:DI 3 "=X,r,X"))
5520    (clobber (match_scratch:<QHI:MODE> 4 "=X,X,wK"))]
5521   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5522   "#"
5523   "&& reload_completed"
5524   [(const_int 0)]
5526   rtx result = operands[0];
5527   rtx input = operands[1];
5528   rtx di = operands[2];
5530   if (!MEM_P (input))
5531     {
5532       rtx tmp = operands[3];
5533       if (altivec_register_operand (input, <QHI:MODE>mode))
5534         emit_insn (gen_extend<QHI:mode>di2 (di, input));
5535       else if (GET_CODE (tmp) == SCRATCH)
5536         emit_insn (gen_extend<QHI:mode>di2 (di, input));
5537       else
5538         {
5539           emit_insn (gen_extend<QHI:mode>di2 (tmp, input));
5540           emit_move_insn (di, tmp);
5541         }
5542     }
5543   else
5544     {
5545       rtx tmp = operands[4];
5546       emit_move_insn (tmp, input);
5547       emit_insn (gen_extend<QHI:mode>di2 (di, tmp));
5548     }
5550   emit_insn (gen_floatdi<FP_ISA3:mode>2 (result, di));
5551   DONE;
5554 (define_expand "floatuns<QHI:mode><FP_ISA3:mode>2"
5555   [(parallel [(set (match_operand:FP_ISA3 0 "vsx_register_operand")
5556                    (unsigned_float:FP_ISA3
5557                     (match_operand:QHI 1 "input_operand")))
5558               (clobber (match_scratch:DI 2))
5559               (clobber (match_scratch:DI 3))])]
5560   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5562   if (MEM_P (operands[1]))
5563     operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
5566 (define_insn_and_split "*floatuns<QHI:mode><FP_ISA3:mode>2_internal"
5567   [(set (match_operand:FP_ISA3 0 "vsx_register_operand" "=<Fv>,<Fv>,<Fv>")
5568         (unsigned_float:FP_ISA3
5569          (match_operand:QHI 1 "reg_or_indexed_operand" "wK,r,Z")))
5570    (clobber (match_scratch:DI 2 "=wK,wi,wJwK"))
5571    (clobber (match_scratch:DI 3 "=X,r,X"))]
5572   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5573   "#"
5574   "&& reload_completed"
5575   [(const_int 0)]
5577   rtx result = operands[0];
5578   rtx input = operands[1];
5579   rtx di = operands[2];
5581   if (MEM_P (input) || altivec_register_operand (input, <QHI:MODE>mode))
5582     emit_insn (gen_zero_extend<QHI:mode>di2 (di, input));
5583   else
5584     {
5585       rtx tmp = operands[3];
5586       if (GET_CODE (tmp) == SCRATCH)
5587         emit_insn (gen_extend<QHI:mode>di2 (di, input));
5588       else
5589         {
5590           emit_insn (gen_zero_extend<QHI:mode>di2 (tmp, input));
5591           emit_move_insn (di, tmp);
5592         }
5593     }
5595   emit_insn (gen_floatdi<FP_ISA3:mode>2 (result, di));
5596   DONE;
5599 (define_expand "fix_trunc<mode>si2"
5600   [(set (match_operand:SI 0 "gpc_reg_operand")
5601         (fix:SI (match_operand:SFDF 1 "gpc_reg_operand")))]
5602   "TARGET_HARD_FLOAT"
5604   if (!(TARGET_P8_VECTOR && TARGET_DIRECT_MOVE))
5605     {
5606       rtx src = force_reg (<MODE>mode, operands[1]);
5608       if (TARGET_STFIWX)
5609         emit_insn (gen_fix_trunc<mode>si2_stfiwx (operands[0], src));
5610       else
5611         {
5612           rtx tmp = gen_reg_rtx (DImode);
5613           rtx stack = rs6000_allocate_stack_temp (DImode, true, false);
5614           emit_insn (gen_fix_trunc<mode>si2_internal (operands[0], src,
5615                                                       tmp, stack));
5616         }
5617       DONE;
5618     }
5621 ; Like the convert to float patterns, this insn must be split before
5622 ; register allocation so that it can allocate the memory slot if it
5623 ; needed
5624 (define_insn_and_split "fix_trunc<mode>si2_stfiwx"
5625   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5626         (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
5627    (clobber (match_scratch:DI 2 "=d"))]
5628   "TARGET_HARD_FLOAT && TARGET_STFIWX && can_create_pseudo_p ()
5629    && !(TARGET_P8_VECTOR && TARGET_DIRECT_MOVE)"
5630   "#"
5631   ""
5632   [(pc)]
5634   rtx dest = operands[0];
5635   rtx src = operands[1];
5636   rtx tmp = operands[2];
5638   if (GET_CODE (tmp) == SCRATCH)
5639     tmp = gen_reg_rtx (DImode);
5641   emit_insn (gen_fctiwz_<mode> (tmp, src));
5642   if (MEM_P (dest))
5643     {
5644       dest = rs6000_force_indexed_or_indirect_mem (dest);
5645       emit_insn (gen_stfiwx (dest, tmp));
5646       DONE;
5647     }
5648   else if (TARGET_POWERPC64 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5649     {
5650       dest = gen_lowpart (DImode, dest);
5651       emit_move_insn (dest, tmp);
5652       DONE;
5653     }
5654   else
5655     {
5656       rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5657       emit_insn (gen_stfiwx (stack, tmp));
5658       emit_move_insn (dest, stack);
5659       DONE;
5660     }
5662   [(set_attr "length" "12")
5663    (set_attr "type" "fp")])
5665 (define_insn_and_split "fix_trunc<mode>si2_internal"
5666   [(set (match_operand:SI 0 "gpc_reg_operand" "=r,?r")
5667         (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d,<rreg>")))
5668    (clobber (match_operand:DI 2 "gpc_reg_operand" "=1,d"))
5669    (clobber (match_operand:DI 3 "offsettable_mem_operand" "=o,o"))]
5670   "TARGET_HARD_FLOAT
5671    && !(TARGET_P8_VECTOR && TARGET_DIRECT_MOVE)"
5672   "#"
5673   ""
5674   [(pc)]
5676   rtx lowword;
5677   gcc_assert (MEM_P (operands[3]));
5678   lowword = adjust_address (operands[3], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
5680   emit_insn (gen_fctiwz_<mode> (operands[2], operands[1]));
5681   emit_move_insn (operands[3], operands[2]);
5682   emit_move_insn (operands[0], lowword);
5683   DONE;
5685   [(set_attr "length" "16")
5686    (set_attr "type" "fp")])
5688 (define_expand "fix_trunc<mode>di2"
5689   [(set (match_operand:DI 0 "gpc_reg_operand")
5690         (fix:DI (match_operand:SFDF 1 "gpc_reg_operand")))]
5691   "TARGET_HARD_FLOAT && TARGET_FCFID"
5692   "")
5694 (define_insn "*fix_trunc<mode>di2_fctidz"
5695   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5696         (fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
5697   "TARGET_HARD_FLOAT && TARGET_FCFID"
5698   "@
5699    fctidz %0,%1
5700    xscvdpsxds %x0,%x1"
5701   [(set_attr "type" "fp")])
5703 ;; If we have ISA 3.0, QI/HImode values can go in both VSX registers and GPR
5704 ;; registers.  If we have ISA 2.07, we don't allow QI/HImode values in the
5705 ;; vector registers, so we need to do direct moves to the GPRs, but SImode
5706 ;; values can go in VSX registers.  Keeping the direct move part through
5707 ;; register allocation prevents the register allocator from doing a direct move
5708 ;; of the SImode value to a GPR, and then a store/load.
5709 (define_insn_and_split "fix<uns>_trunc<SFDF:mode><QHI:mode>2"
5710   [(set (match_operand:<QHI:MODE> 0 "gpc_reg_operand" "=wJ,wJwK,r")
5711         (any_fix:QHI (match_operand:SFDF 1 "gpc_reg_operand" "wJ,wJwK,wa")))
5712    (clobber (match_scratch:SI 2 "=X,X,wi"))]
5713   "TARGET_DIRECT_MOVE"
5714   "@
5715    fctiw<u>z %0,%1
5716    xscvdp<su>xws %x0,%x1
5717    #"
5718   "&& reload_completed && int_reg_operand (operands[0], <QHI:MODE>mode)"
5719   [(set (match_dup 2)
5720         (any_fix:SI (match_dup 1)))
5721    (set (match_dup 3)
5722         (match_dup 2))]
5724   operands[3] = gen_rtx_REG (SImode, REGNO (operands[0]));
5726   [(set_attr "length" "4,4,8")
5727    (set_attr "type" "fp")])
5729 (define_insn "*fix<uns>_trunc<SFDF:mode>si2_p8"
5730   [(set (match_operand:SI 0 "gpc_reg_operand" "=d,wa")
5731         (any_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d,wa")))]
5732   "TARGET_DIRECT_MOVE"
5733   "@
5734    fctiw<u>z %0,%1
5735    xscvdp<su>xws %x0,%x1"
5736   [(set_attr "type" "fp")])
5738 ;; Keep the convert and store together through register allocation to prevent
5739 ;; the register allocator from getting clever and doing a direct move to a GPR
5740 ;; and then store for reg+offset stores.
5741 (define_insn_and_split "*fix<uns>_trunc<SFDF:mode><QHSI:mode>2_mem"
5742   [(set (match_operand:QHSI 0 "memory_operand" "=Z")
5743         (any_fix:QHSI (match_operand:SFDF 1 "gpc_reg_operand" "wa")))
5744    (clobber (match_scratch:SI 2 "=wa"))]
5745     "(<QHSI:MODE>mode == SImode && TARGET_P8_VECTOR) || TARGET_P9_VECTOR"
5746   "#"
5747   "&& reload_completed"
5748   [(set (match_dup 2)
5749         (any_fix:SI (match_dup 1)))
5750    (set (match_dup 0)
5751         (match_dup 3))]
5753   operands[3] = (<QHSI:MODE>mode == SImode
5754                  ? operands[2]
5755                  : gen_rtx_REG (<QHSI:MODE>mode, REGNO (operands[2])));
5758 (define_expand "fixuns_trunc<mode>si2"
5759   [(set (match_operand:SI 0 "gpc_reg_operand")
5760         (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand")))]
5761   "TARGET_HARD_FLOAT && TARGET_FCTIWUZ && TARGET_STFIWX"
5763   if (!TARGET_P8_VECTOR)
5764     {
5765       emit_insn (gen_fixuns_trunc<mode>si2_stfiwx (operands[0], operands[1]));
5766       DONE;
5767     }
5770 (define_insn_and_split "fixuns_trunc<mode>si2_stfiwx"
5771   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5772         (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
5773    (clobber (match_scratch:DI 2 "=d"))]
5774   "TARGET_HARD_FLOAT && TARGET_FCTIWUZ
5775    && TARGET_STFIWX && can_create_pseudo_p ()
5776    && !TARGET_P8_VECTOR"
5777   "#"
5778   ""
5779   [(pc)]
5781   rtx dest = operands[0];
5782   rtx src = operands[1];
5783   rtx tmp = operands[2];
5785   if (GET_CODE (tmp) == SCRATCH)
5786     tmp = gen_reg_rtx (DImode);
5788   emit_insn (gen_fctiwuz_<mode> (tmp, src));
5789   if (MEM_P (dest))
5790     {
5791       dest = rs6000_force_indexed_or_indirect_mem (dest);
5792       emit_insn (gen_stfiwx (dest, tmp));
5793       DONE;
5794     }
5795   else if (TARGET_POWERPC64 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5796     {
5797       dest = gen_lowpart (DImode, dest);
5798       emit_move_insn (dest, tmp);
5799       DONE;
5800     }
5801   else
5802     {
5803       rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5804       emit_insn (gen_stfiwx (stack, tmp));
5805       emit_move_insn (dest, stack);
5806       DONE;
5807     }
5809   [(set_attr "length" "12")
5810    (set_attr "type" "fp")])
5812 (define_insn "fixuns_trunc<mode>di2"
5813   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5814         (unsigned_fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
5815   "TARGET_HARD_FLOAT && TARGET_FCTIDUZ"
5816   "@
5817    fctiduz %0,%1
5818    xscvdpuxds %x0,%x1"
5819   [(set_attr "type" "fp")])
5821 (define_insn "rs6000_mtfsb0"
5822   [(unspec_volatile [(match_operand:SI 0 "u5bit_cint_operand" "n")]
5823                     UNSPECV_MTFSB0)]
5824   "TARGET_HARD_FLOAT"
5825   "mtfsb0 %0"
5826   [(set_attr "type" "fp")])
5828 (define_insn "rs6000_mtfsb1"
5829   [(unspec_volatile [(match_operand:SI 0 "u5bit_cint_operand" "n")]
5830                     UNSPECV_MTFSB1)]
5831   "TARGET_HARD_FLOAT"
5832   "mtfsb1 %0"
5833   [(set_attr "type" "fp")])
5835 (define_insn "rs6000_mffscrn"
5836   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
5837         (unspec_volatile:DF [(match_operand:DF 1 "gpc_reg_operand" "d")]
5838                             UNSPECV_MFFSCRN))]
5839    "TARGET_P9_MISC"
5840    "mffscrn %0,%1"
5841   [(set_attr "type" "fp")])
5843 (define_insn "rs6000_mffscdrn"
5844   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
5845    (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFSCDRN))
5846    (use (match_operand:DF 1 "gpc_reg_operand" "d"))]
5847   "TARGET_P9_MISC"
5848   "mffscdrn %0,%1"
5849   [(set_attr "type" "fp")])
5851 (define_expand "rs6000_set_fpscr_rn"
5852  [(match_operand:DI 0 "reg_or_cint_operand")]
5853   "TARGET_HARD_FLOAT"
5855   rtx tmp_df = gen_reg_rtx (DFmode);
5857   /* The floating point rounding control bits are FPSCR[62:63]. Put the
5858      new rounding mode bits from operands[0][62:63] into FPSCR[62:63].  */
5859   if (TARGET_P9_MISC)
5860     {
5861       rtx src_df = force_reg (DImode, operands[0]);
5862       src_df = simplify_gen_subreg (DFmode, src_df, DImode, 0);
5863       emit_insn (gen_rs6000_mffscrn (tmp_df, src_df));
5864       DONE;
5865     }
5867   if (CONST_INT_P (operands[0]))
5868     {
5869       if ((INTVAL (operands[0]) & 0x1) == 0x1)
5870         emit_insn (gen_rs6000_mtfsb1 (GEN_INT (31)));
5871       else
5872         emit_insn (gen_rs6000_mtfsb0 (GEN_INT (31)));
5874       if ((INTVAL (operands[0]) & 0x2) == 0x2)
5875         emit_insn (gen_rs6000_mtfsb1 (GEN_INT (30)));
5876       else
5877         emit_insn (gen_rs6000_mtfsb0 (GEN_INT (30)));
5878     }
5879   else
5880     {
5881       rtx tmp_rn = gen_reg_rtx (DImode);
5882       rtx tmp_di = gen_reg_rtx (DImode);
5884       /* Extract new RN mode from operand.  */
5885       emit_insn (gen_anddi3 (tmp_rn, operands[0], GEN_INT (0x3)));
5887       /* Insert new RN mode into FSCPR.  */
5888       emit_insn (gen_rs6000_mffs (tmp_df));
5889       tmp_di = simplify_gen_subreg (DImode, tmp_df, DFmode, 0);
5890       emit_insn (gen_anddi3 (tmp_di, tmp_di, GEN_INT (-4)));
5891       emit_insn (gen_iordi3 (tmp_di, tmp_di, tmp_rn));
5893       /* Need to write to field k=15.  The fields are [0:15].  Hence with
5894          L=0, W=0, FLM_i must be equal to 8, 16 = i + 8*(1-W).  FLM is an
5895          8-bit field[0:7]. Need to set the bit that corresponds to the
5896          value of i that you want [0:7].  */
5897       tmp_df = simplify_gen_subreg (DFmode, tmp_di, DImode, 0);
5898       emit_insn (gen_rs6000_mtfsf (GEN_INT (0x01), tmp_df));
5899     }
5900   DONE;
5903 (define_expand "rs6000_set_fpscr_drn"
5904   [(match_operand:DI 0  "gpc_reg_operand")]
5905   "TARGET_HARD_FLOAT"
5907   rtx tmp_df = gen_reg_rtx (DFmode);
5909   /* The decimal floating point rounding control bits are FPSCR[29:31]. Put the
5910      new rounding mode bits from operands[0][61:63] into FPSCR[29:31].  */
5911   if (TARGET_P9_MISC)
5912     {
5913       rtx src_df = gen_reg_rtx (DFmode);
5915       emit_insn (gen_ashldi3 (operands[0], operands[0], GEN_INT (32)));
5916       src_df = simplify_gen_subreg (DFmode, operands[0], DImode, 0);
5917       emit_insn (gen_rs6000_mffscdrn (tmp_df, src_df));
5918     }
5919   else
5920     {
5921       rtx tmp_rn = gen_reg_rtx (DImode);
5922       rtx tmp_di = gen_reg_rtx (DImode);
5924       /* Extract new DRN mode from operand.  */
5925       emit_insn (gen_anddi3 (tmp_rn, operands[0], GEN_INT (0x7)));
5926       emit_insn (gen_ashldi3 (tmp_rn, tmp_rn, GEN_INT (32)));
5928       /* Insert new RN mode into FSCPR.  */
5929       emit_insn (gen_rs6000_mffs (tmp_df));
5930       tmp_di = simplify_gen_subreg (DImode, tmp_df, DFmode, 0);
5931       emit_insn (gen_anddi3 (tmp_di, tmp_di, GEN_INT (0xFFFFFFF8FFFFFFFF)));
5932       emit_insn (gen_iordi3 (tmp_di, tmp_di, tmp_rn));
5934       /* Need to write to field 7.  The fields are [0:15].  The equation to
5935          select the field is i + 8*(1-W). Hence with L=0 and W=1, need to set
5936          i to 0x1 to get field 7 where i selects the field.  */
5937       tmp_df = simplify_gen_subreg (DFmode, tmp_di, DImode, 0);
5938       emit_insn (gen_rs6000_mtfsf_hi (GEN_INT (0x01), tmp_df));
5939     }
5940   DONE;
5943 ;; Here, we use (set (reg) (unspec:DI [(fix:SI ...)] UNSPEC_FCTIWZ))
5944 ;; rather than (set (subreg:SI (reg)) (fix:SI ...))
5945 ;; because the first makes it clear that operand 0 is not live
5946 ;; before the instruction.
5947 (define_insn "fctiwz_<mode>"
5948   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5949         (unspec:DI [(fix:SI
5950                      (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
5951                    UNSPEC_FCTIWZ))]
5952   "TARGET_HARD_FLOAT"
5953   "@
5954    fctiwz %0,%1
5955    xscvdpsxws %x0,%x1"
5956   [(set_attr "type" "fp")])
5958 (define_insn "fctiwuz_<mode>"
5959   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5960         (unspec:DI [(unsigned_fix:SI
5961                      (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
5962                    UNSPEC_FCTIWUZ))]
5963   "TARGET_HARD_FLOAT && TARGET_FCTIWUZ"
5964   "@
5965    fctiwuz %0,%1
5966    xscvdpuxws %x0,%x1"
5967   [(set_attr "type" "fp")])
5969 ;; Only optimize (float (fix x)) -> frz if we are in fast-math mode, since
5970 ;; since the friz instruction does not truncate the value if the floating
5971 ;; point value is < LONG_MIN or > LONG_MAX.
5972 (define_insn "*friz"
5973   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
5974         (float:DF (fix:DI (match_operand:DF 1 "gpc_reg_operand" "d,ws"))))]
5975   "TARGET_HARD_FLOAT && TARGET_FPRND
5976    && flag_unsafe_math_optimizations && !flag_trapping_math && TARGET_FRIZ"
5977   "@
5978    friz %0,%1
5979    xsrdpiz %x0,%x1"
5980   [(set_attr "type" "fp")])
5982 ;; Opitmize converting SF/DFmode to signed SImode and back to SF/DFmode.  This
5983 ;; optimization prevents on ISA 2.06 systems and earlier having to store the
5984 ;; value from the FPR/vector unit to the stack, load the value into a GPR, sign
5985 ;; extend it, store it back on the stack from the GPR, load it back into the
5986 ;; FP/vector unit to do the rounding. If we have direct move (ISA 2.07),
5987 ;; disable using store and load to sign/zero extend the value.
5988 (define_insn_and_split "*round32<mode>2_fprs"
5989   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
5990         (float:SFDF
5991          (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
5992    (clobber (match_scratch:DI 2 "=d"))
5993    (clobber (match_scratch:DI 3 "=d"))]
5994   "TARGET_HARD_FLOAT
5995    && <SI_CONVERT_FP> && TARGET_LFIWAX && TARGET_STFIWX && TARGET_FCFID
5996    && !TARGET_DIRECT_MOVE && can_create_pseudo_p ()"
5997   "#"
5998   ""
5999   [(pc)]
6001   rtx dest = operands[0];
6002   rtx src = operands[1];
6003   rtx tmp1 = operands[2];
6004   rtx tmp2 = operands[3];
6005   rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
6007   if (GET_CODE (tmp1) == SCRATCH)
6008     tmp1 = gen_reg_rtx (DImode);
6009   if (GET_CODE (tmp2) == SCRATCH)
6010     tmp2 = gen_reg_rtx (DImode);
6012   emit_insn (gen_fctiwz_<mode> (tmp1, src));
6013   emit_insn (gen_stfiwx (stack, tmp1));
6014   emit_insn (gen_lfiwax (tmp2, stack));
6015   emit_insn (gen_floatdi<mode>2 (dest, tmp2));
6016   DONE;
6018   [(set_attr "type" "fpload")
6019    (set_attr "length" "16")])
6021 (define_insn_and_split "*roundu32<mode>2_fprs"
6022   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
6023         (unsigned_float:SFDF
6024          (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
6025    (clobber (match_scratch:DI 2 "=d"))
6026    (clobber (match_scratch:DI 3 "=d"))]
6027   "TARGET_HARD_FLOAT
6028    && TARGET_LFIWZX && TARGET_STFIWX && TARGET_FCFIDU && !TARGET_DIRECT_MOVE
6029    && can_create_pseudo_p ()"
6030   "#"
6031   ""
6032   [(pc)]
6034   rtx dest = operands[0];
6035   rtx src = operands[1];
6036   rtx tmp1 = operands[2];
6037   rtx tmp2 = operands[3];
6038   rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
6040   if (GET_CODE (tmp1) == SCRATCH)
6041     tmp1 = gen_reg_rtx (DImode);
6042   if (GET_CODE (tmp2) == SCRATCH)
6043     tmp2 = gen_reg_rtx (DImode);
6045   emit_insn (gen_fctiwuz_<mode> (tmp1, src));
6046   emit_insn (gen_stfiwx (stack, tmp1));
6047   emit_insn (gen_lfiwzx (tmp2, stack));
6048   emit_insn (gen_floatdi<mode>2 (dest, tmp2));
6049   DONE;
6051   [(set_attr "type" "fpload")
6052    (set_attr "length" "16")])
6054 ;; No VSX equivalent to fctid
6055 (define_insn "lrint<mode>di2"
6056   [(set (match_operand:DI 0 "gpc_reg_operand" "=d")
6057         (unspec:DI [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
6058                    UNSPEC_FCTID))]
6059   "TARGET_HARD_FLOAT && TARGET_FPRND"
6060   "fctid %0,%1"
6061   [(set_attr "type" "fp")])
6063 (define_insn "btrunc<mode>2"
6064   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
6065         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
6066                      UNSPEC_FRIZ))]
6067   "TARGET_HARD_FLOAT && TARGET_FPRND"
6068   "@
6069    friz %0,%1
6070    xsrdpiz %x0,%x1"
6071   [(set_attr "type" "fp")])
6073 (define_insn "ceil<mode>2"
6074   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
6075         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
6076                      UNSPEC_FRIP))]
6077   "TARGET_HARD_FLOAT && TARGET_FPRND"
6078   "@
6079    frip %0,%1
6080    xsrdpip %x0,%x1"
6081   [(set_attr "type" "fp")])
6083 (define_insn "floor<mode>2"
6084   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
6085         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
6086                      UNSPEC_FRIM))]
6087   "TARGET_HARD_FLOAT && TARGET_FPRND"
6088   "@
6089    frim %0,%1
6090    xsrdpim %x0,%x1"
6091   [(set_attr "type" "fp")])
6093 ;; No VSX equivalent to frin
6094 (define_insn "round<mode>2"
6095   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<rreg2>")
6096         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
6097                      UNSPEC_FRIN))]
6098   "TARGET_HARD_FLOAT && TARGET_FPRND"
6099   "frin %0,%1"
6100   [(set_attr "type" "fp")])
6102 (define_insn "*xsrdpi<mode>2"
6103   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
6104         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Fv>")]
6105                      UNSPEC_XSRDPI))]
6106   "TARGET_HARD_FLOAT && TARGET_VSX"
6107   "xsrdpi %x0,%x1"
6108   [(set_attr "type" "fp")])
6110 (define_expand "lround<mode>di2"
6111   [(set (match_dup 2)
6112         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand")]
6113                      UNSPEC_XSRDPI))
6114    (set (match_operand:DI 0 "gpc_reg_operand")
6115         (unspec:DI [(match_dup 2)]
6116                    UNSPEC_FCTID))]
6117   "TARGET_HARD_FLOAT && TARGET_VSX && TARGET_FPRND"
6119   operands[2] = gen_reg_rtx (<MODE>mode);
6122 ; An UNSPEC is used so we don't have to support SImode in FP registers.
6123 ; The 'wu' constraint is used for the 2nd alternative to ensure stxsiwx
6124 ; is only generated for Power8 or later.
6125 (define_insn "stfiwx"
6126   [(set (match_operand:SI 0 "memory_operand" "=Z,Z")
6127         (unspec:SI [(match_operand:DI 1 "gpc_reg_operand" "d,wu")]
6128                    UNSPEC_STFIWX))]
6129   "TARGET_PPC_GFXOPT"
6130   "@
6131    stfiwx %1,%y0
6132    stxsiwx %x1,%y0"
6133   [(set_attr "type" "fpstore")])
6135 ;; If we don't have a direct conversion to single precision, don't enable this
6136 ;; conversion for 32-bit without fast math, because we don't have the insn to
6137 ;; generate the fixup swizzle to avoid double rounding problems.
6138 (define_expand "floatsisf2"
6139   [(set (match_operand:SF 0 "gpc_reg_operand")
6140         (float:SF (match_operand:SI 1 "nonimmediate_operand")))]
6141   "TARGET_HARD_FLOAT
6142    && ((TARGET_FCFIDS && TARGET_LFIWAX)
6143        || (TARGET_FCFID
6144            && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))"
6146   if (TARGET_FCFIDS && TARGET_LFIWAX)
6147     {
6148       emit_insn (gen_floatsisf2_lfiwax (operands[0], operands[1]));
6149       DONE;
6150     }
6151   else if (TARGET_FCFID && TARGET_LFIWAX)
6152     {
6153       rtx dfreg = gen_reg_rtx (DFmode);
6154       emit_insn (gen_floatsidf2_lfiwax (dfreg, operands[1]));
6155       emit_insn (gen_truncdfsf2 (operands[0], dfreg));
6156       DONE;
6157     }
6158   else
6159     {
6160       rtx dreg = operands[1];
6161       if (!REG_P (dreg))
6162         dreg = force_reg (SImode, dreg);
6163       dreg = convert_to_mode (DImode, dreg, false);
6164       emit_insn (gen_floatdisf2 (operands[0], dreg));
6165       DONE;
6166     }
6169 (define_insn "floatdidf2"
6170   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
6171         (float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
6172   "TARGET_FCFID && TARGET_HARD_FLOAT"
6173   "@
6174    fcfid %0,%1
6175    xscvsxddp %x0,%x1"
6176   [(set_attr "type" "fp")])
6178 ; Allow the combiner to merge source memory operands to the conversion so that
6179 ; the optimizer/register allocator doesn't try to load the value too early in a
6180 ; GPR and then use store/load to move it to a FPR and suffer from a store-load
6181 ; hit.  We will split after reload to avoid the trip through the GPRs
6183 (define_insn_and_split "*floatdidf2_mem"
6184   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
6185         (float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
6186    (clobber (match_scratch:DI 2 "=d,wi"))]
6187   "TARGET_HARD_FLOAT && TARGET_FCFID"
6188   "#"
6189   "&& reload_completed"
6190   [(set (match_dup 2) (match_dup 1))
6191    (set (match_dup 0) (float:DF (match_dup 2)))]
6192   ""
6193   [(set_attr "length" "8")
6194    (set_attr "type" "fpload")])
6196 (define_expand "floatunsdidf2"
6197   [(set (match_operand:DF 0 "gpc_reg_operand")
6198         (unsigned_float:DF
6199          (match_operand:DI 1 "gpc_reg_operand")))]
6200   "TARGET_HARD_FLOAT && TARGET_FCFIDU"
6201   "")
6203 (define_insn "*floatunsdidf2_fcfidu"
6204   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
6205         (unsigned_float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
6206   "TARGET_HARD_FLOAT && TARGET_FCFIDU"
6207   "@
6208    fcfidu %0,%1
6209    xscvuxddp %x0,%x1"
6210   [(set_attr "type" "fp")])
6212 (define_insn_and_split "*floatunsdidf2_mem"
6213   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
6214         (unsigned_float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
6215    (clobber (match_scratch:DI 2 "=d,wi"))]
6216   "TARGET_HARD_FLOAT && (TARGET_FCFIDU || VECTOR_UNIT_VSX_P (DFmode))"
6217   "#"
6218   "&& reload_completed"
6219   [(set (match_dup 2) (match_dup 1))
6220    (set (match_dup 0) (unsigned_float:DF (match_dup 2)))]
6221   ""
6222   [(set_attr "length" "8")
6223    (set_attr "type" "fpload")])
6225 (define_expand "floatdisf2"
6226   [(set (match_operand:SF 0 "gpc_reg_operand")
6227         (float:SF (match_operand:DI 1 "gpc_reg_operand")))]
6228   "TARGET_FCFID && TARGET_HARD_FLOAT
6229    && (TARGET_FCFIDS || TARGET_POWERPC64 || flag_unsafe_math_optimizations)"
6231   if (!TARGET_FCFIDS)
6232     {
6233       rtx val = operands[1];
6234       if (!flag_unsafe_math_optimizations)
6235         {
6236           rtx label = gen_label_rtx ();
6237           val = gen_reg_rtx (DImode);
6238           emit_insn (gen_floatdisf2_internal2 (val, operands[1], label));
6239           emit_label (label);
6240         }
6241       emit_insn (gen_floatdisf2_internal1 (operands[0], val));
6242       DONE;
6243     }
6246 (define_insn "floatdisf2_fcfids"
6247   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy")
6248         (float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
6249   "TARGET_HARD_FLOAT && TARGET_FCFIDS"
6250   "@
6251    fcfids %0,%1
6252    xscvsxdsp %x0,%x1"
6253   [(set_attr "type" "fp")])
6255 (define_insn_and_split "*floatdisf2_mem"
6256   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy,wy")
6257         (float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
6258    (clobber (match_scratch:DI 2 "=d,d,wi"))]
6259   "TARGET_HARD_FLOAT && TARGET_FCFIDS"
6260   "#"
6261   "&& reload_completed"
6262   [(pc)]
6264   emit_move_insn (operands[2], operands[1]);
6265   emit_insn (gen_floatdisf2_fcfids (operands[0], operands[2]));
6266   DONE;
6268   [(set_attr "length" "8")])
6270 ;; This is not IEEE compliant if rounding mode is "round to nearest".
6271 ;; If the DI->DF conversion is inexact, then it's possible to suffer
6272 ;; from double rounding.
6273 ;; Instead of creating a new cpu type for two FP operations, just use fp
6274 (define_insn_and_split "floatdisf2_internal1"
6275   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
6276         (float:SF (match_operand:DI 1 "gpc_reg_operand" "d")))
6277    (clobber (match_scratch:DF 2 "=d"))]
6278   "TARGET_FCFID && TARGET_HARD_FLOAT && !TARGET_FCFIDS"
6279   "#"
6280   "&& reload_completed"
6281   [(set (match_dup 2)
6282         (float:DF (match_dup 1)))
6283    (set (match_dup 0)
6284         (float_truncate:SF (match_dup 2)))]
6285   ""
6286   [(set_attr "length" "8")
6287    (set_attr "type" "fp")])
6289 ;; Twiddles bits to avoid double rounding.
6290 ;; Bits that might be truncated when converting to DFmode are replaced
6291 ;; by a bit that won't be lost at that stage, but is below the SFmode
6292 ;; rounding position.
6293 (define_expand "floatdisf2_internal2"
6294   [(parallel [(set (match_dup 3) (ashiftrt:DI (match_operand:DI 1 "")
6295                                               (const_int 53)))
6296               (clobber (reg:DI CA_REGNO))])
6297    (set (match_operand:DI 0 "") (and:DI (match_dup 1)
6298                                         (const_int 2047)))
6299    (set (match_dup 3) (plus:DI (match_dup 3)
6300                                (const_int 1)))
6301    (set (match_dup 0) (plus:DI (match_dup 0)
6302                                (const_int 2047)))
6303    (set (match_dup 4) (compare:CCUNS (match_dup 3)
6304                                      (const_int 2)))
6305    (set (match_dup 0) (ior:DI (match_dup 0)
6306                               (match_dup 1)))
6307    (set (match_dup 0) (and:DI (match_dup 0)
6308                               (const_int -2048)))
6309    (set (pc) (if_then_else (geu (match_dup 4) (const_int 0))
6310                            (label_ref (match_operand:DI 2 ""))
6311                            (pc)))
6312    (set (match_dup 0) (match_dup 1))]
6313   "TARGET_POWERPC64 && TARGET_HARD_FLOAT && !TARGET_FCFIDS"
6315   operands[3] = gen_reg_rtx (DImode);
6316   operands[4] = gen_reg_rtx (CCUNSmode);
6319 (define_expand "floatunsdisf2"
6320   [(set (match_operand:SF 0 "gpc_reg_operand")
6321         (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand")))]
6322   "TARGET_HARD_FLOAT && TARGET_FCFIDUS"
6323   "")
6325 (define_insn "floatunsdisf2_fcfidus"
6326   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wu")
6327         (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
6328   "TARGET_HARD_FLOAT && TARGET_FCFIDUS"
6329   "@
6330    fcfidus %0,%1
6331    xscvuxdsp %x0,%x1"
6332   [(set_attr "type" "fp")])
6334 (define_insn_and_split "*floatunsdisf2_mem"
6335   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy,wy")
6336         (unsigned_float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
6337    (clobber (match_scratch:DI 2 "=d,d,wi"))]
6338   "TARGET_HARD_FLOAT && TARGET_FCFIDUS"
6339   "#"
6340   "&& reload_completed"
6341   [(pc)]
6343   emit_move_insn (operands[2], operands[1]);
6344   emit_insn (gen_floatunsdisf2_fcfidus (operands[0], operands[2]));
6345   DONE;
6347   [(set_attr "length" "8")
6348    (set_attr "type" "fpload")])
6350 ;; Define the TImode operations that can be done in a small number
6351 ;; of instructions.  The & constraints are to prevent the register
6352 ;; allocator from allocating registers that overlap with the inputs
6353 ;; (for example, having an input in 7,8 and an output in 6,7).  We
6354 ;; also allow for the output being the same as one of the inputs.
6356 (define_expand "addti3"
6357   [(set (match_operand:TI 0 "gpc_reg_operand")
6358         (plus:TI (match_operand:TI 1 "gpc_reg_operand")
6359                  (match_operand:TI 2 "reg_or_short_operand")))]
6360   "TARGET_64BIT"
6362   rtx lo0 = gen_lowpart (DImode, operands[0]);
6363   rtx lo1 = gen_lowpart (DImode, operands[1]);
6364   rtx lo2 = gen_lowpart (DImode, operands[2]);
6365   rtx hi0 = gen_highpart (DImode, operands[0]);
6366   rtx hi1 = gen_highpart (DImode, operands[1]);
6367   rtx hi2 = gen_highpart_mode (DImode, TImode, operands[2]);
6369   if (!reg_or_short_operand (lo2, DImode))
6370     lo2 = force_reg (DImode, lo2);
6371   if (!adde_operand (hi2, DImode))
6372     hi2 = force_reg (DImode, hi2);
6374   emit_insn (gen_adddi3_carry (lo0, lo1, lo2));
6375   emit_insn (gen_adddi3_carry_in (hi0, hi1, hi2));
6376   DONE;
6379 (define_expand "subti3"
6380   [(set (match_operand:TI 0 "gpc_reg_operand")
6381         (minus:TI (match_operand:TI 1 "reg_or_short_operand")
6382                   (match_operand:TI 2 "gpc_reg_operand")))]
6383   "TARGET_64BIT"
6385   rtx lo0 = gen_lowpart (DImode, operands[0]);
6386   rtx lo1 = gen_lowpart (DImode, operands[1]);
6387   rtx lo2 = gen_lowpart (DImode, operands[2]);
6388   rtx hi0 = gen_highpart (DImode, operands[0]);
6389   rtx hi1 = gen_highpart_mode (DImode, TImode, operands[1]);
6390   rtx hi2 = gen_highpart (DImode, operands[2]);
6392   if (!reg_or_short_operand (lo1, DImode))
6393     lo1 = force_reg (DImode, lo1);
6394   if (!adde_operand (hi1, DImode))
6395     hi1 = force_reg (DImode, hi1);
6397   emit_insn (gen_subfdi3_carry (lo0, lo2, lo1));
6398   emit_insn (gen_subfdi3_carry_in (hi0, hi2, hi1));
6399   DONE;
6402 ;; 128-bit logical operations expanders
6404 (define_expand "and<mode>3"
6405   [(set (match_operand:BOOL_128 0 "vlogical_operand")
6406         (and:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")
6407                       (match_operand:BOOL_128 2 "vlogical_operand")))]
6408   ""
6409   "")
6411 (define_expand "ior<mode>3"
6412   [(set (match_operand:BOOL_128 0 "vlogical_operand")
6413         (ior:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")
6414                       (match_operand:BOOL_128 2 "vlogical_operand")))]
6415   ""
6416   "")
6418 (define_expand "xor<mode>3"
6419   [(set (match_operand:BOOL_128 0 "vlogical_operand")
6420         (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")
6421                       (match_operand:BOOL_128 2 "vlogical_operand")))]
6422   ""
6423   "")
6425 (define_expand "one_cmpl<mode>2"
6426   [(set (match_operand:BOOL_128 0 "vlogical_operand")
6427         (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")))]
6428   ""
6429   "")
6431 (define_expand "nor<mode>3"
6432   [(set (match_operand:BOOL_128 0 "vlogical_operand")
6433         (and:BOOL_128
6434          (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand"))
6435          (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))))]
6436   ""
6437   "")
6439 (define_expand "andc<mode>3"
6440   [(set (match_operand:BOOL_128 0 "vlogical_operand")
6441         (and:BOOL_128
6442          (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))
6443          (match_operand:BOOL_128 1 "vlogical_operand")))]
6444   ""
6445   "")
6447 ;; Power8 vector logical instructions.
6448 (define_expand "eqv<mode>3"
6449   [(set (match_operand:BOOL_128 0 "vlogical_operand")
6450         (not:BOOL_128
6451          (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")
6452                        (match_operand:BOOL_128 2 "vlogical_operand"))))]
6453   "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6454   "")
6456 ;; Rewrite nand into canonical form
6457 (define_expand "nand<mode>3"
6458   [(set (match_operand:BOOL_128 0 "vlogical_operand")
6459         (ior:BOOL_128
6460          (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand"))
6461          (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))))]
6462   "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6463   "")
6465 ;; The canonical form is to have the negated element first, so we need to
6466 ;; reverse arguments.
6467 (define_expand "orc<mode>3"
6468   [(set (match_operand:BOOL_128 0 "vlogical_operand")
6469         (ior:BOOL_128
6470          (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))
6471          (match_operand:BOOL_128 1 "vlogical_operand")))]
6472   "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6473   "")
6475 ;; 128-bit logical operations insns and split operations
6476 (define_insn_and_split "*and<mode>3_internal"
6477   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6478         (and:BOOL_128
6479          (match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
6480          (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")))]
6481   ""
6483   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6484     return "xxland %x0,%x1,%x2";
6486   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6487     return "vand %0,%1,%2";
6489   return "#";
6491   "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6492   [(const_int 0)]
6494   rs6000_split_logical (operands, AND, false, false, false);
6495   DONE;
6497   [(set (attr "type")
6498       (if_then_else
6499         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6500         (const_string "veclogical")
6501         (const_string "integer")))
6502    (set (attr "length")
6503       (if_then_else
6504         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6505         (const_string "4")
6506         (if_then_else
6507          (match_test "TARGET_POWERPC64")
6508          (const_string "8")
6509          (const_string "16"))))])
6511 ;; 128-bit IOR/XOR
6512 (define_insn_and_split "*bool<mode>3_internal"
6513   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6514         (match_operator:BOOL_128 3 "boolean_or_operator"
6515          [(match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
6516           (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")]))]
6517   ""
6519   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6520     return "xxl%q3 %x0,%x1,%x2";
6522   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6523     return "v%q3 %0,%1,%2";
6525   return "#";
6527   "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6528   [(const_int 0)]
6530   rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, false);
6531   DONE;
6533   [(set (attr "type")
6534       (if_then_else
6535         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6536         (const_string "veclogical")
6537         (const_string "integer")))
6538    (set (attr "length")
6539       (if_then_else
6540         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6541         (const_string "4")
6542         (if_then_else
6543          (match_test "TARGET_POWERPC64")
6544          (const_string "8")
6545          (const_string "16"))))])
6547 ;; 128-bit ANDC/ORC
6548 (define_insn_and_split "*boolc<mode>3_internal1"
6549   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6550         (match_operator:BOOL_128 3 "boolean_operator"
6551          [(not:BOOL_128
6552            (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))
6553           (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")]))]
6554   "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
6556   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6557     return "xxl%q3 %x0,%x1,%x2";
6559   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6560     return "v%q3 %0,%1,%2";
6562   return "#";
6564   "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
6565    && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6566   [(const_int 0)]
6568   rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
6569   DONE;
6571   [(set (attr "type")
6572       (if_then_else
6573         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6574         (const_string "veclogical")
6575         (const_string "integer")))
6576    (set (attr "length")
6577       (if_then_else
6578         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6579         (const_string "4")
6580         (if_then_else
6581          (match_test "TARGET_POWERPC64")
6582          (const_string "8")
6583          (const_string "16"))))])
6585 (define_insn_and_split "*boolc<mode>3_internal2"
6586   [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6587         (match_operator:TI2 3 "boolean_operator"
6588          [(not:TI2
6589            (match_operand:TI2 2 "int_reg_operand" "r,0,r"))
6590           (match_operand:TI2 1 "int_reg_operand" "r,r,0")]))]
6591   "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6592   "#"
6593   "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6594   [(const_int 0)]
6596   rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
6597   DONE;
6599   [(set_attr "type" "integer")
6600    (set (attr "length")
6601         (if_then_else
6602          (match_test "TARGET_POWERPC64")
6603          (const_string "8")
6604          (const_string "16")))])
6606 ;; 128-bit NAND/NOR
6607 (define_insn_and_split "*boolcc<mode>3_internal1"
6608   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6609         (match_operator:BOOL_128 3 "boolean_operator"
6610          [(not:BOOL_128
6611            (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>"))
6612           (not:BOOL_128
6613            (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))]))]
6614   "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
6616   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6617     return "xxl%q3 %x0,%x1,%x2";
6619   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6620     return "v%q3 %0,%1,%2";
6622   return "#";
6624   "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
6625    && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6626   [(const_int 0)]
6628   rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
6629   DONE;
6631   [(set (attr "type")
6632       (if_then_else
6633         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6634         (const_string "veclogical")
6635         (const_string "integer")))
6636    (set (attr "length")
6637       (if_then_else
6638         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6639         (const_string "4")
6640         (if_then_else
6641          (match_test "TARGET_POWERPC64")
6642          (const_string "8")
6643          (const_string "16"))))])
6645 (define_insn_and_split "*boolcc<mode>3_internal2"
6646   [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6647         (match_operator:TI2 3 "boolean_operator"
6648          [(not:TI2
6649            (match_operand:TI2 1 "int_reg_operand" "r,0,r"))
6650           (not:TI2
6651            (match_operand:TI2 2 "int_reg_operand" "r,r,0"))]))]
6652   "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6653   "#"
6654   "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6655   [(const_int 0)]
6657   rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
6658   DONE;
6660   [(set_attr "type" "integer")
6661    (set (attr "length")
6662         (if_then_else
6663          (match_test "TARGET_POWERPC64")
6664          (const_string "8")
6665          (const_string "16")))])
6668 ;; 128-bit EQV
6669 (define_insn_and_split "*eqv<mode>3_internal1"
6670   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6671         (not:BOOL_128
6672          (xor:BOOL_128
6673           (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")
6674           (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))))]
6675   "TARGET_P8_VECTOR"
6677   if (vsx_register_operand (operands[0], <MODE>mode))
6678     return "xxleqv %x0,%x1,%x2";
6680   return "#";
6682   "TARGET_P8_VECTOR && reload_completed
6683    && int_reg_operand (operands[0], <MODE>mode)"
6684   [(const_int 0)]
6686   rs6000_split_logical (operands, XOR, true, false, false);
6687   DONE;
6689   [(set (attr "type")
6690       (if_then_else
6691         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6692         (const_string "veclogical")
6693         (const_string "integer")))
6694    (set (attr "length")
6695       (if_then_else
6696         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6697         (const_string "4")
6698         (if_then_else
6699          (match_test "TARGET_POWERPC64")
6700          (const_string "8")
6701          (const_string "16"))))])
6703 (define_insn_and_split "*eqv<mode>3_internal2"
6704   [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6705         (not:TI2
6706          (xor:TI2
6707           (match_operand:TI2 1 "int_reg_operand" "r,0,r")
6708           (match_operand:TI2 2 "int_reg_operand" "r,r,0"))))]
6709   "!TARGET_P8_VECTOR"
6710   "#"
6711   "reload_completed && !TARGET_P8_VECTOR"
6712   [(const_int 0)]
6714   rs6000_split_logical (operands, XOR, true, false, false);
6715   DONE;
6717   [(set_attr "type" "integer")
6718    (set (attr "length")
6719         (if_then_else
6720          (match_test "TARGET_POWERPC64")
6721          (const_string "8")
6722          (const_string "16")))])
6724 ;; 128-bit one's complement
6725 (define_insn_and_split "*one_cmpl<mode>3_internal"
6726   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6727         (not:BOOL_128
6728           (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_UNARY>")))]
6729   ""
6731   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6732     return "xxlnor %x0,%x1,%x1";
6734   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6735     return "vnor %0,%1,%1";
6737   return "#";
6739   "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6740   [(const_int 0)]
6742   rs6000_split_logical (operands, NOT, false, false, false);
6743   DONE;
6745   [(set (attr "type")
6746       (if_then_else
6747         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6748         (const_string "veclogical")
6749         (const_string "integer")))
6750    (set (attr "length")
6751       (if_then_else
6752         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6753         (const_string "4")
6754         (if_then_else
6755          (match_test "TARGET_POWERPC64")
6756          (const_string "8")
6757          (const_string "16"))))])
6760 ;; Now define ways of moving data around.
6762 ;; Set up a register with a value from the GOT table
6764 (define_expand "movsi_got"
6765   [(set (match_operand:SI 0 "gpc_reg_operand")
6766         (unspec:SI [(match_operand:SI 1 "got_operand")
6767                     (match_dup 2)] UNSPEC_MOVSI_GOT))]
6768   "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
6770   if (GET_CODE (operands[1]) == CONST)
6771     {
6772       rtx offset = const0_rtx;
6773       HOST_WIDE_INT value;
6775       operands[1] = eliminate_constant_term (XEXP (operands[1], 0), &offset);
6776       value = INTVAL (offset);
6777       if (value != 0)
6778         {
6779           rtx tmp = (!can_create_pseudo_p ()
6780                      ? operands[0]
6781                      : gen_reg_rtx (Pmode));
6782           emit_insn (gen_movsi_got (tmp, operands[1]));
6783           emit_insn (gen_addsi3 (operands[0], tmp, offset));
6784           DONE;
6785         }
6786     }
6788   operands[2] = rs6000_got_register (operands[1]);
6791 (define_insn "*movsi_got_internal"
6792   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6793         (unspec:SI [(match_operand:SI 1 "got_no_const_operand" "")
6794                     (match_operand:SI 2 "gpc_reg_operand" "b")]
6795                    UNSPEC_MOVSI_GOT))]
6796   "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
6797   "lwz %0,%a1@got(%2)"
6798   [(set_attr "type" "load")])
6800 ;; Used by sched, shorten_branches and final when the GOT pseudo reg
6801 ;; didn't get allocated to a hard register.
6802 (define_split
6803   [(set (match_operand:SI 0 "gpc_reg_operand")
6804         (unspec:SI [(match_operand:SI 1 "got_no_const_operand")
6805                     (match_operand:SI 2 "memory_operand")]
6806                    UNSPEC_MOVSI_GOT))]
6807   "DEFAULT_ABI == ABI_V4
6808     && flag_pic == 1
6809     && reload_completed"
6810   [(set (match_dup 0) (match_dup 2))
6811    (set (match_dup 0) (unspec:SI [(match_dup 1)(match_dup 0)]
6812                                  UNSPEC_MOVSI_GOT))]
6813   "")
6815 ;; For SI, we special-case integers that can't be loaded in one insn.  We
6816 ;; do the load 16-bits at a time.  We could do this by loading from memory,
6817 ;; and this is even supposed to be faster, but it is simpler not to get
6818 ;; integers in the TOC.
6819 (define_insn "movsi_low"
6820   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6821         (mem:SI (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
6822                            (match_operand 2 "" ""))))]
6823   "TARGET_MACHO && ! TARGET_64BIT"
6824   "lwz %0,lo16(%2)(%1)"
6825   [(set_attr "type" "load")])
6827 ;;              MR           LA           LWZ          LFIWZX       LXSIWZX
6828 ;;              STW          STFIWX       STXSIWX      LI           LIS
6829 ;;              #            XXLOR        XXSPLTIB 0   XXSPLTIB -1  VSPLTISW
6830 ;;              XXLXOR 0     XXLORC -1    P9 const     MTVSRWZ      MFVSRWZ
6831 ;;              MF%1         MT%0         NOP
6832 (define_insn "*movsi_internal1"
6833   [(set (match_operand:SI 0 "nonimmediate_operand"
6834                 "=r,         r,           r,           ?*wI,        ?*wH,
6835                  m,          ?Z,          ?Z,          r,           r,
6836                  r,          ?*wIwH,      ?*wJwK,      ?*wJwK,      ?*wu,
6837                  ?*wJwK,     ?*wH,        ?*wK,        ?*wIwH,      ?r,
6838                  r,          *h,          *h")
6840         (match_operand:SI 1 "input_operand"
6841                 "r,          U,           m,           Z,           Z,
6842                  r,          wI,          wH,          I,           L,
6843                  n,          wIwH,        O,           wM,          wB,
6844                  O,          wM,          wS,          r,           wIwH,
6845                  *h,         r,           0"))]
6847   "gpc_reg_operand (operands[0], SImode)
6848    || gpc_reg_operand (operands[1], SImode)"
6849   "@
6850    mr %0,%1
6851    la %0,%a1
6852    lwz%U1%X1 %0,%1
6853    lfiwzx %0,%y1
6854    lxsiwzx %x0,%y1
6855    stw%U0%X0 %1,%0
6856    stfiwx %1,%y0
6857    stxsiwx %x1,%y0
6858    li %0,%1
6859    lis %0,%v1
6860    #
6861    xxlor %x0,%x1,%x1
6862    xxspltib %x0,0
6863    xxspltib %x0,255
6864    vspltisw %0,%1
6865    xxlxor %x0,%x0,%x0
6866    xxlorc %x0,%x0,%x0
6867    #
6868    mtvsrwz %x0,%1
6869    mfvsrwz %0,%x1
6870    mf%1 %0
6871    mt%0 %1
6872    nop"
6873   [(set_attr "type"
6874                 "*,          *,           load,        fpload,      fpload,
6875                  store,      fpstore,     fpstore,     *,           *,
6876                  *,          veclogical,  vecsimple,   vecsimple,   vecsimple,
6877                  veclogical, veclogical,  vecsimple,   mffgpr,      mftgpr,
6878                  *,          *,           *")
6880    (set_attr "length"
6881                 "4,          4,           4,           4,           4,
6882                  4,          4,           4,           4,           4,
6883                  8,          4,           4,           4,           4,
6884                  4,          4,           8,           4,           4,
6885                  4,          4,           4")])
6887 ;; Like movsi, but adjust a SF value to be used in a SI context, i.e.
6888 ;; (set (reg:SI ...) (subreg:SI (reg:SF ...) 0))
6890 ;; Because SF values are actually stored as DF values within the vector
6891 ;; registers, we need to convert the value to the vector SF format when
6892 ;; we need to use the bits in a union or similar cases.  We only need
6893 ;; to do this transformation when the value is a vector register.  Loads,
6894 ;; stores, and transfers within GPRs are assumed to be safe.
6896 ;; This is a more general case of reload_gpr_from_vsxsf.  That insn must have
6897 ;; no alternatives, because the call is created as part of secondary_reload,
6898 ;; and operand #2's register class is used to allocate the temporary register.
6899 ;; This function is called before reload, and it creates the temporary as
6900 ;; needed.
6902 ;;              MR           LWZ          LFIWZX       LXSIWZX   STW
6903 ;;              STFS         STXSSP       STXSSPX      VSX->GPR  VSX->VSX
6904 ;;              MTVSRWZ
6906 (define_insn_and_split "movsi_from_sf"
6907   [(set (match_operand:SI 0 "nonimmediate_operand"
6908                 "=r,         r,           ?*wI,        ?*wH,     m,
6909                  m,          wY,          Z,           r,        ?*wIwH,
6910                  wIwH")
6912         (unspec:SI [(match_operand:SF 1 "input_operand"
6913                 "r,          m,           Z,           Z,        r,
6914                  f,          wb,          wu,          wIwH,     wIwH,
6915                  r")]
6916                     UNSPEC_SI_FROM_SF))
6918    (clobber (match_scratch:V4SF 2
6919                 "=X,         X,           X,           X,        X,
6920                  X,          X,           X,           wIwH,     X,
6921                  X"))]
6923   "TARGET_NO_SF_SUBREG
6924    && (register_operand (operands[0], SImode)
6925        || register_operand (operands[1], SFmode))"
6926   "@
6927    mr %0,%1
6928    lwz%U1%X1 %0,%1
6929    lfiwzx %0,%y1
6930    lxsiwzx %x0,%y1
6931    stw%U0%X0 %1,%0
6932    stfs%U0%X0 %1,%0
6933    stxssp %1,%0
6934    stxsspx %x1,%y0
6935    #
6936    xscvdpspn %x0,%x1
6937    mtvsrwz %x0,%1"
6938   "&& reload_completed
6939    && int_reg_operand (operands[0], SImode)
6940    && vsx_reg_sfsubreg_ok (operands[1], SFmode)"
6941   [(const_int 0)]
6943   rtx op0 = operands[0];
6944   rtx op1 = operands[1];
6945   rtx op2 = operands[2];
6946   rtx op0_di = gen_rtx_REG (DImode, reg_or_subregno (op0));
6947   rtx op2_si = gen_rtx_REG (SImode, reg_or_subregno (op2));
6949   emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
6950   emit_insn (gen_zero_extendsidi2 (op0_di, op2_si));
6951   DONE;
6953   [(set_attr "type"
6954                 "*,          load,        fpload,      fpload,   store,
6955                  fpstore,    fpstore,     fpstore,     mftgpr,   fp,
6956                  mffgpr")
6958    (set_attr "length"
6959                 "4,          4,           4,           4,        4,
6960                  4,          4,           4,           8,        4,
6961                  4")])
6963 ;; movsi_from_sf with zero extension
6965 ;;              RLDICL       LWZ          LFIWZX       LXSIWZX   VSX->GPR
6966 ;;              VSX->VSX     MTVSRWZ
6968 (define_insn_and_split "*movdi_from_sf_zero_ext"
6969   [(set (match_operand:DI 0 "gpc_reg_operand"
6970                 "=r,         r,           ?*wI,        ?*wH,     r,
6971                  ?wK,        wIwH")
6973         (zero_extend:DI
6974          (unspec:SI [(match_operand:SF 1 "input_operand"
6975                 "r,          m,           Z,           Z,        wIwH,
6976                  wIwH,       r")]
6977                     UNSPEC_SI_FROM_SF)))
6979    (clobber (match_scratch:V4SF 2
6980                 "=X,         X,           X,           X,        wa,
6981                  wIwH,       X"))]
6983   "TARGET_DIRECT_MOVE_64BIT
6984    && (register_operand (operands[0], DImode)
6985        || register_operand (operands[1], SImode))"
6986   "@
6987    rldicl %0,%1,0,32
6988    lwz%U1%X1 %0,%1
6989    lfiwzx %0,%y1
6990    lxsiwzx %x0,%y1
6991    #
6992    #
6993    mtvsrwz %x0,%1"
6994   "&& reload_completed
6995    && register_operand (operands[0], DImode)
6996    && vsx_reg_sfsubreg_ok (operands[1], SFmode)"
6997   [(const_int 0)]
6999   rtx op0 = operands[0];
7000   rtx op1 = operands[1];
7001   rtx op2 = operands[2];
7002   rtx op2_si = gen_rtx_REG (SImode, reg_or_subregno (op2));
7004   emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
7005   emit_insn (gen_zero_extendsidi2 (op0, op2_si));
7006   DONE;
7008   [(set_attr "type"
7009                 "*,          load,        fpload,      fpload,   two,
7010                  two,        mffgpr")
7012    (set_attr "length"
7013                 "4,          4,           4,           4,        8,
7014                  8,          4")])
7016 ;; Like movsi_from_sf, but combine a convert from DFmode to SFmode before
7017 ;; moving it to SImode.  We cannot do a SFmode store without having to do the
7018 ;; conversion explicitly since that doesn't work in most cases if the input
7019 ;; isn't representable as SF.  Use XSCVDPSP instead of XSCVDPSPN, since the
7020 ;; former handles cases where the input will not fit in a SFmode, and the
7021 ;; latter assumes the value has already been rounded.
7022 (define_insn "*movsi_from_df"
7023   [(set (match_operand:SI 0 "gpc_reg_operand" "=wa")
7024         (unspec:SI [(float_truncate:SF
7025                      (match_operand:DF 1 "gpc_reg_operand" "wa"))]
7026                     UNSPEC_SI_FROM_SF))]
7027   "TARGET_NO_SF_SUBREG"
7028   "xscvdpsp %x0,%x1"
7029   [(set_attr "type" "fp")])
7031 ;; Split a load of a large constant into the appropriate two-insn
7032 ;; sequence.
7034 (define_split
7035   [(set (match_operand:SI 0 "gpc_reg_operand")
7036         (match_operand:SI 1 "const_int_operand"))]
7037   "(unsigned HOST_WIDE_INT) (INTVAL (operands[1]) + 0x8000) >= 0x10000
7038    && (INTVAL (operands[1]) & 0xffff) != 0"
7039   [(set (match_dup 0)
7040         (match_dup 2))
7041    (set (match_dup 0)
7042         (ior:SI (match_dup 0)
7043                 (match_dup 3)))]
7045   if (rs6000_emit_set_const (operands[0], operands[1]))
7046     DONE;
7047   else
7048     FAIL;
7051 ;; Split loading -128..127 to use XXSPLITB and VEXTSW2D
7052 (define_split
7053   [(set (match_operand:DI 0 "altivec_register_operand")
7054         (match_operand:DI 1 "xxspltib_constant_split"))]
7055   "TARGET_P9_VECTOR && reload_completed"
7056   [(const_int 0)]
7058   rtx op0 = operands[0];
7059   rtx op1 = operands[1];
7060   int r = REGNO (op0);
7061   rtx op0_v16qi = gen_rtx_REG (V16QImode, r);
7063   emit_insn (gen_xxspltib_v16qi (op0_v16qi, op1));
7064   emit_insn (gen_vsx_sign_extend_qi_si (operands[0], op0_v16qi));
7065   DONE;
7068 (define_insn "*mov<mode>_internal2"
7069   [(set (match_operand:CC 2 "cc_reg_operand" "=y,x,?y")
7070         (compare:CC (match_operand:P 1 "gpc_reg_operand" "0,r,r")
7071                     (const_int 0)))
7072    (set (match_operand:P 0 "gpc_reg_operand" "=r,r,r") (match_dup 1))]
7073   ""
7074   "@
7075    cmp<wd>i %2,%0,0
7076    mr. %0,%1
7077    #"
7078   [(set_attr "type" "cmp,logical,cmp")
7079    (set_attr "dot" "yes")
7080    (set_attr "length" "4,4,8")])
7082 (define_split
7083   [(set (match_operand:CC 2 "cc_reg_not_cr0_operand")
7084         (compare:CC (match_operand:P 1 "gpc_reg_operand")
7085                     (const_int 0)))
7086    (set (match_operand:P 0 "gpc_reg_operand") (match_dup 1))]
7087   "reload_completed"
7088   [(set (match_dup 0) (match_dup 1))
7089    (set (match_dup 2)
7090         (compare:CC (match_dup 0)
7091                     (const_int 0)))]
7092   "")
7094 (define_expand "mov<mode>"
7095   [(set (match_operand:INT 0 "general_operand")
7096         (match_operand:INT 1 "any_operand"))]
7097   ""
7099   rs6000_emit_move (operands[0], operands[1], <MODE>mode);
7100   DONE;
7103 ;;              MR          LHZ/LBZ    LXSI*ZX    STH/STB    STXSI*X    LI
7104 ;;              XXLOR       load 0     load -1    VSPLTI*    #          MFVSRWZ
7105 ;;              MTVSRWZ     MF%1       MT%1       NOP
7106 (define_insn "*mov<mode>_internal"
7107   [(set (match_operand:QHI 0 "nonimmediate_operand"
7108                 "=r,        r,         ?*wJwK,    m,         Z,         r,
7109                  ?*wJwK,    ?*wJwK,    ?*wJwK,    ?*wK,      ?*wK,      r,
7110                  ?*wJwK,    r,         *c*l,      *h")
7112         (match_operand:QHI 1 "input_operand"
7113                 "r,         m,         Z,         r,         wJwK,      i,
7114                  wJwK,      O,         wM,        wB,        wS,        ?*wJwK,
7115                  r,         *h,        r,         0"))]
7117   "gpc_reg_operand (operands[0], <MODE>mode)
7118    || gpc_reg_operand (operands[1], <MODE>mode)"
7119   "@
7120    mr %0,%1
7121    l<wd>z%U1%X1 %0,%1
7122    lxsi<wd>zx %x0,%y1
7123    st<wd>%U0%X0 %1,%0
7124    stxsi<wd>x %x1,%y0
7125    li %0,%1
7126    xxlor %x0,%x1,%x1
7127    xxspltib %x0,0
7128    xxspltib %x0,255
7129    vspltis<wd> %0,%1
7130    #
7131    mfvsrwz %0,%x1
7132    mtvsrwz %x0,%1
7133    mf%1 %0
7134    mt%0 %1
7135    nop"
7136   [(set_attr "type"
7137                 "*,         load,      fpload,    store,     fpstore,   *,
7138                  vecsimple, vecperm,   vecperm,   vecperm,   vecperm,   mftgpr,
7139                  mffgpr,    mfjmpr,    mtjmpr,    *")
7141    (set_attr "length"
7142                 "4,         4,         4,         4,         4,         4,
7143                  4,         4,         4,         4,         8,         4,
7144                  4,         4,         4,         4")])
7147 ;; Here is how to move condition codes around.  When we store CC data in
7148 ;; an integer register or memory, we store just the high-order 4 bits.
7149 ;; This lets us not shift in the most common case of CR0.
7150 (define_expand "movcc"
7151   [(set (match_operand:CC 0 "nonimmediate_operand")
7152         (match_operand:CC 1 "nonimmediate_operand"))]
7153   ""
7154   "")
7156 (define_insn "*movcc_internal1"
7157   [(set (match_operand:CC 0 "nonimmediate_operand"
7158                             "=y,x,?y,y,r,r,r,r, r,*c*l,r,m")
7159         (match_operand:CC 1 "general_operand"
7160                             " y,r, r,O,x,y,r,I,*h,   r,m,r"))]
7161   "register_operand (operands[0], CCmode)
7162    || register_operand (operands[1], CCmode)"
7163   "@
7164    mcrf %0,%1
7165    mtcrf 128,%1
7166    rlwinm %1,%1,%F0,0xffffffff\;mtcrf %R0,%1\;rlwinm %1,%1,%f0,0xffffffff
7167    crxor %0,%0,%0
7168    mfcr %0%Q1
7169    mfcr %0%Q1\;rlwinm %0,%0,%f1,0xf0000000
7170    mr %0,%1
7171    li %0,%1
7172    mf%1 %0
7173    mt%0 %1
7174    lwz%U1%X1 %0,%1
7175    stw%U0%X0 %1,%0"
7176   [(set_attr_alternative "type"
7177      [(const_string "cr_logical")
7178       (const_string "mtcr")
7179       (const_string "mtcr")
7180       (const_string "cr_logical")
7181       (if_then_else (match_test "TARGET_MFCRF")
7182                     (const_string "mfcrf") (const_string "mfcr"))
7183       (if_then_else (match_test "TARGET_MFCRF")
7184                     (const_string "mfcrf") (const_string "mfcr"))
7185       (const_string "integer")
7186       (const_string "integer")
7187       (const_string "mfjmpr")
7188       (const_string "mtjmpr")
7189       (const_string "load")
7190       (const_string "store")])
7191    (set_attr "length" "4,4,12,4,4,8,4,4,4,4,4,4")])
7193 ;; For floating-point, we normally deal with the floating-point registers
7194 ;; unless -msoft-float is used.  The sole exception is that parameter passing
7195 ;; can produce floating-point values in fixed-point registers.  Unless the
7196 ;; value is a simple constant or already in memory, we deal with this by
7197 ;; allocating memory and copying the value explicitly via that memory location.
7199 ;; Move 32-bit binary/decimal floating point
7200 (define_expand "mov<mode>"
7201   [(set (match_operand:FMOVE32 0 "nonimmediate_operand")
7202         (match_operand:FMOVE32 1 "any_operand"))]
7203   "<fmove_ok>"
7205   rs6000_emit_move (operands[0], operands[1], <MODE>mode);
7206   DONE;
7209 (define_split
7210   [(set (match_operand:FMOVE32 0 "gpc_reg_operand")
7211         (match_operand:FMOVE32 1 "const_double_operand"))]
7212   "reload_completed
7213    && ((REG_P (operands[0]) && REGNO (operands[0]) <= 31)
7214        || (SUBREG_P (operands[0])
7215            && REG_P (SUBREG_REG (operands[0]))
7216            && REGNO (SUBREG_REG (operands[0])) <= 31))"
7217   [(set (match_dup 2) (match_dup 3))]
7219   long l;
7221   <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7223   if (! TARGET_POWERPC64)
7224     operands[2] = operand_subword (operands[0], 0, 0, <MODE>mode);
7225   else
7226     operands[2] = gen_lowpart (SImode, operands[0]);
7228   operands[3] = gen_int_mode (l, SImode);
7231 ;; Originally, we tried to keep movsf and movsd common, but the differences
7232 ;; addressing was making it rather difficult to hide with mode attributes.  In
7233 ;; particular for SFmode, on ISA 2.07 (power8) systems, having the GPR store
7234 ;; before the VSX stores meant that the register allocator would tend to do a
7235 ;; direct move to the GPR (which involves conversion from scalar to
7236 ;; vector/memory formats) to save values in the traditional Altivec registers,
7237 ;; while SDmode had problems on power6 if the GPR store was not first due to
7238 ;; the power6 not having an integer store operation.
7240 ;;      LWZ          LFS        LXSSP       LXSSPX     STFS       STXSSP
7241 ;;      STXSSPX      STW        XXLXOR      LI         FMR        XSCPSGNDP
7242 ;;      MR           MT<x>      MF<x>       NOP
7244 (define_insn "movsf_hardfloat"
7245   [(set (match_operand:SF 0 "nonimmediate_operand"
7246          "=!r,       f,         wb,         wu,        m,         wY,
7247           Z,         m,         ww,         !r,        f,         ww,
7248           !r,        *c*l,      !r,         *h")
7249         (match_operand:SF 1 "input_operand"
7250          "m,         m,         wY,         Z,         f,         wb,
7251           wu,        r,         j,          j,         f,         ww,
7252           r,         r,         *h,         0"))]
7253   "(register_operand (operands[0], SFmode)
7254    || register_operand (operands[1], SFmode))
7255    && TARGET_HARD_FLOAT
7256    && (TARGET_ALLOW_SF_SUBREG
7257        || valid_sf_si_move (operands[0], operands[1], SFmode))"
7258   "@
7259    lwz%U1%X1 %0,%1
7260    lfs%U1%X1 %0,%1
7261    lxssp %0,%1
7262    lxsspx %x0,%y1
7263    stfs%U0%X0 %1,%0
7264    stxssp %1,%0
7265    stxsspx %x1,%y0
7266    stw%U0%X0 %1,%0
7267    xxlxor %x0,%x0,%x0
7268    li %0,0
7269    fmr %0,%1
7270    xscpsgndp %x0,%x1,%x1
7271    mr %0,%1
7272    mt%0 %1
7273    mf%1 %0
7274    nop"
7275   [(set_attr "type"
7276         "load,       fpload,    fpload,     fpload,    fpstore,   fpstore,
7277          fpstore,    store,     veclogical, integer,   fpsimple,  fpsimple,
7278          *,          mtjmpr,    mfjmpr,     *")])
7280 ;;      LWZ          LFIWZX     STW        STFIWX     MTVSRWZ    MFVSRWZ
7281 ;;      FMR          MR         MT%0       MF%1       NOP
7282 (define_insn "movsd_hardfloat"
7283   [(set (match_operand:SD 0 "nonimmediate_operand"
7284          "=!r,       wz,        m,         Z,         ?wh,       ?r,
7285           f,         !r,        *c*l,      !r,        *h")
7286         (match_operand:SD 1 "input_operand"
7287          "m,         Z,         r,         wx,        r,         wh,
7288           f,         r,         r,         *h,        0"))]
7289   "(register_operand (operands[0], SDmode)
7290    || register_operand (operands[1], SDmode))
7291    && TARGET_HARD_FLOAT"
7292   "@
7293    lwz%U1%X1 %0,%1
7294    lfiwzx %0,%y1
7295    stw%U0%X0 %1,%0
7296    stfiwx %1,%y0
7297    mtvsrwz %x0,%1
7298    mfvsrwz %0,%x1
7299    fmr %0,%1
7300    mr %0,%1
7301    mt%0 %1
7302    mf%1 %0
7303    nop"
7304   [(set_attr "type"
7305         "load,       fpload,    store,     fpstore,   mffgpr,    mftgpr,
7306          fpsimple,   *,         mtjmpr,    mfjmpr,    *")])
7308 ;;      MR           MT%0       MF%0       LWZ        STW        LI
7309 ;;      LIS          G-const.   F/n-const  NOP
7310 (define_insn "*mov<mode>_softfloat"
7311   [(set (match_operand:FMOVE32 0 "nonimmediate_operand"
7312         "=r,         *c*l,      r,         r,         m,         r,
7313           r,         r,         r,         *h")
7315         (match_operand:FMOVE32 1 "input_operand"
7316          "r,         r,         *h,        m,         r,         I,
7317           L,         G,         Fn,        0"))]
7319   "(gpc_reg_operand (operands[0], <MODE>mode)
7320    || gpc_reg_operand (operands[1], <MODE>mode))
7321    && TARGET_SOFT_FLOAT"
7322   "@
7323    mr %0,%1
7324    mt%0 %1
7325    mf%1 %0
7326    lwz%U1%X1 %0,%1
7327    stw%U0%X0 %1,%0
7328    li %0,%1
7329    lis %0,%v1
7330    #
7331    #
7332    nop"
7333   [(set_attr "type"
7334         "*,          mtjmpr,    mfjmpr,    load,      store,     *,
7335          *,          *,         *,         *")
7337    (set_attr "length"
7338         "4,          4,         4,         4,         4,         4,
7339          4,          4,         8,         4")])
7341 ;; Like movsf, but adjust a SI value to be used in a SF context, i.e.
7342 ;; (set (reg:SF ...) (subreg:SF (reg:SI ...) 0))
7344 ;; Because SF values are actually stored as DF values within the vector
7345 ;; registers, we need to convert the value to the vector SF format when
7346 ;; we need to use the bits in a union or similar cases.  We only need
7347 ;; to do this transformation when the value is a vector register.  Loads,
7348 ;; stores, and transfers within GPRs are assumed to be safe.
7350 ;; This is a more general case of reload_vsx_from_gprsf.  That insn must have
7351 ;; no alternatives, because the call is created as part of secondary_reload,
7352 ;; and operand #2's register class is used to allocate the temporary register.
7353 ;; This function is called before reload, and it creates the temporary as
7354 ;; needed.
7356 ;;          LWZ          LFS        LXSSP      LXSSPX     STW        STFIWX
7357 ;;          STXSIWX      GPR->VSX   VSX->GPR   GPR->GPR
7358 (define_insn_and_split "movsf_from_si"
7359   [(set (match_operand:SF 0 "nonimmediate_operand"
7360             "=!r,       f,         wb,        wu,        m,         Z,
7361              Z,         wy,        ?r,        !r")
7363         (unspec:SF [(match_operand:SI 1 "input_operand" 
7364             "m,         m,         wY,        Z,         r,         f,
7365              wu,        r,         wy,        r")]
7366                    UNSPEC_SF_FROM_SI))
7368    (clobber (match_scratch:DI 2
7369             "=X,        X,         X,         X,         X,         X,
7370              X,         r,         X,         X"))]
7372   "TARGET_NO_SF_SUBREG
7373    && (register_operand (operands[0], SFmode)
7374        || register_operand (operands[1], SImode))"
7375   "@
7376    lwz%U1%X1 %0,%1
7377    lfs%U1%X1 %0,%1
7378    lxssp %0,%1
7379    lxsspx %x0,%y1
7380    stw%U0%X0 %1,%0
7381    stfiwx %1,%y0
7382    stxsiwx %x1,%y0
7383    #
7384    mfvsrwz %0,%x1
7385    mr %0,%1"
7387   "&& reload_completed
7388    && vsx_reg_sfsubreg_ok (operands[0], SFmode)
7389    && int_reg_operand_not_pseudo (operands[1], SImode)"
7390   [(const_int 0)]
7392   rtx op0 = operands[0];
7393   rtx op1 = operands[1];
7394   rtx op2 = operands[2];
7395   rtx op1_di = gen_rtx_REG (DImode, REGNO (op1));
7397   /* Move SF value to upper 32-bits for xscvspdpn.  */
7398   emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32)));
7399   emit_insn (gen_p8_mtvsrd_sf (op0, op2));
7400   emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0));
7401   DONE;
7403   [(set_attr "length"
7404             "4,          4,         4,         4,         4,         4,
7405              4,          12,        4,         4")
7406    (set_attr "type"
7407             "load,       fpload,    fpload,    fpload,    store,     fpstore,
7408              fpstore,    vecfloat,  mffgpr,    *")])
7411 ;; Move 64-bit binary/decimal floating point
7412 (define_expand "mov<mode>"
7413   [(set (match_operand:FMOVE64 0 "nonimmediate_operand")
7414         (match_operand:FMOVE64 1 "any_operand"))]
7415   ""
7417   rs6000_emit_move (operands[0], operands[1], <MODE>mode);
7418   DONE;
7421 (define_split
7422   [(set (match_operand:FMOVE64 0 "gpc_reg_operand")
7423         (match_operand:FMOVE64 1 "const_int_operand"))]
7424   "! TARGET_POWERPC64 && reload_completed
7425    && ((REG_P (operands[0]) && REGNO (operands[0]) <= 31)
7426        || (SUBREG_P (operands[0])
7427            && REG_P (SUBREG_REG (operands[0]))
7428            && REGNO (SUBREG_REG (operands[0])) <= 31))"
7429   [(set (match_dup 2) (match_dup 4))
7430    (set (match_dup 3) (match_dup 1))]
7432   int endian = (WORDS_BIG_ENDIAN == 0);
7433   HOST_WIDE_INT value = INTVAL (operands[1]);
7435   operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
7436   operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
7437   operands[4] = GEN_INT (value >> 32);
7438   operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
7441 (define_split
7442   [(set (match_operand:FMOVE64 0 "gpc_reg_operand")
7443         (match_operand:FMOVE64 1 "const_double_operand"))]
7444   "! TARGET_POWERPC64 && reload_completed
7445    && ((REG_P (operands[0]) && REGNO (operands[0]) <= 31)
7446        || (SUBREG_P (operands[0])
7447            && REG_P (SUBREG_REG (operands[0]))
7448            && REGNO (SUBREG_REG (operands[0])) <= 31))"
7449   [(set (match_dup 2) (match_dup 4))
7450    (set (match_dup 3) (match_dup 5))]
7452   int endian = (WORDS_BIG_ENDIAN == 0);
7453   long l[2];
7455   <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7457   operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
7458   operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
7459   operands[4] = gen_int_mode (l[endian], SImode);
7460   operands[5] = gen_int_mode (l[1 - endian], SImode);
7463 (define_split
7464   [(set (match_operand:FMOVE64 0 "gpc_reg_operand")
7465         (match_operand:FMOVE64 1 "const_double_operand"))]
7466   "TARGET_POWERPC64 && reload_completed
7467    && ((REG_P (operands[0]) && REGNO (operands[0]) <= 31)
7468        || (SUBREG_P (operands[0])
7469            && REG_P (SUBREG_REG (operands[0]))
7470            && REGNO (SUBREG_REG (operands[0])) <= 31))"
7471   [(set (match_dup 2) (match_dup 3))]
7473   int endian = (WORDS_BIG_ENDIAN == 0);
7474   long l[2];
7475   HOST_WIDE_INT val;
7477   <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7479   operands[2] = gen_lowpart (DImode, operands[0]);
7480   /* HIGHPART is lower memory address when WORDS_BIG_ENDIAN.  */
7481   val = ((HOST_WIDE_INT)(unsigned long)l[endian] << 32
7482          | ((HOST_WIDE_INT)(unsigned long)l[1 - endian]));
7484   operands[3] = gen_int_mode (val, DImode);
7487 ;; Don't have reload use general registers to load a constant.  It is
7488 ;; less efficient than loading the constant into an FP register, since
7489 ;; it will probably be used there.
7491 ;; The move constraints are ordered to prefer floating point registers before
7492 ;; general purpose registers to avoid doing a store and a load to get the value
7493 ;; into a floating point register when it is needed for a floating point
7494 ;; operation.  Prefer traditional floating point registers over VSX registers,
7495 ;; since the D-form version of the memory instructions does not need a GPR for
7496 ;; reloading.  ISA 3.0 (power9) adds D-form addressing for scalars to Altivec
7497 ;; registers.
7499 ;; If we have FPR registers, rs6000_emit_move has moved all constants to memory,
7500 ;; except for 0.0 which can be created on VSX with an xor instruction.
7502 ;;           STFD         LFD         FMR         LXSD        STXSD
7503 ;;           LXSD         STXSD       XXLOR       XXLXOR      GPR<-0
7504 ;;           LWZ          STW         MR
7507 (define_insn "*mov<mode>_hardfloat32"
7508   [(set (match_operand:FMOVE64 0 "nonimmediate_operand"
7509             "=m,          d,          d,          <f64_p9>,   wY,
7510               <f64_av>,   Z,          <f64_vsx>,  <f64_vsx>,  !r,
7511               Y,          r,          !r")
7513         (match_operand:FMOVE64 1 "input_operand"
7514              "d,          m,          d,          wY,         <f64_p9>,
7515               Z,          <f64_av>,   <f64_vsx>,  <zero_fp>,  <zero_fp>,
7516               r,          Y,          r"))]
7518   "! TARGET_POWERPC64 && TARGET_HARD_FLOAT
7519    && (gpc_reg_operand (operands[0], <MODE>mode)
7520        || gpc_reg_operand (operands[1], <MODE>mode))"
7521   "@
7522    stfd%U0%X0 %1,%0
7523    lfd%U1%X1 %0,%1
7524    fmr %0,%1
7525    lxsd %0,%1
7526    stxsd %1,%0
7527    lxsdx %x0,%y1
7528    stxsdx %x1,%y0
7529    xxlor %x0,%x1,%x1
7530    xxlxor %x0,%x0,%x0
7531    #
7532    #
7533    #
7534    #"
7535   [(set_attr "type"
7536             "fpstore,     fpload,     fpsimple,   fpload,     fpstore,
7537              fpload,      fpstore,    veclogical, veclogical, two,
7538              store,       load,       two")
7540    (set_attr "size" "64")
7541    (set_attr "length"
7542             "4,           4,          4,          4,          4,
7543              4,           4,          4,          4,          8,
7544              8,           8,          8")])
7546 ;;           STW      LWZ     MR      G-const H-const F-const
7548 (define_insn "*mov<mode>_softfloat32"
7549   [(set (match_operand:FMOVE64 0 "nonimmediate_operand"
7550            "=Y,       r,      r,      r,      r,      r")
7552         (match_operand:FMOVE64 1 "input_operand"
7553             "r,       Y,      r,      G,      H,      F"))]
7555   "!TARGET_POWERPC64
7556    && (gpc_reg_operand (operands[0], <MODE>mode)
7557        || gpc_reg_operand (operands[1], <MODE>mode))"
7558   "#"
7559   [(set_attr "type"
7560             "store,   load,   two,    *,      *,      *")
7562    (set_attr "length"
7563              "8,      8,      8,      8,      12,     16")])
7565 ; ld/std require word-aligned displacements -> 'Y' constraint.
7566 ; List Y->r and r->Y before r->r for reload.
7568 ;;           STFD         LFD         FMR         LXSD        STXSD
7569 ;;           LXSDX        STXSDX      XXLOR       XXLXOR      LI 0
7570 ;;           STD          LD          MR          MT{CTR,LR}  MF{CTR,LR}
7571 ;;           NOP          MFTGPR      MFFGPR      MFVSRD      MTVSRD
7573 (define_insn "*mov<mode>_hardfloat64"
7574   [(set (match_operand:FMOVE64 0 "nonimmediate_operand"
7575            "=m,           d,          d,          <f64_p9>,   wY,
7576              <f64_av>,    Z,          <f64_vsx>,  <f64_vsx>,  !r,
7577              YZ,          r,          !r,         *c*l,       !r,
7578             *h,           r,          wg,         r,          <f64_dm>")
7580         (match_operand:FMOVE64 1 "input_operand"
7581             "d,           m,          d,          wY,         <f64_p9>,
7582              Z,           <f64_av>,   <f64_vsx>,  <zero_fp>,  <zero_fp>,
7583              r,           YZ,         r,          r,          *h,
7584              0,           wg,         r,          <f64_dm>,   r"))]
7586   "TARGET_POWERPC64 && TARGET_HARD_FLOAT
7587    && (gpc_reg_operand (operands[0], <MODE>mode)
7588        || gpc_reg_operand (operands[1], <MODE>mode))"
7589   "@
7590    stfd%U0%X0 %1,%0
7591    lfd%U1%X1 %0,%1
7592    fmr %0,%1
7593    lxsd %0,%1
7594    stxsd %1,%0
7595    lxsdx %x0,%y1
7596    stxsdx %x1,%y0
7597    xxlor %x0,%x1,%x1
7598    xxlxor %x0,%x0,%x0
7599    li %0,0
7600    std%U0%X0 %1,%0
7601    ld%U1%X1 %0,%1
7602    mr %0,%1
7603    mt%0 %1
7604    mf%1 %0
7605    nop
7606    mftgpr %0,%1
7607    mffgpr %0,%1
7608    mfvsrd %0,%x1
7609    mtvsrd %x0,%1"
7610   [(set_attr "type"
7611             "fpstore,     fpload,     fpsimple,   fpload,     fpstore,
7612              fpload,      fpstore,    veclogical, veclogical, integer,
7613              store,       load,       *,          mtjmpr,     mfjmpr,
7614              *,           mftgpr,     mffgpr,     mftgpr,    mffgpr")
7616    (set_attr "size" "64")
7617    (set_attr "length" "4")])
7619 ;;           STD      LD       MR      MT<SPR> MF<SPR> G-const
7620 ;;           H-const  F-const  Special
7622 (define_insn "*mov<mode>_softfloat64"
7623   [(set (match_operand:FMOVE64 0 "nonimmediate_operand"
7624            "=Y,       r,      r,      *c*l,   r,      r,
7625              r,       r,      *h")
7627         (match_operand:FMOVE64 1 "input_operand"
7628             "r,       Y,      r,      r,      *h,     G,
7629              H,       F,      0"))]
7631   "TARGET_POWERPC64 && TARGET_SOFT_FLOAT
7632    && (gpc_reg_operand (operands[0], <MODE>mode)
7633        || gpc_reg_operand (operands[1], <MODE>mode))"
7634   "@
7635    std%U0%X0 %1,%0
7636    ld%U1%X1 %0,%1
7637    mr %0,%1
7638    mt%0 %1
7639    mf%1 %0
7640    #
7641    #
7642    #
7643    nop"
7644   [(set_attr "type"
7645             "store,   load,   *,      mtjmpr, mfjmpr, *,
7646              *,       *,      *")
7648    (set_attr "length"
7649             "4,       4,      4,      4,      4,      8,
7650              12,      16,     4")])
7652 (define_expand "mov<mode>"
7653   [(set (match_operand:FMOVE128 0 "general_operand")
7654         (match_operand:FMOVE128 1 "any_operand"))]
7655   ""
7657   rs6000_emit_move (operands[0], operands[1], <MODE>mode);
7658   DONE;
7661 ;; It's important to list Y->r and r->Y before r->r because otherwise
7662 ;; reload, given m->r, will try to pick r->r and reload it, which
7663 ;; doesn't make progress.
7665 ;; We can't split little endian direct moves of TDmode, because the words are
7666 ;; not swapped like they are for TImode or TFmode.  Subregs therefore are
7667 ;; problematical.  Don't allow direct move for this case.
7669 (define_insn_and_split "*mov<mode>_64bit_dm"
7670   [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand" "=m,d,d,d,Y,r,r,r,wh")
7671         (match_operand:FMOVE128_FPR 1 "input_operand" "d,m,d,<zero_fp>,r,<zero_fp>Y,r,wh,r"))]
7672   "TARGET_HARD_FLOAT && TARGET_POWERPC64 && FLOAT128_2REG_P (<MODE>mode)
7673    && (<MODE>mode != TDmode || WORDS_BIG_ENDIAN)
7674    && (gpc_reg_operand (operands[0], <MODE>mode)
7675        || gpc_reg_operand (operands[1], <MODE>mode))"
7676   "#"
7677   "&& reload_completed"
7678   [(pc)]
7679 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7680   [(set_attr "length" "8,8,8,8,12,12,8,8,8")])
7682 (define_insn_and_split "*movtd_64bit_nodm"
7683   [(set (match_operand:TD 0 "nonimmediate_operand" "=m,d,d,Y,r,r")
7684         (match_operand:TD 1 "input_operand" "d,m,d,r,Y,r"))]
7685   "TARGET_HARD_FLOAT && TARGET_POWERPC64 && !WORDS_BIG_ENDIAN
7686    && (gpc_reg_operand (operands[0], TDmode)
7687        || gpc_reg_operand (operands[1], TDmode))"
7688   "#"
7689   "&& reload_completed"
7690   [(pc)]
7691 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7692   [(set_attr "length" "8,8,8,12,12,8")])
7694 (define_insn_and_split "*mov<mode>_32bit"
7695   [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand" "=m,d,d,d,Y,r,r")
7696         (match_operand:FMOVE128_FPR 1 "input_operand" "d,m,d,<zero_fp>,r,<zero_fp>Y,r"))]
7697   "TARGET_HARD_FLOAT && !TARGET_POWERPC64
7698    && (FLOAT128_2REG_P (<MODE>mode)
7699        || int_reg_operand_not_pseudo (operands[0], <MODE>mode)
7700        || int_reg_operand_not_pseudo (operands[1], <MODE>mode))
7701    && (gpc_reg_operand (operands[0], <MODE>mode)
7702        || gpc_reg_operand (operands[1], <MODE>mode))"
7703   "#"
7704   "&& reload_completed"
7705   [(pc)]
7706 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7707   [(set_attr "length" "8,8,8,8,20,20,16")])
7709 (define_insn_and_split "*mov<mode>_softfloat"
7710   [(set (match_operand:FMOVE128 0 "nonimmediate_operand" "=Y,r,r,r")
7711         (match_operand:FMOVE128 1 "input_operand" "r,Y,F,r"))]
7712   "TARGET_SOFT_FLOAT
7713    && (gpc_reg_operand (operands[0], <MODE>mode)
7714        || gpc_reg_operand (operands[1], <MODE>mode))"
7715   "#"
7716   "&& reload_completed"
7717   [(pc)]
7718 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7719   [(set_attr_alternative "length"
7720        [(if_then_else (match_test "TARGET_POWERPC64")
7721             (const_string "8")
7722             (const_string "16"))
7723         (if_then_else (match_test "TARGET_POWERPC64")
7724             (const_string "8")
7725             (const_string "16"))
7726         (if_then_else (match_test "TARGET_POWERPC64")
7727             (const_string "16")
7728             (const_string "32"))
7729         (if_then_else (match_test "TARGET_POWERPC64")
7730             (const_string "8")
7731             (const_string "16"))])])
7733 (define_expand "extenddf<mode>2"
7734   [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
7735         (float_extend:FLOAT128 (match_operand:DF 1 "gpc_reg_operand")))]
7736   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7738   if (FLOAT128_IEEE_P (<MODE>mode))
7739     rs6000_expand_float128_convert (operands[0], operands[1], false);
7740   else if (TARGET_VSX)
7741     {
7742       if (<MODE>mode == TFmode)
7743         emit_insn (gen_extenddftf2_vsx (operands[0], operands[1]));
7744       else if (<MODE>mode == IFmode)
7745         emit_insn (gen_extenddfif2_vsx (operands[0], operands[1]));
7746       else
7747         gcc_unreachable ();
7748     }
7749    else
7750     {
7751       rtx zero = gen_reg_rtx (DFmode);
7752       rs6000_emit_move (zero, CONST0_RTX (DFmode), DFmode);
7754       if (<MODE>mode == TFmode)
7755         emit_insn (gen_extenddftf2_fprs (operands[0], operands[1], zero));
7756       else if (<MODE>mode == IFmode)
7757         emit_insn (gen_extenddfif2_fprs (operands[0], operands[1], zero));
7758       else
7759         gcc_unreachable ();
7760     }
7761   DONE;
7764 ;; Allow memory operands for the source to be created by the combiner.
7765 (define_insn_and_split "extenddf<mode>2_fprs"
7766   [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d,&d")
7767         (float_extend:IBM128
7768          (match_operand:DF 1 "nonimmediate_operand" "d,m,d")))
7769    (use (match_operand:DF 2 "nonimmediate_operand" "m,m,d"))]
7770   "!TARGET_VSX && TARGET_HARD_FLOAT
7771    && TARGET_LONG_DOUBLE_128 && FLOAT128_IBM_P (<MODE>mode)"
7772   "#"
7773   "&& reload_completed"
7774   [(set (match_dup 3) (match_dup 1))
7775    (set (match_dup 4) (match_dup 2))]
7777   const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7778   const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7780   operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
7781   operands[4] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
7784 (define_insn_and_split "extenddf<mode>2_vsx"
7785   [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d")
7786         (float_extend:IBM128
7787          (match_operand:DF 1 "nonimmediate_operand" "ws,m")))]
7788   "TARGET_LONG_DOUBLE_128 && TARGET_VSX && FLOAT128_IBM_P (<MODE>mode)"
7789   "#"
7790   "&& reload_completed"
7791   [(set (match_dup 2) (match_dup 1))
7792    (set (match_dup 3) (match_dup 4))]
7794   const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7795   const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7797   operands[2] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
7798   operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
7799   operands[4] = CONST0_RTX (DFmode);
7802 (define_expand "extendsf<mode>2"
7803   [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
7804         (float_extend:FLOAT128 (match_operand:SF 1 "gpc_reg_operand")))]
7805   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7807   if (FLOAT128_IEEE_P (<MODE>mode))
7808     rs6000_expand_float128_convert (operands[0], operands[1], false);
7809   else
7810     {
7811       rtx tmp = gen_reg_rtx (DFmode);
7812       emit_insn (gen_extendsfdf2 (tmp, operands[1]));
7813       emit_insn (gen_extenddf<mode>2 (operands[0], tmp));
7814     }
7815   DONE;
7818 (define_expand "trunc<mode>df2"
7819   [(set (match_operand:DF 0 "gpc_reg_operand")
7820         (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand")))]
7821   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7823   if (FLOAT128_IEEE_P (<MODE>mode))
7824     {
7825       rs6000_expand_float128_convert (operands[0], operands[1], false);
7826       DONE;
7827     }
7830 (define_insn_and_split "trunc<mode>df2_internal1"
7831   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d")
7832         (float_truncate:DF
7833          (match_operand:IBM128 1 "gpc_reg_operand" "0,d")))]
7834   "FLOAT128_IBM_P (<MODE>mode) && !TARGET_XL_COMPAT
7835    && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7836   "@
7837    #
7838    fmr %0,%1"
7839   "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
7840   [(const_int 0)]
7842   emit_note (NOTE_INSN_DELETED);
7843   DONE;
7845   [(set_attr "type" "fpsimple")])
7847 (define_insn "trunc<mode>df2_internal2"
7848   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
7849         (float_truncate:DF (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
7850   "FLOAT128_IBM_P (<MODE>mode) && TARGET_XL_COMPAT && TARGET_HARD_FLOAT
7851    && TARGET_LONG_DOUBLE_128"
7852   "fadd %0,%1,%L1"
7853   [(set_attr "type" "fp")])
7855 (define_expand "trunc<mode>sf2"
7856   [(set (match_operand:SF 0 "gpc_reg_operand")
7857         (float_truncate:SF (match_operand:FLOAT128 1 "gpc_reg_operand")))]
7858   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7860   if (FLOAT128_IEEE_P (<MODE>mode))
7861     rs6000_expand_float128_convert (operands[0], operands[1], false);
7862   else
7863     {
7864       rtx tmp = gen_reg_rtx (DFmode);
7865       emit_insn (gen_trunc<mode>df2 (tmp, operands[1]));
7866       emit_insn (gen_truncdfsf2 (operands[0], tmp));
7867     }
7868   DONE;
7871 (define_expand "floatsi<mode>2"
7872   [(parallel [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
7873                    (float:FLOAT128 (match_operand:SI 1 "gpc_reg_operand")))
7874               (clobber (match_scratch:DI 2))])]
7875   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7877   rtx op0 = operands[0];
7878   rtx op1 = operands[1];
7880   if (TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode))
7881     ;
7882   else if (FLOAT128_IEEE_P (<MODE>mode))
7883     {
7884       rs6000_expand_float128_convert (op0, op1, false);
7885       DONE;
7886     }
7887   else
7888     {
7889       rtx tmp = gen_reg_rtx (DFmode);
7890       expand_float (tmp, op1, false);
7891       if (<MODE>mode == TFmode)
7892         emit_insn (gen_extenddftf2 (op0, tmp));
7893       else if (<MODE>mode == IFmode)
7894         emit_insn (gen_extenddfif2 (op0, tmp));
7895       else
7896         gcc_unreachable ();
7897       DONE;
7898     }
7901 ; fadd, but rounding towards zero.
7902 ; This is probably not the optimal code sequence.
7903 (define_insn "fix_trunc_helper<mode>"
7904   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
7905         (unspec:DF [(match_operand:IBM128 1 "gpc_reg_operand" "d")]
7906                    UNSPEC_FIX_TRUNC_TF))
7907    (clobber (match_operand:DF 2 "gpc_reg_operand" "=&d"))]
7908   "TARGET_HARD_FLOAT && FLOAT128_IBM_P (<MODE>mode)"
7909   "mffs %2\n\tmtfsb1 31\n\tmtfsb0 30\n\tfadd %0,%1,%L1\n\tmtfsf 1,%2"
7910   [(set_attr "type" "fp")
7911    (set_attr "length" "20")])
7913 (define_expand "fix_trunc<mode>si2"
7914   [(set (match_operand:SI 0 "gpc_reg_operand")
7915         (fix:SI (match_operand:FLOAT128 1 "gpc_reg_operand")))]
7916   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7918   rtx op0 = operands[0];
7919   rtx op1 = operands[1];
7921   if (TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode))
7922     ;
7923   else
7924     {
7925       if (FLOAT128_IEEE_P (<MODE>mode))
7926         rs6000_expand_float128_convert (op0, op1, false);
7927       else if (<MODE>mode == TFmode)
7928         emit_insn (gen_fix_trunctfsi2_fprs (op0, op1));
7929       else if (<MODE>mode == IFmode)
7930         emit_insn (gen_fix_truncifsi2_fprs (op0, op1));
7931       else
7932         gcc_unreachable ();
7933       DONE;
7934     }
7937 (define_expand "fix_trunc<mode>si2_fprs"
7938   [(parallel [(set (match_operand:SI 0 "gpc_reg_operand")
7939                    (fix:SI (match_operand:IBM128 1 "gpc_reg_operand")))
7940               (clobber (match_dup 2))
7941               (clobber (match_dup 3))
7942               (clobber (match_dup 4))
7943               (clobber (match_dup 5))])]
7944   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7946   operands[2] = gen_reg_rtx (DFmode);
7947   operands[3] = gen_reg_rtx (DFmode);
7948   operands[4] = gen_reg_rtx (DImode);
7949   operands[5] = assign_stack_temp (DImode, GET_MODE_SIZE (DImode));
7952 (define_insn_and_split "*fix_trunc<mode>si2_internal"
7953   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
7954         (fix:SI (match_operand:IBM128 1 "gpc_reg_operand" "d")))
7955    (clobber (match_operand:DF 2 "gpc_reg_operand" "=d"))
7956    (clobber (match_operand:DF 3 "gpc_reg_operand" "=&d"))
7957    (clobber (match_operand:DI 4 "gpc_reg_operand" "=d"))
7958    (clobber (match_operand:DI 5 "offsettable_mem_operand" "=o"))]
7959   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7960   "#"
7961   ""
7962   [(pc)]
7964   rtx lowword;
7965   emit_insn (gen_fix_trunc_helper<mode> (operands[2], operands[1],
7966                                          operands[3]));
7968   gcc_assert (MEM_P (operands[5]));
7969   lowword = adjust_address (operands[5], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
7971   emit_insn (gen_fctiwz_df (operands[4], operands[2]));
7972   emit_move_insn (operands[5], operands[4]);
7973   emit_move_insn (operands[0], lowword);
7974   DONE;
7977 (define_expand "fix_trunc<mode>di2"
7978   [(set (match_operand:DI 0 "gpc_reg_operand")
7979         (fix:DI (match_operand:IEEE128 1 "gpc_reg_operand")))]
7980   "TARGET_FLOAT128_TYPE"
7982   if (!TARGET_FLOAT128_HW)
7983     {
7984       rs6000_expand_float128_convert (operands[0], operands[1], false);
7985       DONE;
7986     }
7989 (define_expand "fixuns_trunc<IEEE128:mode><SDI:mode>2"
7990   [(set (match_operand:SDI 0 "gpc_reg_operand")
7991         (unsigned_fix:SDI (match_operand:IEEE128 1 "gpc_reg_operand")))]
7992   "TARGET_FLOAT128_TYPE"
7994   rs6000_expand_float128_convert (operands[0], operands[1], true);
7995   DONE;
7998 (define_expand "floatdi<mode>2"
7999   [(set (match_operand:IEEE128 0 "gpc_reg_operand")
8000         (float:IEEE128 (match_operand:DI 1 "gpc_reg_operand")))]
8001   "TARGET_FLOAT128_TYPE"
8003   if (!TARGET_FLOAT128_HW)
8004     {
8005       rs6000_expand_float128_convert (operands[0], operands[1], false);
8006       DONE;
8007     }
8010 (define_expand "floatunsdi<IEEE128:mode>2"
8011   [(set (match_operand:IEEE128 0 "gpc_reg_operand")
8012         (unsigned_float:IEEE128 (match_operand:DI 1 "gpc_reg_operand")))]
8013   "TARGET_FLOAT128_TYPE"
8015   if (!TARGET_FLOAT128_HW)
8016     {
8017       rs6000_expand_float128_convert (operands[0], operands[1], true);
8018       DONE;
8019     }
8022 (define_expand "floatuns<IEEE128:mode>2"
8023   [(set (match_operand:IEEE128 0 "gpc_reg_operand")
8024         (unsigned_float:IEEE128 (match_operand:SI 1 "gpc_reg_operand")))]
8025   "TARGET_FLOAT128_TYPE"
8027   rtx op0 = operands[0];
8028   rtx op1 = operands[1];
8030   if (TARGET_FLOAT128_HW)
8031     emit_insn (gen_floatuns_<IEEE128:mode>si2_hw (op0, op1));
8032   else
8033     rs6000_expand_float128_convert (op0, op1, true);
8034   DONE;
8037 (define_expand "neg<mode>2"
8038   [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
8039         (neg:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand")))]
8040   "FLOAT128_IEEE_P (<MODE>mode)
8041    || (FLOAT128_IBM_P (<MODE>mode) && TARGET_HARD_FLOAT)"
8043   if (FLOAT128_IEEE_P (<MODE>mode))
8044     {
8045       if (TARGET_FLOAT128_HW)
8046         {
8047           if (<MODE>mode == TFmode)
8048             emit_insn (gen_negtf2_hw (operands[0], operands[1]));
8049           else if (<MODE>mode == KFmode)
8050             emit_insn (gen_negkf2_hw (operands[0], operands[1]));
8051           else
8052             gcc_unreachable ();
8053         }
8054       else if (TARGET_FLOAT128_TYPE)
8055         {
8056           if (<MODE>mode == TFmode)
8057             emit_insn (gen_ieee_128bit_vsx_negtf2 (operands[0], operands[1]));
8058           else if (<MODE>mode == KFmode)
8059             emit_insn (gen_ieee_128bit_vsx_negkf2 (operands[0], operands[1]));
8060           else
8061             gcc_unreachable ();
8062         }
8063       else
8064         {
8065           rtx libfunc = optab_libfunc (neg_optab, <MODE>mode);
8066           rtx target = emit_library_call_value (libfunc, operands[0], LCT_CONST,
8067                                                 <MODE>mode,
8068                                                 operands[1], <MODE>mode);
8070           if (target && !rtx_equal_p (target, operands[0]))
8071             emit_move_insn (operands[0], target);
8072         }
8073       DONE;
8074     }
8077 (define_insn "neg<mode>2_internal"
8078   [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d")
8079         (neg:IBM128 (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
8080   "TARGET_HARD_FLOAT && FLOAT128_IBM_P (<MODE>mode)"
8082   if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
8083     return "fneg %L0,%L1\;fneg %0,%1";
8084   else
8085     return "fneg %0,%1\;fneg %L0,%L1";
8087   [(set_attr "type" "fpsimple")
8088    (set_attr "length" "8")])
8090 (define_expand "abs<mode>2"
8091   [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
8092         (abs:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand")))]
8093   "FLOAT128_IEEE_P (<MODE>mode)
8094    || (FLOAT128_IBM_P (<MODE>mode) && TARGET_HARD_FLOAT)"
8096   rtx label;
8098   if (FLOAT128_IEEE_P (<MODE>mode))
8099     {
8100       if (TARGET_FLOAT128_HW)
8101         {
8102           if (<MODE>mode == TFmode)
8103             emit_insn (gen_abstf2_hw (operands[0], operands[1]));
8104           else if (<MODE>mode == KFmode)
8105             emit_insn (gen_abskf2_hw (operands[0], operands[1]));
8106           else
8107             FAIL;
8108           DONE;
8109         }
8110       else if (TARGET_FLOAT128_TYPE)
8111         {
8112           if (<MODE>mode == TFmode)
8113             emit_insn (gen_ieee_128bit_vsx_abstf2 (operands[0], operands[1]));
8114           else if (<MODE>mode == KFmode)
8115             emit_insn (gen_ieee_128bit_vsx_abskf2 (operands[0], operands[1]));
8116           else
8117             FAIL;
8118           DONE;
8119         }
8120       else
8121         FAIL;
8122     }
8124   label = gen_label_rtx ();
8125   if (<MODE>mode == TFmode)
8126     emit_insn (gen_abstf2_internal (operands[0], operands[1], label));
8127   else if (<MODE>mode == IFmode)
8128     emit_insn (gen_absif2_internal (operands[0], operands[1], label));
8129   else
8130     FAIL;
8131   emit_label (label);
8132   DONE;
8135 (define_expand "abs<mode>2_internal"
8136   [(set (match_operand:IBM128 0 "gpc_reg_operand")
8137         (match_operand:IBM128 1 "gpc_reg_operand"))
8138    (set (match_dup 3) (match_dup 5))
8139    (set (match_dup 5) (abs:DF (match_dup 5)))
8140    (set (match_dup 4) (compare:CCFP (match_dup 3) (match_dup 5)))
8141    (set (pc) (if_then_else (eq (match_dup 4) (const_int 0))
8142                            (label_ref (match_operand 2 ""))
8143                            (pc)))
8144    (set (match_dup 6) (neg:DF (match_dup 6)))]
8145   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8147   const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
8148   const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
8149   operands[3] = gen_reg_rtx (DFmode);
8150   operands[4] = gen_reg_rtx (CCFPmode);
8151   operands[5] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
8152   operands[6] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
8156 ;; Generate IEEE 128-bit -0.0 (0x80000000000000000000000000000000) in a vector
8157 ;; register
8159 (define_expand "ieee_128bit_negative_zero"
8160   [(set (match_operand:V16QI 0 "register_operand") (match_dup 1))]
8161   "TARGET_FLOAT128_TYPE"
8163   rtvec v = rtvec_alloc (16);
8164   int i, high;
8166   for (i = 0; i < 16; i++)
8167     RTVEC_ELT (v, i) = const0_rtx;
8169   high = (BYTES_BIG_ENDIAN) ? 0 : 15;
8170   RTVEC_ELT (v, high) = gen_int_mode (0x80, QImode);
8172   rs6000_expand_vector_init (operands[0], gen_rtx_PARALLEL (V16QImode, v));
8173   DONE;
8176 ;; IEEE 128-bit negate
8178 ;; We have 2 insns here for negate and absolute value.  The first uses
8179 ;; match_scratch so that phases like combine can recognize neg/abs as generic
8180 ;; insns, and second insn after the first split pass loads up the bit to
8181 ;; twiddle the sign bit.  Later GCSE passes can then combine multiple uses of
8182 ;; neg/abs to create the constant just once.
8184 (define_insn_and_split "ieee_128bit_vsx_neg<mode>2"
8185   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8186         (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8187    (clobber (match_scratch:V16QI 2 "=v"))]
8188   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8189   "#"
8190   "&& 1"
8191   [(parallel [(set (match_dup 0)
8192                    (neg:IEEE128 (match_dup 1)))
8193               (use (match_dup 2))])]
8195   if (GET_CODE (operands[2]) == SCRATCH)
8196     operands[2] = gen_reg_rtx (V16QImode);
8198   operands[3] = gen_reg_rtx (V16QImode);
8199   emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8201   [(set_attr "length" "8")
8202    (set_attr "type" "vecsimple")])
8204 (define_insn "*ieee_128bit_vsx_neg<mode>2_internal"
8205   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8206         (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8207    (use (match_operand:V16QI 2 "register_operand" "v"))]
8208   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8209   "xxlxor %x0,%x1,%x2"
8210   [(set_attr "type" "veclogical")])
8212 ;; IEEE 128-bit absolute value
8213 (define_insn_and_split "ieee_128bit_vsx_abs<mode>2"
8214   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8215         (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8216    (clobber (match_scratch:V16QI 2 "=v"))]
8217   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
8218   "#"
8219   "&& 1"
8220   [(parallel [(set (match_dup 0)
8221                    (abs:IEEE128 (match_dup 1)))
8222               (use (match_dup 2))])]
8224   if (GET_CODE (operands[2]) == SCRATCH)
8225     operands[2] = gen_reg_rtx (V16QImode);
8227   operands[3] = gen_reg_rtx (V16QImode);
8228   emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8230   [(set_attr "length" "8")
8231    (set_attr "type" "vecsimple")])
8233 (define_insn "*ieee_128bit_vsx_abs<mode>2_internal"
8234   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8235         (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8236    (use (match_operand:V16QI 2 "register_operand" "v"))]
8237   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8238   "xxlandc %x0,%x1,%x2"
8239   [(set_attr "type" "veclogical")])
8241 ;; IEEE 128-bit negative absolute value
8242 (define_insn_and_split "*ieee_128bit_vsx_nabs<mode>2"
8243   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8244         (neg:IEEE128
8245          (abs:IEEE128
8246           (match_operand:IEEE128 1 "register_operand" "wa"))))
8247    (clobber (match_scratch:V16QI 2 "=v"))]
8248   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW
8249    && FLOAT128_IEEE_P (<MODE>mode)"
8250   "#"
8251   "&& 1"
8252   [(parallel [(set (match_dup 0)
8253                    (neg:IEEE128 (abs:IEEE128 (match_dup 1))))
8254               (use (match_dup 2))])]
8256   if (GET_CODE (operands[2]) == SCRATCH)
8257     operands[2] = gen_reg_rtx (V16QImode);
8259   operands[3] = gen_reg_rtx (V16QImode);
8260   emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8262   [(set_attr "length" "8")
8263    (set_attr "type" "vecsimple")])
8265 (define_insn "*ieee_128bit_vsx_nabs<mode>2_internal"
8266   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8267         (neg:IEEE128
8268          (abs:IEEE128
8269           (match_operand:IEEE128 1 "register_operand" "wa"))))
8270    (use (match_operand:V16QI 2 "register_operand" "v"))]
8271   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8272   "xxlor %x0,%x1,%x2"
8273   [(set_attr "type" "veclogical")])
8275 ;; Float128 conversion functions.  These expand to library function calls.
8276 ;; We use expand to convert from IBM double double to IEEE 128-bit
8277 ;; and trunc for the opposite.
8278 (define_expand "extendiftf2"
8279   [(set (match_operand:TF 0 "gpc_reg_operand")
8280         (float_extend:TF (match_operand:IF 1 "gpc_reg_operand")))]
8281   "TARGET_FLOAT128_TYPE"
8283   rs6000_expand_float128_convert (operands[0], operands[1], false);
8284   DONE;
8287 (define_expand "extendifkf2"
8288   [(set (match_operand:KF 0 "gpc_reg_operand")
8289         (float_extend:KF (match_operand:IF 1 "gpc_reg_operand")))]
8290   "TARGET_FLOAT128_TYPE"
8292   rs6000_expand_float128_convert (operands[0], operands[1], false);
8293   DONE;
8296 (define_expand "extendtfkf2"
8297   [(set (match_operand:KF 0 "gpc_reg_operand")
8298         (float_extend:KF (match_operand:TF 1 "gpc_reg_operand")))]
8299   "TARGET_FLOAT128_TYPE"
8301   rs6000_expand_float128_convert (operands[0], operands[1], false);
8302   DONE;
8305 (define_expand "extendtfif2"
8306   [(set (match_operand:IF 0 "gpc_reg_operand")
8307         (float_extend:IF (match_operand:TF 1 "gpc_reg_operand")))]
8308   "TARGET_FLOAT128_TYPE"
8310   rs6000_expand_float128_convert (operands[0], operands[1], false);
8311   DONE;
8314 (define_expand "trunciftf2"
8315   [(set (match_operand:TF 0 "gpc_reg_operand")
8316         (float_truncate:TF (match_operand:IF 1 "gpc_reg_operand")))]
8317   "TARGET_FLOAT128_TYPE"
8319   rs6000_expand_float128_convert (operands[0], operands[1], false);
8320   DONE;
8323 (define_expand "truncifkf2"
8324   [(set (match_operand:KF 0 "gpc_reg_operand")
8325         (float_truncate:KF (match_operand:IF 1 "gpc_reg_operand")))]
8326   "TARGET_FLOAT128_TYPE"
8328   rs6000_expand_float128_convert (operands[0], operands[1], false);
8329   DONE;
8332 (define_expand "trunckftf2"
8333   [(set (match_operand:TF 0 "gpc_reg_operand")
8334         (float_truncate:TF (match_operand:KF 1 "gpc_reg_operand")))]
8335   "TARGET_FLOAT128_TYPE"
8337   rs6000_expand_float128_convert (operands[0], operands[1], false);
8338   DONE;
8341 (define_expand "trunctfif2"
8342   [(set (match_operand:IF 0 "gpc_reg_operand")
8343         (float_truncate:IF (match_operand:TF 1 "gpc_reg_operand")))]
8344   "TARGET_FLOAT128_TYPE"
8346   rs6000_expand_float128_convert (operands[0], operands[1], false);
8347   DONE;
8350 (define_insn_and_split "*extend<mode>tf2_internal"
8351   [(set (match_operand:TF 0 "gpc_reg_operand" "=<IFKF_reg>")
8352         (float_extend:TF
8353          (match_operand:IFKF 1 "gpc_reg_operand" "<IFKF_reg>")))]
8354    "TARGET_FLOAT128_TYPE
8355     && FLOAT128_IBM_P (TFmode) == FLOAT128_IBM_P (<MODE>mode)"
8356   "#"
8357   "&& reload_completed"
8358   [(set (match_dup 0) (match_dup 2))]
8360   operands[2] = gen_rtx_REG (TFmode, REGNO (operands[1]));
8363 (define_insn_and_split "*extendtf<mode>2_internal"
8364   [(set (match_operand:IFKF 0 "gpc_reg_operand" "=<IFKF_reg>")
8365         (float_extend:IFKF
8366          (match_operand:TF 1 "gpc_reg_operand" "<IFKF_reg>")))]
8367    "TARGET_FLOAT128_TYPE
8368     && FLOAT128_IBM_P (TFmode) == FLOAT128_IBM_P (<MODE>mode)"
8369   "#"
8370   "&& reload_completed"
8371   [(set (match_dup 0) (match_dup 2))]
8373   operands[2] = gen_rtx_REG (<MODE>mode, REGNO (operands[1]));
8377 ;; Reload helper functions used by rs6000_secondary_reload.  The patterns all
8378 ;; must have 3 arguments, and scratch register constraint must be a single
8379 ;; constraint.
8381 ;; Reload patterns to support gpr load/store with misaligned mem.
8382 ;; and multiple gpr load/store at offset >= 0xfffc
8383 (define_expand "reload_<mode>_store"
8384   [(parallel [(match_operand 0 "memory_operand" "=m")
8385               (match_operand 1 "gpc_reg_operand" "r")
8386               (match_operand:GPR 2 "register_operand" "=&b")])]
8387   ""
8389   rs6000_secondary_reload_gpr (operands[1], operands[0], operands[2], true);
8390   DONE;
8393 (define_expand "reload_<mode>_load"
8394   [(parallel [(match_operand 0 "gpc_reg_operand" "=r")
8395               (match_operand 1 "memory_operand" "m")
8396               (match_operand:GPR 2 "register_operand" "=b")])]
8397   ""
8399   rs6000_secondary_reload_gpr (operands[0], operands[1], operands[2], false);
8400   DONE;
8404 ;; Reload patterns for various types using the vector registers.  We may need
8405 ;; an additional base register to convert the reg+offset addressing to reg+reg
8406 ;; for vector registers and reg+reg or (reg+reg)&(-16) addressing to just an
8407 ;; index register for gpr registers.
8408 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_store"
8409   [(parallel [(match_operand:RELOAD 0 "memory_operand" "m")
8410               (match_operand:RELOAD 1 "gpc_reg_operand" "wa")
8411               (match_operand:P 2 "register_operand" "=b")])]
8412   "<P:tptrsize>"
8414   rs6000_secondary_reload_inner (operands[1], operands[0], operands[2], true);
8415   DONE;
8418 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_load"
8419   [(parallel [(match_operand:RELOAD 0 "gpc_reg_operand" "wa")
8420               (match_operand:RELOAD 1 "memory_operand" "m")
8421               (match_operand:P 2 "register_operand" "=b")])]
8422   "<P:tptrsize>"
8424   rs6000_secondary_reload_inner (operands[0], operands[1], operands[2], false);
8425   DONE;
8429 ;; Reload sometimes tries to move the address to a GPR, and can generate
8430 ;; invalid RTL for addresses involving AND -16.  Allow addresses involving
8431 ;; reg+reg, reg+small constant, or just reg, all wrapped in an AND -16.
8433 (define_insn_and_split "*vec_reload_and_plus_<mptrsize>"
8434   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
8435         (and:P (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
8436                        (match_operand:P 2 "reg_or_cint_operand" "rI"))
8437                (const_int -16)))]
8438   "TARGET_ALTIVEC && reload_completed"
8439   "#"
8440   "&& reload_completed"
8441   [(set (match_dup 0)
8442         (plus:P (match_dup 1)
8443                 (match_dup 2)))
8444    (set (match_dup 0)
8445         (and:P (match_dup 0)
8446                (const_int -16)))])
8448 ;; Power8 merge instructions to allow direct move to/from floating point
8449 ;; registers in 32-bit mode.  We use TF mode to get two registers to move the
8450 ;; individual 32-bit parts across.  Subreg doesn't work too well on the TF
8451 ;; value, since it is allocated in reload and not all of the flow information
8452 ;; is setup for it.  We have two patterns to do the two moves between gprs and
8453 ;; fprs.  There isn't a dependancy between the two, but we could potentially
8454 ;; schedule other instructions between the two instructions.
8456 (define_insn "p8_fmrgow_<mode>"
8457   [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
8458         (unspec:FMOVE64X [
8459                 (match_operand:DF 1 "register_operand" "d")
8460                 (match_operand:DF 2 "register_operand" "d")]
8461                          UNSPEC_P8V_FMRGOW))]
8462   "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8463   "fmrgow %0,%1,%2"
8464   [(set_attr "type" "fpsimple")])
8466 (define_insn "p8_mtvsrwz"
8467   [(set (match_operand:DF 0 "register_operand" "=d")
8468         (unspec:DF [(match_operand:SI 1 "register_operand" "r")]
8469                    UNSPEC_P8V_MTVSRWZ))]
8470   "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8471   "mtvsrwz %x0,%1"
8472   [(set_attr "type" "mftgpr")])
8474 (define_insn_and_split "reload_fpr_from_gpr<mode>"
8475   [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
8476         (unspec:FMOVE64X [(match_operand:FMOVE64X 1 "register_operand" "r")]
8477                          UNSPEC_P8V_RELOAD_FROM_GPR))
8478    (clobber (match_operand:IF 2 "register_operand" "=d"))]
8479   "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8480   "#"
8481   "&& reload_completed"
8482   [(const_int 0)]
8484   rtx dest = operands[0];
8485   rtx src = operands[1];
8486   rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0);
8487   rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8);
8488   rtx gpr_hi_reg = gen_highpart (SImode, src);
8489   rtx gpr_lo_reg = gen_lowpart (SImode, src);
8491   emit_insn (gen_p8_mtvsrwz (tmp_hi, gpr_hi_reg));
8492   emit_insn (gen_p8_mtvsrwz (tmp_lo, gpr_lo_reg));
8493   emit_insn (gen_p8_fmrgow_<mode> (dest, tmp_hi, tmp_lo));
8494   DONE;
8496   [(set_attr "length" "12")
8497    (set_attr "type" "three")])
8499 ;; Move 128 bit values from GPRs to VSX registers in 64-bit mode
8500 (define_insn "p8_mtvsrd_df"
8501   [(set (match_operand:DF 0 "register_operand" "=wa")
8502         (unspec:DF [(match_operand:DI 1 "register_operand" "r")]
8503                    UNSPEC_P8V_MTVSRD))]
8504   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8505   "mtvsrd %x0,%1"
8506   [(set_attr "type" "mftgpr")])
8508 (define_insn "p8_xxpermdi_<mode>"
8509   [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
8510         (unspec:FMOVE128_GPR [
8511                 (match_operand:DF 1 "register_operand" "wa")
8512                 (match_operand:DF 2 "register_operand" "wa")]
8513                 UNSPEC_P8V_XXPERMDI))]
8514   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8515   "xxpermdi %x0,%x1,%x2,0"
8516   [(set_attr "type" "vecperm")])
8518 (define_insn_and_split "reload_vsx_from_gpr<mode>"
8519   [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
8520         (unspec:FMOVE128_GPR
8521          [(match_operand:FMOVE128_GPR 1 "register_operand" "r")]
8522          UNSPEC_P8V_RELOAD_FROM_GPR))
8523    (clobber (match_operand:IF 2 "register_operand" "=wa"))]
8524   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8525   "#"
8526   "&& reload_completed"
8527   [(const_int 0)]
8529   rtx dest = operands[0];
8530   rtx src = operands[1];
8531   /* You might think that we could use op0 as one temp and a DF clobber
8532      as op2, but you'd be wrong.  Secondary reload move patterns don't
8533      check for overlap of the clobber and the destination.  */
8534   rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0);
8535   rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8);
8536   rtx gpr_hi_reg = gen_highpart (DImode, src);
8537   rtx gpr_lo_reg = gen_lowpart (DImode, src);
8539   emit_insn (gen_p8_mtvsrd_df (tmp_hi, gpr_hi_reg));
8540   emit_insn (gen_p8_mtvsrd_df (tmp_lo, gpr_lo_reg));
8541   emit_insn (gen_p8_xxpermdi_<mode> (dest, tmp_hi, tmp_lo));
8542   DONE;
8544   [(set_attr "length" "12")
8545    (set_attr "type" "three")])
8547 (define_split
8548   [(set (match_operand:FMOVE128_GPR 0 "nonimmediate_operand")
8549         (match_operand:FMOVE128_GPR 1 "input_operand"))]
8550   "reload_completed
8551    && (int_reg_operand (operands[0], <MODE>mode)
8552        || int_reg_operand (operands[1], <MODE>mode))
8553    && (!TARGET_DIRECT_MOVE_128
8554        || (!vsx_register_operand (operands[0], <MODE>mode)
8555            && !vsx_register_operand (operands[1], <MODE>mode)))"
8556   [(pc)]
8557 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
8559 ;; Move SFmode to a VSX from a GPR register.  Because scalar floating point
8560 ;; type is stored internally as double precision in the VSX registers, we have
8561 ;; to convert it from the vector format.
8562 (define_insn "p8_mtvsrd_sf"
8563   [(set (match_operand:SF 0 "register_operand" "=wa")
8564         (unspec:SF [(match_operand:DI 1 "register_operand" "r")]
8565                    UNSPEC_P8V_MTVSRD))]
8566   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8567   "mtvsrd %x0,%1"
8568   [(set_attr "type" "mftgpr")])
8570 (define_insn_and_split "reload_vsx_from_gprsf"
8571   [(set (match_operand:SF 0 "register_operand" "=wa")
8572         (unspec:SF [(match_operand:SF 1 "register_operand" "r")]
8573                    UNSPEC_P8V_RELOAD_FROM_GPR))
8574    (clobber (match_operand:DI 2 "register_operand" "=r"))]
8575   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8576   "#"
8577   "&& reload_completed"
8578   [(const_int 0)]
8580   rtx op0 = operands[0];
8581   rtx op1 = operands[1];
8582   rtx op2 = operands[2];
8583   rtx op1_di = simplify_gen_subreg (DImode, op1, SFmode, 0);
8585   /* Move SF value to upper 32-bits for xscvspdpn.  */
8586   emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32)));
8587   emit_insn (gen_p8_mtvsrd_sf (op0, op2));
8588   emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0));
8589   DONE;
8591   [(set_attr "length" "8")
8592    (set_attr "type" "two")])
8594 ;; Move 128 bit values from VSX registers to GPRs in 64-bit mode by doing a
8595 ;; normal 64-bit move, followed by an xxpermdi to get the bottom 64-bit value,
8596 ;; and then doing a move of that.
8597 (define_insn "p8_mfvsrd_3_<mode>"
8598   [(set (match_operand:DF 0 "register_operand" "=r")
8599         (unspec:DF [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
8600                    UNSPEC_P8V_RELOAD_FROM_VSX))]
8601   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8602   "mfvsrd %0,%x1"
8603   [(set_attr "type" "mftgpr")])
8605 (define_insn_and_split "reload_gpr_from_vsx<mode>"
8606   [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=r")
8607         (unspec:FMOVE128_GPR
8608          [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
8609          UNSPEC_P8V_RELOAD_FROM_VSX))
8610    (clobber (match_operand:FMOVE128_GPR 2 "register_operand" "=wa"))]
8611   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8612   "#"
8613   "&& reload_completed"
8614   [(const_int 0)]
8616   rtx dest = operands[0];
8617   rtx src = operands[1];
8618   rtx tmp = operands[2];
8619   rtx gpr_hi_reg = gen_highpart (DFmode, dest);
8620   rtx gpr_lo_reg = gen_lowpart (DFmode, dest);
8622   emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_hi_reg, src));
8623   emit_insn (gen_vsx_xxpermdi_<mode>_be (tmp, src, src, GEN_INT (3)));
8624   emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_lo_reg, tmp));
8625   DONE;
8627   [(set_attr "length" "12")
8628    (set_attr "type" "three")])
8630 ;; Move SFmode to a GPR from a VSX register.  Because scalar floating point
8631 ;; type is stored internally as double precision, we have to convert it to the
8632 ;; vector format.
8634 (define_insn_and_split "reload_gpr_from_vsxsf"
8635   [(set (match_operand:SF 0 "register_operand" "=r")
8636         (unspec:SF [(match_operand:SF 1 "register_operand" "ww")]
8637                    UNSPEC_P8V_RELOAD_FROM_VSX))
8638    (clobber (match_operand:V4SF 2 "register_operand" "=wIwH"))]
8639   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8640   "#"
8641   "&& reload_completed"
8642   [(const_int 0)]
8644   rtx op0 = operands[0];
8645   rtx op1 = operands[1];
8646   rtx op2 = operands[2];
8647   rtx op0_di = gen_rtx_REG (DImode, reg_or_subregno (op0));
8648   rtx op2_si = gen_rtx_REG (SImode, reg_or_subregno (op2));
8650   emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
8651   emit_insn (gen_zero_extendsidi2 (op0_di, op2_si));
8652   DONE;
8654   [(set_attr "length" "8")
8655    (set_attr "type" "two")])
8658 ;; Next come the multi-word integer load and store and the load and store
8659 ;; multiple insns.
8661 ;; List r->r after r->Y, otherwise reload will try to reload a
8662 ;; non-offsettable address by using r->r which won't make progress.
8663 ;; Use of fprs is disparaged slightly otherwise reload prefers to reload
8664 ;; a gpr into a fpr instead of reloading an invalid 'Y' address
8666 ;;        GPR store  GPR load   GPR move   FPR store  FPR load   FPR move
8667 ;;        GPR const  AVX store  AVX store  AVX load   AVX load   VSX move
8668 ;;        P9 0       P9 -1      AVX 0/-1   VSX 0      VSX -1     P9 const
8669 ;;        AVX const  
8671 (define_insn "*movdi_internal32"
8672   [(set (match_operand:DI 0 "nonimmediate_operand"
8673          "=Y,        r,         r,         m,         ^d,        ^d,
8674           r,         wY,        Z,         ^wb,       $wv,       ^wi,
8675           *wo,       *wo,       *wv,       *wi,       *wi,       *wv,
8676           *wv")
8678         (match_operand:DI 1 "input_operand"
8679          "r,         Y,         r,         ^d,        m,         ^d,
8680           IJKnF,     ^wb,       $wv,       wY,        Z,         ^wi,
8681           Oj,        wM,        OjwM,      Oj,        wM,        wS,
8682           wB"))]
8684   "! TARGET_POWERPC64
8685    && (gpc_reg_operand (operands[0], DImode)
8686        || gpc_reg_operand (operands[1], DImode))"
8687   "@
8688    #
8689    #
8690    #
8691    stfd%U0%X0 %1,%0
8692    lfd%U1%X1 %0,%1
8693    fmr %0,%1
8694    #
8695    stxsd %1,%0
8696    stxsdx %x1,%y0
8697    lxsd %0,%1
8698    lxsdx %x0,%y1
8699    xxlor %x0,%x1,%x1
8700    xxspltib %x0,0
8701    xxspltib %x0,255
8702    vspltisw %0,%1
8703    xxlxor %x0,%x0,%x0
8704    xxlorc %x0,%x0,%x0
8705    #
8706    #"
8707   [(set_attr "type"
8708          "store,     load,      *,         fpstore,   fpload,    fpsimple,
8709           *,         fpstore,   fpstore,   fpload,    fpload,    veclogical,
8710           vecsimple, vecsimple, vecsimple, veclogical,veclogical,vecsimple,
8711           vecsimple")
8712    (set_attr "size" "64")
8713    (set_attr "length"
8714          "8,         8,         8,         4,         4,         4,
8715           16,        4,         4,         4,         4,         4,
8716           4,         4,         4,         4,         4,         8,
8717           4")])
8719 (define_split
8720   [(set (match_operand:DI 0 "gpc_reg_operand")
8721         (match_operand:DI 1 "const_int_operand"))]
8722   "! TARGET_POWERPC64 && reload_completed
8723    && gpr_or_gpr_p (operands[0], operands[1])
8724    && !direct_move_p (operands[0], operands[1])"
8725   [(set (match_dup 2) (match_dup 4))
8726    (set (match_dup 3) (match_dup 1))]
8728   HOST_WIDE_INT value = INTVAL (operands[1]);
8729   operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
8730                                        DImode);
8731   operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
8732                                        DImode);
8733   operands[4] = GEN_INT (value >> 32);
8734   operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
8737 (define_split
8738   [(set (match_operand:DIFD 0 "nonimmediate_operand")
8739         (match_operand:DIFD 1 "input_operand"))]
8740   "reload_completed && !TARGET_POWERPC64
8741    && gpr_or_gpr_p (operands[0], operands[1])
8742    && !direct_move_p (operands[0], operands[1])"
8743   [(pc)]
8744 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
8746 ;;              GPR store  GPR load   GPR move   GPR li     GPR lis     GPR #
8747 ;;              FPR store  FPR load   FPR move   AVX store  AVX store   AVX load
8748 ;;              AVX load   VSX move   P9 0       P9 -1      AVX 0/-1    VSX 0
8749 ;;              VSX -1     P9 const   AVX const  From SPR   To SPR      SPR<->SPR
8750 ;;              FPR->GPR   GPR->FPR   VSX->GPR   GPR->VSX
8751 (define_insn "*movdi_internal64"
8752   [(set (match_operand:DI 0 "nonimmediate_operand"
8753                "=YZ,       r,         r,         r,         r,          r,
8754                 m,         ^d,        ^d,        wY,        Z,          $wb,
8755                 $wv,       ^wi,       *wo,       *wo,       *wv,        *wi,
8756                 *wi,       *wv,       *wv,       r,         *h,         *h,
8757                 ?*r,       ?*wg,      ?*r,       ?*wj")
8759         (match_operand:DI 1 "input_operand"
8760                "r,         YZ,        r,         I,         L,          nF,
8761                 ^d,        m,         ^d,        ^wb,       $wv,        wY,
8762                 Z,         ^wi,       Oj,        wM,        OjwM,       Oj,
8763                 wM,        wS,        wB,        *h,        r,          0,
8764                 wg,        r,         wj,        r"))]
8766   "TARGET_POWERPC64
8767    && (gpc_reg_operand (operands[0], DImode)
8768        || gpc_reg_operand (operands[1], DImode))"
8769   "@
8770    std%U0%X0 %1,%0
8771    ld%U1%X1 %0,%1
8772    mr %0,%1
8773    li %0,%1
8774    lis %0,%v1
8775    #
8776    stfd%U0%X0 %1,%0
8777    lfd%U1%X1 %0,%1
8778    fmr %0,%1
8779    stxsd %1,%0
8780    stxsdx %x1,%y0
8781    lxsd %0,%1
8782    lxsdx %x0,%y1
8783    xxlor %x0,%x1,%x1
8784    xxspltib %x0,0
8785    xxspltib %x0,255
8786    #
8787    xxlxor %x0,%x0,%x0
8788    xxlorc %x0,%x0,%x0
8789    #
8790    #
8791    mf%1 %0
8792    mt%0 %1
8793    nop
8794    mftgpr %0,%1
8795    mffgpr %0,%1
8796    mfvsrd %0,%x1
8797    mtvsrd %x0,%1"
8798   [(set_attr "type"
8799                "store,      load,       *,         *,         *,         *,
8800                 fpstore,    fpload,     fpsimple,  fpstore,   fpstore,   fpload,
8801                 fpload,     veclogical, vecsimple, vecsimple, vecsimple, veclogical,
8802                 veclogical, vecsimple,  vecsimple, mfjmpr,    mtjmpr,    *,
8803                 mftgpr,     mffgpr,     mftgpr,    mffgpr")
8805    (set_attr "size" "64")
8806    (set_attr "length"
8807                "4,         4,         4,         4,         4,          20,
8808                 4,         4,         4,         4,         4,          4,
8809                 4,         4,         4,         4,         4,          4,
8810                 4,         8,         4,         4,         4,          4,
8811                 4,         4,         4,         4")])
8813 ; Some DImode loads are best done as a load of -1 followed by a mask
8814 ; instruction.
8815 (define_split
8816   [(set (match_operand:DI 0 "int_reg_operand_not_pseudo")
8817         (match_operand:DI 1 "const_int_operand"))]
8818   "TARGET_POWERPC64
8819    && num_insns_constant (operands[1], DImode) > 1
8820    && !IN_RANGE (INTVAL (operands[1]), -0x80000000, 0xffffffff)
8821    && rs6000_is_valid_and_mask (operands[1], DImode)"
8822   [(set (match_dup 0)
8823         (const_int -1))
8824    (set (match_dup 0)
8825         (and:DI (match_dup 0)
8826                 (match_dup 1)))]
8827   "")
8829 ;; Split a load of a large constant into the appropriate five-instruction
8830 ;; sequence.  Handle anything in a constant number of insns.
8831 ;; When non-easy constants can go in the TOC, this should use
8832 ;; easy_fp_constant predicate.
8833 (define_split
8834   [(set (match_operand:DI 0 "int_reg_operand_not_pseudo")
8835         (match_operand:DI 1 "const_int_operand"))]
8836   "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
8837   [(set (match_dup 0) (match_dup 2))
8838    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
8840   if (rs6000_emit_set_const (operands[0], operands[1]))
8841     DONE;
8842   else
8843     FAIL;
8846 (define_split
8847   [(set (match_operand:DI 0 "int_reg_operand_not_pseudo")
8848         (match_operand:DI 1 "const_scalar_int_operand"))]
8849   "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
8850   [(set (match_dup 0) (match_dup 2))
8851    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
8853   if (rs6000_emit_set_const (operands[0], operands[1]))
8854     DONE;
8855   else
8856     FAIL;
8859 (define_split
8860   [(set (match_operand:DI 0 "altivec_register_operand")
8861         (match_operand:DI 1 "s5bit_cint_operand"))]
8862   "TARGET_VSX && reload_completed"
8863   [(const_int 0)]
8865   rtx op0 = operands[0];
8866   rtx op1 = operands[1];
8867   int r = REGNO (op0);
8868   rtx op0_v4si = gen_rtx_REG (V4SImode, r);
8870   emit_insn (gen_altivec_vspltisw (op0_v4si, op1));
8871   if (op1 != const0_rtx && op1 != constm1_rtx)
8872     {
8873       rtx op0_v2di = gen_rtx_REG (V2DImode, r);
8874       emit_insn (gen_altivec_vupkhsw (op0_v2di, op0_v4si));
8875     }
8876   DONE;
8879 ;; Split integer constants that can be loaded with XXSPLTIB and a
8880 ;; sign extend operation.
8881 (define_split
8882   [(set (match_operand:INT_ISA3 0 "altivec_register_operand")
8883         (match_operand:INT_ISA3 1 "xxspltib_constant_split"))]
8884   "TARGET_P9_VECTOR && reload_completed"
8885   [(const_int 0)]
8887   rtx op0 = operands[0];
8888   rtx op1 = operands[1];
8889   int r = REGNO (op0);
8890   rtx op0_v16qi = gen_rtx_REG (V16QImode, r);
8892   emit_insn (gen_xxspltib_v16qi (op0_v16qi, op1));
8893   if (<MODE>mode == DImode)
8894     emit_insn (gen_vsx_sign_extend_qi_di (operands[0], op0_v16qi));
8895   else if (<MODE>mode == SImode)
8896     emit_insn (gen_vsx_sign_extend_qi_si (operands[0], op0_v16qi));
8897   else if (<MODE>mode == HImode)
8898     {
8899       rtx op0_v8hi = gen_rtx_REG (V8HImode, r);
8900       emit_insn (gen_altivec_vupkhsb (op0_v8hi, op0_v16qi));
8901     }
8902   DONE;
8906 ;; TImode/PTImode is similar, except that we usually want to compute the
8907 ;; address into a register and use lsi/stsi (the exception is during reload).
8909 (define_insn "*mov<mode>_string"
8910   [(set (match_operand:TI2 0 "reg_or_mem_operand" "=Q,Y,????r,????r,????r,r")
8911         (match_operand:TI2 1 "input_operand" "r,r,Q,Y,r,n"))]
8912   "! TARGET_POWERPC64
8913    && (<MODE>mode != TImode || VECTOR_MEM_NONE_P (TImode))
8914    && (gpc_reg_operand (operands[0], <MODE>mode)
8915        || gpc_reg_operand (operands[1], <MODE>mode))"
8916   "#"
8917   [(set_attr "type" "store,store,load,load,*,*")
8918    (set_attr "update" "yes")
8919    (set_attr "indexed" "yes")
8920    (set_attr "cell_micro" "conditional")])
8922 (define_insn "*mov<mode>_ppc64"
8923   [(set (match_operand:TI2 0 "nonimmediate_operand" "=wQ,Y,r,r,r,r")
8924         (match_operand:TI2 1 "input_operand" "r,r,wQ,Y,r,n"))]
8925   "(TARGET_POWERPC64 && VECTOR_MEM_NONE_P (<MODE>mode)
8926    && (gpc_reg_operand (operands[0], <MODE>mode)
8927        || gpc_reg_operand (operands[1], <MODE>mode)))"
8929   return rs6000_output_move_128bit (operands);
8931   [(set_attr "type" "store,store,load,load,*,*")
8932    (set_attr "length" "8")])
8934 (define_split
8935   [(set (match_operand:TI2 0 "int_reg_operand")
8936         (match_operand:TI2 1 "const_scalar_int_operand"))]
8937   "TARGET_POWERPC64
8938    && (VECTOR_MEM_NONE_P (<MODE>mode)
8939        || (reload_completed && INT_REGNO_P (REGNO (operands[0]))))"
8940   [(set (match_dup 2) (match_dup 4))
8941    (set (match_dup 3) (match_dup 5))]
8943   operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
8944                                        <MODE>mode);
8945   operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
8946                                        <MODE>mode);
8947   if (CONST_WIDE_INT_P (operands[1]))
8948     {
8949       operands[4] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 1));
8950       operands[5] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 0));
8951     }
8952   else if (CONST_INT_P (operands[1]))
8953     {
8954       operands[4] = GEN_INT (- (INTVAL (operands[1]) < 0));
8955       operands[5] = operands[1];
8956     }
8957   else
8958     FAIL;
8961 (define_split
8962   [(set (match_operand:TI2 0 "nonimmediate_operand")
8963         (match_operand:TI2 1 "input_operand"))]
8964   "reload_completed
8965    && gpr_or_gpr_p (operands[0], operands[1])
8966    && !direct_move_p (operands[0], operands[1])
8967    && !quad_load_store_p (operands[0], operands[1])"
8968   [(pc)]
8969 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
8971 (define_expand "setmemsi"
8972   [(parallel [(set (match_operand:BLK 0 "")
8973                    (match_operand 2 "const_int_operand"))
8974               (use (match_operand:SI 1 ""))
8975               (use (match_operand:SI 3 ""))])]
8976   ""
8978   /* If value to set is not zero, use the library routine.  */
8979   if (operands[2] != const0_rtx)
8980     FAIL;
8982   if (expand_block_clear (operands))
8983     DONE;
8984   else
8985     FAIL;
8988 ;; String compare N insn.
8989 ;; Argument 0 is the target (result)
8990 ;; Argument 1 is the destination
8991 ;; Argument 2 is the source
8992 ;; Argument 3 is the length
8993 ;; Argument 4 is the alignment
8995 (define_expand "cmpstrnsi"
8996   [(parallel [(set (match_operand:SI 0)
8997                (compare:SI (match_operand:BLK 1)
8998                            (match_operand:BLK 2)))
8999               (use (match_operand:SI 3))
9000               (use (match_operand:SI 4))])]
9001   "TARGET_CMPB && (BYTES_BIG_ENDIAN || TARGET_LDBRX)"
9003   if (optimize_insn_for_size_p ())
9004     FAIL;
9006   if (expand_strn_compare (operands, 0))
9007     DONE;
9008   else  
9009     FAIL;
9012 ;; String compare insn.
9013 ;; Argument 0 is the target (result)
9014 ;; Argument 1 is the destination
9015 ;; Argument 2 is the source
9016 ;; Argument 3 is the alignment
9018 (define_expand "cmpstrsi"
9019   [(parallel [(set (match_operand:SI 0)
9020                (compare:SI (match_operand:BLK 1)
9021                            (match_operand:BLK 2)))
9022               (use (match_operand:SI 3))])]
9023   "TARGET_CMPB && (BYTES_BIG_ENDIAN || TARGET_LDBRX)"
9025   if (optimize_insn_for_size_p ())
9026     FAIL;
9028   if (expand_strn_compare (operands, 1))
9029     DONE;
9030   else  
9031     FAIL;
9034 ;; Block compare insn.
9035 ;; Argument 0 is the target (result)
9036 ;; Argument 1 is the destination
9037 ;; Argument 2 is the source
9038 ;; Argument 3 is the length
9039 ;; Argument 4 is the alignment
9041 (define_expand "cmpmemsi"
9042   [(parallel [(set (match_operand:SI 0)
9043                (compare:SI (match_operand:BLK 1)
9044                            (match_operand:BLK 2)))
9045               (use (match_operand:SI 3))
9046               (use (match_operand:SI 4))])]
9047   "TARGET_POPCNTD"
9049   if (expand_block_compare (operands))
9050     DONE;
9051   else
9052     FAIL;
9055 ;; String/block move insn.
9056 ;; Argument 0 is the destination
9057 ;; Argument 1 is the source
9058 ;; Argument 2 is the length
9059 ;; Argument 3 is the alignment
9061 (define_expand "movmemsi"
9062   [(parallel [(set (match_operand:BLK 0 "")
9063                    (match_operand:BLK 1 ""))
9064               (use (match_operand:SI 2 ""))
9065               (use (match_operand:SI 3 ""))])]
9066   ""
9068   if (expand_block_move (operands))
9069     DONE;
9070   else
9071     FAIL;
9074 ;; Define insns that do load or store with update.  Some of these we can
9075 ;; get by using pre-decrement or pre-increment, but the hardware can also
9076 ;; do cases where the increment is not the size of the object.
9078 ;; In all these cases, we use operands 0 and 1 for the register being
9079 ;; incremented because those are the operands that local-alloc will
9080 ;; tie and these are the pair most likely to be tieable (and the ones
9081 ;; that will benefit the most).
9083 (define_insn "*movdi_update1"
9084   [(set (match_operand:DI 3 "gpc_reg_operand" "=r,r")
9085         (mem:DI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0,0")
9086                          (match_operand:DI 2 "reg_or_aligned_short_operand" "r,I"))))
9087    (set (match_operand:DI 0 "gpc_reg_operand" "=b,b")
9088         (plus:DI (match_dup 1) (match_dup 2)))]
9089   "TARGET_POWERPC64 && TARGET_UPDATE
9090    && (!avoiding_indexed_address_p (DImode)
9091        || !gpc_reg_operand (operands[2], DImode))"
9092   "@
9093    ldux %3,%0,%2
9094    ldu %3,%2(%0)"
9095   [(set_attr "type" "load")
9096    (set_attr "update" "yes")
9097    (set_attr "indexed" "yes,no")])
9099 (define_insn "movdi_<mode>_update"
9100   [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9101                          (match_operand:P 2 "reg_or_aligned_short_operand" "r,I")))
9102         (match_operand:DI 3 "gpc_reg_operand" "r,r"))
9103    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9104         (plus:P (match_dup 1) (match_dup 2)))]
9105   "TARGET_POWERPC64 && TARGET_UPDATE
9106    && (!avoiding_indexed_address_p (Pmode)
9107        || !gpc_reg_operand (operands[2], Pmode)
9108        || (REG_P (operands[0])
9109            && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
9110   "@
9111    stdux %3,%0,%2
9112    stdu %3,%2(%0)"
9113   [(set_attr "type" "store")
9114    (set_attr "update" "yes")
9115    (set_attr "indexed" "yes,no")])
9117 ;; This pattern is only conditional on TARGET_POWERPC64, as it is
9118 ;; needed for stack allocation, even if the user passes -mno-update.
9119 (define_insn "movdi_<mode>_update_stack"
9120   [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9121                          (match_operand:P 2 "reg_or_aligned_short_operand" "r,I")))
9122         (match_operand:DI 3 "gpc_reg_operand" "r,r"))
9123    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9124         (plus:P (match_dup 1) (match_dup 2)))]
9125   "TARGET_POWERPC64"
9126   "@
9127    stdux %3,%0,%2
9128    stdu %3,%2(%0)"
9129   [(set_attr "type" "store")
9130    (set_attr "update" "yes")
9131    (set_attr "indexed" "yes,no")])
9133 (define_insn "*movsi_update1"
9134   [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9135         (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9136                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9137    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9138         (plus:SI (match_dup 1) (match_dup 2)))]
9139   "TARGET_UPDATE
9140    && (!avoiding_indexed_address_p (SImode)
9141        || !gpc_reg_operand (operands[2], SImode))"
9142   "@
9143    lwzux %3,%0,%2
9144    lwzu %3,%2(%0)"
9145   [(set_attr "type" "load")
9146    (set_attr "update" "yes")
9147    (set_attr "indexed" "yes,no")])
9149 (define_insn "*movsi_update2"
9150   [(set (match_operand:DI 3 "gpc_reg_operand" "=r")
9151         (sign_extend:DI
9152          (mem:SI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0")
9153                           (match_operand:DI 2 "gpc_reg_operand" "r")))))
9154    (set (match_operand:DI 0 "gpc_reg_operand" "=b")
9155         (plus:DI (match_dup 1) (match_dup 2)))]
9156   "TARGET_POWERPC64 && !avoiding_indexed_address_p (DImode)"
9157   "lwaux %3,%0,%2"
9158   [(set_attr "type" "load")
9159    (set_attr "sign_extend" "yes")
9160    (set_attr "update" "yes")
9161    (set_attr "indexed" "yes")])
9163 (define_insn "movsi_update"
9164   [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9165                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9166         (match_operand:SI 3 "gpc_reg_operand" "r,r"))
9167    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9168         (plus:SI (match_dup 1) (match_dup 2)))]
9169   "TARGET_UPDATE
9170    && (!avoiding_indexed_address_p (SImode)
9171        || !gpc_reg_operand (operands[2], SImode)
9172        || (REG_P (operands[0])
9173            && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
9174   "@
9175    stwux %3,%0,%2
9176    stwu %3,%2(%0)"
9177   [(set_attr "type" "store")
9178    (set_attr "update" "yes")
9179    (set_attr "indexed" "yes,no")])
9181 ;; This is an unconditional pattern; needed for stack allocation, even
9182 ;; if the user passes -mno-update.
9183 (define_insn "movsi_update_stack"
9184   [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9185                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9186         (match_operand:SI 3 "gpc_reg_operand" "r,r"))
9187    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9188         (plus:SI (match_dup 1) (match_dup 2)))]
9189   ""
9190   "@
9191    stwux %3,%0,%2
9192    stwu %3,%2(%0)"
9193   [(set_attr "type" "store")
9194    (set_attr "update" "yes")
9195    (set_attr "indexed" "yes,no")])
9197 (define_insn "*movhi_update1"
9198   [(set (match_operand:HI 3 "gpc_reg_operand" "=r,r")
9199         (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9200                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9201    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9202         (plus:SI (match_dup 1) (match_dup 2)))]
9203   "TARGET_UPDATE
9204    && (!avoiding_indexed_address_p (SImode)
9205        || !gpc_reg_operand (operands[2], SImode))"
9206   "@
9207    lhzux %3,%0,%2
9208    lhzu %3,%2(%0)"
9209   [(set_attr "type" "load")
9210    (set_attr "update" "yes")
9211    (set_attr "indexed" "yes,no")])
9213 (define_insn "*movhi_update2"
9214   [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9215         (zero_extend:SI
9216          (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9217                           (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
9218    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9219         (plus:SI (match_dup 1) (match_dup 2)))]
9220   "TARGET_UPDATE
9221    && (!avoiding_indexed_address_p (SImode)
9222        || !gpc_reg_operand (operands[2], SImode))"
9223   "@
9224    lhzux %3,%0,%2
9225    lhzu %3,%2(%0)"
9226   [(set_attr "type" "load")
9227    (set_attr "update" "yes")
9228    (set_attr "indexed" "yes,no")])
9230 (define_insn "*movhi_update3"
9231   [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9232         (sign_extend:SI
9233          (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9234                           (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
9235    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9236         (plus:SI (match_dup 1) (match_dup 2)))]
9237   "TARGET_UPDATE
9238    && !(avoiding_indexed_address_p (SImode)
9239         && gpc_reg_operand (operands[2], SImode))"
9240   "@
9241    lhaux %3,%0,%2
9242    lhau %3,%2(%0)"
9243   [(set_attr "type" "load")
9244    (set_attr "sign_extend" "yes")
9245    (set_attr "update" "yes")
9246    (set_attr "indexed" "yes,no")])
9248 (define_insn "*movhi_update4"
9249   [(set (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9250                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9251         (match_operand:HI 3 "gpc_reg_operand" "r,r"))
9252    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9253         (plus:SI (match_dup 1) (match_dup 2)))]
9254   "TARGET_UPDATE
9255    && (!avoiding_indexed_address_p (SImode)
9256        || !gpc_reg_operand (operands[2], SImode))"
9257   "@
9258    sthux %3,%0,%2
9259    sthu %3,%2(%0)"
9260   [(set_attr "type" "store")
9261    (set_attr "update" "yes")
9262    (set_attr "indexed" "yes,no")])
9264 (define_insn "*movqi_update1"
9265   [(set (match_operand:QI 3 "gpc_reg_operand" "=r,r")
9266         (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9267                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9268    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9269         (plus:SI (match_dup 1) (match_dup 2)))]
9270   "TARGET_UPDATE
9271    && (!avoiding_indexed_address_p (SImode)
9272        || !gpc_reg_operand (operands[2], SImode))"
9273   "@
9274    lbzux %3,%0,%2
9275    lbzu %3,%2(%0)"
9276   [(set_attr "type" "load")
9277    (set_attr "update" "yes")
9278    (set_attr "indexed" "yes,no")])
9280 (define_insn "*movqi_update2"
9281   [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9282         (zero_extend:SI
9283          (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    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9286         (plus:SI (match_dup 1) (match_dup 2)))]
9287   "TARGET_UPDATE
9288    && (!avoiding_indexed_address_p (SImode)
9289        || !gpc_reg_operand (operands[2], SImode))"
9290   "@
9291    lbzux %3,%0,%2
9292    lbzu %3,%2(%0)"
9293   [(set_attr "type" "load")
9294    (set_attr "update" "yes")
9295    (set_attr "indexed" "yes,no")])
9297 (define_insn "*movqi_update3"
9298   [(set (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9299                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9300         (match_operand:QI 3 "gpc_reg_operand" "r,r"))
9301    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9302         (plus:SI (match_dup 1) (match_dup 2)))]
9303   "TARGET_UPDATE
9304    && (!avoiding_indexed_address_p (SImode)
9305        || !gpc_reg_operand (operands[2], SImode))"
9306   "@
9307    stbux %3,%0,%2
9308    stbu %3,%2(%0)"
9309   [(set_attr "type" "store")
9310    (set_attr "update" "yes")
9311    (set_attr "indexed" "yes,no")])
9313 (define_insn "*movsf_update1"
9314   [(set (match_operand:SF 3 "gpc_reg_operand" "=f,f")
9315         (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    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9318         (plus:SI (match_dup 1) (match_dup 2)))]
9319   "TARGET_HARD_FLOAT && TARGET_UPDATE
9320    && (!avoiding_indexed_address_p (SImode)
9321        || !gpc_reg_operand (operands[2], SImode))"
9322   "@
9323    lfsux %3,%0,%2
9324    lfsu %3,%2(%0)"
9325   [(set_attr "type" "fpload")
9326    (set_attr "update" "yes")
9327    (set_attr "indexed" "yes,no")])
9329 (define_insn "*movsf_update2"
9330   [(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9331                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9332         (match_operand:SF 3 "gpc_reg_operand" "f,f"))
9333    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9334         (plus:SI (match_dup 1) (match_dup 2)))]
9335   "TARGET_HARD_FLOAT && TARGET_UPDATE
9336    && (!avoiding_indexed_address_p (SImode)
9337        || !gpc_reg_operand (operands[2], SImode))"
9338   "@
9339    stfsux %3,%0,%2
9340    stfsu %3,%2(%0)"
9341   [(set_attr "type" "fpstore")
9342    (set_attr "update" "yes")
9343    (set_attr "indexed" "yes,no")])
9345 (define_insn "*movsf_update3"
9346   [(set (match_operand:SF 3 "gpc_reg_operand" "=r,r")
9347         (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    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9350         (plus:SI (match_dup 1) (match_dup 2)))]
9351   "TARGET_SOFT_FLOAT && TARGET_UPDATE
9352    && (!avoiding_indexed_address_p (SImode)
9353        || !gpc_reg_operand (operands[2], SImode))"
9354   "@
9355    lwzux %3,%0,%2
9356    lwzu %3,%2(%0)"
9357   [(set_attr "type" "load")
9358    (set_attr "update" "yes")
9359    (set_attr "indexed" "yes,no")])
9361 (define_insn "*movsf_update4"
9362   [(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9363                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9364         (match_operand:SF 3 "gpc_reg_operand" "r,r"))
9365    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9366         (plus:SI (match_dup 1) (match_dup 2)))]
9367   "TARGET_SOFT_FLOAT && TARGET_UPDATE
9368    && (!avoiding_indexed_address_p (SImode)
9369        || !gpc_reg_operand (operands[2], SImode))"
9370   "@
9371    stwux %3,%0,%2
9372    stwu %3,%2(%0)"
9373   [(set_attr "type" "store")
9374    (set_attr "update" "yes")
9375    (set_attr "indexed" "yes,no")])
9377 (define_insn "*movdf_update1"
9378   [(set (match_operand:DF 3 "gpc_reg_operand" "=d,d")
9379         (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9380                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9381    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9382         (plus:SI (match_dup 1) (match_dup 2)))]
9383   "TARGET_HARD_FLOAT && TARGET_UPDATE
9384    && (!avoiding_indexed_address_p (SImode)
9385        || !gpc_reg_operand (operands[2], SImode))"
9386   "@
9387    lfdux %3,%0,%2
9388    lfdu %3,%2(%0)"
9389   [(set_attr "type" "fpload")
9390    (set_attr "update" "yes")
9391    (set_attr "indexed" "yes,no")
9392    (set_attr "size" "64")])
9394 (define_insn "*movdf_update2"
9395   [(set (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9396                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9397         (match_operand:DF 3 "gpc_reg_operand" "d,d"))
9398    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9399         (plus:SI (match_dup 1) (match_dup 2)))]
9400   "TARGET_HARD_FLOAT && TARGET_UPDATE
9401    && (!avoiding_indexed_address_p (SImode)
9402        || !gpc_reg_operand (operands[2], SImode))"
9403   "@
9404    stfdux %3,%0,%2
9405    stfdu %3,%2(%0)"
9406   [(set_attr "type" "fpstore")
9407    (set_attr "update" "yes")
9408    (set_attr "indexed" "yes,no")])
9411 ;; After inserting conditional returns we can sometimes have
9412 ;; unnecessary register moves.  Unfortunately we cannot have a
9413 ;; modeless peephole here, because some single SImode sets have early
9414 ;; clobber outputs.  Although those sets expand to multi-ppc-insn
9415 ;; sequences, using get_attr_length here will smash the operands
9416 ;; array.  Neither is there an early_cobbler_p predicate.
9417 ;; Also this optimization interferes with scalars going into
9418 ;; altivec registers (the code does reloading through the FPRs).
9419 (define_peephole2
9420   [(set (match_operand:DF 0 "gpc_reg_operand")
9421         (match_operand:DF 1 "any_operand"))
9422    (set (match_operand:DF 2 "gpc_reg_operand")
9423         (match_dup 0))]
9424   "!TARGET_VSX
9425    && peep2_reg_dead_p (2, operands[0])"
9426   [(set (match_dup 2) (match_dup 1))])
9428 (define_peephole2
9429   [(set (match_operand:SF 0 "gpc_reg_operand")
9430         (match_operand:SF 1 "any_operand"))
9431    (set (match_operand:SF 2 "gpc_reg_operand")
9432         (match_dup 0))]
9433   "!TARGET_P8_VECTOR
9434    && peep2_reg_dead_p (2, operands[0])"
9435   [(set (match_dup 2) (match_dup 1))])
9438 ;; TLS support.
9440 (define_insn_and_split "*tls_gd<bits>"
9441   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9442         (unspec:P [(match_operand:P 1 "rs6000_tls_symbol_ref" "")
9443                    (match_operand:P 2 "gpc_reg_operand" "b")]
9444                   UNSPEC_TLSGD))]
9445   "HAVE_AS_TLS && TARGET_TLS_MARKERS"
9446   "addi %0,%2,%1@got@tlsgd"
9447   "&& TARGET_CMODEL != CMODEL_SMALL"
9448   [(set (match_dup 3)
9449         (high:P
9450             (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))
9451    (set (match_dup 0)
9452         (lo_sum:P (match_dup 3)
9453             (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))]
9455   operands[3] = gen_reg_rtx (<MODE>mode);
9457   [(set (attr "length")
9458      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9459                    (const_int 8)
9460                    (const_int 4)))])
9462 (define_insn "*tls_gd_high<bits>"
9463   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9464      (high:P
9465        (unspec:P [(match_operand:P 1 "rs6000_tls_symbol_ref" "")
9466                   (match_operand:P 2 "gpc_reg_operand" "b")]
9467                  UNSPEC_TLSGD)))]
9468   "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9469   "addis %0,%2,%1@got@tlsgd@ha")
9471 (define_insn "*tls_gd_low<bits>"
9472   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9473      (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
9474        (unspec:P [(match_operand:P 2 "rs6000_tls_symbol_ref" "")
9475                   (match_operand:P 3 "gpc_reg_operand" "b")]
9476                  UNSPEC_TLSGD)))]
9477   "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9478   "addi %0,%1,%2@got@tlsgd@l")
9480 (define_insn_and_split "*tls_ld<bits>"
9481   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9482         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")]
9483                   UNSPEC_TLSLD))]
9484   "HAVE_AS_TLS && TARGET_TLS_MARKERS"
9485   "addi %0,%1,%&@got@tlsld"
9486   "&& TARGET_CMODEL != CMODEL_SMALL"
9487   [(set (match_dup 2)
9488         (high:P
9489             (unspec:P [(match_dup 1)] UNSPEC_TLSLD)))
9490    (set (match_dup 0)
9491         (lo_sum:P (match_dup 2)
9492             (unspec:P [(match_dup 1)] UNSPEC_TLSLD)))]
9494   operands[2] = gen_reg_rtx (<MODE>mode);
9496   [(set (attr "length")
9497      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9498                    (const_int 8)
9499                    (const_int 4)))])
9501 (define_insn "*tls_ld_high<bits>"
9502   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9503      (high:P
9504        (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")]
9505                  UNSPEC_TLSLD)))]
9506   "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9507   "addis %0,%1,%&@got@tlsld@ha")
9509 (define_insn "*tls_ld_low<bits>"
9510   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9511      (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
9512        (unspec:P [(match_operand:P 2 "gpc_reg_operand" "b")]
9513                  UNSPEC_TLSLD)))]
9514   "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9515   "addi %0,%1,%&@got@tlsld@l")
9517 (define_insn "tls_dtprel_<bits>"
9518   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9519         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9520                    (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9521                   UNSPEC_TLSDTPREL))]
9522   "HAVE_AS_TLS"
9523   "addi %0,%1,%2@dtprel")
9525 (define_insn "tls_dtprel_ha_<bits>"
9526   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9527         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9528                    (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9529                   UNSPEC_TLSDTPRELHA))]
9530   "HAVE_AS_TLS"
9531   "addis %0,%1,%2@dtprel@ha")
9533 (define_insn "tls_dtprel_lo_<bits>"
9534   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9535         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9536                    (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9537                   UNSPEC_TLSDTPRELLO))]
9538   "HAVE_AS_TLS"
9539   "addi %0,%1,%2@dtprel@l")
9541 (define_insn_and_split "tls_got_dtprel_<bits>"
9542   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9543         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9544                    (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9545                   UNSPEC_TLSGOTDTPREL))]
9546   "HAVE_AS_TLS"
9547   "<ptrload> %0,%2@got@dtprel(%1)"
9548   "&& TARGET_CMODEL != CMODEL_SMALL"
9549   [(set (match_dup 3)
9550         (high:P
9551             (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))
9552    (set (match_dup 0)
9553         (lo_sum:P (match_dup 3)
9554             (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))]
9556   operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9558   [(set (attr "length")
9559      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9560                    (const_int 8)
9561                    (const_int 4)))])
9563 (define_insn "*tls_got_dtprel_high<bits>"
9564   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9565      (high:P
9566        (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9567                   (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9568                  UNSPEC_TLSGOTDTPREL)))]
9569   "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9570   "addis %0,%1,%2@got@dtprel@ha")
9572 (define_insn "*tls_got_dtprel_low<bits>"
9573   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9574      (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
9575          (unspec:P [(match_operand:P 3 "gpc_reg_operand" "b")
9576                     (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9577                    UNSPEC_TLSGOTDTPREL)))]
9578   "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9579   "<ptrload> %0,%2@got@dtprel@l(%1)")
9581 (define_insn "tls_tprel_<bits>"
9582   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9583         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9584                    (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9585                   UNSPEC_TLSTPREL))]
9586   "HAVE_AS_TLS"
9587   "addi %0,%1,%2@tprel")
9589 (define_insn "tls_tprel_ha_<bits>"
9590   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9591         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9592                    (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9593                   UNSPEC_TLSTPRELHA))]
9594   "HAVE_AS_TLS"
9595   "addis %0,%1,%2@tprel@ha")
9597 (define_insn "tls_tprel_lo_<bits>"
9598   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9599         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9600                    (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9601                   UNSPEC_TLSTPRELLO))]
9602   "HAVE_AS_TLS"
9603   "addi %0,%1,%2@tprel@l")
9605 ;; "b" output constraint here and on tls_tls input to support linker tls
9606 ;; optimization.  The linker may edit the instructions emitted by a
9607 ;; tls_got_tprel/tls_tls pair to addis,addi.
9608 (define_insn_and_split "tls_got_tprel_<bits>"
9609   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9610         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9611                    (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9612                   UNSPEC_TLSGOTTPREL))]
9613   "HAVE_AS_TLS"
9614   "<ptrload> %0,%2@got@tprel(%1)"
9615   "&& TARGET_CMODEL != CMODEL_SMALL"
9616   [(set (match_dup 3)
9617         (high:P
9618             (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))
9619    (set (match_dup 0)
9620         (lo_sum:P (match_dup 3)
9621             (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))]
9623   operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9625   [(set (attr "length")
9626      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9627                    (const_int 8)
9628                    (const_int 4)))])
9630 (define_insn "*tls_got_tprel_high<bits>"
9631   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9632      (high:P
9633        (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9634                   (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9635                  UNSPEC_TLSGOTTPREL)))]
9636   "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9637   "addis %0,%1,%2@got@tprel@ha")
9639 (define_insn "*tls_got_tprel_low<bits>"
9640   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9641      (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
9642          (unspec:P [(match_operand:P 3 "gpc_reg_operand" "b")
9643                     (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9644                    UNSPEC_TLSGOTTPREL)))]
9645   "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9646   "<ptrload> %0,%2@got@tprel@l(%1)")
9648 (define_insn "tls_tls_<bits>"
9649   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9650         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9651                    (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9652                   UNSPEC_TLSTLS))]
9653   "TARGET_ELF && HAVE_AS_TLS"
9654   "add %0,%1,%2@tls")
9656 (define_expand "tls_get_tpointer"
9657   [(set (match_operand:SI 0 "gpc_reg_operand")
9658         (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))]
9659   "TARGET_XCOFF && HAVE_AS_TLS"
9661   emit_insn (gen_tls_get_tpointer_internal ());
9662   emit_move_insn (operands[0], gen_rtx_REG (SImode, 3));
9663   DONE;
9666 (define_insn "tls_get_tpointer_internal"
9667   [(set (reg:SI 3)
9668         (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))
9669    (clobber (reg:SI LR_REGNO))]
9670   "TARGET_XCOFF && HAVE_AS_TLS"
9671   "bla __get_tpointer")
9673 (define_expand "tls_get_addr<mode>"
9674   [(set (match_operand:P 0 "gpc_reg_operand")
9675         (unspec:P [(match_operand:P 1 "gpc_reg_operand")
9676                    (match_operand:P 2 "gpc_reg_operand")] UNSPEC_TLSTLS))]
9677   "TARGET_XCOFF && HAVE_AS_TLS"
9679   emit_move_insn (gen_rtx_REG (Pmode, 3), operands[1]);
9680   emit_move_insn (gen_rtx_REG (Pmode, 4), operands[2]);
9681   emit_insn (gen_tls_get_addr_internal<mode> ());
9682   emit_move_insn (operands[0], gen_rtx_REG (Pmode, 3));
9683   DONE;
9686 (define_insn "tls_get_addr_internal<mode>"
9687   [(set (reg:P 3)
9688         (unspec:P [(reg:P 3) (reg:P 4)] UNSPEC_TLSTLS))
9689    (clobber (reg:P 0))
9690    (clobber (reg:P 4))
9691    (clobber (reg:P 5))
9692    (clobber (reg:P 11))
9693    (clobber (reg:CC CR0_REGNO))
9694    (clobber (reg:P LR_REGNO))]
9695   "TARGET_XCOFF && HAVE_AS_TLS"
9696   "bla __tls_get_addr")
9698 ;; Next come insns related to the calling sequence.
9700 ;; First, an insn to allocate new stack space for dynamic use (e.g., alloca).
9701 ;; We move the back-chain and decrement the stack pointer.
9703 ;; Operand1 is more naturally reg_or_short_operand.  However, for a large
9704 ;; constant alloca, using that predicate will force the generic code to put
9705 ;; the constant size into a register before calling the expander.
9707 ;; As a result the expander would not have the constant size information
9708 ;; in those cases and would have to generate less efficient code.
9710 ;; Thus we allow reg_or_cint_operand instead so that the expander can see
9711 ;; the constant size.  The value is forced into a register if necessary.
9713 (define_expand "allocate_stack"
9714   [(set (match_operand 0 "gpc_reg_operand")
9715         (minus (reg 1) (match_operand 1 "reg_or_cint_operand")))
9716    (set (reg 1)
9717         (minus (reg 1) (match_dup 1)))]
9718   ""
9720   rtx chain = gen_reg_rtx (Pmode);
9721   rtx stack_bot = gen_rtx_MEM (Pmode, stack_pointer_rtx);
9722   rtx neg_op0;
9723   rtx insn, par, set, mem;
9725   /* By allowing reg_or_cint_operand as the predicate we can get
9726      better code for stack-clash-protection because we do not lose
9727      size information.  But the rest of the code expects the operand
9728      to be reg_or_short_operand.  If it isn't, then force it into
9729      a register.  */
9730   rtx orig_op1 = operands[1];
9731   if (!reg_or_short_operand (operands[1], Pmode))
9732     operands[1] = force_reg (Pmode, operands[1]);
9734   emit_move_insn (chain, stack_bot);
9736   /* Check stack bounds if necessary.  */
9737   if (crtl->limit_stack)
9738     {
9739       rtx available;
9740       available = expand_binop (Pmode, sub_optab,
9741                                 stack_pointer_rtx, stack_limit_rtx,
9742                                 NULL_RTX, 1, OPTAB_WIDEN);
9743       emit_insn (gen_cond_trap (LTU, available, operands[1], const0_rtx));
9744     }
9746   /* Allocate and probe if requested.
9747      This may look similar to the loop we use for prologue allocations,
9748      but it is critically different.  For the former we know the loop
9749      will iterate, but do not know that generally here.  The former
9750      uses that knowledge to rotate the loop.  Combining them would be
9751      possible with some performance cost.  */
9752   if (flag_stack_clash_protection)
9753     {
9754       rtx rounded_size, last_addr, residual;
9755       HOST_WIDE_INT probe_interval;
9756       compute_stack_clash_protection_loop_data (&rounded_size, &last_addr,
9757                                                 &residual, &probe_interval,
9758                                                 orig_op1);
9759       
9760       /* We do occasionally get in here with constant sizes, we might
9761          as well do a reasonable job when we obviously can.  */
9762       if (rounded_size != const0_rtx)
9763         {
9764           rtx loop_lab, end_loop;
9765           bool rotated = CONST_INT_P (rounded_size);
9766           rtx update = GEN_INT (-probe_interval);
9767           if (probe_interval > 32768)
9768             update = force_reg (Pmode, update);
9770           emit_stack_clash_protection_probe_loop_start (&loop_lab, &end_loop,
9771                                                         last_addr, rotated);
9773           if (Pmode == SImode)
9774             emit_insn (gen_movsi_update_stack (stack_pointer_rtx,
9775                                                stack_pointer_rtx,
9776                                                update, chain));
9777           else
9778             emit_insn (gen_movdi_di_update_stack (stack_pointer_rtx,
9779                                                   stack_pointer_rtx,
9780                                                   update, chain));
9781           emit_stack_clash_protection_probe_loop_end (loop_lab, end_loop,
9782                                                       last_addr, rotated);
9783         }
9785       /* Now handle residuals.  We just have to set operands[1] correctly
9786          and let the rest of the expander run.  */
9787       operands[1] = residual;
9788     }
9790   if (!(CONST_INT_P (operands[1])
9791         && IN_RANGE (INTVAL (operands[1]), -32767, 32768)))
9792     {
9793       operands[1] = force_reg (Pmode, operands[1]);
9794       neg_op0 = gen_reg_rtx (Pmode);
9795       if (TARGET_32BIT)
9796         emit_insn (gen_negsi2 (neg_op0, operands[1]));
9797       else
9798         emit_insn (gen_negdi2 (neg_op0, operands[1]));
9799     }
9800   else
9801     neg_op0 = GEN_INT (-INTVAL (operands[1]));
9803   insn = emit_insn ((* ((TARGET_32BIT) ? gen_movsi_update_stack
9804                                        : gen_movdi_di_update_stack))
9805                         (stack_pointer_rtx, stack_pointer_rtx, neg_op0,
9806                          chain));
9807   /* Since we didn't use gen_frame_mem to generate the MEM, grab
9808      it now and set the alias set/attributes. The above gen_*_update
9809      calls will generate a PARALLEL with the MEM set being the first
9810      operation. */
9811   par = PATTERN (insn);
9812   gcc_assert (GET_CODE (par) == PARALLEL);
9813   set = XVECEXP (par, 0, 0);
9814   gcc_assert (GET_CODE (set) == SET);
9815   mem = SET_DEST (set);
9816   gcc_assert (MEM_P (mem));
9817   MEM_NOTRAP_P (mem) = 1;
9818   set_mem_alias_set (mem, get_frame_alias_set ());
9820   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
9821   DONE;
9824 ;; These patterns say how to save and restore the stack pointer.  We need not
9825 ;; save the stack pointer at function level since we are careful to
9826 ;; preserve the backchain.  At block level, we have to restore the backchain
9827 ;; when we restore the stack pointer.
9829 ;; For nonlocal gotos, we must save both the stack pointer and its
9830 ;; backchain and restore both.  Note that in the nonlocal case, the
9831 ;; save area is a memory location.
9833 (define_expand "save_stack_function"
9834   [(match_operand 0 "any_operand")
9835    (match_operand 1 "any_operand")]
9836   ""
9837   "DONE;")
9839 (define_expand "restore_stack_function"
9840   [(match_operand 0 "any_operand")
9841    (match_operand 1 "any_operand")]
9842   ""
9843   "DONE;")
9845 ;; Adjust stack pointer (op0) to a new value (op1).
9846 ;; First copy old stack backchain to new location, and ensure that the
9847 ;; scheduler won't reorder the sp assignment before the backchain write.
9848 (define_expand "restore_stack_block"
9849   [(set (match_dup 2) (match_dup 3))
9850    (set (match_dup 4) (match_dup 2))
9851    (match_dup 5)
9852    (set (match_operand 0 "register_operand")
9853         (match_operand 1 "register_operand"))]
9854   ""
9856   rtvec p;
9858   operands[1] = force_reg (Pmode, operands[1]);
9859   operands[2] = gen_reg_rtx (Pmode);
9860   operands[3] = gen_frame_mem (Pmode, operands[0]);
9861   operands[4] = gen_frame_mem (Pmode, operands[1]);
9862   p = rtvec_alloc (1);
9863   RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
9864                                   const0_rtx);
9865   operands[5] = gen_rtx_PARALLEL (VOIDmode, p);
9868 (define_expand "save_stack_nonlocal"
9869   [(set (match_dup 3) (match_dup 4))
9870    (set (match_operand 0 "memory_operand") (match_dup 3))
9871    (set (match_dup 2) (match_operand 1 "register_operand"))]
9872   ""
9874   int units_per_word = (TARGET_32BIT) ? 4 : 8;
9876   /* Copy the backchain to the first word, sp to the second.  */
9877   operands[0] = adjust_address_nv (operands[0], Pmode, 0);
9878   operands[2] = adjust_address_nv (operands[0], Pmode, units_per_word);
9879   operands[3] = gen_reg_rtx (Pmode);
9880   operands[4] = gen_frame_mem (Pmode, operands[1]);
9883 (define_expand "restore_stack_nonlocal"
9884   [(set (match_dup 2) (match_operand 1 "memory_operand"))
9885    (set (match_dup 3) (match_dup 4))
9886    (set (match_dup 5) (match_dup 2))
9887    (match_dup 6)
9888    (set (match_operand 0 "register_operand") (match_dup 3))]
9889   ""
9891   int units_per_word = (TARGET_32BIT) ? 4 : 8;
9892   rtvec p;
9894   /* Restore the backchain from the first word, sp from the second.  */
9895   operands[2] = gen_reg_rtx (Pmode);
9896   operands[3] = gen_reg_rtx (Pmode);
9897   operands[1] = adjust_address_nv (operands[1], Pmode, 0);
9898   operands[4] = adjust_address_nv (operands[1], Pmode, units_per_word);
9899   operands[5] = gen_frame_mem (Pmode, operands[3]);
9900   p = rtvec_alloc (1);
9901   RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
9902                                   const0_rtx);
9903   operands[6] = gen_rtx_PARALLEL (VOIDmode, p);
9906 ;; TOC register handling.
9908 ;; Code to initialize the TOC register...
9910 (define_insn "load_toc_aix_si"
9911   [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
9912                    (unspec:SI [(const_int 0)] UNSPEC_TOC))
9913               (use (reg:SI 2))])]
9914   "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_32BIT"
9916   char buf[30];
9917   extern int need_toc_init;
9918   need_toc_init = 1;
9919   ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
9920   operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
9921   operands[2] = gen_rtx_REG (Pmode, 2);
9922   return "lwz %0,%1(%2)";
9924   [(set_attr "type" "load")
9925    (set_attr "update" "no")
9926    (set_attr "indexed" "no")])
9928 (define_insn "load_toc_aix_di"
9929   [(parallel [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
9930                    (unspec:DI [(const_int 0)] UNSPEC_TOC))
9931               (use (reg:DI 2))])]
9932   "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_64BIT"
9934   char buf[30];
9935   extern int need_toc_init;
9936   need_toc_init = 1;
9937   ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC",
9938                                !TARGET_ELF || !TARGET_MINIMAL_TOC);
9939   if (TARGET_ELF)
9940     strcat (buf, "@toc");
9941   operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
9942   operands[2] = gen_rtx_REG (Pmode, 2);
9943   return "ld %0,%1(%2)";
9945   [(set_attr "type" "load")
9946    (set_attr "update" "no")
9947    (set_attr "indexed" "no")])
9949 (define_insn "load_toc_v4_pic_si"
9950   [(set (reg:SI LR_REGNO)
9951         (unspec:SI [(const_int 0)] UNSPEC_TOC))]
9952   "DEFAULT_ABI == ABI_V4 && flag_pic == 1 && TARGET_32BIT"
9953   "bl _GLOBAL_OFFSET_TABLE_@local-4"
9954   [(set_attr "type" "branch")])
9956 (define_expand "load_toc_v4_PIC_1"
9957   [(parallel [(set (reg:SI LR_REGNO)
9958                    (match_operand:SI 0 "immediate_operand" "s"))
9959               (use (unspec [(match_dup 0)] UNSPEC_TOC))])]
9960   "TARGET_ELF && DEFAULT_ABI == ABI_V4
9961    && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
9962   "")
9964 (define_insn "load_toc_v4_PIC_1_normal"
9965   [(set (reg:SI LR_REGNO)
9966         (match_operand:SI 0 "immediate_operand" "s"))
9967    (use (unspec [(match_dup 0)] UNSPEC_TOC))]
9968   "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
9969    && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
9970   "bcl 20,31,%0\n%0:"
9971   [(set_attr "type" "branch")
9972    (set_attr "cannot_copy" "yes")])
9974 (define_insn "load_toc_v4_PIC_1_476"
9975   [(set (reg:SI LR_REGNO)
9976         (match_operand:SI 0 "immediate_operand" "s"))
9977    (use (unspec [(match_dup 0)] UNSPEC_TOC))]
9978   "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
9979    && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
9981   char name[32];
9982   static char templ[32];
9984   get_ppc476_thunk_name (name);
9985   sprintf (templ, "bl %s\n%%0:", name);
9986   return templ;
9988   [(set_attr "type" "branch")
9989    (set_attr "cannot_copy" "yes")])
9991 (define_expand "load_toc_v4_PIC_1b"
9992   [(parallel [(set (reg:SI LR_REGNO)
9993                    (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
9994                                (label_ref (match_operand 1 ""))]
9995                            UNSPEC_TOCPTR))
9996               (match_dup 1)])]
9997   "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
9998   "")
10000 (define_insn "load_toc_v4_PIC_1b_normal"
10001   [(set (reg:SI LR_REGNO)
10002         (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10003                     (label_ref (match_operand 1 "" ""))]
10004                 UNSPEC_TOCPTR))
10005    (match_dup 1)]
10006   "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10007   "bcl 20,31,$+8\;.long %0-$"
10008   [(set_attr "type" "branch")
10009    (set_attr "length" "8")])
10011 (define_insn "load_toc_v4_PIC_1b_476"
10012   [(set (reg:SI LR_REGNO)
10013         (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10014                     (label_ref (match_operand 1 "" ""))]
10015                 UNSPEC_TOCPTR))
10016    (match_dup 1)]
10017   "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10019   char name[32];
10020   static char templ[32];
10022   get_ppc476_thunk_name (name);
10023   sprintf (templ, "bl %s\;b $+8\;.long %%0-$", name);
10024   return templ;
10026   [(set_attr "type" "branch")
10027    (set_attr "length" "16")])
10029 (define_insn "load_toc_v4_PIC_2"
10030   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10031         (mem:SI (plus:SI
10032                   (match_operand:SI 1 "gpc_reg_operand" "b")
10033                   (const
10034                     (minus:SI (match_operand:SI 2 "immediate_operand" "s")
10035                               (match_operand:SI 3 "immediate_operand" "s"))))))]
10036   "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10037   "lwz %0,%2-%3(%1)"
10038   [(set_attr "type" "load")])
10040 (define_insn "load_toc_v4_PIC_3b"
10041   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10042         (plus:SI
10043           (match_operand:SI 1 "gpc_reg_operand" "b")
10044           (high:SI
10045             (const
10046               (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
10047                         (match_operand:SI 3 "symbol_ref_operand" "s"))))))]
10048   "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
10049   "addis %0,%1,%2-%3@ha")
10051 (define_insn "load_toc_v4_PIC_3c"
10052   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10053         (lo_sum:SI
10054           (match_operand:SI 1 "gpc_reg_operand" "b")
10055           (const
10056             (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
10057                       (match_operand:SI 3 "symbol_ref_operand" "s")))))]
10058   "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
10059   "addi %0,%1,%2-%3@l")
10061 ;; If the TOC is shared over a translation unit, as happens with all
10062 ;; the kinds of PIC that we support, we need to restore the TOC
10063 ;; pointer only when jumping over units of translation.
10064 ;; On Darwin, we need to reload the picbase.
10066 (define_expand "builtin_setjmp_receiver"
10067   [(use (label_ref (match_operand 0 "")))]
10068   "(DEFAULT_ABI == ABI_V4 && flag_pic == 1)
10069    || (TARGET_TOC && TARGET_MINIMAL_TOC)
10070    || (DEFAULT_ABI == ABI_DARWIN && flag_pic)"
10072 #if TARGET_MACHO
10073   if (DEFAULT_ABI == ABI_DARWIN)
10074     {
10075       rtx picrtx = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME);
10076       rtx picreg = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
10077       rtx tmplabrtx;
10078       char tmplab[20];
10080       crtl->uses_pic_offset_table = 1;
10081       ASM_GENERATE_INTERNAL_LABEL(tmplab, "LSJR",
10082                                   CODE_LABEL_NUMBER (operands[0]));
10083       tmplabrtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (tmplab));
10085       emit_insn (gen_load_macho_picbase (tmplabrtx));
10086       emit_move_insn (picreg, gen_rtx_REG (Pmode, LR_REGNO));
10087       emit_insn (gen_macho_correct_pic (picreg, picreg, picrtx, tmplabrtx));
10088     }
10089   else
10090 #endif
10091     rs6000_emit_load_toc_table (FALSE);
10092   DONE;
10095 ;; Largetoc support
10096 (define_insn "*largetoc_high"
10097   [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
10098         (high:DI
10099           (unspec [(match_operand:DI 1 "" "")
10100                    (match_operand:DI 2 "gpc_reg_operand" "b")]
10101                   UNSPEC_TOCREL)))]
10102    "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10103    "addis %0,%2,%1@toc@ha")
10105 (define_insn "*largetoc_high_aix<mode>"
10106   [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
10107         (high:P
10108           (unspec [(match_operand:P 1 "" "")
10109                    (match_operand:P 2 "gpc_reg_operand" "b")]
10110                   UNSPEC_TOCREL)))]
10111    "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10112    "addis %0,%1@u(%2)")
10114 (define_insn "*largetoc_high_plus"
10115   [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
10116         (high:DI
10117           (plus:DI
10118             (unspec [(match_operand:DI 1 "" "")
10119                      (match_operand:DI 2 "gpc_reg_operand" "b")]
10120                     UNSPEC_TOCREL)
10121             (match_operand:DI 3 "add_cint_operand" "n"))))]
10122    "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10123    "addis %0,%2,%1+%3@toc@ha")
10125 (define_insn "*largetoc_high_plus_aix<mode>"
10126   [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
10127         (high:P
10128           (plus:P
10129             (unspec [(match_operand:P 1 "" "")
10130                      (match_operand:P 2 "gpc_reg_operand" "b")]
10131                     UNSPEC_TOCREL)
10132             (match_operand:P 3 "add_cint_operand" "n"))))]
10133    "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10134    "addis %0,%1+%3@u(%2)")
10136 (define_insn "*largetoc_low"
10137   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
10138         (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b")
10139                    (match_operand:DI 2 "" "")))]
10140    "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10141    "addi %0,%1,%2@l")
10143 (define_insn "*largetoc_low_aix<mode>"
10144   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10145         (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
10146                    (match_operand:P 2 "" "")))]
10147    "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10148    "la %0,%2@l(%1)")
10150 (define_insn_and_split "*tocref<mode>"
10151   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
10152         (match_operand:P 1 "small_toc_ref" "R"))]
10153    "TARGET_TOC"
10154    "la %0,%a1"
10155    "&& TARGET_CMODEL != CMODEL_SMALL && reload_completed"
10156   [(set (match_dup 0) (high:P (match_dup 1)))
10157    (set (match_dup 0) (lo_sum:P (match_dup 0) (match_dup 1)))])
10159 ;; Elf specific ways of loading addresses for non-PIC code.
10160 ;; The output of this could be r0, but we make a very strong
10161 ;; preference for a base register because it will usually
10162 ;; be needed there.
10163 (define_insn "elf_high"
10164   [(set (match_operand:SI 0 "gpc_reg_operand" "=b*r")
10165         (high:SI (match_operand 1 "" "")))]
10166   "TARGET_ELF && !TARGET_64BIT && !flag_pic"
10167   "lis %0,%1@ha")
10169 (define_insn "elf_low"
10170   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10171         (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
10172                    (match_operand 2 "" "")))]
10173    "TARGET_ELF && !TARGET_64BIT && !flag_pic"
10174    "la %0,%2@l(%1)")
10176 (define_insn "*pltseq_tocsave_<mode>"
10177   [(set (match_operand:P 0 "memory_operand" "=m")
10178         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
10179                    (match_operand:P 2 "symbol_ref_operand" "s")
10180                    (match_operand:P 3 "" "")]
10181                   UNSPEC_PLTSEQ))]
10182   "TARGET_PLTSEQ
10183    && DEFAULT_ABI == ABI_ELFv2"
10185   return rs6000_pltseq_template (operands, 0);
10188 (define_insn "*pltseq_plt16_ha_<mode>"
10189   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10190         (unspec:P [(match_operand:P 1 "" "")
10191                    (match_operand:P 2 "symbol_ref_operand" "s")
10192                    (match_operand:P 3 "" "")]
10193                   UNSPEC_PLT16_HA))]
10194   "TARGET_PLTSEQ"
10196   return rs6000_pltseq_template (operands, 1);
10199 (define_insn "*pltseq_plt16_lo_<mode>"
10200   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10201         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
10202                    (match_operand:P 2 "symbol_ref_operand" "s")
10203                    (match_operand:P 3 "" "")]
10204                   UNSPEC_PLT16_LO))]
10205   "TARGET_PLTSEQ"
10207   return rs6000_pltseq_template (operands, 2);
10209   [(set_attr "type" "load")])
10211 (define_insn "*pltseq_mtctr_<mode>"
10212   [(set (match_operand:P 0 "register_operand" "=c")
10213         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "r")
10214                    (match_operand:P 2 "symbol_ref_operand" "s")
10215                    (match_operand:P 3 "" "")]
10216                   UNSPEC_PLTSEQ))]
10217   "TARGET_PLTSEQ"
10219   return rs6000_pltseq_template (operands, 3);
10222 ;; Call and call_value insns
10223 ;; For the purposes of expanding calls, Darwin is very similar to SYSV.
10224 (define_expand "call"
10225   [(parallel [(call (mem:SI (match_operand 0 "address_operand"))
10226                     (match_operand 1 ""))
10227               (use (match_operand 2 ""))
10228               (clobber (reg:SI LR_REGNO))])]
10229   ""
10231 #if TARGET_MACHO
10232   if (MACHOPIC_INDIRECT)
10233     operands[0] = machopic_indirect_call_target (operands[0]);
10234 #endif
10236   gcc_assert (MEM_P (operands[0]));
10238   operands[0] = XEXP (operands[0], 0);
10240   if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10241     rs6000_call_aix (NULL_RTX, operands[0], operands[1], operands[2]);
10242   else if (DEFAULT_ABI == ABI_V4)
10243     rs6000_call_sysv (NULL_RTX, operands[0], operands[1], operands[2]);
10244   else if (DEFAULT_ABI == ABI_DARWIN)
10245     rs6000_call_darwin (NULL_RTX, operands[0], operands[1], operands[2]);
10246   else
10247     gcc_unreachable ();
10249   DONE;
10252 (define_expand "call_value"
10253   [(parallel [(set (match_operand 0 "")
10254                    (call (mem:SI (match_operand 1 "address_operand"))
10255                          (match_operand 2 "")))
10256               (use (match_operand 3 ""))
10257               (clobber (reg:SI LR_REGNO))])]
10258   ""
10260 #if TARGET_MACHO
10261   if (MACHOPIC_INDIRECT)
10262     operands[1] = machopic_indirect_call_target (operands[1]);
10263 #endif
10265   gcc_assert (MEM_P (operands[1]));
10267   operands[1] = XEXP (operands[1], 0);
10269   if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10270     rs6000_call_aix (operands[0], operands[1], operands[2], operands[3]);
10271   else if (DEFAULT_ABI == ABI_V4)
10272     rs6000_call_sysv (operands[0], operands[1], operands[2], operands[3]);
10273   else if (DEFAULT_ABI == ABI_DARWIN)
10274     rs6000_call_darwin (operands[0], operands[1], operands[2], operands[3]);
10275   else
10276     gcc_unreachable ();
10278   DONE;
10281 ;; Call to function in current module.  No TOC pointer reload needed.
10282 ;; Operand2 is nonzero if we are using the V.4 calling sequence and
10283 ;; either the function was not prototyped, or it was prototyped as a
10284 ;; variable argument function.  It is > 0 if FP registers were passed
10285 ;; and < 0 if they were not.
10287 (define_insn "*call_local32"
10288   [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
10289          (match_operand 1))
10290    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10291    (clobber (reg:SI LR_REGNO))]
10292   "(INTVAL (operands[2]) & CALL_LONG) == 0"
10294   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10295     output_asm_insn ("crxor 6,6,6", operands);
10297   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10298     output_asm_insn ("creqv 6,6,6", operands);
10300   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z0@local" : "bl %z0";
10302   [(set_attr "type" "branch")
10303    (set_attr "length" "4,8")])
10305 (define_insn "*call_local64"
10306   [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
10307          (match_operand 1))
10308    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10309    (clobber (reg:DI LR_REGNO))]
10310   "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
10312   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10313     output_asm_insn ("crxor 6,6,6", operands);
10315   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10316     output_asm_insn ("creqv 6,6,6", operands);
10318   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z0@local" : "bl %z0";
10320   [(set_attr "type" "branch")
10321    (set_attr "length" "4,8")])
10323 (define_insn "*call_value_local32"
10324   [(set (match_operand 0 "" "")
10325         (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
10326               (match_operand 2)))
10327    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10328    (clobber (reg:SI LR_REGNO))]
10329   "(INTVAL (operands[3]) & CALL_LONG) == 0
10330    && !IS_NOMARK_TLSGETADDR (operands[2])"
10332   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10333     output_asm_insn ("crxor 6,6,6", operands);
10335   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10336     output_asm_insn ("creqv 6,6,6", operands);
10338   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z1@local" : "bl %z1";
10340   [(set_attr "type" "branch")
10341    (set_attr "length" "4,8")])
10344 (define_insn "*call_value_local64"
10345   [(set (match_operand 0 "" "")
10346         (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
10347               (match_operand 2)))
10348    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10349    (clobber (reg:DI LR_REGNO))]
10350   "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0
10351    && !IS_NOMARK_TLSGETADDR (operands[2])"
10353   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10354     output_asm_insn ("crxor 6,6,6", operands);
10356   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10357     output_asm_insn ("creqv 6,6,6", operands);
10359   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z1@local" : "bl %z1";
10361   [(set_attr "type" "branch")
10362    (set_attr "length" "4,8")])
10365 ;; A function pointer under System V is just a normal pointer
10366 ;; operands[0] is the function pointer
10367 ;; operands[1] is the tls call arg
10368 ;; operands[2] is the value FUNCTION_ARG returns for the VOID argument
10369 ;; which indicates how to set cr1
10371 (define_insn "*call_indirect_nonlocal_sysv<mode>"
10372   [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X"))
10373          (match_operand 1))
10374    (use (match_operand:SI 2 "immediate_operand" "n,n,n"))
10375    (clobber (reg:P LR_REGNO))]
10376   "DEFAULT_ABI == ABI_V4
10377    || DEFAULT_ABI == ABI_DARWIN"
10379   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10380     output_asm_insn ("crxor 6,6,6", operands);
10382   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10383     output_asm_insn ("creqv 6,6,6", operands);
10385   return rs6000_indirect_call_template (operands, 0);
10387   [(set_attr "type" "jmpreg")
10388    (set (attr "length")
10389         (cond [(and (and (match_test "!rs6000_speculate_indirect_jumps")
10390                          (match_test "which_alternative != 1"))
10391                     (match_test "(INTVAL (operands[2]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
10392                   (const_string "12")
10393                (ior (and (match_test "!rs6000_speculate_indirect_jumps")
10394                          (match_test "which_alternative != 1"))
10395                     (match_test "(INTVAL (operands[2]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
10396                   (const_string "8")]
10397               (const_string "4")))])
10399 (define_insn "*call_nonlocal_sysv<mode>"
10400   [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
10401          (match_operand 1))
10402    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10403    (clobber (reg:P LR_REGNO))]
10404   "(DEFAULT_ABI == ABI_DARWIN
10405    || (DEFAULT_ABI == ABI_V4
10406        && (INTVAL (operands[2]) & CALL_LONG) == 0))"
10408   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10409     output_asm_insn ("crxor 6,6,6", operands);
10411   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10412     output_asm_insn ("creqv 6,6,6", operands);
10414   return rs6000_call_template (operands, 0);
10416   [(set_attr "type" "branch,branch")
10417    (set_attr "length" "4,8")])
10419 (define_insn "*call_nonlocal_sysv_secure<mode>"
10420   [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
10421          (match_operand 1))
10422    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10423    (use (match_operand:SI 3 "register_operand" "r,r"))
10424    (clobber (reg:P LR_REGNO))]
10425   "(DEFAULT_ABI == ABI_V4
10426     && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0])
10427     && (INTVAL (operands[2]) & CALL_LONG) == 0)"
10429   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10430     output_asm_insn ("crxor 6,6,6", operands);
10432   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10433     output_asm_insn ("creqv 6,6,6", operands);
10435   return rs6000_call_template (operands, 0);
10437   [(set_attr "type" "branch,branch")
10438    (set_attr "length" "4,8")])
10440 (define_insn "*call_value_indirect_nonlocal_sysv<mode>"
10441   [(set (match_operand 0 "" "")
10442         (call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X"))
10443               (match_operand:P 2 "unspec_tls" "")))
10444    (use (match_operand:SI 3 "immediate_operand" "n,n,n"))
10445    (clobber (reg:P LR_REGNO))]
10446   "DEFAULT_ABI == ABI_V4
10447    || DEFAULT_ABI == ABI_DARWIN"
10449   if (IS_NOMARK_TLSGETADDR (operands[2]))
10450     rs6000_output_tlsargs (operands);
10452   else if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10453     output_asm_insn ("crxor 6,6,6", operands);
10455   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10456     output_asm_insn ("creqv 6,6,6", operands);
10458   return rs6000_indirect_call_template (operands, 1);
10460   [(set_attr "type" "jmpreg")
10461    (set (attr "length")
10462         (plus
10463           (if_then_else (ior (match_test "IS_NOMARK_TLSGETADDR (operands[2])")
10464                              (match_test "IS_V4_FP_ARGS (operands[3])"))
10465             (const_int 4)
10466             (const_int 0))
10467           (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
10468                              (match_test "which_alternative != 1"))
10469             (const_int 8)
10470             (const_int 4))))])
10472 (define_insn "*call_value_nonlocal_sysv<mode>"
10473   [(set (match_operand 0 "" "")
10474         (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s"))
10475               (match_operand:P 2 "unspec_tls" "")))
10476    (use (match_operand:SI 3 "immediate_operand" "n"))
10477    (clobber (reg:P LR_REGNO))]
10478   "(DEFAULT_ABI == ABI_DARWIN
10479     || (DEFAULT_ABI == ABI_V4
10480         && (INTVAL (operands[3]) & CALL_LONG) == 0))"
10482   if (IS_NOMARK_TLSGETADDR (operands[2]))
10483     rs6000_output_tlsargs (operands);
10485   else if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10486     output_asm_insn ("crxor 6,6,6", operands);
10488   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10489     output_asm_insn ("creqv 6,6,6", operands);
10491   return rs6000_call_template (operands, 1);
10493   [(set_attr "type" "branch")
10494    (set (attr "length")
10495         (if_then_else (ior (match_test "IS_NOMARK_TLSGETADDR (operands[2])")
10496                            (match_test "IS_V4_FP_ARGS (operands[3])"))
10497           (const_int 8)
10498           (const_int 4)))])
10500 (define_insn "*call_value_nonlocal_sysv_secure<mode>"
10501   [(set (match_operand 0 "" "")
10502         (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s"))
10503               (match_operand:P 2 "unspec_tls" "")))
10504    (use (match_operand:SI 3 "immediate_operand" "n"))
10505    (use (match_operand:SI 4 "register_operand" "r"))
10506    (clobber (reg:P LR_REGNO))]
10507   "(DEFAULT_ABI == ABI_V4
10508     && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1])
10509     && (INTVAL (operands[3]) & CALL_LONG) == 0)"
10511   if (IS_NOMARK_TLSGETADDR (operands[2]))
10512     rs6000_output_tlsargs (operands);
10514   else if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10515     output_asm_insn ("crxor 6,6,6", operands);
10517   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10518     output_asm_insn ("creqv 6,6,6", operands);
10520   return rs6000_call_template (operands, 1);
10522   [(set_attr "type" "branch")
10523    (set (attr "length")
10524         (if_then_else (ior (match_test "IS_NOMARK_TLSGETADDR (operands[2])")
10525                            (match_test "IS_V4_FP_ARGS (operands[3])"))
10526           (const_int 8)
10527           (const_int 4)))])
10529 ;; Call to AIX abi function in the same module.
10531 (define_insn "*call_local_aix<mode>"
10532   [(call (mem:SI (match_operand:P 0 "current_file_function_operand" "s"))
10533          (match_operand 1))
10534    (clobber (reg:P LR_REGNO))]
10535   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10536   "bl %z0"
10537   [(set_attr "type" "branch")])
10539 (define_insn "*call_value_local_aix<mode>"
10540   [(set (match_operand 0 "" "")
10541         (call (mem:SI (match_operand:P 1 "current_file_function_operand" "s"))
10542               (match_operand 2)))
10543    (clobber (reg:P LR_REGNO))]
10544   "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10545    && !IS_NOMARK_TLSGETADDR (operands[2])"
10546   "bl %z1"
10547   [(set_attr "type" "branch")])
10549 ;; Call to AIX abi function which may be in another module.
10550 ;; Restore the TOC pointer (r2) after the call.
10552 (define_insn "*call_nonlocal_aix<mode>"
10553   [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s"))
10554          (match_operand 1))
10555    (clobber (reg:P LR_REGNO))]
10556   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10558   return rs6000_call_template (operands, 0);
10560   [(set_attr "type" "branch")
10561    (set_attr "length" "8")])
10563 (define_insn "*call_value_nonlocal_aix<mode>"
10564   [(set (match_operand 0 "" "")
10565         (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s"))
10566               (match_operand:P 2 "unspec_tls" "")))
10567    (clobber (reg:P LR_REGNO))]
10568   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10570   if (IS_NOMARK_TLSGETADDR (operands[2]))
10571     rs6000_output_tlsargs (operands);
10573   return rs6000_call_template (operands, 1);
10575   [(set_attr "type" "branch")
10576    (set (attr "length")
10577         (if_then_else (match_test "IS_NOMARK_TLSGETADDR (operands[2])")
10578           (if_then_else (match_test "TARGET_CMODEL != CMODEL_SMALL")
10579             (const_int 16)
10580             (const_int 12))
10581           (const_int 8)))])
10583 ;; Call to indirect functions with the AIX abi using a 3 word descriptor.
10584 ;; Operand0 is the addresss of the function to call
10585 ;; Operand2 is the location in the function descriptor to load r2 from
10586 ;; Operand3 is the offset of the stack location holding the current TOC pointer
10588 (define_insn "*call_indirect_aix<mode>"
10589   [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X"))
10590          (match_operand 1))
10591    (use (match_operand:P 2 "memory_operand" "<ptrm>,<ptrm>,<ptrm>"))
10592    (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 3 "const_int_operand" "n,n,n")] UNSPEC_TOCSLOT))
10593    (clobber (reg:P LR_REGNO))]
10594   "DEFAULT_ABI == ABI_AIX"
10596   return rs6000_indirect_call_template (operands, 0);
10598   [(set_attr "type" "jmpreg")
10599    (set (attr "length")
10600         (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
10601                            (match_test "which_alternative != 1"))
10602                       (const_string "16")
10603                       (const_string "12")))])
10605 (define_insn "*call_value_indirect_aix<mode>"
10606   [(set (match_operand 0 "" "")
10607         (call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X"))
10608               (match_operand:P 2 "unspec_tls" "")))
10609    (use (match_operand:P 3 "memory_operand" "<ptrm>,<ptrm>,<ptrm>"))
10610    (set (reg:P TOC_REGNUM)
10611         (unspec:P [(match_operand:P 4 "const_int_operand" "n,n,n")]
10612                   UNSPEC_TOCSLOT))
10613    (clobber (reg:P LR_REGNO))]
10614   "DEFAULT_ABI == ABI_AIX"
10616   if (IS_NOMARK_TLSGETADDR (operands[2]))
10617     rs6000_output_tlsargs (operands);
10619   return rs6000_indirect_call_template (operands, 1);
10621   [(set_attr "type" "jmpreg")
10622    (set (attr "length")
10623         (plus
10624           (if_then_else (match_test "IS_NOMARK_TLSGETADDR (operands[2])")
10625             (if_then_else (match_test "TARGET_CMODEL != CMODEL_SMALL")
10626               (const_int 8)
10627               (const_int 4))
10628             (const_int 0))
10629           (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
10630                              (match_test "which_alternative != 1"))
10631             (const_string "16")
10632             (const_string "12"))))])
10634 ;; Call to indirect functions with the ELFv2 ABI.
10635 ;; Operand0 is the addresss of the function to call
10636 ;; Operand2 is the offset of the stack location holding the current TOC pointer
10638 (define_insn "*call_indirect_elfv2<mode>"
10639   [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X"))
10640          (match_operand 1))
10641    (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 2 "const_int_operand" "n,n,n")] UNSPEC_TOCSLOT))
10642    (clobber (reg:P LR_REGNO))]
10643   "DEFAULT_ABI == ABI_ELFv2"
10645   return rs6000_indirect_call_template (operands, 0);
10647   [(set_attr "type" "jmpreg")
10648    (set (attr "length")
10649         (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
10650                            (match_test "which_alternative != 1"))
10651                       (const_string "12")
10652                       (const_string "8")))])
10654 (define_insn "*call_value_indirect_elfv2<mode>"
10655   [(set (match_operand 0 "" "")
10656         (call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X"))
10657               (match_operand:P 2 "unspec_tls" "")))
10658    (set (reg:P TOC_REGNUM)
10659         (unspec:P [(match_operand:P 3 "const_int_operand" "n,n,n")]
10660                   UNSPEC_TOCSLOT))
10661    (clobber (reg:P LR_REGNO))]
10662   "DEFAULT_ABI == ABI_ELFv2"
10664   if (IS_NOMARK_TLSGETADDR (operands[2]))
10665     rs6000_output_tlsargs (operands);
10667   return rs6000_indirect_call_template (operands, 1);
10669   [(set_attr "type" "jmpreg")
10670    (set (attr "length")
10671         (plus
10672           (if_then_else (match_test "IS_NOMARK_TLSGETADDR (operands[2])")
10673             (if_then_else (match_test "TARGET_CMODEL != CMODEL_SMALL")
10674               (const_int 8)
10675               (const_int 4))
10676             (const_int 0))
10677           (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
10678                              (match_test "which_alternative != 1"))
10679             (const_string "12")
10680             (const_string "8"))))])
10682 ;; Call subroutine returning any type.
10683 (define_expand "untyped_call"
10684   [(parallel [(call (match_operand 0 "")
10685                     (const_int 0))
10686               (match_operand 1 "")
10687               (match_operand 2 "")])]
10688   ""
10690   int i;
10692   emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
10694   for (i = 0; i < XVECLEN (operands[2], 0); i++)
10695     {
10696       rtx set = XVECEXP (operands[2], 0, i);
10697       emit_move_insn (SET_DEST (set), SET_SRC (set));
10698     }
10700   /* The optimizer does not know that the call sets the function value
10701      registers we stored in the result block.  We avoid problems by
10702      claiming that all hard registers are used and clobbered at this
10703      point.  */
10704   emit_insn (gen_blockage ());
10706   DONE;
10709 ;; sibling call patterns
10710 (define_expand "sibcall"
10711   [(parallel [(call (mem:SI (match_operand 0 "address_operand"))
10712                     (match_operand 1 ""))
10713               (use (match_operand 2 ""))
10714               (simple_return)])]
10715   ""
10717 #if TARGET_MACHO
10718   if (MACHOPIC_INDIRECT)
10719     operands[0] = machopic_indirect_call_target (operands[0]);
10720 #endif
10722   gcc_assert (MEM_P (operands[0]));
10723   gcc_assert (CONST_INT_P (operands[1]));
10725   operands[0] = XEXP (operands[0], 0);
10727   if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10728     rs6000_sibcall_aix (NULL_RTX, operands[0], operands[1], operands[2]);
10729   else if (DEFAULT_ABI == ABI_V4)
10730     rs6000_sibcall_sysv (NULL_RTX, operands[0], operands[1], operands[2]);
10731   else if (DEFAULT_ABI == ABI_DARWIN)
10732     rs6000_sibcall_darwin (NULL_RTX, operands[0], operands[1], operands[2]);
10733   else
10734     gcc_unreachable ();
10736   DONE;
10739 (define_expand "sibcall_value"
10740   [(parallel [(set (match_operand 0 "register_operand")
10741                 (call (mem:SI (match_operand 1 "address_operand"))
10742                       (match_operand 2 "")))
10743               (use (match_operand 3 ""))
10744               (simple_return)])]
10745   ""
10747 #if TARGET_MACHO
10748   if (MACHOPIC_INDIRECT)
10749     operands[1] = machopic_indirect_call_target (operands[1]);
10750 #endif
10752   gcc_assert (MEM_P (operands[1]));
10753   gcc_assert (CONST_INT_P (operands[2]));
10755   operands[1] = XEXP (operands[1], 0);
10757   if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10758     rs6000_sibcall_aix (operands[0], operands[1], operands[2], operands[3]);
10759   else if (DEFAULT_ABI == ABI_V4)
10760     rs6000_sibcall_sysv (operands[0], operands[1], operands[2], operands[3]);
10761   else if (DEFAULT_ABI == ABI_DARWIN)
10762     rs6000_sibcall_darwin (operands[0], operands[1], operands[2], operands[3]);
10763   else
10764     gcc_unreachable ();
10766   DONE;
10769 (define_insn "*sibcall_local32"
10770   [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
10771          (match_operand 1))
10772    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10773    (simple_return)]
10774   "(INTVAL (operands[2]) & CALL_LONG) == 0"
10776   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10777     output_asm_insn ("crxor 6,6,6", operands);
10779   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10780     output_asm_insn ("creqv 6,6,6", operands);
10782   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z0@local" : "b %z0";
10784   [(set_attr "type" "branch")
10785    (set_attr "length" "4,8")])
10787 (define_insn "*sibcall_local64"
10788   [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
10789          (match_operand 1))
10790    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10791    (simple_return)]
10792   "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
10794   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10795     output_asm_insn ("crxor 6,6,6", operands);
10797   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10798     output_asm_insn ("creqv 6,6,6", operands);
10800   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z0@local" : "b %z0";
10802   [(set_attr "type" "branch")
10803    (set_attr "length" "4,8")])
10805 (define_insn "*sibcall_value_local32"
10806   [(set (match_operand 0 "" "")
10807         (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
10808               (match_operand 2)))
10809    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10810    (simple_return)]
10811   "(INTVAL (operands[3]) & CALL_LONG) == 0"
10813   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10814     output_asm_insn ("crxor 6,6,6", operands);
10816   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10817     output_asm_insn ("creqv 6,6,6", operands);
10819   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z1@local" : "b %z1";
10821   [(set_attr "type" "branch")
10822    (set_attr "length" "4,8")])
10824 (define_insn "*sibcall_value_local64"
10825   [(set (match_operand 0 "" "")
10826         (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
10827               (match_operand 2)))
10828    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10829    (simple_return)]
10830   "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
10832   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10833     output_asm_insn ("crxor 6,6,6", operands);
10835   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10836     output_asm_insn ("creqv 6,6,6", operands);
10838   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z1@local" : "b %z1";
10840   [(set_attr "type" "branch")
10841    (set_attr "length" "4,8")])
10843 (define_insn "*sibcall_indirect_nonlocal_sysv<mode>"
10844   [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X"))
10845          (match_operand 1))
10846    (use (match_operand:SI 2 "immediate_operand" "n,n,n"))
10847    (simple_return)]
10848   "DEFAULT_ABI == ABI_V4
10849    || DEFAULT_ABI == ABI_DARWIN"
10851   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10852     output_asm_insn ("crxor 6,6,6", operands);
10854   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10855     output_asm_insn ("creqv 6,6,6", operands);
10857   return rs6000_indirect_sibcall_template (operands, 0);
10859   [(set_attr "type" "jmpreg")
10860    (set (attr "length")
10861         (cond [(and (and (match_test "!rs6000_speculate_indirect_jumps")
10862                          (match_test "which_alternative != 1"))
10863                     (match_test "(INTVAL (operands[2]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
10864                   (const_string "12")
10865                (ior (and (match_test "!rs6000_speculate_indirect_jumps")
10866                          (match_test "which_alternative != 1"))
10867                    (match_test "(INTVAL (operands[2]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
10868                   (const_string "8")]
10869               (const_string "4")))])
10871 (define_insn "*sibcall_nonlocal_sysv<mode>"
10872   [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
10873          (match_operand 1))
10874    (use (match_operand 2 "immediate_operand" "O,n"))
10875    (simple_return)]
10876   "(DEFAULT_ABI == ABI_DARWIN
10877     || DEFAULT_ABI == ABI_V4)
10878    && (INTVAL (operands[2]) & CALL_LONG) == 0"
10880   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10881     output_asm_insn ("crxor 6,6,6", operands);
10883   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10884     output_asm_insn ("creqv 6,6,6", operands);
10886   return rs6000_sibcall_template (operands, 0);
10888   [(set_attr "type" "branch")
10889    (set_attr "length" "4,8")])
10891 (define_insn "*sibcall_value_indirect_nonlocal_sysv<mode>"
10892   [(set (match_operand 0 "" "")
10893         (call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X"))
10894               (match_operand 2)))
10895    (use (match_operand:SI 3 "immediate_operand" "n,n,n"))
10896    (simple_return)]
10897   "DEFAULT_ABI == ABI_V4
10898    || DEFAULT_ABI == ABI_DARWIN"
10900   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10901     output_asm_insn ("crxor 6,6,6", operands);
10903   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10904     output_asm_insn ("creqv 6,6,6", operands);
10906   return rs6000_indirect_sibcall_template (operands, 1);
10908   [(set_attr "type" "jmpreg")
10909    (set (attr "length")
10910         (cond [(and (and (match_test "!rs6000_speculate_indirect_jumps")
10911                          (match_test "which_alternative != 1"))
10912                     (match_test "(INTVAL (operands[3]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
10913                   (const_string "12")
10914                (ior (and (match_test "!rs6000_speculate_indirect_jumps")
10915                          (match_test "which_alternative != 1"))
10916                    (match_test "(INTVAL (operands[3]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
10917                   (const_string "8")]
10918               (const_string "4")))])
10920 (define_insn "*sibcall_value_nonlocal_sysv<mode>"
10921   [(set (match_operand 0 "" "")
10922         (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
10923               (match_operand 2)))
10924    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10925    (simple_return)]
10926   "(DEFAULT_ABI == ABI_DARWIN
10927     || DEFAULT_ABI == ABI_V4)
10928    && (INTVAL (operands[3]) & CALL_LONG) == 0"
10930   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10931     output_asm_insn ("crxor 6,6,6", operands);
10933   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10934     output_asm_insn ("creqv 6,6,6", operands);
10936   return rs6000_sibcall_template (operands, 1);
10938   [(set_attr "type" "branch")
10939    (set_attr "length" "4,8")])
10941 ;; AIX ABI sibling call patterns.
10943 (define_insn "*sibcall_aix<mode>"
10944   [(call (mem:SI (match_operand:P 0 "call_operand" "s,c"))
10945          (match_operand 1))
10946    (simple_return)]
10947   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10949   if (which_alternative == 0)
10950     return rs6000_sibcall_template (operands, 0);
10951   else
10952     return "b%T0";
10954   [(set_attr "type" "branch")])
10956 (define_insn "*sibcall_value_aix<mode>"
10957   [(set (match_operand 0 "" "")
10958         (call (mem:SI (match_operand:P 1 "call_operand" "s,c"))
10959               (match_operand 2)))
10960    (simple_return)]
10961   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10963   if (which_alternative == 0)
10964     return rs6000_sibcall_template (operands, 1);
10965   else
10966     return "b%T1";
10968   [(set_attr "type" "branch")])
10970 (define_expand "sibcall_epilogue"
10971   [(use (const_int 0))]
10972   ""
10974   if (!TARGET_SCHED_PROLOG)
10975     emit_insn (gen_blockage ());
10976   rs6000_emit_epilogue (TRUE);
10977   DONE;
10980 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
10981 ;; all of memory.  This blocks insns from being moved across this point.
10983 (define_insn "blockage"
10984   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCK)]
10985   ""
10986   ""
10987   [(set_attr "length" "0")])
10989 (define_expand "probe_stack_address"
10990   [(use (match_operand 0 "address_operand"))]
10991   ""
10993   operands[0] = gen_rtx_MEM (Pmode, operands[0]);
10994   MEM_VOLATILE_P (operands[0]) = 1;
10996   if (TARGET_64BIT)
10997     emit_insn (gen_probe_stack_di (operands[0]));
10998   else
10999     emit_insn (gen_probe_stack_si (operands[0]));
11000   DONE;
11003 (define_insn "probe_stack_<mode>"
11004   [(set (match_operand:P 0 "memory_operand" "=m")
11005         (unspec:P [(const_int 0)] UNSPEC_PROBE_STACK))]
11006   ""
11008   operands[1] = gen_rtx_REG (Pmode, 0);
11009   return "st<wd>%U0%X0 %1,%0";
11011   [(set_attr "type" "store")
11012    (set (attr "update")
11013         (if_then_else (match_operand 0 "update_address_mem")
11014                       (const_string "yes")
11015                       (const_string "no")))
11016    (set (attr "indexed")
11017         (if_then_else (match_operand 0 "indexed_address_mem")
11018                       (const_string "yes")
11019                       (const_string "no")))])
11021 (define_insn "probe_stack_range<P:mode>"
11022   [(set (match_operand:P 0 "register_operand" "=&r")
11023         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
11024                             (match_operand:P 2 "register_operand" "r")
11025                             (match_operand:P 3 "register_operand" "r")]
11026                            UNSPECV_PROBE_STACK_RANGE))]
11027   ""
11028   "* return output_probe_stack_range (operands[0], operands[2], operands[3]);"
11029   [(set_attr "type" "three")])
11031 ;; Compare insns are next.  Note that the RS/6000 has two types of compares,
11032 ;; signed & unsigned, and one type of branch.
11034 ;; Start with the DEFINE_EXPANDs to generate the rtl for compares, scc
11035 ;; insns, and branches.
11037 (define_expand "cbranch<mode>4"
11038   [(use (match_operator 0 "comparison_operator"
11039          [(match_operand:GPR 1 "gpc_reg_operand")
11040           (match_operand:GPR 2 "reg_or_short_operand")]))
11041    (use (match_operand 3))]
11042   ""
11044   /* Take care of the possibility that operands[2] might be negative but
11045      this might be a logical operation.  That insn doesn't exist.  */
11046   if (CONST_INT_P (operands[2])
11047       && INTVAL (operands[2]) < 0)
11048     {
11049       operands[2] = force_reg (<MODE>mode, operands[2]);
11050       operands[0] = gen_rtx_fmt_ee (GET_CODE (operands[0]),
11051                                     GET_MODE (operands[0]),
11052                                     operands[1], operands[2]);
11053    }
11055   rs6000_emit_cbranch (<MODE>mode, operands);
11056   DONE;
11059 (define_expand "cbranch<mode>4"
11060   [(use (match_operator 0 "comparison_operator"
11061          [(match_operand:FP 1 "gpc_reg_operand")
11062           (match_operand:FP 2 "gpc_reg_operand")]))
11063    (use (match_operand 3))]
11064   ""
11066   rs6000_emit_cbranch (<MODE>mode, operands);
11067   DONE;
11070 (define_expand "cstore<mode>4_signed"
11071   [(use (match_operator 1 "signed_comparison_operator"
11072          [(match_operand:P 2 "gpc_reg_operand")
11073           (match_operand:P 3 "gpc_reg_operand")]))
11074    (clobber (match_operand:P 0 "gpc_reg_operand"))]
11075   ""
11077   enum rtx_code cond_code = GET_CODE (operands[1]);
11079   rtx op0 = operands[0];
11080   rtx op1 = operands[2];
11081   rtx op2 = operands[3];
11083   if (cond_code == GE || cond_code == LT)
11084     {
11085       cond_code = swap_condition (cond_code);
11086       std::swap (op1, op2);
11087     }
11089   rtx tmp1 = gen_reg_rtx (<MODE>mode);
11090   rtx tmp2 = gen_reg_rtx (<MODE>mode);
11091   rtx tmp3 = gen_reg_rtx (<MODE>mode);
11093   int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11094   emit_insn (gen_lshr<mode>3 (tmp1, op1, GEN_INT (sh)));
11095   emit_insn (gen_ashr<mode>3 (tmp2, op2, GEN_INT (sh)));
11097   emit_insn (gen_subf<mode>3_carry (tmp3, op1, op2));
11099   if (cond_code == LE)
11100     emit_insn (gen_add<mode>3_carry_in (op0, tmp1, tmp2));
11101   else
11102     {
11103       rtx tmp4 = gen_reg_rtx (<MODE>mode);
11104       emit_insn (gen_add<mode>3_carry_in (tmp4, tmp1, tmp2));
11105       emit_insn (gen_xor<mode>3 (op0, tmp4, const1_rtx));
11106     }
11108   DONE;
11111 (define_expand "cstore<mode>4_unsigned"
11112   [(use (match_operator 1 "unsigned_comparison_operator"
11113          [(match_operand:P 2 "gpc_reg_operand")
11114           (match_operand:P 3 "reg_or_short_operand")]))
11115    (clobber (match_operand:P 0 "gpc_reg_operand"))]
11116   ""
11118   enum rtx_code cond_code = GET_CODE (operands[1]);
11120   rtx op0 = operands[0];
11121   rtx op1 = operands[2];
11122   rtx op2 = operands[3];
11124   if (cond_code == GEU || cond_code == LTU)
11125     {
11126       cond_code = swap_condition (cond_code);
11127       std::swap (op1, op2);
11128     }
11130   if (!gpc_reg_operand (op1, <MODE>mode))
11131     op1 = force_reg (<MODE>mode, op1);
11132   if (!reg_or_short_operand (op2, <MODE>mode))
11133     op2 = force_reg (<MODE>mode, op2);
11135   rtx tmp = gen_reg_rtx (<MODE>mode);
11136   rtx tmp2 = gen_reg_rtx (<MODE>mode);
11138   emit_insn (gen_subf<mode>3_carry (tmp, op1, op2));
11139   emit_insn (gen_subf<mode>3_carry_in_xx (tmp2));
11141   if (cond_code == LEU)
11142     emit_insn (gen_add<mode>3 (op0, tmp2, const1_rtx));
11143   else
11144     emit_insn (gen_neg<mode>2 (op0, tmp2));
11146   DONE;
11149 (define_expand "cstore_si_as_di"
11150   [(use (match_operator 1 "unsigned_comparison_operator"
11151          [(match_operand:SI 2 "gpc_reg_operand")
11152           (match_operand:SI 3 "reg_or_short_operand")]))
11153    (clobber (match_operand:SI 0 "gpc_reg_operand"))]
11154   ""
11156   int uns_flag = unsigned_comparison_operator (operands[1], VOIDmode) ? 1 : 0;
11157   enum rtx_code cond_code = signed_condition (GET_CODE (operands[1]));
11159   operands[2] = force_reg (SImode, operands[2]);
11160   operands[3] = force_reg (SImode, operands[3]);
11161   rtx op1 = gen_reg_rtx (DImode);
11162   rtx op2 = gen_reg_rtx (DImode);
11163   convert_move (op1, operands[2], uns_flag);
11164   convert_move (op2, operands[3], uns_flag);
11166   if (cond_code == GT || cond_code == LE)
11167     {
11168       cond_code = swap_condition (cond_code);
11169       std::swap (op1, op2);
11170     }
11172   rtx tmp = gen_reg_rtx (DImode);
11173   rtx tmp2 = gen_reg_rtx (DImode);
11174   emit_insn (gen_subdi3 (tmp, op1, op2));
11175   emit_insn (gen_lshrdi3 (tmp2, tmp, GEN_INT (63)));
11177   rtx tmp3;
11178   switch (cond_code)
11179     {
11180     default:
11181       gcc_unreachable ();
11182     case LT:
11183       tmp3 = tmp2;
11184       break;
11185     case GE:
11186       tmp3 = gen_reg_rtx (DImode);
11187       emit_insn (gen_xordi3 (tmp3, tmp2, const1_rtx));
11188       break;
11189     }
11191   convert_move (operands[0], tmp3, 1);
11193   DONE;
11196 (define_expand "cstore<mode>4_signed_imm"
11197   [(use (match_operator 1 "signed_comparison_operator"
11198          [(match_operand:GPR 2 "gpc_reg_operand")
11199           (match_operand:GPR 3 "immediate_operand")]))
11200    (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11201   ""
11203   bool invert = false;
11205   enum rtx_code cond_code = GET_CODE (operands[1]);
11207   rtx op0 = operands[0];
11208   rtx op1 = operands[2];
11209   HOST_WIDE_INT val = INTVAL (operands[3]);
11211   if (cond_code == GE || cond_code == GT)
11212     {
11213       cond_code = reverse_condition (cond_code);
11214       invert = true;
11215     }
11217   if (cond_code == LE)
11218     val++;
11220   rtx tmp = gen_reg_rtx (<MODE>mode);
11221   emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
11222   rtx x = gen_reg_rtx (<MODE>mode);
11223   if (val < 0)
11224     emit_insn (gen_and<mode>3 (x, op1, tmp));
11225   else
11226     emit_insn (gen_ior<mode>3 (x, op1, tmp));
11228   if (invert)
11229     {
11230       rtx tmp = gen_reg_rtx (<MODE>mode);
11231       emit_insn (gen_one_cmpl<mode>2 (tmp, x));
11232       x = tmp;
11233     }
11235   int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11236   emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
11238   DONE;
11241 (define_expand "cstore<mode>4_unsigned_imm"
11242   [(use (match_operator 1 "unsigned_comparison_operator"
11243          [(match_operand:GPR 2 "gpc_reg_operand")
11244           (match_operand:GPR 3 "immediate_operand")]))
11245    (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11246   ""
11248   bool invert = false;
11250   enum rtx_code cond_code = GET_CODE (operands[1]);
11252   rtx op0 = operands[0];
11253   rtx op1 = operands[2];
11254   HOST_WIDE_INT val = INTVAL (operands[3]);
11256   if (cond_code == GEU || cond_code == GTU)
11257     {
11258       cond_code = reverse_condition (cond_code);
11259       invert = true;
11260     }
11262   if (cond_code == LEU)
11263     val++;
11265   rtx tmp = gen_reg_rtx (<MODE>mode);
11266   rtx tmp2 = gen_reg_rtx (<MODE>mode);
11267   emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
11268   emit_insn (gen_one_cmpl<mode>2 (tmp2, op1));
11269   rtx x = gen_reg_rtx (<MODE>mode);
11270   if (val < 0)
11271     emit_insn (gen_ior<mode>3 (x, tmp, tmp2));
11272   else
11273     emit_insn (gen_and<mode>3 (x, tmp, tmp2));
11275   if (invert)
11276     {
11277       rtx tmp = gen_reg_rtx (<MODE>mode);
11278       emit_insn (gen_one_cmpl<mode>2 (tmp, x));
11279       x = tmp;
11280     }
11282   int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11283   emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
11285   DONE;
11288 (define_expand "cstore<mode>4"
11289   [(use (match_operator 1 "comparison_operator"
11290          [(match_operand:GPR 2 "gpc_reg_operand")
11291           (match_operand:GPR 3 "reg_or_short_operand")]))
11292    (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11293   ""
11295   /* Expanding EQ and NE directly to some machine instructions does not help
11296      but does hurt combine.  So don't.  */
11297   if (GET_CODE (operands[1]) == EQ)
11298     emit_insn (gen_eq<mode>3 (operands[0], operands[2], operands[3]));
11299   else if (<MODE>mode == Pmode
11300            && GET_CODE (operands[1]) == NE)
11301     emit_insn (gen_ne<mode>3 (operands[0], operands[2], operands[3]));
11302   else if (GET_CODE (operands[1]) == NE)
11303     {
11304       rtx tmp = gen_reg_rtx (<MODE>mode);
11305       emit_insn (gen_eq<mode>3 (tmp, operands[2], operands[3]));
11306       emit_insn (gen_xor<mode>3 (operands[0], tmp, const1_rtx));
11307     }
11309   /* If ISEL is fast, expand to it.  */
11310   else if (TARGET_ISEL)
11311     rs6000_emit_int_cmove (operands[0], operands[1], const1_rtx, const0_rtx);
11313   /* Expanding the unsigned comparisons helps a lot: all the neg_ltu
11314      etc. combinations magically work out just right.  */
11315   else if (<MODE>mode == Pmode
11316            && unsigned_comparison_operator (operands[1], VOIDmode))
11317     emit_insn (gen_cstore<mode>4_unsigned (operands[0], operands[1],
11318                                            operands[2], operands[3]));
11320   /* For comparisons smaller than Pmode we can cheaply do things in Pmode.  */
11321   else if (<MODE>mode == SImode && Pmode == DImode)
11322     emit_insn (gen_cstore_si_as_di (operands[0], operands[1],
11323                                     operands[2], operands[3]));
11325   /* For signed comparisons against a constant, we can do some simple
11326      bit-twiddling.  */
11327   else if (signed_comparison_operator (operands[1], VOIDmode)
11328            && CONST_INT_P (operands[3]))
11329     emit_insn (gen_cstore<mode>4_signed_imm (operands[0], operands[1],
11330                                              operands[2], operands[3]));
11332   /* And similarly for unsigned comparisons.  */
11333   else if (unsigned_comparison_operator (operands[1], VOIDmode)
11334            && CONST_INT_P (operands[3]))
11335     emit_insn (gen_cstore<mode>4_unsigned_imm (operands[0], operands[1],
11336                                                operands[2], operands[3]));
11338   /* We also do not want to use mfcr for signed comparisons.  */
11339   else if (<MODE>mode == Pmode
11340            && signed_comparison_operator (operands[1], VOIDmode))
11341     emit_insn (gen_cstore<mode>4_signed (operands[0], operands[1],
11342                                          operands[2], operands[3]));
11344   /* Everything else, use the mfcr brute force.  */
11345   else
11346     rs6000_emit_sCOND (<MODE>mode, operands);
11348   DONE;
11351 (define_expand "cstore<mode>4"
11352   [(use (match_operator 1 "comparison_operator"
11353          [(match_operand:FP 2 "gpc_reg_operand")
11354           (match_operand:FP 3 "gpc_reg_operand")]))
11355    (clobber (match_operand:SI 0 "gpc_reg_operand"))]
11356   ""
11358   rs6000_emit_sCOND (<MODE>mode, operands);
11359   DONE;
11363 (define_expand "stack_protect_set"
11364   [(match_operand 0 "memory_operand")
11365    (match_operand 1 "memory_operand")]
11366   ""
11368   if (rs6000_stack_protector_guard == SSP_TLS)
11369     {
11370       rtx reg = gen_rtx_REG (Pmode, rs6000_stack_protector_guard_reg);
11371       rtx offset = GEN_INT (rs6000_stack_protector_guard_offset);
11372       rtx addr = gen_rtx_PLUS (Pmode, reg, offset);
11373       operands[1] = gen_rtx_MEM (Pmode, addr);
11374     }
11376   if (TARGET_64BIT)
11377     emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
11378   else
11379     emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
11381   DONE;
11384 (define_insn "stack_protect_setsi"
11385   [(set (match_operand:SI 0 "memory_operand" "=m")
11386         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
11387    (set (match_scratch:SI 2 "=&r") (const_int 0))]
11388   "TARGET_32BIT"
11389   "lwz%U1%X1 %2,%1\;stw%U0%X0 %2,%0\;li %2,0"
11390   [(set_attr "type" "three")
11391    (set_attr "length" "12")])
11393 (define_insn "stack_protect_setdi"
11394   [(set (match_operand:DI 0 "memory_operand" "=Y")
11395         (unspec:DI [(match_operand:DI 1 "memory_operand" "Y")] UNSPEC_SP_SET))
11396    (set (match_scratch:DI 2 "=&r") (const_int 0))]
11397   "TARGET_64BIT"
11398   "ld%U1%X1 %2,%1\;std%U0%X0 %2,%0\;li %2,0"
11399   [(set_attr "type" "three")
11400    (set_attr "length" "12")])
11402 (define_expand "stack_protect_test"
11403   [(match_operand 0 "memory_operand")
11404    (match_operand 1 "memory_operand")
11405    (match_operand 2 "")]
11406   ""
11408   rtx guard = operands[1];
11410   if (rs6000_stack_protector_guard == SSP_TLS)
11411     {
11412       rtx reg = gen_rtx_REG (Pmode, rs6000_stack_protector_guard_reg);
11413       rtx offset = GEN_INT (rs6000_stack_protector_guard_offset);
11414       rtx addr = gen_rtx_PLUS (Pmode, reg, offset);
11415       guard = gen_rtx_MEM (Pmode, addr);
11416     }
11418   operands[1] = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, guard), UNSPEC_SP_TEST);
11419   rtx test = gen_rtx_EQ (VOIDmode, operands[0], operands[1]);
11420   rtx jump = gen_cbranchsi4 (test, operands[0], operands[1], operands[2]);
11421   emit_jump_insn (jump);
11423   DONE;
11426 (define_insn "stack_protect_testsi"
11427   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
11428         (unspec:CCEQ [(match_operand:SI 1 "memory_operand" "m,m")
11429                       (match_operand:SI 2 "memory_operand" "m,m")]
11430                      UNSPEC_SP_TEST))
11431    (set (match_scratch:SI 4 "=r,r") (const_int 0))
11432    (clobber (match_scratch:SI 3 "=&r,&r"))]
11433   "TARGET_32BIT"
11434   "@
11435    lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0
11436    lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;cmplw %0,%3,%4\;li %3,0\;li %4,0"
11437   [(set_attr "length" "16,20")])
11439 (define_insn "stack_protect_testdi"
11440   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
11441         (unspec:CCEQ [(match_operand:DI 1 "memory_operand" "Y,Y")
11442                       (match_operand:DI 2 "memory_operand" "Y,Y")]
11443                      UNSPEC_SP_TEST))
11444    (set (match_scratch:DI 4 "=r,r") (const_int 0))
11445    (clobber (match_scratch:DI 3 "=&r,&r"))]
11446   "TARGET_64BIT"
11447   "@
11448    ld%U1%X1 %3,%1\;ld%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0
11449    ld%U1%X1 %3,%1\;ld%U2%X2 %4,%2\;cmpld %0,%3,%4\;li %3,0\;li %4,0"
11450   [(set_attr "length" "16,20")])
11453 ;; Here are the actual compare insns.
11454 (define_insn "*cmp<mode>_signed"
11455   [(set (match_operand:CC 0 "cc_reg_operand" "=y")
11456         (compare:CC (match_operand:GPR 1 "gpc_reg_operand" "r")
11457                     (match_operand:GPR 2 "reg_or_short_operand" "rI")))]
11458   ""
11459   "cmp<wd>%I2 %0,%1,%2"
11460   [(set_attr "type" "cmp")])
11462 (define_insn "*cmp<mode>_unsigned"
11463   [(set (match_operand:CCUNS 0 "cc_reg_operand" "=y")
11464         (compare:CCUNS (match_operand:GPR 1 "gpc_reg_operand" "r")
11465                        (match_operand:GPR 2 "reg_or_u_short_operand" "rK")))]
11466   ""
11467   "cmpl<wd>%I2 %0,%1,%2"
11468   [(set_attr "type" "cmp")])
11470 ;; If we are comparing a register for equality with a large constant,
11471 ;; we can do this with an XOR followed by a compare.  But this is profitable
11472 ;; only if the large constant is only used for the comparison (and in this
11473 ;; case we already have a register to reuse as scratch).
11475 ;; For 64-bit registers, we could only do so if the constant's bit 15 is clear:
11476 ;; otherwise we'd need to XOR with FFFFFFFF????0000 which is not available.
11478 (define_peephole2
11479   [(set (match_operand:SI 0 "register_operand")
11480         (match_operand:SI 1 "logical_const_operand"))
11481    (set (match_dup 0) (match_operator:SI 3 "boolean_or_operator"
11482                        [(match_dup 0)
11483                         (match_operand:SI 2 "logical_const_operand")]))
11484    (set (match_operand:CC 4 "cc_reg_operand")
11485         (compare:CC (match_operand:SI 5 "gpc_reg_operand")
11486                     (match_dup 0)))
11487    (set (pc)
11488         (if_then_else (match_operator 6 "equality_operator"
11489                        [(match_dup 4) (const_int 0)])
11490                       (match_operand 7 "")
11491                       (match_operand 8 "")))]
11492   "peep2_reg_dead_p (3, operands[0])
11493    && peep2_reg_dead_p (4, operands[4])
11494    && REGNO (operands[0]) != REGNO (operands[5])"
11495  [(set (match_dup 0) (xor:SI (match_dup 5) (match_dup 9)))
11496   (set (match_dup 4) (compare:CC (match_dup 0) (match_dup 10)))
11497   (set (pc) (if_then_else (match_dup 6) (match_dup 7) (match_dup 8)))]
11500   /* Get the constant we are comparing against, and see what it looks like
11501      when sign-extended from 16 to 32 bits.  Then see what constant we could
11502      XOR with SEXTC to get the sign-extended value.  */
11503   rtx cnst = simplify_const_binary_operation (GET_CODE (operands[3]),
11504                                               SImode,
11505                                               operands[1], operands[2]);
11506   HOST_WIDE_INT c = INTVAL (cnst);
11507   HOST_WIDE_INT sextc = ((c & 0xffff) ^ 0x8000) - 0x8000;
11508   HOST_WIDE_INT xorv = c ^ sextc;
11510   operands[9] = GEN_INT (xorv);
11511   operands[10] = GEN_INT (sextc);
11514 ;; Only need to compare second words if first words equal
11515 (define_insn "*cmp<mode>_internal1"
11516   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
11517         (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
11518                       (match_operand:IBM128 2 "gpc_reg_operand" "d")))]
11519   "!TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode)
11520    && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
11521   "fcmpu %0,%1,%2\;bne %0,$+8\;fcmpu %0,%L1,%L2"
11522   [(set_attr "type" "fpcompare")
11523    (set_attr "length" "12")])
11525 (define_insn_and_split "*cmp<mode>_internal2"
11526   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
11527         (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
11528                       (match_operand:IBM128 2 "gpc_reg_operand" "d")))
11529     (clobber (match_scratch:DF 3 "=d"))
11530     (clobber (match_scratch:DF 4 "=d"))
11531     (clobber (match_scratch:DF 5 "=d"))
11532     (clobber (match_scratch:DF 6 "=d"))
11533     (clobber (match_scratch:DF 7 "=d"))
11534     (clobber (match_scratch:DF 8 "=d"))
11535     (clobber (match_scratch:DF 9 "=d"))
11536     (clobber (match_scratch:DF 10 "=d"))
11537     (clobber (match_scratch:GPR 11 "=b"))]
11538   "TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode)
11539    && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
11540   "#"
11541   "&& reload_completed"
11542   [(set (match_dup 3) (match_dup 14))
11543    (set (match_dup 4) (match_dup 15))
11544    (set (match_dup 9) (abs:DF (match_dup 5)))
11545    (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 3)))
11546    (set (pc) (if_then_else (ne (match_dup 0) (const_int 0))
11547                            (label_ref (match_dup 12))
11548                            (pc)))
11549    (set (match_dup 0) (compare:CCFP (match_dup 5) (match_dup 7)))
11550    (set (pc) (label_ref (match_dup 13)))
11551    (match_dup 12)
11552    (set (match_dup 10) (minus:DF (match_dup 5) (match_dup 7)))
11553    (set (match_dup 9) (minus:DF (match_dup 6) (match_dup 8)))
11554    (set (match_dup 9) (plus:DF (match_dup 10) (match_dup 9)))
11555    (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 4)))
11556    (match_dup 13)]
11558   REAL_VALUE_TYPE rv;
11559   const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
11560   const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
11562   operands[5] = simplify_gen_subreg (DFmode, operands[1], <MODE>mode, hi_word);
11563   operands[6] = simplify_gen_subreg (DFmode, operands[1], <MODE>mode, lo_word);
11564   operands[7] = simplify_gen_subreg (DFmode, operands[2], <MODE>mode, hi_word);
11565   operands[8] = simplify_gen_subreg (DFmode, operands[2], <MODE>mode, lo_word);
11566   operands[12] = gen_label_rtx ();
11567   operands[13] = gen_label_rtx ();
11568   real_inf (&rv);
11569   operands[14] = force_const_mem (DFmode,
11570                                   const_double_from_real_value (rv, DFmode));
11571   operands[15] = force_const_mem (DFmode,
11572                                   const_double_from_real_value (dconst0,
11573                                                                 DFmode));
11574   if (TARGET_TOC)
11575     {
11576       rtx tocref;
11577       tocref = create_TOC_reference (XEXP (operands[14], 0), operands[11]);
11578       operands[14] = gen_const_mem (DFmode, tocref);
11579       tocref = create_TOC_reference (XEXP (operands[15], 0), operands[11]);
11580       operands[15] = gen_const_mem (DFmode, tocref);
11581       set_mem_alias_set (operands[14], get_TOC_alias_set ());
11582       set_mem_alias_set (operands[15], get_TOC_alias_set ());
11583     }
11586 ;; Now we have the scc insns.  We can do some combinations because of the
11587 ;; way the machine works.
11589 ;; Note that this is probably faster if we can put an insn between the
11590 ;; mfcr and rlinm, but this is tricky.  Let's leave it for now.  In most
11591 ;; cases the insns below which don't use an intermediate CR field will
11592 ;; be used instead.
11593 (define_insn ""
11594   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
11595         (match_operator:GPR 1 "scc_comparison_operator"
11596                             [(match_operand 2 "cc_reg_operand" "y")
11597                              (const_int 0)]))]
11598   ""
11599   "mfcr %0%Q2\;rlwinm %0,%0,%J1,1"
11600   [(set (attr "type")
11601      (cond [(match_test "TARGET_MFCRF")
11602                 (const_string "mfcrf")
11603            ]
11604         (const_string "mfcr")))
11605    (set_attr "length" "8")])
11607 (define_insn_and_split ""
11608   [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
11609         (compare:CC (match_operator:SI 1 "scc_comparison_operator"
11610                                        [(match_operand 2 "cc_reg_operand" "y,y")
11611                                         (const_int 0)])
11612                     (const_int 0)))
11613    (set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
11614         (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
11615   "TARGET_32BIT"
11616   "@
11617    mfcr %3%Q2\;rlwinm. %3,%3,%J1,1
11618    #"
11619   "&& reload_completed"
11620   [(set (match_dup 3)
11621         (match_op_dup 1 [(match_dup 2) (const_int 0)]))
11622    (set (match_dup 0)
11623         (compare:CC (match_dup 3)
11624                     (const_int 0)))]
11625   ""
11626   [(set_attr "type" "shift")
11627    (set_attr "dot" "yes")
11628    (set_attr "length" "8,16")])
11630 (define_insn ""
11631   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11632         (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
11633                                       [(match_operand 2 "cc_reg_operand" "y")
11634                                        (const_int 0)])
11635                    (match_operand:SI 3 "const_int_operand" "n")))]
11636   ""
11638   int is_bit = ccr_bit (operands[1], 1);
11639   int put_bit = 31 - (INTVAL (operands[3]) & 31);
11640   int count;
11642   gcc_assert (is_bit != -1);
11643   if (is_bit >= put_bit)
11644     count = is_bit - put_bit;
11645   else
11646     count = 32 - (put_bit - is_bit);
11648   operands[4] = GEN_INT (count);
11649   operands[5] = GEN_INT (put_bit);
11651   return "mfcr %0%Q2\;rlwinm %0,%0,%4,%5,%5";
11653   [(set (attr "type")
11654      (cond [(match_test "TARGET_MFCRF")
11655                 (const_string "mfcrf")
11656            ]
11657         (const_string "mfcr")))
11658    (set_attr "length" "8")])
11660 (define_insn ""
11661   [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
11662         (compare:CC
11663          (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
11664                                        [(match_operand 2 "cc_reg_operand" "y,y")
11665                                         (const_int 0)])
11666                     (match_operand:SI 3 "const_int_operand" "n,n"))
11667          (const_int 0)))
11668    (set (match_operand:SI 4 "gpc_reg_operand" "=r,r")
11669         (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
11670                    (match_dup 3)))]
11671   ""
11673   int is_bit = ccr_bit (operands[1], 1);
11674   int put_bit = 31 - (INTVAL (operands[3]) & 31);
11675   int count;
11677   gcc_assert (is_bit != -1);
11678   /* Force split for non-cc0 compare.  */
11679   if (which_alternative == 1)
11680      return "#";
11682   if (is_bit >= put_bit)
11683     count = is_bit - put_bit;
11684   else
11685     count = 32 - (put_bit - is_bit);
11687   operands[5] = GEN_INT (count);
11688   operands[6] = GEN_INT (put_bit);
11690   return "mfcr %4%Q2\;rlwinm. %4,%4,%5,%6,%6";
11692   [(set_attr "type" "shift")
11693    (set_attr "dot" "yes")
11694    (set_attr "length" "8,16")])
11696 (define_split
11697   [(set (match_operand:CC 0 "cc_reg_not_cr0_operand")
11698         (compare:CC
11699          (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
11700                                        [(match_operand 2 "cc_reg_operand")
11701                                         (const_int 0)])
11702                     (match_operand:SI 3 "const_int_operand"))
11703          (const_int 0)))
11704    (set (match_operand:SI 4 "gpc_reg_operand")
11705         (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
11706                    (match_dup 3)))]
11707   "reload_completed"
11708   [(set (match_dup 4)
11709         (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
11710                    (match_dup 3)))
11711    (set (match_dup 0)
11712         (compare:CC (match_dup 4)
11713                     (const_int 0)))]
11714   "")
11717 (define_code_iterator cmp [eq ne lt ltu gt gtu le leu ge geu])
11718 (define_code_attr UNS [(eq "CC")
11719                        (ne "CC")
11720                        (lt "CC") (ltu "CCUNS")
11721                        (gt "CC") (gtu "CCUNS")
11722                        (le "CC") (leu "CCUNS")
11723                        (ge "CC") (geu "CCUNS")])
11724 (define_code_attr UNSu_ [(eq "")
11725                          (ne "")
11726                          (lt "") (ltu "u_")
11727                          (gt "") (gtu "u_")
11728                          (le "") (leu "u_")
11729                          (ge "") (geu "u_")])
11730 (define_code_attr UNSIK [(eq "I")
11731                          (ne "I")
11732                          (lt "I") (ltu "K")
11733                          (gt "I") (gtu "K")
11734                          (le "I") (leu "K")
11735                          (ge "I") (geu "K")])
11737 (define_insn_and_split "<code><GPR:mode><GPR2:mode>2_isel"
11738   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
11739         (cmp:GPR (match_operand:GPR2 1 "gpc_reg_operand" "r")
11740                  (match_operand:GPR2 2 "reg_or_<cmp:UNSu_>short_operand" "r<cmp:UNSIK>")))
11741    (clobber (match_scratch:GPR 3 "=r"))
11742    (clobber (match_scratch:GPR 4 "=r"))
11743    (clobber (match_scratch:<UNS> 5 "=y"))]
11744   "TARGET_ISEL
11745    && !(<CODE> == EQ && operands[2] == const0_rtx)
11746    && !(<CODE> == NE && operands[2] == const0_rtx
11747         && <GPR:MODE>mode == Pmode && <GPR2:MODE>mode == Pmode)"
11748   "#"
11749   "&& 1"
11750   [(pc)]
11752   rtx_code code = <CODE>;
11753   if (CONST_INT_P (operands[2]) && code != EQ && code != NE)
11754     {
11755       HOST_WIDE_INT val = INTVAL (operands[2]);
11756       if (code == LT && val != -0x8000)
11757         {
11758           code = LE;
11759           val--;
11760         }
11761       if (code == GT && val != 0x7fff)
11762         {
11763           code = GE;
11764           val++;
11765         }
11766       if (code == LTU && val != 0)
11767         {
11768           code = LEU;
11769           val--;
11770         }
11771       if (code == GTU && val != 0xffff)
11772         {
11773           code = GEU;
11774           val++;
11775         }
11776       operands[2] = GEN_INT (val);
11777     }
11779   if (code == NE || code == LE || code == GE || code == LEU || code == GEU)
11780     operands[3] = const0_rtx;
11781   else
11782     {
11783       if (GET_CODE (operands[3]) == SCRATCH)
11784         operands[3] = gen_reg_rtx (<GPR:MODE>mode);
11785       emit_move_insn (operands[3], const0_rtx);
11786     }
11788   if (GET_CODE (operands[4]) == SCRATCH)
11789     operands[4] = gen_reg_rtx (<GPR:MODE>mode);
11790   emit_move_insn (operands[4], const1_rtx);
11792   if (GET_CODE (operands[5]) == SCRATCH)
11793     operands[5] = gen_reg_rtx (<UNS>mode);
11795   rtx c1 = gen_rtx_COMPARE (<UNS>mode, operands[1], operands[2]);
11796   emit_insn (gen_rtx_SET (operands[5], c1));
11798   rtx c2 = gen_rtx_fmt_ee (code, <GPR:MODE>mode, operands[5], const0_rtx);
11799   rtx x = gen_rtx_IF_THEN_ELSE (<GPR:MODE>mode, c2, operands[4], operands[3]);
11800   emit_move_insn (operands[0], x);
11802   DONE;
11804   [(set (attr "cost")
11805         (if_then_else (match_test "(CONST_INT_P (operands[2]) && <CODE> != EQ)
11806                                    || <CODE> == NE
11807                                    || <CODE> == LE || <CODE> == GE
11808                                    || <CODE> == LEU || <CODE> == GEU")
11809                       (const_string "9")
11810                       (const_string "10")))])
11812 (define_mode_attr scc_eq_op2 [(SI "rKLI")
11813                               (DI "rKJI")])
11815 (define_expand "eq<mode>3"
11816   [(parallel [
11817      (set (match_operand:GPR 0 "gpc_reg_operand" "=r")
11818           (eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
11819                   (match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>")))
11820      (clobber (match_scratch:GPR 3 "=r"))
11821      (clobber (match_scratch:GPR 4 "=r"))])]
11822   ""
11824   if (TARGET_ISEL && operands[2] != const0_rtx)
11825     {
11826       emit_insn (gen_eq<mode><mode>2_isel (operands[0], operands[1],
11827                                            operands[2]));
11828       DONE;
11829     }
11832 (define_insn_and_split "*eq<mode>3"
11833   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
11834         (eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
11835                 (match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>")))
11836    (clobber (match_scratch:GPR 3 "=r"))
11837    (clobber (match_scratch:GPR 4 "=r"))]
11838   "!(TARGET_ISEL && operands[2] != const0_rtx)"
11839   "#"
11840   "&& 1"
11841   [(set (match_dup 4)
11842         (clz:GPR (match_dup 3)))
11843    (set (match_dup 0)
11844         (lshiftrt:GPR (match_dup 4)
11845                       (match_dup 5)))]
11847   operands[3] = rs6000_emit_eqne (<MODE>mode,
11848                                   operands[1], operands[2], operands[3]);
11850   if (GET_CODE (operands[4]) == SCRATCH)
11851     operands[4] = gen_reg_rtx (<MODE>mode);
11853   operands[5] = GEN_INT (exact_log2 (GET_MODE_BITSIZE (<MODE>mode)));
11855   [(set (attr "length")
11856         (if_then_else (match_test "operands[2] == const0_rtx")
11857                       (const_string "8")
11858                       (const_string "12")))])
11860 (define_expand "ne<mode>3"
11861   [(parallel [
11862      (set (match_operand:P 0 "gpc_reg_operand" "=r")
11863           (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
11864                 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")))
11865      (clobber (match_scratch:P 3 "=r"))
11866      (clobber (match_scratch:P 4 "=r"))
11867      (clobber (reg:P CA_REGNO))])]
11868   ""
11870   if (TARGET_ISEL && operands[2] != const0_rtx)
11871     {
11872       emit_insn (gen_ne<mode><mode>2_isel (operands[0], operands[1],
11873                                            operands[2]));
11874       DONE;
11875     }
11878 (define_insn_and_split "*ne<mode>3"
11879   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11880         (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
11881               (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")))
11882    (clobber (match_scratch:P 3 "=r"))
11883    (clobber (match_scratch:P 4 "=r"))
11884    (clobber (reg:P CA_REGNO))]
11885   "!(TARGET_ISEL && operands[2] != const0_rtx)"
11886   "#"
11887   "&& 1"
11888   [(parallel [(set (match_dup 4)
11889                    (plus:P (match_dup 3)
11890                            (const_int -1)))
11891               (set (reg:P CA_REGNO)
11892                    (ne:P (match_dup 3)
11893                          (const_int 0)))])
11894    (parallel [(set (match_dup 0)
11895                    (plus:P (plus:P (not:P (match_dup 4))
11896                                    (reg:P CA_REGNO))
11897                            (match_dup 3)))
11898               (clobber (reg:P CA_REGNO))])]
11900   operands[3] = rs6000_emit_eqne (<MODE>mode,
11901                                   operands[1], operands[2], operands[3]);
11903   if (GET_CODE (operands[4]) == SCRATCH)
11904     operands[4] = gen_reg_rtx (<MODE>mode);
11906   [(set (attr "length")
11907         (if_then_else (match_test "operands[2] == const0_rtx")
11908                       (const_string "8")
11909                       (const_string "12")))])
11911 (define_insn_and_split "*neg_eq_<mode>"
11912   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11913         (neg:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
11914                      (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
11915    (clobber (match_scratch:P 3 "=r"))
11916    (clobber (match_scratch:P 4 "=r"))
11917    (clobber (reg:P CA_REGNO))]
11918   ""
11919   "#"
11920   ""
11921   [(parallel [(set (match_dup 4)
11922                    (plus:P (match_dup 3)
11923                            (const_int -1)))
11924               (set (reg:P CA_REGNO)
11925                    (ne:P (match_dup 3)
11926                          (const_int 0)))])
11927    (parallel [(set (match_dup 0)
11928                    (plus:P (reg:P CA_REGNO)
11929                            (const_int -1)))
11930               (clobber (reg:P CA_REGNO))])]
11932   operands[3] = rs6000_emit_eqne (<MODE>mode,
11933                                   operands[1], operands[2], operands[3]);
11935   if (GET_CODE (operands[4]) == SCRATCH)
11936     operands[4] = gen_reg_rtx (<MODE>mode);
11938   [(set (attr "length")
11939         (if_then_else (match_test "operands[2] == const0_rtx")
11940                       (const_string "8")
11941                       (const_string "12")))])
11943 (define_insn_and_split "*neg_ne_<mode>"
11944   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11945         (neg:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
11946                      (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
11947    (clobber (match_scratch:P 3 "=r"))
11948    (clobber (match_scratch:P 4 "=r"))
11949    (clobber (reg:P CA_REGNO))]
11950   ""
11951   "#"
11952   ""
11953   [(parallel [(set (match_dup 4)
11954                    (neg:P (match_dup 3)))
11955               (set (reg:P CA_REGNO)
11956                    (eq:P (match_dup 3)
11957                          (const_int 0)))])
11958    (parallel [(set (match_dup 0)
11959                    (plus:P (reg:P CA_REGNO)
11960                            (const_int -1)))
11961               (clobber (reg:P CA_REGNO))])]
11963   operands[3] = rs6000_emit_eqne (<MODE>mode,
11964                                   operands[1], operands[2], operands[3]);
11966   if (GET_CODE (operands[4]) == SCRATCH)
11967     operands[4] = gen_reg_rtx (<MODE>mode);
11969   [(set (attr "length")
11970         (if_then_else (match_test "operands[2] == const0_rtx")
11971                       (const_string "8")
11972                       (const_string "12")))])
11974 (define_insn_and_split "*plus_eq_<mode>"
11975   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11976         (plus:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
11977                       (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
11978                 (match_operand:P 3 "gpc_reg_operand" "r")))
11979    (clobber (match_scratch:P 4 "=r"))
11980    (clobber (match_scratch:P 5 "=r"))
11981    (clobber (reg:P CA_REGNO))]
11982   ""
11983   "#"
11984   ""
11985   [(parallel [(set (match_dup 5)
11986                    (neg:P (match_dup 4)))
11987               (set (reg:P CA_REGNO)
11988                    (eq:P (match_dup 4)
11989                          (const_int 0)))])
11990    (parallel [(set (match_dup 0)
11991                    (plus:P (match_dup 3)
11992                            (reg:P CA_REGNO)))
11993               (clobber (reg:P CA_REGNO))])]
11995   operands[4] = rs6000_emit_eqne (<MODE>mode,
11996                                   operands[1], operands[2], operands[4]);
11998   if (GET_CODE (operands[5]) == SCRATCH)
11999     operands[5] = gen_reg_rtx (<MODE>mode);
12001   [(set (attr "length")
12002         (if_then_else (match_test "operands[2] == const0_rtx")
12003                       (const_string "8")
12004                       (const_string "12")))])
12006 (define_insn_and_split "*plus_ne_<mode>"
12007   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12008         (plus:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12009                       (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
12010                 (match_operand:P 3 "gpc_reg_operand" "r")))
12011    (clobber (match_scratch:P 4 "=r"))
12012    (clobber (match_scratch:P 5 "=r"))
12013    (clobber (reg:P CA_REGNO))]
12014   ""
12015   "#"
12016   ""
12017   [(parallel [(set (match_dup 5)
12018                    (plus:P (match_dup 4)
12019                            (const_int -1)))
12020               (set (reg:P CA_REGNO)
12021                    (ne:P (match_dup 4)
12022                          (const_int 0)))])
12023    (parallel [(set (match_dup 0)
12024                    (plus:P (match_dup 3)
12025                            (reg:P CA_REGNO)))
12026               (clobber (reg:P CA_REGNO))])]
12028   operands[4] = rs6000_emit_eqne (<MODE>mode,
12029                                   operands[1], operands[2], operands[4]);
12031   if (GET_CODE (operands[5]) == SCRATCH)
12032     operands[5] = 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 "*minus_eq_<mode>"
12040   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12041         (minus:P (match_operand:P 3 "gpc_reg_operand" "r")
12042                  (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12043                        (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12044    (clobber (match_scratch:P 4 "=r"))
12045    (clobber (match_scratch:P 5 "=r"))
12046    (clobber (reg:P CA_REGNO))]
12047   ""
12048   "#"
12049   ""
12050   [(parallel [(set (match_dup 5)
12051                    (plus:P (match_dup 4)
12052                            (const_int -1)))
12053               (set (reg:P CA_REGNO)
12054                    (ne:P (match_dup 4)
12055                          (const_int 0)))])
12056    (parallel [(set (match_dup 0)
12057                    (plus:P (plus:P (match_dup 3)
12058                                    (reg:P CA_REGNO))
12059                            (const_int -1)))
12060               (clobber (reg:P CA_REGNO))])]
12062   operands[4] = rs6000_emit_eqne (<MODE>mode,
12063                                   operands[1], operands[2], operands[4]);
12065   if (GET_CODE (operands[5]) == SCRATCH)
12066     operands[5] = gen_reg_rtx (<MODE>mode);
12068   [(set (attr "length")
12069         (if_then_else (match_test "operands[2] == const0_rtx")
12070                       (const_string "8")
12071                       (const_string "12")))])
12073 (define_insn_and_split "*minus_ne_<mode>"
12074   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12075         (minus:P (match_operand:P 3 "gpc_reg_operand" "r")
12076                  (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12077                        (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12078    (clobber (match_scratch:P 4 "=r"))
12079    (clobber (match_scratch:P 5 "=r"))
12080    (clobber (reg:P CA_REGNO))]
12081   ""
12082   "#"
12083   ""
12084   [(parallel [(set (match_dup 5)
12085                    (neg:P (match_dup 4)))
12086               (set (reg:P CA_REGNO)
12087                    (eq:P (match_dup 4)
12088                          (const_int 0)))])
12089    (parallel [(set (match_dup 0)
12090                    (plus:P (plus:P (match_dup 3)
12091                                    (reg:P CA_REGNO))
12092                            (const_int -1)))
12093               (clobber (reg:P CA_REGNO))])]
12095   operands[4] = rs6000_emit_eqne (<MODE>mode,
12096                                   operands[1], operands[2], operands[4]);
12098   if (GET_CODE (operands[5]) == SCRATCH)
12099     operands[5] = gen_reg_rtx (<MODE>mode);
12101   [(set (attr "length")
12102         (if_then_else (match_test "operands[2] == const0_rtx")
12103                       (const_string "8")
12104                       (const_string "12")))])
12106 (define_insn_and_split "*eqsi3_ext<mode>"
12107   [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
12108         (eq:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
12109                   (match_operand:SI 2 "scc_eq_operand" "rKLI")))
12110    (clobber (match_scratch:SI 3 "=r"))
12111    (clobber (match_scratch:SI 4 "=r"))]
12112   ""
12113   "#"
12114   ""
12115   [(set (match_dup 4)
12116         (clz:SI (match_dup 3)))
12117    (set (match_dup 0)
12118         (zero_extend:EXTSI
12119           (lshiftrt:SI (match_dup 4)
12120                        (const_int 5))))]
12122   operands[3] = rs6000_emit_eqne (SImode,
12123                                   operands[1], operands[2], operands[3]);
12125   if (GET_CODE (operands[4]) == SCRATCH)
12126     operands[4] = gen_reg_rtx (SImode);
12128   [(set (attr "length")
12129         (if_then_else (match_test "operands[2] == const0_rtx")
12130                       (const_string "8")
12131                       (const_string "12")))])
12133 (define_insn_and_split "*nesi3_ext<mode>"
12134   [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
12135         (ne:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
12136                   (match_operand:SI 2 "scc_eq_operand" "rKLI")))
12137    (clobber (match_scratch:SI 3 "=r"))
12138    (clobber (match_scratch:SI 4 "=r"))
12139    (clobber (match_scratch:EXTSI 5 "=r"))]
12140   "!TARGET_ISEL"
12141   "#"
12142   "&& 1"
12143   [(set (match_dup 4)
12144         (clz:SI (match_dup 3)))
12145    (set (match_dup 5)
12146         (zero_extend:EXTSI
12147           (lshiftrt:SI (match_dup 4)
12148                        (const_int 5))))
12149    (set (match_dup 0)
12150         (xor:EXTSI (match_dup 5)
12151                    (const_int 1)))]
12153   operands[3] = rs6000_emit_eqne (SImode,
12154                                   operands[1], operands[2], operands[3]);
12156   if (GET_CODE (operands[4]) == SCRATCH)
12157     operands[4] = gen_reg_rtx (SImode);
12158   if (GET_CODE (operands[5]) == SCRATCH)
12159     operands[5] = gen_reg_rtx (<MODE>mode);
12161   [(set (attr "length")
12162         (if_then_else (match_test "operands[2] == const0_rtx")
12163                       (const_string "12")
12164                       (const_string "16")))])
12166 ;; Conditional branches.
12167 ;; These either are a single bc insn, or a bc around a b.
12169 (define_insn "*cbranch"
12170   [(set (pc)
12171         (if_then_else (match_operator 1 "branch_comparison_operator"
12172                                       [(match_operand 2 "cc_reg_operand" "y")
12173                                        (const_int 0)])
12174                       (label_ref (match_operand 0))
12175                       (pc)))]
12176   ""
12178   return output_cbranch (operands[1], "%l0", 0, insn);
12180   [(set_attr "type" "branch")
12181    (set (attr "length")
12182         (if_then_else (and (ge (minus (match_dup 0) (pc))
12183                                (const_int -32768))
12184                            (lt (minus (match_dup 0) (pc))
12185                                (const_int 32764)))
12186                       (const_int 4)
12187                       (const_int 8)))])
12189 ;; Conditional return.
12190 (define_insn "*creturn"
12191   [(set (pc)
12192         (if_then_else (match_operator 0 "branch_comparison_operator"
12193                                       [(match_operand 1 "cc_reg_operand" "y")
12194                                        (const_int 0)])
12195                       (any_return)
12196                       (pc)))]
12197   "<return_pred>"
12199   return output_cbranch (operands[0], NULL, 0, insn);
12201   [(set_attr "type" "jmpreg")])
12203 ;; Logic on condition register values.
12205 ; This pattern matches things like
12206 ; (set (reg:CCEQ 68) (compare:CCEQ (ior:SI (gt:SI (reg:CCFP 68) (const_int 0))
12207 ;                                          (eq:SI (reg:CCFP 68) (const_int 0)))
12208 ;                                  (const_int 1)))
12209 ; which are generated by the branch logic.
12210 ; Prefer destructive operations where BT = BB (for crXX BT,BA,BB)
12212 (define_insn "cceq_ior_compare"
12213   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12214         (compare:CCEQ (match_operator:SI 1 "boolean_operator"
12215                         [(match_operator:SI 2
12216                                       "branch_positive_comparison_operator"
12217                                       [(match_operand 3
12218                                                       "cc_reg_operand" "y,y")
12219                                        (const_int 0)])
12220                          (match_operator:SI 4
12221                                       "branch_positive_comparison_operator"
12222                                       [(match_operand 5
12223                                                       "cc_reg_operand" "0,y")
12224                                        (const_int 0)])])
12225                       (const_int 1)))]
12226   ""
12227   "cr%q1 %E0,%j2,%j4"
12228   [(set_attr "type" "cr_logical")
12229    (set_attr "cr_logical_3op" "no,yes")])
12231 ; Why is the constant -1 here, but 1 in the previous pattern?
12232 ; Because ~1 has all but the low bit set.
12233 (define_insn "cceq_ior_compare_complement"
12234   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12235         (compare:CCEQ (match_operator:SI 1 "boolean_operator"
12236                         [(not:SI (match_operator:SI 2
12237                                       "branch_positive_comparison_operator"
12238                                       [(match_operand 3
12239                                                       "cc_reg_operand" "y,y")
12240                                        (const_int 0)]))
12241                          (match_operator:SI 4
12242                                 "branch_positive_comparison_operator"
12243                                 [(match_operand 5
12244                                                 "cc_reg_operand" "0,y")
12245                                  (const_int 0)])])
12246                       (const_int -1)))]
12247   ""
12248   "cr%q1 %E0,%j2,%j4"
12249   [(set_attr "type" "cr_logical")
12250    (set_attr "cr_logical_3op" "no,yes")])
12252 (define_insn "*cceq_rev_compare"
12253   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12254         (compare:CCEQ (match_operator:SI 1
12255                                       "branch_positive_comparison_operator"
12256                                       [(match_operand 2
12257                                                       "cc_reg_operand" "0,y")
12258                                        (const_int 0)])
12259                       (const_int 0)))]
12260   ""
12261   "crnot %E0,%j1"
12262   [(set_attr "type" "cr_logical")
12263    (set_attr "cr_logical_3op" "no,yes")])
12265 ;; If we are comparing the result of two comparisons, this can be done
12266 ;; using creqv or crxor.
12268 (define_insn_and_split ""
12269   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y")
12270         (compare:CCEQ (match_operator 1 "branch_comparison_operator"
12271                               [(match_operand 2 "cc_reg_operand" "y")
12272                                (const_int 0)])
12273                       (match_operator 3 "branch_comparison_operator"
12274                               [(match_operand 4 "cc_reg_operand" "y")
12275                                (const_int 0)])))]
12276   ""
12277   "#"
12278   ""
12279   [(set (match_dup 0) (compare:CCEQ (xor:SI (match_dup 1) (match_dup 3))
12280                                     (match_dup 5)))]
12282   int positive_1, positive_2;
12284   positive_1 = branch_positive_comparison_operator (operands[1],
12285                                                     GET_MODE (operands[1]));
12286   positive_2 = branch_positive_comparison_operator (operands[3],
12287                                                     GET_MODE (operands[3]));
12289   if (! positive_1)
12290     operands[1] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[2]),
12291                                                             GET_CODE (operands[1])),
12292                                   SImode,
12293                                   operands[2], const0_rtx);
12294   else if (GET_MODE (operands[1]) != SImode)
12295     operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), SImode,
12296                                   operands[2], const0_rtx);
12298   if (! positive_2)
12299     operands[3] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[4]),
12300                                                             GET_CODE (operands[3])),
12301                                   SImode,
12302                                   operands[4], const0_rtx);
12303   else if (GET_MODE (operands[3]) != SImode)
12304     operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SImode,
12305                                   operands[4], const0_rtx);
12307   if (positive_1 == positive_2)
12308     {
12309       operands[1] = gen_rtx_NOT (SImode, operands[1]);
12310       operands[5] = constm1_rtx;
12311     }
12312   else
12313     {
12314       operands[5] = const1_rtx;
12315     }
12318 ;; Unconditional branch and return.
12320 (define_insn "jump"
12321   [(set (pc)
12322         (label_ref (match_operand 0)))]
12323   ""
12324   "b %l0"
12325   [(set_attr "type" "branch")])
12327 (define_insn "<return_str>return"
12328   [(any_return)]
12329   "<return_pred>"
12330   "blr"
12331   [(set_attr "type" "jmpreg")])
12333 (define_expand "indirect_jump"
12334   [(set (pc) (match_operand 0 "register_operand"))]
12335  ""
12337   if (!rs6000_speculate_indirect_jumps) {
12338     rtx ccreg = gen_reg_rtx (CCmode);
12339     if (Pmode == DImode)
12340       emit_jump_insn (gen_indirect_jumpdi_nospec (operands[0], ccreg));
12341     else
12342       emit_jump_insn (gen_indirect_jumpsi_nospec (operands[0], ccreg));
12343     DONE;
12344   }
12347 (define_insn "*indirect_jump<mode>"
12348   [(set (pc)
12349         (match_operand:P 0 "register_operand" "c,*l"))]
12350   "rs6000_speculate_indirect_jumps"
12351   "b%T0"
12352   [(set_attr "type" "jmpreg")])
12354 (define_insn "indirect_jump<mode>_nospec"
12355   [(set (pc) (match_operand:P 0 "register_operand" "c,*l"))
12356    (clobber (match_operand:CC 1 "cc_reg_operand" "=y,y"))]
12357   "!rs6000_speculate_indirect_jumps"
12358   "crset %E1\;beq%T0- %1\;b $"
12359   [(set_attr "type" "jmpreg")
12360    (set_attr "length" "12")])
12362 ;; Table jump for switch statements:
12363 (define_expand "tablejump"
12364   [(use (match_operand 0))
12365    (use (label_ref (match_operand 1)))]
12366   ""
12368   if (rs6000_speculate_indirect_jumps)
12369     {
12370       if (TARGET_32BIT)
12371         emit_jump_insn (gen_tablejumpsi (operands[0], operands[1]));
12372       else
12373         emit_jump_insn (gen_tablejumpdi (operands[0], operands[1]));
12374     }
12375   else
12376     {
12377       rtx ccreg = gen_reg_rtx (CCmode);
12378       rtx jump;
12379       if (TARGET_32BIT)
12380         jump = gen_tablejumpsi_nospec (operands[0], operands[1], ccreg);
12381       else
12382         jump = gen_tablejumpdi_nospec (operands[0], operands[1], ccreg);
12383       emit_jump_insn (jump);
12384     }
12385   DONE;
12388 (define_expand "tablejumpsi"
12389   [(set (match_dup 3)
12390         (plus:SI (match_operand:SI 0)
12391                  (match_dup 2)))
12392    (parallel [(set (pc)
12393                    (match_dup 3))
12394               (use (label_ref (match_operand 1)))])]
12395   "TARGET_32BIT && rs6000_speculate_indirect_jumps"
12397   operands[0] = force_reg (SImode, operands[0]);
12398   operands[2] = force_reg (SImode, gen_rtx_LABEL_REF (SImode, operands[1]));
12399   operands[3] = gen_reg_rtx (SImode);
12402 (define_expand "tablejumpsi_nospec"
12403   [(set (match_dup 4)
12404         (plus:SI (match_operand:SI 0)
12405                  (match_dup 3)))
12406    (parallel [(set (pc)
12407                    (match_dup 4))
12408               (use (label_ref (match_operand 1)))
12409               (clobber (match_operand 2))])]
12410   "TARGET_32BIT && !rs6000_speculate_indirect_jumps"
12412   operands[0] = force_reg (SImode, operands[0]);
12413   operands[3] = force_reg (SImode, gen_rtx_LABEL_REF (SImode, operands[1]));
12414   operands[4] = gen_reg_rtx (SImode);
12417 (define_expand "tablejumpdi"
12418   [(set (match_dup 4)
12419         (sign_extend:DI (match_operand:SI 0 "lwa_operand")))
12420    (set (match_dup 3)
12421         (plus:DI (match_dup 4)
12422                  (match_dup 2)))
12423    (parallel [(set (pc)
12424                    (match_dup 3))
12425               (use (label_ref (match_operand 1)))])]
12426   "TARGET_64BIT && rs6000_speculate_indirect_jumps"
12428   operands[2] = force_reg (DImode, gen_rtx_LABEL_REF (DImode, operands[1]));
12429   operands[3] = gen_reg_rtx (DImode);
12430   operands[4] = gen_reg_rtx (DImode);
12433 (define_expand "tablejumpdi_nospec"
12434   [(set (match_dup 5)
12435         (sign_extend:DI (match_operand:SI 0 "lwa_operand")))
12436    (set (match_dup 4)
12437         (plus:DI (match_dup 5)
12438                  (match_dup 3)))
12439    (parallel [(set (pc)
12440                    (match_dup 4))
12441               (use (label_ref (match_operand 1)))
12442               (clobber (match_operand 2))])]
12443   "TARGET_64BIT && !rs6000_speculate_indirect_jumps"
12445   operands[3] = force_reg (DImode, gen_rtx_LABEL_REF (DImode, operands[1]));
12446   operands[4] = gen_reg_rtx (DImode);
12447   operands[5] = gen_reg_rtx (DImode);
12450 (define_insn "*tablejump<mode>_internal1"
12451   [(set (pc)
12452         (match_operand:P 0 "register_operand" "c,*l"))
12453    (use (label_ref (match_operand 1)))]
12454   "rs6000_speculate_indirect_jumps"
12455   "b%T0"
12456   [(set_attr "type" "jmpreg")])
12458 (define_insn "*tablejump<mode>_internal1_nospec"
12459   [(set (pc)
12460         (match_operand:P 0 "register_operand" "c,*l"))
12461    (use (label_ref (match_operand 1)))
12462    (clobber (match_operand:CC 2 "cc_reg_operand" "=y,y"))]
12463   "!rs6000_speculate_indirect_jumps"
12464   "crset %E2\;beq%T0- %2\;b $"
12465   [(set_attr "type" "jmpreg")
12466    (set_attr "length" "12")])
12468 (define_insn "nop"
12469   [(unspec [(const_int 0)] UNSPEC_NOP)]
12470   ""
12471   "nop")
12473 (define_insn "group_ending_nop"
12474   [(unspec [(const_int 0)] UNSPEC_GRP_END_NOP)]
12475   ""
12477   if (rs6000_tune == PROCESSOR_POWER6)
12478     return "ori 1,1,0";
12479   return "ori 2,2,0";
12482 (define_insn "speculation_barrier"
12483   [(unspec_volatile:BLK [(const_int 0)] UNSPECV_SPEC_BARRIER)]
12484   ""
12485   "ori 31,31,0")
12487 ;; Define the subtract-one-and-jump insns, starting with the template
12488 ;; so loop.c knows what to generate.
12490 (define_expand "doloop_end"
12491   [(use (match_operand 0))      ; loop pseudo
12492    (use (match_operand 1))]     ; label
12493   ""
12495   if (TARGET_64BIT)
12496     {
12497       if (GET_MODE (operands[0]) != DImode)
12498         FAIL;
12499       emit_jump_insn (gen_ctrdi (operands[0], operands[1]));
12500     }
12501   else
12502     {
12503       if (GET_MODE (operands[0]) != SImode)
12504         FAIL;
12505       emit_jump_insn (gen_ctrsi (operands[0], operands[1]));
12506     }
12507   DONE;
12510 (define_expand "ctr<mode>"
12511   [(parallel [(set (pc)
12512                    (if_then_else (ne (match_operand:P 0 "register_operand")
12513                                      (const_int 1))
12514                                  (label_ref (match_operand 1))
12515                                  (pc)))
12516               (set (match_dup 0)
12517                    (plus:P (match_dup 0)
12518                             (const_int -1)))
12519               (clobber (match_scratch:CC 2))
12520               (clobber (match_scratch:P 3))])]
12521   ""
12522   "")
12524 ;; We need to be able to do this for any operand, including MEM, or we
12525 ;; will cause reload to blow up since we don't allow output reloads on
12526 ;; JUMP_INSNs.
12527 ;; For the length attribute to be calculated correctly, the
12528 ;; label MUST be operand 0.
12529 ;; rs6000_legitimate_combined_insn prevents combine creating any of
12530 ;; the ctr<mode> insns.
12532 (define_code_iterator eqne [eq ne])
12533 (define_code_attr bd [(eq "bdz") (ne "bdnz")])
12534 (define_code_attr bd_neg [(eq "bdnz") (ne "bdz")])
12536 (define_insn "<bd>_<mode>"
12537   [(set (pc)
12538         (if_then_else (eqne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12539                           (const_int 1))
12540                       (label_ref (match_operand 0))
12541                       (pc)))
12542    (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
12543         (plus:P (match_dup 1)
12544                 (const_int -1)))
12545    (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
12546    (clobber (match_scratch:P 4 "=X,X,&r,r"))]
12547   ""
12549   if (which_alternative != 0)
12550     return "#";
12551   else if (get_attr_length (insn) == 4)
12552     return "<bd> %l0";
12553   else
12554     return "<bd_neg> $+8\;b %l0";
12556   [(set_attr "type" "branch")
12557    (set_attr_alternative "length"
12558      [(if_then_else (and (ge (minus (match_dup 0) (pc))
12559                              (const_int -32768))
12560                          (lt (minus (match_dup 0) (pc))
12561                              (const_int 32764)))
12562                     (const_int 4)
12563                     (const_int 8))
12564       (const_string "16")
12565       (const_string "20")
12566       (const_string "20")])])
12568 ;; Now the splitter if we could not allocate the CTR register
12569 (define_split
12570   [(set (pc)
12571         (if_then_else (match_operator 2 "comparison_operator"
12572                                       [(match_operand:P 1 "gpc_reg_operand")
12573                                        (const_int 1)])
12574                       (match_operand 5)
12575                       (match_operand 6)))
12576    (set (match_operand:P 0 "nonimmediate_operand")
12577         (plus:P (match_dup 1)
12578                 (const_int -1)))
12579    (clobber (match_scratch:CC 3))
12580    (clobber (match_scratch:P 4))]
12581   "reload_completed"
12582   [(set (pc)
12583         (if_then_else (match_dup 7)
12584                       (match_dup 5)
12585                       (match_dup 6)))]
12587   operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[2]), VOIDmode, operands[3],
12588                                 const0_rtx);
12589   emit_insn (gen_rtx_SET (operands[3],
12590                           gen_rtx_COMPARE (CCmode, operands[1], const1_rtx)));
12591   if (int_reg_operand (operands[0], <MODE>mode))
12592     emit_insn (gen_add<mode>3 (operands[0], operands[1], constm1_rtx));
12593   else
12594     {
12595       emit_insn (gen_add<mode>3 (operands[4], operands[1], constm1_rtx));
12596       emit_move_insn (operands[0], operands[4]);
12597     } 
12598     /* No DONE so branch comes from the pattern.  */
12601 ;; patterns for bdnzt/bdnzf/bdzt/bdzf
12602 ;; Note that in the case of long branches we have to decompose this into
12603 ;; bdnz+bc. This is because bdnzt has an implied AND between the ctr condition
12604 ;; and the CR bit, which means there is no way to conveniently invert the
12605 ;; comparison as is done with plain bdnz/bdz.
12607 (define_insn "<bd>tf_<mode>"
12608   [(set (pc)
12609         (if_then_else
12610           (and
12611              (eqne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12612                    (const_int 1))
12613              (match_operator 3 "branch_comparison_operator"
12614                       [(match_operand 4 "cc_reg_operand" "y,y,y,y")
12615                        (const_int 0)]))
12616           (label_ref (match_operand 0))
12617           (pc)))
12618    (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
12619         (plus:P (match_dup 1)
12620                 (const_int -1)))
12621    (clobber (match_scratch:P 5 "=X,X,&r,r"))
12622    (clobber (match_scratch:CC 6 "=X,&y,&y,&y"))
12623    (clobber (match_scratch:CCEQ 7 "=X,&y,&y,&y"))]
12624   ""
12626   if (which_alternative != 0)
12627     return "#";
12628   else if (get_attr_length (insn) == 4)
12629     {
12630       if (branch_positive_comparison_operator (operands[3],
12631                                                GET_MODE (operands[3])))
12632         return "<bd>t %j3,%l0";
12633       else
12634         return "<bd>f %j3,%l0";
12635     }
12636   else
12637     {
12638       static char seq[96];
12639       char *bcs = output_cbranch (operands[3], ".Lshort%=", 1, insn);
12640       sprintf(seq, "<bd_neg> .Lshort%%=\;%s\;b %%l0\;.Lshort%%=:", bcs);
12641       return seq;
12642     }
12644   [(set_attr "type" "branch")
12645    (set_attr_alternative "length"
12646      [(if_then_else (and (ge (minus (match_dup 0) (pc))
12647                              (const_int -32768))
12648                          (lt (minus (match_dup 0) (pc))
12649                              (const_int 32764)))
12650                     (const_int 4)
12651                     (const_int 8))
12652       (const_string "16")
12653       (const_string "20")
12654       (const_string "20")])])
12656 ;; Now the splitter if we could not allocate the CTR register
12657 (define_split
12658   [(set (pc)
12659         (if_then_else
12660           (and
12661              (match_operator 1 "comparison_operator"
12662                              [(match_operand:P 0 "gpc_reg_operand")
12663                               (const_int 1)])
12664              (match_operator 3 "branch_comparison_operator"
12665                       [(match_operand 2 "cc_reg_operand")
12666                        (const_int 0)]))
12667           (match_operand 4)
12668           (match_operand 5)))
12669    (set (match_operand:P 6 "nonimmediate_operand")
12670         (plus:P (match_dup 0)
12671                 (const_int -1)))
12672    (clobber (match_scratch:P 7))
12673    (clobber (match_scratch:CC 8))
12674    (clobber (match_scratch:CCEQ 9))]
12675   "reload_completed"
12676 [(pc)]
12678   rtx ctr = operands[0];
12679   rtx ctrcmp = operands[1];
12680   rtx ccin = operands[2];
12681   rtx cccmp = operands[3];
12682   rtx dst1 = operands[4];
12683   rtx dst2 = operands[5];
12684   rtx ctrout = operands[6];
12685   rtx ctrtmp = operands[7];
12686   enum rtx_code cmpcode = GET_CODE (ctrcmp);
12687   bool ispos = branch_positive_comparison_operator (ctrcmp, GET_MODE (ctrcmp));
12688   if (!ispos)
12689     cmpcode = reverse_condition (cmpcode);
12690   /* Generate crand/crandc here.  */
12691   emit_insn (gen_rtx_SET (operands[8],
12692                           gen_rtx_COMPARE (CCmode, ctr, const1_rtx)));
12693   rtx ctrcmpcc = gen_rtx_fmt_ee (cmpcode, SImode, operands[8], const0_rtx);
12695   rtx andexpr = gen_rtx_AND (SImode, ctrcmpcc, cccmp);
12696   if (ispos)
12697      emit_insn (gen_cceq_ior_compare (operands[9], andexpr, ctrcmpcc,
12698                                       operands[8], cccmp, ccin));
12699   else
12700      emit_insn (gen_cceq_ior_compare_complement (operands[9], andexpr, ctrcmpcc,
12701                                                  operands[8], cccmp, ccin));
12702   if (int_reg_operand (ctrout, <MODE>mode))
12703      emit_insn (gen_add<mode>3 (ctrout, ctr, constm1_rtx));
12704   else
12705     {
12706       emit_insn (gen_add<mode>3 (ctrtmp, ctr, constm1_rtx));
12707       emit_move_insn (ctrout, ctrtmp);
12708     }
12709   rtx cmp = gen_rtx_EQ (CCEQmode, operands[9], const0_rtx);
12710   emit_jump_insn (gen_rtx_SET (pc_rtx,
12711                                gen_rtx_IF_THEN_ELSE (VOIDmode, cmp,
12712                                                      dst1, dst2)));
12713   DONE;
12717 (define_insn "trap"
12718   [(trap_if (const_int 1) (const_int 0))]
12719   ""
12720   "trap"
12721   [(set_attr "type" "trap")])
12723 (define_expand "ctrap<mode>4"
12724   [(trap_if (match_operator 0 "ordered_comparison_operator"
12725                             [(match_operand:GPR 1 "register_operand")
12726                              (match_operand:GPR 2 "reg_or_short_operand")])
12727             (match_operand 3 "zero_constant" ""))]
12728   ""
12729   "")
12731 (define_insn ""
12732   [(trap_if (match_operator 0 "ordered_comparison_operator"
12733                             [(match_operand:GPR 1 "register_operand" "r")
12734                              (match_operand:GPR 2 "reg_or_short_operand" "rI")])
12735             (const_int 0))]
12736   ""
12737   "t<wd>%V0%I2 %1,%2"
12738   [(set_attr "type" "trap")])
12740 ;; Insns related to generating the function prologue and epilogue.
12742 (define_expand "prologue"
12743   [(use (const_int 0))]
12744   ""
12746   rs6000_emit_prologue ();
12747   if (!TARGET_SCHED_PROLOG)
12748     emit_insn (gen_blockage ());
12749   DONE;
12752 (define_insn "*movesi_from_cr_one"
12753   [(match_parallel 0 "mfcr_operation"
12754                    [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
12755                          (unspec:SI [(match_operand:CC 2 "cc_reg_operand" "y")
12756                                      (match_operand 3 "immediate_operand" "n")]
12757                           UNSPEC_MOVESI_FROM_CR))])]
12758   "TARGET_MFCRF"
12760   int mask = 0;
12761   int i;
12762   for (i = 0; i < XVECLEN (operands[0], 0); i++)
12763   {
12764     mask = INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
12765     operands[4] = GEN_INT (mask);
12766     output_asm_insn ("mfcr %1,%4", operands);
12767   }
12768   return "";
12770   [(set_attr "type" "mfcrf")])
12772 ;; Don't include the volatile CRs since their values are not used wrt CR save
12773 ;; in the prologue and doing so prevents shrink-wrapping because we can't move the
12774 ;; prologue past an insn (early exit test) that defines a register used in the
12775 ;; prologue.
12776 (define_insn "prologue_movesi_from_cr"
12777   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
12778         (unspec:SI [(reg:CC CR2_REGNO) (reg:CC CR3_REGNO)
12779                     (reg:CC CR4_REGNO)]
12780                    UNSPEC_MOVESI_FROM_CR))]
12781   ""
12782   "mfcr %0"
12783   [(set_attr "type" "mfcr")])
12785 (define_insn "*crsave"
12786   [(match_parallel 0 "crsave_operation"
12787                    [(set (match_operand:SI 1 "memory_operand" "=m")
12788                          (match_operand:SI 2 "gpc_reg_operand" "r"))])]
12789   ""
12790   "stw %2,%1"
12791   [(set_attr "type" "store")])
12793 (define_insn "*stmw"
12794   [(match_parallel 0 "stmw_operation"
12795                    [(set (match_operand:SI 1 "memory_operand" "=m")
12796                          (match_operand:SI 2 "gpc_reg_operand" "r"))])]
12797   "TARGET_MULTIPLE"
12798   "stmw %2,%1"
12799   [(set_attr "type" "store")
12800    (set_attr "update" "yes")
12801    (set_attr "indexed" "yes")])
12803 ; The following comment applies to:
12804 ;     save_gpregs_*
12805 ;     save_fpregs_*
12806 ;     restore_gpregs*
12807 ;     return_and_restore_gpregs*
12808 ;     return_and_restore_fpregs*
12809 ;     return_and_restore_fpregs_aix*
12811 ; The out-of-line save / restore functions expects one input argument.
12812 ; Since those are not standard call_insn's, we must avoid using
12813 ; MATCH_OPERAND for that argument. That way the register rename
12814 ; optimization will not try to rename this register.
12815 ; Each pattern is repeated for each possible register number used in 
12816 ; various ABIs (r11, r1, and for some functions r12)
12818 (define_insn "*save_gpregs_<mode>_r11"
12819   [(match_parallel 0 "any_parallel_operand"
12820                    [(clobber (reg:P LR_REGNO))
12821                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
12822                     (use (reg:P 11))
12823                     (set (match_operand:P 2 "memory_operand" "=m")
12824                          (match_operand:P 3 "gpc_reg_operand" "r"))])]
12825   ""
12826   "bl %1"
12827   [(set_attr "type" "branch")])
12829 (define_insn "*save_gpregs_<mode>_r12"
12830   [(match_parallel 0 "any_parallel_operand"
12831                    [(clobber (reg:P LR_REGNO))
12832                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
12833                     (use (reg:P 12))
12834                     (set (match_operand:P 2 "memory_operand" "=m")
12835                          (match_operand:P 3 "gpc_reg_operand" "r"))])]
12836   ""
12837   "bl %1"
12838   [(set_attr "type" "branch")])
12840 (define_insn "*save_gpregs_<mode>_r1"
12841   [(match_parallel 0 "any_parallel_operand"
12842                    [(clobber (reg:P LR_REGNO))
12843                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
12844                     (use (reg:P 1))
12845                     (set (match_operand:P 2 "memory_operand" "=m")
12846                          (match_operand:P 3 "gpc_reg_operand" "r"))])]
12847   ""
12848   "bl %1"
12849   [(set_attr "type" "branch")])
12851 (define_insn "*save_fpregs_<mode>_r11"
12852   [(match_parallel 0 "any_parallel_operand"
12853                    [(clobber (reg:P LR_REGNO))
12854                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
12855                     (use (reg:P 11))
12856                     (set (match_operand:DF 2 "memory_operand" "=m")
12857                          (match_operand:DF 3 "gpc_reg_operand" "d"))])]
12858   ""
12859   "bl %1"
12860   [(set_attr "type" "branch")])
12862 (define_insn "*save_fpregs_<mode>_r12"
12863   [(match_parallel 0 "any_parallel_operand"
12864                    [(clobber (reg:P LR_REGNO))
12865                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
12866                     (use (reg:P 12))
12867                     (set (match_operand:DF 2 "memory_operand" "=m")
12868                          (match_operand:DF 3 "gpc_reg_operand" "d"))])]
12869   ""
12870   "bl %1"
12871   [(set_attr "type" "branch")])
12873 (define_insn "*save_fpregs_<mode>_r1"
12874   [(match_parallel 0 "any_parallel_operand"
12875                    [(clobber (reg:P LR_REGNO))
12876                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
12877                     (use (reg:P 1))
12878                     (set (match_operand:DF 2 "memory_operand" "=m")
12879                          (match_operand:DF 3 "gpc_reg_operand" "d"))])]
12880   ""
12881   "bl %1"
12882   [(set_attr "type" "branch")])
12884 ; This is to explain that changes to the stack pointer should
12885 ; not be moved over loads from or stores to stack memory.
12886 (define_insn "stack_tie"
12887   [(match_parallel 0 "tie_operand"
12888                    [(set (mem:BLK (reg 1)) (const_int 0))])]
12889   ""
12890   ""
12891   [(set_attr "length" "0")])
12893 ; Some 32-bit ABIs do not have a red zone, so the stack deallocation has to
12894 ; stay behind all restores from the stack, it cannot be reordered to before
12895 ; one.  See PR77687.  This insn is an add or mr, and a memory clobber.
12896 (define_insn "stack_restore_tie"
12897   [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
12898         (plus:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
12899                  (match_operand:SI 2 "reg_or_cint_operand" "O,rI")))
12900    (set (mem:BLK (scratch)) (const_int 0))]
12901   "TARGET_32BIT"
12902   "@
12903    mr %0,%1
12904    add%I2 %0,%1,%2"
12905   [(set_attr "type" "*,add")])
12907 (define_expand "epilogue"
12908   [(use (const_int 0))]
12909   ""
12911   if (!TARGET_SCHED_PROLOG)
12912     emit_insn (gen_blockage ());
12913   rs6000_emit_epilogue (FALSE);
12914   DONE;
12917 ; On some processors, doing the mtcrf one CC register at a time is
12918 ; faster (like on the 604e).  On others, doing them all at once is
12919 ; faster; for instance, on the 601 and 750.
12921 (define_expand "movsi_to_cr_one"
12922   [(set (match_operand:CC 0 "cc_reg_operand")
12923         (unspec:CC [(match_operand:SI 1 "gpc_reg_operand")
12924                     (match_dup 2)] UNSPEC_MOVESI_TO_CR))]
12925   ""
12926   "operands[2] = GEN_INT (1 << (75 - REGNO (operands[0])));")
12928 (define_insn "*movsi_to_cr"
12929   [(match_parallel 0 "mtcrf_operation"
12930                    [(set (match_operand:CC 1 "cc_reg_operand" "=y")
12931                          (unspec:CC [(match_operand:SI 2 "gpc_reg_operand" "r")
12932                                      (match_operand 3 "immediate_operand" "n")]
12933                                     UNSPEC_MOVESI_TO_CR))])]
12934  ""
12936   int mask = 0;
12937   int i;
12938   for (i = 0; i < XVECLEN (operands[0], 0); i++)
12939     mask |= INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
12940   operands[4] = GEN_INT (mask);
12941   return "mtcrf %4,%2";
12943   [(set_attr "type" "mtcr")])
12945 (define_insn "*mtcrfsi"
12946   [(set (match_operand:CC 0 "cc_reg_operand" "=y")
12947         (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
12948                     (match_operand 2 "immediate_operand" "n")]
12949                    UNSPEC_MOVESI_TO_CR))]
12950   "REG_P (operands[0])
12951    && CR_REGNO_P (REGNO (operands[0]))
12952    && CONST_INT_P (operands[2])
12953    && INTVAL (operands[2]) == 1 << (75 - REGNO (operands[0]))"
12954   "mtcrf %R0,%1"
12955   [(set_attr "type" "mtcr")])
12957 ; The load-multiple instructions have similar properties.
12958 ; Note that "load_multiple" is a name known to the machine-independent
12959 ; code that actually corresponds to the PowerPC load-string.
12961 (define_insn "*lmw"
12962   [(match_parallel 0 "lmw_operation"
12963                    [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
12964                          (match_operand:SI 2 "memory_operand" "m"))])]
12965   "TARGET_MULTIPLE"
12966   "lmw %1,%2"
12967   [(set_attr "type" "load")
12968    (set_attr "update" "yes")
12969    (set_attr "indexed" "yes")
12970    (set_attr "cell_micro" "always")])
12972 ; FIXME: "any_parallel_operand" is a bit flexible...
12974 ; The following comment applies to:
12975 ;     save_gpregs_*
12976 ;     save_fpregs_*
12977 ;     restore_gpregs*
12978 ;     return_and_restore_gpregs*
12979 ;     return_and_restore_fpregs*
12980 ;     return_and_restore_fpregs_aix*
12982 ; The out-of-line save / restore functions expects one input argument.
12983 ; Since those are not standard call_insn's, we must avoid using
12984 ; MATCH_OPERAND for that argument. That way the register rename
12985 ; optimization will not try to rename this register.
12986 ; Each pattern is repeated for each possible register number used in 
12987 ; various ABIs (r11, r1, and for some functions r12)
12989 (define_insn "*restore_gpregs_<mode>_r11"
12990  [(match_parallel 0 "any_parallel_operand"
12991                   [(clobber (reg:P LR_REGNO))
12992                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
12993                    (use (reg:P 11))
12994                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
12995                         (match_operand:P 3 "memory_operand" "m"))])]
12996  ""
12997  "bl %1"
12998  [(set_attr "type" "branch")])
13000 (define_insn "*restore_gpregs_<mode>_r12"
13001  [(match_parallel 0 "any_parallel_operand"
13002                   [(clobber (reg:P LR_REGNO))
13003                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13004                    (use (reg:P 12))
13005                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
13006                         (match_operand:P 3 "memory_operand" "m"))])]
13007  ""
13008  "bl %1"
13009  [(set_attr "type" "branch")])
13011 (define_insn "*restore_gpregs_<mode>_r1"
13012  [(match_parallel 0 "any_parallel_operand"
13013                   [(clobber (reg:P LR_REGNO))
13014                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13015                    (use (reg:P 1))
13016                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
13017                         (match_operand:P 3 "memory_operand" "m"))])]
13018  ""
13019  "bl %1"
13020  [(set_attr "type" "branch")])
13022 (define_insn "*return_and_restore_gpregs_<mode>_r11"
13023  [(match_parallel 0 "any_parallel_operand"
13024                   [(return)
13025                    (clobber (reg:P LR_REGNO))
13026                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13027                    (use (reg:P 11))
13028                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
13029                         (match_operand:P 3 "memory_operand" "m"))])]
13030  ""
13031  "b %1"
13032  [(set_attr "type" "branch")])
13034 (define_insn "*return_and_restore_gpregs_<mode>_r12"
13035  [(match_parallel 0 "any_parallel_operand"
13036                   [(return)
13037                    (clobber (reg:P LR_REGNO))
13038                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13039                    (use (reg:P 12))
13040                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
13041                         (match_operand:P 3 "memory_operand" "m"))])]
13042  ""
13043  "b %1"
13044  [(set_attr "type" "branch")])
13046 (define_insn "*return_and_restore_gpregs_<mode>_r1"
13047  [(match_parallel 0 "any_parallel_operand"
13048                   [(return)
13049                    (clobber (reg:P LR_REGNO))
13050                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13051                    (use (reg:P 1))
13052                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
13053                         (match_operand:P 3 "memory_operand" "m"))])]
13054  ""
13055  "b %1"
13056  [(set_attr "type" "branch")])
13058 (define_insn "*return_and_restore_fpregs_<mode>_r11"
13059  [(match_parallel 0 "any_parallel_operand"
13060                   [(return)
13061                    (clobber (reg:P LR_REGNO))
13062                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13063                    (use (reg:P 11))
13064                    (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13065                         (match_operand:DF 3 "memory_operand" "m"))])]
13066  ""
13067  "b %1"
13068  [(set_attr "type" "branch")])
13070 (define_insn "*return_and_restore_fpregs_<mode>_r12"
13071  [(match_parallel 0 "any_parallel_operand"
13072                   [(return)
13073                    (clobber (reg:P LR_REGNO))
13074                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13075                    (use (reg:P 12))
13076                    (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13077                         (match_operand:DF 3 "memory_operand" "m"))])]
13078  ""
13079  "b %1"
13080  [(set_attr "type" "branch")])
13082 (define_insn "*return_and_restore_fpregs_<mode>_r1"
13083  [(match_parallel 0 "any_parallel_operand"
13084                   [(return)
13085                    (clobber (reg:P LR_REGNO))
13086                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13087                    (use (reg:P 1))
13088                    (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13089                         (match_operand:DF 3 "memory_operand" "m"))])]
13090  ""
13091  "b %1"
13092  [(set_attr "type" "branch")])
13094 (define_insn "*return_and_restore_fpregs_aix_<mode>_r11"
13095  [(match_parallel 0 "any_parallel_operand"
13096                   [(return)
13097                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13098                    (use (reg:P 11))
13099                    (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13100                         (match_operand:DF 3 "memory_operand" "m"))])]
13101  ""
13102  "b %1"
13103  [(set_attr "type" "branch")])
13105 (define_insn "*return_and_restore_fpregs_aix_<mode>_r1"
13106  [(match_parallel 0 "any_parallel_operand"
13107                   [(return)
13108                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13109                    (use (reg:P 1))
13110                    (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13111                         (match_operand:DF 3 "memory_operand" "m"))])]
13112  ""
13113  "b %1"
13114  [(set_attr "type" "branch")])
13116 ; This is used in compiling the unwind routines.
13117 (define_expand "eh_return"
13118   [(use (match_operand 0 "general_operand"))]
13119   ""
13121   if (TARGET_32BIT)
13122     emit_insn (gen_eh_set_lr_si (operands[0]));
13123   else
13124     emit_insn (gen_eh_set_lr_di (operands[0]));
13125   DONE;
13128 ; We can't expand this before we know where the link register is stored.
13129 (define_insn "eh_set_lr_<mode>"
13130   [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
13131                     UNSPECV_EH_RR)
13132    (clobber (match_scratch:P 1 "=&b"))]
13133   ""
13134   "#")
13136 (define_split
13137   [(unspec_volatile [(match_operand 0 "register_operand")] UNSPECV_EH_RR)
13138    (clobber (match_scratch 1))]
13139   "reload_completed"
13140   [(const_int 0)]
13142   rs6000_emit_eh_reg_restore (operands[0], operands[1]);
13143   DONE;
13146 (define_insn "prefetch"
13147   [(prefetch (match_operand 0 "indexed_or_indirect_address" "a")
13148              (match_operand:SI 1 "const_int_operand" "n")
13149              (match_operand:SI 2 "const_int_operand" "n"))]
13150   ""
13154   /* dcbtstt, dcbtt and TH=0b10000 support starts with ISA 2.06 (Power7).
13155      AIX does not support the dcbtstt and dcbtt extended mnemonics.
13156      The AIX assembler does not support the three operand form of dcbt
13157      and dcbtst on Power 7 (-mpwr7).  */
13158   int inst_select = INTVAL (operands[2]) || !TARGET_DIRECT_MOVE;
13160   if (REG_P (operands[0]))
13161     {
13162       if (INTVAL (operands[1]) == 0)
13163         return inst_select ? "dcbt 0,%0" : "dcbt 0,%0,16";
13164       else
13165         return inst_select ? "dcbtst 0,%0" : "dcbtst 0,%0,16";
13166     }
13167   else
13168     {
13169       if (INTVAL (operands[1]) == 0)
13170         return inst_select ? "dcbt %a0" : "dcbt %a0,16";
13171       else
13172         return inst_select ? "dcbtst %a0" : "dcbtst %a0,16";
13173     }
13175   [(set_attr "type" "load")])
13177 ;; Handle -fsplit-stack.
13179 (define_expand "split_stack_prologue"
13180   [(const_int 0)]
13181   ""
13183   rs6000_expand_split_stack_prologue ();
13184   DONE;
13187 (define_expand "load_split_stack_limit"
13188   [(set (match_operand 0)
13189         (unspec [(const_int 0)] UNSPEC_STACK_CHECK))]
13190   ""
13192   emit_insn (gen_rtx_SET (operands[0],
13193                           gen_rtx_UNSPEC (Pmode,
13194                                           gen_rtvec (1, const0_rtx),
13195                                           UNSPEC_STACK_CHECK)));
13196   DONE;
13199 (define_insn "load_split_stack_limit_di"
13200   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
13201         (unspec:DI [(const_int 0)] UNSPEC_STACK_CHECK))]
13202   "TARGET_64BIT"
13203   "ld %0,-0x7040(13)"
13204   [(set_attr "type" "load")
13205    (set_attr "update" "no")
13206    (set_attr "indexed" "no")])
13208 (define_insn "load_split_stack_limit_si"
13209   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
13210         (unspec:SI [(const_int 0)] UNSPEC_STACK_CHECK))]
13211   "!TARGET_64BIT"
13212   "lwz %0,-0x7020(2)"
13213   [(set_attr "type" "load")
13214    (set_attr "update" "no")
13215    (set_attr "indexed" "no")])
13217 ;; A return instruction which the middle-end doesn't see.
13218 ;; Use r0 to stop regrename twiddling with lr restore insns emitted
13219 ;; after the call to __morestack.
13220 (define_insn "split_stack_return"
13221   [(unspec_volatile [(reg:SI 0) (reg:SI LR_REGNO)] UNSPECV_SPLIT_STACK_RETURN)]
13222   ""
13223   "blr"
13224   [(set_attr "type" "jmpreg")])
13226 ;; If there are operand 0 bytes available on the stack, jump to
13227 ;; operand 1.
13228 (define_expand "split_stack_space_check"
13229   [(set (match_dup 2)
13230         (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
13231    (set (match_dup 3)
13232         (minus (reg STACK_POINTER_REGNUM)
13233                (match_operand 0)))
13234    (set (match_dup 4) (compare:CCUNS (match_dup 3) (match_dup 2)))
13235    (set (pc) (if_then_else
13236               (geu (match_dup 4) (const_int 0))
13237               (label_ref (match_operand 1))
13238               (pc)))]
13239   ""
13241   rs6000_split_stack_space_check (operands[0], operands[1]);
13242   DONE;
13245 (define_insn "bpermd_<mode>"
13246   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
13247         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "r")
13248                    (match_operand:P 2 "gpc_reg_operand" "r")] UNSPEC_BPERM))]
13249   "TARGET_POPCNTD"
13250   "bpermd %0,%1,%2"
13251   [(set_attr "type" "popcnt")])
13254 ;; Builtin fma support.  Handle 
13255 ;; Note that the conditions for expansion are in the FMA_F iterator.
13257 (define_expand "fma<mode>4"
13258   [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13259         (fma:FMA_F
13260           (match_operand:FMA_F 1 "gpc_reg_operand")
13261           (match_operand:FMA_F 2 "gpc_reg_operand")
13262           (match_operand:FMA_F 3 "gpc_reg_operand")))]
13263   ""
13264   "")
13266 (define_insn "*fma<mode>4_fpr"
13267   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13268         (fma:SFDF
13269           (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>,<Fv2>")
13270           (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13271           (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>")))]
13272   "TARGET_HARD_FLOAT"
13273   "@
13274    fmadd<Ftrad> %0,%1,%2,%3
13275    xsmadda<Fvsx> %x0,%x1,%x2
13276    xsmaddm<Fvsx> %x0,%x1,%x3"
13277   [(set_attr "type" "fp")])
13279 ; Altivec only has fma and nfms.
13280 (define_expand "fms<mode>4"
13281   [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13282         (fma:FMA_F
13283           (match_operand:FMA_F 1 "gpc_reg_operand")
13284           (match_operand:FMA_F 2 "gpc_reg_operand")
13285           (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand"))))]
13286   "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13287   "")
13289 (define_insn "*fms<mode>4_fpr"
13290   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13291         (fma:SFDF
13292          (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
13293          (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13294          (neg:SFDF (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>"))))]
13295   "TARGET_HARD_FLOAT"
13296   "@
13297    fmsub<Ftrad> %0,%1,%2,%3
13298    xsmsuba<Fvsx> %x0,%x1,%x2
13299    xsmsubm<Fvsx> %x0,%x1,%x3"
13300   [(set_attr "type" "fp")])
13302 ;; If signed zeros are ignored, -(a * b - c) = -a * b + c.
13303 (define_expand "fnma<mode>4"
13304   [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13305         (neg:FMA_F
13306           (fma:FMA_F
13307             (match_operand:FMA_F 1 "gpc_reg_operand")
13308             (match_operand:FMA_F 2 "gpc_reg_operand")
13309             (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand")))))]
13310   "!HONOR_SIGNED_ZEROS (<MODE>mode)"
13311   "")
13313 ;; If signed zeros are ignored, -(a * b + c) = -a * b - c.
13314 (define_expand "fnms<mode>4"
13315   [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13316         (neg:FMA_F
13317           (fma:FMA_F
13318             (match_operand:FMA_F 1 "gpc_reg_operand")
13319             (match_operand:FMA_F 2 "gpc_reg_operand")
13320             (match_operand:FMA_F 3 "gpc_reg_operand"))))]
13321   "!HONOR_SIGNED_ZEROS (<MODE>mode) && !VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13322   "")
13324 ; Not an official optab name, but used from builtins.
13325 (define_expand "nfma<mode>4"
13326   [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13327         (neg:FMA_F
13328           (fma:FMA_F
13329             (match_operand:FMA_F 1 "gpc_reg_operand")
13330             (match_operand:FMA_F 2 "gpc_reg_operand")
13331             (match_operand:FMA_F 3 "gpc_reg_operand"))))]
13332   "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13333   "")
13335 (define_insn "*nfma<mode>4_fpr"
13336   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13337         (neg:SFDF
13338          (fma:SFDF
13339           (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
13340           (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13341           (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>"))))]
13342   "TARGET_HARD_FLOAT"
13343   "@
13344    fnmadd<Ftrad> %0,%1,%2,%3
13345    xsnmadda<Fvsx> %x0,%x1,%x2
13346    xsnmaddm<Fvsx> %x0,%x1,%x3"
13347   [(set_attr "type" "fp")])
13349 ; Not an official optab name, but used from builtins.
13350 (define_expand "nfms<mode>4"
13351   [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13352         (neg:FMA_F
13353           (fma:FMA_F
13354             (match_operand:FMA_F 1 "gpc_reg_operand")
13355             (match_operand:FMA_F 2 "gpc_reg_operand")
13356             (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand")))))]
13357   ""
13358   "")
13360 (define_insn "*nfmssf4_fpr"
13361   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13362         (neg:SFDF
13363          (fma:SFDF
13364           (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
13365           (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13366           (neg:SFDF
13367            (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>")))))]
13368   "TARGET_HARD_FLOAT"
13369   "@
13370    fnmsub<Ftrad> %0,%1,%2,%3
13371    xsnmsuba<Fvsx> %x0,%x1,%x2
13372    xsnmsubm<Fvsx> %x0,%x1,%x3"
13373   [(set_attr "type" "fp")])
13376 (define_expand "rs6000_get_timebase"
13377   [(use (match_operand:DI 0 "gpc_reg_operand"))]
13378   ""
13380   if (TARGET_POWERPC64)
13381     emit_insn (gen_rs6000_mftb_di (operands[0]));
13382   else
13383     emit_insn (gen_rs6000_get_timebase_ppc32 (operands[0]));
13384   DONE;
13387 (define_insn "rs6000_get_timebase_ppc32"
13388   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
13389         (unspec_volatile:DI [(const_int 0)] UNSPECV_MFTB))
13390    (clobber (match_scratch:SI 1 "=r"))
13391    (clobber (match_scratch:CC 2 "=y"))]
13392   "!TARGET_POWERPC64"
13394   if (WORDS_BIG_ENDIAN)
13395     if (TARGET_MFCRF)
13396       {
13397         return "mfspr %0,269\;"
13398                "mfspr %L0,268\;"
13399                "mfspr %1,269\;"
13400                "cmpw %2,%0,%1\;"
13401                "bne- %2,$-16";
13402       }
13403     else
13404       {
13405         return "mftbu %0\;"
13406                "mftb %L0\;"
13407                "mftbu %1\;"
13408                "cmpw %2,%0,%1\;"
13409                "bne- %2,$-16";
13410       }
13411   else
13412     if (TARGET_MFCRF)
13413       {
13414         return "mfspr %L0,269\;"
13415                "mfspr %0,268\;"
13416                "mfspr %1,269\;"
13417                "cmpw %2,%L0,%1\;"
13418                "bne- %2,$-16";
13419       }
13420     else
13421       {
13422         return "mftbu %L0\;"
13423                "mftb %0\;"
13424                "mftbu %1\;"
13425                "cmpw %2,%L0,%1\;"
13426                "bne- %2,$-16";
13427       }
13429   [(set_attr "length" "20")])
13431 (define_insn "rs6000_mftb_<mode>"
13432   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
13433         (unspec_volatile:GPR [(const_int 0)] UNSPECV_MFTB))]
13434   ""
13436   if (TARGET_MFCRF)
13437     return "mfspr %0,268";
13438   else
13439     return "mftb %0";
13443 ;; The ISA 3.0 mffsl instruction is a lower latency instruction
13444 ;; for reading bits [29:31], [45:51] and [56:63] of the FPSCR.
13445 (define_insn "rs6000_mffsl_hw"
13446   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
13447         (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFSL))]
13448   "TARGET_HARD_FLOAT"
13449   "mffsl %0")
13451 (define_expand "rs6000_mffsl"
13452   [(set (match_operand:DF 0 "gpc_reg_operand")
13453         (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFSL))]
13454   "TARGET_HARD_FLOAT"
13456   /* If the low latency mffsl instruction (ISA 3.0) is available use it,
13457      otherwise fall back to the older mffs instruction to emulate the mffsl
13458      instruction.  */
13460   if (!TARGET_P9_MISC)
13461     {
13462        rtx tmp_di = gen_reg_rtx (DImode);
13463        rtx tmp_df = gen_reg_rtx (DFmode);
13465        /* The mffs instruction reads the entire FPSCR.  Emulate the mffsl
13466           instruction using the mffs instruction and masking off the bits
13467           the mmsl instruciton actually reads.  */
13468        emit_insn (gen_rs6000_mffs (tmp_df));
13469        tmp_di = simplify_gen_subreg (DImode, tmp_df, DFmode, 0);
13470        emit_insn (gen_anddi3 (tmp_di, tmp_di, GEN_INT (0x70007f0ffLL)));
13472        operands[0] = simplify_gen_subreg (DFmode, tmp_di, DImode, 0);
13473        DONE;
13474     }
13476     emit_insn (gen_rs6000_mffsl_hw (operands[0]));
13477     DONE;
13480 (define_insn "rs6000_mffs"
13481   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
13482         (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFS))]
13483   "TARGET_HARD_FLOAT"
13484   "mffs %0")
13486 (define_insn "rs6000_mtfsf"
13487   [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "i")
13488                      (match_operand:DF 1 "gpc_reg_operand" "d")]
13489                     UNSPECV_MTFSF)]
13490   "TARGET_HARD_FLOAT"
13491   "mtfsf %0,%1")
13493 (define_insn "rs6000_mtfsf_hi"
13494   [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "n")
13495                      (match_operand:DF 1 "gpc_reg_operand" "d")]
13496                     UNSPECV_MTFSF_HI)]
13497   "TARGET_HARD_FLOAT"
13498   "mtfsf %0,%1,0,1")
13501 ;; Power8 fusion support for fusing an addis instruction with a D-form load of
13502 ;; a GPR.  The addis instruction must be adjacent to the load, and use the same
13503 ;; register that is being loaded.  The fused ops must be physically adjacent.
13505 ;; On Power8 GPR loads, we try to use the register that is being load.  The
13506 ;; peephole2 then gathers any other fused possibilities that it can find after
13507 ;; register allocation.  If power9 fusion is selected, we also fuse floating
13508 ;; point loads/stores.
13510 ;; Find cases where the addis that feeds into a load instruction is either used
13511 ;; once or is the same as the target register, and replace it with the fusion
13512 ;; insn
13514 (define_peephole2
13515   [(set (match_operand:P 0 "base_reg_operand")
13516         (match_operand:P 1 "fusion_gpr_addis"))
13517    (set (match_operand:INT1 2 "base_reg_operand")
13518         (match_operand:INT1 3 "fusion_gpr_mem_load"))]
13519   "TARGET_P8_FUSION
13520    && fusion_gpr_load_p (operands[0], operands[1], operands[2],
13521                          operands[3])"
13522   [(const_int 0)]
13524   expand_fusion_gpr_load (operands);
13525   DONE;
13528 ;; Fusion insn, created by the define_peephole2 above (and eventually by
13529 ;; reload)
13531 (define_insn "*fusion_gpr_load_<mode>"
13532   [(set (match_operand:INT1 0 "base_reg_operand" "=b")
13533         (unspec:INT1 [(match_operand:INT1 1 "fusion_addis_mem_combo_load" "wF")]
13534                      UNSPEC_FUSION_GPR))]
13535   "TARGET_P8_FUSION"
13537   return emit_fusion_gpr_load (operands[0], operands[1]);
13539   [(set_attr "type" "load")
13540    (set_attr "length" "8")])
13543 ;; Optimize cases where we want to do a D-form load (register+offset) on
13544 ;; ISA 2.06/2.07 to an Altivec register, and the register allocator
13545 ;; has generated:
13546 ;;      LFD 0,32(3)
13547 ;;      XXLOR 32,0,0
13549 ;; and we change this to:
13550 ;;      LI 0,32
13551 ;;      LXSDX 32,3,9
13553 (define_peephole2
13554   [(match_scratch:P 0 "b")
13555    (set (match_operand:ALTIVEC_DFORM 1 "fpr_reg_operand")
13556         (match_operand:ALTIVEC_DFORM 2 "simple_offsettable_mem_operand"))
13557    (set (match_operand:ALTIVEC_DFORM 3 "altivec_register_operand")
13558         (match_dup 1))]
13559   "TARGET_VSX && !TARGET_P9_VECTOR && peep2_reg_dead_p (2, operands[1])"
13560   [(set (match_dup 0)
13561         (match_dup 4))
13562    (set (match_dup 3)
13563         (match_dup 5))]
13565   rtx tmp_reg = operands[0];
13566   rtx mem = operands[2];
13567   rtx addr = XEXP (mem, 0);
13568   rtx add_op0, add_op1, new_addr;
13570   gcc_assert (GET_CODE (addr) == PLUS || GET_CODE (addr) == LO_SUM);
13571   add_op0 = XEXP (addr, 0);
13572   add_op1 = XEXP (addr, 1);
13573   gcc_assert (REG_P (add_op0));
13574   new_addr = gen_rtx_PLUS (Pmode, add_op0, tmp_reg);
13576   operands[4] = add_op1;
13577   operands[5] = change_address (mem, <MODE>mode, new_addr);
13580 ;; Optimize cases were want to do a D-form store on ISA 2.06/2.07 from an
13581 ;; Altivec register, and the register allocator has generated:
13582 ;;      XXLOR 0,32,32
13583 ;;      STFD 0,32(3)
13585 ;; and we change this to:
13586 ;;      LI 0,32
13587 ;;      STXSDX 32,3,9
13589 (define_peephole2
13590   [(match_scratch:P 0 "b")
13591    (set (match_operand:ALTIVEC_DFORM 1 "fpr_reg_operand")
13592         (match_operand:ALTIVEC_DFORM 2 "altivec_register_operand"))
13593    (set (match_operand:ALTIVEC_DFORM 3 "simple_offsettable_mem_operand")
13594         (match_dup 1))]
13595   "TARGET_VSX && !TARGET_P9_VECTOR && peep2_reg_dead_p (2, operands[1])"
13596   [(set (match_dup 0)
13597         (match_dup 4))
13598    (set (match_dup 5)
13599         (match_dup 2))]
13601   rtx tmp_reg = operands[0];
13602   rtx mem = operands[3];
13603   rtx addr = XEXP (mem, 0);
13604   rtx add_op0, add_op1, new_addr;
13606   gcc_assert (GET_CODE (addr) == PLUS || GET_CODE (addr) == LO_SUM);
13607   add_op0 = XEXP (addr, 0);
13608   add_op1 = XEXP (addr, 1);
13609   gcc_assert (REG_P (add_op0));
13610   new_addr = gen_rtx_PLUS (Pmode, add_op0, tmp_reg);
13612   operands[4] = add_op1;
13613   operands[5] = change_address (mem, <MODE>mode, new_addr);
13615    
13617 ;; Miscellaneous ISA 2.06 (power7) instructions
13618 (define_insn "addg6s"
13619   [(set (match_operand:SI 0 "register_operand" "=r")
13620         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
13621                     (match_operand:SI 2 "register_operand" "r")]
13622                    UNSPEC_ADDG6S))]
13623   "TARGET_POPCNTD"
13624   "addg6s %0,%1,%2"
13625   [(set_attr "type" "integer")])
13627 (define_insn "cdtbcd"
13628   [(set (match_operand:SI 0 "register_operand" "=r")
13629         (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
13630                    UNSPEC_CDTBCD))]
13631   "TARGET_POPCNTD"
13632   "cdtbcd %0,%1"
13633   [(set_attr "type" "integer")])
13635 (define_insn "cbcdtd"
13636   [(set (match_operand:SI 0 "register_operand" "=r")
13637         (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
13638                    UNSPEC_CBCDTD))]
13639   "TARGET_POPCNTD"
13640   "cbcdtd %0,%1"
13641   [(set_attr "type" "integer")])
13643 (define_int_iterator UNSPEC_DIV_EXTEND [UNSPEC_DIVE
13644                                         UNSPEC_DIVEU])
13646 (define_int_attr div_extend [(UNSPEC_DIVE       "e")
13647                              (UNSPEC_DIVEU      "eu")])
13649 (define_insn "div<div_extend>_<mode>"
13650   [(set (match_operand:GPR 0 "register_operand" "=r")
13651         (unspec:GPR [(match_operand:GPR 1 "register_operand" "r")
13652                      (match_operand:GPR 2 "register_operand" "r")]
13653                     UNSPEC_DIV_EXTEND))]
13654   "TARGET_POPCNTD"
13655   "div<wd><div_extend> %0,%1,%2"
13656   [(set_attr "type" "div")
13657    (set_attr "size" "<bits>")])
13660 ;; Pack/unpack 128-bit floating point types that take 2 scalar registers
13662 ; Type of the 64-bit part when packing/unpacking 128-bit floating point types
13663 (define_mode_attr FP128_64 [(TF "DF")
13664                             (IF "DF")
13665                             (TD "DI")
13666                             (KF "DI")])
13668 (define_expand "unpack<mode>"
13669   [(set (match_operand:<FP128_64> 0 "nonimmediate_operand")
13670         (unspec:<FP128_64>
13671          [(match_operand:FMOVE128 1 "register_operand")
13672           (match_operand:QI 2 "const_0_to_1_operand")]
13673          UNSPEC_UNPACK_128BIT))]
13674   "FLOAT128_2REG_P (<MODE>mode)"
13675   "")
13677 (define_insn_and_split "unpack<mode>_dm"
13678   [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m,d,r,m")
13679         (unspec:<FP128_64>
13680          [(match_operand:FMOVE128 1 "register_operand" "d,d,r,d,r")
13681           (match_operand:QI 2 "const_0_to_1_operand" "i,i,i,i,i")]
13682          UNSPEC_UNPACK_128BIT))]
13683   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE && FLOAT128_2REG_P (<MODE>mode)"
13684   "#"
13685   "&& reload_completed"
13686   [(set (match_dup 0) (match_dup 3))]
13688   unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
13690   if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
13691     {
13692       emit_note (NOTE_INSN_DELETED);
13693       DONE;
13694     }
13696   operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
13698   [(set_attr "type" "fp,fpstore,mffgpr,mftgpr,store")])
13700 (define_insn_and_split "unpack<mode>_nodm"
13701   [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m")
13702         (unspec:<FP128_64>
13703          [(match_operand:FMOVE128 1 "register_operand" "d,d")
13704           (match_operand:QI 2 "const_0_to_1_operand" "i,i")]
13705          UNSPEC_UNPACK_128BIT))]
13706   "(!TARGET_POWERPC64 || !TARGET_DIRECT_MOVE) && FLOAT128_2REG_P (<MODE>mode)"
13707   "#"
13708   "&& reload_completed"
13709   [(set (match_dup 0) (match_dup 3))]
13711   unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
13713   if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
13714     {
13715       emit_note (NOTE_INSN_DELETED);
13716       DONE;
13717     }
13719   operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
13721   [(set_attr "type" "fp,fpstore")])
13723 (define_insn_and_split "pack<mode>"
13724   [(set (match_operand:FMOVE128 0 "register_operand" "=&d")
13725         (unspec:FMOVE128
13726          [(match_operand:<FP128_64> 1 "register_operand" "d")
13727           (match_operand:<FP128_64> 2 "register_operand" "d")]
13728          UNSPEC_PACK_128BIT))]
13729   "FLOAT128_2REG_P (<MODE>mode)"
13730   "#"
13731   "&& reload_completed"
13732   [(set (match_dup 3) (match_dup 1))
13733    (set (match_dup 4) (match_dup 2))]
13735   unsigned dest_hi = REGNO (operands[0]);
13736   unsigned dest_lo = dest_hi + 1;
13738   gcc_assert (!IN_RANGE (REGNO (operands[1]), dest_hi, dest_lo));
13739   gcc_assert (!IN_RANGE (REGNO (operands[2]), dest_hi, dest_lo));
13741   operands[3] = gen_rtx_REG (<FP128_64>mode, dest_hi);
13742   operands[4] = gen_rtx_REG (<FP128_64>mode, dest_lo);
13744   [(set_attr "type" "fp")
13745    (set_attr "length" "8")])
13747 (define_insn "unpack<mode>"
13748   [(set (match_operand:DI 0 "register_operand" "=wa,wa")
13749         (unspec:DI [(match_operand:FMOVE128_VSX 1 "register_operand" "0,wa")
13750                     (match_operand:QI 2 "const_0_to_1_operand" "O,i")]
13751          UNSPEC_UNPACK_128BIT))]
13752   "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)"
13754   if (REGNO (operands[0]) == REGNO (operands[1]) && INTVAL (operands[2]) == 0)
13755     return ASM_COMMENT_START " xxpermdi to same register";
13757   operands[3] = GEN_INT (INTVAL (operands[2]) == 0 ? 0 : 3);
13758   return "xxpermdi %x0,%x1,%x1,%3";
13760   [(set_attr "type" "vecperm")])
13762 (define_insn "pack<mode>"
13763   [(set (match_operand:FMOVE128_VSX 0 "register_operand" "=wa")
13764         (unspec:FMOVE128_VSX
13765          [(match_operand:DI 1 "register_operand" "wa")
13766           (match_operand:DI 2 "register_operand" "wa")]
13767          UNSPEC_PACK_128BIT))]
13768   "TARGET_VSX"
13769   "xxpermdi %x0,%x1,%x2,0"
13770   [(set_attr "type" "vecperm")])
13774 ;; ISA 2.08 IEEE 128-bit floating point support.
13776 (define_insn "add<mode>3"
13777   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13778         (plus:IEEE128
13779          (match_operand:IEEE128 1 "altivec_register_operand" "v")
13780          (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13781   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13782   "xsaddqp %0,%1,%2"
13783   [(set_attr "type" "vecfloat")
13784    (set_attr "size" "128")])
13786 (define_insn "sub<mode>3"
13787   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13788         (minus:IEEE128
13789          (match_operand:IEEE128 1 "altivec_register_operand" "v")
13790          (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13791   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13792   "xssubqp %0,%1,%2"
13793   [(set_attr "type" "vecfloat")
13794    (set_attr "size" "128")])
13796 (define_insn "mul<mode>3"
13797   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13798         (mult:IEEE128
13799          (match_operand:IEEE128 1 "altivec_register_operand" "v")
13800          (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13801   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13802   "xsmulqp %0,%1,%2"
13803   [(set_attr "type" "qmul")
13804    (set_attr "size" "128")])
13806 (define_insn "div<mode>3"
13807   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13808         (div:IEEE128
13809          (match_operand:IEEE128 1 "altivec_register_operand" "v")
13810          (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13811   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13812   "xsdivqp %0,%1,%2"
13813   [(set_attr "type" "vecdiv")
13814    (set_attr "size" "128")])
13816 (define_insn "sqrt<mode>2"
13817   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13818         (sqrt:IEEE128
13819          (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
13820   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13821    "xssqrtqp %0,%1"
13822   [(set_attr "type" "vecdiv")
13823    (set_attr "size" "128")])
13825 (define_expand "copysign<mode>3"
13826   [(use (match_operand:IEEE128 0 "altivec_register_operand"))
13827    (use (match_operand:IEEE128 1 "altivec_register_operand"))
13828    (use (match_operand:IEEE128 2 "altivec_register_operand"))]
13829   "FLOAT128_IEEE_P (<MODE>mode)"
13831   if (TARGET_FLOAT128_HW)
13832     emit_insn (gen_copysign<mode>3_hard (operands[0], operands[1],
13833                                          operands[2]));
13834   else
13835     emit_insn (gen_copysign<mode>3_soft (operands[0], operands[1],
13836                                          operands[2]));
13837   DONE;
13840 (define_insn "copysign<mode>3_hard"
13841   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13842         (unspec:IEEE128
13843          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
13844           (match_operand:IEEE128 2 "altivec_register_operand" "v")]
13845          UNSPEC_COPYSIGN))]
13846   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13847    "xscpsgnqp %0,%2,%1"
13848   [(set_attr "type" "vecmove")
13849    (set_attr "size" "128")])
13851 (define_insn "copysign<mode>3_soft"
13852   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13853         (unspec:IEEE128
13854          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
13855           (match_operand:IEEE128 2 "altivec_register_operand" "v")]
13856          UNSPEC_COPYSIGN))
13857    (clobber (match_scratch:IEEE128 3 "=&v"))]
13858   "!TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13859    "xscpsgndp %x3,%x2,%x1\;xxpermdi %x0,%x3,%x1,1"
13860   [(set_attr "type" "veccomplex")
13861    (set_attr "length" "8")])
13863 (define_insn "neg<mode>2_hw"
13864   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13865         (neg:IEEE128
13866          (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
13867   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13868   "xsnegqp %0,%1"
13869   [(set_attr "type" "vecmove")
13870    (set_attr "size" "128")])
13873 (define_insn "abs<mode>2_hw"
13874   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13875         (abs:IEEE128
13876          (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
13877   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13878   "xsabsqp %0,%1"
13879   [(set_attr "type" "vecmove")
13880    (set_attr "size" "128")])
13883 (define_insn "*nabs<mode>2_hw"
13884   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13885         (neg:IEEE128
13886          (abs:IEEE128
13887           (match_operand:IEEE128 1 "altivec_register_operand" "v"))))]
13888   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13889   "xsnabsqp %0,%1"
13890   [(set_attr "type" "vecmove")
13891    (set_attr "size" "128")])
13893 ;; Initially don't worry about doing fusion
13894 (define_insn "fma<mode>4_hw"
13895   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13896         (fma:IEEE128
13897          (match_operand:IEEE128 1 "altivec_register_operand" "%v")
13898          (match_operand:IEEE128 2 "altivec_register_operand" "v")
13899          (match_operand:IEEE128 3 "altivec_register_operand" "0")))]
13900   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13901   "xsmaddqp %0,%1,%2"
13902   [(set_attr "type" "qmul")
13903    (set_attr "size" "128")])
13905 (define_insn "*fms<mode>4_hw"
13906   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13907         (fma:IEEE128
13908          (match_operand:IEEE128 1 "altivec_register_operand" "%v")
13909          (match_operand:IEEE128 2 "altivec_register_operand" "v")
13910          (neg:IEEE128
13911           (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
13912   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13913   "xsmsubqp %0,%1,%2"
13914   [(set_attr "type" "qmul")
13915    (set_attr "size" "128")])
13917 (define_insn "*nfma<mode>4_hw"
13918   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13919         (neg:IEEE128
13920          (fma:IEEE128
13921           (match_operand:IEEE128 1 "altivec_register_operand" "%v")
13922           (match_operand:IEEE128 2 "altivec_register_operand" "v")
13923           (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
13924   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13925   "xsnmaddqp %0,%1,%2"
13926   [(set_attr "type" "qmul")
13927    (set_attr "size" "128")])
13929 (define_insn "*nfms<mode>4_hw"
13930   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13931         (neg:IEEE128
13932          (fma:IEEE128
13933           (match_operand:IEEE128 1 "altivec_register_operand" "%v")
13934           (match_operand:IEEE128 2 "altivec_register_operand" "v")
13935           (neg:IEEE128
13936            (match_operand:IEEE128 3 "altivec_register_operand" "0")))))]
13937   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13938   "xsnmsubqp %0,%1,%2"
13939   [(set_attr "type" "qmul")
13940    (set_attr "size" "128")])
13942 (define_insn "extend<SFDF:mode><IEEE128:mode>2_hw"
13943   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13944         (float_extend:IEEE128
13945          (match_operand:SFDF 1 "altivec_register_operand" "v")))]
13946   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
13947   "xscvdpqp %0,%1"
13948   [(set_attr "type" "vecfloat")
13949    (set_attr "size" "128")])
13951 ;; Conversion between KFmode and TFmode if TFmode is ieee 128-bit floating
13952 ;; point is a simple copy.
13953 (define_insn_and_split "extendkftf2"
13954   [(set (match_operand:TF 0 "vsx_register_operand" "=wa,?wa")
13955         (float_extend:TF (match_operand:KF 1 "vsx_register_operand" "0,wa")))]
13956   "TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD"
13957   "@
13958    #
13959    xxlor %x0,%x1,%x1"
13960   "&& reload_completed  && REGNO (operands[0]) == REGNO (operands[1])"
13961   [(const_int 0)]
13963   emit_note (NOTE_INSN_DELETED);
13964   DONE;
13966   [(set_attr "type" "*,veclogical")
13967    (set_attr "length" "0,4")])
13969 (define_insn_and_split "trunctfkf2"
13970   [(set (match_operand:KF 0 "vsx_register_operand" "=wa,?wa")
13971         (float_extend:KF (match_operand:TF 1 "vsx_register_operand" "0,wa")))]
13972   "TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD"
13973   "@
13974    #
13975    xxlor %x0,%x1,%x1"
13976   "&& reload_completed  && REGNO (operands[0]) == REGNO (operands[1])"
13977   [(const_int 0)]
13979   emit_note (NOTE_INSN_DELETED);
13980   DONE;
13982   [(set_attr "type" "*,veclogical")
13983    (set_attr "length" "0,4")])
13985 (define_insn "trunc<mode>df2_hw"
13986   [(set (match_operand:DF 0 "altivec_register_operand" "=v")
13987         (float_truncate:DF
13988          (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
13989   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13990   "xscvqpdp %0,%1"
13991   [(set_attr "type" "vecfloat")
13992    (set_attr "size" "128")])
13994 ;; There is no KFmode -> SFmode instruction. Preserve the accuracy by doing
13995 ;; the KFmode -> DFmode conversion using round to odd rather than the normal
13996 ;; conversion
13997 (define_insn_and_split "trunc<mode>sf2_hw"
13998   [(set (match_operand:SF 0 "vsx_register_operand" "=wy")
13999         (float_truncate:SF
14000          (match_operand:IEEE128 1 "altivec_register_operand" "v")))
14001    (clobber (match_scratch:DF 2 "=v"))]
14002   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14003   "#"
14004   "&& 1"
14005   [(set (match_dup 2)
14006         (unspec:DF [(match_dup 1)]
14007                    UNSPEC_TRUNC_ROUND_TO_ODD))
14008    (set (match_dup 0)
14009         (float_truncate:SF (match_dup 2)))]
14011   if (GET_CODE (operands[2]) == SCRATCH)
14012     operands[2] = gen_reg_rtx (DFmode);
14014   [(set_attr "type" "vecfloat")
14015    (set_attr "length" "8")])
14017 ;; Conversion between IEEE 128-bit and integer types
14019 ;; The fix function for DImode and SImode was declared earlier as a
14020 ;; define_expand.  It calls into rs6000_expand_float128_convert if we don't
14021 ;; have IEEE 128-bit hardware support.  QImode and HImode are not provided
14022 ;; unless we have the IEEE 128-bit hardware.
14024 ;; Unlike the code for converting SFmode/DFmode to QImode/HImode, we don't have
14025 ;; to provide a GPR target that used direct move and a conversion in the GPR
14026 ;; which works around QImode/HImode not being allowed in vector registers in
14027 ;; ISA 2.07 (power8).
14028 (define_insn "fix<uns>_<IEEE128:mode><SDI:mode>2_hw"
14029   [(set (match_operand:SDI 0 "altivec_register_operand" "=v")
14030         (any_fix:SDI (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14031   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14032   "xscvqp<su><wd>z %0,%1"
14033   [(set_attr "type" "vecfloat")
14034    (set_attr "size" "128")])
14036 (define_insn "fix<uns>_trunc<IEEE128:mode><QHI:mode>2"
14037   [(set (match_operand:QHI 0 "altivec_register_operand" "=v")
14038         (any_fix:QHI
14039          (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14040   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14041   "xscvqp<su>wz %0,%1"
14042   [(set_attr "type" "vecfloat")
14043    (set_attr "size" "128")])
14045 ;; Combiner patterns to prevent moving the result of converting an IEEE 128-bit
14046 ;; floating point value to 8/16/32-bit integer to GPR in order to save it.
14047 (define_insn_and_split "*fix<uns>_trunc<IEEE128:mode><QHSI:mode>2_mem"
14048   [(set (match_operand:QHSI 0 "memory_operand" "=Z")
14049         (any_fix:QHSI
14050          (match_operand:IEEE128 1 "altivec_register_operand" "v")))
14051    (clobber (match_scratch:QHSI 2 "=v"))]
14052   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14053   "#"
14054   "&& reload_completed"
14055   [(set (match_dup 2)
14056         (any_fix:QHSI (match_dup 1)))
14057    (set (match_dup 0)
14058         (match_dup 2))])
14060 (define_insn "float_<mode>di2_hw"
14061   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14062         (float:IEEE128 (match_operand:DI 1 "altivec_register_operand" "v")))]
14063   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14064   "xscvsdqp %0,%1"
14065   [(set_attr "type" "vecfloat")
14066    (set_attr "size" "128")])
14068 (define_insn_and_split "float_<mode>si2_hw"
14069   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14070         (float:IEEE128 (match_operand:SI 1 "nonimmediate_operand" "vrZ")))
14071    (clobber (match_scratch:DI 2 "=v"))]
14072   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14073   "#"
14074   "&& 1"
14075   [(set (match_dup 2)
14076         (sign_extend:DI (match_dup 1)))
14077    (set (match_dup 0)
14078         (float:IEEE128 (match_dup 2)))]
14080   if (GET_CODE (operands[2]) == SCRATCH)
14081     operands[2] = gen_reg_rtx (DImode);
14083   if (MEM_P (operands[1]))
14084     operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
14087 (define_insn_and_split "float<QHI:mode><IEEE128:mode>2"
14088   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v")
14089         (float:IEEE128 (match_operand:QHI 1 "nonimmediate_operand" "v,r,Z")))
14090    (clobber (match_scratch:DI 2 "=X,r,X"))]
14091   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14092   "#"
14093   "&& reload_completed"
14094   [(const_int 0)]
14096   rtx dest = operands[0];
14097   rtx src = operands[1];
14098   rtx dest_di = gen_rtx_REG (DImode, REGNO (dest));
14100   if (altivec_register_operand (src, <QHI:MODE>mode))
14101     emit_insn (gen_extend<QHI:mode>di2 (dest_di, src));
14102   else if (int_reg_operand (src, <QHI:MODE>mode))
14103     {
14104       rtx ext_di = operands[2];
14105       emit_insn (gen_extend<QHI:mode>di2 (ext_di, src));
14106       emit_move_insn (dest_di, ext_di);
14107     }
14108   else if (MEM_P (src))
14109     {
14110       rtx dest_qhi = gen_rtx_REG (<QHI:MODE>mode, REGNO (dest));
14111       emit_move_insn (dest_qhi, src);
14112       emit_insn (gen_extend<QHI:mode>di2 (dest_di, dest_qhi));
14113     }
14114   else
14115     gcc_unreachable ();
14117   emit_insn (gen_float_<IEEE128:mode>di2_hw (dest, dest_di));
14118   DONE;
14120   [(set_attr "length" "8,12,12")
14121    (set_attr "type" "vecfloat")
14122    (set_attr "size" "128")])
14124 (define_insn "floatuns_<mode>di2_hw"
14125   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14126         (unsigned_float:IEEE128
14127          (match_operand:DI 1 "altivec_register_operand" "v")))]
14128   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14129   "xscvudqp %0,%1"
14130   [(set_attr "type" "vecfloat")
14131    (set_attr "size" "128")])
14133 (define_insn_and_split "floatuns_<mode>si2_hw"
14134   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14135         (unsigned_float:IEEE128
14136          (match_operand:SI 1 "nonimmediate_operand" "vrZ")))
14137    (clobber (match_scratch:DI 2 "=v"))]
14138   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14139   "#"
14140   "&& 1"
14141   [(set (match_dup 2)
14142         (zero_extend:DI (match_dup 1)))
14143    (set (match_dup 0)
14144         (float:IEEE128 (match_dup 2)))]
14146   if (GET_CODE (operands[2]) == SCRATCH)
14147     operands[2] = gen_reg_rtx (DImode);
14149   if (MEM_P (operands[1]))
14150     operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
14153 (define_insn_and_split "floatuns<QHI:mode><IEEE128:mode>2"
14154   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v")
14155         (unsigned_float:IEEE128
14156          (match_operand:QHI 1 "nonimmediate_operand" "v,r,Z")))
14157    (clobber (match_scratch:DI 2 "=X,r,X"))]
14158   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14159   "#"
14160   "&& reload_completed"
14161   [(const_int 0)]
14163   rtx dest = operands[0];
14164   rtx src = operands[1];
14165   rtx dest_di = gen_rtx_REG (DImode, REGNO (dest));
14167   if (altivec_register_operand (src, <QHI:MODE>mode) || MEM_P (src))
14168     emit_insn (gen_zero_extend<QHI:mode>di2 (dest_di, src));
14169   else if (int_reg_operand (src, <QHI:MODE>mode))
14170     {
14171       rtx ext_di = operands[2];
14172       emit_insn (gen_zero_extend<QHI:mode>di2 (ext_di, src));
14173       emit_move_insn (dest_di, ext_di);
14174     }
14175   else
14176     gcc_unreachable ();
14178   emit_insn (gen_floatuns_<IEEE128:mode>di2_hw (dest, dest_di));
14179   DONE;
14181   [(set_attr "length" "8,12,8")
14182    (set_attr "type" "vecfloat")
14183    (set_attr "size" "128")])
14185 ;; IEEE 128-bit round to integer built-in functions
14186 (define_insn "floor<mode>2"
14187   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14188         (unspec:IEEE128
14189          [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14190          UNSPEC_FRIM))]
14191   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14192   "xsrqpi 1,%0,%1,3"
14193   [(set_attr "type" "vecfloat")
14194    (set_attr "size" "128")])
14196 (define_insn "ceil<mode>2"
14197   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14198         (unspec:IEEE128
14199          [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14200          UNSPEC_FRIP))]
14201   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14202   "xsrqpi 1,%0,%1,2"
14203   [(set_attr "type" "vecfloat")
14204    (set_attr "size" "128")])
14206 (define_insn "btrunc<mode>2"
14207   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14208         (unspec:IEEE128
14209          [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14210          UNSPEC_FRIZ))]
14211   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14212   "xsrqpi 1,%0,%1,1"
14213   [(set_attr "type" "vecfloat")
14214    (set_attr "size" "128")])
14216 (define_insn "round<mode>2"
14217   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14218         (unspec:IEEE128
14219          [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14220          UNSPEC_FRIN))]
14221   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14222   "xsrqpi 0,%0,%1,0"
14223   [(set_attr "type" "vecfloat")
14224    (set_attr "size" "128")])
14226 ;; IEEE 128-bit instructions with round to odd semantics
14227 (define_insn "add<mode>3_odd"
14228   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14229         (unspec:IEEE128
14230          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14231           (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14232          UNSPEC_ADD_ROUND_TO_ODD))]
14233   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14234   "xsaddqpo %0,%1,%2"
14235   [(set_attr "type" "vecfloat")
14236    (set_attr "size" "128")])
14238 (define_insn "sub<mode>3_odd"
14239   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14240         (unspec:IEEE128
14241          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14242           (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14243          UNSPEC_SUB_ROUND_TO_ODD))]
14244   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14245   "xssubqpo %0,%1,%2"
14246   [(set_attr "type" "vecfloat")
14247    (set_attr "size" "128")])
14249 (define_insn "mul<mode>3_odd"
14250   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14251         (unspec:IEEE128
14252          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14253           (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14254          UNSPEC_MUL_ROUND_TO_ODD))]
14255   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14256   "xsmulqpo %0,%1,%2"
14257   [(set_attr "type" "qmul")
14258    (set_attr "size" "128")])
14260 (define_insn "div<mode>3_odd"
14261   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14262         (unspec:IEEE128
14263          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14264           (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14265          UNSPEC_DIV_ROUND_TO_ODD))]
14266   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14267   "xsdivqpo %0,%1,%2"
14268   [(set_attr "type" "vecdiv")
14269    (set_attr "size" "128")])
14271 (define_insn "sqrt<mode>2_odd"
14272   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14273         (unspec:IEEE128
14274          [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14275          UNSPEC_SQRT_ROUND_TO_ODD))]
14276   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14277    "xssqrtqpo %0,%1"
14278   [(set_attr "type" "vecdiv")
14279    (set_attr "size" "128")])
14281 (define_insn "fma<mode>4_odd"
14282   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14283         (unspec:IEEE128
14284          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14285           (match_operand:IEEE128 2 "altivec_register_operand" "v")
14286           (match_operand:IEEE128 3 "altivec_register_operand" "0")]
14287          UNSPEC_FMA_ROUND_TO_ODD))]
14288   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14289   "xsmaddqpo %0,%1,%2"
14290   [(set_attr "type" "qmul")
14291    (set_attr "size" "128")])
14293 (define_insn "*fms<mode>4_odd"
14294   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14295         (unspec:IEEE128
14296          [(match_operand:IEEE128 1 "altivec_register_operand" "%v")
14297           (match_operand:IEEE128 2 "altivec_register_operand" "v")
14298           (neg:IEEE128
14299            (match_operand:IEEE128 3 "altivec_register_operand" "0"))]
14300          UNSPEC_FMA_ROUND_TO_ODD))]
14301   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14302   "xsmsubqpo %0,%1,%2"
14303   [(set_attr "type" "qmul")
14304    (set_attr "size" "128")])
14306 (define_insn "*nfma<mode>4_odd"
14307   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14308         (neg:IEEE128
14309          (unspec:IEEE128
14310           [(match_operand:IEEE128 1 "altivec_register_operand" "%v")
14311            (match_operand:IEEE128 2 "altivec_register_operand" "v")
14312            (match_operand:IEEE128 3 "altivec_register_operand" "0")]
14313           UNSPEC_FMA_ROUND_TO_ODD)))]
14314   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14315   "xsnmaddqpo %0,%1,%2"
14316   [(set_attr "type" "qmul")
14317    (set_attr "size" "128")])
14319 (define_insn "*nfms<mode>4_odd"
14320   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14321         (neg:IEEE128
14322          (unspec:IEEE128
14323           [(match_operand:IEEE128 1 "altivec_register_operand" "%v")
14324            (match_operand:IEEE128 2 "altivec_register_operand" "v")
14325            (neg:IEEE128
14326             (match_operand:IEEE128 3 "altivec_register_operand" "0"))]
14327           UNSPEC_FMA_ROUND_TO_ODD)))]
14328   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14329   "xsnmsubqpo %0,%1,%2"
14330   [(set_attr "type" "qmul")
14331    (set_attr "size" "128")])
14333 (define_insn "trunc<mode>df2_odd"
14334   [(set (match_operand:DF 0 "vsx_register_operand" "=v")
14335         (unspec:DF [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14336                    UNSPEC_TRUNC_ROUND_TO_ODD))]
14337   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14338   "xscvqpdpo %0,%1"
14339   [(set_attr "type" "vecfloat")
14340    (set_attr "size" "128")])
14342 ;; IEEE 128-bit comparisons
14343 (define_insn "*cmp<mode>_hw"
14344   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
14345         (compare:CCFP (match_operand:IEEE128 1 "altivec_register_operand" "v")
14346                       (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14347   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14348    "xscmpuqp %0,%1,%2"
14349   [(set_attr "type" "veccmp")
14350    (set_attr "size" "128")])
14354 (include "sync.md")
14355 (include "vector.md")
14356 (include "vsx.md")
14357 (include "altivec.md")
14358 (include "dfp.md")
14359 (include "crypto.md")
14360 (include "htm.md")