altivec.md (altivec_mov<mode>, [...]): Change the RTL attribute "length" from "4...
[official-gcc.git] / gcc / config / rs6000 / rs6000.md
blob503f91aacf045cab4fa48c3158a055e58bb44f6b
1 ;; Machine description for IBM RISC System 6000 (POWER) for GNU C compiler
2 ;; Copyright (C) 1990-2019 Free Software Foundation, Inc.
3 ;; Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
5 ;; This file is part of GCC.
7 ;; GCC is free software; you can redistribute it and/or modify it
8 ;; under the terms of the GNU General Public License as published
9 ;; by the Free Software Foundation; either version 3, or (at your
10 ;; option) any later version.
12 ;; GCC is distributed in the hope that it will be useful, but WITHOUT
13 ;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 ;; or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
15 ;; License for more details.
17 ;; You should have received a copy of the GNU General Public License
18 ;; along with GCC; see the file COPYING3.  If not see
19 ;; <http://www.gnu.org/licenses/>.
21 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
24 ;; REGNOS
27 (define_constants
28   [(FIRST_GPR_REGNO             0)
29    (STACK_POINTER_REGNUM        1)
30    (TOC_REGNUM                  2)
31    (STATIC_CHAIN_REGNUM         11)
32    (HARD_FRAME_POINTER_REGNUM   31)
33    (LAST_GPR_REGNO              31)
34    (FIRST_FPR_REGNO             32)
35    (LAST_FPR_REGNO              63)
36    (FIRST_ALTIVEC_REGNO         64)
37    (LAST_ALTIVEC_REGNO          95)
38    (LR_REGNO                    96)
39    (CTR_REGNO                   97)
40    (CA_REGNO                    98)
41    (ARG_POINTER_REGNUM          99)
42    (CR0_REGNO                   100)
43    (CR1_REGNO                   101)
44    (CR2_REGNO                   102)
45    (CR3_REGNO                   103)
46    (CR4_REGNO                   104)
47    (CR5_REGNO                   105)
48    (CR6_REGNO                   106)
49    (CR7_REGNO                   107)
50    (MAX_CR_REGNO                107)
51    (VRSAVE_REGNO                108)
52    (VSCR_REGNO                  109)
53    (FRAME_POINTER_REGNUM        110)
54   ])
57 ;; UNSPEC usage
60 (define_c_enum "unspec"
61   [UNSPEC_FRSP                  ; frsp for POWER machines
62    UNSPEC_PROBE_STACK           ; probe stack memory reference
63    UNSPEC_TOCPTR                ; address of a word pointing to the TOC
64    UNSPEC_TOC                   ; address of the TOC (more-or-less)
65    UNSPEC_TOCSLOT               ; offset from r1 of toc pointer save slot
66    UNSPEC_MOVSI_GOT
67    UNSPEC_MV_CR_OV              ; move_from_CR_ov_bit
68    UNSPEC_FCTIWZ
69    UNSPEC_FRIM
70    UNSPEC_FRIN
71    UNSPEC_FRIP
72    UNSPEC_FRIZ
73    UNSPEC_XSRDPI
74    UNSPEC_LD_MPIC               ; load_macho_picbase
75    UNSPEC_RELD_MPIC             ; re-load_macho_picbase
76    UNSPEC_MPIC_CORRECT          ; macho_correct_pic
77    UNSPEC_TLSGD
78    UNSPEC_TLSLD
79    UNSPEC_TLS_GET_ADDR
80    UNSPEC_MOVESI_FROM_CR
81    UNSPEC_MOVESI_TO_CR
82    UNSPEC_TLSDTPREL
83    UNSPEC_TLSDTPRELHA
84    UNSPEC_TLSDTPRELLO
85    UNSPEC_TLSGOTDTPREL
86    UNSPEC_TLSTPREL
87    UNSPEC_TLSTPRELHA
88    UNSPEC_TLSTPRELLO
89    UNSPEC_TLSGOTTPREL
90    UNSPEC_TLSTLS
91    UNSPEC_FIX_TRUNC_TF          ; fadd, rounding towards zero
92    UNSPEC_STFIWX
93    UNSPEC_POPCNTB
94    UNSPEC_FRES
95    UNSPEC_SP_SET
96    UNSPEC_SP_TEST
97    UNSPEC_SYNC
98    UNSPEC_LWSYNC
99    UNSPEC_SYNC_OP
100    UNSPEC_ATOMIC
101    UNSPEC_CMPXCHG
102    UNSPEC_XCHG
103    UNSPEC_AND
104    UNSPEC_DLMZB
105    UNSPEC_DLMZB_CR
106    UNSPEC_DLMZB_STRLEN
107    UNSPEC_RSQRT
108    UNSPEC_TOCREL
109    UNSPEC_MACHOPIC_OFFSET
110    UNSPEC_BPERM
111    UNSPEC_COPYSIGN
112    UNSPEC_PARITY
113    UNSPEC_CMPB
114    UNSPEC_FCTIW
115    UNSPEC_FCTID
116    UNSPEC_LFIWAX
117    UNSPEC_LFIWZX
118    UNSPEC_FCTIWUZ
119    UNSPEC_NOP
120    UNSPEC_GRP_END_NOP
121    UNSPEC_P8V_FMRGOW
122    UNSPEC_P8V_MTVSRWZ
123    UNSPEC_P8V_RELOAD_FROM_GPR
124    UNSPEC_P8V_MTVSRD
125    UNSPEC_P8V_XXPERMDI
126    UNSPEC_P8V_RELOAD_FROM_VSX
127    UNSPEC_ADDG6S
128    UNSPEC_CDTBCD
129    UNSPEC_CBCDTD
130    UNSPEC_DIVE
131    UNSPEC_DIVEU
132    UNSPEC_UNPACK_128BIT
133    UNSPEC_PACK_128BIT
134    UNSPEC_LSQ
135    UNSPEC_FUSION_GPR
136    UNSPEC_STACK_CHECK
137    UNSPEC_ADD_ROUND_TO_ODD
138    UNSPEC_SUB_ROUND_TO_ODD
139    UNSPEC_MUL_ROUND_TO_ODD
140    UNSPEC_DIV_ROUND_TO_ODD
141    UNSPEC_FMA_ROUND_TO_ODD
142    UNSPEC_SQRT_ROUND_TO_ODD
143    UNSPEC_TRUNC_ROUND_TO_ODD
144    UNSPEC_SIGNBIT
145    UNSPEC_SF_FROM_SI
146    UNSPEC_SI_FROM_SF
147    UNSPEC_PLTSEQ
148    UNSPEC_PLT16_HA
149    UNSPEC_PLT16_LO
150    UNSPEC_PLT_PCREL
151   ])
154 ;; UNSPEC_VOLATILE usage
157 (define_c_enum "unspecv"
158   [UNSPECV_BLOCK
159    UNSPECV_LL                   ; load-locked
160    UNSPECV_SC                   ; store-conditional
161    UNSPECV_PROBE_STACK_RANGE    ; probe range of stack addresses
162    UNSPECV_EH_RR                ; eh_reg_restore
163    UNSPECV_ISYNC                ; isync instruction
164    UNSPECV_MFTB                 ; move from time base
165    UNSPECV_NLGR                 ; non-local goto receiver
166    UNSPECV_MFFS                 ; Move from FPSCR
167    UNSPECV_MFFSL                ; Move from FPSCR light instruction version
168    UNSPECV_MFFSCRN              ; Move from FPSCR float rounding mode
169    UNSPECV_MFFSCDRN             ; Move from FPSCR decimal float rounding mode
170    UNSPECV_MTFSF                ; Move to FPSCR Fields 8 to 15
171    UNSPECV_MTFSF_HI             ; Move to FPSCR Fields 0 to 7
172    UNSPECV_MTFSB0               ; Set FPSCR Field bit to 0
173    UNSPECV_MTFSB1               ; Set FPSCR Field bit to 1
174    UNSPECV_SPLIT_STACK_RETURN   ; A camouflaged return
175    UNSPECV_SPEC_BARRIER         ; Speculation barrier
176   ])
178 ; The three different kinds of epilogue.
179 (define_enum "epilogue_type" [normal sibcall eh_return])
181 ;; Define an insn type attribute.  This is used in function unit delay
182 ;; computations.
183 (define_attr "type"
184   "integer,two,three,
185    add,logical,shift,insert,
186    mul,halfmul,div,
187    exts,cntlz,popcnt,isel,
188    load,store,fpload,fpstore,vecload,vecstore,
189    cmp,
190    branch,jmpreg,mfjmpr,mtjmpr,trap,isync,sync,load_l,store_c,
191    cr_logical,mfcr,mfcrf,mtcr,
192    fpcompare,fp,fpsimple,dmul,qmul,sdiv,ddiv,ssqrt,dsqrt,
193    vecsimple,veccomplex,vecdiv,veccmp,veccmpsimple,vecperm,
194    vecfloat,vecfdiv,vecdouble,mffgpr,mftgpr,crypto,
195    veclogical,veccmpfx,vecexts,vecmove,
196    htm,htmsimple,dfp"
197   (const_string "integer"))
199 ;; What data size does this instruction work on?
200 ;; This is used for insert, mul and others as necessary.
201 (define_attr "size" "8,16,32,64,128" (const_string "32"))
203 ;; What is the insn_cost for this insn?  The target hook can still override
204 ;; this.  For optimizing for size the "length" attribute is used instead.
205 (define_attr "cost" "" (const_int 0))
207 ;; Is this instruction record form ("dot", signed compare to 0, writing CR0)?
208 ;; This is used for add, logical, shift, exts, mul.
209 (define_attr "dot" "no,yes" (const_string "no"))
211 ;; Does this instruction sign-extend its result?
212 ;; This is used for load insns.
213 (define_attr "sign_extend" "no,yes" (const_string "no"))
215 ;; Does this cr_logical instruction have three operands?  That is, BT != BB.
216 (define_attr "cr_logical_3op" "no,yes" (const_string "no"))
218 ;; Does this instruction use indexed (that is, reg+reg) addressing?
219 ;; This is used for load and store insns.  If operand 0 or 1 is a MEM
220 ;; it is automatically set based on that.  If a load or store instruction
221 ;; has fewer than two operands it needs to set this attribute manually
222 ;; or the compiler will crash.
223 (define_attr "indexed" "no,yes"
224   (if_then_else (ior (match_operand 0 "indexed_address_mem")
225                      (match_operand 1 "indexed_address_mem"))
226                 (const_string "yes")
227                 (const_string "no")))
229 ;; Does this instruction use update addressing?
230 ;; This is used for load and store insns.  See the comments for "indexed".
231 (define_attr "update" "no,yes"
232   (if_then_else (ior (match_operand 0 "update_address_mem")
233                      (match_operand 1 "update_address_mem"))
234                 (const_string "yes")
235                 (const_string "no")))
237 ;; Is this instruction using operands[2] as shift amount, and can that be a
238 ;; register?
239 ;; This is used for shift insns.
240 (define_attr "maybe_var_shift" "no,yes" (const_string "no"))
242 ;; Is this instruction using a shift amount from a register?
243 ;; This is used for shift insns.
244 (define_attr "var_shift" "no,yes"
245   (if_then_else (and (eq_attr "type" "shift")
246                      (eq_attr "maybe_var_shift" "yes"))
247                 (if_then_else (match_operand 2 "gpc_reg_operand")
248                               (const_string "yes")
249                               (const_string "no"))
250                 (const_string "no")))
252 ;; Is copying of this instruction disallowed?
253 (define_attr "cannot_copy" "no,yes" (const_string "no"))
255 ;; Length of the instruction (in bytes).
256 (define_attr "length" "" (const_int 4))
258 ;; Processor type -- this attribute must exactly match the processor_type
259 ;; enumeration in rs6000-opts.h.
260 (define_attr "cpu"
261   "ppc601,ppc603,ppc604,ppc604e,ppc620,ppc630,
262    ppc750,ppc7400,ppc7450,
263    ppc403,ppc405,ppc440,ppc476,
264    ppc8540,ppc8548,ppce300c2,ppce300c3,ppce500mc,ppce500mc64,ppce5500,ppce6500,
265    power4,power5,power6,power7,power8,power9,future,
266    rs64a,mpccore,cell,ppca2,titan"
267   (const (symbol_ref "(enum attr_cpu) rs6000_tune")))
269 ;; The ISA we implement.
270 (define_attr "isa" "any,p5,p6,p7,p7v,p8v,p9v,p9kf,p9tf,fut"
271   (const_string "any"))
273 ;; Is this alternative enabled for the current CPU/ISA/etc.?
274 (define_attr "enabled" ""
275   (cond
276     [(eq_attr "isa" "any")
277      (const_int 1)
279      (and (eq_attr "isa" "p5")
280           (match_test "TARGET_POPCNTB"))
281      (const_int 1)
283      (and (eq_attr "isa" "p6")
284           (match_test "TARGET_CMPB"))
285      (const_int 1)
287      (and (eq_attr "isa" "p7")
288           (match_test "TARGET_POPCNTD"))
289      (const_int 1)
291      (and (eq_attr "isa" "p7v")
292           (match_test "TARGET_VSX"))
293      (const_int 1)
295      (and (eq_attr "isa" "p8v")
296           (match_test "TARGET_P8_VECTOR"))
297      (const_int 1)
299      (and (eq_attr "isa" "p9v")
300           (match_test "TARGET_P9_VECTOR"))
301      (const_int 1)
303      (and (eq_attr "isa" "p9kf")
304           (match_test "TARGET_FLOAT128_TYPE"))
305      (const_int 1)
307      (and (eq_attr "isa" "p9tf")
308           (match_test "FLOAT128_VECTOR_P (TFmode)"))
309      (const_int 1)
311      (and (eq_attr "isa" "fut")
312           (match_test "TARGET_FUTURE"))
313      (const_int 1)
314     ] (const_int 0)))
316 ;; If this instruction is microcoded on the CELL processor
317 ; The default for load extended, the recorded instructions and rotate/shifts by a variable is always microcoded
318 (define_attr "cell_micro" "not,conditional,always"
319   (if_then_else (ior (and (eq_attr "type" "shift,exts,mul")
320                           (eq_attr "dot" "yes"))
321                      (and (eq_attr "type" "load")
322                           (eq_attr "sign_extend" "yes"))
323                      (and (eq_attr "type" "shift")
324                           (eq_attr "var_shift" "yes")))
325                 (const_string "always")
326                 (const_string "not")))
328 (automata_option "ndfa")
330 (include "rs64.md")
331 (include "mpc.md")
332 (include "40x.md")
333 (include "440.md")
334 (include "476.md")
335 (include "601.md")
336 (include "603.md")
337 (include "6xx.md")
338 (include "7xx.md")
339 (include "7450.md")
340 (include "8540.md")
341 (include "e300c2c3.md")
342 (include "e500mc.md")
343 (include "e500mc64.md")
344 (include "e5500.md")
345 (include "e6500.md")
346 (include "power4.md")
347 (include "power5.md")
348 (include "power6.md")
349 (include "power7.md")
350 (include "power8.md")
351 (include "power9.md")
352 (include "cell.md")
353 (include "a2.md")
354 (include "titan.md")
356 (include "predicates.md")
357 (include "constraints.md")
359 (include "darwin.md")
362 ;; Mode iterators
364 ; This mode iterator allows :GPR to be used to indicate the allowable size
365 ; of whole values in GPRs.
366 (define_mode_iterator GPR [SI (DI "TARGET_POWERPC64")])
368 ; And again, for patterns that need two (potentially) different integer modes.
369 (define_mode_iterator GPR2 [SI (DI "TARGET_POWERPC64")])
371 ; Any supported integer mode.
372 (define_mode_iterator INT [QI HI SI DI TI PTI])
374 ; Any supported integer mode that fits in one register.
375 (define_mode_iterator INT1 [QI HI SI (DI "TARGET_POWERPC64")])
377 ; Integer modes supported in VSX registers with ISA 3.0 instructions
378 (define_mode_iterator INT_ISA3 [QI HI SI DI])
380 ; Everything we can extend QImode to.
381 (define_mode_iterator EXTQI [SI (DI "TARGET_POWERPC64")])
383 ; Everything we can extend HImode to.
384 (define_mode_iterator EXTHI [SI (DI "TARGET_POWERPC64")])
386 ; Everything we can extend SImode to.
387 (define_mode_iterator EXTSI [(DI "TARGET_POWERPC64")])
389 ; QImode or HImode for small integer moves and small atomic ops
390 (define_mode_iterator QHI [QI HI])
392 ; QImode, HImode, SImode for fused ops only for GPR loads
393 (define_mode_iterator QHSI [QI HI SI])
395 ; HImode or SImode for sign extended fusion ops
396 (define_mode_iterator HSI [HI SI])
398 ; SImode or DImode, even if DImode doesn't fit in GPRs.
399 (define_mode_iterator SDI [SI DI])
401 ; The size of a pointer.  Also, the size of the value that a record-condition
402 ; (one with a '.') will compare; and the size used for arithmetic carries.
403 (define_mode_iterator P [(SI "TARGET_32BIT") (DI "TARGET_64BIT")])
405 ; Iterator to add PTImode along with TImode (TImode can go in VSX registers,
406 ; PTImode is GPR only)
407 (define_mode_iterator TI2 [TI PTI])
409 ; Any hardware-supported floating-point mode
410 (define_mode_iterator FP [
411   (SF "TARGET_HARD_FLOAT")
412   (DF "TARGET_HARD_FLOAT")
413   (TF "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128")
414   (IF "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128")
415   (KF "TARGET_FLOAT128_TYPE")
416   (DD "TARGET_DFP")
417   (TD "TARGET_DFP")])
419 ; Any fma capable floating-point mode.
420 (define_mode_iterator FMA_F [
421   (SF "TARGET_HARD_FLOAT")
422   (DF "TARGET_HARD_FLOAT || VECTOR_UNIT_VSX_P (DFmode)")
423   (V4SF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)")
424   (V2DF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V2DFmode)")
425   (KF "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (KFmode)")
426   (TF "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (TFmode)")
427   ])
429 ; Floating point move iterators to combine binary and decimal moves
430 (define_mode_iterator FMOVE32 [SF SD])
431 (define_mode_iterator FMOVE64 [DF DD])
432 (define_mode_iterator FMOVE64X [DI DF DD])
433 (define_mode_iterator FMOVE128 [(TF "TARGET_LONG_DOUBLE_128")
434                                 (IF "FLOAT128_IBM_P (IFmode)")
435                                 (TD "TARGET_HARD_FLOAT")])
437 (define_mode_iterator FMOVE128_FPR [(TF "FLOAT128_2REG_P (TFmode)")
438                                     (IF "FLOAT128_2REG_P (IFmode)")
439                                     (TD "TARGET_HARD_FLOAT")])
441 ; Iterators for 128 bit types for direct move
442 (define_mode_iterator FMOVE128_GPR [TI
443                                     V16QI
444                                     V8HI
445                                     V4SI
446                                     V4SF
447                                     V2DI
448                                     V2DF
449                                     V1TI
450                                     (KF    "FLOAT128_VECTOR_P (KFmode)")
451                                     (TF    "FLOAT128_VECTOR_P (TFmode)")])
453 ; Iterator for 128-bit VSX types for pack/unpack
454 (define_mode_iterator FMOVE128_VSX [V1TI KF])
456 ; Iterators for converting to/from TFmode
457 (define_mode_iterator IFKF [IF KF])
459 ; Constraints for moving IF/KFmode.
460 (define_mode_attr IFKF_reg [(IF "d") (KF "wa")])
462 ; Whether a floating point move is ok, don't allow SD without hardware FP
463 (define_mode_attr fmove_ok [(SF "")
464                             (DF "")
465                             (SD "TARGET_HARD_FLOAT")
466                             (DD "")])
468 ; Convert REAL_VALUE to the appropriate bits
469 (define_mode_attr real_value_to_target [(SF "REAL_VALUE_TO_TARGET_SINGLE")
470                                         (DF "REAL_VALUE_TO_TARGET_DOUBLE")
471                                         (SD "REAL_VALUE_TO_TARGET_DECIMAL32")
472                                         (DD "REAL_VALUE_TO_TARGET_DECIMAL64")])
474 ; Whether 0.0 has an all-zero bit pattern
475 (define_mode_attr zero_fp [(SF "j")
476                            (DF "j")
477                            (TF "j")
478                            (IF "j")
479                            (KF "j")
480                            (SD "wn")
481                            (DD "wn")
482                            (TD "wn")])
484 ; Definitions for 64-bit VSX
485 (define_mode_attr f64_vsx [(DF "wa") (DD "wn")])
487 ; Definitions for 64-bit direct move
488 (define_mode_attr f64_dm  [(DF "wa") (DD "d")])
490 ; Definitions for 64-bit use of altivec registers
491 (define_mode_attr f64_av  [(DF "v") (DD "wn")])
493 ; Definitions for 64-bit access to ISA 3.0 (power9) vector
494 (define_mode_attr f64_p9  [(DF "v") (DD "wn")])
496 ; These modes do not fit in integer registers in 32-bit mode.
497 (define_mode_iterator DIFD [DI DF DD])
499 ; Iterator for reciprocal estimate instructions
500 (define_mode_iterator RECIPF [SF DF V4SF V2DF])
502 ; SFmode or DFmode.
503 (define_mode_iterator SFDF [SF DF])
505 ; And again, for when we need two FP modes in a pattern.
506 (define_mode_iterator SFDF2 [SF DF])
508 ; A generic s/d attribute, for sp/dp for example.
509 (define_mode_attr sd [(SF   "s") (DF   "d")
510                       (V4SF "s") (V2DF "d")])
512 ; "s" or nothing, for fmuls/fmul for example.
513 (define_mode_attr s [(SF "s") (DF "")])
515 ; Iterator for 128-bit floating point that uses the IBM double-double format
516 (define_mode_iterator IBM128 [(IF "FLOAT128_IBM_P (IFmode)")
517                               (TF "FLOAT128_IBM_P (TFmode)")])
519 ; Iterator for 128-bit floating point that uses IEEE 128-bit float
520 (define_mode_iterator IEEE128 [(KF "FLOAT128_IEEE_P (KFmode)")
521                                (TF "FLOAT128_IEEE_P (TFmode)")])
523 ; Iterator for 128-bit floating point
524 (define_mode_iterator FLOAT128 [(KF "TARGET_FLOAT128_TYPE")
525                                 (IF "TARGET_FLOAT128_TYPE")
526                                 (TF "TARGET_LONG_DOUBLE_128")])
528 ; Iterator for signbit on 64-bit machines with direct move
529 (define_mode_iterator SIGNBIT [(KF "FLOAT128_VECTOR_P (KFmode)")
530                                (TF "FLOAT128_VECTOR_P (TFmode)")])
532 ; Iterator for ISA 3.0 supported floating point types
533 (define_mode_iterator FP_ISA3 [SF DF])
535 ; SF/DF constraint for arithmetic on traditional floating point registers
536 (define_mode_attr Ff            [(SF "f") (DF "d") (DI "d")])
538 ; SF/DF constraint for arithmetic on VSX registers using instructions added in
539 ; ISA 2.06 (power7).  This includes instructions that normally target DF mode,
540 ; but are used on SFmode, since internally SFmode values are kept in the DFmode
541 ; format.
542 (define_mode_attr Fv            [(SF "wa") (DF "wa") (DI "wa")])
544 ; Which isa is needed for those float instructions?
545 (define_mode_attr Fisa          [(SF "p8v")  (DF "*") (DI "*")])
547 ; FRE/FRES support
548 (define_mode_attr Ffre          [(SF "fres") (DF "fre")])
549 (define_mode_attr FFRE          [(SF "FRES") (DF "FRE")])
551 ; Conditional returns.
552 (define_code_iterator any_return [return simple_return])
553 (define_code_attr return_pred [(return "direct_return ()")
554                                (simple_return "1")])
555 (define_code_attr return_str [(return "") (simple_return "simple_")])
557 ; Logical operators.
558 (define_code_iterator iorxor            [ior xor])
559 (define_code_iterator and_ior_xor       [and ior xor])
561 ; Signed/unsigned variants of ops.
562 (define_code_iterator any_extend        [sign_extend zero_extend])
563 (define_code_iterator any_fix           [fix unsigned_fix])
564 (define_code_iterator any_float         [float unsigned_float])
566 (define_code_attr u  [(sign_extend      "")
567                       (zero_extend      "u")
568                       (fix              "")
569                       (unsigned_fix     "u")])
571 (define_code_attr su [(sign_extend      "s")
572                       (zero_extend      "u")
573                       (fix              "s")
574                       (unsigned_fix     "u")
575                       (float            "s")
576                       (unsigned_float   "u")])
578 (define_code_attr az [(sign_extend      "a")
579                       (zero_extend      "z")
580                       (fix              "a")
581                       (unsigned_fix     "z")
582                       (float            "a")
583                       (unsigned_float   "z")])
585 (define_code_attr uns [(fix             "")
586                        (unsigned_fix    "uns")
587                        (float           "")
588                        (unsigned_float  "uns")])
590 ; Various instructions that come in SI and DI forms.
591 ; A generic w/d attribute, for things like cmpw/cmpd.
592 (define_mode_attr wd [(QI    "b")
593                       (HI    "h")
594                       (SI    "w")
595                       (DI    "d")
596                       (V16QI "b")
597                       (V8HI  "h")
598                       (V4SI  "w")
599                       (V2DI  "d")
600                       (V1TI  "q")
601                       (TI    "q")])
603 ;; How many bits in this mode?
604 (define_mode_attr bits [(QI "8") (HI "16") (SI "32") (DI "64")
605                                            (SF "32") (DF "64")])
607 ; DImode bits
608 (define_mode_attr dbits [(QI "56") (HI "48") (SI "32")])
610 ;; Bitmask for shift instructions
611 (define_mode_attr hH [(SI "h") (DI "H")])
613 ;; A mode twice the size of the given mode
614 (define_mode_attr dmode [(SI "di") (DI "ti")])
615 (define_mode_attr DMODE [(SI "DI") (DI "TI")])
617 ;; Suffix for reload patterns
618 (define_mode_attr ptrsize [(SI "32bit")
619                            (DI "64bit")])
621 (define_mode_attr tptrsize [(SI "TARGET_32BIT")
622                             (DI "TARGET_64BIT")])
624 (define_mode_attr mptrsize [(SI "si")
625                             (DI "di")])
627 (define_mode_attr ptrload [(SI "lwz")
628                            (DI "ld")])
630 (define_mode_attr ptrm [(SI "m")
631                         (DI "Y")])
633 (define_mode_attr rreg [(SF   "f")
634                         (DF   "wa")
635                         (TF   "f")
636                         (TD   "f")
637                         (V4SF "wa")
638                         (V2DF "wa")])
640 (define_mode_attr rreg2 [(SF   "f")
641                          (DF   "d")])
643 (define_mode_attr SI_CONVERT_FP [(SF "TARGET_FCFIDS")
644                                  (DF "TARGET_FCFID")])
646 ;; Mode iterator for logical operations on 128-bit types
647 (define_mode_iterator BOOL_128          [TI
648                                          PTI
649                                          (V16QI "TARGET_ALTIVEC")
650                                          (V8HI  "TARGET_ALTIVEC")
651                                          (V4SI  "TARGET_ALTIVEC")
652                                          (V4SF  "TARGET_ALTIVEC")
653                                          (V2DI  "TARGET_ALTIVEC")
654                                          (V2DF  "TARGET_ALTIVEC")
655                                          (V1TI  "TARGET_ALTIVEC")])
657 ;; For the GPRs we use 3 constraints for register outputs, two that are the
658 ;; same as the output register, and a third where the output register is an
659 ;; early clobber, so we don't have to deal with register overlaps.  For the
660 ;; vector types, we prefer to use the vector registers.  For TI mode, allow
661 ;; either.
663 ;; Mode attribute for boolean operation register constraints for output
664 (define_mode_attr BOOL_REGS_OUTPUT      [(TI    "&r,r,r,wa,v")
665                                          (PTI   "&r,r,r")
666                                          (V16QI "wa,v,&?r,?r,?r")
667                                          (V8HI  "wa,v,&?r,?r,?r")
668                                          (V4SI  "wa,v,&?r,?r,?r")
669                                          (V4SF  "wa,v,&?r,?r,?r")
670                                          (V2DI  "wa,v,&?r,?r,?r")
671                                          (V2DF  "wa,v,&?r,?r,?r")
672                                          (V1TI  "wa,v,&?r,?r,?r")])
674 ;; Mode attribute for boolean operation register constraints for operand1
675 (define_mode_attr BOOL_REGS_OP1         [(TI    "r,0,r,wa,v")
676                                          (PTI   "r,0,r")
677                                          (V16QI "wa,v,r,0,r")
678                                          (V8HI  "wa,v,r,0,r")
679                                          (V4SI  "wa,v,r,0,r")
680                                          (V4SF  "wa,v,r,0,r")
681                                          (V2DI  "wa,v,r,0,r")
682                                          (V2DF  "wa,v,r,0,r")
683                                          (V1TI  "wa,v,r,0,r")])
685 ;; Mode attribute for boolean operation register constraints for operand2
686 (define_mode_attr BOOL_REGS_OP2         [(TI    "r,r,0,wa,v")
687                                          (PTI   "r,r,0")
688                                          (V16QI "wa,v,r,r,0")
689                                          (V8HI  "wa,v,r,r,0")
690                                          (V4SI  "wa,v,r,r,0")
691                                          (V4SF  "wa,v,r,r,0")
692                                          (V2DI  "wa,v,r,r,0")
693                                          (V2DF  "wa,v,r,r,0")
694                                          (V1TI  "wa,v,r,r,0")])
696 ;; Mode attribute for boolean operation register constraints for operand1
697 ;; for one_cmpl.  To simplify things, we repeat the constraint where 0
698 ;; is used for operand1 or operand2
699 (define_mode_attr BOOL_REGS_UNARY       [(TI    "r,0,0,wa,v")
700                                          (PTI   "r,0,0")
701                                          (V16QI "wa,v,r,0,0")
702                                          (V8HI  "wa,v,r,0,0")
703                                          (V4SI  "wa,v,r,0,0")
704                                          (V4SF  "wa,v,r,0,0")
705                                          (V2DI  "wa,v,r,0,0")
706                                          (V2DF  "wa,v,r,0,0")
707                                          (V1TI  "wa,v,r,0,0")])
709 ;; Reload iterator for creating the function to allocate a base register to
710 ;; supplement addressing modes.
711 (define_mode_iterator RELOAD [V16QI V8HI V4SI V2DI V4SF V2DF V1TI
712                               SF SD SI DF DD DI TI PTI KF IF TF])
714 ;; Iterate over smin, smax
715 (define_code_iterator fp_minmax [smin smax])
717 (define_code_attr     minmax    [(smin "min")
718                                  (smax "max")])
720 (define_code_attr     SMINMAX   [(smin "SMIN")
721                                  (smax "SMAX")])
723 ;; Iterator to optimize the following cases:
724 ;;      D-form load to FPR register & move to Altivec register
725 ;;      Move Altivec register to FPR register and store
726 (define_mode_iterator ALTIVEC_DFORM [DF
727                                      (SF "TARGET_P8_VECTOR")
728                                      (DI "TARGET_POWERPC64")])
731 ;; Start with fixed-point load and store insns.  Here we put only the more
732 ;; complex forms.  Basic data transfer is done later.
734 (define_insn "zero_extendqi<mode>2"
735   [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r,^wa,^v")
736         (zero_extend:EXTQI (match_operand:QI 1 "reg_or_mem_operand" "m,r,Z,v")))]
737   ""
738   "@
739    lbz%U1%X1 %0,%1
740    rlwinm %0,%1,0,0xff
741    lxsibzx %x0,%y1
742    vextractub %0,%1,7"
743   [(set_attr "type" "load,shift,fpload,vecperm")
744    (set_attr "isa" "*,*,p9v,p9v")])
746 (define_insn_and_split "*zero_extendqi<mode>2_dot"
747   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
748         (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
749                     (const_int 0)))
750    (clobber (match_scratch:EXTQI 0 "=r,r"))]
751   ""
752   "@
753    andi. %0,%1,0xff
754    #"
755   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
756   [(set (match_dup 0)
757         (zero_extend:EXTQI (match_dup 1)))
758    (set (match_dup 2)
759         (compare:CC (match_dup 0)
760                     (const_int 0)))]
761   ""
762   [(set_attr "type" "logical")
763    (set_attr "dot" "yes")
764    (set_attr "length" "4,8")])
766 (define_insn_and_split "*zero_extendqi<mode>2_dot2"
767   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
768         (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
769                     (const_int 0)))
770    (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
771         (zero_extend:EXTQI (match_dup 1)))]
772   ""
773   "@
774    andi. %0,%1,0xff
775    #"
776   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
777   [(set (match_dup 0)
778         (zero_extend:EXTQI (match_dup 1)))
779    (set (match_dup 2)
780         (compare:CC (match_dup 0)
781                     (const_int 0)))]
782   ""
783   [(set_attr "type" "logical")
784    (set_attr "dot" "yes")
785    (set_attr "length" "4,8")])
788 (define_insn "zero_extendhi<mode>2"
789   [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r,^wa,^v")
790         (zero_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r,Z,v")))]
791   ""
792   "@
793    lhz%U1%X1 %0,%1
794    rlwinm %0,%1,0,0xffff
795    lxsihzx %x0,%y1
796    vextractuh %0,%1,6"
797   [(set_attr "type" "load,shift,fpload,vecperm")
798    (set_attr "isa" "*,*,p9v,p9v")])
800 (define_insn_and_split "*zero_extendhi<mode>2_dot"
801   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
802         (compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
803                     (const_int 0)))
804    (clobber (match_scratch:EXTHI 0 "=r,r"))]
805   ""
806   "@
807    andi. %0,%1,0xffff
808    #"
809   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
810   [(set (match_dup 0)
811         (zero_extend:EXTHI (match_dup 1)))
812    (set (match_dup 2)
813         (compare:CC (match_dup 0)
814                     (const_int 0)))]
815   ""
816   [(set_attr "type" "logical")
817    (set_attr "dot" "yes")
818    (set_attr "length" "4,8")])
820 (define_insn_and_split "*zero_extendhi<mode>2_dot2"
821   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
822         (compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
823                     (const_int 0)))
824    (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
825         (zero_extend:EXTHI (match_dup 1)))]
826   ""
827   "@
828    andi. %0,%1,0xffff
829    #"
830   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
831   [(set (match_dup 0)
832         (zero_extend:EXTHI (match_dup 1)))
833    (set (match_dup 2)
834         (compare:CC (match_dup 0)
835                     (const_int 0)))]
836   ""
837   [(set_attr "type" "logical")
838    (set_attr "dot" "yes")
839    (set_attr "length" "4,8")])
842 (define_insn "zero_extendsi<mode>2"
843   [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r,d,wa,wa,r,wa")
844         (zero_extend:EXTSI (match_operand:SI 1 "reg_or_mem_operand" "m,r,Z,Z,r,wa,wa")))]
845   ""
846   "@
847    lwz%U1%X1 %0,%1
848    rldicl %0,%1,0,32
849    lfiwzx %0,%y1
850    lxsiwzx %x0,%y1
851    mtvsrwz %x0,%1
852    mfvsrwz %0,%x1
853    xxextractuw %x0,%x1,4"
854   [(set_attr "type" "load,shift,fpload,fpload,mffgpr,mftgpr,vecexts")
855    (set_attr "isa" "*,*,p7,p8v,p8v,p8v,p9v")])
857 (define_insn_and_split "*zero_extendsi<mode>2_dot"
858   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
859         (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
860                     (const_int 0)))
861    (clobber (match_scratch:EXTSI 0 "=r,r"))]
862   ""
863   "@
864    rldicl. %0,%1,0,32
865    #"
866   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
867   [(set (match_dup 0)
868         (zero_extend:DI (match_dup 1)))
869    (set (match_dup 2)
870         (compare:CC (match_dup 0)
871                     (const_int 0)))]
872   ""
873   [(set_attr "type" "shift")
874    (set_attr "dot" "yes")
875    (set_attr "length" "4,8")])
877 (define_insn_and_split "*zero_extendsi<mode>2_dot2"
878   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
879         (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
880                     (const_int 0)))
881    (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
882         (zero_extend:EXTSI (match_dup 1)))]
883   ""
884   "@
885    rldicl. %0,%1,0,32
886    #"
887   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
888   [(set (match_dup 0)
889         (zero_extend:EXTSI (match_dup 1)))
890    (set (match_dup 2)
891         (compare:CC (match_dup 0)
892                     (const_int 0)))]
893   ""
894   [(set_attr "type" "shift")
895    (set_attr "dot" "yes")
896    (set_attr "length" "4,8")])
899 (define_insn "extendqi<mode>2"
900   [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,?*v")
901         (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,?*v")))]
902   ""
903   "@
904    extsb %0,%1
905    vextsb2d %0,%1"
906   [(set_attr "type" "exts,vecperm")
907    (set_attr "isa" "*,p9v")])
909 (define_insn_and_split "*extendqi<mode>2_dot"
910   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
911         (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
912                     (const_int 0)))
913    (clobber (match_scratch:EXTQI 0 "=r,r"))]
914   ""
915   "@
916    extsb. %0,%1
917    #"
918   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
919   [(set (match_dup 0)
920         (sign_extend:EXTQI (match_dup 1)))
921    (set (match_dup 2)
922         (compare:CC (match_dup 0)
923                     (const_int 0)))]
924   ""
925   [(set_attr "type" "exts")
926    (set_attr "dot" "yes")
927    (set_attr "length" "4,8")])
929 (define_insn_and_split "*extendqi<mode>2_dot2"
930   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
931         (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
932                     (const_int 0)))
933    (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
934         (sign_extend:EXTQI (match_dup 1)))]
935   ""
936   "@
937    extsb. %0,%1
938    #"
939   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
940   [(set (match_dup 0)
941         (sign_extend:EXTQI (match_dup 1)))
942    (set (match_dup 2)
943         (compare:CC (match_dup 0)
944                     (const_int 0)))]
945   ""
946   [(set_attr "type" "exts")
947    (set_attr "dot" "yes")
948    (set_attr "length" "4,8")])
951 (define_expand "extendhi<mode>2"
952   [(set (match_operand:EXTHI 0 "gpc_reg_operand")
953         (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand")))]
954   ""
955   "")
957 (define_insn "*extendhi<mode>2"
958   [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r,?*v,?*v")
959         (sign_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r,Z,v")))]
960   ""
961   "@
962    lha%U1%X1 %0,%1
963    extsh %0,%1
964    #
965    vextsh2d %0,%1"
966   [(set_attr "type" "load,exts,fpload,vecperm")
967    (set_attr "sign_extend" "yes")
968    (set_attr "length" "*,*,8,*")
969    (set_attr "isa" "*,*,p9v,p9v")])
971 (define_split
972   [(set (match_operand:EXTHI 0 "altivec_register_operand")
973         (sign_extend:EXTHI
974          (match_operand:HI 1 "indexed_or_indirect_operand")))]
975   "TARGET_P9_VECTOR && reload_completed"
976   [(set (match_dup 2)
977         (match_dup 1))
978    (set (match_dup 0)
979         (sign_extend:EXTHI (match_dup 2)))]
981   operands[2] = gen_rtx_REG (HImode, REGNO (operands[0]));
984 (define_insn_and_split "*extendhi<mode>2_dot"
985   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
986         (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
987                     (const_int 0)))
988    (clobber (match_scratch:EXTHI 0 "=r,r"))]
989   ""
990   "@
991    extsh. %0,%1
992    #"
993   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
994   [(set (match_dup 0)
995         (sign_extend:EXTHI (match_dup 1)))
996    (set (match_dup 2)
997         (compare:CC (match_dup 0)
998                     (const_int 0)))]
999   ""
1000   [(set_attr "type" "exts")
1001    (set_attr "dot" "yes")
1002    (set_attr "length" "4,8")])
1004 (define_insn_and_split "*extendhi<mode>2_dot2"
1005   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1006         (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
1007                     (const_int 0)))
1008    (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
1009         (sign_extend:EXTHI (match_dup 1)))]
1010   ""
1011   "@
1012    extsh. %0,%1
1013    #"
1014   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1015   [(set (match_dup 0)
1016         (sign_extend:EXTHI (match_dup 1)))
1017    (set (match_dup 2)
1018         (compare:CC (match_dup 0)
1019                     (const_int 0)))]
1020   ""
1021   [(set_attr "type" "exts")
1022    (set_attr "dot" "yes")
1023    (set_attr "length" "4,8")])
1026 (define_insn "extendsi<mode>2"
1027   [(set (match_operand:EXTSI 0 "gpc_reg_operand"
1028                      "=r, r,   d,     wa,    wa,    v,      v,     wr")
1029         (sign_extend:EXTSI (match_operand:SI 1 "lwa_operand"
1030                      "YZ, r,   Z,     Z,     r,     v,      v,     ?wa")))]
1031   ""
1032   "@
1033    lwa%U1%X1 %0,%1
1034    extsw %0,%1
1035    lfiwax %0,%y1
1036    lxsiwax %x0,%y1
1037    mtvsrwa %x0,%1
1038    vextsw2d %0,%1
1039    #
1040    #"
1041   [(set_attr "type" "load,exts,fpload,fpload,mffgpr,vecexts,vecperm,mftgpr")
1042    (set_attr "sign_extend" "yes")
1043    (set_attr "length" "*,*,*,*,*,*,8,8")
1044    (set_attr "isa" "*,*,p6,p8v,p8v,p9v,p8v,p8v")])
1046 (define_split
1047   [(set (match_operand:EXTSI 0 "int_reg_operand")
1048         (sign_extend:EXTSI (match_operand:SI 1 "vsx_register_operand")))]
1049   "TARGET_DIRECT_MOVE_64BIT && reload_completed"
1050   [(set (match_dup 2)
1051         (match_dup 1))
1052    (set (match_dup 0)
1053         (sign_extend:DI (match_dup 2)))]
1055   operands[2] = gen_rtx_REG (SImode, reg_or_subregno (operands[0]));
1058 (define_split
1059   [(set (match_operand:DI 0 "altivec_register_operand")
1060         (sign_extend:DI (match_operand:SI 1 "altivec_register_operand")))]
1061   "TARGET_P8_VECTOR && !TARGET_P9_VECTOR && reload_completed"
1062   [(const_int 0)]
1064   rtx dest = operands[0];
1065   rtx src = operands[1];
1066   int dest_regno = REGNO (dest);
1067   int src_regno = REGNO (src);
1068   rtx dest_v2di = gen_rtx_REG (V2DImode, dest_regno);
1069   rtx src_v4si = gen_rtx_REG (V4SImode, src_regno);
1071   if (BYTES_BIG_ENDIAN)
1072     {
1073       emit_insn (gen_altivec_vupkhsw (dest_v2di, src_v4si));
1074       emit_insn (gen_vsx_xxspltd_v2di (dest_v2di, dest_v2di, const1_rtx));
1075     }
1076   else
1077     {
1078       emit_insn (gen_altivec_vupklsw (dest_v2di, src_v4si));
1079       emit_insn (gen_vsx_xxspltd_v2di (dest_v2di, dest_v2di, const0_rtx));
1080     }
1081   DONE;
1084 (define_insn_and_split "*extendsi<mode>2_dot"
1085   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1086         (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
1087                     (const_int 0)))
1088    (clobber (match_scratch:EXTSI 0 "=r,r"))]
1089   ""
1090   "@
1091    extsw. %0,%1
1092    #"
1093   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1094   [(set (match_dup 0)
1095         (sign_extend:EXTSI (match_dup 1)))
1096    (set (match_dup 2)
1097         (compare:CC (match_dup 0)
1098                     (const_int 0)))]
1099   ""
1100   [(set_attr "type" "exts")
1101    (set_attr "dot" "yes")
1102    (set_attr "length" "4,8")])
1104 (define_insn_and_split "*extendsi<mode>2_dot2"
1105   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1106         (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
1107                     (const_int 0)))
1108    (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
1109         (sign_extend:EXTSI (match_dup 1)))]
1110   ""
1111   "@
1112    extsw. %0,%1
1113    #"
1114   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1115   [(set (match_dup 0)
1116         (sign_extend:EXTSI (match_dup 1)))
1117    (set (match_dup 2)
1118         (compare:CC (match_dup 0)
1119                     (const_int 0)))]
1120   ""
1121   [(set_attr "type" "exts")
1122    (set_attr "dot" "yes")
1123    (set_attr "length" "4,8")])
1125 ;; IBM 405, 440, 464 and 476 half-word multiplication operations.
1127 (define_insn "*macchwc"
1128   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1129         (compare:CC (plus:SI (mult:SI (ashiftrt:SI
1130                                        (match_operand:SI 2 "gpc_reg_operand" "r")
1131                                        (const_int 16))
1132                                       (sign_extend:SI
1133                                        (match_operand:HI 1 "gpc_reg_operand" "r")))
1134                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1135                     (const_int 0)))
1136    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1137         (plus:SI (mult:SI (ashiftrt:SI
1138                            (match_dup 2)
1139                            (const_int 16))
1140                           (sign_extend:SI
1141                            (match_dup 1)))
1142                  (match_dup 4)))]
1143   "TARGET_MULHW"
1144   "macchw. %0,%1,%2"
1145   [(set_attr "type" "halfmul")])
1147 (define_insn "*macchw"
1148   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1149         (plus:SI (mult:SI (ashiftrt:SI
1150                            (match_operand:SI 2 "gpc_reg_operand" "r")
1151                            (const_int 16))
1152                           (sign_extend:SI
1153                            (match_operand:HI 1 "gpc_reg_operand" "r")))
1154                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1155   "TARGET_MULHW"
1156   "macchw %0,%1,%2"
1157   [(set_attr "type" "halfmul")])
1159 (define_insn "*macchwuc"
1160   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1161         (compare:CC (plus:SI (mult:SI (lshiftrt:SI
1162                                        (match_operand:SI 2 "gpc_reg_operand" "r")
1163                                        (const_int 16))
1164                                       (zero_extend:SI
1165                                        (match_operand:HI 1 "gpc_reg_operand" "r")))
1166                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1167                     (const_int 0)))
1168    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1169         (plus:SI (mult:SI (lshiftrt:SI
1170                            (match_dup 2)
1171                            (const_int 16))
1172                           (zero_extend:SI
1173                            (match_dup 1)))
1174                  (match_dup 4)))]
1175   "TARGET_MULHW"
1176   "macchwu. %0,%1,%2"
1177   [(set_attr "type" "halfmul")])
1179 (define_insn "*macchwu"
1180   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1181         (plus:SI (mult:SI (lshiftrt:SI
1182                            (match_operand:SI 2 "gpc_reg_operand" "r")
1183                            (const_int 16))
1184                           (zero_extend:SI
1185                            (match_operand:HI 1 "gpc_reg_operand" "r")))
1186                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1187   "TARGET_MULHW"
1188   "macchwu %0,%1,%2"
1189   [(set_attr "type" "halfmul")])
1191 (define_insn "*machhwc"
1192   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1193         (compare:CC (plus:SI (mult:SI (ashiftrt:SI
1194                                        (match_operand:SI 1 "gpc_reg_operand" "%r")
1195                                        (const_int 16))
1196                                       (ashiftrt:SI
1197                                        (match_operand:SI 2 "gpc_reg_operand" "r")
1198                                        (const_int 16)))
1199                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1200                     (const_int 0)))
1201    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1202         (plus:SI (mult:SI (ashiftrt:SI
1203                            (match_dup 1)
1204                            (const_int 16))
1205                           (ashiftrt:SI
1206                            (match_dup 2)
1207                            (const_int 16)))
1208                  (match_dup 4)))]
1209   "TARGET_MULHW"
1210   "machhw. %0,%1,%2"
1211   [(set_attr "type" "halfmul")])
1213 (define_insn "*machhw"
1214   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1215         (plus:SI (mult:SI (ashiftrt:SI
1216                            (match_operand:SI 1 "gpc_reg_operand" "%r")
1217                            (const_int 16))
1218                           (ashiftrt:SI
1219                            (match_operand:SI 2 "gpc_reg_operand" "r")
1220                            (const_int 16)))
1221                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1222   "TARGET_MULHW"
1223   "machhw %0,%1,%2"
1224   [(set_attr "type" "halfmul")])
1226 (define_insn "*machhwuc"
1227   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1228         (compare:CC (plus:SI (mult:SI (lshiftrt:SI
1229                                        (match_operand:SI 1 "gpc_reg_operand" "%r")
1230                                        (const_int 16))
1231                                       (lshiftrt:SI
1232                                        (match_operand:SI 2 "gpc_reg_operand" "r")
1233                                        (const_int 16)))
1234                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1235                     (const_int 0)))
1236    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1237         (plus:SI (mult:SI (lshiftrt:SI
1238                            (match_dup 1)
1239                            (const_int 16))
1240                           (lshiftrt:SI
1241                            (match_dup 2)
1242                            (const_int 16)))
1243                  (match_dup 4)))]
1244   "TARGET_MULHW"
1245   "machhwu. %0,%1,%2"
1246   [(set_attr "type" "halfmul")])
1248 (define_insn "*machhwu"
1249   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1250         (plus:SI (mult:SI (lshiftrt:SI
1251                            (match_operand:SI 1 "gpc_reg_operand" "%r")
1252                            (const_int 16))
1253                           (lshiftrt:SI
1254                            (match_operand:SI 2 "gpc_reg_operand" "r")
1255                            (const_int 16)))
1256                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1257   "TARGET_MULHW"
1258   "machhwu %0,%1,%2"
1259   [(set_attr "type" "halfmul")])
1261 (define_insn "*maclhwc"
1262   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1263         (compare:CC (plus:SI (mult:SI (sign_extend:SI
1264                                        (match_operand:HI 1 "gpc_reg_operand" "%r"))
1265                                       (sign_extend:SI
1266                                        (match_operand:HI 2 "gpc_reg_operand" "r")))
1267                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1268                     (const_int 0)))
1269    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1270         (plus:SI (mult:SI (sign_extend:SI
1271                            (match_dup 1))
1272                           (sign_extend:SI
1273                            (match_dup 2)))
1274                  (match_dup 4)))]
1275   "TARGET_MULHW"
1276   "maclhw. %0,%1,%2"
1277   [(set_attr "type" "halfmul")])
1279 (define_insn "*maclhw"
1280   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1281         (plus:SI (mult:SI (sign_extend:SI
1282                            (match_operand:HI 1 "gpc_reg_operand" "%r"))
1283                           (sign_extend:SI
1284                            (match_operand:HI 2 "gpc_reg_operand" "r")))
1285                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1286   "TARGET_MULHW"
1287   "maclhw %0,%1,%2"
1288   [(set_attr "type" "halfmul")])
1290 (define_insn "*maclhwuc"
1291   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1292         (compare:CC (plus:SI (mult:SI (zero_extend:SI
1293                                        (match_operand:HI 1 "gpc_reg_operand" "%r"))
1294                                       (zero_extend:SI
1295                                        (match_operand:HI 2 "gpc_reg_operand" "r")))
1296                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1297                     (const_int 0)))
1298    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1299         (plus:SI (mult:SI (zero_extend:SI
1300                            (match_dup 1))
1301                           (zero_extend:SI
1302                            (match_dup 2)))
1303                  (match_dup 4)))]
1304   "TARGET_MULHW"
1305   "maclhwu. %0,%1,%2"
1306   [(set_attr "type" "halfmul")])
1308 (define_insn "*maclhwu"
1309   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1310         (plus:SI (mult:SI (zero_extend:SI
1311                            (match_operand:HI 1 "gpc_reg_operand" "%r"))
1312                           (zero_extend:SI
1313                            (match_operand:HI 2 "gpc_reg_operand" "r")))
1314                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1315   "TARGET_MULHW"
1316   "maclhwu %0,%1,%2"
1317   [(set_attr "type" "halfmul")])
1319 (define_insn "*nmacchwc"
1320   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1321         (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1322                               (mult:SI (ashiftrt:SI
1323                                         (match_operand:SI 2 "gpc_reg_operand" "r")
1324                                         (const_int 16))
1325                                        (sign_extend:SI
1326                                         (match_operand:HI 1 "gpc_reg_operand" "r"))))
1327                     (const_int 0)))
1328    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1329         (minus:SI (match_dup 4)
1330                   (mult:SI (ashiftrt:SI
1331                             (match_dup 2)
1332                             (const_int 16))
1333                            (sign_extend:SI
1334                             (match_dup 1)))))]
1335   "TARGET_MULHW"
1336   "nmacchw. %0,%1,%2"
1337   [(set_attr "type" "halfmul")])
1339 (define_insn "*nmacchw"
1340   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1341         (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1342                   (mult:SI (ashiftrt:SI
1343                             (match_operand:SI 2 "gpc_reg_operand" "r")
1344                             (const_int 16))
1345                            (sign_extend:SI
1346                             (match_operand:HI 1 "gpc_reg_operand" "r")))))]
1347   "TARGET_MULHW"
1348   "nmacchw %0,%1,%2"
1349   [(set_attr "type" "halfmul")])
1351 (define_insn "*nmachhwc"
1352   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1353         (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1354                               (mult:SI (ashiftrt:SI
1355                                         (match_operand:SI 1 "gpc_reg_operand" "%r")
1356                                         (const_int 16))
1357                                        (ashiftrt:SI
1358                                         (match_operand:SI 2 "gpc_reg_operand" "r")
1359                                         (const_int 16))))
1360                     (const_int 0)))
1361    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1362         (minus:SI (match_dup 4)
1363                   (mult:SI (ashiftrt:SI
1364                             (match_dup 1)
1365                             (const_int 16))
1366                            (ashiftrt:SI
1367                             (match_dup 2)
1368                             (const_int 16)))))]
1369   "TARGET_MULHW"
1370   "nmachhw. %0,%1,%2"
1371   [(set_attr "type" "halfmul")])
1373 (define_insn "*nmachhw"
1374   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1375         (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1376                   (mult:SI (ashiftrt:SI
1377                             (match_operand:SI 1 "gpc_reg_operand" "%r")
1378                             (const_int 16))
1379                            (ashiftrt:SI
1380                             (match_operand:SI 2 "gpc_reg_operand" "r")
1381                             (const_int 16)))))]
1382   "TARGET_MULHW"
1383   "nmachhw %0,%1,%2"
1384   [(set_attr "type" "halfmul")])
1386 (define_insn "*nmaclhwc"
1387   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1388         (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1389                               (mult:SI (sign_extend:SI
1390                                         (match_operand:HI 1 "gpc_reg_operand" "%r"))
1391                                        (sign_extend:SI
1392                                         (match_operand:HI 2 "gpc_reg_operand" "r"))))
1393                     (const_int 0)))
1394    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1395         (minus:SI (match_dup 4)
1396                   (mult:SI (sign_extend:SI
1397                             (match_dup 1))
1398                            (sign_extend:SI
1399                             (match_dup 2)))))]
1400   "TARGET_MULHW"
1401   "nmaclhw. %0,%1,%2"
1402   [(set_attr "type" "halfmul")])
1404 (define_insn "*nmaclhw"
1405   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1406         (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1407                   (mult:SI (sign_extend:SI
1408                             (match_operand:HI 1 "gpc_reg_operand" "%r"))
1409                            (sign_extend:SI
1410                             (match_operand:HI 2 "gpc_reg_operand" "r")))))]
1411   "TARGET_MULHW"
1412   "nmaclhw %0,%1,%2"
1413   [(set_attr "type" "halfmul")])
1415 (define_insn "*mulchwc"
1416   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1417         (compare:CC (mult:SI (ashiftrt:SI
1418                               (match_operand:SI 2 "gpc_reg_operand" "r")
1419                               (const_int 16))
1420                              (sign_extend:SI
1421                               (match_operand:HI 1 "gpc_reg_operand" "r")))
1422                     (const_int 0)))
1423    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1424         (mult:SI (ashiftrt:SI
1425                   (match_dup 2)
1426                   (const_int 16))
1427                  (sign_extend:SI
1428                   (match_dup 1))))]
1429   "TARGET_MULHW"
1430   "mulchw. %0,%1,%2"
1431   [(set_attr "type" "halfmul")])
1433 (define_insn "*mulchw"
1434   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1435         (mult:SI (ashiftrt:SI
1436                   (match_operand:SI 2 "gpc_reg_operand" "r")
1437                   (const_int 16))
1438                  (sign_extend:SI
1439                   (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1440   "TARGET_MULHW"
1441   "mulchw %0,%1,%2"
1442   [(set_attr "type" "halfmul")])
1444 (define_insn "*mulchwuc"
1445   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1446         (compare:CC (mult:SI (lshiftrt:SI
1447                               (match_operand:SI 2 "gpc_reg_operand" "r")
1448                               (const_int 16))
1449                              (zero_extend:SI
1450                               (match_operand:HI 1 "gpc_reg_operand" "r")))
1451                     (const_int 0)))
1452    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1453         (mult:SI (lshiftrt:SI
1454                   (match_dup 2)
1455                   (const_int 16))
1456                  (zero_extend:SI
1457                   (match_dup 1))))]
1458   "TARGET_MULHW"
1459   "mulchwu. %0,%1,%2"
1460   [(set_attr "type" "halfmul")])
1462 (define_insn "*mulchwu"
1463   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1464         (mult:SI (lshiftrt:SI
1465                   (match_operand:SI 2 "gpc_reg_operand" "r")
1466                   (const_int 16))
1467                  (zero_extend:SI
1468                   (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1469   "TARGET_MULHW"
1470   "mulchwu %0,%1,%2"
1471   [(set_attr "type" "halfmul")])
1473 (define_insn "*mulhhwc"
1474   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1475         (compare:CC (mult:SI (ashiftrt:SI
1476                               (match_operand:SI 1 "gpc_reg_operand" "%r")
1477                               (const_int 16))
1478                              (ashiftrt:SI
1479                               (match_operand:SI 2 "gpc_reg_operand" "r")
1480                               (const_int 16)))
1481                     (const_int 0)))
1482    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1483         (mult:SI (ashiftrt:SI
1484                   (match_dup 1)
1485                   (const_int 16))
1486                  (ashiftrt:SI
1487                   (match_dup 2)
1488                   (const_int 16))))]
1489   "TARGET_MULHW"
1490   "mulhhw. %0,%1,%2"
1491   [(set_attr "type" "halfmul")])
1493 (define_insn "*mulhhw"
1494   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1495         (mult:SI (ashiftrt:SI
1496                   (match_operand:SI 1 "gpc_reg_operand" "%r")
1497                   (const_int 16))
1498                  (ashiftrt:SI
1499                   (match_operand:SI 2 "gpc_reg_operand" "r")
1500                   (const_int 16))))]
1501   "TARGET_MULHW"
1502   "mulhhw %0,%1,%2"
1503   [(set_attr "type" "halfmul")])
1505 (define_insn "*mulhhwuc"
1506   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1507         (compare:CC (mult:SI (lshiftrt:SI
1508                               (match_operand:SI 1 "gpc_reg_operand" "%r")
1509                               (const_int 16))
1510                              (lshiftrt:SI
1511                               (match_operand:SI 2 "gpc_reg_operand" "r")
1512                               (const_int 16)))
1513                     (const_int 0)))
1514    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1515         (mult:SI (lshiftrt:SI
1516                   (match_dup 1)
1517                   (const_int 16))
1518                  (lshiftrt:SI
1519                   (match_dup 2)
1520                   (const_int 16))))]
1521   "TARGET_MULHW"
1522   "mulhhwu. %0,%1,%2"
1523   [(set_attr "type" "halfmul")])
1525 (define_insn "*mulhhwu"
1526   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1527         (mult:SI (lshiftrt:SI
1528                   (match_operand:SI 1 "gpc_reg_operand" "%r")
1529                   (const_int 16))
1530                  (lshiftrt:SI
1531                   (match_operand:SI 2 "gpc_reg_operand" "r")
1532                   (const_int 16))))]
1533   "TARGET_MULHW"
1534   "mulhhwu %0,%1,%2"
1535   [(set_attr "type" "halfmul")])
1537 (define_insn "*mullhwc"
1538   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1539         (compare:CC (mult:SI (sign_extend:SI
1540                               (match_operand:HI 1 "gpc_reg_operand" "%r"))
1541                              (sign_extend:SI
1542                               (match_operand:HI 2 "gpc_reg_operand" "r")))
1543                     (const_int 0)))
1544    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1545         (mult:SI (sign_extend:SI
1546                   (match_dup 1))
1547                  (sign_extend:SI
1548                   (match_dup 2))))]
1549   "TARGET_MULHW"
1550   "mullhw. %0,%1,%2"
1551   [(set_attr "type" "halfmul")])
1553 (define_insn "*mullhw"
1554   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1555         (mult:SI (sign_extend:SI
1556                   (match_operand:HI 1 "gpc_reg_operand" "%r"))
1557                  (sign_extend:SI
1558                   (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1559   "TARGET_MULHW"
1560   "mullhw %0,%1,%2"
1561   [(set_attr "type" "halfmul")])
1563 (define_insn "*mullhwuc"
1564   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1565         (compare:CC (mult:SI (zero_extend:SI
1566                               (match_operand:HI 1 "gpc_reg_operand" "%r"))
1567                              (zero_extend:SI
1568                               (match_operand:HI 2 "gpc_reg_operand" "r")))
1569                     (const_int 0)))
1570    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1571         (mult:SI (zero_extend:SI
1572                   (match_dup 1))
1573                  (zero_extend:SI
1574                   (match_dup 2))))]
1575   "TARGET_MULHW"
1576   "mullhwu. %0,%1,%2"
1577   [(set_attr "type" "halfmul")])
1579 (define_insn "*mullhwu"
1580   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1581         (mult:SI (zero_extend:SI
1582                   (match_operand:HI 1 "gpc_reg_operand" "%r"))
1583                  (zero_extend:SI
1584                   (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1585   "TARGET_MULHW"
1586   "mullhwu %0,%1,%2"
1587   [(set_attr "type" "halfmul")])
1589 ;; IBM 405, 440, 464 and 476 string-search dlmzb instruction support.
1590 (define_insn "dlmzb"
1591   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1592         (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
1593                     (match_operand:SI 2 "gpc_reg_operand" "r")]
1594                    UNSPEC_DLMZB_CR))
1595    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1596         (unspec:SI [(match_dup 1)
1597                     (match_dup 2)]
1598                    UNSPEC_DLMZB))]
1599   "TARGET_DLMZB"
1600   "dlmzb. %0,%1,%2")
1602 (define_expand "strlensi"
1603   [(set (match_operand:SI 0 "gpc_reg_operand")
1604         (unspec:SI [(match_operand:BLK 1 "general_operand")
1605                     (match_operand:QI 2 "const_int_operand")
1606                     (match_operand 3 "const_int_operand")]
1607                    UNSPEC_DLMZB_STRLEN))
1608    (clobber (match_scratch:CC 4))]
1609   "TARGET_DLMZB && WORDS_BIG_ENDIAN && !optimize_size"
1611   rtx result = operands[0];
1612   rtx src = operands[1];
1613   rtx search_char = operands[2];
1614   rtx align = operands[3];
1615   rtx addr, scratch_string, word1, word2, scratch_dlmzb;
1616   rtx loop_label, end_label, mem, cr0, cond;
1617   if (search_char != const0_rtx
1618       || !CONST_INT_P (align)
1619       || INTVAL (align) < 8)
1620         FAIL;
1621   word1 = gen_reg_rtx (SImode);
1622   word2 = gen_reg_rtx (SImode);
1623   scratch_dlmzb = gen_reg_rtx (SImode);
1624   scratch_string = gen_reg_rtx (Pmode);
1625   loop_label = gen_label_rtx ();
1626   end_label = gen_label_rtx ();
1627   addr = force_reg (Pmode, XEXP (src, 0));
1628   emit_move_insn (scratch_string, addr);
1629   emit_label (loop_label);
1630   mem = change_address (src, SImode, scratch_string);
1631   emit_move_insn (word1, mem);
1632   emit_move_insn (word2, adjust_address (mem, SImode, 4));
1633   cr0 = gen_rtx_REG (CCmode, CR0_REGNO);
1634   emit_insn (gen_dlmzb (scratch_dlmzb, word1, word2, cr0));
1635   cond = gen_rtx_NE (VOIDmode, cr0, const0_rtx);
1636   emit_jump_insn (gen_rtx_SET (pc_rtx,
1637                                gen_rtx_IF_THEN_ELSE (VOIDmode,
1638                                                      cond,
1639                                                      gen_rtx_LABEL_REF
1640                                                        (VOIDmode,
1641                                                         end_label),
1642                                                      pc_rtx)));
1643   emit_insn (gen_addsi3 (scratch_string, scratch_string, GEN_INT (8)));
1644   emit_jump_insn (gen_rtx_SET (pc_rtx,
1645                                gen_rtx_LABEL_REF (VOIDmode, loop_label)));
1646   emit_barrier ();
1647   emit_label (end_label);
1648   emit_insn (gen_addsi3 (scratch_string, scratch_string, scratch_dlmzb));
1649   emit_insn (gen_subsi3 (result, scratch_string, addr));
1650   emit_insn (gen_addsi3 (result, result, constm1_rtx));
1651   DONE;
1654 ;; Fixed-point arithmetic insns.
1656 (define_expand "add<mode>3"
1657   [(set (match_operand:SDI 0 "gpc_reg_operand")
1658         (plus:SDI (match_operand:SDI 1 "gpc_reg_operand")
1659                   (match_operand:SDI 2 "reg_or_add_cint_operand")))]
1660   ""
1662   if (<MODE>mode == DImode && !TARGET_POWERPC64)
1663     {
1664       rtx lo0 = gen_lowpart (SImode, operands[0]);
1665       rtx lo1 = gen_lowpart (SImode, operands[1]);
1666       rtx lo2 = gen_lowpart (SImode, operands[2]);
1667       rtx hi0 = gen_highpart (SImode, operands[0]);
1668       rtx hi1 = gen_highpart (SImode, operands[1]);
1669       rtx hi2 = gen_highpart_mode (SImode, DImode, operands[2]);
1671       if (!reg_or_short_operand (lo2, SImode))
1672         lo2 = force_reg (SImode, lo2);
1673       if (!adde_operand (hi2, SImode))
1674         hi2 = force_reg (SImode, hi2);
1676       emit_insn (gen_addsi3_carry (lo0, lo1, lo2));
1677       emit_insn (gen_addsi3_carry_in (hi0, hi1, hi2));
1678       DONE;
1679     }
1681   if (CONST_INT_P (operands[2]) && !add_operand (operands[2], <MODE>mode))
1682     {
1683       rtx tmp = ((!can_create_pseudo_p ()
1684                   || rtx_equal_p (operands[0], operands[1]))
1685                  ? operands[0] : gen_reg_rtx (<MODE>mode));
1687       /* Adding a constant to r0 is not a valid insn, so use a different
1688          strategy in that case.  */
1689       if (reg_or_subregno (operands[1]) == 0 || reg_or_subregno (tmp) == 0)
1690         {
1691           if (operands[0] == operands[1])
1692             FAIL;
1693           rs6000_emit_move (operands[0], operands[2], <MODE>mode);
1694           emit_insn (gen_add<mode>3 (operands[0], operands[1], operands[0]));
1695           DONE;
1696         }
1698       HOST_WIDE_INT val = INTVAL (operands[2]);
1699       HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1700       HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1702       if (<MODE>mode == DImode && !satisfies_constraint_L (GEN_INT (rest)))
1703         FAIL;
1705       /* The ordering here is important for the prolog expander.
1706          When space is allocated from the stack, adding 'low' first may
1707          produce a temporary deallocation (which would be bad).  */
1708       emit_insn (gen_add<mode>3 (tmp, operands[1], GEN_INT (rest)));
1709       emit_insn (gen_add<mode>3 (operands[0], tmp, GEN_INT (low)));
1710       DONE;
1711     }
1714 (define_insn "*add<mode>3"
1715   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r,r")
1716         (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b,b")
1717                   (match_operand:GPR 2 "add_operand" "r,I,L")))]
1718   ""
1719   "@
1720    add %0,%1,%2
1721    addi %0,%1,%2
1722    addis %0,%1,%v2"
1723   [(set_attr "type" "add")])
1725 (define_insn "*addsi3_high"
1726   [(set (match_operand:SI 0 "gpc_reg_operand" "=b")
1727         (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
1728                  (high:SI (match_operand 2 "" ""))))]
1729   "TARGET_MACHO && !TARGET_64BIT"
1730   "addis %0,%1,ha16(%2)"
1731   [(set_attr "type" "add")])
1733 (define_insn_and_split "*add<mode>3_dot"
1734   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1735         (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
1736                               (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
1737                     (const_int 0)))
1738    (clobber (match_scratch:GPR 0 "=r,r"))]
1739   "<MODE>mode == Pmode"
1740   "@
1741    add. %0,%1,%2
1742    #"
1743   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1744   [(set (match_dup 0)
1745         (plus:GPR (match_dup 1)
1746                  (match_dup 2)))
1747    (set (match_dup 3)
1748         (compare:CC (match_dup 0)
1749                     (const_int 0)))]
1750   ""
1751   [(set_attr "type" "add")
1752    (set_attr "dot" "yes")
1753    (set_attr "length" "4,8")])
1755 (define_insn_and_split "*add<mode>3_dot2"
1756   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1757         (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
1758                               (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
1759                     (const_int 0)))
1760    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1761         (plus:GPR (match_dup 1)
1762                   (match_dup 2)))]
1763   "<MODE>mode == Pmode"
1764   "@
1765    add. %0,%1,%2
1766    #"
1767   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1768   [(set (match_dup 0)
1769         (plus:GPR (match_dup 1)
1770                   (match_dup 2)))
1771    (set (match_dup 3)
1772         (compare:CC (match_dup 0)
1773                     (const_int 0)))]
1774   ""
1775   [(set_attr "type" "add")
1776    (set_attr "dot" "yes")
1777    (set_attr "length" "4,8")])
1779 (define_insn_and_split "*add<mode>3_imm_dot"
1780   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1781         (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b")
1782                               (match_operand:GPR 2 "short_cint_operand" "I,I"))
1783                     (const_int 0)))
1784    (clobber (match_scratch:GPR 0 "=r,r"))
1785    (clobber (reg:GPR CA_REGNO))]
1786   "<MODE>mode == Pmode"
1787   "@
1788    addic. %0,%1,%2
1789    #"
1790   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1791   [(set (match_dup 0)
1792         (plus:GPR (match_dup 1)
1793                   (match_dup 2)))
1794    (set (match_dup 3)
1795         (compare:CC (match_dup 0)
1796                     (const_int 0)))]
1797   ""
1798   [(set_attr "type" "add")
1799    (set_attr "dot" "yes")
1800    (set_attr "length" "4,8")])
1802 (define_insn_and_split "*add<mode>3_imm_dot2"
1803   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1804         (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b")
1805                               (match_operand:GPR 2 "short_cint_operand" "I,I"))
1806                     (const_int 0)))
1807    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1808         (plus:GPR (match_dup 1)
1809                   (match_dup 2)))
1810    (clobber (reg:GPR CA_REGNO))]
1811   "<MODE>mode == Pmode"
1812   "@
1813    addic. %0,%1,%2
1814    #"
1815   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1816   [(set (match_dup 0)
1817         (plus:GPR (match_dup 1)
1818                   (match_dup 2)))
1819    (set (match_dup 3)
1820         (compare:CC (match_dup 0)
1821                     (const_int 0)))]
1822   ""
1823   [(set_attr "type" "add")
1824    (set_attr "dot" "yes")
1825    (set_attr "length" "4,8")])
1827 ;; Split an add that we can't do in one insn into two insns, each of which
1828 ;; does one 16-bit part.  This is used by combine.  Note that the low-order
1829 ;; add should be last in case the result gets used in an address.
1831 (define_split
1832   [(set (match_operand:GPR 0 "gpc_reg_operand")
1833         (plus:GPR (match_operand:GPR 1 "gpc_reg_operand")
1834                   (match_operand:GPR 2 "non_add_cint_operand")))]
1835   ""
1836   [(set (match_dup 0) (plus:GPR (match_dup 1) (match_dup 3)))
1837    (set (match_dup 0) (plus:GPR (match_dup 0) (match_dup 4)))]
1839   HOST_WIDE_INT val = INTVAL (operands[2]);
1840   HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1841   HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1843   operands[4] = GEN_INT (low);
1844   if (<MODE>mode == SImode || satisfies_constraint_L (GEN_INT (rest)))
1845     operands[3] = GEN_INT (rest);
1846   else if (can_create_pseudo_p ())
1847     {
1848       operands[3] = gen_reg_rtx (DImode);
1849       emit_move_insn (operands[3], operands[2]);
1850       emit_insn (gen_adddi3 (operands[0], operands[1], operands[3]));
1851       DONE;
1852     }
1853   else
1854     FAIL;
1858 (define_insn "add<mode>3_carry"
1859   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1860         (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1861                 (match_operand:P 2 "reg_or_short_operand" "rI")))
1862    (set (reg:P CA_REGNO)
1863         (ltu:P (plus:P (match_dup 1)
1864                        (match_dup 2))
1865                (match_dup 1)))]
1866   ""
1867   "add%I2c %0,%1,%2"
1868   [(set_attr "type" "add")])
1870 (define_insn "*add<mode>3_imm_carry_pos"
1871   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1872         (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1873                 (match_operand:P 2 "short_cint_operand" "n")))
1874    (set (reg:P CA_REGNO)
1875         (geu:P (match_dup 1)
1876                (match_operand:P 3 "const_int_operand" "n")))]
1877   "INTVAL (operands[2]) > 0
1878    && INTVAL (operands[2]) + INTVAL (operands[3]) == 0"
1879   "addic %0,%1,%2"
1880   [(set_attr "type" "add")])
1882 (define_insn "*add<mode>3_imm_carry_0"
1883   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1884         (match_operand:P 1 "gpc_reg_operand" "r"))
1885    (set (reg:P CA_REGNO)
1886         (const_int 0))]
1887   ""
1888   "addic %0,%1,0"
1889   [(set_attr "type" "add")])
1891 (define_insn "*add<mode>3_imm_carry_m1"
1892   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1893         (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1894                 (const_int -1)))
1895    (set (reg:P CA_REGNO)
1896         (ne:P (match_dup 1)
1897               (const_int 0)))]
1898   ""
1899   "addic %0,%1,-1"
1900   [(set_attr "type" "add")])
1902 (define_insn "*add<mode>3_imm_carry_neg"
1903   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1904         (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1905                 (match_operand:P 2 "short_cint_operand" "n")))
1906    (set (reg:P CA_REGNO)
1907         (gtu:P (match_dup 1)
1908                (match_operand:P 3 "const_int_operand" "n")))]
1909   "INTVAL (operands[2]) < 0
1910    && INTVAL (operands[2]) + INTVAL (operands[3]) == -1"
1911   "addic %0,%1,%2"
1912   [(set_attr "type" "add")])
1915 (define_expand "add<mode>3_carry_in"
1916   [(parallel [
1917      (set (match_operand:GPR 0 "gpc_reg_operand")
1918           (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand")
1919                               (match_operand:GPR 2 "adde_operand"))
1920                     (reg:GPR CA_REGNO)))
1921      (clobber (reg:GPR CA_REGNO))])]
1922   ""
1924   if (operands[2] == const0_rtx)
1925     {
1926       emit_insn (gen_add<mode>3_carry_in_0 (operands[0], operands[1]));
1927       DONE;
1928     }
1929   if (operands[2] == constm1_rtx)
1930     {
1931       emit_insn (gen_add<mode>3_carry_in_m1 (operands[0], operands[1]));
1932       DONE;
1933     }
1936 (define_insn "*add<mode>3_carry_in_internal"
1937   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1938         (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1939                             (match_operand:GPR 2 "gpc_reg_operand" "r"))
1940                   (reg:GPR CA_REGNO)))
1941    (clobber (reg:GPR CA_REGNO))]
1942   ""
1943   "adde %0,%1,%2"
1944   [(set_attr "type" "add")])
1946 (define_insn "*add<mode>3_carry_in_internal2"
1947   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1948         (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1949                             (reg:GPR CA_REGNO))
1950                   (match_operand:GPR 2 "gpc_reg_operand" "r")))
1951    (clobber (reg:GPR CA_REGNO))]
1952   ""
1953   "adde %0,%1,%2"
1954   [(set_attr "type" "add")])
1956 (define_insn "add<mode>3_carry_in_0"
1957   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1958         (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1959                   (reg:GPR CA_REGNO)))
1960    (clobber (reg:GPR CA_REGNO))]
1961   ""
1962   "addze %0,%1"
1963   [(set_attr "type" "add")])
1965 (define_insn "add<mode>3_carry_in_m1"
1966   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1967         (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1968                             (reg:GPR CA_REGNO))
1969                   (const_int -1)))
1970    (clobber (reg:GPR CA_REGNO))]
1971   ""
1972   "addme %0,%1"
1973   [(set_attr "type" "add")])
1976 (define_expand "one_cmpl<mode>2"
1977   [(set (match_operand:SDI 0 "gpc_reg_operand")
1978         (not:SDI (match_operand:SDI 1 "gpc_reg_operand")))]
1979   ""
1981   if (<MODE>mode == DImode && !TARGET_POWERPC64)
1982     {
1983       rs6000_split_logical (operands, NOT, false, false, false);
1984       DONE;
1985     }
1988 (define_insn "*one_cmpl<mode>2"
1989   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1990         (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
1991   ""
1992   "not %0,%1")
1994 (define_insn_and_split "*one_cmpl<mode>2_dot"
1995   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1996         (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
1997                     (const_int 0)))
1998    (clobber (match_scratch:GPR 0 "=r,r"))]
1999   "<MODE>mode == Pmode"
2000   "@
2001    not. %0,%1
2002    #"
2003   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2004   [(set (match_dup 0)
2005         (not:GPR (match_dup 1)))
2006    (set (match_dup 2)
2007         (compare:CC (match_dup 0)
2008                     (const_int 0)))]
2009   ""
2010   [(set_attr "type" "logical")
2011    (set_attr "dot" "yes")
2012    (set_attr "length" "4,8")])
2014 (define_insn_and_split "*one_cmpl<mode>2_dot2"
2015   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2016         (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2017                     (const_int 0)))
2018    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2019         (not:GPR (match_dup 1)))]
2020   "<MODE>mode == Pmode"
2021   "@
2022    not. %0,%1
2023    #"
2024   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2025   [(set (match_dup 0)
2026         (not:GPR (match_dup 1)))
2027    (set (match_dup 2)
2028         (compare:CC (match_dup 0)
2029                     (const_int 0)))]
2030   ""
2031   [(set_attr "type" "logical")
2032    (set_attr "dot" "yes")
2033    (set_attr "length" "4,8")])
2036 (define_expand "sub<mode>3"
2037   [(set (match_operand:SDI 0 "gpc_reg_operand")
2038         (minus:SDI (match_operand:SDI 1 "reg_or_short_operand")
2039                    (match_operand:SDI 2 "gpc_reg_operand")))]
2040   ""
2042   if (<MODE>mode == DImode && !TARGET_POWERPC64)
2043     {
2044       rtx lo0 = gen_lowpart (SImode, operands[0]);
2045       rtx lo1 = gen_lowpart (SImode, operands[1]);
2046       rtx lo2 = gen_lowpart (SImode, operands[2]);
2047       rtx hi0 = gen_highpart (SImode, operands[0]);
2048       rtx hi1 = gen_highpart_mode (SImode, DImode, operands[1]);
2049       rtx hi2 = gen_highpart (SImode, operands[2]);
2051       if (!reg_or_short_operand (lo1, SImode))
2052         lo1 = force_reg (SImode, lo1);
2053       if (!adde_operand (hi1, SImode))
2054         hi1 = force_reg (SImode, hi1);
2056       emit_insn (gen_subfsi3_carry (lo0, lo2, lo1));
2057       emit_insn (gen_subfsi3_carry_in (hi0, hi2, hi1));
2058       DONE;
2059     }
2061   if (short_cint_operand (operands[1], <MODE>mode))
2062     {
2063       emit_insn (gen_subf<mode>3_imm (operands[0], operands[2], operands[1]));
2064       DONE;
2065     }
2068 (define_insn "*subf<mode>3"
2069   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2070         (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r")
2071                    (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2072   ""
2073   "subf %0,%1,%2"
2074   [(set_attr "type" "add")])
2076 (define_insn_and_split "*subf<mode>3_dot"
2077   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2078         (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
2079                                (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2080                     (const_int 0)))
2081    (clobber (match_scratch:GPR 0 "=r,r"))]
2082   "<MODE>mode == Pmode"
2083   "@
2084    subf. %0,%1,%2
2085    #"
2086   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2087   [(set (match_dup 0)
2088         (minus:GPR (match_dup 2)
2089                    (match_dup 1)))
2090    (set (match_dup 3)
2091         (compare:CC (match_dup 0)
2092                     (const_int 0)))]
2093   ""
2094   [(set_attr "type" "add")
2095    (set_attr "dot" "yes")
2096    (set_attr "length" "4,8")])
2098 (define_insn_and_split "*subf<mode>3_dot2"
2099   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2100         (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
2101                                (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2102                     (const_int 0)))
2103    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2104         (minus:GPR (match_dup 2)
2105                    (match_dup 1)))]
2106   "<MODE>mode == Pmode"
2107   "@
2108    subf. %0,%1,%2
2109    #"
2110   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2111   [(set (match_dup 0)
2112         (minus:GPR (match_dup 2)
2113                    (match_dup 1)))
2114    (set (match_dup 3)
2115         (compare:CC (match_dup 0)
2116                     (const_int 0)))]
2117   ""
2118   [(set_attr "type" "add")
2119    (set_attr "dot" "yes")
2120    (set_attr "length" "4,8")])
2122 (define_insn "subf<mode>3_imm"
2123   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2124         (minus:GPR (match_operand:GPR 2 "short_cint_operand" "I")
2125                    (match_operand:GPR 1 "gpc_reg_operand" "r")))
2126    (clobber (reg:GPR CA_REGNO))]
2127   ""
2128   "subfic %0,%1,%2"
2129   [(set_attr "type" "add")])
2131 (define_insn_and_split "subf<mode>3_carry_dot2"
2132   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2133         (compare:CC (minus:P (match_operand:P 2 "gpc_reg_operand" "r,r")
2134                                (match_operand:P 1 "gpc_reg_operand" "r,r"))
2135                     (const_int 0)))
2136    (set (match_operand:P 0 "gpc_reg_operand" "=r,r")
2137         (minus:P (match_dup 2)
2138                    (match_dup 1)))
2139    (set (reg:P CA_REGNO)
2140         (leu:P (match_dup 1)
2141                (match_dup 2)))]
2142   "<MODE>mode == Pmode"
2143   "@
2144    subfc. %0,%1,%2
2145    #"
2146   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2147   [(parallel [(set (match_dup 0)
2148                    (minus:P (match_dup 2)
2149                             (match_dup 1)))
2150               (set (reg:P CA_REGNO)
2151                    (leu:P (match_dup 1)
2152                           (match_dup 2)))])
2153    (set (match_dup 3)
2154         (compare:CC (match_dup 0)
2155                     (const_int 0)))]
2156   ""
2157   [(set_attr "type" "add")
2158    (set_attr "dot" "yes")
2159    (set_attr "length" "4,8")])
2161 (define_insn "subf<mode>3_carry"
2162   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2163         (minus:P (match_operand:P 2 "reg_or_short_operand" "rI")
2164                  (match_operand:P 1 "gpc_reg_operand" "r")))
2165    (set (reg:P CA_REGNO)
2166         (leu:P (match_dup 1)
2167                (match_dup 2)))]
2168   ""
2169   "subf%I2c %0,%1,%2"
2170   [(set_attr "type" "add")])
2172 (define_insn "*subf<mode>3_imm_carry_0"
2173   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2174         (neg:P (match_operand:P 1 "gpc_reg_operand" "r")))
2175    (set (reg:P CA_REGNO)
2176         (eq:P (match_dup 1)
2177               (const_int 0)))]
2178   ""
2179   "subfic %0,%1,0"
2180   [(set_attr "type" "add")])
2182 (define_insn "*subf<mode>3_imm_carry_m1"
2183   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2184         (not:P (match_operand:P 1 "gpc_reg_operand" "r")))
2185    (set (reg:P CA_REGNO)
2186         (const_int 1))]
2187   ""
2188   "subfic %0,%1,-1"
2189   [(set_attr "type" "add")])
2192 (define_expand "subf<mode>3_carry_in"
2193   [(parallel [
2194      (set (match_operand:GPR 0 "gpc_reg_operand")
2195           (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand"))
2196                               (reg:GPR CA_REGNO))
2197                     (match_operand:GPR 2 "adde_operand")))
2198      (clobber (reg:GPR CA_REGNO))])]
2199   ""
2201   if (operands[2] == const0_rtx)
2202     {
2203       emit_insn (gen_subf<mode>3_carry_in_0 (operands[0], operands[1]));
2204       DONE;
2205     }
2206   if (operands[2] == constm1_rtx)
2207     {
2208       emit_insn (gen_subf<mode>3_carry_in_m1 (operands[0], operands[1]));
2209       DONE;
2210     }
2213 (define_insn "*subf<mode>3_carry_in_internal"
2214   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2215         (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
2216                             (reg:GPR CA_REGNO))
2217                   (match_operand:GPR 2 "gpc_reg_operand" "r")))
2218    (clobber (reg:GPR CA_REGNO))]
2219   ""
2220   "subfe %0,%1,%2"
2221   [(set_attr "type" "add")])
2223 (define_insn "subf<mode>3_carry_in_0"
2224   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2225         (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
2226                   (reg:GPR CA_REGNO)))
2227    (clobber (reg:GPR CA_REGNO))]
2228   ""
2229   "subfze %0,%1"
2230   [(set_attr "type" "add")])
2232 (define_insn "subf<mode>3_carry_in_m1"
2233   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2234         (plus:GPR (minus:GPR (reg:GPR CA_REGNO)
2235                              (match_operand:GPR 1 "gpc_reg_operand" "r"))
2236                   (const_int -2)))
2237    (clobber (reg:GPR CA_REGNO))]
2238   ""
2239   "subfme %0,%1"
2240   [(set_attr "type" "add")])
2242 (define_insn "subf<mode>3_carry_in_xx"
2243   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2244         (plus:GPR (reg:GPR CA_REGNO)
2245                   (const_int -1)))
2246    (clobber (reg:GPR CA_REGNO))]
2247   ""
2248   "subfe %0,%0,%0"
2249   [(set_attr "type" "add")])
2252 (define_insn "@neg<mode>2"
2253   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2254         (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2255   ""
2256   "neg %0,%1"
2257   [(set_attr "type" "add")])
2259 (define_insn_and_split "*neg<mode>2_dot"
2260   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2261         (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2262                     (const_int 0)))
2263    (clobber (match_scratch:GPR 0 "=r,r"))]
2264   "<MODE>mode == Pmode"
2265   "@
2266    neg. %0,%1
2267    #"
2268   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2269   [(set (match_dup 0)
2270         (neg:GPR (match_dup 1)))
2271    (set (match_dup 2)
2272         (compare:CC (match_dup 0)
2273                     (const_int 0)))]
2274   ""
2275   [(set_attr "type" "add")
2276    (set_attr "dot" "yes")
2277    (set_attr "length" "4,8")])
2279 (define_insn_and_split "*neg<mode>2_dot2"
2280   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2281         (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2282                     (const_int 0)))
2283    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2284         (neg:GPR (match_dup 1)))]
2285   "<MODE>mode == Pmode"
2286   "@
2287    neg. %0,%1
2288    #"
2289   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2290   [(set (match_dup 0)
2291         (neg:GPR (match_dup 1)))
2292    (set (match_dup 2)
2293         (compare:CC (match_dup 0)
2294                     (const_int 0)))]
2295   ""
2296   [(set_attr "type" "add")
2297    (set_attr "dot" "yes")
2298    (set_attr "length" "4,8")])
2301 (define_insn "clz<mode>2"
2302   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2303         (clz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2304   ""
2305   "cntlz<wd> %0,%1"
2306   [(set_attr "type" "cntlz")])
2308 (define_expand "ctz<mode>2"
2309    [(set (match_operand:GPR 0 "gpc_reg_operand")
2310          (ctz:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2311   ""
2313   if (TARGET_CTZ)
2314     {
2315       emit_insn (gen_ctz<mode>2_hw (operands[0], operands[1]));
2316       DONE;
2317     }
2319   rtx tmp1 = gen_reg_rtx (<MODE>mode);
2320   rtx tmp2 = gen_reg_rtx (<MODE>mode);
2321   rtx tmp3 = gen_reg_rtx (<MODE>mode);
2323   if (TARGET_POPCNTD)
2324     {
2325       emit_insn (gen_add<mode>3 (tmp1, operands[1], constm1_rtx));
2326       emit_insn (gen_one_cmpl<mode>2 (tmp2, operands[1]));
2327       emit_insn (gen_and<mode>3 (tmp3, tmp1, tmp2));
2328       emit_insn (gen_popcntd<mode>2 (operands[0], tmp3));
2329     }
2330   else
2331     {
2332       emit_insn (gen_neg<mode>2 (tmp1, operands[1]));
2333       emit_insn (gen_and<mode>3 (tmp2, operands[1], tmp1));
2334       emit_insn (gen_clz<mode>2 (tmp3, tmp2));
2335       emit_insn (gen_sub<mode>3 (operands[0], GEN_INT (<bits> - 1), tmp3));
2336     }
2338   DONE;
2341 (define_insn "ctz<mode>2_hw"
2342   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2343         (ctz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2344   "TARGET_CTZ"
2345   "cnttz<wd> %0,%1"
2346   [(set_attr "type" "cntlz")])
2348 (define_expand "ffs<mode>2"
2349   [(set (match_operand:GPR 0 "gpc_reg_operand")
2350         (ffs:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2351   ""
2353   rtx tmp1 = gen_reg_rtx (<MODE>mode);
2354   rtx tmp2 = gen_reg_rtx (<MODE>mode);
2355   rtx tmp3 = gen_reg_rtx (<MODE>mode);
2356   emit_insn (gen_neg<mode>2 (tmp1, operands[1]));
2357   emit_insn (gen_and<mode>3 (tmp2, operands[1], tmp1));
2358   emit_insn (gen_clz<mode>2 (tmp3, tmp2));
2359   emit_insn (gen_sub<mode>3 (operands[0], GEN_INT (<bits>), tmp3));
2360   DONE;
2364 (define_expand "popcount<mode>2"
2365   [(set (match_operand:GPR 0 "gpc_reg_operand")
2366         (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2367   "TARGET_POPCNTB || TARGET_POPCNTD"
2369   rs6000_emit_popcount (operands[0], operands[1]);
2370   DONE;
2373 (define_insn "popcntb<mode>2"
2374   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2375         (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")]
2376                     UNSPEC_POPCNTB))]
2377   "TARGET_POPCNTB"
2378   "popcntb %0,%1"
2379   [(set_attr "type" "popcnt")])
2381 (define_insn "popcntd<mode>2"
2382   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2383         (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2384   "TARGET_POPCNTD"
2385   "popcnt<wd> %0,%1"
2386   [(set_attr "type" "popcnt")])
2389 (define_expand "parity<mode>2"
2390   [(set (match_operand:GPR 0 "gpc_reg_operand")
2391         (parity:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2392   "TARGET_POPCNTB"
2394   rs6000_emit_parity (operands[0], operands[1]);
2395   DONE;
2398 (define_insn "parity<mode>2_cmpb"
2399   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2400         (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")] UNSPEC_PARITY))]
2401   "TARGET_CMPB && TARGET_POPCNTB"
2402   "prty<wd> %0,%1"
2403   [(set_attr "type" "popcnt")])
2405 (define_insn "cmpb<mode>3"
2406   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2407         (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")
2408                      (match_operand:GPR 2 "gpc_reg_operand" "r")] UNSPEC_CMPB))]
2409   "TARGET_CMPB"
2410   "cmpb %0,%1,%2"
2411   [(set_attr "type" "cmp")])
2413 ;; Since the hardware zeros the upper part of the register, save generating the
2414 ;; AND immediate if we are converting to unsigned
2415 (define_insn "*bswap<mode>2_extenddi"
2416   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2417         (zero_extend:DI
2418          (bswap:HSI (match_operand:HSI 1 "memory_operand" "Z"))))]
2419   "TARGET_POWERPC64"
2420   "l<wd>brx %0,%y1"
2421   [(set_attr "type" "load")])
2423 (define_insn "*bswaphi2_extendsi"
2424   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2425         (zero_extend:SI
2426          (bswap:HI (match_operand:HI 1 "memory_operand" "Z"))))]
2427   ""
2428   "lhbrx %0,%y1"
2429   [(set_attr "type" "load")])
2431 ;; Separate the bswap patterns into load, store, and gpr<-gpr.  This prevents
2432 ;; the register allocator from converting a gpr<-gpr swap into a store and then
2433 ;; load with byte swap, which can be slower than doing it in the registers.  It
2434 ;; also prevents certain failures with the RELOAD register allocator.
2436 (define_expand "bswap<mode>2"
2437   [(use (match_operand:HSI 0 "reg_or_mem_operand"))
2438    (use (match_operand:HSI 1 "reg_or_mem_operand"))]
2439   ""
2441   rtx dest = operands[0];
2442   rtx src = operands[1];
2444   if (!REG_P (dest) && !REG_P (src))
2445     src = force_reg (<MODE>mode, src);
2447   if (MEM_P (src))
2448     {
2449       src = rs6000_force_indexed_or_indirect_mem (src);
2450       emit_insn (gen_bswap<mode>2_load (dest, src));
2451     }
2452   else if (MEM_P (dest))
2453     {
2454       dest = rs6000_force_indexed_or_indirect_mem (dest);
2455       emit_insn (gen_bswap<mode>2_store (dest, src));
2456     }
2457   else
2458     emit_insn (gen_bswap<mode>2_reg (dest, src));
2459   DONE;
2462 (define_insn "bswap<mode>2_load"
2463   [(set (match_operand:HSI 0 "gpc_reg_operand" "=r")
2464         (bswap:HSI (match_operand:HSI 1 "indexed_or_indirect_operand" "Z")))]
2465   ""
2466   "l<wd>brx %0,%y1"
2467   [(set_attr "type" "load")])
2469 (define_insn "bswap<mode>2_store"
2470   [(set (match_operand:HSI 0 "indexed_or_indirect_operand" "=Z")
2471         (bswap:HSI (match_operand:HSI 1 "gpc_reg_operand" "r")))]
2472   ""
2473   "st<wd>brx %1,%y0"
2474   [(set_attr "type" "store")])
2476 (define_insn_and_split "bswaphi2_reg"
2477   [(set (match_operand:HI 0 "gpc_reg_operand" "=&r,wa")
2478         (bswap:HI
2479          (match_operand:HI 1 "gpc_reg_operand" "r,wa")))
2480    (clobber (match_scratch:SI 2 "=&r,X"))]
2481   ""
2482   "@
2483    #
2484    xxbrh %x0,%x1"
2485   "reload_completed && int_reg_operand (operands[0], HImode)"
2486   [(set (match_dup 3)
2487         (and:SI (lshiftrt:SI (match_dup 4)
2488                              (const_int 8))
2489                 (const_int 255)))
2490    (set (match_dup 2)
2491         (and:SI (ashift:SI (match_dup 4)
2492                            (const_int 8))
2493                 (const_int 65280)))             ;; 0xff00
2494    (set (match_dup 3)
2495         (ior:SI (match_dup 3)
2496                 (match_dup 2)))]
2498   operands[3] = simplify_gen_subreg (SImode, operands[0], HImode, 0);
2499   operands[4] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
2501   [(set_attr "length" "12,4")
2502    (set_attr "type" "*,vecperm")
2503    (set_attr "isa" "*,p9v")])
2505 ;; We are always BITS_BIG_ENDIAN, so the bit positions below in
2506 ;; zero_extract insns do not change for -mlittle.
2507 (define_insn_and_split "bswapsi2_reg"
2508   [(set (match_operand:SI 0 "gpc_reg_operand" "=&r,wa")
2509         (bswap:SI
2510          (match_operand:SI 1 "gpc_reg_operand" "r,wa")))]
2511   ""
2512   "@
2513    #
2514    xxbrw %x0,%x1"
2515   "reload_completed && int_reg_operand (operands[0], SImode)"
2516   [(set (match_dup 0)                                   ; DABC
2517         (rotate:SI (match_dup 1)
2518                    (const_int 24)))
2519    (set (match_dup 0)                                   ; DCBC
2520         (ior:SI (and:SI (ashift:SI (match_dup 1)
2521                                    (const_int 8))
2522                         (const_int 16711680))
2523                 (and:SI (match_dup 0)
2524                         (const_int -16711681))))
2525    (set (match_dup 0)                                   ; DCBA
2526         (ior:SI (and:SI (lshiftrt:SI (match_dup 1)
2527                                      (const_int 24))
2528                         (const_int 255))
2529                 (and:SI (match_dup 0)
2530                         (const_int -256))))]
2531   ""
2532   [(set_attr "length" "12,4")
2533    (set_attr "type" "*,vecperm")
2534    (set_attr "isa" "*,p9v")])
2536 ;; On systems with LDBRX/STDBRX generate the loads/stores directly, just like
2537 ;; we do for L{H,W}BRX and ST{H,W}BRX above.  If not, we have to generate more
2538 ;; complex code.
2540 (define_expand "bswapdi2"
2541   [(parallel [(set (match_operand:DI 0 "reg_or_mem_operand")
2542                    (bswap:DI
2543                     (match_operand:DI 1 "reg_or_mem_operand")))
2544               (clobber (match_scratch:DI 2))
2545               (clobber (match_scratch:DI 3))])]
2546   ""
2548   rtx dest = operands[0];
2549   rtx src = operands[1];
2551   if (!REG_P (dest) && !REG_P (src))
2552     operands[1] = src = force_reg (DImode, src);
2554   if (TARGET_POWERPC64 && TARGET_LDBRX)
2555     {
2556       if (MEM_P (src))
2557         {
2558           src = rs6000_force_indexed_or_indirect_mem (src);
2559           emit_insn (gen_bswapdi2_load (dest, src));
2560         }
2561       else if (MEM_P (dest))
2562         {
2563           dest = rs6000_force_indexed_or_indirect_mem (dest);
2564           emit_insn (gen_bswapdi2_store (dest, src));
2565         }
2566       else if (TARGET_P9_VECTOR)
2567         emit_insn (gen_bswapdi2_xxbrd (dest, src));
2568       else
2569         emit_insn (gen_bswapdi2_reg (dest, src));
2570       DONE;
2571     }
2573   if (!TARGET_POWERPC64)
2574     {
2575       /* 32-bit mode needs fewer scratch registers, but 32-bit addressing mode
2576          that uses 64-bit registers needs the same scratch registers as 64-bit
2577          mode.  */
2578       emit_insn (gen_bswapdi2_32bit (dest, src));
2579       DONE;
2580     }
2583 ;; Power7/cell has ldbrx/stdbrx, so use it directly
2584 (define_insn "bswapdi2_load"
2585   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2586         (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand" "Z")))]
2587   "TARGET_POWERPC64 && TARGET_LDBRX"
2588   "ldbrx %0,%y1"
2589   [(set_attr "type" "load")])
2591 (define_insn "bswapdi2_store"
2592   [(set (match_operand:DI 0 "indexed_or_indirect_operand" "=Z")
2593         (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "r")))]
2594   "TARGET_POWERPC64 && TARGET_LDBRX"
2595   "stdbrx %1,%y0"
2596   [(set_attr "type" "store")])
2598 (define_insn "bswapdi2_xxbrd"
2599   [(set (match_operand:DI 0 "gpc_reg_operand" "=wa")
2600         (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "wa")))]
2601   "TARGET_P9_VECTOR"
2602   "xxbrd %x0,%x1"
2603   [(set_attr "type" "vecperm")
2604    (set_attr "isa" "p9v")])
2606 (define_insn "bswapdi2_reg"
2607   [(set (match_operand:DI 0 "gpc_reg_operand" "=&r")
2608         (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "r")))
2609    (clobber (match_scratch:DI 2 "=&r"))
2610    (clobber (match_scratch:DI 3 "=&r"))]
2611   "TARGET_POWERPC64 && TARGET_LDBRX && !TARGET_P9_VECTOR"
2612   "#"
2613   [(set_attr "length" "36")])
2615 ;; Non-power7/cell, fall back to use lwbrx/stwbrx
2616 (define_insn "*bswapdi2_64bit"
2617   [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,&r")
2618         (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2619    (clobber (match_scratch:DI 2 "=&b,&b,&r"))
2620    (clobber (match_scratch:DI 3 "=&r,&r,&r"))]
2621   "TARGET_POWERPC64 && !TARGET_LDBRX
2622    && (REG_P (operands[0]) || REG_P (operands[1]))
2623    && !(MEM_P (operands[0]) && MEM_VOLATILE_P (operands[0]))
2624    && !(MEM_P (operands[1]) && MEM_VOLATILE_P (operands[1]))"
2625   "#"
2626   [(set_attr "length" "16,12,36")])
2628 (define_split
2629   [(set (match_operand:DI 0 "gpc_reg_operand")
2630         (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand")))
2631    (clobber (match_operand:DI 2 "gpc_reg_operand"))
2632    (clobber (match_operand:DI 3 "gpc_reg_operand"))]
2633   "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2634   [(const_int 0)]
2636   rtx dest   = operands[0];
2637   rtx src    = operands[1];
2638   rtx op2    = operands[2];
2639   rtx op3    = operands[3];
2640   rtx op3_32 = simplify_gen_subreg (SImode, op3, DImode,
2641                                     BYTES_BIG_ENDIAN ? 4 : 0);
2642   rtx dest_32 = simplify_gen_subreg (SImode, dest, DImode,
2643                                      BYTES_BIG_ENDIAN ? 4 : 0);
2644   rtx addr1;
2645   rtx addr2;
2646   rtx word1;
2647   rtx word2;
2649   addr1 = XEXP (src, 0);
2650   if (GET_CODE (addr1) == PLUS)
2651     {
2652       emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2653       if (TARGET_AVOID_XFORM)
2654         {
2655           emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2656           addr2 = op2;
2657         }
2658       else
2659         addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2660     }
2661   else if (TARGET_AVOID_XFORM)
2662     {
2663       emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2664       addr2 = op2;
2665     }
2666   else
2667     {
2668       emit_move_insn (op2, GEN_INT (4));
2669       addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2670     }
2672   word1 = change_address (src, SImode, addr1);
2673   word2 = change_address (src, SImode, addr2);
2675   if (BYTES_BIG_ENDIAN)
2676     {
2677       emit_insn (gen_bswapsi2 (op3_32, word2));
2678       emit_insn (gen_bswapsi2 (dest_32, word1));
2679     }
2680   else
2681     {
2682       emit_insn (gen_bswapsi2 (op3_32, word1));
2683       emit_insn (gen_bswapsi2 (dest_32, word2));
2684     }
2686   emit_insn (gen_ashldi3 (op3, op3, GEN_INT (32)));
2687   emit_insn (gen_iordi3 (dest, dest, op3));
2688   DONE;
2691 (define_split
2692   [(set (match_operand:DI 0 "indexed_or_indirect_operand")
2693         (bswap:DI (match_operand:DI 1 "gpc_reg_operand")))
2694    (clobber (match_operand:DI 2 "gpc_reg_operand"))
2695    (clobber (match_operand:DI 3 "gpc_reg_operand"))]
2696   "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2697   [(const_int 0)]
2699   rtx dest   = operands[0];
2700   rtx src    = operands[1];
2701   rtx op2    = operands[2];
2702   rtx op3    = operands[3];
2703   rtx src_si = simplify_gen_subreg (SImode, src, DImode,
2704                                     BYTES_BIG_ENDIAN ? 4 : 0);
2705   rtx op3_si = simplify_gen_subreg (SImode, op3, DImode,
2706                                     BYTES_BIG_ENDIAN ? 4 : 0);
2707   rtx addr1;
2708   rtx addr2;
2709   rtx word1;
2710   rtx word2;
2712   addr1 = XEXP (dest, 0);
2713   if (GET_CODE (addr1) == PLUS)
2714     {
2715       emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2716       if (TARGET_AVOID_XFORM)
2717         {
2718           emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2719           addr2 = op2;
2720         }
2721       else
2722         addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2723     }
2724   else if (TARGET_AVOID_XFORM)
2725     {
2726       emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2727       addr2 = op2;
2728     }
2729   else
2730     {
2731       emit_move_insn (op2, GEN_INT (4));
2732       addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2733     }
2735   word1 = change_address (dest, SImode, addr1);
2736   word2 = change_address (dest, SImode, addr2);
2738   emit_insn (gen_lshrdi3 (op3, src, GEN_INT (32)));
2740   if (BYTES_BIG_ENDIAN)
2741     {
2742       emit_insn (gen_bswapsi2 (word1, src_si));
2743       emit_insn (gen_bswapsi2 (word2, op3_si));
2744     }
2745   else
2746     {
2747       emit_insn (gen_bswapsi2 (word2, src_si));
2748       emit_insn (gen_bswapsi2 (word1, op3_si));
2749     }
2750   DONE;
2753 (define_split
2754   [(set (match_operand:DI 0 "gpc_reg_operand")
2755         (bswap:DI (match_operand:DI 1 "gpc_reg_operand")))
2756    (clobber (match_operand:DI 2 "gpc_reg_operand"))
2757    (clobber (match_operand:DI 3 "gpc_reg_operand"))]
2758   "TARGET_POWERPC64 && !TARGET_P9_VECTOR && reload_completed"
2759   [(const_int 0)]
2761   rtx dest    = operands[0];
2762   rtx src     = operands[1];
2763   rtx op2     = operands[2];
2764   rtx op3     = operands[3];
2765   int lo_off  = BYTES_BIG_ENDIAN ? 4 : 0;
2766   rtx dest_si = simplify_gen_subreg (SImode, dest, DImode, lo_off);
2767   rtx src_si  = simplify_gen_subreg (SImode, src, DImode, lo_off);
2768   rtx op2_si  = simplify_gen_subreg (SImode, op2, DImode, lo_off);
2769   rtx op3_si  = simplify_gen_subreg (SImode, op3, DImode, lo_off);
2771   emit_insn (gen_lshrdi3 (op2, src, GEN_INT (32)));
2772   emit_insn (gen_bswapsi2 (dest_si, src_si));
2773   emit_insn (gen_bswapsi2 (op3_si, op2_si));
2774   emit_insn (gen_ashldi3 (dest, dest, GEN_INT (32)));
2775   emit_insn (gen_iordi3 (dest, dest, op3));
2776   DONE;
2779 (define_insn "bswapdi2_32bit"
2780   [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,?&r")
2781         (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2782    (clobber (match_scratch:SI 2 "=&b,&b,X"))]
2783   "!TARGET_POWERPC64 && (REG_P (operands[0]) || REG_P (operands[1]))"
2784   "#"
2785   [(set_attr "length" "16,12,36")])
2787 (define_split
2788   [(set (match_operand:DI 0 "gpc_reg_operand")
2789         (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand")))
2790    (clobber (match_operand:SI 2 "gpc_reg_operand"))]
2791   "!TARGET_POWERPC64 && reload_completed"
2792   [(const_int 0)]
2794   rtx dest  = operands[0];
2795   rtx src   = operands[1];
2796   rtx op2   = operands[2];
2797   rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
2798   rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
2799   rtx addr1;
2800   rtx addr2;
2801   rtx word1;
2802   rtx word2;
2804   addr1 = XEXP (src, 0);
2805   if (GET_CODE (addr1) == PLUS)
2806     {
2807       emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2808       if (TARGET_AVOID_XFORM
2809           || REGNO (XEXP (addr1, 1)) == REGNO (dest2))
2810         {
2811           emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2812           addr2 = op2;
2813         }
2814       else
2815         addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
2816     }
2817   else if (TARGET_AVOID_XFORM
2818            || REGNO (addr1) == REGNO (dest2))
2819     {
2820       emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2821       addr2 = op2;
2822     }
2823   else
2824     {
2825       emit_move_insn (op2, GEN_INT (4));
2826       addr2 = gen_rtx_PLUS (SImode, op2, addr1);
2827     }
2829   word1 = change_address (src, SImode, addr1);
2830   word2 = change_address (src, SImode, addr2);
2832   emit_insn (gen_bswapsi2 (dest2, word1));
2833   /* The REGNO (dest2) tests above ensure that addr2 has not been trashed,
2834      thus allowing us to omit an early clobber on the output.  */
2835   emit_insn (gen_bswapsi2 (dest1, word2));
2836   DONE;
2839 (define_split
2840   [(set (match_operand:DI 0 "indexed_or_indirect_operand")
2841         (bswap:DI (match_operand:DI 1 "gpc_reg_operand")))
2842    (clobber (match_operand:SI 2 "gpc_reg_operand"))]
2843   "!TARGET_POWERPC64 && reload_completed"
2844   [(const_int 0)]
2846   rtx dest = operands[0];
2847   rtx src  = operands[1];
2848   rtx op2  = operands[2];
2849   rtx src1 = simplify_gen_subreg (SImode, src, DImode, 0);
2850   rtx src2 = simplify_gen_subreg (SImode, src, DImode, 4);
2851   rtx addr1;
2852   rtx addr2;
2853   rtx word1;
2854   rtx word2;
2856   addr1 = XEXP (dest, 0);
2857   if (GET_CODE (addr1) == PLUS)
2858     {
2859       emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2860       if (TARGET_AVOID_XFORM)
2861         {
2862           emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2863           addr2 = op2;
2864         }
2865       else
2866         addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
2867     }
2868   else if (TARGET_AVOID_XFORM)
2869     {
2870       emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2871       addr2 = op2;
2872     }
2873   else
2874     {
2875       emit_move_insn (op2, GEN_INT (4));
2876       addr2 = gen_rtx_PLUS (SImode, op2, addr1);
2877     }
2879   word1 = change_address (dest, SImode, addr1);
2880   word2 = change_address (dest, SImode, addr2);
2882   emit_insn (gen_bswapsi2 (word2, src1));
2883   emit_insn (gen_bswapsi2 (word1, src2));
2884   DONE;
2887 (define_split
2888   [(set (match_operand:DI 0 "gpc_reg_operand")
2889         (bswap:DI (match_operand:DI 1 "gpc_reg_operand")))
2890    (clobber (match_operand:SI 2 ""))]
2891   "!TARGET_POWERPC64 && reload_completed"
2892   [(const_int 0)]
2894   rtx dest  = operands[0];
2895   rtx src   = operands[1];
2896   rtx src1  = simplify_gen_subreg (SImode, src, DImode, 0);
2897   rtx src2  = simplify_gen_subreg (SImode, src, DImode, 4);
2898   rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
2899   rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
2901   emit_insn (gen_bswapsi2 (dest1, src2));
2902   emit_insn (gen_bswapsi2 (dest2, src1));
2903   DONE;
2907 (define_insn "mul<mode>3"
2908   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2909         (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
2910                   (match_operand:GPR 2 "reg_or_short_operand" "r,I")))]
2911   ""
2912   "@
2913    mull<wd> %0,%1,%2
2914    mulli %0,%1,%2"
2915    [(set_attr "type" "mul")
2916     (set (attr "size")
2917       (cond [(match_operand:GPR 2 "s8bit_cint_operand")
2918                 (const_string "8")
2919              (match_operand:GPR 2 "short_cint_operand")
2920                 (const_string "16")]
2921         (const_string "<bits>")))])
2923 (define_insn_and_split "*mul<mode>3_dot"
2924   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2925         (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2926                               (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
2927                     (const_int 0)))
2928    (clobber (match_scratch:GPR 0 "=r,r"))]
2929   "<MODE>mode == Pmode"
2930   "@
2931    mull<wd>. %0,%1,%2
2932    #"
2933   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2934   [(set (match_dup 0)
2935         (mult:GPR (match_dup 1)
2936                   (match_dup 2)))
2937    (set (match_dup 3)
2938         (compare:CC (match_dup 0)
2939                     (const_int 0)))]
2940   ""
2941   [(set_attr "type" "mul")
2942    (set_attr "size" "<bits>")
2943    (set_attr "dot" "yes")
2944    (set_attr "length" "4,8")])
2946 (define_insn_and_split "*mul<mode>3_dot2"
2947   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2948         (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2949                               (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
2950                     (const_int 0)))
2951    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2952         (mult:GPR (match_dup 1)
2953                   (match_dup 2)))]
2954   "<MODE>mode == Pmode"
2955   "@
2956    mull<wd>. %0,%1,%2
2957    #"
2958   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2959   [(set (match_dup 0)
2960         (mult:GPR (match_dup 1)
2961                   (match_dup 2)))
2962    (set (match_dup 3)
2963         (compare:CC (match_dup 0)
2964                     (const_int 0)))]
2965   ""
2966   [(set_attr "type" "mul")
2967    (set_attr "size" "<bits>")
2968    (set_attr "dot" "yes")
2969    (set_attr "length" "4,8")])
2972 (define_expand "<su>mul<mode>3_highpart"
2973   [(set (match_operand:GPR 0 "gpc_reg_operand")
2974         (subreg:GPR
2975           (mult:<DMODE> (any_extend:<DMODE>
2976                           (match_operand:GPR 1 "gpc_reg_operand"))
2977                         (any_extend:<DMODE>
2978                           (match_operand:GPR 2 "gpc_reg_operand")))
2979          0))]
2980   ""
2982   if (<MODE>mode == SImode && TARGET_POWERPC64)
2983     {
2984       emit_insn (gen_<su>mulsi3_highpart_64 (operands[0], operands[1],
2985                                              operands[2]));
2986       DONE;
2987     }
2989   if (!WORDS_BIG_ENDIAN)
2990     {
2991       emit_insn (gen_<su>mul<mode>3_highpart_le (operands[0], operands[1],
2992                                                  operands[2]));
2993       DONE;
2994     }
2997 (define_insn "*<su>mul<mode>3_highpart"
2998   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2999         (subreg:GPR
3000           (mult:<DMODE> (any_extend:<DMODE>
3001                           (match_operand:GPR 1 "gpc_reg_operand" "r"))
3002                         (any_extend:<DMODE>
3003                           (match_operand:GPR 2 "gpc_reg_operand" "r")))
3004          0))]
3005   "WORDS_BIG_ENDIAN && !(<MODE>mode == SImode && TARGET_POWERPC64)"
3006   "mulh<wd><u> %0,%1,%2"
3007   [(set_attr "type" "mul")
3008    (set_attr "size" "<bits>")])
3010 (define_insn "<su>mulsi3_highpart_le"
3011   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
3012         (subreg:SI
3013           (mult:DI (any_extend:DI
3014                      (match_operand:SI 1 "gpc_reg_operand" "r"))
3015                    (any_extend:DI
3016                      (match_operand:SI 2 "gpc_reg_operand" "r")))
3017          4))]
3018   "!WORDS_BIG_ENDIAN && !TARGET_POWERPC64"
3019   "mulhw<u> %0,%1,%2"
3020   [(set_attr "type" "mul")])
3022 (define_insn "<su>muldi3_highpart_le"
3023   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3024         (subreg:DI
3025           (mult:TI (any_extend:TI
3026                      (match_operand:DI 1 "gpc_reg_operand" "r"))
3027                    (any_extend:TI
3028                      (match_operand:DI 2 "gpc_reg_operand" "r")))
3029          8))]
3030   "!WORDS_BIG_ENDIAN && TARGET_POWERPC64"
3031   "mulhd<u> %0,%1,%2"
3032   [(set_attr "type" "mul")
3033    (set_attr "size" "64")])
3035 (define_insn "<su>mulsi3_highpart_64"
3036   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
3037         (truncate:SI
3038           (lshiftrt:DI
3039             (mult:DI (any_extend:DI
3040                        (match_operand:SI 1 "gpc_reg_operand" "r"))
3041                      (any_extend:DI
3042                        (match_operand:SI 2 "gpc_reg_operand" "r")))
3043             (const_int 32))))]
3044   "TARGET_POWERPC64"
3045   "mulhw<u> %0,%1,%2"
3046   [(set_attr "type" "mul")])
3048 (define_expand "<u>mul<mode><dmode>3"
3049   [(set (match_operand:<DMODE> 0 "gpc_reg_operand")
3050         (mult:<DMODE> (any_extend:<DMODE>
3051                         (match_operand:GPR 1 "gpc_reg_operand"))
3052                       (any_extend:<DMODE>
3053                         (match_operand:GPR 2 "gpc_reg_operand"))))]
3054   "!(<MODE>mode == SImode && TARGET_POWERPC64)"
3056   rtx l = gen_reg_rtx (<MODE>mode);
3057   rtx h = gen_reg_rtx (<MODE>mode);
3058   emit_insn (gen_mul<mode>3 (l, operands[1], operands[2]));
3059   emit_insn (gen_<su>mul<mode>3_highpart (h, operands[1], operands[2]));
3060   emit_move_insn (gen_lowpart (<MODE>mode, operands[0]), l);
3061   emit_move_insn (gen_highpart (<MODE>mode, operands[0]), h);
3062   DONE;
3065 (define_insn "*maddld<mode>4"
3066   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3067         (plus:GPR (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3068                             (match_operand:GPR 2 "gpc_reg_operand" "r"))
3069                   (match_operand:GPR 3 "gpc_reg_operand" "r")))]
3070   "TARGET_MADDLD"
3071   "maddld %0,%1,%2,%3"
3072   [(set_attr "type" "mul")])
3074 (define_insn "udiv<mode>3"
3075   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3076         (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3077                   (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3078   ""
3079   "div<wd>u %0,%1,%2"
3080   [(set_attr "type" "div")
3081    (set_attr "size" "<bits>")])
3084 ;; For powers of two we can do sra[wd]i/addze for divide and then adjust for
3085 ;; modulus.  If it isn't a power of two, force operands into register and do
3086 ;; a normal divide.
3087 (define_expand "div<mode>3"
3088   [(set (match_operand:GPR 0 "gpc_reg_operand")
3089         (div:GPR (match_operand:GPR 1 "gpc_reg_operand")
3090                  (match_operand:GPR 2 "reg_or_cint_operand")))]
3091   ""
3093   if (CONST_INT_P (operands[2])
3094       && INTVAL (operands[2]) > 0
3095       && exact_log2 (INTVAL (operands[2])) >= 0)
3096     {
3097       emit_insn (gen_div<mode>3_sra (operands[0], operands[1], operands[2]));
3098       DONE;
3099     }
3101   operands[2] = force_reg (<MODE>mode, operands[2]);
3104 (define_insn "*div<mode>3"
3105   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3106         (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3107                  (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3108   ""
3109   "div<wd> %0,%1,%2"
3110   [(set_attr "type" "div")
3111    (set_attr "size" "<bits>")])
3113 (define_insn "div<mode>3_sra"
3114   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3115         (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3116                  (match_operand:GPR 2 "exact_log2_cint_operand" "N")))
3117    (clobber (reg:GPR CA_REGNO))]
3118   ""
3119   "sra<wd>i %0,%1,%p2\;addze %0,%0"
3120   [(set_attr "type" "two")
3121    (set_attr "length" "8")])
3123 (define_insn_and_split "*div<mode>3_sra_dot"
3124   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3125         (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3126                              (match_operand:GPR 2 "exact_log2_cint_operand" "N,N"))
3127                     (const_int 0)))
3128    (clobber (match_scratch:GPR 0 "=r,r"))
3129    (clobber (reg:GPR CA_REGNO))]
3130   "<MODE>mode == Pmode"
3131   "@
3132    sra<wd>i %0,%1,%p2\;addze. %0,%0
3133    #"
3134   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3135   [(parallel [(set (match_dup 0)
3136                    (div:GPR (match_dup 1)
3137                             (match_dup 2)))
3138               (clobber (reg:GPR CA_REGNO))])
3139    (set (match_dup 3)
3140         (compare:CC (match_dup 0)
3141                     (const_int 0)))]
3142   ""
3143   [(set_attr "type" "two")
3144    (set_attr "length" "8,12")
3145    (set_attr "cell_micro" "not")])
3147 (define_insn_and_split "*div<mode>3_sra_dot2"
3148   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3149         (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3150                              (match_operand:GPR 2 "exact_log2_cint_operand" "N,N"))
3151                     (const_int 0)))
3152    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3153         (div:GPR (match_dup 1)
3154                  (match_dup 2)))
3155    (clobber (reg:GPR CA_REGNO))]
3156   "<MODE>mode == Pmode"
3157   "@
3158    sra<wd>i %0,%1,%p2\;addze. %0,%0
3159    #"
3160   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3161   [(parallel [(set (match_dup 0)
3162                    (div:GPR (match_dup 1)
3163                             (match_dup 2)))
3164               (clobber (reg:GPR CA_REGNO))])
3165    (set (match_dup 3)
3166         (compare:CC (match_dup 0)
3167                     (const_int 0)))]
3168   ""
3169   [(set_attr "type" "two")
3170    (set_attr "length" "8,12")
3171    (set_attr "cell_micro" "not")])
3173 (define_expand "mod<mode>3"
3174   [(set (match_operand:GPR 0 "gpc_reg_operand")
3175         (mod:GPR (match_operand:GPR 1 "gpc_reg_operand")
3176                  (match_operand:GPR 2 "reg_or_cint_operand")))]
3177   ""
3179   int i;
3180   rtx temp1;
3181   rtx temp2;
3183   if (!CONST_INT_P (operands[2])
3184       || INTVAL (operands[2]) <= 0
3185       || (i = exact_log2 (INTVAL (operands[2]))) < 0)
3186     {
3187       if (!TARGET_MODULO)
3188         FAIL;
3190       operands[2] = force_reg (<MODE>mode, operands[2]);
3191     }
3192   else
3193     {
3194       temp1 = gen_reg_rtx (<MODE>mode);
3195       temp2 = gen_reg_rtx (<MODE>mode);
3197       emit_insn (gen_div<mode>3 (temp1, operands[1], operands[2]));
3198       emit_insn (gen_ashl<mode>3 (temp2, temp1, GEN_INT (i)));
3199       emit_insn (gen_sub<mode>3 (operands[0], operands[1], temp2));
3200       DONE;
3201     }
3204 ;; In order to enable using a peephole2 for combining div/mod to eliminate the
3205 ;; mod, prefer putting the result of mod into a different register
3206 (define_insn "*mod<mode>3"
3207   [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
3208         (mod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3209                  (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3210   "TARGET_MODULO"
3211   "mods<wd> %0,%1,%2"
3212   [(set_attr "type" "div")
3213    (set_attr "size" "<bits>")])
3216 (define_insn "umod<mode>3"
3217   [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
3218         (umod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3219                   (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3220   "TARGET_MODULO"
3221   "modu<wd> %0,%1,%2"
3222   [(set_attr "type" "div")
3223    (set_attr "size" "<bits>")])
3225 ;; On machines with modulo support, do a combined div/mod the old fashioned
3226 ;; method, since the multiply/subtract is faster than doing the mod instruction
3227 ;; after a divide.
3229 (define_peephole2
3230   [(set (match_operand:GPR 0 "gpc_reg_operand")
3231         (div:GPR (match_operand:GPR 1 "gpc_reg_operand")
3232                  (match_operand:GPR 2 "gpc_reg_operand")))
3233    (set (match_operand:GPR 3 "gpc_reg_operand")
3234         (mod:GPR (match_dup 1)
3235                  (match_dup 2)))]
3236   "TARGET_MODULO
3237    && ! reg_mentioned_p (operands[0], operands[1])
3238    && ! reg_mentioned_p (operands[0], operands[2])
3239    && ! reg_mentioned_p (operands[3], operands[1])
3240    && ! reg_mentioned_p (operands[3], operands[2])"
3241   [(set (match_dup 0)
3242         (div:GPR (match_dup 1)
3243                  (match_dup 2)))
3244    (set (match_dup 3)
3245         (mult:GPR (match_dup 0)
3246                   (match_dup 2)))
3247    (set (match_dup 3)
3248         (minus:GPR (match_dup 1)
3249                    (match_dup 3)))])
3251 (define_peephole2
3252   [(set (match_operand:GPR 0 "gpc_reg_operand")
3253         (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand")
3254                   (match_operand:GPR 2 "gpc_reg_operand")))
3255    (set (match_operand:GPR 3 "gpc_reg_operand")
3256         (umod:GPR (match_dup 1)
3257                   (match_dup 2)))]
3258   "TARGET_MODULO
3259    && ! reg_mentioned_p (operands[0], operands[1])
3260    && ! reg_mentioned_p (operands[0], operands[2])
3261    && ! reg_mentioned_p (operands[3], operands[1])
3262    && ! reg_mentioned_p (operands[3], operands[2])"
3263   [(set (match_dup 0)
3264         (udiv:GPR (match_dup 1)
3265                   (match_dup 2)))
3266    (set (match_dup 3)
3267         (mult:GPR (match_dup 0)
3268                   (match_dup 2)))
3269    (set (match_dup 3)
3270         (minus:GPR (match_dup 1)
3271                    (match_dup 3)))])
3274 ;; Logical instructions
3275 ;; The logical instructions are mostly combined by using match_operator,
3276 ;; but the plain AND insns are somewhat different because there is no
3277 ;; plain 'andi' (only 'andi.'), no plain 'andis', and there are all
3278 ;; those rotate-and-mask operations.  Thus, the AND insns come first.
3280 (define_expand "and<mode>3"
3281   [(set (match_operand:SDI 0 "gpc_reg_operand")
3282         (and:SDI (match_operand:SDI 1 "gpc_reg_operand")
3283                  (match_operand:SDI 2 "reg_or_cint_operand")))]
3284   ""
3286   if (<MODE>mode == DImode && !TARGET_POWERPC64)
3287     {
3288       rs6000_split_logical (operands, AND, false, false, false);
3289       DONE;
3290     }
3292   if (CONST_INT_P (operands[2]))
3293     {
3294       if (rs6000_is_valid_and_mask (operands[2], <MODE>mode))
3295         {
3296           emit_insn (gen_and<mode>3_mask (operands[0], operands[1], operands[2]));
3297           DONE;
3298         }
3300       if (logical_const_operand (operands[2], <MODE>mode))
3301         {
3302           emit_insn (gen_and<mode>3_imm (operands[0], operands[1], operands[2]));
3303           DONE;
3304         }
3306       if (rs6000_is_valid_2insn_and (operands[2], <MODE>mode))
3307         {
3308           rs6000_emit_2insn_and (<MODE>mode, operands, true, 0);
3309           DONE;
3310         }
3312       operands[2] = force_reg (<MODE>mode, operands[2]);
3313     }
3317 (define_insn "and<mode>3_imm"
3318   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3319         (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3320                  (match_operand:GPR 2 "logical_const_operand" "n")))
3321    (clobber (match_scratch:CC 3 "=x"))]
3322   "!rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3323   "andi%e2. %0,%1,%u2"
3324   [(set_attr "type" "logical")
3325    (set_attr "dot" "yes")])
3327 (define_insn_and_split "*and<mode>3_imm_dot"
3328   [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3329         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3330                              (match_operand:GPR 2 "logical_const_operand" "n,n"))
3331                     (const_int 0)))
3332    (clobber (match_scratch:GPR 0 "=r,r"))
3333    (clobber (match_scratch:CC 4 "=X,x"))]
3334   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3335    && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3336   "@
3337    andi%e2. %0,%1,%u2
3338    #"
3339   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3340   [(parallel [(set (match_dup 0)
3341                    (and:GPR (match_dup 1)
3342                             (match_dup 2)))
3343               (clobber (match_dup 4))])
3344    (set (match_dup 3)
3345         (compare:CC (match_dup 0)
3346                     (const_int 0)))]
3347   ""
3348   [(set_attr "type" "logical")
3349    (set_attr "dot" "yes")
3350    (set_attr "length" "4,8")])
3352 (define_insn_and_split "*and<mode>3_imm_dot2"
3353   [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3354         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3355                              (match_operand:GPR 2 "logical_const_operand" "n,n"))
3356                     (const_int 0)))
3357    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3358         (and:GPR (match_dup 1)
3359                  (match_dup 2)))
3360    (clobber (match_scratch:CC 4 "=X,x"))]
3361   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3362    && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3363   "@
3364    andi%e2. %0,%1,%u2
3365    #"
3366   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3367   [(parallel [(set (match_dup 0)
3368                    (and:GPR (match_dup 1)
3369                             (match_dup 2)))
3370               (clobber (match_dup 4))])
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_split "*and<mode>3_imm_mask_dot"
3380   [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3381         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3382                              (match_operand:GPR 2 "logical_const_operand" "n,n"))
3383                     (const_int 0)))
3384    (clobber (match_scratch:GPR 0 "=r,r"))]
3385   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3386    && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3387   "@
3388    andi%e2. %0,%1,%u2
3389    #"
3390   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3391   [(set (match_dup 0)
3392         (and:GPR (match_dup 1)
3393                  (match_dup 2)))
3394    (set (match_dup 3)
3395         (compare:CC (match_dup 0)
3396                     (const_int 0)))]
3397   ""
3398   [(set_attr "type" "logical")
3399    (set_attr "dot" "yes")
3400    (set_attr "length" "4,8")])
3402 (define_insn_and_split "*and<mode>3_imm_mask_dot2"
3403   [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3404         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3405                              (match_operand:GPR 2 "logical_const_operand" "n,n"))
3406                     (const_int 0)))
3407    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3408         (and:GPR (match_dup 1)
3409                  (match_dup 2)))]
3410   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3411    && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3412   "@
3413    andi%e2. %0,%1,%u2
3414    #"
3415   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3416   [(set (match_dup 0)
3417         (and:GPR (match_dup 1)
3418                  (match_dup 2)))
3419    (set (match_dup 3)
3420         (compare:CC (match_dup 0)
3421                     (const_int 0)))]
3422   ""
3423   [(set_attr "type" "logical")
3424    (set_attr "dot" "yes")
3425    (set_attr "length" "4,8")])
3427 (define_insn "*and<mode>3_imm_dot_shifted"
3428   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
3429         (compare:CC
3430           (and:GPR
3431             (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3432                           (match_operand:SI 4 "const_int_operand" "n"))
3433             (match_operand:GPR 2 "const_int_operand" "n"))
3434           (const_int 0)))
3435    (clobber (match_scratch:GPR 0 "=r"))]
3436   "logical_const_operand (GEN_INT (UINTVAL (operands[2])
3437                                    << INTVAL (operands[4])),
3438                           DImode)
3439    && (<MODE>mode == Pmode
3440        || (UINTVAL (operands[2]) << INTVAL (operands[4])) <= 0x7fffffff)"
3442   operands[2] = GEN_INT (UINTVAL (operands[2]) << INTVAL (operands[4]));
3443   return "andi%e2. %0,%1,%u2";
3445   [(set_attr "type" "logical")
3446    (set_attr "dot" "yes")])
3449 (define_insn "and<mode>3_mask"
3450   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3451         (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3452                  (match_operand:GPR 2 "const_int_operand" "n")))]
3453   "rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3455   return rs6000_insn_for_and_mask (<MODE>mode, operands, false);
3457   [(set_attr "type" "shift")])
3459 (define_insn_and_split "*and<mode>3_mask_dot"
3460   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3461         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3462                              (match_operand:GPR 2 "const_int_operand" "n,n"))
3463                     (const_int 0)))
3464    (clobber (match_scratch:GPR 0 "=r,r"))]
3465   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3466    && !logical_const_operand (operands[2], <MODE>mode)
3467    && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3469   if (which_alternative == 0)
3470     return rs6000_insn_for_and_mask (<MODE>mode, operands, true);
3471   else
3472     return "#";
3474   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3475   [(set (match_dup 0)
3476         (and:GPR (match_dup 1)
3477                  (match_dup 2)))
3478    (set (match_dup 3)
3479         (compare:CC (match_dup 0)
3480                     (const_int 0)))]
3481   ""
3482   [(set_attr "type" "shift")
3483    (set_attr "dot" "yes")
3484    (set_attr "length" "4,8")])
3486 (define_insn_and_split "*and<mode>3_mask_dot2"
3487   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3488         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3489                              (match_operand:GPR 2 "const_int_operand" "n,n"))
3490                     (const_int 0)))
3491    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3492         (and:GPR (match_dup 1)
3493                  (match_dup 2)))]
3494   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3495    && !logical_const_operand (operands[2], <MODE>mode)
3496    && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3498   if (which_alternative == 0)
3499     return rs6000_insn_for_and_mask (<MODE>mode, operands, true);
3500   else
3501     return "#";
3503   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3504   [(set (match_dup 0)
3505         (and:GPR (match_dup 1)
3506                  (match_dup 2)))
3507    (set (match_dup 3)
3508         (compare:CC (match_dup 0)
3509                     (const_int 0)))]
3510   ""
3511   [(set_attr "type" "shift")
3512    (set_attr "dot" "yes")
3513    (set_attr "length" "4,8")])
3516 (define_insn_and_split "*and<mode>3_2insn"
3517   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3518         (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3519                  (match_operand:GPR 2 "const_int_operand" "n")))]
3520   "rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3521    && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3522         || logical_const_operand (operands[2], <MODE>mode))"
3523   "#"
3524   "&& 1"
3525   [(pc)]
3527   rs6000_emit_2insn_and (<MODE>mode, operands, false, 0);
3528   DONE;
3530   [(set_attr "type" "shift")
3531    (set_attr "length" "8")])
3533 (define_insn_and_split "*and<mode>3_2insn_dot"
3534   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3535         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3536                              (match_operand:GPR 2 "const_int_operand" "n,n"))
3537                     (const_int 0)))
3538    (clobber (match_scratch:GPR 0 "=r,r"))]
3539   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3540    && rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3541    && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3542         || logical_const_operand (operands[2], <MODE>mode))"
3543   "#"
3544   "&& reload_completed"
3545   [(pc)]
3547   rs6000_emit_2insn_and (<MODE>mode, operands, false, 1);
3548   DONE;
3550   [(set_attr "type" "shift")
3551    (set_attr "dot" "yes")
3552    (set_attr "length" "8,12")])
3554 (define_insn_and_split "*and<mode>3_2insn_dot2"
3555   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3556         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3557                              (match_operand:GPR 2 "const_int_operand" "n,n"))
3558                     (const_int 0)))
3559    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3560         (and:GPR (match_dup 1)
3561                  (match_dup 2)))]
3562   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3563    && rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3564    && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3565         || logical_const_operand (operands[2], <MODE>mode))"
3566   "#"
3567   "&& reload_completed"
3568   [(pc)]
3570   rs6000_emit_2insn_and (<MODE>mode, operands, false, 2);
3571   DONE;
3573   [(set_attr "type" "shift")
3574    (set_attr "dot" "yes")
3575    (set_attr "length" "8,12")])
3578 (define_expand "<code><mode>3"
3579   [(set (match_operand:SDI 0 "gpc_reg_operand")
3580         (iorxor:SDI (match_operand:SDI 1 "gpc_reg_operand")
3581                     (match_operand:SDI 2 "reg_or_cint_operand")))]
3582   ""
3584   if (<MODE>mode == DImode && !TARGET_POWERPC64)
3585     {
3586       rs6000_split_logical (operands, <CODE>, false, false, false);
3587       DONE;
3588     }
3590   if (non_logical_cint_operand (operands[2], <MODE>mode))
3591     {
3592       rtx tmp = ((!can_create_pseudo_p ()
3593                   || rtx_equal_p (operands[0], operands[1]))
3594                  ? operands[0] : gen_reg_rtx (<MODE>mode));
3596       HOST_WIDE_INT value = INTVAL (operands[2]);
3597       HOST_WIDE_INT lo = value & 0xffff;
3598       HOST_WIDE_INT hi = value - lo;
3600       emit_insn (gen_<code><mode>3 (tmp, operands[1], GEN_INT (hi)));
3601       emit_insn (gen_<code><mode>3 (operands[0], tmp, GEN_INT (lo)));
3602       DONE;
3603     }
3605   if (!reg_or_logical_cint_operand (operands[2], <MODE>mode))
3606     operands[2] = force_reg (<MODE>mode, operands[2]);
3609 (define_split
3610   [(set (match_operand:GPR 0 "gpc_reg_operand")
3611         (iorxor:GPR (match_operand:GPR 1 "gpc_reg_operand")
3612                     (match_operand:GPR 2 "non_logical_cint_operand")))]
3613   ""
3614   [(set (match_dup 3)
3615         (iorxor:GPR (match_dup 1)
3616                     (match_dup 4)))
3617    (set (match_dup 0)
3618         (iorxor:GPR (match_dup 3)
3619                     (match_dup 5)))]
3621   operands[3] = ((!can_create_pseudo_p ()
3622                   || rtx_equal_p (operands[0], operands[1]))
3623                  ? operands[0] : gen_reg_rtx (<MODE>mode));
3625   HOST_WIDE_INT value = INTVAL (operands[2]);
3626   HOST_WIDE_INT lo = value & 0xffff;
3627   HOST_WIDE_INT hi = value - lo;
3629   operands[4] = GEN_INT (hi);
3630   operands[5] = GEN_INT (lo);
3633 (define_insn "*bool<mode>3_imm"
3634   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3635         (match_operator:GPR 3 "boolean_or_operator"
3636          [(match_operand:GPR 1 "gpc_reg_operand" "%r")
3637           (match_operand:GPR 2 "logical_const_operand" "n")]))]
3638   ""
3639   "%q3i%e2 %0,%1,%u2"
3640   [(set_attr "type" "logical")])
3642 (define_insn "*bool<mode>3"
3643   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3644         (match_operator:GPR 3 "boolean_operator"
3645          [(match_operand:GPR 1 "gpc_reg_operand" "r")
3646           (match_operand:GPR 2 "gpc_reg_operand" "r")]))]
3647   ""
3648   "%q3 %0,%1,%2"
3649   [(set_attr "type" "logical")])
3651 (define_insn_and_split "*bool<mode>3_dot"
3652   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3653         (compare:CC (match_operator:GPR 3 "boolean_operator"
3654          [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3655           (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
3656          (const_int 0)))
3657    (clobber (match_scratch:GPR 0 "=r,r"))]
3658   "<MODE>mode == Pmode"
3659   "@
3660    %q3. %0,%1,%2
3661    #"
3662   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3663   [(set (match_dup 0)
3664         (match_dup 3))
3665    (set (match_dup 4)
3666         (compare:CC (match_dup 0)
3667                     (const_int 0)))]
3668   ""
3669   [(set_attr "type" "logical")
3670    (set_attr "dot" "yes")
3671    (set_attr "length" "4,8")])
3673 (define_insn_and_split "*bool<mode>3_dot2"
3674   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3675         (compare:CC (match_operator:GPR 3 "boolean_operator"
3676          [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3677           (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
3678          (const_int 0)))
3679    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3680         (match_dup 3))]
3681   "<MODE>mode == Pmode"
3682   "@
3683    %q3. %0,%1,%2
3684    #"
3685   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3686   [(set (match_dup 0)
3687         (match_dup 3))
3688    (set (match_dup 4)
3689         (compare:CC (match_dup 0)
3690                     (const_int 0)))]
3691   ""
3692   [(set_attr "type" "logical")
3693    (set_attr "dot" "yes")
3694    (set_attr "length" "4,8")])
3697 (define_insn "*boolc<mode>3"
3698   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3699         (match_operator:GPR 3 "boolean_operator"
3700          [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))
3701           (match_operand:GPR 1 "gpc_reg_operand" "r")]))]
3702   ""
3703   "%q3 %0,%1,%2"
3704   [(set_attr "type" "logical")])
3706 (define_insn_and_split "*boolc<mode>3_dot"
3707   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3708         (compare:CC (match_operator:GPR 3 "boolean_operator"
3709          [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3710           (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
3711          (const_int 0)))
3712    (clobber (match_scratch:GPR 0 "=r,r"))]
3713   "<MODE>mode == Pmode"
3714   "@
3715    %q3. %0,%1,%2
3716    #"
3717   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3718   [(set (match_dup 0)
3719         (match_dup 3))
3720    (set (match_dup 4)
3721         (compare:CC (match_dup 0)
3722                     (const_int 0)))]
3723   ""
3724   [(set_attr "type" "logical")
3725    (set_attr "dot" "yes")
3726    (set_attr "length" "4,8")])
3728 (define_insn_and_split "*boolc<mode>3_dot2"
3729   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3730         (compare:CC (match_operator:GPR 3 "boolean_operator"
3731          [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3732           (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
3733          (const_int 0)))
3734    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3735         (match_dup 3))]
3736   "<MODE>mode == Pmode"
3737   "@
3738    %q3. %0,%1,%2
3739    #"
3740   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3741   [(set (match_dup 0)
3742         (match_dup 3))
3743    (set (match_dup 4)
3744         (compare:CC (match_dup 0)
3745                     (const_int 0)))]
3746   ""
3747   [(set_attr "type" "logical")
3748    (set_attr "dot" "yes")
3749    (set_attr "length" "4,8")])
3752 (define_insn "*boolcc<mode>3"
3753   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3754         (match_operator:GPR 3 "boolean_operator"
3755          [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
3756           (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))]))]
3757   ""
3758   "%q3 %0,%1,%2"
3759   [(set_attr "type" "logical")])
3761 (define_insn_and_split "*boolcc<mode>3_dot"
3762   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3763         (compare:CC (match_operator:GPR 3 "boolean_operator"
3764          [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
3765           (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
3766          (const_int 0)))
3767    (clobber (match_scratch:GPR 0 "=r,r"))]
3768   "<MODE>mode == Pmode"
3769   "@
3770    %q3. %0,%1,%2
3771    #"
3772   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3773   [(set (match_dup 0)
3774         (match_dup 3))
3775    (set (match_dup 4)
3776         (compare:CC (match_dup 0)
3777                     (const_int 0)))]
3778   ""
3779   [(set_attr "type" "logical")
3780    (set_attr "dot" "yes")
3781    (set_attr "length" "4,8")])
3783 (define_insn_and_split "*boolcc<mode>3_dot2"
3784   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3785         (compare:CC (match_operator:GPR 3 "boolean_operator"
3786          [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
3787           (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
3788          (const_int 0)))
3789    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3790         (match_dup 3))]
3791   "<MODE>mode == Pmode"
3792   "@
3793    %q3. %0,%1,%2
3794    #"
3795   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3796   [(set (match_dup 0)
3797         (match_dup 3))
3798    (set (match_dup 4)
3799         (compare:CC (match_dup 0)
3800                     (const_int 0)))]
3801   ""
3802   [(set_attr "type" "logical")
3803    (set_attr "dot" "yes")
3804    (set_attr "length" "4,8")])
3807 ;; TODO: Should have dots of this as well.
3808 (define_insn "*eqv<mode>3"
3809   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3810         (not:GPR (xor:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3811                           (match_operand:GPR 2 "gpc_reg_operand" "r"))))]
3812   ""
3813   "eqv %0,%1,%2"
3814   [(set_attr "type" "logical")])
3816 ;; Rotate-and-mask and insert.
3818 (define_insn "*rotl<mode>3_mask"
3819   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3820         (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3821                   [(match_operand:GPR 1 "gpc_reg_operand" "r")
3822                    (match_operand:SI 2 "reg_or_cint_operand" "rn")])
3823                  (match_operand:GPR 3 "const_int_operand" "n")))]
3824   "rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3826   return rs6000_insn_for_shift_mask (<MODE>mode, operands, false);
3828   [(set_attr "type" "shift")
3829    (set_attr "maybe_var_shift" "yes")])
3831 (define_insn_and_split "*rotl<mode>3_mask_dot"
3832   [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y")
3833         (compare:CC
3834           (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3835                     [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3836                      (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")])
3837                    (match_operand:GPR 3 "const_int_operand" "n,n"))
3838           (const_int 0)))
3839    (clobber (match_scratch:GPR 0 "=r,r"))]
3840   "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff)
3841    && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3843   if (which_alternative == 0)
3844     return rs6000_insn_for_shift_mask (<MODE>mode, operands, true);
3845   else
3846     return "#";
3848   "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)"
3849   [(set (match_dup 0)
3850         (and:GPR (match_dup 4)
3851                  (match_dup 3)))
3852    (set (match_dup 5)
3853         (compare:CC (match_dup 0)
3854                     (const_int 0)))]
3855   ""
3856   [(set_attr "type" "shift")
3857    (set_attr "maybe_var_shift" "yes")
3858    (set_attr "dot" "yes")
3859    (set_attr "length" "4,8")])
3861 (define_insn_and_split "*rotl<mode>3_mask_dot2"
3862   [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y")
3863         (compare:CC
3864           (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3865                     [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3866                      (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")])
3867                    (match_operand:GPR 3 "const_int_operand" "n,n"))
3868           (const_int 0)))
3869    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3870         (and:GPR (match_dup 4)
3871                  (match_dup 3)))]
3872   "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff)
3873    && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3875   if (which_alternative == 0)
3876     return rs6000_insn_for_shift_mask (<MODE>mode, operands, true);
3877   else
3878     return "#";
3880   "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)"
3881   [(set (match_dup 0)
3882         (and:GPR (match_dup 4)
3883                  (match_dup 3)))
3884    (set (match_dup 5)
3885         (compare:CC (match_dup 0)
3886                     (const_int 0)))]
3887   ""
3888   [(set_attr "type" "shift")
3889    (set_attr "maybe_var_shift" "yes")
3890    (set_attr "dot" "yes")
3891    (set_attr "length" "4,8")])
3893 ; Special case for less-than-0.  We can do it with just one machine
3894 ; instruction, but the generic optimizers do not realise it is cheap.
3895 (define_insn "*lt0_<mode>di"
3896   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3897         (lt:GPR (match_operand:DI 1 "gpc_reg_operand" "r")
3898                 (const_int 0)))]
3899   "TARGET_POWERPC64"
3900   "srdi %0,%1,63"
3901   [(set_attr "type" "shift")])
3903 (define_insn "*lt0_<mode>si"
3904   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3905         (lt:GPR (match_operand:SI 1 "gpc_reg_operand" "r")
3906                 (const_int 0)))]
3907   ""
3908   "rlwinm %0,%1,1,31,31"
3909   [(set_attr "type" "shift")])
3913 ; Two forms for insert (the two arms of the IOR are not canonicalized,
3914 ; both are an AND so are the same precedence).
3915 (define_insn "*rotl<mode>3_insert"
3916   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3917         (ior:GPR (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3918                            [(match_operand:GPR 1 "gpc_reg_operand" "r")
3919                             (match_operand:SI 2 "const_int_operand" "n")])
3920                           (match_operand:GPR 3 "const_int_operand" "n"))
3921                  (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0")
3922                           (match_operand:GPR 6 "const_int_operand" "n"))))]
3923   "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode)
3924    && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0"
3926   return rs6000_insn_for_insert_mask (<MODE>mode, operands, false);
3928   [(set_attr "type" "insert")])
3929 ; FIXME: this needs an attr "size", so that the scheduler can see the
3930 ; difference between rlwimi and rldimi.  We also might want dot forms,
3931 ; but not for rlwimi on POWER4 and similar processors.
3933 (define_insn "*rotl<mode>3_insert_2"
3934   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3935         (ior:GPR (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0")
3936                           (match_operand:GPR 6 "const_int_operand" "n"))
3937                  (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3938                            [(match_operand:GPR 1 "gpc_reg_operand" "r")
3939                             (match_operand:SI 2 "const_int_operand" "n")])
3940                           (match_operand:GPR 3 "const_int_operand" "n"))))]
3941   "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode)
3942    && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0"
3944   return rs6000_insn_for_insert_mask (<MODE>mode, operands, false);
3946   [(set_attr "type" "insert")])
3948 ; There are also some forms without one of the ANDs.
3949 (define_insn "*rotl<mode>3_insert_3"
3950   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3951         (ior:GPR (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0")
3952                           (match_operand:GPR 4 "const_int_operand" "n"))
3953                  (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3954                              (match_operand:SI 2 "const_int_operand" "n"))))]
3955   "INTVAL (operands[2]) == exact_log2 (UINTVAL (operands[4]) + 1)"
3957   if (<MODE>mode == SImode)
3958     return "rlwimi %0,%1,%h2,0,31-%h2";
3959   else
3960     return "rldimi %0,%1,%H2,0";
3962   [(set_attr "type" "insert")])
3964 (define_insn "*rotl<mode>3_insert_4"
3965   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3966         (ior:GPR (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0")
3967                           (match_operand:GPR 4 "const_int_operand" "n"))
3968                  (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3969                                (match_operand:SI 2 "const_int_operand" "n"))))]
3970   "<MODE>mode == SImode &&
3971    GET_MODE_PRECISION (<MODE>mode)
3972    == INTVAL (operands[2]) + exact_log2 (-UINTVAL (operands[4]))"
3974   operands[2] = GEN_INT (GET_MODE_PRECISION (<MODE>mode)
3975                          - INTVAL (operands[2]));
3976   if (<MODE>mode == SImode)
3977     return "rlwimi %0,%1,%h2,32-%h2,31";
3978   else
3979     return "rldimi %0,%1,%H2,64-%H2";
3981   [(set_attr "type" "insert")])
3983 (define_insn "*rotlsi3_insert_5"
3984   [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
3985         (ior:SI (and:SI (match_operand:SI 1 "gpc_reg_operand" "0,r")
3986                         (match_operand:SI 2 "const_int_operand" "n,n"))
3987                 (and:SI (match_operand:SI 3 "gpc_reg_operand" "r,0")
3988                         (match_operand:SI 4 "const_int_operand" "n,n"))))]
3989   "rs6000_is_valid_mask (operands[2], NULL, NULL, SImode)
3990    && UINTVAL (operands[2]) != 0 && UINTVAL (operands[4]) != 0
3991    && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
3992   "@
3993    rlwimi %0,%3,0,%4
3994    rlwimi %0,%1,0,%2"
3995   [(set_attr "type" "insert")])
3997 (define_insn "*rotldi3_insert_6"
3998   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3999         (ior:DI (and:DI (match_operand:DI 1 "gpc_reg_operand" "0")
4000                         (match_operand:DI 2 "const_int_operand" "n"))
4001                 (and:DI (match_operand:DI 3 "gpc_reg_operand" "r")
4002                         (match_operand:DI 4 "const_int_operand" "n"))))]
4003   "exact_log2 (-UINTVAL (operands[2])) > 0
4004    && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
4006   operands[5] = GEN_INT (64 - exact_log2 (-UINTVAL (operands[2])));
4007   return "rldimi %0,%3,0,%5";
4009   [(set_attr "type" "insert")
4010    (set_attr "size" "64")])
4012 (define_insn "*rotldi3_insert_7"
4013   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4014         (ior:DI (and:DI (match_operand:DI 3 "gpc_reg_operand" "r")
4015                         (match_operand:DI 4 "const_int_operand" "n"))
4016                 (and:DI (match_operand:DI 1 "gpc_reg_operand" "0")
4017                         (match_operand:DI 2 "const_int_operand" "n"))))]
4018   "exact_log2 (-UINTVAL (operands[2])) > 0
4019    && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
4021   operands[5] = GEN_INT (64 - exact_log2 (-UINTVAL (operands[2])));
4022   return "rldimi %0,%3,0,%5";
4024   [(set_attr "type" "insert")
4025    (set_attr "size" "64")])
4028 ; This handles the important case of multiple-precision shifts.  There is
4029 ; no canonicalization rule for ASHIFT vs. LSHIFTRT, so two patterns.
4030 (define_split
4031   [(set (match_operand:GPR 0 "gpc_reg_operand")
4032         (ior:GPR (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand")
4033                              (match_operand:SI 3 "const_int_operand"))
4034                  (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand")
4035                                (match_operand:SI 4 "const_int_operand"))))]
4036   "can_create_pseudo_p ()
4037    && INTVAL (operands[3]) + INTVAL (operands[4])
4038       >= GET_MODE_PRECISION (<MODE>mode)"
4039   [(set (match_dup 5)
4040         (lshiftrt:GPR (match_dup 2)
4041                       (match_dup 4)))
4042    (set (match_dup 0)
4043         (ior:GPR (and:GPR (match_dup 5)
4044                           (match_dup 6))
4045                  (ashift:GPR (match_dup 1)
4046                              (match_dup 3))))]
4048   unsigned HOST_WIDE_INT mask = 1;
4049   mask = (mask << INTVAL (operands[3])) - 1;
4050   operands[5] = gen_reg_rtx (<MODE>mode);
4051   operands[6] = GEN_INT (mask);
4054 (define_split
4055   [(set (match_operand:GPR 0 "gpc_reg_operand")
4056         (ior:GPR (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand")
4057                                (match_operand:SI 4 "const_int_operand"))
4058                  (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand")
4059                              (match_operand:SI 3 "const_int_operand"))))]
4060   "can_create_pseudo_p ()
4061    && INTVAL (operands[3]) + INTVAL (operands[4])
4062       >= GET_MODE_PRECISION (<MODE>mode)"
4063   [(set (match_dup 5)
4064         (lshiftrt:GPR (match_dup 2)
4065                       (match_dup 4)))
4066    (set (match_dup 0)
4067         (ior:GPR (and:GPR (match_dup 5)
4068                           (match_dup 6))
4069                  (ashift:GPR (match_dup 1)
4070                              (match_dup 3))))]
4072   unsigned HOST_WIDE_INT mask = 1;
4073   mask = (mask << INTVAL (operands[3])) - 1;
4074   operands[5] = gen_reg_rtx (<MODE>mode);
4075   operands[6] = GEN_INT (mask);
4079 ; Another important case is setting some bits to 1; we can do that with
4080 ; an insert instruction, in many cases.
4081 (define_insn_and_split "*ior<mode>_mask"
4082   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4083         (ior:GPR (match_operand:GPR 1 "gpc_reg_operand" "0")
4084                  (match_operand:GPR 2 "const_int_operand" "n")))
4085    (clobber (match_scratch:GPR 3 "=r"))]
4086   "!logical_const_operand (operands[2], <MODE>mode)
4087    && rs6000_is_valid_mask (operands[2], NULL, NULL, <MODE>mode)"
4088   "#"
4089   "&& 1"
4090   [(set (match_dup 3)
4091         (const_int -1))
4092    (set (match_dup 0)
4093         (ior:GPR (and:GPR (rotate:GPR (match_dup 3)
4094                                       (match_dup 4))
4095                           (match_dup 2))
4096                  (and:GPR (match_dup 1)
4097                           (match_dup 5))))]
4099   int nb, ne;
4100   rs6000_is_valid_mask (operands[2], &nb, &ne, <MODE>mode);
4101   if (GET_CODE (operands[3]) == SCRATCH)
4102     operands[3] = gen_reg_rtx (<MODE>mode);
4103   operands[4] = GEN_INT (ne);
4104   operands[5] = GEN_INT (~UINTVAL (operands[2]));
4106   [(set_attr "type" "two")
4107    (set_attr "length" "8")])
4110 ; Yet another case is an rldimi with the second value coming from memory.
4111 ; The zero_extend that should become part of the rldimi is merged into the
4112 ; load from memory instead.  Split things properly again.
4113 (define_split
4114   [(set (match_operand:DI 0 "gpc_reg_operand")
4115         (ior:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand")
4116                            (match_operand:SI 2 "const_int_operand"))
4117                 (zero_extend:DI (match_operand:QHSI 3 "memory_operand"))))]
4118   "INTVAL (operands[2]) == <bits>"
4119   [(set (match_dup 4)
4120         (zero_extend:DI (match_dup 3)))
4121    (set (match_dup 0)
4122         (ior:DI (and:DI (match_dup 4)
4123                         (match_dup 5))
4124                 (ashift:DI (match_dup 1)
4125                            (match_dup 2))))]
4127   operands[4] = gen_reg_rtx (DImode);
4128   operands[5] = GEN_INT ((HOST_WIDE_INT_1U << <bits>) - 1);
4131 ; rlwimi, too.
4132 (define_split
4133   [(set (match_operand:SI 0 "gpc_reg_operand")
4134         (ior:SI (ashift:SI (match_operand:SI 1 "gpc_reg_operand")
4135                            (match_operand:SI 2 "const_int_operand"))
4136                 (zero_extend:SI (match_operand:QHI 3 "memory_operand"))))]
4137   "INTVAL (operands[2]) == <bits>"
4138   [(set (match_dup 4)
4139         (zero_extend:SI (match_dup 3)))
4140    (set (match_dup 0)
4141         (ior:SI (and:SI (match_dup 4)
4142                         (match_dup 5))
4143                 (ashift:SI (match_dup 1)
4144                            (match_dup 2))))]
4146   operands[4] = gen_reg_rtx (SImode);
4147   operands[5] = GEN_INT ((HOST_WIDE_INT_1U << <bits>) - 1);
4151 ;; Now the simple shifts.
4153 (define_insn "rotl<mode>3"
4154   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4155         (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4156                     (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4157   ""
4158   "rotl<wd>%I2 %0,%1,%<hH>2"
4159   [(set_attr "type" "shift")
4160    (set_attr "maybe_var_shift" "yes")])
4162 (define_insn "*rotlsi3_64"
4163   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4164         (zero_extend:DI
4165             (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4166                        (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4167   "TARGET_POWERPC64"
4168   "rotlw%I2 %0,%1,%h2"
4169   [(set_attr "type" "shift")
4170    (set_attr "maybe_var_shift" "yes")])
4172 (define_insn_and_split "*rotl<mode>3_dot"
4173   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4174         (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4175                                 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4176                     (const_int 0)))
4177    (clobber (match_scratch:GPR 0 "=r,r"))]
4178   "<MODE>mode == Pmode"
4179   "@
4180    rotl<wd>%I2. %0,%1,%<hH>2
4181    #"
4182   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4183   [(set (match_dup 0)
4184         (rotate:GPR (match_dup 1)
4185                     (match_dup 2)))
4186    (set (match_dup 3)
4187         (compare:CC (match_dup 0)
4188                     (const_int 0)))]
4189   ""
4190   [(set_attr "type" "shift")
4191    (set_attr "maybe_var_shift" "yes")
4192    (set_attr "dot" "yes")
4193    (set_attr "length" "4,8")])
4195 (define_insn_and_split "*rotl<mode>3_dot2"
4196   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4197         (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4198                                 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4199                     (const_int 0)))
4200    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4201         (rotate:GPR (match_dup 1)
4202                     (match_dup 2)))]
4203   "<MODE>mode == Pmode"
4204   "@
4205    rotl<wd>%I2. %0,%1,%<hH>2
4206    #"
4207   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4208   [(set (match_dup 0)
4209         (rotate:GPR (match_dup 1)
4210                     (match_dup 2)))
4211    (set (match_dup 3)
4212         (compare:CC (match_dup 0)
4213                     (const_int 0)))]
4214   ""
4215   [(set_attr "type" "shift")
4216    (set_attr "maybe_var_shift" "yes")
4217    (set_attr "dot" "yes")
4218    (set_attr "length" "4,8")])
4221 (define_insn "ashl<mode>3"
4222   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4223         (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4224                     (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4225   ""
4226   "sl<wd>%I2 %0,%1,%<hH>2"
4227   [(set_attr "type" "shift")
4228    (set_attr "maybe_var_shift" "yes")])
4230 (define_insn "*ashlsi3_64"
4231   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4232         (zero_extend:DI
4233             (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4234                        (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4235   "TARGET_POWERPC64"
4236   "slw%I2 %0,%1,%h2"
4237   [(set_attr "type" "shift")
4238    (set_attr "maybe_var_shift" "yes")])
4240 (define_insn_and_split "*ashl<mode>3_dot"
4241   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4242         (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4243                                 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4244                     (const_int 0)))
4245    (clobber (match_scratch:GPR 0 "=r,r"))]
4246   "<MODE>mode == Pmode"
4247   "@
4248    sl<wd>%I2. %0,%1,%<hH>2
4249    #"
4250   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4251   [(set (match_dup 0)
4252         (ashift:GPR (match_dup 1)
4253                     (match_dup 2)))
4254    (set (match_dup 3)
4255         (compare:CC (match_dup 0)
4256                     (const_int 0)))]
4257   ""
4258   [(set_attr "type" "shift")
4259    (set_attr "maybe_var_shift" "yes")
4260    (set_attr "dot" "yes")
4261    (set_attr "length" "4,8")])
4263 (define_insn_and_split "*ashl<mode>3_dot2"
4264   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4265         (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4266                                 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4267                     (const_int 0)))
4268    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4269         (ashift:GPR (match_dup 1)
4270                     (match_dup 2)))]
4271   "<MODE>mode == Pmode"
4272   "@
4273    sl<wd>%I2. %0,%1,%<hH>2
4274    #"
4275   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4276   [(set (match_dup 0)
4277         (ashift:GPR (match_dup 1)
4278                     (match_dup 2)))
4279    (set (match_dup 3)
4280         (compare:CC (match_dup 0)
4281                     (const_int 0)))]
4282   ""
4283   [(set_attr "type" "shift")
4284    (set_attr "maybe_var_shift" "yes")
4285    (set_attr "dot" "yes")
4286    (set_attr "length" "4,8")])
4288 ;; Pretend we have a memory form of extswsli until register allocation is done
4289 ;; so that we use LWZ to load the value from memory, instead of LWA.
4290 (define_insn_and_split "ashdi3_extswsli"
4291   [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
4292         (ashift:DI
4293          (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,m"))
4294          (match_operand:DI 2 "u6bit_cint_operand" "n,n")))]
4295   "TARGET_EXTSWSLI"
4296   "@
4297    extswsli %0,%1,%2
4298    #"
4299   "&& reload_completed && MEM_P (operands[1])"
4300   [(set (match_dup 3)
4301         (match_dup 1))
4302    (set (match_dup 0)
4303         (ashift:DI (sign_extend:DI (match_dup 3))
4304                    (match_dup 2)))]
4306   operands[3] = gen_lowpart (SImode, operands[0]);
4308   [(set_attr "type" "shift")
4309    (set_attr "maybe_var_shift" "no")])
4312 (define_insn_and_split "ashdi3_extswsli_dot"
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    (clobber (match_scratch:DI 0 "=r,r,r,r"))]
4320   "TARGET_EXTSWSLI"
4321   "@
4322    extswsli. %0,%1,%2
4323    #
4324    #
4325    #"
4326   "&& reload_completed
4327    && (cc_reg_not_cr0_operand (operands[3], CCmode)
4328        || memory_operand (operands[1], SImode))"
4329   [(pc)]
4331   rtx dest = operands[0];
4332   rtx src = operands[1];
4333   rtx shift = operands[2];
4334   rtx cr = operands[3];
4335   rtx src2;
4337   if (!MEM_P (src))
4338     src2 = src;
4339   else
4340     {
4341       src2 = gen_lowpart (SImode, dest);
4342       emit_move_insn (src2, src);
4343     }
4345   if (REGNO (cr) == CR0_REGNO)
4346     {
4347       emit_insn (gen_ashdi3_extswsli_dot2 (dest, src2, shift, cr));
4348       DONE;
4349     }
4351   emit_insn (gen_ashdi3_extswsli (dest, src2, shift));
4352   emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx)));
4353   DONE;
4355   [(set_attr "type" "shift")
4356    (set_attr "maybe_var_shift" "no")
4357    (set_attr "dot" "yes")
4358    (set_attr "length" "4,8,8,12")])
4360 (define_insn_and_split "ashdi3_extswsli_dot2"
4361   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y")
4362         (compare:CC
4363          (ashift:DI
4364           (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m"))
4365           (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n"))
4366          (const_int 0)))
4367    (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r")
4368         (ashift:DI (sign_extend:DI (match_dup 1))
4369                    (match_dup 2)))]
4370   "TARGET_EXTSWSLI"
4371   "@
4372    extswsli. %0,%1,%2
4373    #
4374    #
4375    #"
4376   "&& reload_completed
4377    && (cc_reg_not_cr0_operand (operands[3], CCmode)
4378        || memory_operand (operands[1], SImode))"
4379   [(pc)]
4381   rtx dest = operands[0];
4382   rtx src = operands[1];
4383   rtx shift = operands[2];
4384   rtx cr = operands[3];
4385   rtx src2;
4387   if (!MEM_P (src))
4388     src2 = src;
4389   else
4390     {
4391       src2 = gen_lowpart (SImode, dest);
4392       emit_move_insn (src2, src);
4393     }
4395   if (REGNO (cr) == CR0_REGNO)
4396     {
4397       emit_insn (gen_ashdi3_extswsli_dot2 (dest, src2, shift, cr));
4398       DONE;
4399     }
4401   emit_insn (gen_ashdi3_extswsli (dest, src2, shift));
4402   emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx)));
4403   DONE;
4405   [(set_attr "type" "shift")
4406    (set_attr "maybe_var_shift" "no")
4407    (set_attr "dot" "yes")
4408    (set_attr "length" "4,8,8,12")])
4410 (define_insn "lshr<mode>3"
4411   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4412         (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4413                       (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4414   ""
4415   "sr<wd>%I2 %0,%1,%<hH>2"
4416   [(set_attr "type" "shift")
4417    (set_attr "maybe_var_shift" "yes")])
4419 (define_insn "*lshrsi3_64"
4420   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4421         (zero_extend:DI
4422             (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4423                          (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4424   "TARGET_POWERPC64"
4425   "srw%I2 %0,%1,%h2"
4426   [(set_attr "type" "shift")
4427    (set_attr "maybe_var_shift" "yes")])
4429 (define_insn_and_split "*lshr<mode>3_dot"
4430   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4431         (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4432                                   (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4433                     (const_int 0)))
4434    (clobber (match_scratch:GPR 0 "=r,r"))]
4435   "<MODE>mode == Pmode"
4436   "@
4437    sr<wd>%I2. %0,%1,%<hH>2
4438    #"
4439   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4440   [(set (match_dup 0)
4441         (lshiftrt:GPR (match_dup 1)
4442                       (match_dup 2)))
4443    (set (match_dup 3)
4444         (compare:CC (match_dup 0)
4445                     (const_int 0)))]
4446   ""
4447   [(set_attr "type" "shift")
4448    (set_attr "maybe_var_shift" "yes")
4449    (set_attr "dot" "yes")
4450    (set_attr "length" "4,8")])
4452 (define_insn_and_split "*lshr<mode>3_dot2"
4453   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4454         (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4455                                   (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4456                     (const_int 0)))
4457    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4458         (lshiftrt:GPR (match_dup 1)
4459                       (match_dup 2)))]
4460   "<MODE>mode == Pmode"
4461   "@
4462    sr<wd>%I2. %0,%1,%<hH>2
4463    #"
4464   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4465   [(set (match_dup 0)
4466         (lshiftrt:GPR (match_dup 1)
4467                       (match_dup 2)))
4468    (set (match_dup 3)
4469         (compare:CC (match_dup 0)
4470                     (const_int 0)))]
4471   ""
4472   [(set_attr "type" "shift")
4473    (set_attr "maybe_var_shift" "yes")
4474    (set_attr "dot" "yes")
4475    (set_attr "length" "4,8")])
4478 (define_insn "ashr<mode>3"
4479   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4480         (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4481                       (match_operand:SI 2 "reg_or_cint_operand" "rn")))
4482    (clobber (reg:GPR CA_REGNO))]
4483   ""
4484   "sra<wd>%I2 %0,%1,%<hH>2"
4485   [(set_attr "type" "shift")
4486    (set_attr "maybe_var_shift" "yes")])
4488 (define_insn "*ashrsi3_64"
4489   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4490         (sign_extend:DI
4491             (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4492                          (match_operand:SI 2 "reg_or_cint_operand" "rn"))))
4493    (clobber (reg:SI CA_REGNO))]
4494   "TARGET_POWERPC64"
4495   "sraw%I2 %0,%1,%h2"
4496   [(set_attr "type" "shift")
4497    (set_attr "maybe_var_shift" "yes")])
4499 (define_insn_and_split "*ashr<mode>3_dot"
4500   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4501         (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4502                                   (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4503                     (const_int 0)))
4504    (clobber (match_scratch:GPR 0 "=r,r"))
4505    (clobber (reg:GPR CA_REGNO))]
4506   "<MODE>mode == Pmode"
4507   "@
4508    sra<wd>%I2. %0,%1,%<hH>2
4509    #"
4510   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4511   [(parallel [(set (match_dup 0)
4512                    (ashiftrt:GPR (match_dup 1)
4513                                  (match_dup 2)))
4514               (clobber (reg:GPR CA_REGNO))])
4515    (set (match_dup 3)
4516         (compare:CC (match_dup 0)
4517                     (const_int 0)))]
4518   ""
4519   [(set_attr "type" "shift")
4520    (set_attr "maybe_var_shift" "yes")
4521    (set_attr "dot" "yes")
4522    (set_attr "length" "4,8")])
4524 (define_insn_and_split "*ashr<mode>3_dot2"
4525   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4526         (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4527                                   (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4528                     (const_int 0)))
4529    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4530         (ashiftrt:GPR (match_dup 1)
4531                       (match_dup 2)))
4532    (clobber (reg:GPR CA_REGNO))]
4533   "<MODE>mode == Pmode"
4534   "@
4535    sra<wd>%I2. %0,%1,%<hH>2
4536    #"
4537   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4538   [(parallel [(set (match_dup 0)
4539                    (ashiftrt:GPR (match_dup 1)
4540                                  (match_dup 2)))
4541               (clobber (reg:GPR CA_REGNO))])
4542    (set (match_dup 3)
4543         (compare:CC (match_dup 0)
4544                     (const_int 0)))]
4545   ""
4546   [(set_attr "type" "shift")
4547    (set_attr "maybe_var_shift" "yes")
4548    (set_attr "dot" "yes")
4549    (set_attr "length" "4,8")])
4551 ;; Builtins to replace a division to generate FRE reciprocal estimate
4552 ;; instructions and the necessary fixup instructions
4553 (define_expand "recip<mode>3"
4554   [(match_operand:RECIPF 0 "gpc_reg_operand")
4555    (match_operand:RECIPF 1 "gpc_reg_operand")
4556    (match_operand:RECIPF 2 "gpc_reg_operand")]
4557   "RS6000_RECIP_HAVE_RE_P (<MODE>mode)"
4559    rs6000_emit_swdiv (operands[0], operands[1], operands[2], false);
4560    DONE;
4563 ;; Split to create division from FRE/FRES/etc. and fixup instead of the normal
4564 ;; hardware division.  This is only done before register allocation and with
4565 ;; -ffast-math.  This must appear before the divsf3/divdf3 insns.
4566 ;; We used to also check optimize_insn_for_speed_p () but problems with guessed
4567 ;; frequencies (pr68212/pr77536) yields that unreliable so it was removed.
4568 (define_split
4569   [(set (match_operand:RECIPF 0 "gpc_reg_operand")
4570         (div:RECIPF (match_operand 1 "gpc_reg_operand")
4571                     (match_operand 2 "gpc_reg_operand")))]
4572   "RS6000_RECIP_AUTO_RE_P (<MODE>mode)
4573    && can_create_pseudo_p () && flag_finite_math_only
4574    && !flag_trapping_math && flag_reciprocal_math"
4575   [(const_int 0)]
4577   rs6000_emit_swdiv (operands[0], operands[1], operands[2], true);
4578   DONE;
4581 ;; Builtins to replace 1/sqrt(x) with instructions using RSQRTE and the
4582 ;; appropriate fixup.
4583 (define_expand "rsqrt<mode>2"
4584   [(match_operand:RECIPF 0 "gpc_reg_operand")
4585    (match_operand:RECIPF 1 "gpc_reg_operand")]
4586   "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4588   rs6000_emit_swsqrt (operands[0], operands[1], 1);
4589   DONE;
4592 ;; Floating-point insns, excluding normal data motion.  We combine the SF/DF
4593 ;; modes here, and also add in conditional vsx/power8-vector support to access
4594 ;; values in the traditional Altivec registers if the appropriate
4595 ;; -mupper-regs-{df,sf} option is enabled.
4597 (define_expand "abs<mode>2"
4598   [(set (match_operand:SFDF 0 "gpc_reg_operand")
4599         (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))]
4600   "TARGET_HARD_FLOAT"
4601   "")
4603 (define_insn "*abs<mode>2_fpr"
4604   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4605         (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4606   "TARGET_HARD_FLOAT"
4607   "@
4608    fabs %0,%1
4609    xsabsdp %x0,%x1"
4610   [(set_attr "type" "fpsimple")])
4612 (define_insn "*nabs<mode>2_fpr"
4613   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4614         (neg:SFDF
4615          (abs:SFDF
4616           (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))))]
4617   "TARGET_HARD_FLOAT"
4618   "@
4619    fnabs %0,%1
4620    xsnabsdp %x0,%x1"
4621   [(set_attr "type" "fpsimple")])
4623 (define_expand "neg<mode>2"
4624   [(set (match_operand:SFDF 0 "gpc_reg_operand")
4625         (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))]
4626   "TARGET_HARD_FLOAT"
4627   "")
4629 (define_insn "*neg<mode>2_fpr"
4630   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4631         (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4632   "TARGET_HARD_FLOAT"
4633   "@
4634    fneg %0,%1
4635    xsnegdp %x0,%x1"
4636   [(set_attr "type" "fpsimple")])
4638 (define_expand "add<mode>3"
4639   [(set (match_operand:SFDF 0 "gpc_reg_operand")
4640         (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4641                    (match_operand:SFDF 2 "gpc_reg_operand")))]
4642   "TARGET_HARD_FLOAT"
4643   "")
4645 (define_insn "*add<mode>3_fpr"
4646   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa")
4647         (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,wa")
4648                    (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa")))]
4649   "TARGET_HARD_FLOAT"
4650   "@
4651    fadd<s> %0,%1,%2
4652    xsadd<sd>p %x0,%x1,%x2"
4653   [(set_attr "type" "fp")
4654    (set_attr "isa" "*,<Fisa>")])
4656 (define_expand "sub<mode>3"
4657   [(set (match_operand:SFDF 0 "gpc_reg_operand")
4658         (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4659                     (match_operand:SFDF 2 "gpc_reg_operand")))]
4660   "TARGET_HARD_FLOAT"
4661   "")
4663 (define_insn "*sub<mode>3_fpr"
4664   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa")
4665         (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa")
4666                     (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa")))]
4667   "TARGET_HARD_FLOAT"
4668   "@
4669    fsub<s> %0,%1,%2
4670    xssub<sd>p %x0,%x1,%x2"
4671   [(set_attr "type" "fp")
4672    (set_attr "isa" "*,<Fisa>")])
4674 (define_expand "mul<mode>3"
4675   [(set (match_operand:SFDF 0 "gpc_reg_operand")
4676         (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4677                    (match_operand:SFDF 2 "gpc_reg_operand")))]
4678   "TARGET_HARD_FLOAT"
4679   "")
4681 (define_insn "*mul<mode>3_fpr"
4682   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa")
4683         (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,wa")
4684                    (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa")))]
4685   "TARGET_HARD_FLOAT"
4686   "@
4687    fmul<s> %0,%1,%2
4688    xsmul<sd>p %x0,%x1,%x2"
4689   [(set_attr "type" "dmul")
4690    (set_attr "isa" "*,<Fisa>")])
4692 (define_expand "div<mode>3"
4693   [(set (match_operand:SFDF 0 "gpc_reg_operand")
4694         (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4695                   (match_operand:SFDF 2 "gpc_reg_operand")))]
4696   "TARGET_HARD_FLOAT"
4698   if (RS6000_RECIP_AUTO_RE_P (<MODE>mode)
4699       && can_create_pseudo_p () && flag_finite_math_only
4700       && !flag_trapping_math && flag_reciprocal_math)
4701     {
4702       rs6000_emit_swdiv (operands[0], operands[1], operands[2], true);
4703       DONE;
4704     }
4707 (define_insn "*div<mode>3_fpr"
4708   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa")
4709         (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa")
4710                   (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa")))]
4711   "TARGET_HARD_FLOAT"
4712   "@
4713    fdiv<s> %0,%1,%2
4714    xsdiv<sd>p %x0,%x1,%x2"
4715   [(set_attr "type" "<sd>div")
4716    (set_attr "isa" "*,<Fisa>")])
4718 (define_insn "*sqrt<mode>2_internal"
4719   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa")
4720         (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa")))]
4721   "TARGET_HARD_FLOAT && TARGET_PPC_GPOPT"
4722   "@
4723    fsqrt<s> %0,%1
4724    xssqrt<sd>p %x0,%x1"
4725   [(set_attr "type" "<sd>sqrt")
4726    (set_attr "isa" "*,<Fisa>")])
4728 (define_expand "sqrt<mode>2"
4729   [(set (match_operand:SFDF 0 "gpc_reg_operand")
4730         (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))]
4731   "TARGET_HARD_FLOAT && TARGET_PPC_GPOPT"
4733   if (<MODE>mode == SFmode
4734       && TARGET_RECIP_PRECISION
4735       && RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)
4736       && !optimize_function_for_size_p (cfun)
4737       && flag_finite_math_only && !flag_trapping_math
4738       && flag_unsafe_math_optimizations)
4739     {
4740       rs6000_emit_swsqrt (operands[0], operands[1], 0);
4741       DONE;
4742     }
4745 ;; Floating point reciprocal approximation
4746 (define_insn "fre<sd>"
4747   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa")
4748         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa")]
4749                      UNSPEC_FRES))]
4750   "TARGET_<FFRE>"
4751   "@
4752    fre<s> %0,%1
4753    xsre<sd>p %x0,%x1"
4754   [(set_attr "type" "fp")
4755    (set_attr "isa" "*,<Fisa>")])
4757 (define_insn "*rsqrt<mode>2"
4758   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa")
4759         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa")]
4760                      UNSPEC_RSQRT))]
4761   "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4762   "@
4763    frsqrte<s> %0,%1
4764    xsrsqrte<sd>p %x0,%x1"
4765   [(set_attr "type" "fp")
4766    (set_attr "isa" "*,<Fisa>")])
4768 ;; Floating point comparisons
4769 (define_insn "*cmp<mode>_fpr"
4770   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y,y")
4771         (compare:CCFP (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa")
4772                       (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa")))]
4773   "TARGET_HARD_FLOAT"
4774   "@
4775    fcmpu %0,%1,%2
4776    xscmpudp %0,%x1,%x2"
4777   [(set_attr "type" "fpcompare")
4778    (set_attr "isa" "*,<Fisa>")])
4780 ;; Floating point conversions
4781 (define_expand "extendsfdf2"
4782   [(set (match_operand:DF 0 "gpc_reg_operand")
4783         (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand")))]
4784   "TARGET_HARD_FLOAT"
4786   if (HONOR_SNANS (SFmode))
4787     operands[1] = force_reg (SFmode, operands[1]);
4790 (define_insn_and_split "*extendsfdf2_fpr"
4791   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d,d,wa,?wa,wa,v")
4792         (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand" "0,f,m,0,wa,Z,wY")))]
4793   "TARGET_HARD_FLOAT && !HONOR_SNANS (SFmode)"
4794   "@
4795    #
4796    fmr %0,%1
4797    lfs%U1%X1 %0,%1
4798    #
4799    xscpsgndp %x0,%x1,%x1
4800    lxsspx %x0,%y1
4801    lxssp %0,%1"
4802   "&& reload_completed && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1])"
4803   [(const_int 0)]
4805   emit_note (NOTE_INSN_DELETED);
4806   DONE;
4808   [(set_attr "type" "fp,fpsimple,fpload,fp,fpsimple,fpload,fpload")
4809    (set_attr "isa" "*,*,*,*,p8v,p8v,p9v")])
4811 (define_insn "*extendsfdf2_snan"
4812   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa")
4813         (float_extend:DF (match_operand:SF 1 "gpc_reg_operand" "f,wa")))]
4814   "TARGET_HARD_FLOAT && HONOR_SNANS (SFmode)"
4815   "@
4816    frsp %0,%1
4817    xsrsp %x0,%x1"
4818   [(set_attr "type" "fp")
4819    (set_attr "isa" "*,p8v")])
4821 (define_expand "truncdfsf2"
4822   [(set (match_operand:SF 0 "gpc_reg_operand")
4823         (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand")))]
4824   "TARGET_HARD_FLOAT"
4825   "")
4827 (define_insn "*truncdfsf2_fpr"
4828   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wa")
4829         (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "d,wa")))]
4830   "TARGET_HARD_FLOAT"
4831   "@
4832    frsp %0,%1
4833    xsrsp %x0,%x1"
4834   [(set_attr "type" "fp")
4835    (set_attr "isa" "*,p8v")])
4837 ;; This expander is here to avoid FLOAT_WORDS_BIGENDIAN tests in
4838 ;; builtins.c and optabs.c that are not correct for IBM long double
4839 ;; when little-endian.
4840 (define_expand "signbit<mode>2"
4841   [(set (match_dup 2)
4842         (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand")))
4843    (set (match_dup 3)
4844         (subreg:DI (match_dup 2) 0))
4845    (set (match_dup 4)
4846         (match_dup 5))
4847    (set (match_operand:SI 0 "gpc_reg_operand")
4848         (match_dup 6))]
4849   "TARGET_HARD_FLOAT
4850    && (!FLOAT128_IEEE_P (<MODE>mode)
4851        || (TARGET_POWERPC64 && TARGET_DIRECT_MOVE))"
4853   if (FLOAT128_IEEE_P (<MODE>mode))
4854     {
4855       rtx dest = operands[0];
4856       rtx src = operands[1];
4857       rtx tmp = gen_reg_rtx (DImode);
4858       rtx dest_di = gen_lowpart (DImode, dest);
4860       emit_insn (gen_signbit2_dm (<MODE>mode, tmp, src));
4861       emit_insn (gen_lshrdi3 (dest_di, tmp, GEN_INT (63)));
4862       DONE;
4863     }
4864   operands[2] = gen_reg_rtx (DFmode);
4865   operands[3] = gen_reg_rtx (DImode);
4866   if (TARGET_POWERPC64)
4867     {
4868       operands[4] = gen_reg_rtx (DImode);
4869       operands[5] = gen_rtx_LSHIFTRT (DImode, operands[3], GEN_INT (63));
4870       operands[6] = gen_rtx_SUBREG (SImode, operands[4],
4871                                     WORDS_BIG_ENDIAN ? 4 : 0);
4872     }
4873   else
4874     {
4875       operands[4] = gen_reg_rtx (SImode);
4876       operands[5] = gen_rtx_SUBREG (SImode, operands[3],
4877                                     WORDS_BIG_ENDIAN ? 0 : 4);
4878       operands[6] = gen_rtx_LSHIFTRT (SImode, operands[4], GEN_INT (31));
4879     }
4882 ;; Optimize IEEE 128-bit signbit on 64-bit systems with direct move to avoid
4883 ;; multiple direct moves.  If we used a SUBREG:DI of the Floa128 type, the
4884 ;; register allocator would typically move the entire _Float128 item to GPRs (2
4885 ;; instructions on ISA 3.0, 3-4 instructions on ISA 2.07).
4887 ;; After register allocation, if the _Float128 had originally been in GPRs, the
4888 ;; split allows the post reload phases to eliminate the move, and do the shift
4889 ;; directly with the register that contains the signbit.
4890 (define_insn_and_split "@signbit<mode>2_dm"
4891   [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
4892         (unspec:DI [(match_operand:SIGNBIT 1 "gpc_reg_operand" "wa,r")]
4893                    UNSPEC_SIGNBIT))]
4894   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
4895   "@
4896    mfvsrd %0,%x1
4897    #"
4898   "&& reload_completed && int_reg_operand (operands[1], <MODE>mode)"
4899   [(set (match_dup 0)
4900         (match_dup 2))]
4902   operands[2] = gen_highpart (DImode, operands[1]);
4904  [(set_attr "type" "mftgpr,*")])
4906 ;; Optimize IEEE 128-bit signbit on to avoid loading the value into a vector
4907 ;; register and then doing a direct move if the value comes from memory.  On
4908 ;; little endian, we have to load the 2nd double-word to get the sign bit.
4909 (define_insn_and_split "*signbit<mode>2_dm_mem"
4910   [(set (match_operand:DI 0 "gpc_reg_operand" "=b")
4911         (unspec:DI [(match_operand:SIGNBIT 1 "memory_operand" "m")]
4912                    UNSPEC_SIGNBIT))]
4913   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
4914   "#"
4915   "&& 1"
4916   [(set (match_dup 0)
4917         (match_dup 2))]
4919   rtx dest = operands[0];
4920   rtx src = operands[1];
4921   rtx addr = XEXP (src, 0);
4923   if (WORDS_BIG_ENDIAN)
4924     operands[2] = adjust_address (src, DImode, 0);
4926   else if (REG_P (addr) || SUBREG_P (addr))
4927     operands[2] = adjust_address (src, DImode, 8);
4929   else if (GET_CODE (addr) == PLUS && REG_P (XEXP (addr, 0))
4930            && CONST_INT_P (XEXP (addr, 1)) && mem_operand_gpr (src, DImode))
4931     operands[2] = adjust_address (src, DImode, 8);
4933   else
4934     {
4935       rtx tmp = can_create_pseudo_p () ? gen_reg_rtx (DImode) : dest;
4936       emit_insn (gen_rtx_SET (tmp, addr));
4937       operands[2] = change_address (src, DImode,
4938                                     gen_rtx_PLUS (DImode, tmp, GEN_INT (8)));
4939     }
4942 (define_expand "copysign<mode>3"
4943   [(set (match_dup 3)
4944         (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))
4945    (set (match_dup 4)
4946         (neg:SFDF (abs:SFDF (match_dup 1))))
4947    (set (match_operand:SFDF 0 "gpc_reg_operand")
4948         (if_then_else:SFDF (ge (match_operand:SFDF 2 "gpc_reg_operand")
4949                                (match_dup 5))
4950                          (match_dup 3)
4951                          (match_dup 4)))]
4952   "TARGET_HARD_FLOAT
4953    && ((TARGET_PPC_GFXOPT
4954         && !HONOR_NANS (<MODE>mode)
4955         && !HONOR_SIGNED_ZEROS (<MODE>mode))
4956        || TARGET_CMPB
4957        || VECTOR_UNIT_VSX_P (<MODE>mode))"
4959   if (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode))
4960     {
4961       emit_insn (gen_copysign<mode>3_fcpsgn (operands[0], operands[1],
4962                                              operands[2]));
4963       DONE;
4964     }
4966    operands[3] = gen_reg_rtx (<MODE>mode);
4967    operands[4] = gen_reg_rtx (<MODE>mode);
4968    operands[5] = CONST0_RTX (<MODE>mode);
4969   })
4971 ;; Use an unspec rather providing an if-then-else in RTL, to prevent the
4972 ;; compiler from optimizing -0.0
4973 (define_insn "copysign<mode>3_fcpsgn"
4974   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4975         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")
4976                       (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")]
4977                      UNSPEC_COPYSIGN))]
4978   "TARGET_HARD_FLOAT && (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode))"
4979   "@
4980    fcpsgn %0,%2,%1
4981    xscpsgndp %x0,%x2,%x1"
4982   [(set_attr "type" "fpsimple")])
4984 ;; For MIN, MAX, and conditional move, we use DEFINE_EXPAND's that involve a
4985 ;; fsel instruction and some auxiliary computations.  Then we just have a
4986 ;; single DEFINE_INSN for fsel and the define_splits to make them if made by
4987 ;; combine.
4988 ;; For MIN, MAX on non-VSX machines, and conditional move all of the time, we
4989 ;; use DEFINE_EXPAND's that involve a fsel instruction and some auxiliary
4990 ;; computations.  Then we just have a single DEFINE_INSN for fsel and the
4991 ;; define_splits to make them if made by combine.  On VSX machines we have the
4992 ;; min/max instructions.
4994 ;; On VSX, we only check for TARGET_VSX instead of checking for a vsx/p8 vector
4995 ;; to allow either DF/SF to use only traditional registers.
4997 (define_expand "s<minmax><mode>3"
4998   [(set (match_operand:SFDF 0 "gpc_reg_operand")
4999         (fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
5000                         (match_operand:SFDF 2 "gpc_reg_operand")))]
5001   "TARGET_MINMAX"
5003   rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]);
5004   DONE;
5007 (define_insn "*s<minmax><mode>3_vsx"
5008   [(set (match_operand:SFDF 0 "vsx_register_operand" "=<Fv>")
5009         (fp_minmax:SFDF (match_operand:SFDF 1 "vsx_register_operand" "<Fv>")
5010                         (match_operand:SFDF 2 "vsx_register_operand" "<Fv>")))]
5011   "TARGET_VSX && TARGET_HARD_FLOAT"
5013   return (TARGET_P9_MINMAX
5014           ? "xs<minmax>cdp %x0,%x1,%x2"
5015           : "xs<minmax>dp %x0,%x1,%x2");
5017   [(set_attr "type" "fp")])
5019 ;; The conditional move instructions allow us to perform max and min operations
5020 ;; even when we don't have the appropriate max/min instruction using the FSEL
5021 ;; instruction.
5023 (define_insn_and_split "*s<minmax><mode>3_fpr"
5024   [(set (match_operand:SFDF 0 "gpc_reg_operand")
5025         (fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
5026                         (match_operand:SFDF 2 "gpc_reg_operand")))]
5027   "!TARGET_VSX && TARGET_MINMAX"
5028   "#"
5029   "&& 1"
5030   [(const_int 0)]
5032   rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]);
5033   DONE;
5036 (define_expand "mov<mode>cc"
5037    [(set (match_operand:GPR 0 "gpc_reg_operand")
5038          (if_then_else:GPR (match_operand 1 "comparison_operator")
5039                            (match_operand:GPR 2 "gpc_reg_operand")
5040                            (match_operand:GPR 3 "gpc_reg_operand")))]
5041   "TARGET_ISEL"
5043   if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
5044     DONE;
5045   else
5046     FAIL;
5049 ;; We use the BASE_REGS for the isel input operands because, if rA is
5050 ;; 0, the value of 0 is placed in rD upon truth.  Similarly for rB
5051 ;; because we may switch the operands and rB may end up being rA.
5053 ;; We need 2 patterns: an unsigned and a signed pattern.  We could
5054 ;; leave out the mode in operand 4 and use one pattern, but reload can
5055 ;; change the mode underneath our feet and then gets confused trying
5056 ;; to reload the value.
5057 (define_mode_iterator CCEITHER [CC CCUNS])
5058 (define_mode_attr un [(CC "") (CCUNS "un")])
5059 (define_insn "isel_<un>signed_<GPR:mode>"
5060   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
5061         (if_then_else:GPR
5062          (match_operator 1 "scc_comparison_operator"
5063                          [(match_operand:CCEITHER 4 "cc_reg_operand" "y,y")
5064                           (const_int 0)])
5065          (match_operand:GPR 2 "reg_or_zero_operand" "O,b")
5066          (match_operand:GPR 3 "gpc_reg_operand" "r,r")))]
5067   "TARGET_ISEL"
5068   "isel %0,%2,%3,%j1"
5069   [(set_attr "type" "isel")])
5071 ;; These patterns can be useful for combine; they let combine know that
5072 ;; isel can handle reversed comparisons so long as the operands are
5073 ;; registers.
5075 (define_insn "*isel_reversed_<un>signed_<GPR:mode>"
5076   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
5077         (if_then_else:GPR
5078          (match_operator 1 "scc_rev_comparison_operator"
5079                          [(match_operand:CCEITHER 4 "cc_reg_operand" "y,y")
5080                           (const_int 0)])
5081          (match_operand:GPR 2 "gpc_reg_operand" "r,r")
5082          (match_operand:GPR 3 "reg_or_zero_operand" "O,b")))]
5083   "TARGET_ISEL"
5085   PUT_CODE (operands[1], reverse_condition (GET_CODE (operands[1])));
5086   return "isel %0,%3,%2,%j1";
5088   [(set_attr "type" "isel")])
5090 ;; Floating point conditional move
5091 (define_expand "mov<mode>cc"
5092    [(set (match_operand:SFDF 0 "gpc_reg_operand")
5093          (if_then_else:SFDF (match_operand 1 "comparison_operator")
5094                             (match_operand:SFDF 2 "gpc_reg_operand")
5095                             (match_operand:SFDF 3 "gpc_reg_operand")))]
5096   "TARGET_HARD_FLOAT && TARGET_PPC_GFXOPT"
5098   if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
5099     DONE;
5100   else
5101     FAIL;
5104 (define_insn "*fsel<SFDF:mode><SFDF2:mode>4"
5105   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=&<SFDF:rreg2>")
5106         (if_then_else:SFDF
5107          (ge (match_operand:SFDF2 1 "gpc_reg_operand" "<SFDF2:rreg2>")
5108              (match_operand:SFDF2 4 "zero_fp_constant" "F"))
5109          (match_operand:SFDF 2 "gpc_reg_operand" "<SFDF:rreg2>")
5110          (match_operand:SFDF 3 "gpc_reg_operand" "<SFDF:rreg2>")))]
5111   "TARGET_HARD_FLOAT && TARGET_PPC_GFXOPT"
5112   "fsel %0,%1,%2,%3"
5113   [(set_attr "type" "fp")])
5115 (define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_p9"
5116   [(set (match_operand:SFDF 0 "vsx_register_operand" "=&<SFDF:Fv>,<SFDF:Fv>")
5117         (if_then_else:SFDF
5118          (match_operator:CCFP 1 "fpmask_comparison_operator"
5119                 [(match_operand:SFDF2 2 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")
5120                  (match_operand:SFDF2 3 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")])
5121          (match_operand:SFDF 4 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")
5122          (match_operand:SFDF 5 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")))
5123    (clobber (match_scratch:V2DI 6 "=0,&wa"))]
5124   "TARGET_P9_MINMAX"
5125   "#"
5126   ""
5127   [(set (match_dup 6)
5128         (if_then_else:V2DI (match_dup 1)
5129                            (match_dup 7)
5130                            (match_dup 8)))
5131    (set (match_dup 0)
5132         (if_then_else:SFDF (ne (match_dup 6)
5133                                (match_dup 8))
5134                            (match_dup 4)
5135                            (match_dup 5)))]
5137   if (GET_CODE (operands[6]) == SCRATCH)
5138     operands[6] = gen_reg_rtx (V2DImode);
5140   operands[7] = CONSTM1_RTX (V2DImode);
5141   operands[8] = CONST0_RTX (V2DImode);
5143  [(set_attr "length" "8")
5144   (set_attr "type" "vecperm")])
5146 ;; Handle inverting the fpmask comparisons.
5147 (define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_invert_p9"
5148   [(set (match_operand:SFDF 0 "vsx_register_operand" "=&<SFDF:Fv>,<SFDF:Fv>")
5149         (if_then_else:SFDF
5150          (match_operator:CCFP 1 "invert_fpmask_comparison_operator"
5151                 [(match_operand:SFDF2 2 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")
5152                  (match_operand:SFDF2 3 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")])
5153          (match_operand:SFDF 4 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")
5154          (match_operand:SFDF 5 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")))
5155    (clobber (match_scratch:V2DI 6 "=0,&wa"))]
5156   "TARGET_P9_MINMAX"
5157   "#"
5158   "&& 1"
5159   [(set (match_dup 6)
5160         (if_then_else:V2DI (match_dup 9)
5161                            (match_dup 7)
5162                            (match_dup 8)))
5163    (set (match_dup 0)
5164         (if_then_else:SFDF (ne (match_dup 6)
5165                                (match_dup 8))
5166                            (match_dup 5)
5167                            (match_dup 4)))]
5169   rtx op1 = operands[1];
5170   enum rtx_code cond = reverse_condition_maybe_unordered (GET_CODE (op1));
5172   if (GET_CODE (operands[6]) == SCRATCH)
5173     operands[6] = gen_reg_rtx (V2DImode);
5175   operands[7] = CONSTM1_RTX (V2DImode);
5176   operands[8] = CONST0_RTX (V2DImode);
5178   operands[9] = gen_rtx_fmt_ee (cond, CCFPmode, operands[2], operands[3]);
5180  [(set_attr "length" "8")
5181   (set_attr "type" "vecperm")])
5183 (define_insn "*fpmask<mode>"
5184   [(set (match_operand:V2DI 0 "vsx_register_operand" "=wa")
5185         (if_then_else:V2DI
5186          (match_operator:CCFP 1 "fpmask_comparison_operator"
5187                 [(match_operand:SFDF 2 "vsx_register_operand" "<Fv>")
5188                  (match_operand:SFDF 3 "vsx_register_operand" "<Fv>")])
5189          (match_operand:V2DI 4 "all_ones_constant" "")
5190          (match_operand:V2DI 5 "zero_constant" "")))]
5191   "TARGET_P9_MINMAX"
5192   "xscmp%V1dp %x0,%x2,%x3"
5193   [(set_attr "type" "fpcompare")])
5195 (define_insn "*xxsel<mode>"
5196   [(set (match_operand:SFDF 0 "vsx_register_operand" "=<Fv>")
5197         (if_then_else:SFDF (ne (match_operand:V2DI 1 "vsx_register_operand" "wa")
5198                                (match_operand:V2DI 2 "zero_constant" ""))
5199                            (match_operand:SFDF 3 "vsx_register_operand" "<Fv>")
5200                            (match_operand:SFDF 4 "vsx_register_operand" "<Fv>")))]
5201   "TARGET_P9_MINMAX"
5202   "xxsel %x0,%x4,%x3,%x1"
5203   [(set_attr "type" "vecmove")])
5206 ;; Conversions to and from floating-point.
5208 ; We don't define lfiwax/lfiwzx with the normal definition, because we
5209 ; don't want to support putting SImode in FPR registers.
5210 (define_insn "lfiwax"
5211   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa,wa,v")
5212         (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r,v")]
5213                    UNSPEC_LFIWAX))]
5214   "TARGET_HARD_FLOAT && TARGET_LFIWAX"
5215   "@
5216    lfiwax %0,%y1
5217    lxsiwax %x0,%y1
5218    mtvsrwa %x0,%1
5219    vextsw2d %0,%1"
5220   [(set_attr "type" "fpload,fpload,mffgpr,vecexts")
5221    (set_attr "isa" "*,p8v,p8v,p9v")])
5223 ; This split must be run before register allocation because it allocates the
5224 ; memory slot that is needed to move values to/from the FPR.  We don't allocate
5225 ; it earlier to allow for the combiner to merge insns together where it might
5226 ; not be needed and also in case the insns are deleted as dead code.
5228 (define_insn_and_split "floatsi<mode>2_lfiwax"
5229   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,<Fv>")
5230         (float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r,r")))
5231    (clobber (match_scratch:DI 2 "=d,wa"))]
5232   "TARGET_HARD_FLOAT && TARGET_LFIWAX
5233    && <SI_CONVERT_FP> && can_create_pseudo_p ()"
5234   "#"
5235   ""
5236   [(pc)]
5238   rtx dest = operands[0];
5239   rtx src = operands[1];
5240   rtx tmp;
5242   if (!MEM_P (src) && TARGET_POWERPC64 && TARGET_DIRECT_MOVE)
5243     tmp = convert_to_mode (DImode, src, false);
5244   else
5245     {
5246       tmp = operands[2];
5247       if (GET_CODE (tmp) == SCRATCH)
5248         tmp = gen_reg_rtx (DImode);
5249       if (MEM_P (src))
5250         {
5251           src = rs6000_force_indexed_or_indirect_mem (src);
5252           emit_insn (gen_lfiwax (tmp, src));
5253         }
5254       else
5255         {
5256           rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5257           emit_move_insn (stack, src);
5258           emit_insn (gen_lfiwax (tmp, stack));
5259         }
5260     }
5261   emit_insn (gen_floatdi<mode>2 (dest, tmp));
5262   DONE;
5264   [(set_attr "length" "12")
5265    (set_attr "type" "fpload")])
5267 (define_insn_and_split "floatsi<mode>2_lfiwax_mem"
5268   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,<Fv>")
5269         (float:SFDF
5270          (sign_extend:DI
5271           (match_operand:SI 1 "indexed_or_indirect_operand" "Z,Z"))))
5272    (clobber (match_scratch:DI 2 "=d,wa"))]
5273   "TARGET_HARD_FLOAT && TARGET_LFIWAX && <SI_CONVERT_FP>"
5274   "#"
5275   ""
5276   [(pc)]
5278   operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
5279   if (GET_CODE (operands[2]) == SCRATCH)
5280     operands[2] = gen_reg_rtx (DImode);
5281   if (TARGET_P8_VECTOR)
5282     emit_insn (gen_extendsidi2 (operands[2], operands[1]));
5283   else
5284     emit_insn (gen_lfiwax (operands[2], operands[1]));
5285   emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
5286   DONE;
5288   [(set_attr "length" "8")
5289    (set_attr "type" "fpload")])
5291 (define_insn "lfiwzx"
5292   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa,wa,wa")
5293         (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r,wa")]
5294                    UNSPEC_LFIWZX))]
5295   "TARGET_HARD_FLOAT && TARGET_LFIWZX"
5296   "@
5297    lfiwzx %0,%y1
5298    lxsiwzx %x0,%y1
5299    mtvsrwz %x0,%1
5300    xxextractuw %x0,%x1,4"
5301   [(set_attr "type" "fpload,fpload,mftgpr,vecexts")
5302    (set_attr "isa" "*,p8v,p8v,p9v")])
5304 (define_insn_and_split "floatunssi<mode>2_lfiwzx"
5305   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,<Fv>")
5306         (unsigned_float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r,r")))
5307    (clobber (match_scratch:DI 2 "=d,wa"))]
5308   "TARGET_HARD_FLOAT && TARGET_LFIWZX && <SI_CONVERT_FP>"
5309   "#"
5310   ""
5311   [(pc)]
5313   rtx dest = operands[0];
5314   rtx src = operands[1];
5315   rtx tmp;
5317   if (!MEM_P (src) && TARGET_POWERPC64 && TARGET_DIRECT_MOVE)
5318     tmp = convert_to_mode (DImode, src, true);
5319   else
5320     {
5321       tmp = operands[2];
5322       if (GET_CODE (tmp) == SCRATCH)
5323         tmp = gen_reg_rtx (DImode);
5324       if (MEM_P (src))
5325         {
5326           src = rs6000_force_indexed_or_indirect_mem (src);
5327           emit_insn (gen_lfiwzx (tmp, src));
5328         }
5329       else
5330         {
5331           rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5332           emit_move_insn (stack, src);
5333           emit_insn (gen_lfiwzx (tmp, stack));
5334         }
5335     }
5336   emit_insn (gen_floatdi<mode>2 (dest, tmp));
5337   DONE;
5339   [(set_attr "length" "12")
5340    (set_attr "type" "fpload")])
5342 (define_insn_and_split "floatunssi<mode>2_lfiwzx_mem"
5343   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,<Fv>")
5344         (unsigned_float:SFDF
5345          (zero_extend:DI
5346           (match_operand:SI 1 "indexed_or_indirect_operand" "Z,Z"))))
5347    (clobber (match_scratch:DI 2 "=d,wa"))]
5348   "TARGET_HARD_FLOAT && TARGET_LFIWZX && <SI_CONVERT_FP>"
5349   "#"
5350   ""
5351   [(pc)]
5353   operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
5354   if (GET_CODE (operands[2]) == SCRATCH)
5355     operands[2] = gen_reg_rtx (DImode);
5356   if (TARGET_P8_VECTOR)
5357     emit_insn (gen_zero_extendsidi2 (operands[2], operands[1]));
5358   else
5359     emit_insn (gen_lfiwzx (operands[2], operands[1]));
5360   emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
5361   DONE;
5363   [(set_attr "length" "8")
5364    (set_attr "type" "fpload")])
5366 ; For each of these conversions, there is a define_expand, a define_insn
5367 ; with a '#' template, and a define_split (with C code).  The idea is
5368 ; to allow constant folding with the template of the define_insn,
5369 ; then to have the insns split later (between sched1 and final).
5371 (define_expand "floatsidf2"
5372   [(parallel [(set (match_operand:DF 0 "gpc_reg_operand")
5373                    (float:DF (match_operand:SI 1 "nonimmediate_operand")))
5374               (use (match_dup 2))
5375               (use (match_dup 3))
5376               (clobber (match_dup 4))
5377               (clobber (match_dup 5))
5378               (clobber (match_dup 6))])]
5379   "TARGET_HARD_FLOAT"
5381   if (TARGET_LFIWAX && TARGET_FCFID)
5382     {
5383       emit_insn (gen_floatsidf2_lfiwax (operands[0], operands[1]));
5384       DONE;
5385     }
5386   else if (TARGET_FCFID)
5387     {
5388       rtx dreg = operands[1];
5389       if (!REG_P (dreg))
5390         dreg = force_reg (SImode, dreg);
5391       dreg = convert_to_mode (DImode, dreg, false);
5392       emit_insn (gen_floatdidf2 (operands[0], dreg));
5393       DONE;
5394     }
5396   if (!REG_P (operands[1]))
5397     operands[1] = force_reg (SImode, operands[1]);
5398   operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5399   operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503601774854144\", DFmode));
5400   operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5401   operands[5] = gen_reg_rtx (DFmode);
5402   operands[6] = gen_reg_rtx (SImode);
5405 (define_insn_and_split "*floatsidf2_internal"
5406   [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5407         (float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5408    (use (match_operand:SI 2 "gpc_reg_operand" "r"))
5409    (use (match_operand:DF 3 "gpc_reg_operand" "d"))
5410    (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
5411    (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))
5412    (clobber (match_operand:SI 6 "gpc_reg_operand" "=&r"))]
5413   "!TARGET_FCFID && TARGET_HARD_FLOAT"
5414   "#"
5415   ""
5416   [(pc)]
5418   rtx lowword, highword;
5419   gcc_assert (MEM_P (operands[4]));
5420   highword = adjust_address (operands[4], SImode, 0);
5421   lowword = adjust_address (operands[4], SImode, 4);
5422   if (! WORDS_BIG_ENDIAN)
5423     std::swap (lowword, highword);
5425   emit_insn (gen_xorsi3 (operands[6], operands[1],
5426                          GEN_INT (~ (HOST_WIDE_INT) 0x7fffffff)));
5427   emit_move_insn (lowword, operands[6]);
5428   emit_move_insn (highword, operands[2]);
5429   emit_move_insn (operands[5], operands[4]);
5430   emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5431   DONE;
5433   [(set_attr "length" "24")
5434    (set_attr "type" "fp")])
5436 ;; If we don't have a direct conversion to single precision, don't enable this
5437 ;; conversion for 32-bit without fast math, because we don't have the insn to
5438 ;; generate the fixup swizzle to avoid double rounding problems.
5439 (define_expand "floatunssisf2"
5440   [(set (match_operand:SF 0 "gpc_reg_operand")
5441         (unsigned_float:SF (match_operand:SI 1 "nonimmediate_operand")))]
5442   "TARGET_HARD_FLOAT
5443    && ((TARGET_FCFIDUS && TARGET_LFIWZX)
5444        || (TARGET_FCFID
5445            && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))"
5447   if (TARGET_LFIWZX && TARGET_FCFIDUS)
5448     {
5449       emit_insn (gen_floatunssisf2_lfiwzx (operands[0], operands[1]));
5450       DONE;
5451     }
5452   else
5453     {
5454       rtx dreg = operands[1];
5455       if (!REG_P (dreg))
5456         dreg = force_reg (SImode, dreg);
5457       dreg = convert_to_mode (DImode, dreg, true);
5458       emit_insn (gen_floatdisf2 (operands[0], dreg));
5459       DONE;
5460     }
5463 (define_expand "floatunssidf2"
5464   [(parallel [(set (match_operand:DF 0 "gpc_reg_operand")
5465                    (unsigned_float:DF (match_operand:SI 1 "nonimmediate_operand")))
5466               (use (match_dup 2))
5467               (use (match_dup 3))
5468               (clobber (match_dup 4))
5469               (clobber (match_dup 5))])]
5470   "TARGET_HARD_FLOAT"
5472   if (TARGET_LFIWZX && TARGET_FCFID)
5473     {
5474       emit_insn (gen_floatunssidf2_lfiwzx (operands[0], operands[1]));
5475       DONE;
5476     }
5477   else if (TARGET_FCFID)
5478     {
5479       rtx dreg = operands[1];
5480       if (!REG_P (dreg))
5481         dreg = force_reg (SImode, dreg);
5482       dreg = convert_to_mode (DImode, dreg, true);
5483       emit_insn (gen_floatdidf2 (operands[0], dreg));
5484       DONE;
5485     }
5487   if (!REG_P (operands[1]))
5488     operands[1] = force_reg (SImode, operands[1]);
5489   operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5490   operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503599627370496\", DFmode));
5491   operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5492   operands[5] = gen_reg_rtx (DFmode);
5495 (define_insn_and_split "*floatunssidf2_internal"
5496   [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5497         (unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5498    (use (match_operand:SI 2 "gpc_reg_operand" "r"))
5499    (use (match_operand:DF 3 "gpc_reg_operand" "d"))
5500    (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
5501    (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))]
5502   "!TARGET_FCFIDU && TARGET_HARD_FLOAT
5503    && !(TARGET_FCFID && TARGET_POWERPC64)"
5504   "#"
5505   ""
5506   [(pc)]
5508   rtx lowword, highword;
5509   gcc_assert (MEM_P (operands[4]));
5510   highword = adjust_address (operands[4], SImode, 0);
5511   lowword = adjust_address (operands[4], SImode, 4);
5512   if (! WORDS_BIG_ENDIAN)
5513     std::swap (lowword, highword);
5515   emit_move_insn (lowword, operands[1]);
5516   emit_move_insn (highword, operands[2]);
5517   emit_move_insn (operands[5], operands[4]);
5518   emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5519   DONE;
5521   [(set_attr "length" "20")
5522    (set_attr "type" "fp")])
5524 ;; ISA 3.0 adds instructions lxsi[bh]zx to directly load QImode and HImode to
5525 ;; vector registers.  These insns favor doing the sign/zero extension in
5526 ;; the vector registers, rather then loading up a GPR, doing a sign/zero
5527 ;; extension and then a direct move.
5529 (define_expand "float<QHI:mode><FP_ISA3:mode>2"
5530   [(parallel [(set (match_operand:FP_ISA3 0 "vsx_register_operand")
5531                    (float:FP_ISA3
5532                     (match_operand:QHI 1 "input_operand")))
5533               (clobber (match_scratch:DI 2))
5534               (clobber (match_scratch:DI 3))
5535               (clobber (match_scratch:<QHI:MODE> 4))])]
5536   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5538   if (MEM_P (operands[1]))
5539     operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
5542 (define_insn_and_split "*float<QHI:mode><FP_ISA3:mode>2_internal"
5543   [(set (match_operand:FP_ISA3 0 "vsx_register_operand" "=<Fv>,<Fv>,<Fv>")
5544         (float:FP_ISA3
5545          (match_operand:QHI 1 "reg_or_indexed_operand" "v,r,Z")))
5546    (clobber (match_scratch:DI 2 "=v,wa,v"))
5547    (clobber (match_scratch:DI 3 "=X,r,X"))
5548    (clobber (match_scratch:<QHI:MODE> 4 "=X,X,v"))]
5549   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5550   "#"
5551   "&& reload_completed"
5552   [(const_int 0)]
5554   rtx result = operands[0];
5555   rtx input = operands[1];
5556   rtx di = operands[2];
5558   if (!MEM_P (input))
5559     {
5560       rtx tmp = operands[3];
5561       if (altivec_register_operand (input, <QHI:MODE>mode))
5562         emit_insn (gen_extend<QHI:mode>di2 (di, input));
5563       else if (GET_CODE (tmp) == SCRATCH)
5564         emit_insn (gen_extend<QHI:mode>di2 (di, input));
5565       else
5566         {
5567           emit_insn (gen_extend<QHI:mode>di2 (tmp, input));
5568           emit_move_insn (di, tmp);
5569         }
5570     }
5571   else
5572     {
5573       rtx tmp = operands[4];
5574       emit_move_insn (tmp, input);
5575       emit_insn (gen_extend<QHI:mode>di2 (di, tmp));
5576     }
5578   emit_insn (gen_floatdi<FP_ISA3:mode>2 (result, di));
5579   DONE;
5581   [(set_attr "isa" "p9v,*,p9v")])
5583 (define_expand "floatuns<QHI:mode><FP_ISA3:mode>2"
5584   [(parallel [(set (match_operand:FP_ISA3 0 "vsx_register_operand")
5585                    (unsigned_float:FP_ISA3
5586                     (match_operand:QHI 1 "input_operand")))
5587               (clobber (match_scratch:DI 2))
5588               (clobber (match_scratch:DI 3))])]
5589   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5591   if (MEM_P (operands[1]))
5592     operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
5595 (define_insn_and_split "*floatuns<QHI:mode><FP_ISA3:mode>2_internal"
5596   [(set (match_operand:FP_ISA3 0 "vsx_register_operand" "=<Fv>,<Fv>,<Fv>")
5597         (unsigned_float:FP_ISA3
5598          (match_operand:QHI 1 "reg_or_indexed_operand" "v,r,Z")))
5599    (clobber (match_scratch:DI 2 "=v,wa,wa"))
5600    (clobber (match_scratch:DI 3 "=X,r,X"))]
5601   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5602   "#"
5603   "&& reload_completed"
5604   [(const_int 0)]
5606   rtx result = operands[0];
5607   rtx input = operands[1];
5608   rtx di = operands[2];
5610   if (MEM_P (input) || altivec_register_operand (input, <QHI:MODE>mode))
5611     emit_insn (gen_zero_extend<QHI:mode>di2 (di, input));
5612   else
5613     {
5614       rtx tmp = operands[3];
5615       if (GET_CODE (tmp) == SCRATCH)
5616         emit_insn (gen_extend<QHI:mode>di2 (di, input));
5617       else
5618         {
5619           emit_insn (gen_zero_extend<QHI:mode>di2 (tmp, input));
5620           emit_move_insn (di, tmp);
5621         }
5622     }
5624   emit_insn (gen_floatdi<FP_ISA3:mode>2 (result, di));
5625   DONE;
5627   [(set_attr "isa" "p9v,*,p9v")])
5629 (define_expand "fix_trunc<mode>si2"
5630   [(set (match_operand:SI 0 "gpc_reg_operand")
5631         (fix:SI (match_operand:SFDF 1 "gpc_reg_operand")))]
5632   "TARGET_HARD_FLOAT"
5634   if (!(TARGET_P8_VECTOR && TARGET_DIRECT_MOVE))
5635     {
5636       rtx src = force_reg (<MODE>mode, operands[1]);
5638       if (TARGET_STFIWX)
5639         emit_insn (gen_fix_trunc<mode>si2_stfiwx (operands[0], src));
5640       else
5641         {
5642           rtx tmp = gen_reg_rtx (DImode);
5643           rtx stack = rs6000_allocate_stack_temp (DImode, true, false);
5644           emit_insn (gen_fix_trunc<mode>si2_internal (operands[0], src,
5645                                                       tmp, stack));
5646         }
5647       DONE;
5648     }
5651 ; Like the convert to float patterns, this insn must be split before
5652 ; register allocation so that it can allocate the memory slot if it
5653 ; needed
5654 (define_insn_and_split "fix_trunc<mode>si2_stfiwx"
5655   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5656         (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
5657    (clobber (match_scratch:DI 2 "=d"))]
5658   "TARGET_HARD_FLOAT && TARGET_STFIWX && can_create_pseudo_p ()
5659    && !(TARGET_P8_VECTOR && TARGET_DIRECT_MOVE)"
5660   "#"
5661   ""
5662   [(pc)]
5664   rtx dest = operands[0];
5665   rtx src = operands[1];
5666   rtx tmp = operands[2];
5668   if (GET_CODE (tmp) == SCRATCH)
5669     tmp = gen_reg_rtx (DImode);
5671   emit_insn (gen_fctiwz_<mode> (tmp, src));
5672   if (MEM_P (dest) && (TARGET_MFCRF || MEM_ALIGN (dest) >= 32))
5673     {
5674       dest = rs6000_force_indexed_or_indirect_mem (dest);
5675       emit_insn (gen_stfiwx (dest, tmp));
5676       DONE;
5677     }
5678   else if (TARGET_POWERPC64 && TARGET_DIRECT_MOVE && !MEM_P (dest))
5679     {
5680       dest = gen_lowpart (DImode, dest);
5681       emit_move_insn (dest, tmp);
5682       DONE;
5683     }
5684   else
5685     {
5686       rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5687       emit_insn (gen_stfiwx (stack, tmp));
5688       emit_move_insn (dest, stack);
5689       DONE;
5690     }
5692   [(set_attr "length" "12")
5693    (set_attr "type" "fp")])
5695 (define_insn_and_split "fix_trunc<mode>si2_internal"
5696   [(set (match_operand:SI 0 "gpc_reg_operand" "=r,?r")
5697         (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d,<rreg>")))
5698    (clobber (match_operand:DI 2 "gpc_reg_operand" "=1,d"))
5699    (clobber (match_operand:DI 3 "offsettable_mem_operand" "=o,o"))]
5700   "TARGET_HARD_FLOAT
5701    && !(TARGET_P8_VECTOR && TARGET_DIRECT_MOVE)"
5702   "#"
5703   ""
5704   [(pc)]
5706   rtx lowword;
5707   gcc_assert (MEM_P (operands[3]));
5708   lowword = adjust_address (operands[3], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
5710   emit_insn (gen_fctiwz_<mode> (operands[2], operands[1]));
5711   emit_move_insn (operands[3], operands[2]);
5712   emit_move_insn (operands[0], lowword);
5713   DONE;
5715   [(set_attr "length" "16")
5716    (set_attr "type" "fp")])
5718 (define_expand "fix_trunc<mode>di2"
5719   [(set (match_operand:DI 0 "gpc_reg_operand")
5720         (fix:DI (match_operand:SFDF 1 "gpc_reg_operand")))]
5721   "TARGET_HARD_FLOAT && TARGET_FCFID"
5722   "")
5724 (define_insn "*fix_trunc<mode>di2_fctidz"
5725   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa")
5726         (fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
5727   "TARGET_HARD_FLOAT && TARGET_FCFID"
5728   "@
5729    fctidz %0,%1
5730    xscvdpsxds %x0,%x1"
5731   [(set_attr "type" "fp")])
5733 ;; If we have ISA 3.0, QI/HImode values can go in both VSX registers and GPR
5734 ;; registers.  If we have ISA 2.07, we don't allow QI/HImode values in the
5735 ;; vector registers, so we need to do direct moves to the GPRs, but SImode
5736 ;; values can go in VSX registers.  Keeping the direct move part through
5737 ;; register allocation prevents the register allocator from doing a direct move
5738 ;; of the SImode value to a GPR, and then a store/load.
5739 (define_insn_and_split "fix<uns>_trunc<SFDF:mode><QHI:mode>2"
5740   [(set (match_operand:<QHI:MODE> 0 "gpc_reg_operand" "=d,wa,r")
5741         (any_fix:QHI (match_operand:SFDF 1 "gpc_reg_operand" "d,wa,wa")))
5742    (clobber (match_scratch:SI 2 "=X,X,wa"))]
5743   "TARGET_DIRECT_MOVE"
5744   "@
5745    fctiw<u>z %0,%1
5746    xscvdp<su>xws %x0,%x1
5747    #"
5748   "&& reload_completed && int_reg_operand (operands[0], <QHI:MODE>mode)"
5749   [(set (match_dup 2)
5750         (any_fix:SI (match_dup 1)))
5751    (set (match_dup 3)
5752         (match_dup 2))]
5754   operands[3] = gen_rtx_REG (SImode, REGNO (operands[0]));
5756   [(set_attr "type" "fp")
5757    (set_attr "length" "4,4,8")
5758    (set_attr "isa" "p9v,p9v,*")])
5760 (define_insn "*fix<uns>_trunc<SFDF:mode>si2_p8"
5761   [(set (match_operand:SI 0 "gpc_reg_operand" "=d,wa")
5762         (any_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d,wa")))]
5763   "TARGET_DIRECT_MOVE"
5764   "@
5765    fctiw<u>z %0,%1
5766    xscvdp<su>xws %x0,%x1"
5767   [(set_attr "type" "fp")])
5769 ;; Keep the convert and store together through register allocation to prevent
5770 ;; the register allocator from getting clever and doing a direct move to a GPR
5771 ;; and then store for reg+offset stores.
5772 (define_insn_and_split "*fix<uns>_trunc<SFDF:mode><QHSI:mode>2_mem"
5773   [(set (match_operand:QHSI 0 "memory_operand" "=Z")
5774         (any_fix:QHSI (match_operand:SFDF 1 "gpc_reg_operand" "wa")))
5775    (clobber (match_scratch:SI 2 "=wa"))]
5776     "(<QHSI:MODE>mode == SImode && TARGET_P8_VECTOR) || TARGET_P9_VECTOR"
5777   "#"
5778   "&& reload_completed"
5779   [(set (match_dup 2)
5780         (any_fix:SI (match_dup 1)))
5781    (set (match_dup 0)
5782         (match_dup 3))]
5784   operands[3] = (<QHSI:MODE>mode == SImode
5785                  ? operands[2]
5786                  : gen_rtx_REG (<QHSI:MODE>mode, REGNO (operands[2])));
5789 (define_expand "fixuns_trunc<mode>si2"
5790   [(set (match_operand:SI 0 "gpc_reg_operand")
5791         (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand")))]
5792   "TARGET_HARD_FLOAT && TARGET_FCTIWUZ && TARGET_STFIWX"
5794   if (!TARGET_P8_VECTOR)
5795     {
5796       emit_insn (gen_fixuns_trunc<mode>si2_stfiwx (operands[0], operands[1]));
5797       DONE;
5798     }
5801 (define_insn_and_split "fixuns_trunc<mode>si2_stfiwx"
5802   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5803         (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
5804    (clobber (match_scratch:DI 2 "=d"))]
5805   "TARGET_HARD_FLOAT && TARGET_FCTIWUZ
5806    && TARGET_STFIWX && can_create_pseudo_p ()
5807    && !TARGET_P8_VECTOR"
5808   "#"
5809   ""
5810   [(pc)]
5812   rtx dest = operands[0];
5813   rtx src = operands[1];
5814   rtx tmp = operands[2];
5816   if (GET_CODE (tmp) == SCRATCH)
5817     tmp = gen_reg_rtx (DImode);
5819   emit_insn (gen_fctiwuz_<mode> (tmp, src));
5820   if (MEM_P (dest))
5821     {
5822       dest = rs6000_force_indexed_or_indirect_mem (dest);
5823       emit_insn (gen_stfiwx (dest, tmp));
5824       DONE;
5825     }
5826   else if (TARGET_POWERPC64 && TARGET_DIRECT_MOVE)
5827     {
5828       dest = gen_lowpart (DImode, dest);
5829       emit_move_insn (dest, tmp);
5830       DONE;
5831     }
5832   else
5833     {
5834       rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5835       emit_insn (gen_stfiwx (stack, tmp));
5836       emit_move_insn (dest, stack);
5837       DONE;
5838     }
5840   [(set_attr "length" "12")
5841    (set_attr "type" "fp")])
5843 (define_insn "fixuns_trunc<mode>di2"
5844   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa")
5845         (unsigned_fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
5846   "TARGET_HARD_FLOAT && TARGET_FCTIDUZ"
5847   "@
5848    fctiduz %0,%1
5849    xscvdpuxds %x0,%x1"
5850   [(set_attr "type" "fp")])
5852 (define_insn "rs6000_mtfsb0"
5853   [(unspec_volatile [(match_operand:SI 0 "u5bit_cint_operand" "n")]
5854                     UNSPECV_MTFSB0)]
5855   "TARGET_HARD_FLOAT"
5856   "mtfsb0 %0"
5857   [(set_attr "type" "fp")])
5859 (define_insn "rs6000_mtfsb1"
5860   [(unspec_volatile [(match_operand:SI 0 "u5bit_cint_operand" "n")]
5861                     UNSPECV_MTFSB1)]
5862   "TARGET_HARD_FLOAT"
5863   "mtfsb1 %0"
5864   [(set_attr "type" "fp")])
5866 (define_insn "rs6000_mffscrn"
5867   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
5868         (unspec_volatile:DF [(match_operand:DF 1 "gpc_reg_operand" "d")]
5869                             UNSPECV_MFFSCRN))]
5870    "TARGET_P9_MISC"
5871    "mffscrn %0,%1"
5872   [(set_attr "type" "fp")])
5874 (define_insn "rs6000_mffscdrn"
5875   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
5876    (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFSCDRN))
5877    (use (match_operand:DF 1 "gpc_reg_operand" "d"))]
5878   "TARGET_P9_MISC"
5879   "mffscdrn %0,%1"
5880   [(set_attr "type" "fp")])
5882 (define_expand "rs6000_set_fpscr_rn"
5883  [(match_operand:DI 0 "reg_or_cint_operand")]
5884   "TARGET_HARD_FLOAT"
5886   rtx tmp_df = gen_reg_rtx (DFmode);
5888   /* The floating point rounding control bits are FPSCR[62:63]. Put the
5889      new rounding mode bits from operands[0][62:63] into FPSCR[62:63].  */
5890   if (TARGET_P9_MISC)
5891     {
5892       rtx src_df = force_reg (DImode, operands[0]);
5893       src_df = simplify_gen_subreg (DFmode, src_df, DImode, 0);
5894       emit_insn (gen_rs6000_mffscrn (tmp_df, src_df));
5895       DONE;
5896     }
5898   if (CONST_INT_P (operands[0]))
5899     {
5900       if ((INTVAL (operands[0]) & 0x1) == 0x1)
5901         emit_insn (gen_rs6000_mtfsb1 (GEN_INT (31)));
5902       else
5903         emit_insn (gen_rs6000_mtfsb0 (GEN_INT (31)));
5905       if ((INTVAL (operands[0]) & 0x2) == 0x2)
5906         emit_insn (gen_rs6000_mtfsb1 (GEN_INT (30)));
5907       else
5908         emit_insn (gen_rs6000_mtfsb0 (GEN_INT (30)));
5909     }
5910   else
5911     {
5912       rtx tmp_rn = gen_reg_rtx (DImode);
5913       rtx tmp_di = gen_reg_rtx (DImode);
5915       /* Extract new RN mode from operand.  */
5916       emit_insn (gen_anddi3 (tmp_rn, operands[0], GEN_INT (0x3)));
5918       /* Insert new RN mode into FSCPR.  */
5919       emit_insn (gen_rs6000_mffs (tmp_df));
5920       tmp_di = simplify_gen_subreg (DImode, tmp_df, DFmode, 0);
5921       emit_insn (gen_anddi3 (tmp_di, tmp_di, GEN_INT (-4)));
5922       emit_insn (gen_iordi3 (tmp_di, tmp_di, tmp_rn));
5924       /* Need to write to field k=15.  The fields are [0:15].  Hence with
5925          L=0, W=0, FLM_i must be equal to 8, 16 = i + 8*(1-W).  FLM is an
5926          8-bit field[0:7]. Need to set the bit that corresponds to the
5927          value of i that you want [0:7].  */
5928       tmp_df = simplify_gen_subreg (DFmode, tmp_di, DImode, 0);
5929       emit_insn (gen_rs6000_mtfsf (GEN_INT (0x01), tmp_df));
5930     }
5931   DONE;
5934 (define_expand "rs6000_set_fpscr_drn"
5935   [(match_operand:DI 0  "gpc_reg_operand")]
5936   "TARGET_HARD_FLOAT"
5938   rtx tmp_df = gen_reg_rtx (DFmode);
5940   /* The decimal floating point rounding control bits are FPSCR[29:31]. Put the
5941      new rounding mode bits from operands[0][61:63] into FPSCR[29:31].  */
5942   if (TARGET_P9_MISC)
5943     {
5944       rtx src_df = gen_reg_rtx (DFmode);
5946       emit_insn (gen_ashldi3 (operands[0], operands[0], GEN_INT (32)));
5947       src_df = simplify_gen_subreg (DFmode, operands[0], DImode, 0);
5948       emit_insn (gen_rs6000_mffscdrn (tmp_df, src_df));
5949     }
5950   else
5951     {
5952       rtx tmp_rn = gen_reg_rtx (DImode);
5953       rtx tmp_di = gen_reg_rtx (DImode);
5955       /* Extract new DRN mode from operand.  */
5956       emit_insn (gen_anddi3 (tmp_rn, operands[0], GEN_INT (0x7)));
5957       emit_insn (gen_ashldi3 (tmp_rn, tmp_rn, GEN_INT (32)));
5959       /* Insert new RN mode into FSCPR.  */
5960       emit_insn (gen_rs6000_mffs (tmp_df));
5961       tmp_di = simplify_gen_subreg (DImode, tmp_df, DFmode, 0);
5962       emit_insn (gen_anddi3 (tmp_di, tmp_di, GEN_INT (0xFFFFFFF8FFFFFFFF)));
5963       emit_insn (gen_iordi3 (tmp_di, tmp_di, tmp_rn));
5965       /* Need to write to field 7.  The fields are [0:15].  The equation to
5966          select the field is i + 8*(1-W). Hence with L=0 and W=1, need to set
5967          i to 0x1 to get field 7 where i selects the field.  */
5968       tmp_df = simplify_gen_subreg (DFmode, tmp_di, DImode, 0);
5969       emit_insn (gen_rs6000_mtfsf_hi (GEN_INT (0x01), tmp_df));
5970     }
5971   DONE;
5974 ;; Here, we use (set (reg) (unspec:DI [(fix:SI ...)] UNSPEC_FCTIWZ))
5975 ;; rather than (set (subreg:SI (reg)) (fix:SI ...))
5976 ;; because the first makes it clear that operand 0 is not live
5977 ;; before the instruction.
5978 (define_insn "fctiwz_<mode>"
5979   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa")
5980         (unspec:DI [(fix:SI
5981                      (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
5982                    UNSPEC_FCTIWZ))]
5983   "TARGET_HARD_FLOAT"
5984   "@
5985    fctiwz %0,%1
5986    xscvdpsxws %x0,%x1"
5987   [(set_attr "type" "fp")])
5989 (define_insn "fctiwuz_<mode>"
5990   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa")
5991         (unspec:DI [(unsigned_fix:SI
5992                      (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
5993                    UNSPEC_FCTIWUZ))]
5994   "TARGET_HARD_FLOAT && TARGET_FCTIWUZ"
5995   "@
5996    fctiwuz %0,%1
5997    xscvdpuxws %x0,%x1"
5998   [(set_attr "type" "fp")])
6000 ;; Only optimize (float (fix x)) -> frz if we are in fast-math mode, since
6001 ;; since the friz instruction does not truncate the value if the floating
6002 ;; point value is < LONG_MIN or > LONG_MAX.
6003 (define_insn "*friz"
6004   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa")
6005         (float:DF (fix:DI (match_operand:DF 1 "gpc_reg_operand" "d,wa"))))]
6006   "TARGET_HARD_FLOAT && TARGET_FPRND
6007    && flag_unsafe_math_optimizations && !flag_trapping_math && TARGET_FRIZ"
6008   "@
6009    friz %0,%1
6010    xsrdpiz %x0,%x1"
6011   [(set_attr "type" "fp")])
6013 ;; Opitmize converting SF/DFmode to signed SImode and back to SF/DFmode.  This
6014 ;; optimization prevents on ISA 2.06 systems and earlier having to store the
6015 ;; value from the FPR/vector unit to the stack, load the value into a GPR, sign
6016 ;; extend it, store it back on the stack from the GPR, load it back into the
6017 ;; FP/vector unit to do the rounding. If we have direct move (ISA 2.07),
6018 ;; disable using store and load to sign/zero extend the value.
6019 (define_insn_and_split "*round32<mode>2_fprs"
6020   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
6021         (float:SFDF
6022          (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
6023    (clobber (match_scratch:DI 2 "=d"))
6024    (clobber (match_scratch:DI 3 "=d"))]
6025   "TARGET_HARD_FLOAT
6026    && <SI_CONVERT_FP> && TARGET_LFIWAX && TARGET_STFIWX && TARGET_FCFID
6027    && !TARGET_DIRECT_MOVE && can_create_pseudo_p ()"
6028   "#"
6029   ""
6030   [(pc)]
6032   rtx dest = operands[0];
6033   rtx src = operands[1];
6034   rtx tmp1 = operands[2];
6035   rtx tmp2 = operands[3];
6036   rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
6038   if (GET_CODE (tmp1) == SCRATCH)
6039     tmp1 = gen_reg_rtx (DImode);
6040   if (GET_CODE (tmp2) == SCRATCH)
6041     tmp2 = gen_reg_rtx (DImode);
6043   emit_insn (gen_fctiwz_<mode> (tmp1, src));
6044   emit_insn (gen_stfiwx (stack, tmp1));
6045   emit_insn (gen_lfiwax (tmp2, stack));
6046   emit_insn (gen_floatdi<mode>2 (dest, tmp2));
6047   DONE;
6049   [(set_attr "type" "fpload")
6050    (set_attr "length" "16")])
6052 (define_insn_and_split "*roundu32<mode>2_fprs"
6053   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
6054         (unsigned_float:SFDF
6055          (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
6056    (clobber (match_scratch:DI 2 "=d"))
6057    (clobber (match_scratch:DI 3 "=d"))]
6058   "TARGET_HARD_FLOAT
6059    && TARGET_LFIWZX && TARGET_STFIWX && TARGET_FCFIDU && !TARGET_DIRECT_MOVE
6060    && can_create_pseudo_p ()"
6061   "#"
6062   ""
6063   [(pc)]
6065   rtx dest = operands[0];
6066   rtx src = operands[1];
6067   rtx tmp1 = operands[2];
6068   rtx tmp2 = operands[3];
6069   rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
6071   if (GET_CODE (tmp1) == SCRATCH)
6072     tmp1 = gen_reg_rtx (DImode);
6073   if (GET_CODE (tmp2) == SCRATCH)
6074     tmp2 = gen_reg_rtx (DImode);
6076   emit_insn (gen_fctiwuz_<mode> (tmp1, src));
6077   emit_insn (gen_stfiwx (stack, tmp1));
6078   emit_insn (gen_lfiwzx (tmp2, stack));
6079   emit_insn (gen_floatdi<mode>2 (dest, tmp2));
6080   DONE;
6082   [(set_attr "type" "fpload")
6083    (set_attr "length" "16")])
6085 ;; No VSX equivalent to fctid
6086 (define_insn "lrint<mode>di2"
6087   [(set (match_operand:DI 0 "gpc_reg_operand" "=d")
6088         (unspec:DI [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
6089                    UNSPEC_FCTID))]
6090   "TARGET_HARD_FLOAT && TARGET_FPRND"
6091   "fctid %0,%1"
6092   [(set_attr "type" "fp")])
6094 (define_insn "btrunc<mode>2"
6095   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
6096         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
6097                      UNSPEC_FRIZ))]
6098   "TARGET_HARD_FLOAT && TARGET_FPRND"
6099   "@
6100    friz %0,%1
6101    xsrdpiz %x0,%x1"
6102   [(set_attr "type" "fp")])
6104 (define_insn "ceil<mode>2"
6105   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
6106         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
6107                      UNSPEC_FRIP))]
6108   "TARGET_HARD_FLOAT && TARGET_FPRND"
6109   "@
6110    frip %0,%1
6111    xsrdpip %x0,%x1"
6112   [(set_attr "type" "fp")])
6114 (define_insn "floor<mode>2"
6115   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
6116         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
6117                      UNSPEC_FRIM))]
6118   "TARGET_HARD_FLOAT && TARGET_FPRND"
6119   "@
6120    frim %0,%1
6121    xsrdpim %x0,%x1"
6122   [(set_attr "type" "fp")])
6124 ;; No VSX equivalent to frin
6125 (define_insn "round<mode>2"
6126   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<rreg2>")
6127         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
6128                      UNSPEC_FRIN))]
6129   "TARGET_HARD_FLOAT && TARGET_FPRND"
6130   "frin %0,%1"
6131   [(set_attr "type" "fp")])
6133 (define_insn "*xsrdpi<mode>2"
6134   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
6135         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Fv>")]
6136                      UNSPEC_XSRDPI))]
6137   "TARGET_HARD_FLOAT && TARGET_VSX"
6138   "xsrdpi %x0,%x1"
6139   [(set_attr "type" "fp")])
6141 (define_expand "lround<mode>di2"
6142   [(set (match_dup 2)
6143         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand")]
6144                      UNSPEC_XSRDPI))
6145    (set (match_operand:DI 0 "gpc_reg_operand")
6146         (unspec:DI [(match_dup 2)]
6147                    UNSPEC_FCTID))]
6148   "TARGET_HARD_FLOAT && TARGET_VSX && TARGET_FPRND"
6150   operands[2] = gen_reg_rtx (<MODE>mode);
6153 ; An UNSPEC is used so we don't have to support SImode in FP registers.
6154 (define_insn "stfiwx"
6155   [(set (match_operand:SI 0 "memory_operand" "=Z,Z")
6156         (unspec:SI [(match_operand:DI 1 "gpc_reg_operand" "d,wa")]
6157                    UNSPEC_STFIWX))]
6158   "TARGET_PPC_GFXOPT"
6159   "@
6160    stfiwx %1,%y0
6161    stxsiwx %x1,%y0"
6162   [(set_attr "type" "fpstore")
6163    (set_attr "isa" "*,p8v")])
6165 ;; If we don't have a direct conversion to single precision, don't enable this
6166 ;; conversion for 32-bit without fast math, because we don't have the insn to
6167 ;; generate the fixup swizzle to avoid double rounding problems.
6168 (define_expand "floatsisf2"
6169   [(set (match_operand:SF 0 "gpc_reg_operand")
6170         (float:SF (match_operand:SI 1 "nonimmediate_operand")))]
6171   "TARGET_HARD_FLOAT
6172    && ((TARGET_FCFIDS && TARGET_LFIWAX)
6173        || (TARGET_FCFID
6174            && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))"
6176   if (TARGET_FCFIDS && TARGET_LFIWAX)
6177     {
6178       emit_insn (gen_floatsisf2_lfiwax (operands[0], operands[1]));
6179       DONE;
6180     }
6181   else if (TARGET_FCFID && TARGET_LFIWAX)
6182     {
6183       rtx dfreg = gen_reg_rtx (DFmode);
6184       emit_insn (gen_floatsidf2_lfiwax (dfreg, operands[1]));
6185       emit_insn (gen_truncdfsf2 (operands[0], dfreg));
6186       DONE;
6187     }
6188   else
6189     {
6190       rtx dreg = operands[1];
6191       if (!REG_P (dreg))
6192         dreg = force_reg (SImode, dreg);
6193       dreg = convert_to_mode (DImode, dreg, false);
6194       emit_insn (gen_floatdisf2 (operands[0], dreg));
6195       DONE;
6196     }
6199 (define_insn "floatdidf2"
6200   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa")
6201         (float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wa")))]
6202   "TARGET_FCFID && TARGET_HARD_FLOAT"
6203   "@
6204    fcfid %0,%1
6205    xscvsxddp %x0,%x1"
6206   [(set_attr "type" "fp")])
6208 ; Allow the combiner to merge source memory operands to the conversion so that
6209 ; the optimizer/register allocator doesn't try to load the value too early in a
6210 ; GPR and then use store/load to move it to a FPR and suffer from a store-load
6211 ; hit.  We will split after reload to avoid the trip through the GPRs
6213 (define_insn_and_split "*floatdidf2_mem"
6214   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa")
6215         (float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
6216    (clobber (match_scratch:DI 2 "=d,wa"))]
6217   "TARGET_HARD_FLOAT && TARGET_FCFID"
6218   "#"
6219   "&& reload_completed"
6220   [(set (match_dup 2) (match_dup 1))
6221    (set (match_dup 0) (float:DF (match_dup 2)))]
6222   ""
6223   [(set_attr "length" "8")
6224    (set_attr "type" "fpload")])
6226 (define_expand "floatunsdidf2"
6227   [(set (match_operand:DF 0 "gpc_reg_operand")
6228         (unsigned_float:DF
6229          (match_operand:DI 1 "gpc_reg_operand")))]
6230   "TARGET_HARD_FLOAT && TARGET_FCFIDU"
6231   "")
6233 (define_insn "*floatunsdidf2_fcfidu"
6234   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa")
6235         (unsigned_float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wa")))]
6236   "TARGET_HARD_FLOAT && TARGET_FCFIDU"
6237   "@
6238    fcfidu %0,%1
6239    xscvuxddp %x0,%x1"
6240   [(set_attr "type" "fp")])
6242 (define_insn_and_split "*floatunsdidf2_mem"
6243   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa")
6244         (unsigned_float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
6245    (clobber (match_scratch:DI 2 "=d,wa"))]
6246   "TARGET_HARD_FLOAT && (TARGET_FCFIDU || VECTOR_UNIT_VSX_P (DFmode))"
6247   "#"
6248   "&& reload_completed"
6249   [(set (match_dup 2) (match_dup 1))
6250    (set (match_dup 0) (unsigned_float:DF (match_dup 2)))]
6251   ""
6252   [(set_attr "length" "8")
6253    (set_attr "type" "fpload")])
6255 (define_expand "floatdisf2"
6256   [(set (match_operand:SF 0 "gpc_reg_operand")
6257         (float:SF (match_operand:DI 1 "gpc_reg_operand")))]
6258   "TARGET_FCFID && TARGET_HARD_FLOAT
6259    && (TARGET_FCFIDS || TARGET_POWERPC64 || flag_unsafe_math_optimizations)"
6261   if (!TARGET_FCFIDS)
6262     {
6263       rtx val = operands[1];
6264       if (!flag_unsafe_math_optimizations)
6265         {
6266           rtx label = gen_label_rtx ();
6267           val = gen_reg_rtx (DImode);
6268           emit_insn (gen_floatdisf2_internal2 (val, operands[1], label));
6269           emit_label (label);
6270         }
6271       emit_insn (gen_floatdisf2_internal1 (operands[0], val));
6272       DONE;
6273     }
6276 (define_insn "floatdisf2_fcfids"
6277   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wa")
6278         (float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wa")))]
6279   "TARGET_HARD_FLOAT && TARGET_FCFIDS"
6280   "@
6281    fcfids %0,%1
6282    xscvsxdsp %x0,%x1"
6283   [(set_attr "type" "fp")
6284    (set_attr "isa" "*,p8v")])
6286 (define_insn_and_split "*floatdisf2_mem"
6287   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wa,wa")
6288         (float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
6289    (clobber (match_scratch:DI 2 "=d,d,wa"))]
6290   "TARGET_HARD_FLOAT && TARGET_FCFIDS"
6291   "#"
6292   "&& reload_completed"
6293   [(pc)]
6295   emit_move_insn (operands[2], operands[1]);
6296   emit_insn (gen_floatdisf2_fcfids (operands[0], operands[2]));
6297   DONE;
6299   [(set_attr "length" "8")
6300    (set_attr "isa" "*,p8v,p8v")])
6302 ;; This is not IEEE compliant if rounding mode is "round to nearest".
6303 ;; If the DI->DF conversion is inexact, then it's possible to suffer
6304 ;; from double rounding.
6305 ;; Instead of creating a new cpu type for two FP operations, just use fp
6306 (define_insn_and_split "floatdisf2_internal1"
6307   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
6308         (float:SF (match_operand:DI 1 "gpc_reg_operand" "d")))
6309    (clobber (match_scratch:DF 2 "=d"))]
6310   "TARGET_FCFID && TARGET_HARD_FLOAT && !TARGET_FCFIDS"
6311   "#"
6312   "&& reload_completed"
6313   [(set (match_dup 2)
6314         (float:DF (match_dup 1)))
6315    (set (match_dup 0)
6316         (float_truncate:SF (match_dup 2)))]
6317   ""
6318   [(set_attr "length" "8")
6319    (set_attr "type" "fp")])
6321 ;; Twiddles bits to avoid double rounding.
6322 ;; Bits that might be truncated when converting to DFmode are replaced
6323 ;; by a bit that won't be lost at that stage, but is below the SFmode
6324 ;; rounding position.
6325 (define_expand "floatdisf2_internal2"
6326   [(parallel [(set (match_dup 3) (ashiftrt:DI (match_operand:DI 1 "")
6327                                               (const_int 53)))
6328               (clobber (reg:DI CA_REGNO))])
6329    (set (match_operand:DI 0 "") (and:DI (match_dup 1)
6330                                         (const_int 2047)))
6331    (set (match_dup 3) (plus:DI (match_dup 3)
6332                                (const_int 1)))
6333    (set (match_dup 0) (plus:DI (match_dup 0)
6334                                (const_int 2047)))
6335    (set (match_dup 4) (compare:CCUNS (match_dup 3)
6336                                      (const_int 2)))
6337    (set (match_dup 0) (ior:DI (match_dup 0)
6338                               (match_dup 1)))
6339    (set (match_dup 0) (and:DI (match_dup 0)
6340                               (const_int -2048)))
6341    (set (pc) (if_then_else (geu (match_dup 4) (const_int 0))
6342                            (label_ref (match_operand:DI 2 ""))
6343                            (pc)))
6344    (set (match_dup 0) (match_dup 1))]
6345   "TARGET_POWERPC64 && TARGET_HARD_FLOAT && !TARGET_FCFIDS"
6347   operands[3] = gen_reg_rtx (DImode);
6348   operands[4] = gen_reg_rtx (CCUNSmode);
6351 (define_expand "floatunsdisf2"
6352   [(set (match_operand:SF 0 "gpc_reg_operand")
6353         (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand")))]
6354   "TARGET_HARD_FLOAT && TARGET_FCFIDUS"
6355   "")
6357 (define_insn "floatunsdisf2_fcfidus"
6358   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wa")
6359         (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wa")))]
6360   "TARGET_HARD_FLOAT && TARGET_FCFIDUS"
6361   "@
6362    fcfidus %0,%1
6363    xscvuxdsp %x0,%x1"
6364   [(set_attr "type" "fp")
6365    (set_attr "isa" "*,p8v")])
6367 (define_insn_and_split "*floatunsdisf2_mem"
6368   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wa,wa")
6369         (unsigned_float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
6370    (clobber (match_scratch:DI 2 "=d,d,wa"))]
6371   "TARGET_HARD_FLOAT && TARGET_FCFIDUS"
6372   "#"
6373   "&& reload_completed"
6374   [(pc)]
6376   emit_move_insn (operands[2], operands[1]);
6377   emit_insn (gen_floatunsdisf2_fcfidus (operands[0], operands[2]));
6378   DONE;
6380   [(set_attr "type" "fpload")
6381    (set_attr "length" "8")
6382    (set_attr "isa" "*,p8v,p8v")])
6384 ;; Define the TImode operations that can be done in a small number
6385 ;; of instructions.  The & constraints are to prevent the register
6386 ;; allocator from allocating registers that overlap with the inputs
6387 ;; (for example, having an input in 7,8 and an output in 6,7).  We
6388 ;; also allow for the output being the same as one of the inputs.
6390 (define_expand "addti3"
6391   [(set (match_operand:TI 0 "gpc_reg_operand")
6392         (plus:TI (match_operand:TI 1 "gpc_reg_operand")
6393                  (match_operand:TI 2 "reg_or_short_operand")))]
6394   "TARGET_64BIT"
6396   rtx lo0 = gen_lowpart (DImode, operands[0]);
6397   rtx lo1 = gen_lowpart (DImode, operands[1]);
6398   rtx lo2 = gen_lowpart (DImode, operands[2]);
6399   rtx hi0 = gen_highpart (DImode, operands[0]);
6400   rtx hi1 = gen_highpart (DImode, operands[1]);
6401   rtx hi2 = gen_highpart_mode (DImode, TImode, operands[2]);
6403   if (!reg_or_short_operand (lo2, DImode))
6404     lo2 = force_reg (DImode, lo2);
6405   if (!adde_operand (hi2, DImode))
6406     hi2 = force_reg (DImode, hi2);
6408   emit_insn (gen_adddi3_carry (lo0, lo1, lo2));
6409   emit_insn (gen_adddi3_carry_in (hi0, hi1, hi2));
6410   DONE;
6413 (define_expand "subti3"
6414   [(set (match_operand:TI 0 "gpc_reg_operand")
6415         (minus:TI (match_operand:TI 1 "reg_or_short_operand")
6416                   (match_operand:TI 2 "gpc_reg_operand")))]
6417   "TARGET_64BIT"
6419   rtx lo0 = gen_lowpart (DImode, operands[0]);
6420   rtx lo1 = gen_lowpart (DImode, operands[1]);
6421   rtx lo2 = gen_lowpart (DImode, operands[2]);
6422   rtx hi0 = gen_highpart (DImode, operands[0]);
6423   rtx hi1 = gen_highpart_mode (DImode, TImode, operands[1]);
6424   rtx hi2 = gen_highpart (DImode, operands[2]);
6426   if (!reg_or_short_operand (lo1, DImode))
6427     lo1 = force_reg (DImode, lo1);
6428   if (!adde_operand (hi1, DImode))
6429     hi1 = force_reg (DImode, hi1);
6431   emit_insn (gen_subfdi3_carry (lo0, lo2, lo1));
6432   emit_insn (gen_subfdi3_carry_in (hi0, hi2, hi1));
6433   DONE;
6436 ;; 128-bit logical operations expanders
6438 (define_expand "and<mode>3"
6439   [(set (match_operand:BOOL_128 0 "vlogical_operand")
6440         (and:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")
6441                       (match_operand:BOOL_128 2 "vlogical_operand")))]
6442   ""
6443   "")
6445 (define_expand "ior<mode>3"
6446   [(set (match_operand:BOOL_128 0 "vlogical_operand")
6447         (ior:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")
6448                       (match_operand:BOOL_128 2 "vlogical_operand")))]
6449   ""
6450   "")
6452 (define_expand "xor<mode>3"
6453   [(set (match_operand:BOOL_128 0 "vlogical_operand")
6454         (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")
6455                       (match_operand:BOOL_128 2 "vlogical_operand")))]
6456   ""
6457   "")
6459 (define_expand "one_cmpl<mode>2"
6460   [(set (match_operand:BOOL_128 0 "vlogical_operand")
6461         (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")))]
6462   ""
6463   "")
6465 (define_expand "nor<mode>3"
6466   [(set (match_operand:BOOL_128 0 "vlogical_operand")
6467         (and:BOOL_128
6468          (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand"))
6469          (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))))]
6470   ""
6471   "")
6473 (define_expand "andc<mode>3"
6474   [(set (match_operand:BOOL_128 0 "vlogical_operand")
6475         (and:BOOL_128
6476          (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))
6477          (match_operand:BOOL_128 1 "vlogical_operand")))]
6478   ""
6479   "")
6481 ;; Power8 vector logical instructions.
6482 (define_expand "eqv<mode>3"
6483   [(set (match_operand:BOOL_128 0 "vlogical_operand")
6484         (not:BOOL_128
6485          (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")
6486                        (match_operand:BOOL_128 2 "vlogical_operand"))))]
6487   "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6488   "")
6490 ;; Rewrite nand into canonical form
6491 (define_expand "nand<mode>3"
6492   [(set (match_operand:BOOL_128 0 "vlogical_operand")
6493         (ior:BOOL_128
6494          (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand"))
6495          (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))))]
6496   "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6497   "")
6499 ;; The canonical form is to have the negated element first, so we need to
6500 ;; reverse arguments.
6501 (define_expand "orc<mode>3"
6502   [(set (match_operand:BOOL_128 0 "vlogical_operand")
6503         (ior:BOOL_128
6504          (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))
6505          (match_operand:BOOL_128 1 "vlogical_operand")))]
6506   "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6507   "")
6509 ;; 128-bit logical operations insns and split operations
6510 (define_insn_and_split "*and<mode>3_internal"
6511   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6512         (and:BOOL_128
6513          (match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
6514          (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")))]
6515   ""
6517   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6518     return "xxland %x0,%x1,%x2";
6520   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6521     return "vand %0,%1,%2";
6523   return "#";
6525   "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6526   [(const_int 0)]
6528   rs6000_split_logical (operands, AND, false, false, false);
6529   DONE;
6531   [(set (attr "type")
6532       (if_then_else
6533         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6534         (const_string "veclogical")
6535         (const_string "integer")))
6536    (set (attr "length")
6537       (if_then_else
6538         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6539         (const_string "4")
6540         (if_then_else
6541          (match_test "TARGET_POWERPC64")
6542          (const_string "8")
6543          (const_string "16"))))])
6545 ;; 128-bit IOR/XOR
6546 (define_insn_and_split "*bool<mode>3_internal"
6547   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6548         (match_operator:BOOL_128 3 "boolean_or_operator"
6549          [(match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
6550           (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")]))]
6551   ""
6553   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6554     return "xxl%q3 %x0,%x1,%x2";
6556   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6557     return "v%q3 %0,%1,%2";
6559   return "#";
6561   "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6562   [(const_int 0)]
6564   rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, false);
6565   DONE;
6567   [(set (attr "type")
6568       (if_then_else
6569         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6570         (const_string "veclogical")
6571         (const_string "integer")))
6572    (set (attr "length")
6573       (if_then_else
6574         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6575         (const_string "4")
6576         (if_then_else
6577          (match_test "TARGET_POWERPC64")
6578          (const_string "8")
6579          (const_string "16"))))])
6581 ;; 128-bit ANDC/ORC
6582 (define_insn_and_split "*boolc<mode>3_internal1"
6583   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6584         (match_operator:BOOL_128 3 "boolean_operator"
6585          [(not:BOOL_128
6586            (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))
6587           (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")]))]
6588   "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
6590   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6591     return "xxl%q3 %x0,%x1,%x2";
6593   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6594     return "v%q3 %0,%1,%2";
6596   return "#";
6598   "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
6599    && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6600   [(const_int 0)]
6602   rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
6603   DONE;
6605   [(set (attr "type")
6606       (if_then_else
6607         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6608         (const_string "veclogical")
6609         (const_string "integer")))
6610    (set (attr "length")
6611       (if_then_else
6612         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6613         (const_string "4")
6614         (if_then_else
6615          (match_test "TARGET_POWERPC64")
6616          (const_string "8")
6617          (const_string "16"))))])
6619 (define_insn_and_split "*boolc<mode>3_internal2"
6620   [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6621         (match_operator:TI2 3 "boolean_operator"
6622          [(not:TI2
6623            (match_operand:TI2 2 "int_reg_operand" "r,0,r"))
6624           (match_operand:TI2 1 "int_reg_operand" "r,r,0")]))]
6625   "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6626   "#"
6627   "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6628   [(const_int 0)]
6630   rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
6631   DONE;
6633   [(set_attr "type" "integer")
6634    (set (attr "length")
6635         (if_then_else
6636          (match_test "TARGET_POWERPC64")
6637          (const_string "8")
6638          (const_string "16")))])
6640 ;; 128-bit NAND/NOR
6641 (define_insn_and_split "*boolcc<mode>3_internal1"
6642   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6643         (match_operator:BOOL_128 3 "boolean_operator"
6644          [(not:BOOL_128
6645            (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>"))
6646           (not:BOOL_128
6647            (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))]))]
6648   "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
6650   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6651     return "xxl%q3 %x0,%x1,%x2";
6653   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6654     return "v%q3 %0,%1,%2";
6656   return "#";
6658   "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
6659    && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6660   [(const_int 0)]
6662   rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
6663   DONE;
6665   [(set (attr "type")
6666       (if_then_else
6667         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6668         (const_string "veclogical")
6669         (const_string "integer")))
6670    (set (attr "length")
6671       (if_then_else
6672         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6673         (const_string "4")
6674         (if_then_else
6675          (match_test "TARGET_POWERPC64")
6676          (const_string "8")
6677          (const_string "16"))))])
6679 (define_insn_and_split "*boolcc<mode>3_internal2"
6680   [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6681         (match_operator:TI2 3 "boolean_operator"
6682          [(not:TI2
6683            (match_operand:TI2 1 "int_reg_operand" "r,0,r"))
6684           (not:TI2
6685            (match_operand:TI2 2 "int_reg_operand" "r,r,0"))]))]
6686   "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6687   "#"
6688   "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6689   [(const_int 0)]
6691   rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
6692   DONE;
6694   [(set_attr "type" "integer")
6695    (set (attr "length")
6696         (if_then_else
6697          (match_test "TARGET_POWERPC64")
6698          (const_string "8")
6699          (const_string "16")))])
6702 ;; 128-bit EQV
6703 (define_insn_and_split "*eqv<mode>3_internal1"
6704   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6705         (not:BOOL_128
6706          (xor:BOOL_128
6707           (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")
6708           (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))))]
6709   "TARGET_P8_VECTOR"
6711   if (vsx_register_operand (operands[0], <MODE>mode))
6712     return "xxleqv %x0,%x1,%x2";
6714   return "#";
6716   "TARGET_P8_VECTOR && reload_completed
6717    && int_reg_operand (operands[0], <MODE>mode)"
6718   [(const_int 0)]
6720   rs6000_split_logical (operands, XOR, true, false, false);
6721   DONE;
6723   [(set (attr "type")
6724       (if_then_else
6725         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6726         (const_string "veclogical")
6727         (const_string "integer")))
6728    (set (attr "length")
6729       (if_then_else
6730         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6731         (const_string "4")
6732         (if_then_else
6733          (match_test "TARGET_POWERPC64")
6734          (const_string "8")
6735          (const_string "16"))))])
6737 (define_insn_and_split "*eqv<mode>3_internal2"
6738   [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6739         (not:TI2
6740          (xor:TI2
6741           (match_operand:TI2 1 "int_reg_operand" "r,0,r")
6742           (match_operand:TI2 2 "int_reg_operand" "r,r,0"))))]
6743   "!TARGET_P8_VECTOR"
6744   "#"
6745   "reload_completed && !TARGET_P8_VECTOR"
6746   [(const_int 0)]
6748   rs6000_split_logical (operands, XOR, true, false, false);
6749   DONE;
6751   [(set_attr "type" "integer")
6752    (set (attr "length")
6753         (if_then_else
6754          (match_test "TARGET_POWERPC64")
6755          (const_string "8")
6756          (const_string "16")))])
6758 ;; 128-bit one's complement
6759 (define_insn_and_split "*one_cmpl<mode>3_internal"
6760   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6761         (not:BOOL_128
6762           (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_UNARY>")))]
6763   ""
6765   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6766     return "xxlnor %x0,%x1,%x1";
6768   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6769     return "vnor %0,%1,%1";
6771   return "#";
6773   "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6774   [(const_int 0)]
6776   rs6000_split_logical (operands, NOT, false, false, false);
6777   DONE;
6779   [(set (attr "type")
6780       (if_then_else
6781         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6782         (const_string "veclogical")
6783         (const_string "integer")))
6784    (set (attr "length")
6785       (if_then_else
6786         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6787         (const_string "4")
6788         (if_then_else
6789          (match_test "TARGET_POWERPC64")
6790          (const_string "8")
6791          (const_string "16"))))])
6794 ;; Now define ways of moving data around.
6796 ;; Set up a register with a value from the GOT table
6798 (define_expand "movsi_got"
6799   [(set (match_operand:SI 0 "gpc_reg_operand")
6800         (unspec:SI [(match_operand:SI 1 "got_operand")
6801                     (match_dup 2)] UNSPEC_MOVSI_GOT))]
6802   "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
6804   if (GET_CODE (operands[1]) == CONST)
6805     {
6806       rtx offset = const0_rtx;
6807       HOST_WIDE_INT value;
6809       operands[1] = eliminate_constant_term (XEXP (operands[1], 0), &offset);
6810       value = INTVAL (offset);
6811       if (value != 0)
6812         {
6813           rtx tmp = (!can_create_pseudo_p ()
6814                      ? operands[0]
6815                      : gen_reg_rtx (Pmode));
6816           emit_insn (gen_movsi_got (tmp, operands[1]));
6817           emit_insn (gen_addsi3 (operands[0], tmp, offset));
6818           DONE;
6819         }
6820     }
6822   operands[2] = rs6000_got_register (operands[1]);
6825 (define_insn "*movsi_got_internal"
6826   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6827         (unspec:SI [(match_operand:SI 1 "got_no_const_operand" "")
6828                     (match_operand:SI 2 "gpc_reg_operand" "b")]
6829                    UNSPEC_MOVSI_GOT))]
6830   "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
6831   "lwz %0,%a1@got(%2)"
6832   [(set_attr "type" "load")])
6834 ;; Used by sched, shorten_branches and final when the GOT pseudo reg
6835 ;; didn't get allocated to a hard register.
6836 (define_split
6837   [(set (match_operand:SI 0 "gpc_reg_operand")
6838         (unspec:SI [(match_operand:SI 1 "got_no_const_operand")
6839                     (match_operand:SI 2 "memory_operand")]
6840                    UNSPEC_MOVSI_GOT))]
6841   "DEFAULT_ABI == ABI_V4
6842     && flag_pic == 1
6843     && reload_completed"
6844   [(set (match_dup 0) (match_dup 2))
6845    (set (match_dup 0) (unspec:SI [(match_dup 1)(match_dup 0)]
6846                                  UNSPEC_MOVSI_GOT))]
6847   "")
6849 ;; For SI, we special-case integers that can't be loaded in one insn.  We
6850 ;; do the load 16-bits at a time.  We could do this by loading from memory,
6851 ;; and this is even supposed to be faster, but it is simpler not to get
6852 ;; integers in the TOC.
6853 (define_insn "movsi_low"
6854   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6855         (mem:SI (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
6856                            (match_operand 2 "" ""))))]
6857   "TARGET_MACHO && ! TARGET_64BIT"
6858   "lwz %0,lo16(%2)(%1)"
6859   [(set_attr "type" "load")])
6861 ;;              MR           LA           LWZ          LFIWZX       LXSIWZX
6862 ;;              STW          STFIWX       STXSIWX      LI           LIS
6863 ;;              #            XXLOR        XXSPLTIB 0   XXSPLTIB -1  VSPLTISW
6864 ;;              XXLXOR 0     XXLORC -1    P9 const     MTVSRWZ      MFVSRWZ
6865 ;;              MF%1         MT%0         NOP
6866 (define_insn "*movsi_internal1"
6867   [(set (match_operand:SI 0 "nonimmediate_operand"
6868                 "=r,         r,           r,           d,           v,
6869                  m,          Z,           Z,           r,           r,
6870                  r,          wa,          wa,          wa,          v,
6871                  wa,         v,           v,           wa,          r,
6872                  r,          *h,          *h")
6873         (match_operand:SI 1 "input_operand"
6874                 "r,          U,           m,           Z,           Z,
6875                  r,          d,           v,           I,           L,
6876                  n,          wa,          O,           wM,          wB,
6877                  O,          wM,          wS,          r,           wa,
6878                  *h,         r,           0"))]
6879   "gpc_reg_operand (operands[0], SImode)
6880    || gpc_reg_operand (operands[1], SImode)"
6881   "@
6882    mr %0,%1
6883    la %0,%a1
6884    lwz%U1%X1 %0,%1
6885    lfiwzx %0,%y1
6886    lxsiwzx %x0,%y1
6887    stw%U0%X0 %1,%0
6888    stfiwx %1,%y0
6889    stxsiwx %x1,%y0
6890    li %0,%1
6891    lis %0,%v1
6892    #
6893    xxlor %x0,%x1,%x1
6894    xxspltib %x0,0
6895    xxspltib %x0,255
6896    vspltisw %0,%1
6897    xxlxor %x0,%x0,%x0
6898    xxlorc %x0,%x0,%x0
6899    #
6900    mtvsrwz %x0,%1
6901    mfvsrwz %0,%x1
6902    mf%1 %0
6903    mt%0 %1
6904    nop"
6905   [(set_attr "type"
6906                 "*,          *,           load,        fpload,      fpload,
6907                  store,      fpstore,     fpstore,     *,           *,
6908                  *,          veclogical,  vecsimple,   vecsimple,   vecsimple,
6909                  veclogical, veclogical,  vecsimple,   mffgpr,      mftgpr,
6910                  *,          *,           *")
6911    (set_attr "length"
6912                 "*,          *,           *,           *,           *,
6913                  *,          *,           *,           *,           *,
6914                  8,          *,           *,           *,           *,
6915                  *,          *,           8,           *,           *,
6916                  *,          *,           *")
6917    (set_attr "isa"
6918                 "*,          *,           *,           p8v,         p8v,
6919                  *,          p8v,         p8v,         *,           *,
6920                  *,          p8v,         p9v,         p9v,         p8v,
6921                  p9v,        p8v,         p9v,         p8v,         p8v,
6922                  *,          *,           *")])
6924 ;; Like movsi, but adjust a SF value to be used in a SI context, i.e.
6925 ;; (set (reg:SI ...) (subreg:SI (reg:SF ...) 0))
6927 ;; Because SF values are actually stored as DF values within the vector
6928 ;; registers, we need to convert the value to the vector SF format when
6929 ;; we need to use the bits in a union or similar cases.  We only need
6930 ;; to do this transformation when the value is a vector register.  Loads,
6931 ;; stores, and transfers within GPRs are assumed to be safe.
6933 ;; This is a more general case of reload_gpr_from_vsxsf.  That insn must have
6934 ;; no alternatives, because the call is created as part of secondary_reload,
6935 ;; and operand #2's register class is used to allocate the temporary register.
6936 ;; This function is called before reload, and it creates the temporary as
6937 ;; needed.
6939 ;;              MR           LWZ          LFIWZX       LXSIWZX   STW
6940 ;;              STFS         STXSSP       STXSSPX      VSX->GPR  VSX->VSX
6941 ;;              MTVSRWZ
6943 (define_insn_and_split "movsi_from_sf"
6944   [(set (match_operand:SI 0 "nonimmediate_operand"
6945                 "=r,         r,           ?*d,         ?*v,      m,
6946                  m,          wY,          Z,           r,        ?*wa,
6947                  wa")
6948         (unspec:SI [(match_operand:SF 1 "input_operand"
6949                 "r,          m,           Z,           Z,        r,
6950                  f,          v,           wa,          wa,       wa,
6951                  r")]
6952                     UNSPEC_SI_FROM_SF))
6953    (clobber (match_scratch:V4SF 2
6954                 "=X,         X,           X,           X,        X,
6955                  X,          X,           X,           wa,       X,
6956                  X"))]
6957   "TARGET_NO_SF_SUBREG
6958    && (register_operand (operands[0], SImode)
6959        || register_operand (operands[1], SFmode))"
6960   "@
6961    mr %0,%1
6962    lwz%U1%X1 %0,%1
6963    lfiwzx %0,%y1
6964    lxsiwzx %x0,%y1
6965    stw%U0%X0 %1,%0
6966    stfs%U0%X0 %1,%0
6967    stxssp %1,%0
6968    stxsspx %x1,%y0
6969    #
6970    xscvdpspn %x0,%x1
6971    mtvsrwz %x0,%1"
6972   "&& reload_completed
6973    && int_reg_operand (operands[0], SImode)
6974    && vsx_reg_sfsubreg_ok (operands[1], SFmode)"
6975   [(const_int 0)]
6977   rtx op0 = operands[0];
6978   rtx op1 = operands[1];
6979   rtx op2 = operands[2];
6980   rtx op0_di = gen_rtx_REG (DImode, reg_or_subregno (op0));
6981   rtx op2_si = gen_rtx_REG (SImode, reg_or_subregno (op2));
6983   emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
6984   emit_insn (gen_zero_extendsidi2 (op0_di, op2_si));
6985   DONE;
6987   [(set_attr "type"
6988                 "*,          load,        fpload,      fpload,   store,
6989                  fpstore,    fpstore,     fpstore,     mftgpr,   fp,
6990                  mffgpr")
6991    (set_attr "length"
6992                 "*,          *,           *,           *,        *,
6993                  *,          *,           *,           8,        *,
6994                  *")
6995    (set_attr "isa"
6996                 "*,          *,           p8v,         p8v,      *,
6997                  *,          p9v,         p8v,         p8v,      p8v,
6998                  p8v")])
7000 ;; movsi_from_sf with zero extension
7002 ;;              RLDICL       LWZ          LFIWZX       LXSIWZX   VSX->GPR
7003 ;;              VSX->VSX     MTVSRWZ
7005 (define_insn_and_split "*movdi_from_sf_zero_ext"
7006   [(set (match_operand:DI 0 "gpc_reg_operand"
7007                 "=r,         r,           ?*d,         ?*v,      r,
7008                  ?v,         wa")
7009         (zero_extend:DI
7010          (unspec:SI [(match_operand:SF 1 "input_operand"
7011                 "r,          m,           Z,           Z,        wa,
7012                  wa,         r")]
7013                     UNSPEC_SI_FROM_SF)))
7014    (clobber (match_scratch:V4SF 2
7015                 "=X,         X,           X,           X,        wa,
7016                  wa,         X"))]
7017   "TARGET_DIRECT_MOVE_64BIT
7018    && (register_operand (operands[0], DImode)
7019        || register_operand (operands[1], SImode))"
7020   "@
7021    rldicl %0,%1,0,32
7022    lwz%U1%X1 %0,%1
7023    lfiwzx %0,%y1
7024    lxsiwzx %x0,%y1
7025    #
7026    #
7027    mtvsrwz %x0,%1"
7028   "&& reload_completed
7029    && register_operand (operands[0], DImode)
7030    && vsx_reg_sfsubreg_ok (operands[1], SFmode)"
7031   [(const_int 0)]
7033   rtx op0 = operands[0];
7034   rtx op1 = operands[1];
7035   rtx op2 = operands[2];
7036   rtx op2_si = gen_rtx_REG (SImode, reg_or_subregno (op2));
7038   emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
7039   emit_insn (gen_zero_extendsidi2 (op0, op2_si));
7040   DONE;
7042   [(set_attr "type"
7043                 "*,          load,        fpload,      fpload,   two,
7044                  two,        mffgpr")
7045    (set_attr "length"
7046                 "*,          *,           *,           *,        8,
7047                  8,          *")
7048    (set_attr "isa"
7049                 "*,          *,           p8v,         p8v,      p8v,
7050                  p9v,        p8v")])
7052 ;; Like movsi_from_sf, but combine a convert from DFmode to SFmode before
7053 ;; moving it to SImode.  We cannot do a SFmode store without having to do the
7054 ;; conversion explicitly since that doesn't work in most cases if the input
7055 ;; isn't representable as SF.  Use XSCVDPSP instead of XSCVDPSPN, since the
7056 ;; former handles cases where the input will not fit in a SFmode, and the
7057 ;; latter assumes the value has already been rounded.
7058 (define_insn "*movsi_from_df"
7059   [(set (match_operand:SI 0 "gpc_reg_operand" "=wa")
7060         (unspec:SI [(float_truncate:SF
7061                      (match_operand:DF 1 "gpc_reg_operand" "wa"))]
7062                     UNSPEC_SI_FROM_SF))]
7063   "TARGET_NO_SF_SUBREG"
7064   "xscvdpsp %x0,%x1"
7065   [(set_attr "type" "fp")])
7067 ;; Split a load of a large constant into the appropriate two-insn
7068 ;; sequence.
7070 (define_split
7071   [(set (match_operand:SI 0 "gpc_reg_operand")
7072         (match_operand:SI 1 "const_int_operand"))]
7073   "(unsigned HOST_WIDE_INT) (INTVAL (operands[1]) + 0x8000) >= 0x10000
7074    && (INTVAL (operands[1]) & 0xffff) != 0"
7075   [(set (match_dup 0)
7076         (match_dup 2))
7077    (set (match_dup 0)
7078         (ior:SI (match_dup 0)
7079                 (match_dup 3)))]
7081   if (rs6000_emit_set_const (operands[0], operands[1]))
7082     DONE;
7083   else
7084     FAIL;
7087 ;; Split loading -128..127 to use XXSPLITB and VEXTSW2D
7088 (define_split
7089   [(set (match_operand:DI 0 "altivec_register_operand")
7090         (match_operand:DI 1 "xxspltib_constant_split"))]
7091   "TARGET_P9_VECTOR && reload_completed"
7092   [(const_int 0)]
7094   rtx op0 = operands[0];
7095   rtx op1 = operands[1];
7096   int r = REGNO (op0);
7097   rtx op0_v16qi = gen_rtx_REG (V16QImode, r);
7099   emit_insn (gen_xxspltib_v16qi (op0_v16qi, op1));
7100   emit_insn (gen_vsx_sign_extend_qi_si (operands[0], op0_v16qi));
7101   DONE;
7104 (define_insn "*mov<mode>_internal2"
7105   [(set (match_operand:CC 2 "cc_reg_operand" "=y,x,?y")
7106         (compare:CC (match_operand:P 1 "gpc_reg_operand" "0,r,r")
7107                     (const_int 0)))
7108    (set (match_operand:P 0 "gpc_reg_operand" "=r,r,r") (match_dup 1))]
7109   ""
7110   "@
7111    cmp<wd>i %2,%0,0
7112    mr. %0,%1
7113    #"
7114   [(set_attr "type" "cmp,logical,cmp")
7115    (set_attr "dot" "yes")
7116    (set_attr "length" "4,4,8")])
7118 (define_split
7119   [(set (match_operand:CC 2 "cc_reg_not_cr0_operand")
7120         (compare:CC (match_operand:P 1 "gpc_reg_operand")
7121                     (const_int 0)))
7122    (set (match_operand:P 0 "gpc_reg_operand") (match_dup 1))]
7123   "reload_completed"
7124   [(set (match_dup 0) (match_dup 1))
7125    (set (match_dup 2)
7126         (compare:CC (match_dup 0)
7127                     (const_int 0)))]
7128   "")
7130 (define_expand "mov<mode>"
7131   [(set (match_operand:INT 0 "general_operand")
7132         (match_operand:INT 1 "any_operand"))]
7133   ""
7135   rs6000_emit_move (operands[0], operands[1], <MODE>mode);
7136   DONE;
7139 ;;              MR          LHZ/LBZ    LXSI*ZX    STH/STB    STXSI*X    LI
7140 ;;              XXLOR       load 0     load -1    VSPLTI*    #          MFVSRWZ
7141 ;;              MTVSRWZ     MF%1       MT%1       NOP
7142 (define_insn "*mov<mode>_internal"
7143   [(set (match_operand:QHI 0 "nonimmediate_operand"
7144                 "=r,        r,         wa,        m,         Z,         r,
7145                  wa,        wa,        wa,        v,         ?v,        r,
7146                  wa,        r,         *c*l,      *h")
7147         (match_operand:QHI 1 "input_operand"
7148                 "r,         m,         Z,         r,         wa,        i,
7149                  wa,        O,         wM,        wB,        wS,        wa,
7150                  r,         *h,        r,         0"))]
7151   "gpc_reg_operand (operands[0], <MODE>mode)
7152    || gpc_reg_operand (operands[1], <MODE>mode)"
7153   "@
7154    mr %0,%1
7155    l<wd>z%U1%X1 %0,%1
7156    lxsi<wd>zx %x0,%y1
7157    st<wd>%U0%X0 %1,%0
7158    stxsi<wd>x %x1,%y0
7159    li %0,%1
7160    xxlor %x0,%x1,%x1
7161    xxspltib %x0,0
7162    xxspltib %x0,255
7163    vspltis<wd> %0,%1
7164    #
7165    mfvsrwz %0,%x1
7166    mtvsrwz %x0,%1
7167    mf%1 %0
7168    mt%0 %1
7169    nop"
7170   [(set_attr "type"
7171                 "*,         load,      fpload,    store,     fpstore,   *,
7172                  vecsimple, vecperm,   vecperm,   vecperm,   vecperm,   mftgpr,
7173                  mffgpr,    mfjmpr,    mtjmpr,    *")
7174    (set_attr "length"
7175                 "*,         *,         *,         *,         *,         *,
7176                  *,         *,         *,         *,         8,         *,
7177                  *,         *,         *,         *")
7178    (set_attr "isa"
7179                 "*,         *,         p9v,       *,         p9v,       *,
7180                  p9v,       p9v,       p9v,       p9v,       p9v,       p9v,
7181                  p9v,       *,         *,         *")])
7184 ;; Here is how to move condition codes around.  When we store CC data in
7185 ;; an integer register or memory, we store just the high-order 4 bits.
7186 ;; This lets us not shift in the most common case of CR0.
7187 (define_expand "movcc"
7188   [(set (match_operand:CC 0 "nonimmediate_operand")
7189         (match_operand:CC 1 "nonimmediate_operand"))]
7190   ""
7191   "")
7193 (define_insn "*movcc_internal1"
7194   [(set (match_operand:CC 0 "nonimmediate_operand"
7195                             "=y,x,?y,y,r,r,r,r, r,*c*l,r,m")
7196         (match_operand:CC 1 "general_operand"
7197                             " y,r, r,O,x,y,r,I,*h,   r,m,r"))]
7198   "register_operand (operands[0], CCmode)
7199    || register_operand (operands[1], CCmode)"
7200   "@
7201    mcrf %0,%1
7202    mtcrf 128,%1
7203    rlwinm %1,%1,%F0,0xffffffff\;mtcrf %R0,%1\;rlwinm %1,%1,%f0,0xffffffff
7204    crxor %0,%0,%0
7205    mfcr %0%Q1
7206    mfcr %0%Q1\;rlwinm %0,%0,%f1,0xf0000000
7207    mr %0,%1
7208    li %0,%1
7209    mf%1 %0
7210    mt%0 %1
7211    lwz%U1%X1 %0,%1
7212    stw%U0%X0 %1,%0"
7213   [(set_attr_alternative "type"
7214      [(const_string "cr_logical")
7215       (const_string "mtcr")
7216       (const_string "mtcr")
7217       (const_string "cr_logical")
7218       (if_then_else (match_test "TARGET_MFCRF")
7219                     (const_string "mfcrf") (const_string "mfcr"))
7220       (if_then_else (match_test "TARGET_MFCRF")
7221                     (const_string "mfcrf") (const_string "mfcr"))
7222       (const_string "integer")
7223       (const_string "integer")
7224       (const_string "mfjmpr")
7225       (const_string "mtjmpr")
7226       (const_string "load")
7227       (const_string "store")])
7228    (set_attr "length" "*,*,12,*,*,8,*,*,*,*,*,*")])
7230 ;; For floating-point, we normally deal with the floating-point registers
7231 ;; unless -msoft-float is used.  The sole exception is that parameter passing
7232 ;; can produce floating-point values in fixed-point registers.  Unless the
7233 ;; value is a simple constant or already in memory, we deal with this by
7234 ;; allocating memory and copying the value explicitly via that memory location.
7236 ;; Move 32-bit binary/decimal floating point
7237 (define_expand "mov<mode>"
7238   [(set (match_operand:FMOVE32 0 "nonimmediate_operand")
7239         (match_operand:FMOVE32 1 "any_operand"))]
7240   "<fmove_ok>"
7242   rs6000_emit_move (operands[0], operands[1], <MODE>mode);
7243   DONE;
7246 (define_split
7247   [(set (match_operand:FMOVE32 0 "gpc_reg_operand")
7248         (match_operand:FMOVE32 1 "const_double_operand"))]
7249   "reload_completed
7250    && ((REG_P (operands[0]) && REGNO (operands[0]) <= 31)
7251        || (SUBREG_P (operands[0])
7252            && REG_P (SUBREG_REG (operands[0]))
7253            && REGNO (SUBREG_REG (operands[0])) <= 31))"
7254   [(set (match_dup 2) (match_dup 3))]
7256   long l;
7258   <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7260   if (! TARGET_POWERPC64)
7261     operands[2] = operand_subword (operands[0], 0, 0, <MODE>mode);
7262   else
7263     operands[2] = gen_lowpart (SImode, operands[0]);
7265   operands[3] = gen_int_mode (l, SImode);
7268 ;; Originally, we tried to keep movsf and movsd common, but the differences
7269 ;; addressing was making it rather difficult to hide with mode attributes.  In
7270 ;; particular for SFmode, on ISA 2.07 (power8) systems, having the GPR store
7271 ;; before the VSX stores meant that the register allocator would tend to do a
7272 ;; direct move to the GPR (which involves conversion from scalar to
7273 ;; vector/memory formats) to save values in the traditional Altivec registers,
7274 ;; while SDmode had problems on power6 if the GPR store was not first due to
7275 ;; the power6 not having an integer store operation.
7277 ;;      LWZ          LFS        LXSSP       LXSSPX     STFS       STXSSP
7278 ;;      STXSSPX      STW        XXLXOR      LI         FMR        XSCPSGNDP
7279 ;;      MR           MT<x>      MF<x>       NOP
7281 (define_insn "movsf_hardfloat"
7282   [(set (match_operand:SF 0 "nonimmediate_operand"
7283          "=!r,       f,         v,          wa,        m,         wY,
7284           Z,         m,         wa,         !r,        f,         wa,
7285           !r,        *c*l,      !r,         *h")
7286         (match_operand:SF 1 "input_operand"
7287          "m,         m,         wY,         Z,         f,         v,
7288           wa,        r,         j,          j,         f,         wa,
7289           r,         r,         *h,         0"))]
7290   "(register_operand (operands[0], SFmode)
7291    || register_operand (operands[1], SFmode))
7292    && TARGET_HARD_FLOAT
7293    && (TARGET_ALLOW_SF_SUBREG
7294        || valid_sf_si_move (operands[0], operands[1], SFmode))"
7295   "@
7296    lwz%U1%X1 %0,%1
7297    lfs%U1%X1 %0,%1
7298    lxssp %0,%1
7299    lxsspx %x0,%y1
7300    stfs%U0%X0 %1,%0
7301    stxssp %1,%0
7302    stxsspx %x1,%y0
7303    stw%U0%X0 %1,%0
7304    xxlxor %x0,%x0,%x0
7305    li %0,0
7306    fmr %0,%1
7307    xscpsgndp %x0,%x1,%x1
7308    mr %0,%1
7309    mt%0 %1
7310    mf%1 %0
7311    nop"
7312   [(set_attr "type"
7313         "load,       fpload,    fpload,     fpload,    fpstore,   fpstore,
7314          fpstore,    store,     veclogical, integer,   fpsimple,  fpsimple,
7315          *,          mtjmpr,    mfjmpr,     *")
7316    (set_attr "isa"
7317         "*,          *,         p9v,        p8v,       *,         p9v,
7318          p8v,        *,         *,          *,         *,         *,
7319          *,          *,         *,          *")])
7321 ;;      LWZ          LFIWZX     STW        STFIWX     MTVSRWZ    MFVSRWZ
7322 ;;      FMR          MR         MT%0       MF%1       NOP
7323 (define_insn "movsd_hardfloat"
7324   [(set (match_operand:SD 0 "nonimmediate_operand"
7325          "=!r,       d,         m,         Z,         ?d,        ?r,
7326           f,         !r,        *c*l,      !r,        *h")
7327         (match_operand:SD 1 "input_operand"
7328          "m,         Z,         r,         wx,        r,         d,
7329           f,         r,         r,         *h,        0"))]
7330   "(register_operand (operands[0], SDmode)
7331    || register_operand (operands[1], SDmode))
7332    && TARGET_HARD_FLOAT"
7333   "@
7334    lwz%U1%X1 %0,%1
7335    lfiwzx %0,%y1
7336    stw%U0%X0 %1,%0
7337    stfiwx %1,%y0
7338    mtvsrwz %x0,%1
7339    mfvsrwz %0,%x1
7340    fmr %0,%1
7341    mr %0,%1
7342    mt%0 %1
7343    mf%1 %0
7344    nop"
7345   [(set_attr "type"
7346         "load,       fpload,    store,     fpstore,   mffgpr,    mftgpr,
7347          fpsimple,   *,         mtjmpr,    mfjmpr,    *")
7348    (set_attr "isa"
7349         "*,          p7,        *,         *,         p8v,       p8v,
7350          *,          *,         *,         *,         *")])
7352 ;;      MR           MT%0       MF%0       LWZ        STW        LI
7353 ;;      LIS          G-const.   F/n-const  NOP
7354 (define_insn "*mov<mode>_softfloat"
7355   [(set (match_operand:FMOVE32 0 "nonimmediate_operand"
7356         "=r,         *c*l,      r,         r,         m,         r,
7357           r,         r,         r,         *h")
7359         (match_operand:FMOVE32 1 "input_operand"
7360          "r,         r,         *h,        m,         r,         I,
7361           L,         G,         Fn,        0"))]
7363   "(gpc_reg_operand (operands[0], <MODE>mode)
7364    || gpc_reg_operand (operands[1], <MODE>mode))
7365    && TARGET_SOFT_FLOAT"
7366   "@
7367    mr %0,%1
7368    mt%0 %1
7369    mf%1 %0
7370    lwz%U1%X1 %0,%1
7371    stw%U0%X0 %1,%0
7372    li %0,%1
7373    lis %0,%v1
7374    #
7375    #
7376    nop"
7377   [(set_attr "type"
7378         "*,          mtjmpr,    mfjmpr,    load,      store,     *,
7379          *,          *,         *,         *")
7381    (set_attr "length"
7382         "*,          *,         *,         *,         *,         *,
7383          *,          *,         8,         *")])
7385 ;; Like movsf, but adjust a SI value to be used in a SF context, i.e.
7386 ;; (set (reg:SF ...) (subreg:SF (reg:SI ...) 0))
7388 ;; Because SF values are actually stored as DF values within the vector
7389 ;; registers, we need to convert the value to the vector SF format when
7390 ;; we need to use the bits in a union or similar cases.  We only need
7391 ;; to do this transformation when the value is a vector register.  Loads,
7392 ;; stores, and transfers within GPRs are assumed to be safe.
7394 ;; This is a more general case of reload_vsx_from_gprsf.  That insn must have
7395 ;; no alternatives, because the call is created as part of secondary_reload,
7396 ;; and operand #2's register class is used to allocate the temporary register.
7397 ;; This function is called before reload, and it creates the temporary as
7398 ;; needed.
7400 ;;          LWZ          LFS        LXSSP      LXSSPX     STW        STFIWX
7401 ;;          STXSIWX      GPR->VSX   VSX->GPR   GPR->GPR
7402 (define_insn_and_split "movsf_from_si"
7403   [(set (match_operand:SF 0 "nonimmediate_operand"
7404             "=!r,       f,         v,         wa,        m,         Z,
7405              Z,         wa,        ?r,        !r")
7406         (unspec:SF [(match_operand:SI 1 "input_operand" 
7407             "m,         m,         wY,        Z,         r,         f,
7408              wa,        r,         wa,        r")]
7409                    UNSPEC_SF_FROM_SI))
7410    (clobber (match_scratch:DI 2
7411             "=X,        X,         X,         X,         X,         X,
7412              X,         r,         X,         X"))]
7413   "TARGET_NO_SF_SUBREG
7414    && (register_operand (operands[0], SFmode)
7415        || register_operand (operands[1], SImode))"
7416   "@
7417    lwz%U1%X1 %0,%1
7418    lfs%U1%X1 %0,%1
7419    lxssp %0,%1
7420    lxsspx %x0,%y1
7421    stw%U0%X0 %1,%0
7422    stfiwx %1,%y0
7423    stxsiwx %x1,%y0
7424    #
7425    mfvsrwz %0,%x1
7426    mr %0,%1"
7428   "&& reload_completed
7429    && vsx_reg_sfsubreg_ok (operands[0], SFmode)
7430    && int_reg_operand_not_pseudo (operands[1], SImode)"
7431   [(const_int 0)]
7433   rtx op0 = operands[0];
7434   rtx op1 = operands[1];
7435   rtx op2 = operands[2];
7436   rtx op1_di = gen_rtx_REG (DImode, REGNO (op1));
7438   /* Move SF value to upper 32-bits for xscvspdpn.  */
7439   emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32)));
7440   emit_insn (gen_p8_mtvsrd_sf (op0, op2));
7441   emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0));
7442   DONE;
7444   [(set_attr "length"
7445             "*,          *,         *,         *,         *,         *,
7446              *,          12,        *,         *")
7447    (set_attr "type"
7448             "load,       fpload,    fpload,    fpload,    store,     fpstore,
7449              fpstore,    vecfloat,  mffgpr,    *")
7450    (set_attr "isa"
7451             "*,          *,         p9v,       p8v,       *,         *,
7452              p8v,        p8v,       p8v,       *")])
7455 ;; Move 64-bit binary/decimal floating point
7456 (define_expand "mov<mode>"
7457   [(set (match_operand:FMOVE64 0 "nonimmediate_operand")
7458         (match_operand:FMOVE64 1 "any_operand"))]
7459   ""
7461   rs6000_emit_move (operands[0], operands[1], <MODE>mode);
7462   DONE;
7465 (define_split
7466   [(set (match_operand:FMOVE64 0 "gpc_reg_operand")
7467         (match_operand:FMOVE64 1 "const_int_operand"))]
7468   "! TARGET_POWERPC64 && reload_completed
7469    && ((REG_P (operands[0]) && REGNO (operands[0]) <= 31)
7470        || (SUBREG_P (operands[0])
7471            && REG_P (SUBREG_REG (operands[0]))
7472            && REGNO (SUBREG_REG (operands[0])) <= 31))"
7473   [(set (match_dup 2) (match_dup 4))
7474    (set (match_dup 3) (match_dup 1))]
7476   int endian = (WORDS_BIG_ENDIAN == 0);
7477   HOST_WIDE_INT value = INTVAL (operands[1]);
7479   operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
7480   operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
7481   operands[4] = GEN_INT (value >> 32);
7482   operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
7485 (define_split
7486   [(set (match_operand:FMOVE64 0 "gpc_reg_operand")
7487         (match_operand:FMOVE64 1 "const_double_operand"))]
7488   "! TARGET_POWERPC64 && reload_completed
7489    && ((REG_P (operands[0]) && REGNO (operands[0]) <= 31)
7490        || (SUBREG_P (operands[0])
7491            && REG_P (SUBREG_REG (operands[0]))
7492            && REGNO (SUBREG_REG (operands[0])) <= 31))"
7493   [(set (match_dup 2) (match_dup 4))
7494    (set (match_dup 3) (match_dup 5))]
7496   int endian = (WORDS_BIG_ENDIAN == 0);
7497   long l[2];
7499   <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7501   operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
7502   operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
7503   operands[4] = gen_int_mode (l[endian], SImode);
7504   operands[5] = gen_int_mode (l[1 - endian], SImode);
7507 (define_split
7508   [(set (match_operand:FMOVE64 0 "gpc_reg_operand")
7509         (match_operand:FMOVE64 1 "const_double_operand"))]
7510   "TARGET_POWERPC64 && reload_completed
7511    && ((REG_P (operands[0]) && REGNO (operands[0]) <= 31)
7512        || (SUBREG_P (operands[0])
7513            && REG_P (SUBREG_REG (operands[0]))
7514            && REGNO (SUBREG_REG (operands[0])) <= 31))"
7515   [(set (match_dup 2) (match_dup 3))]
7517   int endian = (WORDS_BIG_ENDIAN == 0);
7518   long l[2];
7519   HOST_WIDE_INT val;
7521   <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7523   operands[2] = gen_lowpart (DImode, operands[0]);
7524   /* HIGHPART is lower memory address when WORDS_BIG_ENDIAN.  */
7525   val = ((HOST_WIDE_INT)(unsigned long)l[endian] << 32
7526          | ((HOST_WIDE_INT)(unsigned long)l[1 - endian]));
7528   operands[3] = gen_int_mode (val, DImode);
7531 ;; Don't have reload use general registers to load a constant.  It is
7532 ;; less efficient than loading the constant into an FP register, since
7533 ;; it will probably be used there.
7535 ;; The move constraints are ordered to prefer floating point registers before
7536 ;; general purpose registers to avoid doing a store and a load to get the value
7537 ;; into a floating point register when it is needed for a floating point
7538 ;; operation.  Prefer traditional floating point registers over VSX registers,
7539 ;; since the D-form version of the memory instructions does not need a GPR for
7540 ;; reloading.  ISA 3.0 (power9) adds D-form addressing for scalars to Altivec
7541 ;; registers.
7543 ;; If we have FPR registers, rs6000_emit_move has moved all constants to memory,
7544 ;; except for 0.0 which can be created on VSX with an xor instruction.
7546 ;;           STFD         LFD         FMR         LXSD        STXSD
7547 ;;           LXSD         STXSD       XXLOR       XXLXOR      GPR<-0
7548 ;;           LWZ          STW         MR
7551 (define_insn "*mov<mode>_hardfloat32"
7552   [(set (match_operand:FMOVE64 0 "nonimmediate_operand"
7553             "=m,          d,          d,          <f64_p9>,   wY,
7554               <f64_av>,   Z,          <f64_vsx>,  <f64_vsx>,  !r,
7555               Y,          r,          !r")
7556         (match_operand:FMOVE64 1 "input_operand"
7557              "d,          m,          d,          wY,         <f64_p9>,
7558               Z,          <f64_av>,   <f64_vsx>,  <zero_fp>,  <zero_fp>,
7559               r,          Y,          r"))]
7560   "! TARGET_POWERPC64 && TARGET_HARD_FLOAT
7561    && (gpc_reg_operand (operands[0], <MODE>mode)
7562        || gpc_reg_operand (operands[1], <MODE>mode))"
7563   "@
7564    stfd%U0%X0 %1,%0
7565    lfd%U1%X1 %0,%1
7566    fmr %0,%1
7567    lxsd %0,%1
7568    stxsd %1,%0
7569    lxsdx %x0,%y1
7570    stxsdx %x1,%y0
7571    xxlor %x0,%x1,%x1
7572    xxlxor %x0,%x0,%x0
7573    #
7574    #
7575    #
7576    #"
7577   [(set_attr "type"
7578             "fpstore,     fpload,     fpsimple,   fpload,     fpstore,
7579              fpload,      fpstore,    veclogical, veclogical, two,
7580              store,       load,       two")
7581    (set_attr "size" "64")
7582    (set_attr "length"
7583             "*,           *,          *,          *,          *,
7584              *,           *,          *,          *,          8,
7585              8,           8,          8")
7586    (set_attr "isa"
7587             "*,           *,          *,          p9v,        p9v,
7588              p7v,         p7v,        *,          *,          *,
7589              *,           *,          *")])
7591 ;;           STW      LWZ     MR      G-const H-const F-const
7593 (define_insn "*mov<mode>_softfloat32"
7594   [(set (match_operand:FMOVE64 0 "nonimmediate_operand"
7595            "=Y,       r,      r,      r,      r,      r")
7597         (match_operand:FMOVE64 1 "input_operand"
7598             "r,       Y,      r,      G,      H,      F"))]
7600   "!TARGET_POWERPC64
7601    && (gpc_reg_operand (operands[0], <MODE>mode)
7602        || gpc_reg_operand (operands[1], <MODE>mode))"
7603   "#"
7604   [(set_attr "type"
7605             "store,   load,   two,    *,      *,      *")
7607    (set_attr "length"
7608              "8,      8,      8,      8,      12,     16")])
7610 ; ld/std require word-aligned displacements -> 'Y' constraint.
7611 ; List Y->r and r->Y before r->r for reload.
7613 ;;           STFD         LFD         FMR         LXSD        STXSD
7614 ;;           LXSDX        STXSDX      XXLOR       XXLXOR      LI 0
7615 ;;           STD          LD          MR          MT{CTR,LR}  MF{CTR,LR}
7616 ;;           NOP          MFVSRD      MTVSRD
7618 (define_insn "*mov<mode>_hardfloat64"
7619   [(set (match_operand:FMOVE64 0 "nonimmediate_operand"
7620            "=m,           d,          d,          <f64_p9>,   wY,
7621              <f64_av>,    Z,          <f64_vsx>,  <f64_vsx>,  !r,
7622              YZ,          r,          !r,         *c*l,       !r,
7623             *h,           r,          <f64_dm>")
7624         (match_operand:FMOVE64 1 "input_operand"
7625             "d,           m,          d,          wY,         <f64_p9>,
7626              Z,           <f64_av>,   <f64_vsx>,  <zero_fp>,  <zero_fp>,
7627              r,           YZ,         r,          r,          *h,
7628              0,           <f64_dm>,   r"))]
7629   "TARGET_POWERPC64 && TARGET_HARD_FLOAT
7630    && (gpc_reg_operand (operands[0], <MODE>mode)
7631        || gpc_reg_operand (operands[1], <MODE>mode))"
7632   "@
7633    stfd%U0%X0 %1,%0
7634    lfd%U1%X1 %0,%1
7635    fmr %0,%1
7636    lxsd %0,%1
7637    stxsd %1,%0
7638    lxsdx %x0,%y1
7639    stxsdx %x1,%y0
7640    xxlor %x0,%x1,%x1
7641    xxlxor %x0,%x0,%x0
7642    li %0,0
7643    std%U0%X0 %1,%0
7644    ld%U1%X1 %0,%1
7645    mr %0,%1
7646    mt%0 %1
7647    mf%1 %0
7648    nop
7649    mfvsrd %0,%x1
7650    mtvsrd %x0,%1"
7651   [(set_attr "type"
7652             "fpstore,     fpload,     fpsimple,   fpload,     fpstore,
7653              fpload,      fpstore,    veclogical, veclogical, integer,
7654              store,       load,       *,          mtjmpr,     mfjmpr,
7655              *,           mftgpr,     mffgpr")
7656    (set_attr "size" "64")
7657    (set_attr "isa"
7658             "*,           *,          *,          p9v,        p9v,
7659              p7v,         p7v,        *,          *,          *,
7660              *,           *,          *,          *,          *,
7661              *,           p8v,        p8v")])
7663 ;;           STD      LD       MR      MT<SPR> MF<SPR> G-const
7664 ;;           H-const  F-const  Special
7666 (define_insn "*mov<mode>_softfloat64"
7667   [(set (match_operand:FMOVE64 0 "nonimmediate_operand"
7668            "=Y,       r,      r,      *c*l,   r,      r,
7669              r,       r,      *h")
7671         (match_operand:FMOVE64 1 "input_operand"
7672             "r,       Y,      r,      r,      *h,     G,
7673              H,       F,      0"))]
7675   "TARGET_POWERPC64 && TARGET_SOFT_FLOAT
7676    && (gpc_reg_operand (operands[0], <MODE>mode)
7677        || gpc_reg_operand (operands[1], <MODE>mode))"
7678   "@
7679    std%U0%X0 %1,%0
7680    ld%U1%X1 %0,%1
7681    mr %0,%1
7682    mt%0 %1
7683    mf%1 %0
7684    #
7685    #
7686    #
7687    nop"
7688   [(set_attr "type"
7689             "store,   load,   *,      mtjmpr, mfjmpr, *,
7690              *,       *,      *")
7692    (set_attr "length"
7693             "*,       *,      *,      *,      *,      8,
7694              12,      16,     *")])
7696 (define_expand "mov<mode>"
7697   [(set (match_operand:FMOVE128 0 "general_operand")
7698         (match_operand:FMOVE128 1 "any_operand"))]
7699   ""
7701   rs6000_emit_move (operands[0], operands[1], <MODE>mode);
7702   DONE;
7705 ;; It's important to list Y->r and r->Y before r->r because otherwise
7706 ;; reload, given m->r, will try to pick r->r and reload it, which
7707 ;; doesn't make progress.
7709 ;; We can't split little endian direct moves of TDmode, because the words are
7710 ;; not swapped like they are for TImode or TFmode.  Subregs therefore are
7711 ;; problematical.  Don't allow direct move for this case.
7713 (define_insn_and_split "*mov<mode>_64bit_dm"
7714   [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand" "=m,d,d,d,Y,r,r,r,d")
7715         (match_operand:FMOVE128_FPR 1 "input_operand" "d,m,d,<zero_fp>,r,<zero_fp>Y,r,d,r"))]
7716   "TARGET_HARD_FLOAT && TARGET_POWERPC64 && FLOAT128_2REG_P (<MODE>mode)
7717    && (<MODE>mode != TDmode || WORDS_BIG_ENDIAN)
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 "length" "8,8,8,8,12,12,8,8,8")
7725    (set_attr "isa" "*,*,*,*,*,*,*,p8v,p8v")])
7727 (define_insn_and_split "*movtd_64bit_nodm"
7728   [(set (match_operand:TD 0 "nonimmediate_operand" "=m,d,d,Y,r,r")
7729         (match_operand:TD 1 "input_operand" "d,m,d,r,Y,r"))]
7730   "TARGET_HARD_FLOAT && TARGET_POWERPC64 && !WORDS_BIG_ENDIAN
7731    && (gpc_reg_operand (operands[0], TDmode)
7732        || gpc_reg_operand (operands[1], TDmode))"
7733   "#"
7734   "&& reload_completed"
7735   [(pc)]
7736 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7737   [(set_attr "length" "8,8,8,12,12,8")])
7739 (define_insn_and_split "*mov<mode>_32bit"
7740   [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand" "=m,d,d,d,Y,r,r")
7741         (match_operand:FMOVE128_FPR 1 "input_operand" "d,m,d,<zero_fp>,r,<zero_fp>Y,r"))]
7742   "TARGET_HARD_FLOAT && !TARGET_POWERPC64
7743    && (FLOAT128_2REG_P (<MODE>mode)
7744        || int_reg_operand_not_pseudo (operands[0], <MODE>mode)
7745        || int_reg_operand_not_pseudo (operands[1], <MODE>mode))
7746    && (gpc_reg_operand (operands[0], <MODE>mode)
7747        || gpc_reg_operand (operands[1], <MODE>mode))"
7748   "#"
7749   "&& reload_completed"
7750   [(pc)]
7751 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7752   [(set_attr "length" "8,8,8,8,20,20,16")])
7754 (define_insn_and_split "*mov<mode>_softfloat"
7755   [(set (match_operand:FMOVE128 0 "nonimmediate_operand" "=Y,r,r,r")
7756         (match_operand:FMOVE128 1 "input_operand" "r,Y,F,r"))]
7757   "TARGET_SOFT_FLOAT
7758    && (gpc_reg_operand (operands[0], <MODE>mode)
7759        || gpc_reg_operand (operands[1], <MODE>mode))"
7760   "#"
7761   "&& reload_completed"
7762   [(pc)]
7763 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7764   [(set_attr_alternative "length"
7765        [(if_then_else (match_test "TARGET_POWERPC64")
7766             (const_string "8")
7767             (const_string "16"))
7768         (if_then_else (match_test "TARGET_POWERPC64")
7769             (const_string "8")
7770             (const_string "16"))
7771         (if_then_else (match_test "TARGET_POWERPC64")
7772             (const_string "16")
7773             (const_string "32"))
7774         (if_then_else (match_test "TARGET_POWERPC64")
7775             (const_string "8")
7776             (const_string "16"))])])
7778 (define_expand "@extenddf<mode>2"
7779   [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
7780         (float_extend:FLOAT128 (match_operand:DF 1 "gpc_reg_operand")))]
7781   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7783   if (FLOAT128_IEEE_P (<MODE>mode))
7784     rs6000_expand_float128_convert (operands[0], operands[1], false);
7785   else if (TARGET_VSX)
7786     emit_insn (gen_extenddf2_vsx (<MODE>mode, operands[0], operands[1]));
7787   else
7788     {
7789       rtx zero = gen_reg_rtx (DFmode);
7790       rs6000_emit_move (zero, CONST0_RTX (DFmode), DFmode);
7792       emit_insn (gen_extenddf2_fprs (<MODE>mode,
7793                                      operands[0], operands[1], zero));
7794     }
7795   DONE;
7798 ;; Allow memory operands for the source to be created by the combiner.
7799 (define_insn_and_split "@extenddf<mode>2_fprs"
7800   [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d,&d")
7801         (float_extend:IBM128
7802          (match_operand:DF 1 "nonimmediate_operand" "d,m,d")))
7803    (use (match_operand:DF 2 "nonimmediate_operand" "m,m,d"))]
7804   "!TARGET_VSX && TARGET_HARD_FLOAT
7805    && TARGET_LONG_DOUBLE_128 && FLOAT128_IBM_P (<MODE>mode)"
7806   "#"
7807   "&& reload_completed"
7808   [(set (match_dup 3) (match_dup 1))
7809    (set (match_dup 4) (match_dup 2))]
7811   const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7812   const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7814   operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
7815   operands[4] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
7818 (define_insn_and_split "@extenddf<mode>2_vsx"
7819   [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d")
7820         (float_extend:IBM128
7821          (match_operand:DF 1 "nonimmediate_operand" "wa,m")))]
7822   "TARGET_LONG_DOUBLE_128 && TARGET_VSX && FLOAT128_IBM_P (<MODE>mode)"
7823   "#"
7824   "&& reload_completed"
7825   [(set (match_dup 2) (match_dup 1))
7826    (set (match_dup 3) (match_dup 4))]
7828   const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7829   const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7831   operands[2] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
7832   operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
7833   operands[4] = CONST0_RTX (DFmode);
7836 (define_expand "extendsf<mode>2"
7837   [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
7838         (float_extend:FLOAT128 (match_operand:SF 1 "gpc_reg_operand")))]
7839   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7841   if (FLOAT128_IEEE_P (<MODE>mode))
7842     rs6000_expand_float128_convert (operands[0], operands[1], false);
7843   else
7844     {
7845       rtx tmp = gen_reg_rtx (DFmode);
7846       emit_insn (gen_extendsfdf2 (tmp, operands[1]));
7847       emit_insn (gen_extenddf<mode>2 (operands[0], tmp));
7848     }
7849   DONE;
7852 (define_expand "trunc<mode>df2"
7853   [(set (match_operand:DF 0 "gpc_reg_operand")
7854         (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand")))]
7855   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7857   if (FLOAT128_IEEE_P (<MODE>mode))
7858     {
7859       rs6000_expand_float128_convert (operands[0], operands[1], false);
7860       DONE;
7861     }
7864 (define_insn_and_split "trunc<mode>df2_internal1"
7865   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d")
7866         (float_truncate:DF
7867          (match_operand:IBM128 1 "gpc_reg_operand" "0,d")))]
7868   "FLOAT128_IBM_P (<MODE>mode) && !TARGET_XL_COMPAT
7869    && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7870   "@
7871    #
7872    fmr %0,%1"
7873   "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
7874   [(const_int 0)]
7876   emit_note (NOTE_INSN_DELETED);
7877   DONE;
7879   [(set_attr "type" "fpsimple")])
7881 (define_insn "trunc<mode>df2_internal2"
7882   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
7883         (float_truncate:DF (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
7884   "FLOAT128_IBM_P (<MODE>mode) && TARGET_XL_COMPAT && TARGET_HARD_FLOAT
7885    && TARGET_LONG_DOUBLE_128"
7886   "fadd %0,%1,%L1"
7887   [(set_attr "type" "fp")])
7889 (define_expand "trunc<mode>sf2"
7890   [(set (match_operand:SF 0 "gpc_reg_operand")
7891         (float_truncate:SF (match_operand:FLOAT128 1 "gpc_reg_operand")))]
7892   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7894   if (FLOAT128_IEEE_P (<MODE>mode))
7895     rs6000_expand_float128_convert (operands[0], operands[1], false);
7896   else
7897     {
7898       rtx tmp = gen_reg_rtx (DFmode);
7899       emit_insn (gen_trunc<mode>df2 (tmp, operands[1]));
7900       emit_insn (gen_truncdfsf2 (operands[0], tmp));
7901     }
7902   DONE;
7905 (define_expand "floatsi<mode>2"
7906   [(parallel [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
7907                    (float:FLOAT128 (match_operand:SI 1 "gpc_reg_operand")))
7908               (clobber (match_scratch:DI 2))])]
7909   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7911   rtx op0 = operands[0];
7912   rtx op1 = operands[1];
7914   if (TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode))
7915     ;
7916   else if (FLOAT128_IEEE_P (<MODE>mode))
7917     {
7918       rs6000_expand_float128_convert (op0, op1, false);
7919       DONE;
7920     }
7921   else
7922     {
7923       rtx tmp = gen_reg_rtx (DFmode);
7924       expand_float (tmp, op1, false);
7925       emit_insn (gen_extenddf2 (<MODE>mode, op0, tmp));
7926       DONE;
7927     }
7930 ; fadd, but rounding towards zero.
7931 ; This is probably not the optimal code sequence.
7932 (define_insn "fix_trunc_helper<mode>"
7933   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
7934         (unspec:DF [(match_operand:IBM128 1 "gpc_reg_operand" "d")]
7935                    UNSPEC_FIX_TRUNC_TF))
7936    (clobber (match_operand:DF 2 "gpc_reg_operand" "=&d"))]
7937   "TARGET_HARD_FLOAT && FLOAT128_IBM_P (<MODE>mode)"
7938   "mffs %2\n\tmtfsb1 31\n\tmtfsb0 30\n\tfadd %0,%1,%L1\n\tmtfsf 1,%2"
7939   [(set_attr "type" "fp")
7940    (set_attr "length" "20")])
7942 (define_expand "fix_trunc<mode>si2"
7943   [(set (match_operand:SI 0 "gpc_reg_operand")
7944         (fix:SI (match_operand:FLOAT128 1 "gpc_reg_operand")))]
7945   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7947   rtx op0 = operands[0];
7948   rtx op1 = operands[1];
7950   if (TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode))
7951     ;
7952   else
7953     {
7954       if (FLOAT128_IEEE_P (<MODE>mode))
7955         rs6000_expand_float128_convert (op0, op1, false);
7956       else
7957         emit_insn (gen_fix_truncsi2_fprs (<MODE>mode, op0, op1));
7958       DONE;
7959     }
7962 (define_expand "@fix_trunc<mode>si2_fprs"
7963   [(parallel [(set (match_operand:SI 0 "gpc_reg_operand")
7964                    (fix:SI (match_operand:IBM128 1 "gpc_reg_operand")))
7965               (clobber (match_dup 2))
7966               (clobber (match_dup 3))
7967               (clobber (match_dup 4))
7968               (clobber (match_dup 5))])]
7969   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7971   operands[2] = gen_reg_rtx (DFmode);
7972   operands[3] = gen_reg_rtx (DFmode);
7973   operands[4] = gen_reg_rtx (DImode);
7974   operands[5] = assign_stack_temp (DImode, GET_MODE_SIZE (DImode));
7977 (define_insn_and_split "*fix_trunc<mode>si2_internal"
7978   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
7979         (fix:SI (match_operand:IBM128 1 "gpc_reg_operand" "d")))
7980    (clobber (match_operand:DF 2 "gpc_reg_operand" "=d"))
7981    (clobber (match_operand:DF 3 "gpc_reg_operand" "=&d"))
7982    (clobber (match_operand:DI 4 "gpc_reg_operand" "=d"))
7983    (clobber (match_operand:DI 5 "offsettable_mem_operand" "=o"))]
7984   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7985   "#"
7986   ""
7987   [(pc)]
7989   rtx lowword;
7990   emit_insn (gen_fix_trunc_helper<mode> (operands[2], operands[1],
7991                                          operands[3]));
7993   gcc_assert (MEM_P (operands[5]));
7994   lowword = adjust_address (operands[5], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
7996   emit_insn (gen_fctiwz_df (operands[4], operands[2]));
7997   emit_move_insn (operands[5], operands[4]);
7998   emit_move_insn (operands[0], lowword);
7999   DONE;
8002 (define_expand "fix_trunc<mode>di2"
8003   [(set (match_operand:DI 0 "gpc_reg_operand")
8004         (fix:DI (match_operand:IEEE128 1 "gpc_reg_operand")))]
8005   "TARGET_FLOAT128_TYPE"
8007   if (!TARGET_FLOAT128_HW)
8008     {
8009       rs6000_expand_float128_convert (operands[0], operands[1], false);
8010       DONE;
8011     }
8014 (define_expand "fixuns_trunc<IEEE128:mode><SDI:mode>2"
8015   [(set (match_operand:SDI 0 "gpc_reg_operand")
8016         (unsigned_fix:SDI (match_operand:IEEE128 1 "gpc_reg_operand")))]
8017   "TARGET_FLOAT128_TYPE"
8019   rs6000_expand_float128_convert (operands[0], operands[1], true);
8020   DONE;
8023 (define_expand "floatdi<mode>2"
8024   [(set (match_operand:IEEE128 0 "gpc_reg_operand")
8025         (float:IEEE128 (match_operand:DI 1 "gpc_reg_operand")))]
8026   "TARGET_FLOAT128_TYPE"
8028   if (!TARGET_FLOAT128_HW)
8029     {
8030       rs6000_expand_float128_convert (operands[0], operands[1], false);
8031       DONE;
8032     }
8035 (define_expand "floatunsdi<IEEE128:mode>2"
8036   [(set (match_operand:IEEE128 0 "gpc_reg_operand")
8037         (unsigned_float:IEEE128 (match_operand:DI 1 "gpc_reg_operand")))]
8038   "TARGET_FLOAT128_TYPE"
8040   if (!TARGET_FLOAT128_HW)
8041     {
8042       rs6000_expand_float128_convert (operands[0], operands[1], true);
8043       DONE;
8044     }
8047 (define_expand "floatuns<IEEE128:mode>2"
8048   [(set (match_operand:IEEE128 0 "gpc_reg_operand")
8049         (unsigned_float:IEEE128 (match_operand:SI 1 "gpc_reg_operand")))]
8050   "TARGET_FLOAT128_TYPE"
8052   rtx op0 = operands[0];
8053   rtx op1 = operands[1];
8055   if (TARGET_FLOAT128_HW)
8056     emit_insn (gen_floatuns_<IEEE128:mode>si2_hw (op0, op1));
8057   else
8058     rs6000_expand_float128_convert (op0, op1, true);
8059   DONE;
8062 (define_expand "neg<mode>2"
8063   [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
8064         (neg:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand")))]
8065   "FLOAT128_IEEE_P (<MODE>mode)
8066    || (FLOAT128_IBM_P (<MODE>mode) && TARGET_HARD_FLOAT)"
8068   if (FLOAT128_IEEE_P (<MODE>mode))
8069     {
8070       if (TARGET_FLOAT128_HW)
8071         emit_insn (gen_neg2_hw (<MODE>mode, operands[0], operands[1]));
8072       else if (TARGET_FLOAT128_TYPE)
8073         emit_insn (gen_ieee_128bit_vsx_neg2 (<MODE>mode,
8074                                              operands[0], operands[1]));
8075       else
8076         {
8077           rtx libfunc = optab_libfunc (neg_optab, <MODE>mode);
8078           rtx target = emit_library_call_value (libfunc, operands[0], LCT_CONST,
8079                                                 <MODE>mode,
8080                                                 operands[1], <MODE>mode);
8082           if (target && !rtx_equal_p (target, operands[0]))
8083             emit_move_insn (operands[0], target);
8084         }
8085       DONE;
8086     }
8089 (define_insn "neg<mode>2_internal"
8090   [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d")
8091         (neg:IBM128 (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
8092   "TARGET_HARD_FLOAT && FLOAT128_IBM_P (<MODE>mode)"
8094   if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
8095     return "fneg %L0,%L1\;fneg %0,%1";
8096   else
8097     return "fneg %0,%1\;fneg %L0,%L1";
8099   [(set_attr "type" "fpsimple")
8100    (set_attr "length" "8")])
8102 (define_expand "abs<mode>2"
8103   [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
8104         (abs:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand")))]
8105   "FLOAT128_IEEE_P (<MODE>mode)
8106    || (FLOAT128_IBM_P (<MODE>mode) && TARGET_HARD_FLOAT)"
8108   rtx label;
8110   if (FLOAT128_IEEE_P (<MODE>mode))
8111     {
8112       if (TARGET_FLOAT128_HW)
8113         {
8114           emit_insn (gen_abs2_hw (<MODE>mode, operands[0], operands[1]));
8115           DONE;
8116         }
8117       else if (TARGET_FLOAT128_TYPE)
8118         {
8119           emit_insn (gen_ieee_128bit_vsx_abs2 (<MODE>mode,
8120                                                operands[0], operands[1]));
8121           DONE;
8122         }
8123       else
8124         FAIL;
8125     }
8127   label = gen_label_rtx ();
8128   emit_insn (gen_abs2_internal (<MODE>mode, operands[0], operands[1], label));
8129   emit_label (label);
8130   DONE;
8133 (define_expand "@abs<mode>2_internal"
8134   [(set (match_operand:IBM128 0 "gpc_reg_operand")
8135         (match_operand:IBM128 1 "gpc_reg_operand"))
8136    (set (match_dup 3) (match_dup 5))
8137    (set (match_dup 5) (abs:DF (match_dup 5)))
8138    (set (match_dup 4) (compare:CCFP (match_dup 3) (match_dup 5)))
8139    (set (pc) (if_then_else (eq (match_dup 4) (const_int 0))
8140                            (label_ref (match_operand 2 ""))
8141                            (pc)))
8142    (set (match_dup 6) (neg:DF (match_dup 6)))]
8143   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8145   const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
8146   const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
8147   operands[3] = gen_reg_rtx (DFmode);
8148   operands[4] = gen_reg_rtx (CCFPmode);
8149   operands[5] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
8150   operands[6] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
8154 ;; Generate IEEE 128-bit -0.0 (0x80000000000000000000000000000000) in a vector
8155 ;; register
8157 (define_expand "ieee_128bit_negative_zero"
8158   [(set (match_operand:V16QI 0 "register_operand") (match_dup 1))]
8159   "TARGET_FLOAT128_TYPE"
8161   rtvec v = rtvec_alloc (16);
8162   int i, high;
8164   for (i = 0; i < 16; i++)
8165     RTVEC_ELT (v, i) = const0_rtx;
8167   high = (BYTES_BIG_ENDIAN) ? 0 : 15;
8168   RTVEC_ELT (v, high) = gen_int_mode (0x80, QImode);
8170   rs6000_expand_vector_init (operands[0], gen_rtx_PARALLEL (V16QImode, v));
8171   DONE;
8174 ;; IEEE 128-bit negate
8176 ;; We have 2 insns here for negate and absolute value.  The first uses
8177 ;; match_scratch so that phases like combine can recognize neg/abs as generic
8178 ;; insns, and second insn after the first split pass loads up the bit to
8179 ;; twiddle the sign bit.  Later GCSE passes can then combine multiple uses of
8180 ;; neg/abs to create the constant just once.
8182 (define_insn_and_split "@ieee_128bit_vsx_neg<mode>2"
8183   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8184         (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8185    (clobber (match_scratch:V16QI 2 "=v"))]
8186   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8187   "#"
8188   "&& 1"
8189   [(parallel [(set (match_dup 0)
8190                    (neg:IEEE128 (match_dup 1)))
8191               (use (match_dup 2))])]
8193   if (GET_CODE (operands[2]) == SCRATCH)
8194     operands[2] = gen_reg_rtx (V16QImode);
8196   operands[3] = gen_reg_rtx (V16QImode);
8197   emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8199   [(set_attr "length" "8")
8200    (set_attr "type" "vecsimple")])
8202 (define_insn "*ieee_128bit_vsx_neg<mode>2_internal"
8203   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8204         (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8205    (use (match_operand:V16QI 2 "register_operand" "v"))]
8206   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8207   "xxlxor %x0,%x1,%x2"
8208   [(set_attr "type" "veclogical")])
8210 ;; IEEE 128-bit absolute value
8211 (define_insn_and_split "@ieee_128bit_vsx_abs<mode>2"
8212   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8213         (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8214    (clobber (match_scratch:V16QI 2 "=v"))]
8215   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
8216   "#"
8217   "&& 1"
8218   [(parallel [(set (match_dup 0)
8219                    (abs:IEEE128 (match_dup 1)))
8220               (use (match_dup 2))])]
8222   if (GET_CODE (operands[2]) == SCRATCH)
8223     operands[2] = gen_reg_rtx (V16QImode);
8225   operands[3] = gen_reg_rtx (V16QImode);
8226   emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8228   [(set_attr "length" "8")
8229    (set_attr "type" "vecsimple")])
8231 (define_insn "*ieee_128bit_vsx_abs<mode>2_internal"
8232   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8233         (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8234    (use (match_operand:V16QI 2 "register_operand" "v"))]
8235   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8236   "xxlandc %x0,%x1,%x2"
8237   [(set_attr "type" "veclogical")])
8239 ;; IEEE 128-bit negative absolute value
8240 (define_insn_and_split "*ieee_128bit_vsx_nabs<mode>2"
8241   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8242         (neg:IEEE128
8243          (abs:IEEE128
8244           (match_operand:IEEE128 1 "register_operand" "wa"))))
8245    (clobber (match_scratch:V16QI 2 "=v"))]
8246   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW
8247    && FLOAT128_IEEE_P (<MODE>mode)"
8248   "#"
8249   "&& 1"
8250   [(parallel [(set (match_dup 0)
8251                    (neg:IEEE128 (abs:IEEE128 (match_dup 1))))
8252               (use (match_dup 2))])]
8254   if (GET_CODE (operands[2]) == SCRATCH)
8255     operands[2] = gen_reg_rtx (V16QImode);
8257   operands[3] = gen_reg_rtx (V16QImode);
8258   emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8260   [(set_attr "length" "8")
8261    (set_attr "type" "vecsimple")])
8263 (define_insn "*ieee_128bit_vsx_nabs<mode>2_internal"
8264   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8265         (neg:IEEE128
8266          (abs:IEEE128
8267           (match_operand:IEEE128 1 "register_operand" "wa"))))
8268    (use (match_operand:V16QI 2 "register_operand" "v"))]
8269   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8270   "xxlor %x0,%x1,%x2"
8271   [(set_attr "type" "veclogical")])
8273 ;; Float128 conversion functions.  These expand to library function calls.
8274 ;; We use expand to convert from IBM double double to IEEE 128-bit
8275 ;; and trunc for the opposite.
8276 (define_expand "extendiftf2"
8277   [(set (match_operand:TF 0 "gpc_reg_operand")
8278         (float_extend:TF (match_operand:IF 1 "gpc_reg_operand")))]
8279   "TARGET_FLOAT128_TYPE"
8281   rs6000_expand_float128_convert (operands[0], operands[1], false);
8282   DONE;
8285 (define_expand "extendifkf2"
8286   [(set (match_operand:KF 0 "gpc_reg_operand")
8287         (float_extend:KF (match_operand:IF 1 "gpc_reg_operand")))]
8288   "TARGET_FLOAT128_TYPE"
8290   rs6000_expand_float128_convert (operands[0], operands[1], false);
8291   DONE;
8294 (define_expand "extendtfkf2"
8295   [(set (match_operand:KF 0 "gpc_reg_operand")
8296         (float_extend:KF (match_operand:TF 1 "gpc_reg_operand")))]
8297   "TARGET_FLOAT128_TYPE"
8299   rs6000_expand_float128_convert (operands[0], operands[1], false);
8300   DONE;
8303 (define_expand "extendtfif2"
8304   [(set (match_operand:IF 0 "gpc_reg_operand")
8305         (float_extend:IF (match_operand:TF 1 "gpc_reg_operand")))]
8306   "TARGET_FLOAT128_TYPE"
8308   rs6000_expand_float128_convert (operands[0], operands[1], false);
8309   DONE;
8312 (define_expand "trunciftf2"
8313   [(set (match_operand:TF 0 "gpc_reg_operand")
8314         (float_truncate:TF (match_operand:IF 1 "gpc_reg_operand")))]
8315   "TARGET_FLOAT128_TYPE"
8317   rs6000_expand_float128_convert (operands[0], operands[1], false);
8318   DONE;
8321 (define_expand "truncifkf2"
8322   [(set (match_operand:KF 0 "gpc_reg_operand")
8323         (float_truncate:KF (match_operand:IF 1 "gpc_reg_operand")))]
8324   "TARGET_FLOAT128_TYPE"
8326   rs6000_expand_float128_convert (operands[0], operands[1], false);
8327   DONE;
8330 (define_expand "trunckftf2"
8331   [(set (match_operand:TF 0 "gpc_reg_operand")
8332         (float_truncate:TF (match_operand:KF 1 "gpc_reg_operand")))]
8333   "TARGET_FLOAT128_TYPE"
8335   rs6000_expand_float128_convert (operands[0], operands[1], false);
8336   DONE;
8339 (define_expand "trunctfif2"
8340   [(set (match_operand:IF 0 "gpc_reg_operand")
8341         (float_truncate:IF (match_operand:TF 1 "gpc_reg_operand")))]
8342   "TARGET_FLOAT128_TYPE"
8344   rs6000_expand_float128_convert (operands[0], operands[1], false);
8345   DONE;
8348 (define_insn_and_split "*extend<mode>tf2_internal"
8349   [(set (match_operand:TF 0 "gpc_reg_operand" "=<IFKF_reg>")
8350         (float_extend:TF
8351          (match_operand:IFKF 1 "gpc_reg_operand" "<IFKF_reg>")))]
8352    "TARGET_FLOAT128_TYPE
8353     && FLOAT128_IBM_P (TFmode) == FLOAT128_IBM_P (<MODE>mode)"
8354   "#"
8355   "&& reload_completed"
8356   [(set (match_dup 0) (match_dup 2))]
8358   operands[2] = gen_rtx_REG (TFmode, REGNO (operands[1]));
8361 (define_insn_and_split "*extendtf<mode>2_internal"
8362   [(set (match_operand:IFKF 0 "gpc_reg_operand" "=<IFKF_reg>")
8363         (float_extend:IFKF
8364          (match_operand:TF 1 "gpc_reg_operand" "<IFKF_reg>")))]
8365    "TARGET_FLOAT128_TYPE
8366     && FLOAT128_IBM_P (TFmode) == FLOAT128_IBM_P (<MODE>mode)"
8367   "#"
8368   "&& reload_completed"
8369   [(set (match_dup 0) (match_dup 2))]
8371   operands[2] = gen_rtx_REG (<MODE>mode, REGNO (operands[1]));
8375 ;; Reload helper functions used by rs6000_secondary_reload.  The patterns all
8376 ;; must have 3 arguments, and scratch register constraint must be a single
8377 ;; constraint.
8379 ;; Reload patterns to support gpr load/store with misaligned mem.
8380 ;; and multiple gpr load/store at offset >= 0xfffc
8381 (define_expand "reload_<mode>_store"
8382   [(parallel [(match_operand 0 "memory_operand" "=m")
8383               (match_operand 1 "gpc_reg_operand" "r")
8384               (match_operand:GPR 2 "register_operand" "=&b")])]
8385   ""
8387   rs6000_secondary_reload_gpr (operands[1], operands[0], operands[2], true);
8388   DONE;
8391 (define_expand "reload_<mode>_load"
8392   [(parallel [(match_operand 0 "gpc_reg_operand" "=r")
8393               (match_operand 1 "memory_operand" "m")
8394               (match_operand:GPR 2 "register_operand" "=b")])]
8395   ""
8397   rs6000_secondary_reload_gpr (operands[0], operands[1], operands[2], false);
8398   DONE;
8402 ;; Reload patterns for various types using the vector registers.  We may need
8403 ;; an additional base register to convert the reg+offset addressing to reg+reg
8404 ;; for vector registers and reg+reg or (reg+reg)&(-16) addressing to just an
8405 ;; index register for gpr registers.
8406 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_store"
8407   [(parallel [(match_operand:RELOAD 0 "memory_operand" "m")
8408               (match_operand:RELOAD 1 "gpc_reg_operand" "wa")
8409               (match_operand:P 2 "register_operand" "=b")])]
8410   "<P:tptrsize>"
8412   rs6000_secondary_reload_inner (operands[1], operands[0], operands[2], true);
8413   DONE;
8416 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_load"
8417   [(parallel [(match_operand:RELOAD 0 "gpc_reg_operand" "wa")
8418               (match_operand:RELOAD 1 "memory_operand" "m")
8419               (match_operand:P 2 "register_operand" "=b")])]
8420   "<P:tptrsize>"
8422   rs6000_secondary_reload_inner (operands[0], operands[1], operands[2], false);
8423   DONE;
8427 ;; Reload sometimes tries to move the address to a GPR, and can generate
8428 ;; invalid RTL for addresses involving AND -16.  Allow addresses involving
8429 ;; reg+reg, reg+small constant, or just reg, all wrapped in an AND -16.
8431 (define_insn_and_split "*vec_reload_and_plus_<mptrsize>"
8432   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
8433         (and:P (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
8434                        (match_operand:P 2 "reg_or_cint_operand" "rI"))
8435                (const_int -16)))]
8436   "TARGET_ALTIVEC && reload_completed"
8437   "#"
8438   "&& reload_completed"
8439   [(set (match_dup 0)
8440         (plus:P (match_dup 1)
8441                 (match_dup 2)))
8442    (set (match_dup 0)
8443         (and:P (match_dup 0)
8444                (const_int -16)))])
8446 ;; Power8 merge instructions to allow direct move to/from floating point
8447 ;; registers in 32-bit mode.  We use TF mode to get two registers to move the
8448 ;; individual 32-bit parts across.  Subreg doesn't work too well on the TF
8449 ;; value, since it is allocated in reload and not all of the flow information
8450 ;; is setup for it.  We have two patterns to do the two moves between gprs and
8451 ;; fprs.  There isn't a dependancy between the two, but we could potentially
8452 ;; schedule other instructions between the two instructions.
8454 (define_insn "p8_fmrgow_<mode>"
8455   [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
8456         (unspec:FMOVE64X [
8457                 (match_operand:DF 1 "register_operand" "d")
8458                 (match_operand:DF 2 "register_operand" "d")]
8459                          UNSPEC_P8V_FMRGOW))]
8460   "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8461   "fmrgow %0,%1,%2"
8462   [(set_attr "type" "fpsimple")])
8464 (define_insn "p8_mtvsrwz"
8465   [(set (match_operand:DF 0 "register_operand" "=d")
8466         (unspec:DF [(match_operand:SI 1 "register_operand" "r")]
8467                    UNSPEC_P8V_MTVSRWZ))]
8468   "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8469   "mtvsrwz %x0,%1"
8470   [(set_attr "type" "mftgpr")])
8472 (define_insn_and_split "reload_fpr_from_gpr<mode>"
8473   [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
8474         (unspec:FMOVE64X [(match_operand:FMOVE64X 1 "register_operand" "r")]
8475                          UNSPEC_P8V_RELOAD_FROM_GPR))
8476    (clobber (match_operand:IF 2 "register_operand" "=d"))]
8477   "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8478   "#"
8479   "&& reload_completed"
8480   [(const_int 0)]
8482   rtx dest = operands[0];
8483   rtx src = operands[1];
8484   rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0);
8485   rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8);
8486   rtx gpr_hi_reg = gen_highpart (SImode, src);
8487   rtx gpr_lo_reg = gen_lowpart (SImode, src);
8489   emit_insn (gen_p8_mtvsrwz (tmp_hi, gpr_hi_reg));
8490   emit_insn (gen_p8_mtvsrwz (tmp_lo, gpr_lo_reg));
8491   emit_insn (gen_p8_fmrgow_<mode> (dest, tmp_hi, tmp_lo));
8492   DONE;
8494   [(set_attr "length" "12")
8495    (set_attr "type" "three")])
8497 ;; Move 128 bit values from GPRs to VSX registers in 64-bit mode
8498 (define_insn "p8_mtvsrd_df"
8499   [(set (match_operand:DF 0 "register_operand" "=wa")
8500         (unspec:DF [(match_operand:DI 1 "register_operand" "r")]
8501                    UNSPEC_P8V_MTVSRD))]
8502   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8503   "mtvsrd %x0,%1"
8504   [(set_attr "type" "mftgpr")])
8506 (define_insn "p8_xxpermdi_<mode>"
8507   [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
8508         (unspec:FMOVE128_GPR [
8509                 (match_operand:DF 1 "register_operand" "wa")
8510                 (match_operand:DF 2 "register_operand" "wa")]
8511                 UNSPEC_P8V_XXPERMDI))]
8512   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8513   "xxpermdi %x0,%x1,%x2,0"
8514   [(set_attr "type" "vecperm")])
8516 (define_insn_and_split "reload_vsx_from_gpr<mode>"
8517   [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
8518         (unspec:FMOVE128_GPR
8519          [(match_operand:FMOVE128_GPR 1 "register_operand" "r")]
8520          UNSPEC_P8V_RELOAD_FROM_GPR))
8521    (clobber (match_operand:IF 2 "register_operand" "=wa"))]
8522   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8523   "#"
8524   "&& reload_completed"
8525   [(const_int 0)]
8527   rtx dest = operands[0];
8528   rtx src = operands[1];
8529   /* You might think that we could use op0 as one temp and a DF clobber
8530      as op2, but you'd be wrong.  Secondary reload move patterns don't
8531      check for overlap of the clobber and the destination.  */
8532   rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0);
8533   rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8);
8534   rtx gpr_hi_reg = gen_highpart (DImode, src);
8535   rtx gpr_lo_reg = gen_lowpart (DImode, src);
8537   emit_insn (gen_p8_mtvsrd_df (tmp_hi, gpr_hi_reg));
8538   emit_insn (gen_p8_mtvsrd_df (tmp_lo, gpr_lo_reg));
8539   emit_insn (gen_p8_xxpermdi_<mode> (dest, tmp_hi, tmp_lo));
8540   DONE;
8542   [(set_attr "length" "12")
8543    (set_attr "type" "three")])
8545 (define_split
8546   [(set (match_operand:FMOVE128_GPR 0 "nonimmediate_operand")
8547         (match_operand:FMOVE128_GPR 1 "input_operand"))]
8548   "reload_completed
8549    && (int_reg_operand (operands[0], <MODE>mode)
8550        || int_reg_operand (operands[1], <MODE>mode))
8551    && (!TARGET_DIRECT_MOVE_128
8552        || (!vsx_register_operand (operands[0], <MODE>mode)
8553            && !vsx_register_operand (operands[1], <MODE>mode)))"
8554   [(pc)]
8555 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
8557 ;; Move SFmode to a VSX from a GPR register.  Because scalar floating point
8558 ;; type is stored internally as double precision in the VSX registers, we have
8559 ;; to convert it from the vector format.
8560 (define_insn "p8_mtvsrd_sf"
8561   [(set (match_operand:SF 0 "register_operand" "=wa")
8562         (unspec:SF [(match_operand:DI 1 "register_operand" "r")]
8563                    UNSPEC_P8V_MTVSRD))]
8564   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8565   "mtvsrd %x0,%1"
8566   [(set_attr "type" "mftgpr")])
8568 (define_insn_and_split "reload_vsx_from_gprsf"
8569   [(set (match_operand:SF 0 "register_operand" "=wa")
8570         (unspec:SF [(match_operand:SF 1 "register_operand" "r")]
8571                    UNSPEC_P8V_RELOAD_FROM_GPR))
8572    (clobber (match_operand:DI 2 "register_operand" "=r"))]
8573   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8574   "#"
8575   "&& reload_completed"
8576   [(const_int 0)]
8578   rtx op0 = operands[0];
8579   rtx op1 = operands[1];
8580   rtx op2 = operands[2];
8581   rtx op1_di = simplify_gen_subreg (DImode, op1, SFmode, 0);
8583   /* Move SF value to upper 32-bits for xscvspdpn.  */
8584   emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32)));
8585   emit_insn (gen_p8_mtvsrd_sf (op0, op2));
8586   emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0));
8587   DONE;
8589   [(set_attr "length" "8")
8590    (set_attr "type" "two")])
8592 ;; Move 128 bit values from VSX registers to GPRs in 64-bit mode by doing a
8593 ;; normal 64-bit move, followed by an xxpermdi to get the bottom 64-bit value,
8594 ;; and then doing a move of that.
8595 (define_insn "p8_mfvsrd_3_<mode>"
8596   [(set (match_operand:DF 0 "register_operand" "=r")
8597         (unspec:DF [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
8598                    UNSPEC_P8V_RELOAD_FROM_VSX))]
8599   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8600   "mfvsrd %0,%x1"
8601   [(set_attr "type" "mftgpr")])
8603 (define_insn_and_split "reload_gpr_from_vsx<mode>"
8604   [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=r")
8605         (unspec:FMOVE128_GPR
8606          [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
8607          UNSPEC_P8V_RELOAD_FROM_VSX))
8608    (clobber (match_operand:FMOVE128_GPR 2 "register_operand" "=wa"))]
8609   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8610   "#"
8611   "&& reload_completed"
8612   [(const_int 0)]
8614   rtx dest = operands[0];
8615   rtx src = operands[1];
8616   rtx tmp = operands[2];
8617   rtx gpr_hi_reg = gen_highpart (DFmode, dest);
8618   rtx gpr_lo_reg = gen_lowpart (DFmode, dest);
8620   emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_hi_reg, src));
8621   emit_insn (gen_vsx_xxpermdi_<mode>_be (tmp, src, src, GEN_INT (3)));
8622   emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_lo_reg, tmp));
8623   DONE;
8625   [(set_attr "length" "12")
8626    (set_attr "type" "three")])
8628 ;; Move SFmode to a GPR from a VSX register.  Because scalar floating point
8629 ;; type is stored internally as double precision, we have to convert it to the
8630 ;; vector format.
8632 (define_insn_and_split "reload_gpr_from_vsxsf"
8633   [(set (match_operand:SF 0 "register_operand" "=r")
8634         (unspec:SF [(match_operand:SF 1 "register_operand" "wa")]
8635                    UNSPEC_P8V_RELOAD_FROM_VSX))
8636    (clobber (match_operand:V4SF 2 "register_operand" "=wa"))]
8637   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8638   "#"
8639   "&& reload_completed"
8640   [(const_int 0)]
8642   rtx op0 = operands[0];
8643   rtx op1 = operands[1];
8644   rtx op2 = operands[2];
8645   rtx op0_di = gen_rtx_REG (DImode, reg_or_subregno (op0));
8646   rtx op2_si = gen_rtx_REG (SImode, reg_or_subregno (op2));
8648   emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
8649   emit_insn (gen_zero_extendsidi2 (op0_di, op2_si));
8650   DONE;
8652   [(set_attr "length" "8")
8653    (set_attr "type" "two")
8654    (set_attr "isa" "p8v")])
8656 ;; Next come the multi-word integer load and store and the load and store
8657 ;; multiple insns.
8659 ;; List r->r after r->Y, otherwise reload will try to reload a
8660 ;; non-offsettable address by using r->r which won't make progress.
8661 ;; Use of fprs is disparaged slightly otherwise reload prefers to reload
8662 ;; a gpr into a fpr instead of reloading an invalid 'Y' address
8664 ;;        GPR store  GPR load   GPR move   FPR store  FPR load   FPR move
8665 ;;        GPR const  AVX store  AVX store  AVX load   AVX load   VSX move
8666 ;;        P9 0       P9 -1      AVX 0/-1   VSX 0      VSX -1     P9 const
8667 ;;        AVX const  
8669 (define_insn "*movdi_internal32"
8670   [(set (match_operand:DI 0 "nonimmediate_operand"
8671          "=Y,        r,         r,         m,         ^d,        ^d,
8672           r,         wY,        Z,         ^v,        $v,        ^wa,
8673           wa,        wa,        v,         wa,        *i,        v,
8674           v")
8675         (match_operand:DI 1 "input_operand"
8676          "r,         Y,         r,         ^d,        m,         ^d,
8677           IJKnF,     ^v,        $v,        wY,        Z,         ^wa,
8678           Oj,        wM,        OjwM,      Oj,        wM,        wS,
8679           wB"))]
8680   "! TARGET_POWERPC64
8681    && (gpc_reg_operand (operands[0], DImode)
8682        || gpc_reg_operand (operands[1], DImode))"
8683   "@
8684    #
8685    #
8686    #
8687    stfd%U0%X0 %1,%0
8688    lfd%U1%X1 %0,%1
8689    fmr %0,%1
8690    #
8691    stxsd %1,%0
8692    stxsdx %x1,%y0
8693    lxsd %0,%1
8694    lxsdx %x0,%y1
8695    xxlor %x0,%x1,%x1
8696    xxspltib %x0,0
8697    xxspltib %x0,255
8698    vspltisw %0,%1
8699    xxlxor %x0,%x0,%x0
8700    xxlorc %x0,%x0,%x0
8701    #
8702    #"
8703   [(set_attr "type"
8704          "store,     load,      *,         fpstore,   fpload,    fpsimple,
8705           *,         fpstore,   fpstore,   fpload,    fpload,    veclogical,
8706           vecsimple, vecsimple, vecsimple, veclogical,veclogical,vecsimple,
8707           vecsimple")
8708    (set_attr "size" "64")
8709    (set_attr "length"
8710          "8,         8,         8,         *,         *,         *,
8711           16,        *,         *,         *,         *,         *,
8712           *,         *,         *,         *,         *,         8,
8713           *")
8714    (set_attr "isa"
8715          "*,         *,         *,         *,         *,         *,
8716           *,         p9v,       p7v,       p9v,       p7v,       *,
8717           p9v,       p9v,       p7v,       *,         *,         p7v,
8718           p7v")])
8720 (define_split
8721   [(set (match_operand:DI 0 "gpc_reg_operand")
8722         (match_operand:DI 1 "const_int_operand"))]
8723   "! TARGET_POWERPC64 && reload_completed
8724    && gpr_or_gpr_p (operands[0], operands[1])
8725    && !direct_move_p (operands[0], operands[1])"
8726   [(set (match_dup 2) (match_dup 4))
8727    (set (match_dup 3) (match_dup 1))]
8729   HOST_WIDE_INT value = INTVAL (operands[1]);
8730   operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
8731                                        DImode);
8732   operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
8733                                        DImode);
8734   operands[4] = GEN_INT (value >> 32);
8735   operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
8738 (define_split
8739   [(set (match_operand:DIFD 0 "nonimmediate_operand")
8740         (match_operand:DIFD 1 "input_operand"))]
8741   "reload_completed && !TARGET_POWERPC64
8742    && gpr_or_gpr_p (operands[0], operands[1])
8743    && !direct_move_p (operands[0], operands[1])"
8744   [(pc)]
8745 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
8747 ;;              GPR store  GPR load   GPR move   GPR li     GPR lis     GPR #
8748 ;;              FPR store  FPR load   FPR move   AVX store  AVX store   AVX load
8749 ;;              AVX load   VSX move   P9 0       P9 -1      AVX 0/-1    VSX 0
8750 ;;              VSX -1     P9 const   AVX const  From SPR   To SPR      SPR<->SPR
8751 ;;              VSX->GPR   GPR->VSX
8752 (define_insn "*movdi_internal64"
8753   [(set (match_operand:DI 0 "nonimmediate_operand"
8754                "=YZ,       r,         r,         r,         r,          r,
8755                 m,         ^d,        ^d,        wY,        Z,          $v,
8756                 $v,        ^wa,       wa,        wa,        v,          wa,
8757                 wa,        v,         v,         r,         *h,         *h,
8758                 ?r,        ?wa")
8759         (match_operand:DI 1 "input_operand"
8760                "r,         YZ,        r,         I,         L,          nF,
8761                 ^d,        m,         ^d,        ^v,        $v,         wY,
8762                 Z,         ^wa,       Oj,        wM,        OjwM,       Oj,
8763                 wM,        wS,        wB,        *h,        r,          0,
8764                 wa,        r"))]
8765   "TARGET_POWERPC64
8766    && (gpc_reg_operand (operands[0], DImode)
8767        || gpc_reg_operand (operands[1], DImode))"
8768   "@
8769    std%U0%X0 %1,%0
8770    ld%U1%X1 %0,%1
8771    mr %0,%1
8772    li %0,%1
8773    lis %0,%v1
8774    #
8775    stfd%U0%X0 %1,%0
8776    lfd%U1%X1 %0,%1
8777    fmr %0,%1
8778    stxsd %1,%0
8779    stxsdx %x1,%y0
8780    lxsd %0,%1
8781    lxsdx %x0,%y1
8782    xxlor %x0,%x1,%x1
8783    xxspltib %x0,0
8784    xxspltib %x0,255
8785    #
8786    xxlxor %x0,%x0,%x0
8787    xxlorc %x0,%x0,%x0
8788    #
8789    #
8790    mf%1 %0
8791    mt%0 %1
8792    nop
8793    mfvsrd %0,%x1
8794    mtvsrd %x0,%1"
8795   [(set_attr "type"
8796                "store,      load,       *,         *,         *,         *,
8797                 fpstore,    fpload,     fpsimple,  fpstore,   fpstore,   fpload,
8798                 fpload,     veclogical, vecsimple, vecsimple, vecsimple, veclogical,
8799                 veclogical, vecsimple,  vecsimple, mfjmpr,    mtjmpr,    *,
8800                 mftgpr,    mffgpr")
8801    (set_attr "size" "64")
8802    (set_attr "length"
8803                "*,         *,         *,         *,         *,          20,
8804                 *,         *,         *,         *,         *,          *,
8805                 *,         *,         *,         *,         *,          *,
8806                 *,         8,         *,         *,         *,          *,
8807                 *,         *")
8808    (set_attr "isa"
8809                "*,         *,         *,         *,         *,          *,
8810                 *,         *,         *,         p9v,       p7v,        p9v,
8811                 p7v,       *,         p9v,       p9v,       p7v,        *,
8812                 *,         p7v,       p7v,       *,         *,          *,
8813                 p8v,       p8v")])
8815 ; Some DImode loads are best done as a load of -1 followed by a mask
8816 ; instruction.
8817 (define_split
8818   [(set (match_operand:DI 0 "int_reg_operand_not_pseudo")
8819         (match_operand:DI 1 "const_int_operand"))]
8820   "TARGET_POWERPC64
8821    && num_insns_constant (operands[1], DImode) > 1
8822    && !IN_RANGE (INTVAL (operands[1]), -0x80000000, 0xffffffff)
8823    && rs6000_is_valid_and_mask (operands[1], DImode)"
8824   [(set (match_dup 0)
8825         (const_int -1))
8826    (set (match_dup 0)
8827         (and:DI (match_dup 0)
8828                 (match_dup 1)))]
8829   "")
8831 ;; Split a load of a large constant into the appropriate five-instruction
8832 ;; sequence.  Handle anything in a constant number of insns.
8833 ;; When non-easy constants can go in the TOC, this should use
8834 ;; easy_fp_constant predicate.
8835 (define_split
8836   [(set (match_operand:DI 0 "int_reg_operand_not_pseudo")
8837         (match_operand:DI 1 "const_int_operand"))]
8838   "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
8839   [(set (match_dup 0) (match_dup 2))
8840    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
8842   if (rs6000_emit_set_const (operands[0], operands[1]))
8843     DONE;
8844   else
8845     FAIL;
8848 (define_split
8849   [(set (match_operand:DI 0 "int_reg_operand_not_pseudo")
8850         (match_operand:DI 1 "const_scalar_int_operand"))]
8851   "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
8852   [(set (match_dup 0) (match_dup 2))
8853    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
8855   if (rs6000_emit_set_const (operands[0], operands[1]))
8856     DONE;
8857   else
8858     FAIL;
8861 (define_split
8862   [(set (match_operand:DI 0 "altivec_register_operand")
8863         (match_operand:DI 1 "s5bit_cint_operand"))]
8864   "TARGET_VSX && reload_completed"
8865   [(const_int 0)]
8867   rtx op0 = operands[0];
8868   rtx op1 = operands[1];
8869   int r = REGNO (op0);
8870   rtx op0_v4si = gen_rtx_REG (V4SImode, r);
8872   emit_insn (gen_altivec_vspltisw (op0_v4si, op1));
8873   if (op1 != const0_rtx && op1 != constm1_rtx)
8874     {
8875       rtx op0_v2di = gen_rtx_REG (V2DImode, r);
8876       emit_insn (gen_altivec_vupkhsw (op0_v2di, op0_v4si));
8877     }
8878   DONE;
8881 ;; Split integer constants that can be loaded with XXSPLTIB and a
8882 ;; sign extend operation.
8883 (define_split
8884   [(set (match_operand:INT_ISA3 0 "altivec_register_operand")
8885         (match_operand:INT_ISA3 1 "xxspltib_constant_split"))]
8886   "TARGET_P9_VECTOR && reload_completed"
8887   [(const_int 0)]
8889   rtx op0 = operands[0];
8890   rtx op1 = operands[1];
8891   int r = REGNO (op0);
8892   rtx op0_v16qi = gen_rtx_REG (V16QImode, r);
8894   emit_insn (gen_xxspltib_v16qi (op0_v16qi, op1));
8895   if (<MODE>mode == DImode)
8896     emit_insn (gen_vsx_sign_extend_qi_di (operands[0], op0_v16qi));
8897   else if (<MODE>mode == SImode)
8898     emit_insn (gen_vsx_sign_extend_qi_si (operands[0], op0_v16qi));
8899   else if (<MODE>mode == HImode)
8900     {
8901       rtx op0_v8hi = gen_rtx_REG (V8HImode, r);
8902       emit_insn (gen_altivec_vupkhsb (op0_v8hi, op0_v16qi));
8903     }
8904   DONE;
8908 ;; TImode/PTImode is similar, except that we usually want to compute the
8909 ;; address into a register and use lsi/stsi (the exception is during reload).
8911 (define_insn "*mov<mode>_string"
8912   [(set (match_operand:TI2 0 "reg_or_mem_operand" "=Q,Y,????r,????r,????r,r")
8913         (match_operand:TI2 1 "input_operand" "r,r,Q,Y,r,n"))]
8914   "! TARGET_POWERPC64
8915    && (<MODE>mode != TImode || VECTOR_MEM_NONE_P (TImode))
8916    && (gpc_reg_operand (operands[0], <MODE>mode)
8917        || gpc_reg_operand (operands[1], <MODE>mode))"
8918   "#"
8919   [(set_attr "type" "store,store,load,load,*,*")
8920    (set_attr "update" "yes")
8921    (set_attr "indexed" "yes")
8922    (set_attr "cell_micro" "conditional")])
8924 (define_insn "*mov<mode>_ppc64"
8925   [(set (match_operand:TI2 0 "nonimmediate_operand" "=wQ,Y,r,r,r,r")
8926         (match_operand:TI2 1 "input_operand" "r,r,wQ,Y,r,n"))]
8927   "(TARGET_POWERPC64 && VECTOR_MEM_NONE_P (<MODE>mode)
8928    && (gpc_reg_operand (operands[0], <MODE>mode)
8929        || gpc_reg_operand (operands[1], <MODE>mode)))"
8931   return rs6000_output_move_128bit (operands);
8933   [(set_attr "type" "store,store,load,load,*,*")
8934    (set_attr "length" "8")])
8936 (define_split
8937   [(set (match_operand:TI2 0 "int_reg_operand")
8938         (match_operand:TI2 1 "const_scalar_int_operand"))]
8939   "TARGET_POWERPC64
8940    && (VECTOR_MEM_NONE_P (<MODE>mode)
8941        || (reload_completed && INT_REGNO_P (REGNO (operands[0]))))"
8942   [(set (match_dup 2) (match_dup 4))
8943    (set (match_dup 3) (match_dup 5))]
8945   operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
8946                                        <MODE>mode);
8947   operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
8948                                        <MODE>mode);
8949   if (CONST_WIDE_INT_P (operands[1]))
8950     {
8951       operands[4] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 1));
8952       operands[5] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 0));
8953     }
8954   else if (CONST_INT_P (operands[1]))
8955     {
8956       operands[4] = GEN_INT (- (INTVAL (operands[1]) < 0));
8957       operands[5] = operands[1];
8958     }
8959   else
8960     FAIL;
8963 (define_split
8964   [(set (match_operand:TI2 0 "nonimmediate_operand")
8965         (match_operand:TI2 1 "input_operand"))]
8966   "reload_completed
8967    && gpr_or_gpr_p (operands[0], operands[1])
8968    && !direct_move_p (operands[0], operands[1])
8969    && !quad_load_store_p (operands[0], operands[1])"
8970   [(pc)]
8971 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
8973 (define_expand "setmemsi"
8974   [(parallel [(set (match_operand:BLK 0 "")
8975                    (match_operand 2 "const_int_operand"))
8976               (use (match_operand:SI 1 ""))
8977               (use (match_operand:SI 3 ""))])]
8978   ""
8980   /* If value to set is not zero, use the library routine.  */
8981   if (operands[2] != const0_rtx)
8982     FAIL;
8984   if (expand_block_clear (operands))
8985     DONE;
8986   else
8987     FAIL;
8990 ;; String compare N insn.
8991 ;; Argument 0 is the target (result)
8992 ;; Argument 1 is the destination
8993 ;; Argument 2 is the source
8994 ;; Argument 3 is the length
8995 ;; Argument 4 is the alignment
8997 (define_expand "cmpstrnsi"
8998   [(parallel [(set (match_operand:SI 0)
8999                (compare:SI (match_operand:BLK 1)
9000                            (match_operand:BLK 2)))
9001               (use (match_operand:SI 3))
9002               (use (match_operand:SI 4))])]
9003   "TARGET_CMPB && (BYTES_BIG_ENDIAN || TARGET_LDBRX)"
9005   if (optimize_insn_for_size_p ())
9006     FAIL;
9008   if (expand_strn_compare (operands, 0))
9009     DONE;
9010   else  
9011     FAIL;
9014 ;; String compare insn.
9015 ;; Argument 0 is the target (result)
9016 ;; Argument 1 is the destination
9017 ;; Argument 2 is the source
9018 ;; Argument 3 is the alignment
9020 (define_expand "cmpstrsi"
9021   [(parallel [(set (match_operand:SI 0)
9022                (compare:SI (match_operand:BLK 1)
9023                            (match_operand:BLK 2)))
9024               (use (match_operand:SI 3))])]
9025   "TARGET_CMPB && (BYTES_BIG_ENDIAN || TARGET_LDBRX)"
9027   if (optimize_insn_for_size_p ())
9028     FAIL;
9030   if (expand_strn_compare (operands, 1))
9031     DONE;
9032   else  
9033     FAIL;
9036 ;; Block compare insn.
9037 ;; Argument 0 is the target (result)
9038 ;; Argument 1 is the destination
9039 ;; Argument 2 is the source
9040 ;; Argument 3 is the length
9041 ;; Argument 4 is the alignment
9043 (define_expand "cmpmemsi"
9044   [(parallel [(set (match_operand:SI 0)
9045                (compare:SI (match_operand:BLK 1)
9046                            (match_operand:BLK 2)))
9047               (use (match_operand:SI 3))
9048               (use (match_operand:SI 4))])]
9049   "TARGET_POPCNTD"
9051   if (expand_block_compare (operands))
9052     DONE;
9053   else
9054     FAIL;
9057 ;; String/block move insn.
9058 ;; Argument 0 is the destination
9059 ;; Argument 1 is the source
9060 ;; Argument 2 is the length
9061 ;; Argument 3 is the alignment
9063 (define_expand "cpymemsi"
9064   [(parallel [(set (match_operand:BLK 0 "")
9065                    (match_operand:BLK 1 ""))
9066               (use (match_operand:SI 2 ""))
9067               (use (match_operand:SI 3 ""))])]
9068   ""
9070   if (expand_block_move (operands))
9071     DONE;
9072   else
9073     FAIL;
9076 ;; Define insns that do load or store with update.  Some of these we can
9077 ;; get by using pre-decrement or pre-increment, but the hardware can also
9078 ;; do cases where the increment is not the size of the object.
9080 ;; In all these cases, we use operands 0 and 1 for the register being
9081 ;; incremented because those are the operands that local-alloc will
9082 ;; tie and these are the pair most likely to be tieable (and the ones
9083 ;; that will benefit the most).
9085 (define_insn "*movdi_update1"
9086   [(set (match_operand:DI 3 "gpc_reg_operand" "=r,r")
9087         (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9088                         (match_operand:P 2 "reg_or_aligned_short_operand" "r,I"))))
9089    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9090         (plus:P (match_dup 1) (match_dup 2)))]
9091   "TARGET_POWERPC64 && TARGET_UPDATE
9092    && (!avoiding_indexed_address_p (DImode)
9093        || !gpc_reg_operand (operands[2], Pmode))"
9094   "@
9095    ldux %3,%0,%2
9096    ldu %3,%2(%0)"
9097   [(set_attr "type" "load")
9098    (set_attr "update" "yes")
9099    (set_attr "indexed" "yes,no")])
9101 (define_insn "movdi_<mode>_update"
9102   [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9103                         (match_operand:P 2 "reg_or_aligned_short_operand" "r,I")))
9104         (match_operand:DI 3 "gpc_reg_operand" "r,r"))
9105    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9106         (plus:P (match_dup 1) (match_dup 2)))]
9107   "TARGET_POWERPC64 && TARGET_UPDATE
9108    && (!avoiding_indexed_address_p (DImode)
9109        || !gpc_reg_operand (operands[2], Pmode)
9110        || (REG_P (operands[0])
9111            && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
9112   "@
9113    stdux %3,%0,%2
9114    stdu %3,%2(%0)"
9115   [(set_attr "type" "store")
9116    (set_attr "update" "yes")
9117    (set_attr "indexed" "yes,no")])
9119 ;; This pattern is only conditional on TARGET_64BIT, as it is
9120 ;; needed for stack allocation, even if the user passes -mno-update.
9121 (define_insn "movdi_update_stack"
9122   [(set (mem:DI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0,0")
9123                          (match_operand:DI 2 "reg_or_aligned_short_operand" "r,I")))
9124         (match_operand:DI 3 "gpc_reg_operand" "r,r"))
9125    (set (match_operand:DI 0 "gpc_reg_operand" "=b,b")
9126         (plus:DI (match_dup 1) (match_dup 2)))]
9127   "TARGET_64BIT"
9128   "@
9129    stdux %3,%0,%2
9130    stdu %3,%2(%0)"
9131   [(set_attr "type" "store")
9132    (set_attr "update" "yes")
9133    (set_attr "indexed" "yes,no")])
9135 (define_insn "*movsi_update1"
9136   [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9137         (mem:SI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9138                         (match_operand:P 2 "reg_or_short_operand" "r,I"))))
9139    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9140         (plus:P (match_dup 1) (match_dup 2)))]
9141   "TARGET_UPDATE
9142    && (!avoiding_indexed_address_p (SImode)
9143        || !gpc_reg_operand (operands[2], Pmode))"
9144   "@
9145    lwzux %3,%0,%2
9146    lwzu %3,%2(%0)"
9147   [(set_attr "type" "load")
9148    (set_attr "update" "yes")
9149    (set_attr "indexed" "yes,no")])
9151 (define_insn "*movsi_update2"
9152   [(set (match_operand:EXTSI 3 "gpc_reg_operand" "=r")
9153         (sign_extend:EXTSI
9154          (mem:SI (plus:P (match_operand:P 1 "gpc_reg_operand" "0")
9155                          (match_operand:P 2 "gpc_reg_operand" "r")))))
9156    (set (match_operand:P 0 "gpc_reg_operand" "=b")
9157         (plus:P (match_dup 1) (match_dup 2)))]
9158   "TARGET_POWERPC64 && !avoiding_indexed_address_p (DImode)"
9159   "lwaux %3,%0,%2"
9160   [(set_attr "type" "load")
9161    (set_attr "sign_extend" "yes")
9162    (set_attr "update" "yes")
9163    (set_attr "indexed" "yes")])
9165 (define_insn "movsi_<mode>_update"
9166   [(set (mem:SI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9167                         (match_operand:P 2 "reg_or_short_operand" "r,I")))
9168         (match_operand:SI 3 "gpc_reg_operand" "r,r"))
9169    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9170         (plus:P (match_dup 1) (match_dup 2)))]
9171   "TARGET_UPDATE
9172    && (!avoiding_indexed_address_p (SImode)
9173        || !gpc_reg_operand (operands[2], Pmode)
9174        || (REG_P (operands[0])
9175            && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
9176   "@
9177    stwux %3,%0,%2
9178    stwu %3,%2(%0)"
9179   [(set_attr "type" "store")
9180    (set_attr "update" "yes")
9181    (set_attr "indexed" "yes,no")])
9183 ;; This is an unconditional pattern; needed for stack allocation, even
9184 ;; if the user passes -mno-update.
9185 (define_insn "movsi_update_stack"
9186   [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9187                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9188         (match_operand:SI 3 "gpc_reg_operand" "r,r"))
9189    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9190         (plus:SI (match_dup 1) (match_dup 2)))]
9191   "TARGET_32BIT"
9192   "@
9193    stwux %3,%0,%2
9194    stwu %3,%2(%0)"
9195   [(set_attr "type" "store")
9196    (set_attr "update" "yes")
9197    (set_attr "indexed" "yes,no")])
9199 (define_insn "*movhi_update1"
9200   [(set (match_operand:HI 3 "gpc_reg_operand" "=r,r")
9201         (mem:HI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9202                         (match_operand:P 2 "reg_or_short_operand" "r,I"))))
9203    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9204         (plus:P (match_dup 1) (match_dup 2)))]
9205   "TARGET_UPDATE
9206    && (!avoiding_indexed_address_p (HImode)
9207        || !gpc_reg_operand (operands[2], SImode))"
9208   "@
9209    lhzux %3,%0,%2
9210    lhzu %3,%2(%0)"
9211   [(set_attr "type" "load")
9212    (set_attr "update" "yes")
9213    (set_attr "indexed" "yes,no")])
9215 (define_insn "*movhi_update2"
9216   [(set (match_operand:EXTHI 3 "gpc_reg_operand" "=r,r")
9217         (zero_extend:EXTHI
9218          (mem:HI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9219                          (match_operand:P 2 "reg_or_short_operand" "r,I")))))
9220    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9221         (plus:P (match_dup 1) (match_dup 2)))]
9222   "TARGET_UPDATE
9223    && (!avoiding_indexed_address_p (HImode)
9224        || !gpc_reg_operand (operands[2], Pmode))"
9225   "@
9226    lhzux %3,%0,%2
9227    lhzu %3,%2(%0)"
9228   [(set_attr "type" "load")
9229    (set_attr "update" "yes")
9230    (set_attr "indexed" "yes,no")])
9232 (define_insn "*movhi_update3"
9233   [(set (match_operand:EXTHI 3 "gpc_reg_operand" "=r,r")
9234         (sign_extend:EXTHI
9235          (mem:HI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9236                          (match_operand:P 2 "reg_or_short_operand" "r,I")))))
9237    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9238         (plus:P (match_dup 1) (match_dup 2)))]
9239   "TARGET_UPDATE
9240    && !(avoiding_indexed_address_p (HImode)
9241         && gpc_reg_operand (operands[2], Pmode))"
9242   "@
9243    lhaux %3,%0,%2
9244    lhau %3,%2(%0)"
9245   [(set_attr "type" "load")
9246    (set_attr "sign_extend" "yes")
9247    (set_attr "update" "yes")
9248    (set_attr "indexed" "yes,no")])
9250 (define_insn "*movhi_update4"
9251   [(set (mem:HI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9252                         (match_operand:P 2 "reg_or_short_operand" "r,I")))
9253         (match_operand:HI 3 "gpc_reg_operand" "r,r"))
9254    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9255         (plus:P (match_dup 1) (match_dup 2)))]
9256   "TARGET_UPDATE
9257    && (!avoiding_indexed_address_p (HImode)
9258        || !gpc_reg_operand (operands[2], Pmode))"
9259   "@
9260    sthux %3,%0,%2
9261    sthu %3,%2(%0)"
9262   [(set_attr "type" "store")
9263    (set_attr "update" "yes")
9264    (set_attr "indexed" "yes,no")])
9266 (define_insn "*movqi_update1"
9267   [(set (match_operand:QI 3 "gpc_reg_operand" "=r,r")
9268         (mem:QI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9269                         (match_operand:P 2 "reg_or_short_operand" "r,I"))))
9270    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9271         (plus:P (match_dup 1) (match_dup 2)))]
9272   "TARGET_UPDATE
9273    && (!avoiding_indexed_address_p (QImode)
9274        || !gpc_reg_operand (operands[2], Pmode))"
9275   "@
9276    lbzux %3,%0,%2
9277    lbzu %3,%2(%0)"
9278   [(set_attr "type" "load")
9279    (set_attr "update" "yes")
9280    (set_attr "indexed" "yes,no")])
9282 (define_insn "*movqi_update2"
9283   [(set (match_operand:EXTQI 3 "gpc_reg_operand" "=r,r")
9284         (zero_extend:EXTQI
9285          (mem:QI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9286                          (match_operand:P 2 "reg_or_short_operand" "r,I")))))
9287    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9288         (plus:P (match_dup 1) (match_dup 2)))]
9289   "TARGET_UPDATE
9290    && (!avoiding_indexed_address_p (QImode)
9291        || !gpc_reg_operand (operands[2], Pmode))"
9292   "@
9293    lbzux %3,%0,%2
9294    lbzu %3,%2(%0)"
9295   [(set_attr "type" "load")
9296    (set_attr "update" "yes")
9297    (set_attr "indexed" "yes,no")])
9299 (define_insn "*movqi_update3"
9300   [(set (mem:QI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9301                         (match_operand:P 2 "reg_or_short_operand" "r,I")))
9302         (match_operand:QI 3 "gpc_reg_operand" "r,r"))
9303    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9304         (plus:P (match_dup 1) (match_dup 2)))]
9305   "TARGET_UPDATE
9306    && (!avoiding_indexed_address_p (QImode)
9307        || !gpc_reg_operand (operands[2], Pmode))"
9308   "@
9309    stbux %3,%0,%2
9310    stbu %3,%2(%0)"
9311   [(set_attr "type" "store")
9312    (set_attr "update" "yes")
9313    (set_attr "indexed" "yes,no")])
9315 (define_insn "*mov<mode>_update1"
9316   [(set (match_operand:SFDF 3 "gpc_reg_operand" "=<Ff>,<Ff>")
9317         (mem:SFDF (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9318                           (match_operand:P 2 "reg_or_short_operand" "r,I"))))
9319    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9320         (plus:P (match_dup 1) (match_dup 2)))]
9321   "TARGET_HARD_FLOAT && TARGET_UPDATE
9322    && (!avoiding_indexed_address_p (<MODE>mode)
9323        || !gpc_reg_operand (operands[2], Pmode))"
9324   "@
9325    lf<sd>ux %3,%0,%2
9326    lf<sd>u %3,%2(%0)"
9327   [(set_attr "type" "fpload")
9328    (set_attr "update" "yes")
9329    (set_attr "indexed" "yes,no")
9330    (set_attr "size" "<bits>")])
9332 (define_insn "*mov<mode>_update2"
9333   [(set (mem:SFDF (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9334                           (match_operand:P 2 "reg_or_short_operand" "r,I")))
9335         (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,<Ff>"))
9336    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9337         (plus:P (match_dup 1) (match_dup 2)))]
9338   "TARGET_HARD_FLOAT && TARGET_UPDATE
9339    && (!avoiding_indexed_address_p (<MODE>mode)
9340        || !gpc_reg_operand (operands[2], Pmode))"
9341   "@
9342    stf<sd>ux %3,%0,%2
9343    stf<sd>u %3,%2(%0)"
9344   [(set_attr "type" "fpstore")
9345    (set_attr "update" "yes")
9346    (set_attr "indexed" "yes,no")
9347    (set_attr "size" "<bits>")])
9349 (define_insn "*movsf_update3"
9350   [(set (match_operand:SF 3 "gpc_reg_operand" "=r,r")
9351         (mem:SF (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9352                         (match_operand:P 2 "reg_or_short_operand" "r,I"))))
9353    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9354         (plus:P (match_dup 1) (match_dup 2)))]
9355   "TARGET_SOFT_FLOAT && TARGET_UPDATE
9356    && (!avoiding_indexed_address_p (SFmode)
9357        || !gpc_reg_operand (operands[2], Pmode))"
9358   "@
9359    lwzux %3,%0,%2
9360    lwzu %3,%2(%0)"
9361   [(set_attr "type" "load")
9362    (set_attr "update" "yes")
9363    (set_attr "indexed" "yes,no")])
9365 (define_insn "*movsf_update4"
9366   [(set (mem:SF (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9367                         (match_operand:P 2 "reg_or_short_operand" "r,I")))
9368         (match_operand:SF 3 "gpc_reg_operand" "r,r"))
9369    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9370         (plus:P (match_dup 1) (match_dup 2)))]
9371   "TARGET_SOFT_FLOAT && TARGET_UPDATE
9372    && (!avoiding_indexed_address_p (SFmode)
9373        || !gpc_reg_operand (operands[2], Pmode))"
9374   "@
9375    stwux %3,%0,%2
9376    stwu %3,%2(%0)"
9377   [(set_attr "type" "store")
9378    (set_attr "update" "yes")
9379    (set_attr "indexed" "yes,no")])
9382 ;; After inserting conditional returns we can sometimes have
9383 ;; unnecessary register moves.  Unfortunately we cannot have a
9384 ;; modeless peephole here, because some single SImode sets have early
9385 ;; clobber outputs.  Although those sets expand to multi-ppc-insn
9386 ;; sequences, using get_attr_length here will smash the operands
9387 ;; array.  Neither is there an early_cobbler_p predicate.
9388 ;; Also this optimization interferes with scalars going into
9389 ;; altivec registers (the code does reloading through the FPRs).
9390 (define_peephole2
9391   [(set (match_operand:DF 0 "gpc_reg_operand")
9392         (match_operand:DF 1 "any_operand"))
9393    (set (match_operand:DF 2 "gpc_reg_operand")
9394         (match_dup 0))]
9395   "!TARGET_VSX
9396    && peep2_reg_dead_p (2, operands[0])"
9397   [(set (match_dup 2) (match_dup 1))])
9399 (define_peephole2
9400   [(set (match_operand:SF 0 "gpc_reg_operand")
9401         (match_operand:SF 1 "any_operand"))
9402    (set (match_operand:SF 2 "gpc_reg_operand")
9403         (match_dup 0))]
9404   "!TARGET_P8_VECTOR
9405    && peep2_reg_dead_p (2, operands[0])"
9406   [(set (match_dup 2) (match_dup 1))])
9409 ;; TLS support.
9411 (define_insn_and_split "*tls_gd<bits>"
9412   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9413         (unspec:P [(match_operand:P 1 "rs6000_tls_symbol_ref" "")
9414                    (match_operand:P 2 "gpc_reg_operand" "b")]
9415                   UNSPEC_TLSGD))]
9416   "HAVE_AS_TLS && TARGET_TLS_MARKERS"
9417   "addi %0,%2,%1@got@tlsgd"
9418   "&& TARGET_CMODEL != CMODEL_SMALL"
9419   [(set (match_dup 3)
9420         (high:P
9421             (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))
9422    (set (match_dup 0)
9423         (lo_sum:P (match_dup 3)
9424             (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))]
9426   operands[3] = gen_reg_rtx (<MODE>mode);
9428   [(set (attr "length")
9429      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9430                    (const_int 8)
9431                    (const_int 4)))])
9433 (define_insn "*tls_gd_high<bits>"
9434   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9435      (high:P
9436        (unspec:P [(match_operand:P 1 "rs6000_tls_symbol_ref" "")
9437                   (match_operand:P 2 "gpc_reg_operand" "b")]
9438                  UNSPEC_TLSGD)))]
9439   "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9440   "addis %0,%2,%1@got@tlsgd@ha")
9442 (define_insn "*tls_gd_low<bits>"
9443   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9444      (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
9445        (unspec:P [(match_operand:P 2 "rs6000_tls_symbol_ref" "")
9446                   (match_operand:P 3 "gpc_reg_operand" "b")]
9447                  UNSPEC_TLSGD)))]
9448   "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9449   "addi %0,%1,%2@got@tlsgd@l")
9451 (define_insn_and_split "*tls_ld<bits>"
9452   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9453         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")]
9454                   UNSPEC_TLSLD))]
9455   "HAVE_AS_TLS && TARGET_TLS_MARKERS"
9456   "addi %0,%1,%&@got@tlsld"
9457   "&& TARGET_CMODEL != CMODEL_SMALL"
9458   [(set (match_dup 2)
9459         (high:P
9460             (unspec:P [(match_dup 1)] UNSPEC_TLSLD)))
9461    (set (match_dup 0)
9462         (lo_sum:P (match_dup 2)
9463             (unspec:P [(match_dup 1)] UNSPEC_TLSLD)))]
9465   operands[2] = gen_reg_rtx (<MODE>mode);
9467   [(set (attr "length")
9468      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9469                    (const_int 8)
9470                    (const_int 4)))])
9472 (define_insn "*tls_ld_high<bits>"
9473   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9474      (high:P
9475        (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")]
9476                  UNSPEC_TLSLD)))]
9477   "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9478   "addis %0,%1,%&@got@tlsld@ha")
9480 (define_insn "*tls_ld_low<bits>"
9481   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9482      (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
9483        (unspec:P [(match_operand:P 2 "gpc_reg_operand" "b")]
9484                  UNSPEC_TLSLD)))]
9485   "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9486   "addi %0,%1,%&@got@tlsld@l")
9488 (define_insn "tls_dtprel_<bits>"
9489   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9490         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9491                    (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9492                   UNSPEC_TLSDTPREL))]
9493   "HAVE_AS_TLS"
9494   "addi %0,%1,%2@dtprel")
9496 (define_insn "tls_dtprel_ha_<bits>"
9497   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9498         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9499                    (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9500                   UNSPEC_TLSDTPRELHA))]
9501   "HAVE_AS_TLS"
9502   "addis %0,%1,%2@dtprel@ha")
9504 (define_insn "tls_dtprel_lo_<bits>"
9505   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9506         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9507                    (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9508                   UNSPEC_TLSDTPRELLO))]
9509   "HAVE_AS_TLS"
9510   "addi %0,%1,%2@dtprel@l")
9512 (define_insn_and_split "tls_got_dtprel_<bits>"
9513   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9514         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9515                    (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9516                   UNSPEC_TLSGOTDTPREL))]
9517   "HAVE_AS_TLS"
9518   "<ptrload> %0,%2@got@dtprel(%1)"
9519   "&& TARGET_CMODEL != CMODEL_SMALL"
9520   [(set (match_dup 3)
9521         (high:P
9522             (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))
9523    (set (match_dup 0)
9524         (lo_sum:P (match_dup 3)
9525             (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))]
9527   operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9529   [(set (attr "length")
9530      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9531                    (const_int 8)
9532                    (const_int 4)))])
9534 (define_insn "*tls_got_dtprel_high<bits>"
9535   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9536      (high:P
9537        (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9538                   (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9539                  UNSPEC_TLSGOTDTPREL)))]
9540   "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9541   "addis %0,%1,%2@got@dtprel@ha")
9543 (define_insn "*tls_got_dtprel_low<bits>"
9544   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9545      (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
9546          (unspec:P [(match_operand:P 3 "gpc_reg_operand" "b")
9547                     (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9548                    UNSPEC_TLSGOTDTPREL)))]
9549   "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9550   "<ptrload> %0,%2@got@dtprel@l(%1)")
9552 (define_insn "tls_tprel_<bits>"
9553   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9554         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9555                    (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9556                   UNSPEC_TLSTPREL))]
9557   "HAVE_AS_TLS"
9558   "addi %0,%1,%2@tprel")
9560 (define_insn "tls_tprel_ha_<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_TLSTPRELHA))]
9565   "HAVE_AS_TLS"
9566   "addis %0,%1,%2@tprel@ha")
9568 (define_insn "tls_tprel_lo_<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_TLSTPRELLO))]
9573   "HAVE_AS_TLS"
9574   "addi %0,%1,%2@tprel@l")
9576 ;; "b" output constraint here and on tls_tls input to support linker tls
9577 ;; optimization.  The linker may edit the instructions emitted by a
9578 ;; tls_got_tprel/tls_tls pair to addis,addi.
9579 (define_insn_and_split "tls_got_tprel_<bits>"
9580   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9581         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9582                    (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9583                   UNSPEC_TLSGOTTPREL))]
9584   "HAVE_AS_TLS"
9585   "<ptrload> %0,%2@got@tprel(%1)"
9586   "&& TARGET_CMODEL != CMODEL_SMALL"
9587   [(set (match_dup 3)
9588         (high:P
9589             (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))
9590    (set (match_dup 0)
9591         (lo_sum:P (match_dup 3)
9592             (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))]
9594   operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9596   [(set (attr "length")
9597      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9598                    (const_int 8)
9599                    (const_int 4)))])
9601 (define_insn "*tls_got_tprel_high<bits>"
9602   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9603      (high:P
9604        (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9605                   (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9606                  UNSPEC_TLSGOTTPREL)))]
9607   "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9608   "addis %0,%1,%2@got@tprel@ha")
9610 (define_insn "*tls_got_tprel_low<bits>"
9611   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9612      (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
9613          (unspec:P [(match_operand:P 3 "gpc_reg_operand" "b")
9614                     (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9615                    UNSPEC_TLSGOTTPREL)))]
9616   "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9617   "<ptrload> %0,%2@got@tprel@l(%1)")
9619 (define_insn "tls_tls_<bits>"
9620   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9621         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9622                    (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9623                   UNSPEC_TLSTLS))]
9624   "TARGET_ELF && HAVE_AS_TLS"
9625   "add %0,%1,%2@tls")
9627 (define_expand "tls_get_tpointer"
9628   [(set (match_operand:SI 0 "gpc_reg_operand")
9629         (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))]
9630   "TARGET_XCOFF && HAVE_AS_TLS"
9632   emit_insn (gen_tls_get_tpointer_internal ());
9633   emit_move_insn (operands[0], gen_rtx_REG (SImode, 3));
9634   DONE;
9637 (define_insn "tls_get_tpointer_internal"
9638   [(set (reg:SI 3)
9639         (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))
9640    (clobber (reg:SI LR_REGNO))]
9641   "TARGET_XCOFF && HAVE_AS_TLS"
9642   "bla __get_tpointer")
9644 (define_expand "tls_get_addr<mode>"
9645   [(set (match_operand:P 0 "gpc_reg_operand")
9646         (unspec:P [(match_operand:P 1 "gpc_reg_operand")
9647                    (match_operand:P 2 "gpc_reg_operand")] UNSPEC_TLSTLS))]
9648   "TARGET_XCOFF && HAVE_AS_TLS"
9650   emit_move_insn (gen_rtx_REG (Pmode, 3), operands[1]);
9651   emit_move_insn (gen_rtx_REG (Pmode, 4), operands[2]);
9652   emit_insn (gen_tls_get_addr_internal<mode> ());
9653   emit_move_insn (operands[0], gen_rtx_REG (Pmode, 3));
9654   DONE;
9657 (define_insn "tls_get_addr_internal<mode>"
9658   [(set (reg:P 3)
9659         (unspec:P [(reg:P 3) (reg:P 4)] UNSPEC_TLSTLS))
9660    (clobber (reg:P 0))
9661    (clobber (reg:P 4))
9662    (clobber (reg:P 5))
9663    (clobber (reg:P 11))
9664    (clobber (reg:CC CR0_REGNO))
9665    (clobber (reg:P LR_REGNO))]
9666   "TARGET_XCOFF && HAVE_AS_TLS"
9667   "bla __tls_get_addr")
9669 ;; Next come insns related to the calling sequence.
9671 ;; First, an insn to allocate new stack space for dynamic use (e.g., alloca).
9672 ;; We move the back-chain and decrement the stack pointer.
9674 ;; Operand1 is more naturally reg_or_short_operand.  However, for a large
9675 ;; constant alloca, using that predicate will force the generic code to put
9676 ;; the constant size into a register before calling the expander.
9678 ;; As a result the expander would not have the constant size information
9679 ;; in those cases and would have to generate less efficient code.
9681 ;; Thus we allow reg_or_cint_operand instead so that the expander can see
9682 ;; the constant size.  The value is forced into a register if necessary.
9684 (define_expand "allocate_stack"
9685   [(set (match_operand 0 "gpc_reg_operand")
9686         (minus (reg 1) (match_operand 1 "reg_or_cint_operand")))
9687    (set (reg 1)
9688         (minus (reg 1) (match_dup 1)))]
9689   ""
9691   rtx chain = gen_reg_rtx (Pmode);
9692   rtx stack_bot = gen_rtx_MEM (Pmode, stack_pointer_rtx);
9693   rtx neg_op0;
9694   rtx insn, par, set, mem;
9696   /* By allowing reg_or_cint_operand as the predicate we can get
9697      better code for stack-clash-protection because we do not lose
9698      size information.  But the rest of the code expects the operand
9699      to be reg_or_short_operand.  If it isn't, then force it into
9700      a register.  */
9701   rtx orig_op1 = operands[1];
9702   if (!reg_or_short_operand (operands[1], Pmode))
9703     operands[1] = force_reg (Pmode, operands[1]);
9705   emit_move_insn (chain, stack_bot);
9707   /* Check stack bounds if necessary.  */
9708   if (crtl->limit_stack)
9709     {
9710       rtx available;
9711       available = expand_binop (Pmode, sub_optab,
9712                                 stack_pointer_rtx, stack_limit_rtx,
9713                                 NULL_RTX, 1, OPTAB_WIDEN);
9714       emit_insn (gen_cond_trap (LTU, available, operands[1], const0_rtx));
9715     }
9717   /* Allocate and probe if requested.
9718      This may look similar to the loop we use for prologue allocations,
9719      but it is critically different.  For the former we know the loop
9720      will iterate, but do not know that generally here.  The former
9721      uses that knowledge to rotate the loop.  Combining them would be
9722      possible with some performance cost.  */
9723   if (flag_stack_clash_protection)
9724     {
9725       rtx rounded_size, last_addr, residual;
9726       HOST_WIDE_INT probe_interval;
9727       compute_stack_clash_protection_loop_data (&rounded_size, &last_addr,
9728                                                 &residual, &probe_interval,
9729                                                 orig_op1);
9730       
9731       /* We do occasionally get in here with constant sizes, we might
9732          as well do a reasonable job when we obviously can.  */
9733       if (rounded_size != const0_rtx)
9734         {
9735           rtx loop_lab, end_loop;
9736           bool rotated = CONST_INT_P (rounded_size);
9737           rtx update = GEN_INT (-probe_interval);
9738           if (probe_interval > 32768)
9739             update = force_reg (Pmode, update);
9741           emit_stack_clash_protection_probe_loop_start (&loop_lab, &end_loop,
9742                                                         last_addr, rotated);
9744           if (TARGET_32BIT)
9745             emit_insn (gen_movsi_update_stack (stack_pointer_rtx,
9746                                                stack_pointer_rtx,
9747                                                update, chain));
9748           else
9749             emit_insn (gen_movdi_update_stack (stack_pointer_rtx,
9750                                                stack_pointer_rtx,
9751                                                update, chain));
9752           emit_stack_clash_protection_probe_loop_end (loop_lab, end_loop,
9753                                                       last_addr, rotated);
9754         }
9756       /* Now handle residuals.  We just have to set operands[1] correctly
9757          and let the rest of the expander run.  */
9758       operands[1] = residual;
9759     }
9761   if (!(CONST_INT_P (operands[1])
9762         && IN_RANGE (INTVAL (operands[1]), -32767, 32768)))
9763     {
9764       operands[1] = force_reg (Pmode, operands[1]);
9765       neg_op0 = gen_reg_rtx (Pmode);
9766       emit_insn (gen_neg2 (Pmode, neg_op0, operands[1]));
9767     }
9768   else
9769     neg_op0 = GEN_INT (-INTVAL (operands[1]));
9771   insn = emit_insn ((* ((TARGET_32BIT) ? gen_movsi_update_stack
9772                                        : gen_movdi_update_stack))
9773                         (stack_pointer_rtx, stack_pointer_rtx, neg_op0,
9774                          chain));
9775   /* Since we didn't use gen_frame_mem to generate the MEM, grab
9776      it now and set the alias set/attributes. The above gen_*_update
9777      calls will generate a PARALLEL with the MEM set being the first
9778      operation. */
9779   par = PATTERN (insn);
9780   gcc_assert (GET_CODE (par) == PARALLEL);
9781   set = XVECEXP (par, 0, 0);
9782   gcc_assert (GET_CODE (set) == SET);
9783   mem = SET_DEST (set);
9784   gcc_assert (MEM_P (mem));
9785   MEM_NOTRAP_P (mem) = 1;
9786   set_mem_alias_set (mem, get_frame_alias_set ());
9788   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
9789   DONE;
9792 ;; These patterns say how to save and restore the stack pointer.  We need not
9793 ;; save the stack pointer at function level since we are careful to
9794 ;; preserve the backchain.  At block level, we have to restore the backchain
9795 ;; when we restore the stack pointer.
9797 ;; For nonlocal gotos, we must save both the stack pointer and its
9798 ;; backchain and restore both.  Note that in the nonlocal case, the
9799 ;; save area is a memory location.
9801 (define_expand "save_stack_function"
9802   [(match_operand 0 "any_operand")
9803    (match_operand 1 "any_operand")]
9804   ""
9805   "DONE;")
9807 (define_expand "restore_stack_function"
9808   [(match_operand 0 "any_operand")
9809    (match_operand 1 "any_operand")]
9810   ""
9811   "DONE;")
9813 ;; Adjust stack pointer (op0) to a new value (op1).
9814 ;; First copy old stack backchain to new location, and ensure that the
9815 ;; scheduler won't reorder the sp assignment before the backchain write.
9816 (define_expand "restore_stack_block"
9817   [(set (match_dup 2) (match_dup 3))
9818    (set (match_dup 4) (match_dup 2))
9819    (match_dup 5)
9820    (set (match_operand 0 "register_operand")
9821         (match_operand 1 "register_operand"))]
9822   ""
9824   rtvec p;
9826   operands[1] = force_reg (Pmode, operands[1]);
9827   operands[2] = gen_reg_rtx (Pmode);
9828   operands[3] = gen_frame_mem (Pmode, operands[0]);
9829   operands[4] = gen_frame_mem (Pmode, operands[1]);
9830   p = rtvec_alloc (1);
9831   RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
9832                                   const0_rtx);
9833   operands[5] = gen_rtx_PARALLEL (VOIDmode, p);
9836 (define_expand "save_stack_nonlocal"
9837   [(set (match_dup 3) (match_dup 4))
9838    (set (match_operand 0 "memory_operand") (match_dup 3))
9839    (set (match_dup 2) (match_operand 1 "register_operand"))]
9840   ""
9842   int units_per_word = (TARGET_32BIT) ? 4 : 8;
9844   /* Copy the backchain to the first word, sp to the second.  */
9845   operands[0] = adjust_address_nv (operands[0], Pmode, 0);
9846   operands[2] = adjust_address_nv (operands[0], Pmode, units_per_word);
9847   operands[3] = gen_reg_rtx (Pmode);
9848   operands[4] = gen_frame_mem (Pmode, operands[1]);
9851 (define_expand "restore_stack_nonlocal"
9852   [(set (match_dup 2) (match_operand 1 "memory_operand"))
9853    (set (match_dup 3) (match_dup 4))
9854    (set (match_dup 5) (match_dup 2))
9855    (match_dup 6)
9856    (set (match_operand 0 "register_operand") (match_dup 3))]
9857   ""
9859   int units_per_word = (TARGET_32BIT) ? 4 : 8;
9860   rtvec p;
9862   /* Restore the backchain from the first word, sp from the second.  */
9863   operands[2] = gen_reg_rtx (Pmode);
9864   operands[3] = gen_reg_rtx (Pmode);
9865   operands[1] = adjust_address_nv (operands[1], Pmode, 0);
9866   operands[4] = adjust_address_nv (operands[1], Pmode, units_per_word);
9867   operands[5] = gen_frame_mem (Pmode, operands[3]);
9868   p = rtvec_alloc (1);
9869   RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
9870                                   const0_rtx);
9871   operands[6] = gen_rtx_PARALLEL (VOIDmode, p);
9874 ;; TOC register handling.
9876 ;; Code to initialize the TOC register...
9878 (define_insn "load_toc_aix_si"
9879   [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
9880                    (unspec:SI [(const_int 0)] UNSPEC_TOC))
9881               (use (reg:SI 2))])]
9882   "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_32BIT"
9884   char buf[30];
9885   extern int need_toc_init;
9886   need_toc_init = 1;
9887   ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
9888   operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
9889   operands[2] = gen_rtx_REG (Pmode, 2);
9890   return "lwz %0,%1(%2)";
9892   [(set_attr "type" "load")
9893    (set_attr "update" "no")
9894    (set_attr "indexed" "no")])
9896 (define_insn "load_toc_aix_di"
9897   [(parallel [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
9898                    (unspec:DI [(const_int 0)] UNSPEC_TOC))
9899               (use (reg:DI 2))])]
9900   "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_64BIT"
9902   char buf[30];
9903   extern int need_toc_init;
9904   need_toc_init = 1;
9905   ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC",
9906                                !TARGET_ELF || !TARGET_MINIMAL_TOC);
9907   if (TARGET_ELF)
9908     strcat (buf, "@toc");
9909   operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
9910   operands[2] = gen_rtx_REG (Pmode, 2);
9911   return "ld %0,%1(%2)";
9913   [(set_attr "type" "load")
9914    (set_attr "update" "no")
9915    (set_attr "indexed" "no")])
9917 (define_insn "load_toc_v4_pic_si"
9918   [(set (reg:SI LR_REGNO)
9919         (unspec:SI [(const_int 0)] UNSPEC_TOC))]
9920   "DEFAULT_ABI == ABI_V4 && flag_pic == 1 && TARGET_32BIT"
9921   "bl _GLOBAL_OFFSET_TABLE_@local-4"
9922   [(set_attr "type" "branch")])
9924 (define_expand "load_toc_v4_PIC_1"
9925   [(parallel [(set (reg:SI LR_REGNO)
9926                    (match_operand:SI 0 "immediate_operand" "s"))
9927               (use (unspec [(match_dup 0)] UNSPEC_TOC))])]
9928   "TARGET_ELF && DEFAULT_ABI == ABI_V4
9929    && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
9930   "")
9932 (define_insn "load_toc_v4_PIC_1_normal"
9933   [(set (reg:SI LR_REGNO)
9934         (match_operand:SI 0 "immediate_operand" "s"))
9935    (use (unspec [(match_dup 0)] UNSPEC_TOC))]
9936   "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
9937    && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
9938   "bcl 20,31,%0\n%0:"
9939   [(set_attr "type" "branch")
9940    (set_attr "cannot_copy" "yes")])
9942 (define_insn "load_toc_v4_PIC_1_476"
9943   [(set (reg:SI LR_REGNO)
9944         (match_operand:SI 0 "immediate_operand" "s"))
9945    (use (unspec [(match_dup 0)] UNSPEC_TOC))]
9946   "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
9947    && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
9949   char name[32];
9950   static char templ[32];
9952   get_ppc476_thunk_name (name);
9953   sprintf (templ, "bl %s\n%%0:", name);
9954   return templ;
9956   [(set_attr "type" "branch")
9957    (set_attr "cannot_copy" "yes")])
9959 (define_expand "load_toc_v4_PIC_1b"
9960   [(parallel [(set (reg:SI LR_REGNO)
9961                    (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
9962                                (label_ref (match_operand 1 ""))]
9963                            UNSPEC_TOCPTR))
9964               (match_dup 1)])]
9965   "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
9966   "")
9968 (define_insn "load_toc_v4_PIC_1b_normal"
9969   [(set (reg:SI LR_REGNO)
9970         (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
9971                     (label_ref (match_operand 1 "" ""))]
9972                 UNSPEC_TOCPTR))
9973    (match_dup 1)]
9974   "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
9975   "bcl 20,31,$+8\;.long %0-$"
9976   [(set_attr "type" "branch")
9977    (set_attr "length" "8")])
9979 (define_insn "load_toc_v4_PIC_1b_476"
9980   [(set (reg:SI LR_REGNO)
9981         (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
9982                     (label_ref (match_operand 1 "" ""))]
9983                 UNSPEC_TOCPTR))
9984    (match_dup 1)]
9985   "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
9987   char name[32];
9988   static char templ[32];
9990   get_ppc476_thunk_name (name);
9991   sprintf (templ, "bl %s\;b $+8\;.long %%0-$", name);
9992   return templ;
9994   [(set_attr "type" "branch")
9995    (set_attr "length" "16")])
9997 (define_insn "load_toc_v4_PIC_2"
9998   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
9999         (mem:SI (plus:SI
10000                   (match_operand:SI 1 "gpc_reg_operand" "b")
10001                   (const
10002                     (minus:SI (match_operand:SI 2 "immediate_operand" "s")
10003                               (match_operand:SI 3 "immediate_operand" "s"))))))]
10004   "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10005   "lwz %0,%2-%3(%1)"
10006   [(set_attr "type" "load")])
10008 (define_insn "load_toc_v4_PIC_3b"
10009   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10010         (plus:SI
10011           (match_operand:SI 1 "gpc_reg_operand" "b")
10012           (high:SI
10013             (const
10014               (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
10015                         (match_operand:SI 3 "symbol_ref_operand" "s"))))))]
10016   "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
10017   "addis %0,%1,%2-%3@ha")
10019 (define_insn "load_toc_v4_PIC_3c"
10020   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10021         (lo_sum:SI
10022           (match_operand:SI 1 "gpc_reg_operand" "b")
10023           (const
10024             (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
10025                       (match_operand:SI 3 "symbol_ref_operand" "s")))))]
10026   "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
10027   "addi %0,%1,%2-%3@l")
10029 ;; If the TOC is shared over a translation unit, as happens with all
10030 ;; the kinds of PIC that we support, we need to restore the TOC
10031 ;; pointer only when jumping over units of translation.
10032 ;; On Darwin, we need to reload the picbase.
10034 (define_expand "builtin_setjmp_receiver"
10035   [(use (label_ref (match_operand 0 "")))]
10036   "(DEFAULT_ABI == ABI_V4 && flag_pic == 1)
10037    || (TARGET_TOC && TARGET_MINIMAL_TOC)
10038    || (DEFAULT_ABI == ABI_DARWIN && flag_pic)"
10040 #if TARGET_MACHO
10041   if (DEFAULT_ABI == ABI_DARWIN)
10042     {
10043       rtx picrtx = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME);
10044       rtx picreg = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
10045       rtx tmplabrtx;
10046       char tmplab[20];
10048       crtl->uses_pic_offset_table = 1;
10049       ASM_GENERATE_INTERNAL_LABEL(tmplab, "LSJR",
10050                                   CODE_LABEL_NUMBER (operands[0]));
10051       tmplabrtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (tmplab));
10053       emit_insn (gen_load_macho_picbase (tmplabrtx));
10054       emit_move_insn (picreg, gen_rtx_REG (Pmode, LR_REGNO));
10055       emit_insn (gen_macho_correct_pic (picreg, picreg, picrtx, tmplabrtx));
10056     }
10057   else
10058 #endif
10059     rs6000_emit_load_toc_table (FALSE);
10060   DONE;
10063 ;; Largetoc support
10064 (define_insn "*largetoc_high"
10065   [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
10066         (high:DI
10067           (unspec [(match_operand:DI 1 "" "")
10068                    (match_operand:DI 2 "gpc_reg_operand" "b")]
10069                   UNSPEC_TOCREL)))]
10070    "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10071    "addis %0,%2,%1@toc@ha")
10073 (define_insn "*largetoc_high_aix<mode>"
10074   [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
10075         (high:P
10076           (unspec [(match_operand:P 1 "" "")
10077                    (match_operand:P 2 "gpc_reg_operand" "b")]
10078                   UNSPEC_TOCREL)))]
10079    "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10080    "addis %0,%1@u(%2)")
10082 (define_insn "*largetoc_high_plus"
10083   [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
10084         (high:DI
10085           (plus:DI
10086             (unspec [(match_operand:DI 1 "" "")
10087                      (match_operand:DI 2 "gpc_reg_operand" "b")]
10088                     UNSPEC_TOCREL)
10089             (match_operand:DI 3 "add_cint_operand" "n"))))]
10090    "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10091    "addis %0,%2,%1+%3@toc@ha")
10093 (define_insn "*largetoc_high_plus_aix<mode>"
10094   [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
10095         (high:P
10096           (plus:P
10097             (unspec [(match_operand:P 1 "" "")
10098                      (match_operand:P 2 "gpc_reg_operand" "b")]
10099                     UNSPEC_TOCREL)
10100             (match_operand:P 3 "add_cint_operand" "n"))))]
10101    "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10102    "addis %0,%1+%3@u(%2)")
10104 (define_insn "*largetoc_low"
10105   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
10106         (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b")
10107                    (match_operand:DI 2 "" "")))]
10108    "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10109    "addi %0,%1,%2@l")
10111 (define_insn "*largetoc_low_aix<mode>"
10112   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10113         (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
10114                    (match_operand:P 2 "" "")))]
10115    "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10116    "la %0,%2@l(%1)")
10118 (define_insn_and_split "*tocref<mode>"
10119   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
10120         (match_operand:P 1 "small_toc_ref" "R"))]
10121    "TARGET_TOC"
10122    "la %0,%a1"
10123    "&& TARGET_CMODEL != CMODEL_SMALL && reload_completed"
10124   [(set (match_dup 0) (high:P (match_dup 1)))
10125    (set (match_dup 0) (lo_sum:P (match_dup 0) (match_dup 1)))])
10127 ;; Elf specific ways of loading addresses for non-PIC code.
10128 ;; The output of this could be r0, but we make a very strong
10129 ;; preference for a base register because it will usually
10130 ;; be needed there.
10131 (define_insn "elf_high"
10132   [(set (match_operand:SI 0 "gpc_reg_operand" "=b*r")
10133         (high:SI (match_operand 1 "" "")))]
10134   "TARGET_ELF && !TARGET_64BIT && !flag_pic"
10135   "lis %0,%1@ha")
10137 (define_insn "elf_low"
10138   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10139         (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
10140                    (match_operand 2 "" "")))]
10141    "TARGET_ELF && !TARGET_64BIT && !flag_pic"
10142    "la %0,%2@l(%1)")
10144 (define_insn "*pltseq_tocsave_<mode>"
10145   [(set (match_operand:P 0 "memory_operand" "=m")
10146         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
10147                    (match_operand:P 2 "symbol_ref_operand" "s")
10148                    (match_operand:P 3 "" "")]
10149                   UNSPEC_PLTSEQ))]
10150   "TARGET_PLTSEQ
10151    && DEFAULT_ABI == ABI_ELFv2"
10153   return rs6000_pltseq_template (operands, RS6000_PLTSEQ_TOCSAVE);
10156 (define_insn "*pltseq_plt16_ha_<mode>"
10157   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10158         (unspec:P [(match_operand:P 1 "" "")
10159                    (match_operand:P 2 "symbol_ref_operand" "s")
10160                    (match_operand:P 3 "" "")]
10161                   UNSPEC_PLT16_HA))]
10162   "TARGET_PLTSEQ"
10164   return rs6000_pltseq_template (operands, RS6000_PLTSEQ_PLT16_HA);
10167 (define_insn "*pltseq_plt16_lo_<mode>"
10168   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10169         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
10170                    (match_operand:P 2 "symbol_ref_operand" "s")
10171                    (match_operand:P 3 "" "")]
10172                   UNSPEC_PLT16_LO))]
10173   "TARGET_PLTSEQ"
10175   return rs6000_pltseq_template (operands, RS6000_PLTSEQ_PLT16_LO);
10177   [(set_attr "type" "load")])
10179 (define_insn "*pltseq_mtctr_<mode>"
10180   [(set (match_operand:P 0 "register_operand" "=c")
10181         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "r")
10182                    (match_operand:P 2 "symbol_ref_operand" "s")
10183                    (match_operand:P 3 "" "")]
10184                   UNSPEC_PLTSEQ))]
10185   "TARGET_PLTSEQ"
10187   return rs6000_pltseq_template (operands, RS6000_PLTSEQ_MTCTR);
10190 (define_insn "*pltseq_plt_pcrel<mode>"
10191   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10192         (unspec:P [(match_operand:P 1 "" "")
10193                    (match_operand:P 2 "symbol_ref_operand" "s")
10194                    (match_operand:P 3 "" "")]
10195                   UNSPEC_PLT_PCREL))]
10196   "HAVE_AS_PLTSEQ && TARGET_TLS_MARKERS
10197    && rs6000_pcrel_p (cfun)"
10199   return rs6000_pltseq_template (operands, RS6000_PLTSEQ_PLT_PCREL34);
10201   [(set_attr "type" "load")
10202    (set_attr "length" "12")])
10204 ;; Call and call_value insns
10205 ;; For the purposes of expanding calls, Darwin is very similar to SYSV.
10206 (define_expand "call"
10207   [(parallel [(call (mem:SI (match_operand 0 "address_operand"))
10208                     (match_operand 1 ""))
10209               (use (match_operand 2 ""))
10210               (clobber (reg:SI LR_REGNO))])]
10211   ""
10213 #if TARGET_MACHO
10214   if (MACHOPIC_INDIRECT)
10215     operands[0] = machopic_indirect_call_target (operands[0]);
10216 #endif
10218   gcc_assert (MEM_P (operands[0]));
10220   operands[0] = XEXP (operands[0], 0);
10222   if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10223     rs6000_call_aix (NULL_RTX, operands[0], operands[1], operands[2]);
10224   else if (DEFAULT_ABI == ABI_V4)
10225     rs6000_call_sysv (NULL_RTX, operands[0], operands[1], operands[2]);
10226   else if (DEFAULT_ABI == ABI_DARWIN)
10227     rs6000_call_darwin (NULL_RTX, operands[0], operands[1], operands[2]);
10228   else
10229     gcc_unreachable ();
10231   DONE;
10234 (define_expand "call_value"
10235   [(parallel [(set (match_operand 0 "")
10236                    (call (mem:SI (match_operand 1 "address_operand"))
10237                          (match_operand 2 "")))
10238               (use (match_operand 3 ""))
10239               (clobber (reg:SI LR_REGNO))])]
10240   ""
10242 #if TARGET_MACHO
10243   if (MACHOPIC_INDIRECT)
10244     operands[1] = machopic_indirect_call_target (operands[1]);
10245 #endif
10247   gcc_assert (MEM_P (operands[1]));
10249   operands[1] = XEXP (operands[1], 0);
10251   if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10252     rs6000_call_aix (operands[0], operands[1], operands[2], operands[3]);
10253   else if (DEFAULT_ABI == ABI_V4)
10254     rs6000_call_sysv (operands[0], operands[1], operands[2], operands[3]);
10255   else if (DEFAULT_ABI == ABI_DARWIN)
10256     rs6000_call_darwin (operands[0], operands[1], operands[2], operands[3]);
10257   else
10258     gcc_unreachable ();
10260   DONE;
10263 ;; Call to function in current module.  No TOC pointer reload needed.
10264 ;; Operand2 is nonzero if we are using the V.4 calling sequence and
10265 ;; either the function was not prototyped, or it was prototyped as a
10266 ;; variable argument function.  It is > 0 if FP registers were passed
10267 ;; and < 0 if they were not.
10269 (define_insn "*call_local32"
10270   [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
10271          (match_operand 1))
10272    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10273    (clobber (reg:SI LR_REGNO))]
10274   "(INTVAL (operands[2]) & CALL_LONG) == 0"
10276   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10277     output_asm_insn ("crxor 6,6,6", operands);
10279   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10280     output_asm_insn ("creqv 6,6,6", operands);
10282   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z0@local" : "bl %z0";
10284   [(set_attr "type" "branch")
10285    (set_attr "length" "4,8")])
10287 (define_insn "*call_local64"
10288   [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
10289          (match_operand 1))
10290    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10291    (clobber (reg:DI LR_REGNO))]
10292   "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
10294   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10295     output_asm_insn ("crxor 6,6,6", operands);
10297   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10298     output_asm_insn ("creqv 6,6,6", operands);
10300   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z0@local" : "bl %z0";
10302   [(set_attr "type" "branch")
10303    (set_attr "length" "4,8")])
10305 (define_insn "*call_value_local32"
10306   [(set (match_operand 0 "" "")
10307         (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
10308               (match_operand 2)))
10309    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10310    (clobber (reg:SI LR_REGNO))]
10311   "(INTVAL (operands[3]) & CALL_LONG) == 0
10312    && !IS_NOMARK_TLSGETADDR (operands[2])"
10314   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10315     output_asm_insn ("crxor 6,6,6", operands);
10317   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10318     output_asm_insn ("creqv 6,6,6", operands);
10320   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z1@local" : "bl %z1";
10322   [(set_attr "type" "branch")
10323    (set_attr "length" "4,8")])
10326 (define_insn "*call_value_local64"
10327   [(set (match_operand 0 "" "")
10328         (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
10329               (match_operand 2)))
10330    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10331    (clobber (reg:DI LR_REGNO))]
10332   "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0
10333    && !IS_NOMARK_TLSGETADDR (operands[2])"
10335   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10336     output_asm_insn ("crxor 6,6,6", operands);
10338   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10339     output_asm_insn ("creqv 6,6,6", operands);
10341   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z1@local" : "bl %z1";
10343   [(set_attr "type" "branch")
10344    (set_attr "length" "4,8")])
10347 ;; A function pointer under System V is just a normal pointer
10348 ;; operands[0] is the function pointer
10349 ;; operands[1] is the tls call arg
10350 ;; operands[2] is the value FUNCTION_ARG returns for the VOID argument
10351 ;; which indicates how to set cr1
10353 (define_insn "*call_indirect_nonlocal_sysv<mode>"
10354   [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X"))
10355          (match_operand 1))
10356    (use (match_operand:SI 2 "immediate_operand" "n,n,n"))
10357    (clobber (reg:P LR_REGNO))]
10358   "DEFAULT_ABI == ABI_V4
10359    || DEFAULT_ABI == ABI_DARWIN"
10361   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10362     output_asm_insn ("crxor 6,6,6", operands);
10364   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10365     output_asm_insn ("creqv 6,6,6", operands);
10367   return rs6000_indirect_call_template (operands, 0);
10369   [(set_attr "type" "jmpreg")
10370    (set (attr "length")
10371         (cond [(and (and (match_test "!rs6000_speculate_indirect_jumps")
10372                          (match_test "which_alternative != 1"))
10373                     (match_test "(INTVAL (operands[2]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
10374                   (const_string "12")
10375                (ior (and (match_test "!rs6000_speculate_indirect_jumps")
10376                          (match_test "which_alternative != 1"))
10377                     (match_test "(INTVAL (operands[2]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
10378                   (const_string "8")]
10379               (const_string "4")))])
10381 (define_insn "*call_nonlocal_sysv<mode>"
10382   [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
10383          (match_operand 1))
10384    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10385    (clobber (reg:P LR_REGNO))]
10386   "(DEFAULT_ABI == ABI_DARWIN
10387    || (DEFAULT_ABI == ABI_V4
10388        && (INTVAL (operands[2]) & CALL_LONG) == 0))"
10390   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10391     output_asm_insn ("crxor 6,6,6", operands);
10393   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10394     output_asm_insn ("creqv 6,6,6", operands);
10396   return rs6000_call_template (operands, 0);
10398   [(set_attr "type" "branch,branch")
10399    (set_attr "length" "4,8")])
10401 (define_insn "*call_nonlocal_sysv_secure<mode>"
10402   [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
10403          (match_operand 1))
10404    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10405    (use (match_operand:SI 3 "register_operand" "r,r"))
10406    (clobber (reg:P LR_REGNO))]
10407   "(DEFAULT_ABI == ABI_V4
10408     && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0])
10409     && (INTVAL (operands[2]) & CALL_LONG) == 0)"
10411   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10412     output_asm_insn ("crxor 6,6,6", operands);
10414   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10415     output_asm_insn ("creqv 6,6,6", operands);
10417   return rs6000_call_template (operands, 0);
10419   [(set_attr "type" "branch,branch")
10420    (set_attr "length" "4,8")])
10422 (define_insn "*call_value_indirect_nonlocal_sysv<mode>"
10423   [(set (match_operand 0 "" "")
10424         (call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X"))
10425               (match_operand:P 2 "unspec_tls" "")))
10426    (use (match_operand:SI 3 "immediate_operand" "n,n,n"))
10427    (clobber (reg:P LR_REGNO))]
10428   "DEFAULT_ABI == ABI_V4
10429    || DEFAULT_ABI == ABI_DARWIN"
10431   if (IS_NOMARK_TLSGETADDR (operands[2]))
10432     rs6000_output_tlsargs (operands);
10434   else if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10435     output_asm_insn ("crxor 6,6,6", operands);
10437   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10438     output_asm_insn ("creqv 6,6,6", operands);
10440   return rs6000_indirect_call_template (operands, 1);
10442   [(set_attr "type" "jmpreg")
10443    (set (attr "length")
10444         (plus
10445           (if_then_else (ior (match_test "IS_NOMARK_TLSGETADDR (operands[2])")
10446                              (match_test "IS_V4_FP_ARGS (operands[3])"))
10447             (const_int 4)
10448             (const_int 0))
10449           (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
10450                              (match_test "which_alternative != 1"))
10451             (const_int 8)
10452             (const_int 4))))])
10454 (define_insn "*call_value_nonlocal_sysv<mode>"
10455   [(set (match_operand 0 "" "")
10456         (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s"))
10457               (match_operand:P 2 "unspec_tls" "")))
10458    (use (match_operand:SI 3 "immediate_operand" "n"))
10459    (clobber (reg:P LR_REGNO))]
10460   "(DEFAULT_ABI == ABI_DARWIN
10461     || (DEFAULT_ABI == ABI_V4
10462         && (INTVAL (operands[3]) & CALL_LONG) == 0))"
10464   if (IS_NOMARK_TLSGETADDR (operands[2]))
10465     rs6000_output_tlsargs (operands);
10467   else if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10468     output_asm_insn ("crxor 6,6,6", operands);
10470   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10471     output_asm_insn ("creqv 6,6,6", operands);
10473   return rs6000_call_template (operands, 1);
10475   [(set_attr "type" "branch")
10476    (set (attr "length")
10477         (if_then_else (ior (match_test "IS_NOMARK_TLSGETADDR (operands[2])")
10478                            (match_test "IS_V4_FP_ARGS (operands[3])"))
10479           (const_int 8)
10480           (const_int 4)))])
10482 (define_insn "*call_value_nonlocal_sysv_secure<mode>"
10483   [(set (match_operand 0 "" "")
10484         (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s"))
10485               (match_operand:P 2 "unspec_tls" "")))
10486    (use (match_operand:SI 3 "immediate_operand" "n"))
10487    (use (match_operand:SI 4 "register_operand" "r"))
10488    (clobber (reg:P LR_REGNO))]
10489   "(DEFAULT_ABI == ABI_V4
10490     && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1])
10491     && (INTVAL (operands[3]) & CALL_LONG) == 0)"
10493   if (IS_NOMARK_TLSGETADDR (operands[2]))
10494     rs6000_output_tlsargs (operands);
10496   else if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10497     output_asm_insn ("crxor 6,6,6", operands);
10499   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10500     output_asm_insn ("creqv 6,6,6", operands);
10502   return rs6000_call_template (operands, 1);
10504   [(set_attr "type" "branch")
10505    (set (attr "length")
10506         (if_then_else (ior (match_test "IS_NOMARK_TLSGETADDR (operands[2])")
10507                            (match_test "IS_V4_FP_ARGS (operands[3])"))
10508           (const_int 8)
10509           (const_int 4)))])
10511 ;; Call to AIX abi function in the same module.
10513 (define_insn "*call_local_aix<mode>"
10514   [(call (mem:SI (match_operand:P 0 "current_file_function_operand" "s"))
10515          (match_operand 1))
10516    (clobber (reg:P LR_REGNO))]
10517   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10519   if (rs6000_pcrel_p (cfun))
10520     return "bl %z0@notoc";
10521   return "bl %z0";
10523   [(set_attr "type" "branch")])
10525 (define_insn "*call_value_local_aix<mode>"
10526   [(set (match_operand 0 "" "")
10527         (call (mem:SI (match_operand:P 1 "current_file_function_operand" "s"))
10528               (match_operand 2)))
10529    (clobber (reg:P LR_REGNO))]
10530   "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10531    && !IS_NOMARK_TLSGETADDR (operands[2])"
10533   if (rs6000_pcrel_p (cfun))
10534     return "bl %z1@notoc";
10535   return "bl %z1";
10537   [(set_attr "type" "branch")])
10539 ;; Call to AIX abi function which may be in another module.
10540 ;; Restore the TOC pointer (r2) after the call.
10542 (define_insn "*call_nonlocal_aix<mode>"
10543   [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s"))
10544          (match_operand 1))
10545    (clobber (reg:P LR_REGNO))]
10546   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10548   return rs6000_call_template (operands, 0);
10550   [(set_attr "type" "branch")
10551    (set (attr "length")
10552         (if_then_else (match_test "rs6000_pcrel_p (cfun)")
10553           (const_int 4)
10554           (const_int 8)))])
10556 (define_insn "*call_value_nonlocal_aix<mode>"
10557   [(set (match_operand 0 "" "")
10558         (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s"))
10559               (match_operand:P 2 "unspec_tls" "")))
10560    (clobber (reg:P LR_REGNO))]
10561   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10563   if (IS_NOMARK_TLSGETADDR (operands[2]))
10564     rs6000_output_tlsargs (operands);
10566   return rs6000_call_template (operands, 1);
10568   [(set_attr "type" "branch")
10569    (set (attr "length")
10570         (plus (if_then_else (match_test "IS_NOMARK_TLSGETADDR (operands[2])")
10571                 (if_then_else (match_test "TARGET_CMODEL != CMODEL_SMALL")
10572                   (const_int 8)
10573                   (const_int 4))
10574                 (const_int 0))
10575               (if_then_else (match_test "rs6000_pcrel_p (cfun)")
10576                 (const_int 4)
10577                 (const_int 8))))])
10579 ;; Call to indirect functions with the AIX abi using a 3 word descriptor.
10580 ;; Operand0 is the addresss of the function to call
10581 ;; Operand2 is the location in the function descriptor to load r2 from
10582 ;; Operand3 is the offset of the stack location holding the current TOC pointer
10584 (define_insn "*call_indirect_aix<mode>"
10585   [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X"))
10586          (match_operand 1))
10587    (use (match_operand:P 2 "memory_operand" "<ptrm>,<ptrm>,<ptrm>"))
10588    (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 3 "const_int_operand" "n,n,n")] UNSPEC_TOCSLOT))
10589    (clobber (reg:P LR_REGNO))]
10590   "DEFAULT_ABI == ABI_AIX"
10592   return rs6000_indirect_call_template (operands, 0);
10594   [(set_attr "type" "jmpreg")
10595    (set (attr "length")
10596         (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
10597                            (match_test "which_alternative != 1"))
10598                       (const_string "16")
10599                       (const_string "12")))])
10601 (define_insn "*call_value_indirect_aix<mode>"
10602   [(set (match_operand 0 "" "")
10603         (call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X"))
10604               (match_operand:P 2 "unspec_tls" "")))
10605    (use (match_operand:P 3 "memory_operand" "<ptrm>,<ptrm>,<ptrm>"))
10606    (set (reg:P TOC_REGNUM)
10607         (unspec:P [(match_operand:P 4 "const_int_operand" "n,n,n")]
10608                   UNSPEC_TOCSLOT))
10609    (clobber (reg:P LR_REGNO))]
10610   "DEFAULT_ABI == ABI_AIX"
10612   if (IS_NOMARK_TLSGETADDR (operands[2]))
10613     rs6000_output_tlsargs (operands);
10615   return rs6000_indirect_call_template (operands, 1);
10617   [(set_attr "type" "jmpreg")
10618    (set (attr "length")
10619         (plus
10620           (if_then_else (match_test "IS_NOMARK_TLSGETADDR (operands[2])")
10621             (if_then_else (match_test "TARGET_CMODEL != CMODEL_SMALL")
10622               (const_int 8)
10623               (const_int 4))
10624             (const_int 0))
10625           (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
10626                              (match_test "which_alternative != 1"))
10627             (const_string "16")
10628             (const_string "12"))))])
10630 ;; Call to indirect functions with the ELFv2 ABI.
10631 ;; Operand0 is the addresss of the function to call
10632 ;; Operand2 is the offset of the stack location holding the current TOC pointer
10634 (define_insn "*call_indirect_elfv2<mode>"
10635   [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X"))
10636          (match_operand 1))
10637    (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 2 "const_int_operand" "n,n,n")] UNSPEC_TOCSLOT))
10638    (clobber (reg:P LR_REGNO))]
10639   "DEFAULT_ABI == ABI_ELFv2"
10641   return rs6000_indirect_call_template (operands, 0);
10643   [(set_attr "type" "jmpreg")
10644    (set (attr "length")
10645         (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
10646                            (match_test "which_alternative != 1"))
10647                       (const_string "12")
10648                       (const_string "8")))])
10650 (define_insn "*call_indirect_pcrel<mode>"
10651   [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X"))
10652          (match_operand 1))
10653    (clobber (reg:P LR_REGNO))]
10654   "rs6000_pcrel_p (cfun)"
10656   return rs6000_indirect_call_template (operands, 0);
10658   [(set_attr "type" "jmpreg")
10659    (set (attr "length")
10660         (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
10661                            (match_test "which_alternative != 1"))
10662                       (const_string "8")
10663                       (const_string "4")))])
10665 (define_insn "*call_value_indirect_elfv2<mode>"
10666   [(set (match_operand 0 "" "")
10667         (call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X"))
10668               (match_operand:P 2 "unspec_tls" "")))
10669    (set (reg:P TOC_REGNUM)
10670         (unspec:P [(match_operand:P 3 "const_int_operand" "n,n,n")]
10671                   UNSPEC_TOCSLOT))
10672    (clobber (reg:P LR_REGNO))]
10673   "DEFAULT_ABI == ABI_ELFv2"
10675   if (IS_NOMARK_TLSGETADDR (operands[2]))
10676     rs6000_output_tlsargs (operands);
10678   return rs6000_indirect_call_template (operands, 1);
10680   [(set_attr "type" "jmpreg")
10681    (set (attr "length")
10682         (plus
10683           (if_then_else (match_test "IS_NOMARK_TLSGETADDR (operands[2])")
10684             (if_then_else (match_test "TARGET_CMODEL != CMODEL_SMALL")
10685               (const_int 8)
10686               (const_int 4))
10687             (const_int 0))
10688           (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
10689                              (match_test "which_alternative != 1"))
10690             (const_string "12")
10691             (const_string "8"))))])
10693 (define_insn "*call_value_indirect_pcrel<mode>"
10694   [(set (match_operand 0 "" "")
10695         (call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X"))
10696               (match_operand:P 2 "unspec_tls" "")))
10697    (clobber (reg:P LR_REGNO))]
10698   "rs6000_pcrel_p (cfun)"
10700   if (IS_NOMARK_TLSGETADDR (operands[2]))
10701     rs6000_output_tlsargs (operands);
10703   return rs6000_indirect_call_template (operands, 1);
10705   [(set_attr "type" "jmpreg")
10706    (set (attr "length")
10707         (plus
10708           (if_then_else (match_test "IS_NOMARK_TLSGETADDR (operands[2])")
10709             (if_then_else (match_test "TARGET_CMODEL != CMODEL_SMALL")
10710               (const_int 8)
10711               (const_int 4))
10712             (const_int 0))
10713           (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
10714                              (match_test "which_alternative != 1"))
10715             (const_string "8")
10716             (const_string "4"))))])
10718 ;; Call subroutine returning any type.
10719 (define_expand "untyped_call"
10720   [(parallel [(call (match_operand 0 "")
10721                     (const_int 0))
10722               (match_operand 1 "")
10723               (match_operand 2 "")])]
10724   ""
10726   int i;
10728   emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
10730   for (i = 0; i < XVECLEN (operands[2], 0); i++)
10731     {
10732       rtx set = XVECEXP (operands[2], 0, i);
10733       emit_move_insn (SET_DEST (set), SET_SRC (set));
10734     }
10736   /* The optimizer does not know that the call sets the function value
10737      registers we stored in the result block.  We avoid problems by
10738      claiming that all hard registers are used and clobbered at this
10739      point.  */
10740   emit_insn (gen_blockage ());
10742   DONE;
10745 ;; sibling call patterns
10746 (define_expand "sibcall"
10747   [(parallel [(call (mem:SI (match_operand 0 "address_operand"))
10748                     (match_operand 1 ""))
10749               (use (match_operand 2 ""))
10750               (simple_return)])]
10751   ""
10753 #if TARGET_MACHO
10754   if (MACHOPIC_INDIRECT)
10755     operands[0] = machopic_indirect_call_target (operands[0]);
10756 #endif
10758   gcc_assert (MEM_P (operands[0]));
10759   gcc_assert (CONST_INT_P (operands[1]));
10761   operands[0] = XEXP (operands[0], 0);
10763   if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10764     rs6000_sibcall_aix (NULL_RTX, operands[0], operands[1], operands[2]);
10765   else if (DEFAULT_ABI == ABI_V4)
10766     rs6000_sibcall_sysv (NULL_RTX, operands[0], operands[1], operands[2]);
10767   else if (DEFAULT_ABI == ABI_DARWIN)
10768     rs6000_sibcall_darwin (NULL_RTX, operands[0], operands[1], operands[2]);
10769   else
10770     gcc_unreachable ();
10772   DONE;
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 (MEM_P (operands[1]));
10789   gcc_assert (CONST_INT_P (operands[2]));
10791   operands[1] = XEXP (operands[1], 0);
10793   if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10794     rs6000_sibcall_aix (operands[0], operands[1], operands[2], operands[3]);
10795   else if (DEFAULT_ABI == ABI_V4)
10796     rs6000_sibcall_sysv (operands[0], operands[1], operands[2], operands[3]);
10797   else if (DEFAULT_ABI == ABI_DARWIN)
10798     rs6000_sibcall_darwin (operands[0], operands[1], operands[2], operands[3]);
10799   else
10800     gcc_unreachable ();
10802   DONE;
10805 (define_insn "*sibcall_local32"
10806   [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
10807          (match_operand 1))
10808    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10809    (simple_return)]
10810   "(INTVAL (operands[2]) & CALL_LONG) == 0"
10812   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10813     output_asm_insn ("crxor 6,6,6", operands);
10815   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10816     output_asm_insn ("creqv 6,6,6", operands);
10818   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z0@local" : "b %z0";
10820   [(set_attr "type" "branch")
10821    (set_attr "length" "4,8")])
10823 (define_insn "*sibcall_local64"
10824   [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
10825          (match_operand 1))
10826    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10827    (simple_return)]
10828   "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
10830   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10831     output_asm_insn ("crxor 6,6,6", operands);
10833   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10834     output_asm_insn ("creqv 6,6,6", operands);
10836   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z0@local" : "b %z0";
10838   [(set_attr "type" "branch")
10839    (set_attr "length" "4,8")])
10841 (define_insn "*sibcall_value_local32"
10842   [(set (match_operand 0 "" "")
10843         (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
10844               (match_operand 2)))
10845    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10846    (simple_return)]
10847   "(INTVAL (operands[3]) & CALL_LONG) == 0"
10849   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10850     output_asm_insn ("crxor 6,6,6", operands);
10852   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10853     output_asm_insn ("creqv 6,6,6", operands);
10855   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z1@local" : "b %z1";
10857   [(set_attr "type" "branch")
10858    (set_attr "length" "4,8")])
10860 (define_insn "*sibcall_value_local64"
10861   [(set (match_operand 0 "" "")
10862         (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
10863               (match_operand 2)))
10864    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10865    (simple_return)]
10866   "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
10868   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10869     output_asm_insn ("crxor 6,6,6", operands);
10871   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10872     output_asm_insn ("creqv 6,6,6", operands);
10874   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z1@local" : "b %z1";
10876   [(set_attr "type" "branch")
10877    (set_attr "length" "4,8")])
10879 (define_insn "*sibcall_indirect_nonlocal_sysv<mode>"
10880   [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X"))
10881          (match_operand 1))
10882    (use (match_operand:SI 2 "immediate_operand" "n,n,n"))
10883    (simple_return)]
10884   "DEFAULT_ABI == ABI_V4
10885    || DEFAULT_ABI == ABI_DARWIN"
10887   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10888     output_asm_insn ("crxor 6,6,6", operands);
10890   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10891     output_asm_insn ("creqv 6,6,6", operands);
10893   return rs6000_indirect_sibcall_template (operands, 0);
10895   [(set_attr "type" "jmpreg")
10896    (set (attr "length")
10897         (cond [(and (and (match_test "!rs6000_speculate_indirect_jumps")
10898                          (match_test "which_alternative != 1"))
10899                     (match_test "(INTVAL (operands[2]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
10900                   (const_string "12")
10901                (ior (and (match_test "!rs6000_speculate_indirect_jumps")
10902                          (match_test "which_alternative != 1"))
10903                    (match_test "(INTVAL (operands[2]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
10904                   (const_string "8")]
10905               (const_string "4")))])
10907 (define_insn "*sibcall_nonlocal_sysv<mode>"
10908   [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
10909          (match_operand 1))
10910    (use (match_operand 2 "immediate_operand" "O,n"))
10911    (simple_return)]
10912   "(DEFAULT_ABI == ABI_DARWIN
10913     || DEFAULT_ABI == ABI_V4)
10914    && (INTVAL (operands[2]) & CALL_LONG) == 0"
10916   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10917     output_asm_insn ("crxor 6,6,6", operands);
10919   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10920     output_asm_insn ("creqv 6,6,6", operands);
10922   return rs6000_sibcall_template (operands, 0);
10924   [(set_attr "type" "branch")
10925    (set_attr "length" "4,8")])
10927 (define_insn "*sibcall_value_indirect_nonlocal_sysv<mode>"
10928   [(set (match_operand 0 "" "")
10929         (call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X"))
10930               (match_operand 2)))
10931    (use (match_operand:SI 3 "immediate_operand" "n,n,n"))
10932    (simple_return)]
10933   "DEFAULT_ABI == ABI_V4
10934    || DEFAULT_ABI == ABI_DARWIN"
10936   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10937     output_asm_insn ("crxor 6,6,6", operands);
10939   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10940     output_asm_insn ("creqv 6,6,6", operands);
10942   return rs6000_indirect_sibcall_template (operands, 1);
10944   [(set_attr "type" "jmpreg")
10945    (set (attr "length")
10946         (cond [(and (and (match_test "!rs6000_speculate_indirect_jumps")
10947                          (match_test "which_alternative != 1"))
10948                     (match_test "(INTVAL (operands[3]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
10949                   (const_string "12")
10950                (ior (and (match_test "!rs6000_speculate_indirect_jumps")
10951                          (match_test "which_alternative != 1"))
10952                    (match_test "(INTVAL (operands[3]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
10953                   (const_string "8")]
10954               (const_string "4")))])
10956 (define_insn "*sibcall_value_nonlocal_sysv<mode>"
10957   [(set (match_operand 0 "" "")
10958         (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
10959               (match_operand 2)))
10960    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10961    (simple_return)]
10962   "(DEFAULT_ABI == ABI_DARWIN
10963     || DEFAULT_ABI == ABI_V4)
10964    && (INTVAL (operands[3]) & CALL_LONG) == 0"
10966   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10967     output_asm_insn ("crxor 6,6,6", operands);
10969   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10970     output_asm_insn ("creqv 6,6,6", operands);
10972   return rs6000_sibcall_template (operands, 1);
10974   [(set_attr "type" "branch")
10975    (set_attr "length" "4,8")])
10977 ;; AIX ABI sibling call patterns.
10979 (define_insn "*sibcall_aix<mode>"
10980   [(call (mem:SI (match_operand:P 0 "call_operand" "s,c"))
10981          (match_operand 1))
10982    (simple_return)]
10983   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10985   if (which_alternative == 0)
10986     return rs6000_sibcall_template (operands, 0);
10987   else
10988     return "b%T0";
10990   [(set_attr "type" "branch")])
10992 (define_insn "*sibcall_value_aix<mode>"
10993   [(set (match_operand 0 "" "")
10994         (call (mem:SI (match_operand:P 1 "call_operand" "s,c"))
10995               (match_operand 2)))
10996    (simple_return)]
10997   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10999   if (which_alternative == 0)
11000     return rs6000_sibcall_template (operands, 1);
11001   else
11002     return "b%T1";
11004   [(set_attr "type" "branch")])
11006 (define_expand "sibcall_epilogue"
11007   [(use (const_int 0))]
11008   ""
11010   if (!TARGET_SCHED_PROLOG)
11011     emit_insn (gen_blockage ());
11012   rs6000_emit_epilogue (EPILOGUE_TYPE_SIBCALL);
11013   DONE;
11016 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11017 ;; all of memory.  This blocks insns from being moved across this point.
11019 (define_insn "blockage"
11020   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCK)]
11021   ""
11022   ""
11023   [(set_attr "length" "0")])
11025 (define_expand "probe_stack_address"
11026   [(use (match_operand 0 "address_operand"))]
11027   ""
11029   operands[0] = gen_rtx_MEM (Pmode, operands[0]);
11030   MEM_VOLATILE_P (operands[0]) = 1;
11032   if (TARGET_64BIT)
11033     emit_insn (gen_probe_stack_di (operands[0]));
11034   else
11035     emit_insn (gen_probe_stack_si (operands[0]));
11036   DONE;
11039 (define_insn "probe_stack_<mode>"
11040   [(set (match_operand:P 0 "memory_operand" "=m")
11041         (unspec:P [(const_int 0)] UNSPEC_PROBE_STACK))]
11042   ""
11044   operands[1] = gen_rtx_REG (Pmode, 0);
11045   return "st<wd>%U0%X0 %1,%0";
11047   [(set_attr "type" "store")
11048    (set (attr "update")
11049         (if_then_else (match_operand 0 "update_address_mem")
11050                       (const_string "yes")
11051                       (const_string "no")))
11052    (set (attr "indexed")
11053         (if_then_else (match_operand 0 "indexed_address_mem")
11054                       (const_string "yes")
11055                       (const_string "no")))])
11057 (define_insn "probe_stack_range<P:mode>"
11058   [(set (match_operand:P 0 "register_operand" "=&r")
11059         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
11060                             (match_operand:P 2 "register_operand" "r")
11061                             (match_operand:P 3 "register_operand" "r")]
11062                            UNSPECV_PROBE_STACK_RANGE))]
11063   ""
11064   "* return output_probe_stack_range (operands[0], operands[2], operands[3]);"
11065   [(set_attr "type" "three")])
11067 ;; Compare insns are next.  Note that the RS/6000 has two types of compares,
11068 ;; signed & unsigned, and one type of branch.
11070 ;; Start with the DEFINE_EXPANDs to generate the rtl for compares, scc
11071 ;; insns, and branches.
11073 (define_expand "cbranch<mode>4"
11074   [(use (match_operator 0 "comparison_operator"
11075          [(match_operand:GPR 1 "gpc_reg_operand")
11076           (match_operand:GPR 2 "reg_or_short_operand")]))
11077    (use (match_operand 3))]
11078   ""
11080   /* Take care of the possibility that operands[2] might be negative but
11081      this might be a logical operation.  That insn doesn't exist.  */
11082   if (CONST_INT_P (operands[2])
11083       && INTVAL (operands[2]) < 0)
11084     {
11085       operands[2] = force_reg (<MODE>mode, operands[2]);
11086       operands[0] = gen_rtx_fmt_ee (GET_CODE (operands[0]),
11087                                     GET_MODE (operands[0]),
11088                                     operands[1], operands[2]);
11089    }
11091   rs6000_emit_cbranch (<MODE>mode, operands);
11092   DONE;
11095 (define_expand "cbranch<mode>4"
11096   [(use (match_operator 0 "comparison_operator"
11097          [(match_operand:FP 1 "gpc_reg_operand")
11098           (match_operand:FP 2 "gpc_reg_operand")]))
11099    (use (match_operand 3))]
11100   ""
11102   rs6000_emit_cbranch (<MODE>mode, operands);
11103   DONE;
11106 (define_expand "cstore<mode>4_signed"
11107   [(use (match_operator 1 "signed_comparison_operator"
11108          [(match_operand:P 2 "gpc_reg_operand")
11109           (match_operand:P 3 "gpc_reg_operand")]))
11110    (clobber (match_operand:P 0 "gpc_reg_operand"))]
11111   ""
11113   enum rtx_code cond_code = GET_CODE (operands[1]);
11115   rtx op0 = operands[0];
11116   rtx op1 = operands[2];
11117   rtx op2 = operands[3];
11119   if (cond_code == GE || cond_code == LT)
11120     {
11121       cond_code = swap_condition (cond_code);
11122       std::swap (op1, op2);
11123     }
11125   rtx tmp1 = gen_reg_rtx (<MODE>mode);
11126   rtx tmp2 = gen_reg_rtx (<MODE>mode);
11127   rtx tmp3 = gen_reg_rtx (<MODE>mode);
11129   int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11130   emit_insn (gen_lshr<mode>3 (tmp1, op1, GEN_INT (sh)));
11131   emit_insn (gen_ashr<mode>3 (tmp2, op2, GEN_INT (sh)));
11133   emit_insn (gen_subf<mode>3_carry (tmp3, op1, op2));
11135   if (cond_code == LE)
11136     emit_insn (gen_add<mode>3_carry_in (op0, tmp1, tmp2));
11137   else
11138     {
11139       rtx tmp4 = gen_reg_rtx (<MODE>mode);
11140       emit_insn (gen_add<mode>3_carry_in (tmp4, tmp1, tmp2));
11141       emit_insn (gen_xor<mode>3 (op0, tmp4, const1_rtx));
11142     }
11144   DONE;
11147 (define_expand "cstore<mode>4_unsigned"
11148   [(use (match_operator 1 "unsigned_comparison_operator"
11149          [(match_operand:P 2 "gpc_reg_operand")
11150           (match_operand:P 3 "reg_or_short_operand")]))
11151    (clobber (match_operand:P 0 "gpc_reg_operand"))]
11152   ""
11154   enum rtx_code cond_code = GET_CODE (operands[1]);
11156   rtx op0 = operands[0];
11157   rtx op1 = operands[2];
11158   rtx op2 = operands[3];
11160   if (cond_code == GEU || cond_code == LTU)
11161     {
11162       cond_code = swap_condition (cond_code);
11163       std::swap (op1, op2);
11164     }
11166   if (!gpc_reg_operand (op1, <MODE>mode))
11167     op1 = force_reg (<MODE>mode, op1);
11168   if (!reg_or_short_operand (op2, <MODE>mode))
11169     op2 = force_reg (<MODE>mode, op2);
11171   rtx tmp = gen_reg_rtx (<MODE>mode);
11172   rtx tmp2 = gen_reg_rtx (<MODE>mode);
11174   emit_insn (gen_subf<mode>3_carry (tmp, op1, op2));
11175   emit_insn (gen_subf<mode>3_carry_in_xx (tmp2));
11177   if (cond_code == LEU)
11178     emit_insn (gen_add<mode>3 (op0, tmp2, const1_rtx));
11179   else
11180     emit_insn (gen_neg<mode>2 (op0, tmp2));
11182   DONE;
11185 (define_expand "cstore_si_as_di"
11186   [(use (match_operator 1 "unsigned_comparison_operator"
11187          [(match_operand:SI 2 "gpc_reg_operand")
11188           (match_operand:SI 3 "reg_or_short_operand")]))
11189    (clobber (match_operand:SI 0 "gpc_reg_operand"))]
11190   ""
11192   int uns_flag = unsigned_comparison_operator (operands[1], VOIDmode) ? 1 : 0;
11193   enum rtx_code cond_code = signed_condition (GET_CODE (operands[1]));
11195   operands[2] = force_reg (SImode, operands[2]);
11196   operands[3] = force_reg (SImode, operands[3]);
11197   rtx op1 = gen_reg_rtx (DImode);
11198   rtx op2 = gen_reg_rtx (DImode);
11199   convert_move (op1, operands[2], uns_flag);
11200   convert_move (op2, operands[3], uns_flag);
11202   if (cond_code == GT || cond_code == LE)
11203     {
11204       cond_code = swap_condition (cond_code);
11205       std::swap (op1, op2);
11206     }
11208   rtx tmp = gen_reg_rtx (DImode);
11209   rtx tmp2 = gen_reg_rtx (DImode);
11210   emit_insn (gen_subdi3 (tmp, op1, op2));
11211   emit_insn (gen_lshrdi3 (tmp2, tmp, GEN_INT (63)));
11213   rtx tmp3;
11214   switch (cond_code)
11215     {
11216     default:
11217       gcc_unreachable ();
11218     case LT:
11219       tmp3 = tmp2;
11220       break;
11221     case GE:
11222       tmp3 = gen_reg_rtx (DImode);
11223       emit_insn (gen_xordi3 (tmp3, tmp2, const1_rtx));
11224       break;
11225     }
11227   convert_move (operands[0], tmp3, 1);
11229   DONE;
11232 (define_expand "cstore<mode>4_signed_imm"
11233   [(use (match_operator 1 "signed_comparison_operator"
11234          [(match_operand:GPR 2 "gpc_reg_operand")
11235           (match_operand:GPR 3 "immediate_operand")]))
11236    (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11237   ""
11239   bool invert = false;
11241   enum rtx_code cond_code = GET_CODE (operands[1]);
11243   rtx op0 = operands[0];
11244   rtx op1 = operands[2];
11245   HOST_WIDE_INT val = INTVAL (operands[3]);
11247   if (cond_code == GE || cond_code == GT)
11248     {
11249       cond_code = reverse_condition (cond_code);
11250       invert = true;
11251     }
11253   if (cond_code == LE)
11254     val++;
11256   rtx tmp = gen_reg_rtx (<MODE>mode);
11257   emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
11258   rtx x = gen_reg_rtx (<MODE>mode);
11259   if (val < 0)
11260     emit_insn (gen_and<mode>3 (x, op1, tmp));
11261   else
11262     emit_insn (gen_ior<mode>3 (x, op1, tmp));
11264   if (invert)
11265     {
11266       rtx tmp = gen_reg_rtx (<MODE>mode);
11267       emit_insn (gen_one_cmpl<mode>2 (tmp, x));
11268       x = tmp;
11269     }
11271   int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11272   emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
11274   DONE;
11277 (define_expand "cstore<mode>4_unsigned_imm"
11278   [(use (match_operator 1 "unsigned_comparison_operator"
11279          [(match_operand:GPR 2 "gpc_reg_operand")
11280           (match_operand:GPR 3 "immediate_operand")]))
11281    (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11282   ""
11284   bool invert = false;
11286   enum rtx_code cond_code = GET_CODE (operands[1]);
11288   rtx op0 = operands[0];
11289   rtx op1 = operands[2];
11290   HOST_WIDE_INT val = INTVAL (operands[3]);
11292   if (cond_code == GEU || cond_code == GTU)
11293     {
11294       cond_code = reverse_condition (cond_code);
11295       invert = true;
11296     }
11298   if (cond_code == LEU)
11299     val++;
11301   rtx tmp = gen_reg_rtx (<MODE>mode);
11302   rtx tmp2 = gen_reg_rtx (<MODE>mode);
11303   emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
11304   emit_insn (gen_one_cmpl<mode>2 (tmp2, op1));
11305   rtx x = gen_reg_rtx (<MODE>mode);
11306   if (val < 0)
11307     emit_insn (gen_ior<mode>3 (x, tmp, tmp2));
11308   else
11309     emit_insn (gen_and<mode>3 (x, tmp, tmp2));
11311   if (invert)
11312     {
11313       rtx tmp = gen_reg_rtx (<MODE>mode);
11314       emit_insn (gen_one_cmpl<mode>2 (tmp, x));
11315       x = tmp;
11316     }
11318   int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11319   emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
11321   DONE;
11324 (define_expand "cstore<mode>4"
11325   [(use (match_operator 1 "comparison_operator"
11326          [(match_operand:GPR 2 "gpc_reg_operand")
11327           (match_operand:GPR 3 "reg_or_short_operand")]))
11328    (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11329   ""
11331   /* Expanding EQ and NE directly to some machine instructions does not help
11332      but does hurt combine.  So don't.  */
11333   if (GET_CODE (operands[1]) == EQ)
11334     emit_insn (gen_eq<mode>3 (operands[0], operands[2], operands[3]));
11335   else if (<MODE>mode == Pmode
11336            && GET_CODE (operands[1]) == NE)
11337     emit_insn (gen_ne<mode>3 (operands[0], operands[2], operands[3]));
11338   else if (GET_CODE (operands[1]) == NE)
11339     {
11340       rtx tmp = gen_reg_rtx (<MODE>mode);
11341       emit_insn (gen_eq<mode>3 (tmp, operands[2], operands[3]));
11342       emit_insn (gen_xor<mode>3 (operands[0], tmp, const1_rtx));
11343     }
11345   /* If ISEL is fast, expand to it.  */
11346   else if (TARGET_ISEL)
11347     rs6000_emit_int_cmove (operands[0], operands[1], const1_rtx, const0_rtx);
11349   /* Expanding the unsigned comparisons helps a lot: all the neg_ltu
11350      etc. combinations magically work out just right.  */
11351   else if (<MODE>mode == Pmode
11352            && unsigned_comparison_operator (operands[1], VOIDmode))
11353     emit_insn (gen_cstore<mode>4_unsigned (operands[0], operands[1],
11354                                            operands[2], operands[3]));
11356   /* For comparisons smaller than Pmode we can cheaply do things in Pmode.  */
11357   else if (<MODE>mode == SImode && Pmode == DImode)
11358     emit_insn (gen_cstore_si_as_di (operands[0], operands[1],
11359                                     operands[2], operands[3]));
11361   /* For signed comparisons against a constant, we can do some simple
11362      bit-twiddling.  */
11363   else if (signed_comparison_operator (operands[1], VOIDmode)
11364            && CONST_INT_P (operands[3]))
11365     emit_insn (gen_cstore<mode>4_signed_imm (operands[0], operands[1],
11366                                              operands[2], operands[3]));
11368   /* And similarly for unsigned comparisons.  */
11369   else if (unsigned_comparison_operator (operands[1], VOIDmode)
11370            && CONST_INT_P (operands[3]))
11371     emit_insn (gen_cstore<mode>4_unsigned_imm (operands[0], operands[1],
11372                                                operands[2], operands[3]));
11374   /* We also do not want to use mfcr for signed comparisons.  */
11375   else if (<MODE>mode == Pmode
11376            && signed_comparison_operator (operands[1], VOIDmode))
11377     emit_insn (gen_cstore<mode>4_signed (operands[0], operands[1],
11378                                          operands[2], operands[3]));
11380   /* Everything else, use the mfcr brute force.  */
11381   else
11382     rs6000_emit_sCOND (<MODE>mode, operands);
11384   DONE;
11387 (define_expand "cstore<mode>4"
11388   [(use (match_operator 1 "comparison_operator"
11389          [(match_operand:FP 2 "gpc_reg_operand")
11390           (match_operand:FP 3 "gpc_reg_operand")]))
11391    (clobber (match_operand:SI 0 "gpc_reg_operand"))]
11392   ""
11394   rs6000_emit_sCOND (<MODE>mode, operands);
11395   DONE;
11399 (define_expand "stack_protect_set"
11400   [(match_operand 0 "memory_operand")
11401    (match_operand 1 "memory_operand")]
11402   ""
11404   if (rs6000_stack_protector_guard == SSP_TLS)
11405     {
11406       rtx reg = gen_rtx_REG (Pmode, rs6000_stack_protector_guard_reg);
11407       rtx offset = GEN_INT (rs6000_stack_protector_guard_offset);
11408       rtx addr = gen_rtx_PLUS (Pmode, reg, offset);
11409       operands[1] = gen_rtx_MEM (Pmode, addr);
11410     }
11412   if (TARGET_64BIT)
11413     emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
11414   else
11415     emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
11417   DONE;
11420 (define_insn "stack_protect_setsi"
11421   [(set (match_operand:SI 0 "memory_operand" "=m")
11422         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
11423    (set (match_scratch:SI 2 "=&r") (const_int 0))]
11424   "TARGET_32BIT"
11425   "lwz%U1%X1 %2,%1\;stw%U0%X0 %2,%0\;li %2,0"
11426   [(set_attr "type" "three")
11427    (set_attr "length" "12")])
11429 (define_insn "stack_protect_setdi"
11430   [(set (match_operand:DI 0 "memory_operand" "=Y")
11431         (unspec:DI [(match_operand:DI 1 "memory_operand" "Y")] UNSPEC_SP_SET))
11432    (set (match_scratch:DI 2 "=&r") (const_int 0))]
11433   "TARGET_64BIT"
11434   "ld%U1%X1 %2,%1\;std%U0%X0 %2,%0\;li %2,0"
11435   [(set_attr "type" "three")
11436    (set_attr "length" "12")])
11438 (define_expand "stack_protect_test"
11439   [(match_operand 0 "memory_operand")
11440    (match_operand 1 "memory_operand")
11441    (match_operand 2 "")]
11442   ""
11444   rtx guard = operands[1];
11446   if (rs6000_stack_protector_guard == SSP_TLS)
11447     {
11448       rtx reg = gen_rtx_REG (Pmode, rs6000_stack_protector_guard_reg);
11449       rtx offset = GEN_INT (rs6000_stack_protector_guard_offset);
11450       rtx addr = gen_rtx_PLUS (Pmode, reg, offset);
11451       guard = gen_rtx_MEM (Pmode, addr);
11452     }
11454   operands[1] = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, guard), UNSPEC_SP_TEST);
11455   rtx test = gen_rtx_EQ (VOIDmode, operands[0], operands[1]);
11456   rtx jump = gen_cbranchsi4 (test, operands[0], operands[1], operands[2]);
11457   emit_jump_insn (jump);
11459   DONE;
11462 (define_insn "stack_protect_testsi"
11463   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
11464         (unspec:CCEQ [(match_operand:SI 1 "memory_operand" "m,m")
11465                       (match_operand:SI 2 "memory_operand" "m,m")]
11466                      UNSPEC_SP_TEST))
11467    (set (match_scratch:SI 4 "=r,r") (const_int 0))
11468    (clobber (match_scratch:SI 3 "=&r,&r"))]
11469   "TARGET_32BIT"
11470   "@
11471    lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0
11472    lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;cmplw %0,%3,%4\;li %3,0\;li %4,0"
11473   [(set_attr "length" "16,20")])
11475 (define_insn "stack_protect_testdi"
11476   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
11477         (unspec:CCEQ [(match_operand:DI 1 "memory_operand" "Y,Y")
11478                       (match_operand:DI 2 "memory_operand" "Y,Y")]
11479                      UNSPEC_SP_TEST))
11480    (set (match_scratch:DI 4 "=r,r") (const_int 0))
11481    (clobber (match_scratch:DI 3 "=&r,&r"))]
11482   "TARGET_64BIT"
11483   "@
11484    ld%U1%X1 %3,%1\;ld%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0
11485    ld%U1%X1 %3,%1\;ld%U2%X2 %4,%2\;cmpld %0,%3,%4\;li %3,0\;li %4,0"
11486   [(set_attr "length" "16,20")])
11489 ;; Here are the actual compare insns.
11490 (define_insn "*cmp<mode>_signed"
11491   [(set (match_operand:CC 0 "cc_reg_operand" "=y")
11492         (compare:CC (match_operand:GPR 1 "gpc_reg_operand" "r")
11493                     (match_operand:GPR 2 "reg_or_short_operand" "rI")))]
11494   ""
11495   "cmp<wd>%I2 %0,%1,%2"
11496   [(set_attr "type" "cmp")])
11498 (define_insn "*cmp<mode>_unsigned"
11499   [(set (match_operand:CCUNS 0 "cc_reg_operand" "=y")
11500         (compare:CCUNS (match_operand:GPR 1 "gpc_reg_operand" "r")
11501                        (match_operand:GPR 2 "reg_or_u_short_operand" "rK")))]
11502   ""
11503   "cmpl<wd>%I2 %0,%1,%2"
11504   [(set_attr "type" "cmp")])
11506 ;; If we are comparing a register for equality with a large constant,
11507 ;; we can do this with an XOR followed by a compare.  But this is profitable
11508 ;; only if the large constant is only used for the comparison (and in this
11509 ;; case we already have a register to reuse as scratch).
11511 ;; For 64-bit registers, we could only do so if the constant's bit 15 is clear:
11512 ;; otherwise we'd need to XOR with FFFFFFFF????0000 which is not available.
11514 (define_peephole2
11515   [(set (match_operand:SI 0 "register_operand")
11516         (match_operand:SI 1 "logical_const_operand"))
11517    (set (match_dup 0) (match_operator:SI 3 "boolean_or_operator"
11518                        [(match_dup 0)
11519                         (match_operand:SI 2 "logical_const_operand")]))
11520    (set (match_operand:CC 4 "cc_reg_operand")
11521         (compare:CC (match_operand:SI 5 "gpc_reg_operand")
11522                     (match_dup 0)))
11523    (set (pc)
11524         (if_then_else (match_operator 6 "equality_operator"
11525                        [(match_dup 4) (const_int 0)])
11526                       (match_operand 7 "")
11527                       (match_operand 8 "")))]
11528   "peep2_reg_dead_p (3, operands[0])
11529    && peep2_reg_dead_p (4, operands[4])
11530    && REGNO (operands[0]) != REGNO (operands[5])"
11531  [(set (match_dup 0) (xor:SI (match_dup 5) (match_dup 9)))
11532   (set (match_dup 4) (compare:CC (match_dup 0) (match_dup 10)))
11533   (set (pc) (if_then_else (match_dup 6) (match_dup 7) (match_dup 8)))]
11536   /* Get the constant we are comparing against, and see what it looks like
11537      when sign-extended from 16 to 32 bits.  Then see what constant we could
11538      XOR with SEXTC to get the sign-extended value.  */
11539   rtx cnst = simplify_const_binary_operation (GET_CODE (operands[3]),
11540                                               SImode,
11541                                               operands[1], operands[2]);
11542   HOST_WIDE_INT c = INTVAL (cnst);
11543   HOST_WIDE_INT sextc = ((c & 0xffff) ^ 0x8000) - 0x8000;
11544   HOST_WIDE_INT xorv = c ^ sextc;
11546   operands[9] = GEN_INT (xorv);
11547   operands[10] = GEN_INT (sextc);
11550 ;; Only need to compare second words if first words equal
11551 (define_insn "*cmp<mode>_internal1"
11552   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
11553         (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
11554                       (match_operand:IBM128 2 "gpc_reg_operand" "d")))]
11555   "!TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode)
11556    && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
11557   "fcmpu %0,%1,%2\;bne %0,$+8\;fcmpu %0,%L1,%L2"
11558   [(set_attr "type" "fpcompare")
11559    (set_attr "length" "12")])
11561 (define_insn_and_split "*cmp<mode>_internal2"
11562   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
11563         (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
11564                       (match_operand:IBM128 2 "gpc_reg_operand" "d")))
11565     (clobber (match_scratch:DF 3 "=d"))
11566     (clobber (match_scratch:DF 4 "=d"))
11567     (clobber (match_scratch:DF 5 "=d"))
11568     (clobber (match_scratch:DF 6 "=d"))
11569     (clobber (match_scratch:DF 7 "=d"))
11570     (clobber (match_scratch:DF 8 "=d"))
11571     (clobber (match_scratch:DF 9 "=d"))
11572     (clobber (match_scratch:DF 10 "=d"))
11573     (clobber (match_scratch:GPR 11 "=b"))]
11574   "TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode)
11575    && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
11576   "#"
11577   "&& reload_completed"
11578   [(set (match_dup 3) (match_dup 14))
11579    (set (match_dup 4) (match_dup 15))
11580    (set (match_dup 9) (abs:DF (match_dup 5)))
11581    (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 3)))
11582    (set (pc) (if_then_else (ne (match_dup 0) (const_int 0))
11583                            (label_ref (match_dup 12))
11584                            (pc)))
11585    (set (match_dup 0) (compare:CCFP (match_dup 5) (match_dup 7)))
11586    (set (pc) (label_ref (match_dup 13)))
11587    (match_dup 12)
11588    (set (match_dup 10) (minus:DF (match_dup 5) (match_dup 7)))
11589    (set (match_dup 9) (minus:DF (match_dup 6) (match_dup 8)))
11590    (set (match_dup 9) (plus:DF (match_dup 10) (match_dup 9)))
11591    (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 4)))
11592    (match_dup 13)]
11594   REAL_VALUE_TYPE rv;
11595   const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
11596   const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
11598   operands[5] = simplify_gen_subreg (DFmode, operands[1], <MODE>mode, hi_word);
11599   operands[6] = simplify_gen_subreg (DFmode, operands[1], <MODE>mode, lo_word);
11600   operands[7] = simplify_gen_subreg (DFmode, operands[2], <MODE>mode, hi_word);
11601   operands[8] = simplify_gen_subreg (DFmode, operands[2], <MODE>mode, lo_word);
11602   operands[12] = gen_label_rtx ();
11603   operands[13] = gen_label_rtx ();
11604   real_inf (&rv);
11605   operands[14] = force_const_mem (DFmode,
11606                                   const_double_from_real_value (rv, DFmode));
11607   operands[15] = force_const_mem (DFmode,
11608                                   const_double_from_real_value (dconst0,
11609                                                                 DFmode));
11610   if (TARGET_TOC)
11611     {
11612       rtx tocref;
11613       tocref = create_TOC_reference (XEXP (operands[14], 0), operands[11]);
11614       operands[14] = gen_const_mem (DFmode, tocref);
11615       tocref = create_TOC_reference (XEXP (operands[15], 0), operands[11]);
11616       operands[15] = gen_const_mem (DFmode, tocref);
11617       set_mem_alias_set (operands[14], get_TOC_alias_set ());
11618       set_mem_alias_set (operands[15], get_TOC_alias_set ());
11619     }
11622 ;; Now we have the scc insns.  We can do some combinations because of the
11623 ;; way the machine works.
11625 ;; Note that this is probably faster if we can put an insn between the
11626 ;; mfcr and rlinm, but this is tricky.  Let's leave it for now.  In most
11627 ;; cases the insns below which don't use an intermediate CR field will
11628 ;; be used instead.
11629 (define_insn ""
11630   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
11631         (match_operator:GPR 1 "scc_comparison_operator"
11632                             [(match_operand 2 "cc_reg_operand" "y")
11633                              (const_int 0)]))]
11634   ""
11635   "mfcr %0%Q2\;rlwinm %0,%0,%J1,1"
11636   [(set (attr "type")
11637      (cond [(match_test "TARGET_MFCRF")
11638                 (const_string "mfcrf")
11639            ]
11640         (const_string "mfcr")))
11641    (set_attr "length" "8")])
11643 (define_insn_and_split ""
11644   [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
11645         (compare:CC (match_operator:SI 1 "scc_comparison_operator"
11646                                        [(match_operand 2 "cc_reg_operand" "y,y")
11647                                         (const_int 0)])
11648                     (const_int 0)))
11649    (set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
11650         (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
11651   "TARGET_32BIT"
11652   "@
11653    mfcr %3%Q2\;rlwinm. %3,%3,%J1,1
11654    #"
11655   "&& reload_completed"
11656   [(set (match_dup 3)
11657         (match_op_dup 1 [(match_dup 2) (const_int 0)]))
11658    (set (match_dup 0)
11659         (compare:CC (match_dup 3)
11660                     (const_int 0)))]
11661   ""
11662   [(set_attr "type" "shift")
11663    (set_attr "dot" "yes")
11664    (set_attr "length" "8,16")])
11666 (define_insn ""
11667   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11668         (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
11669                                       [(match_operand 2 "cc_reg_operand" "y")
11670                                        (const_int 0)])
11671                    (match_operand:SI 3 "const_int_operand" "n")))]
11672   ""
11674   int is_bit = ccr_bit (operands[1], 1);
11675   int put_bit = 31 - (INTVAL (operands[3]) & 31);
11676   int count;
11678   gcc_assert (is_bit != -1);
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   gcc_assert (is_bit != -1);
11714   /* Force split for non-cc0 compare.  */
11715   if (which_alternative == 1)
11716      return "#";
11718   if (is_bit >= put_bit)
11719     count = is_bit - put_bit;
11720   else
11721     count = 32 - (put_bit - is_bit);
11723   operands[5] = GEN_INT (count);
11724   operands[6] = GEN_INT (put_bit);
11726   return "mfcr %4%Q2\;rlwinm. %4,%4,%5,%6,%6";
11728   [(set_attr "type" "shift")
11729    (set_attr "dot" "yes")
11730    (set_attr "length" "8,16")])
11732 (define_split
11733   [(set (match_operand:CC 0 "cc_reg_not_cr0_operand")
11734         (compare:CC
11735          (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
11736                                        [(match_operand 2 "cc_reg_operand")
11737                                         (const_int 0)])
11738                     (match_operand:SI 3 "const_int_operand"))
11739          (const_int 0)))
11740    (set (match_operand:SI 4 "gpc_reg_operand")
11741         (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
11742                    (match_dup 3)))]
11743   "reload_completed"
11744   [(set (match_dup 4)
11745         (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
11746                    (match_dup 3)))
11747    (set (match_dup 0)
11748         (compare:CC (match_dup 4)
11749                     (const_int 0)))]
11750   "")
11753 (define_code_iterator cmp [eq ne lt ltu gt gtu le leu ge geu])
11754 (define_code_attr UNS [(eq "CC")
11755                        (ne "CC")
11756                        (lt "CC") (ltu "CCUNS")
11757                        (gt "CC") (gtu "CCUNS")
11758                        (le "CC") (leu "CCUNS")
11759                        (ge "CC") (geu "CCUNS")])
11760 (define_code_attr UNSu_ [(eq "")
11761                          (ne "")
11762                          (lt "") (ltu "u_")
11763                          (gt "") (gtu "u_")
11764                          (le "") (leu "u_")
11765                          (ge "") (geu "u_")])
11766 (define_code_attr UNSIK [(eq "I")
11767                          (ne "I")
11768                          (lt "I") (ltu "K")
11769                          (gt "I") (gtu "K")
11770                          (le "I") (leu "K")
11771                          (ge "I") (geu "K")])
11773 (define_insn_and_split "<code><GPR:mode><GPR2:mode>2_isel"
11774   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
11775         (cmp:GPR (match_operand:GPR2 1 "gpc_reg_operand" "r")
11776                  (match_operand:GPR2 2 "reg_or_<cmp:UNSu_>short_operand" "r<cmp:UNSIK>")))
11777    (clobber (match_scratch:GPR 3 "=r"))
11778    (clobber (match_scratch:GPR 4 "=r"))
11779    (clobber (match_scratch:<UNS> 5 "=y"))]
11780   "TARGET_ISEL
11781    && !(<CODE> == EQ && operands[2] == const0_rtx)
11782    && !(<CODE> == NE && operands[2] == const0_rtx
11783         && <GPR:MODE>mode == Pmode && <GPR2:MODE>mode == Pmode)"
11784   "#"
11785   "&& 1"
11786   [(pc)]
11788   rtx_code code = <CODE>;
11789   if (CONST_INT_P (operands[2]) && code != EQ && code != NE)
11790     {
11791       HOST_WIDE_INT val = INTVAL (operands[2]);
11792       if (code == LT && val != -0x8000)
11793         {
11794           code = LE;
11795           val--;
11796         }
11797       if (code == GT && val != 0x7fff)
11798         {
11799           code = GE;
11800           val++;
11801         }
11802       if (code == LTU && val != 0)
11803         {
11804           code = LEU;
11805           val--;
11806         }
11807       if (code == GTU && val != 0xffff)
11808         {
11809           code = GEU;
11810           val++;
11811         }
11812       operands[2] = GEN_INT (val);
11813     }
11815   if (code == NE || code == LE || code == GE || code == LEU || code == GEU)
11816     operands[3] = const0_rtx;
11817   else
11818     {
11819       if (GET_CODE (operands[3]) == SCRATCH)
11820         operands[3] = gen_reg_rtx (<GPR:MODE>mode);
11821       emit_move_insn (operands[3], const0_rtx);
11822     }
11824   if (GET_CODE (operands[4]) == SCRATCH)
11825     operands[4] = gen_reg_rtx (<GPR:MODE>mode);
11826   emit_move_insn (operands[4], const1_rtx);
11828   if (GET_CODE (operands[5]) == SCRATCH)
11829     operands[5] = gen_reg_rtx (<UNS>mode);
11831   rtx c1 = gen_rtx_COMPARE (<UNS>mode, operands[1], operands[2]);
11832   emit_insn (gen_rtx_SET (operands[5], c1));
11834   rtx c2 = gen_rtx_fmt_ee (code, <GPR:MODE>mode, operands[5], const0_rtx);
11835   rtx x = gen_rtx_IF_THEN_ELSE (<GPR:MODE>mode, c2, operands[4], operands[3]);
11836   emit_move_insn (operands[0], x);
11838   DONE;
11840   [(set (attr "cost")
11841         (if_then_else (match_test "(CONST_INT_P (operands[2]) && <CODE> != EQ)
11842                                    || <CODE> == NE
11843                                    || <CODE> == LE || <CODE> == GE
11844                                    || <CODE> == LEU || <CODE> == GEU")
11845                       (const_string "9")
11846                       (const_string "10")))])
11848 (define_mode_attr scc_eq_op2 [(SI "rKLI")
11849                               (DI "rKJI")])
11851 (define_expand "eq<mode>3"
11852   [(parallel [
11853      (set (match_operand:GPR 0 "gpc_reg_operand" "=r")
11854           (eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
11855                   (match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>")))
11856      (clobber (match_scratch:GPR 3 "=r"))
11857      (clobber (match_scratch:GPR 4 "=r"))])]
11858   ""
11860   if (TARGET_ISEL && operands[2] != const0_rtx)
11861     {
11862       emit_insn (gen_eq<mode><mode>2_isel (operands[0], operands[1],
11863                                            operands[2]));
11864       DONE;
11865     }
11868 (define_insn_and_split "*eq<mode>3"
11869   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
11870         (eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
11871                 (match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>")))
11872    (clobber (match_scratch:GPR 3 "=r"))
11873    (clobber (match_scratch:GPR 4 "=r"))]
11874   "!(TARGET_ISEL && operands[2] != const0_rtx)"
11875   "#"
11876   "&& 1"
11877   [(set (match_dup 4)
11878         (clz:GPR (match_dup 3)))
11879    (set (match_dup 0)
11880         (lshiftrt:GPR (match_dup 4)
11881                       (match_dup 5)))]
11883   operands[3] = rs6000_emit_eqne (<MODE>mode,
11884                                   operands[1], operands[2], operands[3]);
11886   if (GET_CODE (operands[4]) == SCRATCH)
11887     operands[4] = gen_reg_rtx (<MODE>mode);
11889   operands[5] = GEN_INT (exact_log2 (GET_MODE_BITSIZE (<MODE>mode)));
11891   [(set (attr "length")
11892         (if_then_else (match_test "operands[2] == const0_rtx")
11893                       (const_string "8")
11894                       (const_string "12")))])
11896 (define_expand "ne<mode>3"
11897   [(parallel [
11898      (set (match_operand:P 0 "gpc_reg_operand" "=r")
11899           (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
11900                 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")))
11901      (clobber (match_scratch:P 3 "=r"))
11902      (clobber (match_scratch:P 4 "=r"))
11903      (clobber (reg:P CA_REGNO))])]
11904   ""
11906   if (TARGET_ISEL && operands[2] != const0_rtx)
11907     {
11908       emit_insn (gen_ne<mode><mode>2_isel (operands[0], operands[1],
11909                                            operands[2]));
11910       DONE;
11911     }
11914 (define_insn_and_split "*ne<mode>3"
11915   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11916         (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
11917               (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")))
11918    (clobber (match_scratch:P 3 "=r"))
11919    (clobber (match_scratch:P 4 "=r"))
11920    (clobber (reg:P CA_REGNO))]
11921   "!(TARGET_ISEL && operands[2] != const0_rtx)"
11922   "#"
11923   "&& 1"
11924   [(parallel [(set (match_dup 4)
11925                    (plus:P (match_dup 3)
11926                            (const_int -1)))
11927               (set (reg:P CA_REGNO)
11928                    (ne:P (match_dup 3)
11929                          (const_int 0)))])
11930    (parallel [(set (match_dup 0)
11931                    (plus:P (plus:P (not:P (match_dup 4))
11932                                    (reg:P CA_REGNO))
11933                            (match_dup 3)))
11934               (clobber (reg:P CA_REGNO))])]
11936   operands[3] = rs6000_emit_eqne (<MODE>mode,
11937                                   operands[1], operands[2], operands[3]);
11939   if (GET_CODE (operands[4]) == SCRATCH)
11940     operands[4] = gen_reg_rtx (<MODE>mode);
11942   [(set (attr "length")
11943         (if_then_else (match_test "operands[2] == const0_rtx")
11944                       (const_string "8")
11945                       (const_string "12")))])
11947 (define_insn_and_split "*neg_eq_<mode>"
11948   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11949         (neg:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
11950                      (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
11951    (clobber (match_scratch:P 3 "=r"))
11952    (clobber (match_scratch:P 4 "=r"))
11953    (clobber (reg:P CA_REGNO))]
11954   ""
11955   "#"
11956   ""
11957   [(parallel [(set (match_dup 4)
11958                    (plus:P (match_dup 3)
11959                            (const_int -1)))
11960               (set (reg:P CA_REGNO)
11961                    (ne:P (match_dup 3)
11962                          (const_int 0)))])
11963    (parallel [(set (match_dup 0)
11964                    (plus:P (reg:P CA_REGNO)
11965                            (const_int -1)))
11966               (clobber (reg:P CA_REGNO))])]
11968   operands[3] = rs6000_emit_eqne (<MODE>mode,
11969                                   operands[1], operands[2], operands[3]);
11971   if (GET_CODE (operands[4]) == SCRATCH)
11972     operands[4] = gen_reg_rtx (<MODE>mode);
11974   [(set (attr "length")
11975         (if_then_else (match_test "operands[2] == const0_rtx")
11976                       (const_string "8")
11977                       (const_string "12")))])
11979 (define_insn_and_split "*neg_ne_<mode>"
11980   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11981         (neg:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
11982                      (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
11983    (clobber (match_scratch:P 3 "=r"))
11984    (clobber (match_scratch:P 4 "=r"))
11985    (clobber (reg:P CA_REGNO))]
11986   ""
11987   "#"
11988   ""
11989   [(parallel [(set (match_dup 4)
11990                    (neg:P (match_dup 3)))
11991               (set (reg:P CA_REGNO)
11992                    (eq:P (match_dup 3)
11993                          (const_int 0)))])
11994    (parallel [(set (match_dup 0)
11995                    (plus:P (reg:P CA_REGNO)
11996                            (const_int -1)))
11997               (clobber (reg:P CA_REGNO))])]
11999   operands[3] = rs6000_emit_eqne (<MODE>mode,
12000                                   operands[1], operands[2], operands[3]);
12002   if (GET_CODE (operands[4]) == SCRATCH)
12003     operands[4] = gen_reg_rtx (<MODE>mode);
12005   [(set (attr "length")
12006         (if_then_else (match_test "operands[2] == const0_rtx")
12007                       (const_string "8")
12008                       (const_string "12")))])
12010 (define_insn_and_split "*plus_eq_<mode>"
12011   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12012         (plus:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12013                       (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
12014                 (match_operand:P 3 "gpc_reg_operand" "r")))
12015    (clobber (match_scratch:P 4 "=r"))
12016    (clobber (match_scratch:P 5 "=r"))
12017    (clobber (reg:P CA_REGNO))]
12018   ""
12019   "#"
12020   ""
12021   [(parallel [(set (match_dup 5)
12022                    (neg:P (match_dup 4)))
12023               (set (reg:P CA_REGNO)
12024                    (eq:P (match_dup 4)
12025                          (const_int 0)))])
12026    (parallel [(set (match_dup 0)
12027                    (plus:P (match_dup 3)
12028                            (reg:P CA_REGNO)))
12029               (clobber (reg:P CA_REGNO))])]
12031   operands[4] = rs6000_emit_eqne (<MODE>mode,
12032                                   operands[1], operands[2], operands[4]);
12034   if (GET_CODE (operands[5]) == SCRATCH)
12035     operands[5] = gen_reg_rtx (<MODE>mode);
12037   [(set (attr "length")
12038         (if_then_else (match_test "operands[2] == const0_rtx")
12039                       (const_string "8")
12040                       (const_string "12")))])
12042 (define_insn_and_split "*plus_ne_<mode>"
12043   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12044         (plus:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12045                       (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
12046                 (match_operand:P 3 "gpc_reg_operand" "r")))
12047    (clobber (match_scratch:P 4 "=r"))
12048    (clobber (match_scratch:P 5 "=r"))
12049    (clobber (reg:P CA_REGNO))]
12050   ""
12051   "#"
12052   ""
12053   [(parallel [(set (match_dup 5)
12054                    (plus:P (match_dup 4)
12055                            (const_int -1)))
12056               (set (reg:P CA_REGNO)
12057                    (ne:P (match_dup 4)
12058                          (const_int 0)))])
12059    (parallel [(set (match_dup 0)
12060                    (plus:P (match_dup 3)
12061                            (reg:P CA_REGNO)))
12062               (clobber (reg:P CA_REGNO))])]
12064   operands[4] = rs6000_emit_eqne (<MODE>mode,
12065                                   operands[1], operands[2], operands[4]);
12067   if (GET_CODE (operands[5]) == SCRATCH)
12068     operands[5] = gen_reg_rtx (<MODE>mode);
12070   [(set (attr "length")
12071         (if_then_else (match_test "operands[2] == const0_rtx")
12072                       (const_string "8")
12073                       (const_string "12")))])
12075 (define_insn_and_split "*minus_eq_<mode>"
12076   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12077         (minus:P (match_operand:P 3 "gpc_reg_operand" "r")
12078                  (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12079                        (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12080    (clobber (match_scratch:P 4 "=r"))
12081    (clobber (match_scratch:P 5 "=r"))
12082    (clobber (reg:P CA_REGNO))]
12083   ""
12084   "#"
12085   ""
12086   [(parallel [(set (match_dup 5)
12087                    (plus:P (match_dup 4)
12088                            (const_int -1)))
12089               (set (reg:P CA_REGNO)
12090                    (ne:P (match_dup 4)
12091                          (const_int 0)))])
12092    (parallel [(set (match_dup 0)
12093                    (plus:P (plus:P (match_dup 3)
12094                                    (reg:P CA_REGNO))
12095                            (const_int -1)))
12096               (clobber (reg:P CA_REGNO))])]
12098   operands[4] = rs6000_emit_eqne (<MODE>mode,
12099                                   operands[1], operands[2], operands[4]);
12101   if (GET_CODE (operands[5]) == SCRATCH)
12102     operands[5] = gen_reg_rtx (<MODE>mode);
12104   [(set (attr "length")
12105         (if_then_else (match_test "operands[2] == const0_rtx")
12106                       (const_string "8")
12107                       (const_string "12")))])
12109 (define_insn_and_split "*minus_ne_<mode>"
12110   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12111         (minus:P (match_operand:P 3 "gpc_reg_operand" "r")
12112                  (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12113                        (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12114    (clobber (match_scratch:P 4 "=r"))
12115    (clobber (match_scratch:P 5 "=r"))
12116    (clobber (reg:P CA_REGNO))]
12117   ""
12118   "#"
12119   ""
12120   [(parallel [(set (match_dup 5)
12121                    (neg:P (match_dup 4)))
12122               (set (reg:P CA_REGNO)
12123                    (eq:P (match_dup 4)
12124                          (const_int 0)))])
12125    (parallel [(set (match_dup 0)
12126                    (plus:P (plus:P (match_dup 3)
12127                                    (reg:P CA_REGNO))
12128                            (const_int -1)))
12129               (clobber (reg:P CA_REGNO))])]
12131   operands[4] = rs6000_emit_eqne (<MODE>mode,
12132                                   operands[1], operands[2], operands[4]);
12134   if (GET_CODE (operands[5]) == SCRATCH)
12135     operands[5] = gen_reg_rtx (<MODE>mode);
12137   [(set (attr "length")
12138         (if_then_else (match_test "operands[2] == const0_rtx")
12139                       (const_string "8")
12140                       (const_string "12")))])
12142 (define_insn_and_split "*eqsi3_ext<mode>"
12143   [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
12144         (eq:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
12145                   (match_operand:SI 2 "scc_eq_operand" "rKLI")))
12146    (clobber (match_scratch:SI 3 "=r"))
12147    (clobber (match_scratch:SI 4 "=r"))]
12148   ""
12149   "#"
12150   ""
12151   [(set (match_dup 4)
12152         (clz:SI (match_dup 3)))
12153    (set (match_dup 0)
12154         (zero_extend:EXTSI
12155           (lshiftrt:SI (match_dup 4)
12156                        (const_int 5))))]
12158   operands[3] = rs6000_emit_eqne (SImode,
12159                                   operands[1], operands[2], operands[3]);
12161   if (GET_CODE (operands[4]) == SCRATCH)
12162     operands[4] = gen_reg_rtx (SImode);
12164   [(set (attr "length")
12165         (if_then_else (match_test "operands[2] == const0_rtx")
12166                       (const_string "8")
12167                       (const_string "12")))])
12169 (define_insn_and_split "*nesi3_ext<mode>"
12170   [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
12171         (ne:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
12172                   (match_operand:SI 2 "scc_eq_operand" "rKLI")))
12173    (clobber (match_scratch:SI 3 "=r"))
12174    (clobber (match_scratch:SI 4 "=r"))
12175    (clobber (match_scratch:EXTSI 5 "=r"))]
12176   "!TARGET_ISEL"
12177   "#"
12178   "&& 1"
12179   [(set (match_dup 4)
12180         (clz:SI (match_dup 3)))
12181    (set (match_dup 5)
12182         (zero_extend:EXTSI
12183           (lshiftrt:SI (match_dup 4)
12184                        (const_int 5))))
12185    (set (match_dup 0)
12186         (xor:EXTSI (match_dup 5)
12187                    (const_int 1)))]
12189   operands[3] = rs6000_emit_eqne (SImode,
12190                                   operands[1], operands[2], operands[3]);
12192   if (GET_CODE (operands[4]) == SCRATCH)
12193     operands[4] = gen_reg_rtx (SImode);
12194   if (GET_CODE (operands[5]) == SCRATCH)
12195     operands[5] = gen_reg_rtx (<MODE>mode);
12197   [(set (attr "length")
12198         (if_then_else (match_test "operands[2] == const0_rtx")
12199                       (const_string "12")
12200                       (const_string "16")))])
12202 ;; Conditional branches.
12203 ;; These either are a single bc insn, or a bc around a b.
12205 (define_insn "*cbranch"
12206   [(set (pc)
12207         (if_then_else (match_operator 1 "branch_comparison_operator"
12208                                       [(match_operand 2 "cc_reg_operand" "y")
12209                                        (const_int 0)])
12210                       (label_ref (match_operand 0))
12211                       (pc)))]
12212   ""
12214   return output_cbranch (operands[1], "%l0", 0, insn);
12216   [(set_attr "type" "branch")
12217    (set (attr "length")
12218         (if_then_else (and (ge (minus (match_dup 0) (pc))
12219                                (const_int -32768))
12220                            (lt (minus (match_dup 0) (pc))
12221                                (const_int 32764)))
12222                       (const_int 4)
12223                       (const_int 8)))])
12225 ;; Conditional return.
12226 (define_insn "*creturn"
12227   [(set (pc)
12228         (if_then_else (match_operator 0 "branch_comparison_operator"
12229                                       [(match_operand 1 "cc_reg_operand" "y")
12230                                        (const_int 0)])
12231                       (any_return)
12232                       (pc)))]
12233   "<return_pred>"
12235   return output_cbranch (operands[0], NULL, 0, insn);
12237   [(set_attr "type" "jmpreg")])
12239 ;; Logic on condition register values.
12241 ; This pattern matches things like
12242 ; (set (reg:CCEQ 68) (compare:CCEQ (ior:SI (gt:SI (reg:CCFP 68) (const_int 0))
12243 ;                                          (eq:SI (reg:CCFP 68) (const_int 0)))
12244 ;                                  (const_int 1)))
12245 ; which are generated by the branch logic.
12246 ; Prefer destructive operations where BT = BB (for crXX BT,BA,BB)
12248 (define_insn "cceq_ior_compare"
12249   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12250         (compare:CCEQ (match_operator:SI 1 "boolean_operator"
12251                         [(match_operator:SI 2
12252                                       "branch_positive_comparison_operator"
12253                                       [(match_operand 3
12254                                                       "cc_reg_operand" "y,y")
12255                                        (const_int 0)])
12256                          (match_operator:SI 4
12257                                       "branch_positive_comparison_operator"
12258                                       [(match_operand 5
12259                                                       "cc_reg_operand" "0,y")
12260                                        (const_int 0)])])
12261                       (const_int 1)))]
12262   ""
12263   "cr%q1 %E0,%j2,%j4"
12264   [(set_attr "type" "cr_logical")
12265    (set_attr "cr_logical_3op" "no,yes")])
12267 ; Why is the constant -1 here, but 1 in the previous pattern?
12268 ; Because ~1 has all but the low bit set.
12269 (define_insn "cceq_ior_compare_complement"
12270   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12271         (compare:CCEQ (match_operator:SI 1 "boolean_operator"
12272                         [(not:SI (match_operator:SI 2
12273                                       "branch_positive_comparison_operator"
12274                                       [(match_operand 3
12275                                                       "cc_reg_operand" "y,y")
12276                                        (const_int 0)]))
12277                          (match_operator:SI 4
12278                                 "branch_positive_comparison_operator"
12279                                 [(match_operand 5
12280                                                 "cc_reg_operand" "0,y")
12281                                  (const_int 0)])])
12282                       (const_int -1)))]
12283   ""
12284   "cr%q1 %E0,%j2,%j4"
12285   [(set_attr "type" "cr_logical")
12286    (set_attr "cr_logical_3op" "no,yes")])
12288 (define_insn "*cceq_rev_compare"
12289   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12290         (compare:CCEQ (match_operator:SI 1
12291                                       "branch_positive_comparison_operator"
12292                                       [(match_operand 2
12293                                                       "cc_reg_operand" "0,y")
12294                                        (const_int 0)])
12295                       (const_int 0)))]
12296   ""
12297   "crnot %E0,%j1"
12298   [(set_attr "type" "cr_logical")
12299    (set_attr "cr_logical_3op" "no,yes")])
12301 ;; If we are comparing the result of two comparisons, this can be done
12302 ;; using creqv or crxor.
12304 (define_insn_and_split ""
12305   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y")
12306         (compare:CCEQ (match_operator 1 "branch_comparison_operator"
12307                               [(match_operand 2 "cc_reg_operand" "y")
12308                                (const_int 0)])
12309                       (match_operator 3 "branch_comparison_operator"
12310                               [(match_operand 4 "cc_reg_operand" "y")
12311                                (const_int 0)])))]
12312   ""
12313   "#"
12314   ""
12315   [(set (match_dup 0) (compare:CCEQ (xor:SI (match_dup 1) (match_dup 3))
12316                                     (match_dup 5)))]
12318   int positive_1, positive_2;
12320   positive_1 = branch_positive_comparison_operator (operands[1],
12321                                                     GET_MODE (operands[1]));
12322   positive_2 = branch_positive_comparison_operator (operands[3],
12323                                                     GET_MODE (operands[3]));
12325   if (! positive_1)
12326     operands[1] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[2]),
12327                                                             GET_CODE (operands[1])),
12328                                   SImode,
12329                                   operands[2], const0_rtx);
12330   else if (GET_MODE (operands[1]) != SImode)
12331     operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), SImode,
12332                                   operands[2], const0_rtx);
12334   if (! positive_2)
12335     operands[3] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[4]),
12336                                                             GET_CODE (operands[3])),
12337                                   SImode,
12338                                   operands[4], const0_rtx);
12339   else if (GET_MODE (operands[3]) != SImode)
12340     operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SImode,
12341                                   operands[4], const0_rtx);
12343   if (positive_1 == positive_2)
12344     {
12345       operands[1] = gen_rtx_NOT (SImode, operands[1]);
12346       operands[5] = constm1_rtx;
12347     }
12348   else
12349     {
12350       operands[5] = const1_rtx;
12351     }
12354 ;; Unconditional branch and return.
12356 (define_insn "jump"
12357   [(set (pc)
12358         (label_ref (match_operand 0)))]
12359   ""
12360   "b %l0"
12361   [(set_attr "type" "branch")])
12363 (define_insn "<return_str>return"
12364   [(any_return)]
12365   "<return_pred>"
12366   "blr"
12367   [(set_attr "type" "jmpreg")])
12369 (define_expand "indirect_jump"
12370   [(set (pc) (match_operand 0 "register_operand"))]
12371  ""
12373   if (!rs6000_speculate_indirect_jumps) {
12374     rtx ccreg = gen_reg_rtx (CCmode);
12375     emit_jump_insn (gen_indirect_jump_nospec (Pmode, operands[0], ccreg));
12376     DONE;
12377   }
12380 (define_insn "*indirect_jump<mode>"
12381   [(set (pc)
12382         (match_operand:P 0 "register_operand" "c,*l"))]
12383   "rs6000_speculate_indirect_jumps"
12384   "b%T0"
12385   [(set_attr "type" "jmpreg")])
12387 (define_insn "@indirect_jump<mode>_nospec"
12388   [(set (pc) (match_operand:P 0 "register_operand" "c,*l"))
12389    (clobber (match_operand:CC 1 "cc_reg_operand" "=y,y"))]
12390   "!rs6000_speculate_indirect_jumps"
12391   "crset %E1\;beq%T0- %1\;b $"
12392   [(set_attr "type" "jmpreg")
12393    (set_attr "length" "12")])
12395 ;; Table jump for switch statements:
12396 (define_expand "tablejump"
12397   [(use (match_operand 0))
12398    (use (label_ref (match_operand 1)))]
12399   ""
12401   if (rs6000_speculate_indirect_jumps)
12402     {
12403       if (TARGET_32BIT)
12404         emit_jump_insn (gen_tablejumpsi (operands[0], operands[1]));
12405       else
12406         emit_jump_insn (gen_tablejumpdi (operands[0], operands[1]));
12407     }
12408   else
12409     {
12410       rtx ccreg = gen_reg_rtx (CCmode);
12411       rtx jump;
12412       if (TARGET_32BIT)
12413         jump = gen_tablejumpsi_nospec (operands[0], operands[1], ccreg);
12414       else
12415         jump = gen_tablejumpdi_nospec (operands[0], operands[1], ccreg);
12416       emit_jump_insn (jump);
12417     }
12418   DONE;
12421 (define_expand "tablejumpsi"
12422   [(set (match_dup 3)
12423         (plus:SI (match_operand:SI 0)
12424                  (match_dup 2)))
12425    (parallel [(set (pc)
12426                    (match_dup 3))
12427               (use (label_ref (match_operand 1)))])]
12428   "TARGET_32BIT && rs6000_speculate_indirect_jumps"
12430   operands[0] = force_reg (SImode, operands[0]);
12431   operands[2] = force_reg (SImode, gen_rtx_LABEL_REF (SImode, operands[1]));
12432   operands[3] = gen_reg_rtx (SImode);
12435 (define_expand "tablejumpsi_nospec"
12436   [(set (match_dup 4)
12437         (plus:SI (match_operand:SI 0)
12438                  (match_dup 3)))
12439    (parallel [(set (pc)
12440                    (match_dup 4))
12441               (use (label_ref (match_operand 1)))
12442               (clobber (match_operand 2))])]
12443   "TARGET_32BIT && !rs6000_speculate_indirect_jumps"
12445   operands[0] = force_reg (SImode, operands[0]);
12446   operands[3] = force_reg (SImode, gen_rtx_LABEL_REF (SImode, operands[1]));
12447   operands[4] = gen_reg_rtx (SImode);
12450 (define_expand "tablejumpdi"
12451   [(set (match_dup 4)
12452         (sign_extend:DI (match_operand:SI 0 "lwa_operand")))
12453    (set (match_dup 3)
12454         (plus:DI (match_dup 4)
12455                  (match_dup 2)))
12456    (parallel [(set (pc)
12457                    (match_dup 3))
12458               (use (label_ref (match_operand 1)))])]
12459   "TARGET_64BIT && rs6000_speculate_indirect_jumps"
12461   operands[2] = force_reg (DImode, gen_rtx_LABEL_REF (DImode, operands[1]));
12462   operands[3] = gen_reg_rtx (DImode);
12463   operands[4] = gen_reg_rtx (DImode);
12466 (define_expand "tablejumpdi_nospec"
12467   [(set (match_dup 5)
12468         (sign_extend:DI (match_operand:SI 0 "lwa_operand")))
12469    (set (match_dup 4)
12470         (plus:DI (match_dup 5)
12471                  (match_dup 3)))
12472    (parallel [(set (pc)
12473                    (match_dup 4))
12474               (use (label_ref (match_operand 1)))
12475               (clobber (match_operand 2))])]
12476   "TARGET_64BIT && !rs6000_speculate_indirect_jumps"
12478   operands[3] = force_reg (DImode, gen_rtx_LABEL_REF (DImode, operands[1]));
12479   operands[4] = gen_reg_rtx (DImode);
12480   operands[5] = gen_reg_rtx (DImode);
12483 (define_insn "*tablejump<mode>_internal1"
12484   [(set (pc)
12485         (match_operand:P 0 "register_operand" "c,*l"))
12486    (use (label_ref (match_operand 1)))]
12487   "rs6000_speculate_indirect_jumps"
12488   "b%T0"
12489   [(set_attr "type" "jmpreg")])
12491 (define_insn "*tablejump<mode>_internal1_nospec"
12492   [(set (pc)
12493         (match_operand:P 0 "register_operand" "c,*l"))
12494    (use (label_ref (match_operand 1)))
12495    (clobber (match_operand:CC 2 "cc_reg_operand" "=y,y"))]
12496   "!rs6000_speculate_indirect_jumps"
12497   "crset %E2\;beq%T0- %2\;b $"
12498   [(set_attr "type" "jmpreg")
12499    (set_attr "length" "12")])
12501 (define_insn "nop"
12502   [(unspec [(const_int 0)] UNSPEC_NOP)]
12503   ""
12504   "nop")
12506 (define_insn "group_ending_nop"
12507   [(unspec [(const_int 0)] UNSPEC_GRP_END_NOP)]
12508   ""
12510   operands[0] = gen_rtx_REG (Pmode,
12511                              rs6000_tune == PROCESSOR_POWER6 ? 1 : 2);
12512   return "ori %0,%0,0";
12515 (define_insn "speculation_barrier"
12516   [(unspec_volatile:BLK [(const_int 0)] UNSPECV_SPEC_BARRIER)]
12517   ""
12519   operands[0] = gen_rtx_REG (Pmode, 31);
12520   return "ori %0,%0,0";
12523 ;; Define the subtract-one-and-jump insns, starting with the template
12524 ;; so loop.c knows what to generate.
12526 (define_expand "doloop_end"
12527   [(use (match_operand 0))      ; loop pseudo
12528    (use (match_operand 1))]     ; label
12529   ""
12531   if (GET_MODE (operands[0]) != Pmode)
12532     FAIL;
12534   emit_jump_insn (gen_ctr (Pmode, operands[0], operands[1]));
12535   DONE;
12538 (define_expand "@ctr<mode>"
12539   [(parallel [(set (pc)
12540                    (if_then_else (ne (match_operand:P 0 "register_operand")
12541                                      (const_int 1))
12542                                  (label_ref (match_operand 1))
12543                                  (pc)))
12544               (set (match_dup 0)
12545                    (plus:P (match_dup 0)
12546                             (const_int -1)))
12547               (clobber (match_scratch:CC 2))
12548               (clobber (match_scratch:P 3))])]
12549   ""
12550   "")
12552 ;; We need to be able to do this for any operand, including MEM, or we
12553 ;; will cause reload to blow up since we don't allow output reloads on
12554 ;; JUMP_INSNs.
12555 ;; For the length attribute to be calculated correctly, the
12556 ;; label MUST be operand 0.
12557 ;; rs6000_legitimate_combined_insn prevents combine creating any of
12558 ;; the ctr<mode> insns.
12560 (define_code_iterator eqne [eq ne])
12561 (define_code_attr bd [(eq "bdz") (ne "bdnz")])
12562 (define_code_attr bd_neg [(eq "bdnz") (ne "bdz")])
12564 (define_insn "<bd>_<mode>"
12565   [(set (pc)
12566         (if_then_else (eqne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12567                           (const_int 1))
12568                       (label_ref (match_operand 0))
12569                       (pc)))
12570    (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wa*c*l")
12571         (plus:P (match_dup 1)
12572                 (const_int -1)))
12573    (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
12574    (clobber (match_scratch:P 4 "=X,X,&r,r"))]
12575   ""
12577   if (which_alternative != 0)
12578     return "#";
12579   else if (get_attr_length (insn) == 4)
12580     return "<bd> %l0";
12581   else
12582     return "<bd_neg> $+8\;b %l0";
12584   [(set_attr "type" "branch")
12585    (set_attr_alternative "length"
12586      [(if_then_else (and (ge (minus (match_dup 0) (pc))
12587                              (const_int -32768))
12588                          (lt (minus (match_dup 0) (pc))
12589                              (const_int 32764)))
12590                     (const_int 4)
12591                     (const_int 8))
12592       (const_string "16")
12593       (const_string "20")
12594       (const_string "20")])])
12596 ;; Now the splitter if we could not allocate the CTR register
12597 (define_split
12598   [(set (pc)
12599         (if_then_else (match_operator 2 "comparison_operator"
12600                                       [(match_operand:P 1 "gpc_reg_operand")
12601                                        (const_int 1)])
12602                       (match_operand 5)
12603                       (match_operand 6)))
12604    (set (match_operand:P 0 "nonimmediate_operand")
12605         (plus:P (match_dup 1)
12606                 (const_int -1)))
12607    (clobber (match_scratch:CC 3))
12608    (clobber (match_scratch:P 4))]
12609   "reload_completed"
12610   [(set (pc)
12611         (if_then_else (match_dup 7)
12612                       (match_dup 5)
12613                       (match_dup 6)))]
12615   operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[2]), VOIDmode, operands[3],
12616                                 const0_rtx);
12617   emit_insn (gen_rtx_SET (operands[3],
12618                           gen_rtx_COMPARE (CCmode, operands[1], const1_rtx)));
12619   if (int_reg_operand (operands[0], <MODE>mode))
12620     emit_insn (gen_add<mode>3 (operands[0], operands[1], constm1_rtx));
12621   else
12622     {
12623       emit_insn (gen_add<mode>3 (operands[4], operands[1], constm1_rtx));
12624       emit_move_insn (operands[0], operands[4]);
12625     } 
12626     /* No DONE so branch comes from the pattern.  */
12629 ;; patterns for bdnzt/bdnzf/bdzt/bdzf
12630 ;; Note that in the case of long branches we have to decompose this into
12631 ;; bdnz+bc. This is because bdnzt has an implied AND between the ctr condition
12632 ;; and the CR bit, which means there is no way to conveniently invert the
12633 ;; comparison as is done with plain bdnz/bdz.
12635 (define_insn "<bd>tf_<mode>"
12636   [(set (pc)
12637         (if_then_else
12638           (and
12639              (eqne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12640                    (const_int 1))
12641              (match_operator 3 "branch_comparison_operator"
12642                       [(match_operand 4 "cc_reg_operand" "y,y,y,y")
12643                        (const_int 0)]))
12644           (label_ref (match_operand 0))
12645           (pc)))
12646    (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wa*c*l")
12647         (plus:P (match_dup 1)
12648                 (const_int -1)))
12649    (clobber (match_scratch:P 5 "=X,X,&r,r"))
12650    (clobber (match_scratch:CC 6 "=X,&y,&y,&y"))
12651    (clobber (match_scratch:CCEQ 7 "=X,&y,&y,&y"))]
12652   ""
12654   if (which_alternative != 0)
12655     return "#";
12656   else if (get_attr_length (insn) == 4)
12657     {
12658       if (branch_positive_comparison_operator (operands[3],
12659                                                GET_MODE (operands[3])))
12660         return "<bd>t %j3,%l0";
12661       else
12662         return "<bd>f %j3,%l0";
12663     }
12664   else
12665     {
12666       static char seq[96];
12667       char *bcs = output_cbranch (operands[3], ".Lshort%=", 1, insn);
12668       sprintf(seq, "<bd_neg> .Lshort%%=\;%s\;b %%l0\;.Lshort%%=:", bcs);
12669       return seq;
12670     }
12672   [(set_attr "type" "branch")
12673    (set_attr_alternative "length"
12674      [(if_then_else (and (ge (minus (match_dup 0) (pc))
12675                              (const_int -32768))
12676                          (lt (minus (match_dup 0) (pc))
12677                              (const_int 32764)))
12678                     (const_int 4)
12679                     (const_int 8))
12680       (const_string "16")
12681       (const_string "20")
12682       (const_string "20")])])
12684 ;; Now the splitter if we could not allocate the CTR register
12685 (define_split
12686   [(set (pc)
12687         (if_then_else
12688           (and
12689              (match_operator 1 "comparison_operator"
12690                              [(match_operand:P 0 "gpc_reg_operand")
12691                               (const_int 1)])
12692              (match_operator 3 "branch_comparison_operator"
12693                       [(match_operand 2 "cc_reg_operand")
12694                        (const_int 0)]))
12695           (match_operand 4)
12696           (match_operand 5)))
12697    (set (match_operand:P 6 "nonimmediate_operand")
12698         (plus:P (match_dup 0)
12699                 (const_int -1)))
12700    (clobber (match_scratch:P 7))
12701    (clobber (match_scratch:CC 8))
12702    (clobber (match_scratch:CCEQ 9))]
12703   "reload_completed"
12704 [(pc)]
12706   rtx ctr = operands[0];
12707   rtx ctrcmp = operands[1];
12708   rtx ccin = operands[2];
12709   rtx cccmp = operands[3];
12710   rtx dst1 = operands[4];
12711   rtx dst2 = operands[5];
12712   rtx ctrout = operands[6];
12713   rtx ctrtmp = operands[7];
12714   enum rtx_code cmpcode = GET_CODE (ctrcmp);
12715   bool ispos = branch_positive_comparison_operator (ctrcmp, GET_MODE (ctrcmp));
12716   if (!ispos)
12717     cmpcode = reverse_condition (cmpcode);
12718   /* Generate crand/crandc here.  */
12719   emit_insn (gen_rtx_SET (operands[8],
12720                           gen_rtx_COMPARE (CCmode, ctr, const1_rtx)));
12721   rtx ctrcmpcc = gen_rtx_fmt_ee (cmpcode, SImode, operands[8], const0_rtx);
12723   rtx andexpr = gen_rtx_AND (SImode, ctrcmpcc, cccmp);
12724   if (ispos)
12725      emit_insn (gen_cceq_ior_compare (operands[9], andexpr, ctrcmpcc,
12726                                       operands[8], cccmp, ccin));
12727   else
12728      emit_insn (gen_cceq_ior_compare_complement (operands[9], andexpr, ctrcmpcc,
12729                                                  operands[8], cccmp, ccin));
12730   if (int_reg_operand (ctrout, <MODE>mode))
12731      emit_insn (gen_add<mode>3 (ctrout, ctr, constm1_rtx));
12732   else
12733     {
12734       emit_insn (gen_add<mode>3 (ctrtmp, ctr, constm1_rtx));
12735       emit_move_insn (ctrout, ctrtmp);
12736     }
12737   rtx cmp = gen_rtx_EQ (CCEQmode, operands[9], const0_rtx);
12738   emit_jump_insn (gen_rtx_SET (pc_rtx,
12739                                gen_rtx_IF_THEN_ELSE (VOIDmode, cmp,
12740                                                      dst1, dst2)));
12741   DONE;
12745 (define_insn "trap"
12746   [(trap_if (const_int 1) (const_int 0))]
12747   ""
12748   "trap"
12749   [(set_attr "type" "trap")])
12751 (define_expand "ctrap<mode>4"
12752   [(trap_if (match_operator 0 "ordered_comparison_operator"
12753                             [(match_operand:GPR 1 "register_operand")
12754                              (match_operand:GPR 2 "reg_or_short_operand")])
12755             (match_operand 3 "zero_constant" ""))]
12756   ""
12757   "")
12759 (define_insn ""
12760   [(trap_if (match_operator 0 "ordered_comparison_operator"
12761                             [(match_operand:GPR 1 "register_operand" "r")
12762                              (match_operand:GPR 2 "reg_or_short_operand" "rI")])
12763             (const_int 0))]
12764   ""
12765   "t<wd>%V0%I2 %1,%2"
12766   [(set_attr "type" "trap")])
12768 ;; Insns related to generating the function prologue and epilogue.
12770 (define_expand "prologue"
12771   [(use (const_int 0))]
12772   ""
12774   rs6000_emit_prologue ();
12775   if (!TARGET_SCHED_PROLOG)
12776     emit_insn (gen_blockage ());
12777   DONE;
12780 (define_insn "*movesi_from_cr_one"
12781   [(match_parallel 0 "mfcr_operation"
12782                    [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
12783                          (unspec:SI [(match_operand:CC 2 "cc_reg_operand" "y")
12784                                      (match_operand 3 "immediate_operand" "n")]
12785                           UNSPEC_MOVESI_FROM_CR))])]
12786   "TARGET_MFCRF"
12788   int mask = 0;
12789   int i;
12790   for (i = 0; i < XVECLEN (operands[0], 0); i++)
12791   {
12792     mask = INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
12793     operands[4] = GEN_INT (mask);
12794     output_asm_insn ("mfcr %1,%4", operands);
12795   }
12796   return "";
12798   [(set_attr "type" "mfcrf")])
12800 ;; Don't include the volatile CRs since their values are not used wrt CR save
12801 ;; in the prologue and doing so prevents shrink-wrapping because we can't move the
12802 ;; prologue past an insn (early exit test) that defines a register used in the
12803 ;; prologue.
12804 (define_insn "prologue_movesi_from_cr"
12805   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
12806         (unspec:SI [(reg:CC CR2_REGNO) (reg:CC CR3_REGNO)
12807                     (reg:CC CR4_REGNO)]
12808                    UNSPEC_MOVESI_FROM_CR))]
12809   ""
12810   "mfcr %0"
12811   [(set_attr "type" "mfcr")])
12813 (define_insn "*crsave"
12814   [(match_parallel 0 "crsave_operation"
12815                    [(set (match_operand:SI 1 "memory_operand" "=m")
12816                          (match_operand:SI 2 "gpc_reg_operand" "r"))])]
12817   ""
12818   "stw %2,%1"
12819   [(set_attr "type" "store")])
12821 (define_insn "*stmw"
12822   [(match_parallel 0 "stmw_operation"
12823                    [(set (match_operand:SI 1 "memory_operand" "=m")
12824                          (match_operand:SI 2 "gpc_reg_operand" "r"))])]
12825   "TARGET_MULTIPLE"
12826   "stmw %2,%1"
12827   [(set_attr "type" "store")
12828    (set_attr "update" "yes")
12829    (set_attr "indexed" "yes")])
12831 ; The following comment applies to:
12832 ;     save_gpregs_*
12833 ;     save_fpregs_*
12834 ;     restore_gpregs*
12835 ;     return_and_restore_gpregs*
12836 ;     return_and_restore_fpregs*
12837 ;     return_and_restore_fpregs_aix*
12839 ; The out-of-line save / restore functions expects one input argument.
12840 ; Since those are not standard call_insn's, we must avoid using
12841 ; MATCH_OPERAND for that argument. That way the register rename
12842 ; optimization will not try to rename this register.
12843 ; Each pattern is repeated for each possible register number used in 
12844 ; various ABIs (r11, r1, and for some functions r12)
12846 (define_insn "*save_gpregs_<mode>_r11"
12847   [(match_parallel 0 "any_parallel_operand"
12848                    [(clobber (reg:P LR_REGNO))
12849                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
12850                     (use (reg:P 11))
12851                     (set (match_operand:P 2 "memory_operand" "=m")
12852                          (match_operand:P 3 "gpc_reg_operand" "r"))])]
12853   ""
12854   "bl %1"
12855   [(set_attr "type" "branch")])
12857 (define_insn "*save_gpregs_<mode>_r12"
12858   [(match_parallel 0 "any_parallel_operand"
12859                    [(clobber (reg:P LR_REGNO))
12860                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
12861                     (use (reg:P 12))
12862                     (set (match_operand:P 2 "memory_operand" "=m")
12863                          (match_operand:P 3 "gpc_reg_operand" "r"))])]
12864   ""
12865   "bl %1"
12866   [(set_attr "type" "branch")])
12868 (define_insn "*save_gpregs_<mode>_r1"
12869   [(match_parallel 0 "any_parallel_operand"
12870                    [(clobber (reg:P LR_REGNO))
12871                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
12872                     (use (reg:P 1))
12873                     (set (match_operand:P 2 "memory_operand" "=m")
12874                          (match_operand:P 3 "gpc_reg_operand" "r"))])]
12875   ""
12876   "bl %1"
12877   [(set_attr "type" "branch")])
12879 (define_insn "*save_fpregs_<mode>_r11"
12880   [(match_parallel 0 "any_parallel_operand"
12881                    [(clobber (reg:P LR_REGNO))
12882                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
12883                     (use (reg:P 11))
12884                     (set (match_operand:DF 2 "memory_operand" "=m")
12885                          (match_operand:DF 3 "gpc_reg_operand" "d"))])]
12886   ""
12887   "bl %1"
12888   [(set_attr "type" "branch")])
12890 (define_insn "*save_fpregs_<mode>_r12"
12891   [(match_parallel 0 "any_parallel_operand"
12892                    [(clobber (reg:P LR_REGNO))
12893                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
12894                     (use (reg:P 12))
12895                     (set (match_operand:DF 2 "memory_operand" "=m")
12896                          (match_operand:DF 3 "gpc_reg_operand" "d"))])]
12897   ""
12898   "bl %1"
12899   [(set_attr "type" "branch")])
12901 (define_insn "*save_fpregs_<mode>_r1"
12902   [(match_parallel 0 "any_parallel_operand"
12903                    [(clobber (reg:P LR_REGNO))
12904                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
12905                     (use (reg:P 1))
12906                     (set (match_operand:DF 2 "memory_operand" "=m")
12907                          (match_operand:DF 3 "gpc_reg_operand" "d"))])]
12908   ""
12909   "bl %1"
12910   [(set_attr "type" "branch")])
12912 ; This is to explain that changes to the stack pointer should
12913 ; not be moved over loads from or stores to stack memory.
12914 (define_insn "stack_tie"
12915   [(match_parallel 0 "tie_operand"
12916                    [(set (mem:BLK (reg 1)) (const_int 0))])]
12917   ""
12918   ""
12919   [(set_attr "length" "0")])
12921 ; Some 32-bit ABIs do not have a red zone, so the stack deallocation has to
12922 ; stay behind all restores from the stack, it cannot be reordered to before
12923 ; one.  See PR77687.  This insn is an add or mr, and a memory clobber.
12924 (define_insn "stack_restore_tie"
12925   [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
12926         (plus:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
12927                  (match_operand:SI 2 "reg_or_cint_operand" "O,rI")))
12928    (set (mem:BLK (scratch)) (const_int 0))]
12929   "TARGET_32BIT"
12930   "@
12931    mr %0,%1
12932    add%I2 %0,%1,%2"
12933   [(set_attr "type" "*,add")])
12935 (define_expand "epilogue"
12936   [(use (const_int 0))]
12937   ""
12939   if (!TARGET_SCHED_PROLOG)
12940     emit_insn (gen_blockage ());
12941   rs6000_emit_epilogue (EPILOGUE_TYPE_NORMAL);
12942   DONE;
12945 ; On some processors, doing the mtcrf one CC register at a time is
12946 ; faster (like on the 604e).  On others, doing them all at once is
12947 ; faster; for instance, on the 601 and 750.
12949 (define_expand "movsi_to_cr_one"
12950   [(set (match_operand:CC 0 "cc_reg_operand")
12951         (unspec:CC [(match_operand:SI 1 "gpc_reg_operand")
12952                     (match_dup 2)] UNSPEC_MOVESI_TO_CR))]
12953   ""
12954   "operands[2] = GEN_INT (1 << (75 - REGNO (operands[0])));")
12956 (define_insn "*movsi_to_cr"
12957   [(match_parallel 0 "mtcrf_operation"
12958                    [(set (match_operand:CC 1 "cc_reg_operand" "=y")
12959                          (unspec:CC [(match_operand:SI 2 "gpc_reg_operand" "r")
12960                                      (match_operand 3 "immediate_operand" "n")]
12961                                     UNSPEC_MOVESI_TO_CR))])]
12962  ""
12964   int mask = 0;
12965   int i;
12966   for (i = 0; i < XVECLEN (operands[0], 0); i++)
12967     mask |= INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
12968   operands[4] = GEN_INT (mask);
12969   return "mtcrf %4,%2";
12971   [(set_attr "type" "mtcr")])
12973 (define_insn "*mtcrfsi"
12974   [(set (match_operand:CC 0 "cc_reg_operand" "=y")
12975         (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
12976                     (match_operand 2 "immediate_operand" "n")]
12977                    UNSPEC_MOVESI_TO_CR))]
12978   "REG_P (operands[0])
12979    && CR_REGNO_P (REGNO (operands[0]))
12980    && CONST_INT_P (operands[2])
12981    && INTVAL (operands[2]) == 1 << (75 - REGNO (operands[0]))"
12982   "mtcrf %R0,%1"
12983   [(set_attr "type" "mtcr")])
12985 ; The load-multiple instructions have similar properties.
12986 ; Note that "load_multiple" is a name known to the machine-independent
12987 ; code that actually corresponds to the PowerPC load-string.
12989 (define_insn "*lmw"
12990   [(match_parallel 0 "lmw_operation"
12991                    [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
12992                          (match_operand:SI 2 "memory_operand" "m"))])]
12993   "TARGET_MULTIPLE"
12994   "lmw %1,%2"
12995   [(set_attr "type" "load")
12996    (set_attr "update" "yes")
12997    (set_attr "indexed" "yes")
12998    (set_attr "cell_micro" "always")])
13000 ; FIXME: "any_parallel_operand" is a bit flexible...
13002 ; The following comment applies to:
13003 ;     save_gpregs_*
13004 ;     save_fpregs_*
13005 ;     restore_gpregs*
13006 ;     return_and_restore_gpregs*
13007 ;     return_and_restore_fpregs*
13008 ;     return_and_restore_fpregs_aix*
13010 ; The out-of-line save / restore functions expects one input argument.
13011 ; Since those are not standard call_insn's, we must avoid using
13012 ; MATCH_OPERAND for that argument. That way the register rename
13013 ; optimization will not try to rename this register.
13014 ; Each pattern is repeated for each possible register number used in 
13015 ; various ABIs (r11, r1, and for some functions r12)
13017 (define_insn "*restore_gpregs_<mode>_r11"
13018  [(match_parallel 0 "any_parallel_operand"
13019                   [(clobber (reg:P LR_REGNO))
13020                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13021                    (use (reg:P 11))
13022                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
13023                         (match_operand:P 3 "memory_operand" "m"))])]
13024  ""
13025  "bl %1"
13026  [(set_attr "type" "branch")])
13028 (define_insn "*restore_gpregs_<mode>_r12"
13029  [(match_parallel 0 "any_parallel_operand"
13030                   [(clobber (reg:P LR_REGNO))
13031                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13032                    (use (reg:P 12))
13033                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
13034                         (match_operand:P 3 "memory_operand" "m"))])]
13035  ""
13036  "bl %1"
13037  [(set_attr "type" "branch")])
13039 (define_insn "*restore_gpregs_<mode>_r1"
13040  [(match_parallel 0 "any_parallel_operand"
13041                   [(clobber (reg:P LR_REGNO))
13042                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13043                    (use (reg:P 1))
13044                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
13045                         (match_operand:P 3 "memory_operand" "m"))])]
13046  ""
13047  "bl %1"
13048  [(set_attr "type" "branch")])
13050 (define_insn "*return_and_restore_gpregs_<mode>_r11"
13051  [(match_parallel 0 "any_parallel_operand"
13052                   [(return)
13053                    (clobber (reg:P LR_REGNO))
13054                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13055                    (use (reg:P 11))
13056                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
13057                         (match_operand:P 3 "memory_operand" "m"))])]
13058  ""
13059  "b %1"
13060  [(set_attr "type" "branch")])
13062 (define_insn "*return_and_restore_gpregs_<mode>_r12"
13063  [(match_parallel 0 "any_parallel_operand"
13064                   [(return)
13065                    (clobber (reg:P LR_REGNO))
13066                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13067                    (use (reg:P 12))
13068                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
13069                         (match_operand:P 3 "memory_operand" "m"))])]
13070  ""
13071  "b %1"
13072  [(set_attr "type" "branch")])
13074 (define_insn "*return_and_restore_gpregs_<mode>_r1"
13075  [(match_parallel 0 "any_parallel_operand"
13076                   [(return)
13077                    (clobber (reg:P LR_REGNO))
13078                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13079                    (use (reg:P 1))
13080                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
13081                         (match_operand:P 3 "memory_operand" "m"))])]
13082  ""
13083  "b %1"
13084  [(set_attr "type" "branch")])
13086 (define_insn "*return_and_restore_fpregs_<mode>_r11"
13087  [(match_parallel 0 "any_parallel_operand"
13088                   [(return)
13089                    (clobber (reg:P LR_REGNO))
13090                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13091                    (use (reg:P 11))
13092                    (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13093                         (match_operand:DF 3 "memory_operand" "m"))])]
13094  ""
13095  "b %1"
13096  [(set_attr "type" "branch")])
13098 (define_insn "*return_and_restore_fpregs_<mode>_r12"
13099  [(match_parallel 0 "any_parallel_operand"
13100                   [(return)
13101                    (clobber (reg:P LR_REGNO))
13102                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13103                    (use (reg:P 12))
13104                    (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13105                         (match_operand:DF 3 "memory_operand" "m"))])]
13106  ""
13107  "b %1"
13108  [(set_attr "type" "branch")])
13110 (define_insn "*return_and_restore_fpregs_<mode>_r1"
13111  [(match_parallel 0 "any_parallel_operand"
13112                   [(return)
13113                    (clobber (reg:P LR_REGNO))
13114                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13115                    (use (reg:P 1))
13116                    (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13117                         (match_operand:DF 3 "memory_operand" "m"))])]
13118  ""
13119  "b %1"
13120  [(set_attr "type" "branch")])
13122 (define_insn "*return_and_restore_fpregs_aix_<mode>_r11"
13123  [(match_parallel 0 "any_parallel_operand"
13124                   [(return)
13125                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13126                    (use (reg:P 11))
13127                    (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13128                         (match_operand:DF 3 "memory_operand" "m"))])]
13129  ""
13130  "b %1"
13131  [(set_attr "type" "branch")])
13133 (define_insn "*return_and_restore_fpregs_aix_<mode>_r1"
13134  [(match_parallel 0 "any_parallel_operand"
13135                   [(return)
13136                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13137                    (use (reg:P 1))
13138                    (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13139                         (match_operand:DF 3 "memory_operand" "m"))])]
13140  ""
13141  "b %1"
13142  [(set_attr "type" "branch")])
13144 ; This is used in compiling the unwind routines.
13145 (define_expand "eh_return"
13146   [(use (match_operand 0 "general_operand"))]
13147   ""
13149   emit_insn (gen_eh_set_lr (Pmode, operands[0]));
13150   DONE;
13153 ; We can't expand this before we know where the link register is stored.
13154 (define_insn_and_split "@eh_set_lr_<mode>"
13155   [(unspec_volatile [(match_operand:P 0 "register_operand" "r")] UNSPECV_EH_RR)
13156    (clobber (match_scratch:P 1 "=&b"))]
13157   ""
13158   "#"
13159   "reload_completed"
13160   [(const_int 0)]
13162   rs6000_emit_eh_reg_restore (operands[0], operands[1]);
13163   DONE;
13166 (define_insn "prefetch"
13167   [(prefetch (match_operand 0 "indexed_or_indirect_address" "a")
13168              (match_operand:SI 1 "const_int_operand" "n")
13169              (match_operand:SI 2 "const_int_operand" "n"))]
13170   ""
13174   /* dcbtstt, dcbtt and TH=0b10000 support starts with ISA 2.06 (Power7).
13175      AIX does not support the dcbtstt and dcbtt extended mnemonics.
13176      The AIX assembler does not support the three operand form of dcbt
13177      and dcbtst on Power 7 (-mpwr7).  */
13178   int inst_select = INTVAL (operands[2]) || !TARGET_DIRECT_MOVE;
13180   if (REG_P (operands[0]))
13181     {
13182       if (INTVAL (operands[1]) == 0)
13183         return inst_select ? "dcbt 0,%0" : "dcbt 0,%0,16";
13184       else
13185         return inst_select ? "dcbtst 0,%0" : "dcbtst 0,%0,16";
13186     }
13187   else
13188     {
13189       if (INTVAL (operands[1]) == 0)
13190         return inst_select ? "dcbt %a0" : "dcbt %a0,16";
13191       else
13192         return inst_select ? "dcbtst %a0" : "dcbtst %a0,16";
13193     }
13195   [(set_attr "type" "load")])
13197 ;; Handle -fsplit-stack.
13199 (define_expand "split_stack_prologue"
13200   [(const_int 0)]
13201   ""
13203   rs6000_expand_split_stack_prologue ();
13204   DONE;
13207 (define_expand "load_split_stack_limit"
13208   [(set (match_operand 0)
13209         (unspec [(const_int 0)] UNSPEC_STACK_CHECK))]
13210   ""
13212   emit_insn (gen_rtx_SET (operands[0],
13213                           gen_rtx_UNSPEC (Pmode,
13214                                           gen_rtvec (1, const0_rtx),
13215                                           UNSPEC_STACK_CHECK)));
13216   DONE;
13219 (define_insn "load_split_stack_limit_di"
13220   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
13221         (unspec:DI [(const_int 0)] UNSPEC_STACK_CHECK))]
13222   "TARGET_64BIT"
13223   "ld %0,-0x7040(13)"
13224   [(set_attr "type" "load")
13225    (set_attr "update" "no")
13226    (set_attr "indexed" "no")])
13228 (define_insn "load_split_stack_limit_si"
13229   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
13230         (unspec:SI [(const_int 0)] UNSPEC_STACK_CHECK))]
13231   "!TARGET_64BIT"
13232   "lwz %0,-0x7020(2)"
13233   [(set_attr "type" "load")
13234    (set_attr "update" "no")
13235    (set_attr "indexed" "no")])
13237 ;; A return instruction which the middle-end doesn't see.
13238 ;; Use r0 to stop regrename twiddling with lr restore insns emitted
13239 ;; after the call to __morestack.
13240 (define_insn "split_stack_return"
13241   [(unspec_volatile [(reg:SI 0) (reg:SI LR_REGNO)] UNSPECV_SPLIT_STACK_RETURN)]
13242   ""
13243   "blr"
13244   [(set_attr "type" "jmpreg")])
13246 ;; If there are operand 0 bytes available on the stack, jump to
13247 ;; operand 1.
13248 (define_expand "split_stack_space_check"
13249   [(set (match_dup 2)
13250         (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
13251    (set (match_dup 3)
13252         (minus (reg STACK_POINTER_REGNUM)
13253                (match_operand 0)))
13254    (set (match_dup 4) (compare:CCUNS (match_dup 3) (match_dup 2)))
13255    (set (pc) (if_then_else
13256               (geu (match_dup 4) (const_int 0))
13257               (label_ref (match_operand 1))
13258               (pc)))]
13259   ""
13261   rs6000_split_stack_space_check (operands[0], operands[1]);
13262   DONE;
13265 (define_insn "bpermd_<mode>"
13266   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
13267         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "r")
13268                    (match_operand:P 2 "gpc_reg_operand" "r")] UNSPEC_BPERM))]
13269   "TARGET_POPCNTD"
13270   "bpermd %0,%1,%2"
13271   [(set_attr "type" "popcnt")])
13274 ;; Builtin fma support.  Handle 
13275 ;; Note that the conditions for expansion are in the FMA_F iterator.
13277 (define_expand "fma<mode>4"
13278   [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13279         (fma:FMA_F
13280           (match_operand:FMA_F 1 "gpc_reg_operand")
13281           (match_operand:FMA_F 2 "gpc_reg_operand")
13282           (match_operand:FMA_F 3 "gpc_reg_operand")))]
13283   ""
13284   "")
13286 (define_insn "*fma<mode>4_fpr"
13287   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa,wa")
13288         (fma:SFDF
13289           (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,wa,wa")
13290           (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa,0")
13291           (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,wa")))]
13292   "TARGET_HARD_FLOAT"
13293   "@
13294    fmadd<s> %0,%1,%2,%3
13295    xsmadda<sd>p %x0,%x1,%x2
13296    xsmaddm<sd>p %x0,%x1,%x3"
13297   [(set_attr "type" "fp")
13298    (set_attr "isa" "*,<Fisa>,<Fisa>")])
13300 ; Altivec only has fma and nfms.
13301 (define_expand "fms<mode>4"
13302   [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13303         (fma:FMA_F
13304           (match_operand:FMA_F 1 "gpc_reg_operand")
13305           (match_operand:FMA_F 2 "gpc_reg_operand")
13306           (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand"))))]
13307   "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13308   "")
13310 (define_insn "*fms<mode>4_fpr"
13311   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa,wa")
13312         (fma:SFDF
13313          (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa,wa")
13314          (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa,0")
13315          (neg:SFDF (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,wa"))))]
13316   "TARGET_HARD_FLOAT"
13317   "@
13318    fmsub<s> %0,%1,%2,%3
13319    xsmsuba<sd>p %x0,%x1,%x2
13320    xsmsubm<sd>p %x0,%x1,%x3"
13321   [(set_attr "type" "fp")
13322    (set_attr "isa" "*,<Fisa>,<Fisa>")])
13324 ;; If signed zeros are ignored, -(a * b - c) = -a * b + c.
13325 (define_expand "fnma<mode>4"
13326   [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13327         (neg:FMA_F
13328           (fma:FMA_F
13329             (match_operand:FMA_F 1 "gpc_reg_operand")
13330             (match_operand:FMA_F 2 "gpc_reg_operand")
13331             (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand")))))]
13332   "!HONOR_SIGNED_ZEROS (<MODE>mode)"
13333   "")
13335 ;; If signed zeros are ignored, -(a * b + c) = -a * b - c.
13336 (define_expand "fnms<mode>4"
13337   [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13338         (neg:FMA_F
13339           (fma:FMA_F
13340             (match_operand:FMA_F 1 "gpc_reg_operand")
13341             (match_operand:FMA_F 2 "gpc_reg_operand")
13342             (match_operand:FMA_F 3 "gpc_reg_operand"))))]
13343   "!HONOR_SIGNED_ZEROS (<MODE>mode) && !VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13344   "")
13346 ; Not an official optab name, but used from builtins.
13347 (define_expand "nfma<mode>4"
13348   [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13349         (neg:FMA_F
13350           (fma:FMA_F
13351             (match_operand:FMA_F 1 "gpc_reg_operand")
13352             (match_operand:FMA_F 2 "gpc_reg_operand")
13353             (match_operand:FMA_F 3 "gpc_reg_operand"))))]
13354   "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13355   "")
13357 (define_insn "*nfma<mode>4_fpr"
13358   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa,wa")
13359         (neg:SFDF
13360          (fma:SFDF
13361           (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa,wa")
13362           (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa,0")
13363           (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,wa"))))]
13364   "TARGET_HARD_FLOAT"
13365   "@
13366    fnmadd<s> %0,%1,%2,%3
13367    xsnmadda<sd>p %x0,%x1,%x2
13368    xsnmaddm<sd>p %x0,%x1,%x3"
13369   [(set_attr "type" "fp")
13370    (set_attr "isa" "*,<Fisa>,<Fisa>")])
13372 ; Not an official optab name, but used from builtins.
13373 (define_expand "nfms<mode>4"
13374   [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13375         (neg:FMA_F
13376           (fma:FMA_F
13377             (match_operand:FMA_F 1 "gpc_reg_operand")
13378             (match_operand:FMA_F 2 "gpc_reg_operand")
13379             (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand")))))]
13380   ""
13381   "")
13383 (define_insn "*nfmssf4_fpr"
13384   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa,wa")
13385         (neg:SFDF
13386          (fma:SFDF
13387           (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa,wa")
13388           (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa,0")
13389           (neg:SFDF
13390            (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,wa")))))]
13391   "TARGET_HARD_FLOAT"
13392   "@
13393    fnmsub<s> %0,%1,%2,%3
13394    xsnmsuba<sd>p %x0,%x1,%x2
13395    xsnmsubm<sd>p %x0,%x1,%x3"
13396   [(set_attr "type" "fp")
13397    (set_attr "isa" "*,<Fisa>,<Fisa>")])
13399 (define_expand "rs6000_get_timebase"
13400   [(use (match_operand:DI 0 "gpc_reg_operand"))]
13401   ""
13403   if (TARGET_POWERPC64)
13404     emit_insn (gen_rs6000_mftb_di (operands[0]));
13405   else
13406     emit_insn (gen_rs6000_get_timebase_ppc32 (operands[0]));
13407   DONE;
13410 (define_insn "rs6000_get_timebase_ppc32"
13411   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
13412         (unspec_volatile:DI [(const_int 0)] UNSPECV_MFTB))
13413    (clobber (match_scratch:SI 1 "=r"))
13414    (clobber (match_scratch:CC 2 "=y"))]
13415   "!TARGET_POWERPC64"
13417   if (WORDS_BIG_ENDIAN)
13418     if (TARGET_MFCRF)
13419       {
13420         return "mfspr %0,269\;"
13421                "mfspr %L0,268\;"
13422                "mfspr %1,269\;"
13423                "cmpw %2,%0,%1\;"
13424                "bne- %2,$-16";
13425       }
13426     else
13427       {
13428         return "mftbu %0\;"
13429                "mftb %L0\;"
13430                "mftbu %1\;"
13431                "cmpw %2,%0,%1\;"
13432                "bne- %2,$-16";
13433       }
13434   else
13435     if (TARGET_MFCRF)
13436       {
13437         return "mfspr %L0,269\;"
13438                "mfspr %0,268\;"
13439                "mfspr %1,269\;"
13440                "cmpw %2,%L0,%1\;"
13441                "bne- %2,$-16";
13442       }
13443     else
13444       {
13445         return "mftbu %L0\;"
13446                "mftb %0\;"
13447                "mftbu %1\;"
13448                "cmpw %2,%L0,%1\;"
13449                "bne- %2,$-16";
13450       }
13452   [(set_attr "length" "20")])
13454 (define_insn "rs6000_mftb_<mode>"
13455   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
13456         (unspec_volatile:GPR [(const_int 0)] UNSPECV_MFTB))]
13457   ""
13459   if (TARGET_MFCRF)
13460     return "mfspr %0,268";
13461   else
13462     return "mftb %0";
13466 ;; The ISA 3.0 mffsl instruction is a lower latency instruction
13467 ;; for reading bits [29:31], [45:51] and [56:63] of the FPSCR.
13468 (define_insn "rs6000_mffsl_hw"
13469   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
13470         (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFSL))]
13471   "TARGET_HARD_FLOAT"
13472   "mffsl %0")
13474 (define_expand "rs6000_mffsl"
13475   [(set (match_operand:DF 0 "gpc_reg_operand")
13476         (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFSL))]
13477   "TARGET_HARD_FLOAT"
13479   /* If the low latency mffsl instruction (ISA 3.0) is available use it,
13480      otherwise fall back to the older mffs instruction to emulate the mffsl
13481      instruction.  */
13483   if (!TARGET_P9_MISC)
13484     {
13485        rtx tmp_di = gen_reg_rtx (DImode);
13486        rtx tmp_df = gen_reg_rtx (DFmode);
13488        /* The mffs instruction reads the entire FPSCR.  Emulate the mffsl
13489           instruction using the mffs instruction and masking off the bits
13490           the mmsl instruciton actually reads.  */
13491        emit_insn (gen_rs6000_mffs (tmp_df));
13492        tmp_di = simplify_gen_subreg (DImode, tmp_df, DFmode, 0);
13493        emit_insn (gen_anddi3 (tmp_di, tmp_di, GEN_INT (0x70007f0ffLL)));
13495        operands[0] = simplify_gen_subreg (DFmode, tmp_di, DImode, 0);
13496        DONE;
13497     }
13499     emit_insn (gen_rs6000_mffsl_hw (operands[0]));
13500     DONE;
13503 (define_insn "rs6000_mffs"
13504   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
13505         (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFS))]
13506   "TARGET_HARD_FLOAT"
13507   "mffs %0")
13509 (define_insn "rs6000_mtfsf"
13510   [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "i")
13511                      (match_operand:DF 1 "gpc_reg_operand" "d")]
13512                     UNSPECV_MTFSF)]
13513   "TARGET_HARD_FLOAT"
13514   "mtfsf %0,%1")
13516 (define_insn "rs6000_mtfsf_hi"
13517   [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "n")
13518                      (match_operand:DF 1 "gpc_reg_operand" "d")]
13519                     UNSPECV_MTFSF_HI)]
13520   "TARGET_HARD_FLOAT"
13521   "mtfsf %0,%1,0,1")
13524 ;; Power8 fusion support for fusing an addis instruction with a D-form load of
13525 ;; a GPR.  The addis instruction must be adjacent to the load, and use the same
13526 ;; register that is being loaded.  The fused ops must be physically adjacent.
13528 ;; On Power8 GPR loads, we try to use the register that is being load.  The
13529 ;; peephole2 then gathers any other fused possibilities that it can find after
13530 ;; register allocation.  If power9 fusion is selected, we also fuse floating
13531 ;; point loads/stores.
13533 ;; Find cases where the addis that feeds into a load instruction is either used
13534 ;; once or is the same as the target register, and replace it with the fusion
13535 ;; insn
13537 (define_peephole2
13538   [(set (match_operand:P 0 "base_reg_operand")
13539         (match_operand:P 1 "fusion_gpr_addis"))
13540    (set (match_operand:INT1 2 "base_reg_operand")
13541         (match_operand:INT1 3 "fusion_gpr_mem_load"))]
13542   "TARGET_P8_FUSION
13543    && fusion_gpr_load_p (operands[0], operands[1], operands[2],
13544                          operands[3])"
13545   [(const_int 0)]
13547   expand_fusion_gpr_load (operands);
13548   DONE;
13551 ;; Fusion insn, created by the define_peephole2 above (and eventually by
13552 ;; reload)
13554 (define_insn "*fusion_gpr_load_<mode>"
13555   [(set (match_operand:INT1 0 "base_reg_operand" "=b")
13556         (unspec:INT1 [(match_operand:INT1 1 "fusion_addis_mem_combo_load" "wF")]
13557                      UNSPEC_FUSION_GPR))]
13558   "TARGET_P8_FUSION"
13560   return emit_fusion_gpr_load (operands[0], operands[1]);
13562   [(set_attr "type" "load")
13563    (set_attr "length" "8")])
13566 ;; Optimize cases where we want to do a D-form load (register+offset) on
13567 ;; ISA 2.06/2.07 to an Altivec register, and the register allocator
13568 ;; has generated:
13569 ;;      LFD 0,32(3)
13570 ;;      XXLOR 32,0,0
13572 ;; and we change this to:
13573 ;;      LI 0,32
13574 ;;      LXSDX 32,3,9
13576 (define_peephole2
13577   [(match_scratch:P 0 "b")
13578    (set (match_operand:ALTIVEC_DFORM 1 "fpr_reg_operand")
13579         (match_operand:ALTIVEC_DFORM 2 "simple_offsettable_mem_operand"))
13580    (set (match_operand:ALTIVEC_DFORM 3 "altivec_register_operand")
13581         (match_dup 1))]
13582   "TARGET_VSX && !TARGET_P9_VECTOR && peep2_reg_dead_p (2, operands[1])"
13583   [(set (match_dup 0)
13584         (match_dup 4))
13585    (set (match_dup 3)
13586         (match_dup 5))]
13588   rtx tmp_reg = operands[0];
13589   rtx mem = operands[2];
13590   rtx addr = XEXP (mem, 0);
13591   rtx add_op0, add_op1, new_addr;
13593   gcc_assert (GET_CODE (addr) == PLUS || GET_CODE (addr) == LO_SUM);
13594   add_op0 = XEXP (addr, 0);
13595   add_op1 = XEXP (addr, 1);
13596   gcc_assert (REG_P (add_op0));
13597   new_addr = gen_rtx_PLUS (Pmode, add_op0, tmp_reg);
13599   operands[4] = add_op1;
13600   operands[5] = change_address (mem, <MODE>mode, new_addr);
13603 ;; Optimize cases were want to do a D-form store on ISA 2.06/2.07 from an
13604 ;; Altivec register, and the register allocator has generated:
13605 ;;      XXLOR 0,32,32
13606 ;;      STFD 0,32(3)
13608 ;; and we change this to:
13609 ;;      LI 0,32
13610 ;;      STXSDX 32,3,9
13612 (define_peephole2
13613   [(match_scratch:P 0 "b")
13614    (set (match_operand:ALTIVEC_DFORM 1 "fpr_reg_operand")
13615         (match_operand:ALTIVEC_DFORM 2 "altivec_register_operand"))
13616    (set (match_operand:ALTIVEC_DFORM 3 "simple_offsettable_mem_operand")
13617         (match_dup 1))]
13618   "TARGET_VSX && !TARGET_P9_VECTOR && peep2_reg_dead_p (2, operands[1])"
13619   [(set (match_dup 0)
13620         (match_dup 4))
13621    (set (match_dup 5)
13622         (match_dup 2))]
13624   rtx tmp_reg = operands[0];
13625   rtx mem = operands[3];
13626   rtx addr = XEXP (mem, 0);
13627   rtx add_op0, add_op1, new_addr;
13629   gcc_assert (GET_CODE (addr) == PLUS || GET_CODE (addr) == LO_SUM);
13630   add_op0 = XEXP (addr, 0);
13631   add_op1 = XEXP (addr, 1);
13632   gcc_assert (REG_P (add_op0));
13633   new_addr = gen_rtx_PLUS (Pmode, add_op0, tmp_reg);
13635   operands[4] = add_op1;
13636   operands[5] = change_address (mem, <MODE>mode, new_addr);
13638    
13640 ;; Miscellaneous ISA 2.06 (power7) instructions
13641 (define_insn "addg6s"
13642   [(set (match_operand:SI 0 "register_operand" "=r")
13643         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
13644                     (match_operand:SI 2 "register_operand" "r")]
13645                    UNSPEC_ADDG6S))]
13646   "TARGET_POPCNTD"
13647   "addg6s %0,%1,%2"
13648   [(set_attr "type" "integer")])
13650 (define_insn "cdtbcd"
13651   [(set (match_operand:SI 0 "register_operand" "=r")
13652         (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
13653                    UNSPEC_CDTBCD))]
13654   "TARGET_POPCNTD"
13655   "cdtbcd %0,%1"
13656   [(set_attr "type" "integer")])
13658 (define_insn "cbcdtd"
13659   [(set (match_operand:SI 0 "register_operand" "=r")
13660         (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
13661                    UNSPEC_CBCDTD))]
13662   "TARGET_POPCNTD"
13663   "cbcdtd %0,%1"
13664   [(set_attr "type" "integer")])
13666 (define_int_iterator UNSPEC_DIV_EXTEND [UNSPEC_DIVE
13667                                         UNSPEC_DIVEU])
13669 (define_int_attr div_extend [(UNSPEC_DIVE       "e")
13670                              (UNSPEC_DIVEU      "eu")])
13672 (define_insn "div<div_extend>_<mode>"
13673   [(set (match_operand:GPR 0 "register_operand" "=r")
13674         (unspec:GPR [(match_operand:GPR 1 "register_operand" "r")
13675                      (match_operand:GPR 2 "register_operand" "r")]
13676                     UNSPEC_DIV_EXTEND))]
13677   "TARGET_POPCNTD"
13678   "div<wd><div_extend> %0,%1,%2"
13679   [(set_attr "type" "div")
13680    (set_attr "size" "<bits>")])
13683 ;; Pack/unpack 128-bit floating point types that take 2 scalar registers
13685 ; Type of the 64-bit part when packing/unpacking 128-bit floating point types
13686 (define_mode_attr FP128_64 [(TF "DF")
13687                             (IF "DF")
13688                             (TD "DI")
13689                             (KF "DI")])
13691 (define_expand "unpack<mode>"
13692   [(set (match_operand:<FP128_64> 0 "nonimmediate_operand")
13693         (unspec:<FP128_64>
13694          [(match_operand:FMOVE128 1 "register_operand")
13695           (match_operand:QI 2 "const_0_to_1_operand")]
13696          UNSPEC_UNPACK_128BIT))]
13697   "FLOAT128_2REG_P (<MODE>mode)"
13698   "")
13700 (define_insn_and_split "unpack<mode>_dm"
13701   [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m,d,r,m")
13702         (unspec:<FP128_64>
13703          [(match_operand:FMOVE128 1 "register_operand" "d,d,r,d,r")
13704           (match_operand:QI 2 "const_0_to_1_operand" "i,i,i,i,i")]
13705          UNSPEC_UNPACK_128BIT))]
13706   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE && FLOAT128_2REG_P (<MODE>mode)"
13707   "#"
13708   "&& reload_completed"
13709   [(set (match_dup 0) (match_dup 3))]
13711   unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
13713   if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
13714     {
13715       emit_note (NOTE_INSN_DELETED);
13716       DONE;
13717     }
13719   operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
13721   [(set_attr "type" "fp,fpstore,mffgpr,mftgpr,store")])
13723 (define_insn_and_split "unpack<mode>_nodm"
13724   [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m")
13725         (unspec:<FP128_64>
13726          [(match_operand:FMOVE128 1 "register_operand" "d,d")
13727           (match_operand:QI 2 "const_0_to_1_operand" "i,i")]
13728          UNSPEC_UNPACK_128BIT))]
13729   "(!TARGET_POWERPC64 || !TARGET_DIRECT_MOVE) && FLOAT128_2REG_P (<MODE>mode)"
13730   "#"
13731   "&& reload_completed"
13732   [(set (match_dup 0) (match_dup 3))]
13734   unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
13736   if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
13737     {
13738       emit_note (NOTE_INSN_DELETED);
13739       DONE;
13740     }
13742   operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
13744   [(set_attr "type" "fp,fpstore")])
13746 (define_insn_and_split "pack<mode>"
13747   [(set (match_operand:FMOVE128 0 "register_operand" "=&d")
13748         (unspec:FMOVE128
13749          [(match_operand:<FP128_64> 1 "register_operand" "d")
13750           (match_operand:<FP128_64> 2 "register_operand" "d")]
13751          UNSPEC_PACK_128BIT))]
13752   "FLOAT128_2REG_P (<MODE>mode)"
13753   "#"
13754   "&& reload_completed"
13755   [(set (match_dup 3) (match_dup 1))
13756    (set (match_dup 4) (match_dup 2))]
13758   unsigned dest_hi = REGNO (operands[0]);
13759   unsigned dest_lo = dest_hi + 1;
13761   gcc_assert (!IN_RANGE (REGNO (operands[1]), dest_hi, dest_lo));
13762   gcc_assert (!IN_RANGE (REGNO (operands[2]), dest_hi, dest_lo));
13764   operands[3] = gen_rtx_REG (<FP128_64>mode, dest_hi);
13765   operands[4] = gen_rtx_REG (<FP128_64>mode, dest_lo);
13767   [(set_attr "type" "fp")
13768    (set_attr "length" "8")])
13770 (define_insn "unpack<mode>"
13771   [(set (match_operand:DI 0 "register_operand" "=wa,wa")
13772         (unspec:DI [(match_operand:FMOVE128_VSX 1 "register_operand" "0,wa")
13773                     (match_operand:QI 2 "const_0_to_1_operand" "O,i")]
13774          UNSPEC_UNPACK_128BIT))]
13775   "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)"
13777   if (REGNO (operands[0]) == REGNO (operands[1]) && INTVAL (operands[2]) == 0)
13778     return ASM_COMMENT_START " xxpermdi to same register";
13780   operands[3] = GEN_INT (INTVAL (operands[2]) == 0 ? 0 : 3);
13781   return "xxpermdi %x0,%x1,%x1,%3";
13783   [(set_attr "type" "vecperm")])
13785 (define_insn "pack<mode>"
13786   [(set (match_operand:FMOVE128_VSX 0 "register_operand" "=wa")
13787         (unspec:FMOVE128_VSX
13788          [(match_operand:DI 1 "register_operand" "wa")
13789           (match_operand:DI 2 "register_operand" "wa")]
13790          UNSPEC_PACK_128BIT))]
13791   "TARGET_VSX"
13792   "xxpermdi %x0,%x1,%x2,0"
13793   [(set_attr "type" "vecperm")])
13797 ;; ISA 2.08 IEEE 128-bit floating point support.
13799 (define_insn "add<mode>3"
13800   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13801         (plus:IEEE128
13802          (match_operand:IEEE128 1 "altivec_register_operand" "v")
13803          (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13804   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13805   "xsaddqp %0,%1,%2"
13806   [(set_attr "type" "vecfloat")
13807    (set_attr "size" "128")])
13809 (define_insn "sub<mode>3"
13810   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13811         (minus:IEEE128
13812          (match_operand:IEEE128 1 "altivec_register_operand" "v")
13813          (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13814   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13815   "xssubqp %0,%1,%2"
13816   [(set_attr "type" "vecfloat")
13817    (set_attr "size" "128")])
13819 (define_insn "mul<mode>3"
13820   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13821         (mult:IEEE128
13822          (match_operand:IEEE128 1 "altivec_register_operand" "v")
13823          (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13824   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13825   "xsmulqp %0,%1,%2"
13826   [(set_attr "type" "qmul")
13827    (set_attr "size" "128")])
13829 (define_insn "div<mode>3"
13830   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13831         (div:IEEE128
13832          (match_operand:IEEE128 1 "altivec_register_operand" "v")
13833          (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13834   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13835   "xsdivqp %0,%1,%2"
13836   [(set_attr "type" "vecdiv")
13837    (set_attr "size" "128")])
13839 (define_insn "sqrt<mode>2"
13840   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13841         (sqrt:IEEE128
13842          (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
13843   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13844    "xssqrtqp %0,%1"
13845   [(set_attr "type" "vecdiv")
13846    (set_attr "size" "128")])
13848 (define_expand "copysign<mode>3"
13849   [(use (match_operand:IEEE128 0 "altivec_register_operand"))
13850    (use (match_operand:IEEE128 1 "altivec_register_operand"))
13851    (use (match_operand:IEEE128 2 "altivec_register_operand"))]
13852   "FLOAT128_IEEE_P (<MODE>mode)"
13854   if (TARGET_FLOAT128_HW)
13855     emit_insn (gen_copysign<mode>3_hard (operands[0], operands[1],
13856                                          operands[2]));
13857   else
13858     emit_insn (gen_copysign<mode>3_soft (operands[0], operands[1],
13859                                          operands[2]));
13860   DONE;
13863 (define_insn "copysign<mode>3_hard"
13864   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13865         (unspec:IEEE128
13866          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
13867           (match_operand:IEEE128 2 "altivec_register_operand" "v")]
13868          UNSPEC_COPYSIGN))]
13869   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13870    "xscpsgnqp %0,%2,%1"
13871   [(set_attr "type" "vecmove")
13872    (set_attr "size" "128")])
13874 (define_insn "copysign<mode>3_soft"
13875   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13876         (unspec:IEEE128
13877          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
13878           (match_operand:IEEE128 2 "altivec_register_operand" "v")]
13879          UNSPEC_COPYSIGN))
13880    (clobber (match_scratch:IEEE128 3 "=&v"))]
13881   "!TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13882    "xscpsgndp %x3,%x2,%x1\;xxpermdi %x0,%x3,%x1,1"
13883   [(set_attr "type" "veccomplex")
13884    (set_attr "length" "8")])
13886 (define_insn "@neg<mode>2_hw"
13887   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13888         (neg:IEEE128
13889          (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
13890   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13891   "xsnegqp %0,%1"
13892   [(set_attr "type" "vecmove")
13893    (set_attr "size" "128")])
13896 (define_insn "@abs<mode>2_hw"
13897   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13898         (abs:IEEE128
13899          (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
13900   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13901   "xsabsqp %0,%1"
13902   [(set_attr "type" "vecmove")
13903    (set_attr "size" "128")])
13906 (define_insn "*nabs<mode>2_hw"
13907   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13908         (neg:IEEE128
13909          (abs:IEEE128
13910           (match_operand:IEEE128 1 "altivec_register_operand" "v"))))]
13911   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13912   "xsnabsqp %0,%1"
13913   [(set_attr "type" "vecmove")
13914    (set_attr "size" "128")])
13916 ;; Initially don't worry about doing fusion
13917 (define_insn "fma<mode>4_hw"
13918   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13919         (fma:IEEE128
13920          (match_operand:IEEE128 1 "altivec_register_operand" "%v")
13921          (match_operand:IEEE128 2 "altivec_register_operand" "v")
13922          (match_operand:IEEE128 3 "altivec_register_operand" "0")))]
13923   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13924   "xsmaddqp %0,%1,%2"
13925   [(set_attr "type" "qmul")
13926    (set_attr "size" "128")])
13928 (define_insn "*fms<mode>4_hw"
13929   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13930         (fma:IEEE128
13931          (match_operand:IEEE128 1 "altivec_register_operand" "%v")
13932          (match_operand:IEEE128 2 "altivec_register_operand" "v")
13933          (neg:IEEE128
13934           (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
13935   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13936   "xsmsubqp %0,%1,%2"
13937   [(set_attr "type" "qmul")
13938    (set_attr "size" "128")])
13940 (define_insn "*nfma<mode>4_hw"
13941   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13942         (neg:IEEE128
13943          (fma:IEEE128
13944           (match_operand:IEEE128 1 "altivec_register_operand" "%v")
13945           (match_operand:IEEE128 2 "altivec_register_operand" "v")
13946           (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
13947   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13948   "xsnmaddqp %0,%1,%2"
13949   [(set_attr "type" "qmul")
13950    (set_attr "size" "128")])
13952 (define_insn "*nfms<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           (neg:IEEE128
13959            (match_operand:IEEE128 3 "altivec_register_operand" "0")))))]
13960   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13961   "xsnmsubqp %0,%1,%2"
13962   [(set_attr "type" "qmul")
13963    (set_attr "size" "128")])
13965 (define_insn "extend<SFDF:mode><IEEE128:mode>2_hw"
13966   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13967         (float_extend:IEEE128
13968          (match_operand:SFDF 1 "altivec_register_operand" "v")))]
13969   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
13970   "xscvdpqp %0,%1"
13971   [(set_attr "type" "vecfloat")
13972    (set_attr "size" "128")])
13974 ;; Conversion between KFmode and TFmode if TFmode is ieee 128-bit floating
13975 ;; point is a simple copy.
13976 (define_insn_and_split "extendkftf2"
13977   [(set (match_operand:TF 0 "vsx_register_operand" "=wa,?wa")
13978         (float_extend:TF (match_operand:KF 1 "vsx_register_operand" "0,wa")))]
13979   "TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD"
13980   "@
13981    #
13982    xxlor %x0,%x1,%x1"
13983   "&& reload_completed  && REGNO (operands[0]) == REGNO (operands[1])"
13984   [(const_int 0)]
13986   emit_note (NOTE_INSN_DELETED);
13987   DONE;
13989   [(set_attr "type" "*,veclogical")
13990    (set_attr "length" "0,4")])
13992 (define_insn_and_split "trunctfkf2"
13993   [(set (match_operand:KF 0 "vsx_register_operand" "=wa,?wa")
13994         (float_extend:KF (match_operand:TF 1 "vsx_register_operand" "0,wa")))]
13995   "TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD"
13996   "@
13997    #
13998    xxlor %x0,%x1,%x1"
13999   "&& reload_completed  && REGNO (operands[0]) == REGNO (operands[1])"
14000   [(const_int 0)]
14002   emit_note (NOTE_INSN_DELETED);
14003   DONE;
14005   [(set_attr "type" "*,veclogical")
14006    (set_attr "length" "0,4")])
14008 (define_insn "trunc<mode>df2_hw"
14009   [(set (match_operand:DF 0 "altivec_register_operand" "=v")
14010         (float_truncate:DF
14011          (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14012   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14013   "xscvqpdp %0,%1"
14014   [(set_attr "type" "vecfloat")
14015    (set_attr "size" "128")])
14017 ;; There is no KFmode -> SFmode instruction. Preserve the accuracy by doing
14018 ;; the KFmode -> DFmode conversion using round to odd rather than the normal
14019 ;; conversion
14020 (define_insn_and_split "trunc<mode>sf2_hw"
14021   [(set (match_operand:SF 0 "vsx_register_operand" "=wa")
14022         (float_truncate:SF
14023          (match_operand:IEEE128 1 "altivec_register_operand" "v")))
14024    (clobber (match_scratch:DF 2 "=v"))]
14025   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14026   "#"
14027   "&& 1"
14028   [(set (match_dup 2)
14029         (unspec:DF [(match_dup 1)]
14030                    UNSPEC_TRUNC_ROUND_TO_ODD))
14031    (set (match_dup 0)
14032         (float_truncate:SF (match_dup 2)))]
14034   if (GET_CODE (operands[2]) == SCRATCH)
14035     operands[2] = gen_reg_rtx (DFmode);
14037   [(set_attr "type" "vecfloat")
14038    (set_attr "length" "8")
14039    (set_attr "isa" "p8v")])
14041 ;; Conversion between IEEE 128-bit and integer types
14043 ;; The fix function for DImode and SImode was declared earlier as a
14044 ;; define_expand.  It calls into rs6000_expand_float128_convert if we don't
14045 ;; have IEEE 128-bit hardware support.  QImode and HImode are not provided
14046 ;; unless we have the IEEE 128-bit hardware.
14048 ;; Unlike the code for converting SFmode/DFmode to QImode/HImode, we don't have
14049 ;; to provide a GPR target that used direct move and a conversion in the GPR
14050 ;; which works around QImode/HImode not being allowed in vector registers in
14051 ;; ISA 2.07 (power8).
14052 (define_insn "fix<uns>_<IEEE128:mode><SDI:mode>2_hw"
14053   [(set (match_operand:SDI 0 "altivec_register_operand" "=v")
14054         (any_fix:SDI (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14055   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14056   "xscvqp<su><wd>z %0,%1"
14057   [(set_attr "type" "vecfloat")
14058    (set_attr "size" "128")])
14060 (define_insn "fix<uns>_trunc<IEEE128:mode><QHI:mode>2"
14061   [(set (match_operand:QHI 0 "altivec_register_operand" "=v")
14062         (any_fix:QHI
14063          (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14064   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14065   "xscvqp<su>wz %0,%1"
14066   [(set_attr "type" "vecfloat")
14067    (set_attr "size" "128")])
14069 ;; Combiner patterns to prevent moving the result of converting an IEEE 128-bit
14070 ;; floating point value to 8/16/32-bit integer to GPR in order to save it.
14071 (define_insn_and_split "*fix<uns>_trunc<IEEE128:mode><QHSI:mode>2_mem"
14072   [(set (match_operand:QHSI 0 "memory_operand" "=Z")
14073         (any_fix:QHSI
14074          (match_operand:IEEE128 1 "altivec_register_operand" "v")))
14075    (clobber (match_scratch:QHSI 2 "=v"))]
14076   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14077   "#"
14078   "&& reload_completed"
14079   [(set (match_dup 2)
14080         (any_fix:QHSI (match_dup 1)))
14081    (set (match_dup 0)
14082         (match_dup 2))])
14084 (define_insn "float_<mode>di2_hw"
14085   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14086         (float:IEEE128 (match_operand:DI 1 "altivec_register_operand" "v")))]
14087   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14088   "xscvsdqp %0,%1"
14089   [(set_attr "type" "vecfloat")
14090    (set_attr "size" "128")])
14092 (define_insn_and_split "float_<mode>si2_hw"
14093   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14094         (float:IEEE128 (match_operand:SI 1 "nonimmediate_operand" "vrZ")))
14095    (clobber (match_scratch:DI 2 "=v"))]
14096   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14097   "#"
14098   "&& 1"
14099   [(set (match_dup 2)
14100         (sign_extend:DI (match_dup 1)))
14101    (set (match_dup 0)
14102         (float:IEEE128 (match_dup 2)))]
14104   if (GET_CODE (operands[2]) == SCRATCH)
14105     operands[2] = gen_reg_rtx (DImode);
14107   if (MEM_P (operands[1]))
14108     operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
14111 (define_insn_and_split "float<QHI:mode><IEEE128:mode>2"
14112   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v")
14113         (float:IEEE128 (match_operand:QHI 1 "nonimmediate_operand" "v,r,Z")))
14114    (clobber (match_scratch:DI 2 "=X,r,X"))]
14115   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14116   "#"
14117   "&& reload_completed"
14118   [(const_int 0)]
14120   rtx dest = operands[0];
14121   rtx src = operands[1];
14122   rtx dest_di = gen_rtx_REG (DImode, REGNO (dest));
14124   if (altivec_register_operand (src, <QHI:MODE>mode))
14125     emit_insn (gen_extend<QHI:mode>di2 (dest_di, src));
14126   else if (int_reg_operand (src, <QHI:MODE>mode))
14127     {
14128       rtx ext_di = operands[2];
14129       emit_insn (gen_extend<QHI:mode>di2 (ext_di, src));
14130       emit_move_insn (dest_di, ext_di);
14131     }
14132   else if (MEM_P (src))
14133     {
14134       rtx dest_qhi = gen_rtx_REG (<QHI:MODE>mode, REGNO (dest));
14135       emit_move_insn (dest_qhi, src);
14136       emit_insn (gen_extend<QHI:mode>di2 (dest_di, dest_qhi));
14137     }
14138   else
14139     gcc_unreachable ();
14141   emit_insn (gen_float_<IEEE128:mode>di2_hw (dest, dest_di));
14142   DONE;
14144   [(set_attr "length" "8,12,12")
14145    (set_attr "type" "vecfloat")
14146    (set_attr "size" "128")])
14148 (define_insn "floatuns_<mode>di2_hw"
14149   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14150         (unsigned_float:IEEE128
14151          (match_operand:DI 1 "altivec_register_operand" "v")))]
14152   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14153   "xscvudqp %0,%1"
14154   [(set_attr "type" "vecfloat")
14155    (set_attr "size" "128")])
14157 (define_insn_and_split "floatuns_<mode>si2_hw"
14158   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14159         (unsigned_float:IEEE128
14160          (match_operand:SI 1 "nonimmediate_operand" "vrZ")))
14161    (clobber (match_scratch:DI 2 "=v"))]
14162   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14163   "#"
14164   "&& 1"
14165   [(set (match_dup 2)
14166         (zero_extend:DI (match_dup 1)))
14167    (set (match_dup 0)
14168         (float:IEEE128 (match_dup 2)))]
14170   if (GET_CODE (operands[2]) == SCRATCH)
14171     operands[2] = gen_reg_rtx (DImode);
14173   if (MEM_P (operands[1]))
14174     operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
14177 (define_insn_and_split "floatuns<QHI:mode><IEEE128:mode>2"
14178   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v")
14179         (unsigned_float:IEEE128
14180          (match_operand:QHI 1 "nonimmediate_operand" "v,r,Z")))
14181    (clobber (match_scratch:DI 2 "=X,r,X"))]
14182   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14183   "#"
14184   "&& reload_completed"
14185   [(const_int 0)]
14187   rtx dest = operands[0];
14188   rtx src = operands[1];
14189   rtx dest_di = gen_rtx_REG (DImode, REGNO (dest));
14191   if (altivec_register_operand (src, <QHI:MODE>mode) || MEM_P (src))
14192     emit_insn (gen_zero_extend<QHI:mode>di2 (dest_di, src));
14193   else if (int_reg_operand (src, <QHI:MODE>mode))
14194     {
14195       rtx ext_di = operands[2];
14196       emit_insn (gen_zero_extend<QHI:mode>di2 (ext_di, src));
14197       emit_move_insn (dest_di, ext_di);
14198     }
14199   else
14200     gcc_unreachable ();
14202   emit_insn (gen_floatuns_<IEEE128:mode>di2_hw (dest, dest_di));
14203   DONE;
14205   [(set_attr "length" "8,12,8")
14206    (set_attr "type" "vecfloat")
14207    (set_attr "size" "128")])
14209 ;; IEEE 128-bit round to integer built-in functions
14210 (define_insn "floor<mode>2"
14211   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14212         (unspec:IEEE128
14213          [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14214          UNSPEC_FRIM))]
14215   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14216   "xsrqpi 1,%0,%1,3"
14217   [(set_attr "type" "vecfloat")
14218    (set_attr "size" "128")])
14220 (define_insn "ceil<mode>2"
14221   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14222         (unspec:IEEE128
14223          [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14224          UNSPEC_FRIP))]
14225   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14226   "xsrqpi 1,%0,%1,2"
14227   [(set_attr "type" "vecfloat")
14228    (set_attr "size" "128")])
14230 (define_insn "btrunc<mode>2"
14231   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14232         (unspec:IEEE128
14233          [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14234          UNSPEC_FRIZ))]
14235   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14236   "xsrqpi 1,%0,%1,1"
14237   [(set_attr "type" "vecfloat")
14238    (set_attr "size" "128")])
14240 (define_insn "round<mode>2"
14241   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14242         (unspec:IEEE128
14243          [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14244          UNSPEC_FRIN))]
14245   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14246   "xsrqpi 0,%0,%1,0"
14247   [(set_attr "type" "vecfloat")
14248    (set_attr "size" "128")])
14250 ;; IEEE 128-bit instructions with round to odd semantics
14251 (define_insn "add<mode>3_odd"
14252   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14253         (unspec:IEEE128
14254          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14255           (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14256          UNSPEC_ADD_ROUND_TO_ODD))]
14257   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14258   "xsaddqpo %0,%1,%2"
14259   [(set_attr "type" "vecfloat")
14260    (set_attr "size" "128")])
14262 (define_insn "sub<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_SUB_ROUND_TO_ODD))]
14268   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14269   "xssubqpo %0,%1,%2"
14270   [(set_attr "type" "vecfloat")
14271    (set_attr "size" "128")])
14273 (define_insn "mul<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_MUL_ROUND_TO_ODD))]
14279   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14280   "xsmulqpo %0,%1,%2"
14281   [(set_attr "type" "qmul")
14282    (set_attr "size" "128")])
14284 (define_insn "div<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_DIV_ROUND_TO_ODD))]
14290   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14291   "xsdivqpo %0,%1,%2"
14292   [(set_attr "type" "vecdiv")
14293    (set_attr "size" "128")])
14295 (define_insn "sqrt<mode>2_odd"
14296   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14297         (unspec:IEEE128
14298          [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14299          UNSPEC_SQRT_ROUND_TO_ODD))]
14300   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14301    "xssqrtqpo %0,%1"
14302   [(set_attr "type" "vecdiv")
14303    (set_attr "size" "128")])
14305 (define_insn "fma<mode>4_odd"
14306   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14307         (unspec:IEEE128
14308          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14309           (match_operand:IEEE128 2 "altivec_register_operand" "v")
14310           (match_operand:IEEE128 3 "altivec_register_operand" "0")]
14311          UNSPEC_FMA_ROUND_TO_ODD))]
14312   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14313   "xsmaddqpo %0,%1,%2"
14314   [(set_attr "type" "qmul")
14315    (set_attr "size" "128")])
14317 (define_insn "*fms<mode>4_odd"
14318   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14319         (unspec:IEEE128
14320          [(match_operand:IEEE128 1 "altivec_register_operand" "%v")
14321           (match_operand:IEEE128 2 "altivec_register_operand" "v")
14322           (neg:IEEE128
14323            (match_operand:IEEE128 3 "altivec_register_operand" "0"))]
14324          UNSPEC_FMA_ROUND_TO_ODD))]
14325   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14326   "xsmsubqpo %0,%1,%2"
14327   [(set_attr "type" "qmul")
14328    (set_attr "size" "128")])
14330 (define_insn "*nfma<mode>4_odd"
14331   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14332         (neg:IEEE128
14333          (unspec:IEEE128
14334           [(match_operand:IEEE128 1 "altivec_register_operand" "%v")
14335            (match_operand:IEEE128 2 "altivec_register_operand" "v")
14336            (match_operand:IEEE128 3 "altivec_register_operand" "0")]
14337           UNSPEC_FMA_ROUND_TO_ODD)))]
14338   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14339   "xsnmaddqpo %0,%1,%2"
14340   [(set_attr "type" "qmul")
14341    (set_attr "size" "128")])
14343 (define_insn "*nfms<mode>4_odd"
14344   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14345         (neg:IEEE128
14346          (unspec:IEEE128
14347           [(match_operand:IEEE128 1 "altivec_register_operand" "%v")
14348            (match_operand:IEEE128 2 "altivec_register_operand" "v")
14349            (neg:IEEE128
14350             (match_operand:IEEE128 3 "altivec_register_operand" "0"))]
14351           UNSPEC_FMA_ROUND_TO_ODD)))]
14352   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14353   "xsnmsubqpo %0,%1,%2"
14354   [(set_attr "type" "qmul")
14355    (set_attr "size" "128")])
14357 (define_insn "trunc<mode>df2_odd"
14358   [(set (match_operand:DF 0 "vsx_register_operand" "=v")
14359         (unspec:DF [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14360                    UNSPEC_TRUNC_ROUND_TO_ODD))]
14361   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14362   "xscvqpdpo %0,%1"
14363   [(set_attr "type" "vecfloat")
14364    (set_attr "size" "128")])
14366 ;; IEEE 128-bit comparisons
14367 (define_insn "*cmp<mode>_hw"
14368   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
14369         (compare:CCFP (match_operand:IEEE128 1 "altivec_register_operand" "v")
14370                       (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14371   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14372    "xscmpuqp %0,%1,%2"
14373   [(set_attr "type" "veccmp")
14374    (set_attr "size" "128")])
14378 (include "sync.md")
14379 (include "vector.md")
14380 (include "vsx.md")
14381 (include "altivec.md")
14382 (include "dfp.md")
14383 (include "crypto.md")
14384 (include "htm.md")