rs6000: Rename isa attribute "fut" to "p10"
[gcc.git] / gcc / config / rs6000 / rs6000.md
1 ;; Machine description for IBM RISC System 6000 (POWER) for GNU C compiler
2 ;; Copyright (C) 1990-2020 Free Software Foundation, Inc.
3 ;; Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
4
5 ;; This file is part of GCC.
6
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.
11
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.
16
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/>.
20
21 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
22
23 ;;
24 ;; REGNOS
25 ;;
26
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 ])
55
56 ;;
57 ;; UNSPEC usage
58 ;;
59
60 (define_c_enum "unspec"
61 [UNSPEC_PROBE_STACK ; probe stack memory reference
62 UNSPEC_TOCPTR ; address of a word pointing to the TOC
63 UNSPEC_TOC ; address of the TOC (more-or-less)
64 UNSPEC_TOCSLOT ; offset from r1 of toc pointer save slot
65 UNSPEC_MOVSI_GOT
66 UNSPEC_FCTIWZ
67 UNSPEC_FRIM
68 UNSPEC_FRIN
69 UNSPEC_FRIP
70 UNSPEC_FRIZ
71 UNSPEC_XSRDPI
72 UNSPEC_LD_MPIC ; load_macho_picbase
73 UNSPEC_RELD_MPIC ; re-load_macho_picbase
74 UNSPEC_MPIC_CORRECT ; macho_correct_pic
75 UNSPEC_TLSGD
76 UNSPEC_TLSLD
77 UNSPEC_TLS_GET_ADDR
78 UNSPEC_MOVESI_FROM_CR
79 UNSPEC_MOVESI_TO_CR
80 UNSPEC_TLSDTPREL
81 UNSPEC_TLSDTPRELHA
82 UNSPEC_TLSDTPRELLO
83 UNSPEC_TLSGOTDTPREL
84 UNSPEC_TLSTPREL
85 UNSPEC_TLSTPRELHA
86 UNSPEC_TLSTPRELLO
87 UNSPEC_TLSGOTTPREL
88 UNSPEC_TLSTLS
89 UNSPEC_TLSTLS_PCREL
90 UNSPEC_FIX_TRUNC_TF ; fadd, rounding towards zero
91 UNSPEC_STFIWX
92 UNSPEC_POPCNTB
93 UNSPEC_FRES
94 UNSPEC_SP_SET
95 UNSPEC_SP_TEST
96 UNSPEC_SYNC
97 UNSPEC_LWSYNC
98 UNSPEC_SYNC_OP
99 UNSPEC_ATOMIC
100 UNSPEC_CMPXCHG
101 UNSPEC_XCHG
102 UNSPEC_AND
103 UNSPEC_DLMZB
104 UNSPEC_DLMZB_CR
105 UNSPEC_DLMZB_STRLEN
106 UNSPEC_RSQRT
107 UNSPEC_TOCREL
108 UNSPEC_MACHOPIC_OFFSET
109 UNSPEC_BPERM
110 UNSPEC_COPYSIGN
111 UNSPEC_PARITY
112 UNSPEC_CMPB
113 UNSPEC_FCTIW
114 UNSPEC_FCTID
115 UNSPEC_LFIWAX
116 UNSPEC_LFIWZX
117 UNSPEC_FCTIWUZ
118 UNSPEC_NOP
119 UNSPEC_GRP_END_NOP
120 UNSPEC_P8V_FMRGOW
121 UNSPEC_P8V_MTVSRWZ
122 UNSPEC_P8V_RELOAD_FROM_GPR
123 UNSPEC_P8V_MTVSRD
124 UNSPEC_P8V_XXPERMDI
125 UNSPEC_P8V_RELOAD_FROM_VSX
126 UNSPEC_ADDG6S
127 UNSPEC_CDTBCD
128 UNSPEC_CBCDTD
129 UNSPEC_DIVE
130 UNSPEC_DIVEU
131 UNSPEC_UNPACK_128BIT
132 UNSPEC_PACK_128BIT
133 UNSPEC_LSQ
134 UNSPEC_FUSION_GPR
135 UNSPEC_STACK_CHECK
136 UNSPEC_CMPRB
137 UNSPEC_CMPRB2
138 UNSPEC_CMPEQB
139 UNSPEC_ADD_ROUND_TO_ODD
140 UNSPEC_SUB_ROUND_TO_ODD
141 UNSPEC_MUL_ROUND_TO_ODD
142 UNSPEC_DIV_ROUND_TO_ODD
143 UNSPEC_FMA_ROUND_TO_ODD
144 UNSPEC_SQRT_ROUND_TO_ODD
145 UNSPEC_TRUNC_ROUND_TO_ODD
146 UNSPEC_SIGNBIT
147 UNSPEC_SF_FROM_SI
148 UNSPEC_SI_FROM_SF
149 UNSPEC_PLTSEQ
150 UNSPEC_PLT16_HA
151 UNSPEC_CFUGED
152 UNSPEC_CNTLZDM
153 UNSPEC_CNTTZDM
154 UNSPEC_PDEPD
155 UNSPEC_PEXTD
156 ])
157
158 ;;
159 ;; UNSPEC_VOLATILE usage
160 ;;
161
162 (define_c_enum "unspecv"
163 [UNSPECV_BLOCK
164 UNSPECV_LL ; load-locked
165 UNSPECV_SC ; store-conditional
166 UNSPECV_PROBE_STACK_RANGE ; probe range of stack addresses
167 UNSPECV_EH_RR ; eh_reg_restore
168 UNSPECV_ISYNC ; isync instruction
169 UNSPECV_MFTB ; move from time base
170 UNSPECV_DARN ; darn 1 (deliver a random number)
171 UNSPECV_DARN_32 ; darn 2
172 UNSPECV_DARN_RAW ; darn 0
173 UNSPECV_NLGR ; non-local goto receiver
174 UNSPECV_MFFS ; Move from FPSCR
175 UNSPECV_MFFSL ; Move from FPSCR light instruction version
176 UNSPECV_MFFSCRN ; Move from FPSCR float rounding mode
177 UNSPECV_MFFSCDRN ; Move from FPSCR decimal float rounding mode
178 UNSPECV_MTFSF ; Move to FPSCR Fields 8 to 15
179 UNSPECV_MTFSF_HI ; Move to FPSCR Fields 0 to 7
180 UNSPECV_MTFSB0 ; Set FPSCR Field bit to 0
181 UNSPECV_MTFSB1 ; Set FPSCR Field bit to 1
182 UNSPECV_SPLIT_STACK_RETURN ; A camouflaged return
183 UNSPECV_SPEC_BARRIER ; Speculation barrier
184 UNSPECV_PLT16_LO
185 UNSPECV_PLT_PCREL
186 ])
187
188 ; The three different kinds of epilogue.
189 (define_enum "epilogue_type" [normal sibcall eh_return])
190 \f
191 ;; Define an insn type attribute. This is used in function unit delay
192 ;; computations.
193 (define_attr "type"
194 "integer,two,three,
195 add,logical,shift,insert,
196 mul,halfmul,div,
197 exts,cntlz,popcnt,isel,
198 load,store,fpload,fpstore,vecload,vecstore,
199 cmp,
200 branch,jmpreg,mfjmpr,mtjmpr,trap,isync,sync,load_l,store_c,
201 cr_logical,mfcr,mfcrf,mtcr,
202 fpcompare,fp,fpsimple,dmul,qmul,sdiv,ddiv,ssqrt,dsqrt,
203 vecsimple,veccomplex,vecdiv,veccmp,veccmpsimple,vecperm,
204 vecfloat,vecfdiv,vecdouble,mffgpr,mftgpr,crypto,
205 veclogical,veccmpfx,vecexts,vecmove,
206 htm,htmsimple,dfp,mma"
207 (const_string "integer"))
208
209 ;; What data size does this instruction work on?
210 ;; This is used for insert, mul and others as necessary.
211 (define_attr "size" "8,16,32,64,128" (const_string "32"))
212
213 ;; What is the insn_cost for this insn? The target hook can still override
214 ;; this. For optimizing for size the "length" attribute is used instead.
215 (define_attr "cost" "" (const_int 0))
216
217 ;; Is this instruction record form ("dot", signed compare to 0, writing CR0)?
218 ;; This is used for add, logical, shift, exts, mul.
219 (define_attr "dot" "no,yes" (const_string "no"))
220
221 ;; Does this instruction sign-extend its result?
222 ;; This is used for load insns.
223 (define_attr "sign_extend" "no,yes" (const_string "no"))
224
225 ;; Does this cr_logical instruction have three operands? That is, BT != BB.
226 (define_attr "cr_logical_3op" "no,yes" (const_string "no"))
227
228 ;; Does this instruction use indexed (that is, reg+reg) addressing?
229 ;; This is used for load and store insns. If operand 0 or 1 is a MEM
230 ;; it is automatically set based on that. If a load or store instruction
231 ;; has fewer than two operands it needs to set this attribute manually
232 ;; or the compiler will crash.
233 (define_attr "indexed" "no,yes"
234 (if_then_else (ior (match_operand 0 "indexed_address_mem")
235 (match_operand 1 "indexed_address_mem"))
236 (const_string "yes")
237 (const_string "no")))
238
239 ;; Does this instruction use update addressing?
240 ;; This is used for load and store insns. See the comments for "indexed".
241 (define_attr "update" "no,yes"
242 (if_then_else (ior (match_operand 0 "update_address_mem")
243 (match_operand 1 "update_address_mem"))
244 (const_string "yes")
245 (const_string "no")))
246
247 ;; Is this instruction using operands[2] as shift amount, and can that be a
248 ;; register?
249 ;; This is used for shift insns.
250 (define_attr "maybe_var_shift" "no,yes" (const_string "no"))
251
252 ;; Is this instruction using a shift amount from a register?
253 ;; This is used for shift insns.
254 (define_attr "var_shift" "no,yes"
255 (if_then_else (and (eq_attr "type" "shift")
256 (eq_attr "maybe_var_shift" "yes"))
257 (if_then_else (match_operand 2 "gpc_reg_operand")
258 (const_string "yes")
259 (const_string "no"))
260 (const_string "no")))
261
262 ;; Is copying of this instruction disallowed?
263 (define_attr "cannot_copy" "no,yes" (const_string "no"))
264
265
266 ;; Whether an insn is a prefixed insn, and an initial 'p' should be printed
267 ;; before the instruction. A prefixed instruction has a prefix instruction
268 ;; word that extends the immediate value of the instructions from 12-16 bits to
269 ;; 34 bits. The macro ASM_OUTPUT_OPCODE emits a leading 'p' for prefixed
270 ;; insns. The default "length" attribute will also be adjusted by default to
271 ;; be 12 bytes.
272 (define_attr "prefixed" "no,yes"
273 (cond [(ior (match_test "!TARGET_PREFIXED")
274 (match_test "!NONJUMP_INSN_P (insn)"))
275 (const_string "no")
276
277 (eq_attr "type" "load,fpload,vecload")
278 (if_then_else (match_test "prefixed_load_p (insn)")
279 (const_string "yes")
280 (const_string "no"))
281
282 (eq_attr "type" "store,fpstore,vecstore")
283 (if_then_else (match_test "prefixed_store_p (insn)")
284 (const_string "yes")
285 (const_string "no"))
286
287 (eq_attr "type" "integer,add")
288 (if_then_else (match_test "prefixed_paddi_p (insn)")
289 (const_string "yes")
290 (const_string "no"))]
291
292 (const_string "no")))
293
294 ;; Return the number of real hardware instructions in a combined insn. If it
295 ;; is 0, just use the length / 4.
296 (define_attr "num_insns" "" (const_int 0))
297
298 ;; If an insn is prefixed, return the maximum number of prefixed instructions
299 ;; in the insn. The macro ADJUST_INSN_LENGTH uses this number to adjust the
300 ;; insn length.
301 (define_attr "max_prefixed_insns" "" (const_int 1))
302
303 ;; Length of the instruction (in bytes). This length does not consider the
304 ;; length for prefixed instructions. The macro ADJUST_INSN_LENGTH will adjust
305 ;; the length if there are prefixed instructions.
306 ;;
307 ;; While it might be tempting to use num_insns to calculate the length, it can
308 ;; be problematical unless all insn lengths are adjusted to use num_insns
309 ;; (i.e. if num_insns is 0, it will get the length, which in turn will get
310 ;; num_insns and recurse).
311 (define_attr "length" "" (const_int 4))
312
313 ;; Processor type -- this attribute must exactly match the processor_type
314 ;; enumeration in rs6000-opts.h.
315 (define_attr "cpu"
316 "ppc601,ppc603,ppc604,ppc604e,ppc620,ppc630,
317 ppc750,ppc7400,ppc7450,
318 ppc403,ppc405,ppc440,ppc476,
319 ppc8540,ppc8548,ppce300c2,ppce300c3,ppce500mc,ppce500mc64,ppce5500,ppce6500,
320 power4,power5,power6,power7,power8,power9,power10,
321 rs64a,mpccore,cell,ppca2,titan"
322 (const (symbol_ref "(enum attr_cpu) rs6000_tune")))
323
324 ;; The ISA we implement.
325 (define_attr "isa" "any,p5,p6,p7,p7v,p8v,p9v,p9kf,p9tf,p10"
326 (const_string "any"))
327
328 ;; Is this alternative enabled for the current CPU/ISA/etc.?
329 (define_attr "enabled" ""
330 (cond
331 [(eq_attr "isa" "any")
332 (const_int 1)
333
334 (and (eq_attr "isa" "p5")
335 (match_test "TARGET_POPCNTB"))
336 (const_int 1)
337
338 (and (eq_attr "isa" "p6")
339 (match_test "TARGET_CMPB"))
340 (const_int 1)
341
342 (and (eq_attr "isa" "p7")
343 (match_test "TARGET_POPCNTD"))
344 (const_int 1)
345
346 (and (eq_attr "isa" "p7v")
347 (match_test "TARGET_VSX"))
348 (const_int 1)
349
350 (and (eq_attr "isa" "p8v")
351 (match_test "TARGET_P8_VECTOR"))
352 (const_int 1)
353
354 (and (eq_attr "isa" "p9v")
355 (match_test "TARGET_P9_VECTOR"))
356 (const_int 1)
357
358 (and (eq_attr "isa" "p9kf")
359 (match_test "TARGET_FLOAT128_TYPE"))
360 (const_int 1)
361
362 (and (eq_attr "isa" "p9tf")
363 (match_test "FLOAT128_VECTOR_P (TFmode)"))
364 (const_int 1)
365
366 (and (eq_attr "isa" "p10")
367 (match_test "TARGET_POWER10"))
368 (const_int 1)
369 ] (const_int 0)))
370
371 ;; If this instruction is microcoded on the CELL processor
372 ; The default for load extended, the recorded instructions and rotate/shifts by a variable is always microcoded
373 (define_attr "cell_micro" "not,conditional,always"
374 (if_then_else (ior (and (eq_attr "type" "shift,exts,mul")
375 (eq_attr "dot" "yes"))
376 (and (eq_attr "type" "load")
377 (eq_attr "sign_extend" "yes"))
378 (and (eq_attr "type" "shift")
379 (eq_attr "var_shift" "yes")))
380 (const_string "always")
381 (const_string "not")))
382
383 (automata_option "ndfa")
384
385 (include "rs64.md")
386 (include "mpc.md")
387 (include "40x.md")
388 (include "440.md")
389 (include "476.md")
390 (include "601.md")
391 (include "603.md")
392 (include "6xx.md")
393 (include "7xx.md")
394 (include "7450.md")
395 (include "8540.md")
396 (include "e300c2c3.md")
397 (include "e500mc.md")
398 (include "e500mc64.md")
399 (include "e5500.md")
400 (include "e6500.md")
401 (include "power4.md")
402 (include "power5.md")
403 (include "power6.md")
404 (include "power7.md")
405 (include "power8.md")
406 (include "power9.md")
407 (include "power10.md")
408 (include "cell.md")
409 (include "a2.md")
410 (include "titan.md")
411
412 (include "predicates.md")
413 (include "constraints.md")
414
415 \f
416 ;; Mode iterators
417
418 ; This mode iterator allows :GPR to be used to indicate the allowable size
419 ; of whole values in GPRs.
420 (define_mode_iterator GPR [SI (DI "TARGET_POWERPC64")])
421
422 ; And again, for patterns that need two (potentially) different integer modes.
423 (define_mode_iterator GPR2 [SI (DI "TARGET_POWERPC64")])
424
425 ; Any supported integer mode.
426 (define_mode_iterator INT [QI HI SI DI TI PTI])
427
428 ; Any supported integer mode that fits in one register.
429 (define_mode_iterator INT1 [QI HI SI (DI "TARGET_POWERPC64")])
430
431 ; Integer modes supported in VSX registers with ISA 3.0 instructions
432 (define_mode_iterator INT_ISA3 [QI HI SI DI])
433
434 ; Everything we can extend QImode to.
435 (define_mode_iterator EXTQI [SI (DI "TARGET_POWERPC64")])
436
437 ; Everything we can extend HImode to.
438 (define_mode_iterator EXTHI [SI (DI "TARGET_POWERPC64")])
439
440 ; Everything we can extend SImode to.
441 (define_mode_iterator EXTSI [(DI "TARGET_POWERPC64")])
442
443 ; QImode or HImode for small integer moves and small atomic ops
444 (define_mode_iterator QHI [QI HI])
445
446 ; QImode, HImode, SImode for fused ops only for GPR loads
447 (define_mode_iterator QHSI [QI HI SI])
448
449 ; HImode or SImode for sign extended fusion ops
450 (define_mode_iterator HSI [HI SI])
451
452 ; SImode or DImode, even if DImode doesn't fit in GPRs.
453 (define_mode_iterator SDI [SI DI])
454
455 ; The size of a pointer. Also, the size of the value that a record-condition
456 ; (one with a '.') will compare; and the size used for arithmetic carries.
457 (define_mode_iterator P [(SI "TARGET_32BIT") (DI "TARGET_64BIT")])
458
459 ; Iterator to add PTImode along with TImode (TImode can go in VSX registers,
460 ; PTImode is GPR only)
461 (define_mode_iterator TI2 [TI PTI])
462
463 ; Any hardware-supported floating-point mode
464 (define_mode_iterator FP [
465 (SF "TARGET_HARD_FLOAT")
466 (DF "TARGET_HARD_FLOAT")
467 (TF "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128")
468 (IF "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128")
469 (KF "TARGET_FLOAT128_TYPE")
470 (DD "TARGET_DFP")
471 (TD "TARGET_DFP")])
472
473 ; Any fma capable floating-point mode.
474 (define_mode_iterator FMA_F [
475 (SF "TARGET_HARD_FLOAT")
476 (DF "TARGET_HARD_FLOAT || VECTOR_UNIT_VSX_P (DFmode)")
477 (V4SF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)")
478 (V2DF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V2DFmode)")
479 (KF "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (KFmode)")
480 (TF "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (TFmode)")
481 ])
482
483 ; Floating point move iterators to combine binary and decimal moves
484 (define_mode_iterator FMOVE32 [SF SD])
485 (define_mode_iterator FMOVE64 [DF DD])
486 (define_mode_iterator FMOVE64X [DI DF DD])
487 (define_mode_iterator FMOVE128 [(TF "TARGET_LONG_DOUBLE_128")
488 (IF "FLOAT128_IBM_P (IFmode)")
489 (TD "TARGET_HARD_FLOAT")])
490
491 (define_mode_iterator FMOVE128_FPR [(TF "FLOAT128_2REG_P (TFmode)")
492 (IF "FLOAT128_2REG_P (IFmode)")
493 (TD "TARGET_HARD_FLOAT")])
494
495 ; Iterators for 128 bit types for direct move
496 (define_mode_iterator FMOVE128_GPR [TI
497 V16QI
498 V8HI
499 V4SI
500 V4SF
501 V2DI
502 V2DF
503 V1TI
504 (KF "FLOAT128_VECTOR_P (KFmode)")
505 (TF "FLOAT128_VECTOR_P (TFmode)")])
506
507 ; Iterator for 128-bit VSX types for pack/unpack
508 (define_mode_iterator FMOVE128_VSX [V1TI KF])
509
510 ; Iterators for converting to/from TFmode
511 (define_mode_iterator IFKF [IF KF])
512
513 ; Constraints for moving IF/KFmode.
514 (define_mode_attr IFKF_reg [(IF "d") (KF "wa")])
515
516 ; Whether a floating point move is ok, don't allow SD without hardware FP
517 (define_mode_attr fmove_ok [(SF "")
518 (DF "")
519 (SD "TARGET_HARD_FLOAT")
520 (DD "")])
521
522 ; Convert REAL_VALUE to the appropriate bits
523 (define_mode_attr real_value_to_target [(SF "REAL_VALUE_TO_TARGET_SINGLE")
524 (DF "REAL_VALUE_TO_TARGET_DOUBLE")
525 (SD "REAL_VALUE_TO_TARGET_DECIMAL32")
526 (DD "REAL_VALUE_TO_TARGET_DECIMAL64")])
527
528 ; Whether 0.0 has an all-zero bit pattern
529 (define_mode_attr zero_fp [(SF "j")
530 (DF "j")
531 (TF "j")
532 (IF "j")
533 (KF "j")
534 (SD "wn")
535 (DD "wn")
536 (TD "wn")])
537
538 ; Definitions for 64-bit VSX
539 (define_mode_attr f64_vsx [(DF "wa") (DD "wn")])
540
541 ; Definitions for 64-bit direct move
542 (define_mode_attr f64_dm [(DF "wa") (DD "d")])
543
544 ; Definitions for 64-bit use of altivec registers
545 (define_mode_attr f64_av [(DF "v") (DD "wn")])
546
547 ; Definitions for 64-bit access to ISA 3.0 (power9) vector
548 (define_mode_attr f64_p9 [(DF "v") (DD "wn")])
549
550 ; These modes do not fit in integer registers in 32-bit mode.
551 (define_mode_iterator DIFD [DI DF DD])
552
553 ; Iterator for reciprocal estimate instructions
554 (define_mode_iterator RECIPF [SF DF V4SF V2DF])
555
556 ; SFmode or DFmode.
557 (define_mode_iterator SFDF [SF DF])
558
559 ; And again, for when we need two FP modes in a pattern.
560 (define_mode_iterator SFDF2 [SF DF])
561
562 ; A generic s/d attribute, for sp/dp for example.
563 (define_mode_attr sd [(SF "s") (DF "d")
564 (V4SF "s") (V2DF "d")])
565
566 ; "s" or nothing, for fmuls/fmul for example.
567 (define_mode_attr s [(SF "s") (DF "")])
568
569 ; Iterator for 128-bit floating point that uses the IBM double-double format
570 (define_mode_iterator IBM128 [(IF "FLOAT128_IBM_P (IFmode)")
571 (TF "FLOAT128_IBM_P (TFmode)")])
572
573 ; Iterator for 128-bit floating point that uses IEEE 128-bit float
574 (define_mode_iterator IEEE128 [(KF "FLOAT128_IEEE_P (KFmode)")
575 (TF "FLOAT128_IEEE_P (TFmode)")])
576
577 ; Iterator for 128-bit floating point
578 (define_mode_iterator FLOAT128 [(KF "TARGET_FLOAT128_TYPE")
579 (IF "TARGET_FLOAT128_TYPE")
580 (TF "TARGET_LONG_DOUBLE_128")])
581
582 ; Iterator for signbit on 64-bit machines with direct move
583 (define_mode_iterator SIGNBIT [(KF "FLOAT128_VECTOR_P (KFmode)")
584 (TF "FLOAT128_VECTOR_P (TFmode)")])
585
586 ; Iterator for ISA 3.0 supported floating point types
587 (define_mode_iterator FP_ISA3 [SF DF])
588
589 ; SF/DF constraint for arithmetic on traditional floating point registers
590 (define_mode_attr Ff [(SF "f") (DF "d") (DI "d")])
591
592 ; SF/DF constraint for arithmetic on VSX registers using instructions added in
593 ; ISA 2.06 (power7). This includes instructions that normally target DF mode,
594 ; but are used on SFmode, since internally SFmode values are kept in the DFmode
595 ; format.
596 (define_mode_attr Fv [(SF "wa") (DF "wa") (DI "wa")])
597
598 ; Which isa is needed for those float instructions?
599 (define_mode_attr Fisa [(SF "p8v") (DF "*") (DI "*")])
600
601 ; FRE/FRES support
602 (define_mode_attr FFRE [(SF "FRES") (DF "FRE")])
603
604 ; Conditional returns.
605 (define_code_iterator any_return [return simple_return])
606 (define_code_attr return_pred [(return "direct_return ()")
607 (simple_return "1")])
608 (define_code_attr return_str [(return "") (simple_return "simple_")])
609
610 ; Logical operators.
611 (define_code_iterator iorxor [ior xor])
612 (define_code_iterator and_ior_xor [and ior xor])
613
614 ; Signed/unsigned variants of ops.
615 (define_code_iterator any_extend [sign_extend zero_extend])
616 (define_code_iterator any_fix [fix unsigned_fix])
617 (define_code_iterator any_float [float unsigned_float])
618
619 (define_code_attr u [(sign_extend "")
620 (zero_extend "u")
621 (fix "")
622 (unsigned_fix "u")])
623
624 (define_code_attr su [(sign_extend "s")
625 (zero_extend "u")
626 (fix "s")
627 (unsigned_fix "u")
628 (float "s")
629 (unsigned_float "u")])
630
631 (define_code_attr az [(sign_extend "a")
632 (zero_extend "z")
633 (fix "a")
634 (unsigned_fix "z")
635 (float "a")
636 (unsigned_float "z")])
637
638 (define_code_attr uns [(fix "")
639 (unsigned_fix "uns")
640 (float "")
641 (unsigned_float "uns")])
642
643 ; Various instructions that come in SI and DI forms.
644 ; A generic w/d attribute, for things like cmpw/cmpd.
645 (define_mode_attr wd [(QI "b")
646 (HI "h")
647 (SI "w")
648 (DI "d")
649 (V16QI "b")
650 (V8HI "h")
651 (V4SI "w")
652 (V2DI "d")
653 (V1TI "q")
654 (TI "q")])
655
656 ; For double extract from different origin types
657 (define_mode_attr du_or_d [(QI "du")
658 (HI "du")
659 (SI "du")
660 (DI "d")
661 (V16QI "du")
662 (V8HI "du")
663 (V4SI "du")
664 (V2DI "d")])
665
666 ;; How many bits in this mode?
667 (define_mode_attr bits [(QI "8") (HI "16") (SI "32") (DI "64")
668 (SF "32") (DF "64")])
669
670 ; DImode bits
671 (define_mode_attr dbits [(QI "56") (HI "48") (SI "32")])
672
673 ;; Bitmask for shift instructions
674 (define_mode_attr hH [(SI "h") (DI "H")])
675
676 ;; A mode twice the size of the given mode
677 (define_mode_attr dmode [(SI "di") (DI "ti")])
678 (define_mode_attr DMODE [(SI "DI") (DI "TI")])
679
680 ;; Suffix for reload patterns
681 (define_mode_attr ptrsize [(SI "32bit")
682 (DI "64bit")])
683
684 (define_mode_attr tptrsize [(SI "TARGET_32BIT")
685 (DI "TARGET_64BIT")])
686
687 (define_mode_attr mptrsize [(SI "si")
688 (DI "di")])
689
690 (define_mode_attr ptrload [(SI "lwz")
691 (DI "ld")])
692
693 (define_mode_attr ptrm [(SI "m")
694 (DI "Y")])
695
696 (define_mode_attr rreg [(SF "f")
697 (DF "wa")
698 (TF "f")
699 (TD "f")
700 (V4SF "wa")
701 (V2DF "wa")])
702
703 (define_mode_attr rreg2 [(SF "f")
704 (DF "d")])
705
706 (define_mode_attr SI_CONVERT_FP [(SF "TARGET_FCFIDS")
707 (DF "TARGET_FCFID")])
708
709 ;; Mode iterator for logical operations on 128-bit types
710 (define_mode_iterator BOOL_128 [TI
711 PTI
712 (V16QI "TARGET_ALTIVEC")
713 (V8HI "TARGET_ALTIVEC")
714 (V4SI "TARGET_ALTIVEC")
715 (V4SF "TARGET_ALTIVEC")
716 (V2DI "TARGET_ALTIVEC")
717 (V2DF "TARGET_ALTIVEC")
718 (V1TI "TARGET_ALTIVEC")])
719
720 ;; For the GPRs we use 3 constraints for register outputs, two that are the
721 ;; same as the output register, and a third where the output register is an
722 ;; early clobber, so we don't have to deal with register overlaps. For the
723 ;; vector types, we prefer to use the vector registers. For TI mode, allow
724 ;; either.
725
726 ;; Mode attribute for boolean operation register constraints for output
727 (define_mode_attr BOOL_REGS_OUTPUT [(TI "&r,r,r,wa,v")
728 (PTI "&r,r,r")
729 (V16QI "wa,v,&?r,?r,?r")
730 (V8HI "wa,v,&?r,?r,?r")
731 (V4SI "wa,v,&?r,?r,?r")
732 (V4SF "wa,v,&?r,?r,?r")
733 (V2DI "wa,v,&?r,?r,?r")
734 (V2DF "wa,v,&?r,?r,?r")
735 (V1TI "wa,v,&?r,?r,?r")])
736
737 ;; Mode attribute for boolean operation register constraints for operand1
738 (define_mode_attr BOOL_REGS_OP1 [(TI "r,0,r,wa,v")
739 (PTI "r,0,r")
740 (V16QI "wa,v,r,0,r")
741 (V8HI "wa,v,r,0,r")
742 (V4SI "wa,v,r,0,r")
743 (V4SF "wa,v,r,0,r")
744 (V2DI "wa,v,r,0,r")
745 (V2DF "wa,v,r,0,r")
746 (V1TI "wa,v,r,0,r")])
747
748 ;; Mode attribute for boolean operation register constraints for operand2
749 (define_mode_attr BOOL_REGS_OP2 [(TI "r,r,0,wa,v")
750 (PTI "r,r,0")
751 (V16QI "wa,v,r,r,0")
752 (V8HI "wa,v,r,r,0")
753 (V4SI "wa,v,r,r,0")
754 (V4SF "wa,v,r,r,0")
755 (V2DI "wa,v,r,r,0")
756 (V2DF "wa,v,r,r,0")
757 (V1TI "wa,v,r,r,0")])
758
759 ;; Mode attribute for boolean operation register constraints for operand1
760 ;; for one_cmpl. To simplify things, we repeat the constraint where 0
761 ;; is used for operand1 or operand2
762 (define_mode_attr BOOL_REGS_UNARY [(TI "r,0,0,wa,v")
763 (PTI "r,0,0")
764 (V16QI "wa,v,r,0,0")
765 (V8HI "wa,v,r,0,0")
766 (V4SI "wa,v,r,0,0")
767 (V4SF "wa,v,r,0,0")
768 (V2DI "wa,v,r,0,0")
769 (V2DF "wa,v,r,0,0")
770 (V1TI "wa,v,r,0,0")])
771
772 ;; Reload iterator for creating the function to allocate a base register to
773 ;; supplement addressing modes.
774 (define_mode_iterator RELOAD [V16QI V8HI V4SI V2DI V4SF V2DF V1TI
775 SF SD SI DF DD DI TI PTI KF IF TF
776 POI PXI])
777
778 ;; Iterate over smin, smax
779 (define_code_iterator fp_minmax [smin smax])
780
781 (define_code_attr minmax [(smin "min")
782 (smax "max")])
783
784 (define_code_attr SMINMAX [(smin "SMIN")
785 (smax "SMAX")])
786
787 ;; Iterator to optimize the following cases:
788 ;; D-form load to FPR register & move to Altivec register
789 ;; Move Altivec register to FPR register and store
790 (define_mode_iterator ALTIVEC_DFORM [DF
791 (SF "TARGET_P8_VECTOR")
792 (DI "TARGET_POWERPC64")])
793
794 (include "darwin.md")
795 \f
796 ;; Start with fixed-point load and store insns. Here we put only the more
797 ;; complex forms. Basic data transfer is done later.
798
799 (define_insn "zero_extendqi<mode>2"
800 [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r,^wa,^v")
801 (zero_extend:EXTQI (match_operand:QI 1 "reg_or_mem_operand" "m,r,Z,v")))]
802 ""
803 "@
804 lbz%U1%X1 %0,%1
805 rlwinm %0,%1,0,0xff
806 lxsibzx %x0,%y1
807 vextractub %0,%1,7"
808 [(set_attr "type" "load,shift,fpload,vecperm")
809 (set_attr "isa" "*,*,p9v,p9v")])
810
811 (define_insn_and_split "*zero_extendqi<mode>2_dot"
812 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
813 (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
814 (const_int 0)))
815 (clobber (match_scratch:EXTQI 0 "=r,r"))]
816 ""
817 "@
818 andi. %0,%1,0xff
819 #"
820 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
821 [(set (match_dup 0)
822 (zero_extend:EXTQI (match_dup 1)))
823 (set (match_dup 2)
824 (compare:CC (match_dup 0)
825 (const_int 0)))]
826 ""
827 [(set_attr "type" "logical")
828 (set_attr "dot" "yes")
829 (set_attr "length" "4,8")])
830
831 (define_insn_and_split "*zero_extendqi<mode>2_dot2"
832 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
833 (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
834 (const_int 0)))
835 (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
836 (zero_extend:EXTQI (match_dup 1)))]
837 ""
838 "@
839 andi. %0,%1,0xff
840 #"
841 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
842 [(set (match_dup 0)
843 (zero_extend:EXTQI (match_dup 1)))
844 (set (match_dup 2)
845 (compare:CC (match_dup 0)
846 (const_int 0)))]
847 ""
848 [(set_attr "type" "logical")
849 (set_attr "dot" "yes")
850 (set_attr "length" "4,8")])
851
852
853 (define_insn "zero_extendhi<mode>2"
854 [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r,^wa,^v")
855 (zero_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r,Z,v")))]
856 ""
857 "@
858 lhz%U1%X1 %0,%1
859 rlwinm %0,%1,0,0xffff
860 lxsihzx %x0,%y1
861 vextractuh %0,%1,6"
862 [(set_attr "type" "load,shift,fpload,vecperm")
863 (set_attr "isa" "*,*,p9v,p9v")])
864
865 (define_insn_and_split "*zero_extendhi<mode>2_dot"
866 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
867 (compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
868 (const_int 0)))
869 (clobber (match_scratch:EXTHI 0 "=r,r"))]
870 ""
871 "@
872 andi. %0,%1,0xffff
873 #"
874 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
875 [(set (match_dup 0)
876 (zero_extend:EXTHI (match_dup 1)))
877 (set (match_dup 2)
878 (compare:CC (match_dup 0)
879 (const_int 0)))]
880 ""
881 [(set_attr "type" "logical")
882 (set_attr "dot" "yes")
883 (set_attr "length" "4,8")])
884
885 (define_insn_and_split "*zero_extendhi<mode>2_dot2"
886 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
887 (compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
888 (const_int 0)))
889 (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
890 (zero_extend:EXTHI (match_dup 1)))]
891 ""
892 "@
893 andi. %0,%1,0xffff
894 #"
895 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
896 [(set (match_dup 0)
897 (zero_extend:EXTHI (match_dup 1)))
898 (set (match_dup 2)
899 (compare:CC (match_dup 0)
900 (const_int 0)))]
901 ""
902 [(set_attr "type" "logical")
903 (set_attr "dot" "yes")
904 (set_attr "length" "4,8")])
905
906
907 (define_insn "zero_extendsi<mode>2"
908 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r,d,wa,wa,r,wa")
909 (zero_extend:EXTSI (match_operand:SI 1 "reg_or_mem_operand" "m,r,Z,Z,r,wa,wa")))]
910 ""
911 "@
912 lwz%U1%X1 %0,%1
913 rldicl %0,%1,0,32
914 lfiwzx %0,%y1
915 lxsiwzx %x0,%y1
916 mtvsrwz %x0,%1
917 mfvsrwz %0,%x1
918 xxextractuw %x0,%x1,4"
919 [(set_attr "type" "load,shift,fpload,fpload,mffgpr,mftgpr,vecexts")
920 (set_attr "isa" "*,*,p7,p8v,p8v,p8v,p9v")])
921
922 (define_insn_and_split "*zero_extendsi<mode>2_dot"
923 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
924 (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
925 (const_int 0)))
926 (clobber (match_scratch:EXTSI 0 "=r,r"))]
927 ""
928 "@
929 rldicl. %0,%1,0,32
930 #"
931 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
932 [(set (match_dup 0)
933 (zero_extend:DI (match_dup 1)))
934 (set (match_dup 2)
935 (compare:CC (match_dup 0)
936 (const_int 0)))]
937 ""
938 [(set_attr "type" "shift")
939 (set_attr "dot" "yes")
940 (set_attr "length" "4,8")])
941
942 (define_insn_and_split "*zero_extendsi<mode>2_dot2"
943 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
944 (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
945 (const_int 0)))
946 (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
947 (zero_extend:EXTSI (match_dup 1)))]
948 ""
949 "@
950 rldicl. %0,%1,0,32
951 #"
952 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
953 [(set (match_dup 0)
954 (zero_extend:EXTSI (match_dup 1)))
955 (set (match_dup 2)
956 (compare:CC (match_dup 0)
957 (const_int 0)))]
958 ""
959 [(set_attr "type" "shift")
960 (set_attr "dot" "yes")
961 (set_attr "length" "4,8")])
962
963
964 (define_insn "extendqi<mode>2"
965 [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,?*v")
966 (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,?*v")))]
967 ""
968 "@
969 extsb %0,%1
970 vextsb2d %0,%1"
971 [(set_attr "type" "exts,vecperm")
972 (set_attr "isa" "*,p9v")])
973
974 (define_insn_and_split "*extendqi<mode>2_dot"
975 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
976 (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
977 (const_int 0)))
978 (clobber (match_scratch:EXTQI 0 "=r,r"))]
979 ""
980 "@
981 extsb. %0,%1
982 #"
983 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
984 [(set (match_dup 0)
985 (sign_extend:EXTQI (match_dup 1)))
986 (set (match_dup 2)
987 (compare:CC (match_dup 0)
988 (const_int 0)))]
989 ""
990 [(set_attr "type" "exts")
991 (set_attr "dot" "yes")
992 (set_attr "length" "4,8")])
993
994 (define_insn_and_split "*extendqi<mode>2_dot2"
995 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
996 (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
997 (const_int 0)))
998 (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
999 (sign_extend:EXTQI (match_dup 1)))]
1000 ""
1001 "@
1002 extsb. %0,%1
1003 #"
1004 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1005 [(set (match_dup 0)
1006 (sign_extend:EXTQI (match_dup 1)))
1007 (set (match_dup 2)
1008 (compare:CC (match_dup 0)
1009 (const_int 0)))]
1010 ""
1011 [(set_attr "type" "exts")
1012 (set_attr "dot" "yes")
1013 (set_attr "length" "4,8")])
1014
1015
1016 (define_expand "extendhi<mode>2"
1017 [(set (match_operand:EXTHI 0 "gpc_reg_operand")
1018 (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand")))]
1019 ""
1020 "")
1021
1022 (define_insn "*extendhi<mode>2"
1023 [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r,?*v,?*v")
1024 (sign_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r,Z,v")))]
1025 ""
1026 "@
1027 lha%U1%X1 %0,%1
1028 extsh %0,%1
1029 #
1030 vextsh2d %0,%1"
1031 [(set_attr "type" "load,exts,fpload,vecperm")
1032 (set_attr "sign_extend" "yes")
1033 (set_attr "length" "*,*,8,*")
1034 (set_attr "isa" "*,*,p9v,p9v")])
1035
1036 (define_split
1037 [(set (match_operand:EXTHI 0 "altivec_register_operand")
1038 (sign_extend:EXTHI
1039 (match_operand:HI 1 "indexed_or_indirect_operand")))]
1040 "TARGET_P9_VECTOR && reload_completed"
1041 [(set (match_dup 2)
1042 (match_dup 1))
1043 (set (match_dup 0)
1044 (sign_extend:EXTHI (match_dup 2)))]
1045 {
1046 operands[2] = gen_rtx_REG (HImode, REGNO (operands[0]));
1047 })
1048
1049 (define_insn_and_split "*extendhi<mode>2_dot"
1050 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1051 (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
1052 (const_int 0)))
1053 (clobber (match_scratch:EXTHI 0 "=r,r"))]
1054 ""
1055 "@
1056 extsh. %0,%1
1057 #"
1058 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1059 [(set (match_dup 0)
1060 (sign_extend:EXTHI (match_dup 1)))
1061 (set (match_dup 2)
1062 (compare:CC (match_dup 0)
1063 (const_int 0)))]
1064 ""
1065 [(set_attr "type" "exts")
1066 (set_attr "dot" "yes")
1067 (set_attr "length" "4,8")])
1068
1069 (define_insn_and_split "*extendhi<mode>2_dot2"
1070 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1071 (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
1072 (const_int 0)))
1073 (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
1074 (sign_extend:EXTHI (match_dup 1)))]
1075 ""
1076 "@
1077 extsh. %0,%1
1078 #"
1079 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1080 [(set (match_dup 0)
1081 (sign_extend:EXTHI (match_dup 1)))
1082 (set (match_dup 2)
1083 (compare:CC (match_dup 0)
1084 (const_int 0)))]
1085 ""
1086 [(set_attr "type" "exts")
1087 (set_attr "dot" "yes")
1088 (set_attr "length" "4,8")])
1089
1090
1091 (define_insn "extendsi<mode>2"
1092 [(set (match_operand:EXTSI 0 "gpc_reg_operand"
1093 "=r, r, d, wa, wa, v, v, wr")
1094 (sign_extend:EXTSI (match_operand:SI 1 "lwa_operand"
1095 "YZ, r, Z, Z, r, v, v, ?wa")))]
1096 ""
1097 "@
1098 lwa%U1%X1 %0,%1
1099 extsw %0,%1
1100 lfiwax %0,%y1
1101 lxsiwax %x0,%y1
1102 mtvsrwa %x0,%1
1103 vextsw2d %0,%1
1104 #
1105 #"
1106 [(set_attr "type" "load,exts,fpload,fpload,mffgpr,vecexts,vecperm,mftgpr")
1107 (set_attr "sign_extend" "yes")
1108 (set_attr "length" "*,*,*,*,*,*,8,8")
1109 (set_attr "isa" "*,*,p6,p8v,p8v,p9v,p8v,p8v")])
1110
1111 (define_split
1112 [(set (match_operand:EXTSI 0 "int_reg_operand")
1113 (sign_extend:EXTSI (match_operand:SI 1 "vsx_register_operand")))]
1114 "TARGET_DIRECT_MOVE_64BIT && reload_completed"
1115 [(set (match_dup 2)
1116 (match_dup 1))
1117 (set (match_dup 0)
1118 (sign_extend:DI (match_dup 2)))]
1119 {
1120 operands[2] = gen_rtx_REG (SImode, reg_or_subregno (operands[0]));
1121 })
1122
1123 (define_split
1124 [(set (match_operand:DI 0 "altivec_register_operand")
1125 (sign_extend:DI (match_operand:SI 1 "altivec_register_operand")))]
1126 "TARGET_P8_VECTOR && !TARGET_P9_VECTOR && reload_completed"
1127 [(const_int 0)]
1128 {
1129 rtx dest = operands[0];
1130 rtx src = operands[1];
1131 int dest_regno = REGNO (dest);
1132 int src_regno = REGNO (src);
1133 rtx dest_v2di = gen_rtx_REG (V2DImode, dest_regno);
1134 rtx src_v4si = gen_rtx_REG (V4SImode, src_regno);
1135
1136 if (BYTES_BIG_ENDIAN)
1137 {
1138 emit_insn (gen_altivec_vupkhsw (dest_v2di, src_v4si));
1139 emit_insn (gen_vsx_xxspltd_v2di (dest_v2di, dest_v2di, const1_rtx));
1140 }
1141 else
1142 {
1143 emit_insn (gen_altivec_vupklsw (dest_v2di, src_v4si));
1144 emit_insn (gen_vsx_xxspltd_v2di (dest_v2di, dest_v2di, const0_rtx));
1145 }
1146 DONE;
1147 })
1148
1149 (define_insn_and_split "*extendsi<mode>2_dot"
1150 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1151 (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
1152 (const_int 0)))
1153 (clobber (match_scratch:EXTSI 0 "=r,r"))]
1154 ""
1155 "@
1156 extsw. %0,%1
1157 #"
1158 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1159 [(set (match_dup 0)
1160 (sign_extend:EXTSI (match_dup 1)))
1161 (set (match_dup 2)
1162 (compare:CC (match_dup 0)
1163 (const_int 0)))]
1164 ""
1165 [(set_attr "type" "exts")
1166 (set_attr "dot" "yes")
1167 (set_attr "length" "4,8")])
1168
1169 (define_insn_and_split "*extendsi<mode>2_dot2"
1170 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1171 (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
1172 (const_int 0)))
1173 (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
1174 (sign_extend:EXTSI (match_dup 1)))]
1175 ""
1176 "@
1177 extsw. %0,%1
1178 #"
1179 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1180 [(set (match_dup 0)
1181 (sign_extend:EXTSI (match_dup 1)))
1182 (set (match_dup 2)
1183 (compare:CC (match_dup 0)
1184 (const_int 0)))]
1185 ""
1186 [(set_attr "type" "exts")
1187 (set_attr "dot" "yes")
1188 (set_attr "length" "4,8")])
1189 \f
1190 ;; IBM 405, 440, 464 and 476 half-word multiplication operations.
1191
1192 (define_insn "*macchwc"
1193 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1194 (compare:CC (plus:SI (mult:SI (ashiftrt:SI
1195 (match_operand:SI 2 "gpc_reg_operand" "r")
1196 (const_int 16))
1197 (sign_extend:SI
1198 (match_operand:HI 1 "gpc_reg_operand" "r")))
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 2)
1204 (const_int 16))
1205 (sign_extend:SI
1206 (match_dup 1)))
1207 (match_dup 4)))]
1208 "TARGET_MULHW"
1209 "macchw. %0,%1,%2"
1210 [(set_attr "type" "halfmul")])
1211
1212 (define_insn "*macchw"
1213 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1214 (plus:SI (mult:SI (ashiftrt:SI
1215 (match_operand:SI 2 "gpc_reg_operand" "r")
1216 (const_int 16))
1217 (sign_extend:SI
1218 (match_operand:HI 1 "gpc_reg_operand" "r")))
1219 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1220 "TARGET_MULHW"
1221 "macchw %0,%1,%2"
1222 [(set_attr "type" "halfmul")])
1223
1224 (define_insn "*macchwuc"
1225 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1226 (compare:CC (plus:SI (mult:SI (lshiftrt:SI
1227 (match_operand:SI 2 "gpc_reg_operand" "r")
1228 (const_int 16))
1229 (zero_extend:SI
1230 (match_operand:HI 1 "gpc_reg_operand" "r")))
1231 (match_operand:SI 4 "gpc_reg_operand" "0"))
1232 (const_int 0)))
1233 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1234 (plus:SI (mult:SI (lshiftrt:SI
1235 (match_dup 2)
1236 (const_int 16))
1237 (zero_extend:SI
1238 (match_dup 1)))
1239 (match_dup 4)))]
1240 "TARGET_MULHW"
1241 "macchwu. %0,%1,%2"
1242 [(set_attr "type" "halfmul")])
1243
1244 (define_insn "*macchwu"
1245 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1246 (plus:SI (mult:SI (lshiftrt:SI
1247 (match_operand:SI 2 "gpc_reg_operand" "r")
1248 (const_int 16))
1249 (zero_extend:SI
1250 (match_operand:HI 1 "gpc_reg_operand" "r")))
1251 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1252 "TARGET_MULHW"
1253 "macchwu %0,%1,%2"
1254 [(set_attr "type" "halfmul")])
1255
1256 (define_insn "*machhwc"
1257 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1258 (compare:CC (plus:SI (mult:SI (ashiftrt:SI
1259 (match_operand:SI 1 "gpc_reg_operand" "%r")
1260 (const_int 16))
1261 (ashiftrt:SI
1262 (match_operand:SI 2 "gpc_reg_operand" "r")
1263 (const_int 16)))
1264 (match_operand:SI 4 "gpc_reg_operand" "0"))
1265 (const_int 0)))
1266 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1267 (plus:SI (mult:SI (ashiftrt:SI
1268 (match_dup 1)
1269 (const_int 16))
1270 (ashiftrt:SI
1271 (match_dup 2)
1272 (const_int 16)))
1273 (match_dup 4)))]
1274 "TARGET_MULHW"
1275 "machhw. %0,%1,%2"
1276 [(set_attr "type" "halfmul")])
1277
1278 (define_insn "*machhw"
1279 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1280 (plus:SI (mult:SI (ashiftrt:SI
1281 (match_operand:SI 1 "gpc_reg_operand" "%r")
1282 (const_int 16))
1283 (ashiftrt:SI
1284 (match_operand:SI 2 "gpc_reg_operand" "r")
1285 (const_int 16)))
1286 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1287 "TARGET_MULHW"
1288 "machhw %0,%1,%2"
1289 [(set_attr "type" "halfmul")])
1290
1291 (define_insn "*machhwuc"
1292 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1293 (compare:CC (plus:SI (mult:SI (lshiftrt:SI
1294 (match_operand:SI 1 "gpc_reg_operand" "%r")
1295 (const_int 16))
1296 (lshiftrt:SI
1297 (match_operand:SI 2 "gpc_reg_operand" "r")
1298 (const_int 16)))
1299 (match_operand:SI 4 "gpc_reg_operand" "0"))
1300 (const_int 0)))
1301 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1302 (plus:SI (mult:SI (lshiftrt:SI
1303 (match_dup 1)
1304 (const_int 16))
1305 (lshiftrt:SI
1306 (match_dup 2)
1307 (const_int 16)))
1308 (match_dup 4)))]
1309 "TARGET_MULHW"
1310 "machhwu. %0,%1,%2"
1311 [(set_attr "type" "halfmul")])
1312
1313 (define_insn "*machhwu"
1314 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1315 (plus:SI (mult:SI (lshiftrt:SI
1316 (match_operand:SI 1 "gpc_reg_operand" "%r")
1317 (const_int 16))
1318 (lshiftrt:SI
1319 (match_operand:SI 2 "gpc_reg_operand" "r")
1320 (const_int 16)))
1321 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1322 "TARGET_MULHW"
1323 "machhwu %0,%1,%2"
1324 [(set_attr "type" "halfmul")])
1325
1326 (define_insn "*maclhwc"
1327 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1328 (compare:CC (plus:SI (mult:SI (sign_extend:SI
1329 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1330 (sign_extend:SI
1331 (match_operand:HI 2 "gpc_reg_operand" "r")))
1332 (match_operand:SI 4 "gpc_reg_operand" "0"))
1333 (const_int 0)))
1334 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1335 (plus:SI (mult:SI (sign_extend:SI
1336 (match_dup 1))
1337 (sign_extend:SI
1338 (match_dup 2)))
1339 (match_dup 4)))]
1340 "TARGET_MULHW"
1341 "maclhw. %0,%1,%2"
1342 [(set_attr "type" "halfmul")])
1343
1344 (define_insn "*maclhw"
1345 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1346 (plus:SI (mult:SI (sign_extend:SI
1347 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1348 (sign_extend:SI
1349 (match_operand:HI 2 "gpc_reg_operand" "r")))
1350 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1351 "TARGET_MULHW"
1352 "maclhw %0,%1,%2"
1353 [(set_attr "type" "halfmul")])
1354
1355 (define_insn "*maclhwuc"
1356 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1357 (compare:CC (plus:SI (mult:SI (zero_extend:SI
1358 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1359 (zero_extend:SI
1360 (match_operand:HI 2 "gpc_reg_operand" "r")))
1361 (match_operand:SI 4 "gpc_reg_operand" "0"))
1362 (const_int 0)))
1363 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1364 (plus:SI (mult:SI (zero_extend:SI
1365 (match_dup 1))
1366 (zero_extend:SI
1367 (match_dup 2)))
1368 (match_dup 4)))]
1369 "TARGET_MULHW"
1370 "maclhwu. %0,%1,%2"
1371 [(set_attr "type" "halfmul")])
1372
1373 (define_insn "*maclhwu"
1374 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1375 (plus:SI (mult:SI (zero_extend:SI
1376 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1377 (zero_extend:SI
1378 (match_operand:HI 2 "gpc_reg_operand" "r")))
1379 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1380 "TARGET_MULHW"
1381 "maclhwu %0,%1,%2"
1382 [(set_attr "type" "halfmul")])
1383
1384 (define_insn "*nmacchwc"
1385 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1386 (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1387 (mult:SI (ashiftrt:SI
1388 (match_operand:SI 2 "gpc_reg_operand" "r")
1389 (const_int 16))
1390 (sign_extend:SI
1391 (match_operand:HI 1 "gpc_reg_operand" "r"))))
1392 (const_int 0)))
1393 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1394 (minus:SI (match_dup 4)
1395 (mult:SI (ashiftrt:SI
1396 (match_dup 2)
1397 (const_int 16))
1398 (sign_extend:SI
1399 (match_dup 1)))))]
1400 "TARGET_MULHW"
1401 "nmacchw. %0,%1,%2"
1402 [(set_attr "type" "halfmul")])
1403
1404 (define_insn "*nmacchw"
1405 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1406 (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1407 (mult:SI (ashiftrt:SI
1408 (match_operand:SI 2 "gpc_reg_operand" "r")
1409 (const_int 16))
1410 (sign_extend:SI
1411 (match_operand:HI 1 "gpc_reg_operand" "r")))))]
1412 "TARGET_MULHW"
1413 "nmacchw %0,%1,%2"
1414 [(set_attr "type" "halfmul")])
1415
1416 (define_insn "*nmachhwc"
1417 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1418 (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1419 (mult:SI (ashiftrt:SI
1420 (match_operand:SI 1 "gpc_reg_operand" "%r")
1421 (const_int 16))
1422 (ashiftrt:SI
1423 (match_operand:SI 2 "gpc_reg_operand" "r")
1424 (const_int 16))))
1425 (const_int 0)))
1426 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1427 (minus:SI (match_dup 4)
1428 (mult:SI (ashiftrt:SI
1429 (match_dup 1)
1430 (const_int 16))
1431 (ashiftrt:SI
1432 (match_dup 2)
1433 (const_int 16)))))]
1434 "TARGET_MULHW"
1435 "nmachhw. %0,%1,%2"
1436 [(set_attr "type" "halfmul")])
1437
1438 (define_insn "*nmachhw"
1439 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1440 (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1441 (mult:SI (ashiftrt:SI
1442 (match_operand:SI 1 "gpc_reg_operand" "%r")
1443 (const_int 16))
1444 (ashiftrt:SI
1445 (match_operand:SI 2 "gpc_reg_operand" "r")
1446 (const_int 16)))))]
1447 "TARGET_MULHW"
1448 "nmachhw %0,%1,%2"
1449 [(set_attr "type" "halfmul")])
1450
1451 (define_insn "*nmaclhwc"
1452 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1453 (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1454 (mult:SI (sign_extend:SI
1455 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1456 (sign_extend:SI
1457 (match_operand:HI 2 "gpc_reg_operand" "r"))))
1458 (const_int 0)))
1459 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1460 (minus:SI (match_dup 4)
1461 (mult:SI (sign_extend:SI
1462 (match_dup 1))
1463 (sign_extend:SI
1464 (match_dup 2)))))]
1465 "TARGET_MULHW"
1466 "nmaclhw. %0,%1,%2"
1467 [(set_attr "type" "halfmul")])
1468
1469 (define_insn "*nmaclhw"
1470 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1471 (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1472 (mult:SI (sign_extend:SI
1473 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1474 (sign_extend:SI
1475 (match_operand:HI 2 "gpc_reg_operand" "r")))))]
1476 "TARGET_MULHW"
1477 "nmaclhw %0,%1,%2"
1478 [(set_attr "type" "halfmul")])
1479
1480 (define_insn "*mulchwc"
1481 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1482 (compare:CC (mult:SI (ashiftrt:SI
1483 (match_operand:SI 2 "gpc_reg_operand" "r")
1484 (const_int 16))
1485 (sign_extend:SI
1486 (match_operand:HI 1 "gpc_reg_operand" "r")))
1487 (const_int 0)))
1488 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1489 (mult:SI (ashiftrt:SI
1490 (match_dup 2)
1491 (const_int 16))
1492 (sign_extend:SI
1493 (match_dup 1))))]
1494 "TARGET_MULHW"
1495 "mulchw. %0,%1,%2"
1496 [(set_attr "type" "halfmul")])
1497
1498 (define_insn "*mulchw"
1499 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1500 (mult:SI (ashiftrt:SI
1501 (match_operand:SI 2 "gpc_reg_operand" "r")
1502 (const_int 16))
1503 (sign_extend:SI
1504 (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1505 "TARGET_MULHW"
1506 "mulchw %0,%1,%2"
1507 [(set_attr "type" "halfmul")])
1508
1509 (define_insn "*mulchwuc"
1510 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1511 (compare:CC (mult:SI (lshiftrt:SI
1512 (match_operand:SI 2 "gpc_reg_operand" "r")
1513 (const_int 16))
1514 (zero_extend:SI
1515 (match_operand:HI 1 "gpc_reg_operand" "r")))
1516 (const_int 0)))
1517 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1518 (mult:SI (lshiftrt:SI
1519 (match_dup 2)
1520 (const_int 16))
1521 (zero_extend:SI
1522 (match_dup 1))))]
1523 "TARGET_MULHW"
1524 "mulchwu. %0,%1,%2"
1525 [(set_attr "type" "halfmul")])
1526
1527 (define_insn "*mulchwu"
1528 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1529 (mult:SI (lshiftrt:SI
1530 (match_operand:SI 2 "gpc_reg_operand" "r")
1531 (const_int 16))
1532 (zero_extend:SI
1533 (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1534 "TARGET_MULHW"
1535 "mulchwu %0,%1,%2"
1536 [(set_attr "type" "halfmul")])
1537
1538 (define_insn "*mulhhwc"
1539 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1540 (compare:CC (mult:SI (ashiftrt:SI
1541 (match_operand:SI 1 "gpc_reg_operand" "%r")
1542 (const_int 16))
1543 (ashiftrt:SI
1544 (match_operand:SI 2 "gpc_reg_operand" "r")
1545 (const_int 16)))
1546 (const_int 0)))
1547 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1548 (mult:SI (ashiftrt:SI
1549 (match_dup 1)
1550 (const_int 16))
1551 (ashiftrt:SI
1552 (match_dup 2)
1553 (const_int 16))))]
1554 "TARGET_MULHW"
1555 "mulhhw. %0,%1,%2"
1556 [(set_attr "type" "halfmul")])
1557
1558 (define_insn "*mulhhw"
1559 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1560 (mult:SI (ashiftrt:SI
1561 (match_operand:SI 1 "gpc_reg_operand" "%r")
1562 (const_int 16))
1563 (ashiftrt:SI
1564 (match_operand:SI 2 "gpc_reg_operand" "r")
1565 (const_int 16))))]
1566 "TARGET_MULHW"
1567 "mulhhw %0,%1,%2"
1568 [(set_attr "type" "halfmul")])
1569
1570 (define_insn "*mulhhwuc"
1571 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1572 (compare:CC (mult:SI (lshiftrt:SI
1573 (match_operand:SI 1 "gpc_reg_operand" "%r")
1574 (const_int 16))
1575 (lshiftrt:SI
1576 (match_operand:SI 2 "gpc_reg_operand" "r")
1577 (const_int 16)))
1578 (const_int 0)))
1579 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1580 (mult:SI (lshiftrt:SI
1581 (match_dup 1)
1582 (const_int 16))
1583 (lshiftrt:SI
1584 (match_dup 2)
1585 (const_int 16))))]
1586 "TARGET_MULHW"
1587 "mulhhwu. %0,%1,%2"
1588 [(set_attr "type" "halfmul")])
1589
1590 (define_insn "*mulhhwu"
1591 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1592 (mult:SI (lshiftrt:SI
1593 (match_operand:SI 1 "gpc_reg_operand" "%r")
1594 (const_int 16))
1595 (lshiftrt:SI
1596 (match_operand:SI 2 "gpc_reg_operand" "r")
1597 (const_int 16))))]
1598 "TARGET_MULHW"
1599 "mulhhwu %0,%1,%2"
1600 [(set_attr "type" "halfmul")])
1601
1602 (define_insn "*mullhwc"
1603 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1604 (compare:CC (mult:SI (sign_extend:SI
1605 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1606 (sign_extend:SI
1607 (match_operand:HI 2 "gpc_reg_operand" "r")))
1608 (const_int 0)))
1609 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1610 (mult:SI (sign_extend:SI
1611 (match_dup 1))
1612 (sign_extend:SI
1613 (match_dup 2))))]
1614 "TARGET_MULHW"
1615 "mullhw. %0,%1,%2"
1616 [(set_attr "type" "halfmul")])
1617
1618 (define_insn "*mullhw"
1619 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1620 (mult:SI (sign_extend:SI
1621 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1622 (sign_extend:SI
1623 (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1624 "TARGET_MULHW"
1625 "mullhw %0,%1,%2"
1626 [(set_attr "type" "halfmul")])
1627
1628 (define_insn "*mullhwuc"
1629 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1630 (compare:CC (mult:SI (zero_extend:SI
1631 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1632 (zero_extend:SI
1633 (match_operand:HI 2 "gpc_reg_operand" "r")))
1634 (const_int 0)))
1635 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1636 (mult:SI (zero_extend:SI
1637 (match_dup 1))
1638 (zero_extend:SI
1639 (match_dup 2))))]
1640 "TARGET_MULHW"
1641 "mullhwu. %0,%1,%2"
1642 [(set_attr "type" "halfmul")])
1643
1644 (define_insn "*mullhwu"
1645 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1646 (mult:SI (zero_extend:SI
1647 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1648 (zero_extend:SI
1649 (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1650 "TARGET_MULHW"
1651 "mullhwu %0,%1,%2"
1652 [(set_attr "type" "halfmul")])
1653 \f
1654 ;; IBM 405, 440, 464 and 476 string-search dlmzb instruction support.
1655 (define_insn "dlmzb"
1656 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1657 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
1658 (match_operand:SI 2 "gpc_reg_operand" "r")]
1659 UNSPEC_DLMZB_CR))
1660 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1661 (unspec:SI [(match_dup 1)
1662 (match_dup 2)]
1663 UNSPEC_DLMZB))]
1664 "TARGET_DLMZB"
1665 "dlmzb. %0,%1,%2")
1666
1667 (define_expand "strlensi"
1668 [(set (match_operand:SI 0 "gpc_reg_operand")
1669 (unspec:SI [(match_operand:BLK 1 "general_operand")
1670 (match_operand:QI 2 "const_int_operand")
1671 (match_operand 3 "const_int_operand")]
1672 UNSPEC_DLMZB_STRLEN))
1673 (clobber (match_scratch:CC 4))]
1674 "TARGET_DLMZB && WORDS_BIG_ENDIAN && !optimize_size"
1675 {
1676 rtx result = operands[0];
1677 rtx src = operands[1];
1678 rtx search_char = operands[2];
1679 rtx align = operands[3];
1680 rtx addr, scratch_string, word1, word2, scratch_dlmzb;
1681 rtx loop_label, end_label, mem, cr0, cond;
1682 if (search_char != const0_rtx
1683 || !CONST_INT_P (align)
1684 || INTVAL (align) < 8)
1685 FAIL;
1686 word1 = gen_reg_rtx (SImode);
1687 word2 = gen_reg_rtx (SImode);
1688 scratch_dlmzb = gen_reg_rtx (SImode);
1689 scratch_string = gen_reg_rtx (Pmode);
1690 loop_label = gen_label_rtx ();
1691 end_label = gen_label_rtx ();
1692 addr = force_reg (Pmode, XEXP (src, 0));
1693 emit_move_insn (scratch_string, addr);
1694 emit_label (loop_label);
1695 mem = change_address (src, SImode, scratch_string);
1696 emit_move_insn (word1, mem);
1697 emit_move_insn (word2, adjust_address (mem, SImode, 4));
1698 cr0 = gen_rtx_REG (CCmode, CR0_REGNO);
1699 emit_insn (gen_dlmzb (scratch_dlmzb, word1, word2, cr0));
1700 cond = gen_rtx_NE (VOIDmode, cr0, const0_rtx);
1701 emit_jump_insn (gen_rtx_SET (pc_rtx,
1702 gen_rtx_IF_THEN_ELSE (VOIDmode,
1703 cond,
1704 gen_rtx_LABEL_REF
1705 (VOIDmode,
1706 end_label),
1707 pc_rtx)));
1708 emit_insn (gen_addsi3 (scratch_string, scratch_string, GEN_INT (8)));
1709 emit_jump_insn (gen_rtx_SET (pc_rtx,
1710 gen_rtx_LABEL_REF (VOIDmode, loop_label)));
1711 emit_barrier ();
1712 emit_label (end_label);
1713 emit_insn (gen_addsi3 (scratch_string, scratch_string, scratch_dlmzb));
1714 emit_insn (gen_subsi3 (result, scratch_string, addr));
1715 emit_insn (gen_addsi3 (result, result, constm1_rtx));
1716 DONE;
1717 })
1718 \f
1719 ;; Fixed-point arithmetic insns.
1720
1721 (define_expand "add<mode>3"
1722 [(set (match_operand:SDI 0 "gpc_reg_operand")
1723 (plus:SDI (match_operand:SDI 1 "gpc_reg_operand")
1724 (match_operand:SDI 2 "reg_or_add_cint_operand")))]
1725 ""
1726 {
1727 if (<MODE>mode == DImode && !TARGET_POWERPC64)
1728 {
1729 rtx lo0 = gen_lowpart (SImode, operands[0]);
1730 rtx lo1 = gen_lowpart (SImode, operands[1]);
1731 rtx lo2 = gen_lowpart (SImode, operands[2]);
1732 rtx hi0 = gen_highpart (SImode, operands[0]);
1733 rtx hi1 = gen_highpart (SImode, operands[1]);
1734 rtx hi2 = gen_highpart_mode (SImode, DImode, operands[2]);
1735
1736 if (!reg_or_short_operand (lo2, SImode))
1737 lo2 = force_reg (SImode, lo2);
1738 if (!adde_operand (hi2, SImode))
1739 hi2 = force_reg (SImode, hi2);
1740
1741 emit_insn (gen_addsi3_carry (lo0, lo1, lo2));
1742 emit_insn (gen_addsi3_carry_in (hi0, hi1, hi2));
1743 DONE;
1744 }
1745
1746 if (CONST_INT_P (operands[2]) && !add_operand (operands[2], <MODE>mode))
1747 {
1748 rtx tmp = ((!can_create_pseudo_p ()
1749 || rtx_equal_p (operands[0], operands[1]))
1750 ? operands[0] : gen_reg_rtx (<MODE>mode));
1751
1752 /* Adding a constant to r0 is not a valid insn, so use a different
1753 strategy in that case. */
1754 if (reg_or_subregno (operands[1]) == 0 || reg_or_subregno (tmp) == 0)
1755 {
1756 if (operands[0] == operands[1])
1757 FAIL;
1758 rs6000_emit_move (operands[0], operands[2], <MODE>mode);
1759 emit_insn (gen_add<mode>3 (operands[0], operands[1], operands[0]));
1760 DONE;
1761 }
1762
1763 HOST_WIDE_INT val = INTVAL (operands[2]);
1764 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1765 HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1766
1767 if (<MODE>mode == DImode && !satisfies_constraint_L (GEN_INT (rest)))
1768 FAIL;
1769
1770 /* The ordering here is important for the prolog expander.
1771 When space is allocated from the stack, adding 'low' first may
1772 produce a temporary deallocation (which would be bad). */
1773 emit_insn (gen_add<mode>3 (tmp, operands[1], GEN_INT (rest)));
1774 emit_insn (gen_add<mode>3 (operands[0], tmp, GEN_INT (low)));
1775 DONE;
1776 }
1777 })
1778
1779 (define_insn "*add<mode>3"
1780 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r,r,r")
1781 (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b,b,b")
1782 (match_operand:GPR 2 "add_operand" "r,I,L,eI")))]
1783 ""
1784 "@
1785 add %0,%1,%2
1786 addi %0,%1,%2
1787 addis %0,%1,%v2
1788 addi %0,%1,%2"
1789 [(set_attr "type" "add")
1790 (set_attr "isa" "*,*,*,p10")])
1791
1792 (define_insn "*addsi3_high"
1793 [(set (match_operand:SI 0 "gpc_reg_operand" "=b")
1794 (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
1795 (high:SI (match_operand 2 "" ""))))]
1796 "TARGET_MACHO && !TARGET_64BIT"
1797 "addis %0,%1,ha16(%2)"
1798 [(set_attr "type" "add")])
1799
1800 (define_insn_and_split "*add<mode>3_dot"
1801 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1802 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
1803 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
1804 (const_int 0)))
1805 (clobber (match_scratch:GPR 0 "=r,r"))]
1806 "<MODE>mode == Pmode"
1807 "@
1808 add. %0,%1,%2
1809 #"
1810 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1811 [(set (match_dup 0)
1812 (plus:GPR (match_dup 1)
1813 (match_dup 2)))
1814 (set (match_dup 3)
1815 (compare:CC (match_dup 0)
1816 (const_int 0)))]
1817 ""
1818 [(set_attr "type" "add")
1819 (set_attr "dot" "yes")
1820 (set_attr "length" "4,8")])
1821
1822 (define_insn_and_split "*add<mode>3_dot2"
1823 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1824 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
1825 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
1826 (const_int 0)))
1827 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1828 (plus:GPR (match_dup 1)
1829 (match_dup 2)))]
1830 "<MODE>mode == Pmode"
1831 "@
1832 add. %0,%1,%2
1833 #"
1834 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1835 [(set (match_dup 0)
1836 (plus:GPR (match_dup 1)
1837 (match_dup 2)))
1838 (set (match_dup 3)
1839 (compare:CC (match_dup 0)
1840 (const_int 0)))]
1841 ""
1842 [(set_attr "type" "add")
1843 (set_attr "dot" "yes")
1844 (set_attr "length" "4,8")])
1845
1846 (define_insn_and_split "*add<mode>3_imm_dot"
1847 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1848 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b")
1849 (match_operand:GPR 2 "short_cint_operand" "I,I"))
1850 (const_int 0)))
1851 (clobber (match_scratch:GPR 0 "=r,r"))
1852 (clobber (reg:GPR CA_REGNO))]
1853 "<MODE>mode == Pmode"
1854 "@
1855 addic. %0,%1,%2
1856 #"
1857 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1858 [(set (match_dup 0)
1859 (plus:GPR (match_dup 1)
1860 (match_dup 2)))
1861 (set (match_dup 3)
1862 (compare:CC (match_dup 0)
1863 (const_int 0)))]
1864 ""
1865 [(set_attr "type" "add")
1866 (set_attr "dot" "yes")
1867 (set_attr "length" "4,8")])
1868
1869 (define_insn_and_split "*add<mode>3_imm_dot2"
1870 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1871 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b")
1872 (match_operand:GPR 2 "short_cint_operand" "I,I"))
1873 (const_int 0)))
1874 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1875 (plus:GPR (match_dup 1)
1876 (match_dup 2)))
1877 (clobber (reg:GPR CA_REGNO))]
1878 "<MODE>mode == Pmode"
1879 "@
1880 addic. %0,%1,%2
1881 #"
1882 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1883 [(set (match_dup 0)
1884 (plus:GPR (match_dup 1)
1885 (match_dup 2)))
1886 (set (match_dup 3)
1887 (compare:CC (match_dup 0)
1888 (const_int 0)))]
1889 ""
1890 [(set_attr "type" "add")
1891 (set_attr "dot" "yes")
1892 (set_attr "length" "4,8")])
1893
1894 ;; Split an add that we can't do in one insn into two insns, each of which
1895 ;; does one 16-bit part. This is used by combine. Note that the low-order
1896 ;; add should be last in case the result gets used in an address.
1897
1898 (define_split
1899 [(set (match_operand:GPR 0 "gpc_reg_operand")
1900 (plus:GPR (match_operand:GPR 1 "gpc_reg_operand")
1901 (match_operand:GPR 2 "non_add_cint_operand")))]
1902 ""
1903 [(set (match_dup 0) (plus:GPR (match_dup 1) (match_dup 3)))
1904 (set (match_dup 0) (plus:GPR (match_dup 0) (match_dup 4)))]
1905 {
1906 HOST_WIDE_INT val = INTVAL (operands[2]);
1907 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1908 HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1909
1910 operands[4] = GEN_INT (low);
1911 if (<MODE>mode == SImode || satisfies_constraint_L (GEN_INT (rest)))
1912 operands[3] = GEN_INT (rest);
1913 else if (can_create_pseudo_p ())
1914 {
1915 operands[3] = gen_reg_rtx (DImode);
1916 emit_move_insn (operands[3], operands[2]);
1917 emit_insn (gen_adddi3 (operands[0], operands[1], operands[3]));
1918 DONE;
1919 }
1920 else
1921 FAIL;
1922 })
1923
1924
1925 (define_insn "add<mode>3_carry"
1926 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1927 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1928 (match_operand:P 2 "reg_or_short_operand" "rI")))
1929 (set (reg:P CA_REGNO)
1930 (ltu:P (plus:P (match_dup 1)
1931 (match_dup 2))
1932 (match_dup 1)))]
1933 ""
1934 "add%I2c %0,%1,%2"
1935 [(set_attr "type" "add")])
1936
1937 (define_insn "*add<mode>3_imm_carry_pos"
1938 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1939 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1940 (match_operand:P 2 "short_cint_operand" "n")))
1941 (set (reg:P CA_REGNO)
1942 (geu:P (match_dup 1)
1943 (match_operand:P 3 "const_int_operand" "n")))]
1944 "INTVAL (operands[2]) > 0
1945 && INTVAL (operands[2]) + INTVAL (operands[3]) == 0"
1946 "addic %0,%1,%2"
1947 [(set_attr "type" "add")])
1948
1949 (define_insn "*add<mode>3_imm_carry_0"
1950 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1951 (match_operand:P 1 "gpc_reg_operand" "r"))
1952 (set (reg:P CA_REGNO)
1953 (const_int 0))]
1954 ""
1955 "addic %0,%1,0"
1956 [(set_attr "type" "add")])
1957
1958 (define_insn "*add<mode>3_imm_carry_m1"
1959 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1960 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1961 (const_int -1)))
1962 (set (reg:P CA_REGNO)
1963 (ne:P (match_dup 1)
1964 (const_int 0)))]
1965 ""
1966 "addic %0,%1,-1"
1967 [(set_attr "type" "add")])
1968
1969 (define_insn "*add<mode>3_imm_carry_neg"
1970 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1971 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1972 (match_operand:P 2 "short_cint_operand" "n")))
1973 (set (reg:P CA_REGNO)
1974 (gtu:P (match_dup 1)
1975 (match_operand:P 3 "const_int_operand" "n")))]
1976 "INTVAL (operands[2]) < 0
1977 && INTVAL (operands[2]) + INTVAL (operands[3]) == -1"
1978 "addic %0,%1,%2"
1979 [(set_attr "type" "add")])
1980
1981
1982 (define_expand "add<mode>3_carry_in"
1983 [(parallel [
1984 (set (match_operand:GPR 0 "gpc_reg_operand")
1985 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand")
1986 (match_operand:GPR 2 "adde_operand"))
1987 (reg:GPR CA_REGNO)))
1988 (clobber (reg:GPR CA_REGNO))])]
1989 ""
1990 {
1991 if (operands[2] == const0_rtx)
1992 {
1993 emit_insn (gen_add<mode>3_carry_in_0 (operands[0], operands[1]));
1994 DONE;
1995 }
1996 if (operands[2] == constm1_rtx)
1997 {
1998 emit_insn (gen_add<mode>3_carry_in_m1 (operands[0], operands[1]));
1999 DONE;
2000 }
2001 })
2002
2003 (define_insn "*add<mode>3_carry_in_internal"
2004 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2005 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
2006 (match_operand:GPR 2 "gpc_reg_operand" "r"))
2007 (reg:GPR CA_REGNO)))
2008 (clobber (reg:GPR CA_REGNO))]
2009 ""
2010 "adde %0,%1,%2"
2011 [(set_attr "type" "add")])
2012
2013 (define_insn "*add<mode>3_carry_in_internal2"
2014 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2015 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
2016 (reg:GPR CA_REGNO))
2017 (match_operand:GPR 2 "gpc_reg_operand" "r")))
2018 (clobber (reg:GPR CA_REGNO))]
2019 ""
2020 "adde %0,%1,%2"
2021 [(set_attr "type" "add")])
2022
2023 (define_insn "add<mode>3_carry_in_0"
2024 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2025 (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
2026 (reg:GPR CA_REGNO)))
2027 (clobber (reg:GPR CA_REGNO))]
2028 ""
2029 "addze %0,%1"
2030 [(set_attr "type" "add")])
2031
2032 (define_insn "add<mode>3_carry_in_m1"
2033 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2034 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
2035 (reg:GPR CA_REGNO))
2036 (const_int -1)))
2037 (clobber (reg:GPR CA_REGNO))]
2038 ""
2039 "addme %0,%1"
2040 [(set_attr "type" "add")])
2041
2042
2043 (define_expand "one_cmpl<mode>2"
2044 [(set (match_operand:SDI 0 "gpc_reg_operand")
2045 (not:SDI (match_operand:SDI 1 "gpc_reg_operand")))]
2046 ""
2047 {
2048 if (<MODE>mode == DImode && !TARGET_POWERPC64)
2049 {
2050 rs6000_split_logical (operands, NOT, false, false, false);
2051 DONE;
2052 }
2053 })
2054
2055 (define_insn "*one_cmpl<mode>2"
2056 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2057 (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2058 ""
2059 "not %0,%1")
2060
2061 (define_insn_and_split "*one_cmpl<mode>2_dot"
2062 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2063 (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2064 (const_int 0)))
2065 (clobber (match_scratch:GPR 0 "=r,r"))]
2066 "<MODE>mode == Pmode"
2067 "@
2068 not. %0,%1
2069 #"
2070 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2071 [(set (match_dup 0)
2072 (not:GPR (match_dup 1)))
2073 (set (match_dup 2)
2074 (compare:CC (match_dup 0)
2075 (const_int 0)))]
2076 ""
2077 [(set_attr "type" "logical")
2078 (set_attr "dot" "yes")
2079 (set_attr "length" "4,8")])
2080
2081 (define_insn_and_split "*one_cmpl<mode>2_dot2"
2082 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2083 (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2084 (const_int 0)))
2085 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2086 (not:GPR (match_dup 1)))]
2087 "<MODE>mode == Pmode"
2088 "@
2089 not. %0,%1
2090 #"
2091 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2092 [(set (match_dup 0)
2093 (not:GPR (match_dup 1)))
2094 (set (match_dup 2)
2095 (compare:CC (match_dup 0)
2096 (const_int 0)))]
2097 ""
2098 [(set_attr "type" "logical")
2099 (set_attr "dot" "yes")
2100 (set_attr "length" "4,8")])
2101
2102
2103 (define_expand "sub<mode>3"
2104 [(set (match_operand:SDI 0 "gpc_reg_operand")
2105 (minus:SDI (match_operand:SDI 1 "reg_or_short_operand")
2106 (match_operand:SDI 2 "gpc_reg_operand")))]
2107 ""
2108 {
2109 if (<MODE>mode == DImode && !TARGET_POWERPC64)
2110 {
2111 rtx lo0 = gen_lowpart (SImode, operands[0]);
2112 rtx lo1 = gen_lowpart (SImode, operands[1]);
2113 rtx lo2 = gen_lowpart (SImode, operands[2]);
2114 rtx hi0 = gen_highpart (SImode, operands[0]);
2115 rtx hi1 = gen_highpart_mode (SImode, DImode, operands[1]);
2116 rtx hi2 = gen_highpart (SImode, operands[2]);
2117
2118 if (!reg_or_short_operand (lo1, SImode))
2119 lo1 = force_reg (SImode, lo1);
2120 if (!adde_operand (hi1, SImode))
2121 hi1 = force_reg (SImode, hi1);
2122
2123 emit_insn (gen_subfsi3_carry (lo0, lo2, lo1));
2124 emit_insn (gen_subfsi3_carry_in (hi0, hi2, hi1));
2125 DONE;
2126 }
2127
2128 if (short_cint_operand (operands[1], <MODE>mode))
2129 {
2130 emit_insn (gen_subf<mode>3_imm (operands[0], operands[2], operands[1]));
2131 DONE;
2132 }
2133 })
2134
2135 (define_insn "*subf<mode>3"
2136 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2137 (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r")
2138 (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2139 ""
2140 "subf %0,%1,%2"
2141 [(set_attr "type" "add")])
2142
2143 (define_insn_and_split "*subf<mode>3_dot"
2144 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2145 (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
2146 (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2147 (const_int 0)))
2148 (clobber (match_scratch:GPR 0 "=r,r"))]
2149 "<MODE>mode == Pmode"
2150 "@
2151 subf. %0,%1,%2
2152 #"
2153 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2154 [(set (match_dup 0)
2155 (minus:GPR (match_dup 2)
2156 (match_dup 1)))
2157 (set (match_dup 3)
2158 (compare:CC (match_dup 0)
2159 (const_int 0)))]
2160 ""
2161 [(set_attr "type" "add")
2162 (set_attr "dot" "yes")
2163 (set_attr "length" "4,8")])
2164
2165 (define_insn_and_split "*subf<mode>3_dot2"
2166 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2167 (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
2168 (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2169 (const_int 0)))
2170 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2171 (minus:GPR (match_dup 2)
2172 (match_dup 1)))]
2173 "<MODE>mode == Pmode"
2174 "@
2175 subf. %0,%1,%2
2176 #"
2177 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2178 [(set (match_dup 0)
2179 (minus:GPR (match_dup 2)
2180 (match_dup 1)))
2181 (set (match_dup 3)
2182 (compare:CC (match_dup 0)
2183 (const_int 0)))]
2184 ""
2185 [(set_attr "type" "add")
2186 (set_attr "dot" "yes")
2187 (set_attr "length" "4,8")])
2188
2189 (define_insn "subf<mode>3_imm"
2190 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2191 (minus:GPR (match_operand:GPR 2 "short_cint_operand" "I")
2192 (match_operand:GPR 1 "gpc_reg_operand" "r")))
2193 (clobber (reg:GPR CA_REGNO))]
2194 ""
2195 "subfic %0,%1,%2"
2196 [(set_attr "type" "add")])
2197
2198 (define_insn_and_split "subf<mode>3_carry_dot2"
2199 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2200 (compare:CC (minus:P (match_operand:P 2 "gpc_reg_operand" "r,r")
2201 (match_operand:P 1 "gpc_reg_operand" "r,r"))
2202 (const_int 0)))
2203 (set (match_operand:P 0 "gpc_reg_operand" "=r,r")
2204 (minus:P (match_dup 2)
2205 (match_dup 1)))
2206 (set (reg:P CA_REGNO)
2207 (leu:P (match_dup 1)
2208 (match_dup 2)))]
2209 "<MODE>mode == Pmode"
2210 "@
2211 subfc. %0,%1,%2
2212 #"
2213 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2214 [(parallel [(set (match_dup 0)
2215 (minus:P (match_dup 2)
2216 (match_dup 1)))
2217 (set (reg:P CA_REGNO)
2218 (leu:P (match_dup 1)
2219 (match_dup 2)))])
2220 (set (match_dup 3)
2221 (compare:CC (match_dup 0)
2222 (const_int 0)))]
2223 ""
2224 [(set_attr "type" "add")
2225 (set_attr "dot" "yes")
2226 (set_attr "length" "4,8")])
2227
2228 (define_insn "subf<mode>3_carry"
2229 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2230 (minus:P (match_operand:P 2 "reg_or_short_operand" "rI")
2231 (match_operand:P 1 "gpc_reg_operand" "r")))
2232 (set (reg:P CA_REGNO)
2233 (leu:P (match_dup 1)
2234 (match_dup 2)))]
2235 ""
2236 "subf%I2c %0,%1,%2"
2237 [(set_attr "type" "add")])
2238
2239 (define_insn "*subf<mode>3_imm_carry_0"
2240 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2241 (neg:P (match_operand:P 1 "gpc_reg_operand" "r")))
2242 (set (reg:P CA_REGNO)
2243 (eq:P (match_dup 1)
2244 (const_int 0)))]
2245 ""
2246 "subfic %0,%1,0"
2247 [(set_attr "type" "add")])
2248
2249 (define_insn "*subf<mode>3_imm_carry_m1"
2250 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2251 (not:P (match_operand:P 1 "gpc_reg_operand" "r")))
2252 (set (reg:P CA_REGNO)
2253 (const_int 1))]
2254 ""
2255 "subfic %0,%1,-1"
2256 [(set_attr "type" "add")])
2257
2258
2259 (define_expand "subf<mode>3_carry_in"
2260 [(parallel [
2261 (set (match_operand:GPR 0 "gpc_reg_operand")
2262 (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand"))
2263 (reg:GPR CA_REGNO))
2264 (match_operand:GPR 2 "adde_operand")))
2265 (clobber (reg:GPR CA_REGNO))])]
2266 ""
2267 {
2268 if (operands[2] == const0_rtx)
2269 {
2270 emit_insn (gen_subf<mode>3_carry_in_0 (operands[0], operands[1]));
2271 DONE;
2272 }
2273 if (operands[2] == constm1_rtx)
2274 {
2275 emit_insn (gen_subf<mode>3_carry_in_m1 (operands[0], operands[1]));
2276 DONE;
2277 }
2278 })
2279
2280 (define_insn "*subf<mode>3_carry_in_internal"
2281 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2282 (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
2283 (reg:GPR CA_REGNO))
2284 (match_operand:GPR 2 "gpc_reg_operand" "r")))
2285 (clobber (reg:GPR CA_REGNO))]
2286 ""
2287 "subfe %0,%1,%2"
2288 [(set_attr "type" "add")])
2289
2290 (define_insn "subf<mode>3_carry_in_0"
2291 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2292 (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
2293 (reg:GPR CA_REGNO)))
2294 (clobber (reg:GPR CA_REGNO))]
2295 ""
2296 "subfze %0,%1"
2297 [(set_attr "type" "add")])
2298
2299 (define_insn "subf<mode>3_carry_in_m1"
2300 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2301 (plus:GPR (minus:GPR (reg:GPR CA_REGNO)
2302 (match_operand:GPR 1 "gpc_reg_operand" "r"))
2303 (const_int -2)))
2304 (clobber (reg:GPR CA_REGNO))]
2305 ""
2306 "subfme %0,%1"
2307 [(set_attr "type" "add")])
2308
2309 (define_insn "subf<mode>3_carry_in_xx"
2310 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2311 (plus:GPR (reg:GPR CA_REGNO)
2312 (const_int -1)))
2313 (clobber (reg:GPR CA_REGNO))]
2314 ""
2315 "subfe %0,%0,%0"
2316 [(set_attr "type" "add")])
2317
2318
2319 (define_insn "@neg<mode>2"
2320 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2321 (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2322 ""
2323 "neg %0,%1"
2324 [(set_attr "type" "add")])
2325
2326 (define_insn_and_split "*neg<mode>2_dot"
2327 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2328 (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2329 (const_int 0)))
2330 (clobber (match_scratch:GPR 0 "=r,r"))]
2331 "<MODE>mode == Pmode"
2332 "@
2333 neg. %0,%1
2334 #"
2335 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2336 [(set (match_dup 0)
2337 (neg:GPR (match_dup 1)))
2338 (set (match_dup 2)
2339 (compare:CC (match_dup 0)
2340 (const_int 0)))]
2341 ""
2342 [(set_attr "type" "add")
2343 (set_attr "dot" "yes")
2344 (set_attr "length" "4,8")])
2345
2346 (define_insn_and_split "*neg<mode>2_dot2"
2347 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2348 (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2349 (const_int 0)))
2350 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2351 (neg:GPR (match_dup 1)))]
2352 "<MODE>mode == Pmode"
2353 "@
2354 neg. %0,%1
2355 #"
2356 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2357 [(set (match_dup 0)
2358 (neg:GPR (match_dup 1)))
2359 (set (match_dup 2)
2360 (compare:CC (match_dup 0)
2361 (const_int 0)))]
2362 ""
2363 [(set_attr "type" "add")
2364 (set_attr "dot" "yes")
2365 (set_attr "length" "4,8")])
2366
2367
2368 (define_insn "clz<mode>2"
2369 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2370 (clz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2371 ""
2372 "cntlz<wd> %0,%1"
2373 [(set_attr "type" "cntlz")])
2374
2375 (define_expand "ctz<mode>2"
2376 [(set (match_operand:GPR 0 "gpc_reg_operand")
2377 (ctz:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2378 ""
2379 {
2380 if (TARGET_CTZ)
2381 {
2382 emit_insn (gen_ctz<mode>2_hw (operands[0], operands[1]));
2383 DONE;
2384 }
2385
2386 rtx tmp1 = gen_reg_rtx (<MODE>mode);
2387 rtx tmp2 = gen_reg_rtx (<MODE>mode);
2388 rtx tmp3 = gen_reg_rtx (<MODE>mode);
2389
2390 if (TARGET_POPCNTD)
2391 {
2392 emit_insn (gen_add<mode>3 (tmp1, operands[1], constm1_rtx));
2393 emit_insn (gen_one_cmpl<mode>2 (tmp2, operands[1]));
2394 emit_insn (gen_and<mode>3 (tmp3, tmp1, tmp2));
2395 emit_insn (gen_popcntd<mode>2 (operands[0], tmp3));
2396 }
2397 else
2398 {
2399 emit_insn (gen_neg<mode>2 (tmp1, operands[1]));
2400 emit_insn (gen_and<mode>3 (tmp2, operands[1], tmp1));
2401 emit_insn (gen_clz<mode>2 (tmp3, tmp2));
2402 emit_insn (gen_sub<mode>3 (operands[0], GEN_INT (<bits> - 1), tmp3));
2403 }
2404
2405 DONE;
2406 })
2407
2408 (define_insn "ctz<mode>2_hw"
2409 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2410 (ctz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2411 "TARGET_CTZ"
2412 "cnttz<wd> %0,%1"
2413 [(set_attr "type" "cntlz")])
2414
2415 (define_expand "ffs<mode>2"
2416 [(set (match_operand:GPR 0 "gpc_reg_operand")
2417 (ffs:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2418 ""
2419 {
2420 rtx tmp1 = gen_reg_rtx (<MODE>mode);
2421 rtx tmp2 = gen_reg_rtx (<MODE>mode);
2422 rtx tmp3 = gen_reg_rtx (<MODE>mode);
2423 emit_insn (gen_neg<mode>2 (tmp1, operands[1]));
2424 emit_insn (gen_and<mode>3 (tmp2, operands[1], tmp1));
2425 emit_insn (gen_clz<mode>2 (tmp3, tmp2));
2426 emit_insn (gen_sub<mode>3 (operands[0], GEN_INT (<bits>), tmp3));
2427 DONE;
2428 })
2429
2430
2431 (define_expand "popcount<mode>2"
2432 [(set (match_operand:GPR 0 "gpc_reg_operand")
2433 (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2434 "TARGET_POPCNTB || TARGET_POPCNTD"
2435 {
2436 rs6000_emit_popcount (operands[0], operands[1]);
2437 DONE;
2438 })
2439
2440 (define_insn "popcntb<mode>2"
2441 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2442 (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")]
2443 UNSPEC_POPCNTB))]
2444 "TARGET_POPCNTB"
2445 "popcntb %0,%1"
2446 [(set_attr "type" "popcnt")])
2447
2448 (define_insn "popcntd<mode>2"
2449 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2450 (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2451 "TARGET_POPCNTD"
2452 "popcnt<wd> %0,%1"
2453 [(set_attr "type" "popcnt")])
2454
2455
2456 (define_expand "parity<mode>2"
2457 [(set (match_operand:GPR 0 "gpc_reg_operand")
2458 (parity:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2459 "TARGET_POPCNTB"
2460 {
2461 rs6000_emit_parity (operands[0], operands[1]);
2462 DONE;
2463 })
2464
2465 (define_insn "parity<mode>2_cmpb"
2466 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2467 (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")] UNSPEC_PARITY))]
2468 "TARGET_CMPB && TARGET_POPCNTB"
2469 "prty<wd> %0,%1"
2470 [(set_attr "type" "popcnt")])
2471
2472 (define_insn "cfuged"
2473 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2474 (unspec:DI [(match_operand:DI 1 "gpc_reg_operand" "r")
2475 (match_operand:DI 2 "gpc_reg_operand" "r")]
2476 UNSPEC_CFUGED))]
2477 "TARGET_POWER10 && TARGET_64BIT"
2478 "cfuged %0,%1,%2"
2479 [(set_attr "type" "integer")])
2480
2481 (define_insn "cntlzdm"
2482 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2483 (unspec:DI [(match_operand:DI 1 "gpc_reg_operand" "r")
2484 (match_operand:DI 2 "gpc_reg_operand" "r")]
2485 UNSPEC_CNTLZDM))]
2486 "TARGET_POWER10 && TARGET_POWERPC64"
2487 "cntlzdm %0,%1,%2"
2488 [(set_attr "type" "integer")])
2489
2490 (define_insn "cnttzdm"
2491 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2492 (unspec:DI [(match_operand:DI 1 "gpc_reg_operand" "r")
2493 (match_operand:DI 2 "gpc_reg_operand" "r")]
2494 UNSPEC_CNTTZDM))]
2495 "TARGET_POWER10 && TARGET_POWERPC64"
2496 "cnttzdm %0,%1,%2"
2497 [(set_attr "type" "integer")])
2498
2499 (define_insn "pdepd"
2500 [(set (match_operand:DI 0 "register_operand" "=r")
2501 (unspec:DI [(match_operand:DI 1 "gpc_reg_operand" "r")
2502 (match_operand:DI 2 "gpc_reg_operand" "r")]
2503 UNSPEC_PDEPD))]
2504 "TARGET_POWER10 && TARGET_POWERPC64"
2505 "pdepd %0,%1,%2"
2506 [(set_attr "type" "integer")])
2507
2508 (define_insn "pextd"
2509 [(set (match_operand:DI 0 "register_operand" "=r")
2510 (unspec:DI [(match_operand:DI 1 "gpc_reg_operand" "r")
2511 (match_operand:DI 2 "gpc_reg_operand" "r")]
2512 UNSPEC_PEXTD))]
2513 "TARGET_POWER10 && TARGET_POWERPC64"
2514 "pextd %0,%1,%2"
2515 [(set_attr "type" "integer")])
2516
2517 (define_insn "cmpb<mode>3"
2518 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2519 (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")
2520 (match_operand:GPR 2 "gpc_reg_operand" "r")] UNSPEC_CMPB))]
2521 "TARGET_CMPB"
2522 "cmpb %0,%1,%2"
2523 [(set_attr "type" "cmp")])
2524
2525 ;; Since the hardware zeros the upper part of the register, save generating the
2526 ;; AND immediate if we are converting to unsigned
2527 (define_insn "*bswap<mode>2_extenddi"
2528 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2529 (zero_extend:DI
2530 (bswap:HSI (match_operand:HSI 1 "memory_operand" "Z"))))]
2531 "TARGET_POWERPC64"
2532 "l<wd>brx %0,%y1"
2533 [(set_attr "type" "load")])
2534
2535 (define_insn "*bswaphi2_extendsi"
2536 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2537 (zero_extend:SI
2538 (bswap:HI (match_operand:HI 1 "memory_operand" "Z"))))]
2539 ""
2540 "lhbrx %0,%y1"
2541 [(set_attr "type" "load")])
2542
2543 ;; Separate the bswap patterns into load, store, and gpr<-gpr. This prevents
2544 ;; the register allocator from converting a gpr<-gpr swap into a store and then
2545 ;; load with byte swap, which can be slower than doing it in the registers. It
2546 ;; also prevents certain failures with the RELOAD register allocator.
2547
2548 (define_expand "bswap<mode>2"
2549 [(use (match_operand:HSI 0 "reg_or_mem_operand"))
2550 (use (match_operand:HSI 1 "reg_or_mem_operand"))]
2551 ""
2552 {
2553 rtx dest = operands[0];
2554 rtx src = operands[1];
2555
2556 if (!REG_P (dest) && !REG_P (src))
2557 src = force_reg (<MODE>mode, src);
2558
2559 if (MEM_P (src))
2560 {
2561 src = rs6000_force_indexed_or_indirect_mem (src);
2562 emit_insn (gen_bswap<mode>2_load (dest, src));
2563 }
2564 else if (MEM_P (dest))
2565 {
2566 dest = rs6000_force_indexed_or_indirect_mem (dest);
2567 emit_insn (gen_bswap<mode>2_store (dest, src));
2568 }
2569 else
2570 emit_insn (gen_bswap<mode>2_reg (dest, src));
2571 DONE;
2572 })
2573
2574 (define_insn "bswap<mode>2_load"
2575 [(set (match_operand:HSI 0 "gpc_reg_operand" "=r")
2576 (bswap:HSI (match_operand:HSI 1 "memory_operand" "Z")))]
2577 ""
2578 "l<wd>brx %0,%y1"
2579 [(set_attr "type" "load")])
2580
2581 (define_insn "bswap<mode>2_store"
2582 [(set (match_operand:HSI 0 "memory_operand" "=Z")
2583 (bswap:HSI (match_operand:HSI 1 "gpc_reg_operand" "r")))]
2584 ""
2585 "st<wd>brx %1,%y0"
2586 [(set_attr "type" "store")])
2587
2588 (define_insn_and_split "bswaphi2_reg"
2589 [(set (match_operand:HI 0 "gpc_reg_operand" "=&r,wa")
2590 (bswap:HI
2591 (match_operand:HI 1 "gpc_reg_operand" "r,wa")))
2592 (clobber (match_scratch:SI 2 "=&r,X"))]
2593 ""
2594 "@
2595 #
2596 xxbrh %x0,%x1"
2597 "reload_completed && int_reg_operand (operands[0], HImode)"
2598 [(set (match_dup 3)
2599 (and:SI (lshiftrt:SI (match_dup 4)
2600 (const_int 8))
2601 (const_int 255)))
2602 (set (match_dup 2)
2603 (and:SI (ashift:SI (match_dup 4)
2604 (const_int 8))
2605 (const_int 65280))) ;; 0xff00
2606 (set (match_dup 3)
2607 (ior:SI (match_dup 3)
2608 (match_dup 2)))]
2609 {
2610 operands[3] = simplify_gen_subreg (SImode, operands[0], HImode, 0);
2611 operands[4] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
2612 }
2613 [(set_attr "length" "12,4")
2614 (set_attr "type" "*,vecperm")
2615 (set_attr "isa" "*,p9v")])
2616
2617 ;; We are always BITS_BIG_ENDIAN, so the bit positions below in
2618 ;; zero_extract insns do not change for -mlittle.
2619 (define_insn_and_split "bswapsi2_reg"
2620 [(set (match_operand:SI 0 "gpc_reg_operand" "=&r,wa")
2621 (bswap:SI
2622 (match_operand:SI 1 "gpc_reg_operand" "r,wa")))]
2623 ""
2624 "@
2625 #
2626 xxbrw %x0,%x1"
2627 "reload_completed && int_reg_operand (operands[0], SImode)"
2628 [(set (match_dup 0) ; DABC
2629 (rotate:SI (match_dup 1)
2630 (const_int 24)))
2631 (set (match_dup 0) ; DCBC
2632 (ior:SI (and:SI (ashift:SI (match_dup 1)
2633 (const_int 8))
2634 (const_int 16711680))
2635 (and:SI (match_dup 0)
2636 (const_int -16711681))))
2637 (set (match_dup 0) ; DCBA
2638 (ior:SI (and:SI (lshiftrt:SI (match_dup 1)
2639 (const_int 24))
2640 (const_int 255))
2641 (and:SI (match_dup 0)
2642 (const_int -256))))]
2643 ""
2644 [(set_attr "length" "12,4")
2645 (set_attr "type" "*,vecperm")
2646 (set_attr "isa" "*,p9v")])
2647
2648 ;; On systems with LDBRX/STDBRX generate the loads/stores directly, just like
2649 ;; we do for L{H,W}BRX and ST{H,W}BRX above. If not, we have to generate more
2650 ;; complex code.
2651
2652 (define_expand "bswapdi2"
2653 [(parallel [(set (match_operand:DI 0 "reg_or_mem_operand")
2654 (bswap:DI
2655 (match_operand:DI 1 "reg_or_mem_operand")))
2656 (clobber (match_scratch:DI 2))
2657 (clobber (match_scratch:DI 3))])]
2658 ""
2659 {
2660 rtx dest = operands[0];
2661 rtx src = operands[1];
2662
2663 if (!REG_P (dest) && !REG_P (src))
2664 operands[1] = src = force_reg (DImode, src);
2665
2666 if (TARGET_POWERPC64 && TARGET_LDBRX)
2667 {
2668 if (MEM_P (src))
2669 {
2670 src = rs6000_force_indexed_or_indirect_mem (src);
2671 emit_insn (gen_bswapdi2_load (dest, src));
2672 }
2673 else if (MEM_P (dest))
2674 {
2675 dest = rs6000_force_indexed_or_indirect_mem (dest);
2676 emit_insn (gen_bswapdi2_store (dest, src));
2677 }
2678 else if (TARGET_P9_VECTOR)
2679 emit_insn (gen_bswapdi2_xxbrd (dest, src));
2680 else
2681 emit_insn (gen_bswapdi2_reg (dest, src));
2682 DONE;
2683 }
2684
2685 if (!TARGET_POWERPC64)
2686 {
2687 /* 32-bit mode needs fewer scratch registers, but 32-bit addressing mode
2688 that uses 64-bit registers needs the same scratch registers as 64-bit
2689 mode. */
2690 emit_insn (gen_bswapdi2_32bit (dest, src));
2691 DONE;
2692 }
2693 })
2694
2695 ;; Power7/cell has ldbrx/stdbrx, so use it directly
2696 (define_insn "bswapdi2_load"
2697 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2698 (bswap:DI (match_operand:DI 1 "memory_operand" "Z")))]
2699 "TARGET_POWERPC64 && TARGET_LDBRX"
2700 "ldbrx %0,%y1"
2701 [(set_attr "type" "load")])
2702
2703 (define_insn "bswapdi2_store"
2704 [(set (match_operand:DI 0 "memory_operand" "=Z")
2705 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "r")))]
2706 "TARGET_POWERPC64 && TARGET_LDBRX"
2707 "stdbrx %1,%y0"
2708 [(set_attr "type" "store")])
2709
2710 (define_insn "bswapdi2_xxbrd"
2711 [(set (match_operand:DI 0 "gpc_reg_operand" "=wa")
2712 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "wa")))]
2713 "TARGET_P9_VECTOR"
2714 "xxbrd %x0,%x1"
2715 [(set_attr "type" "vecperm")
2716 (set_attr "isa" "p9v")])
2717
2718 (define_insn "bswapdi2_reg"
2719 [(set (match_operand:DI 0 "gpc_reg_operand" "=&r")
2720 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "r")))
2721 (clobber (match_scratch:DI 2 "=&r"))
2722 (clobber (match_scratch:DI 3 "=&r"))]
2723 "TARGET_POWERPC64 && TARGET_LDBRX && !TARGET_P9_VECTOR"
2724 "#"
2725 [(set_attr "length" "36")])
2726
2727 ;; Non-power7/cell, fall back to use lwbrx/stwbrx
2728 (define_insn "*bswapdi2_64bit"
2729 [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,&r")
2730 (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2731 (clobber (match_scratch:DI 2 "=&b,&b,&r"))
2732 (clobber (match_scratch:DI 3 "=&r,&r,&r"))]
2733 "TARGET_POWERPC64 && !TARGET_LDBRX
2734 && (REG_P (operands[0]) || REG_P (operands[1]))
2735 && !(MEM_P (operands[0]) && MEM_VOLATILE_P (operands[0]))
2736 && !(MEM_P (operands[1]) && MEM_VOLATILE_P (operands[1]))"
2737 "#"
2738 [(set_attr "length" "16,12,36")])
2739
2740 (define_split
2741 [(set (match_operand:DI 0 "gpc_reg_operand")
2742 (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand")))
2743 (clobber (match_operand:DI 2 "gpc_reg_operand"))
2744 (clobber (match_operand:DI 3 "gpc_reg_operand"))]
2745 "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2746 [(const_int 0)]
2747 {
2748 rtx dest = operands[0];
2749 rtx src = operands[1];
2750 rtx op2 = operands[2];
2751 rtx op3 = operands[3];
2752 rtx op3_32 = simplify_gen_subreg (SImode, op3, DImode,
2753 BYTES_BIG_ENDIAN ? 4 : 0);
2754 rtx dest_32 = simplify_gen_subreg (SImode, dest, DImode,
2755 BYTES_BIG_ENDIAN ? 4 : 0);
2756 rtx addr1;
2757 rtx addr2;
2758 rtx word1;
2759 rtx word2;
2760
2761 addr1 = XEXP (src, 0);
2762 if (GET_CODE (addr1) == PLUS)
2763 {
2764 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2765 if (TARGET_AVOID_XFORM)
2766 {
2767 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2768 addr2 = op2;
2769 }
2770 else
2771 addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2772 }
2773 else if (TARGET_AVOID_XFORM)
2774 {
2775 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2776 addr2 = op2;
2777 }
2778 else
2779 {
2780 emit_move_insn (op2, GEN_INT (4));
2781 addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2782 }
2783
2784 word1 = change_address (src, SImode, addr1);
2785 word2 = change_address (src, SImode, addr2);
2786
2787 if (BYTES_BIG_ENDIAN)
2788 {
2789 emit_insn (gen_bswapsi2 (op3_32, word2));
2790 emit_insn (gen_bswapsi2 (dest_32, word1));
2791 }
2792 else
2793 {
2794 emit_insn (gen_bswapsi2 (op3_32, word1));
2795 emit_insn (gen_bswapsi2 (dest_32, word2));
2796 }
2797
2798 emit_insn (gen_ashldi3 (op3, op3, GEN_INT (32)));
2799 emit_insn (gen_iordi3 (dest, dest, op3));
2800 DONE;
2801 })
2802
2803 (define_split
2804 [(set (match_operand:DI 0 "indexed_or_indirect_operand")
2805 (bswap:DI (match_operand:DI 1 "gpc_reg_operand")))
2806 (clobber (match_operand:DI 2 "gpc_reg_operand"))
2807 (clobber (match_operand:DI 3 "gpc_reg_operand"))]
2808 "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2809 [(const_int 0)]
2810 {
2811 rtx dest = operands[0];
2812 rtx src = operands[1];
2813 rtx op2 = operands[2];
2814 rtx op3 = operands[3];
2815 rtx src_si = simplify_gen_subreg (SImode, src, DImode,
2816 BYTES_BIG_ENDIAN ? 4 : 0);
2817 rtx op3_si = simplify_gen_subreg (SImode, op3, DImode,
2818 BYTES_BIG_ENDIAN ? 4 : 0);
2819 rtx addr1;
2820 rtx addr2;
2821 rtx word1;
2822 rtx word2;
2823
2824 addr1 = XEXP (dest, 0);
2825 if (GET_CODE (addr1) == PLUS)
2826 {
2827 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2828 if (TARGET_AVOID_XFORM)
2829 {
2830 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2831 addr2 = op2;
2832 }
2833 else
2834 addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2835 }
2836 else if (TARGET_AVOID_XFORM)
2837 {
2838 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2839 addr2 = op2;
2840 }
2841 else
2842 {
2843 emit_move_insn (op2, GEN_INT (4));
2844 addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2845 }
2846
2847 word1 = change_address (dest, SImode, addr1);
2848 word2 = change_address (dest, SImode, addr2);
2849
2850 emit_insn (gen_lshrdi3 (op3, src, GEN_INT (32)));
2851
2852 if (BYTES_BIG_ENDIAN)
2853 {
2854 emit_insn (gen_bswapsi2 (word1, src_si));
2855 emit_insn (gen_bswapsi2 (word2, op3_si));
2856 }
2857 else
2858 {
2859 emit_insn (gen_bswapsi2 (word2, src_si));
2860 emit_insn (gen_bswapsi2 (word1, op3_si));
2861 }
2862 DONE;
2863 })
2864
2865 (define_split
2866 [(set (match_operand:DI 0 "gpc_reg_operand")
2867 (bswap:DI (match_operand:DI 1 "gpc_reg_operand")))
2868 (clobber (match_operand:DI 2 "gpc_reg_operand"))
2869 (clobber (match_operand:DI 3 "gpc_reg_operand"))]
2870 "TARGET_POWERPC64 && !TARGET_P9_VECTOR && reload_completed"
2871 [(const_int 0)]
2872 {
2873 rtx dest = operands[0];
2874 rtx src = operands[1];
2875 rtx op2 = operands[2];
2876 rtx op3 = operands[3];
2877 int lo_off = BYTES_BIG_ENDIAN ? 4 : 0;
2878 rtx dest_si = simplify_gen_subreg (SImode, dest, DImode, lo_off);
2879 rtx src_si = simplify_gen_subreg (SImode, src, DImode, lo_off);
2880 rtx op2_si = simplify_gen_subreg (SImode, op2, DImode, lo_off);
2881 rtx op3_si = simplify_gen_subreg (SImode, op3, DImode, lo_off);
2882
2883 emit_insn (gen_lshrdi3 (op2, src, GEN_INT (32)));
2884 emit_insn (gen_bswapsi2 (dest_si, src_si));
2885 emit_insn (gen_bswapsi2 (op3_si, op2_si));
2886 emit_insn (gen_ashldi3 (dest, dest, GEN_INT (32)));
2887 emit_insn (gen_iordi3 (dest, dest, op3));
2888 DONE;
2889 })
2890
2891 (define_insn "bswapdi2_32bit"
2892 [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,?&r")
2893 (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2894 (clobber (match_scratch:SI 2 "=&b,&b,X"))]
2895 "!TARGET_POWERPC64 && (REG_P (operands[0]) || REG_P (operands[1]))"
2896 "#"
2897 [(set_attr "length" "16,12,36")])
2898
2899 (define_split
2900 [(set (match_operand:DI 0 "gpc_reg_operand")
2901 (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand")))
2902 (clobber (match_operand:SI 2 "gpc_reg_operand"))]
2903 "!TARGET_POWERPC64 && reload_completed"
2904 [(const_int 0)]
2905 {
2906 rtx dest = operands[0];
2907 rtx src = operands[1];
2908 rtx op2 = operands[2];
2909 rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
2910 rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
2911 rtx addr1;
2912 rtx addr2;
2913 rtx word1;
2914 rtx word2;
2915
2916 addr1 = XEXP (src, 0);
2917 if (GET_CODE (addr1) == PLUS)
2918 {
2919 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2920 if (TARGET_AVOID_XFORM
2921 || REGNO (XEXP (addr1, 1)) == REGNO (dest2))
2922 {
2923 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2924 addr2 = op2;
2925 }
2926 else
2927 addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
2928 }
2929 else if (TARGET_AVOID_XFORM
2930 || REGNO (addr1) == REGNO (dest2))
2931 {
2932 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2933 addr2 = op2;
2934 }
2935 else
2936 {
2937 emit_move_insn (op2, GEN_INT (4));
2938 addr2 = gen_rtx_PLUS (SImode, op2, addr1);
2939 }
2940
2941 word1 = change_address (src, SImode, addr1);
2942 word2 = change_address (src, SImode, addr2);
2943
2944 emit_insn (gen_bswapsi2 (dest2, word1));
2945 /* The REGNO (dest2) tests above ensure that addr2 has not been trashed,
2946 thus allowing us to omit an early clobber on the output. */
2947 emit_insn (gen_bswapsi2 (dest1, word2));
2948 DONE;
2949 })
2950
2951 (define_split
2952 [(set (match_operand:DI 0 "indexed_or_indirect_operand")
2953 (bswap:DI (match_operand:DI 1 "gpc_reg_operand")))
2954 (clobber (match_operand:SI 2 "gpc_reg_operand"))]
2955 "!TARGET_POWERPC64 && reload_completed"
2956 [(const_int 0)]
2957 {
2958 rtx dest = operands[0];
2959 rtx src = operands[1];
2960 rtx op2 = operands[2];
2961 rtx src1 = simplify_gen_subreg (SImode, src, DImode, 0);
2962 rtx src2 = simplify_gen_subreg (SImode, src, DImode, 4);
2963 rtx addr1;
2964 rtx addr2;
2965 rtx word1;
2966 rtx word2;
2967
2968 addr1 = XEXP (dest, 0);
2969 if (GET_CODE (addr1) == PLUS)
2970 {
2971 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2972 if (TARGET_AVOID_XFORM)
2973 {
2974 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2975 addr2 = op2;
2976 }
2977 else
2978 addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
2979 }
2980 else if (TARGET_AVOID_XFORM)
2981 {
2982 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2983 addr2 = op2;
2984 }
2985 else
2986 {
2987 emit_move_insn (op2, GEN_INT (4));
2988 addr2 = gen_rtx_PLUS (SImode, op2, addr1);
2989 }
2990
2991 word1 = change_address (dest, SImode, addr1);
2992 word2 = change_address (dest, SImode, addr2);
2993
2994 emit_insn (gen_bswapsi2 (word2, src1));
2995 emit_insn (gen_bswapsi2 (word1, src2));
2996 DONE;
2997 })
2998
2999 (define_split
3000 [(set (match_operand:DI 0 "gpc_reg_operand")
3001 (bswap:DI (match_operand:DI 1 "gpc_reg_operand")))
3002 (clobber (match_operand:SI 2 ""))]
3003 "!TARGET_POWERPC64 && reload_completed"
3004 [(const_int 0)]
3005 {
3006 rtx dest = operands[0];
3007 rtx src = operands[1];
3008 rtx src1 = simplify_gen_subreg (SImode, src, DImode, 0);
3009 rtx src2 = simplify_gen_subreg (SImode, src, DImode, 4);
3010 rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
3011 rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
3012
3013 emit_insn (gen_bswapsi2 (dest1, src2));
3014 emit_insn (gen_bswapsi2 (dest2, src1));
3015 DONE;
3016 })
3017
3018
3019 (define_insn "mul<mode>3"
3020 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3021 (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3022 (match_operand:GPR 2 "reg_or_short_operand" "r,I")))]
3023 ""
3024 "@
3025 mull<wd> %0,%1,%2
3026 mulli %0,%1,%2"
3027 [(set_attr "type" "mul")
3028 (set (attr "size")
3029 (cond [(match_operand:GPR 2 "s8bit_cint_operand")
3030 (const_string "8")
3031 (match_operand:GPR 2 "short_cint_operand")
3032 (const_string "16")]
3033 (const_string "<bits>")))])
3034
3035 (define_insn_and_split "*mul<mode>3_dot"
3036 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3037 (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3038 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3039 (const_int 0)))
3040 (clobber (match_scratch:GPR 0 "=r,r"))]
3041 "<MODE>mode == Pmode"
3042 "@
3043 mull<wd>. %0,%1,%2
3044 #"
3045 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3046 [(set (match_dup 0)
3047 (mult:GPR (match_dup 1)
3048 (match_dup 2)))
3049 (set (match_dup 3)
3050 (compare:CC (match_dup 0)
3051 (const_int 0)))]
3052 ""
3053 [(set_attr "type" "mul")
3054 (set_attr "size" "<bits>")
3055 (set_attr "dot" "yes")
3056 (set_attr "length" "4,8")])
3057
3058 (define_insn_and_split "*mul<mode>3_dot2"
3059 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3060 (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3061 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3062 (const_int 0)))
3063 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3064 (mult:GPR (match_dup 1)
3065 (match_dup 2)))]
3066 "<MODE>mode == Pmode"
3067 "@
3068 mull<wd>. %0,%1,%2
3069 #"
3070 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3071 [(set (match_dup 0)
3072 (mult:GPR (match_dup 1)
3073 (match_dup 2)))
3074 (set (match_dup 3)
3075 (compare:CC (match_dup 0)
3076 (const_int 0)))]
3077 ""
3078 [(set_attr "type" "mul")
3079 (set_attr "size" "<bits>")
3080 (set_attr "dot" "yes")
3081 (set_attr "length" "4,8")])
3082
3083
3084 (define_expand "<su>mul<mode>3_highpart"
3085 [(set (match_operand:GPR 0 "gpc_reg_operand")
3086 (subreg:GPR
3087 (mult:<DMODE> (any_extend:<DMODE>
3088 (match_operand:GPR 1 "gpc_reg_operand"))
3089 (any_extend:<DMODE>
3090 (match_operand:GPR 2 "gpc_reg_operand")))
3091 0))]
3092 ""
3093 {
3094 if (<MODE>mode == SImode && TARGET_POWERPC64)
3095 {
3096 emit_insn (gen_<su>mulsi3_highpart_64 (operands[0], operands[1],
3097 operands[2]));
3098 DONE;
3099 }
3100
3101 if (!WORDS_BIG_ENDIAN)
3102 {
3103 emit_insn (gen_<su>mul<mode>3_highpart_le (operands[0], operands[1],
3104 operands[2]));
3105 DONE;
3106 }
3107 })
3108
3109 (define_insn "*<su>mul<mode>3_highpart"
3110 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3111 (subreg:GPR
3112 (mult:<DMODE> (any_extend:<DMODE>
3113 (match_operand:GPR 1 "gpc_reg_operand" "r"))
3114 (any_extend:<DMODE>
3115 (match_operand:GPR 2 "gpc_reg_operand" "r")))
3116 0))]
3117 "WORDS_BIG_ENDIAN && !(<MODE>mode == SImode && TARGET_POWERPC64)"
3118 "mulh<wd><u> %0,%1,%2"
3119 [(set_attr "type" "mul")
3120 (set_attr "size" "<bits>")])
3121
3122 (define_insn "<su>mulsi3_highpart_le"
3123 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
3124 (subreg:SI
3125 (mult:DI (any_extend:DI
3126 (match_operand:SI 1 "gpc_reg_operand" "r"))
3127 (any_extend:DI
3128 (match_operand:SI 2 "gpc_reg_operand" "r")))
3129 4))]
3130 "!WORDS_BIG_ENDIAN && !TARGET_POWERPC64"
3131 "mulhw<u> %0,%1,%2"
3132 [(set_attr "type" "mul")])
3133
3134 (define_insn "<su>muldi3_highpart_le"
3135 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3136 (subreg:DI
3137 (mult:TI (any_extend:TI
3138 (match_operand:DI 1 "gpc_reg_operand" "r"))
3139 (any_extend:TI
3140 (match_operand:DI 2 "gpc_reg_operand" "r")))
3141 8))]
3142 "!WORDS_BIG_ENDIAN && TARGET_POWERPC64"
3143 "mulhd<u> %0,%1,%2"
3144 [(set_attr "type" "mul")
3145 (set_attr "size" "64")])
3146
3147 (define_insn "<su>mulsi3_highpart_64"
3148 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
3149 (truncate:SI
3150 (lshiftrt:DI
3151 (mult:DI (any_extend:DI
3152 (match_operand:SI 1 "gpc_reg_operand" "r"))
3153 (any_extend:DI
3154 (match_operand:SI 2 "gpc_reg_operand" "r")))
3155 (const_int 32))))]
3156 "TARGET_POWERPC64"
3157 "mulhw<u> %0,%1,%2"
3158 [(set_attr "type" "mul")])
3159
3160 (define_expand "<u>mul<mode><dmode>3"
3161 [(set (match_operand:<DMODE> 0 "gpc_reg_operand")
3162 (mult:<DMODE> (any_extend:<DMODE>
3163 (match_operand:GPR 1 "gpc_reg_operand"))
3164 (any_extend:<DMODE>
3165 (match_operand:GPR 2 "gpc_reg_operand"))))]
3166 "!(<MODE>mode == SImode && TARGET_POWERPC64)"
3167 {
3168 rtx l = gen_reg_rtx (<MODE>mode);
3169 rtx h = gen_reg_rtx (<MODE>mode);
3170 emit_insn (gen_mul<mode>3 (l, operands[1], operands[2]));
3171 emit_insn (gen_<su>mul<mode>3_highpart (h, operands[1], operands[2]));
3172 emit_move_insn (gen_lowpart (<MODE>mode, operands[0]), l);
3173 emit_move_insn (gen_highpart (<MODE>mode, operands[0]), h);
3174 DONE;
3175 })
3176
3177 (define_insn "*maddld<mode>4"
3178 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3179 (plus:GPR (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3180 (match_operand:GPR 2 "gpc_reg_operand" "r"))
3181 (match_operand:GPR 3 "gpc_reg_operand" "r")))]
3182 "TARGET_MADDLD"
3183 "maddld %0,%1,%2,%3"
3184 [(set_attr "type" "mul")])
3185
3186 (define_insn "udiv<mode>3"
3187 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3188 (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3189 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3190 ""
3191 "div<wd>u %0,%1,%2"
3192 [(set_attr "type" "div")
3193 (set_attr "size" "<bits>")])
3194
3195
3196 ;; For powers of two we can do sra[wd]i/addze for divide and then adjust for
3197 ;; modulus. If it isn't a power of two, force operands into register and do
3198 ;; a normal divide.
3199 (define_expand "div<mode>3"
3200 [(set (match_operand:GPR 0 "gpc_reg_operand")
3201 (div:GPR (match_operand:GPR 1 "gpc_reg_operand")
3202 (match_operand:GPR 2 "reg_or_cint_operand")))]
3203 ""
3204 {
3205 if (CONST_INT_P (operands[2])
3206 && INTVAL (operands[2]) > 0
3207 && exact_log2 (INTVAL (operands[2])) >= 0)
3208 {
3209 emit_insn (gen_div<mode>3_sra (operands[0], operands[1], operands[2]));
3210 DONE;
3211 }
3212
3213 operands[2] = force_reg (<MODE>mode, operands[2]);
3214 })
3215
3216 (define_insn "*div<mode>3"
3217 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3218 (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3219 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3220 ""
3221 "div<wd> %0,%1,%2"
3222 [(set_attr "type" "div")
3223 (set_attr "size" "<bits>")])
3224
3225 (define_insn "div<mode>3_sra"
3226 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3227 (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3228 (match_operand:GPR 2 "exact_log2_cint_operand" "N")))
3229 (clobber (reg:GPR CA_REGNO))]
3230 ""
3231 "sra<wd>i %0,%1,%p2\;addze %0,%0"
3232 [(set_attr "type" "two")
3233 (set_attr "length" "8")])
3234
3235 (define_insn_and_split "*div<mode>3_sra_dot"
3236 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3237 (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3238 (match_operand:GPR 2 "exact_log2_cint_operand" "N,N"))
3239 (const_int 0)))
3240 (clobber (match_scratch:GPR 0 "=r,r"))
3241 (clobber (reg:GPR CA_REGNO))]
3242 "<MODE>mode == Pmode"
3243 "@
3244 sra<wd>i %0,%1,%p2\;addze. %0,%0
3245 #"
3246 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3247 [(parallel [(set (match_dup 0)
3248 (div:GPR (match_dup 1)
3249 (match_dup 2)))
3250 (clobber (reg:GPR CA_REGNO))])
3251 (set (match_dup 3)
3252 (compare:CC (match_dup 0)
3253 (const_int 0)))]
3254 ""
3255 [(set_attr "type" "two")
3256 (set_attr "length" "8,12")
3257 (set_attr "cell_micro" "not")])
3258
3259 (define_insn_and_split "*div<mode>3_sra_dot2"
3260 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3261 (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3262 (match_operand:GPR 2 "exact_log2_cint_operand" "N,N"))
3263 (const_int 0)))
3264 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3265 (div:GPR (match_dup 1)
3266 (match_dup 2)))
3267 (clobber (reg:GPR CA_REGNO))]
3268 "<MODE>mode == Pmode"
3269 "@
3270 sra<wd>i %0,%1,%p2\;addze. %0,%0
3271 #"
3272 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3273 [(parallel [(set (match_dup 0)
3274 (div:GPR (match_dup 1)
3275 (match_dup 2)))
3276 (clobber (reg:GPR CA_REGNO))])
3277 (set (match_dup 3)
3278 (compare:CC (match_dup 0)
3279 (const_int 0)))]
3280 ""
3281 [(set_attr "type" "two")
3282 (set_attr "length" "8,12")
3283 (set_attr "cell_micro" "not")])
3284
3285 (define_expand "mod<mode>3"
3286 [(set (match_operand:GPR 0 "gpc_reg_operand")
3287 (mod:GPR (match_operand:GPR 1 "gpc_reg_operand")
3288 (match_operand:GPR 2 "reg_or_cint_operand")))]
3289 ""
3290 {
3291 int i;
3292 rtx temp1;
3293 rtx temp2;
3294
3295 if (!CONST_INT_P (operands[2])
3296 || INTVAL (operands[2]) <= 0
3297 || (i = exact_log2 (INTVAL (operands[2]))) < 0)
3298 {
3299 if (!TARGET_MODULO)
3300 FAIL;
3301
3302 operands[2] = force_reg (<MODE>mode, operands[2]);
3303 }
3304 else
3305 {
3306 temp1 = gen_reg_rtx (<MODE>mode);
3307 temp2 = gen_reg_rtx (<MODE>mode);
3308
3309 emit_insn (gen_div<mode>3 (temp1, operands[1], operands[2]));
3310 emit_insn (gen_ashl<mode>3 (temp2, temp1, GEN_INT (i)));
3311 emit_insn (gen_sub<mode>3 (operands[0], operands[1], temp2));
3312 DONE;
3313 }
3314 })
3315
3316 ;; In order to enable using a peephole2 for combining div/mod to eliminate the
3317 ;; mod, prefer putting the result of mod into a different register
3318 (define_insn "*mod<mode>3"
3319 [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
3320 (mod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3321 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3322 "TARGET_MODULO"
3323 "mods<wd> %0,%1,%2"
3324 [(set_attr "type" "div")
3325 (set_attr "size" "<bits>")])
3326
3327
3328 (define_insn "umod<mode>3"
3329 [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
3330 (umod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3331 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3332 "TARGET_MODULO"
3333 "modu<wd> %0,%1,%2"
3334 [(set_attr "type" "div")
3335 (set_attr "size" "<bits>")])
3336
3337 ;; On machines with modulo support, do a combined div/mod the old fashioned
3338 ;; method, since the multiply/subtract is faster than doing the mod instruction
3339 ;; after a divide.
3340
3341 (define_peephole2
3342 [(set (match_operand:GPR 0 "gpc_reg_operand")
3343 (div:GPR (match_operand:GPR 1 "gpc_reg_operand")
3344 (match_operand:GPR 2 "gpc_reg_operand")))
3345 (set (match_operand:GPR 3 "gpc_reg_operand")
3346 (mod:GPR (match_dup 1)
3347 (match_dup 2)))]
3348 "TARGET_MODULO
3349 && ! reg_mentioned_p (operands[0], operands[1])
3350 && ! reg_mentioned_p (operands[0], operands[2])
3351 && ! reg_mentioned_p (operands[3], operands[1])
3352 && ! reg_mentioned_p (operands[3], operands[2])"
3353 [(set (match_dup 0)
3354 (div:GPR (match_dup 1)
3355 (match_dup 2)))
3356 (set (match_dup 3)
3357 (mult:GPR (match_dup 0)
3358 (match_dup 2)))
3359 (set (match_dup 3)
3360 (minus:GPR (match_dup 1)
3361 (match_dup 3)))])
3362
3363 (define_peephole2
3364 [(set (match_operand:GPR 0 "gpc_reg_operand")
3365 (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand")
3366 (match_operand:GPR 2 "gpc_reg_operand")))
3367 (set (match_operand:GPR 3 "gpc_reg_operand")
3368 (umod:GPR (match_dup 1)
3369 (match_dup 2)))]
3370 "TARGET_MODULO
3371 && ! reg_mentioned_p (operands[0], operands[1])
3372 && ! reg_mentioned_p (operands[0], operands[2])
3373 && ! reg_mentioned_p (operands[3], operands[1])
3374 && ! reg_mentioned_p (operands[3], operands[2])"
3375 [(set (match_dup 0)
3376 (udiv:GPR (match_dup 1)
3377 (match_dup 2)))
3378 (set (match_dup 3)
3379 (mult:GPR (match_dup 0)
3380 (match_dup 2)))
3381 (set (match_dup 3)
3382 (minus:GPR (match_dup 1)
3383 (match_dup 3)))])
3384
3385 \f
3386 ;; Logical instructions
3387 ;; The logical instructions are mostly combined by using match_operator,
3388 ;; but the plain AND insns are somewhat different because there is no
3389 ;; plain 'andi' (only 'andi.'), no plain 'andis', and there are all
3390 ;; those rotate-and-mask operations. Thus, the AND insns come first.
3391
3392 (define_expand "and<mode>3"
3393 [(set (match_operand:SDI 0 "gpc_reg_operand")
3394 (and:SDI (match_operand:SDI 1 "gpc_reg_operand")
3395 (match_operand:SDI 2 "reg_or_cint_operand")))]
3396 ""
3397 {
3398 if (<MODE>mode == DImode && !TARGET_POWERPC64)
3399 {
3400 rs6000_split_logical (operands, AND, false, false, false);
3401 DONE;
3402 }
3403
3404 if (CONST_INT_P (operands[2]))
3405 {
3406 if (rs6000_is_valid_and_mask (operands[2], <MODE>mode))
3407 {
3408 emit_insn (gen_and<mode>3_mask (operands[0], operands[1], operands[2]));
3409 DONE;
3410 }
3411
3412 if (logical_const_operand (operands[2], <MODE>mode))
3413 {
3414 emit_insn (gen_and<mode>3_imm (operands[0], operands[1], operands[2]));
3415 DONE;
3416 }
3417
3418 if (rs6000_is_valid_2insn_and (operands[2], <MODE>mode))
3419 {
3420 rs6000_emit_2insn_and (<MODE>mode, operands, true, 0);
3421 DONE;
3422 }
3423
3424 operands[2] = force_reg (<MODE>mode, operands[2]);
3425 }
3426 })
3427
3428
3429 (define_insn "and<mode>3_imm"
3430 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3431 (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3432 (match_operand:GPR 2 "logical_const_operand" "n")))
3433 (clobber (match_scratch:CC 3 "=x"))]
3434 "!rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3435 "andi%e2. %0,%1,%u2"
3436 [(set_attr "type" "logical")
3437 (set_attr "dot" "yes")])
3438
3439 (define_insn_and_split "*and<mode>3_imm_dot"
3440 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3441 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3442 (match_operand:GPR 2 "logical_const_operand" "n,n"))
3443 (const_int 0)))
3444 (clobber (match_scratch:GPR 0 "=r,r"))
3445 (clobber (match_scratch:CC 4 "=X,x"))]
3446 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3447 && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3448 "@
3449 andi%e2. %0,%1,%u2
3450 #"
3451 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3452 [(parallel [(set (match_dup 0)
3453 (and:GPR (match_dup 1)
3454 (match_dup 2)))
3455 (clobber (match_dup 4))])
3456 (set (match_dup 3)
3457 (compare:CC (match_dup 0)
3458 (const_int 0)))]
3459 ""
3460 [(set_attr "type" "logical")
3461 (set_attr "dot" "yes")
3462 (set_attr "length" "4,8")])
3463
3464 (define_insn_and_split "*and<mode>3_imm_dot2"
3465 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3466 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3467 (match_operand:GPR 2 "logical_const_operand" "n,n"))
3468 (const_int 0)))
3469 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3470 (and:GPR (match_dup 1)
3471 (match_dup 2)))
3472 (clobber (match_scratch:CC 4 "=X,x"))]
3473 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3474 && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3475 "@
3476 andi%e2. %0,%1,%u2
3477 #"
3478 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3479 [(parallel [(set (match_dup 0)
3480 (and:GPR (match_dup 1)
3481 (match_dup 2)))
3482 (clobber (match_dup 4))])
3483 (set (match_dup 3)
3484 (compare:CC (match_dup 0)
3485 (const_int 0)))]
3486 ""
3487 [(set_attr "type" "logical")
3488 (set_attr "dot" "yes")
3489 (set_attr "length" "4,8")])
3490
3491 (define_insn_and_split "*and<mode>3_imm_mask_dot"
3492 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3493 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3494 (match_operand:GPR 2 "logical_const_operand" "n,n"))
3495 (const_int 0)))
3496 (clobber (match_scratch:GPR 0 "=r,r"))]
3497 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3498 && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3499 "@
3500 andi%e2. %0,%1,%u2
3501 #"
3502 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3503 [(set (match_dup 0)
3504 (and:GPR (match_dup 1)
3505 (match_dup 2)))
3506 (set (match_dup 3)
3507 (compare:CC (match_dup 0)
3508 (const_int 0)))]
3509 ""
3510 [(set_attr "type" "logical")
3511 (set_attr "dot" "yes")
3512 (set_attr "length" "4,8")])
3513
3514 (define_insn_and_split "*and<mode>3_imm_mask_dot2"
3515 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3516 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3517 (match_operand:GPR 2 "logical_const_operand" "n,n"))
3518 (const_int 0)))
3519 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3520 (and:GPR (match_dup 1)
3521 (match_dup 2)))]
3522 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3523 && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3524 "@
3525 andi%e2. %0,%1,%u2
3526 #"
3527 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3528 [(set (match_dup 0)
3529 (and:GPR (match_dup 1)
3530 (match_dup 2)))
3531 (set (match_dup 3)
3532 (compare:CC (match_dup 0)
3533 (const_int 0)))]
3534 ""
3535 [(set_attr "type" "logical")
3536 (set_attr "dot" "yes")
3537 (set_attr "length" "4,8")])
3538
3539 (define_insn "*and<mode>3_imm_dot_shifted"
3540 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
3541 (compare:CC
3542 (and:GPR
3543 (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3544 (match_operand:SI 4 "const_int_operand" "n"))
3545 (match_operand:GPR 2 "const_int_operand" "n"))
3546 (const_int 0)))
3547 (clobber (match_scratch:GPR 0 "=r"))]
3548 "logical_const_operand (GEN_INT (UINTVAL (operands[2])
3549 << INTVAL (operands[4])),
3550 DImode)
3551 && (<MODE>mode == Pmode
3552 || (UINTVAL (operands[2]) << INTVAL (operands[4])) <= 0x7fffffff)"
3553 {
3554 operands[2] = GEN_INT (UINTVAL (operands[2]) << INTVAL (operands[4]));
3555 return "andi%e2. %0,%1,%u2";
3556 }
3557 [(set_attr "type" "logical")
3558 (set_attr "dot" "yes")])
3559
3560
3561 (define_insn "and<mode>3_mask"
3562 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3563 (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3564 (match_operand:GPR 2 "const_int_operand" "n")))]
3565 "rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3566 {
3567 return rs6000_insn_for_and_mask (<MODE>mode, operands, false);
3568 }
3569 [(set_attr "type" "shift")])
3570
3571 (define_insn_and_split "*and<mode>3_mask_dot"
3572 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3573 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3574 (match_operand:GPR 2 "const_int_operand" "n,n"))
3575 (const_int 0)))
3576 (clobber (match_scratch:GPR 0 "=r,r"))]
3577 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3578 && !logical_const_operand (operands[2], <MODE>mode)
3579 && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3580 {
3581 if (which_alternative == 0)
3582 return rs6000_insn_for_and_mask (<MODE>mode, operands, true);
3583 else
3584 return "#";
3585 }
3586 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3587 [(set (match_dup 0)
3588 (and:GPR (match_dup 1)
3589 (match_dup 2)))
3590 (set (match_dup 3)
3591 (compare:CC (match_dup 0)
3592 (const_int 0)))]
3593 ""
3594 [(set_attr "type" "shift")
3595 (set_attr "dot" "yes")
3596 (set_attr "length" "4,8")])
3597
3598 (define_insn_and_split "*and<mode>3_mask_dot2"
3599 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3600 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3601 (match_operand:GPR 2 "const_int_operand" "n,n"))
3602 (const_int 0)))
3603 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3604 (and:GPR (match_dup 1)
3605 (match_dup 2)))]
3606 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3607 && !logical_const_operand (operands[2], <MODE>mode)
3608 && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3609 {
3610 if (which_alternative == 0)
3611 return rs6000_insn_for_and_mask (<MODE>mode, operands, true);
3612 else
3613 return "#";
3614 }
3615 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3616 [(set (match_dup 0)
3617 (and:GPR (match_dup 1)
3618 (match_dup 2)))
3619 (set (match_dup 3)
3620 (compare:CC (match_dup 0)
3621 (const_int 0)))]
3622 ""
3623 [(set_attr "type" "shift")
3624 (set_attr "dot" "yes")
3625 (set_attr "length" "4,8")])
3626
3627
3628 (define_insn_and_split "*and<mode>3_2insn"
3629 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3630 (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3631 (match_operand:GPR 2 "const_int_operand" "n")))]
3632 "rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3633 && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3634 || logical_const_operand (operands[2], <MODE>mode))"
3635 "#"
3636 "&& 1"
3637 [(pc)]
3638 {
3639 rs6000_emit_2insn_and (<MODE>mode, operands, false, 0);
3640 DONE;
3641 }
3642 [(set_attr "type" "shift")
3643 (set_attr "length" "8")])
3644
3645 (define_insn_and_split "*and<mode>3_2insn_dot"
3646 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3647 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3648 (match_operand:GPR 2 "const_int_operand" "n,n"))
3649 (const_int 0)))
3650 (clobber (match_scratch:GPR 0 "=r,r"))]
3651 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3652 && rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3653 && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3654 || logical_const_operand (operands[2], <MODE>mode))"
3655 "#"
3656 "&& reload_completed"
3657 [(pc)]
3658 {
3659 rs6000_emit_2insn_and (<MODE>mode, operands, false, 1);
3660 DONE;
3661 }
3662 [(set_attr "type" "shift")
3663 (set_attr "dot" "yes")
3664 (set_attr "length" "8,12")])
3665
3666 (define_insn_and_split "*and<mode>3_2insn_dot2"
3667 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3668 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3669 (match_operand:GPR 2 "const_int_operand" "n,n"))
3670 (const_int 0)))
3671 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3672 (and:GPR (match_dup 1)
3673 (match_dup 2)))]
3674 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3675 && rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3676 && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3677 || logical_const_operand (operands[2], <MODE>mode))"
3678 "#"
3679 "&& reload_completed"
3680 [(pc)]
3681 {
3682 rs6000_emit_2insn_and (<MODE>mode, operands, false, 2);
3683 DONE;
3684 }
3685 [(set_attr "type" "shift")
3686 (set_attr "dot" "yes")
3687 (set_attr "length" "8,12")])
3688
3689
3690 (define_expand "<code><mode>3"
3691 [(set (match_operand:SDI 0 "gpc_reg_operand")
3692 (iorxor:SDI (match_operand:SDI 1 "gpc_reg_operand")
3693 (match_operand:SDI 2 "reg_or_cint_operand")))]
3694 ""
3695 {
3696 if (<MODE>mode == DImode && !TARGET_POWERPC64)
3697 {
3698 rs6000_split_logical (operands, <CODE>, false, false, false);
3699 DONE;
3700 }
3701
3702 if (non_logical_cint_operand (operands[2], <MODE>mode))
3703 {
3704 rtx tmp = ((!can_create_pseudo_p ()
3705 || rtx_equal_p (operands[0], operands[1]))
3706 ? operands[0] : gen_reg_rtx (<MODE>mode));
3707
3708 HOST_WIDE_INT value = INTVAL (operands[2]);
3709 HOST_WIDE_INT lo = value & 0xffff;
3710 HOST_WIDE_INT hi = value - lo;
3711
3712 emit_insn (gen_<code><mode>3 (tmp, operands[1], GEN_INT (hi)));
3713 emit_insn (gen_<code><mode>3 (operands[0], tmp, GEN_INT (lo)));
3714 DONE;
3715 }
3716
3717 if (!reg_or_logical_cint_operand (operands[2], <MODE>mode))
3718 operands[2] = force_reg (<MODE>mode, operands[2]);
3719 })
3720
3721 (define_split
3722 [(set (match_operand:GPR 0 "gpc_reg_operand")
3723 (iorxor:GPR (match_operand:GPR 1 "gpc_reg_operand")
3724 (match_operand:GPR 2 "non_logical_cint_operand")))]
3725 ""
3726 [(set (match_dup 3)
3727 (iorxor:GPR (match_dup 1)
3728 (match_dup 4)))
3729 (set (match_dup 0)
3730 (iorxor:GPR (match_dup 3)
3731 (match_dup 5)))]
3732 {
3733 operands[3] = ((!can_create_pseudo_p ()
3734 || rtx_equal_p (operands[0], operands[1]))
3735 ? operands[0] : gen_reg_rtx (<MODE>mode));
3736
3737 HOST_WIDE_INT value = INTVAL (operands[2]);
3738 HOST_WIDE_INT lo = value & 0xffff;
3739 HOST_WIDE_INT hi = value - lo;
3740
3741 operands[4] = GEN_INT (hi);
3742 operands[5] = GEN_INT (lo);
3743 })
3744
3745 (define_insn "*bool<mode>3_imm"
3746 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3747 (match_operator:GPR 3 "boolean_or_operator"
3748 [(match_operand:GPR 1 "gpc_reg_operand" "%r")
3749 (match_operand:GPR 2 "logical_const_operand" "n")]))]
3750 ""
3751 "%q3i%e2 %0,%1,%u2"
3752 [(set_attr "type" "logical")])
3753
3754 (define_insn "*bool<mode>3"
3755 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3756 (match_operator:GPR 3 "boolean_operator"
3757 [(match_operand:GPR 1 "gpc_reg_operand" "r")
3758 (match_operand:GPR 2 "gpc_reg_operand" "r")]))]
3759 ""
3760 "%q3 %0,%1,%2"
3761 [(set_attr "type" "logical")])
3762
3763 (define_insn_and_split "*bool<mode>3_dot"
3764 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3765 (compare:CC (match_operator:GPR 3 "boolean_operator"
3766 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3767 (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
3768 (const_int 0)))
3769 (clobber (match_scratch:GPR 0 "=r,r"))]
3770 "<MODE>mode == Pmode"
3771 "@
3772 %q3. %0,%1,%2
3773 #"
3774 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3775 [(set (match_dup 0)
3776 (match_dup 3))
3777 (set (match_dup 4)
3778 (compare:CC (match_dup 0)
3779 (const_int 0)))]
3780 ""
3781 [(set_attr "type" "logical")
3782 (set_attr "dot" "yes")
3783 (set_attr "length" "4,8")])
3784
3785 (define_insn_and_split "*bool<mode>3_dot2"
3786 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3787 (compare:CC (match_operator:GPR 3 "boolean_operator"
3788 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3789 (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
3790 (const_int 0)))
3791 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3792 (match_dup 3))]
3793 "<MODE>mode == Pmode"
3794 "@
3795 %q3. %0,%1,%2
3796 #"
3797 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3798 [(set (match_dup 0)
3799 (match_dup 3))
3800 (set (match_dup 4)
3801 (compare:CC (match_dup 0)
3802 (const_int 0)))]
3803 ""
3804 [(set_attr "type" "logical")
3805 (set_attr "dot" "yes")
3806 (set_attr "length" "4,8")])
3807
3808
3809 (define_insn "*boolc<mode>3"
3810 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3811 (match_operator:GPR 3 "boolean_operator"
3812 [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))
3813 (match_operand:GPR 1 "gpc_reg_operand" "r")]))]
3814 ""
3815 "%q3 %0,%1,%2"
3816 [(set_attr "type" "logical")])
3817
3818 (define_insn_and_split "*boolc<mode>3_dot"
3819 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3820 (compare:CC (match_operator:GPR 3 "boolean_operator"
3821 [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3822 (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
3823 (const_int 0)))
3824 (clobber (match_scratch:GPR 0 "=r,r"))]
3825 "<MODE>mode == Pmode"
3826 "@
3827 %q3. %0,%1,%2
3828 #"
3829 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3830 [(set (match_dup 0)
3831 (match_dup 3))
3832 (set (match_dup 4)
3833 (compare:CC (match_dup 0)
3834 (const_int 0)))]
3835 ""
3836 [(set_attr "type" "logical")
3837 (set_attr "dot" "yes")
3838 (set_attr "length" "4,8")])
3839
3840 (define_insn_and_split "*boolc<mode>3_dot2"
3841 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3842 (compare:CC (match_operator:GPR 3 "boolean_operator"
3843 [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3844 (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
3845 (const_int 0)))
3846 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3847 (match_dup 3))]
3848 "<MODE>mode == Pmode"
3849 "@
3850 %q3. %0,%1,%2
3851 #"
3852 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3853 [(set (match_dup 0)
3854 (match_dup 3))
3855 (set (match_dup 4)
3856 (compare:CC (match_dup 0)
3857 (const_int 0)))]
3858 ""
3859 [(set_attr "type" "logical")
3860 (set_attr "dot" "yes")
3861 (set_attr "length" "4,8")])
3862
3863
3864 (define_insn "*boolcc<mode>3"
3865 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3866 (match_operator:GPR 3 "boolean_operator"
3867 [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
3868 (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))]))]
3869 ""
3870 "%q3 %0,%1,%2"
3871 [(set_attr "type" "logical")])
3872
3873 (define_insn_and_split "*boolcc<mode>3_dot"
3874 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3875 (compare:CC (match_operator:GPR 3 "boolean_operator"
3876 [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
3877 (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
3878 (const_int 0)))
3879 (clobber (match_scratch:GPR 0 "=r,r"))]
3880 "<MODE>mode == Pmode"
3881 "@
3882 %q3. %0,%1,%2
3883 #"
3884 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3885 [(set (match_dup 0)
3886 (match_dup 3))
3887 (set (match_dup 4)
3888 (compare:CC (match_dup 0)
3889 (const_int 0)))]
3890 ""
3891 [(set_attr "type" "logical")
3892 (set_attr "dot" "yes")
3893 (set_attr "length" "4,8")])
3894
3895 (define_insn_and_split "*boolcc<mode>3_dot2"
3896 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3897 (compare:CC (match_operator:GPR 3 "boolean_operator"
3898 [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
3899 (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
3900 (const_int 0)))
3901 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3902 (match_dup 3))]
3903 "<MODE>mode == Pmode"
3904 "@
3905 %q3. %0,%1,%2
3906 #"
3907 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3908 [(set (match_dup 0)
3909 (match_dup 3))
3910 (set (match_dup 4)
3911 (compare:CC (match_dup 0)
3912 (const_int 0)))]
3913 ""
3914 [(set_attr "type" "logical")
3915 (set_attr "dot" "yes")
3916 (set_attr "length" "4,8")])
3917
3918
3919 ;; TODO: Should have dots of this as well.
3920 (define_insn "*eqv<mode>3"
3921 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3922 (not:GPR (xor:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3923 (match_operand:GPR 2 "gpc_reg_operand" "r"))))]
3924 ""
3925 "eqv %0,%1,%2"
3926 [(set_attr "type" "logical")])
3927 \f
3928 ;; Rotate-and-mask and insert.
3929
3930 (define_insn "*rotl<mode>3_mask"
3931 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3932 (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3933 [(match_operand:GPR 1 "gpc_reg_operand" "r")
3934 (match_operand:SI 2 "reg_or_cint_operand" "rn")])
3935 (match_operand:GPR 3 "const_int_operand" "n")))]
3936 "rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3937 {
3938 return rs6000_insn_for_shift_mask (<MODE>mode, operands, false);
3939 }
3940 [(set_attr "type" "shift")
3941 (set_attr "maybe_var_shift" "yes")])
3942
3943 (define_insn_and_split "*rotl<mode>3_mask_dot"
3944 [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y")
3945 (compare:CC
3946 (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3947 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3948 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")])
3949 (match_operand:GPR 3 "const_int_operand" "n,n"))
3950 (const_int 0)))
3951 (clobber (match_scratch:GPR 0 "=r,r"))]
3952 "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff)
3953 && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3954 {
3955 if (which_alternative == 0)
3956 return rs6000_insn_for_shift_mask (<MODE>mode, operands, true);
3957 else
3958 return "#";
3959 }
3960 "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)"
3961 [(set (match_dup 0)
3962 (and:GPR (match_dup 4)
3963 (match_dup 3)))
3964 (set (match_dup 5)
3965 (compare:CC (match_dup 0)
3966 (const_int 0)))]
3967 ""
3968 [(set_attr "type" "shift")
3969 (set_attr "maybe_var_shift" "yes")
3970 (set_attr "dot" "yes")
3971 (set_attr "length" "4,8")])
3972
3973 (define_insn_and_split "*rotl<mode>3_mask_dot2"
3974 [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y")
3975 (compare:CC
3976 (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3977 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3978 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")])
3979 (match_operand:GPR 3 "const_int_operand" "n,n"))
3980 (const_int 0)))
3981 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3982 (and:GPR (match_dup 4)
3983 (match_dup 3)))]
3984 "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff)
3985 && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3986 {
3987 if (which_alternative == 0)
3988 return rs6000_insn_for_shift_mask (<MODE>mode, operands, true);
3989 else
3990 return "#";
3991 }
3992 "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)"
3993 [(set (match_dup 0)
3994 (and:GPR (match_dup 4)
3995 (match_dup 3)))
3996 (set (match_dup 5)
3997 (compare:CC (match_dup 0)
3998 (const_int 0)))]
3999 ""
4000 [(set_attr "type" "shift")
4001 (set_attr "maybe_var_shift" "yes")
4002 (set_attr "dot" "yes")
4003 (set_attr "length" "4,8")])
4004
4005 ; Special case for less-than-0. We can do it with just one machine
4006 ; instruction, but the generic optimizers do not realise it is cheap.
4007 (define_insn "*lt0_<mode>di"
4008 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4009 (lt:GPR (match_operand:DI 1 "gpc_reg_operand" "r")
4010 (const_int 0)))]
4011 "TARGET_POWERPC64"
4012 "srdi %0,%1,63"
4013 [(set_attr "type" "shift")])
4014
4015 (define_insn "*lt0_<mode>si"
4016 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4017 (lt:GPR (match_operand:SI 1 "gpc_reg_operand" "r")
4018 (const_int 0)))]
4019 ""
4020 "rlwinm %0,%1,1,31,31"
4021 [(set_attr "type" "shift")])
4022
4023
4024
4025 ; Two forms for insert (the two arms of the IOR are not canonicalized,
4026 ; both are an AND so are the same precedence).
4027 (define_insn "*rotl<mode>3_insert"
4028 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4029 (ior:GPR (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
4030 [(match_operand:GPR 1 "gpc_reg_operand" "r")
4031 (match_operand:SI 2 "const_int_operand" "n")])
4032 (match_operand:GPR 3 "const_int_operand" "n"))
4033 (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0")
4034 (match_operand:GPR 6 "const_int_operand" "n"))))]
4035 "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode)
4036 && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0"
4037 {
4038 return rs6000_insn_for_insert_mask (<MODE>mode, operands, false);
4039 }
4040 [(set_attr "type" "insert")])
4041 ; FIXME: this needs an attr "size", so that the scheduler can see the
4042 ; difference between rlwimi and rldimi. We also might want dot forms,
4043 ; but not for rlwimi on POWER4 and similar processors.
4044
4045 (define_insn "*rotl<mode>3_insert_2"
4046 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4047 (ior:GPR (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0")
4048 (match_operand:GPR 6 "const_int_operand" "n"))
4049 (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
4050 [(match_operand:GPR 1 "gpc_reg_operand" "r")
4051 (match_operand:SI 2 "const_int_operand" "n")])
4052 (match_operand:GPR 3 "const_int_operand" "n"))))]
4053 "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode)
4054 && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0"
4055 {
4056 return rs6000_insn_for_insert_mask (<MODE>mode, operands, false);
4057 }
4058 [(set_attr "type" "insert")])
4059
4060 ; There are also some forms without one of the ANDs.
4061 (define_insn "*rotl<mode>3_insert_3"
4062 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4063 (ior:GPR (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0")
4064 (match_operand:GPR 4 "const_int_operand" "n"))
4065 (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4066 (match_operand:SI 2 "const_int_operand" "n"))))]
4067 "INTVAL (operands[2]) == exact_log2 (UINTVAL (operands[4]) + 1)"
4068 {
4069 if (<MODE>mode == SImode)
4070 return "rlwimi %0,%1,%h2,0,31-%h2";
4071 else
4072 return "rldimi %0,%1,%H2,0";
4073 }
4074 [(set_attr "type" "insert")])
4075
4076 (define_insn "*rotl<mode>3_insert_4"
4077 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4078 (ior:GPR (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0")
4079 (match_operand:GPR 4 "const_int_operand" "n"))
4080 (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4081 (match_operand:SI 2 "const_int_operand" "n"))))]
4082 "<MODE>mode == SImode &&
4083 GET_MODE_PRECISION (<MODE>mode)
4084 == INTVAL (operands[2]) + exact_log2 (-UINTVAL (operands[4]))"
4085 {
4086 operands[2] = GEN_INT (GET_MODE_PRECISION (<MODE>mode)
4087 - INTVAL (operands[2]));
4088 if (<MODE>mode == SImode)
4089 return "rlwimi %0,%1,%h2,32-%h2,31";
4090 else
4091 return "rldimi %0,%1,%H2,64-%H2";
4092 }
4093 [(set_attr "type" "insert")])
4094
4095 (define_insn "*rotlsi3_insert_5"
4096 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
4097 (ior:SI (and:SI (match_operand:SI 1 "gpc_reg_operand" "0,r")
4098 (match_operand:SI 2 "const_int_operand" "n,n"))
4099 (and:SI (match_operand:SI 3 "gpc_reg_operand" "r,0")
4100 (match_operand:SI 4 "const_int_operand" "n,n"))))]
4101 "rs6000_is_valid_mask (operands[2], NULL, NULL, SImode)
4102 && UINTVAL (operands[2]) != 0 && UINTVAL (operands[4]) != 0
4103 && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
4104 "@
4105 rlwimi %0,%3,0,%4
4106 rlwimi %0,%1,0,%2"
4107 [(set_attr "type" "insert")])
4108
4109 (define_insn "*rotldi3_insert_6"
4110 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4111 (ior:DI (and:DI (match_operand:DI 1 "gpc_reg_operand" "0")
4112 (match_operand:DI 2 "const_int_operand" "n"))
4113 (and:DI (match_operand:DI 3 "gpc_reg_operand" "r")
4114 (match_operand:DI 4 "const_int_operand" "n"))))]
4115 "exact_log2 (-UINTVAL (operands[2])) > 0
4116 && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
4117 {
4118 operands[5] = GEN_INT (64 - exact_log2 (-UINTVAL (operands[2])));
4119 return "rldimi %0,%3,0,%5";
4120 }
4121 [(set_attr "type" "insert")
4122 (set_attr "size" "64")])
4123
4124 (define_insn "*rotldi3_insert_7"
4125 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4126 (ior:DI (and:DI (match_operand:DI 3 "gpc_reg_operand" "r")
4127 (match_operand:DI 4 "const_int_operand" "n"))
4128 (and:DI (match_operand:DI 1 "gpc_reg_operand" "0")
4129 (match_operand:DI 2 "const_int_operand" "n"))))]
4130 "exact_log2 (-UINTVAL (operands[2])) > 0
4131 && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
4132 {
4133 operands[5] = GEN_INT (64 - exact_log2 (-UINTVAL (operands[2])));
4134 return "rldimi %0,%3,0,%5";
4135 }
4136 [(set_attr "type" "insert")
4137 (set_attr "size" "64")])
4138
4139
4140 ; This handles the important case of multiple-precision shifts. There is
4141 ; no canonicalization rule for ASHIFT vs. LSHIFTRT, so two patterns.
4142 (define_split
4143 [(set (match_operand:GPR 0 "gpc_reg_operand")
4144 (ior:GPR (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand")
4145 (match_operand:SI 3 "const_int_operand"))
4146 (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand")
4147 (match_operand:SI 4 "const_int_operand"))))]
4148 "can_create_pseudo_p ()
4149 && INTVAL (operands[3]) + INTVAL (operands[4])
4150 >= GET_MODE_PRECISION (<MODE>mode)"
4151 [(set (match_dup 5)
4152 (lshiftrt:GPR (match_dup 2)
4153 (match_dup 4)))
4154 (set (match_dup 0)
4155 (ior:GPR (and:GPR (match_dup 5)
4156 (match_dup 6))
4157 (ashift:GPR (match_dup 1)
4158 (match_dup 3))))]
4159 {
4160 unsigned HOST_WIDE_INT mask = 1;
4161 mask = (mask << INTVAL (operands[3])) - 1;
4162 operands[5] = gen_reg_rtx (<MODE>mode);
4163 operands[6] = GEN_INT (mask);
4164 })
4165
4166 (define_split
4167 [(set (match_operand:GPR 0 "gpc_reg_operand")
4168 (ior:GPR (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand")
4169 (match_operand:SI 4 "const_int_operand"))
4170 (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand")
4171 (match_operand:SI 3 "const_int_operand"))))]
4172 "can_create_pseudo_p ()
4173 && INTVAL (operands[3]) + INTVAL (operands[4])
4174 >= GET_MODE_PRECISION (<MODE>mode)"
4175 [(set (match_dup 5)
4176 (lshiftrt:GPR (match_dup 2)
4177 (match_dup 4)))
4178 (set (match_dup 0)
4179 (ior:GPR (and:GPR (match_dup 5)
4180 (match_dup 6))
4181 (ashift:GPR (match_dup 1)
4182 (match_dup 3))))]
4183 {
4184 unsigned HOST_WIDE_INT mask = 1;
4185 mask = (mask << INTVAL (operands[3])) - 1;
4186 operands[5] = gen_reg_rtx (<MODE>mode);
4187 operands[6] = GEN_INT (mask);
4188 })
4189
4190
4191 ; Another important case is setting some bits to 1; we can do that with
4192 ; an insert instruction, in many cases.
4193 (define_insn_and_split "*ior<mode>_mask"
4194 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4195 (ior:GPR (match_operand:GPR 1 "gpc_reg_operand" "0")
4196 (match_operand:GPR 2 "const_int_operand" "n")))
4197 (clobber (match_scratch:GPR 3 "=r"))]
4198 "!logical_const_operand (operands[2], <MODE>mode)
4199 && rs6000_is_valid_mask (operands[2], NULL, NULL, <MODE>mode)"
4200 "#"
4201 "&& 1"
4202 [(set (match_dup 3)
4203 (const_int -1))
4204 (set (match_dup 0)
4205 (ior:GPR (and:GPR (rotate:GPR (match_dup 3)
4206 (match_dup 4))
4207 (match_dup 2))
4208 (and:GPR (match_dup 1)
4209 (match_dup 5))))]
4210 {
4211 int nb, ne;
4212 rs6000_is_valid_mask (operands[2], &nb, &ne, <MODE>mode);
4213 if (GET_CODE (operands[3]) == SCRATCH)
4214 operands[3] = gen_reg_rtx (<MODE>mode);
4215 operands[4] = GEN_INT (ne);
4216 operands[5] = GEN_INT (~UINTVAL (operands[2]));
4217 }
4218 [(set_attr "type" "two")
4219 (set_attr "length" "8")])
4220
4221
4222 ; Yet another case is an rldimi with the second value coming from memory.
4223 ; The zero_extend that should become part of the rldimi is merged into the
4224 ; load from memory instead. Split things properly again.
4225 (define_split
4226 [(set (match_operand:DI 0 "gpc_reg_operand")
4227 (ior:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand")
4228 (match_operand:SI 2 "const_int_operand"))
4229 (zero_extend:DI (match_operand:QHSI 3 "memory_operand"))))]
4230 "INTVAL (operands[2]) == <bits>"
4231 [(set (match_dup 4)
4232 (zero_extend:DI (match_dup 3)))
4233 (set (match_dup 0)
4234 (ior:DI (and:DI (match_dup 4)
4235 (match_dup 5))
4236 (ashift:DI (match_dup 1)
4237 (match_dup 2))))]
4238 {
4239 operands[4] = gen_reg_rtx (DImode);
4240 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << <bits>) - 1);
4241 })
4242
4243 ; rlwimi, too.
4244 (define_split
4245 [(set (match_operand:SI 0 "gpc_reg_operand")
4246 (ior:SI (ashift:SI (match_operand:SI 1 "gpc_reg_operand")
4247 (match_operand:SI 2 "const_int_operand"))
4248 (zero_extend:SI (match_operand:QHI 3 "memory_operand"))))]
4249 "INTVAL (operands[2]) == <bits>"
4250 [(set (match_dup 4)
4251 (zero_extend:SI (match_dup 3)))
4252 (set (match_dup 0)
4253 (ior:SI (and:SI (match_dup 4)
4254 (match_dup 5))
4255 (ashift:SI (match_dup 1)
4256 (match_dup 2))))]
4257 {
4258 operands[4] = gen_reg_rtx (SImode);
4259 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << <bits>) - 1);
4260 })
4261
4262
4263 ;; Now the simple shifts.
4264
4265 (define_insn "rotl<mode>3"
4266 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4267 (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4268 (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4269 ""
4270 "rotl<wd>%I2 %0,%1,%<hH>2"
4271 [(set_attr "type" "shift")
4272 (set_attr "maybe_var_shift" "yes")])
4273
4274 (define_insn "*rotlsi3_64"
4275 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4276 (zero_extend:DI
4277 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4278 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4279 "TARGET_POWERPC64"
4280 "rotlw%I2 %0,%1,%h2"
4281 [(set_attr "type" "shift")
4282 (set_attr "maybe_var_shift" "yes")])
4283
4284 (define_insn_and_split "*rotl<mode>3_dot"
4285 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4286 (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4287 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4288 (const_int 0)))
4289 (clobber (match_scratch:GPR 0 "=r,r"))]
4290 "<MODE>mode == Pmode"
4291 "@
4292 rotl<wd>%I2. %0,%1,%<hH>2
4293 #"
4294 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4295 [(set (match_dup 0)
4296 (rotate:GPR (match_dup 1)
4297 (match_dup 2)))
4298 (set (match_dup 3)
4299 (compare:CC (match_dup 0)
4300 (const_int 0)))]
4301 ""
4302 [(set_attr "type" "shift")
4303 (set_attr "maybe_var_shift" "yes")
4304 (set_attr "dot" "yes")
4305 (set_attr "length" "4,8")])
4306
4307 (define_insn_and_split "*rotl<mode>3_dot2"
4308 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4309 (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4310 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4311 (const_int 0)))
4312 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4313 (rotate:GPR (match_dup 1)
4314 (match_dup 2)))]
4315 "<MODE>mode == Pmode"
4316 "@
4317 rotl<wd>%I2. %0,%1,%<hH>2
4318 #"
4319 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4320 [(set (match_dup 0)
4321 (rotate:GPR (match_dup 1)
4322 (match_dup 2)))
4323 (set (match_dup 3)
4324 (compare:CC (match_dup 0)
4325 (const_int 0)))]
4326 ""
4327 [(set_attr "type" "shift")
4328 (set_attr "maybe_var_shift" "yes")
4329 (set_attr "dot" "yes")
4330 (set_attr "length" "4,8")])
4331
4332
4333 (define_insn "ashl<mode>3"
4334 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4335 (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4336 (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4337 ""
4338 "sl<wd>%I2 %0,%1,%<hH>2"
4339 [(set_attr "type" "shift")
4340 (set_attr "maybe_var_shift" "yes")])
4341
4342 (define_insn "*ashlsi3_64"
4343 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4344 (zero_extend:DI
4345 (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4346 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4347 "TARGET_POWERPC64"
4348 "slw%I2 %0,%1,%h2"
4349 [(set_attr "type" "shift")
4350 (set_attr "maybe_var_shift" "yes")])
4351
4352 (define_insn_and_split "*ashl<mode>3_dot"
4353 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4354 (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4355 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4356 (const_int 0)))
4357 (clobber (match_scratch:GPR 0 "=r,r"))]
4358 "<MODE>mode == Pmode"
4359 "@
4360 sl<wd>%I2. %0,%1,%<hH>2
4361 #"
4362 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4363 [(set (match_dup 0)
4364 (ashift:GPR (match_dup 1)
4365 (match_dup 2)))
4366 (set (match_dup 3)
4367 (compare:CC (match_dup 0)
4368 (const_int 0)))]
4369 ""
4370 [(set_attr "type" "shift")
4371 (set_attr "maybe_var_shift" "yes")
4372 (set_attr "dot" "yes")
4373 (set_attr "length" "4,8")])
4374
4375 (define_insn_and_split "*ashl<mode>3_dot2"
4376 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4377 (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4378 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4379 (const_int 0)))
4380 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4381 (ashift:GPR (match_dup 1)
4382 (match_dup 2)))]
4383 "<MODE>mode == Pmode"
4384 "@
4385 sl<wd>%I2. %0,%1,%<hH>2
4386 #"
4387 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4388 [(set (match_dup 0)
4389 (ashift:GPR (match_dup 1)
4390 (match_dup 2)))
4391 (set (match_dup 3)
4392 (compare:CC (match_dup 0)
4393 (const_int 0)))]
4394 ""
4395 [(set_attr "type" "shift")
4396 (set_attr "maybe_var_shift" "yes")
4397 (set_attr "dot" "yes")
4398 (set_attr "length" "4,8")])
4399
4400 ;; Pretend we have a memory form of extswsli until register allocation is done
4401 ;; so that we use LWZ to load the value from memory, instead of LWA.
4402 (define_insn_and_split "ashdi3_extswsli"
4403 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
4404 (ashift:DI
4405 (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,m"))
4406 (match_operand:DI 2 "u6bit_cint_operand" "n,n")))]
4407 "TARGET_EXTSWSLI"
4408 "@
4409 extswsli %0,%1,%2
4410 #"
4411 "&& reload_completed && MEM_P (operands[1])"
4412 [(set (match_dup 3)
4413 (match_dup 1))
4414 (set (match_dup 0)
4415 (ashift:DI (sign_extend:DI (match_dup 3))
4416 (match_dup 2)))]
4417 {
4418 operands[3] = gen_lowpart (SImode, operands[0]);
4419 }
4420 [(set_attr "type" "shift")
4421 (set_attr "maybe_var_shift" "no")])
4422
4423
4424 (define_insn_and_split "ashdi3_extswsli_dot"
4425 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y")
4426 (compare:CC
4427 (ashift:DI
4428 (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m"))
4429 (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n"))
4430 (const_int 0)))
4431 (clobber (match_scratch:DI 0 "=r,r,r,r"))]
4432 "TARGET_EXTSWSLI"
4433 "@
4434 extswsli. %0,%1,%2
4435 #
4436 #
4437 #"
4438 "&& reload_completed
4439 && (cc_reg_not_cr0_operand (operands[3], CCmode)
4440 || memory_operand (operands[1], SImode))"
4441 [(pc)]
4442 {
4443 rtx dest = operands[0];
4444 rtx src = operands[1];
4445 rtx shift = operands[2];
4446 rtx cr = operands[3];
4447 rtx src2;
4448
4449 if (!MEM_P (src))
4450 src2 = src;
4451 else
4452 {
4453 src2 = gen_lowpart (SImode, dest);
4454 emit_move_insn (src2, src);
4455 }
4456
4457 if (REGNO (cr) == CR0_REGNO)
4458 {
4459 emit_insn (gen_ashdi3_extswsli_dot2 (dest, src2, shift, cr));
4460 DONE;
4461 }
4462
4463 emit_insn (gen_ashdi3_extswsli (dest, src2, shift));
4464 emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx)));
4465 DONE;
4466 }
4467 [(set_attr "type" "shift")
4468 (set_attr "maybe_var_shift" "no")
4469 (set_attr "dot" "yes")
4470 (set_attr "length" "4,8,8,12")])
4471
4472 (define_insn_and_split "ashdi3_extswsli_dot2"
4473 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y")
4474 (compare:CC
4475 (ashift:DI
4476 (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m"))
4477 (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n"))
4478 (const_int 0)))
4479 (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r")
4480 (ashift:DI (sign_extend:DI (match_dup 1))
4481 (match_dup 2)))]
4482 "TARGET_EXTSWSLI"
4483 "@
4484 extswsli. %0,%1,%2
4485 #
4486 #
4487 #"
4488 "&& reload_completed
4489 && (cc_reg_not_cr0_operand (operands[3], CCmode)
4490 || memory_operand (operands[1], SImode))"
4491 [(pc)]
4492 {
4493 rtx dest = operands[0];
4494 rtx src = operands[1];
4495 rtx shift = operands[2];
4496 rtx cr = operands[3];
4497 rtx src2;
4498
4499 if (!MEM_P (src))
4500 src2 = src;
4501 else
4502 {
4503 src2 = gen_lowpart (SImode, dest);
4504 emit_move_insn (src2, src);
4505 }
4506
4507 if (REGNO (cr) == CR0_REGNO)
4508 {
4509 emit_insn (gen_ashdi3_extswsli_dot2 (dest, src2, shift, cr));
4510 DONE;
4511 }
4512
4513 emit_insn (gen_ashdi3_extswsli (dest, src2, shift));
4514 emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx)));
4515 DONE;
4516 }
4517 [(set_attr "type" "shift")
4518 (set_attr "maybe_var_shift" "no")
4519 (set_attr "dot" "yes")
4520 (set_attr "length" "4,8,8,12")])
4521
4522 (define_insn "lshr<mode>3"
4523 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4524 (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4525 (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4526 ""
4527 "sr<wd>%I2 %0,%1,%<hH>2"
4528 [(set_attr "type" "shift")
4529 (set_attr "maybe_var_shift" "yes")])
4530
4531 (define_insn "*lshrsi3_64"
4532 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4533 (zero_extend:DI
4534 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4535 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4536 "TARGET_POWERPC64"
4537 "srw%I2 %0,%1,%h2"
4538 [(set_attr "type" "shift")
4539 (set_attr "maybe_var_shift" "yes")])
4540
4541 (define_insn_and_split "*lshr<mode>3_dot"
4542 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4543 (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4544 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4545 (const_int 0)))
4546 (clobber (match_scratch:GPR 0 "=r,r"))]
4547 "<MODE>mode == Pmode"
4548 "@
4549 sr<wd>%I2. %0,%1,%<hH>2
4550 #"
4551 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4552 [(set (match_dup 0)
4553 (lshiftrt:GPR (match_dup 1)
4554 (match_dup 2)))
4555 (set (match_dup 3)
4556 (compare:CC (match_dup 0)
4557 (const_int 0)))]
4558 ""
4559 [(set_attr "type" "shift")
4560 (set_attr "maybe_var_shift" "yes")
4561 (set_attr "dot" "yes")
4562 (set_attr "length" "4,8")])
4563
4564 (define_insn_and_split "*lshr<mode>3_dot2"
4565 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4566 (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4567 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4568 (const_int 0)))
4569 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4570 (lshiftrt:GPR (match_dup 1)
4571 (match_dup 2)))]
4572 "<MODE>mode == Pmode"
4573 "@
4574 sr<wd>%I2. %0,%1,%<hH>2
4575 #"
4576 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4577 [(set (match_dup 0)
4578 (lshiftrt:GPR (match_dup 1)
4579 (match_dup 2)))
4580 (set (match_dup 3)
4581 (compare:CC (match_dup 0)
4582 (const_int 0)))]
4583 ""
4584 [(set_attr "type" "shift")
4585 (set_attr "maybe_var_shift" "yes")
4586 (set_attr "dot" "yes")
4587 (set_attr "length" "4,8")])
4588
4589
4590 (define_insn "ashr<mode>3"
4591 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4592 (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4593 (match_operand:SI 2 "reg_or_cint_operand" "rn")))
4594 (clobber (reg:GPR CA_REGNO))]
4595 ""
4596 "sra<wd>%I2 %0,%1,%<hH>2"
4597 [(set_attr "type" "shift")
4598 (set_attr "maybe_var_shift" "yes")])
4599
4600 (define_insn "*ashrsi3_64"
4601 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4602 (sign_extend:DI
4603 (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4604 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))
4605 (clobber (reg:SI CA_REGNO))]
4606 "TARGET_POWERPC64"
4607 "sraw%I2 %0,%1,%h2"
4608 [(set_attr "type" "shift")
4609 (set_attr "maybe_var_shift" "yes")])
4610
4611 (define_insn_and_split "*ashr<mode>3_dot"
4612 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4613 (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4614 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4615 (const_int 0)))
4616 (clobber (match_scratch:GPR 0 "=r,r"))
4617 (clobber (reg:GPR CA_REGNO))]
4618 "<MODE>mode == Pmode"
4619 "@
4620 sra<wd>%I2. %0,%1,%<hH>2
4621 #"
4622 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4623 [(parallel [(set (match_dup 0)
4624 (ashiftrt:GPR (match_dup 1)
4625 (match_dup 2)))
4626 (clobber (reg:GPR CA_REGNO))])
4627 (set (match_dup 3)
4628 (compare:CC (match_dup 0)
4629 (const_int 0)))]
4630 ""
4631 [(set_attr "type" "shift")
4632 (set_attr "maybe_var_shift" "yes")
4633 (set_attr "dot" "yes")
4634 (set_attr "length" "4,8")])
4635
4636 (define_insn_and_split "*ashr<mode>3_dot2"
4637 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4638 (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4639 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4640 (const_int 0)))
4641 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4642 (ashiftrt:GPR (match_dup 1)
4643 (match_dup 2)))
4644 (clobber (reg:GPR CA_REGNO))]
4645 "<MODE>mode == Pmode"
4646 "@
4647 sra<wd>%I2. %0,%1,%<hH>2
4648 #"
4649 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4650 [(parallel [(set (match_dup 0)
4651 (ashiftrt:GPR (match_dup 1)
4652 (match_dup 2)))
4653 (clobber (reg:GPR CA_REGNO))])
4654 (set (match_dup 3)
4655 (compare:CC (match_dup 0)
4656 (const_int 0)))]
4657 ""
4658 [(set_attr "type" "shift")
4659 (set_attr "maybe_var_shift" "yes")
4660 (set_attr "dot" "yes")
4661 (set_attr "length" "4,8")])
4662 \f
4663 ;; Builtins to replace a division to generate FRE reciprocal estimate
4664 ;; instructions and the necessary fixup instructions
4665 (define_expand "recip<mode>3"
4666 [(match_operand:RECIPF 0 "gpc_reg_operand")
4667 (match_operand:RECIPF 1 "gpc_reg_operand")
4668 (match_operand:RECIPF 2 "gpc_reg_operand")]
4669 "RS6000_RECIP_HAVE_RE_P (<MODE>mode)"
4670 {
4671 rs6000_emit_swdiv (operands[0], operands[1], operands[2], false);
4672 DONE;
4673 })
4674
4675 ;; Split to create division from FRE/FRES/etc. and fixup instead of the normal
4676 ;; hardware division. This is only done before register allocation and with
4677 ;; -ffast-math. This must appear before the divsf3/divdf3 insns.
4678 ;; We used to also check optimize_insn_for_speed_p () but problems with guessed
4679 ;; frequencies (pr68212/pr77536) yields that unreliable so it was removed.
4680 (define_split
4681 [(set (match_operand:RECIPF 0 "gpc_reg_operand")
4682 (div:RECIPF (match_operand 1 "gpc_reg_operand")
4683 (match_operand 2 "gpc_reg_operand")))]
4684 "RS6000_RECIP_AUTO_RE_P (<MODE>mode)
4685 && can_create_pseudo_p () && flag_finite_math_only
4686 && !flag_trapping_math && flag_reciprocal_math"
4687 [(const_int 0)]
4688 {
4689 rs6000_emit_swdiv (operands[0], operands[1], operands[2], true);
4690 DONE;
4691 })
4692
4693 ;; Builtins to replace 1/sqrt(x) with instructions using RSQRTE and the
4694 ;; appropriate fixup.
4695 (define_expand "rsqrt<mode>2"
4696 [(match_operand:RECIPF 0 "gpc_reg_operand")
4697 (match_operand:RECIPF 1 "gpc_reg_operand")]
4698 "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4699 {
4700 rs6000_emit_swsqrt (operands[0], operands[1], 1);
4701 DONE;
4702 })
4703 \f
4704 ;; Floating-point insns, excluding normal data motion. We combine the SF/DF
4705 ;; modes here, and also add in conditional vsx/power8-vector support to access
4706 ;; values in the traditional Altivec registers if the appropriate
4707 ;; -mupper-regs-{df,sf} option is enabled.
4708
4709 (define_expand "abs<mode>2"
4710 [(set (match_operand:SFDF 0 "gpc_reg_operand")
4711 (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))]
4712 "TARGET_HARD_FLOAT"
4713 "")
4714
4715 (define_insn "*abs<mode>2_fpr"
4716 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4717 (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4718 "TARGET_HARD_FLOAT"
4719 "@
4720 fabs %0,%1
4721 xsabsdp %x0,%x1"
4722 [(set_attr "type" "fpsimple")])
4723
4724 (define_insn "*nabs<mode>2_fpr"
4725 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4726 (neg:SFDF
4727 (abs:SFDF
4728 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))))]
4729 "TARGET_HARD_FLOAT"
4730 "@
4731 fnabs %0,%1
4732 xsnabsdp %x0,%x1"
4733 [(set_attr "type" "fpsimple")])
4734
4735 (define_expand "neg<mode>2"
4736 [(set (match_operand:SFDF 0 "gpc_reg_operand")
4737 (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))]
4738 "TARGET_HARD_FLOAT"
4739 "")
4740
4741 (define_insn "*neg<mode>2_fpr"
4742 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4743 (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4744 "TARGET_HARD_FLOAT"
4745 "@
4746 fneg %0,%1
4747 xsnegdp %x0,%x1"
4748 [(set_attr "type" "fpsimple")])
4749
4750 (define_expand "add<mode>3"
4751 [(set (match_operand:SFDF 0 "gpc_reg_operand")
4752 (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4753 (match_operand:SFDF 2 "gpc_reg_operand")))]
4754 "TARGET_HARD_FLOAT"
4755 "")
4756
4757 (define_insn "*add<mode>3_fpr"
4758 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa")
4759 (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,wa")
4760 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa")))]
4761 "TARGET_HARD_FLOAT"
4762 "@
4763 fadd<s> %0,%1,%2
4764 xsadd<sd>p %x0,%x1,%x2"
4765 [(set_attr "type" "fp")
4766 (set_attr "isa" "*,<Fisa>")])
4767
4768 (define_expand "sub<mode>3"
4769 [(set (match_operand:SFDF 0 "gpc_reg_operand")
4770 (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4771 (match_operand:SFDF 2 "gpc_reg_operand")))]
4772 "TARGET_HARD_FLOAT"
4773 "")
4774
4775 (define_insn "*sub<mode>3_fpr"
4776 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa")
4777 (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa")
4778 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa")))]
4779 "TARGET_HARD_FLOAT"
4780 "@
4781 fsub<s> %0,%1,%2
4782 xssub<sd>p %x0,%x1,%x2"
4783 [(set_attr "type" "fp")
4784 (set_attr "isa" "*,<Fisa>")])
4785
4786 (define_expand "mul<mode>3"
4787 [(set (match_operand:SFDF 0 "gpc_reg_operand")
4788 (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4789 (match_operand:SFDF 2 "gpc_reg_operand")))]
4790 "TARGET_HARD_FLOAT"
4791 "")
4792
4793 (define_insn "*mul<mode>3_fpr"
4794 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa")
4795 (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,wa")
4796 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa")))]
4797 "TARGET_HARD_FLOAT"
4798 "@
4799 fmul<s> %0,%1,%2
4800 xsmul<sd>p %x0,%x1,%x2"
4801 [(set_attr "type" "dmul")
4802 (set_attr "isa" "*,<Fisa>")])
4803
4804 (define_expand "div<mode>3"
4805 [(set (match_operand:SFDF 0 "gpc_reg_operand")
4806 (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4807 (match_operand:SFDF 2 "gpc_reg_operand")))]
4808 "TARGET_HARD_FLOAT"
4809 {
4810 if (RS6000_RECIP_AUTO_RE_P (<MODE>mode)
4811 && can_create_pseudo_p () && flag_finite_math_only
4812 && !flag_trapping_math && flag_reciprocal_math)
4813 {
4814 rs6000_emit_swdiv (operands[0], operands[1], operands[2], true);
4815 DONE;
4816 }
4817 })
4818
4819 (define_insn "*div<mode>3_fpr"
4820 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa")
4821 (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa")
4822 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa")))]
4823 "TARGET_HARD_FLOAT"
4824 "@
4825 fdiv<s> %0,%1,%2
4826 xsdiv<sd>p %x0,%x1,%x2"
4827 [(set_attr "type" "<sd>div")
4828 (set_attr "isa" "*,<Fisa>")])
4829
4830 (define_insn "*sqrt<mode>2_internal"
4831 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa")
4832 (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa")))]
4833 "TARGET_HARD_FLOAT && TARGET_PPC_GPOPT"
4834 "@
4835 fsqrt<s> %0,%1
4836 xssqrt<sd>p %x0,%x1"
4837 [(set_attr "type" "<sd>sqrt")
4838 (set_attr "isa" "*,<Fisa>")])
4839
4840 (define_expand "sqrt<mode>2"
4841 [(set (match_operand:SFDF 0 "gpc_reg_operand")
4842 (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))]
4843 "TARGET_HARD_FLOAT && TARGET_PPC_GPOPT"
4844 {
4845 if (<MODE>mode == SFmode
4846 && TARGET_RECIP_PRECISION
4847 && RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)
4848 && !optimize_function_for_size_p (cfun)
4849 && flag_finite_math_only && !flag_trapping_math
4850 && flag_unsafe_math_optimizations)
4851 {
4852 rs6000_emit_swsqrt (operands[0], operands[1], 0);
4853 DONE;
4854 }
4855 })
4856
4857 ;; Floating point reciprocal approximation
4858 (define_insn "fre<sd>"
4859 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa")
4860 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa")]
4861 UNSPEC_FRES))]
4862 "TARGET_<FFRE>"
4863 "@
4864 fre<s> %0,%1
4865 xsre<sd>p %x0,%x1"
4866 [(set_attr "type" "fp")
4867 (set_attr "isa" "*,<Fisa>")])
4868
4869 (define_insn "*rsqrt<mode>2"
4870 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa")
4871 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa")]
4872 UNSPEC_RSQRT))]
4873 "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4874 "@
4875 frsqrte<s> %0,%1
4876 xsrsqrte<sd>p %x0,%x1"
4877 [(set_attr "type" "fp")
4878 (set_attr "isa" "*,<Fisa>")])
4879
4880 ;; Floating point comparisons
4881 (define_insn "*cmp<mode>_fpr"
4882 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y,y")
4883 (compare:CCFP (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa")
4884 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa")))]
4885 "TARGET_HARD_FLOAT"
4886 "@
4887 fcmpu %0,%1,%2
4888 xscmpudp %0,%x1,%x2"
4889 [(set_attr "type" "fpcompare")
4890 (set_attr "isa" "*,<Fisa>")])
4891
4892 ;; Floating point conversions
4893 (define_expand "extendsfdf2"
4894 [(set (match_operand:DF 0 "gpc_reg_operand")
4895 (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand")))]
4896 "TARGET_HARD_FLOAT"
4897 {
4898 if (HONOR_SNANS (SFmode))
4899 operands[1] = force_reg (SFmode, operands[1]);
4900 })
4901
4902 (define_insn_and_split "*extendsfdf2_fpr"
4903 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d,d,wa,?wa,wa,v")
4904 (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand" "0,f,m,0,wa,Z,wY")))]
4905 "TARGET_HARD_FLOAT && !HONOR_SNANS (SFmode)"
4906 "@
4907 #
4908 fmr %0,%1
4909 lfs%U1%X1 %0,%1
4910 #
4911 xscpsgndp %x0,%x1,%x1
4912 lxsspx %x0,%y1
4913 lxssp %0,%1"
4914 "&& reload_completed && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1])"
4915 [(const_int 0)]
4916 {
4917 emit_note (NOTE_INSN_DELETED);
4918 DONE;
4919 }
4920 [(set_attr "type" "fp,fpsimple,fpload,fp,fpsimple,fpload,fpload")
4921 (set_attr "isa" "*,*,*,*,p8v,p8v,p9v")])
4922
4923 (define_insn "*extendsfdf2_snan"
4924 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa")
4925 (float_extend:DF (match_operand:SF 1 "gpc_reg_operand" "f,wa")))]
4926 "TARGET_HARD_FLOAT && HONOR_SNANS (SFmode)"
4927 "@
4928 frsp %0,%1
4929 xsrsp %x0,%x1"
4930 [(set_attr "type" "fp")
4931 (set_attr "isa" "*,p8v")])
4932
4933 (define_expand "truncdfsf2"
4934 [(set (match_operand:SF 0 "gpc_reg_operand")
4935 (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand")))]
4936 "TARGET_HARD_FLOAT"
4937 "")
4938
4939 (define_insn "*truncdfsf2_fpr"
4940 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wa")
4941 (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "d,wa")))]
4942 "TARGET_HARD_FLOAT"
4943 "@
4944 frsp %0,%1
4945 xsrsp %x0,%x1"
4946 [(set_attr "type" "fp")
4947 (set_attr "isa" "*,p8v")])
4948
4949 ;; This expander is here to avoid FLOAT_WORDS_BIGENDIAN tests in
4950 ;; builtins.c and optabs.c that are not correct for IBM long double
4951 ;; when little-endian.
4952 (define_expand "signbit<mode>2"
4953 [(set (match_dup 2)
4954 (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand")))
4955 (set (match_dup 3)
4956 (subreg:DI (match_dup 2) 0))
4957 (set (match_dup 4)
4958 (match_dup 5))
4959 (set (match_operand:SI 0 "gpc_reg_operand")
4960 (match_dup 6))]
4961 "TARGET_HARD_FLOAT
4962 && (!FLOAT128_IEEE_P (<MODE>mode)
4963 || (TARGET_POWERPC64 && TARGET_DIRECT_MOVE))"
4964 {
4965 if (FLOAT128_IEEE_P (<MODE>mode))
4966 {
4967 rtx dest = operands[0];
4968 rtx src = operands[1];
4969 rtx tmp = gen_reg_rtx (DImode);
4970 rtx dest_di = gen_lowpart (DImode, dest);
4971
4972 emit_insn (gen_signbit2_dm (<MODE>mode, tmp, src));
4973 emit_insn (gen_lshrdi3 (dest_di, tmp, GEN_INT (63)));
4974 DONE;
4975 }
4976 operands[2] = gen_reg_rtx (DFmode);
4977 operands[3] = gen_reg_rtx (DImode);
4978 if (TARGET_POWERPC64)
4979 {
4980 operands[4] = gen_reg_rtx (DImode);
4981 operands[5] = gen_rtx_LSHIFTRT (DImode, operands[3], GEN_INT (63));
4982 operands[6] = gen_rtx_SUBREG (SImode, operands[4],
4983 WORDS_BIG_ENDIAN ? 4 : 0);
4984 }
4985 else
4986 {
4987 operands[4] = gen_reg_rtx (SImode);
4988 operands[5] = gen_rtx_SUBREG (SImode, operands[3],
4989 WORDS_BIG_ENDIAN ? 0 : 4);
4990 operands[6] = gen_rtx_LSHIFTRT (SImode, operands[4], GEN_INT (31));
4991 }
4992 })
4993
4994 ;; Optimize IEEE 128-bit signbit on 64-bit systems with direct move to avoid
4995 ;; multiple direct moves. If we used a SUBREG:DI of the Floa128 type, the
4996 ;; register allocator would typically move the entire _Float128 item to GPRs (2
4997 ;; instructions on ISA 3.0, 3-4 instructions on ISA 2.07).
4998 ;;
4999 ;; After register allocation, if the _Float128 had originally been in GPRs, the
5000 ;; split allows the post reload phases to eliminate the move, and do the shift
5001 ;; directly with the register that contains the signbit.
5002 (define_insn_and_split "@signbit<mode>2_dm"
5003 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
5004 (unspec:DI [(match_operand:SIGNBIT 1 "gpc_reg_operand" "wa,r")]
5005 UNSPEC_SIGNBIT))]
5006 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
5007 "@
5008 mfvsrd %0,%x1
5009 #"
5010 "&& reload_completed && int_reg_operand (operands[1], <MODE>mode)"
5011 [(set (match_dup 0)
5012 (match_dup 2))]
5013 {
5014 operands[2] = gen_highpart (DImode, operands[1]);
5015 }
5016 [(set_attr "type" "mftgpr,*")])
5017
5018 ;; Optimize IEEE 128-bit signbit on to avoid loading the value into a vector
5019 ;; register and then doing a direct move if the value comes from memory. On
5020 ;; little endian, we have to load the 2nd double-word to get the sign bit.
5021 (define_insn_and_split "*signbit<mode>2_dm_mem"
5022 [(set (match_operand:DI 0 "gpc_reg_operand" "=b")
5023 (unspec:DI [(match_operand:SIGNBIT 1 "memory_operand" "m")]
5024 UNSPEC_SIGNBIT))]
5025 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
5026 "#"
5027 "&& 1"
5028 [(set (match_dup 0)
5029 (match_dup 2))]
5030 {
5031 rtx dest = operands[0];
5032 rtx src = operands[1];
5033 rtx addr = XEXP (src, 0);
5034
5035 if (WORDS_BIG_ENDIAN)
5036 operands[2] = adjust_address (src, DImode, 0);
5037
5038 else if (REG_P (addr) || SUBREG_P (addr))
5039 operands[2] = adjust_address (src, DImode, 8);
5040
5041 else if (GET_CODE (addr) == PLUS && REG_P (XEXP (addr, 0))
5042 && CONST_INT_P (XEXP (addr, 1)) && mem_operand_gpr (src, DImode))
5043 operands[2] = adjust_address (src, DImode, 8);
5044
5045 else
5046 {
5047 rtx tmp = can_create_pseudo_p () ? gen_reg_rtx (DImode) : dest;
5048 emit_insn (gen_rtx_SET (tmp, addr));
5049 operands[2] = change_address (src, DImode,
5050 gen_rtx_PLUS (DImode, tmp, GEN_INT (8)));
5051 }
5052 })
5053
5054 (define_expand "copysign<mode>3"
5055 [(set (match_dup 3)
5056 (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))
5057 (set (match_dup 4)
5058 (neg:SFDF (abs:SFDF (match_dup 1))))
5059 (set (match_operand:SFDF 0 "gpc_reg_operand")
5060 (if_then_else:SFDF (ge (match_operand:SFDF 2 "gpc_reg_operand")
5061 (match_dup 5))
5062 (match_dup 3)
5063 (match_dup 4)))]
5064 "TARGET_HARD_FLOAT
5065 && ((TARGET_PPC_GFXOPT
5066 && !HONOR_NANS (<MODE>mode)
5067 && !HONOR_SIGNED_ZEROS (<MODE>mode))
5068 || TARGET_CMPB
5069 || VECTOR_UNIT_VSX_P (<MODE>mode))"
5070 {
5071 if (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode))
5072 {
5073 emit_insn (gen_copysign<mode>3_fcpsgn (operands[0], operands[1],
5074 operands[2]));
5075 DONE;
5076 }
5077
5078 operands[3] = gen_reg_rtx (<MODE>mode);
5079 operands[4] = gen_reg_rtx (<MODE>mode);
5080 operands[5] = CONST0_RTX (<MODE>mode);
5081 })
5082
5083 ;; Use an unspec rather providing an if-then-else in RTL, to prevent the
5084 ;; compiler from optimizing -0.0
5085 (define_insn "copysign<mode>3_fcpsgn"
5086 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5087 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")
5088 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")]
5089 UNSPEC_COPYSIGN))]
5090 "TARGET_HARD_FLOAT && (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode))"
5091 "@
5092 fcpsgn %0,%2,%1
5093 xscpsgndp %x0,%x2,%x1"
5094 [(set_attr "type" "fpsimple")])
5095
5096 ;; For MIN, MAX, and conditional move, we use DEFINE_EXPAND's that involve a
5097 ;; fsel instruction and some auxiliary computations. Then we just have a
5098 ;; single DEFINE_INSN for fsel and the define_splits to make them if made by
5099 ;; combine.
5100 ;; For MIN, MAX on non-VSX machines, and conditional move all of the time, we
5101 ;; use DEFINE_EXPAND's that involve a fsel instruction and some auxiliary
5102 ;; computations. Then we just have a single DEFINE_INSN for fsel and the
5103 ;; define_splits to make them if made by combine. On VSX machines we have the
5104 ;; min/max instructions.
5105 ;;
5106 ;; On VSX, we only check for TARGET_VSX instead of checking for a vsx/p8 vector
5107 ;; to allow either DF/SF to use only traditional registers.
5108
5109 (define_expand "s<minmax><mode>3"
5110 [(set (match_operand:SFDF 0 "gpc_reg_operand")
5111 (fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
5112 (match_operand:SFDF 2 "gpc_reg_operand")))]
5113 "TARGET_MINMAX"
5114 {
5115 rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]);
5116 DONE;
5117 })
5118
5119 (define_insn "*s<minmax><mode>3_vsx"
5120 [(set (match_operand:SFDF 0 "vsx_register_operand" "=<Fv>")
5121 (fp_minmax:SFDF (match_operand:SFDF 1 "vsx_register_operand" "<Fv>")
5122 (match_operand:SFDF 2 "vsx_register_operand" "<Fv>")))]
5123 "TARGET_VSX && TARGET_HARD_FLOAT"
5124 {
5125 return (TARGET_P9_MINMAX
5126 ? "xs<minmax>cdp %x0,%x1,%x2"
5127 : "xs<minmax>dp %x0,%x1,%x2");
5128 }
5129 [(set_attr "type" "fp")])
5130
5131 ;; The conditional move instructions allow us to perform max and min operations
5132 ;; even when we don't have the appropriate max/min instruction using the FSEL
5133 ;; instruction.
5134
5135 (define_insn_and_split "*s<minmax><mode>3_fpr"
5136 [(set (match_operand:SFDF 0 "gpc_reg_operand")
5137 (fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
5138 (match_operand:SFDF 2 "gpc_reg_operand")))]
5139 "!TARGET_VSX && TARGET_MINMAX"
5140 "#"
5141 "&& 1"
5142 [(const_int 0)]
5143 {
5144 rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]);
5145 DONE;
5146 })
5147
5148 (define_expand "mov<mode>cc"
5149 [(set (match_operand:GPR 0 "gpc_reg_operand")
5150 (if_then_else:GPR (match_operand 1 "comparison_operator")
5151 (match_operand:GPR 2 "gpc_reg_operand")
5152 (match_operand:GPR 3 "gpc_reg_operand")))]
5153 "TARGET_ISEL"
5154 {
5155 if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
5156 DONE;
5157 else
5158 FAIL;
5159 })
5160
5161 ;; We use the BASE_REGS for the isel input operands because, if rA is
5162 ;; 0, the value of 0 is placed in rD upon truth. Similarly for rB
5163 ;; because we may switch the operands and rB may end up being rA.
5164 ;;
5165 ;; We need 2 patterns: an unsigned and a signed pattern. We could
5166 ;; leave out the mode in operand 4 and use one pattern, but reload can
5167 ;; change the mode underneath our feet and then gets confused trying
5168 ;; to reload the value.
5169 (define_mode_iterator CCEITHER [CC CCUNS])
5170 (define_mode_attr un [(CC "") (CCUNS "un")])
5171 (define_insn "isel_<un>signed_<GPR:mode>"
5172 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
5173 (if_then_else:GPR
5174 (match_operator 1 "scc_comparison_operator"
5175 [(match_operand:CCEITHER 4 "cc_reg_operand" "y,y")
5176 (const_int 0)])
5177 (match_operand:GPR 2 "reg_or_zero_operand" "O,b")
5178 (match_operand:GPR 3 "gpc_reg_operand" "r,r")))]
5179 "TARGET_ISEL"
5180 "isel %0,%2,%3,%j1"
5181 [(set_attr "type" "isel")])
5182
5183 ;; These patterns can be useful for combine; they let combine know that
5184 ;; isel can handle reversed comparisons so long as the operands are
5185 ;; registers.
5186
5187 (define_insn "*isel_reversed_<un>signed_<GPR:mode>"
5188 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
5189 (if_then_else:GPR
5190 (match_operator 1 "scc_rev_comparison_operator"
5191 [(match_operand:CCEITHER 4 "cc_reg_operand" "y,y")
5192 (const_int 0)])
5193 (match_operand:GPR 2 "gpc_reg_operand" "r,r")
5194 (match_operand:GPR 3 "reg_or_zero_operand" "O,b")))]
5195 "TARGET_ISEL"
5196 {
5197 PUT_CODE (operands[1], reverse_condition (GET_CODE (operands[1])));
5198 return "isel %0,%3,%2,%j1";
5199 }
5200 [(set_attr "type" "isel")])
5201
5202 ; Set Boolean Condition (Reverse)
5203 (define_insn "setbc_<un>signed_<GPR:mode>"
5204 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
5205 (match_operator:GPR 1 "scc_comparison_operator"
5206 [(match_operand:CCEITHER 2 "cc_reg_operand" "y")
5207 (const_int 0)]))]
5208 "TARGET_POWER10"
5209 "setbc %0,%j1"
5210 [(set_attr "type" "isel")])
5211
5212 (define_insn "*setbcr_<un>signed_<GPR:mode>"
5213 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
5214 (match_operator:GPR 1 "scc_rev_comparison_operator"
5215 [(match_operand:CCEITHER 2 "cc_reg_operand" "y")
5216 (const_int 0)]))]
5217 "TARGET_POWER10"
5218 "setbcr %0,%j1"
5219 [(set_attr "type" "isel")])
5220
5221 ; Set Negative Boolean Condition (Reverse)
5222 (define_insn "*setnbc_<un>signed_<GPR:mode>"
5223 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
5224 (neg:GPR (match_operator:GPR 1 "scc_comparison_operator"
5225 [(match_operand:CCEITHER 2 "cc_reg_operand" "y")
5226 (const_int 0)])))]
5227 "TARGET_POWER10"
5228 "setnbc %0,%j1"
5229 [(set_attr "type" "isel")])
5230
5231 (define_insn "*setnbcr_<un>signed_<GPR:mode>"
5232 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
5233 (neg:GPR (match_operator:GPR 1 "scc_rev_comparison_operator"
5234 [(match_operand:CCEITHER 2 "cc_reg_operand" "y")
5235 (const_int 0)])))]
5236 "TARGET_POWER10"
5237 "setnbcr %0,%j1"
5238 [(set_attr "type" "isel")])
5239
5240 ;; Floating point conditional move
5241 (define_expand "mov<mode>cc"
5242 [(set (match_operand:SFDF 0 "gpc_reg_operand")
5243 (if_then_else:SFDF (match_operand 1 "comparison_operator")
5244 (match_operand:SFDF 2 "gpc_reg_operand")
5245 (match_operand:SFDF 3 "gpc_reg_operand")))]
5246 "TARGET_HARD_FLOAT && TARGET_PPC_GFXOPT"
5247 {
5248 if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
5249 DONE;
5250 else
5251 FAIL;
5252 })
5253
5254 (define_insn "*fsel<SFDF:mode><SFDF2:mode>4"
5255 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=&<SFDF:rreg2>")
5256 (if_then_else:SFDF
5257 (ge (match_operand:SFDF2 1 "gpc_reg_operand" "<SFDF2:rreg2>")
5258 (match_operand:SFDF2 4 "zero_fp_constant" "F"))
5259 (match_operand:SFDF 2 "gpc_reg_operand" "<SFDF:rreg2>")
5260 (match_operand:SFDF 3 "gpc_reg_operand" "<SFDF:rreg2>")))]
5261 "TARGET_HARD_FLOAT && TARGET_PPC_GFXOPT"
5262 "fsel %0,%1,%2,%3"
5263 [(set_attr "type" "fp")])
5264
5265 (define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_p9"
5266 [(set (match_operand:SFDF 0 "vsx_register_operand" "=&<SFDF:Fv>,<SFDF:Fv>")
5267 (if_then_else:SFDF
5268 (match_operator:CCFP 1 "fpmask_comparison_operator"
5269 [(match_operand:SFDF2 2 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")
5270 (match_operand:SFDF2 3 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")])
5271 (match_operand:SFDF 4 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")
5272 (match_operand:SFDF 5 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")))
5273 (clobber (match_scratch:V2DI 6 "=0,&wa"))]
5274 "TARGET_P9_MINMAX"
5275 "#"
5276 ""
5277 [(set (match_dup 6)
5278 (if_then_else:V2DI (match_dup 1)
5279 (match_dup 7)
5280 (match_dup 8)))
5281 (set (match_dup 0)
5282 (if_then_else:SFDF (ne (match_dup 6)
5283 (match_dup 8))
5284 (match_dup 4)
5285 (match_dup 5)))]
5286 {
5287 if (GET_CODE (operands[6]) == SCRATCH)
5288 operands[6] = gen_reg_rtx (V2DImode);
5289
5290 operands[7] = CONSTM1_RTX (V2DImode);
5291 operands[8] = CONST0_RTX (V2DImode);
5292 }
5293 [(set_attr "length" "8")
5294 (set_attr "type" "vecperm")])
5295
5296 ;; Handle inverting the fpmask comparisons.
5297 (define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_invert_p9"
5298 [(set (match_operand:SFDF 0 "vsx_register_operand" "=&<SFDF:Fv>,<SFDF:Fv>")
5299 (if_then_else:SFDF
5300 (match_operator:CCFP 1 "invert_fpmask_comparison_operator"
5301 [(match_operand:SFDF2 2 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")
5302 (match_operand:SFDF2 3 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")])
5303 (match_operand:SFDF 4 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")
5304 (match_operand:SFDF 5 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")))
5305 (clobber (match_scratch:V2DI 6 "=0,&wa"))]
5306 "TARGET_P9_MINMAX"
5307 "#"
5308 "&& 1"
5309 [(set (match_dup 6)
5310 (if_then_else:V2DI (match_dup 9)
5311 (match_dup 7)
5312 (match_dup 8)))
5313 (set (match_dup 0)
5314 (if_then_else:SFDF (ne (match_dup 6)
5315 (match_dup 8))
5316 (match_dup 5)
5317 (match_dup 4)))]
5318 {
5319 rtx op1 = operands[1];
5320 enum rtx_code cond = reverse_condition_maybe_unordered (GET_CODE (op1));
5321
5322 if (GET_CODE (operands[6]) == SCRATCH)
5323 operands[6] = gen_reg_rtx (V2DImode);
5324
5325 operands[7] = CONSTM1_RTX (V2DImode);
5326 operands[8] = CONST0_RTX (V2DImode);
5327
5328 operands[9] = gen_rtx_fmt_ee (cond, CCFPmode, operands[2], operands[3]);
5329 }
5330 [(set_attr "length" "8")
5331 (set_attr "type" "vecperm")])
5332
5333 (define_insn "*fpmask<mode>"
5334 [(set (match_operand:V2DI 0 "vsx_register_operand" "=wa")
5335 (if_then_else:V2DI
5336 (match_operator:CCFP 1 "fpmask_comparison_operator"
5337 [(match_operand:SFDF 2 "vsx_register_operand" "<Fv>")
5338 (match_operand:SFDF 3 "vsx_register_operand" "<Fv>")])
5339 (match_operand:V2DI 4 "all_ones_constant" "")
5340 (match_operand:V2DI 5 "zero_constant" "")))]
5341 "TARGET_P9_MINMAX"
5342 "xscmp%V1dp %x0,%x2,%x3"
5343 [(set_attr "type" "fpcompare")])
5344
5345 (define_insn "*xxsel<mode>"
5346 [(set (match_operand:SFDF 0 "vsx_register_operand" "=<Fv>")
5347 (if_then_else:SFDF (ne (match_operand:V2DI 1 "vsx_register_operand" "wa")
5348 (match_operand:V2DI 2 "zero_constant" ""))
5349 (match_operand:SFDF 3 "vsx_register_operand" "<Fv>")
5350 (match_operand:SFDF 4 "vsx_register_operand" "<Fv>")))]
5351 "TARGET_P9_MINMAX"
5352 "xxsel %x0,%x4,%x3,%x1"
5353 [(set_attr "type" "vecmove")])
5354
5355 \f
5356 ;; Conversions to and from floating-point.
5357
5358 ; We don't define lfiwax/lfiwzx with the normal definition, because we
5359 ; don't want to support putting SImode in FPR registers.
5360 (define_insn "lfiwax"
5361 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa,wa,v")
5362 (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r,v")]
5363 UNSPEC_LFIWAX))]
5364 "TARGET_HARD_FLOAT && TARGET_LFIWAX"
5365 "@
5366 lfiwax %0,%y1
5367 lxsiwax %x0,%y1
5368 mtvsrwa %x0,%1
5369 vextsw2d %0,%1"
5370 [(set_attr "type" "fpload,fpload,mffgpr,vecexts")
5371 (set_attr "isa" "*,p8v,p8v,p9v")])
5372
5373 ; This split must be run before register allocation because it allocates the
5374 ; memory slot that is needed to move values to/from the FPR. We don't allocate
5375 ; it earlier to allow for the combiner to merge insns together where it might
5376 ; not be needed and also in case the insns are deleted as dead code.
5377
5378 (define_insn_and_split "floatsi<mode>2_lfiwax"
5379 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,<Fv>")
5380 (float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r,r")))
5381 (clobber (match_scratch:DI 2 "=d,wa"))]
5382 "TARGET_HARD_FLOAT && TARGET_LFIWAX
5383 && <SI_CONVERT_FP> && can_create_pseudo_p ()"
5384 "#"
5385 ""
5386 [(pc)]
5387 {
5388 rtx dest = operands[0];
5389 rtx src = operands[1];
5390 rtx tmp;
5391
5392 if (!MEM_P (src) && TARGET_POWERPC64 && TARGET_DIRECT_MOVE)
5393 tmp = convert_to_mode (DImode, src, false);
5394 else
5395 {
5396 tmp = operands[2];
5397 if (GET_CODE (tmp) == SCRATCH)
5398 tmp = gen_reg_rtx (DImode);
5399 if (MEM_P (src))
5400 {
5401 src = rs6000_force_indexed_or_indirect_mem (src);
5402 emit_insn (gen_lfiwax (tmp, src));
5403 }
5404 else
5405 {
5406 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5407 emit_move_insn (stack, src);
5408 emit_insn (gen_lfiwax (tmp, stack));
5409 }
5410 }
5411 emit_insn (gen_floatdi<mode>2 (dest, tmp));
5412 DONE;
5413 }
5414 [(set_attr "length" "12")
5415 (set_attr "type" "fpload")])
5416
5417 (define_insn_and_split "floatsi<mode>2_lfiwax_mem"
5418 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,<Fv>")
5419 (float:SFDF
5420 (sign_extend:DI
5421 (match_operand:SI 1 "indexed_or_indirect_operand" "Z,Z"))))
5422 (clobber (match_scratch:DI 2 "=d,wa"))]
5423 "TARGET_HARD_FLOAT && TARGET_LFIWAX && <SI_CONVERT_FP>"
5424 "#"
5425 ""
5426 [(pc)]
5427 {
5428 operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
5429 if (GET_CODE (operands[2]) == SCRATCH)
5430 operands[2] = gen_reg_rtx (DImode);
5431 if (TARGET_P8_VECTOR)
5432 emit_insn (gen_extendsidi2 (operands[2], operands[1]));
5433 else
5434 emit_insn (gen_lfiwax (operands[2], operands[1]));
5435 emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
5436 DONE;
5437 }
5438 [(set_attr "length" "8")
5439 (set_attr "type" "fpload")])
5440
5441 (define_insn "lfiwzx"
5442 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa,wa,wa")
5443 (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r,wa")]
5444 UNSPEC_LFIWZX))]
5445 "TARGET_HARD_FLOAT && TARGET_LFIWZX"
5446 "@
5447 lfiwzx %0,%y1
5448 lxsiwzx %x0,%y1
5449 mtvsrwz %x0,%1
5450 xxextractuw %x0,%x1,4"
5451 [(set_attr "type" "fpload,fpload,mftgpr,vecexts")
5452 (set_attr "isa" "*,p8v,p8v,p9v")])
5453
5454 (define_insn_and_split "floatunssi<mode>2_lfiwzx"
5455 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,<Fv>")
5456 (unsigned_float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r,r")))
5457 (clobber (match_scratch:DI 2 "=d,wa"))]
5458 "TARGET_HARD_FLOAT && TARGET_LFIWZX && <SI_CONVERT_FP>"
5459 "#"
5460 ""
5461 [(pc)]
5462 {
5463 rtx dest = operands[0];
5464 rtx src = operands[1];
5465 rtx tmp;
5466
5467 if (!MEM_P (src) && TARGET_POWERPC64 && TARGET_DIRECT_MOVE)
5468 tmp = convert_to_mode (DImode, src, true);
5469 else
5470 {
5471 tmp = operands[2];
5472 if (GET_CODE (tmp) == SCRATCH)
5473 tmp = gen_reg_rtx (DImode);
5474 if (MEM_P (src))
5475 {
5476 src = rs6000_force_indexed_or_indirect_mem (src);
5477 emit_insn (gen_lfiwzx (tmp, src));
5478 }
5479 else
5480 {
5481 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5482 emit_move_insn (stack, src);
5483 emit_insn (gen_lfiwzx (tmp, stack));
5484 }
5485 }
5486 emit_insn (gen_floatdi<mode>2 (dest, tmp));
5487 DONE;
5488 }
5489 [(set_attr "length" "12")
5490 (set_attr "type" "fpload")])
5491
5492 (define_insn_and_split "floatunssi<mode>2_lfiwzx_mem"
5493 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,<Fv>")
5494 (unsigned_float:SFDF
5495 (zero_extend:DI
5496 (match_operand:SI 1 "indexed_or_indirect_operand" "Z,Z"))))
5497 (clobber (match_scratch:DI 2 "=d,wa"))]
5498 "TARGET_HARD_FLOAT && TARGET_LFIWZX && <SI_CONVERT_FP>"
5499 "#"
5500 ""
5501 [(pc)]
5502 {
5503 operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
5504 if (GET_CODE (operands[2]) == SCRATCH)
5505 operands[2] = gen_reg_rtx (DImode);
5506 if (TARGET_P8_VECTOR)
5507 emit_insn (gen_zero_extendsidi2 (operands[2], operands[1]));
5508 else
5509 emit_insn (gen_lfiwzx (operands[2], operands[1]));
5510 emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
5511 DONE;
5512 }
5513 [(set_attr "length" "8")
5514 (set_attr "type" "fpload")])
5515
5516 ; For each of these conversions, there is a define_expand, a define_insn
5517 ; with a '#' template, and a define_split (with C code). The idea is
5518 ; to allow constant folding with the template of the define_insn,
5519 ; then to have the insns split later (between sched1 and final).
5520
5521 (define_expand "floatsidf2"
5522 [(parallel [(set (match_operand:DF 0 "gpc_reg_operand")
5523 (float:DF (match_operand:SI 1 "nonimmediate_operand")))
5524 (use (match_dup 2))
5525 (use (match_dup 3))
5526 (clobber (match_dup 4))
5527 (clobber (match_dup 5))
5528 (clobber (match_dup 6))])]
5529 "TARGET_HARD_FLOAT"
5530 {
5531 if (TARGET_LFIWAX && TARGET_FCFID)
5532 {
5533 emit_insn (gen_floatsidf2_lfiwax (operands[0], operands[1]));
5534 DONE;
5535 }
5536 else if (TARGET_FCFID)
5537 {
5538 rtx dreg = operands[1];
5539 if (!REG_P (dreg))
5540 dreg = force_reg (SImode, dreg);
5541 dreg = convert_to_mode (DImode, dreg, false);
5542 emit_insn (gen_floatdidf2 (operands[0], dreg));
5543 DONE;
5544 }
5545
5546 if (!REG_P (operands[1]))
5547 operands[1] = force_reg (SImode, operands[1]);
5548 operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5549 operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503601774854144\", DFmode));
5550 operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5551 operands[5] = gen_reg_rtx (DFmode);
5552 operands[6] = gen_reg_rtx (SImode);
5553 })
5554
5555 (define_insn_and_split "*floatsidf2_internal"
5556 [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5557 (float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5558 (use (match_operand:SI 2 "gpc_reg_operand" "r"))
5559 (use (match_operand:DF 3 "gpc_reg_operand" "d"))
5560 (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
5561 (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))
5562 (clobber (match_operand:SI 6 "gpc_reg_operand" "=&r"))]
5563 "!TARGET_FCFID && TARGET_HARD_FLOAT"
5564 "#"
5565 ""
5566 [(pc)]
5567 {
5568 rtx lowword, highword;
5569 gcc_assert (MEM_P (operands[4]));
5570 highword = adjust_address (operands[4], SImode, 0);
5571 lowword = adjust_address (operands[4], SImode, 4);
5572 if (! WORDS_BIG_ENDIAN)
5573 std::swap (lowword, highword);
5574
5575 emit_insn (gen_xorsi3 (operands[6], operands[1],
5576 GEN_INT (~ (HOST_WIDE_INT) 0x7fffffff)));
5577 emit_move_insn (lowword, operands[6]);
5578 emit_move_insn (highword, operands[2]);
5579 emit_move_insn (operands[5], operands[4]);
5580 emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5581 DONE;
5582 }
5583 [(set_attr "length" "24")
5584 (set_attr "type" "fp")])
5585
5586 ;; If we don't have a direct conversion to single precision, don't enable this
5587 ;; conversion for 32-bit without fast math, because we don't have the insn to
5588 ;; generate the fixup swizzle to avoid double rounding problems.
5589 (define_expand "floatunssisf2"
5590 [(set (match_operand:SF 0 "gpc_reg_operand")
5591 (unsigned_float:SF (match_operand:SI 1 "nonimmediate_operand")))]
5592 "TARGET_HARD_FLOAT
5593 && ((TARGET_FCFIDUS && TARGET_LFIWZX)
5594 || (TARGET_FCFID
5595 && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))"
5596 {
5597 if (TARGET_LFIWZX && TARGET_FCFIDUS)
5598 {
5599 emit_insn (gen_floatunssisf2_lfiwzx (operands[0], operands[1]));
5600 DONE;
5601 }
5602 else
5603 {
5604 rtx dreg = operands[1];
5605 if (!REG_P (dreg))
5606 dreg = force_reg (SImode, dreg);
5607 dreg = convert_to_mode (DImode, dreg, true);
5608 emit_insn (gen_floatdisf2 (operands[0], dreg));
5609 DONE;
5610 }
5611 })
5612
5613 (define_expand "floatunssidf2"
5614 [(parallel [(set (match_operand:DF 0 "gpc_reg_operand")
5615 (unsigned_float:DF (match_operand:SI 1 "nonimmediate_operand")))
5616 (use (match_dup 2))
5617 (use (match_dup 3))
5618 (clobber (match_dup 4))
5619 (clobber (match_dup 5))])]
5620 "TARGET_HARD_FLOAT"
5621 {
5622 if (TARGET_LFIWZX && TARGET_FCFID)
5623 {
5624 emit_insn (gen_floatunssidf2_lfiwzx (operands[0], operands[1]));
5625 DONE;
5626 }
5627 else if (TARGET_FCFID)
5628 {
5629 rtx dreg = operands[1];
5630 if (!REG_P (dreg))
5631 dreg = force_reg (SImode, dreg);
5632 dreg = convert_to_mode (DImode, dreg, true);
5633 emit_insn (gen_floatdidf2 (operands[0], dreg));
5634 DONE;
5635 }
5636
5637 if (!REG_P (operands[1]))
5638 operands[1] = force_reg (SImode, operands[1]);
5639 operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5640 operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503599627370496\", DFmode));
5641 operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5642 operands[5] = gen_reg_rtx (DFmode);
5643 })
5644
5645 (define_insn_and_split "*floatunssidf2_internal"
5646 [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5647 (unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5648 (use (match_operand:SI 2 "gpc_reg_operand" "r"))
5649 (use (match_operand:DF 3 "gpc_reg_operand" "d"))
5650 (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
5651 (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))]
5652 "!TARGET_FCFIDU && TARGET_HARD_FLOAT
5653 && !(TARGET_FCFID && TARGET_POWERPC64)"
5654 "#"
5655 ""
5656 [(pc)]
5657 {
5658 rtx lowword, highword;
5659 gcc_assert (MEM_P (operands[4]));
5660 highword = adjust_address (operands[4], SImode, 0);
5661 lowword = adjust_address (operands[4], SImode, 4);
5662 if (! WORDS_BIG_ENDIAN)
5663 std::swap (lowword, highword);
5664
5665 emit_move_insn (lowword, operands[1]);
5666 emit_move_insn (highword, operands[2]);
5667 emit_move_insn (operands[5], operands[4]);
5668 emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5669 DONE;
5670 }
5671 [(set_attr "length" "20")
5672 (set_attr "type" "fp")])
5673
5674 ;; ISA 3.0 adds instructions lxsi[bh]zx to directly load QImode and HImode to
5675 ;; vector registers. These insns favor doing the sign/zero extension in
5676 ;; the vector registers, rather then loading up a GPR, doing a sign/zero
5677 ;; extension and then a direct move.
5678
5679 (define_expand "float<QHI:mode><FP_ISA3:mode>2"
5680 [(parallel [(set (match_operand:FP_ISA3 0 "vsx_register_operand")
5681 (float:FP_ISA3
5682 (match_operand:QHI 1 "input_operand")))
5683 (clobber (match_scratch:DI 2))
5684 (clobber (match_scratch:DI 3))
5685 (clobber (match_scratch:<QHI:MODE> 4))])]
5686 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5687 {
5688 if (MEM_P (operands[1]))
5689 operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
5690 })
5691
5692 (define_insn_and_split "*float<QHI:mode><FP_ISA3:mode>2_internal"
5693 [(set (match_operand:FP_ISA3 0 "vsx_register_operand" "=<Fv>,<Fv>,<Fv>")
5694 (float:FP_ISA3
5695 (match_operand:QHI 1 "reg_or_indexed_operand" "v,r,Z")))
5696 (clobber (match_scratch:DI 2 "=v,wa,v"))
5697 (clobber (match_scratch:DI 3 "=X,r,X"))
5698 (clobber (match_scratch:<QHI:MODE> 4 "=X,X,v"))]
5699 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5700 "#"
5701 "&& reload_completed"
5702 [(const_int 0)]
5703 {
5704 rtx result = operands[0];
5705 rtx input = operands[1];
5706 rtx di = operands[2];
5707
5708 if (!MEM_P (input))
5709 {
5710 rtx tmp = operands[3];
5711 if (altivec_register_operand (input, <QHI:MODE>mode))
5712 emit_insn (gen_extend<QHI:mode>di2 (di, input));
5713 else if (GET_CODE (tmp) == SCRATCH)
5714 emit_insn (gen_extend<QHI:mode>di2 (di, input));
5715 else
5716 {
5717 emit_insn (gen_extend<QHI:mode>di2 (tmp, input));
5718 emit_move_insn (di, tmp);
5719 }
5720 }
5721 else
5722 {
5723 rtx tmp = operands[4];
5724 emit_move_insn (tmp, input);
5725 emit_insn (gen_extend<QHI:mode>di2 (di, tmp));
5726 }
5727
5728 emit_insn (gen_floatdi<FP_ISA3:mode>2 (result, di));
5729 DONE;
5730 }
5731 [(set_attr "isa" "p9v,*,p9v")])
5732
5733 (define_expand "floatuns<QHI:mode><FP_ISA3:mode>2"
5734 [(parallel [(set (match_operand:FP_ISA3 0 "vsx_register_operand")
5735 (unsigned_float:FP_ISA3
5736 (match_operand:QHI 1 "input_operand")))
5737 (clobber (match_scratch:DI 2))
5738 (clobber (match_scratch:DI 3))])]
5739 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5740 {
5741 if (MEM_P (operands[1]))
5742 operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
5743 })
5744
5745 (define_insn_and_split "*floatuns<QHI:mode><FP_ISA3:mode>2_internal"
5746 [(set (match_operand:FP_ISA3 0 "vsx_register_operand" "=<Fv>,<Fv>,<Fv>")
5747 (unsigned_float:FP_ISA3
5748 (match_operand:QHI 1 "reg_or_indexed_operand" "v,r,Z")))
5749 (clobber (match_scratch:DI 2 "=v,wa,wa"))
5750 (clobber (match_scratch:DI 3 "=X,r,X"))]
5751 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5752 "#"
5753 "&& reload_completed"
5754 [(const_int 0)]
5755 {
5756 rtx result = operands[0];
5757 rtx input = operands[1];
5758 rtx di = operands[2];
5759
5760 if (MEM_P (input) || altivec_register_operand (input, <QHI:MODE>mode))
5761 emit_insn (gen_zero_extend<QHI:mode>di2 (di, input));
5762 else
5763 {
5764 rtx tmp = operands[3];
5765 if (GET_CODE (tmp) == SCRATCH)
5766 emit_insn (gen_extend<QHI:mode>di2 (di, input));
5767 else
5768 {
5769 emit_insn (gen_zero_extend<QHI:mode>di2 (tmp, input));
5770 emit_move_insn (di, tmp);
5771 }
5772 }
5773
5774 emit_insn (gen_floatdi<FP_ISA3:mode>2 (result, di));
5775 DONE;
5776 }
5777 [(set_attr "isa" "p9v,*,p9v")])
5778
5779 (define_expand "fix_trunc<mode>si2"
5780 [(set (match_operand:SI 0 "gpc_reg_operand")
5781 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand")))]
5782 "TARGET_HARD_FLOAT"
5783 {
5784 if (!(TARGET_P8_VECTOR && TARGET_DIRECT_MOVE))
5785 {
5786 rtx src = force_reg (<MODE>mode, operands[1]);
5787
5788 if (TARGET_STFIWX)
5789 emit_insn (gen_fix_trunc<mode>si2_stfiwx (operands[0], src));
5790 else
5791 {
5792 rtx tmp = gen_reg_rtx (DImode);
5793 rtx stack = rs6000_allocate_stack_temp (DImode, true, false);
5794 emit_insn (gen_fix_trunc<mode>si2_internal (operands[0], src,
5795 tmp, stack));
5796 }
5797 DONE;
5798 }
5799 })
5800
5801 ; Like the convert to float patterns, this insn must be split before
5802 ; register allocation so that it can allocate the memory slot if it
5803 ; needed
5804 (define_insn_and_split "fix_trunc<mode>si2_stfiwx"
5805 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5806 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
5807 (clobber (match_scratch:DI 2 "=d"))]
5808 "TARGET_HARD_FLOAT && TARGET_STFIWX && can_create_pseudo_p ()
5809 && !(TARGET_P8_VECTOR && TARGET_DIRECT_MOVE)"
5810 "#"
5811 ""
5812 [(pc)]
5813 {
5814 rtx dest = operands[0];
5815 rtx src = operands[1];
5816 rtx tmp = operands[2];
5817
5818 if (GET_CODE (tmp) == SCRATCH)
5819 tmp = gen_reg_rtx (DImode);
5820
5821 emit_insn (gen_fctiwz_<mode> (tmp, src));
5822 if (MEM_P (dest) && (TARGET_MFCRF || MEM_ALIGN (dest) >= 32))
5823 {
5824 dest = rs6000_force_indexed_or_indirect_mem (dest);
5825 emit_insn (gen_stfiwx (dest, tmp));
5826 DONE;
5827 }
5828 else if (TARGET_POWERPC64 && TARGET_DIRECT_MOVE && !MEM_P (dest))
5829 {
5830 dest = gen_lowpart (DImode, dest);
5831 emit_move_insn (dest, tmp);
5832 DONE;
5833 }
5834 else
5835 {
5836 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5837 emit_insn (gen_stfiwx (stack, tmp));
5838 emit_move_insn (dest, stack);
5839 DONE;
5840 }
5841 }
5842 [(set_attr "length" "12")
5843 (set_attr "type" "fp")])
5844
5845 (define_insn_and_split "fix_trunc<mode>si2_internal"
5846 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,?r")
5847 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d,<rreg>")))
5848 (clobber (match_operand:DI 2 "gpc_reg_operand" "=1,d"))
5849 (clobber (match_operand:DI 3 "offsettable_mem_operand" "=o,o"))]
5850 "TARGET_HARD_FLOAT
5851 && !(TARGET_P8_VECTOR && TARGET_DIRECT_MOVE)"
5852 "#"
5853 ""
5854 [(pc)]
5855 {
5856 rtx lowword;
5857 gcc_assert (MEM_P (operands[3]));
5858 lowword = adjust_address (operands[3], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
5859
5860 emit_insn (gen_fctiwz_<mode> (operands[2], operands[1]));
5861 emit_move_insn (operands[3], operands[2]);
5862 emit_move_insn (operands[0], lowword);
5863 DONE;
5864 }
5865 [(set_attr "length" "16")
5866 (set_attr "type" "fp")])
5867
5868 (define_expand "fix_trunc<mode>di2"
5869 [(set (match_operand:DI 0 "gpc_reg_operand")
5870 (fix:DI (match_operand:SFDF 1 "gpc_reg_operand")))]
5871 "TARGET_HARD_FLOAT && TARGET_FCFID"
5872 "")
5873
5874 (define_insn "*fix_trunc<mode>di2_fctidz"
5875 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa")
5876 (fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
5877 "TARGET_HARD_FLOAT && TARGET_FCFID"
5878 "@
5879 fctidz %0,%1
5880 xscvdpsxds %x0,%x1"
5881 [(set_attr "type" "fp")])
5882
5883 ;; If we have ISA 3.0, QI/HImode values can go in both VSX registers and GPR
5884 ;; registers. If we have ISA 2.07, we don't allow QI/HImode values in the
5885 ;; vector registers, so we need to do direct moves to the GPRs, but SImode
5886 ;; values can go in VSX registers. Keeping the direct move part through
5887 ;; register allocation prevents the register allocator from doing a direct move
5888 ;; of the SImode value to a GPR, and then a store/load.
5889 (define_insn_and_split "fix<uns>_trunc<SFDF:mode><QHI:mode>2"
5890 [(set (match_operand:<QHI:MODE> 0 "gpc_reg_operand" "=d,wa,r")
5891 (any_fix:QHI (match_operand:SFDF 1 "gpc_reg_operand" "d,wa,wa")))
5892 (clobber (match_scratch:SI 2 "=X,X,wa"))]
5893 "TARGET_DIRECT_MOVE"
5894 "@
5895 fctiw<u>z %0,%1
5896 xscvdp<su>xws %x0,%x1
5897 #"
5898 "&& reload_completed && int_reg_operand (operands[0], <QHI:MODE>mode)"
5899 [(set (match_dup 2)
5900 (any_fix:SI (match_dup 1)))
5901 (set (match_dup 3)
5902 (match_dup 2))]
5903 {
5904 operands[3] = gen_rtx_REG (SImode, REGNO (operands[0]));
5905 }
5906 [(set_attr "type" "fp")
5907 (set_attr "length" "4,4,8")
5908 (set_attr "isa" "p9v,p9v,*")])
5909
5910 (define_insn "*fix<uns>_trunc<SFDF:mode>si2_p8"
5911 [(set (match_operand:SI 0 "gpc_reg_operand" "=d,wa")
5912 (any_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d,wa")))]
5913 "TARGET_DIRECT_MOVE"
5914 "@
5915 fctiw<u>z %0,%1
5916 xscvdp<su>xws %x0,%x1"
5917 [(set_attr "type" "fp")])
5918
5919 ;; Keep the convert and store together through register allocation to prevent
5920 ;; the register allocator from getting clever and doing a direct move to a GPR
5921 ;; and then store for reg+offset stores.
5922 (define_insn_and_split "*fix<uns>_trunc<SFDF:mode><QHSI:mode>2_mem"
5923 [(set (match_operand:QHSI 0 "memory_operand" "=Z")
5924 (any_fix:QHSI (match_operand:SFDF 1 "gpc_reg_operand" "wa")))
5925 (clobber (match_scratch:SI 2 "=wa"))]
5926 "(<QHSI:MODE>mode == SImode && TARGET_P8_VECTOR) || TARGET_P9_VECTOR"
5927 "#"
5928 "&& reload_completed"
5929 [(set (match_dup 2)
5930 (any_fix:SI (match_dup 1)))
5931 (set (match_dup 0)
5932 (match_dup 3))]
5933 {
5934 operands[3] = (<QHSI:MODE>mode == SImode
5935 ? operands[2]
5936 : gen_rtx_REG (<QHSI:MODE>mode, REGNO (operands[2])));
5937 })
5938
5939 (define_expand "fixuns_trunc<mode>si2"
5940 [(set (match_operand:SI 0 "gpc_reg_operand")
5941 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand")))]
5942 "TARGET_HARD_FLOAT && TARGET_FCTIWUZ && TARGET_STFIWX"
5943 {
5944 if (!TARGET_P8_VECTOR)
5945 {
5946 emit_insn (gen_fixuns_trunc<mode>si2_stfiwx (operands[0], operands[1]));
5947 DONE;
5948 }
5949 })
5950
5951 (define_insn_and_split "fixuns_trunc<mode>si2_stfiwx"
5952 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5953 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
5954 (clobber (match_scratch:DI 2 "=d"))]
5955 "TARGET_HARD_FLOAT && TARGET_FCTIWUZ
5956 && TARGET_STFIWX && can_create_pseudo_p ()
5957 && !TARGET_P8_VECTOR"
5958 "#"
5959 ""
5960 [(pc)]
5961 {
5962 rtx dest = operands[0];
5963 rtx src = operands[1];
5964 rtx tmp = operands[2];
5965
5966 if (GET_CODE (tmp) == SCRATCH)
5967 tmp = gen_reg_rtx (DImode);
5968
5969 emit_insn (gen_fctiwuz_<mode> (tmp, src));
5970 if (MEM_P (dest))
5971 {
5972 dest = rs6000_force_indexed_or_indirect_mem (dest);
5973 emit_insn (gen_stfiwx (dest, tmp));
5974 DONE;
5975 }
5976 else if (TARGET_POWERPC64 && TARGET_DIRECT_MOVE)
5977 {
5978 dest = gen_lowpart (DImode, dest);
5979 emit_move_insn (dest, tmp);
5980 DONE;
5981 }
5982 else
5983 {
5984 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5985 emit_insn (gen_stfiwx (stack, tmp));
5986 emit_move_insn (dest, stack);
5987 DONE;
5988 }
5989 }
5990 [(set_attr "length" "12")
5991 (set_attr "type" "fp")])
5992
5993 (define_insn "fixuns_trunc<mode>di2"
5994 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa")
5995 (unsigned_fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
5996 "TARGET_HARD_FLOAT && TARGET_FCTIDUZ"
5997 "@
5998 fctiduz %0,%1
5999 xscvdpuxds %x0,%x1"
6000 [(set_attr "type" "fp")])
6001
6002 (define_insn "rs6000_mtfsb0"
6003 [(unspec_volatile [(match_operand:SI 0 "u5bit_cint_operand" "n")]
6004 UNSPECV_MTFSB0)]
6005 "TARGET_HARD_FLOAT"
6006 "mtfsb0 %0"
6007 [(set_attr "type" "fp")])
6008
6009 (define_insn "rs6000_mtfsb1"
6010 [(unspec_volatile [(match_operand:SI 0 "u5bit_cint_operand" "n")]
6011 UNSPECV_MTFSB1)]
6012 "TARGET_HARD_FLOAT"
6013 "mtfsb1 %0"
6014 [(set_attr "type" "fp")])
6015
6016 (define_insn "rs6000_mffscrn"
6017 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
6018 (unspec_volatile:DF [(match_operand:DF 1 "gpc_reg_operand" "d")]
6019 UNSPECV_MFFSCRN))]
6020 "TARGET_P9_MISC"
6021 "mffscrn %0,%1"
6022 [(set_attr "type" "fp")])
6023
6024 (define_insn "rs6000_mffscdrn"
6025 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
6026 (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFSCDRN))
6027 (use (match_operand:DF 1 "gpc_reg_operand" "d"))]
6028 "TARGET_P9_MISC"
6029 "mffscdrn %0,%1"
6030 [(set_attr "type" "fp")])
6031
6032 (define_expand "rs6000_set_fpscr_rn"
6033 [(match_operand:DI 0 "reg_or_cint_operand")]
6034 "TARGET_HARD_FLOAT"
6035 {
6036 rtx tmp_df = gen_reg_rtx (DFmode);
6037
6038 /* The floating point rounding control bits are FPSCR[62:63]. Put the
6039 new rounding mode bits from operands[0][62:63] into FPSCR[62:63]. */
6040 if (TARGET_P9_MISC)
6041 {
6042 rtx src_df = force_reg (DImode, operands[0]);
6043 src_df = simplify_gen_subreg (DFmode, src_df, DImode, 0);
6044 emit_insn (gen_rs6000_mffscrn (tmp_df, src_df));
6045 DONE;
6046 }
6047
6048 if (CONST_INT_P (operands[0]))
6049 {
6050 if ((INTVAL (operands[0]) & 0x1) == 0x1)
6051 emit_insn (gen_rs6000_mtfsb1 (GEN_INT (31)));
6052 else
6053 emit_insn (gen_rs6000_mtfsb0 (GEN_INT (31)));
6054
6055 if ((INTVAL (operands[0]) & 0x2) == 0x2)
6056 emit_insn (gen_rs6000_mtfsb1 (GEN_INT (30)));
6057 else
6058 emit_insn (gen_rs6000_mtfsb0 (GEN_INT (30)));
6059 }
6060 else
6061 {
6062 rtx tmp_rn = gen_reg_rtx (DImode);
6063 rtx tmp_di = gen_reg_rtx (DImode);
6064
6065 /* Extract new RN mode from operand. */
6066 emit_insn (gen_anddi3 (tmp_rn, operands[0], GEN_INT (0x3)));
6067
6068 /* Insert new RN mode into FSCPR. */
6069 emit_insn (gen_rs6000_mffs (tmp_df));
6070 tmp_di = simplify_gen_subreg (DImode, tmp_df, DFmode, 0);
6071 emit_insn (gen_anddi3 (tmp_di, tmp_di, GEN_INT (-4)));
6072 emit_insn (gen_iordi3 (tmp_di, tmp_di, tmp_rn));
6073
6074 /* Need to write to field k=15. The fields are [0:15]. Hence with
6075 L=0, W=0, FLM_i must be equal to 8, 16 = i + 8*(1-W). FLM is an
6076 8-bit field[0:7]. Need to set the bit that corresponds to the
6077 value of i that you want [0:7]. */
6078 tmp_df = simplify_gen_subreg (DFmode, tmp_di, DImode, 0);
6079 emit_insn (gen_rs6000_mtfsf (GEN_INT (0x01), tmp_df));
6080 }
6081 DONE;
6082 })
6083
6084 (define_expand "rs6000_set_fpscr_drn"
6085 [(match_operand:DI 0 "gpc_reg_operand")]
6086 "TARGET_HARD_FLOAT"
6087 {
6088 rtx tmp_df = gen_reg_rtx (DFmode);
6089
6090 /* The decimal floating point rounding control bits are FPSCR[29:31]. Put the
6091 new rounding mode bits from operands[0][61:63] into FPSCR[29:31]. */
6092 if (TARGET_P9_MISC)
6093 {
6094 rtx src_df = gen_reg_rtx (DFmode);
6095
6096 emit_insn (gen_ashldi3 (operands[0], operands[0], GEN_INT (32)));
6097 src_df = simplify_gen_subreg (DFmode, operands[0], DImode, 0);
6098 emit_insn (gen_rs6000_mffscdrn (tmp_df, src_df));
6099 }
6100 else
6101 {
6102 rtx tmp_rn = gen_reg_rtx (DImode);
6103 rtx tmp_di = gen_reg_rtx (DImode);
6104
6105 /* Extract new DRN mode from operand. */
6106 emit_insn (gen_anddi3 (tmp_rn, operands[0], GEN_INT (0x7)));
6107 emit_insn (gen_ashldi3 (tmp_rn, tmp_rn, GEN_INT (32)));
6108
6109 /* Insert new RN mode into FSCPR. */
6110 emit_insn (gen_rs6000_mffs (tmp_df));
6111 tmp_di = simplify_gen_subreg (DImode, tmp_df, DFmode, 0);
6112 emit_insn (gen_anddi3 (tmp_di, tmp_di, GEN_INT (0xFFFFFFF8FFFFFFFFULL)));
6113 emit_insn (gen_iordi3 (tmp_di, tmp_di, tmp_rn));
6114
6115 /* Need to write to field 7. The fields are [0:15]. The equation to
6116 select the field is i + 8*(1-W). Hence with L=0 and W=1, need to set
6117 i to 0x1 to get field 7 where i selects the field. */
6118 tmp_df = simplify_gen_subreg (DFmode, tmp_di, DImode, 0);
6119 emit_insn (gen_rs6000_mtfsf_hi (GEN_INT (0x01), tmp_df));
6120 }
6121 DONE;
6122 })
6123
6124 ;; Here, we use (set (reg) (unspec:DI [(fix:SI ...)] UNSPEC_FCTIWZ))
6125 ;; rather than (set (subreg:SI (reg)) (fix:SI ...))
6126 ;; because the first makes it clear that operand 0 is not live
6127 ;; before the instruction.
6128 (define_insn "fctiwz_<mode>"
6129 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa")
6130 (unspec:DI [(fix:SI
6131 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
6132 UNSPEC_FCTIWZ))]
6133 "TARGET_HARD_FLOAT"
6134 "@
6135 fctiwz %0,%1
6136 xscvdpsxws %x0,%x1"
6137 [(set_attr "type" "fp")])
6138
6139 (define_insn "fctiwuz_<mode>"
6140 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa")
6141 (unspec:DI [(unsigned_fix:SI
6142 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
6143 UNSPEC_FCTIWUZ))]
6144 "TARGET_HARD_FLOAT && TARGET_FCTIWUZ"
6145 "@
6146 fctiwuz %0,%1
6147 xscvdpuxws %x0,%x1"
6148 [(set_attr "type" "fp")])
6149
6150 ;; Only optimize (float (fix x)) -> frz if we are in fast-math mode, since
6151 ;; since the friz instruction does not truncate the value if the floating
6152 ;; point value is < LONG_MIN or > LONG_MAX.
6153 (define_insn "*friz"
6154 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa")
6155 (float:DF (fix:DI (match_operand:DF 1 "gpc_reg_operand" "d,wa"))))]
6156 "TARGET_HARD_FLOAT && TARGET_FPRND
6157 && flag_unsafe_math_optimizations && !flag_trapping_math && TARGET_FRIZ"
6158 "@
6159 friz %0,%1
6160 xsrdpiz %x0,%x1"
6161 [(set_attr "type" "fp")])
6162
6163 ;; Opitmize converting SF/DFmode to signed SImode and back to SF/DFmode. This
6164 ;; optimization prevents on ISA 2.06 systems and earlier having to store the
6165 ;; value from the FPR/vector unit to the stack, load the value into a GPR, sign
6166 ;; extend it, store it back on the stack from the GPR, load it back into the
6167 ;; FP/vector unit to do the rounding. If we have direct move (ISA 2.07),
6168 ;; disable using store and load to sign/zero extend the value.
6169 (define_insn_and_split "*round32<mode>2_fprs"
6170 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
6171 (float:SFDF
6172 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
6173 (clobber (match_scratch:DI 2 "=d"))
6174 (clobber (match_scratch:DI 3 "=d"))]
6175 "TARGET_HARD_FLOAT
6176 && <SI_CONVERT_FP> && TARGET_LFIWAX && TARGET_STFIWX && TARGET_FCFID
6177 && !TARGET_DIRECT_MOVE && can_create_pseudo_p ()"
6178 "#"
6179 ""
6180 [(pc)]
6181 {
6182 rtx dest = operands[0];
6183 rtx src = operands[1];
6184 rtx tmp1 = operands[2];
6185 rtx tmp2 = operands[3];
6186 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
6187
6188 if (GET_CODE (tmp1) == SCRATCH)
6189 tmp1 = gen_reg_rtx (DImode);
6190 if (GET_CODE (tmp2) == SCRATCH)
6191 tmp2 = gen_reg_rtx (DImode);
6192
6193 emit_insn (gen_fctiwz_<mode> (tmp1, src));
6194 emit_insn (gen_stfiwx (stack, tmp1));
6195 emit_insn (gen_lfiwax (tmp2, stack));
6196 emit_insn (gen_floatdi<mode>2 (dest, tmp2));
6197 DONE;
6198 }
6199 [(set_attr "type" "fpload")
6200 (set_attr "length" "16")])
6201
6202 (define_insn_and_split "*roundu32<mode>2_fprs"
6203 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
6204 (unsigned_float:SFDF
6205 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
6206 (clobber (match_scratch:DI 2 "=d"))
6207 (clobber (match_scratch:DI 3 "=d"))]
6208 "TARGET_HARD_FLOAT
6209 && TARGET_LFIWZX && TARGET_STFIWX && TARGET_FCFIDU && !TARGET_DIRECT_MOVE
6210 && can_create_pseudo_p ()"
6211 "#"
6212 ""
6213 [(pc)]
6214 {
6215 rtx dest = operands[0];
6216 rtx src = operands[1];
6217 rtx tmp1 = operands[2];
6218 rtx tmp2 = operands[3];
6219 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
6220
6221 if (GET_CODE (tmp1) == SCRATCH)
6222 tmp1 = gen_reg_rtx (DImode);
6223 if (GET_CODE (tmp2) == SCRATCH)
6224 tmp2 = gen_reg_rtx (DImode);
6225
6226 emit_insn (gen_fctiwuz_<mode> (tmp1, src));
6227 emit_insn (gen_stfiwx (stack, tmp1));
6228 emit_insn (gen_lfiwzx (tmp2, stack));
6229 emit_insn (gen_floatdi<mode>2 (dest, tmp2));
6230 DONE;
6231 }
6232 [(set_attr "type" "fpload")
6233 (set_attr "length" "16")])
6234
6235 ;; No VSX equivalent to fctid
6236 (define_insn "lrint<mode>di2"
6237 [(set (match_operand:DI 0 "gpc_reg_operand" "=d")
6238 (unspec:DI [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
6239 UNSPEC_FCTID))]
6240 "TARGET_HARD_FLOAT && TARGET_FPRND"
6241 "fctid %0,%1"
6242 [(set_attr "type" "fp")])
6243
6244 (define_insn "btrunc<mode>2"
6245 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
6246 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
6247 UNSPEC_FRIZ))]
6248 "TARGET_HARD_FLOAT && TARGET_FPRND"
6249 "@
6250 friz %0,%1
6251 xsrdpiz %x0,%x1"
6252 [(set_attr "type" "fp")])
6253
6254 (define_insn "ceil<mode>2"
6255 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
6256 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
6257 UNSPEC_FRIP))]
6258 "TARGET_HARD_FLOAT && TARGET_FPRND"
6259 "@
6260 frip %0,%1
6261 xsrdpip %x0,%x1"
6262 [(set_attr "type" "fp")])
6263
6264 (define_insn "floor<mode>2"
6265 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
6266 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
6267 UNSPEC_FRIM))]
6268 "TARGET_HARD_FLOAT && TARGET_FPRND"
6269 "@
6270 frim %0,%1
6271 xsrdpim %x0,%x1"
6272 [(set_attr "type" "fp")])
6273
6274 ;; No VSX equivalent to frin
6275 (define_insn "round<mode>2"
6276 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<rreg2>")
6277 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
6278 UNSPEC_FRIN))]
6279 "TARGET_HARD_FLOAT && TARGET_FPRND"
6280 "frin %0,%1"
6281 [(set_attr "type" "fp")])
6282
6283 (define_insn "*xsrdpi<mode>2"
6284 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
6285 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Fv>")]
6286 UNSPEC_XSRDPI))]
6287 "TARGET_HARD_FLOAT && TARGET_VSX"
6288 "xsrdpi %x0,%x1"
6289 [(set_attr "type" "fp")])
6290
6291 (define_expand "lround<mode>di2"
6292 [(set (match_dup 2)
6293 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand")]
6294 UNSPEC_XSRDPI))
6295 (set (match_operand:DI 0 "gpc_reg_operand")
6296 (unspec:DI [(match_dup 2)]
6297 UNSPEC_FCTID))]
6298 "TARGET_HARD_FLOAT && TARGET_VSX && TARGET_FPRND"
6299 {
6300 operands[2] = gen_reg_rtx (<MODE>mode);
6301 })
6302
6303 ; An UNSPEC is used so we don't have to support SImode in FP registers.
6304 (define_insn "stfiwx"
6305 [(set (match_operand:SI 0 "memory_operand" "=Z,Z")
6306 (unspec:SI [(match_operand:DI 1 "gpc_reg_operand" "d,wa")]
6307 UNSPEC_STFIWX))]
6308 "TARGET_PPC_GFXOPT"
6309 "@
6310 stfiwx %1,%y0
6311 stxsiwx %x1,%y0"
6312 [(set_attr "type" "fpstore")
6313 (set_attr "isa" "*,p8v")])
6314
6315 ;; If we don't have a direct conversion to single precision, don't enable this
6316 ;; conversion for 32-bit without fast math, because we don't have the insn to
6317 ;; generate the fixup swizzle to avoid double rounding problems.
6318 (define_expand "floatsisf2"
6319 [(set (match_operand:SF 0 "gpc_reg_operand")
6320 (float:SF (match_operand:SI 1 "nonimmediate_operand")))]
6321 "TARGET_HARD_FLOAT
6322 && ((TARGET_FCFIDS && TARGET_LFIWAX)
6323 || (TARGET_FCFID
6324 && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))"
6325 {
6326 if (TARGET_FCFIDS && TARGET_LFIWAX)
6327 {
6328 emit_insn (gen_floatsisf2_lfiwax (operands[0], operands[1]));
6329 DONE;
6330 }
6331 else if (TARGET_FCFID && TARGET_LFIWAX)
6332 {
6333 rtx dfreg = gen_reg_rtx (DFmode);
6334 emit_insn (gen_floatsidf2_lfiwax (dfreg, operands[1]));
6335 emit_insn (gen_truncdfsf2 (operands[0], dfreg));
6336 DONE;
6337 }
6338 else
6339 {
6340 rtx dreg = operands[1];
6341 if (!REG_P (dreg))
6342 dreg = force_reg (SImode, dreg);
6343 dreg = convert_to_mode (DImode, dreg, false);
6344 emit_insn (gen_floatdisf2 (operands[0], dreg));
6345 DONE;
6346 }
6347 })
6348
6349 (define_insn "floatdidf2"
6350 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa")
6351 (float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wa")))]
6352 "TARGET_FCFID && TARGET_HARD_FLOAT"
6353 "@
6354 fcfid %0,%1
6355 xscvsxddp %x0,%x1"
6356 [(set_attr "type" "fp")])
6357
6358 ; Allow the combiner to merge source memory operands to the conversion so that
6359 ; the optimizer/register allocator doesn't try to load the value too early in a
6360 ; GPR and then use store/load to move it to a FPR and suffer from a store-load
6361 ; hit. We will split after reload to avoid the trip through the GPRs
6362
6363 (define_insn_and_split "*floatdidf2_mem"
6364 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa")
6365 (float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
6366 (clobber (match_scratch:DI 2 "=d,wa"))]
6367 "TARGET_HARD_FLOAT && TARGET_FCFID"
6368 "#"
6369 "&& reload_completed"
6370 [(set (match_dup 2) (match_dup 1))
6371 (set (match_dup 0) (float:DF (match_dup 2)))]
6372 ""
6373 [(set_attr "length" "8")
6374 (set_attr "type" "fpload")])
6375
6376 (define_expand "floatunsdidf2"
6377 [(set (match_operand:DF 0 "gpc_reg_operand")
6378 (unsigned_float:DF
6379 (match_operand:DI 1 "gpc_reg_operand")))]
6380 "TARGET_HARD_FLOAT && TARGET_FCFIDU"
6381 "")
6382
6383 (define_insn "*floatunsdidf2_fcfidu"
6384 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa")
6385 (unsigned_float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wa")))]
6386 "TARGET_HARD_FLOAT && TARGET_FCFIDU"
6387 "@
6388 fcfidu %0,%1
6389 xscvuxddp %x0,%x1"
6390 [(set_attr "type" "fp")])
6391
6392 (define_insn_and_split "*floatunsdidf2_mem"
6393 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa")
6394 (unsigned_float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
6395 (clobber (match_scratch:DI 2 "=d,wa"))]
6396 "TARGET_HARD_FLOAT && (TARGET_FCFIDU || VECTOR_UNIT_VSX_P (DFmode))"
6397 "#"
6398 "&& reload_completed"
6399 [(set (match_dup 2) (match_dup 1))
6400 (set (match_dup 0) (unsigned_float:DF (match_dup 2)))]
6401 ""
6402 [(set_attr "length" "8")
6403 (set_attr "type" "fpload")])
6404
6405 (define_expand "floatdisf2"
6406 [(set (match_operand:SF 0 "gpc_reg_operand")
6407 (float:SF (match_operand:DI 1 "gpc_reg_operand")))]
6408 "TARGET_FCFID && TARGET_HARD_FLOAT
6409 && (TARGET_FCFIDS || TARGET_POWERPC64 || flag_unsafe_math_optimizations)"
6410 {
6411 if (!TARGET_FCFIDS)
6412 {
6413 rtx val = operands[1];
6414 if (!flag_unsafe_math_optimizations)
6415 {
6416 rtx label = gen_label_rtx ();
6417 val = gen_reg_rtx (DImode);
6418 emit_insn (gen_floatdisf2_internal2 (val, operands[1], label));
6419 emit_label (label);
6420 }
6421 emit_insn (gen_floatdisf2_internal1 (operands[0], val));
6422 DONE;
6423 }
6424 })
6425
6426 (define_insn "floatdisf2_fcfids"
6427 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wa")
6428 (float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wa")))]
6429 "TARGET_HARD_FLOAT && TARGET_FCFIDS"
6430 "@
6431 fcfids %0,%1
6432 xscvsxdsp %x0,%x1"
6433 [(set_attr "type" "fp")
6434 (set_attr "isa" "*,p8v")])
6435
6436 (define_insn_and_split "*floatdisf2_mem"
6437 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wa,wa")
6438 (float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
6439 (clobber (match_scratch:DI 2 "=d,d,wa"))]
6440 "TARGET_HARD_FLOAT && TARGET_FCFIDS"
6441 "#"
6442 "&& reload_completed"
6443 [(pc)]
6444 {
6445 emit_move_insn (operands[2], operands[1]);
6446 emit_insn (gen_floatdisf2_fcfids (operands[0], operands[2]));
6447 DONE;
6448 }
6449 [(set_attr "length" "8")
6450 (set_attr "isa" "*,p8v,p8v")])
6451
6452 ;; This is not IEEE compliant if rounding mode is "round to nearest".
6453 ;; If the DI->DF conversion is inexact, then it's possible to suffer
6454 ;; from double rounding.
6455 ;; Instead of creating a new cpu type for two FP operations, just use fp
6456 (define_insn_and_split "floatdisf2_internal1"
6457 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
6458 (float:SF (match_operand:DI 1 "gpc_reg_operand" "d")))
6459 (clobber (match_scratch:DF 2 "=d"))]
6460 "TARGET_FCFID && TARGET_HARD_FLOAT && !TARGET_FCFIDS"
6461 "#"
6462 "&& reload_completed"
6463 [(set (match_dup 2)
6464 (float:DF (match_dup 1)))
6465 (set (match_dup 0)
6466 (float_truncate:SF (match_dup 2)))]
6467 ""
6468 [(set_attr "length" "8")
6469 (set_attr "type" "fp")])
6470
6471 ;; Twiddles bits to avoid double rounding.
6472 ;; Bits that might be truncated when converting to DFmode are replaced
6473 ;; by a bit that won't be lost at that stage, but is below the SFmode
6474 ;; rounding position.
6475 (define_expand "floatdisf2_internal2"
6476 [(parallel [(set (match_dup 3) (ashiftrt:DI (match_operand:DI 1 "")
6477 (const_int 53)))
6478 (clobber (reg:DI CA_REGNO))])
6479 (set (match_operand:DI 0 "") (and:DI (match_dup 1)
6480 (const_int 2047)))
6481 (set (match_dup 3) (plus:DI (match_dup 3)
6482 (const_int 1)))
6483 (set (match_dup 0) (plus:DI (match_dup 0)
6484 (const_int 2047)))
6485 (set (match_dup 4) (compare:CCUNS (match_dup 3)
6486 (const_int 2)))
6487 (set (match_dup 0) (ior:DI (match_dup 0)
6488 (match_dup 1)))
6489 (set (match_dup 0) (and:DI (match_dup 0)
6490 (const_int -2048)))
6491 (set (pc) (if_then_else (geu (match_dup 4) (const_int 0))
6492 (label_ref (match_operand:DI 2 ""))
6493 (pc)))
6494 (set (match_dup 0) (match_dup 1))]
6495 "TARGET_POWERPC64 && TARGET_HARD_FLOAT && !TARGET_FCFIDS"
6496 {
6497 operands[3] = gen_reg_rtx (DImode);
6498 operands[4] = gen_reg_rtx (CCUNSmode);
6499 })
6500
6501 (define_expand "floatunsdisf2"
6502 [(set (match_operand:SF 0 "gpc_reg_operand")
6503 (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand")))]
6504 "TARGET_HARD_FLOAT && TARGET_FCFIDUS"
6505 "")
6506
6507 (define_insn "floatunsdisf2_fcfidus"
6508 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wa")
6509 (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wa")))]
6510 "TARGET_HARD_FLOAT && TARGET_FCFIDUS"
6511 "@
6512 fcfidus %0,%1
6513 xscvuxdsp %x0,%x1"
6514 [(set_attr "type" "fp")
6515 (set_attr "isa" "*,p8v")])
6516
6517 (define_insn_and_split "*floatunsdisf2_mem"
6518 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wa,wa")
6519 (unsigned_float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
6520 (clobber (match_scratch:DI 2 "=d,d,wa"))]
6521 "TARGET_HARD_FLOAT && TARGET_FCFIDUS"
6522 "#"
6523 "&& reload_completed"
6524 [(pc)]
6525 {
6526 emit_move_insn (operands[2], operands[1]);
6527 emit_insn (gen_floatunsdisf2_fcfidus (operands[0], operands[2]));
6528 DONE;
6529 }
6530 [(set_attr "type" "fpload")
6531 (set_attr "length" "8")
6532 (set_attr "isa" "*,p8v,p8v")])
6533 \f
6534 ;; Define the TImode operations that can be done in a small number
6535 ;; of instructions. The & constraints are to prevent the register
6536 ;; allocator from allocating registers that overlap with the inputs
6537 ;; (for example, having an input in 7,8 and an output in 6,7). We
6538 ;; also allow for the output being the same as one of the inputs.
6539
6540 (define_expand "addti3"
6541 [(set (match_operand:TI 0 "gpc_reg_operand")
6542 (plus:TI (match_operand:TI 1 "gpc_reg_operand")
6543 (match_operand:TI 2 "reg_or_short_operand")))]
6544 "TARGET_64BIT"
6545 {
6546 rtx lo0 = gen_lowpart (DImode, operands[0]);
6547 rtx lo1 = gen_lowpart (DImode, operands[1]);
6548 rtx lo2 = gen_lowpart (DImode, operands[2]);
6549 rtx hi0 = gen_highpart (DImode, operands[0]);
6550 rtx hi1 = gen_highpart (DImode, operands[1]);
6551 rtx hi2 = gen_highpart_mode (DImode, TImode, operands[2]);
6552
6553 if (!reg_or_short_operand (lo2, DImode))
6554 lo2 = force_reg (DImode, lo2);
6555 if (!adde_operand (hi2, DImode))
6556 hi2 = force_reg (DImode, hi2);
6557
6558 emit_insn (gen_adddi3_carry (lo0, lo1, lo2));
6559 emit_insn (gen_adddi3_carry_in (hi0, hi1, hi2));
6560 DONE;
6561 })
6562
6563 (define_expand "subti3"
6564 [(set (match_operand:TI 0 "gpc_reg_operand")
6565 (minus:TI (match_operand:TI 1 "reg_or_short_operand")
6566 (match_operand:TI 2 "gpc_reg_operand")))]
6567 "TARGET_64BIT"
6568 {
6569 rtx lo0 = gen_lowpart (DImode, operands[0]);
6570 rtx lo1 = gen_lowpart (DImode, operands[1]);
6571 rtx lo2 = gen_lowpart (DImode, operands[2]);
6572 rtx hi0 = gen_highpart (DImode, operands[0]);
6573 rtx hi1 = gen_highpart_mode (DImode, TImode, operands[1]);
6574 rtx hi2 = gen_highpart (DImode, operands[2]);
6575
6576 if (!reg_or_short_operand (lo1, DImode))
6577 lo1 = force_reg (DImode, lo1);
6578 if (!adde_operand (hi1, DImode))
6579 hi1 = force_reg (DImode, hi1);
6580
6581 emit_insn (gen_subfdi3_carry (lo0, lo2, lo1));
6582 emit_insn (gen_subfdi3_carry_in (hi0, hi2, hi1));
6583 DONE;
6584 })
6585 \f
6586 ;; 128-bit logical operations expanders
6587
6588 (define_expand "and<mode>3"
6589 [(set (match_operand:BOOL_128 0 "vlogical_operand")
6590 (and:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")
6591 (match_operand:BOOL_128 2 "vlogical_operand")))]
6592 ""
6593 "")
6594
6595 (define_expand "ior<mode>3"
6596 [(set (match_operand:BOOL_128 0 "vlogical_operand")
6597 (ior:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")
6598 (match_operand:BOOL_128 2 "vlogical_operand")))]
6599 ""
6600 "")
6601
6602 (define_expand "xor<mode>3"
6603 [(set (match_operand:BOOL_128 0 "vlogical_operand")
6604 (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")
6605 (match_operand:BOOL_128 2 "vlogical_operand")))]
6606 ""
6607 "")
6608
6609 (define_expand "nor<mode>3"
6610 [(set (match_operand:BOOL_128 0 "vlogical_operand")
6611 (and:BOOL_128
6612 (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand"))
6613 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))))]
6614 ""
6615 "")
6616
6617 (define_expand "andc<mode>3"
6618 [(set (match_operand:BOOL_128 0 "vlogical_operand")
6619 (and:BOOL_128
6620 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))
6621 (match_operand:BOOL_128 1 "vlogical_operand")))]
6622 ""
6623 "")
6624
6625 ;; Power8 vector logical instructions.
6626 (define_expand "eqv<mode>3"
6627 [(set (match_operand:BOOL_128 0 "vlogical_operand")
6628 (not:BOOL_128
6629 (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")
6630 (match_operand:BOOL_128 2 "vlogical_operand"))))]
6631 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6632 "")
6633
6634 ;; Rewrite nand into canonical form
6635 (define_expand "nand<mode>3"
6636 [(set (match_operand:BOOL_128 0 "vlogical_operand")
6637 (ior:BOOL_128
6638 (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand"))
6639 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))))]
6640 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6641 "")
6642
6643 ;; The canonical form is to have the negated element first, so we need to
6644 ;; reverse arguments.
6645 (define_expand "orc<mode>3"
6646 [(set (match_operand:BOOL_128 0 "vlogical_operand")
6647 (ior:BOOL_128
6648 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))
6649 (match_operand:BOOL_128 1 "vlogical_operand")))]
6650 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6651 "")
6652
6653 ;; 128-bit logical operations insns and split operations
6654 (define_insn_and_split "*and<mode>3_internal"
6655 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6656 (and:BOOL_128
6657 (match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
6658 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")))]
6659 ""
6660 {
6661 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6662 return "xxland %x0,%x1,%x2";
6663
6664 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6665 return "vand %0,%1,%2";
6666
6667 return "#";
6668 }
6669 "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6670 [(const_int 0)]
6671 {
6672 rs6000_split_logical (operands, AND, false, false, false);
6673 DONE;
6674 }
6675 [(set (attr "type")
6676 (if_then_else
6677 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6678 (const_string "veclogical")
6679 (const_string "integer")))
6680 (set (attr "length")
6681 (if_then_else
6682 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6683 (const_string "4")
6684 (if_then_else
6685 (match_test "TARGET_POWERPC64")
6686 (const_string "8")
6687 (const_string "16"))))])
6688
6689 ;; 128-bit IOR/XOR
6690 (define_insn_and_split "*bool<mode>3_internal"
6691 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6692 (match_operator:BOOL_128 3 "boolean_or_operator"
6693 [(match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
6694 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")]))]
6695 ""
6696 {
6697 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6698 return "xxl%q3 %x0,%x1,%x2";
6699
6700 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6701 return "v%q3 %0,%1,%2";
6702
6703 return "#";
6704 }
6705 "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6706 [(const_int 0)]
6707 {
6708 rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, false);
6709 DONE;
6710 }
6711 [(set (attr "type")
6712 (if_then_else
6713 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6714 (const_string "veclogical")
6715 (const_string "integer")))
6716 (set (attr "length")
6717 (if_then_else
6718 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6719 (const_string "4")
6720 (if_then_else
6721 (match_test "TARGET_POWERPC64")
6722 (const_string "8")
6723 (const_string "16"))))])
6724
6725 ;; 128-bit ANDC/ORC
6726 (define_insn_and_split "*boolc<mode>3_internal1"
6727 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6728 (match_operator:BOOL_128 3 "boolean_operator"
6729 [(not:BOOL_128
6730 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))
6731 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")]))]
6732 "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
6733 {
6734 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6735 return "xxl%q3 %x0,%x1,%x2";
6736
6737 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6738 return "v%q3 %0,%1,%2";
6739
6740 return "#";
6741 }
6742 "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
6743 && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6744 [(const_int 0)]
6745 {
6746 rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
6747 DONE;
6748 }
6749 [(set (attr "type")
6750 (if_then_else
6751 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6752 (const_string "veclogical")
6753 (const_string "integer")))
6754 (set (attr "length")
6755 (if_then_else
6756 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6757 (const_string "4")
6758 (if_then_else
6759 (match_test "TARGET_POWERPC64")
6760 (const_string "8")
6761 (const_string "16"))))])
6762
6763 (define_insn_and_split "*boolc<mode>3_internal2"
6764 [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6765 (match_operator:TI2 3 "boolean_operator"
6766 [(not:TI2
6767 (match_operand:TI2 2 "int_reg_operand" "r,0,r"))
6768 (match_operand:TI2 1 "int_reg_operand" "r,r,0")]))]
6769 "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6770 "#"
6771 "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6772 [(const_int 0)]
6773 {
6774 rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
6775 DONE;
6776 }
6777 [(set_attr "type" "integer")
6778 (set (attr "length")
6779 (if_then_else
6780 (match_test "TARGET_POWERPC64")
6781 (const_string "8")
6782 (const_string "16")))])
6783
6784 ;; 128-bit NAND/NOR
6785 (define_insn_and_split "*boolcc<mode>3_internal1"
6786 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6787 (match_operator:BOOL_128 3 "boolean_operator"
6788 [(not:BOOL_128
6789 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>"))
6790 (not:BOOL_128
6791 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))]))]
6792 "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
6793 {
6794 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6795 return "xxl%q3 %x0,%x1,%x2";
6796
6797 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6798 return "v%q3 %0,%1,%2";
6799
6800 return "#";
6801 }
6802 "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
6803 && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6804 [(const_int 0)]
6805 {
6806 rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
6807 DONE;
6808 }
6809 [(set (attr "type")
6810 (if_then_else
6811 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6812 (const_string "veclogical")
6813 (const_string "integer")))
6814 (set (attr "length")
6815 (if_then_else
6816 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6817 (const_string "4")
6818 (if_then_else
6819 (match_test "TARGET_POWERPC64")
6820 (const_string "8")
6821 (const_string "16"))))])
6822
6823 (define_insn_and_split "*boolcc<mode>3_internal2"
6824 [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6825 (match_operator:TI2 3 "boolean_operator"
6826 [(not:TI2
6827 (match_operand:TI2 1 "int_reg_operand" "r,0,r"))
6828 (not:TI2
6829 (match_operand:TI2 2 "int_reg_operand" "r,r,0"))]))]
6830 "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6831 "#"
6832 "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6833 [(const_int 0)]
6834 {
6835 rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
6836 DONE;
6837 }
6838 [(set_attr "type" "integer")
6839 (set (attr "length")
6840 (if_then_else
6841 (match_test "TARGET_POWERPC64")
6842 (const_string "8")
6843 (const_string "16")))])
6844
6845
6846 ;; 128-bit EQV
6847 (define_insn_and_split "*eqv<mode>3_internal1"
6848 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6849 (not:BOOL_128
6850 (xor:BOOL_128
6851 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")
6852 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))))]
6853 "TARGET_P8_VECTOR"
6854 {
6855 if (vsx_register_operand (operands[0], <MODE>mode))
6856 return "xxleqv %x0,%x1,%x2";
6857
6858 return "#";
6859 }
6860 "TARGET_P8_VECTOR && reload_completed
6861 && int_reg_operand (operands[0], <MODE>mode)"
6862 [(const_int 0)]
6863 {
6864 rs6000_split_logical (operands, XOR, true, false, false);
6865 DONE;
6866 }
6867 [(set (attr "type")
6868 (if_then_else
6869 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6870 (const_string "veclogical")
6871 (const_string "integer")))
6872 (set (attr "length")
6873 (if_then_else
6874 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6875 (const_string "4")
6876 (if_then_else
6877 (match_test "TARGET_POWERPC64")
6878 (const_string "8")
6879 (const_string "16"))))])
6880
6881 (define_insn_and_split "*eqv<mode>3_internal2"
6882 [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6883 (not:TI2
6884 (xor:TI2
6885 (match_operand:TI2 1 "int_reg_operand" "r,0,r")
6886 (match_operand:TI2 2 "int_reg_operand" "r,r,0"))))]
6887 "!TARGET_P8_VECTOR"
6888 "#"
6889 "reload_completed && !TARGET_P8_VECTOR"
6890 [(const_int 0)]
6891 {
6892 rs6000_split_logical (operands, XOR, true, false, false);
6893 DONE;
6894 }
6895 [(set_attr "type" "integer")
6896 (set (attr "length")
6897 (if_then_else
6898 (match_test "TARGET_POWERPC64")
6899 (const_string "8")
6900 (const_string "16")))])
6901
6902 ;; 128-bit one's complement
6903 (define_insn_and_split "one_cmpl<mode>2"
6904 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6905 (not:BOOL_128
6906 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_UNARY>")))]
6907 ""
6908 {
6909 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6910 return "xxlnor %x0,%x1,%x1";
6911
6912 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6913 return "vnor %0,%1,%1";
6914
6915 return "#";
6916 }
6917 "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6918 [(const_int 0)]
6919 {
6920 rs6000_split_logical (operands, NOT, false, false, false);
6921 DONE;
6922 }
6923 [(set (attr "type")
6924 (if_then_else
6925 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6926 (const_string "veclogical")
6927 (const_string "integer")))
6928 (set (attr "length")
6929 (if_then_else
6930 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6931 (const_string "4")
6932 (if_then_else
6933 (match_test "TARGET_POWERPC64")
6934 (const_string "8")
6935 (const_string "16"))))])
6936
6937 \f
6938 ;; Now define ways of moving data around.
6939
6940 ;; Set up a register with a value from the GOT table
6941
6942 (define_expand "movsi_got"
6943 [(set (match_operand:SI 0 "gpc_reg_operand")
6944 (unspec:SI [(match_operand:SI 1 "got_operand")
6945 (match_dup 2)] UNSPEC_MOVSI_GOT))]
6946 "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
6947 {
6948 if (GET_CODE (operands[1]) == CONST)
6949 {
6950 rtx offset = const0_rtx;
6951 HOST_WIDE_INT value;
6952
6953 operands[1] = eliminate_constant_term (XEXP (operands[1], 0), &offset);
6954 value = INTVAL (offset);
6955 if (value != 0)
6956 {
6957 rtx tmp = (!can_create_pseudo_p ()
6958 ? operands[0]
6959 : gen_reg_rtx (Pmode));
6960 emit_insn (gen_movsi_got (tmp, operands[1]));
6961 emit_insn (gen_addsi3 (operands[0], tmp, offset));
6962 DONE;
6963 }
6964 }
6965
6966 operands[2] = rs6000_got_register (operands[1]);
6967 })
6968
6969 (define_insn "*movsi_got_internal"
6970 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6971 (unspec:SI [(match_operand:SI 1 "got_no_const_operand" "")
6972 (match_operand:SI 2 "gpc_reg_operand" "b")]
6973 UNSPEC_MOVSI_GOT))]
6974 "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
6975 "lwz %0,%a1@got(%2)"
6976 [(set_attr "type" "load")])
6977
6978 ;; Used by sched, shorten_branches and final when the GOT pseudo reg
6979 ;; didn't get allocated to a hard register.
6980 (define_split
6981 [(set (match_operand:SI 0 "gpc_reg_operand")
6982 (unspec:SI [(match_operand:SI 1 "got_no_const_operand")
6983 (match_operand:SI 2 "memory_operand")]
6984 UNSPEC_MOVSI_GOT))]
6985 "DEFAULT_ABI == ABI_V4
6986 && flag_pic == 1
6987 && reload_completed"
6988 [(set (match_dup 0) (match_dup 2))
6989 (set (match_dup 0) (unspec:SI [(match_dup 1)(match_dup 0)]
6990 UNSPEC_MOVSI_GOT))]
6991 "")
6992
6993 ;; MR LA
6994 ;; LWZ LFIWZX LXSIWZX
6995 ;; STW STFIWX STXSIWX
6996 ;; LI LIS PLI #
6997 ;; XXLOR XXSPLTIB 0 XXSPLTIB -1 VSPLTISW
6998 ;; XXLXOR 0 XXLORC -1 P9 const
6999 ;; MTVSRWZ MFVSRWZ
7000 ;; MF%1 MT%0 NOP
7001
7002 (define_insn "*movsi_internal1"
7003 [(set (match_operand:SI 0 "nonimmediate_operand"
7004 "=r, r,
7005 r, d, v,
7006 m, Z, Z,
7007 r, r, r, r,
7008 wa, wa, wa, v,
7009 wa, v, v,
7010 wa, r,
7011 r, *h, *h")
7012 (match_operand:SI 1 "input_operand"
7013 "r, U,
7014 m, Z, Z,
7015 r, d, v,
7016 I, L, eI, n,
7017 wa, O, wM, wB,
7018 O, wM, wS,
7019 r, wa,
7020 *h, r, 0"))]
7021 "gpc_reg_operand (operands[0], SImode)
7022 || gpc_reg_operand (operands[1], SImode)"
7023 "@
7024 mr %0,%1
7025 la %0,%a1
7026 lwz%U1%X1 %0,%1
7027 lfiwzx %0,%y1
7028 lxsiwzx %x0,%y1
7029 stw%U0%X0 %1,%0
7030 stfiwx %1,%y0
7031 stxsiwx %x1,%y0
7032 li %0,%1
7033 lis %0,%v1
7034 li %0,%1
7035 #
7036 xxlor %x0,%x1,%x1
7037 xxspltib %x0,0
7038 xxspltib %x0,255
7039 vspltisw %0,%1
7040 xxlxor %x0,%x0,%x0
7041 xxlorc %x0,%x0,%x0
7042 #
7043 mtvsrwz %x0,%1
7044 mfvsrwz %0,%x1
7045 mf%1 %0
7046 mt%0 %1
7047 nop"
7048 [(set_attr "type"
7049 "*, *,
7050 load, fpload, fpload,
7051 store, fpstore, fpstore,
7052 *, *, *, *,
7053 veclogical, vecsimple, vecsimple, vecsimple,
7054 veclogical, veclogical, vecsimple,
7055 mffgpr, mftgpr,
7056 *, *, *")
7057 (set_attr "length"
7058 "*, *,
7059 *, *, *,
7060 *, *, *,
7061 *, *, *, 8,
7062 *, *, *, *,
7063 *, *, 8,
7064 *, *,
7065 *, *, *")
7066 (set_attr "isa"
7067 "*, *,
7068 *, p8v, p8v,
7069 *, p8v, p8v,
7070 *, *, p10, *,
7071 p8v, p9v, p9v, p8v,
7072 p9v, p8v, p9v,
7073 p8v, p8v,
7074 *, *, *")])
7075
7076 ;; Like movsi, but adjust a SF value to be used in a SI context, i.e.
7077 ;; (set (reg:SI ...) (subreg:SI (reg:SF ...) 0))
7078 ;;
7079 ;; Because SF values are actually stored as DF values within the vector
7080 ;; registers, we need to convert the value to the vector SF format when
7081 ;; we need to use the bits in a union or similar cases. We only need
7082 ;; to do this transformation when the value is a vector register. Loads,
7083 ;; stores, and transfers within GPRs are assumed to be safe.
7084 ;;
7085 ;; This is a more general case of reload_gpr_from_vsxsf. That insn must have
7086 ;; no alternatives, because the call is created as part of secondary_reload,
7087 ;; and operand #2's register class is used to allocate the temporary register.
7088 ;; This function is called before reload, and it creates the temporary as
7089 ;; needed.
7090
7091 ;; MR LWZ LFIWZX LXSIWZX STW
7092 ;; STFS STXSSP STXSSPX VSX->GPR VSX->VSX
7093 ;; MTVSRWZ
7094
7095 (define_insn_and_split "movsi_from_sf"
7096 [(set (match_operand:SI 0 "nonimmediate_operand"
7097 "=r, r, ?*d, ?*v, m,
7098 m, wY, Z, r, ?*wa,
7099 wa")
7100 (unspec:SI [(match_operand:SF 1 "input_operand"
7101 "r, m, Z, Z, r,
7102 f, v, wa, wa, wa,
7103 r")]
7104 UNSPEC_SI_FROM_SF))
7105 (clobber (match_scratch:V4SF 2
7106 "=X, X, X, X, X,
7107 X, X, X, wa, X,
7108 X"))]
7109 "TARGET_NO_SF_SUBREG
7110 && (register_operand (operands[0], SImode)
7111 || register_operand (operands[1], SFmode))"
7112 "@
7113 mr %0,%1
7114 lwz%U1%X1 %0,%1
7115 lfiwzx %0,%y1
7116 lxsiwzx %x0,%y1
7117 stw%U0%X0 %1,%0
7118 stfs%U0%X0 %1,%0
7119 stxssp %1,%0
7120 stxsspx %x1,%y0
7121 #
7122 xscvdpspn %x0,%x1
7123 mtvsrwz %x0,%1"
7124 "&& reload_completed
7125 && int_reg_operand (operands[0], SImode)
7126 && vsx_reg_sfsubreg_ok (operands[1], SFmode)"
7127 [(const_int 0)]
7128 {
7129 rtx op0 = operands[0];
7130 rtx op1 = operands[1];
7131 rtx op2 = operands[2];
7132 rtx op0_di = gen_rtx_REG (DImode, reg_or_subregno (op0));
7133 rtx op2_si = gen_rtx_REG (SImode, reg_or_subregno (op2));
7134
7135 emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
7136 emit_insn (gen_zero_extendsidi2 (op0_di, op2_si));
7137 DONE;
7138 }
7139 [(set_attr "type"
7140 "*, load, fpload, fpload, store,
7141 fpstore, fpstore, fpstore, mftgpr, fp,
7142 mffgpr")
7143 (set_attr "length"
7144 "*, *, *, *, *,
7145 *, *, *, 8, *,
7146 *")
7147 (set_attr "isa"
7148 "*, *, p8v, p8v, *,
7149 *, p9v, p8v, p8v, p8v,
7150 p8v")])
7151
7152 ;; movsi_from_sf with zero extension
7153 ;;
7154 ;; RLDICL LWZ LFIWZX LXSIWZX VSX->GPR
7155 ;; VSX->VSX MTVSRWZ
7156
7157 (define_insn_and_split "*movdi_from_sf_zero_ext"
7158 [(set (match_operand:DI 0 "gpc_reg_operand"
7159 "=r, r, ?*d, ?*v, r,
7160 ?v, wa")
7161 (zero_extend:DI
7162 (unspec:SI [(match_operand:SF 1 "input_operand"
7163 "r, m, Z, Z, wa,
7164 wa, r")]
7165 UNSPEC_SI_FROM_SF)))
7166 (clobber (match_scratch:V4SF 2
7167 "=X, X, X, X, wa,
7168 wa, X"))]
7169 "TARGET_DIRECT_MOVE_64BIT
7170 && (register_operand (operands[0], DImode)
7171 || register_operand (operands[1], SImode))"
7172 "@
7173 rldicl %0,%1,0,32
7174 lwz%U1%X1 %0,%1
7175 lfiwzx %0,%y1
7176 lxsiwzx %x0,%y1
7177 #
7178 #
7179 mtvsrwz %x0,%1"
7180 "&& reload_completed
7181 && register_operand (operands[0], DImode)
7182 && vsx_reg_sfsubreg_ok (operands[1], SFmode)"
7183 [(const_int 0)]
7184 {
7185 rtx op0 = operands[0];
7186 rtx op1 = operands[1];
7187 rtx op2 = operands[2];
7188 rtx op2_si = gen_rtx_REG (SImode, reg_or_subregno (op2));
7189
7190 emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
7191 emit_insn (gen_zero_extendsidi2 (op0, op2_si));
7192 DONE;
7193 }
7194 [(set_attr "type"
7195 "*, load, fpload, fpload, two,
7196 two, mffgpr")
7197 (set_attr "length"
7198 "*, *, *, *, 8,
7199 8, *")
7200 (set_attr "isa"
7201 "*, *, p8v, p8v, p8v,
7202 p9v, p8v")])
7203
7204 ;; Like movsi_from_sf, but combine a convert from DFmode to SFmode before
7205 ;; moving it to SImode. We cannot do a SFmode store without having to do the
7206 ;; conversion explicitly since that doesn't work in most cases if the input
7207 ;; isn't representable as SF. Use XSCVDPSP instead of XSCVDPSPN, since the
7208 ;; former handles cases where the input will not fit in a SFmode, and the
7209 ;; latter assumes the value has already been rounded.
7210 (define_insn "*movsi_from_df"
7211 [(set (match_operand:SI 0 "gpc_reg_operand" "=wa")
7212 (unspec:SI [(float_truncate:SF
7213 (match_operand:DF 1 "gpc_reg_operand" "wa"))]
7214 UNSPEC_SI_FROM_SF))]
7215 "TARGET_NO_SF_SUBREG"
7216 "xscvdpsp %x0,%x1"
7217 [(set_attr "type" "fp")])
7218
7219 ;; Split a load of a large constant into the appropriate two-insn
7220 ;; sequence.
7221
7222 (define_split
7223 [(set (match_operand:SI 0 "gpc_reg_operand")
7224 (match_operand:SI 1 "const_int_operand"))]
7225 "num_insns_constant (operands[1], SImode) > 1"
7226 [(set (match_dup 0)
7227 (match_dup 2))
7228 (set (match_dup 0)
7229 (ior:SI (match_dup 0)
7230 (match_dup 3)))]
7231 {
7232 if (rs6000_emit_set_const (operands[0], operands[1]))
7233 DONE;
7234 else
7235 FAIL;
7236 })
7237
7238 ;; Split loading -128..127 to use XXSPLITB and VEXTSW2D
7239 (define_split
7240 [(set (match_operand:DI 0 "altivec_register_operand")
7241 (match_operand:DI 1 "xxspltib_constant_split"))]
7242 "TARGET_P9_VECTOR && reload_completed"
7243 [(const_int 0)]
7244 {
7245 rtx op0 = operands[0];
7246 rtx op1 = operands[1];
7247 int r = REGNO (op0);
7248 rtx op0_v16qi = gen_rtx_REG (V16QImode, r);
7249
7250 emit_insn (gen_xxspltib_v16qi (op0_v16qi, op1));
7251 emit_insn (gen_vsx_sign_extend_qi_si (operands[0], op0_v16qi));
7252 DONE;
7253 })
7254
7255 (define_insn "*mov<mode>_internal2"
7256 [(set (match_operand:CC 2 "cc_reg_operand" "=y,x,?y")
7257 (compare:CC (match_operand:P 1 "gpc_reg_operand" "0,r,r")
7258 (const_int 0)))
7259 (set (match_operand:P 0 "gpc_reg_operand" "=r,r,r") (match_dup 1))]
7260 ""
7261 "@
7262 cmp<wd>i %2,%0,0
7263 mr. %0,%1
7264 #"
7265 [(set_attr "type" "cmp,logical,cmp")
7266 (set_attr "dot" "yes")
7267 (set_attr "length" "4,4,8")])
7268
7269 (define_split
7270 [(set (match_operand:CC 2 "cc_reg_not_cr0_operand")
7271 (compare:CC (match_operand:P 1 "gpc_reg_operand")
7272 (const_int 0)))
7273 (set (match_operand:P 0 "gpc_reg_operand") (match_dup 1))]
7274 "reload_completed"
7275 [(set (match_dup 0) (match_dup 1))
7276 (set (match_dup 2)
7277 (compare:CC (match_dup 0)
7278 (const_int 0)))]
7279 "")
7280 \f
7281 (define_expand "mov<mode>"
7282 [(set (match_operand:INT 0 "general_operand")
7283 (match_operand:INT 1 "any_operand"))]
7284 ""
7285 {
7286 rs6000_emit_move (operands[0], operands[1], <MODE>mode);
7287 DONE;
7288 })
7289
7290 ;; MR LHZ/LBZ LXSI*ZX STH/STB STXSI*X LI
7291 ;; XXLOR load 0 load -1 VSPLTI* # MFVSRWZ
7292 ;; MTVSRWZ MF%1 MT%1 NOP
7293 (define_insn "*mov<mode>_internal"
7294 [(set (match_operand:QHI 0 "nonimmediate_operand"
7295 "=r, r, wa, m, Z, r,
7296 wa, wa, wa, v, ?v, r,
7297 wa, r, *c*l, *h")
7298 (match_operand:QHI 1 "input_operand"
7299 "r, m, Z, r, wa, i,
7300 wa, O, wM, wB, wS, wa,
7301 r, *h, r, 0"))]
7302 "gpc_reg_operand (operands[0], <MODE>mode)
7303 || gpc_reg_operand (operands[1], <MODE>mode)"
7304 "@
7305 mr %0,%1
7306 l<wd>z%U1%X1 %0,%1
7307 lxsi<wd>zx %x0,%y1
7308 st<wd>%U0%X0 %1,%0
7309 stxsi<wd>x %x1,%y0
7310 li %0,%1
7311 xxlor %x0,%x1,%x1
7312 xxspltib %x0,0
7313 xxspltib %x0,255
7314 vspltis<wd> %0,%1
7315 #
7316 mfvsrwz %0,%x1
7317 mtvsrwz %x0,%1
7318 mf%1 %0
7319 mt%0 %1
7320 nop"
7321 [(set_attr "type"
7322 "*, load, fpload, store, fpstore, *,
7323 vecsimple, vecperm, vecperm, vecperm, vecperm, mftgpr,
7324 mffgpr, mfjmpr, mtjmpr, *")
7325 (set_attr "length"
7326 "*, *, *, *, *, *,
7327 *, *, *, *, 8, *,
7328 *, *, *, *")
7329 (set_attr "isa"
7330 "*, *, p9v, *, p9v, *,
7331 p9v, p9v, p9v, p9v, p9v, p9v,
7332 p9v, *, *, *")])
7333
7334 \f
7335 ;; Here is how to move condition codes around. When we store CC data in
7336 ;; an integer register or memory, we store just the high-order 4 bits.
7337 ;; This lets us not shift in the most common case of CR0.
7338 (define_expand "movcc"
7339 [(set (match_operand:CC 0 "nonimmediate_operand")
7340 (match_operand:CC 1 "nonimmediate_operand"))]
7341 ""
7342 "")
7343
7344 (define_mode_iterator CC_any [CC CCUNS CCEQ CCFP])
7345
7346 (define_insn "*movcc_<mode>"
7347 [(set (match_operand:CC_any 0 "nonimmediate_operand"
7348 "=y,x,?y,y,r,r,r,r, r,*c*l,r,m")
7349 (match_operand:CC_any 1 "general_operand"
7350 " y,r, r,O,x,y,r,I,*h, r,m,r"))]
7351 "register_operand (operands[0], <MODE>mode)
7352 || register_operand (operands[1], <MODE>mode)"
7353 "@
7354 mcrf %0,%1
7355 mtcrf 128,%1
7356 rlwinm %1,%1,%F0,0xffffffff\;mtcrf %R0,%1\;rlwinm %1,%1,%f0,0xffffffff
7357 crxor %0,%0,%0
7358 mfcr %0%Q1
7359 mfcr %0%Q1\;rlwinm %0,%0,%f1,0xf0000000
7360 mr %0,%1
7361 li %0,%1
7362 mf%1 %0
7363 mt%0 %1
7364 lwz%U1%X1 %0,%1
7365 stw%U0%X0 %1,%0"
7366 [(set_attr_alternative "type"
7367 [(const_string "cr_logical")
7368 (const_string "mtcr")
7369 (const_string "mtcr")
7370 (const_string "cr_logical")
7371 (if_then_else (match_test "TARGET_MFCRF")
7372 (const_string "mfcrf") (const_string "mfcr"))
7373 (if_then_else (match_test "TARGET_MFCRF")
7374 (const_string "mfcrf") (const_string "mfcr"))
7375 (const_string "integer")
7376 (const_string "integer")
7377 (const_string "mfjmpr")
7378 (const_string "mtjmpr")
7379 (const_string "load")
7380 (const_string "store")])
7381 (set_attr "length" "*,*,12,*,*,8,*,*,*,*,*,*")])
7382 \f
7383 ;; For floating-point, we normally deal with the floating-point registers
7384 ;; unless -msoft-float is used. The sole exception is that parameter passing
7385 ;; can produce floating-point values in fixed-point registers. Unless the
7386 ;; value is a simple constant or already in memory, we deal with this by
7387 ;; allocating memory and copying the value explicitly via that memory location.
7388
7389 ;; Move 32-bit binary/decimal floating point
7390 (define_expand "mov<mode>"
7391 [(set (match_operand:FMOVE32 0 "nonimmediate_operand")
7392 (match_operand:FMOVE32 1 "any_operand"))]
7393 "<fmove_ok>"
7394 {
7395 rs6000_emit_move (operands[0], operands[1], <MODE>mode);
7396 DONE;
7397 })
7398
7399 (define_split
7400 [(set (match_operand:FMOVE32 0 "gpc_reg_operand")
7401 (match_operand:FMOVE32 1 "const_double_operand"))]
7402 "reload_completed
7403 && ((REG_P (operands[0]) && REGNO (operands[0]) <= 31)
7404 || (SUBREG_P (operands[0])
7405 && REG_P (SUBREG_REG (operands[0]))
7406 && REGNO (SUBREG_REG (operands[0])) <= 31))"
7407 [(set (match_dup 2) (match_dup 3))]
7408 {
7409 long l;
7410
7411 <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7412
7413 if (! TARGET_POWERPC64)
7414 operands[2] = operand_subword (operands[0], 0, 0, <MODE>mode);
7415 else
7416 operands[2] = gen_lowpart (SImode, operands[0]);
7417
7418 operands[3] = gen_int_mode (l, SImode);
7419 })
7420
7421 ;; Originally, we tried to keep movsf and movsd common, but the differences
7422 ;; addressing was making it rather difficult to hide with mode attributes. In
7423 ;; particular for SFmode, on ISA 2.07 (power8) systems, having the GPR store
7424 ;; before the VSX stores meant that the register allocator would tend to do a
7425 ;; direct move to the GPR (which involves conversion from scalar to
7426 ;; vector/memory formats) to save values in the traditional Altivec registers,
7427 ;; while SDmode had problems on power6 if the GPR store was not first due to
7428 ;; the power6 not having an integer store operation.
7429 ;;
7430 ;; LWZ LFS LXSSP LXSSPX STFS STXSSP
7431 ;; STXSSPX STW XXLXOR LI FMR XSCPSGNDP
7432 ;; MR MT<x> MF<x> NOP
7433
7434 (define_insn "movsf_hardfloat"
7435 [(set (match_operand:SF 0 "nonimmediate_operand"
7436 "=!r, f, v, wa, m, wY,
7437 Z, m, wa, !r, f, wa,
7438 !r, *c*l, !r, *h")
7439 (match_operand:SF 1 "input_operand"
7440 "m, m, wY, Z, f, v,
7441 wa, r, j, j, f, wa,
7442 r, r, *h, 0"))]
7443 "(register_operand (operands[0], SFmode)
7444 || register_operand (operands[1], SFmode))
7445 && TARGET_HARD_FLOAT
7446 && (TARGET_ALLOW_SF_SUBREG
7447 || valid_sf_si_move (operands[0], operands[1], SFmode))"
7448 "@
7449 lwz%U1%X1 %0,%1
7450 lfs%U1%X1 %0,%1
7451 lxssp %0,%1
7452 lxsspx %x0,%y1
7453 stfs%U0%X0 %1,%0
7454 stxssp %1,%0
7455 stxsspx %x1,%y0
7456 stw%U0%X0 %1,%0
7457 xxlxor %x0,%x0,%x0
7458 li %0,0
7459 fmr %0,%1
7460 xscpsgndp %x0,%x1,%x1
7461 mr %0,%1
7462 mt%0 %1
7463 mf%1 %0
7464 nop"
7465 [(set_attr "type"
7466 "load, fpload, fpload, fpload, fpstore, fpstore,
7467 fpstore, store, veclogical, integer, fpsimple, fpsimple,
7468 *, mtjmpr, mfjmpr, *")
7469 (set_attr "isa"
7470 "*, *, p9v, p8v, *, p9v,
7471 p8v, *, *, *, *, *,
7472 *, *, *, *")])
7473
7474 ;; LWZ LFIWZX STW STFIWX MTVSRWZ MFVSRWZ
7475 ;; FMR MR MT%0 MF%1 NOP
7476 (define_insn "movsd_hardfloat"
7477 [(set (match_operand:SD 0 "nonimmediate_operand"
7478 "=!r, d, m, Z, ?d, ?r,
7479 f, !r, *c*l, !r, *h")
7480 (match_operand:SD 1 "input_operand"
7481 "m, Z, r, wx, r, d,
7482 f, r, r, *h, 0"))]
7483 "(register_operand (operands[0], SDmode)
7484 || register_operand (operands[1], SDmode))
7485 && TARGET_HARD_FLOAT"
7486 "@
7487 lwz%U1%X1 %0,%1
7488 lfiwzx %0,%y1
7489 stw%U0%X0 %1,%0
7490 stfiwx %1,%y0
7491 mtvsrwz %x0,%1
7492 mfvsrwz %0,%x1
7493 fmr %0,%1
7494 mr %0,%1
7495 mt%0 %1
7496 mf%1 %0
7497 nop"
7498 [(set_attr "type"
7499 "load, fpload, store, fpstore, mffgpr, mftgpr,
7500 fpsimple, *, mtjmpr, mfjmpr, *")
7501 (set_attr "isa"
7502 "*, p7, *, *, p8v, p8v,
7503 *, *, *, *, *")])
7504
7505 ;; MR MT%0 MF%0 LWZ STW LI
7506 ;; LIS G-const. F/n-const NOP
7507 (define_insn "*mov<mode>_softfloat"
7508 [(set (match_operand:FMOVE32 0 "nonimmediate_operand"
7509 "=r, *c*l, r, r, m, r,
7510 r, r, r, *h")
7511
7512 (match_operand:FMOVE32 1 "input_operand"
7513 "r, r, *h, m, r, I,
7514 L, G, Fn, 0"))]
7515
7516 "(gpc_reg_operand (operands[0], <MODE>mode)
7517 || gpc_reg_operand (operands[1], <MODE>mode))
7518 && TARGET_SOFT_FLOAT"
7519 "@
7520 mr %0,%1
7521 mt%0 %1
7522 mf%1 %0
7523 lwz%U1%X1 %0,%1
7524 stw%U0%X0 %1,%0
7525 li %0,%1
7526 lis %0,%v1
7527 #
7528 #
7529 nop"
7530 [(set_attr "type"
7531 "*, mtjmpr, mfjmpr, load, store, *,
7532 *, *, *, *")
7533
7534 (set_attr "length"
7535 "*, *, *, *, *, *,
7536 *, *, 8, *")])
7537
7538 ;; Like movsf, but adjust a SI value to be used in a SF context, i.e.
7539 ;; (set (reg:SF ...) (subreg:SF (reg:SI ...) 0))
7540 ;;
7541 ;; Because SF values are actually stored as DF values within the vector
7542 ;; registers, we need to convert the value to the vector SF format when
7543 ;; we need to use the bits in a union or similar cases. We only need
7544 ;; to do this transformation when the value is a vector register. Loads,
7545 ;; stores, and transfers within GPRs are assumed to be safe.
7546 ;;
7547 ;; This is a more general case of reload_vsx_from_gprsf. That insn must have
7548 ;; no alternatives, because the call is created as part of secondary_reload,
7549 ;; and operand #2's register class is used to allocate the temporary register.
7550 ;; This function is called before reload, and it creates the temporary as
7551 ;; needed.
7552
7553 ;; LWZ LFS LXSSP LXSSPX STW STFIWX
7554 ;; STXSIWX GPR->VSX VSX->GPR GPR->GPR
7555 (define_insn_and_split "movsf_from_si"
7556 [(set (match_operand:SF 0 "nonimmediate_operand"
7557 "=!r, f, v, wa, m, Z,
7558 Z, wa, ?r, !r")
7559 (unspec:SF [(match_operand:SI 1 "input_operand"
7560 "m, m, wY, Z, r, f,
7561 wa, r, wa, r")]
7562 UNSPEC_SF_FROM_SI))
7563 (clobber (match_scratch:DI 2
7564 "=X, X, X, X, X, X,
7565 X, r, X, X"))]
7566 "TARGET_NO_SF_SUBREG
7567 && (register_operand (operands[0], SFmode)
7568 || register_operand (operands[1], SImode))"
7569 "@
7570 lwz%U1%X1 %0,%1
7571 lfs%U1%X1 %0,%1
7572 lxssp %0,%1
7573 lxsspx %x0,%y1
7574 stw%U0%X0 %1,%0
7575 stfiwx %1,%y0
7576 stxsiwx %x1,%y0
7577 #
7578 mfvsrwz %0,%x1
7579 mr %0,%1"
7580
7581 "&& reload_completed
7582 && vsx_reg_sfsubreg_ok (operands[0], SFmode)
7583 && int_reg_operand_not_pseudo (operands[1], SImode)"
7584 [(const_int 0)]
7585 {
7586 rtx op0 = operands[0];
7587 rtx op1 = operands[1];
7588 rtx op2 = operands[2];
7589 rtx op1_di = gen_rtx_REG (DImode, REGNO (op1));
7590
7591 /* Move SF value to upper 32-bits for xscvspdpn. */
7592 emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32)));
7593 emit_insn (gen_p8_mtvsrd_sf (op0, op2));
7594 emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0));
7595 DONE;
7596 }
7597 [(set_attr "length"
7598 "*, *, *, *, *, *,
7599 *, 12, *, *")
7600 (set_attr "type"
7601 "load, fpload, fpload, fpload, store, fpstore,
7602 fpstore, vecfloat, mffgpr, *")
7603 (set_attr "isa"
7604 "*, *, p9v, p8v, *, *,
7605 p8v, p8v, p8v, *")])
7606
7607 \f
7608 ;; Move 64-bit binary/decimal floating point
7609 (define_expand "mov<mode>"
7610 [(set (match_operand:FMOVE64 0 "nonimmediate_operand")
7611 (match_operand:FMOVE64 1 "any_operand"))]
7612 ""
7613 {
7614 rs6000_emit_move (operands[0], operands[1], <MODE>mode);
7615 DONE;
7616 })
7617
7618 (define_split
7619 [(set (match_operand:FMOVE64 0 "gpc_reg_operand")
7620 (match_operand:FMOVE64 1 "const_int_operand"))]
7621 "! TARGET_POWERPC64 && reload_completed
7622 && ((REG_P (operands[0]) && REGNO (operands[0]) <= 31)
7623 || (SUBREG_P (operands[0])
7624 && REG_P (SUBREG_REG (operands[0]))
7625 && REGNO (SUBREG_REG (operands[0])) <= 31))"
7626 [(set (match_dup 2) (match_dup 4))
7627 (set (match_dup 3) (match_dup 1))]
7628 {
7629 int endian = (WORDS_BIG_ENDIAN == 0);
7630 HOST_WIDE_INT value = INTVAL (operands[1]);
7631
7632 operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
7633 operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
7634 operands[4] = GEN_INT (value >> 32);
7635 operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
7636 })
7637
7638 (define_split
7639 [(set (match_operand:FMOVE64 0 "gpc_reg_operand")
7640 (match_operand:FMOVE64 1 "const_double_operand"))]
7641 "! TARGET_POWERPC64 && reload_completed
7642 && ((REG_P (operands[0]) && REGNO (operands[0]) <= 31)
7643 || (SUBREG_P (operands[0])
7644 && REG_P (SUBREG_REG (operands[0]))
7645 && REGNO (SUBREG_REG (operands[0])) <= 31))"
7646 [(set (match_dup 2) (match_dup 4))
7647 (set (match_dup 3) (match_dup 5))]
7648 {
7649 int endian = (WORDS_BIG_ENDIAN == 0);
7650 long l[2];
7651
7652 <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7653
7654 operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
7655 operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
7656 operands[4] = gen_int_mode (l[endian], SImode);
7657 operands[5] = gen_int_mode (l[1 - endian], SImode);
7658 })
7659
7660 (define_split
7661 [(set (match_operand:FMOVE64 0 "gpc_reg_operand")
7662 (match_operand:FMOVE64 1 "const_double_operand"))]
7663 "TARGET_POWERPC64 && reload_completed
7664 && ((REG_P (operands[0]) && REGNO (operands[0]) <= 31)
7665 || (SUBREG_P (operands[0])
7666 && REG_P (SUBREG_REG (operands[0]))
7667 && REGNO (SUBREG_REG (operands[0])) <= 31))"
7668 [(set (match_dup 2) (match_dup 3))]
7669 {
7670 int endian = (WORDS_BIG_ENDIAN == 0);
7671 long l[2];
7672 HOST_WIDE_INT val;
7673
7674 <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7675
7676 operands[2] = gen_lowpart (DImode, operands[0]);
7677 /* HIGHPART is lower memory address when WORDS_BIG_ENDIAN. */
7678 val = ((HOST_WIDE_INT)(unsigned long)l[endian] << 32
7679 | ((HOST_WIDE_INT)(unsigned long)l[1 - endian]));
7680
7681 operands[3] = gen_int_mode (val, DImode);
7682 })
7683
7684 ;; Don't have reload use general registers to load a constant. It is
7685 ;; less efficient than loading the constant into an FP register, since
7686 ;; it will probably be used there.
7687
7688 ;; The move constraints are ordered to prefer floating point registers before
7689 ;; general purpose registers to avoid doing a store and a load to get the value
7690 ;; into a floating point register when it is needed for a floating point
7691 ;; operation. Prefer traditional floating point registers over VSX registers,
7692 ;; since the D-form version of the memory instructions does not need a GPR for
7693 ;; reloading. ISA 3.0 (power9) adds D-form addressing for scalars to Altivec
7694 ;; registers.
7695
7696 ;; If we have FPR registers, rs6000_emit_move has moved all constants to memory,
7697 ;; except for 0.0 which can be created on VSX with an xor instruction.
7698
7699 ;; STFD LFD FMR LXSD STXSD
7700 ;; LXSD STXSD XXLOR XXLXOR GPR<-0
7701 ;; LWZ STW MR
7702
7703
7704 (define_insn "*mov<mode>_hardfloat32"
7705 [(set (match_operand:FMOVE64 0 "nonimmediate_operand"
7706 "=m, d, d, <f64_p9>, wY,
7707 <f64_av>, Z, <f64_vsx>, <f64_vsx>, !r,
7708 Y, r, !r")
7709 (match_operand:FMOVE64 1 "input_operand"
7710 "d, m, d, wY, <f64_p9>,
7711 Z, <f64_av>, <f64_vsx>, <zero_fp>, <zero_fp>,
7712 r, Y, r"))]
7713 "! TARGET_POWERPC64 && TARGET_HARD_FLOAT
7714 && (gpc_reg_operand (operands[0], <MODE>mode)
7715 || gpc_reg_operand (operands[1], <MODE>mode))"
7716 "@
7717 stfd%U0%X0 %1,%0
7718 lfd%U1%X1 %0,%1
7719 fmr %0,%1
7720 lxsd %0,%1
7721 stxsd %1,%0
7722 lxsdx %x0,%y1
7723 stxsdx %x1,%y0
7724 xxlor %x0,%x1,%x1
7725 xxlxor %x0,%x0,%x0
7726 #
7727 #
7728 #
7729 #"
7730 [(set_attr "type"
7731 "fpstore, fpload, fpsimple, fpload, fpstore,
7732 fpload, fpstore, veclogical, veclogical, two,
7733 store, load, two")
7734 (set_attr "size" "64")
7735 (set_attr "length"
7736 "*, *, *, *, *,
7737 *, *, *, *, 8,
7738 8, 8, 8")
7739 (set_attr "isa"
7740 "*, *, *, p9v, p9v,
7741 p7v, p7v, *, *, *,
7742 *, *, *")])
7743
7744 ;; STW LWZ MR G-const H-const F-const
7745
7746 (define_insn "*mov<mode>_softfloat32"
7747 [(set (match_operand:FMOVE64 0 "nonimmediate_operand"
7748 "=Y, r, r, r, r, r")
7749
7750 (match_operand:FMOVE64 1 "input_operand"
7751 "r, Y, r, G, H, F"))]
7752
7753 "!TARGET_POWERPC64
7754 && (gpc_reg_operand (operands[0], <MODE>mode)
7755 || gpc_reg_operand (operands[1], <MODE>mode))"
7756 "#"
7757 [(set_attr "type"
7758 "store, load, two, *, *, *")
7759
7760 (set_attr "length"
7761 "8, 8, 8, 8, 12, 16")])
7762
7763 ; ld/std require word-aligned displacements -> 'Y' constraint.
7764 ; List Y->r and r->Y before r->r for reload.
7765
7766 ;; STFD LFD FMR LXSD STXSD
7767 ;; LXSDX STXSDX XXLOR XXLXOR LI 0
7768 ;; STD LD MR MT{CTR,LR} MF{CTR,LR}
7769 ;; NOP MFVSRD MTVSRD
7770
7771 (define_insn "*mov<mode>_hardfloat64"
7772 [(set (match_operand:FMOVE64 0 "nonimmediate_operand"
7773 "=m, d, d, <f64_p9>, wY,
7774 <f64_av>, Z, <f64_vsx>, <f64_vsx>, !r,
7775 YZ, r, !r, *c*l, !r,
7776 *h, r, <f64_dm>")
7777 (match_operand:FMOVE64 1 "input_operand"
7778 "d, m, d, wY, <f64_p9>,
7779 Z, <f64_av>, <f64_vsx>, <zero_fp>, <zero_fp>,
7780 r, YZ, r, r, *h,
7781 0, <f64_dm>, r"))]
7782 "TARGET_POWERPC64 && TARGET_HARD_FLOAT
7783 && (gpc_reg_operand (operands[0], <MODE>mode)
7784 || gpc_reg_operand (operands[1], <MODE>mode))"
7785 "@
7786 stfd%U0%X0 %1,%0
7787 lfd%U1%X1 %0,%1
7788 fmr %0,%1
7789 lxsd %0,%1
7790 stxsd %1,%0
7791 lxsdx %x0,%y1
7792 stxsdx %x1,%y0
7793 xxlor %x0,%x1,%x1
7794 xxlxor %x0,%x0,%x0
7795 li %0,0
7796 std%U0%X0 %1,%0
7797 ld%U1%X1 %0,%1
7798 mr %0,%1
7799 mt%0 %1
7800 mf%1 %0
7801 nop
7802 mfvsrd %0,%x1
7803 mtvsrd %x0,%1"
7804 [(set_attr "type"
7805 "fpstore, fpload, fpsimple, fpload, fpstore,
7806 fpload, fpstore, veclogical, veclogical, integer,
7807 store, load, *, mtjmpr, mfjmpr,
7808 *, mftgpr, mffgpr")
7809 (set_attr "size" "64")
7810 (set_attr "isa"
7811 "*, *, *, p9v, p9v,
7812 p7v, p7v, *, *, *,
7813 *, *, *, *, *,
7814 *, p8v, p8v")])
7815
7816 ;; STD LD MR MT<SPR> MF<SPR> G-const
7817 ;; H-const F-const Special
7818
7819 (define_insn "*mov<mode>_softfloat64"
7820 [(set (match_operand:FMOVE64 0 "nonimmediate_operand"
7821 "=Y, r, r, *c*l, r, r,
7822 r, r, *h")
7823
7824 (match_operand:FMOVE64 1 "input_operand"
7825 "r, Y, r, r, *h, G,
7826 H, F, 0"))]
7827
7828 "TARGET_POWERPC64 && TARGET_SOFT_FLOAT
7829 && (gpc_reg_operand (operands[0], <MODE>mode)
7830 || gpc_reg_operand (operands[1], <MODE>mode))"
7831 "@
7832 std%U0%X0 %1,%0
7833 ld%U1%X1 %0,%1
7834 mr %0,%1
7835 mt%0 %1
7836 mf%1 %0
7837 #
7838 #
7839 #
7840 nop"
7841 [(set_attr "type"
7842 "store, load, *, mtjmpr, mfjmpr, *,
7843 *, *, *")
7844
7845 (set_attr "length"
7846 "*, *, *, *, *, 8,
7847 12, 16, *")])
7848 \f
7849 (define_expand "mov<mode>"
7850 [(set (match_operand:FMOVE128 0 "general_operand")
7851 (match_operand:FMOVE128 1 "any_operand"))]
7852 ""
7853 {
7854 rs6000_emit_move (operands[0], operands[1], <MODE>mode);
7855 DONE;
7856 })
7857
7858 ;; It's important to list Y->r and r->Y before r->r because otherwise
7859 ;; reload, given m->r, will try to pick r->r and reload it, which
7860 ;; doesn't make progress.
7861
7862 ;; We can't split little endian direct moves of TDmode, because the words are
7863 ;; not swapped like they are for TImode or TFmode. Subregs therefore are
7864 ;; problematical. Don't allow direct move for this case.
7865
7866 ;; FPR load FPR store FPR move FPR zero GPR load
7867 ;; GPR zero GPR store GPR move MFVSRD MTVSRD
7868
7869 (define_insn_and_split "*mov<mode>_64bit_dm"
7870 [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand"
7871 "=m, d, d, d, Y,
7872 r, r, r, r, d")
7873
7874 (match_operand:FMOVE128_FPR 1 "input_operand"
7875 "d, m, d, <zero_fp>, r,
7876 <zero_fp>, Y, r, d, r"))]
7877
7878 "TARGET_HARD_FLOAT && TARGET_POWERPC64 && FLOAT128_2REG_P (<MODE>mode)
7879 && (<MODE>mode != TDmode || WORDS_BIG_ENDIAN)
7880 && (gpc_reg_operand (operands[0], <MODE>mode)
7881 || gpc_reg_operand (operands[1], <MODE>mode))"
7882 "#"
7883 "&& reload_completed"
7884 [(pc)]
7885 {
7886 rs6000_split_multireg_move (operands[0], operands[1]);
7887 DONE;
7888 }
7889 [(set_attr "length" "8")
7890 (set_attr "isa" "*,*,*,*,*,*,*,*,p8v,p8v")
7891 (set_attr "max_prefixed_insns" "2")
7892 (set_attr "num_insns" "2")])
7893
7894 (define_insn_and_split "*movtd_64bit_nodm"
7895 [(set (match_operand:TD 0 "nonimmediate_operand" "=m,d,d,Y,r,r")
7896 (match_operand:TD 1 "input_operand" "d,m,d,r,Y,r"))]
7897 "TARGET_HARD_FLOAT && TARGET_POWERPC64 && !WORDS_BIG_ENDIAN
7898 && (gpc_reg_operand (operands[0], TDmode)
7899 || gpc_reg_operand (operands[1], TDmode))"
7900 "#"
7901 "&& reload_completed"
7902 [(pc)]
7903 {
7904 rs6000_split_multireg_move (operands[0], operands[1]);
7905 DONE;
7906 }
7907 [(set_attr "length" "8,8,8,12,12,8")
7908 (set_attr "max_prefixed_insns" "2")
7909 (set_attr "num_insns" "2,2,2,3,3,2")])
7910
7911 (define_insn_and_split "*mov<mode>_32bit"
7912 [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand" "=m,d,d,d,Y,r,r")
7913 (match_operand:FMOVE128_FPR 1 "input_operand" "d,m,d,<zero_fp>,r,<zero_fp>Y,r"))]
7914 "TARGET_HARD_FLOAT && !TARGET_POWERPC64
7915 && (FLOAT128_2REG_P (<MODE>mode)
7916 || int_reg_operand_not_pseudo (operands[0], <MODE>mode)
7917 || int_reg_operand_not_pseudo (operands[1], <MODE>mode))
7918 && (gpc_reg_operand (operands[0], <MODE>mode)
7919 || gpc_reg_operand (operands[1], <MODE>mode))"
7920 "#"
7921 "&& reload_completed"
7922 [(pc)]
7923 {
7924 rs6000_split_multireg_move (operands[0], operands[1]);
7925 DONE;
7926 }
7927 [(set_attr "length" "8,8,8,8,20,20,16")])
7928
7929 (define_insn_and_split "*mov<mode>_softfloat"
7930 [(set (match_operand:FMOVE128 0 "nonimmediate_operand" "=Y,r,r,r")
7931 (match_operand:FMOVE128 1 "input_operand" "r,Y,F,r"))]
7932 "TARGET_SOFT_FLOAT
7933 && (gpc_reg_operand (operands[0], <MODE>mode)
7934 || gpc_reg_operand (operands[1], <MODE>mode))"
7935 "#"
7936 "&& reload_completed"
7937 [(pc)]
7938 {
7939 rs6000_split_multireg_move (operands[0], operands[1]);
7940 DONE;
7941 }
7942 [(set_attr_alternative "length"
7943 [(if_then_else (match_test "TARGET_POWERPC64")
7944 (const_string "8")
7945 (const_string "16"))
7946 (if_then_else (match_test "TARGET_POWERPC64")
7947 (const_string "8")
7948 (const_string "16"))
7949 (if_then_else (match_test "TARGET_POWERPC64")
7950 (const_string "16")
7951 (const_string "32"))
7952 (if_then_else (match_test "TARGET_POWERPC64")
7953 (const_string "8")
7954 (const_string "16"))])])
7955
7956 (define_expand "@extenddf<mode>2"
7957 [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
7958 (float_extend:FLOAT128 (match_operand:DF 1 "gpc_reg_operand")))]
7959 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7960 {
7961 if (FLOAT128_IEEE_P (<MODE>mode))
7962 rs6000_expand_float128_convert (operands[0], operands[1], false);
7963 else if (TARGET_VSX)
7964 emit_insn (gen_extenddf2_vsx (<MODE>mode, operands[0], operands[1]));
7965 else
7966 {
7967 rtx zero = gen_reg_rtx (DFmode);
7968 rs6000_emit_move (zero, CONST0_RTX (DFmode), DFmode);
7969
7970 emit_insn (gen_extenddf2_fprs (<MODE>mode,
7971 operands[0], operands[1], zero));
7972 }
7973 DONE;
7974 })
7975
7976 ;; Allow memory operands for the source to be created by the combiner.
7977 (define_insn_and_split "@extenddf<mode>2_fprs"
7978 [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d,&d")
7979 (float_extend:IBM128
7980 (match_operand:DF 1 "nonimmediate_operand" "d,m,d")))
7981 (use (match_operand:DF 2 "nonimmediate_operand" "m,m,d"))]
7982 "!TARGET_VSX && TARGET_HARD_FLOAT
7983 && TARGET_LONG_DOUBLE_128 && FLOAT128_IBM_P (<MODE>mode)"
7984 "#"
7985 "&& reload_completed"
7986 [(set (match_dup 3) (match_dup 1))
7987 (set (match_dup 4) (match_dup 2))]
7988 {
7989 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7990 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7991
7992 operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
7993 operands[4] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
7994 })
7995
7996 (define_insn_and_split "@extenddf<mode>2_vsx"
7997 [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d")
7998 (float_extend:IBM128
7999 (match_operand:DF 1 "nonimmediate_operand" "wa,m")))]
8000 "TARGET_LONG_DOUBLE_128 && TARGET_VSX && FLOAT128_IBM_P (<MODE>mode)"
8001 "#"
8002 "&& reload_completed"
8003 [(set (match_dup 2) (match_dup 1))
8004 (set (match_dup 3) (match_dup 4))]
8005 {
8006 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
8007 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
8008
8009 operands[2] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
8010 operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
8011 operands[4] = CONST0_RTX (DFmode);
8012 })
8013
8014 (define_expand "extendsf<mode>2"
8015 [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
8016 (float_extend:FLOAT128 (match_operand:SF 1 "gpc_reg_operand")))]
8017 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8018 {
8019 if (FLOAT128_IEEE_P (<MODE>mode))
8020 rs6000_expand_float128_convert (operands[0], operands[1], false);
8021 else
8022 {
8023 rtx tmp = gen_reg_rtx (DFmode);
8024 emit_insn (gen_extendsfdf2 (tmp, operands[1]));
8025 emit_insn (gen_extenddf<mode>2 (operands[0], tmp));
8026 }
8027 DONE;
8028 })
8029
8030 (define_expand "trunc<mode>df2"
8031 [(set (match_operand:DF 0 "gpc_reg_operand")
8032 (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand")))]
8033 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8034 {
8035 if (FLOAT128_IEEE_P (<MODE>mode))
8036 {
8037 rs6000_expand_float128_convert (operands[0], operands[1], false);
8038 DONE;
8039 }
8040 })
8041
8042 (define_insn_and_split "trunc<mode>df2_internal1"
8043 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d")
8044 (float_truncate:DF
8045 (match_operand:IBM128 1 "gpc_reg_operand" "0,d")))]
8046 "FLOAT128_IBM_P (<MODE>mode) && !TARGET_XL_COMPAT
8047 && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8048 "@
8049 #
8050 fmr %0,%1"
8051 "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
8052 [(const_int 0)]
8053 {
8054 emit_note (NOTE_INSN_DELETED);
8055 DONE;
8056 }
8057 [(set_attr "type" "fpsimple")])
8058
8059 (define_insn "trunc<mode>df2_internal2"
8060 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
8061 (float_truncate:DF (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
8062 "FLOAT128_IBM_P (<MODE>mode) && TARGET_XL_COMPAT && TARGET_HARD_FLOAT
8063 && TARGET_LONG_DOUBLE_128"
8064 "fadd %0,%1,%L1"
8065 [(set_attr "type" "fp")])
8066
8067 (define_expand "trunc<mode>sf2"
8068 [(set (match_operand:SF 0 "gpc_reg_operand")
8069 (float_truncate:SF (match_operand:FLOAT128 1 "gpc_reg_operand")))]
8070 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8071 {
8072 if (FLOAT128_IEEE_P (<MODE>mode))
8073 rs6000_expand_float128_convert (operands[0], operands[1], false);
8074 else
8075 {
8076 rtx tmp = gen_reg_rtx (DFmode);
8077 emit_insn (gen_trunc<mode>df2 (tmp, operands[1]));
8078 emit_insn (gen_truncdfsf2 (operands[0], tmp));
8079 }
8080 DONE;
8081 })
8082
8083 (define_expand "floatsi<mode>2"
8084 [(parallel [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
8085 (float:FLOAT128 (match_operand:SI 1 "gpc_reg_operand")))
8086 (clobber (match_scratch:DI 2))])]
8087 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8088 {
8089 rtx op0 = operands[0];
8090 rtx op1 = operands[1];
8091
8092 if (TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode))
8093 ;
8094 else if (FLOAT128_IEEE_P (<MODE>mode))
8095 {
8096 rs6000_expand_float128_convert (op0, op1, false);
8097 DONE;
8098 }
8099 else
8100 {
8101 rtx tmp = gen_reg_rtx (DFmode);
8102 expand_float (tmp, op1, false);
8103 emit_insn (gen_extenddf2 (<MODE>mode, op0, tmp));
8104 DONE;
8105 }
8106 })
8107
8108 ; fadd, but rounding towards zero.
8109 ; This is probably not the optimal code sequence.
8110 (define_insn "fix_trunc_helper<mode>"
8111 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
8112 (unspec:DF [(match_operand:IBM128 1 "gpc_reg_operand" "d")]
8113 UNSPEC_FIX_TRUNC_TF))
8114 (clobber (match_operand:DF 2 "gpc_reg_operand" "=&d"))]
8115 "TARGET_HARD_FLOAT && FLOAT128_IBM_P (<MODE>mode)"
8116 "mffs %2\n\tmtfsb1 31\n\tmtfsb0 30\n\tfadd %0,%1,%L1\n\tmtfsf 1,%2"
8117 [(set_attr "type" "fp")
8118 (set_attr "length" "20")])
8119
8120 (define_expand "fix_trunc<mode>si2"
8121 [(set (match_operand:SI 0 "gpc_reg_operand")
8122 (fix:SI (match_operand:FLOAT128 1 "gpc_reg_operand")))]
8123 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8124 {
8125 rtx op0 = operands[0];
8126 rtx op1 = operands[1];
8127
8128 if (TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode))
8129 ;
8130 else
8131 {
8132 if (FLOAT128_IEEE_P (<MODE>mode))
8133 rs6000_expand_float128_convert (op0, op1, false);
8134 else
8135 emit_insn (gen_fix_truncsi2_fprs (<MODE>mode, op0, op1));
8136 DONE;
8137 }
8138 })
8139
8140 (define_expand "@fix_trunc<mode>si2_fprs"
8141 [(parallel [(set (match_operand:SI 0 "gpc_reg_operand")
8142 (fix:SI (match_operand:IBM128 1 "gpc_reg_operand")))
8143 (clobber (match_dup 2))
8144 (clobber (match_dup 3))
8145 (clobber (match_dup 4))
8146 (clobber (match_dup 5))])]
8147 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8148 {
8149 operands[2] = gen_reg_rtx (DFmode);
8150 operands[3] = gen_reg_rtx (DFmode);
8151 operands[4] = gen_reg_rtx (DImode);
8152 operands[5] = assign_stack_temp (DImode, GET_MODE_SIZE (DImode));
8153 })
8154
8155 (define_insn_and_split "*fix_trunc<mode>si2_internal"
8156 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
8157 (fix:SI (match_operand:IBM128 1 "gpc_reg_operand" "d")))
8158 (clobber (match_operand:DF 2 "gpc_reg_operand" "=d"))
8159 (clobber (match_operand:DF 3 "gpc_reg_operand" "=&d"))
8160 (clobber (match_operand:DI 4 "gpc_reg_operand" "=d"))
8161 (clobber (match_operand:DI 5 "offsettable_mem_operand" "=o"))]
8162 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8163 "#"
8164 ""
8165 [(pc)]
8166 {
8167 rtx lowword;
8168 emit_insn (gen_fix_trunc_helper<mode> (operands[2], operands[1],
8169 operands[3]));
8170
8171 gcc_assert (MEM_P (operands[5]));
8172 lowword = adjust_address (operands[5], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
8173
8174 emit_insn (gen_fctiwz_df (operands[4], operands[2]));
8175 emit_move_insn (operands[5], operands[4]);
8176 emit_move_insn (operands[0], lowword);
8177 DONE;
8178 })
8179
8180 (define_expand "fix_trunc<mode>di2"
8181 [(set (match_operand:DI 0 "gpc_reg_operand")
8182 (fix:DI (match_operand:IEEE128 1 "gpc_reg_operand")))]
8183 "TARGET_FLOAT128_TYPE"
8184 {
8185 if (!TARGET_FLOAT128_HW)
8186 {
8187 rs6000_expand_float128_convert (operands[0], operands[1], false);
8188 DONE;
8189 }
8190 })
8191
8192 (define_expand "fixuns_trunc<IEEE128:mode><SDI:mode>2"
8193 [(set (match_operand:SDI 0 "gpc_reg_operand")
8194 (unsigned_fix:SDI (match_operand:IEEE128 1 "gpc_reg_operand")))]
8195 "TARGET_FLOAT128_TYPE"
8196 {
8197 rs6000_expand_float128_convert (operands[0], operands[1], true);
8198 DONE;
8199 })
8200
8201 (define_expand "floatdi<mode>2"
8202 [(set (match_operand:IEEE128 0 "gpc_reg_operand")
8203 (float:IEEE128 (match_operand:DI 1 "gpc_reg_operand")))]
8204 "TARGET_FLOAT128_TYPE"
8205 {
8206 if (!TARGET_FLOAT128_HW)
8207 {
8208 rs6000_expand_float128_convert (operands[0], operands[1], false);
8209 DONE;
8210 }
8211 })
8212
8213 (define_expand "floatunsdi<IEEE128:mode>2"
8214 [(set (match_operand:IEEE128 0 "gpc_reg_operand")
8215 (unsigned_float:IEEE128 (match_operand:DI 1 "gpc_reg_operand")))]
8216 "TARGET_FLOAT128_TYPE"
8217 {
8218 if (!TARGET_FLOAT128_HW)
8219 {
8220 rs6000_expand_float128_convert (operands[0], operands[1], true);
8221 DONE;
8222 }
8223 })
8224
8225 (define_expand "floatuns<IEEE128:mode>2"
8226 [(set (match_operand:IEEE128 0 "gpc_reg_operand")
8227 (unsigned_float:IEEE128 (match_operand:SI 1 "gpc_reg_operand")))]
8228 "TARGET_FLOAT128_TYPE"
8229 {
8230 rtx op0 = operands[0];
8231 rtx op1 = operands[1];
8232
8233 if (TARGET_FLOAT128_HW)
8234 emit_insn (gen_floatuns_<IEEE128:mode>si2_hw (op0, op1));
8235 else
8236 rs6000_expand_float128_convert (op0, op1, true);
8237 DONE;
8238 })
8239
8240 (define_expand "neg<mode>2"
8241 [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
8242 (neg:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand")))]
8243 "FLOAT128_IEEE_P (<MODE>mode)
8244 || (FLOAT128_IBM_P (<MODE>mode) && TARGET_HARD_FLOAT)"
8245 {
8246 if (FLOAT128_IEEE_P (<MODE>mode))
8247 {
8248 if (TARGET_FLOAT128_HW)
8249 emit_insn (gen_neg2_hw (<MODE>mode, operands[0], operands[1]));
8250 else if (TARGET_FLOAT128_TYPE)
8251 emit_insn (gen_ieee_128bit_vsx_neg2 (<MODE>mode,
8252 operands[0], operands[1]));
8253 else
8254 {
8255 rtx libfunc = optab_libfunc (neg_optab, <MODE>mode);
8256 rtx target = emit_library_call_value (libfunc, operands[0], LCT_CONST,
8257 <MODE>mode,
8258 operands[1], <MODE>mode);
8259
8260 if (target && !rtx_equal_p (target, operands[0]))
8261 emit_move_insn (operands[0], target);
8262 }
8263 DONE;
8264 }
8265 })
8266
8267 (define_insn "neg<mode>2_internal"
8268 [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d")
8269 (neg:IBM128 (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
8270 "TARGET_HARD_FLOAT && FLOAT128_IBM_P (<MODE>mode)"
8271 {
8272 if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
8273 return "fneg %L0,%L1\;fneg %0,%1";
8274 else
8275 return "fneg %0,%1\;fneg %L0,%L1";
8276 }
8277 [(set_attr "type" "fpsimple")
8278 (set_attr "length" "8")])
8279
8280 (define_expand "abs<mode>2"
8281 [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
8282 (abs:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand")))]
8283 "FLOAT128_IEEE_P (<MODE>mode)
8284 || (FLOAT128_IBM_P (<MODE>mode) && TARGET_HARD_FLOAT)"
8285 {
8286 rtx label;
8287
8288 if (FLOAT128_IEEE_P (<MODE>mode))
8289 {
8290 if (TARGET_FLOAT128_HW)
8291 {
8292 emit_insn (gen_abs2_hw (<MODE>mode, operands[0], operands[1]));
8293 DONE;
8294 }
8295 else if (TARGET_FLOAT128_TYPE)
8296 {
8297 emit_insn (gen_ieee_128bit_vsx_abs2 (<MODE>mode,
8298 operands[0], operands[1]));
8299 DONE;
8300 }
8301 else
8302 FAIL;
8303 }
8304
8305 label = gen_label_rtx ();
8306 emit_insn (gen_abs2_internal (<MODE>mode, operands[0], operands[1], label));
8307 emit_label (label);
8308 DONE;
8309 })
8310
8311 (define_expand "@abs<mode>2_internal"
8312 [(set (match_operand:IBM128 0 "gpc_reg_operand")
8313 (match_operand:IBM128 1 "gpc_reg_operand"))
8314 (set (match_dup 3) (match_dup 5))
8315 (set (match_dup 5) (abs:DF (match_dup 5)))
8316 (set (match_dup 4) (compare:CCFP (match_dup 3) (match_dup 5)))
8317 (set (pc) (if_then_else (eq (match_dup 4) (const_int 0))
8318 (label_ref (match_operand 2 ""))
8319 (pc)))
8320 (set (match_dup 6) (neg:DF (match_dup 6)))]
8321 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8322 {
8323 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
8324 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
8325 operands[3] = gen_reg_rtx (DFmode);
8326 operands[4] = gen_reg_rtx (CCFPmode);
8327 operands[5] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
8328 operands[6] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
8329 })
8330
8331 \f
8332 ;; Generate IEEE 128-bit -0.0 (0x80000000000000000000000000000000) in a vector
8333 ;; register
8334
8335 (define_expand "ieee_128bit_negative_zero"
8336 [(set (match_operand:V16QI 0 "register_operand") (match_dup 1))]
8337 "TARGET_FLOAT128_TYPE"
8338 {
8339 rtvec v = rtvec_alloc (16);
8340 int i, high;
8341
8342 for (i = 0; i < 16; i++)
8343 RTVEC_ELT (v, i) = const0_rtx;
8344
8345 high = (BYTES_BIG_ENDIAN) ? 0 : 15;
8346 RTVEC_ELT (v, high) = gen_int_mode (0x80, QImode);
8347
8348 rs6000_expand_vector_init (operands[0], gen_rtx_PARALLEL (V16QImode, v));
8349 DONE;
8350 })
8351
8352 ;; IEEE 128-bit negate
8353
8354 ;; We have 2 insns here for negate and absolute value. The first uses
8355 ;; match_scratch so that phases like combine can recognize neg/abs as generic
8356 ;; insns, and second insn after the first split pass loads up the bit to
8357 ;; twiddle the sign bit. Later GCSE passes can then combine multiple uses of
8358 ;; neg/abs to create the constant just once.
8359
8360 (define_insn_and_split "@ieee_128bit_vsx_neg<mode>2"
8361 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8362 (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8363 (clobber (match_scratch:V16QI 2 "=v"))]
8364 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8365 "#"
8366 "&& 1"
8367 [(parallel [(set (match_dup 0)
8368 (neg:IEEE128 (match_dup 1)))
8369 (use (match_dup 2))])]
8370 {
8371 if (GET_CODE (operands[2]) == SCRATCH)
8372 operands[2] = gen_reg_rtx (V16QImode);
8373
8374 operands[3] = gen_reg_rtx (V16QImode);
8375 emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8376 }
8377 [(set_attr "length" "8")
8378 (set_attr "type" "vecsimple")])
8379
8380 (define_insn "*ieee_128bit_vsx_neg<mode>2_internal"
8381 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8382 (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8383 (use (match_operand:V16QI 2 "register_operand" "v"))]
8384 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8385 "xxlxor %x0,%x1,%x2"
8386 [(set_attr "type" "veclogical")])
8387
8388 ;; IEEE 128-bit absolute value
8389 (define_insn_and_split "@ieee_128bit_vsx_abs<mode>2"
8390 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8391 (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8392 (clobber (match_scratch:V16QI 2 "=v"))]
8393 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
8394 "#"
8395 "&& 1"
8396 [(parallel [(set (match_dup 0)
8397 (abs:IEEE128 (match_dup 1)))
8398 (use (match_dup 2))])]
8399 {
8400 if (GET_CODE (operands[2]) == SCRATCH)
8401 operands[2] = gen_reg_rtx (V16QImode);
8402
8403 operands[3] = gen_reg_rtx (V16QImode);
8404 emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8405 }
8406 [(set_attr "length" "8")
8407 (set_attr "type" "vecsimple")])
8408
8409 (define_insn "*ieee_128bit_vsx_abs<mode>2_internal"
8410 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8411 (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8412 (use (match_operand:V16QI 2 "register_operand" "v"))]
8413 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8414 "xxlandc %x0,%x1,%x2"
8415 [(set_attr "type" "veclogical")])
8416
8417 ;; IEEE 128-bit negative absolute value
8418 (define_insn_and_split "*ieee_128bit_vsx_nabs<mode>2"
8419 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8420 (neg:IEEE128
8421 (abs:IEEE128
8422 (match_operand:IEEE128 1 "register_operand" "wa"))))
8423 (clobber (match_scratch:V16QI 2 "=v"))]
8424 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW
8425 && FLOAT128_IEEE_P (<MODE>mode)"
8426 "#"
8427 "&& 1"
8428 [(parallel [(set (match_dup 0)
8429 (neg:IEEE128 (abs:IEEE128 (match_dup 1))))
8430 (use (match_dup 2))])]
8431 {
8432 if (GET_CODE (operands[2]) == SCRATCH)
8433 operands[2] = gen_reg_rtx (V16QImode);
8434
8435 operands[3] = gen_reg_rtx (V16QImode);
8436 emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8437 }
8438 [(set_attr "length" "8")
8439 (set_attr "type" "vecsimple")])
8440
8441 (define_insn "*ieee_128bit_vsx_nabs<mode>2_internal"
8442 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8443 (neg:IEEE128
8444 (abs:IEEE128
8445 (match_operand:IEEE128 1 "register_operand" "wa"))))
8446 (use (match_operand:V16QI 2 "register_operand" "v"))]
8447 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8448 "xxlor %x0,%x1,%x2"
8449 [(set_attr "type" "veclogical")])
8450
8451 ;; Float128 conversion functions. These expand to library function calls.
8452 ;; We use expand to convert from IBM double double to IEEE 128-bit
8453 ;; and trunc for the opposite.
8454 (define_expand "extendiftf2"
8455 [(set (match_operand:TF 0 "gpc_reg_operand")
8456 (float_extend:TF (match_operand:IF 1 "gpc_reg_operand")))]
8457 "TARGET_FLOAT128_TYPE"
8458 {
8459 rs6000_expand_float128_convert (operands[0], operands[1], false);
8460 DONE;
8461 })
8462
8463 (define_expand "extendifkf2"
8464 [(set (match_operand:KF 0 "gpc_reg_operand")
8465 (float_extend:KF (match_operand:IF 1 "gpc_reg_operand")))]
8466 "TARGET_FLOAT128_TYPE"
8467 {
8468 rs6000_expand_float128_convert (operands[0], operands[1], false);
8469 DONE;
8470 })
8471
8472 (define_expand "extendtfkf2"
8473 [(set (match_operand:KF 0 "gpc_reg_operand")
8474 (float_extend:KF (match_operand:TF 1 "gpc_reg_operand")))]
8475 "TARGET_FLOAT128_TYPE"
8476 {
8477 rs6000_expand_float128_convert (operands[0], operands[1], false);
8478 DONE;
8479 })
8480
8481 (define_expand "extendtfif2"
8482 [(set (match_operand:IF 0 "gpc_reg_operand")
8483 (float_extend:IF (match_operand:TF 1 "gpc_reg_operand")))]
8484 "TARGET_FLOAT128_TYPE"
8485 {
8486 rs6000_expand_float128_convert (operands[0], operands[1], false);
8487 DONE;
8488 })
8489
8490 (define_expand "trunciftf2"
8491 [(set (match_operand:TF 0 "gpc_reg_operand")
8492 (float_truncate:TF (match_operand:IF 1 "gpc_reg_operand")))]
8493 "TARGET_FLOAT128_TYPE"
8494 {
8495 rs6000_expand_float128_convert (operands[0], operands[1], false);
8496 DONE;
8497 })
8498
8499 (define_expand "truncifkf2"
8500 [(set (match_operand:KF 0 "gpc_reg_operand")
8501 (float_truncate:KF (match_operand:IF 1 "gpc_reg_operand")))]
8502 "TARGET_FLOAT128_TYPE"
8503 {
8504 rs6000_expand_float128_convert (operands[0], operands[1], false);
8505 DONE;
8506 })
8507
8508 (define_expand "trunckftf2"
8509 [(set (match_operand:TF 0 "gpc_reg_operand")
8510 (float_truncate:TF (match_operand:KF 1 "gpc_reg_operand")))]
8511 "TARGET_FLOAT128_TYPE"
8512 {
8513 rs6000_expand_float128_convert (operands[0], operands[1], false);
8514 DONE;
8515 })
8516
8517 (define_expand "trunctfif2"
8518 [(set (match_operand:IF 0 "gpc_reg_operand")
8519 (float_truncate:IF (match_operand:TF 1 "gpc_reg_operand")))]
8520 "TARGET_FLOAT128_TYPE"
8521 {
8522 rs6000_expand_float128_convert (operands[0], operands[1], false);
8523 DONE;
8524 })
8525
8526 (define_insn_and_split "*extend<mode>tf2_internal"
8527 [(set (match_operand:TF 0 "gpc_reg_operand" "=<IFKF_reg>")
8528 (float_extend:TF
8529 (match_operand:IFKF 1 "gpc_reg_operand" "<IFKF_reg>")))]
8530 "TARGET_FLOAT128_TYPE
8531 && FLOAT128_IBM_P (TFmode) == FLOAT128_IBM_P (<MODE>mode)"
8532 "#"
8533 "&& reload_completed"
8534 [(set (match_dup 0) (match_dup 2))]
8535 {
8536 operands[2] = gen_rtx_REG (TFmode, REGNO (operands[1]));
8537 })
8538
8539 (define_insn_and_split "*extendtf<mode>2_internal"
8540 [(set (match_operand:IFKF 0 "gpc_reg_operand" "=<IFKF_reg>")
8541 (float_extend:IFKF
8542 (match_operand:TF 1 "gpc_reg_operand" "<IFKF_reg>")))]
8543 "TARGET_FLOAT128_TYPE
8544 && FLOAT128_IBM_P (TFmode) == FLOAT128_IBM_P (<MODE>mode)"
8545 "#"
8546 "&& reload_completed"
8547 [(set (match_dup 0) (match_dup 2))]
8548 {
8549 operands[2] = gen_rtx_REG (<MODE>mode, REGNO (operands[1]));
8550 })
8551
8552 \f
8553 ;; Reload helper functions used by rs6000_secondary_reload. The patterns all
8554 ;; must have 3 arguments, and scratch register constraint must be a single
8555 ;; constraint.
8556
8557 ;; Reload patterns to support gpr load/store with misaligned mem.
8558 ;; and multiple gpr load/store at offset >= 0xfffc
8559 (define_expand "reload_<mode>_store"
8560 [(parallel [(match_operand 0 "memory_operand" "=m")
8561 (match_operand 1 "gpc_reg_operand" "r")
8562 (match_operand:GPR 2 "register_operand" "=&b")])]
8563 ""
8564 {
8565 rs6000_secondary_reload_gpr (operands[1], operands[0], operands[2], true);
8566 DONE;
8567 })
8568
8569 (define_expand "reload_<mode>_load"
8570 [(parallel [(match_operand 0 "gpc_reg_operand" "=r")
8571 (match_operand 1 "memory_operand" "m")
8572 (match_operand:GPR 2 "register_operand" "=b")])]
8573 ""
8574 {
8575 rs6000_secondary_reload_gpr (operands[0], operands[1], operands[2], false);
8576 DONE;
8577 })
8578
8579 \f
8580 ;; Reload patterns for various types using the vector registers. We may need
8581 ;; an additional base register to convert the reg+offset addressing to reg+reg
8582 ;; for vector registers and reg+reg or (reg+reg)&(-16) addressing to just an
8583 ;; index register for gpr registers.
8584 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_store"
8585 [(parallel [(match_operand:RELOAD 0 "memory_operand" "m")
8586 (match_operand:RELOAD 1 "gpc_reg_operand" "wa")
8587 (match_operand:P 2 "register_operand" "=b")])]
8588 "<P:tptrsize>"
8589 {
8590 rs6000_secondary_reload_inner (operands[1], operands[0], operands[2], true);
8591 DONE;
8592 })
8593
8594 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_load"
8595 [(parallel [(match_operand:RELOAD 0 "gpc_reg_operand" "wa")
8596 (match_operand:RELOAD 1 "memory_operand" "m")
8597 (match_operand:P 2 "register_operand" "=b")])]
8598 "<P:tptrsize>"
8599 {
8600 rs6000_secondary_reload_inner (operands[0], operands[1], operands[2], false);
8601 DONE;
8602 })
8603
8604
8605 ;; Reload sometimes tries to move the address to a GPR, and can generate
8606 ;; invalid RTL for addresses involving AND -16. Allow addresses involving
8607 ;; reg+reg, reg+small constant, or just reg, all wrapped in an AND -16.
8608
8609 (define_insn_and_split "*vec_reload_and_plus_<mptrsize>"
8610 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
8611 (and:P (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
8612 (match_operand:P 2 "reg_or_cint_operand" "rI"))
8613 (const_int -16)))]
8614 "TARGET_ALTIVEC && reload_completed"
8615 "#"
8616 "&& reload_completed"
8617 [(set (match_dup 0)
8618 (plus:P (match_dup 1)
8619 (match_dup 2)))
8620 (set (match_dup 0)
8621 (and:P (match_dup 0)
8622 (const_int -16)))])
8623 \f
8624 ;; Power8 merge instructions to allow direct move to/from floating point
8625 ;; registers in 32-bit mode. We use TF mode to get two registers to move the
8626 ;; individual 32-bit parts across. Subreg doesn't work too well on the TF
8627 ;; value, since it is allocated in reload and not all of the flow information
8628 ;; is setup for it. We have two patterns to do the two moves between gprs and
8629 ;; fprs. There isn't a dependancy between the two, but we could potentially
8630 ;; schedule other instructions between the two instructions.
8631
8632 (define_insn "p8_fmrgow_<mode>"
8633 [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
8634 (unspec:FMOVE64X [
8635 (match_operand:DF 1 "register_operand" "d")
8636 (match_operand:DF 2 "register_operand" "d")]
8637 UNSPEC_P8V_FMRGOW))]
8638 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8639 "fmrgow %0,%1,%2"
8640 [(set_attr "type" "fpsimple")])
8641
8642 (define_insn "p8_mtvsrwz"
8643 [(set (match_operand:DF 0 "register_operand" "=d")
8644 (unspec:DF [(match_operand:SI 1 "register_operand" "r")]
8645 UNSPEC_P8V_MTVSRWZ))]
8646 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8647 "mtvsrwz %x0,%1"
8648 [(set_attr "type" "mftgpr")])
8649
8650 (define_insn_and_split "reload_fpr_from_gpr<mode>"
8651 [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
8652 (unspec:FMOVE64X [(match_operand:FMOVE64X 1 "register_operand" "r")]
8653 UNSPEC_P8V_RELOAD_FROM_GPR))
8654 (clobber (match_operand:IF 2 "register_operand" "=d"))]
8655 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8656 "#"
8657 "&& reload_completed"
8658 [(const_int 0)]
8659 {
8660 rtx dest = operands[0];
8661 rtx src = operands[1];
8662 rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0);
8663 rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8);
8664 rtx gpr_hi_reg = gen_highpart (SImode, src);
8665 rtx gpr_lo_reg = gen_lowpart (SImode, src);
8666
8667 emit_insn (gen_p8_mtvsrwz (tmp_hi, gpr_hi_reg));
8668 emit_insn (gen_p8_mtvsrwz (tmp_lo, gpr_lo_reg));
8669 emit_insn (gen_p8_fmrgow_<mode> (dest, tmp_hi, tmp_lo));
8670 DONE;
8671 }
8672 [(set_attr "length" "12")
8673 (set_attr "type" "three")])
8674
8675 ;; Move 128 bit values from GPRs to VSX registers in 64-bit mode
8676 (define_insn "p8_mtvsrd_df"
8677 [(set (match_operand:DF 0 "register_operand" "=wa")
8678 (unspec:DF [(match_operand:DI 1 "register_operand" "r")]
8679 UNSPEC_P8V_MTVSRD))]
8680 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8681 "mtvsrd %x0,%1"
8682 [(set_attr "type" "mftgpr")])
8683
8684 (define_insn "p8_xxpermdi_<mode>"
8685 [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
8686 (unspec:FMOVE128_GPR [
8687 (match_operand:DF 1 "register_operand" "wa")
8688 (match_operand:DF 2 "register_operand" "wa")]
8689 UNSPEC_P8V_XXPERMDI))]
8690 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8691 "xxpermdi %x0,%x1,%x2,0"
8692 [(set_attr "type" "vecperm")])
8693
8694 (define_insn_and_split "reload_vsx_from_gpr<mode>"
8695 [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
8696 (unspec:FMOVE128_GPR
8697 [(match_operand:FMOVE128_GPR 1 "register_operand" "r")]
8698 UNSPEC_P8V_RELOAD_FROM_GPR))
8699 (clobber (match_operand:IF 2 "register_operand" "=wa"))]
8700 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8701 "#"
8702 "&& reload_completed"
8703 [(const_int 0)]
8704 {
8705 rtx dest = operands[0];
8706 rtx src = operands[1];
8707 /* You might think that we could use op0 as one temp and a DF clobber
8708 as op2, but you'd be wrong. Secondary reload move patterns don't
8709 check for overlap of the clobber and the destination. */
8710 rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0);
8711 rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8);
8712 rtx gpr_hi_reg = gen_highpart (DImode, src);
8713 rtx gpr_lo_reg = gen_lowpart (DImode, src);
8714
8715 emit_insn (gen_p8_mtvsrd_df (tmp_hi, gpr_hi_reg));
8716 emit_insn (gen_p8_mtvsrd_df (tmp_lo, gpr_lo_reg));
8717 emit_insn (gen_p8_xxpermdi_<mode> (dest, tmp_hi, tmp_lo));
8718 DONE;
8719 }
8720 [(set_attr "length" "12")
8721 (set_attr "type" "three")])
8722
8723 (define_split
8724 [(set (match_operand:FMOVE128_GPR 0 "nonimmediate_operand")
8725 (match_operand:FMOVE128_GPR 1 "input_operand"))]
8726 "reload_completed
8727 && (int_reg_operand (operands[0], <MODE>mode)
8728 || int_reg_operand (operands[1], <MODE>mode))
8729 && (!TARGET_DIRECT_MOVE_128
8730 || (!vsx_register_operand (operands[0], <MODE>mode)
8731 && !vsx_register_operand (operands[1], <MODE>mode)))"
8732 [(pc)]
8733 {
8734 rs6000_split_multireg_move (operands[0], operands[1]);
8735 DONE;
8736 })
8737
8738 ;; Move SFmode to a VSX from a GPR register. Because scalar floating point
8739 ;; type is stored internally as double precision in the VSX registers, we have
8740 ;; to convert it from the vector format.
8741 (define_insn "p8_mtvsrd_sf"
8742 [(set (match_operand:SF 0 "register_operand" "=wa")
8743 (unspec:SF [(match_operand:DI 1 "register_operand" "r")]
8744 UNSPEC_P8V_MTVSRD))]
8745 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8746 "mtvsrd %x0,%1"
8747 [(set_attr "type" "mftgpr")])
8748
8749 (define_insn_and_split "reload_vsx_from_gprsf"
8750 [(set (match_operand:SF 0 "register_operand" "=wa")
8751 (unspec:SF [(match_operand:SF 1 "register_operand" "r")]
8752 UNSPEC_P8V_RELOAD_FROM_GPR))
8753 (clobber (match_operand:DI 2 "register_operand" "=r"))]
8754 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8755 "#"
8756 "&& reload_completed"
8757 [(const_int 0)]
8758 {
8759 rtx op0 = operands[0];
8760 rtx op1 = operands[1];
8761 rtx op2 = operands[2];
8762 rtx op1_di = simplify_gen_subreg (DImode, op1, SFmode, 0);
8763
8764 /* Move SF value to upper 32-bits for xscvspdpn. */
8765 emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32)));
8766 emit_insn (gen_p8_mtvsrd_sf (op0, op2));
8767 emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0));
8768 DONE;
8769 }
8770 [(set_attr "length" "8")
8771 (set_attr "type" "two")])
8772
8773 ;; Move 128 bit values from VSX registers to GPRs in 64-bit mode by doing a
8774 ;; normal 64-bit move, followed by an xxpermdi to get the bottom 64-bit value,
8775 ;; and then doing a move of that.
8776 (define_insn "p8_mfvsrd_3_<mode>"
8777 [(set (match_operand:DF 0 "register_operand" "=r")
8778 (unspec:DF [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
8779 UNSPEC_P8V_RELOAD_FROM_VSX))]
8780 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8781 "mfvsrd %0,%x1"
8782 [(set_attr "type" "mftgpr")])
8783
8784 (define_insn_and_split "reload_gpr_from_vsx<mode>"
8785 [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=r")
8786 (unspec:FMOVE128_GPR
8787 [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
8788 UNSPEC_P8V_RELOAD_FROM_VSX))
8789 (clobber (match_operand:FMOVE128_GPR 2 "register_operand" "=wa"))]
8790 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8791 "#"
8792 "&& reload_completed"
8793 [(const_int 0)]
8794 {
8795 rtx dest = operands[0];
8796 rtx src = operands[1];
8797 rtx tmp = operands[2];
8798 rtx gpr_hi_reg = gen_highpart (DFmode, dest);
8799 rtx gpr_lo_reg = gen_lowpart (DFmode, dest);
8800
8801 emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_hi_reg, src));
8802 emit_insn (gen_vsx_xxpermdi_<mode>_be (tmp, src, src, GEN_INT (3)));
8803 emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_lo_reg, tmp));
8804 DONE;
8805 }
8806 [(set_attr "length" "12")
8807 (set_attr "type" "three")])
8808
8809 ;; Move SFmode to a GPR from a VSX register. Because scalar floating point
8810 ;; type is stored internally as double precision, we have to convert it to the
8811 ;; vector format.
8812
8813 (define_insn_and_split "reload_gpr_from_vsxsf"
8814 [(set (match_operand:SF 0 "register_operand" "=r")
8815 (unspec:SF [(match_operand:SF 1 "register_operand" "wa")]
8816 UNSPEC_P8V_RELOAD_FROM_VSX))
8817 (clobber (match_operand:V4SF 2 "register_operand" "=wa"))]
8818 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8819 "#"
8820 "&& reload_completed"
8821 [(const_int 0)]
8822 {
8823 rtx op0 = operands[0];
8824 rtx op1 = operands[1];
8825 rtx op2 = operands[2];
8826 rtx op0_di = gen_rtx_REG (DImode, reg_or_subregno (op0));
8827 rtx op2_si = gen_rtx_REG (SImode, reg_or_subregno (op2));
8828
8829 emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
8830 emit_insn (gen_zero_extendsidi2 (op0_di, op2_si));
8831 DONE;
8832 }
8833 [(set_attr "length" "8")
8834 (set_attr "type" "two")
8835 (set_attr "isa" "p8v")])
8836 \f
8837 ;; Next come the multi-word integer load and store and the load and store
8838 ;; multiple insns.
8839
8840 ;; List r->r after r->Y, otherwise reload will try to reload a
8841 ;; non-offsettable address by using r->r which won't make progress.
8842 ;; Use of fprs is disparaged slightly otherwise reload prefers to reload
8843 ;; a gpr into a fpr instead of reloading an invalid 'Y' address
8844
8845 ;; GPR store GPR load GPR move FPR store FPR load FPR move
8846 ;; GPR const AVX store AVX store AVX load AVX load VSX move
8847 ;; P9 0 P9 -1 AVX 0/-1 VSX 0 VSX -1 P9 const
8848 ;; AVX const
8849
8850 (define_insn "*movdi_internal32"
8851 [(set (match_operand:DI 0 "nonimmediate_operand"
8852 "=Y, r, r, m, ^d, ^d,
8853 r, wY, Z, ^v, $v, ^wa,
8854 wa, wa, v, wa, *i, v,
8855 v")
8856 (match_operand:DI 1 "input_operand"
8857 "r, Y, r, ^d, m, ^d,
8858 IJKnF, ^v, $v, wY, Z, ^wa,
8859 Oj, wM, OjwM, Oj, wM, wS,
8860 wB"))]
8861 "! TARGET_POWERPC64
8862 && (gpc_reg_operand (operands[0], DImode)
8863 || gpc_reg_operand (operands[1], DImode))"
8864 "@
8865 #
8866 #
8867 #
8868 stfd%U0%X0 %1,%0
8869 lfd%U1%X1 %0,%1
8870 fmr %0,%1
8871 #
8872 stxsd %1,%0
8873 stxsdx %x1,%y0
8874 lxsd %0,%1
8875 lxsdx %x0,%y1
8876 xxlor %x0,%x1,%x1
8877 xxspltib %x0,0
8878 xxspltib %x0,255
8879 vspltisw %0,%1
8880 xxlxor %x0,%x0,%x0
8881 xxlorc %x0,%x0,%x0
8882 #
8883 #"
8884 [(set_attr "type"
8885 "store, load, *, fpstore, fpload, fpsimple,
8886 *, fpstore, fpstore, fpload, fpload, veclogical,
8887 vecsimple, vecsimple, vecsimple, veclogical,veclogical,vecsimple,
8888 vecsimple")
8889 (set_attr "size" "64")
8890 (set_attr "length"
8891 "8, 8, 8, *, *, *,
8892 16, *, *, *, *, *,
8893 *, *, *, *, *, 8,
8894 *")
8895 (set_attr "isa"
8896 "*, *, *, *, *, *,
8897 *, p9v, p7v, p9v, p7v, *,
8898 p9v, p9v, p7v, *, *, p7v,
8899 p7v")])
8900
8901 (define_split
8902 [(set (match_operand:DI 0 "gpc_reg_operand")
8903 (match_operand:DI 1 "const_int_operand"))]
8904 "! TARGET_POWERPC64 && reload_completed
8905 && gpr_or_gpr_p (operands[0], operands[1])
8906 && !direct_move_p (operands[0], operands[1])"
8907 [(set (match_dup 2) (match_dup 4))
8908 (set (match_dup 3) (match_dup 1))]
8909 {
8910 HOST_WIDE_INT value = INTVAL (operands[1]);
8911 operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
8912 DImode);
8913 operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
8914 DImode);
8915 operands[4] = GEN_INT (value >> 32);
8916 operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
8917 })
8918
8919 (define_split
8920 [(set (match_operand:DIFD 0 "nonimmediate_operand")
8921 (match_operand:DIFD 1 "input_operand"))]
8922 "reload_completed && !TARGET_POWERPC64
8923 && gpr_or_gpr_p (operands[0], operands[1])
8924 && !direct_move_p (operands[0], operands[1])"
8925 [(pc)]
8926 {
8927 rs6000_split_multireg_move (operands[0], operands[1]);
8928 DONE;
8929 })
8930
8931 ;; GPR store GPR load GPR move
8932 ;; GPR li GPR lis GPR pli GPR #
8933 ;; FPR store FPR load FPR move
8934 ;; AVX store AVX store AVX load AVX load VSX move
8935 ;; P9 0 P9 -1 AVX 0/-1 VSX 0 VSX -1
8936 ;; P9 const AVX const
8937 ;; From SPR To SPR SPR<->SPR
8938 ;; VSX->GPR GPR->VSX
8939 (define_insn "*movdi_internal64"
8940 [(set (match_operand:DI 0 "nonimmediate_operand"
8941 "=YZ, r, r,
8942 r, r, r, r,
8943 m, ^d, ^d,
8944 wY, Z, $v, $v, ^wa,
8945 wa, wa, v, wa, wa,
8946 v, v,
8947 r, *h, *h,
8948 ?r, ?wa")
8949 (match_operand:DI 1 "input_operand"
8950 "r, YZ, r,
8951 I, L, eI, nF,
8952 ^d, m, ^d,
8953 ^v, $v, wY, Z, ^wa,
8954 Oj, wM, OjwM, Oj, wM,
8955 wS, wB,
8956 *h, r, 0,
8957 wa, r"))]
8958 "TARGET_POWERPC64
8959 && (gpc_reg_operand (operands[0], DImode)
8960 || gpc_reg_operand (operands[1], DImode))"
8961 "@
8962 std%U0%X0 %1,%0
8963 ld%U1%X1 %0,%1
8964 mr %0,%1
8965 li %0,%1
8966 lis %0,%v1
8967 li %0,%1
8968 #
8969 stfd%U0%X0 %1,%0
8970 lfd%U1%X1 %0,%1
8971 fmr %0,%1
8972 stxsd %1,%0
8973 stxsdx %x1,%y0
8974 lxsd %0,%1
8975 lxsdx %x0,%y1
8976 xxlor %x0,%x1,%x1
8977 xxspltib %x0,0
8978 xxspltib %x0,255
8979 #
8980 xxlxor %x0,%x0,%x0
8981 xxlorc %x0,%x0,%x0
8982 #
8983 #
8984 mf%1 %0
8985 mt%0 %1
8986 nop
8987 mfvsrd %0,%x1
8988 mtvsrd %x0,%1"
8989 [(set_attr "type"
8990 "store, load, *,
8991 *, *, *, *,
8992 fpstore, fpload, fpsimple,
8993 fpstore, fpstore, fpload, fpload, veclogical,
8994 vecsimple, vecsimple, vecsimple, veclogical, veclogical,
8995 vecsimple, vecsimple,
8996 mfjmpr, mtjmpr, *,
8997 mftgpr, mffgpr")
8998 (set_attr "size" "64")
8999 (set_attr "length"
9000 "*, *, *,
9001 *, *, *, 20,
9002 *, *, *,
9003 *, *, *, *, *,
9004 *, *, *, *, *,
9005 8, *,
9006 *, *, *,
9007 *, *")
9008 (set_attr "isa"
9009 "*, *, *,
9010 *, *, p10, *,
9011 *, *, *,
9012 p9v, p7v, p9v, p7v, *,
9013 p9v, p9v, p7v, *, *,
9014 p7v, p7v,
9015 *, *, *,
9016 p8v, p8v")])
9017
9018 ; Some DImode loads are best done as a load of -1 followed by a mask
9019 ; instruction.
9020 (define_split
9021 [(set (match_operand:DI 0 "int_reg_operand_not_pseudo")
9022 (match_operand:DI 1 "const_int_operand"))]
9023 "TARGET_POWERPC64
9024 && num_insns_constant (operands[1], DImode) > 1
9025 && !IN_RANGE (INTVAL (operands[1]), -0x80000000, 0xffffffff)
9026 && rs6000_is_valid_and_mask (operands[1], DImode)"
9027 [(set (match_dup 0)
9028 (const_int -1))
9029 (set (match_dup 0)
9030 (and:DI (match_dup 0)
9031 (match_dup 1)))]
9032 "")
9033
9034 ;; Split a load of a large constant into the appropriate five-instruction
9035 ;; sequence. Handle anything in a constant number of insns.
9036 ;; When non-easy constants can go in the TOC, this should use
9037 ;; easy_fp_constant predicate.
9038 (define_split
9039 [(set (match_operand:DI 0 "int_reg_operand_not_pseudo")
9040 (match_operand:DI 1 "const_int_operand"))]
9041 "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
9042 [(set (match_dup 0) (match_dup 2))
9043 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
9044 {
9045 if (rs6000_emit_set_const (operands[0], operands[1]))
9046 DONE;
9047 else
9048 FAIL;
9049 })
9050
9051 (define_split
9052 [(set (match_operand:DI 0 "int_reg_operand_not_pseudo")
9053 (match_operand:DI 1 "const_scalar_int_operand"))]
9054 "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
9055 [(set (match_dup 0) (match_dup 2))
9056 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
9057 {
9058 if (rs6000_emit_set_const (operands[0], operands[1]))
9059 DONE;
9060 else
9061 FAIL;
9062 })
9063
9064 (define_split
9065 [(set (match_operand:DI 0 "altivec_register_operand")
9066 (match_operand:DI 1 "s5bit_cint_operand"))]
9067 "TARGET_VSX && reload_completed"
9068 [(const_int 0)]
9069 {
9070 rtx op0 = operands[0];
9071 rtx op1 = operands[1];
9072 int r = REGNO (op0);
9073 rtx op0_v4si = gen_rtx_REG (V4SImode, r);
9074
9075 emit_insn (gen_altivec_vspltisw (op0_v4si, op1));
9076 if (op1 != const0_rtx && op1 != constm1_rtx)
9077 {
9078 rtx op0_v2di = gen_rtx_REG (V2DImode, r);
9079 emit_insn (gen_altivec_vupkhsw (op0_v2di, op0_v4si));
9080 }
9081 DONE;
9082 })
9083
9084 ;; Split integer constants that can be loaded with XXSPLTIB and a
9085 ;; sign extend operation.
9086 (define_split
9087 [(set (match_operand:INT_ISA3 0 "altivec_register_operand")
9088 (match_operand:INT_ISA3 1 "xxspltib_constant_split"))]
9089 "TARGET_P9_VECTOR && reload_completed"
9090 [(const_int 0)]
9091 {
9092 rtx op0 = operands[0];
9093 rtx op1 = operands[1];
9094 int r = REGNO (op0);
9095 rtx op0_v16qi = gen_rtx_REG (V16QImode, r);
9096
9097 emit_insn (gen_xxspltib_v16qi (op0_v16qi, op1));
9098 if (<MODE>mode == DImode)
9099 emit_insn (gen_vsx_sign_extend_qi_di (operands[0], op0_v16qi));
9100 else if (<MODE>mode == SImode)
9101 emit_insn (gen_vsx_sign_extend_qi_si (operands[0], op0_v16qi));
9102 else if (<MODE>mode == HImode)
9103 {
9104 rtx op0_v8hi = gen_rtx_REG (V8HImode, r);
9105 emit_insn (gen_altivec_vupkhsb (op0_v8hi, op0_v16qi));
9106 }
9107 DONE;
9108 })
9109
9110 \f
9111 ;; TImode/PTImode is similar, except that we usually want to compute the
9112 ;; address into a register and use lsi/stsi (the exception is during reload).
9113
9114 (define_insn "*mov<mode>_string"
9115 [(set (match_operand:TI2 0 "reg_or_mem_operand" "=Q,Y,????r,????r,????r,r")
9116 (match_operand:TI2 1 "input_operand" "r,r,Q,Y,r,n"))]
9117 "! TARGET_POWERPC64
9118 && (<MODE>mode != TImode || VECTOR_MEM_NONE_P (TImode))
9119 && (gpc_reg_operand (operands[0], <MODE>mode)
9120 || gpc_reg_operand (operands[1], <MODE>mode))"
9121 "#"
9122 [(set_attr "type" "store,store,load,load,*,*")
9123 (set_attr "update" "yes")
9124 (set_attr "indexed" "yes")
9125 (set_attr "cell_micro" "conditional")])
9126
9127 (define_insn "*mov<mode>_ppc64"
9128 [(set (match_operand:TI2 0 "nonimmediate_operand" "=wQ,Y,r,r,r,r")
9129 (match_operand:TI2 1 "input_operand" "r,r,wQ,Y,r,n"))]
9130 "(TARGET_POWERPC64 && VECTOR_MEM_NONE_P (<MODE>mode)
9131 && (gpc_reg_operand (operands[0], <MODE>mode)
9132 || gpc_reg_operand (operands[1], <MODE>mode)))"
9133 {
9134 return rs6000_output_move_128bit (operands);
9135 }
9136 [(set_attr "type" "store,store,load,load,*,*")
9137 (set_attr "length" "8")
9138 (set_attr "max_prefixed_insns" "2")])
9139
9140 (define_split
9141 [(set (match_operand:TI2 0 "int_reg_operand")
9142 (match_operand:TI2 1 "const_scalar_int_operand"))]
9143 "TARGET_POWERPC64
9144 && (VECTOR_MEM_NONE_P (<MODE>mode)
9145 || (reload_completed && INT_REGNO_P (REGNO (operands[0]))))"
9146 [(set (match_dup 2) (match_dup 4))
9147 (set (match_dup 3) (match_dup 5))]
9148 {
9149 operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
9150 <MODE>mode);
9151 operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
9152 <MODE>mode);
9153 if (CONST_WIDE_INT_P (operands[1]))
9154 {
9155 operands[4] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 1));
9156 operands[5] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 0));
9157 }
9158 else if (CONST_INT_P (operands[1]))
9159 {
9160 operands[4] = GEN_INT (- (INTVAL (operands[1]) < 0));
9161 operands[5] = operands[1];
9162 }
9163 else
9164 FAIL;
9165 })
9166
9167 (define_split
9168 [(set (match_operand:TI2 0 "nonimmediate_operand")
9169 (match_operand:TI2 1 "input_operand"))]
9170 "reload_completed
9171 && gpr_or_gpr_p (operands[0], operands[1])
9172 && !direct_move_p (operands[0], operands[1])
9173 && !quad_load_store_p (operands[0], operands[1])"
9174 [(pc)]
9175 {
9176 rs6000_split_multireg_move (operands[0], operands[1]);
9177 DONE;
9178 })
9179 \f
9180 (define_expand "setmemsi"
9181 [(parallel [(set (match_operand:BLK 0 "")
9182 (match_operand 2 "const_int_operand"))
9183 (use (match_operand:SI 1 ""))
9184 (use (match_operand:SI 3 ""))])]
9185 ""
9186 {
9187 /* If value to set is not zero, use the library routine. */
9188 if (operands[2] != const0_rtx)
9189 FAIL;
9190
9191 if (expand_block_clear (operands))
9192 DONE;
9193 else
9194 FAIL;
9195 })
9196
9197 ;; String compare N insn.
9198 ;; Argument 0 is the target (result)
9199 ;; Argument 1 is the destination
9200 ;; Argument 2 is the source
9201 ;; Argument 3 is the length
9202 ;; Argument 4 is the alignment
9203
9204 (define_expand "cmpstrnsi"
9205 [(parallel [(set (match_operand:SI 0)
9206 (compare:SI (match_operand:BLK 1)
9207 (match_operand:BLK 2)))
9208 (use (match_operand:SI 3))
9209 (use (match_operand:SI 4))])]
9210 "TARGET_CMPB && (BYTES_BIG_ENDIAN || TARGET_LDBRX)"
9211 {
9212 if (optimize_insn_for_size_p ())
9213 FAIL;
9214
9215 if (expand_strn_compare (operands, 0))
9216 DONE;
9217 else
9218 FAIL;
9219 })
9220
9221 ;; String compare insn.
9222 ;; Argument 0 is the target (result)
9223 ;; Argument 1 is the destination
9224 ;; Argument 2 is the source
9225 ;; Argument 3 is the alignment
9226
9227 (define_expand "cmpstrsi"
9228 [(parallel [(set (match_operand:SI 0)
9229 (compare:SI (match_operand:BLK 1)
9230 (match_operand:BLK 2)))
9231 (use (match_operand:SI 3))])]
9232 "TARGET_CMPB && (BYTES_BIG_ENDIAN || TARGET_LDBRX)"
9233 {
9234 if (optimize_insn_for_size_p ())
9235 FAIL;
9236
9237 if (expand_strn_compare (operands, 1))
9238 DONE;
9239 else
9240 FAIL;
9241 })
9242
9243 ;; Block compare insn.
9244 ;; Argument 0 is the target (result)
9245 ;; Argument 1 is the destination
9246 ;; Argument 2 is the source
9247 ;; Argument 3 is the length
9248 ;; Argument 4 is the alignment
9249
9250 (define_expand "cmpmemsi"
9251 [(parallel [(set (match_operand:SI 0)
9252 (compare:SI (match_operand:BLK 1)
9253 (match_operand:BLK 2)))
9254 (use (match_operand:SI 3))
9255 (use (match_operand:SI 4))])]
9256 "TARGET_POPCNTD"
9257 {
9258 if (expand_block_compare (operands))
9259 DONE;
9260 else
9261 FAIL;
9262 })
9263
9264 ;; String/block copy insn (source and destination must not overlap).
9265 ;; Argument 0 is the destination
9266 ;; Argument 1 is the source
9267 ;; Argument 2 is the length
9268 ;; Argument 3 is the alignment
9269
9270 (define_expand "cpymemsi"
9271 [(parallel [(set (match_operand:BLK 0 "")
9272 (match_operand:BLK 1 ""))
9273 (use (match_operand:SI 2 ""))
9274 (use (match_operand:SI 3 ""))])]
9275 ""
9276 {
9277 if (expand_block_move (operands, false))
9278 DONE;
9279 else
9280 FAIL;
9281 })
9282
9283 ;; String/block move insn (source and destination may overlap).
9284 ;; Argument 0 is the destination
9285 ;; Argument 1 is the source
9286 ;; Argument 2 is the length
9287 ;; Argument 3 is the alignment
9288
9289 (define_expand "movmemsi"
9290 [(parallel [(set (match_operand:BLK 0 "")
9291 (match_operand:BLK 1 ""))
9292 (use (match_operand:SI 2 ""))
9293 (use (match_operand:SI 3 ""))])]
9294 ""
9295 {
9296 if (expand_block_move (operands, true))
9297 DONE;
9298 else
9299 FAIL;
9300 })
9301
9302 \f
9303 ;; Define insns that do load or store with update. Some of these we can
9304 ;; get by using pre-decrement or pre-increment, but the hardware can also
9305 ;; do cases where the increment is not the size of the object.
9306 ;;
9307 ;; In all these cases, we use operands 0 and 1 for the register being
9308 ;; incremented because those are the operands that local-alloc will
9309 ;; tie and these are the pair most likely to be tieable (and the ones
9310 ;; that will benefit the most).
9311
9312 (define_insn "*movdi_update1"
9313 [(set (match_operand:DI 3 "gpc_reg_operand" "=r,r")
9314 (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9315 (match_operand:P 2 "reg_or_aligned_short_operand" "r,I"))))
9316 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9317 (plus:P (match_dup 1) (match_dup 2)))]
9318 "TARGET_POWERPC64 && TARGET_UPDATE
9319 && (!avoiding_indexed_address_p (DImode)
9320 || !gpc_reg_operand (operands[2], Pmode))"
9321 "@
9322 ldux %3,%0,%2
9323 ldu %3,%2(%0)"
9324 [(set_attr "type" "load")
9325 (set_attr "update" "yes")
9326 (set_attr "indexed" "yes,no")])
9327
9328 (define_insn "movdi_<mode>_update"
9329 [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9330 (match_operand:P 2 "reg_or_aligned_short_operand" "r,I")))
9331 (match_operand:DI 3 "gpc_reg_operand" "r,r"))
9332 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9333 (plus:P (match_dup 1) (match_dup 2)))]
9334 "TARGET_POWERPC64 && TARGET_UPDATE
9335 && (!avoiding_indexed_address_p (DImode)
9336 || !gpc_reg_operand (operands[2], Pmode)
9337 || (REG_P (operands[0])
9338 && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
9339 "@
9340 stdux %3,%0,%2
9341 stdu %3,%2(%0)"
9342 [(set_attr "type" "store")
9343 (set_attr "update" "yes")
9344 (set_attr "indexed" "yes,no")])
9345
9346 ;; This pattern is only conditional on TARGET_64BIT, as it is
9347 ;; needed for stack allocation, even if the user passes -mno-update.
9348 (define_insn "movdi_update_stack"
9349 [(set (mem:DI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0,0")
9350 (match_operand:DI 2 "reg_or_aligned_short_operand" "r,I")))
9351 (match_operand:DI 3 "gpc_reg_operand" "r,r"))
9352 (set (match_operand:DI 0 "gpc_reg_operand" "=b,b")
9353 (plus:DI (match_dup 1) (match_dup 2)))]
9354 "TARGET_64BIT"
9355 "@
9356 stdux %3,%0,%2
9357 stdu %3,%2(%0)"
9358 [(set_attr "type" "store")
9359 (set_attr "update" "yes")
9360 (set_attr "indexed" "yes,no")])
9361
9362 (define_insn "*movsi_update1"
9363 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9364 (mem:SI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9365 (match_operand:P 2 "reg_or_short_operand" "r,I"))))
9366 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9367 (plus:P (match_dup 1) (match_dup 2)))]
9368 "TARGET_UPDATE
9369 && (!avoiding_indexed_address_p (SImode)
9370 || !gpc_reg_operand (operands[2], Pmode))"
9371 "@
9372 lwzux %3,%0,%2
9373 lwzu %3,%2(%0)"
9374 [(set_attr "type" "load")
9375 (set_attr "update" "yes")
9376 (set_attr "indexed" "yes,no")])
9377
9378 (define_insn "*movsi_update2"
9379 [(set (match_operand:EXTSI 3 "gpc_reg_operand" "=r")
9380 (sign_extend:EXTSI
9381 (mem:SI (plus:P (match_operand:P 1 "gpc_reg_operand" "0")
9382 (match_operand:P 2 "gpc_reg_operand" "r")))))
9383 (set (match_operand:P 0 "gpc_reg_operand" "=b")
9384 (plus:P (match_dup 1) (match_dup 2)))]
9385 "TARGET_POWERPC64 && !avoiding_indexed_address_p (DImode)"
9386 "lwaux %3,%0,%2"
9387 [(set_attr "type" "load")
9388 (set_attr "sign_extend" "yes")
9389 (set_attr "update" "yes")
9390 (set_attr "indexed" "yes")])
9391
9392 (define_insn "movsi_<mode>_update"
9393 [(set (mem:SI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9394 (match_operand:P 2 "reg_or_short_operand" "r,I")))
9395 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
9396 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9397 (plus:P (match_dup 1) (match_dup 2)))]
9398 "TARGET_UPDATE
9399 && (!avoiding_indexed_address_p (SImode)
9400 || !gpc_reg_operand (operands[2], Pmode)
9401 || (REG_P (operands[0])
9402 && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
9403 "@
9404 stwux %3,%0,%2
9405 stwu %3,%2(%0)"
9406 [(set_attr "type" "store")
9407 (set_attr "update" "yes")
9408 (set_attr "indexed" "yes,no")])
9409
9410 ;; This is an unconditional pattern; needed for stack allocation, even
9411 ;; if the user passes -mno-update.
9412 (define_insn "movsi_update_stack"
9413 [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9414 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9415 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
9416 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9417 (plus:SI (match_dup 1) (match_dup 2)))]
9418 "TARGET_32BIT"
9419 "@
9420 stwux %3,%0,%2
9421 stwu %3,%2(%0)"
9422 [(set_attr "type" "store")
9423 (set_attr "update" "yes")
9424 (set_attr "indexed" "yes,no")])
9425
9426 (define_insn "*movhi_update1"
9427 [(set (match_operand:HI 3 "gpc_reg_operand" "=r,r")
9428 (mem:HI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9429 (match_operand:P 2 "reg_or_short_operand" "r,I"))))
9430 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9431 (plus:P (match_dup 1) (match_dup 2)))]
9432 "TARGET_UPDATE
9433 && (!avoiding_indexed_address_p (HImode)
9434 || !gpc_reg_operand (operands[2], SImode))"
9435 "@
9436 lhzux %3,%0,%2
9437 lhzu %3,%2(%0)"
9438 [(set_attr "type" "load")
9439 (set_attr "update" "yes")
9440 (set_attr "indexed" "yes,no")])
9441
9442 (define_insn "*movhi_update2"
9443 [(set (match_operand:EXTHI 3 "gpc_reg_operand" "=r,r")
9444 (zero_extend:EXTHI
9445 (mem:HI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9446 (match_operand:P 2 "reg_or_short_operand" "r,I")))))
9447 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9448 (plus:P (match_dup 1) (match_dup 2)))]
9449 "TARGET_UPDATE
9450 && (!avoiding_indexed_address_p (HImode)
9451 || !gpc_reg_operand (operands[2], Pmode))"
9452 "@
9453 lhzux %3,%0,%2
9454 lhzu %3,%2(%0)"
9455 [(set_attr "type" "load")
9456 (set_attr "update" "yes")
9457 (set_attr "indexed" "yes,no")])
9458
9459 (define_insn "*movhi_update3"
9460 [(set (match_operand:EXTHI 3 "gpc_reg_operand" "=r,r")
9461 (sign_extend:EXTHI
9462 (mem:HI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9463 (match_operand:P 2 "reg_or_short_operand" "r,I")))))
9464 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9465 (plus:P (match_dup 1) (match_dup 2)))]
9466 "TARGET_UPDATE
9467 && !(avoiding_indexed_address_p (HImode)
9468 && gpc_reg_operand (operands[2], Pmode))"
9469 "@
9470 lhaux %3,%0,%2
9471 lhau %3,%2(%0)"
9472 [(set_attr "type" "load")
9473 (set_attr "sign_extend" "yes")
9474 (set_attr "update" "yes")
9475 (set_attr "indexed" "yes,no")])
9476
9477 (define_insn "*movhi_update4"
9478 [(set (mem:HI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9479 (match_operand:P 2 "reg_or_short_operand" "r,I")))
9480 (match_operand:HI 3 "gpc_reg_operand" "r,r"))
9481 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9482 (plus:P (match_dup 1) (match_dup 2)))]
9483 "TARGET_UPDATE
9484 && (!avoiding_indexed_address_p (HImode)
9485 || !gpc_reg_operand (operands[2], Pmode))"
9486 "@
9487 sthux %3,%0,%2
9488 sthu %3,%2(%0)"
9489 [(set_attr "type" "store")
9490 (set_attr "update" "yes")
9491 (set_attr "indexed" "yes,no")])
9492
9493 (define_insn "*movqi_update1"
9494 [(set (match_operand:QI 3 "gpc_reg_operand" "=r,r")
9495 (mem:QI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9496 (match_operand:P 2 "reg_or_short_operand" "r,I"))))
9497 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9498 (plus:P (match_dup 1) (match_dup 2)))]
9499 "TARGET_UPDATE
9500 && (!avoiding_indexed_address_p (QImode)
9501 || !gpc_reg_operand (operands[2], Pmode))"
9502 "@
9503 lbzux %3,%0,%2
9504 lbzu %3,%2(%0)"
9505 [(set_attr "type" "load")
9506 (set_attr "update" "yes")
9507 (set_attr "indexed" "yes,no")])
9508
9509 (define_insn "*movqi_update2"
9510 [(set (match_operand:EXTQI 3 "gpc_reg_operand" "=r,r")
9511 (zero_extend:EXTQI
9512 (mem:QI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9513 (match_operand:P 2 "reg_or_short_operand" "r,I")))))
9514 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9515 (plus:P (match_dup 1) (match_dup 2)))]
9516 "TARGET_UPDATE
9517 && (!avoiding_indexed_address_p (QImode)
9518 || !gpc_reg_operand (operands[2], Pmode))"
9519 "@
9520 lbzux %3,%0,%2
9521 lbzu %3,%2(%0)"
9522 [(set_attr "type" "load")
9523 (set_attr "update" "yes")
9524 (set_attr "indexed" "yes,no")])
9525
9526 (define_insn "*movqi_update3"
9527 [(set (mem:QI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9528 (match_operand:P 2 "reg_or_short_operand" "r,I")))
9529 (match_operand:QI 3 "gpc_reg_operand" "r,r"))
9530 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9531 (plus:P (match_dup 1) (match_dup 2)))]
9532 "TARGET_UPDATE
9533 && (!avoiding_indexed_address_p (QImode)
9534 || !gpc_reg_operand (operands[2], Pmode))"
9535 "@
9536 stbux %3,%0,%2
9537 stbu %3,%2(%0)"
9538 [(set_attr "type" "store")
9539 (set_attr "update" "yes")
9540 (set_attr "indexed" "yes,no")])
9541
9542 (define_insn "*mov<SFDF:mode>_update1"
9543 [(set (match_operand:SFDF 3 "gpc_reg_operand" "=<SFDF:Ff>,<SFDF:Ff>")
9544 (mem:SFDF (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9545 (match_operand:P 2 "reg_or_short_operand" "r,I"))))
9546 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9547 (plus:P (match_dup 1) (match_dup 2)))]
9548 "TARGET_HARD_FLOAT && TARGET_UPDATE
9549 && (!avoiding_indexed_address_p (<SFDF:MODE>mode)
9550 || !gpc_reg_operand (operands[2], Pmode))"
9551 "@
9552 lf<sd>ux %3,%0,%2
9553 lf<sd>u %3,%2(%0)"
9554 [(set_attr "type" "fpload")
9555 (set_attr "update" "yes")
9556 (set_attr "indexed" "yes,no")
9557 (set_attr "size" "<SFDF:bits>")])
9558
9559 (define_insn "*mov<SFDF:mode>_update2"
9560 [(set (mem:SFDF (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9561 (match_operand:P 2 "reg_or_short_operand" "r,I")))
9562 (match_operand:SFDF 3 "gpc_reg_operand" "<SFDF:Ff>,<SFDF:Ff>"))
9563 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9564 (plus:P (match_dup 1) (match_dup 2)))]
9565 "TARGET_HARD_FLOAT && TARGET_UPDATE
9566 && (!avoiding_indexed_address_p (<SFDF:MODE>mode)
9567 || !gpc_reg_operand (operands[2], Pmode))"
9568 "@
9569 stf<sd>ux %3,%0,%2
9570 stf<sd>u %3,%2(%0)"
9571 [(set_attr "type" "fpstore")
9572 (set_attr "update" "yes")
9573 (set_attr "indexed" "yes,no")
9574 (set_attr "size" "<SFDF:bits>")])
9575
9576 (define_insn "*movsf_update3"
9577 [(set (match_operand:SF 3 "gpc_reg_operand" "=r,r")
9578 (mem:SF (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9579 (match_operand:P 2 "reg_or_short_operand" "r,I"))))
9580 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9581 (plus:P (match_dup 1) (match_dup 2)))]
9582 "TARGET_SOFT_FLOAT && TARGET_UPDATE
9583 && (!avoiding_indexed_address_p (SFmode)
9584 || !gpc_reg_operand (operands[2], Pmode))"
9585 "@
9586 lwzux %3,%0,%2
9587 lwzu %3,%2(%0)"
9588 [(set_attr "type" "load")
9589 (set_attr "update" "yes")
9590 (set_attr "indexed" "yes,no")])
9591
9592 (define_insn "*movsf_update4"
9593 [(set (mem:SF (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9594 (match_operand:P 2 "reg_or_short_operand" "r,I")))
9595 (match_operand:SF 3 "gpc_reg_operand" "r,r"))
9596 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9597 (plus:P (match_dup 1) (match_dup 2)))]
9598 "TARGET_SOFT_FLOAT && TARGET_UPDATE
9599 && (!avoiding_indexed_address_p (SFmode)
9600 || !gpc_reg_operand (operands[2], Pmode))"
9601 "@
9602 stwux %3,%0,%2
9603 stwu %3,%2(%0)"
9604 [(set_attr "type" "store")
9605 (set_attr "update" "yes")
9606 (set_attr "indexed" "yes,no")])
9607
9608
9609 ;; After inserting conditional returns we can sometimes have
9610 ;; unnecessary register moves. Unfortunately we cannot have a
9611 ;; modeless peephole here, because some single SImode sets have early
9612 ;; clobber outputs. Although those sets expand to multi-ppc-insn
9613 ;; sequences, using get_attr_length here will smash the operands
9614 ;; array. Neither is there an early_cobbler_p predicate.
9615 ;; Also this optimization interferes with scalars going into
9616 ;; altivec registers (the code does reloading through the FPRs).
9617 (define_peephole2
9618 [(set (match_operand:DF 0 "gpc_reg_operand")
9619 (match_operand:DF 1 "any_operand"))
9620 (set (match_operand:DF 2 "gpc_reg_operand")
9621 (match_dup 0))]
9622 "!TARGET_VSX
9623 && peep2_reg_dead_p (2, operands[0])"
9624 [(set (match_dup 2) (match_dup 1))])
9625
9626 (define_peephole2
9627 [(set (match_operand:SF 0 "gpc_reg_operand")
9628 (match_operand:SF 1 "any_operand"))
9629 (set (match_operand:SF 2 "gpc_reg_operand")
9630 (match_dup 0))]
9631 "!TARGET_P8_VECTOR
9632 && peep2_reg_dead_p (2, operands[0])"
9633 [(set (match_dup 2) (match_dup 1))])
9634
9635 \f
9636 ;; TLS support.
9637
9638 (define_insn "*tls_gd_pcrel<bits>"
9639 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9640 (unspec:P [(match_operand:P 1 "rs6000_tls_symbol_ref" "")
9641 (const_int 0)]
9642 UNSPEC_TLSGD))]
9643 "HAVE_AS_TLS && TARGET_ELF"
9644 "la %0,%1@got@tlsgd@pcrel"
9645 [(set_attr "prefixed" "yes")])
9646
9647 (define_insn_and_split "*tls_gd<bits>"
9648 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9649 (unspec:P [(match_operand:P 1 "rs6000_tls_symbol_ref" "")
9650 (match_operand:P 2 "gpc_reg_operand" "b")]
9651 UNSPEC_TLSGD))]
9652 "HAVE_AS_TLS && TARGET_ELF"
9653 "addi %0,%2,%1@got@tlsgd"
9654 "&& TARGET_CMODEL != CMODEL_SMALL"
9655 [(set (match_dup 3)
9656 (high:P
9657 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))
9658 (set (match_dup 0)
9659 (lo_sum:P (match_dup 3)
9660 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))]
9661 {
9662 operands[3] = gen_reg_rtx (<MODE>mode);
9663 }
9664 [(set (attr "length")
9665 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9666 (const_int 8)
9667 (const_int 4)))])
9668
9669 (define_insn "*tls_gd_high<bits>"
9670 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9671 (high:P
9672 (unspec:P [(match_operand:P 1 "rs6000_tls_symbol_ref" "")
9673 (match_operand:P 2 "gpc_reg_operand" "b")]
9674 UNSPEC_TLSGD)))]
9675 "HAVE_AS_TLS && TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
9676 "addis %0,%2,%1@got@tlsgd@ha")
9677
9678 (define_insn "*tls_gd_low<bits>"
9679 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9680 (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
9681 (unspec:P [(match_operand:P 2 "rs6000_tls_symbol_ref" "")
9682 (match_operand:P 3 "gpc_reg_operand" "b")]
9683 UNSPEC_TLSGD)))]
9684 "HAVE_AS_TLS && TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
9685 "addi %0,%1,%2@got@tlsgd@l")
9686
9687 (define_insn "*tls_ld_pcrel<bits>"
9688 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9689 (unspec:P [(const_int 0)]
9690 UNSPEC_TLSLD))]
9691 "HAVE_AS_TLS && TARGET_ELF"
9692 "la %0,%&@got@tlsld@pcrel"
9693 [(set_attr "prefixed" "yes")])
9694
9695 (define_insn_and_split "*tls_ld<bits>"
9696 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9697 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")]
9698 UNSPEC_TLSLD))]
9699 "HAVE_AS_TLS && TARGET_ELF"
9700 "addi %0,%1,%&@got@tlsld"
9701 "&& TARGET_CMODEL != CMODEL_SMALL"
9702 [(set (match_dup 2)
9703 (high:P
9704 (unspec:P [(match_dup 1)] UNSPEC_TLSLD)))
9705 (set (match_dup 0)
9706 (lo_sum:P (match_dup 2)
9707 (unspec:P [(match_dup 1)] UNSPEC_TLSLD)))]
9708 {
9709 operands[2] = gen_reg_rtx (<MODE>mode);
9710 }
9711 [(set (attr "length")
9712 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9713 (const_int 8)
9714 (const_int 4)))])
9715
9716 (define_insn "*tls_ld_high<bits>"
9717 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9718 (high:P
9719 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")]
9720 UNSPEC_TLSLD)))]
9721 "HAVE_AS_TLS && TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
9722 "addis %0,%1,%&@got@tlsld@ha")
9723
9724 (define_insn "*tls_ld_low<bits>"
9725 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9726 (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
9727 (unspec:P [(match_operand:P 2 "gpc_reg_operand" "b")]
9728 UNSPEC_TLSLD)))]
9729 "HAVE_AS_TLS && TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
9730 "addi %0,%1,%&@got@tlsld@l")
9731
9732 (define_insn "tls_dtprel_<bits>"
9733 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9734 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9735 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9736 UNSPEC_TLSDTPREL))]
9737 "HAVE_AS_TLS"
9738 "addi %0,%1,%2@dtprel"
9739 [(set (attr "prefixed")
9740 (if_then_else (match_test "rs6000_tls_size == 16")
9741 (const_string "no")
9742 (const_string "yes")))])
9743
9744 (define_insn "tls_dtprel_ha_<bits>"
9745 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9746 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9747 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9748 UNSPEC_TLSDTPRELHA))]
9749 "HAVE_AS_TLS"
9750 "addis %0,%1,%2@dtprel@ha")
9751
9752 (define_insn "tls_dtprel_lo_<bits>"
9753 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9754 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9755 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9756 UNSPEC_TLSDTPRELLO))]
9757 "HAVE_AS_TLS"
9758 "addi %0,%1,%2@dtprel@l")
9759
9760 (define_insn_and_split "tls_got_dtprel_<bits>"
9761 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9762 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9763 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9764 UNSPEC_TLSGOTDTPREL))]
9765 "HAVE_AS_TLS"
9766 "<ptrload> %0,%2@got@dtprel(%1)"
9767 "&& TARGET_CMODEL != CMODEL_SMALL"
9768 [(set (match_dup 3)
9769 (high:P
9770 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))
9771 (set (match_dup 0)
9772 (lo_sum:P (match_dup 3)
9773 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))]
9774 {
9775 operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9776 }
9777 [(set (attr "length")
9778 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9779 (const_int 8)
9780 (const_int 4)))])
9781
9782 (define_insn "*tls_got_dtprel_high<bits>"
9783 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9784 (high:P
9785 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9786 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9787 UNSPEC_TLSGOTDTPREL)))]
9788 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9789 "addis %0,%1,%2@got@dtprel@ha")
9790
9791 (define_insn "*tls_got_dtprel_low<bits>"
9792 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9793 (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
9794 (unspec:P [(match_operand:P 3 "gpc_reg_operand" "b")
9795 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9796 UNSPEC_TLSGOTDTPREL)))]
9797 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9798 "<ptrload> %0,%2@got@dtprel@l(%1)")
9799
9800 (define_insn "tls_tprel_<bits>"
9801 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9802 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9803 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9804 UNSPEC_TLSTPREL))]
9805 "HAVE_AS_TLS"
9806 "addi %0,%1,%2@tprel"
9807 [(set (attr "prefixed")
9808 (if_then_else (match_test "rs6000_tls_size == 16")
9809 (const_string "no")
9810 (const_string "yes")))])
9811
9812 (define_insn "tls_tprel_ha_<bits>"
9813 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9814 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9815 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9816 UNSPEC_TLSTPRELHA))]
9817 "HAVE_AS_TLS"
9818 "addis %0,%1,%2@tprel@ha")
9819
9820 (define_insn "tls_tprel_lo_<bits>"
9821 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9822 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9823 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9824 UNSPEC_TLSTPRELLO))]
9825 "HAVE_AS_TLS"
9826 "addi %0,%1,%2@tprel@l")
9827
9828 (define_insn "*tls_got_tprel_pcrel_<bits>"
9829 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9830 (unspec:P [(const_int 0)
9831 (match_operand:P 1 "rs6000_tls_symbol_ref" "")]
9832 UNSPEC_TLSGOTTPREL))]
9833 "HAVE_AS_TLS"
9834 "<ptrload> %0,%1@got@tprel@pcrel"
9835 [(set_attr "prefixed" "yes")])
9836
9837 ;; "b" output constraint here and on tls_tls input to support linker tls
9838 ;; optimization. The linker may edit the instructions emitted by a
9839 ;; tls_got_tprel/tls_tls pair to addis,addi.
9840 (define_insn_and_split "tls_got_tprel_<bits>"
9841 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9842 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9843 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9844 UNSPEC_TLSGOTTPREL))]
9845 "HAVE_AS_TLS"
9846 "<ptrload> %0,%2@got@tprel(%1)"
9847 "&& TARGET_CMODEL != CMODEL_SMALL"
9848 [(set (match_dup 3)
9849 (high:P
9850 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))
9851 (set (match_dup 0)
9852 (lo_sum:P (match_dup 3)
9853 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))]
9854 {
9855 operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9856 }
9857 [(set (attr "length")
9858 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9859 (const_int 8)
9860 (const_int 4)))])
9861
9862 (define_insn "*tls_got_tprel_high<bits>"
9863 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9864 (high:P
9865 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9866 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9867 UNSPEC_TLSGOTTPREL)))]
9868 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9869 "addis %0,%1,%2@got@tprel@ha")
9870
9871 (define_insn "*tls_got_tprel_low<bits>"
9872 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9873 (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
9874 (unspec:P [(match_operand:P 3 "gpc_reg_operand" "b")
9875 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9876 UNSPEC_TLSGOTTPREL)))]
9877 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9878 "<ptrload> %0,%2@got@tprel@l(%1)")
9879
9880 (define_insn "tls_tls_pcrel_<bits>"
9881 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9882 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9883 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9884 UNSPEC_TLSTLS_PCREL))]
9885 "TARGET_ELF && HAVE_AS_TLS"
9886 "add %0,%1,%2@tls@pcrel")
9887
9888 (define_insn "tls_tls_<bits>"
9889 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9890 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9891 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9892 UNSPEC_TLSTLS))]
9893 "TARGET_ELF && HAVE_AS_TLS"
9894 "add %0,%1,%2@tls")
9895
9896 (define_expand "tls_get_tpointer"
9897 [(set (match_operand:SI 0 "gpc_reg_operand")
9898 (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))]
9899 "TARGET_XCOFF && HAVE_AS_TLS"
9900 {
9901 emit_insn (gen_tls_get_tpointer_internal ());
9902 emit_move_insn (operands[0], gen_rtx_REG (SImode, 3));
9903 DONE;
9904 })
9905
9906 (define_insn "tls_get_tpointer_internal"
9907 [(set (reg:SI 3)
9908 (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))
9909 (clobber (reg:SI LR_REGNO))]
9910 "TARGET_XCOFF && HAVE_AS_TLS"
9911 "bla __get_tpointer")
9912
9913 (define_expand "tls_get_addr<mode>"
9914 [(set (match_operand:P 0 "gpc_reg_operand")
9915 (unspec:P [(match_operand:P 1 "gpc_reg_operand")
9916 (match_operand:P 2 "gpc_reg_operand")] UNSPEC_TLSTLS))]
9917 "TARGET_XCOFF && HAVE_AS_TLS"
9918 {
9919 emit_move_insn (gen_rtx_REG (Pmode, 3), operands[1]);
9920 emit_move_insn (gen_rtx_REG (Pmode, 4), operands[2]);
9921 emit_insn (gen_tls_get_addr_internal<mode> ());
9922 emit_move_insn (operands[0], gen_rtx_REG (Pmode, 3));
9923 DONE;
9924 })
9925
9926 (define_insn "tls_get_addr_internal<mode>"
9927 [(set (reg:P 3)
9928 (unspec:P [(reg:P 3) (reg:P 4)] UNSPEC_TLSTLS))
9929 (clobber (reg:P 0))
9930 (clobber (reg:P 4))
9931 (clobber (reg:P 5))
9932 (clobber (reg:P 11))
9933 (clobber (reg:CC CR0_REGNO))
9934 (clobber (reg:P LR_REGNO))]
9935 "TARGET_XCOFF && HAVE_AS_TLS"
9936 "bla __tls_get_addr")
9937 \f
9938 ;; Next come insns related to the calling sequence.
9939 ;;
9940 ;; First, an insn to allocate new stack space for dynamic use (e.g., alloca).
9941 ;; We move the back-chain and decrement the stack pointer.
9942 ;;
9943 ;; Operand1 is more naturally reg_or_short_operand. However, for a large
9944 ;; constant alloca, using that predicate will force the generic code to put
9945 ;; the constant size into a register before calling the expander.
9946 ;;
9947 ;; As a result the expander would not have the constant size information
9948 ;; in those cases and would have to generate less efficient code.
9949 ;;
9950 ;; Thus we allow reg_or_cint_operand instead so that the expander can see
9951 ;; the constant size. The value is forced into a register if necessary.
9952 ;;
9953 (define_expand "allocate_stack"
9954 [(set (match_operand 0 "gpc_reg_operand")
9955 (minus (reg 1) (match_operand 1 "reg_or_cint_operand")))
9956 (set (reg 1)
9957 (minus (reg 1) (match_dup 1)))]
9958 ""
9959 {
9960 rtx chain = gen_reg_rtx (Pmode);
9961 rtx stack_bot = gen_rtx_MEM (Pmode, stack_pointer_rtx);
9962 rtx neg_op0;
9963 rtx insn, par, set, mem;
9964
9965 /* By allowing reg_or_cint_operand as the predicate we can get
9966 better code for stack-clash-protection because we do not lose
9967 size information. But the rest of the code expects the operand
9968 to be reg_or_short_operand. If it isn't, then force it into
9969 a register. */
9970 rtx orig_op1 = operands[1];
9971 if (!reg_or_short_operand (operands[1], Pmode))
9972 operands[1] = force_reg (Pmode, operands[1]);
9973
9974 emit_move_insn (chain, stack_bot);
9975
9976 /* Check stack bounds if necessary. */
9977 if (crtl->limit_stack)
9978 {
9979 rtx available;
9980 available = expand_binop (Pmode, sub_optab,
9981 stack_pointer_rtx, stack_limit_rtx,
9982 NULL_RTX, 1, OPTAB_WIDEN);
9983 emit_insn (gen_cond_trap (LTU, available, operands[1], const0_rtx));
9984 }
9985
9986 /* Allocate and probe if requested.
9987 This may look similar to the loop we use for prologue allocations,
9988 but it is critically different. For the former we know the loop
9989 will iterate, but do not know that generally here. The former
9990 uses that knowledge to rotate the loop. Combining them would be
9991 possible with some performance cost. */
9992 if (flag_stack_clash_protection)
9993 {
9994 rtx rounded_size, last_addr, residual;
9995 HOST_WIDE_INT probe_interval;
9996 compute_stack_clash_protection_loop_data (&rounded_size, &last_addr,
9997 &residual, &probe_interval,
9998 orig_op1);
9999
10000 /* We do occasionally get in here with constant sizes, we might
10001 as well do a reasonable job when we obviously can. */
10002 if (rounded_size != const0_rtx)
10003 {
10004 rtx loop_lab, end_loop;
10005 bool rotated = CONST_INT_P (rounded_size);
10006 rtx update = GEN_INT (-probe_interval);
10007 if (probe_interval > 32768)
10008 update = force_reg (Pmode, update);
10009
10010 emit_stack_clash_protection_probe_loop_start (&loop_lab, &end_loop,
10011 last_addr, rotated);
10012
10013 if (TARGET_32BIT)
10014 emit_insn (gen_movsi_update_stack (stack_pointer_rtx,
10015 stack_pointer_rtx,
10016 update, chain));
10017 else
10018 emit_insn (gen_movdi_update_stack (stack_pointer_rtx,
10019 stack_pointer_rtx,
10020 update, chain));
10021 emit_stack_clash_protection_probe_loop_end (loop_lab, end_loop,
10022 last_addr, rotated);
10023 }
10024
10025 /* Now handle residuals. We just have to set operands[1] correctly
10026 and let the rest of the expander run. */
10027 operands[1] = residual;
10028 }
10029
10030 if (!(CONST_INT_P (operands[1])
10031 && IN_RANGE (INTVAL (operands[1]), -32767, 32768)))
10032 {
10033 operands[1] = force_reg (Pmode, operands[1]);
10034 neg_op0 = gen_reg_rtx (Pmode);
10035 emit_insn (gen_neg2 (Pmode, neg_op0, operands[1]));
10036 }
10037 else
10038 neg_op0 = GEN_INT (-INTVAL (operands[1]));
10039
10040 insn = emit_insn ((* ((TARGET_32BIT) ? gen_movsi_update_stack
10041 : gen_movdi_update_stack))
10042 (stack_pointer_rtx, stack_pointer_rtx, neg_op0,
10043 chain));
10044 /* Since we didn't use gen_frame_mem to generate the MEM, grab
10045 it now and set the alias set/attributes. The above gen_*_update
10046 calls will generate a PARALLEL with the MEM set being the first
10047 operation. */
10048 par = PATTERN (insn);
10049 gcc_assert (GET_CODE (par) == PARALLEL);
10050 set = XVECEXP (par, 0, 0);
10051 gcc_assert (GET_CODE (set) == SET);
10052 mem = SET_DEST (set);
10053 gcc_assert (MEM_P (mem));
10054 MEM_NOTRAP_P (mem) = 1;
10055 set_mem_alias_set (mem, get_frame_alias_set ());
10056
10057 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
10058 DONE;
10059 })
10060
10061 ;; These patterns say how to save and restore the stack pointer. We need not
10062 ;; save the stack pointer at function level since we are careful to
10063 ;; preserve the backchain. At block level, we have to restore the backchain
10064 ;; when we restore the stack pointer.
10065 ;;
10066 ;; For nonlocal gotos, we must save both the stack pointer and its
10067 ;; backchain and restore both. Note that in the nonlocal case, the
10068 ;; save area is a memory location.
10069
10070 (define_expand "save_stack_function"
10071 [(match_operand 0 "any_operand")
10072 (match_operand 1 "any_operand")]
10073 ""
10074 "DONE;")
10075
10076 (define_expand "restore_stack_function"
10077 [(match_operand 0 "any_operand")
10078 (match_operand 1 "any_operand")]
10079 ""
10080 "DONE;")
10081
10082 ;; Adjust stack pointer (op0) to a new value (op1).
10083 ;; First copy old stack backchain to new location, and ensure that the
10084 ;; scheduler won't reorder the sp assignment before the backchain write.
10085 (define_expand "restore_stack_block"
10086 [(set (match_dup 2) (match_dup 3))
10087 (set (match_dup 4) (match_dup 2))
10088 (match_dup 5)
10089 (set (match_operand 0 "register_operand")
10090 (match_operand 1 "register_operand"))]
10091 ""
10092 {
10093 rtvec p;
10094
10095 operands[1] = force_reg (Pmode, operands[1]);
10096 operands[2] = gen_reg_rtx (Pmode);
10097 operands[3] = gen_frame_mem (Pmode, operands[0]);
10098 operands[4] = gen_frame_mem (Pmode, operands[1]);
10099 p = rtvec_alloc (1);
10100 RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
10101 const0_rtx);
10102 operands[5] = gen_rtx_PARALLEL (VOIDmode, p);
10103 })
10104
10105 (define_expand "save_stack_nonlocal"
10106 [(set (match_dup 3) (match_dup 4))
10107 (set (match_operand 0 "memory_operand") (match_dup 3))
10108 (set (match_dup 2) (match_operand 1 "register_operand"))]
10109 ""
10110 {
10111 int units_per_word = (TARGET_32BIT) ? 4 : 8;
10112
10113 /* Copy the backchain to the first word, sp to the second. */
10114 operands[0] = adjust_address_nv (operands[0], Pmode, 0);
10115 operands[2] = adjust_address_nv (operands[0], Pmode, units_per_word);
10116 operands[3] = gen_reg_rtx (Pmode);
10117 operands[4] = gen_frame_mem (Pmode, operands[1]);
10118 })
10119
10120 (define_expand "restore_stack_nonlocal"
10121 [(set (match_dup 2) (match_operand 1 "memory_operand"))
10122 (set (match_dup 3) (match_dup 4))
10123 (set (match_dup 5) (match_dup 2))
10124 (match_dup 6)
10125 (set (match_operand 0 "register_operand") (match_dup 3))]
10126 ""
10127 {
10128 int units_per_word = (TARGET_32BIT) ? 4 : 8;
10129 rtvec p;
10130
10131 /* Restore the backchain from the first word, sp from the second. */
10132 operands[2] = gen_reg_rtx (Pmode);
10133 operands[3] = gen_reg_rtx (Pmode);
10134 operands[1] = adjust_address_nv (operands[1], Pmode, 0);
10135 operands[4] = adjust_address_nv (operands[1], Pmode, units_per_word);
10136 operands[5] = gen_frame_mem (Pmode, operands[3]);
10137 p = rtvec_alloc (1);
10138 RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
10139 const0_rtx);
10140 operands[6] = gen_rtx_PARALLEL (VOIDmode, p);
10141 })
10142 \f
10143 ;; Load up a PC-relative address. Print_operand_address will append a @pcrel
10144 ;; to the symbol or label.
10145 (define_insn "*pcrel_local_addr"
10146 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
10147 (match_operand:DI 1 "pcrel_local_address"))]
10148 "TARGET_PCREL"
10149 "la %0,%a1"
10150 [(set_attr "prefixed" "yes")])
10151
10152 ;; Load up a PC-relative address to an external symbol. If the symbol and the
10153 ;; program are both defined in the main program, the linker will optimize this
10154 ;; to a PADDI. Otherwise, it will create a GOT address that is relocated by
10155 ;; the dynamic linker and loaded up. Print_operand_address will append a
10156 ;; @got@pcrel to the symbol.
10157 (define_insn "*pcrel_extern_addr"
10158 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
10159 (match_operand:DI 1 "pcrel_external_address"))]
10160 "TARGET_PCREL"
10161 "ld %0,%a1"
10162 [(set_attr "prefixed" "yes")
10163 (set_attr "type" "load")])
10164
10165 ;; TOC register handling.
10166
10167 ;; Code to initialize the TOC register...
10168
10169 (define_insn "load_toc_aix_si"
10170 [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10171 (unspec:SI [(const_int 0)] UNSPEC_TOC))
10172 (use (reg:SI 2))])]
10173 "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_32BIT"
10174 {
10175 char buf[30];
10176 extern int need_toc_init;
10177 need_toc_init = 1;
10178 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
10179 operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
10180 operands[2] = gen_rtx_REG (Pmode, 2);
10181 return "lwz %0,%1(%2)";
10182 }
10183 [(set_attr "type" "load")
10184 (set_attr "update" "no")
10185 (set_attr "indexed" "no")])
10186
10187 (define_insn "load_toc_aix_di"
10188 [(parallel [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
10189 (unspec:DI [(const_int 0)] UNSPEC_TOC))
10190 (use (reg:DI 2))])]
10191 "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_64BIT"
10192 {
10193 char buf[30];
10194 extern int need_toc_init;
10195 need_toc_init = 1;
10196 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC",
10197 !TARGET_ELF || !TARGET_MINIMAL_TOC);
10198 if (TARGET_ELF)
10199 strcat (buf, "@toc");
10200 operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
10201 operands[2] = gen_rtx_REG (Pmode, 2);
10202 return "ld %0,%1(%2)";
10203 }
10204 [(set_attr "type" "load")
10205 (set_attr "update" "no")
10206 (set_attr "indexed" "no")])
10207
10208 (define_insn "load_toc_v4_pic_si"
10209 [(set (reg:SI LR_REGNO)
10210 (unspec:SI [(const_int 0)] UNSPEC_TOC))]
10211 "DEFAULT_ABI == ABI_V4 && flag_pic == 1 && TARGET_32BIT"
10212 "bl _GLOBAL_OFFSET_TABLE_@local-4"
10213 [(set_attr "type" "branch")])
10214
10215 (define_expand "load_toc_v4_PIC_1"
10216 [(parallel [(set (reg:SI LR_REGNO)
10217 (match_operand:SI 0 "immediate_operand" "s"))
10218 (use (unspec [(match_dup 0)] UNSPEC_TOC))])]
10219 "TARGET_ELF && DEFAULT_ABI == ABI_V4
10220 && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10221 "")
10222
10223 (define_insn "load_toc_v4_PIC_1_normal"
10224 [(set (reg:SI LR_REGNO)
10225 (match_operand:SI 0 "immediate_operand" "s"))
10226 (use (unspec [(match_dup 0)] UNSPEC_TOC))]
10227 "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
10228 && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10229 "bcl 20,31,%0\n%0:"
10230 [(set_attr "type" "branch")
10231 (set_attr "cannot_copy" "yes")])
10232
10233 (define_insn "load_toc_v4_PIC_1_476"
10234 [(set (reg:SI LR_REGNO)
10235 (match_operand:SI 0 "immediate_operand" "s"))
10236 (use (unspec [(match_dup 0)] UNSPEC_TOC))]
10237 "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
10238 && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10239 {
10240 char name[32];
10241 static char templ[32];
10242
10243 get_ppc476_thunk_name (name);
10244 sprintf (templ, "bl %s\n%%0:", name);
10245 return templ;
10246 }
10247 [(set_attr "type" "branch")
10248 (set_attr "cannot_copy" "yes")])
10249
10250 (define_expand "load_toc_v4_PIC_1b"
10251 [(parallel [(set (reg:SI LR_REGNO)
10252 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10253 (label_ref (match_operand 1 ""))]
10254 UNSPEC_TOCPTR))
10255 (match_dup 1)])]
10256 "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10257 "")
10258
10259 (define_insn "load_toc_v4_PIC_1b_normal"
10260 [(set (reg:SI LR_REGNO)
10261 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10262 (label_ref (match_operand 1 "" ""))]
10263 UNSPEC_TOCPTR))
10264 (match_dup 1)]
10265 "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10266 "bcl 20,31,$+8\;.long %0-$"
10267 [(set_attr "type" "branch")
10268 (set_attr "length" "8")])
10269
10270 (define_insn "load_toc_v4_PIC_1b_476"
10271 [(set (reg:SI LR_REGNO)
10272 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10273 (label_ref (match_operand 1 "" ""))]
10274 UNSPEC_TOCPTR))
10275 (match_dup 1)]
10276 "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10277 {
10278 char name[32];
10279 static char templ[32];
10280
10281 get_ppc476_thunk_name (name);
10282 sprintf (templ, "bl %s\;b $+8\;.long %%0-$", name);
10283 return templ;
10284 }
10285 [(set_attr "type" "branch")
10286 (set_attr "length" "16")])
10287
10288 (define_insn "load_toc_v4_PIC_2"
10289 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10290 (mem:SI (plus:SI
10291 (match_operand:SI 1 "gpc_reg_operand" "b")
10292 (const
10293 (minus:SI (match_operand:SI 2 "immediate_operand" "s")
10294 (match_operand:SI 3 "immediate_operand" "s"))))))]
10295 "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10296 "lwz %0,%2-%3(%1)"
10297 [(set_attr "type" "load")])
10298
10299 (define_insn "load_toc_v4_PIC_3b"
10300 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10301 (plus:SI
10302 (match_operand:SI 1 "gpc_reg_operand" "b")
10303 (high:SI
10304 (const
10305 (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
10306 (match_operand:SI 3 "symbol_ref_operand" "s"))))))]
10307 "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
10308 "addis %0,%1,%2-%3@ha")
10309
10310 (define_insn "load_toc_v4_PIC_3c"
10311 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10312 (lo_sum:SI
10313 (match_operand:SI 1 "gpc_reg_operand" "b")
10314 (const
10315 (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
10316 (match_operand:SI 3 "symbol_ref_operand" "s")))))]
10317 "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
10318 "addi %0,%1,%2-%3@l")
10319
10320 ;; If the TOC is shared over a translation unit, as happens with all
10321 ;; the kinds of PIC that we support, we need to restore the TOC
10322 ;; pointer only when jumping over units of translation.
10323 ;; On Darwin, we need to reload the picbase.
10324
10325 (define_expand "builtin_setjmp_receiver"
10326 [(use (label_ref (match_operand 0 "")))]
10327 "(DEFAULT_ABI == ABI_V4 && flag_pic == 1)
10328 || (TARGET_TOC && TARGET_MINIMAL_TOC)
10329 || (DEFAULT_ABI == ABI_DARWIN && flag_pic)"
10330 {
10331 #if TARGET_MACHO
10332 if (DEFAULT_ABI == ABI_DARWIN)
10333 {
10334 rtx picrtx = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME);
10335 rtx picreg = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
10336 rtx tmplabrtx;
10337 char tmplab[20];
10338
10339 crtl->uses_pic_offset_table = 1;
10340 ASM_GENERATE_INTERNAL_LABEL(tmplab, "LSJR",
10341 CODE_LABEL_NUMBER (operands[0]));
10342 tmplabrtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (tmplab));
10343
10344 emit_insn (gen_load_macho_picbase (Pmode, tmplabrtx));
10345 emit_move_insn (picreg, gen_rtx_REG (Pmode, LR_REGNO));
10346 emit_insn (gen_macho_correct_pic (Pmode, picreg, picreg,
10347 picrtx, tmplabrtx));
10348 }
10349 else
10350 #endif
10351 rs6000_emit_load_toc_table (FALSE);
10352 DONE;
10353 })
10354
10355 ;; Largetoc support
10356 (define_insn "*largetoc_high"
10357 [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
10358 (high:DI
10359 (unspec [(match_operand:DI 1 "" "")
10360 (match_operand:DI 2 "gpc_reg_operand" "b")]
10361 UNSPEC_TOCREL)))]
10362 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10363 "addis %0,%2,%1@toc@ha")
10364
10365 (define_insn "*largetoc_high_aix<mode>"
10366 [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
10367 (high:P
10368 (unspec [(match_operand:P 1 "" "")
10369 (match_operand:P 2 "gpc_reg_operand" "b")]
10370 UNSPEC_TOCREL)))]
10371 "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10372 "addis %0,%1@u(%2)")
10373
10374 (define_insn "*largetoc_high_plus"
10375 [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
10376 (high:DI
10377 (plus:DI
10378 (unspec [(match_operand:DI 1 "" "")
10379 (match_operand:DI 2 "gpc_reg_operand" "b")]
10380 UNSPEC_TOCREL)
10381 (match_operand:DI 3 "add_cint_operand" "n"))))]
10382 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10383 "addis %0,%2,%1+%3@toc@ha")
10384
10385 (define_insn "*largetoc_high_plus_aix<mode>"
10386 [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
10387 (high:P
10388 (plus:P
10389 (unspec [(match_operand:P 1 "" "")
10390 (match_operand:P 2 "gpc_reg_operand" "b")]
10391 UNSPEC_TOCREL)
10392 (match_operand:P 3 "add_cint_operand" "n"))))]
10393 "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10394 "addis %0,%1+%3@u(%2)")
10395
10396 (define_insn "*largetoc_low"
10397 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
10398 (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b")
10399 (match_operand:DI 2 "" "")))]
10400 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10401 "addi %0,%1,%2@l")
10402
10403 (define_insn "*largetoc_low_aix<mode>"
10404 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10405 (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
10406 (match_operand:P 2 "" "")))]
10407 "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10408 "la %0,%2@l(%1)")
10409
10410 (define_insn_and_split "*tocref<mode>"
10411 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
10412 (match_operand:P 1 "small_toc_ref" "R"))]
10413 "TARGET_TOC
10414 && legitimate_constant_pool_address_p (operands[1], QImode, false)"
10415 "la %0,%a1"
10416 "&& TARGET_CMODEL != CMODEL_SMALL && reload_completed"
10417 [(set (match_dup 0) (high:P (match_dup 1)))
10418 (set (match_dup 0) (lo_sum:P (match_dup 0) (match_dup 1)))])
10419
10420 ;; Elf specific ways of loading addresses for non-PIC code.
10421 ;; The output of this could be r0, but we make a very strong
10422 ;; preference for a base register because it will usually
10423 ;; be needed there.
10424 (define_insn "elf_high"
10425 [(set (match_operand:SI 0 "gpc_reg_operand" "=b*r")
10426 (high:SI (match_operand 1 "" "")))]
10427 "TARGET_ELF && !TARGET_64BIT && !flag_pic"
10428 "lis %0,%1@ha")
10429
10430 (define_insn "elf_low"
10431 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10432 (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
10433 (match_operand 2 "" "")))]
10434 "TARGET_ELF && !TARGET_64BIT && !flag_pic"
10435 "la %0,%2@l(%1)")
10436
10437 (define_insn "*pltseq_tocsave_<mode>"
10438 [(set (match_operand:P 0 "memory_operand" "=m")
10439 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
10440 (match_operand:P 2 "symbol_ref_operand" "s")
10441 (match_operand:P 3 "" "")]
10442 UNSPEC_PLTSEQ))]
10443 "TARGET_PLTSEQ
10444 && DEFAULT_ABI == ABI_ELFv2"
10445 {
10446 return rs6000_pltseq_template (operands, RS6000_PLTSEQ_TOCSAVE);
10447 })
10448
10449 (define_insn "*pltseq_plt16_ha_<mode>"
10450 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10451 (unspec:P [(match_operand:P 1 "" "")
10452 (match_operand:P 2 "symbol_ref_operand" "s")
10453 (match_operand:P 3 "" "")]
10454 UNSPEC_PLT16_HA))]
10455 "TARGET_PLTSEQ"
10456 {
10457 return rs6000_pltseq_template (operands, RS6000_PLTSEQ_PLT16_HA);
10458 })
10459
10460 (define_insn "*pltseq_plt16_lo_<mode>"
10461 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10462 (unspec_volatile:P [(match_operand:P 1 "gpc_reg_operand" "b")
10463 (match_operand:P 2 "symbol_ref_operand" "s")
10464 (match_operand:P 3 "" "")]
10465 UNSPECV_PLT16_LO))]
10466 "TARGET_PLTSEQ"
10467 {
10468 return rs6000_pltseq_template (operands, RS6000_PLTSEQ_PLT16_LO);
10469 }
10470 [(set_attr "type" "load")])
10471
10472 (define_insn "*pltseq_mtctr_<mode>"
10473 [(set (match_operand:P 0 "register_operand" "=c")
10474 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "r")
10475 (match_operand:P 2 "symbol_ref_operand" "s")
10476 (match_operand:P 3 "" "")]
10477 UNSPEC_PLTSEQ))]
10478 "TARGET_PLTSEQ"
10479 {
10480 return rs6000_pltseq_template (operands, RS6000_PLTSEQ_MTCTR);
10481 })
10482
10483 (define_insn "*pltseq_plt_pcrel<mode>"
10484 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10485 (unspec_volatile:P [(match_operand:P 1 "" "")
10486 (match_operand:P 2 "symbol_ref_operand" "s")
10487 (match_operand:P 3 "" "")]
10488 UNSPECV_PLT_PCREL))]
10489 "HAVE_AS_PLTSEQ && TARGET_ELF
10490 && rs6000_pcrel_p (cfun)"
10491 {
10492 return rs6000_pltseq_template (operands, RS6000_PLTSEQ_PLT_PCREL34);
10493 }
10494 [(set_attr "type" "load")
10495 (set_attr "length" "12")])
10496 \f
10497 ;; Call and call_value insns
10498 ;; For the purposes of expanding calls, Darwin is very similar to SYSV.
10499 (define_expand "call"
10500 [(parallel [(call (mem:SI (match_operand 0 "address_operand"))
10501 (match_operand 1 ""))
10502 (use (match_operand 2 ""))
10503 (clobber (reg:SI LR_REGNO))])]
10504 ""
10505 {
10506 #if TARGET_MACHO
10507 if (MACHOPIC_INDIRECT)
10508 operands[0] = machopic_indirect_call_target (operands[0]);
10509 #endif
10510
10511 gcc_assert (MEM_P (operands[0]));
10512
10513 operands[0] = XEXP (operands[0], 0);
10514
10515 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10516 rs6000_call_aix (NULL_RTX, operands[0], operands[1], operands[2]);
10517 else if (DEFAULT_ABI == ABI_V4)
10518 rs6000_call_sysv (NULL_RTX, operands[0], operands[1], operands[2]);
10519 else if (DEFAULT_ABI == ABI_DARWIN)
10520 rs6000_call_darwin (NULL_RTX, operands[0], operands[1], operands[2]);
10521 else
10522 gcc_unreachable ();
10523
10524 DONE;
10525 })
10526
10527 (define_expand "call_value"
10528 [(parallel [(set (match_operand 0 "")
10529 (call (mem:SI (match_operand 1 "address_operand"))
10530 (match_operand 2 "")))
10531 (use (match_operand 3 ""))
10532 (clobber (reg:SI LR_REGNO))])]
10533 ""
10534 {
10535 #if TARGET_MACHO
10536 if (MACHOPIC_INDIRECT)
10537 operands[1] = machopic_indirect_call_target (operands[1]);
10538 #endif
10539
10540 gcc_assert (MEM_P (operands[1]));
10541
10542 operands[1] = XEXP (operands[1], 0);
10543
10544 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10545 rs6000_call_aix (operands[0], operands[1], operands[2], operands[3]);
10546 else if (DEFAULT_ABI == ABI_V4)
10547 rs6000_call_sysv (operands[0], operands[1], operands[2], operands[3]);
10548 else if (DEFAULT_ABI == ABI_DARWIN)
10549 rs6000_call_darwin (operands[0], operands[1], operands[2], operands[3]);
10550 else
10551 gcc_unreachable ();
10552
10553 DONE;
10554 })
10555
10556 ;; Call to function in current module. No TOC pointer reload needed.
10557 ;; Operand2 is nonzero if we are using the V.4 calling sequence and
10558 ;; either the function was not prototyped, or it was prototyped as a
10559 ;; variable argument function. It is > 0 if FP registers were passed
10560 ;; and < 0 if they were not.
10561
10562 (define_insn "*call_local<mode>"
10563 [(call (mem:SI (match_operand:P 0 "current_file_function_operand" "s,s"))
10564 (match_operand 1))
10565 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10566 (clobber (reg:P LR_REGNO))]
10567 "(INTVAL (operands[2]) & CALL_LONG) == 0"
10568 {
10569 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10570 output_asm_insn ("crxor 6,6,6", operands);
10571
10572 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10573 output_asm_insn ("creqv 6,6,6", operands);
10574
10575 if (rs6000_pcrel_p (cfun))
10576 return "bl %z0@notoc";
10577 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z0@local" : "bl %z0";
10578 }
10579 [(set_attr "type" "branch")
10580 (set_attr "length" "4,8")])
10581
10582 (define_insn "*call_value_local<mode>"
10583 [(set (match_operand 0 "" "")
10584 (call (mem:SI (match_operand:P 1 "current_file_function_operand" "s,s"))
10585 (match_operand 2)))
10586 (use (match_operand:SI 3 "immediate_operand" "O,n"))
10587 (clobber (reg:P LR_REGNO))]
10588 "(INTVAL (operands[3]) & CALL_LONG) == 0"
10589 {
10590 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10591 output_asm_insn ("crxor 6,6,6", operands);
10592
10593 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10594 output_asm_insn ("creqv 6,6,6", operands);
10595
10596 if (rs6000_pcrel_p (cfun))
10597 return "bl %z1@notoc";
10598 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z1@local" : "bl %z1";
10599 }
10600 [(set_attr "type" "branch")
10601 (set_attr "length" "4,8")])
10602
10603
10604 ;; A function pointer under System V is just a normal pointer
10605 ;; operands[0] is the function pointer
10606 ;; operands[1] is the tls call arg
10607 ;; operands[2] is the value FUNCTION_ARG returns for the VOID argument
10608 ;; which indicates how to set cr1
10609
10610 (define_insn "*call_indirect_nonlocal_sysv<mode>"
10611 [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X"))
10612 (match_operand 1))
10613 (use (match_operand:SI 2 "immediate_operand" "n,n,n"))
10614 (clobber (reg:P LR_REGNO))]
10615 "DEFAULT_ABI == ABI_V4
10616 || DEFAULT_ABI == ABI_DARWIN"
10617 {
10618 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10619 output_asm_insn ("crxor 6,6,6", operands);
10620
10621 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10622 output_asm_insn ("creqv 6,6,6", operands);
10623
10624 return rs6000_indirect_call_template (operands, 0);
10625 }
10626 [(set_attr "type" "jmpreg")
10627 (set (attr "length")
10628 (cond [(and (and (match_test "!rs6000_speculate_indirect_jumps")
10629 (match_test "which_alternative != 1"))
10630 (match_test "(INTVAL (operands[2]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
10631 (const_string "12")
10632 (ior (and (match_test "!rs6000_speculate_indirect_jumps")
10633 (match_test "which_alternative != 1"))
10634 (match_test "(INTVAL (operands[2]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
10635 (const_string "8")]
10636 (const_string "4")))])
10637
10638 (define_insn "*call_nonlocal_sysv<mode>"
10639 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
10640 (match_operand 1))
10641 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10642 (clobber (reg:P LR_REGNO))]
10643 "(DEFAULT_ABI == ABI_DARWIN
10644 || (DEFAULT_ABI == ABI_V4
10645 && (INTVAL (operands[2]) & CALL_LONG) == 0))"
10646 {
10647 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10648 output_asm_insn ("crxor 6,6,6", operands);
10649
10650 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10651 output_asm_insn ("creqv 6,6,6", operands);
10652
10653 return rs6000_call_template (operands, 0);
10654 }
10655 [(set_attr "type" "branch,branch")
10656 (set_attr "length" "4,8")])
10657
10658 (define_insn "*call_nonlocal_sysv_secure<mode>"
10659 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
10660 (match_operand 1))
10661 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10662 (use (match_operand:SI 3 "register_operand" "r,r"))
10663 (clobber (reg:P LR_REGNO))]
10664 "(DEFAULT_ABI == ABI_V4
10665 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0])
10666 && (INTVAL (operands[2]) & CALL_LONG) == 0)"
10667 {
10668 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10669 output_asm_insn ("crxor 6,6,6", operands);
10670
10671 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10672 output_asm_insn ("creqv 6,6,6", operands);
10673
10674 return rs6000_call_template (operands, 0);
10675 }
10676 [(set_attr "type" "branch,branch")
10677 (set_attr "length" "4,8")])
10678
10679 (define_insn "*call_value_indirect_nonlocal_sysv<mode>"
10680 [(set (match_operand 0 "" "")
10681 (call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X"))
10682 (match_operand:P 2 "unspec_tls" "")))
10683 (use (match_operand:SI 3 "immediate_operand" "n,n,n"))
10684 (clobber (reg:P LR_REGNO))]
10685 "DEFAULT_ABI == ABI_V4
10686 || DEFAULT_ABI == ABI_DARWIN"
10687 {
10688 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10689 output_asm_insn ("crxor 6,6,6", operands);
10690
10691 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10692 output_asm_insn ("creqv 6,6,6", operands);
10693
10694 return rs6000_indirect_call_template (operands, 1);
10695 }
10696 [(set_attr "type" "jmpreg")
10697 (set (attr "length")
10698 (plus
10699 (if_then_else (match_test "IS_V4_FP_ARGS (operands[3])")
10700 (const_int 4)
10701 (const_int 0))
10702 (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
10703 (match_test "which_alternative != 1"))
10704 (const_int 8)
10705 (const_int 4))))])
10706
10707 (define_insn "*call_value_nonlocal_sysv<mode>"
10708 [(set (match_operand 0 "" "")
10709 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s"))
10710 (match_operand:P 2 "unspec_tls" "")))
10711 (use (match_operand:SI 3 "immediate_operand" "n"))
10712 (clobber (reg:P LR_REGNO))]
10713 "(DEFAULT_ABI == ABI_DARWIN
10714 || (DEFAULT_ABI == ABI_V4
10715 && (INTVAL (operands[3]) & CALL_LONG) == 0))"
10716 {
10717 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10718 output_asm_insn ("crxor 6,6,6", operands);
10719
10720 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10721 output_asm_insn ("creqv 6,6,6", operands);
10722
10723 return rs6000_call_template (operands, 1);
10724 }
10725 [(set_attr "type" "branch")
10726 (set (attr "length")
10727 (if_then_else (match_test "IS_V4_FP_ARGS (operands[3])")
10728 (const_int 8)
10729 (const_int 4)))])
10730
10731 (define_insn "*call_value_nonlocal_sysv_secure<mode>"
10732 [(set (match_operand 0 "" "")
10733 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s"))
10734 (match_operand:P 2 "unspec_tls" "")))
10735 (use (match_operand:SI 3 "immediate_operand" "n"))
10736 (use (match_operand:SI 4 "register_operand" "r"))
10737 (clobber (reg:P LR_REGNO))]
10738 "(DEFAULT_ABI == ABI_V4
10739 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1])
10740 && (INTVAL (operands[3]) & CALL_LONG) == 0)"
10741 {
10742 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10743 output_asm_insn ("crxor 6,6,6", operands);
10744
10745 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10746 output_asm_insn ("creqv 6,6,6", operands);
10747
10748 return rs6000_call_template (operands, 1);
10749 }
10750 [(set_attr "type" "branch")
10751 (set (attr "length")
10752 (if_then_else (match_test "IS_V4_FP_ARGS (operands[3])")
10753 (const_int 8)
10754 (const_int 4)))])
10755
10756 ;; Call to AIX abi function which may be in another module.
10757 ;; Restore the TOC pointer (r2) after the call.
10758
10759 (define_insn "*call_nonlocal_aix<mode>"
10760 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s"))
10761 (match_operand 1))
10762 (use (match_operand:SI 2 "immediate_operand" "n"))
10763 (clobber (reg:P LR_REGNO))]
10764 "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10765 && (INTVAL (operands[2]) & CALL_LONG) == 0"
10766 {
10767 return rs6000_call_template (operands, 0);
10768 }
10769 [(set_attr "type" "branch")
10770 (set (attr "length")
10771 (if_then_else (match_test "rs6000_pcrel_p (cfun)")
10772 (const_int 4)
10773 (const_int 8)))])
10774
10775 (define_insn "*call_value_nonlocal_aix<mode>"
10776 [(set (match_operand 0 "" "")
10777 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s"))
10778 (match_operand:P 2 "unspec_tls" "")))
10779 (use (match_operand:SI 3 "immediate_operand" "n"))
10780 (clobber (reg:P LR_REGNO))]
10781 "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10782 && (INTVAL (operands[3]) & CALL_LONG) == 0"
10783 {
10784 return rs6000_call_template (operands, 1);
10785 }
10786 [(set_attr "type" "branch")
10787 (set (attr "length")
10788 (if_then_else (match_test "rs6000_pcrel_p (cfun)")
10789 (const_int 4)
10790 (const_int 8)))])
10791
10792 ;; Call to indirect functions with the AIX abi using a 3 word descriptor.
10793 ;; Operand0 is the addresss of the function to call
10794 ;; Operand3 is the location in the function descriptor to load r2 from
10795 ;; Operand4 is the offset of the stack location holding the current TOC pointer
10796
10797 (define_insn "*call_indirect_aix<mode>"
10798 [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X"))
10799 (match_operand 1))
10800 (use (match_operand:SI 2 "immediate_operand" "n,n,n"))
10801 (use (match_operand:P 3 "memory_operand" "<ptrm>,<ptrm>,<ptrm>"))
10802 (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 4 "const_int_operand" "n,n,n")] UNSPEC_TOCSLOT))
10803 (clobber (reg:P LR_REGNO))]
10804 "DEFAULT_ABI == ABI_AIX"
10805 {
10806 return rs6000_indirect_call_template (operands, 0);
10807 }
10808 [(set_attr "type" "jmpreg")
10809 (set (attr "length")
10810 (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
10811 (match_test "which_alternative != 1"))
10812 (const_string "16")
10813 (const_string "12")))])
10814
10815 (define_insn "*call_value_indirect_aix<mode>"
10816 [(set (match_operand 0 "" "")
10817 (call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X"))
10818 (match_operand:P 2 "unspec_tls" "")))
10819 (use (match_operand:SI 3 "immediate_operand" "n,n,n"))
10820 (use (match_operand:P 4 "memory_operand" "<ptrm>,<ptrm>,<ptrm>"))
10821 (set (reg:P TOC_REGNUM)
10822 (unspec:P [(match_operand:P 5 "const_int_operand" "n,n,n")]
10823 UNSPEC_TOCSLOT))
10824 (clobber (reg:P LR_REGNO))]
10825 "DEFAULT_ABI == ABI_AIX"
10826 {
10827 return rs6000_indirect_call_template (operands, 1);
10828 }
10829 [(set_attr "type" "jmpreg")
10830 (set (attr "length")
10831 (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
10832 (match_test "which_alternative != 1"))
10833 (const_string "16")
10834 (const_string "12")))])
10835
10836 ;; Call to indirect functions with the ELFv2 ABI.
10837 ;; Operand0 is the addresss of the function to call
10838 ;; Operand3 is the offset of the stack location holding the current TOC pointer
10839
10840 (define_insn "*call_indirect_elfv2<mode>"
10841 [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X"))
10842 (match_operand 1))
10843 (use (match_operand:SI 2 "immediate_operand" "n,n,n"))
10844 (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 3 "const_int_operand" "n,n,n")] UNSPEC_TOCSLOT))
10845 (clobber (reg:P LR_REGNO))]
10846 "DEFAULT_ABI == ABI_ELFv2"
10847 {
10848 return rs6000_indirect_call_template (operands, 0);
10849 }
10850 [(set_attr "type" "jmpreg")
10851 (set (attr "length")
10852 (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
10853 (match_test "which_alternative != 1"))
10854 (const_string "12")
10855 (const_string "8")))])
10856
10857 (define_insn "*call_indirect_pcrel<mode>"
10858 [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X"))
10859 (match_operand 1))
10860 (use (match_operand:SI 2 "immediate_operand" "n,n,n"))
10861 (clobber (reg:P LR_REGNO))]
10862 "rs6000_pcrel_p (cfun)"
10863 {
10864 return rs6000_indirect_call_template (operands, 0);
10865 }
10866 [(set_attr "type" "jmpreg")
10867 (set (attr "length")
10868 (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
10869 (match_test "which_alternative != 1"))
10870 (const_string "8")
10871 (const_string "4")))])
10872
10873 (define_insn "*call_value_indirect_elfv2<mode>"
10874 [(set (match_operand 0 "" "")
10875 (call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X"))
10876 (match_operand:P 2 "unspec_tls" "")))
10877 (use (match_operand:SI 3 "immediate_operand" "n,n,n"))
10878 (set (reg:P TOC_REGNUM)
10879 (unspec:P [(match_operand:P 4 "const_int_operand" "n,n,n")]
10880 UNSPEC_TOCSLOT))
10881 (clobber (reg:P LR_REGNO))]
10882 "DEFAULT_ABI == ABI_ELFv2"
10883 {
10884 return rs6000_indirect_call_template (operands, 1);
10885 }
10886 [(set_attr "type" "jmpreg")
10887 (set (attr "length")
10888 (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
10889 (match_test "which_alternative != 1"))
10890 (const_string "12")
10891 (const_string "8")))])
10892
10893 (define_insn "*call_value_indirect_pcrel<mode>"
10894 [(set (match_operand 0 "" "")
10895 (call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X"))
10896 (match_operand:P 2 "unspec_tls" "")))
10897 (use (match_operand:SI 3 "immediate_operand" "n,n,n"))
10898 (clobber (reg:P LR_REGNO))]
10899 "rs6000_pcrel_p (cfun)"
10900 {
10901 return rs6000_indirect_call_template (operands, 1);
10902 }
10903 [(set_attr "type" "jmpreg")
10904 (set (attr "length")
10905 (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
10906 (match_test "which_alternative != 1"))
10907 (const_string "8")
10908 (const_string "4")))])
10909
10910 ;; Call subroutine returning any type.
10911 (define_expand "untyped_call"
10912 [(parallel [(call (match_operand 0 "")
10913 (const_int 0))
10914 (match_operand 1 "")
10915 (match_operand 2 "")])]
10916 ""
10917 {
10918 int i;
10919
10920 emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
10921
10922 for (int i = 0; i < XVECLEN (operands[2], 0); i++)
10923 emit_clobber (SET_SRC (XVECEXP (operands[2], 0, i)));
10924 emit_insn (gen_blockage ());
10925
10926 for (i = 0; i < XVECLEN (operands[2], 0); i++)
10927 {
10928 rtx set = XVECEXP (operands[2], 0, i);
10929 emit_move_insn (SET_DEST (set), SET_SRC (set));
10930 }
10931
10932 /* The optimizer does not know that the call sets the function value
10933 registers we stored in the result block. We avoid problems by
10934 claiming that all hard registers are used and clobbered at this
10935 point. */
10936 emit_insn (gen_blockage ());
10937
10938 DONE;
10939 })
10940
10941 ;; sibling call patterns
10942 (define_expand "sibcall"
10943 [(parallel [(call (mem:SI (match_operand 0 "address_operand"))
10944 (match_operand 1 ""))
10945 (use (match_operand 2 ""))
10946 (simple_return)])]
10947 ""
10948 {
10949 #if TARGET_MACHO
10950 if (MACHOPIC_INDIRECT)
10951 operands[0] = machopic_indirect_call_target (operands[0]);
10952 #endif
10953
10954 gcc_assert (MEM_P (operands[0]));
10955 gcc_assert (CONST_INT_P (operands[1]));
10956
10957 operands[0] = XEXP (operands[0], 0);
10958
10959 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10960 rs6000_sibcall_aix (NULL_RTX, operands[0], operands[1], operands[2]);
10961 else if (DEFAULT_ABI == ABI_V4)
10962 rs6000_sibcall_sysv (NULL_RTX, operands[0], operands[1], operands[2]);
10963 else if (DEFAULT_ABI == ABI_DARWIN)
10964 rs6000_sibcall_darwin (NULL_RTX, operands[0], operands[1], operands[2]);
10965 else
10966 gcc_unreachable ();
10967
10968 DONE;
10969 })
10970
10971 (define_expand "sibcall_value"
10972 [(parallel [(set (match_operand 0 "register_operand")
10973 (call (mem:SI (match_operand 1 "address_operand"))
10974 (match_operand 2 "")))
10975 (use (match_operand 3 ""))
10976 (simple_return)])]
10977 ""
10978 {
10979 #if TARGET_MACHO
10980 if (MACHOPIC_INDIRECT)
10981 operands[1] = machopic_indirect_call_target (operands[1]);
10982 #endif
10983
10984 gcc_assert (MEM_P (operands[1]));
10985 gcc_assert (CONST_INT_P (operands[2]));
10986
10987 operands[1] = XEXP (operands[1], 0);
10988
10989 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10990 rs6000_sibcall_aix (operands[0], operands[1], operands[2], operands[3]);
10991 else if (DEFAULT_ABI == ABI_V4)
10992 rs6000_sibcall_sysv (operands[0], operands[1], operands[2], operands[3]);
10993 else if (DEFAULT_ABI == ABI_DARWIN)
10994 rs6000_sibcall_darwin (operands[0], operands[1], operands[2], operands[3]);
10995 else
10996 gcc_unreachable ();
10997
10998 DONE;
10999 })
11000
11001 (define_insn "*sibcall_local32"
11002 [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
11003 (match_operand 1))
11004 (use (match_operand:SI 2 "immediate_operand" "O,n"))
11005 (simple_return)]
11006 "(INTVAL (operands[2]) & CALL_LONG) == 0"
11007 {
11008 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
11009 output_asm_insn ("crxor 6,6,6", operands);
11010
11011 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
11012 output_asm_insn ("creqv 6,6,6", operands);
11013
11014 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z0@local" : "b %z0";
11015 }
11016 [(set_attr "type" "branch")
11017 (set_attr "length" "4,8")])
11018
11019 (define_insn "*sibcall_local64"
11020 [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
11021 (match_operand 1))
11022 (use (match_operand:SI 2 "immediate_operand" "O,n"))
11023 (simple_return)]
11024 "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
11025 {
11026 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
11027 output_asm_insn ("crxor 6,6,6", operands);
11028
11029 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
11030 output_asm_insn ("creqv 6,6,6", operands);
11031
11032 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z0@local" : "b %z0";
11033 }
11034 [(set_attr "type" "branch")
11035 (set_attr "length" "4,8")])
11036
11037 (define_insn "*sibcall_value_local32"
11038 [(set (match_operand 0 "" "")
11039 (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
11040 (match_operand 2)))
11041 (use (match_operand:SI 3 "immediate_operand" "O,n"))
11042 (simple_return)]
11043 "(INTVAL (operands[3]) & CALL_LONG) == 0"
11044 {
11045 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11046 output_asm_insn ("crxor 6,6,6", operands);
11047
11048 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11049 output_asm_insn ("creqv 6,6,6", operands);
11050
11051 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z1@local" : "b %z1";
11052 }
11053 [(set_attr "type" "branch")
11054 (set_attr "length" "4,8")])
11055
11056 (define_insn "*sibcall_value_local64"
11057 [(set (match_operand 0 "" "")
11058 (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
11059 (match_operand 2)))
11060 (use (match_operand:SI 3 "immediate_operand" "O,n"))
11061 (simple_return)]
11062 "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
11063 {
11064 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11065 output_asm_insn ("crxor 6,6,6", operands);
11066
11067 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11068 output_asm_insn ("creqv 6,6,6", operands);
11069
11070 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z1@local" : "b %z1";
11071 }
11072 [(set_attr "type" "branch")
11073 (set_attr "length" "4,8")])
11074
11075 (define_insn "*sibcall_indirect_nonlocal_sysv<mode>"
11076 [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X"))
11077 (match_operand 1))
11078 (use (match_operand:SI 2 "immediate_operand" "n,n,n"))
11079 (simple_return)]
11080 "DEFAULT_ABI == ABI_V4
11081 || DEFAULT_ABI == ABI_DARWIN"
11082 {
11083 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
11084 output_asm_insn ("crxor 6,6,6", operands);
11085
11086 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
11087 output_asm_insn ("creqv 6,6,6", operands);
11088
11089 return rs6000_indirect_sibcall_template (operands, 0);
11090 }
11091 [(set_attr "type" "jmpreg")
11092 (set (attr "length")
11093 (cond [(and (and (match_test "!rs6000_speculate_indirect_jumps")
11094 (match_test "which_alternative != 1"))
11095 (match_test "(INTVAL (operands[2]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
11096 (const_string "12")
11097 (ior (and (match_test "!rs6000_speculate_indirect_jumps")
11098 (match_test "which_alternative != 1"))
11099 (match_test "(INTVAL (operands[2]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
11100 (const_string "8")]
11101 (const_string "4")))])
11102
11103 (define_insn "*sibcall_nonlocal_sysv<mode>"
11104 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
11105 (match_operand 1))
11106 (use (match_operand 2 "immediate_operand" "O,n"))
11107 (simple_return)]
11108 "(DEFAULT_ABI == ABI_DARWIN
11109 || DEFAULT_ABI == ABI_V4)
11110 && (INTVAL (operands[2]) & CALL_LONG) == 0"
11111 {
11112 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
11113 output_asm_insn ("crxor 6,6,6", operands);
11114
11115 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
11116 output_asm_insn ("creqv 6,6,6", operands);
11117
11118 return rs6000_sibcall_template (operands, 0);
11119 }
11120 [(set_attr "type" "branch")
11121 (set_attr "length" "4,8")])
11122
11123 (define_insn "*sibcall_value_indirect_nonlocal_sysv<mode>"
11124 [(set (match_operand 0 "" "")
11125 (call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X"))
11126 (match_operand 2)))
11127 (use (match_operand:SI 3 "immediate_operand" "n,n,n"))
11128 (simple_return)]
11129 "DEFAULT_ABI == ABI_V4
11130 || DEFAULT_ABI == ABI_DARWIN"
11131 {
11132 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11133 output_asm_insn ("crxor 6,6,6", operands);
11134
11135 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11136 output_asm_insn ("creqv 6,6,6", operands);
11137
11138 return rs6000_indirect_sibcall_template (operands, 1);
11139 }
11140 [(set_attr "type" "jmpreg")
11141 (set (attr "length")
11142 (cond [(and (and (match_test "!rs6000_speculate_indirect_jumps")
11143 (match_test "which_alternative != 1"))
11144 (match_test "(INTVAL (operands[3]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
11145 (const_string "12")
11146 (ior (and (match_test "!rs6000_speculate_indirect_jumps")
11147 (match_test "which_alternative != 1"))
11148 (match_test "(INTVAL (operands[3]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
11149 (const_string "8")]
11150 (const_string "4")))])
11151
11152 (define_insn "*sibcall_value_nonlocal_sysv<mode>"
11153 [(set (match_operand 0 "" "")
11154 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
11155 (match_operand 2)))
11156 (use (match_operand:SI 3 "immediate_operand" "O,n"))
11157 (simple_return)]
11158 "(DEFAULT_ABI == ABI_DARWIN
11159 || DEFAULT_ABI == ABI_V4)
11160 && (INTVAL (operands[3]) & CALL_LONG) == 0"
11161 {
11162 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11163 output_asm_insn ("crxor 6,6,6", operands);
11164
11165 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11166 output_asm_insn ("creqv 6,6,6", operands);
11167
11168 return rs6000_sibcall_template (operands, 1);
11169 }
11170 [(set_attr "type" "branch")
11171 (set_attr "length" "4,8")])
11172
11173 ;; AIX ABI sibling call patterns.
11174
11175 (define_insn "*sibcall_aix<mode>"
11176 [(call (mem:SI (match_operand:P 0 "call_operand" "s,c"))
11177 (match_operand 1))
11178 (simple_return)]
11179 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11180 {
11181 if (which_alternative == 0)
11182 return rs6000_sibcall_template (operands, 0);
11183 else
11184 return "b%T0";
11185 }
11186 [(set_attr "type" "branch")])
11187
11188 (define_insn "*sibcall_value_aix<mode>"
11189 [(set (match_operand 0 "" "")
11190 (call (mem:SI (match_operand:P 1 "call_operand" "s,c"))
11191 (match_operand 2)))
11192 (simple_return)]
11193 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11194 {
11195 if (which_alternative == 0)
11196 return rs6000_sibcall_template (operands, 1);
11197 else
11198 return "b%T1";
11199 }
11200 [(set_attr "type" "branch")])
11201
11202 (define_expand "sibcall_epilogue"
11203 [(use (const_int 0))]
11204 ""
11205 {
11206 if (!TARGET_SCHED_PROLOG)
11207 emit_insn (gen_blockage ());
11208 rs6000_emit_epilogue (EPILOGUE_TYPE_SIBCALL);
11209 DONE;
11210 })
11211
11212 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11213 ;; all of memory. This blocks insns from being moved across this point.
11214
11215 (define_insn "blockage"
11216 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCK)]
11217 ""
11218 ""
11219 [(set_attr "length" "0")])
11220
11221 (define_expand "probe_stack_address"
11222 [(use (match_operand 0 "address_operand"))]
11223 ""
11224 {
11225 operands[0] = gen_rtx_MEM (Pmode, operands[0]);
11226 MEM_VOLATILE_P (operands[0]) = 1;
11227
11228 if (TARGET_64BIT)
11229 emit_insn (gen_probe_stack_di (operands[0]));
11230 else
11231 emit_insn (gen_probe_stack_si (operands[0]));
11232 DONE;
11233 })
11234
11235 (define_insn "probe_stack_<mode>"
11236 [(set (match_operand:P 0 "memory_operand" "=m")
11237 (unspec:P [(const_int 0)] UNSPEC_PROBE_STACK))]
11238 ""
11239 {
11240 operands[1] = gen_rtx_REG (Pmode, 0);
11241 return "st<wd>%U0%X0 %1,%0";
11242 }
11243 [(set_attr "type" "store")
11244 (set (attr "update")
11245 (if_then_else (match_operand 0 "update_address_mem")
11246 (const_string "yes")
11247 (const_string "no")))
11248 (set (attr "indexed")
11249 (if_then_else (match_operand 0 "indexed_address_mem")
11250 (const_string "yes")
11251 (const_string "no")))])
11252
11253 (define_insn "probe_stack_range<P:mode>"
11254 [(set (match_operand:P 0 "register_operand" "=&r")
11255 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
11256 (match_operand:P 2 "register_operand" "r")
11257 (match_operand:P 3 "register_operand" "r")]
11258 UNSPECV_PROBE_STACK_RANGE))]
11259 ""
11260 "* return output_probe_stack_range (operands[0], operands[2], operands[3]);"
11261 [(set_attr "type" "three")])
11262 \f
11263 ;; Compare insns are next. Note that the RS/6000 has two types of compares,
11264 ;; signed & unsigned, and one type of branch.
11265 ;;
11266 ;; Start with the DEFINE_EXPANDs to generate the rtl for compares, scc
11267 ;; insns, and branches.
11268
11269 (define_expand "cbranch<mode>4"
11270 [(use (match_operator 0 "comparison_operator"
11271 [(match_operand:GPR 1 "gpc_reg_operand")
11272 (match_operand:GPR 2 "reg_or_short_operand")]))
11273 (use (match_operand 3))]
11274 ""
11275 {
11276 /* Take care of the possibility that operands[2] might be negative but
11277 this might be a logical operation. That insn doesn't exist. */
11278 if (CONST_INT_P (operands[2])
11279 && INTVAL (operands[2]) < 0)
11280 {
11281 operands[2] = force_reg (<MODE>mode, operands[2]);
11282 operands[0] = gen_rtx_fmt_ee (GET_CODE (operands[0]),
11283 GET_MODE (operands[0]),
11284 operands[1], operands[2]);
11285 }
11286
11287 rs6000_emit_cbranch (<MODE>mode, operands);
11288 DONE;
11289 })
11290
11291 (define_expand "cbranch<mode>4"
11292 [(use (match_operator 0 "comparison_operator"
11293 [(match_operand:FP 1 "gpc_reg_operand")
11294 (match_operand:FP 2 "gpc_reg_operand")]))
11295 (use (match_operand 3))]
11296 ""
11297 {
11298 rs6000_emit_cbranch (<MODE>mode, operands);
11299 DONE;
11300 })
11301
11302 (define_expand "cstore<mode>4_signed"
11303 [(use (match_operator 1 "signed_comparison_operator"
11304 [(match_operand:P 2 "gpc_reg_operand")
11305 (match_operand:P 3 "gpc_reg_operand")]))
11306 (clobber (match_operand:P 0 "gpc_reg_operand"))]
11307 ""
11308 {
11309 enum rtx_code cond_code = GET_CODE (operands[1]);
11310
11311 rtx op0 = operands[0];
11312 rtx op1 = operands[2];
11313 rtx op2 = operands[3];
11314
11315 if (cond_code == GE || cond_code == LT)
11316 {
11317 cond_code = swap_condition (cond_code);
11318 std::swap (op1, op2);
11319 }
11320
11321 rtx tmp1 = gen_reg_rtx (<MODE>mode);
11322 rtx tmp2 = gen_reg_rtx (<MODE>mode);
11323 rtx tmp3 = gen_reg_rtx (<MODE>mode);
11324
11325 int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11326 emit_insn (gen_lshr<mode>3 (tmp1, op1, GEN_INT (sh)));
11327 emit_insn (gen_ashr<mode>3 (tmp2, op2, GEN_INT (sh)));
11328
11329 emit_insn (gen_subf<mode>3_carry (tmp3, op1, op2));
11330
11331 if (cond_code == LE)
11332 emit_insn (gen_add<mode>3_carry_in (op0, tmp1, tmp2));
11333 else
11334 {
11335 rtx tmp4 = gen_reg_rtx (<MODE>mode);
11336 emit_insn (gen_add<mode>3_carry_in (tmp4, tmp1, tmp2));
11337 emit_insn (gen_xor<mode>3 (op0, tmp4, const1_rtx));
11338 }
11339
11340 DONE;
11341 })
11342
11343 (define_expand "cstore<mode>4_unsigned"
11344 [(use (match_operator 1 "unsigned_comparison_operator"
11345 [(match_operand:P 2 "gpc_reg_operand")
11346 (match_operand:P 3 "reg_or_short_operand")]))
11347 (clobber (match_operand:P 0 "gpc_reg_operand"))]
11348 ""
11349 {
11350 enum rtx_code cond_code = GET_CODE (operands[1]);
11351
11352 rtx op0 = operands[0];
11353 rtx op1 = operands[2];
11354 rtx op2 = operands[3];
11355
11356 if (cond_code == GEU || cond_code == LTU)
11357 {
11358 cond_code = swap_condition (cond_code);
11359 std::swap (op1, op2);
11360 }
11361
11362 if (!gpc_reg_operand (op1, <MODE>mode))
11363 op1 = force_reg (<MODE>mode, op1);
11364 if (!reg_or_short_operand (op2, <MODE>mode))
11365 op2 = force_reg (<MODE>mode, op2);
11366
11367 rtx tmp = gen_reg_rtx (<MODE>mode);
11368 rtx tmp2 = gen_reg_rtx (<MODE>mode);
11369
11370 emit_insn (gen_subf<mode>3_carry (tmp, op1, op2));
11371 emit_insn (gen_subf<mode>3_carry_in_xx (tmp2));
11372
11373 if (cond_code == LEU)
11374 emit_insn (gen_add<mode>3 (op0, tmp2, const1_rtx));
11375 else
11376 emit_insn (gen_neg<mode>2 (op0, tmp2));
11377
11378 DONE;
11379 })
11380
11381 (define_expand "cstore_si_as_di"
11382 [(use (match_operator 1 "unsigned_comparison_operator"
11383 [(match_operand:SI 2 "gpc_reg_operand")
11384 (match_operand:SI 3 "reg_or_short_operand")]))
11385 (clobber (match_operand:SI 0 "gpc_reg_operand"))]
11386 ""
11387 {
11388 int uns_flag = unsigned_comparison_operator (operands[1], VOIDmode) ? 1 : 0;
11389 enum rtx_code cond_code = signed_condition (GET_CODE (operands[1]));
11390
11391 operands[2] = force_reg (SImode, operands[2]);
11392 operands[3] = force_reg (SImode, operands[3]);
11393 rtx op1 = gen_reg_rtx (DImode);
11394 rtx op2 = gen_reg_rtx (DImode);
11395 convert_move (op1, operands[2], uns_flag);
11396 convert_move (op2, operands[3], uns_flag);
11397
11398 if (cond_code == GT || cond_code == LE)
11399 {
11400 cond_code = swap_condition (cond_code);
11401 std::swap (op1, op2);
11402 }
11403
11404 rtx tmp = gen_reg_rtx (DImode);
11405 rtx tmp2 = gen_reg_rtx (DImode);
11406 emit_insn (gen_subdi3 (tmp, op1, op2));
11407 emit_insn (gen_lshrdi3 (tmp2, tmp, GEN_INT (63)));
11408
11409 rtx tmp3;
11410 switch (cond_code)
11411 {
11412 default:
11413 gcc_unreachable ();
11414 case LT:
11415 tmp3 = tmp2;
11416 break;
11417 case GE:
11418 tmp3 = gen_reg_rtx (DImode);
11419 emit_insn (gen_xordi3 (tmp3, tmp2, const1_rtx));
11420 break;
11421 }
11422
11423 convert_move (operands[0], tmp3, 1);
11424
11425 DONE;
11426 })
11427
11428 (define_expand "cstore<mode>4_signed_imm"
11429 [(use (match_operator 1 "signed_comparison_operator"
11430 [(match_operand:GPR 2 "gpc_reg_operand")
11431 (match_operand:GPR 3 "immediate_operand")]))
11432 (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11433 ""
11434 {
11435 bool invert = false;
11436
11437 enum rtx_code cond_code = GET_CODE (operands[1]);
11438
11439 rtx op0 = operands[0];
11440 rtx op1 = operands[2];
11441 HOST_WIDE_INT val = INTVAL (operands[3]);
11442
11443 if (cond_code == GE || cond_code == GT)
11444 {
11445 cond_code = reverse_condition (cond_code);
11446 invert = true;
11447 }
11448
11449 if (cond_code == LE)
11450 val++;
11451
11452 rtx tmp = gen_reg_rtx (<MODE>mode);
11453 emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
11454 rtx x = gen_reg_rtx (<MODE>mode);
11455 if (val < 0)
11456 emit_insn (gen_and<mode>3 (x, op1, tmp));
11457 else
11458 emit_insn (gen_ior<mode>3 (x, op1, tmp));
11459
11460 if (invert)
11461 {
11462 rtx tmp = gen_reg_rtx (<MODE>mode);
11463 emit_insn (gen_one_cmpl<mode>2 (tmp, x));
11464 x = tmp;
11465 }
11466
11467 int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11468 emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
11469
11470 DONE;
11471 })
11472
11473 (define_expand "cstore<mode>4_unsigned_imm"
11474 [(use (match_operator 1 "unsigned_comparison_operator"
11475 [(match_operand:GPR 2 "gpc_reg_operand")
11476 (match_operand:GPR 3 "immediate_operand")]))
11477 (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11478 ""
11479 {
11480 bool invert = false;
11481
11482 enum rtx_code cond_code = GET_CODE (operands[1]);
11483
11484 rtx op0 = operands[0];
11485 rtx op1 = operands[2];
11486 HOST_WIDE_INT val = INTVAL (operands[3]);
11487
11488 if (cond_code == GEU || cond_code == GTU)
11489 {
11490 cond_code = reverse_condition (cond_code);
11491 invert = true;
11492 }
11493
11494 if (cond_code == LEU)
11495 val++;
11496
11497 rtx tmp = gen_reg_rtx (<MODE>mode);
11498 rtx tmp2 = gen_reg_rtx (<MODE>mode);
11499 emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
11500 emit_insn (gen_one_cmpl<mode>2 (tmp2, op1));
11501 rtx x = gen_reg_rtx (<MODE>mode);
11502 if (val < 0)
11503 emit_insn (gen_ior<mode>3 (x, tmp, tmp2));
11504 else
11505 emit_insn (gen_and<mode>3 (x, tmp, tmp2));
11506
11507 if (invert)
11508 {
11509 rtx tmp = gen_reg_rtx (<MODE>mode);
11510 emit_insn (gen_one_cmpl<mode>2 (tmp, x));
11511 x = tmp;
11512 }
11513
11514 int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11515 emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
11516
11517 DONE;
11518 })
11519
11520 (define_expand "cstore<mode>4"
11521 [(use (match_operator 1 "comparison_operator"
11522 [(match_operand:GPR 2 "gpc_reg_operand")
11523 (match_operand:GPR 3 "reg_or_short_operand")]))
11524 (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11525 ""
11526 {
11527 /* Everything is best done with setbc[r] if available. */
11528 if (TARGET_POWER10)
11529 rs6000_emit_int_cmove (operands[0], operands[1], const1_rtx, const0_rtx);
11530
11531 /* Expanding EQ and NE directly to some machine instructions does not help
11532 but does hurt combine. So don't. */
11533 if (GET_CODE (operands[1]) == EQ)
11534 emit_insn (gen_eq<mode>3 (operands[0], operands[2], operands[3]));
11535 else if (<MODE>mode == Pmode
11536 && GET_CODE (operands[1]) == NE)
11537 emit_insn (gen_ne<mode>3 (operands[0], operands[2], operands[3]));
11538 else if (GET_CODE (operands[1]) == NE)
11539 {
11540 rtx tmp = gen_reg_rtx (<MODE>mode);
11541 emit_insn (gen_eq<mode>3 (tmp, operands[2], operands[3]));
11542 emit_insn (gen_xor<mode>3 (operands[0], tmp, const1_rtx));
11543 }
11544
11545 /* If ISEL is fast, expand to it. */
11546 else if (TARGET_ISEL)
11547 rs6000_emit_int_cmove (operands[0], operands[1], const1_rtx, const0_rtx);
11548
11549 /* Expanding the unsigned comparisons helps a lot: all the neg_ltu
11550 etc. combinations magically work out just right. */
11551 else if (<MODE>mode == Pmode
11552 && unsigned_comparison_operator (operands[1], VOIDmode))
11553 emit_insn (gen_cstore<mode>4_unsigned (operands[0], operands[1],
11554 operands[2], operands[3]));
11555
11556 /* For comparisons smaller than Pmode we can cheaply do things in Pmode. */
11557 else if (<MODE>mode == SImode && Pmode == DImode)
11558 emit_insn (gen_cstore_si_as_di (operands[0], operands[1],
11559 operands[2], operands[3]));
11560
11561 /* For signed comparisons against a constant, we can do some simple
11562 bit-twiddling. */
11563 else if (signed_comparison_operator (operands[1], VOIDmode)
11564 && CONST_INT_P (operands[3]))
11565 emit_insn (gen_cstore<mode>4_signed_imm (operands[0], operands[1],
11566 operands[2], operands[3]));
11567
11568 /* And similarly for unsigned comparisons. */
11569 else if (unsigned_comparison_operator (operands[1], VOIDmode)
11570 && CONST_INT_P (operands[3]))
11571 emit_insn (gen_cstore<mode>4_unsigned_imm (operands[0], operands[1],
11572 operands[2], operands[3]));
11573
11574 /* We also do not want to use mfcr for signed comparisons. */
11575 else if (<MODE>mode == Pmode
11576 && signed_comparison_operator (operands[1], VOIDmode))
11577 emit_insn (gen_cstore<mode>4_signed (operands[0], operands[1],
11578 operands[2], operands[3]));
11579
11580 /* Everything else, use the mfcr brute force. */
11581 else
11582 rs6000_emit_sCOND (<MODE>mode, operands);
11583
11584 DONE;
11585 })
11586
11587 (define_expand "cstore<mode>4"
11588 [(use (match_operator 1 "comparison_operator"
11589 [(match_operand:FP 2 "gpc_reg_operand")
11590 (match_operand:FP 3 "gpc_reg_operand")]))
11591 (clobber (match_operand:SI 0 "gpc_reg_operand"))]
11592 ""
11593 {
11594 rs6000_emit_sCOND (<MODE>mode, operands);
11595 DONE;
11596 })
11597
11598
11599 (define_expand "stack_protect_set"
11600 [(match_operand 0 "memory_operand")
11601 (match_operand 1 "memory_operand")]
11602 ""
11603 {
11604 if (rs6000_stack_protector_guard == SSP_TLS)
11605 {
11606 rtx reg = gen_rtx_REG (Pmode, rs6000_stack_protector_guard_reg);
11607 rtx offset = GEN_INT (rs6000_stack_protector_guard_offset);
11608 rtx addr = gen_rtx_PLUS (Pmode, reg, offset);
11609 operands[1] = gen_rtx_MEM (Pmode, addr);
11610 }
11611
11612 if (TARGET_64BIT)
11613 emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
11614 else
11615 emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
11616
11617 DONE;
11618 })
11619
11620 (define_insn "stack_protect_setsi"
11621 [(set (match_operand:SI 0 "memory_operand" "=m")
11622 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
11623 (set (match_scratch:SI 2 "=&r") (const_int 0))]
11624 "TARGET_32BIT"
11625 "lwz%U1%X1 %2,%1\;stw%U0%X0 %2,%0\;li %2,0"
11626 [(set_attr "type" "three")
11627 (set_attr "length" "12")])
11628
11629 ;; We can't use the prefixed attribute here because there are two memory
11630 ;; instructions. We can't split the insn due to the fact that this operation
11631 ;; needs to be done in one piece.
11632 (define_insn "stack_protect_setdi"
11633 [(set (match_operand:DI 0 "memory_operand" "=Y")
11634 (unspec:DI [(match_operand:DI 1 "memory_operand" "Y")] UNSPEC_SP_SET))
11635 (set (match_scratch:DI 2 "=&r") (const_int 0))]
11636 "TARGET_64BIT"
11637 {
11638 if (prefixed_memory (operands[1], DImode))
11639 output_asm_insn ("pld %2,%1", operands);
11640 else
11641 output_asm_insn ("ld%U1%X1 %2,%1", operands);
11642
11643 if (prefixed_memory (operands[0], DImode))
11644 output_asm_insn ("pstd %2,%0", operands);
11645 else
11646 output_asm_insn ("std%U0%X0 %2,%0", operands);
11647
11648 return "li %2,0";
11649 }
11650 [(set_attr "type" "three")
11651
11652 ;; Back to back prefixed memory instructions take 20 bytes (8 bytes for each
11653 ;; prefixed instruction + 4 bytes for the possible NOP). Add in 4 bytes for
11654 ;; the LI 0 at the end.
11655 (set_attr "prefixed" "no")
11656 (set_attr "num_insns" "3")
11657 (set (attr "length")
11658 (cond [(and (match_operand 0 "prefixed_memory")
11659 (match_operand 1 "prefixed_memory"))
11660 (const_int 24)
11661
11662 (ior (match_operand 0 "prefixed_memory")
11663 (match_operand 1 "prefixed_memory"))
11664 (const_int 20)]
11665
11666 (const_int 12)))])
11667
11668 (define_expand "stack_protect_test"
11669 [(match_operand 0 "memory_operand")
11670 (match_operand 1 "memory_operand")
11671 (match_operand 2 "")]
11672 ""
11673 {
11674 rtx guard = operands[1];
11675
11676 if (rs6000_stack_protector_guard == SSP_TLS)
11677 {
11678 rtx reg = gen_rtx_REG (Pmode, rs6000_stack_protector_guard_reg);
11679 rtx offset = GEN_INT (rs6000_stack_protector_guard_offset);
11680 rtx addr = gen_rtx_PLUS (Pmode, reg, offset);
11681 guard = gen_rtx_MEM (Pmode, addr);
11682 }
11683
11684 operands[1] = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, guard), UNSPEC_SP_TEST);
11685 rtx test = gen_rtx_EQ (VOIDmode, operands[0], operands[1]);
11686 rtx jump = gen_cbranchsi4 (test, operands[0], operands[1], operands[2]);
11687 emit_jump_insn (jump);
11688
11689 DONE;
11690 })
11691
11692 (define_insn "stack_protect_testsi"
11693 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
11694 (unspec:CCEQ [(match_operand:SI 1 "memory_operand" "m,m")
11695 (match_operand:SI 2 "memory_operand" "m,m")]
11696 UNSPEC_SP_TEST))
11697 (set (match_scratch:SI 4 "=r,r") (const_int 0))
11698 (clobber (match_scratch:SI 3 "=&r,&r"))]
11699 "TARGET_32BIT"
11700 "@
11701 lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0
11702 lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;cmplw %0,%3,%4\;li %3,0\;li %4,0"
11703 [(set_attr "length" "16,20")])
11704
11705 ;; We can't use the prefixed attribute here because there are two memory
11706 ;; instructions. We can't split the insn due to the fact that this operation
11707 ;; needs to be done in one piece.
11708 (define_insn "stack_protect_testdi"
11709 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
11710 (unspec:CCEQ [(match_operand:DI 1 "memory_operand" "Y,Y")
11711 (match_operand:DI 2 "memory_operand" "Y,Y")]
11712 UNSPEC_SP_TEST))
11713 (set (match_scratch:DI 4 "=r,r") (const_int 0))
11714 (clobber (match_scratch:DI 3 "=&r,&r"))]
11715 "TARGET_64BIT"
11716 {
11717 if (prefixed_memory (operands[1], DImode))
11718 output_asm_insn ("pld %3,%1", operands);
11719 else
11720 output_asm_insn ("ld%U1%X1 %3,%1", operands);
11721
11722 if (prefixed_memory (operands[2], DImode))
11723 output_asm_insn ("pld %4,%2", operands);
11724 else
11725 output_asm_insn ("ld%U2%X2 %4,%2", operands);
11726
11727 if (which_alternative == 0)
11728 output_asm_insn ("xor. %3,%3,%4", operands);
11729 else
11730 output_asm_insn ("cmpld %0,%3,%4\;li %3,0", operands);
11731
11732 return "li %4,0";
11733 }
11734 ;; Back to back prefixed memory instructions take 20 bytes (8 bytes for each
11735 ;; prefixed instruction + 4 bytes for the possible NOP). Add in either 4 or
11736 ;; 8 bytes to do the test.
11737 [(set_attr "prefixed" "no")
11738 (set_attr "num_insns" "4,5")
11739 (set (attr "length")
11740 (cond [(and (match_operand 1 "prefixed_memory")
11741 (match_operand 2 "prefixed_memory"))
11742 (if_then_else (eq_attr "alternative" "0")
11743 (const_int 28)
11744 (const_int 32))
11745
11746 (ior (match_operand 1 "prefixed_memory")
11747 (match_operand 2 "prefixed_memory"))
11748 (if_then_else (eq_attr "alternative" "0")
11749 (const_int 20)
11750 (const_int 24))]
11751
11752 (if_then_else (eq_attr "alternative" "0")
11753 (const_int 16)
11754 (const_int 20))))])
11755
11756 \f
11757 ;; Here are the actual compare insns.
11758 (define_insn "*cmp<mode>_signed"
11759 [(set (match_operand:CC 0 "cc_reg_operand" "=y")
11760 (compare:CC (match_operand:GPR 1 "gpc_reg_operand" "r")
11761 (match_operand:GPR 2 "reg_or_short_operand" "rI")))]
11762 ""
11763 "cmp<wd>%I2 %0,%1,%2"
11764 [(set_attr "type" "cmp")])
11765
11766 (define_insn "*cmp<mode>_unsigned"
11767 [(set (match_operand:CCUNS 0 "cc_reg_operand" "=y")
11768 (compare:CCUNS (match_operand:GPR 1 "gpc_reg_operand" "r")
11769 (match_operand:GPR 2 "reg_or_u_short_operand" "rK")))]
11770 ""
11771 "cmpl<wd>%I2 %0,%1,%2"
11772 [(set_attr "type" "cmp")])
11773
11774 ;; If we are comparing a register for equality with a large constant,
11775 ;; we can do this with an XOR followed by a compare. But this is profitable
11776 ;; only if the large constant is only used for the comparison (and in this
11777 ;; case we already have a register to reuse as scratch).
11778 ;;
11779 ;; For 64-bit registers, we could only do so if the constant's bit 15 is clear:
11780 ;; otherwise we'd need to XOR with FFFFFFFF????0000 which is not available.
11781
11782 (define_peephole2
11783 [(set (match_operand:SI 0 "register_operand")
11784 (match_operand:SI 1 "logical_const_operand"))
11785 (set (match_dup 0) (match_operator:SI 3 "boolean_or_operator"
11786 [(match_dup 0)
11787 (match_operand:SI 2 "logical_const_operand")]))
11788 (set (match_operand:CC 4 "cc_reg_operand")
11789 (compare:CC (match_operand:SI 5 "gpc_reg_operand")
11790 (match_dup 0)))
11791 (set (pc)
11792 (if_then_else (match_operator 6 "equality_operator"
11793 [(match_dup 4) (const_int 0)])
11794 (match_operand 7 "")
11795 (match_operand 8 "")))]
11796 "peep2_reg_dead_p (3, operands[0])
11797 && peep2_reg_dead_p (4, operands[4])
11798 && REGNO (operands[0]) != REGNO (operands[5])"
11799 [(set (match_dup 0) (xor:SI (match_dup 5) (match_dup 9)))
11800 (set (match_dup 4) (compare:CC (match_dup 0) (match_dup 10)))
11801 (set (pc) (if_then_else (match_dup 6) (match_dup 7) (match_dup 8)))]
11802
11803 {
11804 /* Get the constant we are comparing against, and see what it looks like
11805 when sign-extended from 16 to 32 bits. Then see what constant we could
11806 XOR with SEXTC to get the sign-extended value. */
11807 rtx cnst = simplify_const_binary_operation (GET_CODE (operands[3]),
11808 SImode,
11809 operands[1], operands[2]);
11810 HOST_WIDE_INT c = INTVAL (cnst);
11811 HOST_WIDE_INT sextc = ((c & 0xffff) ^ 0x8000) - 0x8000;
11812 HOST_WIDE_INT xorv = c ^ sextc;
11813
11814 operands[9] = GEN_INT (xorv);
11815 operands[10] = GEN_INT (sextc);
11816 })
11817
11818 ;; Only need to compare second words if first words equal
11819 (define_insn "*cmp<mode>_internal1"
11820 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
11821 (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
11822 (match_operand:IBM128 2 "gpc_reg_operand" "d")))]
11823 "!TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode)
11824 && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
11825 "fcmpu %0,%1,%2\;bne %0,$+8\;fcmpu %0,%L1,%L2"
11826 [(set_attr "type" "fpcompare")
11827 (set_attr "length" "12")])
11828
11829 (define_insn_and_split "*cmp<IBM128:mode>_internal2"
11830 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
11831 (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
11832 (match_operand:IBM128 2 "gpc_reg_operand" "d")))
11833 (clobber (match_scratch:DF 3 "=d"))
11834 (clobber (match_scratch:DF 4 "=d"))
11835 (clobber (match_scratch:DF 5 "=d"))
11836 (clobber (match_scratch:DF 6 "=d"))
11837 (clobber (match_scratch:DF 7 "=d"))
11838 (clobber (match_scratch:DF 8 "=d"))
11839 (clobber (match_scratch:DF 9 "=d"))
11840 (clobber (match_scratch:DF 10 "=d"))
11841 (clobber (match_scratch:GPR 11 "=b"))]
11842 "TARGET_XL_COMPAT && FLOAT128_IBM_P (<IBM128:MODE>mode)
11843 && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
11844 "#"
11845 "&& reload_completed"
11846 [(set (match_dup 3) (match_dup 14))
11847 (set (match_dup 4) (match_dup 15))
11848 (set (match_dup 9) (abs:DF (match_dup 5)))
11849 (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 3)))
11850 (set (pc) (if_then_else (ne (match_dup 0) (const_int 0))
11851 (label_ref (match_dup 12))
11852 (pc)))
11853 (set (match_dup 0) (compare:CCFP (match_dup 5) (match_dup 7)))
11854 (set (pc) (label_ref (match_dup 13)))
11855 (match_dup 12)
11856 (set (match_dup 10) (minus:DF (match_dup 5) (match_dup 7)))
11857 (set (match_dup 9) (minus:DF (match_dup 6) (match_dup 8)))
11858 (set (match_dup 9) (plus:DF (match_dup 10) (match_dup 9)))
11859 (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 4)))
11860 (match_dup 13)]
11861 {
11862 REAL_VALUE_TYPE rv;
11863 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
11864 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
11865
11866 operands[5] = simplify_gen_subreg (DFmode, operands[1],
11867 <IBM128:MODE>mode, hi_word);
11868 operands[6] = simplify_gen_subreg (DFmode, operands[1],
11869 <IBM128:MODE>mode, lo_word);
11870 operands[7] = simplify_gen_subreg (DFmode, operands[2],
11871 <IBM128:MODE>mode, hi_word);
11872 operands[8] = simplify_gen_subreg (DFmode, operands[2],
11873 <IBM128:MODE>mode, lo_word);
11874 operands[12] = gen_label_rtx ();
11875 operands[13] = gen_label_rtx ();
11876 real_inf (&rv);
11877 operands[14] = force_const_mem (DFmode,
11878 const_double_from_real_value (rv, DFmode));
11879 operands[15] = force_const_mem (DFmode,
11880 const_double_from_real_value (dconst0,
11881 DFmode));
11882 if (TARGET_TOC)
11883 {
11884 rtx tocref;
11885 tocref = create_TOC_reference (XEXP (operands[14], 0), operands[11]);
11886 operands[14] = gen_const_mem (DFmode, tocref);
11887 tocref = create_TOC_reference (XEXP (operands[15], 0), operands[11]);
11888 operands[15] = gen_const_mem (DFmode, tocref);
11889 set_mem_alias_set (operands[14], get_TOC_alias_set ());
11890 set_mem_alias_set (operands[15], get_TOC_alias_set ());
11891 }
11892 })
11893 \f
11894 ;; Now we have the scc insns. We can do some combinations because of the
11895 ;; way the machine works.
11896 ;;
11897 ;; Note that this is probably faster if we can put an insn between the
11898 ;; mfcr and rlinm, but this is tricky. Let's leave it for now. In most
11899 ;; cases the insns below which don't use an intermediate CR field will
11900 ;; be used instead.
11901 (define_insn "set<mode>_cc"
11902 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
11903 (match_operator:GPR 1 "scc_comparison_operator"
11904 [(match_operand 2 "cc_reg_operand" "y")
11905 (const_int 0)]))]
11906 ""
11907 "mfcr %0%Q2\;rlwinm %0,%0,%J1,1"
11908 [(set (attr "type")
11909 (cond [(match_test "TARGET_MFCRF")
11910 (const_string "mfcrf")
11911 ]
11912 (const_string "mfcr")))
11913 (set_attr "length" "8")])
11914
11915
11916 (define_code_iterator cmp [eq ne lt ltu gt gtu le leu ge geu])
11917 (define_code_attr UNS [(eq "CC")
11918 (ne "CC")
11919 (lt "CC") (ltu "CCUNS")
11920 (gt "CC") (gtu "CCUNS")
11921 (le "CC") (leu "CCUNS")
11922 (ge "CC") (geu "CCUNS")])
11923 (define_code_attr UNSu_ [(eq "")
11924 (ne "")
11925 (lt "") (ltu "u_")
11926 (gt "") (gtu "u_")
11927 (le "") (leu "u_")
11928 (ge "") (geu "u_")])
11929 (define_code_attr UNSIK [(eq "I")
11930 (ne "I")
11931 (lt "I") (ltu "K")
11932 (gt "I") (gtu "K")
11933 (le "I") (leu "K")
11934 (ge "I") (geu "K")])
11935
11936 (define_insn_and_split "<code><GPR:mode><GPR2:mode>2_isel"
11937 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
11938 (cmp:GPR (match_operand:GPR2 1 "gpc_reg_operand" "r")
11939 (match_operand:GPR2 2 "reg_or_<cmp:UNSu_>short_operand" "r<cmp:UNSIK>")))
11940 (clobber (match_scratch:GPR 3 "=r"))
11941 (clobber (match_scratch:GPR 4 "=r"))
11942 (clobber (match_scratch:<UNS> 5 "=y"))]
11943 "!TARGET_POWER10 && TARGET_ISEL
11944 && !(<CODE> == EQ && operands[2] == const0_rtx)
11945 && !(<CODE> == NE && operands[2] == const0_rtx
11946 && <GPR:MODE>mode == Pmode && <GPR2:MODE>mode == Pmode)"
11947 "#"
11948 "&& 1"
11949 [(pc)]
11950 {
11951 rtx_code code = <CODE>;
11952 if (CONST_INT_P (operands[2]) && code != EQ && code != NE)
11953 {
11954 HOST_WIDE_INT val = INTVAL (operands[2]);
11955 if (code == LT && val != -0x8000)
11956 {
11957 code = LE;
11958 val--;
11959 }
11960 if (code == GT && val != 0x7fff)
11961 {
11962 code = GE;
11963 val++;
11964 }
11965 if (code == LTU && val != 0)
11966 {
11967 code = LEU;
11968 val--;
11969 }
11970 if (code == GTU && val != 0xffff)
11971 {
11972 code = GEU;
11973 val++;
11974 }
11975 operands[2] = GEN_INT (val);
11976 }
11977
11978 if (code == NE || code == LE || code == GE || code == LEU || code == GEU)
11979 operands[3] = const0_rtx;
11980 else
11981 {
11982 if (GET_CODE (operands[3]) == SCRATCH)
11983 operands[3] = gen_reg_rtx (<GPR:MODE>mode);
11984 emit_move_insn (operands[3], const0_rtx);
11985 }
11986
11987 if (GET_CODE (operands[4]) == SCRATCH)
11988 operands[4] = gen_reg_rtx (<GPR:MODE>mode);
11989 emit_move_insn (operands[4], const1_rtx);
11990
11991 if (GET_CODE (operands[5]) == SCRATCH)
11992 operands[5] = gen_reg_rtx (<UNS>mode);
11993
11994 rtx c1 = gen_rtx_COMPARE (<UNS>mode, operands[1], operands[2]);
11995 emit_insn (gen_rtx_SET (operands[5], c1));
11996
11997 rtx c2 = gen_rtx_fmt_ee (code, <GPR:MODE>mode, operands[5], const0_rtx);
11998 rtx x = gen_rtx_IF_THEN_ELSE (<GPR:MODE>mode, c2, operands[4], operands[3]);
11999 emit_move_insn (operands[0], x);
12000
12001 DONE;
12002 }
12003 [(set (attr "cost")
12004 (if_then_else (match_test "(CONST_INT_P (operands[2]) && <CODE> != EQ)
12005 || <CODE> == NE
12006 || <CODE> == LE || <CODE> == GE
12007 || <CODE> == LEU || <CODE> == GEU")
12008 (const_string "9")
12009 (const_string "10")))])
12010
12011 (define_mode_attr scc_eq_op2 [(SI "rKLI")
12012 (DI "rKJI")])
12013
12014 (define_expand "eq<mode>3"
12015 [(parallel [
12016 (set (match_operand:GPR 0 "gpc_reg_operand" "=r")
12017 (eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
12018 (match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>")))
12019 (clobber (match_scratch:GPR 3 "=r"))
12020 (clobber (match_scratch:GPR 4 "=r"))])]
12021 ""
12022 {
12023 if (TARGET_POWER10)
12024 {
12025 rtx cc = gen_reg_rtx (CCmode);
12026 rtx compare = gen_rtx_COMPARE (CCmode, operands[1], operands[2]);
12027 emit_insn (gen_rtx_SET (cc, compare));
12028 rtx eq = gen_rtx_fmt_ee (EQ, <MODE>mode, cc, const0_rtx);
12029 emit_insn (gen_setbc_signed_<mode> (operands[0], eq, cc));
12030 DONE;
12031 }
12032
12033 if (TARGET_ISEL && operands[2] != const0_rtx)
12034 {
12035 emit_insn (gen_eq<mode><mode>2_isel (operands[0], operands[1],
12036 operands[2]));
12037 DONE;
12038 }
12039 })
12040
12041 (define_insn_and_split "*eq<mode>3"
12042 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
12043 (eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
12044 (match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>")))
12045 (clobber (match_scratch:GPR 3 "=r"))
12046 (clobber (match_scratch:GPR 4 "=r"))]
12047 "!TARGET_POWER10 && !(TARGET_ISEL && operands[2] != const0_rtx)"
12048 "#"
12049 "&& 1"
12050 [(set (match_dup 4)
12051 (clz:GPR (match_dup 3)))
12052 (set (match_dup 0)
12053 (lshiftrt:GPR (match_dup 4)
12054 (match_dup 5)))]
12055 {
12056 operands[3] = rs6000_emit_eqne (<MODE>mode,
12057 operands[1], operands[2], operands[3]);
12058
12059 if (GET_CODE (operands[4]) == SCRATCH)
12060 operands[4] = gen_reg_rtx (<MODE>mode);
12061
12062 operands[5] = GEN_INT (exact_log2 (GET_MODE_BITSIZE (<MODE>mode)));
12063 }
12064 [(set (attr "length")
12065 (if_then_else (match_test "operands[2] == const0_rtx")
12066 (const_string "8")
12067 (const_string "12")))])
12068
12069 (define_expand "ne<mode>3"
12070 [(parallel [
12071 (set (match_operand:GPR 0 "gpc_reg_operand" "=r")
12072 (ne:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
12073 (match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>")))
12074 (clobber (match_scratch:GPR 3 "=r"))
12075 (clobber (match_scratch:GPR 4 "=r"))
12076 (clobber (reg:GPR CA_REGNO))])]
12077 ""
12078 {
12079 if (TARGET_POWER10)
12080 {
12081 rtx cc = gen_reg_rtx (CCmode);
12082 rtx compare = gen_rtx_COMPARE (CCmode, operands[1], operands[2]);
12083 emit_insn (gen_rtx_SET (cc, compare));
12084 rtx ne = gen_rtx_fmt_ee (NE, <MODE>mode, cc, const0_rtx);
12085 emit_insn (gen_setbc_signed_<mode> (operands[0], ne, cc));
12086 DONE;
12087 }
12088
12089 if (<MODE>mode != Pmode)
12090 {
12091 rtx x = gen_reg_rtx (<MODE>mode);
12092 emit_insn (gen_eq<mode>3 (x, operands[1], operands[2]));
12093 emit_insn (gen_xor<mode>3 (operands[0], x, const1_rtx));
12094 DONE;
12095 }
12096
12097 if (TARGET_ISEL && operands[2] != const0_rtx)
12098 {
12099 emit_insn (gen_ne<mode><mode>2_isel (operands[0], operands[1],
12100 operands[2]));
12101 DONE;
12102 }
12103 })
12104
12105 (define_insn_and_split "*ne<mode>3"
12106 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12107 (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12108 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")))
12109 (clobber (match_scratch:P 3 "=r"))
12110 (clobber (match_scratch:P 4 "=r"))
12111 (clobber (reg:P CA_REGNO))]
12112 "!TARGET_POWER10 && !(TARGET_ISEL && operands[2] != const0_rtx)"
12113 "#"
12114 "&& 1"
12115 [(parallel [(set (match_dup 4)
12116 (plus:P (match_dup 3)
12117 (const_int -1)))
12118 (set (reg:P CA_REGNO)
12119 (ne:P (match_dup 3)
12120 (const_int 0)))])
12121 (parallel [(set (match_dup 0)
12122 (plus:P (plus:P (not:P (match_dup 4))
12123 (reg:P CA_REGNO))
12124 (match_dup 3)))
12125 (clobber (reg:P CA_REGNO))])]
12126 {
12127 operands[3] = rs6000_emit_eqne (<MODE>mode,
12128 operands[1], operands[2], operands[3]);
12129
12130 if (GET_CODE (operands[4]) == SCRATCH)
12131 operands[4] = gen_reg_rtx (<MODE>mode);
12132 }
12133 [(set (attr "length")
12134 (if_then_else (match_test "operands[2] == const0_rtx")
12135 (const_string "8")
12136 (const_string "12")))])
12137
12138 (define_insn_and_split "*neg_eq_<mode>"
12139 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12140 (neg:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12141 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12142 (clobber (match_scratch:P 3 "=r"))
12143 (clobber (match_scratch:P 4 "=r"))
12144 (clobber (reg:P CA_REGNO))]
12145 "!TARGET_POWER10"
12146 "#"
12147 "&& 1"
12148 [(parallel [(set (match_dup 4)
12149 (plus:P (match_dup 3)
12150 (const_int -1)))
12151 (set (reg:P CA_REGNO)
12152 (ne:P (match_dup 3)
12153 (const_int 0)))])
12154 (parallel [(set (match_dup 0)
12155 (plus:P (reg:P CA_REGNO)
12156 (const_int -1)))
12157 (clobber (reg:P CA_REGNO))])]
12158 {
12159 operands[3] = rs6000_emit_eqne (<MODE>mode,
12160 operands[1], operands[2], operands[3]);
12161
12162 if (GET_CODE (operands[4]) == SCRATCH)
12163 operands[4] = gen_reg_rtx (<MODE>mode);
12164 }
12165 [(set (attr "length")
12166 (if_then_else (match_test "operands[2] == const0_rtx")
12167 (const_string "8")
12168 (const_string "12")))])
12169
12170 (define_insn_and_split "*neg_ne_<mode>"
12171 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12172 (neg:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12173 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12174 (clobber (match_scratch:P 3 "=r"))
12175 (clobber (match_scratch:P 4 "=r"))
12176 (clobber (reg:P CA_REGNO))]
12177 "!TARGET_POWER10"
12178 "#"
12179 "&& 1"
12180 [(parallel [(set (match_dup 4)
12181 (neg:P (match_dup 3)))
12182 (set (reg:P CA_REGNO)
12183 (eq:P (match_dup 3)
12184 (const_int 0)))])
12185 (parallel [(set (match_dup 0)
12186 (plus:P (reg:P CA_REGNO)
12187 (const_int -1)))
12188 (clobber (reg:P CA_REGNO))])]
12189 {
12190 operands[3] = rs6000_emit_eqne (<MODE>mode,
12191 operands[1], operands[2], operands[3]);
12192
12193 if (GET_CODE (operands[4]) == SCRATCH)
12194 operands[4] = gen_reg_rtx (<MODE>mode);
12195 }
12196 [(set (attr "length")
12197 (if_then_else (match_test "operands[2] == const0_rtx")
12198 (const_string "8")
12199 (const_string "12")))])
12200
12201 (define_insn_and_split "*plus_eq_<mode>"
12202 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12203 (plus:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12204 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
12205 (match_operand:P 3 "gpc_reg_operand" "r")))
12206 (clobber (match_scratch:P 4 "=r"))
12207 (clobber (match_scratch:P 5 "=r"))
12208 (clobber (reg:P CA_REGNO))]
12209 ""
12210 "#"
12211 ""
12212 [(parallel [(set (match_dup 5)
12213 (neg:P (match_dup 4)))
12214 (set (reg:P CA_REGNO)
12215 (eq:P (match_dup 4)
12216 (const_int 0)))])
12217 (parallel [(set (match_dup 0)
12218 (plus:P (match_dup 3)
12219 (reg:P CA_REGNO)))
12220 (clobber (reg:P CA_REGNO))])]
12221 {
12222 operands[4] = rs6000_emit_eqne (<MODE>mode,
12223 operands[1], operands[2], operands[4]);
12224
12225 if (GET_CODE (operands[5]) == SCRATCH)
12226 operands[5] = gen_reg_rtx (<MODE>mode);
12227 }
12228 [(set (attr "length")
12229 (if_then_else (match_test "operands[2] == const0_rtx")
12230 (const_string "8")
12231 (const_string "12")))])
12232
12233 (define_insn_and_split "*plus_ne_<mode>"
12234 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12235 (plus:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12236 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
12237 (match_operand:P 3 "gpc_reg_operand" "r")))
12238 (clobber (match_scratch:P 4 "=r"))
12239 (clobber (match_scratch:P 5 "=r"))
12240 (clobber (reg:P CA_REGNO))]
12241 ""
12242 "#"
12243 ""
12244 [(parallel [(set (match_dup 5)
12245 (plus:P (match_dup 4)
12246 (const_int -1)))
12247 (set (reg:P CA_REGNO)
12248 (ne:P (match_dup 4)
12249 (const_int 0)))])
12250 (parallel [(set (match_dup 0)
12251 (plus:P (match_dup 3)
12252 (reg:P CA_REGNO)))
12253 (clobber (reg:P CA_REGNO))])]
12254 {
12255 operands[4] = rs6000_emit_eqne (<MODE>mode,
12256 operands[1], operands[2], operands[4]);
12257
12258 if (GET_CODE (operands[5]) == SCRATCH)
12259 operands[5] = gen_reg_rtx (<MODE>mode);
12260 }
12261 [(set (attr "length")
12262 (if_then_else (match_test "operands[2] == const0_rtx")
12263 (const_string "8")
12264 (const_string "12")))])
12265
12266 (define_insn_and_split "*minus_eq_<mode>"
12267 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12268 (minus:P (match_operand:P 3 "gpc_reg_operand" "r")
12269 (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12270 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12271 (clobber (match_scratch:P 4 "=r"))
12272 (clobber (match_scratch:P 5 "=r"))
12273 (clobber (reg:P CA_REGNO))]
12274 ""
12275 "#"
12276 ""
12277 [(parallel [(set (match_dup 5)
12278 (plus:P (match_dup 4)
12279 (const_int -1)))
12280 (set (reg:P CA_REGNO)
12281 (ne:P (match_dup 4)
12282 (const_int 0)))])
12283 (parallel [(set (match_dup 0)
12284 (plus:P (plus:P (match_dup 3)
12285 (reg:P CA_REGNO))
12286 (const_int -1)))
12287 (clobber (reg:P CA_REGNO))])]
12288 {
12289 operands[4] = rs6000_emit_eqne (<MODE>mode,
12290 operands[1], operands[2], operands[4]);
12291
12292 if (GET_CODE (operands[5]) == SCRATCH)
12293 operands[5] = gen_reg_rtx (<MODE>mode);
12294 }
12295 [(set (attr "length")
12296 (if_then_else (match_test "operands[2] == const0_rtx")
12297 (const_string "8")
12298 (const_string "12")))])
12299
12300 (define_insn_and_split "*minus_ne_<mode>"
12301 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12302 (minus:P (match_operand:P 3 "gpc_reg_operand" "r")
12303 (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12304 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12305 (clobber (match_scratch:P 4 "=r"))
12306 (clobber (match_scratch:P 5 "=r"))
12307 (clobber (reg:P CA_REGNO))]
12308 ""
12309 "#"
12310 ""
12311 [(parallel [(set (match_dup 5)
12312 (neg:P (match_dup 4)))
12313 (set (reg:P CA_REGNO)
12314 (eq:P (match_dup 4)
12315 (const_int 0)))])
12316 (parallel [(set (match_dup 0)
12317 (plus:P (plus:P (match_dup 3)
12318 (reg:P CA_REGNO))
12319 (const_int -1)))
12320 (clobber (reg:P CA_REGNO))])]
12321 {
12322 operands[4] = rs6000_emit_eqne (<MODE>mode,
12323 operands[1], operands[2], operands[4]);
12324
12325 if (GET_CODE (operands[5]) == SCRATCH)
12326 operands[5] = gen_reg_rtx (<MODE>mode);
12327 }
12328 [(set (attr "length")
12329 (if_then_else (match_test "operands[2] == const0_rtx")
12330 (const_string "8")
12331 (const_string "12")))])
12332
12333 (define_insn_and_split "*eqsi3_ext<mode>"
12334 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
12335 (eq:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
12336 (match_operand:SI 2 "scc_eq_operand" "rKLI")))
12337 (clobber (match_scratch:SI 3 "=r"))
12338 (clobber (match_scratch:SI 4 "=r"))]
12339 "!TARGET_POWER10"
12340 "#"
12341 "&& 1"
12342 [(set (match_dup 4)
12343 (clz:SI (match_dup 3)))
12344 (set (match_dup 0)
12345 (zero_extend:EXTSI
12346 (lshiftrt:SI (match_dup 4)
12347 (const_int 5))))]
12348 {
12349 operands[3] = rs6000_emit_eqne (SImode,
12350 operands[1], operands[2], operands[3]);
12351
12352 if (GET_CODE (operands[4]) == SCRATCH)
12353 operands[4] = gen_reg_rtx (SImode);
12354 }
12355 [(set (attr "length")
12356 (if_then_else (match_test "operands[2] == const0_rtx")
12357 (const_string "8")
12358 (const_string "12")))])
12359
12360 (define_insn_and_split "*nesi3_ext<mode>"
12361 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
12362 (ne:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
12363 (match_operand:SI 2 "scc_eq_operand" "rKLI")))
12364 (clobber (match_scratch:SI 3 "=r"))
12365 (clobber (match_scratch:SI 4 "=r"))
12366 (clobber (match_scratch:EXTSI 5 "=r"))]
12367 "!TARGET_ISEL"
12368 "#"
12369 "&& 1"
12370 [(set (match_dup 4)
12371 (clz:SI (match_dup 3)))
12372 (set (match_dup 5)
12373 (zero_extend:EXTSI
12374 (lshiftrt:SI (match_dup 4)
12375 (const_int 5))))
12376 (set (match_dup 0)
12377 (xor:EXTSI (match_dup 5)
12378 (const_int 1)))]
12379 {
12380 operands[3] = rs6000_emit_eqne (SImode,
12381 operands[1], operands[2], operands[3]);
12382
12383 if (GET_CODE (operands[4]) == SCRATCH)
12384 operands[4] = gen_reg_rtx (SImode);
12385 if (GET_CODE (operands[5]) == SCRATCH)
12386 operands[5] = gen_reg_rtx (<MODE>mode);
12387 }
12388 [(set (attr "length")
12389 (if_then_else (match_test "operands[2] == const0_rtx")
12390 (const_string "12")
12391 (const_string "16")))])
12392
12393
12394 (define_code_iterator fp_rev [ordered ne unle unge])
12395 (define_code_iterator fp_two [ltgt le ge unlt ungt uneq])
12396
12397 (define_insn_and_split "*<code><mode>_cc"
12398 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
12399 (fp_rev:GPR (match_operand:CCFP 1 "cc_reg_operand" "y")
12400 (const_int 0)))]
12401 "!flag_finite_math_only"
12402 "#"
12403 "&& 1"
12404 [(pc)]
12405 {
12406 rtx_code revcode = reverse_condition_maybe_unordered (<CODE>);
12407 rtx eq = gen_rtx_fmt_ee (revcode, <MODE>mode, operands[1], const0_rtx);
12408 rtx tmp = gen_reg_rtx (<MODE>mode);
12409 emit_move_insn (tmp, eq);
12410 emit_insn (gen_xor<mode>3 (operands[0], tmp, const1_rtx));
12411 DONE;
12412 }
12413 [(set_attr "length" "12")])
12414
12415 (define_insn_and_split "*<code><mode>_cc"
12416 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
12417 (fp_two:GPR (match_operand:CCFP 1 "cc_reg_operand" "y")
12418 (const_int 0)))]
12419 "!flag_finite_math_only"
12420 "#"
12421 "&& 1"
12422 [(pc)]
12423 {
12424 rtx cc = rs6000_emit_fp_cror (<CODE>, <MODE>mode, operands[1]);
12425
12426 emit_move_insn (operands[0], gen_rtx_EQ (<MODE>mode, cc, const0_rtx));
12427 DONE;
12428 }
12429 [(set_attr "length" "12")])
12430 \f
12431 ;; Conditional branches.
12432 ;; These either are a single bc insn, or a bc around a b.
12433
12434 (define_insn "*cbranch"
12435 [(set (pc)
12436 (if_then_else (match_operator 1 "branch_comparison_operator"
12437 [(match_operand 2 "cc_reg_operand" "y")
12438 (const_int 0)])
12439 (label_ref (match_operand 0))
12440 (pc)))]
12441 ""
12442 {
12443 return output_cbranch (operands[1], "%l0", 0, insn);
12444 }
12445 [(set_attr "type" "branch")
12446 (set (attr "length")
12447 (if_then_else (and (ge (minus (match_dup 0) (pc))
12448 (const_int -32768))
12449 (lt (minus (match_dup 0) (pc))
12450 (const_int 32764)))
12451 (const_int 4)
12452 (const_int 8)))])
12453
12454 (define_insn_and_split "*cbranch_2insn"
12455 [(set (pc)
12456 (if_then_else (match_operator 1 "extra_insn_branch_comparison_operator"
12457 [(match_operand 2 "cc_reg_operand" "y")
12458 (const_int 0)])
12459 (label_ref (match_operand 0))
12460 (pc)))]
12461 "!flag_finite_math_only"
12462 "#"
12463 "&& 1"
12464 [(pc)]
12465 {
12466 rtx cc = rs6000_emit_fp_cror (GET_CODE (operands[1]), SImode, operands[2]);
12467
12468 rtx note = find_reg_note (curr_insn, REG_BR_PROB, 0);
12469
12470 rtx loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands[0]);
12471 rtx cond = gen_rtx_EQ (CCEQmode, cc, const0_rtx);
12472 rtx ite = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, loc_ref, pc_rtx);
12473 emit_jump_insn (gen_rtx_SET (pc_rtx, ite));
12474
12475 if (note)
12476 {
12477 profile_probability prob
12478 = profile_probability::from_reg_br_prob_note (XINT (note, 0));
12479
12480 add_reg_br_prob_note (get_last_insn (), prob);
12481 }
12482
12483 DONE;
12484 }
12485 [(set_attr "type" "branch")
12486 (set (attr "length")
12487 (if_then_else (and (ge (minus (match_dup 0) (pc))
12488 (const_int -32764))
12489 (lt (minus (match_dup 0) (pc))
12490 (const_int 32760)))
12491 (const_int 8)
12492 (const_int 16)))])
12493
12494 ;; Conditional return.
12495 (define_insn "*creturn"
12496 [(set (pc)
12497 (if_then_else (match_operator 0 "branch_comparison_operator"
12498 [(match_operand 1 "cc_reg_operand" "y")
12499 (const_int 0)])
12500 (any_return)
12501 (pc)))]
12502 "<return_pred>"
12503 {
12504 return output_cbranch (operands[0], NULL, 0, insn);
12505 }
12506 [(set_attr "type" "jmpreg")])
12507
12508 ;; Logic on condition register values.
12509
12510 ; This pattern matches things like
12511 ; (set (reg:CCEQ 68) (compare:CCEQ (ior:SI (gt:SI (reg:CCFP 68) (const_int 0))
12512 ; (eq:SI (reg:CCFP 68) (const_int 0)))
12513 ; (const_int 1)))
12514 ; which are generated by the branch logic.
12515 ; Prefer destructive operations where BT = BB (for crXX BT,BA,BB)
12516
12517 (define_insn "@cceq_ior_compare_<mode>"
12518 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12519 (compare:CCEQ (match_operator:GPR 1 "boolean_operator"
12520 [(match_operator:GPR 2
12521 "branch_positive_comparison_operator"
12522 [(match_operand 3
12523 "cc_reg_operand" "y,y")
12524 (const_int 0)])
12525 (match_operator:GPR 4
12526 "branch_positive_comparison_operator"
12527 [(match_operand 5
12528 "cc_reg_operand" "0,y")
12529 (const_int 0)])])
12530 (const_int 1)))]
12531 ""
12532 "cr%q1 %E0,%j2,%j4"
12533 [(set_attr "type" "cr_logical")
12534 (set_attr "cr_logical_3op" "no,yes")])
12535
12536 ; Why is the constant -1 here, but 1 in the previous pattern?
12537 ; Because ~1 has all but the low bit set.
12538 (define_insn "cceq_ior_compare_complement"
12539 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12540 (compare:CCEQ (match_operator:SI 1 "boolean_operator"
12541 [(not:SI (match_operator:SI 2
12542 "branch_positive_comparison_operator"
12543 [(match_operand 3
12544 "cc_reg_operand" "y,y")
12545 (const_int 0)]))
12546 (match_operator:SI 4
12547 "branch_positive_comparison_operator"
12548 [(match_operand 5
12549 "cc_reg_operand" "0,y")
12550 (const_int 0)])])
12551 (const_int -1)))]
12552 ""
12553 "cr%q1 %E0,%j2,%j4"
12554 [(set_attr "type" "cr_logical")
12555 (set_attr "cr_logical_3op" "no,yes")])
12556
12557 (define_insn "@cceq_rev_compare_<mode>"
12558 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12559 (compare:CCEQ (match_operator:GPR 1
12560 "branch_positive_comparison_operator"
12561 [(match_operand 2
12562 "cc_reg_operand" "0,y")
12563 (const_int 0)])
12564 (const_int 0)))]
12565 ""
12566 "crnot %E0,%j1"
12567 [(set_attr "type" "cr_logical")
12568 (set_attr "cr_logical_3op" "no,yes")])
12569
12570 ;; If we are comparing the result of two comparisons, this can be done
12571 ;; using creqv or crxor.
12572
12573 (define_insn_and_split ""
12574 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y")
12575 (compare:CCEQ (match_operator 1 "branch_comparison_operator"
12576 [(match_operand 2 "cc_reg_operand" "y")
12577 (const_int 0)])
12578 (match_operator 3 "branch_comparison_operator"
12579 [(match_operand 4 "cc_reg_operand" "y")
12580 (const_int 0)])))]
12581 ""
12582 "#"
12583 ""
12584 [(set (match_dup 0) (compare:CCEQ (xor:SI (match_dup 1) (match_dup 3))
12585 (match_dup 5)))]
12586 {
12587 int positive_1, positive_2;
12588
12589 positive_1 = branch_positive_comparison_operator (operands[1],
12590 GET_MODE (operands[1]));
12591 positive_2 = branch_positive_comparison_operator (operands[3],
12592 GET_MODE (operands[3]));
12593
12594 if (! positive_1)
12595 operands[1] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[2]),
12596 GET_CODE (operands[1])),
12597 SImode,
12598 operands[2], const0_rtx);
12599 else if (GET_MODE (operands[1]) != SImode)
12600 operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), SImode,
12601 operands[2], const0_rtx);
12602
12603 if (! positive_2)
12604 operands[3] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[4]),
12605 GET_CODE (operands[3])),
12606 SImode,
12607 operands[4], const0_rtx);
12608 else if (GET_MODE (operands[3]) != SImode)
12609 operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SImode,
12610 operands[4], const0_rtx);
12611
12612 if (positive_1 == positive_2)
12613 {
12614 operands[1] = gen_rtx_NOT (SImode, operands[1]);
12615 operands[5] = constm1_rtx;
12616 }
12617 else
12618 {
12619 operands[5] = const1_rtx;
12620 }
12621 })
12622
12623 ;; Unconditional branch and return.
12624
12625 (define_insn "jump"
12626 [(set (pc)
12627 (label_ref (match_operand 0)))]
12628 ""
12629 "b %l0"
12630 [(set_attr "type" "branch")])
12631
12632 (define_insn "<return_str>return"
12633 [(any_return)]
12634 "<return_pred>"
12635 "blr"
12636 [(set_attr "type" "jmpreg")])
12637
12638 (define_expand "indirect_jump"
12639 [(set (pc) (match_operand 0 "register_operand"))]
12640 ""
12641 {
12642 if (!rs6000_speculate_indirect_jumps) {
12643 rtx ccreg = gen_reg_rtx (CCmode);
12644 emit_jump_insn (gen_indirect_jump_nospec (Pmode, operands[0], ccreg));
12645 DONE;
12646 }
12647 })
12648
12649 (define_insn "*indirect_jump<mode>"
12650 [(set (pc)
12651 (match_operand:P 0 "register_operand" "c,*l"))]
12652 "rs6000_speculate_indirect_jumps"
12653 "b%T0"
12654 [(set_attr "type" "jmpreg")])
12655
12656 (define_insn "@indirect_jump<mode>_nospec"
12657 [(set (pc) (match_operand:P 0 "register_operand" "c,*l"))
12658 (clobber (match_operand:CC 1 "cc_reg_operand" "=y,y"))]
12659 "!rs6000_speculate_indirect_jumps"
12660 "crset %E1\;beq%T0- %1\;b $"
12661 [(set_attr "type" "jmpreg")
12662 (set_attr "length" "12")])
12663
12664 ;; Table jump for switch statements:
12665 (define_expand "tablejump"
12666 [(use (match_operand 0))
12667 (use (label_ref (match_operand 1)))]
12668 ""
12669 {
12670 if (rs6000_speculate_indirect_jumps)
12671 {
12672 if (TARGET_32BIT)
12673 emit_jump_insn (gen_tablejumpsi (operands[0], operands[1]));
12674 else
12675 emit_jump_insn (gen_tablejumpdi (operands[0], operands[1]));
12676 }
12677 else
12678 {
12679 rtx ccreg = gen_reg_rtx (CCmode);
12680 rtx jump;
12681 if (TARGET_32BIT)
12682 jump = gen_tablejumpsi_nospec (operands[0], operands[1], ccreg);
12683 else
12684 jump = gen_tablejumpdi_nospec (operands[0], operands[1], ccreg);
12685 emit_jump_insn (jump);
12686 }
12687 DONE;
12688 })
12689
12690 (define_expand "tablejumpsi"
12691 [(set (match_dup 3)
12692 (plus:SI (match_operand:SI 0)
12693 (match_dup 2)))
12694 (parallel [(set (pc)
12695 (match_dup 3))
12696 (use (label_ref (match_operand 1)))])]
12697 "TARGET_32BIT && rs6000_speculate_indirect_jumps"
12698 {
12699 operands[0] = force_reg (SImode, operands[0]);
12700 operands[2] = force_reg (SImode, gen_rtx_LABEL_REF (SImode, operands[1]));
12701 operands[3] = gen_reg_rtx (SImode);
12702 })
12703
12704 (define_expand "tablejumpsi_nospec"
12705 [(set (match_dup 4)
12706 (plus:SI (match_operand:SI 0)
12707 (match_dup 3)))
12708 (parallel [(set (pc)
12709 (match_dup 4))
12710 (use (label_ref (match_operand 1)))
12711 (clobber (match_operand 2))])]
12712 "TARGET_32BIT && !rs6000_speculate_indirect_jumps"
12713 {
12714 operands[0] = force_reg (SImode, operands[0]);
12715 operands[3] = force_reg (SImode, gen_rtx_LABEL_REF (SImode, operands[1]));
12716 operands[4] = gen_reg_rtx (SImode);
12717 })
12718
12719 (define_expand "tablejumpdi"
12720 [(set (match_dup 4)
12721 (sign_extend:DI (match_operand:SI 0 "lwa_operand")))
12722 (set (match_dup 3)
12723 (plus:DI (match_dup 4)
12724 (match_dup 2)))
12725 (parallel [(set (pc)
12726 (match_dup 3))
12727 (use (label_ref (match_operand 1)))])]
12728 "TARGET_64BIT && rs6000_speculate_indirect_jumps"
12729 {
12730 operands[2] = force_reg (DImode, gen_rtx_LABEL_REF (DImode, operands[1]));
12731 operands[3] = gen_reg_rtx (DImode);
12732 operands[4] = gen_reg_rtx (DImode);
12733 })
12734
12735 (define_expand "tablejumpdi_nospec"
12736 [(set (match_dup 5)
12737 (sign_extend:DI (match_operand:SI 0 "lwa_operand")))
12738 (set (match_dup 4)
12739 (plus:DI (match_dup 5)
12740 (match_dup 3)))
12741 (parallel [(set (pc)
12742 (match_dup 4))
12743 (use (label_ref (match_operand 1)))
12744 (clobber (match_operand 2))])]
12745 "TARGET_64BIT && !rs6000_speculate_indirect_jumps"
12746 {
12747 operands[3] = force_reg (DImode, gen_rtx_LABEL_REF (DImode, operands[1]));
12748 operands[4] = gen_reg_rtx (DImode);
12749 operands[5] = gen_reg_rtx (DImode);
12750 })
12751
12752 (define_insn "*tablejump<mode>_internal1"
12753 [(set (pc)
12754 (match_operand:P 0 "register_operand" "c,*l"))
12755 (use (label_ref (match_operand 1)))]
12756 "rs6000_speculate_indirect_jumps"
12757 "b%T0"
12758 [(set_attr "type" "jmpreg")])
12759
12760 (define_insn "*tablejump<mode>_internal1_nospec"
12761 [(set (pc)
12762 (match_operand:P 0 "register_operand" "c,*l"))
12763 (use (label_ref (match_operand 1)))
12764 (clobber (match_operand:CC 2 "cc_reg_operand" "=y,y"))]
12765 "!rs6000_speculate_indirect_jumps"
12766 "crset %E2\;beq%T0- %2\;b $"
12767 [(set_attr "type" "jmpreg")
12768 (set_attr "length" "12")])
12769
12770 (define_insn "nop"
12771 [(unspec [(const_int 0)] UNSPEC_NOP)]
12772 ""
12773 "nop")
12774
12775 (define_insn "group_ending_nop"
12776 [(unspec [(const_int 0)] UNSPEC_GRP_END_NOP)]
12777 ""
12778 {
12779 operands[0] = gen_rtx_REG (Pmode,
12780 rs6000_tune == PROCESSOR_POWER6 ? 1 : 2);
12781 return "ori %0,%0,0";
12782 })
12783
12784 (define_insn "speculation_barrier"
12785 [(unspec_volatile:BLK [(const_int 0)] UNSPECV_SPEC_BARRIER)]
12786 ""
12787 {
12788 operands[0] = gen_rtx_REG (Pmode, 31);
12789 return "ori %0,%0,0";
12790 })
12791 \f
12792 ;; Define the subtract-one-and-jump insns, starting with the template
12793 ;; so loop.c knows what to generate.
12794
12795 (define_expand "doloop_end"
12796 [(use (match_operand 0)) ; loop pseudo
12797 (use (match_operand 1))] ; label
12798 ""
12799 {
12800 if (GET_MODE (operands[0]) != Pmode)
12801 FAIL;
12802
12803 emit_jump_insn (gen_ctr (Pmode, operands[0], operands[1]));
12804 DONE;
12805 })
12806
12807 (define_expand "@ctr<mode>"
12808 [(parallel [(set (pc)
12809 (if_then_else (ne (match_operand:P 0 "register_operand")
12810 (const_int 1))
12811 (label_ref (match_operand 1))
12812 (pc)))
12813 (set (match_dup 0)
12814 (plus:P (match_dup 0)
12815 (const_int -1)))
12816 (clobber (match_scratch:CC 2))
12817 (clobber (match_scratch:P 3))])]
12818 ""
12819 "")
12820
12821 ;; We need to be able to do this for any operand, including MEM, or we
12822 ;; will cause reload to blow up since we don't allow output reloads on
12823 ;; JUMP_INSNs.
12824 ;; For the length attribute to be calculated correctly, the
12825 ;; label MUST be operand 0.
12826 ;; rs6000_legitimate_combined_insn prevents combine creating any of
12827 ;; the ctr<mode> insns.
12828
12829 (define_code_iterator eqne [eq ne])
12830 (define_code_attr bd [(eq "bdz") (ne "bdnz")])
12831 (define_code_attr bd_neg [(eq "bdnz") (ne "bdz")])
12832
12833 (define_insn "<bd>_<mode>"
12834 [(set (pc)
12835 (if_then_else (eqne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12836 (const_int 1))
12837 (label_ref (match_operand 0))
12838 (pc)))
12839 (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wa*c*l")
12840 (plus:P (match_dup 1)
12841 (const_int -1)))
12842 (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
12843 (clobber (match_scratch:P 4 "=X,X,&r,r"))]
12844 ""
12845 {
12846 if (which_alternative != 0)
12847 return "#";
12848 else if (get_attr_length (insn) == 4)
12849 return "<bd> %l0";
12850 else
12851 return "<bd_neg> $+8\;b %l0";
12852 }
12853 [(set_attr "type" "branch")
12854 (set_attr_alternative "length"
12855 [(if_then_else (and (ge (minus (match_dup 0) (pc))
12856 (const_int -32768))
12857 (lt (minus (match_dup 0) (pc))
12858 (const_int 32764)))
12859 (const_int 4)
12860 (const_int 8))
12861 (const_string "16")
12862 (const_string "20")
12863 (const_string "20")])])
12864
12865 ;; Now the splitter if we could not allocate the CTR register
12866 (define_split
12867 [(set (pc)
12868 (if_then_else (match_operator 2 "comparison_operator"
12869 [(match_operand:P 1 "gpc_reg_operand")
12870 (const_int 1)])
12871 (match_operand 5)
12872 (match_operand 6)))
12873 (set (match_operand:P 0 "nonimmediate_operand")
12874 (plus:P (match_dup 1)
12875 (const_int -1)))
12876 (clobber (match_scratch:CC 3))
12877 (clobber (match_scratch:P 4))]
12878 "reload_completed"
12879 [(set (pc)
12880 (if_then_else (match_dup 7)
12881 (match_dup 5)
12882 (match_dup 6)))]
12883 {
12884 operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[2]), VOIDmode, operands[3],
12885 const0_rtx);
12886 emit_insn (gen_rtx_SET (operands[3],
12887 gen_rtx_COMPARE (CCmode, operands[1], const1_rtx)));
12888 if (int_reg_operand (operands[0], <MODE>mode))
12889 emit_insn (gen_add<mode>3 (operands[0], operands[1], constm1_rtx));
12890 else
12891 {
12892 emit_insn (gen_add<mode>3 (operands[4], operands[1], constm1_rtx));
12893 emit_move_insn (operands[0], operands[4]);
12894 }
12895 /* No DONE so branch comes from the pattern. */
12896 })
12897
12898 ;; patterns for bdnzt/bdnzf/bdzt/bdzf
12899 ;; Note that in the case of long branches we have to decompose this into
12900 ;; bdnz+bc. This is because bdnzt has an implied AND between the ctr condition
12901 ;; and the CR bit, which means there is no way to conveniently invert the
12902 ;; comparison as is done with plain bdnz/bdz.
12903
12904 (define_insn "<bd>tf_<mode>"
12905 [(set (pc)
12906 (if_then_else
12907 (and
12908 (eqne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12909 (const_int 1))
12910 (match_operator 3 "branch_comparison_operator"
12911 [(match_operand 4 "cc_reg_operand" "y,y,y,y")
12912 (const_int 0)]))
12913 (label_ref (match_operand 0))
12914 (pc)))
12915 (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wa*c*l")
12916 (plus:P (match_dup 1)
12917 (const_int -1)))
12918 (clobber (match_scratch:P 5 "=X,X,&r,r"))
12919 (clobber (match_scratch:CC 6 "=X,&y,&y,&y"))
12920 (clobber (match_scratch:CCEQ 7 "=X,&y,&y,&y"))]
12921 ""
12922 {
12923 if (which_alternative != 0)
12924 return "#";
12925 else if (get_attr_length (insn) == 4)
12926 {
12927 if (branch_positive_comparison_operator (operands[3],
12928 GET_MODE (operands[3])))
12929 return "<bd>t %j3,%l0";
12930 else
12931 return "<bd>f %j3,%l0";
12932 }
12933 else
12934 {
12935 static char seq[96];
12936 char *bcs = output_cbranch (operands[3], ".Lshort%=", 1, insn);
12937 sprintf(seq, "<bd_neg> .Lshort%%=\;%s\;b %%l0\;.Lshort%%=:", bcs);
12938 return seq;
12939 }
12940 }
12941 [(set_attr "type" "branch")
12942 (set_attr_alternative "length"
12943 [(if_then_else (and (ge (minus (match_dup 0) (pc))
12944 (const_int -32768))
12945 (lt (minus (match_dup 0) (pc))
12946 (const_int 32764)))
12947 (const_int 4)
12948 (const_int 8))
12949 (const_string "16")
12950 (const_string "20")
12951 (const_string "20")])])
12952
12953 ;; Now the splitter if we could not allocate the CTR register
12954 (define_split
12955 [(set (pc)
12956 (if_then_else
12957 (and
12958 (match_operator 1 "comparison_operator"
12959 [(match_operand:P 0 "gpc_reg_operand")
12960 (const_int 1)])
12961 (match_operator 3 "branch_comparison_operator"
12962 [(match_operand 2 "cc_reg_operand")
12963 (const_int 0)]))
12964 (match_operand 4)
12965 (match_operand 5)))
12966 (set (match_operand:P 6 "nonimmediate_operand")
12967 (plus:P (match_dup 0)
12968 (const_int -1)))
12969 (clobber (match_scratch:P 7))
12970 (clobber (match_scratch:CC 8))
12971 (clobber (match_scratch:CCEQ 9))]
12972 "reload_completed"
12973 [(pc)]
12974 {
12975 rtx ctr = operands[0];
12976 rtx ctrcmp = operands[1];
12977 rtx ccin = operands[2];
12978 rtx cccmp = operands[3];
12979 rtx dst1 = operands[4];
12980 rtx dst2 = operands[5];
12981 rtx ctrout = operands[6];
12982 rtx ctrtmp = operands[7];
12983 enum rtx_code cmpcode = GET_CODE (ctrcmp);
12984 bool ispos = branch_positive_comparison_operator (ctrcmp, GET_MODE (ctrcmp));
12985 if (!ispos)
12986 cmpcode = reverse_condition (cmpcode);
12987 /* Generate crand/crandc here. */
12988 emit_insn (gen_rtx_SET (operands[8],
12989 gen_rtx_COMPARE (CCmode, ctr, const1_rtx)));
12990 rtx ctrcmpcc = gen_rtx_fmt_ee (cmpcode, SImode, operands[8], const0_rtx);
12991
12992 rtx andexpr = gen_rtx_AND (SImode, ctrcmpcc, cccmp);
12993 if (ispos)
12994 emit_insn (gen_cceq_ior_compare (SImode, operands[9], andexpr, ctrcmpcc,
12995 operands[8], cccmp, ccin));
12996 else
12997 emit_insn (gen_cceq_ior_compare_complement (operands[9], andexpr, ctrcmpcc,
12998 operands[8], cccmp, ccin));
12999 if (int_reg_operand (ctrout, <MODE>mode))
13000 emit_insn (gen_add<mode>3 (ctrout, ctr, constm1_rtx));
13001 else
13002 {
13003 emit_insn (gen_add<mode>3 (ctrtmp, ctr, constm1_rtx));
13004 emit_move_insn (ctrout, ctrtmp);
13005 }
13006 rtx cmp = gen_rtx_EQ (CCEQmode, operands[9], const0_rtx);
13007 emit_jump_insn (gen_rtx_SET (pc_rtx,
13008 gen_rtx_IF_THEN_ELSE (VOIDmode, cmp,
13009 dst1, dst2)));
13010 DONE;
13011 })
13012
13013 \f
13014 (define_insn "trap"
13015 [(trap_if (const_int 1) (const_int 0))]
13016 ""
13017 "trap"
13018 [(set_attr "type" "trap")])
13019
13020 (define_expand "ctrap<mode>4"
13021 [(trap_if (match_operator 0 "ordered_comparison_operator"
13022 [(match_operand:GPR 1 "register_operand")
13023 (match_operand:GPR 2 "reg_or_short_operand")])
13024 (match_operand 3 "zero_constant" ""))]
13025 ""
13026 "")
13027
13028 (define_insn ""
13029 [(trap_if (match_operator 0 "ordered_comparison_operator"
13030 [(match_operand:GPR 1 "register_operand" "r")
13031 (match_operand:GPR 2 "reg_or_short_operand" "rI")])
13032 (const_int 0))]
13033 ""
13034 "t<wd>%V0%I2 %1,%2"
13035 [(set_attr "type" "trap")])
13036 \f
13037 ;; Insns related to generating the function prologue and epilogue.
13038
13039 (define_expand "prologue"
13040 [(use (const_int 0))]
13041 ""
13042 {
13043 rs6000_emit_prologue ();
13044 if (!TARGET_SCHED_PROLOG)
13045 emit_insn (gen_blockage ());
13046 DONE;
13047 })
13048
13049 (define_insn "*movesi_from_cr_one"
13050 [(match_parallel 0 "mfcr_operation"
13051 [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
13052 (unspec:SI [(match_operand:CC 2 "cc_reg_operand" "y")
13053 (match_operand 3 "immediate_operand" "n")]
13054 UNSPEC_MOVESI_FROM_CR))])]
13055 "TARGET_MFCRF"
13056 {
13057 int mask = 0;
13058 int i;
13059 for (i = 0; i < XVECLEN (operands[0], 0); i++)
13060 {
13061 mask = INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
13062 operands[4] = GEN_INT (mask);
13063 output_asm_insn ("mfcr %1,%4", operands);
13064 }
13065 return "";
13066 }
13067 [(set_attr "type" "mfcrf")])
13068
13069 ;; Don't include the volatile CRs since their values are not used wrt CR save
13070 ;; in the prologue and doing so prevents shrink-wrapping because we can't move the
13071 ;; prologue past an insn (early exit test) that defines a register used in the
13072 ;; prologue.
13073 (define_insn "prologue_movesi_from_cr"
13074 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
13075 (unspec:SI [(reg:CC CR2_REGNO) (reg:CC CR3_REGNO)
13076 (reg:CC CR4_REGNO)]
13077 UNSPEC_MOVESI_FROM_CR))]
13078 ""
13079 "mfcr %0"
13080 [(set_attr "type" "mfcr")])
13081
13082 (define_insn "*crsave"
13083 [(match_parallel 0 "crsave_operation"
13084 [(set (match_operand:SI 1 "memory_operand" "=m")
13085 (match_operand:SI 2 "gpc_reg_operand" "r"))])]
13086 ""
13087 "stw %2,%1"
13088 [(set_attr "type" "store")])
13089
13090 (define_insn "*stmw"
13091 [(match_parallel 0 "stmw_operation"
13092 [(set (match_operand:SI 1 "memory_operand" "=m")
13093 (match_operand:SI 2 "gpc_reg_operand" "r"))])]
13094 "TARGET_MULTIPLE"
13095 "stmw %2,%1"
13096 [(set_attr "type" "store")
13097 (set_attr "update" "yes")
13098 (set_attr "indexed" "yes")])
13099
13100 ; The following comment applies to:
13101 ; save_gpregs_*
13102 ; save_fpregs_*
13103 ; restore_gpregs*
13104 ; return_and_restore_gpregs*
13105 ; return_and_restore_fpregs*
13106 ; return_and_restore_fpregs_aix*
13107 ;
13108 ; The out-of-line save / restore functions expects one input argument.
13109 ; Since those are not standard call_insn's, we must avoid using
13110 ; MATCH_OPERAND for that argument. That way the register rename
13111 ; optimization will not try to rename this register.
13112 ; Each pattern is repeated for each possible register number used in
13113 ; various ABIs (r11, r1, and for some functions r12)
13114
13115 (define_insn "*save_gpregs_<mode>_r11"
13116 [(match_parallel 0 "any_parallel_operand"
13117 [(clobber (reg:P LR_REGNO))
13118 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13119 (use (reg:P 11))
13120 (set (match_operand:P 2 "memory_operand" "=m")
13121 (match_operand:P 3 "gpc_reg_operand" "r"))])]
13122 ""
13123 "bl %1"
13124 [(set_attr "type" "branch")])
13125
13126 (define_insn "*save_gpregs_<mode>_r12"
13127 [(match_parallel 0 "any_parallel_operand"
13128 [(clobber (reg:P LR_REGNO))
13129 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13130 (use (reg:P 12))
13131 (set (match_operand:P 2 "memory_operand" "=m")
13132 (match_operand:P 3 "gpc_reg_operand" "r"))])]
13133 ""
13134 "bl %1"
13135 [(set_attr "type" "branch")])
13136
13137 (define_insn "*save_gpregs_<mode>_r1"
13138 [(match_parallel 0 "any_parallel_operand"
13139 [(clobber (reg:P LR_REGNO))
13140 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13141 (use (reg:P 1))
13142 (set (match_operand:P 2 "memory_operand" "=m")
13143 (match_operand:P 3 "gpc_reg_operand" "r"))])]
13144 ""
13145 "bl %1"
13146 [(set_attr "type" "branch")])
13147
13148 (define_insn "*save_fpregs_<mode>_r11"
13149 [(match_parallel 0 "any_parallel_operand"
13150 [(clobber (reg:P LR_REGNO))
13151 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13152 (use (reg:P 11))
13153 (set (match_operand:DF 2 "memory_operand" "=m")
13154 (match_operand:DF 3 "gpc_reg_operand" "d"))])]
13155 ""
13156 "bl %1"
13157 [(set_attr "type" "branch")])
13158
13159 (define_insn "*save_fpregs_<mode>_r12"
13160 [(match_parallel 0 "any_parallel_operand"
13161 [(clobber (reg:P LR_REGNO))
13162 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13163 (use (reg:P 12))
13164 (set (match_operand:DF 2 "memory_operand" "=m")
13165 (match_operand:DF 3 "gpc_reg_operand" "d"))])]
13166 ""
13167 "bl %1"
13168 [(set_attr "type" "branch")])
13169
13170 (define_insn "*save_fpregs_<mode>_r1"
13171 [(match_parallel 0 "any_parallel_operand"
13172 [(clobber (reg:P LR_REGNO))
13173 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13174 (use (reg:P 1))
13175 (set (match_operand:DF 2 "memory_operand" "=m")
13176 (match_operand:DF 3 "gpc_reg_operand" "d"))])]
13177 ""
13178 "bl %1"
13179 [(set_attr "type" "branch")])
13180
13181 ; This is to explain that changes to the stack pointer should
13182 ; not be moved over loads from or stores to stack memory.
13183 (define_insn "stack_tie"
13184 [(match_parallel 0 "tie_operand"
13185 [(set (mem:BLK (reg 1)) (const_int 0))])]
13186 ""
13187 ""
13188 [(set_attr "length" "0")])
13189
13190 ; Some 32-bit ABIs do not have a red zone, so the stack deallocation has to
13191 ; stay behind all restores from the stack, it cannot be reordered to before
13192 ; one. See PR77687. This insn is an add or mr, and a memory clobber.
13193 (define_insn "stack_restore_tie"
13194 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
13195 (plus:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
13196 (match_operand:SI 2 "reg_or_cint_operand" "O,rI")))
13197 (set (mem:BLK (scratch)) (const_int 0))]
13198 "TARGET_32BIT"
13199 "@
13200 mr %0,%1
13201 add%I2 %0,%1,%2"
13202 [(set_attr "type" "*,add")])
13203
13204 (define_expand "epilogue"
13205 [(use (const_int 0))]
13206 ""
13207 {
13208 if (!TARGET_SCHED_PROLOG)
13209 emit_insn (gen_blockage ());
13210 rs6000_emit_epilogue (EPILOGUE_TYPE_NORMAL);
13211 DONE;
13212 })
13213
13214 ; On some processors, doing the mtcrf one CC register at a time is
13215 ; faster (like on the 604e). On others, doing them all at once is
13216 ; faster; for instance, on the 601 and 750.
13217
13218 (define_expand "movsi_to_cr_one"
13219 [(set (match_operand:CC 0 "cc_reg_operand")
13220 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand")
13221 (match_dup 2)] UNSPEC_MOVESI_TO_CR))]
13222 ""
13223 "operands[2] = GEN_INT (1 << (7 - (REGNO (operands[0]) - CR0_REGNO)));")
13224
13225 (define_insn "*movsi_to_cr"
13226 [(match_parallel 0 "mtcrf_operation"
13227 [(set (match_operand:CC 1 "cc_reg_operand" "=y")
13228 (unspec:CC [(match_operand:SI 2 "gpc_reg_operand" "r")
13229 (match_operand 3 "immediate_operand" "n")]
13230 UNSPEC_MOVESI_TO_CR))])]
13231 ""
13232 {
13233 int mask = 0;
13234 int i;
13235 for (i = 0; i < XVECLEN (operands[0], 0); i++)
13236 mask |= INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
13237 operands[4] = GEN_INT (mask);
13238 return "mtcrf %4,%2";
13239 }
13240 [(set_attr "type" "mtcr")])
13241
13242 (define_insn "*mtcrfsi"
13243 [(set (match_operand:CC 0 "cc_reg_operand" "=y")
13244 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
13245 (match_operand 2 "immediate_operand" "n")]
13246 UNSPEC_MOVESI_TO_CR))]
13247 "REG_P (operands[0])
13248 && CR_REGNO_P (REGNO (operands[0]))
13249 && CONST_INT_P (operands[2])
13250 && INTVAL (operands[2]) == 1 << (7 - (REGNO (operands[0]) - CR0_REGNO))"
13251 "mtcrf %R0,%1"
13252 [(set_attr "type" "mtcr")])
13253
13254 ; The load-multiple instructions have similar properties.
13255 ; Note that "load_multiple" is a name known to the machine-independent
13256 ; code that actually corresponds to the PowerPC load-string.
13257
13258 (define_insn "*lmw"
13259 [(match_parallel 0 "lmw_operation"
13260 [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
13261 (match_operand:SI 2 "memory_operand" "m"))])]
13262 "TARGET_MULTIPLE"
13263 "lmw %1,%2"
13264 [(set_attr "type" "load")
13265 (set_attr "update" "yes")
13266 (set_attr "indexed" "yes")
13267 (set_attr "cell_micro" "always")])
13268
13269 ; FIXME: "any_parallel_operand" is a bit flexible...
13270
13271 ; The following comment applies to:
13272 ; save_gpregs_*
13273 ; save_fpregs_*
13274 ; restore_gpregs*
13275 ; return_and_restore_gpregs*
13276 ; return_and_restore_fpregs*
13277 ; return_and_restore_fpregs_aix*
13278 ;
13279 ; The out-of-line save / restore functions expects one input argument.
13280 ; Since those are not standard call_insn's, we must avoid using
13281 ; MATCH_OPERAND for that argument. That way the register rename
13282 ; optimization will not try to rename this register.
13283 ; Each pattern is repeated for each possible register number used in
13284 ; various ABIs (r11, r1, and for some functions r12)
13285
13286 (define_insn "*restore_gpregs_<mode>_r11"
13287 [(match_parallel 0 "any_parallel_operand"
13288 [(clobber (reg:P LR_REGNO))
13289 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13290 (use (reg:P 11))
13291 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13292 (match_operand:P 3 "memory_operand" "m"))])]
13293 ""
13294 "bl %1"
13295 [(set_attr "type" "branch")])
13296
13297 (define_insn "*restore_gpregs_<mode>_r12"
13298 [(match_parallel 0 "any_parallel_operand"
13299 [(clobber (reg:P LR_REGNO))
13300 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13301 (use (reg:P 12))
13302 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13303 (match_operand:P 3 "memory_operand" "m"))])]
13304 ""
13305 "bl %1"
13306 [(set_attr "type" "branch")])
13307
13308 (define_insn "*restore_gpregs_<mode>_r1"
13309 [(match_parallel 0 "any_parallel_operand"
13310 [(clobber (reg:P LR_REGNO))
13311 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13312 (use (reg:P 1))
13313 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13314 (match_operand:P 3 "memory_operand" "m"))])]
13315 ""
13316 "bl %1"
13317 [(set_attr "type" "branch")])
13318
13319 (define_insn "*return_and_restore_gpregs_<mode>_r11"
13320 [(match_parallel 0 "any_parallel_operand"
13321 [(return)
13322 (clobber (reg:P LR_REGNO))
13323 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13324 (use (reg:P 11))
13325 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13326 (match_operand:P 3 "memory_operand" "m"))])]
13327 ""
13328 "b %1"
13329 [(set_attr "type" "branch")])
13330
13331 (define_insn "*return_and_restore_gpregs_<mode>_r12"
13332 [(match_parallel 0 "any_parallel_operand"
13333 [(return)
13334 (clobber (reg:P LR_REGNO))
13335 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13336 (use (reg:P 12))
13337 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13338 (match_operand:P 3 "memory_operand" "m"))])]
13339 ""
13340 "b %1"
13341 [(set_attr "type" "branch")])
13342
13343 (define_insn "*return_and_restore_gpregs_<mode>_r1"
13344 [(match_parallel 0 "any_parallel_operand"
13345 [(return)
13346 (clobber (reg:P LR_REGNO))
13347 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13348 (use (reg:P 1))
13349 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13350 (match_operand:P 3 "memory_operand" "m"))])]
13351 ""
13352 "b %1"
13353 [(set_attr "type" "branch")])
13354
13355 (define_insn "*return_and_restore_fpregs_<mode>_r11"
13356 [(match_parallel 0 "any_parallel_operand"
13357 [(return)
13358 (clobber (reg:P LR_REGNO))
13359 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13360 (use (reg:P 11))
13361 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13362 (match_operand:DF 3 "memory_operand" "m"))])]
13363 ""
13364 "b %1"
13365 [(set_attr "type" "branch")])
13366
13367 (define_insn "*return_and_restore_fpregs_<mode>_r12"
13368 [(match_parallel 0 "any_parallel_operand"
13369 [(return)
13370 (clobber (reg:P LR_REGNO))
13371 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13372 (use (reg:P 12))
13373 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13374 (match_operand:DF 3 "memory_operand" "m"))])]
13375 ""
13376 "b %1"
13377 [(set_attr "type" "branch")])
13378
13379 (define_insn "*return_and_restore_fpregs_<mode>_r1"
13380 [(match_parallel 0 "any_parallel_operand"
13381 [(return)
13382 (clobber (reg:P LR_REGNO))
13383 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13384 (use (reg:P 1))
13385 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13386 (match_operand:DF 3 "memory_operand" "m"))])]
13387 ""
13388 "b %1"
13389 [(set_attr "type" "branch")])
13390
13391 (define_insn "*return_and_restore_fpregs_aix_<mode>_r11"
13392 [(match_parallel 0 "any_parallel_operand"
13393 [(return)
13394 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13395 (use (reg:P 11))
13396 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13397 (match_operand:DF 3 "memory_operand" "m"))])]
13398 ""
13399 "b %1"
13400 [(set_attr "type" "branch")])
13401
13402 (define_insn "*return_and_restore_fpregs_aix_<mode>_r1"
13403 [(match_parallel 0 "any_parallel_operand"
13404 [(return)
13405 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13406 (use (reg:P 1))
13407 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13408 (match_operand:DF 3 "memory_operand" "m"))])]
13409 ""
13410 "b %1"
13411 [(set_attr "type" "branch")])
13412
13413 ; This is used in compiling the unwind routines.
13414 (define_expand "eh_return"
13415 [(use (match_operand 0 "general_operand"))]
13416 ""
13417 {
13418 emit_insn (gen_eh_set_lr (Pmode, operands[0]));
13419 DONE;
13420 })
13421
13422 ; We can't expand this before we know where the link register is stored.
13423 (define_insn_and_split "@eh_set_lr_<mode>"
13424 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")] UNSPECV_EH_RR)
13425 (clobber (match_scratch:P 1 "=&b"))]
13426 ""
13427 "#"
13428 "reload_completed"
13429 [(const_int 0)]
13430 {
13431 rs6000_emit_eh_reg_restore (operands[0], operands[1]);
13432 DONE;
13433 })
13434
13435 (define_insn "prefetch"
13436 [(prefetch (match_operand 0 "indexed_or_indirect_address" "a")
13437 (match_operand:SI 1 "const_int_operand" "n")
13438 (match_operand:SI 2 "const_int_operand" "n"))]
13439 ""
13440 {
13441
13442
13443 /* dcbtstt, dcbtt and TH=0b10000 support starts with ISA 2.06 (Power7).
13444 AIX does not support the dcbtstt and dcbtt extended mnemonics.
13445 The AIX assembler does not support the three operand form of dcbt
13446 and dcbtst on Power 7 (-mpwr7). */
13447 int inst_select = INTVAL (operands[2]) || !TARGET_DIRECT_MOVE;
13448
13449 if (REG_P (operands[0]))
13450 {
13451 if (INTVAL (operands[1]) == 0)
13452 return inst_select ? "dcbt 0,%0" : "dcbt 0,%0,16";
13453 else
13454 return inst_select ? "dcbtst 0,%0" : "dcbtst 0,%0,16";
13455 }
13456 else
13457 {
13458 if (INTVAL (operands[1]) == 0)
13459 return inst_select ? "dcbt %a0" : "dcbt %a0,16";
13460 else
13461 return inst_select ? "dcbtst %a0" : "dcbtst %a0,16";
13462 }
13463 }
13464 [(set_attr "type" "load")])
13465 \f
13466 ;; Handle -fsplit-stack.
13467
13468 (define_expand "split_stack_prologue"
13469 [(const_int 0)]
13470 ""
13471 {
13472 rs6000_expand_split_stack_prologue ();
13473 DONE;
13474 })
13475
13476 (define_expand "load_split_stack_limit"
13477 [(set (match_operand 0)
13478 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))]
13479 ""
13480 {
13481 emit_insn (gen_rtx_SET (operands[0],
13482 gen_rtx_UNSPEC (Pmode,
13483 gen_rtvec (1, const0_rtx),
13484 UNSPEC_STACK_CHECK)));
13485 DONE;
13486 })
13487
13488 (define_insn "load_split_stack_limit_di"
13489 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
13490 (unspec:DI [(const_int 0)] UNSPEC_STACK_CHECK))]
13491 "TARGET_64BIT"
13492 "ld %0,-0x7040(13)"
13493 [(set_attr "type" "load")
13494 (set_attr "update" "no")
13495 (set_attr "indexed" "no")])
13496
13497 (define_insn "load_split_stack_limit_si"
13498 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
13499 (unspec:SI [(const_int 0)] UNSPEC_STACK_CHECK))]
13500 "!TARGET_64BIT"
13501 "lwz %0,-0x7020(2)"
13502 [(set_attr "type" "load")
13503 (set_attr "update" "no")
13504 (set_attr "indexed" "no")])
13505
13506 ;; A return instruction which the middle-end doesn't see.
13507 ;; Use r0 to stop regrename twiddling with lr restore insns emitted
13508 ;; after the call to __morestack.
13509 (define_insn "split_stack_return"
13510 [(unspec_volatile [(reg:SI 0) (reg:SI LR_REGNO)] UNSPECV_SPLIT_STACK_RETURN)]
13511 ""
13512 "blr"
13513 [(set_attr "type" "jmpreg")])
13514
13515 ;; If there are operand 0 bytes available on the stack, jump to
13516 ;; operand 1.
13517 (define_expand "split_stack_space_check"
13518 [(set (match_dup 2)
13519 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
13520 (set (match_dup 3)
13521 (minus (reg STACK_POINTER_REGNUM)
13522 (match_operand 0)))
13523 (set (match_dup 4) (compare:CCUNS (match_dup 3) (match_dup 2)))
13524 (set (pc) (if_then_else
13525 (geu (match_dup 4) (const_int 0))
13526 (label_ref (match_operand 1))
13527 (pc)))]
13528 ""
13529 {
13530 rs6000_split_stack_space_check (operands[0], operands[1]);
13531 DONE;
13532 })
13533 \f
13534 (define_insn "bpermd_<mode>"
13535 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
13536 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "r")
13537 (match_operand:P 2 "gpc_reg_operand" "r")] UNSPEC_BPERM))]
13538 "TARGET_POPCNTD"
13539 "bpermd %0,%1,%2"
13540 [(set_attr "type" "popcnt")])
13541
13542 \f
13543 ;; Builtin fma support. Handle
13544 ;; Note that the conditions for expansion are in the FMA_F iterator.
13545
13546 (define_expand "fma<mode>4"
13547 [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13548 (fma:FMA_F
13549 (match_operand:FMA_F 1 "gpc_reg_operand")
13550 (match_operand:FMA_F 2 "gpc_reg_operand")
13551 (match_operand:FMA_F 3 "gpc_reg_operand")))]
13552 ""
13553 "")
13554
13555 (define_insn "*fma<mode>4_fpr"
13556 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa,wa")
13557 (fma:SFDF
13558 (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,wa,wa")
13559 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa,0")
13560 (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,wa")))]
13561 "TARGET_HARD_FLOAT"
13562 "@
13563 fmadd<s> %0,%1,%2,%3
13564 xsmadda<sd>p %x0,%x1,%x2
13565 xsmaddm<sd>p %x0,%x1,%x3"
13566 [(set_attr "type" "fp")
13567 (set_attr "isa" "*,<Fisa>,<Fisa>")])
13568
13569 ; Altivec only has fma and nfms.
13570 (define_expand "fms<mode>4"
13571 [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13572 (fma:FMA_F
13573 (match_operand:FMA_F 1 "gpc_reg_operand")
13574 (match_operand:FMA_F 2 "gpc_reg_operand")
13575 (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand"))))]
13576 "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13577 "")
13578
13579 (define_insn "*fms<mode>4_fpr"
13580 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa,wa")
13581 (fma:SFDF
13582 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa,wa")
13583 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa,0")
13584 (neg:SFDF (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,wa"))))]
13585 "TARGET_HARD_FLOAT"
13586 "@
13587 fmsub<s> %0,%1,%2,%3
13588 xsmsuba<sd>p %x0,%x1,%x2
13589 xsmsubm<sd>p %x0,%x1,%x3"
13590 [(set_attr "type" "fp")
13591 (set_attr "isa" "*,<Fisa>,<Fisa>")])
13592
13593 ;; If signed zeros are ignored, -(a * b - c) = -a * b + c.
13594 (define_expand "fnma<mode>4"
13595 [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13596 (neg:FMA_F
13597 (fma:FMA_F
13598 (match_operand:FMA_F 1 "gpc_reg_operand")
13599 (match_operand:FMA_F 2 "gpc_reg_operand")
13600 (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand")))))]
13601 "!HONOR_SIGNED_ZEROS (<MODE>mode)"
13602 "")
13603
13604 ;; If signed zeros are ignored, -(a * b + c) = -a * b - c.
13605 (define_expand "fnms<mode>4"
13606 [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13607 (neg:FMA_F
13608 (fma:FMA_F
13609 (match_operand:FMA_F 1 "gpc_reg_operand")
13610 (match_operand:FMA_F 2 "gpc_reg_operand")
13611 (match_operand:FMA_F 3 "gpc_reg_operand"))))]
13612 "!HONOR_SIGNED_ZEROS (<MODE>mode) && !VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13613 "")
13614
13615 ; Not an official optab name, but used from builtins.
13616 (define_expand "nfma<mode>4"
13617 [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13618 (neg:FMA_F
13619 (fma:FMA_F
13620 (match_operand:FMA_F 1 "gpc_reg_operand")
13621 (match_operand:FMA_F 2 "gpc_reg_operand")
13622 (match_operand:FMA_F 3 "gpc_reg_operand"))))]
13623 "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13624 "")
13625
13626 (define_insn "*nfma<mode>4_fpr"
13627 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa,wa")
13628 (neg:SFDF
13629 (fma:SFDF
13630 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa,wa")
13631 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa,0")
13632 (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,wa"))))]
13633 "TARGET_HARD_FLOAT"
13634 "@
13635 fnmadd<s> %0,%1,%2,%3
13636 xsnmadda<sd>p %x0,%x1,%x2
13637 xsnmaddm<sd>p %x0,%x1,%x3"
13638 [(set_attr "type" "fp")
13639 (set_attr "isa" "*,<Fisa>,<Fisa>")])
13640
13641 ; Not an official optab name, but used from builtins.
13642 (define_expand "nfms<mode>4"
13643 [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13644 (neg:FMA_F
13645 (fma:FMA_F
13646 (match_operand:FMA_F 1 "gpc_reg_operand")
13647 (match_operand:FMA_F 2 "gpc_reg_operand")
13648 (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand")))))]
13649 ""
13650 "")
13651
13652 (define_insn "*nfmssf4_fpr"
13653 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa,wa")
13654 (neg:SFDF
13655 (fma:SFDF
13656 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa,wa")
13657 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa,0")
13658 (neg:SFDF
13659 (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,wa")))))]
13660 "TARGET_HARD_FLOAT"
13661 "@
13662 fnmsub<s> %0,%1,%2,%3
13663 xsnmsuba<sd>p %x0,%x1,%x2
13664 xsnmsubm<sd>p %x0,%x1,%x3"
13665 [(set_attr "type" "fp")
13666 (set_attr "isa" "*,<Fisa>,<Fisa>")])
13667 \f
13668 (define_expand "rs6000_get_timebase"
13669 [(use (match_operand:DI 0 "gpc_reg_operand"))]
13670 ""
13671 {
13672 if (TARGET_POWERPC64)
13673 emit_insn (gen_rs6000_mftb_di (operands[0]));
13674 else
13675 emit_insn (gen_rs6000_get_timebase_ppc32 (operands[0]));
13676 DONE;
13677 })
13678
13679 (define_insn "rs6000_get_timebase_ppc32"
13680 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
13681 (unspec_volatile:DI [(const_int 0)] UNSPECV_MFTB))
13682 (clobber (match_scratch:SI 1 "=r"))
13683 (clobber (match_scratch:CC 2 "=y"))]
13684 "!TARGET_POWERPC64"
13685 {
13686 if (WORDS_BIG_ENDIAN)
13687 if (TARGET_MFCRF)
13688 {
13689 return "mfspr %0,269\;"
13690 "mfspr %L0,268\;"
13691 "mfspr %1,269\;"
13692 "cmpw %2,%0,%1\;"
13693 "bne- %2,$-16";
13694 }
13695 else
13696 {
13697 return "mftbu %0\;"
13698 "mftb %L0\;"
13699 "mftbu %1\;"
13700 "cmpw %2,%0,%1\;"
13701 "bne- %2,$-16";
13702 }
13703 else
13704 if (TARGET_MFCRF)
13705 {
13706 return "mfspr %L0,269\;"
13707 "mfspr %0,268\;"
13708 "mfspr %1,269\;"
13709 "cmpw %2,%L0,%1\;"
13710 "bne- %2,$-16";
13711 }
13712 else
13713 {
13714 return "mftbu %L0\;"
13715 "mftb %0\;"
13716 "mftbu %1\;"
13717 "cmpw %2,%L0,%1\;"
13718 "bne- %2,$-16";
13719 }
13720 }
13721 [(set_attr "length" "20")])
13722
13723 (define_insn "rs6000_mftb_<mode>"
13724 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
13725 (unspec_volatile:GPR [(const_int 0)] UNSPECV_MFTB))]
13726 ""
13727 {
13728 if (TARGET_MFCRF)
13729 return "mfspr %0,268";
13730 else
13731 return "mftb %0";
13732 })
13733
13734 \f
13735 ;; The ISA 3.0 mffsl instruction is a lower latency instruction
13736 ;; for reading bits [29:31], [45:51] and [56:63] of the FPSCR.
13737 (define_insn "rs6000_mffsl_hw"
13738 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
13739 (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFSL))]
13740 "TARGET_HARD_FLOAT"
13741 "mffsl %0")
13742
13743 (define_expand "rs6000_mffsl"
13744 [(set (match_operand:DF 0 "gpc_reg_operand")
13745 (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFSL))]
13746 "TARGET_HARD_FLOAT"
13747 {
13748 /* If the low latency mffsl instruction (ISA 3.0) is available use it,
13749 otherwise fall back to the older mffs instruction to emulate the mffsl
13750 instruction. */
13751
13752 if (!TARGET_P9_MISC)
13753 {
13754 rtx tmp1 = gen_reg_rtx (DFmode);
13755
13756 /* The mffs instruction reads the entire FPSCR. Emulate the mffsl
13757 instruction using the mffs instruction and masking the result. */
13758 emit_insn (gen_rs6000_mffs (tmp1));
13759
13760 rtx tmp1di = simplify_gen_subreg (DImode, tmp1, DFmode, 0);
13761 rtx tmp2 = gen_reg_rtx (DImode);
13762 emit_insn (gen_anddi3 (tmp2, tmp1di, GEN_INT (0x70007f0ffLL)));
13763
13764 rtx tmp2df = simplify_gen_subreg (DFmode, tmp2, DImode, 0);
13765 emit_move_insn (operands[0], tmp2df);
13766 DONE;
13767 }
13768
13769 emit_insn (gen_rs6000_mffsl_hw (operands[0]));
13770 DONE;
13771 })
13772
13773 (define_insn "rs6000_mffs"
13774 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
13775 (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFS))]
13776 "TARGET_HARD_FLOAT"
13777 "mffs %0")
13778
13779 (define_insn "rs6000_mtfsf"
13780 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "i")
13781 (match_operand:DF 1 "gpc_reg_operand" "d")]
13782 UNSPECV_MTFSF)]
13783 "TARGET_HARD_FLOAT"
13784 "mtfsf %0,%1")
13785
13786 (define_insn "rs6000_mtfsf_hi"
13787 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "n")
13788 (match_operand:DF 1 "gpc_reg_operand" "d")]
13789 UNSPECV_MTFSF_HI)]
13790 "TARGET_HARD_FLOAT"
13791 "mtfsf %0,%1,0,1")
13792
13793 \f
13794 ;; Power8 fusion support for fusing an addis instruction with a D-form load of
13795 ;; a GPR. The addis instruction must be adjacent to the load, and use the same
13796 ;; register that is being loaded. The fused ops must be physically adjacent.
13797
13798 ;; On Power8 GPR loads, we try to use the register that is being load. The
13799 ;; peephole2 then gathers any other fused possibilities that it can find after
13800 ;; register allocation. If power9 fusion is selected, we also fuse floating
13801 ;; point loads/stores.
13802
13803 ;; Find cases where the addis that feeds into a load instruction is either used
13804 ;; once or is the same as the target register, and replace it with the fusion
13805 ;; insn
13806
13807 (define_peephole2
13808 [(set (match_operand:P 0 "base_reg_operand")
13809 (match_operand:P 1 "fusion_gpr_addis"))
13810 (set (match_operand:INT1 2 "base_reg_operand")
13811 (match_operand:INT1 3 "fusion_gpr_mem_load"))]
13812 "TARGET_P8_FUSION
13813 && fusion_gpr_load_p (operands[0], operands[1], operands[2],
13814 operands[3])"
13815 [(const_int 0)]
13816 {
13817 expand_fusion_gpr_load (operands);
13818 DONE;
13819 })
13820
13821 ;; Fusion insn, created by the define_peephole2 above (and eventually by
13822 ;; reload)
13823
13824 (define_insn "*fusion_gpr_load_<mode>"
13825 [(set (match_operand:INT1 0 "base_reg_operand" "=b")
13826 (unspec:INT1 [(match_operand:INT1 1 "fusion_addis_mem_combo_load" "wF")]
13827 UNSPEC_FUSION_GPR))]
13828 "TARGET_P8_FUSION"
13829 {
13830 return emit_fusion_gpr_load (operands[0], operands[1]);
13831 }
13832 [(set_attr "type" "load")
13833 (set_attr "length" "8")])
13834
13835 \f
13836 ;; Optimize cases where we want to do a D-form load (register+offset) on
13837 ;; ISA 2.06/2.07 to an Altivec register, and the register allocator
13838 ;; has generated:
13839 ;; LFD 0,32(3)
13840 ;; XXLOR 32,0,0
13841 ;;
13842 ;; and we change this to:
13843 ;; LI 0,32
13844 ;; LXSDX 32,3,9
13845
13846 (define_peephole2
13847 [(match_scratch:P 0 "b")
13848 (set (match_operand:ALTIVEC_DFORM 1 "fpr_reg_operand")
13849 (match_operand:ALTIVEC_DFORM 2 "simple_offsettable_mem_operand"))
13850 (set (match_operand:ALTIVEC_DFORM 3 "altivec_register_operand")
13851 (match_dup 1))]
13852 "TARGET_VSX && !TARGET_P9_VECTOR && peep2_reg_dead_p (2, operands[1])"
13853 [(set (match_dup 0)
13854 (match_dup 4))
13855 (set (match_dup 3)
13856 (match_dup 5))]
13857 {
13858 rtx tmp_reg = operands[0];
13859 rtx mem = operands[2];
13860 rtx addr = XEXP (mem, 0);
13861 rtx add_op0, add_op1, new_addr;
13862
13863 gcc_assert (GET_CODE (addr) == PLUS || GET_CODE (addr) == LO_SUM);
13864 add_op0 = XEXP (addr, 0);
13865 add_op1 = XEXP (addr, 1);
13866 gcc_assert (REG_P (add_op0));
13867 new_addr = gen_rtx_PLUS (Pmode, add_op0, tmp_reg);
13868
13869 operands[4] = add_op1;
13870 operands[5] = change_address (mem, <ALTIVEC_DFORM:MODE>mode, new_addr);
13871 })
13872
13873 ;; Optimize cases were want to do a D-form store on ISA 2.06/2.07 from an
13874 ;; Altivec register, and the register allocator has generated:
13875 ;; XXLOR 0,32,32
13876 ;; STFD 0,32(3)
13877 ;;
13878 ;; and we change this to:
13879 ;; LI 0,32
13880 ;; STXSDX 32,3,9
13881
13882 (define_peephole2
13883 [(match_scratch:P 0 "b")
13884 (set (match_operand:ALTIVEC_DFORM 1 "fpr_reg_operand")
13885 (match_operand:ALTIVEC_DFORM 2 "altivec_register_operand"))
13886 (set (match_operand:ALTIVEC_DFORM 3 "simple_offsettable_mem_operand")
13887 (match_dup 1))]
13888 "TARGET_VSX && !TARGET_P9_VECTOR && peep2_reg_dead_p (2, operands[1])"
13889 [(set (match_dup 0)
13890 (match_dup 4))
13891 (set (match_dup 5)
13892 (match_dup 2))]
13893 {
13894 rtx tmp_reg = operands[0];
13895 rtx mem = operands[3];
13896 rtx addr = XEXP (mem, 0);
13897 rtx add_op0, add_op1, new_addr;
13898
13899 gcc_assert (GET_CODE (addr) == PLUS || GET_CODE (addr) == LO_SUM);
13900 add_op0 = XEXP (addr, 0);
13901 add_op1 = XEXP (addr, 1);
13902 gcc_assert (REG_P (add_op0));
13903 new_addr = gen_rtx_PLUS (Pmode, add_op0, tmp_reg);
13904
13905 operands[4] = add_op1;
13906 operands[5] = change_address (mem, <ALTIVEC_DFORM:MODE>mode, new_addr);
13907 })
13908
13909 \f
13910 ;; Miscellaneous ISA 2.06 (power7) instructions
13911 (define_insn "addg6s"
13912 [(set (match_operand:SI 0 "register_operand" "=r")
13913 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
13914 (match_operand:SI 2 "register_operand" "r")]
13915 UNSPEC_ADDG6S))]
13916 "TARGET_POPCNTD"
13917 "addg6s %0,%1,%2"
13918 [(set_attr "type" "integer")])
13919
13920 (define_insn "cdtbcd"
13921 [(set (match_operand:SI 0 "register_operand" "=r")
13922 (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
13923 UNSPEC_CDTBCD))]
13924 "TARGET_POPCNTD"
13925 "cdtbcd %0,%1"
13926 [(set_attr "type" "integer")])
13927
13928 (define_insn "cbcdtd"
13929 [(set (match_operand:SI 0 "register_operand" "=r")
13930 (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
13931 UNSPEC_CBCDTD))]
13932 "TARGET_POPCNTD"
13933 "cbcdtd %0,%1"
13934 [(set_attr "type" "integer")])
13935
13936 (define_int_iterator UNSPEC_DIV_EXTEND [UNSPEC_DIVE
13937 UNSPEC_DIVEU])
13938
13939 (define_int_attr div_extend [(UNSPEC_DIVE "e")
13940 (UNSPEC_DIVEU "eu")])
13941
13942 (define_insn "div<div_extend>_<mode>"
13943 [(set (match_operand:GPR 0 "register_operand" "=r")
13944 (unspec:GPR [(match_operand:GPR 1 "register_operand" "r")
13945 (match_operand:GPR 2 "register_operand" "r")]
13946 UNSPEC_DIV_EXTEND))]
13947 "TARGET_POPCNTD"
13948 "div<wd><div_extend> %0,%1,%2"
13949 [(set_attr "type" "div")
13950 (set_attr "size" "<bits>")])
13951
13952 \f
13953 ;; Pack/unpack 128-bit floating point types that take 2 scalar registers
13954
13955 ; Type of the 64-bit part when packing/unpacking 128-bit floating point types
13956 (define_mode_attr FP128_64 [(TF "DF")
13957 (IF "DF")
13958 (TD "DI")
13959 (KF "DI")])
13960
13961 (define_expand "unpack<mode>"
13962 [(set (match_operand:<FP128_64> 0 "nonimmediate_operand")
13963 (unspec:<FP128_64>
13964 [(match_operand:FMOVE128 1 "register_operand")
13965 (match_operand:QI 2 "const_0_to_1_operand")]
13966 UNSPEC_UNPACK_128BIT))]
13967 "FLOAT128_2REG_P (<MODE>mode)"
13968 "")
13969
13970 (define_insn_and_split "unpack<mode>_dm"
13971 [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m,d,r,m")
13972 (unspec:<FP128_64>
13973 [(match_operand:FMOVE128 1 "register_operand" "d,d,r,d,r")
13974 (match_operand:QI 2 "const_0_to_1_operand" "i,i,i,i,i")]
13975 UNSPEC_UNPACK_128BIT))]
13976 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE && FLOAT128_2REG_P (<MODE>mode)"
13977 "#"
13978 "&& reload_completed"
13979 [(set (match_dup 0) (match_dup 3))]
13980 {
13981 unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
13982
13983 if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
13984 {
13985 emit_note (NOTE_INSN_DELETED);
13986 DONE;
13987 }
13988
13989 operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
13990 }
13991 [(set_attr "type" "fp,fpstore,mffgpr,mftgpr,store")])
13992
13993 (define_insn_and_split "unpack<mode>_nodm"
13994 [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m")
13995 (unspec:<FP128_64>
13996 [(match_operand:FMOVE128 1 "register_operand" "d,d")
13997 (match_operand:QI 2 "const_0_to_1_operand" "i,i")]
13998 UNSPEC_UNPACK_128BIT))]
13999 "(!TARGET_POWERPC64 || !TARGET_DIRECT_MOVE) && FLOAT128_2REG_P (<MODE>mode)"
14000 "#"
14001 "&& reload_completed"
14002 [(set (match_dup 0) (match_dup 3))]
14003 {
14004 unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
14005
14006 if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
14007 {
14008 emit_note (NOTE_INSN_DELETED);
14009 DONE;
14010 }
14011
14012 operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
14013 }
14014 [(set_attr "type" "fp,fpstore")])
14015
14016 (define_insn_and_split "pack<mode>"
14017 [(set (match_operand:FMOVE128 0 "register_operand" "=&d")
14018 (unspec:FMOVE128
14019 [(match_operand:<FP128_64> 1 "register_operand" "d")
14020 (match_operand:<FP128_64> 2 "register_operand" "d")]
14021 UNSPEC_PACK_128BIT))]
14022 "FLOAT128_2REG_P (<MODE>mode)"
14023 "#"
14024 "&& reload_completed"
14025 [(set (match_dup 3) (match_dup 1))
14026 (set (match_dup 4) (match_dup 2))]
14027 {
14028 unsigned dest_hi = REGNO (operands[0]);
14029 unsigned dest_lo = dest_hi + 1;
14030
14031 gcc_assert (!IN_RANGE (REGNO (operands[1]), dest_hi, dest_lo));
14032 gcc_assert (!IN_RANGE (REGNO (operands[2]), dest_hi, dest_lo));
14033
14034 operands[3] = gen_rtx_REG (<FP128_64>mode, dest_hi);
14035 operands[4] = gen_rtx_REG (<FP128_64>mode, dest_lo);
14036 }
14037 [(set_attr "type" "fp")
14038 (set_attr "length" "8")])
14039
14040 (define_insn "unpack<mode>"
14041 [(set (match_operand:DI 0 "register_operand" "=wa,wa")
14042 (unspec:DI [(match_operand:FMOVE128_VSX 1 "register_operand" "0,wa")
14043 (match_operand:QI 2 "const_0_to_1_operand" "O,i")]
14044 UNSPEC_UNPACK_128BIT))]
14045 "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)"
14046 {
14047 if (REGNO (operands[0]) == REGNO (operands[1]) && INTVAL (operands[2]) == 0)
14048 return ASM_COMMENT_START " xxpermdi to same register";
14049
14050 operands[3] = GEN_INT (INTVAL (operands[2]) == 0 ? 0 : 3);
14051 return "xxpermdi %x0,%x1,%x1,%3";
14052 }
14053 [(set_attr "type" "vecperm")])
14054
14055 (define_insn "pack<mode>"
14056 [(set (match_operand:FMOVE128_VSX 0 "register_operand" "=wa")
14057 (unspec:FMOVE128_VSX
14058 [(match_operand:DI 1 "register_operand" "wa")
14059 (match_operand:DI 2 "register_operand" "wa")]
14060 UNSPEC_PACK_128BIT))]
14061 "TARGET_VSX"
14062 "xxpermdi %x0,%x1,%x2,0"
14063 [(set_attr "type" "vecperm")])
14064
14065
14066 \f
14067 ;; ISA 2.08 IEEE 128-bit floating point support.
14068
14069 (define_insn "add<mode>3"
14070 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14071 (plus:IEEE128
14072 (match_operand:IEEE128 1 "altivec_register_operand" "v")
14073 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14074 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14075 "xsaddqp %0,%1,%2"
14076 [(set_attr "type" "vecfloat")
14077 (set_attr "size" "128")])
14078
14079 (define_insn "sub<mode>3"
14080 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14081 (minus:IEEE128
14082 (match_operand:IEEE128 1 "altivec_register_operand" "v")
14083 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14084 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14085 "xssubqp %0,%1,%2"
14086 [(set_attr "type" "vecfloat")
14087 (set_attr "size" "128")])
14088
14089 (define_insn "mul<mode>3"
14090 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14091 (mult:IEEE128
14092 (match_operand:IEEE128 1 "altivec_register_operand" "v")
14093 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14094 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14095 "xsmulqp %0,%1,%2"
14096 [(set_attr "type" "qmul")
14097 (set_attr "size" "128")])
14098
14099 (define_insn "div<mode>3"
14100 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14101 (div:IEEE128
14102 (match_operand:IEEE128 1 "altivec_register_operand" "v")
14103 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14104 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14105 "xsdivqp %0,%1,%2"
14106 [(set_attr "type" "vecdiv")
14107 (set_attr "size" "128")])
14108
14109 (define_insn "sqrt<mode>2"
14110 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14111 (sqrt:IEEE128
14112 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14113 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14114 "xssqrtqp %0,%1"
14115 [(set_attr "type" "vecdiv")
14116 (set_attr "size" "128")])
14117
14118 (define_expand "copysign<mode>3"
14119 [(use (match_operand:IEEE128 0 "altivec_register_operand"))
14120 (use (match_operand:IEEE128 1 "altivec_register_operand"))
14121 (use (match_operand:IEEE128 2 "altivec_register_operand"))]
14122 "FLOAT128_IEEE_P (<MODE>mode)"
14123 {
14124 if (TARGET_FLOAT128_HW)
14125 emit_insn (gen_copysign<mode>3_hard (operands[0], operands[1],
14126 operands[2]));
14127 else
14128 emit_insn (gen_copysign<mode>3_soft (operands[0], operands[1],
14129 operands[2]));
14130 DONE;
14131 })
14132
14133 (define_insn "copysign<mode>3_hard"
14134 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14135 (unspec:IEEE128
14136 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14137 (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14138 UNSPEC_COPYSIGN))]
14139 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14140 "xscpsgnqp %0,%2,%1"
14141 [(set_attr "type" "vecmove")
14142 (set_attr "size" "128")])
14143
14144 (define_insn "copysign<mode>3_soft"
14145 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14146 (unspec:IEEE128
14147 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14148 (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14149 UNSPEC_COPYSIGN))
14150 (clobber (match_scratch:IEEE128 3 "=&v"))]
14151 "!TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14152 "xscpsgndp %x3,%x2,%x1\;xxpermdi %x0,%x3,%x1,1"
14153 [(set_attr "type" "veccomplex")
14154 (set_attr "length" "8")])
14155
14156 (define_insn "@neg<mode>2_hw"
14157 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14158 (neg:IEEE128
14159 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14160 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14161 "xsnegqp %0,%1"
14162 [(set_attr "type" "vecmove")
14163 (set_attr "size" "128")])
14164
14165
14166 (define_insn "@abs<mode>2_hw"
14167 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14168 (abs:IEEE128
14169 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14170 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14171 "xsabsqp %0,%1"
14172 [(set_attr "type" "vecmove")
14173 (set_attr "size" "128")])
14174
14175
14176 (define_insn "*nabs<mode>2_hw"
14177 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14178 (neg:IEEE128
14179 (abs:IEEE128
14180 (match_operand:IEEE128 1 "altivec_register_operand" "v"))))]
14181 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14182 "xsnabsqp %0,%1"
14183 [(set_attr "type" "vecmove")
14184 (set_attr "size" "128")])
14185
14186 ;; Initially don't worry about doing fusion
14187 (define_insn "fma<mode>4_hw"
14188 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14189 (fma:IEEE128
14190 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14191 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14192 (match_operand:IEEE128 3 "altivec_register_operand" "0")))]
14193 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14194 "xsmaddqp %0,%1,%2"
14195 [(set_attr "type" "qmul")
14196 (set_attr "size" "128")])
14197
14198 (define_insn "*fms<mode>4_hw"
14199 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14200 (fma:IEEE128
14201 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14202 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14203 (neg:IEEE128
14204 (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
14205 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14206 "xsmsubqp %0,%1,%2"
14207 [(set_attr "type" "qmul")
14208 (set_attr "size" "128")])
14209
14210 (define_insn "*nfma<mode>4_hw"
14211 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14212 (neg:IEEE128
14213 (fma:IEEE128
14214 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14215 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14216 (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
14217 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14218 "xsnmaddqp %0,%1,%2"
14219 [(set_attr "type" "qmul")
14220 (set_attr "size" "128")])
14221
14222 (define_insn "*nfms<mode>4_hw"
14223 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14224 (neg:IEEE128
14225 (fma:IEEE128
14226 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14227 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14228 (neg:IEEE128
14229 (match_operand:IEEE128 3 "altivec_register_operand" "0")))))]
14230 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14231 "xsnmsubqp %0,%1,%2"
14232 [(set_attr "type" "qmul")
14233 (set_attr "size" "128")])
14234
14235 (define_insn "extend<SFDF:mode><IEEE128:mode>2_hw"
14236 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14237 (float_extend:IEEE128
14238 (match_operand:SFDF 1 "altivec_register_operand" "v")))]
14239 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14240 "xscvdpqp %0,%1"
14241 [(set_attr "type" "vecfloat")
14242 (set_attr "size" "128")])
14243
14244 ;; Conversion between KFmode and TFmode if TFmode is ieee 128-bit floating
14245 ;; point is a simple copy.
14246 (define_insn_and_split "extendkftf2"
14247 [(set (match_operand:TF 0 "vsx_register_operand" "=wa,?wa")
14248 (float_extend:TF (match_operand:KF 1 "vsx_register_operand" "0,wa")))]
14249 "TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD"
14250 "@
14251 #
14252 xxlor %x0,%x1,%x1"
14253 "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
14254 [(const_int 0)]
14255 {
14256 emit_note (NOTE_INSN_DELETED);
14257 DONE;
14258 }
14259 [(set_attr "type" "*,veclogical")
14260 (set_attr "length" "0,4")])
14261
14262 (define_insn_and_split "trunctfkf2"
14263 [(set (match_operand:KF 0 "vsx_register_operand" "=wa,?wa")
14264 (float_extend:KF (match_operand:TF 1 "vsx_register_operand" "0,wa")))]
14265 "TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD"
14266 "@
14267 #
14268 xxlor %x0,%x1,%x1"
14269 "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
14270 [(const_int 0)]
14271 {
14272 emit_note (NOTE_INSN_DELETED);
14273 DONE;
14274 }
14275 [(set_attr "type" "*,veclogical")
14276 (set_attr "length" "0,4")])
14277
14278 (define_insn "trunc<mode>df2_hw"
14279 [(set (match_operand:DF 0 "altivec_register_operand" "=v")
14280 (float_truncate:DF
14281 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14282 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14283 "xscvqpdp %0,%1"
14284 [(set_attr "type" "vecfloat")
14285 (set_attr "size" "128")])
14286
14287 ;; There is no KFmode -> SFmode instruction. Preserve the accuracy by doing
14288 ;; the KFmode -> DFmode conversion using round to odd rather than the normal
14289 ;; conversion
14290 (define_insn_and_split "trunc<mode>sf2_hw"
14291 [(set (match_operand:SF 0 "vsx_register_operand" "=wa")
14292 (float_truncate:SF
14293 (match_operand:IEEE128 1 "altivec_register_operand" "v")))
14294 (clobber (match_scratch:DF 2 "=v"))]
14295 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14296 "#"
14297 "&& 1"
14298 [(set (match_dup 2)
14299 (unspec:DF [(match_dup 1)]
14300 UNSPEC_TRUNC_ROUND_TO_ODD))
14301 (set (match_dup 0)
14302 (float_truncate:SF (match_dup 2)))]
14303 {
14304 if (GET_CODE (operands[2]) == SCRATCH)
14305 operands[2] = gen_reg_rtx (DFmode);
14306 }
14307 [(set_attr "type" "vecfloat")
14308 (set_attr "length" "8")
14309 (set_attr "isa" "p8v")])
14310
14311 ;; Conversion between IEEE 128-bit and integer types
14312
14313 ;; The fix function for DImode and SImode was declared earlier as a
14314 ;; define_expand. It calls into rs6000_expand_float128_convert if we don't
14315 ;; have IEEE 128-bit hardware support. QImode and HImode are not provided
14316 ;; unless we have the IEEE 128-bit hardware.
14317 ;;
14318 ;; Unlike the code for converting SFmode/DFmode to QImode/HImode, we don't have
14319 ;; to provide a GPR target that used direct move and a conversion in the GPR
14320 ;; which works around QImode/HImode not being allowed in vector registers in
14321 ;; ISA 2.07 (power8).
14322 (define_insn "fix<uns>_<IEEE128:mode><SDI:mode>2_hw"
14323 [(set (match_operand:SDI 0 "altivec_register_operand" "=v")
14324 (any_fix:SDI (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14325 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14326 "xscvqp<su><wd>z %0,%1"
14327 [(set_attr "type" "vecfloat")
14328 (set_attr "size" "128")])
14329
14330 (define_insn "fix<uns>_trunc<IEEE128:mode><QHI:mode>2"
14331 [(set (match_operand:QHI 0 "altivec_register_operand" "=v")
14332 (any_fix:QHI
14333 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14334 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14335 "xscvqp<su>wz %0,%1"
14336 [(set_attr "type" "vecfloat")
14337 (set_attr "size" "128")])
14338
14339 ;; Combiner patterns to prevent moving the result of converting an IEEE 128-bit
14340 ;; floating point value to 8/16/32-bit integer to GPR in order to save it.
14341 (define_insn_and_split "*fix<uns>_trunc<IEEE128:mode><QHSI:mode>2_mem"
14342 [(set (match_operand:QHSI 0 "memory_operand" "=Z")
14343 (any_fix:QHSI
14344 (match_operand:IEEE128 1 "altivec_register_operand" "v")))
14345 (clobber (match_scratch:QHSI 2 "=v"))]
14346 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14347 "#"
14348 "&& reload_completed"
14349 [(set (match_dup 2)
14350 (any_fix:QHSI (match_dup 1)))
14351 (set (match_dup 0)
14352 (match_dup 2))])
14353
14354 (define_insn "float_<mode>di2_hw"
14355 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14356 (float:IEEE128 (match_operand:DI 1 "altivec_register_operand" "v")))]
14357 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14358 "xscvsdqp %0,%1"
14359 [(set_attr "type" "vecfloat")
14360 (set_attr "size" "128")])
14361
14362 (define_insn_and_split "float_<mode>si2_hw"
14363 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14364 (float:IEEE128 (match_operand:SI 1 "nonimmediate_operand" "vrZ")))
14365 (clobber (match_scratch:DI 2 "=v"))]
14366 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14367 "#"
14368 "&& 1"
14369 [(set (match_dup 2)
14370 (sign_extend:DI (match_dup 1)))
14371 (set (match_dup 0)
14372 (float:IEEE128 (match_dup 2)))]
14373 {
14374 if (GET_CODE (operands[2]) == SCRATCH)
14375 operands[2] = gen_reg_rtx (DImode);
14376
14377 if (MEM_P (operands[1]))
14378 operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
14379 })
14380
14381 (define_insn_and_split "float<QHI:mode><IEEE128:mode>2"
14382 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v")
14383 (float:IEEE128 (match_operand:QHI 1 "nonimmediate_operand" "v,r,Z")))
14384 (clobber (match_scratch:DI 2 "=X,r,X"))]
14385 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14386 "#"
14387 "&& reload_completed"
14388 [(const_int 0)]
14389 {
14390 rtx dest = operands[0];
14391 rtx src = operands[1];
14392 rtx dest_di = gen_rtx_REG (DImode, REGNO (dest));
14393
14394 if (altivec_register_operand (src, <QHI:MODE>mode))
14395 emit_insn (gen_extend<QHI:mode>di2 (dest_di, src));
14396 else if (int_reg_operand (src, <QHI:MODE>mode))
14397 {
14398 rtx ext_di = operands[2];
14399 emit_insn (gen_extend<QHI:mode>di2 (ext_di, src));
14400 emit_move_insn (dest_di, ext_di);
14401 }
14402 else if (MEM_P (src))
14403 {
14404 rtx dest_qhi = gen_rtx_REG (<QHI:MODE>mode, REGNO (dest));
14405 emit_move_insn (dest_qhi, src);
14406 emit_insn (gen_extend<QHI:mode>di2 (dest_di, dest_qhi));
14407 }
14408 else
14409 gcc_unreachable ();
14410
14411 emit_insn (gen_float_<IEEE128:mode>di2_hw (dest, dest_di));
14412 DONE;
14413 }
14414 [(set_attr "length" "8,12,12")
14415 (set_attr "type" "vecfloat")
14416 (set_attr "size" "128")])
14417
14418 (define_insn "floatuns_<mode>di2_hw"
14419 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14420 (unsigned_float:IEEE128
14421 (match_operand:DI 1 "altivec_register_operand" "v")))]
14422 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14423 "xscvudqp %0,%1"
14424 [(set_attr "type" "vecfloat")
14425 (set_attr "size" "128")])
14426
14427 (define_insn_and_split "floatuns_<mode>si2_hw"
14428 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14429 (unsigned_float:IEEE128
14430 (match_operand:SI 1 "nonimmediate_operand" "vrZ")))
14431 (clobber (match_scratch:DI 2 "=v"))]
14432 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14433 "#"
14434 "&& 1"
14435 [(set (match_dup 2)
14436 (zero_extend:DI (match_dup 1)))
14437 (set (match_dup 0)
14438 (float:IEEE128 (match_dup 2)))]
14439 {
14440 if (GET_CODE (operands[2]) == SCRATCH)
14441 operands[2] = gen_reg_rtx (DImode);
14442
14443 if (MEM_P (operands[1]))
14444 operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
14445 })
14446
14447 (define_insn_and_split "floatuns<QHI:mode><IEEE128:mode>2"
14448 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v")
14449 (unsigned_float:IEEE128
14450 (match_operand:QHI 1 "nonimmediate_operand" "v,r,Z")))
14451 (clobber (match_scratch:DI 2 "=X,r,X"))]
14452 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14453 "#"
14454 "&& reload_completed"
14455 [(const_int 0)]
14456 {
14457 rtx dest = operands[0];
14458 rtx src = operands[1];
14459 rtx dest_di = gen_rtx_REG (DImode, REGNO (dest));
14460
14461 if (altivec_register_operand (src, <QHI:MODE>mode) || MEM_P (src))
14462 emit_insn (gen_zero_extend<QHI:mode>di2 (dest_di, src));
14463 else if (int_reg_operand (src, <QHI:MODE>mode))
14464 {
14465 rtx ext_di = operands[2];
14466 emit_insn (gen_zero_extend<QHI:mode>di2 (ext_di, src));
14467 emit_move_insn (dest_di, ext_di);
14468 }
14469 else
14470 gcc_unreachable ();
14471
14472 emit_insn (gen_floatuns_<IEEE128:mode>di2_hw (dest, dest_di));
14473 DONE;
14474 }
14475 [(set_attr "length" "8,12,8")
14476 (set_attr "type" "vecfloat")
14477 (set_attr "size" "128")])
14478
14479 ;; IEEE 128-bit round to integer built-in functions
14480 (define_insn "floor<mode>2"
14481 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14482 (unspec:IEEE128
14483 [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14484 UNSPEC_FRIM))]
14485 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14486 "xsrqpi 1,%0,%1,3"
14487 [(set_attr "type" "vecfloat")
14488 (set_attr "size" "128")])
14489
14490 (define_insn "ceil<mode>2"
14491 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14492 (unspec:IEEE128
14493 [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14494 UNSPEC_FRIP))]
14495 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14496 "xsrqpi 1,%0,%1,2"
14497 [(set_attr "type" "vecfloat")
14498 (set_attr "size" "128")])
14499
14500 (define_insn "btrunc<mode>2"
14501 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14502 (unspec:IEEE128
14503 [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14504 UNSPEC_FRIZ))]
14505 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14506 "xsrqpi 1,%0,%1,1"
14507 [(set_attr "type" "vecfloat")
14508 (set_attr "size" "128")])
14509
14510 (define_insn "round<mode>2"
14511 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14512 (unspec:IEEE128
14513 [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14514 UNSPEC_FRIN))]
14515 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14516 "xsrqpi 0,%0,%1,0"
14517 [(set_attr "type" "vecfloat")
14518 (set_attr "size" "128")])
14519
14520 ;; IEEE 128-bit instructions with round to odd semantics
14521 (define_insn "add<mode>3_odd"
14522 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14523 (unspec:IEEE128
14524 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14525 (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14526 UNSPEC_ADD_ROUND_TO_ODD))]
14527 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14528 "xsaddqpo %0,%1,%2"
14529 [(set_attr "type" "vecfloat")
14530 (set_attr "size" "128")])
14531
14532 (define_insn "sub<mode>3_odd"
14533 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14534 (unspec:IEEE128
14535 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14536 (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14537 UNSPEC_SUB_ROUND_TO_ODD))]
14538 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14539 "xssubqpo %0,%1,%2"
14540 [(set_attr "type" "vecfloat")
14541 (set_attr "size" "128")])
14542
14543 (define_insn "mul<mode>3_odd"
14544 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14545 (unspec:IEEE128
14546 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14547 (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14548 UNSPEC_MUL_ROUND_TO_ODD))]
14549 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14550 "xsmulqpo %0,%1,%2"
14551 [(set_attr "type" "qmul")
14552 (set_attr "size" "128")])
14553
14554 (define_insn "div<mode>3_odd"
14555 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14556 (unspec:IEEE128
14557 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14558 (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14559 UNSPEC_DIV_ROUND_TO_ODD))]
14560 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14561 "xsdivqpo %0,%1,%2"
14562 [(set_attr "type" "vecdiv")
14563 (set_attr "size" "128")])
14564
14565 (define_insn "sqrt<mode>2_odd"
14566 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14567 (unspec:IEEE128
14568 [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14569 UNSPEC_SQRT_ROUND_TO_ODD))]
14570 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14571 "xssqrtqpo %0,%1"
14572 [(set_attr "type" "vecdiv")
14573 (set_attr "size" "128")])
14574
14575 (define_insn "fma<mode>4_odd"
14576 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14577 (unspec:IEEE128
14578 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14579 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14580 (match_operand:IEEE128 3 "altivec_register_operand" "0")]
14581 UNSPEC_FMA_ROUND_TO_ODD))]
14582 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14583 "xsmaddqpo %0,%1,%2"
14584 [(set_attr "type" "qmul")
14585 (set_attr "size" "128")])
14586
14587 (define_insn "*fms<mode>4_odd"
14588 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14589 (unspec:IEEE128
14590 [(match_operand:IEEE128 1 "altivec_register_operand" "%v")
14591 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14592 (neg:IEEE128
14593 (match_operand:IEEE128 3 "altivec_register_operand" "0"))]
14594 UNSPEC_FMA_ROUND_TO_ODD))]
14595 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14596 "xsmsubqpo %0,%1,%2"
14597 [(set_attr "type" "qmul")
14598 (set_attr "size" "128")])
14599
14600 (define_insn "*nfma<mode>4_odd"
14601 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14602 (neg:IEEE128
14603 (unspec:IEEE128
14604 [(match_operand:IEEE128 1 "altivec_register_operand" "%v")
14605 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14606 (match_operand:IEEE128 3 "altivec_register_operand" "0")]
14607 UNSPEC_FMA_ROUND_TO_ODD)))]
14608 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14609 "xsnmaddqpo %0,%1,%2"
14610 [(set_attr "type" "qmul")
14611 (set_attr "size" "128")])
14612
14613 (define_insn "*nfms<mode>4_odd"
14614 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14615 (neg:IEEE128
14616 (unspec:IEEE128
14617 [(match_operand:IEEE128 1 "altivec_register_operand" "%v")
14618 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14619 (neg:IEEE128
14620 (match_operand:IEEE128 3 "altivec_register_operand" "0"))]
14621 UNSPEC_FMA_ROUND_TO_ODD)))]
14622 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14623 "xsnmsubqpo %0,%1,%2"
14624 [(set_attr "type" "qmul")
14625 (set_attr "size" "128")])
14626
14627 (define_insn "trunc<mode>df2_odd"
14628 [(set (match_operand:DF 0 "vsx_register_operand" "=v")
14629 (unspec:DF [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14630 UNSPEC_TRUNC_ROUND_TO_ODD))]
14631 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14632 "xscvqpdpo %0,%1"
14633 [(set_attr "type" "vecfloat")
14634 (set_attr "size" "128")])
14635
14636 ;; IEEE 128-bit comparisons
14637 (define_insn "*cmp<mode>_hw"
14638 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
14639 (compare:CCFP (match_operand:IEEE128 1 "altivec_register_operand" "v")
14640 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14641 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14642 "xscmpuqp %0,%1,%2"
14643 [(set_attr "type" "veccmp")
14644 (set_attr "size" "128")])
14645 \f
14646 ;; Miscellaneous ISA 3.0 (power9) instructions
14647
14648 (define_insn "darn_32"
14649 [(set (match_operand:SI 0 "register_operand" "=r")
14650 (unspec_volatile:SI [(const_int 0)] UNSPECV_DARN_32))]
14651 "TARGET_P9_MISC"
14652 "darn %0,0"
14653 [(set_attr "type" "integer")])
14654
14655 (define_insn "darn_raw"
14656 [(set (match_operand:DI 0 "register_operand" "=r")
14657 (unspec_volatile:DI [(const_int 0)] UNSPECV_DARN_RAW))]
14658 "TARGET_P9_MISC && TARGET_64BIT"
14659 "darn %0,2"
14660 [(set_attr "type" "integer")])
14661
14662 (define_insn "darn"
14663 [(set (match_operand:DI 0 "register_operand" "=r")
14664 (unspec_volatile:DI [(const_int 0)] UNSPECV_DARN))]
14665 "TARGET_P9_MISC && TARGET_64BIT"
14666 "darn %0,1"
14667 [(set_attr "type" "integer")])
14668
14669 ;; Test byte within range.
14670 ;;
14671 ;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx
14672 ;; represents a byte whose value is ignored in this context and
14673 ;; vv, the least significant byte, holds the byte value that is to
14674 ;; be tested for membership within the range specified by operand 2.
14675 ;; The bytes of operand 2 are organized as xx:xx:hi:lo.
14676 ;;
14677 ;; Return in target register operand 0 a value of 1 if lo <= vv and
14678 ;; vv <= hi. Otherwise, set register operand 0 to 0.
14679 ;;
14680 ;; Though the instructions to which this expansion maps operate on
14681 ;; 64-bit registers, the current implementation only operates on
14682 ;; SI-mode operands as the high-order bits provide no information
14683 ;; that is not already available in the low-order bits. To avoid the
14684 ;; costs of data widening operations, future enhancements might allow
14685 ;; DI mode for operand 0 and/or might allow operand 1 to be QI mode.
14686 (define_expand "cmprb"
14687 [(set (match_dup 3)
14688 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
14689 (match_operand:SI 2 "gpc_reg_operand" "r")]
14690 UNSPEC_CMPRB))
14691 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
14692 (if_then_else:SI (lt (match_dup 3)
14693 (const_int 0))
14694 (const_int -1)
14695 (if_then_else (gt (match_dup 3)
14696 (const_int 0))
14697 (const_int 1)
14698 (const_int 0))))]
14699 "TARGET_P9_MISC"
14700 {
14701 operands[3] = gen_reg_rtx (CCmode);
14702 })
14703
14704 ;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx
14705 ;; represents a byte whose value is ignored in this context and
14706 ;; vv, the least significant byte, holds the byte value that is to
14707 ;; be tested for membership within the range specified by operand 2.
14708 ;; The bytes of operand 2 are organized as xx:xx:hi:lo.
14709 ;;
14710 ;; Set bit 1 (the GT bit, 0x4) of CR register operand 0 to 1 if
14711 ;; lo <= vv and vv <= hi. Otherwise, set the GT bit to 0. The other
14712 ;; 3 bits of the target CR register are all set to 0.
14713 (define_insn "*cmprb_internal"
14714 [(set (match_operand:CC 0 "cc_reg_operand" "=y")
14715 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
14716 (match_operand:SI 2 "gpc_reg_operand" "r")]
14717 UNSPEC_CMPRB))]
14718 "TARGET_P9_MISC"
14719 "cmprb %0,0,%1,%2"
14720 [(set_attr "type" "logical")])
14721
14722 ;; Set operand 0 register to -1 if the LT bit (0x8) of condition
14723 ;; register operand 1 is on. Otherwise, set operand 0 register to 1
14724 ;; if the GT bit (0x4) of condition register operand 1 is on.
14725 ;; Otherwise, set operand 0 to 0. Note that the result stored into
14726 ;; register operand 0 is non-zero iff either the LT or GT bits are on
14727 ;; within condition register operand 1.
14728 (define_insn "setb_signed"
14729 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
14730 (if_then_else:SI (lt (match_operand:CC 1 "cc_reg_operand" "y")
14731 (const_int 0))
14732 (const_int -1)
14733 (if_then_else (gt (match_dup 1)
14734 (const_int 0))
14735 (const_int 1)
14736 (const_int 0))))]
14737 "TARGET_P9_MISC"
14738 "setb %0,%1"
14739 [(set_attr "type" "logical")])
14740
14741 (define_insn "setb_unsigned"
14742 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
14743 (if_then_else:SI (ltu (match_operand:CCUNS 1 "cc_reg_operand" "y")
14744 (const_int 0))
14745 (const_int -1)
14746 (if_then_else (gtu (match_dup 1)
14747 (const_int 0))
14748 (const_int 1)
14749 (const_int 0))))]
14750 "TARGET_P9_MISC"
14751 "setb %0,%1"
14752 [(set_attr "type" "logical")])
14753
14754 ;; Test byte within two ranges.
14755 ;;
14756 ;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx
14757 ;; represents a byte whose value is ignored in this context and
14758 ;; vv, the least significant byte, holds the byte value that is to
14759 ;; be tested for membership within the range specified by operand 2.
14760 ;; The bytes of operand 2 are organized as hi_1:lo_1:hi_2:lo_2.
14761 ;;
14762 ;; Return in target register operand 0 a value of 1 if (lo_1 <= vv and
14763 ;; vv <= hi_1) or if (lo_2 <= vv and vv <= hi_2). Otherwise, set register
14764 ;; operand 0 to 0.
14765 ;;
14766 ;; Though the instructions to which this expansion maps operate on
14767 ;; 64-bit registers, the current implementation only operates on
14768 ;; SI-mode operands as the high-order bits provide no information
14769 ;; that is not already available in the low-order bits. To avoid the
14770 ;; costs of data widening operations, future enhancements might allow
14771 ;; DI mode for operand 0 and/or might allow operand 1 to be QI mode.
14772 (define_expand "cmprb2"
14773 [(set (match_dup 3)
14774 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
14775 (match_operand:SI 2 "gpc_reg_operand" "r")]
14776 UNSPEC_CMPRB2))
14777 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
14778 (if_then_else:SI (lt (match_dup 3)
14779 (const_int 0))
14780 (const_int -1)
14781 (if_then_else (gt (match_dup 3)
14782 (const_int 0))
14783 (const_int 1)
14784 (const_int 0))))]
14785 "TARGET_P9_MISC"
14786 {
14787 operands[3] = gen_reg_rtx (CCmode);
14788 })
14789
14790 ;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx
14791 ;; represents a byte whose value is ignored in this context and
14792 ;; vv, the least significant byte, holds the byte value that is to
14793 ;; be tested for membership within the ranges specified by operand 2.
14794 ;; The bytes of operand 2 are organized as hi_1:lo_1:hi_2:lo_2.
14795 ;;
14796 ;; Set bit 1 (the GT bit, 0x4) of CR register operand 0 to 1 if
14797 ;; (lo_1 <= vv and vv <= hi_1) or if (lo_2 <= vv and vv <= hi_2).
14798 ;; Otherwise, set the GT bit to 0. The other 3 bits of the target
14799 ;; CR register are all set to 0.
14800 (define_insn "*cmprb2_internal"
14801 [(set (match_operand:CC 0 "cc_reg_operand" "=y")
14802 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
14803 (match_operand:SI 2 "gpc_reg_operand" "r")]
14804 UNSPEC_CMPRB2))]
14805 "TARGET_P9_MISC"
14806 "cmprb %0,1,%1,%2"
14807 [(set_attr "type" "logical")])
14808
14809 ;; Test byte membership within set of 8 bytes.
14810 ;;
14811 ;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx
14812 ;; represents a byte whose value is ignored in this context and
14813 ;; vv, the least significant byte, holds the byte value that is to
14814 ;; be tested for membership within the set specified by operand 2.
14815 ;; The bytes of operand 2 are organized as e0:e1:e2:e3:e4:e5:e6:e7.
14816 ;;
14817 ;; Return in target register operand 0 a value of 1 if vv equals one
14818 ;; of the values e0, e1, e2, e3, e4, e5, e6, or e7. Otherwise, set
14819 ;; register operand 0 to 0. Note that the 8 byte values held within
14820 ;; operand 2 need not be unique.
14821 ;;
14822 ;; Though the instructions to which this expansion maps operate on
14823 ;; 64-bit registers, the current implementation requires that operands
14824 ;; 0 and 1 have mode SI as the high-order bits provide no information
14825 ;; that is not already available in the low-order bits. To avoid the
14826 ;; costs of data widening operations, future enhancements might allow
14827 ;; DI mode for operand 0 and/or might allow operand 1 to be QI mode.
14828 (define_expand "cmpeqb"
14829 [(set (match_dup 3)
14830 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
14831 (match_operand:DI 2 "gpc_reg_operand" "r")]
14832 UNSPEC_CMPEQB))
14833 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
14834 (if_then_else:SI (lt (match_dup 3)
14835 (const_int 0))
14836 (const_int -1)
14837 (if_then_else (gt (match_dup 3)
14838 (const_int 0))
14839 (const_int 1)
14840 (const_int 0))))]
14841 "TARGET_P9_MISC && TARGET_64BIT"
14842 {
14843 operands[3] = gen_reg_rtx (CCmode);
14844 })
14845
14846 ;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx
14847 ;; represents a byte whose value is ignored in this context and
14848 ;; vv, the least significant byte, holds the byte value that is to
14849 ;; be tested for membership within the set specified by operand 2.
14850 ;; The bytes of operand 2 are organized as e0:e1:e2:e3:e4:e5:e6:e7.
14851 ;;
14852 ;; Set bit 1 (the GT bit, 0x4) of CR register operand 0 to 1 if vv
14853 ;; equals one of the values e0, e1, e2, e3, e4, e5, e6, or e7. Otherwise,
14854 ;; set the GT bit to zero. The other 3 bits of the target CR register
14855 ;; are all set to 0.
14856 (define_insn "*cmpeqb_internal"
14857 [(set (match_operand:CC 0 "cc_reg_operand" "=y")
14858 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
14859 (match_operand:DI 2 "gpc_reg_operand" "r")]
14860 UNSPEC_CMPEQB))]
14861 "TARGET_P9_MISC && TARGET_64BIT"
14862 "cmpeqb %0,%1,%2"
14863 [(set_attr "type" "logical")])
14864 \f
14865
14866 (include "sync.md")
14867 (include "vector.md")
14868 (include "vsx.md")
14869 (include "altivec.md")
14870 (include "mma.md")
14871 (include "dfp.md")
14872 (include "crypto.md")
14873 (include "htm.md")