]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/config/rs6000/rs6000.md
Update copyright years.
[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-2024 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_PARITY
112 UNSPEC_CMPB
113 UNSPEC_FCTIW
114 UNSPEC_FCTID
115 UNSPEC_LFIWAX
116 UNSPEC_LFIWZX
117 UNSPEC_FCTIWUZ
118 UNSPEC_NOP
119 UNSPEC_GRP_END_NOP
120 UNSPEC_P8V_FMRGOW
121 UNSPEC_P8V_MTVSRWZ
122 UNSPEC_P8V_RELOAD_FROM_GPR
123 UNSPEC_P8V_MTVSRD
124 UNSPEC_P8V_XXPERMDI
125 UNSPEC_P8V_RELOAD_FROM_VSX
126 UNSPEC_ADDG6S
127 UNSPEC_CDTBCD
128 UNSPEC_CBCDTD
129 UNSPEC_DIVE
130 UNSPEC_DIVEU
131 UNSPEC_UNPACK_128BIT
132 UNSPEC_PACK_128BIT
133 UNSPEC_LSQ
134 UNSPEC_FUSION_GPR
135 UNSPEC_STACK_CHECK
136 UNSPEC_CMPRB
137 UNSPEC_CMPRB2
138 UNSPEC_CMPEQB
139 UNSPEC_ADD_ROUND_TO_ODD
140 UNSPEC_SUB_ROUND_TO_ODD
141 UNSPEC_MUL_ROUND_TO_ODD
142 UNSPEC_DIV_ROUND_TO_ODD
143 UNSPEC_FMA_ROUND_TO_ODD
144 UNSPEC_SQRT_ROUND_TO_ODD
145 UNSPEC_TRUNC_ROUND_TO_ODD
146 UNSPEC_SIGNBIT
147 UNSPEC_SF_FROM_SI
148 UNSPEC_SI_FROM_SF
149 UNSPEC_PLTSEQ
150 UNSPEC_PLT16_HA
151 UNSPEC_CFUGED
152 UNSPEC_CNTLZDM
153 UNSPEC_CNTTZDM
154 UNSPEC_PDEPD
155 UNSPEC_PEXTD
156 UNSPEC_HASHST
157 UNSPEC_HASHCHK
158 UNSPEC_XXSPLTIDP_CONST
159 UNSPEC_XXSPLTIW_CONST
160 UNSPEC_FMAX
161 UNSPEC_FMIN
162 ])
163
164 ;;
165 ;; UNSPEC_VOLATILE usage
166 ;;
167
168 (define_c_enum "unspecv"
169 [UNSPECV_BLOCK
170 UNSPECV_LL ; load-locked
171 UNSPECV_SC ; store-conditional
172 UNSPECV_PROBE_STACK_RANGE ; probe range of stack addresses
173 UNSPECV_EH_RR ; eh_reg_restore
174 UNSPECV_ISYNC ; isync instruction
175 UNSPECV_MFTB ; move from time base
176 UNSPECV_DARN ; darn (deliver a random number)
177 UNSPECV_NLGR ; non-local goto receiver
178 UNSPECV_MFFS ; Move from FPSCR
179 UNSPECV_MFFSL ; Move from FPSCR light instruction version
180 UNSPECV_MFFSCRN ; Move from FPSCR float rounding mode
181 UNSPECV_MFFSCDRN ; Move from FPSCR decimal float rounding mode
182 UNSPECV_MTFSF ; Move to FPSCR Fields 8 to 15
183 UNSPECV_MTFSF_HI ; Move to FPSCR Fields 0 to 7
184 UNSPECV_MTFSB0 ; Set FPSCR Field bit to 0
185 UNSPECV_MTFSB1 ; Set FPSCR Field bit to 1
186 UNSPECV_SPLIT_STACK_RETURN ; A camouflaged return
187 UNSPECV_SPEC_BARRIER ; Speculation barrier
188 UNSPECV_PLT16_LO
189 UNSPECV_PLT_PCREL
190 ])
191
192 ; The three different kinds of epilogue.
193 (define_enum "epilogue_type" [normal sibcall eh_return])
194 \f
195 ;; Define an insn type attribute. This is used in function unit delay
196 ;; computations.
197 (define_attr "type"
198 "integer,two,three,
199 add,logical,shift,insert,
200 mul,halfmul,div,
201 exts,cntlz,popcnt,isel,
202 load,store,fpload,fpstore,vecload,vecstore,
203 cmp,
204 branch,jmpreg,mfjmpr,mtjmpr,trap,isync,sync,load_l,store_c,
205 cr_logical,mfcr,mfcrf,mtcr,
206 fpcompare,fp,fpsimple,dmul,qmul,sdiv,ddiv,ssqrt,dsqrt,
207 vecsimple,veccomplex,vecdiv,veccmp,veccmpsimple,vecperm,
208 vecfloat,vecfdiv,vecdouble,mtvsr,mfvsr,crypto,
209 veclogical,veccmpfx,vecexts,vecmove,
210 htm,htmsimple,dfp,mma,
211 fused_arith_logical,
212 fused_cmp_isel,
213 fused_carry,
214 fused_load_cmpi,
215 fused_load_load,fused_store_store,
216 fused_addis_load,
217 fused_mtbc,
218 fused_vector"
219 (const_string "integer"))
220 ;; Attr type definitions for fused pairs:
221 ;; fused_arith_logical is used for scalar logical+add/subf and
222 ;; add/subf+logical pairs of instructions.
223 ;; fused_load_cmpi is used for a D-form load fused with
224 ;; a compare immediate.
225 ;; fused_load_load is for a fused pair of loads to adjacent addresses.
226 ;; fused_store_store is for a fused pair of stores to adjacent addresses.
227 ;; fused_addis_load is for addis fused to D-form load for a larger immediate.
228 ;; fused_mtbc is for fused mtlr and bclr[l] pairs.
229 ;; fused_vector is for a fused pair of vector logical instructions.
230
231 ;; What data size does this instruction work on?
232 ;; This is used for insert, mul and others as necessary.
233 (define_attr "size" "8,16,32,64,128,256" (const_string "32"))
234
235 ;; What is the insn_cost for this insn? The target hook can still override
236 ;; this. For optimizing for size the "length" attribute is used instead.
237 (define_attr "cost" "" (const_int 0))
238
239 ;; Is this instruction record form ("dot", signed compare to 0, writing CR0)?
240 ;; This is used for add, logical, shift, exts, mul.
241 (define_attr "dot" "no,yes" (const_string "no"))
242
243 ;; Does this instruction sign-extend its result?
244 ;; This is used for load insns.
245 (define_attr "sign_extend" "no,yes" (const_string "no"))
246
247 ;; Does this cr_logical instruction have three operands? That is, BT != BB.
248 (define_attr "cr_logical_3op" "no,yes" (const_string "no"))
249
250 ;; Does this instruction use indexed (that is, reg+reg) addressing?
251 ;; This is used for load and store insns. If operand 0 or 1 is a MEM
252 ;; it is automatically set based on that. If a load or store instruction
253 ;; has fewer than two operands it needs to set this attribute manually
254 ;; or the compiler will crash.
255 (define_attr "indexed" "no,yes"
256 (if_then_else (ior (match_operand 0 "indexed_address_mem")
257 (match_operand 1 "indexed_address_mem"))
258 (const_string "yes")
259 (const_string "no")))
260
261 ;; Does this instruction use update addressing?
262 ;; This is used for load and store insns. See the comments for "indexed".
263 (define_attr "update" "no,yes"
264 (if_then_else (ior (match_operand 0 "update_address_mem")
265 (match_operand 1 "update_address_mem"))
266 (const_string "yes")
267 (const_string "no")))
268
269 ;; Is this instruction using operands[2] as shift amount, and can that be a
270 ;; register?
271 ;; This is used for shift insns.
272 (define_attr "maybe_var_shift" "no,yes" (const_string "no"))
273
274 ;; Is this instruction using a shift amount from a register?
275 ;; This is used for shift insns.
276 (define_attr "var_shift" "no,yes"
277 (if_then_else (and (eq_attr "type" "shift")
278 (eq_attr "maybe_var_shift" "yes"))
279 (if_then_else (match_operand 2 "gpc_reg_operand")
280 (const_string "yes")
281 (const_string "no"))
282 (const_string "no")))
283
284 ;; Is copying of this instruction disallowed?
285 (define_attr "cannot_copy" "no,yes" (const_string "no"))
286
287
288 ;; Whether this insn has a prefixed form and a non-prefixed form.
289 (define_attr "maybe_prefixed" "no,yes"
290 (if_then_else (eq_attr "type" "load,fpload,vecload,store,fpstore,vecstore,
291 integer,add,fused_load_cmpi")
292 (const_string "yes")
293 (const_string "no")))
294
295 ;; Whether an insn is a prefixed insn. A prefixed instruction has a prefix
296 ;; instruction word that conveys additional information such as a larger
297 ;; immediate, additional operands, etc., in addition to the normal instruction
298 ;; word. The default "length" attribute will also be adjusted by default to
299 ;; be 12 bytes.
300 (define_attr "prefixed" "no,yes"
301 (cond [(ior (match_test "!TARGET_PREFIXED")
302 (match_test "!NONJUMP_INSN_P (insn)")
303 (eq_attr "maybe_prefixed" "no"))
304 (const_string "no")
305
306 (eq_attr "type" "load,fpload,vecload,fused_load_cmpi")
307 (if_then_else (match_test "prefixed_load_p (insn)")
308 (const_string "yes")
309 (const_string "no"))
310
311 (eq_attr "type" "store,fpstore,vecstore")
312 (if_then_else (match_test "prefixed_store_p (insn)")
313 (const_string "yes")
314 (const_string "no"))
315
316 (eq_attr "type" "integer,add")
317 (if_then_else (match_test "prefixed_paddi_p (insn)")
318 (const_string "yes")
319 (const_string "no"))]
320
321 (const_string "no")))
322
323 ;; Whether an insn loads an external address for the PCREL_OPT optimizaton.
324 (define_attr "loads_external_address" "no,yes"
325 (const_string "no"))
326
327 ;; Return the number of real hardware instructions in a combined insn. If it
328 ;; is 0, just use the length / 4.
329 (define_attr "num_insns" "" (const_int 0))
330
331 ;; If an insn is prefixed, return the maximum number of prefixed instructions
332 ;; in the insn. The macro ADJUST_INSN_LENGTH uses this number to adjust the
333 ;; insn length.
334 (define_attr "max_prefixed_insns" "" (const_int 1))
335
336 ;; Length of the instruction (in bytes). This length does not consider the
337 ;; length for prefixed instructions. The macro ADJUST_INSN_LENGTH will adjust
338 ;; the length if there are prefixed instructions.
339 ;;
340 ;; While it might be tempting to use num_insns to calculate the length, it can
341 ;; be problematical unless all insn lengths are adjusted to use num_insns
342 ;; (i.e. if num_insns is 0, it will get the length, which in turn will get
343 ;; num_insns and recurse).
344 (define_attr "length" "" (const_int 4))
345
346 ;; Processor type -- this attribute must exactly match the processor_type
347 ;; enumeration in rs6000-opts.h.
348 (define_attr "cpu"
349 "ppc601,ppc603,ppc604,ppc604e,ppc620,ppc630,
350 ppc750,ppc7400,ppc7450,
351 ppc403,ppc405,ppc440,ppc476,
352 ppc8540,ppc8548,ppce300c2,ppce300c3,ppce500mc,ppce500mc64,ppce5500,ppce6500,
353 power4,power5,power6,power7,power8,power9,power10,
354 rs64a,mpccore,cell,ppca2,titan"
355 (const (symbol_ref "(enum attr_cpu) rs6000_tune")))
356
357 ;; The ISA we implement.
358 (define_attr "isa" "any,p5,p6,p7,p7v,p8v,p9,p9v,p9kf,p9tf,p10"
359 (const_string "any"))
360
361 ;; Is this alternative enabled for the current CPU/ISA/etc.?
362 (define_attr "enabled" ""
363 (cond
364 [(eq_attr "isa" "any")
365 (const_int 1)
366
367 (and (eq_attr "isa" "p5")
368 (match_test "TARGET_POPCNTB"))
369 (const_int 1)
370
371 (and (eq_attr "isa" "p6")
372 (match_test "TARGET_CMPB"))
373 (const_int 1)
374
375 (and (eq_attr "isa" "p7")
376 (match_test "TARGET_POPCNTD"))
377 (const_int 1)
378
379 (and (eq_attr "isa" "p7v")
380 (match_test "TARGET_VSX"))
381 (const_int 1)
382
383 (and (eq_attr "isa" "p8v")
384 (match_test "TARGET_P8_VECTOR"))
385 (const_int 1)
386
387 (and (eq_attr "isa" "p9")
388 (match_test "TARGET_MODULO"))
389 (const_int 1)
390
391 (and (eq_attr "isa" "p9v")
392 (match_test "TARGET_P9_VECTOR"))
393 (const_int 1)
394
395 (and (eq_attr "isa" "p9kf")
396 (match_test "TARGET_FLOAT128_TYPE"))
397 (const_int 1)
398
399 (and (eq_attr "isa" "p9tf")
400 (match_test "FLOAT128_VECTOR_P (TFmode)"))
401 (const_int 1)
402
403 (and (eq_attr "isa" "p10")
404 (match_test "TARGET_POWER10"))
405 (const_int 1)
406 ] (const_int 0)))
407
408 ;; If this instruction is microcoded on the CELL processor
409 ; The default for load extended, the recorded instructions and rotate/shifts by a variable is always microcoded
410 (define_attr "cell_micro" "not,conditional,always"
411 (if_then_else (ior (and (eq_attr "type" "shift,exts,mul")
412 (eq_attr "dot" "yes"))
413 (and (eq_attr "type" "load")
414 (eq_attr "sign_extend" "yes"))
415 (and (eq_attr "type" "shift")
416 (eq_attr "var_shift" "yes")))
417 (const_string "always")
418 (const_string "not")))
419
420 (automata_option "ndfa")
421
422 (include "rs64.md")
423 (include "mpc.md")
424 (include "40x.md")
425 (include "440.md")
426 (include "476.md")
427 (include "601.md")
428 (include "603.md")
429 (include "6xx.md")
430 (include "7xx.md")
431 (include "7450.md")
432 (include "8540.md")
433 (include "e300c2c3.md")
434 (include "e500mc.md")
435 (include "e500mc64.md")
436 (include "e5500.md")
437 (include "e6500.md")
438 (include "power4.md")
439 (include "power5.md")
440 (include "power6.md")
441 (include "power7.md")
442 (include "power8.md")
443 (include "power9.md")
444 (include "power10.md")
445 (include "cell.md")
446 (include "a2.md")
447 (include "titan.md")
448
449 (include "predicates.md")
450 (include "constraints.md")
451
452 \f
453 ;; Mode iterators
454
455 ; This mode iterator allows :GPR to be used to indicate the allowable size
456 ; of whole values in GPRs.
457 (define_mode_iterator GPR [SI (DI "TARGET_POWERPC64")])
458
459 ; And again, for patterns that need two (potentially) different integer modes.
460 (define_mode_iterator GPR2 [SI (DI "TARGET_POWERPC64")])
461
462 ; Any supported integer mode.
463 (define_mode_iterator INT [QI HI SI DI TI PTI])
464
465 ; Any supported integer mode that fits in one register.
466 (define_mode_iterator INT1 [QI HI SI (DI "TARGET_POWERPC64")])
467
468 ; Integer modes supported in VSX registers with ISA 3.0 instructions
469 (define_mode_iterator INT_ISA3 [QI HI SI DI])
470
471 ; Everything we can extend QImode to.
472 (define_mode_iterator EXTQI [SI (DI "TARGET_POWERPC64")])
473
474 ; Everything we can extend HImode to.
475 (define_mode_iterator EXTHI [SI (DI "TARGET_POWERPC64")])
476
477 ; Everything we can extend SImode to.
478 (define_mode_iterator EXTSI [(DI "TARGET_POWERPC64")])
479
480 ; QImode or HImode for small integer moves and small atomic ops
481 (define_mode_iterator QHI [QI HI])
482
483 ; QImode, HImode, SImode for fused ops only for GPR loads
484 (define_mode_iterator QHSI [QI HI SI])
485
486 ; HImode or SImode for sign extended fusion ops
487 (define_mode_iterator HSI [HI SI])
488
489 ; SImode or DImode, even if DImode doesn't fit in GPRs.
490 (define_mode_iterator SDI [SI DI])
491
492 ; The size of a pointer. Also, the size of the value that a record-condition
493 ; (one with a '.') will compare; and the size used for arithmetic carries.
494 (define_mode_iterator P [(SI "TARGET_32BIT") (DI "TARGET_64BIT")])
495 (define_mode_iterator WORD [(SI "!TARGET_POWERPC64") (DI "TARGET_POWERPC64")])
496
497 ; Iterator to add PTImode along with TImode (TImode can go in VSX registers,
498 ; PTImode is GPR only)
499 (define_mode_iterator TI2 [TI PTI])
500
501 ; Any hardware-supported floating-point mode
502 (define_mode_iterator FP [
503 (SF "TARGET_HARD_FLOAT")
504 (DF "TARGET_HARD_FLOAT")
505 (TF "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128")
506 (IF "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128")
507 (KF "TARGET_FLOAT128_TYPE")
508 (DD "TARGET_DFP")
509 (TD "TARGET_DFP")])
510
511 ; Any fma capable floating-point mode.
512 (define_mode_iterator FMA_F [
513 (SF "TARGET_HARD_FLOAT")
514 (DF "TARGET_HARD_FLOAT || VECTOR_UNIT_VSX_P (DFmode)")
515 (V4SF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)")
516 (V2DF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V2DFmode)")
517 (KF "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (KFmode)")
518 (TF "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (TFmode)")
519 ])
520
521 ; Floating point move iterators to combine binary and decimal moves
522 (define_mode_iterator FMOVE32 [SF SD])
523 (define_mode_iterator FMOVE64 [DF DD])
524 (define_mode_iterator FMOVE64X [DI DF DD])
525 (define_mode_iterator FMOVE128 [(TF "TARGET_LONG_DOUBLE_128")
526 (IF "FLOAT128_IBM_P (IFmode)")
527 (TD "TARGET_HARD_FLOAT")])
528
529 (define_mode_iterator FMOVE128_FPR [(TF "FLOAT128_2REG_P (TFmode)")
530 (IF "FLOAT128_2REG_P (IFmode)")
531 (TD "TARGET_HARD_FLOAT")])
532
533 ; Iterators for 128 bit types for direct move
534 (define_mode_iterator FMOVE128_GPR [TI
535 V16QI
536 V8HI
537 V4SI
538 V4SF
539 V2DI
540 V2DF
541 V1TI
542 (KF "FLOAT128_VECTOR_P (KFmode)")
543 (TF "FLOAT128_VECTOR_P (TFmode)")])
544
545 ; Iterator for 128-bit VSX types for pack/unpack
546 (define_mode_iterator FMOVE128_VSX [V1TI KF])
547
548 ; Iterators for converting to/from TFmode
549 (define_mode_iterator IFKF [IF KF])
550
551 ; Constraints for moving IF/KFmode.
552 (define_mode_attr IFKF_reg [(IF "d") (KF "wa")])
553
554 ; Whether a floating point move is ok, don't allow SD without hardware FP
555 (define_mode_attr fmove_ok [(SF "")
556 (DF "")
557 (SD "TARGET_HARD_FLOAT")
558 (DD "")])
559
560 ; Convert REAL_VALUE to the appropriate bits
561 (define_mode_attr real_value_to_target [(SF "REAL_VALUE_TO_TARGET_SINGLE")
562 (DF "REAL_VALUE_TO_TARGET_DOUBLE")
563 (SD "REAL_VALUE_TO_TARGET_DECIMAL32")
564 (DD "REAL_VALUE_TO_TARGET_DECIMAL64")])
565
566 ; Whether 0.0 has an all-zero bit pattern
567 (define_mode_attr zero_fp [(SF "j")
568 (DF "j")
569 (TF "j")
570 (IF "j")
571 (KF "j")
572 (SD "wn")
573 (DD "wn")
574 (TD "wn")])
575
576 ; Definitions for 64-bit VSX
577 (define_mode_attr f64_vsx [(DF "wa") (DD "wn")])
578
579 ; Definitions for 64-bit direct move
580 (define_mode_attr f64_dm [(DF "wa") (DD "d")])
581
582 ; Definitions for 64-bit use of altivec registers
583 (define_mode_attr f64_av [(DF "v") (DD "wn")])
584
585 ; Definitions for 64-bit access to ISA 3.0 (power9) vector
586 (define_mode_attr f64_p9 [(DF "v") (DD "wn")])
587
588 ; These modes do not fit in integer registers in 32-bit mode.
589 (define_mode_iterator DIFD [DI DF DD])
590
591 ; Iterator for reciprocal estimate instructions
592 (define_mode_iterator RECIPF [SF DF V4SF V2DF])
593
594 ; SFmode or DFmode.
595 (define_mode_iterator SFDF [SF DF])
596
597 ; And again, for when we need two FP modes in a pattern.
598 (define_mode_iterator SFDF2 [SF DF])
599
600 ; A generic s/d attribute, for sp/dp for example.
601 (define_mode_attr sd [(SF "s") (DF "d")
602 (V4SF "s") (V2DF "d")])
603
604 ; "s" or nothing, for fmuls/fmul for example.
605 (define_mode_attr s [(SF "s") (DF "")])
606
607 ; Iterator for 128-bit floating point that uses the IBM double-double format
608 (define_mode_iterator IBM128 [(IF "FLOAT128_IBM_P (IFmode)")
609 (TF "FLOAT128_IBM_P (TFmode)")])
610
611 ; Iterator for 128-bit floating point that uses IEEE 128-bit float
612 (define_mode_iterator IEEE128 [(KF "FLOAT128_IEEE_P (KFmode)")
613 (TF "FLOAT128_IEEE_P (TFmode)")])
614
615 ; Iterator for 128-bit floating point
616 (define_mode_iterator FLOAT128 [(KF "TARGET_FLOAT128_TYPE")
617 (IF "TARGET_FLOAT128_TYPE")
618 (TF "TARGET_LONG_DOUBLE_128")])
619
620 ; Iterator for signbit on 64-bit machines with direct move
621 (define_mode_iterator SIGNBIT [(KF "FLOAT128_VECTOR_P (KFmode)")
622 (TF "FLOAT128_VECTOR_P (TFmode)")])
623
624 ; Which isa is needed for those float instructions?
625 (define_mode_attr Fisa [(SF "p8v") (DF "*") (DI "*")])
626
627 ; FRE/FRES support
628 (define_mode_attr FFRE [(SF "FRES") (DF "FRE")])
629
630 ; Conditional returns.
631 (define_code_iterator any_return [return simple_return])
632 (define_code_attr return_pred [(return "direct_return ()")
633 (simple_return "1")])
634 (define_code_attr return_str [(return "") (simple_return "simple_")])
635
636 ; Logical operators.
637 (define_code_iterator iorxor [ior xor])
638 (define_code_iterator and_ior_xor [and ior xor])
639
640 ; Signed/unsigned variants of ops.
641 (define_code_iterator any_extend [sign_extend zero_extend])
642 (define_code_iterator any_fix [fix unsigned_fix])
643 (define_code_iterator any_float [float unsigned_float])
644
645 ; Shift right.
646 (define_code_iterator any_shiftrt [ashiftrt lshiftrt])
647
648 (define_code_attr u [(sign_extend "")
649 (zero_extend "u")
650 (fix "")
651 (unsigned_fix "u")])
652
653 (define_code_attr su [(sign_extend "s")
654 (zero_extend "u")
655 (fix "s")
656 (unsigned_fix "u")
657 (float "s")
658 (unsigned_float "u")])
659
660 (define_code_attr az [(sign_extend "a")
661 (zero_extend "z")
662 (fix "a")
663 (unsigned_fix "z")
664 (float "a")
665 (unsigned_float "z")])
666
667 (define_code_attr uns [(fix "")
668 (unsigned_fix "uns")
669 (float "")
670 (unsigned_float "uns")])
671
672 ; Various instructions that come in SI and DI forms.
673 ; A generic w/d attribute, for things like cmpw/cmpd.
674 (define_mode_attr wd [(QI "b")
675 (HI "h")
676 (SI "w")
677 (DI "d")
678 (V16QI "b")
679 (V8HI "h")
680 (V4SI "w")
681 (V2DI "d")
682 (V1TI "q")
683 (TI "q")])
684
685 ; For double extract from different origin types
686 (define_mode_attr du_or_d [(QI "du")
687 (HI "du")
688 (SI "du")
689 (DI "d")
690 (V16QI "du")
691 (V8HI "du")
692 (V4SI "du")
693 (V2DI "d")])
694
695 ;; How many bits (per element) in this mode?
696 (define_mode_attr bits [(QI "8") (HI "16") (SI "32") (DI "64")
697 (SF "32") (DF "64")
698 (DD "64") (TD "128")
699 (V4SI "32") (V2DI "64")])
700
701 ; DImode bits
702 (define_mode_attr dbits [(QI "56") (HI "48") (SI "32")])
703
704 ;; Bitmask for shift instructions
705 (define_mode_attr hH [(SI "h") (DI "H")])
706
707 ;; A mode twice the size of the given mode
708 (define_mode_attr dmode [(SI "di") (DI "ti")])
709 (define_mode_attr DMODE [(SI "DI") (DI "TI")])
710
711 ;; Suffix for reload patterns
712 (define_mode_attr ptrsize [(SI "32bit")
713 (DI "64bit")])
714
715 (define_mode_attr tptrsize [(SI "TARGET_32BIT")
716 (DI "TARGET_64BIT")])
717
718 (define_mode_attr mptrsize [(SI "si")
719 (DI "di")])
720
721 (define_mode_attr ptrload [(SI "lwz")
722 (DI "ld")])
723
724 (define_mode_attr ptrm [(SI "m")
725 (DI "Y")])
726
727 (define_mode_attr rreg [(SF "f")
728 (DF "wa")
729 (TF "f")
730 (TD "f")
731 (V4SF "wa")
732 (V2DF "wa")])
733
734 (define_mode_attr rreg2 [(SF "f")
735 (DF "d")])
736
737 (define_mode_attr SI_CONVERT_FP [(SF "TARGET_FCFIDS")
738 (DF "TARGET_FCFID")])
739
740 ;; Mode iterator for logical operations on 128-bit types
741 (define_mode_iterator BOOL_128 [TI
742 PTI
743 (V16QI "TARGET_ALTIVEC")
744 (V8HI "TARGET_ALTIVEC")
745 (V4SI "TARGET_ALTIVEC")
746 (V4SF "TARGET_ALTIVEC")
747 (V2DI "TARGET_ALTIVEC")
748 (V2DF "TARGET_ALTIVEC")
749 (V1TI "TARGET_ALTIVEC")])
750
751 ;; For the GPRs we use 3 constraints for register outputs, two that are the
752 ;; same as the output register, and a third where the output register is an
753 ;; early clobber, so we don't have to deal with register overlaps. For the
754 ;; vector types, we prefer to use the vector registers. For TI mode, allow
755 ;; either.
756
757 ;; Mode attribute for boolean operation register constraints for output
758 (define_mode_attr BOOL_REGS_OUTPUT [(TI "&r,r,r,wa,v")
759 (PTI "&r,r,r")
760 (V16QI "wa,v,&?r,?r,?r")
761 (V8HI "wa,v,&?r,?r,?r")
762 (V4SI "wa,v,&?r,?r,?r")
763 (V4SF "wa,v,&?r,?r,?r")
764 (V2DI "wa,v,&?r,?r,?r")
765 (V2DF "wa,v,&?r,?r,?r")
766 (V1TI "wa,v,&?r,?r,?r")])
767
768 ;; Mode attribute for boolean operation register constraints for operand1
769 (define_mode_attr BOOL_REGS_OP1 [(TI "r,0,r,wa,v")
770 (PTI "r,0,r")
771 (V16QI "wa,v,r,0,r")
772 (V8HI "wa,v,r,0,r")
773 (V4SI "wa,v,r,0,r")
774 (V4SF "wa,v,r,0,r")
775 (V2DI "wa,v,r,0,r")
776 (V2DF "wa,v,r,0,r")
777 (V1TI "wa,v,r,0,r")])
778
779 ;; Mode attribute for boolean operation register constraints for operand2
780 (define_mode_attr BOOL_REGS_OP2 [(TI "r,r,0,wa,v")
781 (PTI "r,r,0")
782 (V16QI "wa,v,r,r,0")
783 (V8HI "wa,v,r,r,0")
784 (V4SI "wa,v,r,r,0")
785 (V4SF "wa,v,r,r,0")
786 (V2DI "wa,v,r,r,0")
787 (V2DF "wa,v,r,r,0")
788 (V1TI "wa,v,r,r,0")])
789
790 ;; Mode attribute for boolean operation register constraints for operand1
791 ;; for one_cmpl. To simplify things, we repeat the constraint where 0
792 ;; is used for operand1 or operand2
793 (define_mode_attr BOOL_REGS_UNARY [(TI "r,0,0,wa,v")
794 (PTI "r,0,0")
795 (V16QI "wa,v,r,0,0")
796 (V8HI "wa,v,r,0,0")
797 (V4SI "wa,v,r,0,0")
798 (V4SF "wa,v,r,0,0")
799 (V2DI "wa,v,r,0,0")
800 (V2DF "wa,v,r,0,0")
801 (V1TI "wa,v,r,0,0")])
802
803 ;; Reload iterator for creating the function to allocate a base register to
804 ;; supplement addressing modes.
805 (define_mode_iterator RELOAD [V16QI V8HI V4SI V2DI V4SF V2DF V1TI
806 SF SD SI DF DD DI TI PTI KF IF TF
807 OO XO])
808
809 ;; Iterate over smin, smax
810 (define_code_iterator fp_minmax [smin smax])
811
812 (define_code_attr minmax [(smin "min")
813 (smax "max")])
814
815 (define_code_attr SMINMAX [(smin "SMIN")
816 (smax "SMAX")])
817
818 ;; Iterator to optimize the following cases:
819 ;; D-form load to FPR register & move to Altivec register
820 ;; Move Altivec register to FPR register and store
821 (define_mode_iterator ALTIVEC_DFORM [DF
822 (SF "TARGET_P8_VECTOR")
823 (DI "TARGET_POWERPC64")])
824
825 (include "darwin.md")
826 \f
827 ;; Start with fixed-point load and store insns. Here we put only the more
828 ;; complex forms. Basic data transfer is done later.
829
830 (define_insn "zero_extendqi<mode>2"
831 [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r,wa,^v")
832 (zero_extend:EXTQI (match_operand:QI 1 "reg_or_mem_operand" "m,r,?Z,v")))]
833 ""
834 "@
835 lbz%U1%X1 %0,%1
836 rlwinm %0,%1,0,0xff
837 lxsibzx %x0,%y1
838 vextractub %0,%1,7"
839 [(set_attr "type" "load,shift,fpload,vecperm")
840 (set_attr "isa" "*,*,p9v,p9v")])
841
842 (define_insn_and_split "*zero_extendqi<mode>2_dot"
843 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
844 (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
845 (const_int 0)))
846 (clobber (match_scratch:EXTQI 0 "=r,r"))]
847 ""
848 "@
849 andi. %0,%1,0xff
850 #"
851 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
852 [(set (match_dup 0)
853 (zero_extend:EXTQI (match_dup 1)))
854 (set (match_dup 2)
855 (compare:CC (match_dup 0)
856 (const_int 0)))]
857 ""
858 [(set_attr "type" "logical")
859 (set_attr "dot" "yes")
860 (set_attr "length" "4,8")])
861
862 (define_insn_and_split "*zero_extendqi<mode>2_dot2"
863 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
864 (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
865 (const_int 0)))
866 (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
867 (zero_extend:EXTQI (match_dup 1)))]
868 ""
869 "@
870 andi. %0,%1,0xff
871 #"
872 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
873 [(set (match_dup 0)
874 (zero_extend:EXTQI (match_dup 1)))
875 (set (match_dup 2)
876 (compare:CC (match_dup 0)
877 (const_int 0)))]
878 ""
879 [(set_attr "type" "logical")
880 (set_attr "dot" "yes")
881 (set_attr "length" "4,8")])
882
883
884 (define_insn "zero_extendhi<mode>2"
885 [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r,wa,^v")
886 (zero_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r,?Z,v")))]
887 ""
888 "@
889 lhz%U1%X1 %0,%1
890 rlwinm %0,%1,0,0xffff
891 lxsihzx %x0,%y1
892 vextractuh %0,%1,6"
893 [(set_attr "type" "load,shift,fpload,vecperm")
894 (set_attr "isa" "*,*,p9v,p9v")])
895
896 (define_insn_and_split "*zero_extendhi<mode>2_dot"
897 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
898 (compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
899 (const_int 0)))
900 (clobber (match_scratch:EXTHI 0 "=r,r"))]
901 ""
902 "@
903 andi. %0,%1,0xffff
904 #"
905 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
906 [(set (match_dup 0)
907 (zero_extend:EXTHI (match_dup 1)))
908 (set (match_dup 2)
909 (compare:CC (match_dup 0)
910 (const_int 0)))]
911 ""
912 [(set_attr "type" "logical")
913 (set_attr "dot" "yes")
914 (set_attr "length" "4,8")])
915
916 (define_insn_and_split "*zero_extendhi<mode>2_dot2"
917 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
918 (compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
919 (const_int 0)))
920 (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
921 (zero_extend:EXTHI (match_dup 1)))]
922 ""
923 "@
924 andi. %0,%1,0xffff
925 #"
926 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
927 [(set (match_dup 0)
928 (zero_extend:EXTHI (match_dup 1)))
929 (set (match_dup 2)
930 (compare:CC (match_dup 0)
931 (const_int 0)))]
932 ""
933 [(set_attr "type" "logical")
934 (set_attr "dot" "yes")
935 (set_attr "length" "4,8")])
936
937
938 (define_insn "zero_extendsi<mode>2"
939 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r,d,wa,wa,r,wa")
940 (zero_extend:EXTSI (match_operand:SI 1 "reg_or_mem_operand" "m,r,?Z,?Z,r,wa,wa")))]
941 ""
942 "@
943 lwz%U1%X1 %0,%1
944 rldicl %0,%1,0,32
945 lfiwzx %0,%y1
946 lxsiwzx %x0,%y1
947 mtvsrwz %x0,%1
948 mfvsrwz %0,%x1
949 xxextractuw %x0,%x1,4"
950 [(set_attr "type" "load,shift,fpload,fpload,mtvsr,mfvsr,vecexts")
951 (set_attr "isa" "*,*,p7,p8v,p8v,p8v,p9v")])
952
953 (define_insn_and_split "*zero_extendsi<mode>2_dot"
954 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
955 (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
956 (const_int 0)))
957 (clobber (match_scratch:EXTSI 0 "=r,r"))]
958 ""
959 "@
960 rldicl. %0,%1,0,32
961 #"
962 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
963 [(set (match_dup 0)
964 (zero_extend:DI (match_dup 1)))
965 (set (match_dup 2)
966 (compare:CC (match_dup 0)
967 (const_int 0)))]
968 ""
969 [(set_attr "type" "shift")
970 (set_attr "dot" "yes")
971 (set_attr "length" "4,8")])
972
973 (define_insn_and_split "*zero_extendsi<mode>2_dot2"
974 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
975 (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
976 (const_int 0)))
977 (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
978 (zero_extend:EXTSI (match_dup 1)))]
979 ""
980 "@
981 rldicl. %0,%1,0,32
982 #"
983 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
984 [(set (match_dup 0)
985 (zero_extend:EXTSI (match_dup 1)))
986 (set (match_dup 2)
987 (compare:CC (match_dup 0)
988 (const_int 0)))]
989 ""
990 [(set_attr "type" "shift")
991 (set_attr "dot" "yes")
992 (set_attr "length" "4,8")])
993
994
995 (define_insn "extendqi<mode>2"
996 [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,?*v")
997 (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,?*v")))]
998 ""
999 "@
1000 extsb %0,%1
1001 vextsb2d %0,%1"
1002 [(set_attr "type" "exts,vecperm")
1003 (set_attr "isa" "*,p9v")])
1004
1005 (define_insn_and_split "*extendqi<mode>2_dot"
1006 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1007 (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
1008 (const_int 0)))
1009 (clobber (match_scratch:EXTQI 0 "=r,r"))]
1010 ""
1011 "@
1012 extsb. %0,%1
1013 #"
1014 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1015 [(set (match_dup 0)
1016 (sign_extend:EXTQI (match_dup 1)))
1017 (set (match_dup 2)
1018 (compare:CC (match_dup 0)
1019 (const_int 0)))]
1020 ""
1021 [(set_attr "type" "exts")
1022 (set_attr "dot" "yes")
1023 (set_attr "length" "4,8")])
1024
1025 (define_insn_and_split "*extendqi<mode>2_dot2"
1026 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1027 (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
1028 (const_int 0)))
1029 (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
1030 (sign_extend:EXTQI (match_dup 1)))]
1031 ""
1032 "@
1033 extsb. %0,%1
1034 #"
1035 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1036 [(set (match_dup 0)
1037 (sign_extend:EXTQI (match_dup 1)))
1038 (set (match_dup 2)
1039 (compare:CC (match_dup 0)
1040 (const_int 0)))]
1041 ""
1042 [(set_attr "type" "exts")
1043 (set_attr "dot" "yes")
1044 (set_attr "length" "4,8")])
1045
1046
1047 (define_expand "extendhi<mode>2"
1048 [(set (match_operand:EXTHI 0 "gpc_reg_operand")
1049 (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand")))]
1050 ""
1051 "")
1052
1053 (define_insn "*extendhi<mode>2"
1054 [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r,?*v,?*v")
1055 (sign_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r,Z,v")))]
1056 ""
1057 "@
1058 lha%U1%X1 %0,%1
1059 extsh %0,%1
1060 #
1061 vextsh2d %0,%1"
1062 [(set_attr "type" "load,exts,fpload,vecperm")
1063 (set_attr "sign_extend" "yes")
1064 (set_attr "length" "*,*,8,*")
1065 (set_attr "isa" "*,*,p9v,p9v")])
1066
1067 (define_split
1068 [(set (match_operand:EXTHI 0 "altivec_register_operand")
1069 (sign_extend:EXTHI
1070 (match_operand:HI 1 "indexed_or_indirect_operand")))]
1071 "TARGET_P9_VECTOR && reload_completed"
1072 [(set (match_dup 2)
1073 (match_dup 1))
1074 (set (match_dup 0)
1075 (sign_extend:EXTHI (match_dup 2)))]
1076 {
1077 operands[2] = gen_rtx_REG (HImode, REGNO (operands[0]));
1078 })
1079
1080 (define_insn_and_split "*extendhi<mode>2_dot"
1081 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1082 (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
1083 (const_int 0)))
1084 (clobber (match_scratch:EXTHI 0 "=r,r"))]
1085 ""
1086 "@
1087 extsh. %0,%1
1088 #"
1089 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1090 [(set (match_dup 0)
1091 (sign_extend:EXTHI (match_dup 1)))
1092 (set (match_dup 2)
1093 (compare:CC (match_dup 0)
1094 (const_int 0)))]
1095 ""
1096 [(set_attr "type" "exts")
1097 (set_attr "dot" "yes")
1098 (set_attr "length" "4,8")])
1099
1100 (define_insn_and_split "*extendhi<mode>2_dot2"
1101 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1102 (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
1103 (const_int 0)))
1104 (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
1105 (sign_extend:EXTHI (match_dup 1)))]
1106 ""
1107 "@
1108 extsh. %0,%1
1109 #"
1110 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1111 [(set (match_dup 0)
1112 (sign_extend:EXTHI (match_dup 1)))
1113 (set (match_dup 2)
1114 (compare:CC (match_dup 0)
1115 (const_int 0)))]
1116 ""
1117 [(set_attr "type" "exts")
1118 (set_attr "dot" "yes")
1119 (set_attr "length" "4,8")])
1120
1121
1122 (define_insn "extendsi<mode>2"
1123 [(set (match_operand:EXTSI 0 "gpc_reg_operand"
1124 "=r, r, d, wa, wa, v, v, wr")
1125 (sign_extend:EXTSI (match_operand:SI 1 "lwa_operand"
1126 "YZ, r, Z, Z, r, v, v, ?wa")))]
1127 ""
1128 "@
1129 lwa%U1%X1 %0,%1
1130 extsw %0,%1
1131 lfiwax %0,%y1
1132 lxsiwax %x0,%y1
1133 mtvsrwa %x0,%1
1134 vextsw2d %0,%1
1135 #
1136 #"
1137 [(set_attr "type" "load,exts,fpload,fpload,mtvsr,vecexts,vecperm,mfvsr")
1138 (set_attr "sign_extend" "yes")
1139 (set_attr "length" "*,*,*,*,*,*,8,8")
1140 (set_attr "isa" "*,*,p6,p8v,p8v,p9v,p8v,p8v")])
1141
1142 (define_split
1143 [(set (match_operand:EXTSI 0 "int_reg_operand")
1144 (sign_extend:EXTSI (match_operand:SI 1 "vsx_register_operand")))]
1145 "TARGET_DIRECT_MOVE_64BIT && reload_completed"
1146 [(set (match_dup 2)
1147 (match_dup 1))
1148 (set (match_dup 0)
1149 (sign_extend:DI (match_dup 2)))]
1150 {
1151 operands[2] = gen_rtx_REG (SImode, reg_or_subregno (operands[0]));
1152 })
1153
1154 (define_split
1155 [(set (match_operand:DI 0 "altivec_register_operand")
1156 (sign_extend:DI (match_operand:SI 1 "altivec_register_operand")))]
1157 "TARGET_P8_VECTOR && !TARGET_P9_VECTOR && reload_completed"
1158 [(const_int 0)]
1159 {
1160 rtx dest = operands[0];
1161 rtx src = operands[1];
1162 int dest_regno = REGNO (dest);
1163 int src_regno = REGNO (src);
1164 rtx dest_v2di = gen_rtx_REG (V2DImode, dest_regno);
1165 rtx src_v4si = gen_rtx_REG (V4SImode, src_regno);
1166
1167 if (BYTES_BIG_ENDIAN)
1168 {
1169 emit_insn (gen_altivec_vupkhsw (dest_v2di, src_v4si));
1170 emit_insn (gen_vsx_xxspltd_v2di (dest_v2di, dest_v2di, const1_rtx));
1171 }
1172 else
1173 {
1174 emit_insn (gen_altivec_vupklsw (dest_v2di, src_v4si));
1175 emit_insn (gen_vsx_xxspltd_v2di (dest_v2di, dest_v2di, const0_rtx));
1176 }
1177 DONE;
1178 })
1179
1180 (define_insn_and_split "*extendsi<mode>2_dot"
1181 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1182 (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
1183 (const_int 0)))
1184 (clobber (match_scratch:EXTSI 0 "=r,r"))]
1185 ""
1186 "@
1187 extsw. %0,%1
1188 #"
1189 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1190 [(set (match_dup 0)
1191 (sign_extend:EXTSI (match_dup 1)))
1192 (set (match_dup 2)
1193 (compare:CC (match_dup 0)
1194 (const_int 0)))]
1195 ""
1196 [(set_attr "type" "exts")
1197 (set_attr "dot" "yes")
1198 (set_attr "length" "4,8")])
1199
1200 (define_insn_and_split "*extendsi<mode>2_dot2"
1201 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1202 (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
1203 (const_int 0)))
1204 (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
1205 (sign_extend:EXTSI (match_dup 1)))]
1206 ""
1207 "@
1208 extsw. %0,%1
1209 #"
1210 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1211 [(set (match_dup 0)
1212 (sign_extend:EXTSI (match_dup 1)))
1213 (set (match_dup 2)
1214 (compare:CC (match_dup 0)
1215 (const_int 0)))]
1216 ""
1217 [(set_attr "type" "exts")
1218 (set_attr "dot" "yes")
1219 (set_attr "length" "4,8")])
1220 \f
1221 ;; IBM 405, 440, 464 and 476 half-word multiplication operations.
1222
1223 (define_insn "*macchwc"
1224 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1225 (compare:CC (plus:SI (mult:SI (ashiftrt:SI
1226 (match_operand:SI 2 "gpc_reg_operand" "r")
1227 (const_int 16))
1228 (sign_extend:SI
1229 (match_operand:HI 1 "gpc_reg_operand" "r")))
1230 (match_operand:SI 4 "gpc_reg_operand" "0"))
1231 (const_int 0)))
1232 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1233 (plus:SI (mult:SI (ashiftrt:SI
1234 (match_dup 2)
1235 (const_int 16))
1236 (sign_extend:SI
1237 (match_dup 1)))
1238 (match_dup 4)))]
1239 "TARGET_MULHW"
1240 "macchw. %0,%1,%2"
1241 [(set_attr "type" "halfmul")])
1242
1243 (define_insn "*macchw"
1244 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1245 (plus:SI (mult:SI (ashiftrt:SI
1246 (match_operand:SI 2 "gpc_reg_operand" "r")
1247 (const_int 16))
1248 (sign_extend:SI
1249 (match_operand:HI 1 "gpc_reg_operand" "r")))
1250 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1251 "TARGET_MULHW"
1252 "macchw %0,%1,%2"
1253 [(set_attr "type" "halfmul")])
1254
1255 (define_insn "*macchwuc"
1256 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1257 (compare:CC (plus:SI (mult:SI (lshiftrt:SI
1258 (match_operand:SI 2 "gpc_reg_operand" "r")
1259 (const_int 16))
1260 (zero_extend:SI
1261 (match_operand:HI 1 "gpc_reg_operand" "r")))
1262 (match_operand:SI 4 "gpc_reg_operand" "0"))
1263 (const_int 0)))
1264 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1265 (plus:SI (mult:SI (lshiftrt:SI
1266 (match_dup 2)
1267 (const_int 16))
1268 (zero_extend:SI
1269 (match_dup 1)))
1270 (match_dup 4)))]
1271 "TARGET_MULHW"
1272 "macchwu. %0,%1,%2"
1273 [(set_attr "type" "halfmul")])
1274
1275 (define_insn "*macchwu"
1276 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1277 (plus:SI (mult:SI (lshiftrt:SI
1278 (match_operand:SI 2 "gpc_reg_operand" "r")
1279 (const_int 16))
1280 (zero_extend:SI
1281 (match_operand:HI 1 "gpc_reg_operand" "r")))
1282 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1283 "TARGET_MULHW"
1284 "macchwu %0,%1,%2"
1285 [(set_attr "type" "halfmul")])
1286
1287 (define_insn "*machhwc"
1288 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1289 (compare:CC (plus:SI (mult:SI (ashiftrt:SI
1290 (match_operand:SI 1 "gpc_reg_operand" "%r")
1291 (const_int 16))
1292 (ashiftrt:SI
1293 (match_operand:SI 2 "gpc_reg_operand" "r")
1294 (const_int 16)))
1295 (match_operand:SI 4 "gpc_reg_operand" "0"))
1296 (const_int 0)))
1297 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1298 (plus:SI (mult:SI (ashiftrt:SI
1299 (match_dup 1)
1300 (const_int 16))
1301 (ashiftrt:SI
1302 (match_dup 2)
1303 (const_int 16)))
1304 (match_dup 4)))]
1305 "TARGET_MULHW"
1306 "machhw. %0,%1,%2"
1307 [(set_attr "type" "halfmul")])
1308
1309 (define_insn "*machhw"
1310 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1311 (plus:SI (mult:SI (ashiftrt:SI
1312 (match_operand:SI 1 "gpc_reg_operand" "%r")
1313 (const_int 16))
1314 (ashiftrt:SI
1315 (match_operand:SI 2 "gpc_reg_operand" "r")
1316 (const_int 16)))
1317 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1318 "TARGET_MULHW"
1319 "machhw %0,%1,%2"
1320 [(set_attr "type" "halfmul")])
1321
1322 (define_insn "*machhwuc"
1323 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1324 (compare:CC (plus:SI (mult:SI (lshiftrt:SI
1325 (match_operand:SI 1 "gpc_reg_operand" "%r")
1326 (const_int 16))
1327 (lshiftrt:SI
1328 (match_operand:SI 2 "gpc_reg_operand" "r")
1329 (const_int 16)))
1330 (match_operand:SI 4 "gpc_reg_operand" "0"))
1331 (const_int 0)))
1332 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1333 (plus:SI (mult:SI (lshiftrt:SI
1334 (match_dup 1)
1335 (const_int 16))
1336 (lshiftrt:SI
1337 (match_dup 2)
1338 (const_int 16)))
1339 (match_dup 4)))]
1340 "TARGET_MULHW"
1341 "machhwu. %0,%1,%2"
1342 [(set_attr "type" "halfmul")])
1343
1344 (define_insn "*machhwu"
1345 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1346 (plus:SI (mult:SI (lshiftrt:SI
1347 (match_operand:SI 1 "gpc_reg_operand" "%r")
1348 (const_int 16))
1349 (lshiftrt:SI
1350 (match_operand:SI 2 "gpc_reg_operand" "r")
1351 (const_int 16)))
1352 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1353 "TARGET_MULHW"
1354 "machhwu %0,%1,%2"
1355 [(set_attr "type" "halfmul")])
1356
1357 (define_insn "*maclhwc"
1358 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1359 (compare:CC (plus:SI (mult:SI (sign_extend:SI
1360 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1361 (sign_extend:SI
1362 (match_operand:HI 2 "gpc_reg_operand" "r")))
1363 (match_operand:SI 4 "gpc_reg_operand" "0"))
1364 (const_int 0)))
1365 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1366 (plus:SI (mult:SI (sign_extend:SI
1367 (match_dup 1))
1368 (sign_extend:SI
1369 (match_dup 2)))
1370 (match_dup 4)))]
1371 "TARGET_MULHW"
1372 "maclhw. %0,%1,%2"
1373 [(set_attr "type" "halfmul")])
1374
1375 (define_insn "*maclhw"
1376 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1377 (plus:SI (mult:SI (sign_extend:SI
1378 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1379 (sign_extend:SI
1380 (match_operand:HI 2 "gpc_reg_operand" "r")))
1381 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1382 "TARGET_MULHW"
1383 "maclhw %0,%1,%2"
1384 [(set_attr "type" "halfmul")])
1385
1386 (define_insn "*maclhwuc"
1387 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1388 (compare:CC (plus:SI (mult:SI (zero_extend:SI
1389 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1390 (zero_extend:SI
1391 (match_operand:HI 2 "gpc_reg_operand" "r")))
1392 (match_operand:SI 4 "gpc_reg_operand" "0"))
1393 (const_int 0)))
1394 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1395 (plus:SI (mult:SI (zero_extend:SI
1396 (match_dup 1))
1397 (zero_extend:SI
1398 (match_dup 2)))
1399 (match_dup 4)))]
1400 "TARGET_MULHW"
1401 "maclhwu. %0,%1,%2"
1402 [(set_attr "type" "halfmul")])
1403
1404 (define_insn "*maclhwu"
1405 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1406 (plus:SI (mult:SI (zero_extend:SI
1407 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1408 (zero_extend:SI
1409 (match_operand:HI 2 "gpc_reg_operand" "r")))
1410 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1411 "TARGET_MULHW"
1412 "maclhwu %0,%1,%2"
1413 [(set_attr "type" "halfmul")])
1414
1415 (define_insn "*nmacchwc"
1416 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1417 (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1418 (mult:SI (ashiftrt:SI
1419 (match_operand:SI 2 "gpc_reg_operand" "r")
1420 (const_int 16))
1421 (sign_extend:SI
1422 (match_operand:HI 1 "gpc_reg_operand" "r"))))
1423 (const_int 0)))
1424 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1425 (minus:SI (match_dup 4)
1426 (mult:SI (ashiftrt:SI
1427 (match_dup 2)
1428 (const_int 16))
1429 (sign_extend:SI
1430 (match_dup 1)))))]
1431 "TARGET_MULHW"
1432 "nmacchw. %0,%1,%2"
1433 [(set_attr "type" "halfmul")])
1434
1435 (define_insn "*nmacchw"
1436 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1437 (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1438 (mult:SI (ashiftrt:SI
1439 (match_operand:SI 2 "gpc_reg_operand" "r")
1440 (const_int 16))
1441 (sign_extend:SI
1442 (match_operand:HI 1 "gpc_reg_operand" "r")))))]
1443 "TARGET_MULHW"
1444 "nmacchw %0,%1,%2"
1445 [(set_attr "type" "halfmul")])
1446
1447 (define_insn "*nmachhwc"
1448 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1449 (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1450 (mult:SI (ashiftrt:SI
1451 (match_operand:SI 1 "gpc_reg_operand" "%r")
1452 (const_int 16))
1453 (ashiftrt:SI
1454 (match_operand:SI 2 "gpc_reg_operand" "r")
1455 (const_int 16))))
1456 (const_int 0)))
1457 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1458 (minus:SI (match_dup 4)
1459 (mult:SI (ashiftrt:SI
1460 (match_dup 1)
1461 (const_int 16))
1462 (ashiftrt:SI
1463 (match_dup 2)
1464 (const_int 16)))))]
1465 "TARGET_MULHW"
1466 "nmachhw. %0,%1,%2"
1467 [(set_attr "type" "halfmul")])
1468
1469 (define_insn "*nmachhw"
1470 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1471 (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1472 (mult:SI (ashiftrt:SI
1473 (match_operand:SI 1 "gpc_reg_operand" "%r")
1474 (const_int 16))
1475 (ashiftrt:SI
1476 (match_operand:SI 2 "gpc_reg_operand" "r")
1477 (const_int 16)))))]
1478 "TARGET_MULHW"
1479 "nmachhw %0,%1,%2"
1480 [(set_attr "type" "halfmul")])
1481
1482 (define_insn "*nmaclhwc"
1483 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1484 (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1485 (mult:SI (sign_extend:SI
1486 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1487 (sign_extend:SI
1488 (match_operand:HI 2 "gpc_reg_operand" "r"))))
1489 (const_int 0)))
1490 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1491 (minus:SI (match_dup 4)
1492 (mult:SI (sign_extend:SI
1493 (match_dup 1))
1494 (sign_extend:SI
1495 (match_dup 2)))))]
1496 "TARGET_MULHW"
1497 "nmaclhw. %0,%1,%2"
1498 [(set_attr "type" "halfmul")])
1499
1500 (define_insn "*nmaclhw"
1501 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1502 (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1503 (mult:SI (sign_extend:SI
1504 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1505 (sign_extend:SI
1506 (match_operand:HI 2 "gpc_reg_operand" "r")))))]
1507 "TARGET_MULHW"
1508 "nmaclhw %0,%1,%2"
1509 [(set_attr "type" "halfmul")])
1510
1511 (define_insn "*mulchwc"
1512 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1513 (compare:CC (mult:SI (ashiftrt:SI
1514 (match_operand:SI 2 "gpc_reg_operand" "r")
1515 (const_int 16))
1516 (sign_extend:SI
1517 (match_operand:HI 1 "gpc_reg_operand" "r")))
1518 (const_int 0)))
1519 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1520 (mult:SI (ashiftrt:SI
1521 (match_dup 2)
1522 (const_int 16))
1523 (sign_extend:SI
1524 (match_dup 1))))]
1525 "TARGET_MULHW"
1526 "mulchw. %0,%1,%2"
1527 [(set_attr "type" "halfmul")])
1528
1529 (define_insn "*mulchw"
1530 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1531 (mult:SI (ashiftrt:SI
1532 (match_operand:SI 2 "gpc_reg_operand" "r")
1533 (const_int 16))
1534 (sign_extend:SI
1535 (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1536 "TARGET_MULHW"
1537 "mulchw %0,%1,%2"
1538 [(set_attr "type" "halfmul")])
1539
1540 (define_insn "*mulchwuc"
1541 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1542 (compare:CC (mult:SI (lshiftrt:SI
1543 (match_operand:SI 2 "gpc_reg_operand" "r")
1544 (const_int 16))
1545 (zero_extend:SI
1546 (match_operand:HI 1 "gpc_reg_operand" "r")))
1547 (const_int 0)))
1548 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1549 (mult:SI (lshiftrt:SI
1550 (match_dup 2)
1551 (const_int 16))
1552 (zero_extend:SI
1553 (match_dup 1))))]
1554 "TARGET_MULHW"
1555 "mulchwu. %0,%1,%2"
1556 [(set_attr "type" "halfmul")])
1557
1558 (define_insn "*mulchwu"
1559 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1560 (mult:SI (lshiftrt:SI
1561 (match_operand:SI 2 "gpc_reg_operand" "r")
1562 (const_int 16))
1563 (zero_extend:SI
1564 (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1565 "TARGET_MULHW"
1566 "mulchwu %0,%1,%2"
1567 [(set_attr "type" "halfmul")])
1568
1569 (define_insn "*mulhhwc"
1570 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1571 (compare:CC (mult:SI (ashiftrt:SI
1572 (match_operand:SI 1 "gpc_reg_operand" "%r")
1573 (const_int 16))
1574 (ashiftrt:SI
1575 (match_operand:SI 2 "gpc_reg_operand" "r")
1576 (const_int 16)))
1577 (const_int 0)))
1578 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1579 (mult:SI (ashiftrt:SI
1580 (match_dup 1)
1581 (const_int 16))
1582 (ashiftrt:SI
1583 (match_dup 2)
1584 (const_int 16))))]
1585 "TARGET_MULHW"
1586 "mulhhw. %0,%1,%2"
1587 [(set_attr "type" "halfmul")])
1588
1589 (define_insn "*mulhhw"
1590 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1591 (mult:SI (ashiftrt:SI
1592 (match_operand:SI 1 "gpc_reg_operand" "%r")
1593 (const_int 16))
1594 (ashiftrt:SI
1595 (match_operand:SI 2 "gpc_reg_operand" "r")
1596 (const_int 16))))]
1597 "TARGET_MULHW"
1598 "mulhhw %0,%1,%2"
1599 [(set_attr "type" "halfmul")])
1600
1601 (define_insn "*mulhhwuc"
1602 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1603 (compare:CC (mult:SI (lshiftrt:SI
1604 (match_operand:SI 1 "gpc_reg_operand" "%r")
1605 (const_int 16))
1606 (lshiftrt:SI
1607 (match_operand:SI 2 "gpc_reg_operand" "r")
1608 (const_int 16)))
1609 (const_int 0)))
1610 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1611 (mult:SI (lshiftrt:SI
1612 (match_dup 1)
1613 (const_int 16))
1614 (lshiftrt:SI
1615 (match_dup 2)
1616 (const_int 16))))]
1617 "TARGET_MULHW"
1618 "mulhhwu. %0,%1,%2"
1619 [(set_attr "type" "halfmul")])
1620
1621 (define_insn "*mulhhwu"
1622 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1623 (mult:SI (lshiftrt:SI
1624 (match_operand:SI 1 "gpc_reg_operand" "%r")
1625 (const_int 16))
1626 (lshiftrt:SI
1627 (match_operand:SI 2 "gpc_reg_operand" "r")
1628 (const_int 16))))]
1629 "TARGET_MULHW"
1630 "mulhhwu %0,%1,%2"
1631 [(set_attr "type" "halfmul")])
1632
1633 (define_insn "*mullhwc"
1634 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1635 (compare:CC (mult:SI (sign_extend:SI
1636 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1637 (sign_extend:SI
1638 (match_operand:HI 2 "gpc_reg_operand" "r")))
1639 (const_int 0)))
1640 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1641 (mult:SI (sign_extend:SI
1642 (match_dup 1))
1643 (sign_extend:SI
1644 (match_dup 2))))]
1645 "TARGET_MULHW"
1646 "mullhw. %0,%1,%2"
1647 [(set_attr "type" "halfmul")])
1648
1649 (define_insn "*mullhw"
1650 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1651 (mult:SI (sign_extend:SI
1652 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1653 (sign_extend:SI
1654 (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1655 "TARGET_MULHW"
1656 "mullhw %0,%1,%2"
1657 [(set_attr "type" "halfmul")])
1658
1659 (define_insn "*mullhwuc"
1660 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1661 (compare:CC (mult:SI (zero_extend:SI
1662 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1663 (zero_extend:SI
1664 (match_operand:HI 2 "gpc_reg_operand" "r")))
1665 (const_int 0)))
1666 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1667 (mult:SI (zero_extend:SI
1668 (match_dup 1))
1669 (zero_extend:SI
1670 (match_dup 2))))]
1671 "TARGET_MULHW"
1672 "mullhwu. %0,%1,%2"
1673 [(set_attr "type" "halfmul")])
1674
1675 (define_insn "*mullhwu"
1676 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1677 (mult:SI (zero_extend:SI
1678 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1679 (zero_extend:SI
1680 (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1681 "TARGET_MULHW"
1682 "mullhwu %0,%1,%2"
1683 [(set_attr "type" "halfmul")])
1684 \f
1685 ;; IBM 405, 440, 464 and 476 string-search dlmzb instruction support.
1686 (define_insn "dlmzb"
1687 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1688 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
1689 (match_operand:SI 2 "gpc_reg_operand" "r")]
1690 UNSPEC_DLMZB_CR))
1691 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1692 (unspec:SI [(match_dup 1)
1693 (match_dup 2)]
1694 UNSPEC_DLMZB))]
1695 "TARGET_DLMZB"
1696 "dlmzb. %0,%1,%2")
1697
1698 (define_expand "strlensi"
1699 [(set (match_operand:SI 0 "gpc_reg_operand")
1700 (unspec:SI [(match_operand:BLK 1 "general_operand")
1701 (match_operand:QI 2 "const_int_operand")
1702 (match_operand 3 "const_int_operand")]
1703 UNSPEC_DLMZB_STRLEN))
1704 (clobber (match_scratch:CC 4))]
1705 "TARGET_DLMZB && WORDS_BIG_ENDIAN && !optimize_size"
1706 {
1707 rtx result = operands[0];
1708 rtx src = operands[1];
1709 rtx search_char = operands[2];
1710 rtx align = operands[3];
1711 rtx addr, scratch_string, word1, word2, scratch_dlmzb;
1712 rtx loop_label, end_label, mem, cr0, cond;
1713 if (search_char != const0_rtx
1714 || !CONST_INT_P (align)
1715 || INTVAL (align) < 8)
1716 FAIL;
1717 word1 = gen_reg_rtx (SImode);
1718 word2 = gen_reg_rtx (SImode);
1719 scratch_dlmzb = gen_reg_rtx (SImode);
1720 scratch_string = gen_reg_rtx (Pmode);
1721 loop_label = gen_label_rtx ();
1722 end_label = gen_label_rtx ();
1723 addr = force_reg (Pmode, XEXP (src, 0));
1724 emit_move_insn (scratch_string, addr);
1725 emit_label (loop_label);
1726 mem = change_address (src, SImode, scratch_string);
1727 emit_move_insn (word1, mem);
1728 emit_move_insn (word2, adjust_address (mem, SImode, 4));
1729 cr0 = gen_rtx_REG (CCmode, CR0_REGNO);
1730 emit_insn (gen_dlmzb (scratch_dlmzb, word1, word2, cr0));
1731 cond = gen_rtx_NE (VOIDmode, cr0, const0_rtx);
1732 emit_jump_insn (gen_rtx_SET (pc_rtx,
1733 gen_rtx_IF_THEN_ELSE (VOIDmode,
1734 cond,
1735 gen_rtx_LABEL_REF
1736 (VOIDmode,
1737 end_label),
1738 pc_rtx)));
1739 emit_insn (gen_addsi3 (scratch_string, scratch_string, GEN_INT (8)));
1740 emit_jump_insn (gen_rtx_SET (pc_rtx,
1741 gen_rtx_LABEL_REF (VOIDmode, loop_label)));
1742 emit_barrier ();
1743 emit_label (end_label);
1744 emit_insn (gen_addsi3 (scratch_string, scratch_string, scratch_dlmzb));
1745 emit_insn (gen_subsi3 (result, scratch_string, addr));
1746 emit_insn (gen_addsi3 (result, result, constm1_rtx));
1747 DONE;
1748 })
1749 \f
1750 ;; Fixed-point arithmetic insns.
1751
1752 (define_expand "add<mode>3"
1753 [(set (match_operand:SDI 0 "gpc_reg_operand")
1754 (plus:SDI (match_operand:SDI 1 "gpc_reg_operand")
1755 (match_operand:SDI 2 "reg_or_add_cint_operand")))]
1756 ""
1757 {
1758 if (<MODE>mode == DImode && !TARGET_POWERPC64)
1759 {
1760 rtx lo0 = gen_lowpart (SImode, operands[0]);
1761 rtx lo1 = gen_lowpart (SImode, operands[1]);
1762 rtx lo2 = gen_lowpart (SImode, operands[2]);
1763 rtx hi0 = gen_highpart (SImode, operands[0]);
1764 rtx hi1 = gen_highpart (SImode, operands[1]);
1765 rtx hi2 = gen_highpart_mode (SImode, DImode, operands[2]);
1766
1767 if (!reg_or_short_operand (lo2, SImode))
1768 lo2 = force_reg (SImode, lo2);
1769 if (!adde_operand (hi2, SImode))
1770 hi2 = force_reg (SImode, hi2);
1771
1772 emit_insn (gen_addsi3_carry (lo0, lo1, lo2));
1773 emit_insn (gen_addsi3_carry_in (hi0, hi1, hi2));
1774 DONE;
1775 }
1776
1777 if (CONST_INT_P (operands[2]) && !add_operand (operands[2], <MODE>mode))
1778 {
1779 rtx tmp = ((!can_create_pseudo_p ()
1780 || rtx_equal_p (operands[0], operands[1]))
1781 ? operands[0] : gen_reg_rtx (<MODE>mode));
1782
1783 /* Adding a constant to r0 is not a valid insn, so use a different
1784 strategy in that case. */
1785 if (reg_or_subregno (operands[1]) == 0 || reg_or_subregno (tmp) == 0)
1786 {
1787 if (operands[0] == operands[1])
1788 FAIL;
1789 rs6000_emit_move (operands[0], operands[2], <MODE>mode);
1790 emit_insn (gen_add<mode>3 (operands[0], operands[1], operands[0]));
1791 DONE;
1792 }
1793
1794 HOST_WIDE_INT val = INTVAL (operands[2]);
1795 HOST_WIDE_INT low = sext_hwi (val, 16);
1796 HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1797
1798 if (<MODE>mode == DImode && !satisfies_constraint_L (GEN_INT (rest)))
1799 FAIL;
1800
1801 /* The ordering here is important for the prolog expander.
1802 When space is allocated from the stack, adding 'low' first may
1803 produce a temporary deallocation (which would be bad). */
1804 emit_insn (gen_add<mode>3 (tmp, operands[1], GEN_INT (rest)));
1805 emit_insn (gen_add<mode>3 (operands[0], tmp, GEN_INT (low)));
1806 DONE;
1807 }
1808 })
1809
1810 (define_insn "*add<mode>3"
1811 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r,r,r")
1812 (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b,b,b")
1813 (match_operand:GPR 2 "add_operand" "r,I,L,eI")))]
1814 ""
1815 "@
1816 add %0,%1,%2
1817 addi %0,%1,%2
1818 addis %0,%1,%v2
1819 addi %0,%1,%2"
1820 [(set_attr "type" "add")
1821 (set_attr "isa" "*,*,*,p10")])
1822
1823 (define_insn "*addsi3_high"
1824 [(set (match_operand:SI 0 "gpc_reg_operand" "=b")
1825 (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
1826 (high:SI (match_operand 2 "" ""))))]
1827 "TARGET_MACHO && !TARGET_64BIT"
1828 "addis %0,%1,ha16(%2)"
1829 [(set_attr "type" "add")])
1830
1831 (define_insn_and_split "*add<mode>3_dot"
1832 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1833 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
1834 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
1835 (const_int 0)))
1836 (clobber (match_scratch:GPR 0 "=r,r"))]
1837 "<MODE>mode == Pmode"
1838 "@
1839 add. %0,%1,%2
1840 #"
1841 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1842 [(set (match_dup 0)
1843 (plus:GPR (match_dup 1)
1844 (match_dup 2)))
1845 (set (match_dup 3)
1846 (compare:CC (match_dup 0)
1847 (const_int 0)))]
1848 ""
1849 [(set_attr "type" "add")
1850 (set_attr "dot" "yes")
1851 (set_attr "length" "4,8")])
1852
1853 (define_insn_and_split "*add<mode>3_dot2"
1854 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1855 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
1856 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
1857 (const_int 0)))
1858 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1859 (plus:GPR (match_dup 1)
1860 (match_dup 2)))]
1861 "<MODE>mode == Pmode"
1862 "@
1863 add. %0,%1,%2
1864 #"
1865 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1866 [(set (match_dup 0)
1867 (plus:GPR (match_dup 1)
1868 (match_dup 2)))
1869 (set (match_dup 3)
1870 (compare:CC (match_dup 0)
1871 (const_int 0)))]
1872 ""
1873 [(set_attr "type" "add")
1874 (set_attr "dot" "yes")
1875 (set_attr "length" "4,8")])
1876
1877 (define_insn_and_split "*add<mode>3_imm_dot"
1878 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1879 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b")
1880 (match_operand:GPR 2 "short_cint_operand" "I,I"))
1881 (const_int 0)))
1882 (clobber (match_scratch:GPR 0 "=r,r"))
1883 (clobber (reg:GPR CA_REGNO))]
1884 "<MODE>mode == Pmode"
1885 "@
1886 addic. %0,%1,%2
1887 #"
1888 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1889 [(set (match_dup 0)
1890 (plus:GPR (match_dup 1)
1891 (match_dup 2)))
1892 (set (match_dup 3)
1893 (compare:CC (match_dup 0)
1894 (const_int 0)))]
1895 ""
1896 [(set_attr "type" "add")
1897 (set_attr "dot" "yes")
1898 (set_attr "length" "4,8")])
1899
1900 (define_insn_and_split "*add<mode>3_imm_dot2"
1901 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1902 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b")
1903 (match_operand:GPR 2 "short_cint_operand" "I,I"))
1904 (const_int 0)))
1905 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1906 (plus:GPR (match_dup 1)
1907 (match_dup 2)))
1908 (clobber (reg:GPR CA_REGNO))]
1909 "<MODE>mode == Pmode"
1910 "@
1911 addic. %0,%1,%2
1912 #"
1913 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1914 [(set (match_dup 0)
1915 (plus:GPR (match_dup 1)
1916 (match_dup 2)))
1917 (set (match_dup 3)
1918 (compare:CC (match_dup 0)
1919 (const_int 0)))]
1920 ""
1921 [(set_attr "type" "add")
1922 (set_attr "dot" "yes")
1923 (set_attr "length" "4,8")])
1924
1925 ;; Split an add that we can't do in one insn into two insns, each of which
1926 ;; does one 16-bit part. This is used by combine. Note that the low-order
1927 ;; add should be last in case the result gets used in an address.
1928
1929 (define_split
1930 [(set (match_operand:GPR 0 "gpc_reg_operand")
1931 (plus:GPR (match_operand:GPR 1 "gpc_reg_operand")
1932 (match_operand:GPR 2 "non_add_cint_operand")))]
1933 ""
1934 [(set (match_dup 0) (plus:GPR (match_dup 1) (match_dup 3)))
1935 (set (match_dup 0) (plus:GPR (match_dup 0) (match_dup 4)))]
1936 {
1937 HOST_WIDE_INT val = INTVAL (operands[2]);
1938 HOST_WIDE_INT low = sext_hwi (val, 16);
1939 HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1940
1941 operands[4] = GEN_INT (low);
1942 if (<MODE>mode == SImode || satisfies_constraint_L (GEN_INT (rest)))
1943 operands[3] = GEN_INT (rest);
1944 else if (can_create_pseudo_p ())
1945 {
1946 operands[3] = gen_reg_rtx (DImode);
1947 emit_move_insn (operands[3], operands[2]);
1948 emit_insn (gen_adddi3 (operands[0], operands[1], operands[3]));
1949 DONE;
1950 }
1951 else
1952 FAIL;
1953 })
1954
1955
1956 (define_insn "add<mode>3_carry"
1957 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1958 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1959 (match_operand:P 2 "reg_or_short_operand" "rI")))
1960 (set (reg:P CA_REGNO)
1961 (ltu:P (plus:P (match_dup 1)
1962 (match_dup 2))
1963 (match_dup 1)))]
1964 ""
1965 "add%I2c %0,%1,%2"
1966 [(set_attr "type" "add")])
1967
1968 (define_insn "*add<mode>3_imm_carry_pos"
1969 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1970 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1971 (match_operand:P 2 "short_cint_operand" "n")))
1972 (set (reg:P CA_REGNO)
1973 (geu:P (match_dup 1)
1974 (match_operand:P 3 "const_int_operand" "n")))]
1975 "INTVAL (operands[2]) > 0
1976 && INTVAL (operands[2]) + INTVAL (operands[3]) == 0"
1977 "addic %0,%1,%2"
1978 [(set_attr "type" "add")])
1979
1980 (define_insn "*add<mode>3_imm_carry_0"
1981 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1982 (match_operand:P 1 "gpc_reg_operand" "r"))
1983 (set (reg:P CA_REGNO)
1984 (const_int 0))]
1985 ""
1986 "addic %0,%1,0"
1987 [(set_attr "type" "add")])
1988
1989 (define_insn "*add<mode>3_imm_carry_m1"
1990 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1991 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1992 (const_int -1)))
1993 (set (reg:P CA_REGNO)
1994 (ne:P (match_dup 1)
1995 (const_int 0)))]
1996 ""
1997 "addic %0,%1,-1"
1998 [(set_attr "type" "add")])
1999
2000 (define_insn "*add<mode>3_imm_carry_neg"
2001 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2002 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
2003 (match_operand:P 2 "short_cint_operand" "n")))
2004 (set (reg:P CA_REGNO)
2005 (gtu:P (match_dup 1)
2006 (match_operand:P 3 "const_int_operand" "n")))]
2007 "INTVAL (operands[2]) < 0
2008 && INTVAL (operands[2]) + INTVAL (operands[3]) == -1"
2009 "addic %0,%1,%2"
2010 [(set_attr "type" "add")])
2011
2012
2013 (define_expand "add<mode>3_carry_in"
2014 [(parallel [
2015 (set (match_operand:GPR 0 "gpc_reg_operand")
2016 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand")
2017 (match_operand:GPR 2 "adde_operand"))
2018 (reg:GPR CA_REGNO)))
2019 (clobber (reg:GPR CA_REGNO))])]
2020 ""
2021 {
2022 if (operands[2] == const0_rtx)
2023 {
2024 emit_insn (gen_add<mode>3_carry_in_0 (operands[0], operands[1]));
2025 DONE;
2026 }
2027 if (operands[2] == constm1_rtx)
2028 {
2029 emit_insn (gen_add<mode>3_carry_in_m1 (operands[0], operands[1]));
2030 DONE;
2031 }
2032 })
2033
2034 (define_insn "*add<mode>3_carry_in_internal"
2035 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2036 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
2037 (match_operand:GPR 2 "gpc_reg_operand" "r"))
2038 (reg:GPR CA_REGNO)))
2039 (clobber (reg:GPR CA_REGNO))]
2040 ""
2041 "adde %0,%1,%2"
2042 [(set_attr "type" "add")])
2043
2044 (define_insn "*add<mode>3_carry_in_internal2"
2045 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2046 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
2047 (reg:GPR CA_REGNO))
2048 (match_operand:GPR 2 "gpc_reg_operand" "r")))
2049 (clobber (reg:GPR CA_REGNO))]
2050 ""
2051 "adde %0,%1,%2"
2052 [(set_attr "type" "add")])
2053
2054 (define_insn "add<mode>3_carry_in_0"
2055 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2056 (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
2057 (reg:GPR CA_REGNO)))
2058 (clobber (reg:GPR CA_REGNO))]
2059 ""
2060 "addze %0,%1"
2061 [(set_attr "type" "add")])
2062
2063 (define_insn "add<mode>3_carry_in_m1"
2064 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2065 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
2066 (reg:GPR CA_REGNO))
2067 (const_int -1)))
2068 (clobber (reg:GPR CA_REGNO))]
2069 ""
2070 "addme %0,%1"
2071 [(set_attr "type" "add")])
2072
2073
2074 (define_expand "one_cmpl<mode>2"
2075 [(set (match_operand:SDI 0 "gpc_reg_operand")
2076 (not:SDI (match_operand:SDI 1 "gpc_reg_operand")))]
2077 ""
2078 {
2079 if (<MODE>mode == DImode && !TARGET_POWERPC64)
2080 {
2081 rs6000_split_logical (operands, NOT, false, false, false);
2082 DONE;
2083 }
2084 })
2085
2086 (define_insn "*one_cmpl<mode>2"
2087 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2088 (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2089 ""
2090 "not %0,%1")
2091
2092 (define_insn_and_split "*one_cmpl<mode>2_dot"
2093 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2094 (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2095 (const_int 0)))
2096 (clobber (match_scratch:GPR 0 "=r,r"))]
2097 "<MODE>mode == Pmode"
2098 "@
2099 not. %0,%1
2100 #"
2101 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2102 [(set (match_dup 0)
2103 (not:GPR (match_dup 1)))
2104 (set (match_dup 2)
2105 (compare:CC (match_dup 0)
2106 (const_int 0)))]
2107 ""
2108 [(set_attr "type" "logical")
2109 (set_attr "dot" "yes")
2110 (set_attr "length" "4,8")])
2111
2112 (define_insn_and_split "*one_cmpl<mode>2_dot2"
2113 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2114 (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2115 (const_int 0)))
2116 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2117 (not:GPR (match_dup 1)))]
2118 "<MODE>mode == Pmode"
2119 "@
2120 not. %0,%1
2121 #"
2122 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2123 [(set (match_dup 0)
2124 (not:GPR (match_dup 1)))
2125 (set (match_dup 2)
2126 (compare:CC (match_dup 0)
2127 (const_int 0)))]
2128 ""
2129 [(set_attr "type" "logical")
2130 (set_attr "dot" "yes")
2131 (set_attr "length" "4,8")])
2132
2133
2134 (define_expand "sub<mode>3"
2135 [(set (match_operand:SDI 0 "gpc_reg_operand")
2136 (minus:SDI (match_operand:SDI 1 "reg_or_short_operand")
2137 (match_operand:SDI 2 "gpc_reg_operand")))]
2138 ""
2139 {
2140 if (<MODE>mode == DImode && !TARGET_POWERPC64)
2141 {
2142 rtx lo0 = gen_lowpart (SImode, operands[0]);
2143 rtx lo1 = gen_lowpart (SImode, operands[1]);
2144 rtx lo2 = gen_lowpart (SImode, operands[2]);
2145 rtx hi0 = gen_highpart (SImode, operands[0]);
2146 rtx hi1 = gen_highpart_mode (SImode, DImode, operands[1]);
2147 rtx hi2 = gen_highpart (SImode, operands[2]);
2148
2149 if (!reg_or_short_operand (lo1, SImode))
2150 lo1 = force_reg (SImode, lo1);
2151 if (!adde_operand (hi1, SImode))
2152 hi1 = force_reg (SImode, hi1);
2153
2154 emit_insn (gen_subfsi3_carry (lo0, lo2, lo1));
2155 emit_insn (gen_subfsi3_carry_in (hi0, hi2, hi1));
2156 DONE;
2157 }
2158
2159 if (short_cint_operand (operands[1], <MODE>mode))
2160 {
2161 emit_insn (gen_subf<mode>3_imm (operands[0], operands[2], operands[1]));
2162 DONE;
2163 }
2164 })
2165
2166 (define_insn "*subf<mode>3"
2167 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2168 (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r")
2169 (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2170 ""
2171 "subf %0,%1,%2"
2172 [(set_attr "type" "add")])
2173
2174 (define_insn_and_split "*subf<mode>3_dot"
2175 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2176 (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
2177 (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2178 (const_int 0)))
2179 (clobber (match_scratch:GPR 0 "=r,r"))]
2180 "<MODE>mode == Pmode"
2181 "@
2182 subf. %0,%1,%2
2183 #"
2184 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2185 [(set (match_dup 0)
2186 (minus:GPR (match_dup 2)
2187 (match_dup 1)))
2188 (set (match_dup 3)
2189 (compare:CC (match_dup 0)
2190 (const_int 0)))]
2191 ""
2192 [(set_attr "type" "add")
2193 (set_attr "dot" "yes")
2194 (set_attr "length" "4,8")])
2195
2196 (define_insn_and_split "*subf<mode>3_dot2"
2197 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2198 (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
2199 (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2200 (const_int 0)))
2201 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2202 (minus:GPR (match_dup 2)
2203 (match_dup 1)))]
2204 "<MODE>mode == Pmode"
2205 "@
2206 subf. %0,%1,%2
2207 #"
2208 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2209 [(set (match_dup 0)
2210 (minus:GPR (match_dup 2)
2211 (match_dup 1)))
2212 (set (match_dup 3)
2213 (compare:CC (match_dup 0)
2214 (const_int 0)))]
2215 ""
2216 [(set_attr "type" "add")
2217 (set_attr "dot" "yes")
2218 (set_attr "length" "4,8")])
2219
2220 (define_insn "subf<mode>3_imm"
2221 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2222 (minus:GPR (match_operand:GPR 2 "short_cint_operand" "I")
2223 (match_operand:GPR 1 "gpc_reg_operand" "r")))
2224 (clobber (reg:GPR CA_REGNO))]
2225 ""
2226 "subfic %0,%1,%2"
2227 [(set_attr "type" "add")])
2228
2229 (define_insn_and_split "subf<mode>3_carry_dot2"
2230 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2231 (compare:CC (minus:P (match_operand:P 2 "gpc_reg_operand" "r,r")
2232 (match_operand:P 1 "gpc_reg_operand" "r,r"))
2233 (const_int 0)))
2234 (set (match_operand:P 0 "gpc_reg_operand" "=r,r")
2235 (minus:P (match_dup 2)
2236 (match_dup 1)))
2237 (set (reg:P CA_REGNO)
2238 (leu:P (match_dup 1)
2239 (match_dup 2)))]
2240 "<MODE>mode == Pmode"
2241 "@
2242 subfc. %0,%1,%2
2243 #"
2244 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2245 [(parallel [(set (match_dup 0)
2246 (minus:P (match_dup 2)
2247 (match_dup 1)))
2248 (set (reg:P CA_REGNO)
2249 (leu:P (match_dup 1)
2250 (match_dup 2)))])
2251 (set (match_dup 3)
2252 (compare:CC (match_dup 0)
2253 (const_int 0)))]
2254 ""
2255 [(set_attr "type" "add")
2256 (set_attr "dot" "yes")
2257 (set_attr "length" "4,8")])
2258
2259 (define_insn "subf<mode>3_carry"
2260 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2261 (minus:P (match_operand:P 2 "reg_or_short_operand" "rI")
2262 (match_operand:P 1 "gpc_reg_operand" "r")))
2263 (set (reg:P CA_REGNO)
2264 (leu:P (match_dup 1)
2265 (match_dup 2)))]
2266 ""
2267 "subf%I2c %0,%1,%2"
2268 [(set_attr "type" "add")])
2269
2270 (define_insn "*subf<mode>3_imm_carry_0"
2271 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2272 (neg:P (match_operand:P 1 "gpc_reg_operand" "r")))
2273 (set (reg:P CA_REGNO)
2274 (eq:P (match_dup 1)
2275 (const_int 0)))]
2276 ""
2277 "subfic %0,%1,0"
2278 [(set_attr "type" "add")])
2279
2280 (define_insn "*subf<mode>3_imm_carry_m1"
2281 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2282 (not:P (match_operand:P 1 "gpc_reg_operand" "r")))
2283 (set (reg:P CA_REGNO)
2284 (const_int 1))]
2285 ""
2286 "subfic %0,%1,-1"
2287 [(set_attr "type" "add")])
2288
2289
2290 (define_expand "subf<mode>3_carry_in"
2291 [(parallel [
2292 (set (match_operand:GPR 0 "gpc_reg_operand")
2293 (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand"))
2294 (reg:GPR CA_REGNO))
2295 (match_operand:GPR 2 "adde_operand")))
2296 (clobber (reg:GPR CA_REGNO))])]
2297 ""
2298 {
2299 if (operands[2] == const0_rtx)
2300 {
2301 emit_insn (gen_subf<mode>3_carry_in_0 (operands[0], operands[1]));
2302 DONE;
2303 }
2304 if (operands[2] == constm1_rtx)
2305 {
2306 emit_insn (gen_subf<mode>3_carry_in_m1 (operands[0], operands[1]));
2307 DONE;
2308 }
2309 })
2310
2311 (define_insn "*subf<mode>3_carry_in_internal"
2312 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2313 (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
2314 (reg:GPR CA_REGNO))
2315 (match_operand:GPR 2 "gpc_reg_operand" "r")))
2316 (clobber (reg:GPR CA_REGNO))]
2317 ""
2318 "subfe %0,%1,%2"
2319 [(set_attr "type" "add")])
2320
2321 (define_insn "subf<mode>3_carry_in_0"
2322 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2323 (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
2324 (reg:GPR CA_REGNO)))
2325 (clobber (reg:GPR CA_REGNO))]
2326 ""
2327 "subfze %0,%1"
2328 [(set_attr "type" "add")])
2329
2330 (define_insn "subf<mode>3_carry_in_m1"
2331 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2332 (plus:GPR (minus:GPR (reg:GPR CA_REGNO)
2333 (match_operand:GPR 1 "gpc_reg_operand" "r"))
2334 (const_int -2)))
2335 (clobber (reg:GPR CA_REGNO))]
2336 ""
2337 "subfme %0,%1"
2338 [(set_attr "type" "add")])
2339
2340 (define_insn "subf<mode>3_carry_in_xx"
2341 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2342 (plus:GPR (reg:GPR CA_REGNO)
2343 (const_int -1)))
2344 (clobber (reg:GPR CA_REGNO))]
2345 ""
2346 "subfe %0,%0,%0"
2347 [(set_attr "type" "add")])
2348
2349 (define_insn_and_split "*subfsi3_carry_in_xx_64"
2350 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2351 (sign_extend:DI (plus:SI (reg:SI CA_REGNO)
2352 (const_int -1))))]
2353 "TARGET_POWERPC64"
2354 "#"
2355 "&&1"
2356 [(parallel [(set (match_dup 0)
2357 (plus:DI (reg:DI CA_REGNO)
2358 (const_int -1)))
2359 (clobber (reg:DI CA_REGNO))])]
2360 ""
2361 )
2362
2363 (define_insn "@neg<mode>2"
2364 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2365 (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2366 ""
2367 "neg %0,%1"
2368 [(set_attr "type" "add")])
2369
2370 (define_insn_and_split "*neg<mode>2_dot"
2371 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2372 (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2373 (const_int 0)))
2374 (clobber (match_scratch:GPR 0 "=r,r"))]
2375 "<MODE>mode == Pmode"
2376 "@
2377 neg. %0,%1
2378 #"
2379 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2380 [(set (match_dup 0)
2381 (neg:GPR (match_dup 1)))
2382 (set (match_dup 2)
2383 (compare:CC (match_dup 0)
2384 (const_int 0)))]
2385 ""
2386 [(set_attr "type" "add")
2387 (set_attr "dot" "yes")
2388 (set_attr "length" "4,8")])
2389
2390 (define_insn_and_split "*neg<mode>2_dot2"
2391 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2392 (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2393 (const_int 0)))
2394 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2395 (neg:GPR (match_dup 1)))]
2396 "<MODE>mode == Pmode"
2397 "@
2398 neg. %0,%1
2399 #"
2400 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2401 [(set (match_dup 0)
2402 (neg:GPR (match_dup 1)))
2403 (set (match_dup 2)
2404 (compare:CC (match_dup 0)
2405 (const_int 0)))]
2406 ""
2407 [(set_attr "type" "add")
2408 (set_attr "dot" "yes")
2409 (set_attr "length" "4,8")])
2410
2411
2412 (define_insn "clz<mode>2"
2413 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2414 (clz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2415 ""
2416 "cntlz<wd> %0,%1"
2417 [(set_attr "type" "cntlz")])
2418
2419 (define_expand "ctz<mode>2"
2420 [(set (match_operand:GPR 0 "gpc_reg_operand")
2421 (ctz:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2422 ""
2423 {
2424 if (TARGET_CTZ)
2425 {
2426 emit_insn (gen_ctz<mode>2_hw (operands[0], operands[1]));
2427 DONE;
2428 }
2429
2430 rtx tmp1 = gen_reg_rtx (<MODE>mode);
2431 rtx tmp2 = gen_reg_rtx (<MODE>mode);
2432 rtx tmp3 = gen_reg_rtx (<MODE>mode);
2433
2434 if (TARGET_POPCNTD)
2435 {
2436 emit_insn (gen_add<mode>3 (tmp1, operands[1], constm1_rtx));
2437 emit_insn (gen_one_cmpl<mode>2 (tmp2, operands[1]));
2438 emit_insn (gen_and<mode>3 (tmp3, tmp1, tmp2));
2439 emit_insn (gen_popcntd<mode>2 (operands[0], tmp3));
2440 }
2441 else
2442 {
2443 emit_insn (gen_neg<mode>2 (tmp1, operands[1]));
2444 emit_insn (gen_and<mode>3 (tmp2, operands[1], tmp1));
2445 emit_insn (gen_clz<mode>2 (tmp3, tmp2));
2446 emit_insn (gen_sub<mode>3 (operands[0], GEN_INT (<bits> - 1), tmp3));
2447 }
2448
2449 DONE;
2450 })
2451
2452 (define_insn "ctz<mode>2_hw"
2453 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2454 (ctz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2455 "TARGET_CTZ"
2456 "cnttz<wd> %0,%1"
2457 [(set_attr "type" "cntlz")])
2458
2459 (define_expand "ffs<mode>2"
2460 [(set (match_operand:GPR 0 "gpc_reg_operand")
2461 (ffs:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2462 ""
2463 {
2464 rtx tmp1 = gen_reg_rtx (<MODE>mode);
2465 rtx tmp2 = gen_reg_rtx (<MODE>mode);
2466 rtx tmp3 = gen_reg_rtx (<MODE>mode);
2467 emit_insn (gen_neg<mode>2 (tmp1, operands[1]));
2468 emit_insn (gen_and<mode>3 (tmp2, operands[1], tmp1));
2469 emit_insn (gen_clz<mode>2 (tmp3, tmp2));
2470 emit_insn (gen_sub<mode>3 (operands[0], GEN_INT (<bits>), tmp3));
2471 DONE;
2472 })
2473
2474
2475 (define_expand "popcount<mode>2"
2476 [(set (match_operand:GPR 0 "gpc_reg_operand")
2477 (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2478 "TARGET_POPCNTB || TARGET_POPCNTD"
2479 {
2480 rs6000_emit_popcount (operands[0], operands[1]);
2481 DONE;
2482 })
2483
2484 (define_insn "popcntb<mode>2"
2485 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2486 (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")]
2487 UNSPEC_POPCNTB))]
2488 "TARGET_POPCNTB"
2489 "popcntb %0,%1"
2490 [(set_attr "type" "popcnt")])
2491
2492 (define_insn "popcntd<mode>2"
2493 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2494 (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2495 "TARGET_POPCNTD"
2496 "popcnt<wd> %0,%1"
2497 [(set_attr "type" "popcnt")])
2498
2499
2500 (define_expand "parity<mode>2"
2501 [(set (match_operand:GPR 0 "gpc_reg_operand")
2502 (parity:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2503 "TARGET_POPCNTB"
2504 {
2505 rs6000_emit_parity (operands[0], operands[1]);
2506 DONE;
2507 })
2508
2509 (define_insn "parity<mode>2_cmpb"
2510 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2511 (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")] UNSPEC_PARITY))]
2512 "TARGET_CMPB && TARGET_POPCNTB"
2513 "prty<wd> %0,%1"
2514 [(set_attr "type" "popcnt")])
2515
2516 (define_insn "cfuged"
2517 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2518 (unspec:DI [(match_operand:DI 1 "gpc_reg_operand" "r")
2519 (match_operand:DI 2 "gpc_reg_operand" "r")]
2520 UNSPEC_CFUGED))]
2521 "TARGET_POWER10 && TARGET_64BIT"
2522 "cfuged %0,%1,%2"
2523 [(set_attr "type" "integer")])
2524
2525 (define_insn "cntlzdm"
2526 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2527 (unspec:DI [(match_operand:DI 1 "gpc_reg_operand" "r")
2528 (match_operand:DI 2 "gpc_reg_operand" "r")]
2529 UNSPEC_CNTLZDM))]
2530 "TARGET_POWER10 && TARGET_POWERPC64"
2531 "cntlzdm %0,%1,%2"
2532 [(set_attr "type" "integer")])
2533
2534 (define_insn "cnttzdm"
2535 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2536 (unspec:DI [(match_operand:DI 1 "gpc_reg_operand" "r")
2537 (match_operand:DI 2 "gpc_reg_operand" "r")]
2538 UNSPEC_CNTTZDM))]
2539 "TARGET_POWER10 && TARGET_POWERPC64"
2540 "cnttzdm %0,%1,%2"
2541 [(set_attr "type" "integer")])
2542
2543 (define_insn "pdepd"
2544 [(set (match_operand:DI 0 "register_operand" "=r")
2545 (unspec:DI [(match_operand:DI 1 "gpc_reg_operand" "r")
2546 (match_operand:DI 2 "gpc_reg_operand" "r")]
2547 UNSPEC_PDEPD))]
2548 "TARGET_POWER10 && TARGET_POWERPC64"
2549 "pdepd %0,%1,%2"
2550 [(set_attr "type" "integer")])
2551
2552 (define_insn "pextd"
2553 [(set (match_operand:DI 0 "register_operand" "=r")
2554 (unspec:DI [(match_operand:DI 1 "gpc_reg_operand" "r")
2555 (match_operand:DI 2 "gpc_reg_operand" "r")]
2556 UNSPEC_PEXTD))]
2557 "TARGET_POWER10 && TARGET_POWERPC64"
2558 "pextd %0,%1,%2"
2559 [(set_attr "type" "integer")])
2560
2561 (define_insn "cmpb<mode>3"
2562 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2563 (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")
2564 (match_operand:GPR 2 "gpc_reg_operand" "r")] UNSPEC_CMPB))]
2565 "TARGET_CMPB"
2566 "cmpb %0,%1,%2"
2567 [(set_attr "type" "cmp")])
2568
2569 ;; Since the hardware zeros the upper part of the register, save generating the
2570 ;; AND immediate if we are converting to unsigned
2571 (define_insn "*bswap<mode>2_extenddi"
2572 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2573 (zero_extend:DI
2574 (bswap:HSI (match_operand:HSI 1 "memory_operand" "Z"))))]
2575 "TARGET_POWERPC64"
2576 "l<wd>brx %0,%y1"
2577 [(set_attr "type" "load")])
2578
2579 (define_insn "*bswaphi2_extendsi"
2580 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2581 (zero_extend:SI
2582 (bswap:HI (match_operand:HI 1 "memory_operand" "Z"))))]
2583 ""
2584 "lhbrx %0,%y1"
2585 [(set_attr "type" "load")])
2586
2587 ;; Separate the bswap patterns into load, store, and gpr<-gpr. This prevents
2588 ;; the register allocator from converting a gpr<-gpr swap into a store and then
2589 ;; load with byte swap, which can be slower than doing it in the registers. It
2590 ;; also prevents certain failures with the RELOAD register allocator.
2591
2592 (define_expand "bswap<mode>2"
2593 [(use (match_operand:HSI 0 "reg_or_mem_operand"))
2594 (use (match_operand:HSI 1 "reg_or_mem_operand"))]
2595 ""
2596 {
2597 rtx dest = operands[0];
2598 rtx src = operands[1];
2599
2600 if (!REG_P (dest) && !REG_P (src))
2601 src = force_reg (<MODE>mode, src);
2602
2603 if (MEM_P (src))
2604 {
2605 src = rs6000_force_indexed_or_indirect_mem (src);
2606 emit_insn (gen_bswap<mode>2_load (dest, src));
2607 }
2608 else if (MEM_P (dest))
2609 {
2610 dest = rs6000_force_indexed_or_indirect_mem (dest);
2611 emit_insn (gen_bswap<mode>2_store (dest, src));
2612 }
2613 else
2614 emit_insn (gen_bswap<mode>2_reg (dest, src));
2615 DONE;
2616 })
2617
2618 (define_insn "bswap<mode>2_load"
2619 [(set (match_operand:HSI 0 "gpc_reg_operand" "=r")
2620 (bswap:HSI (match_operand:HSI 1 "memory_operand" "Z")))]
2621 ""
2622 "l<wd>brx %0,%y1"
2623 [(set_attr "type" "load")])
2624
2625 (define_insn "bswap<mode>2_store"
2626 [(set (match_operand:HSI 0 "memory_operand" "=Z")
2627 (bswap:HSI (match_operand:HSI 1 "gpc_reg_operand" "r")))]
2628 ""
2629 "st<wd>brx %1,%y0"
2630 [(set_attr "type" "store")])
2631
2632 (define_insn_and_split "bswaphi2_reg"
2633 [(set (match_operand:HI 0 "gpc_reg_operand" "=r,&r,wa")
2634 (bswap:HI
2635 (match_operand:HI 1 "gpc_reg_operand" "r,r,wa")))
2636 (clobber (match_scratch:SI 2 "=X,&r,X"))]
2637 ""
2638 "@
2639 brh %0,%1
2640 #
2641 xxbrh %x0,%x1"
2642 "reload_completed && !TARGET_POWER10 && int_reg_operand (operands[0], HImode)"
2643 [(set (match_dup 3)
2644 (and:SI (lshiftrt:SI (match_dup 4)
2645 (const_int 8))
2646 (const_int 255)))
2647 (set (match_dup 2)
2648 (and:SI (ashift:SI (match_dup 4)
2649 (const_int 8))
2650 (const_int 65280))) ;; 0xff00
2651 (set (match_dup 3)
2652 (ior:SI (match_dup 3)
2653 (match_dup 2)))]
2654 {
2655 operands[3] = simplify_gen_subreg (SImode, operands[0], HImode, 0);
2656 operands[4] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
2657 }
2658 [(set_attr "length" "*,12,*")
2659 (set_attr "type" "shift,*,vecperm")
2660 (set_attr "isa" "p10,*,p9v")])
2661
2662 ;; We are always BITS_BIG_ENDIAN, so the bit positions below in
2663 ;; zero_extract insns do not change for -mlittle.
2664 (define_insn_and_split "bswapsi2_reg"
2665 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,&r,wa")
2666 (bswap:SI
2667 (match_operand:SI 1 "gpc_reg_operand" "r,r,wa")))]
2668 ""
2669 "@
2670 brw %0,%1
2671 #
2672 xxbrw %x0,%x1"
2673 "reload_completed && !TARGET_POWER10 && int_reg_operand (operands[0], SImode)"
2674 [(set (match_dup 0) ; DABC
2675 (rotate:SI (match_dup 1)
2676 (const_int 24)))
2677 (set (match_dup 0) ; DCBC
2678 (ior:SI (and:SI (ashift:SI (match_dup 1)
2679 (const_int 8))
2680 (const_int 16711680))
2681 (and:SI (match_dup 0)
2682 (const_int -16711681))))
2683 (set (match_dup 0) ; DCBA
2684 (ior:SI (and:SI (lshiftrt:SI (match_dup 1)
2685 (const_int 24))
2686 (const_int 255))
2687 (and:SI (match_dup 0)
2688 (const_int -256))))]
2689 ""
2690 [(set_attr "length" "4,12,4")
2691 (set_attr "type" "shift,*,vecperm")
2692 (set_attr "isa" "p10,*,p9v")])
2693
2694 ;; On systems with LDBRX/STDBRX generate the loads/stores directly, just like
2695 ;; we do for L{H,W}BRX and ST{H,W}BRX above. If not, we have to generate more
2696 ;; complex code.
2697
2698 (define_expand "bswapdi2"
2699 [(parallel [(set (match_operand:DI 0 "reg_or_mem_operand")
2700 (bswap:DI
2701 (match_operand:DI 1 "reg_or_mem_operand")))
2702 (clobber (match_scratch:DI 2))
2703 (clobber (match_scratch:DI 3))])]
2704 ""
2705 {
2706 rtx dest = operands[0];
2707 rtx src = operands[1];
2708
2709 if (!REG_P (dest) && !REG_P (src))
2710 operands[1] = src = force_reg (DImode, src);
2711
2712 if (TARGET_POWERPC64 && TARGET_LDBRX)
2713 {
2714 if (MEM_P (src))
2715 {
2716 src = rs6000_force_indexed_or_indirect_mem (src);
2717 emit_insn (gen_bswapdi2_load (dest, src));
2718 }
2719 else if (MEM_P (dest))
2720 {
2721 dest = rs6000_force_indexed_or_indirect_mem (dest);
2722 emit_insn (gen_bswapdi2_store (dest, src));
2723 }
2724 else if (TARGET_P9_VECTOR)
2725 emit_insn (gen_bswapdi2_brd (dest, src));
2726 else
2727 emit_insn (gen_bswapdi2_reg (dest, src));
2728 DONE;
2729 }
2730
2731 if (!TARGET_POWERPC64)
2732 {
2733 /* 32-bit mode needs fewer scratch registers, but 32-bit addressing mode
2734 that uses 64-bit registers needs the same scratch registers as 64-bit
2735 mode. */
2736 emit_insn (gen_bswapdi2_32bit (dest, src));
2737 DONE;
2738 }
2739 })
2740
2741 ;; Power7/cell has ldbrx/stdbrx, so use it directly
2742 (define_insn "bswapdi2_load"
2743 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2744 (bswap:DI (match_operand:DI 1 "memory_operand" "Z")))]
2745 "TARGET_POWERPC64 && TARGET_LDBRX"
2746 "ldbrx %0,%y1"
2747 [(set_attr "type" "load")])
2748
2749 (define_insn "bswapdi2_store"
2750 [(set (match_operand:DI 0 "memory_operand" "=Z")
2751 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "r")))]
2752 "TARGET_POWERPC64 && TARGET_LDBRX"
2753 "stdbrx %1,%y0"
2754 [(set_attr "type" "store")])
2755
2756 (define_insn "bswapdi2_brd"
2757 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,wa")
2758 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "r,wa")))]
2759 "TARGET_P9_VECTOR"
2760 "@
2761 brd %0,%1
2762 xxbrd %x0,%x1"
2763 [(set_attr "type" "shift,vecperm")
2764 (set_attr "isa" "p10,p9v")])
2765
2766 (define_insn "bswapdi2_reg"
2767 [(set (match_operand:DI 0 "gpc_reg_operand" "=&r")
2768 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "r")))
2769 (clobber (match_scratch:DI 2 "=&r"))
2770 (clobber (match_scratch:DI 3 "=&r"))]
2771 "TARGET_POWERPC64 && TARGET_LDBRX && !TARGET_P9_VECTOR"
2772 "#"
2773 [(set_attr "length" "36")])
2774
2775 ;; Non-power7/cell, fall back to use lwbrx/stwbrx
2776 (define_insn "*bswapdi2_64bit"
2777 [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,&r")
2778 (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2779 (clobber (match_scratch:DI 2 "=&b,&b,&r"))
2780 (clobber (match_scratch:DI 3 "=&r,&r,&r"))]
2781 "TARGET_POWERPC64 && !TARGET_LDBRX
2782 && (REG_P (operands[0]) || REG_P (operands[1]))
2783 && !(MEM_P (operands[0]) && MEM_VOLATILE_P (operands[0]))
2784 && !(MEM_P (operands[1]) && MEM_VOLATILE_P (operands[1]))"
2785 "#"
2786 [(set_attr "length" "16,12,36")])
2787
2788 (define_split
2789 [(set (match_operand:DI 0 "gpc_reg_operand")
2790 (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand")))
2791 (clobber (match_operand:DI 2 "gpc_reg_operand"))
2792 (clobber (match_operand:DI 3 "gpc_reg_operand"))]
2793 "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2794 [(const_int 0)]
2795 {
2796 rtx dest = operands[0];
2797 rtx src = operands[1];
2798 rtx op2 = operands[2];
2799 rtx op3 = operands[3];
2800 rtx op3_32 = simplify_gen_subreg (SImode, op3, DImode,
2801 BYTES_BIG_ENDIAN ? 4 : 0);
2802 rtx dest_32 = simplify_gen_subreg (SImode, dest, DImode,
2803 BYTES_BIG_ENDIAN ? 4 : 0);
2804 rtx addr1;
2805 rtx addr2;
2806 rtx word1;
2807 rtx word2;
2808
2809 addr1 = XEXP (src, 0);
2810 if (GET_CODE (addr1) == PLUS)
2811 {
2812 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2813 if (TARGET_AVOID_XFORM)
2814 {
2815 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2816 addr2 = op2;
2817 }
2818 else
2819 addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2820 }
2821 else if (TARGET_AVOID_XFORM)
2822 {
2823 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2824 addr2 = op2;
2825 }
2826 else
2827 {
2828 emit_move_insn (op2, GEN_INT (4));
2829 addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2830 }
2831
2832 word1 = change_address (src, SImode, addr1);
2833 word2 = change_address (src, SImode, addr2);
2834
2835 if (BYTES_BIG_ENDIAN)
2836 {
2837 emit_insn (gen_bswapsi2 (op3_32, word2));
2838 emit_insn (gen_bswapsi2 (dest_32, word1));
2839 }
2840 else
2841 {
2842 emit_insn (gen_bswapsi2 (op3_32, word1));
2843 emit_insn (gen_bswapsi2 (dest_32, word2));
2844 }
2845
2846 emit_insn (gen_rotldi3_insert_3 (dest, op3, GEN_INT (32), dest,
2847 GEN_INT (0xffffffff)));
2848 DONE;
2849 })
2850
2851 (define_split
2852 [(set (match_operand:DI 0 "indexed_or_indirect_operand")
2853 (bswap:DI (match_operand:DI 1 "gpc_reg_operand")))
2854 (clobber (match_operand:DI 2 "gpc_reg_operand"))
2855 (clobber (match_operand:DI 3 "gpc_reg_operand"))]
2856 "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2857 [(const_int 0)]
2858 {
2859 rtx dest = operands[0];
2860 rtx src = operands[1];
2861 rtx op2 = operands[2];
2862 rtx op3 = operands[3];
2863 rtx src_si = simplify_gen_subreg (SImode, src, DImode,
2864 BYTES_BIG_ENDIAN ? 4 : 0);
2865 rtx op3_si = simplify_gen_subreg (SImode, op3, DImode,
2866 BYTES_BIG_ENDIAN ? 4 : 0);
2867 rtx addr1;
2868 rtx addr2;
2869 rtx word1;
2870 rtx word2;
2871
2872 addr1 = XEXP (dest, 0);
2873 if (GET_CODE (addr1) == PLUS)
2874 {
2875 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2876 if (TARGET_AVOID_XFORM)
2877 {
2878 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2879 addr2 = op2;
2880 }
2881 else
2882 addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2883 }
2884 else if (TARGET_AVOID_XFORM)
2885 {
2886 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2887 addr2 = op2;
2888 }
2889 else
2890 {
2891 emit_move_insn (op2, GEN_INT (4));
2892 addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2893 }
2894
2895 word1 = change_address (dest, SImode, addr1);
2896 word2 = change_address (dest, SImode, addr2);
2897
2898 emit_insn (gen_lshrdi3 (op3, src, GEN_INT (32)));
2899
2900 if (BYTES_BIG_ENDIAN)
2901 {
2902 emit_insn (gen_bswapsi2 (word1, src_si));
2903 emit_insn (gen_bswapsi2 (word2, op3_si));
2904 }
2905 else
2906 {
2907 emit_insn (gen_bswapsi2 (word2, src_si));
2908 emit_insn (gen_bswapsi2 (word1, op3_si));
2909 }
2910 DONE;
2911 })
2912
2913 (define_split
2914 [(set (match_operand:DI 0 "gpc_reg_operand")
2915 (bswap:DI (match_operand:DI 1 "gpc_reg_operand")))
2916 (clobber (match_operand:DI 2 "gpc_reg_operand"))
2917 (clobber (match_operand:DI 3 "gpc_reg_operand"))]
2918 "TARGET_POWERPC64 && !TARGET_P9_VECTOR && reload_completed"
2919 [(const_int 0)]
2920 {
2921 rtx dest = operands[0];
2922 rtx src = operands[1];
2923 rtx op2 = operands[2];
2924 rtx op3 = operands[3];
2925 int lo_off = BYTES_BIG_ENDIAN ? 4 : 0;
2926 rtx dest_si = simplify_gen_subreg (SImode, dest, DImode, lo_off);
2927 rtx src_si = simplify_gen_subreg (SImode, src, DImode, lo_off);
2928 rtx op2_si = simplify_gen_subreg (SImode, op2, DImode, lo_off);
2929 rtx op3_si = simplify_gen_subreg (SImode, op3, DImode, lo_off);
2930
2931 emit_insn (gen_lshrdi3 (op2, src, GEN_INT (32)));
2932 emit_insn (gen_bswapsi2 (op3_si, src_si));
2933 emit_insn (gen_bswapsi2 (dest_si, op2_si));
2934 emit_insn (gen_rotldi3_insert_3 (dest, op3, GEN_INT (32), dest,
2935 GEN_INT (0xffffffff)));
2936 DONE;
2937 })
2938
2939 (define_insn "bswapdi2_32bit"
2940 [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,?&r")
2941 (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2942 (clobber (match_scratch:SI 2 "=&b,&b,X"))]
2943 "!TARGET_POWERPC64 && (REG_P (operands[0]) || REG_P (operands[1]))"
2944 "#"
2945 [(set_attr "length" "16,12,36")])
2946
2947 (define_split
2948 [(set (match_operand:DI 0 "gpc_reg_operand")
2949 (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand")))
2950 (clobber (match_operand:SI 2 "gpc_reg_operand"))]
2951 "!TARGET_POWERPC64 && reload_completed"
2952 [(const_int 0)]
2953 {
2954 rtx dest = operands[0];
2955 rtx src = operands[1];
2956 rtx op2 = operands[2];
2957 rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
2958 rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
2959 rtx addr1;
2960 rtx addr2;
2961 rtx word1;
2962 rtx word2;
2963
2964 addr1 = XEXP (src, 0);
2965 if (GET_CODE (addr1) == PLUS)
2966 {
2967 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2968 if (TARGET_AVOID_XFORM
2969 || REGNO (XEXP (addr1, 1)) == REGNO (dest2))
2970 {
2971 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2972 addr2 = op2;
2973 }
2974 else
2975 addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
2976 }
2977 else if (TARGET_AVOID_XFORM
2978 || REGNO (addr1) == REGNO (dest2))
2979 {
2980 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2981 addr2 = op2;
2982 }
2983 else
2984 {
2985 emit_move_insn (op2, GEN_INT (4));
2986 addr2 = gen_rtx_PLUS (SImode, op2, addr1);
2987 }
2988
2989 word1 = change_address (src, SImode, addr1);
2990 word2 = change_address (src, SImode, addr2);
2991
2992 emit_insn (gen_bswapsi2 (dest2, word1));
2993 /* The REGNO (dest2) tests above ensure that addr2 has not been trashed,
2994 thus allowing us to omit an early clobber on the output. */
2995 emit_insn (gen_bswapsi2 (dest1, word2));
2996 DONE;
2997 })
2998
2999 (define_split
3000 [(set (match_operand:DI 0 "indexed_or_indirect_operand")
3001 (bswap:DI (match_operand:DI 1 "gpc_reg_operand")))
3002 (clobber (match_operand:SI 2 "gpc_reg_operand"))]
3003 "!TARGET_POWERPC64 && reload_completed"
3004 [(const_int 0)]
3005 {
3006 rtx dest = operands[0];
3007 rtx src = operands[1];
3008 rtx op2 = operands[2];
3009 rtx src1 = simplify_gen_subreg (SImode, src, DImode, 0);
3010 rtx src2 = simplify_gen_subreg (SImode, src, DImode, 4);
3011 rtx addr1;
3012 rtx addr2;
3013 rtx word1;
3014 rtx word2;
3015
3016 addr1 = XEXP (dest, 0);
3017 if (GET_CODE (addr1) == PLUS)
3018 {
3019 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
3020 if (TARGET_AVOID_XFORM)
3021 {
3022 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
3023 addr2 = op2;
3024 }
3025 else
3026 addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
3027 }
3028 else if (TARGET_AVOID_XFORM)
3029 {
3030 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
3031 addr2 = op2;
3032 }
3033 else
3034 {
3035 emit_move_insn (op2, GEN_INT (4));
3036 addr2 = gen_rtx_PLUS (SImode, op2, addr1);
3037 }
3038
3039 word1 = change_address (dest, SImode, addr1);
3040 word2 = change_address (dest, SImode, addr2);
3041
3042 emit_insn (gen_bswapsi2 (word2, src1));
3043 emit_insn (gen_bswapsi2 (word1, src2));
3044 DONE;
3045 })
3046
3047 (define_split
3048 [(set (match_operand:DI 0 "gpc_reg_operand")
3049 (bswap:DI (match_operand:DI 1 "gpc_reg_operand")))
3050 (clobber (match_operand:SI 2 ""))]
3051 "!TARGET_POWERPC64 && reload_completed"
3052 [(const_int 0)]
3053 {
3054 rtx dest = operands[0];
3055 rtx src = operands[1];
3056 rtx src1 = simplify_gen_subreg (SImode, src, DImode, 0);
3057 rtx src2 = simplify_gen_subreg (SImode, src, DImode, 4);
3058 rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
3059 rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
3060
3061 emit_insn (gen_bswapsi2 (dest1, src2));
3062 emit_insn (gen_bswapsi2 (dest2, src1));
3063 DONE;
3064 })
3065
3066
3067 (define_insn "mul<mode>3"
3068 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3069 (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3070 (match_operand:GPR 2 "reg_or_short_operand" "r,I")))]
3071 ""
3072 "@
3073 mull<wd> %0,%1,%2
3074 mulli %0,%1,%2"
3075 [(set_attr "type" "mul")
3076 (set (attr "size")
3077 (cond [(match_operand:GPR 2 "s8bit_cint_operand")
3078 (const_string "8")
3079 (match_operand:GPR 2 "short_cint_operand")
3080 (const_string "16")]
3081 (const_string "<bits>")))])
3082
3083 (define_insn_and_split "*mul<mode>3_dot"
3084 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3085 (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3086 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3087 (const_int 0)))
3088 (clobber (match_scratch:GPR 0 "=r,r"))]
3089 "<MODE>mode == Pmode"
3090 "@
3091 mull<wd>. %0,%1,%2
3092 #"
3093 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3094 [(set (match_dup 0)
3095 (mult:GPR (match_dup 1)
3096 (match_dup 2)))
3097 (set (match_dup 3)
3098 (compare:CC (match_dup 0)
3099 (const_int 0)))]
3100 ""
3101 [(set_attr "type" "mul")
3102 (set_attr "size" "<bits>")
3103 (set_attr "dot" "yes")
3104 (set_attr "length" "4,8")])
3105
3106 (define_insn_and_split "*mul<mode>3_dot2"
3107 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3108 (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3109 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3110 (const_int 0)))
3111 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3112 (mult:GPR (match_dup 1)
3113 (match_dup 2)))]
3114 "<MODE>mode == Pmode"
3115 "@
3116 mull<wd>. %0,%1,%2
3117 #"
3118 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3119 [(set (match_dup 0)
3120 (mult:GPR (match_dup 1)
3121 (match_dup 2)))
3122 (set (match_dup 3)
3123 (compare:CC (match_dup 0)
3124 (const_int 0)))]
3125 ""
3126 [(set_attr "type" "mul")
3127 (set_attr "size" "<bits>")
3128 (set_attr "dot" "yes")
3129 (set_attr "length" "4,8")])
3130
3131
3132 (define_expand "<su>mul<mode>3_highpart"
3133 [(set (match_operand:GPR 0 "gpc_reg_operand")
3134 (subreg:GPR
3135 (mult:<DMODE> (any_extend:<DMODE>
3136 (match_operand:GPR 1 "gpc_reg_operand"))
3137 (any_extend:<DMODE>
3138 (match_operand:GPR 2 "gpc_reg_operand")))
3139 0))]
3140 ""
3141 {
3142 if (<MODE>mode == SImode && TARGET_POWERPC64)
3143 {
3144 emit_insn (gen_<su>mulsi3_highpart_64 (operands[0], operands[1],
3145 operands[2]));
3146 DONE;
3147 }
3148
3149 if (!WORDS_BIG_ENDIAN)
3150 {
3151 emit_insn (gen_<su>mul<mode>3_highpart_le (operands[0], operands[1],
3152 operands[2]));
3153 DONE;
3154 }
3155 })
3156
3157 (define_insn "*<su>mul<mode>3_highpart"
3158 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3159 (subreg:GPR
3160 (mult:<DMODE> (any_extend:<DMODE>
3161 (match_operand:GPR 1 "gpc_reg_operand" "r"))
3162 (any_extend:<DMODE>
3163 (match_operand:GPR 2 "gpc_reg_operand" "r")))
3164 0))]
3165 "WORDS_BIG_ENDIAN && !(<MODE>mode == SImode && TARGET_POWERPC64)"
3166 "mulh<wd><u> %0,%1,%2"
3167 [(set_attr "type" "mul")
3168 (set_attr "size" "<bits>")])
3169
3170 (define_insn "<su>mulsi3_highpart_le"
3171 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
3172 (subreg:SI
3173 (mult:DI (any_extend:DI
3174 (match_operand:SI 1 "gpc_reg_operand" "r"))
3175 (any_extend:DI
3176 (match_operand:SI 2 "gpc_reg_operand" "r")))
3177 4))]
3178 "!WORDS_BIG_ENDIAN && !TARGET_POWERPC64"
3179 "mulhw<u> %0,%1,%2"
3180 [(set_attr "type" "mul")])
3181
3182 (define_insn "<su>muldi3_highpart_le"
3183 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3184 (subreg:DI
3185 (mult:TI (any_extend:TI
3186 (match_operand:DI 1 "gpc_reg_operand" "r"))
3187 (any_extend:TI
3188 (match_operand:DI 2 "gpc_reg_operand" "r")))
3189 8))]
3190 "!WORDS_BIG_ENDIAN && TARGET_POWERPC64"
3191 "mulhd<u> %0,%1,%2"
3192 [(set_attr "type" "mul")
3193 (set_attr "size" "64")])
3194
3195 (define_insn "<su>mulsi3_highpart_64"
3196 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
3197 (truncate:SI
3198 (lshiftrt:DI
3199 (mult:DI (any_extend:DI
3200 (match_operand:SI 1 "gpc_reg_operand" "r"))
3201 (any_extend:DI
3202 (match_operand:SI 2 "gpc_reg_operand" "r")))
3203 (const_int 32))))]
3204 "TARGET_POWERPC64"
3205 "mulhw<u> %0,%1,%2"
3206 [(set_attr "type" "mul")])
3207
3208 (define_expand "<u>mul<mode><dmode>3"
3209 [(set (match_operand:<DMODE> 0 "gpc_reg_operand")
3210 (mult:<DMODE> (any_extend:<DMODE>
3211 (match_operand:GPR 1 "gpc_reg_operand"))
3212 (any_extend:<DMODE>
3213 (match_operand:GPR 2 "gpc_reg_operand"))))]
3214 "!(<MODE>mode == SImode && TARGET_POWERPC64)"
3215 {
3216 rtx l = gen_reg_rtx (<MODE>mode);
3217 rtx h = gen_reg_rtx (<MODE>mode);
3218 emit_insn (gen_mul<mode>3 (l, operands[1], operands[2]));
3219 emit_insn (gen_<su>mul<mode>3_highpart (h, operands[1], operands[2]));
3220 emit_move_insn (gen_lowpart (<MODE>mode, operands[0]), l);
3221 emit_move_insn (gen_highpart (<MODE>mode, operands[0]), h);
3222 DONE;
3223 })
3224
3225 (define_insn "maddld<mode>4"
3226 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3227 (plus:GPR (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3228 (match_operand:GPR 2 "gpc_reg_operand" "r"))
3229 (match_operand:GPR 3 "gpc_reg_operand" "r")))]
3230 "TARGET_MADDLD"
3231 "maddld %0,%1,%2,%3"
3232 [(set_attr "type" "mul")])
3233
3234 ;; umaddditi4 generally needs maddhdu + maddld + add instructions,
3235 ;; unless last operand is zero extended from DImode, then needs
3236 ;; maddhdu + maddld, which is both faster than mulld + mulhdu + addc + adde
3237 ;; resp. mulld + mulhdu + addc + addze.
3238 ;; We don't define maddditi4, as that one needs
3239 ;; maddhd + sradi + maddld + add + sub and for last operand sign extended
3240 ;; from DImode nothing is able to optimize it into maddhd + maddld, while
3241 ;; without maddditi4 mulld + mulhd + addc + adde or
3242 ;; mulld + mulhd + sradi + addc + adde is needed. See PR108787.
3243 (define_expand "umaddditi4"
3244 [(set (match_operand:TI 0 "gpc_reg_operand")
3245 (plus:TI
3246 (mult:TI (zero_extend:TI (match_operand:DI 1 "gpc_reg_operand"))
3247 (zero_extend:TI (match_operand:DI 2 "gpc_reg_operand")))
3248 (match_operand:TI 3 "gpc_reg_operand")))]
3249 "TARGET_MADDLD && TARGET_POWERPC64"
3250 {
3251 rtx op0_lo = gen_rtx_SUBREG (DImode, operands[0], BYTES_BIG_ENDIAN ? 8 : 0);
3252 rtx op0_hi = gen_rtx_SUBREG (DImode, operands[0], BYTES_BIG_ENDIAN ? 0 : 8);
3253 rtx op3_lo = gen_rtx_SUBREG (DImode, operands[3], BYTES_BIG_ENDIAN ? 8 : 0);
3254 rtx op3_hi = gen_rtx_SUBREG (DImode, operands[3], BYTES_BIG_ENDIAN ? 0 : 8);
3255 rtx hi_temp = gen_reg_rtx (DImode);
3256
3257 if (BYTES_BIG_ENDIAN)
3258 emit_insn (gen_umadddi4_highpart (hi_temp, operands[1], operands[2],
3259 op3_lo));
3260 else
3261 emit_insn (gen_umadddi4_highpart_le (hi_temp, operands[1], operands[2],
3262 op3_lo));
3263
3264 emit_insn (gen_maddlddi4 (op0_lo, operands[1], operands[2], op3_lo));
3265
3266 emit_insn (gen_adddi3 (op0_hi, hi_temp, op3_hi));
3267
3268 DONE;
3269 })
3270
3271 (define_insn "<u>madddi4_highpart"
3272 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3273 (subreg:DI
3274 (plus:TI
3275 (mult:TI (any_extend:TI (match_operand:DI 1 "gpc_reg_operand" "r"))
3276 (any_extend:TI (match_operand:DI 2 "gpc_reg_operand" "r")))
3277 (any_extend:TI (match_operand:DI 3 "gpc_reg_operand" "r")))
3278 0))]
3279 "TARGET_MADDLD && BYTES_BIG_ENDIAN && TARGET_POWERPC64"
3280 "maddhd<u> %0,%1,%2,%3"
3281 [(set_attr "type" "mul")])
3282
3283 (define_insn "<u>madddi4_highpart_le"
3284 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3285 (subreg:DI
3286 (plus:TI
3287 (mult:TI (any_extend:TI (match_operand:DI 1 "gpc_reg_operand" "r"))
3288 (any_extend:TI (match_operand:DI 2 "gpc_reg_operand" "r")))
3289 (any_extend:TI (match_operand:DI 3 "gpc_reg_operand" "r")))
3290 8))]
3291 "TARGET_MADDLD && !BYTES_BIG_ENDIAN && TARGET_POWERPC64"
3292 "maddhd<u> %0,%1,%2,%3"
3293 [(set_attr "type" "mul")])
3294
3295 (define_insn "udiv<mode>3"
3296 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3297 (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3298 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3299 ""
3300 "div<wd>u %0,%1,%2"
3301 [(set_attr "type" "div")
3302 (set_attr "size" "<bits>")])
3303
3304 (define_insn "udivti3"
3305 [(set (match_operand:TI 0 "altivec_register_operand" "=v")
3306 (udiv:TI (match_operand:TI 1 "altivec_register_operand" "v")
3307 (match_operand:TI 2 "altivec_register_operand" "v")))]
3308 "TARGET_POWER10 && TARGET_POWERPC64"
3309 "vdivuq %0,%1,%2"
3310 [(set_attr "type" "vecdiv")
3311 (set_attr "size" "128")])
3312
3313 ;; For powers of two we can do sra[wd]i/addze for divide and then adjust for
3314 ;; modulus. If it isn't a power of two, force operands into register and do
3315 ;; a normal divide.
3316 (define_expand "div<mode>3"
3317 [(set (match_operand:GPR 0 "gpc_reg_operand")
3318 (div:GPR (match_operand:GPR 1 "gpc_reg_operand")
3319 (match_operand:GPR 2 "reg_or_cint_operand")))]
3320 ""
3321 {
3322 if (CONST_INT_P (operands[2])
3323 && INTVAL (operands[2]) > 0
3324 && exact_log2 (INTVAL (operands[2])) >= 0)
3325 {
3326 emit_insn (gen_div<mode>3_sra (operands[0], operands[1], operands[2]));
3327 DONE;
3328 }
3329
3330 operands[2] = force_reg (<MODE>mode, operands[2]);
3331 })
3332
3333 (define_insn "*div<mode>3"
3334 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3335 (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3336 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3337 ""
3338 "div<wd> %0,%1,%2"
3339 [(set_attr "type" "div")
3340 (set_attr "size" "<bits>")])
3341
3342 (define_insn "div<mode>3_sra"
3343 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3344 (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3345 (match_operand:GPR 2 "exact_log2_cint_operand" "N")))
3346 (clobber (reg:GPR CA_REGNO))]
3347 ""
3348 "sra<wd>i %0,%1,%p2\;addze %0,%0"
3349 [(set_attr "type" "two")
3350 (set_attr "length" "8")])
3351
3352 (define_insn_and_split "*div<mode>3_sra_dot"
3353 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3354 (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3355 (match_operand:GPR 2 "exact_log2_cint_operand" "N,N"))
3356 (const_int 0)))
3357 (clobber (match_scratch:GPR 0 "=r,r"))
3358 (clobber (reg:GPR CA_REGNO))]
3359 "<MODE>mode == Pmode"
3360 "@
3361 sra<wd>i %0,%1,%p2\;addze. %0,%0
3362 #"
3363 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3364 [(parallel [(set (match_dup 0)
3365 (div:GPR (match_dup 1)
3366 (match_dup 2)))
3367 (clobber (reg:GPR CA_REGNO))])
3368 (set (match_dup 3)
3369 (compare:CC (match_dup 0)
3370 (const_int 0)))]
3371 ""
3372 [(set_attr "type" "two")
3373 (set_attr "length" "8,12")
3374 (set_attr "cell_micro" "not")])
3375
3376 (define_insn_and_split "*div<mode>3_sra_dot2"
3377 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3378 (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3379 (match_operand:GPR 2 "exact_log2_cint_operand" "N,N"))
3380 (const_int 0)))
3381 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3382 (div:GPR (match_dup 1)
3383 (match_dup 2)))
3384 (clobber (reg:GPR CA_REGNO))]
3385 "<MODE>mode == Pmode"
3386 "@
3387 sra<wd>i %0,%1,%p2\;addze. %0,%0
3388 #"
3389 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3390 [(parallel [(set (match_dup 0)
3391 (div:GPR (match_dup 1)
3392 (match_dup 2)))
3393 (clobber (reg:GPR CA_REGNO))])
3394 (set (match_dup 3)
3395 (compare:CC (match_dup 0)
3396 (const_int 0)))]
3397 ""
3398 [(set_attr "type" "two")
3399 (set_attr "length" "8,12")
3400 (set_attr "cell_micro" "not")])
3401
3402 (define_insn "divti3"
3403 [(set (match_operand:TI 0 "altivec_register_operand" "=v")
3404 (div:TI (match_operand:TI 1 "altivec_register_operand" "v")
3405 (match_operand:TI 2 "altivec_register_operand" "v")))]
3406 "TARGET_POWER10 && TARGET_POWERPC64"
3407 "vdivsq %0,%1,%2"
3408 [(set_attr "type" "vecdiv")
3409 (set_attr "size" "128")])
3410
3411 (define_expand "mod<mode>3"
3412 [(set (match_operand:GPR 0 "gpc_reg_operand")
3413 (mod:GPR (match_operand:GPR 1 "gpc_reg_operand")
3414 (match_operand:GPR 2 "reg_or_cint_operand")))]
3415 ""
3416 {
3417 int i;
3418 rtx temp1;
3419 rtx temp2;
3420
3421 if (!CONST_INT_P (operands[2])
3422 || INTVAL (operands[2]) <= 0
3423 || (i = exact_log2 (INTVAL (operands[2]))) < 0)
3424 {
3425 if (!TARGET_MODULO)
3426 FAIL;
3427
3428 operands[2] = force_reg (<MODE>mode, operands[2]);
3429
3430 if (RS6000_DISABLE_SCALAR_MODULO)
3431 {
3432 temp1 = gen_reg_rtx (<MODE>mode);
3433 temp2 = gen_reg_rtx (<MODE>mode);
3434
3435 emit_insn (gen_div<mode>3 (temp1, operands[1], operands[2]));
3436 emit_insn (gen_mul<mode>3 (temp2, temp1, operands[2]));
3437 emit_insn (gen_sub<mode>3 (operands[0], operands[1], temp2));
3438 DONE;
3439 }
3440 }
3441 else
3442 {
3443 temp1 = gen_reg_rtx (<MODE>mode);
3444 temp2 = gen_reg_rtx (<MODE>mode);
3445
3446 emit_insn (gen_div<mode>3 (temp1, operands[1], operands[2]));
3447 emit_insn (gen_ashl<mode>3 (temp2, temp1, GEN_INT (i)));
3448 emit_insn (gen_sub<mode>3 (operands[0], operands[1], temp2));
3449 DONE;
3450 }
3451 })
3452
3453 ;; In order to enable using a peephole2 for combining div/mod to eliminate the
3454 ;; mod, prefer putting the result of mod into a different register
3455 (define_insn "*mod<mode>3"
3456 [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r,r")
3457 (mod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3458 (match_operand:GPR 2 "gpc_reg_operand" "r,r")))]
3459 "TARGET_MODULO && !RS6000_DISABLE_SCALAR_MODULO"
3460 "mods<wd> %0,%1,%2"
3461 [(set_attr "type" "div")
3462 (set_attr "size" "<bits>")])
3463
3464 ;; This define_expand can be removed when RS6000_DISABLE_SCALAR_MODULO is
3465 ;; removed.
3466 (define_expand "umod<mode>3"
3467 [(set (match_operand:GPR 0 "gpc_reg_operand")
3468 (umod:GPR (match_operand:GPR 1 "gpc_reg_operand")
3469 (match_operand:GPR 2 "gpc_reg_operand")))]
3470 "TARGET_MODULO"
3471 {
3472 if (RS6000_DISABLE_SCALAR_MODULO)
3473 {
3474 rtx temp1 = gen_reg_rtx (<MODE>mode);
3475 rtx temp2 = gen_reg_rtx (<MODE>mode);
3476
3477 emit_insn (gen_udiv<mode>3 (temp1, operands[1], operands[2]));
3478 emit_insn (gen_mul<mode>3 (temp2, temp1, operands[2]));
3479 emit_insn (gen_sub<mode>3 (operands[0], operands[1], temp2));
3480 DONE;
3481 }
3482 })
3483
3484 (define_insn "*umod<mode>3"
3485 [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r,r")
3486 (umod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3487 (match_operand:GPR 2 "gpc_reg_operand" "r,r")))]
3488 "TARGET_MODULO && !RS6000_DISABLE_SCALAR_MODULO"
3489 "modu<wd> %0,%1,%2"
3490 [(set_attr "type" "div")
3491 (set_attr "size" "<bits>")])
3492
3493 ;; On machines with modulo support, do a combined div/mod the old fashioned
3494 ;; method, since the multiply/subtract is faster than doing the mod instruction
3495 ;; after a divide.
3496
3497 (define_peephole2
3498 [(set (match_operand:GPR 0 "gpc_reg_operand")
3499 (div:GPR (match_operand:GPR 1 "gpc_reg_operand")
3500 (match_operand:GPR 2 "gpc_reg_operand")))
3501 (set (match_operand:GPR 3 "gpc_reg_operand")
3502 (mod:GPR (match_dup 1)
3503 (match_dup 2)))]
3504 "TARGET_MODULO
3505 && ! reg_mentioned_p (operands[0], operands[1])
3506 && ! reg_mentioned_p (operands[0], operands[2])
3507 && ! reg_mentioned_p (operands[3], operands[1])
3508 && ! reg_mentioned_p (operands[3], operands[2])"
3509 [(set (match_dup 0)
3510 (div:GPR (match_dup 1)
3511 (match_dup 2)))
3512 (set (match_dup 3)
3513 (mult:GPR (match_dup 0)
3514 (match_dup 2)))
3515 (set (match_dup 3)
3516 (minus:GPR (match_dup 1)
3517 (match_dup 3)))])
3518
3519 (define_peephole2
3520 [(set (match_operand:GPR 0 "gpc_reg_operand")
3521 (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand")
3522 (match_operand:GPR 2 "gpc_reg_operand")))
3523 (set (match_operand:GPR 3 "gpc_reg_operand")
3524 (umod:GPR (match_dup 1)
3525 (match_dup 2)))]
3526 "TARGET_MODULO
3527 && ! reg_mentioned_p (operands[0], operands[1])
3528 && ! reg_mentioned_p (operands[0], operands[2])
3529 && ! reg_mentioned_p (operands[3], operands[1])
3530 && ! reg_mentioned_p (operands[3], operands[2])"
3531 [(set (match_dup 0)
3532 (udiv:GPR (match_dup 1)
3533 (match_dup 2)))
3534 (set (match_dup 3)
3535 (mult:GPR (match_dup 0)
3536 (match_dup 2)))
3537 (set (match_dup 3)
3538 (minus:GPR (match_dup 1)
3539 (match_dup 3)))])
3540
3541 (define_insn "umodti3"
3542 [(set (match_operand:TI 0 "altivec_register_operand" "=v")
3543 (umod:TI (match_operand:TI 1 "altivec_register_operand" "v")
3544 (match_operand:TI 2 "altivec_register_operand" "v")))]
3545 "TARGET_POWER10 && TARGET_POWERPC64 && !RS6000_DISABLE_SCALAR_MODULO"
3546 "vmoduq %0,%1,%2"
3547 [(set_attr "type" "vecdiv")
3548 (set_attr "size" "128")])
3549
3550 (define_insn "modti3"
3551 [(set (match_operand:TI 0 "altivec_register_operand" "=v")
3552 (mod:TI (match_operand:TI 1 "altivec_register_operand" "v")
3553 (match_operand:TI 2 "altivec_register_operand" "v")))]
3554 "TARGET_POWER10 && TARGET_POWERPC64 && !RS6000_DISABLE_SCALAR_MODULO"
3555 "vmodsq %0,%1,%2"
3556 [(set_attr "type" "vecdiv")
3557 (set_attr "size" "128")])
3558 \f
3559 ;; Logical instructions
3560 ;; The logical instructions are mostly combined by using match_operator,
3561 ;; but the plain AND insns are somewhat different because there is no
3562 ;; plain 'andi' (only 'andi.'), no plain 'andis', and there are all
3563 ;; those rotate-and-mask operations. Thus, the AND insns come first.
3564
3565 (define_expand "and<mode>3"
3566 [(set (match_operand:SDI 0 "gpc_reg_operand")
3567 (and:SDI (match_operand:SDI 1 "gpc_reg_operand")
3568 (match_operand:SDI 2 "reg_or_cint_operand")))]
3569 ""
3570 {
3571 if (<MODE>mode == DImode && !TARGET_POWERPC64)
3572 {
3573 rs6000_split_logical (operands, AND, false, false, false);
3574 DONE;
3575 }
3576
3577 if (CONST_INT_P (operands[2]))
3578 {
3579 if (rs6000_is_valid_and_mask (operands[2], <MODE>mode))
3580 {
3581 emit_insn (gen_and<mode>3_mask (operands[0], operands[1], operands[2]));
3582 DONE;
3583 }
3584
3585 if (logical_const_operand (operands[2], <MODE>mode))
3586 {
3587 emit_insn (gen_and<mode>3_imm (operands[0], operands[1], operands[2]));
3588 DONE;
3589 }
3590
3591 if (rs6000_is_valid_2insn_and (operands[2], <MODE>mode))
3592 {
3593 rs6000_emit_2insn_and (<MODE>mode, operands, true, 0);
3594 DONE;
3595 }
3596
3597 operands[2] = force_reg (<MODE>mode, operands[2]);
3598 }
3599 })
3600
3601
3602 (define_insn "and<mode>3_imm"
3603 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3604 (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3605 (match_operand:GPR 2 "logical_const_operand" "n")))
3606 (clobber (match_scratch:CC 3 "=x"))]
3607 "!rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3608 "andi%e2. %0,%1,%u2"
3609 [(set_attr "type" "logical")
3610 (set_attr "dot" "yes")])
3611
3612 (define_insn_and_split "*and<mode>3_imm_dot"
3613 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3614 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3615 (match_operand:GPR 2 "logical_const_operand" "n,n"))
3616 (const_int 0)))
3617 (clobber (match_scratch:GPR 0 "=r,r"))
3618 (clobber (match_scratch:CC 4 "=X,x"))]
3619 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3620 && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3621 "@
3622 andi%e2. %0,%1,%u2
3623 #"
3624 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3625 [(parallel [(set (match_dup 0)
3626 (and:GPR (match_dup 1)
3627 (match_dup 2)))
3628 (clobber (match_dup 4))])
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_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 (clobber (match_scratch:CC 4 "=X,x"))]
3646 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3647 && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3648 "@
3649 andi%e2. %0,%1,%u2
3650 #"
3651 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3652 [(parallel [(set (match_dup 0)
3653 (and:GPR (match_dup 1)
3654 (match_dup 2)))
3655 (clobber (match_dup 4))])
3656 (set (match_dup 3)
3657 (compare:CC (match_dup 0)
3658 (const_int 0)))]
3659 ""
3660 [(set_attr "type" "logical")
3661 (set_attr "dot" "yes")
3662 (set_attr "length" "4,8")])
3663
3664 (define_insn_and_split "*and<mode>3_imm_mask_dot"
3665 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3666 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3667 (match_operand:GPR 2 "logical_const_operand" "n,n"))
3668 (const_int 0)))
3669 (clobber (match_scratch:GPR 0 "=r,r"))]
3670 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3671 && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3672 "@
3673 andi%e2. %0,%1,%u2
3674 #"
3675 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3676 [(set (match_dup 0)
3677 (and:GPR (match_dup 1)
3678 (match_dup 2)))
3679 (set (match_dup 3)
3680 (compare:CC (match_dup 0)
3681 (const_int 0)))]
3682 ""
3683 [(set_attr "type" "logical")
3684 (set_attr "dot" "yes")
3685 (set_attr "length" "4,8")])
3686
3687 (define_insn_and_split "*and<mode>3_imm_mask_dot2"
3688 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3689 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3690 (match_operand:GPR 2 "logical_const_operand" "n,n"))
3691 (const_int 0)))
3692 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3693 (and:GPR (match_dup 1)
3694 (match_dup 2)))]
3695 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3696 && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3697 "@
3698 andi%e2. %0,%1,%u2
3699 #"
3700 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3701 [(set (match_dup 0)
3702 (and:GPR (match_dup 1)
3703 (match_dup 2)))
3704 (set (match_dup 3)
3705 (compare:CC (match_dup 0)
3706 (const_int 0)))]
3707 ""
3708 [(set_attr "type" "logical")
3709 (set_attr "dot" "yes")
3710 (set_attr "length" "4,8")])
3711
3712 (define_insn "*and<mode>3_imm_dot_shifted"
3713 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
3714 (compare:CC
3715 (and:GPR
3716 (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3717 (match_operand:SI 4 "const_int_operand" "n"))
3718 (match_operand:GPR 2 "const_int_operand" "n"))
3719 (const_int 0)))
3720 (clobber (match_scratch:GPR 0 "=r"))]
3721 "logical_const_operand (GEN_INT (UINTVAL (operands[2])
3722 << INTVAL (operands[4])),
3723 DImode)
3724 && (<MODE>mode == Pmode
3725 || (UINTVAL (operands[2]) << INTVAL (operands[4])) <= 0x7fffffff)"
3726 {
3727 operands[2] = GEN_INT (UINTVAL (operands[2]) << INTVAL (operands[4]));
3728 return "andi%e2. %0,%1,%u2";
3729 }
3730 [(set_attr "type" "logical")
3731 (set_attr "dot" "yes")])
3732
3733
3734 (define_insn "and<mode>3_mask"
3735 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3736 (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3737 (match_operand:GPR 2 "const_int_operand" "n")))]
3738 "rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3739 {
3740 return rs6000_insn_for_and_mask (<MODE>mode, operands, false);
3741 }
3742 [(set_attr "type" "shift")])
3743
3744 (define_insn_and_split "*and<mode>3_mask_dot"
3745 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3746 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3747 (match_operand:GPR 2 "const_int_operand" "n,n"))
3748 (const_int 0)))
3749 (clobber (match_scratch:GPR 0 "=r,r"))]
3750 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3751 && !logical_const_operand (operands[2], <MODE>mode)
3752 && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3753 {
3754 if (which_alternative == 0)
3755 return rs6000_insn_for_and_mask (<MODE>mode, operands, true);
3756 else
3757 return "#";
3758 }
3759 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3760 [(set (match_dup 0)
3761 (and:GPR (match_dup 1)
3762 (match_dup 2)))
3763 (set (match_dup 3)
3764 (compare:CC (match_dup 0)
3765 (const_int 0)))]
3766 ""
3767 [(set_attr "type" "shift")
3768 (set_attr "dot" "yes")
3769 (set_attr "length" "4,8")])
3770
3771 (define_insn_and_split "*and<mode>3_mask_dot2"
3772 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3773 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3774 (match_operand:GPR 2 "const_int_operand" "n,n"))
3775 (const_int 0)))
3776 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3777 (and:GPR (match_dup 1)
3778 (match_dup 2)))]
3779 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3780 && !logical_const_operand (operands[2], <MODE>mode)
3781 && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3782 {
3783 if (which_alternative == 0)
3784 return rs6000_insn_for_and_mask (<MODE>mode, operands, true);
3785 else
3786 return "#";
3787 }
3788 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3789 [(set (match_dup 0)
3790 (and:GPR (match_dup 1)
3791 (match_dup 2)))
3792 (set (match_dup 3)
3793 (compare:CC (match_dup 0)
3794 (const_int 0)))]
3795 ""
3796 [(set_attr "type" "shift")
3797 (set_attr "dot" "yes")
3798 (set_attr "length" "4,8")])
3799
3800
3801 (define_insn_and_split "*and<mode>3_2insn"
3802 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3803 (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3804 (match_operand:GPR 2 "const_int_operand" "n")))]
3805 "rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3806 && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3807 || logical_const_operand (operands[2], <MODE>mode))"
3808 "#"
3809 "&& 1"
3810 [(pc)]
3811 {
3812 rs6000_emit_2insn_and (<MODE>mode, operands, false, 0);
3813 DONE;
3814 }
3815 [(set_attr "type" "shift")
3816 (set_attr "length" "8")])
3817
3818 (define_insn_and_split "*and<mode>3_2insn_dot"
3819 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3820 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3821 (match_operand:GPR 2 "const_int_operand" "n,n"))
3822 (const_int 0)))
3823 (clobber (match_scratch:GPR 0 "=r,r"))]
3824 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3825 && rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3826 && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3827 || logical_const_operand (operands[2], <MODE>mode))"
3828 "#"
3829 "&& reload_completed"
3830 [(pc)]
3831 {
3832 rs6000_emit_2insn_and (<MODE>mode, operands, false, 1);
3833 DONE;
3834 }
3835 [(set_attr "type" "shift")
3836 (set_attr "dot" "yes")
3837 (set_attr "length" "8,12")])
3838
3839 (define_insn_and_split "*and<mode>3_2insn_dot2"
3840 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3841 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3842 (match_operand:GPR 2 "const_int_operand" "n,n"))
3843 (const_int 0)))
3844 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3845 (and:GPR (match_dup 1)
3846 (match_dup 2)))]
3847 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3848 && rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3849 && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3850 || logical_const_operand (operands[2], <MODE>mode))"
3851 "#"
3852 "&& reload_completed"
3853 [(pc)]
3854 {
3855 rs6000_emit_2insn_and (<MODE>mode, operands, false, 2);
3856 DONE;
3857 }
3858 [(set_attr "type" "shift")
3859 (set_attr "dot" "yes")
3860 (set_attr "length" "8,12")])
3861
3862 (define_insn_and_split "*branch_anddi3_dot"
3863 [(set (pc)
3864 (if_then_else (eq (and:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r")
3865 (match_operand:DI 2 "const_int_operand" "n,n"))
3866 (const_int 0))
3867 (label_ref (match_operand 3 ""))
3868 (pc)))
3869 (clobber (match_scratch:DI 0 "=r,r"))
3870 (clobber (reg:CC CR0_REGNO))]
3871 "rs6000_is_valid_rotate_dot_mask (operands[2], DImode)
3872 && TARGET_POWERPC64"
3873 "#"
3874 "&& reload_completed"
3875 [(pc)]
3876 {
3877 int nb, ne;
3878 if (rs6000_is_valid_mask (operands[2], &nb, &ne, DImode)
3879 && nb >= ne
3880 && ne > 0)
3881 {
3882 unsigned HOST_WIDE_INT val = INTVAL (operands[2]);
3883 int shift = 63 - nb;
3884 rtx tmp = gen_rtx_ASHIFT (DImode, operands[1], GEN_INT (shift));
3885 tmp = gen_rtx_AND (DImode, tmp, GEN_INT (val << shift));
3886 rtx cr0 = gen_rtx_REG (CCmode, CR0_REGNO);
3887 rs6000_emit_dot_insn (operands[0], tmp, 1, cr0);
3888 rtx loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands[3]);
3889 rtx cond = gen_rtx_EQ (CCEQmode, cr0, const0_rtx);
3890 rtx ite = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, loc_ref, pc_rtx);
3891 emit_jump_insn (gen_rtx_SET (pc_rtx, ite));
3892 DONE;
3893 }
3894 else
3895 FAIL;
3896 }
3897 [(set_attr "type" "shift")
3898 (set_attr "dot" "yes")
3899 (set_attr "length" "8,12")])
3900
3901 (define_expand "<code><mode>3"
3902 [(set (match_operand:SDI 0 "gpc_reg_operand")
3903 (iorxor:SDI (match_operand:SDI 1 "gpc_reg_operand")
3904 (match_operand:SDI 2 "reg_or_cint_operand")))]
3905 ""
3906 {
3907 if (<MODE>mode == DImode && !TARGET_POWERPC64)
3908 {
3909 rs6000_split_logical (operands, <CODE>, false, false, false);
3910 DONE;
3911 }
3912
3913 if (non_logical_cint_operand (operands[2], <MODE>mode))
3914 {
3915 rtx tmp = ((!can_create_pseudo_p ()
3916 || rtx_equal_p (operands[0], operands[1]))
3917 ? operands[0] : gen_reg_rtx (<MODE>mode));
3918
3919 HOST_WIDE_INT value = INTVAL (operands[2]);
3920 HOST_WIDE_INT lo = value & 0xffff;
3921 HOST_WIDE_INT hi = value - lo;
3922
3923 emit_insn (gen_<code><mode>3 (tmp, operands[1], GEN_INT (hi)));
3924 emit_insn (gen_<code><mode>3 (operands[0], tmp, GEN_INT (lo)));
3925 DONE;
3926 }
3927
3928 if (!reg_or_logical_cint_operand (operands[2], <MODE>mode))
3929 operands[2] = force_reg (<MODE>mode, operands[2]);
3930 })
3931
3932 (define_split
3933 [(set (match_operand:GPR 0 "gpc_reg_operand")
3934 (iorxor:GPR (match_operand:GPR 1 "gpc_reg_operand")
3935 (match_operand:GPR 2 "non_logical_cint_operand")))]
3936 ""
3937 [(set (match_dup 3)
3938 (iorxor:GPR (match_dup 1)
3939 (match_dup 4)))
3940 (set (match_dup 0)
3941 (iorxor:GPR (match_dup 3)
3942 (match_dup 5)))]
3943 {
3944 operands[3] = ((!can_create_pseudo_p ()
3945 || rtx_equal_p (operands[0], operands[1]))
3946 ? operands[0] : gen_reg_rtx (<MODE>mode));
3947
3948 HOST_WIDE_INT value = INTVAL (operands[2]);
3949 HOST_WIDE_INT lo = value & 0xffff;
3950 HOST_WIDE_INT hi = value - lo;
3951
3952 operands[4] = GEN_INT (hi);
3953 operands[5] = GEN_INT (lo);
3954 })
3955
3956 (define_insn "*bool<mode>3_imm"
3957 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3958 (match_operator:GPR 3 "boolean_or_operator"
3959 [(match_operand:GPR 1 "gpc_reg_operand" "%r")
3960 (match_operand:GPR 2 "logical_const_operand" "n")]))]
3961 ""
3962 "%q3i%e2 %0,%1,%u2"
3963 [(set_attr "type" "logical")])
3964
3965 (define_insn "*bool<mode>3"
3966 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3967 (match_operator:GPR 3 "boolean_operator"
3968 [(match_operand:GPR 1 "gpc_reg_operand" "r")
3969 (match_operand:GPR 2 "gpc_reg_operand" "r")]))]
3970 ""
3971 "%q3 %0,%1,%2"
3972 [(set_attr "type" "logical")])
3973
3974 (define_insn_and_split "*bool<mode>3_dot"
3975 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3976 (compare:CC (match_operator:GPR 3 "boolean_operator"
3977 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3978 (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
3979 (const_int 0)))
3980 (clobber (match_scratch:GPR 0 "=r,r"))]
3981 "<MODE>mode == Pmode"
3982 "@
3983 %q3. %0,%1,%2
3984 #"
3985 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3986 [(set (match_dup 0)
3987 (match_dup 3))
3988 (set (match_dup 4)
3989 (compare:CC (match_dup 0)
3990 (const_int 0)))]
3991 ""
3992 [(set_attr "type" "logical")
3993 (set_attr "dot" "yes")
3994 (set_attr "length" "4,8")])
3995
3996 (define_insn_and_split "*bool<mode>3_dot2"
3997 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3998 (compare:CC (match_operator:GPR 3 "boolean_operator"
3999 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
4000 (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
4001 (const_int 0)))
4002 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4003 (match_dup 3))]
4004 "<MODE>mode == Pmode"
4005 "@
4006 %q3. %0,%1,%2
4007 #"
4008 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
4009 [(set (match_dup 0)
4010 (match_dup 3))
4011 (set (match_dup 4)
4012 (compare:CC (match_dup 0)
4013 (const_int 0)))]
4014 ""
4015 [(set_attr "type" "logical")
4016 (set_attr "dot" "yes")
4017 (set_attr "length" "4,8")])
4018
4019
4020 (define_insn "*boolc<mode>3"
4021 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4022 (match_operator:GPR 3 "boolean_operator"
4023 [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))
4024 (match_operand:GPR 1 "gpc_reg_operand" "r")]))]
4025 ""
4026 "%q3 %0,%1,%2"
4027 [(set_attr "type" "logical")])
4028
4029 (define_insn_and_split "*boolc<mode>3_dot"
4030 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
4031 (compare:CC (match_operator:GPR 3 "boolean_operator"
4032 [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
4033 (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
4034 (const_int 0)))
4035 (clobber (match_scratch:GPR 0 "=r,r"))]
4036 "<MODE>mode == Pmode"
4037 "@
4038 %q3. %0,%1,%2
4039 #"
4040 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
4041 [(set (match_dup 0)
4042 (match_dup 3))
4043 (set (match_dup 4)
4044 (compare:CC (match_dup 0)
4045 (const_int 0)))]
4046 ""
4047 [(set_attr "type" "logical")
4048 (set_attr "dot" "yes")
4049 (set_attr "length" "4,8")])
4050
4051 (define_insn_and_split "*boolc<mode>3_dot2"
4052 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
4053 (compare:CC (match_operator:GPR 3 "boolean_operator"
4054 [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
4055 (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
4056 (const_int 0)))
4057 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4058 (match_dup 3))]
4059 "<MODE>mode == Pmode"
4060 "@
4061 %q3. %0,%1,%2
4062 #"
4063 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
4064 [(set (match_dup 0)
4065 (match_dup 3))
4066 (set (match_dup 4)
4067 (compare:CC (match_dup 0)
4068 (const_int 0)))]
4069 ""
4070 [(set_attr "type" "logical")
4071 (set_attr "dot" "yes")
4072 (set_attr "length" "4,8")])
4073
4074
4075 (define_insn "*boolcc<mode>3"
4076 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4077 (match_operator:GPR 3 "boolean_operator"
4078 [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
4079 (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))]))]
4080 ""
4081 "%q3 %0,%1,%2"
4082 [(set_attr "type" "logical")])
4083
4084 (define_insn_and_split "*boolcc<mode>3_dot"
4085 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
4086 (compare:CC (match_operator:GPR 3 "boolean_operator"
4087 [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
4088 (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
4089 (const_int 0)))
4090 (clobber (match_scratch:GPR 0 "=r,r"))]
4091 "<MODE>mode == Pmode"
4092 "@
4093 %q3. %0,%1,%2
4094 #"
4095 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
4096 [(set (match_dup 0)
4097 (match_dup 3))
4098 (set (match_dup 4)
4099 (compare:CC (match_dup 0)
4100 (const_int 0)))]
4101 ""
4102 [(set_attr "type" "logical")
4103 (set_attr "dot" "yes")
4104 (set_attr "length" "4,8")])
4105
4106 (define_insn_and_split "*boolcc<mode>3_dot2"
4107 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
4108 (compare:CC (match_operator:GPR 3 "boolean_operator"
4109 [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
4110 (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
4111 (const_int 0)))
4112 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4113 (match_dup 3))]
4114 "<MODE>mode == Pmode"
4115 "@
4116 %q3. %0,%1,%2
4117 #"
4118 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
4119 [(set (match_dup 0)
4120 (match_dup 3))
4121 (set (match_dup 4)
4122 (compare:CC (match_dup 0)
4123 (const_int 0)))]
4124 ""
4125 [(set_attr "type" "logical")
4126 (set_attr "dot" "yes")
4127 (set_attr "length" "4,8")])
4128
4129
4130 ;; TODO: Should have dots of this as well.
4131 (define_insn "*eqv<mode>3"
4132 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4133 (not:GPR (xor:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4134 (match_operand:GPR 2 "gpc_reg_operand" "r"))))]
4135 ""
4136 "eqv %0,%1,%2"
4137 [(set_attr "type" "logical")])
4138 \f
4139 ;; Rotate-and-mask and insert.
4140
4141 (define_insn "*rotl<mode>3_mask"
4142 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4143 (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
4144 [(match_operand:GPR 1 "gpc_reg_operand" "r")
4145 (match_operand:SI 2 "reg_or_cint_operand" "rn")])
4146 (match_operand:GPR 3 "const_int_operand" "n")))]
4147 "rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
4148 {
4149 return rs6000_insn_for_shift_mask (<MODE>mode, operands, false);
4150 }
4151 [(set_attr "type" "shift")
4152 (set_attr "maybe_var_shift" "yes")])
4153
4154 (define_insn_and_split "*rotl<mode>3_mask_dot"
4155 [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y")
4156 (compare:CC
4157 (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
4158 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
4159 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")])
4160 (match_operand:GPR 3 "const_int_operand" "n,n"))
4161 (const_int 0)))
4162 (clobber (match_scratch:GPR 0 "=r,r"))]
4163 "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff)
4164 && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
4165 {
4166 if (which_alternative == 0)
4167 return rs6000_insn_for_shift_mask (<MODE>mode, operands, true);
4168 else
4169 return "#";
4170 }
4171 "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)"
4172 [(set (match_dup 0)
4173 (and:GPR (match_dup 4)
4174 (match_dup 3)))
4175 (set (match_dup 5)
4176 (compare:CC (match_dup 0)
4177 (const_int 0)))]
4178 ""
4179 [(set_attr "type" "shift")
4180 (set_attr "maybe_var_shift" "yes")
4181 (set_attr "dot" "yes")
4182 (set_attr "length" "4,8")])
4183
4184 (define_insn_and_split "*rotl<mode>3_mask_dot2"
4185 [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y")
4186 (compare:CC
4187 (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
4188 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
4189 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")])
4190 (match_operand:GPR 3 "const_int_operand" "n,n"))
4191 (const_int 0)))
4192 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4193 (and:GPR (match_dup 4)
4194 (match_dup 3)))]
4195 "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff)
4196 && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
4197 {
4198 if (which_alternative == 0)
4199 return rs6000_insn_for_shift_mask (<MODE>mode, operands, true);
4200 else
4201 return "#";
4202 }
4203 "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)"
4204 [(set (match_dup 0)
4205 (and:GPR (match_dup 4)
4206 (match_dup 3)))
4207 (set (match_dup 5)
4208 (compare:CC (match_dup 0)
4209 (const_int 0)))]
4210 ""
4211 [(set_attr "type" "shift")
4212 (set_attr "maybe_var_shift" "yes")
4213 (set_attr "dot" "yes")
4214 (set_attr "length" "4,8")])
4215
4216 ; Special case for less-than-0. We can do it with just one machine
4217 ; instruction, but the generic optimizers do not realise it is cheap.
4218 (define_insn "*lt0_<mode>di"
4219 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4220 (lt:GPR (match_operand:DI 1 "gpc_reg_operand" "r")
4221 (const_int 0)))]
4222 "TARGET_POWERPC64"
4223 "srdi %0,%1,63"
4224 [(set_attr "type" "shift")])
4225
4226 (define_insn "*lt0_<mode>si"
4227 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4228 (lt:GPR (match_operand:SI 1 "gpc_reg_operand" "r")
4229 (const_int 0)))]
4230 ""
4231 "rlwinm %0,%1,1,31,31"
4232 [(set_attr "type" "shift")])
4233
4234
4235
4236 ; Two forms for insert (the two arms of the IOR are not canonicalized,
4237 ; both are an AND so are the same precedence).
4238 (define_insn "*rotl<mode>3_insert"
4239 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4240 (ior:GPR (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
4241 [(match_operand:GPR 1 "gpc_reg_operand" "r")
4242 (match_operand:SI 2 "const_int_operand" "n")])
4243 (match_operand:GPR 3 "const_int_operand" "n"))
4244 (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0")
4245 (match_operand:GPR 6 "const_int_operand" "n"))))]
4246 "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode)
4247 && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0"
4248 {
4249 return rs6000_insn_for_insert_mask (<MODE>mode, operands, false);
4250 }
4251 [(set_attr "type" "insert")])
4252 ; FIXME: this needs an attr "size", so that the scheduler can see the
4253 ; difference between rlwimi and rldimi. We also might want dot forms,
4254 ; but not for rlwimi on POWER4 and similar processors.
4255
4256 (define_insn "*rotl<mode>3_insert_2"
4257 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4258 (ior:GPR (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0")
4259 (match_operand:GPR 6 "const_int_operand" "n"))
4260 (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
4261 [(match_operand:GPR 1 "gpc_reg_operand" "r")
4262 (match_operand:SI 2 "const_int_operand" "n")])
4263 (match_operand:GPR 3 "const_int_operand" "n"))))]
4264 "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode)
4265 && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0"
4266 {
4267 return rs6000_insn_for_insert_mask (<MODE>mode, operands, false);
4268 }
4269 [(set_attr "type" "insert")])
4270
4271 ; There are also some forms without one of the ANDs.
4272 (define_insn "rotl<mode>3_insert_3"
4273 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4274 (ior:GPR (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0")
4275 (match_operand:GPR 4 "const_int_operand" "n"))
4276 (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4277 (match_operand:SI 2 "const_int_operand" "n"))))]
4278 "INTVAL (operands[2]) > 0
4279 && INTVAL (operands[2]) == exact_log2 (UINTVAL (operands[4]) + 1)"
4280 {
4281 if (<MODE>mode == SImode)
4282 return "rlwimi %0,%1,%h2,0,31-%h2";
4283 else
4284 return "rldimi %0,%1,%H2,0";
4285 }
4286 [(set_attr "type" "insert")])
4287
4288 ; Canonicalize the PLUS and XOR forms to IOR for rotl<mode>3_insert_3
4289 (define_code_iterator plus_xor [plus xor])
4290
4291 (define_insn_and_split "*rotl<mode>3_insert_3_<code>"
4292 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4293 (plus_xor:GPR
4294 (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0")
4295 (match_operand:GPR 4 "const_int_operand" "n"))
4296 (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4297 (match_operand:SI 2 "const_int_operand" "n"))))]
4298 "INTVAL (operands[2]) > 0
4299 && INTVAL (operands[2]) == exact_log2 (UINTVAL (operands[4]) + 1)"
4300 "#"
4301 "&& 1"
4302 [(set (match_dup 0)
4303 (ior:GPR (and:GPR (match_dup 3) (match_dup 4))
4304 (ashift:GPR (match_dup 1) (match_dup 2))))])
4305
4306 (define_code_iterator plus_ior_xor [plus ior xor])
4307
4308 (define_split
4309 [(set (match_operand:GPR 0 "gpc_reg_operand")
4310 (plus_ior_xor:GPR (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand")
4311 (match_operand:SI 2 "const_int_operand"))
4312 (match_operand:GPR 3 "gpc_reg_operand")))]
4313 "nonzero_bits (operands[3], <MODE>mode)
4314 < HOST_WIDE_INT_1U << INTVAL (operands[2])"
4315 [(set (match_dup 0)
4316 (ior:GPR (and:GPR (match_dup 3)
4317 (match_dup 4))
4318 (ashift:GPR (match_dup 1)
4319 (match_dup 2))))]
4320 {
4321 operands[4] = GEN_INT ((HOST_WIDE_INT_1U << INTVAL (operands[2])) - 1);
4322 })
4323
4324 (define_insn "*rotlsi3_insert_4"
4325 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
4326 (ior:SI (and:SI (match_operand:SI 3 "gpc_reg_operand" "0")
4327 (match_operand:SI 4 "const_int_operand" "n"))
4328 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4329 (match_operand:SI 2 "const_int_operand" "n"))))]
4330 "INTVAL (operands[2]) + exact_log2 (-UINTVAL (operands[4])) == 32"
4331 "rlwimi %0,%1,32-%h2,%h2,31"
4332 [(set_attr "type" "insert")])
4333
4334 (define_insn "*rotlsi3_insert_5"
4335 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
4336 (ior:SI (and:SI (match_operand:SI 1 "gpc_reg_operand" "0,r")
4337 (match_operand:SI 2 "const_int_operand" "n,n"))
4338 (and:SI (match_operand:SI 3 "gpc_reg_operand" "r,0")
4339 (match_operand:SI 4 "const_int_operand" "n,n"))))]
4340 "rs6000_is_valid_mask (operands[2], NULL, NULL, SImode)
4341 && UINTVAL (operands[2]) != 0 && UINTVAL (operands[4]) != 0
4342 && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
4343 "@
4344 rlwimi %0,%3,0,%4
4345 rlwimi %0,%1,0,%2"
4346 [(set_attr "type" "insert")])
4347
4348 (define_insn "*rotldi3_insert_6"
4349 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4350 (ior:DI (and:DI (match_operand:DI 1 "gpc_reg_operand" "0")
4351 (match_operand:DI 2 "const_int_operand" "n"))
4352 (and:DI (match_operand:DI 3 "gpc_reg_operand" "r")
4353 (match_operand:DI 4 "const_int_operand" "n"))))]
4354 "exact_log2 (-UINTVAL (operands[2])) > 0
4355 && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
4356 {
4357 operands[5] = GEN_INT (64 - exact_log2 (-UINTVAL (operands[2])));
4358 return "rldimi %0,%3,0,%5";
4359 }
4360 [(set_attr "type" "insert")
4361 (set_attr "size" "64")])
4362
4363 (define_insn "*rotldi3_insert_7"
4364 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4365 (ior:DI (and:DI (match_operand:DI 3 "gpc_reg_operand" "r")
4366 (match_operand:DI 4 "const_int_operand" "n"))
4367 (and:DI (match_operand:DI 1 "gpc_reg_operand" "0")
4368 (match_operand:DI 2 "const_int_operand" "n"))))]
4369 "exact_log2 (-UINTVAL (operands[2])) > 0
4370 && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
4371 {
4372 operands[5] = GEN_INT (64 - exact_log2 (-UINTVAL (operands[2])));
4373 return "rldimi %0,%3,0,%5";
4374 }
4375 [(set_attr "type" "insert")
4376 (set_attr "size" "64")])
4377
4378
4379 ; This handles the important case of multiple-precision shifts. There is
4380 ; no canonicalization rule for ASHIFT vs. LSHIFTRT, so two patterns.
4381 (define_split
4382 [(set (match_operand:GPR 0 "gpc_reg_operand")
4383 (ior:GPR (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand")
4384 (match_operand:SI 3 "const_int_operand"))
4385 (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand")
4386 (match_operand:SI 4 "const_int_operand"))))]
4387 "can_create_pseudo_p ()
4388 && INTVAL (operands[3]) + INTVAL (operands[4])
4389 >= GET_MODE_PRECISION (<MODE>mode)"
4390 [(set (match_dup 5)
4391 (lshiftrt:GPR (match_dup 2)
4392 (match_dup 4)))
4393 (set (match_dup 0)
4394 (ior:GPR (and:GPR (match_dup 5)
4395 (match_dup 6))
4396 (ashift:GPR (match_dup 1)
4397 (match_dup 3))))]
4398 {
4399 unsigned HOST_WIDE_INT mask = 1;
4400 mask = (mask << INTVAL (operands[3])) - 1;
4401 operands[5] = gen_reg_rtx (<MODE>mode);
4402 operands[6] = GEN_INT (mask);
4403 })
4404
4405 (define_split
4406 [(set (match_operand:GPR 0 "gpc_reg_operand")
4407 (ior:GPR (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand")
4408 (match_operand:SI 4 "const_int_operand"))
4409 (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand")
4410 (match_operand:SI 3 "const_int_operand"))))]
4411 "can_create_pseudo_p ()
4412 && INTVAL (operands[3]) + INTVAL (operands[4])
4413 >= GET_MODE_PRECISION (<MODE>mode)"
4414 [(set (match_dup 5)
4415 (lshiftrt:GPR (match_dup 2)
4416 (match_dup 4)))
4417 (set (match_dup 0)
4418 (ior:GPR (and:GPR (match_dup 5)
4419 (match_dup 6))
4420 (ashift:GPR (match_dup 1)
4421 (match_dup 3))))]
4422 {
4423 unsigned HOST_WIDE_INT mask = 1;
4424 mask = (mask << INTVAL (operands[3])) - 1;
4425 operands[5] = gen_reg_rtx (<MODE>mode);
4426 operands[6] = GEN_INT (mask);
4427 })
4428
4429
4430 ; Another important case is setting some bits to 1; we can do that with
4431 ; an insert instruction, in many cases.
4432 (define_insn_and_split "*ior<mode>_mask"
4433 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4434 (ior:GPR (match_operand:GPR 1 "gpc_reg_operand" "0")
4435 (match_operand:GPR 2 "const_int_operand" "n")))
4436 (clobber (match_scratch:GPR 3 "=r"))]
4437 "!logical_const_operand (operands[2], <MODE>mode)
4438 && rs6000_is_valid_mask (operands[2], NULL, NULL, <MODE>mode)"
4439 "#"
4440 "&& 1"
4441 [(set (match_dup 3)
4442 (const_int -1))
4443 (set (match_dup 0)
4444 (ior:GPR (and:GPR (rotate:GPR (match_dup 3)
4445 (match_dup 4))
4446 (match_dup 2))
4447 (and:GPR (match_dup 1)
4448 (match_dup 5))))]
4449 {
4450 int nb, ne;
4451 rs6000_is_valid_mask (operands[2], &nb, &ne, <MODE>mode);
4452 if (GET_CODE (operands[3]) == SCRATCH)
4453 operands[3] = gen_reg_rtx (<MODE>mode);
4454 operands[4] = GEN_INT (ne);
4455 operands[5] = GEN_INT (~UINTVAL (operands[2]));
4456 }
4457 [(set_attr "type" "two")
4458 (set_attr "length" "8")])
4459
4460
4461 ; Yet another case is an rldimi with the second value coming from memory.
4462 ; The zero_extend that should become part of the rldimi is merged into the
4463 ; load from memory instead. Split things properly again.
4464 (define_split
4465 [(set (match_operand:DI 0 "gpc_reg_operand")
4466 (ior:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand")
4467 (match_operand:SI 2 "const_int_operand"))
4468 (zero_extend:DI (match_operand:QHSI 3 "memory_operand"))))]
4469 "INTVAL (operands[2]) == <bits>"
4470 [(set (match_dup 4)
4471 (zero_extend:DI (match_dup 3)))
4472 (set (match_dup 0)
4473 (ior:DI (and:DI (match_dup 4)
4474 (match_dup 5))
4475 (ashift:DI (match_dup 1)
4476 (match_dup 2))))]
4477 {
4478 operands[4] = gen_reg_rtx (DImode);
4479 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << <bits>) - 1);
4480 })
4481
4482 ; rldimi with UNSPEC_SI_FROM_SF.
4483 (define_insn_and_split "*rotldi3_insert_sf"
4484 [(set (match_operand:DI 0 "gpc_reg_operand")
4485 (ior:DI
4486 (ashift:DI (match_operand:DI 1 "gpc_reg_operand")
4487 (match_operand:SI 2 "const_int_operand"))
4488 (zero_extend:DI
4489 (unspec:QHSI
4490 [(match_operand:SF 3 "memory_operand")]
4491 UNSPEC_SI_FROM_SF))))
4492 (clobber (match_scratch:V4SF 4))]
4493 "TARGET_POWERPC64 && INTVAL (operands[2]) == <bits>"
4494 "#"
4495 "&& 1"
4496 [(parallel [(set (match_dup 5)
4497 (zero_extend:DI (unspec:QHSI [(match_dup 3)] UNSPEC_SI_FROM_SF)))
4498 (clobber (match_dup 4))])
4499 (set (match_dup 0)
4500 (ior:DI
4501 (and:DI (match_dup 5) (match_dup 6))
4502 (ashift:DI (match_dup 1) (match_dup 2))))]
4503 {
4504 operands[5] = gen_reg_rtx (DImode);
4505 operands[6] = GEN_INT ((HOST_WIDE_INT_1U << <bits>) - 1);
4506 })
4507
4508 ; rlwimi, too.
4509 (define_split
4510 [(set (match_operand:SI 0 "gpc_reg_operand")
4511 (ior:SI (ashift:SI (match_operand:SI 1 "gpc_reg_operand")
4512 (match_operand:SI 2 "const_int_operand"))
4513 (zero_extend:SI (match_operand:QHI 3 "memory_operand"))))]
4514 "INTVAL (operands[2]) == <bits>"
4515 [(set (match_dup 4)
4516 (zero_extend:SI (match_dup 3)))
4517 (set (match_dup 0)
4518 (ior:SI (and:SI (match_dup 4)
4519 (match_dup 5))
4520 (ashift:SI (match_dup 1)
4521 (match_dup 2))))]
4522 {
4523 operands[4] = gen_reg_rtx (SImode);
4524 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << <bits>) - 1);
4525 })
4526
4527
4528 ;; Now the simple shifts.
4529
4530 (define_insn "rotl<mode>3"
4531 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4532 (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4533 (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4534 ""
4535 "rotl<wd>%I2 %0,%1,%<hH>2"
4536 [(set_attr "type" "shift")
4537 (set_attr "maybe_var_shift" "yes")])
4538
4539 (define_insn "*rotlsi3_64"
4540 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4541 (zero_extend:DI
4542 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4543 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4544 "TARGET_POWERPC64"
4545 "rotlw%I2 %0,%1,%h2"
4546 [(set_attr "type" "shift")
4547 (set_attr "maybe_var_shift" "yes")])
4548
4549 (define_insn_and_split "*rotl<mode>3_dot"
4550 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4551 (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4552 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4553 (const_int 0)))
4554 (clobber (match_scratch:GPR 0 "=r,r"))]
4555 "<MODE>mode == Pmode"
4556 "@
4557 rotl<wd>%I2. %0,%1,%<hH>2
4558 #"
4559 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4560 [(set (match_dup 0)
4561 (rotate:GPR (match_dup 1)
4562 (match_dup 2)))
4563 (set (match_dup 3)
4564 (compare:CC (match_dup 0)
4565 (const_int 0)))]
4566 ""
4567 [(set_attr "type" "shift")
4568 (set_attr "maybe_var_shift" "yes")
4569 (set_attr "dot" "yes")
4570 (set_attr "length" "4,8")])
4571
4572 (define_insn_and_split "*rotl<mode>3_dot2"
4573 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4574 (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4575 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4576 (const_int 0)))
4577 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4578 (rotate:GPR (match_dup 1)
4579 (match_dup 2)))]
4580 "<MODE>mode == Pmode"
4581 "@
4582 rotl<wd>%I2. %0,%1,%<hH>2
4583 #"
4584 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4585 [(set (match_dup 0)
4586 (rotate:GPR (match_dup 1)
4587 (match_dup 2)))
4588 (set (match_dup 3)
4589 (compare:CC (match_dup 0)
4590 (const_int 0)))]
4591 ""
4592 [(set_attr "type" "shift")
4593 (set_attr "maybe_var_shift" "yes")
4594 (set_attr "dot" "yes")
4595 (set_attr "length" "4,8")])
4596
4597
4598 (define_insn "ashl<mode>3"
4599 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4600 (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4601 (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4602 ""
4603 "sl<wd>%I2 %0,%1,%<hH>2"
4604 [(set_attr "type" "shift")
4605 (set_attr "maybe_var_shift" "yes")])
4606
4607 (define_insn "*ashlsi3_64"
4608 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4609 (zero_extend:DI
4610 (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4611 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4612 "TARGET_POWERPC64"
4613 "slw%I2 %0,%1,%h2"
4614 [(set_attr "type" "shift")
4615 (set_attr "maybe_var_shift" "yes")])
4616
4617 (define_insn_and_split "*ashl<mode>3_dot"
4618 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4619 (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4620 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4621 (const_int 0)))
4622 (clobber (match_scratch:GPR 0 "=r,r"))]
4623 "<MODE>mode == Pmode"
4624 "@
4625 sl<wd>%I2. %0,%1,%<hH>2
4626 #"
4627 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4628 [(set (match_dup 0)
4629 (ashift:GPR (match_dup 1)
4630 (match_dup 2)))
4631 (set (match_dup 3)
4632 (compare:CC (match_dup 0)
4633 (const_int 0)))]
4634 ""
4635 [(set_attr "type" "shift")
4636 (set_attr "maybe_var_shift" "yes")
4637 (set_attr "dot" "yes")
4638 (set_attr "length" "4,8")])
4639
4640 (define_insn_and_split "*ashl<mode>3_dot2"
4641 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4642 (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4643 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4644 (const_int 0)))
4645 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4646 (ashift:GPR (match_dup 1)
4647 (match_dup 2)))]
4648 "<MODE>mode == Pmode"
4649 "@
4650 sl<wd>%I2. %0,%1,%<hH>2
4651 #"
4652 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4653 [(set (match_dup 0)
4654 (ashift:GPR (match_dup 1)
4655 (match_dup 2)))
4656 (set (match_dup 3)
4657 (compare:CC (match_dup 0)
4658 (const_int 0)))]
4659 ""
4660 [(set_attr "type" "shift")
4661 (set_attr "maybe_var_shift" "yes")
4662 (set_attr "dot" "yes")
4663 (set_attr "length" "4,8")])
4664
4665 ;; Pretend we have a memory form of extswsli until register allocation is done
4666 ;; so that we use LWZ to load the value from memory, instead of LWA.
4667 (define_insn_and_split "ashdi3_extswsli"
4668 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
4669 (ashift:DI
4670 (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,m"))
4671 (match_operand:DI 2 "u6bit_cint_operand" "n,n")))]
4672 "TARGET_EXTSWSLI"
4673 "@
4674 extswsli %0,%1,%2
4675 #"
4676 "&& reload_completed && MEM_P (operands[1])"
4677 [(set (match_dup 3)
4678 (match_dup 1))
4679 (set (match_dup 0)
4680 (ashift:DI (sign_extend:DI (match_dup 3))
4681 (match_dup 2)))]
4682 {
4683 operands[3] = gen_lowpart (SImode, operands[0]);
4684 }
4685 [(set_attr "type" "shift")
4686 (set_attr "maybe_var_shift" "no")])
4687
4688
4689 (define_insn_and_split "ashdi3_extswsli_dot"
4690 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y")
4691 (compare:CC
4692 (ashift:DI
4693 (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m"))
4694 (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n"))
4695 (const_int 0)))
4696 (clobber (match_scratch:DI 0 "=r,r,r,r"))]
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_and_split "ashdi3_extswsli_dot2"
4738 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y")
4739 (compare:CC
4740 (ashift:DI
4741 (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m"))
4742 (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n"))
4743 (const_int 0)))
4744 (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r")
4745 (ashift:DI (sign_extend:DI (match_dup 1))
4746 (match_dup 2)))]
4747 "TARGET_EXTSWSLI"
4748 "@
4749 extswsli. %0,%1,%2
4750 #
4751 #
4752 #"
4753 "&& reload_completed
4754 && (cc_reg_not_cr0_operand (operands[3], CCmode)
4755 || memory_operand (operands[1], SImode))"
4756 [(pc)]
4757 {
4758 rtx dest = operands[0];
4759 rtx src = operands[1];
4760 rtx shift = operands[2];
4761 rtx cr = operands[3];
4762 rtx src2;
4763
4764 if (!MEM_P (src))
4765 src2 = src;
4766 else
4767 {
4768 src2 = gen_lowpart (SImode, dest);
4769 emit_move_insn (src2, src);
4770 }
4771
4772 if (REGNO (cr) == CR0_REGNO)
4773 {
4774 emit_insn (gen_ashdi3_extswsli_dot2 (dest, src2, shift, cr));
4775 DONE;
4776 }
4777
4778 emit_insn (gen_ashdi3_extswsli (dest, src2, shift));
4779 emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx)));
4780 DONE;
4781 }
4782 [(set_attr "type" "shift")
4783 (set_attr "maybe_var_shift" "no")
4784 (set_attr "dot" "yes")
4785 (set_attr "length" "4,8,8,12")])
4786
4787 (define_insn "lshr<mode>3"
4788 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4789 (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4790 (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4791 ""
4792 "sr<wd>%I2 %0,%1,%<hH>2"
4793 [(set_attr "type" "shift")
4794 (set_attr "maybe_var_shift" "yes")])
4795
4796 (define_insn "*lshrsi3_64"
4797 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4798 (zero_extend:DI
4799 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4800 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4801 "TARGET_POWERPC64"
4802 "srw%I2 %0,%1,%h2"
4803 [(set_attr "type" "shift")
4804 (set_attr "maybe_var_shift" "yes")])
4805
4806 (define_insn_and_split "*lshr<mode>3_dot"
4807 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4808 (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4809 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4810 (const_int 0)))
4811 (clobber (match_scratch:GPR 0 "=r,r"))]
4812 "<MODE>mode == Pmode"
4813 "@
4814 sr<wd>%I2. %0,%1,%<hH>2
4815 #"
4816 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4817 [(set (match_dup 0)
4818 (lshiftrt:GPR (match_dup 1)
4819 (match_dup 2)))
4820 (set (match_dup 3)
4821 (compare:CC (match_dup 0)
4822 (const_int 0)))]
4823 ""
4824 [(set_attr "type" "shift")
4825 (set_attr "maybe_var_shift" "yes")
4826 (set_attr "dot" "yes")
4827 (set_attr "length" "4,8")])
4828
4829 (define_insn_and_split "*lshr<mode>3_dot2"
4830 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4831 (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4832 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4833 (const_int 0)))
4834 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4835 (lshiftrt:GPR (match_dup 1)
4836 (match_dup 2)))]
4837 "<MODE>mode == Pmode"
4838 "@
4839 sr<wd>%I2. %0,%1,%<hH>2
4840 #"
4841 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4842 [(set (match_dup 0)
4843 (lshiftrt:GPR (match_dup 1)
4844 (match_dup 2)))
4845 (set (match_dup 3)
4846 (compare:CC (match_dup 0)
4847 (const_int 0)))]
4848 ""
4849 [(set_attr "type" "shift")
4850 (set_attr "maybe_var_shift" "yes")
4851 (set_attr "dot" "yes")
4852 (set_attr "length" "4,8")])
4853
4854
4855 (define_insn "ashr<mode>3"
4856 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4857 (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4858 (match_operand:SI 2 "reg_or_cint_operand" "rn")))
4859 (clobber (reg:GPR CA_REGNO))]
4860 ""
4861 "sra<wd>%I2 %0,%1,%<hH>2"
4862 [(set_attr "type" "shift")
4863 (set_attr "maybe_var_shift" "yes")])
4864
4865 (define_insn "*ashrsi3_64"
4866 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4867 (sign_extend:DI
4868 (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4869 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))
4870 (clobber (reg:SI CA_REGNO))]
4871 "TARGET_POWERPC64"
4872 "sraw%I2 %0,%1,%h2"
4873 [(set_attr "type" "shift")
4874 (set_attr "maybe_var_shift" "yes")])
4875
4876 (define_insn_and_split "*ashr<mode>3_dot"
4877 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4878 (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4879 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4880 (const_int 0)))
4881 (clobber (match_scratch:GPR 0 "=r,r"))
4882 (clobber (reg:GPR CA_REGNO))]
4883 "<MODE>mode == Pmode"
4884 "@
4885 sra<wd>%I2. %0,%1,%<hH>2
4886 #"
4887 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4888 [(parallel [(set (match_dup 0)
4889 (ashiftrt:GPR (match_dup 1)
4890 (match_dup 2)))
4891 (clobber (reg:GPR CA_REGNO))])
4892 (set (match_dup 3)
4893 (compare:CC (match_dup 0)
4894 (const_int 0)))]
4895 ""
4896 [(set_attr "type" "shift")
4897 (set_attr "maybe_var_shift" "yes")
4898 (set_attr "dot" "yes")
4899 (set_attr "length" "4,8")])
4900
4901 (define_insn_and_split "*ashr<mode>3_dot2"
4902 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4903 (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4904 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4905 (const_int 0)))
4906 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4907 (ashiftrt:GPR (match_dup 1)
4908 (match_dup 2)))
4909 (clobber (reg:GPR CA_REGNO))]
4910 "<MODE>mode == Pmode"
4911 "@
4912 sra<wd>%I2. %0,%1,%<hH>2
4913 #"
4914 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4915 [(parallel [(set (match_dup 0)
4916 (ashiftrt:GPR (match_dup 1)
4917 (match_dup 2)))
4918 (clobber (reg:GPR CA_REGNO))])
4919 (set (match_dup 3)
4920 (compare:CC (match_dup 0)
4921 (const_int 0)))]
4922 ""
4923 [(set_attr "type" "shift")
4924 (set_attr "maybe_var_shift" "yes")
4925 (set_attr "dot" "yes")
4926 (set_attr "length" "4,8")])
4927 \f
4928 ;; Builtins to replace a division to generate FRE reciprocal estimate
4929 ;; instructions and the necessary fixup instructions
4930 (define_expand "recip<mode>3"
4931 [(match_operand:RECIPF 0 "gpc_reg_operand")
4932 (match_operand:RECIPF 1 "gpc_reg_operand")
4933 (match_operand:RECIPF 2 "gpc_reg_operand")]
4934 "RS6000_RECIP_HAVE_RE_P (<MODE>mode)"
4935 {
4936 rs6000_emit_swdiv (operands[0], operands[1], operands[2], false);
4937 DONE;
4938 })
4939
4940 ;; Split to create division from FRE/FRES/etc. and fixup instead of the normal
4941 ;; hardware division. This is only done before register allocation and with
4942 ;; -ffast-math. This must appear before the divsf3/divdf3 insns.
4943 ;; We used to also check optimize_insn_for_speed_p () but problems with guessed
4944 ;; frequencies (pr68212/pr77536) yields that unreliable so it was removed.
4945 (define_split
4946 [(set (match_operand:RECIPF 0 "gpc_reg_operand")
4947 (div:RECIPF (match_operand 1 "gpc_reg_operand")
4948 (match_operand 2 "gpc_reg_operand")))]
4949 "RS6000_RECIP_AUTO_RE_P (<MODE>mode)
4950 && can_create_pseudo_p () && flag_finite_math_only
4951 && !flag_trapping_math && flag_reciprocal_math"
4952 [(const_int 0)]
4953 {
4954 rs6000_emit_swdiv (operands[0], operands[1], operands[2], true);
4955 DONE;
4956 })
4957
4958 ;; Builtins to replace 1/sqrt(x) with instructions using RSQRTE and the
4959 ;; appropriate fixup.
4960 (define_expand "rsqrt<mode>2"
4961 [(match_operand:RECIPF 0 "gpc_reg_operand")
4962 (match_operand:RECIPF 1 "gpc_reg_operand")]
4963 "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4964 {
4965 rs6000_emit_swsqrt (operands[0], operands[1], 1);
4966 DONE;
4967 })
4968 \f
4969 ;; Floating-point insns, excluding normal data motion. We combine the SF/DF
4970 ;; modes here, and also add in conditional vsx/power8-vector support to access
4971 ;; values in the traditional Altivec registers if the appropriate
4972 ;; -mupper-regs-{df,sf} option is enabled.
4973
4974 (define_expand "abs<mode>2"
4975 [(set (match_operand:SFDF 0 "gpc_reg_operand")
4976 (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))]
4977 "TARGET_HARD_FLOAT"
4978 "")
4979
4980 (define_insn "*abs<mode>2_fpr"
4981 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,wa")
4982 (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "d,wa")))]
4983 "TARGET_HARD_FLOAT"
4984 "@
4985 fabs %0,%1
4986 xsabsdp %x0,%x1"
4987 [(set_attr "type" "fpsimple")])
4988
4989 (define_insn "*nabs<mode>2_fpr"
4990 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,wa")
4991 (neg:SFDF
4992 (abs:SFDF
4993 (match_operand:SFDF 1 "gpc_reg_operand" "d,wa"))))]
4994 "TARGET_HARD_FLOAT"
4995 "@
4996 fnabs %0,%1
4997 xsnabsdp %x0,%x1"
4998 [(set_attr "type" "fpsimple")])
4999
5000 (define_expand "neg<mode>2"
5001 [(set (match_operand:SFDF 0 "gpc_reg_operand")
5002 (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))]
5003 "TARGET_HARD_FLOAT"
5004 "")
5005
5006 (define_insn "*neg<mode>2_fpr"
5007 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,wa")
5008 (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "d,wa")))]
5009 "TARGET_HARD_FLOAT"
5010 "@
5011 fneg %0,%1
5012 xsnegdp %x0,%x1"
5013 [(set_attr "type" "fpsimple")])
5014
5015 (define_expand "add<mode>3"
5016 [(set (match_operand:SFDF 0 "gpc_reg_operand")
5017 (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
5018 (match_operand:SFDF 2 "gpc_reg_operand")))]
5019 "TARGET_HARD_FLOAT"
5020 "")
5021
5022 (define_insn "*add<mode>3_fpr"
5023 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,wa")
5024 (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%d,wa")
5025 (match_operand:SFDF 2 "gpc_reg_operand" "d,wa")))]
5026 "TARGET_HARD_FLOAT"
5027 "@
5028 fadd<s> %0,%1,%2
5029 xsadd<sd>p %x0,%x1,%x2"
5030 [(set_attr "type" "fp")
5031 (set_attr "isa" "*,<Fisa>")])
5032
5033 (define_expand "sub<mode>3"
5034 [(set (match_operand:SFDF 0 "gpc_reg_operand")
5035 (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
5036 (match_operand:SFDF 2 "gpc_reg_operand")))]
5037 "TARGET_HARD_FLOAT"
5038 "")
5039
5040 (define_insn "*sub<mode>3_fpr"
5041 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,wa")
5042 (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "d,wa")
5043 (match_operand:SFDF 2 "gpc_reg_operand" "d,wa")))]
5044 "TARGET_HARD_FLOAT"
5045 "@
5046 fsub<s> %0,%1,%2
5047 xssub<sd>p %x0,%x1,%x2"
5048 [(set_attr "type" "fp")
5049 (set_attr "isa" "*,<Fisa>")])
5050
5051 (define_expand "mul<mode>3"
5052 [(set (match_operand:SFDF 0 "gpc_reg_operand")
5053 (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
5054 (match_operand:SFDF 2 "gpc_reg_operand")))]
5055 "TARGET_HARD_FLOAT"
5056 "")
5057
5058 (define_insn "*mul<mode>3_fpr"
5059 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,wa")
5060 (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%d,wa")
5061 (match_operand:SFDF 2 "gpc_reg_operand" "d,wa")))]
5062 "TARGET_HARD_FLOAT"
5063 "@
5064 fmul<s> %0,%1,%2
5065 xsmul<sd>p %x0,%x1,%x2"
5066 [(set_attr "type" "dmul")
5067 (set_attr "isa" "*,<Fisa>")])
5068
5069 (define_expand "div<mode>3"
5070 [(set (match_operand:SFDF 0 "gpc_reg_operand")
5071 (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
5072 (match_operand:SFDF 2 "gpc_reg_operand")))]
5073 "TARGET_HARD_FLOAT"
5074 {
5075 if (RS6000_RECIP_AUTO_RE_P (<MODE>mode)
5076 && can_create_pseudo_p () && flag_finite_math_only
5077 && !flag_trapping_math && flag_reciprocal_math)
5078 {
5079 rs6000_emit_swdiv (operands[0], operands[1], operands[2], true);
5080 DONE;
5081 }
5082 })
5083
5084 (define_insn "*div<mode>3_fpr"
5085 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,wa")
5086 (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "d,wa")
5087 (match_operand:SFDF 2 "gpc_reg_operand" "d,wa")))]
5088 "TARGET_HARD_FLOAT"
5089 "@
5090 fdiv<s> %0,%1,%2
5091 xsdiv<sd>p %x0,%x1,%x2"
5092 [(set_attr "type" "<sd>div")
5093 (set_attr "isa" "*,<Fisa>")])
5094
5095 (define_insn "*sqrt<mode>2_internal"
5096 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,wa")
5097 (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "d,wa")))]
5098 "TARGET_HARD_FLOAT && TARGET_PPC_GPOPT"
5099 "@
5100 fsqrt<s> %0,%1
5101 xssqrt<sd>p %x0,%x1"
5102 [(set_attr "type" "<sd>sqrt")
5103 (set_attr "isa" "*,<Fisa>")])
5104
5105 (define_expand "sqrt<mode>2"
5106 [(set (match_operand:SFDF 0 "gpc_reg_operand")
5107 (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))]
5108 "TARGET_HARD_FLOAT && TARGET_PPC_GPOPT"
5109 {
5110 if (<MODE>mode == SFmode
5111 && TARGET_RECIP_PRECISION
5112 && RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)
5113 && !optimize_function_for_size_p (cfun)
5114 && flag_finite_math_only && !flag_trapping_math
5115 && flag_unsafe_math_optimizations)
5116 {
5117 rs6000_emit_swsqrt (operands[0], operands[1], 0);
5118 DONE;
5119 }
5120 })
5121
5122 ;; Floating point reciprocal approximation
5123 (define_insn "fre<sd>"
5124 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,wa")
5125 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "d,wa")]
5126 UNSPEC_FRES))]
5127 "TARGET_<FFRE>"
5128 "@
5129 fre<s> %0,%1
5130 xsre<sd>p %x0,%x1"
5131 [(set_attr "type" "fp")
5132 (set_attr "isa" "*,<Fisa>")])
5133
5134 (define_expand "fmod<mode>3"
5135 [(use (match_operand:SFDF 0 "gpc_reg_operand"))
5136 (use (match_operand:SFDF 1 "gpc_reg_operand"))
5137 (use (match_operand:SFDF 2 "gpc_reg_operand"))]
5138 "TARGET_HARD_FLOAT
5139 && TARGET_FPRND
5140 && flag_unsafe_math_optimizations"
5141 {
5142 rtx div = gen_reg_rtx (<MODE>mode);
5143 emit_insn (gen_div<mode>3 (div, operands[1], operands[2]));
5144
5145 rtx friz = gen_reg_rtx (<MODE>mode);
5146 emit_insn (gen_btrunc<mode>2 (friz, div));
5147
5148 emit_insn (gen_nfms<mode>4 (operands[0], operands[2], friz, operands[1]));
5149 DONE;
5150 })
5151
5152 (define_expand "remainder<mode>3"
5153 [(use (match_operand:SFDF 0 "gpc_reg_operand"))
5154 (use (match_operand:SFDF 1 "gpc_reg_operand"))
5155 (use (match_operand:SFDF 2 "gpc_reg_operand"))]
5156 "TARGET_HARD_FLOAT
5157 && TARGET_FPRND
5158 && flag_unsafe_math_optimizations"
5159 {
5160 rtx div = gen_reg_rtx (<MODE>mode);
5161 emit_insn (gen_div<mode>3 (div, operands[1], operands[2]));
5162
5163 rtx frin = gen_reg_rtx (<MODE>mode);
5164 emit_insn (gen_round<mode>2 (frin, div));
5165
5166 emit_insn (gen_nfms<mode>4 (operands[0], operands[2], frin, operands[1]));
5167 DONE;
5168 })
5169
5170 (define_insn "*rsqrt<mode>2"
5171 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,wa")
5172 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "d,wa")]
5173 UNSPEC_RSQRT))]
5174 "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
5175 "@
5176 frsqrte<s> %0,%1
5177 xsrsqrte<sd>p %x0,%x1"
5178 [(set_attr "type" "fp")
5179 (set_attr "isa" "*,<Fisa>")])
5180
5181 ;; Floating point comparisons
5182 (define_insn "*cmp<mode>_fpr"
5183 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y,y")
5184 (compare:CCFP (match_operand:SFDF 1 "gpc_reg_operand" "d,wa")
5185 (match_operand:SFDF 2 "gpc_reg_operand" "d,wa")))]
5186 "TARGET_HARD_FLOAT"
5187 "@
5188 fcmpu %0,%1,%2
5189 xscmpudp %0,%x1,%x2"
5190 [(set_attr "type" "fpcompare")
5191 (set_attr "isa" "*,<Fisa>")])
5192
5193 ;; Floating point conversions
5194 (define_expand "extendsfdf2"
5195 [(set (match_operand:DF 0 "gpc_reg_operand")
5196 (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand")))]
5197 "TARGET_HARD_FLOAT"
5198 {
5199 if (HONOR_SNANS (SFmode))
5200 operands[1] = force_reg (SFmode, operands[1]);
5201 })
5202
5203 (define_insn_and_split "*extendsfdf2_fpr"
5204 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d,d,wa,?wa,wa,v")
5205 (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand" "0,f,m,0,wa,Z,wY")))]
5206 "TARGET_HARD_FLOAT && !HONOR_SNANS (SFmode)"
5207 "@
5208 #
5209 fmr %0,%1
5210 lfs%U1%X1 %0,%1
5211 #
5212 xscpsgndp %x0,%x1,%x1
5213 lxsspx %x0,%y1
5214 lxssp %0,%1"
5215 "&& reload_completed && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1])"
5216 [(const_int 0)]
5217 {
5218 emit_note (NOTE_INSN_DELETED);
5219 DONE;
5220 }
5221 [(set_attr "type" "fp,fpsimple,fpload,fp,fpsimple,fpload,fpload")
5222 (set_attr "isa" "*,*,*,*,p8v,p8v,p9v")])
5223
5224 (define_insn "*extendsfdf2_snan"
5225 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa")
5226 (float_extend:DF (match_operand:SF 1 "gpc_reg_operand" "f,wa")))]
5227 "TARGET_HARD_FLOAT && HONOR_SNANS (SFmode)"
5228 "@
5229 frsp %0,%1
5230 xsrsp %x0,%x1"
5231 [(set_attr "type" "fp")
5232 (set_attr "isa" "*,p8v")])
5233
5234 (define_expand "truncdfsf2"
5235 [(set (match_operand:SF 0 "gpc_reg_operand")
5236 (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand")))]
5237 "TARGET_HARD_FLOAT"
5238 "")
5239
5240 (define_insn "*truncdfsf2_fpr"
5241 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wa")
5242 (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "d,wa")))]
5243 "TARGET_HARD_FLOAT"
5244 "@
5245 frsp %0,%1
5246 xsrsp %x0,%x1"
5247 [(set_attr "type" "fp")
5248 (set_attr "isa" "*,p8v")])
5249
5250 ;; This expander is here to avoid FLOAT_WORDS_BIGENDIAN tests in
5251 ;; builtins.cc and optabs.cc that are not correct for IBM long double
5252 ;; when little-endian.
5253 (define_expand "signbit<mode>2"
5254 [(set (match_dup 2)
5255 (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand")))
5256 (set (match_dup 3)
5257 (subreg:DI (match_dup 2) 0))
5258 (set (match_dup 4)
5259 (match_dup 5))
5260 (set (match_operand:SI 0 "gpc_reg_operand")
5261 (match_dup 6))]
5262 "TARGET_HARD_FLOAT
5263 && (!FLOAT128_IEEE_P (<MODE>mode)
5264 || (TARGET_POWERPC64 && TARGET_DIRECT_MOVE))"
5265 {
5266 if (FLOAT128_IEEE_P (<MODE>mode))
5267 {
5268 rtx dest = operands[0];
5269 rtx src = operands[1];
5270 rtx tmp = gen_reg_rtx (DImode);
5271 rtx dest_di = gen_lowpart (DImode, dest);
5272
5273 emit_insn (gen_signbit2_dm (<MODE>mode, tmp, src));
5274 emit_insn (gen_lshrdi3 (dest_di, tmp, GEN_INT (63)));
5275 DONE;
5276 }
5277 operands[2] = gen_reg_rtx (DFmode);
5278 operands[3] = gen_reg_rtx (DImode);
5279 if (TARGET_POWERPC64)
5280 {
5281 operands[4] = gen_reg_rtx (DImode);
5282 operands[5] = gen_rtx_LSHIFTRT (DImode, operands[3], GEN_INT (63));
5283 operands[6] = gen_rtx_SUBREG (SImode, operands[4],
5284 WORDS_BIG_ENDIAN ? 4 : 0);
5285 }
5286 else
5287 {
5288 operands[4] = gen_reg_rtx (SImode);
5289 operands[5] = gen_rtx_SUBREG (SImode, operands[3],
5290 WORDS_BIG_ENDIAN ? 0 : 4);
5291 operands[6] = gen_rtx_LSHIFTRT (SImode, operands[4], GEN_INT (31));
5292 }
5293 })
5294
5295 ;; Optimize IEEE 128-bit signbit on 64-bit systems with direct move to avoid
5296 ;; multiple direct moves. If we used a SUBREG:DI of the Floa128 type, the
5297 ;; register allocator would typically move the entire _Float128 item to GPRs (2
5298 ;; instructions on ISA 3.0, 3-4 instructions on ISA 2.07).
5299 ;;
5300 ;; After register allocation, if the _Float128 had originally been in GPRs, the
5301 ;; split allows the post reload phases to eliminate the move, and do the shift
5302 ;; directly with the register that contains the signbit.
5303 (define_insn_and_split "@signbit<mode>2_dm"
5304 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
5305 (unspec:DI [(match_operand:SIGNBIT 1 "gpc_reg_operand" "wa,r")]
5306 UNSPEC_SIGNBIT))]
5307 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
5308 "@
5309 mfvsrd %0,%x1
5310 #"
5311 "&& reload_completed && int_reg_operand (operands[1], <MODE>mode)"
5312 [(set (match_dup 0)
5313 (match_dup 2))]
5314 {
5315 operands[2] = gen_highpart (DImode, operands[1]);
5316 }
5317 [(set_attr "type" "mfvsr,*")])
5318
5319 ;; Optimize IEEE 128-bit signbit on to avoid loading the value into a vector
5320 ;; register and then doing a direct move if the value comes from memory. On
5321 ;; little endian, we have to load the 2nd double-word to get the sign bit.
5322 (define_insn_and_split "*signbit<mode>2_dm_mem"
5323 [(set (match_operand:DI 0 "gpc_reg_operand" "=b")
5324 (unspec:DI [(match_operand:SIGNBIT 1 "memory_operand" "m")]
5325 UNSPEC_SIGNBIT))]
5326 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
5327 "#"
5328 "&& 1"
5329 [(set (match_dup 0)
5330 (match_dup 2))]
5331 {
5332 rtx dest = operands[0];
5333 rtx src = operands[1];
5334 rtx addr = XEXP (src, 0);
5335
5336 if (WORDS_BIG_ENDIAN)
5337 operands[2] = adjust_address (src, DImode, 0);
5338
5339 else if (REG_P (addr) || SUBREG_P (addr))
5340 operands[2] = adjust_address (src, DImode, 8);
5341
5342 else if (GET_CODE (addr) == PLUS && REG_P (XEXP (addr, 0))
5343 && CONST_INT_P (XEXP (addr, 1)) && mem_operand_gpr (src, DImode))
5344 operands[2] = adjust_address (src, DImode, 8);
5345
5346 else
5347 {
5348 rtx tmp = can_create_pseudo_p () ? gen_reg_rtx (DImode) : dest;
5349 emit_insn (gen_rtx_SET (tmp, addr));
5350 operands[2] = change_address (src, DImode,
5351 gen_rtx_PLUS (DImode, tmp, GEN_INT (8)));
5352 }
5353 })
5354
5355 (define_expand "copysign<mode>3"
5356 [(set (match_dup 3)
5357 (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))
5358 (set (match_dup 4)
5359 (neg:SFDF (abs:SFDF (match_dup 1))))
5360 (set (match_operand:SFDF 0 "gpc_reg_operand")
5361 (if_then_else:SFDF (ge (match_operand:SFDF 2 "any_operand")
5362 (match_dup 5))
5363 (match_dup 3)
5364 (match_dup 4)))]
5365 "TARGET_HARD_FLOAT
5366 && ((TARGET_PPC_GFXOPT
5367 && !HONOR_NANS (<MODE>mode)
5368 && !HONOR_SIGNED_ZEROS (<MODE>mode))
5369 || TARGET_CMPB
5370 || VECTOR_UNIT_VSX_P (<MODE>mode))"
5371 {
5372 /* Middle-end canonicalizes -fabs (x) to copysign (x, -1),
5373 but PowerPC prefers -fabs (x). */
5374 if (CONST_DOUBLE_AS_FLOAT_P (operands[2]))
5375 {
5376 if (real_isneg (CONST_DOUBLE_REAL_VALUE (operands[2])))
5377 {
5378 operands[3] = gen_reg_rtx (<MODE>mode);
5379 emit_insn (gen_abs<mode>2 (operands[3], operands[1]));
5380 emit_insn (gen_neg<mode>2 (operands[0], operands[3]));
5381 }
5382 else
5383 emit_insn (gen_abs<mode>2 (operands[0], operands[1]));
5384 DONE;
5385 }
5386
5387 if (!gpc_reg_operand (operands[2], <MODE>mode))
5388 operands[2] = copy_to_mode_reg (<MODE>mode, operands[2]);
5389
5390 if (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode))
5391 {
5392 emit_insn (gen_copysign<mode>3_fcpsgn (operands[0], operands[1],
5393 operands[2]));
5394 DONE;
5395 }
5396
5397 operands[3] = gen_reg_rtx (<MODE>mode);
5398 operands[4] = gen_reg_rtx (<MODE>mode);
5399 operands[5] = CONST0_RTX (<MODE>mode);
5400 })
5401
5402 (define_insn "copysign<mode>3_fcpsgn"
5403 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,wa")
5404 (copysign:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "d,wa")
5405 (match_operand:SFDF 2 "gpc_reg_operand" "d,wa")))]
5406 "TARGET_HARD_FLOAT && (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode))"
5407 "@
5408 fcpsgn %0,%2,%1
5409 xscpsgndp %x0,%x2,%x1"
5410 [(set_attr "type" "fpsimple")])
5411
5412 ;; For MIN, MAX, and conditional move, we use DEFINE_EXPAND's that involve a
5413 ;; fsel instruction and some auxiliary computations. Then we just have a
5414 ;; single DEFINE_INSN for fsel and the define_splits to make them if made by
5415 ;; combine.
5416 ;; For MIN, MAX on non-VSX machines, and conditional move all of the time, we
5417 ;; use DEFINE_EXPAND's that involve a fsel instruction and some auxiliary
5418 ;; computations. Then we just have a single DEFINE_INSN for fsel and the
5419 ;; define_splits to make them if made by combine. On VSX machines we have the
5420 ;; min/max instructions.
5421 ;;
5422 ;; On VSX, we only check for TARGET_VSX instead of checking for a vsx/p8 vector
5423 ;; to allow either DF/SF to use only traditional registers.
5424
5425 (define_expand "s<minmax><mode>3"
5426 [(set (match_operand:SFDF 0 "gpc_reg_operand")
5427 (fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
5428 (match_operand:SFDF 2 "gpc_reg_operand")))]
5429 "TARGET_MINMAX"
5430 {
5431 rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]);
5432 DONE;
5433 })
5434
5435 (define_insn "*s<minmax><mode>3_vsx"
5436 [(set (match_operand:SFDF 0 "vsx_register_operand" "=wa")
5437 (fp_minmax:SFDF (match_operand:SFDF 1 "vsx_register_operand" "wa")
5438 (match_operand:SFDF 2 "vsx_register_operand" "wa")))]
5439 "TARGET_VSX && TARGET_HARD_FLOAT"
5440 {
5441 return (TARGET_P9_MINMAX
5442 ? "xs<minmax>cdp %x0,%x1,%x2"
5443 : "xs<minmax>dp %x0,%x1,%x2");
5444 }
5445 [(set_attr "type" "fp")])
5446
5447 ;; Min/max for ISA 3.1 IEEE 128-bit floating point
5448 (define_insn "s<minmax><mode>3"
5449 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
5450 (fp_minmax:IEEE128
5451 (match_operand:IEEE128 1 "altivec_register_operand" "v")
5452 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
5453 "TARGET_POWER10 && TARGET_FLOAT128_HW"
5454 "xs<minmax>cqp %0,%1,%2"
5455 [(set_attr "type" "vecfloat")
5456 (set_attr "size" "128")])
5457
5458 ;; The conditional move instructions allow us to perform max and min operations
5459 ;; even when we don't have the appropriate max/min instruction using the FSEL
5460 ;; instruction.
5461
5462 (define_insn_and_split "*s<minmax><mode>3_fpr"
5463 [(set (match_operand:SFDF 0 "gpc_reg_operand")
5464 (fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
5465 (match_operand:SFDF 2 "gpc_reg_operand")))]
5466 "!TARGET_VSX && TARGET_MINMAX"
5467 "#"
5468 "&& 1"
5469 [(const_int 0)]
5470 {
5471 rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]);
5472 DONE;
5473 })
5474
5475
5476 (define_int_iterator FMINMAX [UNSPEC_FMAX UNSPEC_FMIN])
5477
5478 (define_int_attr minmax_op [(UNSPEC_FMAX "max")
5479 (UNSPEC_FMIN "min")])
5480
5481 (define_insn "f<minmax_op><mode>3"
5482 [(set (match_operand:SFDF 0 "vsx_register_operand" "=wa")
5483 (unspec:SFDF [(match_operand:SFDF 1 "vsx_register_operand" "wa")
5484 (match_operand:SFDF 2 "vsx_register_operand" "wa")]
5485 FMINMAX))]
5486 "TARGET_VSX && !flag_finite_math_only"
5487 "xs<minmax_op>dp %x0,%x1,%x2"
5488 [(set_attr "type" "fp")]
5489 )
5490
5491 (define_expand "mov<mode>cc"
5492 [(set (match_operand:GPR 0 "gpc_reg_operand")
5493 (if_then_else:GPR (match_operand 1 "comparison_operator")
5494 (match_operand:GPR 2 "gpc_reg_operand")
5495 (match_operand:GPR 3 "gpc_reg_operand")))]
5496 "TARGET_ISEL"
5497 {
5498 if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
5499 DONE;
5500 else
5501 FAIL;
5502 })
5503
5504 ;; We use the BASE_REGS for the isel input operands because, if rA is
5505 ;; 0, the value of 0 is placed in rD upon truth. Similarly for rB
5506 ;; because we may switch the operands and rB may end up being rA.
5507 ;;
5508 ;; We need 2 patterns: an unsigned and a signed pattern. We could
5509 ;; leave out the mode in operand 4 and use one pattern, but reload can
5510 ;; change the mode underneath our feet and then gets confused trying
5511 ;; to reload the value.
5512 (define_mode_iterator CCANY [CC CCUNS])
5513 (define_insn "isel_<CCANY:mode>_<GPR:mode>"
5514 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
5515 (if_then_else:GPR
5516 (match_operator 1 "scc_comparison_operator"
5517 [(match_operand:CCANY 4 "cc_reg_operand" "y,y")
5518 (const_int 0)])
5519 (match_operand:GPR 2 "reg_or_zero_operand" "O,b")
5520 (match_operand:GPR 3 "gpc_reg_operand" "r,r")))]
5521 "TARGET_ISEL"
5522 "isel %0,%2,%3,%j1"
5523 [(set_attr "type" "isel")])
5524
5525 ;; These patterns can be useful for combine; they let combine know that
5526 ;; isel can handle reversed comparisons so long as the operands are
5527 ;; registers.
5528
5529 (define_insn "*isel_reversed_<CCANY:mode>_<GPR:mode>"
5530 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
5531 (if_then_else:GPR
5532 (match_operator 1 "scc_rev_comparison_operator"
5533 [(match_operand:CCANY 4 "cc_reg_operand" "y,y")
5534 (const_int 0)])
5535 (match_operand:GPR 2 "gpc_reg_operand" "r,r")
5536 (match_operand:GPR 3 "reg_or_zero_operand" "O,b")))]
5537 "TARGET_ISEL"
5538 {
5539 PUT_CODE (operands[1], reverse_condition (GET_CODE (operands[1])));
5540 return "isel %0,%3,%2,%j1";
5541 }
5542 [(set_attr "type" "isel")])
5543
5544 ; Set Boolean Condition (Reverse)
5545 (define_insn "setbc_<CCANY:mode>_<GPR:mode>"
5546 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
5547 (match_operator:GPR 1 "scc_comparison_operator"
5548 [(match_operand:CCANY 2 "cc_reg_operand" "y")
5549 (const_int 0)]))]
5550 "TARGET_POWER10"
5551 "setbc %0,%j1"
5552 [(set_attr "type" "isel")])
5553
5554 (define_insn "*setbcr_<CCANY:mode>_<GPR:mode>"
5555 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
5556 (match_operator:GPR 1 "scc_rev_comparison_operator"
5557 [(match_operand:CCANY 2 "cc_reg_operand" "y")
5558 (const_int 0)]))]
5559 "TARGET_POWER10"
5560 "setbcr %0,%j1"
5561 [(set_attr "type" "isel")])
5562
5563 ; Set Negative Boolean Condition (Reverse)
5564 (define_insn "*setnbc_<CCANY:mode>_<GPR:mode>"
5565 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
5566 (neg:GPR (match_operator:GPR 1 "scc_comparison_operator"
5567 [(match_operand:CCANY 2 "cc_reg_operand" "y")
5568 (const_int 0)])))]
5569 "TARGET_POWER10"
5570 "setnbc %0,%j1"
5571 [(set_attr "type" "isel")])
5572
5573 (define_insn "*setnbcr_<CCANY:mode>_<GPR:mode>"
5574 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
5575 (neg:GPR (match_operator:GPR 1 "scc_rev_comparison_operator"
5576 [(match_operand:CCANY 2 "cc_reg_operand" "y")
5577 (const_int 0)])))]
5578 "TARGET_POWER10"
5579 "setnbcr %0,%j1"
5580 [(set_attr "type" "isel")])
5581
5582 ;; Floating point conditional move
5583 (define_expand "mov<mode>cc"
5584 [(set (match_operand:SFDF 0 "gpc_reg_operand")
5585 (if_then_else:SFDF (match_operand 1 "comparison_operator")
5586 (match_operand:SFDF 2 "gpc_reg_operand")
5587 (match_operand:SFDF 3 "gpc_reg_operand")))]
5588 "TARGET_HARD_FLOAT && TARGET_PPC_GFXOPT"
5589 {
5590 if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
5591 DONE;
5592 else
5593 FAIL;
5594 })
5595
5596 (define_insn "*fsel<SFDF:mode><SFDF2:mode>4"
5597 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=&<SFDF:rreg2>")
5598 (if_then_else:SFDF
5599 (ge (match_operand:SFDF2 1 "gpc_reg_operand" "<SFDF2:rreg2>")
5600 (match_operand:SFDF2 4 "zero_fp_constant" "F"))
5601 (match_operand:SFDF 2 "gpc_reg_operand" "<SFDF:rreg2>")
5602 (match_operand:SFDF 3 "gpc_reg_operand" "<SFDF:rreg2>")))]
5603 "TARGET_HARD_FLOAT && TARGET_PPC_GFXOPT"
5604 "fsel %0,%1,%2,%3"
5605 [(set_attr "type" "fp")])
5606
5607 (define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_p9"
5608 [(set (match_operand:SFDF 0 "vsx_register_operand" "=&wa,wa")
5609 (if_then_else:SFDF
5610 (match_operator:CCFP 1 "fpmask_comparison_operator"
5611 [(match_operand:SFDF2 2 "vsx_register_operand" "wa,wa")
5612 (match_operand:SFDF2 3 "vsx_register_operand" "wa,wa")])
5613 (match_operand:SFDF 4 "vsx_register_operand" "wa,wa")
5614 (match_operand:SFDF 5 "vsx_register_operand" "wa,wa")))
5615 (clobber (match_scratch:V2DI 6 "=0,&wa"))]
5616 "TARGET_P9_MINMAX"
5617 "#"
5618 "&& 1"
5619 [(set (match_dup 6)
5620 (if_then_else:V2DI (match_dup 1)
5621 (match_dup 7)
5622 (match_dup 8)))
5623 (set (match_dup 0)
5624 (if_then_else:SFDF (ne (match_dup 6)
5625 (match_dup 8))
5626 (match_dup 4)
5627 (match_dup 5)))]
5628 {
5629 if (GET_CODE (operands[6]) == SCRATCH)
5630 operands[6] = gen_reg_rtx (V2DImode);
5631
5632 operands[7] = CONSTM1_RTX (V2DImode);
5633 operands[8] = CONST0_RTX (V2DImode);
5634 }
5635 [(set_attr "length" "8")
5636 (set_attr "type" "vecperm")])
5637
5638 ;; Handle inverting the fpmask comparisons.
5639 (define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_invert_p9"
5640 [(set (match_operand:SFDF 0 "vsx_register_operand" "=&wa,wa")
5641 (if_then_else:SFDF
5642 (match_operator:CCFP 1 "invert_fpmask_comparison_operator"
5643 [(match_operand:SFDF2 2 "vsx_register_operand" "wa,wa")
5644 (match_operand:SFDF2 3 "vsx_register_operand" "wa,wa")])
5645 (match_operand:SFDF 4 "vsx_register_operand" "wa,wa")
5646 (match_operand:SFDF 5 "vsx_register_operand" "wa,wa")))
5647 (clobber (match_scratch:V2DI 6 "=0,&wa"))]
5648 "TARGET_P9_MINMAX"
5649 "#"
5650 "&& 1"
5651 [(set (match_dup 6)
5652 (if_then_else:V2DI (match_dup 9)
5653 (match_dup 7)
5654 (match_dup 8)))
5655 (set (match_dup 0)
5656 (if_then_else:SFDF (ne (match_dup 6)
5657 (match_dup 8))
5658 (match_dup 5)
5659 (match_dup 4)))]
5660 {
5661 rtx op1 = operands[1];
5662 enum rtx_code cond = reverse_condition_maybe_unordered (GET_CODE (op1));
5663
5664 if (GET_CODE (operands[6]) == SCRATCH)
5665 operands[6] = gen_reg_rtx (V2DImode);
5666
5667 operands[7] = CONSTM1_RTX (V2DImode);
5668 operands[8] = CONST0_RTX (V2DImode);
5669
5670 operands[9] = gen_rtx_fmt_ee (cond, CCFPmode, operands[2], operands[3]);
5671 }
5672 [(set_attr "length" "8")
5673 (set_attr "type" "vecperm")])
5674
5675 (define_insn "*fpmask<mode>"
5676 [(set (match_operand:V2DI 0 "vsx_register_operand" "=wa")
5677 (if_then_else:V2DI
5678 (match_operator:CCFP 1 "fpmask_comparison_operator"
5679 [(match_operand:SFDF 2 "vsx_register_operand" "wa")
5680 (match_operand:SFDF 3 "vsx_register_operand" "wa")])
5681 (match_operand:V2DI 4 "all_ones_constant" "")
5682 (match_operand:V2DI 5 "zero_constant" "")))]
5683 "TARGET_P9_MINMAX"
5684 "xscmp%V1dp %x0,%x2,%x3"
5685 [(set_attr "type" "fpcompare")])
5686
5687 (define_insn "*xxsel<mode>"
5688 [(set (match_operand:SFDF 0 "vsx_register_operand" "=wa")
5689 (if_then_else:SFDF (ne (match_operand:V2DI 1 "vsx_register_operand" "wa")
5690 (match_operand:V2DI 2 "zero_constant" ""))
5691 (match_operand:SFDF 3 "vsx_register_operand" "wa")
5692 (match_operand:SFDF 4 "vsx_register_operand" "wa")))]
5693 "TARGET_P9_MINMAX"
5694 "xxsel %x0,%x4,%x3,%x1"
5695 [(set_attr "type" "vecmove")])
5696
5697 ;; Support for ISA 3.1 IEEE 128-bit conditional move. The mode used in the
5698 ;; comparison must be the same as used in the move.
5699 (define_expand "mov<mode>cc"
5700 [(set (match_operand:IEEE128 0 "gpc_reg_operand")
5701 (if_then_else:IEEE128 (match_operand 1 "comparison_operator")
5702 (match_operand:IEEE128 2 "gpc_reg_operand")
5703 (match_operand:IEEE128 3 "gpc_reg_operand")))]
5704 "TARGET_POWER10 && TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
5705 {
5706 if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
5707 DONE;
5708 else
5709 FAIL;
5710 })
5711
5712 (define_insn_and_split "*mov<mode>cc_p10"
5713 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=&v,v")
5714 (if_then_else:IEEE128
5715 (match_operator:CCFP 1 "fpmask_comparison_operator"
5716 [(match_operand:IEEE128 2 "altivec_register_operand" "v,v")
5717 (match_operand:IEEE128 3 "altivec_register_operand" "v,v")])
5718 (match_operand:IEEE128 4 "altivec_register_operand" "v,v")
5719 (match_operand:IEEE128 5 "altivec_register_operand" "v,v")))
5720 (clobber (match_scratch:V2DI 6 "=0,&v"))]
5721 "TARGET_POWER10 && TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
5722 "#"
5723 "&& 1"
5724 [(set (match_dup 6)
5725 (if_then_else:V2DI (match_dup 1)
5726 (match_dup 7)
5727 (match_dup 8)))
5728 (set (match_dup 0)
5729 (if_then_else:IEEE128 (ne (match_dup 6)
5730 (match_dup 8))
5731 (match_dup 4)
5732 (match_dup 5)))]
5733 {
5734 if (GET_CODE (operands[6]) == SCRATCH)
5735 operands[6] = gen_reg_rtx (V2DImode);
5736
5737 operands[7] = CONSTM1_RTX (V2DImode);
5738 operands[8] = CONST0_RTX (V2DImode);
5739 }
5740 [(set_attr "length" "8")
5741 (set_attr "type" "vecperm")])
5742
5743 ;; Handle inverting the fpmask comparisons.
5744 (define_insn_and_split "*mov<mode>cc_invert_p10"
5745 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=&v,v")
5746 (if_then_else:IEEE128
5747 (match_operator:CCFP 1 "invert_fpmask_comparison_operator"
5748 [(match_operand:IEEE128 2 "altivec_register_operand" "v,v")
5749 (match_operand:IEEE128 3 "altivec_register_operand" "v,v")])
5750 (match_operand:IEEE128 4 "altivec_register_operand" "v,v")
5751 (match_operand:IEEE128 5 "altivec_register_operand" "v,v")))
5752 (clobber (match_scratch:V2DI 6 "=0,&v"))]
5753 "TARGET_POWER10 && TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
5754 "#"
5755 "&& 1"
5756 [(set (match_dup 6)
5757 (if_then_else:V2DI (match_dup 9)
5758 (match_dup 7)
5759 (match_dup 8)))
5760 (set (match_dup 0)
5761 (if_then_else:IEEE128 (ne (match_dup 6)
5762 (match_dup 8))
5763 (match_dup 5)
5764 (match_dup 4)))]
5765 {
5766 rtx op1 = operands[1];
5767 enum rtx_code cond = reverse_condition_maybe_unordered (GET_CODE (op1));
5768
5769 if (GET_CODE (operands[6]) == SCRATCH)
5770 operands[6] = gen_reg_rtx (V2DImode);
5771
5772 operands[7] = CONSTM1_RTX (V2DImode);
5773 operands[8] = CONST0_RTX (V2DImode);
5774
5775 operands[9] = gen_rtx_fmt_ee (cond, CCFPmode, operands[2], operands[3]);
5776 }
5777 [(set_attr "length" "8")
5778 (set_attr "type" "vecperm")])
5779
5780 (define_insn "*fpmask<mode>"
5781 [(set (match_operand:V2DI 0 "altivec_register_operand" "=v")
5782 (if_then_else:V2DI
5783 (match_operator:CCFP 1 "fpmask_comparison_operator"
5784 [(match_operand:IEEE128 2 "altivec_register_operand" "v")
5785 (match_operand:IEEE128 3 "altivec_register_operand" "v")])
5786 (match_operand:V2DI 4 "all_ones_constant" "")
5787 (match_operand:V2DI 5 "zero_constant" "")))]
5788 "TARGET_POWER10 && TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
5789 "xscmp%V1qp %0,%2,%3"
5790 [(set_attr "type" "fpcompare")])
5791
5792 (define_insn "*xxsel<mode>"
5793 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
5794 (if_then_else:IEEE128
5795 (ne (match_operand:V2DI 1 "altivec_register_operand" "v")
5796 (match_operand:V2DI 2 "zero_constant" ""))
5797 (match_operand:IEEE128 3 "altivec_register_operand" "v")
5798 (match_operand:IEEE128 4 "altivec_register_operand" "v")))]
5799 "TARGET_POWER10 && TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
5800 "xxsel %x0,%x4,%x3,%x1"
5801 [(set_attr "type" "vecmove")])
5802
5803 \f
5804 ;; Conversions to and from floating-point.
5805
5806 ; We don't define lfiwax/lfiwzx with the normal definition, because we
5807 ; don't want to support putting SImode in FPR registers.
5808 (define_insn "lfiwax"
5809 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa,wa,v")
5810 (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r,v")]
5811 UNSPEC_LFIWAX))]
5812 "TARGET_HARD_FLOAT && TARGET_LFIWAX"
5813 "@
5814 lfiwax %0,%y1
5815 lxsiwax %x0,%y1
5816 mtvsrwa %x0,%1
5817 vextsw2d %0,%1"
5818 [(set_attr "type" "fpload,fpload,mtvsr,vecexts")
5819 (set_attr "isa" "*,p8v,p8v,p9v")])
5820
5821 ; This split must be run before register allocation because it allocates the
5822 ; memory slot that is needed to move values to/from the FPR. We don't allocate
5823 ; it earlier to allow for the combiner to merge insns together where it might
5824 ; not be needed and also in case the insns are deleted as dead code.
5825
5826 (define_insn_and_split "floatsi<mode>2_lfiwax"
5827 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,wa")
5828 (float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r,r")))
5829 (clobber (match_scratch:DI 2 "=d,wa"))]
5830 "TARGET_HARD_FLOAT && TARGET_LFIWAX
5831 && <SI_CONVERT_FP> && can_create_pseudo_p ()"
5832 "#"
5833 "&& 1"
5834 [(pc)]
5835 {
5836 rtx dest = operands[0];
5837 rtx src = operands[1];
5838 rtx tmp;
5839
5840 if (!MEM_P (src) && TARGET_POWERPC64 && TARGET_DIRECT_MOVE)
5841 tmp = convert_to_mode (DImode, src, false);
5842 else
5843 {
5844 tmp = operands[2];
5845 if (GET_CODE (tmp) == SCRATCH)
5846 tmp = gen_reg_rtx (DImode);
5847 if (MEM_P (src))
5848 {
5849 src = rs6000_force_indexed_or_indirect_mem (src);
5850 emit_insn (gen_lfiwax (tmp, src));
5851 }
5852 else
5853 {
5854 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5855 emit_move_insn (stack, src);
5856 emit_insn (gen_lfiwax (tmp, stack));
5857 }
5858 }
5859 emit_insn (gen_floatdi<mode>2 (dest, tmp));
5860 DONE;
5861 }
5862 [(set_attr "length" "12")
5863 (set_attr "type" "fpload")])
5864
5865 (define_insn_and_split "floatsi<mode>2_lfiwax_mem"
5866 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,wa")
5867 (float:SFDF
5868 (sign_extend:DI
5869 (match_operand:SI 1 "indexed_or_indirect_operand" "Z,Z"))))
5870 (clobber (match_scratch:DI 2 "=d,wa"))]
5871 "TARGET_HARD_FLOAT && TARGET_LFIWAX && <SI_CONVERT_FP>"
5872 "#"
5873 "&& 1"
5874 [(pc)]
5875 {
5876 operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
5877 if (GET_CODE (operands[2]) == SCRATCH)
5878 operands[2] = gen_reg_rtx (DImode);
5879 if (TARGET_P8_VECTOR)
5880 emit_insn (gen_extendsidi2 (operands[2], operands[1]));
5881 else
5882 emit_insn (gen_lfiwax (operands[2], operands[1]));
5883 emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
5884 DONE;
5885 }
5886 [(set_attr "length" "8")
5887 (set_attr "type" "fpload")])
5888
5889 (define_insn_and_split "floatsi<SFDF:mode>2_lfiwax_<QHI:mode>_mem_zext"
5890 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,wa")
5891 (float:SFDF
5892 (zero_extend:SI
5893 (match_operand:QHI 1 "indexed_or_indirect_operand" "Z,Z"))))
5894 (clobber (match_scratch:DI 2 "=d,wa"))]
5895 "TARGET_HARD_FLOAT && <SI_CONVERT_FP> && TARGET_P9_VECTOR
5896 && TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
5897 "#"
5898 "&& 1"
5899 [(pc)]
5900 {
5901 if (GET_CODE (operands[2]) == SCRATCH)
5902 operands[2] = gen_reg_rtx (DImode);
5903 emit_insn (gen_zero_extendhidi2 (operands[2], operands[1]));
5904 emit_insn (gen_floatdi<SFDF:mode>2 (operands[0], operands[2]));
5905 DONE;
5906 }
5907 [(set_attr "length" "8")
5908 (set_attr "type" "fpload")])
5909
5910 (define_insn "lfiwzx"
5911 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa,wa,wa")
5912 (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r,wa")]
5913 UNSPEC_LFIWZX))]
5914 "TARGET_HARD_FLOAT && TARGET_LFIWZX"
5915 "@
5916 lfiwzx %0,%y1
5917 lxsiwzx %x0,%y1
5918 mtvsrwz %x0,%1
5919 xxextractuw %x0,%x1,4"
5920 [(set_attr "type" "fpload,fpload,mtvsr,vecexts")
5921 (set_attr "isa" "*,p8v,p8v,p9v")])
5922
5923 (define_insn_and_split "floatunssi<mode>2_lfiwzx"
5924 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,wa")
5925 (unsigned_float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r,r")))
5926 (clobber (match_scratch:DI 2 "=d,wa"))]
5927 "TARGET_HARD_FLOAT && TARGET_LFIWZX && <SI_CONVERT_FP>"
5928 "#"
5929 "&& 1"
5930 [(pc)]
5931 {
5932 rtx dest = operands[0];
5933 rtx src = operands[1];
5934 rtx tmp;
5935
5936 if (!MEM_P (src) && TARGET_POWERPC64 && TARGET_DIRECT_MOVE)
5937 tmp = convert_to_mode (DImode, src, true);
5938 else
5939 {
5940 tmp = operands[2];
5941 if (GET_CODE (tmp) == SCRATCH)
5942 tmp = gen_reg_rtx (DImode);
5943 if (MEM_P (src))
5944 {
5945 src = rs6000_force_indexed_or_indirect_mem (src);
5946 emit_insn (gen_lfiwzx (tmp, src));
5947 }
5948 else
5949 {
5950 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5951 emit_move_insn (stack, src);
5952 emit_insn (gen_lfiwzx (tmp, stack));
5953 }
5954 }
5955 emit_insn (gen_floatdi<mode>2 (dest, tmp));
5956 DONE;
5957 }
5958 [(set_attr "length" "12")
5959 (set_attr "type" "fpload")])
5960
5961 (define_insn_and_split "floatunssi<mode>2_lfiwzx_mem"
5962 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,wa")
5963 (unsigned_float:SFDF
5964 (zero_extend:DI
5965 (match_operand:SI 1 "indexed_or_indirect_operand" "Z,Z"))))
5966 (clobber (match_scratch:DI 2 "=d,wa"))]
5967 "TARGET_HARD_FLOAT && TARGET_LFIWZX && <SI_CONVERT_FP>"
5968 "#"
5969 "&& 1"
5970 [(pc)]
5971 {
5972 operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
5973 if (GET_CODE (operands[2]) == SCRATCH)
5974 operands[2] = gen_reg_rtx (DImode);
5975 if (TARGET_P8_VECTOR)
5976 emit_insn (gen_zero_extendsidi2 (operands[2], operands[1]));
5977 else
5978 emit_insn (gen_lfiwzx (operands[2], operands[1]));
5979 emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
5980 DONE;
5981 }
5982 [(set_attr "length" "8")
5983 (set_attr "type" "fpload")])
5984
5985 ; For each of these conversions, there is a define_expand, a define_insn
5986 ; with a '#' template, and a define_split (with C code). The idea is
5987 ; to allow constant folding with the template of the define_insn,
5988 ; then to have the insns split later (between sched1 and final).
5989
5990 (define_expand "floatsidf2"
5991 [(parallel [(set (match_operand:DF 0 "gpc_reg_operand")
5992 (float:DF (match_operand:SI 1 "nonimmediate_operand")))
5993 (use (match_dup 2))
5994 (use (match_dup 3))
5995 (clobber (match_dup 4))
5996 (clobber (match_dup 5))
5997 (clobber (match_dup 6))])]
5998 "TARGET_HARD_FLOAT"
5999 {
6000 if (TARGET_LFIWAX && TARGET_FCFID)
6001 {
6002 emit_insn (gen_floatsidf2_lfiwax (operands[0], operands[1]));
6003 DONE;
6004 }
6005 else if (TARGET_FCFID)
6006 {
6007 rtx dreg = operands[1];
6008 if (!REG_P (dreg))
6009 dreg = force_reg (SImode, dreg);
6010 dreg = convert_to_mode (DImode, dreg, false);
6011 emit_insn (gen_floatdidf2 (operands[0], dreg));
6012 DONE;
6013 }
6014
6015 if (!REG_P (operands[1]))
6016 operands[1] = force_reg (SImode, operands[1]);
6017 operands[2] = force_reg (SImode, GEN_INT (0x43300000));
6018 operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503601774854144\", DFmode));
6019 operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
6020 operands[5] = gen_reg_rtx (DFmode);
6021 operands[6] = gen_reg_rtx (SImode);
6022 })
6023
6024 (define_insn_and_split "*floatsidf2_internal"
6025 [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
6026 (float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
6027 (use (match_operand:SI 2 "gpc_reg_operand" "r"))
6028 (use (match_operand:DF 3 "gpc_reg_operand" "d"))
6029 (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
6030 (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))
6031 (clobber (match_operand:SI 6 "gpc_reg_operand" "=&r"))]
6032 "!TARGET_FCFID && TARGET_HARD_FLOAT"
6033 "#"
6034 "&& 1"
6035 [(pc)]
6036 {
6037 rtx lowword, highword;
6038 gcc_assert (MEM_P (operands[4]));
6039 highword = adjust_address (operands[4], SImode, 0);
6040 lowword = adjust_address (operands[4], SImode, 4);
6041 if (! WORDS_BIG_ENDIAN)
6042 std::swap (lowword, highword);
6043
6044 emit_insn (gen_xorsi3 (operands[6], operands[1],
6045 GEN_INT (~ (HOST_WIDE_INT) 0x7fffffff)));
6046 emit_move_insn (lowword, operands[6]);
6047 emit_move_insn (highword, operands[2]);
6048 emit_move_insn (operands[5], operands[4]);
6049 emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
6050 DONE;
6051 }
6052 [(set_attr "length" "24")
6053 (set_attr "type" "fp")])
6054
6055 ;; If we don't have a direct conversion to single precision, don't enable this
6056 ;; conversion for 32-bit without fast math, because we don't have the insn to
6057 ;; generate the fixup swizzle to avoid double rounding problems.
6058 (define_expand "floatunssisf2"
6059 [(set (match_operand:SF 0 "gpc_reg_operand")
6060 (unsigned_float:SF (match_operand:SI 1 "nonimmediate_operand")))]
6061 "TARGET_HARD_FLOAT
6062 && ((TARGET_FCFIDUS && TARGET_LFIWZX)
6063 || (TARGET_FCFID
6064 && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))"
6065 {
6066 if (TARGET_LFIWZX && TARGET_FCFIDUS)
6067 {
6068 emit_insn (gen_floatunssisf2_lfiwzx (operands[0], operands[1]));
6069 DONE;
6070 }
6071 else
6072 {
6073 rtx dreg = operands[1];
6074 if (!REG_P (dreg))
6075 dreg = force_reg (SImode, dreg);
6076 dreg = convert_to_mode (DImode, dreg, true);
6077 emit_insn (gen_floatdisf2 (operands[0], dreg));
6078 DONE;
6079 }
6080 })
6081
6082 (define_expand "floatunssidf2"
6083 [(parallel [(set (match_operand:DF 0 "gpc_reg_operand")
6084 (unsigned_float:DF (match_operand:SI 1 "nonimmediate_operand")))
6085 (use (match_dup 2))
6086 (use (match_dup 3))
6087 (clobber (match_dup 4))
6088 (clobber (match_dup 5))])]
6089 "TARGET_HARD_FLOAT"
6090 {
6091 if (TARGET_LFIWZX && TARGET_FCFID)
6092 {
6093 emit_insn (gen_floatunssidf2_lfiwzx (operands[0], operands[1]));
6094 DONE;
6095 }
6096 else if (TARGET_FCFID)
6097 {
6098 rtx dreg = operands[1];
6099 if (!REG_P (dreg))
6100 dreg = force_reg (SImode, dreg);
6101 dreg = convert_to_mode (DImode, dreg, true);
6102 emit_insn (gen_floatdidf2 (operands[0], dreg));
6103 DONE;
6104 }
6105
6106 if (!REG_P (operands[1]))
6107 operands[1] = force_reg (SImode, operands[1]);
6108 operands[2] = force_reg (SImode, GEN_INT (0x43300000));
6109 operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503599627370496\", DFmode));
6110 operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
6111 operands[5] = gen_reg_rtx (DFmode);
6112 })
6113
6114 (define_insn_and_split "*floatunssidf2_internal"
6115 [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
6116 (unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
6117 (use (match_operand:SI 2 "gpc_reg_operand" "r"))
6118 (use (match_operand:DF 3 "gpc_reg_operand" "d"))
6119 (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
6120 (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))]
6121 "!TARGET_FCFIDU && TARGET_HARD_FLOAT
6122 && !(TARGET_FCFID && TARGET_POWERPC64)"
6123 "#"
6124 "&& 1"
6125 [(pc)]
6126 {
6127 rtx lowword, highword;
6128 gcc_assert (MEM_P (operands[4]));
6129 highword = adjust_address (operands[4], SImode, 0);
6130 lowword = adjust_address (operands[4], SImode, 4);
6131 if (! WORDS_BIG_ENDIAN)
6132 std::swap (lowword, highword);
6133
6134 emit_move_insn (lowword, operands[1]);
6135 emit_move_insn (highword, operands[2]);
6136 emit_move_insn (operands[5], operands[4]);
6137 emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
6138 DONE;
6139 }
6140 [(set_attr "length" "20")
6141 (set_attr "type" "fp")])
6142
6143 ;; ISA 3.0 adds instructions lxsi[bh]zx to directly load QImode and HImode to
6144 ;; vector registers. These insns favor doing the sign/zero extension in
6145 ;; the vector registers, rather then loading up a GPR, doing a sign/zero
6146 ;; extension and then a direct move.
6147
6148 (define_expand "float<QHI:mode><SFDF:mode>2"
6149 [(parallel [(set (match_operand:SFDF 0 "vsx_register_operand")
6150 (float:SFDF
6151 (match_operand:QHI 1 "input_operand")))
6152 (clobber (match_scratch:DI 2))
6153 (clobber (match_scratch:DI 3))
6154 (clobber (match_scratch:<QHI:MODE> 4))])]
6155 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
6156 {
6157 if (MEM_P (operands[1]))
6158 operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
6159 })
6160
6161 (define_insn_and_split "*float<QHI:mode><SFDF:mode>2_internal"
6162 [(set (match_operand:SFDF 0 "vsx_register_operand" "=wa,wa,wa")
6163 (float:SFDF
6164 (match_operand:QHI 1 "reg_or_indexed_operand" "v,r,Z")))
6165 (clobber (match_scratch:DI 2 "=v,wa,v"))
6166 (clobber (match_scratch:DI 3 "=X,r,X"))
6167 (clobber (match_scratch:<QHI:MODE> 4 "=X,X,v"))]
6168 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
6169 "#"
6170 "&& reload_completed"
6171 [(const_int 0)]
6172 {
6173 rtx result = operands[0];
6174 rtx input = operands[1];
6175 rtx di = operands[2];
6176
6177 if (!MEM_P (input))
6178 {
6179 rtx tmp = operands[3];
6180 if (altivec_register_operand (input, <QHI:MODE>mode))
6181 emit_insn (gen_extend<QHI:mode>di2 (di, input));
6182 else if (GET_CODE (tmp) == SCRATCH)
6183 emit_insn (gen_extend<QHI:mode>di2 (di, input));
6184 else
6185 {
6186 emit_insn (gen_extend<QHI:mode>di2 (tmp, input));
6187 emit_move_insn (di, tmp);
6188 }
6189 }
6190 else
6191 {
6192 rtx tmp = operands[4];
6193 emit_move_insn (tmp, input);
6194 emit_insn (gen_extend<QHI:mode>di2 (di, tmp));
6195 }
6196
6197 emit_insn (gen_floatdi<SFDF:mode>2 (result, di));
6198 DONE;
6199 }
6200 [(set_attr "isa" "p9v,*,p9v")])
6201
6202 (define_expand "floatuns<QHI:mode><SFDF:mode>2"
6203 [(parallel [(set (match_operand:SFDF 0 "vsx_register_operand")
6204 (unsigned_float:SFDF
6205 (match_operand:QHI 1 "input_operand")))
6206 (clobber (match_scratch:DI 2))
6207 (clobber (match_scratch:DI 3))])]
6208 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
6209 {
6210 if (MEM_P (operands[1]))
6211 operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
6212 })
6213
6214 (define_insn_and_split "*floatuns<QHI:mode><SFDF:mode>2_internal"
6215 [(set (match_operand:SFDF 0 "vsx_register_operand" "=wa,wa,wa")
6216 (unsigned_float:SFDF
6217 (match_operand:QHI 1 "reg_or_indexed_operand" "v,r,Z")))
6218 (clobber (match_scratch:DI 2 "=v,wa,wa"))
6219 (clobber (match_scratch:DI 3 "=X,r,X"))]
6220 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
6221 "#"
6222 "&& reload_completed"
6223 [(const_int 0)]
6224 {
6225 rtx result = operands[0];
6226 rtx input = operands[1];
6227 rtx di = operands[2];
6228
6229 if (MEM_P (input) || altivec_register_operand (input, <QHI:MODE>mode))
6230 emit_insn (gen_zero_extend<QHI:mode>di2 (di, input));
6231 else
6232 {
6233 rtx tmp = operands[3];
6234 if (GET_CODE (tmp) == SCRATCH)
6235 emit_insn (gen_extend<QHI:mode>di2 (di, input));
6236 else
6237 {
6238 emit_insn (gen_zero_extend<QHI:mode>di2 (tmp, input));
6239 emit_move_insn (di, tmp);
6240 }
6241 }
6242
6243 emit_insn (gen_floatdi<SFDF:mode>2 (result, di));
6244 DONE;
6245 }
6246 [(set_attr "isa" "p9v,*,p9v")])
6247
6248 (define_expand "fix_trunc<mode>si2"
6249 [(set (match_operand:SI 0 "gpc_reg_operand")
6250 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand")))]
6251 "TARGET_HARD_FLOAT"
6252 {
6253 if (!(TARGET_P8_VECTOR && TARGET_DIRECT_MOVE))
6254 {
6255 rtx src = force_reg (<MODE>mode, operands[1]);
6256
6257 if (TARGET_STFIWX)
6258 emit_insn (gen_fix_trunc<mode>si2_stfiwx (operands[0], src));
6259 else
6260 {
6261 rtx tmp = gen_reg_rtx (DImode);
6262 rtx stack = rs6000_allocate_stack_temp (DImode, true, false);
6263 emit_insn (gen_fix_trunc<mode>si2_internal (operands[0], src,
6264 tmp, stack));
6265 }
6266 DONE;
6267 }
6268 })
6269
6270 ; Like the convert to float patterns, this insn must be split before
6271 ; register allocation so that it can allocate the memory slot if it
6272 ; needed
6273 (define_insn_and_split "fix_trunc<mode>si2_stfiwx"
6274 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
6275 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
6276 (clobber (match_scratch:DI 2 "=d"))]
6277 "TARGET_HARD_FLOAT && TARGET_STFIWX && can_create_pseudo_p ()
6278 && !(TARGET_P8_VECTOR && TARGET_DIRECT_MOVE)"
6279 "#"
6280 "&& 1"
6281 [(pc)]
6282 {
6283 rtx dest = operands[0];
6284 rtx src = operands[1];
6285 rtx tmp = operands[2];
6286
6287 if (GET_CODE (tmp) == SCRATCH)
6288 tmp = gen_reg_rtx (DImode);
6289
6290 emit_insn (gen_fctiwz_<mode> (tmp, src));
6291 if (MEM_P (dest) && (TARGET_MFCRF || MEM_ALIGN (dest) >= 32))
6292 {
6293 dest = rs6000_force_indexed_or_indirect_mem (dest);
6294 emit_insn (gen_stfiwx (dest, tmp));
6295 DONE;
6296 }
6297 else if (TARGET_POWERPC64 && TARGET_DIRECT_MOVE && !MEM_P (dest))
6298 {
6299 dest = gen_lowpart (DImode, dest);
6300 emit_move_insn (dest, tmp);
6301 DONE;
6302 }
6303 else
6304 {
6305 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
6306 emit_insn (gen_stfiwx (stack, tmp));
6307 emit_move_insn (dest, stack);
6308 DONE;
6309 }
6310 }
6311 [(set_attr "length" "12")
6312 (set_attr "type" "fp")])
6313
6314 (define_insn_and_split "fix_trunc<mode>si2_internal"
6315 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,?r")
6316 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d,<rreg>")))
6317 (clobber (match_operand:DI 2 "gpc_reg_operand" "=1,d"))
6318 (clobber (match_operand:DI 3 "offsettable_mem_operand" "=o,o"))]
6319 "TARGET_HARD_FLOAT
6320 && !(TARGET_P8_VECTOR && TARGET_DIRECT_MOVE)"
6321 "#"
6322 "&& 1"
6323 [(pc)]
6324 {
6325 rtx lowword;
6326 gcc_assert (MEM_P (operands[3]));
6327 lowword = adjust_address (operands[3], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
6328
6329 emit_insn (gen_fctiwz_<mode> (operands[2], operands[1]));
6330 emit_move_insn (operands[3], operands[2]);
6331 emit_move_insn (operands[0], lowword);
6332 DONE;
6333 }
6334 [(set_attr "length" "16")
6335 (set_attr "type" "fp")])
6336
6337 (define_expand "fix_trunc<mode>di2"
6338 [(set (match_operand:DI 0 "gpc_reg_operand")
6339 (fix:DI (match_operand:SFDF 1 "gpc_reg_operand")))]
6340 "TARGET_HARD_FLOAT && TARGET_FCFID"
6341 "")
6342
6343 (define_insn "*fix_trunc<mode>di2_fctidz"
6344 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa")
6345 (fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "d,wa")))]
6346 "TARGET_HARD_FLOAT && TARGET_FCFID"
6347 "@
6348 fctidz %0,%1
6349 xscvdpsxds %x0,%x1"
6350 [(set_attr "type" "fp")])
6351
6352 ;; If we have ISA 3.0, QI/HImode values can go in both VSX registers and GPR
6353 ;; registers. If we have ISA 2.07, we don't allow QI/HImode values in the
6354 ;; vector registers, so we need to do direct moves to the GPRs, but SImode
6355 ;; values can go in VSX registers. Keeping the direct move part through
6356 ;; register allocation prevents the register allocator from doing a direct move
6357 ;; of the SImode value to a GPR, and then a store/load.
6358 (define_insn_and_split "fix<uns>_trunc<SFDF:mode><QHI:mode>2"
6359 [(set (match_operand:<QHI:MODE> 0 "gpc_reg_operand" "=d,wa,r")
6360 (any_fix:QHI (match_operand:SFDF 1 "gpc_reg_operand" "d,wa,wa")))
6361 (clobber (match_scratch:SI 2 "=X,X,wa"))]
6362 "TARGET_DIRECT_MOVE"
6363 "@
6364 fctiw<u>z %0,%1
6365 xscvdp<su>xws %x0,%x1
6366 #"
6367 "&& reload_completed && int_reg_operand (operands[0], <QHI:MODE>mode)"
6368 [(set (match_dup 2)
6369 (any_fix:SI (match_dup 1)))
6370 (set (match_dup 3)
6371 (match_dup 2))]
6372 {
6373 operands[3] = gen_rtx_REG (SImode, REGNO (operands[0]));
6374 }
6375 [(set_attr "type" "fp")
6376 (set_attr "length" "4,4,8")
6377 (set_attr "isa" "p9v,p9v,*")])
6378
6379 (define_insn "*fix<uns>_trunc<SFDF:mode>si2_p8"
6380 [(set (match_operand:SI 0 "gpc_reg_operand" "=d,wa")
6381 (any_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d,wa")))]
6382 "TARGET_DIRECT_MOVE"
6383 "@
6384 fctiw<u>z %0,%1
6385 xscvdp<su>xws %x0,%x1"
6386 [(set_attr "type" "fp")])
6387
6388 ;; Keep the convert and store together through register allocation to prevent
6389 ;; the register allocator from getting clever and doing a direct move to a GPR
6390 ;; and then store for reg+offset stores.
6391 (define_insn_and_split "*fix<uns>_trunc<SFDF:mode><QHSI:mode>2_mem"
6392 [(set (match_operand:QHSI 0 "memory_operand" "=Z")
6393 (any_fix:QHSI (match_operand:SFDF 1 "gpc_reg_operand" "wa")))
6394 (clobber (match_scratch:SI 2 "=wa"))]
6395 "(<QHSI:MODE>mode == SImode && TARGET_P8_VECTOR) || TARGET_P9_VECTOR"
6396 "#"
6397 "&& reload_completed"
6398 [(set (match_dup 2)
6399 (any_fix:SI (match_dup 1)))
6400 (set (match_dup 0)
6401 (match_dup 3))]
6402 {
6403 operands[3] = (<QHSI:MODE>mode == SImode
6404 ? operands[2]
6405 : gen_rtx_REG (<QHSI:MODE>mode, REGNO (operands[2])));
6406 })
6407
6408 (define_expand "fixuns_trunc<mode>si2"
6409 [(set (match_operand:SI 0 "gpc_reg_operand")
6410 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand")))]
6411 "TARGET_HARD_FLOAT && TARGET_FCTIWUZ && TARGET_STFIWX"
6412 {
6413 if (!TARGET_P8_VECTOR)
6414 {
6415 emit_insn (gen_fixuns_trunc<mode>si2_stfiwx (operands[0], operands[1]));
6416 DONE;
6417 }
6418 })
6419
6420 (define_insn_and_split "fixuns_trunc<mode>si2_stfiwx"
6421 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
6422 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
6423 (clobber (match_scratch:DI 2 "=d"))]
6424 "TARGET_HARD_FLOAT && TARGET_FCTIWUZ
6425 && TARGET_STFIWX && can_create_pseudo_p ()
6426 && !TARGET_P8_VECTOR"
6427 "#"
6428 "&& 1"
6429 [(pc)]
6430 {
6431 rtx dest = operands[0];
6432 rtx src = operands[1];
6433 rtx tmp = operands[2];
6434
6435 if (GET_CODE (tmp) == SCRATCH)
6436 tmp = gen_reg_rtx (DImode);
6437
6438 emit_insn (gen_fctiwuz_<mode> (tmp, src));
6439 if (MEM_P (dest))
6440 {
6441 dest = rs6000_force_indexed_or_indirect_mem (dest);
6442 emit_insn (gen_stfiwx (dest, tmp));
6443 DONE;
6444 }
6445 else if (TARGET_POWERPC64 && TARGET_DIRECT_MOVE)
6446 {
6447 dest = gen_lowpart (DImode, dest);
6448 emit_move_insn (dest, tmp);
6449 DONE;
6450 }
6451 else
6452 {
6453 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
6454 emit_insn (gen_stfiwx (stack, tmp));
6455 emit_move_insn (dest, stack);
6456 DONE;
6457 }
6458 }
6459 [(set_attr "length" "12")
6460 (set_attr "type" "fp")])
6461
6462 (define_insn "fixuns_trunc<mode>di2"
6463 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa")
6464 (unsigned_fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "d,wa")))]
6465 "TARGET_HARD_FLOAT && TARGET_FCTIDUZ"
6466 "@
6467 fctiduz %0,%1
6468 xscvdpuxds %x0,%x1"
6469 [(set_attr "type" "fp")])
6470
6471 (define_insn "rs6000_mtfsb0"
6472 [(unspec_volatile [(match_operand:SI 0 "u5bit_cint_operand" "n")]
6473 UNSPECV_MTFSB0)]
6474 "TARGET_HARD_FLOAT"
6475 "mtfsb0 %0"
6476 [(set_attr "type" "fp")])
6477
6478 (define_insn "rs6000_mtfsb1"
6479 [(unspec_volatile [(match_operand:SI 0 "u5bit_cint_operand" "n")]
6480 UNSPECV_MTFSB1)]
6481 "TARGET_HARD_FLOAT"
6482 "mtfsb1 %0"
6483 [(set_attr "type" "fp")])
6484
6485 (define_insn "rs6000_mffscrn"
6486 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
6487 (unspec_volatile:DF [(match_operand:DF 1 "gpc_reg_operand" "d")]
6488 UNSPECV_MFFSCRN))]
6489 "TARGET_P9_MISC"
6490 "mffscrn %0,%1"
6491 [(set_attr "type" "fp")])
6492
6493 (define_insn "rs6000_mffscrni"
6494 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
6495 (unspec_volatile:DF [(match_operand:SI 1 "const_0_to_3_operand" "n")]
6496 UNSPECV_MFFSCRN))]
6497 "TARGET_P9_MISC"
6498 "mffscrni %0,%1"
6499 [(set_attr "type" "fp")])
6500
6501 (define_insn "rs6000_mffscdrn"
6502 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
6503 (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFSCDRN))
6504 (use (match_operand:DF 1 "gpc_reg_operand" "d"))]
6505 "TARGET_P9_MISC"
6506 "mffscdrn %0,%1"
6507 [(set_attr "type" "fp")])
6508
6509 (define_expand "rs6000_set_fpscr_rn"
6510 [(use (match_operand:DF 0 "gpc_reg_operand"))
6511 (use (match_operand:SI 1 "reg_or_cint_operand"))]
6512 "TARGET_HARD_FLOAT"
6513 {
6514 rtx tmp_df = gen_reg_rtx (DFmode);
6515
6516 /* The floating point rounding control bits are FPSCR[62:63]. Put the
6517 new rounding mode bits from operands[0][62:63] into FPSCR[62:63]. */
6518 if (TARGET_P9_MISC)
6519 {
6520 if (const_0_to_3_operand (operands[1], VOIDmode))
6521 emit_insn (gen_rs6000_mffscrni (tmp_df, operands[1]));
6522 else
6523 {
6524 rtx op1 = convert_to_mode (DImode, operands[1], false);
6525 rtx src_df = simplify_gen_subreg (DFmode, op1, DImode, 0);
6526 emit_insn (gen_rs6000_mffscrn (tmp_df, src_df));
6527 }
6528 emit_move_insn (operands[0], tmp_df);
6529 DONE;
6530 }
6531
6532 /* Emulate the behavior of the mffscrni, mffscrn instructions for earlier
6533 ISAs. Return bits 29:31 (DRN) and bits 56:63 (VE, OE, UE, ZE, XE, NI,
6534 RN) from the FPSCR. Set the RN field based on the value in operands[1].
6535 */
6536
6537 /* Get the current FPSCR fields, bits 29:31 (DRN) and bits 56:63 (VE, OE, UE,
6538 ZE, XE, NI, RN) from the FPSCR and return them. */
6539
6540 emit_insn (gen_rs6000_mffs (tmp_df));
6541 rtx orig_df_in_di = simplify_gen_subreg (DImode, tmp_df, DFmode, 0);
6542 rtx tmp_di1 = gen_reg_rtx (DImode);
6543 emit_insn (gen_anddi3 (tmp_di1, orig_df_in_di,
6544 GEN_INT (0x00000007000000FFULL)));
6545 rtx tmp_rtn = simplify_gen_subreg (DFmode, tmp_di1, DImode, 0);
6546 emit_move_insn (operands[0], tmp_rtn);
6547
6548 if (CONST_INT_P (operands[1]))
6549 {
6550 if ((INTVAL (operands[1]) & 0x1) == 0x1)
6551 emit_insn (gen_rs6000_mtfsb1 (GEN_INT (31)));
6552 else
6553 emit_insn (gen_rs6000_mtfsb0 (GEN_INT (31)));
6554
6555 if ((INTVAL (operands[1]) & 0x2) == 0x2)
6556 emit_insn (gen_rs6000_mtfsb1 (GEN_INT (30)));
6557 else
6558 emit_insn (gen_rs6000_mtfsb0 (GEN_INT (30)));
6559 }
6560 else
6561 {
6562 /* Extract new RN mode from operand. */
6563 rtx op1 = convert_to_mode (DImode, operands[1], false);
6564 rtx tmp_rn = gen_reg_rtx (DImode);
6565 emit_insn (gen_anddi3 (tmp_rn, op1, GEN_INT (3)));
6566
6567 /* Insert the new RN value from tmp_rn into FPSCR bit [62:63]. */
6568 rtx tmp_di1 = gen_reg_rtx (DImode);
6569 emit_insn (gen_anddi3 (tmp_di1, orig_df_in_di, GEN_INT (-4)));
6570 rtx tmp_di2 = gen_reg_rtx (DImode);
6571 emit_insn (gen_iordi3 (tmp_di2, tmp_di1, tmp_rn));
6572
6573 /* Need to write to field k=15. The fields are [0:15]. Hence with
6574 L=0, W=0, FLM_i must be equal to 8, 16 = i + 8*(1-W). FLM is an
6575 8-bit field[0:7]. Need to set the bit that corresponds to the
6576 value of i that you want [0:7]. */
6577 tmp_df = simplify_gen_subreg (DFmode, tmp_di2, DImode, 0);
6578 emit_insn (gen_rs6000_mtfsf (GEN_INT (0x01), tmp_df));
6579 }
6580 DONE;
6581 })
6582
6583 (define_expand "rs6000_set_fpscr_drn"
6584 [(match_operand:DI 0 "gpc_reg_operand")]
6585 "TARGET_HARD_FLOAT"
6586 {
6587 rtx tmp_df = gen_reg_rtx (DFmode);
6588
6589 /* The decimal floating point rounding control bits are FPSCR[29:31]. Put the
6590 new rounding mode bits from operands[0][61:63] into FPSCR[29:31]. */
6591 if (TARGET_P9_MISC)
6592 {
6593 rtx src_df = gen_reg_rtx (DFmode);
6594
6595 emit_insn (gen_ashldi3 (operands[0], operands[0], GEN_INT (32)));
6596 src_df = simplify_gen_subreg (DFmode, operands[0], DImode, 0);
6597 emit_insn (gen_rs6000_mffscdrn (tmp_df, src_df));
6598 }
6599 else
6600 {
6601 rtx tmp_rn = gen_reg_rtx (DImode);
6602 rtx tmp_di = gen_reg_rtx (DImode);
6603
6604 /* Extract new DRN mode from operand. */
6605 emit_insn (gen_anddi3 (tmp_rn, operands[0], GEN_INT (0x7)));
6606 emit_insn (gen_ashldi3 (tmp_rn, tmp_rn, GEN_INT (32)));
6607
6608 /* Insert new RN mode into FSCPR. */
6609 emit_insn (gen_rs6000_mffs (tmp_df));
6610 tmp_di = simplify_gen_subreg (DImode, tmp_df, DFmode, 0);
6611 emit_insn (gen_anddi3 (tmp_di, tmp_di, GEN_INT (0xFFFFFFF8FFFFFFFFULL)));
6612 emit_insn (gen_iordi3 (tmp_di, tmp_di, tmp_rn));
6613
6614 /* Need to write to field 7. The fields are [0:15]. The equation to
6615 select the field is i + 8*(1-W). Hence with L=0 and W=1, need to set
6616 i to 0x1 to get field 7 where i selects the field. */
6617 tmp_df = simplify_gen_subreg (DFmode, tmp_di, DImode, 0);
6618 emit_insn (gen_rs6000_mtfsf_hi (GEN_INT (0x01), tmp_df));
6619 }
6620 DONE;
6621 })
6622
6623 ;; Here, we use (set (reg) (unspec:DI [(fix:SI ...)] UNSPEC_FCTIWZ))
6624 ;; rather than (set (subreg:SI (reg)) (fix:SI ...))
6625 ;; because the first makes it clear that operand 0 is not live
6626 ;; before the instruction.
6627 (define_insn "fctiwz_<mode>"
6628 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa")
6629 (unspec:DI [(fix:SI
6630 (match_operand:SFDF 1 "gpc_reg_operand" "d,wa"))]
6631 UNSPEC_FCTIWZ))]
6632 "TARGET_HARD_FLOAT"
6633 "@
6634 fctiwz %0,%1
6635 xscvdpsxws %x0,%x1"
6636 [(set_attr "type" "fp")])
6637
6638 (define_insn "fctiwuz_<mode>"
6639 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa")
6640 (unspec:DI [(unsigned_fix:SI
6641 (match_operand:SFDF 1 "gpc_reg_operand" "d,wa"))]
6642 UNSPEC_FCTIWUZ))]
6643 "TARGET_HARD_FLOAT && TARGET_FCTIWUZ"
6644 "@
6645 fctiwuz %0,%1
6646 xscvdpuxws %x0,%x1"
6647 [(set_attr "type" "fp")])
6648
6649 ;; Only optimize (float (fix x)) -> frz if we are in fast-math mode, since
6650 ;; since the friz instruction does not truncate the value if the floating
6651 ;; point value is < LONG_MIN or > LONG_MAX.
6652 (define_insn "*friz"
6653 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa")
6654 (float:DF (fix:DI (match_operand:DF 1 "gpc_reg_operand" "d,wa"))))]
6655 "TARGET_HARD_FLOAT && TARGET_FPRND
6656 && flag_unsafe_math_optimizations && !flag_trapping_math && TARGET_FRIZ"
6657 "@
6658 friz %0,%1
6659 xsrdpiz %x0,%x1"
6660 [(set_attr "type" "fp")])
6661
6662 ;; Opitmize converting SF/DFmode to signed SImode and back to SF/DFmode. This
6663 ;; optimization prevents on ISA 2.06 systems and earlier having to store the
6664 ;; value from the FPR/vector unit to the stack, load the value into a GPR, sign
6665 ;; extend it, store it back on the stack from the GPR, load it back into the
6666 ;; FP/vector unit to do the rounding. If we have direct move (ISA 2.07),
6667 ;; disable using store and load to sign/zero extend the value.
6668 (define_insn_and_split "*round32<mode>2_fprs"
6669 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
6670 (float:SFDF
6671 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
6672 (clobber (match_scratch:DI 2 "=d"))
6673 (clobber (match_scratch:DI 3 "=d"))]
6674 "TARGET_HARD_FLOAT
6675 && <SI_CONVERT_FP> && TARGET_LFIWAX && TARGET_STFIWX && TARGET_FCFID
6676 && !TARGET_DIRECT_MOVE && can_create_pseudo_p ()"
6677 "#"
6678 "&& 1"
6679 [(pc)]
6680 {
6681 rtx dest = operands[0];
6682 rtx src = operands[1];
6683 rtx tmp1 = operands[2];
6684 rtx tmp2 = operands[3];
6685 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
6686
6687 if (GET_CODE (tmp1) == SCRATCH)
6688 tmp1 = gen_reg_rtx (DImode);
6689 if (GET_CODE (tmp2) == SCRATCH)
6690 tmp2 = gen_reg_rtx (DImode);
6691
6692 emit_insn (gen_fctiwz_<mode> (tmp1, src));
6693 emit_insn (gen_stfiwx (stack, tmp1));
6694 emit_insn (gen_lfiwax (tmp2, stack));
6695 emit_insn (gen_floatdi<mode>2 (dest, tmp2));
6696 DONE;
6697 }
6698 [(set_attr "type" "fpload")
6699 (set_attr "length" "16")])
6700
6701 (define_insn_and_split "*roundu32<mode>2_fprs"
6702 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
6703 (unsigned_float:SFDF
6704 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
6705 (clobber (match_scratch:DI 2 "=d"))
6706 (clobber (match_scratch:DI 3 "=d"))]
6707 "TARGET_HARD_FLOAT
6708 && TARGET_LFIWZX && TARGET_STFIWX && TARGET_FCFIDU && !TARGET_DIRECT_MOVE
6709 && can_create_pseudo_p ()"
6710 "#"
6711 "&& 1"
6712 [(pc)]
6713 {
6714 rtx dest = operands[0];
6715 rtx src = operands[1];
6716 rtx tmp1 = operands[2];
6717 rtx tmp2 = operands[3];
6718 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
6719
6720 if (GET_CODE (tmp1) == SCRATCH)
6721 tmp1 = gen_reg_rtx (DImode);
6722 if (GET_CODE (tmp2) == SCRATCH)
6723 tmp2 = gen_reg_rtx (DImode);
6724
6725 emit_insn (gen_fctiwuz_<mode> (tmp1, src));
6726 emit_insn (gen_stfiwx (stack, tmp1));
6727 emit_insn (gen_lfiwzx (tmp2, stack));
6728 emit_insn (gen_floatdi<mode>2 (dest, tmp2));
6729 DONE;
6730 }
6731 [(set_attr "type" "fpload")
6732 (set_attr "length" "16")])
6733
6734 ;; No VSX equivalent to fctid
6735 (define_insn "lrint<mode>di2"
6736 [(set (match_operand:DI 0 "gpc_reg_operand" "=d")
6737 (unspec:DI [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
6738 UNSPEC_FCTID))]
6739 "TARGET_HARD_FLOAT && TARGET_FCTID"
6740 "fctid %0,%1"
6741 [(set_attr "type" "fp")])
6742
6743 (define_expand "lrint<mode>si2"
6744 [(set (match_operand:SI 0 "gpc_reg_operand" "=d")
6745 (unspec:SI [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
6746 UNSPEC_FCTIW))]
6747 "TARGET_HARD_FLOAT && TARGET_STFIWX"
6748 {
6749 /* For those old archs in which SImode can't be hold in float registers,
6750 call lrint<mode>si_di to put the result in DImode then convert it via
6751 stack. */
6752 if (!TARGET_POPCNTD)
6753 {
6754 rtx tmp = gen_reg_rtx (DImode);
6755 emit_insn (gen_lrint<mode>si_di (tmp, operands[1]));
6756 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
6757 emit_insn (gen_stfiwx (stack, tmp));
6758 emit_move_insn (operands[0], stack);
6759 DONE;
6760 }
6761 })
6762
6763 (define_insn "*lrint<mode>si"
6764 [(set (match_operand:SI 0 "gpc_reg_operand" "=d")
6765 (unspec:SI [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
6766 UNSPEC_FCTIW))]
6767 "TARGET_HARD_FLOAT && TARGET_POPCNTD"
6768 "fctiw %0,%1"
6769 [(set_attr "type" "fp")])
6770
6771 (define_insn "lrint<mode>si_di"
6772 [(set (match_operand:DI 0 "gpc_reg_operand" "=d")
6773 (unspec:DI [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
6774 UNSPEC_FCTIW))]
6775 "TARGET_HARD_FLOAT && !TARGET_POPCNTD"
6776 "fctiw %0,%1"
6777 [(set_attr "type" "fp")])
6778
6779 (define_insn "btrunc<mode>2"
6780 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,wa")
6781 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "d,wa")]
6782 UNSPEC_FRIZ))]
6783 "TARGET_HARD_FLOAT && TARGET_FPRND"
6784 "@
6785 friz %0,%1
6786 xsrdpiz %x0,%x1"
6787 [(set_attr "type" "fp")])
6788
6789 (define_insn "ceil<mode>2"
6790 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,wa")
6791 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "d,wa")]
6792 UNSPEC_FRIP))]
6793 "TARGET_HARD_FLOAT && TARGET_FPRND"
6794 "@
6795 frip %0,%1
6796 xsrdpip %x0,%x1"
6797 [(set_attr "type" "fp")])
6798
6799 (define_insn "floor<mode>2"
6800 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,wa")
6801 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "d,wa")]
6802 UNSPEC_FRIM))]
6803 "TARGET_HARD_FLOAT && TARGET_FPRND"
6804 "@
6805 frim %0,%1
6806 xsrdpim %x0,%x1"
6807 [(set_attr "type" "fp")])
6808
6809 ;; No VSX equivalent to frin
6810 (define_insn "round<mode>2"
6811 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<rreg2>")
6812 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
6813 UNSPEC_FRIN))]
6814 "TARGET_HARD_FLOAT && TARGET_FPRND"
6815 "frin %0,%1"
6816 [(set_attr "type" "fp")])
6817
6818 (define_insn "*xsrdpi<mode>2"
6819 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=wa")
6820 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "wa")]
6821 UNSPEC_XSRDPI))]
6822 "TARGET_HARD_FLOAT && TARGET_VSX"
6823 "xsrdpi %x0,%x1"
6824 [(set_attr "type" "fp")])
6825
6826 (define_expand "lround<mode>di2"
6827 [(set (match_dup 2)
6828 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand")]
6829 UNSPEC_XSRDPI))
6830 (set (match_operand:DI 0 "gpc_reg_operand")
6831 (unspec:DI [(match_dup 2)]
6832 UNSPEC_FCTID))]
6833 "TARGET_HARD_FLOAT && TARGET_VSX && TARGET_FCTID"
6834 {
6835 operands[2] = gen_reg_rtx (<MODE>mode);
6836 })
6837
6838 ; An UNSPEC is used so we don't have to support SImode in FP registers.
6839 (define_insn "stfiwx"
6840 [(set (match_operand:SI 0 "memory_operand" "=Z,Z")
6841 (unspec:SI [(match_operand:DI 1 "gpc_reg_operand" "d,wa")]
6842 UNSPEC_STFIWX))]
6843 "TARGET_PPC_GFXOPT"
6844 "@
6845 stfiwx %1,%y0
6846 stxsiwx %x1,%y0"
6847 [(set_attr "type" "fpstore")
6848 (set_attr "isa" "*,p8v")])
6849
6850 ;; If we don't have a direct conversion to single precision, don't enable this
6851 ;; conversion for 32-bit without fast math, because we don't have the insn to
6852 ;; generate the fixup swizzle to avoid double rounding problems.
6853 (define_expand "floatsisf2"
6854 [(set (match_operand:SF 0 "gpc_reg_operand")
6855 (float:SF (match_operand:SI 1 "nonimmediate_operand")))]
6856 "TARGET_HARD_FLOAT
6857 && ((TARGET_FCFIDS && TARGET_LFIWAX)
6858 || (TARGET_FCFID
6859 && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))"
6860 {
6861 if (TARGET_FCFIDS && TARGET_LFIWAX)
6862 {
6863 emit_insn (gen_floatsisf2_lfiwax (operands[0], operands[1]));
6864 DONE;
6865 }
6866 else if (TARGET_FCFID && TARGET_LFIWAX)
6867 {
6868 rtx dfreg = gen_reg_rtx (DFmode);
6869 emit_insn (gen_floatsidf2_lfiwax (dfreg, operands[1]));
6870 emit_insn (gen_truncdfsf2 (operands[0], dfreg));
6871 DONE;
6872 }
6873 else
6874 {
6875 rtx dreg = operands[1];
6876 if (!REG_P (dreg))
6877 dreg = force_reg (SImode, dreg);
6878 dreg = convert_to_mode (DImode, dreg, false);
6879 emit_insn (gen_floatdisf2 (operands[0], dreg));
6880 DONE;
6881 }
6882 })
6883
6884 (define_insn "floatdidf2"
6885 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa")
6886 (float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wa")))]
6887 "TARGET_FCFID && TARGET_HARD_FLOAT"
6888 "@
6889 fcfid %0,%1
6890 xscvsxddp %x0,%x1"
6891 [(set_attr "type" "fp")])
6892
6893 (define_insn "floatti<mode>2"
6894 [(set (match_operand:IEEE128 0 "vsx_register_operand" "=v")
6895 (float:IEEE128 (match_operand:TI 1 "vsx_register_operand" "v")))]
6896 "TARGET_POWER10"
6897 {
6898 return "xscvsqqp %0,%1";
6899 }
6900 [(set_attr "type" "fp")])
6901
6902 (define_insn "floatunsti<mode>2"
6903 [(set (match_operand:IEEE128 0 "vsx_register_operand" "=v")
6904 (unsigned_float:IEEE128 (match_operand:TI 1 "vsx_register_operand" "v")))]
6905 "TARGET_POWER10"
6906 {
6907 return "xscvuqqp %0,%1";
6908 }
6909 [(set_attr "type" "fp")])
6910
6911 (define_insn "fix_trunc<mode>ti2"
6912 [(set (match_operand:TI 0 "vsx_register_operand" "=v")
6913 (fix:TI (match_operand:IEEE128 1 "vsx_register_operand" "v")))]
6914 "TARGET_POWER10"
6915 {
6916 return "xscvqpsqz %0,%1";
6917 }
6918 [(set_attr "type" "fp")])
6919
6920 (define_insn "fixuns_trunc<mode>ti2"
6921 [(set (match_operand:TI 0 "vsx_register_operand" "=v")
6922 (unsigned_fix:TI (match_operand:IEEE128 1 "vsx_register_operand" "v")))]
6923 "TARGET_POWER10"
6924 {
6925 return "xscvqpuqz %0,%1";
6926 }
6927 [(set_attr "type" "fp")])
6928
6929 ; Allow the combiner to merge source memory operands to the conversion so that
6930 ; the optimizer/register allocator doesn't try to load the value too early in a
6931 ; GPR and then use store/load to move it to a FPR and suffer from a store-load
6932 ; hit. We will split after reload to avoid the trip through the GPRs
6933
6934 (define_insn_and_split "*floatdidf2_mem"
6935 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa")
6936 (float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
6937 (clobber (match_scratch:DI 2 "=d,wa"))]
6938 "TARGET_HARD_FLOAT && TARGET_FCFID"
6939 "#"
6940 "&& reload_completed"
6941 [(set (match_dup 2) (match_dup 1))
6942 (set (match_dup 0) (float:DF (match_dup 2)))]
6943 ""
6944 [(set_attr "length" "8")
6945 (set_attr "type" "fpload")])
6946
6947 (define_expand "floatunsdidf2"
6948 [(set (match_operand:DF 0 "gpc_reg_operand")
6949 (unsigned_float:DF
6950 (match_operand:DI 1 "gpc_reg_operand")))]
6951 "TARGET_HARD_FLOAT && TARGET_FCFIDU"
6952 "")
6953
6954 (define_insn "*floatunsdidf2_fcfidu"
6955 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa")
6956 (unsigned_float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wa")))]
6957 "TARGET_HARD_FLOAT && TARGET_FCFIDU"
6958 "@
6959 fcfidu %0,%1
6960 xscvuxddp %x0,%x1"
6961 [(set_attr "type" "fp")])
6962
6963 (define_insn_and_split "*floatunsdidf2_mem"
6964 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa")
6965 (unsigned_float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
6966 (clobber (match_scratch:DI 2 "=d,wa"))]
6967 "TARGET_HARD_FLOAT && (TARGET_FCFIDU || VECTOR_UNIT_VSX_P (DFmode))"
6968 "#"
6969 "&& reload_completed"
6970 [(set (match_dup 2) (match_dup 1))
6971 (set (match_dup 0) (unsigned_float:DF (match_dup 2)))]
6972 ""
6973 [(set_attr "length" "8")
6974 (set_attr "type" "fpload")])
6975
6976 (define_expand "floatdisf2"
6977 [(set (match_operand:SF 0 "gpc_reg_operand")
6978 (float:SF (match_operand:DI 1 "gpc_reg_operand")))]
6979 "TARGET_FCFID && TARGET_HARD_FLOAT
6980 && (TARGET_FCFIDS || TARGET_POWERPC64 || flag_unsafe_math_optimizations)"
6981 {
6982 if (!TARGET_FCFIDS)
6983 {
6984 rtx val = operands[1];
6985 if (!flag_unsafe_math_optimizations)
6986 {
6987 rtx label = gen_label_rtx ();
6988 val = gen_reg_rtx (DImode);
6989 emit_insn (gen_floatdisf2_internal2 (val, operands[1], label));
6990 emit_label (label);
6991 }
6992 emit_insn (gen_floatdisf2_internal1 (operands[0], val));
6993 DONE;
6994 }
6995 })
6996
6997 (define_insn "floatdisf2_fcfids"
6998 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wa")
6999 (float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wa")))]
7000 "TARGET_HARD_FLOAT && TARGET_FCFIDS"
7001 "@
7002 fcfids %0,%1
7003 xscvsxdsp %x0,%x1"
7004 [(set_attr "type" "fp")
7005 (set_attr "isa" "*,p8v")])
7006
7007 (define_insn_and_split "*floatdisf2_mem"
7008 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wa,wa")
7009 (float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
7010 (clobber (match_scratch:DI 2 "=d,d,wa"))]
7011 "TARGET_HARD_FLOAT && TARGET_FCFIDS"
7012 "#"
7013 "&& reload_completed"
7014 [(pc)]
7015 {
7016 emit_move_insn (operands[2], operands[1]);
7017 emit_insn (gen_floatdisf2_fcfids (operands[0], operands[2]));
7018 DONE;
7019 }
7020 [(set_attr "length" "8")
7021 (set_attr "isa" "*,p8v,p8v")])
7022
7023 ;; This is not IEEE compliant if rounding mode is "round to nearest".
7024 ;; If the DI->DF conversion is inexact, then it's possible to suffer
7025 ;; from double rounding.
7026 ;; Instead of creating a new cpu type for two FP operations, just use fp
7027 (define_insn_and_split "floatdisf2_internal1"
7028 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
7029 (float:SF (match_operand:DI 1 "gpc_reg_operand" "d")))
7030 (clobber (match_scratch:DF 2 "=d"))]
7031 "TARGET_FCFID && TARGET_HARD_FLOAT && !TARGET_FCFIDS"
7032 "#"
7033 "&& reload_completed"
7034 [(set (match_dup 2)
7035 (float:DF (match_dup 1)))
7036 (set (match_dup 0)
7037 (float_truncate:SF (match_dup 2)))]
7038 ""
7039 [(set_attr "length" "8")
7040 (set_attr "type" "fp")])
7041
7042 ;; Twiddles bits to avoid double rounding.
7043 ;; Bits that might be truncated when converting to DFmode are replaced
7044 ;; by a bit that won't be lost at that stage, but is below the SFmode
7045 ;; rounding position.
7046 (define_expand "floatdisf2_internal2"
7047 [(parallel [(set (match_dup 3) (ashiftrt:DI (match_operand:DI 1 "")
7048 (const_int 53)))
7049 (clobber (reg:DI CA_REGNO))])
7050 (set (match_operand:DI 0 "") (and:DI (match_dup 1)
7051 (const_int 2047)))
7052 (set (match_dup 3) (plus:DI (match_dup 3)
7053 (const_int 1)))
7054 (set (match_dup 0) (plus:DI (match_dup 0)
7055 (const_int 2047)))
7056 (set (match_dup 4) (compare:CCUNS (match_dup 3)
7057 (const_int 2)))
7058 (set (match_dup 0) (ior:DI (match_dup 0)
7059 (match_dup 1)))
7060 (set (match_dup 0) (and:DI (match_dup 0)
7061 (const_int -2048)))
7062 (set (pc) (if_then_else (geu (match_dup 4) (const_int 0))
7063 (label_ref (match_operand:DI 2 ""))
7064 (pc)))
7065 (set (match_dup 0) (match_dup 1))]
7066 "TARGET_POWERPC64 && TARGET_HARD_FLOAT && !TARGET_FCFIDS"
7067 {
7068 operands[3] = gen_reg_rtx (DImode);
7069 operands[4] = gen_reg_rtx (CCUNSmode);
7070 })
7071
7072 (define_expand "floatunsdisf2"
7073 [(set (match_operand:SF 0 "gpc_reg_operand")
7074 (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand")))]
7075 "TARGET_HARD_FLOAT && TARGET_FCFIDUS"
7076 "")
7077
7078 (define_insn "floatunsdisf2_fcfidus"
7079 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wa")
7080 (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wa")))]
7081 "TARGET_HARD_FLOAT && TARGET_FCFIDUS"
7082 "@
7083 fcfidus %0,%1
7084 xscvuxdsp %x0,%x1"
7085 [(set_attr "type" "fp")
7086 (set_attr "isa" "*,p8v")])
7087
7088 (define_insn_and_split "*floatunsdisf2_mem"
7089 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wa,wa")
7090 (unsigned_float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
7091 (clobber (match_scratch:DI 2 "=d,d,wa"))]
7092 "TARGET_HARD_FLOAT && TARGET_FCFIDUS"
7093 "#"
7094 "&& reload_completed"
7095 [(pc)]
7096 {
7097 emit_move_insn (operands[2], operands[1]);
7098 emit_insn (gen_floatunsdisf2_fcfidus (operands[0], operands[2]));
7099 DONE;
7100 }
7101 [(set_attr "type" "fpload")
7102 (set_attr "length" "8")
7103 (set_attr "isa" "*,p8v,p8v")])
7104
7105 ;; int fegetround(void)
7106 ;;
7107 ;; This expansion for the C99 function only expands for compatible
7108 ;; target libcs, because it needs to return one of FE_DOWNWARD,
7109 ;; FE_TONEAREST, FE_TOWARDZERO or FE_UPWARD with the values as defined
7110 ;; by the target libc, and since the libc is free to choose the values
7111 ;; (and they may differ from the hardware) and the expander needs to
7112 ;; know then beforehand, this expanded only expands for target libcs
7113 ;; that it can handle the values is knows.
7114 ;; Because of these restriction, this only expands on the desired
7115 ;; case and fallback to a call to libc otherwise.
7116 (define_expand "fegetroundsi"
7117 [(set (match_operand:SI 0 "gpc_reg_operand")
7118 (unspec_volatile:SI [(const_int 0)] UNSPECV_MFFSL))]
7119 "TARGET_HARD_FLOAT"
7120 {
7121 if (!OPTION_GLIBC)
7122 FAIL;
7123
7124 rtx tmp_df = gen_reg_rtx (DFmode);
7125 emit_insn (gen_rs6000_mffsl (tmp_df));
7126
7127 rtx tmp_di = simplify_gen_subreg (DImode, tmp_df, DFmode, 0);
7128 rtx tmp_di_2 = gen_reg_rtx (DImode);
7129 emit_insn (gen_anddi3 (tmp_di_2, tmp_di, GEN_INT (3)));
7130 rtx tmp_si = gen_reg_rtx (SImode);
7131 tmp_si = gen_lowpart (SImode, tmp_di_2);
7132 emit_move_insn (operands[0], tmp_si);
7133 DONE;
7134 })
7135
7136 ;; int feclearexcept(int excepts)
7137 ;;
7138 ;; This expansion for the C99 function only works when EXCEPTS is a
7139 ;; constant known at compile time and specifies any one of
7140 ;; FE_INEXACT, FE_DIVBYZERO, FE_UNDERFLOW and FE_OVERFLOW flags.
7141 ;; It doesn't handle values out of range, and always returns 0.
7142 ;; Note that FE_INVALID is unsupported because it maps to more than
7143 ;; one bit of the FPSCR register.
7144 ;; The FE_* are defined in the target libc, and since they are free to
7145 ;; choose the values and the expand needs to know them beforehand,
7146 ;; this expander only expands for target libcs that it can handle the
7147 ;; values it knows.
7148 ;; Because of these restrictions, this only expands on the desired
7149 ;; cases and fallback to a call to libc on any other case.
7150 (define_expand "feclearexceptsi"
7151 [(use (match_operand:SI 1 "const_int_operand" "n"))
7152 (set (match_operand:SI 0 "gpc_reg_operand")
7153 (const_int 0))]
7154 "TARGET_HARD_FLOAT"
7155 {
7156 if (!OPTION_GLIBC)
7157 FAIL;
7158
7159 unsigned int fe = INTVAL (operands[1]);
7160 if (fe != (fe & 0x1e000000))
7161 FAIL;
7162
7163 if (fe & 0x02000000) /* FE_INEXACT */
7164 emit_insn (gen_rs6000_mtfsb0 (gen_rtx_CONST_INT (SImode, 6)));
7165 if (fe & 0x04000000) /* FE_DIVBYZERO */
7166 emit_insn (gen_rs6000_mtfsb0 (gen_rtx_CONST_INT (SImode, 5)));
7167 if (fe & 0x08000000) /* FE_UNDERFLOW */
7168 emit_insn (gen_rs6000_mtfsb0 (gen_rtx_CONST_INT (SImode, 4)));
7169 if (fe & 0x10000000) /* FE_OVERFLOW */
7170 emit_insn (gen_rs6000_mtfsb0 (gen_rtx_CONST_INT (SImode, 3)));
7171
7172 emit_move_insn (operands[0], const0_rtx);
7173 DONE;
7174 })
7175
7176 ;; int feraiseexcept(int excepts)
7177 ;;
7178 ;; This expansion for the C99 function only works when excepts is a
7179 ;; constant known at compile time and specifies any one of
7180 ;; FE_INEXACT, FE_DIVBYZERO, FE_UNDERFLOW and FE_OVERFLOW flags.
7181 ;; It doesn't handle values out of range, and always returns 0.
7182 ;; Note that FE_INVALID is unsupported because it maps to more than
7183 ;; one bit of the FPSCR register.
7184 ;; The FE_* are defined in the target libc, and since they are free to
7185 ;; choose the values and the expand needs to know them beforehand,
7186 ;; this expander only expands for target libcs that it can handle the
7187 ;; values it knows.
7188 ;; Because of these restrictions, this only expands on the desired
7189 ;; cases and fallback to a call to libc on any other case.
7190 (define_expand "feraiseexceptsi"
7191 [(use (match_operand:SI 1 "const_int_operand" "n"))
7192 (set (match_operand:SI 0 "gpc_reg_operand")
7193 (const_int 0))]
7194 "TARGET_HARD_FLOAT"
7195 {
7196 if (!OPTION_GLIBC)
7197 FAIL;
7198
7199 unsigned int fe = INTVAL (operands[1]);
7200 if (fe != (fe & 0x1e000000))
7201 FAIL;
7202
7203 if (fe & 0x02000000) /* FE_INEXACT */
7204 emit_insn (gen_rs6000_mtfsb1 (gen_rtx_CONST_INT (SImode, 6)));
7205 if (fe & 0x04000000) /* FE_DIVBYZERO */
7206 emit_insn (gen_rs6000_mtfsb1 (gen_rtx_CONST_INT (SImode, 5)));
7207 if (fe & 0x08000000) /* FE_UNDERFLOW */
7208 emit_insn (gen_rs6000_mtfsb1 (gen_rtx_CONST_INT (SImode, 4)));
7209 if (fe & 0x10000000) /* FE_OVERFLOW */
7210 emit_insn (gen_rs6000_mtfsb1 (gen_rtx_CONST_INT (SImode, 3)));
7211
7212 emit_move_insn (operands[0], const0_rtx);
7213 DONE;
7214 })
7215 \f
7216 ;; Define the TImode operations that can be done in a small number
7217 ;; of instructions. The & constraints are to prevent the register
7218 ;; allocator from allocating registers that overlap with the inputs
7219 ;; (for example, having an input in 7,8 and an output in 6,7). We
7220 ;; also allow for the output being the same as one of the inputs.
7221
7222 (define_expand "addti3"
7223 [(set (match_operand:TI 0 "gpc_reg_operand")
7224 (plus:TI (match_operand:TI 1 "gpc_reg_operand")
7225 (match_operand:TI 2 "reg_or_short_operand")))]
7226 "TARGET_64BIT"
7227 {
7228 rtx lo0 = gen_lowpart (DImode, operands[0]);
7229 rtx lo1 = gen_lowpart (DImode, operands[1]);
7230 rtx lo2 = gen_lowpart (DImode, operands[2]);
7231 rtx hi0 = gen_highpart (DImode, operands[0]);
7232 rtx hi1 = gen_highpart (DImode, operands[1]);
7233 rtx hi2 = gen_highpart_mode (DImode, TImode, operands[2]);
7234
7235 if (!reg_or_short_operand (lo2, DImode))
7236 lo2 = force_reg (DImode, lo2);
7237 if (!adde_operand (hi2, DImode))
7238 hi2 = force_reg (DImode, hi2);
7239
7240 emit_insn (gen_adddi3_carry (lo0, lo1, lo2));
7241 emit_insn (gen_adddi3_carry_in (hi0, hi1, hi2));
7242 DONE;
7243 })
7244
7245 (define_expand "subti3"
7246 [(set (match_operand:TI 0 "gpc_reg_operand")
7247 (minus:TI (match_operand:TI 1 "reg_or_short_operand")
7248 (match_operand:TI 2 "gpc_reg_operand")))]
7249 "TARGET_64BIT"
7250 {
7251 rtx lo0 = gen_lowpart (DImode, operands[0]);
7252 rtx lo1 = gen_lowpart (DImode, operands[1]);
7253 rtx lo2 = gen_lowpart (DImode, operands[2]);
7254 rtx hi0 = gen_highpart (DImode, operands[0]);
7255 rtx hi1 = gen_highpart_mode (DImode, TImode, operands[1]);
7256 rtx hi2 = gen_highpart (DImode, operands[2]);
7257
7258 if (!reg_or_short_operand (lo1, DImode))
7259 lo1 = force_reg (DImode, lo1);
7260 if (!adde_operand (hi1, DImode))
7261 hi1 = force_reg (DImode, hi1);
7262
7263 emit_insn (gen_subfdi3_carry (lo0, lo2, lo1));
7264 emit_insn (gen_subfdi3_carry_in (hi0, hi2, hi1));
7265 DONE;
7266 })
7267 \f
7268 ;; 128-bit logical operations expanders
7269
7270 (define_expand "and<mode>3"
7271 [(set (match_operand:BOOL_128 0 "vlogical_operand")
7272 (and:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")
7273 (match_operand:BOOL_128 2 "vlogical_operand")))]
7274 ""
7275 "")
7276
7277 (define_expand "ior<mode>3"
7278 [(set (match_operand:BOOL_128 0 "vlogical_operand")
7279 (ior:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")
7280 (match_operand:BOOL_128 2 "vlogical_operand")))]
7281 ""
7282 "")
7283
7284 (define_expand "xor<mode>3"
7285 [(set (match_operand:BOOL_128 0 "vlogical_operand")
7286 (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")
7287 (match_operand:BOOL_128 2 "vlogical_operand")))]
7288 ""
7289 "")
7290
7291 (define_expand "nor<mode>3"
7292 [(set (match_operand:BOOL_128 0 "vlogical_operand")
7293 (and:BOOL_128
7294 (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand"))
7295 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))))]
7296 ""
7297 "")
7298
7299 (define_expand "andc<mode>3"
7300 [(set (match_operand:BOOL_128 0 "vlogical_operand")
7301 (and:BOOL_128
7302 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))
7303 (match_operand:BOOL_128 1 "vlogical_operand")))]
7304 ""
7305 "")
7306
7307 ;; Power8 vector logical instructions.
7308 (define_expand "eqv<mode>3"
7309 [(set (match_operand:BOOL_128 0 "vlogical_operand")
7310 (not:BOOL_128
7311 (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")
7312 (match_operand:BOOL_128 2 "vlogical_operand"))))]
7313 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
7314 "")
7315
7316 ;; Rewrite nand into canonical form
7317 (define_expand "nand<mode>3"
7318 [(set (match_operand:BOOL_128 0 "vlogical_operand")
7319 (ior:BOOL_128
7320 (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand"))
7321 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))))]
7322 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
7323 "")
7324
7325 ;; The canonical form is to have the negated element first, so we need to
7326 ;; reverse arguments.
7327 (define_expand "orc<mode>3"
7328 [(set (match_operand:BOOL_128 0 "vlogical_operand")
7329 (ior:BOOL_128
7330 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))
7331 (match_operand:BOOL_128 1 "vlogical_operand")))]
7332 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
7333 "")
7334
7335 ;; 128-bit logical operations insns and split operations
7336 (define_insn_and_split "*and<mode>3_internal"
7337 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
7338 (and:BOOL_128
7339 (match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
7340 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")))]
7341 ""
7342 {
7343 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
7344 return "xxland %x0,%x1,%x2";
7345
7346 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
7347 return "vand %0,%1,%2";
7348
7349 return "#";
7350 }
7351 "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
7352 [(const_int 0)]
7353 {
7354 rs6000_split_logical (operands, AND, false, false, false);
7355 DONE;
7356 }
7357 [(set (attr "type")
7358 (if_then_else
7359 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
7360 (const_string "veclogical")
7361 (const_string "integer")))
7362 (set (attr "length")
7363 (if_then_else
7364 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
7365 (const_string "4")
7366 (if_then_else
7367 (match_test "TARGET_POWERPC64")
7368 (const_string "8")
7369 (const_string "16"))))])
7370
7371 ;; 128-bit IOR/XOR
7372 (define_insn_and_split "*bool<mode>3_internal"
7373 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
7374 (match_operator:BOOL_128 3 "boolean_or_operator"
7375 [(match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
7376 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")]))]
7377 ""
7378 {
7379 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
7380 return "xxl%q3 %x0,%x1,%x2";
7381
7382 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
7383 return "v%q3 %0,%1,%2";
7384
7385 return "#";
7386 }
7387 "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
7388 [(const_int 0)]
7389 {
7390 rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, false);
7391 DONE;
7392 }
7393 [(set (attr "type")
7394 (if_then_else
7395 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
7396 (const_string "veclogical")
7397 (const_string "integer")))
7398 (set (attr "length")
7399 (if_then_else
7400 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
7401 (const_string "4")
7402 (if_then_else
7403 (match_test "TARGET_POWERPC64")
7404 (const_string "8")
7405 (const_string "16"))))])
7406
7407 ;; 128-bit ANDC/ORC
7408 (define_insn_and_split "*boolc<mode>3_internal1"
7409 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
7410 (match_operator:BOOL_128 3 "boolean_operator"
7411 [(not:BOOL_128
7412 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))
7413 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")]))]
7414 "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
7415 {
7416 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
7417 return "xxl%q3 %x0,%x1,%x2";
7418
7419 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
7420 return "v%q3 %0,%1,%2";
7421
7422 return "#";
7423 }
7424 "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
7425 && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
7426 [(const_int 0)]
7427 {
7428 rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
7429 DONE;
7430 }
7431 [(set (attr "type")
7432 (if_then_else
7433 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
7434 (const_string "veclogical")
7435 (const_string "integer")))
7436 (set (attr "length")
7437 (if_then_else
7438 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
7439 (const_string "4")
7440 (if_then_else
7441 (match_test "TARGET_POWERPC64")
7442 (const_string "8")
7443 (const_string "16"))))])
7444
7445 (define_insn_and_split "*boolc<mode>3_internal2"
7446 [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
7447 (match_operator:TI2 3 "boolean_operator"
7448 [(not:TI2
7449 (match_operand:TI2 2 "int_reg_operand" "r,0,r"))
7450 (match_operand:TI2 1 "int_reg_operand" "r,r,0")]))]
7451 "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
7452 "#"
7453 "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
7454 [(const_int 0)]
7455 {
7456 rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
7457 DONE;
7458 }
7459 [(set_attr "type" "integer")
7460 (set (attr "length")
7461 (if_then_else
7462 (match_test "TARGET_POWERPC64")
7463 (const_string "8")
7464 (const_string "16")))])
7465
7466 ;; 128-bit NAND/NOR
7467 (define_insn_and_split "*boolcc<mode>3_internal1"
7468 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
7469 (match_operator:BOOL_128 3 "boolean_operator"
7470 [(not:BOOL_128
7471 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>"))
7472 (not:BOOL_128
7473 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))]))]
7474 "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
7475 {
7476 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
7477 return "xxl%q3 %x0,%x1,%x2";
7478
7479 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
7480 return "v%q3 %0,%1,%2";
7481
7482 return "#";
7483 }
7484 "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
7485 && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
7486 [(const_int 0)]
7487 {
7488 rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
7489 DONE;
7490 }
7491 [(set (attr "type")
7492 (if_then_else
7493 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
7494 (const_string "veclogical")
7495 (const_string "integer")))
7496 (set (attr "length")
7497 (if_then_else
7498 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
7499 (const_string "4")
7500 (if_then_else
7501 (match_test "TARGET_POWERPC64")
7502 (const_string "8")
7503 (const_string "16"))))])
7504
7505 (define_insn_and_split "*boolcc<mode>3_internal2"
7506 [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
7507 (match_operator:TI2 3 "boolean_operator"
7508 [(not:TI2
7509 (match_operand:TI2 1 "int_reg_operand" "r,0,r"))
7510 (not:TI2
7511 (match_operand:TI2 2 "int_reg_operand" "r,r,0"))]))]
7512 "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
7513 "#"
7514 "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
7515 [(const_int 0)]
7516 {
7517 rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
7518 DONE;
7519 }
7520 [(set_attr "type" "integer")
7521 (set (attr "length")
7522 (if_then_else
7523 (match_test "TARGET_POWERPC64")
7524 (const_string "8")
7525 (const_string "16")))])
7526
7527
7528 ;; 128-bit EQV
7529 (define_insn_and_split "*eqv<mode>3_internal1"
7530 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
7531 (not:BOOL_128
7532 (xor:BOOL_128
7533 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")
7534 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))))]
7535 "TARGET_P8_VECTOR"
7536 {
7537 if (vsx_register_operand (operands[0], <MODE>mode))
7538 return "xxleqv %x0,%x1,%x2";
7539
7540 return "#";
7541 }
7542 "TARGET_P8_VECTOR && reload_completed
7543 && int_reg_operand (operands[0], <MODE>mode)"
7544 [(const_int 0)]
7545 {
7546 rs6000_split_logical (operands, XOR, true, false, false);
7547 DONE;
7548 }
7549 [(set (attr "type")
7550 (if_then_else
7551 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
7552 (const_string "veclogical")
7553 (const_string "integer")))
7554 (set (attr "length")
7555 (if_then_else
7556 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
7557 (const_string "4")
7558 (if_then_else
7559 (match_test "TARGET_POWERPC64")
7560 (const_string "8")
7561 (const_string "16"))))])
7562
7563 (define_insn_and_split "*eqv<mode>3_internal2"
7564 [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
7565 (not:TI2
7566 (xor:TI2
7567 (match_operand:TI2 1 "int_reg_operand" "r,0,r")
7568 (match_operand:TI2 2 "int_reg_operand" "r,r,0"))))]
7569 "!TARGET_P8_VECTOR"
7570 "#"
7571 "reload_completed && !TARGET_P8_VECTOR"
7572 [(const_int 0)]
7573 {
7574 rs6000_split_logical (operands, XOR, true, false, false);
7575 DONE;
7576 }
7577 [(set_attr "type" "integer")
7578 (set (attr "length")
7579 (if_then_else
7580 (match_test "TARGET_POWERPC64")
7581 (const_string "8")
7582 (const_string "16")))])
7583
7584 ;; 128-bit one's complement
7585 (define_insn_and_split "one_cmpl<mode>2"
7586 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
7587 (not:BOOL_128
7588 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_UNARY>")))]
7589 ""
7590 {
7591 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
7592 return "xxlnor %x0,%x1,%x1";
7593
7594 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
7595 return "vnor %0,%1,%1";
7596
7597 return "#";
7598 }
7599 "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
7600 [(const_int 0)]
7601 {
7602 rs6000_split_logical (operands, NOT, false, false, false);
7603 DONE;
7604 }
7605 [(set (attr "type")
7606 (if_then_else
7607 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
7608 (const_string "veclogical")
7609 (const_string "integer")))
7610 (set (attr "length")
7611 (if_then_else
7612 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
7613 (const_string "4")
7614 (if_then_else
7615 (match_test "TARGET_POWERPC64")
7616 (const_string "8")
7617 (const_string "16"))))])
7618
7619 \f
7620 ;; Now define ways of moving data around.
7621
7622 ;; Set up a register with a value from the GOT table
7623
7624 (define_expand "movsi_got"
7625 [(set (match_operand:SI 0 "gpc_reg_operand")
7626 (unspec:SI [(match_operand:SI 1 "got_operand")
7627 (match_dup 2)] UNSPEC_MOVSI_GOT))]
7628 "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
7629 {
7630 if (GET_CODE (operands[1]) == CONST)
7631 {
7632 rtx offset = const0_rtx;
7633 HOST_WIDE_INT value;
7634
7635 operands[1] = eliminate_constant_term (XEXP (operands[1], 0), &offset);
7636 value = INTVAL (offset);
7637 if (value != 0)
7638 {
7639 rtx tmp = (!can_create_pseudo_p ()
7640 ? operands[0]
7641 : gen_reg_rtx (Pmode));
7642 emit_insn (gen_movsi_got (tmp, operands[1]));
7643 emit_insn (gen_addsi3 (operands[0], tmp, offset));
7644 DONE;
7645 }
7646 }
7647
7648 operands[2] = rs6000_got_register (operands[1]);
7649 })
7650
7651 (define_insn "*movsi_got_internal"
7652 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
7653 (unspec:SI [(match_operand:SI 1 "got_no_const_operand" "")
7654 (match_operand:SI 2 "gpc_reg_operand" "b")]
7655 UNSPEC_MOVSI_GOT))]
7656 "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
7657 "lwz %0,%a1@got(%2)"
7658 [(set_attr "type" "load")])
7659
7660 ;; Used by sched, shorten_branches and final when the GOT pseudo reg
7661 ;; didn't get allocated to a hard register.
7662 (define_split
7663 [(set (match_operand:SI 0 "gpc_reg_operand")
7664 (unspec:SI [(match_operand:SI 1 "got_no_const_operand")
7665 (match_operand:SI 2 "memory_operand")]
7666 UNSPEC_MOVSI_GOT))]
7667 "DEFAULT_ABI == ABI_V4
7668 && flag_pic == 1
7669 && reload_completed"
7670 [(set (match_dup 0) (match_dup 2))
7671 (set (match_dup 0) (unspec:SI [(match_dup 1)(match_dup 0)]
7672 UNSPEC_MOVSI_GOT))]
7673 "")
7674
7675 ;; MR LA
7676 ;; LWZ LFIWZX LXSIWZX
7677 ;; STW STFIWX STXSIWX
7678 ;; LI LIS PLI #
7679 ;; XXLOR XXSPLTIB 0 XXSPLTIB -1 VSPLTISW
7680 ;; XXLXOR 0 XXLORC -1 P9 const
7681 ;; MTVSRWZ MFVSRWZ
7682 ;; MF%1 MT%0 NOP
7683
7684 (define_insn "*movsi_internal1"
7685 [(set (match_operand:SI 0 "nonimmediate_operand"
7686 "=r, r, d,
7687 r, d, v,
7688 m, ?Z, ?Z,
7689 r, r, r, r,
7690 wa, wa, wa, v,
7691 wa, v, v,
7692 wa, r,
7693 r, *h, *h")
7694 (match_operand:SI 1 "input_operand"
7695 "r, U, d,
7696 m, ?Z, ?Z,
7697 r, d, v,
7698 I, L, eI, n,
7699 wa, O, wM, wB,
7700 O, wM, wS,
7701 r, wa,
7702 *h, r, 0"))]
7703 "gpc_reg_operand (operands[0], SImode)
7704 || gpc_reg_operand (operands[1], SImode)"
7705 "@
7706 mr %0,%1
7707 la %0,%a1
7708 fmr %0,%1
7709 lwz%U1%X1 %0,%1
7710 lfiwzx %0,%y1
7711 lxsiwzx %x0,%y1
7712 stw%U0%X0 %1,%0
7713 stfiwx %1,%y0
7714 stxsiwx %x1,%y0
7715 li %0,%1
7716 lis %0,%v1
7717 li %0,%1
7718 #
7719 xxlor %x0,%x1,%x1
7720 xxspltib %x0,0
7721 xxspltib %x0,255
7722 vspltisw %0,%1
7723 xxlxor %x0,%x0,%x0
7724 xxlorc %x0,%x0,%x0
7725 #
7726 mtvsrwz %x0,%1
7727 mfvsrwz %0,%x1
7728 mf%1 %0
7729 mt%0 %1
7730 nop"
7731 [(set_attr "type"
7732 "*, *, fpsimple,
7733 load, fpload, fpload,
7734 store, fpstore, fpstore,
7735 *, *, *, *,
7736 veclogical, vecsimple, vecsimple, vecsimple,
7737 veclogical, veclogical, vecsimple,
7738 mtvsr, mfvsr,
7739 *, *, *")
7740 (set_attr "length"
7741 "*, *, *,
7742 *, *, *,
7743 *, *, *,
7744 *, *, *, 8,
7745 *, *, *, *,
7746 *, *, 8,
7747 *, *,
7748 *, *, *")
7749 (set_attr "isa"
7750 "*, *, *,
7751 *, p7, p8v,
7752 *, *, p8v,
7753 *, *, p10, *,
7754 p8v, p9v, p9v, p8v,
7755 p9v, p8v, p9v,
7756 p8v, p8v,
7757 *, *, *")])
7758
7759 ;; Like movsi, but adjust a SF value to be used in a SI context, i.e.
7760 ;; (set (reg:SI ...) (subreg:SI (reg:SF ...) 0))
7761 ;;
7762 ;; Because SF values are actually stored as DF values within the vector
7763 ;; registers, we need to convert the value to the vector SF format when
7764 ;; we need to use the bits in a union or similar cases. We only need
7765 ;; to do this transformation when the value is a vector register. Loads,
7766 ;; stores, and transfers within GPRs are assumed to be safe.
7767 ;;
7768 ;; This is a more general case of reload_gpr_from_vsxsf. That insn must have
7769 ;; no alternatives, because the call is created as part of secondary_reload,
7770 ;; and operand #2's register class is used to allocate the temporary register.
7771 ;; This function is called before reload, and it creates the temporary as
7772 ;; needed.
7773
7774 ;; MR LWZ LFIWZX LXSIWZX STW
7775 ;; STFS STXSSP STXSSPX VSX->GPR VSX->VSX
7776 ;; MTVSRWZ
7777
7778 (define_insn_and_split "movsi_from_sf"
7779 [(set (match_operand:SI 0 "nonimmediate_operand"
7780 "=r, r, ?*d, ?*v, m,
7781 m, wY, Z, r, ?*wa,
7782 wa")
7783 (unspec:SI [(match_operand:SF 1 "input_operand"
7784 "r, m, Z, Z, r,
7785 f, v, wa, wa, wa,
7786 r")]
7787 UNSPEC_SI_FROM_SF))
7788 (clobber (match_scratch:V4SF 2
7789 "=X, X, X, X, X,
7790 X, X, X, wa, X,
7791 X"))]
7792 "TARGET_NO_SF_SUBREG
7793 && (register_operand (operands[0], SImode)
7794 || register_operand (operands[1], SFmode))"
7795 "@
7796 mr %0,%1
7797 lwz%U1%X1 %0,%1
7798 lfiwzx %0,%y1
7799 lxsiwzx %x0,%y1
7800 stw%U0%X0 %1,%0
7801 stfs%U0%X0 %1,%0
7802 stxssp %1,%0
7803 stxsspx %x1,%y0
7804 #
7805 xscvdpspn %x0,%x1
7806 mtvsrwz %x0,%1"
7807 "&& reload_completed
7808 && int_reg_operand (operands[0], SImode)
7809 && vsx_reg_sfsubreg_ok (operands[1], SFmode)"
7810 [(const_int 0)]
7811 {
7812 rtx op0 = operands[0];
7813 rtx op1 = operands[1];
7814 rtx op2 = operands[2];
7815 rtx op0_di = gen_rtx_REG (DImode, reg_or_subregno (op0));
7816 rtx op2_si = gen_rtx_REG (SImode, reg_or_subregno (op2));
7817
7818 emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
7819 emit_insn (gen_zero_extendsidi2 (op0_di, op2_si));
7820 DONE;
7821 }
7822 [(set_attr "type"
7823 "*, load, fpload, fpload, store,
7824 fpstore, fpstore, fpstore, mfvsr, fp,
7825 mtvsr")
7826 (set_attr "length"
7827 "*, *, *, *, *,
7828 *, *, *, 8, *,
7829 *")
7830 (set_attr "isa"
7831 "*, *, p8v, p8v, *,
7832 *, p9v, p8v, p8v, p8v,
7833 p8v")])
7834
7835 ;; movsi_from_sf with zero extension
7836 ;;
7837 ;; RLDICL LWZ LFIWZX LXSIWZX VSX->GPR
7838 ;; VSX->VSX MTVSRWZ
7839
7840 (define_insn_and_split "*movdi_from_sf_zero_ext"
7841 [(set (match_operand:DI 0 "gpc_reg_operand"
7842 "=r, r, ?*d, ?*v, r,
7843 ?v, wa")
7844 (zero_extend:DI
7845 (unspec:SI [(match_operand:SF 1 "input_operand"
7846 "r, m, Z, Z, wa,
7847 wa, r")]
7848 UNSPEC_SI_FROM_SF)))
7849 (clobber (match_scratch:V4SF 2
7850 "=X, X, X, X, wa,
7851 wa, X"))]
7852 "TARGET_DIRECT_MOVE_64BIT
7853 && (register_operand (operands[0], DImode)
7854 || register_operand (operands[1], SImode))"
7855 "@
7856 rldicl %0,%1,0,32
7857 lwz%U1%X1 %0,%1
7858 lfiwzx %0,%y1
7859 lxsiwzx %x0,%y1
7860 #
7861 #
7862 mtvsrwz %x0,%1"
7863 "&& reload_completed
7864 && register_operand (operands[0], DImode)
7865 && vsx_reg_sfsubreg_ok (operands[1], SFmode)"
7866 [(const_int 0)]
7867 {
7868 rtx op0 = operands[0];
7869 rtx op1 = operands[1];
7870 rtx op2 = operands[2];
7871 rtx op2_si = gen_rtx_REG (SImode, reg_or_subregno (op2));
7872
7873 emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
7874 emit_insn (gen_zero_extendsidi2 (op0, op2_si));
7875 DONE;
7876 }
7877 [(set_attr "type"
7878 "*, load, fpload, fpload, two,
7879 two, mtvsr")
7880 (set_attr "length"
7881 "*, *, *, *, 8,
7882 8, *")
7883 (set_attr "isa"
7884 "*, *, p8v, p8v, p8v,
7885 p9v, p8v")])
7886
7887 ;; Like movsi_from_sf, but combine a convert from DFmode to SFmode before
7888 ;; moving it to SImode. We cannot do a SFmode store without having to do the
7889 ;; conversion explicitly since that doesn't work in most cases if the input
7890 ;; isn't representable as SF. Use XSCVDPSP instead of XSCVDPSPN, since the
7891 ;; former handles cases where the input will not fit in a SFmode, and the
7892 ;; latter assumes the value has already been rounded.
7893 (define_insn "*movsi_from_df"
7894 [(set (match_operand:SI 0 "gpc_reg_operand" "=wa")
7895 (unspec:SI [(float_truncate:SF
7896 (match_operand:DF 1 "gpc_reg_operand" "wa"))]
7897 UNSPEC_SI_FROM_SF))]
7898 "TARGET_NO_SF_SUBREG"
7899 "xscvdpsp %x0,%x1"
7900 [(set_attr "type" "fp")])
7901
7902
7903 (define_code_iterator eqne [eq ne])
7904
7905 ;; "i == C" ==> "rotl(i,N) == rotl(C,N)"
7906 (define_insn_and_split "*rotate_on_cmpdi"
7907 [(set (pc)
7908 (if_then_else (eqne (match_operand:DI 1 "gpc_reg_operand" "r")
7909 (match_operand:DI 2 "const_int_operand" "n"))
7910 (label_ref (match_operand 0 ""))
7911 (pc)))
7912 (clobber (match_scratch:DI 3 "=r"))
7913 (clobber (match_scratch:CCUNS 4 "=y"))]
7914 "TARGET_POWERPC64 && num_insns_constant (operands[2], DImode) > 1
7915 && (can_be_rotated_to_positive_16bits (INTVAL (operands[2]))
7916 || can_be_rotated_to_negative_15bits (INTVAL (operands[2])))"
7917 "#"
7918 "&& 1"
7919 [(pc)]
7920 {
7921 bool sgn = false;
7922 unsigned HOST_WIDE_INT C = INTVAL (operands[2]);
7923 int rot;
7924
7925 /* cmpldi */
7926 if (!can_be_rotated_to_lowbits (C, 16, &rot))
7927 {
7928 /* cmpdi */
7929 sgn = true;
7930 bool res = can_be_rotated_to_lowbits (~C, 15, &rot);
7931 gcc_assert (res);
7932 }
7933
7934 rtx n = GEN_INT (rot);
7935
7936 /* i' = rotl (i, n) */
7937 rtx op0 = can_create_pseudo_p () ? gen_reg_rtx (DImode) : operands[3];
7938 emit_insn (gen_rtx_SET (op0, gen_rtx_ROTATE (DImode, operands[1], n)));
7939
7940 /* C' = rotl (C, n) */
7941 rtx op1 = GEN_INT ((C << rot) | (C >> (HOST_BITS_PER_WIDE_INT - rot)));
7942
7943 /* i' == C' */
7944 machine_mode comp_mode = sgn ? CCmode : CCUNSmode;
7945 rtx cc = can_create_pseudo_p () ? gen_reg_rtx (comp_mode) : operands[4];
7946 PUT_MODE (cc, comp_mode);
7947 emit_insn (gen_rtx_SET (cc, gen_rtx_COMPARE (comp_mode, op0, op1)));
7948 rtx cmp = gen_rtx_<eqne:CODE> (CCmode, cc, const0_rtx);
7949 rtx loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands[0]);
7950 emit_jump_insn (gen_rtx_SET (pc_rtx,
7951 gen_rtx_IF_THEN_ELSE (VOIDmode, cmp,
7952 loc_ref, pc_rtx)));
7953
7954 /* Keep the probability info for the prediction of the branch insn. */
7955 rtx note = find_reg_note (curr_insn, REG_BR_PROB, 0);
7956 if (note)
7957 {
7958 profile_probability prob
7959 = profile_probability::from_reg_br_prob_note (XINT (note, 0));
7960
7961 add_reg_br_prob_note (get_last_insn (), prob);
7962 }
7963
7964 DONE;
7965 })
7966
7967 ;; Split a load of a large constant into the appropriate two-insn
7968 ;; sequence.
7969
7970 (define_split
7971 [(set (match_operand:SI 0 "gpc_reg_operand")
7972 (match_operand:SI 1 "const_int_operand"))]
7973 "num_insns_constant (operands[1], SImode) > 1"
7974 [(pc)]
7975 {
7976 if (rs6000_emit_set_const (operands[0], operands[1]))
7977 DONE;
7978 else
7979 FAIL;
7980 })
7981
7982 ;; Split loading -128..127 to use XXSPLITB and VEXTSW2D
7983 (define_split
7984 [(set (match_operand:DI 0 "altivec_register_operand")
7985 (match_operand:DI 1 "xxspltib_constant_split"))]
7986 "TARGET_P9_VECTOR && reload_completed"
7987 [(const_int 0)]
7988 {
7989 rtx op0 = operands[0];
7990 rtx op1 = operands[1];
7991 int r = REGNO (op0);
7992 rtx op0_v16qi = gen_rtx_REG (V16QImode, r);
7993
7994 emit_insn (gen_xxspltib_v16qi (op0_v16qi, op1));
7995 emit_insn (gen_vsx_sign_extend_v16qi_si (operands[0], op0_v16qi));
7996 DONE;
7997 })
7998
7999 (define_insn "*mov<mode>_internal2"
8000 [(set (match_operand:CC 2 "cc_reg_operand" "=y,x,?y")
8001 (compare:CC (match_operand:WORD 1 "gpc_reg_operand" "0,r,r")
8002 (const_int 0)))
8003 (set (match_operand:WORD 0 "gpc_reg_operand" "=r,r,r") (match_dup 1))]
8004 ""
8005 "@
8006 cmp<wd>i %2,%0,0
8007 mr. %0,%1
8008 #"
8009 [(set_attr "type" "cmp,logical,cmp")
8010 (set_attr "dot" "yes")
8011 (set_attr "length" "4,4,8")])
8012
8013 (define_peephole2
8014 [(set (match_operand:CC 2 "cc_reg_operand")
8015 (compare:CC (match_operand:WORD 1 "int_reg_operand")
8016 (const_int 0)))
8017 (set (match_operand:WORD 0 "int_reg_operand")
8018 (match_dup 1))]
8019 "!cc_reg_not_cr0_operand (operands[2], CCmode)"
8020 [(parallel [(set (match_operand:CC 2 "cc_reg_operand" "=x")
8021 (compare:CC (match_operand:WORD 1 "int_reg_operand" "r")
8022 (const_int 0)))
8023 (set (match_operand:WORD 0 "int_reg_operand" "=r")
8024 (match_dup 1))])]
8025 ""
8026 )
8027
8028 (define_peephole2
8029 [(set (match_operand:WORD 0 "int_reg_operand")
8030 (match_operand:WORD 1 "int_reg_operand"))
8031 (set (match_operand:CC 2 "cc_reg_operand")
8032 (compare:CC (match_dup 1)
8033 (const_int 0)))]
8034 "!cc_reg_not_cr0_operand (operands[2], CCmode)"
8035 [(parallel [(set (match_operand:CC 2 "cc_reg_operand" "=x")
8036 (compare:CC (match_operand:GPR 1 "int_reg_operand" "r")
8037 (const_int 0)))
8038 (set (match_operand:WORD 0 "int_reg_operand" "=r")
8039 (match_dup 1))])]
8040 ""
8041 )
8042
8043 (define_split
8044 [(set (match_operand:CC 2 "cc_reg_not_cr0_operand")
8045 (compare:CC (match_operand:WORD 1 "gpc_reg_operand")
8046 (const_int 0)))
8047 (set (match_operand:WORD 0 "gpc_reg_operand") (match_dup 1))]
8048 "reload_completed"
8049 [(set (match_dup 0) (match_dup 1))
8050 (set (match_dup 2)
8051 (compare:CC (match_dup 0)
8052 (const_int 0)))]
8053 "")
8054 \f
8055 (define_expand "mov<mode>"
8056 [(set (match_operand:INT 0 "general_operand")
8057 (match_operand:INT 1 "any_operand"))]
8058 ""
8059 {
8060 rs6000_emit_move (operands[0], operands[1], <MODE>mode);
8061 DONE;
8062 })
8063
8064 ;; MR LHZ/LBZ LXSI*ZX STH/STB STXSI*X LI
8065 ;; XXLOR load 0 load -1 VSPLTI* # MFVSRWZ
8066 ;; MTVSRWZ MF%1 MT%1 NOP
8067 (define_insn "*mov<mode>_internal"
8068 [(set (match_operand:QHI 0 "nonimmediate_operand"
8069 "=r, r, wa, m, ?Z, r,
8070 wa, wa, wa, v, ?v, r,
8071 wa, r, *c*l, *h")
8072 (match_operand:QHI 1 "input_operand"
8073 "r, m, ?Z, r, wa, i,
8074 wa, O, wM, wB, wS, wa,
8075 r, *h, r, 0"))]
8076 "gpc_reg_operand (operands[0], <MODE>mode)
8077 || gpc_reg_operand (operands[1], <MODE>mode)"
8078 "@
8079 mr %0,%1
8080 l<wd>z%U1%X1 %0,%1
8081 lxsi<wd>zx %x0,%y1
8082 st<wd>%U0%X0 %1,%0
8083 stxsi<wd>x %x1,%y0
8084 li %0,%1
8085 xxlor %x0,%x1,%x1
8086 xxspltib %x0,0
8087 xxspltib %x0,255
8088 vspltis<wd> %0,%1
8089 #
8090 mfvsrwz %0,%x1
8091 mtvsrwz %x0,%1
8092 mf%1 %0
8093 mt%0 %1
8094 nop"
8095 [(set_attr "type"
8096 "*, load, fpload, store, fpstore, *,
8097 vecsimple, vecperm, vecperm, vecperm, vecperm, mfvsr,
8098 mtvsr, mfjmpr, mtjmpr, *")
8099 (set_attr "length"
8100 "*, *, *, *, *, *,
8101 *, *, *, *, 8, *,
8102 *, *, *, *")
8103 (set_attr "isa"
8104 "*, *, p9v, *, p9v, *,
8105 p9v, p9v, p9v, p9v, p9v, p9v,
8106 p9v, *, *, *")])
8107
8108 \f
8109 ;; Here is how to move condition codes around. When we store CC data in
8110 ;; an integer register or memory, we store just the high-order 4 bits.
8111 ;; This lets us not shift in the most common case of CR0.
8112 (define_expand "movcc"
8113 [(set (match_operand:CC 0 "nonimmediate_operand")
8114 (match_operand:CC 1 "nonimmediate_operand"))]
8115 ""
8116 "")
8117
8118 (define_mode_iterator CC_any [CC CCUNS CCEQ CCFP])
8119
8120 (define_insn "*movcc_<mode>"
8121 [(set (match_operand:CC_any 0 "nonimmediate_operand"
8122 "=y,x,?y,y,r,r,r,r, r,*c*l,r,m")
8123 (match_operand:CC_any 1 "general_operand"
8124 " y,r, r,O,x,y,r,I,*h, r,m,r"))]
8125 "register_operand (operands[0], <MODE>mode)
8126 || register_operand (operands[1], <MODE>mode)"
8127 "@
8128 mcrf %0,%1
8129 mtcrf 128,%1
8130 rlwinm %1,%1,%F0,0xffffffff\;mtcrf %R0,%1\;rlwinm %1,%1,%f0,0xffffffff
8131 crxor %0,%0,%0
8132 mfcr %0%Q1
8133 mfcr %0%Q1\;rlwinm %0,%0,%f1,0xf0000000
8134 mr %0,%1
8135 li %0,%1
8136 mf%1 %0
8137 mt%0 %1
8138 lwz%U1%X1 %0,%1
8139 stw%U0%X0 %1,%0"
8140 [(set_attr_alternative "type"
8141 [(const_string "cr_logical")
8142 (const_string "mtcr")
8143 (const_string "mtcr")
8144 (const_string "cr_logical")
8145 (if_then_else (match_test "TARGET_MFCRF")
8146 (const_string "mfcrf") (const_string "mfcr"))
8147 (if_then_else (match_test "TARGET_MFCRF")
8148 (const_string "mfcrf") (const_string "mfcr"))
8149 (const_string "integer")
8150 (const_string "integer")
8151 (const_string "mfjmpr")
8152 (const_string "mtjmpr")
8153 (const_string "load")
8154 (const_string "store")])
8155 (set_attr "length" "*,*,12,*,*,8,*,*,*,*,*,*")])
8156 \f
8157 ;; For floating-point, we normally deal with the floating-point registers
8158 ;; unless -msoft-float is used. The sole exception is that parameter passing
8159 ;; can produce floating-point values in fixed-point registers. Unless the
8160 ;; value is a simple constant or already in memory, we deal with this by
8161 ;; allocating memory and copying the value explicitly via that memory location.
8162
8163 ;; Move 32-bit binary/decimal floating point
8164 (define_expand "mov<mode>"
8165 [(set (match_operand:FMOVE32 0 "nonimmediate_operand")
8166 (match_operand:FMOVE32 1 "any_operand"))]
8167 "<fmove_ok>"
8168 {
8169 rs6000_emit_move (operands[0], operands[1], <MODE>mode);
8170 DONE;
8171 })
8172
8173 (define_split
8174 [(set (match_operand:FMOVE32 0 "gpc_reg_operand")
8175 (match_operand:FMOVE32 1 "const_double_operand"))]
8176 "reload_completed
8177 && ((REG_P (operands[0]) && REGNO (operands[0]) <= 31)
8178 || (SUBREG_P (operands[0])
8179 && REG_P (SUBREG_REG (operands[0]))
8180 && REGNO (SUBREG_REG (operands[0])) <= 31))"
8181 [(set (match_dup 2) (match_dup 3))]
8182 {
8183 long l;
8184
8185 <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
8186
8187 if (! TARGET_POWERPC64)
8188 operands[2] = operand_subword (operands[0], 0, 0, <MODE>mode);
8189 else
8190 operands[2] = gen_lowpart (SImode, operands[0]);
8191
8192 operands[3] = gen_int_mode (l, SImode);
8193 })
8194
8195 ;; Originally, we tried to keep movsf and movsd common, but the differences
8196 ;; addressing was making it rather difficult to hide with mode attributes. In
8197 ;; particular for SFmode, on ISA 2.07 (power8) systems, having the GPR store
8198 ;; before the VSX stores meant that the register allocator would tend to do a
8199 ;; direct move to the GPR (which involves conversion from scalar to
8200 ;; vector/memory formats) to save values in the traditional Altivec registers,
8201 ;; while SDmode had problems on power6 if the GPR store was not first due to
8202 ;; the power6 not having an integer store operation.
8203 ;;
8204 ;; LWZ LFS LXSSP LXSSPX STFS STXSSP
8205 ;; STXSSPX STW XXLXOR LI FMR XSCPSGNDP
8206 ;; MR MT<x> MF<x> NOP XXSPLTIDP
8207
8208 (define_insn "movsf_hardfloat"
8209 [(set (match_operand:SF 0 "nonimmediate_operand"
8210 "=!r, f, v, wa, m, wY,
8211 Z, m, wa, !r, f, wa,
8212 !r, *c*l, !r, *h, wa")
8213 (match_operand:SF 1 "input_operand"
8214 "m, m, wY, Z, f, v,
8215 wa, r, j, j, f, wa,
8216 r, r, *h, 0, eP"))]
8217 "(register_operand (operands[0], SFmode)
8218 || register_operand (operands[1], SFmode))
8219 && TARGET_HARD_FLOAT
8220 && (TARGET_ALLOW_SF_SUBREG
8221 || valid_sf_si_move (operands[0], operands[1], SFmode))"
8222 "@
8223 lwz%U1%X1 %0,%1
8224 lfs%U1%X1 %0,%1
8225 lxssp %0,%1
8226 lxsspx %x0,%y1
8227 stfs%U0%X0 %1,%0
8228 stxssp %1,%0
8229 stxsspx %x1,%y0
8230 stw%U0%X0 %1,%0
8231 xxlxor %x0,%x0,%x0
8232 li %0,0
8233 fmr %0,%1
8234 xscpsgndp %x0,%x1,%x1
8235 mr %0,%1
8236 mt%0 %1
8237 mf%1 %0
8238 nop
8239 #"
8240 [(set_attr "type"
8241 "load, fpload, fpload, fpload, fpstore, fpstore,
8242 fpstore, store, veclogical, integer, fpsimple, fpsimple,
8243 *, mtjmpr, mfjmpr, *, vecperm")
8244 (set_attr "isa"
8245 "*, *, p9v, p8v, *, p9v,
8246 p8v, *, *, *, *, *,
8247 *, *, *, *, p10")
8248 (set_attr "prefixed"
8249 "*, *, *, *, *, *,
8250 *, *, *, *, *, *,
8251 *, *, *, *, yes")])
8252
8253 ;; LWZ LFIWZX STW STFIWX MTVSRWZ MFVSRWZ
8254 ;; FMR MR MT%0 MF%1 NOP
8255 (define_insn "movsd_hardfloat"
8256 [(set (match_operand:SD 0 "nonimmediate_operand"
8257 "=!r, d, m, ?Z, ?d, ?r,
8258 f, !r, *c*l, !r, *h")
8259 (match_operand:SD 1 "input_operand"
8260 "m, ?Z, r, wx, r, d,
8261 f, r, r, *h, 0"))]
8262 "(register_operand (operands[0], SDmode)
8263 || register_operand (operands[1], SDmode))
8264 && TARGET_HARD_FLOAT"
8265 "@
8266 lwz%U1%X1 %0,%1
8267 lfiwzx %0,%y1
8268 stw%U0%X0 %1,%0
8269 stfiwx %1,%y0
8270 mtvsrwz %x0,%1
8271 mfvsrwz %0,%x1
8272 fmr %0,%1
8273 mr %0,%1
8274 mt%0 %1
8275 mf%1 %0
8276 nop"
8277 [(set_attr "type"
8278 "load, fpload, store, fpstore, mtvsr, mfvsr,
8279 fpsimple, *, mtjmpr, mfjmpr, *")
8280 (set_attr "isa"
8281 "*, p7, *, *, p8v, p8v,
8282 *, *, *, *, *")])
8283
8284 ;; MR MT%0 MF%0 LWZ STW LI
8285 ;; LIS G-const. F/n-const NOP
8286 (define_insn "*mov<mode>_softfloat"
8287 [(set (match_operand:FMOVE32 0 "nonimmediate_operand"
8288 "=r, *c*l, r, r, m, r,
8289 r, r, r, *h")
8290
8291 (match_operand:FMOVE32 1 "input_operand"
8292 "r, r, *h, m, r, I,
8293 L, G, Fn, 0"))]
8294
8295 "(gpc_reg_operand (operands[0], <MODE>mode)
8296 || gpc_reg_operand (operands[1], <MODE>mode))
8297 && TARGET_SOFT_FLOAT"
8298 "@
8299 mr %0,%1
8300 mt%0 %1
8301 mf%1 %0
8302 lwz%U1%X1 %0,%1
8303 stw%U0%X0 %1,%0
8304 li %0,%1
8305 lis %0,%v1
8306 #
8307 #
8308 nop"
8309 [(set_attr "type"
8310 "*, mtjmpr, mfjmpr, load, store, *,
8311 *, *, *, *")
8312
8313 (set_attr "length"
8314 "*, *, *, *, *, *,
8315 *, *, 8, *")])
8316
8317 ;; Like movsf, but adjust a SI value to be used in a SF context, i.e.
8318 ;; (set (reg:SF ...) (subreg:SF (reg:SI ...) 0))
8319 ;;
8320 ;; Because SF values are actually stored as DF values within the vector
8321 ;; registers, we need to convert the value to the vector SF format when
8322 ;; we need to use the bits in a union or similar cases. We only need
8323 ;; to do this transformation when the value is a vector register. Loads,
8324 ;; stores, and transfers within GPRs are assumed to be safe.
8325 ;;
8326 ;; This is a more general case of reload_vsx_from_gprsf. That insn must have
8327 ;; no alternatives, because the call is created as part of secondary_reload,
8328 ;; and operand #2's register class is used to allocate the temporary register.
8329 ;; This function is called before reload, and it creates the temporary as
8330 ;; needed.
8331
8332 ;; LWZ LFS LXSSP LXSSPX STW STFIWX
8333 ;; STXSIWX GPR->VSX VSX->GPR GPR->GPR
8334 (define_insn_and_split "movsf_from_si"
8335 [(set (match_operand:SF 0 "nonimmediate_operand"
8336 "=!r, f, v, wa, m, Z,
8337 Z, wa, ?r, !r")
8338 (unspec:SF [(match_operand:SI 1 "input_operand"
8339 "m, m, wY, Z, r, f,
8340 wa, r, wa, r")]
8341 UNSPEC_SF_FROM_SI))
8342 (clobber (match_scratch:DI 2
8343 "=X, X, X, X, X, X,
8344 X, r, X, X"))]
8345 "TARGET_NO_SF_SUBREG
8346 && (register_operand (operands[0], SFmode)
8347 || register_operand (operands[1], SImode))"
8348 "@
8349 lwz%U1%X1 %0,%1
8350 lfs%U1%X1 %0,%1
8351 lxssp %0,%1
8352 lxsspx %x0,%y1
8353 stw%U0%X0 %1,%0
8354 stfiwx %1,%y0
8355 stxsiwx %x1,%y0
8356 #
8357 mfvsrwz %0,%x1
8358 mr %0,%1"
8359
8360 "&& reload_completed
8361 && vsx_reg_sfsubreg_ok (operands[0], SFmode)
8362 && int_reg_operand_not_pseudo (operands[1], SImode)"
8363 [(const_int 0)]
8364 {
8365 rtx op0 = operands[0];
8366 rtx op1 = operands[1];
8367
8368 /* Move lowpart 32-bits from register for SFmode. */
8369 if (TARGET_P9_VECTOR)
8370 {
8371 /* Using mtvsrws;xscvspdpn. */
8372 rtx op0_v = gen_rtx_REG (V4SImode, REGNO (op0));
8373 emit_insn (gen_vsx_splat_v4si (op0_v, op1));
8374 emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0));
8375 }
8376 else
8377 {
8378 rtx op2 = operands[2];
8379 rtx op1_di = gen_rtx_REG (DImode, REGNO (op1));
8380
8381 /* Using sldi;mtvsrd;xscvspdpn. */
8382 emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32)));
8383 emit_insn (gen_p8_mtvsrd_sf (op0, op2));
8384 emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0));
8385 }
8386
8387 DONE;
8388 }
8389 [(set_attr "length"
8390 "*, *, *, *, *, *,
8391 *, 12, *, *")
8392 (set_attr "type"
8393 "load, fpload, fpload, fpload, store, fpstore,
8394 fpstore, vecfloat, mfvsr, *")
8395 (set_attr "isa"
8396 "*, *, p9v, p8v, *, *,
8397 p8v, p8v, p8v, *")])
8398
8399 ;; For extracting high part element from DImode register like:
8400 ;; {%1:SF=unspec[r122:DI>>0x20#0] 86;clobber scratch;}
8401 ;; split it before reload with "and mask" to avoid generating shift right
8402 ;; 32 bit then shift left 32 bit.
8403 (define_insn_and_split "movsf_from_si2_<code>"
8404 [(set (match_operand:SF 0 "gpc_reg_operand" "=wa")
8405 (unspec:SF
8406 [(match_operator:SI 3 "lowpart_subreg_operator"
8407 [(any_shiftrt:DI
8408 (match_operand:DI 1 "input_operand" "r")
8409 (const_int 32))])]
8410 UNSPEC_SF_FROM_SI))
8411 (clobber (match_scratch:DI 2 "=r"))]
8412 "TARGET_NO_SF_SUBREG"
8413 "#"
8414 "&& 1"
8415 [(const_int 0)]
8416 {
8417 if (GET_CODE (operands[2]) == SCRATCH)
8418 operands[2] = gen_reg_rtx (DImode);
8419
8420 rtx mask = GEN_INT (HOST_WIDE_INT_M1U << 32);
8421 emit_insn (gen_anddi3 (operands[2], operands[1], mask));
8422 emit_insn (gen_p8_mtvsrd_sf (operands[0], operands[2]));
8423 emit_insn (gen_vsx_xscvspdpn_directmove (operands[0], operands[0]));
8424 DONE;
8425 }
8426 [(set_attr "length" "12")
8427 (set_attr "type" "vecfloat")
8428 (set_attr "isa" "p8v")])
8429 \f
8430 ;; Move 64-bit binary/decimal floating point
8431 (define_expand "mov<mode>"
8432 [(set (match_operand:FMOVE64 0 "nonimmediate_operand")
8433 (match_operand:FMOVE64 1 "any_operand"))]
8434 ""
8435 {
8436 rs6000_emit_move (operands[0], operands[1], <MODE>mode);
8437 DONE;
8438 })
8439
8440 (define_split
8441 [(set (match_operand:FMOVE64 0 "gpc_reg_operand")
8442 (match_operand:FMOVE64 1 "const_int_operand"))]
8443 "! TARGET_POWERPC64 && reload_completed
8444 && ((REG_P (operands[0]) && REGNO (operands[0]) <= 31)
8445 || (SUBREG_P (operands[0])
8446 && REG_P (SUBREG_REG (operands[0]))
8447 && REGNO (SUBREG_REG (operands[0])) <= 31))"
8448 [(set (match_dup 2) (match_dup 4))
8449 (set (match_dup 3) (match_dup 1))]
8450 {
8451 int endian = (WORDS_BIG_ENDIAN == 0);
8452 HOST_WIDE_INT value = INTVAL (operands[1]);
8453
8454 operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
8455 operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
8456 operands[4] = GEN_INT (value >> 32);
8457 operands[1] = GEN_INT (sext_hwi (value, 32));
8458 })
8459
8460 (define_split
8461 [(set (match_operand:FMOVE64 0 "gpc_reg_operand")
8462 (match_operand:FMOVE64 1 "const_double_operand"))]
8463 "! TARGET_POWERPC64 && reload_completed
8464 && ((REG_P (operands[0]) && REGNO (operands[0]) <= 31)
8465 || (SUBREG_P (operands[0])
8466 && REG_P (SUBREG_REG (operands[0]))
8467 && REGNO (SUBREG_REG (operands[0])) <= 31))"
8468 [(set (match_dup 2) (match_dup 4))
8469 (set (match_dup 3) (match_dup 5))]
8470 {
8471 int endian = (WORDS_BIG_ENDIAN == 0);
8472 long l[2];
8473
8474 <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
8475
8476 operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
8477 operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
8478 operands[4] = gen_int_mode (l[endian], SImode);
8479 operands[5] = gen_int_mode (l[1 - endian], SImode);
8480 })
8481
8482 (define_split
8483 [(set (match_operand:FMOVE64 0 "gpc_reg_operand")
8484 (match_operand:FMOVE64 1 "const_double_operand"))]
8485 "TARGET_POWERPC64 && reload_completed
8486 && ((REG_P (operands[0]) && REGNO (operands[0]) <= 31)
8487 || (SUBREG_P (operands[0])
8488 && REG_P (SUBREG_REG (operands[0]))
8489 && REGNO (SUBREG_REG (operands[0])) <= 31))"
8490 [(set (match_dup 2) (match_dup 3))]
8491 {
8492 int endian = (WORDS_BIG_ENDIAN == 0);
8493 long l[2];
8494 HOST_WIDE_INT val;
8495
8496 <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
8497
8498 operands[2] = gen_lowpart (DImode, operands[0]);
8499 /* HIGHPART is lower memory address when WORDS_BIG_ENDIAN. */
8500 val = ((HOST_WIDE_INT)(unsigned long)l[endian] << 32
8501 | ((HOST_WIDE_INT)(unsigned long)l[1 - endian]));
8502
8503 operands[3] = gen_int_mode (val, DImode);
8504 })
8505
8506 ;; Don't have reload use general registers to load a constant. It is
8507 ;; less efficient than loading the constant into an FP register, since
8508 ;; it will probably be used there.
8509
8510 ;; The move constraints are ordered to prefer floating point registers before
8511 ;; general purpose registers to avoid doing a store and a load to get the value
8512 ;; into a floating point register when it is needed for a floating point
8513 ;; operation. Prefer traditional floating point registers over VSX registers,
8514 ;; since the D-form version of the memory instructions does not need a GPR for
8515 ;; reloading. ISA 3.0 (power9) adds D-form addressing for scalars to Altivec
8516 ;; registers.
8517
8518 ;; If we have FPR registers, rs6000_emit_move has moved all constants to memory,
8519 ;; except for 0.0 which can be created on VSX with an xor instruction.
8520
8521 ;; STFD LFD FMR LXSD STXSD
8522 ;; LXSD STXSD XXLOR XXLXOR GPR<-0
8523 ;; LWZ STW MR XXSPLTIDP
8524
8525
8526 (define_insn "*mov<mode>_hardfloat32"
8527 [(set (match_operand:FMOVE64 0 "nonimmediate_operand"
8528 "=m, d, d, <f64_p9>, wY,
8529 <f64_av>, Z, <f64_vsx>, <f64_vsx>, !r,
8530 Y, r, !r, wa")
8531 (match_operand:FMOVE64 1 "input_operand"
8532 "d, m, d, wY, <f64_p9>,
8533 Z, <f64_av>, <f64_vsx>, <zero_fp>, <zero_fp>,
8534 r, Y, r, eP"))]
8535 "! TARGET_POWERPC64 && TARGET_HARD_FLOAT
8536 && (gpc_reg_operand (operands[0], <MODE>mode)
8537 || gpc_reg_operand (operands[1], <MODE>mode))"
8538 "@
8539 stfd%U0%X0 %1,%0
8540 lfd%U1%X1 %0,%1
8541 fmr %0,%1
8542 lxsd %0,%1
8543 stxsd %1,%0
8544 lxsdx %x0,%y1
8545 stxsdx %x1,%y0
8546 xxlor %x0,%x1,%x1
8547 xxlxor %x0,%x0,%x0
8548 #
8549 #
8550 #
8551 #
8552 #"
8553 [(set_attr "type"
8554 "fpstore, fpload, fpsimple, fpload, fpstore,
8555 fpload, fpstore, veclogical, veclogical, two,
8556 store, load, two, vecperm")
8557 (set_attr "size" "64")
8558 (set_attr "length"
8559 "*, *, *, *, *,
8560 *, *, *, *, 8,
8561 8, 8, 8, *")
8562 (set_attr "isa"
8563 "*, *, *, p9v, p9v,
8564 p7v, p7v, *, *, *,
8565 *, *, *, p10")
8566 (set_attr "prefixed"
8567 "*, *, *, *, *,
8568 *, *, *, *, *,
8569 *, *, *, yes")])
8570
8571 ;; STW LWZ MR G-const H-const F-const
8572
8573 (define_insn "*mov<mode>_softfloat32"
8574 [(set (match_operand:FMOVE64 0 "nonimmediate_operand"
8575 "=Y, r, r, r, r, r")
8576
8577 (match_operand:FMOVE64 1 "input_operand"
8578 "r, Y, r, G, H, F"))]
8579
8580 "!TARGET_POWERPC64
8581 && (gpc_reg_operand (operands[0], <MODE>mode)
8582 || gpc_reg_operand (operands[1], <MODE>mode))"
8583 "#"
8584 [(set_attr "type"
8585 "store, load, two, *, *, *")
8586
8587 (set_attr "length"
8588 "8, 8, 8, 8, 12, 16")])
8589
8590 ; ld/std require word-aligned displacements -> 'Y' constraint.
8591 ; List Y->r and r->Y before r->r for reload.
8592
8593 ;; STFD LFD FMR LXSD STXSD
8594 ;; LXSDX STXSDX XXLOR XXLXOR LI 0
8595 ;; STD LD MR MT{CTR,LR} MF{CTR,LR}
8596 ;; NOP MFVSRD MTVSRD XXSPLTIDP
8597
8598 (define_insn "*mov<mode>_hardfloat64"
8599 [(set (match_operand:FMOVE64 0 "nonimmediate_operand"
8600 "=m, d, d, <f64_p9>, wY,
8601 <f64_av>, Z, <f64_vsx>, <f64_vsx>, !r,
8602 YZ, r, !r, *c*l, !r,
8603 *h, r, <f64_dm>, wa")
8604 (match_operand:FMOVE64 1 "input_operand"
8605 "d, m, d, wY, <f64_p9>,
8606 Z, <f64_av>, <f64_vsx>, <zero_fp>, <zero_fp>,
8607 r, YZ, r, r, *h,
8608 0, <f64_dm>, r, eP"))]
8609 "TARGET_POWERPC64 && TARGET_HARD_FLOAT
8610 && (gpc_reg_operand (operands[0], <MODE>mode)
8611 || gpc_reg_operand (operands[1], <MODE>mode))"
8612 "@
8613 stfd%U0%X0 %1,%0
8614 lfd%U1%X1 %0,%1
8615 fmr %0,%1
8616 lxsd %0,%1
8617 stxsd %1,%0
8618 lxsdx %x0,%y1
8619 stxsdx %x1,%y0
8620 xxlor %x0,%x1,%x1
8621 xxlxor %x0,%x0,%x0
8622 li %0,0
8623 std%U0%X0 %1,%0
8624 ld%U1%X1 %0,%1
8625 mr %0,%1
8626 mt%0 %1
8627 mf%1 %0
8628 nop
8629 mfvsrd %0,%x1
8630 mtvsrd %x0,%1
8631 #"
8632 [(set_attr "type"
8633 "fpstore, fpload, fpsimple, fpload, fpstore,
8634 fpload, fpstore, veclogical, veclogical, integer,
8635 store, load, *, mtjmpr, mfjmpr,
8636 *, mfvsr, mtvsr, vecperm")
8637 (set_attr "size" "64")
8638 (set_attr "isa"
8639 "*, *, *, p9v, p9v,
8640 p7v, p7v, *, *, *,
8641 *, *, *, *, *,
8642 *, p8v, p8v, p10")
8643 (set_attr "prefixed"
8644 "*, *, *, *, *,
8645 *, *, *, *, *,
8646 *, *, *, *, *,
8647 *, *, *, *")])
8648
8649 ;; STD LD MR MT<SPR> MF<SPR> G-const
8650 ;; H-const F-const Special
8651
8652 (define_insn "*mov<mode>_softfloat64"
8653 [(set (match_operand:FMOVE64 0 "nonimmediate_operand"
8654 "=Y, r, r, *c*l, r, r,
8655 r, r, *h")
8656
8657 (match_operand:FMOVE64 1 "input_operand"
8658 "r, Y, r, r, *h, G,
8659 H, F, 0"))]
8660
8661 "TARGET_POWERPC64 && TARGET_SOFT_FLOAT
8662 && (gpc_reg_operand (operands[0], <MODE>mode)
8663 || gpc_reg_operand (operands[1], <MODE>mode))"
8664 "@
8665 std%U0%X0 %1,%0
8666 ld%U1%X1 %0,%1
8667 mr %0,%1
8668 mt%0 %1
8669 mf%1 %0
8670 #
8671 #
8672 #
8673 nop"
8674 [(set_attr "type"
8675 "store, load, *, mtjmpr, mfjmpr, *,
8676 *, *, *")
8677
8678 (set_attr "length"
8679 "*, *, *, *, *, 8,
8680 12, 16, *")])
8681
8682 ;; Split the VSX prefixed instruction to support SFmode and DFmode scalar
8683 ;; constants that look like DFmode floating point values where both elements
8684 ;; are the same. The constant has to be expressible as a SFmode constant that
8685 ;; is not a SFmode denormal value.
8686 ;;
8687 ;; We don't need splitters for the 128-bit types, since the function
8688 ;; rs6000_output_move_128bit handles the generation of XXSPLTIDP.
8689 (define_insn "xxspltidp_<mode>_internal"
8690 [(set (match_operand:SFDF 0 "register_operand" "=wa")
8691 (unspec:SFDF [(match_operand:SI 1 "c32bit_cint_operand" "n")]
8692 UNSPEC_XXSPLTIDP_CONST))]
8693 "TARGET_POWER10"
8694 "xxspltidp %x0,%1"
8695 [(set_attr "type" "vecperm")
8696 (set_attr "prefixed" "yes")])
8697
8698 (define_insn "xxspltiw_<mode>_internal"
8699 [(set (match_operand:SFDF 0 "register_operand" "=wa")
8700 (unspec:SFDF [(match_operand:SI 1 "c32bit_cint_operand" "n")]
8701 UNSPEC_XXSPLTIW_CONST))]
8702 "TARGET_POWER10"
8703 "xxspltiw %x0,%1"
8704 [(set_attr "type" "vecperm")
8705 (set_attr "prefixed" "yes")])
8706
8707 (define_split
8708 [(set (match_operand:SFDF 0 "vsx_register_operand")
8709 (match_operand:SFDF 1 "vsx_prefixed_constant"))]
8710 "TARGET_POWER10"
8711 [(pc)]
8712 {
8713 rtx dest = operands[0];
8714 rtx src = operands[1];
8715 vec_const_128bit_type vsx_const;
8716
8717 if (!vec_const_128bit_to_bytes (src, <MODE>mode, &vsx_const))
8718 gcc_unreachable ();
8719
8720 unsigned imm = constant_generates_xxspltidp (&vsx_const);
8721 if (imm)
8722 {
8723 emit_insn (gen_xxspltidp_<mode>_internal (dest, GEN_INT (imm)));
8724 DONE;
8725 }
8726
8727 imm = constant_generates_xxspltiw (&vsx_const);
8728 if (imm)
8729 {
8730 emit_insn (gen_xxspltiw_<mode>_internal (dest, GEN_INT (imm)));
8731 DONE;
8732 }
8733
8734 else
8735 gcc_unreachable ();
8736 })
8737 \f
8738 (define_expand "mov<mode>"
8739 [(set (match_operand:FMOVE128 0 "general_operand")
8740 (match_operand:FMOVE128 1 "any_operand"))]
8741 ""
8742 {
8743 rs6000_emit_move (operands[0], operands[1], <MODE>mode);
8744 DONE;
8745 })
8746
8747 ;; It's important to list Y->r and r->Y before r->r because otherwise
8748 ;; reload, given m->r, will try to pick r->r and reload it, which
8749 ;; doesn't make progress.
8750
8751 ;; We can't split little endian direct moves of TDmode, because the words are
8752 ;; not swapped like they are for TImode or TFmode. Subregs therefore are
8753 ;; problematical. Don't allow direct move for this case.
8754
8755 ;; FPR load FPR store FPR move FPR zero GPR load
8756 ;; GPR zero GPR store GPR move MFVSRD MTVSRD
8757
8758 (define_insn_and_split "*mov<mode>_64bit_dm"
8759 [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand"
8760 "=m, d, d, d, Y,
8761 r, r, r, r, d")
8762
8763 (match_operand:FMOVE128_FPR 1 "input_operand"
8764 "d, m, d, <zero_fp>, r,
8765 <zero_fp>, Y, r, d, r"))]
8766
8767 "TARGET_HARD_FLOAT && TARGET_POWERPC64 && FLOAT128_2REG_P (<MODE>mode)
8768 && (<MODE>mode != TDmode || WORDS_BIG_ENDIAN)
8769 && (gpc_reg_operand (operands[0], <MODE>mode)
8770 || gpc_reg_operand (operands[1], <MODE>mode))"
8771 "#"
8772 "&& reload_completed"
8773 [(pc)]
8774 {
8775 rs6000_split_multireg_move (operands[0], operands[1]);
8776 DONE;
8777 }
8778 [(set_attr "length" "8")
8779 (set_attr "isa" "*,*,*,*,*,*,*,*,p8v,p8v")
8780 (set_attr "max_prefixed_insns" "2")
8781 (set_attr "num_insns" "2")])
8782
8783 (define_insn_and_split "*movtd_64bit_nodm"
8784 [(set (match_operand:TD 0 "nonimmediate_operand" "=m,d,d,Y,r,r")
8785 (match_operand:TD 1 "input_operand" "d,m,d,r,Y,r"))]
8786 "TARGET_HARD_FLOAT && TARGET_POWERPC64 && !WORDS_BIG_ENDIAN
8787 && (gpc_reg_operand (operands[0], TDmode)
8788 || gpc_reg_operand (operands[1], TDmode))"
8789 "#"
8790 "&& reload_completed"
8791 [(pc)]
8792 {
8793 rs6000_split_multireg_move (operands[0], operands[1]);
8794 DONE;
8795 }
8796 [(set_attr "length" "8,8,8,12,12,8")
8797 (set_attr "max_prefixed_insns" "2")
8798 (set_attr "num_insns" "2,2,2,3,3,2")])
8799
8800 (define_insn_and_split "*mov<mode>_32bit"
8801 [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand" "=m,d,d,d,Y,r,r")
8802 (match_operand:FMOVE128_FPR 1 "input_operand" "d,m,d,<zero_fp>,r,<zero_fp>Y,r"))]
8803 "TARGET_HARD_FLOAT && !TARGET_POWERPC64
8804 && (FLOAT128_2REG_P (<MODE>mode)
8805 || int_reg_operand_not_pseudo (operands[0], <MODE>mode)
8806 || int_reg_operand_not_pseudo (operands[1], <MODE>mode))
8807 && (gpc_reg_operand (operands[0], <MODE>mode)
8808 || gpc_reg_operand (operands[1], <MODE>mode))"
8809 "#"
8810 "&& reload_completed"
8811 [(pc)]
8812 {
8813 rs6000_split_multireg_move (operands[0], operands[1]);
8814 DONE;
8815 }
8816 [(set_attr "length" "8,8,8,8,20,20,16")])
8817
8818 (define_insn_and_split "*mov<mode>_softfloat"
8819 [(set (match_operand:FMOVE128 0 "nonimmediate_operand" "=Y,r,r,r")
8820 (match_operand:FMOVE128 1 "input_operand" "r,Y,F,r"))]
8821 "TARGET_SOFT_FLOAT
8822 && (gpc_reg_operand (operands[0], <MODE>mode)
8823 || gpc_reg_operand (operands[1], <MODE>mode))"
8824 "#"
8825 "&& reload_completed"
8826 [(pc)]
8827 {
8828 rs6000_split_multireg_move (operands[0], operands[1]);
8829 DONE;
8830 }
8831 [(set_attr_alternative "length"
8832 [(if_then_else (match_test "TARGET_POWERPC64")
8833 (const_string "8")
8834 (const_string "16"))
8835 (if_then_else (match_test "TARGET_POWERPC64")
8836 (const_string "8")
8837 (const_string "16"))
8838 (if_then_else (match_test "TARGET_POWERPC64")
8839 (const_string "16")
8840 (const_string "32"))
8841 (if_then_else (match_test "TARGET_POWERPC64")
8842 (const_string "8")
8843 (const_string "16"))])])
8844
8845 (define_expand "@extenddf<mode>2"
8846 [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
8847 (float_extend:FLOAT128 (match_operand:DF 1 "gpc_reg_operand")))]
8848 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8849 {
8850 if (FLOAT128_IEEE_P (<MODE>mode))
8851 rs6000_expand_float128_convert (operands[0], operands[1], false);
8852 else if (TARGET_VSX)
8853 emit_insn (gen_extenddf2_vsx (<MODE>mode, operands[0], operands[1]));
8854 else
8855 {
8856 rtx zero = gen_reg_rtx (DFmode);
8857 rs6000_emit_move (zero, CONST0_RTX (DFmode), DFmode);
8858
8859 emit_insn (gen_extenddf2_fprs (<MODE>mode,
8860 operands[0], operands[1], zero));
8861 }
8862 DONE;
8863 })
8864
8865 ;; Allow memory operands for the source to be created by the combiner.
8866 (define_insn_and_split "@extenddf<mode>2_fprs"
8867 [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d,&d")
8868 (float_extend:IBM128
8869 (match_operand:DF 1 "nonimmediate_operand" "d,m,d")))
8870 (use (match_operand:DF 2 "nonimmediate_operand" "m,m,d"))]
8871 "!TARGET_VSX && TARGET_HARD_FLOAT
8872 && TARGET_LONG_DOUBLE_128 && FLOAT128_IBM_P (<MODE>mode)"
8873 "#"
8874 "&& reload_completed"
8875 [(set (match_dup 3) (match_dup 1))
8876 (set (match_dup 4) (match_dup 2))]
8877 {
8878 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
8879 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
8880
8881 operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
8882 operands[4] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
8883 })
8884
8885 (define_insn_and_split "@extenddf<mode>2_vsx"
8886 [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d")
8887 (float_extend:IBM128
8888 (match_operand:DF 1 "nonimmediate_operand" "wa,m")))]
8889 "TARGET_LONG_DOUBLE_128 && TARGET_VSX && FLOAT128_IBM_P (<MODE>mode)"
8890 "#"
8891 "&& reload_completed"
8892 [(set (match_dup 2) (match_dup 1))
8893 (set (match_dup 3) (match_dup 4))]
8894 {
8895 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
8896 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
8897
8898 operands[2] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
8899 operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
8900 operands[4] = CONST0_RTX (DFmode);
8901 })
8902
8903 (define_expand "extendsf<mode>2"
8904 [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
8905 (float_extend:FLOAT128 (match_operand:SF 1 "gpc_reg_operand")))]
8906 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8907 {
8908 if (FLOAT128_IEEE_P (<MODE>mode))
8909 rs6000_expand_float128_convert (operands[0], operands[1], false);
8910 else
8911 {
8912 rtx tmp = gen_reg_rtx (DFmode);
8913 emit_insn (gen_extendsfdf2 (tmp, operands[1]));
8914 emit_insn (gen_extenddf<mode>2 (operands[0], tmp));
8915 }
8916 DONE;
8917 })
8918
8919 (define_expand "trunc<mode>df2"
8920 [(set (match_operand:DF 0 "gpc_reg_operand")
8921 (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand")))]
8922 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8923 {
8924 if (FLOAT128_IEEE_P (<MODE>mode))
8925 {
8926 rs6000_expand_float128_convert (operands[0], operands[1], false);
8927 DONE;
8928 }
8929 })
8930
8931 (define_insn_and_split "trunc<mode>df2_internal1"
8932 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d")
8933 (float_truncate:DF
8934 (match_operand:IBM128 1 "gpc_reg_operand" "0,d")))]
8935 "FLOAT128_IBM_P (<MODE>mode) && !TARGET_XL_COMPAT
8936 && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8937 "@
8938 #
8939 fmr %0,%1"
8940 "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
8941 [(const_int 0)]
8942 {
8943 emit_note (NOTE_INSN_DELETED);
8944 DONE;
8945 }
8946 [(set_attr "type" "fpsimple")])
8947
8948 (define_insn "trunc<mode>df2_internal2"
8949 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
8950 (float_truncate:DF (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
8951 "FLOAT128_IBM_P (<MODE>mode) && TARGET_XL_COMPAT && TARGET_HARD_FLOAT
8952 && TARGET_LONG_DOUBLE_128"
8953 "fadd %0,%1,%L1"
8954 [(set_attr "type" "fp")])
8955
8956 (define_expand "trunc<mode>sf2"
8957 [(set (match_operand:SF 0 "gpc_reg_operand")
8958 (float_truncate:SF (match_operand:FLOAT128 1 "gpc_reg_operand")))]
8959 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8960 {
8961 if (FLOAT128_IEEE_P (<MODE>mode))
8962 rs6000_expand_float128_convert (operands[0], operands[1], false);
8963 else
8964 {
8965 rtx tmp = gen_reg_rtx (DFmode);
8966 emit_insn (gen_trunc<mode>df2 (tmp, operands[1]));
8967 emit_insn (gen_truncdfsf2 (operands[0], tmp));
8968 }
8969 DONE;
8970 })
8971
8972 (define_expand "floatsi<mode>2"
8973 [(parallel [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
8974 (float:FLOAT128 (match_operand:SI 1 "gpc_reg_operand")))
8975 (clobber (match_scratch:DI 2))])]
8976 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8977 {
8978 rtx op0 = operands[0];
8979 rtx op1 = operands[1];
8980
8981 if (TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode))
8982 ;
8983 else if (FLOAT128_IEEE_P (<MODE>mode))
8984 {
8985 rs6000_expand_float128_convert (op0, op1, false);
8986 DONE;
8987 }
8988 else
8989 {
8990 rtx tmp = gen_reg_rtx (DFmode);
8991 expand_float (tmp, op1, false);
8992 emit_insn (gen_extenddf2 (<MODE>mode, op0, tmp));
8993 DONE;
8994 }
8995 })
8996
8997 ; fadd, but rounding towards zero.
8998 ; This is probably not the optimal code sequence.
8999 (define_insn "fix_trunc_helper<mode>"
9000 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
9001 (unspec:DF [(match_operand:IBM128 1 "gpc_reg_operand" "d")]
9002 UNSPEC_FIX_TRUNC_TF))
9003 (clobber (match_operand:DF 2 "gpc_reg_operand" "=&d"))]
9004 "TARGET_HARD_FLOAT && FLOAT128_IBM_P (<MODE>mode)"
9005 "mffs %2\n\tmtfsb1 31\n\tmtfsb0 30\n\tfadd %0,%1,%L1\n\tmtfsf 1,%2"
9006 [(set_attr "type" "fp")
9007 (set_attr "length" "20")])
9008
9009 (define_expand "fix_trunc<mode>si2"
9010 [(set (match_operand:SI 0 "gpc_reg_operand")
9011 (fix:SI (match_operand:FLOAT128 1 "gpc_reg_operand")))]
9012 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
9013 {
9014 rtx op0 = operands[0];
9015 rtx op1 = operands[1];
9016
9017 if (TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode))
9018 ;
9019 else
9020 {
9021 if (FLOAT128_IEEE_P (<MODE>mode))
9022 rs6000_expand_float128_convert (op0, op1, false);
9023 else
9024 emit_insn (gen_fix_truncsi2_fprs (<MODE>mode, op0, op1));
9025 DONE;
9026 }
9027 })
9028
9029 (define_expand "@fix_trunc<mode>si2_fprs"
9030 [(parallel [(set (match_operand:SI 0 "gpc_reg_operand")
9031 (fix:SI (match_operand:IBM128 1 "gpc_reg_operand")))
9032 (clobber (match_dup 2))
9033 (clobber (match_dup 3))
9034 (clobber (match_dup 4))
9035 (clobber (match_dup 5))])]
9036 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
9037 {
9038 operands[2] = gen_reg_rtx (DFmode);
9039 operands[3] = gen_reg_rtx (DFmode);
9040 operands[4] = gen_reg_rtx (DImode);
9041 operands[5] = assign_stack_temp (DImode, GET_MODE_SIZE (DImode));
9042 })
9043
9044 (define_insn_and_split "*fix_trunc<mode>si2_internal"
9045 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
9046 (fix:SI (match_operand:IBM128 1 "gpc_reg_operand" "d")))
9047 (clobber (match_operand:DF 2 "gpc_reg_operand" "=d"))
9048 (clobber (match_operand:DF 3 "gpc_reg_operand" "=&d"))
9049 (clobber (match_operand:DI 4 "gpc_reg_operand" "=d"))
9050 (clobber (match_operand:DI 5 "offsettable_mem_operand" "=o"))]
9051 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
9052 "#"
9053 "&& 1"
9054 [(pc)]
9055 {
9056 rtx lowword;
9057 emit_insn (gen_fix_trunc_helper<mode> (operands[2], operands[1],
9058 operands[3]));
9059
9060 gcc_assert (MEM_P (operands[5]));
9061 lowword = adjust_address (operands[5], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
9062
9063 emit_insn (gen_fctiwz_df (operands[4], operands[2]));
9064 emit_move_insn (operands[5], operands[4]);
9065 emit_move_insn (operands[0], lowword);
9066 DONE;
9067 })
9068
9069 (define_expand "fix_trunc<mode>di2"
9070 [(set (match_operand:DI 0 "gpc_reg_operand")
9071 (fix:DI (match_operand:IEEE128 1 "gpc_reg_operand")))]
9072 "TARGET_FLOAT128_TYPE"
9073 {
9074 if (!TARGET_FLOAT128_HW)
9075 {
9076 rs6000_expand_float128_convert (operands[0], operands[1], false);
9077 DONE;
9078 }
9079 })
9080
9081 (define_expand "fixuns_trunc<IEEE128:mode><SDI:mode>2"
9082 [(set (match_operand:SDI 0 "gpc_reg_operand")
9083 (unsigned_fix:SDI (match_operand:IEEE128 1 "gpc_reg_operand")))]
9084 "TARGET_FLOAT128_TYPE"
9085 {
9086 rs6000_expand_float128_convert (operands[0], operands[1], true);
9087 DONE;
9088 })
9089
9090 (define_expand "floatdi<mode>2"
9091 [(set (match_operand:IEEE128 0 "gpc_reg_operand")
9092 (float:IEEE128 (match_operand:DI 1 "gpc_reg_operand")))]
9093 "TARGET_FLOAT128_TYPE"
9094 {
9095 if (!TARGET_FLOAT128_HW)
9096 {
9097 rs6000_expand_float128_convert (operands[0], operands[1], false);
9098 DONE;
9099 }
9100 })
9101
9102 (define_expand "floatunsdi<IEEE128:mode>2"
9103 [(set (match_operand:IEEE128 0 "gpc_reg_operand")
9104 (unsigned_float:IEEE128 (match_operand:DI 1 "gpc_reg_operand")))]
9105 "TARGET_FLOAT128_TYPE"
9106 {
9107 if (!TARGET_FLOAT128_HW)
9108 {
9109 rs6000_expand_float128_convert (operands[0], operands[1], true);
9110 DONE;
9111 }
9112 })
9113
9114 (define_expand "floatuns<IEEE128:mode>2"
9115 [(set (match_operand:IEEE128 0 "gpc_reg_operand")
9116 (unsigned_float:IEEE128 (match_operand:SI 1 "gpc_reg_operand")))]
9117 "TARGET_FLOAT128_TYPE"
9118 {
9119 rtx op0 = operands[0];
9120 rtx op1 = operands[1];
9121
9122 if (TARGET_FLOAT128_HW)
9123 emit_insn (gen_floatuns_<IEEE128:mode>si2_hw (op0, op1));
9124 else
9125 rs6000_expand_float128_convert (op0, op1, true);
9126 DONE;
9127 })
9128
9129 (define_expand "neg<mode>2"
9130 [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
9131 (neg:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand")))]
9132 "FLOAT128_IEEE_P (<MODE>mode)
9133 || (FLOAT128_IBM_P (<MODE>mode) && TARGET_HARD_FLOAT)"
9134 {
9135 if (FLOAT128_IEEE_P (<MODE>mode))
9136 {
9137 if (TARGET_FLOAT128_HW)
9138 emit_insn (gen_neg2_hw (<MODE>mode, operands[0], operands[1]));
9139 else if (TARGET_FLOAT128_TYPE)
9140 emit_insn (gen_ieee_128bit_vsx_neg2 (<MODE>mode,
9141 operands[0], operands[1]));
9142 else
9143 {
9144 rtx libfunc = optab_libfunc (neg_optab, <MODE>mode);
9145 rtx target = emit_library_call_value (libfunc, operands[0], LCT_CONST,
9146 <MODE>mode,
9147 operands[1], <MODE>mode);
9148
9149 if (target && !rtx_equal_p (target, operands[0]))
9150 emit_move_insn (operands[0], target);
9151 }
9152 DONE;
9153 }
9154 })
9155
9156 (define_insn "neg<mode>2_internal"
9157 [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d")
9158 (neg:IBM128 (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
9159 "TARGET_HARD_FLOAT && FLOAT128_IBM_P (<MODE>mode)"
9160 {
9161 if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
9162 return "fneg %L0,%L1\;fneg %0,%1";
9163 else
9164 return "fneg %0,%1\;fneg %L0,%L1";
9165 }
9166 [(set_attr "type" "fpsimple")
9167 (set_attr "length" "8")])
9168
9169 (define_expand "abs<mode>2"
9170 [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
9171 (abs:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand")))]
9172 "FLOAT128_IEEE_P (<MODE>mode)
9173 || (FLOAT128_IBM_P (<MODE>mode) && TARGET_HARD_FLOAT)"
9174 {
9175 rtx label;
9176
9177 if (FLOAT128_IEEE_P (<MODE>mode))
9178 {
9179 if (TARGET_FLOAT128_HW)
9180 {
9181 emit_insn (gen_abs2_hw (<MODE>mode, operands[0], operands[1]));
9182 DONE;
9183 }
9184 else if (TARGET_FLOAT128_TYPE)
9185 {
9186 emit_insn (gen_ieee_128bit_vsx_abs2 (<MODE>mode,
9187 operands[0], operands[1]));
9188 DONE;
9189 }
9190 else
9191 FAIL;
9192 }
9193
9194 label = gen_label_rtx ();
9195 emit_insn (gen_abs2_internal (<MODE>mode, operands[0], operands[1], label));
9196 emit_label (label);
9197 DONE;
9198 })
9199
9200 (define_expand "@abs<mode>2_internal"
9201 [(set (match_operand:IBM128 0 "gpc_reg_operand")
9202 (match_operand:IBM128 1 "gpc_reg_operand"))
9203 (set (match_dup 3) (match_dup 5))
9204 (set (match_dup 5) (abs:DF (match_dup 5)))
9205 (set (match_dup 4) (compare:CCFP (match_dup 3) (match_dup 5)))
9206 (set (pc) (if_then_else (eq (match_dup 4) (const_int 0))
9207 (label_ref (match_operand 2 ""))
9208 (pc)))
9209 (set (match_dup 6) (neg:DF (match_dup 6)))]
9210 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
9211 {
9212 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
9213 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
9214 operands[3] = gen_reg_rtx (DFmode);
9215 operands[4] = gen_reg_rtx (CCFPmode);
9216 operands[5] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
9217 operands[6] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
9218 })
9219
9220 \f
9221 ;; Generate IEEE 128-bit -0.0 (0x80000000000000000000000000000000) in a vector
9222 ;; register
9223
9224 (define_expand "ieee_128bit_negative_zero"
9225 [(set (match_operand:V16QI 0 "register_operand") (match_dup 1))]
9226 "TARGET_FLOAT128_TYPE"
9227 {
9228 rtvec v = rtvec_alloc (16);
9229 int i, high;
9230
9231 for (i = 0; i < 16; i++)
9232 RTVEC_ELT (v, i) = const0_rtx;
9233
9234 high = (BYTES_BIG_ENDIAN) ? 0 : 15;
9235 RTVEC_ELT (v, high) = gen_int_mode (0x80, QImode);
9236
9237 rs6000_expand_vector_init (operands[0], gen_rtx_PARALLEL (V16QImode, v));
9238 DONE;
9239 })
9240
9241 ;; IEEE 128-bit negate
9242
9243 ;; We have 2 insns here for negate and absolute value. The first uses
9244 ;; match_scratch so that phases like combine can recognize neg/abs as generic
9245 ;; insns, and second insn after the first split pass loads up the bit to
9246 ;; twiddle the sign bit. Later GCSE passes can then combine multiple uses of
9247 ;; neg/abs to create the constant just once.
9248
9249 (define_insn_and_split "@ieee_128bit_vsx_neg<mode>2"
9250 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
9251 (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
9252 (clobber (match_scratch:V16QI 2 "=v"))]
9253 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
9254 "#"
9255 "&& 1"
9256 [(parallel [(set (match_dup 0)
9257 (neg:IEEE128 (match_dup 1)))
9258 (use (match_dup 2))])]
9259 {
9260 if (GET_CODE (operands[2]) == SCRATCH)
9261 operands[2] = gen_reg_rtx (V16QImode);
9262
9263 operands[3] = gen_reg_rtx (V16QImode);
9264 emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
9265 }
9266 [(set_attr "length" "8")
9267 (set_attr "type" "vecsimple")])
9268
9269 (define_insn "*ieee_128bit_vsx_neg<mode>2_internal"
9270 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
9271 (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
9272 (use (match_operand:V16QI 2 "register_operand" "v"))]
9273 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
9274 "xxlxor %x0,%x1,%x2"
9275 [(set_attr "type" "veclogical")])
9276
9277 ;; IEEE 128-bit absolute value
9278 (define_insn_and_split "@ieee_128bit_vsx_abs<mode>2"
9279 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
9280 (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
9281 (clobber (match_scratch:V16QI 2 "=v"))]
9282 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
9283 "#"
9284 "&& 1"
9285 [(parallel [(set (match_dup 0)
9286 (abs:IEEE128 (match_dup 1)))
9287 (use (match_dup 2))])]
9288 {
9289 if (GET_CODE (operands[2]) == SCRATCH)
9290 operands[2] = gen_reg_rtx (V16QImode);
9291
9292 operands[3] = gen_reg_rtx (V16QImode);
9293 emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
9294 }
9295 [(set_attr "length" "8")
9296 (set_attr "type" "vecsimple")])
9297
9298 (define_insn "*ieee_128bit_vsx_abs<mode>2_internal"
9299 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
9300 (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
9301 (use (match_operand:V16QI 2 "register_operand" "v"))]
9302 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
9303 "xxlandc %x0,%x1,%x2"
9304 [(set_attr "type" "veclogical")])
9305
9306 ;; IEEE 128-bit negative absolute value
9307 (define_insn_and_split "*ieee_128bit_vsx_nabs<mode>2"
9308 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
9309 (neg:IEEE128
9310 (abs:IEEE128
9311 (match_operand:IEEE128 1 "register_operand" "wa"))))
9312 (clobber (match_scratch:V16QI 2 "=v"))]
9313 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW
9314 && FLOAT128_IEEE_P (<MODE>mode)"
9315 "#"
9316 "&& 1"
9317 [(parallel [(set (match_dup 0)
9318 (neg:IEEE128 (abs:IEEE128 (match_dup 1))))
9319 (use (match_dup 2))])]
9320 {
9321 if (GET_CODE (operands[2]) == SCRATCH)
9322 operands[2] = gen_reg_rtx (V16QImode);
9323
9324 operands[3] = gen_reg_rtx (V16QImode);
9325 emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
9326 }
9327 [(set_attr "length" "8")
9328 (set_attr "type" "vecsimple")])
9329
9330 (define_insn "*ieee_128bit_vsx_nabs<mode>2_internal"
9331 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
9332 (neg:IEEE128
9333 (abs:IEEE128
9334 (match_operand:IEEE128 1 "register_operand" "wa"))))
9335 (use (match_operand:V16QI 2 "register_operand" "v"))]
9336 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
9337 "xxlor %x0,%x1,%x2"
9338 [(set_attr "type" "veclogical")])
9339
9340 ;; Float128 conversion functions. These expand to library function calls.
9341 ;; We use expand to convert from IBM double double to IEEE 128-bit
9342 ;; and trunc for the opposite.
9343 (define_expand "extendiftf2"
9344 [(set (match_operand:TF 0 "gpc_reg_operand")
9345 (float_extend:TF (match_operand:IF 1 "gpc_reg_operand")))]
9346 "TARGET_FLOAT128_TYPE"
9347 {
9348 rs6000_expand_float128_convert (operands[0], operands[1], false);
9349 DONE;
9350 })
9351
9352 (define_expand "extendifkf2"
9353 [(set (match_operand:KF 0 "gpc_reg_operand")
9354 (float_extend:KF (match_operand:IF 1 "gpc_reg_operand")))]
9355 "TARGET_FLOAT128_TYPE"
9356 {
9357 rs6000_expand_float128_convert (operands[0], operands[1], false);
9358 DONE;
9359 })
9360
9361 (define_expand "extendtfkf2"
9362 [(set (match_operand:KF 0 "gpc_reg_operand")
9363 (float_extend:KF (match_operand:TF 1 "gpc_reg_operand")))]
9364 "TARGET_FLOAT128_TYPE"
9365 {
9366 rs6000_expand_float128_convert (operands[0], operands[1], false);
9367 DONE;
9368 })
9369
9370 (define_expand "extendtfif2"
9371 [(set (match_operand:IF 0 "gpc_reg_operand")
9372 (float_extend:IF (match_operand:TF 1 "gpc_reg_operand")))]
9373 "TARGET_FLOAT128_TYPE"
9374 {
9375 rs6000_expand_float128_convert (operands[0], operands[1], false);
9376 DONE;
9377 })
9378
9379 (define_expand "trunciftf2"
9380 [(set (match_operand:TF 0 "gpc_reg_operand")
9381 (float_truncate:TF (match_operand:IF 1 "gpc_reg_operand")))]
9382 "TARGET_FLOAT128_TYPE"
9383 {
9384 rs6000_expand_float128_convert (operands[0], operands[1], false);
9385 DONE;
9386 })
9387
9388 (define_expand "truncifkf2"
9389 [(set (match_operand:KF 0 "gpc_reg_operand")
9390 (float_truncate:KF (match_operand:IF 1 "gpc_reg_operand")))]
9391 "TARGET_FLOAT128_TYPE"
9392 {
9393 rs6000_expand_float128_convert (operands[0], operands[1], false);
9394 DONE;
9395 })
9396
9397 (define_expand "trunckftf2"
9398 [(set (match_operand:TF 0 "gpc_reg_operand")
9399 (float_truncate:TF (match_operand:KF 1 "gpc_reg_operand")))]
9400 "TARGET_FLOAT128_TYPE"
9401 {
9402 rs6000_expand_float128_convert (operands[0], operands[1], false);
9403 DONE;
9404 })
9405
9406 (define_expand "trunctfif2"
9407 [(set (match_operand:IF 0 "gpc_reg_operand")
9408 (float_truncate:IF (match_operand:TF 1 "gpc_reg_operand")))]
9409 "TARGET_FLOAT128_TYPE"
9410 {
9411 rs6000_expand_float128_convert (operands[0], operands[1], false);
9412 DONE;
9413 })
9414
9415 (define_insn_and_split "*extend<mode>tf2_internal"
9416 [(set (match_operand:TF 0 "gpc_reg_operand" "=<IFKF_reg>")
9417 (float_extend:TF
9418 (match_operand:IFKF 1 "gpc_reg_operand" "<IFKF_reg>")))]
9419 "TARGET_FLOAT128_TYPE
9420 && FLOAT128_IBM_P (TFmode) == FLOAT128_IBM_P (<MODE>mode)"
9421 "#"
9422 "&& reload_completed"
9423 [(set (match_dup 0) (match_dup 2))]
9424 {
9425 operands[2] = gen_rtx_REG (TFmode, REGNO (operands[1]));
9426 })
9427
9428 (define_insn_and_split "*extendtf<mode>2_internal"
9429 [(set (match_operand:IFKF 0 "gpc_reg_operand" "=<IFKF_reg>")
9430 (float_extend:IFKF
9431 (match_operand:TF 1 "gpc_reg_operand" "<IFKF_reg>")))]
9432 "TARGET_FLOAT128_TYPE
9433 && FLOAT128_IBM_P (TFmode) == FLOAT128_IBM_P (<MODE>mode)"
9434 "#"
9435 "&& reload_completed"
9436 [(set (match_dup 0) (match_dup 2))]
9437 {
9438 operands[2] = gen_rtx_REG (<MODE>mode, REGNO (operands[1]));
9439 })
9440
9441 \f
9442 ;; Reload helper functions used by rs6000_secondary_reload. The patterns all
9443 ;; must have 3 arguments, and scratch register constraint must be a single
9444 ;; constraint.
9445
9446 ;; Reload patterns to support gpr load/store with misaligned mem.
9447 ;; and multiple gpr load/store at offset >= 0xfffc
9448 (define_expand "reload_<mode>_store"
9449 [(parallel [(match_operand 0 "memory_operand" "=m")
9450 (match_operand 1 "gpc_reg_operand" "r")
9451 (match_operand:GPR 2 "register_operand" "=&b")])]
9452 ""
9453 {
9454 rs6000_secondary_reload_gpr (operands[1], operands[0], operands[2], true);
9455 DONE;
9456 })
9457
9458 (define_expand "reload_<mode>_load"
9459 [(parallel [(match_operand 0 "gpc_reg_operand" "=r")
9460 (match_operand 1 "memory_operand" "m")
9461 (match_operand:GPR 2 "register_operand" "=b")])]
9462 ""
9463 {
9464 rs6000_secondary_reload_gpr (operands[0], operands[1], operands[2], false);
9465 DONE;
9466 })
9467
9468 \f
9469 ;; Reload patterns for various types using the vector registers. We may need
9470 ;; an additional base register to convert the reg+offset addressing to reg+reg
9471 ;; for vector registers and reg+reg or (reg+reg)&(-16) addressing to just an
9472 ;; index register for gpr registers.
9473 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_store"
9474 [(parallel [(match_operand:RELOAD 0 "memory_operand" "m")
9475 (match_operand:RELOAD 1 "gpc_reg_operand" "wa")
9476 (match_operand:P 2 "register_operand" "=b")])]
9477 "<P:tptrsize>"
9478 {
9479 rs6000_secondary_reload_inner (operands[1], operands[0], operands[2], true);
9480 DONE;
9481 })
9482
9483 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_load"
9484 [(parallel [(match_operand:RELOAD 0 "gpc_reg_operand" "wa")
9485 (match_operand:RELOAD 1 "memory_operand" "m")
9486 (match_operand:P 2 "register_operand" "=b")])]
9487 "<P:tptrsize>"
9488 {
9489 rs6000_secondary_reload_inner (operands[0], operands[1], operands[2], false);
9490 DONE;
9491 })
9492
9493
9494 ;; Reload sometimes tries to move the address to a GPR, and can generate
9495 ;; invalid RTL for addresses involving AND -16. Allow addresses involving
9496 ;; reg+reg, reg+small constant, or just reg, all wrapped in an AND -16.
9497
9498 (define_insn_and_split "*vec_reload_and_plus_<mptrsize>"
9499 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9500 (and:P (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
9501 (match_operand:P 2 "reg_or_cint_operand" "rI"))
9502 (const_int -16)))]
9503 "TARGET_ALTIVEC && reload_completed"
9504 "#"
9505 "&& reload_completed"
9506 [(set (match_dup 0)
9507 (plus:P (match_dup 1)
9508 (match_dup 2)))
9509 (set (match_dup 0)
9510 (and:P (match_dup 0)
9511 (const_int -16)))])
9512 \f
9513 ;; Power8 merge instructions to allow direct move to/from floating point
9514 ;; registers in 32-bit mode. We use TF mode to get two registers to move the
9515 ;; individual 32-bit parts across. Subreg doesn't work too well on the TF
9516 ;; value, since it is allocated in reload and not all of the flow information
9517 ;; is setup for it. We have two patterns to do the two moves between gprs and
9518 ;; fprs. There isn't a dependancy between the two, but we could potentially
9519 ;; schedule other instructions between the two instructions.
9520
9521 (define_insn "p8_fmrgow_<mode>"
9522 [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
9523 (unspec:FMOVE64X [
9524 (match_operand:DF 1 "register_operand" "d")
9525 (match_operand:DF 2 "register_operand" "d")]
9526 UNSPEC_P8V_FMRGOW))]
9527 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
9528 "fmrgow %0,%1,%2"
9529 [(set_attr "type" "fpsimple")])
9530
9531 (define_insn "p8_mtvsrwz"
9532 [(set (match_operand:DF 0 "register_operand" "=d")
9533 (unspec:DF [(match_operand:SI 1 "register_operand" "r")]
9534 UNSPEC_P8V_MTVSRWZ))]
9535 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
9536 "mtvsrwz %x0,%1"
9537 [(set_attr "type" "mtvsr")])
9538
9539 (define_insn "p8_mtvsrwz_v16qisi2"
9540 [(set (match_operand:V16QI 0 "register_operand" "=wa")
9541 (unspec:V16QI [(match_operand:SI 1 "register_operand" "r")]
9542 UNSPEC_P8V_MTVSRWZ))]
9543 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
9544 "mtvsrwz %x0,%1"
9545 [(set_attr "type" "mtvsr")])
9546
9547 (define_insn "p8_mtvsrd_v16qidi2"
9548 [(set (match_operand:V16QI 0 "register_operand" "=wa")
9549 (unspec:V16QI [(match_operand:DI 1 "register_operand" "r")]
9550 UNSPEC_P8V_MTVSRD))]
9551 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
9552 "mtvsrd %x0,%1"
9553 [(set_attr "type" "mtvsr")])
9554
9555 (define_insn_and_split "reload_fpr_from_gpr<mode>"
9556 [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
9557 (unspec:FMOVE64X [(match_operand:FMOVE64X 1 "register_operand" "r")]
9558 UNSPEC_P8V_RELOAD_FROM_GPR))
9559 (clobber (match_operand:IF 2 "register_operand" "=d"))]
9560 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
9561 "#"
9562 "&& reload_completed"
9563 [(const_int 0)]
9564 {
9565 rtx dest = operands[0];
9566 rtx src = operands[1];
9567 rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0);
9568 rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8);
9569 rtx gpr_hi_reg = gen_highpart (SImode, src);
9570 rtx gpr_lo_reg = gen_lowpart (SImode, src);
9571
9572 emit_insn (gen_p8_mtvsrwz (tmp_hi, gpr_hi_reg));
9573 emit_insn (gen_p8_mtvsrwz (tmp_lo, gpr_lo_reg));
9574 emit_insn (gen_p8_fmrgow_<mode> (dest, tmp_hi, tmp_lo));
9575 DONE;
9576 }
9577 [(set_attr "length" "12")
9578 (set_attr "type" "three")])
9579
9580 ;; Move 128 bit values from GPRs to VSX registers in 64-bit mode
9581 (define_insn "p8_mtvsrd_df"
9582 [(set (match_operand:DF 0 "register_operand" "=wa")
9583 (unspec:DF [(match_operand:DI 1 "register_operand" "r")]
9584 UNSPEC_P8V_MTVSRD))]
9585 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
9586 "mtvsrd %x0,%1"
9587 [(set_attr "type" "mtvsr")])
9588
9589 (define_insn "p8_xxpermdi_<mode>"
9590 [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
9591 (unspec:FMOVE128_GPR [
9592 (match_operand:DF 1 "register_operand" "wa")
9593 (match_operand:DF 2 "register_operand" "wa")]
9594 UNSPEC_P8V_XXPERMDI))]
9595 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
9596 "xxpermdi %x0,%x1,%x2,0"
9597 [(set_attr "type" "vecperm")])
9598
9599 (define_insn_and_split "reload_vsx_from_gpr<mode>"
9600 [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
9601 (unspec:FMOVE128_GPR
9602 [(match_operand:FMOVE128_GPR 1 "register_operand" "r")]
9603 UNSPEC_P8V_RELOAD_FROM_GPR))
9604 (clobber (match_operand:IF 2 "register_operand" "=wa"))]
9605 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
9606 "#"
9607 "&& reload_completed"
9608 [(const_int 0)]
9609 {
9610 rtx dest = operands[0];
9611 rtx src = operands[1];
9612 /* You might think that we could use op0 as one temp and a DF clobber
9613 as op2, but you'd be wrong. Secondary reload move patterns don't
9614 check for overlap of the clobber and the destination. */
9615 rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0);
9616 rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8);
9617 rtx gpr_hi_reg = gen_highpart (DImode, src);
9618 rtx gpr_lo_reg = gen_lowpart (DImode, src);
9619
9620 emit_insn (gen_p8_mtvsrd_df (tmp_hi, gpr_hi_reg));
9621 emit_insn (gen_p8_mtvsrd_df (tmp_lo, gpr_lo_reg));
9622 emit_insn (gen_p8_xxpermdi_<mode> (dest, tmp_hi, tmp_lo));
9623 DONE;
9624 }
9625 [(set_attr "length" "12")
9626 (set_attr "type" "three")])
9627
9628 (define_split
9629 [(set (match_operand:FMOVE128_GPR 0 "nonimmediate_operand")
9630 (match_operand:FMOVE128_GPR 1 "input_operand"))]
9631 "reload_completed
9632 && (int_reg_operand (operands[0], <MODE>mode)
9633 || int_reg_operand (operands[1], <MODE>mode))
9634 && (!TARGET_DIRECT_MOVE_128
9635 || (!vsx_register_operand (operands[0], <MODE>mode)
9636 && !vsx_register_operand (operands[1], <MODE>mode)))"
9637 [(pc)]
9638 {
9639 rs6000_split_multireg_move (operands[0], operands[1]);
9640 DONE;
9641 })
9642
9643 ;; Move SFmode to a VSX from a GPR register. Because scalar floating point
9644 ;; type is stored internally as double precision in the VSX registers, we have
9645 ;; to convert it from the vector format.
9646 (define_insn "p8_mtvsrd_sf"
9647 [(set (match_operand:SF 0 "register_operand" "=wa")
9648 (unspec:SF [(match_operand:DI 1 "register_operand" "r")]
9649 UNSPEC_P8V_MTVSRD))]
9650 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
9651 "mtvsrd %x0,%1"
9652 [(set_attr "type" "mtvsr")])
9653
9654 (define_insn_and_split "reload_vsx_from_gprsf"
9655 [(set (match_operand:SF 0 "register_operand" "=wa")
9656 (unspec:SF [(match_operand:SF 1 "register_operand" "r")]
9657 UNSPEC_P8V_RELOAD_FROM_GPR))
9658 (clobber (match_operand:DI 2 "register_operand" "=r"))]
9659 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
9660 "#"
9661 "&& reload_completed"
9662 [(const_int 0)]
9663 {
9664 rtx op0 = operands[0];
9665 rtx op1 = operands[1];
9666 rtx op2 = operands[2];
9667 rtx op1_di = simplify_gen_subreg (DImode, op1, SFmode, 0);
9668
9669 /* Move SF value to upper 32-bits for xscvspdpn. */
9670 emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32)));
9671 emit_insn (gen_p8_mtvsrd_sf (op0, op2));
9672 emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0));
9673 DONE;
9674 }
9675 [(set_attr "length" "8")
9676 (set_attr "type" "two")])
9677
9678 ;; Move 128 bit values from VSX registers to GPRs in 64-bit mode by doing a
9679 ;; normal 64-bit move, followed by an xxpermdi to get the bottom 64-bit value,
9680 ;; and then doing a move of that.
9681 (define_insn "p8_mfvsrd_3_<mode>"
9682 [(set (match_operand:DF 0 "register_operand" "=r")
9683 (unspec:DF [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
9684 UNSPEC_P8V_RELOAD_FROM_VSX))]
9685 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
9686 "mfvsrd %0,%x1"
9687 [(set_attr "type" "mfvsr")])
9688
9689 (define_insn_and_split "reload_gpr_from_vsx<mode>"
9690 [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=r")
9691 (unspec:FMOVE128_GPR
9692 [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
9693 UNSPEC_P8V_RELOAD_FROM_VSX))
9694 (clobber (match_operand:FMOVE128_GPR 2 "register_operand" "=wa"))]
9695 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
9696 "#"
9697 "&& reload_completed"
9698 [(const_int 0)]
9699 {
9700 rtx dest = operands[0];
9701 rtx src = operands[1];
9702 rtx tmp = operands[2];
9703 rtx gpr_hi_reg = gen_highpart (DFmode, dest);
9704 rtx gpr_lo_reg = gen_lowpart (DFmode, dest);
9705
9706 emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_hi_reg, src));
9707 emit_insn (gen_vsx_xxpermdi_<mode>_be (tmp, src, src, GEN_INT (3)));
9708 emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_lo_reg, tmp));
9709 DONE;
9710 }
9711 [(set_attr "length" "12")
9712 (set_attr "type" "three")])
9713
9714 ;; Move SFmode to a GPR from a VSX register. Because scalar floating point
9715 ;; type is stored internally as double precision, we have to convert it to the
9716 ;; vector format.
9717
9718 (define_insn_and_split "reload_gpr_from_vsxsf"
9719 [(set (match_operand:SF 0 "register_operand" "=r")
9720 (unspec:SF [(match_operand:SF 1 "register_operand" "wa")]
9721 UNSPEC_P8V_RELOAD_FROM_VSX))
9722 (clobber (match_operand:V4SF 2 "register_operand" "=wa"))]
9723 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
9724 "#"
9725 "&& reload_completed"
9726 [(const_int 0)]
9727 {
9728 rtx op0 = operands[0];
9729 rtx op1 = operands[1];
9730 rtx op2 = operands[2];
9731 rtx op0_di = gen_rtx_REG (DImode, reg_or_subregno (op0));
9732 rtx op2_si = gen_rtx_REG (SImode, reg_or_subregno (op2));
9733
9734 emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
9735 emit_insn (gen_zero_extendsidi2 (op0_di, op2_si));
9736 DONE;
9737 }
9738 [(set_attr "length" "8")
9739 (set_attr "type" "two")
9740 (set_attr "isa" "p8v")])
9741 \f
9742 ;; Next come the multi-word integer load and store and the load and store
9743 ;; multiple insns.
9744
9745 ;; List r->r after r->Y, otherwise reload will try to reload a
9746 ;; non-offsettable address by using r->r which won't make progress.
9747 ;; Use of fprs is disparaged slightly otherwise reload prefers to reload
9748 ;; a gpr into a fpr instead of reloading an invalid 'Y' address
9749
9750 ;; GPR store GPR load GPR move FPR store FPR load FPR move
9751 ;; GPR const AVX store AVX store AVX load AVX load VSX move
9752 ;; P9 0 P9 -1 AVX 0/-1 VSX 0 VSX -1 P9 const
9753 ;; AVX const
9754
9755 (define_insn "*movdi_internal32"
9756 [(set (match_operand:DI 0 "nonimmediate_operand"
9757 "=Y, r, r, m, ^d, ^d,
9758 r, wY, Z, ^v, $v, ^wa,
9759 wa, wa, v, wa, *i, v,
9760 v")
9761 (match_operand:DI 1 "input_operand"
9762 "r, Y, r, ^d, m, ^d,
9763 IJKnF, ^v, $v, wY, Z, ^wa,
9764 Oj, wM, OjwM, Oj, wM, wS,
9765 wB"))]
9766 "! TARGET_POWERPC64
9767 && (gpc_reg_operand (operands[0], DImode)
9768 || gpc_reg_operand (operands[1], DImode))"
9769 "@
9770 #
9771 #
9772 #
9773 stfd%U0%X0 %1,%0
9774 lfd%U1%X1 %0,%1
9775 fmr %0,%1
9776 #
9777 stxsd %1,%0
9778 stxsdx %x1,%y0
9779 lxsd %0,%1
9780 lxsdx %x0,%y1
9781 xxlor %x0,%x1,%x1
9782 xxspltib %x0,0
9783 xxspltib %x0,255
9784 vspltisw %0,%1
9785 xxlxor %x0,%x0,%x0
9786 xxlorc %x0,%x0,%x0
9787 #
9788 #"
9789 [(set_attr "type"
9790 "store, load, *, fpstore, fpload, fpsimple,
9791 *, fpstore, fpstore, fpload, fpload, veclogical,
9792 vecsimple, vecsimple, vecsimple, veclogical,veclogical,vecsimple,
9793 vecsimple")
9794 (set_attr "size" "64")
9795 (set_attr "length"
9796 "8, 8, 8, *, *, *,
9797 16, *, *, *, *, *,
9798 *, *, *, *, *, 8,
9799 *")
9800 (set_attr "isa"
9801 "*, *, *, *, *, *,
9802 *, p9v, p7v, p9v, p7v, *,
9803 p9v, p9v, p7v, *, *, p7v,
9804 p7v")])
9805
9806 (define_split
9807 [(set (match_operand:DI 0 "gpc_reg_operand")
9808 (match_operand:DI 1 "const_int_operand"))]
9809 "! TARGET_POWERPC64 && reload_completed
9810 && gpr_or_gpr_p (operands[0], operands[1])
9811 && !direct_move_p (operands[0], operands[1])"
9812 [(set (match_dup 2) (match_dup 4))
9813 (set (match_dup 3) (match_dup 1))]
9814 {
9815 HOST_WIDE_INT value = INTVAL (operands[1]);
9816 operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
9817 DImode);
9818 operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
9819 DImode);
9820 operands[4] = GEN_INT (value >> 32);
9821 operands[1] = GEN_INT (sext_hwi (value, 32));
9822 })
9823
9824 (define_split
9825 [(set (match_operand:DIFD 0 "nonimmediate_operand")
9826 (match_operand:DIFD 1 "input_operand"))]
9827 "reload_completed && !TARGET_POWERPC64
9828 && gpr_or_gpr_p (operands[0], operands[1])
9829 && !direct_move_p (operands[0], operands[1])"
9830 [(pc)]
9831 {
9832 rs6000_split_multireg_move (operands[0], operands[1]);
9833 DONE;
9834 })
9835
9836 ;; GPR store GPR load GPR move
9837 ;; GPR li GPR lis GPR pli GPR #
9838 ;; FPR store FPR load FPR move
9839 ;; AVX store AVX store AVX load AVX load VSX move
9840 ;; P9 0 P9 -1 AVX 0/-1 VSX 0 VSX -1
9841 ;; P9 const AVX const
9842 ;; From SPR To SPR SPR<->SPR
9843 ;; VSX->GPR GPR->VSX
9844 (define_insn "*movdi_internal64"
9845 [(set (match_operand:DI 0 "nonimmediate_operand"
9846 "=YZ, r, r,
9847 r, r, r, r,
9848 m, ^d, ^d,
9849 wY, Z, $v, $v, ^wa,
9850 wa, wa, v, wa, wa,
9851 v, v,
9852 r, *h, *h,
9853 ?r, ?wa")
9854 (match_operand:DI 1 "input_operand"
9855 "r, YZ, r,
9856 I, L, eI, nF,
9857 ^d, m, ^d,
9858 ^v, $v, wY, Z, ^wa,
9859 Oj, wM, OjwM, Oj, wM,
9860 wS, wB,
9861 *h, r, 0,
9862 wa, r"))]
9863 "TARGET_POWERPC64
9864 && (gpc_reg_operand (operands[0], DImode)
9865 || gpc_reg_operand (operands[1], DImode))"
9866 "@
9867 std%U0%X0 %1,%0
9868 ld%U1%X1 %0,%1
9869 mr %0,%1
9870 li %0,%1
9871 lis %0,%v1
9872 li %0,%1
9873 #
9874 stfd%U0%X0 %1,%0
9875 lfd%U1%X1 %0,%1
9876 fmr %0,%1
9877 stxsd %1,%0
9878 stxsdx %x1,%y0
9879 lxsd %0,%1
9880 lxsdx %x0,%y1
9881 xxlor %x0,%x1,%x1
9882 xxspltib %x0,0
9883 xxspltib %x0,255
9884 #
9885 xxlxor %x0,%x0,%x0
9886 xxlorc %x0,%x0,%x0
9887 #
9888 #
9889 mf%1 %0
9890 mt%0 %1
9891 nop
9892 mfvsrd %0,%x1
9893 mtvsrd %x0,%1"
9894 [(set_attr "type"
9895 "store, load, *,
9896 *, *, *, *,
9897 fpstore, fpload, fpsimple,
9898 fpstore, fpstore, fpload, fpload, veclogical,
9899 vecsimple, vecsimple, vecsimple, veclogical, veclogical,
9900 vecsimple, vecsimple,
9901 mfjmpr, mtjmpr, *,
9902 mfvsr, mtvsr")
9903 (set_attr "size" "64")
9904 (set_attr "length"
9905 "*, *, *,
9906 *, *, *, 20,
9907 *, *, *,
9908 *, *, *, *, *,
9909 *, *, *, *, *,
9910 8, *,
9911 *, *, *,
9912 *, *")
9913 (set_attr "isa"
9914 "*, *, *,
9915 *, *, p10, *,
9916 *, *, *,
9917 p9v, p7v, p9v, p7v, *,
9918 p9v, p9v, p7v, *, *,
9919 p7v, p7v,
9920 *, *, *,
9921 p8v, p8v")])
9922
9923 ; Some DImode loads are best done as a load of -1 followed by a mask
9924 ; instruction.
9925 (define_split
9926 [(set (match_operand:DI 0 "int_reg_operand")
9927 (match_operand:DI 1 "const_int_operand"))]
9928 "TARGET_POWERPC64
9929 && num_insns_constant (operands[1], DImode) > 1
9930 && !IN_RANGE (INTVAL (operands[1]), -0x80000000, 0xffffffff)
9931 && rs6000_is_valid_and_mask (operands[1], DImode)"
9932 [(set (match_dup 0)
9933 (const_int -1))
9934 (set (match_dup 0)
9935 (and:DI (match_dup 0)
9936 (match_dup 1)))]
9937 "")
9938
9939 ;; Split a load of a large constant into the appropriate five-instruction
9940 ;; sequence. Handle anything in a constant number of insns.
9941 ;; When non-easy constants can go in the TOC, this should use
9942 ;; easy_fp_constant predicate.
9943 (define_split
9944 [(set (match_operand:DI 0 "int_reg_operand")
9945 (match_operand:DI 1 "const_int_operand"))]
9946 "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
9947 [(pc)]
9948 {
9949 if (rs6000_emit_set_const (operands[0], operands[1]))
9950 DONE;
9951 else
9952 FAIL;
9953 })
9954
9955 (define_split
9956 [(set (match_operand:DI 0 "altivec_register_operand")
9957 (match_operand:DI 1 "s5bit_cint_operand"))]
9958 "TARGET_VSX && reload_completed"
9959 [(const_int 0)]
9960 {
9961 rtx op0 = operands[0];
9962 rtx op1 = operands[1];
9963 int r = REGNO (op0);
9964 rtx op0_v4si = gen_rtx_REG (V4SImode, r);
9965
9966 emit_insn (gen_altivec_vspltisw (op0_v4si, op1));
9967 if (op1 != const0_rtx && op1 != constm1_rtx)
9968 {
9969 rtx op0_v2di = gen_rtx_REG (V2DImode, r);
9970 emit_insn (gen_altivec_vupkhsw (op0_v2di, op0_v4si));
9971 }
9972 DONE;
9973 })
9974
9975 ;; Split integer constants that can be loaded with XXSPLTIB and a
9976 ;; sign extend operation.
9977 (define_split
9978 [(set (match_operand:INT_ISA3 0 "altivec_register_operand")
9979 (match_operand:INT_ISA3 1 "xxspltib_constant_split"))]
9980 "TARGET_P9_VECTOR && reload_completed"
9981 [(const_int 0)]
9982 {
9983 rtx op0 = operands[0];
9984 rtx op1 = operands[1];
9985 int r = REGNO (op0);
9986 rtx op0_v16qi = gen_rtx_REG (V16QImode, r);
9987
9988 emit_insn (gen_xxspltib_v16qi (op0_v16qi, op1));
9989 if (<MODE>mode == DImode)
9990 emit_insn (gen_vsx_sign_extend_v16qi_di (operands[0], op0_v16qi));
9991 else if (<MODE>mode == SImode)
9992 emit_insn (gen_vsx_sign_extend_v16qi_si (operands[0], op0_v16qi));
9993 else if (<MODE>mode == HImode)
9994 {
9995 rtx op0_v8hi = gen_rtx_REG (V8HImode, r);
9996 emit_insn (gen_altivec_vupkhsb (op0_v8hi, op0_v16qi));
9997 }
9998 DONE;
9999 })
10000
10001 \f
10002 ;; TImode/PTImode is similar, except that we usually want to compute the
10003 ;; address into a register and use lsi/stsi (the exception is during reload).
10004
10005 (define_insn "*mov<mode>_string"
10006 [(set (match_operand:TI2 0 "reg_or_mem_operand" "=Q,Y,????r,????r,????r,r")
10007 (match_operand:TI2 1 "input_operand" "r,r,Q,Y,r,n"))]
10008 "! TARGET_POWERPC64
10009 && (<MODE>mode != TImode || VECTOR_MEM_NONE_P (TImode))
10010 && (gpc_reg_operand (operands[0], <MODE>mode)
10011 || gpc_reg_operand (operands[1], <MODE>mode))"
10012 "#"
10013 [(set_attr "type" "store,store,load,load,*,*")
10014 (set_attr "update" "yes")
10015 (set_attr "indexed" "yes")
10016 (set_attr "cell_micro" "conditional")])
10017
10018 (define_insn "*mov<mode>_ppc64"
10019 [(set (match_operand:TI2 0 "nonimmediate_operand" "=wQ,Y,r,r,r,r")
10020 (match_operand:TI2 1 "input_operand" "r,r,wQ,Y,r,n"))]
10021 "(TARGET_POWERPC64 && VECTOR_MEM_NONE_P (<MODE>mode)
10022 && (gpc_reg_operand (operands[0], <MODE>mode)
10023 || gpc_reg_operand (operands[1], <MODE>mode)))"
10024 {
10025 return rs6000_output_move_128bit (operands);
10026 }
10027 [(set_attr "type" "store,store,load,load,*,*")
10028 (set_attr "length" "8")
10029 (set_attr "max_prefixed_insns" "2")])
10030
10031 (define_split
10032 [(set (match_operand:TI2 0 "int_reg_operand")
10033 (match_operand:TI2 1 "const_scalar_int_operand"))]
10034 "TARGET_POWERPC64
10035 && (VECTOR_MEM_NONE_P (<MODE>mode)
10036 || (reload_completed && INT_REGNO_P (REGNO (operands[0]))))"
10037 [(set (match_dup 2) (match_dup 4))
10038 (set (match_dup 3) (match_dup 5))]
10039 {
10040 operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
10041 <MODE>mode);
10042 operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
10043 <MODE>mode);
10044 if (CONST_WIDE_INT_P (operands[1]))
10045 {
10046 operands[4] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 1));
10047 operands[5] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 0));
10048 }
10049 else if (CONST_INT_P (operands[1]))
10050 {
10051 operands[4] = GEN_INT (- (INTVAL (operands[1]) < 0));
10052 operands[5] = operands[1];
10053 }
10054 else
10055 FAIL;
10056 })
10057
10058 (define_split
10059 [(set (match_operand:TI2 0 "nonimmediate_operand")
10060 (match_operand:TI2 1 "input_operand"))]
10061 "reload_completed
10062 && gpr_or_gpr_p (operands[0], operands[1])
10063 && !direct_move_p (operands[0], operands[1])
10064 && !quad_load_store_p (operands[0], operands[1])"
10065 [(pc)]
10066 {
10067 rs6000_split_multireg_move (operands[0], operands[1]);
10068 DONE;
10069 })
10070 \f
10071 (define_expand "setmemsi"
10072 [(parallel [(set (match_operand:BLK 0 "")
10073 (match_operand 2 "const_int_operand"))
10074 (use (match_operand:SI 1 ""))
10075 (use (match_operand:SI 3 ""))])]
10076 ""
10077 {
10078 /* If value to set is not zero, use the library routine. */
10079 if (operands[2] != const0_rtx)
10080 FAIL;
10081
10082 if (expand_block_clear (operands))
10083 DONE;
10084 else
10085 FAIL;
10086 })
10087
10088 ;; String compare N insn.
10089 ;; Argument 0 is the target (result)
10090 ;; Argument 1 is the destination
10091 ;; Argument 2 is the source
10092 ;; Argument 3 is the length
10093 ;; Argument 4 is the alignment
10094
10095 (define_expand "cmpstrnsi"
10096 [(parallel [(set (match_operand:SI 0)
10097 (compare:SI (match_operand:BLK 1)
10098 (match_operand:BLK 2)))
10099 (use (match_operand:SI 3))
10100 (use (match_operand:SI 4))])]
10101 "TARGET_CMPB && (BYTES_BIG_ENDIAN || TARGET_LDBRX)"
10102 {
10103 if (optimize_insn_for_size_p ())
10104 FAIL;
10105
10106 if (expand_strn_compare (operands, 0))
10107 DONE;
10108 else
10109 FAIL;
10110 })
10111
10112 ;; String compare insn.
10113 ;; Argument 0 is the target (result)
10114 ;; Argument 1 is the destination
10115 ;; Argument 2 is the source
10116 ;; Argument 3 is the alignment
10117
10118 (define_expand "cmpstrsi"
10119 [(parallel [(set (match_operand:SI 0)
10120 (compare:SI (match_operand:BLK 1)
10121 (match_operand:BLK 2)))
10122 (use (match_operand:SI 3))])]
10123 "TARGET_CMPB && (BYTES_BIG_ENDIAN || TARGET_LDBRX)"
10124 {
10125 if (optimize_insn_for_size_p ())
10126 FAIL;
10127
10128 if (expand_strn_compare (operands, 1))
10129 DONE;
10130 else
10131 FAIL;
10132 })
10133
10134 ;; Block compare insn.
10135 ;; Argument 0 is the target (result)
10136 ;; Argument 1 is the destination
10137 ;; Argument 2 is the source
10138 ;; Argument 3 is the length
10139 ;; Argument 4 is the alignment
10140
10141 (define_expand "cmpmemsi"
10142 [(parallel [(set (match_operand:SI 0)
10143 (compare:SI (match_operand:BLK 1)
10144 (match_operand:BLK 2)))
10145 (use (match_operand:SI 3))
10146 (use (match_operand:SI 4))])]
10147 "TARGET_POPCNTD"
10148 {
10149 if (optimize_insn_for_size_p ())
10150 FAIL;
10151
10152 if (expand_block_compare (operands))
10153 DONE;
10154 else
10155 FAIL;
10156 })
10157
10158 ;; String/block copy insn (source and destination must not overlap).
10159 ;; Argument 0 is the destination
10160 ;; Argument 1 is the source
10161 ;; Argument 2 is the length
10162 ;; Argument 3 is the alignment
10163
10164 (define_expand "cpymemsi"
10165 [(parallel [(set (match_operand:BLK 0 "")
10166 (match_operand:BLK 1 ""))
10167 (use (match_operand:SI 2 ""))
10168 (use (match_operand:SI 3 ""))])]
10169 ""
10170 {
10171 if (expand_block_move (operands, false))
10172 DONE;
10173 else
10174 FAIL;
10175 })
10176
10177 ;; String/block move insn (source and destination may overlap).
10178 ;; Argument 0 is the destination
10179 ;; Argument 1 is the source
10180 ;; Argument 2 is the length
10181 ;; Argument 3 is the alignment
10182
10183 (define_expand "movmemsi"
10184 [(parallel [(set (match_operand:BLK 0 "")
10185 (match_operand:BLK 1 ""))
10186 (use (match_operand:SI 2 ""))
10187 (use (match_operand:SI 3 ""))])]
10188 ""
10189 {
10190 if (expand_block_move (operands, true))
10191 DONE;
10192 else
10193 FAIL;
10194 })
10195
10196 \f
10197 ;; Define insns that do load or store with update. Some of these we can
10198 ;; get by using pre-decrement or pre-increment, but the hardware can also
10199 ;; do cases where the increment is not the size of the object.
10200 ;;
10201 ;; In all these cases, we use operands 0 and 1 for the register being
10202 ;; incremented because those are the operands that local-alloc will
10203 ;; tie and these are the pair most likely to be tieable (and the ones
10204 ;; that will benefit the most).
10205
10206 (define_insn "*movdi_update1"
10207 [(set (match_operand:DI 3 "gpc_reg_operand" "=r,r")
10208 (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
10209 (match_operand:P 2 "reg_or_aligned_short_operand" "r,I"))))
10210 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
10211 (plus:P (match_dup 1) (match_dup 2)))]
10212 "TARGET_POWERPC64 && TARGET_UPDATE
10213 && (!avoiding_indexed_address_p (DImode)
10214 || !gpc_reg_operand (operands[2], Pmode))"
10215 "@
10216 ldux %3,%0,%2
10217 ldu %3,%2(%0)"
10218 [(set_attr "type" "load")
10219 (set_attr "update" "yes")
10220 (set_attr "indexed" "yes,no")])
10221
10222 (define_insn "movdi_<mode>_update"
10223 [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
10224 (match_operand:P 2 "reg_or_aligned_short_operand" "r,I")))
10225 (match_operand:DI 3 "gpc_reg_operand" "r,r"))
10226 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
10227 (plus:P (match_dup 1) (match_dup 2)))]
10228 "TARGET_POWERPC64 && TARGET_UPDATE
10229 && (!avoiding_indexed_address_p (DImode)
10230 || !gpc_reg_operand (operands[2], Pmode)
10231 || (REG_P (operands[0])
10232 && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
10233 "@
10234 stdux %3,%0,%2
10235 stdu %3,%2(%0)"
10236 [(set_attr "type" "store")
10237 (set_attr "update" "yes")
10238 (set_attr "indexed" "yes,no")])
10239
10240 ;; This pattern is only conditional on TARGET_64BIT, as it is
10241 ;; needed for stack allocation, even if the user passes -mno-update.
10242 (define_insn "movdi_update_stack"
10243 [(set (mem:DI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0,0")
10244 (match_operand:DI 2 "reg_or_aligned_short_operand" "r,I")))
10245 (match_operand:DI 3 "gpc_reg_operand" "r,r"))
10246 (set (match_operand:DI 0 "gpc_reg_operand" "=b,b")
10247 (plus:DI (match_dup 1) (match_dup 2)))]
10248 "TARGET_64BIT"
10249 "@
10250 stdux %3,%0,%2
10251 stdu %3,%2(%0)"
10252 [(set_attr "type" "store")
10253 (set_attr "update" "yes")
10254 (set_attr "indexed" "yes,no")])
10255
10256 (define_insn "*movsi_update1"
10257 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
10258 (mem:SI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
10259 (match_operand:P 2 "reg_or_short_operand" "r,I"))))
10260 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
10261 (plus:P (match_dup 1) (match_dup 2)))]
10262 "TARGET_UPDATE
10263 && (!avoiding_indexed_address_p (SImode)
10264 || !gpc_reg_operand (operands[2], Pmode))"
10265 "@
10266 lwzux %3,%0,%2
10267 lwzu %3,%2(%0)"
10268 [(set_attr "type" "load")
10269 (set_attr "update" "yes")
10270 (set_attr "indexed" "yes,no")])
10271
10272 (define_insn "*movsi_update2"
10273 [(set (match_operand:EXTSI 3 "gpc_reg_operand" "=r")
10274 (sign_extend:EXTSI
10275 (mem:SI (plus:P (match_operand:P 1 "gpc_reg_operand" "0")
10276 (match_operand:P 2 "gpc_reg_operand" "r")))))
10277 (set (match_operand:P 0 "gpc_reg_operand" "=b")
10278 (plus:P (match_dup 1) (match_dup 2)))]
10279 "TARGET_POWERPC64 && !avoiding_indexed_address_p (DImode)"
10280 "lwaux %3,%0,%2"
10281 [(set_attr "type" "load")
10282 (set_attr "sign_extend" "yes")
10283 (set_attr "update" "yes")
10284 (set_attr "indexed" "yes")])
10285
10286 (define_insn "movsi_<mode>_update"
10287 [(set (mem:SI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
10288 (match_operand:P 2 "reg_or_short_operand" "r,I")))
10289 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
10290 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
10291 (plus:P (match_dup 1) (match_dup 2)))]
10292 "TARGET_UPDATE
10293 && (!avoiding_indexed_address_p (SImode)
10294 || !gpc_reg_operand (operands[2], Pmode)
10295 || (REG_P (operands[0])
10296 && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
10297 "@
10298 stwux %3,%0,%2
10299 stwu %3,%2(%0)"
10300 [(set_attr "type" "store")
10301 (set_attr "update" "yes")
10302 (set_attr "indexed" "yes,no")])
10303
10304 ;; This is an unconditional pattern; needed for stack allocation, even
10305 ;; if the user passes -mno-update.
10306 (define_insn "movsi_update_stack"
10307 [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
10308 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
10309 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
10310 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
10311 (plus:SI (match_dup 1) (match_dup 2)))]
10312 "TARGET_32BIT"
10313 "@
10314 stwux %3,%0,%2
10315 stwu %3,%2(%0)"
10316 [(set_attr "type" "store")
10317 (set_attr "update" "yes")
10318 (set_attr "indexed" "yes,no")])
10319
10320 (define_insn "*movhi_update1"
10321 [(set (match_operand:HI 3 "gpc_reg_operand" "=r,r")
10322 (mem:HI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
10323 (match_operand:P 2 "reg_or_short_operand" "r,I"))))
10324 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
10325 (plus:P (match_dup 1) (match_dup 2)))]
10326 "TARGET_UPDATE
10327 && (!avoiding_indexed_address_p (HImode)
10328 || !gpc_reg_operand (operands[2], SImode))"
10329 "@
10330 lhzux %3,%0,%2
10331 lhzu %3,%2(%0)"
10332 [(set_attr "type" "load")
10333 (set_attr "update" "yes")
10334 (set_attr "indexed" "yes,no")])
10335
10336 (define_insn "*movhi_update2"
10337 [(set (match_operand:EXTHI 3 "gpc_reg_operand" "=r,r")
10338 (zero_extend:EXTHI
10339 (mem:HI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
10340 (match_operand:P 2 "reg_or_short_operand" "r,I")))))
10341 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
10342 (plus:P (match_dup 1) (match_dup 2)))]
10343 "TARGET_UPDATE
10344 && (!avoiding_indexed_address_p (HImode)
10345 || !gpc_reg_operand (operands[2], Pmode))"
10346 "@
10347 lhzux %3,%0,%2
10348 lhzu %3,%2(%0)"
10349 [(set_attr "type" "load")
10350 (set_attr "update" "yes")
10351 (set_attr "indexed" "yes,no")])
10352
10353 (define_insn "*movhi_update3"
10354 [(set (match_operand:EXTHI 3 "gpc_reg_operand" "=r,r")
10355 (sign_extend:EXTHI
10356 (mem:HI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
10357 (match_operand:P 2 "reg_or_short_operand" "r,I")))))
10358 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
10359 (plus:P (match_dup 1) (match_dup 2)))]
10360 "TARGET_UPDATE
10361 && !(avoiding_indexed_address_p (HImode)
10362 && gpc_reg_operand (operands[2], Pmode))"
10363 "@
10364 lhaux %3,%0,%2
10365 lhau %3,%2(%0)"
10366 [(set_attr "type" "load")
10367 (set_attr "sign_extend" "yes")
10368 (set_attr "update" "yes")
10369 (set_attr "indexed" "yes,no")])
10370
10371 (define_insn "*movhi_update4"
10372 [(set (mem:HI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
10373 (match_operand:P 2 "reg_or_short_operand" "r,I")))
10374 (match_operand:HI 3 "gpc_reg_operand" "r,r"))
10375 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
10376 (plus:P (match_dup 1) (match_dup 2)))]
10377 "TARGET_UPDATE
10378 && (!avoiding_indexed_address_p (HImode)
10379 || !gpc_reg_operand (operands[2], Pmode))"
10380 "@
10381 sthux %3,%0,%2
10382 sthu %3,%2(%0)"
10383 [(set_attr "type" "store")
10384 (set_attr "update" "yes")
10385 (set_attr "indexed" "yes,no")])
10386
10387 (define_insn "*movqi_update1"
10388 [(set (match_operand:QI 3 "gpc_reg_operand" "=r,r")
10389 (mem:QI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
10390 (match_operand:P 2 "reg_or_short_operand" "r,I"))))
10391 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
10392 (plus:P (match_dup 1) (match_dup 2)))]
10393 "TARGET_UPDATE
10394 && (!avoiding_indexed_address_p (QImode)
10395 || !gpc_reg_operand (operands[2], Pmode))"
10396 "@
10397 lbzux %3,%0,%2
10398 lbzu %3,%2(%0)"
10399 [(set_attr "type" "load")
10400 (set_attr "update" "yes")
10401 (set_attr "indexed" "yes,no")])
10402
10403 (define_insn "*movqi_update2"
10404 [(set (match_operand:EXTQI 3 "gpc_reg_operand" "=r,r")
10405 (zero_extend:EXTQI
10406 (mem:QI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
10407 (match_operand:P 2 "reg_or_short_operand" "r,I")))))
10408 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
10409 (plus:P (match_dup 1) (match_dup 2)))]
10410 "TARGET_UPDATE
10411 && (!avoiding_indexed_address_p (QImode)
10412 || !gpc_reg_operand (operands[2], Pmode))"
10413 "@
10414 lbzux %3,%0,%2
10415 lbzu %3,%2(%0)"
10416 [(set_attr "type" "load")
10417 (set_attr "update" "yes")
10418 (set_attr "indexed" "yes,no")])
10419
10420 (define_insn "*movqi_update3"
10421 [(set (mem:QI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
10422 (match_operand:P 2 "reg_or_short_operand" "r,I")))
10423 (match_operand:QI 3 "gpc_reg_operand" "r,r"))
10424 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
10425 (plus:P (match_dup 1) (match_dup 2)))]
10426 "TARGET_UPDATE
10427 && (!avoiding_indexed_address_p (QImode)
10428 || !gpc_reg_operand (operands[2], Pmode))"
10429 "@
10430 stbux %3,%0,%2
10431 stbu %3,%2(%0)"
10432 [(set_attr "type" "store")
10433 (set_attr "update" "yes")
10434 (set_attr "indexed" "yes,no")])
10435
10436 (define_insn "*mov<SFDF:mode>_update1"
10437 [(set (match_operand:SFDF 3 "gpc_reg_operand" "=d,d")
10438 (mem:SFDF (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
10439 (match_operand:P 2 "reg_or_short_operand" "r,I"))))
10440 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
10441 (plus:P (match_dup 1) (match_dup 2)))]
10442 "TARGET_HARD_FLOAT && TARGET_UPDATE
10443 && (!avoiding_indexed_address_p (<SFDF:MODE>mode)
10444 || !gpc_reg_operand (operands[2], Pmode))"
10445 "@
10446 lf<sd>ux %3,%0,%2
10447 lf<sd>u %3,%2(%0)"
10448 [(set_attr "type" "fpload")
10449 (set_attr "update" "yes")
10450 (set_attr "indexed" "yes,no")
10451 (set_attr "size" "<SFDF:bits>")])
10452
10453 (define_insn "*mov<SFDF:mode>_update2"
10454 [(set (mem:SFDF (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
10455 (match_operand:P 2 "reg_or_short_operand" "r,I")))
10456 (match_operand:SFDF 3 "gpc_reg_operand" "d,d"))
10457 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
10458 (plus:P (match_dup 1) (match_dup 2)))]
10459 "TARGET_HARD_FLOAT && TARGET_UPDATE
10460 && (!avoiding_indexed_address_p (<SFDF:MODE>mode)
10461 || !gpc_reg_operand (operands[2], Pmode))"
10462 "@
10463 stf<sd>ux %3,%0,%2
10464 stf<sd>u %3,%2(%0)"
10465 [(set_attr "type" "fpstore")
10466 (set_attr "update" "yes")
10467 (set_attr "indexed" "yes,no")
10468 (set_attr "size" "<SFDF:bits>")])
10469
10470 (define_insn "*movsf_update3"
10471 [(set (match_operand:SF 3 "gpc_reg_operand" "=r,r")
10472 (mem:SF (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
10473 (match_operand:P 2 "reg_or_short_operand" "r,I"))))
10474 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
10475 (plus:P (match_dup 1) (match_dup 2)))]
10476 "TARGET_SOFT_FLOAT && TARGET_UPDATE
10477 && (!avoiding_indexed_address_p (SFmode)
10478 || !gpc_reg_operand (operands[2], Pmode))"
10479 "@
10480 lwzux %3,%0,%2
10481 lwzu %3,%2(%0)"
10482 [(set_attr "type" "load")
10483 (set_attr "update" "yes")
10484 (set_attr "indexed" "yes,no")])
10485
10486 (define_insn "*movsf_update4"
10487 [(set (mem:SF (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
10488 (match_operand:P 2 "reg_or_short_operand" "r,I")))
10489 (match_operand:SF 3 "gpc_reg_operand" "r,r"))
10490 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
10491 (plus:P (match_dup 1) (match_dup 2)))]
10492 "TARGET_SOFT_FLOAT && TARGET_UPDATE
10493 && (!avoiding_indexed_address_p (SFmode)
10494 || !gpc_reg_operand (operands[2], Pmode))"
10495 "@
10496 stwux %3,%0,%2
10497 stwu %3,%2(%0)"
10498 [(set_attr "type" "store")
10499 (set_attr "update" "yes")
10500 (set_attr "indexed" "yes,no")])
10501
10502
10503 ;; After inserting conditional returns we can sometimes have
10504 ;; unnecessary register moves. Unfortunately we cannot have a
10505 ;; modeless peephole here, because some single SImode sets have early
10506 ;; clobber outputs. Although those sets expand to multi-ppc-insn
10507 ;; sequences, using get_attr_length here will smash the operands
10508 ;; array. Neither is there an early_cobbler_p predicate.
10509 ;; Also this optimization interferes with scalars going into
10510 ;; altivec registers (the code does reloading through the FPRs).
10511 (define_peephole2
10512 [(set (match_operand:DF 0 "gpc_reg_operand")
10513 (match_operand:DF 1 "any_operand"))
10514 (set (match_operand:DF 2 "gpc_reg_operand")
10515 (match_dup 0))]
10516 "!TARGET_VSX
10517 && peep2_reg_dead_p (2, operands[0])"
10518 [(set (match_dup 2) (match_dup 1))])
10519
10520 (define_peephole2
10521 [(set (match_operand:SF 0 "gpc_reg_operand")
10522 (match_operand:SF 1 "any_operand"))
10523 (set (match_operand:SF 2 "gpc_reg_operand")
10524 (match_dup 0))]
10525 "!TARGET_P8_VECTOR
10526 && peep2_reg_dead_p (2, operands[0])"
10527 [(set (match_dup 2) (match_dup 1))])
10528
10529 \f
10530 ;; TLS support.
10531
10532 (define_insn "*tls_gd_pcrel<bits>"
10533 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
10534 (unspec:P [(match_operand:P 1 "rs6000_tls_symbol_ref" "")
10535 (const_int 0)]
10536 UNSPEC_TLSGD))]
10537 "HAVE_AS_TLS && TARGET_ELF"
10538 "la %0,%1@got@tlsgd@pcrel"
10539 [(set_attr "prefixed" "yes")])
10540
10541 (define_insn_and_split "*tls_gd<bits>"
10542 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
10543 (unspec:P [(match_operand:P 1 "rs6000_tls_symbol_ref" "")
10544 (match_operand:P 2 "gpc_reg_operand" "b")]
10545 UNSPEC_TLSGD))]
10546 "HAVE_AS_TLS && TARGET_ELF"
10547 "addi %0,%2,%1@got@tlsgd"
10548 "&& TARGET_CMODEL != CMODEL_SMALL"
10549 [(set (match_dup 3)
10550 (high:P
10551 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))
10552 (set (match_dup 0)
10553 (lo_sum:P (match_dup 3)
10554 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))]
10555 {
10556 operands[3] = gen_reg_rtx (<MODE>mode);
10557 }
10558 [(set (attr "length")
10559 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
10560 (const_int 8)
10561 (const_int 4)))])
10562
10563 (define_insn "*tls_gd_high<bits>"
10564 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
10565 (high:P
10566 (unspec:P [(match_operand:P 1 "rs6000_tls_symbol_ref" "")
10567 (match_operand:P 2 "gpc_reg_operand" "b")]
10568 UNSPEC_TLSGD)))]
10569 "HAVE_AS_TLS && TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10570 "addis %0,%2,%1@got@tlsgd@ha")
10571
10572 (define_insn "*tls_gd_low<bits>"
10573 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
10574 (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
10575 (unspec:P [(match_operand:P 2 "rs6000_tls_symbol_ref" "")
10576 (match_operand:P 3 "gpc_reg_operand" "b")]
10577 UNSPEC_TLSGD)))]
10578 "HAVE_AS_TLS && TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10579 "addi %0,%1,%2@got@tlsgd@l")
10580
10581 (define_insn "*tls_ld_pcrel<bits>"
10582 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
10583 (unspec:P [(const_int 0)]
10584 UNSPEC_TLSLD))]
10585 "HAVE_AS_TLS && TARGET_ELF"
10586 "la %0,%&@got@tlsld@pcrel"
10587 [(set_attr "prefixed" "yes")])
10588
10589 (define_insn_and_split "*tls_ld<bits>"
10590 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
10591 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")]
10592 UNSPEC_TLSLD))]
10593 "HAVE_AS_TLS && TARGET_ELF"
10594 "addi %0,%1,%&@got@tlsld"
10595 "&& TARGET_CMODEL != CMODEL_SMALL"
10596 [(set (match_dup 2)
10597 (high:P
10598 (unspec:P [(match_dup 1)] UNSPEC_TLSLD)))
10599 (set (match_dup 0)
10600 (lo_sum:P (match_dup 2)
10601 (unspec:P [(match_dup 1)] UNSPEC_TLSLD)))]
10602 {
10603 operands[2] = gen_reg_rtx (<MODE>mode);
10604 }
10605 [(set (attr "length")
10606 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
10607 (const_int 8)
10608 (const_int 4)))])
10609
10610 (define_insn "*tls_ld_high<bits>"
10611 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
10612 (high:P
10613 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")]
10614 UNSPEC_TLSLD)))]
10615 "HAVE_AS_TLS && TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10616 "addis %0,%1,%&@got@tlsld@ha")
10617
10618 (define_insn "*tls_ld_low<bits>"
10619 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
10620 (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
10621 (unspec:P [(match_operand:P 2 "gpc_reg_operand" "b")]
10622 UNSPEC_TLSLD)))]
10623 "HAVE_AS_TLS && TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10624 "addi %0,%1,%&@got@tlsld@l")
10625
10626 (define_insn "tls_dtprel_<bits>"
10627 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10628 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
10629 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
10630 UNSPEC_TLSDTPREL))]
10631 "HAVE_AS_TLS"
10632 "addi %0,%1,%2@dtprel"
10633 [(set (attr "prefixed")
10634 (if_then_else (match_test "rs6000_tls_size == 16")
10635 (const_string "no")
10636 (const_string "yes")))])
10637
10638 (define_insn "tls_dtprel_ha_<bits>"
10639 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10640 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
10641 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
10642 UNSPEC_TLSDTPRELHA))]
10643 "HAVE_AS_TLS"
10644 "addis %0,%1,%2@dtprel@ha")
10645
10646 (define_insn "tls_dtprel_lo_<bits>"
10647 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10648 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
10649 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
10650 UNSPEC_TLSDTPRELLO))]
10651 "HAVE_AS_TLS"
10652 "addi %0,%1,%2@dtprel@l")
10653
10654 (define_insn_and_split "tls_got_dtprel_<bits>"
10655 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10656 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
10657 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
10658 UNSPEC_TLSGOTDTPREL))]
10659 "HAVE_AS_TLS"
10660 "<ptrload> %0,%2@got@dtprel(%1)"
10661 "&& TARGET_CMODEL != CMODEL_SMALL"
10662 [(set (match_dup 3)
10663 (high:P
10664 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))
10665 (set (match_dup 0)
10666 (lo_sum:P (match_dup 3)
10667 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))]
10668 {
10669 operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
10670 }
10671 [(set (attr "length")
10672 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
10673 (const_int 8)
10674 (const_int 4)))])
10675
10676 (define_insn "*tls_got_dtprel_high<bits>"
10677 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
10678 (high:P
10679 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
10680 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
10681 UNSPEC_TLSGOTDTPREL)))]
10682 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
10683 "addis %0,%1,%2@got@dtprel@ha")
10684
10685 (define_insn "*tls_got_dtprel_low<bits>"
10686 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10687 (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
10688 (unspec:P [(match_operand:P 3 "gpc_reg_operand" "b")
10689 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
10690 UNSPEC_TLSGOTDTPREL)))]
10691 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
10692 "<ptrload> %0,%2@got@dtprel@l(%1)")
10693
10694 (define_insn "tls_tprel_<bits>"
10695 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10696 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
10697 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
10698 UNSPEC_TLSTPREL))]
10699 "HAVE_AS_TLS"
10700 "addi %0,%1,%2@tprel"
10701 [(set (attr "prefixed")
10702 (if_then_else (match_test "rs6000_tls_size == 16")
10703 (const_string "no")
10704 (const_string "yes")))])
10705
10706 (define_insn "tls_tprel_ha_<bits>"
10707 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10708 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
10709 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
10710 UNSPEC_TLSTPRELHA))]
10711 "HAVE_AS_TLS"
10712 "addis %0,%1,%2@tprel@ha")
10713
10714 (define_insn "tls_tprel_lo_<bits>"
10715 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10716 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
10717 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
10718 UNSPEC_TLSTPRELLO))]
10719 "HAVE_AS_TLS"
10720 "addi %0,%1,%2@tprel@l")
10721
10722 (define_insn "*tls_got_tprel_pcrel_<bits>"
10723 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
10724 (unspec:P [(const_int 0)
10725 (match_operand:P 1 "rs6000_tls_symbol_ref" "")]
10726 UNSPEC_TLSGOTTPREL))]
10727 "HAVE_AS_TLS"
10728 "<ptrload> %0,%1@got@tprel@pcrel"
10729 [(set_attr "prefixed" "yes")])
10730
10731 ;; "b" output constraint here and on tls_tls input to support linker tls
10732 ;; optimization. The linker may edit the instructions emitted by a
10733 ;; tls_got_tprel/tls_tls pair to addis,addi.
10734 (define_insn_and_split "tls_got_tprel_<bits>"
10735 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
10736 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
10737 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
10738 UNSPEC_TLSGOTTPREL))]
10739 "HAVE_AS_TLS"
10740 "<ptrload> %0,%2@got@tprel(%1)"
10741 "&& TARGET_CMODEL != CMODEL_SMALL"
10742 [(set (match_dup 3)
10743 (high:P
10744 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))
10745 (set (match_dup 0)
10746 (lo_sum:P (match_dup 3)
10747 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))]
10748 {
10749 operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
10750 }
10751 [(set (attr "length")
10752 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
10753 (const_int 8)
10754 (const_int 4)))])
10755
10756 (define_insn "*tls_got_tprel_high<bits>"
10757 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
10758 (high:P
10759 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
10760 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
10761 UNSPEC_TLSGOTTPREL)))]
10762 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
10763 "addis %0,%1,%2@got@tprel@ha")
10764
10765 (define_insn "*tls_got_tprel_low<bits>"
10766 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10767 (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
10768 (unspec:P [(match_operand:P 3 "gpc_reg_operand" "b")
10769 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
10770 UNSPEC_TLSGOTTPREL)))]
10771 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
10772 "<ptrload> %0,%2@got@tprel@l(%1)")
10773
10774 (define_insn "tls_tls_pcrel_<bits>"
10775 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10776 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
10777 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
10778 UNSPEC_TLSTLS_PCREL))]
10779 "TARGET_ELF && HAVE_AS_TLS"
10780 "add %0,%1,%2@tls@pcrel")
10781
10782 (define_insn "tls_tls_<bits>"
10783 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10784 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
10785 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
10786 UNSPEC_TLSTLS))]
10787 "TARGET_ELF && HAVE_AS_TLS"
10788 "add %0,%1,%2@tls")
10789
10790 (define_expand "tls_get_tpointer"
10791 [(set (match_operand:SI 0 "gpc_reg_operand")
10792 (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))]
10793 "TARGET_XCOFF && HAVE_AS_TLS"
10794 {
10795 emit_insn (gen_tls_get_tpointer_internal ());
10796 emit_move_insn (operands[0], gen_rtx_REG (SImode, 3));
10797 DONE;
10798 })
10799
10800 (define_insn "tls_get_tpointer_internal"
10801 [(set (reg:SI 3)
10802 (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))
10803 (clobber (reg:SI LR_REGNO))]
10804 "TARGET_XCOFF && HAVE_AS_TLS"
10805 "bla .__get_tpointer")
10806
10807 (define_expand "tls_get_addr<mode>"
10808 [(set (match_operand:P 0 "gpc_reg_operand")
10809 (unspec:P [(match_operand:P 1 "gpc_reg_operand")
10810 (match_operand:P 2 "gpc_reg_operand")] UNSPEC_TLSTLS))]
10811 "TARGET_XCOFF && HAVE_AS_TLS"
10812 {
10813 emit_move_insn (gen_rtx_REG (Pmode, 3), operands[1]);
10814 emit_move_insn (gen_rtx_REG (Pmode, 4), operands[2]);
10815 emit_insn (gen_tls_get_addr_internal<mode> ());
10816 emit_move_insn (operands[0], gen_rtx_REG (Pmode, 3));
10817 DONE;
10818 })
10819
10820 (define_insn "tls_get_addr_internal<mode>"
10821 [(set (reg:P 3)
10822 (unspec:P [(reg:P 3) (reg:P 4)] UNSPEC_TLSTLS))
10823 (clobber (reg:P 0))
10824 (clobber (reg:P 4))
10825 (clobber (reg:P 5))
10826 (clobber (reg:P 11))
10827 (clobber (reg:CC CR0_REGNO))
10828 (clobber (reg:P LR_REGNO))]
10829 "TARGET_XCOFF && HAVE_AS_TLS"
10830 "bla .__tls_get_addr")
10831 \f
10832 ;; Next come insns related to the calling sequence.
10833 ;;
10834 ;; First, an insn to allocate new stack space for dynamic use (e.g., alloca).
10835 ;; We move the back-chain and decrement the stack pointer.
10836 ;;
10837 ;; Operand1 is more naturally reg_or_short_operand. However, for a large
10838 ;; constant alloca, using that predicate will force the generic code to put
10839 ;; the constant size into a register before calling the expander.
10840 ;;
10841 ;; As a result the expander would not have the constant size information
10842 ;; in those cases and would have to generate less efficient code.
10843 ;;
10844 ;; Thus we allow reg_or_cint_operand instead so that the expander can see
10845 ;; the constant size. The value is forced into a register if necessary.
10846 ;;
10847 (define_expand "allocate_stack"
10848 [(set (match_operand 0 "gpc_reg_operand")
10849 (minus (reg 1) (match_operand 1 "reg_or_cint_operand")))
10850 (set (reg 1)
10851 (minus (reg 1) (match_dup 1)))]
10852 ""
10853 {
10854 rtx chain = gen_reg_rtx (Pmode);
10855 rtx stack_bot = gen_rtx_MEM (Pmode, stack_pointer_rtx);
10856 rtx neg_op0;
10857 rtx insn, par, set, mem;
10858
10859 /* By allowing reg_or_cint_operand as the predicate we can get
10860 better code for stack-clash-protection because we do not lose
10861 size information. But the rest of the code expects the operand
10862 to be reg_or_short_operand. If it isn't, then force it into
10863 a register. */
10864 rtx orig_op1 = operands[1];
10865 if (!reg_or_short_operand (operands[1], Pmode))
10866 operands[1] = force_reg (Pmode, operands[1]);
10867
10868 emit_move_insn (chain, stack_bot);
10869
10870 /* Check stack bounds if necessary. */
10871 if (crtl->limit_stack)
10872 {
10873 rtx available;
10874 available = expand_binop (Pmode, sub_optab,
10875 stack_pointer_rtx, stack_limit_rtx,
10876 NULL_RTX, 1, OPTAB_WIDEN);
10877 emit_insn (gen_cond_trap (LTU, available, operands[1], const0_rtx));
10878 }
10879
10880 /* Allocate and probe if requested.
10881 This may look similar to the loop we use for prologue allocations,
10882 but it is critically different. For the former we know the loop
10883 will iterate, but do not know that generally here. The former
10884 uses that knowledge to rotate the loop. Combining them would be
10885 possible with some performance cost. */
10886 if (flag_stack_clash_protection)
10887 {
10888 rtx rounded_size, last_addr, residual;
10889 HOST_WIDE_INT probe_interval;
10890 compute_stack_clash_protection_loop_data (&rounded_size, &last_addr,
10891 &residual, &probe_interval,
10892 orig_op1);
10893
10894 /* We do occasionally get in here with constant sizes, we might
10895 as well do a reasonable job when we obviously can. */
10896 if (rounded_size != const0_rtx)
10897 {
10898 rtx loop_lab, end_loop;
10899 bool rotated = CONST_INT_P (rounded_size);
10900 rtx update = GEN_INT (-probe_interval);
10901 if (probe_interval > 32768)
10902 update = force_reg (Pmode, update);
10903
10904 emit_stack_clash_protection_probe_loop_start (&loop_lab, &end_loop,
10905 last_addr, rotated);
10906
10907 if (TARGET_32BIT)
10908 emit_insn (gen_movsi_update_stack (stack_pointer_rtx,
10909 stack_pointer_rtx,
10910 update, chain));
10911 else
10912 emit_insn (gen_movdi_update_stack (stack_pointer_rtx,
10913 stack_pointer_rtx,
10914 update, chain));
10915 emit_stack_clash_protection_probe_loop_end (loop_lab, end_loop,
10916 last_addr, rotated);
10917 }
10918
10919 /* Now handle residuals. We just have to set operands[1] correctly
10920 and let the rest of the expander run. */
10921 operands[1] = residual;
10922 }
10923
10924 if (!(CONST_INT_P (operands[1])
10925 && IN_RANGE (INTVAL (operands[1]), -32767, 32768)))
10926 {
10927 operands[1] = force_reg (Pmode, operands[1]);
10928 neg_op0 = gen_reg_rtx (Pmode);
10929 emit_insn (gen_neg2 (Pmode, neg_op0, operands[1]));
10930 }
10931 else
10932 neg_op0 = GEN_INT (-INTVAL (operands[1]));
10933
10934 insn = emit_insn ((* ((TARGET_32BIT) ? gen_movsi_update_stack
10935 : gen_movdi_update_stack))
10936 (stack_pointer_rtx, stack_pointer_rtx, neg_op0,
10937 chain));
10938 /* Since we didn't use gen_frame_mem to generate the MEM, grab
10939 it now and set the alias set/attributes. The above gen_*_update
10940 calls will generate a PARALLEL with the MEM set being the first
10941 operation. */
10942 par = PATTERN (insn);
10943 gcc_assert (GET_CODE (par) == PARALLEL);
10944 set = XVECEXP (par, 0, 0);
10945 gcc_assert (GET_CODE (set) == SET);
10946 mem = SET_DEST (set);
10947 gcc_assert (MEM_P (mem));
10948 MEM_NOTRAP_P (mem) = 1;
10949 set_mem_alias_set (mem, get_frame_alias_set ());
10950
10951 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
10952 DONE;
10953 })
10954
10955 ;; These patterns say how to save and restore the stack pointer. We need not
10956 ;; save the stack pointer at function level since we are careful to
10957 ;; preserve the backchain. At block level, we have to restore the backchain
10958 ;; when we restore the stack pointer.
10959 ;;
10960 ;; For nonlocal gotos, we must save both the stack pointer and its
10961 ;; backchain and restore both. Note that in the nonlocal case, the
10962 ;; save area is a memory location.
10963
10964 (define_expand "save_stack_function"
10965 [(match_operand 0 "any_operand")
10966 (match_operand 1 "any_operand")]
10967 ""
10968 "DONE;")
10969
10970 (define_expand "restore_stack_function"
10971 [(match_operand 0 "any_operand")
10972 (match_operand 1 "any_operand")]
10973 ""
10974 "DONE;")
10975
10976 ;; Adjust stack pointer (op0) to a new value (op1).
10977 ;; First copy old stack backchain to new location, and ensure that the
10978 ;; scheduler won't reorder the sp assignment before the backchain write.
10979 (define_expand "restore_stack_block"
10980 [(set (match_dup 2) (match_dup 3))
10981 (set (match_dup 4) (match_dup 2))
10982 (match_dup 5)
10983 (set (match_operand 0 "register_operand")
10984 (match_operand 1 "register_operand"))]
10985 ""
10986 {
10987 rtvec p;
10988
10989 operands[1] = force_reg (Pmode, operands[1]);
10990 operands[2] = gen_reg_rtx (Pmode);
10991 operands[3] = gen_frame_mem (Pmode, operands[0]);
10992 operands[4] = gen_frame_mem (Pmode, operands[1]);
10993 p = rtvec_alloc (1);
10994 RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
10995 const0_rtx);
10996 operands[5] = gen_rtx_PARALLEL (VOIDmode, p);
10997 })
10998
10999 (define_expand "save_stack_nonlocal"
11000 [(set (match_dup 3) (match_dup 4))
11001 (set (match_operand 0 "memory_operand") (match_dup 3))
11002 (set (match_dup 2) (match_operand 1 "register_operand"))]
11003 ""
11004 {
11005 int units_per_word = (TARGET_32BIT) ? 4 : 8;
11006
11007 /* Copy the backchain to the first word, sp to the second. */
11008 operands[0] = adjust_address_nv (operands[0], Pmode, 0);
11009 operands[2] = adjust_address_nv (operands[0], Pmode, units_per_word);
11010 operands[3] = gen_reg_rtx (Pmode);
11011 operands[4] = gen_frame_mem (Pmode, operands[1]);
11012 })
11013
11014 (define_expand "restore_stack_nonlocal"
11015 [(set (match_dup 2) (match_operand 1 "memory_operand"))
11016 (set (match_dup 3) (match_dup 4))
11017 (set (match_dup 5) (match_dup 2))
11018 (match_dup 6)
11019 (set (match_operand 0 "register_operand") (match_dup 3))]
11020 ""
11021 {
11022 int units_per_word = (TARGET_32BIT) ? 4 : 8;
11023 rtvec p;
11024
11025 /* Restore the backchain from the first word, sp from the second. */
11026 operands[2] = gen_reg_rtx (Pmode);
11027 operands[3] = gen_reg_rtx (Pmode);
11028 operands[1] = adjust_address_nv (operands[1], Pmode, 0);
11029 operands[4] = adjust_address_nv (operands[1], Pmode, units_per_word);
11030 operands[5] = gen_frame_mem (Pmode, operands[3]);
11031 p = rtvec_alloc (1);
11032 RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
11033 const0_rtx);
11034 operands[6] = gen_rtx_PARALLEL (VOIDmode, p);
11035 })
11036 \f
11037 ;; Load up a PC-relative address. Print_operand_address will append a @pcrel
11038 ;; to the symbol or label.
11039 (define_insn "*pcrel_local_addr"
11040 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
11041 (match_operand:DI 1 "pcrel_local_address"))]
11042 "TARGET_PCREL"
11043 "la %0,%a1"
11044 [(set_attr "prefixed" "yes")])
11045
11046 ;; Load up a PC-relative address to an external symbol. If the symbol and the
11047 ;; program are both defined in the main program, the linker will optimize this
11048 ;; to a PADDI. Otherwise, it will create a GOT address that is relocated by
11049 ;; the dynamic linker and loaded up. Print_operand_address will append a
11050 ;; @got@pcrel to the symbol.
11051 (define_insn "*pcrel_extern_addr"
11052 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
11053 (match_operand:DI 1 "pcrel_external_address"))]
11054 "TARGET_PCREL"
11055 "ld %0,%a1"
11056 [(set_attr "prefixed" "yes")
11057 (set_attr "type" "load")
11058 (set_attr "loads_external_address" "yes")])
11059
11060 ;; TOC register handling.
11061
11062 ;; Code to initialize the TOC register...
11063
11064 (define_insn "load_toc_aix_si"
11065 [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11066 (unspec:SI [(const_int 0)] UNSPEC_TOC))
11067 (use (reg:SI 2))])]
11068 "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_32BIT"
11069 {
11070 char buf[30];
11071 extern int need_toc_init;
11072 need_toc_init = 1;
11073 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
11074 operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
11075 operands[2] = gen_rtx_REG (Pmode, 2);
11076 return "lwz %0,%1(%2)";
11077 }
11078 [(set_attr "type" "load")
11079 (set_attr "update" "no")
11080 (set_attr "indexed" "no")])
11081
11082 (define_insn "load_toc_aix_di"
11083 [(parallel [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
11084 (unspec:DI [(const_int 0)] UNSPEC_TOC))
11085 (use (reg:DI 2))])]
11086 "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_64BIT"
11087 {
11088 char buf[30];
11089 extern int need_toc_init;
11090 need_toc_init = 1;
11091 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC",
11092 !TARGET_ELF || !TARGET_MINIMAL_TOC);
11093 if (TARGET_ELF)
11094 strcat (buf, "@toc");
11095 operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
11096 operands[2] = gen_rtx_REG (Pmode, 2);
11097 return "ld %0,%1(%2)";
11098 }
11099 [(set_attr "type" "load")
11100 (set_attr "update" "no")
11101 (set_attr "indexed" "no")])
11102
11103 (define_insn "load_toc_v4_pic_si"
11104 [(set (reg:SI LR_REGNO)
11105 (unspec:SI [(const_int 0)] UNSPEC_TOC))]
11106 "DEFAULT_ABI == ABI_V4 && flag_pic == 1 && TARGET_32BIT"
11107 "bl _GLOBAL_OFFSET_TABLE_@local-4"
11108 [(set_attr "type" "branch")])
11109
11110 (define_expand "load_toc_v4_PIC_1"
11111 [(parallel [(set (reg:SI LR_REGNO)
11112 (match_operand:SI 0 "immediate_operand" "s"))
11113 (use (unspec [(match_dup 0)] UNSPEC_TOC))])]
11114 "TARGET_ELF && DEFAULT_ABI == ABI_V4
11115 && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
11116 "")
11117
11118 (define_insn "load_toc_v4_PIC_1_normal"
11119 [(set (reg:SI LR_REGNO)
11120 (match_operand:SI 0 "immediate_operand" "s"))
11121 (use (unspec [(match_dup 0)] UNSPEC_TOC))]
11122 "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
11123 && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
11124 "bcl 20,31,%0\n%0:"
11125 [(set_attr "type" "branch")
11126 (set_attr "cannot_copy" "yes")])
11127
11128 (define_insn "load_toc_v4_PIC_1_476"
11129 [(set (reg:SI LR_REGNO)
11130 (match_operand:SI 0 "immediate_operand" "s"))
11131 (use (unspec [(match_dup 0)] UNSPEC_TOC))]
11132 "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
11133 && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
11134 {
11135 char name[32];
11136 static char templ[32];
11137
11138 get_ppc476_thunk_name (name);
11139 sprintf (templ, "bl %s\n%%0:", name);
11140 return templ;
11141 }
11142 [(set_attr "type" "branch")
11143 (set_attr "cannot_copy" "yes")])
11144
11145 (define_expand "load_toc_v4_PIC_1b"
11146 [(parallel [(set (reg:SI LR_REGNO)
11147 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
11148 (label_ref (match_operand 1 ""))]
11149 UNSPEC_TOCPTR))
11150 (match_dup 1)])]
11151 "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
11152 "")
11153
11154 (define_insn "load_toc_v4_PIC_1b_normal"
11155 [(set (reg:SI LR_REGNO)
11156 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
11157 (label_ref (match_operand 1 "" ""))]
11158 UNSPEC_TOCPTR))
11159 (match_dup 1)]
11160 "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
11161 "bcl 20,31,$+8\;.long %0-$"
11162 [(set_attr "type" "branch")
11163 (set_attr "length" "8")])
11164
11165 (define_insn "load_toc_v4_PIC_1b_476"
11166 [(set (reg:SI LR_REGNO)
11167 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
11168 (label_ref (match_operand 1 "" ""))]
11169 UNSPEC_TOCPTR))
11170 (match_dup 1)]
11171 "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
11172 {
11173 char name[32];
11174 static char templ[32];
11175
11176 get_ppc476_thunk_name (name);
11177 sprintf (templ, "bl %s\;b $+8\;.long %%0-$", name);
11178 return templ;
11179 }
11180 [(set_attr "type" "branch")
11181 (set_attr "length" "16")])
11182
11183 (define_insn "load_toc_v4_PIC_2"
11184 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11185 (mem:SI (plus:SI
11186 (match_operand:SI 1 "gpc_reg_operand" "b")
11187 (const
11188 (minus:SI (match_operand:SI 2 "immediate_operand" "s")
11189 (match_operand:SI 3 "immediate_operand" "s"))))))]
11190 "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
11191 "lwz %0,%2-%3(%1)"
11192 [(set_attr "type" "load")])
11193
11194 (define_insn "load_toc_v4_PIC_3b"
11195 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11196 (plus:SI
11197 (match_operand:SI 1 "gpc_reg_operand" "b")
11198 (high:SI
11199 (const
11200 (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
11201 (match_operand:SI 3 "symbol_ref_operand" "s"))))))]
11202 "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
11203 "addis %0,%1,%2-%3@ha")
11204
11205 (define_insn "load_toc_v4_PIC_3c"
11206 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11207 (lo_sum:SI
11208 (match_operand:SI 1 "gpc_reg_operand" "b")
11209 (const
11210 (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
11211 (match_operand:SI 3 "symbol_ref_operand" "s")))))]
11212 "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
11213 "addi %0,%1,%2-%3@l")
11214
11215 ;; If the TOC is shared over a translation unit, as happens with all
11216 ;; the kinds of PIC that we support, we need to restore the TOC
11217 ;; pointer only when jumping over units of translation.
11218 ;; On Darwin, we need to reload the picbase.
11219
11220 (define_expand "builtin_setjmp_receiver"
11221 [(use (label_ref (match_operand 0 "")))]
11222 "(DEFAULT_ABI == ABI_V4 && flag_pic == 1)
11223 || (TARGET_TOC && TARGET_MINIMAL_TOC)
11224 || (DEFAULT_ABI == ABI_DARWIN && flag_pic)"
11225 {
11226 #if TARGET_MACHO
11227 if (DEFAULT_ABI == ABI_DARWIN)
11228 {
11229 rtx picrtx = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME);
11230 rtx picreg = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
11231 rtx tmplabrtx;
11232 char tmplab[20];
11233
11234 crtl->uses_pic_offset_table = 1;
11235 ASM_GENERATE_INTERNAL_LABEL(tmplab, "LSJR",
11236 CODE_LABEL_NUMBER (operands[0]));
11237 tmplabrtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (tmplab));
11238
11239 emit_insn (gen_load_macho_picbase (Pmode, tmplabrtx));
11240 emit_move_insn (picreg, gen_rtx_REG (Pmode, LR_REGNO));
11241 emit_insn (gen_macho_correct_pic (Pmode, picreg, picreg,
11242 picrtx, tmplabrtx));
11243 }
11244 else
11245 #endif
11246 rs6000_emit_load_toc_table (FALSE);
11247 DONE;
11248 })
11249
11250 ;; Largetoc support
11251 (define_insn "*largetoc_high"
11252 [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
11253 (high:DI
11254 (unspec [(match_operand:DI 1 "" "")
11255 (match_operand:DI 2 "gpc_reg_operand" "b")]
11256 UNSPEC_TOCREL)))]
11257 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
11258 "addis %0,%2,%1@toc@ha")
11259
11260 (define_insn "*largetoc_high_aix<mode>"
11261 [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
11262 (high:P
11263 (unspec [(match_operand:P 1 "" "")
11264 (match_operand:P 2 "gpc_reg_operand" "b")]
11265 UNSPEC_TOCREL)))]
11266 "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
11267 "addis %0,%1@u(%2)")
11268
11269 (define_insn "*largetoc_high_plus"
11270 [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
11271 (high:DI
11272 (plus:DI
11273 (unspec [(match_operand:DI 1 "" "")
11274 (match_operand:DI 2 "gpc_reg_operand" "b")]
11275 UNSPEC_TOCREL)
11276 (match_operand:DI 3 "add_cint_operand" "n"))))]
11277 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
11278 "addis %0,%2,%1+%3@toc@ha")
11279
11280 (define_insn "*largetoc_high_plus_aix<mode>"
11281 [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
11282 (high:P
11283 (plus:P
11284 (unspec [(match_operand:P 1 "" "")
11285 (match_operand:P 2 "gpc_reg_operand" "b")]
11286 UNSPEC_TOCREL)
11287 (match_operand:P 3 "add_cint_operand" "n"))))]
11288 "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
11289 "addis %0,%1+%3@u(%2)")
11290
11291 (define_insn "*largetoc_low"
11292 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
11293 (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b")
11294 (match_operand:DI 2 "" "")))]
11295 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
11296 "addi %0,%1,%2@l")
11297
11298 (define_insn "*largetoc_low_aix<mode>"
11299 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11300 (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
11301 (match_operand:P 2 "" "")))]
11302 "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
11303 "la %0,%2@l(%1)")
11304
11305 (define_insn_and_split "*tocref<mode>"
11306 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
11307 (match_operand:P 1 "small_toc_ref" "R"))]
11308 "TARGET_TOC
11309 && legitimate_constant_pool_address_p (operands[1], QImode, false)"
11310 "la %0,%a1"
11311 "&& TARGET_CMODEL != CMODEL_SMALL && reload_completed"
11312 [(set (match_dup 0) (high:P (match_dup 1)))
11313 (set (match_dup 0) (lo_sum:P (match_dup 0) (match_dup 1)))])
11314
11315 ;; Elf specific ways of loading addresses for non-PIC code.
11316 ;; The output of this could be r0, but we make a very strong
11317 ;; preference for a base register because it will usually
11318 ;; be needed there.
11319 (define_insn "elf_high"
11320 [(set (match_operand:SI 0 "gpc_reg_operand" "=b*r")
11321 (high:SI (match_operand 1 "" "")))]
11322 "TARGET_ELF && !TARGET_64BIT && !flag_pic"
11323 "lis %0,%1@ha")
11324
11325 (define_insn "elf_low"
11326 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11327 (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
11328 (match_operand 2 "" "")))]
11329 "TARGET_ELF && !TARGET_64BIT && !flag_pic"
11330 "la %0,%2@l(%1)")
11331
11332 (define_insn "*pltseq_tocsave_<mode>"
11333 [(set (match_operand:P 0 "memory_operand" "=m")
11334 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
11335 (match_operand:P 2 "symbol_ref_operand" "s")
11336 (match_operand:P 3 "" "")]
11337 UNSPEC_PLTSEQ))]
11338 "TARGET_PLTSEQ
11339 && DEFAULT_ABI == ABI_ELFv2"
11340 {
11341 return rs6000_pltseq_template (operands, RS6000_PLTSEQ_TOCSAVE);
11342 })
11343
11344 (define_insn "*pltseq_plt16_ha_<mode>"
11345 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11346 (unspec:P [(match_operand:P 1 "" "")
11347 (match_operand:P 2 "symbol_ref_operand" "s")
11348 (match_operand:P 3 "" "")]
11349 UNSPEC_PLT16_HA))]
11350 "TARGET_PLTSEQ"
11351 {
11352 return rs6000_pltseq_template (operands, RS6000_PLTSEQ_PLT16_HA);
11353 })
11354
11355 (define_insn "*pltseq_plt16_lo_<mode>"
11356 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11357 (unspec_volatile:P [(match_operand:P 1 "gpc_reg_operand" "b")
11358 (match_operand:P 2 "symbol_ref_operand" "s")
11359 (match_operand:P 3 "" "")]
11360 UNSPECV_PLT16_LO))]
11361 "TARGET_PLTSEQ"
11362 {
11363 return rs6000_pltseq_template (operands, RS6000_PLTSEQ_PLT16_LO);
11364 }
11365 [(set_attr "type" "load")])
11366
11367 (define_insn "*pltseq_mtctr_<mode>"
11368 [(set (match_operand:P 0 "register_operand" "=c")
11369 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "r")
11370 (match_operand:P 2 "symbol_ref_operand" "s")
11371 (match_operand:P 3 "" "")]
11372 UNSPEC_PLTSEQ))]
11373 "TARGET_PLTSEQ"
11374 {
11375 return rs6000_pltseq_template (operands, RS6000_PLTSEQ_MTCTR);
11376 })
11377
11378 (define_insn "*pltseq_plt_pcrel<mode>"
11379 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11380 (unspec_volatile:P [(match_operand:P 1 "" "")
11381 (match_operand:P 2 "symbol_ref_operand" "s")
11382 (match_operand:P 3 "" "")]
11383 UNSPECV_PLT_PCREL))]
11384 "HAVE_AS_PLTSEQ && TARGET_ELF
11385 && rs6000_pcrel_p ()"
11386 {
11387 return rs6000_pltseq_template (operands, RS6000_PLTSEQ_PLT_PCREL34);
11388 }
11389 [(set_attr "type" "load")
11390 (set_attr "length" "12")])
11391 \f
11392 ;; Call and call_value insns
11393 ;; For the purposes of expanding calls, Darwin is very similar to SYSV.
11394 (define_expand "call"
11395 [(parallel [(call (mem:SI (match_operand 0 "address_operand"))
11396 (match_operand 1 ""))
11397 (use (match_operand 2 ""))
11398 (clobber (reg:SI LR_REGNO))])]
11399 ""
11400 {
11401 #if TARGET_MACHO
11402 if (MACHOPIC_INDIRECT)
11403 operands[0] = machopic_indirect_call_target (operands[0]);
11404 #endif
11405
11406 gcc_assert (MEM_P (operands[0]));
11407
11408 operands[0] = XEXP (operands[0], 0);
11409
11410 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
11411 rs6000_call_aix (NULL_RTX, operands[0], operands[1], operands[2]);
11412 else if (DEFAULT_ABI == ABI_V4)
11413 rs6000_call_sysv (NULL_RTX, operands[0], operands[1], operands[2]);
11414 else if (DEFAULT_ABI == ABI_DARWIN)
11415 rs6000_call_darwin (NULL_RTX, operands[0], operands[1], operands[2]);
11416 else
11417 gcc_unreachable ();
11418
11419 DONE;
11420 })
11421
11422 (define_expand "call_value"
11423 [(parallel [(set (match_operand 0 "")
11424 (call (mem:SI (match_operand 1 "address_operand"))
11425 (match_operand 2 "")))
11426 (use (match_operand 3 ""))
11427 (clobber (reg:SI LR_REGNO))])]
11428 ""
11429 {
11430 #if TARGET_MACHO
11431 if (MACHOPIC_INDIRECT)
11432 operands[1] = machopic_indirect_call_target (operands[1]);
11433 #endif
11434
11435 gcc_assert (MEM_P (operands[1]));
11436
11437 operands[1] = XEXP (operands[1], 0);
11438
11439 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
11440 rs6000_call_aix (operands[0], operands[1], operands[2], operands[3]);
11441 else if (DEFAULT_ABI == ABI_V4)
11442 rs6000_call_sysv (operands[0], operands[1], operands[2], operands[3]);
11443 else if (DEFAULT_ABI == ABI_DARWIN)
11444 rs6000_call_darwin (operands[0], operands[1], operands[2], operands[3]);
11445 else
11446 gcc_unreachable ();
11447
11448 DONE;
11449 })
11450
11451 ;; Call to function in current module. No TOC pointer reload needed.
11452 ;; Operand2 is nonzero if we are using the V.4 calling sequence and
11453 ;; either the function was not prototyped, or it was prototyped as a
11454 ;; variable argument function. It is > 0 if FP registers were passed
11455 ;; and < 0 if they were not.
11456
11457 (define_insn "*call_local<mode>"
11458 [(call (mem:SI (match_operand:P 0 "current_file_function_operand" "s,s"))
11459 (match_operand 1))
11460 (use (match_operand:SI 2 "immediate_operand" "O,n"))
11461 (clobber (reg:P LR_REGNO))]
11462 "(INTVAL (operands[2]) & CALL_LONG) == 0"
11463 {
11464 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
11465 output_asm_insn ("crxor 6,6,6", operands);
11466
11467 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
11468 output_asm_insn ("creqv 6,6,6", operands);
11469
11470 if (rs6000_pcrel_p ())
11471 return "bl %z0@notoc";
11472 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z0@local" : "bl %z0";
11473 }
11474 [(set_attr "type" "branch")
11475 (set_attr "length" "4,8")])
11476
11477 (define_insn "*call_value_local<mode>"
11478 [(set (match_operand 0 "" "")
11479 (call (mem:SI (match_operand:P 1 "current_file_function_operand" "s,s"))
11480 (match_operand 2)))
11481 (use (match_operand:SI 3 "immediate_operand" "O,n"))
11482 (clobber (reg:P LR_REGNO))]
11483 "(INTVAL (operands[3]) & CALL_LONG) == 0"
11484 {
11485 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11486 output_asm_insn ("crxor 6,6,6", operands);
11487
11488 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11489 output_asm_insn ("creqv 6,6,6", operands);
11490
11491 if (rs6000_pcrel_p ())
11492 return "bl %z1@notoc";
11493 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z1@local" : "bl %z1";
11494 }
11495 [(set_attr "type" "branch")
11496 (set_attr "length" "4,8")])
11497
11498
11499 ;; A function pointer under System V is just a normal pointer
11500 ;; operands[0] is the function pointer
11501 ;; operands[1] is the tls call arg
11502 ;; operands[2] is the value FUNCTION_ARG returns for the VOID argument
11503 ;; which indicates how to set cr1
11504
11505 (define_insn "*call_indirect_nonlocal_sysv<mode>"
11506 [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X"))
11507 (match_operand 1))
11508 (use (match_operand:SI 2 "immediate_operand" "n,n,n"))
11509 (clobber (reg:P LR_REGNO))]
11510 "DEFAULT_ABI == ABI_V4
11511 || DEFAULT_ABI == ABI_DARWIN"
11512 {
11513 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
11514 output_asm_insn ("crxor 6,6,6", operands);
11515
11516 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
11517 output_asm_insn ("creqv 6,6,6", operands);
11518
11519 return rs6000_indirect_call_template (operands, 0);
11520 }
11521 [(set_attr "type" "jmpreg")
11522 (set (attr "length")
11523 (cond [(and (and (match_test "!rs6000_speculate_indirect_jumps")
11524 (match_test "which_alternative != 1"))
11525 (match_test "(INTVAL (operands[2]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
11526 (const_string "12")
11527 (ior (and (match_test "!rs6000_speculate_indirect_jumps")
11528 (match_test "which_alternative != 1"))
11529 (match_test "(INTVAL (operands[2]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
11530 (const_string "8")]
11531 (const_string "4")))])
11532
11533 (define_insn "*call_nonlocal_sysv<mode>"
11534 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
11535 (match_operand 1))
11536 (use (match_operand:SI 2 "immediate_operand" "O,n"))
11537 (clobber (reg:P LR_REGNO))]
11538 "(DEFAULT_ABI == ABI_DARWIN
11539 || (DEFAULT_ABI == ABI_V4
11540 && (INTVAL (operands[2]) & CALL_LONG) == 0))"
11541 {
11542 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
11543 output_asm_insn ("crxor 6,6,6", operands);
11544
11545 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
11546 output_asm_insn ("creqv 6,6,6", operands);
11547
11548 return rs6000_call_template (operands, 0);
11549 }
11550 [(set_attr "type" "branch,branch")
11551 (set_attr "length" "4,8")])
11552
11553 (define_insn "*call_nonlocal_sysv_secure<mode>"
11554 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
11555 (match_operand 1))
11556 (use (match_operand:SI 2 "immediate_operand" "O,n"))
11557 (use (match_operand:SI 3 "register_operand" "r,r"))
11558 (clobber (reg:P LR_REGNO))]
11559 "(DEFAULT_ABI == ABI_V4
11560 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0])
11561 && (INTVAL (operands[2]) & CALL_LONG) == 0)"
11562 {
11563 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
11564 output_asm_insn ("crxor 6,6,6", operands);
11565
11566 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
11567 output_asm_insn ("creqv 6,6,6", operands);
11568
11569 return rs6000_call_template (operands, 0);
11570 }
11571 [(set_attr "type" "branch,branch")
11572 (set_attr "length" "4,8")])
11573
11574 (define_insn "*call_value_indirect_nonlocal_sysv<mode>"
11575 [(set (match_operand 0 "" "")
11576 (call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X"))
11577 (match_operand:P 2 "unspec_tls" "")))
11578 (use (match_operand:SI 3 "immediate_operand" "n,n,n"))
11579 (clobber (reg:P LR_REGNO))]
11580 "DEFAULT_ABI == ABI_V4
11581 || DEFAULT_ABI == ABI_DARWIN"
11582 {
11583 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11584 output_asm_insn ("crxor 6,6,6", operands);
11585
11586 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11587 output_asm_insn ("creqv 6,6,6", operands);
11588
11589 return rs6000_indirect_call_template (operands, 1);
11590 }
11591 [(set_attr "type" "jmpreg")
11592 (set (attr "length")
11593 (plus
11594 (if_then_else (match_test "IS_V4_FP_ARGS (operands[3])")
11595 (const_int 4)
11596 (const_int 0))
11597 (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
11598 (match_test "which_alternative != 1"))
11599 (const_int 8)
11600 (const_int 4))))])
11601
11602 (define_insn "*call_value_nonlocal_sysv<mode>"
11603 [(set (match_operand 0 "" "")
11604 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s"))
11605 (match_operand:P 2 "unspec_tls" "")))
11606 (use (match_operand:SI 3 "immediate_operand" "n"))
11607 (clobber (reg:P LR_REGNO))]
11608 "(DEFAULT_ABI == ABI_DARWIN
11609 || (DEFAULT_ABI == ABI_V4
11610 && (INTVAL (operands[3]) & CALL_LONG) == 0))"
11611 {
11612 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11613 output_asm_insn ("crxor 6,6,6", operands);
11614
11615 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11616 output_asm_insn ("creqv 6,6,6", operands);
11617
11618 return rs6000_call_template (operands, 1);
11619 }
11620 [(set_attr "type" "branch")
11621 (set (attr "length")
11622 (if_then_else (match_test "IS_V4_FP_ARGS (operands[3])")
11623 (const_int 8)
11624 (const_int 4)))])
11625
11626 (define_insn "*call_value_nonlocal_sysv_secure<mode>"
11627 [(set (match_operand 0 "" "")
11628 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s"))
11629 (match_operand:P 2 "unspec_tls" "")))
11630 (use (match_operand:SI 3 "immediate_operand" "n"))
11631 (use (match_operand:SI 4 "register_operand" "r"))
11632 (clobber (reg:P LR_REGNO))]
11633 "(DEFAULT_ABI == ABI_V4
11634 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1])
11635 && (INTVAL (operands[3]) & CALL_LONG) == 0)"
11636 {
11637 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11638 output_asm_insn ("crxor 6,6,6", operands);
11639
11640 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11641 output_asm_insn ("creqv 6,6,6", operands);
11642
11643 return rs6000_call_template (operands, 1);
11644 }
11645 [(set_attr "type" "branch")
11646 (set (attr "length")
11647 (if_then_else (match_test "IS_V4_FP_ARGS (operands[3])")
11648 (const_int 8)
11649 (const_int 4)))])
11650
11651 ;; Call to AIX abi function which may be in another module.
11652 ;; Restore the TOC pointer (r2) after the call.
11653
11654 (define_insn "*call_nonlocal_aix<mode>"
11655 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s"))
11656 (match_operand 1))
11657 (use (match_operand:SI 2 "immediate_operand" "n"))
11658 (clobber (reg:P LR_REGNO))]
11659 "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
11660 && (INTVAL (operands[2]) & CALL_LONG) == 0"
11661 {
11662 return rs6000_call_template (operands, 0);
11663 }
11664 [(set_attr "type" "branch")
11665 (set (attr "length")
11666 (if_then_else (match_test "rs6000_pcrel_p ()")
11667 (const_int 4)
11668 (const_int 8)))])
11669
11670 (define_insn "*call_value_nonlocal_aix<mode>"
11671 [(set (match_operand 0 "" "")
11672 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s"))
11673 (match_operand:P 2 "unspec_tls" "")))
11674 (use (match_operand:SI 3 "immediate_operand" "n"))
11675 (clobber (reg:P LR_REGNO))]
11676 "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
11677 && (INTVAL (operands[3]) & CALL_LONG) == 0"
11678 {
11679 return rs6000_call_template (operands, 1);
11680 }
11681 [(set_attr "type" "branch")
11682 (set (attr "length")
11683 (if_then_else (match_test "rs6000_pcrel_p ()")
11684 (const_int 4)
11685 (const_int 8)))])
11686
11687 ;; Call to indirect functions with the AIX abi using a 3 word descriptor.
11688 ;; Operand0 is the addresss of the function to call
11689 ;; Operand3 is the location in the function descriptor to load r2 from
11690 ;; Operand4 is the offset of the stack location holding the current TOC pointer
11691
11692 (define_insn "*call_indirect_aix<mode>"
11693 [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X"))
11694 (match_operand 1))
11695 (use (match_operand:SI 2 "immediate_operand" "n,n,n"))
11696 (use (match_operand:P 3 "memory_operand" "<ptrm>,<ptrm>,<ptrm>"))
11697 (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 4 "const_int_operand" "n,n,n")] UNSPEC_TOCSLOT))
11698 (clobber (reg:P LR_REGNO))]
11699 "DEFAULT_ABI == ABI_AIX"
11700 {
11701 return rs6000_indirect_call_template (operands, 0);
11702 }
11703 [(set_attr "type" "jmpreg")
11704 (set (attr "length")
11705 (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
11706 (match_test "which_alternative != 1"))
11707 (const_string "16")
11708 (const_string "12")))])
11709
11710 (define_insn "*call_value_indirect_aix<mode>"
11711 [(set (match_operand 0 "" "")
11712 (call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X"))
11713 (match_operand:P 2 "unspec_tls" "")))
11714 (use (match_operand:SI 3 "immediate_operand" "n,n,n"))
11715 (use (match_operand:P 4 "memory_operand" "<ptrm>,<ptrm>,<ptrm>"))
11716 (set (reg:P TOC_REGNUM)
11717 (unspec:P [(match_operand:P 5 "const_int_operand" "n,n,n")]
11718 UNSPEC_TOCSLOT))
11719 (clobber (reg:P LR_REGNO))]
11720 "DEFAULT_ABI == ABI_AIX"
11721 {
11722 return rs6000_indirect_call_template (operands, 1);
11723 }
11724 [(set_attr "type" "jmpreg")
11725 (set (attr "length")
11726 (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
11727 (match_test "which_alternative != 1"))
11728 (const_string "16")
11729 (const_string "12")))])
11730
11731 ;; Call to indirect functions with the ELFv2 ABI.
11732 ;; Operand0 is the addresss of the function to call
11733 ;; Operand3 is the offset of the stack location holding the current TOC pointer
11734
11735 (define_insn "*call_indirect_elfv2<mode>"
11736 [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X"))
11737 (match_operand 1))
11738 (use (match_operand:SI 2 "immediate_operand" "n,n,n"))
11739 (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 3 "const_int_operand" "n,n,n")] UNSPEC_TOCSLOT))
11740 (clobber (reg:P LR_REGNO))]
11741 "DEFAULT_ABI == ABI_ELFv2"
11742 {
11743 return rs6000_indirect_call_template (operands, 0);
11744 }
11745 [(set_attr "type" "jmpreg")
11746 (set (attr "length")
11747 (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
11748 (match_test "which_alternative != 1"))
11749 (const_string "12")
11750 (const_string "8")))])
11751
11752 (define_insn "*call_indirect_pcrel<mode>"
11753 [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X"))
11754 (match_operand 1))
11755 (use (match_operand:SI 2 "immediate_operand" "n,n,n"))
11756 (clobber (reg:P LR_REGNO))]
11757 "rs6000_pcrel_p ()"
11758 {
11759 return rs6000_indirect_call_template (operands, 0);
11760 }
11761 [(set_attr "type" "jmpreg")
11762 (set (attr "length")
11763 (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
11764 (match_test "which_alternative != 1"))
11765 (const_string "8")
11766 (const_string "4")))])
11767
11768 (define_insn "*call_value_indirect_elfv2<mode>"
11769 [(set (match_operand 0 "" "")
11770 (call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X"))
11771 (match_operand:P 2 "unspec_tls" "")))
11772 (use (match_operand:SI 3 "immediate_operand" "n,n,n"))
11773 (set (reg:P TOC_REGNUM)
11774 (unspec:P [(match_operand:P 4 "const_int_operand" "n,n,n")]
11775 UNSPEC_TOCSLOT))
11776 (clobber (reg:P LR_REGNO))]
11777 "DEFAULT_ABI == ABI_ELFv2"
11778 {
11779 return rs6000_indirect_call_template (operands, 1);
11780 }
11781 [(set_attr "type" "jmpreg")
11782 (set (attr "length")
11783 (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
11784 (match_test "which_alternative != 1"))
11785 (const_string "12")
11786 (const_string "8")))])
11787
11788 (define_insn "*call_value_indirect_pcrel<mode>"
11789 [(set (match_operand 0 "" "")
11790 (call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X"))
11791 (match_operand:P 2 "unspec_tls" "")))
11792 (use (match_operand:SI 3 "immediate_operand" "n,n,n"))
11793 (clobber (reg:P LR_REGNO))]
11794 "rs6000_pcrel_p ()"
11795 {
11796 return rs6000_indirect_call_template (operands, 1);
11797 }
11798 [(set_attr "type" "jmpreg")
11799 (set (attr "length")
11800 (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
11801 (match_test "which_alternative != 1"))
11802 (const_string "8")
11803 (const_string "4")))])
11804
11805 ;; Call subroutine returning any type.
11806 (define_expand "untyped_call"
11807 [(parallel [(call (match_operand 0 "")
11808 (const_int 0))
11809 (match_operand 1 "")
11810 (match_operand 2 "")])]
11811 ""
11812 {
11813 int i;
11814
11815 emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
11816
11817 for (int i = 0; i < XVECLEN (operands[2], 0); i++)
11818 emit_clobber (SET_SRC (XVECEXP (operands[2], 0, i)));
11819 emit_insn (gen_blockage ());
11820
11821 for (i = 0; i < XVECLEN (operands[2], 0); i++)
11822 {
11823 rtx set = XVECEXP (operands[2], 0, i);
11824 emit_move_insn (SET_DEST (set), SET_SRC (set));
11825 }
11826
11827 /* The optimizer does not know that the call sets the function value
11828 registers we stored in the result block. We avoid problems by
11829 claiming that all hard registers are used and clobbered at this
11830 point. */
11831 emit_insn (gen_blockage ());
11832
11833 DONE;
11834 })
11835
11836 ;; sibling call patterns
11837 (define_expand "sibcall"
11838 [(parallel [(call (mem:SI (match_operand 0 "address_operand"))
11839 (match_operand 1 ""))
11840 (use (match_operand 2 ""))
11841 (simple_return)])]
11842 ""
11843 {
11844 #if TARGET_MACHO
11845 if (MACHOPIC_INDIRECT)
11846 operands[0] = machopic_indirect_call_target (operands[0]);
11847 #endif
11848
11849 gcc_assert (MEM_P (operands[0]));
11850 gcc_assert (CONST_INT_P (operands[1]));
11851
11852 operands[0] = XEXP (operands[0], 0);
11853
11854 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
11855 rs6000_sibcall_aix (NULL_RTX, operands[0], operands[1], operands[2]);
11856 else if (DEFAULT_ABI == ABI_V4)
11857 rs6000_sibcall_sysv (NULL_RTX, operands[0], operands[1], operands[2]);
11858 else if (DEFAULT_ABI == ABI_DARWIN)
11859 rs6000_sibcall_darwin (NULL_RTX, operands[0], operands[1], operands[2]);
11860 else
11861 gcc_unreachable ();
11862
11863 DONE;
11864 })
11865
11866 (define_expand "sibcall_value"
11867 [(parallel [(set (match_operand 0 "register_operand")
11868 (call (mem:SI (match_operand 1 "address_operand"))
11869 (match_operand 2 "")))
11870 (use (match_operand 3 ""))
11871 (simple_return)])]
11872 ""
11873 {
11874 #if TARGET_MACHO
11875 if (MACHOPIC_INDIRECT)
11876 operands[1] = machopic_indirect_call_target (operands[1]);
11877 #endif
11878
11879 gcc_assert (MEM_P (operands[1]));
11880 gcc_assert (CONST_INT_P (operands[2]));
11881
11882 operands[1] = XEXP (operands[1], 0);
11883
11884 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
11885 rs6000_sibcall_aix (operands[0], operands[1], operands[2], operands[3]);
11886 else if (DEFAULT_ABI == ABI_V4)
11887 rs6000_sibcall_sysv (operands[0], operands[1], operands[2], operands[3]);
11888 else if (DEFAULT_ABI == ABI_DARWIN)
11889 rs6000_sibcall_darwin (operands[0], operands[1], operands[2], operands[3]);
11890 else
11891 gcc_unreachable ();
11892
11893 DONE;
11894 })
11895
11896 (define_insn "*sibcall_local<mode>"
11897 [(call (mem:SI (match_operand:P 0 "current_file_function_operand" "s,s"))
11898 (match_operand 1))
11899 (use (match_operand:SI 2 "immediate_operand" "O,n"))
11900 (simple_return)]
11901 "(INTVAL (operands[2]) & CALL_LONG) == 0"
11902 {
11903 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
11904 output_asm_insn ("crxor 6,6,6", operands);
11905
11906 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
11907 output_asm_insn ("creqv 6,6,6", operands);
11908
11909 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z0@local" : "b %z0";
11910 }
11911 [(set_attr "type" "branch")
11912 (set_attr "length" "4,8")])
11913
11914 (define_insn "*sibcall_value_local<mode>"
11915 [(set (match_operand 0 "" "")
11916 (call (mem:SI (match_operand:P 1 "current_file_function_operand" "s,s"))
11917 (match_operand 2)))
11918 (use (match_operand:SI 3 "immediate_operand" "O,n"))
11919 (simple_return)]
11920 "(INTVAL (operands[3]) & CALL_LONG) == 0"
11921 {
11922 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11923 output_asm_insn ("crxor 6,6,6", operands);
11924
11925 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11926 output_asm_insn ("creqv 6,6,6", operands);
11927
11928 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z1@local" : "b %z1";
11929 }
11930 [(set_attr "type" "branch")
11931 (set_attr "length" "4,8")])
11932
11933 (define_insn "*sibcall_indirect_nonlocal_sysv<mode>"
11934 [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X"))
11935 (match_operand 1))
11936 (use (match_operand:SI 2 "immediate_operand" "n,n,n"))
11937 (simple_return)]
11938 "DEFAULT_ABI == ABI_V4
11939 || DEFAULT_ABI == ABI_DARWIN"
11940 {
11941 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
11942 output_asm_insn ("crxor 6,6,6", operands);
11943
11944 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
11945 output_asm_insn ("creqv 6,6,6", operands);
11946
11947 return rs6000_indirect_sibcall_template (operands, 0);
11948 }
11949 [(set_attr "type" "jmpreg")
11950 (set (attr "length")
11951 (cond [(and (and (match_test "!rs6000_speculate_indirect_jumps")
11952 (match_test "which_alternative != 1"))
11953 (match_test "(INTVAL (operands[2]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
11954 (const_string "12")
11955 (ior (and (match_test "!rs6000_speculate_indirect_jumps")
11956 (match_test "which_alternative != 1"))
11957 (match_test "(INTVAL (operands[2]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
11958 (const_string "8")]
11959 (const_string "4")))])
11960
11961 (define_insn "*sibcall_nonlocal_sysv<mode>"
11962 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
11963 (match_operand 1))
11964 (use (match_operand 2 "immediate_operand" "O,n"))
11965 (simple_return)]
11966 "(DEFAULT_ABI == ABI_DARWIN
11967 || DEFAULT_ABI == ABI_V4)
11968 && (INTVAL (operands[2]) & CALL_LONG) == 0"
11969 {
11970 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
11971 output_asm_insn ("crxor 6,6,6", operands);
11972
11973 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
11974 output_asm_insn ("creqv 6,6,6", operands);
11975
11976 return rs6000_sibcall_template (operands, 0);
11977 }
11978 [(set_attr "type" "branch")
11979 (set_attr "length" "4,8")])
11980
11981 (define_insn "*sibcall_value_indirect_nonlocal_sysv<mode>"
11982 [(set (match_operand 0 "" "")
11983 (call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X"))
11984 (match_operand 2)))
11985 (use (match_operand:SI 3 "immediate_operand" "n,n,n"))
11986 (simple_return)]
11987 "DEFAULT_ABI == ABI_V4
11988 || DEFAULT_ABI == ABI_DARWIN"
11989 {
11990 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11991 output_asm_insn ("crxor 6,6,6", operands);
11992
11993 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11994 output_asm_insn ("creqv 6,6,6", operands);
11995
11996 return rs6000_indirect_sibcall_template (operands, 1);
11997 }
11998 [(set_attr "type" "jmpreg")
11999 (set (attr "length")
12000 (cond [(and (and (match_test "!rs6000_speculate_indirect_jumps")
12001 (match_test "which_alternative != 1"))
12002 (match_test "(INTVAL (operands[3]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
12003 (const_string "12")
12004 (ior (and (match_test "!rs6000_speculate_indirect_jumps")
12005 (match_test "which_alternative != 1"))
12006 (match_test "(INTVAL (operands[3]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
12007 (const_string "8")]
12008 (const_string "4")))])
12009
12010 (define_insn "*sibcall_value_nonlocal_sysv<mode>"
12011 [(set (match_operand 0 "" "")
12012 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
12013 (match_operand 2)))
12014 (use (match_operand:SI 3 "immediate_operand" "O,n"))
12015 (simple_return)]
12016 "(DEFAULT_ABI == ABI_DARWIN
12017 || DEFAULT_ABI == ABI_V4)
12018 && (INTVAL (operands[3]) & CALL_LONG) == 0"
12019 {
12020 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
12021 output_asm_insn ("crxor 6,6,6", operands);
12022
12023 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
12024 output_asm_insn ("creqv 6,6,6", operands);
12025
12026 return rs6000_sibcall_template (operands, 1);
12027 }
12028 [(set_attr "type" "branch")
12029 (set_attr "length" "4,8")])
12030
12031 ;; AIX ABI sibling call patterns.
12032
12033 (define_insn "*sibcall_aix<mode>"
12034 [(call (mem:SI (match_operand:P 0 "call_operand" "s,c"))
12035 (match_operand 1))
12036 (simple_return)]
12037 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
12038 {
12039 if (which_alternative == 0)
12040 return rs6000_sibcall_template (operands, 0);
12041 else
12042 return "b%T0";
12043 }
12044 [(set_attr "type" "branch")])
12045
12046 (define_insn "*sibcall_value_aix<mode>"
12047 [(set (match_operand 0 "" "")
12048 (call (mem:SI (match_operand:P 1 "call_operand" "s,c"))
12049 (match_operand 2)))
12050 (simple_return)]
12051 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
12052 {
12053 if (which_alternative == 0)
12054 return rs6000_sibcall_template (operands, 1);
12055 else
12056 return "b%T1";
12057 }
12058 [(set_attr "type" "branch")])
12059
12060 (define_expand "sibcall_epilogue"
12061 [(use (const_int 0))]
12062 ""
12063 {
12064 if (!TARGET_SCHED_PROLOG)
12065 emit_insn (gen_blockage ());
12066 rs6000_emit_epilogue (EPILOGUE_TYPE_SIBCALL);
12067 DONE;
12068 })
12069
12070 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
12071 ;; all of memory. This blocks insns from being moved across this point.
12072
12073 (define_insn "blockage"
12074 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCK)]
12075 ""
12076 ""
12077 [(set_attr "length" "0")])
12078
12079 (define_expand "probe_stack_address"
12080 [(use (match_operand 0 "address_operand"))]
12081 ""
12082 {
12083 operands[0] = gen_rtx_MEM (Pmode, operands[0]);
12084 MEM_VOLATILE_P (operands[0]) = 1;
12085
12086 if (TARGET_64BIT)
12087 emit_insn (gen_probe_stack_di (operands[0]));
12088 else
12089 emit_insn (gen_probe_stack_si (operands[0]));
12090 DONE;
12091 })
12092
12093 (define_insn "probe_stack_<mode>"
12094 [(set (match_operand:P 0 "memory_operand" "=m")
12095 (unspec:P [(const_int 0)] UNSPEC_PROBE_STACK))]
12096 ""
12097 {
12098 operands[1] = gen_rtx_REG (Pmode, 0);
12099 return "st<wd>%U0%X0 %1,%0";
12100 }
12101 [(set_attr "type" "store")
12102 (set (attr "update")
12103 (if_then_else (match_operand 0 "update_address_mem")
12104 (const_string "yes")
12105 (const_string "no")))
12106 (set (attr "indexed")
12107 (if_then_else (match_operand 0 "indexed_address_mem")
12108 (const_string "yes")
12109 (const_string "no")))])
12110
12111 (define_insn "probe_stack_range<P:mode>"
12112 [(set (match_operand:P 0 "register_operand" "=&r")
12113 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
12114 (match_operand:P 2 "register_operand" "r")
12115 (match_operand:P 3 "register_operand" "r")]
12116 UNSPECV_PROBE_STACK_RANGE))]
12117 ""
12118 "* return output_probe_stack_range (operands[0], operands[2], operands[3]);"
12119 [(set_attr "type" "three")])
12120 \f
12121 ;; Compare insns are next. Note that the RS/6000 has two types of compares,
12122 ;; signed & unsigned, and one type of branch.
12123 ;;
12124 ;; Start with the DEFINE_EXPANDs to generate the rtl for compares, scc
12125 ;; insns, and branches.
12126
12127 (define_expand "cbranch<mode>4"
12128 [(use (match_operator 0 "comparison_operator"
12129 [(match_operand:GPR 1 "gpc_reg_operand")
12130 (match_operand:GPR 2 "reg_or_short_operand")]))
12131 (use (match_operand 3))]
12132 ""
12133 {
12134 /* Take care of the possibility that operands[2] might be negative but
12135 this might be a logical operation. That insn doesn't exist. */
12136 if (CONST_INT_P (operands[2])
12137 && INTVAL (operands[2]) < 0)
12138 {
12139 operands[2] = force_reg (<MODE>mode, operands[2]);
12140 operands[0] = gen_rtx_fmt_ee (GET_CODE (operands[0]),
12141 GET_MODE (operands[0]),
12142 operands[1], operands[2]);
12143 }
12144
12145 rs6000_emit_cbranch (<MODE>mode, operands);
12146 DONE;
12147 })
12148
12149 (define_expand "cbranch<mode>4"
12150 [(use (match_operator 0 "comparison_operator"
12151 [(match_operand:FP 1 "gpc_reg_operand")
12152 (match_operand:FP 2 "gpc_reg_operand")]))
12153 (use (match_operand 3))]
12154 ""
12155 {
12156 rs6000_emit_cbranch (<MODE>mode, operands);
12157 DONE;
12158 })
12159
12160 (define_expand "cbranchcc4"
12161 [(set (pc)
12162 (if_then_else (match_operator 0 "branch_comparison_operator"
12163 [(match_operand 1 "cc_reg_operand")
12164 (match_operand 2 "zero_constant")])
12165 (label_ref (match_operand 3))
12166 (pc)))]
12167 ""
12168 "")
12169
12170 (define_expand "cstore<mode>4_signed"
12171 [(use (match_operator 1 "signed_comparison_operator"
12172 [(match_operand:P 2 "gpc_reg_operand")
12173 (match_operand:P 3 "gpc_reg_operand")]))
12174 (clobber (match_operand:P 0 "gpc_reg_operand"))]
12175 ""
12176 {
12177 enum rtx_code cond_code = GET_CODE (operands[1]);
12178
12179 rtx op0 = operands[0];
12180 rtx op1 = operands[2];
12181 rtx op2 = operands[3];
12182
12183 if (cond_code == GE || cond_code == LT)
12184 {
12185 cond_code = swap_condition (cond_code);
12186 std::swap (op1, op2);
12187 }
12188
12189 rtx tmp1 = gen_reg_rtx (<MODE>mode);
12190 rtx tmp2 = gen_reg_rtx (<MODE>mode);
12191 rtx tmp3 = gen_reg_rtx (<MODE>mode);
12192
12193 int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
12194 emit_insn (gen_lshr<mode>3 (tmp1, op1, GEN_INT (sh)));
12195 emit_insn (gen_ashr<mode>3 (tmp2, op2, GEN_INT (sh)));
12196
12197 emit_insn (gen_subf<mode>3_carry (tmp3, op1, op2));
12198
12199 if (cond_code == LE)
12200 emit_insn (gen_add<mode>3_carry_in (op0, tmp1, tmp2));
12201 else
12202 {
12203 rtx tmp4 = gen_reg_rtx (<MODE>mode);
12204 emit_insn (gen_add<mode>3_carry_in (tmp4, tmp1, tmp2));
12205 emit_insn (gen_xor<mode>3 (op0, tmp4, const1_rtx));
12206 }
12207
12208 DONE;
12209 })
12210
12211 (define_expand "cstore<mode>4_unsigned"
12212 [(use (match_operator 1 "unsigned_comparison_operator"
12213 [(match_operand:P 2 "gpc_reg_operand")
12214 (match_operand:P 3 "reg_or_short_operand")]))
12215 (clobber (match_operand:P 0 "gpc_reg_operand"))]
12216 ""
12217 {
12218 enum rtx_code cond_code = GET_CODE (operands[1]);
12219
12220 rtx op0 = operands[0];
12221 rtx op1 = operands[2];
12222 rtx op2 = operands[3];
12223
12224 if (cond_code == GEU || cond_code == LTU)
12225 {
12226 cond_code = swap_condition (cond_code);
12227 std::swap (op1, op2);
12228 }
12229
12230 if (!gpc_reg_operand (op1, <MODE>mode))
12231 op1 = force_reg (<MODE>mode, op1);
12232 if (!reg_or_short_operand (op2, <MODE>mode))
12233 op2 = force_reg (<MODE>mode, op2);
12234
12235 rtx tmp = gen_reg_rtx (<MODE>mode);
12236 rtx tmp2 = gen_reg_rtx (<MODE>mode);
12237
12238 emit_insn (gen_subf<mode>3_carry (tmp, op1, op2));
12239 emit_insn (gen_subf<mode>3_carry_in_xx (tmp2));
12240
12241 if (cond_code == LEU)
12242 emit_insn (gen_add<mode>3 (op0, tmp2, const1_rtx));
12243 else
12244 emit_insn (gen_neg<mode>2 (op0, tmp2));
12245
12246 DONE;
12247 })
12248
12249 (define_expand "cstore_si_as_di"
12250 [(use (match_operator 1 "unsigned_comparison_operator"
12251 [(match_operand:SI 2 "gpc_reg_operand")
12252 (match_operand:SI 3 "reg_or_short_operand")]))
12253 (clobber (match_operand:SI 0 "gpc_reg_operand"))]
12254 ""
12255 {
12256 int uns_flag = unsigned_comparison_operator (operands[1], VOIDmode) ? 1 : 0;
12257 enum rtx_code cond_code = signed_condition (GET_CODE (operands[1]));
12258
12259 operands[2] = force_reg (SImode, operands[2]);
12260 operands[3] = force_reg (SImode, operands[3]);
12261 rtx op1 = gen_reg_rtx (DImode);
12262 rtx op2 = gen_reg_rtx (DImode);
12263 convert_move (op1, operands[2], uns_flag);
12264 convert_move (op2, operands[3], uns_flag);
12265
12266 if (cond_code == GT || cond_code == LE)
12267 {
12268 cond_code = swap_condition (cond_code);
12269 std::swap (op1, op2);
12270 }
12271
12272 rtx tmp = gen_reg_rtx (DImode);
12273 rtx tmp2 = gen_reg_rtx (DImode);
12274 emit_insn (gen_subdi3 (tmp, op1, op2));
12275 emit_insn (gen_lshrdi3 (tmp2, tmp, GEN_INT (63)));
12276
12277 rtx tmp3;
12278 switch (cond_code)
12279 {
12280 default:
12281 gcc_unreachable ();
12282 case LT:
12283 tmp3 = tmp2;
12284 break;
12285 case GE:
12286 tmp3 = gen_reg_rtx (DImode);
12287 emit_insn (gen_xordi3 (tmp3, tmp2, const1_rtx));
12288 break;
12289 }
12290
12291 convert_move (operands[0], tmp3, 1);
12292
12293 DONE;
12294 })
12295
12296 (define_expand "cstore<mode>4_signed_imm"
12297 [(use (match_operator 1 "signed_comparison_operator"
12298 [(match_operand:GPR 2 "gpc_reg_operand")
12299 (match_operand:GPR 3 "immediate_operand")]))
12300 (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
12301 ""
12302 {
12303 bool invert = false;
12304
12305 enum rtx_code cond_code = GET_CODE (operands[1]);
12306
12307 rtx op0 = operands[0];
12308 rtx op1 = operands[2];
12309 HOST_WIDE_INT val = INTVAL (operands[3]);
12310
12311 if (cond_code == GE || cond_code == GT)
12312 {
12313 cond_code = reverse_condition (cond_code);
12314 invert = true;
12315 }
12316
12317 if (cond_code == LE)
12318 val++;
12319
12320 rtx tmp = gen_reg_rtx (<MODE>mode);
12321 emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
12322 rtx x = gen_reg_rtx (<MODE>mode);
12323 if (val < 0)
12324 emit_insn (gen_and<mode>3 (x, op1, tmp));
12325 else
12326 emit_insn (gen_ior<mode>3 (x, op1, tmp));
12327
12328 if (invert)
12329 {
12330 rtx tmp = gen_reg_rtx (<MODE>mode);
12331 emit_insn (gen_one_cmpl<mode>2 (tmp, x));
12332 x = tmp;
12333 }
12334
12335 int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
12336 emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
12337
12338 DONE;
12339 })
12340
12341 (define_expand "cstore<mode>4_unsigned_imm"
12342 [(use (match_operator 1 "unsigned_comparison_operator"
12343 [(match_operand:GPR 2 "gpc_reg_operand")
12344 (match_operand:GPR 3 "immediate_operand")]))
12345 (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
12346 ""
12347 {
12348 bool invert = false;
12349
12350 enum rtx_code cond_code = GET_CODE (operands[1]);
12351
12352 rtx op0 = operands[0];
12353 rtx op1 = operands[2];
12354 HOST_WIDE_INT val = INTVAL (operands[3]);
12355
12356 if (cond_code == GEU || cond_code == GTU)
12357 {
12358 cond_code = reverse_condition (cond_code);
12359 invert = true;
12360 }
12361
12362 if (cond_code == LEU)
12363 val++;
12364
12365 rtx tmp = gen_reg_rtx (<MODE>mode);
12366 rtx tmp2 = gen_reg_rtx (<MODE>mode);
12367 emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
12368 emit_insn (gen_one_cmpl<mode>2 (tmp2, op1));
12369 rtx x = gen_reg_rtx (<MODE>mode);
12370 if (val < 0)
12371 emit_insn (gen_ior<mode>3 (x, tmp, tmp2));
12372 else
12373 emit_insn (gen_and<mode>3 (x, tmp, tmp2));
12374
12375 if (invert)
12376 {
12377 rtx tmp = gen_reg_rtx (<MODE>mode);
12378 emit_insn (gen_one_cmpl<mode>2 (tmp, x));
12379 x = tmp;
12380 }
12381
12382 int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
12383 emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
12384
12385 DONE;
12386 })
12387
12388 (define_expand "cstore<mode>4"
12389 [(use (match_operator 1 "comparison_operator"
12390 [(match_operand:GPR 2 "gpc_reg_operand")
12391 (match_operand:GPR 3 "reg_or_short_operand")]))
12392 (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
12393 ""
12394 {
12395 /* Everything is best done with setbc[r] if available. */
12396 if (TARGET_POWER10 && TARGET_ISEL)
12397 {
12398 rs6000_emit_int_cmove (operands[0], operands[1], const1_rtx, const0_rtx);
12399 DONE;
12400 }
12401
12402 /* Expanding EQ and NE directly to some machine instructions does not help
12403 but does hurt combine. So don't. */
12404 if (GET_CODE (operands[1]) == EQ)
12405 emit_insn (gen_eq<mode>3 (operands[0], operands[2], operands[3]));
12406 else if (<MODE>mode == Pmode
12407 && GET_CODE (operands[1]) == NE)
12408 emit_insn (gen_ne<mode>3 (operands[0], operands[2], operands[3]));
12409 else if (GET_CODE (operands[1]) == NE)
12410 {
12411 rtx tmp = gen_reg_rtx (<MODE>mode);
12412 emit_insn (gen_eq<mode>3 (tmp, operands[2], operands[3]));
12413 emit_insn (gen_xor<mode>3 (operands[0], tmp, const1_rtx));
12414 }
12415
12416 /* If ISEL is fast, expand to it. */
12417 else if (TARGET_ISEL)
12418 rs6000_emit_int_cmove (operands[0], operands[1], const1_rtx, const0_rtx);
12419
12420 /* Expanding the unsigned comparisons helps a lot: all the neg_ltu
12421 etc. combinations magically work out just right. */
12422 else if (<MODE>mode == Pmode
12423 && unsigned_comparison_operator (operands[1], VOIDmode))
12424 emit_insn (gen_cstore<mode>4_unsigned (operands[0], operands[1],
12425 operands[2], operands[3]));
12426
12427 /* For comparisons smaller than Pmode we can cheaply do things in Pmode. */
12428 else if (<MODE>mode == SImode && Pmode == DImode)
12429 emit_insn (gen_cstore_si_as_di (operands[0], operands[1],
12430 operands[2], operands[3]));
12431
12432 /* For signed comparisons against a constant, we can do some simple
12433 bit-twiddling. */
12434 else if (signed_comparison_operator (operands[1], VOIDmode)
12435 && CONST_INT_P (operands[3]))
12436 emit_insn (gen_cstore<mode>4_signed_imm (operands[0], operands[1],
12437 operands[2], operands[3]));
12438
12439 /* And similarly for unsigned comparisons. */
12440 else if (unsigned_comparison_operator (operands[1], VOIDmode)
12441 && CONST_INT_P (operands[3]))
12442 emit_insn (gen_cstore<mode>4_unsigned_imm (operands[0], operands[1],
12443 operands[2], operands[3]));
12444
12445 /* We also do not want to use mfcr for signed comparisons. */
12446 else if (<MODE>mode == Pmode
12447 && signed_comparison_operator (operands[1], VOIDmode))
12448 emit_insn (gen_cstore<mode>4_signed (operands[0], operands[1],
12449 operands[2], operands[3]));
12450
12451 /* Everything else, use the mfcr brute force. */
12452 else
12453 rs6000_emit_sCOND (<MODE>mode, operands);
12454
12455 DONE;
12456 })
12457
12458 (define_expand "cstore<mode>4"
12459 [(use (match_operator 1 "comparison_operator"
12460 [(match_operand:FP 2 "gpc_reg_operand")
12461 (match_operand:FP 3 "gpc_reg_operand")]))
12462 (clobber (match_operand:SI 0 "gpc_reg_operand"))]
12463 ""
12464 {
12465 rs6000_emit_sCOND (<MODE>mode, operands);
12466 DONE;
12467 })
12468
12469
12470 (define_expand "stack_protect_set"
12471 [(match_operand 0 "memory_operand")
12472 (match_operand 1 "memory_operand")]
12473 ""
12474 {
12475 if (rs6000_stack_protector_guard == SSP_TLS)
12476 {
12477 rtx reg = gen_rtx_REG (Pmode, rs6000_stack_protector_guard_reg);
12478 rtx offset = GEN_INT (rs6000_stack_protector_guard_offset);
12479 rtx addr = gen_rtx_PLUS (Pmode, reg, offset);
12480 operands[1] = gen_rtx_MEM (Pmode, addr);
12481 }
12482
12483 if (TARGET_64BIT)
12484 emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
12485 else
12486 emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
12487
12488 DONE;
12489 })
12490
12491 ;; We can't use the prefixed attribute here because there are two memory
12492 ;; instructions. We can't split the insn due to the fact that this operation
12493 ;; needs to be done in one piece.
12494 (define_insn "stack_protect_set<mode>"
12495 [(set (match_operand:P 0 "memory_operand" "=YZ")
12496 (unspec:P [(match_operand:P 1 "memory_operand" "YZ")] UNSPEC_SP_SET))
12497 (set (match_scratch:P 2 "=&r") (const_int 0))]
12498 ""
12499 {
12500 if (prefixed_memory (operands[1], <MODE>mode))
12501 /* Prefixed load only supports D-form but no update and X-form. */
12502 output_asm_insn ("p<ptrload> %2,%1", operands);
12503 else
12504 output_asm_insn ("<ptrload>%U1%X1 %2,%1", operands);
12505
12506 if (prefixed_memory (operands[0], <MODE>mode))
12507 /* Prefixed store only supports D-form but no update and X-form. */
12508 output_asm_insn ("pst<wd> %2,%0", operands);
12509 else
12510 output_asm_insn ("st<wd>%U0%X0 %2,%0", operands);
12511
12512 return "li %2,0";
12513 }
12514 [(set_attr "type" "three")
12515
12516 ;; Back to back prefixed memory instructions take 20 bytes (8 bytes for each
12517 ;; prefixed instruction + 4 bytes for the possible NOP). Add in 4 bytes for
12518 ;; the LI 0 at the end.
12519 (set_attr "prefixed" "no")
12520 (set_attr "num_insns" "3")
12521 (set (attr "length")
12522 (cond [(and (match_operand 0 "prefixed_memory")
12523 (match_operand 1 "prefixed_memory"))
12524 (const_int 24)
12525
12526 (ior (match_operand 0 "prefixed_memory")
12527 (match_operand 1 "prefixed_memory"))
12528 (const_int 20)]
12529
12530 (const_int 12)))])
12531
12532 (define_expand "stack_protect_test"
12533 [(match_operand 0 "memory_operand")
12534 (match_operand 1 "memory_operand")
12535 (match_operand 2 "")]
12536 ""
12537 {
12538 rtx guard = operands[1];
12539
12540 if (rs6000_stack_protector_guard == SSP_TLS)
12541 {
12542 rtx reg = gen_rtx_REG (Pmode, rs6000_stack_protector_guard_reg);
12543 rtx offset = GEN_INT (rs6000_stack_protector_guard_offset);
12544 rtx addr = gen_rtx_PLUS (Pmode, reg, offset);
12545 guard = gen_rtx_MEM (Pmode, addr);
12546 }
12547
12548 operands[1] = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, guard), UNSPEC_SP_TEST);
12549 rtx test = gen_rtx_EQ (VOIDmode, operands[0], operands[1]);
12550 rtx jump = gen_cbranchsi4 (test, operands[0], operands[1], operands[2]);
12551 emit_jump_insn (jump);
12552
12553 DONE;
12554 })
12555
12556 ;; We can't use the prefixed attribute here because there are two memory
12557 ;; instructions. We can't split the insn due to the fact that this operation
12558 ;; needs to be done in one piece.
12559 (define_insn "stack_protect_test<mode>"
12560 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
12561 (unspec:CCEQ [(match_operand:P 1 "memory_operand" "YZ,YZ")
12562 (match_operand:P 2 "memory_operand" "YZ,YZ")]
12563 UNSPEC_SP_TEST))
12564 (set (match_scratch:P 4 "=r,r") (const_int 0))
12565 (clobber (match_scratch:P 3 "=&r,&r"))]
12566 ""
12567 {
12568 if (prefixed_memory (operands[1], <MODE>mode))
12569 /* Prefixed load only supports D-form but no update and X-form. */
12570 output_asm_insn ("p<ptrload> %3,%1", operands);
12571 else
12572 output_asm_insn ("<ptrload>%U1%X1 %3,%1", operands);
12573
12574 if (prefixed_memory (operands[2], <MODE>mode))
12575 output_asm_insn ("p<ptrload> %4,%2", operands);
12576 else
12577 output_asm_insn ("<ptrload>%U2%X2 %4,%2", operands);
12578
12579 if (which_alternative == 0)
12580 output_asm_insn ("xor. %3,%3,%4", operands);
12581 else
12582 output_asm_insn ("cmpl<wd> %0,%3,%4\;li %3,0", operands);
12583
12584 return "li %4,0";
12585 }
12586 ;; Back to back prefixed memory instructions take 20 bytes (8 bytes for each
12587 ;; prefixed instruction + 4 bytes for the possible NOP). Add in either 4 or
12588 ;; 8 bytes to do the test.
12589 [(set_attr "prefixed" "no")
12590 (set_attr "num_insns" "4,5")
12591 (set (attr "length")
12592 (cond [(and (match_operand 1 "prefixed_memory")
12593 (match_operand 2 "prefixed_memory"))
12594 (if_then_else (eq_attr "alternative" "0")
12595 (const_int 28)
12596 (const_int 32))
12597
12598 (ior (match_operand 1 "prefixed_memory")
12599 (match_operand 2 "prefixed_memory"))
12600 (if_then_else (eq_attr "alternative" "0")
12601 (const_int 20)
12602 (const_int 24))]
12603
12604 (if_then_else (eq_attr "alternative" "0")
12605 (const_int 16)
12606 (const_int 20))))])
12607
12608 \f
12609 ;; Here are the actual compare insns.
12610 (define_insn "*cmp<mode>_signed"
12611 [(set (match_operand:CC 0 "cc_reg_operand" "=y")
12612 (compare:CC (match_operand:GPR 1 "gpc_reg_operand" "r")
12613 (match_operand:GPR 2 "reg_or_short_operand" "rI")))]
12614 ""
12615 "cmp<wd>%I2 %0,%1,%2"
12616 [(set_attr "type" "cmp")])
12617
12618 (define_insn "*cmp<mode>_unsigned"
12619 [(set (match_operand:CCUNS 0 "cc_reg_operand" "=y")
12620 (compare:CCUNS (match_operand:GPR 1 "gpc_reg_operand" "r")
12621 (match_operand:GPR 2 "reg_or_u_short_operand" "rK")))]
12622 ""
12623 "cmpl<wd>%I2 %0,%1,%2"
12624 [(set_attr "type" "cmp")])
12625
12626 ;; If we are comparing a register for equality with a large constant,
12627 ;; we can do this with an XOR followed by a compare. But this is profitable
12628 ;; only if the large constant is only used for the comparison (and in this
12629 ;; case we already have a register to reuse as scratch).
12630 ;;
12631 ;; For 64-bit registers, we could only do so if the constant's bit 15 is clear:
12632 ;; otherwise we'd need to XOR with FFFFFFFF????0000 which is not available.
12633
12634 (define_peephole2
12635 [(set (match_operand:SI 0 "register_operand")
12636 (match_operand:SI 1 "logical_const_operand"))
12637 (set (match_dup 0) (match_operator:SI 3 "boolean_or_operator"
12638 [(match_dup 0)
12639 (match_operand:SI 2 "logical_const_operand")]))
12640 (set (match_operand:CC 4 "cc_reg_operand")
12641 (compare:CC (match_operand:SI 5 "gpc_reg_operand")
12642 (match_dup 0)))
12643 (set (pc)
12644 (if_then_else (match_operator 6 "equality_operator"
12645 [(match_dup 4) (const_int 0)])
12646 (match_operand 7 "")
12647 (match_operand 8 "")))]
12648 "peep2_reg_dead_p (3, operands[0])
12649 && peep2_reg_dead_p (4, operands[4])
12650 && REGNO (operands[0]) != REGNO (operands[5])"
12651 [(set (match_dup 0) (xor:SI (match_dup 5) (match_dup 9)))
12652 (set (match_dup 4) (compare:CC (match_dup 0) (match_dup 10)))
12653 (set (pc) (if_then_else (match_dup 6) (match_dup 7) (match_dup 8)))]
12654
12655 {
12656 /* Get the constant we are comparing against, and see what it looks like
12657 when sign-extended from 16 to 32 bits. Then see what constant we could
12658 XOR with SEXTC to get the sign-extended value. */
12659 rtx cnst = simplify_const_binary_operation (GET_CODE (operands[3]),
12660 SImode,
12661 operands[1], operands[2]);
12662 HOST_WIDE_INT c = INTVAL (cnst);
12663 HOST_WIDE_INT sextc = sext_hwi (c, 16);
12664 HOST_WIDE_INT xorv = c ^ sextc;
12665
12666 operands[9] = GEN_INT (xorv);
12667 operands[10] = GEN_INT (sextc);
12668 })
12669
12670 ;; Only need to compare second words if first words equal
12671 (define_insn "*cmp<mode>_internal1"
12672 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
12673 (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
12674 (match_operand:IBM128 2 "gpc_reg_operand" "d")))]
12675 "!TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode)
12676 && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
12677 "fcmpu %0,%1,%2\;bne %0,$+8\;fcmpu %0,%L1,%L2"
12678 [(set_attr "type" "fpcompare")
12679 (set_attr "length" "12")])
12680
12681 (define_insn_and_split "*cmp<IBM128:mode>_internal2"
12682 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
12683 (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
12684 (match_operand:IBM128 2 "gpc_reg_operand" "d")))
12685 (clobber (match_scratch:DF 3 "=d"))
12686 (clobber (match_scratch:DF 4 "=d"))
12687 (clobber (match_scratch:DF 5 "=d"))
12688 (clobber (match_scratch:DF 6 "=d"))
12689 (clobber (match_scratch:DF 7 "=d"))
12690 (clobber (match_scratch:DF 8 "=d"))
12691 (clobber (match_scratch:DF 9 "=d"))
12692 (clobber (match_scratch:DF 10 "=d"))
12693 (clobber (match_scratch:GPR 11 "=b"))]
12694 "TARGET_XL_COMPAT && FLOAT128_IBM_P (<IBM128:MODE>mode)
12695 && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
12696 "#"
12697 "&& reload_completed"
12698 [(set (match_dup 3) (match_dup 14))
12699 (set (match_dup 4) (match_dup 15))
12700 (set (match_dup 9) (abs:DF (match_dup 5)))
12701 (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 3)))
12702 (set (pc) (if_then_else (ne (match_dup 0) (const_int 0))
12703 (label_ref (match_dup 12))
12704 (pc)))
12705 (set (match_dup 0) (compare:CCFP (match_dup 5) (match_dup 7)))
12706 (set (pc) (label_ref (match_dup 13)))
12707 (match_dup 12)
12708 (set (match_dup 10) (minus:DF (match_dup 5) (match_dup 7)))
12709 (set (match_dup 9) (minus:DF (match_dup 6) (match_dup 8)))
12710 (set (match_dup 9) (plus:DF (match_dup 10) (match_dup 9)))
12711 (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 4)))
12712 (match_dup 13)]
12713 {
12714 REAL_VALUE_TYPE rv;
12715 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
12716 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
12717
12718 operands[5] = simplify_gen_subreg (DFmode, operands[1],
12719 <IBM128:MODE>mode, hi_word);
12720 operands[6] = simplify_gen_subreg (DFmode, operands[1],
12721 <IBM128:MODE>mode, lo_word);
12722 operands[7] = simplify_gen_subreg (DFmode, operands[2],
12723 <IBM128:MODE>mode, hi_word);
12724 operands[8] = simplify_gen_subreg (DFmode, operands[2],
12725 <IBM128:MODE>mode, lo_word);
12726 operands[12] = gen_label_rtx ();
12727 operands[13] = gen_label_rtx ();
12728 real_inf (&rv);
12729 operands[14] = force_const_mem (DFmode,
12730 const_double_from_real_value (rv, DFmode));
12731 operands[15] = force_const_mem (DFmode,
12732 const_double_from_real_value (dconst0,
12733 DFmode));
12734 if (TARGET_TOC)
12735 {
12736 rtx tocref;
12737 tocref = create_TOC_reference (XEXP (operands[14], 0), operands[11]);
12738 operands[14] = gen_const_mem (DFmode, tocref);
12739 tocref = create_TOC_reference (XEXP (operands[15], 0), operands[11]);
12740 operands[15] = gen_const_mem (DFmode, tocref);
12741 set_mem_alias_set (operands[14], get_TOC_alias_set ());
12742 set_mem_alias_set (operands[15], get_TOC_alias_set ());
12743 }
12744 })
12745 \f
12746 ;; Now we have the scc insns. We can do some combinations because of the
12747 ;; way the machine works.
12748 ;;
12749 ;; Note that this is probably faster if we can put an insn between the
12750 ;; mfcr and rlinm, but this is tricky. Let's leave it for now. In most
12751 ;; cases the insns below which don't use an intermediate CR field will
12752 ;; be used instead.
12753 (define_insn "set<mode>_cc"
12754 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
12755 (match_operator:GPR 1 "scc_comparison_operator"
12756 [(match_operand 2 "cc_reg_operand" "y")
12757 (const_int 0)]))]
12758 ""
12759 "mfcr %0%Q2\;rlwinm %0,%0,%J1,1"
12760 [(set (attr "type")
12761 (cond [(match_test "TARGET_MFCRF")
12762 (const_string "mfcrf")
12763 ]
12764 (const_string "mfcr")))
12765 (set_attr "length" "8")])
12766
12767
12768 (define_code_iterator cmp [eq ne lt ltu gt gtu le leu ge geu])
12769 (define_code_attr UNS [(eq "CC")
12770 (ne "CC")
12771 (lt "CC") (ltu "CCUNS")
12772 (gt "CC") (gtu "CCUNS")
12773 (le "CC") (leu "CCUNS")
12774 (ge "CC") (geu "CCUNS")])
12775 (define_code_attr UNSu_ [(eq "")
12776 (ne "")
12777 (lt "") (ltu "u_")
12778 (gt "") (gtu "u_")
12779 (le "") (leu "u_")
12780 (ge "") (geu "u_")])
12781 (define_code_attr UNSIK [(eq "I")
12782 (ne "I")
12783 (lt "I") (ltu "K")
12784 (gt "I") (gtu "K")
12785 (le "I") (leu "K")
12786 (ge "I") (geu "K")])
12787
12788 (define_insn_and_split "<code><GPR:mode><GPR2:mode>2_isel"
12789 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
12790 (cmp:GPR (match_operand:GPR2 1 "gpc_reg_operand" "r")
12791 (match_operand:GPR2 2 "reg_or_<cmp:UNSu_>short_operand" "r<cmp:UNSIK>")))
12792 (clobber (match_scratch:GPR 3 "=r"))
12793 (clobber (match_scratch:GPR 4 "=r"))
12794 (clobber (match_scratch:<UNS> 5 "=y"))]
12795 "!TARGET_POWER10 && TARGET_ISEL
12796 && !(<CODE> == EQ && operands[2] == const0_rtx)
12797 && !(<CODE> == NE && operands[2] == const0_rtx
12798 && <GPR:MODE>mode == Pmode && <GPR2:MODE>mode == Pmode)"
12799 "#"
12800 "&& 1"
12801 [(pc)]
12802 {
12803 rtx_code code = <CODE>;
12804 if (CONST_INT_P (operands[2]) && code != EQ && code != NE)
12805 {
12806 HOST_WIDE_INT val = INTVAL (operands[2]);
12807 if (code == LT && val != -0x8000)
12808 {
12809 code = LE;
12810 val--;
12811 }
12812 if (code == GT && val != 0x7fff)
12813 {
12814 code = GE;
12815 val++;
12816 }
12817 if (code == LTU && val != 0)
12818 {
12819 code = LEU;
12820 val--;
12821 }
12822 if (code == GTU && val != 0xffff)
12823 {
12824 code = GEU;
12825 val++;
12826 }
12827 operands[2] = GEN_INT (val);
12828 }
12829
12830 if (code == NE || code == LE || code == GE || code == LEU || code == GEU)
12831 operands[3] = const0_rtx;
12832 else
12833 {
12834 if (GET_CODE (operands[3]) == SCRATCH)
12835 operands[3] = gen_reg_rtx (<GPR:MODE>mode);
12836 emit_move_insn (operands[3], const0_rtx);
12837 }
12838
12839 if (GET_CODE (operands[4]) == SCRATCH)
12840 operands[4] = gen_reg_rtx (<GPR:MODE>mode);
12841 emit_move_insn (operands[4], const1_rtx);
12842
12843 if (GET_CODE (operands[5]) == SCRATCH)
12844 operands[5] = gen_reg_rtx (<UNS>mode);
12845
12846 rtx c1 = gen_rtx_COMPARE (<UNS>mode, operands[1], operands[2]);
12847 emit_insn (gen_rtx_SET (operands[5], c1));
12848
12849 rtx c2 = gen_rtx_fmt_ee (code, <GPR:MODE>mode, operands[5], const0_rtx);
12850 rtx x = gen_rtx_IF_THEN_ELSE (<GPR:MODE>mode, c2, operands[4], operands[3]);
12851 emit_move_insn (operands[0], x);
12852
12853 DONE;
12854 }
12855 [(set (attr "cost")
12856 (if_then_else (match_test "(CONST_INT_P (operands[2]) && <CODE> != EQ)
12857 || <CODE> == NE
12858 || <CODE> == LE || <CODE> == GE
12859 || <CODE> == LEU || <CODE> == GEU")
12860 (const_string "9")
12861 (const_string "10")))])
12862
12863 (define_mode_attr scc_eq_op2 [(SI "rKLI")
12864 (DI "rKJI")])
12865
12866 (define_expand "eq<mode>3"
12867 [(parallel [
12868 (set (match_operand:GPR 0 "gpc_reg_operand" "=r")
12869 (eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
12870 (match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>")))
12871 (clobber (match_scratch:GPR 3 "=r"))
12872 (clobber (match_scratch:GPR 4 "=r"))])]
12873 ""
12874 {
12875 if (TARGET_POWER10)
12876 {
12877 rtx cc = gen_reg_rtx (CCmode);
12878 rtx compare = gen_rtx_COMPARE (CCmode, operands[1], operands[2]);
12879 emit_insn (gen_rtx_SET (cc, compare));
12880 rtx eq = gen_rtx_fmt_ee (EQ, <MODE>mode, cc, const0_rtx);
12881 emit_insn (gen_setbc_cc_<mode> (operands[0], eq, cc));
12882 DONE;
12883 }
12884
12885 if (TARGET_ISEL && operands[2] != const0_rtx)
12886 {
12887 emit_insn (gen_eq<mode><mode>2_isel (operands[0], operands[1],
12888 operands[2]));
12889 DONE;
12890 }
12891 })
12892
12893 (define_insn_and_split "*eq<mode>3"
12894 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
12895 (eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
12896 (match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>")))
12897 (clobber (match_scratch:GPR 3 "=r"))
12898 (clobber (match_scratch:GPR 4 "=r"))]
12899 "!TARGET_POWER10 && !(TARGET_ISEL && operands[2] != const0_rtx)"
12900 "#"
12901 "&& 1"
12902 [(set (match_dup 4)
12903 (clz:GPR (match_dup 3)))
12904 (set (match_dup 0)
12905 (lshiftrt:GPR (match_dup 4)
12906 (match_dup 5)))]
12907 {
12908 operands[3] = rs6000_emit_eqne (<MODE>mode,
12909 operands[1], operands[2], operands[3]);
12910
12911 if (GET_CODE (operands[4]) == SCRATCH)
12912 operands[4] = gen_reg_rtx (<MODE>mode);
12913
12914 operands[5] = GEN_INT (exact_log2 (GET_MODE_BITSIZE (<MODE>mode)));
12915 }
12916 [(set (attr "length")
12917 (if_then_else (match_test "operands[2] == const0_rtx")
12918 (const_string "8")
12919 (const_string "12")))])
12920
12921 (define_expand "ne<mode>3"
12922 [(parallel [
12923 (set (match_operand:GPR 0 "gpc_reg_operand" "=r")
12924 (ne:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
12925 (match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>")))
12926 (clobber (match_scratch:GPR 3 "=r"))
12927 (clobber (match_scratch:GPR 4 "=r"))
12928 (clobber (reg:GPR CA_REGNO))])]
12929 ""
12930 {
12931 if (TARGET_POWER10)
12932 {
12933 rtx cc = gen_reg_rtx (CCmode);
12934 rtx compare = gen_rtx_COMPARE (CCmode, operands[1], operands[2]);
12935 emit_insn (gen_rtx_SET (cc, compare));
12936 rtx ne = gen_rtx_fmt_ee (NE, <MODE>mode, cc, const0_rtx);
12937 emit_insn (gen_setbc_cc_<mode> (operands[0], ne, cc));
12938 DONE;
12939 }
12940
12941 if (<MODE>mode != Pmode)
12942 {
12943 rtx x = gen_reg_rtx (<MODE>mode);
12944 emit_insn (gen_eq<mode>3 (x, operands[1], operands[2]));
12945 emit_insn (gen_xor<mode>3 (operands[0], x, const1_rtx));
12946 DONE;
12947 }
12948
12949 if (TARGET_ISEL && operands[2] != const0_rtx)
12950 {
12951 emit_insn (gen_ne<mode><mode>2_isel (operands[0], operands[1],
12952 operands[2]));
12953 DONE;
12954 }
12955 })
12956
12957 (define_insn_and_split "*ne<mode>3"
12958 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12959 (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12960 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")))
12961 (clobber (match_scratch:P 3 "=r"))
12962 (clobber (match_scratch:P 4 "=r"))
12963 (clobber (reg:P CA_REGNO))]
12964 "!TARGET_POWER10 && !(TARGET_ISEL && operands[2] != const0_rtx)"
12965 "#"
12966 "&& 1"
12967 [(parallel [(set (match_dup 4)
12968 (plus:P (match_dup 3)
12969 (const_int -1)))
12970 (set (reg:P CA_REGNO)
12971 (ne:P (match_dup 3)
12972 (const_int 0)))])
12973 (parallel [(set (match_dup 0)
12974 (plus:P (plus:P (not:P (match_dup 4))
12975 (reg:P CA_REGNO))
12976 (match_dup 3)))
12977 (clobber (reg:P CA_REGNO))])]
12978 {
12979 operands[3] = rs6000_emit_eqne (<MODE>mode,
12980 operands[1], operands[2], operands[3]);
12981
12982 if (GET_CODE (operands[4]) == SCRATCH)
12983 operands[4] = gen_reg_rtx (<MODE>mode);
12984 }
12985 [(set (attr "length")
12986 (if_then_else (match_test "operands[2] == const0_rtx")
12987 (const_string "8")
12988 (const_string "12")))])
12989
12990 (define_insn_and_split "*neg_eq_<mode>"
12991 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12992 (neg:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12993 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12994 (clobber (match_scratch:P 3 "=r"))
12995 (clobber (match_scratch:P 4 "=r"))
12996 (clobber (reg:P CA_REGNO))]
12997 "!TARGET_POWER10"
12998 "#"
12999 "&& 1"
13000 [(parallel [(set (match_dup 4)
13001 (plus:P (match_dup 3)
13002 (const_int -1)))
13003 (set (reg:P CA_REGNO)
13004 (ne:P (match_dup 3)
13005 (const_int 0)))])
13006 (parallel [(set (match_dup 0)
13007 (plus:P (reg:P CA_REGNO)
13008 (const_int -1)))
13009 (clobber (reg:P CA_REGNO))])]
13010 {
13011 operands[3] = rs6000_emit_eqne (<MODE>mode,
13012 operands[1], operands[2], operands[3]);
13013
13014 if (GET_CODE (operands[4]) == SCRATCH)
13015 operands[4] = gen_reg_rtx (<MODE>mode);
13016 }
13017 [(set (attr "length")
13018 (if_then_else (match_test "operands[2] == const0_rtx")
13019 (const_string "8")
13020 (const_string "12")))])
13021
13022 (define_insn_and_split "*neg_ne_<mode>"
13023 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
13024 (neg:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
13025 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
13026 (clobber (match_scratch:P 3 "=r"))
13027 (clobber (match_scratch:P 4 "=r"))
13028 (clobber (reg:P CA_REGNO))]
13029 "!TARGET_POWER10"
13030 "#"
13031 "&& 1"
13032 [(parallel [(set (match_dup 4)
13033 (neg:P (match_dup 3)))
13034 (set (reg:P CA_REGNO)
13035 (eq:P (match_dup 3)
13036 (const_int 0)))])
13037 (parallel [(set (match_dup 0)
13038 (plus:P (reg:P CA_REGNO)
13039 (const_int -1)))
13040 (clobber (reg:P CA_REGNO))])]
13041 {
13042 operands[3] = rs6000_emit_eqne (<MODE>mode,
13043 operands[1], operands[2], operands[3]);
13044
13045 if (GET_CODE (operands[4]) == SCRATCH)
13046 operands[4] = gen_reg_rtx (<MODE>mode);
13047 }
13048 [(set (attr "length")
13049 (if_then_else (match_test "operands[2] == const0_rtx")
13050 (const_string "8")
13051 (const_string "12")))])
13052
13053 (define_insn_and_split "*plus_eq_<mode>"
13054 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
13055 (plus:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
13056 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
13057 (match_operand:P 3 "gpc_reg_operand" "r")))
13058 (clobber (match_scratch:P 4 "=r"))
13059 (clobber (match_scratch:P 5 "=r"))
13060 (clobber (reg:P CA_REGNO))]
13061 ""
13062 "#"
13063 ""
13064 [(parallel [(set (match_dup 5)
13065 (neg:P (match_dup 4)))
13066 (set (reg:P CA_REGNO)
13067 (eq:P (match_dup 4)
13068 (const_int 0)))])
13069 (parallel [(set (match_dup 0)
13070 (plus:P (match_dup 3)
13071 (reg:P CA_REGNO)))
13072 (clobber (reg:P CA_REGNO))])]
13073 {
13074 operands[4] = rs6000_emit_eqne (<MODE>mode,
13075 operands[1], operands[2], operands[4]);
13076
13077 if (GET_CODE (operands[5]) == SCRATCH)
13078 operands[5] = gen_reg_rtx (<MODE>mode);
13079 }
13080 [(set (attr "length")
13081 (if_then_else (match_test "operands[2] == const0_rtx")
13082 (const_string "8")
13083 (const_string "12")))])
13084
13085 (define_insn_and_split "*plus_ne_<mode>"
13086 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
13087 (plus:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
13088 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
13089 (match_operand:P 3 "gpc_reg_operand" "r")))
13090 (clobber (match_scratch:P 4 "=r"))
13091 (clobber (match_scratch:P 5 "=r"))
13092 (clobber (reg:P CA_REGNO))]
13093 ""
13094 "#"
13095 ""
13096 [(parallel [(set (match_dup 5)
13097 (plus:P (match_dup 4)
13098 (const_int -1)))
13099 (set (reg:P CA_REGNO)
13100 (ne:P (match_dup 4)
13101 (const_int 0)))])
13102 (parallel [(set (match_dup 0)
13103 (plus:P (match_dup 3)
13104 (reg:P CA_REGNO)))
13105 (clobber (reg:P CA_REGNO))])]
13106 {
13107 operands[4] = rs6000_emit_eqne (<MODE>mode,
13108 operands[1], operands[2], operands[4]);
13109
13110 if (GET_CODE (operands[5]) == SCRATCH)
13111 operands[5] = gen_reg_rtx (<MODE>mode);
13112 }
13113 [(set (attr "length")
13114 (if_then_else (match_test "operands[2] == const0_rtx")
13115 (const_string "8")
13116 (const_string "12")))])
13117
13118 (define_insn_and_split "*minus_eq_<mode>"
13119 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
13120 (minus:P (match_operand:P 3 "gpc_reg_operand" "r")
13121 (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
13122 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
13123 (clobber (match_scratch:P 4 "=r"))
13124 (clobber (match_scratch:P 5 "=r"))
13125 (clobber (reg:P CA_REGNO))]
13126 ""
13127 "#"
13128 ""
13129 [(parallel [(set (match_dup 5)
13130 (plus:P (match_dup 4)
13131 (const_int -1)))
13132 (set (reg:P CA_REGNO)
13133 (ne:P (match_dup 4)
13134 (const_int 0)))])
13135 (parallel [(set (match_dup 0)
13136 (plus:P (plus:P (match_dup 3)
13137 (reg:P CA_REGNO))
13138 (const_int -1)))
13139 (clobber (reg:P CA_REGNO))])]
13140 {
13141 operands[4] = rs6000_emit_eqne (<MODE>mode,
13142 operands[1], operands[2], operands[4]);
13143
13144 if (GET_CODE (operands[5]) == SCRATCH)
13145 operands[5] = gen_reg_rtx (<MODE>mode);
13146 }
13147 [(set (attr "length")
13148 (if_then_else (match_test "operands[2] == const0_rtx")
13149 (const_string "8")
13150 (const_string "12")))])
13151
13152 (define_insn_and_split "*minus_ne_<mode>"
13153 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
13154 (minus:P (match_operand:P 3 "gpc_reg_operand" "r")
13155 (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
13156 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
13157 (clobber (match_scratch:P 4 "=r"))
13158 (clobber (match_scratch:P 5 "=r"))
13159 (clobber (reg:P CA_REGNO))]
13160 ""
13161 "#"
13162 ""
13163 [(parallel [(set (match_dup 5)
13164 (neg:P (match_dup 4)))
13165 (set (reg:P CA_REGNO)
13166 (eq:P (match_dup 4)
13167 (const_int 0)))])
13168 (parallel [(set (match_dup 0)
13169 (plus:P (plus:P (match_dup 3)
13170 (reg:P CA_REGNO))
13171 (const_int -1)))
13172 (clobber (reg:P CA_REGNO))])]
13173 {
13174 operands[4] = rs6000_emit_eqne (<MODE>mode,
13175 operands[1], operands[2], operands[4]);
13176
13177 if (GET_CODE (operands[5]) == SCRATCH)
13178 operands[5] = gen_reg_rtx (<MODE>mode);
13179 }
13180 [(set (attr "length")
13181 (if_then_else (match_test "operands[2] == const0_rtx")
13182 (const_string "8")
13183 (const_string "12")))])
13184
13185 (define_insn_and_split "*eqsi3_ext<mode>"
13186 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
13187 (eq:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
13188 (match_operand:SI 2 "scc_eq_operand" "rKLI")))
13189 (clobber (match_scratch:SI 3 "=r"))
13190 (clobber (match_scratch:SI 4 "=r"))]
13191 "!TARGET_POWER10"
13192 "#"
13193 "&& 1"
13194 [(set (match_dup 4)
13195 (clz:SI (match_dup 3)))
13196 (set (match_dup 0)
13197 (zero_extend:EXTSI
13198 (lshiftrt:SI (match_dup 4)
13199 (const_int 5))))]
13200 {
13201 operands[3] = rs6000_emit_eqne (SImode,
13202 operands[1], operands[2], operands[3]);
13203
13204 if (GET_CODE (operands[4]) == SCRATCH)
13205 operands[4] = gen_reg_rtx (SImode);
13206 }
13207 [(set (attr "length")
13208 (if_then_else (match_test "operands[2] == const0_rtx")
13209 (const_string "8")
13210 (const_string "12")))])
13211
13212 (define_insn_and_split "*nesi3_ext<mode>"
13213 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
13214 (ne:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
13215 (match_operand:SI 2 "scc_eq_operand" "rKLI")))
13216 (clobber (match_scratch:SI 3 "=r"))
13217 (clobber (match_scratch:SI 4 "=r"))
13218 (clobber (match_scratch:EXTSI 5 "=r"))]
13219 "!TARGET_ISEL"
13220 "#"
13221 "&& 1"
13222 [(set (match_dup 4)
13223 (clz:SI (match_dup 3)))
13224 (set (match_dup 5)
13225 (zero_extend:EXTSI
13226 (lshiftrt:SI (match_dup 4)
13227 (const_int 5))))
13228 (set (match_dup 0)
13229 (xor:EXTSI (match_dup 5)
13230 (const_int 1)))]
13231 {
13232 operands[3] = rs6000_emit_eqne (SImode,
13233 operands[1], operands[2], operands[3]);
13234
13235 if (GET_CODE (operands[4]) == SCRATCH)
13236 operands[4] = gen_reg_rtx (SImode);
13237 if (GET_CODE (operands[5]) == SCRATCH)
13238 operands[5] = gen_reg_rtx (<MODE>mode);
13239 }
13240 [(set (attr "length")
13241 (if_then_else (match_test "operands[2] == const0_rtx")
13242 (const_string "12")
13243 (const_string "16")))])
13244
13245
13246 (define_code_iterator fp_rev [ordered ne unle unge])
13247 (define_code_iterator fp_two [ltgt le ge unlt ungt uneq])
13248
13249 (define_insn_and_split "*<code><mode>_cc"
13250 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
13251 (fp_rev:GPR (match_operand:CCFP 1 "cc_reg_operand" "y")
13252 (const_int 0)))]
13253 "!flag_finite_math_only"
13254 "#"
13255 "&& 1"
13256 [(pc)]
13257 {
13258 rtx_code revcode = reverse_condition_maybe_unordered (<CODE>);
13259 rtx eq = gen_rtx_fmt_ee (revcode, <MODE>mode, operands[1], const0_rtx);
13260 rtx tmp = gen_reg_rtx (<MODE>mode);
13261 emit_move_insn (tmp, eq);
13262 emit_insn (gen_xor<mode>3 (operands[0], tmp, const1_rtx));
13263 DONE;
13264 }
13265 [(set_attr "length" "12")])
13266
13267 (define_insn_and_split "*<code><mode>_cc"
13268 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
13269 (fp_two:GPR (match_operand:CCFP 1 "cc_reg_operand" "y")
13270 (const_int 0)))]
13271 "!flag_finite_math_only"
13272 "#"
13273 "&& 1"
13274 [(pc)]
13275 {
13276 rtx cc = rs6000_emit_fp_cror (<CODE>, <MODE>mode, operands[1]);
13277
13278 emit_move_insn (operands[0], gen_rtx_EQ (<MODE>mode, cc, const0_rtx));
13279 DONE;
13280 }
13281 [(set_attr "length" "12")])
13282 \f
13283 ;; Conditional branches.
13284 ;; These either are a single bc insn, or a bc around a b.
13285
13286 (define_insn "*cbranch"
13287 [(set (pc)
13288 (if_then_else (match_operator 1 "branch_comparison_operator"
13289 [(match_operand 2 "cc_reg_operand" "y")
13290 (const_int 0)])
13291 (label_ref (match_operand 0))
13292 (pc)))]
13293 ""
13294 {
13295 return output_cbranch (operands[1], "%l0", 0, insn);
13296 }
13297 [(set_attr "type" "branch")
13298 (set (attr "length")
13299 (if_then_else (and (ge (minus (match_dup 0) (pc))
13300 (const_int -32768))
13301 (lt (minus (match_dup 0) (pc))
13302 (const_int 32764)))
13303 (const_int 4)
13304 (const_int 8)))])
13305
13306 (define_insn_and_split "*cbranch_2insn"
13307 [(set (pc)
13308 (if_then_else (match_operator 1 "extra_insn_branch_comparison_operator"
13309 [(match_operand 2 "cc_reg_operand" "y")
13310 (const_int 0)])
13311 (label_ref (match_operand 0))
13312 (pc)))]
13313 "!flag_finite_math_only"
13314 "#"
13315 "&& 1"
13316 [(pc)]
13317 {
13318 rtx cc = rs6000_emit_fp_cror (GET_CODE (operands[1]), SImode, operands[2]);
13319
13320 rtx note = find_reg_note (curr_insn, REG_BR_PROB, 0);
13321
13322 rtx loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands[0]);
13323 rtx cond = gen_rtx_EQ (CCEQmode, cc, const0_rtx);
13324 rtx ite = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, loc_ref, pc_rtx);
13325 emit_jump_insn (gen_rtx_SET (pc_rtx, ite));
13326
13327 if (note)
13328 {
13329 profile_probability prob
13330 = profile_probability::from_reg_br_prob_note (XINT (note, 0));
13331
13332 add_reg_br_prob_note (get_last_insn (), prob);
13333 }
13334
13335 DONE;
13336 }
13337 [(set_attr "type" "branch")
13338 (set (attr "length")
13339 (if_then_else (and (ge (minus (match_dup 0) (pc))
13340 (const_int -32764))
13341 (lt (minus (match_dup 0) (pc))
13342 (const_int 32760)))
13343 (const_int 8)
13344 (const_int 16)))])
13345
13346 ;; Conditional return.
13347 (define_insn "*creturn"
13348 [(set (pc)
13349 (if_then_else (match_operator 0 "branch_comparison_operator"
13350 [(match_operand 1 "cc_reg_operand" "y")
13351 (const_int 0)])
13352 (any_return)
13353 (pc)))]
13354 "<return_pred>"
13355 {
13356 return output_cbranch (operands[0], NULL, 0, insn);
13357 }
13358 [(set_attr "type" "jmpreg")])
13359
13360 ;; Logic on condition register values.
13361
13362 ; This pattern matches things like
13363 ; (set (reg:CCEQ 68) (compare:CCEQ (ior:SI (gt:SI (reg:CCFP 68) (const_int 0))
13364 ; (eq:SI (reg:CCFP 68) (const_int 0)))
13365 ; (const_int 1)))
13366 ; which are generated by the branch logic.
13367 ; Prefer destructive operations where BT = BB (for crXX BT,BA,BB)
13368
13369 (define_insn "@cceq_ior_compare_<mode>"
13370 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
13371 (compare:CCEQ (match_operator:GPR 1 "boolean_operator"
13372 [(match_operator:GPR 2
13373 "branch_positive_comparison_operator"
13374 [(match_operand 3
13375 "cc_reg_operand" "y,y")
13376 (const_int 0)])
13377 (match_operator:GPR 4
13378 "branch_positive_comparison_operator"
13379 [(match_operand 5
13380 "cc_reg_operand" "0,y")
13381 (const_int 0)])])
13382 (const_int 1)))]
13383 ""
13384 "cr%q1 %E0,%j2,%j4"
13385 [(set_attr "type" "cr_logical")
13386 (set_attr "cr_logical_3op" "no,yes")])
13387
13388 ; Why is the constant -1 here, but 1 in the previous pattern?
13389 ; Because ~1 has all but the low bit set.
13390 (define_insn "cceq_ior_compare_complement"
13391 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
13392 (compare:CCEQ (match_operator:SI 1 "boolean_operator"
13393 [(not:SI (match_operator:SI 2
13394 "branch_positive_comparison_operator"
13395 [(match_operand 3
13396 "cc_reg_operand" "y,y")
13397 (const_int 0)]))
13398 (match_operator:SI 4
13399 "branch_positive_comparison_operator"
13400 [(match_operand 5
13401 "cc_reg_operand" "0,y")
13402 (const_int 0)])])
13403 (const_int -1)))]
13404 ""
13405 "cr%q1 %E0,%j2,%j4"
13406 [(set_attr "type" "cr_logical")
13407 (set_attr "cr_logical_3op" "no,yes")])
13408
13409 (define_insn "@cceq_rev_compare_<mode>"
13410 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
13411 (compare:CCEQ (match_operator:GPR 1
13412 "branch_positive_comparison_operator"
13413 [(match_operand 2
13414 "cc_reg_operand" "0,y")
13415 (const_int 0)])
13416 (const_int 0)))]
13417 ""
13418 "crnot %E0,%j1"
13419 [(set_attr "type" "cr_logical")
13420 (set_attr "cr_logical_3op" "no,yes")])
13421
13422 ;; If we are comparing the result of two comparisons, this can be done
13423 ;; using creqv or crxor.
13424
13425 (define_insn_and_split ""
13426 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y")
13427 (compare:CCEQ (match_operator 1 "branch_comparison_operator"
13428 [(match_operand 2 "cc_reg_operand" "y")
13429 (const_int 0)])
13430 (match_operator 3 "branch_comparison_operator"
13431 [(match_operand 4 "cc_reg_operand" "y")
13432 (const_int 0)])))]
13433 ""
13434 "#"
13435 ""
13436 [(set (match_dup 0) (compare:CCEQ (xor:SI (match_dup 1) (match_dup 3))
13437 (match_dup 5)))]
13438 {
13439 int positive_1, positive_2;
13440
13441 positive_1 = branch_positive_comparison_operator (operands[1],
13442 GET_MODE (operands[1]));
13443 positive_2 = branch_positive_comparison_operator (operands[3],
13444 GET_MODE (operands[3]));
13445
13446 if (! positive_1)
13447 operands[1] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[2]),
13448 GET_CODE (operands[1])),
13449 SImode,
13450 operands[2], const0_rtx);
13451 else if (GET_MODE (operands[1]) != SImode)
13452 operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), SImode,
13453 operands[2], const0_rtx);
13454
13455 if (! positive_2)
13456 operands[3] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[4]),
13457 GET_CODE (operands[3])),
13458 SImode,
13459 operands[4], const0_rtx);
13460 else if (GET_MODE (operands[3]) != SImode)
13461 operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SImode,
13462 operands[4], const0_rtx);
13463
13464 if (positive_1 == positive_2)
13465 {
13466 operands[1] = gen_rtx_NOT (SImode, operands[1]);
13467 operands[5] = constm1_rtx;
13468 }
13469 else
13470 {
13471 operands[5] = const1_rtx;
13472 }
13473 })
13474
13475 ;; Unconditional branch and return.
13476
13477 (define_insn "jump"
13478 [(set (pc)
13479 (label_ref (match_operand 0)))]
13480 ""
13481 "b %l0"
13482 [(set_attr "type" "branch")])
13483
13484 (define_insn "<return_str>return"
13485 [(any_return)]
13486 "<return_pred>"
13487 "blr"
13488 [(set_attr "type" "jmpreg")])
13489
13490 (define_expand "indirect_jump"
13491 [(set (pc) (match_operand 0 "register_operand"))]
13492 ""
13493 {
13494 if (!rs6000_speculate_indirect_jumps) {
13495 rtx ccreg = gen_reg_rtx (CCmode);
13496 emit_jump_insn (gen_indirect_jump_nospec (Pmode, operands[0], ccreg));
13497 DONE;
13498 }
13499 })
13500
13501 (define_insn "*indirect_jump<mode>"
13502 [(set (pc)
13503 (match_operand:P 0 "register_operand" "c,*l"))]
13504 "rs6000_speculate_indirect_jumps"
13505 "b%T0"
13506 [(set_attr "type" "jmpreg")])
13507
13508 (define_insn "@indirect_jump<mode>_nospec"
13509 [(set (pc) (match_operand:P 0 "register_operand" "c,*l"))
13510 (clobber (match_operand:CC 1 "cc_reg_operand" "=y,y"))]
13511 "!rs6000_speculate_indirect_jumps"
13512 "crset %E1\;beq%T0- %1\;b $"
13513 [(set_attr "type" "jmpreg")
13514 (set_attr "length" "12")])
13515
13516 ;; Table jump for switch statements:
13517 (define_expand "tablejump"
13518 [(use (match_operand 0))
13519 (use (label_ref (match_operand 1)))]
13520 ""
13521 {
13522 if (rs6000_speculate_indirect_jumps)
13523 {
13524 if (rs6000_relative_jumptables)
13525 emit_jump_insn (gen_tablejump_normal (Pmode, operands[0], operands[1]));
13526 else
13527 emit_jump_insn (gen_tablejump_absolute (Pmode, operands[0],
13528 operands[1]));
13529 }
13530 else
13531 {
13532 rtx ccreg = gen_reg_rtx (CCmode);
13533 rtx jump;
13534 if (rs6000_relative_jumptables)
13535 jump = gen_tablejump_nospec (Pmode, operands[0], operands[1], ccreg);
13536 else
13537 jump = gen_tablejump_absolute_nospec (Pmode, operands[0], operands[1],
13538 ccreg);
13539 emit_jump_insn (jump);
13540 }
13541 DONE;
13542 })
13543
13544 (define_expand "@tablejump<mode>_normal"
13545 [(use (match_operand:SI 0))
13546 (use (match_operand:P 1))]
13547 "rs6000_speculate_indirect_jumps && rs6000_relative_jumptables"
13548 {
13549 rtx off = force_reg (SImode, operands[0]);
13550 if (<MODE>mode != SImode)
13551 {
13552 rtx src = gen_rtx_fmt_e (SIGN_EXTEND, Pmode, off);
13553 off = gen_reg_rtx (Pmode);
13554 emit_move_insn (off, src);
13555 }
13556
13557 rtx lab = force_reg (Pmode, gen_rtx_LABEL_REF (Pmode, operands[1]));
13558 rtx addr = gen_reg_rtx (Pmode);
13559
13560 emit_insn (gen_add<mode>3 (addr, off, lab));
13561 emit_jump_insn (gen_tablejump_insn_normal (Pmode, addr, operands[1]));
13562 DONE;
13563 })
13564
13565 (define_expand "@tablejump<mode>_absolute"
13566 [(use (match_operand:P 0))
13567 (use (match_operand:P 1))]
13568 "rs6000_speculate_indirect_jumps && !rs6000_relative_jumptables"
13569 {
13570 rtx addr = gen_reg_rtx (Pmode);
13571 emit_move_insn (addr, operands[0]);
13572
13573 emit_jump_insn (gen_tablejump_insn_normal (Pmode, addr, operands[1]));
13574 DONE;
13575 })
13576
13577 (define_expand "@tablejump<mode>_nospec"
13578 [(use (match_operand:SI 0))
13579 (use (match_operand:P 1))
13580 (use (match_operand:CC 2))]
13581 "!rs6000_speculate_indirect_jumps && rs6000_relative_jumptables"
13582 {
13583 rtx off = force_reg (SImode, operands[0]);
13584 if (<MODE>mode != SImode)
13585 {
13586 rtx src = gen_rtx_fmt_e (SIGN_EXTEND, Pmode, off);
13587 off = gen_reg_rtx (Pmode);
13588 emit_move_insn (off, src);
13589 }
13590
13591 rtx lab = force_reg (Pmode, gen_rtx_LABEL_REF (Pmode, operands[1]));
13592 rtx addr = gen_reg_rtx (Pmode);
13593
13594 emit_insn (gen_add<mode>3 (addr, off, lab));
13595 emit_jump_insn (gen_tablejump_insn_nospec (Pmode, addr, operands[1],
13596 operands[2]));
13597 DONE;
13598 })
13599
13600 (define_expand "@tablejump<mode>_absolute_nospec"
13601 [(use (match_operand:P 0))
13602 (use (match_operand:P 1))
13603 (use (match_operand:CC 2))]
13604 "!rs6000_speculate_indirect_jumps && !rs6000_relative_jumptables"
13605 {
13606 rtx addr = gen_reg_rtx (Pmode);
13607 emit_move_insn (addr, operands[0]);
13608
13609 emit_jump_insn (gen_tablejump_insn_nospec (Pmode, addr, operands[1],
13610 operands[2]));
13611 DONE;
13612 })
13613
13614 (define_insn "@tablejump<mode>_insn_normal"
13615 [(set (pc)
13616 (match_operand:P 0 "register_operand" "c,*l"))
13617 (use (label_ref (match_operand 1)))]
13618 "rs6000_speculate_indirect_jumps"
13619 "b%T0"
13620 [(set_attr "type" "jmpreg")])
13621
13622 (define_insn "@tablejump<mode>_insn_nospec"
13623 [(set (pc)
13624 (match_operand:P 0 "register_operand" "c,*l"))
13625 (use (label_ref (match_operand 1)))
13626 (clobber (match_operand:CC 2 "cc_reg_operand" "=y,y"))]
13627 "!rs6000_speculate_indirect_jumps"
13628 "crset %E2\;beq%T0- %2\;b $"
13629 [(set_attr "type" "jmpreg")
13630 (set_attr "length" "12")])
13631
13632 (define_insn "nop"
13633 [(unspec [(const_int 0)] UNSPEC_NOP)]
13634 ""
13635 "nop")
13636
13637 (define_insn "group_ending_nop"
13638 [(unspec [(const_int 0)] UNSPEC_GRP_END_NOP)]
13639 ""
13640 {
13641 operands[0] = gen_rtx_REG (Pmode,
13642 rs6000_tune == PROCESSOR_POWER6 ? 1 : 2);
13643 return "ori %0,%0,0";
13644 })
13645
13646 (define_insn "speculation_barrier"
13647 [(unspec_volatile:BLK [(const_int 0)] UNSPECV_SPEC_BARRIER)]
13648 ""
13649 {
13650 operands[0] = gen_rtx_REG (Pmode, 31);
13651 return "ori %0,%0,0";
13652 })
13653 \f
13654 ;; Define the subtract-one-and-jump insns, starting with the template
13655 ;; so loop.c knows what to generate.
13656
13657 (define_expand "doloop_end"
13658 [(use (match_operand 0)) ; loop pseudo
13659 (use (match_operand 1))] ; label
13660 ""
13661 {
13662 if (GET_MODE (operands[0]) != Pmode)
13663 FAIL;
13664
13665 emit_jump_insn (gen_ctr (Pmode, operands[0], operands[1]));
13666 DONE;
13667 })
13668
13669 (define_expand "@ctr<mode>"
13670 [(parallel [(set (pc)
13671 (if_then_else (ne (match_operand:P 0 "register_operand")
13672 (const_int 1))
13673 (label_ref (match_operand 1))
13674 (pc)))
13675 (set (match_dup 0)
13676 (plus:P (match_dup 0)
13677 (const_int -1)))
13678 (clobber (match_scratch:CC 2))
13679 (clobber (match_scratch:P 3))])]
13680 ""
13681 "")
13682
13683 ;; We need to be able to do this for any operand, including MEM, or we
13684 ;; will cause reload to blow up since we don't allow output reloads on
13685 ;; JUMP_INSNs.
13686 ;; For the length attribute to be calculated correctly, the
13687 ;; label MUST be operand 0.
13688 ;; rs6000_legitimate_combined_insn prevents combine creating any of
13689 ;; the ctr<mode> insns.
13690
13691 (define_code_attr bd [(eq "bdz") (ne "bdnz")])
13692 (define_code_attr bd_neg [(eq "bdnz") (ne "bdz")])
13693
13694 (define_insn "<bd>_<mode>"
13695 [(set (pc)
13696 (if_then_else (eqne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
13697 (const_int 1))
13698 (label_ref (match_operand 0))
13699 (pc)))
13700 (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wa*c*l")
13701 (plus:P (match_dup 1)
13702 (const_int -1)))
13703 (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
13704 (clobber (match_scratch:P 4 "=X,X,&r,r"))]
13705 ""
13706 {
13707 if (which_alternative != 0)
13708 return "#";
13709 else if (get_attr_length (insn) == 4)
13710 return "<bd> %l0";
13711 else
13712 return "<bd_neg> $+8\;b %l0";
13713 }
13714 [(set_attr "type" "branch")
13715 (set_attr_alternative "length"
13716 [(if_then_else (and (ge (minus (match_dup 0) (pc))
13717 (const_int -32768))
13718 (lt (minus (match_dup 0) (pc))
13719 (const_int 32764)))
13720 (const_int 4)
13721 (const_int 8))
13722 (const_string "16")
13723 (const_string "20")
13724 (const_string "20")])])
13725
13726 ;; Now the splitter if we could not allocate the CTR register
13727 (define_split
13728 [(set (pc)
13729 (if_then_else (match_operator 2 "comparison_operator"
13730 [(match_operand:P 1 "gpc_reg_operand")
13731 (const_int 1)])
13732 (match_operand 5)
13733 (match_operand 6)))
13734 (set (match_operand:P 0 "nonimmediate_operand")
13735 (plus:P (match_dup 1)
13736 (const_int -1)))
13737 (clobber (match_scratch:CC 3))
13738 (clobber (match_scratch:P 4))]
13739 "reload_completed"
13740 [(set (pc)
13741 (if_then_else (match_dup 7)
13742 (match_dup 5)
13743 (match_dup 6)))]
13744 {
13745 operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[2]), VOIDmode, operands[3],
13746 const0_rtx);
13747 emit_insn (gen_rtx_SET (operands[3],
13748 gen_rtx_COMPARE (CCmode, operands[1], const1_rtx)));
13749 if (int_reg_operand (operands[0], <MODE>mode))
13750 emit_insn (gen_add<mode>3 (operands[0], operands[1], constm1_rtx));
13751 else
13752 {
13753 emit_insn (gen_add<mode>3 (operands[4], operands[1], constm1_rtx));
13754 emit_move_insn (operands[0], operands[4]);
13755 }
13756 /* No DONE so branch comes from the pattern. */
13757 })
13758
13759 ;; patterns for bdnzt/bdnzf/bdzt/bdzf
13760 ;; Note that in the case of long branches we have to decompose this into
13761 ;; bdnz+bc. This is because bdnzt has an implied AND between the ctr condition
13762 ;; and the CR bit, which means there is no way to conveniently invert the
13763 ;; comparison as is done with plain bdnz/bdz.
13764
13765 (define_insn "<bd>tf_<mode>"
13766 [(set (pc)
13767 (if_then_else
13768 (and
13769 (eqne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
13770 (const_int 1))
13771 (match_operator 3 "branch_comparison_operator"
13772 [(match_operand 4 "cc_reg_operand" "y,y,y,y")
13773 (const_int 0)]))
13774 (label_ref (match_operand 0))
13775 (pc)))
13776 (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wa*c*l")
13777 (plus:P (match_dup 1)
13778 (const_int -1)))
13779 (clobber (match_scratch:P 5 "=X,X,&r,r"))
13780 (clobber (match_scratch:CC 6 "=X,&y,&y,&y"))
13781 (clobber (match_scratch:CCEQ 7 "=X,&y,&y,&y"))]
13782 ""
13783 {
13784 if (which_alternative != 0)
13785 return "#";
13786 else if (get_attr_length (insn) == 4)
13787 {
13788 if (branch_positive_comparison_operator (operands[3],
13789 GET_MODE (operands[3])))
13790 return "<bd>t %j3,%l0";
13791 else
13792 return "<bd>f %j3,%l0";
13793 }
13794 else
13795 {
13796 static char seq[96];
13797 char *bcs = output_cbranch (operands[3], ".Lshort%=", 1, insn);
13798 sprintf(seq, "<bd_neg> .Lshort%%=\;%s\;b %%l0\;.Lshort%%=:", bcs);
13799 return seq;
13800 }
13801 }
13802 [(set_attr "type" "branch")
13803 (set_attr_alternative "length"
13804 [(if_then_else (and (ge (minus (match_dup 0) (pc))
13805 (const_int -32768))
13806 (lt (minus (match_dup 0) (pc))
13807 (const_int 32764)))
13808 (const_int 4)
13809 (const_int 8))
13810 (const_string "16")
13811 (const_string "20")
13812 (const_string "20")])])
13813
13814 ;; Now the splitter if we could not allocate the CTR register
13815 (define_split
13816 [(set (pc)
13817 (if_then_else
13818 (and
13819 (match_operator 1 "comparison_operator"
13820 [(match_operand:P 0 "gpc_reg_operand")
13821 (const_int 1)])
13822 (match_operator 3 "branch_comparison_operator"
13823 [(match_operand 2 "cc_reg_operand")
13824 (const_int 0)]))
13825 (match_operand 4)
13826 (match_operand 5)))
13827 (set (match_operand:P 6 "nonimmediate_operand")
13828 (plus:P (match_dup 0)
13829 (const_int -1)))
13830 (clobber (match_scratch:P 7))
13831 (clobber (match_scratch:CC 8))
13832 (clobber (match_scratch:CCEQ 9))]
13833 "reload_completed"
13834 [(pc)]
13835 {
13836 rtx ctr = operands[0];
13837 rtx ctrcmp = operands[1];
13838 rtx ccin = operands[2];
13839 rtx cccmp = operands[3];
13840 rtx dst1 = operands[4];
13841 rtx dst2 = operands[5];
13842 rtx ctrout = operands[6];
13843 rtx ctrtmp = operands[7];
13844 enum rtx_code cmpcode = GET_CODE (ctrcmp);
13845 bool ispos = branch_positive_comparison_operator (ctrcmp, GET_MODE (ctrcmp));
13846 if (!ispos)
13847 cmpcode = reverse_condition (cmpcode);
13848 /* Generate crand/crandc here. */
13849 emit_insn (gen_rtx_SET (operands[8],
13850 gen_rtx_COMPARE (CCmode, ctr, const1_rtx)));
13851 rtx ctrcmpcc = gen_rtx_fmt_ee (cmpcode, SImode, operands[8], const0_rtx);
13852
13853 rtx andexpr = gen_rtx_AND (SImode, ctrcmpcc, cccmp);
13854 if (ispos)
13855 emit_insn (gen_cceq_ior_compare (SImode, operands[9], andexpr, ctrcmpcc,
13856 operands[8], cccmp, ccin));
13857 else
13858 emit_insn (gen_cceq_ior_compare_complement (operands[9], andexpr, ctrcmpcc,
13859 operands[8], cccmp, ccin));
13860 if (int_reg_operand (ctrout, <MODE>mode))
13861 emit_insn (gen_add<mode>3 (ctrout, ctr, constm1_rtx));
13862 else
13863 {
13864 emit_insn (gen_add<mode>3 (ctrtmp, ctr, constm1_rtx));
13865 emit_move_insn (ctrout, ctrtmp);
13866 }
13867 rtx cmp = gen_rtx_EQ (CCEQmode, operands[9], const0_rtx);
13868 emit_jump_insn (gen_rtx_SET (pc_rtx,
13869 gen_rtx_IF_THEN_ELSE (VOIDmode, cmp,
13870 dst1, dst2)));
13871 DONE;
13872 })
13873
13874 \f
13875 (define_insn "trap"
13876 [(trap_if (const_int 1) (const_int 0))]
13877 ""
13878 "trap"
13879 [(set_attr "type" "trap")])
13880
13881 (define_expand "ctrap<mode>4"
13882 [(trap_if (match_operator 0 "ordered_comparison_operator"
13883 [(match_operand:GPR 1 "register_operand")
13884 (match_operand:GPR 2 "reg_or_short_operand")])
13885 (match_operand 3 "zero_constant" ""))]
13886 ""
13887 "")
13888
13889 (define_insn ""
13890 [(trap_if (match_operator 0 "ordered_comparison_operator"
13891 [(match_operand:GPR 1 "register_operand" "r")
13892 (match_operand:GPR 2 "reg_or_short_operand" "rI")])
13893 (const_int 0))]
13894 ""
13895 "t<wd>%V0%I2 %1,%2"
13896 [(set_attr "type" "trap")])
13897 \f
13898 ;; Insns related to generating the function prologue and epilogue.
13899
13900 (define_expand "prologue"
13901 [(use (const_int 0))]
13902 ""
13903 {
13904 rs6000_emit_prologue ();
13905 if (!TARGET_SCHED_PROLOG)
13906 emit_insn (gen_blockage ());
13907 DONE;
13908 })
13909
13910 (define_insn "*movesi_from_cr_one"
13911 [(match_parallel 0 "mfcr_operation"
13912 [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
13913 (unspec:SI [(match_operand:CC 2 "cc_reg_operand" "y")
13914 (match_operand 3 "immediate_operand" "n")]
13915 UNSPEC_MOVESI_FROM_CR))])]
13916 "TARGET_MFCRF"
13917 {
13918 int mask = 0;
13919 int i;
13920 for (i = 0; i < XVECLEN (operands[0], 0); i++)
13921 {
13922 mask = INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
13923 operands[4] = GEN_INT (mask);
13924 output_asm_insn ("mfcr %1,%4", operands);
13925 }
13926 return "";
13927 }
13928 [(set_attr "type" "mfcrf")])
13929
13930 ;; Don't include the volatile CRs since their values are not used wrt CR save
13931 ;; in the prologue and doing so prevents shrink-wrapping because we can't move the
13932 ;; prologue past an insn (early exit test) that defines a register used in the
13933 ;; prologue.
13934 (define_insn "prologue_movesi_from_cr"
13935 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
13936 (unspec:SI [(reg:CC CR2_REGNO) (reg:CC CR3_REGNO)
13937 (reg:CC CR4_REGNO)]
13938 UNSPEC_MOVESI_FROM_CR))]
13939 ""
13940 "mfcr %0"
13941 [(set_attr "type" "mfcr")])
13942
13943 (define_insn "*crsave"
13944 [(match_parallel 0 "crsave_operation"
13945 [(set (match_operand:SI 1 "memory_operand" "=m")
13946 (match_operand:SI 2 "gpc_reg_operand" "r"))])]
13947 ""
13948 "stw %2,%1"
13949 [(set_attr "type" "store")])
13950
13951 (define_insn "*stmw"
13952 [(match_parallel 0 "stmw_operation"
13953 [(set (match_operand:SI 1 "memory_operand" "=m")
13954 (match_operand:SI 2 "gpc_reg_operand" "r"))])]
13955 "TARGET_MULTIPLE"
13956 "stmw %2,%1"
13957 [(set_attr "type" "store")
13958 (set_attr "update" "yes")
13959 (set_attr "indexed" "yes")])
13960
13961 ; The following comment applies to:
13962 ; save_gpregs_*
13963 ; save_fpregs_*
13964 ; restore_gpregs*
13965 ; return_and_restore_gpregs*
13966 ; return_and_restore_fpregs*
13967 ; return_and_restore_fpregs_aix*
13968 ;
13969 ; The out-of-line save / restore functions expects one input argument.
13970 ; Since those are not standard call_insn's, we must avoid using
13971 ; MATCH_OPERAND for that argument. That way the register rename
13972 ; optimization will not try to rename this register.
13973 ; Each pattern is repeated for each possible register number used in
13974 ; various ABIs (r11, r1, and for some functions r12)
13975
13976 (define_insn "*save_gpregs_<mode>_r11"
13977 [(match_parallel 0 "any_parallel_operand"
13978 [(clobber (reg:P LR_REGNO))
13979 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13980 (use (reg:P 11))
13981 (set (match_operand:P 2 "memory_operand" "=m")
13982 (match_operand:P 3 "gpc_reg_operand" "r"))])]
13983 ""
13984 "bl %1"
13985 [(set_attr "type" "branch")])
13986
13987 (define_insn "*save_gpregs_<mode>_r12"
13988 [(match_parallel 0 "any_parallel_operand"
13989 [(clobber (reg:P LR_REGNO))
13990 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13991 (use (reg:P 12))
13992 (set (match_operand:P 2 "memory_operand" "=m")
13993 (match_operand:P 3 "gpc_reg_operand" "r"))])]
13994 ""
13995 "bl %1"
13996 [(set_attr "type" "branch")])
13997
13998 (define_insn "*save_gpregs_<mode>_r1"
13999 [(match_parallel 0 "any_parallel_operand"
14000 [(clobber (reg:P LR_REGNO))
14001 (use (match_operand:P 1 "symbol_ref_operand" "s"))
14002 (use (reg:P 1))
14003 (set (match_operand:P 2 "memory_operand" "=m")
14004 (match_operand:P 3 "gpc_reg_operand" "r"))])]
14005 ""
14006 "bl %1"
14007 [(set_attr "type" "branch")])
14008
14009 (define_insn "*save_fpregs_<mode>_r11"
14010 [(match_parallel 0 "any_parallel_operand"
14011 [(clobber (reg:P LR_REGNO))
14012 (use (match_operand:P 1 "symbol_ref_operand" "s"))
14013 (use (reg:P 11))
14014 (set (match_operand:DF 2 "memory_operand" "=m")
14015 (match_operand:DF 3 "gpc_reg_operand" "d"))])]
14016 ""
14017 "bl %1"
14018 [(set_attr "type" "branch")])
14019
14020 (define_insn "*save_fpregs_<mode>_r12"
14021 [(match_parallel 0 "any_parallel_operand"
14022 [(clobber (reg:P LR_REGNO))
14023 (use (match_operand:P 1 "symbol_ref_operand" "s"))
14024 (use (reg:P 12))
14025 (set (match_operand:DF 2 "memory_operand" "=m")
14026 (match_operand:DF 3 "gpc_reg_operand" "d"))])]
14027 ""
14028 "bl %1"
14029 [(set_attr "type" "branch")])
14030
14031 (define_insn "*save_fpregs_<mode>_r1"
14032 [(match_parallel 0 "any_parallel_operand"
14033 [(clobber (reg:P LR_REGNO))
14034 (use (match_operand:P 1 "symbol_ref_operand" "s"))
14035 (use (reg:P 1))
14036 (set (match_operand:DF 2 "memory_operand" "=m")
14037 (match_operand:DF 3 "gpc_reg_operand" "d"))])]
14038 ""
14039 "bl %1"
14040 [(set_attr "type" "branch")])
14041
14042 ; This is to explain that changes to the stack pointer should
14043 ; not be moved over loads from or stores to stack memory.
14044 (define_insn "stack_tie"
14045 [(match_parallel 0 "tie_operand"
14046 [(set (mem:BLK (reg 1)) (const_int 0))])]
14047 ""
14048 ""
14049 [(set_attr "length" "0")])
14050
14051 ; Some 32-bit ABIs do not have a red zone, so the stack deallocation has to
14052 ; stay behind all restores from the stack, it cannot be reordered to before
14053 ; one. See PR77687. This insn is an add or mr, and a memory clobber.
14054 (define_insn "stack_restore_tie"
14055 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
14056 (plus:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
14057 (match_operand:SI 2 "reg_or_cint_operand" "O,rI")))
14058 (set (mem:BLK (scratch)) (const_int 0))]
14059 "TARGET_32BIT"
14060 "@
14061 mr %0,%1
14062 add%I2 %0,%1,%2"
14063 [(set_attr "type" "*,add")])
14064
14065 (define_expand "epilogue"
14066 [(use (const_int 0))]
14067 ""
14068 {
14069 if (!TARGET_SCHED_PROLOG)
14070 emit_insn (gen_blockage ());
14071 rs6000_emit_epilogue (EPILOGUE_TYPE_NORMAL);
14072 DONE;
14073 })
14074
14075 ; On some processors, doing the mtcrf one CC register at a time is
14076 ; faster (like on the 604e). On others, doing them all at once is
14077 ; faster; for instance, on the 601 and 750.
14078
14079 (define_expand "movsi_to_cr_one"
14080 [(set (match_operand:CC 0 "cc_reg_operand")
14081 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand")
14082 (match_dup 2)] UNSPEC_MOVESI_TO_CR))]
14083 ""
14084 "operands[2] = GEN_INT (1 << (7 - (REGNO (operands[0]) - CR0_REGNO)));")
14085
14086 (define_insn "*movsi_to_cr"
14087 [(match_parallel 0 "mtcrf_operation"
14088 [(set (match_operand:CC 1 "cc_reg_operand" "=y")
14089 (unspec:CC [(match_operand:SI 2 "gpc_reg_operand" "r")
14090 (match_operand 3 "immediate_operand" "n")]
14091 UNSPEC_MOVESI_TO_CR))])]
14092 ""
14093 {
14094 int mask = 0;
14095 int i;
14096 for (i = 0; i < XVECLEN (operands[0], 0); i++)
14097 mask |= INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
14098 operands[4] = GEN_INT (mask);
14099 return "mtcrf %4,%2";
14100 }
14101 [(set_attr "type" "mtcr")])
14102
14103 (define_insn "*mtcrfsi"
14104 [(set (match_operand:CC 0 "cc_reg_operand" "=y")
14105 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
14106 (match_operand 2 "immediate_operand" "n")]
14107 UNSPEC_MOVESI_TO_CR))]
14108 "REG_P (operands[0])
14109 && CR_REGNO_P (REGNO (operands[0]))
14110 && CONST_INT_P (operands[2])
14111 && INTVAL (operands[2]) == 1 << (7 - (REGNO (operands[0]) - CR0_REGNO))"
14112 "mtcrf %R0,%1"
14113 [(set_attr "type" "mtcr")])
14114
14115 ; The load-multiple instructions have similar properties.
14116 ; Note that "load_multiple" is a name known to the machine-independent
14117 ; code that actually corresponds to the PowerPC load-string.
14118
14119 (define_insn "*lmw"
14120 [(match_parallel 0 "lmw_operation"
14121 [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
14122 (match_operand:SI 2 "memory_operand" "m"))])]
14123 "TARGET_MULTIPLE"
14124 "lmw %1,%2"
14125 [(set_attr "type" "load")
14126 (set_attr "update" "yes")
14127 (set_attr "indexed" "yes")
14128 (set_attr "cell_micro" "always")])
14129
14130 ; FIXME: "any_parallel_operand" is a bit flexible...
14131
14132 ; The following comment applies to:
14133 ; save_gpregs_*
14134 ; save_fpregs_*
14135 ; restore_gpregs*
14136 ; return_and_restore_gpregs*
14137 ; return_and_restore_fpregs*
14138 ; return_and_restore_fpregs_aix*
14139 ;
14140 ; The out-of-line save / restore functions expects one input argument.
14141 ; Since those are not standard call_insn's, we must avoid using
14142 ; MATCH_OPERAND for that argument. That way the register rename
14143 ; optimization will not try to rename this register.
14144 ; Each pattern is repeated for each possible register number used in
14145 ; various ABIs (r11, r1, and for some functions r12)
14146
14147 (define_insn "*restore_gpregs_<mode>_r11"
14148 [(match_parallel 0 "any_parallel_operand"
14149 [(clobber (reg:P LR_REGNO))
14150 (use (match_operand:P 1 "symbol_ref_operand" "s"))
14151 (use (reg:P 11))
14152 (set (match_operand:P 2 "gpc_reg_operand" "=r")
14153 (match_operand:P 3 "memory_operand" "m"))])]
14154 ""
14155 "bl %1"
14156 [(set_attr "type" "branch")])
14157
14158 (define_insn "*restore_gpregs_<mode>_r12"
14159 [(match_parallel 0 "any_parallel_operand"
14160 [(clobber (reg:P LR_REGNO))
14161 (use (match_operand:P 1 "symbol_ref_operand" "s"))
14162 (use (reg:P 12))
14163 (set (match_operand:P 2 "gpc_reg_operand" "=r")
14164 (match_operand:P 3 "memory_operand" "m"))])]
14165 ""
14166 "bl %1"
14167 [(set_attr "type" "branch")])
14168
14169 (define_insn "*restore_gpregs_<mode>_r1"
14170 [(match_parallel 0 "any_parallel_operand"
14171 [(clobber (reg:P LR_REGNO))
14172 (use (match_operand:P 1 "symbol_ref_operand" "s"))
14173 (use (reg:P 1))
14174 (set (match_operand:P 2 "gpc_reg_operand" "=r")
14175 (match_operand:P 3 "memory_operand" "m"))])]
14176 ""
14177 "bl %1"
14178 [(set_attr "type" "branch")])
14179
14180 (define_insn "*return_and_restore_gpregs_<mode>_r11"
14181 [(match_parallel 0 "any_parallel_operand"
14182 [(return)
14183 (clobber (reg:P LR_REGNO))
14184 (use (match_operand:P 1 "symbol_ref_operand" "s"))
14185 (use (reg:P 11))
14186 (set (match_operand:P 2 "gpc_reg_operand" "=r")
14187 (match_operand:P 3 "memory_operand" "m"))])]
14188 ""
14189 "b %1"
14190 [(set_attr "type" "branch")])
14191
14192 (define_insn "*return_and_restore_gpregs_<mode>_r12"
14193 [(match_parallel 0 "any_parallel_operand"
14194 [(return)
14195 (clobber (reg:P LR_REGNO))
14196 (use (match_operand:P 1 "symbol_ref_operand" "s"))
14197 (use (reg:P 12))
14198 (set (match_operand:P 2 "gpc_reg_operand" "=r")
14199 (match_operand:P 3 "memory_operand" "m"))])]
14200 ""
14201 "b %1"
14202 [(set_attr "type" "branch")])
14203
14204 (define_insn "*return_and_restore_gpregs_<mode>_r1"
14205 [(match_parallel 0 "any_parallel_operand"
14206 [(return)
14207 (clobber (reg:P LR_REGNO))
14208 (use (match_operand:P 1 "symbol_ref_operand" "s"))
14209 (use (reg:P 1))
14210 (set (match_operand:P 2 "gpc_reg_operand" "=r")
14211 (match_operand:P 3 "memory_operand" "m"))])]
14212 ""
14213 "b %1"
14214 [(set_attr "type" "branch")])
14215
14216 (define_insn "*return_and_restore_fpregs_<mode>_r11"
14217 [(match_parallel 0 "any_parallel_operand"
14218 [(return)
14219 (clobber (reg:P LR_REGNO))
14220 (use (match_operand:P 1 "symbol_ref_operand" "s"))
14221 (use (reg:P 11))
14222 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
14223 (match_operand:DF 3 "memory_operand" "m"))])]
14224 ""
14225 "b %1"
14226 [(set_attr "type" "branch")])
14227
14228 (define_insn "*return_and_restore_fpregs_<mode>_r12"
14229 [(match_parallel 0 "any_parallel_operand"
14230 [(return)
14231 (clobber (reg:P LR_REGNO))
14232 (use (match_operand:P 1 "symbol_ref_operand" "s"))
14233 (use (reg:P 12))
14234 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
14235 (match_operand:DF 3 "memory_operand" "m"))])]
14236 ""
14237 "b %1"
14238 [(set_attr "type" "branch")])
14239
14240 (define_insn "*return_and_restore_fpregs_<mode>_r1"
14241 [(match_parallel 0 "any_parallel_operand"
14242 [(return)
14243 (clobber (reg:P LR_REGNO))
14244 (use (match_operand:P 1 "symbol_ref_operand" "s"))
14245 (use (reg:P 1))
14246 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
14247 (match_operand:DF 3 "memory_operand" "m"))])]
14248 ""
14249 "b %1"
14250 [(set_attr "type" "branch")])
14251
14252 (define_insn "*return_and_restore_fpregs_aix_<mode>_r11"
14253 [(match_parallel 0 "any_parallel_operand"
14254 [(return)
14255 (use (match_operand:P 1 "symbol_ref_operand" "s"))
14256 (use (reg:P 11))
14257 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
14258 (match_operand:DF 3 "memory_operand" "m"))])]
14259 ""
14260 "b %1"
14261 [(set_attr "type" "branch")])
14262
14263 (define_insn "*return_and_restore_fpregs_aix_<mode>_r1"
14264 [(match_parallel 0 "any_parallel_operand"
14265 [(return)
14266 (use (match_operand:P 1 "symbol_ref_operand" "s"))
14267 (use (reg:P 1))
14268 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
14269 (match_operand:DF 3 "memory_operand" "m"))])]
14270 ""
14271 "b %1"
14272 [(set_attr "type" "branch")])
14273
14274 ; This is used in compiling the unwind routines.
14275 (define_expand "eh_return"
14276 [(use (match_operand 0 "general_operand"))]
14277 ""
14278 {
14279 emit_insn (gen_eh_set_lr (Pmode, operands[0]));
14280 DONE;
14281 })
14282
14283 ; We can't expand this before we know where the link register is stored.
14284 (define_insn_and_split "@eh_set_lr_<mode>"
14285 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")] UNSPECV_EH_RR)
14286 (clobber (match_scratch:P 1 "=&b"))]
14287 ""
14288 "#"
14289 "reload_completed"
14290 [(const_int 0)]
14291 {
14292 rs6000_emit_eh_reg_restore (operands[0], operands[1]);
14293 DONE;
14294 })
14295
14296 (define_insn "prefetch"
14297 [(prefetch (match_operand 0 "indexed_or_indirect_address" "a")
14298 (match_operand:SI 1 "const_int_operand" "n")
14299 (match_operand:SI 2 "const_int_operand" "n"))]
14300 ""
14301 {
14302
14303
14304 /* dcbtstt, dcbtt and TH=0b10000 support starts with ISA 2.06 (Power7).
14305 AIX does not support the dcbtstt and dcbtt extended mnemonics.
14306 The AIX assembler does not support the three operand form of dcbt
14307 and dcbtst on Power 7 (-mpwr7). */
14308 int inst_select = INTVAL (operands[2]) || !TARGET_DIRECT_MOVE;
14309
14310 if (REG_P (operands[0]))
14311 {
14312 if (INTVAL (operands[1]) == 0)
14313 return inst_select ? "dcbt 0,%0" : "dcbt 0,%0,16";
14314 else
14315 return inst_select ? "dcbtst 0,%0" : "dcbtst 0,%0,16";
14316 }
14317 else
14318 {
14319 if (INTVAL (operands[1]) == 0)
14320 return inst_select ? "dcbt %a0" : "dcbt %a0,16";
14321 else
14322 return inst_select ? "dcbtst %a0" : "dcbtst %a0,16";
14323 }
14324 }
14325 [(set_attr "type" "load")])
14326 \f
14327 ;; Handle -fsplit-stack.
14328
14329 (define_expand "split_stack_prologue"
14330 [(const_int 0)]
14331 ""
14332 {
14333 rs6000_expand_split_stack_prologue ();
14334 DONE;
14335 })
14336
14337 (define_expand "load_split_stack_limit"
14338 [(set (match_operand 0)
14339 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))]
14340 ""
14341 {
14342 emit_insn (gen_rtx_SET (operands[0],
14343 gen_rtx_UNSPEC (Pmode,
14344 gen_rtvec (1, const0_rtx),
14345 UNSPEC_STACK_CHECK)));
14346 DONE;
14347 })
14348
14349 (define_insn "load_split_stack_limit_di"
14350 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
14351 (unspec:DI [(const_int 0)] UNSPEC_STACK_CHECK))]
14352 "TARGET_64BIT"
14353 "ld %0,-0x7040(13)"
14354 [(set_attr "type" "load")
14355 (set_attr "update" "no")
14356 (set_attr "indexed" "no")])
14357
14358 (define_insn "load_split_stack_limit_si"
14359 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
14360 (unspec:SI [(const_int 0)] UNSPEC_STACK_CHECK))]
14361 "!TARGET_64BIT"
14362 "lwz %0,-0x7020(2)"
14363 [(set_attr "type" "load")
14364 (set_attr "update" "no")
14365 (set_attr "indexed" "no")])
14366
14367 ;; A return instruction which the middle-end doesn't see.
14368 ;; Use r0 to stop regrename twiddling with lr restore insns emitted
14369 ;; after the call to __morestack.
14370 (define_insn "split_stack_return"
14371 [(unspec_volatile [(reg:SI 0) (reg:SI LR_REGNO)] UNSPECV_SPLIT_STACK_RETURN)]
14372 ""
14373 "blr"
14374 [(set_attr "type" "jmpreg")])
14375
14376 ;; If there are operand 0 bytes available on the stack, jump to
14377 ;; operand 1.
14378 (define_expand "split_stack_space_check"
14379 [(set (match_dup 2)
14380 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
14381 (set (match_dup 3)
14382 (minus (reg STACK_POINTER_REGNUM)
14383 (match_operand 0)))
14384 (set (match_dup 4) (compare:CCUNS (match_dup 3) (match_dup 2)))
14385 (set (pc) (if_then_else
14386 (geu (match_dup 4) (const_int 0))
14387 (label_ref (match_operand 1))
14388 (pc)))]
14389 ""
14390 {
14391 rs6000_split_stack_space_check (operands[0], operands[1]);
14392 DONE;
14393 })
14394 \f
14395 (define_insn "bpermd_<mode>"
14396 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
14397 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "r")
14398 (match_operand:P 2 "gpc_reg_operand" "r")] UNSPEC_BPERM))]
14399 "TARGET_POPCNTD"
14400 "bpermd %0,%1,%2"
14401 [(set_attr "type" "popcnt")])
14402
14403 \f
14404 ;; Builtin fma support. Handle
14405 ;; Note that the conditions for expansion are in the FMA_F iterator.
14406
14407 (define_expand "fma<mode>4"
14408 [(set (match_operand:FMA_F 0 "gpc_reg_operand")
14409 (fma:FMA_F
14410 (match_operand:FMA_F 1 "gpc_reg_operand")
14411 (match_operand:FMA_F 2 "gpc_reg_operand")
14412 (match_operand:FMA_F 3 "gpc_reg_operand")))]
14413 ""
14414 "")
14415
14416 (define_insn "*fma<mode>4_fpr"
14417 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,wa,wa")
14418 (fma:SFDF
14419 (match_operand:SFDF 1 "gpc_reg_operand" "%d,wa,wa")
14420 (match_operand:SFDF 2 "gpc_reg_operand" "d,wa,0")
14421 (match_operand:SFDF 3 "gpc_reg_operand" "d,0,wa")))]
14422 "TARGET_HARD_FLOAT"
14423 "@
14424 fmadd<s> %0,%1,%2,%3
14425 xsmadda<sd>p %x0,%x1,%x2
14426 xsmaddm<sd>p %x0,%x1,%x3"
14427 [(set_attr "type" "fp")
14428 (set_attr "isa" "*,<Fisa>,<Fisa>")])
14429
14430 ; Altivec only has fma and nfms.
14431 (define_expand "fms<mode>4"
14432 [(set (match_operand:FMA_F 0 "gpc_reg_operand")
14433 (fma:FMA_F
14434 (match_operand:FMA_F 1 "gpc_reg_operand")
14435 (match_operand:FMA_F 2 "gpc_reg_operand")
14436 (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand"))))]
14437 "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
14438 "")
14439
14440 (define_insn "*fms<mode>4_fpr"
14441 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,wa,wa")
14442 (fma:SFDF
14443 (match_operand:SFDF 1 "gpc_reg_operand" "d,wa,wa")
14444 (match_operand:SFDF 2 "gpc_reg_operand" "d,wa,0")
14445 (neg:SFDF (match_operand:SFDF 3 "gpc_reg_operand" "d,0,wa"))))]
14446 "TARGET_HARD_FLOAT"
14447 "@
14448 fmsub<s> %0,%1,%2,%3
14449 xsmsuba<sd>p %x0,%x1,%x2
14450 xsmsubm<sd>p %x0,%x1,%x3"
14451 [(set_attr "type" "fp")
14452 (set_attr "isa" "*,<Fisa>,<Fisa>")])
14453
14454 ;; If signed zeros are ignored, -(a * b - c) = -a * b + c.
14455 (define_expand "fnma<mode>4"
14456 [(set (match_operand:FMA_F 0 "gpc_reg_operand")
14457 (neg:FMA_F
14458 (fma:FMA_F
14459 (match_operand:FMA_F 1 "gpc_reg_operand")
14460 (match_operand:FMA_F 2 "gpc_reg_operand")
14461 (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand")))))]
14462 "!HONOR_SIGNED_ZEROS (<MODE>mode)"
14463 "")
14464
14465 ;; If signed zeros are ignored, -(a * b + c) = -a * b - c.
14466 (define_expand "fnms<mode>4"
14467 [(set (match_operand:FMA_F 0 "gpc_reg_operand")
14468 (neg:FMA_F
14469 (fma:FMA_F
14470 (match_operand:FMA_F 1 "gpc_reg_operand")
14471 (match_operand:FMA_F 2 "gpc_reg_operand")
14472 (match_operand:FMA_F 3 "gpc_reg_operand"))))]
14473 "!HONOR_SIGNED_ZEROS (<MODE>mode) && !VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
14474 "")
14475
14476 ; Not an official optab name, but used from builtins.
14477 (define_expand "nfma<mode>4"
14478 [(set (match_operand:FMA_F 0 "gpc_reg_operand")
14479 (neg:FMA_F
14480 (fma:FMA_F
14481 (match_operand:FMA_F 1 "gpc_reg_operand")
14482 (match_operand:FMA_F 2 "gpc_reg_operand")
14483 (match_operand:FMA_F 3 "gpc_reg_operand"))))]
14484 "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
14485 "")
14486
14487 (define_insn "*nfma<mode>4_fpr"
14488 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,wa,wa")
14489 (neg:SFDF
14490 (fma:SFDF
14491 (match_operand:SFDF 1 "gpc_reg_operand" "d,wa,wa")
14492 (match_operand:SFDF 2 "gpc_reg_operand" "d,wa,0")
14493 (match_operand:SFDF 3 "gpc_reg_operand" "d,0,wa"))))]
14494 "TARGET_HARD_FLOAT"
14495 "@
14496 fnmadd<s> %0,%1,%2,%3
14497 xsnmadda<sd>p %x0,%x1,%x2
14498 xsnmaddm<sd>p %x0,%x1,%x3"
14499 [(set_attr "type" "fp")
14500 (set_attr "isa" "*,<Fisa>,<Fisa>")])
14501
14502 ; Not an official optab name, but used from builtins.
14503 (define_expand "nfms<mode>4"
14504 [(set (match_operand:FMA_F 0 "gpc_reg_operand")
14505 (neg:FMA_F
14506 (fma:FMA_F
14507 (match_operand:FMA_F 1 "gpc_reg_operand")
14508 (match_operand:FMA_F 2 "gpc_reg_operand")
14509 (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand")))))]
14510 ""
14511 "")
14512
14513 (define_insn "*nfmssf4_fpr"
14514 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,wa,wa")
14515 (neg:SFDF
14516 (fma:SFDF
14517 (match_operand:SFDF 1 "gpc_reg_operand" "d,wa,wa")
14518 (match_operand:SFDF 2 "gpc_reg_operand" "d,wa,0")
14519 (neg:SFDF
14520 (match_operand:SFDF 3 "gpc_reg_operand" "d,0,wa")))))]
14521 "TARGET_HARD_FLOAT"
14522 "@
14523 fnmsub<s> %0,%1,%2,%3
14524 xsnmsuba<sd>p %x0,%x1,%x2
14525 xsnmsubm<sd>p %x0,%x1,%x3"
14526 [(set_attr "type" "fp")
14527 (set_attr "isa" "*,<Fisa>,<Fisa>")])
14528 \f
14529 (define_expand "rs6000_get_timebase"
14530 [(use (match_operand:DI 0 "gpc_reg_operand"))]
14531 ""
14532 {
14533 if (TARGET_POWERPC64)
14534 emit_insn (gen_rs6000_mftb_di (operands[0]));
14535 else
14536 emit_insn (gen_rs6000_get_timebase_ppc32 (operands[0]));
14537 DONE;
14538 })
14539
14540 (define_insn "rs6000_get_timebase_ppc32"
14541 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
14542 (unspec_volatile:DI [(const_int 0)] UNSPECV_MFTB))
14543 (clobber (match_scratch:SI 1 "=r"))
14544 (clobber (match_scratch:CC 2 "=y"))]
14545 "!TARGET_POWERPC64"
14546 {
14547 if (WORDS_BIG_ENDIAN)
14548 if (TARGET_MFCRF)
14549 {
14550 return "mfspr %0,269\;"
14551 "mfspr %L0,268\;"
14552 "mfspr %1,269\;"
14553 "cmpw %2,%0,%1\;"
14554 "bne- %2,$-16";
14555 }
14556 else
14557 {
14558 return "mftbu %0\;"
14559 "mftb %L0\;"
14560 "mftbu %1\;"
14561 "cmpw %2,%0,%1\;"
14562 "bne- %2,$-16";
14563 }
14564 else
14565 if (TARGET_MFCRF)
14566 {
14567 return "mfspr %L0,269\;"
14568 "mfspr %0,268\;"
14569 "mfspr %1,269\;"
14570 "cmpw %2,%L0,%1\;"
14571 "bne- %2,$-16";
14572 }
14573 else
14574 {
14575 return "mftbu %L0\;"
14576 "mftb %0\;"
14577 "mftbu %1\;"
14578 "cmpw %2,%L0,%1\;"
14579 "bne- %2,$-16";
14580 }
14581 }
14582 [(set_attr "length" "20")])
14583
14584 (define_insn "rs6000_mftb_<mode>"
14585 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
14586 (unspec_volatile:GPR [(const_int 0)] UNSPECV_MFTB))]
14587 ""
14588 {
14589 if (TARGET_MFCRF)
14590 return "mfspr %0,268";
14591 else
14592 return "mftb %0";
14593 })
14594
14595 \f
14596 ;; The ISA 3.0 mffsl instruction is a lower latency instruction
14597 ;; for reading bits [29:31], [45:51] and [56:63] of the FPSCR.
14598 (define_insn "rs6000_mffsl_hw"
14599 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
14600 (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFSL))]
14601 "TARGET_HARD_FLOAT"
14602 "mffsl %0")
14603
14604 (define_expand "rs6000_mffsl"
14605 [(set (match_operand:DF 0 "gpc_reg_operand")
14606 (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFSL))]
14607 "TARGET_HARD_FLOAT"
14608 {
14609 /* If the low latency mffsl instruction (ISA 3.0) is available use it,
14610 otherwise fall back to the older mffs instruction to emulate the mffsl
14611 instruction. */
14612
14613 if (!TARGET_P9_MISC)
14614 {
14615 rtx tmp1 = gen_reg_rtx (DFmode);
14616
14617 /* The mffs instruction reads the entire FPSCR. Emulate the mffsl
14618 instruction using the mffs instruction and masking the result. */
14619 emit_insn (gen_rs6000_mffs (tmp1));
14620
14621 rtx tmp1di = simplify_gen_subreg (DImode, tmp1, DFmode, 0);
14622 rtx tmp2 = gen_reg_rtx (DImode);
14623 emit_insn (gen_anddi3 (tmp2, tmp1di, GEN_INT (0x70007f0ffLL)));
14624
14625 rtx tmp2df = simplify_gen_subreg (DFmode, tmp2, DImode, 0);
14626 emit_move_insn (operands[0], tmp2df);
14627 DONE;
14628 }
14629
14630 emit_insn (gen_rs6000_mffsl_hw (operands[0]));
14631 DONE;
14632 })
14633
14634 (define_insn "rs6000_mffs"
14635 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
14636 (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFS))]
14637 "TARGET_HARD_FLOAT"
14638 "mffs %0")
14639
14640 (define_insn "rs6000_mtfsf"
14641 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "i")
14642 (match_operand:DF 1 "gpc_reg_operand" "d")]
14643 UNSPECV_MTFSF)]
14644 "TARGET_HARD_FLOAT"
14645 "mtfsf %0,%1")
14646
14647 (define_insn "rs6000_mtfsf_hi"
14648 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "n")
14649 (match_operand:DF 1 "gpc_reg_operand" "d")]
14650 UNSPECV_MTFSF_HI)]
14651 "TARGET_HARD_FLOAT"
14652 "mtfsf %0,%1,0,1")
14653
14654 \f
14655 ;; Power8 fusion support for fusing an addis instruction with a D-form load of
14656 ;; a GPR. The addis instruction must be adjacent to the load, and use the same
14657 ;; register that is being loaded. The fused ops must be physically adjacent.
14658
14659 ;; On Power8 GPR loads, we try to use the register that is being load. The
14660 ;; peephole2 then gathers any other fused possibilities that it can find after
14661 ;; register allocation. If power9 fusion is selected, we also fuse floating
14662 ;; point loads/stores.
14663
14664 ;; Find cases where the addis that feeds into a load instruction is either used
14665 ;; once or is the same as the target register, and replace it with the fusion
14666 ;; insn
14667
14668 (define_peephole2
14669 [(set (match_operand:P 0 "base_reg_operand")
14670 (match_operand:P 1 "fusion_gpr_addis"))
14671 (set (match_operand:INT1 2 "base_reg_operand")
14672 (match_operand:INT1 3 "fusion_gpr_mem_load"))]
14673 "TARGET_P8_FUSION
14674 && fusion_gpr_load_p (operands[0], operands[1], operands[2],
14675 operands[3])"
14676 [(const_int 0)]
14677 {
14678 expand_fusion_gpr_load (operands);
14679 DONE;
14680 })
14681
14682 ;; Fusion insn, created by the define_peephole2 above (and eventually by
14683 ;; reload)
14684
14685 (define_insn "*fusion_gpr_load_<mode>"
14686 [(set (match_operand:INT1 0 "base_reg_operand" "=b")
14687 (unspec:INT1 [(match_operand:INT1 1 "fusion_addis_mem_combo_load" "wF")]
14688 UNSPEC_FUSION_GPR))]
14689 "TARGET_P8_FUSION"
14690 {
14691 return emit_fusion_gpr_load (operands[0], operands[1]);
14692 }
14693 [(set_attr "type" "load")
14694 (set_attr "length" "8")])
14695
14696 \f
14697 ;; Optimize cases where we want to do a D-form load (register+offset) on
14698 ;; ISA 2.06/2.07 to an Altivec register, and the register allocator
14699 ;; has generated:
14700 ;; LFD 0,32(3)
14701 ;; XXLOR 32,0,0
14702 ;;
14703 ;; and we change this to:
14704 ;; LI 0,32
14705 ;; LXSDX 32,3,9
14706
14707 (define_peephole2
14708 [(match_scratch:P 0 "b")
14709 (set (match_operand:ALTIVEC_DFORM 1 "fpr_reg_operand")
14710 (match_operand:ALTIVEC_DFORM 2 "simple_offsettable_mem_operand"))
14711 (set (match_operand:ALTIVEC_DFORM 3 "altivec_register_operand")
14712 (match_dup 1))]
14713 "TARGET_VSX && !TARGET_P9_VECTOR && peep2_reg_dead_p (2, operands[1])"
14714 [(set (match_dup 0)
14715 (match_dup 4))
14716 (set (match_dup 3)
14717 (match_dup 5))]
14718 {
14719 rtx tmp_reg = operands[0];
14720 rtx mem = operands[2];
14721 rtx addr = XEXP (mem, 0);
14722 rtx add_op0, add_op1, new_addr;
14723
14724 gcc_assert (GET_CODE (addr) == PLUS || GET_CODE (addr) == LO_SUM);
14725 add_op0 = XEXP (addr, 0);
14726 add_op1 = XEXP (addr, 1);
14727 gcc_assert (REG_P (add_op0));
14728 new_addr = gen_rtx_PLUS (Pmode, add_op0, tmp_reg);
14729
14730 operands[4] = add_op1;
14731 operands[5] = change_address (mem, <ALTIVEC_DFORM:MODE>mode, new_addr);
14732 })
14733
14734 ;; Optimize cases were want to do a D-form store on ISA 2.06/2.07 from an
14735 ;; Altivec register, and the register allocator has generated:
14736 ;; XXLOR 0,32,32
14737 ;; STFD 0,32(3)
14738 ;;
14739 ;; and we change this to:
14740 ;; LI 0,32
14741 ;; STXSDX 32,3,9
14742
14743 (define_peephole2
14744 [(match_scratch:P 0 "b")
14745 (set (match_operand:ALTIVEC_DFORM 1 "fpr_reg_operand")
14746 (match_operand:ALTIVEC_DFORM 2 "altivec_register_operand"))
14747 (set (match_operand:ALTIVEC_DFORM 3 "simple_offsettable_mem_operand")
14748 (match_dup 1))]
14749 "TARGET_VSX && !TARGET_P9_VECTOR && peep2_reg_dead_p (2, operands[1])"
14750 [(set (match_dup 0)
14751 (match_dup 4))
14752 (set (match_dup 5)
14753 (match_dup 2))]
14754 {
14755 rtx tmp_reg = operands[0];
14756 rtx mem = operands[3];
14757 rtx addr = XEXP (mem, 0);
14758 rtx add_op0, add_op1, new_addr;
14759
14760 gcc_assert (GET_CODE (addr) == PLUS || GET_CODE (addr) == LO_SUM);
14761 add_op0 = XEXP (addr, 0);
14762 add_op1 = XEXP (addr, 1);
14763 gcc_assert (REG_P (add_op0));
14764 new_addr = gen_rtx_PLUS (Pmode, add_op0, tmp_reg);
14765
14766 operands[4] = add_op1;
14767 operands[5] = change_address (mem, <ALTIVEC_DFORM:MODE>mode, new_addr);
14768 })
14769
14770 \f
14771 ;; Miscellaneous ISA 2.06 (power7) instructions
14772 (define_insn "addg6s"
14773 [(set (match_operand:SI 0 "register_operand" "=r")
14774 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
14775 (match_operand:SI 2 "register_operand" "r")]
14776 UNSPEC_ADDG6S))]
14777 "TARGET_POPCNTD"
14778 "addg6s %0,%1,%2"
14779 [(set_attr "type" "integer")])
14780
14781 (define_insn "cdtbcd"
14782 [(set (match_operand:SI 0 "register_operand" "=r")
14783 (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
14784 UNSPEC_CDTBCD))]
14785 "TARGET_POPCNTD"
14786 "cdtbcd %0,%1"
14787 [(set_attr "type" "integer")])
14788
14789 (define_insn "cbcdtd"
14790 [(set (match_operand:SI 0 "register_operand" "=r")
14791 (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
14792 UNSPEC_CBCDTD))]
14793 "TARGET_POPCNTD"
14794 "cbcdtd %0,%1"
14795 [(set_attr "type" "integer")])
14796
14797 (define_int_iterator UNSPEC_DIV_EXTEND [UNSPEC_DIVE
14798 UNSPEC_DIVEU])
14799
14800 (define_int_attr div_extend [(UNSPEC_DIVE "e")
14801 (UNSPEC_DIVEU "eu")])
14802
14803 (define_insn "div<div_extend>_<mode>"
14804 [(set (match_operand:GPR 0 "register_operand" "=r")
14805 (unspec:GPR [(match_operand:GPR 1 "register_operand" "r")
14806 (match_operand:GPR 2 "register_operand" "r")]
14807 UNSPEC_DIV_EXTEND))]
14808 "TARGET_POPCNTD"
14809 "div<wd><div_extend> %0,%1,%2"
14810 [(set_attr "type" "div")
14811 (set_attr "size" "<bits>")])
14812
14813 \f
14814 ;; Pack/unpack 128-bit floating point types that take 2 scalar registers
14815
14816 ; Type of the 64-bit part when packing/unpacking 128-bit floating point types
14817 (define_mode_attr FP128_64 [(TF "DF")
14818 (IF "DF")
14819 (TD "DI")
14820 (KF "DI")])
14821
14822 (define_expand "unpack<mode>"
14823 [(set (match_operand:<FP128_64> 0 "nonimmediate_operand")
14824 (unspec:<FP128_64>
14825 [(match_operand:FMOVE128 1 "register_operand")
14826 (match_operand:QI 2 "const_0_to_1_operand")]
14827 UNSPEC_UNPACK_128BIT))]
14828 "FLOAT128_2REG_P (<MODE>mode)"
14829 "")
14830
14831 (define_insn_and_split "unpack<mode>_dm"
14832 [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m,d,r,m")
14833 (unspec:<FP128_64>
14834 [(match_operand:FMOVE128 1 "register_operand" "d,d,r,d,r")
14835 (match_operand:QI 2 "const_0_to_1_operand" "i,i,i,i,i")]
14836 UNSPEC_UNPACK_128BIT))]
14837 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE && FLOAT128_2REG_P (<MODE>mode)"
14838 "#"
14839 "&& reload_completed"
14840 [(set (match_dup 0) (match_dup 3))]
14841 {
14842 unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
14843
14844 if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
14845 {
14846 emit_note (NOTE_INSN_DELETED);
14847 DONE;
14848 }
14849
14850 operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
14851 }
14852 [(set_attr "type" "fp,fpstore,mtvsr,mfvsr,store")])
14853
14854 (define_insn_and_split "unpack<mode>_nodm"
14855 [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m,m")
14856 (unspec:<FP128_64>
14857 [(match_operand:FMOVE128 1 "register_operand" "d,d,r")
14858 (match_operand:QI 2 "const_0_to_1_operand" "i,i,i")]
14859 UNSPEC_UNPACK_128BIT))]
14860 "(!TARGET_POWERPC64 || !TARGET_DIRECT_MOVE) && FLOAT128_2REG_P (<MODE>mode)"
14861 "#"
14862 "&& reload_completed"
14863 [(set (match_dup 0) (match_dup 3))]
14864 {
14865 unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
14866
14867 if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
14868 {
14869 emit_note (NOTE_INSN_DELETED);
14870 DONE;
14871 }
14872
14873 operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
14874 }
14875 [(set_attr "type" "fp,fpstore,store")])
14876
14877 (define_expand "pack<mode>"
14878 [(use (match_operand:FMOVE128 0 "register_operand"))
14879 (use (match_operand:<FP128_64> 1 "register_operand"))
14880 (use (match_operand:<FP128_64> 2 "register_operand"))]
14881 "FLOAT128_2REG_P (<MODE>mode)"
14882 {
14883 if (TARGET_HARD_FLOAT)
14884 emit_insn (gen_pack<mode>_hard (operands[0], operands[1], operands[2]));
14885 else
14886 emit_insn (gen_pack<mode>_soft (operands[0], operands[1], operands[2]));
14887 DONE;
14888 })
14889
14890 (define_insn_and_split "pack<mode>_hard"
14891 [(set (match_operand:FMOVE128 0 "register_operand" "=&d")
14892 (unspec:FMOVE128
14893 [(match_operand:<FP128_64> 1 "register_operand" "d")
14894 (match_operand:<FP128_64> 2 "register_operand" "d")]
14895 UNSPEC_PACK_128BIT))]
14896 "FLOAT128_2REG_P (<MODE>mode) && TARGET_HARD_FLOAT"
14897 "#"
14898 "&& reload_completed"
14899 [(set (match_dup 3) (match_dup 1))
14900 (set (match_dup 4) (match_dup 2))]
14901 {
14902 unsigned dest_hi = REGNO (operands[0]);
14903 unsigned dest_lo = dest_hi + 1;
14904
14905 gcc_assert (!IN_RANGE (REGNO (operands[1]), dest_hi, dest_lo));
14906 gcc_assert (!IN_RANGE (REGNO (operands[2]), dest_hi, dest_lo));
14907
14908 operands[3] = gen_rtx_REG (<FP128_64>mode, dest_hi);
14909 operands[4] = gen_rtx_REG (<FP128_64>mode, dest_lo);
14910 }
14911 [(set_attr "type" "fp")
14912 (set_attr "length" "8")])
14913
14914 (define_insn_and_split "pack<mode>_soft"
14915 [(set (match_operand:FMOVE128 0 "register_operand" "=&r")
14916 (unspec:FMOVE128
14917 [(match_operand:<FP128_64> 1 "register_operand" "r")
14918 (match_operand:<FP128_64> 2 "register_operand" "r")]
14919 UNSPEC_PACK_128BIT))]
14920 "FLOAT128_2REG_P (<MODE>mode) && TARGET_SOFT_FLOAT"
14921 "#"
14922 "&& reload_completed"
14923 [(set (match_dup 3) (match_dup 1))
14924 (set (match_dup 4) (match_dup 2))]
14925 {
14926 unsigned dest_hi = REGNO (operands[0]);
14927 unsigned dest_lo = dest_hi + (TARGET_POWERPC64 ? 1 : 2);
14928
14929 gcc_assert (!IN_RANGE (REGNO (operands[1]), dest_hi, dest_lo));
14930 gcc_assert (!IN_RANGE (REGNO (operands[2]), dest_hi, dest_lo));
14931
14932 operands[3] = gen_rtx_REG (<FP128_64>mode, dest_hi);
14933 operands[4] = gen_rtx_REG (<FP128_64>mode, dest_lo);
14934 }
14935 [(set_attr "type" "integer")
14936 (set (attr "length")
14937 (if_then_else
14938 (match_test "TARGET_POWERPC64")
14939 (const_string "8")
14940 (const_string "16")))])
14941
14942 (define_insn "unpack<mode>"
14943 [(set (match_operand:DI 0 "register_operand" "=wa,wa")
14944 (unspec:DI [(match_operand:FMOVE128_VSX 1 "register_operand" "0,wa")
14945 (match_operand:QI 2 "const_0_to_1_operand" "O,i")]
14946 UNSPEC_UNPACK_128BIT))]
14947 "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)"
14948 {
14949 if (REGNO (operands[0]) == REGNO (operands[1]) && INTVAL (operands[2]) == 0)
14950 return ASM_COMMENT_START " xxpermdi to same register";
14951
14952 operands[3] = GEN_INT (INTVAL (operands[2]) == 0 ? 0 : 3);
14953 return "xxpermdi %x0,%x1,%x1,%3";
14954 }
14955 [(set_attr "type" "vecperm")])
14956
14957 (define_insn "pack<mode>"
14958 [(set (match_operand:FMOVE128_VSX 0 "register_operand" "=wa")
14959 (unspec:FMOVE128_VSX
14960 [(match_operand:DI 1 "register_operand" "wa")
14961 (match_operand:DI 2 "register_operand" "wa")]
14962 UNSPEC_PACK_128BIT))]
14963 "TARGET_VSX"
14964 "xxpermdi %x0,%x1,%x2,0"
14965 [(set_attr "type" "vecperm")])
14966
14967
14968 \f
14969 ;; ISA 2.08 IEEE 128-bit floating point support.
14970
14971 (define_insn "add<mode>3"
14972 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14973 (plus:IEEE128
14974 (match_operand:IEEE128 1 "altivec_register_operand" "v")
14975 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14976 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14977 "xsaddqp %0,%1,%2"
14978 [(set_attr "type" "vecfloat")
14979 (set_attr "size" "128")])
14980
14981 (define_insn "sub<mode>3"
14982 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14983 (minus:IEEE128
14984 (match_operand:IEEE128 1 "altivec_register_operand" "v")
14985 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14986 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14987 "xssubqp %0,%1,%2"
14988 [(set_attr "type" "vecfloat")
14989 (set_attr "size" "128")])
14990
14991 (define_insn "mul<mode>3"
14992 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14993 (mult:IEEE128
14994 (match_operand:IEEE128 1 "altivec_register_operand" "v")
14995 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14996 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14997 "xsmulqp %0,%1,%2"
14998 [(set_attr "type" "qmul")
14999 (set_attr "size" "128")])
15000
15001 (define_insn "div<mode>3"
15002 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
15003 (div:IEEE128
15004 (match_operand:IEEE128 1 "altivec_register_operand" "v")
15005 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
15006 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
15007 "xsdivqp %0,%1,%2"
15008 [(set_attr "type" "vecdiv")
15009 (set_attr "size" "128")])
15010
15011 (define_insn "sqrt<mode>2"
15012 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
15013 (sqrt:IEEE128
15014 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
15015 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
15016 "xssqrtqp %0,%1"
15017 [(set_attr "type" "vecdiv")
15018 (set_attr "size" "128")])
15019
15020 (define_expand "copysign<mode>3"
15021 [(use (match_operand:IEEE128 0 "altivec_register_operand"))
15022 (use (match_operand:IEEE128 1 "altivec_register_operand"))
15023 (use (match_operand:IEEE128 2 "altivec_register_operand"))]
15024 "FLOAT128_IEEE_P (<MODE>mode)"
15025 {
15026 if (TARGET_FLOAT128_HW)
15027 emit_insn (gen_copysign<mode>3_hard (operands[0], operands[1],
15028 operands[2]));
15029 else
15030 emit_insn (gen_copysign<mode>3_soft (operands[0], operands[1],
15031 operands[2]));
15032 DONE;
15033 })
15034
15035 (define_insn "copysign<mode>3_hard"
15036 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
15037 (copysign:IEEE128
15038 (match_operand:IEEE128 1 "altivec_register_operand" "v")
15039 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
15040 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
15041 "xscpsgnqp %0,%2,%1"
15042 [(set_attr "type" "vecmove")
15043 (set_attr "size" "128")])
15044
15045 (define_insn "copysign<mode>3_soft"
15046 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
15047 (copysign:IEEE128
15048 (match_operand:IEEE128 1 "altivec_register_operand" "v")
15049 (match_operand:IEEE128 2 "altivec_register_operand" "v")))
15050 (clobber (match_scratch:IEEE128 3 "=&v"))]
15051 "!TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
15052 "xscpsgndp %x3,%x2,%x1\;xxpermdi %x0,%x3,%x1,1"
15053 [(set_attr "type" "veccomplex")
15054 (set_attr "length" "8")])
15055
15056 (define_insn "@neg<mode>2_hw"
15057 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
15058 (neg:IEEE128
15059 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
15060 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
15061 "xsnegqp %0,%1"
15062 [(set_attr "type" "vecmove")
15063 (set_attr "size" "128")])
15064
15065
15066 (define_insn "@abs<mode>2_hw"
15067 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
15068 (abs:IEEE128
15069 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
15070 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
15071 "xsabsqp %0,%1"
15072 [(set_attr "type" "vecmove")
15073 (set_attr "size" "128")])
15074
15075
15076 (define_insn "*nabs<mode>2_hw"
15077 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
15078 (neg:IEEE128
15079 (abs:IEEE128
15080 (match_operand:IEEE128 1 "altivec_register_operand" "v"))))]
15081 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
15082 "xsnabsqp %0,%1"
15083 [(set_attr "type" "vecmove")
15084 (set_attr "size" "128")])
15085
15086 ;; Initially don't worry about doing fusion
15087 (define_insn "fma<mode>4_hw"
15088 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
15089 (fma:IEEE128
15090 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
15091 (match_operand:IEEE128 2 "altivec_register_operand" "v")
15092 (match_operand:IEEE128 3 "altivec_register_operand" "0")))]
15093 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
15094 "xsmaddqp %0,%1,%2"
15095 [(set_attr "type" "qmul")
15096 (set_attr "size" "128")])
15097
15098 (define_insn "*fms<mode>4_hw"
15099 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
15100 (fma:IEEE128
15101 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
15102 (match_operand:IEEE128 2 "altivec_register_operand" "v")
15103 (neg:IEEE128
15104 (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
15105 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
15106 "xsmsubqp %0,%1,%2"
15107 [(set_attr "type" "qmul")
15108 (set_attr "size" "128")])
15109
15110 (define_insn "*nfma<mode>4_hw"
15111 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
15112 (neg:IEEE128
15113 (fma:IEEE128
15114 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
15115 (match_operand:IEEE128 2 "altivec_register_operand" "v")
15116 (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
15117 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
15118 "xsnmaddqp %0,%1,%2"
15119 [(set_attr "type" "qmul")
15120 (set_attr "size" "128")])
15121
15122 (define_insn "*nfms<mode>4_hw"
15123 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
15124 (neg:IEEE128
15125 (fma:IEEE128
15126 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
15127 (match_operand:IEEE128 2 "altivec_register_operand" "v")
15128 (neg:IEEE128
15129 (match_operand:IEEE128 3 "altivec_register_operand" "0")))))]
15130 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
15131 "xsnmsubqp %0,%1,%2"
15132 [(set_attr "type" "qmul")
15133 (set_attr "size" "128")])
15134
15135 (define_insn "extend<SFDF:mode><IEEE128:mode>2_hw"
15136 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
15137 (float_extend:IEEE128
15138 (match_operand:SFDF 1 "altivec_register_operand" "v")))]
15139 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
15140 "xscvdpqp %0,%1"
15141 [(set_attr "type" "vecfloat")
15142 (set_attr "size" "128")])
15143
15144 ;; Conversion between KFmode and TFmode if TFmode is ieee 128-bit floating
15145 ;; point is a simple copy.
15146 (define_insn_and_split "extendkftf2"
15147 [(set (match_operand:TF 0 "vsx_register_operand" "=wa,?wa")
15148 (float_extend:TF (match_operand:KF 1 "vsx_register_operand" "0,wa")))]
15149 "TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD"
15150 "@
15151 #
15152 xxlor %x0,%x1,%x1"
15153 "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
15154 [(const_int 0)]
15155 {
15156 emit_note (NOTE_INSN_DELETED);
15157 DONE;
15158 }
15159 [(set_attr "type" "*,veclogical")
15160 (set_attr "length" "0,4")])
15161
15162 (define_insn_and_split "trunctfkf2"
15163 [(set (match_operand:KF 0 "vsx_register_operand" "=wa,?wa")
15164 (float_extend:KF (match_operand:TF 1 "vsx_register_operand" "0,wa")))]
15165 "TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD"
15166 "@
15167 #
15168 xxlor %x0,%x1,%x1"
15169 "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
15170 [(const_int 0)]
15171 {
15172 emit_note (NOTE_INSN_DELETED);
15173 DONE;
15174 }
15175 [(set_attr "type" "*,veclogical")
15176 (set_attr "length" "0,4")])
15177
15178 (define_insn "trunc<mode>df2_hw"
15179 [(set (match_operand:DF 0 "altivec_register_operand" "=v")
15180 (float_truncate:DF
15181 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
15182 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
15183 "xscvqpdp %0,%1"
15184 [(set_attr "type" "vecfloat")
15185 (set_attr "size" "128")])
15186
15187 ;; There is no KFmode -> SFmode instruction. Preserve the accuracy by doing
15188 ;; the KFmode -> DFmode conversion using round to odd rather than the normal
15189 ;; conversion
15190 (define_insn_and_split "trunc<mode>sf2_hw"
15191 [(set (match_operand:SF 0 "vsx_register_operand" "=wa")
15192 (float_truncate:SF
15193 (match_operand:IEEE128 1 "altivec_register_operand" "v")))
15194 (clobber (match_scratch:DF 2 "=v"))]
15195 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
15196 "#"
15197 "&& 1"
15198 [(set (match_dup 2)
15199 (unspec:DF [(match_dup 1)]
15200 UNSPEC_TRUNC_ROUND_TO_ODD))
15201 (set (match_dup 0)
15202 (float_truncate:SF (match_dup 2)))]
15203 {
15204 if (GET_CODE (operands[2]) == SCRATCH)
15205 operands[2] = gen_reg_rtx (DFmode);
15206 }
15207 [(set_attr "type" "vecfloat")
15208 (set_attr "length" "8")
15209 (set_attr "isa" "p8v")])
15210
15211 ;; Conversion between IEEE 128-bit and integer types
15212
15213 ;; The fix function for DImode and SImode was declared earlier as a
15214 ;; define_expand. It calls into rs6000_expand_float128_convert if we don't
15215 ;; have IEEE 128-bit hardware support. QImode and HImode are not provided
15216 ;; unless we have the IEEE 128-bit hardware.
15217 ;;
15218 ;; Unlike the code for converting SFmode/DFmode to QImode/HImode, we don't have
15219 ;; to provide a GPR target that used direct move and a conversion in the GPR
15220 ;; which works around QImode/HImode not being allowed in vector registers in
15221 ;; ISA 2.07 (power8).
15222 (define_insn "fix<uns>_<IEEE128:mode><SDI:mode>2_hw"
15223 [(set (match_operand:SDI 0 "altivec_register_operand" "=v")
15224 (any_fix:SDI (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
15225 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
15226 "xscvqp<su><wd>z %0,%1"
15227 [(set_attr "type" "vecfloat")
15228 (set_attr "size" "128")])
15229
15230 (define_insn "fix<uns>_trunc<IEEE128:mode><QHI:mode>2"
15231 [(set (match_operand:QHI 0 "altivec_register_operand" "=v")
15232 (any_fix:QHI
15233 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
15234 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
15235 "xscvqp<su>wz %0,%1"
15236 [(set_attr "type" "vecfloat")
15237 (set_attr "size" "128")])
15238
15239 ;; Combiner patterns to prevent moving the result of converting an IEEE 128-bit
15240 ;; floating point value to 8/16/32-bit integer to GPR in order to save it.
15241 (define_insn_and_split "*fix<uns>_trunc<IEEE128:mode><QHSI:mode>2_mem"
15242 [(set (match_operand:QHSI 0 "memory_operand" "=Z")
15243 (any_fix:QHSI
15244 (match_operand:IEEE128 1 "altivec_register_operand" "v")))
15245 (clobber (match_scratch:QHSI 2 "=v"))]
15246 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
15247 "#"
15248 "&& reload_completed"
15249 [(set (match_dup 2)
15250 (any_fix:QHSI (match_dup 1)))
15251 (set (match_dup 0)
15252 (match_dup 2))])
15253
15254 (define_insn "float_<mode>di2_hw"
15255 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
15256 (float:IEEE128 (match_operand:DI 1 "altivec_register_operand" "v")))]
15257 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
15258 "xscvsdqp %0,%1"
15259 [(set_attr "type" "vecfloat")
15260 (set_attr "size" "128")])
15261
15262 (define_insn_and_split "float_<mode>si2_hw"
15263 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
15264 (float:IEEE128 (match_operand:SI 1 "nonimmediate_operand" "vrZ")))
15265 (clobber (match_scratch:DI 2 "=v"))]
15266 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
15267 "#"
15268 "&& 1"
15269 [(set (match_dup 2)
15270 (sign_extend:DI (match_dup 1)))
15271 (set (match_dup 0)
15272 (float:IEEE128 (match_dup 2)))]
15273 {
15274 if (GET_CODE (operands[2]) == SCRATCH)
15275 operands[2] = gen_reg_rtx (DImode);
15276
15277 if (MEM_P (operands[1]))
15278 operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
15279 })
15280
15281 (define_insn_and_split "float<QHI:mode><IEEE128:mode>2"
15282 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v")
15283 (float:IEEE128 (match_operand:QHI 1 "nonimmediate_operand" "v,r,Z")))
15284 (clobber (match_scratch:DI 2 "=X,r,X"))]
15285 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
15286 "#"
15287 "&& reload_completed"
15288 [(const_int 0)]
15289 {
15290 rtx dest = operands[0];
15291 rtx src = operands[1];
15292 rtx dest_di = gen_rtx_REG (DImode, REGNO (dest));
15293
15294 if (altivec_register_operand (src, <QHI:MODE>mode))
15295 emit_insn (gen_extend<QHI:mode>di2 (dest_di, src));
15296 else if (int_reg_operand (src, <QHI:MODE>mode))
15297 {
15298 rtx ext_di = operands[2];
15299 emit_insn (gen_extend<QHI:mode>di2 (ext_di, src));
15300 emit_move_insn (dest_di, ext_di);
15301 }
15302 else if (MEM_P (src))
15303 {
15304 rtx dest_qhi = gen_rtx_REG (<QHI:MODE>mode, REGNO (dest));
15305 emit_move_insn (dest_qhi, src);
15306 emit_insn (gen_extend<QHI:mode>di2 (dest_di, dest_qhi));
15307 }
15308 else
15309 gcc_unreachable ();
15310
15311 emit_insn (gen_float_<IEEE128:mode>di2_hw (dest, dest_di));
15312 DONE;
15313 }
15314 [(set_attr "length" "8,12,12")
15315 (set_attr "type" "vecfloat")
15316 (set_attr "size" "128")])
15317
15318 (define_insn "floatuns_<mode>di2_hw"
15319 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
15320 (unsigned_float:IEEE128
15321 (match_operand:DI 1 "altivec_register_operand" "v")))]
15322 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
15323 "xscvudqp %0,%1"
15324 [(set_attr "type" "vecfloat")
15325 (set_attr "size" "128")])
15326
15327 (define_insn_and_split "floatuns_<mode>si2_hw"
15328 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
15329 (unsigned_float:IEEE128
15330 (match_operand:SI 1 "nonimmediate_operand" "vrZ")))
15331 (clobber (match_scratch:DI 2 "=v"))]
15332 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
15333 "#"
15334 "&& 1"
15335 [(set (match_dup 2)
15336 (zero_extend:DI (match_dup 1)))
15337 (set (match_dup 0)
15338 (float:IEEE128 (match_dup 2)))]
15339 {
15340 if (GET_CODE (operands[2]) == SCRATCH)
15341 operands[2] = gen_reg_rtx (DImode);
15342
15343 if (MEM_P (operands[1]))
15344 operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
15345 })
15346
15347 (define_insn_and_split "floatuns<QHI:mode><IEEE128:mode>2"
15348 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v")
15349 (unsigned_float:IEEE128
15350 (match_operand:QHI 1 "nonimmediate_operand" "v,r,Z")))
15351 (clobber (match_scratch:DI 2 "=X,r,X"))]
15352 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
15353 "#"
15354 "&& reload_completed"
15355 [(const_int 0)]
15356 {
15357 rtx dest = operands[0];
15358 rtx src = operands[1];
15359 rtx dest_di = gen_rtx_REG (DImode, REGNO (dest));
15360
15361 if (altivec_register_operand (src, <QHI:MODE>mode) || MEM_P (src))
15362 emit_insn (gen_zero_extend<QHI:mode>di2 (dest_di, src));
15363 else if (int_reg_operand (src, <QHI:MODE>mode))
15364 {
15365 rtx ext_di = operands[2];
15366 emit_insn (gen_zero_extend<QHI:mode>di2 (ext_di, src));
15367 emit_move_insn (dest_di, ext_di);
15368 }
15369 else
15370 gcc_unreachable ();
15371
15372 emit_insn (gen_floatuns_<IEEE128:mode>di2_hw (dest, dest_di));
15373 DONE;
15374 }
15375 [(set_attr "length" "8,12,8")
15376 (set_attr "type" "vecfloat")
15377 (set_attr "size" "128")])
15378
15379 ;; IEEE 128-bit round to integer built-in functions
15380 (define_insn "floor<mode>2"
15381 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
15382 (unspec:IEEE128
15383 [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
15384 UNSPEC_FRIM))]
15385 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
15386 "xsrqpi 1,%0,%1,3"
15387 [(set_attr "type" "vecfloat")
15388 (set_attr "size" "128")])
15389
15390 (define_insn "ceil<mode>2"
15391 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
15392 (unspec:IEEE128
15393 [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
15394 UNSPEC_FRIP))]
15395 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
15396 "xsrqpi 1,%0,%1,2"
15397 [(set_attr "type" "vecfloat")
15398 (set_attr "size" "128")])
15399
15400 (define_insn "btrunc<mode>2"
15401 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
15402 (unspec:IEEE128
15403 [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
15404 UNSPEC_FRIZ))]
15405 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
15406 "xsrqpi 1,%0,%1,1"
15407 [(set_attr "type" "vecfloat")
15408 (set_attr "size" "128")])
15409
15410 (define_insn "round<mode>2"
15411 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
15412 (unspec:IEEE128
15413 [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
15414 UNSPEC_FRIN))]
15415 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
15416 "xsrqpi 0,%0,%1,0"
15417 [(set_attr "type" "vecfloat")
15418 (set_attr "size" "128")])
15419
15420 ;; IEEE 128-bit instructions with round to odd semantics
15421 (define_insn "add<mode>3_odd"
15422 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
15423 (unspec:IEEE128
15424 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
15425 (match_operand:IEEE128 2 "altivec_register_operand" "v")]
15426 UNSPEC_ADD_ROUND_TO_ODD))]
15427 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
15428 "xsaddqpo %0,%1,%2"
15429 [(set_attr "type" "vecfloat")
15430 (set_attr "size" "128")])
15431
15432 (define_insn "sub<mode>3_odd"
15433 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
15434 (unspec:IEEE128
15435 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
15436 (match_operand:IEEE128 2 "altivec_register_operand" "v")]
15437 UNSPEC_SUB_ROUND_TO_ODD))]
15438 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
15439 "xssubqpo %0,%1,%2"
15440 [(set_attr "type" "vecfloat")
15441 (set_attr "size" "128")])
15442
15443 (define_insn "mul<mode>3_odd"
15444 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
15445 (unspec:IEEE128
15446 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
15447 (match_operand:IEEE128 2 "altivec_register_operand" "v")]
15448 UNSPEC_MUL_ROUND_TO_ODD))]
15449 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
15450 "xsmulqpo %0,%1,%2"
15451 [(set_attr "type" "qmul")
15452 (set_attr "size" "128")])
15453
15454 (define_insn "div<mode>3_odd"
15455 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
15456 (unspec:IEEE128
15457 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
15458 (match_operand:IEEE128 2 "altivec_register_operand" "v")]
15459 UNSPEC_DIV_ROUND_TO_ODD))]
15460 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
15461 "xsdivqpo %0,%1,%2"
15462 [(set_attr "type" "vecdiv")
15463 (set_attr "size" "128")])
15464
15465 (define_insn "sqrt<mode>2_odd"
15466 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
15467 (unspec:IEEE128
15468 [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
15469 UNSPEC_SQRT_ROUND_TO_ODD))]
15470 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
15471 "xssqrtqpo %0,%1"
15472 [(set_attr "type" "vecdiv")
15473 (set_attr "size" "128")])
15474
15475 (define_insn "fma<mode>4_odd"
15476 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
15477 (unspec:IEEE128
15478 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
15479 (match_operand:IEEE128 2 "altivec_register_operand" "v")
15480 (match_operand:IEEE128 3 "altivec_register_operand" "0")]
15481 UNSPEC_FMA_ROUND_TO_ODD))]
15482 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
15483 "xsmaddqpo %0,%1,%2"
15484 [(set_attr "type" "qmul")
15485 (set_attr "size" "128")])
15486
15487 (define_insn "*fms<mode>4_odd"
15488 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
15489 (unspec:IEEE128
15490 [(match_operand:IEEE128 1 "altivec_register_operand" "%v")
15491 (match_operand:IEEE128 2 "altivec_register_operand" "v")
15492 (neg:IEEE128
15493 (match_operand:IEEE128 3 "altivec_register_operand" "0"))]
15494 UNSPEC_FMA_ROUND_TO_ODD))]
15495 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
15496 "xsmsubqpo %0,%1,%2"
15497 [(set_attr "type" "qmul")
15498 (set_attr "size" "128")])
15499
15500 (define_insn "*nfma<mode>4_odd"
15501 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
15502 (neg:IEEE128
15503 (unspec:IEEE128
15504 [(match_operand:IEEE128 1 "altivec_register_operand" "%v")
15505 (match_operand:IEEE128 2 "altivec_register_operand" "v")
15506 (match_operand:IEEE128 3 "altivec_register_operand" "0")]
15507 UNSPEC_FMA_ROUND_TO_ODD)))]
15508 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
15509 "xsnmaddqpo %0,%1,%2"
15510 [(set_attr "type" "qmul")
15511 (set_attr "size" "128")])
15512
15513 (define_insn "*nfms<mode>4_odd"
15514 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
15515 (neg:IEEE128
15516 (unspec:IEEE128
15517 [(match_operand:IEEE128 1 "altivec_register_operand" "%v")
15518 (match_operand:IEEE128 2 "altivec_register_operand" "v")
15519 (neg:IEEE128
15520 (match_operand:IEEE128 3 "altivec_register_operand" "0"))]
15521 UNSPEC_FMA_ROUND_TO_ODD)))]
15522 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
15523 "xsnmsubqpo %0,%1,%2"
15524 [(set_attr "type" "qmul")
15525 (set_attr "size" "128")])
15526
15527 (define_insn "trunc<mode>df2_odd"
15528 [(set (match_operand:DF 0 "vsx_register_operand" "=v")
15529 (unspec:DF [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
15530 UNSPEC_TRUNC_ROUND_TO_ODD))]
15531 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
15532 "xscvqpdpo %0,%1"
15533 [(set_attr "type" "vecfloat")
15534 (set_attr "size" "128")])
15535
15536 ;; IEEE 128-bit comparisons
15537 (define_insn "*cmp<mode>_hw"
15538 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
15539 (compare:CCFP (match_operand:IEEE128 1 "altivec_register_operand" "v")
15540 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
15541 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
15542 "xscmpuqp %0,%1,%2"
15543 [(set_attr "type" "veccmp")
15544 (set_attr "size" "128")])
15545 \f
15546 ;; Miscellaneous ISA 3.0 (power9) instructions
15547
15548 (define_expand "darn_32_<mode>"
15549 [(use (match_operand:GPR 0 "register_operand"))]
15550 "TARGET_P9_MISC"
15551 {
15552 emit_insn (gen_darn (<MODE>mode, operands[0], const0_rtx));
15553 DONE;
15554 })
15555
15556 (define_expand "darn_64_<mode>"
15557 [(use (match_operand:GPR 0 "register_operand"))]
15558 "TARGET_P9_MISC"
15559 {
15560 emit_insn (gen_darn (<MODE>mode, operands[0], const1_rtx));
15561 DONE;
15562 })
15563
15564 (define_expand "darn_raw_<mode>"
15565 [(use (match_operand:GPR 0 "register_operand"))]
15566 "TARGET_P9_MISC"
15567 {
15568 emit_insn (gen_darn (<MODE>mode, operands[0], const2_rtx));
15569 DONE;
15570 })
15571
15572 (define_insn "@darn<mode>"
15573 [(set (match_operand:GPR 0 "register_operand" "=r")
15574 (unspec_volatile:GPR [(match_operand 1 "const_int_operand" "n")]
15575 UNSPECV_DARN))]
15576 "TARGET_P9_MISC"
15577 "darn %0,%1"
15578 [(set_attr "type" "integer")])
15579
15580 ;; Test byte within range.
15581 ;;
15582 ;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx
15583 ;; represents a byte whose value is ignored in this context and
15584 ;; vv, the least significant byte, holds the byte value that is to
15585 ;; be tested for membership within the range specified by operand 2.
15586 ;; The bytes of operand 2 are organized as xx:xx:hi:lo.
15587 ;;
15588 ;; Return in target register operand 0 a value of 1 if lo <= vv and
15589 ;; vv <= hi. Otherwise, set register operand 0 to 0.
15590 ;;
15591 ;; Though the instructions to which this expansion maps operate on
15592 ;; 64-bit registers, the current implementation only operates on
15593 ;; SI-mode operands as the high-order bits provide no information
15594 ;; that is not already available in the low-order bits. To avoid the
15595 ;; costs of data widening operations, future enhancements might allow
15596 ;; DI mode for operand 0 and/or might allow operand 1 to be QI mode.
15597 (define_expand "cmprb"
15598 [(set (match_dup 3)
15599 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
15600 (match_operand:SI 2 "gpc_reg_operand" "r")]
15601 UNSPEC_CMPRB))
15602 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
15603 (if_then_else:SI (lt (match_dup 3)
15604 (const_int 0))
15605 (const_int -1)
15606 (if_then_else (gt (match_dup 3)
15607 (const_int 0))
15608 (const_int 1)
15609 (const_int 0))))]
15610 "TARGET_P9_MISC"
15611 {
15612 operands[3] = gen_reg_rtx (CCmode);
15613 })
15614
15615 ;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx
15616 ;; represents a byte whose value is ignored in this context and
15617 ;; vv, the least significant byte, holds the byte value that is to
15618 ;; be tested for membership within the range specified by operand 2.
15619 ;; The bytes of operand 2 are organized as xx:xx:hi:lo.
15620 ;;
15621 ;; Set bit 1 (the GT bit, 0x4) of CR register operand 0 to 1 if
15622 ;; lo <= vv and vv <= hi. Otherwise, set the GT bit to 0. The other
15623 ;; 3 bits of the target CR register are all set to 0.
15624 (define_insn "*cmprb_internal"
15625 [(set (match_operand:CC 0 "cc_reg_operand" "=y")
15626 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
15627 (match_operand:SI 2 "gpc_reg_operand" "r")]
15628 UNSPEC_CMPRB))]
15629 "TARGET_P9_MISC"
15630 "cmprb %0,0,%1,%2"
15631 [(set_attr "type" "logical")])
15632
15633 ;; Set operand 0 register to -1 if the LT bit (0x8) of condition
15634 ;; register operand 1 is on. Otherwise, set operand 0 register to 1
15635 ;; if the GT bit (0x4) of condition register operand 1 is on.
15636 ;; Otherwise, set operand 0 to 0. Note that the result stored into
15637 ;; register operand 0 is non-zero iff either the LT or GT bits are on
15638 ;; within condition register operand 1.
15639 (define_insn "setb_signed"
15640 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
15641 (if_then_else:SI (lt (match_operand:CC 1 "cc_reg_operand" "y")
15642 (const_int 0))
15643 (const_int -1)
15644 (if_then_else (gt (match_dup 1)
15645 (const_int 0))
15646 (const_int 1)
15647 (const_int 0))))]
15648 "TARGET_P9_MISC"
15649 "setb %0,%1"
15650 [(set_attr "type" "logical")])
15651
15652 (define_insn "setb_unsigned"
15653 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
15654 (if_then_else:SI (ltu (match_operand:CCUNS 1 "cc_reg_operand" "y")
15655 (const_int 0))
15656 (const_int -1)
15657 (if_then_else (gtu (match_dup 1)
15658 (const_int 0))
15659 (const_int 1)
15660 (const_int 0))))]
15661 "TARGET_P9_MISC"
15662 "setb %0,%1"
15663 [(set_attr "type" "logical")])
15664
15665 ;; Test byte within two ranges.
15666 ;;
15667 ;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx
15668 ;; represents a byte whose value is ignored in this context and
15669 ;; vv, the least significant byte, holds the byte value that is to
15670 ;; be tested for membership within the range specified by operand 2.
15671 ;; The bytes of operand 2 are organized as hi_1:lo_1:hi_2:lo_2.
15672 ;;
15673 ;; Return in target register operand 0 a value of 1 if (lo_1 <= vv and
15674 ;; vv <= hi_1) or if (lo_2 <= vv and vv <= hi_2). Otherwise, set register
15675 ;; operand 0 to 0.
15676 ;;
15677 ;; Though the instructions to which this expansion maps operate on
15678 ;; 64-bit registers, the current implementation only operates on
15679 ;; SI-mode operands as the high-order bits provide no information
15680 ;; that is not already available in the low-order bits. To avoid the
15681 ;; costs of data widening operations, future enhancements might allow
15682 ;; DI mode for operand 0 and/or might allow operand 1 to be QI mode.
15683 (define_expand "cmprb2"
15684 [(set (match_dup 3)
15685 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
15686 (match_operand:SI 2 "gpc_reg_operand" "r")]
15687 UNSPEC_CMPRB2))
15688 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
15689 (if_then_else:SI (lt (match_dup 3)
15690 (const_int 0))
15691 (const_int -1)
15692 (if_then_else (gt (match_dup 3)
15693 (const_int 0))
15694 (const_int 1)
15695 (const_int 0))))]
15696 "TARGET_P9_MISC"
15697 {
15698 operands[3] = gen_reg_rtx (CCmode);
15699 })
15700
15701 ;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx
15702 ;; represents a byte whose value is ignored in this context and
15703 ;; vv, the least significant byte, holds the byte value that is to
15704 ;; be tested for membership within the ranges specified by operand 2.
15705 ;; The bytes of operand 2 are organized as hi_1:lo_1:hi_2:lo_2.
15706 ;;
15707 ;; Set bit 1 (the GT bit, 0x4) of CR register operand 0 to 1 if
15708 ;; (lo_1 <= vv and vv <= hi_1) or if (lo_2 <= vv and vv <= hi_2).
15709 ;; Otherwise, set the GT bit to 0. The other 3 bits of the target
15710 ;; CR register are all set to 0.
15711 (define_insn "*cmprb2_internal"
15712 [(set (match_operand:CC 0 "cc_reg_operand" "=y")
15713 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
15714 (match_operand:SI 2 "gpc_reg_operand" "r")]
15715 UNSPEC_CMPRB2))]
15716 "TARGET_P9_MISC"
15717 "cmprb %0,1,%1,%2"
15718 [(set_attr "type" "logical")])
15719
15720 ;; Test byte membership within set of 8 bytes.
15721 ;;
15722 ;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx
15723 ;; represents a byte whose value is ignored in this context and
15724 ;; vv, the least significant byte, holds the byte value that is to
15725 ;; be tested for membership within the set specified by operand 2.
15726 ;; The bytes of operand 2 are organized as e0:e1:e2:e3:e4:e5:e6:e7.
15727 ;;
15728 ;; Return in target register operand 0 a value of 1 if vv equals one
15729 ;; of the values e0, e1, e2, e3, e4, e5, e6, or e7. Otherwise, set
15730 ;; register operand 0 to 0. Note that the 8 byte values held within
15731 ;; operand 2 need not be unique.
15732 ;;
15733 ;; Though the instructions to which this expansion maps operate on
15734 ;; 64-bit registers, the current implementation requires that operands
15735 ;; 0 and 1 have mode SI as the high-order bits provide no information
15736 ;; that is not already available in the low-order bits. To avoid the
15737 ;; costs of data widening operations, future enhancements might allow
15738 ;; DI mode for operand 0 and/or might allow operand 1 to be QI mode.
15739 (define_expand "cmpeqb"
15740 [(set (match_dup 3)
15741 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
15742 (match_operand:DI 2 "gpc_reg_operand" "r")]
15743 UNSPEC_CMPEQB))
15744 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
15745 (if_then_else:SI (lt (match_dup 3)
15746 (const_int 0))
15747 (const_int -1)
15748 (if_then_else (gt (match_dup 3)
15749 (const_int 0))
15750 (const_int 1)
15751 (const_int 0))))]
15752 "TARGET_P9_MISC && TARGET_64BIT"
15753 {
15754 operands[3] = gen_reg_rtx (CCmode);
15755 })
15756
15757 ;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx
15758 ;; represents a byte whose value is ignored in this context and
15759 ;; vv, the least significant byte, holds the byte value that is to
15760 ;; be tested for membership within the set specified by operand 2.
15761 ;; The bytes of operand 2 are organized as e0:e1:e2:e3:e4:e5:e6:e7.
15762 ;;
15763 ;; Set bit 1 (the GT bit, 0x4) of CR register operand 0 to 1 if vv
15764 ;; equals one of the values e0, e1, e2, e3, e4, e5, e6, or e7. Otherwise,
15765 ;; set the GT bit to zero. The other 3 bits of the target CR register
15766 ;; are all set to 0.
15767 (define_insn "*cmpeqb_internal"
15768 [(set (match_operand:CC 0 "cc_reg_operand" "=y")
15769 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
15770 (match_operand:DI 2 "gpc_reg_operand" "r")]
15771 UNSPEC_CMPEQB))]
15772 "TARGET_P9_MISC && TARGET_64BIT"
15773 "cmpeqb %0,%1,%2"
15774 [(set_attr "type" "logical")])
15775
15776
15777 ;; ROP mitigation instructions.
15778
15779 (define_insn "hashst"
15780 [(set (match_operand:DI 0 "simple_offsettable_mem_operand" "=m")
15781 (unspec_volatile:DI [(match_operand:DI 1 "int_reg_operand" "r")]
15782 UNSPEC_HASHST))]
15783 "TARGET_POWER10 && rs6000_rop_protect"
15784 {
15785 static char templ[32];
15786 const char *p = rs6000_privileged ? "p" : "";
15787 sprintf (templ, "hashst%s %%1,%%0", p);
15788 return templ;
15789 }
15790 [(set_attr "type" "store")])
15791
15792 (define_insn "hashchk"
15793 [(unspec_volatile [(match_operand:DI 0 "int_reg_operand" "r")
15794 (match_operand:DI 1 "simple_offsettable_mem_operand" "m")]
15795 UNSPEC_HASHCHK)]
15796 "TARGET_POWER10 && rs6000_rop_protect"
15797 {
15798 static char templ[32];
15799 const char *p = rs6000_privileged ? "p" : "";
15800 sprintf (templ, "hashchk%s %%0,%%1", p);
15801 return templ;
15802 }
15803 [(set_attr "type" "load")])
15804 \f
15805
15806 (include "sync.md")
15807 (include "vector.md")
15808 (include "vsx.md")
15809 (include "altivec.md")
15810 (include "mma.md")
15811 (include "dfp.md")
15812 (include "crypto.md")
15813 (include "htm.md")
15814 (include "fusion.md")
15815 (include "pcrel-opt.md")