]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/config/rs6000/rs6000.md
6011f5bf76adc9fea859bf094482249e7e6843c3
[thirdparty/gcc.git] / gcc / config / rs6000 / rs6000.md
1 ;; Machine description for IBM RISC System 6000 (POWER) for GNU C compiler
2 ;; Copyright (C) 1990-2022 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 UNSPEC_HASHST
158 UNSPEC_HASHCHK
159 UNSPEC_XXSPLTIDP_CONST
160 UNSPEC_XXSPLTIW_CONST
161 ])
162
163 ;;
164 ;; UNSPEC_VOLATILE usage
165 ;;
166
167 (define_c_enum "unspecv"
168 [UNSPECV_BLOCK
169 UNSPECV_LL ; load-locked
170 UNSPECV_SC ; store-conditional
171 UNSPECV_PROBE_STACK_RANGE ; probe range of stack addresses
172 UNSPECV_EH_RR ; eh_reg_restore
173 UNSPECV_ISYNC ; isync instruction
174 UNSPECV_MFTB ; move from time base
175 UNSPECV_DARN ; darn (deliver a random number)
176 UNSPECV_NLGR ; non-local goto receiver
177 UNSPECV_MFFS ; Move from FPSCR
178 UNSPECV_MFFSL ; Move from FPSCR light instruction version
179 UNSPECV_MFFSCRN ; Move from FPSCR float rounding mode
180 UNSPECV_MFFSCDRN ; Move from FPSCR decimal float rounding mode
181 UNSPECV_MTFSF ; Move to FPSCR Fields 8 to 15
182 UNSPECV_MTFSF_HI ; Move to FPSCR Fields 0 to 7
183 UNSPECV_MTFSB0 ; Set FPSCR Field bit to 0
184 UNSPECV_MTFSB1 ; Set FPSCR Field bit to 1
185 UNSPECV_SPLIT_STACK_RETURN ; A camouflaged return
186 UNSPECV_SPEC_BARRIER ; Speculation barrier
187 UNSPECV_PLT16_LO
188 UNSPECV_PLT_PCREL
189 ])
190
191 ; The three different kinds of epilogue.
192 (define_enum "epilogue_type" [normal sibcall eh_return])
193 \f
194 ;; Define an insn type attribute. This is used in function unit delay
195 ;; computations.
196 (define_attr "type"
197 "integer,two,three,
198 add,logical,shift,insert,
199 mul,halfmul,div,
200 exts,cntlz,popcnt,isel,
201 load,store,fpload,fpstore,vecload,vecstore,
202 cmp,
203 branch,jmpreg,mfjmpr,mtjmpr,trap,isync,sync,load_l,store_c,
204 cr_logical,mfcr,mfcrf,mtcr,
205 fpcompare,fp,fpsimple,dmul,qmul,sdiv,ddiv,ssqrt,dsqrt,
206 vecsimple,veccomplex,vecdiv,veccmp,veccmpsimple,vecperm,
207 vecfloat,vecfdiv,vecdouble,mtvsr,mfvsr,crypto,
208 veclogical,veccmpfx,vecexts,vecmove,
209 htm,htmsimple,dfp,mma,
210 fused_arith_logical,
211 fused_cmp_isel,
212 fused_carry,
213 fused_load_cmpi,
214 fused_load_load,fused_store_store,
215 fused_addis_load,
216 fused_mtbc,
217 fused_vector"
218 (const_string "integer"))
219 ;; Attr type definitions for fused pairs:
220 ;; fused_arith_logical is used for scalar logical+add/subf and
221 ;; add/subf+logical pairs of instructions.
222 ;; fused_load_cmpi is used for a D-form load fused with
223 ;; a compare immediate.
224 ;; fused_load_load is for a fused pair of loads to adjacent addresses.
225 ;; fused_store_store is for a fused pair of stores to adjacent addresses.
226 ;; fused_addis_load is for addis fused to D-form load for a larger immediate.
227 ;; fused_mtbc is for fused mtlr and bclr[l] pairs.
228 ;; fused_vector is for a fused pair of vector logical instructions.
229
230 ;; What data size does this instruction work on?
231 ;; This is used for insert, mul and others as necessary.
232 (define_attr "size" "8,16,32,64,128,256" (const_string "32"))
233
234 ;; What is the insn_cost for this insn? The target hook can still override
235 ;; this. For optimizing for size the "length" attribute is used instead.
236 (define_attr "cost" "" (const_int 0))
237
238 ;; Is this instruction record form ("dot", signed compare to 0, writing CR0)?
239 ;; This is used for add, logical, shift, exts, mul.
240 (define_attr "dot" "no,yes" (const_string "no"))
241
242 ;; Does this instruction sign-extend its result?
243 ;; This is used for load insns.
244 (define_attr "sign_extend" "no,yes" (const_string "no"))
245
246 ;; Does this cr_logical instruction have three operands? That is, BT != BB.
247 (define_attr "cr_logical_3op" "no,yes" (const_string "no"))
248
249 ;; Does this instruction use indexed (that is, reg+reg) addressing?
250 ;; This is used for load and store insns. If operand 0 or 1 is a MEM
251 ;; it is automatically set based on that. If a load or store instruction
252 ;; has fewer than two operands it needs to set this attribute manually
253 ;; or the compiler will crash.
254 (define_attr "indexed" "no,yes"
255 (if_then_else (ior (match_operand 0 "indexed_address_mem")
256 (match_operand 1 "indexed_address_mem"))
257 (const_string "yes")
258 (const_string "no")))
259
260 ;; Does this instruction use update addressing?
261 ;; This is used for load and store insns. See the comments for "indexed".
262 (define_attr "update" "no,yes"
263 (if_then_else (ior (match_operand 0 "update_address_mem")
264 (match_operand 1 "update_address_mem"))
265 (const_string "yes")
266 (const_string "no")))
267
268 ;; Is this instruction using operands[2] as shift amount, and can that be a
269 ;; register?
270 ;; This is used for shift insns.
271 (define_attr "maybe_var_shift" "no,yes" (const_string "no"))
272
273 ;; Is this instruction using a shift amount from a register?
274 ;; This is used for shift insns.
275 (define_attr "var_shift" "no,yes"
276 (if_then_else (and (eq_attr "type" "shift")
277 (eq_attr "maybe_var_shift" "yes"))
278 (if_then_else (match_operand 2 "gpc_reg_operand")
279 (const_string "yes")
280 (const_string "no"))
281 (const_string "no")))
282
283 ;; Is copying of this instruction disallowed?
284 (define_attr "cannot_copy" "no,yes" (const_string "no"))
285
286
287 ;; Whether this insn has a prefixed form and a non-prefixed form.
288 (define_attr "maybe_prefixed" "no,yes"
289 (if_then_else (eq_attr "type" "load,fpload,vecload,store,fpstore,vecstore,
290 integer,add")
291 (const_string "yes")
292 (const_string "no")))
293
294 ;; Whether an insn is a prefixed insn. A prefixed instruction has a prefix
295 ;; instruction word that conveys additional information such as a larger
296 ;; immediate, additional operands, etc., in addition to the normal instruction
297 ;; word. The default "length" attribute will also be adjusted by default to
298 ;; be 12 bytes.
299 (define_attr "prefixed" "no,yes"
300 (cond [(ior (match_test "!TARGET_PREFIXED")
301 (match_test "!NONJUMP_INSN_P (insn)")
302 (eq_attr "maybe_prefixed" "no"))
303 (const_string "no")
304
305 (eq_attr "type" "load,fpload,vecload")
306 (if_then_else (match_test "prefixed_load_p (insn)")
307 (const_string "yes")
308 (const_string "no"))
309
310 (eq_attr "type" "store,fpstore,vecstore")
311 (if_then_else (match_test "prefixed_store_p (insn)")
312 (const_string "yes")
313 (const_string "no"))
314
315 (eq_attr "type" "integer,add")
316 (if_then_else (match_test "prefixed_paddi_p (insn)")
317 (const_string "yes")
318 (const_string "no"))]
319
320 (const_string "no")))
321
322 ;; Whether an insn loads an external address for the PCREL_OPT optimizaton.
323 (define_attr "loads_external_address" "no,yes"
324 (const_string "no"))
325
326 ;; Return the number of real hardware instructions in a combined insn. If it
327 ;; is 0, just use the length / 4.
328 (define_attr "num_insns" "" (const_int 0))
329
330 ;; If an insn is prefixed, return the maximum number of prefixed instructions
331 ;; in the insn. The macro ADJUST_INSN_LENGTH uses this number to adjust the
332 ;; insn length.
333 (define_attr "max_prefixed_insns" "" (const_int 1))
334
335 ;; Length of the instruction (in bytes). This length does not consider the
336 ;; length for prefixed instructions. The macro ADJUST_INSN_LENGTH will adjust
337 ;; the length if there are prefixed instructions.
338 ;;
339 ;; While it might be tempting to use num_insns to calculate the length, it can
340 ;; be problematical unless all insn lengths are adjusted to use num_insns
341 ;; (i.e. if num_insns is 0, it will get the length, which in turn will get
342 ;; num_insns and recurse).
343 (define_attr "length" "" (const_int 4))
344
345 ;; Processor type -- this attribute must exactly match the processor_type
346 ;; enumeration in rs6000-opts.h.
347 (define_attr "cpu"
348 "ppc601,ppc603,ppc604,ppc604e,ppc620,ppc630,
349 ppc750,ppc7400,ppc7450,
350 ppc403,ppc405,ppc440,ppc476,
351 ppc8540,ppc8548,ppce300c2,ppce300c3,ppce500mc,ppce500mc64,ppce5500,ppce6500,
352 power4,power5,power6,power7,power8,power9,power10,
353 rs64a,mpccore,cell,ppca2,titan"
354 (const (symbol_ref "(enum attr_cpu) rs6000_tune")))
355
356 ;; The ISA we implement.
357 (define_attr "isa" "any,p5,p6,p7,p7v,p8v,p9,p9v,p9kf,p9tf,p10"
358 (const_string "any"))
359
360 ;; Is this alternative enabled for the current CPU/ISA/etc.?
361 (define_attr "enabled" ""
362 (cond
363 [(eq_attr "isa" "any")
364 (const_int 1)
365
366 (and (eq_attr "isa" "p5")
367 (match_test "TARGET_POPCNTB"))
368 (const_int 1)
369
370 (and (eq_attr "isa" "p6")
371 (match_test "TARGET_CMPB"))
372 (const_int 1)
373
374 (and (eq_attr "isa" "p7")
375 (match_test "TARGET_POPCNTD"))
376 (const_int 1)
377
378 (and (eq_attr "isa" "p7v")
379 (match_test "TARGET_VSX"))
380 (const_int 1)
381
382 (and (eq_attr "isa" "p8v")
383 (match_test "TARGET_P8_VECTOR"))
384 (const_int 1)
385
386 (and (eq_attr "isa" "p9")
387 (match_test "TARGET_MODULO"))
388 (const_int 1)
389
390 (and (eq_attr "isa" "p9v")
391 (match_test "TARGET_P9_VECTOR"))
392 (const_int 1)
393
394 (and (eq_attr "isa" "p9kf")
395 (match_test "TARGET_FLOAT128_TYPE"))
396 (const_int 1)
397
398 (and (eq_attr "isa" "p9tf")
399 (match_test "FLOAT128_VECTOR_P (TFmode)"))
400 (const_int 1)
401
402 (and (eq_attr "isa" "p10")
403 (match_test "TARGET_POWER10"))
404 (const_int 1)
405 ] (const_int 0)))
406
407 ;; If this instruction is microcoded on the CELL processor
408 ; The default for load extended, the recorded instructions and rotate/shifts by a variable is always microcoded
409 (define_attr "cell_micro" "not,conditional,always"
410 (if_then_else (ior (and (eq_attr "type" "shift,exts,mul")
411 (eq_attr "dot" "yes"))
412 (and (eq_attr "type" "load")
413 (eq_attr "sign_extend" "yes"))
414 (and (eq_attr "type" "shift")
415 (eq_attr "var_shift" "yes")))
416 (const_string "always")
417 (const_string "not")))
418
419 (automata_option "ndfa")
420
421 (include "rs64.md")
422 (include "mpc.md")
423 (include "40x.md")
424 (include "440.md")
425 (include "476.md")
426 (include "601.md")
427 (include "603.md")
428 (include "6xx.md")
429 (include "7xx.md")
430 (include "7450.md")
431 (include "8540.md")
432 (include "e300c2c3.md")
433 (include "e500mc.md")
434 (include "e500mc64.md")
435 (include "e5500.md")
436 (include "e6500.md")
437 (include "power4.md")
438 (include "power5.md")
439 (include "power6.md")
440 (include "power7.md")
441 (include "power8.md")
442 (include "power9.md")
443 (include "power10.md")
444 (include "cell.md")
445 (include "a2.md")
446 (include "titan.md")
447
448 (include "predicates.md")
449 (include "constraints.md")
450
451 \f
452 ;; Mode iterators
453
454 ; This mode iterator allows :GPR to be used to indicate the allowable size
455 ; of whole values in GPRs.
456 (define_mode_iterator GPR [SI (DI "TARGET_POWERPC64")])
457
458 ; And again, for patterns that need two (potentially) different integer modes.
459 (define_mode_iterator GPR2 [SI (DI "TARGET_POWERPC64")])
460
461 ; Any supported integer mode.
462 (define_mode_iterator INT [QI HI SI DI TI PTI])
463
464 ; Any supported integer mode that fits in one register.
465 (define_mode_iterator INT1 [QI HI SI (DI "TARGET_POWERPC64")])
466
467 ; Integer modes supported in VSX registers with ISA 3.0 instructions
468 (define_mode_iterator INT_ISA3 [QI HI SI DI])
469
470 ; Everything we can extend QImode to.
471 (define_mode_iterator EXTQI [SI (DI "TARGET_POWERPC64")])
472
473 ; Everything we can extend HImode to.
474 (define_mode_iterator EXTHI [SI (DI "TARGET_POWERPC64")])
475
476 ; Everything we can extend SImode to.
477 (define_mode_iterator EXTSI [(DI "TARGET_POWERPC64")])
478
479 ; QImode or HImode for small integer moves and small atomic ops
480 (define_mode_iterator QHI [QI HI])
481
482 ; QImode, HImode, SImode for fused ops only for GPR loads
483 (define_mode_iterator QHSI [QI HI SI])
484
485 ; HImode or SImode for sign extended fusion ops
486 (define_mode_iterator HSI [HI SI])
487
488 ; SImode or DImode, even if DImode doesn't fit in GPRs.
489 (define_mode_iterator SDI [SI DI])
490
491 ; The size of a pointer. Also, the size of the value that a record-condition
492 ; (one with a '.') will compare; and the size used for arithmetic carries.
493 (define_mode_iterator P [(SI "TARGET_32BIT") (DI "TARGET_64BIT")])
494
495 ; Iterator to add PTImode along with TImode (TImode can go in VSX registers,
496 ; PTImode is GPR only)
497 (define_mode_iterator TI2 [TI PTI])
498
499 ; Any hardware-supported floating-point mode
500 (define_mode_iterator FP [
501 (SF "TARGET_HARD_FLOAT")
502 (DF "TARGET_HARD_FLOAT")
503 (TF "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128")
504 (IF "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128")
505 (KF "TARGET_FLOAT128_TYPE")
506 (DD "TARGET_DFP")
507 (TD "TARGET_DFP")])
508
509 ; Any fma capable floating-point mode.
510 (define_mode_iterator FMA_F [
511 (SF "TARGET_HARD_FLOAT")
512 (DF "TARGET_HARD_FLOAT || VECTOR_UNIT_VSX_P (DFmode)")
513 (V4SF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)")
514 (V2DF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V2DFmode)")
515 (KF "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (KFmode)")
516 (TF "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (TFmode)")
517 ])
518
519 ; Floating point move iterators to combine binary and decimal moves
520 (define_mode_iterator FMOVE32 [SF SD])
521 (define_mode_iterator FMOVE64 [DF DD])
522 (define_mode_iterator FMOVE64X [DI DF DD])
523 (define_mode_iterator FMOVE128 [(TF "TARGET_LONG_DOUBLE_128")
524 (IF "FLOAT128_IBM_P (IFmode)")
525 (TD "TARGET_HARD_FLOAT")])
526
527 (define_mode_iterator FMOVE128_FPR [(TF "FLOAT128_2REG_P (TFmode)")
528 (IF "FLOAT128_2REG_P (IFmode)")
529 (TD "TARGET_HARD_FLOAT")])
530
531 ; Iterators for 128 bit types for direct move
532 (define_mode_iterator FMOVE128_GPR [TI
533 V16QI
534 V8HI
535 V4SI
536 V4SF
537 V2DI
538 V2DF
539 V1TI
540 (KF "FLOAT128_VECTOR_P (KFmode)")
541 (TF "FLOAT128_VECTOR_P (TFmode)")])
542
543 ; Iterator for 128-bit VSX types for pack/unpack
544 (define_mode_iterator FMOVE128_VSX [V1TI KF])
545
546 ; Iterators for converting to/from TFmode
547 (define_mode_iterator IFKF [IF KF])
548
549 ; Constraints for moving IF/KFmode.
550 (define_mode_attr IFKF_reg [(IF "d") (KF "wa")])
551
552 ; Whether a floating point move is ok, don't allow SD without hardware FP
553 (define_mode_attr fmove_ok [(SF "")
554 (DF "")
555 (SD "TARGET_HARD_FLOAT")
556 (DD "")])
557
558 ; Convert REAL_VALUE to the appropriate bits
559 (define_mode_attr real_value_to_target [(SF "REAL_VALUE_TO_TARGET_SINGLE")
560 (DF "REAL_VALUE_TO_TARGET_DOUBLE")
561 (SD "REAL_VALUE_TO_TARGET_DECIMAL32")
562 (DD "REAL_VALUE_TO_TARGET_DECIMAL64")])
563
564 ; Whether 0.0 has an all-zero bit pattern
565 (define_mode_attr zero_fp [(SF "j")
566 (DF "j")
567 (TF "j")
568 (IF "j")
569 (KF "j")
570 (SD "wn")
571 (DD "wn")
572 (TD "wn")])
573
574 ; Definitions for 64-bit VSX
575 (define_mode_attr f64_vsx [(DF "wa") (DD "wn")])
576
577 ; Definitions for 64-bit direct move
578 (define_mode_attr f64_dm [(DF "wa") (DD "d")])
579
580 ; Definitions for 64-bit use of altivec registers
581 (define_mode_attr f64_av [(DF "v") (DD "wn")])
582
583 ; Definitions for 64-bit access to ISA 3.0 (power9) vector
584 (define_mode_attr f64_p9 [(DF "v") (DD "wn")])
585
586 ; These modes do not fit in integer registers in 32-bit mode.
587 (define_mode_iterator DIFD [DI DF DD])
588
589 ; Iterator for reciprocal estimate instructions
590 (define_mode_iterator RECIPF [SF DF V4SF V2DF])
591
592 ; SFmode or DFmode.
593 (define_mode_iterator SFDF [SF DF])
594
595 ; And again, for when we need two FP modes in a pattern.
596 (define_mode_iterator SFDF2 [SF DF])
597
598 ; A generic s/d attribute, for sp/dp for example.
599 (define_mode_attr sd [(SF "s") (DF "d")
600 (V4SF "s") (V2DF "d")])
601
602 ; "s" or nothing, for fmuls/fmul for example.
603 (define_mode_attr s [(SF "s") (DF "")])
604
605 ; Iterator for 128-bit floating point that uses the IBM double-double format
606 (define_mode_iterator IBM128 [(IF "FLOAT128_IBM_P (IFmode)")
607 (TF "FLOAT128_IBM_P (TFmode)")])
608
609 ; Iterator for 128-bit floating point that uses IEEE 128-bit float
610 (define_mode_iterator IEEE128 [(KF "FLOAT128_IEEE_P (KFmode)")
611 (TF "FLOAT128_IEEE_P (TFmode)")])
612
613 ; Iterator for 128-bit floating point
614 (define_mode_iterator FLOAT128 [(KF "TARGET_FLOAT128_TYPE")
615 (IF "TARGET_FLOAT128_TYPE")
616 (TF "TARGET_LONG_DOUBLE_128")])
617
618 ; Iterator for signbit on 64-bit machines with direct move
619 (define_mode_iterator SIGNBIT [(KF "FLOAT128_VECTOR_P (KFmode)")
620 (TF "FLOAT128_VECTOR_P (TFmode)")])
621
622 ; Which isa is needed for those float instructions?
623 (define_mode_attr Fisa [(SF "p8v") (DF "*") (DI "*")])
624
625 ; FRE/FRES support
626 (define_mode_attr FFRE [(SF "FRES") (DF "FRE")])
627
628 ; Conditional returns.
629 (define_code_iterator any_return [return simple_return])
630 (define_code_attr return_pred [(return "direct_return ()")
631 (simple_return "1")])
632 (define_code_attr return_str [(return "") (simple_return "simple_")])
633
634 ; Logical operators.
635 (define_code_iterator iorxor [ior xor])
636 (define_code_iterator and_ior_xor [and ior xor])
637
638 ; Signed/unsigned variants of ops.
639 (define_code_iterator any_extend [sign_extend zero_extend])
640 (define_code_iterator any_fix [fix unsigned_fix])
641 (define_code_iterator any_float [float unsigned_float])
642
643 (define_code_attr u [(sign_extend "")
644 (zero_extend "u")
645 (fix "")
646 (unsigned_fix "u")])
647
648 (define_code_attr su [(sign_extend "s")
649 (zero_extend "u")
650 (fix "s")
651 (unsigned_fix "u")
652 (float "s")
653 (unsigned_float "u")])
654
655 (define_code_attr az [(sign_extend "a")
656 (zero_extend "z")
657 (fix "a")
658 (unsigned_fix "z")
659 (float "a")
660 (unsigned_float "z")])
661
662 (define_code_attr uns [(fix "")
663 (unsigned_fix "uns")
664 (float "")
665 (unsigned_float "uns")])
666
667 ; Various instructions that come in SI and DI forms.
668 ; A generic w/d attribute, for things like cmpw/cmpd.
669 (define_mode_attr wd [(QI "b")
670 (HI "h")
671 (SI "w")
672 (DI "d")
673 (V16QI "b")
674 (V8HI "h")
675 (V4SI "w")
676 (V2DI "d")
677 (V1TI "q")
678 (TI "q")])
679
680 ; For double extract from different origin types
681 (define_mode_attr du_or_d [(QI "du")
682 (HI "du")
683 (SI "du")
684 (DI "d")
685 (V16QI "du")
686 (V8HI "du")
687 (V4SI "du")
688 (V2DI "d")])
689
690 ;; How many bits (per element) in this mode?
691 (define_mode_attr bits [(QI "8") (HI "16") (SI "32") (DI "64")
692 (SF "32") (DF "64")
693 (DD "64") (TD "128")
694 (V4SI "32") (V2DI "64")])
695
696 ; DImode bits
697 (define_mode_attr dbits [(QI "56") (HI "48") (SI "32")])
698
699 ;; Bitmask for shift instructions
700 (define_mode_attr hH [(SI "h") (DI "H")])
701
702 ;; A mode twice the size of the given mode
703 (define_mode_attr dmode [(SI "di") (DI "ti")])
704 (define_mode_attr DMODE [(SI "DI") (DI "TI")])
705
706 ;; Suffix for reload patterns
707 (define_mode_attr ptrsize [(SI "32bit")
708 (DI "64bit")])
709
710 (define_mode_attr tptrsize [(SI "TARGET_32BIT")
711 (DI "TARGET_64BIT")])
712
713 (define_mode_attr mptrsize [(SI "si")
714 (DI "di")])
715
716 (define_mode_attr ptrload [(SI "lwz")
717 (DI "ld")])
718
719 (define_mode_attr ptrm [(SI "m")
720 (DI "Y")])
721
722 (define_mode_attr rreg [(SF "f")
723 (DF "wa")
724 (TF "f")
725 (TD "f")
726 (V4SF "wa")
727 (V2DF "wa")])
728
729 (define_mode_attr rreg2 [(SF "f")
730 (DF "d")])
731
732 (define_mode_attr SI_CONVERT_FP [(SF "TARGET_FCFIDS")
733 (DF "TARGET_FCFID")])
734
735 ;; Mode iterator for logical operations on 128-bit types
736 (define_mode_iterator BOOL_128 [TI
737 PTI
738 (V16QI "TARGET_ALTIVEC")
739 (V8HI "TARGET_ALTIVEC")
740 (V4SI "TARGET_ALTIVEC")
741 (V4SF "TARGET_ALTIVEC")
742 (V2DI "TARGET_ALTIVEC")
743 (V2DF "TARGET_ALTIVEC")
744 (V1TI "TARGET_ALTIVEC")])
745
746 ;; For the GPRs we use 3 constraints for register outputs, two that are the
747 ;; same as the output register, and a third where the output register is an
748 ;; early clobber, so we don't have to deal with register overlaps. For the
749 ;; vector types, we prefer to use the vector registers. For TI mode, allow
750 ;; either.
751
752 ;; Mode attribute for boolean operation register constraints for output
753 (define_mode_attr BOOL_REGS_OUTPUT [(TI "&r,r,r,wa,v")
754 (PTI "&r,r,r")
755 (V16QI "wa,v,&?r,?r,?r")
756 (V8HI "wa,v,&?r,?r,?r")
757 (V4SI "wa,v,&?r,?r,?r")
758 (V4SF "wa,v,&?r,?r,?r")
759 (V2DI "wa,v,&?r,?r,?r")
760 (V2DF "wa,v,&?r,?r,?r")
761 (V1TI "wa,v,&?r,?r,?r")])
762
763 ;; Mode attribute for boolean operation register constraints for operand1
764 (define_mode_attr BOOL_REGS_OP1 [(TI "r,0,r,wa,v")
765 (PTI "r,0,r")
766 (V16QI "wa,v,r,0,r")
767 (V8HI "wa,v,r,0,r")
768 (V4SI "wa,v,r,0,r")
769 (V4SF "wa,v,r,0,r")
770 (V2DI "wa,v,r,0,r")
771 (V2DF "wa,v,r,0,r")
772 (V1TI "wa,v,r,0,r")])
773
774 ;; Mode attribute for boolean operation register constraints for operand2
775 (define_mode_attr BOOL_REGS_OP2 [(TI "r,r,0,wa,v")
776 (PTI "r,r,0")
777 (V16QI "wa,v,r,r,0")
778 (V8HI "wa,v,r,r,0")
779 (V4SI "wa,v,r,r,0")
780 (V4SF "wa,v,r,r,0")
781 (V2DI "wa,v,r,r,0")
782 (V2DF "wa,v,r,r,0")
783 (V1TI "wa,v,r,r,0")])
784
785 ;; Mode attribute for boolean operation register constraints for operand1
786 ;; for one_cmpl. To simplify things, we repeat the constraint where 0
787 ;; is used for operand1 or operand2
788 (define_mode_attr BOOL_REGS_UNARY [(TI "r,0,0,wa,v")
789 (PTI "r,0,0")
790 (V16QI "wa,v,r,0,0")
791 (V8HI "wa,v,r,0,0")
792 (V4SI "wa,v,r,0,0")
793 (V4SF "wa,v,r,0,0")
794 (V2DI "wa,v,r,0,0")
795 (V2DF "wa,v,r,0,0")
796 (V1TI "wa,v,r,0,0")])
797
798 ;; Reload iterator for creating the function to allocate a base register to
799 ;; supplement addressing modes.
800 (define_mode_iterator RELOAD [V16QI V8HI V4SI V2DI V4SF V2DF V1TI
801 SF SD SI DF DD DI TI PTI KF IF TF
802 OO XO])
803
804 ;; Iterate over smin, smax
805 (define_code_iterator fp_minmax [smin smax])
806
807 (define_code_attr minmax [(smin "min")
808 (smax "max")])
809
810 (define_code_attr SMINMAX [(smin "SMIN")
811 (smax "SMAX")])
812
813 ;; Iterator to optimize the following cases:
814 ;; D-form load to FPR register & move to Altivec register
815 ;; Move Altivec register to FPR register and store
816 (define_mode_iterator ALTIVEC_DFORM [DF
817 (SF "TARGET_P8_VECTOR")
818 (DI "TARGET_POWERPC64")])
819
820 (include "darwin.md")
821 \f
822 ;; Start with fixed-point load and store insns. Here we put only the more
823 ;; complex forms. Basic data transfer is done later.
824
825 (define_insn "zero_extendqi<mode>2"
826 [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r,wa,^v")
827 (zero_extend:EXTQI (match_operand:QI 1 "reg_or_mem_operand" "m,r,?Z,v")))]
828 ""
829 "@
830 lbz%U1%X1 %0,%1
831 rlwinm %0,%1,0,0xff
832 lxsibzx %x0,%y1
833 vextractub %0,%1,7"
834 [(set_attr "type" "load,shift,fpload,vecperm")
835 (set_attr "isa" "*,*,p9v,p9v")])
836
837 (define_insn_and_split "*zero_extendqi<mode>2_dot"
838 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
839 (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
840 (const_int 0)))
841 (clobber (match_scratch:EXTQI 0 "=r,r"))]
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 (define_insn_and_split "*zero_extendqi<mode>2_dot2"
858 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
859 (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
860 (const_int 0)))
861 (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
862 (zero_extend:EXTQI (match_dup 1)))]
863 ""
864 "@
865 andi. %0,%1,0xff
866 #"
867 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
868 [(set (match_dup 0)
869 (zero_extend:EXTQI (match_dup 1)))
870 (set (match_dup 2)
871 (compare:CC (match_dup 0)
872 (const_int 0)))]
873 ""
874 [(set_attr "type" "logical")
875 (set_attr "dot" "yes")
876 (set_attr "length" "4,8")])
877
878
879 (define_insn "zero_extendhi<mode>2"
880 [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r,wa,^v")
881 (zero_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r,?Z,v")))]
882 ""
883 "@
884 lhz%U1%X1 %0,%1
885 rlwinm %0,%1,0,0xffff
886 lxsihzx %x0,%y1
887 vextractuh %0,%1,6"
888 [(set_attr "type" "load,shift,fpload,vecperm")
889 (set_attr "isa" "*,*,p9v,p9v")])
890
891 (define_insn_and_split "*zero_extendhi<mode>2_dot"
892 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
893 (compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
894 (const_int 0)))
895 (clobber (match_scratch:EXTHI 0 "=r,r"))]
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 (define_insn_and_split "*zero_extendhi<mode>2_dot2"
912 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
913 (compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
914 (const_int 0)))
915 (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
916 (zero_extend:EXTHI (match_dup 1)))]
917 ""
918 "@
919 andi. %0,%1,0xffff
920 #"
921 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
922 [(set (match_dup 0)
923 (zero_extend:EXTHI (match_dup 1)))
924 (set (match_dup 2)
925 (compare:CC (match_dup 0)
926 (const_int 0)))]
927 ""
928 [(set_attr "type" "logical")
929 (set_attr "dot" "yes")
930 (set_attr "length" "4,8")])
931
932
933 (define_insn "zero_extendsi<mode>2"
934 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r,d,wa,wa,r,wa")
935 (zero_extend:EXTSI (match_operand:SI 1 "reg_or_mem_operand" "m,r,?Z,?Z,r,wa,wa")))]
936 ""
937 "@
938 lwz%U1%X1 %0,%1
939 rldicl %0,%1,0,32
940 lfiwzx %0,%y1
941 lxsiwzx %x0,%y1
942 mtvsrwz %x0,%1
943 mfvsrwz %0,%x1
944 xxextractuw %x0,%x1,4"
945 [(set_attr "type" "load,shift,fpload,fpload,mtvsr,mfvsr,vecexts")
946 (set_attr "isa" "*,*,p7,p8v,p8v,p8v,p9v")])
947
948 (define_insn_and_split "*zero_extendsi<mode>2_dot"
949 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
950 (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
951 (const_int 0)))
952 (clobber (match_scratch:EXTSI 0 "=r,r"))]
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:DI (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 (define_insn_and_split "*zero_extendsi<mode>2_dot2"
969 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
970 (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
971 (const_int 0)))
972 (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
973 (zero_extend:EXTSI (match_dup 1)))]
974 ""
975 "@
976 rldicl. %0,%1,0,32
977 #"
978 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
979 [(set (match_dup 0)
980 (zero_extend:EXTSI (match_dup 1)))
981 (set (match_dup 2)
982 (compare:CC (match_dup 0)
983 (const_int 0)))]
984 ""
985 [(set_attr "type" "shift")
986 (set_attr "dot" "yes")
987 (set_attr "length" "4,8")])
988
989
990 (define_insn "extendqi<mode>2"
991 [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,?*v")
992 (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,?*v")))]
993 ""
994 "@
995 extsb %0,%1
996 vextsb2d %0,%1"
997 [(set_attr "type" "exts,vecperm")
998 (set_attr "isa" "*,p9v")])
999
1000 (define_insn_and_split "*extendqi<mode>2_dot"
1001 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1002 (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
1003 (const_int 0)))
1004 (clobber (match_scratch:EXTQI 0 "=r,r"))]
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 (define_insn_and_split "*extendqi<mode>2_dot2"
1021 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1022 (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
1023 (const_int 0)))
1024 (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
1025 (sign_extend:EXTQI (match_dup 1)))]
1026 ""
1027 "@
1028 extsb. %0,%1
1029 #"
1030 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1031 [(set (match_dup 0)
1032 (sign_extend:EXTQI (match_dup 1)))
1033 (set (match_dup 2)
1034 (compare:CC (match_dup 0)
1035 (const_int 0)))]
1036 ""
1037 [(set_attr "type" "exts")
1038 (set_attr "dot" "yes")
1039 (set_attr "length" "4,8")])
1040
1041
1042 (define_expand "extendhi<mode>2"
1043 [(set (match_operand:EXTHI 0 "gpc_reg_operand")
1044 (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand")))]
1045 ""
1046 "")
1047
1048 (define_insn "*extendhi<mode>2"
1049 [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r,?*v,?*v")
1050 (sign_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r,Z,v")))]
1051 ""
1052 "@
1053 lha%U1%X1 %0,%1
1054 extsh %0,%1
1055 #
1056 vextsh2d %0,%1"
1057 [(set_attr "type" "load,exts,fpload,vecperm")
1058 (set_attr "sign_extend" "yes")
1059 (set_attr "length" "*,*,8,*")
1060 (set_attr "isa" "*,*,p9v,p9v")])
1061
1062 (define_split
1063 [(set (match_operand:EXTHI 0 "altivec_register_operand")
1064 (sign_extend:EXTHI
1065 (match_operand:HI 1 "indexed_or_indirect_operand")))]
1066 "TARGET_P9_VECTOR && reload_completed"
1067 [(set (match_dup 2)
1068 (match_dup 1))
1069 (set (match_dup 0)
1070 (sign_extend:EXTHI (match_dup 2)))]
1071 {
1072 operands[2] = gen_rtx_REG (HImode, REGNO (operands[0]));
1073 })
1074
1075 (define_insn_and_split "*extendhi<mode>2_dot"
1076 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1077 (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
1078 (const_int 0)))
1079 (clobber (match_scratch:EXTHI 0 "=r,r"))]
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 (define_insn_and_split "*extendhi<mode>2_dot2"
1096 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1097 (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
1098 (const_int 0)))
1099 (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
1100 (sign_extend:EXTHI (match_dup 1)))]
1101 ""
1102 "@
1103 extsh. %0,%1
1104 #"
1105 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1106 [(set (match_dup 0)
1107 (sign_extend:EXTHI (match_dup 1)))
1108 (set (match_dup 2)
1109 (compare:CC (match_dup 0)
1110 (const_int 0)))]
1111 ""
1112 [(set_attr "type" "exts")
1113 (set_attr "dot" "yes")
1114 (set_attr "length" "4,8")])
1115
1116
1117 (define_insn "extendsi<mode>2"
1118 [(set (match_operand:EXTSI 0 "gpc_reg_operand"
1119 "=r, r, d, wa, wa, v, v, wr")
1120 (sign_extend:EXTSI (match_operand:SI 1 "lwa_operand"
1121 "YZ, r, Z, Z, r, v, v, ?wa")))]
1122 ""
1123 "@
1124 lwa%U1%X1 %0,%1
1125 extsw %0,%1
1126 lfiwax %0,%y1
1127 lxsiwax %x0,%y1
1128 mtvsrwa %x0,%1
1129 vextsw2d %0,%1
1130 #
1131 #"
1132 [(set_attr "type" "load,exts,fpload,fpload,mtvsr,vecexts,vecperm,mfvsr")
1133 (set_attr "sign_extend" "yes")
1134 (set_attr "length" "*,*,*,*,*,*,8,8")
1135 (set_attr "isa" "*,*,p6,p8v,p8v,p9v,p8v,p8v")])
1136
1137 (define_split
1138 [(set (match_operand:EXTSI 0 "int_reg_operand")
1139 (sign_extend:EXTSI (match_operand:SI 1 "vsx_register_operand")))]
1140 "TARGET_DIRECT_MOVE_64BIT && reload_completed"
1141 [(set (match_dup 2)
1142 (match_dup 1))
1143 (set (match_dup 0)
1144 (sign_extend:DI (match_dup 2)))]
1145 {
1146 operands[2] = gen_rtx_REG (SImode, reg_or_subregno (operands[0]));
1147 })
1148
1149 (define_split
1150 [(set (match_operand:DI 0 "altivec_register_operand")
1151 (sign_extend:DI (match_operand:SI 1 "altivec_register_operand")))]
1152 "TARGET_P8_VECTOR && !TARGET_P9_VECTOR && reload_completed"
1153 [(const_int 0)]
1154 {
1155 rtx dest = operands[0];
1156 rtx src = operands[1];
1157 int dest_regno = REGNO (dest);
1158 int src_regno = REGNO (src);
1159 rtx dest_v2di = gen_rtx_REG (V2DImode, dest_regno);
1160 rtx src_v4si = gen_rtx_REG (V4SImode, src_regno);
1161
1162 if (BYTES_BIG_ENDIAN)
1163 {
1164 emit_insn (gen_altivec_vupkhsw (dest_v2di, src_v4si));
1165 emit_insn (gen_vsx_xxspltd_v2di (dest_v2di, dest_v2di, const1_rtx));
1166 }
1167 else
1168 {
1169 emit_insn (gen_altivec_vupklsw (dest_v2di, src_v4si));
1170 emit_insn (gen_vsx_xxspltd_v2di (dest_v2di, dest_v2di, const0_rtx));
1171 }
1172 DONE;
1173 })
1174
1175 (define_insn_and_split "*extendsi<mode>2_dot"
1176 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1177 (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
1178 (const_int 0)))
1179 (clobber (match_scratch:EXTSI 0 "=r,r"))]
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
1195 (define_insn_and_split "*extendsi<mode>2_dot2"
1196 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1197 (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
1198 (const_int 0)))
1199 (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
1200 (sign_extend:EXTSI (match_dup 1)))]
1201 ""
1202 "@
1203 extsw. %0,%1
1204 #"
1205 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1206 [(set (match_dup 0)
1207 (sign_extend:EXTSI (match_dup 1)))
1208 (set (match_dup 2)
1209 (compare:CC (match_dup 0)
1210 (const_int 0)))]
1211 ""
1212 [(set_attr "type" "exts")
1213 (set_attr "dot" "yes")
1214 (set_attr "length" "4,8")])
1215 \f
1216 ;; IBM 405, 440, 464 and 476 half-word multiplication operations.
1217
1218 (define_insn "*macchwc"
1219 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1220 (compare:CC (plus:SI (mult:SI (ashiftrt:SI
1221 (match_operand:SI 2 "gpc_reg_operand" "r")
1222 (const_int 16))
1223 (sign_extend:SI
1224 (match_operand:HI 1 "gpc_reg_operand" "r")))
1225 (match_operand:SI 4 "gpc_reg_operand" "0"))
1226 (const_int 0)))
1227 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1228 (plus:SI (mult:SI (ashiftrt:SI
1229 (match_dup 2)
1230 (const_int 16))
1231 (sign_extend:SI
1232 (match_dup 1)))
1233 (match_dup 4)))]
1234 "TARGET_MULHW"
1235 "macchw. %0,%1,%2"
1236 [(set_attr "type" "halfmul")])
1237
1238 (define_insn "*macchw"
1239 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1240 (plus:SI (mult:SI (ashiftrt:SI
1241 (match_operand:SI 2 "gpc_reg_operand" "r")
1242 (const_int 16))
1243 (sign_extend:SI
1244 (match_operand:HI 1 "gpc_reg_operand" "r")))
1245 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1246 "TARGET_MULHW"
1247 "macchw %0,%1,%2"
1248 [(set_attr "type" "halfmul")])
1249
1250 (define_insn "*macchwuc"
1251 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1252 (compare:CC (plus:SI (mult:SI (lshiftrt:SI
1253 (match_operand:SI 2 "gpc_reg_operand" "r")
1254 (const_int 16))
1255 (zero_extend:SI
1256 (match_operand:HI 1 "gpc_reg_operand" "r")))
1257 (match_operand:SI 4 "gpc_reg_operand" "0"))
1258 (const_int 0)))
1259 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1260 (plus:SI (mult:SI (lshiftrt:SI
1261 (match_dup 2)
1262 (const_int 16))
1263 (zero_extend:SI
1264 (match_dup 1)))
1265 (match_dup 4)))]
1266 "TARGET_MULHW"
1267 "macchwu. %0,%1,%2"
1268 [(set_attr "type" "halfmul")])
1269
1270 (define_insn "*macchwu"
1271 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1272 (plus:SI (mult:SI (lshiftrt:SI
1273 (match_operand:SI 2 "gpc_reg_operand" "r")
1274 (const_int 16))
1275 (zero_extend:SI
1276 (match_operand:HI 1 "gpc_reg_operand" "r")))
1277 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1278 "TARGET_MULHW"
1279 "macchwu %0,%1,%2"
1280 [(set_attr "type" "halfmul")])
1281
1282 (define_insn "*machhwc"
1283 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1284 (compare:CC (plus:SI (mult:SI (ashiftrt:SI
1285 (match_operand:SI 1 "gpc_reg_operand" "%r")
1286 (const_int 16))
1287 (ashiftrt:SI
1288 (match_operand:SI 2 "gpc_reg_operand" "r")
1289 (const_int 16)))
1290 (match_operand:SI 4 "gpc_reg_operand" "0"))
1291 (const_int 0)))
1292 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1293 (plus:SI (mult:SI (ashiftrt:SI
1294 (match_dup 1)
1295 (const_int 16))
1296 (ashiftrt:SI
1297 (match_dup 2)
1298 (const_int 16)))
1299 (match_dup 4)))]
1300 "TARGET_MULHW"
1301 "machhw. %0,%1,%2"
1302 [(set_attr "type" "halfmul")])
1303
1304 (define_insn "*machhw"
1305 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1306 (plus:SI (mult:SI (ashiftrt:SI
1307 (match_operand:SI 1 "gpc_reg_operand" "%r")
1308 (const_int 16))
1309 (ashiftrt:SI
1310 (match_operand:SI 2 "gpc_reg_operand" "r")
1311 (const_int 16)))
1312 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1313 "TARGET_MULHW"
1314 "machhw %0,%1,%2"
1315 [(set_attr "type" "halfmul")])
1316
1317 (define_insn "*machhwuc"
1318 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1319 (compare:CC (plus:SI (mult:SI (lshiftrt:SI
1320 (match_operand:SI 1 "gpc_reg_operand" "%r")
1321 (const_int 16))
1322 (lshiftrt:SI
1323 (match_operand:SI 2 "gpc_reg_operand" "r")
1324 (const_int 16)))
1325 (match_operand:SI 4 "gpc_reg_operand" "0"))
1326 (const_int 0)))
1327 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1328 (plus:SI (mult:SI (lshiftrt:SI
1329 (match_dup 1)
1330 (const_int 16))
1331 (lshiftrt:SI
1332 (match_dup 2)
1333 (const_int 16)))
1334 (match_dup 4)))]
1335 "TARGET_MULHW"
1336 "machhwu. %0,%1,%2"
1337 [(set_attr "type" "halfmul")])
1338
1339 (define_insn "*machhwu"
1340 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1341 (plus:SI (mult:SI (lshiftrt:SI
1342 (match_operand:SI 1 "gpc_reg_operand" "%r")
1343 (const_int 16))
1344 (lshiftrt:SI
1345 (match_operand:SI 2 "gpc_reg_operand" "r")
1346 (const_int 16)))
1347 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1348 "TARGET_MULHW"
1349 "machhwu %0,%1,%2"
1350 [(set_attr "type" "halfmul")])
1351
1352 (define_insn "*maclhwc"
1353 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1354 (compare:CC (plus:SI (mult:SI (sign_extend:SI
1355 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1356 (sign_extend:SI
1357 (match_operand:HI 2 "gpc_reg_operand" "r")))
1358 (match_operand:SI 4 "gpc_reg_operand" "0"))
1359 (const_int 0)))
1360 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1361 (plus:SI (mult:SI (sign_extend:SI
1362 (match_dup 1))
1363 (sign_extend:SI
1364 (match_dup 2)))
1365 (match_dup 4)))]
1366 "TARGET_MULHW"
1367 "maclhw. %0,%1,%2"
1368 [(set_attr "type" "halfmul")])
1369
1370 (define_insn "*maclhw"
1371 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1372 (plus:SI (mult:SI (sign_extend:SI
1373 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1374 (sign_extend:SI
1375 (match_operand:HI 2 "gpc_reg_operand" "r")))
1376 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1377 "TARGET_MULHW"
1378 "maclhw %0,%1,%2"
1379 [(set_attr "type" "halfmul")])
1380
1381 (define_insn "*maclhwuc"
1382 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1383 (compare:CC (plus:SI (mult:SI (zero_extend:SI
1384 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1385 (zero_extend:SI
1386 (match_operand:HI 2 "gpc_reg_operand" "r")))
1387 (match_operand:SI 4 "gpc_reg_operand" "0"))
1388 (const_int 0)))
1389 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1390 (plus:SI (mult:SI (zero_extend:SI
1391 (match_dup 1))
1392 (zero_extend:SI
1393 (match_dup 2)))
1394 (match_dup 4)))]
1395 "TARGET_MULHW"
1396 "maclhwu. %0,%1,%2"
1397 [(set_attr "type" "halfmul")])
1398
1399 (define_insn "*maclhwu"
1400 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1401 (plus:SI (mult:SI (zero_extend:SI
1402 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1403 (zero_extend:SI
1404 (match_operand:HI 2 "gpc_reg_operand" "r")))
1405 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1406 "TARGET_MULHW"
1407 "maclhwu %0,%1,%2"
1408 [(set_attr "type" "halfmul")])
1409
1410 (define_insn "*nmacchwc"
1411 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1412 (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1413 (mult:SI (ashiftrt:SI
1414 (match_operand:SI 2 "gpc_reg_operand" "r")
1415 (const_int 16))
1416 (sign_extend:SI
1417 (match_operand:HI 1 "gpc_reg_operand" "r"))))
1418 (const_int 0)))
1419 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1420 (minus:SI (match_dup 4)
1421 (mult:SI (ashiftrt:SI
1422 (match_dup 2)
1423 (const_int 16))
1424 (sign_extend:SI
1425 (match_dup 1)))))]
1426 "TARGET_MULHW"
1427 "nmacchw. %0,%1,%2"
1428 [(set_attr "type" "halfmul")])
1429
1430 (define_insn "*nmacchw"
1431 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1432 (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1433 (mult:SI (ashiftrt:SI
1434 (match_operand:SI 2 "gpc_reg_operand" "r")
1435 (const_int 16))
1436 (sign_extend:SI
1437 (match_operand:HI 1 "gpc_reg_operand" "r")))))]
1438 "TARGET_MULHW"
1439 "nmacchw %0,%1,%2"
1440 [(set_attr "type" "halfmul")])
1441
1442 (define_insn "*nmachhwc"
1443 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1444 (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1445 (mult:SI (ashiftrt:SI
1446 (match_operand:SI 1 "gpc_reg_operand" "%r")
1447 (const_int 16))
1448 (ashiftrt:SI
1449 (match_operand:SI 2 "gpc_reg_operand" "r")
1450 (const_int 16))))
1451 (const_int 0)))
1452 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1453 (minus:SI (match_dup 4)
1454 (mult:SI (ashiftrt:SI
1455 (match_dup 1)
1456 (const_int 16))
1457 (ashiftrt:SI
1458 (match_dup 2)
1459 (const_int 16)))))]
1460 "TARGET_MULHW"
1461 "nmachhw. %0,%1,%2"
1462 [(set_attr "type" "halfmul")])
1463
1464 (define_insn "*nmachhw"
1465 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1466 (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1467 (mult:SI (ashiftrt:SI
1468 (match_operand:SI 1 "gpc_reg_operand" "%r")
1469 (const_int 16))
1470 (ashiftrt:SI
1471 (match_operand:SI 2 "gpc_reg_operand" "r")
1472 (const_int 16)))))]
1473 "TARGET_MULHW"
1474 "nmachhw %0,%1,%2"
1475 [(set_attr "type" "halfmul")])
1476
1477 (define_insn "*nmaclhwc"
1478 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1479 (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1480 (mult:SI (sign_extend:SI
1481 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1482 (sign_extend:SI
1483 (match_operand:HI 2 "gpc_reg_operand" "r"))))
1484 (const_int 0)))
1485 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1486 (minus:SI (match_dup 4)
1487 (mult:SI (sign_extend:SI
1488 (match_dup 1))
1489 (sign_extend:SI
1490 (match_dup 2)))))]
1491 "TARGET_MULHW"
1492 "nmaclhw. %0,%1,%2"
1493 [(set_attr "type" "halfmul")])
1494
1495 (define_insn "*nmaclhw"
1496 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1497 (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1498 (mult:SI (sign_extend:SI
1499 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1500 (sign_extend:SI
1501 (match_operand:HI 2 "gpc_reg_operand" "r")))))]
1502 "TARGET_MULHW"
1503 "nmaclhw %0,%1,%2"
1504 [(set_attr "type" "halfmul")])
1505
1506 (define_insn "*mulchwc"
1507 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1508 (compare:CC (mult:SI (ashiftrt:SI
1509 (match_operand:SI 2 "gpc_reg_operand" "r")
1510 (const_int 16))
1511 (sign_extend:SI
1512 (match_operand:HI 1 "gpc_reg_operand" "r")))
1513 (const_int 0)))
1514 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1515 (mult:SI (ashiftrt:SI
1516 (match_dup 2)
1517 (const_int 16))
1518 (sign_extend:SI
1519 (match_dup 1))))]
1520 "TARGET_MULHW"
1521 "mulchw. %0,%1,%2"
1522 [(set_attr "type" "halfmul")])
1523
1524 (define_insn "*mulchw"
1525 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1526 (mult:SI (ashiftrt:SI
1527 (match_operand:SI 2 "gpc_reg_operand" "r")
1528 (const_int 16))
1529 (sign_extend:SI
1530 (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1531 "TARGET_MULHW"
1532 "mulchw %0,%1,%2"
1533 [(set_attr "type" "halfmul")])
1534
1535 (define_insn "*mulchwuc"
1536 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1537 (compare:CC (mult:SI (lshiftrt:SI
1538 (match_operand:SI 2 "gpc_reg_operand" "r")
1539 (const_int 16))
1540 (zero_extend:SI
1541 (match_operand:HI 1 "gpc_reg_operand" "r")))
1542 (const_int 0)))
1543 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1544 (mult:SI (lshiftrt:SI
1545 (match_dup 2)
1546 (const_int 16))
1547 (zero_extend:SI
1548 (match_dup 1))))]
1549 "TARGET_MULHW"
1550 "mulchwu. %0,%1,%2"
1551 [(set_attr "type" "halfmul")])
1552
1553 (define_insn "*mulchwu"
1554 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1555 (mult:SI (lshiftrt:SI
1556 (match_operand:SI 2 "gpc_reg_operand" "r")
1557 (const_int 16))
1558 (zero_extend:SI
1559 (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1560 "TARGET_MULHW"
1561 "mulchwu %0,%1,%2"
1562 [(set_attr "type" "halfmul")])
1563
1564 (define_insn "*mulhhwc"
1565 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1566 (compare:CC (mult:SI (ashiftrt:SI
1567 (match_operand:SI 1 "gpc_reg_operand" "%r")
1568 (const_int 16))
1569 (ashiftrt:SI
1570 (match_operand:SI 2 "gpc_reg_operand" "r")
1571 (const_int 16)))
1572 (const_int 0)))
1573 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1574 (mult:SI (ashiftrt:SI
1575 (match_dup 1)
1576 (const_int 16))
1577 (ashiftrt:SI
1578 (match_dup 2)
1579 (const_int 16))))]
1580 "TARGET_MULHW"
1581 "mulhhw. %0,%1,%2"
1582 [(set_attr "type" "halfmul")])
1583
1584 (define_insn "*mulhhw"
1585 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1586 (mult:SI (ashiftrt:SI
1587 (match_operand:SI 1 "gpc_reg_operand" "%r")
1588 (const_int 16))
1589 (ashiftrt:SI
1590 (match_operand:SI 2 "gpc_reg_operand" "r")
1591 (const_int 16))))]
1592 "TARGET_MULHW"
1593 "mulhhw %0,%1,%2"
1594 [(set_attr "type" "halfmul")])
1595
1596 (define_insn "*mulhhwuc"
1597 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1598 (compare:CC (mult:SI (lshiftrt:SI
1599 (match_operand:SI 1 "gpc_reg_operand" "%r")
1600 (const_int 16))
1601 (lshiftrt:SI
1602 (match_operand:SI 2 "gpc_reg_operand" "r")
1603 (const_int 16)))
1604 (const_int 0)))
1605 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1606 (mult:SI (lshiftrt:SI
1607 (match_dup 1)
1608 (const_int 16))
1609 (lshiftrt:SI
1610 (match_dup 2)
1611 (const_int 16))))]
1612 "TARGET_MULHW"
1613 "mulhhwu. %0,%1,%2"
1614 [(set_attr "type" "halfmul")])
1615
1616 (define_insn "*mulhhwu"
1617 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1618 (mult:SI (lshiftrt:SI
1619 (match_operand:SI 1 "gpc_reg_operand" "%r")
1620 (const_int 16))
1621 (lshiftrt:SI
1622 (match_operand:SI 2 "gpc_reg_operand" "r")
1623 (const_int 16))))]
1624 "TARGET_MULHW"
1625 "mulhhwu %0,%1,%2"
1626 [(set_attr "type" "halfmul")])
1627
1628 (define_insn "*mullhwc"
1629 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1630 (compare:CC (mult:SI (sign_extend:SI
1631 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1632 (sign_extend:SI
1633 (match_operand:HI 2 "gpc_reg_operand" "r")))
1634 (const_int 0)))
1635 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1636 (mult:SI (sign_extend:SI
1637 (match_dup 1))
1638 (sign_extend:SI
1639 (match_dup 2))))]
1640 "TARGET_MULHW"
1641 "mullhw. %0,%1,%2"
1642 [(set_attr "type" "halfmul")])
1643
1644 (define_insn "*mullhw"
1645 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1646 (mult:SI (sign_extend:SI
1647 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1648 (sign_extend:SI
1649 (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1650 "TARGET_MULHW"
1651 "mullhw %0,%1,%2"
1652 [(set_attr "type" "halfmul")])
1653
1654 (define_insn "*mullhwuc"
1655 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1656 (compare:CC (mult:SI (zero_extend:SI
1657 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1658 (zero_extend:SI
1659 (match_operand:HI 2 "gpc_reg_operand" "r")))
1660 (const_int 0)))
1661 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1662 (mult:SI (zero_extend:SI
1663 (match_dup 1))
1664 (zero_extend:SI
1665 (match_dup 2))))]
1666 "TARGET_MULHW"
1667 "mullhwu. %0,%1,%2"
1668 [(set_attr "type" "halfmul")])
1669
1670 (define_insn "*mullhwu"
1671 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1672 (mult:SI (zero_extend:SI
1673 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1674 (zero_extend:SI
1675 (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1676 "TARGET_MULHW"
1677 "mullhwu %0,%1,%2"
1678 [(set_attr "type" "halfmul")])
1679 \f
1680 ;; IBM 405, 440, 464 and 476 string-search dlmzb instruction support.
1681 (define_insn "dlmzb"
1682 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1683 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
1684 (match_operand:SI 2 "gpc_reg_operand" "r")]
1685 UNSPEC_DLMZB_CR))
1686 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1687 (unspec:SI [(match_dup 1)
1688 (match_dup 2)]
1689 UNSPEC_DLMZB))]
1690 "TARGET_DLMZB"
1691 "dlmzb. %0,%1,%2")
1692
1693 (define_expand "strlensi"
1694 [(set (match_operand:SI 0 "gpc_reg_operand")
1695 (unspec:SI [(match_operand:BLK 1 "general_operand")
1696 (match_operand:QI 2 "const_int_operand")
1697 (match_operand 3 "const_int_operand")]
1698 UNSPEC_DLMZB_STRLEN))
1699 (clobber (match_scratch:CC 4))]
1700 "TARGET_DLMZB && WORDS_BIG_ENDIAN && !optimize_size"
1701 {
1702 rtx result = operands[0];
1703 rtx src = operands[1];
1704 rtx search_char = operands[2];
1705 rtx align = operands[3];
1706 rtx addr, scratch_string, word1, word2, scratch_dlmzb;
1707 rtx loop_label, end_label, mem, cr0, cond;
1708 if (search_char != const0_rtx
1709 || !CONST_INT_P (align)
1710 || INTVAL (align) < 8)
1711 FAIL;
1712 word1 = gen_reg_rtx (SImode);
1713 word2 = gen_reg_rtx (SImode);
1714 scratch_dlmzb = gen_reg_rtx (SImode);
1715 scratch_string = gen_reg_rtx (Pmode);
1716 loop_label = gen_label_rtx ();
1717 end_label = gen_label_rtx ();
1718 addr = force_reg (Pmode, XEXP (src, 0));
1719 emit_move_insn (scratch_string, addr);
1720 emit_label (loop_label);
1721 mem = change_address (src, SImode, scratch_string);
1722 emit_move_insn (word1, mem);
1723 emit_move_insn (word2, adjust_address (mem, SImode, 4));
1724 cr0 = gen_rtx_REG (CCmode, CR0_REGNO);
1725 emit_insn (gen_dlmzb (scratch_dlmzb, word1, word2, cr0));
1726 cond = gen_rtx_NE (VOIDmode, cr0, const0_rtx);
1727 emit_jump_insn (gen_rtx_SET (pc_rtx,
1728 gen_rtx_IF_THEN_ELSE (VOIDmode,
1729 cond,
1730 gen_rtx_LABEL_REF
1731 (VOIDmode,
1732 end_label),
1733 pc_rtx)));
1734 emit_insn (gen_addsi3 (scratch_string, scratch_string, GEN_INT (8)));
1735 emit_jump_insn (gen_rtx_SET (pc_rtx,
1736 gen_rtx_LABEL_REF (VOIDmode, loop_label)));
1737 emit_barrier ();
1738 emit_label (end_label);
1739 emit_insn (gen_addsi3 (scratch_string, scratch_string, scratch_dlmzb));
1740 emit_insn (gen_subsi3 (result, scratch_string, addr));
1741 emit_insn (gen_addsi3 (result, result, constm1_rtx));
1742 DONE;
1743 })
1744 \f
1745 ;; Fixed-point arithmetic insns.
1746
1747 (define_expand "add<mode>3"
1748 [(set (match_operand:SDI 0 "gpc_reg_operand")
1749 (plus:SDI (match_operand:SDI 1 "gpc_reg_operand")
1750 (match_operand:SDI 2 "reg_or_add_cint_operand")))]
1751 ""
1752 {
1753 if (<MODE>mode == DImode && !TARGET_POWERPC64)
1754 {
1755 rtx lo0 = gen_lowpart (SImode, operands[0]);
1756 rtx lo1 = gen_lowpart (SImode, operands[1]);
1757 rtx lo2 = gen_lowpart (SImode, operands[2]);
1758 rtx hi0 = gen_highpart (SImode, operands[0]);
1759 rtx hi1 = gen_highpart (SImode, operands[1]);
1760 rtx hi2 = gen_highpart_mode (SImode, DImode, operands[2]);
1761
1762 if (!reg_or_short_operand (lo2, SImode))
1763 lo2 = force_reg (SImode, lo2);
1764 if (!adde_operand (hi2, SImode))
1765 hi2 = force_reg (SImode, hi2);
1766
1767 emit_insn (gen_addsi3_carry (lo0, lo1, lo2));
1768 emit_insn (gen_addsi3_carry_in (hi0, hi1, hi2));
1769 DONE;
1770 }
1771
1772 if (CONST_INT_P (operands[2]) && !add_operand (operands[2], <MODE>mode))
1773 {
1774 rtx tmp = ((!can_create_pseudo_p ()
1775 || rtx_equal_p (operands[0], operands[1]))
1776 ? operands[0] : gen_reg_rtx (<MODE>mode));
1777
1778 /* Adding a constant to r0 is not a valid insn, so use a different
1779 strategy in that case. */
1780 if (reg_or_subregno (operands[1]) == 0 || reg_or_subregno (tmp) == 0)
1781 {
1782 if (operands[0] == operands[1])
1783 FAIL;
1784 rs6000_emit_move (operands[0], operands[2], <MODE>mode);
1785 emit_insn (gen_add<mode>3 (operands[0], operands[1], operands[0]));
1786 DONE;
1787 }
1788
1789 HOST_WIDE_INT val = INTVAL (operands[2]);
1790 HOST_WIDE_INT low = sext_hwi (val, 16);
1791 HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1792
1793 if (<MODE>mode == DImode && !satisfies_constraint_L (GEN_INT (rest)))
1794 FAIL;
1795
1796 /* The ordering here is important for the prolog expander.
1797 When space is allocated from the stack, adding 'low' first may
1798 produce a temporary deallocation (which would be bad). */
1799 emit_insn (gen_add<mode>3 (tmp, operands[1], GEN_INT (rest)));
1800 emit_insn (gen_add<mode>3 (operands[0], tmp, GEN_INT (low)));
1801 DONE;
1802 }
1803 })
1804
1805 (define_insn "*add<mode>3"
1806 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r,r,r")
1807 (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b,b,b")
1808 (match_operand:GPR 2 "add_operand" "r,I,L,eI")))]
1809 ""
1810 "@
1811 add %0,%1,%2
1812 addi %0,%1,%2
1813 addis %0,%1,%v2
1814 addi %0,%1,%2"
1815 [(set_attr "type" "add")
1816 (set_attr "isa" "*,*,*,p10")])
1817
1818 (define_insn "*addsi3_high"
1819 [(set (match_operand:SI 0 "gpc_reg_operand" "=b")
1820 (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
1821 (high:SI (match_operand 2 "" ""))))]
1822 "TARGET_MACHO && !TARGET_64BIT"
1823 "addis %0,%1,ha16(%2)"
1824 [(set_attr "type" "add")])
1825
1826 (define_insn_and_split "*add<mode>3_dot"
1827 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1828 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
1829 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
1830 (const_int 0)))
1831 (clobber (match_scratch:GPR 0 "=r,r"))]
1832 "<MODE>mode == Pmode"
1833 "@
1834 add. %0,%1,%2
1835 #"
1836 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1837 [(set (match_dup 0)
1838 (plus:GPR (match_dup 1)
1839 (match_dup 2)))
1840 (set (match_dup 3)
1841 (compare:CC (match_dup 0)
1842 (const_int 0)))]
1843 ""
1844 [(set_attr "type" "add")
1845 (set_attr "dot" "yes")
1846 (set_attr "length" "4,8")])
1847
1848 (define_insn_and_split "*add<mode>3_dot2"
1849 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1850 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
1851 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
1852 (const_int 0)))
1853 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1854 (plus:GPR (match_dup 1)
1855 (match_dup 2)))]
1856 "<MODE>mode == Pmode"
1857 "@
1858 add. %0,%1,%2
1859 #"
1860 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1861 [(set (match_dup 0)
1862 (plus:GPR (match_dup 1)
1863 (match_dup 2)))
1864 (set (match_dup 3)
1865 (compare:CC (match_dup 0)
1866 (const_int 0)))]
1867 ""
1868 [(set_attr "type" "add")
1869 (set_attr "dot" "yes")
1870 (set_attr "length" "4,8")])
1871
1872 (define_insn_and_split "*add<mode>3_imm_dot"
1873 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1874 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b")
1875 (match_operand:GPR 2 "short_cint_operand" "I,I"))
1876 (const_int 0)))
1877 (clobber (match_scratch:GPR 0 "=r,r"))
1878 (clobber (reg:GPR CA_REGNO))]
1879 "<MODE>mode == Pmode"
1880 "@
1881 addic. %0,%1,%2
1882 #"
1883 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1884 [(set (match_dup 0)
1885 (plus:GPR (match_dup 1)
1886 (match_dup 2)))
1887 (set (match_dup 3)
1888 (compare:CC (match_dup 0)
1889 (const_int 0)))]
1890 ""
1891 [(set_attr "type" "add")
1892 (set_attr "dot" "yes")
1893 (set_attr "length" "4,8")])
1894
1895 (define_insn_and_split "*add<mode>3_imm_dot2"
1896 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1897 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b")
1898 (match_operand:GPR 2 "short_cint_operand" "I,I"))
1899 (const_int 0)))
1900 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1901 (plus:GPR (match_dup 1)
1902 (match_dup 2)))
1903 (clobber (reg:GPR CA_REGNO))]
1904 "<MODE>mode == Pmode"
1905 "@
1906 addic. %0,%1,%2
1907 #"
1908 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1909 [(set (match_dup 0)
1910 (plus:GPR (match_dup 1)
1911 (match_dup 2)))
1912 (set (match_dup 3)
1913 (compare:CC (match_dup 0)
1914 (const_int 0)))]
1915 ""
1916 [(set_attr "type" "add")
1917 (set_attr "dot" "yes")
1918 (set_attr "length" "4,8")])
1919
1920 ;; Split an add that we can't do in one insn into two insns, each of which
1921 ;; does one 16-bit part. This is used by combine. Note that the low-order
1922 ;; add should be last in case the result gets used in an address.
1923
1924 (define_split
1925 [(set (match_operand:GPR 0 "gpc_reg_operand")
1926 (plus:GPR (match_operand:GPR 1 "gpc_reg_operand")
1927 (match_operand:GPR 2 "non_add_cint_operand")))]
1928 ""
1929 [(set (match_dup 0) (plus:GPR (match_dup 1) (match_dup 3)))
1930 (set (match_dup 0) (plus:GPR (match_dup 0) (match_dup 4)))]
1931 {
1932 HOST_WIDE_INT val = INTVAL (operands[2]);
1933 HOST_WIDE_INT low = sext_hwi (val, 16);
1934 HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1935
1936 operands[4] = GEN_INT (low);
1937 if (<MODE>mode == SImode || satisfies_constraint_L (GEN_INT (rest)))
1938 operands[3] = GEN_INT (rest);
1939 else if (can_create_pseudo_p ())
1940 {
1941 operands[3] = gen_reg_rtx (DImode);
1942 emit_move_insn (operands[3], operands[2]);
1943 emit_insn (gen_adddi3 (operands[0], operands[1], operands[3]));
1944 DONE;
1945 }
1946 else
1947 FAIL;
1948 })
1949
1950
1951 (define_insn "add<mode>3_carry"
1952 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1953 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1954 (match_operand:P 2 "reg_or_short_operand" "rI")))
1955 (set (reg:P CA_REGNO)
1956 (ltu:P (plus:P (match_dup 1)
1957 (match_dup 2))
1958 (match_dup 1)))]
1959 ""
1960 "add%I2c %0,%1,%2"
1961 [(set_attr "type" "add")])
1962
1963 (define_insn "*add<mode>3_imm_carry_pos"
1964 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1965 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1966 (match_operand:P 2 "short_cint_operand" "n")))
1967 (set (reg:P CA_REGNO)
1968 (geu:P (match_dup 1)
1969 (match_operand:P 3 "const_int_operand" "n")))]
1970 "INTVAL (operands[2]) > 0
1971 && INTVAL (operands[2]) + INTVAL (operands[3]) == 0"
1972 "addic %0,%1,%2"
1973 [(set_attr "type" "add")])
1974
1975 (define_insn "*add<mode>3_imm_carry_0"
1976 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1977 (match_operand:P 1 "gpc_reg_operand" "r"))
1978 (set (reg:P CA_REGNO)
1979 (const_int 0))]
1980 ""
1981 "addic %0,%1,0"
1982 [(set_attr "type" "add")])
1983
1984 (define_insn "*add<mode>3_imm_carry_m1"
1985 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1986 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1987 (const_int -1)))
1988 (set (reg:P CA_REGNO)
1989 (ne:P (match_dup 1)
1990 (const_int 0)))]
1991 ""
1992 "addic %0,%1,-1"
1993 [(set_attr "type" "add")])
1994
1995 (define_insn "*add<mode>3_imm_carry_neg"
1996 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1997 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1998 (match_operand:P 2 "short_cint_operand" "n")))
1999 (set (reg:P CA_REGNO)
2000 (gtu:P (match_dup 1)
2001 (match_operand:P 3 "const_int_operand" "n")))]
2002 "INTVAL (operands[2]) < 0
2003 && INTVAL (operands[2]) + INTVAL (operands[3]) == -1"
2004 "addic %0,%1,%2"
2005 [(set_attr "type" "add")])
2006
2007
2008 (define_expand "add<mode>3_carry_in"
2009 [(parallel [
2010 (set (match_operand:GPR 0 "gpc_reg_operand")
2011 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand")
2012 (match_operand:GPR 2 "adde_operand"))
2013 (reg:GPR CA_REGNO)))
2014 (clobber (reg:GPR CA_REGNO))])]
2015 ""
2016 {
2017 if (operands[2] == const0_rtx)
2018 {
2019 emit_insn (gen_add<mode>3_carry_in_0 (operands[0], operands[1]));
2020 DONE;
2021 }
2022 if (operands[2] == constm1_rtx)
2023 {
2024 emit_insn (gen_add<mode>3_carry_in_m1 (operands[0], operands[1]));
2025 DONE;
2026 }
2027 })
2028
2029 (define_insn "*add<mode>3_carry_in_internal"
2030 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2031 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
2032 (match_operand:GPR 2 "gpc_reg_operand" "r"))
2033 (reg:GPR CA_REGNO)))
2034 (clobber (reg:GPR CA_REGNO))]
2035 ""
2036 "adde %0,%1,%2"
2037 [(set_attr "type" "add")])
2038
2039 (define_insn "*add<mode>3_carry_in_internal2"
2040 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2041 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
2042 (reg:GPR CA_REGNO))
2043 (match_operand:GPR 2 "gpc_reg_operand" "r")))
2044 (clobber (reg:GPR CA_REGNO))]
2045 ""
2046 "adde %0,%1,%2"
2047 [(set_attr "type" "add")])
2048
2049 (define_insn "add<mode>3_carry_in_0"
2050 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2051 (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
2052 (reg:GPR CA_REGNO)))
2053 (clobber (reg:GPR CA_REGNO))]
2054 ""
2055 "addze %0,%1"
2056 [(set_attr "type" "add")])
2057
2058 (define_insn "add<mode>3_carry_in_m1"
2059 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2060 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
2061 (reg:GPR CA_REGNO))
2062 (const_int -1)))
2063 (clobber (reg:GPR CA_REGNO))]
2064 ""
2065 "addme %0,%1"
2066 [(set_attr "type" "add")])
2067
2068
2069 (define_expand "one_cmpl<mode>2"
2070 [(set (match_operand:SDI 0 "gpc_reg_operand")
2071 (not:SDI (match_operand:SDI 1 "gpc_reg_operand")))]
2072 ""
2073 {
2074 if (<MODE>mode == DImode && !TARGET_POWERPC64)
2075 {
2076 rs6000_split_logical (operands, NOT, false, false, false);
2077 DONE;
2078 }
2079 })
2080
2081 (define_insn "*one_cmpl<mode>2"
2082 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2083 (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2084 ""
2085 "not %0,%1")
2086
2087 (define_insn_and_split "*one_cmpl<mode>2_dot"
2088 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2089 (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2090 (const_int 0)))
2091 (clobber (match_scratch:GPR 0 "=r,r"))]
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 (define_insn_and_split "*one_cmpl<mode>2_dot2"
2108 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2109 (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2110 (const_int 0)))
2111 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2112 (not:GPR (match_dup 1)))]
2113 "<MODE>mode == Pmode"
2114 "@
2115 not. %0,%1
2116 #"
2117 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2118 [(set (match_dup 0)
2119 (not:GPR (match_dup 1)))
2120 (set (match_dup 2)
2121 (compare:CC (match_dup 0)
2122 (const_int 0)))]
2123 ""
2124 [(set_attr "type" "logical")
2125 (set_attr "dot" "yes")
2126 (set_attr "length" "4,8")])
2127
2128
2129 (define_expand "sub<mode>3"
2130 [(set (match_operand:SDI 0 "gpc_reg_operand")
2131 (minus:SDI (match_operand:SDI 1 "reg_or_short_operand")
2132 (match_operand:SDI 2 "gpc_reg_operand")))]
2133 ""
2134 {
2135 if (<MODE>mode == DImode && !TARGET_POWERPC64)
2136 {
2137 rtx lo0 = gen_lowpart (SImode, operands[0]);
2138 rtx lo1 = gen_lowpart (SImode, operands[1]);
2139 rtx lo2 = gen_lowpart (SImode, operands[2]);
2140 rtx hi0 = gen_highpart (SImode, operands[0]);
2141 rtx hi1 = gen_highpart_mode (SImode, DImode, operands[1]);
2142 rtx hi2 = gen_highpart (SImode, operands[2]);
2143
2144 if (!reg_or_short_operand (lo1, SImode))
2145 lo1 = force_reg (SImode, lo1);
2146 if (!adde_operand (hi1, SImode))
2147 hi1 = force_reg (SImode, hi1);
2148
2149 emit_insn (gen_subfsi3_carry (lo0, lo2, lo1));
2150 emit_insn (gen_subfsi3_carry_in (hi0, hi2, hi1));
2151 DONE;
2152 }
2153
2154 if (short_cint_operand (operands[1], <MODE>mode))
2155 {
2156 emit_insn (gen_subf<mode>3_imm (operands[0], operands[2], operands[1]));
2157 DONE;
2158 }
2159 })
2160
2161 (define_insn "*subf<mode>3"
2162 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2163 (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r")
2164 (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2165 ""
2166 "subf %0,%1,%2"
2167 [(set_attr "type" "add")])
2168
2169 (define_insn_and_split "*subf<mode>3_dot"
2170 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2171 (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
2172 (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2173 (const_int 0)))
2174 (clobber (match_scratch:GPR 0 "=r,r"))]
2175 "<MODE>mode == Pmode"
2176 "@
2177 subf. %0,%1,%2
2178 #"
2179 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2180 [(set (match_dup 0)
2181 (minus:GPR (match_dup 2)
2182 (match_dup 1)))
2183 (set (match_dup 3)
2184 (compare:CC (match_dup 0)
2185 (const_int 0)))]
2186 ""
2187 [(set_attr "type" "add")
2188 (set_attr "dot" "yes")
2189 (set_attr "length" "4,8")])
2190
2191 (define_insn_and_split "*subf<mode>3_dot2"
2192 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2193 (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
2194 (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2195 (const_int 0)))
2196 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2197 (minus:GPR (match_dup 2)
2198 (match_dup 1)))]
2199 "<MODE>mode == Pmode"
2200 "@
2201 subf. %0,%1,%2
2202 #"
2203 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2204 [(set (match_dup 0)
2205 (minus:GPR (match_dup 2)
2206 (match_dup 1)))
2207 (set (match_dup 3)
2208 (compare:CC (match_dup 0)
2209 (const_int 0)))]
2210 ""
2211 [(set_attr "type" "add")
2212 (set_attr "dot" "yes")
2213 (set_attr "length" "4,8")])
2214
2215 (define_insn "subf<mode>3_imm"
2216 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2217 (minus:GPR (match_operand:GPR 2 "short_cint_operand" "I")
2218 (match_operand:GPR 1 "gpc_reg_operand" "r")))
2219 (clobber (reg:GPR CA_REGNO))]
2220 ""
2221 "subfic %0,%1,%2"
2222 [(set_attr "type" "add")])
2223
2224 (define_insn_and_split "subf<mode>3_carry_dot2"
2225 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2226 (compare:CC (minus:P (match_operand:P 2 "gpc_reg_operand" "r,r")
2227 (match_operand:P 1 "gpc_reg_operand" "r,r"))
2228 (const_int 0)))
2229 (set (match_operand:P 0 "gpc_reg_operand" "=r,r")
2230 (minus:P (match_dup 2)
2231 (match_dup 1)))
2232 (set (reg:P CA_REGNO)
2233 (leu:P (match_dup 1)
2234 (match_dup 2)))]
2235 "<MODE>mode == Pmode"
2236 "@
2237 subfc. %0,%1,%2
2238 #"
2239 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2240 [(parallel [(set (match_dup 0)
2241 (minus:P (match_dup 2)
2242 (match_dup 1)))
2243 (set (reg:P CA_REGNO)
2244 (leu:P (match_dup 1)
2245 (match_dup 2)))])
2246 (set (match_dup 3)
2247 (compare:CC (match_dup 0)
2248 (const_int 0)))]
2249 ""
2250 [(set_attr "type" "add")
2251 (set_attr "dot" "yes")
2252 (set_attr "length" "4,8")])
2253
2254 (define_insn "subf<mode>3_carry"
2255 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2256 (minus:P (match_operand:P 2 "reg_or_short_operand" "rI")
2257 (match_operand:P 1 "gpc_reg_operand" "r")))
2258 (set (reg:P CA_REGNO)
2259 (leu:P (match_dup 1)
2260 (match_dup 2)))]
2261 ""
2262 "subf%I2c %0,%1,%2"
2263 [(set_attr "type" "add")])
2264
2265 (define_insn "*subf<mode>3_imm_carry_0"
2266 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2267 (neg:P (match_operand:P 1 "gpc_reg_operand" "r")))
2268 (set (reg:P CA_REGNO)
2269 (eq:P (match_dup 1)
2270 (const_int 0)))]
2271 ""
2272 "subfic %0,%1,0"
2273 [(set_attr "type" "add")])
2274
2275 (define_insn "*subf<mode>3_imm_carry_m1"
2276 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2277 (not:P (match_operand:P 1 "gpc_reg_operand" "r")))
2278 (set (reg:P CA_REGNO)
2279 (const_int 1))]
2280 ""
2281 "subfic %0,%1,-1"
2282 [(set_attr "type" "add")])
2283
2284
2285 (define_expand "subf<mode>3_carry_in"
2286 [(parallel [
2287 (set (match_operand:GPR 0 "gpc_reg_operand")
2288 (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand"))
2289 (reg:GPR CA_REGNO))
2290 (match_operand:GPR 2 "adde_operand")))
2291 (clobber (reg:GPR CA_REGNO))])]
2292 ""
2293 {
2294 if (operands[2] == const0_rtx)
2295 {
2296 emit_insn (gen_subf<mode>3_carry_in_0 (operands[0], operands[1]));
2297 DONE;
2298 }
2299 if (operands[2] == constm1_rtx)
2300 {
2301 emit_insn (gen_subf<mode>3_carry_in_m1 (operands[0], operands[1]));
2302 DONE;
2303 }
2304 })
2305
2306 (define_insn "*subf<mode>3_carry_in_internal"
2307 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2308 (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
2309 (reg:GPR CA_REGNO))
2310 (match_operand:GPR 2 "gpc_reg_operand" "r")))
2311 (clobber (reg:GPR CA_REGNO))]
2312 ""
2313 "subfe %0,%1,%2"
2314 [(set_attr "type" "add")])
2315
2316 (define_insn "subf<mode>3_carry_in_0"
2317 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2318 (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
2319 (reg:GPR CA_REGNO)))
2320 (clobber (reg:GPR CA_REGNO))]
2321 ""
2322 "subfze %0,%1"
2323 [(set_attr "type" "add")])
2324
2325 (define_insn "subf<mode>3_carry_in_m1"
2326 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2327 (plus:GPR (minus:GPR (reg:GPR CA_REGNO)
2328 (match_operand:GPR 1 "gpc_reg_operand" "r"))
2329 (const_int -2)))
2330 (clobber (reg:GPR CA_REGNO))]
2331 ""
2332 "subfme %0,%1"
2333 [(set_attr "type" "add")])
2334
2335 (define_insn "subf<mode>3_carry_in_xx"
2336 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2337 (plus:GPR (reg:GPR CA_REGNO)
2338 (const_int -1)))
2339 (clobber (reg:GPR CA_REGNO))]
2340 ""
2341 "subfe %0,%0,%0"
2342 [(set_attr "type" "add")])
2343
2344 (define_insn_and_split "*subfsi3_carry_in_xx_64"
2345 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2346 (sign_extend:DI (plus:SI (reg:SI CA_REGNO)
2347 (const_int -1))))]
2348 "TARGET_POWERPC64"
2349 "#"
2350 "&&1"
2351 [(parallel [(set (match_dup 0)
2352 (plus:DI (reg:DI CA_REGNO)
2353 (const_int -1)))
2354 (clobber (reg:DI CA_REGNO))])]
2355 ""
2356 )
2357
2358 (define_insn "@neg<mode>2"
2359 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2360 (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2361 ""
2362 "neg %0,%1"
2363 [(set_attr "type" "add")])
2364
2365 (define_insn_and_split "*neg<mode>2_dot"
2366 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2367 (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2368 (const_int 0)))
2369 (clobber (match_scratch:GPR 0 "=r,r"))]
2370 "<MODE>mode == Pmode"
2371 "@
2372 neg. %0,%1
2373 #"
2374 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2375 [(set (match_dup 0)
2376 (neg:GPR (match_dup 1)))
2377 (set (match_dup 2)
2378 (compare:CC (match_dup 0)
2379 (const_int 0)))]
2380 ""
2381 [(set_attr "type" "add")
2382 (set_attr "dot" "yes")
2383 (set_attr "length" "4,8")])
2384
2385 (define_insn_and_split "*neg<mode>2_dot2"
2386 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2387 (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2388 (const_int 0)))
2389 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2390 (neg:GPR (match_dup 1)))]
2391 "<MODE>mode == Pmode"
2392 "@
2393 neg. %0,%1
2394 #"
2395 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2396 [(set (match_dup 0)
2397 (neg:GPR (match_dup 1)))
2398 (set (match_dup 2)
2399 (compare:CC (match_dup 0)
2400 (const_int 0)))]
2401 ""
2402 [(set_attr "type" "add")
2403 (set_attr "dot" "yes")
2404 (set_attr "length" "4,8")])
2405
2406
2407 (define_insn "clz<mode>2"
2408 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2409 (clz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2410 ""
2411 "cntlz<wd> %0,%1"
2412 [(set_attr "type" "cntlz")])
2413
2414 (define_expand "ctz<mode>2"
2415 [(set (match_operand:GPR 0 "gpc_reg_operand")
2416 (ctz:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2417 ""
2418 {
2419 if (TARGET_CTZ)
2420 {
2421 emit_insn (gen_ctz<mode>2_hw (operands[0], operands[1]));
2422 DONE;
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
2429 if (TARGET_POPCNTD)
2430 {
2431 emit_insn (gen_add<mode>3 (tmp1, operands[1], constm1_rtx));
2432 emit_insn (gen_one_cmpl<mode>2 (tmp2, operands[1]));
2433 emit_insn (gen_and<mode>3 (tmp3, tmp1, tmp2));
2434 emit_insn (gen_popcntd<mode>2 (operands[0], tmp3));
2435 }
2436 else
2437 {
2438 emit_insn (gen_neg<mode>2 (tmp1, operands[1]));
2439 emit_insn (gen_and<mode>3 (tmp2, operands[1], tmp1));
2440 emit_insn (gen_clz<mode>2 (tmp3, tmp2));
2441 emit_insn (gen_sub<mode>3 (operands[0], GEN_INT (<bits> - 1), tmp3));
2442 }
2443
2444 DONE;
2445 })
2446
2447 (define_insn "ctz<mode>2_hw"
2448 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2449 (ctz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2450 "TARGET_CTZ"
2451 "cnttz<wd> %0,%1"
2452 [(set_attr "type" "cntlz")])
2453
2454 (define_expand "ffs<mode>2"
2455 [(set (match_operand:GPR 0 "gpc_reg_operand")
2456 (ffs:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2457 ""
2458 {
2459 rtx tmp1 = gen_reg_rtx (<MODE>mode);
2460 rtx tmp2 = gen_reg_rtx (<MODE>mode);
2461 rtx tmp3 = gen_reg_rtx (<MODE>mode);
2462 emit_insn (gen_neg<mode>2 (tmp1, operands[1]));
2463 emit_insn (gen_and<mode>3 (tmp2, operands[1], tmp1));
2464 emit_insn (gen_clz<mode>2 (tmp3, tmp2));
2465 emit_insn (gen_sub<mode>3 (operands[0], GEN_INT (<bits>), tmp3));
2466 DONE;
2467 })
2468
2469
2470 (define_expand "popcount<mode>2"
2471 [(set (match_operand:GPR 0 "gpc_reg_operand")
2472 (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2473 "TARGET_POPCNTB || TARGET_POPCNTD"
2474 {
2475 rs6000_emit_popcount (operands[0], operands[1]);
2476 DONE;
2477 })
2478
2479 (define_insn "popcntb<mode>2"
2480 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2481 (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")]
2482 UNSPEC_POPCNTB))]
2483 "TARGET_POPCNTB"
2484 "popcntb %0,%1"
2485 [(set_attr "type" "popcnt")])
2486
2487 (define_insn "popcntd<mode>2"
2488 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2489 (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2490 "TARGET_POPCNTD"
2491 "popcnt<wd> %0,%1"
2492 [(set_attr "type" "popcnt")])
2493
2494
2495 (define_expand "parity<mode>2"
2496 [(set (match_operand:GPR 0 "gpc_reg_operand")
2497 (parity:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2498 "TARGET_POPCNTB"
2499 {
2500 rs6000_emit_parity (operands[0], operands[1]);
2501 DONE;
2502 })
2503
2504 (define_insn "parity<mode>2_cmpb"
2505 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2506 (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")] UNSPEC_PARITY))]
2507 "TARGET_CMPB && TARGET_POPCNTB"
2508 "prty<wd> %0,%1"
2509 [(set_attr "type" "popcnt")])
2510
2511 (define_insn "cfuged"
2512 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2513 (unspec:DI [(match_operand:DI 1 "gpc_reg_operand" "r")
2514 (match_operand:DI 2 "gpc_reg_operand" "r")]
2515 UNSPEC_CFUGED))]
2516 "TARGET_POWER10 && TARGET_64BIT"
2517 "cfuged %0,%1,%2"
2518 [(set_attr "type" "integer")])
2519
2520 (define_insn "cntlzdm"
2521 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2522 (unspec:DI [(match_operand:DI 1 "gpc_reg_operand" "r")
2523 (match_operand:DI 2 "gpc_reg_operand" "r")]
2524 UNSPEC_CNTLZDM))]
2525 "TARGET_POWER10 && TARGET_POWERPC64"
2526 "cntlzdm %0,%1,%2"
2527 [(set_attr "type" "integer")])
2528
2529 (define_insn "cnttzdm"
2530 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2531 (unspec:DI [(match_operand:DI 1 "gpc_reg_operand" "r")
2532 (match_operand:DI 2 "gpc_reg_operand" "r")]
2533 UNSPEC_CNTTZDM))]
2534 "TARGET_POWER10 && TARGET_POWERPC64"
2535 "cnttzdm %0,%1,%2"
2536 [(set_attr "type" "integer")])
2537
2538 (define_insn "pdepd"
2539 [(set (match_operand:DI 0 "register_operand" "=r")
2540 (unspec:DI [(match_operand:DI 1 "gpc_reg_operand" "r")
2541 (match_operand:DI 2 "gpc_reg_operand" "r")]
2542 UNSPEC_PDEPD))]
2543 "TARGET_POWER10 && TARGET_POWERPC64"
2544 "pdepd %0,%1,%2"
2545 [(set_attr "type" "integer")])
2546
2547 (define_insn "pextd"
2548 [(set (match_operand:DI 0 "register_operand" "=r")
2549 (unspec:DI [(match_operand:DI 1 "gpc_reg_operand" "r")
2550 (match_operand:DI 2 "gpc_reg_operand" "r")]
2551 UNSPEC_PEXTD))]
2552 "TARGET_POWER10 && TARGET_POWERPC64"
2553 "pextd %0,%1,%2"
2554 [(set_attr "type" "integer")])
2555
2556 (define_insn "cmpb<mode>3"
2557 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2558 (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")
2559 (match_operand:GPR 2 "gpc_reg_operand" "r")] UNSPEC_CMPB))]
2560 "TARGET_CMPB"
2561 "cmpb %0,%1,%2"
2562 [(set_attr "type" "cmp")])
2563
2564 ;; Since the hardware zeros the upper part of the register, save generating the
2565 ;; AND immediate if we are converting to unsigned
2566 (define_insn "*bswap<mode>2_extenddi"
2567 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2568 (zero_extend:DI
2569 (bswap:HSI (match_operand:HSI 1 "memory_operand" "Z"))))]
2570 "TARGET_POWERPC64"
2571 "l<wd>brx %0,%y1"
2572 [(set_attr "type" "load")])
2573
2574 (define_insn "*bswaphi2_extendsi"
2575 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2576 (zero_extend:SI
2577 (bswap:HI (match_operand:HI 1 "memory_operand" "Z"))))]
2578 ""
2579 "lhbrx %0,%y1"
2580 [(set_attr "type" "load")])
2581
2582 ;; Separate the bswap patterns into load, store, and gpr<-gpr. This prevents
2583 ;; the register allocator from converting a gpr<-gpr swap into a store and then
2584 ;; load with byte swap, which can be slower than doing it in the registers. It
2585 ;; also prevents certain failures with the RELOAD register allocator.
2586
2587 (define_expand "bswap<mode>2"
2588 [(use (match_operand:HSI 0 "reg_or_mem_operand"))
2589 (use (match_operand:HSI 1 "reg_or_mem_operand"))]
2590 ""
2591 {
2592 rtx dest = operands[0];
2593 rtx src = operands[1];
2594
2595 if (!REG_P (dest) && !REG_P (src))
2596 src = force_reg (<MODE>mode, src);
2597
2598 if (MEM_P (src))
2599 {
2600 src = rs6000_force_indexed_or_indirect_mem (src);
2601 emit_insn (gen_bswap<mode>2_load (dest, src));
2602 }
2603 else if (MEM_P (dest))
2604 {
2605 dest = rs6000_force_indexed_or_indirect_mem (dest);
2606 emit_insn (gen_bswap<mode>2_store (dest, src));
2607 }
2608 else
2609 emit_insn (gen_bswap<mode>2_reg (dest, src));
2610 DONE;
2611 })
2612
2613 (define_insn "bswap<mode>2_load"
2614 [(set (match_operand:HSI 0 "gpc_reg_operand" "=r")
2615 (bswap:HSI (match_operand:HSI 1 "memory_operand" "Z")))]
2616 ""
2617 "l<wd>brx %0,%y1"
2618 [(set_attr "type" "load")])
2619
2620 (define_insn "bswap<mode>2_store"
2621 [(set (match_operand:HSI 0 "memory_operand" "=Z")
2622 (bswap:HSI (match_operand:HSI 1 "gpc_reg_operand" "r")))]
2623 ""
2624 "st<wd>brx %1,%y0"
2625 [(set_attr "type" "store")])
2626
2627 (define_insn_and_split "bswaphi2_reg"
2628 [(set (match_operand:HI 0 "gpc_reg_operand" "=r,&r,wa")
2629 (bswap:HI
2630 (match_operand:HI 1 "gpc_reg_operand" "r,r,wa")))
2631 (clobber (match_scratch:SI 2 "=X,&r,X"))]
2632 ""
2633 "@
2634 brh %0,%1
2635 #
2636 xxbrh %x0,%x1"
2637 "reload_completed && !TARGET_POWER10 && int_reg_operand (operands[0], HImode)"
2638 [(set (match_dup 3)
2639 (and:SI (lshiftrt:SI (match_dup 4)
2640 (const_int 8))
2641 (const_int 255)))
2642 (set (match_dup 2)
2643 (and:SI (ashift:SI (match_dup 4)
2644 (const_int 8))
2645 (const_int 65280))) ;; 0xff00
2646 (set (match_dup 3)
2647 (ior:SI (match_dup 3)
2648 (match_dup 2)))]
2649 {
2650 operands[3] = simplify_gen_subreg (SImode, operands[0], HImode, 0);
2651 operands[4] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
2652 }
2653 [(set_attr "length" "*,12,*")
2654 (set_attr "type" "shift,*,vecperm")
2655 (set_attr "isa" "p10,*,p9v")])
2656
2657 ;; We are always BITS_BIG_ENDIAN, so the bit positions below in
2658 ;; zero_extract insns do not change for -mlittle.
2659 (define_insn_and_split "bswapsi2_reg"
2660 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,&r,wa")
2661 (bswap:SI
2662 (match_operand:SI 1 "gpc_reg_operand" "r,r,wa")))]
2663 ""
2664 "@
2665 brw %0,%1
2666 #
2667 xxbrw %x0,%x1"
2668 "reload_completed && !TARGET_POWER10 && int_reg_operand (operands[0], SImode)"
2669 [(set (match_dup 0) ; DABC
2670 (rotate:SI (match_dup 1)
2671 (const_int 24)))
2672 (set (match_dup 0) ; DCBC
2673 (ior:SI (and:SI (ashift:SI (match_dup 1)
2674 (const_int 8))
2675 (const_int 16711680))
2676 (and:SI (match_dup 0)
2677 (const_int -16711681))))
2678 (set (match_dup 0) ; DCBA
2679 (ior:SI (and:SI (lshiftrt:SI (match_dup 1)
2680 (const_int 24))
2681 (const_int 255))
2682 (and:SI (match_dup 0)
2683 (const_int -256))))]
2684 ""
2685 [(set_attr "length" "4,12,4")
2686 (set_attr "type" "shift,*,vecperm")
2687 (set_attr "isa" "p10,*,p9v")])
2688
2689 ;; On systems with LDBRX/STDBRX generate the loads/stores directly, just like
2690 ;; we do for L{H,W}BRX and ST{H,W}BRX above. If not, we have to generate more
2691 ;; complex code.
2692
2693 (define_expand "bswapdi2"
2694 [(parallel [(set (match_operand:DI 0 "reg_or_mem_operand")
2695 (bswap:DI
2696 (match_operand:DI 1 "reg_or_mem_operand")))
2697 (clobber (match_scratch:DI 2))
2698 (clobber (match_scratch:DI 3))])]
2699 ""
2700 {
2701 rtx dest = operands[0];
2702 rtx src = operands[1];
2703
2704 if (!REG_P (dest) && !REG_P (src))
2705 operands[1] = src = force_reg (DImode, src);
2706
2707 if (TARGET_POWERPC64 && TARGET_LDBRX)
2708 {
2709 if (MEM_P (src))
2710 {
2711 src = rs6000_force_indexed_or_indirect_mem (src);
2712 emit_insn (gen_bswapdi2_load (dest, src));
2713 }
2714 else if (MEM_P (dest))
2715 {
2716 dest = rs6000_force_indexed_or_indirect_mem (dest);
2717 emit_insn (gen_bswapdi2_store (dest, src));
2718 }
2719 else if (TARGET_P9_VECTOR)
2720 emit_insn (gen_bswapdi2_brd (dest, src));
2721 else
2722 emit_insn (gen_bswapdi2_reg (dest, src));
2723 DONE;
2724 }
2725
2726 if (!TARGET_POWERPC64)
2727 {
2728 /* 32-bit mode needs fewer scratch registers, but 32-bit addressing mode
2729 that uses 64-bit registers needs the same scratch registers as 64-bit
2730 mode. */
2731 emit_insn (gen_bswapdi2_32bit (dest, src));
2732 DONE;
2733 }
2734 })
2735
2736 ;; Power7/cell has ldbrx/stdbrx, so use it directly
2737 (define_insn "bswapdi2_load"
2738 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2739 (bswap:DI (match_operand:DI 1 "memory_operand" "Z")))]
2740 "TARGET_POWERPC64 && TARGET_LDBRX"
2741 "ldbrx %0,%y1"
2742 [(set_attr "type" "load")])
2743
2744 (define_insn "bswapdi2_store"
2745 [(set (match_operand:DI 0 "memory_operand" "=Z")
2746 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "r")))]
2747 "TARGET_POWERPC64 && TARGET_LDBRX"
2748 "stdbrx %1,%y0"
2749 [(set_attr "type" "store")])
2750
2751 (define_insn "bswapdi2_brd"
2752 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,wa")
2753 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "r,wa")))]
2754 "TARGET_P9_VECTOR"
2755 "@
2756 brd %0,%1
2757 xxbrd %x0,%x1"
2758 [(set_attr "type" "shift,vecperm")
2759 (set_attr "isa" "p10,p9v")])
2760
2761 (define_insn "bswapdi2_reg"
2762 [(set (match_operand:DI 0 "gpc_reg_operand" "=&r")
2763 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "r")))
2764 (clobber (match_scratch:DI 2 "=&r"))
2765 (clobber (match_scratch:DI 3 "=&r"))]
2766 "TARGET_POWERPC64 && TARGET_LDBRX && !TARGET_P9_VECTOR"
2767 "#"
2768 [(set_attr "length" "36")])
2769
2770 ;; Non-power7/cell, fall back to use lwbrx/stwbrx
2771 (define_insn "*bswapdi2_64bit"
2772 [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,&r")
2773 (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2774 (clobber (match_scratch:DI 2 "=&b,&b,&r"))
2775 (clobber (match_scratch:DI 3 "=&r,&r,&r"))]
2776 "TARGET_POWERPC64 && !TARGET_LDBRX
2777 && (REG_P (operands[0]) || REG_P (operands[1]))
2778 && !(MEM_P (operands[0]) && MEM_VOLATILE_P (operands[0]))
2779 && !(MEM_P (operands[1]) && MEM_VOLATILE_P (operands[1]))"
2780 "#"
2781 [(set_attr "length" "16,12,36")])
2782
2783 (define_split
2784 [(set (match_operand:DI 0 "gpc_reg_operand")
2785 (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand")))
2786 (clobber (match_operand:DI 2 "gpc_reg_operand"))
2787 (clobber (match_operand:DI 3 "gpc_reg_operand"))]
2788 "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2789 [(const_int 0)]
2790 {
2791 rtx dest = operands[0];
2792 rtx src = operands[1];
2793 rtx op2 = operands[2];
2794 rtx op3 = operands[3];
2795 rtx op3_32 = simplify_gen_subreg (SImode, op3, DImode,
2796 BYTES_BIG_ENDIAN ? 4 : 0);
2797 rtx dest_32 = simplify_gen_subreg (SImode, dest, DImode,
2798 BYTES_BIG_ENDIAN ? 4 : 0);
2799 rtx addr1;
2800 rtx addr2;
2801 rtx word1;
2802 rtx word2;
2803
2804 addr1 = XEXP (src, 0);
2805 if (GET_CODE (addr1) == PLUS)
2806 {
2807 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2808 if (TARGET_AVOID_XFORM)
2809 {
2810 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2811 addr2 = op2;
2812 }
2813 else
2814 addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2815 }
2816 else if (TARGET_AVOID_XFORM)
2817 {
2818 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2819 addr2 = op2;
2820 }
2821 else
2822 {
2823 emit_move_insn (op2, GEN_INT (4));
2824 addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2825 }
2826
2827 word1 = change_address (src, SImode, addr1);
2828 word2 = change_address (src, SImode, addr2);
2829
2830 if (BYTES_BIG_ENDIAN)
2831 {
2832 emit_insn (gen_bswapsi2 (op3_32, word2));
2833 emit_insn (gen_bswapsi2 (dest_32, word1));
2834 }
2835 else
2836 {
2837 emit_insn (gen_bswapsi2 (op3_32, word1));
2838 emit_insn (gen_bswapsi2 (dest_32, word2));
2839 }
2840
2841 emit_insn (gen_rotldi3_insert_3 (dest, op3, GEN_INT (32), dest,
2842 GEN_INT (0xffffffff)));
2843 DONE;
2844 })
2845
2846 (define_split
2847 [(set (match_operand:DI 0 "indexed_or_indirect_operand")
2848 (bswap:DI (match_operand:DI 1 "gpc_reg_operand")))
2849 (clobber (match_operand:DI 2 "gpc_reg_operand"))
2850 (clobber (match_operand:DI 3 "gpc_reg_operand"))]
2851 "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2852 [(const_int 0)]
2853 {
2854 rtx dest = operands[0];
2855 rtx src = operands[1];
2856 rtx op2 = operands[2];
2857 rtx op3 = operands[3];
2858 rtx src_si = simplify_gen_subreg (SImode, src, DImode,
2859 BYTES_BIG_ENDIAN ? 4 : 0);
2860 rtx op3_si = simplify_gen_subreg (SImode, op3, DImode,
2861 BYTES_BIG_ENDIAN ? 4 : 0);
2862 rtx addr1;
2863 rtx addr2;
2864 rtx word1;
2865 rtx word2;
2866
2867 addr1 = XEXP (dest, 0);
2868 if (GET_CODE (addr1) == PLUS)
2869 {
2870 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2871 if (TARGET_AVOID_XFORM)
2872 {
2873 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2874 addr2 = op2;
2875 }
2876 else
2877 addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2878 }
2879 else if (TARGET_AVOID_XFORM)
2880 {
2881 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2882 addr2 = op2;
2883 }
2884 else
2885 {
2886 emit_move_insn (op2, GEN_INT (4));
2887 addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2888 }
2889
2890 word1 = change_address (dest, SImode, addr1);
2891 word2 = change_address (dest, SImode, addr2);
2892
2893 emit_insn (gen_lshrdi3 (op3, src, GEN_INT (32)));
2894
2895 if (BYTES_BIG_ENDIAN)
2896 {
2897 emit_insn (gen_bswapsi2 (word1, src_si));
2898 emit_insn (gen_bswapsi2 (word2, op3_si));
2899 }
2900 else
2901 {
2902 emit_insn (gen_bswapsi2 (word2, src_si));
2903 emit_insn (gen_bswapsi2 (word1, op3_si));
2904 }
2905 DONE;
2906 })
2907
2908 (define_split
2909 [(set (match_operand:DI 0 "gpc_reg_operand")
2910 (bswap:DI (match_operand:DI 1 "gpc_reg_operand")))
2911 (clobber (match_operand:DI 2 "gpc_reg_operand"))
2912 (clobber (match_operand:DI 3 "gpc_reg_operand"))]
2913 "TARGET_POWERPC64 && !TARGET_P9_VECTOR && reload_completed"
2914 [(const_int 0)]
2915 {
2916 rtx dest = operands[0];
2917 rtx src = operands[1];
2918 rtx op2 = operands[2];
2919 rtx op3 = operands[3];
2920 int lo_off = BYTES_BIG_ENDIAN ? 4 : 0;
2921 rtx dest_si = simplify_gen_subreg (SImode, dest, DImode, lo_off);
2922 rtx src_si = simplify_gen_subreg (SImode, src, DImode, lo_off);
2923 rtx op2_si = simplify_gen_subreg (SImode, op2, DImode, lo_off);
2924 rtx op3_si = simplify_gen_subreg (SImode, op3, DImode, lo_off);
2925
2926 emit_insn (gen_lshrdi3 (op2, src, GEN_INT (32)));
2927 emit_insn (gen_bswapsi2 (op3_si, src_si));
2928 emit_insn (gen_bswapsi2 (dest_si, op2_si));
2929 emit_insn (gen_rotldi3_insert_3 (dest, op3, GEN_INT (32), dest,
2930 GEN_INT (0xffffffff)));
2931 DONE;
2932 })
2933
2934 (define_insn "bswapdi2_32bit"
2935 [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,?&r")
2936 (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2937 (clobber (match_scratch:SI 2 "=&b,&b,X"))]
2938 "!TARGET_POWERPC64 && (REG_P (operands[0]) || REG_P (operands[1]))"
2939 "#"
2940 [(set_attr "length" "16,12,36")])
2941
2942 (define_split
2943 [(set (match_operand:DI 0 "gpc_reg_operand")
2944 (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand")))
2945 (clobber (match_operand:SI 2 "gpc_reg_operand"))]
2946 "!TARGET_POWERPC64 && reload_completed"
2947 [(const_int 0)]
2948 {
2949 rtx dest = operands[0];
2950 rtx src = operands[1];
2951 rtx op2 = operands[2];
2952 rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
2953 rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
2954 rtx addr1;
2955 rtx addr2;
2956 rtx word1;
2957 rtx word2;
2958
2959 addr1 = XEXP (src, 0);
2960 if (GET_CODE (addr1) == PLUS)
2961 {
2962 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2963 if (TARGET_AVOID_XFORM
2964 || REGNO (XEXP (addr1, 1)) == REGNO (dest2))
2965 {
2966 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2967 addr2 = op2;
2968 }
2969 else
2970 addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
2971 }
2972 else if (TARGET_AVOID_XFORM
2973 || REGNO (addr1) == REGNO (dest2))
2974 {
2975 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2976 addr2 = op2;
2977 }
2978 else
2979 {
2980 emit_move_insn (op2, GEN_INT (4));
2981 addr2 = gen_rtx_PLUS (SImode, op2, addr1);
2982 }
2983
2984 word1 = change_address (src, SImode, addr1);
2985 word2 = change_address (src, SImode, addr2);
2986
2987 emit_insn (gen_bswapsi2 (dest2, word1));
2988 /* The REGNO (dest2) tests above ensure that addr2 has not been trashed,
2989 thus allowing us to omit an early clobber on the output. */
2990 emit_insn (gen_bswapsi2 (dest1, word2));
2991 DONE;
2992 })
2993
2994 (define_split
2995 [(set (match_operand:DI 0 "indexed_or_indirect_operand")
2996 (bswap:DI (match_operand:DI 1 "gpc_reg_operand")))
2997 (clobber (match_operand:SI 2 "gpc_reg_operand"))]
2998 "!TARGET_POWERPC64 && reload_completed"
2999 [(const_int 0)]
3000 {
3001 rtx dest = operands[0];
3002 rtx src = operands[1];
3003 rtx op2 = operands[2];
3004 rtx src1 = simplify_gen_subreg (SImode, src, DImode, 0);
3005 rtx src2 = simplify_gen_subreg (SImode, src, DImode, 4);
3006 rtx addr1;
3007 rtx addr2;
3008 rtx word1;
3009 rtx word2;
3010
3011 addr1 = XEXP (dest, 0);
3012 if (GET_CODE (addr1) == PLUS)
3013 {
3014 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
3015 if (TARGET_AVOID_XFORM)
3016 {
3017 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
3018 addr2 = op2;
3019 }
3020 else
3021 addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
3022 }
3023 else if (TARGET_AVOID_XFORM)
3024 {
3025 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
3026 addr2 = op2;
3027 }
3028 else
3029 {
3030 emit_move_insn (op2, GEN_INT (4));
3031 addr2 = gen_rtx_PLUS (SImode, op2, addr1);
3032 }
3033
3034 word1 = change_address (dest, SImode, addr1);
3035 word2 = change_address (dest, SImode, addr2);
3036
3037 emit_insn (gen_bswapsi2 (word2, src1));
3038 emit_insn (gen_bswapsi2 (word1, src2));
3039 DONE;
3040 })
3041
3042 (define_split
3043 [(set (match_operand:DI 0 "gpc_reg_operand")
3044 (bswap:DI (match_operand:DI 1 "gpc_reg_operand")))
3045 (clobber (match_operand:SI 2 ""))]
3046 "!TARGET_POWERPC64 && reload_completed"
3047 [(const_int 0)]
3048 {
3049 rtx dest = operands[0];
3050 rtx src = operands[1];
3051 rtx src1 = simplify_gen_subreg (SImode, src, DImode, 0);
3052 rtx src2 = simplify_gen_subreg (SImode, src, DImode, 4);
3053 rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
3054 rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
3055
3056 emit_insn (gen_bswapsi2 (dest1, src2));
3057 emit_insn (gen_bswapsi2 (dest2, src1));
3058 DONE;
3059 })
3060
3061
3062 (define_insn "mul<mode>3"
3063 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3064 (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3065 (match_operand:GPR 2 "reg_or_short_operand" "r,I")))]
3066 ""
3067 "@
3068 mull<wd> %0,%1,%2
3069 mulli %0,%1,%2"
3070 [(set_attr "type" "mul")
3071 (set (attr "size")
3072 (cond [(match_operand:GPR 2 "s8bit_cint_operand")
3073 (const_string "8")
3074 (match_operand:GPR 2 "short_cint_operand")
3075 (const_string "16")]
3076 (const_string "<bits>")))])
3077
3078 (define_insn_and_split "*mul<mode>3_dot"
3079 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3080 (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3081 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3082 (const_int 0)))
3083 (clobber (match_scratch:GPR 0 "=r,r"))]
3084 "<MODE>mode == Pmode"
3085 "@
3086 mull<wd>. %0,%1,%2
3087 #"
3088 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3089 [(set (match_dup 0)
3090 (mult:GPR (match_dup 1)
3091 (match_dup 2)))
3092 (set (match_dup 3)
3093 (compare:CC (match_dup 0)
3094 (const_int 0)))]
3095 ""
3096 [(set_attr "type" "mul")
3097 (set_attr "size" "<bits>")
3098 (set_attr "dot" "yes")
3099 (set_attr "length" "4,8")])
3100
3101 (define_insn_and_split "*mul<mode>3_dot2"
3102 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3103 (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3104 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3105 (const_int 0)))
3106 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3107 (mult:GPR (match_dup 1)
3108 (match_dup 2)))]
3109 "<MODE>mode == Pmode"
3110 "@
3111 mull<wd>. %0,%1,%2
3112 #"
3113 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3114 [(set (match_dup 0)
3115 (mult:GPR (match_dup 1)
3116 (match_dup 2)))
3117 (set (match_dup 3)
3118 (compare:CC (match_dup 0)
3119 (const_int 0)))]
3120 ""
3121 [(set_attr "type" "mul")
3122 (set_attr "size" "<bits>")
3123 (set_attr "dot" "yes")
3124 (set_attr "length" "4,8")])
3125
3126
3127 (define_expand "<su>mul<mode>3_highpart"
3128 [(set (match_operand:GPR 0 "gpc_reg_operand")
3129 (subreg:GPR
3130 (mult:<DMODE> (any_extend:<DMODE>
3131 (match_operand:GPR 1 "gpc_reg_operand"))
3132 (any_extend:<DMODE>
3133 (match_operand:GPR 2 "gpc_reg_operand")))
3134 0))]
3135 ""
3136 {
3137 if (<MODE>mode == SImode && TARGET_POWERPC64)
3138 {
3139 emit_insn (gen_<su>mulsi3_highpart_64 (operands[0], operands[1],
3140 operands[2]));
3141 DONE;
3142 }
3143
3144 if (!WORDS_BIG_ENDIAN)
3145 {
3146 emit_insn (gen_<su>mul<mode>3_highpart_le (operands[0], operands[1],
3147 operands[2]));
3148 DONE;
3149 }
3150 })
3151
3152 (define_insn "*<su>mul<mode>3_highpart"
3153 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3154 (subreg:GPR
3155 (mult:<DMODE> (any_extend:<DMODE>
3156 (match_operand:GPR 1 "gpc_reg_operand" "r"))
3157 (any_extend:<DMODE>
3158 (match_operand:GPR 2 "gpc_reg_operand" "r")))
3159 0))]
3160 "WORDS_BIG_ENDIAN && !(<MODE>mode == SImode && TARGET_POWERPC64)"
3161 "mulh<wd><u> %0,%1,%2"
3162 [(set_attr "type" "mul")
3163 (set_attr "size" "<bits>")])
3164
3165 (define_insn "<su>mulsi3_highpart_le"
3166 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
3167 (subreg:SI
3168 (mult:DI (any_extend:DI
3169 (match_operand:SI 1 "gpc_reg_operand" "r"))
3170 (any_extend:DI
3171 (match_operand:SI 2 "gpc_reg_operand" "r")))
3172 4))]
3173 "!WORDS_BIG_ENDIAN && !TARGET_POWERPC64"
3174 "mulhw<u> %0,%1,%2"
3175 [(set_attr "type" "mul")])
3176
3177 (define_insn "<su>muldi3_highpart_le"
3178 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3179 (subreg:DI
3180 (mult:TI (any_extend:TI
3181 (match_operand:DI 1 "gpc_reg_operand" "r"))
3182 (any_extend:TI
3183 (match_operand:DI 2 "gpc_reg_operand" "r")))
3184 8))]
3185 "!WORDS_BIG_ENDIAN && TARGET_POWERPC64"
3186 "mulhd<u> %0,%1,%2"
3187 [(set_attr "type" "mul")
3188 (set_attr "size" "64")])
3189
3190 (define_insn "<su>mulsi3_highpart_64"
3191 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
3192 (truncate:SI
3193 (lshiftrt:DI
3194 (mult:DI (any_extend:DI
3195 (match_operand:SI 1 "gpc_reg_operand" "r"))
3196 (any_extend:DI
3197 (match_operand:SI 2 "gpc_reg_operand" "r")))
3198 (const_int 32))))]
3199 "TARGET_POWERPC64"
3200 "mulhw<u> %0,%1,%2"
3201 [(set_attr "type" "mul")])
3202
3203 (define_expand "<u>mul<mode><dmode>3"
3204 [(set (match_operand:<DMODE> 0 "gpc_reg_operand")
3205 (mult:<DMODE> (any_extend:<DMODE>
3206 (match_operand:GPR 1 "gpc_reg_operand"))
3207 (any_extend:<DMODE>
3208 (match_operand:GPR 2 "gpc_reg_operand"))))]
3209 "!(<MODE>mode == SImode && TARGET_POWERPC64)"
3210 {
3211 rtx l = gen_reg_rtx (<MODE>mode);
3212 rtx h = gen_reg_rtx (<MODE>mode);
3213 emit_insn (gen_mul<mode>3 (l, operands[1], operands[2]));
3214 emit_insn (gen_<su>mul<mode>3_highpart (h, operands[1], operands[2]));
3215 emit_move_insn (gen_lowpart (<MODE>mode, operands[0]), l);
3216 emit_move_insn (gen_highpart (<MODE>mode, operands[0]), h);
3217 DONE;
3218 })
3219
3220 (define_insn "maddld<mode>4"
3221 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3222 (plus:GPR (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3223 (match_operand:GPR 2 "gpc_reg_operand" "r"))
3224 (match_operand:GPR 3 "gpc_reg_operand" "r")))]
3225 "TARGET_MADDLD"
3226 "maddld %0,%1,%2,%3"
3227 [(set_attr "type" "mul")])
3228
3229 (define_expand "<u>maddditi4"
3230 [(set (match_operand:TI 0 "gpc_reg_operand")
3231 (plus:TI
3232 (mult:TI (any_extend:TI (match_operand:DI 1 "gpc_reg_operand"))
3233 (any_extend:TI (match_operand:DI 2 "gpc_reg_operand")))
3234 (any_extend:TI (match_operand:DI 3 "gpc_reg_operand"))))]
3235 "TARGET_MADDLD && TARGET_POWERPC64"
3236 {
3237 rtx op0_lo = gen_rtx_SUBREG (DImode, operands[0], BYTES_BIG_ENDIAN ? 8 : 0);
3238 rtx op0_hi = gen_rtx_SUBREG (DImode, operands[0], BYTES_BIG_ENDIAN ? 0 : 8);
3239
3240 emit_insn (gen_maddlddi4 (op0_lo, operands[1], operands[2], operands[3]));
3241
3242 if (BYTES_BIG_ENDIAN)
3243 emit_insn (gen_<u>madddi4_highpart (op0_hi, operands[1], operands[2],
3244 operands[3]));
3245 else
3246 emit_insn (gen_<u>madddi4_highpart_le (op0_hi, operands[1], operands[2],
3247 operands[3]));
3248 DONE;
3249 })
3250
3251 (define_insn "<u>madddi4_highpart"
3252 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3253 (subreg:DI
3254 (plus:TI
3255 (mult:TI (any_extend:TI (match_operand:DI 1 "gpc_reg_operand" "r"))
3256 (any_extend:TI (match_operand:DI 2 "gpc_reg_operand" "r")))
3257 (any_extend:TI (match_operand:DI 3 "gpc_reg_operand" "r")))
3258 0))]
3259 "TARGET_MADDLD && BYTES_BIG_ENDIAN && TARGET_POWERPC64"
3260 "maddhd<u> %0,%1,%2,%3"
3261 [(set_attr "type" "mul")])
3262
3263 (define_insn "<u>madddi4_highpart_le"
3264 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3265 (subreg:DI
3266 (plus:TI
3267 (mult:TI (any_extend:TI (match_operand:DI 1 "gpc_reg_operand" "r"))
3268 (any_extend:TI (match_operand:DI 2 "gpc_reg_operand" "r")))
3269 (any_extend:TI (match_operand:DI 3 "gpc_reg_operand" "r")))
3270 8))]
3271 "TARGET_MADDLD && !BYTES_BIG_ENDIAN && TARGET_POWERPC64"
3272 "maddhd<u> %0,%1,%2,%3"
3273 [(set_attr "type" "mul")])
3274
3275 (define_insn "udiv<mode>3"
3276 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3277 (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3278 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3279 ""
3280 "div<wd>u %0,%1,%2"
3281 [(set_attr "type" "div")
3282 (set_attr "size" "<bits>")])
3283
3284 (define_insn "udivti3"
3285 [(set (match_operand:TI 0 "altivec_register_operand" "=v")
3286 (udiv:TI (match_operand:TI 1 "altivec_register_operand" "v")
3287 (match_operand:TI 2 "altivec_register_operand" "v")))]
3288 "TARGET_POWER10 && TARGET_POWERPC64"
3289 "vdivuq %0,%1,%2"
3290 [(set_attr "type" "vecdiv")
3291 (set_attr "size" "128")])
3292
3293 ;; For powers of two we can do sra[wd]i/addze for divide and then adjust for
3294 ;; modulus. If it isn't a power of two, force operands into register and do
3295 ;; a normal divide.
3296 (define_expand "div<mode>3"
3297 [(set (match_operand:GPR 0 "gpc_reg_operand")
3298 (div:GPR (match_operand:GPR 1 "gpc_reg_operand")
3299 (match_operand:GPR 2 "reg_or_cint_operand")))]
3300 ""
3301 {
3302 if (CONST_INT_P (operands[2])
3303 && INTVAL (operands[2]) > 0
3304 && exact_log2 (INTVAL (operands[2])) >= 0)
3305 {
3306 emit_insn (gen_div<mode>3_sra (operands[0], operands[1], operands[2]));
3307 DONE;
3308 }
3309
3310 operands[2] = force_reg (<MODE>mode, operands[2]);
3311 })
3312
3313 (define_insn "*div<mode>3"
3314 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3315 (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3316 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3317 ""
3318 "div<wd> %0,%1,%2"
3319 [(set_attr "type" "div")
3320 (set_attr "size" "<bits>")])
3321
3322 (define_insn "div<mode>3_sra"
3323 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3324 (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3325 (match_operand:GPR 2 "exact_log2_cint_operand" "N")))
3326 (clobber (reg:GPR CA_REGNO))]
3327 ""
3328 "sra<wd>i %0,%1,%p2\;addze %0,%0"
3329 [(set_attr "type" "two")
3330 (set_attr "length" "8")])
3331
3332 (define_insn_and_split "*div<mode>3_sra_dot"
3333 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3334 (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3335 (match_operand:GPR 2 "exact_log2_cint_operand" "N,N"))
3336 (const_int 0)))
3337 (clobber (match_scratch:GPR 0 "=r,r"))
3338 (clobber (reg:GPR CA_REGNO))]
3339 "<MODE>mode == Pmode"
3340 "@
3341 sra<wd>i %0,%1,%p2\;addze. %0,%0
3342 #"
3343 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3344 [(parallel [(set (match_dup 0)
3345 (div:GPR (match_dup 1)
3346 (match_dup 2)))
3347 (clobber (reg:GPR CA_REGNO))])
3348 (set (match_dup 3)
3349 (compare:CC (match_dup 0)
3350 (const_int 0)))]
3351 ""
3352 [(set_attr "type" "two")
3353 (set_attr "length" "8,12")
3354 (set_attr "cell_micro" "not")])
3355
3356 (define_insn_and_split "*div<mode>3_sra_dot2"
3357 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3358 (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3359 (match_operand:GPR 2 "exact_log2_cint_operand" "N,N"))
3360 (const_int 0)))
3361 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3362 (div:GPR (match_dup 1)
3363 (match_dup 2)))
3364 (clobber (reg:GPR CA_REGNO))]
3365 "<MODE>mode == Pmode"
3366 "@
3367 sra<wd>i %0,%1,%p2\;addze. %0,%0
3368 #"
3369 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3370 [(parallel [(set (match_dup 0)
3371 (div:GPR (match_dup 1)
3372 (match_dup 2)))
3373 (clobber (reg:GPR CA_REGNO))])
3374 (set (match_dup 3)
3375 (compare:CC (match_dup 0)
3376 (const_int 0)))]
3377 ""
3378 [(set_attr "type" "two")
3379 (set_attr "length" "8,12")
3380 (set_attr "cell_micro" "not")])
3381
3382 (define_insn "divti3"
3383 [(set (match_operand:TI 0 "altivec_register_operand" "=v")
3384 (div:TI (match_operand:TI 1 "altivec_register_operand" "v")
3385 (match_operand:TI 2 "altivec_register_operand" "v")))]
3386 "TARGET_POWER10 && TARGET_POWERPC64"
3387 "vdivsq %0,%1,%2"
3388 [(set_attr "type" "vecdiv")
3389 (set_attr "size" "128")])
3390
3391 (define_expand "mod<mode>3"
3392 [(set (match_operand:GPR 0 "gpc_reg_operand")
3393 (mod:GPR (match_operand:GPR 1 "gpc_reg_operand")
3394 (match_operand:GPR 2 "reg_or_cint_operand")))]
3395 ""
3396 {
3397 int i;
3398 rtx temp1;
3399 rtx temp2;
3400
3401 if (!CONST_INT_P (operands[2])
3402 || INTVAL (operands[2]) <= 0
3403 || (i = exact_log2 (INTVAL (operands[2]))) < 0)
3404 {
3405 if (!TARGET_MODULO)
3406 FAIL;
3407
3408 operands[2] = force_reg (<MODE>mode, operands[2]);
3409 }
3410 else
3411 {
3412 temp1 = gen_reg_rtx (<MODE>mode);
3413 temp2 = gen_reg_rtx (<MODE>mode);
3414
3415 emit_insn (gen_div<mode>3 (temp1, operands[1], operands[2]));
3416 emit_insn (gen_ashl<mode>3 (temp2, temp1, GEN_INT (i)));
3417 emit_insn (gen_sub<mode>3 (operands[0], operands[1], temp2));
3418 DONE;
3419 }
3420 })
3421
3422 ;; In order to enable using a peephole2 for combining div/mod to eliminate the
3423 ;; mod, prefer putting the result of mod into a different register
3424 (define_insn "*mod<mode>3"
3425 [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
3426 (mod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3427 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3428 "TARGET_MODULO"
3429 "mods<wd> %0,%1,%2"
3430 [(set_attr "type" "div")
3431 (set_attr "size" "<bits>")])
3432
3433
3434 (define_insn "umod<mode>3"
3435 [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
3436 (umod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3437 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3438 "TARGET_MODULO"
3439 "modu<wd> %0,%1,%2"
3440 [(set_attr "type" "div")
3441 (set_attr "size" "<bits>")])
3442
3443 ;; On machines with modulo support, do a combined div/mod the old fashioned
3444 ;; method, since the multiply/subtract is faster than doing the mod instruction
3445 ;; after a divide.
3446
3447 (define_peephole2
3448 [(set (match_operand:GPR 0 "gpc_reg_operand")
3449 (div:GPR (match_operand:GPR 1 "gpc_reg_operand")
3450 (match_operand:GPR 2 "gpc_reg_operand")))
3451 (set (match_operand:GPR 3 "gpc_reg_operand")
3452 (mod:GPR (match_dup 1)
3453 (match_dup 2)))]
3454 "TARGET_MODULO
3455 && ! reg_mentioned_p (operands[0], operands[1])
3456 && ! reg_mentioned_p (operands[0], operands[2])
3457 && ! reg_mentioned_p (operands[3], operands[1])
3458 && ! reg_mentioned_p (operands[3], operands[2])"
3459 [(set (match_dup 0)
3460 (div:GPR (match_dup 1)
3461 (match_dup 2)))
3462 (set (match_dup 3)
3463 (mult:GPR (match_dup 0)
3464 (match_dup 2)))
3465 (set (match_dup 3)
3466 (minus:GPR (match_dup 1)
3467 (match_dup 3)))])
3468
3469 (define_peephole2
3470 [(set (match_operand:GPR 0 "gpc_reg_operand")
3471 (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand")
3472 (match_operand:GPR 2 "gpc_reg_operand")))
3473 (set (match_operand:GPR 3 "gpc_reg_operand")
3474 (umod:GPR (match_dup 1)
3475 (match_dup 2)))]
3476 "TARGET_MODULO
3477 && ! reg_mentioned_p (operands[0], operands[1])
3478 && ! reg_mentioned_p (operands[0], operands[2])
3479 && ! reg_mentioned_p (operands[3], operands[1])
3480 && ! reg_mentioned_p (operands[3], operands[2])"
3481 [(set (match_dup 0)
3482 (udiv:GPR (match_dup 1)
3483 (match_dup 2)))
3484 (set (match_dup 3)
3485 (mult:GPR (match_dup 0)
3486 (match_dup 2)))
3487 (set (match_dup 3)
3488 (minus:GPR (match_dup 1)
3489 (match_dup 3)))])
3490
3491 (define_insn "umodti3"
3492 [(set (match_operand:TI 0 "altivec_register_operand" "=v")
3493 (umod:TI (match_operand:TI 1 "altivec_register_operand" "v")
3494 (match_operand:TI 2 "altivec_register_operand" "v")))]
3495 "TARGET_POWER10 && TARGET_POWERPC64"
3496 "vmoduq %0,%1,%2"
3497 [(set_attr "type" "vecdiv")
3498 (set_attr "size" "128")])
3499
3500 (define_insn "modti3"
3501 [(set (match_operand:TI 0 "altivec_register_operand" "=v")
3502 (mod:TI (match_operand:TI 1 "altivec_register_operand" "v")
3503 (match_operand:TI 2 "altivec_register_operand" "v")))]
3504 "TARGET_POWER10 && TARGET_POWERPC64"
3505 "vmodsq %0,%1,%2"
3506 [(set_attr "type" "vecdiv")
3507 (set_attr "size" "128")])
3508 \f
3509 ;; Logical instructions
3510 ;; The logical instructions are mostly combined by using match_operator,
3511 ;; but the plain AND insns are somewhat different because there is no
3512 ;; plain 'andi' (only 'andi.'), no plain 'andis', and there are all
3513 ;; those rotate-and-mask operations. Thus, the AND insns come first.
3514
3515 (define_expand "and<mode>3"
3516 [(set (match_operand:SDI 0 "gpc_reg_operand")
3517 (and:SDI (match_operand:SDI 1 "gpc_reg_operand")
3518 (match_operand:SDI 2 "reg_or_cint_operand")))]
3519 ""
3520 {
3521 if (<MODE>mode == DImode && !TARGET_POWERPC64)
3522 {
3523 rs6000_split_logical (operands, AND, false, false, false);
3524 DONE;
3525 }
3526
3527 if (CONST_INT_P (operands[2]))
3528 {
3529 if (rs6000_is_valid_and_mask (operands[2], <MODE>mode))
3530 {
3531 emit_insn (gen_and<mode>3_mask (operands[0], operands[1], operands[2]));
3532 DONE;
3533 }
3534
3535 if (logical_const_operand (operands[2], <MODE>mode))
3536 {
3537 emit_insn (gen_and<mode>3_imm (operands[0], operands[1], operands[2]));
3538 DONE;
3539 }
3540
3541 if (rs6000_is_valid_2insn_and (operands[2], <MODE>mode))
3542 {
3543 rs6000_emit_2insn_and (<MODE>mode, operands, true, 0);
3544 DONE;
3545 }
3546
3547 operands[2] = force_reg (<MODE>mode, operands[2]);
3548 }
3549 })
3550
3551
3552 (define_insn "and<mode>3_imm"
3553 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3554 (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3555 (match_operand:GPR 2 "logical_const_operand" "n")))
3556 (clobber (match_scratch:CC 3 "=x"))]
3557 "!rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3558 "andi%e2. %0,%1,%u2"
3559 [(set_attr "type" "logical")
3560 (set_attr "dot" "yes")])
3561
3562 (define_insn_and_split "*and<mode>3_imm_dot"
3563 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3564 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3565 (match_operand:GPR 2 "logical_const_operand" "n,n"))
3566 (const_int 0)))
3567 (clobber (match_scratch:GPR 0 "=r,r"))
3568 (clobber (match_scratch:CC 4 "=X,x"))]
3569 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3570 && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3571 "@
3572 andi%e2. %0,%1,%u2
3573 #"
3574 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3575 [(parallel [(set (match_dup 0)
3576 (and:GPR (match_dup 1)
3577 (match_dup 2)))
3578 (clobber (match_dup 4))])
3579 (set (match_dup 3)
3580 (compare:CC (match_dup 0)
3581 (const_int 0)))]
3582 ""
3583 [(set_attr "type" "logical")
3584 (set_attr "dot" "yes")
3585 (set_attr "length" "4,8")])
3586
3587 (define_insn_and_split "*and<mode>3_imm_dot2"
3588 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3589 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3590 (match_operand:GPR 2 "logical_const_operand" "n,n"))
3591 (const_int 0)))
3592 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3593 (and:GPR (match_dup 1)
3594 (match_dup 2)))
3595 (clobber (match_scratch:CC 4 "=X,x"))]
3596 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3597 && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3598 "@
3599 andi%e2. %0,%1,%u2
3600 #"
3601 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3602 [(parallel [(set (match_dup 0)
3603 (and:GPR (match_dup 1)
3604 (match_dup 2)))
3605 (clobber (match_dup 4))])
3606 (set (match_dup 3)
3607 (compare:CC (match_dup 0)
3608 (const_int 0)))]
3609 ""
3610 [(set_attr "type" "logical")
3611 (set_attr "dot" "yes")
3612 (set_attr "length" "4,8")])
3613
3614 (define_insn_and_split "*and<mode>3_imm_mask_dot"
3615 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3616 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3617 (match_operand:GPR 2 "logical_const_operand" "n,n"))
3618 (const_int 0)))
3619 (clobber (match_scratch:GPR 0 "=r,r"))]
3620 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3621 && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3622 "@
3623 andi%e2. %0,%1,%u2
3624 #"
3625 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3626 [(set (match_dup 0)
3627 (and:GPR (match_dup 1)
3628 (match_dup 2)))
3629 (set (match_dup 3)
3630 (compare:CC (match_dup 0)
3631 (const_int 0)))]
3632 ""
3633 [(set_attr "type" "logical")
3634 (set_attr "dot" "yes")
3635 (set_attr "length" "4,8")])
3636
3637 (define_insn_and_split "*and<mode>3_imm_mask_dot2"
3638 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3639 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3640 (match_operand:GPR 2 "logical_const_operand" "n,n"))
3641 (const_int 0)))
3642 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3643 (and:GPR (match_dup 1)
3644 (match_dup 2)))]
3645 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3646 && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3647 "@
3648 andi%e2. %0,%1,%u2
3649 #"
3650 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3651 [(set (match_dup 0)
3652 (and:GPR (match_dup 1)
3653 (match_dup 2)))
3654 (set (match_dup 3)
3655 (compare:CC (match_dup 0)
3656 (const_int 0)))]
3657 ""
3658 [(set_attr "type" "logical")
3659 (set_attr "dot" "yes")
3660 (set_attr "length" "4,8")])
3661
3662 (define_insn "*and<mode>3_imm_dot_shifted"
3663 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
3664 (compare:CC
3665 (and:GPR
3666 (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3667 (match_operand:SI 4 "const_int_operand" "n"))
3668 (match_operand:GPR 2 "const_int_operand" "n"))
3669 (const_int 0)))
3670 (clobber (match_scratch:GPR 0 "=r"))]
3671 "logical_const_operand (GEN_INT (UINTVAL (operands[2])
3672 << INTVAL (operands[4])),
3673 DImode)
3674 && (<MODE>mode == Pmode
3675 || (UINTVAL (operands[2]) << INTVAL (operands[4])) <= 0x7fffffff)"
3676 {
3677 operands[2] = GEN_INT (UINTVAL (operands[2]) << INTVAL (operands[4]));
3678 return "andi%e2. %0,%1,%u2";
3679 }
3680 [(set_attr "type" "logical")
3681 (set_attr "dot" "yes")])
3682
3683
3684 (define_insn "and<mode>3_mask"
3685 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3686 (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3687 (match_operand:GPR 2 "const_int_operand" "n")))]
3688 "rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3689 {
3690 return rs6000_insn_for_and_mask (<MODE>mode, operands, false);
3691 }
3692 [(set_attr "type" "shift")])
3693
3694 (define_insn_and_split "*and<mode>3_mask_dot"
3695 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3696 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3697 (match_operand:GPR 2 "const_int_operand" "n,n"))
3698 (const_int 0)))
3699 (clobber (match_scratch:GPR 0 "=r,r"))]
3700 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3701 && !logical_const_operand (operands[2], <MODE>mode)
3702 && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3703 {
3704 if (which_alternative == 0)
3705 return rs6000_insn_for_and_mask (<MODE>mode, operands, true);
3706 else
3707 return "#";
3708 }
3709 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3710 [(set (match_dup 0)
3711 (and:GPR (match_dup 1)
3712 (match_dup 2)))
3713 (set (match_dup 3)
3714 (compare:CC (match_dup 0)
3715 (const_int 0)))]
3716 ""
3717 [(set_attr "type" "shift")
3718 (set_attr "dot" "yes")
3719 (set_attr "length" "4,8")])
3720
3721 (define_insn_and_split "*and<mode>3_mask_dot2"
3722 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3723 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3724 (match_operand:GPR 2 "const_int_operand" "n,n"))
3725 (const_int 0)))
3726 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3727 (and:GPR (match_dup 1)
3728 (match_dup 2)))]
3729 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3730 && !logical_const_operand (operands[2], <MODE>mode)
3731 && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3732 {
3733 if (which_alternative == 0)
3734 return rs6000_insn_for_and_mask (<MODE>mode, operands, true);
3735 else
3736 return "#";
3737 }
3738 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3739 [(set (match_dup 0)
3740 (and:GPR (match_dup 1)
3741 (match_dup 2)))
3742 (set (match_dup 3)
3743 (compare:CC (match_dup 0)
3744 (const_int 0)))]
3745 ""
3746 [(set_attr "type" "shift")
3747 (set_attr "dot" "yes")
3748 (set_attr "length" "4,8")])
3749
3750
3751 (define_insn_and_split "*and<mode>3_2insn"
3752 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3753 (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3754 (match_operand:GPR 2 "const_int_operand" "n")))]
3755 "rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3756 && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3757 || logical_const_operand (operands[2], <MODE>mode))"
3758 "#"
3759 "&& 1"
3760 [(pc)]
3761 {
3762 rs6000_emit_2insn_and (<MODE>mode, operands, false, 0);
3763 DONE;
3764 }
3765 [(set_attr "type" "shift")
3766 (set_attr "length" "8")])
3767
3768 (define_insn_and_split "*and<mode>3_2insn_dot"
3769 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3770 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3771 (match_operand:GPR 2 "const_int_operand" "n,n"))
3772 (const_int 0)))
3773 (clobber (match_scratch:GPR 0 "=r,r"))]
3774 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3775 && rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3776 && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3777 || logical_const_operand (operands[2], <MODE>mode))"
3778 "#"
3779 "&& reload_completed"
3780 [(pc)]
3781 {
3782 rs6000_emit_2insn_and (<MODE>mode, operands, false, 1);
3783 DONE;
3784 }
3785 [(set_attr "type" "shift")
3786 (set_attr "dot" "yes")
3787 (set_attr "length" "8,12")])
3788
3789 (define_insn_and_split "*and<mode>3_2insn_dot2"
3790 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3791 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3792 (match_operand:GPR 2 "const_int_operand" "n,n"))
3793 (const_int 0)))
3794 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3795 (and:GPR (match_dup 1)
3796 (match_dup 2)))]
3797 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3798 && rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3799 && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3800 || logical_const_operand (operands[2], <MODE>mode))"
3801 "#"
3802 "&& reload_completed"
3803 [(pc)]
3804 {
3805 rs6000_emit_2insn_and (<MODE>mode, operands, false, 2);
3806 DONE;
3807 }
3808 [(set_attr "type" "shift")
3809 (set_attr "dot" "yes")
3810 (set_attr "length" "8,12")])
3811
3812 (define_insn_and_split "*branch_anddi3_dot"
3813 [(set (pc)
3814 (if_then_else (eq (and:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r")
3815 (match_operand:DI 2 "const_int_operand" "n,n"))
3816 (const_int 0))
3817 (label_ref (match_operand 3 ""))
3818 (pc)))
3819 (clobber (match_scratch:DI 0 "=r,r"))
3820 (clobber (reg:CC CR0_REGNO))]
3821 "rs6000_is_valid_rotate_dot_mask (operands[2], DImode)
3822 && TARGET_POWERPC64"
3823 "#"
3824 "&& reload_completed"
3825 [(pc)]
3826 {
3827 int nb, ne;
3828 if (rs6000_is_valid_mask (operands[2], &nb, &ne, DImode)
3829 && nb >= ne
3830 && ne > 0)
3831 {
3832 unsigned HOST_WIDE_INT val = INTVAL (operands[2]);
3833 int shift = 63 - nb;
3834 rtx tmp = gen_rtx_ASHIFT (DImode, operands[1], GEN_INT (shift));
3835 tmp = gen_rtx_AND (DImode, tmp, GEN_INT (val << shift));
3836 rtx cr0 = gen_rtx_REG (CCmode, CR0_REGNO);
3837 rs6000_emit_dot_insn (operands[0], tmp, 1, cr0);
3838 rtx loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands[3]);
3839 rtx cond = gen_rtx_EQ (CCEQmode, cr0, const0_rtx);
3840 rtx ite = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, loc_ref, pc_rtx);
3841 emit_jump_insn (gen_rtx_SET (pc_rtx, ite));
3842 DONE;
3843 }
3844 else
3845 FAIL;
3846 }
3847 [(set_attr "type" "shift")
3848 (set_attr "dot" "yes")
3849 (set_attr "length" "8,12")])
3850
3851 (define_expand "<code><mode>3"
3852 [(set (match_operand:SDI 0 "gpc_reg_operand")
3853 (iorxor:SDI (match_operand:SDI 1 "gpc_reg_operand")
3854 (match_operand:SDI 2 "reg_or_cint_operand")))]
3855 ""
3856 {
3857 if (<MODE>mode == DImode && !TARGET_POWERPC64)
3858 {
3859 rs6000_split_logical (operands, <CODE>, false, false, false);
3860 DONE;
3861 }
3862
3863 if (non_logical_cint_operand (operands[2], <MODE>mode))
3864 {
3865 rtx tmp = ((!can_create_pseudo_p ()
3866 || rtx_equal_p (operands[0], operands[1]))
3867 ? operands[0] : gen_reg_rtx (<MODE>mode));
3868
3869 HOST_WIDE_INT value = INTVAL (operands[2]);
3870 HOST_WIDE_INT lo = value & 0xffff;
3871 HOST_WIDE_INT hi = value - lo;
3872
3873 emit_insn (gen_<code><mode>3 (tmp, operands[1], GEN_INT (hi)));
3874 emit_insn (gen_<code><mode>3 (operands[0], tmp, GEN_INT (lo)));
3875 DONE;
3876 }
3877
3878 if (!reg_or_logical_cint_operand (operands[2], <MODE>mode))
3879 operands[2] = force_reg (<MODE>mode, operands[2]);
3880 })
3881
3882 (define_split
3883 [(set (match_operand:GPR 0 "gpc_reg_operand")
3884 (iorxor:GPR (match_operand:GPR 1 "gpc_reg_operand")
3885 (match_operand:GPR 2 "non_logical_cint_operand")))]
3886 ""
3887 [(set (match_dup 3)
3888 (iorxor:GPR (match_dup 1)
3889 (match_dup 4)))
3890 (set (match_dup 0)
3891 (iorxor:GPR (match_dup 3)
3892 (match_dup 5)))]
3893 {
3894 operands[3] = ((!can_create_pseudo_p ()
3895 || rtx_equal_p (operands[0], operands[1]))
3896 ? operands[0] : gen_reg_rtx (<MODE>mode));
3897
3898 HOST_WIDE_INT value = INTVAL (operands[2]);
3899 HOST_WIDE_INT lo = value & 0xffff;
3900 HOST_WIDE_INT hi = value - lo;
3901
3902 operands[4] = GEN_INT (hi);
3903 operands[5] = GEN_INT (lo);
3904 })
3905
3906 (define_insn "*bool<mode>3_imm"
3907 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3908 (match_operator:GPR 3 "boolean_or_operator"
3909 [(match_operand:GPR 1 "gpc_reg_operand" "%r")
3910 (match_operand:GPR 2 "logical_const_operand" "n")]))]
3911 ""
3912 "%q3i%e2 %0,%1,%u2"
3913 [(set_attr "type" "logical")])
3914
3915 (define_insn "*bool<mode>3"
3916 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3917 (match_operator:GPR 3 "boolean_operator"
3918 [(match_operand:GPR 1 "gpc_reg_operand" "r")
3919 (match_operand:GPR 2 "gpc_reg_operand" "r")]))]
3920 ""
3921 "%q3 %0,%1,%2"
3922 [(set_attr "type" "logical")])
3923
3924 (define_insn_and_split "*bool<mode>3_dot"
3925 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3926 (compare:CC (match_operator:GPR 3 "boolean_operator"
3927 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3928 (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
3929 (const_int 0)))
3930 (clobber (match_scratch:GPR 0 "=r,r"))]
3931 "<MODE>mode == Pmode"
3932 "@
3933 %q3. %0,%1,%2
3934 #"
3935 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3936 [(set (match_dup 0)
3937 (match_dup 3))
3938 (set (match_dup 4)
3939 (compare:CC (match_dup 0)
3940 (const_int 0)))]
3941 ""
3942 [(set_attr "type" "logical")
3943 (set_attr "dot" "yes")
3944 (set_attr "length" "4,8")])
3945
3946 (define_insn_and_split "*bool<mode>3_dot2"
3947 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3948 (compare:CC (match_operator:GPR 3 "boolean_operator"
3949 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3950 (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
3951 (const_int 0)))
3952 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3953 (match_dup 3))]
3954 "<MODE>mode == Pmode"
3955 "@
3956 %q3. %0,%1,%2
3957 #"
3958 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3959 [(set (match_dup 0)
3960 (match_dup 3))
3961 (set (match_dup 4)
3962 (compare:CC (match_dup 0)
3963 (const_int 0)))]
3964 ""
3965 [(set_attr "type" "logical")
3966 (set_attr "dot" "yes")
3967 (set_attr "length" "4,8")])
3968
3969
3970 (define_insn "*boolc<mode>3"
3971 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3972 (match_operator:GPR 3 "boolean_operator"
3973 [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))
3974 (match_operand:GPR 1 "gpc_reg_operand" "r")]))]
3975 ""
3976 "%q3 %0,%1,%2"
3977 [(set_attr "type" "logical")])
3978
3979 (define_insn_and_split "*boolc<mode>3_dot"
3980 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3981 (compare:CC (match_operator:GPR 3 "boolean_operator"
3982 [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3983 (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
3984 (const_int 0)))
3985 (clobber (match_scratch:GPR 0 "=r,r"))]
3986 "<MODE>mode == Pmode"
3987 "@
3988 %q3. %0,%1,%2
3989 #"
3990 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3991 [(set (match_dup 0)
3992 (match_dup 3))
3993 (set (match_dup 4)
3994 (compare:CC (match_dup 0)
3995 (const_int 0)))]
3996 ""
3997 [(set_attr "type" "logical")
3998 (set_attr "dot" "yes")
3999 (set_attr "length" "4,8")])
4000
4001 (define_insn_and_split "*boolc<mode>3_dot2"
4002 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
4003 (compare:CC (match_operator:GPR 3 "boolean_operator"
4004 [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
4005 (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
4006 (const_int 0)))
4007 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4008 (match_dup 3))]
4009 "<MODE>mode == Pmode"
4010 "@
4011 %q3. %0,%1,%2
4012 #"
4013 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
4014 [(set (match_dup 0)
4015 (match_dup 3))
4016 (set (match_dup 4)
4017 (compare:CC (match_dup 0)
4018 (const_int 0)))]
4019 ""
4020 [(set_attr "type" "logical")
4021 (set_attr "dot" "yes")
4022 (set_attr "length" "4,8")])
4023
4024
4025 (define_insn "*boolcc<mode>3"
4026 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4027 (match_operator:GPR 3 "boolean_operator"
4028 [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
4029 (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))]))]
4030 ""
4031 "%q3 %0,%1,%2"
4032 [(set_attr "type" "logical")])
4033
4034 (define_insn_and_split "*boolcc<mode>3_dot"
4035 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
4036 (compare:CC (match_operator:GPR 3 "boolean_operator"
4037 [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
4038 (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
4039 (const_int 0)))
4040 (clobber (match_scratch:GPR 0 "=r,r"))]
4041 "<MODE>mode == Pmode"
4042 "@
4043 %q3. %0,%1,%2
4044 #"
4045 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
4046 [(set (match_dup 0)
4047 (match_dup 3))
4048 (set (match_dup 4)
4049 (compare:CC (match_dup 0)
4050 (const_int 0)))]
4051 ""
4052 [(set_attr "type" "logical")
4053 (set_attr "dot" "yes")
4054 (set_attr "length" "4,8")])
4055
4056 (define_insn_and_split "*boolcc<mode>3_dot2"
4057 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
4058 (compare:CC (match_operator:GPR 3 "boolean_operator"
4059 [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
4060 (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
4061 (const_int 0)))
4062 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4063 (match_dup 3))]
4064 "<MODE>mode == Pmode"
4065 "@
4066 %q3. %0,%1,%2
4067 #"
4068 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
4069 [(set (match_dup 0)
4070 (match_dup 3))
4071 (set (match_dup 4)
4072 (compare:CC (match_dup 0)
4073 (const_int 0)))]
4074 ""
4075 [(set_attr "type" "logical")
4076 (set_attr "dot" "yes")
4077 (set_attr "length" "4,8")])
4078
4079
4080 ;; TODO: Should have dots of this as well.
4081 (define_insn "*eqv<mode>3"
4082 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4083 (not:GPR (xor:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4084 (match_operand:GPR 2 "gpc_reg_operand" "r"))))]
4085 ""
4086 "eqv %0,%1,%2"
4087 [(set_attr "type" "logical")])
4088 \f
4089 ;; Rotate-and-mask and insert.
4090
4091 (define_insn "*rotl<mode>3_mask"
4092 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4093 (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
4094 [(match_operand:GPR 1 "gpc_reg_operand" "r")
4095 (match_operand:SI 2 "reg_or_cint_operand" "rn")])
4096 (match_operand:GPR 3 "const_int_operand" "n")))]
4097 "rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
4098 {
4099 return rs6000_insn_for_shift_mask (<MODE>mode, operands, false);
4100 }
4101 [(set_attr "type" "shift")
4102 (set_attr "maybe_var_shift" "yes")])
4103
4104 (define_insn_and_split "*rotl<mode>3_mask_dot"
4105 [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y")
4106 (compare:CC
4107 (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
4108 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
4109 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")])
4110 (match_operand:GPR 3 "const_int_operand" "n,n"))
4111 (const_int 0)))
4112 (clobber (match_scratch:GPR 0 "=r,r"))]
4113 "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff)
4114 && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
4115 {
4116 if (which_alternative == 0)
4117 return rs6000_insn_for_shift_mask (<MODE>mode, operands, true);
4118 else
4119 return "#";
4120 }
4121 "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)"
4122 [(set (match_dup 0)
4123 (and:GPR (match_dup 4)
4124 (match_dup 3)))
4125 (set (match_dup 5)
4126 (compare:CC (match_dup 0)
4127 (const_int 0)))]
4128 ""
4129 [(set_attr "type" "shift")
4130 (set_attr "maybe_var_shift" "yes")
4131 (set_attr "dot" "yes")
4132 (set_attr "length" "4,8")])
4133
4134 (define_insn_and_split "*rotl<mode>3_mask_dot2"
4135 [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y")
4136 (compare:CC
4137 (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
4138 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
4139 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")])
4140 (match_operand:GPR 3 "const_int_operand" "n,n"))
4141 (const_int 0)))
4142 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4143 (and:GPR (match_dup 4)
4144 (match_dup 3)))]
4145 "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff)
4146 && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
4147 {
4148 if (which_alternative == 0)
4149 return rs6000_insn_for_shift_mask (<MODE>mode, operands, true);
4150 else
4151 return "#";
4152 }
4153 "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)"
4154 [(set (match_dup 0)
4155 (and:GPR (match_dup 4)
4156 (match_dup 3)))
4157 (set (match_dup 5)
4158 (compare:CC (match_dup 0)
4159 (const_int 0)))]
4160 ""
4161 [(set_attr "type" "shift")
4162 (set_attr "maybe_var_shift" "yes")
4163 (set_attr "dot" "yes")
4164 (set_attr "length" "4,8")])
4165
4166 ; Special case for less-than-0. We can do it with just one machine
4167 ; instruction, but the generic optimizers do not realise it is cheap.
4168 (define_insn "*lt0_<mode>di"
4169 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4170 (lt:GPR (match_operand:DI 1 "gpc_reg_operand" "r")
4171 (const_int 0)))]
4172 "TARGET_POWERPC64"
4173 "srdi %0,%1,63"
4174 [(set_attr "type" "shift")])
4175
4176 (define_insn "*lt0_<mode>si"
4177 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4178 (lt:GPR (match_operand:SI 1 "gpc_reg_operand" "r")
4179 (const_int 0)))]
4180 ""
4181 "rlwinm %0,%1,1,31,31"
4182 [(set_attr "type" "shift")])
4183
4184
4185
4186 ; Two forms for insert (the two arms of the IOR are not canonicalized,
4187 ; both are an AND so are the same precedence).
4188 (define_insn "*rotl<mode>3_insert"
4189 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4190 (ior:GPR (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
4191 [(match_operand:GPR 1 "gpc_reg_operand" "r")
4192 (match_operand:SI 2 "const_int_operand" "n")])
4193 (match_operand:GPR 3 "const_int_operand" "n"))
4194 (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0")
4195 (match_operand:GPR 6 "const_int_operand" "n"))))]
4196 "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode)
4197 && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0"
4198 {
4199 return rs6000_insn_for_insert_mask (<MODE>mode, operands, false);
4200 }
4201 [(set_attr "type" "insert")])
4202 ; FIXME: this needs an attr "size", so that the scheduler can see the
4203 ; difference between rlwimi and rldimi. We also might want dot forms,
4204 ; but not for rlwimi on POWER4 and similar processors.
4205
4206 (define_insn "*rotl<mode>3_insert_2"
4207 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4208 (ior:GPR (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0")
4209 (match_operand:GPR 6 "const_int_operand" "n"))
4210 (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
4211 [(match_operand:GPR 1 "gpc_reg_operand" "r")
4212 (match_operand:SI 2 "const_int_operand" "n")])
4213 (match_operand:GPR 3 "const_int_operand" "n"))))]
4214 "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode)
4215 && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0"
4216 {
4217 return rs6000_insn_for_insert_mask (<MODE>mode, operands, false);
4218 }
4219 [(set_attr "type" "insert")])
4220
4221 ; There are also some forms without one of the ANDs.
4222 (define_insn "rotl<mode>3_insert_3"
4223 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4224 (ior:GPR (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0")
4225 (match_operand:GPR 4 "const_int_operand" "n"))
4226 (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4227 (match_operand:SI 2 "const_int_operand" "n"))))]
4228 "INTVAL (operands[2]) > 0
4229 && INTVAL (operands[2]) == exact_log2 (UINTVAL (operands[4]) + 1)"
4230 {
4231 if (<MODE>mode == SImode)
4232 return "rlwimi %0,%1,%h2,0,31-%h2";
4233 else
4234 return "rldimi %0,%1,%H2,0";
4235 }
4236 [(set_attr "type" "insert")])
4237
4238 ; Canonicalize the PLUS and XOR forms to IOR for rotl<mode>3_insert_3
4239 (define_code_iterator plus_xor [plus xor])
4240
4241 (define_insn_and_split "*rotl<mode>3_insert_3_<code>"
4242 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4243 (plus_xor:GPR
4244 (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0")
4245 (match_operand:GPR 4 "const_int_operand" "n"))
4246 (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4247 (match_operand:SI 2 "const_int_operand" "n"))))]
4248 "INTVAL (operands[2]) > 0
4249 && INTVAL (operands[2]) == exact_log2 (UINTVAL (operands[4]) + 1)"
4250 "#"
4251 "&& 1"
4252 [(set (match_dup 0)
4253 (ior:GPR (and:GPR (match_dup 3) (match_dup 4))
4254 (ashift:GPR (match_dup 1) (match_dup 2))))])
4255
4256 (define_code_iterator plus_ior_xor [plus ior xor])
4257
4258 (define_split
4259 [(set (match_operand:GPR 0 "gpc_reg_operand")
4260 (plus_ior_xor:GPR (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand")
4261 (match_operand:SI 2 "const_int_operand"))
4262 (match_operand:GPR 3 "gpc_reg_operand")))]
4263 "nonzero_bits (operands[3], <MODE>mode)
4264 < HOST_WIDE_INT_1U << INTVAL (operands[2])"
4265 [(set (match_dup 0)
4266 (ior:GPR (and:GPR (match_dup 3)
4267 (match_dup 4))
4268 (ashift:GPR (match_dup 1)
4269 (match_dup 2))))]
4270 {
4271 operands[4] = GEN_INT ((HOST_WIDE_INT_1U << INTVAL (operands[2])) - 1);
4272 })
4273
4274 (define_insn "*rotlsi3_insert_4"
4275 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
4276 (ior:SI (and:SI (match_operand:SI 3 "gpc_reg_operand" "0")
4277 (match_operand:SI 4 "const_int_operand" "n"))
4278 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4279 (match_operand:SI 2 "const_int_operand" "n"))))]
4280 "INTVAL (operands[2]) + exact_log2 (-UINTVAL (operands[4])) == 32"
4281 "rlwimi %0,%1,32-%h2,%h2,31"
4282 [(set_attr "type" "insert")])
4283
4284 (define_insn "*rotlsi3_insert_5"
4285 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
4286 (ior:SI (and:SI (match_operand:SI 1 "gpc_reg_operand" "0,r")
4287 (match_operand:SI 2 "const_int_operand" "n,n"))
4288 (and:SI (match_operand:SI 3 "gpc_reg_operand" "r,0")
4289 (match_operand:SI 4 "const_int_operand" "n,n"))))]
4290 "rs6000_is_valid_mask (operands[2], NULL, NULL, SImode)
4291 && UINTVAL (operands[2]) != 0 && UINTVAL (operands[4]) != 0
4292 && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
4293 "@
4294 rlwimi %0,%3,0,%4
4295 rlwimi %0,%1,0,%2"
4296 [(set_attr "type" "insert")])
4297
4298 (define_insn "*rotldi3_insert_6"
4299 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4300 (ior:DI (and:DI (match_operand:DI 1 "gpc_reg_operand" "0")
4301 (match_operand:DI 2 "const_int_operand" "n"))
4302 (and:DI (match_operand:DI 3 "gpc_reg_operand" "r")
4303 (match_operand:DI 4 "const_int_operand" "n"))))]
4304 "exact_log2 (-UINTVAL (operands[2])) > 0
4305 && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
4306 {
4307 operands[5] = GEN_INT (64 - exact_log2 (-UINTVAL (operands[2])));
4308 return "rldimi %0,%3,0,%5";
4309 }
4310 [(set_attr "type" "insert")
4311 (set_attr "size" "64")])
4312
4313 (define_insn "*rotldi3_insert_7"
4314 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4315 (ior:DI (and:DI (match_operand:DI 3 "gpc_reg_operand" "r")
4316 (match_operand:DI 4 "const_int_operand" "n"))
4317 (and:DI (match_operand:DI 1 "gpc_reg_operand" "0")
4318 (match_operand:DI 2 "const_int_operand" "n"))))]
4319 "exact_log2 (-UINTVAL (operands[2])) > 0
4320 && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
4321 {
4322 operands[5] = GEN_INT (64 - exact_log2 (-UINTVAL (operands[2])));
4323 return "rldimi %0,%3,0,%5";
4324 }
4325 [(set_attr "type" "insert")
4326 (set_attr "size" "64")])
4327
4328
4329 ; This handles the important case of multiple-precision shifts. There is
4330 ; no canonicalization rule for ASHIFT vs. LSHIFTRT, so two patterns.
4331 (define_split
4332 [(set (match_operand:GPR 0 "gpc_reg_operand")
4333 (ior:GPR (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand")
4334 (match_operand:SI 3 "const_int_operand"))
4335 (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand")
4336 (match_operand:SI 4 "const_int_operand"))))]
4337 "can_create_pseudo_p ()
4338 && INTVAL (operands[3]) + INTVAL (operands[4])
4339 >= GET_MODE_PRECISION (<MODE>mode)"
4340 [(set (match_dup 5)
4341 (lshiftrt:GPR (match_dup 2)
4342 (match_dup 4)))
4343 (set (match_dup 0)
4344 (ior:GPR (and:GPR (match_dup 5)
4345 (match_dup 6))
4346 (ashift:GPR (match_dup 1)
4347 (match_dup 3))))]
4348 {
4349 unsigned HOST_WIDE_INT mask = 1;
4350 mask = (mask << INTVAL (operands[3])) - 1;
4351 operands[5] = gen_reg_rtx (<MODE>mode);
4352 operands[6] = GEN_INT (mask);
4353 })
4354
4355 (define_split
4356 [(set (match_operand:GPR 0 "gpc_reg_operand")
4357 (ior:GPR (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand")
4358 (match_operand:SI 4 "const_int_operand"))
4359 (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand")
4360 (match_operand:SI 3 "const_int_operand"))))]
4361 "can_create_pseudo_p ()
4362 && INTVAL (operands[3]) + INTVAL (operands[4])
4363 >= GET_MODE_PRECISION (<MODE>mode)"
4364 [(set (match_dup 5)
4365 (lshiftrt:GPR (match_dup 2)
4366 (match_dup 4)))
4367 (set (match_dup 0)
4368 (ior:GPR (and:GPR (match_dup 5)
4369 (match_dup 6))
4370 (ashift:GPR (match_dup 1)
4371 (match_dup 3))))]
4372 {
4373 unsigned HOST_WIDE_INT mask = 1;
4374 mask = (mask << INTVAL (operands[3])) - 1;
4375 operands[5] = gen_reg_rtx (<MODE>mode);
4376 operands[6] = GEN_INT (mask);
4377 })
4378
4379
4380 ; Another important case is setting some bits to 1; we can do that with
4381 ; an insert instruction, in many cases.
4382 (define_insn_and_split "*ior<mode>_mask"
4383 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4384 (ior:GPR (match_operand:GPR 1 "gpc_reg_operand" "0")
4385 (match_operand:GPR 2 "const_int_operand" "n")))
4386 (clobber (match_scratch:GPR 3 "=r"))]
4387 "!logical_const_operand (operands[2], <MODE>mode)
4388 && rs6000_is_valid_mask (operands[2], NULL, NULL, <MODE>mode)"
4389 "#"
4390 "&& 1"
4391 [(set (match_dup 3)
4392 (const_int -1))
4393 (set (match_dup 0)
4394 (ior:GPR (and:GPR (rotate:GPR (match_dup 3)
4395 (match_dup 4))
4396 (match_dup 2))
4397 (and:GPR (match_dup 1)
4398 (match_dup 5))))]
4399 {
4400 int nb, ne;
4401 rs6000_is_valid_mask (operands[2], &nb, &ne, <MODE>mode);
4402 if (GET_CODE (operands[3]) == SCRATCH)
4403 operands[3] = gen_reg_rtx (<MODE>mode);
4404 operands[4] = GEN_INT (ne);
4405 operands[5] = GEN_INT (~UINTVAL (operands[2]));
4406 }
4407 [(set_attr "type" "two")
4408 (set_attr "length" "8")])
4409
4410
4411 ; Yet another case is an rldimi with the second value coming from memory.
4412 ; The zero_extend that should become part of the rldimi is merged into the
4413 ; load from memory instead. Split things properly again.
4414 (define_split
4415 [(set (match_operand:DI 0 "gpc_reg_operand")
4416 (ior:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand")
4417 (match_operand:SI 2 "const_int_operand"))
4418 (zero_extend:DI (match_operand:QHSI 3 "memory_operand"))))]
4419 "INTVAL (operands[2]) == <bits>"
4420 [(set (match_dup 4)
4421 (zero_extend:DI (match_dup 3)))
4422 (set (match_dup 0)
4423 (ior:DI (and:DI (match_dup 4)
4424 (match_dup 5))
4425 (ashift:DI (match_dup 1)
4426 (match_dup 2))))]
4427 {
4428 operands[4] = gen_reg_rtx (DImode);
4429 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << <bits>) - 1);
4430 })
4431
4432 ; rldimi with UNSPEC_SI_FROM_SF.
4433 (define_insn_and_split "*rotldi3_insert_sf"
4434 [(set (match_operand:DI 0 "gpc_reg_operand")
4435 (ior:DI
4436 (ashift:DI (match_operand:DI 1 "gpc_reg_operand")
4437 (match_operand:SI 2 "const_int_operand"))
4438 (zero_extend:DI
4439 (unspec:QHSI
4440 [(match_operand:SF 3 "memory_operand")]
4441 UNSPEC_SI_FROM_SF))))
4442 (clobber (match_scratch:V4SF 4))]
4443 "TARGET_POWERPC64 && INTVAL (operands[2]) == <bits>"
4444 "#"
4445 "&& 1"
4446 [(parallel [(set (match_dup 5)
4447 (zero_extend:DI (unspec:QHSI [(match_dup 3)] UNSPEC_SI_FROM_SF)))
4448 (clobber (match_dup 4))])
4449 (set (match_dup 0)
4450 (ior:DI
4451 (and:DI (match_dup 5) (match_dup 6))
4452 (ashift:DI (match_dup 1) (match_dup 2))))]
4453 {
4454 operands[5] = gen_reg_rtx (DImode);
4455 operands[6] = GEN_INT ((HOST_WIDE_INT_1U << <bits>) - 1);
4456 })
4457
4458 ; rlwimi, too.
4459 (define_split
4460 [(set (match_operand:SI 0 "gpc_reg_operand")
4461 (ior:SI (ashift:SI (match_operand:SI 1 "gpc_reg_operand")
4462 (match_operand:SI 2 "const_int_operand"))
4463 (zero_extend:SI (match_operand:QHI 3 "memory_operand"))))]
4464 "INTVAL (operands[2]) == <bits>"
4465 [(set (match_dup 4)
4466 (zero_extend:SI (match_dup 3)))
4467 (set (match_dup 0)
4468 (ior:SI (and:SI (match_dup 4)
4469 (match_dup 5))
4470 (ashift:SI (match_dup 1)
4471 (match_dup 2))))]
4472 {
4473 operands[4] = gen_reg_rtx (SImode);
4474 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << <bits>) - 1);
4475 })
4476
4477
4478 ;; Now the simple shifts.
4479
4480 (define_insn "rotl<mode>3"
4481 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4482 (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4483 (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4484 ""
4485 "rotl<wd>%I2 %0,%1,%<hH>2"
4486 [(set_attr "type" "shift")
4487 (set_attr "maybe_var_shift" "yes")])
4488
4489 (define_insn "*rotlsi3_64"
4490 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4491 (zero_extend:DI
4492 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4493 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4494 "TARGET_POWERPC64"
4495 "rotlw%I2 %0,%1,%h2"
4496 [(set_attr "type" "shift")
4497 (set_attr "maybe_var_shift" "yes")])
4498
4499 (define_insn_and_split "*rotl<mode>3_dot"
4500 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4501 (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4502 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4503 (const_int 0)))
4504 (clobber (match_scratch:GPR 0 "=r,r"))]
4505 "<MODE>mode == Pmode"
4506 "@
4507 rotl<wd>%I2. %0,%1,%<hH>2
4508 #"
4509 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4510 [(set (match_dup 0)
4511 (rotate:GPR (match_dup 1)
4512 (match_dup 2)))
4513 (set (match_dup 3)
4514 (compare:CC (match_dup 0)
4515 (const_int 0)))]
4516 ""
4517 [(set_attr "type" "shift")
4518 (set_attr "maybe_var_shift" "yes")
4519 (set_attr "dot" "yes")
4520 (set_attr "length" "4,8")])
4521
4522 (define_insn_and_split "*rotl<mode>3_dot2"
4523 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4524 (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4525 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4526 (const_int 0)))
4527 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4528 (rotate:GPR (match_dup 1)
4529 (match_dup 2)))]
4530 "<MODE>mode == Pmode"
4531 "@
4532 rotl<wd>%I2. %0,%1,%<hH>2
4533 #"
4534 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4535 [(set (match_dup 0)
4536 (rotate:GPR (match_dup 1)
4537 (match_dup 2)))
4538 (set (match_dup 3)
4539 (compare:CC (match_dup 0)
4540 (const_int 0)))]
4541 ""
4542 [(set_attr "type" "shift")
4543 (set_attr "maybe_var_shift" "yes")
4544 (set_attr "dot" "yes")
4545 (set_attr "length" "4,8")])
4546
4547
4548 (define_insn "ashl<mode>3"
4549 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4550 (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4551 (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4552 ""
4553 "sl<wd>%I2 %0,%1,%<hH>2"
4554 [(set_attr "type" "shift")
4555 (set_attr "maybe_var_shift" "yes")])
4556
4557 (define_insn "*ashlsi3_64"
4558 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4559 (zero_extend:DI
4560 (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4561 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4562 "TARGET_POWERPC64"
4563 "slw%I2 %0,%1,%h2"
4564 [(set_attr "type" "shift")
4565 (set_attr "maybe_var_shift" "yes")])
4566
4567 (define_insn_and_split "*ashl<mode>3_dot"
4568 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4569 (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4570 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4571 (const_int 0)))
4572 (clobber (match_scratch:GPR 0 "=r,r"))]
4573 "<MODE>mode == Pmode"
4574 "@
4575 sl<wd>%I2. %0,%1,%<hH>2
4576 #"
4577 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4578 [(set (match_dup 0)
4579 (ashift:GPR (match_dup 1)
4580 (match_dup 2)))
4581 (set (match_dup 3)
4582 (compare:CC (match_dup 0)
4583 (const_int 0)))]
4584 ""
4585 [(set_attr "type" "shift")
4586 (set_attr "maybe_var_shift" "yes")
4587 (set_attr "dot" "yes")
4588 (set_attr "length" "4,8")])
4589
4590 (define_insn_and_split "*ashl<mode>3_dot2"
4591 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4592 (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4593 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4594 (const_int 0)))
4595 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4596 (ashift:GPR (match_dup 1)
4597 (match_dup 2)))]
4598 "<MODE>mode == Pmode"
4599 "@
4600 sl<wd>%I2. %0,%1,%<hH>2
4601 #"
4602 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4603 [(set (match_dup 0)
4604 (ashift:GPR (match_dup 1)
4605 (match_dup 2)))
4606 (set (match_dup 3)
4607 (compare:CC (match_dup 0)
4608 (const_int 0)))]
4609 ""
4610 [(set_attr "type" "shift")
4611 (set_attr "maybe_var_shift" "yes")
4612 (set_attr "dot" "yes")
4613 (set_attr "length" "4,8")])
4614
4615 ;; Pretend we have a memory form of extswsli until register allocation is done
4616 ;; so that we use LWZ to load the value from memory, instead of LWA.
4617 (define_insn_and_split "ashdi3_extswsli"
4618 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
4619 (ashift:DI
4620 (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,m"))
4621 (match_operand:DI 2 "u6bit_cint_operand" "n,n")))]
4622 "TARGET_EXTSWSLI"
4623 "@
4624 extswsli %0,%1,%2
4625 #"
4626 "&& reload_completed && MEM_P (operands[1])"
4627 [(set (match_dup 3)
4628 (match_dup 1))
4629 (set (match_dup 0)
4630 (ashift:DI (sign_extend:DI (match_dup 3))
4631 (match_dup 2)))]
4632 {
4633 operands[3] = gen_lowpart (SImode, operands[0]);
4634 }
4635 [(set_attr "type" "shift")
4636 (set_attr "maybe_var_shift" "no")])
4637
4638
4639 (define_insn_and_split "ashdi3_extswsli_dot"
4640 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y")
4641 (compare:CC
4642 (ashift:DI
4643 (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m"))
4644 (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n"))
4645 (const_int 0)))
4646 (clobber (match_scratch:DI 0 "=r,r,r,r"))]
4647 "TARGET_EXTSWSLI"
4648 "@
4649 extswsli. %0,%1,%2
4650 #
4651 #
4652 #"
4653 "&& reload_completed
4654 && (cc_reg_not_cr0_operand (operands[3], CCmode)
4655 || memory_operand (operands[1], SImode))"
4656 [(pc)]
4657 {
4658 rtx dest = operands[0];
4659 rtx src = operands[1];
4660 rtx shift = operands[2];
4661 rtx cr = operands[3];
4662 rtx src2;
4663
4664 if (!MEM_P (src))
4665 src2 = src;
4666 else
4667 {
4668 src2 = gen_lowpart (SImode, dest);
4669 emit_move_insn (src2, src);
4670 }
4671
4672 if (REGNO (cr) == CR0_REGNO)
4673 {
4674 emit_insn (gen_ashdi3_extswsli_dot2 (dest, src2, shift, cr));
4675 DONE;
4676 }
4677
4678 emit_insn (gen_ashdi3_extswsli (dest, src2, shift));
4679 emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx)));
4680 DONE;
4681 }
4682 [(set_attr "type" "shift")
4683 (set_attr "maybe_var_shift" "no")
4684 (set_attr "dot" "yes")
4685 (set_attr "length" "4,8,8,12")])
4686
4687 (define_insn_and_split "ashdi3_extswsli_dot2"
4688 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y")
4689 (compare:CC
4690 (ashift:DI
4691 (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m"))
4692 (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n"))
4693 (const_int 0)))
4694 (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r")
4695 (ashift:DI (sign_extend:DI (match_dup 1))
4696 (match_dup 2)))]
4697 "TARGET_EXTSWSLI"
4698 "@
4699 extswsli. %0,%1,%2
4700 #
4701 #
4702 #"
4703 "&& reload_completed
4704 && (cc_reg_not_cr0_operand (operands[3], CCmode)
4705 || memory_operand (operands[1], SImode))"
4706 [(pc)]
4707 {
4708 rtx dest = operands[0];
4709 rtx src = operands[1];
4710 rtx shift = operands[2];
4711 rtx cr = operands[3];
4712 rtx src2;
4713
4714 if (!MEM_P (src))
4715 src2 = src;
4716 else
4717 {
4718 src2 = gen_lowpart (SImode, dest);
4719 emit_move_insn (src2, src);
4720 }
4721
4722 if (REGNO (cr) == CR0_REGNO)
4723 {
4724 emit_insn (gen_ashdi3_extswsli_dot2 (dest, src2, shift, cr));
4725 DONE;
4726 }
4727
4728 emit_insn (gen_ashdi3_extswsli (dest, src2, shift));
4729 emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx)));
4730 DONE;
4731 }
4732 [(set_attr "type" "shift")
4733 (set_attr "maybe_var_shift" "no")
4734 (set_attr "dot" "yes")
4735 (set_attr "length" "4,8,8,12")])
4736
4737 (define_insn "lshr<mode>3"
4738 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4739 (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4740 (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4741 ""
4742 "sr<wd>%I2 %0,%1,%<hH>2"
4743 [(set_attr "type" "shift")
4744 (set_attr "maybe_var_shift" "yes")])
4745
4746 (define_insn "*lshrsi3_64"
4747 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4748 (zero_extend:DI
4749 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4750 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4751 "TARGET_POWERPC64"
4752 "srw%I2 %0,%1,%h2"
4753 [(set_attr "type" "shift")
4754 (set_attr "maybe_var_shift" "yes")])
4755
4756 (define_insn_and_split "*lshr<mode>3_dot"
4757 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4758 (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4759 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4760 (const_int 0)))
4761 (clobber (match_scratch:GPR 0 "=r,r"))]
4762 "<MODE>mode == Pmode"
4763 "@
4764 sr<wd>%I2. %0,%1,%<hH>2
4765 #"
4766 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4767 [(set (match_dup 0)
4768 (lshiftrt:GPR (match_dup 1)
4769 (match_dup 2)))
4770 (set (match_dup 3)
4771 (compare:CC (match_dup 0)
4772 (const_int 0)))]
4773 ""
4774 [(set_attr "type" "shift")
4775 (set_attr "maybe_var_shift" "yes")
4776 (set_attr "dot" "yes")
4777 (set_attr "length" "4,8")])
4778
4779 (define_insn_and_split "*lshr<mode>3_dot2"
4780 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4781 (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4782 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4783 (const_int 0)))
4784 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4785 (lshiftrt:GPR (match_dup 1)
4786 (match_dup 2)))]
4787 "<MODE>mode == Pmode"
4788 "@
4789 sr<wd>%I2. %0,%1,%<hH>2
4790 #"
4791 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4792 [(set (match_dup 0)
4793 (lshiftrt:GPR (match_dup 1)
4794 (match_dup 2)))
4795 (set (match_dup 3)
4796 (compare:CC (match_dup 0)
4797 (const_int 0)))]
4798 ""
4799 [(set_attr "type" "shift")
4800 (set_attr "maybe_var_shift" "yes")
4801 (set_attr "dot" "yes")
4802 (set_attr "length" "4,8")])
4803
4804
4805 (define_insn "ashr<mode>3"
4806 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4807 (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4808 (match_operand:SI 2 "reg_or_cint_operand" "rn")))
4809 (clobber (reg:GPR CA_REGNO))]
4810 ""
4811 "sra<wd>%I2 %0,%1,%<hH>2"
4812 [(set_attr "type" "shift")
4813 (set_attr "maybe_var_shift" "yes")])
4814
4815 (define_insn "*ashrsi3_64"
4816 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4817 (sign_extend:DI
4818 (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4819 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))
4820 (clobber (reg:SI CA_REGNO))]
4821 "TARGET_POWERPC64"
4822 "sraw%I2 %0,%1,%h2"
4823 [(set_attr "type" "shift")
4824 (set_attr "maybe_var_shift" "yes")])
4825
4826 (define_insn_and_split "*ashr<mode>3_dot"
4827 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4828 (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4829 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4830 (const_int 0)))
4831 (clobber (match_scratch:GPR 0 "=r,r"))
4832 (clobber (reg:GPR CA_REGNO))]
4833 "<MODE>mode == Pmode"
4834 "@
4835 sra<wd>%I2. %0,%1,%<hH>2
4836 #"
4837 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4838 [(parallel [(set (match_dup 0)
4839 (ashiftrt:GPR (match_dup 1)
4840 (match_dup 2)))
4841 (clobber (reg:GPR CA_REGNO))])
4842 (set (match_dup 3)
4843 (compare:CC (match_dup 0)
4844 (const_int 0)))]
4845 ""
4846 [(set_attr "type" "shift")
4847 (set_attr "maybe_var_shift" "yes")
4848 (set_attr "dot" "yes")
4849 (set_attr "length" "4,8")])
4850
4851 (define_insn_and_split "*ashr<mode>3_dot2"
4852 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4853 (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4854 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4855 (const_int 0)))
4856 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4857 (ashiftrt:GPR (match_dup 1)
4858 (match_dup 2)))
4859 (clobber (reg:GPR CA_REGNO))]
4860 "<MODE>mode == Pmode"
4861 "@
4862 sra<wd>%I2. %0,%1,%<hH>2
4863 #"
4864 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4865 [(parallel [(set (match_dup 0)
4866 (ashiftrt:GPR (match_dup 1)
4867 (match_dup 2)))
4868 (clobber (reg:GPR CA_REGNO))])
4869 (set (match_dup 3)
4870 (compare:CC (match_dup 0)
4871 (const_int 0)))]
4872 ""
4873 [(set_attr "type" "shift")
4874 (set_attr "maybe_var_shift" "yes")
4875 (set_attr "dot" "yes")
4876 (set_attr "length" "4,8")])
4877 \f
4878 ;; Builtins to replace a division to generate FRE reciprocal estimate
4879 ;; instructions and the necessary fixup instructions
4880 (define_expand "recip<mode>3"
4881 [(match_operand:RECIPF 0 "gpc_reg_operand")
4882 (match_operand:RECIPF 1 "gpc_reg_operand")
4883 (match_operand:RECIPF 2 "gpc_reg_operand")]
4884 "RS6000_RECIP_HAVE_RE_P (<MODE>mode)"
4885 {
4886 rs6000_emit_swdiv (operands[0], operands[1], operands[2], false);
4887 DONE;
4888 })
4889
4890 ;; Split to create division from FRE/FRES/etc. and fixup instead of the normal
4891 ;; hardware division. This is only done before register allocation and with
4892 ;; -ffast-math. This must appear before the divsf3/divdf3 insns.
4893 ;; We used to also check optimize_insn_for_speed_p () but problems with guessed
4894 ;; frequencies (pr68212/pr77536) yields that unreliable so it was removed.
4895 (define_split
4896 [(set (match_operand:RECIPF 0 "gpc_reg_operand")
4897 (div:RECIPF (match_operand 1 "gpc_reg_operand")
4898 (match_operand 2 "gpc_reg_operand")))]
4899 "RS6000_RECIP_AUTO_RE_P (<MODE>mode)
4900 && can_create_pseudo_p () && flag_finite_math_only
4901 && !flag_trapping_math && flag_reciprocal_math"
4902 [(const_int 0)]
4903 {
4904 rs6000_emit_swdiv (operands[0], operands[1], operands[2], true);
4905 DONE;
4906 })
4907
4908 ;; Builtins to replace 1/sqrt(x) with instructions using RSQRTE and the
4909 ;; appropriate fixup.
4910 (define_expand "rsqrt<mode>2"
4911 [(match_operand:RECIPF 0 "gpc_reg_operand")
4912 (match_operand:RECIPF 1 "gpc_reg_operand")]
4913 "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4914 {
4915 rs6000_emit_swsqrt (operands[0], operands[1], 1);
4916 DONE;
4917 })
4918 \f
4919 ;; Floating-point insns, excluding normal data motion. We combine the SF/DF
4920 ;; modes here, and also add in conditional vsx/power8-vector support to access
4921 ;; values in the traditional Altivec registers if the appropriate
4922 ;; -mupper-regs-{df,sf} option is enabled.
4923
4924 (define_expand "abs<mode>2"
4925 [(set (match_operand:SFDF 0 "gpc_reg_operand")
4926 (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))]
4927 "TARGET_HARD_FLOAT"
4928 "")
4929
4930 (define_insn "*abs<mode>2_fpr"
4931 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,wa")
4932 (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "d,wa")))]
4933 "TARGET_HARD_FLOAT"
4934 "@
4935 fabs %0,%1
4936 xsabsdp %x0,%x1"
4937 [(set_attr "type" "fpsimple")])
4938
4939 (define_insn "*nabs<mode>2_fpr"
4940 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,wa")
4941 (neg:SFDF
4942 (abs:SFDF
4943 (match_operand:SFDF 1 "gpc_reg_operand" "d,wa"))))]
4944 "TARGET_HARD_FLOAT"
4945 "@
4946 fnabs %0,%1
4947 xsnabsdp %x0,%x1"
4948 [(set_attr "type" "fpsimple")])
4949
4950 (define_expand "neg<mode>2"
4951 [(set (match_operand:SFDF 0 "gpc_reg_operand")
4952 (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))]
4953 "TARGET_HARD_FLOAT"
4954 "")
4955
4956 (define_insn "*neg<mode>2_fpr"
4957 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,wa")
4958 (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "d,wa")))]
4959 "TARGET_HARD_FLOAT"
4960 "@
4961 fneg %0,%1
4962 xsnegdp %x0,%x1"
4963 [(set_attr "type" "fpsimple")])
4964
4965 (define_expand "add<mode>3"
4966 [(set (match_operand:SFDF 0 "gpc_reg_operand")
4967 (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4968 (match_operand:SFDF 2 "gpc_reg_operand")))]
4969 "TARGET_HARD_FLOAT"
4970 "")
4971
4972 (define_insn "*add<mode>3_fpr"
4973 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,wa")
4974 (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%d,wa")
4975 (match_operand:SFDF 2 "gpc_reg_operand" "d,wa")))]
4976 "TARGET_HARD_FLOAT"
4977 "@
4978 fadd<s> %0,%1,%2
4979 xsadd<sd>p %x0,%x1,%x2"
4980 [(set_attr "type" "fp")
4981 (set_attr "isa" "*,<Fisa>")])
4982
4983 (define_expand "sub<mode>3"
4984 [(set (match_operand:SFDF 0 "gpc_reg_operand")
4985 (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4986 (match_operand:SFDF 2 "gpc_reg_operand")))]
4987 "TARGET_HARD_FLOAT"
4988 "")
4989
4990 (define_insn "*sub<mode>3_fpr"
4991 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,wa")
4992 (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "d,wa")
4993 (match_operand:SFDF 2 "gpc_reg_operand" "d,wa")))]
4994 "TARGET_HARD_FLOAT"
4995 "@
4996 fsub<s> %0,%1,%2
4997 xssub<sd>p %x0,%x1,%x2"
4998 [(set_attr "type" "fp")
4999 (set_attr "isa" "*,<Fisa>")])
5000
5001 (define_expand "mul<mode>3"
5002 [(set (match_operand:SFDF 0 "gpc_reg_operand")
5003 (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
5004 (match_operand:SFDF 2 "gpc_reg_operand")))]
5005 "TARGET_HARD_FLOAT"
5006 "")
5007
5008 (define_insn "*mul<mode>3_fpr"
5009 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,wa")
5010 (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%d,wa")
5011 (match_operand:SFDF 2 "gpc_reg_operand" "d,wa")))]
5012 "TARGET_HARD_FLOAT"
5013 "@
5014 fmul<s> %0,%1,%2
5015 xsmul<sd>p %x0,%x1,%x2"
5016 [(set_attr "type" "dmul")
5017 (set_attr "isa" "*,<Fisa>")])
5018
5019 (define_expand "div<mode>3"
5020 [(set (match_operand:SFDF 0 "gpc_reg_operand")
5021 (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
5022 (match_operand:SFDF 2 "gpc_reg_operand")))]
5023 "TARGET_HARD_FLOAT"
5024 {
5025 if (RS6000_RECIP_AUTO_RE_P (<MODE>mode)
5026 && can_create_pseudo_p () && flag_finite_math_only
5027 && !flag_trapping_math && flag_reciprocal_math)
5028 {
5029 rs6000_emit_swdiv (operands[0], operands[1], operands[2], true);
5030 DONE;
5031 }
5032 })
5033
5034 (define_insn "*div<mode>3_fpr"
5035 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,wa")
5036 (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "d,wa")
5037 (match_operand:SFDF 2 "gpc_reg_operand" "d,wa")))]
5038 "TARGET_HARD_FLOAT"
5039 "@
5040 fdiv<s> %0,%1,%2
5041 xsdiv<sd>p %x0,%x1,%x2"
5042 [(set_attr "type" "<sd>div")
5043 (set_attr "isa" "*,<Fisa>")])
5044
5045 (define_insn "*sqrt<mode>2_internal"
5046 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,wa")
5047 (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "d,wa")))]
5048 "TARGET_HARD_FLOAT && TARGET_PPC_GPOPT"
5049 "@
5050 fsqrt<s> %0,%1
5051 xssqrt<sd>p %x0,%x1"
5052 [(set_attr "type" "<sd>sqrt")
5053 (set_attr "isa" "*,<Fisa>")])
5054
5055 (define_expand "sqrt<mode>2"
5056 [(set (match_operand:SFDF 0 "gpc_reg_operand")
5057 (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))]
5058 "TARGET_HARD_FLOAT && TARGET_PPC_GPOPT"
5059 {
5060 if (<MODE>mode == SFmode
5061 && TARGET_RECIP_PRECISION
5062 && RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)
5063 && !optimize_function_for_size_p (cfun)
5064 && flag_finite_math_only && !flag_trapping_math
5065 && flag_unsafe_math_optimizations)
5066 {
5067 rs6000_emit_swsqrt (operands[0], operands[1], 0);
5068 DONE;
5069 }
5070 })
5071
5072 ;; Floating point reciprocal approximation
5073 (define_insn "fre<sd>"
5074 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,wa")
5075 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "d,wa")]
5076 UNSPEC_FRES))]
5077 "TARGET_<FFRE>"
5078 "@
5079 fre<s> %0,%1
5080 xsre<sd>p %x0,%x1"
5081 [(set_attr "type" "fp")
5082 (set_attr "isa" "*,<Fisa>")])
5083
5084 (define_expand "fmod<mode>3"
5085 [(use (match_operand:SFDF 0 "gpc_reg_operand"))
5086 (use (match_operand:SFDF 1 "gpc_reg_operand"))
5087 (use (match_operand:SFDF 2 "gpc_reg_operand"))]
5088 "TARGET_HARD_FLOAT
5089 && TARGET_FPRND
5090 && flag_unsafe_math_optimizations"
5091 {
5092 rtx div = gen_reg_rtx (<MODE>mode);
5093 emit_insn (gen_div<mode>3 (div, operands[1], operands[2]));
5094
5095 rtx friz = gen_reg_rtx (<MODE>mode);
5096 emit_insn (gen_btrunc<mode>2 (friz, div));
5097
5098 emit_insn (gen_nfms<mode>4 (operands[0], operands[2], friz, operands[1]));
5099 DONE;
5100 })
5101
5102 (define_expand "remainder<mode>3"
5103 [(use (match_operand:SFDF 0 "gpc_reg_operand"))
5104 (use (match_operand:SFDF 1 "gpc_reg_operand"))
5105 (use (match_operand:SFDF 2 "gpc_reg_operand"))]
5106 "TARGET_HARD_FLOAT
5107 && TARGET_FPRND
5108 && flag_unsafe_math_optimizations"
5109 {
5110 rtx div = gen_reg_rtx (<MODE>mode);
5111 emit_insn (gen_div<mode>3 (div, operands[1], operands[2]));
5112
5113 rtx frin = gen_reg_rtx (<MODE>mode);
5114 emit_insn (gen_round<mode>2 (frin, div));
5115
5116 emit_insn (gen_nfms<mode>4 (operands[0], operands[2], frin, operands[1]));
5117 DONE;
5118 })
5119
5120 (define_insn "*rsqrt<mode>2"
5121 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,wa")
5122 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "d,wa")]
5123 UNSPEC_RSQRT))]
5124 "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
5125 "@
5126 frsqrte<s> %0,%1
5127 xsrsqrte<sd>p %x0,%x1"
5128 [(set_attr "type" "fp")
5129 (set_attr "isa" "*,<Fisa>")])
5130
5131 ;; Floating point comparisons
5132 (define_insn "*cmp<mode>_fpr"
5133 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y,y")
5134 (compare:CCFP (match_operand:SFDF 1 "gpc_reg_operand" "d,wa")
5135 (match_operand:SFDF 2 "gpc_reg_operand" "d,wa")))]
5136 "TARGET_HARD_FLOAT"
5137 "@
5138 fcmpu %0,%1,%2
5139 xscmpudp %0,%x1,%x2"
5140 [(set_attr "type" "fpcompare")
5141 (set_attr "isa" "*,<Fisa>")])
5142
5143 ;; Floating point conversions
5144 (define_expand "extendsfdf2"
5145 [(set (match_operand:DF 0 "gpc_reg_operand")
5146 (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand")))]
5147 "TARGET_HARD_FLOAT"
5148 {
5149 if (HONOR_SNANS (SFmode))
5150 operands[1] = force_reg (SFmode, operands[1]);
5151 })
5152
5153 (define_insn_and_split "*extendsfdf2_fpr"
5154 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d,d,wa,?wa,wa,v")
5155 (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand" "0,f,m,0,wa,Z,wY")))]
5156 "TARGET_HARD_FLOAT && !HONOR_SNANS (SFmode)"
5157 "@
5158 #
5159 fmr %0,%1
5160 lfs%U1%X1 %0,%1
5161 #
5162 xscpsgndp %x0,%x1,%x1
5163 lxsspx %x0,%y1
5164 lxssp %0,%1"
5165 "&& reload_completed && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1])"
5166 [(const_int 0)]
5167 {
5168 emit_note (NOTE_INSN_DELETED);
5169 DONE;
5170 }
5171 [(set_attr "type" "fp,fpsimple,fpload,fp,fpsimple,fpload,fpload")
5172 (set_attr "isa" "*,*,*,*,p8v,p8v,p9v")])
5173
5174 (define_insn "*extendsfdf2_snan"
5175 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa")
5176 (float_extend:DF (match_operand:SF 1 "gpc_reg_operand" "f,wa")))]
5177 "TARGET_HARD_FLOAT && HONOR_SNANS (SFmode)"
5178 "@
5179 frsp %0,%1
5180 xsrsp %x0,%x1"
5181 [(set_attr "type" "fp")
5182 (set_attr "isa" "*,p8v")])
5183
5184 (define_expand "truncdfsf2"
5185 [(set (match_operand:SF 0 "gpc_reg_operand")
5186 (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand")))]
5187 "TARGET_HARD_FLOAT"
5188 "")
5189
5190 (define_insn "*truncdfsf2_fpr"
5191 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wa")
5192 (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "d,wa")))]
5193 "TARGET_HARD_FLOAT"
5194 "@
5195 frsp %0,%1
5196 xsrsp %x0,%x1"
5197 [(set_attr "type" "fp")
5198 (set_attr "isa" "*,p8v")])
5199
5200 ;; This expander is here to avoid FLOAT_WORDS_BIGENDIAN tests in
5201 ;; builtins.cc and optabs.cc that are not correct for IBM long double
5202 ;; when little-endian.
5203 (define_expand "signbit<mode>2"
5204 [(set (match_dup 2)
5205 (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand")))
5206 (set (match_dup 3)
5207 (subreg:DI (match_dup 2) 0))
5208 (set (match_dup 4)
5209 (match_dup 5))
5210 (set (match_operand:SI 0 "gpc_reg_operand")
5211 (match_dup 6))]
5212 "TARGET_HARD_FLOAT
5213 && (!FLOAT128_IEEE_P (<MODE>mode)
5214 || (TARGET_POWERPC64 && TARGET_DIRECT_MOVE))"
5215 {
5216 if (FLOAT128_IEEE_P (<MODE>mode))
5217 {
5218 rtx dest = operands[0];
5219 rtx src = operands[1];
5220 rtx tmp = gen_reg_rtx (DImode);
5221 rtx dest_di = gen_lowpart (DImode, dest);
5222
5223 emit_insn (gen_signbit2_dm (<MODE>mode, tmp, src));
5224 emit_insn (gen_lshrdi3 (dest_di, tmp, GEN_INT (63)));
5225 DONE;
5226 }
5227 operands[2] = gen_reg_rtx (DFmode);
5228 operands[3] = gen_reg_rtx (DImode);
5229 if (TARGET_POWERPC64)
5230 {
5231 operands[4] = gen_reg_rtx (DImode);
5232 operands[5] = gen_rtx_LSHIFTRT (DImode, operands[3], GEN_INT (63));
5233 operands[6] = gen_rtx_SUBREG (SImode, operands[4],
5234 WORDS_BIG_ENDIAN ? 4 : 0);
5235 }
5236 else
5237 {
5238 operands[4] = gen_reg_rtx (SImode);
5239 operands[5] = gen_rtx_SUBREG (SImode, operands[3],
5240 WORDS_BIG_ENDIAN ? 0 : 4);
5241 operands[6] = gen_rtx_LSHIFTRT (SImode, operands[4], GEN_INT (31));
5242 }
5243 })
5244
5245 ;; Optimize IEEE 128-bit signbit on 64-bit systems with direct move to avoid
5246 ;; multiple direct moves. If we used a SUBREG:DI of the Floa128 type, the
5247 ;; register allocator would typically move the entire _Float128 item to GPRs (2
5248 ;; instructions on ISA 3.0, 3-4 instructions on ISA 2.07).
5249 ;;
5250 ;; After register allocation, if the _Float128 had originally been in GPRs, the
5251 ;; split allows the post reload phases to eliminate the move, and do the shift
5252 ;; directly with the register that contains the signbit.
5253 (define_insn_and_split "@signbit<mode>2_dm"
5254 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
5255 (unspec:DI [(match_operand:SIGNBIT 1 "gpc_reg_operand" "wa,r")]
5256 UNSPEC_SIGNBIT))]
5257 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
5258 "@
5259 mfvsrd %0,%x1
5260 #"
5261 "&& reload_completed && int_reg_operand (operands[1], <MODE>mode)"
5262 [(set (match_dup 0)
5263 (match_dup 2))]
5264 {
5265 operands[2] = gen_highpart (DImode, operands[1]);
5266 }
5267 [(set_attr "type" "mfvsr,*")])
5268
5269 ;; Optimize IEEE 128-bit signbit on to avoid loading the value into a vector
5270 ;; register and then doing a direct move if the value comes from memory. On
5271 ;; little endian, we have to load the 2nd double-word to get the sign bit.
5272 (define_insn_and_split "*signbit<mode>2_dm_mem"
5273 [(set (match_operand:DI 0 "gpc_reg_operand" "=b")
5274 (unspec:DI [(match_operand:SIGNBIT 1 "memory_operand" "m")]
5275 UNSPEC_SIGNBIT))]
5276 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
5277 "#"
5278 "&& 1"
5279 [(set (match_dup 0)
5280 (match_dup 2))]
5281 {
5282 rtx dest = operands[0];
5283 rtx src = operands[1];
5284 rtx addr = XEXP (src, 0);
5285
5286 if (WORDS_BIG_ENDIAN)
5287 operands[2] = adjust_address (src, DImode, 0);
5288
5289 else if (REG_P (addr) || SUBREG_P (addr))
5290 operands[2] = adjust_address (src, DImode, 8);
5291
5292 else if (GET_CODE (addr) == PLUS && REG_P (XEXP (addr, 0))
5293 && CONST_INT_P (XEXP (addr, 1)) && mem_operand_gpr (src, DImode))
5294 operands[2] = adjust_address (src, DImode, 8);
5295
5296 else
5297 {
5298 rtx tmp = can_create_pseudo_p () ? gen_reg_rtx (DImode) : dest;
5299 emit_insn (gen_rtx_SET (tmp, addr));
5300 operands[2] = change_address (src, DImode,
5301 gen_rtx_PLUS (DImode, tmp, GEN_INT (8)));
5302 }
5303 })
5304
5305 (define_expand "copysign<mode>3"
5306 [(set (match_dup 3)
5307 (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))
5308 (set (match_dup 4)
5309 (neg:SFDF (abs:SFDF (match_dup 1))))
5310 (set (match_operand:SFDF 0 "gpc_reg_operand")
5311 (if_then_else:SFDF (ge (match_operand:SFDF 2 "gpc_reg_operand")
5312 (match_dup 5))
5313 (match_dup 3)
5314 (match_dup 4)))]
5315 "TARGET_HARD_FLOAT
5316 && ((TARGET_PPC_GFXOPT
5317 && !HONOR_NANS (<MODE>mode)
5318 && !HONOR_SIGNED_ZEROS (<MODE>mode))
5319 || TARGET_CMPB
5320 || VECTOR_UNIT_VSX_P (<MODE>mode))"
5321 {
5322 if (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode))
5323 {
5324 emit_insn (gen_copysign<mode>3_fcpsgn (operands[0], operands[1],
5325 operands[2]));
5326 DONE;
5327 }
5328
5329 operands[3] = gen_reg_rtx (<MODE>mode);
5330 operands[4] = gen_reg_rtx (<MODE>mode);
5331 operands[5] = CONST0_RTX (<MODE>mode);
5332 })
5333
5334 ;; Use an unspec rather providing an if-then-else in RTL, to prevent the
5335 ;; compiler from optimizing -0.0
5336 (define_insn "copysign<mode>3_fcpsgn"
5337 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,wa")
5338 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "d,wa")
5339 (match_operand:SFDF 2 "gpc_reg_operand" "d,wa")]
5340 UNSPEC_COPYSIGN))]
5341 "TARGET_HARD_FLOAT && (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode))"
5342 "@
5343 fcpsgn %0,%2,%1
5344 xscpsgndp %x0,%x2,%x1"
5345 [(set_attr "type" "fpsimple")])
5346
5347 ;; For MIN, MAX, and conditional move, we use DEFINE_EXPAND's that involve a
5348 ;; fsel instruction and some auxiliary computations. Then we just have a
5349 ;; single DEFINE_INSN for fsel and the define_splits to make them if made by
5350 ;; combine.
5351 ;; For MIN, MAX on non-VSX machines, and conditional move all of the time, we
5352 ;; use DEFINE_EXPAND's that involve a fsel instruction and some auxiliary
5353 ;; computations. Then we just have a single DEFINE_INSN for fsel and the
5354 ;; define_splits to make them if made by combine. On VSX machines we have the
5355 ;; min/max instructions.
5356 ;;
5357 ;; On VSX, we only check for TARGET_VSX instead of checking for a vsx/p8 vector
5358 ;; to allow either DF/SF to use only traditional registers.
5359
5360 (define_expand "s<minmax><mode>3"
5361 [(set (match_operand:SFDF 0 "gpc_reg_operand")
5362 (fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
5363 (match_operand:SFDF 2 "gpc_reg_operand")))]
5364 "TARGET_MINMAX"
5365 {
5366 rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]);
5367 DONE;
5368 })
5369
5370 (define_insn "*s<minmax><mode>3_vsx"
5371 [(set (match_operand:SFDF 0 "vsx_register_operand" "=wa")
5372 (fp_minmax:SFDF (match_operand:SFDF 1 "vsx_register_operand" "wa")
5373 (match_operand:SFDF 2 "vsx_register_operand" "wa")))]
5374 "TARGET_VSX && TARGET_HARD_FLOAT"
5375 {
5376 return (TARGET_P9_MINMAX
5377 ? "xs<minmax>cdp %x0,%x1,%x2"
5378 : "xs<minmax>dp %x0,%x1,%x2");
5379 }
5380 [(set_attr "type" "fp")])
5381
5382 ;; Min/max for ISA 3.1 IEEE 128-bit floating point
5383 (define_insn "s<minmax><mode>3"
5384 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
5385 (fp_minmax:IEEE128
5386 (match_operand:IEEE128 1 "altivec_register_operand" "v")
5387 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
5388 "TARGET_POWER10 && TARGET_FLOAT128_HW"
5389 "xs<minmax>cqp %0,%1,%2"
5390 [(set_attr "type" "vecfloat")
5391 (set_attr "size" "128")])
5392
5393 ;; The conditional move instructions allow us to perform max and min operations
5394 ;; even when we don't have the appropriate max/min instruction using the FSEL
5395 ;; instruction.
5396
5397 (define_insn_and_split "*s<minmax><mode>3_fpr"
5398 [(set (match_operand:SFDF 0 "gpc_reg_operand")
5399 (fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
5400 (match_operand:SFDF 2 "gpc_reg_operand")))]
5401 "!TARGET_VSX && TARGET_MINMAX"
5402 "#"
5403 "&& 1"
5404 [(const_int 0)]
5405 {
5406 rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]);
5407 DONE;
5408 })
5409
5410 (define_expand "mov<mode>cc"
5411 [(set (match_operand:GPR 0 "gpc_reg_operand")
5412 (if_then_else:GPR (match_operand 1 "comparison_operator")
5413 (match_operand:GPR 2 "gpc_reg_operand")
5414 (match_operand:GPR 3 "gpc_reg_operand")))]
5415 "TARGET_ISEL"
5416 {
5417 if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
5418 DONE;
5419 else
5420 FAIL;
5421 })
5422
5423 ;; We use the BASE_REGS for the isel input operands because, if rA is
5424 ;; 0, the value of 0 is placed in rD upon truth. Similarly for rB
5425 ;; because we may switch the operands and rB may end up being rA.
5426 ;;
5427 ;; We need 2 patterns: an unsigned and a signed pattern. We could
5428 ;; leave out the mode in operand 4 and use one pattern, but reload can
5429 ;; change the mode underneath our feet and then gets confused trying
5430 ;; to reload the value.
5431 (define_mode_iterator CCANY [CC CCUNS])
5432 (define_insn "isel_<CCANY:mode>_<GPR:mode>"
5433 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
5434 (if_then_else:GPR
5435 (match_operator 1 "scc_comparison_operator"
5436 [(match_operand:CCANY 4 "cc_reg_operand" "y,y")
5437 (const_int 0)])
5438 (match_operand:GPR 2 "reg_or_zero_operand" "O,b")
5439 (match_operand:GPR 3 "gpc_reg_operand" "r,r")))]
5440 "TARGET_ISEL"
5441 "isel %0,%2,%3,%j1"
5442 [(set_attr "type" "isel")])
5443
5444 ;; These patterns can be useful for combine; they let combine know that
5445 ;; isel can handle reversed comparisons so long as the operands are
5446 ;; registers.
5447
5448 (define_insn "*isel_reversed_<CCANY:mode>_<GPR:mode>"
5449 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
5450 (if_then_else:GPR
5451 (match_operator 1 "scc_rev_comparison_operator"
5452 [(match_operand:CCANY 4 "cc_reg_operand" "y,y")
5453 (const_int 0)])
5454 (match_operand:GPR 2 "gpc_reg_operand" "r,r")
5455 (match_operand:GPR 3 "reg_or_zero_operand" "O,b")))]
5456 "TARGET_ISEL"
5457 {
5458 PUT_CODE (operands[1], reverse_condition (GET_CODE (operands[1])));
5459 return "isel %0,%3,%2,%j1";
5460 }
5461 [(set_attr "type" "isel")])
5462
5463 ; Set Boolean Condition (Reverse)
5464 (define_insn "setbc_<CCANY:mode>_<GPR:mode>"
5465 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
5466 (match_operator:GPR 1 "scc_comparison_operator"
5467 [(match_operand:CCANY 2 "cc_reg_operand" "y")
5468 (const_int 0)]))]
5469 "TARGET_POWER10"
5470 "setbc %0,%j1"
5471 [(set_attr "type" "isel")])
5472
5473 (define_insn "*setbcr_<CCANY:mode>_<GPR:mode>"
5474 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
5475 (match_operator:GPR 1 "scc_rev_comparison_operator"
5476 [(match_operand:CCANY 2 "cc_reg_operand" "y")
5477 (const_int 0)]))]
5478 "TARGET_POWER10"
5479 "setbcr %0,%j1"
5480 [(set_attr "type" "isel")])
5481
5482 ; Set Negative Boolean Condition (Reverse)
5483 (define_insn "*setnbc_<CCANY:mode>_<GPR:mode>"
5484 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
5485 (neg:GPR (match_operator:GPR 1 "scc_comparison_operator"
5486 [(match_operand:CCANY 2 "cc_reg_operand" "y")
5487 (const_int 0)])))]
5488 "TARGET_POWER10"
5489 "setnbc %0,%j1"
5490 [(set_attr "type" "isel")])
5491
5492 (define_insn "*setnbcr_<CCANY:mode>_<GPR:mode>"
5493 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
5494 (neg:GPR (match_operator:GPR 1 "scc_rev_comparison_operator"
5495 [(match_operand:CCANY 2 "cc_reg_operand" "y")
5496 (const_int 0)])))]
5497 "TARGET_POWER10"
5498 "setnbcr %0,%j1"
5499 [(set_attr "type" "isel")])
5500
5501 ;; Floating point conditional move
5502 (define_expand "mov<mode>cc"
5503 [(set (match_operand:SFDF 0 "gpc_reg_operand")
5504 (if_then_else:SFDF (match_operand 1 "comparison_operator")
5505 (match_operand:SFDF 2 "gpc_reg_operand")
5506 (match_operand:SFDF 3 "gpc_reg_operand")))]
5507 "TARGET_HARD_FLOAT && TARGET_PPC_GFXOPT"
5508 {
5509 if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
5510 DONE;
5511 else
5512 FAIL;
5513 })
5514
5515 (define_insn "*fsel<SFDF:mode><SFDF2:mode>4"
5516 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=&<SFDF:rreg2>")
5517 (if_then_else:SFDF
5518 (ge (match_operand:SFDF2 1 "gpc_reg_operand" "<SFDF2:rreg2>")
5519 (match_operand:SFDF2 4 "zero_fp_constant" "F"))
5520 (match_operand:SFDF 2 "gpc_reg_operand" "<SFDF:rreg2>")
5521 (match_operand:SFDF 3 "gpc_reg_operand" "<SFDF:rreg2>")))]
5522 "TARGET_HARD_FLOAT && TARGET_PPC_GFXOPT"
5523 "fsel %0,%1,%2,%3"
5524 [(set_attr "type" "fp")])
5525
5526 (define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_p9"
5527 [(set (match_operand:SFDF 0 "vsx_register_operand" "=&wa,wa")
5528 (if_then_else:SFDF
5529 (match_operator:CCFP 1 "fpmask_comparison_operator"
5530 [(match_operand:SFDF2 2 "vsx_register_operand" "wa,wa")
5531 (match_operand:SFDF2 3 "vsx_register_operand" "wa,wa")])
5532 (match_operand:SFDF 4 "vsx_register_operand" "wa,wa")
5533 (match_operand:SFDF 5 "vsx_register_operand" "wa,wa")))
5534 (clobber (match_scratch:V2DI 6 "=0,&wa"))]
5535 "TARGET_P9_MINMAX"
5536 "#"
5537 "&& 1"
5538 [(set (match_dup 6)
5539 (if_then_else:V2DI (match_dup 1)
5540 (match_dup 7)
5541 (match_dup 8)))
5542 (set (match_dup 0)
5543 (if_then_else:SFDF (ne (match_dup 6)
5544 (match_dup 8))
5545 (match_dup 4)
5546 (match_dup 5)))]
5547 {
5548 if (GET_CODE (operands[6]) == SCRATCH)
5549 operands[6] = gen_reg_rtx (V2DImode);
5550
5551 operands[7] = CONSTM1_RTX (V2DImode);
5552 operands[8] = CONST0_RTX (V2DImode);
5553 }
5554 [(set_attr "length" "8")
5555 (set_attr "type" "vecperm")])
5556
5557 ;; Handle inverting the fpmask comparisons.
5558 (define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_invert_p9"
5559 [(set (match_operand:SFDF 0 "vsx_register_operand" "=&wa,wa")
5560 (if_then_else:SFDF
5561 (match_operator:CCFP 1 "invert_fpmask_comparison_operator"
5562 [(match_operand:SFDF2 2 "vsx_register_operand" "wa,wa")
5563 (match_operand:SFDF2 3 "vsx_register_operand" "wa,wa")])
5564 (match_operand:SFDF 4 "vsx_register_operand" "wa,wa")
5565 (match_operand:SFDF 5 "vsx_register_operand" "wa,wa")))
5566 (clobber (match_scratch:V2DI 6 "=0,&wa"))]
5567 "TARGET_P9_MINMAX"
5568 "#"
5569 "&& 1"
5570 [(set (match_dup 6)
5571 (if_then_else:V2DI (match_dup 9)
5572 (match_dup 7)
5573 (match_dup 8)))
5574 (set (match_dup 0)
5575 (if_then_else:SFDF (ne (match_dup 6)
5576 (match_dup 8))
5577 (match_dup 5)
5578 (match_dup 4)))]
5579 {
5580 rtx op1 = operands[1];
5581 enum rtx_code cond = reverse_condition_maybe_unordered (GET_CODE (op1));
5582
5583 if (GET_CODE (operands[6]) == SCRATCH)
5584 operands[6] = gen_reg_rtx (V2DImode);
5585
5586 operands[7] = CONSTM1_RTX (V2DImode);
5587 operands[8] = CONST0_RTX (V2DImode);
5588
5589 operands[9] = gen_rtx_fmt_ee (cond, CCFPmode, operands[2], operands[3]);
5590 }
5591 [(set_attr "length" "8")
5592 (set_attr "type" "vecperm")])
5593
5594 (define_insn "*fpmask<mode>"
5595 [(set (match_operand:V2DI 0 "vsx_register_operand" "=wa")
5596 (if_then_else:V2DI
5597 (match_operator:CCFP 1 "fpmask_comparison_operator"
5598 [(match_operand:SFDF 2 "vsx_register_operand" "wa")
5599 (match_operand:SFDF 3 "vsx_register_operand" "wa")])
5600 (match_operand:V2DI 4 "all_ones_constant" "")
5601 (match_operand:V2DI 5 "zero_constant" "")))]
5602 "TARGET_P9_MINMAX"
5603 "xscmp%V1dp %x0,%x2,%x3"
5604 [(set_attr "type" "fpcompare")])
5605
5606 (define_insn "*xxsel<mode>"
5607 [(set (match_operand:SFDF 0 "vsx_register_operand" "=wa")
5608 (if_then_else:SFDF (ne (match_operand:V2DI 1 "vsx_register_operand" "wa")
5609 (match_operand:V2DI 2 "zero_constant" ""))
5610 (match_operand:SFDF 3 "vsx_register_operand" "wa")
5611 (match_operand:SFDF 4 "vsx_register_operand" "wa")))]
5612 "TARGET_P9_MINMAX"
5613 "xxsel %x0,%x4,%x3,%x1"
5614 [(set_attr "type" "vecmove")])
5615
5616 ;; Support for ISA 3.1 IEEE 128-bit conditional move. The mode used in the
5617 ;; comparison must be the same as used in the move.
5618 (define_expand "mov<mode>cc"
5619 [(set (match_operand:IEEE128 0 "gpc_reg_operand")
5620 (if_then_else:IEEE128 (match_operand 1 "comparison_operator")
5621 (match_operand:IEEE128 2 "gpc_reg_operand")
5622 (match_operand:IEEE128 3 "gpc_reg_operand")))]
5623 "TARGET_POWER10 && TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
5624 {
5625 if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
5626 DONE;
5627 else
5628 FAIL;
5629 })
5630
5631 (define_insn_and_split "*mov<mode>cc_p10"
5632 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=&v,v")
5633 (if_then_else:IEEE128
5634 (match_operator:CCFP 1 "fpmask_comparison_operator"
5635 [(match_operand:IEEE128 2 "altivec_register_operand" "v,v")
5636 (match_operand:IEEE128 3 "altivec_register_operand" "v,v")])
5637 (match_operand:IEEE128 4 "altivec_register_operand" "v,v")
5638 (match_operand:IEEE128 5 "altivec_register_operand" "v,v")))
5639 (clobber (match_scratch:V2DI 6 "=0,&v"))]
5640 "TARGET_POWER10 && TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
5641 "#"
5642 "&& 1"
5643 [(set (match_dup 6)
5644 (if_then_else:V2DI (match_dup 1)
5645 (match_dup 7)
5646 (match_dup 8)))
5647 (set (match_dup 0)
5648 (if_then_else:IEEE128 (ne (match_dup 6)
5649 (match_dup 8))
5650 (match_dup 4)
5651 (match_dup 5)))]
5652 {
5653 if (GET_CODE (operands[6]) == SCRATCH)
5654 operands[6] = gen_reg_rtx (V2DImode);
5655
5656 operands[7] = CONSTM1_RTX (V2DImode);
5657 operands[8] = CONST0_RTX (V2DImode);
5658 }
5659 [(set_attr "length" "8")
5660 (set_attr "type" "vecperm")])
5661
5662 ;; Handle inverting the fpmask comparisons.
5663 (define_insn_and_split "*mov<mode>cc_invert_p10"
5664 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=&v,v")
5665 (if_then_else:IEEE128
5666 (match_operator:CCFP 1 "invert_fpmask_comparison_operator"
5667 [(match_operand:IEEE128 2 "altivec_register_operand" "v,v")
5668 (match_operand:IEEE128 3 "altivec_register_operand" "v,v")])
5669 (match_operand:IEEE128 4 "altivec_register_operand" "v,v")
5670 (match_operand:IEEE128 5 "altivec_register_operand" "v,v")))
5671 (clobber (match_scratch:V2DI 6 "=0,&v"))]
5672 "TARGET_POWER10 && TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
5673 "#"
5674 "&& 1"
5675 [(set (match_dup 6)
5676 (if_then_else:V2DI (match_dup 9)
5677 (match_dup 7)
5678 (match_dup 8)))
5679 (set (match_dup 0)
5680 (if_then_else:IEEE128 (ne (match_dup 6)
5681 (match_dup 8))
5682 (match_dup 5)
5683 (match_dup 4)))]
5684 {
5685 rtx op1 = operands[1];
5686 enum rtx_code cond = reverse_condition_maybe_unordered (GET_CODE (op1));
5687
5688 if (GET_CODE (operands[6]) == SCRATCH)
5689 operands[6] = gen_reg_rtx (V2DImode);
5690
5691 operands[7] = CONSTM1_RTX (V2DImode);
5692 operands[8] = CONST0_RTX (V2DImode);
5693
5694 operands[9] = gen_rtx_fmt_ee (cond, CCFPmode, operands[2], operands[3]);
5695 }
5696 [(set_attr "length" "8")
5697 (set_attr "type" "vecperm")])
5698
5699 (define_insn "*fpmask<mode>"
5700 [(set (match_operand:V2DI 0 "altivec_register_operand" "=v")
5701 (if_then_else:V2DI
5702 (match_operator:CCFP 1 "fpmask_comparison_operator"
5703 [(match_operand:IEEE128 2 "altivec_register_operand" "v")
5704 (match_operand:IEEE128 3 "altivec_register_operand" "v")])
5705 (match_operand:V2DI 4 "all_ones_constant" "")
5706 (match_operand:V2DI 5 "zero_constant" "")))]
5707 "TARGET_POWER10 && TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
5708 "xscmp%V1qp %0,%2,%3"
5709 [(set_attr "type" "fpcompare")])
5710
5711 (define_insn "*xxsel<mode>"
5712 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
5713 (if_then_else:IEEE128
5714 (ne (match_operand:V2DI 1 "altivec_register_operand" "v")
5715 (match_operand:V2DI 2 "zero_constant" ""))
5716 (match_operand:IEEE128 3 "altivec_register_operand" "v")
5717 (match_operand:IEEE128 4 "altivec_register_operand" "v")))]
5718 "TARGET_POWER10 && TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
5719 "xxsel %x0,%x4,%x3,%x1"
5720 [(set_attr "type" "vecmove")])
5721
5722 \f
5723 ;; Conversions to and from floating-point.
5724
5725 ; We don't define lfiwax/lfiwzx with the normal definition, because we
5726 ; don't want to support putting SImode in FPR registers.
5727 (define_insn "lfiwax"
5728 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa,wa,v")
5729 (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r,v")]
5730 UNSPEC_LFIWAX))]
5731 "TARGET_HARD_FLOAT && TARGET_LFIWAX"
5732 "@
5733 lfiwax %0,%y1
5734 lxsiwax %x0,%y1
5735 mtvsrwa %x0,%1
5736 vextsw2d %0,%1"
5737 [(set_attr "type" "fpload,fpload,mtvsr,vecexts")
5738 (set_attr "isa" "*,p8v,p8v,p9v")])
5739
5740 ; This split must be run before register allocation because it allocates the
5741 ; memory slot that is needed to move values to/from the FPR. We don't allocate
5742 ; it earlier to allow for the combiner to merge insns together where it might
5743 ; not be needed and also in case the insns are deleted as dead code.
5744
5745 (define_insn_and_split "floatsi<mode>2_lfiwax"
5746 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,wa")
5747 (float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r,r")))
5748 (clobber (match_scratch:DI 2 "=d,wa"))]
5749 "TARGET_HARD_FLOAT && TARGET_LFIWAX
5750 && <SI_CONVERT_FP> && can_create_pseudo_p ()"
5751 "#"
5752 "&& 1"
5753 [(pc)]
5754 {
5755 rtx dest = operands[0];
5756 rtx src = operands[1];
5757 rtx tmp;
5758
5759 if (!MEM_P (src) && TARGET_POWERPC64 && TARGET_DIRECT_MOVE)
5760 tmp = convert_to_mode (DImode, src, false);
5761 else
5762 {
5763 tmp = operands[2];
5764 if (GET_CODE (tmp) == SCRATCH)
5765 tmp = gen_reg_rtx (DImode);
5766 if (MEM_P (src))
5767 {
5768 src = rs6000_force_indexed_or_indirect_mem (src);
5769 emit_insn (gen_lfiwax (tmp, src));
5770 }
5771 else
5772 {
5773 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5774 emit_move_insn (stack, src);
5775 emit_insn (gen_lfiwax (tmp, stack));
5776 }
5777 }
5778 emit_insn (gen_floatdi<mode>2 (dest, tmp));
5779 DONE;
5780 }
5781 [(set_attr "length" "12")
5782 (set_attr "type" "fpload")])
5783
5784 (define_insn_and_split "floatsi<mode>2_lfiwax_mem"
5785 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,wa")
5786 (float:SFDF
5787 (sign_extend:DI
5788 (match_operand:SI 1 "indexed_or_indirect_operand" "Z,Z"))))
5789 (clobber (match_scratch:DI 2 "=d,wa"))]
5790 "TARGET_HARD_FLOAT && TARGET_LFIWAX && <SI_CONVERT_FP>"
5791 "#"
5792 "&& 1"
5793 [(pc)]
5794 {
5795 operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
5796 if (GET_CODE (operands[2]) == SCRATCH)
5797 operands[2] = gen_reg_rtx (DImode);
5798 if (TARGET_P8_VECTOR)
5799 emit_insn (gen_extendsidi2 (operands[2], operands[1]));
5800 else
5801 emit_insn (gen_lfiwax (operands[2], operands[1]));
5802 emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
5803 DONE;
5804 }
5805 [(set_attr "length" "8")
5806 (set_attr "type" "fpload")])
5807
5808 (define_insn_and_split "floatsi<SFDF:mode>2_lfiwax_<QHI:mode>_mem_zext"
5809 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,wa")
5810 (float:SFDF
5811 (zero_extend:SI
5812 (match_operand:QHI 1 "indexed_or_indirect_operand" "Z,Z"))))
5813 (clobber (match_scratch:DI 2 "=d,wa"))]
5814 "TARGET_HARD_FLOAT && <SI_CONVERT_FP> && TARGET_P9_VECTOR
5815 && TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
5816 "#"
5817 "&& 1"
5818 [(pc)]
5819 {
5820 if (GET_CODE (operands[2]) == SCRATCH)
5821 operands[2] = gen_reg_rtx (DImode);
5822 emit_insn (gen_zero_extendhidi2 (operands[2], operands[1]));
5823 emit_insn (gen_floatdi<SFDF:mode>2 (operands[0], operands[2]));
5824 DONE;
5825 }
5826 [(set_attr "length" "8")
5827 (set_attr "type" "fpload")])
5828
5829 (define_insn "lfiwzx"
5830 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa,wa,wa")
5831 (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r,wa")]
5832 UNSPEC_LFIWZX))]
5833 "TARGET_HARD_FLOAT && TARGET_LFIWZX"
5834 "@
5835 lfiwzx %0,%y1
5836 lxsiwzx %x0,%y1
5837 mtvsrwz %x0,%1
5838 xxextractuw %x0,%x1,4"
5839 [(set_attr "type" "fpload,fpload,mtvsr,vecexts")
5840 (set_attr "isa" "*,p8v,p8v,p9v")])
5841
5842 (define_insn_and_split "floatunssi<mode>2_lfiwzx"
5843 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,wa")
5844 (unsigned_float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r,r")))
5845 (clobber (match_scratch:DI 2 "=d,wa"))]
5846 "TARGET_HARD_FLOAT && TARGET_LFIWZX && <SI_CONVERT_FP>"
5847 "#"
5848 "&& 1"
5849 [(pc)]
5850 {
5851 rtx dest = operands[0];
5852 rtx src = operands[1];
5853 rtx tmp;
5854
5855 if (!MEM_P (src) && TARGET_POWERPC64 && TARGET_DIRECT_MOVE)
5856 tmp = convert_to_mode (DImode, src, true);
5857 else
5858 {
5859 tmp = operands[2];
5860 if (GET_CODE (tmp) == SCRATCH)
5861 tmp = gen_reg_rtx (DImode);
5862 if (MEM_P (src))
5863 {
5864 src = rs6000_force_indexed_or_indirect_mem (src);
5865 emit_insn (gen_lfiwzx (tmp, src));
5866 }
5867 else
5868 {
5869 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5870 emit_move_insn (stack, src);
5871 emit_insn (gen_lfiwzx (tmp, stack));
5872 }
5873 }
5874 emit_insn (gen_floatdi<mode>2 (dest, tmp));
5875 DONE;
5876 }
5877 [(set_attr "length" "12")
5878 (set_attr "type" "fpload")])
5879
5880 (define_insn_and_split "floatunssi<mode>2_lfiwzx_mem"
5881 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,wa")
5882 (unsigned_float:SFDF
5883 (zero_extend:DI
5884 (match_operand:SI 1 "indexed_or_indirect_operand" "Z,Z"))))
5885 (clobber (match_scratch:DI 2 "=d,wa"))]
5886 "TARGET_HARD_FLOAT && TARGET_LFIWZX && <SI_CONVERT_FP>"
5887 "#"
5888 "&& 1"
5889 [(pc)]
5890 {
5891 operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
5892 if (GET_CODE (operands[2]) == SCRATCH)
5893 operands[2] = gen_reg_rtx (DImode);
5894 if (TARGET_P8_VECTOR)
5895 emit_insn (gen_zero_extendsidi2 (operands[2], operands[1]));
5896 else
5897 emit_insn (gen_lfiwzx (operands[2], operands[1]));
5898 emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
5899 DONE;
5900 }
5901 [(set_attr "length" "8")
5902 (set_attr "type" "fpload")])
5903
5904 ; For each of these conversions, there is a define_expand, a define_insn
5905 ; with a '#' template, and a define_split (with C code). The idea is
5906 ; to allow constant folding with the template of the define_insn,
5907 ; then to have the insns split later (between sched1 and final).
5908
5909 (define_expand "floatsidf2"
5910 [(parallel [(set (match_operand:DF 0 "gpc_reg_operand")
5911 (float:DF (match_operand:SI 1 "nonimmediate_operand")))
5912 (use (match_dup 2))
5913 (use (match_dup 3))
5914 (clobber (match_dup 4))
5915 (clobber (match_dup 5))
5916 (clobber (match_dup 6))])]
5917 "TARGET_HARD_FLOAT"
5918 {
5919 if (TARGET_LFIWAX && TARGET_FCFID)
5920 {
5921 emit_insn (gen_floatsidf2_lfiwax (operands[0], operands[1]));
5922 DONE;
5923 }
5924 else if (TARGET_FCFID)
5925 {
5926 rtx dreg = operands[1];
5927 if (!REG_P (dreg))
5928 dreg = force_reg (SImode, dreg);
5929 dreg = convert_to_mode (DImode, dreg, false);
5930 emit_insn (gen_floatdidf2 (operands[0], dreg));
5931 DONE;
5932 }
5933
5934 if (!REG_P (operands[1]))
5935 operands[1] = force_reg (SImode, operands[1]);
5936 operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5937 operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503601774854144\", DFmode));
5938 operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5939 operands[5] = gen_reg_rtx (DFmode);
5940 operands[6] = gen_reg_rtx (SImode);
5941 })
5942
5943 (define_insn_and_split "*floatsidf2_internal"
5944 [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5945 (float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5946 (use (match_operand:SI 2 "gpc_reg_operand" "r"))
5947 (use (match_operand:DF 3 "gpc_reg_operand" "d"))
5948 (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
5949 (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))
5950 (clobber (match_operand:SI 6 "gpc_reg_operand" "=&r"))]
5951 "!TARGET_FCFID && TARGET_HARD_FLOAT"
5952 "#"
5953 "&& 1"
5954 [(pc)]
5955 {
5956 rtx lowword, highword;
5957 gcc_assert (MEM_P (operands[4]));
5958 highword = adjust_address (operands[4], SImode, 0);
5959 lowword = adjust_address (operands[4], SImode, 4);
5960 if (! WORDS_BIG_ENDIAN)
5961 std::swap (lowword, highword);
5962
5963 emit_insn (gen_xorsi3 (operands[6], operands[1],
5964 GEN_INT (~ (HOST_WIDE_INT) 0x7fffffff)));
5965 emit_move_insn (lowword, operands[6]);
5966 emit_move_insn (highword, operands[2]);
5967 emit_move_insn (operands[5], operands[4]);
5968 emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5969 DONE;
5970 }
5971 [(set_attr "length" "24")
5972 (set_attr "type" "fp")])
5973
5974 ;; If we don't have a direct conversion to single precision, don't enable this
5975 ;; conversion for 32-bit without fast math, because we don't have the insn to
5976 ;; generate the fixup swizzle to avoid double rounding problems.
5977 (define_expand "floatunssisf2"
5978 [(set (match_operand:SF 0 "gpc_reg_operand")
5979 (unsigned_float:SF (match_operand:SI 1 "nonimmediate_operand")))]
5980 "TARGET_HARD_FLOAT
5981 && ((TARGET_FCFIDUS && TARGET_LFIWZX)
5982 || (TARGET_FCFID
5983 && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))"
5984 {
5985 if (TARGET_LFIWZX && TARGET_FCFIDUS)
5986 {
5987 emit_insn (gen_floatunssisf2_lfiwzx (operands[0], operands[1]));
5988 DONE;
5989 }
5990 else
5991 {
5992 rtx dreg = operands[1];
5993 if (!REG_P (dreg))
5994 dreg = force_reg (SImode, dreg);
5995 dreg = convert_to_mode (DImode, dreg, true);
5996 emit_insn (gen_floatdisf2 (operands[0], dreg));
5997 DONE;
5998 }
5999 })
6000
6001 (define_expand "floatunssidf2"
6002 [(parallel [(set (match_operand:DF 0 "gpc_reg_operand")
6003 (unsigned_float:DF (match_operand:SI 1 "nonimmediate_operand")))
6004 (use (match_dup 2))
6005 (use (match_dup 3))
6006 (clobber (match_dup 4))
6007 (clobber (match_dup 5))])]
6008 "TARGET_HARD_FLOAT"
6009 {
6010 if (TARGET_LFIWZX && TARGET_FCFID)
6011 {
6012 emit_insn (gen_floatunssidf2_lfiwzx (operands[0], operands[1]));
6013 DONE;
6014 }
6015 else if (TARGET_FCFID)
6016 {
6017 rtx dreg = operands[1];
6018 if (!REG_P (dreg))
6019 dreg = force_reg (SImode, dreg);
6020 dreg = convert_to_mode (DImode, dreg, true);
6021 emit_insn (gen_floatdidf2 (operands[0], dreg));
6022 DONE;
6023 }
6024
6025 if (!REG_P (operands[1]))
6026 operands[1] = force_reg (SImode, operands[1]);
6027 operands[2] = force_reg (SImode, GEN_INT (0x43300000));
6028 operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503599627370496\", DFmode));
6029 operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
6030 operands[5] = gen_reg_rtx (DFmode);
6031 })
6032
6033 (define_insn_and_split "*floatunssidf2_internal"
6034 [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
6035 (unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
6036 (use (match_operand:SI 2 "gpc_reg_operand" "r"))
6037 (use (match_operand:DF 3 "gpc_reg_operand" "d"))
6038 (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
6039 (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))]
6040 "!TARGET_FCFIDU && TARGET_HARD_FLOAT
6041 && !(TARGET_FCFID && TARGET_POWERPC64)"
6042 "#"
6043 "&& 1"
6044 [(pc)]
6045 {
6046 rtx lowword, highword;
6047 gcc_assert (MEM_P (operands[4]));
6048 highword = adjust_address (operands[4], SImode, 0);
6049 lowword = adjust_address (operands[4], SImode, 4);
6050 if (! WORDS_BIG_ENDIAN)
6051 std::swap (lowword, highword);
6052
6053 emit_move_insn (lowword, operands[1]);
6054 emit_move_insn (highword, operands[2]);
6055 emit_move_insn (operands[5], operands[4]);
6056 emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
6057 DONE;
6058 }
6059 [(set_attr "length" "20")
6060 (set_attr "type" "fp")])
6061
6062 ;; ISA 3.0 adds instructions lxsi[bh]zx to directly load QImode and HImode to
6063 ;; vector registers. These insns favor doing the sign/zero extension in
6064 ;; the vector registers, rather then loading up a GPR, doing a sign/zero
6065 ;; extension and then a direct move.
6066
6067 (define_expand "float<QHI:mode><SFDF:mode>2"
6068 [(parallel [(set (match_operand:SFDF 0 "vsx_register_operand")
6069 (float:SFDF
6070 (match_operand:QHI 1 "input_operand")))
6071 (clobber (match_scratch:DI 2))
6072 (clobber (match_scratch:DI 3))
6073 (clobber (match_scratch:<QHI:MODE> 4))])]
6074 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
6075 {
6076 if (MEM_P (operands[1]))
6077 operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
6078 })
6079
6080 (define_insn_and_split "*float<QHI:mode><SFDF:mode>2_internal"
6081 [(set (match_operand:SFDF 0 "vsx_register_operand" "=wa,wa,wa")
6082 (float:SFDF
6083 (match_operand:QHI 1 "reg_or_indexed_operand" "v,r,Z")))
6084 (clobber (match_scratch:DI 2 "=v,wa,v"))
6085 (clobber (match_scratch:DI 3 "=X,r,X"))
6086 (clobber (match_scratch:<QHI:MODE> 4 "=X,X,v"))]
6087 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
6088 "#"
6089 "&& reload_completed"
6090 [(const_int 0)]
6091 {
6092 rtx result = operands[0];
6093 rtx input = operands[1];
6094 rtx di = operands[2];
6095
6096 if (!MEM_P (input))
6097 {
6098 rtx tmp = operands[3];
6099 if (altivec_register_operand (input, <QHI:MODE>mode))
6100 emit_insn (gen_extend<QHI:mode>di2 (di, input));
6101 else if (GET_CODE (tmp) == SCRATCH)
6102 emit_insn (gen_extend<QHI:mode>di2 (di, input));
6103 else
6104 {
6105 emit_insn (gen_extend<QHI:mode>di2 (tmp, input));
6106 emit_move_insn (di, tmp);
6107 }
6108 }
6109 else
6110 {
6111 rtx tmp = operands[4];
6112 emit_move_insn (tmp, input);
6113 emit_insn (gen_extend<QHI:mode>di2 (di, tmp));
6114 }
6115
6116 emit_insn (gen_floatdi<SFDF:mode>2 (result, di));
6117 DONE;
6118 }
6119 [(set_attr "isa" "p9v,*,p9v")])
6120
6121 (define_expand "floatuns<QHI:mode><SFDF:mode>2"
6122 [(parallel [(set (match_operand:SFDF 0 "vsx_register_operand")
6123 (unsigned_float:SFDF
6124 (match_operand:QHI 1 "input_operand")))
6125 (clobber (match_scratch:DI 2))
6126 (clobber (match_scratch:DI 3))])]
6127 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
6128 {
6129 if (MEM_P (operands[1]))
6130 operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
6131 })
6132
6133 (define_insn_and_split "*floatuns<QHI:mode><SFDF:mode>2_internal"
6134 [(set (match_operand:SFDF 0 "vsx_register_operand" "=wa,wa,wa")
6135 (unsigned_float:SFDF
6136 (match_operand:QHI 1 "reg_or_indexed_operand" "v,r,Z")))
6137 (clobber (match_scratch:DI 2 "=v,wa,wa"))
6138 (clobber (match_scratch:DI 3 "=X,r,X"))]
6139 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
6140 "#"
6141 "&& reload_completed"
6142 [(const_int 0)]
6143 {
6144 rtx result = operands[0];
6145 rtx input = operands[1];
6146 rtx di = operands[2];
6147
6148 if (MEM_P (input) || altivec_register_operand (input, <QHI:MODE>mode))
6149 emit_insn (gen_zero_extend<QHI:mode>di2 (di, input));
6150 else
6151 {
6152 rtx tmp = operands[3];
6153 if (GET_CODE (tmp) == SCRATCH)
6154 emit_insn (gen_extend<QHI:mode>di2 (di, input));
6155 else
6156 {
6157 emit_insn (gen_zero_extend<QHI:mode>di2 (tmp, input));
6158 emit_move_insn (di, tmp);
6159 }
6160 }
6161
6162 emit_insn (gen_floatdi<SFDF:mode>2 (result, di));
6163 DONE;
6164 }
6165 [(set_attr "isa" "p9v,*,p9v")])
6166
6167 (define_expand "fix_trunc<mode>si2"
6168 [(set (match_operand:SI 0 "gpc_reg_operand")
6169 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand")))]
6170 "TARGET_HARD_FLOAT"
6171 {
6172 if (!(TARGET_P8_VECTOR && TARGET_DIRECT_MOVE))
6173 {
6174 rtx src = force_reg (<MODE>mode, operands[1]);
6175
6176 if (TARGET_STFIWX)
6177 emit_insn (gen_fix_trunc<mode>si2_stfiwx (operands[0], src));
6178 else
6179 {
6180 rtx tmp = gen_reg_rtx (DImode);
6181 rtx stack = rs6000_allocate_stack_temp (DImode, true, false);
6182 emit_insn (gen_fix_trunc<mode>si2_internal (operands[0], src,
6183 tmp, stack));
6184 }
6185 DONE;
6186 }
6187 })
6188
6189 ; Like the convert to float patterns, this insn must be split before
6190 ; register allocation so that it can allocate the memory slot if it
6191 ; needed
6192 (define_insn_and_split "fix_trunc<mode>si2_stfiwx"
6193 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
6194 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
6195 (clobber (match_scratch:DI 2 "=d"))]
6196 "TARGET_HARD_FLOAT && TARGET_STFIWX && can_create_pseudo_p ()
6197 && !(TARGET_P8_VECTOR && TARGET_DIRECT_MOVE)"
6198 "#"
6199 "&& 1"
6200 [(pc)]
6201 {
6202 rtx dest = operands[0];
6203 rtx src = operands[1];
6204 rtx tmp = operands[2];
6205
6206 if (GET_CODE (tmp) == SCRATCH)
6207 tmp = gen_reg_rtx (DImode);
6208
6209 emit_insn (gen_fctiwz_<mode> (tmp, src));
6210 if (MEM_P (dest) && (TARGET_MFCRF || MEM_ALIGN (dest) >= 32))
6211 {
6212 dest = rs6000_force_indexed_or_indirect_mem (dest);
6213 emit_insn (gen_stfiwx (dest, tmp));
6214 DONE;
6215 }
6216 else if (TARGET_POWERPC64 && TARGET_DIRECT_MOVE && !MEM_P (dest))
6217 {
6218 dest = gen_lowpart (DImode, dest);
6219 emit_move_insn (dest, tmp);
6220 DONE;
6221 }
6222 else
6223 {
6224 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
6225 emit_insn (gen_stfiwx (stack, tmp));
6226 emit_move_insn (dest, stack);
6227 DONE;
6228 }
6229 }
6230 [(set_attr "length" "12")
6231 (set_attr "type" "fp")])
6232
6233 (define_insn_and_split "fix_trunc<mode>si2_internal"
6234 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,?r")
6235 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d,<rreg>")))
6236 (clobber (match_operand:DI 2 "gpc_reg_operand" "=1,d"))
6237 (clobber (match_operand:DI 3 "offsettable_mem_operand" "=o,o"))]
6238 "TARGET_HARD_FLOAT
6239 && !(TARGET_P8_VECTOR && TARGET_DIRECT_MOVE)"
6240 "#"
6241 "&& 1"
6242 [(pc)]
6243 {
6244 rtx lowword;
6245 gcc_assert (MEM_P (operands[3]));
6246 lowword = adjust_address (operands[3], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
6247
6248 emit_insn (gen_fctiwz_<mode> (operands[2], operands[1]));
6249 emit_move_insn (operands[3], operands[2]);
6250 emit_move_insn (operands[0], lowword);
6251 DONE;
6252 }
6253 [(set_attr "length" "16")
6254 (set_attr "type" "fp")])
6255
6256 (define_expand "fix_trunc<mode>di2"
6257 [(set (match_operand:DI 0 "gpc_reg_operand")
6258 (fix:DI (match_operand:SFDF 1 "gpc_reg_operand")))]
6259 "TARGET_HARD_FLOAT && TARGET_FCFID"
6260 "")
6261
6262 (define_insn "*fix_trunc<mode>di2_fctidz"
6263 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa")
6264 (fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "d,wa")))]
6265 "TARGET_HARD_FLOAT && TARGET_FCFID"
6266 "@
6267 fctidz %0,%1
6268 xscvdpsxds %x0,%x1"
6269 [(set_attr "type" "fp")])
6270
6271 ;; If we have ISA 3.0, QI/HImode values can go in both VSX registers and GPR
6272 ;; registers. If we have ISA 2.07, we don't allow QI/HImode values in the
6273 ;; vector registers, so we need to do direct moves to the GPRs, but SImode
6274 ;; values can go in VSX registers. Keeping the direct move part through
6275 ;; register allocation prevents the register allocator from doing a direct move
6276 ;; of the SImode value to a GPR, and then a store/load.
6277 (define_insn_and_split "fix<uns>_trunc<SFDF:mode><QHI:mode>2"
6278 [(set (match_operand:<QHI:MODE> 0 "gpc_reg_operand" "=d,wa,r")
6279 (any_fix:QHI (match_operand:SFDF 1 "gpc_reg_operand" "d,wa,wa")))
6280 (clobber (match_scratch:SI 2 "=X,X,wa"))]
6281 "TARGET_DIRECT_MOVE"
6282 "@
6283 fctiw<u>z %0,%1
6284 xscvdp<su>xws %x0,%x1
6285 #"
6286 "&& reload_completed && int_reg_operand (operands[0], <QHI:MODE>mode)"
6287 [(set (match_dup 2)
6288 (any_fix:SI (match_dup 1)))
6289 (set (match_dup 3)
6290 (match_dup 2))]
6291 {
6292 operands[3] = gen_rtx_REG (SImode, REGNO (operands[0]));
6293 }
6294 [(set_attr "type" "fp")
6295 (set_attr "length" "4,4,8")
6296 (set_attr "isa" "p9v,p9v,*")])
6297
6298 (define_insn "*fix<uns>_trunc<SFDF:mode>si2_p8"
6299 [(set (match_operand:SI 0 "gpc_reg_operand" "=d,wa")
6300 (any_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d,wa")))]
6301 "TARGET_DIRECT_MOVE"
6302 "@
6303 fctiw<u>z %0,%1
6304 xscvdp<su>xws %x0,%x1"
6305 [(set_attr "type" "fp")])
6306
6307 ;; Keep the convert and store together through register allocation to prevent
6308 ;; the register allocator from getting clever and doing a direct move to a GPR
6309 ;; and then store for reg+offset stores.
6310 (define_insn_and_split "*fix<uns>_trunc<SFDF:mode><QHSI:mode>2_mem"
6311 [(set (match_operand:QHSI 0 "memory_operand" "=Z")
6312 (any_fix:QHSI (match_operand:SFDF 1 "gpc_reg_operand" "wa")))
6313 (clobber (match_scratch:SI 2 "=wa"))]
6314 "(<QHSI:MODE>mode == SImode && TARGET_P8_VECTOR) || TARGET_P9_VECTOR"
6315 "#"
6316 "&& reload_completed"
6317 [(set (match_dup 2)
6318 (any_fix:SI (match_dup 1)))
6319 (set (match_dup 0)
6320 (match_dup 3))]
6321 {
6322 operands[3] = (<QHSI:MODE>mode == SImode
6323 ? operands[2]
6324 : gen_rtx_REG (<QHSI:MODE>mode, REGNO (operands[2])));
6325 })
6326
6327 (define_expand "fixuns_trunc<mode>si2"
6328 [(set (match_operand:SI 0 "gpc_reg_operand")
6329 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand")))]
6330 "TARGET_HARD_FLOAT && TARGET_FCTIWUZ && TARGET_STFIWX"
6331 {
6332 if (!TARGET_P8_VECTOR)
6333 {
6334 emit_insn (gen_fixuns_trunc<mode>si2_stfiwx (operands[0], operands[1]));
6335 DONE;
6336 }
6337 })
6338
6339 (define_insn_and_split "fixuns_trunc<mode>si2_stfiwx"
6340 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
6341 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
6342 (clobber (match_scratch:DI 2 "=d"))]
6343 "TARGET_HARD_FLOAT && TARGET_FCTIWUZ
6344 && TARGET_STFIWX && can_create_pseudo_p ()
6345 && !TARGET_P8_VECTOR"
6346 "#"
6347 "&& 1"
6348 [(pc)]
6349 {
6350 rtx dest = operands[0];
6351 rtx src = operands[1];
6352 rtx tmp = operands[2];
6353
6354 if (GET_CODE (tmp) == SCRATCH)
6355 tmp = gen_reg_rtx (DImode);
6356
6357 emit_insn (gen_fctiwuz_<mode> (tmp, src));
6358 if (MEM_P (dest))
6359 {
6360 dest = rs6000_force_indexed_or_indirect_mem (dest);
6361 emit_insn (gen_stfiwx (dest, tmp));
6362 DONE;
6363 }
6364 else if (TARGET_POWERPC64 && TARGET_DIRECT_MOVE)
6365 {
6366 dest = gen_lowpart (DImode, dest);
6367 emit_move_insn (dest, tmp);
6368 DONE;
6369 }
6370 else
6371 {
6372 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
6373 emit_insn (gen_stfiwx (stack, tmp));
6374 emit_move_insn (dest, stack);
6375 DONE;
6376 }
6377 }
6378 [(set_attr "length" "12")
6379 (set_attr "type" "fp")])
6380
6381 (define_insn "fixuns_trunc<mode>di2"
6382 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa")
6383 (unsigned_fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "d,wa")))]
6384 "TARGET_HARD_FLOAT && TARGET_FCTIDUZ"
6385 "@
6386 fctiduz %0,%1
6387 xscvdpuxds %x0,%x1"
6388 [(set_attr "type" "fp")])
6389
6390 (define_insn "rs6000_mtfsb0"
6391 [(unspec_volatile [(match_operand:SI 0 "u5bit_cint_operand" "n")]
6392 UNSPECV_MTFSB0)]
6393 "TARGET_HARD_FLOAT"
6394 "mtfsb0 %0"
6395 [(set_attr "type" "fp")])
6396
6397 (define_insn "rs6000_mtfsb1"
6398 [(unspec_volatile [(match_operand:SI 0 "u5bit_cint_operand" "n")]
6399 UNSPECV_MTFSB1)]
6400 "TARGET_HARD_FLOAT"
6401 "mtfsb1 %0"
6402 [(set_attr "type" "fp")])
6403
6404 (define_insn "rs6000_mffscrn"
6405 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
6406 (unspec_volatile:DF [(match_operand:DF 1 "gpc_reg_operand" "d")]
6407 UNSPECV_MFFSCRN))]
6408 "TARGET_P9_MISC"
6409 "mffscrn %0,%1"
6410 [(set_attr "type" "fp")])
6411
6412 (define_insn "rs6000_mffscrni"
6413 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
6414 (unspec_volatile:DF [(match_operand:SI 1 "const_0_to_3_operand" "n")]
6415 UNSPECV_MFFSCRN))]
6416 "TARGET_P9_MISC"
6417 "mffscrni %0,%1"
6418 [(set_attr "type" "fp")])
6419
6420 (define_insn "rs6000_mffscdrn"
6421 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
6422 (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFSCDRN))
6423 (use (match_operand:DF 1 "gpc_reg_operand" "d"))]
6424 "TARGET_P9_MISC"
6425 "mffscdrn %0,%1"
6426 [(set_attr "type" "fp")])
6427
6428 (define_expand "rs6000_set_fpscr_rn"
6429 [(match_operand:SI 0 "reg_or_cint_operand")]
6430 "TARGET_HARD_FLOAT"
6431 {
6432 rtx tmp_df = gen_reg_rtx (DFmode);
6433
6434 /* The floating point rounding control bits are FPSCR[62:63]. Put the
6435 new rounding mode bits from operands[0][62:63] into FPSCR[62:63]. */
6436 if (TARGET_P9_MISC)
6437 {
6438 if (const_0_to_3_operand (operands[0], VOIDmode))
6439 emit_insn (gen_rs6000_mffscrni (tmp_df, operands[0]));
6440 else
6441 {
6442 rtx op0 = convert_to_mode (DImode, operands[0], false);
6443 rtx src_df = simplify_gen_subreg (DFmode, op0, DImode, 0);
6444 emit_insn (gen_rs6000_mffscrn (tmp_df, src_df));
6445 }
6446 DONE;
6447 }
6448
6449 if (CONST_INT_P (operands[0]))
6450 {
6451 if ((INTVAL (operands[0]) & 0x1) == 0x1)
6452 emit_insn (gen_rs6000_mtfsb1 (GEN_INT (31)));
6453 else
6454 emit_insn (gen_rs6000_mtfsb0 (GEN_INT (31)));
6455
6456 if ((INTVAL (operands[0]) & 0x2) == 0x2)
6457 emit_insn (gen_rs6000_mtfsb1 (GEN_INT (30)));
6458 else
6459 emit_insn (gen_rs6000_mtfsb0 (GEN_INT (30)));
6460 }
6461 else
6462 {
6463 rtx tmp_rn = gen_reg_rtx (DImode);
6464 rtx tmp_di = gen_reg_rtx (DImode);
6465
6466 /* Extract new RN mode from operand. */
6467 rtx op0 = convert_to_mode (DImode, operands[0], false);
6468 emit_insn (gen_anddi3 (tmp_rn, op0, GEN_INT (3)));
6469
6470 /* Insert new RN mode into FSCPR. */
6471 emit_insn (gen_rs6000_mffs (tmp_df));
6472 tmp_di = simplify_gen_subreg (DImode, tmp_df, DFmode, 0);
6473 emit_insn (gen_anddi3 (tmp_di, tmp_di, GEN_INT (-4)));
6474 emit_insn (gen_iordi3 (tmp_di, tmp_di, tmp_rn));
6475
6476 /* Need to write to field k=15. The fields are [0:15]. Hence with
6477 L=0, W=0, FLM_i must be equal to 8, 16 = i + 8*(1-W). FLM is an
6478 8-bit field[0:7]. Need to set the bit that corresponds to the
6479 value of i that you want [0:7]. */
6480 tmp_df = simplify_gen_subreg (DFmode, tmp_di, DImode, 0);
6481 emit_insn (gen_rs6000_mtfsf (GEN_INT (0x01), tmp_df));
6482 }
6483 DONE;
6484 })
6485
6486 (define_expand "rs6000_set_fpscr_drn"
6487 [(match_operand:DI 0 "gpc_reg_operand")]
6488 "TARGET_HARD_FLOAT"
6489 {
6490 rtx tmp_df = gen_reg_rtx (DFmode);
6491
6492 /* The decimal floating point rounding control bits are FPSCR[29:31]. Put the
6493 new rounding mode bits from operands[0][61:63] into FPSCR[29:31]. */
6494 if (TARGET_P9_MISC)
6495 {
6496 rtx src_df = gen_reg_rtx (DFmode);
6497
6498 emit_insn (gen_ashldi3 (operands[0], operands[0], GEN_INT (32)));
6499 src_df = simplify_gen_subreg (DFmode, operands[0], DImode, 0);
6500 emit_insn (gen_rs6000_mffscdrn (tmp_df, src_df));
6501 }
6502 else
6503 {
6504 rtx tmp_rn = gen_reg_rtx (DImode);
6505 rtx tmp_di = gen_reg_rtx (DImode);
6506
6507 /* Extract new DRN mode from operand. */
6508 emit_insn (gen_anddi3 (tmp_rn, operands[0], GEN_INT (0x7)));
6509 emit_insn (gen_ashldi3 (tmp_rn, tmp_rn, GEN_INT (32)));
6510
6511 /* Insert new RN mode into FSCPR. */
6512 emit_insn (gen_rs6000_mffs (tmp_df));
6513 tmp_di = simplify_gen_subreg (DImode, tmp_df, DFmode, 0);
6514 emit_insn (gen_anddi3 (tmp_di, tmp_di, GEN_INT (0xFFFFFFF8FFFFFFFFULL)));
6515 emit_insn (gen_iordi3 (tmp_di, tmp_di, tmp_rn));
6516
6517 /* Need to write to field 7. The fields are [0:15]. The equation to
6518 select the field is i + 8*(1-W). Hence with L=0 and W=1, need to set
6519 i to 0x1 to get field 7 where i selects the field. */
6520 tmp_df = simplify_gen_subreg (DFmode, tmp_di, DImode, 0);
6521 emit_insn (gen_rs6000_mtfsf_hi (GEN_INT (0x01), tmp_df));
6522 }
6523 DONE;
6524 })
6525
6526 ;; Here, we use (set (reg) (unspec:DI [(fix:SI ...)] UNSPEC_FCTIWZ))
6527 ;; rather than (set (subreg:SI (reg)) (fix:SI ...))
6528 ;; because the first makes it clear that operand 0 is not live
6529 ;; before the instruction.
6530 (define_insn "fctiwz_<mode>"
6531 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa")
6532 (unspec:DI [(fix:SI
6533 (match_operand:SFDF 1 "gpc_reg_operand" "d,wa"))]
6534 UNSPEC_FCTIWZ))]
6535 "TARGET_HARD_FLOAT"
6536 "@
6537 fctiwz %0,%1
6538 xscvdpsxws %x0,%x1"
6539 [(set_attr "type" "fp")])
6540
6541 (define_insn "fctiwuz_<mode>"
6542 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa")
6543 (unspec:DI [(unsigned_fix:SI
6544 (match_operand:SFDF 1 "gpc_reg_operand" "d,wa"))]
6545 UNSPEC_FCTIWUZ))]
6546 "TARGET_HARD_FLOAT && TARGET_FCTIWUZ"
6547 "@
6548 fctiwuz %0,%1
6549 xscvdpuxws %x0,%x1"
6550 [(set_attr "type" "fp")])
6551
6552 ;; Only optimize (float (fix x)) -> frz if we are in fast-math mode, since
6553 ;; since the friz instruction does not truncate the value if the floating
6554 ;; point value is < LONG_MIN or > LONG_MAX.
6555 (define_insn "*friz"
6556 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa")
6557 (float:DF (fix:DI (match_operand:DF 1 "gpc_reg_operand" "d,wa"))))]
6558 "TARGET_HARD_FLOAT && TARGET_FPRND
6559 && flag_unsafe_math_optimizations && !flag_trapping_math && TARGET_FRIZ"
6560 "@
6561 friz %0,%1
6562 xsrdpiz %x0,%x1"
6563 [(set_attr "type" "fp")])
6564
6565 ;; Opitmize converting SF/DFmode to signed SImode and back to SF/DFmode. This
6566 ;; optimization prevents on ISA 2.06 systems and earlier having to store the
6567 ;; value from the FPR/vector unit to the stack, load the value into a GPR, sign
6568 ;; extend it, store it back on the stack from the GPR, load it back into the
6569 ;; FP/vector unit to do the rounding. If we have direct move (ISA 2.07),
6570 ;; disable using store and load to sign/zero extend the value.
6571 (define_insn_and_split "*round32<mode>2_fprs"
6572 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
6573 (float:SFDF
6574 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
6575 (clobber (match_scratch:DI 2 "=d"))
6576 (clobber (match_scratch:DI 3 "=d"))]
6577 "TARGET_HARD_FLOAT
6578 && <SI_CONVERT_FP> && TARGET_LFIWAX && TARGET_STFIWX && TARGET_FCFID
6579 && !TARGET_DIRECT_MOVE && can_create_pseudo_p ()"
6580 "#"
6581 "&& 1"
6582 [(pc)]
6583 {
6584 rtx dest = operands[0];
6585 rtx src = operands[1];
6586 rtx tmp1 = operands[2];
6587 rtx tmp2 = operands[3];
6588 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
6589
6590 if (GET_CODE (tmp1) == SCRATCH)
6591 tmp1 = gen_reg_rtx (DImode);
6592 if (GET_CODE (tmp2) == SCRATCH)
6593 tmp2 = gen_reg_rtx (DImode);
6594
6595 emit_insn (gen_fctiwz_<mode> (tmp1, src));
6596 emit_insn (gen_stfiwx (stack, tmp1));
6597 emit_insn (gen_lfiwax (tmp2, stack));
6598 emit_insn (gen_floatdi<mode>2 (dest, tmp2));
6599 DONE;
6600 }
6601 [(set_attr "type" "fpload")
6602 (set_attr "length" "16")])
6603
6604 (define_insn_and_split "*roundu32<mode>2_fprs"
6605 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
6606 (unsigned_float:SFDF
6607 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
6608 (clobber (match_scratch:DI 2 "=d"))
6609 (clobber (match_scratch:DI 3 "=d"))]
6610 "TARGET_HARD_FLOAT
6611 && TARGET_LFIWZX && TARGET_STFIWX && TARGET_FCFIDU && !TARGET_DIRECT_MOVE
6612 && can_create_pseudo_p ()"
6613 "#"
6614 "&& 1"
6615 [(pc)]
6616 {
6617 rtx dest = operands[0];
6618 rtx src = operands[1];
6619 rtx tmp1 = operands[2];
6620 rtx tmp2 = operands[3];
6621 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
6622
6623 if (GET_CODE (tmp1) == SCRATCH)
6624 tmp1 = gen_reg_rtx (DImode);
6625 if (GET_CODE (tmp2) == SCRATCH)
6626 tmp2 = gen_reg_rtx (DImode);
6627
6628 emit_insn (gen_fctiwuz_<mode> (tmp1, src));
6629 emit_insn (gen_stfiwx (stack, tmp1));
6630 emit_insn (gen_lfiwzx (tmp2, stack));
6631 emit_insn (gen_floatdi<mode>2 (dest, tmp2));
6632 DONE;
6633 }
6634 [(set_attr "type" "fpload")
6635 (set_attr "length" "16")])
6636
6637 ;; No VSX equivalent to fctid
6638 (define_insn "lrint<mode>di2"
6639 [(set (match_operand:DI 0 "gpc_reg_operand" "=d")
6640 (unspec:DI [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
6641 UNSPEC_FCTID))]
6642 "TARGET_HARD_FLOAT && TARGET_FPRND"
6643 "fctid %0,%1"
6644 [(set_attr "type" "fp")])
6645
6646 (define_insn "btrunc<mode>2"
6647 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,wa")
6648 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "d,wa")]
6649 UNSPEC_FRIZ))]
6650 "TARGET_HARD_FLOAT && TARGET_FPRND"
6651 "@
6652 friz %0,%1
6653 xsrdpiz %x0,%x1"
6654 [(set_attr "type" "fp")])
6655
6656 (define_insn "ceil<mode>2"
6657 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,wa")
6658 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "d,wa")]
6659 UNSPEC_FRIP))]
6660 "TARGET_HARD_FLOAT && TARGET_FPRND"
6661 "@
6662 frip %0,%1
6663 xsrdpip %x0,%x1"
6664 [(set_attr "type" "fp")])
6665
6666 (define_insn "floor<mode>2"
6667 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,wa")
6668 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "d,wa")]
6669 UNSPEC_FRIM))]
6670 "TARGET_HARD_FLOAT && TARGET_FPRND"
6671 "@
6672 frim %0,%1
6673 xsrdpim %x0,%x1"
6674 [(set_attr "type" "fp")])
6675
6676 ;; No VSX equivalent to frin
6677 (define_insn "round<mode>2"
6678 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<rreg2>")
6679 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
6680 UNSPEC_FRIN))]
6681 "TARGET_HARD_FLOAT && TARGET_FPRND"
6682 "frin %0,%1"
6683 [(set_attr "type" "fp")])
6684
6685 (define_insn "*xsrdpi<mode>2"
6686 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=wa")
6687 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "wa")]
6688 UNSPEC_XSRDPI))]
6689 "TARGET_HARD_FLOAT && TARGET_VSX"
6690 "xsrdpi %x0,%x1"
6691 [(set_attr "type" "fp")])
6692
6693 (define_expand "lround<mode>di2"
6694 [(set (match_dup 2)
6695 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand")]
6696 UNSPEC_XSRDPI))
6697 (set (match_operand:DI 0 "gpc_reg_operand")
6698 (unspec:DI [(match_dup 2)]
6699 UNSPEC_FCTID))]
6700 "TARGET_HARD_FLOAT && TARGET_VSX && TARGET_FPRND"
6701 {
6702 operands[2] = gen_reg_rtx (<MODE>mode);
6703 })
6704
6705 ; An UNSPEC is used so we don't have to support SImode in FP registers.
6706 (define_insn "stfiwx"
6707 [(set (match_operand:SI 0 "memory_operand" "=Z,Z")
6708 (unspec:SI [(match_operand:DI 1 "gpc_reg_operand" "d,wa")]
6709 UNSPEC_STFIWX))]
6710 "TARGET_PPC_GFXOPT"
6711 "@
6712 stfiwx %1,%y0
6713 stxsiwx %x1,%y0"
6714 [(set_attr "type" "fpstore")
6715 (set_attr "isa" "*,p8v")])
6716
6717 ;; If we don't have a direct conversion to single precision, don't enable this
6718 ;; conversion for 32-bit without fast math, because we don't have the insn to
6719 ;; generate the fixup swizzle to avoid double rounding problems.
6720 (define_expand "floatsisf2"
6721 [(set (match_operand:SF 0 "gpc_reg_operand")
6722 (float:SF (match_operand:SI 1 "nonimmediate_operand")))]
6723 "TARGET_HARD_FLOAT
6724 && ((TARGET_FCFIDS && TARGET_LFIWAX)
6725 || (TARGET_FCFID
6726 && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))"
6727 {
6728 if (TARGET_FCFIDS && TARGET_LFIWAX)
6729 {
6730 emit_insn (gen_floatsisf2_lfiwax (operands[0], operands[1]));
6731 DONE;
6732 }
6733 else if (TARGET_FCFID && TARGET_LFIWAX)
6734 {
6735 rtx dfreg = gen_reg_rtx (DFmode);
6736 emit_insn (gen_floatsidf2_lfiwax (dfreg, operands[1]));
6737 emit_insn (gen_truncdfsf2 (operands[0], dfreg));
6738 DONE;
6739 }
6740 else
6741 {
6742 rtx dreg = operands[1];
6743 if (!REG_P (dreg))
6744 dreg = force_reg (SImode, dreg);
6745 dreg = convert_to_mode (DImode, dreg, false);
6746 emit_insn (gen_floatdisf2 (operands[0], dreg));
6747 DONE;
6748 }
6749 })
6750
6751 (define_insn "floatdidf2"
6752 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa")
6753 (float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wa")))]
6754 "TARGET_FCFID && TARGET_HARD_FLOAT"
6755 "@
6756 fcfid %0,%1
6757 xscvsxddp %x0,%x1"
6758 [(set_attr "type" "fp")])
6759
6760 (define_insn "floatti<mode>2"
6761 [(set (match_operand:IEEE128 0 "vsx_register_operand" "=v")
6762 (float:IEEE128 (match_operand:TI 1 "vsx_register_operand" "v")))]
6763 "TARGET_POWER10"
6764 {
6765 return "xscvsqqp %0,%1";
6766 }
6767 [(set_attr "type" "fp")])
6768
6769 (define_insn "floatunsti<mode>2"
6770 [(set (match_operand:IEEE128 0 "vsx_register_operand" "=v")
6771 (unsigned_float:IEEE128 (match_operand:TI 1 "vsx_register_operand" "v")))]
6772 "TARGET_POWER10"
6773 {
6774 return "xscvuqqp %0,%1";
6775 }
6776 [(set_attr "type" "fp")])
6777
6778 (define_insn "fix_trunc<mode>ti2"
6779 [(set (match_operand:TI 0 "vsx_register_operand" "=v")
6780 (fix:TI (match_operand:IEEE128 1 "vsx_register_operand" "v")))]
6781 "TARGET_POWER10"
6782 {
6783 return "xscvqpsqz %0,%1";
6784 }
6785 [(set_attr "type" "fp")])
6786
6787 (define_insn "fixuns_trunc<mode>ti2"
6788 [(set (match_operand:TI 0 "vsx_register_operand" "=v")
6789 (unsigned_fix:TI (match_operand:IEEE128 1 "vsx_register_operand" "v")))]
6790 "TARGET_POWER10"
6791 {
6792 return "xscvqpuqz %0,%1";
6793 }
6794 [(set_attr "type" "fp")])
6795
6796 ; Allow the combiner to merge source memory operands to the conversion so that
6797 ; the optimizer/register allocator doesn't try to load the value too early in a
6798 ; GPR and then use store/load to move it to a FPR and suffer from a store-load
6799 ; hit. We will split after reload to avoid the trip through the GPRs
6800
6801 (define_insn_and_split "*floatdidf2_mem"
6802 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa")
6803 (float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
6804 (clobber (match_scratch:DI 2 "=d,wa"))]
6805 "TARGET_HARD_FLOAT && TARGET_FCFID"
6806 "#"
6807 "&& reload_completed"
6808 [(set (match_dup 2) (match_dup 1))
6809 (set (match_dup 0) (float:DF (match_dup 2)))]
6810 ""
6811 [(set_attr "length" "8")
6812 (set_attr "type" "fpload")])
6813
6814 (define_expand "floatunsdidf2"
6815 [(set (match_operand:DF 0 "gpc_reg_operand")
6816 (unsigned_float:DF
6817 (match_operand:DI 1 "gpc_reg_operand")))]
6818 "TARGET_HARD_FLOAT && TARGET_FCFIDU"
6819 "")
6820
6821 (define_insn "*floatunsdidf2_fcfidu"
6822 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa")
6823 (unsigned_float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wa")))]
6824 "TARGET_HARD_FLOAT && TARGET_FCFIDU"
6825 "@
6826 fcfidu %0,%1
6827 xscvuxddp %x0,%x1"
6828 [(set_attr "type" "fp")])
6829
6830 (define_insn_and_split "*floatunsdidf2_mem"
6831 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa")
6832 (unsigned_float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
6833 (clobber (match_scratch:DI 2 "=d,wa"))]
6834 "TARGET_HARD_FLOAT && (TARGET_FCFIDU || VECTOR_UNIT_VSX_P (DFmode))"
6835 "#"
6836 "&& reload_completed"
6837 [(set (match_dup 2) (match_dup 1))
6838 (set (match_dup 0) (unsigned_float:DF (match_dup 2)))]
6839 ""
6840 [(set_attr "length" "8")
6841 (set_attr "type" "fpload")])
6842
6843 (define_expand "floatdisf2"
6844 [(set (match_operand:SF 0 "gpc_reg_operand")
6845 (float:SF (match_operand:DI 1 "gpc_reg_operand")))]
6846 "TARGET_FCFID && TARGET_HARD_FLOAT
6847 && (TARGET_FCFIDS || TARGET_POWERPC64 || flag_unsafe_math_optimizations)"
6848 {
6849 if (!TARGET_FCFIDS)
6850 {
6851 rtx val = operands[1];
6852 if (!flag_unsafe_math_optimizations)
6853 {
6854 rtx label = gen_label_rtx ();
6855 val = gen_reg_rtx (DImode);
6856 emit_insn (gen_floatdisf2_internal2 (val, operands[1], label));
6857 emit_label (label);
6858 }
6859 emit_insn (gen_floatdisf2_internal1 (operands[0], val));
6860 DONE;
6861 }
6862 })
6863
6864 (define_insn "floatdisf2_fcfids"
6865 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wa")
6866 (float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wa")))]
6867 "TARGET_HARD_FLOAT && TARGET_FCFIDS"
6868 "@
6869 fcfids %0,%1
6870 xscvsxdsp %x0,%x1"
6871 [(set_attr "type" "fp")
6872 (set_attr "isa" "*,p8v")])
6873
6874 (define_insn_and_split "*floatdisf2_mem"
6875 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wa,wa")
6876 (float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
6877 (clobber (match_scratch:DI 2 "=d,d,wa"))]
6878 "TARGET_HARD_FLOAT && TARGET_FCFIDS"
6879 "#"
6880 "&& reload_completed"
6881 [(pc)]
6882 {
6883 emit_move_insn (operands[2], operands[1]);
6884 emit_insn (gen_floatdisf2_fcfids (operands[0], operands[2]));
6885 DONE;
6886 }
6887 [(set_attr "length" "8")
6888 (set_attr "isa" "*,p8v,p8v")])
6889
6890 ;; This is not IEEE compliant if rounding mode is "round to nearest".
6891 ;; If the DI->DF conversion is inexact, then it's possible to suffer
6892 ;; from double rounding.
6893 ;; Instead of creating a new cpu type for two FP operations, just use fp
6894 (define_insn_and_split "floatdisf2_internal1"
6895 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
6896 (float:SF (match_operand:DI 1 "gpc_reg_operand" "d")))
6897 (clobber (match_scratch:DF 2 "=d"))]
6898 "TARGET_FCFID && TARGET_HARD_FLOAT && !TARGET_FCFIDS"
6899 "#"
6900 "&& reload_completed"
6901 [(set (match_dup 2)
6902 (float:DF (match_dup 1)))
6903 (set (match_dup 0)
6904 (float_truncate:SF (match_dup 2)))]
6905 ""
6906 [(set_attr "length" "8")
6907 (set_attr "type" "fp")])
6908
6909 ;; Twiddles bits to avoid double rounding.
6910 ;; Bits that might be truncated when converting to DFmode are replaced
6911 ;; by a bit that won't be lost at that stage, but is below the SFmode
6912 ;; rounding position.
6913 (define_expand "floatdisf2_internal2"
6914 [(parallel [(set (match_dup 3) (ashiftrt:DI (match_operand:DI 1 "")
6915 (const_int 53)))
6916 (clobber (reg:DI CA_REGNO))])
6917 (set (match_operand:DI 0 "") (and:DI (match_dup 1)
6918 (const_int 2047)))
6919 (set (match_dup 3) (plus:DI (match_dup 3)
6920 (const_int 1)))
6921 (set (match_dup 0) (plus:DI (match_dup 0)
6922 (const_int 2047)))
6923 (set (match_dup 4) (compare:CCUNS (match_dup 3)
6924 (const_int 2)))
6925 (set (match_dup 0) (ior:DI (match_dup 0)
6926 (match_dup 1)))
6927 (set (match_dup 0) (and:DI (match_dup 0)
6928 (const_int -2048)))
6929 (set (pc) (if_then_else (geu (match_dup 4) (const_int 0))
6930 (label_ref (match_operand:DI 2 ""))
6931 (pc)))
6932 (set (match_dup 0) (match_dup 1))]
6933 "TARGET_POWERPC64 && TARGET_HARD_FLOAT && !TARGET_FCFIDS"
6934 {
6935 operands[3] = gen_reg_rtx (DImode);
6936 operands[4] = gen_reg_rtx (CCUNSmode);
6937 })
6938
6939 (define_expand "floatunsdisf2"
6940 [(set (match_operand:SF 0 "gpc_reg_operand")
6941 (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand")))]
6942 "TARGET_HARD_FLOAT && TARGET_FCFIDUS"
6943 "")
6944
6945 (define_insn "floatunsdisf2_fcfidus"
6946 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wa")
6947 (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wa")))]
6948 "TARGET_HARD_FLOAT && TARGET_FCFIDUS"
6949 "@
6950 fcfidus %0,%1
6951 xscvuxdsp %x0,%x1"
6952 [(set_attr "type" "fp")
6953 (set_attr "isa" "*,p8v")])
6954
6955 (define_insn_and_split "*floatunsdisf2_mem"
6956 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wa,wa")
6957 (unsigned_float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
6958 (clobber (match_scratch:DI 2 "=d,d,wa"))]
6959 "TARGET_HARD_FLOAT && TARGET_FCFIDUS"
6960 "#"
6961 "&& reload_completed"
6962 [(pc)]
6963 {
6964 emit_move_insn (operands[2], operands[1]);
6965 emit_insn (gen_floatunsdisf2_fcfidus (operands[0], operands[2]));
6966 DONE;
6967 }
6968 [(set_attr "type" "fpload")
6969 (set_attr "length" "8")
6970 (set_attr "isa" "*,p8v,p8v")])
6971
6972 ;; int fegetround(void)
6973 ;;
6974 ;; This expansion for the C99 function only expands for compatible
6975 ;; target libcs, because it needs to return one of FE_DOWNWARD,
6976 ;; FE_TONEAREST, FE_TOWARDZERO or FE_UPWARD with the values as defined
6977 ;; by the target libc, and since the libc is free to choose the values
6978 ;; (and they may differ from the hardware) and the expander needs to
6979 ;; know then beforehand, this expanded only expands for target libcs
6980 ;; that it can handle the values is knows.
6981 ;; Because of these restriction, this only expands on the desired
6982 ;; case and fallback to a call to libc otherwise.
6983 (define_expand "fegetroundsi"
6984 [(set (match_operand:SI 0 "gpc_reg_operand")
6985 (unspec_volatile:SI [(const_int 0)] UNSPECV_MFFSL))]
6986 "TARGET_HARD_FLOAT"
6987 {
6988 if (!OPTION_GLIBC)
6989 FAIL;
6990
6991 rtx tmp_df = gen_reg_rtx (DFmode);
6992 emit_insn (gen_rs6000_mffsl (tmp_df));
6993
6994 rtx tmp_di = simplify_gen_subreg (DImode, tmp_df, DFmode, 0);
6995 rtx tmp_di_2 = gen_reg_rtx (DImode);
6996 emit_insn (gen_anddi3 (tmp_di_2, tmp_di, GEN_INT (3)));
6997 rtx tmp_si = gen_reg_rtx (SImode);
6998 tmp_si = gen_lowpart (SImode, tmp_di_2);
6999 emit_move_insn (operands[0], tmp_si);
7000 DONE;
7001 })
7002
7003 ;; int feclearexcept(int excepts)
7004 ;;
7005 ;; This expansion for the C99 function only works when EXCEPTS is a
7006 ;; constant known at compile time and specifies any one of
7007 ;; FE_INEXACT, FE_DIVBYZERO, FE_UNDERFLOW and FE_OVERFLOW flags.
7008 ;; It doesn't handle values out of range, and always returns 0.
7009 ;; Note that FE_INVALID is unsupported because it maps to more than
7010 ;; one bit of the FPSCR register.
7011 ;; The FE_* are defined in the target libc, and since they are free to
7012 ;; choose the values and the expand needs to know them beforehand,
7013 ;; this expander only expands for target libcs that it can handle the
7014 ;; values it knows.
7015 ;; Because of these restrictions, this only expands on the desired
7016 ;; cases and fallback to a call to libc on any other case.
7017 (define_expand "feclearexceptsi"
7018 [(use (match_operand:SI 1 "const_int_operand" "n"))
7019 (set (match_operand:SI 0 "gpc_reg_operand")
7020 (const_int 0))]
7021 "TARGET_HARD_FLOAT"
7022 {
7023 if (!OPTION_GLIBC)
7024 FAIL;
7025
7026 unsigned int fe = INTVAL (operands[1]);
7027 if (fe != (fe & 0x1e000000))
7028 FAIL;
7029
7030 if (fe & 0x02000000) /* FE_INEXACT */
7031 emit_insn (gen_rs6000_mtfsb0 (gen_rtx_CONST_INT (SImode, 6)));
7032 if (fe & 0x04000000) /* FE_DIVBYZERO */
7033 emit_insn (gen_rs6000_mtfsb0 (gen_rtx_CONST_INT (SImode, 5)));
7034 if (fe & 0x08000000) /* FE_UNDERFLOW */
7035 emit_insn (gen_rs6000_mtfsb0 (gen_rtx_CONST_INT (SImode, 4)));
7036 if (fe & 0x10000000) /* FE_OVERFLOW */
7037 emit_insn (gen_rs6000_mtfsb0 (gen_rtx_CONST_INT (SImode, 3)));
7038
7039 emit_move_insn (operands[0], const0_rtx);
7040 DONE;
7041 })
7042
7043 ;; int feraiseexcept(int excepts)
7044 ;;
7045 ;; This expansion for the C99 function only works when excepts is a
7046 ;; constant known at compile time and specifies any one of
7047 ;; FE_INEXACT, FE_DIVBYZERO, FE_UNDERFLOW and FE_OVERFLOW flags.
7048 ;; It doesn't handle values out of range, and always returns 0.
7049 ;; Note that FE_INVALID is unsupported because it maps to more than
7050 ;; one bit of the FPSCR register.
7051 ;; The FE_* are defined in the target libc, and since they are free to
7052 ;; choose the values and the expand needs to know them beforehand,
7053 ;; this expander only expands for target libcs that it can handle the
7054 ;; values it knows.
7055 ;; Because of these restrictions, this only expands on the desired
7056 ;; cases and fallback to a call to libc on any other case.
7057 (define_expand "feraiseexceptsi"
7058 [(use (match_operand:SI 1 "const_int_operand" "n"))
7059 (set (match_operand:SI 0 "gpc_reg_operand")
7060 (const_int 0))]
7061 "TARGET_HARD_FLOAT"
7062 {
7063 if (!OPTION_GLIBC)
7064 FAIL;
7065
7066 unsigned int fe = INTVAL (operands[1]);
7067 if (fe != (fe & 0x1e000000))
7068 FAIL;
7069
7070 if (fe & 0x02000000) /* FE_INEXACT */
7071 emit_insn (gen_rs6000_mtfsb1 (gen_rtx_CONST_INT (SImode, 6)));
7072 if (fe & 0x04000000) /* FE_DIVBYZERO */
7073 emit_insn (gen_rs6000_mtfsb1 (gen_rtx_CONST_INT (SImode, 5)));
7074 if (fe & 0x08000000) /* FE_UNDERFLOW */
7075 emit_insn (gen_rs6000_mtfsb1 (gen_rtx_CONST_INT (SImode, 4)));
7076 if (fe & 0x10000000) /* FE_OVERFLOW */
7077 emit_insn (gen_rs6000_mtfsb1 (gen_rtx_CONST_INT (SImode, 3)));
7078
7079 emit_move_insn (operands[0], const0_rtx);
7080 DONE;
7081 })
7082 \f
7083 ;; Define the TImode operations that can be done in a small number
7084 ;; of instructions. The & constraints are to prevent the register
7085 ;; allocator from allocating registers that overlap with the inputs
7086 ;; (for example, having an input in 7,8 and an output in 6,7). We
7087 ;; also allow for the output being the same as one of the inputs.
7088
7089 (define_expand "addti3"
7090 [(set (match_operand:TI 0 "gpc_reg_operand")
7091 (plus:TI (match_operand:TI 1 "gpc_reg_operand")
7092 (match_operand:TI 2 "reg_or_short_operand")))]
7093 "TARGET_64BIT"
7094 {
7095 rtx lo0 = gen_lowpart (DImode, operands[0]);
7096 rtx lo1 = gen_lowpart (DImode, operands[1]);
7097 rtx lo2 = gen_lowpart (DImode, operands[2]);
7098 rtx hi0 = gen_highpart (DImode, operands[0]);
7099 rtx hi1 = gen_highpart (DImode, operands[1]);
7100 rtx hi2 = gen_highpart_mode (DImode, TImode, operands[2]);
7101
7102 if (!reg_or_short_operand (lo2, DImode))
7103 lo2 = force_reg (DImode, lo2);
7104 if (!adde_operand (hi2, DImode))
7105 hi2 = force_reg (DImode, hi2);
7106
7107 emit_insn (gen_adddi3_carry (lo0, lo1, lo2));
7108 emit_insn (gen_adddi3_carry_in (hi0, hi1, hi2));
7109 DONE;
7110 })
7111
7112 (define_expand "subti3"
7113 [(set (match_operand:TI 0 "gpc_reg_operand")
7114 (minus:TI (match_operand:TI 1 "reg_or_short_operand")
7115 (match_operand:TI 2 "gpc_reg_operand")))]
7116 "TARGET_64BIT"
7117 {
7118 rtx lo0 = gen_lowpart (DImode, operands[0]);
7119 rtx lo1 = gen_lowpart (DImode, operands[1]);
7120 rtx lo2 = gen_lowpart (DImode, operands[2]);
7121 rtx hi0 = gen_highpart (DImode, operands[0]);
7122 rtx hi1 = gen_highpart_mode (DImode, TImode, operands[1]);
7123 rtx hi2 = gen_highpart (DImode, operands[2]);
7124
7125 if (!reg_or_short_operand (lo1, DImode))
7126 lo1 = force_reg (DImode, lo1);
7127 if (!adde_operand (hi1, DImode))
7128 hi1 = force_reg (DImode, hi1);
7129
7130 emit_insn (gen_subfdi3_carry (lo0, lo2, lo1));
7131 emit_insn (gen_subfdi3_carry_in (hi0, hi2, hi1));
7132 DONE;
7133 })
7134 \f
7135 ;; 128-bit logical operations expanders
7136
7137 (define_expand "and<mode>3"
7138 [(set (match_operand:BOOL_128 0 "vlogical_operand")
7139 (and:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")
7140 (match_operand:BOOL_128 2 "vlogical_operand")))]
7141 ""
7142 "")
7143
7144 (define_expand "ior<mode>3"
7145 [(set (match_operand:BOOL_128 0 "vlogical_operand")
7146 (ior:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")
7147 (match_operand:BOOL_128 2 "vlogical_operand")))]
7148 ""
7149 "")
7150
7151 (define_expand "xor<mode>3"
7152 [(set (match_operand:BOOL_128 0 "vlogical_operand")
7153 (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")
7154 (match_operand:BOOL_128 2 "vlogical_operand")))]
7155 ""
7156 "")
7157
7158 (define_expand "nor<mode>3"
7159 [(set (match_operand:BOOL_128 0 "vlogical_operand")
7160 (and:BOOL_128
7161 (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand"))
7162 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))))]
7163 ""
7164 "")
7165
7166 (define_expand "andc<mode>3"
7167 [(set (match_operand:BOOL_128 0 "vlogical_operand")
7168 (and:BOOL_128
7169 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))
7170 (match_operand:BOOL_128 1 "vlogical_operand")))]
7171 ""
7172 "")
7173
7174 ;; Power8 vector logical instructions.
7175 (define_expand "eqv<mode>3"
7176 [(set (match_operand:BOOL_128 0 "vlogical_operand")
7177 (not:BOOL_128
7178 (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")
7179 (match_operand:BOOL_128 2 "vlogical_operand"))))]
7180 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
7181 "")
7182
7183 ;; Rewrite nand into canonical form
7184 (define_expand "nand<mode>3"
7185 [(set (match_operand:BOOL_128 0 "vlogical_operand")
7186 (ior:BOOL_128
7187 (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand"))
7188 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))))]
7189 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
7190 "")
7191
7192 ;; The canonical form is to have the negated element first, so we need to
7193 ;; reverse arguments.
7194 (define_expand "orc<mode>3"
7195 [(set (match_operand:BOOL_128 0 "vlogical_operand")
7196 (ior:BOOL_128
7197 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))
7198 (match_operand:BOOL_128 1 "vlogical_operand")))]
7199 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
7200 "")
7201
7202 ;; 128-bit logical operations insns and split operations
7203 (define_insn_and_split "*and<mode>3_internal"
7204 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
7205 (and:BOOL_128
7206 (match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
7207 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")))]
7208 ""
7209 {
7210 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
7211 return "xxland %x0,%x1,%x2";
7212
7213 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
7214 return "vand %0,%1,%2";
7215
7216 return "#";
7217 }
7218 "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
7219 [(const_int 0)]
7220 {
7221 rs6000_split_logical (operands, AND, false, false, false);
7222 DONE;
7223 }
7224 [(set (attr "type")
7225 (if_then_else
7226 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
7227 (const_string "veclogical")
7228 (const_string "integer")))
7229 (set (attr "length")
7230 (if_then_else
7231 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
7232 (const_string "4")
7233 (if_then_else
7234 (match_test "TARGET_POWERPC64")
7235 (const_string "8")
7236 (const_string "16"))))])
7237
7238 ;; 128-bit IOR/XOR
7239 (define_insn_and_split "*bool<mode>3_internal"
7240 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
7241 (match_operator:BOOL_128 3 "boolean_or_operator"
7242 [(match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
7243 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")]))]
7244 ""
7245 {
7246 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
7247 return "xxl%q3 %x0,%x1,%x2";
7248
7249 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
7250 return "v%q3 %0,%1,%2";
7251
7252 return "#";
7253 }
7254 "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
7255 [(const_int 0)]
7256 {
7257 rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, false);
7258 DONE;
7259 }
7260 [(set (attr "type")
7261 (if_then_else
7262 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
7263 (const_string "veclogical")
7264 (const_string "integer")))
7265 (set (attr "length")
7266 (if_then_else
7267 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
7268 (const_string "4")
7269 (if_then_else
7270 (match_test "TARGET_POWERPC64")
7271 (const_string "8")
7272 (const_string "16"))))])
7273
7274 ;; 128-bit ANDC/ORC
7275 (define_insn_and_split "*boolc<mode>3_internal1"
7276 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
7277 (match_operator:BOOL_128 3 "boolean_operator"
7278 [(not:BOOL_128
7279 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))
7280 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")]))]
7281 "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
7282 {
7283 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
7284 return "xxl%q3 %x0,%x1,%x2";
7285
7286 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
7287 return "v%q3 %0,%1,%2";
7288
7289 return "#";
7290 }
7291 "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
7292 && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
7293 [(const_int 0)]
7294 {
7295 rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
7296 DONE;
7297 }
7298 [(set (attr "type")
7299 (if_then_else
7300 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
7301 (const_string "veclogical")
7302 (const_string "integer")))
7303 (set (attr "length")
7304 (if_then_else
7305 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
7306 (const_string "4")
7307 (if_then_else
7308 (match_test "TARGET_POWERPC64")
7309 (const_string "8")
7310 (const_string "16"))))])
7311
7312 (define_insn_and_split "*boolc<mode>3_internal2"
7313 [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
7314 (match_operator:TI2 3 "boolean_operator"
7315 [(not:TI2
7316 (match_operand:TI2 2 "int_reg_operand" "r,0,r"))
7317 (match_operand:TI2 1 "int_reg_operand" "r,r,0")]))]
7318 "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
7319 "#"
7320 "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
7321 [(const_int 0)]
7322 {
7323 rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
7324 DONE;
7325 }
7326 [(set_attr "type" "integer")
7327 (set (attr "length")
7328 (if_then_else
7329 (match_test "TARGET_POWERPC64")
7330 (const_string "8")
7331 (const_string "16")))])
7332
7333 ;; 128-bit NAND/NOR
7334 (define_insn_and_split "*boolcc<mode>3_internal1"
7335 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
7336 (match_operator:BOOL_128 3 "boolean_operator"
7337 [(not:BOOL_128
7338 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>"))
7339 (not:BOOL_128
7340 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))]))]
7341 "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
7342 {
7343 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
7344 return "xxl%q3 %x0,%x1,%x2";
7345
7346 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
7347 return "v%q3 %0,%1,%2";
7348
7349 return "#";
7350 }
7351 "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
7352 && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
7353 [(const_int 0)]
7354 {
7355 rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
7356 DONE;
7357 }
7358 [(set (attr "type")
7359 (if_then_else
7360 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
7361 (const_string "veclogical")
7362 (const_string "integer")))
7363 (set (attr "length")
7364 (if_then_else
7365 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
7366 (const_string "4")
7367 (if_then_else
7368 (match_test "TARGET_POWERPC64")
7369 (const_string "8")
7370 (const_string "16"))))])
7371
7372 (define_insn_and_split "*boolcc<mode>3_internal2"
7373 [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
7374 (match_operator:TI2 3 "boolean_operator"
7375 [(not:TI2
7376 (match_operand:TI2 1 "int_reg_operand" "r,0,r"))
7377 (not:TI2
7378 (match_operand:TI2 2 "int_reg_operand" "r,r,0"))]))]
7379 "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
7380 "#"
7381 "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
7382 [(const_int 0)]
7383 {
7384 rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
7385 DONE;
7386 }
7387 [(set_attr "type" "integer")
7388 (set (attr "length")
7389 (if_then_else
7390 (match_test "TARGET_POWERPC64")
7391 (const_string "8")
7392 (const_string "16")))])
7393
7394
7395 ;; 128-bit EQV
7396 (define_insn_and_split "*eqv<mode>3_internal1"
7397 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
7398 (not:BOOL_128
7399 (xor:BOOL_128
7400 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")
7401 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))))]
7402 "TARGET_P8_VECTOR"
7403 {
7404 if (vsx_register_operand (operands[0], <MODE>mode))
7405 return "xxleqv %x0,%x1,%x2";
7406
7407 return "#";
7408 }
7409 "TARGET_P8_VECTOR && reload_completed
7410 && int_reg_operand (operands[0], <MODE>mode)"
7411 [(const_int 0)]
7412 {
7413 rs6000_split_logical (operands, XOR, true, false, false);
7414 DONE;
7415 }
7416 [(set (attr "type")
7417 (if_then_else
7418 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
7419 (const_string "veclogical")
7420 (const_string "integer")))
7421 (set (attr "length")
7422 (if_then_else
7423 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
7424 (const_string "4")
7425 (if_then_else
7426 (match_test "TARGET_POWERPC64")
7427 (const_string "8")
7428 (const_string "16"))))])
7429
7430 (define_insn_and_split "*eqv<mode>3_internal2"
7431 [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
7432 (not:TI2
7433 (xor:TI2
7434 (match_operand:TI2 1 "int_reg_operand" "r,0,r")
7435 (match_operand:TI2 2 "int_reg_operand" "r,r,0"))))]
7436 "!TARGET_P8_VECTOR"
7437 "#"
7438 "reload_completed && !TARGET_P8_VECTOR"
7439 [(const_int 0)]
7440 {
7441 rs6000_split_logical (operands, XOR, true, false, false);
7442 DONE;
7443 }
7444 [(set_attr "type" "integer")
7445 (set (attr "length")
7446 (if_then_else
7447 (match_test "TARGET_POWERPC64")
7448 (const_string "8")
7449 (const_string "16")))])
7450
7451 ;; 128-bit one's complement
7452 (define_insn_and_split "one_cmpl<mode>2"
7453 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
7454 (not:BOOL_128
7455 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_UNARY>")))]
7456 ""
7457 {
7458 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
7459 return "xxlnor %x0,%x1,%x1";
7460
7461 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
7462 return "vnor %0,%1,%1";
7463
7464 return "#";
7465 }
7466 "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
7467 [(const_int 0)]
7468 {
7469 rs6000_split_logical (operands, NOT, false, false, false);
7470 DONE;
7471 }
7472 [(set (attr "type")
7473 (if_then_else
7474 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
7475 (const_string "veclogical")
7476 (const_string "integer")))
7477 (set (attr "length")
7478 (if_then_else
7479 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
7480 (const_string "4")
7481 (if_then_else
7482 (match_test "TARGET_POWERPC64")
7483 (const_string "8")
7484 (const_string "16"))))])
7485
7486 \f
7487 ;; Now define ways of moving data around.
7488
7489 ;; Set up a register with a value from the GOT table
7490
7491 (define_expand "movsi_got"
7492 [(set (match_operand:SI 0 "gpc_reg_operand")
7493 (unspec:SI [(match_operand:SI 1 "got_operand")
7494 (match_dup 2)] UNSPEC_MOVSI_GOT))]
7495 "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
7496 {
7497 if (GET_CODE (operands[1]) == CONST)
7498 {
7499 rtx offset = const0_rtx;
7500 HOST_WIDE_INT value;
7501
7502 operands[1] = eliminate_constant_term (XEXP (operands[1], 0), &offset);
7503 value = INTVAL (offset);
7504 if (value != 0)
7505 {
7506 rtx tmp = (!can_create_pseudo_p ()
7507 ? operands[0]
7508 : gen_reg_rtx (Pmode));
7509 emit_insn (gen_movsi_got (tmp, operands[1]));
7510 emit_insn (gen_addsi3 (operands[0], tmp, offset));
7511 DONE;
7512 }
7513 }
7514
7515 operands[2] = rs6000_got_register (operands[1]);
7516 })
7517
7518 (define_insn "*movsi_got_internal"
7519 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
7520 (unspec:SI [(match_operand:SI 1 "got_no_const_operand" "")
7521 (match_operand:SI 2 "gpc_reg_operand" "b")]
7522 UNSPEC_MOVSI_GOT))]
7523 "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
7524 "lwz %0,%a1@got(%2)"
7525 [(set_attr "type" "load")])
7526
7527 ;; Used by sched, shorten_branches and final when the GOT pseudo reg
7528 ;; didn't get allocated to a hard register.
7529 (define_split
7530 [(set (match_operand:SI 0 "gpc_reg_operand")
7531 (unspec:SI [(match_operand:SI 1 "got_no_const_operand")
7532 (match_operand:SI 2 "memory_operand")]
7533 UNSPEC_MOVSI_GOT))]
7534 "DEFAULT_ABI == ABI_V4
7535 && flag_pic == 1
7536 && reload_completed"
7537 [(set (match_dup 0) (match_dup 2))
7538 (set (match_dup 0) (unspec:SI [(match_dup 1)(match_dup 0)]
7539 UNSPEC_MOVSI_GOT))]
7540 "")
7541
7542 ;; MR LA
7543 ;; LWZ LFIWZX LXSIWZX
7544 ;; STW STFIWX STXSIWX
7545 ;; LI LIS PLI #
7546 ;; XXLOR XXSPLTIB 0 XXSPLTIB -1 VSPLTISW
7547 ;; XXLXOR 0 XXLORC -1 P9 const
7548 ;; MTVSRWZ MFVSRWZ
7549 ;; MF%1 MT%0 NOP
7550
7551 (define_insn "*movsi_internal1"
7552 [(set (match_operand:SI 0 "nonimmediate_operand"
7553 "=r, r,
7554 r, d, v,
7555 m, ?Z, ?Z,
7556 r, r, r, r,
7557 wa, wa, wa, v,
7558 wa, v, v,
7559 wa, r,
7560 r, *h, *h")
7561 (match_operand:SI 1 "input_operand"
7562 "r, U,
7563 m, ?Z, ?Z,
7564 r, d, v,
7565 I, L, eI, n,
7566 wa, O, wM, wB,
7567 O, wM, wS,
7568 r, wa,
7569 *h, r, 0"))]
7570 "gpc_reg_operand (operands[0], SImode)
7571 || gpc_reg_operand (operands[1], SImode)"
7572 "@
7573 mr %0,%1
7574 la %0,%a1
7575 lwz%U1%X1 %0,%1
7576 lfiwzx %0,%y1
7577 lxsiwzx %x0,%y1
7578 stw%U0%X0 %1,%0
7579 stfiwx %1,%y0
7580 stxsiwx %x1,%y0
7581 li %0,%1
7582 lis %0,%v1
7583 li %0,%1
7584 #
7585 xxlor %x0,%x1,%x1
7586 xxspltib %x0,0
7587 xxspltib %x0,255
7588 vspltisw %0,%1
7589 xxlxor %x0,%x0,%x0
7590 xxlorc %x0,%x0,%x0
7591 #
7592 mtvsrwz %x0,%1
7593 mfvsrwz %0,%x1
7594 mf%1 %0
7595 mt%0 %1
7596 nop"
7597 [(set_attr "type"
7598 "*, *,
7599 load, fpload, fpload,
7600 store, fpstore, fpstore,
7601 *, *, *, *,
7602 veclogical, vecsimple, vecsimple, vecsimple,
7603 veclogical, veclogical, vecsimple,
7604 mtvsr, mfvsr,
7605 *, *, *")
7606 (set_attr "length"
7607 "*, *,
7608 *, *, *,
7609 *, *, *,
7610 *, *, *, 8,
7611 *, *, *, *,
7612 *, *, 8,
7613 *, *,
7614 *, *, *")
7615 (set_attr "isa"
7616 "*, *,
7617 *, p8v, p8v,
7618 *, p8v, p8v,
7619 *, *, p10, *,
7620 p8v, p9v, p9v, p8v,
7621 p9v, p8v, p9v,
7622 p8v, p8v,
7623 *, *, *")])
7624
7625 ;; Like movsi, but adjust a SF value to be used in a SI context, i.e.
7626 ;; (set (reg:SI ...) (subreg:SI (reg:SF ...) 0))
7627 ;;
7628 ;; Because SF values are actually stored as DF values within the vector
7629 ;; registers, we need to convert the value to the vector SF format when
7630 ;; we need to use the bits in a union or similar cases. We only need
7631 ;; to do this transformation when the value is a vector register. Loads,
7632 ;; stores, and transfers within GPRs are assumed to be safe.
7633 ;;
7634 ;; This is a more general case of reload_gpr_from_vsxsf. That insn must have
7635 ;; no alternatives, because the call is created as part of secondary_reload,
7636 ;; and operand #2's register class is used to allocate the temporary register.
7637 ;; This function is called before reload, and it creates the temporary as
7638 ;; needed.
7639
7640 ;; MR LWZ LFIWZX LXSIWZX STW
7641 ;; STFS STXSSP STXSSPX VSX->GPR VSX->VSX
7642 ;; MTVSRWZ
7643
7644 (define_insn_and_split "movsi_from_sf"
7645 [(set (match_operand:SI 0 "nonimmediate_operand"
7646 "=r, r, ?*d, ?*v, m,
7647 m, wY, Z, r, ?*wa,
7648 wa")
7649 (unspec:SI [(match_operand:SF 1 "input_operand"
7650 "r, m, Z, Z, r,
7651 f, v, wa, wa, wa,
7652 r")]
7653 UNSPEC_SI_FROM_SF))
7654 (clobber (match_scratch:V4SF 2
7655 "=X, X, X, X, X,
7656 X, X, X, wa, X,
7657 X"))]
7658 "TARGET_NO_SF_SUBREG
7659 && (register_operand (operands[0], SImode)
7660 || register_operand (operands[1], SFmode))"
7661 "@
7662 mr %0,%1
7663 lwz%U1%X1 %0,%1
7664 lfiwzx %0,%y1
7665 lxsiwzx %x0,%y1
7666 stw%U0%X0 %1,%0
7667 stfs%U0%X0 %1,%0
7668 stxssp %1,%0
7669 stxsspx %x1,%y0
7670 #
7671 xscvdpspn %x0,%x1
7672 mtvsrwz %x0,%1"
7673 "&& reload_completed
7674 && int_reg_operand (operands[0], SImode)
7675 && vsx_reg_sfsubreg_ok (operands[1], SFmode)"
7676 [(const_int 0)]
7677 {
7678 rtx op0 = operands[0];
7679 rtx op1 = operands[1];
7680 rtx op2 = operands[2];
7681 rtx op0_di = gen_rtx_REG (DImode, reg_or_subregno (op0));
7682 rtx op2_si = gen_rtx_REG (SImode, reg_or_subregno (op2));
7683
7684 emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
7685 emit_insn (gen_zero_extendsidi2 (op0_di, op2_si));
7686 DONE;
7687 }
7688 [(set_attr "type"
7689 "*, load, fpload, fpload, store,
7690 fpstore, fpstore, fpstore, mfvsr, fp,
7691 mtvsr")
7692 (set_attr "length"
7693 "*, *, *, *, *,
7694 *, *, *, 8, *,
7695 *")
7696 (set_attr "isa"
7697 "*, *, p8v, p8v, *,
7698 *, p9v, p8v, p8v, p8v,
7699 p8v")])
7700
7701 ;; movsi_from_sf with zero extension
7702 ;;
7703 ;; RLDICL LWZ LFIWZX LXSIWZX VSX->GPR
7704 ;; VSX->VSX MTVSRWZ
7705
7706 (define_insn_and_split "*movdi_from_sf_zero_ext"
7707 [(set (match_operand:DI 0 "gpc_reg_operand"
7708 "=r, r, ?*d, ?*v, r,
7709 ?v, wa")
7710 (zero_extend:DI
7711 (unspec:SI [(match_operand:SF 1 "input_operand"
7712 "r, m, Z, Z, wa,
7713 wa, r")]
7714 UNSPEC_SI_FROM_SF)))
7715 (clobber (match_scratch:V4SF 2
7716 "=X, X, X, X, wa,
7717 wa, X"))]
7718 "TARGET_DIRECT_MOVE_64BIT
7719 && (register_operand (operands[0], DImode)
7720 || register_operand (operands[1], SImode))"
7721 "@
7722 rldicl %0,%1,0,32
7723 lwz%U1%X1 %0,%1
7724 lfiwzx %0,%y1
7725 lxsiwzx %x0,%y1
7726 #
7727 #
7728 mtvsrwz %x0,%1"
7729 "&& reload_completed
7730 && register_operand (operands[0], DImode)
7731 && vsx_reg_sfsubreg_ok (operands[1], SFmode)"
7732 [(const_int 0)]
7733 {
7734 rtx op0 = operands[0];
7735 rtx op1 = operands[1];
7736 rtx op2 = operands[2];
7737 rtx op2_si = gen_rtx_REG (SImode, reg_or_subregno (op2));
7738
7739 emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
7740 emit_insn (gen_zero_extendsidi2 (op0, op2_si));
7741 DONE;
7742 }
7743 [(set_attr "type"
7744 "*, load, fpload, fpload, two,
7745 two, mtvsr")
7746 (set_attr "length"
7747 "*, *, *, *, 8,
7748 8, *")
7749 (set_attr "isa"
7750 "*, *, p8v, p8v, p8v,
7751 p9v, p8v")])
7752
7753 ;; Like movsi_from_sf, but combine a convert from DFmode to SFmode before
7754 ;; moving it to SImode. We cannot do a SFmode store without having to do the
7755 ;; conversion explicitly since that doesn't work in most cases if the input
7756 ;; isn't representable as SF. Use XSCVDPSP instead of XSCVDPSPN, since the
7757 ;; former handles cases where the input will not fit in a SFmode, and the
7758 ;; latter assumes the value has already been rounded.
7759 (define_insn "*movsi_from_df"
7760 [(set (match_operand:SI 0 "gpc_reg_operand" "=wa")
7761 (unspec:SI [(float_truncate:SF
7762 (match_operand:DF 1 "gpc_reg_operand" "wa"))]
7763 UNSPEC_SI_FROM_SF))]
7764 "TARGET_NO_SF_SUBREG"
7765 "xscvdpsp %x0,%x1"
7766 [(set_attr "type" "fp")])
7767
7768 ;; Split a load of a large constant into the appropriate two-insn
7769 ;; sequence.
7770
7771 (define_split
7772 [(set (match_operand:SI 0 "gpc_reg_operand")
7773 (match_operand:SI 1 "const_int_operand"))]
7774 "num_insns_constant (operands[1], SImode) > 1"
7775 [(pc)]
7776 {
7777 if (rs6000_emit_set_const (operands[0], operands[1]))
7778 DONE;
7779 else
7780 FAIL;
7781 })
7782
7783 ;; Split loading -128..127 to use XXSPLITB and VEXTSW2D
7784 (define_split
7785 [(set (match_operand:DI 0 "altivec_register_operand")
7786 (match_operand:DI 1 "xxspltib_constant_split"))]
7787 "TARGET_P9_VECTOR && reload_completed"
7788 [(const_int 0)]
7789 {
7790 rtx op0 = operands[0];
7791 rtx op1 = operands[1];
7792 int r = REGNO (op0);
7793 rtx op0_v16qi = gen_rtx_REG (V16QImode, r);
7794
7795 emit_insn (gen_xxspltib_v16qi (op0_v16qi, op1));
7796 emit_insn (gen_vsx_sign_extend_qi_si (operands[0], op0_v16qi));
7797 DONE;
7798 })
7799
7800 (define_insn "*mov<mode>_internal2"
7801 [(set (match_operand:CC 2 "cc_reg_operand" "=y,x,?y")
7802 (compare:CC (match_operand:P 1 "gpc_reg_operand" "0,r,r")
7803 (const_int 0)))
7804 (set (match_operand:P 0 "gpc_reg_operand" "=r,r,r") (match_dup 1))]
7805 ""
7806 "@
7807 cmp<wd>i %2,%0,0
7808 mr. %0,%1
7809 #"
7810 [(set_attr "type" "cmp,logical,cmp")
7811 (set_attr "dot" "yes")
7812 (set_attr "length" "4,4,8")])
7813
7814 (define_split
7815 [(set (match_operand:CC 2 "cc_reg_not_cr0_operand")
7816 (compare:CC (match_operand:P 1 "gpc_reg_operand")
7817 (const_int 0)))
7818 (set (match_operand:P 0 "gpc_reg_operand") (match_dup 1))]
7819 "reload_completed"
7820 [(set (match_dup 0) (match_dup 1))
7821 (set (match_dup 2)
7822 (compare:CC (match_dup 0)
7823 (const_int 0)))]
7824 "")
7825 \f
7826 (define_expand "mov<mode>"
7827 [(set (match_operand:INT 0 "general_operand")
7828 (match_operand:INT 1 "any_operand"))]
7829 ""
7830 {
7831 rs6000_emit_move (operands[0], operands[1], <MODE>mode);
7832 DONE;
7833 })
7834
7835 ;; MR LHZ/LBZ LXSI*ZX STH/STB STXSI*X LI
7836 ;; XXLOR load 0 load -1 VSPLTI* # MFVSRWZ
7837 ;; MTVSRWZ MF%1 MT%1 NOP
7838 (define_insn "*mov<mode>_internal"
7839 [(set (match_operand:QHI 0 "nonimmediate_operand"
7840 "=r, r, wa, m, ?Z, r,
7841 wa, wa, wa, v, ?v, r,
7842 wa, r, *c*l, *h")
7843 (match_operand:QHI 1 "input_operand"
7844 "r, m, ?Z, r, wa, i,
7845 wa, O, wM, wB, wS, wa,
7846 r, *h, r, 0"))]
7847 "gpc_reg_operand (operands[0], <MODE>mode)
7848 || gpc_reg_operand (operands[1], <MODE>mode)"
7849 "@
7850 mr %0,%1
7851 l<wd>z%U1%X1 %0,%1
7852 lxsi<wd>zx %x0,%y1
7853 st<wd>%U0%X0 %1,%0
7854 stxsi<wd>x %x1,%y0
7855 li %0,%1
7856 xxlor %x0,%x1,%x1
7857 xxspltib %x0,0
7858 xxspltib %x0,255
7859 vspltis<wd> %0,%1
7860 #
7861 mfvsrwz %0,%x1
7862 mtvsrwz %x0,%1
7863 mf%1 %0
7864 mt%0 %1
7865 nop"
7866 [(set_attr "type"
7867 "*, load, fpload, store, fpstore, *,
7868 vecsimple, vecperm, vecperm, vecperm, vecperm, mfvsr,
7869 mtvsr, mfjmpr, mtjmpr, *")
7870 (set_attr "length"
7871 "*, *, *, *, *, *,
7872 *, *, *, *, 8, *,
7873 *, *, *, *")
7874 (set_attr "isa"
7875 "*, *, p9v, *, p9v, *,
7876 p9v, p9v, p9v, p9v, p9v, p9v,
7877 p9v, *, *, *")])
7878
7879 \f
7880 ;; Here is how to move condition codes around. When we store CC data in
7881 ;; an integer register or memory, we store just the high-order 4 bits.
7882 ;; This lets us not shift in the most common case of CR0.
7883 (define_expand "movcc"
7884 [(set (match_operand:CC 0 "nonimmediate_operand")
7885 (match_operand:CC 1 "nonimmediate_operand"))]
7886 ""
7887 "")
7888
7889 (define_mode_iterator CC_any [CC CCUNS CCEQ CCFP])
7890
7891 (define_insn "*movcc_<mode>"
7892 [(set (match_operand:CC_any 0 "nonimmediate_operand"
7893 "=y,x,?y,y,r,r,r,r, r,*c*l,r,m")
7894 (match_operand:CC_any 1 "general_operand"
7895 " y,r, r,O,x,y,r,I,*h, r,m,r"))]
7896 "register_operand (operands[0], <MODE>mode)
7897 || register_operand (operands[1], <MODE>mode)"
7898 "@
7899 mcrf %0,%1
7900 mtcrf 128,%1
7901 rlwinm %1,%1,%F0,0xffffffff\;mtcrf %R0,%1\;rlwinm %1,%1,%f0,0xffffffff
7902 crxor %0,%0,%0
7903 mfcr %0%Q1
7904 mfcr %0%Q1\;rlwinm %0,%0,%f1,0xf0000000
7905 mr %0,%1
7906 li %0,%1
7907 mf%1 %0
7908 mt%0 %1
7909 lwz%U1%X1 %0,%1
7910 stw%U0%X0 %1,%0"
7911 [(set_attr_alternative "type"
7912 [(const_string "cr_logical")
7913 (const_string "mtcr")
7914 (const_string "mtcr")
7915 (const_string "cr_logical")
7916 (if_then_else (match_test "TARGET_MFCRF")
7917 (const_string "mfcrf") (const_string "mfcr"))
7918 (if_then_else (match_test "TARGET_MFCRF")
7919 (const_string "mfcrf") (const_string "mfcr"))
7920 (const_string "integer")
7921 (const_string "integer")
7922 (const_string "mfjmpr")
7923 (const_string "mtjmpr")
7924 (const_string "load")
7925 (const_string "store")])
7926 (set_attr "length" "*,*,12,*,*,8,*,*,*,*,*,*")])
7927 \f
7928 ;; For floating-point, we normally deal with the floating-point registers
7929 ;; unless -msoft-float is used. The sole exception is that parameter passing
7930 ;; can produce floating-point values in fixed-point registers. Unless the
7931 ;; value is a simple constant or already in memory, we deal with this by
7932 ;; allocating memory and copying the value explicitly via that memory location.
7933
7934 ;; Move 32-bit binary/decimal floating point
7935 (define_expand "mov<mode>"
7936 [(set (match_operand:FMOVE32 0 "nonimmediate_operand")
7937 (match_operand:FMOVE32 1 "any_operand"))]
7938 "<fmove_ok>"
7939 {
7940 rs6000_emit_move (operands[0], operands[1], <MODE>mode);
7941 DONE;
7942 })
7943
7944 (define_split
7945 [(set (match_operand:FMOVE32 0 "gpc_reg_operand")
7946 (match_operand:FMOVE32 1 "const_double_operand"))]
7947 "reload_completed
7948 && ((REG_P (operands[0]) && REGNO (operands[0]) <= 31)
7949 || (SUBREG_P (operands[0])
7950 && REG_P (SUBREG_REG (operands[0]))
7951 && REGNO (SUBREG_REG (operands[0])) <= 31))"
7952 [(set (match_dup 2) (match_dup 3))]
7953 {
7954 long l;
7955
7956 <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7957
7958 if (! TARGET_POWERPC64)
7959 operands[2] = operand_subword (operands[0], 0, 0, <MODE>mode);
7960 else
7961 operands[2] = gen_lowpart (SImode, operands[0]);
7962
7963 operands[3] = gen_int_mode (l, SImode);
7964 })
7965
7966 ;; Originally, we tried to keep movsf and movsd common, but the differences
7967 ;; addressing was making it rather difficult to hide with mode attributes. In
7968 ;; particular for SFmode, on ISA 2.07 (power8) systems, having the GPR store
7969 ;; before the VSX stores meant that the register allocator would tend to do a
7970 ;; direct move to the GPR (which involves conversion from scalar to
7971 ;; vector/memory formats) to save values in the traditional Altivec registers,
7972 ;; while SDmode had problems on power6 if the GPR store was not first due to
7973 ;; the power6 not having an integer store operation.
7974 ;;
7975 ;; LWZ LFS LXSSP LXSSPX STFS STXSSP
7976 ;; STXSSPX STW XXLXOR LI FMR XSCPSGNDP
7977 ;; MR MT<x> MF<x> NOP XXSPLTIDP
7978
7979 (define_insn "movsf_hardfloat"
7980 [(set (match_operand:SF 0 "nonimmediate_operand"
7981 "=!r, f, v, wa, m, wY,
7982 Z, m, wa, !r, f, wa,
7983 !r, *c*l, !r, *h, wa")
7984 (match_operand:SF 1 "input_operand"
7985 "m, m, wY, Z, f, v,
7986 wa, r, j, j, f, wa,
7987 r, r, *h, 0, eP"))]
7988 "(register_operand (operands[0], SFmode)
7989 || register_operand (operands[1], SFmode))
7990 && TARGET_HARD_FLOAT
7991 && (TARGET_ALLOW_SF_SUBREG
7992 || valid_sf_si_move (operands[0], operands[1], SFmode))"
7993 "@
7994 lwz%U1%X1 %0,%1
7995 lfs%U1%X1 %0,%1
7996 lxssp %0,%1
7997 lxsspx %x0,%y1
7998 stfs%U0%X0 %1,%0
7999 stxssp %1,%0
8000 stxsspx %x1,%y0
8001 stw%U0%X0 %1,%0
8002 xxlxor %x0,%x0,%x0
8003 li %0,0
8004 fmr %0,%1
8005 xscpsgndp %x0,%x1,%x1
8006 mr %0,%1
8007 mt%0 %1
8008 mf%1 %0
8009 nop
8010 #"
8011 [(set_attr "type"
8012 "load, fpload, fpload, fpload, fpstore, fpstore,
8013 fpstore, store, veclogical, integer, fpsimple, fpsimple,
8014 *, mtjmpr, mfjmpr, *, vecperm")
8015 (set_attr "isa"
8016 "*, *, p9v, p8v, *, p9v,
8017 p8v, *, *, *, *, *,
8018 *, *, *, *, p10")
8019 (set_attr "prefixed"
8020 "*, *, *, *, *, *,
8021 *, *, *, *, *, *,
8022 *, *, *, *, yes")])
8023
8024 ;; LWZ LFIWZX STW STFIWX MTVSRWZ MFVSRWZ
8025 ;; FMR MR MT%0 MF%1 NOP
8026 (define_insn "movsd_hardfloat"
8027 [(set (match_operand:SD 0 "nonimmediate_operand"
8028 "=!r, d, m, ?Z, ?d, ?r,
8029 f, !r, *c*l, !r, *h")
8030 (match_operand:SD 1 "input_operand"
8031 "m, ?Z, r, wx, r, d,
8032 f, r, r, *h, 0"))]
8033 "(register_operand (operands[0], SDmode)
8034 || register_operand (operands[1], SDmode))
8035 && TARGET_HARD_FLOAT"
8036 "@
8037 lwz%U1%X1 %0,%1
8038 lfiwzx %0,%y1
8039 stw%U0%X0 %1,%0
8040 stfiwx %1,%y0
8041 mtvsrwz %x0,%1
8042 mfvsrwz %0,%x1
8043 fmr %0,%1
8044 mr %0,%1
8045 mt%0 %1
8046 mf%1 %0
8047 nop"
8048 [(set_attr "type"
8049 "load, fpload, store, fpstore, mtvsr, mfvsr,
8050 fpsimple, *, mtjmpr, mfjmpr, *")
8051 (set_attr "isa"
8052 "*, p7, *, *, p8v, p8v,
8053 *, *, *, *, *")])
8054
8055 ;; MR MT%0 MF%0 LWZ STW LI
8056 ;; LIS G-const. F/n-const NOP
8057 (define_insn "*mov<mode>_softfloat"
8058 [(set (match_operand:FMOVE32 0 "nonimmediate_operand"
8059 "=r, *c*l, r, r, m, r,
8060 r, r, r, *h")
8061
8062 (match_operand:FMOVE32 1 "input_operand"
8063 "r, r, *h, m, r, I,
8064 L, G, Fn, 0"))]
8065
8066 "(gpc_reg_operand (operands[0], <MODE>mode)
8067 || gpc_reg_operand (operands[1], <MODE>mode))
8068 && TARGET_SOFT_FLOAT"
8069 "@
8070 mr %0,%1
8071 mt%0 %1
8072 mf%1 %0
8073 lwz%U1%X1 %0,%1
8074 stw%U0%X0 %1,%0
8075 li %0,%1
8076 lis %0,%v1
8077 #
8078 #
8079 nop"
8080 [(set_attr "type"
8081 "*, mtjmpr, mfjmpr, load, store, *,
8082 *, *, *, *")
8083
8084 (set_attr "length"
8085 "*, *, *, *, *, *,
8086 *, *, 8, *")])
8087
8088 ;; Like movsf, but adjust a SI value to be used in a SF context, i.e.
8089 ;; (set (reg:SF ...) (subreg:SF (reg:SI ...) 0))
8090 ;;
8091 ;; Because SF values are actually stored as DF values within the vector
8092 ;; registers, we need to convert the value to the vector SF format when
8093 ;; we need to use the bits in a union or similar cases. We only need
8094 ;; to do this transformation when the value is a vector register. Loads,
8095 ;; stores, and transfers within GPRs are assumed to be safe.
8096 ;;
8097 ;; This is a more general case of reload_vsx_from_gprsf. That insn must have
8098 ;; no alternatives, because the call is created as part of secondary_reload,
8099 ;; and operand #2's register class is used to allocate the temporary register.
8100 ;; This function is called before reload, and it creates the temporary as
8101 ;; needed.
8102
8103 ;; LWZ LFS LXSSP LXSSPX STW STFIWX
8104 ;; STXSIWX GPR->VSX VSX->GPR GPR->GPR
8105 (define_insn_and_split "movsf_from_si"
8106 [(set (match_operand:SF 0 "nonimmediate_operand"
8107 "=!r, f, v, wa, m, Z,
8108 Z, wa, ?r, !r")
8109 (unspec:SF [(match_operand:SI 1 "input_operand"
8110 "m, m, wY, Z, r, f,
8111 wa, r, wa, r")]
8112 UNSPEC_SF_FROM_SI))
8113 (clobber (match_scratch:DI 2
8114 "=X, X, X, X, X, X,
8115 X, r, X, X"))]
8116 "TARGET_NO_SF_SUBREG
8117 && (register_operand (operands[0], SFmode)
8118 || register_operand (operands[1], SImode))"
8119 "@
8120 lwz%U1%X1 %0,%1
8121 lfs%U1%X1 %0,%1
8122 lxssp %0,%1
8123 lxsspx %x0,%y1
8124 stw%U0%X0 %1,%0
8125 stfiwx %1,%y0
8126 stxsiwx %x1,%y0
8127 #
8128 mfvsrwz %0,%x1
8129 mr %0,%1"
8130
8131 "&& reload_completed
8132 && vsx_reg_sfsubreg_ok (operands[0], SFmode)
8133 && int_reg_operand_not_pseudo (operands[1], SImode)"
8134 [(const_int 0)]
8135 {
8136 rtx op0 = operands[0];
8137 rtx op1 = operands[1];
8138 rtx op2 = operands[2];
8139 rtx op1_di = gen_rtx_REG (DImode, REGNO (op1));
8140
8141 /* Move SF value to upper 32-bits for xscvspdpn. */
8142 emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32)));
8143 emit_insn (gen_p8_mtvsrd_sf (op0, op2));
8144 emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0));
8145 DONE;
8146 }
8147 [(set_attr "length"
8148 "*, *, *, *, *, *,
8149 *, 12, *, *")
8150 (set_attr "type"
8151 "load, fpload, fpload, fpload, store, fpstore,
8152 fpstore, vecfloat, mfvsr, *")
8153 (set_attr "isa"
8154 "*, *, p9v, p8v, *, *,
8155 p8v, p8v, p8v, *")])
8156
8157 ;; For extracting high part element from DImode register like:
8158 ;; {%1:SF=unspec[r122:DI>>0x20#0] 86;clobber scratch;}
8159 ;; split it before reload with "and mask" to avoid generating shift right
8160 ;; 32 bit then shift left 32 bit.
8161 (define_insn_and_split "movsf_from_si2"
8162 [(set (match_operand:SF 0 "gpc_reg_operand" "=wa")
8163 (unspec:SF
8164 [(subreg:SI
8165 (ashiftrt:DI
8166 (match_operand:DI 1 "input_operand" "r")
8167 (const_int 32))
8168 0)]
8169 UNSPEC_SF_FROM_SI))
8170 (clobber (match_scratch:DI 2 "=r"))]
8171 "TARGET_NO_SF_SUBREG"
8172 "#"
8173 "&& 1"
8174 [(const_int 0)]
8175 {
8176 if (GET_CODE (operands[2]) == SCRATCH)
8177 operands[2] = gen_reg_rtx (DImode);
8178
8179 rtx mask = GEN_INT (HOST_WIDE_INT_M1U << 32);
8180 emit_insn (gen_anddi3 (operands[2], operands[1], mask));
8181 emit_insn (gen_p8_mtvsrd_sf (operands[0], operands[2]));
8182 emit_insn (gen_vsx_xscvspdpn_directmove (operands[0], operands[0]));
8183 DONE;
8184 }
8185 [(set_attr "length" "12")
8186 (set_attr "type" "vecfloat")
8187 (set_attr "isa" "p8v")])
8188 \f
8189 ;; Move 64-bit binary/decimal floating point
8190 (define_expand "mov<mode>"
8191 [(set (match_operand:FMOVE64 0 "nonimmediate_operand")
8192 (match_operand:FMOVE64 1 "any_operand"))]
8193 ""
8194 {
8195 rs6000_emit_move (operands[0], operands[1], <MODE>mode);
8196 DONE;
8197 })
8198
8199 (define_split
8200 [(set (match_operand:FMOVE64 0 "gpc_reg_operand")
8201 (match_operand:FMOVE64 1 "const_int_operand"))]
8202 "! TARGET_POWERPC64 && reload_completed
8203 && ((REG_P (operands[0]) && REGNO (operands[0]) <= 31)
8204 || (SUBREG_P (operands[0])
8205 && REG_P (SUBREG_REG (operands[0]))
8206 && REGNO (SUBREG_REG (operands[0])) <= 31))"
8207 [(set (match_dup 2) (match_dup 4))
8208 (set (match_dup 3) (match_dup 1))]
8209 {
8210 int endian = (WORDS_BIG_ENDIAN == 0);
8211 HOST_WIDE_INT value = INTVAL (operands[1]);
8212
8213 operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
8214 operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
8215 operands[4] = GEN_INT (value >> 32);
8216 operands[1] = GEN_INT (sext_hwi (value, 32));
8217 })
8218
8219 (define_split
8220 [(set (match_operand:FMOVE64 0 "gpc_reg_operand")
8221 (match_operand:FMOVE64 1 "const_double_operand"))]
8222 "! TARGET_POWERPC64 && reload_completed
8223 && ((REG_P (operands[0]) && REGNO (operands[0]) <= 31)
8224 || (SUBREG_P (operands[0])
8225 && REG_P (SUBREG_REG (operands[0]))
8226 && REGNO (SUBREG_REG (operands[0])) <= 31))"
8227 [(set (match_dup 2) (match_dup 4))
8228 (set (match_dup 3) (match_dup 5))]
8229 {
8230 int endian = (WORDS_BIG_ENDIAN == 0);
8231 long l[2];
8232
8233 <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
8234
8235 operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
8236 operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
8237 operands[4] = gen_int_mode (l[endian], SImode);
8238 operands[5] = gen_int_mode (l[1 - endian], SImode);
8239 })
8240
8241 (define_split
8242 [(set (match_operand:FMOVE64 0 "gpc_reg_operand")
8243 (match_operand:FMOVE64 1 "const_double_operand"))]
8244 "TARGET_POWERPC64 && reload_completed
8245 && ((REG_P (operands[0]) && REGNO (operands[0]) <= 31)
8246 || (SUBREG_P (operands[0])
8247 && REG_P (SUBREG_REG (operands[0]))
8248 && REGNO (SUBREG_REG (operands[0])) <= 31))"
8249 [(set (match_dup 2) (match_dup 3))]
8250 {
8251 int endian = (WORDS_BIG_ENDIAN == 0);
8252 long l[2];
8253 HOST_WIDE_INT val;
8254
8255 <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
8256
8257 operands[2] = gen_lowpart (DImode, operands[0]);
8258 /* HIGHPART is lower memory address when WORDS_BIG_ENDIAN. */
8259 val = ((HOST_WIDE_INT)(unsigned long)l[endian] << 32
8260 | ((HOST_WIDE_INT)(unsigned long)l[1 - endian]));
8261
8262 operands[3] = gen_int_mode (val, DImode);
8263 })
8264
8265 ;; Don't have reload use general registers to load a constant. It is
8266 ;; less efficient than loading the constant into an FP register, since
8267 ;; it will probably be used there.
8268
8269 ;; The move constraints are ordered to prefer floating point registers before
8270 ;; general purpose registers to avoid doing a store and a load to get the value
8271 ;; into a floating point register when it is needed for a floating point
8272 ;; operation. Prefer traditional floating point registers over VSX registers,
8273 ;; since the D-form version of the memory instructions does not need a GPR for
8274 ;; reloading. ISA 3.0 (power9) adds D-form addressing for scalars to Altivec
8275 ;; registers.
8276
8277 ;; If we have FPR registers, rs6000_emit_move has moved all constants to memory,
8278 ;; except for 0.0 which can be created on VSX with an xor instruction.
8279
8280 ;; STFD LFD FMR LXSD STXSD
8281 ;; LXSD STXSD XXLOR XXLXOR GPR<-0
8282 ;; LWZ STW MR XXSPLTIDP
8283
8284
8285 (define_insn "*mov<mode>_hardfloat32"
8286 [(set (match_operand:FMOVE64 0 "nonimmediate_operand"
8287 "=m, d, d, <f64_p9>, wY,
8288 <f64_av>, Z, <f64_vsx>, <f64_vsx>, !r,
8289 Y, r, !r, wa")
8290 (match_operand:FMOVE64 1 "input_operand"
8291 "d, m, d, wY, <f64_p9>,
8292 Z, <f64_av>, <f64_vsx>, <zero_fp>, <zero_fp>,
8293 r, Y, r, eP"))]
8294 "! TARGET_POWERPC64 && TARGET_HARD_FLOAT
8295 && (gpc_reg_operand (operands[0], <MODE>mode)
8296 || gpc_reg_operand (operands[1], <MODE>mode))"
8297 "@
8298 stfd%U0%X0 %1,%0
8299 lfd%U1%X1 %0,%1
8300 fmr %0,%1
8301 lxsd %0,%1
8302 stxsd %1,%0
8303 lxsdx %x0,%y1
8304 stxsdx %x1,%y0
8305 xxlor %x0,%x1,%x1
8306 xxlxor %x0,%x0,%x0
8307 #
8308 #
8309 #
8310 #
8311 #"
8312 [(set_attr "type"
8313 "fpstore, fpload, fpsimple, fpload, fpstore,
8314 fpload, fpstore, veclogical, veclogical, two,
8315 store, load, two, vecperm")
8316 (set_attr "size" "64")
8317 (set_attr "length"
8318 "*, *, *, *, *,
8319 *, *, *, *, 8,
8320 8, 8, 8, *")
8321 (set_attr "isa"
8322 "*, *, *, p9v, p9v,
8323 p7v, p7v, *, *, *,
8324 *, *, *, p10")
8325 (set_attr "prefixed"
8326 "*, *, *, *, *,
8327 *, *, *, *, *,
8328 *, *, *, yes")])
8329
8330 ;; STW LWZ MR G-const H-const F-const
8331
8332 (define_insn "*mov<mode>_softfloat32"
8333 [(set (match_operand:FMOVE64 0 "nonimmediate_operand"
8334 "=Y, r, r, r, r, r")
8335
8336 (match_operand:FMOVE64 1 "input_operand"
8337 "r, Y, r, G, H, F"))]
8338
8339 "!TARGET_POWERPC64
8340 && (gpc_reg_operand (operands[0], <MODE>mode)
8341 || gpc_reg_operand (operands[1], <MODE>mode))"
8342 "#"
8343 [(set_attr "type"
8344 "store, load, two, *, *, *")
8345
8346 (set_attr "length"
8347 "8, 8, 8, 8, 12, 16")])
8348
8349 ; ld/std require word-aligned displacements -> 'Y' constraint.
8350 ; List Y->r and r->Y before r->r for reload.
8351
8352 ;; STFD LFD FMR LXSD STXSD
8353 ;; LXSDX STXSDX XXLOR XXLXOR LI 0
8354 ;; STD LD MR MT{CTR,LR} MF{CTR,LR}
8355 ;; NOP MFVSRD MTVSRD XXSPLTIDP
8356
8357 (define_insn "*mov<mode>_hardfloat64"
8358 [(set (match_operand:FMOVE64 0 "nonimmediate_operand"
8359 "=m, d, d, <f64_p9>, wY,
8360 <f64_av>, Z, <f64_vsx>, <f64_vsx>, !r,
8361 YZ, r, !r, *c*l, !r,
8362 *h, r, <f64_dm>, wa")
8363 (match_operand:FMOVE64 1 "input_operand"
8364 "d, m, d, wY, <f64_p9>,
8365 Z, <f64_av>, <f64_vsx>, <zero_fp>, <zero_fp>,
8366 r, YZ, r, r, *h,
8367 0, <f64_dm>, r, eP"))]
8368 "TARGET_POWERPC64 && TARGET_HARD_FLOAT
8369 && (gpc_reg_operand (operands[0], <MODE>mode)
8370 || gpc_reg_operand (operands[1], <MODE>mode))"
8371 "@
8372 stfd%U0%X0 %1,%0
8373 lfd%U1%X1 %0,%1
8374 fmr %0,%1
8375 lxsd %0,%1
8376 stxsd %1,%0
8377 lxsdx %x0,%y1
8378 stxsdx %x1,%y0
8379 xxlor %x0,%x1,%x1
8380 xxlxor %x0,%x0,%x0
8381 li %0,0
8382 std%U0%X0 %1,%0
8383 ld%U1%X1 %0,%1
8384 mr %0,%1
8385 mt%0 %1
8386 mf%1 %0
8387 nop
8388 mfvsrd %0,%x1
8389 mtvsrd %x0,%1
8390 #"
8391 [(set_attr "type"
8392 "fpstore, fpload, fpsimple, fpload, fpstore,
8393 fpload, fpstore, veclogical, veclogical, integer,
8394 store, load, *, mtjmpr, mfjmpr,
8395 *, mfvsr, mtvsr, vecperm")
8396 (set_attr "size" "64")
8397 (set_attr "isa"
8398 "*, *, *, p9v, p9v,
8399 p7v, p7v, *, *, *,
8400 *, *, *, *, *,
8401 *, p8v, p8v, p10")
8402 (set_attr "prefixed"
8403 "*, *, *, *, *,
8404 *, *, *, *, *,
8405 *, *, *, *, *,
8406 *, *, *, *")])
8407
8408 ;; STD LD MR MT<SPR> MF<SPR> G-const
8409 ;; H-const F-const Special
8410
8411 (define_insn "*mov<mode>_softfloat64"
8412 [(set (match_operand:FMOVE64 0 "nonimmediate_operand"
8413 "=Y, r, r, *c*l, r, r,
8414 r, r, *h")
8415
8416 (match_operand:FMOVE64 1 "input_operand"
8417 "r, Y, r, r, *h, G,
8418 H, F, 0"))]
8419
8420 "TARGET_POWERPC64 && TARGET_SOFT_FLOAT
8421 && (gpc_reg_operand (operands[0], <MODE>mode)
8422 || gpc_reg_operand (operands[1], <MODE>mode))"
8423 "@
8424 std%U0%X0 %1,%0
8425 ld%U1%X1 %0,%1
8426 mr %0,%1
8427 mt%0 %1
8428 mf%1 %0
8429 #
8430 #
8431 #
8432 nop"
8433 [(set_attr "type"
8434 "store, load, *, mtjmpr, mfjmpr, *,
8435 *, *, *")
8436
8437 (set_attr "length"
8438 "*, *, *, *, *, 8,
8439 12, 16, *")])
8440
8441 ;; Split the VSX prefixed instruction to support SFmode and DFmode scalar
8442 ;; constants that look like DFmode floating point values where both elements
8443 ;; are the same. The constant has to be expressible as a SFmode constant that
8444 ;; is not a SFmode denormal value.
8445 ;;
8446 ;; We don't need splitters for the 128-bit types, since the function
8447 ;; rs6000_output_move_128bit handles the generation of XXSPLTIDP.
8448 (define_insn "xxspltidp_<mode>_internal"
8449 [(set (match_operand:SFDF 0 "register_operand" "=wa")
8450 (unspec:SFDF [(match_operand:SI 1 "c32bit_cint_operand" "n")]
8451 UNSPEC_XXSPLTIDP_CONST))]
8452 "TARGET_POWER10"
8453 "xxspltidp %x0,%1"
8454 [(set_attr "type" "vecperm")
8455 (set_attr "prefixed" "yes")])
8456
8457 (define_insn "xxspltiw_<mode>_internal"
8458 [(set (match_operand:SFDF 0 "register_operand" "=wa")
8459 (unspec:SFDF [(match_operand:SI 1 "c32bit_cint_operand" "n")]
8460 UNSPEC_XXSPLTIW_CONST))]
8461 "TARGET_POWER10"
8462 "xxspltiw %x0,%1"
8463 [(set_attr "type" "vecperm")
8464 (set_attr "prefixed" "yes")])
8465
8466 (define_split
8467 [(set (match_operand:SFDF 0 "vsx_register_operand")
8468 (match_operand:SFDF 1 "vsx_prefixed_constant"))]
8469 "TARGET_POWER10"
8470 [(pc)]
8471 {
8472 rtx dest = operands[0];
8473 rtx src = operands[1];
8474 vec_const_128bit_type vsx_const;
8475
8476 if (!vec_const_128bit_to_bytes (src, <MODE>mode, &vsx_const))
8477 gcc_unreachable ();
8478
8479 unsigned imm = constant_generates_xxspltidp (&vsx_const);
8480 if (imm)
8481 {
8482 emit_insn (gen_xxspltidp_<mode>_internal (dest, GEN_INT (imm)));
8483 DONE;
8484 }
8485
8486 imm = constant_generates_xxspltiw (&vsx_const);
8487 if (imm)
8488 {
8489 emit_insn (gen_xxspltiw_<mode>_internal (dest, GEN_INT (imm)));
8490 DONE;
8491 }
8492
8493 else
8494 gcc_unreachable ();
8495 })
8496 \f
8497 (define_expand "mov<mode>"
8498 [(set (match_operand:FMOVE128 0 "general_operand")
8499 (match_operand:FMOVE128 1 "any_operand"))]
8500 ""
8501 {
8502 rs6000_emit_move (operands[0], operands[1], <MODE>mode);
8503 DONE;
8504 })
8505
8506 ;; It's important to list Y->r and r->Y before r->r because otherwise
8507 ;; reload, given m->r, will try to pick r->r and reload it, which
8508 ;; doesn't make progress.
8509
8510 ;; We can't split little endian direct moves of TDmode, because the words are
8511 ;; not swapped like they are for TImode or TFmode. Subregs therefore are
8512 ;; problematical. Don't allow direct move for this case.
8513
8514 ;; FPR load FPR store FPR move FPR zero GPR load
8515 ;; GPR zero GPR store GPR move MFVSRD MTVSRD
8516
8517 (define_insn_and_split "*mov<mode>_64bit_dm"
8518 [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand"
8519 "=m, d, d, d, Y,
8520 r, r, r, r, d")
8521
8522 (match_operand:FMOVE128_FPR 1 "input_operand"
8523 "d, m, d, <zero_fp>, r,
8524 <zero_fp>, Y, r, d, r"))]
8525
8526 "TARGET_HARD_FLOAT && TARGET_POWERPC64 && FLOAT128_2REG_P (<MODE>mode)
8527 && (<MODE>mode != TDmode || WORDS_BIG_ENDIAN)
8528 && (gpc_reg_operand (operands[0], <MODE>mode)
8529 || gpc_reg_operand (operands[1], <MODE>mode))"
8530 "#"
8531 "&& reload_completed"
8532 [(pc)]
8533 {
8534 rs6000_split_multireg_move (operands[0], operands[1]);
8535 DONE;
8536 }
8537 [(set_attr "length" "8")
8538 (set_attr "isa" "*,*,*,*,*,*,*,*,p8v,p8v")
8539 (set_attr "max_prefixed_insns" "2")
8540 (set_attr "num_insns" "2")])
8541
8542 (define_insn_and_split "*movtd_64bit_nodm"
8543 [(set (match_operand:TD 0 "nonimmediate_operand" "=m,d,d,Y,r,r")
8544 (match_operand:TD 1 "input_operand" "d,m,d,r,Y,r"))]
8545 "TARGET_HARD_FLOAT && TARGET_POWERPC64 && !WORDS_BIG_ENDIAN
8546 && (gpc_reg_operand (operands[0], TDmode)
8547 || gpc_reg_operand (operands[1], TDmode))"
8548 "#"
8549 "&& reload_completed"
8550 [(pc)]
8551 {
8552 rs6000_split_multireg_move (operands[0], operands[1]);
8553 DONE;
8554 }
8555 [(set_attr "length" "8,8,8,12,12,8")
8556 (set_attr "max_prefixed_insns" "2")
8557 (set_attr "num_insns" "2,2,2,3,3,2")])
8558
8559 (define_insn_and_split "*mov<mode>_32bit"
8560 [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand" "=m,d,d,d,Y,r,r")
8561 (match_operand:FMOVE128_FPR 1 "input_operand" "d,m,d,<zero_fp>,r,<zero_fp>Y,r"))]
8562 "TARGET_HARD_FLOAT && !TARGET_POWERPC64
8563 && (FLOAT128_2REG_P (<MODE>mode)
8564 || int_reg_operand_not_pseudo (operands[0], <MODE>mode)
8565 || int_reg_operand_not_pseudo (operands[1], <MODE>mode))
8566 && (gpc_reg_operand (operands[0], <MODE>mode)
8567 || gpc_reg_operand (operands[1], <MODE>mode))"
8568 "#"
8569 "&& reload_completed"
8570 [(pc)]
8571 {
8572 rs6000_split_multireg_move (operands[0], operands[1]);
8573 DONE;
8574 }
8575 [(set_attr "length" "8,8,8,8,20,20,16")])
8576
8577 (define_insn_and_split "*mov<mode>_softfloat"
8578 [(set (match_operand:FMOVE128 0 "nonimmediate_operand" "=Y,r,r,r")
8579 (match_operand:FMOVE128 1 "input_operand" "r,Y,F,r"))]
8580 "TARGET_SOFT_FLOAT
8581 && (gpc_reg_operand (operands[0], <MODE>mode)
8582 || gpc_reg_operand (operands[1], <MODE>mode))"
8583 "#"
8584 "&& reload_completed"
8585 [(pc)]
8586 {
8587 rs6000_split_multireg_move (operands[0], operands[1]);
8588 DONE;
8589 }
8590 [(set_attr_alternative "length"
8591 [(if_then_else (match_test "TARGET_POWERPC64")
8592 (const_string "8")
8593 (const_string "16"))
8594 (if_then_else (match_test "TARGET_POWERPC64")
8595 (const_string "8")
8596 (const_string "16"))
8597 (if_then_else (match_test "TARGET_POWERPC64")
8598 (const_string "16")
8599 (const_string "32"))
8600 (if_then_else (match_test "TARGET_POWERPC64")
8601 (const_string "8")
8602 (const_string "16"))])])
8603
8604 (define_expand "@extenddf<mode>2"
8605 [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
8606 (float_extend:FLOAT128 (match_operand:DF 1 "gpc_reg_operand")))]
8607 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8608 {
8609 if (FLOAT128_IEEE_P (<MODE>mode))
8610 rs6000_expand_float128_convert (operands[0], operands[1], false);
8611 else if (TARGET_VSX)
8612 emit_insn (gen_extenddf2_vsx (<MODE>mode, operands[0], operands[1]));
8613 else
8614 {
8615 rtx zero = gen_reg_rtx (DFmode);
8616 rs6000_emit_move (zero, CONST0_RTX (DFmode), DFmode);
8617
8618 emit_insn (gen_extenddf2_fprs (<MODE>mode,
8619 operands[0], operands[1], zero));
8620 }
8621 DONE;
8622 })
8623
8624 ;; Allow memory operands for the source to be created by the combiner.
8625 (define_insn_and_split "@extenddf<mode>2_fprs"
8626 [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d,&d")
8627 (float_extend:IBM128
8628 (match_operand:DF 1 "nonimmediate_operand" "d,m,d")))
8629 (use (match_operand:DF 2 "nonimmediate_operand" "m,m,d"))]
8630 "!TARGET_VSX && TARGET_HARD_FLOAT
8631 && TARGET_LONG_DOUBLE_128 && FLOAT128_IBM_P (<MODE>mode)"
8632 "#"
8633 "&& reload_completed"
8634 [(set (match_dup 3) (match_dup 1))
8635 (set (match_dup 4) (match_dup 2))]
8636 {
8637 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
8638 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
8639
8640 operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
8641 operands[4] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
8642 })
8643
8644 (define_insn_and_split "@extenddf<mode>2_vsx"
8645 [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d")
8646 (float_extend:IBM128
8647 (match_operand:DF 1 "nonimmediate_operand" "wa,m")))]
8648 "TARGET_LONG_DOUBLE_128 && TARGET_VSX && FLOAT128_IBM_P (<MODE>mode)"
8649 "#"
8650 "&& reload_completed"
8651 [(set (match_dup 2) (match_dup 1))
8652 (set (match_dup 3) (match_dup 4))]
8653 {
8654 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
8655 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
8656
8657 operands[2] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
8658 operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
8659 operands[4] = CONST0_RTX (DFmode);
8660 })
8661
8662 (define_expand "extendsf<mode>2"
8663 [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
8664 (float_extend:FLOAT128 (match_operand:SF 1 "gpc_reg_operand")))]
8665 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8666 {
8667 if (FLOAT128_IEEE_P (<MODE>mode))
8668 rs6000_expand_float128_convert (operands[0], operands[1], false);
8669 else
8670 {
8671 rtx tmp = gen_reg_rtx (DFmode);
8672 emit_insn (gen_extendsfdf2 (tmp, operands[1]));
8673 emit_insn (gen_extenddf<mode>2 (operands[0], tmp));
8674 }
8675 DONE;
8676 })
8677
8678 (define_expand "trunc<mode>df2"
8679 [(set (match_operand:DF 0 "gpc_reg_operand")
8680 (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand")))]
8681 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8682 {
8683 if (FLOAT128_IEEE_P (<MODE>mode))
8684 {
8685 rs6000_expand_float128_convert (operands[0], operands[1], false);
8686 DONE;
8687 }
8688 })
8689
8690 (define_insn_and_split "trunc<mode>df2_internal1"
8691 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d")
8692 (float_truncate:DF
8693 (match_operand:IBM128 1 "gpc_reg_operand" "0,d")))]
8694 "FLOAT128_IBM_P (<MODE>mode) && !TARGET_XL_COMPAT
8695 && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8696 "@
8697 #
8698 fmr %0,%1"
8699 "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
8700 [(const_int 0)]
8701 {
8702 emit_note (NOTE_INSN_DELETED);
8703 DONE;
8704 }
8705 [(set_attr "type" "fpsimple")])
8706
8707 (define_insn "trunc<mode>df2_internal2"
8708 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
8709 (float_truncate:DF (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
8710 "FLOAT128_IBM_P (<MODE>mode) && TARGET_XL_COMPAT && TARGET_HARD_FLOAT
8711 && TARGET_LONG_DOUBLE_128"
8712 "fadd %0,%1,%L1"
8713 [(set_attr "type" "fp")])
8714
8715 (define_expand "trunc<mode>sf2"
8716 [(set (match_operand:SF 0 "gpc_reg_operand")
8717 (float_truncate:SF (match_operand:FLOAT128 1 "gpc_reg_operand")))]
8718 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8719 {
8720 if (FLOAT128_IEEE_P (<MODE>mode))
8721 rs6000_expand_float128_convert (operands[0], operands[1], false);
8722 else
8723 {
8724 rtx tmp = gen_reg_rtx (DFmode);
8725 emit_insn (gen_trunc<mode>df2 (tmp, operands[1]));
8726 emit_insn (gen_truncdfsf2 (operands[0], tmp));
8727 }
8728 DONE;
8729 })
8730
8731 (define_expand "floatsi<mode>2"
8732 [(parallel [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
8733 (float:FLOAT128 (match_operand:SI 1 "gpc_reg_operand")))
8734 (clobber (match_scratch:DI 2))])]
8735 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8736 {
8737 rtx op0 = operands[0];
8738 rtx op1 = operands[1];
8739
8740 if (TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode))
8741 ;
8742 else if (FLOAT128_IEEE_P (<MODE>mode))
8743 {
8744 rs6000_expand_float128_convert (op0, op1, false);
8745 DONE;
8746 }
8747 else
8748 {
8749 rtx tmp = gen_reg_rtx (DFmode);
8750 expand_float (tmp, op1, false);
8751 emit_insn (gen_extenddf2 (<MODE>mode, op0, tmp));
8752 DONE;
8753 }
8754 })
8755
8756 ; fadd, but rounding towards zero.
8757 ; This is probably not the optimal code sequence.
8758 (define_insn "fix_trunc_helper<mode>"
8759 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
8760 (unspec:DF [(match_operand:IBM128 1 "gpc_reg_operand" "d")]
8761 UNSPEC_FIX_TRUNC_TF))
8762 (clobber (match_operand:DF 2 "gpc_reg_operand" "=&d"))]
8763 "TARGET_HARD_FLOAT && FLOAT128_IBM_P (<MODE>mode)"
8764 "mffs %2\n\tmtfsb1 31\n\tmtfsb0 30\n\tfadd %0,%1,%L1\n\tmtfsf 1,%2"
8765 [(set_attr "type" "fp")
8766 (set_attr "length" "20")])
8767
8768 (define_expand "fix_trunc<mode>si2"
8769 [(set (match_operand:SI 0 "gpc_reg_operand")
8770 (fix:SI (match_operand:FLOAT128 1 "gpc_reg_operand")))]
8771 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8772 {
8773 rtx op0 = operands[0];
8774 rtx op1 = operands[1];
8775
8776 if (TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode))
8777 ;
8778 else
8779 {
8780 if (FLOAT128_IEEE_P (<MODE>mode))
8781 rs6000_expand_float128_convert (op0, op1, false);
8782 else
8783 emit_insn (gen_fix_truncsi2_fprs (<MODE>mode, op0, op1));
8784 DONE;
8785 }
8786 })
8787
8788 (define_expand "@fix_trunc<mode>si2_fprs"
8789 [(parallel [(set (match_operand:SI 0 "gpc_reg_operand")
8790 (fix:SI (match_operand:IBM128 1 "gpc_reg_operand")))
8791 (clobber (match_dup 2))
8792 (clobber (match_dup 3))
8793 (clobber (match_dup 4))
8794 (clobber (match_dup 5))])]
8795 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8796 {
8797 operands[2] = gen_reg_rtx (DFmode);
8798 operands[3] = gen_reg_rtx (DFmode);
8799 operands[4] = gen_reg_rtx (DImode);
8800 operands[5] = assign_stack_temp (DImode, GET_MODE_SIZE (DImode));
8801 })
8802
8803 (define_insn_and_split "*fix_trunc<mode>si2_internal"
8804 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
8805 (fix:SI (match_operand:IBM128 1 "gpc_reg_operand" "d")))
8806 (clobber (match_operand:DF 2 "gpc_reg_operand" "=d"))
8807 (clobber (match_operand:DF 3 "gpc_reg_operand" "=&d"))
8808 (clobber (match_operand:DI 4 "gpc_reg_operand" "=d"))
8809 (clobber (match_operand:DI 5 "offsettable_mem_operand" "=o"))]
8810 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8811 "#"
8812 "&& 1"
8813 [(pc)]
8814 {
8815 rtx lowword;
8816 emit_insn (gen_fix_trunc_helper<mode> (operands[2], operands[1],
8817 operands[3]));
8818
8819 gcc_assert (MEM_P (operands[5]));
8820 lowword = adjust_address (operands[5], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
8821
8822 emit_insn (gen_fctiwz_df (operands[4], operands[2]));
8823 emit_move_insn (operands[5], operands[4]);
8824 emit_move_insn (operands[0], lowword);
8825 DONE;
8826 })
8827
8828 (define_expand "fix_trunc<mode>di2"
8829 [(set (match_operand:DI 0 "gpc_reg_operand")
8830 (fix:DI (match_operand:IEEE128 1 "gpc_reg_operand")))]
8831 "TARGET_FLOAT128_TYPE"
8832 {
8833 if (!TARGET_FLOAT128_HW)
8834 {
8835 rs6000_expand_float128_convert (operands[0], operands[1], false);
8836 DONE;
8837 }
8838 })
8839
8840 (define_expand "fixuns_trunc<IEEE128:mode><SDI:mode>2"
8841 [(set (match_operand:SDI 0 "gpc_reg_operand")
8842 (unsigned_fix:SDI (match_operand:IEEE128 1 "gpc_reg_operand")))]
8843 "TARGET_FLOAT128_TYPE"
8844 {
8845 rs6000_expand_float128_convert (operands[0], operands[1], true);
8846 DONE;
8847 })
8848
8849 (define_expand "floatdi<mode>2"
8850 [(set (match_operand:IEEE128 0 "gpc_reg_operand")
8851 (float:IEEE128 (match_operand:DI 1 "gpc_reg_operand")))]
8852 "TARGET_FLOAT128_TYPE"
8853 {
8854 if (!TARGET_FLOAT128_HW)
8855 {
8856 rs6000_expand_float128_convert (operands[0], operands[1], false);
8857 DONE;
8858 }
8859 })
8860
8861 (define_expand "floatunsdi<IEEE128:mode>2"
8862 [(set (match_operand:IEEE128 0 "gpc_reg_operand")
8863 (unsigned_float:IEEE128 (match_operand:DI 1 "gpc_reg_operand")))]
8864 "TARGET_FLOAT128_TYPE"
8865 {
8866 if (!TARGET_FLOAT128_HW)
8867 {
8868 rs6000_expand_float128_convert (operands[0], operands[1], true);
8869 DONE;
8870 }
8871 })
8872
8873 (define_expand "floatuns<IEEE128:mode>2"
8874 [(set (match_operand:IEEE128 0 "gpc_reg_operand")
8875 (unsigned_float:IEEE128 (match_operand:SI 1 "gpc_reg_operand")))]
8876 "TARGET_FLOAT128_TYPE"
8877 {
8878 rtx op0 = operands[0];
8879 rtx op1 = operands[1];
8880
8881 if (TARGET_FLOAT128_HW)
8882 emit_insn (gen_floatuns_<IEEE128:mode>si2_hw (op0, op1));
8883 else
8884 rs6000_expand_float128_convert (op0, op1, true);
8885 DONE;
8886 })
8887
8888 (define_expand "neg<mode>2"
8889 [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
8890 (neg:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand")))]
8891 "FLOAT128_IEEE_P (<MODE>mode)
8892 || (FLOAT128_IBM_P (<MODE>mode) && TARGET_HARD_FLOAT)"
8893 {
8894 if (FLOAT128_IEEE_P (<MODE>mode))
8895 {
8896 if (TARGET_FLOAT128_HW)
8897 emit_insn (gen_neg2_hw (<MODE>mode, operands[0], operands[1]));
8898 else if (TARGET_FLOAT128_TYPE)
8899 emit_insn (gen_ieee_128bit_vsx_neg2 (<MODE>mode,
8900 operands[0], operands[1]));
8901 else
8902 {
8903 rtx libfunc = optab_libfunc (neg_optab, <MODE>mode);
8904 rtx target = emit_library_call_value (libfunc, operands[0], LCT_CONST,
8905 <MODE>mode,
8906 operands[1], <MODE>mode);
8907
8908 if (target && !rtx_equal_p (target, operands[0]))
8909 emit_move_insn (operands[0], target);
8910 }
8911 DONE;
8912 }
8913 })
8914
8915 (define_insn "neg<mode>2_internal"
8916 [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d")
8917 (neg:IBM128 (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
8918 "TARGET_HARD_FLOAT && FLOAT128_IBM_P (<MODE>mode)"
8919 {
8920 if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
8921 return "fneg %L0,%L1\;fneg %0,%1";
8922 else
8923 return "fneg %0,%1\;fneg %L0,%L1";
8924 }
8925 [(set_attr "type" "fpsimple")
8926 (set_attr "length" "8")])
8927
8928 (define_expand "abs<mode>2"
8929 [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
8930 (abs:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand")))]
8931 "FLOAT128_IEEE_P (<MODE>mode)
8932 || (FLOAT128_IBM_P (<MODE>mode) && TARGET_HARD_FLOAT)"
8933 {
8934 rtx label;
8935
8936 if (FLOAT128_IEEE_P (<MODE>mode))
8937 {
8938 if (TARGET_FLOAT128_HW)
8939 {
8940 emit_insn (gen_abs2_hw (<MODE>mode, operands[0], operands[1]));
8941 DONE;
8942 }
8943 else if (TARGET_FLOAT128_TYPE)
8944 {
8945 emit_insn (gen_ieee_128bit_vsx_abs2 (<MODE>mode,
8946 operands[0], operands[1]));
8947 DONE;
8948 }
8949 else
8950 FAIL;
8951 }
8952
8953 label = gen_label_rtx ();
8954 emit_insn (gen_abs2_internal (<MODE>mode, operands[0], operands[1], label));
8955 emit_label (label);
8956 DONE;
8957 })
8958
8959 (define_expand "@abs<mode>2_internal"
8960 [(set (match_operand:IBM128 0 "gpc_reg_operand")
8961 (match_operand:IBM128 1 "gpc_reg_operand"))
8962 (set (match_dup 3) (match_dup 5))
8963 (set (match_dup 5) (abs:DF (match_dup 5)))
8964 (set (match_dup 4) (compare:CCFP (match_dup 3) (match_dup 5)))
8965 (set (pc) (if_then_else (eq (match_dup 4) (const_int 0))
8966 (label_ref (match_operand 2 ""))
8967 (pc)))
8968 (set (match_dup 6) (neg:DF (match_dup 6)))]
8969 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8970 {
8971 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
8972 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
8973 operands[3] = gen_reg_rtx (DFmode);
8974 operands[4] = gen_reg_rtx (CCFPmode);
8975 operands[5] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
8976 operands[6] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
8977 })
8978
8979 \f
8980 ;; Generate IEEE 128-bit -0.0 (0x80000000000000000000000000000000) in a vector
8981 ;; register
8982
8983 (define_expand "ieee_128bit_negative_zero"
8984 [(set (match_operand:V16QI 0 "register_operand") (match_dup 1))]
8985 "TARGET_FLOAT128_TYPE"
8986 {
8987 rtvec v = rtvec_alloc (16);
8988 int i, high;
8989
8990 for (i = 0; i < 16; i++)
8991 RTVEC_ELT (v, i) = const0_rtx;
8992
8993 high = (BYTES_BIG_ENDIAN) ? 0 : 15;
8994 RTVEC_ELT (v, high) = gen_int_mode (0x80, QImode);
8995
8996 rs6000_expand_vector_init (operands[0], gen_rtx_PARALLEL (V16QImode, v));
8997 DONE;
8998 })
8999
9000 ;; IEEE 128-bit negate
9001
9002 ;; We have 2 insns here for negate and absolute value. The first uses
9003 ;; match_scratch so that phases like combine can recognize neg/abs as generic
9004 ;; insns, and second insn after the first split pass loads up the bit to
9005 ;; twiddle the sign bit. Later GCSE passes can then combine multiple uses of
9006 ;; neg/abs to create the constant just once.
9007
9008 (define_insn_and_split "@ieee_128bit_vsx_neg<mode>2"
9009 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
9010 (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
9011 (clobber (match_scratch:V16QI 2 "=v"))]
9012 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
9013 "#"
9014 "&& 1"
9015 [(parallel [(set (match_dup 0)
9016 (neg:IEEE128 (match_dup 1)))
9017 (use (match_dup 2))])]
9018 {
9019 if (GET_CODE (operands[2]) == SCRATCH)
9020 operands[2] = gen_reg_rtx (V16QImode);
9021
9022 operands[3] = gen_reg_rtx (V16QImode);
9023 emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
9024 }
9025 [(set_attr "length" "8")
9026 (set_attr "type" "vecsimple")])
9027
9028 (define_insn "*ieee_128bit_vsx_neg<mode>2_internal"
9029 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
9030 (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
9031 (use (match_operand:V16QI 2 "register_operand" "v"))]
9032 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
9033 "xxlxor %x0,%x1,%x2"
9034 [(set_attr "type" "veclogical")])
9035
9036 ;; IEEE 128-bit absolute value
9037 (define_insn_and_split "@ieee_128bit_vsx_abs<mode>2"
9038 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
9039 (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
9040 (clobber (match_scratch:V16QI 2 "=v"))]
9041 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
9042 "#"
9043 "&& 1"
9044 [(parallel [(set (match_dup 0)
9045 (abs:IEEE128 (match_dup 1)))
9046 (use (match_dup 2))])]
9047 {
9048 if (GET_CODE (operands[2]) == SCRATCH)
9049 operands[2] = gen_reg_rtx (V16QImode);
9050
9051 operands[3] = gen_reg_rtx (V16QImode);
9052 emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
9053 }
9054 [(set_attr "length" "8")
9055 (set_attr "type" "vecsimple")])
9056
9057 (define_insn "*ieee_128bit_vsx_abs<mode>2_internal"
9058 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
9059 (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
9060 (use (match_operand:V16QI 2 "register_operand" "v"))]
9061 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
9062 "xxlandc %x0,%x1,%x2"
9063 [(set_attr "type" "veclogical")])
9064
9065 ;; IEEE 128-bit negative absolute value
9066 (define_insn_and_split "*ieee_128bit_vsx_nabs<mode>2"
9067 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
9068 (neg:IEEE128
9069 (abs:IEEE128
9070 (match_operand:IEEE128 1 "register_operand" "wa"))))
9071 (clobber (match_scratch:V16QI 2 "=v"))]
9072 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW
9073 && FLOAT128_IEEE_P (<MODE>mode)"
9074 "#"
9075 "&& 1"
9076 [(parallel [(set (match_dup 0)
9077 (neg:IEEE128 (abs:IEEE128 (match_dup 1))))
9078 (use (match_dup 2))])]
9079 {
9080 if (GET_CODE (operands[2]) == SCRATCH)
9081 operands[2] = gen_reg_rtx (V16QImode);
9082
9083 operands[3] = gen_reg_rtx (V16QImode);
9084 emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
9085 }
9086 [(set_attr "length" "8")
9087 (set_attr "type" "vecsimple")])
9088
9089 (define_insn "*ieee_128bit_vsx_nabs<mode>2_internal"
9090 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
9091 (neg:IEEE128
9092 (abs:IEEE128
9093 (match_operand:IEEE128 1 "register_operand" "wa"))))
9094 (use (match_operand:V16QI 2 "register_operand" "v"))]
9095 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
9096 "xxlor %x0,%x1,%x2"
9097 [(set_attr "type" "veclogical")])
9098
9099 ;; Float128 conversion functions. These expand to library function calls.
9100 ;; We use expand to convert from IBM double double to IEEE 128-bit
9101 ;; and trunc for the opposite.
9102 (define_expand "extendiftf2"
9103 [(set (match_operand:TF 0 "gpc_reg_operand")
9104 (float_extend:TF (match_operand:IF 1 "gpc_reg_operand")))]
9105 "TARGET_FLOAT128_TYPE"
9106 {
9107 rs6000_expand_float128_convert (operands[0], operands[1], false);
9108 DONE;
9109 })
9110
9111 (define_expand "extendifkf2"
9112 [(set (match_operand:KF 0 "gpc_reg_operand")
9113 (float_extend:KF (match_operand:IF 1 "gpc_reg_operand")))]
9114 "TARGET_FLOAT128_TYPE"
9115 {
9116 rs6000_expand_float128_convert (operands[0], operands[1], false);
9117 DONE;
9118 })
9119
9120 (define_expand "extendtfkf2"
9121 [(set (match_operand:KF 0 "gpc_reg_operand")
9122 (float_extend:KF (match_operand:TF 1 "gpc_reg_operand")))]
9123 "TARGET_FLOAT128_TYPE"
9124 {
9125 rs6000_expand_float128_convert (operands[0], operands[1], false);
9126 DONE;
9127 })
9128
9129 (define_expand "extendtfif2"
9130 [(set (match_operand:IF 0 "gpc_reg_operand")
9131 (float_extend:IF (match_operand:TF 1 "gpc_reg_operand")))]
9132 "TARGET_FLOAT128_TYPE"
9133 {
9134 rs6000_expand_float128_convert (operands[0], operands[1], false);
9135 DONE;
9136 })
9137
9138 (define_expand "trunciftf2"
9139 [(set (match_operand:TF 0 "gpc_reg_operand")
9140 (float_truncate:TF (match_operand:IF 1 "gpc_reg_operand")))]
9141 "TARGET_FLOAT128_TYPE"
9142 {
9143 rs6000_expand_float128_convert (operands[0], operands[1], false);
9144 DONE;
9145 })
9146
9147 (define_expand "truncifkf2"
9148 [(set (match_operand:KF 0 "gpc_reg_operand")
9149 (float_truncate:KF (match_operand:IF 1 "gpc_reg_operand")))]
9150 "TARGET_FLOAT128_TYPE"
9151 {
9152 rs6000_expand_float128_convert (operands[0], operands[1], false);
9153 DONE;
9154 })
9155
9156 (define_expand "trunckftf2"
9157 [(set (match_operand:TF 0 "gpc_reg_operand")
9158 (float_truncate:TF (match_operand:KF 1 "gpc_reg_operand")))]
9159 "TARGET_FLOAT128_TYPE"
9160 {
9161 rs6000_expand_float128_convert (operands[0], operands[1], false);
9162 DONE;
9163 })
9164
9165 (define_expand "trunctfif2"
9166 [(set (match_operand:IF 0 "gpc_reg_operand")
9167 (float_truncate:IF (match_operand:TF 1 "gpc_reg_operand")))]
9168 "TARGET_FLOAT128_TYPE"
9169 {
9170 rs6000_expand_float128_convert (operands[0], operands[1], false);
9171 DONE;
9172 })
9173
9174 (define_insn_and_split "*extend<mode>tf2_internal"
9175 [(set (match_operand:TF 0 "gpc_reg_operand" "=<IFKF_reg>")
9176 (float_extend:TF
9177 (match_operand:IFKF 1 "gpc_reg_operand" "<IFKF_reg>")))]
9178 "TARGET_FLOAT128_TYPE
9179 && FLOAT128_IBM_P (TFmode) == FLOAT128_IBM_P (<MODE>mode)"
9180 "#"
9181 "&& reload_completed"
9182 [(set (match_dup 0) (match_dup 2))]
9183 {
9184 operands[2] = gen_rtx_REG (TFmode, REGNO (operands[1]));
9185 })
9186
9187 (define_insn_and_split "*extendtf<mode>2_internal"
9188 [(set (match_operand:IFKF 0 "gpc_reg_operand" "=<IFKF_reg>")
9189 (float_extend:IFKF
9190 (match_operand:TF 1 "gpc_reg_operand" "<IFKF_reg>")))]
9191 "TARGET_FLOAT128_TYPE
9192 && FLOAT128_IBM_P (TFmode) == FLOAT128_IBM_P (<MODE>mode)"
9193 "#"
9194 "&& reload_completed"
9195 [(set (match_dup 0) (match_dup 2))]
9196 {
9197 operands[2] = gen_rtx_REG (<MODE>mode, REGNO (operands[1]));
9198 })
9199
9200 \f
9201 ;; Reload helper functions used by rs6000_secondary_reload. The patterns all
9202 ;; must have 3 arguments, and scratch register constraint must be a single
9203 ;; constraint.
9204
9205 ;; Reload patterns to support gpr load/store with misaligned mem.
9206 ;; and multiple gpr load/store at offset >= 0xfffc
9207 (define_expand "reload_<mode>_store"
9208 [(parallel [(match_operand 0 "memory_operand" "=m")
9209 (match_operand 1 "gpc_reg_operand" "r")
9210 (match_operand:GPR 2 "register_operand" "=&b")])]
9211 ""
9212 {
9213 rs6000_secondary_reload_gpr (operands[1], operands[0], operands[2], true);
9214 DONE;
9215 })
9216
9217 (define_expand "reload_<mode>_load"
9218 [(parallel [(match_operand 0 "gpc_reg_operand" "=r")
9219 (match_operand 1 "memory_operand" "m")
9220 (match_operand:GPR 2 "register_operand" "=b")])]
9221 ""
9222 {
9223 rs6000_secondary_reload_gpr (operands[0], operands[1], operands[2], false);
9224 DONE;
9225 })
9226
9227 \f
9228 ;; Reload patterns for various types using the vector registers. We may need
9229 ;; an additional base register to convert the reg+offset addressing to reg+reg
9230 ;; for vector registers and reg+reg or (reg+reg)&(-16) addressing to just an
9231 ;; index register for gpr registers.
9232 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_store"
9233 [(parallel [(match_operand:RELOAD 0 "memory_operand" "m")
9234 (match_operand:RELOAD 1 "gpc_reg_operand" "wa")
9235 (match_operand:P 2 "register_operand" "=b")])]
9236 "<P:tptrsize>"
9237 {
9238 rs6000_secondary_reload_inner (operands[1], operands[0], operands[2], true);
9239 DONE;
9240 })
9241
9242 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_load"
9243 [(parallel [(match_operand:RELOAD 0 "gpc_reg_operand" "wa")
9244 (match_operand:RELOAD 1 "memory_operand" "m")
9245 (match_operand:P 2 "register_operand" "=b")])]
9246 "<P:tptrsize>"
9247 {
9248 rs6000_secondary_reload_inner (operands[0], operands[1], operands[2], false);
9249 DONE;
9250 })
9251
9252
9253 ;; Reload sometimes tries to move the address to a GPR, and can generate
9254 ;; invalid RTL for addresses involving AND -16. Allow addresses involving
9255 ;; reg+reg, reg+small constant, or just reg, all wrapped in an AND -16.
9256
9257 (define_insn_and_split "*vec_reload_and_plus_<mptrsize>"
9258 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9259 (and:P (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
9260 (match_operand:P 2 "reg_or_cint_operand" "rI"))
9261 (const_int -16)))]
9262 "TARGET_ALTIVEC && reload_completed"
9263 "#"
9264 "&& reload_completed"
9265 [(set (match_dup 0)
9266 (plus:P (match_dup 1)
9267 (match_dup 2)))
9268 (set (match_dup 0)
9269 (and:P (match_dup 0)
9270 (const_int -16)))])
9271 \f
9272 ;; Power8 merge instructions to allow direct move to/from floating point
9273 ;; registers in 32-bit mode. We use TF mode to get two registers to move the
9274 ;; individual 32-bit parts across. Subreg doesn't work too well on the TF
9275 ;; value, since it is allocated in reload and not all of the flow information
9276 ;; is setup for it. We have two patterns to do the two moves between gprs and
9277 ;; fprs. There isn't a dependancy between the two, but we could potentially
9278 ;; schedule other instructions between the two instructions.
9279
9280 (define_insn "p8_fmrgow_<mode>"
9281 [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
9282 (unspec:FMOVE64X [
9283 (match_operand:DF 1 "register_operand" "d")
9284 (match_operand:DF 2 "register_operand" "d")]
9285 UNSPEC_P8V_FMRGOW))]
9286 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
9287 "fmrgow %0,%1,%2"
9288 [(set_attr "type" "fpsimple")])
9289
9290 (define_insn "p8_mtvsrwz"
9291 [(set (match_operand:DF 0 "register_operand" "=d")
9292 (unspec:DF [(match_operand:SI 1 "register_operand" "r")]
9293 UNSPEC_P8V_MTVSRWZ))]
9294 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
9295 "mtvsrwz %x0,%1"
9296 [(set_attr "type" "mtvsr")])
9297
9298 (define_insn "p8_mtvsrwz_v16qisi2"
9299 [(set (match_operand:V16QI 0 "register_operand" "=wa")
9300 (unspec:V16QI [(match_operand:SI 1 "register_operand" "r")]
9301 UNSPEC_P8V_MTVSRWZ))]
9302 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
9303 "mtvsrwz %x0,%1"
9304 [(set_attr "type" "mtvsr")])
9305
9306 (define_insn "p8_mtvsrd_v16qidi2"
9307 [(set (match_operand:V16QI 0 "register_operand" "=wa")
9308 (unspec:V16QI [(match_operand:DI 1 "register_operand" "r")]
9309 UNSPEC_P8V_MTVSRD))]
9310 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
9311 "mtvsrd %x0,%1"
9312 [(set_attr "type" "mtvsr")])
9313
9314 (define_insn_and_split "reload_fpr_from_gpr<mode>"
9315 [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
9316 (unspec:FMOVE64X [(match_operand:FMOVE64X 1 "register_operand" "r")]
9317 UNSPEC_P8V_RELOAD_FROM_GPR))
9318 (clobber (match_operand:IF 2 "register_operand" "=d"))]
9319 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
9320 "#"
9321 "&& reload_completed"
9322 [(const_int 0)]
9323 {
9324 rtx dest = operands[0];
9325 rtx src = operands[1];
9326 rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0);
9327 rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8);
9328 rtx gpr_hi_reg = gen_highpart (SImode, src);
9329 rtx gpr_lo_reg = gen_lowpart (SImode, src);
9330
9331 emit_insn (gen_p8_mtvsrwz (tmp_hi, gpr_hi_reg));
9332 emit_insn (gen_p8_mtvsrwz (tmp_lo, gpr_lo_reg));
9333 emit_insn (gen_p8_fmrgow_<mode> (dest, tmp_hi, tmp_lo));
9334 DONE;
9335 }
9336 [(set_attr "length" "12")
9337 (set_attr "type" "three")])
9338
9339 ;; Move 128 bit values from GPRs to VSX registers in 64-bit mode
9340 (define_insn "p8_mtvsrd_df"
9341 [(set (match_operand:DF 0 "register_operand" "=wa")
9342 (unspec:DF [(match_operand:DI 1 "register_operand" "r")]
9343 UNSPEC_P8V_MTVSRD))]
9344 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
9345 "mtvsrd %x0,%1"
9346 [(set_attr "type" "mtvsr")])
9347
9348 (define_insn "p8_xxpermdi_<mode>"
9349 [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
9350 (unspec:FMOVE128_GPR [
9351 (match_operand:DF 1 "register_operand" "wa")
9352 (match_operand:DF 2 "register_operand" "wa")]
9353 UNSPEC_P8V_XXPERMDI))]
9354 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
9355 "xxpermdi %x0,%x1,%x2,0"
9356 [(set_attr "type" "vecperm")])
9357
9358 (define_insn_and_split "reload_vsx_from_gpr<mode>"
9359 [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
9360 (unspec:FMOVE128_GPR
9361 [(match_operand:FMOVE128_GPR 1 "register_operand" "r")]
9362 UNSPEC_P8V_RELOAD_FROM_GPR))
9363 (clobber (match_operand:IF 2 "register_operand" "=wa"))]
9364 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
9365 "#"
9366 "&& reload_completed"
9367 [(const_int 0)]
9368 {
9369 rtx dest = operands[0];
9370 rtx src = operands[1];
9371 /* You might think that we could use op0 as one temp and a DF clobber
9372 as op2, but you'd be wrong. Secondary reload move patterns don't
9373 check for overlap of the clobber and the destination. */
9374 rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0);
9375 rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8);
9376 rtx gpr_hi_reg = gen_highpart (DImode, src);
9377 rtx gpr_lo_reg = gen_lowpart (DImode, src);
9378
9379 emit_insn (gen_p8_mtvsrd_df (tmp_hi, gpr_hi_reg));
9380 emit_insn (gen_p8_mtvsrd_df (tmp_lo, gpr_lo_reg));
9381 emit_insn (gen_p8_xxpermdi_<mode> (dest, tmp_hi, tmp_lo));
9382 DONE;
9383 }
9384 [(set_attr "length" "12")
9385 (set_attr "type" "three")])
9386
9387 (define_split
9388 [(set (match_operand:FMOVE128_GPR 0 "nonimmediate_operand")
9389 (match_operand:FMOVE128_GPR 1 "input_operand"))]
9390 "reload_completed
9391 && (int_reg_operand (operands[0], <MODE>mode)
9392 || int_reg_operand (operands[1], <MODE>mode))
9393 && (!TARGET_DIRECT_MOVE_128
9394 || (!vsx_register_operand (operands[0], <MODE>mode)
9395 && !vsx_register_operand (operands[1], <MODE>mode)))"
9396 [(pc)]
9397 {
9398 rs6000_split_multireg_move (operands[0], operands[1]);
9399 DONE;
9400 })
9401
9402 ;; Move SFmode to a VSX from a GPR register. Because scalar floating point
9403 ;; type is stored internally as double precision in the VSX registers, we have
9404 ;; to convert it from the vector format.
9405 (define_insn "p8_mtvsrd_sf"
9406 [(set (match_operand:SF 0 "register_operand" "=wa")
9407 (unspec:SF [(match_operand:DI 1 "register_operand" "r")]
9408 UNSPEC_P8V_MTVSRD))]
9409 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
9410 "mtvsrd %x0,%1"
9411 [(set_attr "type" "mtvsr")])
9412
9413 (define_insn_and_split "reload_vsx_from_gprsf"
9414 [(set (match_operand:SF 0 "register_operand" "=wa")
9415 (unspec:SF [(match_operand:SF 1 "register_operand" "r")]
9416 UNSPEC_P8V_RELOAD_FROM_GPR))
9417 (clobber (match_operand:DI 2 "register_operand" "=r"))]
9418 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
9419 "#"
9420 "&& reload_completed"
9421 [(const_int 0)]
9422 {
9423 rtx op0 = operands[0];
9424 rtx op1 = operands[1];
9425 rtx op2 = operands[2];
9426 rtx op1_di = simplify_gen_subreg (DImode, op1, SFmode, 0);
9427
9428 /* Move SF value to upper 32-bits for xscvspdpn. */
9429 emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32)));
9430 emit_insn (gen_p8_mtvsrd_sf (op0, op2));
9431 emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0));
9432 DONE;
9433 }
9434 [(set_attr "length" "8")
9435 (set_attr "type" "two")])
9436
9437 ;; Move 128 bit values from VSX registers to GPRs in 64-bit mode by doing a
9438 ;; normal 64-bit move, followed by an xxpermdi to get the bottom 64-bit value,
9439 ;; and then doing a move of that.
9440 (define_insn "p8_mfvsrd_3_<mode>"
9441 [(set (match_operand:DF 0 "register_operand" "=r")
9442 (unspec:DF [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
9443 UNSPEC_P8V_RELOAD_FROM_VSX))]
9444 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
9445 "mfvsrd %0,%x1"
9446 [(set_attr "type" "mfvsr")])
9447
9448 (define_insn_and_split "reload_gpr_from_vsx<mode>"
9449 [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=r")
9450 (unspec:FMOVE128_GPR
9451 [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
9452 UNSPEC_P8V_RELOAD_FROM_VSX))
9453 (clobber (match_operand:FMOVE128_GPR 2 "register_operand" "=wa"))]
9454 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
9455 "#"
9456 "&& reload_completed"
9457 [(const_int 0)]
9458 {
9459 rtx dest = operands[0];
9460 rtx src = operands[1];
9461 rtx tmp = operands[2];
9462 rtx gpr_hi_reg = gen_highpart (DFmode, dest);
9463 rtx gpr_lo_reg = gen_lowpart (DFmode, dest);
9464
9465 emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_hi_reg, src));
9466 emit_insn (gen_vsx_xxpermdi_<mode>_be (tmp, src, src, GEN_INT (3)));
9467 emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_lo_reg, tmp));
9468 DONE;
9469 }
9470 [(set_attr "length" "12")
9471 (set_attr "type" "three")])
9472
9473 ;; Move SFmode to a GPR from a VSX register. Because scalar floating point
9474 ;; type is stored internally as double precision, we have to convert it to the
9475 ;; vector format.
9476
9477 (define_insn_and_split "reload_gpr_from_vsxsf"
9478 [(set (match_operand:SF 0 "register_operand" "=r")
9479 (unspec:SF [(match_operand:SF 1 "register_operand" "wa")]
9480 UNSPEC_P8V_RELOAD_FROM_VSX))
9481 (clobber (match_operand:V4SF 2 "register_operand" "=wa"))]
9482 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
9483 "#"
9484 "&& reload_completed"
9485 [(const_int 0)]
9486 {
9487 rtx op0 = operands[0];
9488 rtx op1 = operands[1];
9489 rtx op2 = operands[2];
9490 rtx op0_di = gen_rtx_REG (DImode, reg_or_subregno (op0));
9491 rtx op2_si = gen_rtx_REG (SImode, reg_or_subregno (op2));
9492
9493 emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
9494 emit_insn (gen_zero_extendsidi2 (op0_di, op2_si));
9495 DONE;
9496 }
9497 [(set_attr "length" "8")
9498 (set_attr "type" "two")
9499 (set_attr "isa" "p8v")])
9500 \f
9501 ;; Next come the multi-word integer load and store and the load and store
9502 ;; multiple insns.
9503
9504 ;; List r->r after r->Y, otherwise reload will try to reload a
9505 ;; non-offsettable address by using r->r which won't make progress.
9506 ;; Use of fprs is disparaged slightly otherwise reload prefers to reload
9507 ;; a gpr into a fpr instead of reloading an invalid 'Y' address
9508
9509 ;; GPR store GPR load GPR move FPR store FPR load FPR move
9510 ;; GPR const AVX store AVX store AVX load AVX load VSX move
9511 ;; P9 0 P9 -1 AVX 0/-1 VSX 0 VSX -1 P9 const
9512 ;; AVX const
9513
9514 (define_insn "*movdi_internal32"
9515 [(set (match_operand:DI 0 "nonimmediate_operand"
9516 "=Y, r, r, m, ^d, ^d,
9517 r, wY, Z, ^v, $v, ^wa,
9518 wa, wa, v, wa, *i, v,
9519 v")
9520 (match_operand:DI 1 "input_operand"
9521 "r, Y, r, ^d, m, ^d,
9522 IJKnF, ^v, $v, wY, Z, ^wa,
9523 Oj, wM, OjwM, Oj, wM, wS,
9524 wB"))]
9525 "! TARGET_POWERPC64
9526 && (gpc_reg_operand (operands[0], DImode)
9527 || gpc_reg_operand (operands[1], DImode))"
9528 "@
9529 #
9530 #
9531 #
9532 stfd%U0%X0 %1,%0
9533 lfd%U1%X1 %0,%1
9534 fmr %0,%1
9535 #
9536 stxsd %1,%0
9537 stxsdx %x1,%y0
9538 lxsd %0,%1
9539 lxsdx %x0,%y1
9540 xxlor %x0,%x1,%x1
9541 xxspltib %x0,0
9542 xxspltib %x0,255
9543 vspltisw %0,%1
9544 xxlxor %x0,%x0,%x0
9545 xxlorc %x0,%x0,%x0
9546 #
9547 #"
9548 [(set_attr "type"
9549 "store, load, *, fpstore, fpload, fpsimple,
9550 *, fpstore, fpstore, fpload, fpload, veclogical,
9551 vecsimple, vecsimple, vecsimple, veclogical,veclogical,vecsimple,
9552 vecsimple")
9553 (set_attr "size" "64")
9554 (set_attr "length"
9555 "8, 8, 8, *, *, *,
9556 16, *, *, *, *, *,
9557 *, *, *, *, *, 8,
9558 *")
9559 (set_attr "isa"
9560 "*, *, *, *, *, *,
9561 *, p9v, p7v, p9v, p7v, *,
9562 p9v, p9v, p7v, *, *, p7v,
9563 p7v")])
9564
9565 (define_split
9566 [(set (match_operand:DI 0 "gpc_reg_operand")
9567 (match_operand:DI 1 "const_int_operand"))]
9568 "! TARGET_POWERPC64 && reload_completed
9569 && gpr_or_gpr_p (operands[0], operands[1])
9570 && !direct_move_p (operands[0], operands[1])"
9571 [(set (match_dup 2) (match_dup 4))
9572 (set (match_dup 3) (match_dup 1))]
9573 {
9574 HOST_WIDE_INT value = INTVAL (operands[1]);
9575 operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
9576 DImode);
9577 operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
9578 DImode);
9579 operands[4] = GEN_INT (value >> 32);
9580 operands[1] = GEN_INT (sext_hwi (value, 32));
9581 })
9582
9583 (define_split
9584 [(set (match_operand:DIFD 0 "nonimmediate_operand")
9585 (match_operand:DIFD 1 "input_operand"))]
9586 "reload_completed && !TARGET_POWERPC64
9587 && gpr_or_gpr_p (operands[0], operands[1])
9588 && !direct_move_p (operands[0], operands[1])"
9589 [(pc)]
9590 {
9591 rs6000_split_multireg_move (operands[0], operands[1]);
9592 DONE;
9593 })
9594
9595 ;; GPR store GPR load GPR move
9596 ;; GPR li GPR lis GPR pli GPR #
9597 ;; FPR store FPR load FPR move
9598 ;; AVX store AVX store AVX load AVX load VSX move
9599 ;; P9 0 P9 -1 AVX 0/-1 VSX 0 VSX -1
9600 ;; P9 const AVX const
9601 ;; From SPR To SPR SPR<->SPR
9602 ;; VSX->GPR GPR->VSX
9603 (define_insn "*movdi_internal64"
9604 [(set (match_operand:DI 0 "nonimmediate_operand"
9605 "=YZ, r, r,
9606 r, r, r, r,
9607 m, ^d, ^d,
9608 wY, Z, $v, $v, ^wa,
9609 wa, wa, v, wa, wa,
9610 v, v,
9611 r, *h, *h,
9612 ?r, ?wa")
9613 (match_operand:DI 1 "input_operand"
9614 "r, YZ, r,
9615 I, L, eI, nF,
9616 ^d, m, ^d,
9617 ^v, $v, wY, Z, ^wa,
9618 Oj, wM, OjwM, Oj, wM,
9619 wS, wB,
9620 *h, r, 0,
9621 wa, r"))]
9622 "TARGET_POWERPC64
9623 && (gpc_reg_operand (operands[0], DImode)
9624 || gpc_reg_operand (operands[1], DImode))"
9625 "@
9626 std%U0%X0 %1,%0
9627 ld%U1%X1 %0,%1
9628 mr %0,%1
9629 li %0,%1
9630 lis %0,%v1
9631 li %0,%1
9632 #
9633 stfd%U0%X0 %1,%0
9634 lfd%U1%X1 %0,%1
9635 fmr %0,%1
9636 stxsd %1,%0
9637 stxsdx %x1,%y0
9638 lxsd %0,%1
9639 lxsdx %x0,%y1
9640 xxlor %x0,%x1,%x1
9641 xxspltib %x0,0
9642 xxspltib %x0,255
9643 #
9644 xxlxor %x0,%x0,%x0
9645 xxlorc %x0,%x0,%x0
9646 #
9647 #
9648 mf%1 %0
9649 mt%0 %1
9650 nop
9651 mfvsrd %0,%x1
9652 mtvsrd %x0,%1"
9653 [(set_attr "type"
9654 "store, load, *,
9655 *, *, *, *,
9656 fpstore, fpload, fpsimple,
9657 fpstore, fpstore, fpload, fpload, veclogical,
9658 vecsimple, vecsimple, vecsimple, veclogical, veclogical,
9659 vecsimple, vecsimple,
9660 mfjmpr, mtjmpr, *,
9661 mfvsr, mtvsr")
9662 (set_attr "size" "64")
9663 (set_attr "length"
9664 "*, *, *,
9665 *, *, *, 20,
9666 *, *, *,
9667 *, *, *, *, *,
9668 *, *, *, *, *,
9669 8, *,
9670 *, *, *,
9671 *, *")
9672 (set_attr "isa"
9673 "*, *, *,
9674 *, *, p10, *,
9675 *, *, *,
9676 p9v, p7v, p9v, p7v, *,
9677 p9v, p9v, p7v, *, *,
9678 p7v, p7v,
9679 *, *, *,
9680 p8v, p8v")])
9681
9682 ; Some DImode loads are best done as a load of -1 followed by a mask
9683 ; instruction.
9684 (define_split
9685 [(set (match_operand:DI 0 "int_reg_operand")
9686 (match_operand:DI 1 "const_int_operand"))]
9687 "TARGET_POWERPC64
9688 && num_insns_constant (operands[1], DImode) > 1
9689 && !IN_RANGE (INTVAL (operands[1]), -0x80000000, 0xffffffff)
9690 && rs6000_is_valid_and_mask (operands[1], DImode)"
9691 [(set (match_dup 0)
9692 (const_int -1))
9693 (set (match_dup 0)
9694 (and:DI (match_dup 0)
9695 (match_dup 1)))]
9696 "")
9697
9698 ;; Split a load of a large constant into the appropriate five-instruction
9699 ;; sequence. Handle anything in a constant number of insns.
9700 ;; When non-easy constants can go in the TOC, this should use
9701 ;; easy_fp_constant predicate.
9702 (define_split
9703 [(set (match_operand:DI 0 "int_reg_operand")
9704 (match_operand:DI 1 "const_int_operand"))]
9705 "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
9706 [(pc)]
9707 {
9708 if (rs6000_emit_set_const (operands[0], operands[1]))
9709 DONE;
9710 else
9711 FAIL;
9712 })
9713
9714 (define_split
9715 [(set (match_operand:DI 0 "altivec_register_operand")
9716 (match_operand:DI 1 "s5bit_cint_operand"))]
9717 "TARGET_VSX && reload_completed"
9718 [(const_int 0)]
9719 {
9720 rtx op0 = operands[0];
9721 rtx op1 = operands[1];
9722 int r = REGNO (op0);
9723 rtx op0_v4si = gen_rtx_REG (V4SImode, r);
9724
9725 emit_insn (gen_altivec_vspltisw (op0_v4si, op1));
9726 if (op1 != const0_rtx && op1 != constm1_rtx)
9727 {
9728 rtx op0_v2di = gen_rtx_REG (V2DImode, r);
9729 emit_insn (gen_altivec_vupkhsw (op0_v2di, op0_v4si));
9730 }
9731 DONE;
9732 })
9733
9734 ;; Split integer constants that can be loaded with XXSPLTIB and a
9735 ;; sign extend operation.
9736 (define_split
9737 [(set (match_operand:INT_ISA3 0 "altivec_register_operand")
9738 (match_operand:INT_ISA3 1 "xxspltib_constant_split"))]
9739 "TARGET_P9_VECTOR && reload_completed"
9740 [(const_int 0)]
9741 {
9742 rtx op0 = operands[0];
9743 rtx op1 = operands[1];
9744 int r = REGNO (op0);
9745 rtx op0_v16qi = gen_rtx_REG (V16QImode, r);
9746
9747 emit_insn (gen_xxspltib_v16qi (op0_v16qi, op1));
9748 if (<MODE>mode == DImode)
9749 emit_insn (gen_vsx_sign_extend_qi_di (operands[0], op0_v16qi));
9750 else if (<MODE>mode == SImode)
9751 emit_insn (gen_vsx_sign_extend_qi_si (operands[0], op0_v16qi));
9752 else if (<MODE>mode == HImode)
9753 {
9754 rtx op0_v8hi = gen_rtx_REG (V8HImode, r);
9755 emit_insn (gen_altivec_vupkhsb (op0_v8hi, op0_v16qi));
9756 }
9757 DONE;
9758 })
9759
9760 \f
9761 ;; TImode/PTImode is similar, except that we usually want to compute the
9762 ;; address into a register and use lsi/stsi (the exception is during reload).
9763
9764 (define_insn "*mov<mode>_string"
9765 [(set (match_operand:TI2 0 "reg_or_mem_operand" "=Q,Y,????r,????r,????r,r")
9766 (match_operand:TI2 1 "input_operand" "r,r,Q,Y,r,n"))]
9767 "! TARGET_POWERPC64
9768 && (<MODE>mode != TImode || VECTOR_MEM_NONE_P (TImode))
9769 && (gpc_reg_operand (operands[0], <MODE>mode)
9770 || gpc_reg_operand (operands[1], <MODE>mode))"
9771 "#"
9772 [(set_attr "type" "store,store,load,load,*,*")
9773 (set_attr "update" "yes")
9774 (set_attr "indexed" "yes")
9775 (set_attr "cell_micro" "conditional")])
9776
9777 (define_insn "*mov<mode>_ppc64"
9778 [(set (match_operand:TI2 0 "nonimmediate_operand" "=wQ,Y,r,r,r,r")
9779 (match_operand:TI2 1 "input_operand" "r,r,wQ,Y,r,n"))]
9780 "(TARGET_POWERPC64 && VECTOR_MEM_NONE_P (<MODE>mode)
9781 && (gpc_reg_operand (operands[0], <MODE>mode)
9782 || gpc_reg_operand (operands[1], <MODE>mode)))"
9783 {
9784 return rs6000_output_move_128bit (operands);
9785 }
9786 [(set_attr "type" "store,store,load,load,*,*")
9787 (set_attr "length" "8")
9788 (set_attr "max_prefixed_insns" "2")])
9789
9790 (define_split
9791 [(set (match_operand:TI2 0 "int_reg_operand")
9792 (match_operand:TI2 1 "const_scalar_int_operand"))]
9793 "TARGET_POWERPC64
9794 && (VECTOR_MEM_NONE_P (<MODE>mode)
9795 || (reload_completed && INT_REGNO_P (REGNO (operands[0]))))"
9796 [(set (match_dup 2) (match_dup 4))
9797 (set (match_dup 3) (match_dup 5))]
9798 {
9799 operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
9800 <MODE>mode);
9801 operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
9802 <MODE>mode);
9803 if (CONST_WIDE_INT_P (operands[1]))
9804 {
9805 operands[4] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 1));
9806 operands[5] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 0));
9807 }
9808 else if (CONST_INT_P (operands[1]))
9809 {
9810 operands[4] = GEN_INT (- (INTVAL (operands[1]) < 0));
9811 operands[5] = operands[1];
9812 }
9813 else
9814 FAIL;
9815 })
9816
9817 (define_split
9818 [(set (match_operand:TI2 0 "nonimmediate_operand")
9819 (match_operand:TI2 1 "input_operand"))]
9820 "reload_completed
9821 && gpr_or_gpr_p (operands[0], operands[1])
9822 && !direct_move_p (operands[0], operands[1])
9823 && !quad_load_store_p (operands[0], operands[1])"
9824 [(pc)]
9825 {
9826 rs6000_split_multireg_move (operands[0], operands[1]);
9827 DONE;
9828 })
9829 \f
9830 (define_expand "setmemsi"
9831 [(parallel [(set (match_operand:BLK 0 "")
9832 (match_operand 2 "const_int_operand"))
9833 (use (match_operand:SI 1 ""))
9834 (use (match_operand:SI 3 ""))])]
9835 ""
9836 {
9837 /* If value to set is not zero, use the library routine. */
9838 if (operands[2] != const0_rtx)
9839 FAIL;
9840
9841 if (expand_block_clear (operands))
9842 DONE;
9843 else
9844 FAIL;
9845 })
9846
9847 ;; String compare N insn.
9848 ;; Argument 0 is the target (result)
9849 ;; Argument 1 is the destination
9850 ;; Argument 2 is the source
9851 ;; Argument 3 is the length
9852 ;; Argument 4 is the alignment
9853
9854 (define_expand "cmpstrnsi"
9855 [(parallel [(set (match_operand:SI 0)
9856 (compare:SI (match_operand:BLK 1)
9857 (match_operand:BLK 2)))
9858 (use (match_operand:SI 3))
9859 (use (match_operand:SI 4))])]
9860 "TARGET_CMPB && (BYTES_BIG_ENDIAN || TARGET_LDBRX)"
9861 {
9862 if (optimize_insn_for_size_p ())
9863 FAIL;
9864
9865 if (expand_strn_compare (operands, 0))
9866 DONE;
9867 else
9868 FAIL;
9869 })
9870
9871 ;; String compare insn.
9872 ;; Argument 0 is the target (result)
9873 ;; Argument 1 is the destination
9874 ;; Argument 2 is the source
9875 ;; Argument 3 is the alignment
9876
9877 (define_expand "cmpstrsi"
9878 [(parallel [(set (match_operand:SI 0)
9879 (compare:SI (match_operand:BLK 1)
9880 (match_operand:BLK 2)))
9881 (use (match_operand:SI 3))])]
9882 "TARGET_CMPB && (BYTES_BIG_ENDIAN || TARGET_LDBRX)"
9883 {
9884 if (optimize_insn_for_size_p ())
9885 FAIL;
9886
9887 if (expand_strn_compare (operands, 1))
9888 DONE;
9889 else
9890 FAIL;
9891 })
9892
9893 ;; Block compare insn.
9894 ;; Argument 0 is the target (result)
9895 ;; Argument 1 is the destination
9896 ;; Argument 2 is the source
9897 ;; Argument 3 is the length
9898 ;; Argument 4 is the alignment
9899
9900 (define_expand "cmpmemsi"
9901 [(parallel [(set (match_operand:SI 0)
9902 (compare:SI (match_operand:BLK 1)
9903 (match_operand:BLK 2)))
9904 (use (match_operand:SI 3))
9905 (use (match_operand:SI 4))])]
9906 "TARGET_POPCNTD"
9907 {
9908 if (expand_block_compare (operands))
9909 DONE;
9910 else
9911 FAIL;
9912 })
9913
9914 ;; String/block copy insn (source and destination must not overlap).
9915 ;; Argument 0 is the destination
9916 ;; Argument 1 is the source
9917 ;; Argument 2 is the length
9918 ;; Argument 3 is the alignment
9919
9920 (define_expand "cpymemsi"
9921 [(parallel [(set (match_operand:BLK 0 "")
9922 (match_operand:BLK 1 ""))
9923 (use (match_operand:SI 2 ""))
9924 (use (match_operand:SI 3 ""))])]
9925 ""
9926 {
9927 if (expand_block_move (operands, false))
9928 DONE;
9929 else
9930 FAIL;
9931 })
9932
9933 ;; String/block move insn (source and destination may overlap).
9934 ;; Argument 0 is the destination
9935 ;; Argument 1 is the source
9936 ;; Argument 2 is the length
9937 ;; Argument 3 is the alignment
9938
9939 (define_expand "movmemsi"
9940 [(parallel [(set (match_operand:BLK 0 "")
9941 (match_operand:BLK 1 ""))
9942 (use (match_operand:SI 2 ""))
9943 (use (match_operand:SI 3 ""))])]
9944 ""
9945 {
9946 if (expand_block_move (operands, true))
9947 DONE;
9948 else
9949 FAIL;
9950 })
9951
9952 \f
9953 ;; Define insns that do load or store with update. Some of these we can
9954 ;; get by using pre-decrement or pre-increment, but the hardware can also
9955 ;; do cases where the increment is not the size of the object.
9956 ;;
9957 ;; In all these cases, we use operands 0 and 1 for the register being
9958 ;; incremented because those are the operands that local-alloc will
9959 ;; tie and these are the pair most likely to be tieable (and the ones
9960 ;; that will benefit the most).
9961
9962 (define_insn "*movdi_update1"
9963 [(set (match_operand:DI 3 "gpc_reg_operand" "=r,r")
9964 (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9965 (match_operand:P 2 "reg_or_aligned_short_operand" "r,I"))))
9966 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9967 (plus:P (match_dup 1) (match_dup 2)))]
9968 "TARGET_POWERPC64 && TARGET_UPDATE
9969 && (!avoiding_indexed_address_p (DImode)
9970 || !gpc_reg_operand (operands[2], Pmode))"
9971 "@
9972 ldux %3,%0,%2
9973 ldu %3,%2(%0)"
9974 [(set_attr "type" "load")
9975 (set_attr "update" "yes")
9976 (set_attr "indexed" "yes,no")])
9977
9978 (define_insn "movdi_<mode>_update"
9979 [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9980 (match_operand:P 2 "reg_or_aligned_short_operand" "r,I")))
9981 (match_operand:DI 3 "gpc_reg_operand" "r,r"))
9982 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9983 (plus:P (match_dup 1) (match_dup 2)))]
9984 "TARGET_POWERPC64 && TARGET_UPDATE
9985 && (!avoiding_indexed_address_p (DImode)
9986 || !gpc_reg_operand (operands[2], Pmode)
9987 || (REG_P (operands[0])
9988 && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
9989 "@
9990 stdux %3,%0,%2
9991 stdu %3,%2(%0)"
9992 [(set_attr "type" "store")
9993 (set_attr "update" "yes")
9994 (set_attr "indexed" "yes,no")])
9995
9996 ;; This pattern is only conditional on TARGET_64BIT, as it is
9997 ;; needed for stack allocation, even if the user passes -mno-update.
9998 (define_insn "movdi_update_stack"
9999 [(set (mem:DI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0,0")
10000 (match_operand:DI 2 "reg_or_aligned_short_operand" "r,I")))
10001 (match_operand:DI 3 "gpc_reg_operand" "r,r"))
10002 (set (match_operand:DI 0 "gpc_reg_operand" "=b,b")
10003 (plus:DI (match_dup 1) (match_dup 2)))]
10004 "TARGET_64BIT"
10005 "@
10006 stdux %3,%0,%2
10007 stdu %3,%2(%0)"
10008 [(set_attr "type" "store")
10009 (set_attr "update" "yes")
10010 (set_attr "indexed" "yes,no")])
10011
10012 (define_insn "*movsi_update1"
10013 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
10014 (mem:SI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
10015 (match_operand:P 2 "reg_or_short_operand" "r,I"))))
10016 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
10017 (plus:P (match_dup 1) (match_dup 2)))]
10018 "TARGET_UPDATE
10019 && (!avoiding_indexed_address_p (SImode)
10020 || !gpc_reg_operand (operands[2], Pmode))"
10021 "@
10022 lwzux %3,%0,%2
10023 lwzu %3,%2(%0)"
10024 [(set_attr "type" "load")
10025 (set_attr "update" "yes")
10026 (set_attr "indexed" "yes,no")])
10027
10028 (define_insn "*movsi_update2"
10029 [(set (match_operand:EXTSI 3 "gpc_reg_operand" "=r")
10030 (sign_extend:EXTSI
10031 (mem:SI (plus:P (match_operand:P 1 "gpc_reg_operand" "0")
10032 (match_operand:P 2 "gpc_reg_operand" "r")))))
10033 (set (match_operand:P 0 "gpc_reg_operand" "=b")
10034 (plus:P (match_dup 1) (match_dup 2)))]
10035 "TARGET_POWERPC64 && !avoiding_indexed_address_p (DImode)"
10036 "lwaux %3,%0,%2"
10037 [(set_attr "type" "load")
10038 (set_attr "sign_extend" "yes")
10039 (set_attr "update" "yes")
10040 (set_attr "indexed" "yes")])
10041
10042 (define_insn "movsi_<mode>_update"
10043 [(set (mem:SI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
10044 (match_operand:P 2 "reg_or_short_operand" "r,I")))
10045 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
10046 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
10047 (plus:P (match_dup 1) (match_dup 2)))]
10048 "TARGET_UPDATE
10049 && (!avoiding_indexed_address_p (SImode)
10050 || !gpc_reg_operand (operands[2], Pmode)
10051 || (REG_P (operands[0])
10052 && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
10053 "@
10054 stwux %3,%0,%2
10055 stwu %3,%2(%0)"
10056 [(set_attr "type" "store")
10057 (set_attr "update" "yes")
10058 (set_attr "indexed" "yes,no")])
10059
10060 ;; This is an unconditional pattern; needed for stack allocation, even
10061 ;; if the user passes -mno-update.
10062 (define_insn "movsi_update_stack"
10063 [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
10064 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
10065 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
10066 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
10067 (plus:SI (match_dup 1) (match_dup 2)))]
10068 "TARGET_32BIT"
10069 "@
10070 stwux %3,%0,%2
10071 stwu %3,%2(%0)"
10072 [(set_attr "type" "store")
10073 (set_attr "update" "yes")
10074 (set_attr "indexed" "yes,no")])
10075
10076 (define_insn "*movhi_update1"
10077 [(set (match_operand:HI 3 "gpc_reg_operand" "=r,r")
10078 (mem:HI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
10079 (match_operand:P 2 "reg_or_short_operand" "r,I"))))
10080 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
10081 (plus:P (match_dup 1) (match_dup 2)))]
10082 "TARGET_UPDATE
10083 && (!avoiding_indexed_address_p (HImode)
10084 || !gpc_reg_operand (operands[2], SImode))"
10085 "@
10086 lhzux %3,%0,%2
10087 lhzu %3,%2(%0)"
10088 [(set_attr "type" "load")
10089 (set_attr "update" "yes")
10090 (set_attr "indexed" "yes,no")])
10091
10092 (define_insn "*movhi_update2"
10093 [(set (match_operand:EXTHI 3 "gpc_reg_operand" "=r,r")
10094 (zero_extend:EXTHI
10095 (mem:HI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
10096 (match_operand:P 2 "reg_or_short_operand" "r,I")))))
10097 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
10098 (plus:P (match_dup 1) (match_dup 2)))]
10099 "TARGET_UPDATE
10100 && (!avoiding_indexed_address_p (HImode)
10101 || !gpc_reg_operand (operands[2], Pmode))"
10102 "@
10103 lhzux %3,%0,%2
10104 lhzu %3,%2(%0)"
10105 [(set_attr "type" "load")
10106 (set_attr "update" "yes")
10107 (set_attr "indexed" "yes,no")])
10108
10109 (define_insn "*movhi_update3"
10110 [(set (match_operand:EXTHI 3 "gpc_reg_operand" "=r,r")
10111 (sign_extend:EXTHI
10112 (mem:HI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
10113 (match_operand:P 2 "reg_or_short_operand" "r,I")))))
10114 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
10115 (plus:P (match_dup 1) (match_dup 2)))]
10116 "TARGET_UPDATE
10117 && !(avoiding_indexed_address_p (HImode)
10118 && gpc_reg_operand (operands[2], Pmode))"
10119 "@
10120 lhaux %3,%0,%2
10121 lhau %3,%2(%0)"
10122 [(set_attr "type" "load")
10123 (set_attr "sign_extend" "yes")
10124 (set_attr "update" "yes")
10125 (set_attr "indexed" "yes,no")])
10126
10127 (define_insn "*movhi_update4"
10128 [(set (mem:HI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
10129 (match_operand:P 2 "reg_or_short_operand" "r,I")))
10130 (match_operand:HI 3 "gpc_reg_operand" "r,r"))
10131 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
10132 (plus:P (match_dup 1) (match_dup 2)))]
10133 "TARGET_UPDATE
10134 && (!avoiding_indexed_address_p (HImode)
10135 || !gpc_reg_operand (operands[2], Pmode))"
10136 "@
10137 sthux %3,%0,%2
10138 sthu %3,%2(%0)"
10139 [(set_attr "type" "store")
10140 (set_attr "update" "yes")
10141 (set_attr "indexed" "yes,no")])
10142
10143 (define_insn "*movqi_update1"
10144 [(set (match_operand:QI 3 "gpc_reg_operand" "=r,r")
10145 (mem:QI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
10146 (match_operand:P 2 "reg_or_short_operand" "r,I"))))
10147 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
10148 (plus:P (match_dup 1) (match_dup 2)))]
10149 "TARGET_UPDATE
10150 && (!avoiding_indexed_address_p (QImode)
10151 || !gpc_reg_operand (operands[2], Pmode))"
10152 "@
10153 lbzux %3,%0,%2
10154 lbzu %3,%2(%0)"
10155 [(set_attr "type" "load")
10156 (set_attr "update" "yes")
10157 (set_attr "indexed" "yes,no")])
10158
10159 (define_insn "*movqi_update2"
10160 [(set (match_operand:EXTQI 3 "gpc_reg_operand" "=r,r")
10161 (zero_extend:EXTQI
10162 (mem:QI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
10163 (match_operand:P 2 "reg_or_short_operand" "r,I")))))
10164 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
10165 (plus:P (match_dup 1) (match_dup 2)))]
10166 "TARGET_UPDATE
10167 && (!avoiding_indexed_address_p (QImode)
10168 || !gpc_reg_operand (operands[2], Pmode))"
10169 "@
10170 lbzux %3,%0,%2
10171 lbzu %3,%2(%0)"
10172 [(set_attr "type" "load")
10173 (set_attr "update" "yes")
10174 (set_attr "indexed" "yes,no")])
10175
10176 (define_insn "*movqi_update3"
10177 [(set (mem:QI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
10178 (match_operand:P 2 "reg_or_short_operand" "r,I")))
10179 (match_operand:QI 3 "gpc_reg_operand" "r,r"))
10180 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
10181 (plus:P (match_dup 1) (match_dup 2)))]
10182 "TARGET_UPDATE
10183 && (!avoiding_indexed_address_p (QImode)
10184 || !gpc_reg_operand (operands[2], Pmode))"
10185 "@
10186 stbux %3,%0,%2
10187 stbu %3,%2(%0)"
10188 [(set_attr "type" "store")
10189 (set_attr "update" "yes")
10190 (set_attr "indexed" "yes,no")])
10191
10192 (define_insn "*mov<SFDF:mode>_update1"
10193 [(set (match_operand:SFDF 3 "gpc_reg_operand" "=d,d")
10194 (mem:SFDF (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
10195 (match_operand:P 2 "reg_or_short_operand" "r,I"))))
10196 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
10197 (plus:P (match_dup 1) (match_dup 2)))]
10198 "TARGET_HARD_FLOAT && TARGET_UPDATE
10199 && (!avoiding_indexed_address_p (<SFDF:MODE>mode)
10200 || !gpc_reg_operand (operands[2], Pmode))"
10201 "@
10202 lf<sd>ux %3,%0,%2
10203 lf<sd>u %3,%2(%0)"
10204 [(set_attr "type" "fpload")
10205 (set_attr "update" "yes")
10206 (set_attr "indexed" "yes,no")
10207 (set_attr "size" "<SFDF:bits>")])
10208
10209 (define_insn "*mov<SFDF:mode>_update2"
10210 [(set (mem:SFDF (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
10211 (match_operand:P 2 "reg_or_short_operand" "r,I")))
10212 (match_operand:SFDF 3 "gpc_reg_operand" "d,d"))
10213 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
10214 (plus:P (match_dup 1) (match_dup 2)))]
10215 "TARGET_HARD_FLOAT && TARGET_UPDATE
10216 && (!avoiding_indexed_address_p (<SFDF:MODE>mode)
10217 || !gpc_reg_operand (operands[2], Pmode))"
10218 "@
10219 stf<sd>ux %3,%0,%2
10220 stf<sd>u %3,%2(%0)"
10221 [(set_attr "type" "fpstore")
10222 (set_attr "update" "yes")
10223 (set_attr "indexed" "yes,no")
10224 (set_attr "size" "<SFDF:bits>")])
10225
10226 (define_insn "*movsf_update3"
10227 [(set (match_operand:SF 3 "gpc_reg_operand" "=r,r")
10228 (mem:SF (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
10229 (match_operand:P 2 "reg_or_short_operand" "r,I"))))
10230 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
10231 (plus:P (match_dup 1) (match_dup 2)))]
10232 "TARGET_SOFT_FLOAT && TARGET_UPDATE
10233 && (!avoiding_indexed_address_p (SFmode)
10234 || !gpc_reg_operand (operands[2], Pmode))"
10235 "@
10236 lwzux %3,%0,%2
10237 lwzu %3,%2(%0)"
10238 [(set_attr "type" "load")
10239 (set_attr "update" "yes")
10240 (set_attr "indexed" "yes,no")])
10241
10242 (define_insn "*movsf_update4"
10243 [(set (mem:SF (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
10244 (match_operand:P 2 "reg_or_short_operand" "r,I")))
10245 (match_operand:SF 3 "gpc_reg_operand" "r,r"))
10246 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
10247 (plus:P (match_dup 1) (match_dup 2)))]
10248 "TARGET_SOFT_FLOAT && TARGET_UPDATE
10249 && (!avoiding_indexed_address_p (SFmode)
10250 || !gpc_reg_operand (operands[2], Pmode))"
10251 "@
10252 stwux %3,%0,%2
10253 stwu %3,%2(%0)"
10254 [(set_attr "type" "store")
10255 (set_attr "update" "yes")
10256 (set_attr "indexed" "yes,no")])
10257
10258
10259 ;; After inserting conditional returns we can sometimes have
10260 ;; unnecessary register moves. Unfortunately we cannot have a
10261 ;; modeless peephole here, because some single SImode sets have early
10262 ;; clobber outputs. Although those sets expand to multi-ppc-insn
10263 ;; sequences, using get_attr_length here will smash the operands
10264 ;; array. Neither is there an early_cobbler_p predicate.
10265 ;; Also this optimization interferes with scalars going into
10266 ;; altivec registers (the code does reloading through the FPRs).
10267 (define_peephole2
10268 [(set (match_operand:DF 0 "gpc_reg_operand")
10269 (match_operand:DF 1 "any_operand"))
10270 (set (match_operand:DF 2 "gpc_reg_operand")
10271 (match_dup 0))]
10272 "!TARGET_VSX
10273 && peep2_reg_dead_p (2, operands[0])"
10274 [(set (match_dup 2) (match_dup 1))])
10275
10276 (define_peephole2
10277 [(set (match_operand:SF 0 "gpc_reg_operand")
10278 (match_operand:SF 1 "any_operand"))
10279 (set (match_operand:SF 2 "gpc_reg_operand")
10280 (match_dup 0))]
10281 "!TARGET_P8_VECTOR
10282 && peep2_reg_dead_p (2, operands[0])"
10283 [(set (match_dup 2) (match_dup 1))])
10284
10285 \f
10286 ;; TLS support.
10287
10288 (define_insn "*tls_gd_pcrel<bits>"
10289 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
10290 (unspec:P [(match_operand:P 1 "rs6000_tls_symbol_ref" "")
10291 (const_int 0)]
10292 UNSPEC_TLSGD))]
10293 "HAVE_AS_TLS && TARGET_ELF"
10294 "la %0,%1@got@tlsgd@pcrel"
10295 [(set_attr "prefixed" "yes")])
10296
10297 (define_insn_and_split "*tls_gd<bits>"
10298 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
10299 (unspec:P [(match_operand:P 1 "rs6000_tls_symbol_ref" "")
10300 (match_operand:P 2 "gpc_reg_operand" "b")]
10301 UNSPEC_TLSGD))]
10302 "HAVE_AS_TLS && TARGET_ELF"
10303 "addi %0,%2,%1@got@tlsgd"
10304 "&& TARGET_CMODEL != CMODEL_SMALL"
10305 [(set (match_dup 3)
10306 (high:P
10307 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))
10308 (set (match_dup 0)
10309 (lo_sum:P (match_dup 3)
10310 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))]
10311 {
10312 operands[3] = gen_reg_rtx (<MODE>mode);
10313 }
10314 [(set (attr "length")
10315 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
10316 (const_int 8)
10317 (const_int 4)))])
10318
10319 (define_insn "*tls_gd_high<bits>"
10320 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
10321 (high:P
10322 (unspec:P [(match_operand:P 1 "rs6000_tls_symbol_ref" "")
10323 (match_operand:P 2 "gpc_reg_operand" "b")]
10324 UNSPEC_TLSGD)))]
10325 "HAVE_AS_TLS && TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10326 "addis %0,%2,%1@got@tlsgd@ha")
10327
10328 (define_insn "*tls_gd_low<bits>"
10329 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
10330 (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
10331 (unspec:P [(match_operand:P 2 "rs6000_tls_symbol_ref" "")
10332 (match_operand:P 3 "gpc_reg_operand" "b")]
10333 UNSPEC_TLSGD)))]
10334 "HAVE_AS_TLS && TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10335 "addi %0,%1,%2@got@tlsgd@l")
10336
10337 (define_insn "*tls_ld_pcrel<bits>"
10338 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
10339 (unspec:P [(const_int 0)]
10340 UNSPEC_TLSLD))]
10341 "HAVE_AS_TLS && TARGET_ELF"
10342 "la %0,%&@got@tlsld@pcrel"
10343 [(set_attr "prefixed" "yes")])
10344
10345 (define_insn_and_split "*tls_ld<bits>"
10346 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
10347 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")]
10348 UNSPEC_TLSLD))]
10349 "HAVE_AS_TLS && TARGET_ELF"
10350 "addi %0,%1,%&@got@tlsld"
10351 "&& TARGET_CMODEL != CMODEL_SMALL"
10352 [(set (match_dup 2)
10353 (high:P
10354 (unspec:P [(match_dup 1)] UNSPEC_TLSLD)))
10355 (set (match_dup 0)
10356 (lo_sum:P (match_dup 2)
10357 (unspec:P [(match_dup 1)] UNSPEC_TLSLD)))]
10358 {
10359 operands[2] = gen_reg_rtx (<MODE>mode);
10360 }
10361 [(set (attr "length")
10362 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
10363 (const_int 8)
10364 (const_int 4)))])
10365
10366 (define_insn "*tls_ld_high<bits>"
10367 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
10368 (high:P
10369 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")]
10370 UNSPEC_TLSLD)))]
10371 "HAVE_AS_TLS && TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10372 "addis %0,%1,%&@got@tlsld@ha")
10373
10374 (define_insn "*tls_ld_low<bits>"
10375 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
10376 (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
10377 (unspec:P [(match_operand:P 2 "gpc_reg_operand" "b")]
10378 UNSPEC_TLSLD)))]
10379 "HAVE_AS_TLS && TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10380 "addi %0,%1,%&@got@tlsld@l")
10381
10382 (define_insn "tls_dtprel_<bits>"
10383 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10384 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
10385 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
10386 UNSPEC_TLSDTPREL))]
10387 "HAVE_AS_TLS"
10388 "addi %0,%1,%2@dtprel"
10389 [(set (attr "prefixed")
10390 (if_then_else (match_test "rs6000_tls_size == 16")
10391 (const_string "no")
10392 (const_string "yes")))])
10393
10394 (define_insn "tls_dtprel_ha_<bits>"
10395 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10396 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
10397 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
10398 UNSPEC_TLSDTPRELHA))]
10399 "HAVE_AS_TLS"
10400 "addis %0,%1,%2@dtprel@ha")
10401
10402 (define_insn "tls_dtprel_lo_<bits>"
10403 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10404 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
10405 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
10406 UNSPEC_TLSDTPRELLO))]
10407 "HAVE_AS_TLS"
10408 "addi %0,%1,%2@dtprel@l")
10409
10410 (define_insn_and_split "tls_got_dtprel_<bits>"
10411 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10412 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
10413 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
10414 UNSPEC_TLSGOTDTPREL))]
10415 "HAVE_AS_TLS"
10416 "<ptrload> %0,%2@got@dtprel(%1)"
10417 "&& TARGET_CMODEL != CMODEL_SMALL"
10418 [(set (match_dup 3)
10419 (high:P
10420 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))
10421 (set (match_dup 0)
10422 (lo_sum:P (match_dup 3)
10423 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))]
10424 {
10425 operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
10426 }
10427 [(set (attr "length")
10428 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
10429 (const_int 8)
10430 (const_int 4)))])
10431
10432 (define_insn "*tls_got_dtprel_high<bits>"
10433 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
10434 (high:P
10435 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
10436 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
10437 UNSPEC_TLSGOTDTPREL)))]
10438 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
10439 "addis %0,%1,%2@got@dtprel@ha")
10440
10441 (define_insn "*tls_got_dtprel_low<bits>"
10442 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10443 (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
10444 (unspec:P [(match_operand:P 3 "gpc_reg_operand" "b")
10445 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
10446 UNSPEC_TLSGOTDTPREL)))]
10447 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
10448 "<ptrload> %0,%2@got@dtprel@l(%1)")
10449
10450 (define_insn "tls_tprel_<bits>"
10451 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10452 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
10453 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
10454 UNSPEC_TLSTPREL))]
10455 "HAVE_AS_TLS"
10456 "addi %0,%1,%2@tprel"
10457 [(set (attr "prefixed")
10458 (if_then_else (match_test "rs6000_tls_size == 16")
10459 (const_string "no")
10460 (const_string "yes")))])
10461
10462 (define_insn "tls_tprel_ha_<bits>"
10463 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10464 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
10465 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
10466 UNSPEC_TLSTPRELHA))]
10467 "HAVE_AS_TLS"
10468 "addis %0,%1,%2@tprel@ha")
10469
10470 (define_insn "tls_tprel_lo_<bits>"
10471 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10472 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
10473 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
10474 UNSPEC_TLSTPRELLO))]
10475 "HAVE_AS_TLS"
10476 "addi %0,%1,%2@tprel@l")
10477
10478 (define_insn "*tls_got_tprel_pcrel_<bits>"
10479 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
10480 (unspec:P [(const_int 0)
10481 (match_operand:P 1 "rs6000_tls_symbol_ref" "")]
10482 UNSPEC_TLSGOTTPREL))]
10483 "HAVE_AS_TLS"
10484 "<ptrload> %0,%1@got@tprel@pcrel"
10485 [(set_attr "prefixed" "yes")])
10486
10487 ;; "b" output constraint here and on tls_tls input to support linker tls
10488 ;; optimization. The linker may edit the instructions emitted by a
10489 ;; tls_got_tprel/tls_tls pair to addis,addi.
10490 (define_insn_and_split "tls_got_tprel_<bits>"
10491 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
10492 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
10493 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
10494 UNSPEC_TLSGOTTPREL))]
10495 "HAVE_AS_TLS"
10496 "<ptrload> %0,%2@got@tprel(%1)"
10497 "&& TARGET_CMODEL != CMODEL_SMALL"
10498 [(set (match_dup 3)
10499 (high:P
10500 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))
10501 (set (match_dup 0)
10502 (lo_sum:P (match_dup 3)
10503 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))]
10504 {
10505 operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
10506 }
10507 [(set (attr "length")
10508 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
10509 (const_int 8)
10510 (const_int 4)))])
10511
10512 (define_insn "*tls_got_tprel_high<bits>"
10513 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
10514 (high:P
10515 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
10516 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
10517 UNSPEC_TLSGOTTPREL)))]
10518 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
10519 "addis %0,%1,%2@got@tprel@ha")
10520
10521 (define_insn "*tls_got_tprel_low<bits>"
10522 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10523 (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
10524 (unspec:P [(match_operand:P 3 "gpc_reg_operand" "b")
10525 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
10526 UNSPEC_TLSGOTTPREL)))]
10527 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
10528 "<ptrload> %0,%2@got@tprel@l(%1)")
10529
10530 (define_insn "tls_tls_pcrel_<bits>"
10531 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10532 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
10533 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
10534 UNSPEC_TLSTLS_PCREL))]
10535 "TARGET_ELF && HAVE_AS_TLS"
10536 "add %0,%1,%2@tls@pcrel")
10537
10538 (define_insn "tls_tls_<bits>"
10539 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10540 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
10541 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
10542 UNSPEC_TLSTLS))]
10543 "TARGET_ELF && HAVE_AS_TLS"
10544 "add %0,%1,%2@tls")
10545
10546 (define_expand "tls_get_tpointer"
10547 [(set (match_operand:SI 0 "gpc_reg_operand")
10548 (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))]
10549 "TARGET_XCOFF && HAVE_AS_TLS"
10550 {
10551 emit_insn (gen_tls_get_tpointer_internal ());
10552 emit_move_insn (operands[0], gen_rtx_REG (SImode, 3));
10553 DONE;
10554 })
10555
10556 (define_insn "tls_get_tpointer_internal"
10557 [(set (reg:SI 3)
10558 (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))
10559 (clobber (reg:SI LR_REGNO))]
10560 "TARGET_XCOFF && HAVE_AS_TLS"
10561 "bla .__get_tpointer")
10562
10563 (define_expand "tls_get_addr<mode>"
10564 [(set (match_operand:P 0 "gpc_reg_operand")
10565 (unspec:P [(match_operand:P 1 "gpc_reg_operand")
10566 (match_operand:P 2 "gpc_reg_operand")] UNSPEC_TLSTLS))]
10567 "TARGET_XCOFF && HAVE_AS_TLS"
10568 {
10569 emit_move_insn (gen_rtx_REG (Pmode, 3), operands[1]);
10570 emit_move_insn (gen_rtx_REG (Pmode, 4), operands[2]);
10571 emit_insn (gen_tls_get_addr_internal<mode> ());
10572 emit_move_insn (operands[0], gen_rtx_REG (Pmode, 3));
10573 DONE;
10574 })
10575
10576 (define_insn "tls_get_addr_internal<mode>"
10577 [(set (reg:P 3)
10578 (unspec:P [(reg:P 3) (reg:P 4)] UNSPEC_TLSTLS))
10579 (clobber (reg:P 0))
10580 (clobber (reg:P 4))
10581 (clobber (reg:P 5))
10582 (clobber (reg:P 11))
10583 (clobber (reg:CC CR0_REGNO))
10584 (clobber (reg:P LR_REGNO))]
10585 "TARGET_XCOFF && HAVE_AS_TLS"
10586 "bla .__tls_get_addr")
10587 \f
10588 ;; Next come insns related to the calling sequence.
10589 ;;
10590 ;; First, an insn to allocate new stack space for dynamic use (e.g., alloca).
10591 ;; We move the back-chain and decrement the stack pointer.
10592 ;;
10593 ;; Operand1 is more naturally reg_or_short_operand. However, for a large
10594 ;; constant alloca, using that predicate will force the generic code to put
10595 ;; the constant size into a register before calling the expander.
10596 ;;
10597 ;; As a result the expander would not have the constant size information
10598 ;; in those cases and would have to generate less efficient code.
10599 ;;
10600 ;; Thus we allow reg_or_cint_operand instead so that the expander can see
10601 ;; the constant size. The value is forced into a register if necessary.
10602 ;;
10603 (define_expand "allocate_stack"
10604 [(set (match_operand 0 "gpc_reg_operand")
10605 (minus (reg 1) (match_operand 1 "reg_or_cint_operand")))
10606 (set (reg 1)
10607 (minus (reg 1) (match_dup 1)))]
10608 ""
10609 {
10610 rtx chain = gen_reg_rtx (Pmode);
10611 rtx stack_bot = gen_rtx_MEM (Pmode, stack_pointer_rtx);
10612 rtx neg_op0;
10613 rtx insn, par, set, mem;
10614
10615 /* By allowing reg_or_cint_operand as the predicate we can get
10616 better code for stack-clash-protection because we do not lose
10617 size information. But the rest of the code expects the operand
10618 to be reg_or_short_operand. If it isn't, then force it into
10619 a register. */
10620 rtx orig_op1 = operands[1];
10621 if (!reg_or_short_operand (operands[1], Pmode))
10622 operands[1] = force_reg (Pmode, operands[1]);
10623
10624 emit_move_insn (chain, stack_bot);
10625
10626 /* Check stack bounds if necessary. */
10627 if (crtl->limit_stack)
10628 {
10629 rtx available;
10630 available = expand_binop (Pmode, sub_optab,
10631 stack_pointer_rtx, stack_limit_rtx,
10632 NULL_RTX, 1, OPTAB_WIDEN);
10633 emit_insn (gen_cond_trap (LTU, available, operands[1], const0_rtx));
10634 }
10635
10636 /* Allocate and probe if requested.
10637 This may look similar to the loop we use for prologue allocations,
10638 but it is critically different. For the former we know the loop
10639 will iterate, but do not know that generally here. The former
10640 uses that knowledge to rotate the loop. Combining them would be
10641 possible with some performance cost. */
10642 if (flag_stack_clash_protection)
10643 {
10644 rtx rounded_size, last_addr, residual;
10645 HOST_WIDE_INT probe_interval;
10646 compute_stack_clash_protection_loop_data (&rounded_size, &last_addr,
10647 &residual, &probe_interval,
10648 orig_op1);
10649
10650 /* We do occasionally get in here with constant sizes, we might
10651 as well do a reasonable job when we obviously can. */
10652 if (rounded_size != const0_rtx)
10653 {
10654 rtx loop_lab, end_loop;
10655 bool rotated = CONST_INT_P (rounded_size);
10656 rtx update = GEN_INT (-probe_interval);
10657 if (probe_interval > 32768)
10658 update = force_reg (Pmode, update);
10659
10660 emit_stack_clash_protection_probe_loop_start (&loop_lab, &end_loop,
10661 last_addr, rotated);
10662
10663 if (TARGET_32BIT)
10664 emit_insn (gen_movsi_update_stack (stack_pointer_rtx,
10665 stack_pointer_rtx,
10666 update, chain));
10667 else
10668 emit_insn (gen_movdi_update_stack (stack_pointer_rtx,
10669 stack_pointer_rtx,
10670 update, chain));
10671 emit_stack_clash_protection_probe_loop_end (loop_lab, end_loop,
10672 last_addr, rotated);
10673 }
10674
10675 /* Now handle residuals. We just have to set operands[1] correctly
10676 and let the rest of the expander run. */
10677 operands[1] = residual;
10678 }
10679
10680 if (!(CONST_INT_P (operands[1])
10681 && IN_RANGE (INTVAL (operands[1]), -32767, 32768)))
10682 {
10683 operands[1] = force_reg (Pmode, operands[1]);
10684 neg_op0 = gen_reg_rtx (Pmode);
10685 emit_insn (gen_neg2 (Pmode, neg_op0, operands[1]));
10686 }
10687 else
10688 neg_op0 = GEN_INT (-INTVAL (operands[1]));
10689
10690 insn = emit_insn ((* ((TARGET_32BIT) ? gen_movsi_update_stack
10691 : gen_movdi_update_stack))
10692 (stack_pointer_rtx, stack_pointer_rtx, neg_op0,
10693 chain));
10694 /* Since we didn't use gen_frame_mem to generate the MEM, grab
10695 it now and set the alias set/attributes. The above gen_*_update
10696 calls will generate a PARALLEL with the MEM set being the first
10697 operation. */
10698 par = PATTERN (insn);
10699 gcc_assert (GET_CODE (par) == PARALLEL);
10700 set = XVECEXP (par, 0, 0);
10701 gcc_assert (GET_CODE (set) == SET);
10702 mem = SET_DEST (set);
10703 gcc_assert (MEM_P (mem));
10704 MEM_NOTRAP_P (mem) = 1;
10705 set_mem_alias_set (mem, get_frame_alias_set ());
10706
10707 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
10708 DONE;
10709 })
10710
10711 ;; These patterns say how to save and restore the stack pointer. We need not
10712 ;; save the stack pointer at function level since we are careful to
10713 ;; preserve the backchain. At block level, we have to restore the backchain
10714 ;; when we restore the stack pointer.
10715 ;;
10716 ;; For nonlocal gotos, we must save both the stack pointer and its
10717 ;; backchain and restore both. Note that in the nonlocal case, the
10718 ;; save area is a memory location.
10719
10720 (define_expand "save_stack_function"
10721 [(match_operand 0 "any_operand")
10722 (match_operand 1 "any_operand")]
10723 ""
10724 "DONE;")
10725
10726 (define_expand "restore_stack_function"
10727 [(match_operand 0 "any_operand")
10728 (match_operand 1 "any_operand")]
10729 ""
10730 "DONE;")
10731
10732 ;; Adjust stack pointer (op0) to a new value (op1).
10733 ;; First copy old stack backchain to new location, and ensure that the
10734 ;; scheduler won't reorder the sp assignment before the backchain write.
10735 (define_expand "restore_stack_block"
10736 [(set (match_dup 2) (match_dup 3))
10737 (set (match_dup 4) (match_dup 2))
10738 (match_dup 5)
10739 (set (match_operand 0 "register_operand")
10740 (match_operand 1 "register_operand"))]
10741 ""
10742 {
10743 rtvec p;
10744
10745 operands[1] = force_reg (Pmode, operands[1]);
10746 operands[2] = gen_reg_rtx (Pmode);
10747 operands[3] = gen_frame_mem (Pmode, operands[0]);
10748 operands[4] = gen_frame_mem (Pmode, operands[1]);
10749 p = rtvec_alloc (1);
10750 RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
10751 const0_rtx);
10752 operands[5] = gen_rtx_PARALLEL (VOIDmode, p);
10753 })
10754
10755 (define_expand "save_stack_nonlocal"
10756 [(set (match_dup 3) (match_dup 4))
10757 (set (match_operand 0 "memory_operand") (match_dup 3))
10758 (set (match_dup 2) (match_operand 1 "register_operand"))]
10759 ""
10760 {
10761 int units_per_word = (TARGET_32BIT) ? 4 : 8;
10762
10763 /* Copy the backchain to the first word, sp to the second. */
10764 operands[0] = adjust_address_nv (operands[0], Pmode, 0);
10765 operands[2] = adjust_address_nv (operands[0], Pmode, units_per_word);
10766 operands[3] = gen_reg_rtx (Pmode);
10767 operands[4] = gen_frame_mem (Pmode, operands[1]);
10768 })
10769
10770 (define_expand "restore_stack_nonlocal"
10771 [(set (match_dup 2) (match_operand 1 "memory_operand"))
10772 (set (match_dup 3) (match_dup 4))
10773 (set (match_dup 5) (match_dup 2))
10774 (match_dup 6)
10775 (set (match_operand 0 "register_operand") (match_dup 3))]
10776 ""
10777 {
10778 int units_per_word = (TARGET_32BIT) ? 4 : 8;
10779 rtvec p;
10780
10781 /* Restore the backchain from the first word, sp from the second. */
10782 operands[2] = gen_reg_rtx (Pmode);
10783 operands[3] = gen_reg_rtx (Pmode);
10784 operands[1] = adjust_address_nv (operands[1], Pmode, 0);
10785 operands[4] = adjust_address_nv (operands[1], Pmode, units_per_word);
10786 operands[5] = gen_frame_mem (Pmode, operands[3]);
10787 p = rtvec_alloc (1);
10788 RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
10789 const0_rtx);
10790 operands[6] = gen_rtx_PARALLEL (VOIDmode, p);
10791 })
10792 \f
10793 ;; Load up a PC-relative address. Print_operand_address will append a @pcrel
10794 ;; to the symbol or label.
10795 (define_insn "*pcrel_local_addr"
10796 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
10797 (match_operand:DI 1 "pcrel_local_address"))]
10798 "TARGET_PCREL"
10799 "la %0,%a1"
10800 [(set_attr "prefixed" "yes")])
10801
10802 ;; Load up a PC-relative address to an external symbol. If the symbol and the
10803 ;; program are both defined in the main program, the linker will optimize this
10804 ;; to a PADDI. Otherwise, it will create a GOT address that is relocated by
10805 ;; the dynamic linker and loaded up. Print_operand_address will append a
10806 ;; @got@pcrel to the symbol.
10807 (define_insn "*pcrel_extern_addr"
10808 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
10809 (match_operand:DI 1 "pcrel_external_address"))]
10810 "TARGET_PCREL"
10811 "ld %0,%a1"
10812 [(set_attr "prefixed" "yes")
10813 (set_attr "type" "load")
10814 (set_attr "loads_external_address" "yes")])
10815
10816 ;; TOC register handling.
10817
10818 ;; Code to initialize the TOC register...
10819
10820 (define_insn "load_toc_aix_si"
10821 [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10822 (unspec:SI [(const_int 0)] UNSPEC_TOC))
10823 (use (reg:SI 2))])]
10824 "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_32BIT"
10825 {
10826 char buf[30];
10827 extern int need_toc_init;
10828 need_toc_init = 1;
10829 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
10830 operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
10831 operands[2] = gen_rtx_REG (Pmode, 2);
10832 return "lwz %0,%1(%2)";
10833 }
10834 [(set_attr "type" "load")
10835 (set_attr "update" "no")
10836 (set_attr "indexed" "no")])
10837
10838 (define_insn "load_toc_aix_di"
10839 [(parallel [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
10840 (unspec:DI [(const_int 0)] UNSPEC_TOC))
10841 (use (reg:DI 2))])]
10842 "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_64BIT"
10843 {
10844 char buf[30];
10845 extern int need_toc_init;
10846 need_toc_init = 1;
10847 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC",
10848 !TARGET_ELF || !TARGET_MINIMAL_TOC);
10849 if (TARGET_ELF)
10850 strcat (buf, "@toc");
10851 operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
10852 operands[2] = gen_rtx_REG (Pmode, 2);
10853 return "ld %0,%1(%2)";
10854 }
10855 [(set_attr "type" "load")
10856 (set_attr "update" "no")
10857 (set_attr "indexed" "no")])
10858
10859 (define_insn "load_toc_v4_pic_si"
10860 [(set (reg:SI LR_REGNO)
10861 (unspec:SI [(const_int 0)] UNSPEC_TOC))]
10862 "DEFAULT_ABI == ABI_V4 && flag_pic == 1 && TARGET_32BIT"
10863 "bl _GLOBAL_OFFSET_TABLE_@local-4"
10864 [(set_attr "type" "branch")])
10865
10866 (define_expand "load_toc_v4_PIC_1"
10867 [(parallel [(set (reg:SI LR_REGNO)
10868 (match_operand:SI 0 "immediate_operand" "s"))
10869 (use (unspec [(match_dup 0)] UNSPEC_TOC))])]
10870 "TARGET_ELF && DEFAULT_ABI == ABI_V4
10871 && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10872 "")
10873
10874 (define_insn "load_toc_v4_PIC_1_normal"
10875 [(set (reg:SI LR_REGNO)
10876 (match_operand:SI 0 "immediate_operand" "s"))
10877 (use (unspec [(match_dup 0)] UNSPEC_TOC))]
10878 "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
10879 && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10880 "bcl 20,31,%0\n%0:"
10881 [(set_attr "type" "branch")
10882 (set_attr "cannot_copy" "yes")])
10883
10884 (define_insn "load_toc_v4_PIC_1_476"
10885 [(set (reg:SI LR_REGNO)
10886 (match_operand:SI 0 "immediate_operand" "s"))
10887 (use (unspec [(match_dup 0)] UNSPEC_TOC))]
10888 "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
10889 && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10890 {
10891 char name[32];
10892 static char templ[32];
10893
10894 get_ppc476_thunk_name (name);
10895 sprintf (templ, "bl %s\n%%0:", name);
10896 return templ;
10897 }
10898 [(set_attr "type" "branch")
10899 (set_attr "cannot_copy" "yes")])
10900
10901 (define_expand "load_toc_v4_PIC_1b"
10902 [(parallel [(set (reg:SI LR_REGNO)
10903 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10904 (label_ref (match_operand 1 ""))]
10905 UNSPEC_TOCPTR))
10906 (match_dup 1)])]
10907 "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10908 "")
10909
10910 (define_insn "load_toc_v4_PIC_1b_normal"
10911 [(set (reg:SI LR_REGNO)
10912 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10913 (label_ref (match_operand 1 "" ""))]
10914 UNSPEC_TOCPTR))
10915 (match_dup 1)]
10916 "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10917 "bcl 20,31,$+8\;.long %0-$"
10918 [(set_attr "type" "branch")
10919 (set_attr "length" "8")])
10920
10921 (define_insn "load_toc_v4_PIC_1b_476"
10922 [(set (reg:SI LR_REGNO)
10923 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10924 (label_ref (match_operand 1 "" ""))]
10925 UNSPEC_TOCPTR))
10926 (match_dup 1)]
10927 "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10928 {
10929 char name[32];
10930 static char templ[32];
10931
10932 get_ppc476_thunk_name (name);
10933 sprintf (templ, "bl %s\;b $+8\;.long %%0-$", name);
10934 return templ;
10935 }
10936 [(set_attr "type" "branch")
10937 (set_attr "length" "16")])
10938
10939 (define_insn "load_toc_v4_PIC_2"
10940 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10941 (mem:SI (plus:SI
10942 (match_operand:SI 1 "gpc_reg_operand" "b")
10943 (const
10944 (minus:SI (match_operand:SI 2 "immediate_operand" "s")
10945 (match_operand:SI 3 "immediate_operand" "s"))))))]
10946 "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10947 "lwz %0,%2-%3(%1)"
10948 [(set_attr "type" "load")])
10949
10950 (define_insn "load_toc_v4_PIC_3b"
10951 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10952 (plus:SI
10953 (match_operand:SI 1 "gpc_reg_operand" "b")
10954 (high:SI
10955 (const
10956 (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
10957 (match_operand:SI 3 "symbol_ref_operand" "s"))))))]
10958 "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
10959 "addis %0,%1,%2-%3@ha")
10960
10961 (define_insn "load_toc_v4_PIC_3c"
10962 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10963 (lo_sum:SI
10964 (match_operand:SI 1 "gpc_reg_operand" "b")
10965 (const
10966 (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
10967 (match_operand:SI 3 "symbol_ref_operand" "s")))))]
10968 "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
10969 "addi %0,%1,%2-%3@l")
10970
10971 ;; If the TOC is shared over a translation unit, as happens with all
10972 ;; the kinds of PIC that we support, we need to restore the TOC
10973 ;; pointer only when jumping over units of translation.
10974 ;; On Darwin, we need to reload the picbase.
10975
10976 (define_expand "builtin_setjmp_receiver"
10977 [(use (label_ref (match_operand 0 "")))]
10978 "(DEFAULT_ABI == ABI_V4 && flag_pic == 1)
10979 || (TARGET_TOC && TARGET_MINIMAL_TOC)
10980 || (DEFAULT_ABI == ABI_DARWIN && flag_pic)"
10981 {
10982 #if TARGET_MACHO
10983 if (DEFAULT_ABI == ABI_DARWIN)
10984 {
10985 rtx picrtx = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME);
10986 rtx picreg = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
10987 rtx tmplabrtx;
10988 char tmplab[20];
10989
10990 crtl->uses_pic_offset_table = 1;
10991 ASM_GENERATE_INTERNAL_LABEL(tmplab, "LSJR",
10992 CODE_LABEL_NUMBER (operands[0]));
10993 tmplabrtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (tmplab));
10994
10995 emit_insn (gen_load_macho_picbase (Pmode, tmplabrtx));
10996 emit_move_insn (picreg, gen_rtx_REG (Pmode, LR_REGNO));
10997 emit_insn (gen_macho_correct_pic (Pmode, picreg, picreg,
10998 picrtx, tmplabrtx));
10999 }
11000 else
11001 #endif
11002 rs6000_emit_load_toc_table (FALSE);
11003 DONE;
11004 })
11005
11006 ;; Largetoc support
11007 (define_insn "*largetoc_high"
11008 [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
11009 (high:DI
11010 (unspec [(match_operand:DI 1 "" "")
11011 (match_operand:DI 2 "gpc_reg_operand" "b")]
11012 UNSPEC_TOCREL)))]
11013 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
11014 "addis %0,%2,%1@toc@ha")
11015
11016 (define_insn "*largetoc_high_aix<mode>"
11017 [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
11018 (high:P
11019 (unspec [(match_operand:P 1 "" "")
11020 (match_operand:P 2 "gpc_reg_operand" "b")]
11021 UNSPEC_TOCREL)))]
11022 "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
11023 "addis %0,%1@u(%2)")
11024
11025 (define_insn "*largetoc_high_plus"
11026 [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
11027 (high:DI
11028 (plus:DI
11029 (unspec [(match_operand:DI 1 "" "")
11030 (match_operand:DI 2 "gpc_reg_operand" "b")]
11031 UNSPEC_TOCREL)
11032 (match_operand:DI 3 "add_cint_operand" "n"))))]
11033 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
11034 "addis %0,%2,%1+%3@toc@ha")
11035
11036 (define_insn "*largetoc_high_plus_aix<mode>"
11037 [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
11038 (high:P
11039 (plus:P
11040 (unspec [(match_operand:P 1 "" "")
11041 (match_operand:P 2 "gpc_reg_operand" "b")]
11042 UNSPEC_TOCREL)
11043 (match_operand:P 3 "add_cint_operand" "n"))))]
11044 "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
11045 "addis %0,%1+%3@u(%2)")
11046
11047 (define_insn "*largetoc_low"
11048 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
11049 (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b")
11050 (match_operand:DI 2 "" "")))]
11051 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
11052 "addi %0,%1,%2@l")
11053
11054 (define_insn "*largetoc_low_aix<mode>"
11055 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11056 (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
11057 (match_operand:P 2 "" "")))]
11058 "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
11059 "la %0,%2@l(%1)")
11060
11061 (define_insn_and_split "*tocref<mode>"
11062 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
11063 (match_operand:P 1 "small_toc_ref" "R"))]
11064 "TARGET_TOC
11065 && legitimate_constant_pool_address_p (operands[1], QImode, false)"
11066 "la %0,%a1"
11067 "&& TARGET_CMODEL != CMODEL_SMALL && reload_completed"
11068 [(set (match_dup 0) (high:P (match_dup 1)))
11069 (set (match_dup 0) (lo_sum:P (match_dup 0) (match_dup 1)))])
11070
11071 ;; Elf specific ways of loading addresses for non-PIC code.
11072 ;; The output of this could be r0, but we make a very strong
11073 ;; preference for a base register because it will usually
11074 ;; be needed there.
11075 (define_insn "elf_high"
11076 [(set (match_operand:SI 0 "gpc_reg_operand" "=b*r")
11077 (high:SI (match_operand 1 "" "")))]
11078 "TARGET_ELF && !TARGET_64BIT && !flag_pic"
11079 "lis %0,%1@ha")
11080
11081 (define_insn "elf_low"
11082 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11083 (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
11084 (match_operand 2 "" "")))]
11085 "TARGET_ELF && !TARGET_64BIT && !flag_pic"
11086 "la %0,%2@l(%1)")
11087
11088 (define_insn "*pltseq_tocsave_<mode>"
11089 [(set (match_operand:P 0 "memory_operand" "=m")
11090 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
11091 (match_operand:P 2 "symbol_ref_operand" "s")
11092 (match_operand:P 3 "" "")]
11093 UNSPEC_PLTSEQ))]
11094 "TARGET_PLTSEQ
11095 && DEFAULT_ABI == ABI_ELFv2"
11096 {
11097 return rs6000_pltseq_template (operands, RS6000_PLTSEQ_TOCSAVE);
11098 })
11099
11100 (define_insn "*pltseq_plt16_ha_<mode>"
11101 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11102 (unspec:P [(match_operand:P 1 "" "")
11103 (match_operand:P 2 "symbol_ref_operand" "s")
11104 (match_operand:P 3 "" "")]
11105 UNSPEC_PLT16_HA))]
11106 "TARGET_PLTSEQ"
11107 {
11108 return rs6000_pltseq_template (operands, RS6000_PLTSEQ_PLT16_HA);
11109 })
11110
11111 (define_insn "*pltseq_plt16_lo_<mode>"
11112 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11113 (unspec_volatile:P [(match_operand:P 1 "gpc_reg_operand" "b")
11114 (match_operand:P 2 "symbol_ref_operand" "s")
11115 (match_operand:P 3 "" "")]
11116 UNSPECV_PLT16_LO))]
11117 "TARGET_PLTSEQ"
11118 {
11119 return rs6000_pltseq_template (operands, RS6000_PLTSEQ_PLT16_LO);
11120 }
11121 [(set_attr "type" "load")])
11122
11123 (define_insn "*pltseq_mtctr_<mode>"
11124 [(set (match_operand:P 0 "register_operand" "=c")
11125 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "r")
11126 (match_operand:P 2 "symbol_ref_operand" "s")
11127 (match_operand:P 3 "" "")]
11128 UNSPEC_PLTSEQ))]
11129 "TARGET_PLTSEQ"
11130 {
11131 return rs6000_pltseq_template (operands, RS6000_PLTSEQ_MTCTR);
11132 })
11133
11134 (define_insn "*pltseq_plt_pcrel<mode>"
11135 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11136 (unspec_volatile:P [(match_operand:P 1 "" "")
11137 (match_operand:P 2 "symbol_ref_operand" "s")
11138 (match_operand:P 3 "" "")]
11139 UNSPECV_PLT_PCREL))]
11140 "HAVE_AS_PLTSEQ && TARGET_ELF
11141 && rs6000_pcrel_p ()"
11142 {
11143 return rs6000_pltseq_template (operands, RS6000_PLTSEQ_PLT_PCREL34);
11144 }
11145 [(set_attr "type" "load")
11146 (set_attr "length" "12")])
11147 \f
11148 ;; Call and call_value insns
11149 ;; For the purposes of expanding calls, Darwin is very similar to SYSV.
11150 (define_expand "call"
11151 [(parallel [(call (mem:SI (match_operand 0 "address_operand"))
11152 (match_operand 1 ""))
11153 (use (match_operand 2 ""))
11154 (clobber (reg:SI LR_REGNO))])]
11155 ""
11156 {
11157 #if TARGET_MACHO
11158 if (MACHOPIC_INDIRECT)
11159 operands[0] = machopic_indirect_call_target (operands[0]);
11160 #endif
11161
11162 gcc_assert (MEM_P (operands[0]));
11163
11164 operands[0] = XEXP (operands[0], 0);
11165
11166 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
11167 rs6000_call_aix (NULL_RTX, operands[0], operands[1], operands[2]);
11168 else if (DEFAULT_ABI == ABI_V4)
11169 rs6000_call_sysv (NULL_RTX, operands[0], operands[1], operands[2]);
11170 else if (DEFAULT_ABI == ABI_DARWIN)
11171 rs6000_call_darwin (NULL_RTX, operands[0], operands[1], operands[2]);
11172 else
11173 gcc_unreachable ();
11174
11175 DONE;
11176 })
11177
11178 (define_expand "call_value"
11179 [(parallel [(set (match_operand 0 "")
11180 (call (mem:SI (match_operand 1 "address_operand"))
11181 (match_operand 2 "")))
11182 (use (match_operand 3 ""))
11183 (clobber (reg:SI LR_REGNO))])]
11184 ""
11185 {
11186 #if TARGET_MACHO
11187 if (MACHOPIC_INDIRECT)
11188 operands[1] = machopic_indirect_call_target (operands[1]);
11189 #endif
11190
11191 gcc_assert (MEM_P (operands[1]));
11192
11193 operands[1] = XEXP (operands[1], 0);
11194
11195 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
11196 rs6000_call_aix (operands[0], operands[1], operands[2], operands[3]);
11197 else if (DEFAULT_ABI == ABI_V4)
11198 rs6000_call_sysv (operands[0], operands[1], operands[2], operands[3]);
11199 else if (DEFAULT_ABI == ABI_DARWIN)
11200 rs6000_call_darwin (operands[0], operands[1], operands[2], operands[3]);
11201 else
11202 gcc_unreachable ();
11203
11204 DONE;
11205 })
11206
11207 ;; Call to function in current module. No TOC pointer reload needed.
11208 ;; Operand2 is nonzero if we are using the V.4 calling sequence and
11209 ;; either the function was not prototyped, or it was prototyped as a
11210 ;; variable argument function. It is > 0 if FP registers were passed
11211 ;; and < 0 if they were not.
11212
11213 (define_insn "*call_local<mode>"
11214 [(call (mem:SI (match_operand:P 0 "current_file_function_operand" "s,s"))
11215 (match_operand 1))
11216 (use (match_operand:SI 2 "immediate_operand" "O,n"))
11217 (clobber (reg:P LR_REGNO))]
11218 "(INTVAL (operands[2]) & CALL_LONG) == 0"
11219 {
11220 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
11221 output_asm_insn ("crxor 6,6,6", operands);
11222
11223 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
11224 output_asm_insn ("creqv 6,6,6", operands);
11225
11226 if (rs6000_pcrel_p ())
11227 return "bl %z0@notoc";
11228 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z0@local" : "bl %z0";
11229 }
11230 [(set_attr "type" "branch")
11231 (set_attr "length" "4,8")])
11232
11233 (define_insn "*call_value_local<mode>"
11234 [(set (match_operand 0 "" "")
11235 (call (mem:SI (match_operand:P 1 "current_file_function_operand" "s,s"))
11236 (match_operand 2)))
11237 (use (match_operand:SI 3 "immediate_operand" "O,n"))
11238 (clobber (reg:P LR_REGNO))]
11239 "(INTVAL (operands[3]) & CALL_LONG) == 0"
11240 {
11241 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11242 output_asm_insn ("crxor 6,6,6", operands);
11243
11244 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11245 output_asm_insn ("creqv 6,6,6", operands);
11246
11247 if (rs6000_pcrel_p ())
11248 return "bl %z1@notoc";
11249 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z1@local" : "bl %z1";
11250 }
11251 [(set_attr "type" "branch")
11252 (set_attr "length" "4,8")])
11253
11254
11255 ;; A function pointer under System V is just a normal pointer
11256 ;; operands[0] is the function pointer
11257 ;; operands[1] is the tls call arg
11258 ;; operands[2] is the value FUNCTION_ARG returns for the VOID argument
11259 ;; which indicates how to set cr1
11260
11261 (define_insn "*call_indirect_nonlocal_sysv<mode>"
11262 [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X"))
11263 (match_operand 1))
11264 (use (match_operand:SI 2 "immediate_operand" "n,n,n"))
11265 (clobber (reg:P LR_REGNO))]
11266 "DEFAULT_ABI == ABI_V4
11267 || DEFAULT_ABI == ABI_DARWIN"
11268 {
11269 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
11270 output_asm_insn ("crxor 6,6,6", operands);
11271
11272 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
11273 output_asm_insn ("creqv 6,6,6", operands);
11274
11275 return rs6000_indirect_call_template (operands, 0);
11276 }
11277 [(set_attr "type" "jmpreg")
11278 (set (attr "length")
11279 (cond [(and (and (match_test "!rs6000_speculate_indirect_jumps")
11280 (match_test "which_alternative != 1"))
11281 (match_test "(INTVAL (operands[2]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
11282 (const_string "12")
11283 (ior (and (match_test "!rs6000_speculate_indirect_jumps")
11284 (match_test "which_alternative != 1"))
11285 (match_test "(INTVAL (operands[2]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
11286 (const_string "8")]
11287 (const_string "4")))])
11288
11289 (define_insn "*call_nonlocal_sysv<mode>"
11290 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
11291 (match_operand 1))
11292 (use (match_operand:SI 2 "immediate_operand" "O,n"))
11293 (clobber (reg:P LR_REGNO))]
11294 "(DEFAULT_ABI == ABI_DARWIN
11295 || (DEFAULT_ABI == ABI_V4
11296 && (INTVAL (operands[2]) & CALL_LONG) == 0))"
11297 {
11298 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
11299 output_asm_insn ("crxor 6,6,6", operands);
11300
11301 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
11302 output_asm_insn ("creqv 6,6,6", operands);
11303
11304 return rs6000_call_template (operands, 0);
11305 }
11306 [(set_attr "type" "branch,branch")
11307 (set_attr "length" "4,8")])
11308
11309 (define_insn "*call_nonlocal_sysv_secure<mode>"
11310 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
11311 (match_operand 1))
11312 (use (match_operand:SI 2 "immediate_operand" "O,n"))
11313 (use (match_operand:SI 3 "register_operand" "r,r"))
11314 (clobber (reg:P LR_REGNO))]
11315 "(DEFAULT_ABI == ABI_V4
11316 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0])
11317 && (INTVAL (operands[2]) & CALL_LONG) == 0)"
11318 {
11319 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
11320 output_asm_insn ("crxor 6,6,6", operands);
11321
11322 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
11323 output_asm_insn ("creqv 6,6,6", operands);
11324
11325 return rs6000_call_template (operands, 0);
11326 }
11327 [(set_attr "type" "branch,branch")
11328 (set_attr "length" "4,8")])
11329
11330 (define_insn "*call_value_indirect_nonlocal_sysv<mode>"
11331 [(set (match_operand 0 "" "")
11332 (call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X"))
11333 (match_operand:P 2 "unspec_tls" "")))
11334 (use (match_operand:SI 3 "immediate_operand" "n,n,n"))
11335 (clobber (reg:P LR_REGNO))]
11336 "DEFAULT_ABI == ABI_V4
11337 || DEFAULT_ABI == ABI_DARWIN"
11338 {
11339 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11340 output_asm_insn ("crxor 6,6,6", operands);
11341
11342 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11343 output_asm_insn ("creqv 6,6,6", operands);
11344
11345 return rs6000_indirect_call_template (operands, 1);
11346 }
11347 [(set_attr "type" "jmpreg")
11348 (set (attr "length")
11349 (plus
11350 (if_then_else (match_test "IS_V4_FP_ARGS (operands[3])")
11351 (const_int 4)
11352 (const_int 0))
11353 (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
11354 (match_test "which_alternative != 1"))
11355 (const_int 8)
11356 (const_int 4))))])
11357
11358 (define_insn "*call_value_nonlocal_sysv<mode>"
11359 [(set (match_operand 0 "" "")
11360 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s"))
11361 (match_operand:P 2 "unspec_tls" "")))
11362 (use (match_operand:SI 3 "immediate_operand" "n"))
11363 (clobber (reg:P LR_REGNO))]
11364 "(DEFAULT_ABI == ABI_DARWIN
11365 || (DEFAULT_ABI == ABI_V4
11366 && (INTVAL (operands[3]) & CALL_LONG) == 0))"
11367 {
11368 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11369 output_asm_insn ("crxor 6,6,6", operands);
11370
11371 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11372 output_asm_insn ("creqv 6,6,6", operands);
11373
11374 return rs6000_call_template (operands, 1);
11375 }
11376 [(set_attr "type" "branch")
11377 (set (attr "length")
11378 (if_then_else (match_test "IS_V4_FP_ARGS (operands[3])")
11379 (const_int 8)
11380 (const_int 4)))])
11381
11382 (define_insn "*call_value_nonlocal_sysv_secure<mode>"
11383 [(set (match_operand 0 "" "")
11384 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s"))
11385 (match_operand:P 2 "unspec_tls" "")))
11386 (use (match_operand:SI 3 "immediate_operand" "n"))
11387 (use (match_operand:SI 4 "register_operand" "r"))
11388 (clobber (reg:P LR_REGNO))]
11389 "(DEFAULT_ABI == ABI_V4
11390 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1])
11391 && (INTVAL (operands[3]) & CALL_LONG) == 0)"
11392 {
11393 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11394 output_asm_insn ("crxor 6,6,6", operands);
11395
11396 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11397 output_asm_insn ("creqv 6,6,6", operands);
11398
11399 return rs6000_call_template (operands, 1);
11400 }
11401 [(set_attr "type" "branch")
11402 (set (attr "length")
11403 (if_then_else (match_test "IS_V4_FP_ARGS (operands[3])")
11404 (const_int 8)
11405 (const_int 4)))])
11406
11407 ;; Call to AIX abi function which may be in another module.
11408 ;; Restore the TOC pointer (r2) after the call.
11409
11410 (define_insn "*call_nonlocal_aix<mode>"
11411 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s"))
11412 (match_operand 1))
11413 (use (match_operand:SI 2 "immediate_operand" "n"))
11414 (clobber (reg:P LR_REGNO))]
11415 "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
11416 && (INTVAL (operands[2]) & CALL_LONG) == 0"
11417 {
11418 return rs6000_call_template (operands, 0);
11419 }
11420 [(set_attr "type" "branch")
11421 (set (attr "length")
11422 (if_then_else (match_test "rs6000_pcrel_p ()")
11423 (const_int 4)
11424 (const_int 8)))])
11425
11426 (define_insn "*call_value_nonlocal_aix<mode>"
11427 [(set (match_operand 0 "" "")
11428 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s"))
11429 (match_operand:P 2 "unspec_tls" "")))
11430 (use (match_operand:SI 3 "immediate_operand" "n"))
11431 (clobber (reg:P LR_REGNO))]
11432 "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
11433 && (INTVAL (operands[3]) & CALL_LONG) == 0"
11434 {
11435 return rs6000_call_template (operands, 1);
11436 }
11437 [(set_attr "type" "branch")
11438 (set (attr "length")
11439 (if_then_else (match_test "rs6000_pcrel_p ()")
11440 (const_int 4)
11441 (const_int 8)))])
11442
11443 ;; Call to indirect functions with the AIX abi using a 3 word descriptor.
11444 ;; Operand0 is the addresss of the function to call
11445 ;; Operand3 is the location in the function descriptor to load r2 from
11446 ;; Operand4 is the offset of the stack location holding the current TOC pointer
11447
11448 (define_insn "*call_indirect_aix<mode>"
11449 [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X"))
11450 (match_operand 1))
11451 (use (match_operand:SI 2 "immediate_operand" "n,n,n"))
11452 (use (match_operand:P 3 "memory_operand" "<ptrm>,<ptrm>,<ptrm>"))
11453 (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 4 "const_int_operand" "n,n,n")] UNSPEC_TOCSLOT))
11454 (clobber (reg:P LR_REGNO))]
11455 "DEFAULT_ABI == ABI_AIX"
11456 {
11457 return rs6000_indirect_call_template (operands, 0);
11458 }
11459 [(set_attr "type" "jmpreg")
11460 (set (attr "length")
11461 (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
11462 (match_test "which_alternative != 1"))
11463 (const_string "16")
11464 (const_string "12")))])
11465
11466 (define_insn "*call_value_indirect_aix<mode>"
11467 [(set (match_operand 0 "" "")
11468 (call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X"))
11469 (match_operand:P 2 "unspec_tls" "")))
11470 (use (match_operand:SI 3 "immediate_operand" "n,n,n"))
11471 (use (match_operand:P 4 "memory_operand" "<ptrm>,<ptrm>,<ptrm>"))
11472 (set (reg:P TOC_REGNUM)
11473 (unspec:P [(match_operand:P 5 "const_int_operand" "n,n,n")]
11474 UNSPEC_TOCSLOT))
11475 (clobber (reg:P LR_REGNO))]
11476 "DEFAULT_ABI == ABI_AIX"
11477 {
11478 return rs6000_indirect_call_template (operands, 1);
11479 }
11480 [(set_attr "type" "jmpreg")
11481 (set (attr "length")
11482 (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
11483 (match_test "which_alternative != 1"))
11484 (const_string "16")
11485 (const_string "12")))])
11486
11487 ;; Call to indirect functions with the ELFv2 ABI.
11488 ;; Operand0 is the addresss of the function to call
11489 ;; Operand3 is the offset of the stack location holding the current TOC pointer
11490
11491 (define_insn "*call_indirect_elfv2<mode>"
11492 [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X"))
11493 (match_operand 1))
11494 (use (match_operand:SI 2 "immediate_operand" "n,n,n"))
11495 (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 3 "const_int_operand" "n,n,n")] UNSPEC_TOCSLOT))
11496 (clobber (reg:P LR_REGNO))]
11497 "DEFAULT_ABI == ABI_ELFv2"
11498 {
11499 return rs6000_indirect_call_template (operands, 0);
11500 }
11501 [(set_attr "type" "jmpreg")
11502 (set (attr "length")
11503 (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
11504 (match_test "which_alternative != 1"))
11505 (const_string "12")
11506 (const_string "8")))])
11507
11508 (define_insn "*call_indirect_pcrel<mode>"
11509 [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X"))
11510 (match_operand 1))
11511 (use (match_operand:SI 2 "immediate_operand" "n,n,n"))
11512 (clobber (reg:P LR_REGNO))]
11513 "rs6000_pcrel_p ()"
11514 {
11515 return rs6000_indirect_call_template (operands, 0);
11516 }
11517 [(set_attr "type" "jmpreg")
11518 (set (attr "length")
11519 (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
11520 (match_test "which_alternative != 1"))
11521 (const_string "8")
11522 (const_string "4")))])
11523
11524 (define_insn "*call_value_indirect_elfv2<mode>"
11525 [(set (match_operand 0 "" "")
11526 (call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X"))
11527 (match_operand:P 2 "unspec_tls" "")))
11528 (use (match_operand:SI 3 "immediate_operand" "n,n,n"))
11529 (set (reg:P TOC_REGNUM)
11530 (unspec:P [(match_operand:P 4 "const_int_operand" "n,n,n")]
11531 UNSPEC_TOCSLOT))
11532 (clobber (reg:P LR_REGNO))]
11533 "DEFAULT_ABI == ABI_ELFv2"
11534 {
11535 return rs6000_indirect_call_template (operands, 1);
11536 }
11537 [(set_attr "type" "jmpreg")
11538 (set (attr "length")
11539 (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
11540 (match_test "which_alternative != 1"))
11541 (const_string "12")
11542 (const_string "8")))])
11543
11544 (define_insn "*call_value_indirect_pcrel<mode>"
11545 [(set (match_operand 0 "" "")
11546 (call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X"))
11547 (match_operand:P 2 "unspec_tls" "")))
11548 (use (match_operand:SI 3 "immediate_operand" "n,n,n"))
11549 (clobber (reg:P LR_REGNO))]
11550 "rs6000_pcrel_p ()"
11551 {
11552 return rs6000_indirect_call_template (operands, 1);
11553 }
11554 [(set_attr "type" "jmpreg")
11555 (set (attr "length")
11556 (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
11557 (match_test "which_alternative != 1"))
11558 (const_string "8")
11559 (const_string "4")))])
11560
11561 ;; Call subroutine returning any type.
11562 (define_expand "untyped_call"
11563 [(parallel [(call (match_operand 0 "")
11564 (const_int 0))
11565 (match_operand 1 "")
11566 (match_operand 2 "")])]
11567 ""
11568 {
11569 int i;
11570
11571 emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
11572
11573 for (int i = 0; i < XVECLEN (operands[2], 0); i++)
11574 emit_clobber (SET_SRC (XVECEXP (operands[2], 0, i)));
11575 emit_insn (gen_blockage ());
11576
11577 for (i = 0; i < XVECLEN (operands[2], 0); i++)
11578 {
11579 rtx set = XVECEXP (operands[2], 0, i);
11580 emit_move_insn (SET_DEST (set), SET_SRC (set));
11581 }
11582
11583 /* The optimizer does not know that the call sets the function value
11584 registers we stored in the result block. We avoid problems by
11585 claiming that all hard registers are used and clobbered at this
11586 point. */
11587 emit_insn (gen_blockage ());
11588
11589 DONE;
11590 })
11591
11592 ;; sibling call patterns
11593 (define_expand "sibcall"
11594 [(parallel [(call (mem:SI (match_operand 0 "address_operand"))
11595 (match_operand 1 ""))
11596 (use (match_operand 2 ""))
11597 (simple_return)])]
11598 ""
11599 {
11600 #if TARGET_MACHO
11601 if (MACHOPIC_INDIRECT)
11602 operands[0] = machopic_indirect_call_target (operands[0]);
11603 #endif
11604
11605 gcc_assert (MEM_P (operands[0]));
11606 gcc_assert (CONST_INT_P (operands[1]));
11607
11608 operands[0] = XEXP (operands[0], 0);
11609
11610 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
11611 rs6000_sibcall_aix (NULL_RTX, operands[0], operands[1], operands[2]);
11612 else if (DEFAULT_ABI == ABI_V4)
11613 rs6000_sibcall_sysv (NULL_RTX, operands[0], operands[1], operands[2]);
11614 else if (DEFAULT_ABI == ABI_DARWIN)
11615 rs6000_sibcall_darwin (NULL_RTX, operands[0], operands[1], operands[2]);
11616 else
11617 gcc_unreachable ();
11618
11619 DONE;
11620 })
11621
11622 (define_expand "sibcall_value"
11623 [(parallel [(set (match_operand 0 "register_operand")
11624 (call (mem:SI (match_operand 1 "address_operand"))
11625 (match_operand 2 "")))
11626 (use (match_operand 3 ""))
11627 (simple_return)])]
11628 ""
11629 {
11630 #if TARGET_MACHO
11631 if (MACHOPIC_INDIRECT)
11632 operands[1] = machopic_indirect_call_target (operands[1]);
11633 #endif
11634
11635 gcc_assert (MEM_P (operands[1]));
11636 gcc_assert (CONST_INT_P (operands[2]));
11637
11638 operands[1] = XEXP (operands[1], 0);
11639
11640 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
11641 rs6000_sibcall_aix (operands[0], operands[1], operands[2], operands[3]);
11642 else if (DEFAULT_ABI == ABI_V4)
11643 rs6000_sibcall_sysv (operands[0], operands[1], operands[2], operands[3]);
11644 else if (DEFAULT_ABI == ABI_DARWIN)
11645 rs6000_sibcall_darwin (operands[0], operands[1], operands[2], operands[3]);
11646 else
11647 gcc_unreachable ();
11648
11649 DONE;
11650 })
11651
11652 (define_insn "*sibcall_local<mode>"
11653 [(call (mem:SI (match_operand:P 0 "current_file_function_operand" "s,s"))
11654 (match_operand 1))
11655 (use (match_operand:SI 2 "immediate_operand" "O,n"))
11656 (simple_return)]
11657 "(INTVAL (operands[2]) & CALL_LONG) == 0"
11658 {
11659 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
11660 output_asm_insn ("crxor 6,6,6", operands);
11661
11662 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
11663 output_asm_insn ("creqv 6,6,6", operands);
11664
11665 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z0@local" : "b %z0";
11666 }
11667 [(set_attr "type" "branch")
11668 (set_attr "length" "4,8")])
11669
11670 (define_insn "*sibcall_value_local<mode>"
11671 [(set (match_operand 0 "" "")
11672 (call (mem:SI (match_operand:P 1 "current_file_function_operand" "s,s"))
11673 (match_operand 2)))
11674 (use (match_operand:SI 3 "immediate_operand" "O,n"))
11675 (simple_return)]
11676 "(INTVAL (operands[3]) & CALL_LONG) == 0"
11677 {
11678 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11679 output_asm_insn ("crxor 6,6,6", operands);
11680
11681 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11682 output_asm_insn ("creqv 6,6,6", operands);
11683
11684 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z1@local" : "b %z1";
11685 }
11686 [(set_attr "type" "branch")
11687 (set_attr "length" "4,8")])
11688
11689 (define_insn "*sibcall_indirect_nonlocal_sysv<mode>"
11690 [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X"))
11691 (match_operand 1))
11692 (use (match_operand:SI 2 "immediate_operand" "n,n,n"))
11693 (simple_return)]
11694 "DEFAULT_ABI == ABI_V4
11695 || DEFAULT_ABI == ABI_DARWIN"
11696 {
11697 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
11698 output_asm_insn ("crxor 6,6,6", operands);
11699
11700 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
11701 output_asm_insn ("creqv 6,6,6", operands);
11702
11703 return rs6000_indirect_sibcall_template (operands, 0);
11704 }
11705 [(set_attr "type" "jmpreg")
11706 (set (attr "length")
11707 (cond [(and (and (match_test "!rs6000_speculate_indirect_jumps")
11708 (match_test "which_alternative != 1"))
11709 (match_test "(INTVAL (operands[2]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
11710 (const_string "12")
11711 (ior (and (match_test "!rs6000_speculate_indirect_jumps")
11712 (match_test "which_alternative != 1"))
11713 (match_test "(INTVAL (operands[2]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
11714 (const_string "8")]
11715 (const_string "4")))])
11716
11717 (define_insn "*sibcall_nonlocal_sysv<mode>"
11718 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
11719 (match_operand 1))
11720 (use (match_operand 2 "immediate_operand" "O,n"))
11721 (simple_return)]
11722 "(DEFAULT_ABI == ABI_DARWIN
11723 || DEFAULT_ABI == ABI_V4)
11724 && (INTVAL (operands[2]) & CALL_LONG) == 0"
11725 {
11726 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
11727 output_asm_insn ("crxor 6,6,6", operands);
11728
11729 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
11730 output_asm_insn ("creqv 6,6,6", operands);
11731
11732 return rs6000_sibcall_template (operands, 0);
11733 }
11734 [(set_attr "type" "branch")
11735 (set_attr "length" "4,8")])
11736
11737 (define_insn "*sibcall_value_indirect_nonlocal_sysv<mode>"
11738 [(set (match_operand 0 "" "")
11739 (call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X"))
11740 (match_operand 2)))
11741 (use (match_operand:SI 3 "immediate_operand" "n,n,n"))
11742 (simple_return)]
11743 "DEFAULT_ABI == ABI_V4
11744 || DEFAULT_ABI == ABI_DARWIN"
11745 {
11746 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11747 output_asm_insn ("crxor 6,6,6", operands);
11748
11749 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11750 output_asm_insn ("creqv 6,6,6", operands);
11751
11752 return rs6000_indirect_sibcall_template (operands, 1);
11753 }
11754 [(set_attr "type" "jmpreg")
11755 (set (attr "length")
11756 (cond [(and (and (match_test "!rs6000_speculate_indirect_jumps")
11757 (match_test "which_alternative != 1"))
11758 (match_test "(INTVAL (operands[3]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
11759 (const_string "12")
11760 (ior (and (match_test "!rs6000_speculate_indirect_jumps")
11761 (match_test "which_alternative != 1"))
11762 (match_test "(INTVAL (operands[3]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
11763 (const_string "8")]
11764 (const_string "4")))])
11765
11766 (define_insn "*sibcall_value_nonlocal_sysv<mode>"
11767 [(set (match_operand 0 "" "")
11768 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
11769 (match_operand 2)))
11770 (use (match_operand:SI 3 "immediate_operand" "O,n"))
11771 (simple_return)]
11772 "(DEFAULT_ABI == ABI_DARWIN
11773 || DEFAULT_ABI == ABI_V4)
11774 && (INTVAL (operands[3]) & CALL_LONG) == 0"
11775 {
11776 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11777 output_asm_insn ("crxor 6,6,6", operands);
11778
11779 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11780 output_asm_insn ("creqv 6,6,6", operands);
11781
11782 return rs6000_sibcall_template (operands, 1);
11783 }
11784 [(set_attr "type" "branch")
11785 (set_attr "length" "4,8")])
11786
11787 ;; AIX ABI sibling call patterns.
11788
11789 (define_insn "*sibcall_aix<mode>"
11790 [(call (mem:SI (match_operand:P 0 "call_operand" "s,c"))
11791 (match_operand 1))
11792 (simple_return)]
11793 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11794 {
11795 if (which_alternative == 0)
11796 return rs6000_sibcall_template (operands, 0);
11797 else
11798 return "b%T0";
11799 }
11800 [(set_attr "type" "branch")])
11801
11802 (define_insn "*sibcall_value_aix<mode>"
11803 [(set (match_operand 0 "" "")
11804 (call (mem:SI (match_operand:P 1 "call_operand" "s,c"))
11805 (match_operand 2)))
11806 (simple_return)]
11807 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11808 {
11809 if (which_alternative == 0)
11810 return rs6000_sibcall_template (operands, 1);
11811 else
11812 return "b%T1";
11813 }
11814 [(set_attr "type" "branch")])
11815
11816 (define_expand "sibcall_epilogue"
11817 [(use (const_int 0))]
11818 ""
11819 {
11820 if (!TARGET_SCHED_PROLOG)
11821 emit_insn (gen_blockage ());
11822 rs6000_emit_epilogue (EPILOGUE_TYPE_SIBCALL);
11823 DONE;
11824 })
11825
11826 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11827 ;; all of memory. This blocks insns from being moved across this point.
11828
11829 (define_insn "blockage"
11830 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCK)]
11831 ""
11832 ""
11833 [(set_attr "length" "0")])
11834
11835 (define_expand "probe_stack_address"
11836 [(use (match_operand 0 "address_operand"))]
11837 ""
11838 {
11839 operands[0] = gen_rtx_MEM (Pmode, operands[0]);
11840 MEM_VOLATILE_P (operands[0]) = 1;
11841
11842 if (TARGET_64BIT)
11843 emit_insn (gen_probe_stack_di (operands[0]));
11844 else
11845 emit_insn (gen_probe_stack_si (operands[0]));
11846 DONE;
11847 })
11848
11849 (define_insn "probe_stack_<mode>"
11850 [(set (match_operand:P 0 "memory_operand" "=m")
11851 (unspec:P [(const_int 0)] UNSPEC_PROBE_STACK))]
11852 ""
11853 {
11854 operands[1] = gen_rtx_REG (Pmode, 0);
11855 return "st<wd>%U0%X0 %1,%0";
11856 }
11857 [(set_attr "type" "store")
11858 (set (attr "update")
11859 (if_then_else (match_operand 0 "update_address_mem")
11860 (const_string "yes")
11861 (const_string "no")))
11862 (set (attr "indexed")
11863 (if_then_else (match_operand 0 "indexed_address_mem")
11864 (const_string "yes")
11865 (const_string "no")))])
11866
11867 (define_insn "probe_stack_range<P:mode>"
11868 [(set (match_operand:P 0 "register_operand" "=&r")
11869 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
11870 (match_operand:P 2 "register_operand" "r")
11871 (match_operand:P 3 "register_operand" "r")]
11872 UNSPECV_PROBE_STACK_RANGE))]
11873 ""
11874 "* return output_probe_stack_range (operands[0], operands[2], operands[3]);"
11875 [(set_attr "type" "three")])
11876 \f
11877 ;; Compare insns are next. Note that the RS/6000 has two types of compares,
11878 ;; signed & unsigned, and one type of branch.
11879 ;;
11880 ;; Start with the DEFINE_EXPANDs to generate the rtl for compares, scc
11881 ;; insns, and branches.
11882
11883 (define_expand "cbranch<mode>4"
11884 [(use (match_operator 0 "comparison_operator"
11885 [(match_operand:GPR 1 "gpc_reg_operand")
11886 (match_operand:GPR 2 "reg_or_short_operand")]))
11887 (use (match_operand 3))]
11888 ""
11889 {
11890 /* Take care of the possibility that operands[2] might be negative but
11891 this might be a logical operation. That insn doesn't exist. */
11892 if (CONST_INT_P (operands[2])
11893 && INTVAL (operands[2]) < 0)
11894 {
11895 operands[2] = force_reg (<MODE>mode, operands[2]);
11896 operands[0] = gen_rtx_fmt_ee (GET_CODE (operands[0]),
11897 GET_MODE (operands[0]),
11898 operands[1], operands[2]);
11899 }
11900
11901 rs6000_emit_cbranch (<MODE>mode, operands);
11902 DONE;
11903 })
11904
11905 (define_expand "cbranch<mode>4"
11906 [(use (match_operator 0 "comparison_operator"
11907 [(match_operand:FP 1 "gpc_reg_operand")
11908 (match_operand:FP 2 "gpc_reg_operand")]))
11909 (use (match_operand 3))]
11910 ""
11911 {
11912 rs6000_emit_cbranch (<MODE>mode, operands);
11913 DONE;
11914 })
11915
11916 (define_expand "cbranchcc4"
11917 [(set (pc)
11918 (if_then_else (match_operator 0 "branch_comparison_operator"
11919 [(match_operand 1 "cc_reg_operand")
11920 (match_operand 2 "zero_constant")])
11921 (label_ref (match_operand 3))
11922 (pc)))]
11923 ""
11924 "")
11925
11926 (define_expand "cstore<mode>4_signed"
11927 [(use (match_operator 1 "signed_comparison_operator"
11928 [(match_operand:P 2 "gpc_reg_operand")
11929 (match_operand:P 3 "gpc_reg_operand")]))
11930 (clobber (match_operand:P 0 "gpc_reg_operand"))]
11931 ""
11932 {
11933 enum rtx_code cond_code = GET_CODE (operands[1]);
11934
11935 rtx op0 = operands[0];
11936 rtx op1 = operands[2];
11937 rtx op2 = operands[3];
11938
11939 if (cond_code == GE || cond_code == LT)
11940 {
11941 cond_code = swap_condition (cond_code);
11942 std::swap (op1, op2);
11943 }
11944
11945 rtx tmp1 = gen_reg_rtx (<MODE>mode);
11946 rtx tmp2 = gen_reg_rtx (<MODE>mode);
11947 rtx tmp3 = gen_reg_rtx (<MODE>mode);
11948
11949 int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11950 emit_insn (gen_lshr<mode>3 (tmp1, op1, GEN_INT (sh)));
11951 emit_insn (gen_ashr<mode>3 (tmp2, op2, GEN_INT (sh)));
11952
11953 emit_insn (gen_subf<mode>3_carry (tmp3, op1, op2));
11954
11955 if (cond_code == LE)
11956 emit_insn (gen_add<mode>3_carry_in (op0, tmp1, tmp2));
11957 else
11958 {
11959 rtx tmp4 = gen_reg_rtx (<MODE>mode);
11960 emit_insn (gen_add<mode>3_carry_in (tmp4, tmp1, tmp2));
11961 emit_insn (gen_xor<mode>3 (op0, tmp4, const1_rtx));
11962 }
11963
11964 DONE;
11965 })
11966
11967 (define_expand "cstore<mode>4_unsigned"
11968 [(use (match_operator 1 "unsigned_comparison_operator"
11969 [(match_operand:P 2 "gpc_reg_operand")
11970 (match_operand:P 3 "reg_or_short_operand")]))
11971 (clobber (match_operand:P 0 "gpc_reg_operand"))]
11972 ""
11973 {
11974 enum rtx_code cond_code = GET_CODE (operands[1]);
11975
11976 rtx op0 = operands[0];
11977 rtx op1 = operands[2];
11978 rtx op2 = operands[3];
11979
11980 if (cond_code == GEU || cond_code == LTU)
11981 {
11982 cond_code = swap_condition (cond_code);
11983 std::swap (op1, op2);
11984 }
11985
11986 if (!gpc_reg_operand (op1, <MODE>mode))
11987 op1 = force_reg (<MODE>mode, op1);
11988 if (!reg_or_short_operand (op2, <MODE>mode))
11989 op2 = force_reg (<MODE>mode, op2);
11990
11991 rtx tmp = gen_reg_rtx (<MODE>mode);
11992 rtx tmp2 = gen_reg_rtx (<MODE>mode);
11993
11994 emit_insn (gen_subf<mode>3_carry (tmp, op1, op2));
11995 emit_insn (gen_subf<mode>3_carry_in_xx (tmp2));
11996
11997 if (cond_code == LEU)
11998 emit_insn (gen_add<mode>3 (op0, tmp2, const1_rtx));
11999 else
12000 emit_insn (gen_neg<mode>2 (op0, tmp2));
12001
12002 DONE;
12003 })
12004
12005 (define_expand "cstore_si_as_di"
12006 [(use (match_operator 1 "unsigned_comparison_operator"
12007 [(match_operand:SI 2 "gpc_reg_operand")
12008 (match_operand:SI 3 "reg_or_short_operand")]))
12009 (clobber (match_operand:SI 0 "gpc_reg_operand"))]
12010 ""
12011 {
12012 int uns_flag = unsigned_comparison_operator (operands[1], VOIDmode) ? 1 : 0;
12013 enum rtx_code cond_code = signed_condition (GET_CODE (operands[1]));
12014
12015 operands[2] = force_reg (SImode, operands[2]);
12016 operands[3] = force_reg (SImode, operands[3]);
12017 rtx op1 = gen_reg_rtx (DImode);
12018 rtx op2 = gen_reg_rtx (DImode);
12019 convert_move (op1, operands[2], uns_flag);
12020 convert_move (op2, operands[3], uns_flag);
12021
12022 if (cond_code == GT || cond_code == LE)
12023 {
12024 cond_code = swap_condition (cond_code);
12025 std::swap (op1, op2);
12026 }
12027
12028 rtx tmp = gen_reg_rtx (DImode);
12029 rtx tmp2 = gen_reg_rtx (DImode);
12030 emit_insn (gen_subdi3 (tmp, op1, op2));
12031 emit_insn (gen_lshrdi3 (tmp2, tmp, GEN_INT (63)));
12032
12033 rtx tmp3;
12034 switch (cond_code)
12035 {
12036 default:
12037 gcc_unreachable ();
12038 case LT:
12039 tmp3 = tmp2;
12040 break;
12041 case GE:
12042 tmp3 = gen_reg_rtx (DImode);
12043 emit_insn (gen_xordi3 (tmp3, tmp2, const1_rtx));
12044 break;
12045 }
12046
12047 convert_move (operands[0], tmp3, 1);
12048
12049 DONE;
12050 })
12051
12052 (define_expand "cstore<mode>4_signed_imm"
12053 [(use (match_operator 1 "signed_comparison_operator"
12054 [(match_operand:GPR 2 "gpc_reg_operand")
12055 (match_operand:GPR 3 "immediate_operand")]))
12056 (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
12057 ""
12058 {
12059 bool invert = false;
12060
12061 enum rtx_code cond_code = GET_CODE (operands[1]);
12062
12063 rtx op0 = operands[0];
12064 rtx op1 = operands[2];
12065 HOST_WIDE_INT val = INTVAL (operands[3]);
12066
12067 if (cond_code == GE || cond_code == GT)
12068 {
12069 cond_code = reverse_condition (cond_code);
12070 invert = true;
12071 }
12072
12073 if (cond_code == LE)
12074 val++;
12075
12076 rtx tmp = gen_reg_rtx (<MODE>mode);
12077 emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
12078 rtx x = gen_reg_rtx (<MODE>mode);
12079 if (val < 0)
12080 emit_insn (gen_and<mode>3 (x, op1, tmp));
12081 else
12082 emit_insn (gen_ior<mode>3 (x, op1, tmp));
12083
12084 if (invert)
12085 {
12086 rtx tmp = gen_reg_rtx (<MODE>mode);
12087 emit_insn (gen_one_cmpl<mode>2 (tmp, x));
12088 x = tmp;
12089 }
12090
12091 int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
12092 emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
12093
12094 DONE;
12095 })
12096
12097 (define_expand "cstore<mode>4_unsigned_imm"
12098 [(use (match_operator 1 "unsigned_comparison_operator"
12099 [(match_operand:GPR 2 "gpc_reg_operand")
12100 (match_operand:GPR 3 "immediate_operand")]))
12101 (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
12102 ""
12103 {
12104 bool invert = false;
12105
12106 enum rtx_code cond_code = GET_CODE (operands[1]);
12107
12108 rtx op0 = operands[0];
12109 rtx op1 = operands[2];
12110 HOST_WIDE_INT val = INTVAL (operands[3]);
12111
12112 if (cond_code == GEU || cond_code == GTU)
12113 {
12114 cond_code = reverse_condition (cond_code);
12115 invert = true;
12116 }
12117
12118 if (cond_code == LEU)
12119 val++;
12120
12121 rtx tmp = gen_reg_rtx (<MODE>mode);
12122 rtx tmp2 = gen_reg_rtx (<MODE>mode);
12123 emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
12124 emit_insn (gen_one_cmpl<mode>2 (tmp2, op1));
12125 rtx x = gen_reg_rtx (<MODE>mode);
12126 if (val < 0)
12127 emit_insn (gen_ior<mode>3 (x, tmp, tmp2));
12128 else
12129 emit_insn (gen_and<mode>3 (x, tmp, tmp2));
12130
12131 if (invert)
12132 {
12133 rtx tmp = gen_reg_rtx (<MODE>mode);
12134 emit_insn (gen_one_cmpl<mode>2 (tmp, x));
12135 x = tmp;
12136 }
12137
12138 int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
12139 emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
12140
12141 DONE;
12142 })
12143
12144 (define_expand "cstore<mode>4"
12145 [(use (match_operator 1 "comparison_operator"
12146 [(match_operand:GPR 2 "gpc_reg_operand")
12147 (match_operand:GPR 3 "reg_or_short_operand")]))
12148 (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
12149 ""
12150 {
12151 /* Everything is best done with setbc[r] if available. */
12152 if (TARGET_POWER10 && TARGET_ISEL)
12153 {
12154 rs6000_emit_int_cmove (operands[0], operands[1], const1_rtx, const0_rtx);
12155 DONE;
12156 }
12157
12158 /* Expanding EQ and NE directly to some machine instructions does not help
12159 but does hurt combine. So don't. */
12160 if (GET_CODE (operands[1]) == EQ)
12161 emit_insn (gen_eq<mode>3 (operands[0], operands[2], operands[3]));
12162 else if (<MODE>mode == Pmode
12163 && GET_CODE (operands[1]) == NE)
12164 emit_insn (gen_ne<mode>3 (operands[0], operands[2], operands[3]));
12165 else if (GET_CODE (operands[1]) == NE)
12166 {
12167 rtx tmp = gen_reg_rtx (<MODE>mode);
12168 emit_insn (gen_eq<mode>3 (tmp, operands[2], operands[3]));
12169 emit_insn (gen_xor<mode>3 (operands[0], tmp, const1_rtx));
12170 }
12171
12172 /* If ISEL is fast, expand to it. */
12173 else if (TARGET_ISEL)
12174 rs6000_emit_int_cmove (operands[0], operands[1], const1_rtx, const0_rtx);
12175
12176 /* Expanding the unsigned comparisons helps a lot: all the neg_ltu
12177 etc. combinations magically work out just right. */
12178 else if (<MODE>mode == Pmode
12179 && unsigned_comparison_operator (operands[1], VOIDmode))
12180 emit_insn (gen_cstore<mode>4_unsigned (operands[0], operands[1],
12181 operands[2], operands[3]));
12182
12183 /* For comparisons smaller than Pmode we can cheaply do things in Pmode. */
12184 else if (<MODE>mode == SImode && Pmode == DImode)
12185 emit_insn (gen_cstore_si_as_di (operands[0], operands[1],
12186 operands[2], operands[3]));
12187
12188 /* For signed comparisons against a constant, we can do some simple
12189 bit-twiddling. */
12190 else if (signed_comparison_operator (operands[1], VOIDmode)
12191 && CONST_INT_P (operands[3]))
12192 emit_insn (gen_cstore<mode>4_signed_imm (operands[0], operands[1],
12193 operands[2], operands[3]));
12194
12195 /* And similarly for unsigned comparisons. */
12196 else if (unsigned_comparison_operator (operands[1], VOIDmode)
12197 && CONST_INT_P (operands[3]))
12198 emit_insn (gen_cstore<mode>4_unsigned_imm (operands[0], operands[1],
12199 operands[2], operands[3]));
12200
12201 /* We also do not want to use mfcr for signed comparisons. */
12202 else if (<MODE>mode == Pmode
12203 && signed_comparison_operator (operands[1], VOIDmode))
12204 emit_insn (gen_cstore<mode>4_signed (operands[0], operands[1],
12205 operands[2], operands[3]));
12206
12207 /* Everything else, use the mfcr brute force. */
12208 else
12209 rs6000_emit_sCOND (<MODE>mode, operands);
12210
12211 DONE;
12212 })
12213
12214 (define_expand "cstore<mode>4"
12215 [(use (match_operator 1 "comparison_operator"
12216 [(match_operand:FP 2 "gpc_reg_operand")
12217 (match_operand:FP 3 "gpc_reg_operand")]))
12218 (clobber (match_operand:SI 0 "gpc_reg_operand"))]
12219 ""
12220 {
12221 rs6000_emit_sCOND (<MODE>mode, operands);
12222 DONE;
12223 })
12224
12225
12226 (define_expand "stack_protect_set"
12227 [(match_operand 0 "memory_operand")
12228 (match_operand 1 "memory_operand")]
12229 ""
12230 {
12231 if (rs6000_stack_protector_guard == SSP_TLS)
12232 {
12233 rtx reg = gen_rtx_REG (Pmode, rs6000_stack_protector_guard_reg);
12234 rtx offset = GEN_INT (rs6000_stack_protector_guard_offset);
12235 rtx addr = gen_rtx_PLUS (Pmode, reg, offset);
12236 operands[1] = gen_rtx_MEM (Pmode, addr);
12237 }
12238
12239 if (TARGET_64BIT)
12240 emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
12241 else
12242 emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
12243
12244 DONE;
12245 })
12246
12247 (define_insn "stack_protect_setsi"
12248 [(set (match_operand:SI 0 "memory_operand" "=m")
12249 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
12250 (set (match_scratch:SI 2 "=&r") (const_int 0))]
12251 "TARGET_32BIT"
12252 "lwz%U1%X1 %2,%1\;stw%U0%X0 %2,%0\;li %2,0"
12253 [(set_attr "type" "three")
12254 (set_attr "length" "12")])
12255
12256 ;; We can't use the prefixed attribute here because there are two memory
12257 ;; instructions. We can't split the insn due to the fact that this operation
12258 ;; needs to be done in one piece.
12259 (define_insn "stack_protect_setdi"
12260 [(set (match_operand:DI 0 "memory_operand" "=Y")
12261 (unspec:DI [(match_operand:DI 1 "memory_operand" "Y")] UNSPEC_SP_SET))
12262 (set (match_scratch:DI 2 "=&r") (const_int 0))]
12263 "TARGET_64BIT"
12264 {
12265 if (prefixed_memory (operands[1], DImode))
12266 output_asm_insn ("pld %2,%1", operands);
12267 else
12268 output_asm_insn ("ld%U1%X1 %2,%1", operands);
12269
12270 if (prefixed_memory (operands[0], DImode))
12271 output_asm_insn ("pstd %2,%0", operands);
12272 else
12273 output_asm_insn ("std%U0%X0 %2,%0", operands);
12274
12275 return "li %2,0";
12276 }
12277 [(set_attr "type" "three")
12278
12279 ;; Back to back prefixed memory instructions take 20 bytes (8 bytes for each
12280 ;; prefixed instruction + 4 bytes for the possible NOP). Add in 4 bytes for
12281 ;; the LI 0 at the end.
12282 (set_attr "prefixed" "no")
12283 (set_attr "num_insns" "3")
12284 (set (attr "length")
12285 (cond [(and (match_operand 0 "prefixed_memory")
12286 (match_operand 1 "prefixed_memory"))
12287 (const_int 24)
12288
12289 (ior (match_operand 0 "prefixed_memory")
12290 (match_operand 1 "prefixed_memory"))
12291 (const_int 20)]
12292
12293 (const_int 12)))])
12294
12295 (define_expand "stack_protect_test"
12296 [(match_operand 0 "memory_operand")
12297 (match_operand 1 "memory_operand")
12298 (match_operand 2 "")]
12299 ""
12300 {
12301 rtx guard = operands[1];
12302
12303 if (rs6000_stack_protector_guard == SSP_TLS)
12304 {
12305 rtx reg = gen_rtx_REG (Pmode, rs6000_stack_protector_guard_reg);
12306 rtx offset = GEN_INT (rs6000_stack_protector_guard_offset);
12307 rtx addr = gen_rtx_PLUS (Pmode, reg, offset);
12308 guard = gen_rtx_MEM (Pmode, addr);
12309 }
12310
12311 operands[1] = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, guard), UNSPEC_SP_TEST);
12312 rtx test = gen_rtx_EQ (VOIDmode, operands[0], operands[1]);
12313 rtx jump = gen_cbranchsi4 (test, operands[0], operands[1], operands[2]);
12314 emit_jump_insn (jump);
12315
12316 DONE;
12317 })
12318
12319 (define_insn "stack_protect_testsi"
12320 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
12321 (unspec:CCEQ [(match_operand:SI 1 "memory_operand" "m,m")
12322 (match_operand:SI 2 "memory_operand" "m,m")]
12323 UNSPEC_SP_TEST))
12324 (set (match_scratch:SI 4 "=r,r") (const_int 0))
12325 (clobber (match_scratch:SI 3 "=&r,&r"))]
12326 "TARGET_32BIT"
12327 "@
12328 lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0
12329 lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;cmplw %0,%3,%4\;li %3,0\;li %4,0"
12330 [(set_attr "length" "16,20")])
12331
12332 ;; We can't use the prefixed attribute here because there are two memory
12333 ;; instructions. We can't split the insn due to the fact that this operation
12334 ;; needs to be done in one piece.
12335 (define_insn "stack_protect_testdi"
12336 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
12337 (unspec:CCEQ [(match_operand:DI 1 "memory_operand" "Y,Y")
12338 (match_operand:DI 2 "memory_operand" "Y,Y")]
12339 UNSPEC_SP_TEST))
12340 (set (match_scratch:DI 4 "=r,r") (const_int 0))
12341 (clobber (match_scratch:DI 3 "=&r,&r"))]
12342 "TARGET_64BIT"
12343 {
12344 if (prefixed_memory (operands[1], DImode))
12345 output_asm_insn ("pld %3,%1", operands);
12346 else
12347 output_asm_insn ("ld%U1%X1 %3,%1", operands);
12348
12349 if (prefixed_memory (operands[2], DImode))
12350 output_asm_insn ("pld %4,%2", operands);
12351 else
12352 output_asm_insn ("ld%U2%X2 %4,%2", operands);
12353
12354 if (which_alternative == 0)
12355 output_asm_insn ("xor. %3,%3,%4", operands);
12356 else
12357 output_asm_insn ("cmpld %0,%3,%4\;li %3,0", operands);
12358
12359 return "li %4,0";
12360 }
12361 ;; Back to back prefixed memory instructions take 20 bytes (8 bytes for each
12362 ;; prefixed instruction + 4 bytes for the possible NOP). Add in either 4 or
12363 ;; 8 bytes to do the test.
12364 [(set_attr "prefixed" "no")
12365 (set_attr "num_insns" "4,5")
12366 (set (attr "length")
12367 (cond [(and (match_operand 1 "prefixed_memory")
12368 (match_operand 2 "prefixed_memory"))
12369 (if_then_else (eq_attr "alternative" "0")
12370 (const_int 28)
12371 (const_int 32))
12372
12373 (ior (match_operand 1 "prefixed_memory")
12374 (match_operand 2 "prefixed_memory"))
12375 (if_then_else (eq_attr "alternative" "0")
12376 (const_int 20)
12377 (const_int 24))]
12378
12379 (if_then_else (eq_attr "alternative" "0")
12380 (const_int 16)
12381 (const_int 20))))])
12382
12383 \f
12384 ;; Here are the actual compare insns.
12385 (define_insn "*cmp<mode>_signed"
12386 [(set (match_operand:CC 0 "cc_reg_operand" "=y")
12387 (compare:CC (match_operand:GPR 1 "gpc_reg_operand" "r")
12388 (match_operand:GPR 2 "reg_or_short_operand" "rI")))]
12389 ""
12390 "cmp<wd>%I2 %0,%1,%2"
12391 [(set_attr "type" "cmp")])
12392
12393 (define_insn "*cmp<mode>_unsigned"
12394 [(set (match_operand:CCUNS 0 "cc_reg_operand" "=y")
12395 (compare:CCUNS (match_operand:GPR 1 "gpc_reg_operand" "r")
12396 (match_operand:GPR 2 "reg_or_u_short_operand" "rK")))]
12397 ""
12398 "cmpl<wd>%I2 %0,%1,%2"
12399 [(set_attr "type" "cmp")])
12400
12401 ;; If we are comparing a register for equality with a large constant,
12402 ;; we can do this with an XOR followed by a compare. But this is profitable
12403 ;; only if the large constant is only used for the comparison (and in this
12404 ;; case we already have a register to reuse as scratch).
12405 ;;
12406 ;; For 64-bit registers, we could only do so if the constant's bit 15 is clear:
12407 ;; otherwise we'd need to XOR with FFFFFFFF????0000 which is not available.
12408
12409 (define_peephole2
12410 [(set (match_operand:SI 0 "register_operand")
12411 (match_operand:SI 1 "logical_const_operand"))
12412 (set (match_dup 0) (match_operator:SI 3 "boolean_or_operator"
12413 [(match_dup 0)
12414 (match_operand:SI 2 "logical_const_operand")]))
12415 (set (match_operand:CC 4 "cc_reg_operand")
12416 (compare:CC (match_operand:SI 5 "gpc_reg_operand")
12417 (match_dup 0)))
12418 (set (pc)
12419 (if_then_else (match_operator 6 "equality_operator"
12420 [(match_dup 4) (const_int 0)])
12421 (match_operand 7 "")
12422 (match_operand 8 "")))]
12423 "peep2_reg_dead_p (3, operands[0])
12424 && peep2_reg_dead_p (4, operands[4])
12425 && REGNO (operands[0]) != REGNO (operands[5])"
12426 [(set (match_dup 0) (xor:SI (match_dup 5) (match_dup 9)))
12427 (set (match_dup 4) (compare:CC (match_dup 0) (match_dup 10)))
12428 (set (pc) (if_then_else (match_dup 6) (match_dup 7) (match_dup 8)))]
12429
12430 {
12431 /* Get the constant we are comparing against, and see what it looks like
12432 when sign-extended from 16 to 32 bits. Then see what constant we could
12433 XOR with SEXTC to get the sign-extended value. */
12434 rtx cnst = simplify_const_binary_operation (GET_CODE (operands[3]),
12435 SImode,
12436 operands[1], operands[2]);
12437 HOST_WIDE_INT c = INTVAL (cnst);
12438 HOST_WIDE_INT sextc = sext_hwi (c, 16);
12439 HOST_WIDE_INT xorv = c ^ sextc;
12440
12441 operands[9] = GEN_INT (xorv);
12442 operands[10] = GEN_INT (sextc);
12443 })
12444
12445 ;; Only need to compare second words if first words equal
12446 (define_insn "*cmp<mode>_internal1"
12447 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
12448 (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
12449 (match_operand:IBM128 2 "gpc_reg_operand" "d")))]
12450 "!TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode)
12451 && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
12452 "fcmpu %0,%1,%2\;bne %0,$+8\;fcmpu %0,%L1,%L2"
12453 [(set_attr "type" "fpcompare")
12454 (set_attr "length" "12")])
12455
12456 (define_insn_and_split "*cmp<IBM128:mode>_internal2"
12457 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
12458 (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
12459 (match_operand:IBM128 2 "gpc_reg_operand" "d")))
12460 (clobber (match_scratch:DF 3 "=d"))
12461 (clobber (match_scratch:DF 4 "=d"))
12462 (clobber (match_scratch:DF 5 "=d"))
12463 (clobber (match_scratch:DF 6 "=d"))
12464 (clobber (match_scratch:DF 7 "=d"))
12465 (clobber (match_scratch:DF 8 "=d"))
12466 (clobber (match_scratch:DF 9 "=d"))
12467 (clobber (match_scratch:DF 10 "=d"))
12468 (clobber (match_scratch:GPR 11 "=b"))]
12469 "TARGET_XL_COMPAT && FLOAT128_IBM_P (<IBM128:MODE>mode)
12470 && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
12471 "#"
12472 "&& reload_completed"
12473 [(set (match_dup 3) (match_dup 14))
12474 (set (match_dup 4) (match_dup 15))
12475 (set (match_dup 9) (abs:DF (match_dup 5)))
12476 (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 3)))
12477 (set (pc) (if_then_else (ne (match_dup 0) (const_int 0))
12478 (label_ref (match_dup 12))
12479 (pc)))
12480 (set (match_dup 0) (compare:CCFP (match_dup 5) (match_dup 7)))
12481 (set (pc) (label_ref (match_dup 13)))
12482 (match_dup 12)
12483 (set (match_dup 10) (minus:DF (match_dup 5) (match_dup 7)))
12484 (set (match_dup 9) (minus:DF (match_dup 6) (match_dup 8)))
12485 (set (match_dup 9) (plus:DF (match_dup 10) (match_dup 9)))
12486 (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 4)))
12487 (match_dup 13)]
12488 {
12489 REAL_VALUE_TYPE rv;
12490 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
12491 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
12492
12493 operands[5] = simplify_gen_subreg (DFmode, operands[1],
12494 <IBM128:MODE>mode, hi_word);
12495 operands[6] = simplify_gen_subreg (DFmode, operands[1],
12496 <IBM128:MODE>mode, lo_word);
12497 operands[7] = simplify_gen_subreg (DFmode, operands[2],
12498 <IBM128:MODE>mode, hi_word);
12499 operands[8] = simplify_gen_subreg (DFmode, operands[2],
12500 <IBM128:MODE>mode, lo_word);
12501 operands[12] = gen_label_rtx ();
12502 operands[13] = gen_label_rtx ();
12503 real_inf (&rv);
12504 operands[14] = force_const_mem (DFmode,
12505 const_double_from_real_value (rv, DFmode));
12506 operands[15] = force_const_mem (DFmode,
12507 const_double_from_real_value (dconst0,
12508 DFmode));
12509 if (TARGET_TOC)
12510 {
12511 rtx tocref;
12512 tocref = create_TOC_reference (XEXP (operands[14], 0), operands[11]);
12513 operands[14] = gen_const_mem (DFmode, tocref);
12514 tocref = create_TOC_reference (XEXP (operands[15], 0), operands[11]);
12515 operands[15] = gen_const_mem (DFmode, tocref);
12516 set_mem_alias_set (operands[14], get_TOC_alias_set ());
12517 set_mem_alias_set (operands[15], get_TOC_alias_set ());
12518 }
12519 })
12520 \f
12521 ;; Now we have the scc insns. We can do some combinations because of the
12522 ;; way the machine works.
12523 ;;
12524 ;; Note that this is probably faster if we can put an insn between the
12525 ;; mfcr and rlinm, but this is tricky. Let's leave it for now. In most
12526 ;; cases the insns below which don't use an intermediate CR field will
12527 ;; be used instead.
12528 (define_insn "set<mode>_cc"
12529 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
12530 (match_operator:GPR 1 "scc_comparison_operator"
12531 [(match_operand 2 "cc_reg_operand" "y")
12532 (const_int 0)]))]
12533 ""
12534 "mfcr %0%Q2\;rlwinm %0,%0,%J1,1"
12535 [(set (attr "type")
12536 (cond [(match_test "TARGET_MFCRF")
12537 (const_string "mfcrf")
12538 ]
12539 (const_string "mfcr")))
12540 (set_attr "length" "8")])
12541
12542
12543 (define_code_iterator cmp [eq ne lt ltu gt gtu le leu ge geu])
12544 (define_code_attr UNS [(eq "CC")
12545 (ne "CC")
12546 (lt "CC") (ltu "CCUNS")
12547 (gt "CC") (gtu "CCUNS")
12548 (le "CC") (leu "CCUNS")
12549 (ge "CC") (geu "CCUNS")])
12550 (define_code_attr UNSu_ [(eq "")
12551 (ne "")
12552 (lt "") (ltu "u_")
12553 (gt "") (gtu "u_")
12554 (le "") (leu "u_")
12555 (ge "") (geu "u_")])
12556 (define_code_attr UNSIK [(eq "I")
12557 (ne "I")
12558 (lt "I") (ltu "K")
12559 (gt "I") (gtu "K")
12560 (le "I") (leu "K")
12561 (ge "I") (geu "K")])
12562
12563 (define_insn_and_split "<code><GPR:mode><GPR2:mode>2_isel"
12564 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
12565 (cmp:GPR (match_operand:GPR2 1 "gpc_reg_operand" "r")
12566 (match_operand:GPR2 2 "reg_or_<cmp:UNSu_>short_operand" "r<cmp:UNSIK>")))
12567 (clobber (match_scratch:GPR 3 "=r"))
12568 (clobber (match_scratch:GPR 4 "=r"))
12569 (clobber (match_scratch:<UNS> 5 "=y"))]
12570 "!TARGET_POWER10 && TARGET_ISEL
12571 && !(<CODE> == EQ && operands[2] == const0_rtx)
12572 && !(<CODE> == NE && operands[2] == const0_rtx
12573 && <GPR:MODE>mode == Pmode && <GPR2:MODE>mode == Pmode)"
12574 "#"
12575 "&& 1"
12576 [(pc)]
12577 {
12578 rtx_code code = <CODE>;
12579 if (CONST_INT_P (operands[2]) && code != EQ && code != NE)
12580 {
12581 HOST_WIDE_INT val = INTVAL (operands[2]);
12582 if (code == LT && val != -0x8000)
12583 {
12584 code = LE;
12585 val--;
12586 }
12587 if (code == GT && val != 0x7fff)
12588 {
12589 code = GE;
12590 val++;
12591 }
12592 if (code == LTU && val != 0)
12593 {
12594 code = LEU;
12595 val--;
12596 }
12597 if (code == GTU && val != 0xffff)
12598 {
12599 code = GEU;
12600 val++;
12601 }
12602 operands[2] = GEN_INT (val);
12603 }
12604
12605 if (code == NE || code == LE || code == GE || code == LEU || code == GEU)
12606 operands[3] = const0_rtx;
12607 else
12608 {
12609 if (GET_CODE (operands[3]) == SCRATCH)
12610 operands[3] = gen_reg_rtx (<GPR:MODE>mode);
12611 emit_move_insn (operands[3], const0_rtx);
12612 }
12613
12614 if (GET_CODE (operands[4]) == SCRATCH)
12615 operands[4] = gen_reg_rtx (<GPR:MODE>mode);
12616 emit_move_insn (operands[4], const1_rtx);
12617
12618 if (GET_CODE (operands[5]) == SCRATCH)
12619 operands[5] = gen_reg_rtx (<UNS>mode);
12620
12621 rtx c1 = gen_rtx_COMPARE (<UNS>mode, operands[1], operands[2]);
12622 emit_insn (gen_rtx_SET (operands[5], c1));
12623
12624 rtx c2 = gen_rtx_fmt_ee (code, <GPR:MODE>mode, operands[5], const0_rtx);
12625 rtx x = gen_rtx_IF_THEN_ELSE (<GPR:MODE>mode, c2, operands[4], operands[3]);
12626 emit_move_insn (operands[0], x);
12627
12628 DONE;
12629 }
12630 [(set (attr "cost")
12631 (if_then_else (match_test "(CONST_INT_P (operands[2]) && <CODE> != EQ)
12632 || <CODE> == NE
12633 || <CODE> == LE || <CODE> == GE
12634 || <CODE> == LEU || <CODE> == GEU")
12635 (const_string "9")
12636 (const_string "10")))])
12637
12638 (define_mode_attr scc_eq_op2 [(SI "rKLI")
12639 (DI "rKJI")])
12640
12641 (define_expand "eq<mode>3"
12642 [(parallel [
12643 (set (match_operand:GPR 0 "gpc_reg_operand" "=r")
12644 (eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
12645 (match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>")))
12646 (clobber (match_scratch:GPR 3 "=r"))
12647 (clobber (match_scratch:GPR 4 "=r"))])]
12648 ""
12649 {
12650 if (TARGET_POWER10)
12651 {
12652 rtx cc = gen_reg_rtx (CCmode);
12653 rtx compare = gen_rtx_COMPARE (CCmode, operands[1], operands[2]);
12654 emit_insn (gen_rtx_SET (cc, compare));
12655 rtx eq = gen_rtx_fmt_ee (EQ, <MODE>mode, cc, const0_rtx);
12656 emit_insn (gen_setbc_cc_<mode> (operands[0], eq, cc));
12657 DONE;
12658 }
12659
12660 if (TARGET_ISEL && operands[2] != const0_rtx)
12661 {
12662 emit_insn (gen_eq<mode><mode>2_isel (operands[0], operands[1],
12663 operands[2]));
12664 DONE;
12665 }
12666 })
12667
12668 (define_insn_and_split "*eq<mode>3"
12669 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
12670 (eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
12671 (match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>")))
12672 (clobber (match_scratch:GPR 3 "=r"))
12673 (clobber (match_scratch:GPR 4 "=r"))]
12674 "!TARGET_POWER10 && !(TARGET_ISEL && operands[2] != const0_rtx)"
12675 "#"
12676 "&& 1"
12677 [(set (match_dup 4)
12678 (clz:GPR (match_dup 3)))
12679 (set (match_dup 0)
12680 (lshiftrt:GPR (match_dup 4)
12681 (match_dup 5)))]
12682 {
12683 operands[3] = rs6000_emit_eqne (<MODE>mode,
12684 operands[1], operands[2], operands[3]);
12685
12686 if (GET_CODE (operands[4]) == SCRATCH)
12687 operands[4] = gen_reg_rtx (<MODE>mode);
12688
12689 operands[5] = GEN_INT (exact_log2 (GET_MODE_BITSIZE (<MODE>mode)));
12690 }
12691 [(set (attr "length")
12692 (if_then_else (match_test "operands[2] == const0_rtx")
12693 (const_string "8")
12694 (const_string "12")))])
12695
12696 (define_expand "ne<mode>3"
12697 [(parallel [
12698 (set (match_operand:GPR 0 "gpc_reg_operand" "=r")
12699 (ne:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
12700 (match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>")))
12701 (clobber (match_scratch:GPR 3 "=r"))
12702 (clobber (match_scratch:GPR 4 "=r"))
12703 (clobber (reg:GPR CA_REGNO))])]
12704 ""
12705 {
12706 if (TARGET_POWER10)
12707 {
12708 rtx cc = gen_reg_rtx (CCmode);
12709 rtx compare = gen_rtx_COMPARE (CCmode, operands[1], operands[2]);
12710 emit_insn (gen_rtx_SET (cc, compare));
12711 rtx ne = gen_rtx_fmt_ee (NE, <MODE>mode, cc, const0_rtx);
12712 emit_insn (gen_setbc_cc_<mode> (operands[0], ne, cc));
12713 DONE;
12714 }
12715
12716 if (<MODE>mode != Pmode)
12717 {
12718 rtx x = gen_reg_rtx (<MODE>mode);
12719 emit_insn (gen_eq<mode>3 (x, operands[1], operands[2]));
12720 emit_insn (gen_xor<mode>3 (operands[0], x, const1_rtx));
12721 DONE;
12722 }
12723
12724 if (TARGET_ISEL && operands[2] != const0_rtx)
12725 {
12726 emit_insn (gen_ne<mode><mode>2_isel (operands[0], operands[1],
12727 operands[2]));
12728 DONE;
12729 }
12730 })
12731
12732 (define_insn_and_split "*ne<mode>3"
12733 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12734 (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12735 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")))
12736 (clobber (match_scratch:P 3 "=r"))
12737 (clobber (match_scratch:P 4 "=r"))
12738 (clobber (reg:P CA_REGNO))]
12739 "!TARGET_POWER10 && !(TARGET_ISEL && operands[2] != const0_rtx)"
12740 "#"
12741 "&& 1"
12742 [(parallel [(set (match_dup 4)
12743 (plus:P (match_dup 3)
12744 (const_int -1)))
12745 (set (reg:P CA_REGNO)
12746 (ne:P (match_dup 3)
12747 (const_int 0)))])
12748 (parallel [(set (match_dup 0)
12749 (plus:P (plus:P (not:P (match_dup 4))
12750 (reg:P CA_REGNO))
12751 (match_dup 3)))
12752 (clobber (reg:P CA_REGNO))])]
12753 {
12754 operands[3] = rs6000_emit_eqne (<MODE>mode,
12755 operands[1], operands[2], operands[3]);
12756
12757 if (GET_CODE (operands[4]) == SCRATCH)
12758 operands[4] = gen_reg_rtx (<MODE>mode);
12759 }
12760 [(set (attr "length")
12761 (if_then_else (match_test "operands[2] == const0_rtx")
12762 (const_string "8")
12763 (const_string "12")))])
12764
12765 (define_insn_and_split "*neg_eq_<mode>"
12766 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12767 (neg:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12768 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12769 (clobber (match_scratch:P 3 "=r"))
12770 (clobber (match_scratch:P 4 "=r"))
12771 (clobber (reg:P CA_REGNO))]
12772 "!TARGET_POWER10"
12773 "#"
12774 "&& 1"
12775 [(parallel [(set (match_dup 4)
12776 (plus:P (match_dup 3)
12777 (const_int -1)))
12778 (set (reg:P CA_REGNO)
12779 (ne:P (match_dup 3)
12780 (const_int 0)))])
12781 (parallel [(set (match_dup 0)
12782 (plus:P (reg:P CA_REGNO)
12783 (const_int -1)))
12784 (clobber (reg:P CA_REGNO))])]
12785 {
12786 operands[3] = rs6000_emit_eqne (<MODE>mode,
12787 operands[1], operands[2], operands[3]);
12788
12789 if (GET_CODE (operands[4]) == SCRATCH)
12790 operands[4] = gen_reg_rtx (<MODE>mode);
12791 }
12792 [(set (attr "length")
12793 (if_then_else (match_test "operands[2] == const0_rtx")
12794 (const_string "8")
12795 (const_string "12")))])
12796
12797 (define_insn_and_split "*neg_ne_<mode>"
12798 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12799 (neg:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12800 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12801 (clobber (match_scratch:P 3 "=r"))
12802 (clobber (match_scratch:P 4 "=r"))
12803 (clobber (reg:P CA_REGNO))]
12804 "!TARGET_POWER10"
12805 "#"
12806 "&& 1"
12807 [(parallel [(set (match_dup 4)
12808 (neg:P (match_dup 3)))
12809 (set (reg:P CA_REGNO)
12810 (eq:P (match_dup 3)
12811 (const_int 0)))])
12812 (parallel [(set (match_dup 0)
12813 (plus:P (reg:P CA_REGNO)
12814 (const_int -1)))
12815 (clobber (reg:P CA_REGNO))])]
12816 {
12817 operands[3] = rs6000_emit_eqne (<MODE>mode,
12818 operands[1], operands[2], operands[3]);
12819
12820 if (GET_CODE (operands[4]) == SCRATCH)
12821 operands[4] = gen_reg_rtx (<MODE>mode);
12822 }
12823 [(set (attr "length")
12824 (if_then_else (match_test "operands[2] == const0_rtx")
12825 (const_string "8")
12826 (const_string "12")))])
12827
12828 (define_insn_and_split "*plus_eq_<mode>"
12829 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12830 (plus:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12831 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
12832 (match_operand:P 3 "gpc_reg_operand" "r")))
12833 (clobber (match_scratch:P 4 "=r"))
12834 (clobber (match_scratch:P 5 "=r"))
12835 (clobber (reg:P CA_REGNO))]
12836 ""
12837 "#"
12838 ""
12839 [(parallel [(set (match_dup 5)
12840 (neg:P (match_dup 4)))
12841 (set (reg:P CA_REGNO)
12842 (eq:P (match_dup 4)
12843 (const_int 0)))])
12844 (parallel [(set (match_dup 0)
12845 (plus:P (match_dup 3)
12846 (reg:P CA_REGNO)))
12847 (clobber (reg:P CA_REGNO))])]
12848 {
12849 operands[4] = rs6000_emit_eqne (<MODE>mode,
12850 operands[1], operands[2], operands[4]);
12851
12852 if (GET_CODE (operands[5]) == SCRATCH)
12853 operands[5] = gen_reg_rtx (<MODE>mode);
12854 }
12855 [(set (attr "length")
12856 (if_then_else (match_test "operands[2] == const0_rtx")
12857 (const_string "8")
12858 (const_string "12")))])
12859
12860 (define_insn_and_split "*plus_ne_<mode>"
12861 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12862 (plus:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12863 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
12864 (match_operand:P 3 "gpc_reg_operand" "r")))
12865 (clobber (match_scratch:P 4 "=r"))
12866 (clobber (match_scratch:P 5 "=r"))
12867 (clobber (reg:P CA_REGNO))]
12868 ""
12869 "#"
12870 ""
12871 [(parallel [(set (match_dup 5)
12872 (plus:P (match_dup 4)
12873 (const_int -1)))
12874 (set (reg:P CA_REGNO)
12875 (ne:P (match_dup 4)
12876 (const_int 0)))])
12877 (parallel [(set (match_dup 0)
12878 (plus:P (match_dup 3)
12879 (reg:P CA_REGNO)))
12880 (clobber (reg:P CA_REGNO))])]
12881 {
12882 operands[4] = rs6000_emit_eqne (<MODE>mode,
12883 operands[1], operands[2], operands[4]);
12884
12885 if (GET_CODE (operands[5]) == SCRATCH)
12886 operands[5] = gen_reg_rtx (<MODE>mode);
12887 }
12888 [(set (attr "length")
12889 (if_then_else (match_test "operands[2] == const0_rtx")
12890 (const_string "8")
12891 (const_string "12")))])
12892
12893 (define_insn_and_split "*minus_eq_<mode>"
12894 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12895 (minus:P (match_operand:P 3 "gpc_reg_operand" "r")
12896 (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12897 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12898 (clobber (match_scratch:P 4 "=r"))
12899 (clobber (match_scratch:P 5 "=r"))
12900 (clobber (reg:P CA_REGNO))]
12901 ""
12902 "#"
12903 ""
12904 [(parallel [(set (match_dup 5)
12905 (plus:P (match_dup 4)
12906 (const_int -1)))
12907 (set (reg:P CA_REGNO)
12908 (ne:P (match_dup 4)
12909 (const_int 0)))])
12910 (parallel [(set (match_dup 0)
12911 (plus:P (plus:P (match_dup 3)
12912 (reg:P CA_REGNO))
12913 (const_int -1)))
12914 (clobber (reg:P CA_REGNO))])]
12915 {
12916 operands[4] = rs6000_emit_eqne (<MODE>mode,
12917 operands[1], operands[2], operands[4]);
12918
12919 if (GET_CODE (operands[5]) == SCRATCH)
12920 operands[5] = gen_reg_rtx (<MODE>mode);
12921 }
12922 [(set (attr "length")
12923 (if_then_else (match_test "operands[2] == const0_rtx")
12924 (const_string "8")
12925 (const_string "12")))])
12926
12927 (define_insn_and_split "*minus_ne_<mode>"
12928 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12929 (minus:P (match_operand:P 3 "gpc_reg_operand" "r")
12930 (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12931 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12932 (clobber (match_scratch:P 4 "=r"))
12933 (clobber (match_scratch:P 5 "=r"))
12934 (clobber (reg:P CA_REGNO))]
12935 ""
12936 "#"
12937 ""
12938 [(parallel [(set (match_dup 5)
12939 (neg:P (match_dup 4)))
12940 (set (reg:P CA_REGNO)
12941 (eq:P (match_dup 4)
12942 (const_int 0)))])
12943 (parallel [(set (match_dup 0)
12944 (plus:P (plus:P (match_dup 3)
12945 (reg:P CA_REGNO))
12946 (const_int -1)))
12947 (clobber (reg:P CA_REGNO))])]
12948 {
12949 operands[4] = rs6000_emit_eqne (<MODE>mode,
12950 operands[1], operands[2], operands[4]);
12951
12952 if (GET_CODE (operands[5]) == SCRATCH)
12953 operands[5] = gen_reg_rtx (<MODE>mode);
12954 }
12955 [(set (attr "length")
12956 (if_then_else (match_test "operands[2] == const0_rtx")
12957 (const_string "8")
12958 (const_string "12")))])
12959
12960 (define_insn_and_split "*eqsi3_ext<mode>"
12961 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
12962 (eq:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
12963 (match_operand:SI 2 "scc_eq_operand" "rKLI")))
12964 (clobber (match_scratch:SI 3 "=r"))
12965 (clobber (match_scratch:SI 4 "=r"))]
12966 "!TARGET_POWER10"
12967 "#"
12968 "&& 1"
12969 [(set (match_dup 4)
12970 (clz:SI (match_dup 3)))
12971 (set (match_dup 0)
12972 (zero_extend:EXTSI
12973 (lshiftrt:SI (match_dup 4)
12974 (const_int 5))))]
12975 {
12976 operands[3] = rs6000_emit_eqne (SImode,
12977 operands[1], operands[2], operands[3]);
12978
12979 if (GET_CODE (operands[4]) == SCRATCH)
12980 operands[4] = gen_reg_rtx (SImode);
12981 }
12982 [(set (attr "length")
12983 (if_then_else (match_test "operands[2] == const0_rtx")
12984 (const_string "8")
12985 (const_string "12")))])
12986
12987 (define_insn_and_split "*nesi3_ext<mode>"
12988 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
12989 (ne:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
12990 (match_operand:SI 2 "scc_eq_operand" "rKLI")))
12991 (clobber (match_scratch:SI 3 "=r"))
12992 (clobber (match_scratch:SI 4 "=r"))
12993 (clobber (match_scratch:EXTSI 5 "=r"))]
12994 "!TARGET_ISEL"
12995 "#"
12996 "&& 1"
12997 [(set (match_dup 4)
12998 (clz:SI (match_dup 3)))
12999 (set (match_dup 5)
13000 (zero_extend:EXTSI
13001 (lshiftrt:SI (match_dup 4)
13002 (const_int 5))))
13003 (set (match_dup 0)
13004 (xor:EXTSI (match_dup 5)
13005 (const_int 1)))]
13006 {
13007 operands[3] = rs6000_emit_eqne (SImode,
13008 operands[1], operands[2], operands[3]);
13009
13010 if (GET_CODE (operands[4]) == SCRATCH)
13011 operands[4] = gen_reg_rtx (SImode);
13012 if (GET_CODE (operands[5]) == SCRATCH)
13013 operands[5] = gen_reg_rtx (<MODE>mode);
13014 }
13015 [(set (attr "length")
13016 (if_then_else (match_test "operands[2] == const0_rtx")
13017 (const_string "12")
13018 (const_string "16")))])
13019
13020
13021 (define_code_iterator fp_rev [ordered ne unle unge])
13022 (define_code_iterator fp_two [ltgt le ge unlt ungt uneq])
13023
13024 (define_insn_and_split "*<code><mode>_cc"
13025 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
13026 (fp_rev:GPR (match_operand:CCFP 1 "cc_reg_operand" "y")
13027 (const_int 0)))]
13028 "!flag_finite_math_only"
13029 "#"
13030 "&& 1"
13031 [(pc)]
13032 {
13033 rtx_code revcode = reverse_condition_maybe_unordered (<CODE>);
13034 rtx eq = gen_rtx_fmt_ee (revcode, <MODE>mode, operands[1], const0_rtx);
13035 rtx tmp = gen_reg_rtx (<MODE>mode);
13036 emit_move_insn (tmp, eq);
13037 emit_insn (gen_xor<mode>3 (operands[0], tmp, const1_rtx));
13038 DONE;
13039 }
13040 [(set_attr "length" "12")])
13041
13042 (define_insn_and_split "*<code><mode>_cc"
13043 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
13044 (fp_two:GPR (match_operand:CCFP 1 "cc_reg_operand" "y")
13045 (const_int 0)))]
13046 "!flag_finite_math_only"
13047 "#"
13048 "&& 1"
13049 [(pc)]
13050 {
13051 rtx cc = rs6000_emit_fp_cror (<CODE>, <MODE>mode, operands[1]);
13052
13053 emit_move_insn (operands[0], gen_rtx_EQ (<MODE>mode, cc, const0_rtx));
13054 DONE;
13055 }
13056 [(set_attr "length" "12")])
13057 \f
13058 ;; Conditional branches.
13059 ;; These either are a single bc insn, or a bc around a b.
13060
13061 (define_insn "*cbranch"
13062 [(set (pc)
13063 (if_then_else (match_operator 1 "branch_comparison_operator"
13064 [(match_operand 2 "cc_reg_operand" "y")
13065 (const_int 0)])
13066 (label_ref (match_operand 0))
13067 (pc)))]
13068 ""
13069 {
13070 return output_cbranch (operands[1], "%l0", 0, insn);
13071 }
13072 [(set_attr "type" "branch")
13073 (set (attr "length")
13074 (if_then_else (and (ge (minus (match_dup 0) (pc))
13075 (const_int -32768))
13076 (lt (minus (match_dup 0) (pc))
13077 (const_int 32764)))
13078 (const_int 4)
13079 (const_int 8)))])
13080
13081 (define_insn_and_split "*cbranch_2insn"
13082 [(set (pc)
13083 (if_then_else (match_operator 1 "extra_insn_branch_comparison_operator"
13084 [(match_operand 2 "cc_reg_operand" "y")
13085 (const_int 0)])
13086 (label_ref (match_operand 0))
13087 (pc)))]
13088 "!flag_finite_math_only"
13089 "#"
13090 "&& 1"
13091 [(pc)]
13092 {
13093 rtx cc = rs6000_emit_fp_cror (GET_CODE (operands[1]), SImode, operands[2]);
13094
13095 rtx note = find_reg_note (curr_insn, REG_BR_PROB, 0);
13096
13097 rtx loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands[0]);
13098 rtx cond = gen_rtx_EQ (CCEQmode, cc, const0_rtx);
13099 rtx ite = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, loc_ref, pc_rtx);
13100 emit_jump_insn (gen_rtx_SET (pc_rtx, ite));
13101
13102 if (note)
13103 {
13104 profile_probability prob
13105 = profile_probability::from_reg_br_prob_note (XINT (note, 0));
13106
13107 add_reg_br_prob_note (get_last_insn (), prob);
13108 }
13109
13110 DONE;
13111 }
13112 [(set_attr "type" "branch")
13113 (set (attr "length")
13114 (if_then_else (and (ge (minus (match_dup 0) (pc))
13115 (const_int -32764))
13116 (lt (minus (match_dup 0) (pc))
13117 (const_int 32760)))
13118 (const_int 8)
13119 (const_int 16)))])
13120
13121 ;; Conditional return.
13122 (define_insn "*creturn"
13123 [(set (pc)
13124 (if_then_else (match_operator 0 "branch_comparison_operator"
13125 [(match_operand 1 "cc_reg_operand" "y")
13126 (const_int 0)])
13127 (any_return)
13128 (pc)))]
13129 "<return_pred>"
13130 {
13131 return output_cbranch (operands[0], NULL, 0, insn);
13132 }
13133 [(set_attr "type" "jmpreg")])
13134
13135 ;; Logic on condition register values.
13136
13137 ; This pattern matches things like
13138 ; (set (reg:CCEQ 68) (compare:CCEQ (ior:SI (gt:SI (reg:CCFP 68) (const_int 0))
13139 ; (eq:SI (reg:CCFP 68) (const_int 0)))
13140 ; (const_int 1)))
13141 ; which are generated by the branch logic.
13142 ; Prefer destructive operations where BT = BB (for crXX BT,BA,BB)
13143
13144 (define_insn "@cceq_ior_compare_<mode>"
13145 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
13146 (compare:CCEQ (match_operator:GPR 1 "boolean_operator"
13147 [(match_operator:GPR 2
13148 "branch_positive_comparison_operator"
13149 [(match_operand 3
13150 "cc_reg_operand" "y,y")
13151 (const_int 0)])
13152 (match_operator:GPR 4
13153 "branch_positive_comparison_operator"
13154 [(match_operand 5
13155 "cc_reg_operand" "0,y")
13156 (const_int 0)])])
13157 (const_int 1)))]
13158 ""
13159 "cr%q1 %E0,%j2,%j4"
13160 [(set_attr "type" "cr_logical")
13161 (set_attr "cr_logical_3op" "no,yes")])
13162
13163 ; Why is the constant -1 here, but 1 in the previous pattern?
13164 ; Because ~1 has all but the low bit set.
13165 (define_insn "cceq_ior_compare_complement"
13166 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
13167 (compare:CCEQ (match_operator:SI 1 "boolean_operator"
13168 [(not:SI (match_operator:SI 2
13169 "branch_positive_comparison_operator"
13170 [(match_operand 3
13171 "cc_reg_operand" "y,y")
13172 (const_int 0)]))
13173 (match_operator:SI 4
13174 "branch_positive_comparison_operator"
13175 [(match_operand 5
13176 "cc_reg_operand" "0,y")
13177 (const_int 0)])])
13178 (const_int -1)))]
13179 ""
13180 "cr%q1 %E0,%j2,%j4"
13181 [(set_attr "type" "cr_logical")
13182 (set_attr "cr_logical_3op" "no,yes")])
13183
13184 (define_insn "@cceq_rev_compare_<mode>"
13185 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
13186 (compare:CCEQ (match_operator:GPR 1
13187 "branch_positive_comparison_operator"
13188 [(match_operand 2
13189 "cc_reg_operand" "0,y")
13190 (const_int 0)])
13191 (const_int 0)))]
13192 ""
13193 "crnot %E0,%j1"
13194 [(set_attr "type" "cr_logical")
13195 (set_attr "cr_logical_3op" "no,yes")])
13196
13197 ;; If we are comparing the result of two comparisons, this can be done
13198 ;; using creqv or crxor.
13199
13200 (define_insn_and_split ""
13201 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y")
13202 (compare:CCEQ (match_operator 1 "branch_comparison_operator"
13203 [(match_operand 2 "cc_reg_operand" "y")
13204 (const_int 0)])
13205 (match_operator 3 "branch_comparison_operator"
13206 [(match_operand 4 "cc_reg_operand" "y")
13207 (const_int 0)])))]
13208 ""
13209 "#"
13210 ""
13211 [(set (match_dup 0) (compare:CCEQ (xor:SI (match_dup 1) (match_dup 3))
13212 (match_dup 5)))]
13213 {
13214 int positive_1, positive_2;
13215
13216 positive_1 = branch_positive_comparison_operator (operands[1],
13217 GET_MODE (operands[1]));
13218 positive_2 = branch_positive_comparison_operator (operands[3],
13219 GET_MODE (operands[3]));
13220
13221 if (! positive_1)
13222 operands[1] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[2]),
13223 GET_CODE (operands[1])),
13224 SImode,
13225 operands[2], const0_rtx);
13226 else if (GET_MODE (operands[1]) != SImode)
13227 operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), SImode,
13228 operands[2], const0_rtx);
13229
13230 if (! positive_2)
13231 operands[3] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[4]),
13232 GET_CODE (operands[3])),
13233 SImode,
13234 operands[4], const0_rtx);
13235 else if (GET_MODE (operands[3]) != SImode)
13236 operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SImode,
13237 operands[4], const0_rtx);
13238
13239 if (positive_1 == positive_2)
13240 {
13241 operands[1] = gen_rtx_NOT (SImode, operands[1]);
13242 operands[5] = constm1_rtx;
13243 }
13244 else
13245 {
13246 operands[5] = const1_rtx;
13247 }
13248 })
13249
13250 ;; Unconditional branch and return.
13251
13252 (define_insn "jump"
13253 [(set (pc)
13254 (label_ref (match_operand 0)))]
13255 ""
13256 "b %l0"
13257 [(set_attr "type" "branch")])
13258
13259 (define_insn "<return_str>return"
13260 [(any_return)]
13261 "<return_pred>"
13262 "blr"
13263 [(set_attr "type" "jmpreg")])
13264
13265 (define_expand "indirect_jump"
13266 [(set (pc) (match_operand 0 "register_operand"))]
13267 ""
13268 {
13269 if (!rs6000_speculate_indirect_jumps) {
13270 rtx ccreg = gen_reg_rtx (CCmode);
13271 emit_jump_insn (gen_indirect_jump_nospec (Pmode, operands[0], ccreg));
13272 DONE;
13273 }
13274 })
13275
13276 (define_insn "*indirect_jump<mode>"
13277 [(set (pc)
13278 (match_operand:P 0 "register_operand" "c,*l"))]
13279 "rs6000_speculate_indirect_jumps"
13280 "b%T0"
13281 [(set_attr "type" "jmpreg")])
13282
13283 (define_insn "@indirect_jump<mode>_nospec"
13284 [(set (pc) (match_operand:P 0 "register_operand" "c,*l"))
13285 (clobber (match_operand:CC 1 "cc_reg_operand" "=y,y"))]
13286 "!rs6000_speculate_indirect_jumps"
13287 "crset %E1\;beq%T0- %1\;b $"
13288 [(set_attr "type" "jmpreg")
13289 (set_attr "length" "12")])
13290
13291 ;; Table jump for switch statements:
13292 (define_expand "tablejump"
13293 [(use (match_operand 0))
13294 (use (label_ref (match_operand 1)))]
13295 ""
13296 {
13297 if (rs6000_speculate_indirect_jumps)
13298 {
13299 if (rs6000_relative_jumptables)
13300 emit_jump_insn (gen_tablejump_normal (Pmode, operands[0], operands[1]));
13301 else
13302 emit_jump_insn (gen_tablejump_absolute (Pmode, operands[0],
13303 operands[1]));
13304 }
13305 else
13306 {
13307 rtx ccreg = gen_reg_rtx (CCmode);
13308 rtx jump;
13309 if (rs6000_relative_jumptables)
13310 jump = gen_tablejump_nospec (Pmode, operands[0], operands[1], ccreg);
13311 else
13312 jump = gen_tablejump_absolute_nospec (Pmode, operands[0], operands[1],
13313 ccreg);
13314 emit_jump_insn (jump);
13315 }
13316 DONE;
13317 })
13318
13319 (define_expand "@tablejump<mode>_normal"
13320 [(use (match_operand:SI 0))
13321 (use (match_operand:P 1))]
13322 "rs6000_speculate_indirect_jumps && rs6000_relative_jumptables"
13323 {
13324 rtx off = force_reg (SImode, operands[0]);
13325 if (<MODE>mode != SImode)
13326 {
13327 rtx src = gen_rtx_fmt_e (SIGN_EXTEND, Pmode, off);
13328 off = gen_reg_rtx (Pmode);
13329 emit_move_insn (off, src);
13330 }
13331
13332 rtx lab = force_reg (Pmode, gen_rtx_LABEL_REF (Pmode, operands[1]));
13333 rtx addr = gen_reg_rtx (Pmode);
13334
13335 emit_insn (gen_add<mode>3 (addr, off, lab));
13336 emit_jump_insn (gen_tablejump_insn_normal (Pmode, addr, operands[1]));
13337 DONE;
13338 })
13339
13340 (define_expand "@tablejump<mode>_absolute"
13341 [(use (match_operand:P 0))
13342 (use (match_operand:P 1))]
13343 "rs6000_speculate_indirect_jumps && !rs6000_relative_jumptables"
13344 {
13345 rtx addr = gen_reg_rtx (Pmode);
13346 emit_move_insn (addr, operands[0]);
13347
13348 emit_jump_insn (gen_tablejump_insn_normal (Pmode, addr, operands[1]));
13349 DONE;
13350 })
13351
13352 (define_expand "@tablejump<mode>_nospec"
13353 [(use (match_operand:SI 0))
13354 (use (match_operand:P 1))
13355 (use (match_operand:CC 2))]
13356 "!rs6000_speculate_indirect_jumps && rs6000_relative_jumptables"
13357 {
13358 rtx off = force_reg (SImode, operands[0]);
13359 if (<MODE>mode != SImode)
13360 {
13361 rtx src = gen_rtx_fmt_e (SIGN_EXTEND, Pmode, off);
13362 off = gen_reg_rtx (Pmode);
13363 emit_move_insn (off, src);
13364 }
13365
13366 rtx lab = force_reg (Pmode, gen_rtx_LABEL_REF (Pmode, operands[1]));
13367 rtx addr = gen_reg_rtx (Pmode);
13368
13369 emit_insn (gen_add<mode>3 (addr, off, lab));
13370 emit_jump_insn (gen_tablejump_insn_nospec (Pmode, addr, operands[1],
13371 operands[2]));
13372 DONE;
13373 })
13374
13375 (define_expand "@tablejump<mode>_absolute_nospec"
13376 [(use (match_operand:P 0))
13377 (use (match_operand:P 1))
13378 (use (match_operand:CC 2))]
13379 "!rs6000_speculate_indirect_jumps && !rs6000_relative_jumptables"
13380 {
13381 rtx addr = gen_reg_rtx (Pmode);
13382 emit_move_insn (addr, operands[0]);
13383
13384 emit_jump_insn (gen_tablejump_insn_nospec (Pmode, addr, operands[1],
13385 operands[2]));
13386 DONE;
13387 })
13388
13389 (define_insn "@tablejump<mode>_insn_normal"
13390 [(set (pc)
13391 (match_operand:P 0 "register_operand" "c,*l"))
13392 (use (label_ref (match_operand 1)))]
13393 "rs6000_speculate_indirect_jumps"
13394 "b%T0"
13395 [(set_attr "type" "jmpreg")])
13396
13397 (define_insn "@tablejump<mode>_insn_nospec"
13398 [(set (pc)
13399 (match_operand:P 0 "register_operand" "c,*l"))
13400 (use (label_ref (match_operand 1)))
13401 (clobber (match_operand:CC 2 "cc_reg_operand" "=y,y"))]
13402 "!rs6000_speculate_indirect_jumps"
13403 "crset %E2\;beq%T0- %2\;b $"
13404 [(set_attr "type" "jmpreg")
13405 (set_attr "length" "12")])
13406
13407 (define_insn "nop"
13408 [(unspec [(const_int 0)] UNSPEC_NOP)]
13409 ""
13410 "nop")
13411
13412 (define_insn "group_ending_nop"
13413 [(unspec [(const_int 0)] UNSPEC_GRP_END_NOP)]
13414 ""
13415 {
13416 operands[0] = gen_rtx_REG (Pmode,
13417 rs6000_tune == PROCESSOR_POWER6 ? 1 : 2);
13418 return "ori %0,%0,0";
13419 })
13420
13421 (define_insn "speculation_barrier"
13422 [(unspec_volatile:BLK [(const_int 0)] UNSPECV_SPEC_BARRIER)]
13423 ""
13424 {
13425 operands[0] = gen_rtx_REG (Pmode, 31);
13426 return "ori %0,%0,0";
13427 })
13428 \f
13429 ;; Define the subtract-one-and-jump insns, starting with the template
13430 ;; so loop.c knows what to generate.
13431
13432 (define_expand "doloop_end"
13433 [(use (match_operand 0)) ; loop pseudo
13434 (use (match_operand 1))] ; label
13435 ""
13436 {
13437 if (GET_MODE (operands[0]) != Pmode)
13438 FAIL;
13439
13440 emit_jump_insn (gen_ctr (Pmode, operands[0], operands[1]));
13441 DONE;
13442 })
13443
13444 (define_expand "@ctr<mode>"
13445 [(parallel [(set (pc)
13446 (if_then_else (ne (match_operand:P 0 "register_operand")
13447 (const_int 1))
13448 (label_ref (match_operand 1))
13449 (pc)))
13450 (set (match_dup 0)
13451 (plus:P (match_dup 0)
13452 (const_int -1)))
13453 (clobber (match_scratch:CC 2))
13454 (clobber (match_scratch:P 3))])]
13455 ""
13456 "")
13457
13458 ;; We need to be able to do this for any operand, including MEM, or we
13459 ;; will cause reload to blow up since we don't allow output reloads on
13460 ;; JUMP_INSNs.
13461 ;; For the length attribute to be calculated correctly, the
13462 ;; label MUST be operand 0.
13463 ;; rs6000_legitimate_combined_insn prevents combine creating any of
13464 ;; the ctr<mode> insns.
13465
13466 (define_code_iterator eqne [eq ne])
13467 (define_code_attr bd [(eq "bdz") (ne "bdnz")])
13468 (define_code_attr bd_neg [(eq "bdnz") (ne "bdz")])
13469
13470 (define_insn "<bd>_<mode>"
13471 [(set (pc)
13472 (if_then_else (eqne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
13473 (const_int 1))
13474 (label_ref (match_operand 0))
13475 (pc)))
13476 (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wa*c*l")
13477 (plus:P (match_dup 1)
13478 (const_int -1)))
13479 (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
13480 (clobber (match_scratch:P 4 "=X,X,&r,r"))]
13481 ""
13482 {
13483 if (which_alternative != 0)
13484 return "#";
13485 else if (get_attr_length (insn) == 4)
13486 return "<bd> %l0";
13487 else
13488 return "<bd_neg> $+8\;b %l0";
13489 }
13490 [(set_attr "type" "branch")
13491 (set_attr_alternative "length"
13492 [(if_then_else (and (ge (minus (match_dup 0) (pc))
13493 (const_int -32768))
13494 (lt (minus (match_dup 0) (pc))
13495 (const_int 32764)))
13496 (const_int 4)
13497 (const_int 8))
13498 (const_string "16")
13499 (const_string "20")
13500 (const_string "20")])])
13501
13502 ;; Now the splitter if we could not allocate the CTR register
13503 (define_split
13504 [(set (pc)
13505 (if_then_else (match_operator 2 "comparison_operator"
13506 [(match_operand:P 1 "gpc_reg_operand")
13507 (const_int 1)])
13508 (match_operand 5)
13509 (match_operand 6)))
13510 (set (match_operand:P 0 "nonimmediate_operand")
13511 (plus:P (match_dup 1)
13512 (const_int -1)))
13513 (clobber (match_scratch:CC 3))
13514 (clobber (match_scratch:P 4))]
13515 "reload_completed"
13516 [(set (pc)
13517 (if_then_else (match_dup 7)
13518 (match_dup 5)
13519 (match_dup 6)))]
13520 {
13521 operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[2]), VOIDmode, operands[3],
13522 const0_rtx);
13523 emit_insn (gen_rtx_SET (operands[3],
13524 gen_rtx_COMPARE (CCmode, operands[1], const1_rtx)));
13525 if (int_reg_operand (operands[0], <MODE>mode))
13526 emit_insn (gen_add<mode>3 (operands[0], operands[1], constm1_rtx));
13527 else
13528 {
13529 emit_insn (gen_add<mode>3 (operands[4], operands[1], constm1_rtx));
13530 emit_move_insn (operands[0], operands[4]);
13531 }
13532 /* No DONE so branch comes from the pattern. */
13533 })
13534
13535 ;; patterns for bdnzt/bdnzf/bdzt/bdzf
13536 ;; Note that in the case of long branches we have to decompose this into
13537 ;; bdnz+bc. This is because bdnzt has an implied AND between the ctr condition
13538 ;; and the CR bit, which means there is no way to conveniently invert the
13539 ;; comparison as is done with plain bdnz/bdz.
13540
13541 (define_insn "<bd>tf_<mode>"
13542 [(set (pc)
13543 (if_then_else
13544 (and
13545 (eqne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
13546 (const_int 1))
13547 (match_operator 3 "branch_comparison_operator"
13548 [(match_operand 4 "cc_reg_operand" "y,y,y,y")
13549 (const_int 0)]))
13550 (label_ref (match_operand 0))
13551 (pc)))
13552 (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wa*c*l")
13553 (plus:P (match_dup 1)
13554 (const_int -1)))
13555 (clobber (match_scratch:P 5 "=X,X,&r,r"))
13556 (clobber (match_scratch:CC 6 "=X,&y,&y,&y"))
13557 (clobber (match_scratch:CCEQ 7 "=X,&y,&y,&y"))]
13558 ""
13559 {
13560 if (which_alternative != 0)
13561 return "#";
13562 else if (get_attr_length (insn) == 4)
13563 {
13564 if (branch_positive_comparison_operator (operands[3],
13565 GET_MODE (operands[3])))
13566 return "<bd>t %j3,%l0";
13567 else
13568 return "<bd>f %j3,%l0";
13569 }
13570 else
13571 {
13572 static char seq[96];
13573 char *bcs = output_cbranch (operands[3], ".Lshort%=", 1, insn);
13574 sprintf(seq, "<bd_neg> .Lshort%%=\;%s\;b %%l0\;.Lshort%%=:", bcs);
13575 return seq;
13576 }
13577 }
13578 [(set_attr "type" "branch")
13579 (set_attr_alternative "length"
13580 [(if_then_else (and (ge (minus (match_dup 0) (pc))
13581 (const_int -32768))
13582 (lt (minus (match_dup 0) (pc))
13583 (const_int 32764)))
13584 (const_int 4)
13585 (const_int 8))
13586 (const_string "16")
13587 (const_string "20")
13588 (const_string "20")])])
13589
13590 ;; Now the splitter if we could not allocate the CTR register
13591 (define_split
13592 [(set (pc)
13593 (if_then_else
13594 (and
13595 (match_operator 1 "comparison_operator"
13596 [(match_operand:P 0 "gpc_reg_operand")
13597 (const_int 1)])
13598 (match_operator 3 "branch_comparison_operator"
13599 [(match_operand 2 "cc_reg_operand")
13600 (const_int 0)]))
13601 (match_operand 4)
13602 (match_operand 5)))
13603 (set (match_operand:P 6 "nonimmediate_operand")
13604 (plus:P (match_dup 0)
13605 (const_int -1)))
13606 (clobber (match_scratch:P 7))
13607 (clobber (match_scratch:CC 8))
13608 (clobber (match_scratch:CCEQ 9))]
13609 "reload_completed"
13610 [(pc)]
13611 {
13612 rtx ctr = operands[0];
13613 rtx ctrcmp = operands[1];
13614 rtx ccin = operands[2];
13615 rtx cccmp = operands[3];
13616 rtx dst1 = operands[4];
13617 rtx dst2 = operands[5];
13618 rtx ctrout = operands[6];
13619 rtx ctrtmp = operands[7];
13620 enum rtx_code cmpcode = GET_CODE (ctrcmp);
13621 bool ispos = branch_positive_comparison_operator (ctrcmp, GET_MODE (ctrcmp));
13622 if (!ispos)
13623 cmpcode = reverse_condition (cmpcode);
13624 /* Generate crand/crandc here. */
13625 emit_insn (gen_rtx_SET (operands[8],
13626 gen_rtx_COMPARE (CCmode, ctr, const1_rtx)));
13627 rtx ctrcmpcc = gen_rtx_fmt_ee (cmpcode, SImode, operands[8], const0_rtx);
13628
13629 rtx andexpr = gen_rtx_AND (SImode, ctrcmpcc, cccmp);
13630 if (ispos)
13631 emit_insn (gen_cceq_ior_compare (SImode, operands[9], andexpr, ctrcmpcc,
13632 operands[8], cccmp, ccin));
13633 else
13634 emit_insn (gen_cceq_ior_compare_complement (operands[9], andexpr, ctrcmpcc,
13635 operands[8], cccmp, ccin));
13636 if (int_reg_operand (ctrout, <MODE>mode))
13637 emit_insn (gen_add<mode>3 (ctrout, ctr, constm1_rtx));
13638 else
13639 {
13640 emit_insn (gen_add<mode>3 (ctrtmp, ctr, constm1_rtx));
13641 emit_move_insn (ctrout, ctrtmp);
13642 }
13643 rtx cmp = gen_rtx_EQ (CCEQmode, operands[9], const0_rtx);
13644 emit_jump_insn (gen_rtx_SET (pc_rtx,
13645 gen_rtx_IF_THEN_ELSE (VOIDmode, cmp,
13646 dst1, dst2)));
13647 DONE;
13648 })
13649
13650 \f
13651 (define_insn "trap"
13652 [(trap_if (const_int 1) (const_int 0))]
13653 ""
13654 "trap"
13655 [(set_attr "type" "trap")])
13656
13657 (define_expand "ctrap<mode>4"
13658 [(trap_if (match_operator 0 "ordered_comparison_operator"
13659 [(match_operand:GPR 1 "register_operand")
13660 (match_operand:GPR 2 "reg_or_short_operand")])
13661 (match_operand 3 "zero_constant" ""))]
13662 ""
13663 "")
13664
13665 (define_insn ""
13666 [(trap_if (match_operator 0 "ordered_comparison_operator"
13667 [(match_operand:GPR 1 "register_operand" "r")
13668 (match_operand:GPR 2 "reg_or_short_operand" "rI")])
13669 (const_int 0))]
13670 ""
13671 "t<wd>%V0%I2 %1,%2"
13672 [(set_attr "type" "trap")])
13673 \f
13674 ;; Insns related to generating the function prologue and epilogue.
13675
13676 (define_expand "prologue"
13677 [(use (const_int 0))]
13678 ""
13679 {
13680 rs6000_emit_prologue ();
13681 if (!TARGET_SCHED_PROLOG)
13682 emit_insn (gen_blockage ());
13683 DONE;
13684 })
13685
13686 (define_insn "*movesi_from_cr_one"
13687 [(match_parallel 0 "mfcr_operation"
13688 [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
13689 (unspec:SI [(match_operand:CC 2 "cc_reg_operand" "y")
13690 (match_operand 3 "immediate_operand" "n")]
13691 UNSPEC_MOVESI_FROM_CR))])]
13692 "TARGET_MFCRF"
13693 {
13694 int mask = 0;
13695 int i;
13696 for (i = 0; i < XVECLEN (operands[0], 0); i++)
13697 {
13698 mask = INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
13699 operands[4] = GEN_INT (mask);
13700 output_asm_insn ("mfcr %1,%4", operands);
13701 }
13702 return "";
13703 }
13704 [(set_attr "type" "mfcrf")])
13705
13706 ;; Don't include the volatile CRs since their values are not used wrt CR save
13707 ;; in the prologue and doing so prevents shrink-wrapping because we can't move the
13708 ;; prologue past an insn (early exit test) that defines a register used in the
13709 ;; prologue.
13710 (define_insn "prologue_movesi_from_cr"
13711 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
13712 (unspec:SI [(reg:CC CR2_REGNO) (reg:CC CR3_REGNO)
13713 (reg:CC CR4_REGNO)]
13714 UNSPEC_MOVESI_FROM_CR))]
13715 ""
13716 "mfcr %0"
13717 [(set_attr "type" "mfcr")])
13718
13719 (define_insn "*crsave"
13720 [(match_parallel 0 "crsave_operation"
13721 [(set (match_operand:SI 1 "memory_operand" "=m")
13722 (match_operand:SI 2 "gpc_reg_operand" "r"))])]
13723 ""
13724 "stw %2,%1"
13725 [(set_attr "type" "store")])
13726
13727 (define_insn "*stmw"
13728 [(match_parallel 0 "stmw_operation"
13729 [(set (match_operand:SI 1 "memory_operand" "=m")
13730 (match_operand:SI 2 "gpc_reg_operand" "r"))])]
13731 "TARGET_MULTIPLE"
13732 "stmw %2,%1"
13733 [(set_attr "type" "store")
13734 (set_attr "update" "yes")
13735 (set_attr "indexed" "yes")])
13736
13737 ; The following comment applies to:
13738 ; save_gpregs_*
13739 ; save_fpregs_*
13740 ; restore_gpregs*
13741 ; return_and_restore_gpregs*
13742 ; return_and_restore_fpregs*
13743 ; return_and_restore_fpregs_aix*
13744 ;
13745 ; The out-of-line save / restore functions expects one input argument.
13746 ; Since those are not standard call_insn's, we must avoid using
13747 ; MATCH_OPERAND for that argument. That way the register rename
13748 ; optimization will not try to rename this register.
13749 ; Each pattern is repeated for each possible register number used in
13750 ; various ABIs (r11, r1, and for some functions r12)
13751
13752 (define_insn "*save_gpregs_<mode>_r11"
13753 [(match_parallel 0 "any_parallel_operand"
13754 [(clobber (reg:P LR_REGNO))
13755 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13756 (use (reg:P 11))
13757 (set (match_operand:P 2 "memory_operand" "=m")
13758 (match_operand:P 3 "gpc_reg_operand" "r"))])]
13759 ""
13760 "bl %1"
13761 [(set_attr "type" "branch")])
13762
13763 (define_insn "*save_gpregs_<mode>_r12"
13764 [(match_parallel 0 "any_parallel_operand"
13765 [(clobber (reg:P LR_REGNO))
13766 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13767 (use (reg:P 12))
13768 (set (match_operand:P 2 "memory_operand" "=m")
13769 (match_operand:P 3 "gpc_reg_operand" "r"))])]
13770 ""
13771 "bl %1"
13772 [(set_attr "type" "branch")])
13773
13774 (define_insn "*save_gpregs_<mode>_r1"
13775 [(match_parallel 0 "any_parallel_operand"
13776 [(clobber (reg:P LR_REGNO))
13777 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13778 (use (reg:P 1))
13779 (set (match_operand:P 2 "memory_operand" "=m")
13780 (match_operand:P 3 "gpc_reg_operand" "r"))])]
13781 ""
13782 "bl %1"
13783 [(set_attr "type" "branch")])
13784
13785 (define_insn "*save_fpregs_<mode>_r11"
13786 [(match_parallel 0 "any_parallel_operand"
13787 [(clobber (reg:P LR_REGNO))
13788 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13789 (use (reg:P 11))
13790 (set (match_operand:DF 2 "memory_operand" "=m")
13791 (match_operand:DF 3 "gpc_reg_operand" "d"))])]
13792 ""
13793 "bl %1"
13794 [(set_attr "type" "branch")])
13795
13796 (define_insn "*save_fpregs_<mode>_r12"
13797 [(match_parallel 0 "any_parallel_operand"
13798 [(clobber (reg:P LR_REGNO))
13799 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13800 (use (reg:P 12))
13801 (set (match_operand:DF 2 "memory_operand" "=m")
13802 (match_operand:DF 3 "gpc_reg_operand" "d"))])]
13803 ""
13804 "bl %1"
13805 [(set_attr "type" "branch")])
13806
13807 (define_insn "*save_fpregs_<mode>_r1"
13808 [(match_parallel 0 "any_parallel_operand"
13809 [(clobber (reg:P LR_REGNO))
13810 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13811 (use (reg:P 1))
13812 (set (match_operand:DF 2 "memory_operand" "=m")
13813 (match_operand:DF 3 "gpc_reg_operand" "d"))])]
13814 ""
13815 "bl %1"
13816 [(set_attr "type" "branch")])
13817
13818 ; This is to explain that changes to the stack pointer should
13819 ; not be moved over loads from or stores to stack memory.
13820 (define_insn "stack_tie"
13821 [(match_parallel 0 "tie_operand"
13822 [(set (mem:BLK (reg 1)) (const_int 0))])]
13823 ""
13824 ""
13825 [(set_attr "length" "0")])
13826
13827 ; Some 32-bit ABIs do not have a red zone, so the stack deallocation has to
13828 ; stay behind all restores from the stack, it cannot be reordered to before
13829 ; one. See PR77687. This insn is an add or mr, and a memory clobber.
13830 (define_insn "stack_restore_tie"
13831 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
13832 (plus:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
13833 (match_operand:SI 2 "reg_or_cint_operand" "O,rI")))
13834 (set (mem:BLK (scratch)) (const_int 0))]
13835 "TARGET_32BIT"
13836 "@
13837 mr %0,%1
13838 add%I2 %0,%1,%2"
13839 [(set_attr "type" "*,add")])
13840
13841 (define_expand "epilogue"
13842 [(use (const_int 0))]
13843 ""
13844 {
13845 if (!TARGET_SCHED_PROLOG)
13846 emit_insn (gen_blockage ());
13847 rs6000_emit_epilogue (EPILOGUE_TYPE_NORMAL);
13848 DONE;
13849 })
13850
13851 ; On some processors, doing the mtcrf one CC register at a time is
13852 ; faster (like on the 604e). On others, doing them all at once is
13853 ; faster; for instance, on the 601 and 750.
13854
13855 (define_expand "movsi_to_cr_one"
13856 [(set (match_operand:CC 0 "cc_reg_operand")
13857 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand")
13858 (match_dup 2)] UNSPEC_MOVESI_TO_CR))]
13859 ""
13860 "operands[2] = GEN_INT (1 << (7 - (REGNO (operands[0]) - CR0_REGNO)));")
13861
13862 (define_insn "*movsi_to_cr"
13863 [(match_parallel 0 "mtcrf_operation"
13864 [(set (match_operand:CC 1 "cc_reg_operand" "=y")
13865 (unspec:CC [(match_operand:SI 2 "gpc_reg_operand" "r")
13866 (match_operand 3 "immediate_operand" "n")]
13867 UNSPEC_MOVESI_TO_CR))])]
13868 ""
13869 {
13870 int mask = 0;
13871 int i;
13872 for (i = 0; i < XVECLEN (operands[0], 0); i++)
13873 mask |= INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
13874 operands[4] = GEN_INT (mask);
13875 return "mtcrf %4,%2";
13876 }
13877 [(set_attr "type" "mtcr")])
13878
13879 (define_insn "*mtcrfsi"
13880 [(set (match_operand:CC 0 "cc_reg_operand" "=y")
13881 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
13882 (match_operand 2 "immediate_operand" "n")]
13883 UNSPEC_MOVESI_TO_CR))]
13884 "REG_P (operands[0])
13885 && CR_REGNO_P (REGNO (operands[0]))
13886 && CONST_INT_P (operands[2])
13887 && INTVAL (operands[2]) == 1 << (7 - (REGNO (operands[0]) - CR0_REGNO))"
13888 "mtcrf %R0,%1"
13889 [(set_attr "type" "mtcr")])
13890
13891 ; The load-multiple instructions have similar properties.
13892 ; Note that "load_multiple" is a name known to the machine-independent
13893 ; code that actually corresponds to the PowerPC load-string.
13894
13895 (define_insn "*lmw"
13896 [(match_parallel 0 "lmw_operation"
13897 [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
13898 (match_operand:SI 2 "memory_operand" "m"))])]
13899 "TARGET_MULTIPLE"
13900 "lmw %1,%2"
13901 [(set_attr "type" "load")
13902 (set_attr "update" "yes")
13903 (set_attr "indexed" "yes")
13904 (set_attr "cell_micro" "always")])
13905
13906 ; FIXME: "any_parallel_operand" is a bit flexible...
13907
13908 ; The following comment applies to:
13909 ; save_gpregs_*
13910 ; save_fpregs_*
13911 ; restore_gpregs*
13912 ; return_and_restore_gpregs*
13913 ; return_and_restore_fpregs*
13914 ; return_and_restore_fpregs_aix*
13915 ;
13916 ; The out-of-line save / restore functions expects one input argument.
13917 ; Since those are not standard call_insn's, we must avoid using
13918 ; MATCH_OPERAND for that argument. That way the register rename
13919 ; optimization will not try to rename this register.
13920 ; Each pattern is repeated for each possible register number used in
13921 ; various ABIs (r11, r1, and for some functions r12)
13922
13923 (define_insn "*restore_gpregs_<mode>_r11"
13924 [(match_parallel 0 "any_parallel_operand"
13925 [(clobber (reg:P LR_REGNO))
13926 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13927 (use (reg:P 11))
13928 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13929 (match_operand:P 3 "memory_operand" "m"))])]
13930 ""
13931 "bl %1"
13932 [(set_attr "type" "branch")])
13933
13934 (define_insn "*restore_gpregs_<mode>_r12"
13935 [(match_parallel 0 "any_parallel_operand"
13936 [(clobber (reg:P LR_REGNO))
13937 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13938 (use (reg:P 12))
13939 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13940 (match_operand:P 3 "memory_operand" "m"))])]
13941 ""
13942 "bl %1"
13943 [(set_attr "type" "branch")])
13944
13945 (define_insn "*restore_gpregs_<mode>_r1"
13946 [(match_parallel 0 "any_parallel_operand"
13947 [(clobber (reg:P LR_REGNO))
13948 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13949 (use (reg:P 1))
13950 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13951 (match_operand:P 3 "memory_operand" "m"))])]
13952 ""
13953 "bl %1"
13954 [(set_attr "type" "branch")])
13955
13956 (define_insn "*return_and_restore_gpregs_<mode>_r11"
13957 [(match_parallel 0 "any_parallel_operand"
13958 [(return)
13959 (clobber (reg:P LR_REGNO))
13960 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13961 (use (reg:P 11))
13962 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13963 (match_operand:P 3 "memory_operand" "m"))])]
13964 ""
13965 "b %1"
13966 [(set_attr "type" "branch")])
13967
13968 (define_insn "*return_and_restore_gpregs_<mode>_r12"
13969 [(match_parallel 0 "any_parallel_operand"
13970 [(return)
13971 (clobber (reg:P LR_REGNO))
13972 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13973 (use (reg:P 12))
13974 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13975 (match_operand:P 3 "memory_operand" "m"))])]
13976 ""
13977 "b %1"
13978 [(set_attr "type" "branch")])
13979
13980 (define_insn "*return_and_restore_gpregs_<mode>_r1"
13981 [(match_parallel 0 "any_parallel_operand"
13982 [(return)
13983 (clobber (reg:P LR_REGNO))
13984 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13985 (use (reg:P 1))
13986 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13987 (match_operand:P 3 "memory_operand" "m"))])]
13988 ""
13989 "b %1"
13990 [(set_attr "type" "branch")])
13991
13992 (define_insn "*return_and_restore_fpregs_<mode>_r11"
13993 [(match_parallel 0 "any_parallel_operand"
13994 [(return)
13995 (clobber (reg:P LR_REGNO))
13996 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13997 (use (reg:P 11))
13998 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13999 (match_operand:DF 3 "memory_operand" "m"))])]
14000 ""
14001 "b %1"
14002 [(set_attr "type" "branch")])
14003
14004 (define_insn "*return_and_restore_fpregs_<mode>_r12"
14005 [(match_parallel 0 "any_parallel_operand"
14006 [(return)
14007 (clobber (reg:P LR_REGNO))
14008 (use (match_operand:P 1 "symbol_ref_operand" "s"))
14009 (use (reg:P 12))
14010 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
14011 (match_operand:DF 3 "memory_operand" "m"))])]
14012 ""
14013 "b %1"
14014 [(set_attr "type" "branch")])
14015
14016 (define_insn "*return_and_restore_fpregs_<mode>_r1"
14017 [(match_parallel 0 "any_parallel_operand"
14018 [(return)
14019 (clobber (reg:P LR_REGNO))
14020 (use (match_operand:P 1 "symbol_ref_operand" "s"))
14021 (use (reg:P 1))
14022 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
14023 (match_operand:DF 3 "memory_operand" "m"))])]
14024 ""
14025 "b %1"
14026 [(set_attr "type" "branch")])
14027
14028 (define_insn "*return_and_restore_fpregs_aix_<mode>_r11"
14029 [(match_parallel 0 "any_parallel_operand"
14030 [(return)
14031 (use (match_operand:P 1 "symbol_ref_operand" "s"))
14032 (use (reg:P 11))
14033 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
14034 (match_operand:DF 3 "memory_operand" "m"))])]
14035 ""
14036 "b %1"
14037 [(set_attr "type" "branch")])
14038
14039 (define_insn "*return_and_restore_fpregs_aix_<mode>_r1"
14040 [(match_parallel 0 "any_parallel_operand"
14041 [(return)
14042 (use (match_operand:P 1 "symbol_ref_operand" "s"))
14043 (use (reg:P 1))
14044 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
14045 (match_operand:DF 3 "memory_operand" "m"))])]
14046 ""
14047 "b %1"
14048 [(set_attr "type" "branch")])
14049
14050 ; This is used in compiling the unwind routines.
14051 (define_expand "eh_return"
14052 [(use (match_operand 0 "general_operand"))]
14053 ""
14054 {
14055 emit_insn (gen_eh_set_lr (Pmode, operands[0]));
14056 DONE;
14057 })
14058
14059 ; We can't expand this before we know where the link register is stored.
14060 (define_insn_and_split "@eh_set_lr_<mode>"
14061 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")] UNSPECV_EH_RR)
14062 (clobber (match_scratch:P 1 "=&b"))]
14063 ""
14064 "#"
14065 "reload_completed"
14066 [(const_int 0)]
14067 {
14068 rs6000_emit_eh_reg_restore (operands[0], operands[1]);
14069 DONE;
14070 })
14071
14072 (define_insn "prefetch"
14073 [(prefetch (match_operand 0 "indexed_or_indirect_address" "a")
14074 (match_operand:SI 1 "const_int_operand" "n")
14075 (match_operand:SI 2 "const_int_operand" "n"))]
14076 ""
14077 {
14078
14079
14080 /* dcbtstt, dcbtt and TH=0b10000 support starts with ISA 2.06 (Power7).
14081 AIX does not support the dcbtstt and dcbtt extended mnemonics.
14082 The AIX assembler does not support the three operand form of dcbt
14083 and dcbtst on Power 7 (-mpwr7). */
14084 int inst_select = INTVAL (operands[2]) || !TARGET_DIRECT_MOVE;
14085
14086 if (REG_P (operands[0]))
14087 {
14088 if (INTVAL (operands[1]) == 0)
14089 return inst_select ? "dcbt 0,%0" : "dcbt 0,%0,16";
14090 else
14091 return inst_select ? "dcbtst 0,%0" : "dcbtst 0,%0,16";
14092 }
14093 else
14094 {
14095 if (INTVAL (operands[1]) == 0)
14096 return inst_select ? "dcbt %a0" : "dcbt %a0,16";
14097 else
14098 return inst_select ? "dcbtst %a0" : "dcbtst %a0,16";
14099 }
14100 }
14101 [(set_attr "type" "load")])
14102 \f
14103 ;; Handle -fsplit-stack.
14104
14105 (define_expand "split_stack_prologue"
14106 [(const_int 0)]
14107 ""
14108 {
14109 rs6000_expand_split_stack_prologue ();
14110 DONE;
14111 })
14112
14113 (define_expand "load_split_stack_limit"
14114 [(set (match_operand 0)
14115 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))]
14116 ""
14117 {
14118 emit_insn (gen_rtx_SET (operands[0],
14119 gen_rtx_UNSPEC (Pmode,
14120 gen_rtvec (1, const0_rtx),
14121 UNSPEC_STACK_CHECK)));
14122 DONE;
14123 })
14124
14125 (define_insn "load_split_stack_limit_di"
14126 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
14127 (unspec:DI [(const_int 0)] UNSPEC_STACK_CHECK))]
14128 "TARGET_64BIT"
14129 "ld %0,-0x7040(13)"
14130 [(set_attr "type" "load")
14131 (set_attr "update" "no")
14132 (set_attr "indexed" "no")])
14133
14134 (define_insn "load_split_stack_limit_si"
14135 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
14136 (unspec:SI [(const_int 0)] UNSPEC_STACK_CHECK))]
14137 "!TARGET_64BIT"
14138 "lwz %0,-0x7020(2)"
14139 [(set_attr "type" "load")
14140 (set_attr "update" "no")
14141 (set_attr "indexed" "no")])
14142
14143 ;; A return instruction which the middle-end doesn't see.
14144 ;; Use r0 to stop regrename twiddling with lr restore insns emitted
14145 ;; after the call to __morestack.
14146 (define_insn "split_stack_return"
14147 [(unspec_volatile [(reg:SI 0) (reg:SI LR_REGNO)] UNSPECV_SPLIT_STACK_RETURN)]
14148 ""
14149 "blr"
14150 [(set_attr "type" "jmpreg")])
14151
14152 ;; If there are operand 0 bytes available on the stack, jump to
14153 ;; operand 1.
14154 (define_expand "split_stack_space_check"
14155 [(set (match_dup 2)
14156 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
14157 (set (match_dup 3)
14158 (minus (reg STACK_POINTER_REGNUM)
14159 (match_operand 0)))
14160 (set (match_dup 4) (compare:CCUNS (match_dup 3) (match_dup 2)))
14161 (set (pc) (if_then_else
14162 (geu (match_dup 4) (const_int 0))
14163 (label_ref (match_operand 1))
14164 (pc)))]
14165 ""
14166 {
14167 rs6000_split_stack_space_check (operands[0], operands[1]);
14168 DONE;
14169 })
14170 \f
14171 (define_insn "bpermd_<mode>"
14172 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
14173 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "r")
14174 (match_operand:P 2 "gpc_reg_operand" "r")] UNSPEC_BPERM))]
14175 "TARGET_POPCNTD"
14176 "bpermd %0,%1,%2"
14177 [(set_attr "type" "popcnt")])
14178
14179 \f
14180 ;; Builtin fma support. Handle
14181 ;; Note that the conditions for expansion are in the FMA_F iterator.
14182
14183 (define_expand "fma<mode>4"
14184 [(set (match_operand:FMA_F 0 "gpc_reg_operand")
14185 (fma:FMA_F
14186 (match_operand:FMA_F 1 "gpc_reg_operand")
14187 (match_operand:FMA_F 2 "gpc_reg_operand")
14188 (match_operand:FMA_F 3 "gpc_reg_operand")))]
14189 ""
14190 "")
14191
14192 (define_insn "*fma<mode>4_fpr"
14193 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,wa,wa")
14194 (fma:SFDF
14195 (match_operand:SFDF 1 "gpc_reg_operand" "%d,wa,wa")
14196 (match_operand:SFDF 2 "gpc_reg_operand" "d,wa,0")
14197 (match_operand:SFDF 3 "gpc_reg_operand" "d,0,wa")))]
14198 "TARGET_HARD_FLOAT"
14199 "@
14200 fmadd<s> %0,%1,%2,%3
14201 xsmadda<sd>p %x0,%x1,%x2
14202 xsmaddm<sd>p %x0,%x1,%x3"
14203 [(set_attr "type" "fp")
14204 (set_attr "isa" "*,<Fisa>,<Fisa>")])
14205
14206 ; Altivec only has fma and nfms.
14207 (define_expand "fms<mode>4"
14208 [(set (match_operand:FMA_F 0 "gpc_reg_operand")
14209 (fma:FMA_F
14210 (match_operand:FMA_F 1 "gpc_reg_operand")
14211 (match_operand:FMA_F 2 "gpc_reg_operand")
14212 (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand"))))]
14213 "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
14214 "")
14215
14216 (define_insn "*fms<mode>4_fpr"
14217 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,wa,wa")
14218 (fma:SFDF
14219 (match_operand:SFDF 1 "gpc_reg_operand" "d,wa,wa")
14220 (match_operand:SFDF 2 "gpc_reg_operand" "d,wa,0")
14221 (neg:SFDF (match_operand:SFDF 3 "gpc_reg_operand" "d,0,wa"))))]
14222 "TARGET_HARD_FLOAT"
14223 "@
14224 fmsub<s> %0,%1,%2,%3
14225 xsmsuba<sd>p %x0,%x1,%x2
14226 xsmsubm<sd>p %x0,%x1,%x3"
14227 [(set_attr "type" "fp")
14228 (set_attr "isa" "*,<Fisa>,<Fisa>")])
14229
14230 ;; If signed zeros are ignored, -(a * b - c) = -a * b + c.
14231 (define_expand "fnma<mode>4"
14232 [(set (match_operand:FMA_F 0 "gpc_reg_operand")
14233 (neg:FMA_F
14234 (fma:FMA_F
14235 (match_operand:FMA_F 1 "gpc_reg_operand")
14236 (match_operand:FMA_F 2 "gpc_reg_operand")
14237 (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand")))))]
14238 "!HONOR_SIGNED_ZEROS (<MODE>mode)"
14239 "")
14240
14241 ;; If signed zeros are ignored, -(a * b + c) = -a * b - c.
14242 (define_expand "fnms<mode>4"
14243 [(set (match_operand:FMA_F 0 "gpc_reg_operand")
14244 (neg:FMA_F
14245 (fma:FMA_F
14246 (match_operand:FMA_F 1 "gpc_reg_operand")
14247 (match_operand:FMA_F 2 "gpc_reg_operand")
14248 (match_operand:FMA_F 3 "gpc_reg_operand"))))]
14249 "!HONOR_SIGNED_ZEROS (<MODE>mode) && !VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
14250 "")
14251
14252 ; Not an official optab name, but used from builtins.
14253 (define_expand "nfma<mode>4"
14254 [(set (match_operand:FMA_F 0 "gpc_reg_operand")
14255 (neg:FMA_F
14256 (fma:FMA_F
14257 (match_operand:FMA_F 1 "gpc_reg_operand")
14258 (match_operand:FMA_F 2 "gpc_reg_operand")
14259 (match_operand:FMA_F 3 "gpc_reg_operand"))))]
14260 "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
14261 "")
14262
14263 (define_insn "*nfma<mode>4_fpr"
14264 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,wa,wa")
14265 (neg:SFDF
14266 (fma:SFDF
14267 (match_operand:SFDF 1 "gpc_reg_operand" "d,wa,wa")
14268 (match_operand:SFDF 2 "gpc_reg_operand" "d,wa,0")
14269 (match_operand:SFDF 3 "gpc_reg_operand" "d,0,wa"))))]
14270 "TARGET_HARD_FLOAT"
14271 "@
14272 fnmadd<s> %0,%1,%2,%3
14273 xsnmadda<sd>p %x0,%x1,%x2
14274 xsnmaddm<sd>p %x0,%x1,%x3"
14275 [(set_attr "type" "fp")
14276 (set_attr "isa" "*,<Fisa>,<Fisa>")])
14277
14278 ; Not an official optab name, but used from builtins.
14279 (define_expand "nfms<mode>4"
14280 [(set (match_operand:FMA_F 0 "gpc_reg_operand")
14281 (neg:FMA_F
14282 (fma:FMA_F
14283 (match_operand:FMA_F 1 "gpc_reg_operand")
14284 (match_operand:FMA_F 2 "gpc_reg_operand")
14285 (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand")))))]
14286 ""
14287 "")
14288
14289 (define_insn "*nfmssf4_fpr"
14290 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,wa,wa")
14291 (neg:SFDF
14292 (fma:SFDF
14293 (match_operand:SFDF 1 "gpc_reg_operand" "d,wa,wa")
14294 (match_operand:SFDF 2 "gpc_reg_operand" "d,wa,0")
14295 (neg:SFDF
14296 (match_operand:SFDF 3 "gpc_reg_operand" "d,0,wa")))))]
14297 "TARGET_HARD_FLOAT"
14298 "@
14299 fnmsub<s> %0,%1,%2,%3
14300 xsnmsuba<sd>p %x0,%x1,%x2
14301 xsnmsubm<sd>p %x0,%x1,%x3"
14302 [(set_attr "type" "fp")
14303 (set_attr "isa" "*,<Fisa>,<Fisa>")])
14304 \f
14305 (define_expand "rs6000_get_timebase"
14306 [(use (match_operand:DI 0 "gpc_reg_operand"))]
14307 ""
14308 {
14309 if (TARGET_POWERPC64)
14310 emit_insn (gen_rs6000_mftb_di (operands[0]));
14311 else
14312 emit_insn (gen_rs6000_get_timebase_ppc32 (operands[0]));
14313 DONE;
14314 })
14315
14316 (define_insn "rs6000_get_timebase_ppc32"
14317 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
14318 (unspec_volatile:DI [(const_int 0)] UNSPECV_MFTB))
14319 (clobber (match_scratch:SI 1 "=r"))
14320 (clobber (match_scratch:CC 2 "=y"))]
14321 "!TARGET_POWERPC64"
14322 {
14323 if (WORDS_BIG_ENDIAN)
14324 if (TARGET_MFCRF)
14325 {
14326 return "mfspr %0,269\;"
14327 "mfspr %L0,268\;"
14328 "mfspr %1,269\;"
14329 "cmpw %2,%0,%1\;"
14330 "bne- %2,$-16";
14331 }
14332 else
14333 {
14334 return "mftbu %0\;"
14335 "mftb %L0\;"
14336 "mftbu %1\;"
14337 "cmpw %2,%0,%1\;"
14338 "bne- %2,$-16";
14339 }
14340 else
14341 if (TARGET_MFCRF)
14342 {
14343 return "mfspr %L0,269\;"
14344 "mfspr %0,268\;"
14345 "mfspr %1,269\;"
14346 "cmpw %2,%L0,%1\;"
14347 "bne- %2,$-16";
14348 }
14349 else
14350 {
14351 return "mftbu %L0\;"
14352 "mftb %0\;"
14353 "mftbu %1\;"
14354 "cmpw %2,%L0,%1\;"
14355 "bne- %2,$-16";
14356 }
14357 }
14358 [(set_attr "length" "20")])
14359
14360 (define_insn "rs6000_mftb_<mode>"
14361 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
14362 (unspec_volatile:GPR [(const_int 0)] UNSPECV_MFTB))]
14363 ""
14364 {
14365 if (TARGET_MFCRF)
14366 return "mfspr %0,268";
14367 else
14368 return "mftb %0";
14369 })
14370
14371 \f
14372 ;; The ISA 3.0 mffsl instruction is a lower latency instruction
14373 ;; for reading bits [29:31], [45:51] and [56:63] of the FPSCR.
14374 (define_insn "rs6000_mffsl_hw"
14375 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
14376 (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFSL))]
14377 "TARGET_HARD_FLOAT"
14378 "mffsl %0")
14379
14380 (define_expand "rs6000_mffsl"
14381 [(set (match_operand:DF 0 "gpc_reg_operand")
14382 (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFSL))]
14383 "TARGET_HARD_FLOAT"
14384 {
14385 /* If the low latency mffsl instruction (ISA 3.0) is available use it,
14386 otherwise fall back to the older mffs instruction to emulate the mffsl
14387 instruction. */
14388
14389 if (!TARGET_P9_MISC)
14390 {
14391 rtx tmp1 = gen_reg_rtx (DFmode);
14392
14393 /* The mffs instruction reads the entire FPSCR. Emulate the mffsl
14394 instruction using the mffs instruction and masking the result. */
14395 emit_insn (gen_rs6000_mffs (tmp1));
14396
14397 rtx tmp1di = simplify_gen_subreg (DImode, tmp1, DFmode, 0);
14398 rtx tmp2 = gen_reg_rtx (DImode);
14399 emit_insn (gen_anddi3 (tmp2, tmp1di, GEN_INT (0x70007f0ffLL)));
14400
14401 rtx tmp2df = simplify_gen_subreg (DFmode, tmp2, DImode, 0);
14402 emit_move_insn (operands[0], tmp2df);
14403 DONE;
14404 }
14405
14406 emit_insn (gen_rs6000_mffsl_hw (operands[0]));
14407 DONE;
14408 })
14409
14410 (define_insn "rs6000_mffs"
14411 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
14412 (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFS))]
14413 "TARGET_HARD_FLOAT"
14414 "mffs %0")
14415
14416 (define_insn "rs6000_mtfsf"
14417 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "i")
14418 (match_operand:DF 1 "gpc_reg_operand" "d")]
14419 UNSPECV_MTFSF)]
14420 "TARGET_HARD_FLOAT"
14421 "mtfsf %0,%1")
14422
14423 (define_insn "rs6000_mtfsf_hi"
14424 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "n")
14425 (match_operand:DF 1 "gpc_reg_operand" "d")]
14426 UNSPECV_MTFSF_HI)]
14427 "TARGET_HARD_FLOAT"
14428 "mtfsf %0,%1,0,1")
14429
14430 \f
14431 ;; Power8 fusion support for fusing an addis instruction with a D-form load of
14432 ;; a GPR. The addis instruction must be adjacent to the load, and use the same
14433 ;; register that is being loaded. The fused ops must be physically adjacent.
14434
14435 ;; On Power8 GPR loads, we try to use the register that is being load. The
14436 ;; peephole2 then gathers any other fused possibilities that it can find after
14437 ;; register allocation. If power9 fusion is selected, we also fuse floating
14438 ;; point loads/stores.
14439
14440 ;; Find cases where the addis that feeds into a load instruction is either used
14441 ;; once or is the same as the target register, and replace it with the fusion
14442 ;; insn
14443
14444 (define_peephole2
14445 [(set (match_operand:P 0 "base_reg_operand")
14446 (match_operand:P 1 "fusion_gpr_addis"))
14447 (set (match_operand:INT1 2 "base_reg_operand")
14448 (match_operand:INT1 3 "fusion_gpr_mem_load"))]
14449 "TARGET_P8_FUSION
14450 && fusion_gpr_load_p (operands[0], operands[1], operands[2],
14451 operands[3])"
14452 [(const_int 0)]
14453 {
14454 expand_fusion_gpr_load (operands);
14455 DONE;
14456 })
14457
14458 ;; Fusion insn, created by the define_peephole2 above (and eventually by
14459 ;; reload)
14460
14461 (define_insn "*fusion_gpr_load_<mode>"
14462 [(set (match_operand:INT1 0 "base_reg_operand" "=b")
14463 (unspec:INT1 [(match_operand:INT1 1 "fusion_addis_mem_combo_load" "wF")]
14464 UNSPEC_FUSION_GPR))]
14465 "TARGET_P8_FUSION"
14466 {
14467 return emit_fusion_gpr_load (operands[0], operands[1]);
14468 }
14469 [(set_attr "type" "load")
14470 (set_attr "length" "8")])
14471
14472 \f
14473 ;; Optimize cases where we want to do a D-form load (register+offset) on
14474 ;; ISA 2.06/2.07 to an Altivec register, and the register allocator
14475 ;; has generated:
14476 ;; LFD 0,32(3)
14477 ;; XXLOR 32,0,0
14478 ;;
14479 ;; and we change this to:
14480 ;; LI 0,32
14481 ;; LXSDX 32,3,9
14482
14483 (define_peephole2
14484 [(match_scratch:P 0 "b")
14485 (set (match_operand:ALTIVEC_DFORM 1 "fpr_reg_operand")
14486 (match_operand:ALTIVEC_DFORM 2 "simple_offsettable_mem_operand"))
14487 (set (match_operand:ALTIVEC_DFORM 3 "altivec_register_operand")
14488 (match_dup 1))]
14489 "TARGET_VSX && !TARGET_P9_VECTOR && peep2_reg_dead_p (2, operands[1])"
14490 [(set (match_dup 0)
14491 (match_dup 4))
14492 (set (match_dup 3)
14493 (match_dup 5))]
14494 {
14495 rtx tmp_reg = operands[0];
14496 rtx mem = operands[2];
14497 rtx addr = XEXP (mem, 0);
14498 rtx add_op0, add_op1, new_addr;
14499
14500 gcc_assert (GET_CODE (addr) == PLUS || GET_CODE (addr) == LO_SUM);
14501 add_op0 = XEXP (addr, 0);
14502 add_op1 = XEXP (addr, 1);
14503 gcc_assert (REG_P (add_op0));
14504 new_addr = gen_rtx_PLUS (Pmode, add_op0, tmp_reg);
14505
14506 operands[4] = add_op1;
14507 operands[5] = change_address (mem, <ALTIVEC_DFORM:MODE>mode, new_addr);
14508 })
14509
14510 ;; Optimize cases were want to do a D-form store on ISA 2.06/2.07 from an
14511 ;; Altivec register, and the register allocator has generated:
14512 ;; XXLOR 0,32,32
14513 ;; STFD 0,32(3)
14514 ;;
14515 ;; and we change this to:
14516 ;; LI 0,32
14517 ;; STXSDX 32,3,9
14518
14519 (define_peephole2
14520 [(match_scratch:P 0 "b")
14521 (set (match_operand:ALTIVEC_DFORM 1 "fpr_reg_operand")
14522 (match_operand:ALTIVEC_DFORM 2 "altivec_register_operand"))
14523 (set (match_operand:ALTIVEC_DFORM 3 "simple_offsettable_mem_operand")
14524 (match_dup 1))]
14525 "TARGET_VSX && !TARGET_P9_VECTOR && peep2_reg_dead_p (2, operands[1])"
14526 [(set (match_dup 0)
14527 (match_dup 4))
14528 (set (match_dup 5)
14529 (match_dup 2))]
14530 {
14531 rtx tmp_reg = operands[0];
14532 rtx mem = operands[3];
14533 rtx addr = XEXP (mem, 0);
14534 rtx add_op0, add_op1, new_addr;
14535
14536 gcc_assert (GET_CODE (addr) == PLUS || GET_CODE (addr) == LO_SUM);
14537 add_op0 = XEXP (addr, 0);
14538 add_op1 = XEXP (addr, 1);
14539 gcc_assert (REG_P (add_op0));
14540 new_addr = gen_rtx_PLUS (Pmode, add_op0, tmp_reg);
14541
14542 operands[4] = add_op1;
14543 operands[5] = change_address (mem, <ALTIVEC_DFORM:MODE>mode, new_addr);
14544 })
14545
14546 \f
14547 ;; Miscellaneous ISA 2.06 (power7) instructions
14548 (define_insn "addg6s"
14549 [(set (match_operand:SI 0 "register_operand" "=r")
14550 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
14551 (match_operand:SI 2 "register_operand" "r")]
14552 UNSPEC_ADDG6S))]
14553 "TARGET_POPCNTD"
14554 "addg6s %0,%1,%2"
14555 [(set_attr "type" "integer")])
14556
14557 (define_insn "cdtbcd"
14558 [(set (match_operand:SI 0 "register_operand" "=r")
14559 (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
14560 UNSPEC_CDTBCD))]
14561 "TARGET_POPCNTD"
14562 "cdtbcd %0,%1"
14563 [(set_attr "type" "integer")])
14564
14565 (define_insn "cbcdtd"
14566 [(set (match_operand:SI 0 "register_operand" "=r")
14567 (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
14568 UNSPEC_CBCDTD))]
14569 "TARGET_POPCNTD"
14570 "cbcdtd %0,%1"
14571 [(set_attr "type" "integer")])
14572
14573 (define_int_iterator UNSPEC_DIV_EXTEND [UNSPEC_DIVE
14574 UNSPEC_DIVEU])
14575
14576 (define_int_attr div_extend [(UNSPEC_DIVE "e")
14577 (UNSPEC_DIVEU "eu")])
14578
14579 (define_insn "div<div_extend>_<mode>"
14580 [(set (match_operand:GPR 0 "register_operand" "=r")
14581 (unspec:GPR [(match_operand:GPR 1 "register_operand" "r")
14582 (match_operand:GPR 2 "register_operand" "r")]
14583 UNSPEC_DIV_EXTEND))]
14584 "TARGET_POPCNTD"
14585 "div<wd><div_extend> %0,%1,%2"
14586 [(set_attr "type" "div")
14587 (set_attr "size" "<bits>")])
14588
14589 \f
14590 ;; Pack/unpack 128-bit floating point types that take 2 scalar registers
14591
14592 ; Type of the 64-bit part when packing/unpacking 128-bit floating point types
14593 (define_mode_attr FP128_64 [(TF "DF")
14594 (IF "DF")
14595 (TD "DI")
14596 (KF "DI")])
14597
14598 (define_expand "unpack<mode>"
14599 [(set (match_operand:<FP128_64> 0 "nonimmediate_operand")
14600 (unspec:<FP128_64>
14601 [(match_operand:FMOVE128 1 "register_operand")
14602 (match_operand:QI 2 "const_0_to_1_operand")]
14603 UNSPEC_UNPACK_128BIT))]
14604 "FLOAT128_2REG_P (<MODE>mode)"
14605 "")
14606
14607 (define_insn_and_split "unpack<mode>_dm"
14608 [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m,d,r,m")
14609 (unspec:<FP128_64>
14610 [(match_operand:FMOVE128 1 "register_operand" "d,d,r,d,r")
14611 (match_operand:QI 2 "const_0_to_1_operand" "i,i,i,i,i")]
14612 UNSPEC_UNPACK_128BIT))]
14613 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE && FLOAT128_2REG_P (<MODE>mode)"
14614 "#"
14615 "&& reload_completed"
14616 [(set (match_dup 0) (match_dup 3))]
14617 {
14618 unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
14619
14620 if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
14621 {
14622 emit_note (NOTE_INSN_DELETED);
14623 DONE;
14624 }
14625
14626 operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
14627 }
14628 [(set_attr "type" "fp,fpstore,mtvsr,mfvsr,store")])
14629
14630 (define_insn_and_split "unpack<mode>_nodm"
14631 [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m,m")
14632 (unspec:<FP128_64>
14633 [(match_operand:FMOVE128 1 "register_operand" "d,d,r")
14634 (match_operand:QI 2 "const_0_to_1_operand" "i,i,i")]
14635 UNSPEC_UNPACK_128BIT))]
14636 "(!TARGET_POWERPC64 || !TARGET_DIRECT_MOVE) && FLOAT128_2REG_P (<MODE>mode)"
14637 "#"
14638 "&& reload_completed"
14639 [(set (match_dup 0) (match_dup 3))]
14640 {
14641 unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
14642
14643 if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
14644 {
14645 emit_note (NOTE_INSN_DELETED);
14646 DONE;
14647 }
14648
14649 operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
14650 }
14651 [(set_attr "type" "fp,fpstore,store")])
14652
14653 (define_expand "pack<mode>"
14654 [(use (match_operand:FMOVE128 0 "register_operand"))
14655 (use (match_operand:<FP128_64> 1 "register_operand"))
14656 (use (match_operand:<FP128_64> 2 "register_operand"))]
14657 "FLOAT128_2REG_P (<MODE>mode)"
14658 {
14659 if (TARGET_HARD_FLOAT)
14660 emit_insn (gen_pack<mode>_hard (operands[0], operands[1], operands[2]));
14661 else
14662 emit_insn (gen_pack<mode>_soft (operands[0], operands[1], operands[2]));
14663 DONE;
14664 })
14665
14666 (define_insn_and_split "pack<mode>_hard"
14667 [(set (match_operand:FMOVE128 0 "register_operand" "=&d")
14668 (unspec:FMOVE128
14669 [(match_operand:<FP128_64> 1 "register_operand" "d")
14670 (match_operand:<FP128_64> 2 "register_operand" "d")]
14671 UNSPEC_PACK_128BIT))]
14672 "FLOAT128_2REG_P (<MODE>mode) && TARGET_HARD_FLOAT"
14673 "#"
14674 "&& reload_completed"
14675 [(set (match_dup 3) (match_dup 1))
14676 (set (match_dup 4) (match_dup 2))]
14677 {
14678 unsigned dest_hi = REGNO (operands[0]);
14679 unsigned dest_lo = dest_hi + 1;
14680
14681 gcc_assert (!IN_RANGE (REGNO (operands[1]), dest_hi, dest_lo));
14682 gcc_assert (!IN_RANGE (REGNO (operands[2]), dest_hi, dest_lo));
14683
14684 operands[3] = gen_rtx_REG (<FP128_64>mode, dest_hi);
14685 operands[4] = gen_rtx_REG (<FP128_64>mode, dest_lo);
14686 }
14687 [(set_attr "type" "fp")
14688 (set_attr "length" "8")])
14689
14690 (define_insn_and_split "pack<mode>_soft"
14691 [(set (match_operand:FMOVE128 0 "register_operand" "=&r")
14692 (unspec:FMOVE128
14693 [(match_operand:<FP128_64> 1 "register_operand" "r")
14694 (match_operand:<FP128_64> 2 "register_operand" "r")]
14695 UNSPEC_PACK_128BIT))]
14696 "FLOAT128_2REG_P (<MODE>mode) && TARGET_SOFT_FLOAT"
14697 "#"
14698 "&& reload_completed"
14699 [(set (match_dup 3) (match_dup 1))
14700 (set (match_dup 4) (match_dup 2))]
14701 {
14702 unsigned dest_hi = REGNO (operands[0]);
14703 unsigned dest_lo = dest_hi + (TARGET_POWERPC64 ? 1 : 2);
14704
14705 gcc_assert (!IN_RANGE (REGNO (operands[1]), dest_hi, dest_lo));
14706 gcc_assert (!IN_RANGE (REGNO (operands[2]), dest_hi, dest_lo));
14707
14708 operands[3] = gen_rtx_REG (<FP128_64>mode, dest_hi);
14709 operands[4] = gen_rtx_REG (<FP128_64>mode, dest_lo);
14710 }
14711 [(set_attr "type" "integer")
14712 (set (attr "length")
14713 (if_then_else
14714 (match_test "TARGET_POWERPC64")
14715 (const_string "8")
14716 (const_string "16")))])
14717
14718 (define_insn "unpack<mode>"
14719 [(set (match_operand:DI 0 "register_operand" "=wa,wa")
14720 (unspec:DI [(match_operand:FMOVE128_VSX 1 "register_operand" "0,wa")
14721 (match_operand:QI 2 "const_0_to_1_operand" "O,i")]
14722 UNSPEC_UNPACK_128BIT))]
14723 "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)"
14724 {
14725 if (REGNO (operands[0]) == REGNO (operands[1]) && INTVAL (operands[2]) == 0)
14726 return ASM_COMMENT_START " xxpermdi to same register";
14727
14728 operands[3] = GEN_INT (INTVAL (operands[2]) == 0 ? 0 : 3);
14729 return "xxpermdi %x0,%x1,%x1,%3";
14730 }
14731 [(set_attr "type" "vecperm")])
14732
14733 (define_insn "pack<mode>"
14734 [(set (match_operand:FMOVE128_VSX 0 "register_operand" "=wa")
14735 (unspec:FMOVE128_VSX
14736 [(match_operand:DI 1 "register_operand" "wa")
14737 (match_operand:DI 2 "register_operand" "wa")]
14738 UNSPEC_PACK_128BIT))]
14739 "TARGET_VSX"
14740 "xxpermdi %x0,%x1,%x2,0"
14741 [(set_attr "type" "vecperm")])
14742
14743
14744 \f
14745 ;; ISA 2.08 IEEE 128-bit floating point support.
14746
14747 (define_insn "add<mode>3"
14748 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14749 (plus:IEEE128
14750 (match_operand:IEEE128 1 "altivec_register_operand" "v")
14751 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14752 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14753 "xsaddqp %0,%1,%2"
14754 [(set_attr "type" "vecfloat")
14755 (set_attr "size" "128")])
14756
14757 (define_insn "sub<mode>3"
14758 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14759 (minus:IEEE128
14760 (match_operand:IEEE128 1 "altivec_register_operand" "v")
14761 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14762 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14763 "xssubqp %0,%1,%2"
14764 [(set_attr "type" "vecfloat")
14765 (set_attr "size" "128")])
14766
14767 (define_insn "mul<mode>3"
14768 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14769 (mult:IEEE128
14770 (match_operand:IEEE128 1 "altivec_register_operand" "v")
14771 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14772 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14773 "xsmulqp %0,%1,%2"
14774 [(set_attr "type" "qmul")
14775 (set_attr "size" "128")])
14776
14777 (define_insn "div<mode>3"
14778 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14779 (div:IEEE128
14780 (match_operand:IEEE128 1 "altivec_register_operand" "v")
14781 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14782 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14783 "xsdivqp %0,%1,%2"
14784 [(set_attr "type" "vecdiv")
14785 (set_attr "size" "128")])
14786
14787 (define_insn "sqrt<mode>2"
14788 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14789 (sqrt:IEEE128
14790 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14791 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14792 "xssqrtqp %0,%1"
14793 [(set_attr "type" "vecdiv")
14794 (set_attr "size" "128")])
14795
14796 (define_expand "copysign<mode>3"
14797 [(use (match_operand:IEEE128 0 "altivec_register_operand"))
14798 (use (match_operand:IEEE128 1 "altivec_register_operand"))
14799 (use (match_operand:IEEE128 2 "altivec_register_operand"))]
14800 "FLOAT128_IEEE_P (<MODE>mode)"
14801 {
14802 if (TARGET_FLOAT128_HW)
14803 emit_insn (gen_copysign<mode>3_hard (operands[0], operands[1],
14804 operands[2]));
14805 else
14806 emit_insn (gen_copysign<mode>3_soft (operands[0], operands[1],
14807 operands[2]));
14808 DONE;
14809 })
14810
14811 (define_insn "copysign<mode>3_hard"
14812 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14813 (unspec:IEEE128
14814 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14815 (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14816 UNSPEC_COPYSIGN))]
14817 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14818 "xscpsgnqp %0,%2,%1"
14819 [(set_attr "type" "vecmove")
14820 (set_attr "size" "128")])
14821
14822 (define_insn "copysign<mode>3_soft"
14823 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14824 (unspec:IEEE128
14825 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14826 (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14827 UNSPEC_COPYSIGN))
14828 (clobber (match_scratch:IEEE128 3 "=&v"))]
14829 "!TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14830 "xscpsgndp %x3,%x2,%x1\;xxpermdi %x0,%x3,%x1,1"
14831 [(set_attr "type" "veccomplex")
14832 (set_attr "length" "8")])
14833
14834 (define_insn "@neg<mode>2_hw"
14835 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14836 (neg:IEEE128
14837 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14838 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14839 "xsnegqp %0,%1"
14840 [(set_attr "type" "vecmove")
14841 (set_attr "size" "128")])
14842
14843
14844 (define_insn "@abs<mode>2_hw"
14845 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14846 (abs:IEEE128
14847 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14848 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14849 "xsabsqp %0,%1"
14850 [(set_attr "type" "vecmove")
14851 (set_attr "size" "128")])
14852
14853
14854 (define_insn "*nabs<mode>2_hw"
14855 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14856 (neg:IEEE128
14857 (abs:IEEE128
14858 (match_operand:IEEE128 1 "altivec_register_operand" "v"))))]
14859 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14860 "xsnabsqp %0,%1"
14861 [(set_attr "type" "vecmove")
14862 (set_attr "size" "128")])
14863
14864 ;; Initially don't worry about doing fusion
14865 (define_insn "fma<mode>4_hw"
14866 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14867 (fma:IEEE128
14868 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14869 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14870 (match_operand:IEEE128 3 "altivec_register_operand" "0")))]
14871 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14872 "xsmaddqp %0,%1,%2"
14873 [(set_attr "type" "qmul")
14874 (set_attr "size" "128")])
14875
14876 (define_insn "*fms<mode>4_hw"
14877 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14878 (fma:IEEE128
14879 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14880 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14881 (neg:IEEE128
14882 (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
14883 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14884 "xsmsubqp %0,%1,%2"
14885 [(set_attr "type" "qmul")
14886 (set_attr "size" "128")])
14887
14888 (define_insn "*nfma<mode>4_hw"
14889 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14890 (neg:IEEE128
14891 (fma:IEEE128
14892 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14893 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14894 (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
14895 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14896 "xsnmaddqp %0,%1,%2"
14897 [(set_attr "type" "qmul")
14898 (set_attr "size" "128")])
14899
14900 (define_insn "*nfms<mode>4_hw"
14901 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14902 (neg:IEEE128
14903 (fma:IEEE128
14904 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14905 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14906 (neg:IEEE128
14907 (match_operand:IEEE128 3 "altivec_register_operand" "0")))))]
14908 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14909 "xsnmsubqp %0,%1,%2"
14910 [(set_attr "type" "qmul")
14911 (set_attr "size" "128")])
14912
14913 (define_insn "extend<SFDF:mode><IEEE128:mode>2_hw"
14914 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14915 (float_extend:IEEE128
14916 (match_operand:SFDF 1 "altivec_register_operand" "v")))]
14917 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14918 "xscvdpqp %0,%1"
14919 [(set_attr "type" "vecfloat")
14920 (set_attr "size" "128")])
14921
14922 ;; Conversion between KFmode and TFmode if TFmode is ieee 128-bit floating
14923 ;; point is a simple copy.
14924 (define_insn_and_split "extendkftf2"
14925 [(set (match_operand:TF 0 "vsx_register_operand" "=wa,?wa")
14926 (float_extend:TF (match_operand:KF 1 "vsx_register_operand" "0,wa")))]
14927 "TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD"
14928 "@
14929 #
14930 xxlor %x0,%x1,%x1"
14931 "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
14932 [(const_int 0)]
14933 {
14934 emit_note (NOTE_INSN_DELETED);
14935 DONE;
14936 }
14937 [(set_attr "type" "*,veclogical")
14938 (set_attr "length" "0,4")])
14939
14940 (define_insn_and_split "trunctfkf2"
14941 [(set (match_operand:KF 0 "vsx_register_operand" "=wa,?wa")
14942 (float_extend:KF (match_operand:TF 1 "vsx_register_operand" "0,wa")))]
14943 "TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD"
14944 "@
14945 #
14946 xxlor %x0,%x1,%x1"
14947 "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
14948 [(const_int 0)]
14949 {
14950 emit_note (NOTE_INSN_DELETED);
14951 DONE;
14952 }
14953 [(set_attr "type" "*,veclogical")
14954 (set_attr "length" "0,4")])
14955
14956 (define_insn "trunc<mode>df2_hw"
14957 [(set (match_operand:DF 0 "altivec_register_operand" "=v")
14958 (float_truncate:DF
14959 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14960 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14961 "xscvqpdp %0,%1"
14962 [(set_attr "type" "vecfloat")
14963 (set_attr "size" "128")])
14964
14965 ;; There is no KFmode -> SFmode instruction. Preserve the accuracy by doing
14966 ;; the KFmode -> DFmode conversion using round to odd rather than the normal
14967 ;; conversion
14968 (define_insn_and_split "trunc<mode>sf2_hw"
14969 [(set (match_operand:SF 0 "vsx_register_operand" "=wa")
14970 (float_truncate:SF
14971 (match_operand:IEEE128 1 "altivec_register_operand" "v")))
14972 (clobber (match_scratch:DF 2 "=v"))]
14973 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14974 "#"
14975 "&& 1"
14976 [(set (match_dup 2)
14977 (unspec:DF [(match_dup 1)]
14978 UNSPEC_TRUNC_ROUND_TO_ODD))
14979 (set (match_dup 0)
14980 (float_truncate:SF (match_dup 2)))]
14981 {
14982 if (GET_CODE (operands[2]) == SCRATCH)
14983 operands[2] = gen_reg_rtx (DFmode);
14984 }
14985 [(set_attr "type" "vecfloat")
14986 (set_attr "length" "8")
14987 (set_attr "isa" "p8v")])
14988
14989 ;; Conversion between IEEE 128-bit and integer types
14990
14991 ;; The fix function for DImode and SImode was declared earlier as a
14992 ;; define_expand. It calls into rs6000_expand_float128_convert if we don't
14993 ;; have IEEE 128-bit hardware support. QImode and HImode are not provided
14994 ;; unless we have the IEEE 128-bit hardware.
14995 ;;
14996 ;; Unlike the code for converting SFmode/DFmode to QImode/HImode, we don't have
14997 ;; to provide a GPR target that used direct move and a conversion in the GPR
14998 ;; which works around QImode/HImode not being allowed in vector registers in
14999 ;; ISA 2.07 (power8).
15000 (define_insn "fix<uns>_<IEEE128:mode><SDI:mode>2_hw"
15001 [(set (match_operand:SDI 0 "altivec_register_operand" "=v")
15002 (any_fix:SDI (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
15003 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
15004 "xscvqp<su><wd>z %0,%1"
15005 [(set_attr "type" "vecfloat")
15006 (set_attr "size" "128")])
15007
15008 (define_insn "fix<uns>_trunc<IEEE128:mode><QHI:mode>2"
15009 [(set (match_operand:QHI 0 "altivec_register_operand" "=v")
15010 (any_fix:QHI
15011 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
15012 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
15013 "xscvqp<su>wz %0,%1"
15014 [(set_attr "type" "vecfloat")
15015 (set_attr "size" "128")])
15016
15017 ;; Combiner patterns to prevent moving the result of converting an IEEE 128-bit
15018 ;; floating point value to 8/16/32-bit integer to GPR in order to save it.
15019 (define_insn_and_split "*fix<uns>_trunc<IEEE128:mode><QHSI:mode>2_mem"
15020 [(set (match_operand:QHSI 0 "memory_operand" "=Z")
15021 (any_fix:QHSI
15022 (match_operand:IEEE128 1 "altivec_register_operand" "v")))
15023 (clobber (match_scratch:QHSI 2 "=v"))]
15024 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
15025 "#"
15026 "&& reload_completed"
15027 [(set (match_dup 2)
15028 (any_fix:QHSI (match_dup 1)))
15029 (set (match_dup 0)
15030 (match_dup 2))])
15031
15032 (define_insn "float_<mode>di2_hw"
15033 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
15034 (float:IEEE128 (match_operand:DI 1 "altivec_register_operand" "v")))]
15035 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
15036 "xscvsdqp %0,%1"
15037 [(set_attr "type" "vecfloat")
15038 (set_attr "size" "128")])
15039
15040 (define_insn_and_split "float_<mode>si2_hw"
15041 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
15042 (float:IEEE128 (match_operand:SI 1 "nonimmediate_operand" "vrZ")))
15043 (clobber (match_scratch:DI 2 "=v"))]
15044 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
15045 "#"
15046 "&& 1"
15047 [(set (match_dup 2)
15048 (sign_extend:DI (match_dup 1)))
15049 (set (match_dup 0)
15050 (float:IEEE128 (match_dup 2)))]
15051 {
15052 if (GET_CODE (operands[2]) == SCRATCH)
15053 operands[2] = gen_reg_rtx (DImode);
15054
15055 if (MEM_P (operands[1]))
15056 operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
15057 })
15058
15059 (define_insn_and_split "float<QHI:mode><IEEE128:mode>2"
15060 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v")
15061 (float:IEEE128 (match_operand:QHI 1 "nonimmediate_operand" "v,r,Z")))
15062 (clobber (match_scratch:DI 2 "=X,r,X"))]
15063 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
15064 "#"
15065 "&& reload_completed"
15066 [(const_int 0)]
15067 {
15068 rtx dest = operands[0];
15069 rtx src = operands[1];
15070 rtx dest_di = gen_rtx_REG (DImode, REGNO (dest));
15071
15072 if (altivec_register_operand (src, <QHI:MODE>mode))
15073 emit_insn (gen_extend<QHI:mode>di2 (dest_di, src));
15074 else if (int_reg_operand (src, <QHI:MODE>mode))
15075 {
15076 rtx ext_di = operands[2];
15077 emit_insn (gen_extend<QHI:mode>di2 (ext_di, src));
15078 emit_move_insn (dest_di, ext_di);
15079 }
15080 else if (MEM_P (src))
15081 {
15082 rtx dest_qhi = gen_rtx_REG (<QHI:MODE>mode, REGNO (dest));
15083 emit_move_insn (dest_qhi, src);
15084 emit_insn (gen_extend<QHI:mode>di2 (dest_di, dest_qhi));
15085 }
15086 else
15087 gcc_unreachable ();
15088
15089 emit_insn (gen_float_<IEEE128:mode>di2_hw (dest, dest_di));
15090 DONE;
15091 }
15092 [(set_attr "length" "8,12,12")
15093 (set_attr "type" "vecfloat")
15094 (set_attr "size" "128")])
15095
15096 (define_insn "floatuns_<mode>di2_hw"
15097 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
15098 (unsigned_float:IEEE128
15099 (match_operand:DI 1 "altivec_register_operand" "v")))]
15100 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
15101 "xscvudqp %0,%1"
15102 [(set_attr "type" "vecfloat")
15103 (set_attr "size" "128")])
15104
15105 (define_insn_and_split "floatuns_<mode>si2_hw"
15106 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
15107 (unsigned_float:IEEE128
15108 (match_operand:SI 1 "nonimmediate_operand" "vrZ")))
15109 (clobber (match_scratch:DI 2 "=v"))]
15110 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
15111 "#"
15112 "&& 1"
15113 [(set (match_dup 2)
15114 (zero_extend:DI (match_dup 1)))
15115 (set (match_dup 0)
15116 (float:IEEE128 (match_dup 2)))]
15117 {
15118 if (GET_CODE (operands[2]) == SCRATCH)
15119 operands[2] = gen_reg_rtx (DImode);
15120
15121 if (MEM_P (operands[1]))
15122 operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
15123 })
15124
15125 (define_insn_and_split "floatuns<QHI:mode><IEEE128:mode>2"
15126 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v")
15127 (unsigned_float:IEEE128
15128 (match_operand:QHI 1 "nonimmediate_operand" "v,r,Z")))
15129 (clobber (match_scratch:DI 2 "=X,r,X"))]
15130 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
15131 "#"
15132 "&& reload_completed"
15133 [(const_int 0)]
15134 {
15135 rtx dest = operands[0];
15136 rtx src = operands[1];
15137 rtx dest_di = gen_rtx_REG (DImode, REGNO (dest));
15138
15139 if (altivec_register_operand (src, <QHI:MODE>mode) || MEM_P (src))
15140 emit_insn (gen_zero_extend<QHI:mode>di2 (dest_di, src));
15141 else if (int_reg_operand (src, <QHI:MODE>mode))
15142 {
15143 rtx ext_di = operands[2];
15144 emit_insn (gen_zero_extend<QHI:mode>di2 (ext_di, src));
15145 emit_move_insn (dest_di, ext_di);
15146 }
15147 else
15148 gcc_unreachable ();
15149
15150 emit_insn (gen_floatuns_<IEEE128:mode>di2_hw (dest, dest_di));
15151 DONE;
15152 }
15153 [(set_attr "length" "8,12,8")
15154 (set_attr "type" "vecfloat")
15155 (set_attr "size" "128")])
15156
15157 ;; IEEE 128-bit round to integer built-in functions
15158 (define_insn "floor<mode>2"
15159 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
15160 (unspec:IEEE128
15161 [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
15162 UNSPEC_FRIM))]
15163 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
15164 "xsrqpi 1,%0,%1,3"
15165 [(set_attr "type" "vecfloat")
15166 (set_attr "size" "128")])
15167
15168 (define_insn "ceil<mode>2"
15169 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
15170 (unspec:IEEE128
15171 [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
15172 UNSPEC_FRIP))]
15173 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
15174 "xsrqpi 1,%0,%1,2"
15175 [(set_attr "type" "vecfloat")
15176 (set_attr "size" "128")])
15177
15178 (define_insn "btrunc<mode>2"
15179 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
15180 (unspec:IEEE128
15181 [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
15182 UNSPEC_FRIZ))]
15183 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
15184 "xsrqpi 1,%0,%1,1"
15185 [(set_attr "type" "vecfloat")
15186 (set_attr "size" "128")])
15187
15188 (define_insn "round<mode>2"
15189 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
15190 (unspec:IEEE128
15191 [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
15192 UNSPEC_FRIN))]
15193 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
15194 "xsrqpi 0,%0,%1,0"
15195 [(set_attr "type" "vecfloat")
15196 (set_attr "size" "128")])
15197
15198 ;; IEEE 128-bit instructions with round to odd semantics
15199 (define_insn "add<mode>3_odd"
15200 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
15201 (unspec:IEEE128
15202 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
15203 (match_operand:IEEE128 2 "altivec_register_operand" "v")]
15204 UNSPEC_ADD_ROUND_TO_ODD))]
15205 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
15206 "xsaddqpo %0,%1,%2"
15207 [(set_attr "type" "vecfloat")
15208 (set_attr "size" "128")])
15209
15210 (define_insn "sub<mode>3_odd"
15211 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
15212 (unspec:IEEE128
15213 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
15214 (match_operand:IEEE128 2 "altivec_register_operand" "v")]
15215 UNSPEC_SUB_ROUND_TO_ODD))]
15216 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
15217 "xssubqpo %0,%1,%2"
15218 [(set_attr "type" "vecfloat")
15219 (set_attr "size" "128")])
15220
15221 (define_insn "mul<mode>3_odd"
15222 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
15223 (unspec:IEEE128
15224 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
15225 (match_operand:IEEE128 2 "altivec_register_operand" "v")]
15226 UNSPEC_MUL_ROUND_TO_ODD))]
15227 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
15228 "xsmulqpo %0,%1,%2"
15229 [(set_attr "type" "qmul")
15230 (set_attr "size" "128")])
15231
15232 (define_insn "div<mode>3_odd"
15233 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
15234 (unspec:IEEE128
15235 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
15236 (match_operand:IEEE128 2 "altivec_register_operand" "v")]
15237 UNSPEC_DIV_ROUND_TO_ODD))]
15238 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
15239 "xsdivqpo %0,%1,%2"
15240 [(set_attr "type" "vecdiv")
15241 (set_attr "size" "128")])
15242
15243 (define_insn "sqrt<mode>2_odd"
15244 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
15245 (unspec:IEEE128
15246 [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
15247 UNSPEC_SQRT_ROUND_TO_ODD))]
15248 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
15249 "xssqrtqpo %0,%1"
15250 [(set_attr "type" "vecdiv")
15251 (set_attr "size" "128")])
15252
15253 (define_insn "fma<mode>4_odd"
15254 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
15255 (unspec:IEEE128
15256 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
15257 (match_operand:IEEE128 2 "altivec_register_operand" "v")
15258 (match_operand:IEEE128 3 "altivec_register_operand" "0")]
15259 UNSPEC_FMA_ROUND_TO_ODD))]
15260 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
15261 "xsmaddqpo %0,%1,%2"
15262 [(set_attr "type" "qmul")
15263 (set_attr "size" "128")])
15264
15265 (define_insn "*fms<mode>4_odd"
15266 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
15267 (unspec:IEEE128
15268 [(match_operand:IEEE128 1 "altivec_register_operand" "%v")
15269 (match_operand:IEEE128 2 "altivec_register_operand" "v")
15270 (neg:IEEE128
15271 (match_operand:IEEE128 3 "altivec_register_operand" "0"))]
15272 UNSPEC_FMA_ROUND_TO_ODD))]
15273 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
15274 "xsmsubqpo %0,%1,%2"
15275 [(set_attr "type" "qmul")
15276 (set_attr "size" "128")])
15277
15278 (define_insn "*nfma<mode>4_odd"
15279 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
15280 (neg:IEEE128
15281 (unspec:IEEE128
15282 [(match_operand:IEEE128 1 "altivec_register_operand" "%v")
15283 (match_operand:IEEE128 2 "altivec_register_operand" "v")
15284 (match_operand:IEEE128 3 "altivec_register_operand" "0")]
15285 UNSPEC_FMA_ROUND_TO_ODD)))]
15286 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
15287 "xsnmaddqpo %0,%1,%2"
15288 [(set_attr "type" "qmul")
15289 (set_attr "size" "128")])
15290
15291 (define_insn "*nfms<mode>4_odd"
15292 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
15293 (neg:IEEE128
15294 (unspec:IEEE128
15295 [(match_operand:IEEE128 1 "altivec_register_operand" "%v")
15296 (match_operand:IEEE128 2 "altivec_register_operand" "v")
15297 (neg:IEEE128
15298 (match_operand:IEEE128 3 "altivec_register_operand" "0"))]
15299 UNSPEC_FMA_ROUND_TO_ODD)))]
15300 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
15301 "xsnmsubqpo %0,%1,%2"
15302 [(set_attr "type" "qmul")
15303 (set_attr "size" "128")])
15304
15305 (define_insn "trunc<mode>df2_odd"
15306 [(set (match_operand:DF 0 "vsx_register_operand" "=v")
15307 (unspec:DF [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
15308 UNSPEC_TRUNC_ROUND_TO_ODD))]
15309 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
15310 "xscvqpdpo %0,%1"
15311 [(set_attr "type" "vecfloat")
15312 (set_attr "size" "128")])
15313
15314 ;; IEEE 128-bit comparisons
15315 (define_insn "*cmp<mode>_hw"
15316 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
15317 (compare:CCFP (match_operand:IEEE128 1 "altivec_register_operand" "v")
15318 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
15319 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
15320 "xscmpuqp %0,%1,%2"
15321 [(set_attr "type" "veccmp")
15322 (set_attr "size" "128")])
15323 \f
15324 ;; Miscellaneous ISA 3.0 (power9) instructions
15325
15326 (define_expand "darn_32_<mode>"
15327 [(use (match_operand:GPR 0 "register_operand"))]
15328 "TARGET_P9_MISC"
15329 {
15330 emit_insn (gen_darn (<MODE>mode, operands[0], const0_rtx));
15331 DONE;
15332 })
15333
15334 (define_expand "darn_64_<mode>"
15335 [(use (match_operand:GPR 0 "register_operand"))]
15336 "TARGET_P9_MISC"
15337 {
15338 emit_insn (gen_darn (<MODE>mode, operands[0], const1_rtx));
15339 DONE;
15340 })
15341
15342 (define_expand "darn_raw_<mode>"
15343 [(use (match_operand:GPR 0 "register_operand"))]
15344 "TARGET_P9_MISC"
15345 {
15346 emit_insn (gen_darn (<MODE>mode, operands[0], const2_rtx));
15347 DONE;
15348 })
15349
15350 (define_insn "@darn<mode>"
15351 [(set (match_operand:GPR 0 "register_operand" "=r")
15352 (unspec_volatile:GPR [(match_operand 1 "const_int_operand" "n")]
15353 UNSPECV_DARN))]
15354 "TARGET_P9_MISC"
15355 "darn %0,%1"
15356 [(set_attr "type" "integer")])
15357
15358 ;; Test byte within range.
15359 ;;
15360 ;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx
15361 ;; represents a byte whose value is ignored in this context and
15362 ;; vv, the least significant byte, holds the byte value that is to
15363 ;; be tested for membership within the range specified by operand 2.
15364 ;; The bytes of operand 2 are organized as xx:xx:hi:lo.
15365 ;;
15366 ;; Return in target register operand 0 a value of 1 if lo <= vv and
15367 ;; vv <= hi. Otherwise, set register operand 0 to 0.
15368 ;;
15369 ;; Though the instructions to which this expansion maps operate on
15370 ;; 64-bit registers, the current implementation only operates on
15371 ;; SI-mode operands as the high-order bits provide no information
15372 ;; that is not already available in the low-order bits. To avoid the
15373 ;; costs of data widening operations, future enhancements might allow
15374 ;; DI mode for operand 0 and/or might allow operand 1 to be QI mode.
15375 (define_expand "cmprb"
15376 [(set (match_dup 3)
15377 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
15378 (match_operand:SI 2 "gpc_reg_operand" "r")]
15379 UNSPEC_CMPRB))
15380 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
15381 (if_then_else:SI (lt (match_dup 3)
15382 (const_int 0))
15383 (const_int -1)
15384 (if_then_else (gt (match_dup 3)
15385 (const_int 0))
15386 (const_int 1)
15387 (const_int 0))))]
15388 "TARGET_P9_MISC"
15389 {
15390 operands[3] = gen_reg_rtx (CCmode);
15391 })
15392
15393 ;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx
15394 ;; represents a byte whose value is ignored in this context and
15395 ;; vv, the least significant byte, holds the byte value that is to
15396 ;; be tested for membership within the range specified by operand 2.
15397 ;; The bytes of operand 2 are organized as xx:xx:hi:lo.
15398 ;;
15399 ;; Set bit 1 (the GT bit, 0x4) of CR register operand 0 to 1 if
15400 ;; lo <= vv and vv <= hi. Otherwise, set the GT bit to 0. The other
15401 ;; 3 bits of the target CR register are all set to 0.
15402 (define_insn "*cmprb_internal"
15403 [(set (match_operand:CC 0 "cc_reg_operand" "=y")
15404 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
15405 (match_operand:SI 2 "gpc_reg_operand" "r")]
15406 UNSPEC_CMPRB))]
15407 "TARGET_P9_MISC"
15408 "cmprb %0,0,%1,%2"
15409 [(set_attr "type" "logical")])
15410
15411 ;; Set operand 0 register to -1 if the LT bit (0x8) of condition
15412 ;; register operand 1 is on. Otherwise, set operand 0 register to 1
15413 ;; if the GT bit (0x4) of condition register operand 1 is on.
15414 ;; Otherwise, set operand 0 to 0. Note that the result stored into
15415 ;; register operand 0 is non-zero iff either the LT or GT bits are on
15416 ;; within condition register operand 1.
15417 (define_insn "setb_signed"
15418 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
15419 (if_then_else:SI (lt (match_operand:CC 1 "cc_reg_operand" "y")
15420 (const_int 0))
15421 (const_int -1)
15422 (if_then_else (gt (match_dup 1)
15423 (const_int 0))
15424 (const_int 1)
15425 (const_int 0))))]
15426 "TARGET_P9_MISC"
15427 "setb %0,%1"
15428 [(set_attr "type" "logical")])
15429
15430 (define_insn "setb_unsigned"
15431 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
15432 (if_then_else:SI (ltu (match_operand:CCUNS 1 "cc_reg_operand" "y")
15433 (const_int 0))
15434 (const_int -1)
15435 (if_then_else (gtu (match_dup 1)
15436 (const_int 0))
15437 (const_int 1)
15438 (const_int 0))))]
15439 "TARGET_P9_MISC"
15440 "setb %0,%1"
15441 [(set_attr "type" "logical")])
15442
15443 ;; Test byte within two ranges.
15444 ;;
15445 ;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx
15446 ;; represents a byte whose value is ignored in this context and
15447 ;; vv, the least significant byte, holds the byte value that is to
15448 ;; be tested for membership within the range specified by operand 2.
15449 ;; The bytes of operand 2 are organized as hi_1:lo_1:hi_2:lo_2.
15450 ;;
15451 ;; Return in target register operand 0 a value of 1 if (lo_1 <= vv and
15452 ;; vv <= hi_1) or if (lo_2 <= vv and vv <= hi_2). Otherwise, set register
15453 ;; operand 0 to 0.
15454 ;;
15455 ;; Though the instructions to which this expansion maps operate on
15456 ;; 64-bit registers, the current implementation only operates on
15457 ;; SI-mode operands as the high-order bits provide no information
15458 ;; that is not already available in the low-order bits. To avoid the
15459 ;; costs of data widening operations, future enhancements might allow
15460 ;; DI mode for operand 0 and/or might allow operand 1 to be QI mode.
15461 (define_expand "cmprb2"
15462 [(set (match_dup 3)
15463 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
15464 (match_operand:SI 2 "gpc_reg_operand" "r")]
15465 UNSPEC_CMPRB2))
15466 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
15467 (if_then_else:SI (lt (match_dup 3)
15468 (const_int 0))
15469 (const_int -1)
15470 (if_then_else (gt (match_dup 3)
15471 (const_int 0))
15472 (const_int 1)
15473 (const_int 0))))]
15474 "TARGET_P9_MISC"
15475 {
15476 operands[3] = gen_reg_rtx (CCmode);
15477 })
15478
15479 ;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx
15480 ;; represents a byte whose value is ignored in this context and
15481 ;; vv, the least significant byte, holds the byte value that is to
15482 ;; be tested for membership within the ranges specified by operand 2.
15483 ;; The bytes of operand 2 are organized as hi_1:lo_1:hi_2:lo_2.
15484 ;;
15485 ;; Set bit 1 (the GT bit, 0x4) of CR register operand 0 to 1 if
15486 ;; (lo_1 <= vv and vv <= hi_1) or if (lo_2 <= vv and vv <= hi_2).
15487 ;; Otherwise, set the GT bit to 0. The other 3 bits of the target
15488 ;; CR register are all set to 0.
15489 (define_insn "*cmprb2_internal"
15490 [(set (match_operand:CC 0 "cc_reg_operand" "=y")
15491 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
15492 (match_operand:SI 2 "gpc_reg_operand" "r")]
15493 UNSPEC_CMPRB2))]
15494 "TARGET_P9_MISC"
15495 "cmprb %0,1,%1,%2"
15496 [(set_attr "type" "logical")])
15497
15498 ;; Test byte membership within set of 8 bytes.
15499 ;;
15500 ;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx
15501 ;; represents a byte whose value is ignored in this context and
15502 ;; vv, the least significant byte, holds the byte value that is to
15503 ;; be tested for membership within the set specified by operand 2.
15504 ;; The bytes of operand 2 are organized as e0:e1:e2:e3:e4:e5:e6:e7.
15505 ;;
15506 ;; Return in target register operand 0 a value of 1 if vv equals one
15507 ;; of the values e0, e1, e2, e3, e4, e5, e6, or e7. Otherwise, set
15508 ;; register operand 0 to 0. Note that the 8 byte values held within
15509 ;; operand 2 need not be unique.
15510 ;;
15511 ;; Though the instructions to which this expansion maps operate on
15512 ;; 64-bit registers, the current implementation requires that operands
15513 ;; 0 and 1 have mode SI as the high-order bits provide no information
15514 ;; that is not already available in the low-order bits. To avoid the
15515 ;; costs of data widening operations, future enhancements might allow
15516 ;; DI mode for operand 0 and/or might allow operand 1 to be QI mode.
15517 (define_expand "cmpeqb"
15518 [(set (match_dup 3)
15519 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
15520 (match_operand:DI 2 "gpc_reg_operand" "r")]
15521 UNSPEC_CMPEQB))
15522 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
15523 (if_then_else:SI (lt (match_dup 3)
15524 (const_int 0))
15525 (const_int -1)
15526 (if_then_else (gt (match_dup 3)
15527 (const_int 0))
15528 (const_int 1)
15529 (const_int 0))))]
15530 "TARGET_P9_MISC && TARGET_64BIT"
15531 {
15532 operands[3] = gen_reg_rtx (CCmode);
15533 })
15534
15535 ;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx
15536 ;; represents a byte whose value is ignored in this context and
15537 ;; vv, the least significant byte, holds the byte value that is to
15538 ;; be tested for membership within the set specified by operand 2.
15539 ;; The bytes of operand 2 are organized as e0:e1:e2:e3:e4:e5:e6:e7.
15540 ;;
15541 ;; Set bit 1 (the GT bit, 0x4) of CR register operand 0 to 1 if vv
15542 ;; equals one of the values e0, e1, e2, e3, e4, e5, e6, or e7. Otherwise,
15543 ;; set the GT bit to zero. The other 3 bits of the target CR register
15544 ;; are all set to 0.
15545 (define_insn "*cmpeqb_internal"
15546 [(set (match_operand:CC 0 "cc_reg_operand" "=y")
15547 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
15548 (match_operand:DI 2 "gpc_reg_operand" "r")]
15549 UNSPEC_CMPEQB))]
15550 "TARGET_P9_MISC && TARGET_64BIT"
15551 "cmpeqb %0,%1,%2"
15552 [(set_attr "type" "logical")])
15553
15554
15555 ;; ROP mitigation instructions.
15556
15557 (define_insn "hashst"
15558 [(set (match_operand:DI 0 "simple_offsettable_mem_operand" "=m")
15559 (unspec_volatile:DI [(match_operand:DI 1 "int_reg_operand" "r")]
15560 UNSPEC_HASHST))]
15561 "TARGET_POWER10 && rs6000_rop_protect"
15562 {
15563 static char templ[32];
15564 const char *p = rs6000_privileged ? "p" : "";
15565 sprintf (templ, "hashst%s %%1,%%0", p);
15566 return templ;
15567 }
15568 [(set_attr "type" "store")])
15569
15570 (define_insn "hashchk"
15571 [(unspec_volatile [(match_operand:DI 0 "int_reg_operand" "r")
15572 (match_operand:DI 1 "simple_offsettable_mem_operand" "m")]
15573 UNSPEC_HASHCHK)]
15574 "TARGET_POWER10 && rs6000_rop_protect"
15575 {
15576 static char templ[32];
15577 const char *p = rs6000_privileged ? "p" : "";
15578 sprintf (templ, "hashchk%s %%0,%%1", p);
15579 return templ;
15580 }
15581 [(set_attr "type" "load")])
15582 \f
15583
15584 (include "sync.md")
15585 (include "vector.md")
15586 (include "vsx.md")
15587 (include "altivec.md")
15588 (include "mma.md")
15589 (include "dfp.md")
15590 (include "crypto.md")
15591 (include "htm.md")
15592 (include "fusion.md")
15593 (include "pcrel-opt.md")