[RS6000] movdi_internal64 insn lengths
[official-gcc.git] / gcc / config / rs6000 / rs6000.md
blobd2f6f11b3e5b19cacfe5a70b4686fcf953dbc806
1 ;; Machine description for IBM RISC System 6000 (POWER) for GNU C compiler
2 ;; Copyright (C) 1990-2018 Free Software Foundation, Inc.
3 ;; Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
5 ;; This file is part of GCC.
7 ;; GCC is free software; you can redistribute it and/or modify it
8 ;; under the terms of the GNU General Public License as published
9 ;; by the Free Software Foundation; either version 3, or (at your
10 ;; option) any later version.
12 ;; GCC is distributed in the hope that it will be useful, but WITHOUT
13 ;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 ;; or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
15 ;; License for more details.
17 ;; You should have received a copy of the GNU General Public License
18 ;; along with GCC; see the file COPYING3.  If not see
19 ;; <http://www.gnu.org/licenses/>.
21 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
24 ;; REGNOS
27 (define_constants
28   [(FIRST_GPR_REGNO             0)
29    (STACK_POINTER_REGNUM        1)
30    (TOC_REGNUM                  2)
31    (STATIC_CHAIN_REGNUM         11)
32    (HARD_FRAME_POINTER_REGNUM   31)
33    (LAST_GPR_REGNO              31)
34    (FIRST_FPR_REGNO             32)
35    (LAST_FPR_REGNO              63)
36    (LR_REGNO                    65)
37    (CTR_REGNO                   66)
38    (ARG_POINTER_REGNUM          67)
39    (CR0_REGNO                   68)
40    (CR1_REGNO                   69)
41    (CR2_REGNO                   70)
42    (CR3_REGNO                   71)
43    (CR4_REGNO                   72)
44    (CR5_REGNO                   73)
45    (CR6_REGNO                   74)
46    (CR7_REGNO                   75)
47    (MAX_CR_REGNO                75)
48    (CA_REGNO                    76)
49    (FIRST_ALTIVEC_REGNO         77)
50    (LAST_ALTIVEC_REGNO          108)
51    (VRSAVE_REGNO                109)
52    (VSCR_REGNO                  110)
53    (FRAME_POINTER_REGNUM        111)
54    (TFHAR_REGNO                 112)
55    (TFIAR_REGNO                 113)
56    (TEXASR_REGNO                114)
57   ])
60 ;; UNSPEC usage
63 (define_c_enum "unspec"
64   [UNSPEC_FRSP                  ; frsp for POWER machines
65    UNSPEC_PROBE_STACK           ; probe stack memory reference
66    UNSPEC_TOCPTR                ; address of a word pointing to the TOC
67    UNSPEC_TOC                   ; address of the TOC (more-or-less)
68    UNSPEC_TOCSLOT               ; offset from r1 of toc pointer save slot
69    UNSPEC_MOVSI_GOT
70    UNSPEC_MV_CR_OV              ; move_from_CR_ov_bit
71    UNSPEC_FCTIWZ
72    UNSPEC_FRIM
73    UNSPEC_FRIN
74    UNSPEC_FRIP
75    UNSPEC_FRIZ
76    UNSPEC_XSRDPI
77    UNSPEC_LD_MPIC               ; load_macho_picbase
78    UNSPEC_RELD_MPIC             ; re-load_macho_picbase
79    UNSPEC_MPIC_CORRECT          ; macho_correct_pic
80    UNSPEC_TLSGD
81    UNSPEC_TLSLD
82    UNSPEC_MOVESI_FROM_CR
83    UNSPEC_MOVESI_TO_CR
84    UNSPEC_TLSDTPREL
85    UNSPEC_TLSDTPRELHA
86    UNSPEC_TLSDTPRELLO
87    UNSPEC_TLSGOTDTPREL
88    UNSPEC_TLSTPREL
89    UNSPEC_TLSTPRELHA
90    UNSPEC_TLSTPRELLO
91    UNSPEC_TLSGOTTPREL
92    UNSPEC_TLSTLS
93    UNSPEC_FIX_TRUNC_TF          ; fadd, rounding towards zero
94    UNSPEC_STFIWX
95    UNSPEC_POPCNTB
96    UNSPEC_FRES
97    UNSPEC_SP_SET
98    UNSPEC_SP_TEST
99    UNSPEC_SYNC
100    UNSPEC_LWSYNC
101    UNSPEC_SYNC_OP
102    UNSPEC_ATOMIC
103    UNSPEC_CMPXCHG
104    UNSPEC_XCHG
105    UNSPEC_AND
106    UNSPEC_DLMZB
107    UNSPEC_DLMZB_CR
108    UNSPEC_DLMZB_STRLEN
109    UNSPEC_RSQRT
110    UNSPEC_TOCREL
111    UNSPEC_MACHOPIC_OFFSET
112    UNSPEC_BPERM
113    UNSPEC_COPYSIGN
114    UNSPEC_PARITY
115    UNSPEC_CMPB
116    UNSPEC_FCTIW
117    UNSPEC_FCTID
118    UNSPEC_LFIWAX
119    UNSPEC_LFIWZX
120    UNSPEC_FCTIWUZ
121    UNSPEC_NOP
122    UNSPEC_GRP_END_NOP
123    UNSPEC_P8V_FMRGOW
124    UNSPEC_P8V_MTVSRWZ
125    UNSPEC_P8V_RELOAD_FROM_GPR
126    UNSPEC_P8V_MTVSRD
127    UNSPEC_P8V_XXPERMDI
128    UNSPEC_P8V_RELOAD_FROM_VSX
129    UNSPEC_ADDG6S
130    UNSPEC_CDTBCD
131    UNSPEC_CBCDTD
132    UNSPEC_DIVE
133    UNSPEC_DIVEU
134    UNSPEC_UNPACK_128BIT
135    UNSPEC_PACK_128BIT
136    UNSPEC_LSQ
137    UNSPEC_FUSION_GPR
138    UNSPEC_STACK_CHECK
139    UNSPEC_ADD_ROUND_TO_ODD
140    UNSPEC_SUB_ROUND_TO_ODD
141    UNSPEC_MUL_ROUND_TO_ODD
142    UNSPEC_DIV_ROUND_TO_ODD
143    UNSPEC_FMA_ROUND_TO_ODD
144    UNSPEC_SQRT_ROUND_TO_ODD
145    UNSPEC_TRUNC_ROUND_TO_ODD
146    UNSPEC_SIGNBIT
147    UNSPEC_SF_FROM_SI
148    UNSPEC_SI_FROM_SF
149    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       || GET_CODE (align) != CONST_INT
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 (GET_CODE (operands[2]) != CONST_INT
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 can do a SFmode store without having to do the
7018 ;; conversion explicitly.  If we are doing a register->register conversion, use
7019 ;; XSCVDPSP instead of XSCVDPSPN, since the former handles cases where the
7020 ;; input will not fit in a SFmode, and the later assumes the value has already
7021 ;; been rounded.
7022 (define_insn "*movsi_from_df"
7023   [(set (match_operand:SI 0 "nonimmediate_operand"         "=wa,m,wY,Z")
7024         (unspec:SI [(float_truncate:SF
7025                      (match_operand:DF 1 "gpc_reg_operand" "wa, f,wb,wa"))]
7026                     UNSPEC_SI_FROM_SF))]
7028   "TARGET_NO_SF_SUBREG"
7029   "@
7030    xscvdpsp %x0,%x1
7031    stfs%U0%X0 %1,%0
7032    stxssp %1,%0
7033    stxsspx %x1,%y0"
7034   [(set_attr "type"   "fp,fpstore,fpstore,fpstore")])
7036 ;; Split a load of a large constant into the appropriate two-insn
7037 ;; sequence.
7039 (define_split
7040   [(set (match_operand:SI 0 "gpc_reg_operand")
7041         (match_operand:SI 1 "const_int_operand"))]
7042   "(unsigned HOST_WIDE_INT) (INTVAL (operands[1]) + 0x8000) >= 0x10000
7043    && (INTVAL (operands[1]) & 0xffff) != 0"
7044   [(set (match_dup 0)
7045         (match_dup 2))
7046    (set (match_dup 0)
7047         (ior:SI (match_dup 0)
7048                 (match_dup 3)))]
7050   if (rs6000_emit_set_const (operands[0], operands[1]))
7051     DONE;
7052   else
7053     FAIL;
7056 ;; Split loading -128..127 to use XXSPLITB and VEXTSW2D
7057 (define_split
7058   [(set (match_operand:DI 0 "altivec_register_operand")
7059         (match_operand:DI 1 "xxspltib_constant_split"))]
7060   "TARGET_P9_VECTOR && reload_completed"
7061   [(const_int 0)]
7063   rtx op0 = operands[0];
7064   rtx op1 = operands[1];
7065   int r = REGNO (op0);
7066   rtx op0_v16qi = gen_rtx_REG (V16QImode, r);
7068   emit_insn (gen_xxspltib_v16qi (op0_v16qi, op1));
7069   emit_insn (gen_vsx_sign_extend_qi_si (operands[0], op0_v16qi));
7070   DONE;
7073 (define_insn "*mov<mode>_internal2"
7074   [(set (match_operand:CC 2 "cc_reg_operand" "=y,x,?y")
7075         (compare:CC (match_operand:P 1 "gpc_reg_operand" "0,r,r")
7076                     (const_int 0)))
7077    (set (match_operand:P 0 "gpc_reg_operand" "=r,r,r") (match_dup 1))]
7078   ""
7079   "@
7080    cmp<wd>i %2,%0,0
7081    mr. %0,%1
7082    #"
7083   [(set_attr "type" "cmp,logical,cmp")
7084    (set_attr "dot" "yes")
7085    (set_attr "length" "4,4,8")])
7087 (define_split
7088   [(set (match_operand:CC 2 "cc_reg_not_cr0_operand")
7089         (compare:CC (match_operand:P 1 "gpc_reg_operand")
7090                     (const_int 0)))
7091    (set (match_operand:P 0 "gpc_reg_operand") (match_dup 1))]
7092   "reload_completed"
7093   [(set (match_dup 0) (match_dup 1))
7094    (set (match_dup 2)
7095         (compare:CC (match_dup 0)
7096                     (const_int 0)))]
7097   "")
7099 (define_expand "mov<mode>"
7100   [(set (match_operand:INT 0 "general_operand")
7101         (match_operand:INT 1 "any_operand"))]
7102   ""
7104   rs6000_emit_move (operands[0], operands[1], <MODE>mode);
7105   DONE;
7108 ;;              MR          LHZ/LBZ    LXSI*ZX    STH/STB    STXSI*X    LI
7109 ;;              XXLOR       load 0     load -1    VSPLTI*    #          MFVSRWZ
7110 ;;              MTVSRWZ     MF%1       MT%1       NOP
7111 (define_insn "*mov<mode>_internal"
7112   [(set (match_operand:QHI 0 "nonimmediate_operand"
7113                 "=r,        r,         ?*wJwK,    m,         Z,         r,
7114                  ?*wJwK,    ?*wJwK,    ?*wJwK,    ?*wK,      ?*wK,      r,
7115                  ?*wJwK,    r,         *c*l,      *h")
7117         (match_operand:QHI 1 "input_operand"
7118                 "r,         m,         Z,         r,         wJwK,      i,
7119                  wJwK,      O,         wM,        wB,        wS,        ?*wJwK,
7120                  r,         *h,        r,         0"))]
7122   "gpc_reg_operand (operands[0], <MODE>mode)
7123    || gpc_reg_operand (operands[1], <MODE>mode)"
7124   "@
7125    mr %0,%1
7126    l<wd>z%U1%X1 %0,%1
7127    lxsi<wd>zx %x0,%y1
7128    st<wd>%U0%X0 %1,%0
7129    stxsi<wd>x %x1,%y0
7130    li %0,%1
7131    xxlor %x0,%x1,%x1
7132    xxspltib %x0,0
7133    xxspltib %x0,255
7134    vspltis<wd> %0,%1
7135    #
7136    mfvsrwz %0,%x1
7137    mtvsrwz %x0,%1
7138    mf%1 %0
7139    mt%0 %1
7140    nop"
7141   [(set_attr "type"
7142                 "*,         load,      fpload,    store,     fpstore,   *,
7143                  vecsimple, vecperm,   vecperm,   vecperm,   vecperm,   mftgpr,
7144                  mffgpr,    mfjmpr,    mtjmpr,    *")
7146    (set_attr "length"
7147                 "4,         4,         4,         4,         4,         4,
7148                  4,         4,         4,         4,         8,         4,
7149                  4,         4,         4,         4")])
7152 ;; Here is how to move condition codes around.  When we store CC data in
7153 ;; an integer register or memory, we store just the high-order 4 bits.
7154 ;; This lets us not shift in the most common case of CR0.
7155 (define_expand "movcc"
7156   [(set (match_operand:CC 0 "nonimmediate_operand")
7157         (match_operand:CC 1 "nonimmediate_operand"))]
7158   ""
7159   "")
7161 (define_insn "*movcc_internal1"
7162   [(set (match_operand:CC 0 "nonimmediate_operand"
7163                             "=y,x,?y,y,r,r,r,r, r,*c*l,r,m")
7164         (match_operand:CC 1 "general_operand"
7165                             " y,r, r,O,x,y,r,I,*h,   r,m,r"))]
7166   "register_operand (operands[0], CCmode)
7167    || register_operand (operands[1], CCmode)"
7168   "@
7169    mcrf %0,%1
7170    mtcrf 128,%1
7171    rlwinm %1,%1,%F0,0xffffffff\;mtcrf %R0,%1\;rlwinm %1,%1,%f0,0xffffffff
7172    crxor %0,%0,%0
7173    mfcr %0%Q1
7174    mfcr %0%Q1\;rlwinm %0,%0,%f1,0xf0000000
7175    mr %0,%1
7176    li %0,%1
7177    mf%1 %0
7178    mt%0 %1
7179    lwz%U1%X1 %0,%1
7180    stw%U0%X0 %1,%0"
7181   [(set_attr_alternative "type"
7182      [(const_string "cr_logical")
7183       (const_string "mtcr")
7184       (const_string "mtcr")
7185       (const_string "cr_logical")
7186       (if_then_else (match_test "TARGET_MFCRF")
7187                     (const_string "mfcrf") (const_string "mfcr"))
7188       (if_then_else (match_test "TARGET_MFCRF")
7189                     (const_string "mfcrf") (const_string "mfcr"))
7190       (const_string "integer")
7191       (const_string "integer")
7192       (const_string "mfjmpr")
7193       (const_string "mtjmpr")
7194       (const_string "load")
7195       (const_string "store")])
7196    (set_attr "length" "4,4,12,4,4,8,4,4,4,4,4,4")])
7198 ;; For floating-point, we normally deal with the floating-point registers
7199 ;; unless -msoft-float is used.  The sole exception is that parameter passing
7200 ;; can produce floating-point values in fixed-point registers.  Unless the
7201 ;; value is a simple constant or already in memory, we deal with this by
7202 ;; allocating memory and copying the value explicitly via that memory location.
7204 ;; Move 32-bit binary/decimal floating point
7205 (define_expand "mov<mode>"
7206   [(set (match_operand:FMOVE32 0 "nonimmediate_operand")
7207         (match_operand:FMOVE32 1 "any_operand"))]
7208   "<fmove_ok>"
7210   rs6000_emit_move (operands[0], operands[1], <MODE>mode);
7211   DONE;
7214 (define_split
7215   [(set (match_operand:FMOVE32 0 "gpc_reg_operand")
7216         (match_operand:FMOVE32 1 "const_double_operand"))]
7217   "reload_completed
7218    && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
7219        || (GET_CODE (operands[0]) == SUBREG
7220            && GET_CODE (SUBREG_REG (operands[0])) == REG
7221            && REGNO (SUBREG_REG (operands[0])) <= 31))"
7222   [(set (match_dup 2) (match_dup 3))]
7224   long l;
7226   <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7228   if (! TARGET_POWERPC64)
7229     operands[2] = operand_subword (operands[0], 0, 0, <MODE>mode);
7230   else
7231     operands[2] = gen_lowpart (SImode, operands[0]);
7233   operands[3] = gen_int_mode (l, SImode);
7236 ;; Originally, we tried to keep movsf and movsd common, but the differences
7237 ;; addressing was making it rather difficult to hide with mode attributes.  In
7238 ;; particular for SFmode, on ISA 2.07 (power8) systems, having the GPR store
7239 ;; before the VSX stores meant that the register allocator would tend to do a
7240 ;; direct move to the GPR (which involves conversion from scalar to
7241 ;; vector/memory formats) to save values in the traditional Altivec registers,
7242 ;; while SDmode had problems on power6 if the GPR store was not first due to
7243 ;; the power6 not having an integer store operation.
7245 ;;      LWZ          LFS        LXSSP       LXSSPX     STFS       STXSSP
7246 ;;      STXSSPX      STW        XXLXOR      LI         FMR        XSCPSGNDP
7247 ;;      MR           MT<x>      MF<x>       NOP
7249 (define_insn "movsf_hardfloat"
7250   [(set (match_operand:SF 0 "nonimmediate_operand"
7251          "=!r,       f,         wb,         wu,        m,         wY,
7252           Z,         m,         ww,         !r,        f,         ww,
7253           !r,        *c*l,      !r,         *h")
7254         (match_operand:SF 1 "input_operand"
7255          "m,         m,         wY,         Z,         f,         wb,
7256           wu,        r,         j,          j,         f,         ww,
7257           r,         r,         *h,         0"))]
7258   "(register_operand (operands[0], SFmode)
7259    || register_operand (operands[1], SFmode))
7260    && TARGET_HARD_FLOAT
7261    && (TARGET_ALLOW_SF_SUBREG
7262        || valid_sf_si_move (operands[0], operands[1], SFmode))"
7263   "@
7264    lwz%U1%X1 %0,%1
7265    lfs%U1%X1 %0,%1
7266    lxssp %0,%1
7267    lxsspx %x0,%y1
7268    stfs%U0%X0 %1,%0
7269    stxssp %1,%0
7270    stxsspx %x1,%y0
7271    stw%U0%X0 %1,%0
7272    xxlxor %x0,%x0,%x0
7273    li %0,0
7274    fmr %0,%1
7275    xscpsgndp %x0,%x1,%x1
7276    mr %0,%1
7277    mt%0 %1
7278    mf%1 %0
7279    nop"
7280   [(set_attr "type"
7281         "load,       fpload,    fpload,     fpload,    fpstore,   fpstore,
7282          fpstore,    store,     veclogical, integer,   fpsimple,  fpsimple,
7283          *,          mtjmpr,    mfjmpr,     *")])
7285 ;;      LWZ          LFIWZX     STW        STFIWX     MTVSRWZ    MFVSRWZ
7286 ;;      FMR          MR         MT%0       MF%1       NOP
7287 (define_insn "movsd_hardfloat"
7288   [(set (match_operand:SD 0 "nonimmediate_operand"
7289          "=!r,       wz,        m,         Z,         ?wh,       ?r,
7290           f,         !r,        *c*l,      !r,        *h")
7291         (match_operand:SD 1 "input_operand"
7292          "m,         Z,         r,         wx,        r,         wh,
7293           f,         r,         r,         *h,        0"))]
7294   "(register_operand (operands[0], SDmode)
7295    || register_operand (operands[1], SDmode))
7296    && TARGET_HARD_FLOAT"
7297   "@
7298    lwz%U1%X1 %0,%1
7299    lfiwzx %0,%y1
7300    stw%U0%X0 %1,%0
7301    stfiwx %1,%y0
7302    mtvsrwz %x0,%1
7303    mfvsrwz %0,%x1
7304    fmr %0,%1
7305    mr %0,%1
7306    mt%0 %1
7307    mf%1 %0
7308    nop"
7309   [(set_attr "type"
7310         "load,       fpload,    store,     fpstore,   mffgpr,    mftgpr,
7311          fpsimple,   *,         mtjmpr,    mfjmpr,    *")])
7313 ;;      MR           MT%0       MF%0       LWZ        STW        LI
7314 ;;      LIS          G-const.   F/n-const  NOP
7315 (define_insn "*mov<mode>_softfloat"
7316   [(set (match_operand:FMOVE32 0 "nonimmediate_operand"
7317         "=r,         *c*l,      r,         r,         m,         r,
7318           r,         r,         r,         *h")
7320         (match_operand:FMOVE32 1 "input_operand"
7321          "r,         r,         *h,        m,         r,         I,
7322           L,         G,         Fn,        0"))]
7324   "(gpc_reg_operand (operands[0], <MODE>mode)
7325    || gpc_reg_operand (operands[1], <MODE>mode))
7326    && TARGET_SOFT_FLOAT"
7327   "@
7328    mr %0,%1
7329    mt%0 %1
7330    mf%1 %0
7331    lwz%U1%X1 %0,%1
7332    stw%U0%X0 %1,%0
7333    li %0,%1
7334    lis %0,%v1
7335    #
7336    #
7337    nop"
7338   [(set_attr "type"
7339         "*,          mtjmpr,    mfjmpr,    load,      store,     *,
7340          *,          *,         *,         *")
7342    (set_attr "length"
7343         "4,          4,         4,         4,         4,         4,
7344          4,          4,         8,         4")])
7346 ;; Like movsf, but adjust a SI value to be used in a SF context, i.e.
7347 ;; (set (reg:SF ...) (subreg:SF (reg:SI ...) 0))
7349 ;; Because SF values are actually stored as DF values within the vector
7350 ;; registers, we need to convert the value to the vector SF format when
7351 ;; we need to use the bits in a union or similar cases.  We only need
7352 ;; to do this transformation when the value is a vector register.  Loads,
7353 ;; stores, and transfers within GPRs are assumed to be safe.
7355 ;; This is a more general case of reload_vsx_from_gprsf.  That insn must have
7356 ;; no alternatives, because the call is created as part of secondary_reload,
7357 ;; and operand #2's register class is used to allocate the temporary register.
7358 ;; This function is called before reload, and it creates the temporary as
7359 ;; needed.
7361 ;;          LWZ          LFS        LXSSP      LXSSPX     STW        STFIWX
7362 ;;          STXSIWX      GPR->VSX   VSX->GPR   GPR->GPR
7363 (define_insn_and_split "movsf_from_si"
7364   [(set (match_operand:SF 0 "nonimmediate_operand"
7365             "=!r,       f,         wb,        wu,        m,         Z,
7366              Z,         wy,        ?r,        !r")
7368         (unspec:SF [(match_operand:SI 1 "input_operand" 
7369             "m,         m,         wY,        Z,         r,         f,
7370              wu,        r,         wy,        r")]
7371                    UNSPEC_SF_FROM_SI))
7373    (clobber (match_scratch:DI 2
7374             "=X,        X,         X,         X,         X,         X,
7375              X,         r,         X,         X"))]
7377   "TARGET_NO_SF_SUBREG
7378    && (register_operand (operands[0], SFmode)
7379        || register_operand (operands[1], SImode))"
7380   "@
7381    lwz%U1%X1 %0,%1
7382    lfs%U1%X1 %0,%1
7383    lxssp %0,%1
7384    lxsspx %x0,%y1
7385    stw%U0%X0 %1,%0
7386    stfiwx %1,%y0
7387    stxsiwx %x1,%y0
7388    #
7389    mfvsrwz %0,%x1
7390    mr %0,%1"
7392   "&& reload_completed
7393    && vsx_reg_sfsubreg_ok (operands[0], SFmode)
7394    && int_reg_operand_not_pseudo (operands[1], SImode)"
7395   [(const_int 0)]
7397   rtx op0 = operands[0];
7398   rtx op1 = operands[1];
7399   rtx op2 = operands[2];
7400   rtx op1_di = gen_rtx_REG (DImode, REGNO (op1));
7402   /* Move SF value to upper 32-bits for xscvspdpn.  */
7403   emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32)));
7404   emit_insn (gen_p8_mtvsrd_sf (op0, op2));
7405   emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0));
7406   DONE;
7408   [(set_attr "length"
7409             "4,          4,         4,         4,         4,         4,
7410              4,          12,        4,         4")
7411    (set_attr "type"
7412             "load,       fpload,    fpload,    fpload,    store,     fpstore,
7413              fpstore,    vecfloat,  mffgpr,    *")])
7416 ;; Move 64-bit binary/decimal floating point
7417 (define_expand "mov<mode>"
7418   [(set (match_operand:FMOVE64 0 "nonimmediate_operand")
7419         (match_operand:FMOVE64 1 "any_operand"))]
7420   ""
7422   rs6000_emit_move (operands[0], operands[1], <MODE>mode);
7423   DONE;
7426 (define_split
7427   [(set (match_operand:FMOVE64 0 "gpc_reg_operand")
7428         (match_operand:FMOVE64 1 "const_int_operand"))]
7429   "! TARGET_POWERPC64 && reload_completed
7430    && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
7431        || (GET_CODE (operands[0]) == SUBREG
7432            && GET_CODE (SUBREG_REG (operands[0])) == REG
7433            && REGNO (SUBREG_REG (operands[0])) <= 31))"
7434   [(set (match_dup 2) (match_dup 4))
7435    (set (match_dup 3) (match_dup 1))]
7437   int endian = (WORDS_BIG_ENDIAN == 0);
7438   HOST_WIDE_INT value = INTVAL (operands[1]);
7440   operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
7441   operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
7442   operands[4] = GEN_INT (value >> 32);
7443   operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
7446 (define_split
7447   [(set (match_operand:FMOVE64 0 "gpc_reg_operand")
7448         (match_operand:FMOVE64 1 "const_double_operand"))]
7449   "! TARGET_POWERPC64 && reload_completed
7450    && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
7451        || (GET_CODE (operands[0]) == SUBREG
7452            && GET_CODE (SUBREG_REG (operands[0])) == REG
7453            && REGNO (SUBREG_REG (operands[0])) <= 31))"
7454   [(set (match_dup 2) (match_dup 4))
7455    (set (match_dup 3) (match_dup 5))]
7457   int endian = (WORDS_BIG_ENDIAN == 0);
7458   long l[2];
7460   <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7462   operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
7463   operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
7464   operands[4] = gen_int_mode (l[endian], SImode);
7465   operands[5] = gen_int_mode (l[1 - endian], SImode);
7468 (define_split
7469   [(set (match_operand:FMOVE64 0 "gpc_reg_operand")
7470         (match_operand:FMOVE64 1 "const_double_operand"))]
7471   "TARGET_POWERPC64 && reload_completed
7472    && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
7473        || (GET_CODE (operands[0]) == SUBREG
7474            && GET_CODE (SUBREG_REG (operands[0])) == REG
7475            && REGNO (SUBREG_REG (operands[0])) <= 31))"
7476   [(set (match_dup 2) (match_dup 3))]
7478   int endian = (WORDS_BIG_ENDIAN == 0);
7479   long l[2];
7480   HOST_WIDE_INT val;
7482   <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7484   operands[2] = gen_lowpart (DImode, operands[0]);
7485   /* HIGHPART is lower memory address when WORDS_BIG_ENDIAN.  */
7486   val = ((HOST_WIDE_INT)(unsigned long)l[endian] << 32
7487          | ((HOST_WIDE_INT)(unsigned long)l[1 - endian]));
7489   operands[3] = gen_int_mode (val, DImode);
7492 ;; Don't have reload use general registers to load a constant.  It is
7493 ;; less efficient than loading the constant into an FP register, since
7494 ;; it will probably be used there.
7496 ;; The move constraints are ordered to prefer floating point registers before
7497 ;; general purpose registers to avoid doing a store and a load to get the value
7498 ;; into a floating point register when it is needed for a floating point
7499 ;; operation.  Prefer traditional floating point registers over VSX registers,
7500 ;; since the D-form version of the memory instructions does not need a GPR for
7501 ;; reloading.  ISA 3.0 (power9) adds D-form addressing for scalars to Altivec
7502 ;; registers.
7504 ;; If we have FPR registers, rs6000_emit_move has moved all constants to memory,
7505 ;; except for 0.0 which can be created on VSX with an xor instruction.
7507 ;;           STFD         LFD         FMR         LXSD        STXSD
7508 ;;           LXSD         STXSD       XXLOR       XXLXOR      GPR<-0
7509 ;;           LWZ          STW         MR
7512 (define_insn "*mov<mode>_hardfloat32"
7513   [(set (match_operand:FMOVE64 0 "nonimmediate_operand"
7514             "=m,          d,          d,          <f64_p9>,   wY,
7515               <f64_av>,   Z,          <f64_vsx>,  <f64_vsx>,  !r,
7516               Y,          r,          !r")
7518         (match_operand:FMOVE64 1 "input_operand"
7519              "d,          m,          d,          wY,         <f64_p9>,
7520               Z,          <f64_av>,   <f64_vsx>,  <zero_fp>,  <zero_fp>,
7521               r,          Y,          r"))]
7523   "! TARGET_POWERPC64 && TARGET_HARD_FLOAT
7524    && (gpc_reg_operand (operands[0], <MODE>mode)
7525        || gpc_reg_operand (operands[1], <MODE>mode))"
7526   "@
7527    stfd%U0%X0 %1,%0
7528    lfd%U1%X1 %0,%1
7529    fmr %0,%1
7530    lxsd %0,%1
7531    stxsd %1,%0
7532    lxsdx %x0,%y1
7533    stxsdx %x1,%y0
7534    xxlor %x0,%x1,%x1
7535    xxlxor %x0,%x0,%x0
7536    #
7537    #
7538    #
7539    #"
7540   [(set_attr "type"
7541             "fpstore,     fpload,     fpsimple,   fpload,     fpstore,
7542              fpload,      fpstore,    veclogical, veclogical, two,
7543              store,       load,       two")
7545    (set_attr "size" "64")
7546    (set_attr "length"
7547             "4,           4,          4,          4,          4,
7548              4,           4,          4,          4,          8,
7549              8,           8,          8")])
7551 ;;           STW      LWZ     MR      G-const H-const F-const
7553 (define_insn "*mov<mode>_softfloat32"
7554   [(set (match_operand:FMOVE64 0 "nonimmediate_operand"
7555            "=Y,       r,      r,      r,      r,      r")
7557         (match_operand:FMOVE64 1 "input_operand"
7558             "r,       Y,      r,      G,      H,      F"))]
7560   "!TARGET_POWERPC64
7561    && (gpc_reg_operand (operands[0], <MODE>mode)
7562        || gpc_reg_operand (operands[1], <MODE>mode))"
7563   "#"
7564   [(set_attr "type"
7565             "store,   load,   two,    *,      *,      *")
7567    (set_attr "length"
7568              "8,      8,      8,      8,      12,     16")])
7570 ; ld/std require word-aligned displacements -> 'Y' constraint.
7571 ; List Y->r and r->Y before r->r for reload.
7573 ;;           STFD         LFD         FMR         LXSD        STXSD
7574 ;;           LXSDX        STXSDX      XXLOR       XXLXOR      LI 0
7575 ;;           STD          LD          MR          MT{CTR,LR}  MF{CTR,LR}
7576 ;;           NOP          MFTGPR      MFFGPR      MFVSRD      MTVSRD
7578 (define_insn "*mov<mode>_hardfloat64"
7579   [(set (match_operand:FMOVE64 0 "nonimmediate_operand"
7580            "=m,           d,          d,          <f64_p9>,   wY,
7581              <f64_av>,    Z,          <f64_vsx>,  <f64_vsx>,  !r,
7582              YZ,          r,          !r,         *c*l,       !r,
7583             *h,           r,          wg,         r,          <f64_dm>")
7585         (match_operand:FMOVE64 1 "input_operand"
7586             "d,           m,          d,          wY,         <f64_p9>,
7587              Z,           <f64_av>,   <f64_vsx>,  <zero_fp>,  <zero_fp>,
7588              r,           YZ,         r,          r,          *h,
7589              0,           wg,         r,          <f64_dm>,   r"))]
7591   "TARGET_POWERPC64 && TARGET_HARD_FLOAT
7592    && (gpc_reg_operand (operands[0], <MODE>mode)
7593        || gpc_reg_operand (operands[1], <MODE>mode))"
7594   "@
7595    stfd%U0%X0 %1,%0
7596    lfd%U1%X1 %0,%1
7597    fmr %0,%1
7598    lxsd %0,%1
7599    stxsd %1,%0
7600    lxsdx %x0,%y1
7601    stxsdx %x1,%y0
7602    xxlor %x0,%x1,%x1
7603    xxlxor %x0,%x0,%x0
7604    li %0,0
7605    std%U0%X0 %1,%0
7606    ld%U1%X1 %0,%1
7607    mr %0,%1
7608    mt%0 %1
7609    mf%1 %0
7610    nop
7611    mftgpr %0,%1
7612    mffgpr %0,%1
7613    mfvsrd %0,%x1
7614    mtvsrd %x0,%1"
7615   [(set_attr "type"
7616             "fpstore,     fpload,     fpsimple,   fpload,     fpstore,
7617              fpload,      fpstore,    veclogical, veclogical, integer,
7618              store,       load,       *,          mtjmpr,     mfjmpr,
7619              *,           mftgpr,     mffgpr,     mftgpr,    mffgpr")
7621    (set_attr "size" "64")
7622    (set_attr "length" "4")])
7624 ;;           STD      LD       MR      MT<SPR> MF<SPR> G-const
7625 ;;           H-const  F-const  Special
7627 (define_insn "*mov<mode>_softfloat64"
7628   [(set (match_operand:FMOVE64 0 "nonimmediate_operand"
7629            "=Y,       r,      r,      *c*l,   r,      r,
7630              r,       r,      *h")
7632         (match_operand:FMOVE64 1 "input_operand"
7633             "r,       Y,      r,      r,      *h,     G,
7634              H,       F,      0"))]
7636   "TARGET_POWERPC64 && TARGET_SOFT_FLOAT
7637    && (gpc_reg_operand (operands[0], <MODE>mode)
7638        || gpc_reg_operand (operands[1], <MODE>mode))"
7639   "@
7640    std%U0%X0 %1,%0
7641    ld%U1%X1 %0,%1
7642    mr %0,%1
7643    mt%0 %1
7644    mf%1 %0
7645    #
7646    #
7647    #
7648    nop"
7649   [(set_attr "type"
7650             "store,   load,   *,      mtjmpr, mfjmpr, *,
7651              *,       *,      *")
7653    (set_attr "length"
7654             "4,       4,      4,      4,      4,      8,
7655              12,      16,     4")])
7657 (define_expand "mov<mode>"
7658   [(set (match_operand:FMOVE128 0 "general_operand")
7659         (match_operand:FMOVE128 1 "any_operand"))]
7660   ""
7662   rs6000_emit_move (operands[0], operands[1], <MODE>mode);
7663   DONE;
7666 ;; It's important to list Y->r and r->Y before r->r because otherwise
7667 ;; reload, given m->r, will try to pick r->r and reload it, which
7668 ;; doesn't make progress.
7670 ;; We can't split little endian direct moves of TDmode, because the words are
7671 ;; not swapped like they are for TImode or TFmode.  Subregs therefore are
7672 ;; problematical.  Don't allow direct move for this case.
7674 (define_insn_and_split "*mov<mode>_64bit_dm"
7675   [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand" "=m,d,d,d,Y,r,r,r,wh")
7676         (match_operand:FMOVE128_FPR 1 "input_operand" "d,m,d,<zero_fp>,r,<zero_fp>Y,r,wh,r"))]
7677   "TARGET_HARD_FLOAT && TARGET_POWERPC64 && FLOAT128_2REG_P (<MODE>mode)
7678    && (<MODE>mode != TDmode || WORDS_BIG_ENDIAN)
7679    && (gpc_reg_operand (operands[0], <MODE>mode)
7680        || gpc_reg_operand (operands[1], <MODE>mode))"
7681   "#"
7682   "&& reload_completed"
7683   [(pc)]
7684 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7685   [(set_attr "length" "8,8,8,8,12,12,8,8,8")])
7687 (define_insn_and_split "*movtd_64bit_nodm"
7688   [(set (match_operand:TD 0 "nonimmediate_operand" "=m,d,d,Y,r,r")
7689         (match_operand:TD 1 "input_operand" "d,m,d,r,Y,r"))]
7690   "TARGET_HARD_FLOAT && TARGET_POWERPC64 && !WORDS_BIG_ENDIAN
7691    && (gpc_reg_operand (operands[0], TDmode)
7692        || gpc_reg_operand (operands[1], TDmode))"
7693   "#"
7694   "&& reload_completed"
7695   [(pc)]
7696 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7697   [(set_attr "length" "8,8,8,12,12,8")])
7699 (define_insn_and_split "*mov<mode>_32bit"
7700   [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand" "=m,d,d,d,Y,r,r")
7701         (match_operand:FMOVE128_FPR 1 "input_operand" "d,m,d,<zero_fp>,r,<zero_fp>Y,r"))]
7702   "TARGET_HARD_FLOAT && !TARGET_POWERPC64
7703    && (FLOAT128_2REG_P (<MODE>mode)
7704        || int_reg_operand_not_pseudo (operands[0], <MODE>mode)
7705        || int_reg_operand_not_pseudo (operands[1], <MODE>mode))
7706    && (gpc_reg_operand (operands[0], <MODE>mode)
7707        || gpc_reg_operand (operands[1], <MODE>mode))"
7708   "#"
7709   "&& reload_completed"
7710   [(pc)]
7711 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7712   [(set_attr "length" "8,8,8,8,20,20,16")])
7714 (define_insn_and_split "*mov<mode>_softfloat"
7715   [(set (match_operand:FMOVE128 0 "nonimmediate_operand" "=Y,r,r,r")
7716         (match_operand:FMOVE128 1 "input_operand" "r,Y,F,r"))]
7717   "TARGET_SOFT_FLOAT
7718    && (gpc_reg_operand (operands[0], <MODE>mode)
7719        || gpc_reg_operand (operands[1], <MODE>mode))"
7720   "#"
7721   "&& reload_completed"
7722   [(pc)]
7723 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7724   [(set_attr_alternative "length"
7725        [(if_then_else (match_test "TARGET_POWERPC64")
7726             (const_string "8")
7727             (const_string "16"))
7728         (if_then_else (match_test "TARGET_POWERPC64")
7729             (const_string "8")
7730             (const_string "16"))
7731         (if_then_else (match_test "TARGET_POWERPC64")
7732             (const_string "40")
7733             (const_string "32"))
7734         (if_then_else (match_test "TARGET_POWERPC64")
7735             (const_string "8")
7736             (const_string "16"))])])
7738 (define_expand "extenddf<mode>2"
7739   [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
7740         (float_extend:FLOAT128 (match_operand:DF 1 "gpc_reg_operand")))]
7741   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7743   if (FLOAT128_IEEE_P (<MODE>mode))
7744     rs6000_expand_float128_convert (operands[0], operands[1], false);
7745   else if (TARGET_VSX)
7746     {
7747       if (<MODE>mode == TFmode)
7748         emit_insn (gen_extenddftf2_vsx (operands[0], operands[1]));
7749       else if (<MODE>mode == IFmode)
7750         emit_insn (gen_extenddfif2_vsx (operands[0], operands[1]));
7751       else
7752         gcc_unreachable ();
7753     }
7754    else
7755     {
7756       rtx zero = gen_reg_rtx (DFmode);
7757       rs6000_emit_move (zero, CONST0_RTX (DFmode), DFmode);
7759       if (<MODE>mode == TFmode)
7760         emit_insn (gen_extenddftf2_fprs (operands[0], operands[1], zero));
7761       else if (<MODE>mode == IFmode)
7762         emit_insn (gen_extenddfif2_fprs (operands[0], operands[1], zero));
7763       else
7764         gcc_unreachable ();
7765     }
7766   DONE;
7769 ;; Allow memory operands for the source to be created by the combiner.
7770 (define_insn_and_split "extenddf<mode>2_fprs"
7771   [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d,&d")
7772         (float_extend:IBM128
7773          (match_operand:DF 1 "nonimmediate_operand" "d,m,d")))
7774    (use (match_operand:DF 2 "nonimmediate_operand" "m,m,d"))]
7775   "!TARGET_VSX && TARGET_HARD_FLOAT
7776    && TARGET_LONG_DOUBLE_128 && FLOAT128_IBM_P (<MODE>mode)"
7777   "#"
7778   "&& reload_completed"
7779   [(set (match_dup 3) (match_dup 1))
7780    (set (match_dup 4) (match_dup 2))]
7782   const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7783   const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7785   operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
7786   operands[4] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
7789 (define_insn_and_split "extenddf<mode>2_vsx"
7790   [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d")
7791         (float_extend:IBM128
7792          (match_operand:DF 1 "nonimmediate_operand" "ws,m")))]
7793   "TARGET_LONG_DOUBLE_128 && TARGET_VSX && FLOAT128_IBM_P (<MODE>mode)"
7794   "#"
7795   "&& reload_completed"
7796   [(set (match_dup 2) (match_dup 1))
7797    (set (match_dup 3) (match_dup 4))]
7799   const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7800   const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7802   operands[2] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
7803   operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
7804   operands[4] = CONST0_RTX (DFmode);
7807 (define_expand "extendsf<mode>2"
7808   [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
7809         (float_extend:FLOAT128 (match_operand:SF 1 "gpc_reg_operand")))]
7810   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7812   if (FLOAT128_IEEE_P (<MODE>mode))
7813     rs6000_expand_float128_convert (operands[0], operands[1], false);
7814   else
7815     {
7816       rtx tmp = gen_reg_rtx (DFmode);
7817       emit_insn (gen_extendsfdf2 (tmp, operands[1]));
7818       emit_insn (gen_extenddf<mode>2 (operands[0], tmp));
7819     }
7820   DONE;
7823 (define_expand "trunc<mode>df2"
7824   [(set (match_operand:DF 0 "gpc_reg_operand")
7825         (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand")))]
7826   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7828   if (FLOAT128_IEEE_P (<MODE>mode))
7829     {
7830       rs6000_expand_float128_convert (operands[0], operands[1], false);
7831       DONE;
7832     }
7835 (define_insn_and_split "trunc<mode>df2_internal1"
7836   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d")
7837         (float_truncate:DF
7838          (match_operand:IBM128 1 "gpc_reg_operand" "0,d")))]
7839   "FLOAT128_IBM_P (<MODE>mode) && !TARGET_XL_COMPAT
7840    && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7841   "@
7842    #
7843    fmr %0,%1"
7844   "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
7845   [(const_int 0)]
7847   emit_note (NOTE_INSN_DELETED);
7848   DONE;
7850   [(set_attr "type" "fpsimple")])
7852 (define_insn "trunc<mode>df2_internal2"
7853   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
7854         (float_truncate:DF (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
7855   "FLOAT128_IBM_P (<MODE>mode) && TARGET_XL_COMPAT && TARGET_HARD_FLOAT
7856    && TARGET_LONG_DOUBLE_128"
7857   "fadd %0,%1,%L1"
7858   [(set_attr "type" "fp")])
7860 (define_expand "trunc<mode>sf2"
7861   [(set (match_operand:SF 0 "gpc_reg_operand")
7862         (float_truncate:SF (match_operand:FLOAT128 1 "gpc_reg_operand")))]
7863   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7865   if (FLOAT128_IEEE_P (<MODE>mode))
7866     rs6000_expand_float128_convert (operands[0], operands[1], false);
7867   else
7868     {
7869       rtx tmp = gen_reg_rtx (DFmode);
7870       emit_insn (gen_trunc<mode>df2 (tmp, operands[1]));
7871       emit_insn (gen_truncdfsf2 (operands[0], tmp));
7872     }
7873   DONE;
7876 (define_expand "floatsi<mode>2"
7877   [(parallel [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
7878                    (float:FLOAT128 (match_operand:SI 1 "gpc_reg_operand")))
7879               (clobber (match_scratch:DI 2))])]
7880   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7882   rtx op0 = operands[0];
7883   rtx op1 = operands[1];
7885   if (TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode))
7886     ;
7887   else if (FLOAT128_IEEE_P (<MODE>mode))
7888     {
7889       rs6000_expand_float128_convert (op0, op1, false);
7890       DONE;
7891     }
7892   else
7893     {
7894       rtx tmp = gen_reg_rtx (DFmode);
7895       expand_float (tmp, op1, false);
7896       if (<MODE>mode == TFmode)
7897         emit_insn (gen_extenddftf2 (op0, tmp));
7898       else if (<MODE>mode == IFmode)
7899         emit_insn (gen_extenddfif2 (op0, tmp));
7900       else
7901         gcc_unreachable ();
7902       DONE;
7903     }
7906 ; fadd, but rounding towards zero.
7907 ; This is probably not the optimal code sequence.
7908 (define_insn "fix_trunc_helper<mode>"
7909   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
7910         (unspec:DF [(match_operand:IBM128 1 "gpc_reg_operand" "d")]
7911                    UNSPEC_FIX_TRUNC_TF))
7912    (clobber (match_operand:DF 2 "gpc_reg_operand" "=&d"))]
7913   "TARGET_HARD_FLOAT && FLOAT128_IBM_P (<MODE>mode)"
7914   "mffs %2\n\tmtfsb1 31\n\tmtfsb0 30\n\tfadd %0,%1,%L1\n\tmtfsf 1,%2"
7915   [(set_attr "type" "fp")
7916    (set_attr "length" "20")])
7918 (define_expand "fix_trunc<mode>si2"
7919   [(set (match_operand:SI 0 "gpc_reg_operand")
7920         (fix:SI (match_operand:FLOAT128 1 "gpc_reg_operand")))]
7921   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7923   rtx op0 = operands[0];
7924   rtx op1 = operands[1];
7926   if (TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode))
7927     ;
7928   else
7929     {
7930       if (FLOAT128_IEEE_P (<MODE>mode))
7931         rs6000_expand_float128_convert (op0, op1, false);
7932       else if (<MODE>mode == TFmode)
7933         emit_insn (gen_fix_trunctfsi2_fprs (op0, op1));
7934       else if (<MODE>mode == IFmode)
7935         emit_insn (gen_fix_truncifsi2_fprs (op0, op1));
7936       else
7937         gcc_unreachable ();
7938       DONE;
7939     }
7942 (define_expand "fix_trunc<mode>si2_fprs"
7943   [(parallel [(set (match_operand:SI 0 "gpc_reg_operand")
7944                    (fix:SI (match_operand:IBM128 1 "gpc_reg_operand")))
7945               (clobber (match_dup 2))
7946               (clobber (match_dup 3))
7947               (clobber (match_dup 4))
7948               (clobber (match_dup 5))])]
7949   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7951   operands[2] = gen_reg_rtx (DFmode);
7952   operands[3] = gen_reg_rtx (DFmode);
7953   operands[4] = gen_reg_rtx (DImode);
7954   operands[5] = assign_stack_temp (DImode, GET_MODE_SIZE (DImode));
7957 (define_insn_and_split "*fix_trunc<mode>si2_internal"
7958   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
7959         (fix:SI (match_operand:IBM128 1 "gpc_reg_operand" "d")))
7960    (clobber (match_operand:DF 2 "gpc_reg_operand" "=d"))
7961    (clobber (match_operand:DF 3 "gpc_reg_operand" "=&d"))
7962    (clobber (match_operand:DI 4 "gpc_reg_operand" "=d"))
7963    (clobber (match_operand:DI 5 "offsettable_mem_operand" "=o"))]
7964   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7965   "#"
7966   ""
7967   [(pc)]
7969   rtx lowword;
7970   emit_insn (gen_fix_trunc_helper<mode> (operands[2], operands[1],
7971                                          operands[3]));
7973   gcc_assert (MEM_P (operands[5]));
7974   lowword = adjust_address (operands[5], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
7976   emit_insn (gen_fctiwz_df (operands[4], operands[2]));
7977   emit_move_insn (operands[5], operands[4]);
7978   emit_move_insn (operands[0], lowword);
7979   DONE;
7982 (define_expand "fix_trunc<mode>di2"
7983   [(set (match_operand:DI 0 "gpc_reg_operand")
7984         (fix:DI (match_operand:IEEE128 1 "gpc_reg_operand")))]
7985   "TARGET_FLOAT128_TYPE"
7987   if (!TARGET_FLOAT128_HW)
7988     {
7989       rs6000_expand_float128_convert (operands[0], operands[1], false);
7990       DONE;
7991     }
7994 (define_expand "fixuns_trunc<IEEE128:mode><SDI:mode>2"
7995   [(set (match_operand:SDI 0 "gpc_reg_operand")
7996         (unsigned_fix:SDI (match_operand:IEEE128 1 "gpc_reg_operand")))]
7997   "TARGET_FLOAT128_TYPE"
7999   rs6000_expand_float128_convert (operands[0], operands[1], true);
8000   DONE;
8003 (define_expand "floatdi<mode>2"
8004   [(set (match_operand:IEEE128 0 "gpc_reg_operand")
8005         (float:IEEE128 (match_operand:DI 1 "gpc_reg_operand")))]
8006   "TARGET_FLOAT128_TYPE"
8008   if (!TARGET_FLOAT128_HW)
8009     {
8010       rs6000_expand_float128_convert (operands[0], operands[1], false);
8011       DONE;
8012     }
8015 (define_expand "floatunsdi<IEEE128:mode>2"
8016   [(set (match_operand:IEEE128 0 "gpc_reg_operand")
8017         (unsigned_float:IEEE128 (match_operand:DI 1 "gpc_reg_operand")))]
8018   "TARGET_FLOAT128_TYPE"
8020   if (!TARGET_FLOAT128_HW)
8021     {
8022       rs6000_expand_float128_convert (operands[0], operands[1], true);
8023       DONE;
8024     }
8027 (define_expand "floatuns<IEEE128:mode>2"
8028   [(set (match_operand:IEEE128 0 "gpc_reg_operand")
8029         (unsigned_float:IEEE128 (match_operand:SI 1 "gpc_reg_operand")))]
8030   "TARGET_FLOAT128_TYPE"
8032   rtx op0 = operands[0];
8033   rtx op1 = operands[1];
8035   if (TARGET_FLOAT128_HW)
8036     emit_insn (gen_floatuns_<IEEE128:mode>si2_hw (op0, op1));
8037   else
8038     rs6000_expand_float128_convert (op0, op1, true);
8039   DONE;
8042 (define_expand "neg<mode>2"
8043   [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
8044         (neg:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand")))]
8045   "FLOAT128_IEEE_P (<MODE>mode)
8046    || (FLOAT128_IBM_P (<MODE>mode) && TARGET_HARD_FLOAT)"
8048   if (FLOAT128_IEEE_P (<MODE>mode))
8049     {
8050       if (TARGET_FLOAT128_HW)
8051         {
8052           if (<MODE>mode == TFmode)
8053             emit_insn (gen_negtf2_hw (operands[0], operands[1]));
8054           else if (<MODE>mode == KFmode)
8055             emit_insn (gen_negkf2_hw (operands[0], operands[1]));
8056           else
8057             gcc_unreachable ();
8058         }
8059       else if (TARGET_FLOAT128_TYPE)
8060         {
8061           if (<MODE>mode == TFmode)
8062             emit_insn (gen_ieee_128bit_vsx_negtf2 (operands[0], operands[1]));
8063           else if (<MODE>mode == KFmode)
8064             emit_insn (gen_ieee_128bit_vsx_negkf2 (operands[0], operands[1]));
8065           else
8066             gcc_unreachable ();
8067         }
8068       else
8069         {
8070           rtx libfunc = optab_libfunc (neg_optab, <MODE>mode);
8071           rtx target = emit_library_call_value (libfunc, operands[0], LCT_CONST,
8072                                                 <MODE>mode,
8073                                                 operands[1], <MODE>mode);
8075           if (target && !rtx_equal_p (target, operands[0]))
8076             emit_move_insn (operands[0], target);
8077         }
8078       DONE;
8079     }
8082 (define_insn "neg<mode>2_internal"
8083   [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d")
8084         (neg:IBM128 (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
8085   "TARGET_HARD_FLOAT && FLOAT128_IBM_P (<MODE>mode)"
8087   if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
8088     return "fneg %L0,%L1\;fneg %0,%1";
8089   else
8090     return "fneg %0,%1\;fneg %L0,%L1";
8092   [(set_attr "type" "fpsimple")
8093    (set_attr "length" "8")])
8095 (define_expand "abs<mode>2"
8096   [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
8097         (abs:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand")))]
8098   "FLOAT128_IEEE_P (<MODE>mode)
8099    || (FLOAT128_IBM_P (<MODE>mode) && TARGET_HARD_FLOAT)"
8101   rtx label;
8103   if (FLOAT128_IEEE_P (<MODE>mode))
8104     {
8105       if (TARGET_FLOAT128_HW)
8106         {
8107           if (<MODE>mode == TFmode)
8108             emit_insn (gen_abstf2_hw (operands[0], operands[1]));
8109           else if (<MODE>mode == KFmode)
8110             emit_insn (gen_abskf2_hw (operands[0], operands[1]));
8111           else
8112             FAIL;
8113           DONE;
8114         }
8115       else if (TARGET_FLOAT128_TYPE)
8116         {
8117           if (<MODE>mode == TFmode)
8118             emit_insn (gen_ieee_128bit_vsx_abstf2 (operands[0], operands[1]));
8119           else if (<MODE>mode == KFmode)
8120             emit_insn (gen_ieee_128bit_vsx_abskf2 (operands[0], operands[1]));
8121           else
8122             FAIL;
8123           DONE;
8124         }
8125       else
8126         FAIL;
8127     }
8129   label = gen_label_rtx ();
8130   if (<MODE>mode == TFmode)
8131     emit_insn (gen_abstf2_internal (operands[0], operands[1], label));
8132   else if (<MODE>mode == IFmode)
8133     emit_insn (gen_absif2_internal (operands[0], operands[1], label));
8134   else
8135     FAIL;
8136   emit_label (label);
8137   DONE;
8140 (define_expand "abs<mode>2_internal"
8141   [(set (match_operand:IBM128 0 "gpc_reg_operand")
8142         (match_operand:IBM128 1 "gpc_reg_operand"))
8143    (set (match_dup 3) (match_dup 5))
8144    (set (match_dup 5) (abs:DF (match_dup 5)))
8145    (set (match_dup 4) (compare:CCFP (match_dup 3) (match_dup 5)))
8146    (set (pc) (if_then_else (eq (match_dup 4) (const_int 0))
8147                            (label_ref (match_operand 2 ""))
8148                            (pc)))
8149    (set (match_dup 6) (neg:DF (match_dup 6)))]
8150   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8152   const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
8153   const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
8154   operands[3] = gen_reg_rtx (DFmode);
8155   operands[4] = gen_reg_rtx (CCFPmode);
8156   operands[5] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
8157   operands[6] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
8161 ;; Generate IEEE 128-bit -0.0 (0x80000000000000000000000000000000) in a vector
8162 ;; register
8164 (define_expand "ieee_128bit_negative_zero"
8165   [(set (match_operand:V16QI 0 "register_operand") (match_dup 1))]
8166   "TARGET_FLOAT128_TYPE"
8168   rtvec v = rtvec_alloc (16);
8169   int i, high;
8171   for (i = 0; i < 16; i++)
8172     RTVEC_ELT (v, i) = const0_rtx;
8174   high = (BYTES_BIG_ENDIAN) ? 0 : 15;
8175   RTVEC_ELT (v, high) = gen_int_mode (0x80, QImode);
8177   rs6000_expand_vector_init (operands[0], gen_rtx_PARALLEL (V16QImode, v));
8178   DONE;
8181 ;; IEEE 128-bit negate
8183 ;; We have 2 insns here for negate and absolute value.  The first uses
8184 ;; match_scratch so that phases like combine can recognize neg/abs as generic
8185 ;; insns, and second insn after the first split pass loads up the bit to
8186 ;; twiddle the sign bit.  Later GCSE passes can then combine multiple uses of
8187 ;; neg/abs to create the constant just once.
8189 (define_insn_and_split "ieee_128bit_vsx_neg<mode>2"
8190   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8191         (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8192    (clobber (match_scratch:V16QI 2 "=v"))]
8193   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8194   "#"
8195   "&& 1"
8196   [(parallel [(set (match_dup 0)
8197                    (neg:IEEE128 (match_dup 1)))
8198               (use (match_dup 2))])]
8200   if (GET_CODE (operands[2]) == SCRATCH)
8201     operands[2] = gen_reg_rtx (V16QImode);
8203   operands[3] = gen_reg_rtx (V16QImode);
8204   emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8206   [(set_attr "length" "8")
8207    (set_attr "type" "vecsimple")])
8209 (define_insn "*ieee_128bit_vsx_neg<mode>2_internal"
8210   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8211         (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8212    (use (match_operand:V16QI 2 "register_operand" "v"))]
8213   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8214   "xxlxor %x0,%x1,%x2"
8215   [(set_attr "type" "veclogical")])
8217 ;; IEEE 128-bit absolute value
8218 (define_insn_and_split "ieee_128bit_vsx_abs<mode>2"
8219   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8220         (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8221    (clobber (match_scratch:V16QI 2 "=v"))]
8222   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
8223   "#"
8224   "&& 1"
8225   [(parallel [(set (match_dup 0)
8226                    (abs:IEEE128 (match_dup 1)))
8227               (use (match_dup 2))])]
8229   if (GET_CODE (operands[2]) == SCRATCH)
8230     operands[2] = gen_reg_rtx (V16QImode);
8232   operands[3] = gen_reg_rtx (V16QImode);
8233   emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8235   [(set_attr "length" "8")
8236    (set_attr "type" "vecsimple")])
8238 (define_insn "*ieee_128bit_vsx_abs<mode>2_internal"
8239   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8240         (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8241    (use (match_operand:V16QI 2 "register_operand" "v"))]
8242   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8243   "xxlandc %x0,%x1,%x2"
8244   [(set_attr "type" "veclogical")])
8246 ;; IEEE 128-bit negative absolute value
8247 (define_insn_and_split "*ieee_128bit_vsx_nabs<mode>2"
8248   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8249         (neg:IEEE128
8250          (abs:IEEE128
8251           (match_operand:IEEE128 1 "register_operand" "wa"))))
8252    (clobber (match_scratch:V16QI 2 "=v"))]
8253   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW
8254    && FLOAT128_IEEE_P (<MODE>mode)"
8255   "#"
8256   "&& 1"
8257   [(parallel [(set (match_dup 0)
8258                    (neg:IEEE128 (abs:IEEE128 (match_dup 1))))
8259               (use (match_dup 2))])]
8261   if (GET_CODE (operands[2]) == SCRATCH)
8262     operands[2] = gen_reg_rtx (V16QImode);
8264   operands[3] = gen_reg_rtx (V16QImode);
8265   emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8267   [(set_attr "length" "8")
8268    (set_attr "type" "vecsimple")])
8270 (define_insn "*ieee_128bit_vsx_nabs<mode>2_internal"
8271   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8272         (neg:IEEE128
8273          (abs:IEEE128
8274           (match_operand:IEEE128 1 "register_operand" "wa"))))
8275    (use (match_operand:V16QI 2 "register_operand" "v"))]
8276   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8277   "xxlor %x0,%x1,%x2"
8278   [(set_attr "type" "veclogical")])
8280 ;; Float128 conversion functions.  These expand to library function calls.
8281 ;; We use expand to convert from IBM double double to IEEE 128-bit
8282 ;; and trunc for the opposite.
8283 (define_expand "extendiftf2"
8284   [(set (match_operand:TF 0 "gpc_reg_operand")
8285         (float_extend:TF (match_operand:IF 1 "gpc_reg_operand")))]
8286   "TARGET_FLOAT128_TYPE"
8288   rs6000_expand_float128_convert (operands[0], operands[1], false);
8289   DONE;
8292 (define_expand "extendifkf2"
8293   [(set (match_operand:KF 0 "gpc_reg_operand")
8294         (float_extend:KF (match_operand:IF 1 "gpc_reg_operand")))]
8295   "TARGET_FLOAT128_TYPE"
8297   rs6000_expand_float128_convert (operands[0], operands[1], false);
8298   DONE;
8301 (define_expand "extendtfkf2"
8302   [(set (match_operand:KF 0 "gpc_reg_operand")
8303         (float_extend:KF (match_operand:TF 1 "gpc_reg_operand")))]
8304   "TARGET_FLOAT128_TYPE"
8306   rs6000_expand_float128_convert (operands[0], operands[1], false);
8307   DONE;
8310 (define_expand "extendtfif2"
8311   [(set (match_operand:IF 0 "gpc_reg_operand")
8312         (float_extend:IF (match_operand:TF 1 "gpc_reg_operand")))]
8313   "TARGET_FLOAT128_TYPE"
8315   rs6000_expand_float128_convert (operands[0], operands[1], false);
8316   DONE;
8319 (define_expand "trunciftf2"
8320   [(set (match_operand:TF 0 "gpc_reg_operand")
8321         (float_truncate:TF (match_operand:IF 1 "gpc_reg_operand")))]
8322   "TARGET_FLOAT128_TYPE"
8324   rs6000_expand_float128_convert (operands[0], operands[1], false);
8325   DONE;
8328 (define_expand "truncifkf2"
8329   [(set (match_operand:KF 0 "gpc_reg_operand")
8330         (float_truncate:KF (match_operand:IF 1 "gpc_reg_operand")))]
8331   "TARGET_FLOAT128_TYPE"
8333   rs6000_expand_float128_convert (operands[0], operands[1], false);
8334   DONE;
8337 (define_expand "trunckftf2"
8338   [(set (match_operand:TF 0 "gpc_reg_operand")
8339         (float_truncate:TF (match_operand:KF 1 "gpc_reg_operand")))]
8340   "TARGET_FLOAT128_TYPE"
8342   rs6000_expand_float128_convert (operands[0], operands[1], false);
8343   DONE;
8346 (define_expand "trunctfif2"
8347   [(set (match_operand:IF 0 "gpc_reg_operand")
8348         (float_truncate:IF (match_operand:TF 1 "gpc_reg_operand")))]
8349   "TARGET_FLOAT128_TYPE"
8351   rs6000_expand_float128_convert (operands[0], operands[1], false);
8352   DONE;
8355 (define_insn_and_split "*extend<mode>tf2_internal"
8356   [(set (match_operand:TF 0 "gpc_reg_operand" "=<IFKF_reg>")
8357         (float_extend:TF
8358          (match_operand:IFKF 1 "gpc_reg_operand" "<IFKF_reg>")))]
8359    "TARGET_FLOAT128_TYPE
8360     && FLOAT128_IBM_P (TFmode) == FLOAT128_IBM_P (<MODE>mode)"
8361   "#"
8362   "&& reload_completed"
8363   [(set (match_dup 0) (match_dup 2))]
8365   operands[2] = gen_rtx_REG (TFmode, REGNO (operands[1]));
8368 (define_insn_and_split "*extendtf<mode>2_internal"
8369   [(set (match_operand:IFKF 0 "gpc_reg_operand" "=<IFKF_reg>")
8370         (float_extend:IFKF
8371          (match_operand:TF 1 "gpc_reg_operand" "<IFKF_reg>")))]
8372    "TARGET_FLOAT128_TYPE
8373     && FLOAT128_IBM_P (TFmode) == FLOAT128_IBM_P (<MODE>mode)"
8374   "#"
8375   "&& reload_completed"
8376   [(set (match_dup 0) (match_dup 2))]
8378   operands[2] = gen_rtx_REG (<MODE>mode, REGNO (operands[1]));
8382 ;; Reload helper functions used by rs6000_secondary_reload.  The patterns all
8383 ;; must have 3 arguments, and scratch register constraint must be a single
8384 ;; constraint.
8386 ;; Reload patterns to support gpr load/store with misaligned mem.
8387 ;; and multiple gpr load/store at offset >= 0xfffc
8388 (define_expand "reload_<mode>_store"
8389   [(parallel [(match_operand 0 "memory_operand" "=m")
8390               (match_operand 1 "gpc_reg_operand" "r")
8391               (match_operand:GPR 2 "register_operand" "=&b")])]
8392   ""
8394   rs6000_secondary_reload_gpr (operands[1], operands[0], operands[2], true);
8395   DONE;
8398 (define_expand "reload_<mode>_load"
8399   [(parallel [(match_operand 0 "gpc_reg_operand" "=r")
8400               (match_operand 1 "memory_operand" "m")
8401               (match_operand:GPR 2 "register_operand" "=b")])]
8402   ""
8404   rs6000_secondary_reload_gpr (operands[0], operands[1], operands[2], false);
8405   DONE;
8409 ;; Reload patterns for various types using the vector registers.  We may need
8410 ;; an additional base register to convert the reg+offset addressing to reg+reg
8411 ;; for vector registers and reg+reg or (reg+reg)&(-16) addressing to just an
8412 ;; index register for gpr registers.
8413 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_store"
8414   [(parallel [(match_operand:RELOAD 0 "memory_operand" "m")
8415               (match_operand:RELOAD 1 "gpc_reg_operand" "wa")
8416               (match_operand:P 2 "register_operand" "=b")])]
8417   "<P:tptrsize>"
8419   rs6000_secondary_reload_inner (operands[1], operands[0], operands[2], true);
8420   DONE;
8423 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_load"
8424   [(parallel [(match_operand:RELOAD 0 "gpc_reg_operand" "wa")
8425               (match_operand:RELOAD 1 "memory_operand" "m")
8426               (match_operand:P 2 "register_operand" "=b")])]
8427   "<P:tptrsize>"
8429   rs6000_secondary_reload_inner (operands[0], operands[1], operands[2], false);
8430   DONE;
8434 ;; Reload sometimes tries to move the address to a GPR, and can generate
8435 ;; invalid RTL for addresses involving AND -16.  Allow addresses involving
8436 ;; reg+reg, reg+small constant, or just reg, all wrapped in an AND -16.
8438 (define_insn_and_split "*vec_reload_and_plus_<mptrsize>"
8439   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
8440         (and:P (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
8441                        (match_operand:P 2 "reg_or_cint_operand" "rI"))
8442                (const_int -16)))]
8443   "TARGET_ALTIVEC && reload_completed"
8444   "#"
8445   "&& reload_completed"
8446   [(set (match_dup 0)
8447         (plus:P (match_dup 1)
8448                 (match_dup 2)))
8449    (set (match_dup 0)
8450         (and:P (match_dup 0)
8451                (const_int -16)))])
8453 ;; Power8 merge instructions to allow direct move to/from floating point
8454 ;; registers in 32-bit mode.  We use TF mode to get two registers to move the
8455 ;; individual 32-bit parts across.  Subreg doesn't work too well on the TF
8456 ;; value, since it is allocated in reload and not all of the flow information
8457 ;; is setup for it.  We have two patterns to do the two moves between gprs and
8458 ;; fprs.  There isn't a dependancy between the two, but we could potentially
8459 ;; schedule other instructions between the two instructions.
8461 (define_insn "p8_fmrgow_<mode>"
8462   [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
8463         (unspec:FMOVE64X [
8464                 (match_operand:DF 1 "register_operand" "d")
8465                 (match_operand:DF 2 "register_operand" "d")]
8466                          UNSPEC_P8V_FMRGOW))]
8467   "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8468   "fmrgow %0,%1,%2"
8469   [(set_attr "type" "fpsimple")])
8471 (define_insn "p8_mtvsrwz"
8472   [(set (match_operand:DF 0 "register_operand" "=d")
8473         (unspec:DF [(match_operand:SI 1 "register_operand" "r")]
8474                    UNSPEC_P8V_MTVSRWZ))]
8475   "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8476   "mtvsrwz %x0,%1"
8477   [(set_attr "type" "mftgpr")])
8479 (define_insn_and_split "reload_fpr_from_gpr<mode>"
8480   [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
8481         (unspec:FMOVE64X [(match_operand:FMOVE64X 1 "register_operand" "r")]
8482                          UNSPEC_P8V_RELOAD_FROM_GPR))
8483    (clobber (match_operand:IF 2 "register_operand" "=d"))]
8484   "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8485   "#"
8486   "&& reload_completed"
8487   [(const_int 0)]
8489   rtx dest = operands[0];
8490   rtx src = operands[1];
8491   rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0);
8492   rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8);
8493   rtx gpr_hi_reg = gen_highpart (SImode, src);
8494   rtx gpr_lo_reg = gen_lowpart (SImode, src);
8496   emit_insn (gen_p8_mtvsrwz (tmp_hi, gpr_hi_reg));
8497   emit_insn (gen_p8_mtvsrwz (tmp_lo, gpr_lo_reg));
8498   emit_insn (gen_p8_fmrgow_<mode> (dest, tmp_hi, tmp_lo));
8499   DONE;
8501   [(set_attr "length" "12")
8502    (set_attr "type" "three")])
8504 ;; Move 128 bit values from GPRs to VSX registers in 64-bit mode
8505 (define_insn "p8_mtvsrd_df"
8506   [(set (match_operand:DF 0 "register_operand" "=wa")
8507         (unspec:DF [(match_operand:DI 1 "register_operand" "r")]
8508                    UNSPEC_P8V_MTVSRD))]
8509   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8510   "mtvsrd %x0,%1"
8511   [(set_attr "type" "mftgpr")])
8513 (define_insn "p8_xxpermdi_<mode>"
8514   [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
8515         (unspec:FMOVE128_GPR [
8516                 (match_operand:DF 1 "register_operand" "wa")
8517                 (match_operand:DF 2 "register_operand" "wa")]
8518                 UNSPEC_P8V_XXPERMDI))]
8519   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8520   "xxpermdi %x0,%x1,%x2,0"
8521   [(set_attr "type" "vecperm")])
8523 (define_insn_and_split "reload_vsx_from_gpr<mode>"
8524   [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
8525         (unspec:FMOVE128_GPR
8526          [(match_operand:FMOVE128_GPR 1 "register_operand" "r")]
8527          UNSPEC_P8V_RELOAD_FROM_GPR))
8528    (clobber (match_operand:IF 2 "register_operand" "=wa"))]
8529   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8530   "#"
8531   "&& reload_completed"
8532   [(const_int 0)]
8534   rtx dest = operands[0];
8535   rtx src = operands[1];
8536   /* You might think that we could use op0 as one temp and a DF clobber
8537      as op2, but you'd be wrong.  Secondary reload move patterns don't
8538      check for overlap of the clobber and the destination.  */
8539   rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0);
8540   rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8);
8541   rtx gpr_hi_reg = gen_highpart (DImode, src);
8542   rtx gpr_lo_reg = gen_lowpart (DImode, src);
8544   emit_insn (gen_p8_mtvsrd_df (tmp_hi, gpr_hi_reg));
8545   emit_insn (gen_p8_mtvsrd_df (tmp_lo, gpr_lo_reg));
8546   emit_insn (gen_p8_xxpermdi_<mode> (dest, tmp_hi, tmp_lo));
8547   DONE;
8549   [(set_attr "length" "12")
8550    (set_attr "type" "three")])
8552 (define_split
8553   [(set (match_operand:FMOVE128_GPR 0 "nonimmediate_operand")
8554         (match_operand:FMOVE128_GPR 1 "input_operand"))]
8555   "reload_completed
8556    && (int_reg_operand (operands[0], <MODE>mode)
8557        || int_reg_operand (operands[1], <MODE>mode))
8558    && (!TARGET_DIRECT_MOVE_128
8559        || (!vsx_register_operand (operands[0], <MODE>mode)
8560            && !vsx_register_operand (operands[1], <MODE>mode)))"
8561   [(pc)]
8562 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
8564 ;; Move SFmode to a VSX from a GPR register.  Because scalar floating point
8565 ;; type is stored internally as double precision in the VSX registers, we have
8566 ;; to convert it from the vector format.
8567 (define_insn "p8_mtvsrd_sf"
8568   [(set (match_operand:SF 0 "register_operand" "=wa")
8569         (unspec:SF [(match_operand:DI 1 "register_operand" "r")]
8570                    UNSPEC_P8V_MTVSRD))]
8571   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8572   "mtvsrd %x0,%1"
8573   [(set_attr "type" "mftgpr")])
8575 (define_insn_and_split "reload_vsx_from_gprsf"
8576   [(set (match_operand:SF 0 "register_operand" "=wa")
8577         (unspec:SF [(match_operand:SF 1 "register_operand" "r")]
8578                    UNSPEC_P8V_RELOAD_FROM_GPR))
8579    (clobber (match_operand:DI 2 "register_operand" "=r"))]
8580   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8581   "#"
8582   "&& reload_completed"
8583   [(const_int 0)]
8585   rtx op0 = operands[0];
8586   rtx op1 = operands[1];
8587   rtx op2 = operands[2];
8588   rtx op1_di = simplify_gen_subreg (DImode, op1, SFmode, 0);
8590   /* Move SF value to upper 32-bits for xscvspdpn.  */
8591   emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32)));
8592   emit_insn (gen_p8_mtvsrd_sf (op0, op2));
8593   emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0));
8594   DONE;
8596   [(set_attr "length" "8")
8597    (set_attr "type" "two")])
8599 ;; Move 128 bit values from VSX registers to GPRs in 64-bit mode by doing a
8600 ;; normal 64-bit move, followed by an xxpermdi to get the bottom 64-bit value,
8601 ;; and then doing a move of that.
8602 (define_insn "p8_mfvsrd_3_<mode>"
8603   [(set (match_operand:DF 0 "register_operand" "=r")
8604         (unspec:DF [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
8605                    UNSPEC_P8V_RELOAD_FROM_VSX))]
8606   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8607   "mfvsrd %0,%x1"
8608   [(set_attr "type" "mftgpr")])
8610 (define_insn_and_split "reload_gpr_from_vsx<mode>"
8611   [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=r")
8612         (unspec:FMOVE128_GPR
8613          [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
8614          UNSPEC_P8V_RELOAD_FROM_VSX))
8615    (clobber (match_operand:FMOVE128_GPR 2 "register_operand" "=wa"))]
8616   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8617   "#"
8618   "&& reload_completed"
8619   [(const_int 0)]
8621   rtx dest = operands[0];
8622   rtx src = operands[1];
8623   rtx tmp = operands[2];
8624   rtx gpr_hi_reg = gen_highpart (DFmode, dest);
8625   rtx gpr_lo_reg = gen_lowpart (DFmode, dest);
8627   emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_hi_reg, src));
8628   emit_insn (gen_vsx_xxpermdi_<mode>_be (tmp, src, src, GEN_INT (3)));
8629   emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_lo_reg, tmp));
8630   DONE;
8632   [(set_attr "length" "12")
8633    (set_attr "type" "three")])
8635 ;; Move SFmode to a GPR from a VSX register.  Because scalar floating point
8636 ;; type is stored internally as double precision, we have to convert it to the
8637 ;; vector format.
8639 (define_insn_and_split "reload_gpr_from_vsxsf"
8640   [(set (match_operand:SF 0 "register_operand" "=r")
8641         (unspec:SF [(match_operand:SF 1 "register_operand" "ww")]
8642                    UNSPEC_P8V_RELOAD_FROM_VSX))
8643    (clobber (match_operand:V4SF 2 "register_operand" "=wIwH"))]
8644   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8645   "#"
8646   "&& reload_completed"
8647   [(const_int 0)]
8649   rtx op0 = operands[0];
8650   rtx op1 = operands[1];
8651   rtx op2 = operands[2];
8652   rtx op0_di = gen_rtx_REG (DImode, reg_or_subregno (op0));
8653   rtx op2_si = gen_rtx_REG (SImode, reg_or_subregno (op2));
8655   emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
8656   emit_insn (gen_zero_extendsidi2 (op0_di, op2_si));
8657   DONE;
8659   [(set_attr "length" "8")
8660    (set_attr "type" "two")])
8663 ;; Next come the multi-word integer load and store and the load and store
8664 ;; multiple insns.
8666 ;; List r->r after r->Y, otherwise reload will try to reload a
8667 ;; non-offsettable address by using r->r which won't make progress.
8668 ;; Use of fprs is disparaged slightly otherwise reload prefers to reload
8669 ;; a gpr into a fpr instead of reloading an invalid 'Y' address
8671 ;;        GPR store  GPR load   GPR move   FPR store  FPR load   FPR move
8672 ;;        GPR const  AVX store  AVX store  AVX load   AVX load   VSX move
8673 ;;        P9 0       P9 -1      AVX 0/-1   VSX 0      VSX -1     P9 const
8674 ;;        AVX const  
8676 (define_insn "*movdi_internal32"
8677   [(set (match_operand:DI 0 "nonimmediate_operand"
8678          "=Y,        r,         r,         m,         ^d,        ^d,
8679           r,         wY,        Z,         ^wb,       $wv,       ^wi,
8680           *wo,       *wo,       *wv,       *wi,       *wi,       *wv,
8681           *wv")
8683         (match_operand:DI 1 "input_operand"
8684          "r,         Y,         r,         ^d,        m,         ^d,
8685           IJKnF,     ^wb,       $wv,       wY,        Z,         ^wi,
8686           Oj,        wM,        OjwM,      Oj,        wM,        wS,
8687           wB"))]
8689   "! TARGET_POWERPC64
8690    && (gpc_reg_operand (operands[0], DImode)
8691        || gpc_reg_operand (operands[1], DImode))"
8692   "@
8693    #
8694    #
8695    #
8696    stfd%U0%X0 %1,%0
8697    lfd%U1%X1 %0,%1
8698    fmr %0,%1
8699    #
8700    stxsd %1,%0
8701    stxsdx %x1,%y0
8702    lxsd %0,%1
8703    lxsdx %x0,%y1
8704    xxlor %x0,%x1,%x1
8705    xxspltib %x0,0
8706    xxspltib %x0,255
8707    vspltisw %0,%1
8708    xxlxor %x0,%x0,%x0
8709    xxlorc %x0,%x0,%x0
8710    #
8711    #"
8712   [(set_attr "type"
8713          "store,     load,      *,         fpstore,   fpload,    fpsimple,
8714           *,         fpstore,   fpstore,   fpload,    fpload,    veclogical,
8715           vecsimple, vecsimple, vecsimple, veclogical,veclogical,vecsimple,
8716           vecsimple")
8717    (set_attr "size" "64")
8718    (set_attr "length"
8719          "8,         8,         8,         4,         4,         4,
8720           16,        4,         4,         4,         4,         4,
8721           4,         4,         4,         4,         4,         8,
8722           4")])
8724 (define_split
8725   [(set (match_operand:DI 0 "gpc_reg_operand")
8726         (match_operand:DI 1 "const_int_operand"))]
8727   "! TARGET_POWERPC64 && reload_completed
8728    && gpr_or_gpr_p (operands[0], operands[1])
8729    && !direct_move_p (operands[0], operands[1])"
8730   [(set (match_dup 2) (match_dup 4))
8731    (set (match_dup 3) (match_dup 1))]
8733   HOST_WIDE_INT value = INTVAL (operands[1]);
8734   operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
8735                                        DImode);
8736   operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
8737                                        DImode);
8738   operands[4] = GEN_INT (value >> 32);
8739   operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
8742 (define_split
8743   [(set (match_operand:DIFD 0 "nonimmediate_operand")
8744         (match_operand:DIFD 1 "input_operand"))]
8745   "reload_completed && !TARGET_POWERPC64
8746    && gpr_or_gpr_p (operands[0], operands[1])
8747    && !direct_move_p (operands[0], operands[1])"
8748   [(pc)]
8749 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
8751 ;;              GPR store  GPR load   GPR move   GPR li     GPR lis     GPR #
8752 ;;              FPR store  FPR load   FPR move   AVX store  AVX store   AVX load
8753 ;;              AVX load   VSX move   P9 0       P9 -1      AVX 0/-1    VSX 0
8754 ;;              VSX -1     P9 const   AVX const  From SPR   To SPR      SPR<->SPR
8755 ;;              FPR->GPR   GPR->FPR   VSX->GPR   GPR->VSX
8756 (define_insn "*movdi_internal64"
8757   [(set (match_operand:DI 0 "nonimmediate_operand"
8758                "=YZ,       r,         r,         r,         r,          r,
8759                 m,         ^d,        ^d,        wY,        Z,          $wb,
8760                 $wv,       ^wi,       *wo,       *wo,       *wv,        *wi,
8761                 *wi,       *wv,       *wv,       r,         *h,         *h,
8762                 ?*r,       ?*wg,      ?*r,       ?*wj")
8764         (match_operand:DI 1 "input_operand"
8765                "r,         YZ,        r,         I,         L,          nF,
8766                 ^d,        m,         ^d,        ^wb,       $wv,        wY,
8767                 Z,         ^wi,       Oj,        wM,        OjwM,       Oj,
8768                 wM,        wS,        wB,        *h,        r,          0,
8769                 wg,        r,         wj,        r"))]
8771   "TARGET_POWERPC64
8772    && (gpc_reg_operand (operands[0], DImode)
8773        || gpc_reg_operand (operands[1], DImode))"
8774   "@
8775    std%U0%X0 %1,%0
8776    ld%U1%X1 %0,%1
8777    mr %0,%1
8778    li %0,%1
8779    lis %0,%v1
8780    #
8781    stfd%U0%X0 %1,%0
8782    lfd%U1%X1 %0,%1
8783    fmr %0,%1
8784    stxsd %1,%0
8785    stxsdx %x1,%y0
8786    lxsd %0,%1
8787    lxsdx %x0,%y1
8788    xxlor %x0,%x1,%x1
8789    xxspltib %x0,0
8790    xxspltib %x0,255
8791    #
8792    xxlxor %x0,%x0,%x0
8793    xxlorc %x0,%x0,%x0
8794    #
8795    #
8796    mf%1 %0
8797    mt%0 %1
8798    nop
8799    mftgpr %0,%1
8800    mffgpr %0,%1
8801    mfvsrd %0,%x1
8802    mtvsrd %x0,%1"
8803   [(set_attr "type"
8804                "store,      load,       *,         *,         *,         *,
8805                 fpstore,    fpload,     fpsimple,  fpstore,   fpstore,   fpload,
8806                 fpload,     veclogical, vecsimple, vecsimple, vecsimple, veclogical,
8807                 veclogical, vecsimple,  vecsimple, mfjmpr,    mtjmpr,    *,
8808                 mftgpr,     mffgpr,     mftgpr,    mffgpr")
8810    (set_attr "size" "64")
8811    (set_attr "length"
8812                "4,         4,         4,         4,         4,          20,
8813                 4,         4,         4,         4,         4,          4,
8814                 4,         4,         4,         4,         4,          4,
8815                 4,         8,         4,         4,         4,          4,
8816                 4,         4,         4,         4")])
8818 ; Some DImode loads are best done as a load of -1 followed by a mask
8819 ; instruction.
8820 (define_split
8821   [(set (match_operand:DI 0 "int_reg_operand_not_pseudo")
8822         (match_operand:DI 1 "const_int_operand"))]
8823   "TARGET_POWERPC64
8824    && num_insns_constant (operands[1], DImode) > 1
8825    && !IN_RANGE (INTVAL (operands[1]), -0x80000000, 0xffffffff)
8826    && rs6000_is_valid_and_mask (operands[1], DImode)"
8827   [(set (match_dup 0)
8828         (const_int -1))
8829    (set (match_dup 0)
8830         (and:DI (match_dup 0)
8831                 (match_dup 1)))]
8832   "")
8834 ;; Split a load of a large constant into the appropriate five-instruction
8835 ;; sequence.  Handle anything in a constant number of insns.
8836 ;; When non-easy constants can go in the TOC, this should use
8837 ;; easy_fp_constant predicate.
8838 (define_split
8839   [(set (match_operand:DI 0 "int_reg_operand_not_pseudo")
8840         (match_operand:DI 1 "const_int_operand"))]
8841   "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
8842   [(set (match_dup 0) (match_dup 2))
8843    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
8845   if (rs6000_emit_set_const (operands[0], operands[1]))
8846     DONE;
8847   else
8848     FAIL;
8851 (define_split
8852   [(set (match_operand:DI 0 "int_reg_operand_not_pseudo")
8853         (match_operand:DI 1 "const_scalar_int_operand"))]
8854   "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
8855   [(set (match_dup 0) (match_dup 2))
8856    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
8858   if (rs6000_emit_set_const (operands[0], operands[1]))
8859     DONE;
8860   else
8861     FAIL;
8864 (define_split
8865   [(set (match_operand:DI 0 "altivec_register_operand")
8866         (match_operand:DI 1 "s5bit_cint_operand"))]
8867   "TARGET_VSX && reload_completed"
8868   [(const_int 0)]
8870   rtx op0 = operands[0];
8871   rtx op1 = operands[1];
8872   int r = REGNO (op0);
8873   rtx op0_v4si = gen_rtx_REG (V4SImode, r);
8875   emit_insn (gen_altivec_vspltisw (op0_v4si, op1));
8876   if (op1 != const0_rtx && op1 != constm1_rtx)
8877     {
8878       rtx op0_v2di = gen_rtx_REG (V2DImode, r);
8879       emit_insn (gen_altivec_vupkhsw (op0_v2di, op0_v4si));
8880     }
8881   DONE;
8884 ;; Split integer constants that can be loaded with XXSPLTIB and a
8885 ;; sign extend operation.
8886 (define_split
8887   [(set (match_operand:INT_ISA3 0 "altivec_register_operand")
8888         (match_operand:INT_ISA3 1 "xxspltib_constant_split"))]
8889   "TARGET_P9_VECTOR && reload_completed"
8890   [(const_int 0)]
8892   rtx op0 = operands[0];
8893   rtx op1 = operands[1];
8894   int r = REGNO (op0);
8895   rtx op0_v16qi = gen_rtx_REG (V16QImode, r);
8897   emit_insn (gen_xxspltib_v16qi (op0_v16qi, op1));
8898   if (<MODE>mode == DImode)
8899     emit_insn (gen_vsx_sign_extend_qi_di (operands[0], op0_v16qi));
8900   else if (<MODE>mode == SImode)
8901     emit_insn (gen_vsx_sign_extend_qi_si (operands[0], op0_v16qi));
8902   else if (<MODE>mode == HImode)
8903     {
8904       rtx op0_v8hi = gen_rtx_REG (V8HImode, r);
8905       emit_insn (gen_altivec_vupkhsb (op0_v8hi, op0_v16qi));
8906     }
8907   DONE;
8911 ;; TImode/PTImode is similar, except that we usually want to compute the
8912 ;; address into a register and use lsi/stsi (the exception is during reload).
8914 (define_insn "*mov<mode>_string"
8915   [(set (match_operand:TI2 0 "reg_or_mem_operand" "=Q,Y,????r,????r,????r,r")
8916         (match_operand:TI2 1 "input_operand" "r,r,Q,Y,r,n"))]
8917   "! TARGET_POWERPC64
8918    && (<MODE>mode != TImode || VECTOR_MEM_NONE_P (TImode))
8919    && (gpc_reg_operand (operands[0], <MODE>mode)
8920        || gpc_reg_operand (operands[1], <MODE>mode))"
8921   "#"
8922   [(set_attr "type" "store,store,load,load,*,*")
8923    (set_attr "update" "yes")
8924    (set_attr "indexed" "yes")
8925    (set_attr "cell_micro" "conditional")])
8927 (define_insn "*mov<mode>_ppc64"
8928   [(set (match_operand:TI2 0 "nonimmediate_operand" "=wQ,Y,r,r,r,r")
8929         (match_operand:TI2 1 "input_operand" "r,r,wQ,Y,r,n"))]
8930   "(TARGET_POWERPC64 && VECTOR_MEM_NONE_P (<MODE>mode)
8931    && (gpc_reg_operand (operands[0], <MODE>mode)
8932        || gpc_reg_operand (operands[1], <MODE>mode)))"
8934   return rs6000_output_move_128bit (operands);
8936   [(set_attr "type" "store,store,load,load,*,*")
8937    (set_attr "length" "8")])
8939 (define_split
8940   [(set (match_operand:TI2 0 "int_reg_operand")
8941         (match_operand:TI2 1 "const_scalar_int_operand"))]
8942   "TARGET_POWERPC64
8943    && (VECTOR_MEM_NONE_P (<MODE>mode)
8944        || (reload_completed && INT_REGNO_P (REGNO (operands[0]))))"
8945   [(set (match_dup 2) (match_dup 4))
8946    (set (match_dup 3) (match_dup 5))]
8948   operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
8949                                        <MODE>mode);
8950   operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
8951                                        <MODE>mode);
8952   if (CONST_WIDE_INT_P (operands[1]))
8953     {
8954       operands[4] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 1));
8955       operands[5] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 0));
8956     }
8957   else if (CONST_INT_P (operands[1]))
8958     {
8959       operands[4] = GEN_INT (- (INTVAL (operands[1]) < 0));
8960       operands[5] = operands[1];
8961     }
8962   else
8963     FAIL;
8966 (define_split
8967   [(set (match_operand:TI2 0 "nonimmediate_operand")
8968         (match_operand:TI2 1 "input_operand"))]
8969   "reload_completed
8970    && gpr_or_gpr_p (operands[0], operands[1])
8971    && !direct_move_p (operands[0], operands[1])
8972    && !quad_load_store_p (operands[0], operands[1])"
8973   [(pc)]
8974 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
8976 (define_expand "setmemsi"
8977   [(parallel [(set (match_operand:BLK 0 "")
8978                    (match_operand 2 "const_int_operand"))
8979               (use (match_operand:SI 1 ""))
8980               (use (match_operand:SI 3 ""))])]
8981   ""
8983   /* If value to set is not zero, use the library routine.  */
8984   if (operands[2] != const0_rtx)
8985     FAIL;
8987   if (expand_block_clear (operands))
8988     DONE;
8989   else
8990     FAIL;
8993 ;; String compare N insn.
8994 ;; Argument 0 is the target (result)
8995 ;; Argument 1 is the destination
8996 ;; Argument 2 is the source
8997 ;; Argument 3 is the length
8998 ;; Argument 4 is the alignment
9000 (define_expand "cmpstrnsi"
9001   [(parallel [(set (match_operand:SI 0)
9002                (compare:SI (match_operand:BLK 1)
9003                            (match_operand:BLK 2)))
9004               (use (match_operand:SI 3))
9005               (use (match_operand:SI 4))])]
9006   "TARGET_CMPB && (BYTES_BIG_ENDIAN || TARGET_LDBRX)"
9008   if (optimize_insn_for_size_p ())
9009     FAIL;
9011   if (expand_strn_compare (operands, 0))
9012     DONE;
9013   else  
9014     FAIL;
9017 ;; String compare insn.
9018 ;; Argument 0 is the target (result)
9019 ;; Argument 1 is the destination
9020 ;; Argument 2 is the source
9021 ;; Argument 3 is the alignment
9023 (define_expand "cmpstrsi"
9024   [(parallel [(set (match_operand:SI 0)
9025                (compare:SI (match_operand:BLK 1)
9026                            (match_operand:BLK 2)))
9027               (use (match_operand:SI 3))])]
9028   "TARGET_CMPB && (BYTES_BIG_ENDIAN || TARGET_LDBRX)"
9030   if (optimize_insn_for_size_p ())
9031     FAIL;
9033   if (expand_strn_compare (operands, 1))
9034     DONE;
9035   else  
9036     FAIL;
9039 ;; Block compare insn.
9040 ;; Argument 0 is the target (result)
9041 ;; Argument 1 is the destination
9042 ;; Argument 2 is the source
9043 ;; Argument 3 is the length
9044 ;; Argument 4 is the alignment
9046 (define_expand "cmpmemsi"
9047   [(parallel [(set (match_operand:SI 0)
9048                (compare:SI (match_operand:BLK 1)
9049                            (match_operand:BLK 2)))
9050               (use (match_operand:SI 3))
9051               (use (match_operand:SI 4))])]
9052   "TARGET_POPCNTD"
9054   if (expand_block_compare (operands))
9055     DONE;
9056   else
9057     FAIL;
9060 ;; String/block move insn.
9061 ;; Argument 0 is the destination
9062 ;; Argument 1 is the source
9063 ;; Argument 2 is the length
9064 ;; Argument 3 is the alignment
9066 (define_expand "movmemsi"
9067   [(parallel [(set (match_operand:BLK 0 "")
9068                    (match_operand:BLK 1 ""))
9069               (use (match_operand:SI 2 ""))
9070               (use (match_operand:SI 3 ""))])]
9071   ""
9073   if (expand_block_move (operands))
9074     DONE;
9075   else
9076     FAIL;
9079 ;; Define insns that do load or store with update.  Some of these we can
9080 ;; get by using pre-decrement or pre-increment, but the hardware can also
9081 ;; do cases where the increment is not the size of the object.
9083 ;; In all these cases, we use operands 0 and 1 for the register being
9084 ;; incremented because those are the operands that local-alloc will
9085 ;; tie and these are the pair most likely to be tieable (and the ones
9086 ;; that will benefit the most).
9088 (define_insn "*movdi_update1"
9089   [(set (match_operand:DI 3 "gpc_reg_operand" "=r,r")
9090         (mem:DI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0,0")
9091                          (match_operand:DI 2 "reg_or_aligned_short_operand" "r,I"))))
9092    (set (match_operand:DI 0 "gpc_reg_operand" "=b,b")
9093         (plus:DI (match_dup 1) (match_dup 2)))]
9094   "TARGET_POWERPC64 && TARGET_UPDATE
9095    && (!avoiding_indexed_address_p (DImode)
9096        || !gpc_reg_operand (operands[2], DImode))"
9097   "@
9098    ldux %3,%0,%2
9099    ldu %3,%2(%0)"
9100   [(set_attr "type" "load")
9101    (set_attr "update" "yes")
9102    (set_attr "indexed" "yes,no")])
9104 (define_insn "movdi_<mode>_update"
9105   [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9106                          (match_operand:P 2 "reg_or_aligned_short_operand" "r,I")))
9107         (match_operand:DI 3 "gpc_reg_operand" "r,r"))
9108    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9109         (plus:P (match_dup 1) (match_dup 2)))]
9110   "TARGET_POWERPC64 && TARGET_UPDATE
9111    && (!avoiding_indexed_address_p (Pmode)
9112        || !gpc_reg_operand (operands[2], Pmode)
9113        || (REG_P (operands[0])
9114            && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
9115   "@
9116    stdux %3,%0,%2
9117    stdu %3,%2(%0)"
9118   [(set_attr "type" "store")
9119    (set_attr "update" "yes")
9120    (set_attr "indexed" "yes,no")])
9122 ;; This pattern is only conditional on TARGET_POWERPC64, as it is
9123 ;; needed for stack allocation, even if the user passes -mno-update.
9124 (define_insn "movdi_<mode>_update_stack"
9125   [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9126                          (match_operand:P 2 "reg_or_aligned_short_operand" "r,I")))
9127         (match_operand:DI 3 "gpc_reg_operand" "r,r"))
9128    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9129         (plus:P (match_dup 1) (match_dup 2)))]
9130   "TARGET_POWERPC64"
9131   "@
9132    stdux %3,%0,%2
9133    stdu %3,%2(%0)"
9134   [(set_attr "type" "store")
9135    (set_attr "update" "yes")
9136    (set_attr "indexed" "yes,no")])
9138 (define_insn "*movsi_update1"
9139   [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9140         (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9141                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9142    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9143         (plus:SI (match_dup 1) (match_dup 2)))]
9144   "TARGET_UPDATE
9145    && (!avoiding_indexed_address_p (SImode)
9146        || !gpc_reg_operand (operands[2], SImode))"
9147   "@
9148    lwzux %3,%0,%2
9149    lwzu %3,%2(%0)"
9150   [(set_attr "type" "load")
9151    (set_attr "update" "yes")
9152    (set_attr "indexed" "yes,no")])
9154 (define_insn "*movsi_update2"
9155   [(set (match_operand:DI 3 "gpc_reg_operand" "=r")
9156         (sign_extend:DI
9157          (mem:SI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0")
9158                           (match_operand:DI 2 "gpc_reg_operand" "r")))))
9159    (set (match_operand:DI 0 "gpc_reg_operand" "=b")
9160         (plus:DI (match_dup 1) (match_dup 2)))]
9161   "TARGET_POWERPC64 && !avoiding_indexed_address_p (DImode)"
9162   "lwaux %3,%0,%2"
9163   [(set_attr "type" "load")
9164    (set_attr "sign_extend" "yes")
9165    (set_attr "update" "yes")
9166    (set_attr "indexed" "yes")])
9168 (define_insn "movsi_update"
9169   [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9170                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9171         (match_operand:SI 3 "gpc_reg_operand" "r,r"))
9172    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9173         (plus:SI (match_dup 1) (match_dup 2)))]
9174   "TARGET_UPDATE
9175    && (!avoiding_indexed_address_p (SImode)
9176        || !gpc_reg_operand (operands[2], SImode)
9177        || (REG_P (operands[0])
9178            && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
9179   "@
9180    stwux %3,%0,%2
9181    stwu %3,%2(%0)"
9182   [(set_attr "type" "store")
9183    (set_attr "update" "yes")
9184    (set_attr "indexed" "yes,no")])
9186 ;; This is an unconditional pattern; needed for stack allocation, even
9187 ;; if the user passes -mno-update.
9188 (define_insn "movsi_update_stack"
9189   [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9190                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9191         (match_operand:SI 3 "gpc_reg_operand" "r,r"))
9192    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9193         (plus:SI (match_dup 1) (match_dup 2)))]
9194   ""
9195   "@
9196    stwux %3,%0,%2
9197    stwu %3,%2(%0)"
9198   [(set_attr "type" "store")
9199    (set_attr "update" "yes")
9200    (set_attr "indexed" "yes,no")])
9202 (define_insn "*movhi_update1"
9203   [(set (match_operand:HI 3 "gpc_reg_operand" "=r,r")
9204         (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9205                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9206    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9207         (plus:SI (match_dup 1) (match_dup 2)))]
9208   "TARGET_UPDATE
9209    && (!avoiding_indexed_address_p (SImode)
9210        || !gpc_reg_operand (operands[2], SImode))"
9211   "@
9212    lhzux %3,%0,%2
9213    lhzu %3,%2(%0)"
9214   [(set_attr "type" "load")
9215    (set_attr "update" "yes")
9216    (set_attr "indexed" "yes,no")])
9218 (define_insn "*movhi_update2"
9219   [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9220         (zero_extend:SI
9221          (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9222                           (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
9223    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9224         (plus:SI (match_dup 1) (match_dup 2)))]
9225   "TARGET_UPDATE
9226    && (!avoiding_indexed_address_p (SImode)
9227        || !gpc_reg_operand (operands[2], SImode))"
9228   "@
9229    lhzux %3,%0,%2
9230    lhzu %3,%2(%0)"
9231   [(set_attr "type" "load")
9232    (set_attr "update" "yes")
9233    (set_attr "indexed" "yes,no")])
9235 (define_insn "*movhi_update3"
9236   [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9237         (sign_extend:SI
9238          (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9239                           (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
9240    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9241         (plus:SI (match_dup 1) (match_dup 2)))]
9242   "TARGET_UPDATE
9243    && !(avoiding_indexed_address_p (SImode)
9244         && gpc_reg_operand (operands[2], SImode))"
9245   "@
9246    lhaux %3,%0,%2
9247    lhau %3,%2(%0)"
9248   [(set_attr "type" "load")
9249    (set_attr "sign_extend" "yes")
9250    (set_attr "update" "yes")
9251    (set_attr "indexed" "yes,no")])
9253 (define_insn "*movhi_update4"
9254   [(set (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9255                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9256         (match_operand:HI 3 "gpc_reg_operand" "r,r"))
9257    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9258         (plus:SI (match_dup 1) (match_dup 2)))]
9259   "TARGET_UPDATE
9260    && (!avoiding_indexed_address_p (SImode)
9261        || !gpc_reg_operand (operands[2], SImode))"
9262   "@
9263    sthux %3,%0,%2
9264    sthu %3,%2(%0)"
9265   [(set_attr "type" "store")
9266    (set_attr "update" "yes")
9267    (set_attr "indexed" "yes,no")])
9269 (define_insn "*movqi_update1"
9270   [(set (match_operand:QI 3 "gpc_reg_operand" "=r,r")
9271         (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9272                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9273    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9274         (plus:SI (match_dup 1) (match_dup 2)))]
9275   "TARGET_UPDATE
9276    && (!avoiding_indexed_address_p (SImode)
9277        || !gpc_reg_operand (operands[2], SImode))"
9278   "@
9279    lbzux %3,%0,%2
9280    lbzu %3,%2(%0)"
9281   [(set_attr "type" "load")
9282    (set_attr "update" "yes")
9283    (set_attr "indexed" "yes,no")])
9285 (define_insn "*movqi_update2"
9286   [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9287         (zero_extend:SI
9288          (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9289                           (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
9290    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9291         (plus:SI (match_dup 1) (match_dup 2)))]
9292   "TARGET_UPDATE
9293    && (!avoiding_indexed_address_p (SImode)
9294        || !gpc_reg_operand (operands[2], SImode))"
9295   "@
9296    lbzux %3,%0,%2
9297    lbzu %3,%2(%0)"
9298   [(set_attr "type" "load")
9299    (set_attr "update" "yes")
9300    (set_attr "indexed" "yes,no")])
9302 (define_insn "*movqi_update3"
9303   [(set (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9304                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9305         (match_operand:QI 3 "gpc_reg_operand" "r,r"))
9306    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9307         (plus:SI (match_dup 1) (match_dup 2)))]
9308   "TARGET_UPDATE
9309    && (!avoiding_indexed_address_p (SImode)
9310        || !gpc_reg_operand (operands[2], SImode))"
9311   "@
9312    stbux %3,%0,%2
9313    stbu %3,%2(%0)"
9314   [(set_attr "type" "store")
9315    (set_attr "update" "yes")
9316    (set_attr "indexed" "yes,no")])
9318 (define_insn "*movsf_update1"
9319   [(set (match_operand:SF 3 "gpc_reg_operand" "=f,f")
9320         (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9321                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9322    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9323         (plus:SI (match_dup 1) (match_dup 2)))]
9324   "TARGET_HARD_FLOAT && TARGET_UPDATE
9325    && (!avoiding_indexed_address_p (SImode)
9326        || !gpc_reg_operand (operands[2], SImode))"
9327   "@
9328    lfsux %3,%0,%2
9329    lfsu %3,%2(%0)"
9330   [(set_attr "type" "fpload")
9331    (set_attr "update" "yes")
9332    (set_attr "indexed" "yes,no")])
9334 (define_insn "*movsf_update2"
9335   [(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9336                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9337         (match_operand:SF 3 "gpc_reg_operand" "f,f"))
9338    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9339         (plus:SI (match_dup 1) (match_dup 2)))]
9340   "TARGET_HARD_FLOAT && TARGET_UPDATE
9341    && (!avoiding_indexed_address_p (SImode)
9342        || !gpc_reg_operand (operands[2], SImode))"
9343   "@
9344    stfsux %3,%0,%2
9345    stfsu %3,%2(%0)"
9346   [(set_attr "type" "fpstore")
9347    (set_attr "update" "yes")
9348    (set_attr "indexed" "yes,no")])
9350 (define_insn "*movsf_update3"
9351   [(set (match_operand:SF 3 "gpc_reg_operand" "=r,r")
9352         (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9353                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9354    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9355         (plus:SI (match_dup 1) (match_dup 2)))]
9356   "TARGET_SOFT_FLOAT && TARGET_UPDATE
9357    && (!avoiding_indexed_address_p (SImode)
9358        || !gpc_reg_operand (operands[2], SImode))"
9359   "@
9360    lwzux %3,%0,%2
9361    lwzu %3,%2(%0)"
9362   [(set_attr "type" "load")
9363    (set_attr "update" "yes")
9364    (set_attr "indexed" "yes,no")])
9366 (define_insn "*movsf_update4"
9367   [(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9368                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9369         (match_operand:SF 3 "gpc_reg_operand" "r,r"))
9370    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9371         (plus:SI (match_dup 1) (match_dup 2)))]
9372   "TARGET_SOFT_FLOAT && TARGET_UPDATE
9373    && (!avoiding_indexed_address_p (SImode)
9374        || !gpc_reg_operand (operands[2], SImode))"
9375   "@
9376    stwux %3,%0,%2
9377    stwu %3,%2(%0)"
9378   [(set_attr "type" "store")
9379    (set_attr "update" "yes")
9380    (set_attr "indexed" "yes,no")])
9382 (define_insn "*movdf_update1"
9383   [(set (match_operand:DF 3 "gpc_reg_operand" "=d,d")
9384         (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9385                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9386    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9387         (plus:SI (match_dup 1) (match_dup 2)))]
9388   "TARGET_HARD_FLOAT && TARGET_UPDATE
9389    && (!avoiding_indexed_address_p (SImode)
9390        || !gpc_reg_operand (operands[2], SImode))"
9391   "@
9392    lfdux %3,%0,%2
9393    lfdu %3,%2(%0)"
9394   [(set_attr "type" "fpload")
9395    (set_attr "update" "yes")
9396    (set_attr "indexed" "yes,no")
9397    (set_attr "size" "64")])
9399 (define_insn "*movdf_update2"
9400   [(set (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9401                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9402         (match_operand:DF 3 "gpc_reg_operand" "d,d"))
9403    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9404         (plus:SI (match_dup 1) (match_dup 2)))]
9405   "TARGET_HARD_FLOAT && TARGET_UPDATE
9406    && (!avoiding_indexed_address_p (SImode)
9407        || !gpc_reg_operand (operands[2], SImode))"
9408   "@
9409    stfdux %3,%0,%2
9410    stfdu %3,%2(%0)"
9411   [(set_attr "type" "fpstore")
9412    (set_attr "update" "yes")
9413    (set_attr "indexed" "yes,no")])
9416 ;; After inserting conditional returns we can sometimes have
9417 ;; unnecessary register moves.  Unfortunately we cannot have a
9418 ;; modeless peephole here, because some single SImode sets have early
9419 ;; clobber outputs.  Although those sets expand to multi-ppc-insn
9420 ;; sequences, using get_attr_length here will smash the operands
9421 ;; array.  Neither is there an early_cobbler_p predicate.
9422 ;; Also this optimization interferes with scalars going into
9423 ;; altivec registers (the code does reloading through the FPRs).
9424 (define_peephole2
9425   [(set (match_operand:DF 0 "gpc_reg_operand")
9426         (match_operand:DF 1 "any_operand"))
9427    (set (match_operand:DF 2 "gpc_reg_operand")
9428         (match_dup 0))]
9429   "!TARGET_VSX
9430    && peep2_reg_dead_p (2, operands[0])"
9431   [(set (match_dup 2) (match_dup 1))])
9433 (define_peephole2
9434   [(set (match_operand:SF 0 "gpc_reg_operand")
9435         (match_operand:SF 1 "any_operand"))
9436    (set (match_operand:SF 2 "gpc_reg_operand")
9437         (match_dup 0))]
9438   "!TARGET_P8_VECTOR
9439    && peep2_reg_dead_p (2, operands[0])"
9440   [(set (match_dup 2) (match_dup 1))])
9443 ;; TLS support.
9445 (define_insn "*tls_gdld_nomark<bits>"
9446   [(match_parallel 3 ""
9447     [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9448           (call (mem:SI (match_operand:P 1))
9449                 (match_operand:P 2 "unspec_tls")))
9450      (match_dup 2)])]
9451   "HAVE_AS_TLS && !TARGET_TLS_MARKERS && DEFAULT_ABI != ABI_DARWIN"
9453   rtx op[3];
9454   op[0] = operands[0];
9455   op[1] = XVECEXP (operands[2], 0, 0);
9456   if (XINT (operands[2], 1) == UNSPEC_TLSGD)
9457     {
9458       op[2] = XVECEXP (operands[2], 0, 1);
9459       if (TARGET_CMODEL != CMODEL_SMALL)
9460         output_asm_insn ("addis %0,%2,%1@got@tlsgd@ha\;"
9461                          "addi %0,%0,%1@got@tlsgd@l", op);
9462       else
9463         output_asm_insn ("addi %0,%2,%1@got@tlsgd", op);
9464     }
9465   else
9466     {
9467       if (TARGET_CMODEL != CMODEL_SMALL)
9468         output_asm_insn ("addis %0,%1,%&@got@tlsld@ha\;"
9469                          "addi %0,%0,%&@got@tlsld@l", op);
9470       else
9471         output_asm_insn ("addi %0,%1,%&@got@tlsld", op);
9472     }
9473   return rs6000_call_template (operands, 1);
9475   [(set_attr "type" "two")
9476    (set (attr "length")
9477      (cond [(match_test "TARGET_CMODEL != CMODEL_SMALL")
9478                 (const_int 16)
9479             (match_test "DEFAULT_ABI != ABI_V4")
9480                 (const_int 12)]
9481         (const_int 8)))])
9483 (define_insn_and_split "*tls_gd<bits>"
9484   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9485         (unspec:P [(match_operand:P 1 "rs6000_tls_symbol_ref" "")
9486                    (match_operand:P 2 "gpc_reg_operand" "b")]
9487                   UNSPEC_TLSGD))]
9488   "HAVE_AS_TLS && TARGET_TLS_MARKERS"
9489   "addi %0,%2,%1@got@tlsgd"
9490   "&& TARGET_CMODEL != CMODEL_SMALL"
9491   [(set (match_dup 3)
9492         (high:P
9493             (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))
9494    (set (match_dup 0)
9495         (lo_sum:P (match_dup 3)
9496             (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))]
9498   operands[3] = gen_reg_rtx (<MODE>mode);
9500   [(set (attr "length")
9501      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9502                    (const_int 8)
9503                    (const_int 4)))])
9505 (define_insn "*tls_gd_high<bits>"
9506   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9507      (high:P
9508        (unspec:P [(match_operand:P 1 "rs6000_tls_symbol_ref" "")
9509                   (match_operand:P 2 "gpc_reg_operand" "b")]
9510                  UNSPEC_TLSGD)))]
9511   "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9512   "addis %0,%2,%1@got@tlsgd@ha")
9514 (define_insn "*tls_gd_low<bits>"
9515   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9516      (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
9517        (unspec:P [(match_operand:P 2 "rs6000_tls_symbol_ref" "")
9518                   (match_operand:P 3 "gpc_reg_operand" "b")]
9519                  UNSPEC_TLSGD)))]
9520   "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9521   "addi %0,%1,%2@got@tlsgd@l")
9523 (define_insn_and_split "*tls_ld<bits>"
9524   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9525         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")]
9526                   UNSPEC_TLSLD))]
9527   "HAVE_AS_TLS && TARGET_TLS_MARKERS"
9528   "addi %0,%1,%&@got@tlsld"
9529   "&& TARGET_CMODEL != CMODEL_SMALL"
9530   [(set (match_dup 2)
9531         (high:P
9532             (unspec:P [(match_dup 1)] UNSPEC_TLSLD)))
9533    (set (match_dup 0)
9534         (lo_sum:P (match_dup 2)
9535             (unspec:P [(match_dup 1)] UNSPEC_TLSLD)))]
9537   operands[2] = gen_reg_rtx (<MODE>mode);
9539   [(set (attr "length")
9540      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9541                    (const_int 8)
9542                    (const_int 4)))])
9544 (define_insn "*tls_ld_high<bits>"
9545   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9546      (high:P
9547        (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")]
9548                  UNSPEC_TLSLD)))]
9549   "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9550   "addis %0,%1,%&@got@tlsld@ha")
9552 (define_insn "*tls_ld_low<bits>"
9553   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9554      (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
9555        (unspec:P [(match_operand:P 2 "gpc_reg_operand" "b")]
9556                  UNSPEC_TLSLD)))]
9557   "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9558   "addi %0,%1,%&@got@tlsld@l")
9560 (define_insn "tls_dtprel_<bits>"
9561   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9562         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9563                    (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9564                   UNSPEC_TLSDTPREL))]
9565   "HAVE_AS_TLS"
9566   "addi %0,%1,%2@dtprel")
9568 (define_insn "tls_dtprel_ha_<bits>"
9569   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9570         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9571                    (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9572                   UNSPEC_TLSDTPRELHA))]
9573   "HAVE_AS_TLS"
9574   "addis %0,%1,%2@dtprel@ha")
9576 (define_insn "tls_dtprel_lo_<bits>"
9577   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9578         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9579                    (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9580                   UNSPEC_TLSDTPRELLO))]
9581   "HAVE_AS_TLS"
9582   "addi %0,%1,%2@dtprel@l")
9584 (define_insn_and_split "tls_got_dtprel_<bits>"
9585   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9586         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9587                    (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9588                   UNSPEC_TLSGOTDTPREL))]
9589   "HAVE_AS_TLS"
9590   "<ptrload> %0,%2@got@dtprel(%1)"
9591   "&& TARGET_CMODEL != CMODEL_SMALL"
9592   [(set (match_dup 3)
9593         (high:P
9594             (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))
9595    (set (match_dup 0)
9596         (lo_sum:P (match_dup 3)
9597             (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))]
9599   operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9601   [(set (attr "length")
9602      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9603                    (const_int 8)
9604                    (const_int 4)))])
9606 (define_insn "*tls_got_dtprel_high<bits>"
9607   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9608      (high:P
9609        (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9610                   (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9611                  UNSPEC_TLSGOTDTPREL)))]
9612   "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9613   "addis %0,%1,%2@got@dtprel@ha")
9615 (define_insn "*tls_got_dtprel_low<bits>"
9616   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9617      (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
9618          (unspec:P [(match_operand:P 3 "gpc_reg_operand" "b")
9619                     (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9620                    UNSPEC_TLSGOTDTPREL)))]
9621   "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9622   "<ptrload> %0,%2@got@dtprel@l(%1)")
9624 (define_insn "tls_tprel_<bits>"
9625   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9626         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9627                    (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9628                   UNSPEC_TLSTPREL))]
9629   "HAVE_AS_TLS"
9630   "addi %0,%1,%2@tprel")
9632 (define_insn "tls_tprel_ha_<bits>"
9633   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9634         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9635                    (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9636                   UNSPEC_TLSTPRELHA))]
9637   "HAVE_AS_TLS"
9638   "addis %0,%1,%2@tprel@ha")
9640 (define_insn "tls_tprel_lo_<bits>"
9641   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9642         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9643                    (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9644                   UNSPEC_TLSTPRELLO))]
9645   "HAVE_AS_TLS"
9646   "addi %0,%1,%2@tprel@l")
9648 ;; "b" output constraint here and on tls_tls input to support linker tls
9649 ;; optimization.  The linker may edit the instructions emitted by a
9650 ;; tls_got_tprel/tls_tls pair to addis,addi.
9651 (define_insn_and_split "tls_got_tprel_<bits>"
9652   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9653         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9654                    (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9655                   UNSPEC_TLSGOTTPREL))]
9656   "HAVE_AS_TLS"
9657   "<ptrload> %0,%2@got@tprel(%1)"
9658   "&& TARGET_CMODEL != CMODEL_SMALL"
9659   [(set (match_dup 3)
9660         (high:P
9661             (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))
9662    (set (match_dup 0)
9663         (lo_sum:P (match_dup 3)
9664             (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))]
9666   operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9668   [(set (attr "length")
9669      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9670                    (const_int 8)
9671                    (const_int 4)))])
9673 (define_insn "*tls_got_tprel_high<bits>"
9674   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9675      (high:P
9676        (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9677                   (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9678                  UNSPEC_TLSGOTTPREL)))]
9679   "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9680   "addis %0,%1,%2@got@tprel@ha")
9682 (define_insn "*tls_got_tprel_low<bits>"
9683   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9684      (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
9685          (unspec:P [(match_operand:P 3 "gpc_reg_operand" "b")
9686                     (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9687                    UNSPEC_TLSGOTTPREL)))]
9688   "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9689   "<ptrload> %0,%2@got@tprel@l(%1)")
9691 (define_insn "tls_tls_<bits>"
9692   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9693         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9694                    (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9695                   UNSPEC_TLSTLS))]
9696   "TARGET_ELF && HAVE_AS_TLS"
9697   "add %0,%1,%2@tls")
9699 (define_expand "tls_get_tpointer"
9700   [(set (match_operand:SI 0 "gpc_reg_operand")
9701         (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))]
9702   "TARGET_XCOFF && HAVE_AS_TLS"
9704   emit_insn (gen_tls_get_tpointer_internal ());
9705   emit_move_insn (operands[0], gen_rtx_REG (SImode, 3));
9706   DONE;
9709 (define_insn "tls_get_tpointer_internal"
9710   [(set (reg:SI 3)
9711         (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))
9712    (clobber (reg:SI LR_REGNO))]
9713   "TARGET_XCOFF && HAVE_AS_TLS"
9714   "bla __get_tpointer")
9716 (define_expand "tls_get_addr<mode>"
9717   [(set (match_operand:P 0 "gpc_reg_operand")
9718         (unspec:P [(match_operand:P 1 "gpc_reg_operand")
9719                    (match_operand:P 2 "gpc_reg_operand")] UNSPEC_TLSTLS))]
9720   "TARGET_XCOFF && HAVE_AS_TLS"
9722   emit_move_insn (gen_rtx_REG (Pmode, 3), operands[1]);
9723   emit_move_insn (gen_rtx_REG (Pmode, 4), operands[2]);
9724   emit_insn (gen_tls_get_addr_internal<mode> ());
9725   emit_move_insn (operands[0], gen_rtx_REG (Pmode, 3));
9726   DONE;
9729 (define_insn "tls_get_addr_internal<mode>"
9730   [(set (reg:P 3)
9731         (unspec:P [(reg:P 3) (reg:P 4)] UNSPEC_TLSTLS))
9732    (clobber (reg:P 0))
9733    (clobber (reg:P 4))
9734    (clobber (reg:P 5))
9735    (clobber (reg:P 11))
9736    (clobber (reg:CC CR0_REGNO))
9737    (clobber (reg:P LR_REGNO))]
9738   "TARGET_XCOFF && HAVE_AS_TLS"
9739   "bla __tls_get_addr")
9741 ;; Next come insns related to the calling sequence.
9743 ;; First, an insn to allocate new stack space for dynamic use (e.g., alloca).
9744 ;; We move the back-chain and decrement the stack pointer.
9746 ;; Operand1 is more naturally reg_or_short_operand.  However, for a large
9747 ;; constant alloca, using that predicate will force the generic code to put
9748 ;; the constant size into a register before calling the expander.
9750 ;; As a result the expander would not have the constant size information
9751 ;; in those cases and would have to generate less efficient code.
9753 ;; Thus we allow reg_or_cint_operand instead so that the expander can see
9754 ;; the constant size.  The value is forced into a register if necessary.
9756 (define_expand "allocate_stack"
9757   [(set (match_operand 0 "gpc_reg_operand")
9758         (minus (reg 1) (match_operand 1 "reg_or_cint_operand")))
9759    (set (reg 1)
9760         (minus (reg 1) (match_dup 1)))]
9761   ""
9763   rtx chain = gen_reg_rtx (Pmode);
9764   rtx stack_bot = gen_rtx_MEM (Pmode, stack_pointer_rtx);
9765   rtx neg_op0;
9766   rtx insn, par, set, mem;
9768   /* By allowing reg_or_cint_operand as the predicate we can get
9769      better code for stack-clash-protection because we do not lose
9770      size information.  But the rest of the code expects the operand
9771      to be reg_or_short_operand.  If it isn't, then force it into
9772      a register.  */
9773   rtx orig_op1 = operands[1];
9774   if (!reg_or_short_operand (operands[1], Pmode))
9775     operands[1] = force_reg (Pmode, operands[1]);
9777   emit_move_insn (chain, stack_bot);
9779   /* Check stack bounds if necessary.  */
9780   if (crtl->limit_stack)
9781     {
9782       rtx available;
9783       available = expand_binop (Pmode, sub_optab,
9784                                 stack_pointer_rtx, stack_limit_rtx,
9785                                 NULL_RTX, 1, OPTAB_WIDEN);
9786       emit_insn (gen_cond_trap (LTU, available, operands[1], const0_rtx));
9787     }
9789   /* Allocate and probe if requested.
9790      This may look similar to the loop we use for prologue allocations,
9791      but it is critically different.  For the former we know the loop
9792      will iterate, but do not know that generally here.  The former
9793      uses that knowledge to rotate the loop.  Combining them would be
9794      possible with some performance cost.  */
9795   if (flag_stack_clash_protection)
9796     {
9797       rtx rounded_size, last_addr, residual;
9798       HOST_WIDE_INT probe_interval;
9799       compute_stack_clash_protection_loop_data (&rounded_size, &last_addr,
9800                                                 &residual, &probe_interval,
9801                                                 orig_op1);
9802       
9803       /* We do occasionally get in here with constant sizes, we might
9804          as well do a reasonable job when we obviously can.  */
9805       if (rounded_size != const0_rtx)
9806         {
9807           rtx loop_lab, end_loop;
9808           bool rotated = CONST_INT_P (rounded_size);
9809           rtx update = GEN_INT (-probe_interval);
9810           if (probe_interval > 32768)
9811             update = force_reg (Pmode, update);
9813           emit_stack_clash_protection_probe_loop_start (&loop_lab, &end_loop,
9814                                                         last_addr, rotated);
9816           if (Pmode == SImode)
9817             emit_insn (gen_movsi_update_stack (stack_pointer_rtx,
9818                                                stack_pointer_rtx,
9819                                                update, chain));
9820           else
9821             emit_insn (gen_movdi_di_update_stack (stack_pointer_rtx,
9822                                                   stack_pointer_rtx,
9823                                                   update, chain));
9824           emit_stack_clash_protection_probe_loop_end (loop_lab, end_loop,
9825                                                       last_addr, rotated);
9826         }
9828       /* Now handle residuals.  We just have to set operands[1] correctly
9829          and let the rest of the expander run.  */
9830       operands[1] = residual;
9831     }
9833   if (!(CONST_INT_P (operands[1])
9834         && IN_RANGE (INTVAL (operands[1]), -32767, 32768)))
9835     {
9836       operands[1] = force_reg (Pmode, operands[1]);
9837       neg_op0 = gen_reg_rtx (Pmode);
9838       if (TARGET_32BIT)
9839         emit_insn (gen_negsi2 (neg_op0, operands[1]));
9840       else
9841         emit_insn (gen_negdi2 (neg_op0, operands[1]));
9842     }
9843   else
9844     neg_op0 = GEN_INT (-INTVAL (operands[1]));
9846   insn = emit_insn ((* ((TARGET_32BIT) ? gen_movsi_update_stack
9847                                        : gen_movdi_di_update_stack))
9848                         (stack_pointer_rtx, stack_pointer_rtx, neg_op0,
9849                          chain));
9850   /* Since we didn't use gen_frame_mem to generate the MEM, grab
9851      it now and set the alias set/attributes. The above gen_*_update
9852      calls will generate a PARALLEL with the MEM set being the first
9853      operation. */
9854   par = PATTERN (insn);
9855   gcc_assert (GET_CODE (par) == PARALLEL);
9856   set = XVECEXP (par, 0, 0);
9857   gcc_assert (GET_CODE (set) == SET);
9858   mem = SET_DEST (set);
9859   gcc_assert (MEM_P (mem));
9860   MEM_NOTRAP_P (mem) = 1;
9861   set_mem_alias_set (mem, get_frame_alias_set ());
9863   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
9864   DONE;
9867 ;; These patterns say how to save and restore the stack pointer.  We need not
9868 ;; save the stack pointer at function level since we are careful to
9869 ;; preserve the backchain.  At block level, we have to restore the backchain
9870 ;; when we restore the stack pointer.
9872 ;; For nonlocal gotos, we must save both the stack pointer and its
9873 ;; backchain and restore both.  Note that in the nonlocal case, the
9874 ;; save area is a memory location.
9876 (define_expand "save_stack_function"
9877   [(match_operand 0 "any_operand")
9878    (match_operand 1 "any_operand")]
9879   ""
9880   "DONE;")
9882 (define_expand "restore_stack_function"
9883   [(match_operand 0 "any_operand")
9884    (match_operand 1 "any_operand")]
9885   ""
9886   "DONE;")
9888 ;; Adjust stack pointer (op0) to a new value (op1).
9889 ;; First copy old stack backchain to new location, and ensure that the
9890 ;; scheduler won't reorder the sp assignment before the backchain write.
9891 (define_expand "restore_stack_block"
9892   [(set (match_dup 2) (match_dup 3))
9893    (set (match_dup 4) (match_dup 2))
9894    (match_dup 5)
9895    (set (match_operand 0 "register_operand")
9896         (match_operand 1 "register_operand"))]
9897   ""
9899   rtvec p;
9901   operands[1] = force_reg (Pmode, operands[1]);
9902   operands[2] = gen_reg_rtx (Pmode);
9903   operands[3] = gen_frame_mem (Pmode, operands[0]);
9904   operands[4] = gen_frame_mem (Pmode, operands[1]);
9905   p = rtvec_alloc (1);
9906   RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
9907                                   const0_rtx);
9908   operands[5] = gen_rtx_PARALLEL (VOIDmode, p);
9911 (define_expand "save_stack_nonlocal"
9912   [(set (match_dup 3) (match_dup 4))
9913    (set (match_operand 0 "memory_operand") (match_dup 3))
9914    (set (match_dup 2) (match_operand 1 "register_operand"))]
9915   ""
9917   int units_per_word = (TARGET_32BIT) ? 4 : 8;
9919   /* Copy the backchain to the first word, sp to the second.  */
9920   operands[0] = adjust_address_nv (operands[0], Pmode, 0);
9921   operands[2] = adjust_address_nv (operands[0], Pmode, units_per_word);
9922   operands[3] = gen_reg_rtx (Pmode);
9923   operands[4] = gen_frame_mem (Pmode, operands[1]);
9926 (define_expand "restore_stack_nonlocal"
9927   [(set (match_dup 2) (match_operand 1 "memory_operand"))
9928    (set (match_dup 3) (match_dup 4))
9929    (set (match_dup 5) (match_dup 2))
9930    (match_dup 6)
9931    (set (match_operand 0 "register_operand") (match_dup 3))]
9932   ""
9934   int units_per_word = (TARGET_32BIT) ? 4 : 8;
9935   rtvec p;
9937   /* Restore the backchain from the first word, sp from the second.  */
9938   operands[2] = gen_reg_rtx (Pmode);
9939   operands[3] = gen_reg_rtx (Pmode);
9940   operands[1] = adjust_address_nv (operands[1], Pmode, 0);
9941   operands[4] = adjust_address_nv (operands[1], Pmode, units_per_word);
9942   operands[5] = gen_frame_mem (Pmode, operands[3]);
9943   p = rtvec_alloc (1);
9944   RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
9945                                   const0_rtx);
9946   operands[6] = gen_rtx_PARALLEL (VOIDmode, p);
9949 ;; TOC register handling.
9951 ;; Code to initialize the TOC register...
9953 (define_insn "load_toc_aix_si"
9954   [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
9955                    (unspec:SI [(const_int 0)] UNSPEC_TOC))
9956               (use (reg:SI 2))])]
9957   "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_32BIT"
9959   char buf[30];
9960   extern int need_toc_init;
9961   need_toc_init = 1;
9962   ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
9963   operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
9964   operands[2] = gen_rtx_REG (Pmode, 2);
9965   return "lwz %0,%1(%2)";
9967   [(set_attr "type" "load")
9968    (set_attr "update" "no")
9969    (set_attr "indexed" "no")])
9971 (define_insn "load_toc_aix_di"
9972   [(parallel [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
9973                    (unspec:DI [(const_int 0)] UNSPEC_TOC))
9974               (use (reg:DI 2))])]
9975   "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_64BIT"
9977   char buf[30];
9978   extern int need_toc_init;
9979   need_toc_init = 1;
9980   ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC",
9981                                !TARGET_ELF || !TARGET_MINIMAL_TOC);
9982   if (TARGET_ELF)
9983     strcat (buf, "@toc");
9984   operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
9985   operands[2] = gen_rtx_REG (Pmode, 2);
9986   return "ld %0,%1(%2)";
9988   [(set_attr "type" "load")
9989    (set_attr "update" "no")
9990    (set_attr "indexed" "no")])
9992 (define_insn "load_toc_v4_pic_si"
9993   [(set (reg:SI LR_REGNO)
9994         (unspec:SI [(const_int 0)] UNSPEC_TOC))]
9995   "DEFAULT_ABI == ABI_V4 && flag_pic == 1 && TARGET_32BIT"
9996   "bl _GLOBAL_OFFSET_TABLE_@local-4"
9997   [(set_attr "type" "branch")])
9999 (define_expand "load_toc_v4_PIC_1"
10000   [(parallel [(set (reg:SI LR_REGNO)
10001                    (match_operand:SI 0 "immediate_operand" "s"))
10002               (use (unspec [(match_dup 0)] UNSPEC_TOC))])]
10003   "TARGET_ELF && DEFAULT_ABI == ABI_V4
10004    && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10005   "")
10007 (define_insn "load_toc_v4_PIC_1_normal"
10008   [(set (reg:SI LR_REGNO)
10009         (match_operand:SI 0 "immediate_operand" "s"))
10010    (use (unspec [(match_dup 0)] UNSPEC_TOC))]
10011   "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
10012    && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10013   "bcl 20,31,%0\n%0:"
10014   [(set_attr "type" "branch")
10015    (set_attr "cannot_copy" "yes")])
10017 (define_insn "load_toc_v4_PIC_1_476"
10018   [(set (reg:SI LR_REGNO)
10019         (match_operand:SI 0 "immediate_operand" "s"))
10020    (use (unspec [(match_dup 0)] UNSPEC_TOC))]
10021   "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
10022    && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10024   char name[32];
10025   static char templ[32];
10027   get_ppc476_thunk_name (name);
10028   sprintf (templ, "bl %s\n%%0:", name);
10029   return templ;
10031   [(set_attr "type" "branch")
10032    (set_attr "cannot_copy" "yes")])
10034 (define_expand "load_toc_v4_PIC_1b"
10035   [(parallel [(set (reg:SI LR_REGNO)
10036                    (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10037                                (label_ref (match_operand 1 ""))]
10038                            UNSPEC_TOCPTR))
10039               (match_dup 1)])]
10040   "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10041   "")
10043 (define_insn "load_toc_v4_PIC_1b_normal"
10044   [(set (reg:SI LR_REGNO)
10045         (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10046                     (label_ref (match_operand 1 "" ""))]
10047                 UNSPEC_TOCPTR))
10048    (match_dup 1)]
10049   "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10050   "bcl 20,31,$+8\;.long %0-$"
10051   [(set_attr "type" "branch")
10052    (set_attr "length" "8")])
10054 (define_insn "load_toc_v4_PIC_1b_476"
10055   [(set (reg:SI LR_REGNO)
10056         (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10057                     (label_ref (match_operand 1 "" ""))]
10058                 UNSPEC_TOCPTR))
10059    (match_dup 1)]
10060   "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10062   char name[32];
10063   static char templ[32];
10065   get_ppc476_thunk_name (name);
10066   sprintf (templ, "bl %s\;b $+8\;.long %%0-$", name);
10067   return templ;
10069   [(set_attr "type" "branch")
10070    (set_attr "length" "16")])
10072 (define_insn "load_toc_v4_PIC_2"
10073   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10074         (mem:SI (plus:SI
10075                   (match_operand:SI 1 "gpc_reg_operand" "b")
10076                   (const
10077                     (minus:SI (match_operand:SI 2 "immediate_operand" "s")
10078                               (match_operand:SI 3 "immediate_operand" "s"))))))]
10079   "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10080   "lwz %0,%2-%3(%1)"
10081   [(set_attr "type" "load")])
10083 (define_insn "load_toc_v4_PIC_3b"
10084   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10085         (plus:SI
10086           (match_operand:SI 1 "gpc_reg_operand" "b")
10087           (high:SI
10088             (const
10089               (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
10090                         (match_operand:SI 3 "symbol_ref_operand" "s"))))))]
10091   "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
10092   "addis %0,%1,%2-%3@ha")
10094 (define_insn "load_toc_v4_PIC_3c"
10095   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10096         (lo_sum:SI
10097           (match_operand:SI 1 "gpc_reg_operand" "b")
10098           (const
10099             (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
10100                       (match_operand:SI 3 "symbol_ref_operand" "s")))))]
10101   "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
10102   "addi %0,%1,%2-%3@l")
10104 ;; If the TOC is shared over a translation unit, as happens with all
10105 ;; the kinds of PIC that we support, we need to restore the TOC
10106 ;; pointer only when jumping over units of translation.
10107 ;; On Darwin, we need to reload the picbase.
10109 (define_expand "builtin_setjmp_receiver"
10110   [(use (label_ref (match_operand 0 "")))]
10111   "(DEFAULT_ABI == ABI_V4 && flag_pic == 1)
10112    || (TARGET_TOC && TARGET_MINIMAL_TOC)
10113    || (DEFAULT_ABI == ABI_DARWIN && flag_pic)"
10115 #if TARGET_MACHO
10116   if (DEFAULT_ABI == ABI_DARWIN)
10117     {
10118       rtx picrtx = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME);
10119       rtx picreg = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
10120       rtx tmplabrtx;
10121       char tmplab[20];
10123       crtl->uses_pic_offset_table = 1;
10124       ASM_GENERATE_INTERNAL_LABEL(tmplab, "LSJR",
10125                                   CODE_LABEL_NUMBER (operands[0]));
10126       tmplabrtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (tmplab));
10128       emit_insn (gen_load_macho_picbase (tmplabrtx));
10129       emit_move_insn (picreg, gen_rtx_REG (Pmode, LR_REGNO));
10130       emit_insn (gen_macho_correct_pic (picreg, picreg, picrtx, tmplabrtx));
10131     }
10132   else
10133 #endif
10134     rs6000_emit_load_toc_table (FALSE);
10135   DONE;
10138 ;; Largetoc support
10139 (define_insn "*largetoc_high"
10140   [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
10141         (high:DI
10142           (unspec [(match_operand:DI 1 "" "")
10143                    (match_operand:DI 2 "gpc_reg_operand" "b")]
10144                   UNSPEC_TOCREL)))]
10145    "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10146    "addis %0,%2,%1@toc@ha")
10148 (define_insn "*largetoc_high_aix<mode>"
10149   [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
10150         (high:P
10151           (unspec [(match_operand:P 1 "" "")
10152                    (match_operand:P 2 "gpc_reg_operand" "b")]
10153                   UNSPEC_TOCREL)))]
10154    "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10155    "addis %0,%1@u(%2)")
10157 (define_insn "*largetoc_high_plus"
10158   [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
10159         (high:DI
10160           (plus:DI
10161             (unspec [(match_operand:DI 1 "" "")
10162                      (match_operand:DI 2 "gpc_reg_operand" "b")]
10163                     UNSPEC_TOCREL)
10164             (match_operand:DI 3 "add_cint_operand" "n"))))]
10165    "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10166    "addis %0,%2,%1+%3@toc@ha")
10168 (define_insn "*largetoc_high_plus_aix<mode>"
10169   [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
10170         (high:P
10171           (plus:P
10172             (unspec [(match_operand:P 1 "" "")
10173                      (match_operand:P 2 "gpc_reg_operand" "b")]
10174                     UNSPEC_TOCREL)
10175             (match_operand:P 3 "add_cint_operand" "n"))))]
10176    "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10177    "addis %0,%1+%3@u(%2)")
10179 (define_insn "*largetoc_low"
10180   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
10181         (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b")
10182                    (match_operand:DI 2 "" "")))]
10183    "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10184    "addi %0,%1,%2@l")
10186 (define_insn "*largetoc_low_aix<mode>"
10187   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10188         (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
10189                    (match_operand:P 2 "" "")))]
10190    "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10191    "la %0,%2@l(%1)")
10193 (define_insn_and_split "*tocref<mode>"
10194   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
10195         (match_operand:P 1 "small_toc_ref" "R"))]
10196    "TARGET_TOC"
10197    "la %0,%a1"
10198    "&& TARGET_CMODEL != CMODEL_SMALL && reload_completed"
10199   [(set (match_dup 0) (high:P (match_dup 1)))
10200    (set (match_dup 0) (lo_sum:P (match_dup 0) (match_dup 1)))])
10202 ;; Elf specific ways of loading addresses for non-PIC code.
10203 ;; The output of this could be r0, but we make a very strong
10204 ;; preference for a base register because it will usually
10205 ;; be needed there.
10206 (define_insn "elf_high"
10207   [(set (match_operand:SI 0 "gpc_reg_operand" "=b*r")
10208         (high:SI (match_operand 1 "" "")))]
10209   "TARGET_ELF && !TARGET_64BIT && !flag_pic"
10210   "lis %0,%1@ha")
10212 (define_insn "elf_low"
10213   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10214         (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
10215                    (match_operand 2 "" "")))]
10216    "TARGET_ELF && !TARGET_64BIT && !flag_pic"
10217    "la %0,%2@l(%1)")
10219 (define_insn "*pltseq_tocsave_<mode>"
10220   [(set (match_operand:P 0 "memory_operand" "=m")
10221         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
10222                    (match_operand:P 2 "symbol_ref_operand" "s")
10223                    (match_operand:P 3 "" "")]
10224                   UNSPEC_PLTSEQ))]
10225   "HAVE_AS_PLTSEQ && TARGET_TLS_MARKERS
10226    && DEFAULT_ABI == ABI_ELFv2"
10228   return rs6000_pltseq_template (operands, 0);
10231 (define_insn "*pltseq_plt16_ha_<mode>"
10232   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10233         (unspec:P [(match_operand:P 1 "" "")
10234                    (match_operand:P 2 "symbol_ref_operand" "s")
10235                    (match_operand:P 3 "" "")]
10236                   UNSPEC_PLT16_HA))]
10237   "HAVE_AS_PLTSEQ && TARGET_TLS_MARKERS
10238    && (DEFAULT_ABI == ABI_ELFv2 || DEFAULT_ABI == ABI_V4)"
10240   return rs6000_pltseq_template (operands, 1);
10243 (define_insn "*pltseq_plt16_lo_<mode>"
10244   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10245         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
10246                    (match_operand:P 2 "symbol_ref_operand" "s")
10247                    (match_operand:P 3 "" "")]
10248                   UNSPEC_PLT16_LO))]
10249   "HAVE_AS_PLTSEQ && TARGET_TLS_MARKERS
10250    && (DEFAULT_ABI == ABI_ELFv2 || DEFAULT_ABI == ABI_V4)"
10252   return rs6000_pltseq_template (operands, 2);
10254   [(set_attr "type" "load")])
10256 (define_insn "*pltseq_mtctr_<mode>"
10257   [(set (match_operand:P 0 "register_operand" "=c")
10258         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "r")
10259                    (match_operand:P 2 "symbol_ref_operand" "s")
10260                    (match_operand:P 3 "" "")]
10261                   UNSPEC_PLTSEQ))]
10262   "HAVE_AS_PLTSEQ && TARGET_TLS_MARKERS
10263    && (DEFAULT_ABI == ABI_ELFv2 || DEFAULT_ABI == ABI_V4)"
10265   return rs6000_pltseq_template (operands, 3);
10268 ;; Call and call_value insns
10269 (define_expand "call"
10270   [(parallel [(call (mem:SI (match_operand 0 "address_operand"))
10271                     (match_operand 1 ""))
10272               (use (match_operand 2 ""))
10273               (clobber (reg:SI LR_REGNO))])]
10274   ""
10276 #if TARGET_MACHO
10277   if (MACHOPIC_INDIRECT)
10278     operands[0] = machopic_indirect_call_target (operands[0]);
10279 #endif
10281   gcc_assert (GET_CODE (operands[0]) == MEM);
10283   operands[0] = XEXP (operands[0], 0);
10285   if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10286     {
10287       rs6000_call_aix (NULL_RTX, operands[0], operands[1], operands[2]);
10288       DONE;
10289     }
10291   if (DEFAULT_ABI == ABI_V4)
10292     {
10293       rs6000_call_sysv (NULL_RTX, operands[0], operands[1], operands[2]);
10294       DONE;
10295     }
10297   if (GET_CODE (operands[0]) != SYMBOL_REF)
10298     operands[0] = force_reg (Pmode, operands[0]);
10301 (define_expand "call_value"
10302   [(parallel [(set (match_operand 0 "")
10303                    (call (mem:SI (match_operand 1 "address_operand"))
10304                          (match_operand 2 "")))
10305               (use (match_operand 3 ""))
10306               (clobber (reg:SI LR_REGNO))])]
10307   ""
10309 #if TARGET_MACHO
10310   if (MACHOPIC_INDIRECT)
10311     operands[1] = machopic_indirect_call_target (operands[1]);
10312 #endif
10314   gcc_assert (GET_CODE (operands[1]) == MEM);
10316   operands[1] = XEXP (operands[1], 0);
10318   if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10319     {
10320       rs6000_call_aix (operands[0], operands[1], operands[2], operands[3]);
10321       DONE;
10322     }
10324   if (DEFAULT_ABI == ABI_V4)
10325     {
10326       rs6000_call_sysv (operands[0], operands[1], operands[2], operands[3]);
10327       DONE;
10328     }
10330   if (GET_CODE (operands[1]) != SYMBOL_REF)
10331     operands[1] = force_reg (Pmode, operands[1]);
10334 ;; Call to function in current module.  No TOC pointer reload needed.
10335 ;; Operand2 is nonzero if we are using the V.4 calling sequence and
10336 ;; either the function was not prototyped, or it was prototyped as a
10337 ;; variable argument function.  It is > 0 if FP registers were passed
10338 ;; and < 0 if they were not.
10340 (define_insn "*call_local32"
10341   [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
10342          (match_operand 1))
10343    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10344    (clobber (reg:SI LR_REGNO))]
10345   "(INTVAL (operands[2]) & CALL_LONG) == 0"
10347   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10348     output_asm_insn ("crxor 6,6,6", operands);
10350   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10351     output_asm_insn ("creqv 6,6,6", operands);
10353   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z0@local" : "bl %z0";
10355   [(set_attr "type" "branch")
10356    (set_attr "length" "4,8")])
10358 (define_insn "*call_local64"
10359   [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
10360          (match_operand 1))
10361    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10362    (clobber (reg:SI LR_REGNO))]
10363   "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
10365   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10366     output_asm_insn ("crxor 6,6,6", operands);
10368   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10369     output_asm_insn ("creqv 6,6,6", operands);
10371   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z0@local" : "bl %z0";
10373   [(set_attr "type" "branch")
10374    (set_attr "length" "4,8")])
10376 (define_insn "*call_value_local32"
10377   [(set (match_operand 0 "" "")
10378         (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
10379               (match_operand 2)))
10380    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10381    (clobber (reg:SI LR_REGNO))]
10382   "(INTVAL (operands[3]) & CALL_LONG) == 0"
10384   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10385     output_asm_insn ("crxor 6,6,6", operands);
10387   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10388     output_asm_insn ("creqv 6,6,6", operands);
10390   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z1@local" : "bl %z1";
10392   [(set_attr "type" "branch")
10393    (set_attr "length" "4,8")])
10396 (define_insn "*call_value_local64"
10397   [(set (match_operand 0 "" "")
10398         (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
10399               (match_operand 2)))
10400    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10401    (clobber (reg:SI LR_REGNO))]
10402   "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
10404   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10405     output_asm_insn ("crxor 6,6,6", operands);
10407   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10408     output_asm_insn ("creqv 6,6,6", operands);
10410   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z1@local" : "bl %z1";
10412   [(set_attr "type" "branch")
10413    (set_attr "length" "4,8")])
10416 ;; A function pointer under System V is just a normal pointer
10417 ;; operands[0] is the function pointer
10418 ;; operands[1] is the tls call arg
10419 ;; operands[2] is the value FUNCTION_ARG returns for the VOID argument
10420 ;; which indicates how to set cr1
10422 (define_insn "*call_indirect_nonlocal_sysv<mode>"
10423   [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X"))
10424          (match_operand 1))
10425    (use (match_operand:SI 2 "immediate_operand" "n,n,n"))
10426    (clobber (reg:SI LR_REGNO))]
10427   "DEFAULT_ABI == ABI_V4
10428    || DEFAULT_ABI == ABI_DARWIN"
10430   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10431     output_asm_insn ("crxor 6,6,6", operands);
10433   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10434     output_asm_insn ("creqv 6,6,6", operands);
10436   return rs6000_indirect_call_template (operands, 0);
10438   [(set_attr "type" "jmpreg")
10439    (set (attr "length")
10440         (cond [(and (and (match_test "!rs6000_speculate_indirect_jumps")
10441                          (match_test "which_alternative != 1"))
10442                     (match_test "(INTVAL (operands[2]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
10443                   (const_string "12")
10444                (ior (and (match_test "!rs6000_speculate_indirect_jumps")
10445                          (match_test "which_alternative != 1"))
10446                     (match_test "(INTVAL (operands[2]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
10447                   (const_string "8")]
10448               (const_string "4")))])
10450 (define_insn_and_split "*call_nonlocal_sysv<mode>"
10451   [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
10452          (match_operand 1))
10453    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10454    (clobber (reg:SI LR_REGNO))]
10455   "(DEFAULT_ABI == ABI_DARWIN
10456    || (DEFAULT_ABI == ABI_V4
10457        && (INTVAL (operands[2]) & CALL_LONG) == 0))"
10459   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10460     output_asm_insn ("crxor 6,6,6", operands);
10462   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10463     output_asm_insn ("creqv 6,6,6", operands);
10465 #if TARGET_MACHO
10466   return macho_call_template (insn, operands, 0, 2);
10467 #else
10468   return rs6000_call_template (operands, 0);
10469 #endif
10471   "DEFAULT_ABI == ABI_V4
10472    && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0])
10473    && (INTVAL (operands[2]) & CALL_LONG) == 0"
10474   [(parallel [(call (mem:SI (match_dup 0))
10475                     (match_dup 1))
10476               (use (match_dup 2))
10477               (use (match_dup 3))
10478               (clobber (reg:SI LR_REGNO))])]
10480   operands[3] = pic_offset_table_rtx;
10482   [(set_attr "type" "branch,branch")
10483    (set_attr "length" "4,8")])
10485 (define_insn "*call_nonlocal_sysv_secure<mode>"
10486   [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
10487          (match_operand 1))
10488    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10489    (use (match_operand:SI 3 "register_operand" "r,r"))
10490    (clobber (reg:SI LR_REGNO))]
10491   "(DEFAULT_ABI == ABI_V4
10492     && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0])
10493     && (INTVAL (operands[2]) & CALL_LONG) == 0)"
10495   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10496     output_asm_insn ("crxor 6,6,6", operands);
10498   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10499     output_asm_insn ("creqv 6,6,6", operands);
10501   return rs6000_call_template (operands, 0);
10503   [(set_attr "type" "branch,branch")
10504    (set_attr "length" "4,8")])
10506 (define_insn "*call_value_indirect_nonlocal_sysv<mode>"
10507   [(set (match_operand 0 "" "")
10508         (call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X"))
10509               (match_operand 2)))
10510    (use (match_operand:SI 3 "immediate_operand" "n,n,n"))
10511    (clobber (reg:SI LR_REGNO))]
10512   "DEFAULT_ABI == ABI_V4
10513    || DEFAULT_ABI == ABI_DARWIN"
10515   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10516     output_asm_insn ("crxor 6,6,6", operands);
10518   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10519     output_asm_insn ("creqv 6,6,6", operands);
10521   return rs6000_indirect_call_template (operands, 1);
10523   [(set_attr "type" "jmpreg")
10524    (set (attr "length")
10525         (cond [(and (and (match_test "!rs6000_speculate_indirect_jumps")
10526                          (match_test "which_alternative != 1"))
10527                     (match_test "(INTVAL (operands[3]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
10528                   (const_string "12")
10529                (ior (and (match_test "!rs6000_speculate_indirect_jumps")
10530                          (match_test "which_alternative != 1"))
10531                    (match_test "(INTVAL (operands[3]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
10532                   (const_string "8")]
10533               (const_string "4")))])
10535 (define_insn_and_split "*call_value_nonlocal_sysv<mode>"
10536   [(set (match_operand 0 "" "")
10537         (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
10538               (match_operand 2)))
10539    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10540    (clobber (reg:SI LR_REGNO))]
10541   "(DEFAULT_ABI == ABI_DARWIN
10542    || (DEFAULT_ABI == ABI_V4
10543        && (INTVAL (operands[3]) & CALL_LONG) == 0))"
10545   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10546     output_asm_insn ("crxor 6,6,6", operands);
10548   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10549     output_asm_insn ("creqv 6,6,6", operands);
10551 #if TARGET_MACHO
10552   return macho_call_template (insn, operands, 1, 3);
10553 #else
10554   return rs6000_call_template (operands, 1);
10555 #endif
10557   "DEFAULT_ABI == ABI_V4
10558    && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1])
10559    && (INTVAL (operands[3]) & CALL_LONG) == 0"
10560   [(parallel [(set (match_dup 0)
10561                    (call (mem:SI (match_dup 1))
10562                          (match_dup 2)))
10563               (use (match_dup 3))
10564               (use (match_dup 4))
10565               (clobber (reg:SI LR_REGNO))])]
10567   operands[4] = pic_offset_table_rtx;
10569   [(set_attr "type" "branch,branch")
10570    (set_attr "length" "4,8")])
10572 (define_insn "*call_value_nonlocal_sysv_secure<mode>"
10573   [(set (match_operand 0 "" "")
10574         (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
10575               (match_operand 2)))
10576    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10577    (use (match_operand:SI 4 "register_operand" "r,r"))
10578    (clobber (reg:SI LR_REGNO))]
10579   "(DEFAULT_ABI == ABI_V4
10580     && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1])
10581     && (INTVAL (operands[3]) & CALL_LONG) == 0)"
10583   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10584     output_asm_insn ("crxor 6,6,6", operands);
10586   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10587     output_asm_insn ("creqv 6,6,6", operands);
10589   return rs6000_call_template (operands, 1);
10591   [(set_attr "type" "branch,branch")
10592    (set_attr "length" "4,8")])
10595 ;; Call to AIX abi function in the same module.
10597 (define_insn "*call_local_aix<mode>"
10598   [(call (mem:SI (match_operand:P 0 "current_file_function_operand" "s"))
10599          (match_operand 1))
10600    (clobber (reg:P LR_REGNO))]
10601   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10602   "bl %z0"
10603   [(set_attr "type" "branch")])
10605 (define_insn "*call_value_local_aix<mode>"
10606   [(set (match_operand 0 "" "")
10607         (call (mem:SI (match_operand:P 1 "current_file_function_operand" "s"))
10608               (match_operand 2)))
10609    (clobber (reg:P LR_REGNO))]
10610   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10611   "bl %z1"
10612   [(set_attr "type" "branch")])
10614 ;; Call to AIX abi function which may be in another module.
10615 ;; Restore the TOC pointer (r2) after the call.
10617 (define_insn "*call_nonlocal_aix<mode>"
10618   [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s"))
10619          (match_operand 1))
10620    (clobber (reg:P LR_REGNO))]
10621   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10623   return rs6000_call_template (operands, 0);
10625   [(set_attr "type" "branch")
10626    (set_attr "length" "8")])
10628 (define_insn "*call_value_nonlocal_aix<mode>"
10629   [(set (match_operand 0 "" "")
10630         (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s"))
10631               (match_operand 2)))
10632    (clobber (reg:P LR_REGNO))]
10633   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10635   return rs6000_call_template (operands, 1);
10637   [(set_attr "type" "branch")
10638    (set_attr "length" "8")])
10640 ;; Call to indirect functions with the AIX abi using a 3 word descriptor.
10641 ;; Operand0 is the addresss of the function to call
10642 ;; Operand2 is the location in the function descriptor to load r2 from
10643 ;; Operand3 is the offset of the stack location holding the current TOC pointer
10645 (define_insn "*call_indirect_aix<mode>"
10646   [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X"))
10647          (match_operand 1))
10648    (use (match_operand:P 2 "memory_operand" "<ptrm>,<ptrm>,<ptrm>"))
10649    (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 3 "const_int_operand" "n,n,n")] UNSPEC_TOCSLOT))
10650    (clobber (reg:P LR_REGNO))]
10651   "DEFAULT_ABI == ABI_AIX"
10653   return rs6000_indirect_call_template (operands, 0);
10655   [(set_attr "type" "jmpreg")
10656    (set (attr "length")
10657         (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
10658                            (match_test "which_alternative != 1"))
10659                       (const_string "16")
10660                       (const_string "12")))])
10662 (define_insn "*call_value_indirect_aix<mode>"
10663   [(set (match_operand 0 "" "")
10664         (call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X"))
10665               (match_operand 2)))
10666    (use (match_operand:P 3 "memory_operand" "<ptrm>,<ptrm>,<ptrm>"))
10667    (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 4 "const_int_operand" "n,n,n")] UNSPEC_TOCSLOT))
10668    (clobber (reg:P LR_REGNO))]
10669   "DEFAULT_ABI == ABI_AIX"
10671   return rs6000_indirect_call_template (operands, 1);
10673   [(set_attr "type" "jmpreg")
10674    (set (attr "length")
10675         (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
10676                            (match_test "which_alternative != 1"))
10677                       (const_string "16")
10678                       (const_string "12")))])
10680 ;; Call to indirect functions with the ELFv2 ABI.
10681 ;; Operand0 is the addresss of the function to call
10682 ;; Operand2 is the offset of the stack location holding the current TOC pointer
10684 (define_insn "*call_indirect_elfv2<mode>"
10685   [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X"))
10686          (match_operand 1))
10687    (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 2 "const_int_operand" "n,n,n")] UNSPEC_TOCSLOT))
10688    (clobber (reg:P LR_REGNO))]
10689   "DEFAULT_ABI == ABI_ELFv2"
10691   return rs6000_indirect_call_template (operands, 0);
10693   [(set_attr "type" "jmpreg")
10694    (set (attr "length")
10695         (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
10696                            (match_test "which_alternative != 1"))
10697                       (const_string "12")
10698                       (const_string "8")))])
10700 (define_insn "*call_value_indirect_elfv2<mode>"
10701   [(set (match_operand 0 "" "")
10702         (call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X"))
10703               (match_operand 2)))
10704    (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 3 "const_int_operand" "n,n,n")] UNSPEC_TOCSLOT))
10705    (clobber (reg:P LR_REGNO))]
10706   "DEFAULT_ABI == ABI_ELFv2"
10708   return rs6000_indirect_call_template (operands, 1);
10710   [(set_attr "type" "jmpreg")
10711    (set (attr "length")
10712         (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
10713                            (match_test "which_alternative != 1"))
10714                       (const_string "12")
10715                       (const_string "8")))])
10717 ;; Call subroutine returning any type.
10718 (define_expand "untyped_call"
10719   [(parallel [(call (match_operand 0 "")
10720                     (const_int 0))
10721               (match_operand 1 "")
10722               (match_operand 2 "")])]
10723   ""
10725   int i;
10727   emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
10729   for (i = 0; i < XVECLEN (operands[2], 0); i++)
10730     {
10731       rtx set = XVECEXP (operands[2], 0, i);
10732       emit_move_insn (SET_DEST (set), SET_SRC (set));
10733     }
10735   /* The optimizer does not know that the call sets the function value
10736      registers we stored in the result block.  We avoid problems by
10737      claiming that all hard registers are used and clobbered at this
10738      point.  */
10739   emit_insn (gen_blockage ());
10741   DONE;
10744 ;; sibling call patterns
10745 (define_expand "sibcall"
10746   [(parallel [(call (mem:SI (match_operand 0 "address_operand"))
10747                     (match_operand 1 ""))
10748               (use (match_operand 2 ""))
10749               (simple_return)])]
10750   ""
10752 #if TARGET_MACHO
10753   if (MACHOPIC_INDIRECT)
10754     operands[0] = machopic_indirect_call_target (operands[0]);
10755 #endif
10757   gcc_assert (GET_CODE (operands[0]) == MEM);
10758   gcc_assert (GET_CODE (operands[1]) == CONST_INT);
10760   operands[0] = XEXP (operands[0], 0);
10762   if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10763     {
10764       rs6000_sibcall_aix (NULL_RTX, operands[0], operands[1], operands[2]);
10765       DONE;
10766     }
10768   if (DEFAULT_ABI == ABI_V4)
10769     {
10770       rs6000_sibcall_sysv (NULL_RTX, operands[0], operands[1], operands[2]);
10771       DONE;
10772     }
10775 (define_expand "sibcall_value"
10776   [(parallel [(set (match_operand 0 "register_operand")
10777                 (call (mem:SI (match_operand 1 "address_operand"))
10778                       (match_operand 2 "")))
10779               (use (match_operand 3 ""))
10780               (simple_return)])]
10781   ""
10783 #if TARGET_MACHO
10784   if (MACHOPIC_INDIRECT)
10785     operands[1] = machopic_indirect_call_target (operands[1]);
10786 #endif
10788   gcc_assert (GET_CODE (operands[1]) == MEM);
10789   gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10791   operands[1] = XEXP (operands[1], 0);
10793   if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10794     {
10795       rs6000_sibcall_aix (operands[0], operands[1], operands[2], operands[3]);
10796       DONE;
10797     }
10799   if (DEFAULT_ABI == ABI_V4)
10800     {
10801       rs6000_sibcall_sysv (operands[0], operands[1], operands[2], operands[3]);
10802       DONE;
10803     }
10806 (define_insn "*sibcall_local32"
10807   [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
10808          (match_operand 1))
10809    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10810    (simple_return)]
10811   "(INTVAL (operands[2]) & CALL_LONG) == 0"
10813   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10814     output_asm_insn ("crxor 6,6,6", operands);
10816   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10817     output_asm_insn ("creqv 6,6,6", operands);
10819   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z0@local" : "b %z0";
10821   [(set_attr "type" "branch")
10822    (set_attr "length" "4,8")])
10824 (define_insn "*sibcall_local64"
10825   [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
10826          (match_operand 1))
10827    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10828    (simple_return)]
10829   "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
10831   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10832     output_asm_insn ("crxor 6,6,6", operands);
10834   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10835     output_asm_insn ("creqv 6,6,6", operands);
10837   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z0@local" : "b %z0";
10839   [(set_attr "type" "branch")
10840    (set_attr "length" "4,8")])
10842 (define_insn "*sibcall_value_local32"
10843   [(set (match_operand 0 "" "")
10844         (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
10845               (match_operand 2)))
10846    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10847    (simple_return)]
10848   "(INTVAL (operands[3]) & CALL_LONG) == 0"
10850   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10851     output_asm_insn ("crxor 6,6,6", operands);
10853   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10854     output_asm_insn ("creqv 6,6,6", operands);
10856   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z1@local" : "b %z1";
10858   [(set_attr "type" "branch")
10859    (set_attr "length" "4,8")])
10861 (define_insn "*sibcall_value_local64"
10862   [(set (match_operand 0 "" "")
10863         (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
10864               (match_operand 2)))
10865    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10866    (simple_return)]
10867   "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
10869   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10870     output_asm_insn ("crxor 6,6,6", operands);
10872   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10873     output_asm_insn ("creqv 6,6,6", operands);
10875   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z1@local" : "b %z1";
10877   [(set_attr "type" "branch")
10878    (set_attr "length" "4,8")])
10880 (define_insn "*sibcall_indirect_nonlocal_sysv<mode>"
10881   [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X"))
10882          (match_operand 1))
10883    (use (match_operand:SI 2 "immediate_operand" "n,n,n"))
10884    (simple_return)]
10885   "DEFAULT_ABI == ABI_V4
10886    || DEFAULT_ABI == ABI_DARWIN"
10888   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10889     output_asm_insn ("crxor 6,6,6", operands);
10891   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10892     output_asm_insn ("creqv 6,6,6", operands);
10894   return rs6000_indirect_sibcall_template (operands, 0);
10896   [(set_attr "type" "jmpreg")
10897    (set (attr "length")
10898         (cond [(and (and (match_test "!rs6000_speculate_indirect_jumps")
10899                          (match_test "which_alternative != 1"))
10900                     (match_test "(INTVAL (operands[2]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
10901                   (const_string "12")
10902                (ior (and (match_test "!rs6000_speculate_indirect_jumps")
10903                          (match_test "which_alternative != 1"))
10904                    (match_test "(INTVAL (operands[2]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
10905                   (const_string "8")]
10906               (const_string "4")))])
10908 (define_insn "*sibcall_nonlocal_sysv<mode>"
10909   [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
10910          (match_operand 1))
10911    (use (match_operand 2 "immediate_operand" "O,n"))
10912    (simple_return)]
10913   "(DEFAULT_ABI == ABI_DARWIN
10914     || DEFAULT_ABI == ABI_V4)
10915    && (INTVAL (operands[2]) & CALL_LONG) == 0"
10917   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10918     output_asm_insn ("crxor 6,6,6", operands);
10920   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10921     output_asm_insn ("creqv 6,6,6", operands);
10923   return rs6000_sibcall_template (operands, 0);
10925   [(set_attr "type" "branch")
10926    (set_attr "length" "4,8")])
10928 (define_insn "*sibcall_value_indirect_nonlocal_sysv<mode>"
10929   [(set (match_operand 0 "" "")
10930         (call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X"))
10931               (match_operand 2)))
10932    (use (match_operand:SI 3 "immediate_operand" "n,n,n"))
10933    (simple_return)]
10934   "DEFAULT_ABI == ABI_V4
10935    || DEFAULT_ABI == ABI_DARWIN"
10937   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10938     output_asm_insn ("crxor 6,6,6", operands);
10940   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10941     output_asm_insn ("creqv 6,6,6", operands);
10943   return rs6000_indirect_sibcall_template (operands, 1);
10945   [(set_attr "type" "jmpreg")
10946    (set (attr "length")
10947         (cond [(and (and (match_test "!rs6000_speculate_indirect_jumps")
10948                          (match_test "which_alternative != 1"))
10949                     (match_test "(INTVAL (operands[3]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
10950                   (const_string "12")
10951                (ior (and (match_test "!rs6000_speculate_indirect_jumps")
10952                          (match_test "which_alternative != 1"))
10953                    (match_test "(INTVAL (operands[3]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
10954                   (const_string "8")]
10955               (const_string "4")))])
10957 (define_insn "*sibcall_value_nonlocal_sysv<mode>"
10958   [(set (match_operand 0 "" "")
10959         (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
10960               (match_operand 2)))
10961    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10962    (simple_return)]
10963   "(DEFAULT_ABI == ABI_DARWIN
10964     || DEFAULT_ABI == ABI_V4)
10965    && (INTVAL (operands[3]) & CALL_LONG) == 0"
10967   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10968     output_asm_insn ("crxor 6,6,6", operands);
10970   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10971     output_asm_insn ("creqv 6,6,6", operands);
10973   return rs6000_sibcall_template (operands, 1);
10975   [(set_attr "type" "branch")
10976    (set_attr "length" "4,8")])
10978 ;; AIX ABI sibling call patterns.
10980 (define_insn "*sibcall_aix<mode>"
10981   [(call (mem:SI (match_operand:P 0 "call_operand" "s,c"))
10982          (match_operand 1))
10983    (simple_return)]
10984   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10986   if (which_alternative == 0)
10987     return rs6000_sibcall_template (operands, 0);
10988   else
10989     return "b%T0";
10991   [(set_attr "type" "branch")])
10993 (define_insn "*sibcall_value_aix<mode>"
10994   [(set (match_operand 0 "" "")
10995         (call (mem:SI (match_operand:P 1 "call_operand" "s,c"))
10996               (match_operand 2)))
10997    (simple_return)]
10998   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11000   if (which_alternative == 0)
11001     return rs6000_sibcall_template (operands, 1);
11002   else
11003     return "b%T1";
11005   [(set_attr "type" "branch")])
11007 (define_expand "sibcall_epilogue"
11008   [(use (const_int 0))]
11009   ""
11011   if (!TARGET_SCHED_PROLOG)
11012     emit_insn (gen_blockage ());
11013   rs6000_emit_epilogue (TRUE);
11014   DONE;
11017 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11018 ;; all of memory.  This blocks insns from being moved across this point.
11020 (define_insn "blockage"
11021   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCK)]
11022   ""
11023   ""
11024   [(set_attr "length" "0")])
11026 (define_expand "probe_stack_address"
11027   [(use (match_operand 0 "address_operand"))]
11028   ""
11030   operands[0] = gen_rtx_MEM (Pmode, operands[0]);
11031   MEM_VOLATILE_P (operands[0]) = 1;
11033   if (TARGET_64BIT)
11034     emit_insn (gen_probe_stack_di (operands[0]));
11035   else
11036     emit_insn (gen_probe_stack_si (operands[0]));
11037   DONE;
11040 (define_insn "probe_stack_<mode>"
11041   [(set (match_operand:P 0 "memory_operand" "=m")
11042         (unspec:P [(const_int 0)] UNSPEC_PROBE_STACK))]
11043   ""
11045   operands[1] = gen_rtx_REG (Pmode, 0);
11046   return "st<wd>%U0%X0 %1,%0";
11048   [(set_attr "type" "store")
11049    (set (attr "update")
11050         (if_then_else (match_operand 0 "update_address_mem")
11051                       (const_string "yes")
11052                       (const_string "no")))
11053    (set (attr "indexed")
11054         (if_then_else (match_operand 0 "indexed_address_mem")
11055                       (const_string "yes")
11056                       (const_string "no")))])
11058 (define_insn "probe_stack_range<P:mode>"
11059   [(set (match_operand:P 0 "register_operand" "=&r")
11060         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
11061                             (match_operand:P 2 "register_operand" "r")
11062                             (match_operand:P 3 "register_operand" "r")]
11063                            UNSPECV_PROBE_STACK_RANGE))]
11064   ""
11065   "* return output_probe_stack_range (operands[0], operands[2], operands[3]);"
11066   [(set_attr "type" "three")])
11068 ;; Compare insns are next.  Note that the RS/6000 has two types of compares,
11069 ;; signed & unsigned, and one type of branch.
11071 ;; Start with the DEFINE_EXPANDs to generate the rtl for compares, scc
11072 ;; insns, and branches.
11074 (define_expand "cbranch<mode>4"
11075   [(use (match_operator 0 "comparison_operator"
11076          [(match_operand:GPR 1 "gpc_reg_operand")
11077           (match_operand:GPR 2 "reg_or_short_operand")]))
11078    (use (match_operand 3))]
11079   ""
11081   /* Take care of the possibility that operands[2] might be negative but
11082      this might be a logical operation.  That insn doesn't exist.  */
11083   if (GET_CODE (operands[2]) == CONST_INT
11084       && INTVAL (operands[2]) < 0)
11085     {
11086       operands[2] = force_reg (<MODE>mode, operands[2]);
11087       operands[0] = gen_rtx_fmt_ee (GET_CODE (operands[0]),
11088                                     GET_MODE (operands[0]),
11089                                     operands[1], operands[2]);
11090    }
11092   rs6000_emit_cbranch (<MODE>mode, operands);
11093   DONE;
11096 (define_expand "cbranch<mode>4"
11097   [(use (match_operator 0 "comparison_operator"
11098          [(match_operand:FP 1 "gpc_reg_operand")
11099           (match_operand:FP 2 "gpc_reg_operand")]))
11100    (use (match_operand 3))]
11101   ""
11103   rs6000_emit_cbranch (<MODE>mode, operands);
11104   DONE;
11107 (define_expand "cstore<mode>4_signed"
11108   [(use (match_operator 1 "signed_comparison_operator"
11109          [(match_operand:P 2 "gpc_reg_operand")
11110           (match_operand:P 3 "gpc_reg_operand")]))
11111    (clobber (match_operand:P 0 "gpc_reg_operand"))]
11112   ""
11114   enum rtx_code cond_code = GET_CODE (operands[1]);
11116   rtx op0 = operands[0];
11117   rtx op1 = operands[2];
11118   rtx op2 = operands[3];
11120   if (cond_code == GE || cond_code == LT)
11121     {
11122       cond_code = swap_condition (cond_code);
11123       std::swap (op1, op2);
11124     }
11126   rtx tmp1 = gen_reg_rtx (<MODE>mode);
11127   rtx tmp2 = gen_reg_rtx (<MODE>mode);
11128   rtx tmp3 = gen_reg_rtx (<MODE>mode);
11130   int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11131   emit_insn (gen_lshr<mode>3 (tmp1, op1, GEN_INT (sh)));
11132   emit_insn (gen_ashr<mode>3 (tmp2, op2, GEN_INT (sh)));
11134   emit_insn (gen_subf<mode>3_carry (tmp3, op1, op2));
11136   if (cond_code == LE)
11137     emit_insn (gen_add<mode>3_carry_in (op0, tmp1, tmp2));
11138   else
11139     {
11140       rtx tmp4 = gen_reg_rtx (<MODE>mode);
11141       emit_insn (gen_add<mode>3_carry_in (tmp4, tmp1, tmp2));
11142       emit_insn (gen_xor<mode>3 (op0, tmp4, const1_rtx));
11143     }
11145   DONE;
11148 (define_expand "cstore<mode>4_unsigned"
11149   [(use (match_operator 1 "unsigned_comparison_operator"
11150          [(match_operand:P 2 "gpc_reg_operand")
11151           (match_operand:P 3 "reg_or_short_operand")]))
11152    (clobber (match_operand:P 0 "gpc_reg_operand"))]
11153   ""
11155   enum rtx_code cond_code = GET_CODE (operands[1]);
11157   rtx op0 = operands[0];
11158   rtx op1 = operands[2];
11159   rtx op2 = operands[3];
11161   if (cond_code == GEU || cond_code == LTU)
11162     {
11163       cond_code = swap_condition (cond_code);
11164       std::swap (op1, op2);
11165     }
11167   if (!gpc_reg_operand (op1, <MODE>mode))
11168     op1 = force_reg (<MODE>mode, op1);
11169   if (!reg_or_short_operand (op2, <MODE>mode))
11170     op2 = force_reg (<MODE>mode, op2);
11172   rtx tmp = gen_reg_rtx (<MODE>mode);
11173   rtx tmp2 = gen_reg_rtx (<MODE>mode);
11175   emit_insn (gen_subf<mode>3_carry (tmp, op1, op2));
11176   emit_insn (gen_subf<mode>3_carry_in_xx (tmp2));
11178   if (cond_code == LEU)
11179     emit_insn (gen_add<mode>3 (op0, tmp2, const1_rtx));
11180   else
11181     emit_insn (gen_neg<mode>2 (op0, tmp2));
11183   DONE;
11186 (define_expand "cstore_si_as_di"
11187   [(use (match_operator 1 "unsigned_comparison_operator"
11188          [(match_operand:SI 2 "gpc_reg_operand")
11189           (match_operand:SI 3 "reg_or_short_operand")]))
11190    (clobber (match_operand:SI 0 "gpc_reg_operand"))]
11191   ""
11193   int uns_flag = unsigned_comparison_operator (operands[1], VOIDmode) ? 1 : 0;
11194   enum rtx_code cond_code = signed_condition (GET_CODE (operands[1]));
11196   operands[2] = force_reg (SImode, operands[2]);
11197   operands[3] = force_reg (SImode, operands[3]);
11198   rtx op1 = gen_reg_rtx (DImode);
11199   rtx op2 = gen_reg_rtx (DImode);
11200   convert_move (op1, operands[2], uns_flag);
11201   convert_move (op2, operands[3], uns_flag);
11203   if (cond_code == GT || cond_code == LE)
11204     {
11205       cond_code = swap_condition (cond_code);
11206       std::swap (op1, op2);
11207     }
11209   rtx tmp = gen_reg_rtx (DImode);
11210   rtx tmp2 = gen_reg_rtx (DImode);
11211   emit_insn (gen_subdi3 (tmp, op1, op2));
11212   emit_insn (gen_lshrdi3 (tmp2, tmp, GEN_INT (63)));
11214   rtx tmp3;
11215   switch (cond_code)
11216     {
11217     default:
11218       gcc_unreachable ();
11219     case LT:
11220       tmp3 = tmp2;
11221       break;
11222     case GE:
11223       tmp3 = gen_reg_rtx (DImode);
11224       emit_insn (gen_xordi3 (tmp3, tmp2, const1_rtx));
11225       break;
11226     }
11228   convert_move (operands[0], tmp3, 1);
11230   DONE;
11233 (define_expand "cstore<mode>4_signed_imm"
11234   [(use (match_operator 1 "signed_comparison_operator"
11235          [(match_operand:GPR 2 "gpc_reg_operand")
11236           (match_operand:GPR 3 "immediate_operand")]))
11237    (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11238   ""
11240   bool invert = false;
11242   enum rtx_code cond_code = GET_CODE (operands[1]);
11244   rtx op0 = operands[0];
11245   rtx op1 = operands[2];
11246   HOST_WIDE_INT val = INTVAL (operands[3]);
11248   if (cond_code == GE || cond_code == GT)
11249     {
11250       cond_code = reverse_condition (cond_code);
11251       invert = true;
11252     }
11254   if (cond_code == LE)
11255     val++;
11257   rtx tmp = gen_reg_rtx (<MODE>mode);
11258   emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
11259   rtx x = gen_reg_rtx (<MODE>mode);
11260   if (val < 0)
11261     emit_insn (gen_and<mode>3 (x, op1, tmp));
11262   else
11263     emit_insn (gen_ior<mode>3 (x, op1, tmp));
11265   if (invert)
11266     {
11267       rtx tmp = gen_reg_rtx (<MODE>mode);
11268       emit_insn (gen_one_cmpl<mode>2 (tmp, x));
11269       x = tmp;
11270     }
11272   int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11273   emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
11275   DONE;
11278 (define_expand "cstore<mode>4_unsigned_imm"
11279   [(use (match_operator 1 "unsigned_comparison_operator"
11280          [(match_operand:GPR 2 "gpc_reg_operand")
11281           (match_operand:GPR 3 "immediate_operand")]))
11282    (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11283   ""
11285   bool invert = false;
11287   enum rtx_code cond_code = GET_CODE (operands[1]);
11289   rtx op0 = operands[0];
11290   rtx op1 = operands[2];
11291   HOST_WIDE_INT val = INTVAL (operands[3]);
11293   if (cond_code == GEU || cond_code == GTU)
11294     {
11295       cond_code = reverse_condition (cond_code);
11296       invert = true;
11297     }
11299   if (cond_code == LEU)
11300     val++;
11302   rtx tmp = gen_reg_rtx (<MODE>mode);
11303   rtx tmp2 = gen_reg_rtx (<MODE>mode);
11304   emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
11305   emit_insn (gen_one_cmpl<mode>2 (tmp2, op1));
11306   rtx x = gen_reg_rtx (<MODE>mode);
11307   if (val < 0)
11308     emit_insn (gen_ior<mode>3 (x, tmp, tmp2));
11309   else
11310     emit_insn (gen_and<mode>3 (x, tmp, tmp2));
11312   if (invert)
11313     {
11314       rtx tmp = gen_reg_rtx (<MODE>mode);
11315       emit_insn (gen_one_cmpl<mode>2 (tmp, x));
11316       x = tmp;
11317     }
11319   int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11320   emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
11322   DONE;
11325 (define_expand "cstore<mode>4"
11326   [(use (match_operator 1 "comparison_operator"
11327          [(match_operand:GPR 2 "gpc_reg_operand")
11328           (match_operand:GPR 3 "reg_or_short_operand")]))
11329    (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11330   ""
11332   /* Expanding EQ and NE directly to some machine instructions does not help
11333      but does hurt combine.  So don't.  */
11334   if (GET_CODE (operands[1]) == EQ)
11335     emit_insn (gen_eq<mode>3 (operands[0], operands[2], operands[3]));
11336   else if (<MODE>mode == Pmode
11337            && GET_CODE (operands[1]) == NE)
11338     emit_insn (gen_ne<mode>3 (operands[0], operands[2], operands[3]));
11339   else if (GET_CODE (operands[1]) == NE)
11340     {
11341       rtx tmp = gen_reg_rtx (<MODE>mode);
11342       emit_insn (gen_eq<mode>3 (tmp, operands[2], operands[3]));
11343       emit_insn (gen_xor<mode>3 (operands[0], tmp, const1_rtx));
11344     }
11346   /* If ISEL is fast, expand to it.  */
11347   else if (TARGET_ISEL)
11348     rs6000_emit_int_cmove (operands[0], operands[1], const1_rtx, const0_rtx);
11350   /* Expanding the unsigned comparisons helps a lot: all the neg_ltu
11351      etc. combinations magically work out just right.  */
11352   else if (<MODE>mode == Pmode
11353            && unsigned_comparison_operator (operands[1], VOIDmode))
11354     emit_insn (gen_cstore<mode>4_unsigned (operands[0], operands[1],
11355                                            operands[2], operands[3]));
11357   /* For comparisons smaller than Pmode we can cheaply do things in Pmode.  */
11358   else if (<MODE>mode == SImode && Pmode == DImode)
11359     emit_insn (gen_cstore_si_as_di (operands[0], operands[1],
11360                                     operands[2], operands[3]));
11362   /* For signed comparisons against a constant, we can do some simple
11363      bit-twiddling.  */
11364   else if (signed_comparison_operator (operands[1], VOIDmode)
11365            && CONST_INT_P (operands[3]))
11366     emit_insn (gen_cstore<mode>4_signed_imm (operands[0], operands[1],
11367                                              operands[2], operands[3]));
11369   /* And similarly for unsigned comparisons.  */
11370   else if (unsigned_comparison_operator (operands[1], VOIDmode)
11371            && CONST_INT_P (operands[3]))
11372     emit_insn (gen_cstore<mode>4_unsigned_imm (operands[0], operands[1],
11373                                                operands[2], operands[3]));
11375   /* We also do not want to use mfcr for signed comparisons.  */
11376   else if (<MODE>mode == Pmode
11377            && signed_comparison_operator (operands[1], VOIDmode))
11378     emit_insn (gen_cstore<mode>4_signed (operands[0], operands[1],
11379                                          operands[2], operands[3]));
11381   /* Everything else, use the mfcr brute force.  */
11382   else
11383     rs6000_emit_sCOND (<MODE>mode, operands);
11385   DONE;
11388 (define_expand "cstore<mode>4"
11389   [(use (match_operator 1 "comparison_operator"
11390          [(match_operand:FP 2 "gpc_reg_operand")
11391           (match_operand:FP 3 "gpc_reg_operand")]))
11392    (clobber (match_operand:SI 0 "gpc_reg_operand"))]
11393   ""
11395   rs6000_emit_sCOND (<MODE>mode, operands);
11396   DONE;
11400 (define_expand "stack_protect_set"
11401   [(match_operand 0 "memory_operand")
11402    (match_operand 1 "memory_operand")]
11403   ""
11405   if (rs6000_stack_protector_guard == SSP_TLS)
11406     {
11407       rtx reg = gen_rtx_REG (Pmode, rs6000_stack_protector_guard_reg);
11408       rtx offset = GEN_INT (rs6000_stack_protector_guard_offset);
11409       rtx addr = gen_rtx_PLUS (Pmode, reg, offset);
11410       operands[1] = gen_rtx_MEM (Pmode, addr);
11411     }
11413   if (TARGET_64BIT)
11414     emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
11415   else
11416     emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
11418   DONE;
11421 (define_insn "stack_protect_setsi"
11422   [(set (match_operand:SI 0 "memory_operand" "=m")
11423         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
11424    (set (match_scratch:SI 2 "=&r") (const_int 0))]
11425   "TARGET_32BIT"
11426   "lwz%U1%X1 %2,%1\;stw%U0%X0 %2,%0\;li %2,0"
11427   [(set_attr "type" "three")
11428    (set_attr "length" "12")])
11430 (define_insn "stack_protect_setdi"
11431   [(set (match_operand:DI 0 "memory_operand" "=Y")
11432         (unspec:DI [(match_operand:DI 1 "memory_operand" "Y")] UNSPEC_SP_SET))
11433    (set (match_scratch:DI 2 "=&r") (const_int 0))]
11434   "TARGET_64BIT"
11435   "ld%U1%X1 %2,%1\;std%U0%X0 %2,%0\;li %2,0"
11436   [(set_attr "type" "three")
11437    (set_attr "length" "12")])
11439 (define_expand "stack_protect_test"
11440   [(match_operand 0 "memory_operand")
11441    (match_operand 1 "memory_operand")
11442    (match_operand 2 "")]
11443   ""
11445   rtx guard = operands[1];
11447   if (rs6000_stack_protector_guard == SSP_TLS)
11448     {
11449       rtx reg = gen_rtx_REG (Pmode, rs6000_stack_protector_guard_reg);
11450       rtx offset = GEN_INT (rs6000_stack_protector_guard_offset);
11451       rtx addr = gen_rtx_PLUS (Pmode, reg, offset);
11452       guard = gen_rtx_MEM (Pmode, addr);
11453     }
11455   operands[1] = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, guard), UNSPEC_SP_TEST);
11456   rtx test = gen_rtx_EQ (VOIDmode, operands[0], operands[1]);
11457   rtx jump = gen_cbranchsi4 (test, operands[0], operands[1], operands[2]);
11458   emit_jump_insn (jump);
11460   DONE;
11463 (define_insn "stack_protect_testsi"
11464   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
11465         (unspec:CCEQ [(match_operand:SI 1 "memory_operand" "m,m")
11466                       (match_operand:SI 2 "memory_operand" "m,m")]
11467                      UNSPEC_SP_TEST))
11468    (set (match_scratch:SI 4 "=r,r") (const_int 0))
11469    (clobber (match_scratch:SI 3 "=&r,&r"))]
11470   "TARGET_32BIT"
11471   "@
11472    lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0
11473    lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;cmplw %0,%3,%4\;li %3,0\;li %4,0"
11474   [(set_attr "length" "16,20")])
11476 (define_insn "stack_protect_testdi"
11477   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
11478         (unspec:CCEQ [(match_operand:DI 1 "memory_operand" "Y,Y")
11479                       (match_operand:DI 2 "memory_operand" "Y,Y")]
11480                      UNSPEC_SP_TEST))
11481    (set (match_scratch:DI 4 "=r,r") (const_int 0))
11482    (clobber (match_scratch:DI 3 "=&r,&r"))]
11483   "TARGET_64BIT"
11484   "@
11485    ld%U1%X1 %3,%1\;ld%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0
11486    ld%U1%X1 %3,%1\;ld%U2%X2 %4,%2\;cmpld %0,%3,%4\;li %3,0\;li %4,0"
11487   [(set_attr "length" "16,20")])
11490 ;; Here are the actual compare insns.
11491 (define_insn "*cmp<mode>_signed"
11492   [(set (match_operand:CC 0 "cc_reg_operand" "=y")
11493         (compare:CC (match_operand:GPR 1 "gpc_reg_operand" "r")
11494                     (match_operand:GPR 2 "reg_or_short_operand" "rI")))]
11495   ""
11496   "cmp<wd>%I2 %0,%1,%2"
11497   [(set_attr "type" "cmp")])
11499 (define_insn "*cmp<mode>_unsigned"
11500   [(set (match_operand:CCUNS 0 "cc_reg_operand" "=y")
11501         (compare:CCUNS (match_operand:GPR 1 "gpc_reg_operand" "r")
11502                        (match_operand:GPR 2 "reg_or_u_short_operand" "rK")))]
11503   ""
11504   "cmpl<wd>%I2 %0,%1,%2"
11505   [(set_attr "type" "cmp")])
11507 ;; If we are comparing a register for equality with a large constant,
11508 ;; we can do this with an XOR followed by a compare.  But this is profitable
11509 ;; only if the large constant is only used for the comparison (and in this
11510 ;; case we already have a register to reuse as scratch).
11512 ;; For 64-bit registers, we could only do so if the constant's bit 15 is clear:
11513 ;; otherwise we'd need to XOR with FFFFFFFF????0000 which is not available.
11515 (define_peephole2
11516   [(set (match_operand:SI 0 "register_operand")
11517         (match_operand:SI 1 "logical_const_operand"))
11518    (set (match_dup 0) (match_operator:SI 3 "boolean_or_operator"
11519                        [(match_dup 0)
11520                         (match_operand:SI 2 "logical_const_operand")]))
11521    (set (match_operand:CC 4 "cc_reg_operand")
11522         (compare:CC (match_operand:SI 5 "gpc_reg_operand")
11523                     (match_dup 0)))
11524    (set (pc)
11525         (if_then_else (match_operator 6 "equality_operator"
11526                        [(match_dup 4) (const_int 0)])
11527                       (match_operand 7 "")
11528                       (match_operand 8 "")))]
11529   "peep2_reg_dead_p (3, operands[0])
11530    && peep2_reg_dead_p (4, operands[4])
11531    && REGNO (operands[0]) != REGNO (operands[5])"
11532  [(set (match_dup 0) (xor:SI (match_dup 5) (match_dup 9)))
11533   (set (match_dup 4) (compare:CC (match_dup 0) (match_dup 10)))
11534   (set (pc) (if_then_else (match_dup 6) (match_dup 7) (match_dup 8)))]
11537   /* Get the constant we are comparing against, and see what it looks like
11538      when sign-extended from 16 to 32 bits.  Then see what constant we could
11539      XOR with SEXTC to get the sign-extended value.  */
11540   rtx cnst = simplify_const_binary_operation (GET_CODE (operands[3]),
11541                                               SImode,
11542                                               operands[1], operands[2]);
11543   HOST_WIDE_INT c = INTVAL (cnst);
11544   HOST_WIDE_INT sextc = ((c & 0xffff) ^ 0x8000) - 0x8000;
11545   HOST_WIDE_INT xorv = c ^ sextc;
11547   operands[9] = GEN_INT (xorv);
11548   operands[10] = GEN_INT (sextc);
11551 ;; Only need to compare second words if first words equal
11552 (define_insn "*cmp<mode>_internal1"
11553   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
11554         (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
11555                       (match_operand:IBM128 2 "gpc_reg_operand" "d")))]
11556   "!TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode)
11557    && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
11558   "fcmpu %0,%1,%2\;bne %0,$+8\;fcmpu %0,%L1,%L2"
11559   [(set_attr "type" "fpcompare")
11560    (set_attr "length" "12")])
11562 (define_insn_and_split "*cmp<mode>_internal2"
11563   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
11564         (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
11565                       (match_operand:IBM128 2 "gpc_reg_operand" "d")))
11566     (clobber (match_scratch:DF 3 "=d"))
11567     (clobber (match_scratch:DF 4 "=d"))
11568     (clobber (match_scratch:DF 5 "=d"))
11569     (clobber (match_scratch:DF 6 "=d"))
11570     (clobber (match_scratch:DF 7 "=d"))
11571     (clobber (match_scratch:DF 8 "=d"))
11572     (clobber (match_scratch:DF 9 "=d"))
11573     (clobber (match_scratch:DF 10 "=d"))
11574     (clobber (match_scratch:GPR 11 "=b"))]
11575   "TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode)
11576    && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
11577   "#"
11578   "&& reload_completed"
11579   [(set (match_dup 3) (match_dup 14))
11580    (set (match_dup 4) (match_dup 15))
11581    (set (match_dup 9) (abs:DF (match_dup 5)))
11582    (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 3)))
11583    (set (pc) (if_then_else (ne (match_dup 0) (const_int 0))
11584                            (label_ref (match_dup 12))
11585                            (pc)))
11586    (set (match_dup 0) (compare:CCFP (match_dup 5) (match_dup 7)))
11587    (set (pc) (label_ref (match_dup 13)))
11588    (match_dup 12)
11589    (set (match_dup 10) (minus:DF (match_dup 5) (match_dup 7)))
11590    (set (match_dup 9) (minus:DF (match_dup 6) (match_dup 8)))
11591    (set (match_dup 9) (plus:DF (match_dup 10) (match_dup 9)))
11592    (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 4)))
11593    (match_dup 13)]
11595   REAL_VALUE_TYPE rv;
11596   const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
11597   const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
11599   operands[5] = simplify_gen_subreg (DFmode, operands[1], <MODE>mode, hi_word);
11600   operands[6] = simplify_gen_subreg (DFmode, operands[1], <MODE>mode, lo_word);
11601   operands[7] = simplify_gen_subreg (DFmode, operands[2], <MODE>mode, hi_word);
11602   operands[8] = simplify_gen_subreg (DFmode, operands[2], <MODE>mode, lo_word);
11603   operands[12] = gen_label_rtx ();
11604   operands[13] = gen_label_rtx ();
11605   real_inf (&rv);
11606   operands[14] = force_const_mem (DFmode,
11607                                   const_double_from_real_value (rv, DFmode));
11608   operands[15] = force_const_mem (DFmode,
11609                                   const_double_from_real_value (dconst0,
11610                                                                 DFmode));
11611   if (TARGET_TOC)
11612     {
11613       rtx tocref;
11614       tocref = create_TOC_reference (XEXP (operands[14], 0), operands[11]);
11615       operands[14] = gen_const_mem (DFmode, tocref);
11616       tocref = create_TOC_reference (XEXP (operands[15], 0), operands[11]);
11617       operands[15] = gen_const_mem (DFmode, tocref);
11618       set_mem_alias_set (operands[14], get_TOC_alias_set ());
11619       set_mem_alias_set (operands[15], get_TOC_alias_set ());
11620     }
11623 ;; Now we have the scc insns.  We can do some combinations because of the
11624 ;; way the machine works.
11626 ;; Note that this is probably faster if we can put an insn between the
11627 ;; mfcr and rlinm, but this is tricky.  Let's leave it for now.  In most
11628 ;; cases the insns below which don't use an intermediate CR field will
11629 ;; be used instead.
11630 (define_insn ""
11631   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
11632         (match_operator:GPR 1 "scc_comparison_operator"
11633                             [(match_operand 2 "cc_reg_operand" "y")
11634                              (const_int 0)]))]
11635   ""
11636   "mfcr %0%Q2\;rlwinm %0,%0,%J1,1"
11637   [(set (attr "type")
11638      (cond [(match_test "TARGET_MFCRF")
11639                 (const_string "mfcrf")
11640            ]
11641         (const_string "mfcr")))
11642    (set_attr "length" "8")])
11644 (define_insn_and_split ""
11645   [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
11646         (compare:CC (match_operator:SI 1 "scc_comparison_operator"
11647                                        [(match_operand 2 "cc_reg_operand" "y,y")
11648                                         (const_int 0)])
11649                     (const_int 0)))
11650    (set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
11651         (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
11652   "TARGET_32BIT"
11653   "@
11654    mfcr %3%Q2\;rlwinm. %3,%3,%J1,1
11655    #"
11656   "&& reload_completed"
11657   [(set (match_dup 3)
11658         (match_op_dup 1 [(match_dup 2) (const_int 0)]))
11659    (set (match_dup 0)
11660         (compare:CC (match_dup 3)
11661                     (const_int 0)))]
11662   ""
11663   [(set_attr "type" "shift")
11664    (set_attr "dot" "yes")
11665    (set_attr "length" "8,16")])
11667 (define_insn ""
11668   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11669         (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
11670                                       [(match_operand 2 "cc_reg_operand" "y")
11671                                        (const_int 0)])
11672                    (match_operand:SI 3 "const_int_operand" "n")))]
11673   ""
11675   int is_bit = ccr_bit (operands[1], 1);
11676   int put_bit = 31 - (INTVAL (operands[3]) & 31);
11677   int count;
11679   if (is_bit >= put_bit)
11680     count = is_bit - put_bit;
11681   else
11682     count = 32 - (put_bit - is_bit);
11684   operands[4] = GEN_INT (count);
11685   operands[5] = GEN_INT (put_bit);
11687   return "mfcr %0%Q2\;rlwinm %0,%0,%4,%5,%5";
11689   [(set (attr "type")
11690      (cond [(match_test "TARGET_MFCRF")
11691                 (const_string "mfcrf")
11692            ]
11693         (const_string "mfcr")))
11694    (set_attr "length" "8")])
11696 (define_insn ""
11697   [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
11698         (compare:CC
11699          (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
11700                                        [(match_operand 2 "cc_reg_operand" "y,y")
11701                                         (const_int 0)])
11702                     (match_operand:SI 3 "const_int_operand" "n,n"))
11703          (const_int 0)))
11704    (set (match_operand:SI 4 "gpc_reg_operand" "=r,r")
11705         (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
11706                    (match_dup 3)))]
11707   ""
11709   int is_bit = ccr_bit (operands[1], 1);
11710   int put_bit = 31 - (INTVAL (operands[3]) & 31);
11711   int count;
11713   /* Force split for non-cc0 compare.  */
11714   if (which_alternative == 1)
11715      return "#";
11717   if (is_bit >= put_bit)
11718     count = is_bit - put_bit;
11719   else
11720     count = 32 - (put_bit - is_bit);
11722   operands[5] = GEN_INT (count);
11723   operands[6] = GEN_INT (put_bit);
11725   return "mfcr %4%Q2\;rlwinm. %4,%4,%5,%6,%6";
11727   [(set_attr "type" "shift")
11728    (set_attr "dot" "yes")
11729    (set_attr "length" "8,16")])
11731 (define_split
11732   [(set (match_operand:CC 0 "cc_reg_not_cr0_operand")
11733         (compare:CC
11734          (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
11735                                        [(match_operand 2 "cc_reg_operand")
11736                                         (const_int 0)])
11737                     (match_operand:SI 3 "const_int_operand"))
11738          (const_int 0)))
11739    (set (match_operand:SI 4 "gpc_reg_operand")
11740         (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
11741                    (match_dup 3)))]
11742   "reload_completed"
11743   [(set (match_dup 4)
11744         (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
11745                    (match_dup 3)))
11746    (set (match_dup 0)
11747         (compare:CC (match_dup 4)
11748                     (const_int 0)))]
11749   "")
11752 (define_code_iterator cmp [eq ne lt ltu gt gtu le leu ge geu])
11753 (define_code_attr UNS [(eq "CC")
11754                        (ne "CC")
11755                        (lt "CC") (ltu "CCUNS")
11756                        (gt "CC") (gtu "CCUNS")
11757                        (le "CC") (leu "CCUNS")
11758                        (ge "CC") (geu "CCUNS")])
11759 (define_code_attr UNSu_ [(eq "")
11760                          (ne "")
11761                          (lt "") (ltu "u_")
11762                          (gt "") (gtu "u_")
11763                          (le "") (leu "u_")
11764                          (ge "") (geu "u_")])
11765 (define_code_attr UNSIK [(eq "I")
11766                          (ne "I")
11767                          (lt "I") (ltu "K")
11768                          (gt "I") (gtu "K")
11769                          (le "I") (leu "K")
11770                          (ge "I") (geu "K")])
11772 (define_insn_and_split "<code><GPR:mode><GPR2:mode>2_isel"
11773   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
11774         (cmp:GPR (match_operand:GPR2 1 "gpc_reg_operand" "r")
11775                  (match_operand:GPR2 2 "reg_or_<cmp:UNSu_>short_operand" "r<cmp:UNSIK>")))
11776    (clobber (match_scratch:GPR 3 "=r"))
11777    (clobber (match_scratch:GPR 4 "=r"))
11778    (clobber (match_scratch:<UNS> 5 "=y"))]
11779   "TARGET_ISEL
11780    && !(<CODE> == EQ && operands[2] == const0_rtx)
11781    && !(<CODE> == NE && operands[2] == const0_rtx
11782         && <GPR:MODE>mode == Pmode && <GPR2:MODE>mode == Pmode)"
11783   "#"
11784   "&& 1"
11785   [(pc)]
11787   rtx_code code = <CODE>;
11788   if (CONST_INT_P (operands[2]) && code != EQ && code != NE)
11789     {
11790       HOST_WIDE_INT val = INTVAL (operands[2]);
11791       if (code == LT && val != -0x8000)
11792         {
11793           code = LE;
11794           val--;
11795         }
11796       if (code == GT && val != 0x7fff)
11797         {
11798           code = GE;
11799           val++;
11800         }
11801       if (code == LTU && val != 0)
11802         {
11803           code = LEU;
11804           val--;
11805         }
11806       if (code == GTU && val != 0xffff)
11807         {
11808           code = GEU;
11809           val++;
11810         }
11811       operands[2] = GEN_INT (val);
11812     }
11814   if (code == NE || code == LE || code == GE || code == LEU || code == GEU)
11815     operands[3] = const0_rtx;
11816   else
11817     {
11818       if (GET_CODE (operands[3]) == SCRATCH)
11819         operands[3] = gen_reg_rtx (<GPR:MODE>mode);
11820       emit_move_insn (operands[3], const0_rtx);
11821     }
11823   if (GET_CODE (operands[4]) == SCRATCH)
11824     operands[4] = gen_reg_rtx (<GPR:MODE>mode);
11825   emit_move_insn (operands[4], const1_rtx);
11827   if (GET_CODE (operands[5]) == SCRATCH)
11828     operands[5] = gen_reg_rtx (<UNS>mode);
11830   rtx c1 = gen_rtx_COMPARE (<UNS>mode, operands[1], operands[2]);
11831   emit_insn (gen_rtx_SET (operands[5], c1));
11833   rtx c2 = gen_rtx_fmt_ee (code, <GPR:MODE>mode, operands[5], const0_rtx);
11834   rtx x = gen_rtx_IF_THEN_ELSE (<GPR:MODE>mode, c2, operands[4], operands[3]);
11835   emit_move_insn (operands[0], x);
11837   DONE;
11839   [(set (attr "cost")
11840         (if_then_else (match_test "(CONST_INT_P (operands[2]) && <CODE> != EQ)
11841                                    || <CODE> == NE
11842                                    || <CODE> == LE || <CODE> == GE
11843                                    || <CODE> == LEU || <CODE> == GEU")
11844                       (const_string "9")
11845                       (const_string "10")))])
11847 (define_mode_attr scc_eq_op2 [(SI "rKLI")
11848                               (DI "rKJI")])
11850 (define_expand "eq<mode>3"
11851   [(parallel [
11852      (set (match_operand:GPR 0 "gpc_reg_operand" "=r")
11853           (eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
11854                   (match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>")))
11855      (clobber (match_scratch:GPR 3 "=r"))
11856      (clobber (match_scratch:GPR 4 "=r"))])]
11857   ""
11859   if (TARGET_ISEL && operands[2] != const0_rtx)
11860     {
11861       emit_insn (gen_eq<mode><mode>2_isel (operands[0], operands[1],
11862                                            operands[2]));
11863       DONE;
11864     }
11867 (define_insn_and_split "*eq<mode>3"
11868   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
11869         (eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
11870                 (match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>")))
11871    (clobber (match_scratch:GPR 3 "=r"))
11872    (clobber (match_scratch:GPR 4 "=r"))]
11873   "!(TARGET_ISEL && operands[2] != const0_rtx)"
11874   "#"
11875   "&& 1"
11876   [(set (match_dup 4)
11877         (clz:GPR (match_dup 3)))
11878    (set (match_dup 0)
11879         (lshiftrt:GPR (match_dup 4)
11880                       (match_dup 5)))]
11882   operands[3] = rs6000_emit_eqne (<MODE>mode,
11883                                   operands[1], operands[2], operands[3]);
11885   if (GET_CODE (operands[4]) == SCRATCH)
11886     operands[4] = gen_reg_rtx (<MODE>mode);
11888   operands[5] = GEN_INT (exact_log2 (GET_MODE_BITSIZE (<MODE>mode)));
11890   [(set (attr "length")
11891         (if_then_else (match_test "operands[2] == const0_rtx")
11892                       (const_string "8")
11893                       (const_string "12")))])
11895 (define_expand "ne<mode>3"
11896   [(parallel [
11897      (set (match_operand:P 0 "gpc_reg_operand" "=r")
11898           (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
11899                 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")))
11900      (clobber (match_scratch:P 3 "=r"))
11901      (clobber (match_scratch:P 4 "=r"))
11902      (clobber (reg:P CA_REGNO))])]
11903   ""
11905   if (TARGET_ISEL && operands[2] != const0_rtx)
11906     {
11907       emit_insn (gen_ne<mode><mode>2_isel (operands[0], operands[1],
11908                                            operands[2]));
11909       DONE;
11910     }
11913 (define_insn_and_split "*ne<mode>3"
11914   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11915         (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
11916               (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")))
11917    (clobber (match_scratch:P 3 "=r"))
11918    (clobber (match_scratch:P 4 "=r"))
11919    (clobber (reg:P CA_REGNO))]
11920   "!(TARGET_ISEL && operands[2] != const0_rtx)"
11921   "#"
11922   "&& 1"
11923   [(parallel [(set (match_dup 4)
11924                    (plus:P (match_dup 3)
11925                            (const_int -1)))
11926               (set (reg:P CA_REGNO)
11927                    (ne:P (match_dup 3)
11928                          (const_int 0)))])
11929    (parallel [(set (match_dup 0)
11930                    (plus:P (plus:P (not:P (match_dup 4))
11931                                    (reg:P CA_REGNO))
11932                            (match_dup 3)))
11933               (clobber (reg:P CA_REGNO))])]
11935   operands[3] = rs6000_emit_eqne (<MODE>mode,
11936                                   operands[1], operands[2], operands[3]);
11938   if (GET_CODE (operands[4]) == SCRATCH)
11939     operands[4] = gen_reg_rtx (<MODE>mode);
11941   [(set (attr "length")
11942         (if_then_else (match_test "operands[2] == const0_rtx")
11943                       (const_string "8")
11944                       (const_string "12")))])
11946 (define_insn_and_split "*neg_eq_<mode>"
11947   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11948         (neg:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
11949                      (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
11950    (clobber (match_scratch:P 3 "=r"))
11951    (clobber (match_scratch:P 4 "=r"))
11952    (clobber (reg:P CA_REGNO))]
11953   ""
11954   "#"
11955   ""
11956   [(parallel [(set (match_dup 4)
11957                    (plus:P (match_dup 3)
11958                            (const_int -1)))
11959               (set (reg:P CA_REGNO)
11960                    (ne:P (match_dup 3)
11961                          (const_int 0)))])
11962    (parallel [(set (match_dup 0)
11963                    (plus:P (reg:P CA_REGNO)
11964                            (const_int -1)))
11965               (clobber (reg:P CA_REGNO))])]
11967   operands[3] = rs6000_emit_eqne (<MODE>mode,
11968                                   operands[1], operands[2], operands[3]);
11970   if (GET_CODE (operands[4]) == SCRATCH)
11971     operands[4] = gen_reg_rtx (<MODE>mode);
11973   [(set (attr "length")
11974         (if_then_else (match_test "operands[2] == const0_rtx")
11975                       (const_string "8")
11976                       (const_string "12")))])
11978 (define_insn_and_split "*neg_ne_<mode>"
11979   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11980         (neg:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
11981                      (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
11982    (clobber (match_scratch:P 3 "=r"))
11983    (clobber (match_scratch:P 4 "=r"))
11984    (clobber (reg:P CA_REGNO))]
11985   ""
11986   "#"
11987   ""
11988   [(parallel [(set (match_dup 4)
11989                    (neg:P (match_dup 3)))
11990               (set (reg:P CA_REGNO)
11991                    (eq:P (match_dup 3)
11992                          (const_int 0)))])
11993    (parallel [(set (match_dup 0)
11994                    (plus:P (reg:P CA_REGNO)
11995                            (const_int -1)))
11996               (clobber (reg:P CA_REGNO))])]
11998   operands[3] = rs6000_emit_eqne (<MODE>mode,
11999                                   operands[1], operands[2], operands[3]);
12001   if (GET_CODE (operands[4]) == SCRATCH)
12002     operands[4] = gen_reg_rtx (<MODE>mode);
12004   [(set (attr "length")
12005         (if_then_else (match_test "operands[2] == const0_rtx")
12006                       (const_string "8")
12007                       (const_string "12")))])
12009 (define_insn_and_split "*plus_eq_<mode>"
12010   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12011         (plus:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12012                       (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
12013                 (match_operand:P 3 "gpc_reg_operand" "r")))
12014    (clobber (match_scratch:P 4 "=r"))
12015    (clobber (match_scratch:P 5 "=r"))
12016    (clobber (reg:P CA_REGNO))]
12017   ""
12018   "#"
12019   ""
12020   [(parallel [(set (match_dup 5)
12021                    (neg:P (match_dup 4)))
12022               (set (reg:P CA_REGNO)
12023                    (eq:P (match_dup 4)
12024                          (const_int 0)))])
12025    (parallel [(set (match_dup 0)
12026                    (plus:P (match_dup 3)
12027                            (reg:P CA_REGNO)))
12028               (clobber (reg:P CA_REGNO))])]
12030   operands[4] = rs6000_emit_eqne (<MODE>mode,
12031                                   operands[1], operands[2], operands[4]);
12033   if (GET_CODE (operands[5]) == SCRATCH)
12034     operands[5] = gen_reg_rtx (<MODE>mode);
12036   [(set (attr "length")
12037         (if_then_else (match_test "operands[2] == const0_rtx")
12038                       (const_string "8")
12039                       (const_string "12")))])
12041 (define_insn_and_split "*plus_ne_<mode>"
12042   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12043         (plus:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12044                       (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
12045                 (match_operand:P 3 "gpc_reg_operand" "r")))
12046    (clobber (match_scratch:P 4 "=r"))
12047    (clobber (match_scratch:P 5 "=r"))
12048    (clobber (reg:P CA_REGNO))]
12049   ""
12050   "#"
12051   ""
12052   [(parallel [(set (match_dup 5)
12053                    (plus:P (match_dup 4)
12054                            (const_int -1)))
12055               (set (reg:P CA_REGNO)
12056                    (ne:P (match_dup 4)
12057                          (const_int 0)))])
12058    (parallel [(set (match_dup 0)
12059                    (plus:P (match_dup 3)
12060                            (reg:P CA_REGNO)))
12061               (clobber (reg:P CA_REGNO))])]
12063   operands[4] = rs6000_emit_eqne (<MODE>mode,
12064                                   operands[1], operands[2], operands[4]);
12066   if (GET_CODE (operands[5]) == SCRATCH)
12067     operands[5] = gen_reg_rtx (<MODE>mode);
12069   [(set (attr "length")
12070         (if_then_else (match_test "operands[2] == const0_rtx")
12071                       (const_string "8")
12072                       (const_string "12")))])
12074 (define_insn_and_split "*minus_eq_<mode>"
12075   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12076         (minus:P (match_operand:P 3 "gpc_reg_operand" "r")
12077                  (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12078                        (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12079    (clobber (match_scratch:P 4 "=r"))
12080    (clobber (match_scratch:P 5 "=r"))
12081    (clobber (reg:P CA_REGNO))]
12082   ""
12083   "#"
12084   ""
12085   [(parallel [(set (match_dup 5)
12086                    (plus:P (match_dup 4)
12087                            (const_int -1)))
12088               (set (reg:P CA_REGNO)
12089                    (ne:P (match_dup 4)
12090                          (const_int 0)))])
12091    (parallel [(set (match_dup 0)
12092                    (plus:P (plus:P (match_dup 3)
12093                                    (reg:P CA_REGNO))
12094                            (const_int -1)))
12095               (clobber (reg:P CA_REGNO))])]
12097   operands[4] = rs6000_emit_eqne (<MODE>mode,
12098                                   operands[1], operands[2], operands[4]);
12100   if (GET_CODE (operands[5]) == SCRATCH)
12101     operands[5] = gen_reg_rtx (<MODE>mode);
12103   [(set (attr "length")
12104         (if_then_else (match_test "operands[2] == const0_rtx")
12105                       (const_string "8")
12106                       (const_string "12")))])
12108 (define_insn_and_split "*minus_ne_<mode>"
12109   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12110         (minus:P (match_operand:P 3 "gpc_reg_operand" "r")
12111                  (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12112                        (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12113    (clobber (match_scratch:P 4 "=r"))
12114    (clobber (match_scratch:P 5 "=r"))
12115    (clobber (reg:P CA_REGNO))]
12116   ""
12117   "#"
12118   ""
12119   [(parallel [(set (match_dup 5)
12120                    (neg:P (match_dup 4)))
12121               (set (reg:P CA_REGNO)
12122                    (eq:P (match_dup 4)
12123                          (const_int 0)))])
12124    (parallel [(set (match_dup 0)
12125                    (plus:P (plus:P (match_dup 3)
12126                                    (reg:P CA_REGNO))
12127                            (const_int -1)))
12128               (clobber (reg:P CA_REGNO))])]
12130   operands[4] = rs6000_emit_eqne (<MODE>mode,
12131                                   operands[1], operands[2], operands[4]);
12133   if (GET_CODE (operands[5]) == SCRATCH)
12134     operands[5] = gen_reg_rtx (<MODE>mode);
12136   [(set (attr "length")
12137         (if_then_else (match_test "operands[2] == const0_rtx")
12138                       (const_string "8")
12139                       (const_string "12")))])
12141 (define_insn_and_split "*eqsi3_ext<mode>"
12142   [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
12143         (eq:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
12144                   (match_operand:SI 2 "scc_eq_operand" "rKLI")))
12145    (clobber (match_scratch:SI 3 "=r"))
12146    (clobber (match_scratch:SI 4 "=r"))]
12147   ""
12148   "#"
12149   ""
12150   [(set (match_dup 4)
12151         (clz:SI (match_dup 3)))
12152    (set (match_dup 0)
12153         (zero_extend:EXTSI
12154           (lshiftrt:SI (match_dup 4)
12155                        (const_int 5))))]
12157   operands[3] = rs6000_emit_eqne (SImode,
12158                                   operands[1], operands[2], operands[3]);
12160   if (GET_CODE (operands[4]) == SCRATCH)
12161     operands[4] = gen_reg_rtx (SImode);
12163   [(set (attr "length")
12164         (if_then_else (match_test "operands[2] == const0_rtx")
12165                       (const_string "8")
12166                       (const_string "12")))])
12168 (define_insn_and_split "*nesi3_ext<mode>"
12169   [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
12170         (ne:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
12171                   (match_operand:SI 2 "scc_eq_operand" "rKLI")))
12172    (clobber (match_scratch:SI 3 "=r"))
12173    (clobber (match_scratch:SI 4 "=r"))
12174    (clobber (match_scratch:EXTSI 5 "=r"))]
12175   "!TARGET_ISEL"
12176   "#"
12177   "&& 1"
12178   [(set (match_dup 4)
12179         (clz:SI (match_dup 3)))
12180    (set (match_dup 5)
12181         (zero_extend:EXTSI
12182           (lshiftrt:SI (match_dup 4)
12183                        (const_int 5))))
12184    (set (match_dup 0)
12185         (xor:EXTSI (match_dup 5)
12186                    (const_int 1)))]
12188   operands[3] = rs6000_emit_eqne (SImode,
12189                                   operands[1], operands[2], operands[3]);
12191   if (GET_CODE (operands[4]) == SCRATCH)
12192     operands[4] = gen_reg_rtx (SImode);
12193   if (GET_CODE (operands[5]) == SCRATCH)
12194     operands[5] = gen_reg_rtx (<MODE>mode);
12196   [(set (attr "length")
12197         (if_then_else (match_test "operands[2] == const0_rtx")
12198                       (const_string "12")
12199                       (const_string "16")))])
12201 ;; Conditional branches.
12202 ;; These either are a single bc insn, or a bc around a b.
12204 (define_insn "*cbranch"
12205   [(set (pc)
12206         (if_then_else (match_operator 1 "branch_comparison_operator"
12207                                       [(match_operand 2 "cc_reg_operand" "y")
12208                                        (const_int 0)])
12209                       (label_ref (match_operand 0))
12210                       (pc)))]
12211   ""
12213   return output_cbranch (operands[1], "%l0", 0, insn);
12215   [(set_attr "type" "branch")
12216    (set (attr "length")
12217         (if_then_else (and (ge (minus (match_dup 0) (pc))
12218                                (const_int -32768))
12219                            (lt (minus (match_dup 0) (pc))
12220                                (const_int 32764)))
12221                       (const_int 4)
12222                       (const_int 8)))])
12224 ;; Conditional return.
12225 (define_insn "*creturn"
12226   [(set (pc)
12227         (if_then_else (match_operator 0 "branch_comparison_operator"
12228                                       [(match_operand 1 "cc_reg_operand" "y")
12229                                        (const_int 0)])
12230                       (any_return)
12231                       (pc)))]
12232   "<return_pred>"
12234   return output_cbranch (operands[0], NULL, 0, insn);
12236   [(set_attr "type" "jmpreg")])
12238 ;; Logic on condition register values.
12240 ; This pattern matches things like
12241 ; (set (reg:CCEQ 68) (compare:CCEQ (ior:SI (gt:SI (reg:CCFP 68) (const_int 0))
12242 ;                                          (eq:SI (reg:CCFP 68) (const_int 0)))
12243 ;                                  (const_int 1)))
12244 ; which are generated by the branch logic.
12245 ; Prefer destructive operations where BT = BB (for crXX BT,BA,BB)
12247 (define_insn "cceq_ior_compare"
12248   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12249         (compare:CCEQ (match_operator:SI 1 "boolean_operator"
12250                         [(match_operator:SI 2
12251                                       "branch_positive_comparison_operator"
12252                                       [(match_operand 3
12253                                                       "cc_reg_operand" "y,y")
12254                                        (const_int 0)])
12255                          (match_operator:SI 4
12256                                       "branch_positive_comparison_operator"
12257                                       [(match_operand 5
12258                                                       "cc_reg_operand" "0,y")
12259                                        (const_int 0)])])
12260                       (const_int 1)))]
12261   ""
12262   "cr%q1 %E0,%j2,%j4"
12263   [(set_attr "type" "cr_logical")
12264    (set_attr "cr_logical_3op" "no,yes")])
12266 ; Why is the constant -1 here, but 1 in the previous pattern?
12267 ; Because ~1 has all but the low bit set.
12268 (define_insn "cceq_ior_compare_complement"
12269   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12270         (compare:CCEQ (match_operator:SI 1 "boolean_operator"
12271                         [(not:SI (match_operator:SI 2
12272                                       "branch_positive_comparison_operator"
12273                                       [(match_operand 3
12274                                                       "cc_reg_operand" "y,y")
12275                                        (const_int 0)]))
12276                          (match_operator:SI 4
12277                                 "branch_positive_comparison_operator"
12278                                 [(match_operand 5
12279                                                 "cc_reg_operand" "0,y")
12280                                  (const_int 0)])])
12281                       (const_int -1)))]
12282   ""
12283   "cr%q1 %E0,%j2,%j4"
12284   [(set_attr "type" "cr_logical")
12285    (set_attr "cr_logical_3op" "no,yes")])
12287 (define_insn "*cceq_rev_compare"
12288   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12289         (compare:CCEQ (match_operator:SI 1
12290                                       "branch_positive_comparison_operator"
12291                                       [(match_operand 2
12292                                                       "cc_reg_operand" "0,y")
12293                                        (const_int 0)])
12294                       (const_int 0)))]
12295   ""
12296   "crnot %E0,%j1"
12297   [(set_attr "type" "cr_logical")
12298    (set_attr "cr_logical_3op" "no,yes")])
12300 ;; If we are comparing the result of two comparisons, this can be done
12301 ;; using creqv or crxor.
12303 (define_insn_and_split ""
12304   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y")
12305         (compare:CCEQ (match_operator 1 "branch_comparison_operator"
12306                               [(match_operand 2 "cc_reg_operand" "y")
12307                                (const_int 0)])
12308                       (match_operator 3 "branch_comparison_operator"
12309                               [(match_operand 4 "cc_reg_operand" "y")
12310                                (const_int 0)])))]
12311   ""
12312   "#"
12313   ""
12314   [(set (match_dup 0) (compare:CCEQ (xor:SI (match_dup 1) (match_dup 3))
12315                                     (match_dup 5)))]
12317   int positive_1, positive_2;
12319   positive_1 = branch_positive_comparison_operator (operands[1],
12320                                                     GET_MODE (operands[1]));
12321   positive_2 = branch_positive_comparison_operator (operands[3],
12322                                                     GET_MODE (operands[3]));
12324   if (! positive_1)
12325     operands[1] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[2]),
12326                                                             GET_CODE (operands[1])),
12327                                   SImode,
12328                                   operands[2], const0_rtx);
12329   else if (GET_MODE (operands[1]) != SImode)
12330     operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), SImode,
12331                                   operands[2], const0_rtx);
12333   if (! positive_2)
12334     operands[3] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[4]),
12335                                                             GET_CODE (operands[3])),
12336                                   SImode,
12337                                   operands[4], const0_rtx);
12338   else if (GET_MODE (operands[3]) != SImode)
12339     operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SImode,
12340                                   operands[4], const0_rtx);
12342   if (positive_1 == positive_2)
12343     {
12344       operands[1] = gen_rtx_NOT (SImode, operands[1]);
12345       operands[5] = constm1_rtx;
12346     }
12347   else
12348     {
12349       operands[5] = const1_rtx;
12350     }
12353 ;; Unconditional branch and return.
12355 (define_insn "jump"
12356   [(set (pc)
12357         (label_ref (match_operand 0)))]
12358   ""
12359   "b %l0"
12360   [(set_attr "type" "branch")])
12362 (define_insn "<return_str>return"
12363   [(any_return)]
12364   "<return_pred>"
12365   "blr"
12366   [(set_attr "type" "jmpreg")])
12368 (define_expand "indirect_jump"
12369   [(set (pc) (match_operand 0 "register_operand"))]
12370  ""
12372   if (!rs6000_speculate_indirect_jumps) {
12373     rtx ccreg = gen_reg_rtx (CCmode);
12374     if (Pmode == DImode)
12375       emit_jump_insn (gen_indirect_jumpdi_nospec (operands[0], ccreg));
12376     else
12377       emit_jump_insn (gen_indirect_jumpsi_nospec (operands[0], ccreg));
12378     DONE;
12379   }
12382 (define_insn "*indirect_jump<mode>"
12383   [(set (pc)
12384         (match_operand:P 0 "register_operand" "c,*l"))]
12385   "rs6000_speculate_indirect_jumps"
12386   "b%T0"
12387   [(set_attr "type" "jmpreg")])
12389 (define_insn "indirect_jump<mode>_nospec"
12390   [(set (pc) (match_operand:P 0 "register_operand" "c,*l"))
12391    (clobber (match_operand:CC 1 "cc_reg_operand" "=y,y"))]
12392   "!rs6000_speculate_indirect_jumps"
12393   "crset %E1\;beq%T0- %1\;b $"
12394   [(set_attr "type" "jmpreg")
12395    (set_attr "length" "12")])
12397 ;; Table jump for switch statements:
12398 (define_expand "tablejump"
12399   [(use (match_operand 0))
12400    (use (label_ref (match_operand 1)))]
12401   ""
12403   if (rs6000_speculate_indirect_jumps)
12404     {
12405       if (TARGET_32BIT)
12406         emit_jump_insn (gen_tablejumpsi (operands[0], operands[1]));
12407       else
12408         emit_jump_insn (gen_tablejumpdi (operands[0], operands[1]));
12409     }
12410   else
12411     {
12412       rtx ccreg = gen_reg_rtx (CCmode);
12413       rtx jump;
12414       if (TARGET_32BIT)
12415         jump = gen_tablejumpsi_nospec (operands[0], operands[1], ccreg);
12416       else
12417         jump = gen_tablejumpdi_nospec (operands[0], operands[1], ccreg);
12418       emit_jump_insn (jump);
12419     }
12420   DONE;
12423 (define_expand "tablejumpsi"
12424   [(set (match_dup 3)
12425         (plus:SI (match_operand:SI 0)
12426                  (match_dup 2)))
12427    (parallel [(set (pc)
12428                    (match_dup 3))
12429               (use (label_ref (match_operand 1)))])]
12430   "TARGET_32BIT && rs6000_speculate_indirect_jumps"
12432   operands[0] = force_reg (SImode, operands[0]);
12433   operands[2] = force_reg (SImode, gen_rtx_LABEL_REF (SImode, operands[1]));
12434   operands[3] = gen_reg_rtx (SImode);
12437 (define_expand "tablejumpsi_nospec"
12438   [(set (match_dup 4)
12439         (plus:SI (match_operand:SI 0)
12440                  (match_dup 3)))
12441    (parallel [(set (pc)
12442                    (match_dup 4))
12443               (use (label_ref (match_operand 1)))
12444               (clobber (match_operand 2))])]
12445   "TARGET_32BIT && !rs6000_speculate_indirect_jumps"
12447   operands[0] = force_reg (SImode, operands[0]);
12448   operands[3] = force_reg (SImode, gen_rtx_LABEL_REF (SImode, operands[1]));
12449   operands[4] = gen_reg_rtx (SImode);
12452 (define_expand "tablejumpdi"
12453   [(set (match_dup 4)
12454         (sign_extend:DI (match_operand:SI 0 "lwa_operand")))
12455    (set (match_dup 3)
12456         (plus:DI (match_dup 4)
12457                  (match_dup 2)))
12458    (parallel [(set (pc)
12459                    (match_dup 3))
12460               (use (label_ref (match_operand 1)))])]
12461   "TARGET_64BIT && rs6000_speculate_indirect_jumps"
12463   operands[2] = force_reg (DImode, gen_rtx_LABEL_REF (DImode, operands[1]));
12464   operands[3] = gen_reg_rtx (DImode);
12465   operands[4] = gen_reg_rtx (DImode);
12468 (define_expand "tablejumpdi_nospec"
12469   [(set (match_dup 5)
12470         (sign_extend:DI (match_operand:SI 0 "lwa_operand")))
12471    (set (match_dup 4)
12472         (plus:DI (match_dup 5)
12473                  (match_dup 3)))
12474    (parallel [(set (pc)
12475                    (match_dup 4))
12476               (use (label_ref (match_operand 1)))
12477               (clobber (match_operand 2))])]
12478   "TARGET_64BIT && !rs6000_speculate_indirect_jumps"
12480   operands[3] = force_reg (DImode, gen_rtx_LABEL_REF (DImode, operands[1]));
12481   operands[4] = gen_reg_rtx (DImode);
12482   operands[5] = gen_reg_rtx (DImode);
12485 (define_insn "*tablejump<mode>_internal1"
12486   [(set (pc)
12487         (match_operand:P 0 "register_operand" "c,*l"))
12488    (use (label_ref (match_operand 1)))]
12489   "rs6000_speculate_indirect_jumps"
12490   "b%T0"
12491   [(set_attr "type" "jmpreg")])
12493 (define_insn "*tablejump<mode>_internal1_nospec"
12494   [(set (pc)
12495         (match_operand:P 0 "register_operand" "c,*l"))
12496    (use (label_ref (match_operand 1)))
12497    (clobber (match_operand:CC 2 "cc_reg_operand" "=y,y"))]
12498   "!rs6000_speculate_indirect_jumps"
12499   "crset %E2\;beq%T0- %2\;b $"
12500   [(set_attr "type" "jmpreg")
12501    (set_attr "length" "12")])
12503 (define_insn "nop"
12504   [(unspec [(const_int 0)] UNSPEC_NOP)]
12505   ""
12506   "nop")
12508 (define_insn "group_ending_nop"
12509   [(unspec [(const_int 0)] UNSPEC_GRP_END_NOP)]
12510   ""
12512   if (rs6000_tune == PROCESSOR_POWER6)
12513     return "ori 1,1,0";
12514   return "ori 2,2,0";
12517 (define_insn "speculation_barrier"
12518   [(unspec_volatile:BLK [(const_int 0)] UNSPECV_SPEC_BARRIER)]
12519   ""
12520   "ori 31,31,0")
12522 ;; Define the subtract-one-and-jump insns, starting with the template
12523 ;; so loop.c knows what to generate.
12525 (define_expand "doloop_end"
12526   [(use (match_operand 0))      ; loop pseudo
12527    (use (match_operand 1))]     ; label
12528   ""
12530   if (TARGET_64BIT)
12531     {
12532       if (GET_MODE (operands[0]) != DImode)
12533         FAIL;
12534       emit_jump_insn (gen_ctrdi (operands[0], operands[1]));
12535     }
12536   else
12537     {
12538       if (GET_MODE (operands[0]) != SImode)
12539         FAIL;
12540       emit_jump_insn (gen_ctrsi (operands[0], operands[1]));
12541     }
12542   DONE;
12545 (define_expand "ctr<mode>"
12546   [(parallel [(set (pc)
12547                    (if_then_else (ne (match_operand:P 0 "register_operand")
12548                                      (const_int 1))
12549                                  (label_ref (match_operand 1))
12550                                  (pc)))
12551               (set (match_dup 0)
12552                    (plus:P (match_dup 0)
12553                             (const_int -1)))
12554               (clobber (match_scratch:CC 2))
12555               (clobber (match_scratch:P 3))])]
12556   ""
12557   "")
12559 ;; We need to be able to do this for any operand, including MEM, or we
12560 ;; will cause reload to blow up since we don't allow output reloads on
12561 ;; JUMP_INSNs.
12562 ;; For the length attribute to be calculated correctly, the
12563 ;; label MUST be operand 0.
12564 ;; rs6000_legitimate_combined_insn prevents combine creating any of
12565 ;; the ctr<mode> insns.
12567 (define_code_iterator eqne [eq ne])
12568 (define_code_attr bd [(eq "bdz") (ne "bdnz")])
12569 (define_code_attr bd_neg [(eq "bdnz") (ne "bdz")])
12571 (define_insn "<bd>_<mode>"
12572   [(set (pc)
12573         (if_then_else (eqne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12574                           (const_int 1))
12575                       (label_ref (match_operand 0))
12576                       (pc)))
12577    (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
12578         (plus:P (match_dup 1)
12579                 (const_int -1)))
12580    (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
12581    (clobber (match_scratch:P 4 "=X,X,&r,r"))]
12582   ""
12584   if (which_alternative != 0)
12585     return "#";
12586   else if (get_attr_length (insn) == 4)
12587     return "<bd> %l0";
12588   else
12589     return "<bd_neg> $+8\;b %l0";
12591   [(set_attr "type" "branch")
12592    (set_attr_alternative "length"
12593      [(if_then_else (and (ge (minus (match_dup 0) (pc))
12594                              (const_int -32768))
12595                          (lt (minus (match_dup 0) (pc))
12596                              (const_int 32764)))
12597                     (const_int 4)
12598                     (const_int 8))
12599       (const_string "16")
12600       (const_string "20")
12601       (const_string "20")])])
12603 ;; Now the splitter if we could not allocate the CTR register
12604 (define_split
12605   [(set (pc)
12606         (if_then_else (match_operator 2 "comparison_operator"
12607                                       [(match_operand:P 1 "gpc_reg_operand")
12608                                        (const_int 1)])
12609                       (match_operand 5)
12610                       (match_operand 6)))
12611    (set (match_operand:P 0 "nonimmediate_operand")
12612         (plus:P (match_dup 1)
12613                 (const_int -1)))
12614    (clobber (match_scratch:CC 3))
12615    (clobber (match_scratch:P 4))]
12616   "reload_completed"
12617   [(set (pc)
12618         (if_then_else (match_dup 7)
12619                       (match_dup 5)
12620                       (match_dup 6)))]
12622   operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[2]), VOIDmode, operands[3],
12623                                 const0_rtx);
12624   emit_insn (gen_rtx_SET (operands[3],
12625                           gen_rtx_COMPARE (CCmode, operands[1], const1_rtx)));
12626   if (gpc_reg_operand (operands[0], <MODE>mode))
12627     emit_insn (gen_add<mode>3 (operands[0], operands[1], constm1_rtx));
12628   else
12629     {
12630       emit_insn (gen_add<mode>3 (operands[4], operands[1], constm1_rtx));
12631       emit_move_insn (operands[0], operands[4]);
12632     } 
12633     /* No DONE so branch comes from the pattern.  */
12636 ;; patterns for bdnzt/bdnzf/bdzt/bdzf
12637 ;; Note that in the case of long branches we have to decompose this into
12638 ;; bdnz+bc. This is because bdnzt has an implied AND between the ctr condition
12639 ;; and the CR bit, which means there is no way to conveniently invert the
12640 ;; comparison as is done with plain bdnz/bdz.
12642 (define_insn "<bd>tf_<mode>"
12643   [(set (pc)
12644         (if_then_else
12645           (and
12646              (eqne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12647                    (const_int 1))
12648              (match_operator 3 "branch_comparison_operator"
12649                       [(match_operand 4 "cc_reg_operand" "y,y,y,y")
12650                        (const_int 0)]))
12651           (label_ref (match_operand 0))
12652           (pc)))
12653    (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
12654         (plus:P (match_dup 1)
12655                 (const_int -1)))
12656    (clobber (match_scratch:P 5 "=X,X,&r,r"))
12657    (clobber (match_scratch:CC 6 "=X,&y,&y,&y"))
12658    (clobber (match_scratch:CCEQ 7 "=X,&y,&y,&y"))]
12659   ""
12661   if (which_alternative != 0)
12662     return "#";
12663   else if (get_attr_length (insn) == 4)
12664     {
12665       if (branch_positive_comparison_operator (operands[3],
12666                                                GET_MODE (operands[3])))
12667         return "<bd>t %j3,%l0";
12668       else
12669         return "<bd>f %j3,%l0";
12670     }
12671   else
12672     {
12673       static char seq[96];
12674       char *bcs = output_cbranch (operands[3], "$+8", 1, insn);
12675       sprintf(seq, "<bd_neg> $+12\;%s;b %%l0", bcs);
12676       return seq;
12677     }
12679   [(set_attr "type" "branch")
12680    (set_attr_alternative "length"
12681      [(if_then_else (and (ge (minus (match_dup 0) (pc))
12682                              (const_int -32768))
12683                          (lt (minus (match_dup 0) (pc))
12684                              (const_int 32764)))
12685                     (const_int 4)
12686                     (const_int 8))
12687       (const_string "16")
12688       (const_string "20")
12689       (const_string "20")])])
12691 ;; Now the splitter if we could not allocate the CTR register
12692 (define_split
12693   [(set (pc)
12694         (if_then_else
12695           (and
12696              (match_operator 1 "comparison_operator"
12697                              [(match_operand:P 0 "gpc_reg_operand")
12698                               (const_int 1)])
12699              (match_operator 3 "branch_comparison_operator"
12700                       [(match_operand 2 "cc_reg_operand")
12701                        (const_int 0)]))
12702           (match_operand 4)
12703           (match_operand 5)))
12704    (set (match_operand:P 6 "int_reg_operand")
12705         (plus:P (match_dup 0)
12706                 (const_int -1)))
12707    (clobber (match_scratch:P 7))
12708    (clobber (match_scratch:CC 8))
12709    (clobber (match_scratch:CCEQ 9))]
12710   "reload_completed"
12711 [(pc)]
12713   rtx ctr = operands[0];
12714   rtx ctrcmp = operands[1];
12715   rtx ccin = operands[2];
12716   rtx cccmp = operands[3];
12717   rtx dst1 = operands[4];
12718   rtx dst2 = operands[5];
12719   rtx ctrout = operands[6];
12720   rtx ctrtmp = operands[7];
12721   enum rtx_code cmpcode = GET_CODE (ctrcmp);
12722   bool ispos = branch_positive_comparison_operator (ctrcmp, GET_MODE (ctrcmp));
12723   if (!ispos)
12724     cmpcode = reverse_condition (cmpcode);
12725   /* Generate crand/crandc here.  */
12726   emit_insn (gen_rtx_SET (operands[8],
12727                           gen_rtx_COMPARE (CCmode, ctr, const1_rtx)));
12728   rtx ctrcmpcc = gen_rtx_fmt_ee (cmpcode, SImode, operands[8], const0_rtx);
12730   rtx andexpr = gen_rtx_AND (SImode, ctrcmpcc, cccmp);
12731   if (ispos)
12732      emit_insn (gen_cceq_ior_compare (operands[9], andexpr, ctrcmpcc,
12733                                       operands[8], cccmp, ccin));
12734   else
12735      emit_insn (gen_cceq_ior_compare_complement (operands[9], andexpr, ctrcmpcc,
12736                                                  operands[8], cccmp, ccin));
12737   if (gpc_reg_operand (operands[0], <MODE>mode))
12738      emit_insn (gen_add<mode>3 (ctrout, ctr, constm1_rtx));
12739   else
12740     {
12741       emit_insn (gen_add<mode>3 (ctrtmp, ctr, constm1_rtx));
12742       emit_move_insn (ctrout, ctrtmp);
12743     }
12744   rtx cmp = gen_rtx_EQ (CCEQmode, operands[9], const0_rtx);
12745   emit_jump_insn (gen_rtx_SET (pc_rtx,
12746                                gen_rtx_IF_THEN_ELSE (VOIDmode, cmp,
12747                                                      dst1, dst2)));
12748   DONE;
12752 (define_insn "trap"
12753   [(trap_if (const_int 1) (const_int 0))]
12754   ""
12755   "trap"
12756   [(set_attr "type" "trap")])
12758 (define_expand "ctrap<mode>4"
12759   [(trap_if (match_operator 0 "ordered_comparison_operator"
12760                             [(match_operand:GPR 1 "register_operand")
12761                              (match_operand:GPR 2 "reg_or_short_operand")])
12762             (match_operand 3 "zero_constant" ""))]
12763   ""
12764   "")
12766 (define_insn ""
12767   [(trap_if (match_operator 0 "ordered_comparison_operator"
12768                             [(match_operand:GPR 1 "register_operand" "r")
12769                              (match_operand:GPR 2 "reg_or_short_operand" "rI")])
12770             (const_int 0))]
12771   ""
12772   "t<wd>%V0%I2 %1,%2"
12773   [(set_attr "type" "trap")])
12775 ;; Insns related to generating the function prologue and epilogue.
12777 (define_expand "prologue"
12778   [(use (const_int 0))]
12779   ""
12781   rs6000_emit_prologue ();
12782   if (!TARGET_SCHED_PROLOG)
12783     emit_insn (gen_blockage ());
12784   DONE;
12787 (define_insn "*movesi_from_cr_one"
12788   [(match_parallel 0 "mfcr_operation"
12789                    [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
12790                          (unspec:SI [(match_operand:CC 2 "cc_reg_operand" "y")
12791                                      (match_operand 3 "immediate_operand" "n")]
12792                           UNSPEC_MOVESI_FROM_CR))])]
12793   "TARGET_MFCRF"
12795   int mask = 0;
12796   int i;
12797   for (i = 0; i < XVECLEN (operands[0], 0); i++)
12798   {
12799     mask = INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
12800     operands[4] = GEN_INT (mask);
12801     output_asm_insn ("mfcr %1,%4", operands);
12802   }
12803   return "";
12805   [(set_attr "type" "mfcrf")])
12807 ;; Don't include the volatile CRs since their values are not used wrt CR save
12808 ;; in the prologue and doing so prevents shrink-wrapping because we can't move the
12809 ;; prologue past an insn (early exit test) that defines a register used in the
12810 ;; prologue.
12811 (define_insn "prologue_movesi_from_cr"
12812   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
12813         (unspec:SI [(reg:CC CR2_REGNO) (reg:CC CR3_REGNO)
12814                     (reg:CC CR4_REGNO)]
12815                    UNSPEC_MOVESI_FROM_CR))]
12816   ""
12817   "mfcr %0"
12818   [(set_attr "type" "mfcr")])
12820 (define_insn "*crsave"
12821   [(match_parallel 0 "crsave_operation"
12822                    [(set (match_operand:SI 1 "memory_operand" "=m")
12823                          (match_operand:SI 2 "gpc_reg_operand" "r"))])]
12824   ""
12825   "stw %2,%1"
12826   [(set_attr "type" "store")])
12828 (define_insn "*stmw"
12829   [(match_parallel 0 "stmw_operation"
12830                    [(set (match_operand:SI 1 "memory_operand" "=m")
12831                          (match_operand:SI 2 "gpc_reg_operand" "r"))])]
12832   "TARGET_MULTIPLE"
12833   "stmw %2,%1"
12834   [(set_attr "type" "store")
12835    (set_attr "update" "yes")
12836    (set_attr "indexed" "yes")])
12838 ; The following comment applies to:
12839 ;     save_gpregs_*
12840 ;     save_fpregs_*
12841 ;     restore_gpregs*
12842 ;     return_and_restore_gpregs*
12843 ;     return_and_restore_fpregs*
12844 ;     return_and_restore_fpregs_aix*
12846 ; The out-of-line save / restore functions expects one input argument.
12847 ; Since those are not standard call_insn's, we must avoid using
12848 ; MATCH_OPERAND for that argument. That way the register rename
12849 ; optimization will not try to rename this register.
12850 ; Each pattern is repeated for each possible register number used in 
12851 ; various ABIs (r11, r1, and for some functions r12)
12853 (define_insn "*save_gpregs_<mode>_r11"
12854   [(match_parallel 0 "any_parallel_operand"
12855                    [(clobber (reg:P LR_REGNO))
12856                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
12857                     (use (reg:P 11))
12858                     (set (match_operand:P 2 "memory_operand" "=m")
12859                          (match_operand:P 3 "gpc_reg_operand" "r"))])]
12860   ""
12861   "bl %1"
12862   [(set_attr "type" "branch")])
12864 (define_insn "*save_gpregs_<mode>_r12"
12865   [(match_parallel 0 "any_parallel_operand"
12866                    [(clobber (reg:P LR_REGNO))
12867                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
12868                     (use (reg:P 12))
12869                     (set (match_operand:P 2 "memory_operand" "=m")
12870                          (match_operand:P 3 "gpc_reg_operand" "r"))])]
12871   ""
12872   "bl %1"
12873   [(set_attr "type" "branch")])
12875 (define_insn "*save_gpregs_<mode>_r1"
12876   [(match_parallel 0 "any_parallel_operand"
12877                    [(clobber (reg:P LR_REGNO))
12878                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
12879                     (use (reg:P 1))
12880                     (set (match_operand:P 2 "memory_operand" "=m")
12881                          (match_operand:P 3 "gpc_reg_operand" "r"))])]
12882   ""
12883   "bl %1"
12884   [(set_attr "type" "branch")])
12886 (define_insn "*save_fpregs_<mode>_r11"
12887   [(match_parallel 0 "any_parallel_operand"
12888                    [(clobber (reg:P LR_REGNO))
12889                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
12890                     (use (reg:P 11))
12891                     (set (match_operand:DF 2 "memory_operand" "=m")
12892                          (match_operand:DF 3 "gpc_reg_operand" "d"))])]
12893   ""
12894   "bl %1"
12895   [(set_attr "type" "branch")])
12897 (define_insn "*save_fpregs_<mode>_r12"
12898   [(match_parallel 0 "any_parallel_operand"
12899                    [(clobber (reg:P LR_REGNO))
12900                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
12901                     (use (reg:P 12))
12902                     (set (match_operand:DF 2 "memory_operand" "=m")
12903                          (match_operand:DF 3 "gpc_reg_operand" "d"))])]
12904   ""
12905   "bl %1"
12906   [(set_attr "type" "branch")])
12908 (define_insn "*save_fpregs_<mode>_r1"
12909   [(match_parallel 0 "any_parallel_operand"
12910                    [(clobber (reg:P LR_REGNO))
12911                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
12912                     (use (reg:P 1))
12913                     (set (match_operand:DF 2 "memory_operand" "=m")
12914                          (match_operand:DF 3 "gpc_reg_operand" "d"))])]
12915   ""
12916   "bl %1"
12917   [(set_attr "type" "branch")])
12919 ; This is to explain that changes to the stack pointer should
12920 ; not be moved over loads from or stores to stack memory.
12921 (define_insn "stack_tie"
12922   [(match_parallel 0 "tie_operand"
12923                    [(set (mem:BLK (reg 1)) (const_int 0))])]
12924   ""
12925   ""
12926   [(set_attr "length" "0")])
12928 ; Some 32-bit ABIs do not have a red zone, so the stack deallocation has to
12929 ; stay behind all restores from the stack, it cannot be reordered to before
12930 ; one.  See PR77687.  This insn is an add or mr, and a memory clobber.
12931 (define_insn "stack_restore_tie"
12932   [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
12933         (plus:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
12934                  (match_operand:SI 2 "reg_or_cint_operand" "O,rI")))
12935    (set (mem:BLK (scratch)) (const_int 0))]
12936   "TARGET_32BIT"
12937   "@
12938    mr %0,%1
12939    add%I2 %0,%1,%2"
12940   [(set_attr "type" "*,add")])
12942 (define_expand "epilogue"
12943   [(use (const_int 0))]
12944   ""
12946   if (!TARGET_SCHED_PROLOG)
12947     emit_insn (gen_blockage ());
12948   rs6000_emit_epilogue (FALSE);
12949   DONE;
12952 ; On some processors, doing the mtcrf one CC register at a time is
12953 ; faster (like on the 604e).  On others, doing them all at once is
12954 ; faster; for instance, on the 601 and 750.
12956 (define_expand "movsi_to_cr_one"
12957   [(set (match_operand:CC 0 "cc_reg_operand")
12958         (unspec:CC [(match_operand:SI 1 "gpc_reg_operand")
12959                     (match_dup 2)] UNSPEC_MOVESI_TO_CR))]
12960   ""
12961   "operands[2] = GEN_INT (1 << (75 - REGNO (operands[0])));")
12963 (define_insn "*movsi_to_cr"
12964   [(match_parallel 0 "mtcrf_operation"
12965                    [(set (match_operand:CC 1 "cc_reg_operand" "=y")
12966                          (unspec:CC [(match_operand:SI 2 "gpc_reg_operand" "r")
12967                                      (match_operand 3 "immediate_operand" "n")]
12968                                     UNSPEC_MOVESI_TO_CR))])]
12969  ""
12971   int mask = 0;
12972   int i;
12973   for (i = 0; i < XVECLEN (operands[0], 0); i++)
12974     mask |= INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
12975   operands[4] = GEN_INT (mask);
12976   return "mtcrf %4,%2";
12978   [(set_attr "type" "mtcr")])
12980 (define_insn "*mtcrfsi"
12981   [(set (match_operand:CC 0 "cc_reg_operand" "=y")
12982         (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
12983                     (match_operand 2 "immediate_operand" "n")]
12984                    UNSPEC_MOVESI_TO_CR))]
12985   "GET_CODE (operands[0]) == REG
12986    && CR_REGNO_P (REGNO (operands[0]))
12987    && GET_CODE (operands[2]) == CONST_INT
12988    && INTVAL (operands[2]) == 1 << (75 - REGNO (operands[0]))"
12989   "mtcrf %R0,%1"
12990   [(set_attr "type" "mtcr")])
12992 ; The load-multiple instructions have similar properties.
12993 ; Note that "load_multiple" is a name known to the machine-independent
12994 ; code that actually corresponds to the PowerPC load-string.
12996 (define_insn "*lmw"
12997   [(match_parallel 0 "lmw_operation"
12998                    [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
12999                          (match_operand:SI 2 "memory_operand" "m"))])]
13000   "TARGET_MULTIPLE"
13001   "lmw %1,%2"
13002   [(set_attr "type" "load")
13003    (set_attr "update" "yes")
13004    (set_attr "indexed" "yes")
13005    (set_attr "cell_micro" "always")])
13007 ; FIXME: "any_parallel_operand" is a bit flexible...
13009 ; The following comment applies to:
13010 ;     save_gpregs_*
13011 ;     save_fpregs_*
13012 ;     restore_gpregs*
13013 ;     return_and_restore_gpregs*
13014 ;     return_and_restore_fpregs*
13015 ;     return_and_restore_fpregs_aix*
13017 ; The out-of-line save / restore functions expects one input argument.
13018 ; Since those are not standard call_insn's, we must avoid using
13019 ; MATCH_OPERAND for that argument. That way the register rename
13020 ; optimization will not try to rename this register.
13021 ; Each pattern is repeated for each possible register number used in 
13022 ; various ABIs (r11, r1, and for some functions r12)
13024 (define_insn "*restore_gpregs_<mode>_r11"
13025  [(match_parallel 0 "any_parallel_operand"
13026                   [(clobber (reg:P LR_REGNO))
13027                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13028                    (use (reg:P 11))
13029                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
13030                         (match_operand:P 3 "memory_operand" "m"))])]
13031  ""
13032  "bl %1"
13033  [(set_attr "type" "branch")])
13035 (define_insn "*restore_gpregs_<mode>_r12"
13036  [(match_parallel 0 "any_parallel_operand"
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  "bl %1"
13044  [(set_attr "type" "branch")])
13046 (define_insn "*restore_gpregs_<mode>_r1"
13047  [(match_parallel 0 "any_parallel_operand"
13048                   [(clobber (reg:P LR_REGNO))
13049                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13050                    (use (reg:P 1))
13051                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
13052                         (match_operand:P 3 "memory_operand" "m"))])]
13053  ""
13054  "bl %1"
13055  [(set_attr "type" "branch")])
13057 (define_insn "*return_and_restore_gpregs_<mode>_r11"
13058  [(match_parallel 0 "any_parallel_operand"
13059                   [(return)
13060                    (clobber (reg:P LR_REGNO))
13061                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13062                    (use (reg:P 11))
13063                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
13064                         (match_operand:P 3 "memory_operand" "m"))])]
13065  ""
13066  "b %1"
13067  [(set_attr "type" "branch")])
13069 (define_insn "*return_and_restore_gpregs_<mode>_r12"
13070  [(match_parallel 0 "any_parallel_operand"
13071                   [(return)
13072                    (clobber (reg:P LR_REGNO))
13073                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13074                    (use (reg:P 12))
13075                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
13076                         (match_operand:P 3 "memory_operand" "m"))])]
13077  ""
13078  "b %1"
13079  [(set_attr "type" "branch")])
13081 (define_insn "*return_and_restore_gpregs_<mode>_r1"
13082  [(match_parallel 0 "any_parallel_operand"
13083                   [(return)
13084                    (clobber (reg:P LR_REGNO))
13085                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13086                    (use (reg:P 1))
13087                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
13088                         (match_operand:P 3 "memory_operand" "m"))])]
13089  ""
13090  "b %1"
13091  [(set_attr "type" "branch")])
13093 (define_insn "*return_and_restore_fpregs_<mode>_r11"
13094  [(match_parallel 0 "any_parallel_operand"
13095                   [(return)
13096                    (clobber (reg:P LR_REGNO))
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_<mode>_r12"
13106  [(match_parallel 0 "any_parallel_operand"
13107                   [(return)
13108                    (clobber (reg:P LR_REGNO))
13109                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13110                    (use (reg:P 12))
13111                    (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13112                         (match_operand:DF 3 "memory_operand" "m"))])]
13113  ""
13114  "b %1"
13115  [(set_attr "type" "branch")])
13117 (define_insn "*return_and_restore_fpregs_<mode>_r1"
13118  [(match_parallel 0 "any_parallel_operand"
13119                   [(return)
13120                    (clobber (reg:P LR_REGNO))
13121                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13122                    (use (reg:P 1))
13123                    (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13124                         (match_operand:DF 3 "memory_operand" "m"))])]
13125  ""
13126  "b %1"
13127  [(set_attr "type" "branch")])
13129 (define_insn "*return_and_restore_fpregs_aix_<mode>_r11"
13130  [(match_parallel 0 "any_parallel_operand"
13131                   [(return)
13132                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13133                    (use (reg:P 11))
13134                    (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13135                         (match_operand:DF 3 "memory_operand" "m"))])]
13136  ""
13137  "b %1"
13138  [(set_attr "type" "branch")])
13140 (define_insn "*return_and_restore_fpregs_aix_<mode>_r1"
13141  [(match_parallel 0 "any_parallel_operand"
13142                   [(return)
13143                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13144                    (use (reg:P 1))
13145                    (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13146                         (match_operand:DF 3 "memory_operand" "m"))])]
13147  ""
13148  "b %1"
13149  [(set_attr "type" "branch")])
13151 ; This is used in compiling the unwind routines.
13152 (define_expand "eh_return"
13153   [(use (match_operand 0 "general_operand"))]
13154   ""
13156   if (TARGET_32BIT)
13157     emit_insn (gen_eh_set_lr_si (operands[0]));
13158   else
13159     emit_insn (gen_eh_set_lr_di (operands[0]));
13160   DONE;
13163 ; We can't expand this before we know where the link register is stored.
13164 (define_insn "eh_set_lr_<mode>"
13165   [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
13166                     UNSPECV_EH_RR)
13167    (clobber (match_scratch:P 1 "=&b"))]
13168   ""
13169   "#")
13171 (define_split
13172   [(unspec_volatile [(match_operand 0 "register_operand")] UNSPECV_EH_RR)
13173    (clobber (match_scratch 1))]
13174   "reload_completed"
13175   [(const_int 0)]
13177   rs6000_emit_eh_reg_restore (operands[0], operands[1]);
13178   DONE;
13181 (define_insn "prefetch"
13182   [(prefetch (match_operand 0 "indexed_or_indirect_address" "a")
13183              (match_operand:SI 1 "const_int_operand" "n")
13184              (match_operand:SI 2 "const_int_operand" "n"))]
13185   ""
13189   /* dcbtstt, dcbtt and TH=0b10000 support starts with ISA 2.06 (Power7).
13190      AIX does not support the dcbtstt and dcbtt extended mnemonics.
13191      The AIX assembler does not support the three operand form of dcbt
13192      and dcbtst on Power 7 (-mpwr7).  */
13193   int inst_select = INTVAL (operands[2]) || !TARGET_DIRECT_MOVE;
13195   if (REG_P (operands[0]))
13196     {
13197       if (INTVAL (operands[1]) == 0)
13198         return inst_select ? "dcbt 0,%0" : "dcbt 0,%0,16";
13199       else
13200         return inst_select ? "dcbtst 0,%0" : "dcbtst 0,%0,16";
13201     }
13202   else
13203     {
13204       if (INTVAL (operands[1]) == 0)
13205         return inst_select ? "dcbt %a0" : "dcbt %a0,16";
13206       else
13207         return inst_select ? "dcbtst %a0" : "dcbtst %a0,16";
13208     }
13210   [(set_attr "type" "load")])
13212 ;; Handle -fsplit-stack.
13214 (define_expand "split_stack_prologue"
13215   [(const_int 0)]
13216   ""
13218   rs6000_expand_split_stack_prologue ();
13219   DONE;
13222 (define_expand "load_split_stack_limit"
13223   [(set (match_operand 0)
13224         (unspec [(const_int 0)] UNSPEC_STACK_CHECK))]
13225   ""
13227   emit_insn (gen_rtx_SET (operands[0],
13228                           gen_rtx_UNSPEC (Pmode,
13229                                           gen_rtvec (1, const0_rtx),
13230                                           UNSPEC_STACK_CHECK)));
13231   DONE;
13234 (define_insn "load_split_stack_limit_di"
13235   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
13236         (unspec:DI [(const_int 0)] UNSPEC_STACK_CHECK))]
13237   "TARGET_64BIT"
13238   "ld %0,-0x7040(13)"
13239   [(set_attr "type" "load")
13240    (set_attr "update" "no")
13241    (set_attr "indexed" "no")])
13243 (define_insn "load_split_stack_limit_si"
13244   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
13245         (unspec:SI [(const_int 0)] UNSPEC_STACK_CHECK))]
13246   "!TARGET_64BIT"
13247   "lwz %0,-0x7020(2)"
13248   [(set_attr "type" "load")
13249    (set_attr "update" "no")
13250    (set_attr "indexed" "no")])
13252 ;; A return instruction which the middle-end doesn't see.
13253 ;; Use r0 to stop regrename twiddling with lr restore insns emitted
13254 ;; after the call to __morestack.
13255 (define_insn "split_stack_return"
13256   [(unspec_volatile [(reg:SI 0) (reg:SI LR_REGNO)] UNSPECV_SPLIT_STACK_RETURN)]
13257   ""
13258   "blr"
13259   [(set_attr "type" "jmpreg")])
13261 ;; If there are operand 0 bytes available on the stack, jump to
13262 ;; operand 1.
13263 (define_expand "split_stack_space_check"
13264   [(set (match_dup 2)
13265         (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
13266    (set (match_dup 3)
13267         (minus (reg STACK_POINTER_REGNUM)
13268                (match_operand 0)))
13269    (set (match_dup 4) (compare:CCUNS (match_dup 3) (match_dup 2)))
13270    (set (pc) (if_then_else
13271               (geu (match_dup 4) (const_int 0))
13272               (label_ref (match_operand 1))
13273               (pc)))]
13274   ""
13276   rs6000_split_stack_space_check (operands[0], operands[1]);
13277   DONE;
13280 (define_insn "bpermd_<mode>"
13281   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
13282         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "r")
13283                    (match_operand:P 2 "gpc_reg_operand" "r")] UNSPEC_BPERM))]
13284   "TARGET_POPCNTD"
13285   "bpermd %0,%1,%2"
13286   [(set_attr "type" "popcnt")])
13289 ;; Builtin fma support.  Handle 
13290 ;; Note that the conditions for expansion are in the FMA_F iterator.
13292 (define_expand "fma<mode>4"
13293   [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13294         (fma:FMA_F
13295           (match_operand:FMA_F 1 "gpc_reg_operand")
13296           (match_operand:FMA_F 2 "gpc_reg_operand")
13297           (match_operand:FMA_F 3 "gpc_reg_operand")))]
13298   ""
13299   "")
13301 (define_insn "*fma<mode>4_fpr"
13302   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13303         (fma:SFDF
13304           (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>,<Fv2>")
13305           (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13306           (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>")))]
13307   "TARGET_HARD_FLOAT"
13308   "@
13309    fmadd<Ftrad> %0,%1,%2,%3
13310    xsmadda<Fvsx> %x0,%x1,%x2
13311    xsmaddm<Fvsx> %x0,%x1,%x3"
13312   [(set_attr "type" "fp")])
13314 ; Altivec only has fma and nfms.
13315 (define_expand "fms<mode>4"
13316   [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13317         (fma:FMA_F
13318           (match_operand:FMA_F 1 "gpc_reg_operand")
13319           (match_operand:FMA_F 2 "gpc_reg_operand")
13320           (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand"))))]
13321   "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13322   "")
13324 (define_insn "*fms<mode>4_fpr"
13325   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13326         (fma:SFDF
13327          (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
13328          (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13329          (neg:SFDF (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>"))))]
13330   "TARGET_HARD_FLOAT"
13331   "@
13332    fmsub<Ftrad> %0,%1,%2,%3
13333    xsmsuba<Fvsx> %x0,%x1,%x2
13334    xsmsubm<Fvsx> %x0,%x1,%x3"
13335   [(set_attr "type" "fp")])
13337 ;; If signed zeros are ignored, -(a * b - c) = -a * b + c.
13338 (define_expand "fnma<mode>4"
13339   [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13340         (neg:FMA_F
13341           (fma:FMA_F
13342             (match_operand:FMA_F 1 "gpc_reg_operand")
13343             (match_operand:FMA_F 2 "gpc_reg_operand")
13344             (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand")))))]
13345   "!HONOR_SIGNED_ZEROS (<MODE>mode)"
13346   "")
13348 ;; If signed zeros are ignored, -(a * b + c) = -a * b - c.
13349 (define_expand "fnms<mode>4"
13350   [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13351         (neg:FMA_F
13352           (fma:FMA_F
13353             (match_operand:FMA_F 1 "gpc_reg_operand")
13354             (match_operand:FMA_F 2 "gpc_reg_operand")
13355             (match_operand:FMA_F 3 "gpc_reg_operand"))))]
13356   "!HONOR_SIGNED_ZEROS (<MODE>mode) && !VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13357   "")
13359 ; Not an official optab name, but used from builtins.
13360 (define_expand "nfma<mode>4"
13361   [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13362         (neg:FMA_F
13363           (fma:FMA_F
13364             (match_operand:FMA_F 1 "gpc_reg_operand")
13365             (match_operand:FMA_F 2 "gpc_reg_operand")
13366             (match_operand:FMA_F 3 "gpc_reg_operand"))))]
13367   "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13368   "")
13370 (define_insn "*nfma<mode>4_fpr"
13371   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13372         (neg:SFDF
13373          (fma:SFDF
13374           (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
13375           (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13376           (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>"))))]
13377   "TARGET_HARD_FLOAT"
13378   "@
13379    fnmadd<Ftrad> %0,%1,%2,%3
13380    xsnmadda<Fvsx> %x0,%x1,%x2
13381    xsnmaddm<Fvsx> %x0,%x1,%x3"
13382   [(set_attr "type" "fp")])
13384 ; Not an official optab name, but used from builtins.
13385 (define_expand "nfms<mode>4"
13386   [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13387         (neg:FMA_F
13388           (fma:FMA_F
13389             (match_operand:FMA_F 1 "gpc_reg_operand")
13390             (match_operand:FMA_F 2 "gpc_reg_operand")
13391             (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand")))))]
13392   ""
13393   "")
13395 (define_insn "*nfmssf4_fpr"
13396   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13397         (neg:SFDF
13398          (fma:SFDF
13399           (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
13400           (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13401           (neg:SFDF
13402            (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>")))))]
13403   "TARGET_HARD_FLOAT"
13404   "@
13405    fnmsub<Ftrad> %0,%1,%2,%3
13406    xsnmsuba<Fvsx> %x0,%x1,%x2
13407    xsnmsubm<Fvsx> %x0,%x1,%x3"
13408   [(set_attr "type" "fp")])
13411 (define_expand "rs6000_get_timebase"
13412   [(use (match_operand:DI 0 "gpc_reg_operand"))]
13413   ""
13415   if (TARGET_POWERPC64)
13416     emit_insn (gen_rs6000_mftb_di (operands[0]));
13417   else
13418     emit_insn (gen_rs6000_get_timebase_ppc32 (operands[0]));
13419   DONE;
13422 (define_insn "rs6000_get_timebase_ppc32"
13423   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
13424         (unspec_volatile:DI [(const_int 0)] UNSPECV_MFTB))
13425    (clobber (match_scratch:SI 1 "=r"))
13426    (clobber (match_scratch:CC 2 "=y"))]
13427   "!TARGET_POWERPC64"
13429   if (WORDS_BIG_ENDIAN)
13430     if (TARGET_MFCRF)
13431       {
13432         return "mfspr %0,269\;"
13433                "mfspr %L0,268\;"
13434                "mfspr %1,269\;"
13435                "cmpw %2,%0,%1\;"
13436                "bne- %2,$-16";
13437       }
13438     else
13439       {
13440         return "mftbu %0\;"
13441                "mftb %L0\;"
13442                "mftbu %1\;"
13443                "cmpw %2,%0,%1\;"
13444                "bne- %2,$-16";
13445       }
13446   else
13447     if (TARGET_MFCRF)
13448       {
13449         return "mfspr %L0,269\;"
13450                "mfspr %0,268\;"
13451                "mfspr %1,269\;"
13452                "cmpw %2,%L0,%1\;"
13453                "bne- %2,$-16";
13454       }
13455     else
13456       {
13457         return "mftbu %L0\;"
13458                "mftb %0\;"
13459                "mftbu %1\;"
13460                "cmpw %2,%L0,%1\;"
13461                "bne- %2,$-16";
13462       }
13464   [(set_attr "length" "20")])
13466 (define_insn "rs6000_mftb_<mode>"
13467   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
13468         (unspec_volatile:GPR [(const_int 0)] UNSPECV_MFTB))]
13469   ""
13471   if (TARGET_MFCRF)
13472     return "mfspr %0,268";
13473   else
13474     return "mftb %0";
13478 ;; The ISA 3.0 mffsl instruction is a lower latency instruction
13479 ;; for reading bits [29:31], [45:51] and [56:63] of the FPSCR.
13480 (define_insn "rs6000_mffsl_hw"
13481   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
13482         (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFSL))]
13483   "TARGET_HARD_FLOAT"
13484   "mffsl %0")
13486 (define_expand "rs6000_mffsl"
13487   [(set (match_operand:DF 0 "gpc_reg_operand")
13488         (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFSL))]
13489   "TARGET_HARD_FLOAT"
13491   /* If the low latency mffsl instruction (ISA 3.0) is available use it,
13492      otherwise fall back to the older mffs instruction to emulate the mffsl
13493      instruction.  */
13495   if (!TARGET_P9_MISC)
13496     {
13497        rtx tmp_di = gen_reg_rtx (DImode);
13498        rtx tmp_df = gen_reg_rtx (DFmode);
13500        /* The mffs instruction reads the entire FPSCR.  Emulate the mffsl
13501           instruction using the mffs instruction and masking off the bits
13502           the mmsl instruciton actually reads.  */
13503        emit_insn (gen_rs6000_mffs (tmp_df));
13504        tmp_di = simplify_gen_subreg (DImode, tmp_df, DFmode, 0);
13505        emit_insn (gen_anddi3 (tmp_di, tmp_di, GEN_INT (0x70007f0ffLL)));
13507        operands[0] = simplify_gen_subreg (DFmode, tmp_di, DImode, 0);
13508        DONE;
13509     }
13511     emit_insn (gen_rs6000_mffsl_hw (operands[0]));
13512     DONE;
13515 (define_insn "rs6000_mffs"
13516   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
13517         (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFS))]
13518   "TARGET_HARD_FLOAT"
13519   "mffs %0")
13521 (define_insn "rs6000_mtfsf"
13522   [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "i")
13523                      (match_operand:DF 1 "gpc_reg_operand" "d")]
13524                     UNSPECV_MTFSF)]
13525   "TARGET_HARD_FLOAT"
13526   "mtfsf %0,%1")
13528 (define_insn "rs6000_mtfsf_hi"
13529   [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "n")
13530                      (match_operand:DF 1 "gpc_reg_operand" "d")]
13531                     UNSPECV_MTFSF_HI)]
13532   "TARGET_HARD_FLOAT"
13533   "mtfsf %0,%1,0,1")
13536 ;; Power8 fusion support for fusing an addis instruction with a D-form load of
13537 ;; a GPR.  The addis instruction must be adjacent to the load, and use the same
13538 ;; register that is being loaded.  The fused ops must be physically adjacent.
13540 ;; On Power8 GPR loads, we try to use the register that is being load.  The
13541 ;; peephole2 then gathers any other fused possibilities that it can find after
13542 ;; register allocation.  If power9 fusion is selected, we also fuse floating
13543 ;; point loads/stores.
13545 ;; Find cases where the addis that feeds into a load instruction is either used
13546 ;; once or is the same as the target register, and replace it with the fusion
13547 ;; insn
13549 (define_peephole2
13550   [(set (match_operand:P 0 "base_reg_operand")
13551         (match_operand:P 1 "fusion_gpr_addis"))
13552    (set (match_operand:INT1 2 "base_reg_operand")
13553         (match_operand:INT1 3 "fusion_gpr_mem_load"))]
13554   "TARGET_P8_FUSION
13555    && fusion_gpr_load_p (operands[0], operands[1], operands[2],
13556                          operands[3])"
13557   [(const_int 0)]
13559   expand_fusion_gpr_load (operands);
13560   DONE;
13563 ;; Fusion insn, created by the define_peephole2 above (and eventually by
13564 ;; reload)
13566 (define_insn "*fusion_gpr_load_<mode>"
13567   [(set (match_operand:INT1 0 "base_reg_operand" "=b")
13568         (unspec:INT1 [(match_operand:INT1 1 "fusion_addis_mem_combo_load" "wF")]
13569                      UNSPEC_FUSION_GPR))]
13570   "TARGET_P8_FUSION"
13572   return emit_fusion_gpr_load (operands[0], operands[1]);
13574   [(set_attr "type" "load")
13575    (set_attr "length" "8")])
13578 ;; Optimize cases where we want to do a D-form load (register+offset) on
13579 ;; ISA 2.06/2.07 to an Altivec register, and the register allocator
13580 ;; has generated:
13581 ;;      LFD 0,32(3)
13582 ;;      XXLOR 32,0,0
13584 ;; and we change this to:
13585 ;;      LI 0,32
13586 ;;      LXSDX 32,3,9
13588 (define_peephole2
13589   [(match_scratch:P 0 "b")
13590    (set (match_operand:ALTIVEC_DFORM 1 "fpr_reg_operand")
13591         (match_operand:ALTIVEC_DFORM 2 "simple_offsettable_mem_operand"))
13592    (set (match_operand:ALTIVEC_DFORM 3 "altivec_register_operand")
13593         (match_dup 1))]
13594   "TARGET_VSX && !TARGET_P9_VECTOR && peep2_reg_dead_p (2, operands[1])"
13595   [(set (match_dup 0)
13596         (match_dup 4))
13597    (set (match_dup 3)
13598         (match_dup 5))]
13600   rtx tmp_reg = operands[0];
13601   rtx mem = operands[2];
13602   rtx addr = XEXP (mem, 0);
13603   rtx add_op0, add_op1, new_addr;
13605   gcc_assert (GET_CODE (addr) == PLUS || GET_CODE (addr) == LO_SUM);
13606   add_op0 = XEXP (addr, 0);
13607   add_op1 = XEXP (addr, 1);
13608   gcc_assert (REG_P (add_op0));
13609   new_addr = gen_rtx_PLUS (Pmode, add_op0, tmp_reg);
13611   operands[4] = add_op1;
13612   operands[5] = change_address (mem, <MODE>mode, new_addr);
13615 ;; Optimize cases were want to do a D-form store on ISA 2.06/2.07 from an
13616 ;; Altivec register, and the register allocator has generated:
13617 ;;      XXLOR 0,32,32
13618 ;;      STFD 0,32(3)
13620 ;; and we change this to:
13621 ;;      LI 0,32
13622 ;;      STXSDX 32,3,9
13624 (define_peephole2
13625   [(match_scratch:P 0 "b")
13626    (set (match_operand:ALTIVEC_DFORM 1 "fpr_reg_operand")
13627         (match_operand:ALTIVEC_DFORM 2 "altivec_register_operand"))
13628    (set (match_operand:ALTIVEC_DFORM 3 "simple_offsettable_mem_operand")
13629         (match_dup 1))]
13630   "TARGET_VSX && !TARGET_P9_VECTOR && peep2_reg_dead_p (2, operands[1])"
13631   [(set (match_dup 0)
13632         (match_dup 4))
13633    (set (match_dup 5)
13634         (match_dup 2))]
13636   rtx tmp_reg = operands[0];
13637   rtx mem = operands[3];
13638   rtx addr = XEXP (mem, 0);
13639   rtx add_op0, add_op1, new_addr;
13641   gcc_assert (GET_CODE (addr) == PLUS || GET_CODE (addr) == LO_SUM);
13642   add_op0 = XEXP (addr, 0);
13643   add_op1 = XEXP (addr, 1);
13644   gcc_assert (REG_P (add_op0));
13645   new_addr = gen_rtx_PLUS (Pmode, add_op0, tmp_reg);
13647   operands[4] = add_op1;
13648   operands[5] = change_address (mem, <MODE>mode, new_addr);
13650    
13652 ;; Miscellaneous ISA 2.06 (power7) instructions
13653 (define_insn "addg6s"
13654   [(set (match_operand:SI 0 "register_operand" "=r")
13655         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
13656                     (match_operand:SI 2 "register_operand" "r")]
13657                    UNSPEC_ADDG6S))]
13658   "TARGET_POPCNTD"
13659   "addg6s %0,%1,%2"
13660   [(set_attr "type" "integer")])
13662 (define_insn "cdtbcd"
13663   [(set (match_operand:SI 0 "register_operand" "=r")
13664         (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
13665                    UNSPEC_CDTBCD))]
13666   "TARGET_POPCNTD"
13667   "cdtbcd %0,%1"
13668   [(set_attr "type" "integer")])
13670 (define_insn "cbcdtd"
13671   [(set (match_operand:SI 0 "register_operand" "=r")
13672         (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
13673                    UNSPEC_CBCDTD))]
13674   "TARGET_POPCNTD"
13675   "cbcdtd %0,%1"
13676   [(set_attr "type" "integer")])
13678 (define_int_iterator UNSPEC_DIV_EXTEND [UNSPEC_DIVE
13679                                         UNSPEC_DIVEU])
13681 (define_int_attr div_extend [(UNSPEC_DIVE       "e")
13682                              (UNSPEC_DIVEU      "eu")])
13684 (define_insn "div<div_extend>_<mode>"
13685   [(set (match_operand:GPR 0 "register_operand" "=r")
13686         (unspec:GPR [(match_operand:GPR 1 "register_operand" "r")
13687                      (match_operand:GPR 2 "register_operand" "r")]
13688                     UNSPEC_DIV_EXTEND))]
13689   "TARGET_POPCNTD"
13690   "div<wd><div_extend> %0,%1,%2"
13691   [(set_attr "type" "div")
13692    (set_attr "size" "<bits>")])
13695 ;; Pack/unpack 128-bit floating point types that take 2 scalar registers
13697 ; Type of the 64-bit part when packing/unpacking 128-bit floating point types
13698 (define_mode_attr FP128_64 [(TF "DF")
13699                             (IF "DF")
13700                             (TD "DI")
13701                             (KF "DI")])
13703 (define_expand "unpack<mode>"
13704   [(set (match_operand:<FP128_64> 0 "nonimmediate_operand")
13705         (unspec:<FP128_64>
13706          [(match_operand:FMOVE128 1 "register_operand")
13707           (match_operand:QI 2 "const_0_to_1_operand")]
13708          UNSPEC_UNPACK_128BIT))]
13709   "FLOAT128_2REG_P (<MODE>mode)"
13710   "")
13712 (define_insn_and_split "unpack<mode>_dm"
13713   [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m,d,r,m")
13714         (unspec:<FP128_64>
13715          [(match_operand:FMOVE128 1 "register_operand" "d,d,r,d,r")
13716           (match_operand:QI 2 "const_0_to_1_operand" "i,i,i,i,i")]
13717          UNSPEC_UNPACK_128BIT))]
13718   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE && FLOAT128_2REG_P (<MODE>mode)"
13719   "#"
13720   "&& reload_completed"
13721   [(set (match_dup 0) (match_dup 3))]
13723   unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
13725   if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
13726     {
13727       emit_note (NOTE_INSN_DELETED);
13728       DONE;
13729     }
13731   operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
13733   [(set_attr "type" "fp,fpstore,mffgpr,mftgpr,store")])
13735 (define_insn_and_split "unpack<mode>_nodm"
13736   [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m")
13737         (unspec:<FP128_64>
13738          [(match_operand:FMOVE128 1 "register_operand" "d,d")
13739           (match_operand:QI 2 "const_0_to_1_operand" "i,i")]
13740          UNSPEC_UNPACK_128BIT))]
13741   "(!TARGET_POWERPC64 || !TARGET_DIRECT_MOVE) && FLOAT128_2REG_P (<MODE>mode)"
13742   "#"
13743   "&& reload_completed"
13744   [(set (match_dup 0) (match_dup 3))]
13746   unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
13748   if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
13749     {
13750       emit_note (NOTE_INSN_DELETED);
13751       DONE;
13752     }
13754   operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
13756   [(set_attr "type" "fp,fpstore")])
13758 (define_insn_and_split "pack<mode>"
13759   [(set (match_operand:FMOVE128 0 "register_operand" "=&d")
13760         (unspec:FMOVE128
13761          [(match_operand:<FP128_64> 1 "register_operand" "d")
13762           (match_operand:<FP128_64> 2 "register_operand" "d")]
13763          UNSPEC_PACK_128BIT))]
13764   "FLOAT128_2REG_P (<MODE>mode)"
13765   "#"
13766   "&& reload_completed"
13767   [(set (match_dup 3) (match_dup 1))
13768    (set (match_dup 4) (match_dup 2))]
13770   unsigned dest_hi = REGNO (operands[0]);
13771   unsigned dest_lo = dest_hi + 1;
13773   gcc_assert (!IN_RANGE (REGNO (operands[1]), dest_hi, dest_lo));
13774   gcc_assert (!IN_RANGE (REGNO (operands[2]), dest_hi, dest_lo));
13776   operands[3] = gen_rtx_REG (<FP128_64>mode, dest_hi);
13777   operands[4] = gen_rtx_REG (<FP128_64>mode, dest_lo);
13779   [(set_attr "type" "fp")
13780    (set_attr "length" "8")])
13782 (define_insn "unpack<mode>"
13783   [(set (match_operand:DI 0 "register_operand" "=wa,wa")
13784         (unspec:DI [(match_operand:FMOVE128_VSX 1 "register_operand" "0,wa")
13785                     (match_operand:QI 2 "const_0_to_1_operand" "O,i")]
13786          UNSPEC_UNPACK_128BIT))]
13787   "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)"
13789   if (REGNO (operands[0]) == REGNO (operands[1]) && INTVAL (operands[2]) == 0)
13790     return ASM_COMMENT_START " xxpermdi to same register";
13792   operands[3] = GEN_INT (INTVAL (operands[2]) == 0 ? 0 : 3);
13793   return "xxpermdi %x0,%x1,%x1,%3";
13795   [(set_attr "type" "vecperm")])
13797 (define_insn "pack<mode>"
13798   [(set (match_operand:FMOVE128_VSX 0 "register_operand" "=wa")
13799         (unspec:FMOVE128_VSX
13800          [(match_operand:DI 1 "register_operand" "wa")
13801           (match_operand:DI 2 "register_operand" "wa")]
13802          UNSPEC_PACK_128BIT))]
13803   "TARGET_VSX"
13804   "xxpermdi %x0,%x1,%x2,0"
13805   [(set_attr "type" "vecperm")])
13809 ;; ISA 2.08 IEEE 128-bit floating point support.
13811 (define_insn "add<mode>3"
13812   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13813         (plus:IEEE128
13814          (match_operand:IEEE128 1 "altivec_register_operand" "v")
13815          (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13816   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13817   "xsaddqp %0,%1,%2"
13818   [(set_attr "type" "vecfloat")
13819    (set_attr "size" "128")])
13821 (define_insn "sub<mode>3"
13822   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13823         (minus:IEEE128
13824          (match_operand:IEEE128 1 "altivec_register_operand" "v")
13825          (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13826   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13827   "xssubqp %0,%1,%2"
13828   [(set_attr "type" "vecfloat")
13829    (set_attr "size" "128")])
13831 (define_insn "mul<mode>3"
13832   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13833         (mult:IEEE128
13834          (match_operand:IEEE128 1 "altivec_register_operand" "v")
13835          (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13836   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13837   "xsmulqp %0,%1,%2"
13838   [(set_attr "type" "qmul")
13839    (set_attr "size" "128")])
13841 (define_insn "div<mode>3"
13842   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13843         (div:IEEE128
13844          (match_operand:IEEE128 1 "altivec_register_operand" "v")
13845          (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13846   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13847   "xsdivqp %0,%1,%2"
13848   [(set_attr "type" "vecdiv")
13849    (set_attr "size" "128")])
13851 (define_insn "sqrt<mode>2"
13852   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13853         (sqrt:IEEE128
13854          (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
13855   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13856    "xssqrtqp %0,%1"
13857   [(set_attr "type" "vecdiv")
13858    (set_attr "size" "128")])
13860 (define_expand "copysign<mode>3"
13861   [(use (match_operand:IEEE128 0 "altivec_register_operand"))
13862    (use (match_operand:IEEE128 1 "altivec_register_operand"))
13863    (use (match_operand:IEEE128 2 "altivec_register_operand"))]
13864   "FLOAT128_IEEE_P (<MODE>mode)"
13866   if (TARGET_FLOAT128_HW)
13867     emit_insn (gen_copysign<mode>3_hard (operands[0], operands[1],
13868                                          operands[2]));
13869   else
13870     emit_insn (gen_copysign<mode>3_soft (operands[0], operands[1],
13871                                          operands[2]));
13872   DONE;
13875 (define_insn "copysign<mode>3_hard"
13876   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13877         (unspec:IEEE128
13878          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
13879           (match_operand:IEEE128 2 "altivec_register_operand" "v")]
13880          UNSPEC_COPYSIGN))]
13881   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13882    "xscpsgnqp %0,%2,%1"
13883   [(set_attr "type" "vecmove")
13884    (set_attr "size" "128")])
13886 (define_insn "copysign<mode>3_soft"
13887   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13888         (unspec:IEEE128
13889          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
13890           (match_operand:IEEE128 2 "altivec_register_operand" "v")]
13891          UNSPEC_COPYSIGN))
13892    (clobber (match_scratch:IEEE128 3 "=&v"))]
13893   "!TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13894    "xscpsgndp %x3,%x2,%x1\;xxpermdi %x0,%x3,%x1,1"
13895   [(set_attr "type" "veccomplex")
13896    (set_attr "length" "8")])
13898 (define_insn "neg<mode>2_hw"
13899   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13900         (neg:IEEE128
13901          (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
13902   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13903   "xsnegqp %0,%1"
13904   [(set_attr "type" "vecmove")
13905    (set_attr "size" "128")])
13908 (define_insn "abs<mode>2_hw"
13909   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13910         (abs:IEEE128
13911          (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
13912   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13913   "xsabsqp %0,%1"
13914   [(set_attr "type" "vecmove")
13915    (set_attr "size" "128")])
13918 (define_insn "*nabs<mode>2_hw"
13919   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13920         (neg:IEEE128
13921          (abs:IEEE128
13922           (match_operand:IEEE128 1 "altivec_register_operand" "v"))))]
13923   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13924   "xsnabsqp %0,%1"
13925   [(set_attr "type" "vecmove")
13926    (set_attr "size" "128")])
13928 ;; Initially don't worry about doing fusion
13929 (define_insn "fma<mode>4_hw"
13930   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13931         (fma:IEEE128
13932          (match_operand:IEEE128 1 "altivec_register_operand" "%v")
13933          (match_operand:IEEE128 2 "altivec_register_operand" "v")
13934          (match_operand:IEEE128 3 "altivec_register_operand" "0")))]
13935   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13936   "xsmaddqp %0,%1,%2"
13937   [(set_attr "type" "qmul")
13938    (set_attr "size" "128")])
13940 (define_insn "*fms<mode>4_hw"
13941   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13942         (fma:IEEE128
13943          (match_operand:IEEE128 1 "altivec_register_operand" "%v")
13944          (match_operand:IEEE128 2 "altivec_register_operand" "v")
13945          (neg:IEEE128
13946           (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
13947   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13948   "xsmsubqp %0,%1,%2"
13949   [(set_attr "type" "qmul")
13950    (set_attr "size" "128")])
13952 (define_insn "*nfma<mode>4_hw"
13953   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13954         (neg:IEEE128
13955          (fma:IEEE128
13956           (match_operand:IEEE128 1 "altivec_register_operand" "%v")
13957           (match_operand:IEEE128 2 "altivec_register_operand" "v")
13958           (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
13959   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13960   "xsnmaddqp %0,%1,%2"
13961   [(set_attr "type" "qmul")
13962    (set_attr "size" "128")])
13964 (define_insn "*nfms<mode>4_hw"
13965   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13966         (neg:IEEE128
13967          (fma:IEEE128
13968           (match_operand:IEEE128 1 "altivec_register_operand" "%v")
13969           (match_operand:IEEE128 2 "altivec_register_operand" "v")
13970           (neg:IEEE128
13971            (match_operand:IEEE128 3 "altivec_register_operand" "0")))))]
13972   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13973   "xsnmsubqp %0,%1,%2"
13974   [(set_attr "type" "qmul")
13975    (set_attr "size" "128")])
13977 (define_insn "extend<SFDF:mode><IEEE128:mode>2_hw"
13978   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13979         (float_extend:IEEE128
13980          (match_operand:SFDF 1 "altivec_register_operand" "v")))]
13981   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
13982   "xscvdpqp %0,%1"
13983   [(set_attr "type" "vecfloat")
13984    (set_attr "size" "128")])
13986 ;; Conversion between KFmode and TFmode if TFmode is ieee 128-bit floating
13987 ;; point is a simple copy.
13988 (define_insn_and_split "extendkftf2"
13989   [(set (match_operand:TF 0 "vsx_register_operand" "=wa,?wa")
13990         (float_extend:TF (match_operand:KF 1 "vsx_register_operand" "0,wa")))]
13991   "TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD"
13992   "@
13993    #
13994    xxlor %x0,%x1,%x1"
13995   "&& reload_completed  && REGNO (operands[0]) == REGNO (operands[1])"
13996   [(const_int 0)]
13998   emit_note (NOTE_INSN_DELETED);
13999   DONE;
14001   [(set_attr "type" "*,veclogical")
14002    (set_attr "length" "0,4")])
14004 (define_insn_and_split "trunctfkf2"
14005   [(set (match_operand:KF 0 "vsx_register_operand" "=wa,?wa")
14006         (float_extend:KF (match_operand:TF 1 "vsx_register_operand" "0,wa")))]
14007   "TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD"
14008   "@
14009    #
14010    xxlor %x0,%x1,%x1"
14011   "&& reload_completed  && REGNO (operands[0]) == REGNO (operands[1])"
14012   [(const_int 0)]
14014   emit_note (NOTE_INSN_DELETED);
14015   DONE;
14017   [(set_attr "type" "*,veclogical")
14018    (set_attr "length" "0,4")])
14020 (define_insn "trunc<mode>df2_hw"
14021   [(set (match_operand:DF 0 "altivec_register_operand" "=v")
14022         (float_truncate:DF
14023          (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14024   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14025   "xscvqpdp %0,%1"
14026   [(set_attr "type" "vecfloat")
14027    (set_attr "size" "128")])
14029 ;; There is no KFmode -> SFmode instruction. Preserve the accuracy by doing
14030 ;; the KFmode -> DFmode conversion using round to odd rather than the normal
14031 ;; conversion
14032 (define_insn_and_split "trunc<mode>sf2_hw"
14033   [(set (match_operand:SF 0 "vsx_register_operand" "=wy")
14034         (float_truncate:SF
14035          (match_operand:IEEE128 1 "altivec_register_operand" "v")))
14036    (clobber (match_scratch:DF 2 "=v"))]
14037   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14038   "#"
14039   "&& 1"
14040   [(set (match_dup 2)
14041         (unspec:DF [(match_dup 1)]
14042                    UNSPEC_TRUNC_ROUND_TO_ODD))
14043    (set (match_dup 0)
14044         (float_truncate:SF (match_dup 2)))]
14046   if (GET_CODE (operands[2]) == SCRATCH)
14047     operands[2] = gen_reg_rtx (DFmode);
14049   [(set_attr "type" "vecfloat")
14050    (set_attr "length" "8")])
14052 ;; Conversion between IEEE 128-bit and integer types
14054 ;; The fix function for DImode and SImode was declared earlier as a
14055 ;; define_expand.  It calls into rs6000_expand_float128_convert if we don't
14056 ;; have IEEE 128-bit hardware support.  QImode and HImode are not provided
14057 ;; unless we have the IEEE 128-bit hardware.
14059 ;; Unlike the code for converting SFmode/DFmode to QImode/HImode, we don't have
14060 ;; to provide a GPR target that used direct move and a conversion in the GPR
14061 ;; which works around QImode/HImode not being allowed in vector registers in
14062 ;; ISA 2.07 (power8).
14063 (define_insn "fix<uns>_<IEEE128:mode><SDI:mode>2_hw"
14064   [(set (match_operand:SDI 0 "altivec_register_operand" "=v")
14065         (any_fix:SDI (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14066   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14067   "xscvqp<su><wd>z %0,%1"
14068   [(set_attr "type" "vecfloat")
14069    (set_attr "size" "128")])
14071 (define_insn "fix<uns>_trunc<IEEE128:mode><QHI:mode>2"
14072   [(set (match_operand:QHI 0 "altivec_register_operand" "=v")
14073         (any_fix:QHI
14074          (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14075   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14076   "xscvqp<su>wz %0,%1"
14077   [(set_attr "type" "vecfloat")
14078    (set_attr "size" "128")])
14080 ;; Combiner patterns to prevent moving the result of converting an IEEE 128-bit
14081 ;; floating point value to 8/16/32-bit integer to GPR in order to save it.
14082 (define_insn_and_split "*fix<uns>_trunc<IEEE128:mode><QHSI:mode>2_mem"
14083   [(set (match_operand:QHSI 0 "memory_operand" "=Z")
14084         (any_fix:QHSI
14085          (match_operand:IEEE128 1 "altivec_register_operand" "v")))
14086    (clobber (match_scratch:QHSI 2 "=v"))]
14087   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14088   "#"
14089   "&& reload_completed"
14090   [(set (match_dup 2)
14091         (any_fix:QHSI (match_dup 1)))
14092    (set (match_dup 0)
14093         (match_dup 2))])
14095 (define_insn "float_<mode>di2_hw"
14096   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14097         (float:IEEE128 (match_operand:DI 1 "altivec_register_operand" "v")))]
14098   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14099   "xscvsdqp %0,%1"
14100   [(set_attr "type" "vecfloat")
14101    (set_attr "size" "128")])
14103 (define_insn_and_split "float_<mode>si2_hw"
14104   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14105         (float:IEEE128 (match_operand:SI 1 "nonimmediate_operand" "vrZ")))
14106    (clobber (match_scratch:DI 2 "=v"))]
14107   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14108   "#"
14109   "&& 1"
14110   [(set (match_dup 2)
14111         (sign_extend:DI (match_dup 1)))
14112    (set (match_dup 0)
14113         (float:IEEE128 (match_dup 2)))]
14115   if (GET_CODE (operands[2]) == SCRATCH)
14116     operands[2] = gen_reg_rtx (DImode);
14118   if (MEM_P (operands[1]))
14119     operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
14122 (define_insn_and_split "float<QHI:mode><IEEE128:mode>2"
14123   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v")
14124         (float:IEEE128 (match_operand:QHI 1 "nonimmediate_operand" "v,r,Z")))
14125    (clobber (match_scratch:DI 2 "=X,r,X"))]
14126   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14127   "#"
14128   "&& reload_completed"
14129   [(const_int 0)]
14131   rtx dest = operands[0];
14132   rtx src = operands[1];
14133   rtx dest_di = gen_rtx_REG (DImode, REGNO (dest));
14135   if (altivec_register_operand (src, <QHI:MODE>mode))
14136     emit_insn (gen_extend<QHI:mode>di2 (dest_di, src));
14137   else if (int_reg_operand (src, <QHI:MODE>mode))
14138     {
14139       rtx ext_di = operands[2];
14140       emit_insn (gen_extend<QHI:mode>di2 (ext_di, src));
14141       emit_move_insn (dest_di, ext_di);
14142     }
14143   else if (MEM_P (src))
14144     {
14145       rtx dest_qhi = gen_rtx_REG (<QHI:MODE>mode, REGNO (dest));
14146       emit_move_insn (dest_qhi, src);
14147       emit_insn (gen_extend<QHI:mode>di2 (dest_di, dest_qhi));
14148     }
14149   else
14150     gcc_unreachable ();
14152   emit_insn (gen_float_<IEEE128:mode>di2_hw (dest, dest_di));
14153   DONE;
14155   [(set_attr "length" "8,12,12")
14156    (set_attr "type" "vecfloat")
14157    (set_attr "size" "128")])
14159 (define_insn "floatuns_<mode>di2_hw"
14160   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14161         (unsigned_float:IEEE128
14162          (match_operand:DI 1 "altivec_register_operand" "v")))]
14163   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14164   "xscvudqp %0,%1"
14165   [(set_attr "type" "vecfloat")
14166    (set_attr "size" "128")])
14168 (define_insn_and_split "floatuns_<mode>si2_hw"
14169   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14170         (unsigned_float:IEEE128
14171          (match_operand:SI 1 "nonimmediate_operand" "vrZ")))
14172    (clobber (match_scratch:DI 2 "=v"))]
14173   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14174   "#"
14175   "&& 1"
14176   [(set (match_dup 2)
14177         (zero_extend:DI (match_dup 1)))
14178    (set (match_dup 0)
14179         (float:IEEE128 (match_dup 2)))]
14181   if (GET_CODE (operands[2]) == SCRATCH)
14182     operands[2] = gen_reg_rtx (DImode);
14184   if (MEM_P (operands[1]))
14185     operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
14188 (define_insn_and_split "floatuns<QHI:mode><IEEE128:mode>2"
14189   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v")
14190         (unsigned_float:IEEE128
14191          (match_operand:QHI 1 "nonimmediate_operand" "v,r,Z")))
14192    (clobber (match_scratch:DI 2 "=X,r,X"))]
14193   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14194   "#"
14195   "&& reload_completed"
14196   [(const_int 0)]
14198   rtx dest = operands[0];
14199   rtx src = operands[1];
14200   rtx dest_di = gen_rtx_REG (DImode, REGNO (dest));
14202   if (altivec_register_operand (src, <QHI:MODE>mode) || MEM_P (src))
14203     emit_insn (gen_zero_extend<QHI:mode>di2 (dest_di, src));
14204   else if (int_reg_operand (src, <QHI:MODE>mode))
14205     {
14206       rtx ext_di = operands[2];
14207       emit_insn (gen_zero_extend<QHI:mode>di2 (ext_di, src));
14208       emit_move_insn (dest_di, ext_di);
14209     }
14210   else
14211     gcc_unreachable ();
14213   emit_insn (gen_floatuns_<IEEE128:mode>di2_hw (dest, dest_di));
14214   DONE;
14216   [(set_attr "length" "8,12,8")
14217    (set_attr "type" "vecfloat")
14218    (set_attr "size" "128")])
14220 ;; IEEE 128-bit round to integer built-in functions
14221 (define_insn "floor<mode>2"
14222   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14223         (unspec:IEEE128
14224          [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14225          UNSPEC_FRIM))]
14226   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14227   "xsrqpi 1,%0,%1,3"
14228   [(set_attr "type" "vecfloat")
14229    (set_attr "size" "128")])
14231 (define_insn "ceil<mode>2"
14232   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14233         (unspec:IEEE128
14234          [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14235          UNSPEC_FRIP))]
14236   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14237   "xsrqpi 1,%0,%1,2"
14238   [(set_attr "type" "vecfloat")
14239    (set_attr "size" "128")])
14241 (define_insn "btrunc<mode>2"
14242   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14243         (unspec:IEEE128
14244          [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14245          UNSPEC_FRIZ))]
14246   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14247   "xsrqpi 1,%0,%1,1"
14248   [(set_attr "type" "vecfloat")
14249    (set_attr "size" "128")])
14251 (define_insn "round<mode>2"
14252   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14253         (unspec:IEEE128
14254          [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14255          UNSPEC_FRIN))]
14256   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14257   "xsrqpi 0,%0,%1,0"
14258   [(set_attr "type" "vecfloat")
14259    (set_attr "size" "128")])
14261 ;; IEEE 128-bit instructions with round to odd semantics
14262 (define_insn "add<mode>3_odd"
14263   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14264         (unspec:IEEE128
14265          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14266           (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14267          UNSPEC_ADD_ROUND_TO_ODD))]
14268   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14269   "xsaddqpo %0,%1,%2"
14270   [(set_attr "type" "vecfloat")
14271    (set_attr "size" "128")])
14273 (define_insn "sub<mode>3_odd"
14274   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14275         (unspec:IEEE128
14276          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14277           (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14278          UNSPEC_SUB_ROUND_TO_ODD))]
14279   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14280   "xssubqpo %0,%1,%2"
14281   [(set_attr "type" "vecfloat")
14282    (set_attr "size" "128")])
14284 (define_insn "mul<mode>3_odd"
14285   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14286         (unspec:IEEE128
14287          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14288           (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14289          UNSPEC_MUL_ROUND_TO_ODD))]
14290   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14291   "xsmulqpo %0,%1,%2"
14292   [(set_attr "type" "qmul")
14293    (set_attr "size" "128")])
14295 (define_insn "div<mode>3_odd"
14296   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14297         (unspec:IEEE128
14298          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14299           (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14300          UNSPEC_DIV_ROUND_TO_ODD))]
14301   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14302   "xsdivqpo %0,%1,%2"
14303   [(set_attr "type" "vecdiv")
14304    (set_attr "size" "128")])
14306 (define_insn "sqrt<mode>2_odd"
14307   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14308         (unspec:IEEE128
14309          [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14310          UNSPEC_SQRT_ROUND_TO_ODD))]
14311   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14312    "xssqrtqpo %0,%1"
14313   [(set_attr "type" "vecdiv")
14314    (set_attr "size" "128")])
14316 (define_insn "fma<mode>4_odd"
14317   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14318         (unspec:IEEE128
14319          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14320           (match_operand:IEEE128 2 "altivec_register_operand" "v")
14321           (match_operand:IEEE128 3 "altivec_register_operand" "0")]
14322          UNSPEC_FMA_ROUND_TO_ODD))]
14323   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14324   "xsmaddqpo %0,%1,%2"
14325   [(set_attr "type" "qmul")
14326    (set_attr "size" "128")])
14328 (define_insn "*fms<mode>4_odd"
14329   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14330         (unspec:IEEE128
14331          [(match_operand:IEEE128 1 "altivec_register_operand" "%v")
14332           (match_operand:IEEE128 2 "altivec_register_operand" "v")
14333           (neg:IEEE128
14334            (match_operand:IEEE128 3 "altivec_register_operand" "0"))]
14335          UNSPEC_FMA_ROUND_TO_ODD))]
14336   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14337   "xsmsubqpo %0,%1,%2"
14338   [(set_attr "type" "qmul")
14339    (set_attr "size" "128")])
14341 (define_insn "*nfma<mode>4_odd"
14342   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14343         (neg:IEEE128
14344          (unspec:IEEE128
14345           [(match_operand:IEEE128 1 "altivec_register_operand" "%v")
14346            (match_operand:IEEE128 2 "altivec_register_operand" "v")
14347            (match_operand:IEEE128 3 "altivec_register_operand" "0")]
14348           UNSPEC_FMA_ROUND_TO_ODD)))]
14349   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14350   "xsnmaddqpo %0,%1,%2"
14351   [(set_attr "type" "qmul")
14352    (set_attr "size" "128")])
14354 (define_insn "*nfms<mode>4_odd"
14355   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14356         (neg:IEEE128
14357          (unspec:IEEE128
14358           [(match_operand:IEEE128 1 "altivec_register_operand" "%v")
14359            (match_operand:IEEE128 2 "altivec_register_operand" "v")
14360            (neg:IEEE128
14361             (match_operand:IEEE128 3 "altivec_register_operand" "0"))]
14362           UNSPEC_FMA_ROUND_TO_ODD)))]
14363   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14364   "xsnmsubqpo %0,%1,%2"
14365   [(set_attr "type" "qmul")
14366    (set_attr "size" "128")])
14368 (define_insn "trunc<mode>df2_odd"
14369   [(set (match_operand:DF 0 "vsx_register_operand" "=v")
14370         (unspec:DF [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14371                    UNSPEC_TRUNC_ROUND_TO_ODD))]
14372   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14373   "xscvqpdpo %0,%1"
14374   [(set_attr "type" "vecfloat")
14375    (set_attr "size" "128")])
14377 ;; IEEE 128-bit comparisons
14378 (define_insn "*cmp<mode>_hw"
14379   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
14380         (compare:CCFP (match_operand:IEEE128 1 "altivec_register_operand" "v")
14381                       (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14382   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14383    "xscmpuqp %0,%1,%2"
14384   [(set_attr "type" "veccmp")
14385    (set_attr "size" "128")])
14389 (include "sync.md")
14390 (include "vector.md")
14391 (include "vsx.md")
14392 (include "altivec.md")
14393 (include "dfp.md")
14394 (include "crypto.md")
14395 (include "htm.md")