rs6000: Fix p8_mtvsrd_df's insn type
[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_XVTLSBB
81 UNSPEC_TLSDTPREL
82 UNSPEC_TLSDTPRELHA
83 UNSPEC_TLSDTPRELLO
84 UNSPEC_TLSGOTDTPREL
85 UNSPEC_TLSTPREL
86 UNSPEC_TLSTPRELHA
87 UNSPEC_TLSTPRELLO
88 UNSPEC_TLSGOTTPREL
89 UNSPEC_TLSTLS
90 UNSPEC_TLSTLS_PCREL
91 UNSPEC_FIX_TRUNC_TF ; fadd, rounding towards zero
92 UNSPEC_STFIWX
93 UNSPEC_POPCNTB
94 UNSPEC_FRES
95 UNSPEC_SP_SET
96 UNSPEC_SP_TEST
97 UNSPEC_SYNC
98 UNSPEC_LWSYNC
99 UNSPEC_SYNC_OP
100 UNSPEC_ATOMIC
101 UNSPEC_CMPXCHG
102 UNSPEC_XCHG
103 UNSPEC_AND
104 UNSPEC_DLMZB
105 UNSPEC_DLMZB_CR
106 UNSPEC_DLMZB_STRLEN
107 UNSPEC_RSQRT
108 UNSPEC_TOCREL
109 UNSPEC_MACHOPIC_OFFSET
110 UNSPEC_BPERM
111 UNSPEC_COPYSIGN
112 UNSPEC_PARITY
113 UNSPEC_CMPB
114 UNSPEC_FCTIW
115 UNSPEC_FCTID
116 UNSPEC_LFIWAX
117 UNSPEC_LFIWZX
118 UNSPEC_FCTIWUZ
119 UNSPEC_NOP
120 UNSPEC_GRP_END_NOP
121 UNSPEC_P8V_FMRGOW
122 UNSPEC_P8V_MTVSRWZ
123 UNSPEC_P8V_RELOAD_FROM_GPR
124 UNSPEC_P8V_MTVSRD
125 UNSPEC_P8V_XXPERMDI
126 UNSPEC_P8V_RELOAD_FROM_VSX
127 UNSPEC_ADDG6S
128 UNSPEC_CDTBCD
129 UNSPEC_CBCDTD
130 UNSPEC_DIVE
131 UNSPEC_DIVEU
132 UNSPEC_UNPACK_128BIT
133 UNSPEC_PACK_128BIT
134 UNSPEC_LSQ
135 UNSPEC_FUSION_GPR
136 UNSPEC_STACK_CHECK
137 UNSPEC_CMPRB
138 UNSPEC_CMPRB2
139 UNSPEC_CMPEQB
140 UNSPEC_ADD_ROUND_TO_ODD
141 UNSPEC_SUB_ROUND_TO_ODD
142 UNSPEC_MUL_ROUND_TO_ODD
143 UNSPEC_DIV_ROUND_TO_ODD
144 UNSPEC_FMA_ROUND_TO_ODD
145 UNSPEC_SQRT_ROUND_TO_ODD
146 UNSPEC_TRUNC_ROUND_TO_ODD
147 UNSPEC_SIGNBIT
148 UNSPEC_SF_FROM_SI
149 UNSPEC_SI_FROM_SF
150 UNSPEC_PLTSEQ
151 UNSPEC_PLT16_HA
152 UNSPEC_CFUGED
153 UNSPEC_CNTLZDM
154 UNSPEC_CNTTZDM
155 UNSPEC_PDEPD
156 UNSPEC_PEXTD
157 ])
158
159 ;;
160 ;; UNSPEC_VOLATILE usage
161 ;;
162
163 (define_c_enum "unspecv"
164 [UNSPECV_BLOCK
165 UNSPECV_LL ; load-locked
166 UNSPECV_SC ; store-conditional
167 UNSPECV_PROBE_STACK_RANGE ; probe range of stack addresses
168 UNSPECV_EH_RR ; eh_reg_restore
169 UNSPECV_ISYNC ; isync instruction
170 UNSPECV_MFTB ; move from time base
171 UNSPECV_DARN ; darn 1 (deliver a random number)
172 UNSPECV_DARN_32 ; darn 2
173 UNSPECV_DARN_RAW ; darn 0
174 UNSPECV_NLGR ; non-local goto receiver
175 UNSPECV_MFFS ; Move from FPSCR
176 UNSPECV_MFFSL ; Move from FPSCR light instruction version
177 UNSPECV_MFFSCRN ; Move from FPSCR float rounding mode
178 UNSPECV_MFFSCDRN ; Move from FPSCR decimal float rounding mode
179 UNSPECV_MTFSF ; Move to FPSCR Fields 8 to 15
180 UNSPECV_MTFSF_HI ; Move to FPSCR Fields 0 to 7
181 UNSPECV_MTFSB0 ; Set FPSCR Field bit to 0
182 UNSPECV_MTFSB1 ; Set FPSCR Field bit to 1
183 UNSPECV_SPLIT_STACK_RETURN ; A camouflaged return
184 UNSPECV_SPEC_BARRIER ; Speculation barrier
185 UNSPECV_PLT16_LO
186 UNSPECV_PLT_PCREL
187 ])
188
189 ; The three different kinds of epilogue.
190 (define_enum "epilogue_type" [normal sibcall eh_return])
191 \f
192 ;; Define an insn type attribute. This is used in function unit delay
193 ;; computations.
194 (define_attr "type"
195 "integer,two,three,
196 add,logical,shift,insert,
197 mul,halfmul,div,
198 exts,cntlz,popcnt,isel,
199 load,store,fpload,fpstore,vecload,vecstore,
200 cmp,
201 branch,jmpreg,mfjmpr,mtjmpr,trap,isync,sync,load_l,store_c,
202 cr_logical,mfcr,mfcrf,mtcr,
203 fpcompare,fp,fpsimple,dmul,qmul,sdiv,ddiv,ssqrt,dsqrt,
204 vecsimple,veccomplex,vecdiv,veccmp,veccmpsimple,vecperm,
205 vecfloat,vecfdiv,vecdouble,mtvsr,mfvsr,crypto,
206 veclogical,veccmpfx,vecexts,vecmove,
207 htm,htmsimple,dfp,mma"
208 (const_string "integer"))
209
210 ;; What data size does this instruction work on?
211 ;; This is used for insert, mul and others as necessary.
212 (define_attr "size" "8,16,32,64,128" (const_string "32"))
213
214 ;; What is the insn_cost for this insn? The target hook can still override
215 ;; this. For optimizing for size the "length" attribute is used instead.
216 (define_attr "cost" "" (const_int 0))
217
218 ;; Is this instruction record form ("dot", signed compare to 0, writing CR0)?
219 ;; This is used for add, logical, shift, exts, mul.
220 (define_attr "dot" "no,yes" (const_string "no"))
221
222 ;; Does this instruction sign-extend its result?
223 ;; This is used for load insns.
224 (define_attr "sign_extend" "no,yes" (const_string "no"))
225
226 ;; Does this cr_logical instruction have three operands? That is, BT != BB.
227 (define_attr "cr_logical_3op" "no,yes" (const_string "no"))
228
229 ;; Does this instruction use indexed (that is, reg+reg) addressing?
230 ;; This is used for load and store insns. If operand 0 or 1 is a MEM
231 ;; it is automatically set based on that. If a load or store instruction
232 ;; has fewer than two operands it needs to set this attribute manually
233 ;; or the compiler will crash.
234 (define_attr "indexed" "no,yes"
235 (if_then_else (ior (match_operand 0 "indexed_address_mem")
236 (match_operand 1 "indexed_address_mem"))
237 (const_string "yes")
238 (const_string "no")))
239
240 ;; Does this instruction use update addressing?
241 ;; This is used for load and store insns. See the comments for "indexed".
242 (define_attr "update" "no,yes"
243 (if_then_else (ior (match_operand 0 "update_address_mem")
244 (match_operand 1 "update_address_mem"))
245 (const_string "yes")
246 (const_string "no")))
247
248 ;; Is this instruction using operands[2] as shift amount, and can that be a
249 ;; register?
250 ;; This is used for shift insns.
251 (define_attr "maybe_var_shift" "no,yes" (const_string "no"))
252
253 ;; Is this instruction using a shift amount from a register?
254 ;; This is used for shift insns.
255 (define_attr "var_shift" "no,yes"
256 (if_then_else (and (eq_attr "type" "shift")
257 (eq_attr "maybe_var_shift" "yes"))
258 (if_then_else (match_operand 2 "gpc_reg_operand")
259 (const_string "yes")
260 (const_string "no"))
261 (const_string "no")))
262
263 ;; Is copying of this instruction disallowed?
264 (define_attr "cannot_copy" "no,yes" (const_string "no"))
265
266
267 ;; Whether an insn is a prefixed insn, and an initial 'p' should be printed
268 ;; before the instruction. A prefixed instruction has a prefix instruction
269 ;; word that extends the immediate value of the instructions from 12-16 bits to
270 ;; 34 bits. The macro ASM_OUTPUT_OPCODE emits a leading 'p' for prefixed
271 ;; insns. The default "length" attribute will also be adjusted by default to
272 ;; be 12 bytes.
273 (define_attr "prefixed" "no,yes"
274 (cond [(ior (match_test "!TARGET_PREFIXED")
275 (match_test "!NONJUMP_INSN_P (insn)"))
276 (const_string "no")
277
278 (eq_attr "type" "load,fpload,vecload")
279 (if_then_else (match_test "prefixed_load_p (insn)")
280 (const_string "yes")
281 (const_string "no"))
282
283 (eq_attr "type" "store,fpstore,vecstore")
284 (if_then_else (match_test "prefixed_store_p (insn)")
285 (const_string "yes")
286 (const_string "no"))
287
288 (eq_attr "type" "integer,add")
289 (if_then_else (match_test "prefixed_paddi_p (insn)")
290 (const_string "yes")
291 (const_string "no"))]
292
293 (const_string "no")))
294
295 ;; Return the number of real hardware instructions in a combined insn. If it
296 ;; is 0, just use the length / 4.
297 (define_attr "num_insns" "" (const_int 0))
298
299 ;; If an insn is prefixed, return the maximum number of prefixed instructions
300 ;; in the insn. The macro ADJUST_INSN_LENGTH uses this number to adjust the
301 ;; insn length.
302 (define_attr "max_prefixed_insns" "" (const_int 1))
303
304 ;; Length of the instruction (in bytes). This length does not consider the
305 ;; length for prefixed instructions. The macro ADJUST_INSN_LENGTH will adjust
306 ;; the length if there are prefixed instructions.
307 ;;
308 ;; While it might be tempting to use num_insns to calculate the length, it can
309 ;; be problematical unless all insn lengths are adjusted to use num_insns
310 ;; (i.e. if num_insns is 0, it will get the length, which in turn will get
311 ;; num_insns and recurse).
312 (define_attr "length" "" (const_int 4))
313
314 ;; Processor type -- this attribute must exactly match the processor_type
315 ;; enumeration in rs6000-opts.h.
316 (define_attr "cpu"
317 "ppc601,ppc603,ppc604,ppc604e,ppc620,ppc630,
318 ppc750,ppc7400,ppc7450,
319 ppc403,ppc405,ppc440,ppc476,
320 ppc8540,ppc8548,ppce300c2,ppce300c3,ppce500mc,ppce500mc64,ppce5500,ppce6500,
321 power4,power5,power6,power7,power8,power9,power10,
322 rs64a,mpccore,cell,ppca2,titan"
323 (const (symbol_ref "(enum attr_cpu) rs6000_tune")))
324
325 ;; The ISA we implement.
326 (define_attr "isa" "any,p5,p6,p7,p7v,p8v,p9,p9v,p9kf,p9tf,p10"
327 (const_string "any"))
328
329 ;; Is this alternative enabled for the current CPU/ISA/etc.?
330 (define_attr "enabled" ""
331 (cond
332 [(eq_attr "isa" "any")
333 (const_int 1)
334
335 (and (eq_attr "isa" "p5")
336 (match_test "TARGET_POPCNTB"))
337 (const_int 1)
338
339 (and (eq_attr "isa" "p6")
340 (match_test "TARGET_CMPB"))
341 (const_int 1)
342
343 (and (eq_attr "isa" "p7")
344 (match_test "TARGET_POPCNTD"))
345 (const_int 1)
346
347 (and (eq_attr "isa" "p7v")
348 (match_test "TARGET_VSX"))
349 (const_int 1)
350
351 (and (eq_attr "isa" "p8v")
352 (match_test "TARGET_P8_VECTOR"))
353 (const_int 1)
354
355 (and (eq_attr "isa" "p9")
356 (match_test "TARGET_MODULO"))
357 (const_int 1)
358
359 (and (eq_attr "isa" "p9v")
360 (match_test "TARGET_P9_VECTOR"))
361 (const_int 1)
362
363 (and (eq_attr "isa" "p9kf")
364 (match_test "TARGET_FLOAT128_TYPE"))
365 (const_int 1)
366
367 (and (eq_attr "isa" "p9tf")
368 (match_test "FLOAT128_VECTOR_P (TFmode)"))
369 (const_int 1)
370
371 (and (eq_attr "isa" "p10")
372 (match_test "TARGET_POWER10"))
373 (const_int 1)
374 ] (const_int 0)))
375
376 ;; If this instruction is microcoded on the CELL processor
377 ; The default for load extended, the recorded instructions and rotate/shifts by a variable is always microcoded
378 (define_attr "cell_micro" "not,conditional,always"
379 (if_then_else (ior (and (eq_attr "type" "shift,exts,mul")
380 (eq_attr "dot" "yes"))
381 (and (eq_attr "type" "load")
382 (eq_attr "sign_extend" "yes"))
383 (and (eq_attr "type" "shift")
384 (eq_attr "var_shift" "yes")))
385 (const_string "always")
386 (const_string "not")))
387
388 (automata_option "ndfa")
389
390 (include "rs64.md")
391 (include "mpc.md")
392 (include "40x.md")
393 (include "440.md")
394 (include "476.md")
395 (include "601.md")
396 (include "603.md")
397 (include "6xx.md")
398 (include "7xx.md")
399 (include "7450.md")
400 (include "8540.md")
401 (include "e300c2c3.md")
402 (include "e500mc.md")
403 (include "e500mc64.md")
404 (include "e5500.md")
405 (include "e6500.md")
406 (include "power4.md")
407 (include "power5.md")
408 (include "power6.md")
409 (include "power7.md")
410 (include "power8.md")
411 (include "power9.md")
412 (include "power10.md")
413 (include "cell.md")
414 (include "a2.md")
415 (include "titan.md")
416
417 (include "predicates.md")
418 (include "constraints.md")
419
420 \f
421 ;; Mode iterators
422
423 ; This mode iterator allows :GPR to be used to indicate the allowable size
424 ; of whole values in GPRs.
425 (define_mode_iterator GPR [SI (DI "TARGET_POWERPC64")])
426
427 ; And again, for patterns that need two (potentially) different integer modes.
428 (define_mode_iterator GPR2 [SI (DI "TARGET_POWERPC64")])
429
430 ; Any supported integer mode.
431 (define_mode_iterator INT [QI HI SI DI TI PTI])
432
433 ; Any supported integer mode that fits in one register.
434 (define_mode_iterator INT1 [QI HI SI (DI "TARGET_POWERPC64")])
435
436 ; Integer modes supported in VSX registers with ISA 3.0 instructions
437 (define_mode_iterator INT_ISA3 [QI HI SI DI])
438
439 ; Everything we can extend QImode to.
440 (define_mode_iterator EXTQI [SI (DI "TARGET_POWERPC64")])
441
442 ; Everything we can extend HImode to.
443 (define_mode_iterator EXTHI [SI (DI "TARGET_POWERPC64")])
444
445 ; Everything we can extend SImode to.
446 (define_mode_iterator EXTSI [(DI "TARGET_POWERPC64")])
447
448 ; QImode or HImode for small integer moves and small atomic ops
449 (define_mode_iterator QHI [QI HI])
450
451 ; QImode, HImode, SImode for fused ops only for GPR loads
452 (define_mode_iterator QHSI [QI HI SI])
453
454 ; HImode or SImode for sign extended fusion ops
455 (define_mode_iterator HSI [HI SI])
456
457 ; SImode or DImode, even if DImode doesn't fit in GPRs.
458 (define_mode_iterator SDI [SI DI])
459
460 ; The size of a pointer. Also, the size of the value that a record-condition
461 ; (one with a '.') will compare; and the size used for arithmetic carries.
462 (define_mode_iterator P [(SI "TARGET_32BIT") (DI "TARGET_64BIT")])
463
464 ; Iterator to add PTImode along with TImode (TImode can go in VSX registers,
465 ; PTImode is GPR only)
466 (define_mode_iterator TI2 [TI PTI])
467
468 ; Any hardware-supported floating-point mode
469 (define_mode_iterator FP [
470 (SF "TARGET_HARD_FLOAT")
471 (DF "TARGET_HARD_FLOAT")
472 (TF "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128")
473 (IF "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128")
474 (KF "TARGET_FLOAT128_TYPE")
475 (DD "TARGET_DFP")
476 (TD "TARGET_DFP")])
477
478 ; Any fma capable floating-point mode.
479 (define_mode_iterator FMA_F [
480 (SF "TARGET_HARD_FLOAT")
481 (DF "TARGET_HARD_FLOAT || VECTOR_UNIT_VSX_P (DFmode)")
482 (V4SF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)")
483 (V2DF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V2DFmode)")
484 (KF "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (KFmode)")
485 (TF "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (TFmode)")
486 ])
487
488 ; Floating point move iterators to combine binary and decimal moves
489 (define_mode_iterator FMOVE32 [SF SD])
490 (define_mode_iterator FMOVE64 [DF DD])
491 (define_mode_iterator FMOVE64X [DI DF DD])
492 (define_mode_iterator FMOVE128 [(TF "TARGET_LONG_DOUBLE_128")
493 (IF "FLOAT128_IBM_P (IFmode)")
494 (TD "TARGET_HARD_FLOAT")])
495
496 (define_mode_iterator FMOVE128_FPR [(TF "FLOAT128_2REG_P (TFmode)")
497 (IF "FLOAT128_2REG_P (IFmode)")
498 (TD "TARGET_HARD_FLOAT")])
499
500 ; Iterators for 128 bit types for direct move
501 (define_mode_iterator FMOVE128_GPR [TI
502 V16QI
503 V8HI
504 V4SI
505 V4SF
506 V2DI
507 V2DF
508 V1TI
509 (KF "FLOAT128_VECTOR_P (KFmode)")
510 (TF "FLOAT128_VECTOR_P (TFmode)")])
511
512 ; Iterator for 128-bit VSX types for pack/unpack
513 (define_mode_iterator FMOVE128_VSX [V1TI KF])
514
515 ; Iterators for converting to/from TFmode
516 (define_mode_iterator IFKF [IF KF])
517
518 ; Constraints for moving IF/KFmode.
519 (define_mode_attr IFKF_reg [(IF "d") (KF "wa")])
520
521 ; Whether a floating point move is ok, don't allow SD without hardware FP
522 (define_mode_attr fmove_ok [(SF "")
523 (DF "")
524 (SD "TARGET_HARD_FLOAT")
525 (DD "")])
526
527 ; Convert REAL_VALUE to the appropriate bits
528 (define_mode_attr real_value_to_target [(SF "REAL_VALUE_TO_TARGET_SINGLE")
529 (DF "REAL_VALUE_TO_TARGET_DOUBLE")
530 (SD "REAL_VALUE_TO_TARGET_DECIMAL32")
531 (DD "REAL_VALUE_TO_TARGET_DECIMAL64")])
532
533 ; Whether 0.0 has an all-zero bit pattern
534 (define_mode_attr zero_fp [(SF "j")
535 (DF "j")
536 (TF "j")
537 (IF "j")
538 (KF "j")
539 (SD "wn")
540 (DD "wn")
541 (TD "wn")])
542
543 ; Definitions for 64-bit VSX
544 (define_mode_attr f64_vsx [(DF "wa") (DD "wn")])
545
546 ; Definitions for 64-bit direct move
547 (define_mode_attr f64_dm [(DF "wa") (DD "d")])
548
549 ; Definitions for 64-bit use of altivec registers
550 (define_mode_attr f64_av [(DF "v") (DD "wn")])
551
552 ; Definitions for 64-bit access to ISA 3.0 (power9) vector
553 (define_mode_attr f64_p9 [(DF "v") (DD "wn")])
554
555 ; These modes do not fit in integer registers in 32-bit mode.
556 (define_mode_iterator DIFD [DI DF DD])
557
558 ; Iterator for reciprocal estimate instructions
559 (define_mode_iterator RECIPF [SF DF V4SF V2DF])
560
561 ; SFmode or DFmode.
562 (define_mode_iterator SFDF [SF DF])
563
564 ; And again, for when we need two FP modes in a pattern.
565 (define_mode_iterator SFDF2 [SF DF])
566
567 ; A generic s/d attribute, for sp/dp for example.
568 (define_mode_attr sd [(SF "s") (DF "d")
569 (V4SF "s") (V2DF "d")])
570
571 ; "s" or nothing, for fmuls/fmul for example.
572 (define_mode_attr s [(SF "s") (DF "")])
573
574 ; Iterator for 128-bit floating point that uses the IBM double-double format
575 (define_mode_iterator IBM128 [(IF "FLOAT128_IBM_P (IFmode)")
576 (TF "FLOAT128_IBM_P (TFmode)")])
577
578 ; Iterator for 128-bit floating point that uses IEEE 128-bit float
579 (define_mode_iterator IEEE128 [(KF "FLOAT128_IEEE_P (KFmode)")
580 (TF "FLOAT128_IEEE_P (TFmode)")])
581
582 ; Iterator for 128-bit floating point
583 (define_mode_iterator FLOAT128 [(KF "TARGET_FLOAT128_TYPE")
584 (IF "TARGET_FLOAT128_TYPE")
585 (TF "TARGET_LONG_DOUBLE_128")])
586
587 ; Iterator for signbit on 64-bit machines with direct move
588 (define_mode_iterator SIGNBIT [(KF "FLOAT128_VECTOR_P (KFmode)")
589 (TF "FLOAT128_VECTOR_P (TFmode)")])
590
591 ; Iterator for ISA 3.0 supported floating point types
592 (define_mode_iterator FP_ISA3 [SF DF])
593
594 ; SF/DF constraint for arithmetic on traditional floating point registers
595 (define_mode_attr Ff [(SF "f") (DF "d") (DI "d")])
596
597 ; SF/DF constraint for arithmetic on VSX registers using instructions added in
598 ; ISA 2.06 (power7). This includes instructions that normally target DF mode,
599 ; but are used on SFmode, since internally SFmode values are kept in the DFmode
600 ; format.
601 (define_mode_attr Fv [(SF "wa") (DF "wa") (DI "wa")])
602
603 ; Which isa is needed for those float instructions?
604 (define_mode_attr Fisa [(SF "p8v") (DF "*") (DI "*")])
605
606 ; FRE/FRES support
607 (define_mode_attr FFRE [(SF "FRES") (DF "FRE")])
608
609 ; Conditional returns.
610 (define_code_iterator any_return [return simple_return])
611 (define_code_attr return_pred [(return "direct_return ()")
612 (simple_return "1")])
613 (define_code_attr return_str [(return "") (simple_return "simple_")])
614
615 ; Logical operators.
616 (define_code_iterator iorxor [ior xor])
617 (define_code_iterator and_ior_xor [and ior xor])
618
619 ; Signed/unsigned variants of ops.
620 (define_code_iterator any_extend [sign_extend zero_extend])
621 (define_code_iterator any_fix [fix unsigned_fix])
622 (define_code_iterator any_float [float unsigned_float])
623
624 (define_code_attr u [(sign_extend "")
625 (zero_extend "u")
626 (fix "")
627 (unsigned_fix "u")])
628
629 (define_code_attr su [(sign_extend "s")
630 (zero_extend "u")
631 (fix "s")
632 (unsigned_fix "u")
633 (float "s")
634 (unsigned_float "u")])
635
636 (define_code_attr az [(sign_extend "a")
637 (zero_extend "z")
638 (fix "a")
639 (unsigned_fix "z")
640 (float "a")
641 (unsigned_float "z")])
642
643 (define_code_attr uns [(fix "")
644 (unsigned_fix "uns")
645 (float "")
646 (unsigned_float "uns")])
647
648 ; Various instructions that come in SI and DI forms.
649 ; A generic w/d attribute, for things like cmpw/cmpd.
650 (define_mode_attr wd [(QI "b")
651 (HI "h")
652 (SI "w")
653 (DI "d")
654 (V16QI "b")
655 (V8HI "h")
656 (V4SI "w")
657 (V2DI "d")
658 (V1TI "q")
659 (TI "q")])
660
661 ; For double extract from different origin types
662 (define_mode_attr du_or_d [(QI "du")
663 (HI "du")
664 (SI "du")
665 (DI "d")
666 (V16QI "du")
667 (V8HI "du")
668 (V4SI "du")
669 (V2DI "d")])
670
671 ;; How many bits in this mode?
672 (define_mode_attr bits [(QI "8") (HI "16") (SI "32") (DI "64")
673 (SF "32") (DF "64")])
674
675 ; DImode bits
676 (define_mode_attr dbits [(QI "56") (HI "48") (SI "32")])
677
678 ;; Bitmask for shift instructions
679 (define_mode_attr hH [(SI "h") (DI "H")])
680
681 ;; A mode twice the size of the given mode
682 (define_mode_attr dmode [(SI "di") (DI "ti")])
683 (define_mode_attr DMODE [(SI "DI") (DI "TI")])
684
685 ;; Suffix for reload patterns
686 (define_mode_attr ptrsize [(SI "32bit")
687 (DI "64bit")])
688
689 (define_mode_attr tptrsize [(SI "TARGET_32BIT")
690 (DI "TARGET_64BIT")])
691
692 (define_mode_attr mptrsize [(SI "si")
693 (DI "di")])
694
695 (define_mode_attr ptrload [(SI "lwz")
696 (DI "ld")])
697
698 (define_mode_attr ptrm [(SI "m")
699 (DI "Y")])
700
701 (define_mode_attr rreg [(SF "f")
702 (DF "wa")
703 (TF "f")
704 (TD "f")
705 (V4SF "wa")
706 (V2DF "wa")])
707
708 (define_mode_attr rreg2 [(SF "f")
709 (DF "d")])
710
711 (define_mode_attr SI_CONVERT_FP [(SF "TARGET_FCFIDS")
712 (DF "TARGET_FCFID")])
713
714 ;; Mode iterator for logical operations on 128-bit types
715 (define_mode_iterator BOOL_128 [TI
716 PTI
717 (V16QI "TARGET_ALTIVEC")
718 (V8HI "TARGET_ALTIVEC")
719 (V4SI "TARGET_ALTIVEC")
720 (V4SF "TARGET_ALTIVEC")
721 (V2DI "TARGET_ALTIVEC")
722 (V2DF "TARGET_ALTIVEC")
723 (V1TI "TARGET_ALTIVEC")])
724
725 ;; For the GPRs we use 3 constraints for register outputs, two that are the
726 ;; same as the output register, and a third where the output register is an
727 ;; early clobber, so we don't have to deal with register overlaps. For the
728 ;; vector types, we prefer to use the vector registers. For TI mode, allow
729 ;; either.
730
731 ;; Mode attribute for boolean operation register constraints for output
732 (define_mode_attr BOOL_REGS_OUTPUT [(TI "&r,r,r,wa,v")
733 (PTI "&r,r,r")
734 (V16QI "wa,v,&?r,?r,?r")
735 (V8HI "wa,v,&?r,?r,?r")
736 (V4SI "wa,v,&?r,?r,?r")
737 (V4SF "wa,v,&?r,?r,?r")
738 (V2DI "wa,v,&?r,?r,?r")
739 (V2DF "wa,v,&?r,?r,?r")
740 (V1TI "wa,v,&?r,?r,?r")])
741
742 ;; Mode attribute for boolean operation register constraints for operand1
743 (define_mode_attr BOOL_REGS_OP1 [(TI "r,0,r,wa,v")
744 (PTI "r,0,r")
745 (V16QI "wa,v,r,0,r")
746 (V8HI "wa,v,r,0,r")
747 (V4SI "wa,v,r,0,r")
748 (V4SF "wa,v,r,0,r")
749 (V2DI "wa,v,r,0,r")
750 (V2DF "wa,v,r,0,r")
751 (V1TI "wa,v,r,0,r")])
752
753 ;; Mode attribute for boolean operation register constraints for operand2
754 (define_mode_attr BOOL_REGS_OP2 [(TI "r,r,0,wa,v")
755 (PTI "r,r,0")
756 (V16QI "wa,v,r,r,0")
757 (V8HI "wa,v,r,r,0")
758 (V4SI "wa,v,r,r,0")
759 (V4SF "wa,v,r,r,0")
760 (V2DI "wa,v,r,r,0")
761 (V2DF "wa,v,r,r,0")
762 (V1TI "wa,v,r,r,0")])
763
764 ;; Mode attribute for boolean operation register constraints for operand1
765 ;; for one_cmpl. To simplify things, we repeat the constraint where 0
766 ;; is used for operand1 or operand2
767 (define_mode_attr BOOL_REGS_UNARY [(TI "r,0,0,wa,v")
768 (PTI "r,0,0")
769 (V16QI "wa,v,r,0,0")
770 (V8HI "wa,v,r,0,0")
771 (V4SI "wa,v,r,0,0")
772 (V4SF "wa,v,r,0,0")
773 (V2DI "wa,v,r,0,0")
774 (V2DF "wa,v,r,0,0")
775 (V1TI "wa,v,r,0,0")])
776
777 ;; Reload iterator for creating the function to allocate a base register to
778 ;; supplement addressing modes.
779 (define_mode_iterator RELOAD [V16QI V8HI V4SI V2DI V4SF V2DF V1TI
780 SF SD SI DF DD DI TI PTI KF IF TF
781 POI PXI])
782
783 ;; Iterate over smin, smax
784 (define_code_iterator fp_minmax [smin smax])
785
786 (define_code_attr minmax [(smin "min")
787 (smax "max")])
788
789 (define_code_attr SMINMAX [(smin "SMIN")
790 (smax "SMAX")])
791
792 ;; Iterator to optimize the following cases:
793 ;; D-form load to FPR register & move to Altivec register
794 ;; Move Altivec register to FPR register and store
795 (define_mode_iterator ALTIVEC_DFORM [DF
796 (SF "TARGET_P8_VECTOR")
797 (DI "TARGET_POWERPC64")])
798
799 (include "darwin.md")
800 \f
801 ;; Start with fixed-point load and store insns. Here we put only the more
802 ;; complex forms. Basic data transfer is done later.
803
804 (define_insn "zero_extendqi<mode>2"
805 [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r,^wa,^v")
806 (zero_extend:EXTQI (match_operand:QI 1 "reg_or_mem_operand" "m,r,Z,v")))]
807 ""
808 "@
809 lbz%U1%X1 %0,%1
810 rlwinm %0,%1,0,0xff
811 lxsibzx %x0,%y1
812 vextractub %0,%1,7"
813 [(set_attr "type" "load,shift,fpload,vecperm")
814 (set_attr "isa" "*,*,p9v,p9v")])
815
816 (define_insn_and_split "*zero_extendqi<mode>2_dot"
817 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
818 (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
819 (const_int 0)))
820 (clobber (match_scratch:EXTQI 0 "=r,r"))]
821 ""
822 "@
823 andi. %0,%1,0xff
824 #"
825 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
826 [(set (match_dup 0)
827 (zero_extend:EXTQI (match_dup 1)))
828 (set (match_dup 2)
829 (compare:CC (match_dup 0)
830 (const_int 0)))]
831 ""
832 [(set_attr "type" "logical")
833 (set_attr "dot" "yes")
834 (set_attr "length" "4,8")])
835
836 (define_insn_and_split "*zero_extendqi<mode>2_dot2"
837 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
838 (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
839 (const_int 0)))
840 (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
841 (zero_extend:EXTQI (match_dup 1)))]
842 ""
843 "@
844 andi. %0,%1,0xff
845 #"
846 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
847 [(set (match_dup 0)
848 (zero_extend:EXTQI (match_dup 1)))
849 (set (match_dup 2)
850 (compare:CC (match_dup 0)
851 (const_int 0)))]
852 ""
853 [(set_attr "type" "logical")
854 (set_attr "dot" "yes")
855 (set_attr "length" "4,8")])
856
857
858 (define_insn "zero_extendhi<mode>2"
859 [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r,^wa,^v")
860 (zero_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r,Z,v")))]
861 ""
862 "@
863 lhz%U1%X1 %0,%1
864 rlwinm %0,%1,0,0xffff
865 lxsihzx %x0,%y1
866 vextractuh %0,%1,6"
867 [(set_attr "type" "load,shift,fpload,vecperm")
868 (set_attr "isa" "*,*,p9v,p9v")])
869
870 (define_insn_and_split "*zero_extendhi<mode>2_dot"
871 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
872 (compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
873 (const_int 0)))
874 (clobber (match_scratch:EXTHI 0 "=r,r"))]
875 ""
876 "@
877 andi. %0,%1,0xffff
878 #"
879 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
880 [(set (match_dup 0)
881 (zero_extend:EXTHI (match_dup 1)))
882 (set (match_dup 2)
883 (compare:CC (match_dup 0)
884 (const_int 0)))]
885 ""
886 [(set_attr "type" "logical")
887 (set_attr "dot" "yes")
888 (set_attr "length" "4,8")])
889
890 (define_insn_and_split "*zero_extendhi<mode>2_dot2"
891 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
892 (compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
893 (const_int 0)))
894 (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
895 (zero_extend:EXTHI (match_dup 1)))]
896 ""
897 "@
898 andi. %0,%1,0xffff
899 #"
900 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
901 [(set (match_dup 0)
902 (zero_extend:EXTHI (match_dup 1)))
903 (set (match_dup 2)
904 (compare:CC (match_dup 0)
905 (const_int 0)))]
906 ""
907 [(set_attr "type" "logical")
908 (set_attr "dot" "yes")
909 (set_attr "length" "4,8")])
910
911
912 (define_insn "zero_extendsi<mode>2"
913 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r,d,wa,wa,r,wa")
914 (zero_extend:EXTSI (match_operand:SI 1 "reg_or_mem_operand" "m,r,Z,Z,r,wa,wa")))]
915 ""
916 "@
917 lwz%U1%X1 %0,%1
918 rldicl %0,%1,0,32
919 lfiwzx %0,%y1
920 lxsiwzx %x0,%y1
921 mtvsrwz %x0,%1
922 mfvsrwz %0,%x1
923 xxextractuw %x0,%x1,4"
924 [(set_attr "type" "load,shift,fpload,fpload,mtvsr,mfvsr,vecexts")
925 (set_attr "isa" "*,*,p7,p8v,p8v,p8v,p9v")])
926
927 (define_insn_and_split "*zero_extendsi<mode>2_dot"
928 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
929 (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
930 (const_int 0)))
931 (clobber (match_scratch:EXTSI 0 "=r,r"))]
932 ""
933 "@
934 rldicl. %0,%1,0,32
935 #"
936 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
937 [(set (match_dup 0)
938 (zero_extend:DI (match_dup 1)))
939 (set (match_dup 2)
940 (compare:CC (match_dup 0)
941 (const_int 0)))]
942 ""
943 [(set_attr "type" "shift")
944 (set_attr "dot" "yes")
945 (set_attr "length" "4,8")])
946
947 (define_insn_and_split "*zero_extendsi<mode>2_dot2"
948 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
949 (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
950 (const_int 0)))
951 (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
952 (zero_extend:EXTSI (match_dup 1)))]
953 ""
954 "@
955 rldicl. %0,%1,0,32
956 #"
957 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
958 [(set (match_dup 0)
959 (zero_extend:EXTSI (match_dup 1)))
960 (set (match_dup 2)
961 (compare:CC (match_dup 0)
962 (const_int 0)))]
963 ""
964 [(set_attr "type" "shift")
965 (set_attr "dot" "yes")
966 (set_attr "length" "4,8")])
967
968
969 (define_insn "extendqi<mode>2"
970 [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,?*v")
971 (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,?*v")))]
972 ""
973 "@
974 extsb %0,%1
975 vextsb2d %0,%1"
976 [(set_attr "type" "exts,vecperm")
977 (set_attr "isa" "*,p9v")])
978
979 (define_insn_and_split "*extendqi<mode>2_dot"
980 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
981 (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
982 (const_int 0)))
983 (clobber (match_scratch:EXTQI 0 "=r,r"))]
984 ""
985 "@
986 extsb. %0,%1
987 #"
988 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
989 [(set (match_dup 0)
990 (sign_extend:EXTQI (match_dup 1)))
991 (set (match_dup 2)
992 (compare:CC (match_dup 0)
993 (const_int 0)))]
994 ""
995 [(set_attr "type" "exts")
996 (set_attr "dot" "yes")
997 (set_attr "length" "4,8")])
998
999 (define_insn_and_split "*extendqi<mode>2_dot2"
1000 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1001 (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
1002 (const_int 0)))
1003 (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
1004 (sign_extend:EXTQI (match_dup 1)))]
1005 ""
1006 "@
1007 extsb. %0,%1
1008 #"
1009 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1010 [(set (match_dup 0)
1011 (sign_extend:EXTQI (match_dup 1)))
1012 (set (match_dup 2)
1013 (compare:CC (match_dup 0)
1014 (const_int 0)))]
1015 ""
1016 [(set_attr "type" "exts")
1017 (set_attr "dot" "yes")
1018 (set_attr "length" "4,8")])
1019
1020
1021 (define_expand "extendhi<mode>2"
1022 [(set (match_operand:EXTHI 0 "gpc_reg_operand")
1023 (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand")))]
1024 ""
1025 "")
1026
1027 (define_insn "*extendhi<mode>2"
1028 [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r,?*v,?*v")
1029 (sign_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r,Z,v")))]
1030 ""
1031 "@
1032 lha%U1%X1 %0,%1
1033 extsh %0,%1
1034 #
1035 vextsh2d %0,%1"
1036 [(set_attr "type" "load,exts,fpload,vecperm")
1037 (set_attr "sign_extend" "yes")
1038 (set_attr "length" "*,*,8,*")
1039 (set_attr "isa" "*,*,p9v,p9v")])
1040
1041 (define_split
1042 [(set (match_operand:EXTHI 0 "altivec_register_operand")
1043 (sign_extend:EXTHI
1044 (match_operand:HI 1 "indexed_or_indirect_operand")))]
1045 "TARGET_P9_VECTOR && reload_completed"
1046 [(set (match_dup 2)
1047 (match_dup 1))
1048 (set (match_dup 0)
1049 (sign_extend:EXTHI (match_dup 2)))]
1050 {
1051 operands[2] = gen_rtx_REG (HImode, REGNO (operands[0]));
1052 })
1053
1054 (define_insn_and_split "*extendhi<mode>2_dot"
1055 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1056 (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
1057 (const_int 0)))
1058 (clobber (match_scratch:EXTHI 0 "=r,r"))]
1059 ""
1060 "@
1061 extsh. %0,%1
1062 #"
1063 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1064 [(set (match_dup 0)
1065 (sign_extend:EXTHI (match_dup 1)))
1066 (set (match_dup 2)
1067 (compare:CC (match_dup 0)
1068 (const_int 0)))]
1069 ""
1070 [(set_attr "type" "exts")
1071 (set_attr "dot" "yes")
1072 (set_attr "length" "4,8")])
1073
1074 (define_insn_and_split "*extendhi<mode>2_dot2"
1075 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1076 (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
1077 (const_int 0)))
1078 (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
1079 (sign_extend:EXTHI (match_dup 1)))]
1080 ""
1081 "@
1082 extsh. %0,%1
1083 #"
1084 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1085 [(set (match_dup 0)
1086 (sign_extend:EXTHI (match_dup 1)))
1087 (set (match_dup 2)
1088 (compare:CC (match_dup 0)
1089 (const_int 0)))]
1090 ""
1091 [(set_attr "type" "exts")
1092 (set_attr "dot" "yes")
1093 (set_attr "length" "4,8")])
1094
1095
1096 (define_insn "extendsi<mode>2"
1097 [(set (match_operand:EXTSI 0 "gpc_reg_operand"
1098 "=r, r, d, wa, wa, v, v, wr")
1099 (sign_extend:EXTSI (match_operand:SI 1 "lwa_operand"
1100 "YZ, r, Z, Z, r, v, v, ?wa")))]
1101 ""
1102 "@
1103 lwa%U1%X1 %0,%1
1104 extsw %0,%1
1105 lfiwax %0,%y1
1106 lxsiwax %x0,%y1
1107 mtvsrwa %x0,%1
1108 vextsw2d %0,%1
1109 #
1110 #"
1111 [(set_attr "type" "load,exts,fpload,fpload,mtvsr,vecexts,vecperm,mfvsr")
1112 (set_attr "sign_extend" "yes")
1113 (set_attr "length" "*,*,*,*,*,*,8,8")
1114 (set_attr "isa" "*,*,p6,p8v,p8v,p9v,p8v,p8v")])
1115
1116 (define_split
1117 [(set (match_operand:EXTSI 0 "int_reg_operand")
1118 (sign_extend:EXTSI (match_operand:SI 1 "vsx_register_operand")))]
1119 "TARGET_DIRECT_MOVE_64BIT && reload_completed"
1120 [(set (match_dup 2)
1121 (match_dup 1))
1122 (set (match_dup 0)
1123 (sign_extend:DI (match_dup 2)))]
1124 {
1125 operands[2] = gen_rtx_REG (SImode, reg_or_subregno (operands[0]));
1126 })
1127
1128 (define_split
1129 [(set (match_operand:DI 0 "altivec_register_operand")
1130 (sign_extend:DI (match_operand:SI 1 "altivec_register_operand")))]
1131 "TARGET_P8_VECTOR && !TARGET_P9_VECTOR && reload_completed"
1132 [(const_int 0)]
1133 {
1134 rtx dest = operands[0];
1135 rtx src = operands[1];
1136 int dest_regno = REGNO (dest);
1137 int src_regno = REGNO (src);
1138 rtx dest_v2di = gen_rtx_REG (V2DImode, dest_regno);
1139 rtx src_v4si = gen_rtx_REG (V4SImode, src_regno);
1140
1141 if (BYTES_BIG_ENDIAN)
1142 {
1143 emit_insn (gen_altivec_vupkhsw (dest_v2di, src_v4si));
1144 emit_insn (gen_vsx_xxspltd_v2di (dest_v2di, dest_v2di, const1_rtx));
1145 }
1146 else
1147 {
1148 emit_insn (gen_altivec_vupklsw (dest_v2di, src_v4si));
1149 emit_insn (gen_vsx_xxspltd_v2di (dest_v2di, dest_v2di, const0_rtx));
1150 }
1151 DONE;
1152 })
1153
1154 (define_insn_and_split "*extendsi<mode>2_dot"
1155 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1156 (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
1157 (const_int 0)))
1158 (clobber (match_scratch:EXTSI 0 "=r,r"))]
1159 ""
1160 "@
1161 extsw. %0,%1
1162 #"
1163 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1164 [(set (match_dup 0)
1165 (sign_extend:EXTSI (match_dup 1)))
1166 (set (match_dup 2)
1167 (compare:CC (match_dup 0)
1168 (const_int 0)))]
1169 ""
1170 [(set_attr "type" "exts")
1171 (set_attr "dot" "yes")
1172 (set_attr "length" "4,8")])
1173
1174 (define_insn_and_split "*extendsi<mode>2_dot2"
1175 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1176 (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
1177 (const_int 0)))
1178 (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
1179 (sign_extend:EXTSI (match_dup 1)))]
1180 ""
1181 "@
1182 extsw. %0,%1
1183 #"
1184 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1185 [(set (match_dup 0)
1186 (sign_extend:EXTSI (match_dup 1)))
1187 (set (match_dup 2)
1188 (compare:CC (match_dup 0)
1189 (const_int 0)))]
1190 ""
1191 [(set_attr "type" "exts")
1192 (set_attr "dot" "yes")
1193 (set_attr "length" "4,8")])
1194 \f
1195 ;; IBM 405, 440, 464 and 476 half-word multiplication operations.
1196
1197 (define_insn "*macchwc"
1198 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1199 (compare:CC (plus:SI (mult:SI (ashiftrt:SI
1200 (match_operand:SI 2 "gpc_reg_operand" "r")
1201 (const_int 16))
1202 (sign_extend:SI
1203 (match_operand:HI 1 "gpc_reg_operand" "r")))
1204 (match_operand:SI 4 "gpc_reg_operand" "0"))
1205 (const_int 0)))
1206 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1207 (plus:SI (mult:SI (ashiftrt:SI
1208 (match_dup 2)
1209 (const_int 16))
1210 (sign_extend:SI
1211 (match_dup 1)))
1212 (match_dup 4)))]
1213 "TARGET_MULHW"
1214 "macchw. %0,%1,%2"
1215 [(set_attr "type" "halfmul")])
1216
1217 (define_insn "*macchw"
1218 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1219 (plus:SI (mult:SI (ashiftrt:SI
1220 (match_operand:SI 2 "gpc_reg_operand" "r")
1221 (const_int 16))
1222 (sign_extend:SI
1223 (match_operand:HI 1 "gpc_reg_operand" "r")))
1224 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1225 "TARGET_MULHW"
1226 "macchw %0,%1,%2"
1227 [(set_attr "type" "halfmul")])
1228
1229 (define_insn "*macchwuc"
1230 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1231 (compare:CC (plus:SI (mult:SI (lshiftrt:SI
1232 (match_operand:SI 2 "gpc_reg_operand" "r")
1233 (const_int 16))
1234 (zero_extend:SI
1235 (match_operand:HI 1 "gpc_reg_operand" "r")))
1236 (match_operand:SI 4 "gpc_reg_operand" "0"))
1237 (const_int 0)))
1238 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1239 (plus:SI (mult:SI (lshiftrt:SI
1240 (match_dup 2)
1241 (const_int 16))
1242 (zero_extend:SI
1243 (match_dup 1)))
1244 (match_dup 4)))]
1245 "TARGET_MULHW"
1246 "macchwu. %0,%1,%2"
1247 [(set_attr "type" "halfmul")])
1248
1249 (define_insn "*macchwu"
1250 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1251 (plus:SI (mult:SI (lshiftrt:SI
1252 (match_operand:SI 2 "gpc_reg_operand" "r")
1253 (const_int 16))
1254 (zero_extend:SI
1255 (match_operand:HI 1 "gpc_reg_operand" "r")))
1256 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1257 "TARGET_MULHW"
1258 "macchwu %0,%1,%2"
1259 [(set_attr "type" "halfmul")])
1260
1261 (define_insn "*machhwc"
1262 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1263 (compare:CC (plus:SI (mult:SI (ashiftrt:SI
1264 (match_operand:SI 1 "gpc_reg_operand" "%r")
1265 (const_int 16))
1266 (ashiftrt:SI
1267 (match_operand:SI 2 "gpc_reg_operand" "r")
1268 (const_int 16)))
1269 (match_operand:SI 4 "gpc_reg_operand" "0"))
1270 (const_int 0)))
1271 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1272 (plus:SI (mult:SI (ashiftrt:SI
1273 (match_dup 1)
1274 (const_int 16))
1275 (ashiftrt:SI
1276 (match_dup 2)
1277 (const_int 16)))
1278 (match_dup 4)))]
1279 "TARGET_MULHW"
1280 "machhw. %0,%1,%2"
1281 [(set_attr "type" "halfmul")])
1282
1283 (define_insn "*machhw"
1284 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1285 (plus:SI (mult:SI (ashiftrt:SI
1286 (match_operand:SI 1 "gpc_reg_operand" "%r")
1287 (const_int 16))
1288 (ashiftrt:SI
1289 (match_operand:SI 2 "gpc_reg_operand" "r")
1290 (const_int 16)))
1291 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1292 "TARGET_MULHW"
1293 "machhw %0,%1,%2"
1294 [(set_attr "type" "halfmul")])
1295
1296 (define_insn "*machhwuc"
1297 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1298 (compare:CC (plus:SI (mult:SI (lshiftrt:SI
1299 (match_operand:SI 1 "gpc_reg_operand" "%r")
1300 (const_int 16))
1301 (lshiftrt:SI
1302 (match_operand:SI 2 "gpc_reg_operand" "r")
1303 (const_int 16)))
1304 (match_operand:SI 4 "gpc_reg_operand" "0"))
1305 (const_int 0)))
1306 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1307 (plus:SI (mult:SI (lshiftrt:SI
1308 (match_dup 1)
1309 (const_int 16))
1310 (lshiftrt:SI
1311 (match_dup 2)
1312 (const_int 16)))
1313 (match_dup 4)))]
1314 "TARGET_MULHW"
1315 "machhwu. %0,%1,%2"
1316 [(set_attr "type" "halfmul")])
1317
1318 (define_insn "*machhwu"
1319 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1320 (plus:SI (mult:SI (lshiftrt:SI
1321 (match_operand:SI 1 "gpc_reg_operand" "%r")
1322 (const_int 16))
1323 (lshiftrt:SI
1324 (match_operand:SI 2 "gpc_reg_operand" "r")
1325 (const_int 16)))
1326 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1327 "TARGET_MULHW"
1328 "machhwu %0,%1,%2"
1329 [(set_attr "type" "halfmul")])
1330
1331 (define_insn "*maclhwc"
1332 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1333 (compare:CC (plus:SI (mult:SI (sign_extend:SI
1334 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1335 (sign_extend:SI
1336 (match_operand:HI 2 "gpc_reg_operand" "r")))
1337 (match_operand:SI 4 "gpc_reg_operand" "0"))
1338 (const_int 0)))
1339 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1340 (plus:SI (mult:SI (sign_extend:SI
1341 (match_dup 1))
1342 (sign_extend:SI
1343 (match_dup 2)))
1344 (match_dup 4)))]
1345 "TARGET_MULHW"
1346 "maclhw. %0,%1,%2"
1347 [(set_attr "type" "halfmul")])
1348
1349 (define_insn "*maclhw"
1350 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1351 (plus:SI (mult:SI (sign_extend:SI
1352 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1353 (sign_extend:SI
1354 (match_operand:HI 2 "gpc_reg_operand" "r")))
1355 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1356 "TARGET_MULHW"
1357 "maclhw %0,%1,%2"
1358 [(set_attr "type" "halfmul")])
1359
1360 (define_insn "*maclhwuc"
1361 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1362 (compare:CC (plus:SI (mult:SI (zero_extend:SI
1363 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1364 (zero_extend:SI
1365 (match_operand:HI 2 "gpc_reg_operand" "r")))
1366 (match_operand:SI 4 "gpc_reg_operand" "0"))
1367 (const_int 0)))
1368 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1369 (plus:SI (mult:SI (zero_extend:SI
1370 (match_dup 1))
1371 (zero_extend:SI
1372 (match_dup 2)))
1373 (match_dup 4)))]
1374 "TARGET_MULHW"
1375 "maclhwu. %0,%1,%2"
1376 [(set_attr "type" "halfmul")])
1377
1378 (define_insn "*maclhwu"
1379 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1380 (plus:SI (mult:SI (zero_extend:SI
1381 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1382 (zero_extend:SI
1383 (match_operand:HI 2 "gpc_reg_operand" "r")))
1384 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1385 "TARGET_MULHW"
1386 "maclhwu %0,%1,%2"
1387 [(set_attr "type" "halfmul")])
1388
1389 (define_insn "*nmacchwc"
1390 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1391 (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1392 (mult:SI (ashiftrt:SI
1393 (match_operand:SI 2 "gpc_reg_operand" "r")
1394 (const_int 16))
1395 (sign_extend:SI
1396 (match_operand:HI 1 "gpc_reg_operand" "r"))))
1397 (const_int 0)))
1398 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1399 (minus:SI (match_dup 4)
1400 (mult:SI (ashiftrt:SI
1401 (match_dup 2)
1402 (const_int 16))
1403 (sign_extend:SI
1404 (match_dup 1)))))]
1405 "TARGET_MULHW"
1406 "nmacchw. %0,%1,%2"
1407 [(set_attr "type" "halfmul")])
1408
1409 (define_insn "*nmacchw"
1410 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1411 (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1412 (mult:SI (ashiftrt:SI
1413 (match_operand:SI 2 "gpc_reg_operand" "r")
1414 (const_int 16))
1415 (sign_extend:SI
1416 (match_operand:HI 1 "gpc_reg_operand" "r")))))]
1417 "TARGET_MULHW"
1418 "nmacchw %0,%1,%2"
1419 [(set_attr "type" "halfmul")])
1420
1421 (define_insn "*nmachhwc"
1422 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1423 (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1424 (mult:SI (ashiftrt:SI
1425 (match_operand:SI 1 "gpc_reg_operand" "%r")
1426 (const_int 16))
1427 (ashiftrt:SI
1428 (match_operand:SI 2 "gpc_reg_operand" "r")
1429 (const_int 16))))
1430 (const_int 0)))
1431 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1432 (minus:SI (match_dup 4)
1433 (mult:SI (ashiftrt:SI
1434 (match_dup 1)
1435 (const_int 16))
1436 (ashiftrt:SI
1437 (match_dup 2)
1438 (const_int 16)))))]
1439 "TARGET_MULHW"
1440 "nmachhw. %0,%1,%2"
1441 [(set_attr "type" "halfmul")])
1442
1443 (define_insn "*nmachhw"
1444 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1445 (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1446 (mult:SI (ashiftrt:SI
1447 (match_operand:SI 1 "gpc_reg_operand" "%r")
1448 (const_int 16))
1449 (ashiftrt:SI
1450 (match_operand:SI 2 "gpc_reg_operand" "r")
1451 (const_int 16)))))]
1452 "TARGET_MULHW"
1453 "nmachhw %0,%1,%2"
1454 [(set_attr "type" "halfmul")])
1455
1456 (define_insn "*nmaclhwc"
1457 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1458 (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1459 (mult:SI (sign_extend:SI
1460 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1461 (sign_extend:SI
1462 (match_operand:HI 2 "gpc_reg_operand" "r"))))
1463 (const_int 0)))
1464 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1465 (minus:SI (match_dup 4)
1466 (mult:SI (sign_extend:SI
1467 (match_dup 1))
1468 (sign_extend:SI
1469 (match_dup 2)))))]
1470 "TARGET_MULHW"
1471 "nmaclhw. %0,%1,%2"
1472 [(set_attr "type" "halfmul")])
1473
1474 (define_insn "*nmaclhw"
1475 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1476 (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1477 (mult:SI (sign_extend:SI
1478 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1479 (sign_extend:SI
1480 (match_operand:HI 2 "gpc_reg_operand" "r")))))]
1481 "TARGET_MULHW"
1482 "nmaclhw %0,%1,%2"
1483 [(set_attr "type" "halfmul")])
1484
1485 (define_insn "*mulchwc"
1486 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1487 (compare:CC (mult:SI (ashiftrt:SI
1488 (match_operand:SI 2 "gpc_reg_operand" "r")
1489 (const_int 16))
1490 (sign_extend:SI
1491 (match_operand:HI 1 "gpc_reg_operand" "r")))
1492 (const_int 0)))
1493 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1494 (mult:SI (ashiftrt:SI
1495 (match_dup 2)
1496 (const_int 16))
1497 (sign_extend:SI
1498 (match_dup 1))))]
1499 "TARGET_MULHW"
1500 "mulchw. %0,%1,%2"
1501 [(set_attr "type" "halfmul")])
1502
1503 (define_insn "*mulchw"
1504 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1505 (mult:SI (ashiftrt:SI
1506 (match_operand:SI 2 "gpc_reg_operand" "r")
1507 (const_int 16))
1508 (sign_extend:SI
1509 (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1510 "TARGET_MULHW"
1511 "mulchw %0,%1,%2"
1512 [(set_attr "type" "halfmul")])
1513
1514 (define_insn "*mulchwuc"
1515 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1516 (compare:CC (mult:SI (lshiftrt:SI
1517 (match_operand:SI 2 "gpc_reg_operand" "r")
1518 (const_int 16))
1519 (zero_extend:SI
1520 (match_operand:HI 1 "gpc_reg_operand" "r")))
1521 (const_int 0)))
1522 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1523 (mult:SI (lshiftrt:SI
1524 (match_dup 2)
1525 (const_int 16))
1526 (zero_extend:SI
1527 (match_dup 1))))]
1528 "TARGET_MULHW"
1529 "mulchwu. %0,%1,%2"
1530 [(set_attr "type" "halfmul")])
1531
1532 (define_insn "*mulchwu"
1533 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1534 (mult:SI (lshiftrt:SI
1535 (match_operand:SI 2 "gpc_reg_operand" "r")
1536 (const_int 16))
1537 (zero_extend:SI
1538 (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1539 "TARGET_MULHW"
1540 "mulchwu %0,%1,%2"
1541 [(set_attr "type" "halfmul")])
1542
1543 (define_insn "*mulhhwc"
1544 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1545 (compare:CC (mult:SI (ashiftrt:SI
1546 (match_operand:SI 1 "gpc_reg_operand" "%r")
1547 (const_int 16))
1548 (ashiftrt:SI
1549 (match_operand:SI 2 "gpc_reg_operand" "r")
1550 (const_int 16)))
1551 (const_int 0)))
1552 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1553 (mult:SI (ashiftrt:SI
1554 (match_dup 1)
1555 (const_int 16))
1556 (ashiftrt:SI
1557 (match_dup 2)
1558 (const_int 16))))]
1559 "TARGET_MULHW"
1560 "mulhhw. %0,%1,%2"
1561 [(set_attr "type" "halfmul")])
1562
1563 (define_insn "*mulhhw"
1564 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1565 (mult:SI (ashiftrt:SI
1566 (match_operand:SI 1 "gpc_reg_operand" "%r")
1567 (const_int 16))
1568 (ashiftrt:SI
1569 (match_operand:SI 2 "gpc_reg_operand" "r")
1570 (const_int 16))))]
1571 "TARGET_MULHW"
1572 "mulhhw %0,%1,%2"
1573 [(set_attr "type" "halfmul")])
1574
1575 (define_insn "*mulhhwuc"
1576 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1577 (compare:CC (mult:SI (lshiftrt:SI
1578 (match_operand:SI 1 "gpc_reg_operand" "%r")
1579 (const_int 16))
1580 (lshiftrt:SI
1581 (match_operand:SI 2 "gpc_reg_operand" "r")
1582 (const_int 16)))
1583 (const_int 0)))
1584 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1585 (mult:SI (lshiftrt:SI
1586 (match_dup 1)
1587 (const_int 16))
1588 (lshiftrt:SI
1589 (match_dup 2)
1590 (const_int 16))))]
1591 "TARGET_MULHW"
1592 "mulhhwu. %0,%1,%2"
1593 [(set_attr "type" "halfmul")])
1594
1595 (define_insn "*mulhhwu"
1596 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1597 (mult:SI (lshiftrt:SI
1598 (match_operand:SI 1 "gpc_reg_operand" "%r")
1599 (const_int 16))
1600 (lshiftrt:SI
1601 (match_operand:SI 2 "gpc_reg_operand" "r")
1602 (const_int 16))))]
1603 "TARGET_MULHW"
1604 "mulhhwu %0,%1,%2"
1605 [(set_attr "type" "halfmul")])
1606
1607 (define_insn "*mullhwc"
1608 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1609 (compare:CC (mult:SI (sign_extend:SI
1610 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1611 (sign_extend:SI
1612 (match_operand:HI 2 "gpc_reg_operand" "r")))
1613 (const_int 0)))
1614 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1615 (mult:SI (sign_extend:SI
1616 (match_dup 1))
1617 (sign_extend:SI
1618 (match_dup 2))))]
1619 "TARGET_MULHW"
1620 "mullhw. %0,%1,%2"
1621 [(set_attr "type" "halfmul")])
1622
1623 (define_insn "*mullhw"
1624 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1625 (mult:SI (sign_extend:SI
1626 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1627 (sign_extend:SI
1628 (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1629 "TARGET_MULHW"
1630 "mullhw %0,%1,%2"
1631 [(set_attr "type" "halfmul")])
1632
1633 (define_insn "*mullhwuc"
1634 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1635 (compare:CC (mult:SI (zero_extend:SI
1636 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1637 (zero_extend:SI
1638 (match_operand:HI 2 "gpc_reg_operand" "r")))
1639 (const_int 0)))
1640 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1641 (mult:SI (zero_extend:SI
1642 (match_dup 1))
1643 (zero_extend:SI
1644 (match_dup 2))))]
1645 "TARGET_MULHW"
1646 "mullhwu. %0,%1,%2"
1647 [(set_attr "type" "halfmul")])
1648
1649 (define_insn "*mullhwu"
1650 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1651 (mult:SI (zero_extend:SI
1652 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1653 (zero_extend:SI
1654 (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1655 "TARGET_MULHW"
1656 "mullhwu %0,%1,%2"
1657 [(set_attr "type" "halfmul")])
1658 \f
1659 ;; IBM 405, 440, 464 and 476 string-search dlmzb instruction support.
1660 (define_insn "dlmzb"
1661 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1662 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
1663 (match_operand:SI 2 "gpc_reg_operand" "r")]
1664 UNSPEC_DLMZB_CR))
1665 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1666 (unspec:SI [(match_dup 1)
1667 (match_dup 2)]
1668 UNSPEC_DLMZB))]
1669 "TARGET_DLMZB"
1670 "dlmzb. %0,%1,%2")
1671
1672 (define_expand "strlensi"
1673 [(set (match_operand:SI 0 "gpc_reg_operand")
1674 (unspec:SI [(match_operand:BLK 1 "general_operand")
1675 (match_operand:QI 2 "const_int_operand")
1676 (match_operand 3 "const_int_operand")]
1677 UNSPEC_DLMZB_STRLEN))
1678 (clobber (match_scratch:CC 4))]
1679 "TARGET_DLMZB && WORDS_BIG_ENDIAN && !optimize_size"
1680 {
1681 rtx result = operands[0];
1682 rtx src = operands[1];
1683 rtx search_char = operands[2];
1684 rtx align = operands[3];
1685 rtx addr, scratch_string, word1, word2, scratch_dlmzb;
1686 rtx loop_label, end_label, mem, cr0, cond;
1687 if (search_char != const0_rtx
1688 || !CONST_INT_P (align)
1689 || INTVAL (align) < 8)
1690 FAIL;
1691 word1 = gen_reg_rtx (SImode);
1692 word2 = gen_reg_rtx (SImode);
1693 scratch_dlmzb = gen_reg_rtx (SImode);
1694 scratch_string = gen_reg_rtx (Pmode);
1695 loop_label = gen_label_rtx ();
1696 end_label = gen_label_rtx ();
1697 addr = force_reg (Pmode, XEXP (src, 0));
1698 emit_move_insn (scratch_string, addr);
1699 emit_label (loop_label);
1700 mem = change_address (src, SImode, scratch_string);
1701 emit_move_insn (word1, mem);
1702 emit_move_insn (word2, adjust_address (mem, SImode, 4));
1703 cr0 = gen_rtx_REG (CCmode, CR0_REGNO);
1704 emit_insn (gen_dlmzb (scratch_dlmzb, word1, word2, cr0));
1705 cond = gen_rtx_NE (VOIDmode, cr0, const0_rtx);
1706 emit_jump_insn (gen_rtx_SET (pc_rtx,
1707 gen_rtx_IF_THEN_ELSE (VOIDmode,
1708 cond,
1709 gen_rtx_LABEL_REF
1710 (VOIDmode,
1711 end_label),
1712 pc_rtx)));
1713 emit_insn (gen_addsi3 (scratch_string, scratch_string, GEN_INT (8)));
1714 emit_jump_insn (gen_rtx_SET (pc_rtx,
1715 gen_rtx_LABEL_REF (VOIDmode, loop_label)));
1716 emit_barrier ();
1717 emit_label (end_label);
1718 emit_insn (gen_addsi3 (scratch_string, scratch_string, scratch_dlmzb));
1719 emit_insn (gen_subsi3 (result, scratch_string, addr));
1720 emit_insn (gen_addsi3 (result, result, constm1_rtx));
1721 DONE;
1722 })
1723 \f
1724 ;; Fixed-point arithmetic insns.
1725
1726 (define_expand "add<mode>3"
1727 [(set (match_operand:SDI 0 "gpc_reg_operand")
1728 (plus:SDI (match_operand:SDI 1 "gpc_reg_operand")
1729 (match_operand:SDI 2 "reg_or_add_cint_operand")))]
1730 ""
1731 {
1732 if (<MODE>mode == DImode && !TARGET_POWERPC64)
1733 {
1734 rtx lo0 = gen_lowpart (SImode, operands[0]);
1735 rtx lo1 = gen_lowpart (SImode, operands[1]);
1736 rtx lo2 = gen_lowpart (SImode, operands[2]);
1737 rtx hi0 = gen_highpart (SImode, operands[0]);
1738 rtx hi1 = gen_highpart (SImode, operands[1]);
1739 rtx hi2 = gen_highpart_mode (SImode, DImode, operands[2]);
1740
1741 if (!reg_or_short_operand (lo2, SImode))
1742 lo2 = force_reg (SImode, lo2);
1743 if (!adde_operand (hi2, SImode))
1744 hi2 = force_reg (SImode, hi2);
1745
1746 emit_insn (gen_addsi3_carry (lo0, lo1, lo2));
1747 emit_insn (gen_addsi3_carry_in (hi0, hi1, hi2));
1748 DONE;
1749 }
1750
1751 if (CONST_INT_P (operands[2]) && !add_operand (operands[2], <MODE>mode))
1752 {
1753 rtx tmp = ((!can_create_pseudo_p ()
1754 || rtx_equal_p (operands[0], operands[1]))
1755 ? operands[0] : gen_reg_rtx (<MODE>mode));
1756
1757 /* Adding a constant to r0 is not a valid insn, so use a different
1758 strategy in that case. */
1759 if (reg_or_subregno (operands[1]) == 0 || reg_or_subregno (tmp) == 0)
1760 {
1761 if (operands[0] == operands[1])
1762 FAIL;
1763 rs6000_emit_move (operands[0], operands[2], <MODE>mode);
1764 emit_insn (gen_add<mode>3 (operands[0], operands[1], operands[0]));
1765 DONE;
1766 }
1767
1768 HOST_WIDE_INT val = INTVAL (operands[2]);
1769 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1770 HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1771
1772 if (<MODE>mode == DImode && !satisfies_constraint_L (GEN_INT (rest)))
1773 FAIL;
1774
1775 /* The ordering here is important for the prolog expander.
1776 When space is allocated from the stack, adding 'low' first may
1777 produce a temporary deallocation (which would be bad). */
1778 emit_insn (gen_add<mode>3 (tmp, operands[1], GEN_INT (rest)));
1779 emit_insn (gen_add<mode>3 (operands[0], tmp, GEN_INT (low)));
1780 DONE;
1781 }
1782 })
1783
1784 (define_insn "*add<mode>3"
1785 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r,r,r")
1786 (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b,b,b")
1787 (match_operand:GPR 2 "add_operand" "r,I,L,eI")))]
1788 ""
1789 "@
1790 add %0,%1,%2
1791 addi %0,%1,%2
1792 addis %0,%1,%v2
1793 addi %0,%1,%2"
1794 [(set_attr "type" "add")
1795 (set_attr "isa" "*,*,*,p10")])
1796
1797 (define_insn "*addsi3_high"
1798 [(set (match_operand:SI 0 "gpc_reg_operand" "=b")
1799 (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
1800 (high:SI (match_operand 2 "" ""))))]
1801 "TARGET_MACHO && !TARGET_64BIT"
1802 "addis %0,%1,ha16(%2)"
1803 [(set_attr "type" "add")])
1804
1805 (define_insn_and_split "*add<mode>3_dot"
1806 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1807 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
1808 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
1809 (const_int 0)))
1810 (clobber (match_scratch:GPR 0 "=r,r"))]
1811 "<MODE>mode == Pmode"
1812 "@
1813 add. %0,%1,%2
1814 #"
1815 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1816 [(set (match_dup 0)
1817 (plus:GPR (match_dup 1)
1818 (match_dup 2)))
1819 (set (match_dup 3)
1820 (compare:CC (match_dup 0)
1821 (const_int 0)))]
1822 ""
1823 [(set_attr "type" "add")
1824 (set_attr "dot" "yes")
1825 (set_attr "length" "4,8")])
1826
1827 (define_insn_and_split "*add<mode>3_dot2"
1828 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1829 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
1830 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
1831 (const_int 0)))
1832 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1833 (plus:GPR (match_dup 1)
1834 (match_dup 2)))]
1835 "<MODE>mode == Pmode"
1836 "@
1837 add. %0,%1,%2
1838 #"
1839 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1840 [(set (match_dup 0)
1841 (plus:GPR (match_dup 1)
1842 (match_dup 2)))
1843 (set (match_dup 3)
1844 (compare:CC (match_dup 0)
1845 (const_int 0)))]
1846 ""
1847 [(set_attr "type" "add")
1848 (set_attr "dot" "yes")
1849 (set_attr "length" "4,8")])
1850
1851 (define_insn_and_split "*add<mode>3_imm_dot"
1852 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1853 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b")
1854 (match_operand:GPR 2 "short_cint_operand" "I,I"))
1855 (const_int 0)))
1856 (clobber (match_scratch:GPR 0 "=r,r"))
1857 (clobber (reg:GPR CA_REGNO))]
1858 "<MODE>mode == Pmode"
1859 "@
1860 addic. %0,%1,%2
1861 #"
1862 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1863 [(set (match_dup 0)
1864 (plus:GPR (match_dup 1)
1865 (match_dup 2)))
1866 (set (match_dup 3)
1867 (compare:CC (match_dup 0)
1868 (const_int 0)))]
1869 ""
1870 [(set_attr "type" "add")
1871 (set_attr "dot" "yes")
1872 (set_attr "length" "4,8")])
1873
1874 (define_insn_and_split "*add<mode>3_imm_dot2"
1875 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1876 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b")
1877 (match_operand:GPR 2 "short_cint_operand" "I,I"))
1878 (const_int 0)))
1879 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1880 (plus:GPR (match_dup 1)
1881 (match_dup 2)))
1882 (clobber (reg:GPR CA_REGNO))]
1883 "<MODE>mode == Pmode"
1884 "@
1885 addic. %0,%1,%2
1886 #"
1887 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1888 [(set (match_dup 0)
1889 (plus:GPR (match_dup 1)
1890 (match_dup 2)))
1891 (set (match_dup 3)
1892 (compare:CC (match_dup 0)
1893 (const_int 0)))]
1894 ""
1895 [(set_attr "type" "add")
1896 (set_attr "dot" "yes")
1897 (set_attr "length" "4,8")])
1898
1899 ;; Split an add that we can't do in one insn into two insns, each of which
1900 ;; does one 16-bit part. This is used by combine. Note that the low-order
1901 ;; add should be last in case the result gets used in an address.
1902
1903 (define_split
1904 [(set (match_operand:GPR 0 "gpc_reg_operand")
1905 (plus:GPR (match_operand:GPR 1 "gpc_reg_operand")
1906 (match_operand:GPR 2 "non_add_cint_operand")))]
1907 ""
1908 [(set (match_dup 0) (plus:GPR (match_dup 1) (match_dup 3)))
1909 (set (match_dup 0) (plus:GPR (match_dup 0) (match_dup 4)))]
1910 {
1911 HOST_WIDE_INT val = INTVAL (operands[2]);
1912 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1913 HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1914
1915 operands[4] = GEN_INT (low);
1916 if (<MODE>mode == SImode || satisfies_constraint_L (GEN_INT (rest)))
1917 operands[3] = GEN_INT (rest);
1918 else if (can_create_pseudo_p ())
1919 {
1920 operands[3] = gen_reg_rtx (DImode);
1921 emit_move_insn (operands[3], operands[2]);
1922 emit_insn (gen_adddi3 (operands[0], operands[1], operands[3]));
1923 DONE;
1924 }
1925 else
1926 FAIL;
1927 })
1928
1929
1930 (define_insn "add<mode>3_carry"
1931 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1932 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1933 (match_operand:P 2 "reg_or_short_operand" "rI")))
1934 (set (reg:P CA_REGNO)
1935 (ltu:P (plus:P (match_dup 1)
1936 (match_dup 2))
1937 (match_dup 1)))]
1938 ""
1939 "add%I2c %0,%1,%2"
1940 [(set_attr "type" "add")])
1941
1942 (define_insn "*add<mode>3_imm_carry_pos"
1943 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1944 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1945 (match_operand:P 2 "short_cint_operand" "n")))
1946 (set (reg:P CA_REGNO)
1947 (geu:P (match_dup 1)
1948 (match_operand:P 3 "const_int_operand" "n")))]
1949 "INTVAL (operands[2]) > 0
1950 && INTVAL (operands[2]) + INTVAL (operands[3]) == 0"
1951 "addic %0,%1,%2"
1952 [(set_attr "type" "add")])
1953
1954 (define_insn "*add<mode>3_imm_carry_0"
1955 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1956 (match_operand:P 1 "gpc_reg_operand" "r"))
1957 (set (reg:P CA_REGNO)
1958 (const_int 0))]
1959 ""
1960 "addic %0,%1,0"
1961 [(set_attr "type" "add")])
1962
1963 (define_insn "*add<mode>3_imm_carry_m1"
1964 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1965 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1966 (const_int -1)))
1967 (set (reg:P CA_REGNO)
1968 (ne:P (match_dup 1)
1969 (const_int 0)))]
1970 ""
1971 "addic %0,%1,-1"
1972 [(set_attr "type" "add")])
1973
1974 (define_insn "*add<mode>3_imm_carry_neg"
1975 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1976 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1977 (match_operand:P 2 "short_cint_operand" "n")))
1978 (set (reg:P CA_REGNO)
1979 (gtu:P (match_dup 1)
1980 (match_operand:P 3 "const_int_operand" "n")))]
1981 "INTVAL (operands[2]) < 0
1982 && INTVAL (operands[2]) + INTVAL (operands[3]) == -1"
1983 "addic %0,%1,%2"
1984 [(set_attr "type" "add")])
1985
1986
1987 (define_expand "add<mode>3_carry_in"
1988 [(parallel [
1989 (set (match_operand:GPR 0 "gpc_reg_operand")
1990 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand")
1991 (match_operand:GPR 2 "adde_operand"))
1992 (reg:GPR CA_REGNO)))
1993 (clobber (reg:GPR CA_REGNO))])]
1994 ""
1995 {
1996 if (operands[2] == const0_rtx)
1997 {
1998 emit_insn (gen_add<mode>3_carry_in_0 (operands[0], operands[1]));
1999 DONE;
2000 }
2001 if (operands[2] == constm1_rtx)
2002 {
2003 emit_insn (gen_add<mode>3_carry_in_m1 (operands[0], operands[1]));
2004 DONE;
2005 }
2006 })
2007
2008 (define_insn "*add<mode>3_carry_in_internal"
2009 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2010 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
2011 (match_operand:GPR 2 "gpc_reg_operand" "r"))
2012 (reg:GPR CA_REGNO)))
2013 (clobber (reg:GPR CA_REGNO))]
2014 ""
2015 "adde %0,%1,%2"
2016 [(set_attr "type" "add")])
2017
2018 (define_insn "*add<mode>3_carry_in_internal2"
2019 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2020 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
2021 (reg:GPR CA_REGNO))
2022 (match_operand:GPR 2 "gpc_reg_operand" "r")))
2023 (clobber (reg:GPR CA_REGNO))]
2024 ""
2025 "adde %0,%1,%2"
2026 [(set_attr "type" "add")])
2027
2028 (define_insn "add<mode>3_carry_in_0"
2029 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2030 (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
2031 (reg:GPR CA_REGNO)))
2032 (clobber (reg:GPR CA_REGNO))]
2033 ""
2034 "addze %0,%1"
2035 [(set_attr "type" "add")])
2036
2037 (define_insn "add<mode>3_carry_in_m1"
2038 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2039 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
2040 (reg:GPR CA_REGNO))
2041 (const_int -1)))
2042 (clobber (reg:GPR CA_REGNO))]
2043 ""
2044 "addme %0,%1"
2045 [(set_attr "type" "add")])
2046
2047
2048 (define_expand "one_cmpl<mode>2"
2049 [(set (match_operand:SDI 0 "gpc_reg_operand")
2050 (not:SDI (match_operand:SDI 1 "gpc_reg_operand")))]
2051 ""
2052 {
2053 if (<MODE>mode == DImode && !TARGET_POWERPC64)
2054 {
2055 rs6000_split_logical (operands, NOT, false, false, false);
2056 DONE;
2057 }
2058 })
2059
2060 (define_insn "*one_cmpl<mode>2"
2061 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2062 (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2063 ""
2064 "not %0,%1")
2065
2066 (define_insn_and_split "*one_cmpl<mode>2_dot"
2067 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2068 (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2069 (const_int 0)))
2070 (clobber (match_scratch:GPR 0 "=r,r"))]
2071 "<MODE>mode == Pmode"
2072 "@
2073 not. %0,%1
2074 #"
2075 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2076 [(set (match_dup 0)
2077 (not:GPR (match_dup 1)))
2078 (set (match_dup 2)
2079 (compare:CC (match_dup 0)
2080 (const_int 0)))]
2081 ""
2082 [(set_attr "type" "logical")
2083 (set_attr "dot" "yes")
2084 (set_attr "length" "4,8")])
2085
2086 (define_insn_and_split "*one_cmpl<mode>2_dot2"
2087 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2088 (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2089 (const_int 0)))
2090 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2091 (not:GPR (match_dup 1)))]
2092 "<MODE>mode == Pmode"
2093 "@
2094 not. %0,%1
2095 #"
2096 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2097 [(set (match_dup 0)
2098 (not:GPR (match_dup 1)))
2099 (set (match_dup 2)
2100 (compare:CC (match_dup 0)
2101 (const_int 0)))]
2102 ""
2103 [(set_attr "type" "logical")
2104 (set_attr "dot" "yes")
2105 (set_attr "length" "4,8")])
2106
2107
2108 (define_expand "sub<mode>3"
2109 [(set (match_operand:SDI 0 "gpc_reg_operand")
2110 (minus:SDI (match_operand:SDI 1 "reg_or_short_operand")
2111 (match_operand:SDI 2 "gpc_reg_operand")))]
2112 ""
2113 {
2114 if (<MODE>mode == DImode && !TARGET_POWERPC64)
2115 {
2116 rtx lo0 = gen_lowpart (SImode, operands[0]);
2117 rtx lo1 = gen_lowpart (SImode, operands[1]);
2118 rtx lo2 = gen_lowpart (SImode, operands[2]);
2119 rtx hi0 = gen_highpart (SImode, operands[0]);
2120 rtx hi1 = gen_highpart_mode (SImode, DImode, operands[1]);
2121 rtx hi2 = gen_highpart (SImode, operands[2]);
2122
2123 if (!reg_or_short_operand (lo1, SImode))
2124 lo1 = force_reg (SImode, lo1);
2125 if (!adde_operand (hi1, SImode))
2126 hi1 = force_reg (SImode, hi1);
2127
2128 emit_insn (gen_subfsi3_carry (lo0, lo2, lo1));
2129 emit_insn (gen_subfsi3_carry_in (hi0, hi2, hi1));
2130 DONE;
2131 }
2132
2133 if (short_cint_operand (operands[1], <MODE>mode))
2134 {
2135 emit_insn (gen_subf<mode>3_imm (operands[0], operands[2], operands[1]));
2136 DONE;
2137 }
2138 })
2139
2140 (define_insn "*subf<mode>3"
2141 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2142 (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r")
2143 (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2144 ""
2145 "subf %0,%1,%2"
2146 [(set_attr "type" "add")])
2147
2148 (define_insn_and_split "*subf<mode>3_dot"
2149 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2150 (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
2151 (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2152 (const_int 0)))
2153 (clobber (match_scratch:GPR 0 "=r,r"))]
2154 "<MODE>mode == Pmode"
2155 "@
2156 subf. %0,%1,%2
2157 #"
2158 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2159 [(set (match_dup 0)
2160 (minus:GPR (match_dup 2)
2161 (match_dup 1)))
2162 (set (match_dup 3)
2163 (compare:CC (match_dup 0)
2164 (const_int 0)))]
2165 ""
2166 [(set_attr "type" "add")
2167 (set_attr "dot" "yes")
2168 (set_attr "length" "4,8")])
2169
2170 (define_insn_and_split "*subf<mode>3_dot2"
2171 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2172 (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
2173 (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2174 (const_int 0)))
2175 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2176 (minus:GPR (match_dup 2)
2177 (match_dup 1)))]
2178 "<MODE>mode == Pmode"
2179 "@
2180 subf. %0,%1,%2
2181 #"
2182 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2183 [(set (match_dup 0)
2184 (minus:GPR (match_dup 2)
2185 (match_dup 1)))
2186 (set (match_dup 3)
2187 (compare:CC (match_dup 0)
2188 (const_int 0)))]
2189 ""
2190 [(set_attr "type" "add")
2191 (set_attr "dot" "yes")
2192 (set_attr "length" "4,8")])
2193
2194 (define_insn "subf<mode>3_imm"
2195 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2196 (minus:GPR (match_operand:GPR 2 "short_cint_operand" "I")
2197 (match_operand:GPR 1 "gpc_reg_operand" "r")))
2198 (clobber (reg:GPR CA_REGNO))]
2199 ""
2200 "subfic %0,%1,%2"
2201 [(set_attr "type" "add")])
2202
2203 (define_insn_and_split "subf<mode>3_carry_dot2"
2204 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2205 (compare:CC (minus:P (match_operand:P 2 "gpc_reg_operand" "r,r")
2206 (match_operand:P 1 "gpc_reg_operand" "r,r"))
2207 (const_int 0)))
2208 (set (match_operand:P 0 "gpc_reg_operand" "=r,r")
2209 (minus:P (match_dup 2)
2210 (match_dup 1)))
2211 (set (reg:P CA_REGNO)
2212 (leu:P (match_dup 1)
2213 (match_dup 2)))]
2214 "<MODE>mode == Pmode"
2215 "@
2216 subfc. %0,%1,%2
2217 #"
2218 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2219 [(parallel [(set (match_dup 0)
2220 (minus:P (match_dup 2)
2221 (match_dup 1)))
2222 (set (reg:P CA_REGNO)
2223 (leu:P (match_dup 1)
2224 (match_dup 2)))])
2225 (set (match_dup 3)
2226 (compare:CC (match_dup 0)
2227 (const_int 0)))]
2228 ""
2229 [(set_attr "type" "add")
2230 (set_attr "dot" "yes")
2231 (set_attr "length" "4,8")])
2232
2233 (define_insn "subf<mode>3_carry"
2234 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2235 (minus:P (match_operand:P 2 "reg_or_short_operand" "rI")
2236 (match_operand:P 1 "gpc_reg_operand" "r")))
2237 (set (reg:P CA_REGNO)
2238 (leu:P (match_dup 1)
2239 (match_dup 2)))]
2240 ""
2241 "subf%I2c %0,%1,%2"
2242 [(set_attr "type" "add")])
2243
2244 (define_insn "*subf<mode>3_imm_carry_0"
2245 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2246 (neg:P (match_operand:P 1 "gpc_reg_operand" "r")))
2247 (set (reg:P CA_REGNO)
2248 (eq:P (match_dup 1)
2249 (const_int 0)))]
2250 ""
2251 "subfic %0,%1,0"
2252 [(set_attr "type" "add")])
2253
2254 (define_insn "*subf<mode>3_imm_carry_m1"
2255 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2256 (not:P (match_operand:P 1 "gpc_reg_operand" "r")))
2257 (set (reg:P CA_REGNO)
2258 (const_int 1))]
2259 ""
2260 "subfic %0,%1,-1"
2261 [(set_attr "type" "add")])
2262
2263
2264 (define_expand "subf<mode>3_carry_in"
2265 [(parallel [
2266 (set (match_operand:GPR 0 "gpc_reg_operand")
2267 (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand"))
2268 (reg:GPR CA_REGNO))
2269 (match_operand:GPR 2 "adde_operand")))
2270 (clobber (reg:GPR CA_REGNO))])]
2271 ""
2272 {
2273 if (operands[2] == const0_rtx)
2274 {
2275 emit_insn (gen_subf<mode>3_carry_in_0 (operands[0], operands[1]));
2276 DONE;
2277 }
2278 if (operands[2] == constm1_rtx)
2279 {
2280 emit_insn (gen_subf<mode>3_carry_in_m1 (operands[0], operands[1]));
2281 DONE;
2282 }
2283 })
2284
2285 (define_insn "*subf<mode>3_carry_in_internal"
2286 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2287 (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
2288 (reg:GPR CA_REGNO))
2289 (match_operand:GPR 2 "gpc_reg_operand" "r")))
2290 (clobber (reg:GPR CA_REGNO))]
2291 ""
2292 "subfe %0,%1,%2"
2293 [(set_attr "type" "add")])
2294
2295 (define_insn "subf<mode>3_carry_in_0"
2296 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2297 (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
2298 (reg:GPR CA_REGNO)))
2299 (clobber (reg:GPR CA_REGNO))]
2300 ""
2301 "subfze %0,%1"
2302 [(set_attr "type" "add")])
2303
2304 (define_insn "subf<mode>3_carry_in_m1"
2305 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2306 (plus:GPR (minus:GPR (reg:GPR CA_REGNO)
2307 (match_operand:GPR 1 "gpc_reg_operand" "r"))
2308 (const_int -2)))
2309 (clobber (reg:GPR CA_REGNO))]
2310 ""
2311 "subfme %0,%1"
2312 [(set_attr "type" "add")])
2313
2314 (define_insn "subf<mode>3_carry_in_xx"
2315 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2316 (plus:GPR (reg:GPR CA_REGNO)
2317 (const_int -1)))
2318 (clobber (reg:GPR CA_REGNO))]
2319 ""
2320 "subfe %0,%0,%0"
2321 [(set_attr "type" "add")])
2322
2323
2324 (define_insn "@neg<mode>2"
2325 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2326 (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2327 ""
2328 "neg %0,%1"
2329 [(set_attr "type" "add")])
2330
2331 (define_insn_and_split "*neg<mode>2_dot"
2332 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2333 (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2334 (const_int 0)))
2335 (clobber (match_scratch:GPR 0 "=r,r"))]
2336 "<MODE>mode == Pmode"
2337 "@
2338 neg. %0,%1
2339 #"
2340 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2341 [(set (match_dup 0)
2342 (neg:GPR (match_dup 1)))
2343 (set (match_dup 2)
2344 (compare:CC (match_dup 0)
2345 (const_int 0)))]
2346 ""
2347 [(set_attr "type" "add")
2348 (set_attr "dot" "yes")
2349 (set_attr "length" "4,8")])
2350
2351 (define_insn_and_split "*neg<mode>2_dot2"
2352 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2353 (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2354 (const_int 0)))
2355 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2356 (neg:GPR (match_dup 1)))]
2357 "<MODE>mode == Pmode"
2358 "@
2359 neg. %0,%1
2360 #"
2361 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2362 [(set (match_dup 0)
2363 (neg:GPR (match_dup 1)))
2364 (set (match_dup 2)
2365 (compare:CC (match_dup 0)
2366 (const_int 0)))]
2367 ""
2368 [(set_attr "type" "add")
2369 (set_attr "dot" "yes")
2370 (set_attr "length" "4,8")])
2371
2372
2373 (define_insn "clz<mode>2"
2374 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2375 (clz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2376 ""
2377 "cntlz<wd> %0,%1"
2378 [(set_attr "type" "cntlz")])
2379
2380 (define_expand "ctz<mode>2"
2381 [(set (match_operand:GPR 0 "gpc_reg_operand")
2382 (ctz:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2383 ""
2384 {
2385 if (TARGET_CTZ)
2386 {
2387 emit_insn (gen_ctz<mode>2_hw (operands[0], operands[1]));
2388 DONE;
2389 }
2390
2391 rtx tmp1 = gen_reg_rtx (<MODE>mode);
2392 rtx tmp2 = gen_reg_rtx (<MODE>mode);
2393 rtx tmp3 = gen_reg_rtx (<MODE>mode);
2394
2395 if (TARGET_POPCNTD)
2396 {
2397 emit_insn (gen_add<mode>3 (tmp1, operands[1], constm1_rtx));
2398 emit_insn (gen_one_cmpl<mode>2 (tmp2, operands[1]));
2399 emit_insn (gen_and<mode>3 (tmp3, tmp1, tmp2));
2400 emit_insn (gen_popcntd<mode>2 (operands[0], tmp3));
2401 }
2402 else
2403 {
2404 emit_insn (gen_neg<mode>2 (tmp1, operands[1]));
2405 emit_insn (gen_and<mode>3 (tmp2, operands[1], tmp1));
2406 emit_insn (gen_clz<mode>2 (tmp3, tmp2));
2407 emit_insn (gen_sub<mode>3 (operands[0], GEN_INT (<bits> - 1), tmp3));
2408 }
2409
2410 DONE;
2411 })
2412
2413 (define_insn "ctz<mode>2_hw"
2414 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2415 (ctz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2416 "TARGET_CTZ"
2417 "cnttz<wd> %0,%1"
2418 [(set_attr "type" "cntlz")])
2419
2420 (define_expand "ffs<mode>2"
2421 [(set (match_operand:GPR 0 "gpc_reg_operand")
2422 (ffs:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2423 ""
2424 {
2425 rtx tmp1 = gen_reg_rtx (<MODE>mode);
2426 rtx tmp2 = gen_reg_rtx (<MODE>mode);
2427 rtx tmp3 = gen_reg_rtx (<MODE>mode);
2428 emit_insn (gen_neg<mode>2 (tmp1, operands[1]));
2429 emit_insn (gen_and<mode>3 (tmp2, operands[1], tmp1));
2430 emit_insn (gen_clz<mode>2 (tmp3, tmp2));
2431 emit_insn (gen_sub<mode>3 (operands[0], GEN_INT (<bits>), tmp3));
2432 DONE;
2433 })
2434
2435
2436 (define_expand "popcount<mode>2"
2437 [(set (match_operand:GPR 0 "gpc_reg_operand")
2438 (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2439 "TARGET_POPCNTB || TARGET_POPCNTD"
2440 {
2441 rs6000_emit_popcount (operands[0], operands[1]);
2442 DONE;
2443 })
2444
2445 (define_insn "popcntb<mode>2"
2446 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2447 (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")]
2448 UNSPEC_POPCNTB))]
2449 "TARGET_POPCNTB"
2450 "popcntb %0,%1"
2451 [(set_attr "type" "popcnt")])
2452
2453 (define_insn "popcntd<mode>2"
2454 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2455 (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2456 "TARGET_POPCNTD"
2457 "popcnt<wd> %0,%1"
2458 [(set_attr "type" "popcnt")])
2459
2460
2461 (define_expand "parity<mode>2"
2462 [(set (match_operand:GPR 0 "gpc_reg_operand")
2463 (parity:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2464 "TARGET_POPCNTB"
2465 {
2466 rs6000_emit_parity (operands[0], operands[1]);
2467 DONE;
2468 })
2469
2470 (define_insn "parity<mode>2_cmpb"
2471 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2472 (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")] UNSPEC_PARITY))]
2473 "TARGET_CMPB && TARGET_POPCNTB"
2474 "prty<wd> %0,%1"
2475 [(set_attr "type" "popcnt")])
2476
2477 (define_insn "cfuged"
2478 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2479 (unspec:DI [(match_operand:DI 1 "gpc_reg_operand" "r")
2480 (match_operand:DI 2 "gpc_reg_operand" "r")]
2481 UNSPEC_CFUGED))]
2482 "TARGET_POWER10 && TARGET_64BIT"
2483 "cfuged %0,%1,%2"
2484 [(set_attr "type" "integer")])
2485
2486 (define_insn "cntlzdm"
2487 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2488 (unspec:DI [(match_operand:DI 1 "gpc_reg_operand" "r")
2489 (match_operand:DI 2 "gpc_reg_operand" "r")]
2490 UNSPEC_CNTLZDM))]
2491 "TARGET_POWER10 && TARGET_POWERPC64"
2492 "cntlzdm %0,%1,%2"
2493 [(set_attr "type" "integer")])
2494
2495 (define_insn "cnttzdm"
2496 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2497 (unspec:DI [(match_operand:DI 1 "gpc_reg_operand" "r")
2498 (match_operand:DI 2 "gpc_reg_operand" "r")]
2499 UNSPEC_CNTTZDM))]
2500 "TARGET_POWER10 && TARGET_POWERPC64"
2501 "cnttzdm %0,%1,%2"
2502 [(set_attr "type" "integer")])
2503
2504 (define_insn "pdepd"
2505 [(set (match_operand:DI 0 "register_operand" "=r")
2506 (unspec:DI [(match_operand:DI 1 "gpc_reg_operand" "r")
2507 (match_operand:DI 2 "gpc_reg_operand" "r")]
2508 UNSPEC_PDEPD))]
2509 "TARGET_POWER10 && TARGET_POWERPC64"
2510 "pdepd %0,%1,%2"
2511 [(set_attr "type" "integer")])
2512
2513 (define_insn "pextd"
2514 [(set (match_operand:DI 0 "register_operand" "=r")
2515 (unspec:DI [(match_operand:DI 1 "gpc_reg_operand" "r")
2516 (match_operand:DI 2 "gpc_reg_operand" "r")]
2517 UNSPEC_PEXTD))]
2518 "TARGET_POWER10 && TARGET_POWERPC64"
2519 "pextd %0,%1,%2"
2520 [(set_attr "type" "integer")])
2521
2522 (define_insn "cmpb<mode>3"
2523 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2524 (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")
2525 (match_operand:GPR 2 "gpc_reg_operand" "r")] UNSPEC_CMPB))]
2526 "TARGET_CMPB"
2527 "cmpb %0,%1,%2"
2528 [(set_attr "type" "cmp")])
2529
2530 ;; Since the hardware zeros the upper part of the register, save generating the
2531 ;; AND immediate if we are converting to unsigned
2532 (define_insn "*bswap<mode>2_extenddi"
2533 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2534 (zero_extend:DI
2535 (bswap:HSI (match_operand:HSI 1 "memory_operand" "Z"))))]
2536 "TARGET_POWERPC64"
2537 "l<wd>brx %0,%y1"
2538 [(set_attr "type" "load")])
2539
2540 (define_insn "*bswaphi2_extendsi"
2541 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2542 (zero_extend:SI
2543 (bswap:HI (match_operand:HI 1 "memory_operand" "Z"))))]
2544 ""
2545 "lhbrx %0,%y1"
2546 [(set_attr "type" "load")])
2547
2548 ;; Separate the bswap patterns into load, store, and gpr<-gpr. This prevents
2549 ;; the register allocator from converting a gpr<-gpr swap into a store and then
2550 ;; load with byte swap, which can be slower than doing it in the registers. It
2551 ;; also prevents certain failures with the RELOAD register allocator.
2552
2553 (define_expand "bswap<mode>2"
2554 [(use (match_operand:HSI 0 "reg_or_mem_operand"))
2555 (use (match_operand:HSI 1 "reg_or_mem_operand"))]
2556 ""
2557 {
2558 rtx dest = operands[0];
2559 rtx src = operands[1];
2560
2561 if (!REG_P (dest) && !REG_P (src))
2562 src = force_reg (<MODE>mode, src);
2563
2564 if (MEM_P (src))
2565 {
2566 src = rs6000_force_indexed_or_indirect_mem (src);
2567 emit_insn (gen_bswap<mode>2_load (dest, src));
2568 }
2569 else if (MEM_P (dest))
2570 {
2571 dest = rs6000_force_indexed_or_indirect_mem (dest);
2572 emit_insn (gen_bswap<mode>2_store (dest, src));
2573 }
2574 else
2575 emit_insn (gen_bswap<mode>2_reg (dest, src));
2576 DONE;
2577 })
2578
2579 (define_insn "bswap<mode>2_load"
2580 [(set (match_operand:HSI 0 "gpc_reg_operand" "=r")
2581 (bswap:HSI (match_operand:HSI 1 "memory_operand" "Z")))]
2582 ""
2583 "l<wd>brx %0,%y1"
2584 [(set_attr "type" "load")])
2585
2586 (define_insn "bswap<mode>2_store"
2587 [(set (match_operand:HSI 0 "memory_operand" "=Z")
2588 (bswap:HSI (match_operand:HSI 1 "gpc_reg_operand" "r")))]
2589 ""
2590 "st<wd>brx %1,%y0"
2591 [(set_attr "type" "store")])
2592
2593 (define_insn_and_split "bswaphi2_reg"
2594 [(set (match_operand:HI 0 "gpc_reg_operand" "=r,&r,wa")
2595 (bswap:HI
2596 (match_operand:HI 1 "gpc_reg_operand" "r,r,wa")))
2597 (clobber (match_scratch:SI 2 "=X,&r,X"))]
2598 ""
2599 "@
2600 brh %0,%1
2601 #
2602 xxbrh %x0,%x1"
2603 "reload_completed && !TARGET_POWER10 && int_reg_operand (operands[0], HImode)"
2604 [(set (match_dup 3)
2605 (and:SI (lshiftrt:SI (match_dup 4)
2606 (const_int 8))
2607 (const_int 255)))
2608 (set (match_dup 2)
2609 (and:SI (ashift:SI (match_dup 4)
2610 (const_int 8))
2611 (const_int 65280))) ;; 0xff00
2612 (set (match_dup 3)
2613 (ior:SI (match_dup 3)
2614 (match_dup 2)))]
2615 {
2616 operands[3] = simplify_gen_subreg (SImode, operands[0], HImode, 0);
2617 operands[4] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
2618 }
2619 [(set_attr "length" "*,12,*")
2620 (set_attr "type" "shift,*,vecperm")
2621 (set_attr "isa" "p10,*,p9v")])
2622
2623 ;; We are always BITS_BIG_ENDIAN, so the bit positions below in
2624 ;; zero_extract insns do not change for -mlittle.
2625 (define_insn_and_split "bswapsi2_reg"
2626 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,&r,wa")
2627 (bswap:SI
2628 (match_operand:SI 1 "gpc_reg_operand" "r,r,wa")))]
2629 ""
2630 "@
2631 brw %0,%1
2632 #
2633 xxbrw %x0,%x1"
2634 "reload_completed && !TARGET_POWER10 && int_reg_operand (operands[0], SImode)"
2635 [(set (match_dup 0) ; DABC
2636 (rotate:SI (match_dup 1)
2637 (const_int 24)))
2638 (set (match_dup 0) ; DCBC
2639 (ior:SI (and:SI (ashift:SI (match_dup 1)
2640 (const_int 8))
2641 (const_int 16711680))
2642 (and:SI (match_dup 0)
2643 (const_int -16711681))))
2644 (set (match_dup 0) ; DCBA
2645 (ior:SI (and:SI (lshiftrt:SI (match_dup 1)
2646 (const_int 24))
2647 (const_int 255))
2648 (and:SI (match_dup 0)
2649 (const_int -256))))]
2650 ""
2651 [(set_attr "length" "4,12,4")
2652 (set_attr "type" "shift,*,vecperm")
2653 (set_attr "isa" "p10,*,p9v")])
2654
2655 ;; On systems with LDBRX/STDBRX generate the loads/stores directly, just like
2656 ;; we do for L{H,W}BRX and ST{H,W}BRX above. If not, we have to generate more
2657 ;; complex code.
2658
2659 (define_expand "bswapdi2"
2660 [(parallel [(set (match_operand:DI 0 "reg_or_mem_operand")
2661 (bswap:DI
2662 (match_operand:DI 1 "reg_or_mem_operand")))
2663 (clobber (match_scratch:DI 2))
2664 (clobber (match_scratch:DI 3))])]
2665 ""
2666 {
2667 rtx dest = operands[0];
2668 rtx src = operands[1];
2669
2670 if (!REG_P (dest) && !REG_P (src))
2671 operands[1] = src = force_reg (DImode, src);
2672
2673 if (TARGET_POWERPC64 && TARGET_LDBRX)
2674 {
2675 if (MEM_P (src))
2676 {
2677 src = rs6000_force_indexed_or_indirect_mem (src);
2678 emit_insn (gen_bswapdi2_load (dest, src));
2679 }
2680 else if (MEM_P (dest))
2681 {
2682 dest = rs6000_force_indexed_or_indirect_mem (dest);
2683 emit_insn (gen_bswapdi2_store (dest, src));
2684 }
2685 else if (TARGET_P9_VECTOR)
2686 emit_insn (gen_bswapdi2_brd (dest, src));
2687 else
2688 emit_insn (gen_bswapdi2_reg (dest, src));
2689 DONE;
2690 }
2691
2692 if (!TARGET_POWERPC64)
2693 {
2694 /* 32-bit mode needs fewer scratch registers, but 32-bit addressing mode
2695 that uses 64-bit registers needs the same scratch registers as 64-bit
2696 mode. */
2697 emit_insn (gen_bswapdi2_32bit (dest, src));
2698 DONE;
2699 }
2700 })
2701
2702 ;; Power7/cell has ldbrx/stdbrx, so use it directly
2703 (define_insn "bswapdi2_load"
2704 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2705 (bswap:DI (match_operand:DI 1 "memory_operand" "Z")))]
2706 "TARGET_POWERPC64 && TARGET_LDBRX"
2707 "ldbrx %0,%y1"
2708 [(set_attr "type" "load")])
2709
2710 (define_insn "bswapdi2_store"
2711 [(set (match_operand:DI 0 "memory_operand" "=Z")
2712 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "r")))]
2713 "TARGET_POWERPC64 && TARGET_LDBRX"
2714 "stdbrx %1,%y0"
2715 [(set_attr "type" "store")])
2716
2717 (define_insn "bswapdi2_brd"
2718 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,wa")
2719 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "r,wa")))]
2720 "TARGET_P9_VECTOR"
2721 "@
2722 brd %0,%1
2723 xxbrd %x0,%x1"
2724 [(set_attr "type" "shift,vecperm")
2725 (set_attr "isa" "p10,p9v")])
2726
2727 (define_insn "bswapdi2_reg"
2728 [(set (match_operand:DI 0 "gpc_reg_operand" "=&r")
2729 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "r")))
2730 (clobber (match_scratch:DI 2 "=&r"))
2731 (clobber (match_scratch:DI 3 "=&r"))]
2732 "TARGET_POWERPC64 && TARGET_LDBRX && !TARGET_P9_VECTOR"
2733 "#"
2734 [(set_attr "length" "36")])
2735
2736 ;; Non-power7/cell, fall back to use lwbrx/stwbrx
2737 (define_insn "*bswapdi2_64bit"
2738 [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,&r")
2739 (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2740 (clobber (match_scratch:DI 2 "=&b,&b,&r"))
2741 (clobber (match_scratch:DI 3 "=&r,&r,&r"))]
2742 "TARGET_POWERPC64 && !TARGET_LDBRX
2743 && (REG_P (operands[0]) || REG_P (operands[1]))
2744 && !(MEM_P (operands[0]) && MEM_VOLATILE_P (operands[0]))
2745 && !(MEM_P (operands[1]) && MEM_VOLATILE_P (operands[1]))"
2746 "#"
2747 [(set_attr "length" "16,12,36")])
2748
2749 (define_split
2750 [(set (match_operand:DI 0 "gpc_reg_operand")
2751 (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand")))
2752 (clobber (match_operand:DI 2 "gpc_reg_operand"))
2753 (clobber (match_operand:DI 3 "gpc_reg_operand"))]
2754 "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2755 [(const_int 0)]
2756 {
2757 rtx dest = operands[0];
2758 rtx src = operands[1];
2759 rtx op2 = operands[2];
2760 rtx op3 = operands[3];
2761 rtx op3_32 = simplify_gen_subreg (SImode, op3, DImode,
2762 BYTES_BIG_ENDIAN ? 4 : 0);
2763 rtx dest_32 = simplify_gen_subreg (SImode, dest, DImode,
2764 BYTES_BIG_ENDIAN ? 4 : 0);
2765 rtx addr1;
2766 rtx addr2;
2767 rtx word1;
2768 rtx word2;
2769
2770 addr1 = XEXP (src, 0);
2771 if (GET_CODE (addr1) == PLUS)
2772 {
2773 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2774 if (TARGET_AVOID_XFORM)
2775 {
2776 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2777 addr2 = op2;
2778 }
2779 else
2780 addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2781 }
2782 else if (TARGET_AVOID_XFORM)
2783 {
2784 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2785 addr2 = op2;
2786 }
2787 else
2788 {
2789 emit_move_insn (op2, GEN_INT (4));
2790 addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2791 }
2792
2793 word1 = change_address (src, SImode, addr1);
2794 word2 = change_address (src, SImode, addr2);
2795
2796 if (BYTES_BIG_ENDIAN)
2797 {
2798 emit_insn (gen_bswapsi2 (op3_32, word2));
2799 emit_insn (gen_bswapsi2 (dest_32, word1));
2800 }
2801 else
2802 {
2803 emit_insn (gen_bswapsi2 (op3_32, word1));
2804 emit_insn (gen_bswapsi2 (dest_32, word2));
2805 }
2806
2807 emit_insn (gen_ashldi3 (op3, op3, GEN_INT (32)));
2808 emit_insn (gen_iordi3 (dest, dest, op3));
2809 DONE;
2810 })
2811
2812 (define_split
2813 [(set (match_operand:DI 0 "indexed_or_indirect_operand")
2814 (bswap:DI (match_operand:DI 1 "gpc_reg_operand")))
2815 (clobber (match_operand:DI 2 "gpc_reg_operand"))
2816 (clobber (match_operand:DI 3 "gpc_reg_operand"))]
2817 "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2818 [(const_int 0)]
2819 {
2820 rtx dest = operands[0];
2821 rtx src = operands[1];
2822 rtx op2 = operands[2];
2823 rtx op3 = operands[3];
2824 rtx src_si = simplify_gen_subreg (SImode, src, DImode,
2825 BYTES_BIG_ENDIAN ? 4 : 0);
2826 rtx op3_si = simplify_gen_subreg (SImode, op3, DImode,
2827 BYTES_BIG_ENDIAN ? 4 : 0);
2828 rtx addr1;
2829 rtx addr2;
2830 rtx word1;
2831 rtx word2;
2832
2833 addr1 = XEXP (dest, 0);
2834 if (GET_CODE (addr1) == PLUS)
2835 {
2836 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2837 if (TARGET_AVOID_XFORM)
2838 {
2839 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2840 addr2 = op2;
2841 }
2842 else
2843 addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2844 }
2845 else if (TARGET_AVOID_XFORM)
2846 {
2847 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2848 addr2 = op2;
2849 }
2850 else
2851 {
2852 emit_move_insn (op2, GEN_INT (4));
2853 addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2854 }
2855
2856 word1 = change_address (dest, SImode, addr1);
2857 word2 = change_address (dest, SImode, addr2);
2858
2859 emit_insn (gen_lshrdi3 (op3, src, GEN_INT (32)));
2860
2861 if (BYTES_BIG_ENDIAN)
2862 {
2863 emit_insn (gen_bswapsi2 (word1, src_si));
2864 emit_insn (gen_bswapsi2 (word2, op3_si));
2865 }
2866 else
2867 {
2868 emit_insn (gen_bswapsi2 (word2, src_si));
2869 emit_insn (gen_bswapsi2 (word1, op3_si));
2870 }
2871 DONE;
2872 })
2873
2874 (define_split
2875 [(set (match_operand:DI 0 "gpc_reg_operand")
2876 (bswap:DI (match_operand:DI 1 "gpc_reg_operand")))
2877 (clobber (match_operand:DI 2 "gpc_reg_operand"))
2878 (clobber (match_operand:DI 3 "gpc_reg_operand"))]
2879 "TARGET_POWERPC64 && !TARGET_P9_VECTOR && reload_completed"
2880 [(const_int 0)]
2881 {
2882 rtx dest = operands[0];
2883 rtx src = operands[1];
2884 rtx op2 = operands[2];
2885 rtx op3 = operands[3];
2886 int lo_off = BYTES_BIG_ENDIAN ? 4 : 0;
2887 rtx dest_si = simplify_gen_subreg (SImode, dest, DImode, lo_off);
2888 rtx src_si = simplify_gen_subreg (SImode, src, DImode, lo_off);
2889 rtx op2_si = simplify_gen_subreg (SImode, op2, DImode, lo_off);
2890 rtx op3_si = simplify_gen_subreg (SImode, op3, DImode, lo_off);
2891
2892 emit_insn (gen_lshrdi3 (op2, src, GEN_INT (32)));
2893 emit_insn (gen_bswapsi2 (dest_si, src_si));
2894 emit_insn (gen_bswapsi2 (op3_si, op2_si));
2895 emit_insn (gen_ashldi3 (dest, dest, GEN_INT (32)));
2896 emit_insn (gen_iordi3 (dest, dest, op3));
2897 DONE;
2898 })
2899
2900 (define_insn "bswapdi2_32bit"
2901 [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,?&r")
2902 (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2903 (clobber (match_scratch:SI 2 "=&b,&b,X"))]
2904 "!TARGET_POWERPC64 && (REG_P (operands[0]) || REG_P (operands[1]))"
2905 "#"
2906 [(set_attr "length" "16,12,36")])
2907
2908 (define_split
2909 [(set (match_operand:DI 0 "gpc_reg_operand")
2910 (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand")))
2911 (clobber (match_operand:SI 2 "gpc_reg_operand"))]
2912 "!TARGET_POWERPC64 && reload_completed"
2913 [(const_int 0)]
2914 {
2915 rtx dest = operands[0];
2916 rtx src = operands[1];
2917 rtx op2 = operands[2];
2918 rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
2919 rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
2920 rtx addr1;
2921 rtx addr2;
2922 rtx word1;
2923 rtx word2;
2924
2925 addr1 = XEXP (src, 0);
2926 if (GET_CODE (addr1) == PLUS)
2927 {
2928 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2929 if (TARGET_AVOID_XFORM
2930 || REGNO (XEXP (addr1, 1)) == REGNO (dest2))
2931 {
2932 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2933 addr2 = op2;
2934 }
2935 else
2936 addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
2937 }
2938 else if (TARGET_AVOID_XFORM
2939 || REGNO (addr1) == REGNO (dest2))
2940 {
2941 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2942 addr2 = op2;
2943 }
2944 else
2945 {
2946 emit_move_insn (op2, GEN_INT (4));
2947 addr2 = gen_rtx_PLUS (SImode, op2, addr1);
2948 }
2949
2950 word1 = change_address (src, SImode, addr1);
2951 word2 = change_address (src, SImode, addr2);
2952
2953 emit_insn (gen_bswapsi2 (dest2, word1));
2954 /* The REGNO (dest2) tests above ensure that addr2 has not been trashed,
2955 thus allowing us to omit an early clobber on the output. */
2956 emit_insn (gen_bswapsi2 (dest1, word2));
2957 DONE;
2958 })
2959
2960 (define_split
2961 [(set (match_operand:DI 0 "indexed_or_indirect_operand")
2962 (bswap:DI (match_operand:DI 1 "gpc_reg_operand")))
2963 (clobber (match_operand:SI 2 "gpc_reg_operand"))]
2964 "!TARGET_POWERPC64 && reload_completed"
2965 [(const_int 0)]
2966 {
2967 rtx dest = operands[0];
2968 rtx src = operands[1];
2969 rtx op2 = operands[2];
2970 rtx src1 = simplify_gen_subreg (SImode, src, DImode, 0);
2971 rtx src2 = simplify_gen_subreg (SImode, src, DImode, 4);
2972 rtx addr1;
2973 rtx addr2;
2974 rtx word1;
2975 rtx word2;
2976
2977 addr1 = XEXP (dest, 0);
2978 if (GET_CODE (addr1) == PLUS)
2979 {
2980 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2981 if (TARGET_AVOID_XFORM)
2982 {
2983 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2984 addr2 = op2;
2985 }
2986 else
2987 addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
2988 }
2989 else if (TARGET_AVOID_XFORM)
2990 {
2991 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2992 addr2 = op2;
2993 }
2994 else
2995 {
2996 emit_move_insn (op2, GEN_INT (4));
2997 addr2 = gen_rtx_PLUS (SImode, op2, addr1);
2998 }
2999
3000 word1 = change_address (dest, SImode, addr1);
3001 word2 = change_address (dest, SImode, addr2);
3002
3003 emit_insn (gen_bswapsi2 (word2, src1));
3004 emit_insn (gen_bswapsi2 (word1, src2));
3005 DONE;
3006 })
3007
3008 (define_split
3009 [(set (match_operand:DI 0 "gpc_reg_operand")
3010 (bswap:DI (match_operand:DI 1 "gpc_reg_operand")))
3011 (clobber (match_operand:SI 2 ""))]
3012 "!TARGET_POWERPC64 && reload_completed"
3013 [(const_int 0)]
3014 {
3015 rtx dest = operands[0];
3016 rtx src = operands[1];
3017 rtx src1 = simplify_gen_subreg (SImode, src, DImode, 0);
3018 rtx src2 = simplify_gen_subreg (SImode, src, DImode, 4);
3019 rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
3020 rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
3021
3022 emit_insn (gen_bswapsi2 (dest1, src2));
3023 emit_insn (gen_bswapsi2 (dest2, src1));
3024 DONE;
3025 })
3026
3027
3028 (define_insn "mul<mode>3"
3029 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3030 (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3031 (match_operand:GPR 2 "reg_or_short_operand" "r,I")))]
3032 ""
3033 "@
3034 mull<wd> %0,%1,%2
3035 mulli %0,%1,%2"
3036 [(set_attr "type" "mul")
3037 (set (attr "size")
3038 (cond [(match_operand:GPR 2 "s8bit_cint_operand")
3039 (const_string "8")
3040 (match_operand:GPR 2 "short_cint_operand")
3041 (const_string "16")]
3042 (const_string "<bits>")))])
3043
3044 (define_insn_and_split "*mul<mode>3_dot"
3045 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3046 (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3047 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3048 (const_int 0)))
3049 (clobber (match_scratch:GPR 0 "=r,r"))]
3050 "<MODE>mode == Pmode"
3051 "@
3052 mull<wd>. %0,%1,%2
3053 #"
3054 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3055 [(set (match_dup 0)
3056 (mult:GPR (match_dup 1)
3057 (match_dup 2)))
3058 (set (match_dup 3)
3059 (compare:CC (match_dup 0)
3060 (const_int 0)))]
3061 ""
3062 [(set_attr "type" "mul")
3063 (set_attr "size" "<bits>")
3064 (set_attr "dot" "yes")
3065 (set_attr "length" "4,8")])
3066
3067 (define_insn_and_split "*mul<mode>3_dot2"
3068 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3069 (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3070 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3071 (const_int 0)))
3072 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3073 (mult:GPR (match_dup 1)
3074 (match_dup 2)))]
3075 "<MODE>mode == Pmode"
3076 "@
3077 mull<wd>. %0,%1,%2
3078 #"
3079 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3080 [(set (match_dup 0)
3081 (mult:GPR (match_dup 1)
3082 (match_dup 2)))
3083 (set (match_dup 3)
3084 (compare:CC (match_dup 0)
3085 (const_int 0)))]
3086 ""
3087 [(set_attr "type" "mul")
3088 (set_attr "size" "<bits>")
3089 (set_attr "dot" "yes")
3090 (set_attr "length" "4,8")])
3091
3092
3093 (define_expand "<su>mul<mode>3_highpart"
3094 [(set (match_operand:GPR 0 "gpc_reg_operand")
3095 (subreg:GPR
3096 (mult:<DMODE> (any_extend:<DMODE>
3097 (match_operand:GPR 1 "gpc_reg_operand"))
3098 (any_extend:<DMODE>
3099 (match_operand:GPR 2 "gpc_reg_operand")))
3100 0))]
3101 ""
3102 {
3103 if (<MODE>mode == SImode && TARGET_POWERPC64)
3104 {
3105 emit_insn (gen_<su>mulsi3_highpart_64 (operands[0], operands[1],
3106 operands[2]));
3107 DONE;
3108 }
3109
3110 if (!WORDS_BIG_ENDIAN)
3111 {
3112 emit_insn (gen_<su>mul<mode>3_highpart_le (operands[0], operands[1],
3113 operands[2]));
3114 DONE;
3115 }
3116 })
3117
3118 (define_insn "*<su>mul<mode>3_highpart"
3119 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3120 (subreg:GPR
3121 (mult:<DMODE> (any_extend:<DMODE>
3122 (match_operand:GPR 1 "gpc_reg_operand" "r"))
3123 (any_extend:<DMODE>
3124 (match_operand:GPR 2 "gpc_reg_operand" "r")))
3125 0))]
3126 "WORDS_BIG_ENDIAN && !(<MODE>mode == SImode && TARGET_POWERPC64)"
3127 "mulh<wd><u> %0,%1,%2"
3128 [(set_attr "type" "mul")
3129 (set_attr "size" "<bits>")])
3130
3131 (define_insn "<su>mulsi3_highpart_le"
3132 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
3133 (subreg:SI
3134 (mult:DI (any_extend:DI
3135 (match_operand:SI 1 "gpc_reg_operand" "r"))
3136 (any_extend:DI
3137 (match_operand:SI 2 "gpc_reg_operand" "r")))
3138 4))]
3139 "!WORDS_BIG_ENDIAN && !TARGET_POWERPC64"
3140 "mulhw<u> %0,%1,%2"
3141 [(set_attr "type" "mul")])
3142
3143 (define_insn "<su>muldi3_highpart_le"
3144 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3145 (subreg:DI
3146 (mult:TI (any_extend:TI
3147 (match_operand:DI 1 "gpc_reg_operand" "r"))
3148 (any_extend:TI
3149 (match_operand:DI 2 "gpc_reg_operand" "r")))
3150 8))]
3151 "!WORDS_BIG_ENDIAN && TARGET_POWERPC64"
3152 "mulhd<u> %0,%1,%2"
3153 [(set_attr "type" "mul")
3154 (set_attr "size" "64")])
3155
3156 (define_insn "<su>mulsi3_highpart_64"
3157 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
3158 (truncate:SI
3159 (lshiftrt:DI
3160 (mult:DI (any_extend:DI
3161 (match_operand:SI 1 "gpc_reg_operand" "r"))
3162 (any_extend:DI
3163 (match_operand:SI 2 "gpc_reg_operand" "r")))
3164 (const_int 32))))]
3165 "TARGET_POWERPC64"
3166 "mulhw<u> %0,%1,%2"
3167 [(set_attr "type" "mul")])
3168
3169 (define_expand "<u>mul<mode><dmode>3"
3170 [(set (match_operand:<DMODE> 0 "gpc_reg_operand")
3171 (mult:<DMODE> (any_extend:<DMODE>
3172 (match_operand:GPR 1 "gpc_reg_operand"))
3173 (any_extend:<DMODE>
3174 (match_operand:GPR 2 "gpc_reg_operand"))))]
3175 "!(<MODE>mode == SImode && TARGET_POWERPC64)"
3176 {
3177 rtx l = gen_reg_rtx (<MODE>mode);
3178 rtx h = gen_reg_rtx (<MODE>mode);
3179 emit_insn (gen_mul<mode>3 (l, operands[1], operands[2]));
3180 emit_insn (gen_<su>mul<mode>3_highpart (h, operands[1], operands[2]));
3181 emit_move_insn (gen_lowpart (<MODE>mode, operands[0]), l);
3182 emit_move_insn (gen_highpart (<MODE>mode, operands[0]), h);
3183 DONE;
3184 })
3185
3186 (define_insn "*maddld<mode>4"
3187 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3188 (plus:GPR (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3189 (match_operand:GPR 2 "gpc_reg_operand" "r"))
3190 (match_operand:GPR 3 "gpc_reg_operand" "r")))]
3191 "TARGET_MADDLD"
3192 "maddld %0,%1,%2,%3"
3193 [(set_attr "type" "mul")])
3194
3195 (define_insn "udiv<mode>3"
3196 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3197 (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3198 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3199 ""
3200 "div<wd>u %0,%1,%2"
3201 [(set_attr "type" "div")
3202 (set_attr "size" "<bits>")])
3203
3204
3205 ;; For powers of two we can do sra[wd]i/addze for divide and then adjust for
3206 ;; modulus. If it isn't a power of two, force operands into register and do
3207 ;; a normal divide.
3208 (define_expand "div<mode>3"
3209 [(set (match_operand:GPR 0 "gpc_reg_operand")
3210 (div:GPR (match_operand:GPR 1 "gpc_reg_operand")
3211 (match_operand:GPR 2 "reg_or_cint_operand")))]
3212 ""
3213 {
3214 if (CONST_INT_P (operands[2])
3215 && INTVAL (operands[2]) > 0
3216 && exact_log2 (INTVAL (operands[2])) >= 0)
3217 {
3218 emit_insn (gen_div<mode>3_sra (operands[0], operands[1], operands[2]));
3219 DONE;
3220 }
3221
3222 operands[2] = force_reg (<MODE>mode, operands[2]);
3223 })
3224
3225 (define_insn "*div<mode>3"
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 "gpc_reg_operand" "r")))]
3229 ""
3230 "div<wd> %0,%1,%2"
3231 [(set_attr "type" "div")
3232 (set_attr "size" "<bits>")])
3233
3234 (define_insn "div<mode>3_sra"
3235 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3236 (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3237 (match_operand:GPR 2 "exact_log2_cint_operand" "N")))
3238 (clobber (reg:GPR CA_REGNO))]
3239 ""
3240 "sra<wd>i %0,%1,%p2\;addze %0,%0"
3241 [(set_attr "type" "two")
3242 (set_attr "length" "8")])
3243
3244 (define_insn_and_split "*div<mode>3_sra_dot"
3245 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3246 (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3247 (match_operand:GPR 2 "exact_log2_cint_operand" "N,N"))
3248 (const_int 0)))
3249 (clobber (match_scratch:GPR 0 "=r,r"))
3250 (clobber (reg:GPR CA_REGNO))]
3251 "<MODE>mode == Pmode"
3252 "@
3253 sra<wd>i %0,%1,%p2\;addze. %0,%0
3254 #"
3255 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3256 [(parallel [(set (match_dup 0)
3257 (div:GPR (match_dup 1)
3258 (match_dup 2)))
3259 (clobber (reg:GPR CA_REGNO))])
3260 (set (match_dup 3)
3261 (compare:CC (match_dup 0)
3262 (const_int 0)))]
3263 ""
3264 [(set_attr "type" "two")
3265 (set_attr "length" "8,12")
3266 (set_attr "cell_micro" "not")])
3267
3268 (define_insn_and_split "*div<mode>3_sra_dot2"
3269 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3270 (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3271 (match_operand:GPR 2 "exact_log2_cint_operand" "N,N"))
3272 (const_int 0)))
3273 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3274 (div:GPR (match_dup 1)
3275 (match_dup 2)))
3276 (clobber (reg:GPR CA_REGNO))]
3277 "<MODE>mode == Pmode"
3278 "@
3279 sra<wd>i %0,%1,%p2\;addze. %0,%0
3280 #"
3281 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3282 [(parallel [(set (match_dup 0)
3283 (div:GPR (match_dup 1)
3284 (match_dup 2)))
3285 (clobber (reg:GPR CA_REGNO))])
3286 (set (match_dup 3)
3287 (compare:CC (match_dup 0)
3288 (const_int 0)))]
3289 ""
3290 [(set_attr "type" "two")
3291 (set_attr "length" "8,12")
3292 (set_attr "cell_micro" "not")])
3293
3294 (define_expand "mod<mode>3"
3295 [(set (match_operand:GPR 0 "gpc_reg_operand")
3296 (mod:GPR (match_operand:GPR 1 "gpc_reg_operand")
3297 (match_operand:GPR 2 "reg_or_cint_operand")))]
3298 ""
3299 {
3300 int i;
3301 rtx temp1;
3302 rtx temp2;
3303
3304 if (!CONST_INT_P (operands[2])
3305 || INTVAL (operands[2]) <= 0
3306 || (i = exact_log2 (INTVAL (operands[2]))) < 0)
3307 {
3308 if (!TARGET_MODULO)
3309 FAIL;
3310
3311 operands[2] = force_reg (<MODE>mode, operands[2]);
3312 }
3313 else
3314 {
3315 temp1 = gen_reg_rtx (<MODE>mode);
3316 temp2 = gen_reg_rtx (<MODE>mode);
3317
3318 emit_insn (gen_div<mode>3 (temp1, operands[1], operands[2]));
3319 emit_insn (gen_ashl<mode>3 (temp2, temp1, GEN_INT (i)));
3320 emit_insn (gen_sub<mode>3 (operands[0], operands[1], temp2));
3321 DONE;
3322 }
3323 })
3324
3325 ;; In order to enable using a peephole2 for combining div/mod to eliminate the
3326 ;; mod, prefer putting the result of mod into a different register
3327 (define_insn "*mod<mode>3"
3328 [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
3329 (mod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3330 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3331 "TARGET_MODULO"
3332 "mods<wd> %0,%1,%2"
3333 [(set_attr "type" "div")
3334 (set_attr "size" "<bits>")])
3335
3336
3337 (define_insn "umod<mode>3"
3338 [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
3339 (umod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3340 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3341 "TARGET_MODULO"
3342 "modu<wd> %0,%1,%2"
3343 [(set_attr "type" "div")
3344 (set_attr "size" "<bits>")])
3345
3346 ;; On machines with modulo support, do a combined div/mod the old fashioned
3347 ;; method, since the multiply/subtract is faster than doing the mod instruction
3348 ;; after a divide.
3349
3350 (define_peephole2
3351 [(set (match_operand:GPR 0 "gpc_reg_operand")
3352 (div:GPR (match_operand:GPR 1 "gpc_reg_operand")
3353 (match_operand:GPR 2 "gpc_reg_operand")))
3354 (set (match_operand:GPR 3 "gpc_reg_operand")
3355 (mod:GPR (match_dup 1)
3356 (match_dup 2)))]
3357 "TARGET_MODULO
3358 && ! reg_mentioned_p (operands[0], operands[1])
3359 && ! reg_mentioned_p (operands[0], operands[2])
3360 && ! reg_mentioned_p (operands[3], operands[1])
3361 && ! reg_mentioned_p (operands[3], operands[2])"
3362 [(set (match_dup 0)
3363 (div:GPR (match_dup 1)
3364 (match_dup 2)))
3365 (set (match_dup 3)
3366 (mult:GPR (match_dup 0)
3367 (match_dup 2)))
3368 (set (match_dup 3)
3369 (minus:GPR (match_dup 1)
3370 (match_dup 3)))])
3371
3372 (define_peephole2
3373 [(set (match_operand:GPR 0 "gpc_reg_operand")
3374 (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand")
3375 (match_operand:GPR 2 "gpc_reg_operand")))
3376 (set (match_operand:GPR 3 "gpc_reg_operand")
3377 (umod:GPR (match_dup 1)
3378 (match_dup 2)))]
3379 "TARGET_MODULO
3380 && ! reg_mentioned_p (operands[0], operands[1])
3381 && ! reg_mentioned_p (operands[0], operands[2])
3382 && ! reg_mentioned_p (operands[3], operands[1])
3383 && ! reg_mentioned_p (operands[3], operands[2])"
3384 [(set (match_dup 0)
3385 (udiv:GPR (match_dup 1)
3386 (match_dup 2)))
3387 (set (match_dup 3)
3388 (mult:GPR (match_dup 0)
3389 (match_dup 2)))
3390 (set (match_dup 3)
3391 (minus:GPR (match_dup 1)
3392 (match_dup 3)))])
3393
3394 \f
3395 ;; Logical instructions
3396 ;; The logical instructions are mostly combined by using match_operator,
3397 ;; but the plain AND insns are somewhat different because there is no
3398 ;; plain 'andi' (only 'andi.'), no plain 'andis', and there are all
3399 ;; those rotate-and-mask operations. Thus, the AND insns come first.
3400
3401 (define_expand "and<mode>3"
3402 [(set (match_operand:SDI 0 "gpc_reg_operand")
3403 (and:SDI (match_operand:SDI 1 "gpc_reg_operand")
3404 (match_operand:SDI 2 "reg_or_cint_operand")))]
3405 ""
3406 {
3407 if (<MODE>mode == DImode && !TARGET_POWERPC64)
3408 {
3409 rs6000_split_logical (operands, AND, false, false, false);
3410 DONE;
3411 }
3412
3413 if (CONST_INT_P (operands[2]))
3414 {
3415 if (rs6000_is_valid_and_mask (operands[2], <MODE>mode))
3416 {
3417 emit_insn (gen_and<mode>3_mask (operands[0], operands[1], operands[2]));
3418 DONE;
3419 }
3420
3421 if (logical_const_operand (operands[2], <MODE>mode))
3422 {
3423 emit_insn (gen_and<mode>3_imm (operands[0], operands[1], operands[2]));
3424 DONE;
3425 }
3426
3427 if (rs6000_is_valid_2insn_and (operands[2], <MODE>mode))
3428 {
3429 rs6000_emit_2insn_and (<MODE>mode, operands, true, 0);
3430 DONE;
3431 }
3432
3433 operands[2] = force_reg (<MODE>mode, operands[2]);
3434 }
3435 })
3436
3437
3438 (define_insn "and<mode>3_imm"
3439 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3440 (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3441 (match_operand:GPR 2 "logical_const_operand" "n")))
3442 (clobber (match_scratch:CC 3 "=x"))]
3443 "!rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3444 "andi%e2. %0,%1,%u2"
3445 [(set_attr "type" "logical")
3446 (set_attr "dot" "yes")])
3447
3448 (define_insn_and_split "*and<mode>3_imm_dot"
3449 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3450 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3451 (match_operand:GPR 2 "logical_const_operand" "n,n"))
3452 (const_int 0)))
3453 (clobber (match_scratch:GPR 0 "=r,r"))
3454 (clobber (match_scratch:CC 4 "=X,x"))]
3455 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3456 && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3457 "@
3458 andi%e2. %0,%1,%u2
3459 #"
3460 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3461 [(parallel [(set (match_dup 0)
3462 (and:GPR (match_dup 1)
3463 (match_dup 2)))
3464 (clobber (match_dup 4))])
3465 (set (match_dup 3)
3466 (compare:CC (match_dup 0)
3467 (const_int 0)))]
3468 ""
3469 [(set_attr "type" "logical")
3470 (set_attr "dot" "yes")
3471 (set_attr "length" "4,8")])
3472
3473 (define_insn_and_split "*and<mode>3_imm_dot2"
3474 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3475 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3476 (match_operand:GPR 2 "logical_const_operand" "n,n"))
3477 (const_int 0)))
3478 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3479 (and:GPR (match_dup 1)
3480 (match_dup 2)))
3481 (clobber (match_scratch:CC 4 "=X,x"))]
3482 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3483 && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3484 "@
3485 andi%e2. %0,%1,%u2
3486 #"
3487 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3488 [(parallel [(set (match_dup 0)
3489 (and:GPR (match_dup 1)
3490 (match_dup 2)))
3491 (clobber (match_dup 4))])
3492 (set (match_dup 3)
3493 (compare:CC (match_dup 0)
3494 (const_int 0)))]
3495 ""
3496 [(set_attr "type" "logical")
3497 (set_attr "dot" "yes")
3498 (set_attr "length" "4,8")])
3499
3500 (define_insn_and_split "*and<mode>3_imm_mask_dot"
3501 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3502 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3503 (match_operand:GPR 2 "logical_const_operand" "n,n"))
3504 (const_int 0)))
3505 (clobber (match_scratch:GPR 0 "=r,r"))]
3506 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3507 && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3508 "@
3509 andi%e2. %0,%1,%u2
3510 #"
3511 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3512 [(set (match_dup 0)
3513 (and:GPR (match_dup 1)
3514 (match_dup 2)))
3515 (set (match_dup 3)
3516 (compare:CC (match_dup 0)
3517 (const_int 0)))]
3518 ""
3519 [(set_attr "type" "logical")
3520 (set_attr "dot" "yes")
3521 (set_attr "length" "4,8")])
3522
3523 (define_insn_and_split "*and<mode>3_imm_mask_dot2"
3524 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3525 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3526 (match_operand:GPR 2 "logical_const_operand" "n,n"))
3527 (const_int 0)))
3528 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3529 (and:GPR (match_dup 1)
3530 (match_dup 2)))]
3531 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3532 && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3533 "@
3534 andi%e2. %0,%1,%u2
3535 #"
3536 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3537 [(set (match_dup 0)
3538 (and:GPR (match_dup 1)
3539 (match_dup 2)))
3540 (set (match_dup 3)
3541 (compare:CC (match_dup 0)
3542 (const_int 0)))]
3543 ""
3544 [(set_attr "type" "logical")
3545 (set_attr "dot" "yes")
3546 (set_attr "length" "4,8")])
3547
3548 (define_insn "*and<mode>3_imm_dot_shifted"
3549 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
3550 (compare:CC
3551 (and:GPR
3552 (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3553 (match_operand:SI 4 "const_int_operand" "n"))
3554 (match_operand:GPR 2 "const_int_operand" "n"))
3555 (const_int 0)))
3556 (clobber (match_scratch:GPR 0 "=r"))]
3557 "logical_const_operand (GEN_INT (UINTVAL (operands[2])
3558 << INTVAL (operands[4])),
3559 DImode)
3560 && (<MODE>mode == Pmode
3561 || (UINTVAL (operands[2]) << INTVAL (operands[4])) <= 0x7fffffff)"
3562 {
3563 operands[2] = GEN_INT (UINTVAL (operands[2]) << INTVAL (operands[4]));
3564 return "andi%e2. %0,%1,%u2";
3565 }
3566 [(set_attr "type" "logical")
3567 (set_attr "dot" "yes")])
3568
3569
3570 (define_insn "and<mode>3_mask"
3571 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3572 (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3573 (match_operand:GPR 2 "const_int_operand" "n")))]
3574 "rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3575 {
3576 return rs6000_insn_for_and_mask (<MODE>mode, operands, false);
3577 }
3578 [(set_attr "type" "shift")])
3579
3580 (define_insn_and_split "*and<mode>3_mask_dot"
3581 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3582 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3583 (match_operand:GPR 2 "const_int_operand" "n,n"))
3584 (const_int 0)))
3585 (clobber (match_scratch:GPR 0 "=r,r"))]
3586 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3587 && !logical_const_operand (operands[2], <MODE>mode)
3588 && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3589 {
3590 if (which_alternative == 0)
3591 return rs6000_insn_for_and_mask (<MODE>mode, operands, true);
3592 else
3593 return "#";
3594 }
3595 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3596 [(set (match_dup 0)
3597 (and:GPR (match_dup 1)
3598 (match_dup 2)))
3599 (set (match_dup 3)
3600 (compare:CC (match_dup 0)
3601 (const_int 0)))]
3602 ""
3603 [(set_attr "type" "shift")
3604 (set_attr "dot" "yes")
3605 (set_attr "length" "4,8")])
3606
3607 (define_insn_and_split "*and<mode>3_mask_dot2"
3608 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3609 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3610 (match_operand:GPR 2 "const_int_operand" "n,n"))
3611 (const_int 0)))
3612 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3613 (and:GPR (match_dup 1)
3614 (match_dup 2)))]
3615 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3616 && !logical_const_operand (operands[2], <MODE>mode)
3617 && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3618 {
3619 if (which_alternative == 0)
3620 return rs6000_insn_for_and_mask (<MODE>mode, operands, true);
3621 else
3622 return "#";
3623 }
3624 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3625 [(set (match_dup 0)
3626 (and:GPR (match_dup 1)
3627 (match_dup 2)))
3628 (set (match_dup 3)
3629 (compare:CC (match_dup 0)
3630 (const_int 0)))]
3631 ""
3632 [(set_attr "type" "shift")
3633 (set_attr "dot" "yes")
3634 (set_attr "length" "4,8")])
3635
3636
3637 (define_insn_and_split "*and<mode>3_2insn"
3638 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3639 (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3640 (match_operand:GPR 2 "const_int_operand" "n")))]
3641 "rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3642 && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3643 || logical_const_operand (operands[2], <MODE>mode))"
3644 "#"
3645 "&& 1"
3646 [(pc)]
3647 {
3648 rs6000_emit_2insn_and (<MODE>mode, operands, false, 0);
3649 DONE;
3650 }
3651 [(set_attr "type" "shift")
3652 (set_attr "length" "8")])
3653
3654 (define_insn_and_split "*and<mode>3_2insn_dot"
3655 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3656 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3657 (match_operand:GPR 2 "const_int_operand" "n,n"))
3658 (const_int 0)))
3659 (clobber (match_scratch:GPR 0 "=r,r"))]
3660 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3661 && rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3662 && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3663 || logical_const_operand (operands[2], <MODE>mode))"
3664 "#"
3665 "&& reload_completed"
3666 [(pc)]
3667 {
3668 rs6000_emit_2insn_and (<MODE>mode, operands, false, 1);
3669 DONE;
3670 }
3671 [(set_attr "type" "shift")
3672 (set_attr "dot" "yes")
3673 (set_attr "length" "8,12")])
3674
3675 (define_insn_and_split "*and<mode>3_2insn_dot2"
3676 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3677 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3678 (match_operand:GPR 2 "const_int_operand" "n,n"))
3679 (const_int 0)))
3680 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3681 (and:GPR (match_dup 1)
3682 (match_dup 2)))]
3683 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3684 && rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3685 && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3686 || logical_const_operand (operands[2], <MODE>mode))"
3687 "#"
3688 "&& reload_completed"
3689 [(pc)]
3690 {
3691 rs6000_emit_2insn_and (<MODE>mode, operands, false, 2);
3692 DONE;
3693 }
3694 [(set_attr "type" "shift")
3695 (set_attr "dot" "yes")
3696 (set_attr "length" "8,12")])
3697
3698
3699 (define_expand "<code><mode>3"
3700 [(set (match_operand:SDI 0 "gpc_reg_operand")
3701 (iorxor:SDI (match_operand:SDI 1 "gpc_reg_operand")
3702 (match_operand:SDI 2 "reg_or_cint_operand")))]
3703 ""
3704 {
3705 if (<MODE>mode == DImode && !TARGET_POWERPC64)
3706 {
3707 rs6000_split_logical (operands, <CODE>, false, false, false);
3708 DONE;
3709 }
3710
3711 if (non_logical_cint_operand (operands[2], <MODE>mode))
3712 {
3713 rtx tmp = ((!can_create_pseudo_p ()
3714 || rtx_equal_p (operands[0], operands[1]))
3715 ? operands[0] : gen_reg_rtx (<MODE>mode));
3716
3717 HOST_WIDE_INT value = INTVAL (operands[2]);
3718 HOST_WIDE_INT lo = value & 0xffff;
3719 HOST_WIDE_INT hi = value - lo;
3720
3721 emit_insn (gen_<code><mode>3 (tmp, operands[1], GEN_INT (hi)));
3722 emit_insn (gen_<code><mode>3 (operands[0], tmp, GEN_INT (lo)));
3723 DONE;
3724 }
3725
3726 if (!reg_or_logical_cint_operand (operands[2], <MODE>mode))
3727 operands[2] = force_reg (<MODE>mode, operands[2]);
3728 })
3729
3730 (define_split
3731 [(set (match_operand:GPR 0 "gpc_reg_operand")
3732 (iorxor:GPR (match_operand:GPR 1 "gpc_reg_operand")
3733 (match_operand:GPR 2 "non_logical_cint_operand")))]
3734 ""
3735 [(set (match_dup 3)
3736 (iorxor:GPR (match_dup 1)
3737 (match_dup 4)))
3738 (set (match_dup 0)
3739 (iorxor:GPR (match_dup 3)
3740 (match_dup 5)))]
3741 {
3742 operands[3] = ((!can_create_pseudo_p ()
3743 || rtx_equal_p (operands[0], operands[1]))
3744 ? operands[0] : gen_reg_rtx (<MODE>mode));
3745
3746 HOST_WIDE_INT value = INTVAL (operands[2]);
3747 HOST_WIDE_INT lo = value & 0xffff;
3748 HOST_WIDE_INT hi = value - lo;
3749
3750 operands[4] = GEN_INT (hi);
3751 operands[5] = GEN_INT (lo);
3752 })
3753
3754 (define_insn "*bool<mode>3_imm"
3755 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3756 (match_operator:GPR 3 "boolean_or_operator"
3757 [(match_operand:GPR 1 "gpc_reg_operand" "%r")
3758 (match_operand:GPR 2 "logical_const_operand" "n")]))]
3759 ""
3760 "%q3i%e2 %0,%1,%u2"
3761 [(set_attr "type" "logical")])
3762
3763 (define_insn "*bool<mode>3"
3764 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3765 (match_operator:GPR 3 "boolean_operator"
3766 [(match_operand:GPR 1 "gpc_reg_operand" "r")
3767 (match_operand:GPR 2 "gpc_reg_operand" "r")]))]
3768 ""
3769 "%q3 %0,%1,%2"
3770 [(set_attr "type" "logical")])
3771
3772 (define_insn_and_split "*bool<mode>3_dot"
3773 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3774 (compare:CC (match_operator:GPR 3 "boolean_operator"
3775 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3776 (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
3777 (const_int 0)))
3778 (clobber (match_scratch:GPR 0 "=r,r"))]
3779 "<MODE>mode == Pmode"
3780 "@
3781 %q3. %0,%1,%2
3782 #"
3783 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3784 [(set (match_dup 0)
3785 (match_dup 3))
3786 (set (match_dup 4)
3787 (compare:CC (match_dup 0)
3788 (const_int 0)))]
3789 ""
3790 [(set_attr "type" "logical")
3791 (set_attr "dot" "yes")
3792 (set_attr "length" "4,8")])
3793
3794 (define_insn_and_split "*bool<mode>3_dot2"
3795 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3796 (compare:CC (match_operator:GPR 3 "boolean_operator"
3797 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3798 (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
3799 (const_int 0)))
3800 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3801 (match_dup 3))]
3802 "<MODE>mode == Pmode"
3803 "@
3804 %q3. %0,%1,%2
3805 #"
3806 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3807 [(set (match_dup 0)
3808 (match_dup 3))
3809 (set (match_dup 4)
3810 (compare:CC (match_dup 0)
3811 (const_int 0)))]
3812 ""
3813 [(set_attr "type" "logical")
3814 (set_attr "dot" "yes")
3815 (set_attr "length" "4,8")])
3816
3817
3818 (define_insn "*boolc<mode>3"
3819 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3820 (match_operator:GPR 3 "boolean_operator"
3821 [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))
3822 (match_operand:GPR 1 "gpc_reg_operand" "r")]))]
3823 ""
3824 "%q3 %0,%1,%2"
3825 [(set_attr "type" "logical")])
3826
3827 (define_insn_and_split "*boolc<mode>3_dot"
3828 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3829 (compare:CC (match_operator:GPR 3 "boolean_operator"
3830 [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3831 (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
3832 (const_int 0)))
3833 (clobber (match_scratch:GPR 0 "=r,r"))]
3834 "<MODE>mode == Pmode"
3835 "@
3836 %q3. %0,%1,%2
3837 #"
3838 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3839 [(set (match_dup 0)
3840 (match_dup 3))
3841 (set (match_dup 4)
3842 (compare:CC (match_dup 0)
3843 (const_int 0)))]
3844 ""
3845 [(set_attr "type" "logical")
3846 (set_attr "dot" "yes")
3847 (set_attr "length" "4,8")])
3848
3849 (define_insn_and_split "*boolc<mode>3_dot2"
3850 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3851 (compare:CC (match_operator:GPR 3 "boolean_operator"
3852 [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3853 (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
3854 (const_int 0)))
3855 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3856 (match_dup 3))]
3857 "<MODE>mode == Pmode"
3858 "@
3859 %q3. %0,%1,%2
3860 #"
3861 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3862 [(set (match_dup 0)
3863 (match_dup 3))
3864 (set (match_dup 4)
3865 (compare:CC (match_dup 0)
3866 (const_int 0)))]
3867 ""
3868 [(set_attr "type" "logical")
3869 (set_attr "dot" "yes")
3870 (set_attr "length" "4,8")])
3871
3872
3873 (define_insn "*boolcc<mode>3"
3874 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3875 (match_operator:GPR 3 "boolean_operator"
3876 [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
3877 (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))]))]
3878 ""
3879 "%q3 %0,%1,%2"
3880 [(set_attr "type" "logical")])
3881
3882 (define_insn_and_split "*boolcc<mode>3_dot"
3883 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3884 (compare:CC (match_operator:GPR 3 "boolean_operator"
3885 [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
3886 (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
3887 (const_int 0)))
3888 (clobber (match_scratch:GPR 0 "=r,r"))]
3889 "<MODE>mode == Pmode"
3890 "@
3891 %q3. %0,%1,%2
3892 #"
3893 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3894 [(set (match_dup 0)
3895 (match_dup 3))
3896 (set (match_dup 4)
3897 (compare:CC (match_dup 0)
3898 (const_int 0)))]
3899 ""
3900 [(set_attr "type" "logical")
3901 (set_attr "dot" "yes")
3902 (set_attr "length" "4,8")])
3903
3904 (define_insn_and_split "*boolcc<mode>3_dot2"
3905 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3906 (compare:CC (match_operator:GPR 3 "boolean_operator"
3907 [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
3908 (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
3909 (const_int 0)))
3910 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3911 (match_dup 3))]
3912 "<MODE>mode == Pmode"
3913 "@
3914 %q3. %0,%1,%2
3915 #"
3916 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3917 [(set (match_dup 0)
3918 (match_dup 3))
3919 (set (match_dup 4)
3920 (compare:CC (match_dup 0)
3921 (const_int 0)))]
3922 ""
3923 [(set_attr "type" "logical")
3924 (set_attr "dot" "yes")
3925 (set_attr "length" "4,8")])
3926
3927
3928 ;; TODO: Should have dots of this as well.
3929 (define_insn "*eqv<mode>3"
3930 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3931 (not:GPR (xor:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3932 (match_operand:GPR 2 "gpc_reg_operand" "r"))))]
3933 ""
3934 "eqv %0,%1,%2"
3935 [(set_attr "type" "logical")])
3936 \f
3937 ;; Rotate-and-mask and insert.
3938
3939 (define_insn "*rotl<mode>3_mask"
3940 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3941 (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3942 [(match_operand:GPR 1 "gpc_reg_operand" "r")
3943 (match_operand:SI 2 "reg_or_cint_operand" "rn")])
3944 (match_operand:GPR 3 "const_int_operand" "n")))]
3945 "rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3946 {
3947 return rs6000_insn_for_shift_mask (<MODE>mode, operands, false);
3948 }
3949 [(set_attr "type" "shift")
3950 (set_attr "maybe_var_shift" "yes")])
3951
3952 (define_insn_and_split "*rotl<mode>3_mask_dot"
3953 [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y")
3954 (compare:CC
3955 (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3956 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3957 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")])
3958 (match_operand:GPR 3 "const_int_operand" "n,n"))
3959 (const_int 0)))
3960 (clobber (match_scratch:GPR 0 "=r,r"))]
3961 "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff)
3962 && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3963 {
3964 if (which_alternative == 0)
3965 return rs6000_insn_for_shift_mask (<MODE>mode, operands, true);
3966 else
3967 return "#";
3968 }
3969 "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)"
3970 [(set (match_dup 0)
3971 (and:GPR (match_dup 4)
3972 (match_dup 3)))
3973 (set (match_dup 5)
3974 (compare:CC (match_dup 0)
3975 (const_int 0)))]
3976 ""
3977 [(set_attr "type" "shift")
3978 (set_attr "maybe_var_shift" "yes")
3979 (set_attr "dot" "yes")
3980 (set_attr "length" "4,8")])
3981
3982 (define_insn_and_split "*rotl<mode>3_mask_dot2"
3983 [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y")
3984 (compare:CC
3985 (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3986 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3987 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")])
3988 (match_operand:GPR 3 "const_int_operand" "n,n"))
3989 (const_int 0)))
3990 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3991 (and:GPR (match_dup 4)
3992 (match_dup 3)))]
3993 "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff)
3994 && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3995 {
3996 if (which_alternative == 0)
3997 return rs6000_insn_for_shift_mask (<MODE>mode, operands, true);
3998 else
3999 return "#";
4000 }
4001 "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)"
4002 [(set (match_dup 0)
4003 (and:GPR (match_dup 4)
4004 (match_dup 3)))
4005 (set (match_dup 5)
4006 (compare:CC (match_dup 0)
4007 (const_int 0)))]
4008 ""
4009 [(set_attr "type" "shift")
4010 (set_attr "maybe_var_shift" "yes")
4011 (set_attr "dot" "yes")
4012 (set_attr "length" "4,8")])
4013
4014 ; Special case for less-than-0. We can do it with just one machine
4015 ; instruction, but the generic optimizers do not realise it is cheap.
4016 (define_insn "*lt0_<mode>di"
4017 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4018 (lt:GPR (match_operand:DI 1 "gpc_reg_operand" "r")
4019 (const_int 0)))]
4020 "TARGET_POWERPC64"
4021 "srdi %0,%1,63"
4022 [(set_attr "type" "shift")])
4023
4024 (define_insn "*lt0_<mode>si"
4025 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4026 (lt:GPR (match_operand:SI 1 "gpc_reg_operand" "r")
4027 (const_int 0)))]
4028 ""
4029 "rlwinm %0,%1,1,31,31"
4030 [(set_attr "type" "shift")])
4031
4032
4033
4034 ; Two forms for insert (the two arms of the IOR are not canonicalized,
4035 ; both are an AND so are the same precedence).
4036 (define_insn "*rotl<mode>3_insert"
4037 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4038 (ior:GPR (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
4039 [(match_operand:GPR 1 "gpc_reg_operand" "r")
4040 (match_operand:SI 2 "const_int_operand" "n")])
4041 (match_operand:GPR 3 "const_int_operand" "n"))
4042 (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0")
4043 (match_operand:GPR 6 "const_int_operand" "n"))))]
4044 "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode)
4045 && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0"
4046 {
4047 return rs6000_insn_for_insert_mask (<MODE>mode, operands, false);
4048 }
4049 [(set_attr "type" "insert")])
4050 ; FIXME: this needs an attr "size", so that the scheduler can see the
4051 ; difference between rlwimi and rldimi. We also might want dot forms,
4052 ; but not for rlwimi on POWER4 and similar processors.
4053
4054 (define_insn "*rotl<mode>3_insert_2"
4055 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4056 (ior:GPR (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0")
4057 (match_operand:GPR 6 "const_int_operand" "n"))
4058 (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
4059 [(match_operand:GPR 1 "gpc_reg_operand" "r")
4060 (match_operand:SI 2 "const_int_operand" "n")])
4061 (match_operand:GPR 3 "const_int_operand" "n"))))]
4062 "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode)
4063 && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0"
4064 {
4065 return rs6000_insn_for_insert_mask (<MODE>mode, operands, false);
4066 }
4067 [(set_attr "type" "insert")])
4068
4069 ; There are also some forms without one of the ANDs.
4070 (define_insn "*rotl<mode>3_insert_3"
4071 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4072 (ior:GPR (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0")
4073 (match_operand:GPR 4 "const_int_operand" "n"))
4074 (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4075 (match_operand:SI 2 "const_int_operand" "n"))))]
4076 "INTVAL (operands[2]) == exact_log2 (UINTVAL (operands[4]) + 1)"
4077 {
4078 if (<MODE>mode == SImode)
4079 return "rlwimi %0,%1,%h2,0,31-%h2";
4080 else
4081 return "rldimi %0,%1,%H2,0";
4082 }
4083 [(set_attr "type" "insert")])
4084
4085 (define_insn "*rotl<mode>3_insert_4"
4086 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4087 (ior:GPR (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0")
4088 (match_operand:GPR 4 "const_int_operand" "n"))
4089 (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4090 (match_operand:SI 2 "const_int_operand" "n"))))]
4091 "<MODE>mode == SImode &&
4092 GET_MODE_PRECISION (<MODE>mode)
4093 == INTVAL (operands[2]) + exact_log2 (-UINTVAL (operands[4]))"
4094 {
4095 operands[2] = GEN_INT (GET_MODE_PRECISION (<MODE>mode)
4096 - INTVAL (operands[2]));
4097 if (<MODE>mode == SImode)
4098 return "rlwimi %0,%1,%h2,32-%h2,31";
4099 else
4100 return "rldimi %0,%1,%H2,64-%H2";
4101 }
4102 [(set_attr "type" "insert")])
4103
4104 (define_insn "*rotlsi3_insert_5"
4105 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
4106 (ior:SI (and:SI (match_operand:SI 1 "gpc_reg_operand" "0,r")
4107 (match_operand:SI 2 "const_int_operand" "n,n"))
4108 (and:SI (match_operand:SI 3 "gpc_reg_operand" "r,0")
4109 (match_operand:SI 4 "const_int_operand" "n,n"))))]
4110 "rs6000_is_valid_mask (operands[2], NULL, NULL, SImode)
4111 && UINTVAL (operands[2]) != 0 && UINTVAL (operands[4]) != 0
4112 && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
4113 "@
4114 rlwimi %0,%3,0,%4
4115 rlwimi %0,%1,0,%2"
4116 [(set_attr "type" "insert")])
4117
4118 (define_insn "*rotldi3_insert_6"
4119 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4120 (ior:DI (and:DI (match_operand:DI 1 "gpc_reg_operand" "0")
4121 (match_operand:DI 2 "const_int_operand" "n"))
4122 (and:DI (match_operand:DI 3 "gpc_reg_operand" "r")
4123 (match_operand:DI 4 "const_int_operand" "n"))))]
4124 "exact_log2 (-UINTVAL (operands[2])) > 0
4125 && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
4126 {
4127 operands[5] = GEN_INT (64 - exact_log2 (-UINTVAL (operands[2])));
4128 return "rldimi %0,%3,0,%5";
4129 }
4130 [(set_attr "type" "insert")
4131 (set_attr "size" "64")])
4132
4133 (define_insn "*rotldi3_insert_7"
4134 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4135 (ior:DI (and:DI (match_operand:DI 3 "gpc_reg_operand" "r")
4136 (match_operand:DI 4 "const_int_operand" "n"))
4137 (and:DI (match_operand:DI 1 "gpc_reg_operand" "0")
4138 (match_operand:DI 2 "const_int_operand" "n"))))]
4139 "exact_log2 (-UINTVAL (operands[2])) > 0
4140 && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
4141 {
4142 operands[5] = GEN_INT (64 - exact_log2 (-UINTVAL (operands[2])));
4143 return "rldimi %0,%3,0,%5";
4144 }
4145 [(set_attr "type" "insert")
4146 (set_attr "size" "64")])
4147
4148
4149 ; This handles the important case of multiple-precision shifts. There is
4150 ; no canonicalization rule for ASHIFT vs. LSHIFTRT, so two patterns.
4151 (define_split
4152 [(set (match_operand:GPR 0 "gpc_reg_operand")
4153 (ior:GPR (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand")
4154 (match_operand:SI 3 "const_int_operand"))
4155 (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand")
4156 (match_operand:SI 4 "const_int_operand"))))]
4157 "can_create_pseudo_p ()
4158 && INTVAL (operands[3]) + INTVAL (operands[4])
4159 >= GET_MODE_PRECISION (<MODE>mode)"
4160 [(set (match_dup 5)
4161 (lshiftrt:GPR (match_dup 2)
4162 (match_dup 4)))
4163 (set (match_dup 0)
4164 (ior:GPR (and:GPR (match_dup 5)
4165 (match_dup 6))
4166 (ashift:GPR (match_dup 1)
4167 (match_dup 3))))]
4168 {
4169 unsigned HOST_WIDE_INT mask = 1;
4170 mask = (mask << INTVAL (operands[3])) - 1;
4171 operands[5] = gen_reg_rtx (<MODE>mode);
4172 operands[6] = GEN_INT (mask);
4173 })
4174
4175 (define_split
4176 [(set (match_operand:GPR 0 "gpc_reg_operand")
4177 (ior:GPR (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand")
4178 (match_operand:SI 4 "const_int_operand"))
4179 (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand")
4180 (match_operand:SI 3 "const_int_operand"))))]
4181 "can_create_pseudo_p ()
4182 && INTVAL (operands[3]) + INTVAL (operands[4])
4183 >= GET_MODE_PRECISION (<MODE>mode)"
4184 [(set (match_dup 5)
4185 (lshiftrt:GPR (match_dup 2)
4186 (match_dup 4)))
4187 (set (match_dup 0)
4188 (ior:GPR (and:GPR (match_dup 5)
4189 (match_dup 6))
4190 (ashift:GPR (match_dup 1)
4191 (match_dup 3))))]
4192 {
4193 unsigned HOST_WIDE_INT mask = 1;
4194 mask = (mask << INTVAL (operands[3])) - 1;
4195 operands[5] = gen_reg_rtx (<MODE>mode);
4196 operands[6] = GEN_INT (mask);
4197 })
4198
4199
4200 ; Another important case is setting some bits to 1; we can do that with
4201 ; an insert instruction, in many cases.
4202 (define_insn_and_split "*ior<mode>_mask"
4203 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4204 (ior:GPR (match_operand:GPR 1 "gpc_reg_operand" "0")
4205 (match_operand:GPR 2 "const_int_operand" "n")))
4206 (clobber (match_scratch:GPR 3 "=r"))]
4207 "!logical_const_operand (operands[2], <MODE>mode)
4208 && rs6000_is_valid_mask (operands[2], NULL, NULL, <MODE>mode)"
4209 "#"
4210 "&& 1"
4211 [(set (match_dup 3)
4212 (const_int -1))
4213 (set (match_dup 0)
4214 (ior:GPR (and:GPR (rotate:GPR (match_dup 3)
4215 (match_dup 4))
4216 (match_dup 2))
4217 (and:GPR (match_dup 1)
4218 (match_dup 5))))]
4219 {
4220 int nb, ne;
4221 rs6000_is_valid_mask (operands[2], &nb, &ne, <MODE>mode);
4222 if (GET_CODE (operands[3]) == SCRATCH)
4223 operands[3] = gen_reg_rtx (<MODE>mode);
4224 operands[4] = GEN_INT (ne);
4225 operands[5] = GEN_INT (~UINTVAL (operands[2]));
4226 }
4227 [(set_attr "type" "two")
4228 (set_attr "length" "8")])
4229
4230
4231 ; Yet another case is an rldimi with the second value coming from memory.
4232 ; The zero_extend that should become part of the rldimi is merged into the
4233 ; load from memory instead. Split things properly again.
4234 (define_split
4235 [(set (match_operand:DI 0 "gpc_reg_operand")
4236 (ior:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand")
4237 (match_operand:SI 2 "const_int_operand"))
4238 (zero_extend:DI (match_operand:QHSI 3 "memory_operand"))))]
4239 "INTVAL (operands[2]) == <bits>"
4240 [(set (match_dup 4)
4241 (zero_extend:DI (match_dup 3)))
4242 (set (match_dup 0)
4243 (ior:DI (and:DI (match_dup 4)
4244 (match_dup 5))
4245 (ashift:DI (match_dup 1)
4246 (match_dup 2))))]
4247 {
4248 operands[4] = gen_reg_rtx (DImode);
4249 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << <bits>) - 1);
4250 })
4251
4252 ; rldimi with UNSPEC_SI_FROM_SF.
4253 (define_insn_and_split "*rotldi3_insert_sf"
4254 [(set (match_operand:DI 0 "gpc_reg_operand")
4255 (ior:DI
4256 (ashift:DI (match_operand:DI 1 "gpc_reg_operand")
4257 (match_operand:SI 2 "const_int_operand"))
4258 (zero_extend:DI
4259 (unspec:QHSI
4260 [(match_operand:SF 3 "memory_operand")]
4261 UNSPEC_SI_FROM_SF))))
4262 (clobber (match_scratch:V4SF 4))]
4263 "TARGET_POWERPC64 && INTVAL (operands[2]) == <bits>"
4264 "#"
4265 ""
4266 [(parallel [(set (match_dup 5)
4267 (zero_extend:DI (unspec:QHSI [(match_dup 3)] UNSPEC_SI_FROM_SF)))
4268 (clobber (match_dup 4))])
4269 (set (match_dup 0)
4270 (ior:DI
4271 (and:DI (match_dup 5) (match_dup 6))
4272 (ashift:DI (match_dup 1) (match_dup 2))))]
4273 {
4274 operands[5] = gen_reg_rtx (DImode);
4275 operands[6] = GEN_INT ((HOST_WIDE_INT_1U << <bits>) - 1);
4276 })
4277
4278 ; rlwimi, too.
4279 (define_split
4280 [(set (match_operand:SI 0 "gpc_reg_operand")
4281 (ior:SI (ashift:SI (match_operand:SI 1 "gpc_reg_operand")
4282 (match_operand:SI 2 "const_int_operand"))
4283 (zero_extend:SI (match_operand:QHI 3 "memory_operand"))))]
4284 "INTVAL (operands[2]) == <bits>"
4285 [(set (match_dup 4)
4286 (zero_extend:SI (match_dup 3)))
4287 (set (match_dup 0)
4288 (ior:SI (and:SI (match_dup 4)
4289 (match_dup 5))
4290 (ashift:SI (match_dup 1)
4291 (match_dup 2))))]
4292 {
4293 operands[4] = gen_reg_rtx (SImode);
4294 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << <bits>) - 1);
4295 })
4296
4297
4298 ;; Now the simple shifts.
4299
4300 (define_insn "rotl<mode>3"
4301 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4302 (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4303 (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4304 ""
4305 "rotl<wd>%I2 %0,%1,%<hH>2"
4306 [(set_attr "type" "shift")
4307 (set_attr "maybe_var_shift" "yes")])
4308
4309 (define_insn "*rotlsi3_64"
4310 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4311 (zero_extend:DI
4312 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4313 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4314 "TARGET_POWERPC64"
4315 "rotlw%I2 %0,%1,%h2"
4316 [(set_attr "type" "shift")
4317 (set_attr "maybe_var_shift" "yes")])
4318
4319 (define_insn_and_split "*rotl<mode>3_dot"
4320 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4321 (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4322 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4323 (const_int 0)))
4324 (clobber (match_scratch:GPR 0 "=r,r"))]
4325 "<MODE>mode == Pmode"
4326 "@
4327 rotl<wd>%I2. %0,%1,%<hH>2
4328 #"
4329 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4330 [(set (match_dup 0)
4331 (rotate:GPR (match_dup 1)
4332 (match_dup 2)))
4333 (set (match_dup 3)
4334 (compare:CC (match_dup 0)
4335 (const_int 0)))]
4336 ""
4337 [(set_attr "type" "shift")
4338 (set_attr "maybe_var_shift" "yes")
4339 (set_attr "dot" "yes")
4340 (set_attr "length" "4,8")])
4341
4342 (define_insn_and_split "*rotl<mode>3_dot2"
4343 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4344 (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4345 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4346 (const_int 0)))
4347 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4348 (rotate:GPR (match_dup 1)
4349 (match_dup 2)))]
4350 "<MODE>mode == Pmode"
4351 "@
4352 rotl<wd>%I2. %0,%1,%<hH>2
4353 #"
4354 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4355 [(set (match_dup 0)
4356 (rotate:GPR (match_dup 1)
4357 (match_dup 2)))
4358 (set (match_dup 3)
4359 (compare:CC (match_dup 0)
4360 (const_int 0)))]
4361 ""
4362 [(set_attr "type" "shift")
4363 (set_attr "maybe_var_shift" "yes")
4364 (set_attr "dot" "yes")
4365 (set_attr "length" "4,8")])
4366
4367
4368 (define_insn "ashl<mode>3"
4369 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4370 (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4371 (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4372 ""
4373 "sl<wd>%I2 %0,%1,%<hH>2"
4374 [(set_attr "type" "shift")
4375 (set_attr "maybe_var_shift" "yes")])
4376
4377 (define_insn "*ashlsi3_64"
4378 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4379 (zero_extend:DI
4380 (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4381 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4382 "TARGET_POWERPC64"
4383 "slw%I2 %0,%1,%h2"
4384 [(set_attr "type" "shift")
4385 (set_attr "maybe_var_shift" "yes")])
4386
4387 (define_insn_and_split "*ashl<mode>3_dot"
4388 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4389 (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4390 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4391 (const_int 0)))
4392 (clobber (match_scratch:GPR 0 "=r,r"))]
4393 "<MODE>mode == Pmode"
4394 "@
4395 sl<wd>%I2. %0,%1,%<hH>2
4396 #"
4397 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4398 [(set (match_dup 0)
4399 (ashift:GPR (match_dup 1)
4400 (match_dup 2)))
4401 (set (match_dup 3)
4402 (compare:CC (match_dup 0)
4403 (const_int 0)))]
4404 ""
4405 [(set_attr "type" "shift")
4406 (set_attr "maybe_var_shift" "yes")
4407 (set_attr "dot" "yes")
4408 (set_attr "length" "4,8")])
4409
4410 (define_insn_and_split "*ashl<mode>3_dot2"
4411 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4412 (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4413 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4414 (const_int 0)))
4415 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4416 (ashift:GPR (match_dup 1)
4417 (match_dup 2)))]
4418 "<MODE>mode == Pmode"
4419 "@
4420 sl<wd>%I2. %0,%1,%<hH>2
4421 #"
4422 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4423 [(set (match_dup 0)
4424 (ashift:GPR (match_dup 1)
4425 (match_dup 2)))
4426 (set (match_dup 3)
4427 (compare:CC (match_dup 0)
4428 (const_int 0)))]
4429 ""
4430 [(set_attr "type" "shift")
4431 (set_attr "maybe_var_shift" "yes")
4432 (set_attr "dot" "yes")
4433 (set_attr "length" "4,8")])
4434
4435 ;; Pretend we have a memory form of extswsli until register allocation is done
4436 ;; so that we use LWZ to load the value from memory, instead of LWA.
4437 (define_insn_and_split "ashdi3_extswsli"
4438 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
4439 (ashift:DI
4440 (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,m"))
4441 (match_operand:DI 2 "u6bit_cint_operand" "n,n")))]
4442 "TARGET_EXTSWSLI"
4443 "@
4444 extswsli %0,%1,%2
4445 #"
4446 "&& reload_completed && MEM_P (operands[1])"
4447 [(set (match_dup 3)
4448 (match_dup 1))
4449 (set (match_dup 0)
4450 (ashift:DI (sign_extend:DI (match_dup 3))
4451 (match_dup 2)))]
4452 {
4453 operands[3] = gen_lowpart (SImode, operands[0]);
4454 }
4455 [(set_attr "type" "shift")
4456 (set_attr "maybe_var_shift" "no")])
4457
4458
4459 (define_insn_and_split "ashdi3_extswsli_dot"
4460 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y")
4461 (compare:CC
4462 (ashift:DI
4463 (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m"))
4464 (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n"))
4465 (const_int 0)))
4466 (clobber (match_scratch:DI 0 "=r,r,r,r"))]
4467 "TARGET_EXTSWSLI"
4468 "@
4469 extswsli. %0,%1,%2
4470 #
4471 #
4472 #"
4473 "&& reload_completed
4474 && (cc_reg_not_cr0_operand (operands[3], CCmode)
4475 || memory_operand (operands[1], SImode))"
4476 [(pc)]
4477 {
4478 rtx dest = operands[0];
4479 rtx src = operands[1];
4480 rtx shift = operands[2];
4481 rtx cr = operands[3];
4482 rtx src2;
4483
4484 if (!MEM_P (src))
4485 src2 = src;
4486 else
4487 {
4488 src2 = gen_lowpart (SImode, dest);
4489 emit_move_insn (src2, src);
4490 }
4491
4492 if (REGNO (cr) == CR0_REGNO)
4493 {
4494 emit_insn (gen_ashdi3_extswsli_dot2 (dest, src2, shift, cr));
4495 DONE;
4496 }
4497
4498 emit_insn (gen_ashdi3_extswsli (dest, src2, shift));
4499 emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx)));
4500 DONE;
4501 }
4502 [(set_attr "type" "shift")
4503 (set_attr "maybe_var_shift" "no")
4504 (set_attr "dot" "yes")
4505 (set_attr "length" "4,8,8,12")])
4506
4507 (define_insn_and_split "ashdi3_extswsli_dot2"
4508 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y")
4509 (compare:CC
4510 (ashift:DI
4511 (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m"))
4512 (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n"))
4513 (const_int 0)))
4514 (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r")
4515 (ashift:DI (sign_extend:DI (match_dup 1))
4516 (match_dup 2)))]
4517 "TARGET_EXTSWSLI"
4518 "@
4519 extswsli. %0,%1,%2
4520 #
4521 #
4522 #"
4523 "&& reload_completed
4524 && (cc_reg_not_cr0_operand (operands[3], CCmode)
4525 || memory_operand (operands[1], SImode))"
4526 [(pc)]
4527 {
4528 rtx dest = operands[0];
4529 rtx src = operands[1];
4530 rtx shift = operands[2];
4531 rtx cr = operands[3];
4532 rtx src2;
4533
4534 if (!MEM_P (src))
4535 src2 = src;
4536 else
4537 {
4538 src2 = gen_lowpart (SImode, dest);
4539 emit_move_insn (src2, src);
4540 }
4541
4542 if (REGNO (cr) == CR0_REGNO)
4543 {
4544 emit_insn (gen_ashdi3_extswsli_dot2 (dest, src2, shift, cr));
4545 DONE;
4546 }
4547
4548 emit_insn (gen_ashdi3_extswsli (dest, src2, shift));
4549 emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx)));
4550 DONE;
4551 }
4552 [(set_attr "type" "shift")
4553 (set_attr "maybe_var_shift" "no")
4554 (set_attr "dot" "yes")
4555 (set_attr "length" "4,8,8,12")])
4556
4557 (define_insn "lshr<mode>3"
4558 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4559 (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4560 (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4561 ""
4562 "sr<wd>%I2 %0,%1,%<hH>2"
4563 [(set_attr "type" "shift")
4564 (set_attr "maybe_var_shift" "yes")])
4565
4566 (define_insn "*lshrsi3_64"
4567 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4568 (zero_extend:DI
4569 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4570 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4571 "TARGET_POWERPC64"
4572 "srw%I2 %0,%1,%h2"
4573 [(set_attr "type" "shift")
4574 (set_attr "maybe_var_shift" "yes")])
4575
4576 (define_insn_and_split "*lshr<mode>3_dot"
4577 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4578 (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4579 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4580 (const_int 0)))
4581 (clobber (match_scratch:GPR 0 "=r,r"))]
4582 "<MODE>mode == Pmode"
4583 "@
4584 sr<wd>%I2. %0,%1,%<hH>2
4585 #"
4586 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4587 [(set (match_dup 0)
4588 (lshiftrt:GPR (match_dup 1)
4589 (match_dup 2)))
4590 (set (match_dup 3)
4591 (compare:CC (match_dup 0)
4592 (const_int 0)))]
4593 ""
4594 [(set_attr "type" "shift")
4595 (set_attr "maybe_var_shift" "yes")
4596 (set_attr "dot" "yes")
4597 (set_attr "length" "4,8")])
4598
4599 (define_insn_and_split "*lshr<mode>3_dot2"
4600 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4601 (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4602 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4603 (const_int 0)))
4604 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4605 (lshiftrt:GPR (match_dup 1)
4606 (match_dup 2)))]
4607 "<MODE>mode == Pmode"
4608 "@
4609 sr<wd>%I2. %0,%1,%<hH>2
4610 #"
4611 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4612 [(set (match_dup 0)
4613 (lshiftrt:GPR (match_dup 1)
4614 (match_dup 2)))
4615 (set (match_dup 3)
4616 (compare:CC (match_dup 0)
4617 (const_int 0)))]
4618 ""
4619 [(set_attr "type" "shift")
4620 (set_attr "maybe_var_shift" "yes")
4621 (set_attr "dot" "yes")
4622 (set_attr "length" "4,8")])
4623
4624
4625 (define_insn "ashr<mode>3"
4626 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4627 (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4628 (match_operand:SI 2 "reg_or_cint_operand" "rn")))
4629 (clobber (reg:GPR CA_REGNO))]
4630 ""
4631 "sra<wd>%I2 %0,%1,%<hH>2"
4632 [(set_attr "type" "shift")
4633 (set_attr "maybe_var_shift" "yes")])
4634
4635 (define_insn "*ashrsi3_64"
4636 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4637 (sign_extend:DI
4638 (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4639 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))
4640 (clobber (reg:SI CA_REGNO))]
4641 "TARGET_POWERPC64"
4642 "sraw%I2 %0,%1,%h2"
4643 [(set_attr "type" "shift")
4644 (set_attr "maybe_var_shift" "yes")])
4645
4646 (define_insn_and_split "*ashr<mode>3_dot"
4647 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4648 (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4649 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4650 (const_int 0)))
4651 (clobber (match_scratch:GPR 0 "=r,r"))
4652 (clobber (reg:GPR CA_REGNO))]
4653 "<MODE>mode == Pmode"
4654 "@
4655 sra<wd>%I2. %0,%1,%<hH>2
4656 #"
4657 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4658 [(parallel [(set (match_dup 0)
4659 (ashiftrt:GPR (match_dup 1)
4660 (match_dup 2)))
4661 (clobber (reg:GPR CA_REGNO))])
4662 (set (match_dup 3)
4663 (compare:CC (match_dup 0)
4664 (const_int 0)))]
4665 ""
4666 [(set_attr "type" "shift")
4667 (set_attr "maybe_var_shift" "yes")
4668 (set_attr "dot" "yes")
4669 (set_attr "length" "4,8")])
4670
4671 (define_insn_and_split "*ashr<mode>3_dot2"
4672 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4673 (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4674 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4675 (const_int 0)))
4676 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4677 (ashiftrt:GPR (match_dup 1)
4678 (match_dup 2)))
4679 (clobber (reg:GPR CA_REGNO))]
4680 "<MODE>mode == Pmode"
4681 "@
4682 sra<wd>%I2. %0,%1,%<hH>2
4683 #"
4684 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4685 [(parallel [(set (match_dup 0)
4686 (ashiftrt:GPR (match_dup 1)
4687 (match_dup 2)))
4688 (clobber (reg:GPR CA_REGNO))])
4689 (set (match_dup 3)
4690 (compare:CC (match_dup 0)
4691 (const_int 0)))]
4692 ""
4693 [(set_attr "type" "shift")
4694 (set_attr "maybe_var_shift" "yes")
4695 (set_attr "dot" "yes")
4696 (set_attr "length" "4,8")])
4697 \f
4698 ;; Builtins to replace a division to generate FRE reciprocal estimate
4699 ;; instructions and the necessary fixup instructions
4700 (define_expand "recip<mode>3"
4701 [(match_operand:RECIPF 0 "gpc_reg_operand")
4702 (match_operand:RECIPF 1 "gpc_reg_operand")
4703 (match_operand:RECIPF 2 "gpc_reg_operand")]
4704 "RS6000_RECIP_HAVE_RE_P (<MODE>mode)"
4705 {
4706 rs6000_emit_swdiv (operands[0], operands[1], operands[2], false);
4707 DONE;
4708 })
4709
4710 ;; Split to create division from FRE/FRES/etc. and fixup instead of the normal
4711 ;; hardware division. This is only done before register allocation and with
4712 ;; -ffast-math. This must appear before the divsf3/divdf3 insns.
4713 ;; We used to also check optimize_insn_for_speed_p () but problems with guessed
4714 ;; frequencies (pr68212/pr77536) yields that unreliable so it was removed.
4715 (define_split
4716 [(set (match_operand:RECIPF 0 "gpc_reg_operand")
4717 (div:RECIPF (match_operand 1 "gpc_reg_operand")
4718 (match_operand 2 "gpc_reg_operand")))]
4719 "RS6000_RECIP_AUTO_RE_P (<MODE>mode)
4720 && can_create_pseudo_p () && flag_finite_math_only
4721 && !flag_trapping_math && flag_reciprocal_math"
4722 [(const_int 0)]
4723 {
4724 rs6000_emit_swdiv (operands[0], operands[1], operands[2], true);
4725 DONE;
4726 })
4727
4728 ;; Builtins to replace 1/sqrt(x) with instructions using RSQRTE and the
4729 ;; appropriate fixup.
4730 (define_expand "rsqrt<mode>2"
4731 [(match_operand:RECIPF 0 "gpc_reg_operand")
4732 (match_operand:RECIPF 1 "gpc_reg_operand")]
4733 "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4734 {
4735 rs6000_emit_swsqrt (operands[0], operands[1], 1);
4736 DONE;
4737 })
4738 \f
4739 ;; Floating-point insns, excluding normal data motion. We combine the SF/DF
4740 ;; modes here, and also add in conditional vsx/power8-vector support to access
4741 ;; values in the traditional Altivec registers if the appropriate
4742 ;; -mupper-regs-{df,sf} option is enabled.
4743
4744 (define_expand "abs<mode>2"
4745 [(set (match_operand:SFDF 0 "gpc_reg_operand")
4746 (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))]
4747 "TARGET_HARD_FLOAT"
4748 "")
4749
4750 (define_insn "*abs<mode>2_fpr"
4751 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4752 (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4753 "TARGET_HARD_FLOAT"
4754 "@
4755 fabs %0,%1
4756 xsabsdp %x0,%x1"
4757 [(set_attr "type" "fpsimple")])
4758
4759 (define_insn "*nabs<mode>2_fpr"
4760 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4761 (neg:SFDF
4762 (abs:SFDF
4763 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))))]
4764 "TARGET_HARD_FLOAT"
4765 "@
4766 fnabs %0,%1
4767 xsnabsdp %x0,%x1"
4768 [(set_attr "type" "fpsimple")])
4769
4770 (define_expand "neg<mode>2"
4771 [(set (match_operand:SFDF 0 "gpc_reg_operand")
4772 (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))]
4773 "TARGET_HARD_FLOAT"
4774 "")
4775
4776 (define_insn "*neg<mode>2_fpr"
4777 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4778 (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4779 "TARGET_HARD_FLOAT"
4780 "@
4781 fneg %0,%1
4782 xsnegdp %x0,%x1"
4783 [(set_attr "type" "fpsimple")])
4784
4785 (define_expand "add<mode>3"
4786 [(set (match_operand:SFDF 0 "gpc_reg_operand")
4787 (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4788 (match_operand:SFDF 2 "gpc_reg_operand")))]
4789 "TARGET_HARD_FLOAT"
4790 "")
4791
4792 (define_insn "*add<mode>3_fpr"
4793 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa")
4794 (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,wa")
4795 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa")))]
4796 "TARGET_HARD_FLOAT"
4797 "@
4798 fadd<s> %0,%1,%2
4799 xsadd<sd>p %x0,%x1,%x2"
4800 [(set_attr "type" "fp")
4801 (set_attr "isa" "*,<Fisa>")])
4802
4803 (define_expand "sub<mode>3"
4804 [(set (match_operand:SFDF 0 "gpc_reg_operand")
4805 (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4806 (match_operand:SFDF 2 "gpc_reg_operand")))]
4807 "TARGET_HARD_FLOAT"
4808 "")
4809
4810 (define_insn "*sub<mode>3_fpr"
4811 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa")
4812 (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa")
4813 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa")))]
4814 "TARGET_HARD_FLOAT"
4815 "@
4816 fsub<s> %0,%1,%2
4817 xssub<sd>p %x0,%x1,%x2"
4818 [(set_attr "type" "fp")
4819 (set_attr "isa" "*,<Fisa>")])
4820
4821 (define_expand "mul<mode>3"
4822 [(set (match_operand:SFDF 0 "gpc_reg_operand")
4823 (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4824 (match_operand:SFDF 2 "gpc_reg_operand")))]
4825 "TARGET_HARD_FLOAT"
4826 "")
4827
4828 (define_insn "*mul<mode>3_fpr"
4829 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa")
4830 (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,wa")
4831 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa")))]
4832 "TARGET_HARD_FLOAT"
4833 "@
4834 fmul<s> %0,%1,%2
4835 xsmul<sd>p %x0,%x1,%x2"
4836 [(set_attr "type" "dmul")
4837 (set_attr "isa" "*,<Fisa>")])
4838
4839 (define_expand "div<mode>3"
4840 [(set (match_operand:SFDF 0 "gpc_reg_operand")
4841 (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4842 (match_operand:SFDF 2 "gpc_reg_operand")))]
4843 "TARGET_HARD_FLOAT"
4844 {
4845 if (RS6000_RECIP_AUTO_RE_P (<MODE>mode)
4846 && can_create_pseudo_p () && flag_finite_math_only
4847 && !flag_trapping_math && flag_reciprocal_math)
4848 {
4849 rs6000_emit_swdiv (operands[0], operands[1], operands[2], true);
4850 DONE;
4851 }
4852 })
4853
4854 (define_insn "*div<mode>3_fpr"
4855 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa")
4856 (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa")
4857 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa")))]
4858 "TARGET_HARD_FLOAT"
4859 "@
4860 fdiv<s> %0,%1,%2
4861 xsdiv<sd>p %x0,%x1,%x2"
4862 [(set_attr "type" "<sd>div")
4863 (set_attr "isa" "*,<Fisa>")])
4864
4865 (define_insn "*sqrt<mode>2_internal"
4866 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa")
4867 (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa")))]
4868 "TARGET_HARD_FLOAT && TARGET_PPC_GPOPT"
4869 "@
4870 fsqrt<s> %0,%1
4871 xssqrt<sd>p %x0,%x1"
4872 [(set_attr "type" "<sd>sqrt")
4873 (set_attr "isa" "*,<Fisa>")])
4874
4875 (define_expand "sqrt<mode>2"
4876 [(set (match_operand:SFDF 0 "gpc_reg_operand")
4877 (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))]
4878 "TARGET_HARD_FLOAT && TARGET_PPC_GPOPT"
4879 {
4880 if (<MODE>mode == SFmode
4881 && TARGET_RECIP_PRECISION
4882 && RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)
4883 && !optimize_function_for_size_p (cfun)
4884 && flag_finite_math_only && !flag_trapping_math
4885 && flag_unsafe_math_optimizations)
4886 {
4887 rs6000_emit_swsqrt (operands[0], operands[1], 0);
4888 DONE;
4889 }
4890 })
4891
4892 ;; Floating point reciprocal approximation
4893 (define_insn "fre<sd>"
4894 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa")
4895 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa")]
4896 UNSPEC_FRES))]
4897 "TARGET_<FFRE>"
4898 "@
4899 fre<s> %0,%1
4900 xsre<sd>p %x0,%x1"
4901 [(set_attr "type" "fp")
4902 (set_attr "isa" "*,<Fisa>")])
4903
4904 (define_insn "*rsqrt<mode>2"
4905 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa")
4906 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa")]
4907 UNSPEC_RSQRT))]
4908 "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4909 "@
4910 frsqrte<s> %0,%1
4911 xsrsqrte<sd>p %x0,%x1"
4912 [(set_attr "type" "fp")
4913 (set_attr "isa" "*,<Fisa>")])
4914
4915 ;; Floating point comparisons
4916 (define_insn "*cmp<mode>_fpr"
4917 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y,y")
4918 (compare:CCFP (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa")
4919 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa")))]
4920 "TARGET_HARD_FLOAT"
4921 "@
4922 fcmpu %0,%1,%2
4923 xscmpudp %0,%x1,%x2"
4924 [(set_attr "type" "fpcompare")
4925 (set_attr "isa" "*,<Fisa>")])
4926
4927 ;; Floating point conversions
4928 (define_expand "extendsfdf2"
4929 [(set (match_operand:DF 0 "gpc_reg_operand")
4930 (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand")))]
4931 "TARGET_HARD_FLOAT"
4932 {
4933 if (HONOR_SNANS (SFmode))
4934 operands[1] = force_reg (SFmode, operands[1]);
4935 })
4936
4937 (define_insn_and_split "*extendsfdf2_fpr"
4938 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d,d,wa,?wa,wa,v")
4939 (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand" "0,f,m,0,wa,Z,wY")))]
4940 "TARGET_HARD_FLOAT && !HONOR_SNANS (SFmode)"
4941 "@
4942 #
4943 fmr %0,%1
4944 lfs%U1%X1 %0,%1
4945 #
4946 xscpsgndp %x0,%x1,%x1
4947 lxsspx %x0,%y1
4948 lxssp %0,%1"
4949 "&& reload_completed && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1])"
4950 [(const_int 0)]
4951 {
4952 emit_note (NOTE_INSN_DELETED);
4953 DONE;
4954 }
4955 [(set_attr "type" "fp,fpsimple,fpload,fp,fpsimple,fpload,fpload")
4956 (set_attr "isa" "*,*,*,*,p8v,p8v,p9v")])
4957
4958 (define_insn "*extendsfdf2_snan"
4959 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa")
4960 (float_extend:DF (match_operand:SF 1 "gpc_reg_operand" "f,wa")))]
4961 "TARGET_HARD_FLOAT && HONOR_SNANS (SFmode)"
4962 "@
4963 frsp %0,%1
4964 xsrsp %x0,%x1"
4965 [(set_attr "type" "fp")
4966 (set_attr "isa" "*,p8v")])
4967
4968 (define_expand "truncdfsf2"
4969 [(set (match_operand:SF 0 "gpc_reg_operand")
4970 (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand")))]
4971 "TARGET_HARD_FLOAT"
4972 "")
4973
4974 (define_insn "*truncdfsf2_fpr"
4975 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wa")
4976 (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "d,wa")))]
4977 "TARGET_HARD_FLOAT"
4978 "@
4979 frsp %0,%1
4980 xsrsp %x0,%x1"
4981 [(set_attr "type" "fp")
4982 (set_attr "isa" "*,p8v")])
4983
4984 ;; This expander is here to avoid FLOAT_WORDS_BIGENDIAN tests in
4985 ;; builtins.c and optabs.c that are not correct for IBM long double
4986 ;; when little-endian.
4987 (define_expand "signbit<mode>2"
4988 [(set (match_dup 2)
4989 (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand")))
4990 (set (match_dup 3)
4991 (subreg:DI (match_dup 2) 0))
4992 (set (match_dup 4)
4993 (match_dup 5))
4994 (set (match_operand:SI 0 "gpc_reg_operand")
4995 (match_dup 6))]
4996 "TARGET_HARD_FLOAT
4997 && (!FLOAT128_IEEE_P (<MODE>mode)
4998 || (TARGET_POWERPC64 && TARGET_DIRECT_MOVE))"
4999 {
5000 if (FLOAT128_IEEE_P (<MODE>mode))
5001 {
5002 rtx dest = operands[0];
5003 rtx src = operands[1];
5004 rtx tmp = gen_reg_rtx (DImode);
5005 rtx dest_di = gen_lowpart (DImode, dest);
5006
5007 emit_insn (gen_signbit2_dm (<MODE>mode, tmp, src));
5008 emit_insn (gen_lshrdi3 (dest_di, tmp, GEN_INT (63)));
5009 DONE;
5010 }
5011 operands[2] = gen_reg_rtx (DFmode);
5012 operands[3] = gen_reg_rtx (DImode);
5013 if (TARGET_POWERPC64)
5014 {
5015 operands[4] = gen_reg_rtx (DImode);
5016 operands[5] = gen_rtx_LSHIFTRT (DImode, operands[3], GEN_INT (63));
5017 operands[6] = gen_rtx_SUBREG (SImode, operands[4],
5018 WORDS_BIG_ENDIAN ? 4 : 0);
5019 }
5020 else
5021 {
5022 operands[4] = gen_reg_rtx (SImode);
5023 operands[5] = gen_rtx_SUBREG (SImode, operands[3],
5024 WORDS_BIG_ENDIAN ? 0 : 4);
5025 operands[6] = gen_rtx_LSHIFTRT (SImode, operands[4], GEN_INT (31));
5026 }
5027 })
5028
5029 ;; Optimize IEEE 128-bit signbit on 64-bit systems with direct move to avoid
5030 ;; multiple direct moves. If we used a SUBREG:DI of the Floa128 type, the
5031 ;; register allocator would typically move the entire _Float128 item to GPRs (2
5032 ;; instructions on ISA 3.0, 3-4 instructions on ISA 2.07).
5033 ;;
5034 ;; After register allocation, if the _Float128 had originally been in GPRs, the
5035 ;; split allows the post reload phases to eliminate the move, and do the shift
5036 ;; directly with the register that contains the signbit.
5037 (define_insn_and_split "@signbit<mode>2_dm"
5038 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
5039 (unspec:DI [(match_operand:SIGNBIT 1 "gpc_reg_operand" "wa,r")]
5040 UNSPEC_SIGNBIT))]
5041 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
5042 "@
5043 mfvsrd %0,%x1
5044 #"
5045 "&& reload_completed && int_reg_operand (operands[1], <MODE>mode)"
5046 [(set (match_dup 0)
5047 (match_dup 2))]
5048 {
5049 operands[2] = gen_highpart (DImode, operands[1]);
5050 }
5051 [(set_attr "type" "mfvsr,*")])
5052
5053 ;; Optimize IEEE 128-bit signbit on to avoid loading the value into a vector
5054 ;; register and then doing a direct move if the value comes from memory. On
5055 ;; little endian, we have to load the 2nd double-word to get the sign bit.
5056 (define_insn_and_split "*signbit<mode>2_dm_mem"
5057 [(set (match_operand:DI 0 "gpc_reg_operand" "=b")
5058 (unspec:DI [(match_operand:SIGNBIT 1 "memory_operand" "m")]
5059 UNSPEC_SIGNBIT))]
5060 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
5061 "#"
5062 "&& 1"
5063 [(set (match_dup 0)
5064 (match_dup 2))]
5065 {
5066 rtx dest = operands[0];
5067 rtx src = operands[1];
5068 rtx addr = XEXP (src, 0);
5069
5070 if (WORDS_BIG_ENDIAN)
5071 operands[2] = adjust_address (src, DImode, 0);
5072
5073 else if (REG_P (addr) || SUBREG_P (addr))
5074 operands[2] = adjust_address (src, DImode, 8);
5075
5076 else if (GET_CODE (addr) == PLUS && REG_P (XEXP (addr, 0))
5077 && CONST_INT_P (XEXP (addr, 1)) && mem_operand_gpr (src, DImode))
5078 operands[2] = adjust_address (src, DImode, 8);
5079
5080 else
5081 {
5082 rtx tmp = can_create_pseudo_p () ? gen_reg_rtx (DImode) : dest;
5083 emit_insn (gen_rtx_SET (tmp, addr));
5084 operands[2] = change_address (src, DImode,
5085 gen_rtx_PLUS (DImode, tmp, GEN_INT (8)));
5086 }
5087 })
5088
5089 (define_expand "copysign<mode>3"
5090 [(set (match_dup 3)
5091 (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))
5092 (set (match_dup 4)
5093 (neg:SFDF (abs:SFDF (match_dup 1))))
5094 (set (match_operand:SFDF 0 "gpc_reg_operand")
5095 (if_then_else:SFDF (ge (match_operand:SFDF 2 "gpc_reg_operand")
5096 (match_dup 5))
5097 (match_dup 3)
5098 (match_dup 4)))]
5099 "TARGET_HARD_FLOAT
5100 && ((TARGET_PPC_GFXOPT
5101 && !HONOR_NANS (<MODE>mode)
5102 && !HONOR_SIGNED_ZEROS (<MODE>mode))
5103 || TARGET_CMPB
5104 || VECTOR_UNIT_VSX_P (<MODE>mode))"
5105 {
5106 if (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode))
5107 {
5108 emit_insn (gen_copysign<mode>3_fcpsgn (operands[0], operands[1],
5109 operands[2]));
5110 DONE;
5111 }
5112
5113 operands[3] = gen_reg_rtx (<MODE>mode);
5114 operands[4] = gen_reg_rtx (<MODE>mode);
5115 operands[5] = CONST0_RTX (<MODE>mode);
5116 })
5117
5118 ;; Use an unspec rather providing an if-then-else in RTL, to prevent the
5119 ;; compiler from optimizing -0.0
5120 (define_insn "copysign<mode>3_fcpsgn"
5121 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5122 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")
5123 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")]
5124 UNSPEC_COPYSIGN))]
5125 "TARGET_HARD_FLOAT && (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode))"
5126 "@
5127 fcpsgn %0,%2,%1
5128 xscpsgndp %x0,%x2,%x1"
5129 [(set_attr "type" "fpsimple")])
5130
5131 ;; For MIN, MAX, and conditional move, we use DEFINE_EXPAND's that involve a
5132 ;; fsel instruction and some auxiliary computations. Then we just have a
5133 ;; single DEFINE_INSN for fsel and the define_splits to make them if made by
5134 ;; combine.
5135 ;; For MIN, MAX on non-VSX machines, and conditional move all of the time, we
5136 ;; use DEFINE_EXPAND's that involve a fsel instruction and some auxiliary
5137 ;; computations. Then we just have a single DEFINE_INSN for fsel and the
5138 ;; define_splits to make them if made by combine. On VSX machines we have the
5139 ;; min/max instructions.
5140 ;;
5141 ;; On VSX, we only check for TARGET_VSX instead of checking for a vsx/p8 vector
5142 ;; to allow either DF/SF to use only traditional registers.
5143
5144 (define_expand "s<minmax><mode>3"
5145 [(set (match_operand:SFDF 0 "gpc_reg_operand")
5146 (fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
5147 (match_operand:SFDF 2 "gpc_reg_operand")))]
5148 "TARGET_MINMAX"
5149 {
5150 rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]);
5151 DONE;
5152 })
5153
5154 (define_insn "*s<minmax><mode>3_vsx"
5155 [(set (match_operand:SFDF 0 "vsx_register_operand" "=<Fv>")
5156 (fp_minmax:SFDF (match_operand:SFDF 1 "vsx_register_operand" "<Fv>")
5157 (match_operand:SFDF 2 "vsx_register_operand" "<Fv>")))]
5158 "TARGET_VSX && TARGET_HARD_FLOAT"
5159 {
5160 return (TARGET_P9_MINMAX
5161 ? "xs<minmax>cdp %x0,%x1,%x2"
5162 : "xs<minmax>dp %x0,%x1,%x2");
5163 }
5164 [(set_attr "type" "fp")])
5165
5166 ;; The conditional move instructions allow us to perform max and min operations
5167 ;; even when we don't have the appropriate max/min instruction using the FSEL
5168 ;; instruction.
5169
5170 (define_insn_and_split "*s<minmax><mode>3_fpr"
5171 [(set (match_operand:SFDF 0 "gpc_reg_operand")
5172 (fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
5173 (match_operand:SFDF 2 "gpc_reg_operand")))]
5174 "!TARGET_VSX && TARGET_MINMAX"
5175 "#"
5176 "&& 1"
5177 [(const_int 0)]
5178 {
5179 rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]);
5180 DONE;
5181 })
5182
5183 (define_expand "mov<mode>cc"
5184 [(set (match_operand:GPR 0 "gpc_reg_operand")
5185 (if_then_else:GPR (match_operand 1 "comparison_operator")
5186 (match_operand:GPR 2 "gpc_reg_operand")
5187 (match_operand:GPR 3 "gpc_reg_operand")))]
5188 "TARGET_ISEL"
5189 {
5190 if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
5191 DONE;
5192 else
5193 FAIL;
5194 })
5195
5196 ;; We use the BASE_REGS for the isel input operands because, if rA is
5197 ;; 0, the value of 0 is placed in rD upon truth. Similarly for rB
5198 ;; because we may switch the operands and rB may end up being rA.
5199 ;;
5200 ;; We need 2 patterns: an unsigned and a signed pattern. We could
5201 ;; leave out the mode in operand 4 and use one pattern, but reload can
5202 ;; change the mode underneath our feet and then gets confused trying
5203 ;; to reload the value.
5204 (define_mode_iterator CCEITHER [CC CCUNS])
5205 (define_mode_attr un [(CC "") (CCUNS "un")])
5206 (define_insn "isel_<un>signed_<GPR:mode>"
5207 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
5208 (if_then_else:GPR
5209 (match_operator 1 "scc_comparison_operator"
5210 [(match_operand:CCEITHER 4 "cc_reg_operand" "y,y")
5211 (const_int 0)])
5212 (match_operand:GPR 2 "reg_or_zero_operand" "O,b")
5213 (match_operand:GPR 3 "gpc_reg_operand" "r,r")))]
5214 "TARGET_ISEL"
5215 "isel %0,%2,%3,%j1"
5216 [(set_attr "type" "isel")])
5217
5218 ;; These patterns can be useful for combine; they let combine know that
5219 ;; isel can handle reversed comparisons so long as the operands are
5220 ;; registers.
5221
5222 (define_insn "*isel_reversed_<un>signed_<GPR:mode>"
5223 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
5224 (if_then_else:GPR
5225 (match_operator 1 "scc_rev_comparison_operator"
5226 [(match_operand:CCEITHER 4 "cc_reg_operand" "y,y")
5227 (const_int 0)])
5228 (match_operand:GPR 2 "gpc_reg_operand" "r,r")
5229 (match_operand:GPR 3 "reg_or_zero_operand" "O,b")))]
5230 "TARGET_ISEL"
5231 {
5232 PUT_CODE (operands[1], reverse_condition (GET_CODE (operands[1])));
5233 return "isel %0,%3,%2,%j1";
5234 }
5235 [(set_attr "type" "isel")])
5236
5237 ; Set Boolean Condition (Reverse)
5238 (define_insn "setbc_<un>signed_<GPR:mode>"
5239 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
5240 (match_operator:GPR 1 "scc_comparison_operator"
5241 [(match_operand:CCEITHER 2 "cc_reg_operand" "y")
5242 (const_int 0)]))]
5243 "TARGET_POWER10"
5244 "setbc %0,%j1"
5245 [(set_attr "type" "isel")])
5246
5247 (define_insn "*setbcr_<un>signed_<GPR:mode>"
5248 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
5249 (match_operator:GPR 1 "scc_rev_comparison_operator"
5250 [(match_operand:CCEITHER 2 "cc_reg_operand" "y")
5251 (const_int 0)]))]
5252 "TARGET_POWER10"
5253 "setbcr %0,%j1"
5254 [(set_attr "type" "isel")])
5255
5256 ; Set Negative Boolean Condition (Reverse)
5257 (define_insn "*setnbc_<un>signed_<GPR:mode>"
5258 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
5259 (neg:GPR (match_operator:GPR 1 "scc_comparison_operator"
5260 [(match_operand:CCEITHER 2 "cc_reg_operand" "y")
5261 (const_int 0)])))]
5262 "TARGET_POWER10"
5263 "setnbc %0,%j1"
5264 [(set_attr "type" "isel")])
5265
5266 (define_insn "*setnbcr_<un>signed_<GPR:mode>"
5267 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
5268 (neg:GPR (match_operator:GPR 1 "scc_rev_comparison_operator"
5269 [(match_operand:CCEITHER 2 "cc_reg_operand" "y")
5270 (const_int 0)])))]
5271 "TARGET_POWER10"
5272 "setnbcr %0,%j1"
5273 [(set_attr "type" "isel")])
5274
5275 ;; Floating point conditional move
5276 (define_expand "mov<mode>cc"
5277 [(set (match_operand:SFDF 0 "gpc_reg_operand")
5278 (if_then_else:SFDF (match_operand 1 "comparison_operator")
5279 (match_operand:SFDF 2 "gpc_reg_operand")
5280 (match_operand:SFDF 3 "gpc_reg_operand")))]
5281 "TARGET_HARD_FLOAT && TARGET_PPC_GFXOPT"
5282 {
5283 if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
5284 DONE;
5285 else
5286 FAIL;
5287 })
5288
5289 (define_insn "*fsel<SFDF:mode><SFDF2:mode>4"
5290 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=&<SFDF:rreg2>")
5291 (if_then_else:SFDF
5292 (ge (match_operand:SFDF2 1 "gpc_reg_operand" "<SFDF2:rreg2>")
5293 (match_operand:SFDF2 4 "zero_fp_constant" "F"))
5294 (match_operand:SFDF 2 "gpc_reg_operand" "<SFDF:rreg2>")
5295 (match_operand:SFDF 3 "gpc_reg_operand" "<SFDF:rreg2>")))]
5296 "TARGET_HARD_FLOAT && TARGET_PPC_GFXOPT"
5297 "fsel %0,%1,%2,%3"
5298 [(set_attr "type" "fp")])
5299
5300 (define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_p9"
5301 [(set (match_operand:SFDF 0 "vsx_register_operand" "=&<SFDF:Fv>,<SFDF:Fv>")
5302 (if_then_else:SFDF
5303 (match_operator:CCFP 1 "fpmask_comparison_operator"
5304 [(match_operand:SFDF2 2 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")
5305 (match_operand:SFDF2 3 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")])
5306 (match_operand:SFDF 4 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")
5307 (match_operand:SFDF 5 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")))
5308 (clobber (match_scratch:V2DI 6 "=0,&wa"))]
5309 "TARGET_P9_MINMAX"
5310 "#"
5311 ""
5312 [(set (match_dup 6)
5313 (if_then_else:V2DI (match_dup 1)
5314 (match_dup 7)
5315 (match_dup 8)))
5316 (set (match_dup 0)
5317 (if_then_else:SFDF (ne (match_dup 6)
5318 (match_dup 8))
5319 (match_dup 4)
5320 (match_dup 5)))]
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 [(set_attr "length" "8")
5329 (set_attr "type" "vecperm")])
5330
5331 ;; Handle inverting the fpmask comparisons.
5332 (define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_invert_p9"
5333 [(set (match_operand:SFDF 0 "vsx_register_operand" "=&<SFDF:Fv>,<SFDF:Fv>")
5334 (if_then_else:SFDF
5335 (match_operator:CCFP 1 "invert_fpmask_comparison_operator"
5336 [(match_operand:SFDF2 2 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")
5337 (match_operand:SFDF2 3 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")])
5338 (match_operand:SFDF 4 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")
5339 (match_operand:SFDF 5 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")))
5340 (clobber (match_scratch:V2DI 6 "=0,&wa"))]
5341 "TARGET_P9_MINMAX"
5342 "#"
5343 "&& 1"
5344 [(set (match_dup 6)
5345 (if_then_else:V2DI (match_dup 9)
5346 (match_dup 7)
5347 (match_dup 8)))
5348 (set (match_dup 0)
5349 (if_then_else:SFDF (ne (match_dup 6)
5350 (match_dup 8))
5351 (match_dup 5)
5352 (match_dup 4)))]
5353 {
5354 rtx op1 = operands[1];
5355 enum rtx_code cond = reverse_condition_maybe_unordered (GET_CODE (op1));
5356
5357 if (GET_CODE (operands[6]) == SCRATCH)
5358 operands[6] = gen_reg_rtx (V2DImode);
5359
5360 operands[7] = CONSTM1_RTX (V2DImode);
5361 operands[8] = CONST0_RTX (V2DImode);
5362
5363 operands[9] = gen_rtx_fmt_ee (cond, CCFPmode, operands[2], operands[3]);
5364 }
5365 [(set_attr "length" "8")
5366 (set_attr "type" "vecperm")])
5367
5368 (define_insn "*fpmask<mode>"
5369 [(set (match_operand:V2DI 0 "vsx_register_operand" "=wa")
5370 (if_then_else:V2DI
5371 (match_operator:CCFP 1 "fpmask_comparison_operator"
5372 [(match_operand:SFDF 2 "vsx_register_operand" "<Fv>")
5373 (match_operand:SFDF 3 "vsx_register_operand" "<Fv>")])
5374 (match_operand:V2DI 4 "all_ones_constant" "")
5375 (match_operand:V2DI 5 "zero_constant" "")))]
5376 "TARGET_P9_MINMAX"
5377 "xscmp%V1dp %x0,%x2,%x3"
5378 [(set_attr "type" "fpcompare")])
5379
5380 (define_insn "*xxsel<mode>"
5381 [(set (match_operand:SFDF 0 "vsx_register_operand" "=<Fv>")
5382 (if_then_else:SFDF (ne (match_operand:V2DI 1 "vsx_register_operand" "wa")
5383 (match_operand:V2DI 2 "zero_constant" ""))
5384 (match_operand:SFDF 3 "vsx_register_operand" "<Fv>")
5385 (match_operand:SFDF 4 "vsx_register_operand" "<Fv>")))]
5386 "TARGET_P9_MINMAX"
5387 "xxsel %x0,%x4,%x3,%x1"
5388 [(set_attr "type" "vecmove")])
5389
5390 \f
5391 ;; Conversions to and from floating-point.
5392
5393 ; We don't define lfiwax/lfiwzx with the normal definition, because we
5394 ; don't want to support putting SImode in FPR registers.
5395 (define_insn "lfiwax"
5396 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa,wa,v")
5397 (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r,v")]
5398 UNSPEC_LFIWAX))]
5399 "TARGET_HARD_FLOAT && TARGET_LFIWAX"
5400 "@
5401 lfiwax %0,%y1
5402 lxsiwax %x0,%y1
5403 mtvsrwa %x0,%1
5404 vextsw2d %0,%1"
5405 [(set_attr "type" "fpload,fpload,mtvsr,vecexts")
5406 (set_attr "isa" "*,p8v,p8v,p9v")])
5407
5408 ; This split must be run before register allocation because it allocates the
5409 ; memory slot that is needed to move values to/from the FPR. We don't allocate
5410 ; it earlier to allow for the combiner to merge insns together where it might
5411 ; not be needed and also in case the insns are deleted as dead code.
5412
5413 (define_insn_and_split "floatsi<mode>2_lfiwax"
5414 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,<Fv>")
5415 (float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r,r")))
5416 (clobber (match_scratch:DI 2 "=d,wa"))]
5417 "TARGET_HARD_FLOAT && TARGET_LFIWAX
5418 && <SI_CONVERT_FP> && can_create_pseudo_p ()"
5419 "#"
5420 ""
5421 [(pc)]
5422 {
5423 rtx dest = operands[0];
5424 rtx src = operands[1];
5425 rtx tmp;
5426
5427 if (!MEM_P (src) && TARGET_POWERPC64 && TARGET_DIRECT_MOVE)
5428 tmp = convert_to_mode (DImode, src, false);
5429 else
5430 {
5431 tmp = operands[2];
5432 if (GET_CODE (tmp) == SCRATCH)
5433 tmp = gen_reg_rtx (DImode);
5434 if (MEM_P (src))
5435 {
5436 src = rs6000_force_indexed_or_indirect_mem (src);
5437 emit_insn (gen_lfiwax (tmp, src));
5438 }
5439 else
5440 {
5441 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5442 emit_move_insn (stack, src);
5443 emit_insn (gen_lfiwax (tmp, stack));
5444 }
5445 }
5446 emit_insn (gen_floatdi<mode>2 (dest, tmp));
5447 DONE;
5448 }
5449 [(set_attr "length" "12")
5450 (set_attr "type" "fpload")])
5451
5452 (define_insn_and_split "floatsi<mode>2_lfiwax_mem"
5453 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,<Fv>")
5454 (float:SFDF
5455 (sign_extend:DI
5456 (match_operand:SI 1 "indexed_or_indirect_operand" "Z,Z"))))
5457 (clobber (match_scratch:DI 2 "=d,wa"))]
5458 "TARGET_HARD_FLOAT && TARGET_LFIWAX && <SI_CONVERT_FP>"
5459 "#"
5460 ""
5461 [(pc)]
5462 {
5463 operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
5464 if (GET_CODE (operands[2]) == SCRATCH)
5465 operands[2] = gen_reg_rtx (DImode);
5466 if (TARGET_P8_VECTOR)
5467 emit_insn (gen_extendsidi2 (operands[2], operands[1]));
5468 else
5469 emit_insn (gen_lfiwax (operands[2], operands[1]));
5470 emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
5471 DONE;
5472 }
5473 [(set_attr "length" "8")
5474 (set_attr "type" "fpload")])
5475
5476 (define_insn "lfiwzx"
5477 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa,wa,wa")
5478 (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r,wa")]
5479 UNSPEC_LFIWZX))]
5480 "TARGET_HARD_FLOAT && TARGET_LFIWZX"
5481 "@
5482 lfiwzx %0,%y1
5483 lxsiwzx %x0,%y1
5484 mtvsrwz %x0,%1
5485 xxextractuw %x0,%x1,4"
5486 [(set_attr "type" "fpload,fpload,mtvsr,vecexts")
5487 (set_attr "isa" "*,p8v,p8v,p9v")])
5488
5489 (define_insn_and_split "floatunssi<mode>2_lfiwzx"
5490 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,<Fv>")
5491 (unsigned_float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r,r")))
5492 (clobber (match_scratch:DI 2 "=d,wa"))]
5493 "TARGET_HARD_FLOAT && TARGET_LFIWZX && <SI_CONVERT_FP>"
5494 "#"
5495 ""
5496 [(pc)]
5497 {
5498 rtx dest = operands[0];
5499 rtx src = operands[1];
5500 rtx tmp;
5501
5502 if (!MEM_P (src) && TARGET_POWERPC64 && TARGET_DIRECT_MOVE)
5503 tmp = convert_to_mode (DImode, src, true);
5504 else
5505 {
5506 tmp = operands[2];
5507 if (GET_CODE (tmp) == SCRATCH)
5508 tmp = gen_reg_rtx (DImode);
5509 if (MEM_P (src))
5510 {
5511 src = rs6000_force_indexed_or_indirect_mem (src);
5512 emit_insn (gen_lfiwzx (tmp, src));
5513 }
5514 else
5515 {
5516 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5517 emit_move_insn (stack, src);
5518 emit_insn (gen_lfiwzx (tmp, stack));
5519 }
5520 }
5521 emit_insn (gen_floatdi<mode>2 (dest, tmp));
5522 DONE;
5523 }
5524 [(set_attr "length" "12")
5525 (set_attr "type" "fpload")])
5526
5527 (define_insn_and_split "floatunssi<mode>2_lfiwzx_mem"
5528 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,<Fv>")
5529 (unsigned_float:SFDF
5530 (zero_extend:DI
5531 (match_operand:SI 1 "indexed_or_indirect_operand" "Z,Z"))))
5532 (clobber (match_scratch:DI 2 "=d,wa"))]
5533 "TARGET_HARD_FLOAT && TARGET_LFIWZX && <SI_CONVERT_FP>"
5534 "#"
5535 ""
5536 [(pc)]
5537 {
5538 operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
5539 if (GET_CODE (operands[2]) == SCRATCH)
5540 operands[2] = gen_reg_rtx (DImode);
5541 if (TARGET_P8_VECTOR)
5542 emit_insn (gen_zero_extendsidi2 (operands[2], operands[1]));
5543 else
5544 emit_insn (gen_lfiwzx (operands[2], operands[1]));
5545 emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
5546 DONE;
5547 }
5548 [(set_attr "length" "8")
5549 (set_attr "type" "fpload")])
5550
5551 ; For each of these conversions, there is a define_expand, a define_insn
5552 ; with a '#' template, and a define_split (with C code). The idea is
5553 ; to allow constant folding with the template of the define_insn,
5554 ; then to have the insns split later (between sched1 and final).
5555
5556 (define_expand "floatsidf2"
5557 [(parallel [(set (match_operand:DF 0 "gpc_reg_operand")
5558 (float:DF (match_operand:SI 1 "nonimmediate_operand")))
5559 (use (match_dup 2))
5560 (use (match_dup 3))
5561 (clobber (match_dup 4))
5562 (clobber (match_dup 5))
5563 (clobber (match_dup 6))])]
5564 "TARGET_HARD_FLOAT"
5565 {
5566 if (TARGET_LFIWAX && TARGET_FCFID)
5567 {
5568 emit_insn (gen_floatsidf2_lfiwax (operands[0], operands[1]));
5569 DONE;
5570 }
5571 else if (TARGET_FCFID)
5572 {
5573 rtx dreg = operands[1];
5574 if (!REG_P (dreg))
5575 dreg = force_reg (SImode, dreg);
5576 dreg = convert_to_mode (DImode, dreg, false);
5577 emit_insn (gen_floatdidf2 (operands[0], dreg));
5578 DONE;
5579 }
5580
5581 if (!REG_P (operands[1]))
5582 operands[1] = force_reg (SImode, operands[1]);
5583 operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5584 operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503601774854144\", DFmode));
5585 operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5586 operands[5] = gen_reg_rtx (DFmode);
5587 operands[6] = gen_reg_rtx (SImode);
5588 })
5589
5590 (define_insn_and_split "*floatsidf2_internal"
5591 [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5592 (float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5593 (use (match_operand:SI 2 "gpc_reg_operand" "r"))
5594 (use (match_operand:DF 3 "gpc_reg_operand" "d"))
5595 (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
5596 (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))
5597 (clobber (match_operand:SI 6 "gpc_reg_operand" "=&r"))]
5598 "!TARGET_FCFID && TARGET_HARD_FLOAT"
5599 "#"
5600 ""
5601 [(pc)]
5602 {
5603 rtx lowword, highword;
5604 gcc_assert (MEM_P (operands[4]));
5605 highword = adjust_address (operands[4], SImode, 0);
5606 lowword = adjust_address (operands[4], SImode, 4);
5607 if (! WORDS_BIG_ENDIAN)
5608 std::swap (lowword, highword);
5609
5610 emit_insn (gen_xorsi3 (operands[6], operands[1],
5611 GEN_INT (~ (HOST_WIDE_INT) 0x7fffffff)));
5612 emit_move_insn (lowword, operands[6]);
5613 emit_move_insn (highword, operands[2]);
5614 emit_move_insn (operands[5], operands[4]);
5615 emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5616 DONE;
5617 }
5618 [(set_attr "length" "24")
5619 (set_attr "type" "fp")])
5620
5621 ;; If we don't have a direct conversion to single precision, don't enable this
5622 ;; conversion for 32-bit without fast math, because we don't have the insn to
5623 ;; generate the fixup swizzle to avoid double rounding problems.
5624 (define_expand "floatunssisf2"
5625 [(set (match_operand:SF 0 "gpc_reg_operand")
5626 (unsigned_float:SF (match_operand:SI 1 "nonimmediate_operand")))]
5627 "TARGET_HARD_FLOAT
5628 && ((TARGET_FCFIDUS && TARGET_LFIWZX)
5629 || (TARGET_FCFID
5630 && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))"
5631 {
5632 if (TARGET_LFIWZX && TARGET_FCFIDUS)
5633 {
5634 emit_insn (gen_floatunssisf2_lfiwzx (operands[0], operands[1]));
5635 DONE;
5636 }
5637 else
5638 {
5639 rtx dreg = operands[1];
5640 if (!REG_P (dreg))
5641 dreg = force_reg (SImode, dreg);
5642 dreg = convert_to_mode (DImode, dreg, true);
5643 emit_insn (gen_floatdisf2 (operands[0], dreg));
5644 DONE;
5645 }
5646 })
5647
5648 (define_expand "floatunssidf2"
5649 [(parallel [(set (match_operand:DF 0 "gpc_reg_operand")
5650 (unsigned_float:DF (match_operand:SI 1 "nonimmediate_operand")))
5651 (use (match_dup 2))
5652 (use (match_dup 3))
5653 (clobber (match_dup 4))
5654 (clobber (match_dup 5))])]
5655 "TARGET_HARD_FLOAT"
5656 {
5657 if (TARGET_LFIWZX && TARGET_FCFID)
5658 {
5659 emit_insn (gen_floatunssidf2_lfiwzx (operands[0], operands[1]));
5660 DONE;
5661 }
5662 else if (TARGET_FCFID)
5663 {
5664 rtx dreg = operands[1];
5665 if (!REG_P (dreg))
5666 dreg = force_reg (SImode, dreg);
5667 dreg = convert_to_mode (DImode, dreg, true);
5668 emit_insn (gen_floatdidf2 (operands[0], dreg));
5669 DONE;
5670 }
5671
5672 if (!REG_P (operands[1]))
5673 operands[1] = force_reg (SImode, operands[1]);
5674 operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5675 operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503599627370496\", DFmode));
5676 operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5677 operands[5] = gen_reg_rtx (DFmode);
5678 })
5679
5680 (define_insn_and_split "*floatunssidf2_internal"
5681 [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5682 (unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5683 (use (match_operand:SI 2 "gpc_reg_operand" "r"))
5684 (use (match_operand:DF 3 "gpc_reg_operand" "d"))
5685 (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
5686 (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))]
5687 "!TARGET_FCFIDU && TARGET_HARD_FLOAT
5688 && !(TARGET_FCFID && TARGET_POWERPC64)"
5689 "#"
5690 ""
5691 [(pc)]
5692 {
5693 rtx lowword, highword;
5694 gcc_assert (MEM_P (operands[4]));
5695 highword = adjust_address (operands[4], SImode, 0);
5696 lowword = adjust_address (operands[4], SImode, 4);
5697 if (! WORDS_BIG_ENDIAN)
5698 std::swap (lowword, highword);
5699
5700 emit_move_insn (lowword, operands[1]);
5701 emit_move_insn (highword, operands[2]);
5702 emit_move_insn (operands[5], operands[4]);
5703 emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5704 DONE;
5705 }
5706 [(set_attr "length" "20")
5707 (set_attr "type" "fp")])
5708
5709 ;; ISA 3.0 adds instructions lxsi[bh]zx to directly load QImode and HImode to
5710 ;; vector registers. These insns favor doing the sign/zero extension in
5711 ;; the vector registers, rather then loading up a GPR, doing a sign/zero
5712 ;; extension and then a direct move.
5713
5714 (define_expand "float<QHI:mode><FP_ISA3:mode>2"
5715 [(parallel [(set (match_operand:FP_ISA3 0 "vsx_register_operand")
5716 (float:FP_ISA3
5717 (match_operand:QHI 1 "input_operand")))
5718 (clobber (match_scratch:DI 2))
5719 (clobber (match_scratch:DI 3))
5720 (clobber (match_scratch:<QHI:MODE> 4))])]
5721 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5722 {
5723 if (MEM_P (operands[1]))
5724 operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
5725 })
5726
5727 (define_insn_and_split "*float<QHI:mode><FP_ISA3:mode>2_internal"
5728 [(set (match_operand:FP_ISA3 0 "vsx_register_operand" "=<Fv>,<Fv>,<Fv>")
5729 (float:FP_ISA3
5730 (match_operand:QHI 1 "reg_or_indexed_operand" "v,r,Z")))
5731 (clobber (match_scratch:DI 2 "=v,wa,v"))
5732 (clobber (match_scratch:DI 3 "=X,r,X"))
5733 (clobber (match_scratch:<QHI:MODE> 4 "=X,X,v"))]
5734 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5735 "#"
5736 "&& reload_completed"
5737 [(const_int 0)]
5738 {
5739 rtx result = operands[0];
5740 rtx input = operands[1];
5741 rtx di = operands[2];
5742
5743 if (!MEM_P (input))
5744 {
5745 rtx tmp = operands[3];
5746 if (altivec_register_operand (input, <QHI:MODE>mode))
5747 emit_insn (gen_extend<QHI:mode>di2 (di, input));
5748 else if (GET_CODE (tmp) == SCRATCH)
5749 emit_insn (gen_extend<QHI:mode>di2 (di, input));
5750 else
5751 {
5752 emit_insn (gen_extend<QHI:mode>di2 (tmp, input));
5753 emit_move_insn (di, tmp);
5754 }
5755 }
5756 else
5757 {
5758 rtx tmp = operands[4];
5759 emit_move_insn (tmp, input);
5760 emit_insn (gen_extend<QHI:mode>di2 (di, tmp));
5761 }
5762
5763 emit_insn (gen_floatdi<FP_ISA3:mode>2 (result, di));
5764 DONE;
5765 }
5766 [(set_attr "isa" "p9v,*,p9v")])
5767
5768 (define_expand "floatuns<QHI:mode><FP_ISA3:mode>2"
5769 [(parallel [(set (match_operand:FP_ISA3 0 "vsx_register_operand")
5770 (unsigned_float:FP_ISA3
5771 (match_operand:QHI 1 "input_operand")))
5772 (clobber (match_scratch:DI 2))
5773 (clobber (match_scratch:DI 3))])]
5774 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5775 {
5776 if (MEM_P (operands[1]))
5777 operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
5778 })
5779
5780 (define_insn_and_split "*floatuns<QHI:mode><FP_ISA3:mode>2_internal"
5781 [(set (match_operand:FP_ISA3 0 "vsx_register_operand" "=<Fv>,<Fv>,<Fv>")
5782 (unsigned_float:FP_ISA3
5783 (match_operand:QHI 1 "reg_or_indexed_operand" "v,r,Z")))
5784 (clobber (match_scratch:DI 2 "=v,wa,wa"))
5785 (clobber (match_scratch:DI 3 "=X,r,X"))]
5786 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5787 "#"
5788 "&& reload_completed"
5789 [(const_int 0)]
5790 {
5791 rtx result = operands[0];
5792 rtx input = operands[1];
5793 rtx di = operands[2];
5794
5795 if (MEM_P (input) || altivec_register_operand (input, <QHI:MODE>mode))
5796 emit_insn (gen_zero_extend<QHI:mode>di2 (di, input));
5797 else
5798 {
5799 rtx tmp = operands[3];
5800 if (GET_CODE (tmp) == SCRATCH)
5801 emit_insn (gen_extend<QHI:mode>di2 (di, input));
5802 else
5803 {
5804 emit_insn (gen_zero_extend<QHI:mode>di2 (tmp, input));
5805 emit_move_insn (di, tmp);
5806 }
5807 }
5808
5809 emit_insn (gen_floatdi<FP_ISA3:mode>2 (result, di));
5810 DONE;
5811 }
5812 [(set_attr "isa" "p9v,*,p9v")])
5813
5814 (define_expand "fix_trunc<mode>si2"
5815 [(set (match_operand:SI 0 "gpc_reg_operand")
5816 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand")))]
5817 "TARGET_HARD_FLOAT"
5818 {
5819 if (!(TARGET_P8_VECTOR && TARGET_DIRECT_MOVE))
5820 {
5821 rtx src = force_reg (<MODE>mode, operands[1]);
5822
5823 if (TARGET_STFIWX)
5824 emit_insn (gen_fix_trunc<mode>si2_stfiwx (operands[0], src));
5825 else
5826 {
5827 rtx tmp = gen_reg_rtx (DImode);
5828 rtx stack = rs6000_allocate_stack_temp (DImode, true, false);
5829 emit_insn (gen_fix_trunc<mode>si2_internal (operands[0], src,
5830 tmp, stack));
5831 }
5832 DONE;
5833 }
5834 })
5835
5836 ; Like the convert to float patterns, this insn must be split before
5837 ; register allocation so that it can allocate the memory slot if it
5838 ; needed
5839 (define_insn_and_split "fix_trunc<mode>si2_stfiwx"
5840 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5841 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
5842 (clobber (match_scratch:DI 2 "=d"))]
5843 "TARGET_HARD_FLOAT && TARGET_STFIWX && can_create_pseudo_p ()
5844 && !(TARGET_P8_VECTOR && TARGET_DIRECT_MOVE)"
5845 "#"
5846 ""
5847 [(pc)]
5848 {
5849 rtx dest = operands[0];
5850 rtx src = operands[1];
5851 rtx tmp = operands[2];
5852
5853 if (GET_CODE (tmp) == SCRATCH)
5854 tmp = gen_reg_rtx (DImode);
5855
5856 emit_insn (gen_fctiwz_<mode> (tmp, src));
5857 if (MEM_P (dest) && (TARGET_MFCRF || MEM_ALIGN (dest) >= 32))
5858 {
5859 dest = rs6000_force_indexed_or_indirect_mem (dest);
5860 emit_insn (gen_stfiwx (dest, tmp));
5861 DONE;
5862 }
5863 else if (TARGET_POWERPC64 && TARGET_DIRECT_MOVE && !MEM_P (dest))
5864 {
5865 dest = gen_lowpart (DImode, dest);
5866 emit_move_insn (dest, tmp);
5867 DONE;
5868 }
5869 else
5870 {
5871 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5872 emit_insn (gen_stfiwx (stack, tmp));
5873 emit_move_insn (dest, stack);
5874 DONE;
5875 }
5876 }
5877 [(set_attr "length" "12")
5878 (set_attr "type" "fp")])
5879
5880 (define_insn_and_split "fix_trunc<mode>si2_internal"
5881 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,?r")
5882 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d,<rreg>")))
5883 (clobber (match_operand:DI 2 "gpc_reg_operand" "=1,d"))
5884 (clobber (match_operand:DI 3 "offsettable_mem_operand" "=o,o"))]
5885 "TARGET_HARD_FLOAT
5886 && !(TARGET_P8_VECTOR && TARGET_DIRECT_MOVE)"
5887 "#"
5888 ""
5889 [(pc)]
5890 {
5891 rtx lowword;
5892 gcc_assert (MEM_P (operands[3]));
5893 lowword = adjust_address (operands[3], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
5894
5895 emit_insn (gen_fctiwz_<mode> (operands[2], operands[1]));
5896 emit_move_insn (operands[3], operands[2]);
5897 emit_move_insn (operands[0], lowword);
5898 DONE;
5899 }
5900 [(set_attr "length" "16")
5901 (set_attr "type" "fp")])
5902
5903 (define_expand "fix_trunc<mode>di2"
5904 [(set (match_operand:DI 0 "gpc_reg_operand")
5905 (fix:DI (match_operand:SFDF 1 "gpc_reg_operand")))]
5906 "TARGET_HARD_FLOAT && TARGET_FCFID"
5907 "")
5908
5909 (define_insn "*fix_trunc<mode>di2_fctidz"
5910 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa")
5911 (fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
5912 "TARGET_HARD_FLOAT && TARGET_FCFID"
5913 "@
5914 fctidz %0,%1
5915 xscvdpsxds %x0,%x1"
5916 [(set_attr "type" "fp")])
5917
5918 ;; If we have ISA 3.0, QI/HImode values can go in both VSX registers and GPR
5919 ;; registers. If we have ISA 2.07, we don't allow QI/HImode values in the
5920 ;; vector registers, so we need to do direct moves to the GPRs, but SImode
5921 ;; values can go in VSX registers. Keeping the direct move part through
5922 ;; register allocation prevents the register allocator from doing a direct move
5923 ;; of the SImode value to a GPR, and then a store/load.
5924 (define_insn_and_split "fix<uns>_trunc<SFDF:mode><QHI:mode>2"
5925 [(set (match_operand:<QHI:MODE> 0 "gpc_reg_operand" "=d,wa,r")
5926 (any_fix:QHI (match_operand:SFDF 1 "gpc_reg_operand" "d,wa,wa")))
5927 (clobber (match_scratch:SI 2 "=X,X,wa"))]
5928 "TARGET_DIRECT_MOVE"
5929 "@
5930 fctiw<u>z %0,%1
5931 xscvdp<su>xws %x0,%x1
5932 #"
5933 "&& reload_completed && int_reg_operand (operands[0], <QHI:MODE>mode)"
5934 [(set (match_dup 2)
5935 (any_fix:SI (match_dup 1)))
5936 (set (match_dup 3)
5937 (match_dup 2))]
5938 {
5939 operands[3] = gen_rtx_REG (SImode, REGNO (operands[0]));
5940 }
5941 [(set_attr "type" "fp")
5942 (set_attr "length" "4,4,8")
5943 (set_attr "isa" "p9v,p9v,*")])
5944
5945 (define_insn "*fix<uns>_trunc<SFDF:mode>si2_p8"
5946 [(set (match_operand:SI 0 "gpc_reg_operand" "=d,wa")
5947 (any_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d,wa")))]
5948 "TARGET_DIRECT_MOVE"
5949 "@
5950 fctiw<u>z %0,%1
5951 xscvdp<su>xws %x0,%x1"
5952 [(set_attr "type" "fp")])
5953
5954 ;; Keep the convert and store together through register allocation to prevent
5955 ;; the register allocator from getting clever and doing a direct move to a GPR
5956 ;; and then store for reg+offset stores.
5957 (define_insn_and_split "*fix<uns>_trunc<SFDF:mode><QHSI:mode>2_mem"
5958 [(set (match_operand:QHSI 0 "memory_operand" "=Z")
5959 (any_fix:QHSI (match_operand:SFDF 1 "gpc_reg_operand" "wa")))
5960 (clobber (match_scratch:SI 2 "=wa"))]
5961 "(<QHSI:MODE>mode == SImode && TARGET_P8_VECTOR) || TARGET_P9_VECTOR"
5962 "#"
5963 "&& reload_completed"
5964 [(set (match_dup 2)
5965 (any_fix:SI (match_dup 1)))
5966 (set (match_dup 0)
5967 (match_dup 3))]
5968 {
5969 operands[3] = (<QHSI:MODE>mode == SImode
5970 ? operands[2]
5971 : gen_rtx_REG (<QHSI:MODE>mode, REGNO (operands[2])));
5972 })
5973
5974 (define_expand "fixuns_trunc<mode>si2"
5975 [(set (match_operand:SI 0 "gpc_reg_operand")
5976 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand")))]
5977 "TARGET_HARD_FLOAT && TARGET_FCTIWUZ && TARGET_STFIWX"
5978 {
5979 if (!TARGET_P8_VECTOR)
5980 {
5981 emit_insn (gen_fixuns_trunc<mode>si2_stfiwx (operands[0], operands[1]));
5982 DONE;
5983 }
5984 })
5985
5986 (define_insn_and_split "fixuns_trunc<mode>si2_stfiwx"
5987 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5988 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
5989 (clobber (match_scratch:DI 2 "=d"))]
5990 "TARGET_HARD_FLOAT && TARGET_FCTIWUZ
5991 && TARGET_STFIWX && can_create_pseudo_p ()
5992 && !TARGET_P8_VECTOR"
5993 "#"
5994 ""
5995 [(pc)]
5996 {
5997 rtx dest = operands[0];
5998 rtx src = operands[1];
5999 rtx tmp = operands[2];
6000
6001 if (GET_CODE (tmp) == SCRATCH)
6002 tmp = gen_reg_rtx (DImode);
6003
6004 emit_insn (gen_fctiwuz_<mode> (tmp, src));
6005 if (MEM_P (dest))
6006 {
6007 dest = rs6000_force_indexed_or_indirect_mem (dest);
6008 emit_insn (gen_stfiwx (dest, tmp));
6009 DONE;
6010 }
6011 else if (TARGET_POWERPC64 && TARGET_DIRECT_MOVE)
6012 {
6013 dest = gen_lowpart (DImode, dest);
6014 emit_move_insn (dest, tmp);
6015 DONE;
6016 }
6017 else
6018 {
6019 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
6020 emit_insn (gen_stfiwx (stack, tmp));
6021 emit_move_insn (dest, stack);
6022 DONE;
6023 }
6024 }
6025 [(set_attr "length" "12")
6026 (set_attr "type" "fp")])
6027
6028 (define_insn "fixuns_trunc<mode>di2"
6029 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa")
6030 (unsigned_fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
6031 "TARGET_HARD_FLOAT && TARGET_FCTIDUZ"
6032 "@
6033 fctiduz %0,%1
6034 xscvdpuxds %x0,%x1"
6035 [(set_attr "type" "fp")])
6036
6037 (define_insn "rs6000_mtfsb0"
6038 [(unspec_volatile [(match_operand:SI 0 "u5bit_cint_operand" "n")]
6039 UNSPECV_MTFSB0)]
6040 "TARGET_HARD_FLOAT"
6041 "mtfsb0 %0"
6042 [(set_attr "type" "fp")])
6043
6044 (define_insn "rs6000_mtfsb1"
6045 [(unspec_volatile [(match_operand:SI 0 "u5bit_cint_operand" "n")]
6046 UNSPECV_MTFSB1)]
6047 "TARGET_HARD_FLOAT"
6048 "mtfsb1 %0"
6049 [(set_attr "type" "fp")])
6050
6051 (define_insn "rs6000_mffscrn"
6052 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
6053 (unspec_volatile:DF [(match_operand:DF 1 "gpc_reg_operand" "d")]
6054 UNSPECV_MFFSCRN))]
6055 "TARGET_P9_MISC"
6056 "mffscrn %0,%1"
6057 [(set_attr "type" "fp")])
6058
6059 (define_insn "rs6000_mffscdrn"
6060 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
6061 (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFSCDRN))
6062 (use (match_operand:DF 1 "gpc_reg_operand" "d"))]
6063 "TARGET_P9_MISC"
6064 "mffscdrn %0,%1"
6065 [(set_attr "type" "fp")])
6066
6067 (define_expand "rs6000_set_fpscr_rn"
6068 [(match_operand:DI 0 "reg_or_cint_operand")]
6069 "TARGET_HARD_FLOAT"
6070 {
6071 rtx tmp_df = gen_reg_rtx (DFmode);
6072
6073 /* The floating point rounding control bits are FPSCR[62:63]. Put the
6074 new rounding mode bits from operands[0][62:63] into FPSCR[62:63]. */
6075 if (TARGET_P9_MISC)
6076 {
6077 rtx src_df = force_reg (DImode, operands[0]);
6078 src_df = simplify_gen_subreg (DFmode, src_df, DImode, 0);
6079 emit_insn (gen_rs6000_mffscrn (tmp_df, src_df));
6080 DONE;
6081 }
6082
6083 if (CONST_INT_P (operands[0]))
6084 {
6085 if ((INTVAL (operands[0]) & 0x1) == 0x1)
6086 emit_insn (gen_rs6000_mtfsb1 (GEN_INT (31)));
6087 else
6088 emit_insn (gen_rs6000_mtfsb0 (GEN_INT (31)));
6089
6090 if ((INTVAL (operands[0]) & 0x2) == 0x2)
6091 emit_insn (gen_rs6000_mtfsb1 (GEN_INT (30)));
6092 else
6093 emit_insn (gen_rs6000_mtfsb0 (GEN_INT (30)));
6094 }
6095 else
6096 {
6097 rtx tmp_rn = gen_reg_rtx (DImode);
6098 rtx tmp_di = gen_reg_rtx (DImode);
6099
6100 /* Extract new RN mode from operand. */
6101 emit_insn (gen_anddi3 (tmp_rn, operands[0], GEN_INT (0x3)));
6102
6103 /* Insert new RN mode into FSCPR. */
6104 emit_insn (gen_rs6000_mffs (tmp_df));
6105 tmp_di = simplify_gen_subreg (DImode, tmp_df, DFmode, 0);
6106 emit_insn (gen_anddi3 (tmp_di, tmp_di, GEN_INT (-4)));
6107 emit_insn (gen_iordi3 (tmp_di, tmp_di, tmp_rn));
6108
6109 /* Need to write to field k=15. The fields are [0:15]. Hence with
6110 L=0, W=0, FLM_i must be equal to 8, 16 = i + 8*(1-W). FLM is an
6111 8-bit field[0:7]. Need to set the bit that corresponds to the
6112 value of i that you want [0:7]. */
6113 tmp_df = simplify_gen_subreg (DFmode, tmp_di, DImode, 0);
6114 emit_insn (gen_rs6000_mtfsf (GEN_INT (0x01), tmp_df));
6115 }
6116 DONE;
6117 })
6118
6119 (define_expand "rs6000_set_fpscr_drn"
6120 [(match_operand:DI 0 "gpc_reg_operand")]
6121 "TARGET_HARD_FLOAT"
6122 {
6123 rtx tmp_df = gen_reg_rtx (DFmode);
6124
6125 /* The decimal floating point rounding control bits are FPSCR[29:31]. Put the
6126 new rounding mode bits from operands[0][61:63] into FPSCR[29:31]. */
6127 if (TARGET_P9_MISC)
6128 {
6129 rtx src_df = gen_reg_rtx (DFmode);
6130
6131 emit_insn (gen_ashldi3 (operands[0], operands[0], GEN_INT (32)));
6132 src_df = simplify_gen_subreg (DFmode, operands[0], DImode, 0);
6133 emit_insn (gen_rs6000_mffscdrn (tmp_df, src_df));
6134 }
6135 else
6136 {
6137 rtx tmp_rn = gen_reg_rtx (DImode);
6138 rtx tmp_di = gen_reg_rtx (DImode);
6139
6140 /* Extract new DRN mode from operand. */
6141 emit_insn (gen_anddi3 (tmp_rn, operands[0], GEN_INT (0x7)));
6142 emit_insn (gen_ashldi3 (tmp_rn, tmp_rn, GEN_INT (32)));
6143
6144 /* Insert new RN mode into FSCPR. */
6145 emit_insn (gen_rs6000_mffs (tmp_df));
6146 tmp_di = simplify_gen_subreg (DImode, tmp_df, DFmode, 0);
6147 emit_insn (gen_anddi3 (tmp_di, tmp_di, GEN_INT (0xFFFFFFF8FFFFFFFFULL)));
6148 emit_insn (gen_iordi3 (tmp_di, tmp_di, tmp_rn));
6149
6150 /* Need to write to field 7. The fields are [0:15]. The equation to
6151 select the field is i + 8*(1-W). Hence with L=0 and W=1, need to set
6152 i to 0x1 to get field 7 where i selects the field. */
6153 tmp_df = simplify_gen_subreg (DFmode, tmp_di, DImode, 0);
6154 emit_insn (gen_rs6000_mtfsf_hi (GEN_INT (0x01), tmp_df));
6155 }
6156 DONE;
6157 })
6158
6159 ;; Here, we use (set (reg) (unspec:DI [(fix:SI ...)] UNSPEC_FCTIWZ))
6160 ;; rather than (set (subreg:SI (reg)) (fix:SI ...))
6161 ;; because the first makes it clear that operand 0 is not live
6162 ;; before the instruction.
6163 (define_insn "fctiwz_<mode>"
6164 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa")
6165 (unspec:DI [(fix:SI
6166 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
6167 UNSPEC_FCTIWZ))]
6168 "TARGET_HARD_FLOAT"
6169 "@
6170 fctiwz %0,%1
6171 xscvdpsxws %x0,%x1"
6172 [(set_attr "type" "fp")])
6173
6174 (define_insn "fctiwuz_<mode>"
6175 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa")
6176 (unspec:DI [(unsigned_fix:SI
6177 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
6178 UNSPEC_FCTIWUZ))]
6179 "TARGET_HARD_FLOAT && TARGET_FCTIWUZ"
6180 "@
6181 fctiwuz %0,%1
6182 xscvdpuxws %x0,%x1"
6183 [(set_attr "type" "fp")])
6184
6185 ;; Only optimize (float (fix x)) -> frz if we are in fast-math mode, since
6186 ;; since the friz instruction does not truncate the value if the floating
6187 ;; point value is < LONG_MIN or > LONG_MAX.
6188 (define_insn "*friz"
6189 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa")
6190 (float:DF (fix:DI (match_operand:DF 1 "gpc_reg_operand" "d,wa"))))]
6191 "TARGET_HARD_FLOAT && TARGET_FPRND
6192 && flag_unsafe_math_optimizations && !flag_trapping_math && TARGET_FRIZ"
6193 "@
6194 friz %0,%1
6195 xsrdpiz %x0,%x1"
6196 [(set_attr "type" "fp")])
6197
6198 ;; Opitmize converting SF/DFmode to signed SImode and back to SF/DFmode. This
6199 ;; optimization prevents on ISA 2.06 systems and earlier having to store the
6200 ;; value from the FPR/vector unit to the stack, load the value into a GPR, sign
6201 ;; extend it, store it back on the stack from the GPR, load it back into the
6202 ;; FP/vector unit to do the rounding. If we have direct move (ISA 2.07),
6203 ;; disable using store and load to sign/zero extend the value.
6204 (define_insn_and_split "*round32<mode>2_fprs"
6205 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
6206 (float:SFDF
6207 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
6208 (clobber (match_scratch:DI 2 "=d"))
6209 (clobber (match_scratch:DI 3 "=d"))]
6210 "TARGET_HARD_FLOAT
6211 && <SI_CONVERT_FP> && TARGET_LFIWAX && TARGET_STFIWX && TARGET_FCFID
6212 && !TARGET_DIRECT_MOVE && can_create_pseudo_p ()"
6213 "#"
6214 ""
6215 [(pc)]
6216 {
6217 rtx dest = operands[0];
6218 rtx src = operands[1];
6219 rtx tmp1 = operands[2];
6220 rtx tmp2 = operands[3];
6221 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
6222
6223 if (GET_CODE (tmp1) == SCRATCH)
6224 tmp1 = gen_reg_rtx (DImode);
6225 if (GET_CODE (tmp2) == SCRATCH)
6226 tmp2 = gen_reg_rtx (DImode);
6227
6228 emit_insn (gen_fctiwz_<mode> (tmp1, src));
6229 emit_insn (gen_stfiwx (stack, tmp1));
6230 emit_insn (gen_lfiwax (tmp2, stack));
6231 emit_insn (gen_floatdi<mode>2 (dest, tmp2));
6232 DONE;
6233 }
6234 [(set_attr "type" "fpload")
6235 (set_attr "length" "16")])
6236
6237 (define_insn_and_split "*roundu32<mode>2_fprs"
6238 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
6239 (unsigned_float:SFDF
6240 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
6241 (clobber (match_scratch:DI 2 "=d"))
6242 (clobber (match_scratch:DI 3 "=d"))]
6243 "TARGET_HARD_FLOAT
6244 && TARGET_LFIWZX && TARGET_STFIWX && TARGET_FCFIDU && !TARGET_DIRECT_MOVE
6245 && can_create_pseudo_p ()"
6246 "#"
6247 ""
6248 [(pc)]
6249 {
6250 rtx dest = operands[0];
6251 rtx src = operands[1];
6252 rtx tmp1 = operands[2];
6253 rtx tmp2 = operands[3];
6254 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
6255
6256 if (GET_CODE (tmp1) == SCRATCH)
6257 tmp1 = gen_reg_rtx (DImode);
6258 if (GET_CODE (tmp2) == SCRATCH)
6259 tmp2 = gen_reg_rtx (DImode);
6260
6261 emit_insn (gen_fctiwuz_<mode> (tmp1, src));
6262 emit_insn (gen_stfiwx (stack, tmp1));
6263 emit_insn (gen_lfiwzx (tmp2, stack));
6264 emit_insn (gen_floatdi<mode>2 (dest, tmp2));
6265 DONE;
6266 }
6267 [(set_attr "type" "fpload")
6268 (set_attr "length" "16")])
6269
6270 ;; No VSX equivalent to fctid
6271 (define_insn "lrint<mode>di2"
6272 [(set (match_operand:DI 0 "gpc_reg_operand" "=d")
6273 (unspec:DI [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
6274 UNSPEC_FCTID))]
6275 "TARGET_HARD_FLOAT && TARGET_FPRND"
6276 "fctid %0,%1"
6277 [(set_attr "type" "fp")])
6278
6279 (define_insn "btrunc<mode>2"
6280 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
6281 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
6282 UNSPEC_FRIZ))]
6283 "TARGET_HARD_FLOAT && TARGET_FPRND"
6284 "@
6285 friz %0,%1
6286 xsrdpiz %x0,%x1"
6287 [(set_attr "type" "fp")])
6288
6289 (define_insn "ceil<mode>2"
6290 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
6291 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
6292 UNSPEC_FRIP))]
6293 "TARGET_HARD_FLOAT && TARGET_FPRND"
6294 "@
6295 frip %0,%1
6296 xsrdpip %x0,%x1"
6297 [(set_attr "type" "fp")])
6298
6299 (define_insn "floor<mode>2"
6300 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
6301 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
6302 UNSPEC_FRIM))]
6303 "TARGET_HARD_FLOAT && TARGET_FPRND"
6304 "@
6305 frim %0,%1
6306 xsrdpim %x0,%x1"
6307 [(set_attr "type" "fp")])
6308
6309 ;; No VSX equivalent to frin
6310 (define_insn "round<mode>2"
6311 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<rreg2>")
6312 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
6313 UNSPEC_FRIN))]
6314 "TARGET_HARD_FLOAT && TARGET_FPRND"
6315 "frin %0,%1"
6316 [(set_attr "type" "fp")])
6317
6318 (define_insn "*xsrdpi<mode>2"
6319 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
6320 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Fv>")]
6321 UNSPEC_XSRDPI))]
6322 "TARGET_HARD_FLOAT && TARGET_VSX"
6323 "xsrdpi %x0,%x1"
6324 [(set_attr "type" "fp")])
6325
6326 (define_expand "lround<mode>di2"
6327 [(set (match_dup 2)
6328 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand")]
6329 UNSPEC_XSRDPI))
6330 (set (match_operand:DI 0 "gpc_reg_operand")
6331 (unspec:DI [(match_dup 2)]
6332 UNSPEC_FCTID))]
6333 "TARGET_HARD_FLOAT && TARGET_VSX && TARGET_FPRND"
6334 {
6335 operands[2] = gen_reg_rtx (<MODE>mode);
6336 })
6337
6338 ; An UNSPEC is used so we don't have to support SImode in FP registers.
6339 (define_insn "stfiwx"
6340 [(set (match_operand:SI 0 "memory_operand" "=Z,Z")
6341 (unspec:SI [(match_operand:DI 1 "gpc_reg_operand" "d,wa")]
6342 UNSPEC_STFIWX))]
6343 "TARGET_PPC_GFXOPT"
6344 "@
6345 stfiwx %1,%y0
6346 stxsiwx %x1,%y0"
6347 [(set_attr "type" "fpstore")
6348 (set_attr "isa" "*,p8v")])
6349
6350 ;; If we don't have a direct conversion to single precision, don't enable this
6351 ;; conversion for 32-bit without fast math, because we don't have the insn to
6352 ;; generate the fixup swizzle to avoid double rounding problems.
6353 (define_expand "floatsisf2"
6354 [(set (match_operand:SF 0 "gpc_reg_operand")
6355 (float:SF (match_operand:SI 1 "nonimmediate_operand")))]
6356 "TARGET_HARD_FLOAT
6357 && ((TARGET_FCFIDS && TARGET_LFIWAX)
6358 || (TARGET_FCFID
6359 && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))"
6360 {
6361 if (TARGET_FCFIDS && TARGET_LFIWAX)
6362 {
6363 emit_insn (gen_floatsisf2_lfiwax (operands[0], operands[1]));
6364 DONE;
6365 }
6366 else if (TARGET_FCFID && TARGET_LFIWAX)
6367 {
6368 rtx dfreg = gen_reg_rtx (DFmode);
6369 emit_insn (gen_floatsidf2_lfiwax (dfreg, operands[1]));
6370 emit_insn (gen_truncdfsf2 (operands[0], dfreg));
6371 DONE;
6372 }
6373 else
6374 {
6375 rtx dreg = operands[1];
6376 if (!REG_P (dreg))
6377 dreg = force_reg (SImode, dreg);
6378 dreg = convert_to_mode (DImode, dreg, false);
6379 emit_insn (gen_floatdisf2 (operands[0], dreg));
6380 DONE;
6381 }
6382 })
6383
6384 (define_insn "floatdidf2"
6385 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa")
6386 (float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wa")))]
6387 "TARGET_FCFID && TARGET_HARD_FLOAT"
6388 "@
6389 fcfid %0,%1
6390 xscvsxddp %x0,%x1"
6391 [(set_attr "type" "fp")])
6392
6393 ; Allow the combiner to merge source memory operands to the conversion so that
6394 ; the optimizer/register allocator doesn't try to load the value too early in a
6395 ; GPR and then use store/load to move it to a FPR and suffer from a store-load
6396 ; hit. We will split after reload to avoid the trip through the GPRs
6397
6398 (define_insn_and_split "*floatdidf2_mem"
6399 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa")
6400 (float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
6401 (clobber (match_scratch:DI 2 "=d,wa"))]
6402 "TARGET_HARD_FLOAT && TARGET_FCFID"
6403 "#"
6404 "&& reload_completed"
6405 [(set (match_dup 2) (match_dup 1))
6406 (set (match_dup 0) (float:DF (match_dup 2)))]
6407 ""
6408 [(set_attr "length" "8")
6409 (set_attr "type" "fpload")])
6410
6411 (define_expand "floatunsdidf2"
6412 [(set (match_operand:DF 0 "gpc_reg_operand")
6413 (unsigned_float:DF
6414 (match_operand:DI 1 "gpc_reg_operand")))]
6415 "TARGET_HARD_FLOAT && TARGET_FCFIDU"
6416 "")
6417
6418 (define_insn "*floatunsdidf2_fcfidu"
6419 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa")
6420 (unsigned_float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wa")))]
6421 "TARGET_HARD_FLOAT && TARGET_FCFIDU"
6422 "@
6423 fcfidu %0,%1
6424 xscvuxddp %x0,%x1"
6425 [(set_attr "type" "fp")])
6426
6427 (define_insn_and_split "*floatunsdidf2_mem"
6428 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa")
6429 (unsigned_float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
6430 (clobber (match_scratch:DI 2 "=d,wa"))]
6431 "TARGET_HARD_FLOAT && (TARGET_FCFIDU || VECTOR_UNIT_VSX_P (DFmode))"
6432 "#"
6433 "&& reload_completed"
6434 [(set (match_dup 2) (match_dup 1))
6435 (set (match_dup 0) (unsigned_float:DF (match_dup 2)))]
6436 ""
6437 [(set_attr "length" "8")
6438 (set_attr "type" "fpload")])
6439
6440 (define_expand "floatdisf2"
6441 [(set (match_operand:SF 0 "gpc_reg_operand")
6442 (float:SF (match_operand:DI 1 "gpc_reg_operand")))]
6443 "TARGET_FCFID && TARGET_HARD_FLOAT
6444 && (TARGET_FCFIDS || TARGET_POWERPC64 || flag_unsafe_math_optimizations)"
6445 {
6446 if (!TARGET_FCFIDS)
6447 {
6448 rtx val = operands[1];
6449 if (!flag_unsafe_math_optimizations)
6450 {
6451 rtx label = gen_label_rtx ();
6452 val = gen_reg_rtx (DImode);
6453 emit_insn (gen_floatdisf2_internal2 (val, operands[1], label));
6454 emit_label (label);
6455 }
6456 emit_insn (gen_floatdisf2_internal1 (operands[0], val));
6457 DONE;
6458 }
6459 })
6460
6461 (define_insn "floatdisf2_fcfids"
6462 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wa")
6463 (float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wa")))]
6464 "TARGET_HARD_FLOAT && TARGET_FCFIDS"
6465 "@
6466 fcfids %0,%1
6467 xscvsxdsp %x0,%x1"
6468 [(set_attr "type" "fp")
6469 (set_attr "isa" "*,p8v")])
6470
6471 (define_insn_and_split "*floatdisf2_mem"
6472 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wa,wa")
6473 (float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
6474 (clobber (match_scratch:DI 2 "=d,d,wa"))]
6475 "TARGET_HARD_FLOAT && TARGET_FCFIDS"
6476 "#"
6477 "&& reload_completed"
6478 [(pc)]
6479 {
6480 emit_move_insn (operands[2], operands[1]);
6481 emit_insn (gen_floatdisf2_fcfids (operands[0], operands[2]));
6482 DONE;
6483 }
6484 [(set_attr "length" "8")
6485 (set_attr "isa" "*,p8v,p8v")])
6486
6487 ;; This is not IEEE compliant if rounding mode is "round to nearest".
6488 ;; If the DI->DF conversion is inexact, then it's possible to suffer
6489 ;; from double rounding.
6490 ;; Instead of creating a new cpu type for two FP operations, just use fp
6491 (define_insn_and_split "floatdisf2_internal1"
6492 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
6493 (float:SF (match_operand:DI 1 "gpc_reg_operand" "d")))
6494 (clobber (match_scratch:DF 2 "=d"))]
6495 "TARGET_FCFID && TARGET_HARD_FLOAT && !TARGET_FCFIDS"
6496 "#"
6497 "&& reload_completed"
6498 [(set (match_dup 2)
6499 (float:DF (match_dup 1)))
6500 (set (match_dup 0)
6501 (float_truncate:SF (match_dup 2)))]
6502 ""
6503 [(set_attr "length" "8")
6504 (set_attr "type" "fp")])
6505
6506 ;; Twiddles bits to avoid double rounding.
6507 ;; Bits that might be truncated when converting to DFmode are replaced
6508 ;; by a bit that won't be lost at that stage, but is below the SFmode
6509 ;; rounding position.
6510 (define_expand "floatdisf2_internal2"
6511 [(parallel [(set (match_dup 3) (ashiftrt:DI (match_operand:DI 1 "")
6512 (const_int 53)))
6513 (clobber (reg:DI CA_REGNO))])
6514 (set (match_operand:DI 0 "") (and:DI (match_dup 1)
6515 (const_int 2047)))
6516 (set (match_dup 3) (plus:DI (match_dup 3)
6517 (const_int 1)))
6518 (set (match_dup 0) (plus:DI (match_dup 0)
6519 (const_int 2047)))
6520 (set (match_dup 4) (compare:CCUNS (match_dup 3)
6521 (const_int 2)))
6522 (set (match_dup 0) (ior:DI (match_dup 0)
6523 (match_dup 1)))
6524 (set (match_dup 0) (and:DI (match_dup 0)
6525 (const_int -2048)))
6526 (set (pc) (if_then_else (geu (match_dup 4) (const_int 0))
6527 (label_ref (match_operand:DI 2 ""))
6528 (pc)))
6529 (set (match_dup 0) (match_dup 1))]
6530 "TARGET_POWERPC64 && TARGET_HARD_FLOAT && !TARGET_FCFIDS"
6531 {
6532 operands[3] = gen_reg_rtx (DImode);
6533 operands[4] = gen_reg_rtx (CCUNSmode);
6534 })
6535
6536 (define_expand "floatunsdisf2"
6537 [(set (match_operand:SF 0 "gpc_reg_operand")
6538 (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand")))]
6539 "TARGET_HARD_FLOAT && TARGET_FCFIDUS"
6540 "")
6541
6542 (define_insn "floatunsdisf2_fcfidus"
6543 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wa")
6544 (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wa")))]
6545 "TARGET_HARD_FLOAT && TARGET_FCFIDUS"
6546 "@
6547 fcfidus %0,%1
6548 xscvuxdsp %x0,%x1"
6549 [(set_attr "type" "fp")
6550 (set_attr "isa" "*,p8v")])
6551
6552 (define_insn_and_split "*floatunsdisf2_mem"
6553 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wa,wa")
6554 (unsigned_float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
6555 (clobber (match_scratch:DI 2 "=d,d,wa"))]
6556 "TARGET_HARD_FLOAT && TARGET_FCFIDUS"
6557 "#"
6558 "&& reload_completed"
6559 [(pc)]
6560 {
6561 emit_move_insn (operands[2], operands[1]);
6562 emit_insn (gen_floatunsdisf2_fcfidus (operands[0], operands[2]));
6563 DONE;
6564 }
6565 [(set_attr "type" "fpload")
6566 (set_attr "length" "8")
6567 (set_attr "isa" "*,p8v,p8v")])
6568 \f
6569 ;; Define the TImode operations that can be done in a small number
6570 ;; of instructions. The & constraints are to prevent the register
6571 ;; allocator from allocating registers that overlap with the inputs
6572 ;; (for example, having an input in 7,8 and an output in 6,7). We
6573 ;; also allow for the output being the same as one of the inputs.
6574
6575 (define_expand "addti3"
6576 [(set (match_operand:TI 0 "gpc_reg_operand")
6577 (plus:TI (match_operand:TI 1 "gpc_reg_operand")
6578 (match_operand:TI 2 "reg_or_short_operand")))]
6579 "TARGET_64BIT"
6580 {
6581 rtx lo0 = gen_lowpart (DImode, operands[0]);
6582 rtx lo1 = gen_lowpart (DImode, operands[1]);
6583 rtx lo2 = gen_lowpart (DImode, operands[2]);
6584 rtx hi0 = gen_highpart (DImode, operands[0]);
6585 rtx hi1 = gen_highpart (DImode, operands[1]);
6586 rtx hi2 = gen_highpart_mode (DImode, TImode, operands[2]);
6587
6588 if (!reg_or_short_operand (lo2, DImode))
6589 lo2 = force_reg (DImode, lo2);
6590 if (!adde_operand (hi2, DImode))
6591 hi2 = force_reg (DImode, hi2);
6592
6593 emit_insn (gen_adddi3_carry (lo0, lo1, lo2));
6594 emit_insn (gen_adddi3_carry_in (hi0, hi1, hi2));
6595 DONE;
6596 })
6597
6598 (define_expand "subti3"
6599 [(set (match_operand:TI 0 "gpc_reg_operand")
6600 (minus:TI (match_operand:TI 1 "reg_or_short_operand")
6601 (match_operand:TI 2 "gpc_reg_operand")))]
6602 "TARGET_64BIT"
6603 {
6604 rtx lo0 = gen_lowpart (DImode, operands[0]);
6605 rtx lo1 = gen_lowpart (DImode, operands[1]);
6606 rtx lo2 = gen_lowpart (DImode, operands[2]);
6607 rtx hi0 = gen_highpart (DImode, operands[0]);
6608 rtx hi1 = gen_highpart_mode (DImode, TImode, operands[1]);
6609 rtx hi2 = gen_highpart (DImode, operands[2]);
6610
6611 if (!reg_or_short_operand (lo1, DImode))
6612 lo1 = force_reg (DImode, lo1);
6613 if (!adde_operand (hi1, DImode))
6614 hi1 = force_reg (DImode, hi1);
6615
6616 emit_insn (gen_subfdi3_carry (lo0, lo2, lo1));
6617 emit_insn (gen_subfdi3_carry_in (hi0, hi2, hi1));
6618 DONE;
6619 })
6620 \f
6621 ;; 128-bit logical operations expanders
6622
6623 (define_expand "and<mode>3"
6624 [(set (match_operand:BOOL_128 0 "vlogical_operand")
6625 (and:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")
6626 (match_operand:BOOL_128 2 "vlogical_operand")))]
6627 ""
6628 "")
6629
6630 (define_expand "ior<mode>3"
6631 [(set (match_operand:BOOL_128 0 "vlogical_operand")
6632 (ior:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")
6633 (match_operand:BOOL_128 2 "vlogical_operand")))]
6634 ""
6635 "")
6636
6637 (define_expand "xor<mode>3"
6638 [(set (match_operand:BOOL_128 0 "vlogical_operand")
6639 (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")
6640 (match_operand:BOOL_128 2 "vlogical_operand")))]
6641 ""
6642 "")
6643
6644 (define_expand "nor<mode>3"
6645 [(set (match_operand:BOOL_128 0 "vlogical_operand")
6646 (and:BOOL_128
6647 (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand"))
6648 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))))]
6649 ""
6650 "")
6651
6652 (define_expand "andc<mode>3"
6653 [(set (match_operand:BOOL_128 0 "vlogical_operand")
6654 (and:BOOL_128
6655 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))
6656 (match_operand:BOOL_128 1 "vlogical_operand")))]
6657 ""
6658 "")
6659
6660 ;; Power8 vector logical instructions.
6661 (define_expand "eqv<mode>3"
6662 [(set (match_operand:BOOL_128 0 "vlogical_operand")
6663 (not:BOOL_128
6664 (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")
6665 (match_operand:BOOL_128 2 "vlogical_operand"))))]
6666 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6667 "")
6668
6669 ;; Rewrite nand into canonical form
6670 (define_expand "nand<mode>3"
6671 [(set (match_operand:BOOL_128 0 "vlogical_operand")
6672 (ior:BOOL_128
6673 (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand"))
6674 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))))]
6675 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6676 "")
6677
6678 ;; The canonical form is to have the negated element first, so we need to
6679 ;; reverse arguments.
6680 (define_expand "orc<mode>3"
6681 [(set (match_operand:BOOL_128 0 "vlogical_operand")
6682 (ior:BOOL_128
6683 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))
6684 (match_operand:BOOL_128 1 "vlogical_operand")))]
6685 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6686 "")
6687
6688 ;; 128-bit logical operations insns and split operations
6689 (define_insn_and_split "*and<mode>3_internal"
6690 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6691 (and:BOOL_128
6692 (match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
6693 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")))]
6694 ""
6695 {
6696 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6697 return "xxland %x0,%x1,%x2";
6698
6699 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6700 return "vand %0,%1,%2";
6701
6702 return "#";
6703 }
6704 "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6705 [(const_int 0)]
6706 {
6707 rs6000_split_logical (operands, AND, false, false, false);
6708 DONE;
6709 }
6710 [(set (attr "type")
6711 (if_then_else
6712 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6713 (const_string "veclogical")
6714 (const_string "integer")))
6715 (set (attr "length")
6716 (if_then_else
6717 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6718 (const_string "4")
6719 (if_then_else
6720 (match_test "TARGET_POWERPC64")
6721 (const_string "8")
6722 (const_string "16"))))])
6723
6724 ;; 128-bit IOR/XOR
6725 (define_insn_and_split "*bool<mode>3_internal"
6726 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6727 (match_operator:BOOL_128 3 "boolean_or_operator"
6728 [(match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
6729 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")]))]
6730 ""
6731 {
6732 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6733 return "xxl%q3 %x0,%x1,%x2";
6734
6735 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6736 return "v%q3 %0,%1,%2";
6737
6738 return "#";
6739 }
6740 "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6741 [(const_int 0)]
6742 {
6743 rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, false);
6744 DONE;
6745 }
6746 [(set (attr "type")
6747 (if_then_else
6748 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6749 (const_string "veclogical")
6750 (const_string "integer")))
6751 (set (attr "length")
6752 (if_then_else
6753 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6754 (const_string "4")
6755 (if_then_else
6756 (match_test "TARGET_POWERPC64")
6757 (const_string "8")
6758 (const_string "16"))))])
6759
6760 ;; 128-bit ANDC/ORC
6761 (define_insn_and_split "*boolc<mode>3_internal1"
6762 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6763 (match_operator:BOOL_128 3 "boolean_operator"
6764 [(not:BOOL_128
6765 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))
6766 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")]))]
6767 "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
6768 {
6769 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6770 return "xxl%q3 %x0,%x1,%x2";
6771
6772 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6773 return "v%q3 %0,%1,%2";
6774
6775 return "#";
6776 }
6777 "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
6778 && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6779 [(const_int 0)]
6780 {
6781 rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
6782 DONE;
6783 }
6784 [(set (attr "type")
6785 (if_then_else
6786 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6787 (const_string "veclogical")
6788 (const_string "integer")))
6789 (set (attr "length")
6790 (if_then_else
6791 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6792 (const_string "4")
6793 (if_then_else
6794 (match_test "TARGET_POWERPC64")
6795 (const_string "8")
6796 (const_string "16"))))])
6797
6798 (define_insn_and_split "*boolc<mode>3_internal2"
6799 [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6800 (match_operator:TI2 3 "boolean_operator"
6801 [(not:TI2
6802 (match_operand:TI2 2 "int_reg_operand" "r,0,r"))
6803 (match_operand:TI2 1 "int_reg_operand" "r,r,0")]))]
6804 "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6805 "#"
6806 "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6807 [(const_int 0)]
6808 {
6809 rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
6810 DONE;
6811 }
6812 [(set_attr "type" "integer")
6813 (set (attr "length")
6814 (if_then_else
6815 (match_test "TARGET_POWERPC64")
6816 (const_string "8")
6817 (const_string "16")))])
6818
6819 ;; 128-bit NAND/NOR
6820 (define_insn_and_split "*boolcc<mode>3_internal1"
6821 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6822 (match_operator:BOOL_128 3 "boolean_operator"
6823 [(not:BOOL_128
6824 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>"))
6825 (not:BOOL_128
6826 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))]))]
6827 "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
6828 {
6829 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6830 return "xxl%q3 %x0,%x1,%x2";
6831
6832 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6833 return "v%q3 %0,%1,%2";
6834
6835 return "#";
6836 }
6837 "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
6838 && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6839 [(const_int 0)]
6840 {
6841 rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
6842 DONE;
6843 }
6844 [(set (attr "type")
6845 (if_then_else
6846 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6847 (const_string "veclogical")
6848 (const_string "integer")))
6849 (set (attr "length")
6850 (if_then_else
6851 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6852 (const_string "4")
6853 (if_then_else
6854 (match_test "TARGET_POWERPC64")
6855 (const_string "8")
6856 (const_string "16"))))])
6857
6858 (define_insn_and_split "*boolcc<mode>3_internal2"
6859 [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6860 (match_operator:TI2 3 "boolean_operator"
6861 [(not:TI2
6862 (match_operand:TI2 1 "int_reg_operand" "r,0,r"))
6863 (not:TI2
6864 (match_operand:TI2 2 "int_reg_operand" "r,r,0"))]))]
6865 "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6866 "#"
6867 "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6868 [(const_int 0)]
6869 {
6870 rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
6871 DONE;
6872 }
6873 [(set_attr "type" "integer")
6874 (set (attr "length")
6875 (if_then_else
6876 (match_test "TARGET_POWERPC64")
6877 (const_string "8")
6878 (const_string "16")))])
6879
6880
6881 ;; 128-bit EQV
6882 (define_insn_and_split "*eqv<mode>3_internal1"
6883 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6884 (not:BOOL_128
6885 (xor:BOOL_128
6886 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")
6887 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))))]
6888 "TARGET_P8_VECTOR"
6889 {
6890 if (vsx_register_operand (operands[0], <MODE>mode))
6891 return "xxleqv %x0,%x1,%x2";
6892
6893 return "#";
6894 }
6895 "TARGET_P8_VECTOR && reload_completed
6896 && int_reg_operand (operands[0], <MODE>mode)"
6897 [(const_int 0)]
6898 {
6899 rs6000_split_logical (operands, XOR, true, false, false);
6900 DONE;
6901 }
6902 [(set (attr "type")
6903 (if_then_else
6904 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6905 (const_string "veclogical")
6906 (const_string "integer")))
6907 (set (attr "length")
6908 (if_then_else
6909 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6910 (const_string "4")
6911 (if_then_else
6912 (match_test "TARGET_POWERPC64")
6913 (const_string "8")
6914 (const_string "16"))))])
6915
6916 (define_insn_and_split "*eqv<mode>3_internal2"
6917 [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6918 (not:TI2
6919 (xor:TI2
6920 (match_operand:TI2 1 "int_reg_operand" "r,0,r")
6921 (match_operand:TI2 2 "int_reg_operand" "r,r,0"))))]
6922 "!TARGET_P8_VECTOR"
6923 "#"
6924 "reload_completed && !TARGET_P8_VECTOR"
6925 [(const_int 0)]
6926 {
6927 rs6000_split_logical (operands, XOR, true, false, false);
6928 DONE;
6929 }
6930 [(set_attr "type" "integer")
6931 (set (attr "length")
6932 (if_then_else
6933 (match_test "TARGET_POWERPC64")
6934 (const_string "8")
6935 (const_string "16")))])
6936
6937 ;; 128-bit one's complement
6938 (define_insn_and_split "one_cmpl<mode>2"
6939 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6940 (not:BOOL_128
6941 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_UNARY>")))]
6942 ""
6943 {
6944 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6945 return "xxlnor %x0,%x1,%x1";
6946
6947 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6948 return "vnor %0,%1,%1";
6949
6950 return "#";
6951 }
6952 "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6953 [(const_int 0)]
6954 {
6955 rs6000_split_logical (operands, NOT, false, false, false);
6956 DONE;
6957 }
6958 [(set (attr "type")
6959 (if_then_else
6960 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6961 (const_string "veclogical")
6962 (const_string "integer")))
6963 (set (attr "length")
6964 (if_then_else
6965 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6966 (const_string "4")
6967 (if_then_else
6968 (match_test "TARGET_POWERPC64")
6969 (const_string "8")
6970 (const_string "16"))))])
6971
6972 \f
6973 ;; Now define ways of moving data around.
6974
6975 ;; Set up a register with a value from the GOT table
6976
6977 (define_expand "movsi_got"
6978 [(set (match_operand:SI 0 "gpc_reg_operand")
6979 (unspec:SI [(match_operand:SI 1 "got_operand")
6980 (match_dup 2)] UNSPEC_MOVSI_GOT))]
6981 "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
6982 {
6983 if (GET_CODE (operands[1]) == CONST)
6984 {
6985 rtx offset = const0_rtx;
6986 HOST_WIDE_INT value;
6987
6988 operands[1] = eliminate_constant_term (XEXP (operands[1], 0), &offset);
6989 value = INTVAL (offset);
6990 if (value != 0)
6991 {
6992 rtx tmp = (!can_create_pseudo_p ()
6993 ? operands[0]
6994 : gen_reg_rtx (Pmode));
6995 emit_insn (gen_movsi_got (tmp, operands[1]));
6996 emit_insn (gen_addsi3 (operands[0], tmp, offset));
6997 DONE;
6998 }
6999 }
7000
7001 operands[2] = rs6000_got_register (operands[1]);
7002 })
7003
7004 (define_insn "*movsi_got_internal"
7005 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
7006 (unspec:SI [(match_operand:SI 1 "got_no_const_operand" "")
7007 (match_operand:SI 2 "gpc_reg_operand" "b")]
7008 UNSPEC_MOVSI_GOT))]
7009 "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
7010 "lwz %0,%a1@got(%2)"
7011 [(set_attr "type" "load")])
7012
7013 ;; Used by sched, shorten_branches and final when the GOT pseudo reg
7014 ;; didn't get allocated to a hard register.
7015 (define_split
7016 [(set (match_operand:SI 0 "gpc_reg_operand")
7017 (unspec:SI [(match_operand:SI 1 "got_no_const_operand")
7018 (match_operand:SI 2 "memory_operand")]
7019 UNSPEC_MOVSI_GOT))]
7020 "DEFAULT_ABI == ABI_V4
7021 && flag_pic == 1
7022 && reload_completed"
7023 [(set (match_dup 0) (match_dup 2))
7024 (set (match_dup 0) (unspec:SI [(match_dup 1)(match_dup 0)]
7025 UNSPEC_MOVSI_GOT))]
7026 "")
7027
7028 ;; MR LA
7029 ;; LWZ LFIWZX LXSIWZX
7030 ;; STW STFIWX STXSIWX
7031 ;; LI LIS PLI #
7032 ;; XXLOR XXSPLTIB 0 XXSPLTIB -1 VSPLTISW
7033 ;; XXLXOR 0 XXLORC -1 P9 const
7034 ;; MTVSRWZ MFVSRWZ
7035 ;; MF%1 MT%0 NOP
7036
7037 (define_insn "*movsi_internal1"
7038 [(set (match_operand:SI 0 "nonimmediate_operand"
7039 "=r, r,
7040 r, d, v,
7041 m, Z, Z,
7042 r, r, r, r,
7043 wa, wa, wa, v,
7044 wa, v, v,
7045 wa, r,
7046 r, *h, *h")
7047 (match_operand:SI 1 "input_operand"
7048 "r, U,
7049 m, Z, Z,
7050 r, d, v,
7051 I, L, eI, n,
7052 wa, O, wM, wB,
7053 O, wM, wS,
7054 r, wa,
7055 *h, r, 0"))]
7056 "gpc_reg_operand (operands[0], SImode)
7057 || gpc_reg_operand (operands[1], SImode)"
7058 "@
7059 mr %0,%1
7060 la %0,%a1
7061 lwz%U1%X1 %0,%1
7062 lfiwzx %0,%y1
7063 lxsiwzx %x0,%y1
7064 stw%U0%X0 %1,%0
7065 stfiwx %1,%y0
7066 stxsiwx %x1,%y0
7067 li %0,%1
7068 lis %0,%v1
7069 li %0,%1
7070 #
7071 xxlor %x0,%x1,%x1
7072 xxspltib %x0,0
7073 xxspltib %x0,255
7074 vspltisw %0,%1
7075 xxlxor %x0,%x0,%x0
7076 xxlorc %x0,%x0,%x0
7077 #
7078 mtvsrwz %x0,%1
7079 mfvsrwz %0,%x1
7080 mf%1 %0
7081 mt%0 %1
7082 nop"
7083 [(set_attr "type"
7084 "*, *,
7085 load, fpload, fpload,
7086 store, fpstore, fpstore,
7087 *, *, *, *,
7088 veclogical, vecsimple, vecsimple, vecsimple,
7089 veclogical, veclogical, vecsimple,
7090 mtvsr, mfvsr,
7091 *, *, *")
7092 (set_attr "length"
7093 "*, *,
7094 *, *, *,
7095 *, *, *,
7096 *, *, *, 8,
7097 *, *, *, *,
7098 *, *, 8,
7099 *, *,
7100 *, *, *")
7101 (set_attr "isa"
7102 "*, *,
7103 *, p8v, p8v,
7104 *, p8v, p8v,
7105 *, *, p10, *,
7106 p8v, p9v, p9v, p8v,
7107 p9v, p8v, p9v,
7108 p8v, p8v,
7109 *, *, *")])
7110
7111 ;; Like movsi, but adjust a SF value to be used in a SI context, i.e.
7112 ;; (set (reg:SI ...) (subreg:SI (reg:SF ...) 0))
7113 ;;
7114 ;; Because SF values are actually stored as DF values within the vector
7115 ;; registers, we need to convert the value to the vector SF format when
7116 ;; we need to use the bits in a union or similar cases. We only need
7117 ;; to do this transformation when the value is a vector register. Loads,
7118 ;; stores, and transfers within GPRs are assumed to be safe.
7119 ;;
7120 ;; This is a more general case of reload_gpr_from_vsxsf. That insn must have
7121 ;; no alternatives, because the call is created as part of secondary_reload,
7122 ;; and operand #2's register class is used to allocate the temporary register.
7123 ;; This function is called before reload, and it creates the temporary as
7124 ;; needed.
7125
7126 ;; MR LWZ LFIWZX LXSIWZX STW
7127 ;; STFS STXSSP STXSSPX VSX->GPR VSX->VSX
7128 ;; MTVSRWZ
7129
7130 (define_insn_and_split "movsi_from_sf"
7131 [(set (match_operand:SI 0 "nonimmediate_operand"
7132 "=r, r, ?*d, ?*v, m,
7133 m, wY, Z, r, ?*wa,
7134 wa")
7135 (unspec:SI [(match_operand:SF 1 "input_operand"
7136 "r, m, Z, Z, r,
7137 f, v, wa, wa, wa,
7138 r")]
7139 UNSPEC_SI_FROM_SF))
7140 (clobber (match_scratch:V4SF 2
7141 "=X, X, X, X, X,
7142 X, X, X, wa, X,
7143 X"))]
7144 "TARGET_NO_SF_SUBREG
7145 && (register_operand (operands[0], SImode)
7146 || register_operand (operands[1], SFmode))"
7147 "@
7148 mr %0,%1
7149 lwz%U1%X1 %0,%1
7150 lfiwzx %0,%y1
7151 lxsiwzx %x0,%y1
7152 stw%U0%X0 %1,%0
7153 stfs%U0%X0 %1,%0
7154 stxssp %1,%0
7155 stxsspx %x1,%y0
7156 #
7157 xscvdpspn %x0,%x1
7158 mtvsrwz %x0,%1"
7159 "&& reload_completed
7160 && int_reg_operand (operands[0], SImode)
7161 && vsx_reg_sfsubreg_ok (operands[1], SFmode)"
7162 [(const_int 0)]
7163 {
7164 rtx op0 = operands[0];
7165 rtx op1 = operands[1];
7166 rtx op2 = operands[2];
7167 rtx op0_di = gen_rtx_REG (DImode, reg_or_subregno (op0));
7168 rtx op2_si = gen_rtx_REG (SImode, reg_or_subregno (op2));
7169
7170 emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
7171 emit_insn (gen_zero_extendsidi2 (op0_di, op2_si));
7172 DONE;
7173 }
7174 [(set_attr "type"
7175 "*, load, fpload, fpload, store,
7176 fpstore, fpstore, fpstore, mfvsr, fp,
7177 mtvsr")
7178 (set_attr "length"
7179 "*, *, *, *, *,
7180 *, *, *, 8, *,
7181 *")
7182 (set_attr "isa"
7183 "*, *, p8v, p8v, *,
7184 *, p9v, p8v, p8v, p8v,
7185 p8v")])
7186
7187 ;; movsi_from_sf with zero extension
7188 ;;
7189 ;; RLDICL LWZ LFIWZX LXSIWZX VSX->GPR
7190 ;; VSX->VSX MTVSRWZ
7191
7192 (define_insn_and_split "*movdi_from_sf_zero_ext"
7193 [(set (match_operand:DI 0 "gpc_reg_operand"
7194 "=r, r, ?*d, ?*v, r,
7195 ?v, wa")
7196 (zero_extend:DI
7197 (unspec:SI [(match_operand:SF 1 "input_operand"
7198 "r, m, Z, Z, wa,
7199 wa, r")]
7200 UNSPEC_SI_FROM_SF)))
7201 (clobber (match_scratch:V4SF 2
7202 "=X, X, X, X, wa,
7203 wa, X"))]
7204 "TARGET_DIRECT_MOVE_64BIT
7205 && (register_operand (operands[0], DImode)
7206 || register_operand (operands[1], SImode))"
7207 "@
7208 rldicl %0,%1,0,32
7209 lwz%U1%X1 %0,%1
7210 lfiwzx %0,%y1
7211 lxsiwzx %x0,%y1
7212 #
7213 #
7214 mtvsrwz %x0,%1"
7215 "&& reload_completed
7216 && register_operand (operands[0], DImode)
7217 && vsx_reg_sfsubreg_ok (operands[1], SFmode)"
7218 [(const_int 0)]
7219 {
7220 rtx op0 = operands[0];
7221 rtx op1 = operands[1];
7222 rtx op2 = operands[2];
7223 rtx op2_si = gen_rtx_REG (SImode, reg_or_subregno (op2));
7224
7225 emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
7226 emit_insn (gen_zero_extendsidi2 (op0, op2_si));
7227 DONE;
7228 }
7229 [(set_attr "type"
7230 "*, load, fpload, fpload, two,
7231 two, mtvsr")
7232 (set_attr "length"
7233 "*, *, *, *, 8,
7234 8, *")
7235 (set_attr "isa"
7236 "*, *, p8v, p8v, p8v,
7237 p9v, p8v")])
7238
7239 ;; Like movsi_from_sf, but combine a convert from DFmode to SFmode before
7240 ;; moving it to SImode. We cannot do a SFmode store without having to do the
7241 ;; conversion explicitly since that doesn't work in most cases if the input
7242 ;; isn't representable as SF. Use XSCVDPSP instead of XSCVDPSPN, since the
7243 ;; former handles cases where the input will not fit in a SFmode, and the
7244 ;; latter assumes the value has already been rounded.
7245 (define_insn "*movsi_from_df"
7246 [(set (match_operand:SI 0 "gpc_reg_operand" "=wa")
7247 (unspec:SI [(float_truncate:SF
7248 (match_operand:DF 1 "gpc_reg_operand" "wa"))]
7249 UNSPEC_SI_FROM_SF))]
7250 "TARGET_NO_SF_SUBREG"
7251 "xscvdpsp %x0,%x1"
7252 [(set_attr "type" "fp")])
7253
7254 ;; Split a load of a large constant into the appropriate two-insn
7255 ;; sequence.
7256
7257 (define_split
7258 [(set (match_operand:SI 0 "gpc_reg_operand")
7259 (match_operand:SI 1 "const_int_operand"))]
7260 "num_insns_constant (operands[1], SImode) > 1"
7261 [(set (match_dup 0)
7262 (match_dup 2))
7263 (set (match_dup 0)
7264 (ior:SI (match_dup 0)
7265 (match_dup 3)))]
7266 {
7267 if (rs6000_emit_set_const (operands[0], operands[1]))
7268 DONE;
7269 else
7270 FAIL;
7271 })
7272
7273 ;; Split loading -128..127 to use XXSPLITB and VEXTSW2D
7274 (define_split
7275 [(set (match_operand:DI 0 "altivec_register_operand")
7276 (match_operand:DI 1 "xxspltib_constant_split"))]
7277 "TARGET_P9_VECTOR && reload_completed"
7278 [(const_int 0)]
7279 {
7280 rtx op0 = operands[0];
7281 rtx op1 = operands[1];
7282 int r = REGNO (op0);
7283 rtx op0_v16qi = gen_rtx_REG (V16QImode, r);
7284
7285 emit_insn (gen_xxspltib_v16qi (op0_v16qi, op1));
7286 emit_insn (gen_vsx_sign_extend_qi_si (operands[0], op0_v16qi));
7287 DONE;
7288 })
7289
7290 (define_insn "*mov<mode>_internal2"
7291 [(set (match_operand:CC 2 "cc_reg_operand" "=y,x,?y")
7292 (compare:CC (match_operand:P 1 "gpc_reg_operand" "0,r,r")
7293 (const_int 0)))
7294 (set (match_operand:P 0 "gpc_reg_operand" "=r,r,r") (match_dup 1))]
7295 ""
7296 "@
7297 cmp<wd>i %2,%0,0
7298 mr. %0,%1
7299 #"
7300 [(set_attr "type" "cmp,logical,cmp")
7301 (set_attr "dot" "yes")
7302 (set_attr "length" "4,4,8")])
7303
7304 (define_split
7305 [(set (match_operand:CC 2 "cc_reg_not_cr0_operand")
7306 (compare:CC (match_operand:P 1 "gpc_reg_operand")
7307 (const_int 0)))
7308 (set (match_operand:P 0 "gpc_reg_operand") (match_dup 1))]
7309 "reload_completed"
7310 [(set (match_dup 0) (match_dup 1))
7311 (set (match_dup 2)
7312 (compare:CC (match_dup 0)
7313 (const_int 0)))]
7314 "")
7315 \f
7316 (define_expand "mov<mode>"
7317 [(set (match_operand:INT 0 "general_operand")
7318 (match_operand:INT 1 "any_operand"))]
7319 ""
7320 {
7321 rs6000_emit_move (operands[0], operands[1], <MODE>mode);
7322 DONE;
7323 })
7324
7325 ;; MR LHZ/LBZ LXSI*ZX STH/STB STXSI*X LI
7326 ;; XXLOR load 0 load -1 VSPLTI* # MFVSRWZ
7327 ;; MTVSRWZ MF%1 MT%1 NOP
7328 (define_insn "*mov<mode>_internal"
7329 [(set (match_operand:QHI 0 "nonimmediate_operand"
7330 "=r, r, wa, m, Z, r,
7331 wa, wa, wa, v, ?v, r,
7332 wa, r, *c*l, *h")
7333 (match_operand:QHI 1 "input_operand"
7334 "r, m, Z, r, wa, i,
7335 wa, O, wM, wB, wS, wa,
7336 r, *h, r, 0"))]
7337 "gpc_reg_operand (operands[0], <MODE>mode)
7338 || gpc_reg_operand (operands[1], <MODE>mode)"
7339 "@
7340 mr %0,%1
7341 l<wd>z%U1%X1 %0,%1
7342 lxsi<wd>zx %x0,%y1
7343 st<wd>%U0%X0 %1,%0
7344 stxsi<wd>x %x1,%y0
7345 li %0,%1
7346 xxlor %x0,%x1,%x1
7347 xxspltib %x0,0
7348 xxspltib %x0,255
7349 vspltis<wd> %0,%1
7350 #
7351 mfvsrwz %0,%x1
7352 mtvsrwz %x0,%1
7353 mf%1 %0
7354 mt%0 %1
7355 nop"
7356 [(set_attr "type"
7357 "*, load, fpload, store, fpstore, *,
7358 vecsimple, vecperm, vecperm, vecperm, vecperm, mfvsr,
7359 mtvsr, mfjmpr, mtjmpr, *")
7360 (set_attr "length"
7361 "*, *, *, *, *, *,
7362 *, *, *, *, 8, *,
7363 *, *, *, *")
7364 (set_attr "isa"
7365 "*, *, p9v, *, p9v, *,
7366 p9v, p9v, p9v, p9v, p9v, p9v,
7367 p9v, *, *, *")])
7368
7369 \f
7370 ;; Here is how to move condition codes around. When we store CC data in
7371 ;; an integer register or memory, we store just the high-order 4 bits.
7372 ;; This lets us not shift in the most common case of CR0.
7373 (define_expand "movcc"
7374 [(set (match_operand:CC 0 "nonimmediate_operand")
7375 (match_operand:CC 1 "nonimmediate_operand"))]
7376 ""
7377 "")
7378
7379 (define_mode_iterator CC_any [CC CCUNS CCEQ CCFP])
7380
7381 (define_insn "*movcc_<mode>"
7382 [(set (match_operand:CC_any 0 "nonimmediate_operand"
7383 "=y,x,?y,y,r,r,r,r, r,*c*l,r,m")
7384 (match_operand:CC_any 1 "general_operand"
7385 " y,r, r,O,x,y,r,I,*h, r,m,r"))]
7386 "register_operand (operands[0], <MODE>mode)
7387 || register_operand (operands[1], <MODE>mode)"
7388 "@
7389 mcrf %0,%1
7390 mtcrf 128,%1
7391 rlwinm %1,%1,%F0,0xffffffff\;mtcrf %R0,%1\;rlwinm %1,%1,%f0,0xffffffff
7392 crxor %0,%0,%0
7393 mfcr %0%Q1
7394 mfcr %0%Q1\;rlwinm %0,%0,%f1,0xf0000000
7395 mr %0,%1
7396 li %0,%1
7397 mf%1 %0
7398 mt%0 %1
7399 lwz%U1%X1 %0,%1
7400 stw%U0%X0 %1,%0"
7401 [(set_attr_alternative "type"
7402 [(const_string "cr_logical")
7403 (const_string "mtcr")
7404 (const_string "mtcr")
7405 (const_string "cr_logical")
7406 (if_then_else (match_test "TARGET_MFCRF")
7407 (const_string "mfcrf") (const_string "mfcr"))
7408 (if_then_else (match_test "TARGET_MFCRF")
7409 (const_string "mfcrf") (const_string "mfcr"))
7410 (const_string "integer")
7411 (const_string "integer")
7412 (const_string "mfjmpr")
7413 (const_string "mtjmpr")
7414 (const_string "load")
7415 (const_string "store")])
7416 (set_attr "length" "*,*,12,*,*,8,*,*,*,*,*,*")])
7417 \f
7418 ;; For floating-point, we normally deal with the floating-point registers
7419 ;; unless -msoft-float is used. The sole exception is that parameter passing
7420 ;; can produce floating-point values in fixed-point registers. Unless the
7421 ;; value is a simple constant or already in memory, we deal with this by
7422 ;; allocating memory and copying the value explicitly via that memory location.
7423
7424 ;; Move 32-bit binary/decimal floating point
7425 (define_expand "mov<mode>"
7426 [(set (match_operand:FMOVE32 0 "nonimmediate_operand")
7427 (match_operand:FMOVE32 1 "any_operand"))]
7428 "<fmove_ok>"
7429 {
7430 rs6000_emit_move (operands[0], operands[1], <MODE>mode);
7431 DONE;
7432 })
7433
7434 (define_split
7435 [(set (match_operand:FMOVE32 0 "gpc_reg_operand")
7436 (match_operand:FMOVE32 1 "const_double_operand"))]
7437 "reload_completed
7438 && ((REG_P (operands[0]) && REGNO (operands[0]) <= 31)
7439 || (SUBREG_P (operands[0])
7440 && REG_P (SUBREG_REG (operands[0]))
7441 && REGNO (SUBREG_REG (operands[0])) <= 31))"
7442 [(set (match_dup 2) (match_dup 3))]
7443 {
7444 long l;
7445
7446 <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7447
7448 if (! TARGET_POWERPC64)
7449 operands[2] = operand_subword (operands[0], 0, 0, <MODE>mode);
7450 else
7451 operands[2] = gen_lowpart (SImode, operands[0]);
7452
7453 operands[3] = gen_int_mode (l, SImode);
7454 })
7455
7456 ;; Originally, we tried to keep movsf and movsd common, but the differences
7457 ;; addressing was making it rather difficult to hide with mode attributes. In
7458 ;; particular for SFmode, on ISA 2.07 (power8) systems, having the GPR store
7459 ;; before the VSX stores meant that the register allocator would tend to do a
7460 ;; direct move to the GPR (which involves conversion from scalar to
7461 ;; vector/memory formats) to save values in the traditional Altivec registers,
7462 ;; while SDmode had problems on power6 if the GPR store was not first due to
7463 ;; the power6 not having an integer store operation.
7464 ;;
7465 ;; LWZ LFS LXSSP LXSSPX STFS STXSSP
7466 ;; STXSSPX STW XXLXOR LI FMR XSCPSGNDP
7467 ;; MR MT<x> MF<x> NOP
7468
7469 (define_insn "movsf_hardfloat"
7470 [(set (match_operand:SF 0 "nonimmediate_operand"
7471 "=!r, f, v, wa, m, wY,
7472 Z, m, wa, !r, f, wa,
7473 !r, *c*l, !r, *h")
7474 (match_operand:SF 1 "input_operand"
7475 "m, m, wY, Z, f, v,
7476 wa, r, j, j, f, wa,
7477 r, r, *h, 0"))]
7478 "(register_operand (operands[0], SFmode)
7479 || register_operand (operands[1], SFmode))
7480 && TARGET_HARD_FLOAT
7481 && (TARGET_ALLOW_SF_SUBREG
7482 || valid_sf_si_move (operands[0], operands[1], SFmode))"
7483 "@
7484 lwz%U1%X1 %0,%1
7485 lfs%U1%X1 %0,%1
7486 lxssp %0,%1
7487 lxsspx %x0,%y1
7488 stfs%U0%X0 %1,%0
7489 stxssp %1,%0
7490 stxsspx %x1,%y0
7491 stw%U0%X0 %1,%0
7492 xxlxor %x0,%x0,%x0
7493 li %0,0
7494 fmr %0,%1
7495 xscpsgndp %x0,%x1,%x1
7496 mr %0,%1
7497 mt%0 %1
7498 mf%1 %0
7499 nop"
7500 [(set_attr "type"
7501 "load, fpload, fpload, fpload, fpstore, fpstore,
7502 fpstore, store, veclogical, integer, fpsimple, fpsimple,
7503 *, mtjmpr, mfjmpr, *")
7504 (set_attr "isa"
7505 "*, *, p9v, p8v, *, p9v,
7506 p8v, *, *, *, *, *,
7507 *, *, *, *")])
7508
7509 ;; LWZ LFIWZX STW STFIWX MTVSRWZ MFVSRWZ
7510 ;; FMR MR MT%0 MF%1 NOP
7511 (define_insn "movsd_hardfloat"
7512 [(set (match_operand:SD 0 "nonimmediate_operand"
7513 "=!r, d, m, Z, ?d, ?r,
7514 f, !r, *c*l, !r, *h")
7515 (match_operand:SD 1 "input_operand"
7516 "m, Z, r, wx, r, d,
7517 f, r, r, *h, 0"))]
7518 "(register_operand (operands[0], SDmode)
7519 || register_operand (operands[1], SDmode))
7520 && TARGET_HARD_FLOAT"
7521 "@
7522 lwz%U1%X1 %0,%1
7523 lfiwzx %0,%y1
7524 stw%U0%X0 %1,%0
7525 stfiwx %1,%y0
7526 mtvsrwz %x0,%1
7527 mfvsrwz %0,%x1
7528 fmr %0,%1
7529 mr %0,%1
7530 mt%0 %1
7531 mf%1 %0
7532 nop"
7533 [(set_attr "type"
7534 "load, fpload, store, fpstore, mtvsr, mfvsr,
7535 fpsimple, *, mtjmpr, mfjmpr, *")
7536 (set_attr "isa"
7537 "*, p7, *, *, p8v, p8v,
7538 *, *, *, *, *")])
7539
7540 ;; MR MT%0 MF%0 LWZ STW LI
7541 ;; LIS G-const. F/n-const NOP
7542 (define_insn "*mov<mode>_softfloat"
7543 [(set (match_operand:FMOVE32 0 "nonimmediate_operand"
7544 "=r, *c*l, r, r, m, r,
7545 r, r, r, *h")
7546
7547 (match_operand:FMOVE32 1 "input_operand"
7548 "r, r, *h, m, r, I,
7549 L, G, Fn, 0"))]
7550
7551 "(gpc_reg_operand (operands[0], <MODE>mode)
7552 || gpc_reg_operand (operands[1], <MODE>mode))
7553 && TARGET_SOFT_FLOAT"
7554 "@
7555 mr %0,%1
7556 mt%0 %1
7557 mf%1 %0
7558 lwz%U1%X1 %0,%1
7559 stw%U0%X0 %1,%0
7560 li %0,%1
7561 lis %0,%v1
7562 #
7563 #
7564 nop"
7565 [(set_attr "type"
7566 "*, mtjmpr, mfjmpr, load, store, *,
7567 *, *, *, *")
7568
7569 (set_attr "length"
7570 "*, *, *, *, *, *,
7571 *, *, 8, *")])
7572
7573 ;; Like movsf, but adjust a SI value to be used in a SF context, i.e.
7574 ;; (set (reg:SF ...) (subreg:SF (reg:SI ...) 0))
7575 ;;
7576 ;; Because SF values are actually stored as DF values within the vector
7577 ;; registers, we need to convert the value to the vector SF format when
7578 ;; we need to use the bits in a union or similar cases. We only need
7579 ;; to do this transformation when the value is a vector register. Loads,
7580 ;; stores, and transfers within GPRs are assumed to be safe.
7581 ;;
7582 ;; This is a more general case of reload_vsx_from_gprsf. That insn must have
7583 ;; no alternatives, because the call is created as part of secondary_reload,
7584 ;; and operand #2's register class is used to allocate the temporary register.
7585 ;; This function is called before reload, and it creates the temporary as
7586 ;; needed.
7587
7588 ;; LWZ LFS LXSSP LXSSPX STW STFIWX
7589 ;; STXSIWX GPR->VSX VSX->GPR GPR->GPR
7590 (define_insn_and_split "movsf_from_si"
7591 [(set (match_operand:SF 0 "nonimmediate_operand"
7592 "=!r, f, v, wa, m, Z,
7593 Z, wa, ?r, !r")
7594 (unspec:SF [(match_operand:SI 1 "input_operand"
7595 "m, m, wY, Z, r, f,
7596 wa, r, wa, r")]
7597 UNSPEC_SF_FROM_SI))
7598 (clobber (match_scratch:DI 2
7599 "=X, X, X, X, X, X,
7600 X, r, X, X"))]
7601 "TARGET_NO_SF_SUBREG
7602 && (register_operand (operands[0], SFmode)
7603 || register_operand (operands[1], SImode))"
7604 "@
7605 lwz%U1%X1 %0,%1
7606 lfs%U1%X1 %0,%1
7607 lxssp %0,%1
7608 lxsspx %x0,%y1
7609 stw%U0%X0 %1,%0
7610 stfiwx %1,%y0
7611 stxsiwx %x1,%y0
7612 #
7613 mfvsrwz %0,%x1
7614 mr %0,%1"
7615
7616 "&& reload_completed
7617 && vsx_reg_sfsubreg_ok (operands[0], SFmode)
7618 && int_reg_operand_not_pseudo (operands[1], SImode)"
7619 [(const_int 0)]
7620 {
7621 rtx op0 = operands[0];
7622 rtx op1 = operands[1];
7623 rtx op2 = operands[2];
7624 rtx op1_di = gen_rtx_REG (DImode, REGNO (op1));
7625
7626 /* Move SF value to upper 32-bits for xscvspdpn. */
7627 emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32)));
7628 emit_insn (gen_p8_mtvsrd_sf (op0, op2));
7629 emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0));
7630 DONE;
7631 }
7632 [(set_attr "length"
7633 "*, *, *, *, *, *,
7634 *, 12, *, *")
7635 (set_attr "type"
7636 "load, fpload, fpload, fpload, store, fpstore,
7637 fpstore, vecfloat, mfvsr, *")
7638 (set_attr "isa"
7639 "*, *, p9v, p8v, *, *,
7640 p8v, p8v, p8v, *")])
7641
7642 ;; For extracting high part element from DImode register like:
7643 ;; {%1:SF=unspec[r122:DI>>0x20#0] 86;clobber scratch;}
7644 ;; split it before reload with "and mask" to avoid generating shift right
7645 ;; 32 bit then shift left 32 bit.
7646 (define_insn_and_split "movsf_from_si2"
7647 [(set (match_operand:SF 0 "gpc_reg_operand" "=wa")
7648 (unspec:SF
7649 [(subreg:SI
7650 (ashiftrt:DI
7651 (match_operand:DI 1 "input_operand" "r")
7652 (const_int 32))
7653 0)]
7654 UNSPEC_SF_FROM_SI))
7655 (clobber (match_scratch:DI 2 "=r"))]
7656 "TARGET_NO_SF_SUBREG"
7657 "#"
7658 "&& 1"
7659 [(const_int 0)]
7660 {
7661 if (GET_CODE (operands[2]) == SCRATCH)
7662 operands[2] = gen_reg_rtx (DImode);
7663
7664 rtx mask = GEN_INT (HOST_WIDE_INT_M1U << 32);
7665 emit_insn (gen_anddi3 (operands[2], operands[1], mask));
7666 emit_insn (gen_p8_mtvsrd_sf (operands[0], operands[2]));
7667 emit_insn (gen_vsx_xscvspdpn_directmove (operands[0], operands[0]));
7668 DONE;
7669 }
7670 [(set_attr "length" "12")
7671 (set_attr "type" "vecfloat")
7672 (set_attr "isa" "p8v")])
7673 \f
7674 ;; Move 64-bit binary/decimal floating point
7675 (define_expand "mov<mode>"
7676 [(set (match_operand:FMOVE64 0 "nonimmediate_operand")
7677 (match_operand:FMOVE64 1 "any_operand"))]
7678 ""
7679 {
7680 rs6000_emit_move (operands[0], operands[1], <MODE>mode);
7681 DONE;
7682 })
7683
7684 (define_split
7685 [(set (match_operand:FMOVE64 0 "gpc_reg_operand")
7686 (match_operand:FMOVE64 1 "const_int_operand"))]
7687 "! TARGET_POWERPC64 && reload_completed
7688 && ((REG_P (operands[0]) && REGNO (operands[0]) <= 31)
7689 || (SUBREG_P (operands[0])
7690 && REG_P (SUBREG_REG (operands[0]))
7691 && REGNO (SUBREG_REG (operands[0])) <= 31))"
7692 [(set (match_dup 2) (match_dup 4))
7693 (set (match_dup 3) (match_dup 1))]
7694 {
7695 int endian = (WORDS_BIG_ENDIAN == 0);
7696 HOST_WIDE_INT value = INTVAL (operands[1]);
7697
7698 operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
7699 operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
7700 operands[4] = GEN_INT (value >> 32);
7701 operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
7702 })
7703
7704 (define_split
7705 [(set (match_operand:FMOVE64 0 "gpc_reg_operand")
7706 (match_operand:FMOVE64 1 "const_double_operand"))]
7707 "! TARGET_POWERPC64 && reload_completed
7708 && ((REG_P (operands[0]) && REGNO (operands[0]) <= 31)
7709 || (SUBREG_P (operands[0])
7710 && REG_P (SUBREG_REG (operands[0]))
7711 && REGNO (SUBREG_REG (operands[0])) <= 31))"
7712 [(set (match_dup 2) (match_dup 4))
7713 (set (match_dup 3) (match_dup 5))]
7714 {
7715 int endian = (WORDS_BIG_ENDIAN == 0);
7716 long l[2];
7717
7718 <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7719
7720 operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
7721 operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
7722 operands[4] = gen_int_mode (l[endian], SImode);
7723 operands[5] = gen_int_mode (l[1 - endian], SImode);
7724 })
7725
7726 (define_split
7727 [(set (match_operand:FMOVE64 0 "gpc_reg_operand")
7728 (match_operand:FMOVE64 1 "const_double_operand"))]
7729 "TARGET_POWERPC64 && reload_completed
7730 && ((REG_P (operands[0]) && REGNO (operands[0]) <= 31)
7731 || (SUBREG_P (operands[0])
7732 && REG_P (SUBREG_REG (operands[0]))
7733 && REGNO (SUBREG_REG (operands[0])) <= 31))"
7734 [(set (match_dup 2) (match_dup 3))]
7735 {
7736 int endian = (WORDS_BIG_ENDIAN == 0);
7737 long l[2];
7738 HOST_WIDE_INT val;
7739
7740 <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7741
7742 operands[2] = gen_lowpart (DImode, operands[0]);
7743 /* HIGHPART is lower memory address when WORDS_BIG_ENDIAN. */
7744 val = ((HOST_WIDE_INT)(unsigned long)l[endian] << 32
7745 | ((HOST_WIDE_INT)(unsigned long)l[1 - endian]));
7746
7747 operands[3] = gen_int_mode (val, DImode);
7748 })
7749
7750 ;; Don't have reload use general registers to load a constant. It is
7751 ;; less efficient than loading the constant into an FP register, since
7752 ;; it will probably be used there.
7753
7754 ;; The move constraints are ordered to prefer floating point registers before
7755 ;; general purpose registers to avoid doing a store and a load to get the value
7756 ;; into a floating point register when it is needed for a floating point
7757 ;; operation. Prefer traditional floating point registers over VSX registers,
7758 ;; since the D-form version of the memory instructions does not need a GPR for
7759 ;; reloading. ISA 3.0 (power9) adds D-form addressing for scalars to Altivec
7760 ;; registers.
7761
7762 ;; If we have FPR registers, rs6000_emit_move has moved all constants to memory,
7763 ;; except for 0.0 which can be created on VSX with an xor instruction.
7764
7765 ;; STFD LFD FMR LXSD STXSD
7766 ;; LXSD STXSD XXLOR XXLXOR GPR<-0
7767 ;; LWZ STW MR
7768
7769
7770 (define_insn "*mov<mode>_hardfloat32"
7771 [(set (match_operand:FMOVE64 0 "nonimmediate_operand"
7772 "=m, d, d, <f64_p9>, wY,
7773 <f64_av>, Z, <f64_vsx>, <f64_vsx>, !r,
7774 Y, r, !r")
7775 (match_operand:FMOVE64 1 "input_operand"
7776 "d, m, d, wY, <f64_p9>,
7777 Z, <f64_av>, <f64_vsx>, <zero_fp>, <zero_fp>,
7778 r, Y, r"))]
7779 "! TARGET_POWERPC64 && TARGET_HARD_FLOAT
7780 && (gpc_reg_operand (operands[0], <MODE>mode)
7781 || gpc_reg_operand (operands[1], <MODE>mode))"
7782 "@
7783 stfd%U0%X0 %1,%0
7784 lfd%U1%X1 %0,%1
7785 fmr %0,%1
7786 lxsd %0,%1
7787 stxsd %1,%0
7788 lxsdx %x0,%y1
7789 stxsdx %x1,%y0
7790 xxlor %x0,%x1,%x1
7791 xxlxor %x0,%x0,%x0
7792 #
7793 #
7794 #
7795 #"
7796 [(set_attr "type"
7797 "fpstore, fpload, fpsimple, fpload, fpstore,
7798 fpload, fpstore, veclogical, veclogical, two,
7799 store, load, two")
7800 (set_attr "size" "64")
7801 (set_attr "length"
7802 "*, *, *, *, *,
7803 *, *, *, *, 8,
7804 8, 8, 8")
7805 (set_attr "isa"
7806 "*, *, *, p9v, p9v,
7807 p7v, p7v, *, *, *,
7808 *, *, *")])
7809
7810 ;; STW LWZ MR G-const H-const F-const
7811
7812 (define_insn "*mov<mode>_softfloat32"
7813 [(set (match_operand:FMOVE64 0 "nonimmediate_operand"
7814 "=Y, r, r, r, r, r")
7815
7816 (match_operand:FMOVE64 1 "input_operand"
7817 "r, Y, r, G, H, F"))]
7818
7819 "!TARGET_POWERPC64
7820 && (gpc_reg_operand (operands[0], <MODE>mode)
7821 || gpc_reg_operand (operands[1], <MODE>mode))"
7822 "#"
7823 [(set_attr "type"
7824 "store, load, two, *, *, *")
7825
7826 (set_attr "length"
7827 "8, 8, 8, 8, 12, 16")])
7828
7829 ; ld/std require word-aligned displacements -> 'Y' constraint.
7830 ; List Y->r and r->Y before r->r for reload.
7831
7832 ;; STFD LFD FMR LXSD STXSD
7833 ;; LXSDX STXSDX XXLOR XXLXOR LI 0
7834 ;; STD LD MR MT{CTR,LR} MF{CTR,LR}
7835 ;; NOP MFVSRD MTVSRD
7836
7837 (define_insn "*mov<mode>_hardfloat64"
7838 [(set (match_operand:FMOVE64 0 "nonimmediate_operand"
7839 "=m, d, d, <f64_p9>, wY,
7840 <f64_av>, Z, <f64_vsx>, <f64_vsx>, !r,
7841 YZ, r, !r, *c*l, !r,
7842 *h, r, <f64_dm>")
7843 (match_operand:FMOVE64 1 "input_operand"
7844 "d, m, d, wY, <f64_p9>,
7845 Z, <f64_av>, <f64_vsx>, <zero_fp>, <zero_fp>,
7846 r, YZ, r, r, *h,
7847 0, <f64_dm>, r"))]
7848 "TARGET_POWERPC64 && TARGET_HARD_FLOAT
7849 && (gpc_reg_operand (operands[0], <MODE>mode)
7850 || gpc_reg_operand (operands[1], <MODE>mode))"
7851 "@
7852 stfd%U0%X0 %1,%0
7853 lfd%U1%X1 %0,%1
7854 fmr %0,%1
7855 lxsd %0,%1
7856 stxsd %1,%0
7857 lxsdx %x0,%y1
7858 stxsdx %x1,%y0
7859 xxlor %x0,%x1,%x1
7860 xxlxor %x0,%x0,%x0
7861 li %0,0
7862 std%U0%X0 %1,%0
7863 ld%U1%X1 %0,%1
7864 mr %0,%1
7865 mt%0 %1
7866 mf%1 %0
7867 nop
7868 mfvsrd %0,%x1
7869 mtvsrd %x0,%1"
7870 [(set_attr "type"
7871 "fpstore, fpload, fpsimple, fpload, fpstore,
7872 fpload, fpstore, veclogical, veclogical, integer,
7873 store, load, *, mtjmpr, mfjmpr,
7874 *, mfvsr, mtvsr")
7875 (set_attr "size" "64")
7876 (set_attr "isa"
7877 "*, *, *, p9v, p9v,
7878 p7v, p7v, *, *, *,
7879 *, *, *, *, *,
7880 *, p8v, p8v")])
7881
7882 ;; STD LD MR MT<SPR> MF<SPR> G-const
7883 ;; H-const F-const Special
7884
7885 (define_insn "*mov<mode>_softfloat64"
7886 [(set (match_operand:FMOVE64 0 "nonimmediate_operand"
7887 "=Y, r, r, *c*l, r, r,
7888 r, r, *h")
7889
7890 (match_operand:FMOVE64 1 "input_operand"
7891 "r, Y, r, r, *h, G,
7892 H, F, 0"))]
7893
7894 "TARGET_POWERPC64 && TARGET_SOFT_FLOAT
7895 && (gpc_reg_operand (operands[0], <MODE>mode)
7896 || gpc_reg_operand (operands[1], <MODE>mode))"
7897 "@
7898 std%U0%X0 %1,%0
7899 ld%U1%X1 %0,%1
7900 mr %0,%1
7901 mt%0 %1
7902 mf%1 %0
7903 #
7904 #
7905 #
7906 nop"
7907 [(set_attr "type"
7908 "store, load, *, mtjmpr, mfjmpr, *,
7909 *, *, *")
7910
7911 (set_attr "length"
7912 "*, *, *, *, *, 8,
7913 12, 16, *")])
7914 \f
7915 (define_expand "mov<mode>"
7916 [(set (match_operand:FMOVE128 0 "general_operand")
7917 (match_operand:FMOVE128 1 "any_operand"))]
7918 ""
7919 {
7920 rs6000_emit_move (operands[0], operands[1], <MODE>mode);
7921 DONE;
7922 })
7923
7924 ;; It's important to list Y->r and r->Y before r->r because otherwise
7925 ;; reload, given m->r, will try to pick r->r and reload it, which
7926 ;; doesn't make progress.
7927
7928 ;; We can't split little endian direct moves of TDmode, because the words are
7929 ;; not swapped like they are for TImode or TFmode. Subregs therefore are
7930 ;; problematical. Don't allow direct move for this case.
7931
7932 ;; FPR load FPR store FPR move FPR zero GPR load
7933 ;; GPR zero GPR store GPR move MFVSRD MTVSRD
7934
7935 (define_insn_and_split "*mov<mode>_64bit_dm"
7936 [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand"
7937 "=m, d, d, d, Y,
7938 r, r, r, r, d")
7939
7940 (match_operand:FMOVE128_FPR 1 "input_operand"
7941 "d, m, d, <zero_fp>, r,
7942 <zero_fp>, Y, r, d, r"))]
7943
7944 "TARGET_HARD_FLOAT && TARGET_POWERPC64 && FLOAT128_2REG_P (<MODE>mode)
7945 && (<MODE>mode != TDmode || WORDS_BIG_ENDIAN)
7946 && (gpc_reg_operand (operands[0], <MODE>mode)
7947 || gpc_reg_operand (operands[1], <MODE>mode))"
7948 "#"
7949 "&& reload_completed"
7950 [(pc)]
7951 {
7952 rs6000_split_multireg_move (operands[0], operands[1]);
7953 DONE;
7954 }
7955 [(set_attr "length" "8")
7956 (set_attr "isa" "*,*,*,*,*,*,*,*,p8v,p8v")
7957 (set_attr "max_prefixed_insns" "2")
7958 (set_attr "num_insns" "2")])
7959
7960 (define_insn_and_split "*movtd_64bit_nodm"
7961 [(set (match_operand:TD 0 "nonimmediate_operand" "=m,d,d,Y,r,r")
7962 (match_operand:TD 1 "input_operand" "d,m,d,r,Y,r"))]
7963 "TARGET_HARD_FLOAT && TARGET_POWERPC64 && !WORDS_BIG_ENDIAN
7964 && (gpc_reg_operand (operands[0], TDmode)
7965 || gpc_reg_operand (operands[1], TDmode))"
7966 "#"
7967 "&& reload_completed"
7968 [(pc)]
7969 {
7970 rs6000_split_multireg_move (operands[0], operands[1]);
7971 DONE;
7972 }
7973 [(set_attr "length" "8,8,8,12,12,8")
7974 (set_attr "max_prefixed_insns" "2")
7975 (set_attr "num_insns" "2,2,2,3,3,2")])
7976
7977 (define_insn_and_split "*mov<mode>_32bit"
7978 [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand" "=m,d,d,d,Y,r,r")
7979 (match_operand:FMOVE128_FPR 1 "input_operand" "d,m,d,<zero_fp>,r,<zero_fp>Y,r"))]
7980 "TARGET_HARD_FLOAT && !TARGET_POWERPC64
7981 && (FLOAT128_2REG_P (<MODE>mode)
7982 || int_reg_operand_not_pseudo (operands[0], <MODE>mode)
7983 || int_reg_operand_not_pseudo (operands[1], <MODE>mode))
7984 && (gpc_reg_operand (operands[0], <MODE>mode)
7985 || gpc_reg_operand (operands[1], <MODE>mode))"
7986 "#"
7987 "&& reload_completed"
7988 [(pc)]
7989 {
7990 rs6000_split_multireg_move (operands[0], operands[1]);
7991 DONE;
7992 }
7993 [(set_attr "length" "8,8,8,8,20,20,16")])
7994
7995 (define_insn_and_split "*mov<mode>_softfloat"
7996 [(set (match_operand:FMOVE128 0 "nonimmediate_operand" "=Y,r,r,r")
7997 (match_operand:FMOVE128 1 "input_operand" "r,Y,F,r"))]
7998 "TARGET_SOFT_FLOAT
7999 && (gpc_reg_operand (operands[0], <MODE>mode)
8000 || gpc_reg_operand (operands[1], <MODE>mode))"
8001 "#"
8002 "&& reload_completed"
8003 [(pc)]
8004 {
8005 rs6000_split_multireg_move (operands[0], operands[1]);
8006 DONE;
8007 }
8008 [(set_attr_alternative "length"
8009 [(if_then_else (match_test "TARGET_POWERPC64")
8010 (const_string "8")
8011 (const_string "16"))
8012 (if_then_else (match_test "TARGET_POWERPC64")
8013 (const_string "8")
8014 (const_string "16"))
8015 (if_then_else (match_test "TARGET_POWERPC64")
8016 (const_string "16")
8017 (const_string "32"))
8018 (if_then_else (match_test "TARGET_POWERPC64")
8019 (const_string "8")
8020 (const_string "16"))])])
8021
8022 (define_expand "@extenddf<mode>2"
8023 [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
8024 (float_extend:FLOAT128 (match_operand:DF 1 "gpc_reg_operand")))]
8025 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8026 {
8027 if (FLOAT128_IEEE_P (<MODE>mode))
8028 rs6000_expand_float128_convert (operands[0], operands[1], false);
8029 else if (TARGET_VSX)
8030 emit_insn (gen_extenddf2_vsx (<MODE>mode, operands[0], operands[1]));
8031 else
8032 {
8033 rtx zero = gen_reg_rtx (DFmode);
8034 rs6000_emit_move (zero, CONST0_RTX (DFmode), DFmode);
8035
8036 emit_insn (gen_extenddf2_fprs (<MODE>mode,
8037 operands[0], operands[1], zero));
8038 }
8039 DONE;
8040 })
8041
8042 ;; Allow memory operands for the source to be created by the combiner.
8043 (define_insn_and_split "@extenddf<mode>2_fprs"
8044 [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d,&d")
8045 (float_extend:IBM128
8046 (match_operand:DF 1 "nonimmediate_operand" "d,m,d")))
8047 (use (match_operand:DF 2 "nonimmediate_operand" "m,m,d"))]
8048 "!TARGET_VSX && TARGET_HARD_FLOAT
8049 && TARGET_LONG_DOUBLE_128 && FLOAT128_IBM_P (<MODE>mode)"
8050 "#"
8051 "&& reload_completed"
8052 [(set (match_dup 3) (match_dup 1))
8053 (set (match_dup 4) (match_dup 2))]
8054 {
8055 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
8056 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
8057
8058 operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
8059 operands[4] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
8060 })
8061
8062 (define_insn_and_split "@extenddf<mode>2_vsx"
8063 [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d")
8064 (float_extend:IBM128
8065 (match_operand:DF 1 "nonimmediate_operand" "wa,m")))]
8066 "TARGET_LONG_DOUBLE_128 && TARGET_VSX && FLOAT128_IBM_P (<MODE>mode)"
8067 "#"
8068 "&& reload_completed"
8069 [(set (match_dup 2) (match_dup 1))
8070 (set (match_dup 3) (match_dup 4))]
8071 {
8072 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
8073 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
8074
8075 operands[2] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
8076 operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
8077 operands[4] = CONST0_RTX (DFmode);
8078 })
8079
8080 (define_expand "extendsf<mode>2"
8081 [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
8082 (float_extend:FLOAT128 (match_operand:SF 1 "gpc_reg_operand")))]
8083 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8084 {
8085 if (FLOAT128_IEEE_P (<MODE>mode))
8086 rs6000_expand_float128_convert (operands[0], operands[1], false);
8087 else
8088 {
8089 rtx tmp = gen_reg_rtx (DFmode);
8090 emit_insn (gen_extendsfdf2 (tmp, operands[1]));
8091 emit_insn (gen_extenddf<mode>2 (operands[0], tmp));
8092 }
8093 DONE;
8094 })
8095
8096 (define_expand "trunc<mode>df2"
8097 [(set (match_operand:DF 0 "gpc_reg_operand")
8098 (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand")))]
8099 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8100 {
8101 if (FLOAT128_IEEE_P (<MODE>mode))
8102 {
8103 rs6000_expand_float128_convert (operands[0], operands[1], false);
8104 DONE;
8105 }
8106 })
8107
8108 (define_insn_and_split "trunc<mode>df2_internal1"
8109 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d")
8110 (float_truncate:DF
8111 (match_operand:IBM128 1 "gpc_reg_operand" "0,d")))]
8112 "FLOAT128_IBM_P (<MODE>mode) && !TARGET_XL_COMPAT
8113 && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8114 "@
8115 #
8116 fmr %0,%1"
8117 "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
8118 [(const_int 0)]
8119 {
8120 emit_note (NOTE_INSN_DELETED);
8121 DONE;
8122 }
8123 [(set_attr "type" "fpsimple")])
8124
8125 (define_insn "trunc<mode>df2_internal2"
8126 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
8127 (float_truncate:DF (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
8128 "FLOAT128_IBM_P (<MODE>mode) && TARGET_XL_COMPAT && TARGET_HARD_FLOAT
8129 && TARGET_LONG_DOUBLE_128"
8130 "fadd %0,%1,%L1"
8131 [(set_attr "type" "fp")])
8132
8133 (define_expand "trunc<mode>sf2"
8134 [(set (match_operand:SF 0 "gpc_reg_operand")
8135 (float_truncate:SF (match_operand:FLOAT128 1 "gpc_reg_operand")))]
8136 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8137 {
8138 if (FLOAT128_IEEE_P (<MODE>mode))
8139 rs6000_expand_float128_convert (operands[0], operands[1], false);
8140 else
8141 {
8142 rtx tmp = gen_reg_rtx (DFmode);
8143 emit_insn (gen_trunc<mode>df2 (tmp, operands[1]));
8144 emit_insn (gen_truncdfsf2 (operands[0], tmp));
8145 }
8146 DONE;
8147 })
8148
8149 (define_expand "floatsi<mode>2"
8150 [(parallel [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
8151 (float:FLOAT128 (match_operand:SI 1 "gpc_reg_operand")))
8152 (clobber (match_scratch:DI 2))])]
8153 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8154 {
8155 rtx op0 = operands[0];
8156 rtx op1 = operands[1];
8157
8158 if (TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode))
8159 ;
8160 else if (FLOAT128_IEEE_P (<MODE>mode))
8161 {
8162 rs6000_expand_float128_convert (op0, op1, false);
8163 DONE;
8164 }
8165 else
8166 {
8167 rtx tmp = gen_reg_rtx (DFmode);
8168 expand_float (tmp, op1, false);
8169 emit_insn (gen_extenddf2 (<MODE>mode, op0, tmp));
8170 DONE;
8171 }
8172 })
8173
8174 ; fadd, but rounding towards zero.
8175 ; This is probably not the optimal code sequence.
8176 (define_insn "fix_trunc_helper<mode>"
8177 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
8178 (unspec:DF [(match_operand:IBM128 1 "gpc_reg_operand" "d")]
8179 UNSPEC_FIX_TRUNC_TF))
8180 (clobber (match_operand:DF 2 "gpc_reg_operand" "=&d"))]
8181 "TARGET_HARD_FLOAT && FLOAT128_IBM_P (<MODE>mode)"
8182 "mffs %2\n\tmtfsb1 31\n\tmtfsb0 30\n\tfadd %0,%1,%L1\n\tmtfsf 1,%2"
8183 [(set_attr "type" "fp")
8184 (set_attr "length" "20")])
8185
8186 (define_expand "fix_trunc<mode>si2"
8187 [(set (match_operand:SI 0 "gpc_reg_operand")
8188 (fix:SI (match_operand:FLOAT128 1 "gpc_reg_operand")))]
8189 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8190 {
8191 rtx op0 = operands[0];
8192 rtx op1 = operands[1];
8193
8194 if (TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode))
8195 ;
8196 else
8197 {
8198 if (FLOAT128_IEEE_P (<MODE>mode))
8199 rs6000_expand_float128_convert (op0, op1, false);
8200 else
8201 emit_insn (gen_fix_truncsi2_fprs (<MODE>mode, op0, op1));
8202 DONE;
8203 }
8204 })
8205
8206 (define_expand "@fix_trunc<mode>si2_fprs"
8207 [(parallel [(set (match_operand:SI 0 "gpc_reg_operand")
8208 (fix:SI (match_operand:IBM128 1 "gpc_reg_operand")))
8209 (clobber (match_dup 2))
8210 (clobber (match_dup 3))
8211 (clobber (match_dup 4))
8212 (clobber (match_dup 5))])]
8213 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8214 {
8215 operands[2] = gen_reg_rtx (DFmode);
8216 operands[3] = gen_reg_rtx (DFmode);
8217 operands[4] = gen_reg_rtx (DImode);
8218 operands[5] = assign_stack_temp (DImode, GET_MODE_SIZE (DImode));
8219 })
8220
8221 (define_insn_and_split "*fix_trunc<mode>si2_internal"
8222 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
8223 (fix:SI (match_operand:IBM128 1 "gpc_reg_operand" "d")))
8224 (clobber (match_operand:DF 2 "gpc_reg_operand" "=d"))
8225 (clobber (match_operand:DF 3 "gpc_reg_operand" "=&d"))
8226 (clobber (match_operand:DI 4 "gpc_reg_operand" "=d"))
8227 (clobber (match_operand:DI 5 "offsettable_mem_operand" "=o"))]
8228 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8229 "#"
8230 ""
8231 [(pc)]
8232 {
8233 rtx lowword;
8234 emit_insn (gen_fix_trunc_helper<mode> (operands[2], operands[1],
8235 operands[3]));
8236
8237 gcc_assert (MEM_P (operands[5]));
8238 lowword = adjust_address (operands[5], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
8239
8240 emit_insn (gen_fctiwz_df (operands[4], operands[2]));
8241 emit_move_insn (operands[5], operands[4]);
8242 emit_move_insn (operands[0], lowword);
8243 DONE;
8244 })
8245
8246 (define_expand "fix_trunc<mode>di2"
8247 [(set (match_operand:DI 0 "gpc_reg_operand")
8248 (fix:DI (match_operand:IEEE128 1 "gpc_reg_operand")))]
8249 "TARGET_FLOAT128_TYPE"
8250 {
8251 if (!TARGET_FLOAT128_HW)
8252 {
8253 rs6000_expand_float128_convert (operands[0], operands[1], false);
8254 DONE;
8255 }
8256 })
8257
8258 (define_expand "fixuns_trunc<IEEE128:mode><SDI:mode>2"
8259 [(set (match_operand:SDI 0 "gpc_reg_operand")
8260 (unsigned_fix:SDI (match_operand:IEEE128 1 "gpc_reg_operand")))]
8261 "TARGET_FLOAT128_TYPE"
8262 {
8263 rs6000_expand_float128_convert (operands[0], operands[1], true);
8264 DONE;
8265 })
8266
8267 (define_expand "floatdi<mode>2"
8268 [(set (match_operand:IEEE128 0 "gpc_reg_operand")
8269 (float:IEEE128 (match_operand:DI 1 "gpc_reg_operand")))]
8270 "TARGET_FLOAT128_TYPE"
8271 {
8272 if (!TARGET_FLOAT128_HW)
8273 {
8274 rs6000_expand_float128_convert (operands[0], operands[1], false);
8275 DONE;
8276 }
8277 })
8278
8279 (define_expand "floatunsdi<IEEE128:mode>2"
8280 [(set (match_operand:IEEE128 0 "gpc_reg_operand")
8281 (unsigned_float:IEEE128 (match_operand:DI 1 "gpc_reg_operand")))]
8282 "TARGET_FLOAT128_TYPE"
8283 {
8284 if (!TARGET_FLOAT128_HW)
8285 {
8286 rs6000_expand_float128_convert (operands[0], operands[1], true);
8287 DONE;
8288 }
8289 })
8290
8291 (define_expand "floatuns<IEEE128:mode>2"
8292 [(set (match_operand:IEEE128 0 "gpc_reg_operand")
8293 (unsigned_float:IEEE128 (match_operand:SI 1 "gpc_reg_operand")))]
8294 "TARGET_FLOAT128_TYPE"
8295 {
8296 rtx op0 = operands[0];
8297 rtx op1 = operands[1];
8298
8299 if (TARGET_FLOAT128_HW)
8300 emit_insn (gen_floatuns_<IEEE128:mode>si2_hw (op0, op1));
8301 else
8302 rs6000_expand_float128_convert (op0, op1, true);
8303 DONE;
8304 })
8305
8306 (define_expand "neg<mode>2"
8307 [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
8308 (neg:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand")))]
8309 "FLOAT128_IEEE_P (<MODE>mode)
8310 || (FLOAT128_IBM_P (<MODE>mode) && TARGET_HARD_FLOAT)"
8311 {
8312 if (FLOAT128_IEEE_P (<MODE>mode))
8313 {
8314 if (TARGET_FLOAT128_HW)
8315 emit_insn (gen_neg2_hw (<MODE>mode, operands[0], operands[1]));
8316 else if (TARGET_FLOAT128_TYPE)
8317 emit_insn (gen_ieee_128bit_vsx_neg2 (<MODE>mode,
8318 operands[0], operands[1]));
8319 else
8320 {
8321 rtx libfunc = optab_libfunc (neg_optab, <MODE>mode);
8322 rtx target = emit_library_call_value (libfunc, operands[0], LCT_CONST,
8323 <MODE>mode,
8324 operands[1], <MODE>mode);
8325
8326 if (target && !rtx_equal_p (target, operands[0]))
8327 emit_move_insn (operands[0], target);
8328 }
8329 DONE;
8330 }
8331 })
8332
8333 (define_insn "neg<mode>2_internal"
8334 [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d")
8335 (neg:IBM128 (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
8336 "TARGET_HARD_FLOAT && FLOAT128_IBM_P (<MODE>mode)"
8337 {
8338 if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
8339 return "fneg %L0,%L1\;fneg %0,%1";
8340 else
8341 return "fneg %0,%1\;fneg %L0,%L1";
8342 }
8343 [(set_attr "type" "fpsimple")
8344 (set_attr "length" "8")])
8345
8346 (define_expand "abs<mode>2"
8347 [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
8348 (abs:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand")))]
8349 "FLOAT128_IEEE_P (<MODE>mode)
8350 || (FLOAT128_IBM_P (<MODE>mode) && TARGET_HARD_FLOAT)"
8351 {
8352 rtx label;
8353
8354 if (FLOAT128_IEEE_P (<MODE>mode))
8355 {
8356 if (TARGET_FLOAT128_HW)
8357 {
8358 emit_insn (gen_abs2_hw (<MODE>mode, operands[0], operands[1]));
8359 DONE;
8360 }
8361 else if (TARGET_FLOAT128_TYPE)
8362 {
8363 emit_insn (gen_ieee_128bit_vsx_abs2 (<MODE>mode,
8364 operands[0], operands[1]));
8365 DONE;
8366 }
8367 else
8368 FAIL;
8369 }
8370
8371 label = gen_label_rtx ();
8372 emit_insn (gen_abs2_internal (<MODE>mode, operands[0], operands[1], label));
8373 emit_label (label);
8374 DONE;
8375 })
8376
8377 (define_expand "@abs<mode>2_internal"
8378 [(set (match_operand:IBM128 0 "gpc_reg_operand")
8379 (match_operand:IBM128 1 "gpc_reg_operand"))
8380 (set (match_dup 3) (match_dup 5))
8381 (set (match_dup 5) (abs:DF (match_dup 5)))
8382 (set (match_dup 4) (compare:CCFP (match_dup 3) (match_dup 5)))
8383 (set (pc) (if_then_else (eq (match_dup 4) (const_int 0))
8384 (label_ref (match_operand 2 ""))
8385 (pc)))
8386 (set (match_dup 6) (neg:DF (match_dup 6)))]
8387 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8388 {
8389 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
8390 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
8391 operands[3] = gen_reg_rtx (DFmode);
8392 operands[4] = gen_reg_rtx (CCFPmode);
8393 operands[5] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
8394 operands[6] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
8395 })
8396
8397 \f
8398 ;; Generate IEEE 128-bit -0.0 (0x80000000000000000000000000000000) in a vector
8399 ;; register
8400
8401 (define_expand "ieee_128bit_negative_zero"
8402 [(set (match_operand:V16QI 0 "register_operand") (match_dup 1))]
8403 "TARGET_FLOAT128_TYPE"
8404 {
8405 rtvec v = rtvec_alloc (16);
8406 int i, high;
8407
8408 for (i = 0; i < 16; i++)
8409 RTVEC_ELT (v, i) = const0_rtx;
8410
8411 high = (BYTES_BIG_ENDIAN) ? 0 : 15;
8412 RTVEC_ELT (v, high) = gen_int_mode (0x80, QImode);
8413
8414 rs6000_expand_vector_init (operands[0], gen_rtx_PARALLEL (V16QImode, v));
8415 DONE;
8416 })
8417
8418 ;; IEEE 128-bit negate
8419
8420 ;; We have 2 insns here for negate and absolute value. The first uses
8421 ;; match_scratch so that phases like combine can recognize neg/abs as generic
8422 ;; insns, and second insn after the first split pass loads up the bit to
8423 ;; twiddle the sign bit. Later GCSE passes can then combine multiple uses of
8424 ;; neg/abs to create the constant just once.
8425
8426 (define_insn_and_split "@ieee_128bit_vsx_neg<mode>2"
8427 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8428 (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8429 (clobber (match_scratch:V16QI 2 "=v"))]
8430 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8431 "#"
8432 "&& 1"
8433 [(parallel [(set (match_dup 0)
8434 (neg:IEEE128 (match_dup 1)))
8435 (use (match_dup 2))])]
8436 {
8437 if (GET_CODE (operands[2]) == SCRATCH)
8438 operands[2] = gen_reg_rtx (V16QImode);
8439
8440 operands[3] = gen_reg_rtx (V16QImode);
8441 emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8442 }
8443 [(set_attr "length" "8")
8444 (set_attr "type" "vecsimple")])
8445
8446 (define_insn "*ieee_128bit_vsx_neg<mode>2_internal"
8447 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8448 (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8449 (use (match_operand:V16QI 2 "register_operand" "v"))]
8450 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8451 "xxlxor %x0,%x1,%x2"
8452 [(set_attr "type" "veclogical")])
8453
8454 ;; IEEE 128-bit absolute value
8455 (define_insn_and_split "@ieee_128bit_vsx_abs<mode>2"
8456 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8457 (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8458 (clobber (match_scratch:V16QI 2 "=v"))]
8459 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
8460 "#"
8461 "&& 1"
8462 [(parallel [(set (match_dup 0)
8463 (abs:IEEE128 (match_dup 1)))
8464 (use (match_dup 2))])]
8465 {
8466 if (GET_CODE (operands[2]) == SCRATCH)
8467 operands[2] = gen_reg_rtx (V16QImode);
8468
8469 operands[3] = gen_reg_rtx (V16QImode);
8470 emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8471 }
8472 [(set_attr "length" "8")
8473 (set_attr "type" "vecsimple")])
8474
8475 (define_insn "*ieee_128bit_vsx_abs<mode>2_internal"
8476 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8477 (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8478 (use (match_operand:V16QI 2 "register_operand" "v"))]
8479 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8480 "xxlandc %x0,%x1,%x2"
8481 [(set_attr "type" "veclogical")])
8482
8483 ;; IEEE 128-bit negative absolute value
8484 (define_insn_and_split "*ieee_128bit_vsx_nabs<mode>2"
8485 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8486 (neg:IEEE128
8487 (abs:IEEE128
8488 (match_operand:IEEE128 1 "register_operand" "wa"))))
8489 (clobber (match_scratch:V16QI 2 "=v"))]
8490 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW
8491 && FLOAT128_IEEE_P (<MODE>mode)"
8492 "#"
8493 "&& 1"
8494 [(parallel [(set (match_dup 0)
8495 (neg:IEEE128 (abs:IEEE128 (match_dup 1))))
8496 (use (match_dup 2))])]
8497 {
8498 if (GET_CODE (operands[2]) == SCRATCH)
8499 operands[2] = gen_reg_rtx (V16QImode);
8500
8501 operands[3] = gen_reg_rtx (V16QImode);
8502 emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8503 }
8504 [(set_attr "length" "8")
8505 (set_attr "type" "vecsimple")])
8506
8507 (define_insn "*ieee_128bit_vsx_nabs<mode>2_internal"
8508 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8509 (neg:IEEE128
8510 (abs:IEEE128
8511 (match_operand:IEEE128 1 "register_operand" "wa"))))
8512 (use (match_operand:V16QI 2 "register_operand" "v"))]
8513 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8514 "xxlor %x0,%x1,%x2"
8515 [(set_attr "type" "veclogical")])
8516
8517 ;; Float128 conversion functions. These expand to library function calls.
8518 ;; We use expand to convert from IBM double double to IEEE 128-bit
8519 ;; and trunc for the opposite.
8520 (define_expand "extendiftf2"
8521 [(set (match_operand:TF 0 "gpc_reg_operand")
8522 (float_extend:TF (match_operand:IF 1 "gpc_reg_operand")))]
8523 "TARGET_FLOAT128_TYPE"
8524 {
8525 rs6000_expand_float128_convert (operands[0], operands[1], false);
8526 DONE;
8527 })
8528
8529 (define_expand "extendifkf2"
8530 [(set (match_operand:KF 0 "gpc_reg_operand")
8531 (float_extend:KF (match_operand:IF 1 "gpc_reg_operand")))]
8532 "TARGET_FLOAT128_TYPE"
8533 {
8534 rs6000_expand_float128_convert (operands[0], operands[1], false);
8535 DONE;
8536 })
8537
8538 (define_expand "extendtfkf2"
8539 [(set (match_operand:KF 0 "gpc_reg_operand")
8540 (float_extend:KF (match_operand:TF 1 "gpc_reg_operand")))]
8541 "TARGET_FLOAT128_TYPE"
8542 {
8543 rs6000_expand_float128_convert (operands[0], operands[1], false);
8544 DONE;
8545 })
8546
8547 (define_expand "extendtfif2"
8548 [(set (match_operand:IF 0 "gpc_reg_operand")
8549 (float_extend:IF (match_operand:TF 1 "gpc_reg_operand")))]
8550 "TARGET_FLOAT128_TYPE"
8551 {
8552 rs6000_expand_float128_convert (operands[0], operands[1], false);
8553 DONE;
8554 })
8555
8556 (define_expand "trunciftf2"
8557 [(set (match_operand:TF 0 "gpc_reg_operand")
8558 (float_truncate:TF (match_operand:IF 1 "gpc_reg_operand")))]
8559 "TARGET_FLOAT128_TYPE"
8560 {
8561 rs6000_expand_float128_convert (operands[0], operands[1], false);
8562 DONE;
8563 })
8564
8565 (define_expand "truncifkf2"
8566 [(set (match_operand:KF 0 "gpc_reg_operand")
8567 (float_truncate:KF (match_operand:IF 1 "gpc_reg_operand")))]
8568 "TARGET_FLOAT128_TYPE"
8569 {
8570 rs6000_expand_float128_convert (operands[0], operands[1], false);
8571 DONE;
8572 })
8573
8574 (define_expand "trunckftf2"
8575 [(set (match_operand:TF 0 "gpc_reg_operand")
8576 (float_truncate:TF (match_operand:KF 1 "gpc_reg_operand")))]
8577 "TARGET_FLOAT128_TYPE"
8578 {
8579 rs6000_expand_float128_convert (operands[0], operands[1], false);
8580 DONE;
8581 })
8582
8583 (define_expand "trunctfif2"
8584 [(set (match_operand:IF 0 "gpc_reg_operand")
8585 (float_truncate:IF (match_operand:TF 1 "gpc_reg_operand")))]
8586 "TARGET_FLOAT128_TYPE"
8587 {
8588 rs6000_expand_float128_convert (operands[0], operands[1], false);
8589 DONE;
8590 })
8591
8592 (define_insn_and_split "*extend<mode>tf2_internal"
8593 [(set (match_operand:TF 0 "gpc_reg_operand" "=<IFKF_reg>")
8594 (float_extend:TF
8595 (match_operand:IFKF 1 "gpc_reg_operand" "<IFKF_reg>")))]
8596 "TARGET_FLOAT128_TYPE
8597 && FLOAT128_IBM_P (TFmode) == FLOAT128_IBM_P (<MODE>mode)"
8598 "#"
8599 "&& reload_completed"
8600 [(set (match_dup 0) (match_dup 2))]
8601 {
8602 operands[2] = gen_rtx_REG (TFmode, REGNO (operands[1]));
8603 })
8604
8605 (define_insn_and_split "*extendtf<mode>2_internal"
8606 [(set (match_operand:IFKF 0 "gpc_reg_operand" "=<IFKF_reg>")
8607 (float_extend:IFKF
8608 (match_operand:TF 1 "gpc_reg_operand" "<IFKF_reg>")))]
8609 "TARGET_FLOAT128_TYPE
8610 && FLOAT128_IBM_P (TFmode) == FLOAT128_IBM_P (<MODE>mode)"
8611 "#"
8612 "&& reload_completed"
8613 [(set (match_dup 0) (match_dup 2))]
8614 {
8615 operands[2] = gen_rtx_REG (<MODE>mode, REGNO (operands[1]));
8616 })
8617
8618 \f
8619 ;; Reload helper functions used by rs6000_secondary_reload. The patterns all
8620 ;; must have 3 arguments, and scratch register constraint must be a single
8621 ;; constraint.
8622
8623 ;; Reload patterns to support gpr load/store with misaligned mem.
8624 ;; and multiple gpr load/store at offset >= 0xfffc
8625 (define_expand "reload_<mode>_store"
8626 [(parallel [(match_operand 0 "memory_operand" "=m")
8627 (match_operand 1 "gpc_reg_operand" "r")
8628 (match_operand:GPR 2 "register_operand" "=&b")])]
8629 ""
8630 {
8631 rs6000_secondary_reload_gpr (operands[1], operands[0], operands[2], true);
8632 DONE;
8633 })
8634
8635 (define_expand "reload_<mode>_load"
8636 [(parallel [(match_operand 0 "gpc_reg_operand" "=r")
8637 (match_operand 1 "memory_operand" "m")
8638 (match_operand:GPR 2 "register_operand" "=b")])]
8639 ""
8640 {
8641 rs6000_secondary_reload_gpr (operands[0], operands[1], operands[2], false);
8642 DONE;
8643 })
8644
8645 \f
8646 ;; Reload patterns for various types using the vector registers. We may need
8647 ;; an additional base register to convert the reg+offset addressing to reg+reg
8648 ;; for vector registers and reg+reg or (reg+reg)&(-16) addressing to just an
8649 ;; index register for gpr registers.
8650 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_store"
8651 [(parallel [(match_operand:RELOAD 0 "memory_operand" "m")
8652 (match_operand:RELOAD 1 "gpc_reg_operand" "wa")
8653 (match_operand:P 2 "register_operand" "=b")])]
8654 "<P:tptrsize>"
8655 {
8656 rs6000_secondary_reload_inner (operands[1], operands[0], operands[2], true);
8657 DONE;
8658 })
8659
8660 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_load"
8661 [(parallel [(match_operand:RELOAD 0 "gpc_reg_operand" "wa")
8662 (match_operand:RELOAD 1 "memory_operand" "m")
8663 (match_operand:P 2 "register_operand" "=b")])]
8664 "<P:tptrsize>"
8665 {
8666 rs6000_secondary_reload_inner (operands[0], operands[1], operands[2], false);
8667 DONE;
8668 })
8669
8670
8671 ;; Reload sometimes tries to move the address to a GPR, and can generate
8672 ;; invalid RTL for addresses involving AND -16. Allow addresses involving
8673 ;; reg+reg, reg+small constant, or just reg, all wrapped in an AND -16.
8674
8675 (define_insn_and_split "*vec_reload_and_plus_<mptrsize>"
8676 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
8677 (and:P (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
8678 (match_operand:P 2 "reg_or_cint_operand" "rI"))
8679 (const_int -16)))]
8680 "TARGET_ALTIVEC && reload_completed"
8681 "#"
8682 "&& reload_completed"
8683 [(set (match_dup 0)
8684 (plus:P (match_dup 1)
8685 (match_dup 2)))
8686 (set (match_dup 0)
8687 (and:P (match_dup 0)
8688 (const_int -16)))])
8689 \f
8690 ;; Power8 merge instructions to allow direct move to/from floating point
8691 ;; registers in 32-bit mode. We use TF mode to get two registers to move the
8692 ;; individual 32-bit parts across. Subreg doesn't work too well on the TF
8693 ;; value, since it is allocated in reload and not all of the flow information
8694 ;; is setup for it. We have two patterns to do the two moves between gprs and
8695 ;; fprs. There isn't a dependancy between the two, but we could potentially
8696 ;; schedule other instructions between the two instructions.
8697
8698 (define_insn "p8_fmrgow_<mode>"
8699 [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
8700 (unspec:FMOVE64X [
8701 (match_operand:DF 1 "register_operand" "d")
8702 (match_operand:DF 2 "register_operand" "d")]
8703 UNSPEC_P8V_FMRGOW))]
8704 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8705 "fmrgow %0,%1,%2"
8706 [(set_attr "type" "fpsimple")])
8707
8708 (define_insn "p8_mtvsrwz"
8709 [(set (match_operand:DF 0 "register_operand" "=d")
8710 (unspec:DF [(match_operand:SI 1 "register_operand" "r")]
8711 UNSPEC_P8V_MTVSRWZ))]
8712 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8713 "mtvsrwz %x0,%1"
8714 [(set_attr "type" "mtvsr")])
8715
8716 (define_insn "p8_mtvsrwz_v16qisi2"
8717 [(set (match_operand:V16QI 0 "register_operand" "=wa")
8718 (unspec:V16QI [(match_operand:SI 1 "register_operand" "r")]
8719 UNSPEC_P8V_MTVSRWZ))]
8720 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8721 "mtvsrwz %x0,%1"
8722 [(set_attr "type" "mtvsr")])
8723
8724 (define_insn "p8_mtvsrd_v16qidi2"
8725 [(set (match_operand:V16QI 0 "register_operand" "=wa")
8726 (unspec:V16QI [(match_operand:DI 1 "register_operand" "r")]
8727 UNSPEC_P8V_MTVSRD))]
8728 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8729 "mtvsrd %x0,%1"
8730 [(set_attr "type" "mtvsr")])
8731
8732 (define_insn_and_split "reload_fpr_from_gpr<mode>"
8733 [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
8734 (unspec:FMOVE64X [(match_operand:FMOVE64X 1 "register_operand" "r")]
8735 UNSPEC_P8V_RELOAD_FROM_GPR))
8736 (clobber (match_operand:IF 2 "register_operand" "=d"))]
8737 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8738 "#"
8739 "&& reload_completed"
8740 [(const_int 0)]
8741 {
8742 rtx dest = operands[0];
8743 rtx src = operands[1];
8744 rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0);
8745 rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8);
8746 rtx gpr_hi_reg = gen_highpart (SImode, src);
8747 rtx gpr_lo_reg = gen_lowpart (SImode, src);
8748
8749 emit_insn (gen_p8_mtvsrwz (tmp_hi, gpr_hi_reg));
8750 emit_insn (gen_p8_mtvsrwz (tmp_lo, gpr_lo_reg));
8751 emit_insn (gen_p8_fmrgow_<mode> (dest, tmp_hi, tmp_lo));
8752 DONE;
8753 }
8754 [(set_attr "length" "12")
8755 (set_attr "type" "three")])
8756
8757 ;; Move 128 bit values from GPRs to VSX registers in 64-bit mode
8758 (define_insn "p8_mtvsrd_df"
8759 [(set (match_operand:DF 0 "register_operand" "=wa")
8760 (unspec:DF [(match_operand:DI 1 "register_operand" "r")]
8761 UNSPEC_P8V_MTVSRD))]
8762 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8763 "mtvsrd %x0,%1"
8764 [(set_attr "type" "mtvsr")])
8765
8766 (define_insn "p8_xxpermdi_<mode>"
8767 [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
8768 (unspec:FMOVE128_GPR [
8769 (match_operand:DF 1 "register_operand" "wa")
8770 (match_operand:DF 2 "register_operand" "wa")]
8771 UNSPEC_P8V_XXPERMDI))]
8772 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8773 "xxpermdi %x0,%x1,%x2,0"
8774 [(set_attr "type" "vecperm")])
8775
8776 (define_insn_and_split "reload_vsx_from_gpr<mode>"
8777 [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
8778 (unspec:FMOVE128_GPR
8779 [(match_operand:FMOVE128_GPR 1 "register_operand" "r")]
8780 UNSPEC_P8V_RELOAD_FROM_GPR))
8781 (clobber (match_operand:IF 2 "register_operand" "=wa"))]
8782 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8783 "#"
8784 "&& reload_completed"
8785 [(const_int 0)]
8786 {
8787 rtx dest = operands[0];
8788 rtx src = operands[1];
8789 /* You might think that we could use op0 as one temp and a DF clobber
8790 as op2, but you'd be wrong. Secondary reload move patterns don't
8791 check for overlap of the clobber and the destination. */
8792 rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0);
8793 rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8);
8794 rtx gpr_hi_reg = gen_highpart (DImode, src);
8795 rtx gpr_lo_reg = gen_lowpart (DImode, src);
8796
8797 emit_insn (gen_p8_mtvsrd_df (tmp_hi, gpr_hi_reg));
8798 emit_insn (gen_p8_mtvsrd_df (tmp_lo, gpr_lo_reg));
8799 emit_insn (gen_p8_xxpermdi_<mode> (dest, tmp_hi, tmp_lo));
8800 DONE;
8801 }
8802 [(set_attr "length" "12")
8803 (set_attr "type" "three")])
8804
8805 (define_split
8806 [(set (match_operand:FMOVE128_GPR 0 "nonimmediate_operand")
8807 (match_operand:FMOVE128_GPR 1 "input_operand"))]
8808 "reload_completed
8809 && (int_reg_operand (operands[0], <MODE>mode)
8810 || int_reg_operand (operands[1], <MODE>mode))
8811 && (!TARGET_DIRECT_MOVE_128
8812 || (!vsx_register_operand (operands[0], <MODE>mode)
8813 && !vsx_register_operand (operands[1], <MODE>mode)))"
8814 [(pc)]
8815 {
8816 rs6000_split_multireg_move (operands[0], operands[1]);
8817 DONE;
8818 })
8819
8820 ;; Move SFmode to a VSX from a GPR register. Because scalar floating point
8821 ;; type is stored internally as double precision in the VSX registers, we have
8822 ;; to convert it from the vector format.
8823 (define_insn "p8_mtvsrd_sf"
8824 [(set (match_operand:SF 0 "register_operand" "=wa")
8825 (unspec:SF [(match_operand:DI 1 "register_operand" "r")]
8826 UNSPEC_P8V_MTVSRD))]
8827 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8828 "mtvsrd %x0,%1"
8829 [(set_attr "type" "mtvsr")])
8830
8831 (define_insn_and_split "reload_vsx_from_gprsf"
8832 [(set (match_operand:SF 0 "register_operand" "=wa")
8833 (unspec:SF [(match_operand:SF 1 "register_operand" "r")]
8834 UNSPEC_P8V_RELOAD_FROM_GPR))
8835 (clobber (match_operand:DI 2 "register_operand" "=r"))]
8836 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8837 "#"
8838 "&& reload_completed"
8839 [(const_int 0)]
8840 {
8841 rtx op0 = operands[0];
8842 rtx op1 = operands[1];
8843 rtx op2 = operands[2];
8844 rtx op1_di = simplify_gen_subreg (DImode, op1, SFmode, 0);
8845
8846 /* Move SF value to upper 32-bits for xscvspdpn. */
8847 emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32)));
8848 emit_insn (gen_p8_mtvsrd_sf (op0, op2));
8849 emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0));
8850 DONE;
8851 }
8852 [(set_attr "length" "8")
8853 (set_attr "type" "two")])
8854
8855 ;; Move 128 bit values from VSX registers to GPRs in 64-bit mode by doing a
8856 ;; normal 64-bit move, followed by an xxpermdi to get the bottom 64-bit value,
8857 ;; and then doing a move of that.
8858 (define_insn "p8_mfvsrd_3_<mode>"
8859 [(set (match_operand:DF 0 "register_operand" "=r")
8860 (unspec:DF [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
8861 UNSPEC_P8V_RELOAD_FROM_VSX))]
8862 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8863 "mfvsrd %0,%x1"
8864 [(set_attr "type" "mfvsr")])
8865
8866 (define_insn_and_split "reload_gpr_from_vsx<mode>"
8867 [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=r")
8868 (unspec:FMOVE128_GPR
8869 [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
8870 UNSPEC_P8V_RELOAD_FROM_VSX))
8871 (clobber (match_operand:FMOVE128_GPR 2 "register_operand" "=wa"))]
8872 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8873 "#"
8874 "&& reload_completed"
8875 [(const_int 0)]
8876 {
8877 rtx dest = operands[0];
8878 rtx src = operands[1];
8879 rtx tmp = operands[2];
8880 rtx gpr_hi_reg = gen_highpart (DFmode, dest);
8881 rtx gpr_lo_reg = gen_lowpart (DFmode, dest);
8882
8883 emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_hi_reg, src));
8884 emit_insn (gen_vsx_xxpermdi_<mode>_be (tmp, src, src, GEN_INT (3)));
8885 emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_lo_reg, tmp));
8886 DONE;
8887 }
8888 [(set_attr "length" "12")
8889 (set_attr "type" "three")])
8890
8891 ;; Move SFmode to a GPR from a VSX register. Because scalar floating point
8892 ;; type is stored internally as double precision, we have to convert it to the
8893 ;; vector format.
8894
8895 (define_insn_and_split "reload_gpr_from_vsxsf"
8896 [(set (match_operand:SF 0 "register_operand" "=r")
8897 (unspec:SF [(match_operand:SF 1 "register_operand" "wa")]
8898 UNSPEC_P8V_RELOAD_FROM_VSX))
8899 (clobber (match_operand:V4SF 2 "register_operand" "=wa"))]
8900 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8901 "#"
8902 "&& reload_completed"
8903 [(const_int 0)]
8904 {
8905 rtx op0 = operands[0];
8906 rtx op1 = operands[1];
8907 rtx op2 = operands[2];
8908 rtx op0_di = gen_rtx_REG (DImode, reg_or_subregno (op0));
8909 rtx op2_si = gen_rtx_REG (SImode, reg_or_subregno (op2));
8910
8911 emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
8912 emit_insn (gen_zero_extendsidi2 (op0_di, op2_si));
8913 DONE;
8914 }
8915 [(set_attr "length" "8")
8916 (set_attr "type" "two")
8917 (set_attr "isa" "p8v")])
8918 \f
8919 ;; Next come the multi-word integer load and store and the load and store
8920 ;; multiple insns.
8921
8922 ;; List r->r after r->Y, otherwise reload will try to reload a
8923 ;; non-offsettable address by using r->r which won't make progress.
8924 ;; Use of fprs is disparaged slightly otherwise reload prefers to reload
8925 ;; a gpr into a fpr instead of reloading an invalid 'Y' address
8926
8927 ;; GPR store GPR load GPR move FPR store FPR load FPR move
8928 ;; GPR const AVX store AVX store AVX load AVX load VSX move
8929 ;; P9 0 P9 -1 AVX 0/-1 VSX 0 VSX -1 P9 const
8930 ;; AVX const
8931
8932 (define_insn "*movdi_internal32"
8933 [(set (match_operand:DI 0 "nonimmediate_operand"
8934 "=Y, r, r, m, ^d, ^d,
8935 r, wY, Z, ^v, $v, ^wa,
8936 wa, wa, v, wa, *i, v,
8937 v")
8938 (match_operand:DI 1 "input_operand"
8939 "r, Y, r, ^d, m, ^d,
8940 IJKnF, ^v, $v, wY, Z, ^wa,
8941 Oj, wM, OjwM, Oj, wM, wS,
8942 wB"))]
8943 "! TARGET_POWERPC64
8944 && (gpc_reg_operand (operands[0], DImode)
8945 || gpc_reg_operand (operands[1], DImode))"
8946 "@
8947 #
8948 #
8949 #
8950 stfd%U0%X0 %1,%0
8951 lfd%U1%X1 %0,%1
8952 fmr %0,%1
8953 #
8954 stxsd %1,%0
8955 stxsdx %x1,%y0
8956 lxsd %0,%1
8957 lxsdx %x0,%y1
8958 xxlor %x0,%x1,%x1
8959 xxspltib %x0,0
8960 xxspltib %x0,255
8961 vspltisw %0,%1
8962 xxlxor %x0,%x0,%x0
8963 xxlorc %x0,%x0,%x0
8964 #
8965 #"
8966 [(set_attr "type"
8967 "store, load, *, fpstore, fpload, fpsimple,
8968 *, fpstore, fpstore, fpload, fpload, veclogical,
8969 vecsimple, vecsimple, vecsimple, veclogical,veclogical,vecsimple,
8970 vecsimple")
8971 (set_attr "size" "64")
8972 (set_attr "length"
8973 "8, 8, 8, *, *, *,
8974 16, *, *, *, *, *,
8975 *, *, *, *, *, 8,
8976 *")
8977 (set_attr "isa"
8978 "*, *, *, *, *, *,
8979 *, p9v, p7v, p9v, p7v, *,
8980 p9v, p9v, p7v, *, *, p7v,
8981 p7v")])
8982
8983 (define_split
8984 [(set (match_operand:DI 0 "gpc_reg_operand")
8985 (match_operand:DI 1 "const_int_operand"))]
8986 "! TARGET_POWERPC64 && reload_completed
8987 && gpr_or_gpr_p (operands[0], operands[1])
8988 && !direct_move_p (operands[0], operands[1])"
8989 [(set (match_dup 2) (match_dup 4))
8990 (set (match_dup 3) (match_dup 1))]
8991 {
8992 HOST_WIDE_INT value = INTVAL (operands[1]);
8993 operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
8994 DImode);
8995 operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
8996 DImode);
8997 operands[4] = GEN_INT (value >> 32);
8998 operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
8999 })
9000
9001 (define_split
9002 [(set (match_operand:DIFD 0 "nonimmediate_operand")
9003 (match_operand:DIFD 1 "input_operand"))]
9004 "reload_completed && !TARGET_POWERPC64
9005 && gpr_or_gpr_p (operands[0], operands[1])
9006 && !direct_move_p (operands[0], operands[1])"
9007 [(pc)]
9008 {
9009 rs6000_split_multireg_move (operands[0], operands[1]);
9010 DONE;
9011 })
9012
9013 ;; GPR store GPR load GPR move
9014 ;; GPR li GPR lis GPR pli GPR #
9015 ;; FPR store FPR load FPR move
9016 ;; AVX store AVX store AVX load AVX load VSX move
9017 ;; P9 0 P9 -1 AVX 0/-1 VSX 0 VSX -1
9018 ;; P9 const AVX const
9019 ;; From SPR To SPR SPR<->SPR
9020 ;; VSX->GPR GPR->VSX
9021 (define_insn "*movdi_internal64"
9022 [(set (match_operand:DI 0 "nonimmediate_operand"
9023 "=YZ, r, r,
9024 r, r, r, r,
9025 m, ^d, ^d,
9026 wY, Z, $v, $v, ^wa,
9027 wa, wa, v, wa, wa,
9028 v, v,
9029 r, *h, *h,
9030 ?r, ?wa")
9031 (match_operand:DI 1 "input_operand"
9032 "r, YZ, r,
9033 I, L, eI, nF,
9034 ^d, m, ^d,
9035 ^v, $v, wY, Z, ^wa,
9036 Oj, wM, OjwM, Oj, wM,
9037 wS, wB,
9038 *h, r, 0,
9039 wa, r"))]
9040 "TARGET_POWERPC64
9041 && (gpc_reg_operand (operands[0], DImode)
9042 || gpc_reg_operand (operands[1], DImode))"
9043 "@
9044 std%U0%X0 %1,%0
9045 ld%U1%X1 %0,%1
9046 mr %0,%1
9047 li %0,%1
9048 lis %0,%v1
9049 li %0,%1
9050 #
9051 stfd%U0%X0 %1,%0
9052 lfd%U1%X1 %0,%1
9053 fmr %0,%1
9054 stxsd %1,%0
9055 stxsdx %x1,%y0
9056 lxsd %0,%1
9057 lxsdx %x0,%y1
9058 xxlor %x0,%x1,%x1
9059 xxspltib %x0,0
9060 xxspltib %x0,255
9061 #
9062 xxlxor %x0,%x0,%x0
9063 xxlorc %x0,%x0,%x0
9064 #
9065 #
9066 mf%1 %0
9067 mt%0 %1
9068 nop
9069 mfvsrd %0,%x1
9070 mtvsrd %x0,%1"
9071 [(set_attr "type"
9072 "store, load, *,
9073 *, *, *, *,
9074 fpstore, fpload, fpsimple,
9075 fpstore, fpstore, fpload, fpload, veclogical,
9076 vecsimple, vecsimple, vecsimple, veclogical, veclogical,
9077 vecsimple, vecsimple,
9078 mfjmpr, mtjmpr, *,
9079 mfvsr, mtvsr")
9080 (set_attr "size" "64")
9081 (set_attr "length"
9082 "*, *, *,
9083 *, *, *, 20,
9084 *, *, *,
9085 *, *, *, *, *,
9086 *, *, *, *, *,
9087 8, *,
9088 *, *, *,
9089 *, *")
9090 (set_attr "isa"
9091 "*, *, *,
9092 *, *, p10, *,
9093 *, *, *,
9094 p9v, p7v, p9v, p7v, *,
9095 p9v, p9v, p7v, *, *,
9096 p7v, p7v,
9097 *, *, *,
9098 p8v, p8v")])
9099
9100 ; Some DImode loads are best done as a load of -1 followed by a mask
9101 ; instruction.
9102 (define_split
9103 [(set (match_operand:DI 0 "int_reg_operand_not_pseudo")
9104 (match_operand:DI 1 "const_int_operand"))]
9105 "TARGET_POWERPC64
9106 && num_insns_constant (operands[1], DImode) > 1
9107 && !IN_RANGE (INTVAL (operands[1]), -0x80000000, 0xffffffff)
9108 && rs6000_is_valid_and_mask (operands[1], DImode)"
9109 [(set (match_dup 0)
9110 (const_int -1))
9111 (set (match_dup 0)
9112 (and:DI (match_dup 0)
9113 (match_dup 1)))]
9114 "")
9115
9116 ;; Split a load of a large constant into the appropriate five-instruction
9117 ;; sequence. Handle anything in a constant number of insns.
9118 ;; When non-easy constants can go in the TOC, this should use
9119 ;; easy_fp_constant predicate.
9120 (define_split
9121 [(set (match_operand:DI 0 "int_reg_operand_not_pseudo")
9122 (match_operand:DI 1 "const_int_operand"))]
9123 "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
9124 [(set (match_dup 0) (match_dup 2))
9125 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
9126 {
9127 if (rs6000_emit_set_const (operands[0], operands[1]))
9128 DONE;
9129 else
9130 FAIL;
9131 })
9132
9133 (define_split
9134 [(set (match_operand:DI 0 "int_reg_operand_not_pseudo")
9135 (match_operand:DI 1 "const_scalar_int_operand"))]
9136 "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
9137 [(set (match_dup 0) (match_dup 2))
9138 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
9139 {
9140 if (rs6000_emit_set_const (operands[0], operands[1]))
9141 DONE;
9142 else
9143 FAIL;
9144 })
9145
9146 (define_split
9147 [(set (match_operand:DI 0 "altivec_register_operand")
9148 (match_operand:DI 1 "s5bit_cint_operand"))]
9149 "TARGET_VSX && reload_completed"
9150 [(const_int 0)]
9151 {
9152 rtx op0 = operands[0];
9153 rtx op1 = operands[1];
9154 int r = REGNO (op0);
9155 rtx op0_v4si = gen_rtx_REG (V4SImode, r);
9156
9157 emit_insn (gen_altivec_vspltisw (op0_v4si, op1));
9158 if (op1 != const0_rtx && op1 != constm1_rtx)
9159 {
9160 rtx op0_v2di = gen_rtx_REG (V2DImode, r);
9161 emit_insn (gen_altivec_vupkhsw (op0_v2di, op0_v4si));
9162 }
9163 DONE;
9164 })
9165
9166 ;; Split integer constants that can be loaded with XXSPLTIB and a
9167 ;; sign extend operation.
9168 (define_split
9169 [(set (match_operand:INT_ISA3 0 "altivec_register_operand")
9170 (match_operand:INT_ISA3 1 "xxspltib_constant_split"))]
9171 "TARGET_P9_VECTOR && reload_completed"
9172 [(const_int 0)]
9173 {
9174 rtx op0 = operands[0];
9175 rtx op1 = operands[1];
9176 int r = REGNO (op0);
9177 rtx op0_v16qi = gen_rtx_REG (V16QImode, r);
9178
9179 emit_insn (gen_xxspltib_v16qi (op0_v16qi, op1));
9180 if (<MODE>mode == DImode)
9181 emit_insn (gen_vsx_sign_extend_qi_di (operands[0], op0_v16qi));
9182 else if (<MODE>mode == SImode)
9183 emit_insn (gen_vsx_sign_extend_qi_si (operands[0], op0_v16qi));
9184 else if (<MODE>mode == HImode)
9185 {
9186 rtx op0_v8hi = gen_rtx_REG (V8HImode, r);
9187 emit_insn (gen_altivec_vupkhsb (op0_v8hi, op0_v16qi));
9188 }
9189 DONE;
9190 })
9191
9192 \f
9193 ;; TImode/PTImode is similar, except that we usually want to compute the
9194 ;; address into a register and use lsi/stsi (the exception is during reload).
9195
9196 (define_insn "*mov<mode>_string"
9197 [(set (match_operand:TI2 0 "reg_or_mem_operand" "=Q,Y,????r,????r,????r,r")
9198 (match_operand:TI2 1 "input_operand" "r,r,Q,Y,r,n"))]
9199 "! TARGET_POWERPC64
9200 && (<MODE>mode != TImode || VECTOR_MEM_NONE_P (TImode))
9201 && (gpc_reg_operand (operands[0], <MODE>mode)
9202 || gpc_reg_operand (operands[1], <MODE>mode))"
9203 "#"
9204 [(set_attr "type" "store,store,load,load,*,*")
9205 (set_attr "update" "yes")
9206 (set_attr "indexed" "yes")
9207 (set_attr "cell_micro" "conditional")])
9208
9209 (define_insn "*mov<mode>_ppc64"
9210 [(set (match_operand:TI2 0 "nonimmediate_operand" "=wQ,Y,r,r,r,r")
9211 (match_operand:TI2 1 "input_operand" "r,r,wQ,Y,r,n"))]
9212 "(TARGET_POWERPC64 && VECTOR_MEM_NONE_P (<MODE>mode)
9213 && (gpc_reg_operand (operands[0], <MODE>mode)
9214 || gpc_reg_operand (operands[1], <MODE>mode)))"
9215 {
9216 return rs6000_output_move_128bit (operands);
9217 }
9218 [(set_attr "type" "store,store,load,load,*,*")
9219 (set_attr "length" "8")
9220 (set_attr "max_prefixed_insns" "2")])
9221
9222 (define_split
9223 [(set (match_operand:TI2 0 "int_reg_operand")
9224 (match_operand:TI2 1 "const_scalar_int_operand"))]
9225 "TARGET_POWERPC64
9226 && (VECTOR_MEM_NONE_P (<MODE>mode)
9227 || (reload_completed && INT_REGNO_P (REGNO (operands[0]))))"
9228 [(set (match_dup 2) (match_dup 4))
9229 (set (match_dup 3) (match_dup 5))]
9230 {
9231 operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
9232 <MODE>mode);
9233 operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
9234 <MODE>mode);
9235 if (CONST_WIDE_INT_P (operands[1]))
9236 {
9237 operands[4] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 1));
9238 operands[5] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 0));
9239 }
9240 else if (CONST_INT_P (operands[1]))
9241 {
9242 operands[4] = GEN_INT (- (INTVAL (operands[1]) < 0));
9243 operands[5] = operands[1];
9244 }
9245 else
9246 FAIL;
9247 })
9248
9249 (define_split
9250 [(set (match_operand:TI2 0 "nonimmediate_operand")
9251 (match_operand:TI2 1 "input_operand"))]
9252 "reload_completed
9253 && gpr_or_gpr_p (operands[0], operands[1])
9254 && !direct_move_p (operands[0], operands[1])
9255 && !quad_load_store_p (operands[0], operands[1])"
9256 [(pc)]
9257 {
9258 rs6000_split_multireg_move (operands[0], operands[1]);
9259 DONE;
9260 })
9261 \f
9262 (define_expand "setmemsi"
9263 [(parallel [(set (match_operand:BLK 0 "")
9264 (match_operand 2 "const_int_operand"))
9265 (use (match_operand:SI 1 ""))
9266 (use (match_operand:SI 3 ""))])]
9267 ""
9268 {
9269 /* If value to set is not zero, use the library routine. */
9270 if (operands[2] != const0_rtx)
9271 FAIL;
9272
9273 if (expand_block_clear (operands))
9274 DONE;
9275 else
9276 FAIL;
9277 })
9278
9279 ;; String compare N insn.
9280 ;; Argument 0 is the target (result)
9281 ;; Argument 1 is the destination
9282 ;; Argument 2 is the source
9283 ;; Argument 3 is the length
9284 ;; Argument 4 is the alignment
9285
9286 (define_expand "cmpstrnsi"
9287 [(parallel [(set (match_operand:SI 0)
9288 (compare:SI (match_operand:BLK 1)
9289 (match_operand:BLK 2)))
9290 (use (match_operand:SI 3))
9291 (use (match_operand:SI 4))])]
9292 "TARGET_CMPB && (BYTES_BIG_ENDIAN || TARGET_LDBRX)"
9293 {
9294 if (optimize_insn_for_size_p ())
9295 FAIL;
9296
9297 if (expand_strn_compare (operands, 0))
9298 DONE;
9299 else
9300 FAIL;
9301 })
9302
9303 ;; String compare insn.
9304 ;; Argument 0 is the target (result)
9305 ;; Argument 1 is the destination
9306 ;; Argument 2 is the source
9307 ;; Argument 3 is the alignment
9308
9309 (define_expand "cmpstrsi"
9310 [(parallel [(set (match_operand:SI 0)
9311 (compare:SI (match_operand:BLK 1)
9312 (match_operand:BLK 2)))
9313 (use (match_operand:SI 3))])]
9314 "TARGET_CMPB && (BYTES_BIG_ENDIAN || TARGET_LDBRX)"
9315 {
9316 if (optimize_insn_for_size_p ())
9317 FAIL;
9318
9319 if (expand_strn_compare (operands, 1))
9320 DONE;
9321 else
9322 FAIL;
9323 })
9324
9325 ;; Block compare insn.
9326 ;; Argument 0 is the target (result)
9327 ;; Argument 1 is the destination
9328 ;; Argument 2 is the source
9329 ;; Argument 3 is the length
9330 ;; Argument 4 is the alignment
9331
9332 (define_expand "cmpmemsi"
9333 [(parallel [(set (match_operand:SI 0)
9334 (compare:SI (match_operand:BLK 1)
9335 (match_operand:BLK 2)))
9336 (use (match_operand:SI 3))
9337 (use (match_operand:SI 4))])]
9338 "TARGET_POPCNTD"
9339 {
9340 if (expand_block_compare (operands))
9341 DONE;
9342 else
9343 FAIL;
9344 })
9345
9346 ;; String/block copy insn (source and destination must not overlap).
9347 ;; Argument 0 is the destination
9348 ;; Argument 1 is the source
9349 ;; Argument 2 is the length
9350 ;; Argument 3 is the alignment
9351
9352 (define_expand "cpymemsi"
9353 [(parallel [(set (match_operand:BLK 0 "")
9354 (match_operand:BLK 1 ""))
9355 (use (match_operand:SI 2 ""))
9356 (use (match_operand:SI 3 ""))])]
9357 ""
9358 {
9359 if (expand_block_move (operands, false))
9360 DONE;
9361 else
9362 FAIL;
9363 })
9364
9365 ;; String/block move insn (source and destination may overlap).
9366 ;; Argument 0 is the destination
9367 ;; Argument 1 is the source
9368 ;; Argument 2 is the length
9369 ;; Argument 3 is the alignment
9370
9371 (define_expand "movmemsi"
9372 [(parallel [(set (match_operand:BLK 0 "")
9373 (match_operand:BLK 1 ""))
9374 (use (match_operand:SI 2 ""))
9375 (use (match_operand:SI 3 ""))])]
9376 ""
9377 {
9378 if (expand_block_move (operands, true))
9379 DONE;
9380 else
9381 FAIL;
9382 })
9383
9384 \f
9385 ;; Define insns that do load or store with update. Some of these we can
9386 ;; get by using pre-decrement or pre-increment, but the hardware can also
9387 ;; do cases where the increment is not the size of the object.
9388 ;;
9389 ;; In all these cases, we use operands 0 and 1 for the register being
9390 ;; incremented because those are the operands that local-alloc will
9391 ;; tie and these are the pair most likely to be tieable (and the ones
9392 ;; that will benefit the most).
9393
9394 (define_insn "*movdi_update1"
9395 [(set (match_operand:DI 3 "gpc_reg_operand" "=r,r")
9396 (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9397 (match_operand:P 2 "reg_or_aligned_short_operand" "r,I"))))
9398 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9399 (plus:P (match_dup 1) (match_dup 2)))]
9400 "TARGET_POWERPC64 && TARGET_UPDATE
9401 && (!avoiding_indexed_address_p (DImode)
9402 || !gpc_reg_operand (operands[2], Pmode))"
9403 "@
9404 ldux %3,%0,%2
9405 ldu %3,%2(%0)"
9406 [(set_attr "type" "load")
9407 (set_attr "update" "yes")
9408 (set_attr "indexed" "yes,no")])
9409
9410 (define_insn "movdi_<mode>_update"
9411 [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9412 (match_operand:P 2 "reg_or_aligned_short_operand" "r,I")))
9413 (match_operand:DI 3 "gpc_reg_operand" "r,r"))
9414 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9415 (plus:P (match_dup 1) (match_dup 2)))]
9416 "TARGET_POWERPC64 && TARGET_UPDATE
9417 && (!avoiding_indexed_address_p (DImode)
9418 || !gpc_reg_operand (operands[2], Pmode)
9419 || (REG_P (operands[0])
9420 && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
9421 "@
9422 stdux %3,%0,%2
9423 stdu %3,%2(%0)"
9424 [(set_attr "type" "store")
9425 (set_attr "update" "yes")
9426 (set_attr "indexed" "yes,no")])
9427
9428 ;; This pattern is only conditional on TARGET_64BIT, as it is
9429 ;; needed for stack allocation, even if the user passes -mno-update.
9430 (define_insn "movdi_update_stack"
9431 [(set (mem:DI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0,0")
9432 (match_operand:DI 2 "reg_or_aligned_short_operand" "r,I")))
9433 (match_operand:DI 3 "gpc_reg_operand" "r,r"))
9434 (set (match_operand:DI 0 "gpc_reg_operand" "=b,b")
9435 (plus:DI (match_dup 1) (match_dup 2)))]
9436 "TARGET_64BIT"
9437 "@
9438 stdux %3,%0,%2
9439 stdu %3,%2(%0)"
9440 [(set_attr "type" "store")
9441 (set_attr "update" "yes")
9442 (set_attr "indexed" "yes,no")])
9443
9444 (define_insn "*movsi_update1"
9445 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9446 (mem:SI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9447 (match_operand:P 2 "reg_or_short_operand" "r,I"))))
9448 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9449 (plus:P (match_dup 1) (match_dup 2)))]
9450 "TARGET_UPDATE
9451 && (!avoiding_indexed_address_p (SImode)
9452 || !gpc_reg_operand (operands[2], Pmode))"
9453 "@
9454 lwzux %3,%0,%2
9455 lwzu %3,%2(%0)"
9456 [(set_attr "type" "load")
9457 (set_attr "update" "yes")
9458 (set_attr "indexed" "yes,no")])
9459
9460 (define_insn "*movsi_update2"
9461 [(set (match_operand:EXTSI 3 "gpc_reg_operand" "=r")
9462 (sign_extend:EXTSI
9463 (mem:SI (plus:P (match_operand:P 1 "gpc_reg_operand" "0")
9464 (match_operand:P 2 "gpc_reg_operand" "r")))))
9465 (set (match_operand:P 0 "gpc_reg_operand" "=b")
9466 (plus:P (match_dup 1) (match_dup 2)))]
9467 "TARGET_POWERPC64 && !avoiding_indexed_address_p (DImode)"
9468 "lwaux %3,%0,%2"
9469 [(set_attr "type" "load")
9470 (set_attr "sign_extend" "yes")
9471 (set_attr "update" "yes")
9472 (set_attr "indexed" "yes")])
9473
9474 (define_insn "movsi_<mode>_update"
9475 [(set (mem:SI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9476 (match_operand:P 2 "reg_or_short_operand" "r,I")))
9477 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
9478 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9479 (plus:P (match_dup 1) (match_dup 2)))]
9480 "TARGET_UPDATE
9481 && (!avoiding_indexed_address_p (SImode)
9482 || !gpc_reg_operand (operands[2], Pmode)
9483 || (REG_P (operands[0])
9484 && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
9485 "@
9486 stwux %3,%0,%2
9487 stwu %3,%2(%0)"
9488 [(set_attr "type" "store")
9489 (set_attr "update" "yes")
9490 (set_attr "indexed" "yes,no")])
9491
9492 ;; This is an unconditional pattern; needed for stack allocation, even
9493 ;; if the user passes -mno-update.
9494 (define_insn "movsi_update_stack"
9495 [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9496 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9497 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
9498 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9499 (plus:SI (match_dup 1) (match_dup 2)))]
9500 "TARGET_32BIT"
9501 "@
9502 stwux %3,%0,%2
9503 stwu %3,%2(%0)"
9504 [(set_attr "type" "store")
9505 (set_attr "update" "yes")
9506 (set_attr "indexed" "yes,no")])
9507
9508 (define_insn "*movhi_update1"
9509 [(set (match_operand:HI 3 "gpc_reg_operand" "=r,r")
9510 (mem:HI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9511 (match_operand:P 2 "reg_or_short_operand" "r,I"))))
9512 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9513 (plus:P (match_dup 1) (match_dup 2)))]
9514 "TARGET_UPDATE
9515 && (!avoiding_indexed_address_p (HImode)
9516 || !gpc_reg_operand (operands[2], SImode))"
9517 "@
9518 lhzux %3,%0,%2
9519 lhzu %3,%2(%0)"
9520 [(set_attr "type" "load")
9521 (set_attr "update" "yes")
9522 (set_attr "indexed" "yes,no")])
9523
9524 (define_insn "*movhi_update2"
9525 [(set (match_operand:EXTHI 3 "gpc_reg_operand" "=r,r")
9526 (zero_extend:EXTHI
9527 (mem:HI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9528 (match_operand:P 2 "reg_or_short_operand" "r,I")))))
9529 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9530 (plus:P (match_dup 1) (match_dup 2)))]
9531 "TARGET_UPDATE
9532 && (!avoiding_indexed_address_p (HImode)
9533 || !gpc_reg_operand (operands[2], Pmode))"
9534 "@
9535 lhzux %3,%0,%2
9536 lhzu %3,%2(%0)"
9537 [(set_attr "type" "load")
9538 (set_attr "update" "yes")
9539 (set_attr "indexed" "yes,no")])
9540
9541 (define_insn "*movhi_update3"
9542 [(set (match_operand:EXTHI 3 "gpc_reg_operand" "=r,r")
9543 (sign_extend:EXTHI
9544 (mem:HI (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_UPDATE
9549 && !(avoiding_indexed_address_p (HImode)
9550 && gpc_reg_operand (operands[2], Pmode))"
9551 "@
9552 lhaux %3,%0,%2
9553 lhau %3,%2(%0)"
9554 [(set_attr "type" "load")
9555 (set_attr "sign_extend" "yes")
9556 (set_attr "update" "yes")
9557 (set_attr "indexed" "yes,no")])
9558
9559 (define_insn "*movhi_update4"
9560 [(set (mem:HI (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:HI 3 "gpc_reg_operand" "r,r"))
9563 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9564 (plus:P (match_dup 1) (match_dup 2)))]
9565 "TARGET_UPDATE
9566 && (!avoiding_indexed_address_p (HImode)
9567 || !gpc_reg_operand (operands[2], Pmode))"
9568 "@
9569 sthux %3,%0,%2
9570 sthu %3,%2(%0)"
9571 [(set_attr "type" "store")
9572 (set_attr "update" "yes")
9573 (set_attr "indexed" "yes,no")])
9574
9575 (define_insn "*movqi_update1"
9576 [(set (match_operand:QI 3 "gpc_reg_operand" "=r,r")
9577 (mem:QI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9578 (match_operand:P 2 "reg_or_short_operand" "r,I"))))
9579 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9580 (plus:P (match_dup 1) (match_dup 2)))]
9581 "TARGET_UPDATE
9582 && (!avoiding_indexed_address_p (QImode)
9583 || !gpc_reg_operand (operands[2], Pmode))"
9584 "@
9585 lbzux %3,%0,%2
9586 lbzu %3,%2(%0)"
9587 [(set_attr "type" "load")
9588 (set_attr "update" "yes")
9589 (set_attr "indexed" "yes,no")])
9590
9591 (define_insn "*movqi_update2"
9592 [(set (match_operand:EXTQI 3 "gpc_reg_operand" "=r,r")
9593 (zero_extend:EXTQI
9594 (mem:QI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9595 (match_operand:P 2 "reg_or_short_operand" "r,I")))))
9596 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9597 (plus:P (match_dup 1) (match_dup 2)))]
9598 "TARGET_UPDATE
9599 && (!avoiding_indexed_address_p (QImode)
9600 || !gpc_reg_operand (operands[2], Pmode))"
9601 "@
9602 lbzux %3,%0,%2
9603 lbzu %3,%2(%0)"
9604 [(set_attr "type" "load")
9605 (set_attr "update" "yes")
9606 (set_attr "indexed" "yes,no")])
9607
9608 (define_insn "*movqi_update3"
9609 [(set (mem:QI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9610 (match_operand:P 2 "reg_or_short_operand" "r,I")))
9611 (match_operand:QI 3 "gpc_reg_operand" "r,r"))
9612 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9613 (plus:P (match_dup 1) (match_dup 2)))]
9614 "TARGET_UPDATE
9615 && (!avoiding_indexed_address_p (QImode)
9616 || !gpc_reg_operand (operands[2], Pmode))"
9617 "@
9618 stbux %3,%0,%2
9619 stbu %3,%2(%0)"
9620 [(set_attr "type" "store")
9621 (set_attr "update" "yes")
9622 (set_attr "indexed" "yes,no")])
9623
9624 (define_insn "*mov<SFDF:mode>_update1"
9625 [(set (match_operand:SFDF 3 "gpc_reg_operand" "=<SFDF:Ff>,<SFDF:Ff>")
9626 (mem:SFDF (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9627 (match_operand:P 2 "reg_or_short_operand" "r,I"))))
9628 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9629 (plus:P (match_dup 1) (match_dup 2)))]
9630 "TARGET_HARD_FLOAT && TARGET_UPDATE
9631 && (!avoiding_indexed_address_p (<SFDF:MODE>mode)
9632 || !gpc_reg_operand (operands[2], Pmode))"
9633 "@
9634 lf<sd>ux %3,%0,%2
9635 lf<sd>u %3,%2(%0)"
9636 [(set_attr "type" "fpload")
9637 (set_attr "update" "yes")
9638 (set_attr "indexed" "yes,no")
9639 (set_attr "size" "<SFDF:bits>")])
9640
9641 (define_insn "*mov<SFDF:mode>_update2"
9642 [(set (mem:SFDF (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9643 (match_operand:P 2 "reg_or_short_operand" "r,I")))
9644 (match_operand:SFDF 3 "gpc_reg_operand" "<SFDF:Ff>,<SFDF:Ff>"))
9645 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9646 (plus:P (match_dup 1) (match_dup 2)))]
9647 "TARGET_HARD_FLOAT && TARGET_UPDATE
9648 && (!avoiding_indexed_address_p (<SFDF:MODE>mode)
9649 || !gpc_reg_operand (operands[2], Pmode))"
9650 "@
9651 stf<sd>ux %3,%0,%2
9652 stf<sd>u %3,%2(%0)"
9653 [(set_attr "type" "fpstore")
9654 (set_attr "update" "yes")
9655 (set_attr "indexed" "yes,no")
9656 (set_attr "size" "<SFDF:bits>")])
9657
9658 (define_insn "*movsf_update3"
9659 [(set (match_operand:SF 3 "gpc_reg_operand" "=r,r")
9660 (mem:SF (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9661 (match_operand:P 2 "reg_or_short_operand" "r,I"))))
9662 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9663 (plus:P (match_dup 1) (match_dup 2)))]
9664 "TARGET_SOFT_FLOAT && TARGET_UPDATE
9665 && (!avoiding_indexed_address_p (SFmode)
9666 || !gpc_reg_operand (operands[2], Pmode))"
9667 "@
9668 lwzux %3,%0,%2
9669 lwzu %3,%2(%0)"
9670 [(set_attr "type" "load")
9671 (set_attr "update" "yes")
9672 (set_attr "indexed" "yes,no")])
9673
9674 (define_insn "*movsf_update4"
9675 [(set (mem:SF (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9676 (match_operand:P 2 "reg_or_short_operand" "r,I")))
9677 (match_operand:SF 3 "gpc_reg_operand" "r,r"))
9678 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9679 (plus:P (match_dup 1) (match_dup 2)))]
9680 "TARGET_SOFT_FLOAT && TARGET_UPDATE
9681 && (!avoiding_indexed_address_p (SFmode)
9682 || !gpc_reg_operand (operands[2], Pmode))"
9683 "@
9684 stwux %3,%0,%2
9685 stwu %3,%2(%0)"
9686 [(set_attr "type" "store")
9687 (set_attr "update" "yes")
9688 (set_attr "indexed" "yes,no")])
9689
9690
9691 ;; After inserting conditional returns we can sometimes have
9692 ;; unnecessary register moves. Unfortunately we cannot have a
9693 ;; modeless peephole here, because some single SImode sets have early
9694 ;; clobber outputs. Although those sets expand to multi-ppc-insn
9695 ;; sequences, using get_attr_length here will smash the operands
9696 ;; array. Neither is there an early_cobbler_p predicate.
9697 ;; Also this optimization interferes with scalars going into
9698 ;; altivec registers (the code does reloading through the FPRs).
9699 (define_peephole2
9700 [(set (match_operand:DF 0 "gpc_reg_operand")
9701 (match_operand:DF 1 "any_operand"))
9702 (set (match_operand:DF 2 "gpc_reg_operand")
9703 (match_dup 0))]
9704 "!TARGET_VSX
9705 && peep2_reg_dead_p (2, operands[0])"
9706 [(set (match_dup 2) (match_dup 1))])
9707
9708 (define_peephole2
9709 [(set (match_operand:SF 0 "gpc_reg_operand")
9710 (match_operand:SF 1 "any_operand"))
9711 (set (match_operand:SF 2 "gpc_reg_operand")
9712 (match_dup 0))]
9713 "!TARGET_P8_VECTOR
9714 && peep2_reg_dead_p (2, operands[0])"
9715 [(set (match_dup 2) (match_dup 1))])
9716
9717 \f
9718 ;; TLS support.
9719
9720 (define_insn "*tls_gd_pcrel<bits>"
9721 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9722 (unspec:P [(match_operand:P 1 "rs6000_tls_symbol_ref" "")
9723 (const_int 0)]
9724 UNSPEC_TLSGD))]
9725 "HAVE_AS_TLS && TARGET_ELF"
9726 "la %0,%1@got@tlsgd@pcrel"
9727 [(set_attr "prefixed" "yes")])
9728
9729 (define_insn_and_split "*tls_gd<bits>"
9730 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9731 (unspec:P [(match_operand:P 1 "rs6000_tls_symbol_ref" "")
9732 (match_operand:P 2 "gpc_reg_operand" "b")]
9733 UNSPEC_TLSGD))]
9734 "HAVE_AS_TLS && TARGET_ELF"
9735 "addi %0,%2,%1@got@tlsgd"
9736 "&& TARGET_CMODEL != CMODEL_SMALL"
9737 [(set (match_dup 3)
9738 (high:P
9739 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))
9740 (set (match_dup 0)
9741 (lo_sum:P (match_dup 3)
9742 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))]
9743 {
9744 operands[3] = gen_reg_rtx (<MODE>mode);
9745 }
9746 [(set (attr "length")
9747 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9748 (const_int 8)
9749 (const_int 4)))])
9750
9751 (define_insn "*tls_gd_high<bits>"
9752 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9753 (high:P
9754 (unspec:P [(match_operand:P 1 "rs6000_tls_symbol_ref" "")
9755 (match_operand:P 2 "gpc_reg_operand" "b")]
9756 UNSPEC_TLSGD)))]
9757 "HAVE_AS_TLS && TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
9758 "addis %0,%2,%1@got@tlsgd@ha")
9759
9760 (define_insn "*tls_gd_low<bits>"
9761 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9762 (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
9763 (unspec:P [(match_operand:P 2 "rs6000_tls_symbol_ref" "")
9764 (match_operand:P 3 "gpc_reg_operand" "b")]
9765 UNSPEC_TLSGD)))]
9766 "HAVE_AS_TLS && TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
9767 "addi %0,%1,%2@got@tlsgd@l")
9768
9769 (define_insn "*tls_ld_pcrel<bits>"
9770 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9771 (unspec:P [(const_int 0)]
9772 UNSPEC_TLSLD))]
9773 "HAVE_AS_TLS && TARGET_ELF"
9774 "la %0,%&@got@tlsld@pcrel"
9775 [(set_attr "prefixed" "yes")])
9776
9777 (define_insn_and_split "*tls_ld<bits>"
9778 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9779 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")]
9780 UNSPEC_TLSLD))]
9781 "HAVE_AS_TLS && TARGET_ELF"
9782 "addi %0,%1,%&@got@tlsld"
9783 "&& TARGET_CMODEL != CMODEL_SMALL"
9784 [(set (match_dup 2)
9785 (high:P
9786 (unspec:P [(match_dup 1)] UNSPEC_TLSLD)))
9787 (set (match_dup 0)
9788 (lo_sum:P (match_dup 2)
9789 (unspec:P [(match_dup 1)] UNSPEC_TLSLD)))]
9790 {
9791 operands[2] = gen_reg_rtx (<MODE>mode);
9792 }
9793 [(set (attr "length")
9794 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9795 (const_int 8)
9796 (const_int 4)))])
9797
9798 (define_insn "*tls_ld_high<bits>"
9799 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9800 (high:P
9801 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")]
9802 UNSPEC_TLSLD)))]
9803 "HAVE_AS_TLS && TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
9804 "addis %0,%1,%&@got@tlsld@ha")
9805
9806 (define_insn "*tls_ld_low<bits>"
9807 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9808 (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
9809 (unspec:P [(match_operand:P 2 "gpc_reg_operand" "b")]
9810 UNSPEC_TLSLD)))]
9811 "HAVE_AS_TLS && TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
9812 "addi %0,%1,%&@got@tlsld@l")
9813
9814 (define_insn "tls_dtprel_<bits>"
9815 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9816 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9817 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9818 UNSPEC_TLSDTPREL))]
9819 "HAVE_AS_TLS"
9820 "addi %0,%1,%2@dtprel"
9821 [(set (attr "prefixed")
9822 (if_then_else (match_test "rs6000_tls_size == 16")
9823 (const_string "no")
9824 (const_string "yes")))])
9825
9826 (define_insn "tls_dtprel_ha_<bits>"
9827 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9828 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9829 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9830 UNSPEC_TLSDTPRELHA))]
9831 "HAVE_AS_TLS"
9832 "addis %0,%1,%2@dtprel@ha")
9833
9834 (define_insn "tls_dtprel_lo_<bits>"
9835 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9836 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9837 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9838 UNSPEC_TLSDTPRELLO))]
9839 "HAVE_AS_TLS"
9840 "addi %0,%1,%2@dtprel@l")
9841
9842 (define_insn_and_split "tls_got_dtprel_<bits>"
9843 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9844 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9845 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9846 UNSPEC_TLSGOTDTPREL))]
9847 "HAVE_AS_TLS"
9848 "<ptrload> %0,%2@got@dtprel(%1)"
9849 "&& TARGET_CMODEL != CMODEL_SMALL"
9850 [(set (match_dup 3)
9851 (high:P
9852 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))
9853 (set (match_dup 0)
9854 (lo_sum:P (match_dup 3)
9855 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))]
9856 {
9857 operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9858 }
9859 [(set (attr "length")
9860 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9861 (const_int 8)
9862 (const_int 4)))])
9863
9864 (define_insn "*tls_got_dtprel_high<bits>"
9865 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9866 (high:P
9867 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9868 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9869 UNSPEC_TLSGOTDTPREL)))]
9870 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9871 "addis %0,%1,%2@got@dtprel@ha")
9872
9873 (define_insn "*tls_got_dtprel_low<bits>"
9874 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9875 (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
9876 (unspec:P [(match_operand:P 3 "gpc_reg_operand" "b")
9877 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9878 UNSPEC_TLSGOTDTPREL)))]
9879 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9880 "<ptrload> %0,%2@got@dtprel@l(%1)")
9881
9882 (define_insn "tls_tprel_<bits>"
9883 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9884 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9885 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9886 UNSPEC_TLSTPREL))]
9887 "HAVE_AS_TLS"
9888 "addi %0,%1,%2@tprel"
9889 [(set (attr "prefixed")
9890 (if_then_else (match_test "rs6000_tls_size == 16")
9891 (const_string "no")
9892 (const_string "yes")))])
9893
9894 (define_insn "tls_tprel_ha_<bits>"
9895 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9896 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9897 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9898 UNSPEC_TLSTPRELHA))]
9899 "HAVE_AS_TLS"
9900 "addis %0,%1,%2@tprel@ha")
9901
9902 (define_insn "tls_tprel_lo_<bits>"
9903 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9904 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9905 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9906 UNSPEC_TLSTPRELLO))]
9907 "HAVE_AS_TLS"
9908 "addi %0,%1,%2@tprel@l")
9909
9910 (define_insn "*tls_got_tprel_pcrel_<bits>"
9911 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9912 (unspec:P [(const_int 0)
9913 (match_operand:P 1 "rs6000_tls_symbol_ref" "")]
9914 UNSPEC_TLSGOTTPREL))]
9915 "HAVE_AS_TLS"
9916 "<ptrload> %0,%1@got@tprel@pcrel"
9917 [(set_attr "prefixed" "yes")])
9918
9919 ;; "b" output constraint here and on tls_tls input to support linker tls
9920 ;; optimization. The linker may edit the instructions emitted by a
9921 ;; tls_got_tprel/tls_tls pair to addis,addi.
9922 (define_insn_and_split "tls_got_tprel_<bits>"
9923 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9924 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9925 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9926 UNSPEC_TLSGOTTPREL))]
9927 "HAVE_AS_TLS"
9928 "<ptrload> %0,%2@got@tprel(%1)"
9929 "&& TARGET_CMODEL != CMODEL_SMALL"
9930 [(set (match_dup 3)
9931 (high:P
9932 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))
9933 (set (match_dup 0)
9934 (lo_sum:P (match_dup 3)
9935 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))]
9936 {
9937 operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9938 }
9939 [(set (attr "length")
9940 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9941 (const_int 8)
9942 (const_int 4)))])
9943
9944 (define_insn "*tls_got_tprel_high<bits>"
9945 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9946 (high:P
9947 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9948 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9949 UNSPEC_TLSGOTTPREL)))]
9950 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9951 "addis %0,%1,%2@got@tprel@ha")
9952
9953 (define_insn "*tls_got_tprel_low<bits>"
9954 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9955 (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
9956 (unspec:P [(match_operand:P 3 "gpc_reg_operand" "b")
9957 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9958 UNSPEC_TLSGOTTPREL)))]
9959 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9960 "<ptrload> %0,%2@got@tprel@l(%1)")
9961
9962 (define_insn "tls_tls_pcrel_<bits>"
9963 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9964 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9965 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9966 UNSPEC_TLSTLS_PCREL))]
9967 "TARGET_ELF && HAVE_AS_TLS"
9968 "add %0,%1,%2@tls@pcrel")
9969
9970 (define_insn "tls_tls_<bits>"
9971 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9972 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9973 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9974 UNSPEC_TLSTLS))]
9975 "TARGET_ELF && HAVE_AS_TLS"
9976 "add %0,%1,%2@tls")
9977
9978 (define_expand "tls_get_tpointer"
9979 [(set (match_operand:SI 0 "gpc_reg_operand")
9980 (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))]
9981 "TARGET_XCOFF && HAVE_AS_TLS"
9982 {
9983 emit_insn (gen_tls_get_tpointer_internal ());
9984 emit_move_insn (operands[0], gen_rtx_REG (SImode, 3));
9985 DONE;
9986 })
9987
9988 (define_insn "tls_get_tpointer_internal"
9989 [(set (reg:SI 3)
9990 (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))
9991 (clobber (reg:SI LR_REGNO))]
9992 "TARGET_XCOFF && HAVE_AS_TLS"
9993 "bla __get_tpointer")
9994
9995 (define_expand "tls_get_addr<mode>"
9996 [(set (match_operand:P 0 "gpc_reg_operand")
9997 (unspec:P [(match_operand:P 1 "gpc_reg_operand")
9998 (match_operand:P 2 "gpc_reg_operand")] UNSPEC_TLSTLS))]
9999 "TARGET_XCOFF && HAVE_AS_TLS"
10000 {
10001 emit_move_insn (gen_rtx_REG (Pmode, 3), operands[1]);
10002 emit_move_insn (gen_rtx_REG (Pmode, 4), operands[2]);
10003 emit_insn (gen_tls_get_addr_internal<mode> ());
10004 emit_move_insn (operands[0], gen_rtx_REG (Pmode, 3));
10005 DONE;
10006 })
10007
10008 (define_insn "tls_get_addr_internal<mode>"
10009 [(set (reg:P 3)
10010 (unspec:P [(reg:P 3) (reg:P 4)] UNSPEC_TLSTLS))
10011 (clobber (reg:P 0))
10012 (clobber (reg:P 4))
10013 (clobber (reg:P 5))
10014 (clobber (reg:P 11))
10015 (clobber (reg:CC CR0_REGNO))
10016 (clobber (reg:P LR_REGNO))]
10017 "TARGET_XCOFF && HAVE_AS_TLS"
10018 "bla __tls_get_addr")
10019 \f
10020 ;; Next come insns related to the calling sequence.
10021 ;;
10022 ;; First, an insn to allocate new stack space for dynamic use (e.g., alloca).
10023 ;; We move the back-chain and decrement the stack pointer.
10024 ;;
10025 ;; Operand1 is more naturally reg_or_short_operand. However, for a large
10026 ;; constant alloca, using that predicate will force the generic code to put
10027 ;; the constant size into a register before calling the expander.
10028 ;;
10029 ;; As a result the expander would not have the constant size information
10030 ;; in those cases and would have to generate less efficient code.
10031 ;;
10032 ;; Thus we allow reg_or_cint_operand instead so that the expander can see
10033 ;; the constant size. The value is forced into a register if necessary.
10034 ;;
10035 (define_expand "allocate_stack"
10036 [(set (match_operand 0 "gpc_reg_operand")
10037 (minus (reg 1) (match_operand 1 "reg_or_cint_operand")))
10038 (set (reg 1)
10039 (minus (reg 1) (match_dup 1)))]
10040 ""
10041 {
10042 rtx chain = gen_reg_rtx (Pmode);
10043 rtx stack_bot = gen_rtx_MEM (Pmode, stack_pointer_rtx);
10044 rtx neg_op0;
10045 rtx insn, par, set, mem;
10046
10047 /* By allowing reg_or_cint_operand as the predicate we can get
10048 better code for stack-clash-protection because we do not lose
10049 size information. But the rest of the code expects the operand
10050 to be reg_or_short_operand. If it isn't, then force it into
10051 a register. */
10052 rtx orig_op1 = operands[1];
10053 if (!reg_or_short_operand (operands[1], Pmode))
10054 operands[1] = force_reg (Pmode, operands[1]);
10055
10056 emit_move_insn (chain, stack_bot);
10057
10058 /* Check stack bounds if necessary. */
10059 if (crtl->limit_stack)
10060 {
10061 rtx available;
10062 available = expand_binop (Pmode, sub_optab,
10063 stack_pointer_rtx, stack_limit_rtx,
10064 NULL_RTX, 1, OPTAB_WIDEN);
10065 emit_insn (gen_cond_trap (LTU, available, operands[1], const0_rtx));
10066 }
10067
10068 /* Allocate and probe if requested.
10069 This may look similar to the loop we use for prologue allocations,
10070 but it is critically different. For the former we know the loop
10071 will iterate, but do not know that generally here. The former
10072 uses that knowledge to rotate the loop. Combining them would be
10073 possible with some performance cost. */
10074 if (flag_stack_clash_protection)
10075 {
10076 rtx rounded_size, last_addr, residual;
10077 HOST_WIDE_INT probe_interval;
10078 compute_stack_clash_protection_loop_data (&rounded_size, &last_addr,
10079 &residual, &probe_interval,
10080 orig_op1);
10081
10082 /* We do occasionally get in here with constant sizes, we might
10083 as well do a reasonable job when we obviously can. */
10084 if (rounded_size != const0_rtx)
10085 {
10086 rtx loop_lab, end_loop;
10087 bool rotated = CONST_INT_P (rounded_size);
10088 rtx update = GEN_INT (-probe_interval);
10089 if (probe_interval > 32768)
10090 update = force_reg (Pmode, update);
10091
10092 emit_stack_clash_protection_probe_loop_start (&loop_lab, &end_loop,
10093 last_addr, rotated);
10094
10095 if (TARGET_32BIT)
10096 emit_insn (gen_movsi_update_stack (stack_pointer_rtx,
10097 stack_pointer_rtx,
10098 update, chain));
10099 else
10100 emit_insn (gen_movdi_update_stack (stack_pointer_rtx,
10101 stack_pointer_rtx,
10102 update, chain));
10103 emit_stack_clash_protection_probe_loop_end (loop_lab, end_loop,
10104 last_addr, rotated);
10105 }
10106
10107 /* Now handle residuals. We just have to set operands[1] correctly
10108 and let the rest of the expander run. */
10109 operands[1] = residual;
10110 }
10111
10112 if (!(CONST_INT_P (operands[1])
10113 && IN_RANGE (INTVAL (operands[1]), -32767, 32768)))
10114 {
10115 operands[1] = force_reg (Pmode, operands[1]);
10116 neg_op0 = gen_reg_rtx (Pmode);
10117 emit_insn (gen_neg2 (Pmode, neg_op0, operands[1]));
10118 }
10119 else
10120 neg_op0 = GEN_INT (-INTVAL (operands[1]));
10121
10122 insn = emit_insn ((* ((TARGET_32BIT) ? gen_movsi_update_stack
10123 : gen_movdi_update_stack))
10124 (stack_pointer_rtx, stack_pointer_rtx, neg_op0,
10125 chain));
10126 /* Since we didn't use gen_frame_mem to generate the MEM, grab
10127 it now and set the alias set/attributes. The above gen_*_update
10128 calls will generate a PARALLEL with the MEM set being the first
10129 operation. */
10130 par = PATTERN (insn);
10131 gcc_assert (GET_CODE (par) == PARALLEL);
10132 set = XVECEXP (par, 0, 0);
10133 gcc_assert (GET_CODE (set) == SET);
10134 mem = SET_DEST (set);
10135 gcc_assert (MEM_P (mem));
10136 MEM_NOTRAP_P (mem) = 1;
10137 set_mem_alias_set (mem, get_frame_alias_set ());
10138
10139 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
10140 DONE;
10141 })
10142
10143 ;; These patterns say how to save and restore the stack pointer. We need not
10144 ;; save the stack pointer at function level since we are careful to
10145 ;; preserve the backchain. At block level, we have to restore the backchain
10146 ;; when we restore the stack pointer.
10147 ;;
10148 ;; For nonlocal gotos, we must save both the stack pointer and its
10149 ;; backchain and restore both. Note that in the nonlocal case, the
10150 ;; save area is a memory location.
10151
10152 (define_expand "save_stack_function"
10153 [(match_operand 0 "any_operand")
10154 (match_operand 1 "any_operand")]
10155 ""
10156 "DONE;")
10157
10158 (define_expand "restore_stack_function"
10159 [(match_operand 0 "any_operand")
10160 (match_operand 1 "any_operand")]
10161 ""
10162 "DONE;")
10163
10164 ;; Adjust stack pointer (op0) to a new value (op1).
10165 ;; First copy old stack backchain to new location, and ensure that the
10166 ;; scheduler won't reorder the sp assignment before the backchain write.
10167 (define_expand "restore_stack_block"
10168 [(set (match_dup 2) (match_dup 3))
10169 (set (match_dup 4) (match_dup 2))
10170 (match_dup 5)
10171 (set (match_operand 0 "register_operand")
10172 (match_operand 1 "register_operand"))]
10173 ""
10174 {
10175 rtvec p;
10176
10177 operands[1] = force_reg (Pmode, operands[1]);
10178 operands[2] = gen_reg_rtx (Pmode);
10179 operands[3] = gen_frame_mem (Pmode, operands[0]);
10180 operands[4] = gen_frame_mem (Pmode, operands[1]);
10181 p = rtvec_alloc (1);
10182 RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
10183 const0_rtx);
10184 operands[5] = gen_rtx_PARALLEL (VOIDmode, p);
10185 })
10186
10187 (define_expand "save_stack_nonlocal"
10188 [(set (match_dup 3) (match_dup 4))
10189 (set (match_operand 0 "memory_operand") (match_dup 3))
10190 (set (match_dup 2) (match_operand 1 "register_operand"))]
10191 ""
10192 {
10193 int units_per_word = (TARGET_32BIT) ? 4 : 8;
10194
10195 /* Copy the backchain to the first word, sp to the second. */
10196 operands[0] = adjust_address_nv (operands[0], Pmode, 0);
10197 operands[2] = adjust_address_nv (operands[0], Pmode, units_per_word);
10198 operands[3] = gen_reg_rtx (Pmode);
10199 operands[4] = gen_frame_mem (Pmode, operands[1]);
10200 })
10201
10202 (define_expand "restore_stack_nonlocal"
10203 [(set (match_dup 2) (match_operand 1 "memory_operand"))
10204 (set (match_dup 3) (match_dup 4))
10205 (set (match_dup 5) (match_dup 2))
10206 (match_dup 6)
10207 (set (match_operand 0 "register_operand") (match_dup 3))]
10208 ""
10209 {
10210 int units_per_word = (TARGET_32BIT) ? 4 : 8;
10211 rtvec p;
10212
10213 /* Restore the backchain from the first word, sp from the second. */
10214 operands[2] = gen_reg_rtx (Pmode);
10215 operands[3] = gen_reg_rtx (Pmode);
10216 operands[1] = adjust_address_nv (operands[1], Pmode, 0);
10217 operands[4] = adjust_address_nv (operands[1], Pmode, units_per_word);
10218 operands[5] = gen_frame_mem (Pmode, operands[3]);
10219 p = rtvec_alloc (1);
10220 RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
10221 const0_rtx);
10222 operands[6] = gen_rtx_PARALLEL (VOIDmode, p);
10223 })
10224 \f
10225 ;; Load up a PC-relative address. Print_operand_address will append a @pcrel
10226 ;; to the symbol or label.
10227 (define_insn "*pcrel_local_addr"
10228 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
10229 (match_operand:DI 1 "pcrel_local_address"))]
10230 "TARGET_PCREL"
10231 "la %0,%a1"
10232 [(set_attr "prefixed" "yes")])
10233
10234 ;; Load up a PC-relative address to an external symbol. If the symbol and the
10235 ;; program are both defined in the main program, the linker will optimize this
10236 ;; to a PADDI. Otherwise, it will create a GOT address that is relocated by
10237 ;; the dynamic linker and loaded up. Print_operand_address will append a
10238 ;; @got@pcrel to the symbol.
10239 (define_insn "*pcrel_extern_addr"
10240 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
10241 (match_operand:DI 1 "pcrel_external_address"))]
10242 "TARGET_PCREL"
10243 "ld %0,%a1"
10244 [(set_attr "prefixed" "yes")
10245 (set_attr "type" "load")])
10246
10247 ;; TOC register handling.
10248
10249 ;; Code to initialize the TOC register...
10250
10251 (define_insn "load_toc_aix_si"
10252 [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10253 (unspec:SI [(const_int 0)] UNSPEC_TOC))
10254 (use (reg:SI 2))])]
10255 "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_32BIT"
10256 {
10257 char buf[30];
10258 extern int need_toc_init;
10259 need_toc_init = 1;
10260 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
10261 operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
10262 operands[2] = gen_rtx_REG (Pmode, 2);
10263 return "lwz %0,%1(%2)";
10264 }
10265 [(set_attr "type" "load")
10266 (set_attr "update" "no")
10267 (set_attr "indexed" "no")])
10268
10269 (define_insn "load_toc_aix_di"
10270 [(parallel [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
10271 (unspec:DI [(const_int 0)] UNSPEC_TOC))
10272 (use (reg:DI 2))])]
10273 "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_64BIT"
10274 {
10275 char buf[30];
10276 extern int need_toc_init;
10277 need_toc_init = 1;
10278 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC",
10279 !TARGET_ELF || !TARGET_MINIMAL_TOC);
10280 if (TARGET_ELF)
10281 strcat (buf, "@toc");
10282 operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
10283 operands[2] = gen_rtx_REG (Pmode, 2);
10284 return "ld %0,%1(%2)";
10285 }
10286 [(set_attr "type" "load")
10287 (set_attr "update" "no")
10288 (set_attr "indexed" "no")])
10289
10290 (define_insn "load_toc_v4_pic_si"
10291 [(set (reg:SI LR_REGNO)
10292 (unspec:SI [(const_int 0)] UNSPEC_TOC))]
10293 "DEFAULT_ABI == ABI_V4 && flag_pic == 1 && TARGET_32BIT"
10294 "bl _GLOBAL_OFFSET_TABLE_@local-4"
10295 [(set_attr "type" "branch")])
10296
10297 (define_expand "load_toc_v4_PIC_1"
10298 [(parallel [(set (reg:SI LR_REGNO)
10299 (match_operand:SI 0 "immediate_operand" "s"))
10300 (use (unspec [(match_dup 0)] UNSPEC_TOC))])]
10301 "TARGET_ELF && DEFAULT_ABI == ABI_V4
10302 && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10303 "")
10304
10305 (define_insn "load_toc_v4_PIC_1_normal"
10306 [(set (reg:SI LR_REGNO)
10307 (match_operand:SI 0 "immediate_operand" "s"))
10308 (use (unspec [(match_dup 0)] UNSPEC_TOC))]
10309 "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
10310 && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10311 "bcl 20,31,%0\n%0:"
10312 [(set_attr "type" "branch")
10313 (set_attr "cannot_copy" "yes")])
10314
10315 (define_insn "load_toc_v4_PIC_1_476"
10316 [(set (reg:SI LR_REGNO)
10317 (match_operand:SI 0 "immediate_operand" "s"))
10318 (use (unspec [(match_dup 0)] UNSPEC_TOC))]
10319 "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
10320 && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10321 {
10322 char name[32];
10323 static char templ[32];
10324
10325 get_ppc476_thunk_name (name);
10326 sprintf (templ, "bl %s\n%%0:", name);
10327 return templ;
10328 }
10329 [(set_attr "type" "branch")
10330 (set_attr "cannot_copy" "yes")])
10331
10332 (define_expand "load_toc_v4_PIC_1b"
10333 [(parallel [(set (reg:SI LR_REGNO)
10334 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10335 (label_ref (match_operand 1 ""))]
10336 UNSPEC_TOCPTR))
10337 (match_dup 1)])]
10338 "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10339 "")
10340
10341 (define_insn "load_toc_v4_PIC_1b_normal"
10342 [(set (reg:SI LR_REGNO)
10343 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10344 (label_ref (match_operand 1 "" ""))]
10345 UNSPEC_TOCPTR))
10346 (match_dup 1)]
10347 "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10348 "bcl 20,31,$+8\;.long %0-$"
10349 [(set_attr "type" "branch")
10350 (set_attr "length" "8")])
10351
10352 (define_insn "load_toc_v4_PIC_1b_476"
10353 [(set (reg:SI LR_REGNO)
10354 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10355 (label_ref (match_operand 1 "" ""))]
10356 UNSPEC_TOCPTR))
10357 (match_dup 1)]
10358 "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10359 {
10360 char name[32];
10361 static char templ[32];
10362
10363 get_ppc476_thunk_name (name);
10364 sprintf (templ, "bl %s\;b $+8\;.long %%0-$", name);
10365 return templ;
10366 }
10367 [(set_attr "type" "branch")
10368 (set_attr "length" "16")])
10369
10370 (define_insn "load_toc_v4_PIC_2"
10371 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10372 (mem:SI (plus:SI
10373 (match_operand:SI 1 "gpc_reg_operand" "b")
10374 (const
10375 (minus:SI (match_operand:SI 2 "immediate_operand" "s")
10376 (match_operand:SI 3 "immediate_operand" "s"))))))]
10377 "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10378 "lwz %0,%2-%3(%1)"
10379 [(set_attr "type" "load")])
10380
10381 (define_insn "load_toc_v4_PIC_3b"
10382 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10383 (plus:SI
10384 (match_operand:SI 1 "gpc_reg_operand" "b")
10385 (high:SI
10386 (const
10387 (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
10388 (match_operand:SI 3 "symbol_ref_operand" "s"))))))]
10389 "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
10390 "addis %0,%1,%2-%3@ha")
10391
10392 (define_insn "load_toc_v4_PIC_3c"
10393 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10394 (lo_sum:SI
10395 (match_operand:SI 1 "gpc_reg_operand" "b")
10396 (const
10397 (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
10398 (match_operand:SI 3 "symbol_ref_operand" "s")))))]
10399 "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
10400 "addi %0,%1,%2-%3@l")
10401
10402 ;; If the TOC is shared over a translation unit, as happens with all
10403 ;; the kinds of PIC that we support, we need to restore the TOC
10404 ;; pointer only when jumping over units of translation.
10405 ;; On Darwin, we need to reload the picbase.
10406
10407 (define_expand "builtin_setjmp_receiver"
10408 [(use (label_ref (match_operand 0 "")))]
10409 "(DEFAULT_ABI == ABI_V4 && flag_pic == 1)
10410 || (TARGET_TOC && TARGET_MINIMAL_TOC)
10411 || (DEFAULT_ABI == ABI_DARWIN && flag_pic)"
10412 {
10413 #if TARGET_MACHO
10414 if (DEFAULT_ABI == ABI_DARWIN)
10415 {
10416 rtx picrtx = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME);
10417 rtx picreg = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
10418 rtx tmplabrtx;
10419 char tmplab[20];
10420
10421 crtl->uses_pic_offset_table = 1;
10422 ASM_GENERATE_INTERNAL_LABEL(tmplab, "LSJR",
10423 CODE_LABEL_NUMBER (operands[0]));
10424 tmplabrtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (tmplab));
10425
10426 emit_insn (gen_load_macho_picbase (Pmode, tmplabrtx));
10427 emit_move_insn (picreg, gen_rtx_REG (Pmode, LR_REGNO));
10428 emit_insn (gen_macho_correct_pic (Pmode, picreg, picreg,
10429 picrtx, tmplabrtx));
10430 }
10431 else
10432 #endif
10433 rs6000_emit_load_toc_table (FALSE);
10434 DONE;
10435 })
10436
10437 ;; Largetoc support
10438 (define_insn "*largetoc_high"
10439 [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
10440 (high:DI
10441 (unspec [(match_operand:DI 1 "" "")
10442 (match_operand:DI 2 "gpc_reg_operand" "b")]
10443 UNSPEC_TOCREL)))]
10444 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10445 "addis %0,%2,%1@toc@ha")
10446
10447 (define_insn "*largetoc_high_aix<mode>"
10448 [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
10449 (high:P
10450 (unspec [(match_operand:P 1 "" "")
10451 (match_operand:P 2 "gpc_reg_operand" "b")]
10452 UNSPEC_TOCREL)))]
10453 "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10454 "addis %0,%1@u(%2)")
10455
10456 (define_insn "*largetoc_high_plus"
10457 [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
10458 (high:DI
10459 (plus:DI
10460 (unspec [(match_operand:DI 1 "" "")
10461 (match_operand:DI 2 "gpc_reg_operand" "b")]
10462 UNSPEC_TOCREL)
10463 (match_operand:DI 3 "add_cint_operand" "n"))))]
10464 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10465 "addis %0,%2,%1+%3@toc@ha")
10466
10467 (define_insn "*largetoc_high_plus_aix<mode>"
10468 [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
10469 (high:P
10470 (plus:P
10471 (unspec [(match_operand:P 1 "" "")
10472 (match_operand:P 2 "gpc_reg_operand" "b")]
10473 UNSPEC_TOCREL)
10474 (match_operand:P 3 "add_cint_operand" "n"))))]
10475 "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10476 "addis %0,%1+%3@u(%2)")
10477
10478 (define_insn "*largetoc_low"
10479 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
10480 (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b")
10481 (match_operand:DI 2 "" "")))]
10482 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10483 "addi %0,%1,%2@l")
10484
10485 (define_insn "*largetoc_low_aix<mode>"
10486 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10487 (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
10488 (match_operand:P 2 "" "")))]
10489 "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10490 "la %0,%2@l(%1)")
10491
10492 (define_insn_and_split "*tocref<mode>"
10493 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
10494 (match_operand:P 1 "small_toc_ref" "R"))]
10495 "TARGET_TOC
10496 && legitimate_constant_pool_address_p (operands[1], QImode, false)"
10497 "la %0,%a1"
10498 "&& TARGET_CMODEL != CMODEL_SMALL && reload_completed"
10499 [(set (match_dup 0) (high:P (match_dup 1)))
10500 (set (match_dup 0) (lo_sum:P (match_dup 0) (match_dup 1)))])
10501
10502 ;; Elf specific ways of loading addresses for non-PIC code.
10503 ;; The output of this could be r0, but we make a very strong
10504 ;; preference for a base register because it will usually
10505 ;; be needed there.
10506 (define_insn "elf_high"
10507 [(set (match_operand:SI 0 "gpc_reg_operand" "=b*r")
10508 (high:SI (match_operand 1 "" "")))]
10509 "TARGET_ELF && !TARGET_64BIT && !flag_pic"
10510 "lis %0,%1@ha")
10511
10512 (define_insn "elf_low"
10513 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10514 (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
10515 (match_operand 2 "" "")))]
10516 "TARGET_ELF && !TARGET_64BIT && !flag_pic"
10517 "la %0,%2@l(%1)")
10518
10519 (define_insn "*pltseq_tocsave_<mode>"
10520 [(set (match_operand:P 0 "memory_operand" "=m")
10521 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
10522 (match_operand:P 2 "symbol_ref_operand" "s")
10523 (match_operand:P 3 "" "")]
10524 UNSPEC_PLTSEQ))]
10525 "TARGET_PLTSEQ
10526 && DEFAULT_ABI == ABI_ELFv2"
10527 {
10528 return rs6000_pltseq_template (operands, RS6000_PLTSEQ_TOCSAVE);
10529 })
10530
10531 (define_insn "*pltseq_plt16_ha_<mode>"
10532 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10533 (unspec:P [(match_operand:P 1 "" "")
10534 (match_operand:P 2 "symbol_ref_operand" "s")
10535 (match_operand:P 3 "" "")]
10536 UNSPEC_PLT16_HA))]
10537 "TARGET_PLTSEQ"
10538 {
10539 return rs6000_pltseq_template (operands, RS6000_PLTSEQ_PLT16_HA);
10540 })
10541
10542 (define_insn "*pltseq_plt16_lo_<mode>"
10543 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10544 (unspec_volatile:P [(match_operand:P 1 "gpc_reg_operand" "b")
10545 (match_operand:P 2 "symbol_ref_operand" "s")
10546 (match_operand:P 3 "" "")]
10547 UNSPECV_PLT16_LO))]
10548 "TARGET_PLTSEQ"
10549 {
10550 return rs6000_pltseq_template (operands, RS6000_PLTSEQ_PLT16_LO);
10551 }
10552 [(set_attr "type" "load")])
10553
10554 (define_insn "*pltseq_mtctr_<mode>"
10555 [(set (match_operand:P 0 "register_operand" "=c")
10556 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "r")
10557 (match_operand:P 2 "symbol_ref_operand" "s")
10558 (match_operand:P 3 "" "")]
10559 UNSPEC_PLTSEQ))]
10560 "TARGET_PLTSEQ"
10561 {
10562 return rs6000_pltseq_template (operands, RS6000_PLTSEQ_MTCTR);
10563 })
10564
10565 (define_insn "*pltseq_plt_pcrel<mode>"
10566 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10567 (unspec_volatile:P [(match_operand:P 1 "" "")
10568 (match_operand:P 2 "symbol_ref_operand" "s")
10569 (match_operand:P 3 "" "")]
10570 UNSPECV_PLT_PCREL))]
10571 "HAVE_AS_PLTSEQ && TARGET_ELF
10572 && rs6000_pcrel_p ()"
10573 {
10574 return rs6000_pltseq_template (operands, RS6000_PLTSEQ_PLT_PCREL34);
10575 }
10576 [(set_attr "type" "load")
10577 (set_attr "length" "12")])
10578 \f
10579 ;; Call and call_value insns
10580 ;; For the purposes of expanding calls, Darwin is very similar to SYSV.
10581 (define_expand "call"
10582 [(parallel [(call (mem:SI (match_operand 0 "address_operand"))
10583 (match_operand 1 ""))
10584 (use (match_operand 2 ""))
10585 (clobber (reg:SI LR_REGNO))])]
10586 ""
10587 {
10588 #if TARGET_MACHO
10589 if (MACHOPIC_INDIRECT)
10590 operands[0] = machopic_indirect_call_target (operands[0]);
10591 #endif
10592
10593 gcc_assert (MEM_P (operands[0]));
10594
10595 operands[0] = XEXP (operands[0], 0);
10596
10597 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10598 rs6000_call_aix (NULL_RTX, operands[0], operands[1], operands[2]);
10599 else if (DEFAULT_ABI == ABI_V4)
10600 rs6000_call_sysv (NULL_RTX, operands[0], operands[1], operands[2]);
10601 else if (DEFAULT_ABI == ABI_DARWIN)
10602 rs6000_call_darwin (NULL_RTX, operands[0], operands[1], operands[2]);
10603 else
10604 gcc_unreachable ();
10605
10606 DONE;
10607 })
10608
10609 (define_expand "call_value"
10610 [(parallel [(set (match_operand 0 "")
10611 (call (mem:SI (match_operand 1 "address_operand"))
10612 (match_operand 2 "")))
10613 (use (match_operand 3 ""))
10614 (clobber (reg:SI LR_REGNO))])]
10615 ""
10616 {
10617 #if TARGET_MACHO
10618 if (MACHOPIC_INDIRECT)
10619 operands[1] = machopic_indirect_call_target (operands[1]);
10620 #endif
10621
10622 gcc_assert (MEM_P (operands[1]));
10623
10624 operands[1] = XEXP (operands[1], 0);
10625
10626 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10627 rs6000_call_aix (operands[0], operands[1], operands[2], operands[3]);
10628 else if (DEFAULT_ABI == ABI_V4)
10629 rs6000_call_sysv (operands[0], operands[1], operands[2], operands[3]);
10630 else if (DEFAULT_ABI == ABI_DARWIN)
10631 rs6000_call_darwin (operands[0], operands[1], operands[2], operands[3]);
10632 else
10633 gcc_unreachable ();
10634
10635 DONE;
10636 })
10637
10638 ;; Call to function in current module. No TOC pointer reload needed.
10639 ;; Operand2 is nonzero if we are using the V.4 calling sequence and
10640 ;; either the function was not prototyped, or it was prototyped as a
10641 ;; variable argument function. It is > 0 if FP registers were passed
10642 ;; and < 0 if they were not.
10643
10644 (define_insn "*call_local<mode>"
10645 [(call (mem:SI (match_operand:P 0 "current_file_function_operand" "s,s"))
10646 (match_operand 1))
10647 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10648 (clobber (reg:P LR_REGNO))]
10649 "(INTVAL (operands[2]) & CALL_LONG) == 0"
10650 {
10651 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10652 output_asm_insn ("crxor 6,6,6", operands);
10653
10654 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10655 output_asm_insn ("creqv 6,6,6", operands);
10656
10657 if (rs6000_pcrel_p ())
10658 return "bl %z0@notoc";
10659 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z0@local" : "bl %z0";
10660 }
10661 [(set_attr "type" "branch")
10662 (set_attr "length" "4,8")])
10663
10664 (define_insn "*call_value_local<mode>"
10665 [(set (match_operand 0 "" "")
10666 (call (mem:SI (match_operand:P 1 "current_file_function_operand" "s,s"))
10667 (match_operand 2)))
10668 (use (match_operand:SI 3 "immediate_operand" "O,n"))
10669 (clobber (reg:P LR_REGNO))]
10670 "(INTVAL (operands[3]) & CALL_LONG) == 0"
10671 {
10672 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10673 output_asm_insn ("crxor 6,6,6", operands);
10674
10675 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10676 output_asm_insn ("creqv 6,6,6", operands);
10677
10678 if (rs6000_pcrel_p ())
10679 return "bl %z1@notoc";
10680 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z1@local" : "bl %z1";
10681 }
10682 [(set_attr "type" "branch")
10683 (set_attr "length" "4,8")])
10684
10685
10686 ;; A function pointer under System V is just a normal pointer
10687 ;; operands[0] is the function pointer
10688 ;; operands[1] is the tls call arg
10689 ;; operands[2] is the value FUNCTION_ARG returns for the VOID argument
10690 ;; which indicates how to set cr1
10691
10692 (define_insn "*call_indirect_nonlocal_sysv<mode>"
10693 [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X"))
10694 (match_operand 1))
10695 (use (match_operand:SI 2 "immediate_operand" "n,n,n"))
10696 (clobber (reg:P LR_REGNO))]
10697 "DEFAULT_ABI == ABI_V4
10698 || DEFAULT_ABI == ABI_DARWIN"
10699 {
10700 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10701 output_asm_insn ("crxor 6,6,6", operands);
10702
10703 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10704 output_asm_insn ("creqv 6,6,6", operands);
10705
10706 return rs6000_indirect_call_template (operands, 0);
10707 }
10708 [(set_attr "type" "jmpreg")
10709 (set (attr "length")
10710 (cond [(and (and (match_test "!rs6000_speculate_indirect_jumps")
10711 (match_test "which_alternative != 1"))
10712 (match_test "(INTVAL (operands[2]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
10713 (const_string "12")
10714 (ior (and (match_test "!rs6000_speculate_indirect_jumps")
10715 (match_test "which_alternative != 1"))
10716 (match_test "(INTVAL (operands[2]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
10717 (const_string "8")]
10718 (const_string "4")))])
10719
10720 (define_insn "*call_nonlocal_sysv<mode>"
10721 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
10722 (match_operand 1))
10723 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10724 (clobber (reg:P LR_REGNO))]
10725 "(DEFAULT_ABI == ABI_DARWIN
10726 || (DEFAULT_ABI == ABI_V4
10727 && (INTVAL (operands[2]) & CALL_LONG) == 0))"
10728 {
10729 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10730 output_asm_insn ("crxor 6,6,6", operands);
10731
10732 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10733 output_asm_insn ("creqv 6,6,6", operands);
10734
10735 return rs6000_call_template (operands, 0);
10736 }
10737 [(set_attr "type" "branch,branch")
10738 (set_attr "length" "4,8")])
10739
10740 (define_insn "*call_nonlocal_sysv_secure<mode>"
10741 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
10742 (match_operand 1))
10743 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10744 (use (match_operand:SI 3 "register_operand" "r,r"))
10745 (clobber (reg:P LR_REGNO))]
10746 "(DEFAULT_ABI == ABI_V4
10747 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0])
10748 && (INTVAL (operands[2]) & CALL_LONG) == 0)"
10749 {
10750 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10751 output_asm_insn ("crxor 6,6,6", operands);
10752
10753 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10754 output_asm_insn ("creqv 6,6,6", operands);
10755
10756 return rs6000_call_template (operands, 0);
10757 }
10758 [(set_attr "type" "branch,branch")
10759 (set_attr "length" "4,8")])
10760
10761 (define_insn "*call_value_indirect_nonlocal_sysv<mode>"
10762 [(set (match_operand 0 "" "")
10763 (call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X"))
10764 (match_operand:P 2 "unspec_tls" "")))
10765 (use (match_operand:SI 3 "immediate_operand" "n,n,n"))
10766 (clobber (reg:P LR_REGNO))]
10767 "DEFAULT_ABI == ABI_V4
10768 || DEFAULT_ABI == ABI_DARWIN"
10769 {
10770 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10771 output_asm_insn ("crxor 6,6,6", operands);
10772
10773 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10774 output_asm_insn ("creqv 6,6,6", operands);
10775
10776 return rs6000_indirect_call_template (operands, 1);
10777 }
10778 [(set_attr "type" "jmpreg")
10779 (set (attr "length")
10780 (plus
10781 (if_then_else (match_test "IS_V4_FP_ARGS (operands[3])")
10782 (const_int 4)
10783 (const_int 0))
10784 (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
10785 (match_test "which_alternative != 1"))
10786 (const_int 8)
10787 (const_int 4))))])
10788
10789 (define_insn "*call_value_nonlocal_sysv<mode>"
10790 [(set (match_operand 0 "" "")
10791 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s"))
10792 (match_operand:P 2 "unspec_tls" "")))
10793 (use (match_operand:SI 3 "immediate_operand" "n"))
10794 (clobber (reg:P LR_REGNO))]
10795 "(DEFAULT_ABI == ABI_DARWIN
10796 || (DEFAULT_ABI == ABI_V4
10797 && (INTVAL (operands[3]) & CALL_LONG) == 0))"
10798 {
10799 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10800 output_asm_insn ("crxor 6,6,6", operands);
10801
10802 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10803 output_asm_insn ("creqv 6,6,6", operands);
10804
10805 return rs6000_call_template (operands, 1);
10806 }
10807 [(set_attr "type" "branch")
10808 (set (attr "length")
10809 (if_then_else (match_test "IS_V4_FP_ARGS (operands[3])")
10810 (const_int 8)
10811 (const_int 4)))])
10812
10813 (define_insn "*call_value_nonlocal_sysv_secure<mode>"
10814 [(set (match_operand 0 "" "")
10815 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s"))
10816 (match_operand:P 2 "unspec_tls" "")))
10817 (use (match_operand:SI 3 "immediate_operand" "n"))
10818 (use (match_operand:SI 4 "register_operand" "r"))
10819 (clobber (reg:P LR_REGNO))]
10820 "(DEFAULT_ABI == ABI_V4
10821 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1])
10822 && (INTVAL (operands[3]) & CALL_LONG) == 0)"
10823 {
10824 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10825 output_asm_insn ("crxor 6,6,6", operands);
10826
10827 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10828 output_asm_insn ("creqv 6,6,6", operands);
10829
10830 return rs6000_call_template (operands, 1);
10831 }
10832 [(set_attr "type" "branch")
10833 (set (attr "length")
10834 (if_then_else (match_test "IS_V4_FP_ARGS (operands[3])")
10835 (const_int 8)
10836 (const_int 4)))])
10837
10838 ;; Call to AIX abi function which may be in another module.
10839 ;; Restore the TOC pointer (r2) after the call.
10840
10841 (define_insn "*call_nonlocal_aix<mode>"
10842 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s"))
10843 (match_operand 1))
10844 (use (match_operand:SI 2 "immediate_operand" "n"))
10845 (clobber (reg:P LR_REGNO))]
10846 "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10847 && (INTVAL (operands[2]) & CALL_LONG) == 0"
10848 {
10849 return rs6000_call_template (operands, 0);
10850 }
10851 [(set_attr "type" "branch")
10852 (set (attr "length")
10853 (if_then_else (match_test "rs6000_pcrel_p ()")
10854 (const_int 4)
10855 (const_int 8)))])
10856
10857 (define_insn "*call_value_nonlocal_aix<mode>"
10858 [(set (match_operand 0 "" "")
10859 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s"))
10860 (match_operand:P 2 "unspec_tls" "")))
10861 (use (match_operand:SI 3 "immediate_operand" "n"))
10862 (clobber (reg:P LR_REGNO))]
10863 "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10864 && (INTVAL (operands[3]) & CALL_LONG) == 0"
10865 {
10866 return rs6000_call_template (operands, 1);
10867 }
10868 [(set_attr "type" "branch")
10869 (set (attr "length")
10870 (if_then_else (match_test "rs6000_pcrel_p ()")
10871 (const_int 4)
10872 (const_int 8)))])
10873
10874 ;; Call to indirect functions with the AIX abi using a 3 word descriptor.
10875 ;; Operand0 is the addresss of the function to call
10876 ;; Operand3 is the location in the function descriptor to load r2 from
10877 ;; Operand4 is the offset of the stack location holding the current TOC pointer
10878
10879 (define_insn "*call_indirect_aix<mode>"
10880 [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X"))
10881 (match_operand 1))
10882 (use (match_operand:SI 2 "immediate_operand" "n,n,n"))
10883 (use (match_operand:P 3 "memory_operand" "<ptrm>,<ptrm>,<ptrm>"))
10884 (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 4 "const_int_operand" "n,n,n")] UNSPEC_TOCSLOT))
10885 (clobber (reg:P LR_REGNO))]
10886 "DEFAULT_ABI == ABI_AIX"
10887 {
10888 return rs6000_indirect_call_template (operands, 0);
10889 }
10890 [(set_attr "type" "jmpreg")
10891 (set (attr "length")
10892 (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
10893 (match_test "which_alternative != 1"))
10894 (const_string "16")
10895 (const_string "12")))])
10896
10897 (define_insn "*call_value_indirect_aix<mode>"
10898 [(set (match_operand 0 "" "")
10899 (call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X"))
10900 (match_operand:P 2 "unspec_tls" "")))
10901 (use (match_operand:SI 3 "immediate_operand" "n,n,n"))
10902 (use (match_operand:P 4 "memory_operand" "<ptrm>,<ptrm>,<ptrm>"))
10903 (set (reg:P TOC_REGNUM)
10904 (unspec:P [(match_operand:P 5 "const_int_operand" "n,n,n")]
10905 UNSPEC_TOCSLOT))
10906 (clobber (reg:P LR_REGNO))]
10907 "DEFAULT_ABI == ABI_AIX"
10908 {
10909 return rs6000_indirect_call_template (operands, 1);
10910 }
10911 [(set_attr "type" "jmpreg")
10912 (set (attr "length")
10913 (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
10914 (match_test "which_alternative != 1"))
10915 (const_string "16")
10916 (const_string "12")))])
10917
10918 ;; Call to indirect functions with the ELFv2 ABI.
10919 ;; Operand0 is the addresss of the function to call
10920 ;; Operand3 is the offset of the stack location holding the current TOC pointer
10921
10922 (define_insn "*call_indirect_elfv2<mode>"
10923 [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X"))
10924 (match_operand 1))
10925 (use (match_operand:SI 2 "immediate_operand" "n,n,n"))
10926 (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 3 "const_int_operand" "n,n,n")] UNSPEC_TOCSLOT))
10927 (clobber (reg:P LR_REGNO))]
10928 "DEFAULT_ABI == ABI_ELFv2"
10929 {
10930 return rs6000_indirect_call_template (operands, 0);
10931 }
10932 [(set_attr "type" "jmpreg")
10933 (set (attr "length")
10934 (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
10935 (match_test "which_alternative != 1"))
10936 (const_string "12")
10937 (const_string "8")))])
10938
10939 (define_insn "*call_indirect_pcrel<mode>"
10940 [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X"))
10941 (match_operand 1))
10942 (use (match_operand:SI 2 "immediate_operand" "n,n,n"))
10943 (clobber (reg:P LR_REGNO))]
10944 "rs6000_pcrel_p ()"
10945 {
10946 return rs6000_indirect_call_template (operands, 0);
10947 }
10948 [(set_attr "type" "jmpreg")
10949 (set (attr "length")
10950 (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
10951 (match_test "which_alternative != 1"))
10952 (const_string "8")
10953 (const_string "4")))])
10954
10955 (define_insn "*call_value_indirect_elfv2<mode>"
10956 [(set (match_operand 0 "" "")
10957 (call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X"))
10958 (match_operand:P 2 "unspec_tls" "")))
10959 (use (match_operand:SI 3 "immediate_operand" "n,n,n"))
10960 (set (reg:P TOC_REGNUM)
10961 (unspec:P [(match_operand:P 4 "const_int_operand" "n,n,n")]
10962 UNSPEC_TOCSLOT))
10963 (clobber (reg:P LR_REGNO))]
10964 "DEFAULT_ABI == ABI_ELFv2"
10965 {
10966 return rs6000_indirect_call_template (operands, 1);
10967 }
10968 [(set_attr "type" "jmpreg")
10969 (set (attr "length")
10970 (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
10971 (match_test "which_alternative != 1"))
10972 (const_string "12")
10973 (const_string "8")))])
10974
10975 (define_insn "*call_value_indirect_pcrel<mode>"
10976 [(set (match_operand 0 "" "")
10977 (call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X"))
10978 (match_operand:P 2 "unspec_tls" "")))
10979 (use (match_operand:SI 3 "immediate_operand" "n,n,n"))
10980 (clobber (reg:P LR_REGNO))]
10981 "rs6000_pcrel_p ()"
10982 {
10983 return rs6000_indirect_call_template (operands, 1);
10984 }
10985 [(set_attr "type" "jmpreg")
10986 (set (attr "length")
10987 (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
10988 (match_test "which_alternative != 1"))
10989 (const_string "8")
10990 (const_string "4")))])
10991
10992 ;; Call subroutine returning any type.
10993 (define_expand "untyped_call"
10994 [(parallel [(call (match_operand 0 "")
10995 (const_int 0))
10996 (match_operand 1 "")
10997 (match_operand 2 "")])]
10998 ""
10999 {
11000 int i;
11001
11002 emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
11003
11004 for (int i = 0; i < XVECLEN (operands[2], 0); i++)
11005 emit_clobber (SET_SRC (XVECEXP (operands[2], 0, i)));
11006 emit_insn (gen_blockage ());
11007
11008 for (i = 0; i < XVECLEN (operands[2], 0); i++)
11009 {
11010 rtx set = XVECEXP (operands[2], 0, i);
11011 emit_move_insn (SET_DEST (set), SET_SRC (set));
11012 }
11013
11014 /* The optimizer does not know that the call sets the function value
11015 registers we stored in the result block. We avoid problems by
11016 claiming that all hard registers are used and clobbered at this
11017 point. */
11018 emit_insn (gen_blockage ());
11019
11020 DONE;
11021 })
11022
11023 ;; sibling call patterns
11024 (define_expand "sibcall"
11025 [(parallel [(call (mem:SI (match_operand 0 "address_operand"))
11026 (match_operand 1 ""))
11027 (use (match_operand 2 ""))
11028 (simple_return)])]
11029 ""
11030 {
11031 #if TARGET_MACHO
11032 if (MACHOPIC_INDIRECT)
11033 operands[0] = machopic_indirect_call_target (operands[0]);
11034 #endif
11035
11036 gcc_assert (MEM_P (operands[0]));
11037 gcc_assert (CONST_INT_P (operands[1]));
11038
11039 operands[0] = XEXP (operands[0], 0);
11040
11041 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
11042 rs6000_sibcall_aix (NULL_RTX, operands[0], operands[1], operands[2]);
11043 else if (DEFAULT_ABI == ABI_V4)
11044 rs6000_sibcall_sysv (NULL_RTX, operands[0], operands[1], operands[2]);
11045 else if (DEFAULT_ABI == ABI_DARWIN)
11046 rs6000_sibcall_darwin (NULL_RTX, operands[0], operands[1], operands[2]);
11047 else
11048 gcc_unreachable ();
11049
11050 DONE;
11051 })
11052
11053 (define_expand "sibcall_value"
11054 [(parallel [(set (match_operand 0 "register_operand")
11055 (call (mem:SI (match_operand 1 "address_operand"))
11056 (match_operand 2 "")))
11057 (use (match_operand 3 ""))
11058 (simple_return)])]
11059 ""
11060 {
11061 #if TARGET_MACHO
11062 if (MACHOPIC_INDIRECT)
11063 operands[1] = machopic_indirect_call_target (operands[1]);
11064 #endif
11065
11066 gcc_assert (MEM_P (operands[1]));
11067 gcc_assert (CONST_INT_P (operands[2]));
11068
11069 operands[1] = XEXP (operands[1], 0);
11070
11071 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
11072 rs6000_sibcall_aix (operands[0], operands[1], operands[2], operands[3]);
11073 else if (DEFAULT_ABI == ABI_V4)
11074 rs6000_sibcall_sysv (operands[0], operands[1], operands[2], operands[3]);
11075 else if (DEFAULT_ABI == ABI_DARWIN)
11076 rs6000_sibcall_darwin (operands[0], operands[1], operands[2], operands[3]);
11077 else
11078 gcc_unreachable ();
11079
11080 DONE;
11081 })
11082
11083 (define_insn "*sibcall_local<mode>"
11084 [(call (mem:SI (match_operand:P 0 "current_file_function_operand" "s,s"))
11085 (match_operand 1))
11086 (use (match_operand:SI 2 "immediate_operand" "O,n"))
11087 (simple_return)]
11088 "(INTVAL (operands[2]) & CALL_LONG) == 0"
11089 {
11090 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
11091 output_asm_insn ("crxor 6,6,6", operands);
11092
11093 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
11094 output_asm_insn ("creqv 6,6,6", operands);
11095
11096 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z0@local" : "b %z0";
11097 }
11098 [(set_attr "type" "branch")
11099 (set_attr "length" "4,8")])
11100
11101 (define_insn "*sibcall_value_local<mode>"
11102 [(set (match_operand 0 "" "")
11103 (call (mem:SI (match_operand:P 1 "current_file_function_operand" "s,s"))
11104 (match_operand 2)))
11105 (use (match_operand:SI 3 "immediate_operand" "O,n"))
11106 (simple_return)]
11107 "(INTVAL (operands[3]) & CALL_LONG) == 0"
11108 {
11109 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11110 output_asm_insn ("crxor 6,6,6", operands);
11111
11112 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11113 output_asm_insn ("creqv 6,6,6", operands);
11114
11115 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z1@local" : "b %z1";
11116 }
11117 [(set_attr "type" "branch")
11118 (set_attr "length" "4,8")])
11119
11120 (define_insn "*sibcall_indirect_nonlocal_sysv<mode>"
11121 [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X"))
11122 (match_operand 1))
11123 (use (match_operand:SI 2 "immediate_operand" "n,n,n"))
11124 (simple_return)]
11125 "DEFAULT_ABI == ABI_V4
11126 || DEFAULT_ABI == ABI_DARWIN"
11127 {
11128 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
11129 output_asm_insn ("crxor 6,6,6", operands);
11130
11131 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
11132 output_asm_insn ("creqv 6,6,6", operands);
11133
11134 return rs6000_indirect_sibcall_template (operands, 0);
11135 }
11136 [(set_attr "type" "jmpreg")
11137 (set (attr "length")
11138 (cond [(and (and (match_test "!rs6000_speculate_indirect_jumps")
11139 (match_test "which_alternative != 1"))
11140 (match_test "(INTVAL (operands[2]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
11141 (const_string "12")
11142 (ior (and (match_test "!rs6000_speculate_indirect_jumps")
11143 (match_test "which_alternative != 1"))
11144 (match_test "(INTVAL (operands[2]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
11145 (const_string "8")]
11146 (const_string "4")))])
11147
11148 (define_insn "*sibcall_nonlocal_sysv<mode>"
11149 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
11150 (match_operand 1))
11151 (use (match_operand 2 "immediate_operand" "O,n"))
11152 (simple_return)]
11153 "(DEFAULT_ABI == ABI_DARWIN
11154 || DEFAULT_ABI == ABI_V4)
11155 && (INTVAL (operands[2]) & CALL_LONG) == 0"
11156 {
11157 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
11158 output_asm_insn ("crxor 6,6,6", operands);
11159
11160 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
11161 output_asm_insn ("creqv 6,6,6", operands);
11162
11163 return rs6000_sibcall_template (operands, 0);
11164 }
11165 [(set_attr "type" "branch")
11166 (set_attr "length" "4,8")])
11167
11168 (define_insn "*sibcall_value_indirect_nonlocal_sysv<mode>"
11169 [(set (match_operand 0 "" "")
11170 (call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X"))
11171 (match_operand 2)))
11172 (use (match_operand:SI 3 "immediate_operand" "n,n,n"))
11173 (simple_return)]
11174 "DEFAULT_ABI == ABI_V4
11175 || DEFAULT_ABI == ABI_DARWIN"
11176 {
11177 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11178 output_asm_insn ("crxor 6,6,6", operands);
11179
11180 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11181 output_asm_insn ("creqv 6,6,6", operands);
11182
11183 return rs6000_indirect_sibcall_template (operands, 1);
11184 }
11185 [(set_attr "type" "jmpreg")
11186 (set (attr "length")
11187 (cond [(and (and (match_test "!rs6000_speculate_indirect_jumps")
11188 (match_test "which_alternative != 1"))
11189 (match_test "(INTVAL (operands[3]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
11190 (const_string "12")
11191 (ior (and (match_test "!rs6000_speculate_indirect_jumps")
11192 (match_test "which_alternative != 1"))
11193 (match_test "(INTVAL (operands[3]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
11194 (const_string "8")]
11195 (const_string "4")))])
11196
11197 (define_insn "*sibcall_value_nonlocal_sysv<mode>"
11198 [(set (match_operand 0 "" "")
11199 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
11200 (match_operand 2)))
11201 (use (match_operand:SI 3 "immediate_operand" "O,n"))
11202 (simple_return)]
11203 "(DEFAULT_ABI == ABI_DARWIN
11204 || DEFAULT_ABI == ABI_V4)
11205 && (INTVAL (operands[3]) & CALL_LONG) == 0"
11206 {
11207 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11208 output_asm_insn ("crxor 6,6,6", operands);
11209
11210 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11211 output_asm_insn ("creqv 6,6,6", operands);
11212
11213 return rs6000_sibcall_template (operands, 1);
11214 }
11215 [(set_attr "type" "branch")
11216 (set_attr "length" "4,8")])
11217
11218 ;; AIX ABI sibling call patterns.
11219
11220 (define_insn "*sibcall_aix<mode>"
11221 [(call (mem:SI (match_operand:P 0 "call_operand" "s,c"))
11222 (match_operand 1))
11223 (simple_return)]
11224 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11225 {
11226 if (which_alternative == 0)
11227 return rs6000_sibcall_template (operands, 0);
11228 else
11229 return "b%T0";
11230 }
11231 [(set_attr "type" "branch")])
11232
11233 (define_insn "*sibcall_value_aix<mode>"
11234 [(set (match_operand 0 "" "")
11235 (call (mem:SI (match_operand:P 1 "call_operand" "s,c"))
11236 (match_operand 2)))
11237 (simple_return)]
11238 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11239 {
11240 if (which_alternative == 0)
11241 return rs6000_sibcall_template (operands, 1);
11242 else
11243 return "b%T1";
11244 }
11245 [(set_attr "type" "branch")])
11246
11247 (define_expand "sibcall_epilogue"
11248 [(use (const_int 0))]
11249 ""
11250 {
11251 if (!TARGET_SCHED_PROLOG)
11252 emit_insn (gen_blockage ());
11253 rs6000_emit_epilogue (EPILOGUE_TYPE_SIBCALL);
11254 DONE;
11255 })
11256
11257 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11258 ;; all of memory. This blocks insns from being moved across this point.
11259
11260 (define_insn "blockage"
11261 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCK)]
11262 ""
11263 ""
11264 [(set_attr "length" "0")])
11265
11266 (define_expand "probe_stack_address"
11267 [(use (match_operand 0 "address_operand"))]
11268 ""
11269 {
11270 operands[0] = gen_rtx_MEM (Pmode, operands[0]);
11271 MEM_VOLATILE_P (operands[0]) = 1;
11272
11273 if (TARGET_64BIT)
11274 emit_insn (gen_probe_stack_di (operands[0]));
11275 else
11276 emit_insn (gen_probe_stack_si (operands[0]));
11277 DONE;
11278 })
11279
11280 (define_insn "probe_stack_<mode>"
11281 [(set (match_operand:P 0 "memory_operand" "=m")
11282 (unspec:P [(const_int 0)] UNSPEC_PROBE_STACK))]
11283 ""
11284 {
11285 operands[1] = gen_rtx_REG (Pmode, 0);
11286 return "st<wd>%U0%X0 %1,%0";
11287 }
11288 [(set_attr "type" "store")
11289 (set (attr "update")
11290 (if_then_else (match_operand 0 "update_address_mem")
11291 (const_string "yes")
11292 (const_string "no")))
11293 (set (attr "indexed")
11294 (if_then_else (match_operand 0 "indexed_address_mem")
11295 (const_string "yes")
11296 (const_string "no")))])
11297
11298 (define_insn "probe_stack_range<P:mode>"
11299 [(set (match_operand:P 0 "register_operand" "=&r")
11300 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
11301 (match_operand:P 2 "register_operand" "r")
11302 (match_operand:P 3 "register_operand" "r")]
11303 UNSPECV_PROBE_STACK_RANGE))]
11304 ""
11305 "* return output_probe_stack_range (operands[0], operands[2], operands[3]);"
11306 [(set_attr "type" "three")])
11307 \f
11308 ;; Compare insns are next. Note that the RS/6000 has two types of compares,
11309 ;; signed & unsigned, and one type of branch.
11310 ;;
11311 ;; Start with the DEFINE_EXPANDs to generate the rtl for compares, scc
11312 ;; insns, and branches.
11313
11314 (define_expand "cbranch<mode>4"
11315 [(use (match_operator 0 "comparison_operator"
11316 [(match_operand:GPR 1 "gpc_reg_operand")
11317 (match_operand:GPR 2 "reg_or_short_operand")]))
11318 (use (match_operand 3))]
11319 ""
11320 {
11321 /* Take care of the possibility that operands[2] might be negative but
11322 this might be a logical operation. That insn doesn't exist. */
11323 if (CONST_INT_P (operands[2])
11324 && INTVAL (operands[2]) < 0)
11325 {
11326 operands[2] = force_reg (<MODE>mode, operands[2]);
11327 operands[0] = gen_rtx_fmt_ee (GET_CODE (operands[0]),
11328 GET_MODE (operands[0]),
11329 operands[1], operands[2]);
11330 }
11331
11332 rs6000_emit_cbranch (<MODE>mode, operands);
11333 DONE;
11334 })
11335
11336 (define_expand "cbranch<mode>4"
11337 [(use (match_operator 0 "comparison_operator"
11338 [(match_operand:FP 1 "gpc_reg_operand")
11339 (match_operand:FP 2 "gpc_reg_operand")]))
11340 (use (match_operand 3))]
11341 ""
11342 {
11343 rs6000_emit_cbranch (<MODE>mode, operands);
11344 DONE;
11345 })
11346
11347 (define_expand "cstore<mode>4_signed"
11348 [(use (match_operator 1 "signed_comparison_operator"
11349 [(match_operand:P 2 "gpc_reg_operand")
11350 (match_operand:P 3 "gpc_reg_operand")]))
11351 (clobber (match_operand:P 0 "gpc_reg_operand"))]
11352 ""
11353 {
11354 enum rtx_code cond_code = GET_CODE (operands[1]);
11355
11356 rtx op0 = operands[0];
11357 rtx op1 = operands[2];
11358 rtx op2 = operands[3];
11359
11360 if (cond_code == GE || cond_code == LT)
11361 {
11362 cond_code = swap_condition (cond_code);
11363 std::swap (op1, op2);
11364 }
11365
11366 rtx tmp1 = gen_reg_rtx (<MODE>mode);
11367 rtx tmp2 = gen_reg_rtx (<MODE>mode);
11368 rtx tmp3 = gen_reg_rtx (<MODE>mode);
11369
11370 int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11371 emit_insn (gen_lshr<mode>3 (tmp1, op1, GEN_INT (sh)));
11372 emit_insn (gen_ashr<mode>3 (tmp2, op2, GEN_INT (sh)));
11373
11374 emit_insn (gen_subf<mode>3_carry (tmp3, op1, op2));
11375
11376 if (cond_code == LE)
11377 emit_insn (gen_add<mode>3_carry_in (op0, tmp1, tmp2));
11378 else
11379 {
11380 rtx tmp4 = gen_reg_rtx (<MODE>mode);
11381 emit_insn (gen_add<mode>3_carry_in (tmp4, tmp1, tmp2));
11382 emit_insn (gen_xor<mode>3 (op0, tmp4, const1_rtx));
11383 }
11384
11385 DONE;
11386 })
11387
11388 (define_expand "cstore<mode>4_unsigned"
11389 [(use (match_operator 1 "unsigned_comparison_operator"
11390 [(match_operand:P 2 "gpc_reg_operand")
11391 (match_operand:P 3 "reg_or_short_operand")]))
11392 (clobber (match_operand:P 0 "gpc_reg_operand"))]
11393 ""
11394 {
11395 enum rtx_code cond_code = GET_CODE (operands[1]);
11396
11397 rtx op0 = operands[0];
11398 rtx op1 = operands[2];
11399 rtx op2 = operands[3];
11400
11401 if (cond_code == GEU || cond_code == LTU)
11402 {
11403 cond_code = swap_condition (cond_code);
11404 std::swap (op1, op2);
11405 }
11406
11407 if (!gpc_reg_operand (op1, <MODE>mode))
11408 op1 = force_reg (<MODE>mode, op1);
11409 if (!reg_or_short_operand (op2, <MODE>mode))
11410 op2 = force_reg (<MODE>mode, op2);
11411
11412 rtx tmp = gen_reg_rtx (<MODE>mode);
11413 rtx tmp2 = gen_reg_rtx (<MODE>mode);
11414
11415 emit_insn (gen_subf<mode>3_carry (tmp, op1, op2));
11416 emit_insn (gen_subf<mode>3_carry_in_xx (tmp2));
11417
11418 if (cond_code == LEU)
11419 emit_insn (gen_add<mode>3 (op0, tmp2, const1_rtx));
11420 else
11421 emit_insn (gen_neg<mode>2 (op0, tmp2));
11422
11423 DONE;
11424 })
11425
11426 (define_expand "cstore_si_as_di"
11427 [(use (match_operator 1 "unsigned_comparison_operator"
11428 [(match_operand:SI 2 "gpc_reg_operand")
11429 (match_operand:SI 3 "reg_or_short_operand")]))
11430 (clobber (match_operand:SI 0 "gpc_reg_operand"))]
11431 ""
11432 {
11433 int uns_flag = unsigned_comparison_operator (operands[1], VOIDmode) ? 1 : 0;
11434 enum rtx_code cond_code = signed_condition (GET_CODE (operands[1]));
11435
11436 operands[2] = force_reg (SImode, operands[2]);
11437 operands[3] = force_reg (SImode, operands[3]);
11438 rtx op1 = gen_reg_rtx (DImode);
11439 rtx op2 = gen_reg_rtx (DImode);
11440 convert_move (op1, operands[2], uns_flag);
11441 convert_move (op2, operands[3], uns_flag);
11442
11443 if (cond_code == GT || cond_code == LE)
11444 {
11445 cond_code = swap_condition (cond_code);
11446 std::swap (op1, op2);
11447 }
11448
11449 rtx tmp = gen_reg_rtx (DImode);
11450 rtx tmp2 = gen_reg_rtx (DImode);
11451 emit_insn (gen_subdi3 (tmp, op1, op2));
11452 emit_insn (gen_lshrdi3 (tmp2, tmp, GEN_INT (63)));
11453
11454 rtx tmp3;
11455 switch (cond_code)
11456 {
11457 default:
11458 gcc_unreachable ();
11459 case LT:
11460 tmp3 = tmp2;
11461 break;
11462 case GE:
11463 tmp3 = gen_reg_rtx (DImode);
11464 emit_insn (gen_xordi3 (tmp3, tmp2, const1_rtx));
11465 break;
11466 }
11467
11468 convert_move (operands[0], tmp3, 1);
11469
11470 DONE;
11471 })
11472
11473 (define_expand "cstore<mode>4_signed_imm"
11474 [(use (match_operator 1 "signed_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 == GE || cond_code == GT)
11489 {
11490 cond_code = reverse_condition (cond_code);
11491 invert = true;
11492 }
11493
11494 if (cond_code == LE)
11495 val++;
11496
11497 rtx tmp = gen_reg_rtx (<MODE>mode);
11498 emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
11499 rtx x = gen_reg_rtx (<MODE>mode);
11500 if (val < 0)
11501 emit_insn (gen_and<mode>3 (x, op1, tmp));
11502 else
11503 emit_insn (gen_ior<mode>3 (x, op1, tmp));
11504
11505 if (invert)
11506 {
11507 rtx tmp = gen_reg_rtx (<MODE>mode);
11508 emit_insn (gen_one_cmpl<mode>2 (tmp, x));
11509 x = tmp;
11510 }
11511
11512 int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11513 emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
11514
11515 DONE;
11516 })
11517
11518 (define_expand "cstore<mode>4_unsigned_imm"
11519 [(use (match_operator 1 "unsigned_comparison_operator"
11520 [(match_operand:GPR 2 "gpc_reg_operand")
11521 (match_operand:GPR 3 "immediate_operand")]))
11522 (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11523 ""
11524 {
11525 bool invert = false;
11526
11527 enum rtx_code cond_code = GET_CODE (operands[1]);
11528
11529 rtx op0 = operands[0];
11530 rtx op1 = operands[2];
11531 HOST_WIDE_INT val = INTVAL (operands[3]);
11532
11533 if (cond_code == GEU || cond_code == GTU)
11534 {
11535 cond_code = reverse_condition (cond_code);
11536 invert = true;
11537 }
11538
11539 if (cond_code == LEU)
11540 val++;
11541
11542 rtx tmp = gen_reg_rtx (<MODE>mode);
11543 rtx tmp2 = gen_reg_rtx (<MODE>mode);
11544 emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
11545 emit_insn (gen_one_cmpl<mode>2 (tmp2, op1));
11546 rtx x = gen_reg_rtx (<MODE>mode);
11547 if (val < 0)
11548 emit_insn (gen_ior<mode>3 (x, tmp, tmp2));
11549 else
11550 emit_insn (gen_and<mode>3 (x, tmp, tmp2));
11551
11552 if (invert)
11553 {
11554 rtx tmp = gen_reg_rtx (<MODE>mode);
11555 emit_insn (gen_one_cmpl<mode>2 (tmp, x));
11556 x = tmp;
11557 }
11558
11559 int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11560 emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
11561
11562 DONE;
11563 })
11564
11565 (define_expand "cstore<mode>4"
11566 [(use (match_operator 1 "comparison_operator"
11567 [(match_operand:GPR 2 "gpc_reg_operand")
11568 (match_operand:GPR 3 "reg_or_short_operand")]))
11569 (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11570 ""
11571 {
11572 /* Everything is best done with setbc[r] if available. */
11573 if (TARGET_POWER10 && TARGET_ISEL)
11574 rs6000_emit_int_cmove (operands[0], operands[1], const1_rtx, const0_rtx);
11575
11576 /* Expanding EQ and NE directly to some machine instructions does not help
11577 but does hurt combine. So don't. */
11578 if (GET_CODE (operands[1]) == EQ)
11579 emit_insn (gen_eq<mode>3 (operands[0], operands[2], operands[3]));
11580 else if (<MODE>mode == Pmode
11581 && GET_CODE (operands[1]) == NE)
11582 emit_insn (gen_ne<mode>3 (operands[0], operands[2], operands[3]));
11583 else if (GET_CODE (operands[1]) == NE)
11584 {
11585 rtx tmp = gen_reg_rtx (<MODE>mode);
11586 emit_insn (gen_eq<mode>3 (tmp, operands[2], operands[3]));
11587 emit_insn (gen_xor<mode>3 (operands[0], tmp, const1_rtx));
11588 }
11589
11590 /* If ISEL is fast, expand to it. */
11591 else if (TARGET_ISEL)
11592 rs6000_emit_int_cmove (operands[0], operands[1], const1_rtx, const0_rtx);
11593
11594 /* Expanding the unsigned comparisons helps a lot: all the neg_ltu
11595 etc. combinations magically work out just right. */
11596 else if (<MODE>mode == Pmode
11597 && unsigned_comparison_operator (operands[1], VOIDmode))
11598 emit_insn (gen_cstore<mode>4_unsigned (operands[0], operands[1],
11599 operands[2], operands[3]));
11600
11601 /* For comparisons smaller than Pmode we can cheaply do things in Pmode. */
11602 else if (<MODE>mode == SImode && Pmode == DImode)
11603 emit_insn (gen_cstore_si_as_di (operands[0], operands[1],
11604 operands[2], operands[3]));
11605
11606 /* For signed comparisons against a constant, we can do some simple
11607 bit-twiddling. */
11608 else if (signed_comparison_operator (operands[1], VOIDmode)
11609 && CONST_INT_P (operands[3]))
11610 emit_insn (gen_cstore<mode>4_signed_imm (operands[0], operands[1],
11611 operands[2], operands[3]));
11612
11613 /* And similarly for unsigned comparisons. */
11614 else if (unsigned_comparison_operator (operands[1], VOIDmode)
11615 && CONST_INT_P (operands[3]))
11616 emit_insn (gen_cstore<mode>4_unsigned_imm (operands[0], operands[1],
11617 operands[2], operands[3]));
11618
11619 /* We also do not want to use mfcr for signed comparisons. */
11620 else if (<MODE>mode == Pmode
11621 && signed_comparison_operator (operands[1], VOIDmode))
11622 emit_insn (gen_cstore<mode>4_signed (operands[0], operands[1],
11623 operands[2], operands[3]));
11624
11625 /* Everything else, use the mfcr brute force. */
11626 else
11627 rs6000_emit_sCOND (<MODE>mode, operands);
11628
11629 DONE;
11630 })
11631
11632 (define_expand "cstore<mode>4"
11633 [(use (match_operator 1 "comparison_operator"
11634 [(match_operand:FP 2 "gpc_reg_operand")
11635 (match_operand:FP 3 "gpc_reg_operand")]))
11636 (clobber (match_operand:SI 0 "gpc_reg_operand"))]
11637 ""
11638 {
11639 rs6000_emit_sCOND (<MODE>mode, operands);
11640 DONE;
11641 })
11642
11643
11644 (define_expand "stack_protect_set"
11645 [(match_operand 0 "memory_operand")
11646 (match_operand 1 "memory_operand")]
11647 ""
11648 {
11649 if (rs6000_stack_protector_guard == SSP_TLS)
11650 {
11651 rtx reg = gen_rtx_REG (Pmode, rs6000_stack_protector_guard_reg);
11652 rtx offset = GEN_INT (rs6000_stack_protector_guard_offset);
11653 rtx addr = gen_rtx_PLUS (Pmode, reg, offset);
11654 operands[1] = gen_rtx_MEM (Pmode, addr);
11655 }
11656
11657 if (TARGET_64BIT)
11658 emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
11659 else
11660 emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
11661
11662 DONE;
11663 })
11664
11665 (define_insn "stack_protect_setsi"
11666 [(set (match_operand:SI 0 "memory_operand" "=m")
11667 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
11668 (set (match_scratch:SI 2 "=&r") (const_int 0))]
11669 "TARGET_32BIT"
11670 "lwz%U1%X1 %2,%1\;stw%U0%X0 %2,%0\;li %2,0"
11671 [(set_attr "type" "three")
11672 (set_attr "length" "12")])
11673
11674 ;; We can't use the prefixed attribute here because there are two memory
11675 ;; instructions. We can't split the insn due to the fact that this operation
11676 ;; needs to be done in one piece.
11677 (define_insn "stack_protect_setdi"
11678 [(set (match_operand:DI 0 "memory_operand" "=Y")
11679 (unspec:DI [(match_operand:DI 1 "memory_operand" "Y")] UNSPEC_SP_SET))
11680 (set (match_scratch:DI 2 "=&r") (const_int 0))]
11681 "TARGET_64BIT"
11682 {
11683 if (prefixed_memory (operands[1], DImode))
11684 output_asm_insn ("pld %2,%1", operands);
11685 else
11686 output_asm_insn ("ld%U1%X1 %2,%1", operands);
11687
11688 if (prefixed_memory (operands[0], DImode))
11689 output_asm_insn ("pstd %2,%0", operands);
11690 else
11691 output_asm_insn ("std%U0%X0 %2,%0", operands);
11692
11693 return "li %2,0";
11694 }
11695 [(set_attr "type" "three")
11696
11697 ;; Back to back prefixed memory instructions take 20 bytes (8 bytes for each
11698 ;; prefixed instruction + 4 bytes for the possible NOP). Add in 4 bytes for
11699 ;; the LI 0 at the end.
11700 (set_attr "prefixed" "no")
11701 (set_attr "num_insns" "3")
11702 (set (attr "length")
11703 (cond [(and (match_operand 0 "prefixed_memory")
11704 (match_operand 1 "prefixed_memory"))
11705 (const_int 24)
11706
11707 (ior (match_operand 0 "prefixed_memory")
11708 (match_operand 1 "prefixed_memory"))
11709 (const_int 20)]
11710
11711 (const_int 12)))])
11712
11713 (define_expand "stack_protect_test"
11714 [(match_operand 0 "memory_operand")
11715 (match_operand 1 "memory_operand")
11716 (match_operand 2 "")]
11717 ""
11718 {
11719 rtx guard = operands[1];
11720
11721 if (rs6000_stack_protector_guard == SSP_TLS)
11722 {
11723 rtx reg = gen_rtx_REG (Pmode, rs6000_stack_protector_guard_reg);
11724 rtx offset = GEN_INT (rs6000_stack_protector_guard_offset);
11725 rtx addr = gen_rtx_PLUS (Pmode, reg, offset);
11726 guard = gen_rtx_MEM (Pmode, addr);
11727 }
11728
11729 operands[1] = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, guard), UNSPEC_SP_TEST);
11730 rtx test = gen_rtx_EQ (VOIDmode, operands[0], operands[1]);
11731 rtx jump = gen_cbranchsi4 (test, operands[0], operands[1], operands[2]);
11732 emit_jump_insn (jump);
11733
11734 DONE;
11735 })
11736
11737 (define_insn "stack_protect_testsi"
11738 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
11739 (unspec:CCEQ [(match_operand:SI 1 "memory_operand" "m,m")
11740 (match_operand:SI 2 "memory_operand" "m,m")]
11741 UNSPEC_SP_TEST))
11742 (set (match_scratch:SI 4 "=r,r") (const_int 0))
11743 (clobber (match_scratch:SI 3 "=&r,&r"))]
11744 "TARGET_32BIT"
11745 "@
11746 lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0
11747 lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;cmplw %0,%3,%4\;li %3,0\;li %4,0"
11748 [(set_attr "length" "16,20")])
11749
11750 ;; We can't use the prefixed attribute here because there are two memory
11751 ;; instructions. We can't split the insn due to the fact that this operation
11752 ;; needs to be done in one piece.
11753 (define_insn "stack_protect_testdi"
11754 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
11755 (unspec:CCEQ [(match_operand:DI 1 "memory_operand" "Y,Y")
11756 (match_operand:DI 2 "memory_operand" "Y,Y")]
11757 UNSPEC_SP_TEST))
11758 (set (match_scratch:DI 4 "=r,r") (const_int 0))
11759 (clobber (match_scratch:DI 3 "=&r,&r"))]
11760 "TARGET_64BIT"
11761 {
11762 if (prefixed_memory (operands[1], DImode))
11763 output_asm_insn ("pld %3,%1", operands);
11764 else
11765 output_asm_insn ("ld%U1%X1 %3,%1", operands);
11766
11767 if (prefixed_memory (operands[2], DImode))
11768 output_asm_insn ("pld %4,%2", operands);
11769 else
11770 output_asm_insn ("ld%U2%X2 %4,%2", operands);
11771
11772 if (which_alternative == 0)
11773 output_asm_insn ("xor. %3,%3,%4", operands);
11774 else
11775 output_asm_insn ("cmpld %0,%3,%4\;li %3,0", operands);
11776
11777 return "li %4,0";
11778 }
11779 ;; Back to back prefixed memory instructions take 20 bytes (8 bytes for each
11780 ;; prefixed instruction + 4 bytes for the possible NOP). Add in either 4 or
11781 ;; 8 bytes to do the test.
11782 [(set_attr "prefixed" "no")
11783 (set_attr "num_insns" "4,5")
11784 (set (attr "length")
11785 (cond [(and (match_operand 1 "prefixed_memory")
11786 (match_operand 2 "prefixed_memory"))
11787 (if_then_else (eq_attr "alternative" "0")
11788 (const_int 28)
11789 (const_int 32))
11790
11791 (ior (match_operand 1 "prefixed_memory")
11792 (match_operand 2 "prefixed_memory"))
11793 (if_then_else (eq_attr "alternative" "0")
11794 (const_int 20)
11795 (const_int 24))]
11796
11797 (if_then_else (eq_attr "alternative" "0")
11798 (const_int 16)
11799 (const_int 20))))])
11800
11801 \f
11802 ;; Here are the actual compare insns.
11803 (define_insn "*cmp<mode>_signed"
11804 [(set (match_operand:CC 0 "cc_reg_operand" "=y")
11805 (compare:CC (match_operand:GPR 1 "gpc_reg_operand" "r")
11806 (match_operand:GPR 2 "reg_or_short_operand" "rI")))]
11807 ""
11808 "cmp<wd>%I2 %0,%1,%2"
11809 [(set_attr "type" "cmp")])
11810
11811 (define_insn "*cmp<mode>_unsigned"
11812 [(set (match_operand:CCUNS 0 "cc_reg_operand" "=y")
11813 (compare:CCUNS (match_operand:GPR 1 "gpc_reg_operand" "r")
11814 (match_operand:GPR 2 "reg_or_u_short_operand" "rK")))]
11815 ""
11816 "cmpl<wd>%I2 %0,%1,%2"
11817 [(set_attr "type" "cmp")])
11818
11819 ;; If we are comparing a register for equality with a large constant,
11820 ;; we can do this with an XOR followed by a compare. But this is profitable
11821 ;; only if the large constant is only used for the comparison (and in this
11822 ;; case we already have a register to reuse as scratch).
11823 ;;
11824 ;; For 64-bit registers, we could only do so if the constant's bit 15 is clear:
11825 ;; otherwise we'd need to XOR with FFFFFFFF????0000 which is not available.
11826
11827 (define_peephole2
11828 [(set (match_operand:SI 0 "register_operand")
11829 (match_operand:SI 1 "logical_const_operand"))
11830 (set (match_dup 0) (match_operator:SI 3 "boolean_or_operator"
11831 [(match_dup 0)
11832 (match_operand:SI 2 "logical_const_operand")]))
11833 (set (match_operand:CC 4 "cc_reg_operand")
11834 (compare:CC (match_operand:SI 5 "gpc_reg_operand")
11835 (match_dup 0)))
11836 (set (pc)
11837 (if_then_else (match_operator 6 "equality_operator"
11838 [(match_dup 4) (const_int 0)])
11839 (match_operand 7 "")
11840 (match_operand 8 "")))]
11841 "peep2_reg_dead_p (3, operands[0])
11842 && peep2_reg_dead_p (4, operands[4])
11843 && REGNO (operands[0]) != REGNO (operands[5])"
11844 [(set (match_dup 0) (xor:SI (match_dup 5) (match_dup 9)))
11845 (set (match_dup 4) (compare:CC (match_dup 0) (match_dup 10)))
11846 (set (pc) (if_then_else (match_dup 6) (match_dup 7) (match_dup 8)))]
11847
11848 {
11849 /* Get the constant we are comparing against, and see what it looks like
11850 when sign-extended from 16 to 32 bits. Then see what constant we could
11851 XOR with SEXTC to get the sign-extended value. */
11852 rtx cnst = simplify_const_binary_operation (GET_CODE (operands[3]),
11853 SImode,
11854 operands[1], operands[2]);
11855 HOST_WIDE_INT c = INTVAL (cnst);
11856 HOST_WIDE_INT sextc = ((c & 0xffff) ^ 0x8000) - 0x8000;
11857 HOST_WIDE_INT xorv = c ^ sextc;
11858
11859 operands[9] = GEN_INT (xorv);
11860 operands[10] = GEN_INT (sextc);
11861 })
11862
11863 ;; Only need to compare second words if first words equal
11864 (define_insn "*cmp<mode>_internal1"
11865 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
11866 (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
11867 (match_operand:IBM128 2 "gpc_reg_operand" "d")))]
11868 "!TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode)
11869 && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
11870 "fcmpu %0,%1,%2\;bne %0,$+8\;fcmpu %0,%L1,%L2"
11871 [(set_attr "type" "fpcompare")
11872 (set_attr "length" "12")])
11873
11874 (define_insn_and_split "*cmp<IBM128:mode>_internal2"
11875 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
11876 (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
11877 (match_operand:IBM128 2 "gpc_reg_operand" "d")))
11878 (clobber (match_scratch:DF 3 "=d"))
11879 (clobber (match_scratch:DF 4 "=d"))
11880 (clobber (match_scratch:DF 5 "=d"))
11881 (clobber (match_scratch:DF 6 "=d"))
11882 (clobber (match_scratch:DF 7 "=d"))
11883 (clobber (match_scratch:DF 8 "=d"))
11884 (clobber (match_scratch:DF 9 "=d"))
11885 (clobber (match_scratch:DF 10 "=d"))
11886 (clobber (match_scratch:GPR 11 "=b"))]
11887 "TARGET_XL_COMPAT && FLOAT128_IBM_P (<IBM128:MODE>mode)
11888 && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
11889 "#"
11890 "&& reload_completed"
11891 [(set (match_dup 3) (match_dup 14))
11892 (set (match_dup 4) (match_dup 15))
11893 (set (match_dup 9) (abs:DF (match_dup 5)))
11894 (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 3)))
11895 (set (pc) (if_then_else (ne (match_dup 0) (const_int 0))
11896 (label_ref (match_dup 12))
11897 (pc)))
11898 (set (match_dup 0) (compare:CCFP (match_dup 5) (match_dup 7)))
11899 (set (pc) (label_ref (match_dup 13)))
11900 (match_dup 12)
11901 (set (match_dup 10) (minus:DF (match_dup 5) (match_dup 7)))
11902 (set (match_dup 9) (minus:DF (match_dup 6) (match_dup 8)))
11903 (set (match_dup 9) (plus:DF (match_dup 10) (match_dup 9)))
11904 (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 4)))
11905 (match_dup 13)]
11906 {
11907 REAL_VALUE_TYPE rv;
11908 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
11909 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
11910
11911 operands[5] = simplify_gen_subreg (DFmode, operands[1],
11912 <IBM128:MODE>mode, hi_word);
11913 operands[6] = simplify_gen_subreg (DFmode, operands[1],
11914 <IBM128:MODE>mode, lo_word);
11915 operands[7] = simplify_gen_subreg (DFmode, operands[2],
11916 <IBM128:MODE>mode, hi_word);
11917 operands[8] = simplify_gen_subreg (DFmode, operands[2],
11918 <IBM128:MODE>mode, lo_word);
11919 operands[12] = gen_label_rtx ();
11920 operands[13] = gen_label_rtx ();
11921 real_inf (&rv);
11922 operands[14] = force_const_mem (DFmode,
11923 const_double_from_real_value (rv, DFmode));
11924 operands[15] = force_const_mem (DFmode,
11925 const_double_from_real_value (dconst0,
11926 DFmode));
11927 if (TARGET_TOC)
11928 {
11929 rtx tocref;
11930 tocref = create_TOC_reference (XEXP (operands[14], 0), operands[11]);
11931 operands[14] = gen_const_mem (DFmode, tocref);
11932 tocref = create_TOC_reference (XEXP (operands[15], 0), operands[11]);
11933 operands[15] = gen_const_mem (DFmode, tocref);
11934 set_mem_alias_set (operands[14], get_TOC_alias_set ());
11935 set_mem_alias_set (operands[15], get_TOC_alias_set ());
11936 }
11937 })
11938 \f
11939 ;; Now we have the scc insns. We can do some combinations because of the
11940 ;; way the machine works.
11941 ;;
11942 ;; Note that this is probably faster if we can put an insn between the
11943 ;; mfcr and rlinm, but this is tricky. Let's leave it for now. In most
11944 ;; cases the insns below which don't use an intermediate CR field will
11945 ;; be used instead.
11946 (define_insn "set<mode>_cc"
11947 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
11948 (match_operator:GPR 1 "scc_comparison_operator"
11949 [(match_operand 2 "cc_reg_operand" "y")
11950 (const_int 0)]))]
11951 ""
11952 "mfcr %0%Q2\;rlwinm %0,%0,%J1,1"
11953 [(set (attr "type")
11954 (cond [(match_test "TARGET_MFCRF")
11955 (const_string "mfcrf")
11956 ]
11957 (const_string "mfcr")))
11958 (set_attr "length" "8")])
11959
11960
11961 (define_code_iterator cmp [eq ne lt ltu gt gtu le leu ge geu])
11962 (define_code_attr UNS [(eq "CC")
11963 (ne "CC")
11964 (lt "CC") (ltu "CCUNS")
11965 (gt "CC") (gtu "CCUNS")
11966 (le "CC") (leu "CCUNS")
11967 (ge "CC") (geu "CCUNS")])
11968 (define_code_attr UNSu_ [(eq "")
11969 (ne "")
11970 (lt "") (ltu "u_")
11971 (gt "") (gtu "u_")
11972 (le "") (leu "u_")
11973 (ge "") (geu "u_")])
11974 (define_code_attr UNSIK [(eq "I")
11975 (ne "I")
11976 (lt "I") (ltu "K")
11977 (gt "I") (gtu "K")
11978 (le "I") (leu "K")
11979 (ge "I") (geu "K")])
11980
11981 (define_insn_and_split "<code><GPR:mode><GPR2:mode>2_isel"
11982 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
11983 (cmp:GPR (match_operand:GPR2 1 "gpc_reg_operand" "r")
11984 (match_operand:GPR2 2 "reg_or_<cmp:UNSu_>short_operand" "r<cmp:UNSIK>")))
11985 (clobber (match_scratch:GPR 3 "=r"))
11986 (clobber (match_scratch:GPR 4 "=r"))
11987 (clobber (match_scratch:<UNS> 5 "=y"))]
11988 "!TARGET_POWER10 && TARGET_ISEL
11989 && !(<CODE> == EQ && operands[2] == const0_rtx)
11990 && !(<CODE> == NE && operands[2] == const0_rtx
11991 && <GPR:MODE>mode == Pmode && <GPR2:MODE>mode == Pmode)"
11992 "#"
11993 "&& 1"
11994 [(pc)]
11995 {
11996 rtx_code code = <CODE>;
11997 if (CONST_INT_P (operands[2]) && code != EQ && code != NE)
11998 {
11999 HOST_WIDE_INT val = INTVAL (operands[2]);
12000 if (code == LT && val != -0x8000)
12001 {
12002 code = LE;
12003 val--;
12004 }
12005 if (code == GT && val != 0x7fff)
12006 {
12007 code = GE;
12008 val++;
12009 }
12010 if (code == LTU && val != 0)
12011 {
12012 code = LEU;
12013 val--;
12014 }
12015 if (code == GTU && val != 0xffff)
12016 {
12017 code = GEU;
12018 val++;
12019 }
12020 operands[2] = GEN_INT (val);
12021 }
12022
12023 if (code == NE || code == LE || code == GE || code == LEU || code == GEU)
12024 operands[3] = const0_rtx;
12025 else
12026 {
12027 if (GET_CODE (operands[3]) == SCRATCH)
12028 operands[3] = gen_reg_rtx (<GPR:MODE>mode);
12029 emit_move_insn (operands[3], const0_rtx);
12030 }
12031
12032 if (GET_CODE (operands[4]) == SCRATCH)
12033 operands[4] = gen_reg_rtx (<GPR:MODE>mode);
12034 emit_move_insn (operands[4], const1_rtx);
12035
12036 if (GET_CODE (operands[5]) == SCRATCH)
12037 operands[5] = gen_reg_rtx (<UNS>mode);
12038
12039 rtx c1 = gen_rtx_COMPARE (<UNS>mode, operands[1], operands[2]);
12040 emit_insn (gen_rtx_SET (operands[5], c1));
12041
12042 rtx c2 = gen_rtx_fmt_ee (code, <GPR:MODE>mode, operands[5], const0_rtx);
12043 rtx x = gen_rtx_IF_THEN_ELSE (<GPR:MODE>mode, c2, operands[4], operands[3]);
12044 emit_move_insn (operands[0], x);
12045
12046 DONE;
12047 }
12048 [(set (attr "cost")
12049 (if_then_else (match_test "(CONST_INT_P (operands[2]) && <CODE> != EQ)
12050 || <CODE> == NE
12051 || <CODE> == LE || <CODE> == GE
12052 || <CODE> == LEU || <CODE> == GEU")
12053 (const_string "9")
12054 (const_string "10")))])
12055
12056 (define_mode_attr scc_eq_op2 [(SI "rKLI")
12057 (DI "rKJI")])
12058
12059 (define_expand "eq<mode>3"
12060 [(parallel [
12061 (set (match_operand:GPR 0 "gpc_reg_operand" "=r")
12062 (eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
12063 (match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>")))
12064 (clobber (match_scratch:GPR 3 "=r"))
12065 (clobber (match_scratch:GPR 4 "=r"))])]
12066 ""
12067 {
12068 if (TARGET_POWER10)
12069 {
12070 rtx cc = gen_reg_rtx (CCmode);
12071 rtx compare = gen_rtx_COMPARE (CCmode, operands[1], operands[2]);
12072 emit_insn (gen_rtx_SET (cc, compare));
12073 rtx eq = gen_rtx_fmt_ee (EQ, <MODE>mode, cc, const0_rtx);
12074 emit_insn (gen_setbc_signed_<mode> (operands[0], eq, cc));
12075 DONE;
12076 }
12077
12078 if (TARGET_ISEL && operands[2] != const0_rtx)
12079 {
12080 emit_insn (gen_eq<mode><mode>2_isel (operands[0], operands[1],
12081 operands[2]));
12082 DONE;
12083 }
12084 })
12085
12086 (define_insn_and_split "*eq<mode>3"
12087 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
12088 (eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
12089 (match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>")))
12090 (clobber (match_scratch:GPR 3 "=r"))
12091 (clobber (match_scratch:GPR 4 "=r"))]
12092 "!TARGET_POWER10 && !(TARGET_ISEL && operands[2] != const0_rtx)"
12093 "#"
12094 "&& 1"
12095 [(set (match_dup 4)
12096 (clz:GPR (match_dup 3)))
12097 (set (match_dup 0)
12098 (lshiftrt:GPR (match_dup 4)
12099 (match_dup 5)))]
12100 {
12101 operands[3] = rs6000_emit_eqne (<MODE>mode,
12102 operands[1], operands[2], operands[3]);
12103
12104 if (GET_CODE (operands[4]) == SCRATCH)
12105 operands[4] = gen_reg_rtx (<MODE>mode);
12106
12107 operands[5] = GEN_INT (exact_log2 (GET_MODE_BITSIZE (<MODE>mode)));
12108 }
12109 [(set (attr "length")
12110 (if_then_else (match_test "operands[2] == const0_rtx")
12111 (const_string "8")
12112 (const_string "12")))])
12113
12114 (define_expand "ne<mode>3"
12115 [(parallel [
12116 (set (match_operand:GPR 0 "gpc_reg_operand" "=r")
12117 (ne:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
12118 (match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>")))
12119 (clobber (match_scratch:GPR 3 "=r"))
12120 (clobber (match_scratch:GPR 4 "=r"))
12121 (clobber (reg:GPR CA_REGNO))])]
12122 ""
12123 {
12124 if (TARGET_POWER10)
12125 {
12126 rtx cc = gen_reg_rtx (CCmode);
12127 rtx compare = gen_rtx_COMPARE (CCmode, operands[1], operands[2]);
12128 emit_insn (gen_rtx_SET (cc, compare));
12129 rtx ne = gen_rtx_fmt_ee (NE, <MODE>mode, cc, const0_rtx);
12130 emit_insn (gen_setbc_signed_<mode> (operands[0], ne, cc));
12131 DONE;
12132 }
12133
12134 if (<MODE>mode != Pmode)
12135 {
12136 rtx x = gen_reg_rtx (<MODE>mode);
12137 emit_insn (gen_eq<mode>3 (x, operands[1], operands[2]));
12138 emit_insn (gen_xor<mode>3 (operands[0], x, const1_rtx));
12139 DONE;
12140 }
12141
12142 if (TARGET_ISEL && operands[2] != const0_rtx)
12143 {
12144 emit_insn (gen_ne<mode><mode>2_isel (operands[0], operands[1],
12145 operands[2]));
12146 DONE;
12147 }
12148 })
12149
12150 (define_insn_and_split "*ne<mode>3"
12151 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12152 (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12153 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")))
12154 (clobber (match_scratch:P 3 "=r"))
12155 (clobber (match_scratch:P 4 "=r"))
12156 (clobber (reg:P CA_REGNO))]
12157 "!TARGET_POWER10 && !(TARGET_ISEL && operands[2] != const0_rtx)"
12158 "#"
12159 "&& 1"
12160 [(parallel [(set (match_dup 4)
12161 (plus:P (match_dup 3)
12162 (const_int -1)))
12163 (set (reg:P CA_REGNO)
12164 (ne:P (match_dup 3)
12165 (const_int 0)))])
12166 (parallel [(set (match_dup 0)
12167 (plus:P (plus:P (not:P (match_dup 4))
12168 (reg:P CA_REGNO))
12169 (match_dup 3)))
12170 (clobber (reg:P CA_REGNO))])]
12171 {
12172 operands[3] = rs6000_emit_eqne (<MODE>mode,
12173 operands[1], operands[2], operands[3]);
12174
12175 if (GET_CODE (operands[4]) == SCRATCH)
12176 operands[4] = gen_reg_rtx (<MODE>mode);
12177 }
12178 [(set (attr "length")
12179 (if_then_else (match_test "operands[2] == const0_rtx")
12180 (const_string "8")
12181 (const_string "12")))])
12182
12183 (define_insn_and_split "*neg_eq_<mode>"
12184 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12185 (neg:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12186 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12187 (clobber (match_scratch:P 3 "=r"))
12188 (clobber (match_scratch:P 4 "=r"))
12189 (clobber (reg:P CA_REGNO))]
12190 "!TARGET_POWER10"
12191 "#"
12192 "&& 1"
12193 [(parallel [(set (match_dup 4)
12194 (plus:P (match_dup 3)
12195 (const_int -1)))
12196 (set (reg:P CA_REGNO)
12197 (ne:P (match_dup 3)
12198 (const_int 0)))])
12199 (parallel [(set (match_dup 0)
12200 (plus:P (reg:P CA_REGNO)
12201 (const_int -1)))
12202 (clobber (reg:P CA_REGNO))])]
12203 {
12204 operands[3] = rs6000_emit_eqne (<MODE>mode,
12205 operands[1], operands[2], operands[3]);
12206
12207 if (GET_CODE (operands[4]) == SCRATCH)
12208 operands[4] = gen_reg_rtx (<MODE>mode);
12209 }
12210 [(set (attr "length")
12211 (if_then_else (match_test "operands[2] == const0_rtx")
12212 (const_string "8")
12213 (const_string "12")))])
12214
12215 (define_insn_and_split "*neg_ne_<mode>"
12216 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12217 (neg:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12218 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12219 (clobber (match_scratch:P 3 "=r"))
12220 (clobber (match_scratch:P 4 "=r"))
12221 (clobber (reg:P CA_REGNO))]
12222 "!TARGET_POWER10"
12223 "#"
12224 "&& 1"
12225 [(parallel [(set (match_dup 4)
12226 (neg:P (match_dup 3)))
12227 (set (reg:P CA_REGNO)
12228 (eq:P (match_dup 3)
12229 (const_int 0)))])
12230 (parallel [(set (match_dup 0)
12231 (plus:P (reg:P CA_REGNO)
12232 (const_int -1)))
12233 (clobber (reg:P CA_REGNO))])]
12234 {
12235 operands[3] = rs6000_emit_eqne (<MODE>mode,
12236 operands[1], operands[2], operands[3]);
12237
12238 if (GET_CODE (operands[4]) == SCRATCH)
12239 operands[4] = gen_reg_rtx (<MODE>mode);
12240 }
12241 [(set (attr "length")
12242 (if_then_else (match_test "operands[2] == const0_rtx")
12243 (const_string "8")
12244 (const_string "12")))])
12245
12246 (define_insn_and_split "*plus_eq_<mode>"
12247 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12248 (plus:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12249 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
12250 (match_operand:P 3 "gpc_reg_operand" "r")))
12251 (clobber (match_scratch:P 4 "=r"))
12252 (clobber (match_scratch:P 5 "=r"))
12253 (clobber (reg:P CA_REGNO))]
12254 ""
12255 "#"
12256 ""
12257 [(parallel [(set (match_dup 5)
12258 (neg:P (match_dup 4)))
12259 (set (reg:P CA_REGNO)
12260 (eq:P (match_dup 4)
12261 (const_int 0)))])
12262 (parallel [(set (match_dup 0)
12263 (plus:P (match_dup 3)
12264 (reg:P CA_REGNO)))
12265 (clobber (reg:P CA_REGNO))])]
12266 {
12267 operands[4] = rs6000_emit_eqne (<MODE>mode,
12268 operands[1], operands[2], operands[4]);
12269
12270 if (GET_CODE (operands[5]) == SCRATCH)
12271 operands[5] = gen_reg_rtx (<MODE>mode);
12272 }
12273 [(set (attr "length")
12274 (if_then_else (match_test "operands[2] == const0_rtx")
12275 (const_string "8")
12276 (const_string "12")))])
12277
12278 (define_insn_and_split "*plus_ne_<mode>"
12279 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12280 (plus:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12281 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
12282 (match_operand:P 3 "gpc_reg_operand" "r")))
12283 (clobber (match_scratch:P 4 "=r"))
12284 (clobber (match_scratch:P 5 "=r"))
12285 (clobber (reg:P CA_REGNO))]
12286 ""
12287 "#"
12288 ""
12289 [(parallel [(set (match_dup 5)
12290 (plus:P (match_dup 4)
12291 (const_int -1)))
12292 (set (reg:P CA_REGNO)
12293 (ne:P (match_dup 4)
12294 (const_int 0)))])
12295 (parallel [(set (match_dup 0)
12296 (plus:P (match_dup 3)
12297 (reg:P CA_REGNO)))
12298 (clobber (reg:P CA_REGNO))])]
12299 {
12300 operands[4] = rs6000_emit_eqne (<MODE>mode,
12301 operands[1], operands[2], operands[4]);
12302
12303 if (GET_CODE (operands[5]) == SCRATCH)
12304 operands[5] = gen_reg_rtx (<MODE>mode);
12305 }
12306 [(set (attr "length")
12307 (if_then_else (match_test "operands[2] == const0_rtx")
12308 (const_string "8")
12309 (const_string "12")))])
12310
12311 (define_insn_and_split "*minus_eq_<mode>"
12312 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12313 (minus:P (match_operand:P 3 "gpc_reg_operand" "r")
12314 (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12315 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12316 (clobber (match_scratch:P 4 "=r"))
12317 (clobber (match_scratch:P 5 "=r"))
12318 (clobber (reg:P CA_REGNO))]
12319 ""
12320 "#"
12321 ""
12322 [(parallel [(set (match_dup 5)
12323 (plus:P (match_dup 4)
12324 (const_int -1)))
12325 (set (reg:P CA_REGNO)
12326 (ne:P (match_dup 4)
12327 (const_int 0)))])
12328 (parallel [(set (match_dup 0)
12329 (plus:P (plus:P (match_dup 3)
12330 (reg:P CA_REGNO))
12331 (const_int -1)))
12332 (clobber (reg:P CA_REGNO))])]
12333 {
12334 operands[4] = rs6000_emit_eqne (<MODE>mode,
12335 operands[1], operands[2], operands[4]);
12336
12337 if (GET_CODE (operands[5]) == SCRATCH)
12338 operands[5] = gen_reg_rtx (<MODE>mode);
12339 }
12340 [(set (attr "length")
12341 (if_then_else (match_test "operands[2] == const0_rtx")
12342 (const_string "8")
12343 (const_string "12")))])
12344
12345 (define_insn_and_split "*minus_ne_<mode>"
12346 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12347 (minus:P (match_operand:P 3 "gpc_reg_operand" "r")
12348 (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12349 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12350 (clobber (match_scratch:P 4 "=r"))
12351 (clobber (match_scratch:P 5 "=r"))
12352 (clobber (reg:P CA_REGNO))]
12353 ""
12354 "#"
12355 ""
12356 [(parallel [(set (match_dup 5)
12357 (neg:P (match_dup 4)))
12358 (set (reg:P CA_REGNO)
12359 (eq:P (match_dup 4)
12360 (const_int 0)))])
12361 (parallel [(set (match_dup 0)
12362 (plus:P (plus:P (match_dup 3)
12363 (reg:P CA_REGNO))
12364 (const_int -1)))
12365 (clobber (reg:P CA_REGNO))])]
12366 {
12367 operands[4] = rs6000_emit_eqne (<MODE>mode,
12368 operands[1], operands[2], operands[4]);
12369
12370 if (GET_CODE (operands[5]) == SCRATCH)
12371 operands[5] = gen_reg_rtx (<MODE>mode);
12372 }
12373 [(set (attr "length")
12374 (if_then_else (match_test "operands[2] == const0_rtx")
12375 (const_string "8")
12376 (const_string "12")))])
12377
12378 (define_insn_and_split "*eqsi3_ext<mode>"
12379 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
12380 (eq:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
12381 (match_operand:SI 2 "scc_eq_operand" "rKLI")))
12382 (clobber (match_scratch:SI 3 "=r"))
12383 (clobber (match_scratch:SI 4 "=r"))]
12384 "!TARGET_POWER10"
12385 "#"
12386 "&& 1"
12387 [(set (match_dup 4)
12388 (clz:SI (match_dup 3)))
12389 (set (match_dup 0)
12390 (zero_extend:EXTSI
12391 (lshiftrt:SI (match_dup 4)
12392 (const_int 5))))]
12393 {
12394 operands[3] = rs6000_emit_eqne (SImode,
12395 operands[1], operands[2], operands[3]);
12396
12397 if (GET_CODE (operands[4]) == SCRATCH)
12398 operands[4] = gen_reg_rtx (SImode);
12399 }
12400 [(set (attr "length")
12401 (if_then_else (match_test "operands[2] == const0_rtx")
12402 (const_string "8")
12403 (const_string "12")))])
12404
12405 (define_insn_and_split "*nesi3_ext<mode>"
12406 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
12407 (ne:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
12408 (match_operand:SI 2 "scc_eq_operand" "rKLI")))
12409 (clobber (match_scratch:SI 3 "=r"))
12410 (clobber (match_scratch:SI 4 "=r"))
12411 (clobber (match_scratch:EXTSI 5 "=r"))]
12412 "!TARGET_ISEL"
12413 "#"
12414 "&& 1"
12415 [(set (match_dup 4)
12416 (clz:SI (match_dup 3)))
12417 (set (match_dup 5)
12418 (zero_extend:EXTSI
12419 (lshiftrt:SI (match_dup 4)
12420 (const_int 5))))
12421 (set (match_dup 0)
12422 (xor:EXTSI (match_dup 5)
12423 (const_int 1)))]
12424 {
12425 operands[3] = rs6000_emit_eqne (SImode,
12426 operands[1], operands[2], operands[3]);
12427
12428 if (GET_CODE (operands[4]) == SCRATCH)
12429 operands[4] = gen_reg_rtx (SImode);
12430 if (GET_CODE (operands[5]) == SCRATCH)
12431 operands[5] = gen_reg_rtx (<MODE>mode);
12432 }
12433 [(set (attr "length")
12434 (if_then_else (match_test "operands[2] == const0_rtx")
12435 (const_string "12")
12436 (const_string "16")))])
12437
12438
12439 (define_code_iterator fp_rev [ordered ne unle unge])
12440 (define_code_iterator fp_two [ltgt le ge unlt ungt uneq])
12441
12442 (define_insn_and_split "*<code><mode>_cc"
12443 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
12444 (fp_rev:GPR (match_operand:CCFP 1 "cc_reg_operand" "y")
12445 (const_int 0)))]
12446 "!flag_finite_math_only"
12447 "#"
12448 "&& 1"
12449 [(pc)]
12450 {
12451 rtx_code revcode = reverse_condition_maybe_unordered (<CODE>);
12452 rtx eq = gen_rtx_fmt_ee (revcode, <MODE>mode, operands[1], const0_rtx);
12453 rtx tmp = gen_reg_rtx (<MODE>mode);
12454 emit_move_insn (tmp, eq);
12455 emit_insn (gen_xor<mode>3 (operands[0], tmp, const1_rtx));
12456 DONE;
12457 }
12458 [(set_attr "length" "12")])
12459
12460 (define_insn_and_split "*<code><mode>_cc"
12461 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
12462 (fp_two:GPR (match_operand:CCFP 1 "cc_reg_operand" "y")
12463 (const_int 0)))]
12464 "!flag_finite_math_only"
12465 "#"
12466 "&& 1"
12467 [(pc)]
12468 {
12469 rtx cc = rs6000_emit_fp_cror (<CODE>, <MODE>mode, operands[1]);
12470
12471 emit_move_insn (operands[0], gen_rtx_EQ (<MODE>mode, cc, const0_rtx));
12472 DONE;
12473 }
12474 [(set_attr "length" "12")])
12475 \f
12476 ;; Conditional branches.
12477 ;; These either are a single bc insn, or a bc around a b.
12478
12479 (define_insn "*cbranch"
12480 [(set (pc)
12481 (if_then_else (match_operator 1 "branch_comparison_operator"
12482 [(match_operand 2 "cc_reg_operand" "y")
12483 (const_int 0)])
12484 (label_ref (match_operand 0))
12485 (pc)))]
12486 ""
12487 {
12488 return output_cbranch (operands[1], "%l0", 0, insn);
12489 }
12490 [(set_attr "type" "branch")
12491 (set (attr "length")
12492 (if_then_else (and (ge (minus (match_dup 0) (pc))
12493 (const_int -32768))
12494 (lt (minus (match_dup 0) (pc))
12495 (const_int 32764)))
12496 (const_int 4)
12497 (const_int 8)))])
12498
12499 (define_insn_and_split "*cbranch_2insn"
12500 [(set (pc)
12501 (if_then_else (match_operator 1 "extra_insn_branch_comparison_operator"
12502 [(match_operand 2 "cc_reg_operand" "y")
12503 (const_int 0)])
12504 (label_ref (match_operand 0))
12505 (pc)))]
12506 "!flag_finite_math_only"
12507 "#"
12508 "&& 1"
12509 [(pc)]
12510 {
12511 rtx cc = rs6000_emit_fp_cror (GET_CODE (operands[1]), SImode, operands[2]);
12512
12513 rtx note = find_reg_note (curr_insn, REG_BR_PROB, 0);
12514
12515 rtx loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands[0]);
12516 rtx cond = gen_rtx_EQ (CCEQmode, cc, const0_rtx);
12517 rtx ite = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, loc_ref, pc_rtx);
12518 emit_jump_insn (gen_rtx_SET (pc_rtx, ite));
12519
12520 if (note)
12521 {
12522 profile_probability prob
12523 = profile_probability::from_reg_br_prob_note (XINT (note, 0));
12524
12525 add_reg_br_prob_note (get_last_insn (), prob);
12526 }
12527
12528 DONE;
12529 }
12530 [(set_attr "type" "branch")
12531 (set (attr "length")
12532 (if_then_else (and (ge (minus (match_dup 0) (pc))
12533 (const_int -32764))
12534 (lt (minus (match_dup 0) (pc))
12535 (const_int 32760)))
12536 (const_int 8)
12537 (const_int 16)))])
12538
12539 ;; Conditional return.
12540 (define_insn "*creturn"
12541 [(set (pc)
12542 (if_then_else (match_operator 0 "branch_comparison_operator"
12543 [(match_operand 1 "cc_reg_operand" "y")
12544 (const_int 0)])
12545 (any_return)
12546 (pc)))]
12547 "<return_pred>"
12548 {
12549 return output_cbranch (operands[0], NULL, 0, insn);
12550 }
12551 [(set_attr "type" "jmpreg")])
12552
12553 ;; Logic on condition register values.
12554
12555 ; This pattern matches things like
12556 ; (set (reg:CCEQ 68) (compare:CCEQ (ior:SI (gt:SI (reg:CCFP 68) (const_int 0))
12557 ; (eq:SI (reg:CCFP 68) (const_int 0)))
12558 ; (const_int 1)))
12559 ; which are generated by the branch logic.
12560 ; Prefer destructive operations where BT = BB (for crXX BT,BA,BB)
12561
12562 (define_insn "@cceq_ior_compare_<mode>"
12563 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12564 (compare:CCEQ (match_operator:GPR 1 "boolean_operator"
12565 [(match_operator:GPR 2
12566 "branch_positive_comparison_operator"
12567 [(match_operand 3
12568 "cc_reg_operand" "y,y")
12569 (const_int 0)])
12570 (match_operator:GPR 4
12571 "branch_positive_comparison_operator"
12572 [(match_operand 5
12573 "cc_reg_operand" "0,y")
12574 (const_int 0)])])
12575 (const_int 1)))]
12576 ""
12577 "cr%q1 %E0,%j2,%j4"
12578 [(set_attr "type" "cr_logical")
12579 (set_attr "cr_logical_3op" "no,yes")])
12580
12581 ; Why is the constant -1 here, but 1 in the previous pattern?
12582 ; Because ~1 has all but the low bit set.
12583 (define_insn "cceq_ior_compare_complement"
12584 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12585 (compare:CCEQ (match_operator:SI 1 "boolean_operator"
12586 [(not:SI (match_operator:SI 2
12587 "branch_positive_comparison_operator"
12588 [(match_operand 3
12589 "cc_reg_operand" "y,y")
12590 (const_int 0)]))
12591 (match_operator:SI 4
12592 "branch_positive_comparison_operator"
12593 [(match_operand 5
12594 "cc_reg_operand" "0,y")
12595 (const_int 0)])])
12596 (const_int -1)))]
12597 ""
12598 "cr%q1 %E0,%j2,%j4"
12599 [(set_attr "type" "cr_logical")
12600 (set_attr "cr_logical_3op" "no,yes")])
12601
12602 (define_insn "@cceq_rev_compare_<mode>"
12603 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12604 (compare:CCEQ (match_operator:GPR 1
12605 "branch_positive_comparison_operator"
12606 [(match_operand 2
12607 "cc_reg_operand" "0,y")
12608 (const_int 0)])
12609 (const_int 0)))]
12610 ""
12611 "crnot %E0,%j1"
12612 [(set_attr "type" "cr_logical")
12613 (set_attr "cr_logical_3op" "no,yes")])
12614
12615 ;; If we are comparing the result of two comparisons, this can be done
12616 ;; using creqv or crxor.
12617
12618 (define_insn_and_split ""
12619 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y")
12620 (compare:CCEQ (match_operator 1 "branch_comparison_operator"
12621 [(match_operand 2 "cc_reg_operand" "y")
12622 (const_int 0)])
12623 (match_operator 3 "branch_comparison_operator"
12624 [(match_operand 4 "cc_reg_operand" "y")
12625 (const_int 0)])))]
12626 ""
12627 "#"
12628 ""
12629 [(set (match_dup 0) (compare:CCEQ (xor:SI (match_dup 1) (match_dup 3))
12630 (match_dup 5)))]
12631 {
12632 int positive_1, positive_2;
12633
12634 positive_1 = branch_positive_comparison_operator (operands[1],
12635 GET_MODE (operands[1]));
12636 positive_2 = branch_positive_comparison_operator (operands[3],
12637 GET_MODE (operands[3]));
12638
12639 if (! positive_1)
12640 operands[1] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[2]),
12641 GET_CODE (operands[1])),
12642 SImode,
12643 operands[2], const0_rtx);
12644 else if (GET_MODE (operands[1]) != SImode)
12645 operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), SImode,
12646 operands[2], const0_rtx);
12647
12648 if (! positive_2)
12649 operands[3] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[4]),
12650 GET_CODE (operands[3])),
12651 SImode,
12652 operands[4], const0_rtx);
12653 else if (GET_MODE (operands[3]) != SImode)
12654 operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SImode,
12655 operands[4], const0_rtx);
12656
12657 if (positive_1 == positive_2)
12658 {
12659 operands[1] = gen_rtx_NOT (SImode, operands[1]);
12660 operands[5] = constm1_rtx;
12661 }
12662 else
12663 {
12664 operands[5] = const1_rtx;
12665 }
12666 })
12667
12668 ;; Unconditional branch and return.
12669
12670 (define_insn "jump"
12671 [(set (pc)
12672 (label_ref (match_operand 0)))]
12673 ""
12674 "b %l0"
12675 [(set_attr "type" "branch")])
12676
12677 (define_insn "<return_str>return"
12678 [(any_return)]
12679 "<return_pred>"
12680 "blr"
12681 [(set_attr "type" "jmpreg")])
12682
12683 (define_expand "indirect_jump"
12684 [(set (pc) (match_operand 0 "register_operand"))]
12685 ""
12686 {
12687 if (!rs6000_speculate_indirect_jumps) {
12688 rtx ccreg = gen_reg_rtx (CCmode);
12689 emit_jump_insn (gen_indirect_jump_nospec (Pmode, operands[0], ccreg));
12690 DONE;
12691 }
12692 })
12693
12694 (define_insn "*indirect_jump<mode>"
12695 [(set (pc)
12696 (match_operand:P 0 "register_operand" "c,*l"))]
12697 "rs6000_speculate_indirect_jumps"
12698 "b%T0"
12699 [(set_attr "type" "jmpreg")])
12700
12701 (define_insn "@indirect_jump<mode>_nospec"
12702 [(set (pc) (match_operand:P 0 "register_operand" "c,*l"))
12703 (clobber (match_operand:CC 1 "cc_reg_operand" "=y,y"))]
12704 "!rs6000_speculate_indirect_jumps"
12705 "crset %E1\;beq%T0- %1\;b $"
12706 [(set_attr "type" "jmpreg")
12707 (set_attr "length" "12")])
12708
12709 ;; Table jump for switch statements:
12710 (define_expand "tablejump"
12711 [(use (match_operand 0))
12712 (use (label_ref (match_operand 1)))]
12713 ""
12714 {
12715 if (rs6000_speculate_indirect_jumps)
12716 emit_jump_insn (gen_tablejump_normal (Pmode, operands[0], operands[1]));
12717 else
12718 {
12719 rtx ccreg = gen_reg_rtx (CCmode);
12720 rtx jump;
12721 if (TARGET_32BIT)
12722 jump = gen_tablejumpsi_nospec (operands[0], operands[1], ccreg);
12723 else
12724 jump = gen_tablejumpdi_nospec (operands[0], operands[1], ccreg);
12725 emit_jump_insn (jump);
12726 }
12727 DONE;
12728 })
12729
12730 (define_expand "@tablejump<mode>_normal"
12731 [(use (match_operand:SI 0))
12732 (use (match_operand:P 1))]
12733 "rs6000_speculate_indirect_jumps"
12734 {
12735 rtx off = force_reg (SImode, operands[0]);
12736 if (<MODE>mode != SImode)
12737 {
12738 rtx src = gen_rtx_fmt_e (SIGN_EXTEND, Pmode, off);
12739 off = gen_reg_rtx (Pmode);
12740 emit_move_insn (off, src);
12741 }
12742
12743 rtx lab = force_reg (Pmode, gen_rtx_LABEL_REF (Pmode, operands[1]));
12744 rtx addr = gen_reg_rtx (Pmode);
12745
12746 emit_insn (gen_add<mode>3 (addr, off, lab));
12747 emit_jump_insn (gen_tablejump_insn_normal (Pmode, addr, operands[1]));
12748 DONE;
12749 })
12750
12751 (define_expand "@tablejump<mode>_nospec"
12752 [(use (match_operand:SI 0))
12753 (use (match_operand:P 1))
12754 (use (match_operand:CC 2))]
12755 "!rs6000_speculate_indirect_jumps"
12756 {
12757 rtx off = force_reg (SImode, operands[0]);
12758 if (<MODE>mode != SImode)
12759 {
12760 rtx src = gen_rtx_fmt_e (SIGN_EXTEND, Pmode, off);
12761 off = gen_reg_rtx (Pmode);
12762 emit_move_insn (off, src);
12763 }
12764
12765 rtx lab = force_reg (Pmode, gen_rtx_LABEL_REF (Pmode, operands[1]));
12766 rtx addr = gen_reg_rtx (Pmode);
12767
12768 emit_insn (gen_add<mode>3 (addr, off, lab));
12769 emit_jump_insn (gen_tablejump_insn_nospec (Pmode, addr, operands[1],
12770 operands[2]));
12771 DONE;
12772 })
12773
12774 (define_insn "@tablejump<mode>_insn_normal"
12775 [(set (pc)
12776 (match_operand:P 0 "register_operand" "c,*l"))
12777 (use (label_ref (match_operand 1)))]
12778 "rs6000_speculate_indirect_jumps"
12779 "b%T0"
12780 [(set_attr "type" "jmpreg")])
12781
12782 (define_insn "@tablejump<mode>_insn_nospec"
12783 [(set (pc)
12784 (match_operand:P 0 "register_operand" "c,*l"))
12785 (use (label_ref (match_operand 1)))
12786 (clobber (match_operand:CC 2 "cc_reg_operand" "=y,y"))]
12787 "!rs6000_speculate_indirect_jumps"
12788 "crset %E2\;beq%T0- %2\;b $"
12789 [(set_attr "type" "jmpreg")
12790 (set_attr "length" "12")])
12791
12792 (define_insn "nop"
12793 [(unspec [(const_int 0)] UNSPEC_NOP)]
12794 ""
12795 "nop")
12796
12797 (define_insn "group_ending_nop"
12798 [(unspec [(const_int 0)] UNSPEC_GRP_END_NOP)]
12799 ""
12800 {
12801 operands[0] = gen_rtx_REG (Pmode,
12802 rs6000_tune == PROCESSOR_POWER6 ? 1 : 2);
12803 return "ori %0,%0,0";
12804 })
12805
12806 (define_insn "speculation_barrier"
12807 [(unspec_volatile:BLK [(const_int 0)] UNSPECV_SPEC_BARRIER)]
12808 ""
12809 {
12810 operands[0] = gen_rtx_REG (Pmode, 31);
12811 return "ori %0,%0,0";
12812 })
12813 \f
12814 ;; Define the subtract-one-and-jump insns, starting with the template
12815 ;; so loop.c knows what to generate.
12816
12817 (define_expand "doloop_end"
12818 [(use (match_operand 0)) ; loop pseudo
12819 (use (match_operand 1))] ; label
12820 ""
12821 {
12822 if (GET_MODE (operands[0]) != Pmode)
12823 FAIL;
12824
12825 emit_jump_insn (gen_ctr (Pmode, operands[0], operands[1]));
12826 DONE;
12827 })
12828
12829 (define_expand "@ctr<mode>"
12830 [(parallel [(set (pc)
12831 (if_then_else (ne (match_operand:P 0 "register_operand")
12832 (const_int 1))
12833 (label_ref (match_operand 1))
12834 (pc)))
12835 (set (match_dup 0)
12836 (plus:P (match_dup 0)
12837 (const_int -1)))
12838 (clobber (match_scratch:CC 2))
12839 (clobber (match_scratch:P 3))])]
12840 ""
12841 "")
12842
12843 ;; We need to be able to do this for any operand, including MEM, or we
12844 ;; will cause reload to blow up since we don't allow output reloads on
12845 ;; JUMP_INSNs.
12846 ;; For the length attribute to be calculated correctly, the
12847 ;; label MUST be operand 0.
12848 ;; rs6000_legitimate_combined_insn prevents combine creating any of
12849 ;; the ctr<mode> insns.
12850
12851 (define_code_iterator eqne [eq ne])
12852 (define_code_attr bd [(eq "bdz") (ne "bdnz")])
12853 (define_code_attr bd_neg [(eq "bdnz") (ne "bdz")])
12854
12855 (define_insn "<bd>_<mode>"
12856 [(set (pc)
12857 (if_then_else (eqne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12858 (const_int 1))
12859 (label_ref (match_operand 0))
12860 (pc)))
12861 (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wa*c*l")
12862 (plus:P (match_dup 1)
12863 (const_int -1)))
12864 (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
12865 (clobber (match_scratch:P 4 "=X,X,&r,r"))]
12866 ""
12867 {
12868 if (which_alternative != 0)
12869 return "#";
12870 else if (get_attr_length (insn) == 4)
12871 return "<bd> %l0";
12872 else
12873 return "<bd_neg> $+8\;b %l0";
12874 }
12875 [(set_attr "type" "branch")
12876 (set_attr_alternative "length"
12877 [(if_then_else (and (ge (minus (match_dup 0) (pc))
12878 (const_int -32768))
12879 (lt (minus (match_dup 0) (pc))
12880 (const_int 32764)))
12881 (const_int 4)
12882 (const_int 8))
12883 (const_string "16")
12884 (const_string "20")
12885 (const_string "20")])])
12886
12887 ;; Now the splitter if we could not allocate the CTR register
12888 (define_split
12889 [(set (pc)
12890 (if_then_else (match_operator 2 "comparison_operator"
12891 [(match_operand:P 1 "gpc_reg_operand")
12892 (const_int 1)])
12893 (match_operand 5)
12894 (match_operand 6)))
12895 (set (match_operand:P 0 "nonimmediate_operand")
12896 (plus:P (match_dup 1)
12897 (const_int -1)))
12898 (clobber (match_scratch:CC 3))
12899 (clobber (match_scratch:P 4))]
12900 "reload_completed"
12901 [(set (pc)
12902 (if_then_else (match_dup 7)
12903 (match_dup 5)
12904 (match_dup 6)))]
12905 {
12906 operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[2]), VOIDmode, operands[3],
12907 const0_rtx);
12908 emit_insn (gen_rtx_SET (operands[3],
12909 gen_rtx_COMPARE (CCmode, operands[1], const1_rtx)));
12910 if (int_reg_operand (operands[0], <MODE>mode))
12911 emit_insn (gen_add<mode>3 (operands[0], operands[1], constm1_rtx));
12912 else
12913 {
12914 emit_insn (gen_add<mode>3 (operands[4], operands[1], constm1_rtx));
12915 emit_move_insn (operands[0], operands[4]);
12916 }
12917 /* No DONE so branch comes from the pattern. */
12918 })
12919
12920 ;; patterns for bdnzt/bdnzf/bdzt/bdzf
12921 ;; Note that in the case of long branches we have to decompose this into
12922 ;; bdnz+bc. This is because bdnzt has an implied AND between the ctr condition
12923 ;; and the CR bit, which means there is no way to conveniently invert the
12924 ;; comparison as is done with plain bdnz/bdz.
12925
12926 (define_insn "<bd>tf_<mode>"
12927 [(set (pc)
12928 (if_then_else
12929 (and
12930 (eqne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12931 (const_int 1))
12932 (match_operator 3 "branch_comparison_operator"
12933 [(match_operand 4 "cc_reg_operand" "y,y,y,y")
12934 (const_int 0)]))
12935 (label_ref (match_operand 0))
12936 (pc)))
12937 (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wa*c*l")
12938 (plus:P (match_dup 1)
12939 (const_int -1)))
12940 (clobber (match_scratch:P 5 "=X,X,&r,r"))
12941 (clobber (match_scratch:CC 6 "=X,&y,&y,&y"))
12942 (clobber (match_scratch:CCEQ 7 "=X,&y,&y,&y"))]
12943 ""
12944 {
12945 if (which_alternative != 0)
12946 return "#";
12947 else if (get_attr_length (insn) == 4)
12948 {
12949 if (branch_positive_comparison_operator (operands[3],
12950 GET_MODE (operands[3])))
12951 return "<bd>t %j3,%l0";
12952 else
12953 return "<bd>f %j3,%l0";
12954 }
12955 else
12956 {
12957 static char seq[96];
12958 char *bcs = output_cbranch (operands[3], ".Lshort%=", 1, insn);
12959 sprintf(seq, "<bd_neg> .Lshort%%=\;%s\;b %%l0\;.Lshort%%=:", bcs);
12960 return seq;
12961 }
12962 }
12963 [(set_attr "type" "branch")
12964 (set_attr_alternative "length"
12965 [(if_then_else (and (ge (minus (match_dup 0) (pc))
12966 (const_int -32768))
12967 (lt (minus (match_dup 0) (pc))
12968 (const_int 32764)))
12969 (const_int 4)
12970 (const_int 8))
12971 (const_string "16")
12972 (const_string "20")
12973 (const_string "20")])])
12974
12975 ;; Now the splitter if we could not allocate the CTR register
12976 (define_split
12977 [(set (pc)
12978 (if_then_else
12979 (and
12980 (match_operator 1 "comparison_operator"
12981 [(match_operand:P 0 "gpc_reg_operand")
12982 (const_int 1)])
12983 (match_operator 3 "branch_comparison_operator"
12984 [(match_operand 2 "cc_reg_operand")
12985 (const_int 0)]))
12986 (match_operand 4)
12987 (match_operand 5)))
12988 (set (match_operand:P 6 "nonimmediate_operand")
12989 (plus:P (match_dup 0)
12990 (const_int -1)))
12991 (clobber (match_scratch:P 7))
12992 (clobber (match_scratch:CC 8))
12993 (clobber (match_scratch:CCEQ 9))]
12994 "reload_completed"
12995 [(pc)]
12996 {
12997 rtx ctr = operands[0];
12998 rtx ctrcmp = operands[1];
12999 rtx ccin = operands[2];
13000 rtx cccmp = operands[3];
13001 rtx dst1 = operands[4];
13002 rtx dst2 = operands[5];
13003 rtx ctrout = operands[6];
13004 rtx ctrtmp = operands[7];
13005 enum rtx_code cmpcode = GET_CODE (ctrcmp);
13006 bool ispos = branch_positive_comparison_operator (ctrcmp, GET_MODE (ctrcmp));
13007 if (!ispos)
13008 cmpcode = reverse_condition (cmpcode);
13009 /* Generate crand/crandc here. */
13010 emit_insn (gen_rtx_SET (operands[8],
13011 gen_rtx_COMPARE (CCmode, ctr, const1_rtx)));
13012 rtx ctrcmpcc = gen_rtx_fmt_ee (cmpcode, SImode, operands[8], const0_rtx);
13013
13014 rtx andexpr = gen_rtx_AND (SImode, ctrcmpcc, cccmp);
13015 if (ispos)
13016 emit_insn (gen_cceq_ior_compare (SImode, operands[9], andexpr, ctrcmpcc,
13017 operands[8], cccmp, ccin));
13018 else
13019 emit_insn (gen_cceq_ior_compare_complement (operands[9], andexpr, ctrcmpcc,
13020 operands[8], cccmp, ccin));
13021 if (int_reg_operand (ctrout, <MODE>mode))
13022 emit_insn (gen_add<mode>3 (ctrout, ctr, constm1_rtx));
13023 else
13024 {
13025 emit_insn (gen_add<mode>3 (ctrtmp, ctr, constm1_rtx));
13026 emit_move_insn (ctrout, ctrtmp);
13027 }
13028 rtx cmp = gen_rtx_EQ (CCEQmode, operands[9], const0_rtx);
13029 emit_jump_insn (gen_rtx_SET (pc_rtx,
13030 gen_rtx_IF_THEN_ELSE (VOIDmode, cmp,
13031 dst1, dst2)));
13032 DONE;
13033 })
13034
13035 \f
13036 (define_insn "trap"
13037 [(trap_if (const_int 1) (const_int 0))]
13038 ""
13039 "trap"
13040 [(set_attr "type" "trap")])
13041
13042 (define_expand "ctrap<mode>4"
13043 [(trap_if (match_operator 0 "ordered_comparison_operator"
13044 [(match_operand:GPR 1 "register_operand")
13045 (match_operand:GPR 2 "reg_or_short_operand")])
13046 (match_operand 3 "zero_constant" ""))]
13047 ""
13048 "")
13049
13050 (define_insn ""
13051 [(trap_if (match_operator 0 "ordered_comparison_operator"
13052 [(match_operand:GPR 1 "register_operand" "r")
13053 (match_operand:GPR 2 "reg_or_short_operand" "rI")])
13054 (const_int 0))]
13055 ""
13056 "t<wd>%V0%I2 %1,%2"
13057 [(set_attr "type" "trap")])
13058 \f
13059 ;; Insns related to generating the function prologue and epilogue.
13060
13061 (define_expand "prologue"
13062 [(use (const_int 0))]
13063 ""
13064 {
13065 rs6000_emit_prologue ();
13066 if (!TARGET_SCHED_PROLOG)
13067 emit_insn (gen_blockage ());
13068 DONE;
13069 })
13070
13071 (define_insn "*movesi_from_cr_one"
13072 [(match_parallel 0 "mfcr_operation"
13073 [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
13074 (unspec:SI [(match_operand:CC 2 "cc_reg_operand" "y")
13075 (match_operand 3 "immediate_operand" "n")]
13076 UNSPEC_MOVESI_FROM_CR))])]
13077 "TARGET_MFCRF"
13078 {
13079 int mask = 0;
13080 int i;
13081 for (i = 0; i < XVECLEN (operands[0], 0); i++)
13082 {
13083 mask = INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
13084 operands[4] = GEN_INT (mask);
13085 output_asm_insn ("mfcr %1,%4", operands);
13086 }
13087 return "";
13088 }
13089 [(set_attr "type" "mfcrf")])
13090
13091 ;; Don't include the volatile CRs since their values are not used wrt CR save
13092 ;; in the prologue and doing so prevents shrink-wrapping because we can't move the
13093 ;; prologue past an insn (early exit test) that defines a register used in the
13094 ;; prologue.
13095 (define_insn "prologue_movesi_from_cr"
13096 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
13097 (unspec:SI [(reg:CC CR2_REGNO) (reg:CC CR3_REGNO)
13098 (reg:CC CR4_REGNO)]
13099 UNSPEC_MOVESI_FROM_CR))]
13100 ""
13101 "mfcr %0"
13102 [(set_attr "type" "mfcr")])
13103
13104 (define_insn "*crsave"
13105 [(match_parallel 0 "crsave_operation"
13106 [(set (match_operand:SI 1 "memory_operand" "=m")
13107 (match_operand:SI 2 "gpc_reg_operand" "r"))])]
13108 ""
13109 "stw %2,%1"
13110 [(set_attr "type" "store")])
13111
13112 (define_insn "*stmw"
13113 [(match_parallel 0 "stmw_operation"
13114 [(set (match_operand:SI 1 "memory_operand" "=m")
13115 (match_operand:SI 2 "gpc_reg_operand" "r"))])]
13116 "TARGET_MULTIPLE"
13117 "stmw %2,%1"
13118 [(set_attr "type" "store")
13119 (set_attr "update" "yes")
13120 (set_attr "indexed" "yes")])
13121
13122 ; The following comment applies to:
13123 ; save_gpregs_*
13124 ; save_fpregs_*
13125 ; restore_gpregs*
13126 ; return_and_restore_gpregs*
13127 ; return_and_restore_fpregs*
13128 ; return_and_restore_fpregs_aix*
13129 ;
13130 ; The out-of-line save / restore functions expects one input argument.
13131 ; Since those are not standard call_insn's, we must avoid using
13132 ; MATCH_OPERAND for that argument. That way the register rename
13133 ; optimization will not try to rename this register.
13134 ; Each pattern is repeated for each possible register number used in
13135 ; various ABIs (r11, r1, and for some functions r12)
13136
13137 (define_insn "*save_gpregs_<mode>_r11"
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 11))
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_gpregs_<mode>_r12"
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 12))
13153 (set (match_operand:P 2 "memory_operand" "=m")
13154 (match_operand:P 3 "gpc_reg_operand" "r"))])]
13155 ""
13156 "bl %1"
13157 [(set_attr "type" "branch")])
13158
13159 (define_insn "*save_gpregs_<mode>_r1"
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 1))
13164 (set (match_operand:P 2 "memory_operand" "=m")
13165 (match_operand:P 3 "gpc_reg_operand" "r"))])]
13166 ""
13167 "bl %1"
13168 [(set_attr "type" "branch")])
13169
13170 (define_insn "*save_fpregs_<mode>_r11"
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 11))
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 (define_insn "*save_fpregs_<mode>_r12"
13182 [(match_parallel 0 "any_parallel_operand"
13183 [(clobber (reg:P LR_REGNO))
13184 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13185 (use (reg:P 12))
13186 (set (match_operand:DF 2 "memory_operand" "=m")
13187 (match_operand:DF 3 "gpc_reg_operand" "d"))])]
13188 ""
13189 "bl %1"
13190 [(set_attr "type" "branch")])
13191
13192 (define_insn "*save_fpregs_<mode>_r1"
13193 [(match_parallel 0 "any_parallel_operand"
13194 [(clobber (reg:P LR_REGNO))
13195 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13196 (use (reg:P 1))
13197 (set (match_operand:DF 2 "memory_operand" "=m")
13198 (match_operand:DF 3 "gpc_reg_operand" "d"))])]
13199 ""
13200 "bl %1"
13201 [(set_attr "type" "branch")])
13202
13203 ; This is to explain that changes to the stack pointer should
13204 ; not be moved over loads from or stores to stack memory.
13205 (define_insn "stack_tie"
13206 [(match_parallel 0 "tie_operand"
13207 [(set (mem:BLK (reg 1)) (const_int 0))])]
13208 ""
13209 ""
13210 [(set_attr "length" "0")])
13211
13212 ; Some 32-bit ABIs do not have a red zone, so the stack deallocation has to
13213 ; stay behind all restores from the stack, it cannot be reordered to before
13214 ; one. See PR77687. This insn is an add or mr, and a memory clobber.
13215 (define_insn "stack_restore_tie"
13216 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
13217 (plus:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
13218 (match_operand:SI 2 "reg_or_cint_operand" "O,rI")))
13219 (set (mem:BLK (scratch)) (const_int 0))]
13220 "TARGET_32BIT"
13221 "@
13222 mr %0,%1
13223 add%I2 %0,%1,%2"
13224 [(set_attr "type" "*,add")])
13225
13226 (define_expand "epilogue"
13227 [(use (const_int 0))]
13228 ""
13229 {
13230 if (!TARGET_SCHED_PROLOG)
13231 emit_insn (gen_blockage ());
13232 rs6000_emit_epilogue (EPILOGUE_TYPE_NORMAL);
13233 DONE;
13234 })
13235
13236 ; On some processors, doing the mtcrf one CC register at a time is
13237 ; faster (like on the 604e). On others, doing them all at once is
13238 ; faster; for instance, on the 601 and 750.
13239
13240 (define_expand "movsi_to_cr_one"
13241 [(set (match_operand:CC 0 "cc_reg_operand")
13242 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand")
13243 (match_dup 2)] UNSPEC_MOVESI_TO_CR))]
13244 ""
13245 "operands[2] = GEN_INT (1 << (7 - (REGNO (operands[0]) - CR0_REGNO)));")
13246
13247 (define_insn "*movsi_to_cr"
13248 [(match_parallel 0 "mtcrf_operation"
13249 [(set (match_operand:CC 1 "cc_reg_operand" "=y")
13250 (unspec:CC [(match_operand:SI 2 "gpc_reg_operand" "r")
13251 (match_operand 3 "immediate_operand" "n")]
13252 UNSPEC_MOVESI_TO_CR))])]
13253 ""
13254 {
13255 int mask = 0;
13256 int i;
13257 for (i = 0; i < XVECLEN (operands[0], 0); i++)
13258 mask |= INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
13259 operands[4] = GEN_INT (mask);
13260 return "mtcrf %4,%2";
13261 }
13262 [(set_attr "type" "mtcr")])
13263
13264 (define_insn "*mtcrfsi"
13265 [(set (match_operand:CC 0 "cc_reg_operand" "=y")
13266 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
13267 (match_operand 2 "immediate_operand" "n")]
13268 UNSPEC_MOVESI_TO_CR))]
13269 "REG_P (operands[0])
13270 && CR_REGNO_P (REGNO (operands[0]))
13271 && CONST_INT_P (operands[2])
13272 && INTVAL (operands[2]) == 1 << (7 - (REGNO (operands[0]) - CR0_REGNO))"
13273 "mtcrf %R0,%1"
13274 [(set_attr "type" "mtcr")])
13275
13276 ; The load-multiple instructions have similar properties.
13277 ; Note that "load_multiple" is a name known to the machine-independent
13278 ; code that actually corresponds to the PowerPC load-string.
13279
13280 (define_insn "*lmw"
13281 [(match_parallel 0 "lmw_operation"
13282 [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
13283 (match_operand:SI 2 "memory_operand" "m"))])]
13284 "TARGET_MULTIPLE"
13285 "lmw %1,%2"
13286 [(set_attr "type" "load")
13287 (set_attr "update" "yes")
13288 (set_attr "indexed" "yes")
13289 (set_attr "cell_micro" "always")])
13290
13291 ; FIXME: "any_parallel_operand" is a bit flexible...
13292
13293 ; The following comment applies to:
13294 ; save_gpregs_*
13295 ; save_fpregs_*
13296 ; restore_gpregs*
13297 ; return_and_restore_gpregs*
13298 ; return_and_restore_fpregs*
13299 ; return_and_restore_fpregs_aix*
13300 ;
13301 ; The out-of-line save / restore functions expects one input argument.
13302 ; Since those are not standard call_insn's, we must avoid using
13303 ; MATCH_OPERAND for that argument. That way the register rename
13304 ; optimization will not try to rename this register.
13305 ; Each pattern is repeated for each possible register number used in
13306 ; various ABIs (r11, r1, and for some functions r12)
13307
13308 (define_insn "*restore_gpregs_<mode>_r11"
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 11))
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 "*restore_gpregs_<mode>_r12"
13320 [(match_parallel 0 "any_parallel_operand"
13321 [(clobber (reg:P LR_REGNO))
13322 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13323 (use (reg:P 12))
13324 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13325 (match_operand:P 3 "memory_operand" "m"))])]
13326 ""
13327 "bl %1"
13328 [(set_attr "type" "branch")])
13329
13330 (define_insn "*restore_gpregs_<mode>_r1"
13331 [(match_parallel 0 "any_parallel_operand"
13332 [(clobber (reg:P LR_REGNO))
13333 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13334 (use (reg:P 1))
13335 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13336 (match_operand:P 3 "memory_operand" "m"))])]
13337 ""
13338 "bl %1"
13339 [(set_attr "type" "branch")])
13340
13341 (define_insn "*return_and_restore_gpregs_<mode>_r11"
13342 [(match_parallel 0 "any_parallel_operand"
13343 [(return)
13344 (clobber (reg:P LR_REGNO))
13345 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13346 (use (reg:P 11))
13347 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13348 (match_operand:P 3 "memory_operand" "m"))])]
13349 ""
13350 "b %1"
13351 [(set_attr "type" "branch")])
13352
13353 (define_insn "*return_and_restore_gpregs_<mode>_r12"
13354 [(match_parallel 0 "any_parallel_operand"
13355 [(return)
13356 (clobber (reg:P LR_REGNO))
13357 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13358 (use (reg:P 12))
13359 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13360 (match_operand:P 3 "memory_operand" "m"))])]
13361 ""
13362 "b %1"
13363 [(set_attr "type" "branch")])
13364
13365 (define_insn "*return_and_restore_gpregs_<mode>_r1"
13366 [(match_parallel 0 "any_parallel_operand"
13367 [(return)
13368 (clobber (reg:P LR_REGNO))
13369 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13370 (use (reg:P 1))
13371 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13372 (match_operand:P 3 "memory_operand" "m"))])]
13373 ""
13374 "b %1"
13375 [(set_attr "type" "branch")])
13376
13377 (define_insn "*return_and_restore_fpregs_<mode>_r11"
13378 [(match_parallel 0 "any_parallel_operand"
13379 [(return)
13380 (clobber (reg:P LR_REGNO))
13381 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13382 (use (reg:P 11))
13383 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13384 (match_operand:DF 3 "memory_operand" "m"))])]
13385 ""
13386 "b %1"
13387 [(set_attr "type" "branch")])
13388
13389 (define_insn "*return_and_restore_fpregs_<mode>_r12"
13390 [(match_parallel 0 "any_parallel_operand"
13391 [(return)
13392 (clobber (reg:P LR_REGNO))
13393 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13394 (use (reg:P 12))
13395 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13396 (match_operand:DF 3 "memory_operand" "m"))])]
13397 ""
13398 "b %1"
13399 [(set_attr "type" "branch")])
13400
13401 (define_insn "*return_and_restore_fpregs_<mode>_r1"
13402 [(match_parallel 0 "any_parallel_operand"
13403 [(return)
13404 (clobber (reg:P LR_REGNO))
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 (define_insn "*return_and_restore_fpregs_aix_<mode>_r11"
13414 [(match_parallel 0 "any_parallel_operand"
13415 [(return)
13416 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13417 (use (reg:P 11))
13418 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13419 (match_operand:DF 3 "memory_operand" "m"))])]
13420 ""
13421 "b %1"
13422 [(set_attr "type" "branch")])
13423
13424 (define_insn "*return_and_restore_fpregs_aix_<mode>_r1"
13425 [(match_parallel 0 "any_parallel_operand"
13426 [(return)
13427 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13428 (use (reg:P 1))
13429 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13430 (match_operand:DF 3 "memory_operand" "m"))])]
13431 ""
13432 "b %1"
13433 [(set_attr "type" "branch")])
13434
13435 ; This is used in compiling the unwind routines.
13436 (define_expand "eh_return"
13437 [(use (match_operand 0 "general_operand"))]
13438 ""
13439 {
13440 emit_insn (gen_eh_set_lr (Pmode, operands[0]));
13441 DONE;
13442 })
13443
13444 ; We can't expand this before we know where the link register is stored.
13445 (define_insn_and_split "@eh_set_lr_<mode>"
13446 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")] UNSPECV_EH_RR)
13447 (clobber (match_scratch:P 1 "=&b"))]
13448 ""
13449 "#"
13450 "reload_completed"
13451 [(const_int 0)]
13452 {
13453 rs6000_emit_eh_reg_restore (operands[0], operands[1]);
13454 DONE;
13455 })
13456
13457 (define_insn "prefetch"
13458 [(prefetch (match_operand 0 "indexed_or_indirect_address" "a")
13459 (match_operand:SI 1 "const_int_operand" "n")
13460 (match_operand:SI 2 "const_int_operand" "n"))]
13461 ""
13462 {
13463
13464
13465 /* dcbtstt, dcbtt and TH=0b10000 support starts with ISA 2.06 (Power7).
13466 AIX does not support the dcbtstt and dcbtt extended mnemonics.
13467 The AIX assembler does not support the three operand form of dcbt
13468 and dcbtst on Power 7 (-mpwr7). */
13469 int inst_select = INTVAL (operands[2]) || !TARGET_DIRECT_MOVE;
13470
13471 if (REG_P (operands[0]))
13472 {
13473 if (INTVAL (operands[1]) == 0)
13474 return inst_select ? "dcbt 0,%0" : "dcbt 0,%0,16";
13475 else
13476 return inst_select ? "dcbtst 0,%0" : "dcbtst 0,%0,16";
13477 }
13478 else
13479 {
13480 if (INTVAL (operands[1]) == 0)
13481 return inst_select ? "dcbt %a0" : "dcbt %a0,16";
13482 else
13483 return inst_select ? "dcbtst %a0" : "dcbtst %a0,16";
13484 }
13485 }
13486 [(set_attr "type" "load")])
13487 \f
13488 ;; Handle -fsplit-stack.
13489
13490 (define_expand "split_stack_prologue"
13491 [(const_int 0)]
13492 ""
13493 {
13494 rs6000_expand_split_stack_prologue ();
13495 DONE;
13496 })
13497
13498 (define_expand "load_split_stack_limit"
13499 [(set (match_operand 0)
13500 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))]
13501 ""
13502 {
13503 emit_insn (gen_rtx_SET (operands[0],
13504 gen_rtx_UNSPEC (Pmode,
13505 gen_rtvec (1, const0_rtx),
13506 UNSPEC_STACK_CHECK)));
13507 DONE;
13508 })
13509
13510 (define_insn "load_split_stack_limit_di"
13511 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
13512 (unspec:DI [(const_int 0)] UNSPEC_STACK_CHECK))]
13513 "TARGET_64BIT"
13514 "ld %0,-0x7040(13)"
13515 [(set_attr "type" "load")
13516 (set_attr "update" "no")
13517 (set_attr "indexed" "no")])
13518
13519 (define_insn "load_split_stack_limit_si"
13520 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
13521 (unspec:SI [(const_int 0)] UNSPEC_STACK_CHECK))]
13522 "!TARGET_64BIT"
13523 "lwz %0,-0x7020(2)"
13524 [(set_attr "type" "load")
13525 (set_attr "update" "no")
13526 (set_attr "indexed" "no")])
13527
13528 ;; A return instruction which the middle-end doesn't see.
13529 ;; Use r0 to stop regrename twiddling with lr restore insns emitted
13530 ;; after the call to __morestack.
13531 (define_insn "split_stack_return"
13532 [(unspec_volatile [(reg:SI 0) (reg:SI LR_REGNO)] UNSPECV_SPLIT_STACK_RETURN)]
13533 ""
13534 "blr"
13535 [(set_attr "type" "jmpreg")])
13536
13537 ;; If there are operand 0 bytes available on the stack, jump to
13538 ;; operand 1.
13539 (define_expand "split_stack_space_check"
13540 [(set (match_dup 2)
13541 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
13542 (set (match_dup 3)
13543 (minus (reg STACK_POINTER_REGNUM)
13544 (match_operand 0)))
13545 (set (match_dup 4) (compare:CCUNS (match_dup 3) (match_dup 2)))
13546 (set (pc) (if_then_else
13547 (geu (match_dup 4) (const_int 0))
13548 (label_ref (match_operand 1))
13549 (pc)))]
13550 ""
13551 {
13552 rs6000_split_stack_space_check (operands[0], operands[1]);
13553 DONE;
13554 })
13555 \f
13556 (define_insn "bpermd_<mode>"
13557 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
13558 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "r")
13559 (match_operand:P 2 "gpc_reg_operand" "r")] UNSPEC_BPERM))]
13560 "TARGET_POPCNTD"
13561 "bpermd %0,%1,%2"
13562 [(set_attr "type" "popcnt")])
13563
13564 \f
13565 ;; Builtin fma support. Handle
13566 ;; Note that the conditions for expansion are in the FMA_F iterator.
13567
13568 (define_expand "fma<mode>4"
13569 [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13570 (fma:FMA_F
13571 (match_operand:FMA_F 1 "gpc_reg_operand")
13572 (match_operand:FMA_F 2 "gpc_reg_operand")
13573 (match_operand:FMA_F 3 "gpc_reg_operand")))]
13574 ""
13575 "")
13576
13577 (define_insn "*fma<mode>4_fpr"
13578 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa,wa")
13579 (fma:SFDF
13580 (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,wa,wa")
13581 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa,0")
13582 (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,wa")))]
13583 "TARGET_HARD_FLOAT"
13584 "@
13585 fmadd<s> %0,%1,%2,%3
13586 xsmadda<sd>p %x0,%x1,%x2
13587 xsmaddm<sd>p %x0,%x1,%x3"
13588 [(set_attr "type" "fp")
13589 (set_attr "isa" "*,<Fisa>,<Fisa>")])
13590
13591 ; Altivec only has fma and nfms.
13592 (define_expand "fms<mode>4"
13593 [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13594 (fma:FMA_F
13595 (match_operand:FMA_F 1 "gpc_reg_operand")
13596 (match_operand:FMA_F 2 "gpc_reg_operand")
13597 (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand"))))]
13598 "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13599 "")
13600
13601 (define_insn "*fms<mode>4_fpr"
13602 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa,wa")
13603 (fma:SFDF
13604 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa,wa")
13605 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa,0")
13606 (neg:SFDF (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,wa"))))]
13607 "TARGET_HARD_FLOAT"
13608 "@
13609 fmsub<s> %0,%1,%2,%3
13610 xsmsuba<sd>p %x0,%x1,%x2
13611 xsmsubm<sd>p %x0,%x1,%x3"
13612 [(set_attr "type" "fp")
13613 (set_attr "isa" "*,<Fisa>,<Fisa>")])
13614
13615 ;; If signed zeros are ignored, -(a * b - c) = -a * b + c.
13616 (define_expand "fnma<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 (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand")))))]
13623 "!HONOR_SIGNED_ZEROS (<MODE>mode)"
13624 "")
13625
13626 ;; If signed zeros are ignored, -(a * b + c) = -a * b - c.
13627 (define_expand "fnms<mode>4"
13628 [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13629 (neg:FMA_F
13630 (fma:FMA_F
13631 (match_operand:FMA_F 1 "gpc_reg_operand")
13632 (match_operand:FMA_F 2 "gpc_reg_operand")
13633 (match_operand:FMA_F 3 "gpc_reg_operand"))))]
13634 "!HONOR_SIGNED_ZEROS (<MODE>mode) && !VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13635 "")
13636
13637 ; Not an official optab name, but used from builtins.
13638 (define_expand "nfma<mode>4"
13639 [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13640 (neg:FMA_F
13641 (fma:FMA_F
13642 (match_operand:FMA_F 1 "gpc_reg_operand")
13643 (match_operand:FMA_F 2 "gpc_reg_operand")
13644 (match_operand:FMA_F 3 "gpc_reg_operand"))))]
13645 "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13646 "")
13647
13648 (define_insn "*nfma<mode>4_fpr"
13649 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa,wa")
13650 (neg:SFDF
13651 (fma:SFDF
13652 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa,wa")
13653 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa,0")
13654 (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,wa"))))]
13655 "TARGET_HARD_FLOAT"
13656 "@
13657 fnmadd<s> %0,%1,%2,%3
13658 xsnmadda<sd>p %x0,%x1,%x2
13659 xsnmaddm<sd>p %x0,%x1,%x3"
13660 [(set_attr "type" "fp")
13661 (set_attr "isa" "*,<Fisa>,<Fisa>")])
13662
13663 ; Not an official optab name, but used from builtins.
13664 (define_expand "nfms<mode>4"
13665 [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13666 (neg:FMA_F
13667 (fma:FMA_F
13668 (match_operand:FMA_F 1 "gpc_reg_operand")
13669 (match_operand:FMA_F 2 "gpc_reg_operand")
13670 (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand")))))]
13671 ""
13672 "")
13673
13674 (define_insn "*nfmssf4_fpr"
13675 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa,wa")
13676 (neg:SFDF
13677 (fma:SFDF
13678 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa,wa")
13679 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa,0")
13680 (neg:SFDF
13681 (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,wa")))))]
13682 "TARGET_HARD_FLOAT"
13683 "@
13684 fnmsub<s> %0,%1,%2,%3
13685 xsnmsuba<sd>p %x0,%x1,%x2
13686 xsnmsubm<sd>p %x0,%x1,%x3"
13687 [(set_attr "type" "fp")
13688 (set_attr "isa" "*,<Fisa>,<Fisa>")])
13689 \f
13690 (define_expand "rs6000_get_timebase"
13691 [(use (match_operand:DI 0 "gpc_reg_operand"))]
13692 ""
13693 {
13694 if (TARGET_POWERPC64)
13695 emit_insn (gen_rs6000_mftb_di (operands[0]));
13696 else
13697 emit_insn (gen_rs6000_get_timebase_ppc32 (operands[0]));
13698 DONE;
13699 })
13700
13701 (define_insn "rs6000_get_timebase_ppc32"
13702 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
13703 (unspec_volatile:DI [(const_int 0)] UNSPECV_MFTB))
13704 (clobber (match_scratch:SI 1 "=r"))
13705 (clobber (match_scratch:CC 2 "=y"))]
13706 "!TARGET_POWERPC64"
13707 {
13708 if (WORDS_BIG_ENDIAN)
13709 if (TARGET_MFCRF)
13710 {
13711 return "mfspr %0,269\;"
13712 "mfspr %L0,268\;"
13713 "mfspr %1,269\;"
13714 "cmpw %2,%0,%1\;"
13715 "bne- %2,$-16";
13716 }
13717 else
13718 {
13719 return "mftbu %0\;"
13720 "mftb %L0\;"
13721 "mftbu %1\;"
13722 "cmpw %2,%0,%1\;"
13723 "bne- %2,$-16";
13724 }
13725 else
13726 if (TARGET_MFCRF)
13727 {
13728 return "mfspr %L0,269\;"
13729 "mfspr %0,268\;"
13730 "mfspr %1,269\;"
13731 "cmpw %2,%L0,%1\;"
13732 "bne- %2,$-16";
13733 }
13734 else
13735 {
13736 return "mftbu %L0\;"
13737 "mftb %0\;"
13738 "mftbu %1\;"
13739 "cmpw %2,%L0,%1\;"
13740 "bne- %2,$-16";
13741 }
13742 }
13743 [(set_attr "length" "20")])
13744
13745 (define_insn "rs6000_mftb_<mode>"
13746 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
13747 (unspec_volatile:GPR [(const_int 0)] UNSPECV_MFTB))]
13748 ""
13749 {
13750 if (TARGET_MFCRF)
13751 return "mfspr %0,268";
13752 else
13753 return "mftb %0";
13754 })
13755
13756 \f
13757 ;; The ISA 3.0 mffsl instruction is a lower latency instruction
13758 ;; for reading bits [29:31], [45:51] and [56:63] of the FPSCR.
13759 (define_insn "rs6000_mffsl_hw"
13760 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
13761 (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFSL))]
13762 "TARGET_HARD_FLOAT"
13763 "mffsl %0")
13764
13765 (define_expand "rs6000_mffsl"
13766 [(set (match_operand:DF 0 "gpc_reg_operand")
13767 (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFSL))]
13768 "TARGET_HARD_FLOAT"
13769 {
13770 /* If the low latency mffsl instruction (ISA 3.0) is available use it,
13771 otherwise fall back to the older mffs instruction to emulate the mffsl
13772 instruction. */
13773
13774 if (!TARGET_P9_MISC)
13775 {
13776 rtx tmp1 = gen_reg_rtx (DFmode);
13777
13778 /* The mffs instruction reads the entire FPSCR. Emulate the mffsl
13779 instruction using the mffs instruction and masking the result. */
13780 emit_insn (gen_rs6000_mffs (tmp1));
13781
13782 rtx tmp1di = simplify_gen_subreg (DImode, tmp1, DFmode, 0);
13783 rtx tmp2 = gen_reg_rtx (DImode);
13784 emit_insn (gen_anddi3 (tmp2, tmp1di, GEN_INT (0x70007f0ffLL)));
13785
13786 rtx tmp2df = simplify_gen_subreg (DFmode, tmp2, DImode, 0);
13787 emit_move_insn (operands[0], tmp2df);
13788 DONE;
13789 }
13790
13791 emit_insn (gen_rs6000_mffsl_hw (operands[0]));
13792 DONE;
13793 })
13794
13795 (define_insn "rs6000_mffs"
13796 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
13797 (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFS))]
13798 "TARGET_HARD_FLOAT"
13799 "mffs %0")
13800
13801 (define_insn "rs6000_mtfsf"
13802 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "i")
13803 (match_operand:DF 1 "gpc_reg_operand" "d")]
13804 UNSPECV_MTFSF)]
13805 "TARGET_HARD_FLOAT"
13806 "mtfsf %0,%1")
13807
13808 (define_insn "rs6000_mtfsf_hi"
13809 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "n")
13810 (match_operand:DF 1 "gpc_reg_operand" "d")]
13811 UNSPECV_MTFSF_HI)]
13812 "TARGET_HARD_FLOAT"
13813 "mtfsf %0,%1,0,1")
13814
13815 \f
13816 ;; Power8 fusion support for fusing an addis instruction with a D-form load of
13817 ;; a GPR. The addis instruction must be adjacent to the load, and use the same
13818 ;; register that is being loaded. The fused ops must be physically adjacent.
13819
13820 ;; On Power8 GPR loads, we try to use the register that is being load. The
13821 ;; peephole2 then gathers any other fused possibilities that it can find after
13822 ;; register allocation. If power9 fusion is selected, we also fuse floating
13823 ;; point loads/stores.
13824
13825 ;; Find cases where the addis that feeds into a load instruction is either used
13826 ;; once or is the same as the target register, and replace it with the fusion
13827 ;; insn
13828
13829 (define_peephole2
13830 [(set (match_operand:P 0 "base_reg_operand")
13831 (match_operand:P 1 "fusion_gpr_addis"))
13832 (set (match_operand:INT1 2 "base_reg_operand")
13833 (match_operand:INT1 3 "fusion_gpr_mem_load"))]
13834 "TARGET_P8_FUSION
13835 && fusion_gpr_load_p (operands[0], operands[1], operands[2],
13836 operands[3])"
13837 [(const_int 0)]
13838 {
13839 expand_fusion_gpr_load (operands);
13840 DONE;
13841 })
13842
13843 ;; Fusion insn, created by the define_peephole2 above (and eventually by
13844 ;; reload)
13845
13846 (define_insn "*fusion_gpr_load_<mode>"
13847 [(set (match_operand:INT1 0 "base_reg_operand" "=b")
13848 (unspec:INT1 [(match_operand:INT1 1 "fusion_addis_mem_combo_load" "wF")]
13849 UNSPEC_FUSION_GPR))]
13850 "TARGET_P8_FUSION"
13851 {
13852 return emit_fusion_gpr_load (operands[0], operands[1]);
13853 }
13854 [(set_attr "type" "load")
13855 (set_attr "length" "8")])
13856
13857 \f
13858 ;; Optimize cases where we want to do a D-form load (register+offset) on
13859 ;; ISA 2.06/2.07 to an Altivec register, and the register allocator
13860 ;; has generated:
13861 ;; LFD 0,32(3)
13862 ;; XXLOR 32,0,0
13863 ;;
13864 ;; and we change this to:
13865 ;; LI 0,32
13866 ;; LXSDX 32,3,9
13867
13868 (define_peephole2
13869 [(match_scratch:P 0 "b")
13870 (set (match_operand:ALTIVEC_DFORM 1 "fpr_reg_operand")
13871 (match_operand:ALTIVEC_DFORM 2 "simple_offsettable_mem_operand"))
13872 (set (match_operand:ALTIVEC_DFORM 3 "altivec_register_operand")
13873 (match_dup 1))]
13874 "TARGET_VSX && !TARGET_P9_VECTOR && peep2_reg_dead_p (2, operands[1])"
13875 [(set (match_dup 0)
13876 (match_dup 4))
13877 (set (match_dup 3)
13878 (match_dup 5))]
13879 {
13880 rtx tmp_reg = operands[0];
13881 rtx mem = operands[2];
13882 rtx addr = XEXP (mem, 0);
13883 rtx add_op0, add_op1, new_addr;
13884
13885 gcc_assert (GET_CODE (addr) == PLUS || GET_CODE (addr) == LO_SUM);
13886 add_op0 = XEXP (addr, 0);
13887 add_op1 = XEXP (addr, 1);
13888 gcc_assert (REG_P (add_op0));
13889 new_addr = gen_rtx_PLUS (Pmode, add_op0, tmp_reg);
13890
13891 operands[4] = add_op1;
13892 operands[5] = change_address (mem, <ALTIVEC_DFORM:MODE>mode, new_addr);
13893 })
13894
13895 ;; Optimize cases were want to do a D-form store on ISA 2.06/2.07 from an
13896 ;; Altivec register, and the register allocator has generated:
13897 ;; XXLOR 0,32,32
13898 ;; STFD 0,32(3)
13899 ;;
13900 ;; and we change this to:
13901 ;; LI 0,32
13902 ;; STXSDX 32,3,9
13903
13904 (define_peephole2
13905 [(match_scratch:P 0 "b")
13906 (set (match_operand:ALTIVEC_DFORM 1 "fpr_reg_operand")
13907 (match_operand:ALTIVEC_DFORM 2 "altivec_register_operand"))
13908 (set (match_operand:ALTIVEC_DFORM 3 "simple_offsettable_mem_operand")
13909 (match_dup 1))]
13910 "TARGET_VSX && !TARGET_P9_VECTOR && peep2_reg_dead_p (2, operands[1])"
13911 [(set (match_dup 0)
13912 (match_dup 4))
13913 (set (match_dup 5)
13914 (match_dup 2))]
13915 {
13916 rtx tmp_reg = operands[0];
13917 rtx mem = operands[3];
13918 rtx addr = XEXP (mem, 0);
13919 rtx add_op0, add_op1, new_addr;
13920
13921 gcc_assert (GET_CODE (addr) == PLUS || GET_CODE (addr) == LO_SUM);
13922 add_op0 = XEXP (addr, 0);
13923 add_op1 = XEXP (addr, 1);
13924 gcc_assert (REG_P (add_op0));
13925 new_addr = gen_rtx_PLUS (Pmode, add_op0, tmp_reg);
13926
13927 operands[4] = add_op1;
13928 operands[5] = change_address (mem, <ALTIVEC_DFORM:MODE>mode, new_addr);
13929 })
13930
13931 \f
13932 ;; Miscellaneous ISA 2.06 (power7) instructions
13933 (define_insn "addg6s"
13934 [(set (match_operand:SI 0 "register_operand" "=r")
13935 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
13936 (match_operand:SI 2 "register_operand" "r")]
13937 UNSPEC_ADDG6S))]
13938 "TARGET_POPCNTD"
13939 "addg6s %0,%1,%2"
13940 [(set_attr "type" "integer")])
13941
13942 (define_insn "cdtbcd"
13943 [(set (match_operand:SI 0 "register_operand" "=r")
13944 (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
13945 UNSPEC_CDTBCD))]
13946 "TARGET_POPCNTD"
13947 "cdtbcd %0,%1"
13948 [(set_attr "type" "integer")])
13949
13950 (define_insn "cbcdtd"
13951 [(set (match_operand:SI 0 "register_operand" "=r")
13952 (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
13953 UNSPEC_CBCDTD))]
13954 "TARGET_POPCNTD"
13955 "cbcdtd %0,%1"
13956 [(set_attr "type" "integer")])
13957
13958 (define_int_iterator UNSPEC_DIV_EXTEND [UNSPEC_DIVE
13959 UNSPEC_DIVEU])
13960
13961 (define_int_attr div_extend [(UNSPEC_DIVE "e")
13962 (UNSPEC_DIVEU "eu")])
13963
13964 (define_insn "div<div_extend>_<mode>"
13965 [(set (match_operand:GPR 0 "register_operand" "=r")
13966 (unspec:GPR [(match_operand:GPR 1 "register_operand" "r")
13967 (match_operand:GPR 2 "register_operand" "r")]
13968 UNSPEC_DIV_EXTEND))]
13969 "TARGET_POPCNTD"
13970 "div<wd><div_extend> %0,%1,%2"
13971 [(set_attr "type" "div")
13972 (set_attr "size" "<bits>")])
13973
13974 \f
13975 ;; Pack/unpack 128-bit floating point types that take 2 scalar registers
13976
13977 ; Type of the 64-bit part when packing/unpacking 128-bit floating point types
13978 (define_mode_attr FP128_64 [(TF "DF")
13979 (IF "DF")
13980 (TD "DI")
13981 (KF "DI")])
13982
13983 (define_expand "unpack<mode>"
13984 [(set (match_operand:<FP128_64> 0 "nonimmediate_operand")
13985 (unspec:<FP128_64>
13986 [(match_operand:FMOVE128 1 "register_operand")
13987 (match_operand:QI 2 "const_0_to_1_operand")]
13988 UNSPEC_UNPACK_128BIT))]
13989 "FLOAT128_2REG_P (<MODE>mode)"
13990 "")
13991
13992 (define_insn_and_split "unpack<mode>_dm"
13993 [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m,d,r,m")
13994 (unspec:<FP128_64>
13995 [(match_operand:FMOVE128 1 "register_operand" "d,d,r,d,r")
13996 (match_operand:QI 2 "const_0_to_1_operand" "i,i,i,i,i")]
13997 UNSPEC_UNPACK_128BIT))]
13998 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE && FLOAT128_2REG_P (<MODE>mode)"
13999 "#"
14000 "&& reload_completed"
14001 [(set (match_dup 0) (match_dup 3))]
14002 {
14003 unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
14004
14005 if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
14006 {
14007 emit_note (NOTE_INSN_DELETED);
14008 DONE;
14009 }
14010
14011 operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
14012 }
14013 [(set_attr "type" "fp,fpstore,mtvsr,mfvsr,store")])
14014
14015 (define_insn_and_split "unpack<mode>_nodm"
14016 [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m")
14017 (unspec:<FP128_64>
14018 [(match_operand:FMOVE128 1 "register_operand" "d,d")
14019 (match_operand:QI 2 "const_0_to_1_operand" "i,i")]
14020 UNSPEC_UNPACK_128BIT))]
14021 "(!TARGET_POWERPC64 || !TARGET_DIRECT_MOVE) && FLOAT128_2REG_P (<MODE>mode)"
14022 "#"
14023 "&& reload_completed"
14024 [(set (match_dup 0) (match_dup 3))]
14025 {
14026 unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
14027
14028 if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
14029 {
14030 emit_note (NOTE_INSN_DELETED);
14031 DONE;
14032 }
14033
14034 operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
14035 }
14036 [(set_attr "type" "fp,fpstore")])
14037
14038 (define_insn_and_split "pack<mode>"
14039 [(set (match_operand:FMOVE128 0 "register_operand" "=&d")
14040 (unspec:FMOVE128
14041 [(match_operand:<FP128_64> 1 "register_operand" "d")
14042 (match_operand:<FP128_64> 2 "register_operand" "d")]
14043 UNSPEC_PACK_128BIT))]
14044 "FLOAT128_2REG_P (<MODE>mode)"
14045 "#"
14046 "&& reload_completed"
14047 [(set (match_dup 3) (match_dup 1))
14048 (set (match_dup 4) (match_dup 2))]
14049 {
14050 unsigned dest_hi = REGNO (operands[0]);
14051 unsigned dest_lo = dest_hi + 1;
14052
14053 gcc_assert (!IN_RANGE (REGNO (operands[1]), dest_hi, dest_lo));
14054 gcc_assert (!IN_RANGE (REGNO (operands[2]), dest_hi, dest_lo));
14055
14056 operands[3] = gen_rtx_REG (<FP128_64>mode, dest_hi);
14057 operands[4] = gen_rtx_REG (<FP128_64>mode, dest_lo);
14058 }
14059 [(set_attr "type" "fp")
14060 (set_attr "length" "8")])
14061
14062 (define_insn "unpack<mode>"
14063 [(set (match_operand:DI 0 "register_operand" "=wa,wa")
14064 (unspec:DI [(match_operand:FMOVE128_VSX 1 "register_operand" "0,wa")
14065 (match_operand:QI 2 "const_0_to_1_operand" "O,i")]
14066 UNSPEC_UNPACK_128BIT))]
14067 "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)"
14068 {
14069 if (REGNO (operands[0]) == REGNO (operands[1]) && INTVAL (operands[2]) == 0)
14070 return ASM_COMMENT_START " xxpermdi to same register";
14071
14072 operands[3] = GEN_INT (INTVAL (operands[2]) == 0 ? 0 : 3);
14073 return "xxpermdi %x0,%x1,%x1,%3";
14074 }
14075 [(set_attr "type" "vecperm")])
14076
14077 (define_insn "pack<mode>"
14078 [(set (match_operand:FMOVE128_VSX 0 "register_operand" "=wa")
14079 (unspec:FMOVE128_VSX
14080 [(match_operand:DI 1 "register_operand" "wa")
14081 (match_operand:DI 2 "register_operand" "wa")]
14082 UNSPEC_PACK_128BIT))]
14083 "TARGET_VSX"
14084 "xxpermdi %x0,%x1,%x2,0"
14085 [(set_attr "type" "vecperm")])
14086
14087
14088 \f
14089 ;; ISA 2.08 IEEE 128-bit floating point support.
14090
14091 (define_insn "add<mode>3"
14092 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14093 (plus:IEEE128
14094 (match_operand:IEEE128 1 "altivec_register_operand" "v")
14095 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14096 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14097 "xsaddqp %0,%1,%2"
14098 [(set_attr "type" "vecfloat")
14099 (set_attr "size" "128")])
14100
14101 (define_insn "sub<mode>3"
14102 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14103 (minus:IEEE128
14104 (match_operand:IEEE128 1 "altivec_register_operand" "v")
14105 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14106 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14107 "xssubqp %0,%1,%2"
14108 [(set_attr "type" "vecfloat")
14109 (set_attr "size" "128")])
14110
14111 (define_insn "mul<mode>3"
14112 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14113 (mult:IEEE128
14114 (match_operand:IEEE128 1 "altivec_register_operand" "v")
14115 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14116 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14117 "xsmulqp %0,%1,%2"
14118 [(set_attr "type" "qmul")
14119 (set_attr "size" "128")])
14120
14121 (define_insn "div<mode>3"
14122 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14123 (div:IEEE128
14124 (match_operand:IEEE128 1 "altivec_register_operand" "v")
14125 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14126 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14127 "xsdivqp %0,%1,%2"
14128 [(set_attr "type" "vecdiv")
14129 (set_attr "size" "128")])
14130
14131 (define_insn "sqrt<mode>2"
14132 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14133 (sqrt:IEEE128
14134 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14135 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14136 "xssqrtqp %0,%1"
14137 [(set_attr "type" "vecdiv")
14138 (set_attr "size" "128")])
14139
14140 (define_expand "copysign<mode>3"
14141 [(use (match_operand:IEEE128 0 "altivec_register_operand"))
14142 (use (match_operand:IEEE128 1 "altivec_register_operand"))
14143 (use (match_operand:IEEE128 2 "altivec_register_operand"))]
14144 "FLOAT128_IEEE_P (<MODE>mode)"
14145 {
14146 if (TARGET_FLOAT128_HW)
14147 emit_insn (gen_copysign<mode>3_hard (operands[0], operands[1],
14148 operands[2]));
14149 else
14150 emit_insn (gen_copysign<mode>3_soft (operands[0], operands[1],
14151 operands[2]));
14152 DONE;
14153 })
14154
14155 (define_insn "copysign<mode>3_hard"
14156 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14157 (unspec:IEEE128
14158 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14159 (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14160 UNSPEC_COPYSIGN))]
14161 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14162 "xscpsgnqp %0,%2,%1"
14163 [(set_attr "type" "vecmove")
14164 (set_attr "size" "128")])
14165
14166 (define_insn "copysign<mode>3_soft"
14167 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14168 (unspec:IEEE128
14169 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14170 (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14171 UNSPEC_COPYSIGN))
14172 (clobber (match_scratch:IEEE128 3 "=&v"))]
14173 "!TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14174 "xscpsgndp %x3,%x2,%x1\;xxpermdi %x0,%x3,%x1,1"
14175 [(set_attr "type" "veccomplex")
14176 (set_attr "length" "8")])
14177
14178 (define_insn "@neg<mode>2_hw"
14179 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14180 (neg:IEEE128
14181 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14182 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14183 "xsnegqp %0,%1"
14184 [(set_attr "type" "vecmove")
14185 (set_attr "size" "128")])
14186
14187
14188 (define_insn "@abs<mode>2_hw"
14189 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14190 (abs:IEEE128
14191 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14192 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14193 "xsabsqp %0,%1"
14194 [(set_attr "type" "vecmove")
14195 (set_attr "size" "128")])
14196
14197
14198 (define_insn "*nabs<mode>2_hw"
14199 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14200 (neg:IEEE128
14201 (abs:IEEE128
14202 (match_operand:IEEE128 1 "altivec_register_operand" "v"))))]
14203 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14204 "xsnabsqp %0,%1"
14205 [(set_attr "type" "vecmove")
14206 (set_attr "size" "128")])
14207
14208 ;; Initially don't worry about doing fusion
14209 (define_insn "fma<mode>4_hw"
14210 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14211 (fma:IEEE128
14212 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14213 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14214 (match_operand:IEEE128 3 "altivec_register_operand" "0")))]
14215 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14216 "xsmaddqp %0,%1,%2"
14217 [(set_attr "type" "qmul")
14218 (set_attr "size" "128")])
14219
14220 (define_insn "*fms<mode>4_hw"
14221 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14222 (fma:IEEE128
14223 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14224 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14225 (neg:IEEE128
14226 (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
14227 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14228 "xsmsubqp %0,%1,%2"
14229 [(set_attr "type" "qmul")
14230 (set_attr "size" "128")])
14231
14232 (define_insn "*nfma<mode>4_hw"
14233 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14234 (neg:IEEE128
14235 (fma:IEEE128
14236 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14237 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14238 (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
14239 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14240 "xsnmaddqp %0,%1,%2"
14241 [(set_attr "type" "qmul")
14242 (set_attr "size" "128")])
14243
14244 (define_insn "*nfms<mode>4_hw"
14245 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14246 (neg:IEEE128
14247 (fma:IEEE128
14248 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14249 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14250 (neg:IEEE128
14251 (match_operand:IEEE128 3 "altivec_register_operand" "0")))))]
14252 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14253 "xsnmsubqp %0,%1,%2"
14254 [(set_attr "type" "qmul")
14255 (set_attr "size" "128")])
14256
14257 (define_insn "extend<SFDF:mode><IEEE128:mode>2_hw"
14258 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14259 (float_extend:IEEE128
14260 (match_operand:SFDF 1 "altivec_register_operand" "v")))]
14261 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14262 "xscvdpqp %0,%1"
14263 [(set_attr "type" "vecfloat")
14264 (set_attr "size" "128")])
14265
14266 ;; Conversion between KFmode and TFmode if TFmode is ieee 128-bit floating
14267 ;; point is a simple copy.
14268 (define_insn_and_split "extendkftf2"
14269 [(set (match_operand:TF 0 "vsx_register_operand" "=wa,?wa")
14270 (float_extend:TF (match_operand:KF 1 "vsx_register_operand" "0,wa")))]
14271 "TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD"
14272 "@
14273 #
14274 xxlor %x0,%x1,%x1"
14275 "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
14276 [(const_int 0)]
14277 {
14278 emit_note (NOTE_INSN_DELETED);
14279 DONE;
14280 }
14281 [(set_attr "type" "*,veclogical")
14282 (set_attr "length" "0,4")])
14283
14284 (define_insn_and_split "trunctfkf2"
14285 [(set (match_operand:KF 0 "vsx_register_operand" "=wa,?wa")
14286 (float_extend:KF (match_operand:TF 1 "vsx_register_operand" "0,wa")))]
14287 "TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD"
14288 "@
14289 #
14290 xxlor %x0,%x1,%x1"
14291 "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
14292 [(const_int 0)]
14293 {
14294 emit_note (NOTE_INSN_DELETED);
14295 DONE;
14296 }
14297 [(set_attr "type" "*,veclogical")
14298 (set_attr "length" "0,4")])
14299
14300 (define_insn "trunc<mode>df2_hw"
14301 [(set (match_operand:DF 0 "altivec_register_operand" "=v")
14302 (float_truncate:DF
14303 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14304 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14305 "xscvqpdp %0,%1"
14306 [(set_attr "type" "vecfloat")
14307 (set_attr "size" "128")])
14308
14309 ;; There is no KFmode -> SFmode instruction. Preserve the accuracy by doing
14310 ;; the KFmode -> DFmode conversion using round to odd rather than the normal
14311 ;; conversion
14312 (define_insn_and_split "trunc<mode>sf2_hw"
14313 [(set (match_operand:SF 0 "vsx_register_operand" "=wa")
14314 (float_truncate:SF
14315 (match_operand:IEEE128 1 "altivec_register_operand" "v")))
14316 (clobber (match_scratch:DF 2 "=v"))]
14317 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14318 "#"
14319 "&& 1"
14320 [(set (match_dup 2)
14321 (unspec:DF [(match_dup 1)]
14322 UNSPEC_TRUNC_ROUND_TO_ODD))
14323 (set (match_dup 0)
14324 (float_truncate:SF (match_dup 2)))]
14325 {
14326 if (GET_CODE (operands[2]) == SCRATCH)
14327 operands[2] = gen_reg_rtx (DFmode);
14328 }
14329 [(set_attr "type" "vecfloat")
14330 (set_attr "length" "8")
14331 (set_attr "isa" "p8v")])
14332
14333 ;; Conversion between IEEE 128-bit and integer types
14334
14335 ;; The fix function for DImode and SImode was declared earlier as a
14336 ;; define_expand. It calls into rs6000_expand_float128_convert if we don't
14337 ;; have IEEE 128-bit hardware support. QImode and HImode are not provided
14338 ;; unless we have the IEEE 128-bit hardware.
14339 ;;
14340 ;; Unlike the code for converting SFmode/DFmode to QImode/HImode, we don't have
14341 ;; to provide a GPR target that used direct move and a conversion in the GPR
14342 ;; which works around QImode/HImode not being allowed in vector registers in
14343 ;; ISA 2.07 (power8).
14344 (define_insn "fix<uns>_<IEEE128:mode><SDI:mode>2_hw"
14345 [(set (match_operand:SDI 0 "altivec_register_operand" "=v")
14346 (any_fix:SDI (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14347 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14348 "xscvqp<su><wd>z %0,%1"
14349 [(set_attr "type" "vecfloat")
14350 (set_attr "size" "128")])
14351
14352 (define_insn "fix<uns>_trunc<IEEE128:mode><QHI:mode>2"
14353 [(set (match_operand:QHI 0 "altivec_register_operand" "=v")
14354 (any_fix:QHI
14355 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14356 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14357 "xscvqp<su>wz %0,%1"
14358 [(set_attr "type" "vecfloat")
14359 (set_attr "size" "128")])
14360
14361 ;; Combiner patterns to prevent moving the result of converting an IEEE 128-bit
14362 ;; floating point value to 8/16/32-bit integer to GPR in order to save it.
14363 (define_insn_and_split "*fix<uns>_trunc<IEEE128:mode><QHSI:mode>2_mem"
14364 [(set (match_operand:QHSI 0 "memory_operand" "=Z")
14365 (any_fix:QHSI
14366 (match_operand:IEEE128 1 "altivec_register_operand" "v")))
14367 (clobber (match_scratch:QHSI 2 "=v"))]
14368 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14369 "#"
14370 "&& reload_completed"
14371 [(set (match_dup 2)
14372 (any_fix:QHSI (match_dup 1)))
14373 (set (match_dup 0)
14374 (match_dup 2))])
14375
14376 (define_insn "float_<mode>di2_hw"
14377 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14378 (float:IEEE128 (match_operand:DI 1 "altivec_register_operand" "v")))]
14379 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14380 "xscvsdqp %0,%1"
14381 [(set_attr "type" "vecfloat")
14382 (set_attr "size" "128")])
14383
14384 (define_insn_and_split "float_<mode>si2_hw"
14385 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14386 (float:IEEE128 (match_operand:SI 1 "nonimmediate_operand" "vrZ")))
14387 (clobber (match_scratch:DI 2 "=v"))]
14388 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14389 "#"
14390 "&& 1"
14391 [(set (match_dup 2)
14392 (sign_extend:DI (match_dup 1)))
14393 (set (match_dup 0)
14394 (float:IEEE128 (match_dup 2)))]
14395 {
14396 if (GET_CODE (operands[2]) == SCRATCH)
14397 operands[2] = gen_reg_rtx (DImode);
14398
14399 if (MEM_P (operands[1]))
14400 operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
14401 })
14402
14403 (define_insn_and_split "float<QHI:mode><IEEE128:mode>2"
14404 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v")
14405 (float:IEEE128 (match_operand:QHI 1 "nonimmediate_operand" "v,r,Z")))
14406 (clobber (match_scratch:DI 2 "=X,r,X"))]
14407 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14408 "#"
14409 "&& reload_completed"
14410 [(const_int 0)]
14411 {
14412 rtx dest = operands[0];
14413 rtx src = operands[1];
14414 rtx dest_di = gen_rtx_REG (DImode, REGNO (dest));
14415
14416 if (altivec_register_operand (src, <QHI:MODE>mode))
14417 emit_insn (gen_extend<QHI:mode>di2 (dest_di, src));
14418 else if (int_reg_operand (src, <QHI:MODE>mode))
14419 {
14420 rtx ext_di = operands[2];
14421 emit_insn (gen_extend<QHI:mode>di2 (ext_di, src));
14422 emit_move_insn (dest_di, ext_di);
14423 }
14424 else if (MEM_P (src))
14425 {
14426 rtx dest_qhi = gen_rtx_REG (<QHI:MODE>mode, REGNO (dest));
14427 emit_move_insn (dest_qhi, src);
14428 emit_insn (gen_extend<QHI:mode>di2 (dest_di, dest_qhi));
14429 }
14430 else
14431 gcc_unreachable ();
14432
14433 emit_insn (gen_float_<IEEE128:mode>di2_hw (dest, dest_di));
14434 DONE;
14435 }
14436 [(set_attr "length" "8,12,12")
14437 (set_attr "type" "vecfloat")
14438 (set_attr "size" "128")])
14439
14440 (define_insn "floatuns_<mode>di2_hw"
14441 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14442 (unsigned_float:IEEE128
14443 (match_operand:DI 1 "altivec_register_operand" "v")))]
14444 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14445 "xscvudqp %0,%1"
14446 [(set_attr "type" "vecfloat")
14447 (set_attr "size" "128")])
14448
14449 (define_insn_and_split "floatuns_<mode>si2_hw"
14450 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14451 (unsigned_float:IEEE128
14452 (match_operand:SI 1 "nonimmediate_operand" "vrZ")))
14453 (clobber (match_scratch:DI 2 "=v"))]
14454 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14455 "#"
14456 "&& 1"
14457 [(set (match_dup 2)
14458 (zero_extend:DI (match_dup 1)))
14459 (set (match_dup 0)
14460 (float:IEEE128 (match_dup 2)))]
14461 {
14462 if (GET_CODE (operands[2]) == SCRATCH)
14463 operands[2] = gen_reg_rtx (DImode);
14464
14465 if (MEM_P (operands[1]))
14466 operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
14467 })
14468
14469 (define_insn_and_split "floatuns<QHI:mode><IEEE128:mode>2"
14470 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v")
14471 (unsigned_float:IEEE128
14472 (match_operand:QHI 1 "nonimmediate_operand" "v,r,Z")))
14473 (clobber (match_scratch:DI 2 "=X,r,X"))]
14474 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14475 "#"
14476 "&& reload_completed"
14477 [(const_int 0)]
14478 {
14479 rtx dest = operands[0];
14480 rtx src = operands[1];
14481 rtx dest_di = gen_rtx_REG (DImode, REGNO (dest));
14482
14483 if (altivec_register_operand (src, <QHI:MODE>mode) || MEM_P (src))
14484 emit_insn (gen_zero_extend<QHI:mode>di2 (dest_di, src));
14485 else if (int_reg_operand (src, <QHI:MODE>mode))
14486 {
14487 rtx ext_di = operands[2];
14488 emit_insn (gen_zero_extend<QHI:mode>di2 (ext_di, src));
14489 emit_move_insn (dest_di, ext_di);
14490 }
14491 else
14492 gcc_unreachable ();
14493
14494 emit_insn (gen_floatuns_<IEEE128:mode>di2_hw (dest, dest_di));
14495 DONE;
14496 }
14497 [(set_attr "length" "8,12,8")
14498 (set_attr "type" "vecfloat")
14499 (set_attr "size" "128")])
14500
14501 ;; IEEE 128-bit round to integer built-in functions
14502 (define_insn "floor<mode>2"
14503 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14504 (unspec:IEEE128
14505 [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14506 UNSPEC_FRIM))]
14507 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14508 "xsrqpi 1,%0,%1,3"
14509 [(set_attr "type" "vecfloat")
14510 (set_attr "size" "128")])
14511
14512 (define_insn "ceil<mode>2"
14513 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14514 (unspec:IEEE128
14515 [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14516 UNSPEC_FRIP))]
14517 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14518 "xsrqpi 1,%0,%1,2"
14519 [(set_attr "type" "vecfloat")
14520 (set_attr "size" "128")])
14521
14522 (define_insn "btrunc<mode>2"
14523 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14524 (unspec:IEEE128
14525 [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14526 UNSPEC_FRIZ))]
14527 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14528 "xsrqpi 1,%0,%1,1"
14529 [(set_attr "type" "vecfloat")
14530 (set_attr "size" "128")])
14531
14532 (define_insn "round<mode>2"
14533 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14534 (unspec:IEEE128
14535 [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14536 UNSPEC_FRIN))]
14537 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14538 "xsrqpi 0,%0,%1,0"
14539 [(set_attr "type" "vecfloat")
14540 (set_attr "size" "128")])
14541
14542 ;; IEEE 128-bit instructions with round to odd semantics
14543 (define_insn "add<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_ADD_ROUND_TO_ODD))]
14549 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14550 "xsaddqpo %0,%1,%2"
14551 [(set_attr "type" "vecfloat")
14552 (set_attr "size" "128")])
14553
14554 (define_insn "sub<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_SUB_ROUND_TO_ODD))]
14560 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14561 "xssubqpo %0,%1,%2"
14562 [(set_attr "type" "vecfloat")
14563 (set_attr "size" "128")])
14564
14565 (define_insn "mul<mode>3_odd"
14566 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14567 (unspec:IEEE128
14568 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14569 (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14570 UNSPEC_MUL_ROUND_TO_ODD))]
14571 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14572 "xsmulqpo %0,%1,%2"
14573 [(set_attr "type" "qmul")
14574 (set_attr "size" "128")])
14575
14576 (define_insn "div<mode>3_odd"
14577 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14578 (unspec:IEEE128
14579 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14580 (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14581 UNSPEC_DIV_ROUND_TO_ODD))]
14582 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14583 "xsdivqpo %0,%1,%2"
14584 [(set_attr "type" "vecdiv")
14585 (set_attr "size" "128")])
14586
14587 (define_insn "sqrt<mode>2_odd"
14588 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14589 (unspec:IEEE128
14590 [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14591 UNSPEC_SQRT_ROUND_TO_ODD))]
14592 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14593 "xssqrtqpo %0,%1"
14594 [(set_attr "type" "vecdiv")
14595 (set_attr "size" "128")])
14596
14597 (define_insn "fma<mode>4_odd"
14598 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14599 (unspec:IEEE128
14600 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14601 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14602 (match_operand:IEEE128 3 "altivec_register_operand" "0")]
14603 UNSPEC_FMA_ROUND_TO_ODD))]
14604 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14605 "xsmaddqpo %0,%1,%2"
14606 [(set_attr "type" "qmul")
14607 (set_attr "size" "128")])
14608
14609 (define_insn "*fms<mode>4_odd"
14610 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14611 (unspec:IEEE128
14612 [(match_operand:IEEE128 1 "altivec_register_operand" "%v")
14613 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14614 (neg:IEEE128
14615 (match_operand:IEEE128 3 "altivec_register_operand" "0"))]
14616 UNSPEC_FMA_ROUND_TO_ODD))]
14617 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14618 "xsmsubqpo %0,%1,%2"
14619 [(set_attr "type" "qmul")
14620 (set_attr "size" "128")])
14621
14622 (define_insn "*nfma<mode>4_odd"
14623 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14624 (neg:IEEE128
14625 (unspec:IEEE128
14626 [(match_operand:IEEE128 1 "altivec_register_operand" "%v")
14627 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14628 (match_operand:IEEE128 3 "altivec_register_operand" "0")]
14629 UNSPEC_FMA_ROUND_TO_ODD)))]
14630 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14631 "xsnmaddqpo %0,%1,%2"
14632 [(set_attr "type" "qmul")
14633 (set_attr "size" "128")])
14634
14635 (define_insn "*nfms<mode>4_odd"
14636 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14637 (neg:IEEE128
14638 (unspec:IEEE128
14639 [(match_operand:IEEE128 1 "altivec_register_operand" "%v")
14640 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14641 (neg:IEEE128
14642 (match_operand:IEEE128 3 "altivec_register_operand" "0"))]
14643 UNSPEC_FMA_ROUND_TO_ODD)))]
14644 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14645 "xsnmsubqpo %0,%1,%2"
14646 [(set_attr "type" "qmul")
14647 (set_attr "size" "128")])
14648
14649 (define_insn "trunc<mode>df2_odd"
14650 [(set (match_operand:DF 0 "vsx_register_operand" "=v")
14651 (unspec:DF [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14652 UNSPEC_TRUNC_ROUND_TO_ODD))]
14653 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14654 "xscvqpdpo %0,%1"
14655 [(set_attr "type" "vecfloat")
14656 (set_attr "size" "128")])
14657
14658 ;; IEEE 128-bit comparisons
14659 (define_insn "*cmp<mode>_hw"
14660 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
14661 (compare:CCFP (match_operand:IEEE128 1 "altivec_register_operand" "v")
14662 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14663 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14664 "xscmpuqp %0,%1,%2"
14665 [(set_attr "type" "veccmp")
14666 (set_attr "size" "128")])
14667 \f
14668 ;; Miscellaneous ISA 3.0 (power9) instructions
14669
14670 (define_insn "darn_32"
14671 [(set (match_operand:SI 0 "register_operand" "=r")
14672 (unspec_volatile:SI [(const_int 0)] UNSPECV_DARN_32))]
14673 "TARGET_P9_MISC"
14674 "darn %0,0"
14675 [(set_attr "type" "integer")])
14676
14677 (define_insn "darn_raw"
14678 [(set (match_operand:DI 0 "register_operand" "=r")
14679 (unspec_volatile:DI [(const_int 0)] UNSPECV_DARN_RAW))]
14680 "TARGET_P9_MISC && TARGET_64BIT"
14681 "darn %0,2"
14682 [(set_attr "type" "integer")])
14683
14684 (define_insn "darn"
14685 [(set (match_operand:DI 0 "register_operand" "=r")
14686 (unspec_volatile:DI [(const_int 0)] UNSPECV_DARN))]
14687 "TARGET_P9_MISC && TARGET_64BIT"
14688 "darn %0,1"
14689 [(set_attr "type" "integer")])
14690
14691 ;; Test byte within range.
14692 ;;
14693 ;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx
14694 ;; represents a byte whose value is ignored in this context and
14695 ;; vv, the least significant byte, holds the byte value that is to
14696 ;; be tested for membership within the range specified by operand 2.
14697 ;; The bytes of operand 2 are organized as xx:xx:hi:lo.
14698 ;;
14699 ;; Return in target register operand 0 a value of 1 if lo <= vv and
14700 ;; vv <= hi. Otherwise, set register operand 0 to 0.
14701 ;;
14702 ;; Though the instructions to which this expansion maps operate on
14703 ;; 64-bit registers, the current implementation only operates on
14704 ;; SI-mode operands as the high-order bits provide no information
14705 ;; that is not already available in the low-order bits. To avoid the
14706 ;; costs of data widening operations, future enhancements might allow
14707 ;; DI mode for operand 0 and/or might allow operand 1 to be QI mode.
14708 (define_expand "cmprb"
14709 [(set (match_dup 3)
14710 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
14711 (match_operand:SI 2 "gpc_reg_operand" "r")]
14712 UNSPEC_CMPRB))
14713 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
14714 (if_then_else:SI (lt (match_dup 3)
14715 (const_int 0))
14716 (const_int -1)
14717 (if_then_else (gt (match_dup 3)
14718 (const_int 0))
14719 (const_int 1)
14720 (const_int 0))))]
14721 "TARGET_P9_MISC"
14722 {
14723 operands[3] = gen_reg_rtx (CCmode);
14724 })
14725
14726 ;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx
14727 ;; represents a byte whose value is ignored in this context and
14728 ;; vv, the least significant byte, holds the byte value that is to
14729 ;; be tested for membership within the range specified by operand 2.
14730 ;; The bytes of operand 2 are organized as xx:xx:hi:lo.
14731 ;;
14732 ;; Set bit 1 (the GT bit, 0x4) of CR register operand 0 to 1 if
14733 ;; lo <= vv and vv <= hi. Otherwise, set the GT bit to 0. The other
14734 ;; 3 bits of the target CR register are all set to 0.
14735 (define_insn "*cmprb_internal"
14736 [(set (match_operand:CC 0 "cc_reg_operand" "=y")
14737 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
14738 (match_operand:SI 2 "gpc_reg_operand" "r")]
14739 UNSPEC_CMPRB))]
14740 "TARGET_P9_MISC"
14741 "cmprb %0,0,%1,%2"
14742 [(set_attr "type" "logical")])
14743
14744 ;; Set operand 0 register to -1 if the LT bit (0x8) of condition
14745 ;; register operand 1 is on. Otherwise, set operand 0 register to 1
14746 ;; if the GT bit (0x4) of condition register operand 1 is on.
14747 ;; Otherwise, set operand 0 to 0. Note that the result stored into
14748 ;; register operand 0 is non-zero iff either the LT or GT bits are on
14749 ;; within condition register operand 1.
14750 (define_insn "setb_signed"
14751 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
14752 (if_then_else:SI (lt (match_operand:CC 1 "cc_reg_operand" "y")
14753 (const_int 0))
14754 (const_int -1)
14755 (if_then_else (gt (match_dup 1)
14756 (const_int 0))
14757 (const_int 1)
14758 (const_int 0))))]
14759 "TARGET_P9_MISC"
14760 "setb %0,%1"
14761 [(set_attr "type" "logical")])
14762
14763 (define_insn "setb_unsigned"
14764 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
14765 (if_then_else:SI (ltu (match_operand:CCUNS 1 "cc_reg_operand" "y")
14766 (const_int 0))
14767 (const_int -1)
14768 (if_then_else (gtu (match_dup 1)
14769 (const_int 0))
14770 (const_int 1)
14771 (const_int 0))))]
14772 "TARGET_P9_MISC"
14773 "setb %0,%1"
14774 [(set_attr "type" "logical")])
14775
14776 ;; Test byte within two ranges.
14777 ;;
14778 ;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx
14779 ;; represents a byte whose value is ignored in this context and
14780 ;; vv, the least significant byte, holds the byte value that is to
14781 ;; be tested for membership within the range specified by operand 2.
14782 ;; The bytes of operand 2 are organized as hi_1:lo_1:hi_2:lo_2.
14783 ;;
14784 ;; Return in target register operand 0 a value of 1 if (lo_1 <= vv and
14785 ;; vv <= hi_1) or if (lo_2 <= vv and vv <= hi_2). Otherwise, set register
14786 ;; operand 0 to 0.
14787 ;;
14788 ;; Though the instructions to which this expansion maps operate on
14789 ;; 64-bit registers, the current implementation only operates on
14790 ;; SI-mode operands as the high-order bits provide no information
14791 ;; that is not already available in the low-order bits. To avoid the
14792 ;; costs of data widening operations, future enhancements might allow
14793 ;; DI mode for operand 0 and/or might allow operand 1 to be QI mode.
14794 (define_expand "cmprb2"
14795 [(set (match_dup 3)
14796 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
14797 (match_operand:SI 2 "gpc_reg_operand" "r")]
14798 UNSPEC_CMPRB2))
14799 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
14800 (if_then_else:SI (lt (match_dup 3)
14801 (const_int 0))
14802 (const_int -1)
14803 (if_then_else (gt (match_dup 3)
14804 (const_int 0))
14805 (const_int 1)
14806 (const_int 0))))]
14807 "TARGET_P9_MISC"
14808 {
14809 operands[3] = gen_reg_rtx (CCmode);
14810 })
14811
14812 ;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx
14813 ;; represents a byte whose value is ignored in this context and
14814 ;; vv, the least significant byte, holds the byte value that is to
14815 ;; be tested for membership within the ranges specified by operand 2.
14816 ;; The bytes of operand 2 are organized as hi_1:lo_1:hi_2:lo_2.
14817 ;;
14818 ;; Set bit 1 (the GT bit, 0x4) of CR register operand 0 to 1 if
14819 ;; (lo_1 <= vv and vv <= hi_1) or if (lo_2 <= vv and vv <= hi_2).
14820 ;; Otherwise, set the GT bit to 0. The other 3 bits of the target
14821 ;; CR register are all set to 0.
14822 (define_insn "*cmprb2_internal"
14823 [(set (match_operand:CC 0 "cc_reg_operand" "=y")
14824 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
14825 (match_operand:SI 2 "gpc_reg_operand" "r")]
14826 UNSPEC_CMPRB2))]
14827 "TARGET_P9_MISC"
14828 "cmprb %0,1,%1,%2"
14829 [(set_attr "type" "logical")])
14830
14831 ;; Test byte membership within set of 8 bytes.
14832 ;;
14833 ;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx
14834 ;; represents a byte whose value is ignored in this context and
14835 ;; vv, the least significant byte, holds the byte value that is to
14836 ;; be tested for membership within the set specified by operand 2.
14837 ;; The bytes of operand 2 are organized as e0:e1:e2:e3:e4:e5:e6:e7.
14838 ;;
14839 ;; Return in target register operand 0 a value of 1 if vv equals one
14840 ;; of the values e0, e1, e2, e3, e4, e5, e6, or e7. Otherwise, set
14841 ;; register operand 0 to 0. Note that the 8 byte values held within
14842 ;; operand 2 need not be unique.
14843 ;;
14844 ;; Though the instructions to which this expansion maps operate on
14845 ;; 64-bit registers, the current implementation requires that operands
14846 ;; 0 and 1 have mode SI as the high-order bits provide no information
14847 ;; that is not already available in the low-order bits. To avoid the
14848 ;; costs of data widening operations, future enhancements might allow
14849 ;; DI mode for operand 0 and/or might allow operand 1 to be QI mode.
14850 (define_expand "cmpeqb"
14851 [(set (match_dup 3)
14852 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
14853 (match_operand:DI 2 "gpc_reg_operand" "r")]
14854 UNSPEC_CMPEQB))
14855 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
14856 (if_then_else:SI (lt (match_dup 3)
14857 (const_int 0))
14858 (const_int -1)
14859 (if_then_else (gt (match_dup 3)
14860 (const_int 0))
14861 (const_int 1)
14862 (const_int 0))))]
14863 "TARGET_P9_MISC && TARGET_64BIT"
14864 {
14865 operands[3] = gen_reg_rtx (CCmode);
14866 })
14867
14868 ;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx
14869 ;; represents a byte whose value is ignored in this context and
14870 ;; vv, the least significant byte, holds the byte value that is to
14871 ;; be tested for membership within the set specified by operand 2.
14872 ;; The bytes of operand 2 are organized as e0:e1:e2:e3:e4:e5:e6:e7.
14873 ;;
14874 ;; Set bit 1 (the GT bit, 0x4) of CR register operand 0 to 1 if vv
14875 ;; equals one of the values e0, e1, e2, e3, e4, e5, e6, or e7. Otherwise,
14876 ;; set the GT bit to zero. The other 3 bits of the target CR register
14877 ;; are all set to 0.
14878 (define_insn "*cmpeqb_internal"
14879 [(set (match_operand:CC 0 "cc_reg_operand" "=y")
14880 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
14881 (match_operand:DI 2 "gpc_reg_operand" "r")]
14882 UNSPEC_CMPEQB))]
14883 "TARGET_P9_MISC && TARGET_64BIT"
14884 "cmpeqb %0,%1,%2"
14885 [(set_attr "type" "logical")])
14886 \f
14887
14888 (include "sync.md")
14889 (include "vector.md")
14890 (include "vsx.md")
14891 (include "altivec.md")
14892 (include "mma.md")
14893 (include "dfp.md")
14894 (include "crypto.md")
14895 (include "htm.md")