]> gcc.gnu.org Git - gcc.git/blob - gcc/config/rs6000/rs6000.md
PowerPC: Add -mcpu=future.
[gcc.git] / gcc / config / rs6000 / rs6000.md
1 ;; Machine description for IBM RISC System 6000 (POWER) for GNU C compiler
2 ;; Copyright (C) 1990-2023 Free Software Foundation, Inc.
3 ;; Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
4
5 ;; This file is part of GCC.
6
7 ;; GCC is free software; you can redistribute it and/or modify it
8 ;; under the terms of the GNU General Public License as published
9 ;; by the Free Software Foundation; either version 3, or (at your
10 ;; option) any later version.
11
12 ;; GCC is distributed in the hope that it will be useful, but WITHOUT
13 ;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 ;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
15 ;; License for more details.
16
17 ;; You should have received a copy of the GNU General Public License
18 ;; along with GCC; see the file COPYING3. If not see
19 ;; <http://www.gnu.org/licenses/>.
20
21 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
22
23 ;;
24 ;; REGNOS
25 ;;
26
27 (define_constants
28 [(FIRST_GPR_REGNO 0)
29 (STACK_POINTER_REGNUM 1)
30 (TOC_REGNUM 2)
31 (STATIC_CHAIN_REGNUM 11)
32 (HARD_FRAME_POINTER_REGNUM 31)
33 (LAST_GPR_REGNO 31)
34 (FIRST_FPR_REGNO 32)
35 (LAST_FPR_REGNO 63)
36 (FIRST_ALTIVEC_REGNO 64)
37 (LAST_ALTIVEC_REGNO 95)
38 (LR_REGNO 96)
39 (CTR_REGNO 97)
40 (CA_REGNO 98)
41 (ARG_POINTER_REGNUM 99)
42 (CR0_REGNO 100)
43 (CR1_REGNO 101)
44 (CR2_REGNO 102)
45 (CR3_REGNO 103)
46 (CR4_REGNO 104)
47 (CR5_REGNO 105)
48 (CR6_REGNO 106)
49 (CR7_REGNO 107)
50 (MAX_CR_REGNO 107)
51 (VRSAVE_REGNO 108)
52 (VSCR_REGNO 109)
53 (FRAME_POINTER_REGNUM 110)
54 ])
55
56 ;;
57 ;; UNSPEC usage
58 ;;
59
60 (define_c_enum "unspec"
61 [UNSPEC_PROBE_STACK ; probe stack memory reference
62 UNSPEC_TOCPTR ; address of a word pointing to the TOC
63 UNSPEC_TOC ; address of the TOC (more-or-less)
64 UNSPEC_TOCSLOT ; offset from r1 of toc pointer save slot
65 UNSPEC_MOVSI_GOT
66 UNSPEC_FCTIWZ
67 UNSPEC_FRIM
68 UNSPEC_FRIN
69 UNSPEC_FRIP
70 UNSPEC_FRIZ
71 UNSPEC_XSRDPI
72 UNSPEC_LD_MPIC ; load_macho_picbase
73 UNSPEC_RELD_MPIC ; re-load_macho_picbase
74 UNSPEC_MPIC_CORRECT ; macho_correct_pic
75 UNSPEC_TLSGD
76 UNSPEC_TLSLD
77 UNSPEC_TLS_GET_ADDR
78 UNSPEC_MOVESI_FROM_CR
79 UNSPEC_MOVESI_TO_CR
80 UNSPEC_XVTLSBB
81 UNSPEC_TLSDTPREL
82 UNSPEC_TLSDTPRELHA
83 UNSPEC_TLSDTPRELLO
84 UNSPEC_TLSGOTDTPREL
85 UNSPEC_TLSTPREL
86 UNSPEC_TLSTPRELHA
87 UNSPEC_TLSTPRELLO
88 UNSPEC_TLSGOTTPREL
89 UNSPEC_TLSTLS
90 UNSPEC_TLSTLS_PCREL
91 UNSPEC_FIX_TRUNC_TF ; fadd, rounding towards zero
92 UNSPEC_STFIWX
93 UNSPEC_POPCNTB
94 UNSPEC_FRES
95 UNSPEC_SP_SET
96 UNSPEC_SP_TEST
97 UNSPEC_SYNC
98 UNSPEC_LWSYNC
99 UNSPEC_SYNC_OP
100 UNSPEC_ATOMIC
101 UNSPEC_CMPXCHG
102 UNSPEC_XCHG
103 UNSPEC_AND
104 UNSPEC_DLMZB
105 UNSPEC_DLMZB_CR
106 UNSPEC_DLMZB_STRLEN
107 UNSPEC_RSQRT
108 UNSPEC_TOCREL
109 UNSPEC_MACHOPIC_OFFSET
110 UNSPEC_BPERM
111 UNSPEC_COPYSIGN
112 UNSPEC_PARITY
113 UNSPEC_CMPB
114 UNSPEC_FCTIW
115 UNSPEC_FCTID
116 UNSPEC_LFIWAX
117 UNSPEC_LFIWZX
118 UNSPEC_FCTIWUZ
119 UNSPEC_NOP
120 UNSPEC_GRP_END_NOP
121 UNSPEC_P8V_FMRGOW
122 UNSPEC_P8V_MTVSRWZ
123 UNSPEC_P8V_RELOAD_FROM_GPR
124 UNSPEC_P8V_MTVSRD
125 UNSPEC_P8V_XXPERMDI
126 UNSPEC_P8V_RELOAD_FROM_VSX
127 UNSPEC_ADDG6S
128 UNSPEC_CDTBCD
129 UNSPEC_CBCDTD
130 UNSPEC_DIVE
131 UNSPEC_DIVEU
132 UNSPEC_UNPACK_128BIT
133 UNSPEC_PACK_128BIT
134 UNSPEC_LSQ
135 UNSPEC_FUSION_GPR
136 UNSPEC_STACK_CHECK
137 UNSPEC_CMPRB
138 UNSPEC_CMPRB2
139 UNSPEC_CMPEQB
140 UNSPEC_ADD_ROUND_TO_ODD
141 UNSPEC_SUB_ROUND_TO_ODD
142 UNSPEC_MUL_ROUND_TO_ODD
143 UNSPEC_DIV_ROUND_TO_ODD
144 UNSPEC_FMA_ROUND_TO_ODD
145 UNSPEC_SQRT_ROUND_TO_ODD
146 UNSPEC_TRUNC_ROUND_TO_ODD
147 UNSPEC_SIGNBIT
148 UNSPEC_SF_FROM_SI
149 UNSPEC_SI_FROM_SF
150 UNSPEC_PLTSEQ
151 UNSPEC_PLT16_HA
152 UNSPEC_CFUGED
153 UNSPEC_CNTLZDM
154 UNSPEC_CNTTZDM
155 UNSPEC_PDEPD
156 UNSPEC_PEXTD
157 UNSPEC_HASHST
158 UNSPEC_HASHCHK
159 UNSPEC_XXSPLTIDP_CONST
160 UNSPEC_XXSPLTIW_CONST
161 ])
162
163 ;;
164 ;; UNSPEC_VOLATILE usage
165 ;;
166
167 (define_c_enum "unspecv"
168 [UNSPECV_BLOCK
169 UNSPECV_LL ; load-locked
170 UNSPECV_SC ; store-conditional
171 UNSPECV_PROBE_STACK_RANGE ; probe range of stack addresses
172 UNSPECV_EH_RR ; eh_reg_restore
173 UNSPECV_ISYNC ; isync instruction
174 UNSPECV_MFTB ; move from time base
175 UNSPECV_DARN ; darn (deliver a random number)
176 UNSPECV_NLGR ; non-local goto receiver
177 UNSPECV_MFFS ; Move from FPSCR
178 UNSPECV_MFFSL ; Move from FPSCR light instruction version
179 UNSPECV_MFFSCRN ; Move from FPSCR float rounding mode
180 UNSPECV_MFFSCDRN ; Move from FPSCR decimal float rounding mode
181 UNSPECV_MTFSF ; Move to FPSCR Fields 8 to 15
182 UNSPECV_MTFSF_HI ; Move to FPSCR Fields 0 to 7
183 UNSPECV_MTFSB0 ; Set FPSCR Field bit to 0
184 UNSPECV_MTFSB1 ; Set FPSCR Field bit to 1
185 UNSPECV_SPLIT_STACK_RETURN ; A camouflaged return
186 UNSPECV_SPEC_BARRIER ; Speculation barrier
187 UNSPECV_PLT16_LO
188 UNSPECV_PLT_PCREL
189 ])
190
191 ; The three different kinds of epilogue.
192 (define_enum "epilogue_type" [normal sibcall eh_return])
193 \f
194 ;; Define an insn type attribute. This is used in function unit delay
195 ;; computations.
196 (define_attr "type"
197 "integer,two,three,
198 add,logical,shift,insert,
199 mul,halfmul,div,
200 exts,cntlz,popcnt,isel,
201 load,store,fpload,fpstore,vecload,vecstore,
202 cmp,
203 branch,jmpreg,mfjmpr,mtjmpr,trap,isync,sync,load_l,store_c,
204 cr_logical,mfcr,mfcrf,mtcr,
205 fpcompare,fp,fpsimple,dmul,qmul,sdiv,ddiv,ssqrt,dsqrt,
206 vecsimple,veccomplex,vecdiv,veccmp,veccmpsimple,vecperm,
207 vecfloat,vecfdiv,vecdouble,mtvsr,mfvsr,crypto,
208 veclogical,veccmpfx,vecexts,vecmove,
209 htm,htmsimple,dfp,mma,
210 fused_arith_logical,
211 fused_cmp_isel,
212 fused_carry,
213 fused_load_cmpi,
214 fused_load_load,fused_store_store,
215 fused_addis_load,
216 fused_mtbc,
217 fused_vector"
218 (const_string "integer"))
219 ;; Attr type definitions for fused pairs:
220 ;; fused_arith_logical is used for scalar logical+add/subf and
221 ;; add/subf+logical pairs of instructions.
222 ;; fused_load_cmpi is used for a D-form load fused with
223 ;; a compare immediate.
224 ;; fused_load_load is for a fused pair of loads to adjacent addresses.
225 ;; fused_store_store is for a fused pair of stores to adjacent addresses.
226 ;; fused_addis_load is for addis fused to D-form load for a larger immediate.
227 ;; fused_mtbc is for fused mtlr and bclr[l] pairs.
228 ;; fused_vector is for a fused pair of vector logical instructions.
229
230 ;; What data size does this instruction work on?
231 ;; This is used for insert, mul and others as necessary.
232 (define_attr "size" "8,16,32,64,128,256" (const_string "32"))
233
234 ;; What is the insn_cost for this insn? The target hook can still override
235 ;; this. For optimizing for size the "length" attribute is used instead.
236 (define_attr "cost" "" (const_int 0))
237
238 ;; Is this instruction record form ("dot", signed compare to 0, writing CR0)?
239 ;; This is used for add, logical, shift, exts, mul.
240 (define_attr "dot" "no,yes" (const_string "no"))
241
242 ;; Does this instruction sign-extend its result?
243 ;; This is used for load insns.
244 (define_attr "sign_extend" "no,yes" (const_string "no"))
245
246 ;; Does this cr_logical instruction have three operands? That is, BT != BB.
247 (define_attr "cr_logical_3op" "no,yes" (const_string "no"))
248
249 ;; Does this instruction use indexed (that is, reg+reg) addressing?
250 ;; This is used for load and store insns. If operand 0 or 1 is a MEM
251 ;; it is automatically set based on that. If a load or store instruction
252 ;; has fewer than two operands it needs to set this attribute manually
253 ;; or the compiler will crash.
254 (define_attr "indexed" "no,yes"
255 (if_then_else (ior (match_operand 0 "indexed_address_mem")
256 (match_operand 1 "indexed_address_mem"))
257 (const_string "yes")
258 (const_string "no")))
259
260 ;; Does this instruction use update addressing?
261 ;; This is used for load and store insns. See the comments for "indexed".
262 (define_attr "update" "no,yes"
263 (if_then_else (ior (match_operand 0 "update_address_mem")
264 (match_operand 1 "update_address_mem"))
265 (const_string "yes")
266 (const_string "no")))
267
268 ;; Is this instruction using operands[2] as shift amount, and can that be a
269 ;; register?
270 ;; This is used for shift insns.
271 (define_attr "maybe_var_shift" "no,yes" (const_string "no"))
272
273 ;; Is this instruction using a shift amount from a register?
274 ;; This is used for shift insns.
275 (define_attr "var_shift" "no,yes"
276 (if_then_else (and (eq_attr "type" "shift")
277 (eq_attr "maybe_var_shift" "yes"))
278 (if_then_else (match_operand 2 "gpc_reg_operand")
279 (const_string "yes")
280 (const_string "no"))
281 (const_string "no")))
282
283 ;; Is copying of this instruction disallowed?
284 (define_attr "cannot_copy" "no,yes" (const_string "no"))
285
286
287 ;; Whether this insn has a prefixed form and a non-prefixed form.
288 (define_attr "maybe_prefixed" "no,yes"
289 (if_then_else (eq_attr "type" "load,fpload,vecload,store,fpstore,vecstore,
290 integer,add")
291 (const_string "yes")
292 (const_string "no")))
293
294 ;; Whether an insn is a prefixed insn. A prefixed instruction has a prefix
295 ;; instruction word that conveys additional information such as a larger
296 ;; immediate, additional operands, etc., in addition to the normal instruction
297 ;; word. The default "length" attribute will also be adjusted by default to
298 ;; be 12 bytes.
299 (define_attr "prefixed" "no,yes"
300 (cond [(ior (match_test "!TARGET_PREFIXED")
301 (match_test "!NONJUMP_INSN_P (insn)")
302 (eq_attr "maybe_prefixed" "no"))
303 (const_string "no")
304
305 (eq_attr "type" "load,fpload,vecload")
306 (if_then_else (match_test "prefixed_load_p (insn)")
307 (const_string "yes")
308 (const_string "no"))
309
310 (eq_attr "type" "store,fpstore,vecstore")
311 (if_then_else (match_test "prefixed_store_p (insn)")
312 (const_string "yes")
313 (const_string "no"))
314
315 (eq_attr "type" "integer,add")
316 (if_then_else (match_test "prefixed_paddi_p (insn)")
317 (const_string "yes")
318 (const_string "no"))]
319
320 (const_string "no")))
321
322 ;; Whether an insn loads an external address for the PCREL_OPT optimizaton.
323 (define_attr "loads_external_address" "no,yes"
324 (const_string "no"))
325
326 ;; Return the number of real hardware instructions in a combined insn. If it
327 ;; is 0, just use the length / 4.
328 (define_attr "num_insns" "" (const_int 0))
329
330 ;; If an insn is prefixed, return the maximum number of prefixed instructions
331 ;; in the insn. The macro ADJUST_INSN_LENGTH uses this number to adjust the
332 ;; insn length.
333 (define_attr "max_prefixed_insns" "" (const_int 1))
334
335 ;; Length of the instruction (in bytes). This length does not consider the
336 ;; length for prefixed instructions. The macro ADJUST_INSN_LENGTH will adjust
337 ;; the length if there are prefixed instructions.
338 ;;
339 ;; While it might be tempting to use num_insns to calculate the length, it can
340 ;; be problematical unless all insn lengths are adjusted to use num_insns
341 ;; (i.e. if num_insns is 0, it will get the length, which in turn will get
342 ;; num_insns and recurse).
343 (define_attr "length" "" (const_int 4))
344
345 ;; Processor type -- this attribute must exactly match the processor_type
346 ;; enumeration in rs6000-opts.h.
347 (define_attr "cpu"
348 "ppc601,ppc603,ppc604,ppc604e,ppc620,ppc630,
349 ppc750,ppc7400,ppc7450,
350 ppc403,ppc405,ppc440,ppc476,
351 ppc8540,ppc8548,ppce300c2,ppce300c3,ppce500mc,ppce500mc64,ppce5500,ppce6500,
352 power4,power5,power6,power7,power8,power9,power10,
353 rs64a,mpccore,cell,ppca2,titan,future"
354 (const (symbol_ref "(enum attr_cpu) rs6000_tune")))
355
356 ;; The ISA we implement.
357 (define_attr "isa" "any,p5,p6,p7,p7v,p8v,p9,p9v,p9kf,p9tf,p10"
358 (const_string "any"))
359
360 ;; Is this alternative enabled for the current CPU/ISA/etc.?
361 (define_attr "enabled" ""
362 (cond
363 [(eq_attr "isa" "any")
364 (const_int 1)
365
366 (and (eq_attr "isa" "p5")
367 (match_test "TARGET_POPCNTB"))
368 (const_int 1)
369
370 (and (eq_attr "isa" "p6")
371 (match_test "TARGET_CMPB"))
372 (const_int 1)
373
374 (and (eq_attr "isa" "p7")
375 (match_test "TARGET_POPCNTD"))
376 (const_int 1)
377
378 (and (eq_attr "isa" "p7v")
379 (match_test "TARGET_VSX"))
380 (const_int 1)
381
382 (and (eq_attr "isa" "p8v")
383 (match_test "TARGET_P8_VECTOR"))
384 (const_int 1)
385
386 (and (eq_attr "isa" "p9")
387 (match_test "TARGET_MODULO"))
388 (const_int 1)
389
390 (and (eq_attr "isa" "p9v")
391 (match_test "TARGET_P9_VECTOR"))
392 (const_int 1)
393
394 (and (eq_attr "isa" "p9kf")
395 (match_test "TARGET_FLOAT128_TYPE"))
396 (const_int 1)
397
398 (and (eq_attr "isa" "p9tf")
399 (match_test "FLOAT128_VECTOR_P (TFmode)"))
400 (const_int 1)
401
402 (and (eq_attr "isa" "p10")
403 (match_test "TARGET_POWER10"))
404 (const_int 1)
405 ] (const_int 0)))
406
407 ;; If this instruction is microcoded on the CELL processor
408 ; The default for load extended, the recorded instructions and rotate/shifts by a variable is always microcoded
409 (define_attr "cell_micro" "not,conditional,always"
410 (if_then_else (ior (and (eq_attr "type" "shift,exts,mul")
411 (eq_attr "dot" "yes"))
412 (and (eq_attr "type" "load")
413 (eq_attr "sign_extend" "yes"))
414 (and (eq_attr "type" "shift")
415 (eq_attr "var_shift" "yes")))
416 (const_string "always")
417 (const_string "not")))
418
419 (automata_option "ndfa")
420
421 (include "rs64.md")
422 (include "mpc.md")
423 (include "40x.md")
424 (include "440.md")
425 (include "476.md")
426 (include "601.md")
427 (include "603.md")
428 (include "6xx.md")
429 (include "7xx.md")
430 (include "7450.md")
431 (include "8540.md")
432 (include "e300c2c3.md")
433 (include "e500mc.md")
434 (include "e500mc64.md")
435 (include "e5500.md")
436 (include "e6500.md")
437 (include "power4.md")
438 (include "power5.md")
439 (include "power6.md")
440 (include "power7.md")
441 (include "power8.md")
442 (include "power9.md")
443 (include "power10.md")
444 (include "cell.md")
445 (include "a2.md")
446 (include "titan.md")
447
448 (include "predicates.md")
449 (include "constraints.md")
450
451 \f
452 ;; Mode iterators
453
454 ; This mode iterator allows :GPR to be used to indicate the allowable size
455 ; of whole values in GPRs.
456 (define_mode_iterator GPR [SI (DI "TARGET_POWERPC64")])
457
458 ; And again, for patterns that need two (potentially) different integer modes.
459 (define_mode_iterator GPR2 [SI (DI "TARGET_POWERPC64")])
460
461 ; Any supported integer mode.
462 (define_mode_iterator INT [QI HI SI DI TI PTI])
463
464 ; Any supported integer mode that fits in one register.
465 (define_mode_iterator INT1 [QI HI SI (DI "TARGET_POWERPC64")])
466
467 ; Integer modes supported in VSX registers with ISA 3.0 instructions
468 (define_mode_iterator INT_ISA3 [QI HI SI DI])
469
470 ; Everything we can extend QImode to.
471 (define_mode_iterator EXTQI [SI (DI "TARGET_POWERPC64")])
472
473 ; Everything we can extend HImode to.
474 (define_mode_iterator EXTHI [SI (DI "TARGET_POWERPC64")])
475
476 ; Everything we can extend SImode to.
477 (define_mode_iterator EXTSI [(DI "TARGET_POWERPC64")])
478
479 ; QImode or HImode for small integer moves and small atomic ops
480 (define_mode_iterator QHI [QI HI])
481
482 ; QImode, HImode, SImode for fused ops only for GPR loads
483 (define_mode_iterator QHSI [QI HI SI])
484
485 ; HImode or SImode for sign extended fusion ops
486 (define_mode_iterator HSI [HI SI])
487
488 ; SImode or DImode, even if DImode doesn't fit in GPRs.
489 (define_mode_iterator SDI [SI DI])
490
491 ; The size of a pointer. Also, the size of the value that a record-condition
492 ; (one with a '.') will compare; and the size used for arithmetic carries.
493 (define_mode_iterator P [(SI "TARGET_32BIT") (DI "TARGET_64BIT")])
494
495 ; Iterator to add PTImode along with TImode (TImode can go in VSX registers,
496 ; PTImode is GPR only)
497 (define_mode_iterator TI2 [TI PTI])
498
499 ; Any hardware-supported floating-point mode
500 (define_mode_iterator FP [
501 (SF "TARGET_HARD_FLOAT")
502 (DF "TARGET_HARD_FLOAT")
503 (TF "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128")
504 (IF "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128")
505 (KF "TARGET_FLOAT128_TYPE")
506 (DD "TARGET_DFP")
507 (TD "TARGET_DFP")])
508
509 ; Any fma capable floating-point mode.
510 (define_mode_iterator FMA_F [
511 (SF "TARGET_HARD_FLOAT")
512 (DF "TARGET_HARD_FLOAT || VECTOR_UNIT_VSX_P (DFmode)")
513 (V4SF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)")
514 (V2DF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V2DFmode)")
515 (KF "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (KFmode)")
516 (TF "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (TFmode)")
517 ])
518
519 ; Floating point move iterators to combine binary and decimal moves
520 (define_mode_iterator FMOVE32 [SF SD])
521 (define_mode_iterator FMOVE64 [DF DD])
522 (define_mode_iterator FMOVE64X [DI DF DD])
523 (define_mode_iterator FMOVE128 [(TF "TARGET_LONG_DOUBLE_128")
524 (IF "FLOAT128_IBM_P (IFmode)")
525 (TD "TARGET_HARD_FLOAT")])
526
527 (define_mode_iterator FMOVE128_FPR [(TF "FLOAT128_2REG_P (TFmode)")
528 (IF "FLOAT128_2REG_P (IFmode)")
529 (TD "TARGET_HARD_FLOAT")])
530
531 ; Iterators for 128 bit types for direct move
532 (define_mode_iterator FMOVE128_GPR [TI
533 V16QI
534 V8HI
535 V4SI
536 V4SF
537 V2DI
538 V2DF
539 V1TI
540 (KF "FLOAT128_VECTOR_P (KFmode)")
541 (TF "FLOAT128_VECTOR_P (TFmode)")])
542
543 ; Iterator for 128-bit VSX types for pack/unpack
544 (define_mode_iterator FMOVE128_VSX [V1TI KF])
545
546 ; Iterators for converting to/from TFmode
547 (define_mode_iterator IFKF [IF KF])
548
549 ; Constraints for moving IF/KFmode.
550 (define_mode_attr IFKF_reg [(IF "d") (KF "wa")])
551
552 ; Whether a floating point move is ok, don't allow SD without hardware FP
553 (define_mode_attr fmove_ok [(SF "")
554 (DF "")
555 (SD "TARGET_HARD_FLOAT")
556 (DD "")])
557
558 ; Convert REAL_VALUE to the appropriate bits
559 (define_mode_attr real_value_to_target [(SF "REAL_VALUE_TO_TARGET_SINGLE")
560 (DF "REAL_VALUE_TO_TARGET_DOUBLE")
561 (SD "REAL_VALUE_TO_TARGET_DECIMAL32")
562 (DD "REAL_VALUE_TO_TARGET_DECIMAL64")])
563
564 ; Whether 0.0 has an all-zero bit pattern
565 (define_mode_attr zero_fp [(SF "j")
566 (DF "j")
567 (TF "j")
568 (IF "j")
569 (KF "j")
570 (SD "wn")
571 (DD "wn")
572 (TD "wn")])
573
574 ; Definitions for 64-bit VSX
575 (define_mode_attr f64_vsx [(DF "wa") (DD "wn")])
576
577 ; Definitions for 64-bit direct move
578 (define_mode_attr f64_dm [(DF "wa") (DD "d")])
579
580 ; Definitions for 64-bit use of altivec registers
581 (define_mode_attr f64_av [(DF "v") (DD "wn")])
582
583 ; Definitions for 64-bit access to ISA 3.0 (power9) vector
584 (define_mode_attr f64_p9 [(DF "v") (DD "wn")])
585
586 ; These modes do not fit in integer registers in 32-bit mode.
587 (define_mode_iterator DIFD [DI DF DD])
588
589 ; Iterator for reciprocal estimate instructions
590 (define_mode_iterator RECIPF [SF DF V4SF V2DF])
591
592 ; SFmode or DFmode.
593 (define_mode_iterator SFDF [SF DF])
594
595 ; And again, for when we need two FP modes in a pattern.
596 (define_mode_iterator SFDF2 [SF DF])
597
598 ; A generic s/d attribute, for sp/dp for example.
599 (define_mode_attr sd [(SF "s") (DF "d")
600 (V4SF "s") (V2DF "d")])
601
602 ; "s" or nothing, for fmuls/fmul for example.
603 (define_mode_attr s [(SF "s") (DF "")])
604
605 ; Iterator for 128-bit floating point that uses the IBM double-double format
606 (define_mode_iterator IBM128 [(IF "FLOAT128_IBM_P (IFmode)")
607 (TF "FLOAT128_IBM_P (TFmode)")])
608
609 ; Iterator for 128-bit floating point that uses IEEE 128-bit float
610 (define_mode_iterator IEEE128 [(KF "FLOAT128_IEEE_P (KFmode)")
611 (TF "FLOAT128_IEEE_P (TFmode)")])
612
613 ; Iterator for 128-bit floating point
614 (define_mode_iterator FLOAT128 [(KF "TARGET_FLOAT128_TYPE")
615 (IF "TARGET_FLOAT128_TYPE")
616 (TF "TARGET_LONG_DOUBLE_128")])
617
618 ; Iterator for signbit on 64-bit machines with direct move
619 (define_mode_iterator SIGNBIT [(KF "FLOAT128_VECTOR_P (KFmode)")
620 (TF "FLOAT128_VECTOR_P (TFmode)")])
621
622 ; Which isa is needed for those float instructions?
623 (define_mode_attr Fisa [(SF "p8v") (DF "*") (DI "*")])
624
625 ; FRE/FRES support
626 (define_mode_attr FFRE [(SF "FRES") (DF "FRE")])
627
628 ; Conditional returns.
629 (define_code_iterator any_return [return simple_return])
630 (define_code_attr return_pred [(return "direct_return ()")
631 (simple_return "1")])
632 (define_code_attr return_str [(return "") (simple_return "simple_")])
633
634 ; Logical operators.
635 (define_code_iterator iorxor [ior xor])
636 (define_code_iterator and_ior_xor [and ior xor])
637
638 ; Signed/unsigned variants of ops.
639 (define_code_iterator any_extend [sign_extend zero_extend])
640 (define_code_iterator any_fix [fix unsigned_fix])
641 (define_code_iterator any_float [float unsigned_float])
642
643 (define_code_attr u [(sign_extend "")
644 (zero_extend "u")
645 (fix "")
646 (unsigned_fix "u")])
647
648 (define_code_attr su [(sign_extend "s")
649 (zero_extend "u")
650 (fix "s")
651 (unsigned_fix "u")
652 (float "s")
653 (unsigned_float "u")])
654
655 (define_code_attr az [(sign_extend "a")
656 (zero_extend "z")
657 (fix "a")
658 (unsigned_fix "z")
659 (float "a")
660 (unsigned_float "z")])
661
662 (define_code_attr uns [(fix "")
663 (unsigned_fix "uns")
664 (float "")
665 (unsigned_float "uns")])
666
667 ; Various instructions that come in SI and DI forms.
668 ; A generic w/d attribute, for things like cmpw/cmpd.
669 (define_mode_attr wd [(QI "b")
670 (HI "h")
671 (SI "w")
672 (DI "d")
673 (V16QI "b")
674 (V8HI "h")
675 (V4SI "w")
676 (V2DI "d")
677 (V1TI "q")
678 (TI "q")])
679
680 ; For double extract from different origin types
681 (define_mode_attr du_or_d [(QI "du")
682 (HI "du")
683 (SI "du")
684 (DI "d")
685 (V16QI "du")
686 (V8HI "du")
687 (V4SI "du")
688 (V2DI "d")])
689
690 ;; How many bits (per element) in this mode?
691 (define_mode_attr bits [(QI "8") (HI "16") (SI "32") (DI "64")
692 (SF "32") (DF "64")
693 (DD "64") (TD "128")
694 (V4SI "32") (V2DI "64")])
695
696 ; DImode bits
697 (define_mode_attr dbits [(QI "56") (HI "48") (SI "32")])
698
699 ;; Bitmask for shift instructions
700 (define_mode_attr hH [(SI "h") (DI "H")])
701
702 ;; A mode twice the size of the given mode
703 (define_mode_attr dmode [(SI "di") (DI "ti")])
704 (define_mode_attr DMODE [(SI "DI") (DI "TI")])
705
706 ;; Suffix for reload patterns
707 (define_mode_attr ptrsize [(SI "32bit")
708 (DI "64bit")])
709
710 (define_mode_attr tptrsize [(SI "TARGET_32BIT")
711 (DI "TARGET_64BIT")])
712
713 (define_mode_attr mptrsize [(SI "si")
714 (DI "di")])
715
716 (define_mode_attr ptrload [(SI "lwz")
717 (DI "ld")])
718
719 (define_mode_attr ptrm [(SI "m")
720 (DI "Y")])
721
722 (define_mode_attr rreg [(SF "f")
723 (DF "wa")
724 (TF "f")
725 (TD "f")
726 (V4SF "wa")
727 (V2DF "wa")])
728
729 (define_mode_attr rreg2 [(SF "f")
730 (DF "d")])
731
732 (define_mode_attr SI_CONVERT_FP [(SF "TARGET_FCFIDS")
733 (DF "TARGET_FCFID")])
734
735 ;; Mode iterator for logical operations on 128-bit types
736 (define_mode_iterator BOOL_128 [TI
737 PTI
738 (V16QI "TARGET_ALTIVEC")
739 (V8HI "TARGET_ALTIVEC")
740 (V4SI "TARGET_ALTIVEC")
741 (V4SF "TARGET_ALTIVEC")
742 (V2DI "TARGET_ALTIVEC")
743 (V2DF "TARGET_ALTIVEC")
744 (V1TI "TARGET_ALTIVEC")])
745
746 ;; For the GPRs we use 3 constraints for register outputs, two that are the
747 ;; same as the output register, and a third where the output register is an
748 ;; early clobber, so we don't have to deal with register overlaps. For the
749 ;; vector types, we prefer to use the vector registers. For TI mode, allow
750 ;; either.
751
752 ;; Mode attribute for boolean operation register constraints for output
753 (define_mode_attr BOOL_REGS_OUTPUT [(TI "&r,r,r,wa,v")
754 (PTI "&r,r,r")
755 (V16QI "wa,v,&?r,?r,?r")
756 (V8HI "wa,v,&?r,?r,?r")
757 (V4SI "wa,v,&?r,?r,?r")
758 (V4SF "wa,v,&?r,?r,?r")
759 (V2DI "wa,v,&?r,?r,?r")
760 (V2DF "wa,v,&?r,?r,?r")
761 (V1TI "wa,v,&?r,?r,?r")])
762
763 ;; Mode attribute for boolean operation register constraints for operand1
764 (define_mode_attr BOOL_REGS_OP1 [(TI "r,0,r,wa,v")
765 (PTI "r,0,r")
766 (V16QI "wa,v,r,0,r")
767 (V8HI "wa,v,r,0,r")
768 (V4SI "wa,v,r,0,r")
769 (V4SF "wa,v,r,0,r")
770 (V2DI "wa,v,r,0,r")
771 (V2DF "wa,v,r,0,r")
772 (V1TI "wa,v,r,0,r")])
773
774 ;; Mode attribute for boolean operation register constraints for operand2
775 (define_mode_attr BOOL_REGS_OP2 [(TI "r,r,0,wa,v")
776 (PTI "r,r,0")
777 (V16QI "wa,v,r,r,0")
778 (V8HI "wa,v,r,r,0")
779 (V4SI "wa,v,r,r,0")
780 (V4SF "wa,v,r,r,0")
781 (V2DI "wa,v,r,r,0")
782 (V2DF "wa,v,r,r,0")
783 (V1TI "wa,v,r,r,0")])
784
785 ;; Mode attribute for boolean operation register constraints for operand1
786 ;; for one_cmpl. To simplify things, we repeat the constraint where 0
787 ;; is used for operand1 or operand2
788 (define_mode_attr BOOL_REGS_UNARY [(TI "r,0,0,wa,v")
789 (PTI "r,0,0")
790 (V16QI "wa,v,r,0,0")
791 (V8HI "wa,v,r,0,0")
792 (V4SI "wa,v,r,0,0")
793 (V4SF "wa,v,r,0,0")
794 (V2DI "wa,v,r,0,0")
795 (V2DF "wa,v,r,0,0")
796 (V1TI "wa,v,r,0,0")])
797
798 ;; Reload iterator for creating the function to allocate a base register to
799 ;; supplement addressing modes.
800 (define_mode_iterator RELOAD [V16QI V8HI V4SI V2DI V4SF V2DF V1TI
801 SF SD SI DF DD DI TI PTI KF IF TF
802 OO XO])
803
804 ;; Iterate over smin, smax
805 (define_code_iterator fp_minmax [smin smax])
806
807 (define_code_attr minmax [(smin "min")
808 (smax "max")])
809
810 (define_code_attr SMINMAX [(smin "SMIN")
811 (smax "SMAX")])
812
813 ;; Iterator to optimize the following cases:
814 ;; D-form load to FPR register & move to Altivec register
815 ;; Move Altivec register to FPR register and store
816 (define_mode_iterator ALTIVEC_DFORM [DF
817 (SF "TARGET_P8_VECTOR")
818 (DI "TARGET_POWERPC64")])
819
820 (include "darwin.md")
821 \f
822 ;; Start with fixed-point load and store insns. Here we put only the more
823 ;; complex forms. Basic data transfer is done later.
824
825 (define_insn "zero_extendqi<mode>2"
826 [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r,wa,^v")
827 (zero_extend:EXTQI (match_operand:QI 1 "reg_or_mem_operand" "m,r,?Z,v")))]
828 ""
829 "@
830 lbz%U1%X1 %0,%1
831 rlwinm %0,%1,0,0xff
832 lxsibzx %x0,%y1
833 vextractub %0,%1,7"
834 [(set_attr "type" "load,shift,fpload,vecperm")
835 (set_attr "isa" "*,*,p9v,p9v")])
836
837 (define_insn_and_split "*zero_extendqi<mode>2_dot"
838 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
839 (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
840 (const_int 0)))
841 (clobber (match_scratch:EXTQI 0 "=r,r"))]
842 ""
843 "@
844 andi. %0,%1,0xff
845 #"
846 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
847 [(set (match_dup 0)
848 (zero_extend:EXTQI (match_dup 1)))
849 (set (match_dup 2)
850 (compare:CC (match_dup 0)
851 (const_int 0)))]
852 ""
853 [(set_attr "type" "logical")
854 (set_attr "dot" "yes")
855 (set_attr "length" "4,8")])
856
857 (define_insn_and_split "*zero_extendqi<mode>2_dot2"
858 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
859 (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
860 (const_int 0)))
861 (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
862 (zero_extend:EXTQI (match_dup 1)))]
863 ""
864 "@
865 andi. %0,%1,0xff
866 #"
867 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
868 [(set (match_dup 0)
869 (zero_extend:EXTQI (match_dup 1)))
870 (set (match_dup 2)
871 (compare:CC (match_dup 0)
872 (const_int 0)))]
873 ""
874 [(set_attr "type" "logical")
875 (set_attr "dot" "yes")
876 (set_attr "length" "4,8")])
877
878
879 (define_insn "zero_extendhi<mode>2"
880 [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r,wa,^v")
881 (zero_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r,?Z,v")))]
882 ""
883 "@
884 lhz%U1%X1 %0,%1
885 rlwinm %0,%1,0,0xffff
886 lxsihzx %x0,%y1
887 vextractuh %0,%1,6"
888 [(set_attr "type" "load,shift,fpload,vecperm")
889 (set_attr "isa" "*,*,p9v,p9v")])
890
891 (define_insn_and_split "*zero_extendhi<mode>2_dot"
892 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
893 (compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
894 (const_int 0)))
895 (clobber (match_scratch:EXTHI 0 "=r,r"))]
896 ""
897 "@
898 andi. %0,%1,0xffff
899 #"
900 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
901 [(set (match_dup 0)
902 (zero_extend:EXTHI (match_dup 1)))
903 (set (match_dup 2)
904 (compare:CC (match_dup 0)
905 (const_int 0)))]
906 ""
907 [(set_attr "type" "logical")
908 (set_attr "dot" "yes")
909 (set_attr "length" "4,8")])
910
911 (define_insn_and_split "*zero_extendhi<mode>2_dot2"
912 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
913 (compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
914 (const_int 0)))
915 (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
916 (zero_extend:EXTHI (match_dup 1)))]
917 ""
918 "@
919 andi. %0,%1,0xffff
920 #"
921 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
922 [(set (match_dup 0)
923 (zero_extend:EXTHI (match_dup 1)))
924 (set (match_dup 2)
925 (compare:CC (match_dup 0)
926 (const_int 0)))]
927 ""
928 [(set_attr "type" "logical")
929 (set_attr "dot" "yes")
930 (set_attr "length" "4,8")])
931
932
933 (define_insn "zero_extendsi<mode>2"
934 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r,d,wa,wa,r,wa")
935 (zero_extend:EXTSI (match_operand:SI 1 "reg_or_mem_operand" "m,r,?Z,?Z,r,wa,wa")))]
936 ""
937 "@
938 lwz%U1%X1 %0,%1
939 rldicl %0,%1,0,32
940 lfiwzx %0,%y1
941 lxsiwzx %x0,%y1
942 mtvsrwz %x0,%1
943 mfvsrwz %0,%x1
944 xxextractuw %x0,%x1,4"
945 [(set_attr "type" "load,shift,fpload,fpload,mtvsr,mfvsr,vecexts")
946 (set_attr "isa" "*,*,p7,p8v,p8v,p8v,p9v")])
947
948 (define_insn_and_split "*zero_extendsi<mode>2_dot"
949 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
950 (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
951 (const_int 0)))
952 (clobber (match_scratch:EXTSI 0 "=r,r"))]
953 ""
954 "@
955 rldicl. %0,%1,0,32
956 #"
957 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
958 [(set (match_dup 0)
959 (zero_extend:DI (match_dup 1)))
960 (set (match_dup 2)
961 (compare:CC (match_dup 0)
962 (const_int 0)))]
963 ""
964 [(set_attr "type" "shift")
965 (set_attr "dot" "yes")
966 (set_attr "length" "4,8")])
967
968 (define_insn_and_split "*zero_extendsi<mode>2_dot2"
969 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
970 (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
971 (const_int 0)))
972 (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
973 (zero_extend:EXTSI (match_dup 1)))]
974 ""
975 "@
976 rldicl. %0,%1,0,32
977 #"
978 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
979 [(set (match_dup 0)
980 (zero_extend:EXTSI (match_dup 1)))
981 (set (match_dup 2)
982 (compare:CC (match_dup 0)
983 (const_int 0)))]
984 ""
985 [(set_attr "type" "shift")
986 (set_attr "dot" "yes")
987 (set_attr "length" "4,8")])
988
989
990 (define_insn "extendqi<mode>2"
991 [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,?*v")
992 (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,?*v")))]
993 ""
994 "@
995 extsb %0,%1
996 vextsb2d %0,%1"
997 [(set_attr "type" "exts,vecperm")
998 (set_attr "isa" "*,p9v")])
999
1000 (define_insn_and_split "*extendqi<mode>2_dot"
1001 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1002 (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
1003 (const_int 0)))
1004 (clobber (match_scratch:EXTQI 0 "=r,r"))]
1005 ""
1006 "@
1007 extsb. %0,%1
1008 #"
1009 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1010 [(set (match_dup 0)
1011 (sign_extend:EXTQI (match_dup 1)))
1012 (set (match_dup 2)
1013 (compare:CC (match_dup 0)
1014 (const_int 0)))]
1015 ""
1016 [(set_attr "type" "exts")
1017 (set_attr "dot" "yes")
1018 (set_attr "length" "4,8")])
1019
1020 (define_insn_and_split "*extendqi<mode>2_dot2"
1021 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1022 (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
1023 (const_int 0)))
1024 (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
1025 (sign_extend:EXTQI (match_dup 1)))]
1026 ""
1027 "@
1028 extsb. %0,%1
1029 #"
1030 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1031 [(set (match_dup 0)
1032 (sign_extend:EXTQI (match_dup 1)))
1033 (set (match_dup 2)
1034 (compare:CC (match_dup 0)
1035 (const_int 0)))]
1036 ""
1037 [(set_attr "type" "exts")
1038 (set_attr "dot" "yes")
1039 (set_attr "length" "4,8")])
1040
1041
1042 (define_expand "extendhi<mode>2"
1043 [(set (match_operand:EXTHI 0 "gpc_reg_operand")
1044 (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand")))]
1045 ""
1046 "")
1047
1048 (define_insn "*extendhi<mode>2"
1049 [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r,?*v,?*v")
1050 (sign_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r,Z,v")))]
1051 ""
1052 "@
1053 lha%U1%X1 %0,%1
1054 extsh %0,%1
1055 #
1056 vextsh2d %0,%1"
1057 [(set_attr "type" "load,exts,fpload,vecperm")
1058 (set_attr "sign_extend" "yes")
1059 (set_attr "length" "*,*,8,*")
1060 (set_attr "isa" "*,*,p9v,p9v")])
1061
1062 (define_split
1063 [(set (match_operand:EXTHI 0 "altivec_register_operand")
1064 (sign_extend:EXTHI
1065 (match_operand:HI 1 "indexed_or_indirect_operand")))]
1066 "TARGET_P9_VECTOR && reload_completed"
1067 [(set (match_dup 2)
1068 (match_dup 1))
1069 (set (match_dup 0)
1070 (sign_extend:EXTHI (match_dup 2)))]
1071 {
1072 operands[2] = gen_rtx_REG (HImode, REGNO (operands[0]));
1073 })
1074
1075 (define_insn_and_split "*extendhi<mode>2_dot"
1076 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1077 (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
1078 (const_int 0)))
1079 (clobber (match_scratch:EXTHI 0 "=r,r"))]
1080 ""
1081 "@
1082 extsh. %0,%1
1083 #"
1084 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1085 [(set (match_dup 0)
1086 (sign_extend:EXTHI (match_dup 1)))
1087 (set (match_dup 2)
1088 (compare:CC (match_dup 0)
1089 (const_int 0)))]
1090 ""
1091 [(set_attr "type" "exts")
1092 (set_attr "dot" "yes")
1093 (set_attr "length" "4,8")])
1094
1095 (define_insn_and_split "*extendhi<mode>2_dot2"
1096 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1097 (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
1098 (const_int 0)))
1099 (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
1100 (sign_extend:EXTHI (match_dup 1)))]
1101 ""
1102 "@
1103 extsh. %0,%1
1104 #"
1105 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1106 [(set (match_dup 0)
1107 (sign_extend:EXTHI (match_dup 1)))
1108 (set (match_dup 2)
1109 (compare:CC (match_dup 0)
1110 (const_int 0)))]
1111 ""
1112 [(set_attr "type" "exts")
1113 (set_attr "dot" "yes")
1114 (set_attr "length" "4,8")])
1115
1116
1117 (define_insn "extendsi<mode>2"
1118 [(set (match_operand:EXTSI 0 "gpc_reg_operand"
1119 "=r, r, d, wa, wa, v, v, wr")
1120 (sign_extend:EXTSI (match_operand:SI 1 "lwa_operand"
1121 "YZ, r, Z, Z, r, v, v, ?wa")))]
1122 ""
1123 "@
1124 lwa%U1%X1 %0,%1
1125 extsw %0,%1
1126 lfiwax %0,%y1
1127 lxsiwax %x0,%y1
1128 mtvsrwa %x0,%1
1129 vextsw2d %0,%1
1130 #
1131 #"
1132 [(set_attr "type" "load,exts,fpload,fpload,mtvsr,vecexts,vecperm,mfvsr")
1133 (set_attr "sign_extend" "yes")
1134 (set_attr "length" "*,*,*,*,*,*,8,8")
1135 (set_attr "isa" "*,*,p6,p8v,p8v,p9v,p8v,p8v")])
1136
1137 (define_split
1138 [(set (match_operand:EXTSI 0 "int_reg_operand")
1139 (sign_extend:EXTSI (match_operand:SI 1 "vsx_register_operand")))]
1140 "TARGET_DIRECT_MOVE_64BIT && reload_completed"
1141 [(set (match_dup 2)
1142 (match_dup 1))
1143 (set (match_dup 0)
1144 (sign_extend:DI (match_dup 2)))]
1145 {
1146 operands[2] = gen_rtx_REG (SImode, reg_or_subregno (operands[0]));
1147 })
1148
1149 (define_split
1150 [(set (match_operand:DI 0 "altivec_register_operand")
1151 (sign_extend:DI (match_operand:SI 1 "altivec_register_operand")))]
1152 "TARGET_P8_VECTOR && !TARGET_P9_VECTOR && reload_completed"
1153 [(const_int 0)]
1154 {
1155 rtx dest = operands[0];
1156 rtx src = operands[1];
1157 int dest_regno = REGNO (dest);
1158 int src_regno = REGNO (src);
1159 rtx dest_v2di = gen_rtx_REG (V2DImode, dest_regno);
1160 rtx src_v4si = gen_rtx_REG (V4SImode, src_regno);
1161
1162 if (BYTES_BIG_ENDIAN)
1163 {
1164 emit_insn (gen_altivec_vupkhsw (dest_v2di, src_v4si));
1165 emit_insn (gen_vsx_xxspltd_v2di (dest_v2di, dest_v2di, const1_rtx));
1166 }
1167 else
1168 {
1169 emit_insn (gen_altivec_vupklsw (dest_v2di, src_v4si));
1170 emit_insn (gen_vsx_xxspltd_v2di (dest_v2di, dest_v2di, const0_rtx));
1171 }
1172 DONE;
1173 })
1174
1175 (define_insn_and_split "*extendsi<mode>2_dot"
1176 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1177 (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
1178 (const_int 0)))
1179 (clobber (match_scratch:EXTSI 0 "=r,r"))]
1180 ""
1181 "@
1182 extsw. %0,%1
1183 #"
1184 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1185 [(set (match_dup 0)
1186 (sign_extend:EXTSI (match_dup 1)))
1187 (set (match_dup 2)
1188 (compare:CC (match_dup 0)
1189 (const_int 0)))]
1190 ""
1191 [(set_attr "type" "exts")
1192 (set_attr "dot" "yes")
1193 (set_attr "length" "4,8")])
1194
1195 (define_insn_and_split "*extendsi<mode>2_dot2"
1196 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1197 (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
1198 (const_int 0)))
1199 (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
1200 (sign_extend:EXTSI (match_dup 1)))]
1201 ""
1202 "@
1203 extsw. %0,%1
1204 #"
1205 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1206 [(set (match_dup 0)
1207 (sign_extend:EXTSI (match_dup 1)))
1208 (set (match_dup 2)
1209 (compare:CC (match_dup 0)
1210 (const_int 0)))]
1211 ""
1212 [(set_attr "type" "exts")
1213 (set_attr "dot" "yes")
1214 (set_attr "length" "4,8")])
1215 \f
1216 ;; IBM 405, 440, 464 and 476 half-word multiplication operations.
1217
1218 (define_insn "*macchwc"
1219 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1220 (compare:CC (plus:SI (mult:SI (ashiftrt:SI
1221 (match_operand:SI 2 "gpc_reg_operand" "r")
1222 (const_int 16))
1223 (sign_extend:SI
1224 (match_operand:HI 1 "gpc_reg_operand" "r")))
1225 (match_operand:SI 4 "gpc_reg_operand" "0"))
1226 (const_int 0)))
1227 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1228 (plus:SI (mult:SI (ashiftrt:SI
1229 (match_dup 2)
1230 (const_int 16))
1231 (sign_extend:SI
1232 (match_dup 1)))
1233 (match_dup 4)))]
1234 "TARGET_MULHW"
1235 "macchw. %0,%1,%2"
1236 [(set_attr "type" "halfmul")])
1237
1238 (define_insn "*macchw"
1239 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1240 (plus:SI (mult:SI (ashiftrt:SI
1241 (match_operand:SI 2 "gpc_reg_operand" "r")
1242 (const_int 16))
1243 (sign_extend:SI
1244 (match_operand:HI 1 "gpc_reg_operand" "r")))
1245 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1246 "TARGET_MULHW"
1247 "macchw %0,%1,%2"
1248 [(set_attr "type" "halfmul")])
1249
1250 (define_insn "*macchwuc"
1251 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1252 (compare:CC (plus:SI (mult:SI (lshiftrt:SI
1253 (match_operand:SI 2 "gpc_reg_operand" "r")
1254 (const_int 16))
1255 (zero_extend:SI
1256 (match_operand:HI 1 "gpc_reg_operand" "r")))
1257 (match_operand:SI 4 "gpc_reg_operand" "0"))
1258 (const_int 0)))
1259 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1260 (plus:SI (mult:SI (lshiftrt:SI
1261 (match_dup 2)
1262 (const_int 16))
1263 (zero_extend:SI
1264 (match_dup 1)))
1265 (match_dup 4)))]
1266 "TARGET_MULHW"
1267 "macchwu. %0,%1,%2"
1268 [(set_attr "type" "halfmul")])
1269
1270 (define_insn "*macchwu"
1271 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1272 (plus:SI (mult:SI (lshiftrt:SI
1273 (match_operand:SI 2 "gpc_reg_operand" "r")
1274 (const_int 16))
1275 (zero_extend:SI
1276 (match_operand:HI 1 "gpc_reg_operand" "r")))
1277 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1278 "TARGET_MULHW"
1279 "macchwu %0,%1,%2"
1280 [(set_attr "type" "halfmul")])
1281
1282 (define_insn "*machhwc"
1283 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1284 (compare:CC (plus:SI (mult:SI (ashiftrt:SI
1285 (match_operand:SI 1 "gpc_reg_operand" "%r")
1286 (const_int 16))
1287 (ashiftrt:SI
1288 (match_operand:SI 2 "gpc_reg_operand" "r")
1289 (const_int 16)))
1290 (match_operand:SI 4 "gpc_reg_operand" "0"))
1291 (const_int 0)))
1292 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1293 (plus:SI (mult:SI (ashiftrt:SI
1294 (match_dup 1)
1295 (const_int 16))
1296 (ashiftrt:SI
1297 (match_dup 2)
1298 (const_int 16)))
1299 (match_dup 4)))]
1300 "TARGET_MULHW"
1301 "machhw. %0,%1,%2"
1302 [(set_attr "type" "halfmul")])
1303
1304 (define_insn "*machhw"
1305 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1306 (plus:SI (mult:SI (ashiftrt:SI
1307 (match_operand:SI 1 "gpc_reg_operand" "%r")
1308 (const_int 16))
1309 (ashiftrt:SI
1310 (match_operand:SI 2 "gpc_reg_operand" "r")
1311 (const_int 16)))
1312 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1313 "TARGET_MULHW"
1314 "machhw %0,%1,%2"
1315 [(set_attr "type" "halfmul")])
1316
1317 (define_insn "*machhwuc"
1318 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1319 (compare:CC (plus:SI (mult:SI (lshiftrt:SI
1320 (match_operand:SI 1 "gpc_reg_operand" "%r")
1321 (const_int 16))
1322 (lshiftrt:SI
1323 (match_operand:SI 2 "gpc_reg_operand" "r")
1324 (const_int 16)))
1325 (match_operand:SI 4 "gpc_reg_operand" "0"))
1326 (const_int 0)))
1327 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1328 (plus:SI (mult:SI (lshiftrt:SI
1329 (match_dup 1)
1330 (const_int 16))
1331 (lshiftrt:SI
1332 (match_dup 2)
1333 (const_int 16)))
1334 (match_dup 4)))]
1335 "TARGET_MULHW"
1336 "machhwu. %0,%1,%2"
1337 [(set_attr "type" "halfmul")])
1338
1339 (define_insn "*machhwu"
1340 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1341 (plus:SI (mult:SI (lshiftrt:SI
1342 (match_operand:SI 1 "gpc_reg_operand" "%r")
1343 (const_int 16))
1344 (lshiftrt:SI
1345 (match_operand:SI 2 "gpc_reg_operand" "r")
1346 (const_int 16)))
1347 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1348 "TARGET_MULHW"
1349 "machhwu %0,%1,%2"
1350 [(set_attr "type" "halfmul")])
1351
1352 (define_insn "*maclhwc"
1353 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1354 (compare:CC (plus:SI (mult:SI (sign_extend:SI
1355 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1356 (sign_extend:SI
1357 (match_operand:HI 2 "gpc_reg_operand" "r")))
1358 (match_operand:SI 4 "gpc_reg_operand" "0"))
1359 (const_int 0)))
1360 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1361 (plus:SI (mult:SI (sign_extend:SI
1362 (match_dup 1))
1363 (sign_extend:SI
1364 (match_dup 2)))
1365 (match_dup 4)))]
1366 "TARGET_MULHW"
1367 "maclhw. %0,%1,%2"
1368 [(set_attr "type" "halfmul")])
1369
1370 (define_insn "*maclhw"
1371 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1372 (plus:SI (mult:SI (sign_extend:SI
1373 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1374 (sign_extend:SI
1375 (match_operand:HI 2 "gpc_reg_operand" "r")))
1376 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1377 "TARGET_MULHW"
1378 "maclhw %0,%1,%2"
1379 [(set_attr "type" "halfmul")])
1380
1381 (define_insn "*maclhwuc"
1382 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1383 (compare:CC (plus:SI (mult:SI (zero_extend:SI
1384 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1385 (zero_extend:SI
1386 (match_operand:HI 2 "gpc_reg_operand" "r")))
1387 (match_operand:SI 4 "gpc_reg_operand" "0"))
1388 (const_int 0)))
1389 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1390 (plus:SI (mult:SI (zero_extend:SI
1391 (match_dup 1))
1392 (zero_extend:SI
1393 (match_dup 2)))
1394 (match_dup 4)))]
1395 "TARGET_MULHW"
1396 "maclhwu. %0,%1,%2"
1397 [(set_attr "type" "halfmul")])
1398
1399 (define_insn "*maclhwu"
1400 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1401 (plus:SI (mult:SI (zero_extend:SI
1402 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1403 (zero_extend:SI
1404 (match_operand:HI 2 "gpc_reg_operand" "r")))
1405 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1406 "TARGET_MULHW"
1407 "maclhwu %0,%1,%2"
1408 [(set_attr "type" "halfmul")])
1409
1410 (define_insn "*nmacchwc"
1411 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1412 (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1413 (mult:SI (ashiftrt:SI
1414 (match_operand:SI 2 "gpc_reg_operand" "r")
1415 (const_int 16))
1416 (sign_extend:SI
1417 (match_operand:HI 1 "gpc_reg_operand" "r"))))
1418 (const_int 0)))
1419 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1420 (minus:SI (match_dup 4)
1421 (mult:SI (ashiftrt:SI
1422 (match_dup 2)
1423 (const_int 16))
1424 (sign_extend:SI
1425 (match_dup 1)))))]
1426 "TARGET_MULHW"
1427 "nmacchw. %0,%1,%2"
1428 [(set_attr "type" "halfmul")])
1429
1430 (define_insn "*nmacchw"
1431 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1432 (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1433 (mult:SI (ashiftrt:SI
1434 (match_operand:SI 2 "gpc_reg_operand" "r")
1435 (const_int 16))
1436 (sign_extend:SI
1437 (match_operand:HI 1 "gpc_reg_operand" "r")))))]
1438 "TARGET_MULHW"
1439 "nmacchw %0,%1,%2"
1440 [(set_attr "type" "halfmul")])
1441
1442 (define_insn "*nmachhwc"
1443 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1444 (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1445 (mult:SI (ashiftrt:SI
1446 (match_operand:SI 1 "gpc_reg_operand" "%r")
1447 (const_int 16))
1448 (ashiftrt:SI
1449 (match_operand:SI 2 "gpc_reg_operand" "r")
1450 (const_int 16))))
1451 (const_int 0)))
1452 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1453 (minus:SI (match_dup 4)
1454 (mult:SI (ashiftrt:SI
1455 (match_dup 1)
1456 (const_int 16))
1457 (ashiftrt:SI
1458 (match_dup 2)
1459 (const_int 16)))))]
1460 "TARGET_MULHW"
1461 "nmachhw. %0,%1,%2"
1462 [(set_attr "type" "halfmul")])
1463
1464 (define_insn "*nmachhw"
1465 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1466 (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1467 (mult:SI (ashiftrt:SI
1468 (match_operand:SI 1 "gpc_reg_operand" "%r")
1469 (const_int 16))
1470 (ashiftrt:SI
1471 (match_operand:SI 2 "gpc_reg_operand" "r")
1472 (const_int 16)))))]
1473 "TARGET_MULHW"
1474 "nmachhw %0,%1,%2"
1475 [(set_attr "type" "halfmul")])
1476
1477 (define_insn "*nmaclhwc"
1478 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1479 (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1480 (mult:SI (sign_extend:SI
1481 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1482 (sign_extend:SI
1483 (match_operand:HI 2 "gpc_reg_operand" "r"))))
1484 (const_int 0)))
1485 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1486 (minus:SI (match_dup 4)
1487 (mult:SI (sign_extend:SI
1488 (match_dup 1))
1489 (sign_extend:SI
1490 (match_dup 2)))))]
1491 "TARGET_MULHW"
1492 "nmaclhw. %0,%1,%2"
1493 [(set_attr "type" "halfmul")])
1494
1495 (define_insn "*nmaclhw"
1496 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1497 (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1498 (mult:SI (sign_extend:SI
1499 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1500 (sign_extend:SI
1501 (match_operand:HI 2 "gpc_reg_operand" "r")))))]
1502 "TARGET_MULHW"
1503 "nmaclhw %0,%1,%2"
1504 [(set_attr "type" "halfmul")])
1505
1506 (define_insn "*mulchwc"
1507 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1508 (compare:CC (mult:SI (ashiftrt:SI
1509 (match_operand:SI 2 "gpc_reg_operand" "r")
1510 (const_int 16))
1511 (sign_extend:SI
1512 (match_operand:HI 1 "gpc_reg_operand" "r")))
1513 (const_int 0)))
1514 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1515 (mult:SI (ashiftrt:SI
1516 (match_dup 2)
1517 (const_int 16))
1518 (sign_extend:SI
1519 (match_dup 1))))]
1520 "TARGET_MULHW"
1521 "mulchw. %0,%1,%2"
1522 [(set_attr "type" "halfmul")])
1523
1524 (define_insn "*mulchw"
1525 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1526 (mult:SI (ashiftrt:SI
1527 (match_operand:SI 2 "gpc_reg_operand" "r")
1528 (const_int 16))
1529 (sign_extend:SI
1530 (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1531 "TARGET_MULHW"
1532 "mulchw %0,%1,%2"
1533 [(set_attr "type" "halfmul")])
1534
1535 (define_insn "*mulchwuc"
1536 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1537 (compare:CC (mult:SI (lshiftrt:SI
1538 (match_operand:SI 2 "gpc_reg_operand" "r")
1539 (const_int 16))
1540 (zero_extend:SI
1541 (match_operand:HI 1 "gpc_reg_operand" "r")))
1542 (const_int 0)))
1543 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1544 (mult:SI (lshiftrt:SI
1545 (match_dup 2)
1546 (const_int 16))
1547 (zero_extend:SI
1548 (match_dup 1))))]
1549 "TARGET_MULHW"
1550 "mulchwu. %0,%1,%2"
1551 [(set_attr "type" "halfmul")])
1552
1553 (define_insn "*mulchwu"
1554 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1555 (mult:SI (lshiftrt:SI
1556 (match_operand:SI 2 "gpc_reg_operand" "r")
1557 (const_int 16))
1558 (zero_extend:SI
1559 (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1560 "TARGET_MULHW"
1561 "mulchwu %0,%1,%2"
1562 [(set_attr "type" "halfmul")])
1563
1564 (define_insn "*mulhhwc"
1565 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1566 (compare:CC (mult:SI (ashiftrt:SI
1567 (match_operand:SI 1 "gpc_reg_operand" "%r")
1568 (const_int 16))
1569 (ashiftrt:SI
1570 (match_operand:SI 2 "gpc_reg_operand" "r")
1571 (const_int 16)))
1572 (const_int 0)))
1573 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1574 (mult:SI (ashiftrt:SI
1575 (match_dup 1)
1576 (const_int 16))
1577 (ashiftrt:SI
1578 (match_dup 2)
1579 (const_int 16))))]
1580 "TARGET_MULHW"
1581 "mulhhw. %0,%1,%2"
1582 [(set_attr "type" "halfmul")])
1583
1584 (define_insn "*mulhhw"
1585 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1586 (mult:SI (ashiftrt:SI
1587 (match_operand:SI 1 "gpc_reg_operand" "%r")
1588 (const_int 16))
1589 (ashiftrt:SI
1590 (match_operand:SI 2 "gpc_reg_operand" "r")
1591 (const_int 16))))]
1592 "TARGET_MULHW"
1593 "mulhhw %0,%1,%2"
1594 [(set_attr "type" "halfmul")])
1595
1596 (define_insn "*mulhhwuc"
1597 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1598 (compare:CC (mult:SI (lshiftrt:SI
1599 (match_operand:SI 1 "gpc_reg_operand" "%r")
1600 (const_int 16))
1601 (lshiftrt:SI
1602 (match_operand:SI 2 "gpc_reg_operand" "r")
1603 (const_int 16)))
1604 (const_int 0)))
1605 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1606 (mult:SI (lshiftrt:SI
1607 (match_dup 1)
1608 (const_int 16))
1609 (lshiftrt:SI
1610 (match_dup 2)
1611 (const_int 16))))]
1612 "TARGET_MULHW"
1613 "mulhhwu. %0,%1,%2"
1614 [(set_attr "type" "halfmul")])
1615
1616 (define_insn "*mulhhwu"
1617 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1618 (mult:SI (lshiftrt:SI
1619 (match_operand:SI 1 "gpc_reg_operand" "%r")
1620 (const_int 16))
1621 (lshiftrt:SI
1622 (match_operand:SI 2 "gpc_reg_operand" "r")
1623 (const_int 16))))]
1624 "TARGET_MULHW"
1625 "mulhhwu %0,%1,%2"
1626 [(set_attr "type" "halfmul")])
1627
1628 (define_insn "*mullhwc"
1629 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1630 (compare:CC (mult:SI (sign_extend:SI
1631 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1632 (sign_extend:SI
1633 (match_operand:HI 2 "gpc_reg_operand" "r")))
1634 (const_int 0)))
1635 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1636 (mult:SI (sign_extend:SI
1637 (match_dup 1))
1638 (sign_extend:SI
1639 (match_dup 2))))]
1640 "TARGET_MULHW"
1641 "mullhw. %0,%1,%2"
1642 [(set_attr "type" "halfmul")])
1643
1644 (define_insn "*mullhw"
1645 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1646 (mult:SI (sign_extend:SI
1647 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1648 (sign_extend:SI
1649 (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1650 "TARGET_MULHW"
1651 "mullhw %0,%1,%2"
1652 [(set_attr "type" "halfmul")])
1653
1654 (define_insn "*mullhwuc"
1655 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1656 (compare:CC (mult:SI (zero_extend:SI
1657 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1658 (zero_extend:SI
1659 (match_operand:HI 2 "gpc_reg_operand" "r")))
1660 (const_int 0)))
1661 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1662 (mult:SI (zero_extend:SI
1663 (match_dup 1))
1664 (zero_extend:SI
1665 (match_dup 2))))]
1666 "TARGET_MULHW"
1667 "mullhwu. %0,%1,%2"
1668 [(set_attr "type" "halfmul")])
1669
1670 (define_insn "*mullhwu"
1671 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1672 (mult:SI (zero_extend:SI
1673 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1674 (zero_extend:SI
1675 (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1676 "TARGET_MULHW"
1677 "mullhwu %0,%1,%2"
1678 [(set_attr "type" "halfmul")])
1679 \f
1680 ;; IBM 405, 440, 464 and 476 string-search dlmzb instruction support.
1681 (define_insn "dlmzb"
1682 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1683 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
1684 (match_operand:SI 2 "gpc_reg_operand" "r")]
1685 UNSPEC_DLMZB_CR))
1686 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1687 (unspec:SI [(match_dup 1)
1688 (match_dup 2)]
1689 UNSPEC_DLMZB))]
1690 "TARGET_DLMZB"
1691 "dlmzb. %0,%1,%2")
1692
1693 (define_expand "strlensi"
1694 [(set (match_operand:SI 0 "gpc_reg_operand")
1695 (unspec:SI [(match_operand:BLK 1 "general_operand")
1696 (match_operand:QI 2 "const_int_operand")
1697 (match_operand 3 "const_int_operand")]
1698 UNSPEC_DLMZB_STRLEN))
1699 (clobber (match_scratch:CC 4))]
1700 "TARGET_DLMZB && WORDS_BIG_ENDIAN && !optimize_size"
1701 {
1702 rtx result = operands[0];
1703 rtx src = operands[1];
1704 rtx search_char = operands[2];
1705 rtx align = operands[3];
1706 rtx addr, scratch_string, word1, word2, scratch_dlmzb;
1707 rtx loop_label, end_label, mem, cr0, cond;
1708 if (search_char != const0_rtx
1709 || !CONST_INT_P (align)
1710 || INTVAL (align) < 8)
1711 FAIL;
1712 word1 = gen_reg_rtx (SImode);
1713 word2 = gen_reg_rtx (SImode);
1714 scratch_dlmzb = gen_reg_rtx (SImode);
1715 scratch_string = gen_reg_rtx (Pmode);
1716 loop_label = gen_label_rtx ();
1717 end_label = gen_label_rtx ();
1718 addr = force_reg (Pmode, XEXP (src, 0));
1719 emit_move_insn (scratch_string, addr);
1720 emit_label (loop_label);
1721 mem = change_address (src, SImode, scratch_string);
1722 emit_move_insn (word1, mem);
1723 emit_move_insn (word2, adjust_address (mem, SImode, 4));
1724 cr0 = gen_rtx_REG (CCmode, CR0_REGNO);
1725 emit_insn (gen_dlmzb (scratch_dlmzb, word1, word2, cr0));
1726 cond = gen_rtx_NE (VOIDmode, cr0, const0_rtx);
1727 emit_jump_insn (gen_rtx_SET (pc_rtx,
1728 gen_rtx_IF_THEN_ELSE (VOIDmode,
1729 cond,
1730 gen_rtx_LABEL_REF
1731 (VOIDmode,
1732 end_label),
1733 pc_rtx)));
1734 emit_insn (gen_addsi3 (scratch_string, scratch_string, GEN_INT (8)));
1735 emit_jump_insn (gen_rtx_SET (pc_rtx,
1736 gen_rtx_LABEL_REF (VOIDmode, loop_label)));
1737 emit_barrier ();
1738 emit_label (end_label);
1739 emit_insn (gen_addsi3 (scratch_string, scratch_string, scratch_dlmzb));
1740 emit_insn (gen_subsi3 (result, scratch_string, addr));
1741 emit_insn (gen_addsi3 (result, result, constm1_rtx));
1742 DONE;
1743 })
1744 \f
1745 ;; Fixed-point arithmetic insns.
1746
1747 (define_expand "add<mode>3"
1748 [(set (match_operand:SDI 0 "gpc_reg_operand")
1749 (plus:SDI (match_operand:SDI 1 "gpc_reg_operand")
1750 (match_operand:SDI 2 "reg_or_add_cint_operand")))]
1751 ""
1752 {
1753 if (<MODE>mode == DImode && !TARGET_POWERPC64)
1754 {
1755 rtx lo0 = gen_lowpart (SImode, operands[0]);
1756 rtx lo1 = gen_lowpart (SImode, operands[1]);
1757 rtx lo2 = gen_lowpart (SImode, operands[2]);
1758 rtx hi0 = gen_highpart (SImode, operands[0]);
1759 rtx hi1 = gen_highpart (SImode, operands[1]);
1760 rtx hi2 = gen_highpart_mode (SImode, DImode, operands[2]);
1761
1762 if (!reg_or_short_operand (lo2, SImode))
1763 lo2 = force_reg (SImode, lo2);
1764 if (!adde_operand (hi2, SImode))
1765 hi2 = force_reg (SImode, hi2);
1766
1767 emit_insn (gen_addsi3_carry (lo0, lo1, lo2));
1768 emit_insn (gen_addsi3_carry_in (hi0, hi1, hi2));
1769 DONE;
1770 }
1771
1772 if (CONST_INT_P (operands[2]) && !add_operand (operands[2], <MODE>mode))
1773 {
1774 rtx tmp = ((!can_create_pseudo_p ()
1775 || rtx_equal_p (operands[0], operands[1]))
1776 ? operands[0] : gen_reg_rtx (<MODE>mode));
1777
1778 /* Adding a constant to r0 is not a valid insn, so use a different
1779 strategy in that case. */
1780 if (reg_or_subregno (operands[1]) == 0 || reg_or_subregno (tmp) == 0)
1781 {
1782 if (operands[0] == operands[1])
1783 FAIL;
1784 rs6000_emit_move (operands[0], operands[2], <MODE>mode);
1785 emit_insn (gen_add<mode>3 (operands[0], operands[1], operands[0]));
1786 DONE;
1787 }
1788
1789 HOST_WIDE_INT val = INTVAL (operands[2]);
1790 HOST_WIDE_INT low = sext_hwi (val, 16);
1791 HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1792
1793 if (<MODE>mode == DImode && !satisfies_constraint_L (GEN_INT (rest)))
1794 FAIL;
1795
1796 /* The ordering here is important for the prolog expander.
1797 When space is allocated from the stack, adding 'low' first may
1798 produce a temporary deallocation (which would be bad). */
1799 emit_insn (gen_add<mode>3 (tmp, operands[1], GEN_INT (rest)));
1800 emit_insn (gen_add<mode>3 (operands[0], tmp, GEN_INT (low)));
1801 DONE;
1802 }
1803 })
1804
1805 (define_insn "*add<mode>3"
1806 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r,r,r")
1807 (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b,b,b")
1808 (match_operand:GPR 2 "add_operand" "r,I,L,eI")))]
1809 ""
1810 "@
1811 add %0,%1,%2
1812 addi %0,%1,%2
1813 addis %0,%1,%v2
1814 addi %0,%1,%2"
1815 [(set_attr "type" "add")
1816 (set_attr "isa" "*,*,*,p10")])
1817
1818 (define_insn "*addsi3_high"
1819 [(set (match_operand:SI 0 "gpc_reg_operand" "=b")
1820 (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
1821 (high:SI (match_operand 2 "" ""))))]
1822 "TARGET_MACHO && !TARGET_64BIT"
1823 "addis %0,%1,ha16(%2)"
1824 [(set_attr "type" "add")])
1825
1826 (define_insn_and_split "*add<mode>3_dot"
1827 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1828 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
1829 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
1830 (const_int 0)))
1831 (clobber (match_scratch:GPR 0 "=r,r"))]
1832 "<MODE>mode == Pmode"
1833 "@
1834 add. %0,%1,%2
1835 #"
1836 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1837 [(set (match_dup 0)
1838 (plus:GPR (match_dup 1)
1839 (match_dup 2)))
1840 (set (match_dup 3)
1841 (compare:CC (match_dup 0)
1842 (const_int 0)))]
1843 ""
1844 [(set_attr "type" "add")
1845 (set_attr "dot" "yes")
1846 (set_attr "length" "4,8")])
1847
1848 (define_insn_and_split "*add<mode>3_dot2"
1849 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1850 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
1851 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
1852 (const_int 0)))
1853 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1854 (plus:GPR (match_dup 1)
1855 (match_dup 2)))]
1856 "<MODE>mode == Pmode"
1857 "@
1858 add. %0,%1,%2
1859 #"
1860 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1861 [(set (match_dup 0)
1862 (plus:GPR (match_dup 1)
1863 (match_dup 2)))
1864 (set (match_dup 3)
1865 (compare:CC (match_dup 0)
1866 (const_int 0)))]
1867 ""
1868 [(set_attr "type" "add")
1869 (set_attr "dot" "yes")
1870 (set_attr "length" "4,8")])
1871
1872 (define_insn_and_split "*add<mode>3_imm_dot"
1873 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1874 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b")
1875 (match_operand:GPR 2 "short_cint_operand" "I,I"))
1876 (const_int 0)))
1877 (clobber (match_scratch:GPR 0 "=r,r"))
1878 (clobber (reg:GPR CA_REGNO))]
1879 "<MODE>mode == Pmode"
1880 "@
1881 addic. %0,%1,%2
1882 #"
1883 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1884 [(set (match_dup 0)
1885 (plus:GPR (match_dup 1)
1886 (match_dup 2)))
1887 (set (match_dup 3)
1888 (compare:CC (match_dup 0)
1889 (const_int 0)))]
1890 ""
1891 [(set_attr "type" "add")
1892 (set_attr "dot" "yes")
1893 (set_attr "length" "4,8")])
1894
1895 (define_insn_and_split "*add<mode>3_imm_dot2"
1896 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1897 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b")
1898 (match_operand:GPR 2 "short_cint_operand" "I,I"))
1899 (const_int 0)))
1900 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1901 (plus:GPR (match_dup 1)
1902 (match_dup 2)))
1903 (clobber (reg:GPR CA_REGNO))]
1904 "<MODE>mode == Pmode"
1905 "@
1906 addic. %0,%1,%2
1907 #"
1908 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1909 [(set (match_dup 0)
1910 (plus:GPR (match_dup 1)
1911 (match_dup 2)))
1912 (set (match_dup 3)
1913 (compare:CC (match_dup 0)
1914 (const_int 0)))]
1915 ""
1916 [(set_attr "type" "add")
1917 (set_attr "dot" "yes")
1918 (set_attr "length" "4,8")])
1919
1920 ;; Split an add that we can't do in one insn into two insns, each of which
1921 ;; does one 16-bit part. This is used by combine. Note that the low-order
1922 ;; add should be last in case the result gets used in an address.
1923
1924 (define_split
1925 [(set (match_operand:GPR 0 "gpc_reg_operand")
1926 (plus:GPR (match_operand:GPR 1 "gpc_reg_operand")
1927 (match_operand:GPR 2 "non_add_cint_operand")))]
1928 ""
1929 [(set (match_dup 0) (plus:GPR (match_dup 1) (match_dup 3)))
1930 (set (match_dup 0) (plus:GPR (match_dup 0) (match_dup 4)))]
1931 {
1932 HOST_WIDE_INT val = INTVAL (operands[2]);
1933 HOST_WIDE_INT low = sext_hwi (val, 16);
1934 HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1935
1936 operands[4] = GEN_INT (low);
1937 if (<MODE>mode == SImode || satisfies_constraint_L (GEN_INT (rest)))
1938 operands[3] = GEN_INT (rest);
1939 else if (can_create_pseudo_p ())
1940 {
1941 operands[3] = gen_reg_rtx (DImode);
1942 emit_move_insn (operands[3], operands[2]);
1943 emit_insn (gen_adddi3 (operands[0], operands[1], operands[3]));
1944 DONE;
1945 }
1946 else
1947 FAIL;
1948 })
1949
1950
1951 (define_insn "add<mode>3_carry"
1952 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1953 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1954 (match_operand:P 2 "reg_or_short_operand" "rI")))
1955 (set (reg:P CA_REGNO)
1956 (ltu:P (plus:P (match_dup 1)
1957 (match_dup 2))
1958 (match_dup 1)))]
1959 ""
1960 "add%I2c %0,%1,%2"
1961 [(set_attr "type" "add")])
1962
1963 (define_insn "*add<mode>3_imm_carry_pos"
1964 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1965 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1966 (match_operand:P 2 "short_cint_operand" "n")))
1967 (set (reg:P CA_REGNO)
1968 (geu:P (match_dup 1)
1969 (match_operand:P 3 "const_int_operand" "n")))]
1970 "INTVAL (operands[2]) > 0
1971 && INTVAL (operands[2]) + INTVAL (operands[3]) == 0"
1972 "addic %0,%1,%2"
1973 [(set_attr "type" "add")])
1974
1975 (define_insn "*add<mode>3_imm_carry_0"
1976 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1977 (match_operand:P 1 "gpc_reg_operand" "r"))
1978 (set (reg:P CA_REGNO)
1979 (const_int 0))]
1980 ""
1981 "addic %0,%1,0"
1982 [(set_attr "type" "add")])
1983
1984 (define_insn "*add<mode>3_imm_carry_m1"
1985 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1986 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1987 (const_int -1)))
1988 (set (reg:P CA_REGNO)
1989 (ne:P (match_dup 1)
1990 (const_int 0)))]
1991 ""
1992 "addic %0,%1,-1"
1993 [(set_attr "type" "add")])
1994
1995 (define_insn "*add<mode>3_imm_carry_neg"
1996 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1997 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1998 (match_operand:P 2 "short_cint_operand" "n")))
1999 (set (reg:P CA_REGNO)
2000 (gtu:P (match_dup 1)
2001 (match_operand:P 3 "const_int_operand" "n")))]
2002 "INTVAL (operands[2]) < 0
2003 && INTVAL (operands[2]) + INTVAL (operands[3]) == -1"
2004 "addic %0,%1,%2"
2005 [(set_attr "type" "add")])
2006
2007
2008 (define_expand "add<mode>3_carry_in"
2009 [(parallel [
2010 (set (match_operand:GPR 0 "gpc_reg_operand")
2011 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand")
2012 (match_operand:GPR 2 "adde_operand"))
2013 (reg:GPR CA_REGNO)))
2014 (clobber (reg:GPR CA_REGNO))])]
2015 ""
2016 {
2017 if (operands[2] == const0_rtx)
2018 {
2019 emit_insn (gen_add<mode>3_carry_in_0 (operands[0], operands[1]));
2020 DONE;
2021 }
2022 if (operands[2] == constm1_rtx)
2023 {
2024 emit_insn (gen_add<mode>3_carry_in_m1 (operands[0], operands[1]));
2025 DONE;
2026 }
2027 })
2028
2029 (define_insn "*add<mode>3_carry_in_internal"
2030 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2031 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
2032 (match_operand:GPR 2 "gpc_reg_operand" "r"))
2033 (reg:GPR CA_REGNO)))
2034 (clobber (reg:GPR CA_REGNO))]
2035 ""
2036 "adde %0,%1,%2"
2037 [(set_attr "type" "add")])
2038
2039 (define_insn "*add<mode>3_carry_in_internal2"
2040 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2041 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
2042 (reg:GPR CA_REGNO))
2043 (match_operand:GPR 2 "gpc_reg_operand" "r")))
2044 (clobber (reg:GPR CA_REGNO))]
2045 ""
2046 "adde %0,%1,%2"
2047 [(set_attr "type" "add")])
2048
2049 (define_insn "add<mode>3_carry_in_0"
2050 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2051 (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
2052 (reg:GPR CA_REGNO)))
2053 (clobber (reg:GPR CA_REGNO))]
2054 ""
2055 "addze %0,%1"
2056 [(set_attr "type" "add")])
2057
2058 (define_insn "add<mode>3_carry_in_m1"
2059 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2060 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
2061 (reg:GPR CA_REGNO))
2062 (const_int -1)))
2063 (clobber (reg:GPR CA_REGNO))]
2064 ""
2065 "addme %0,%1"
2066 [(set_attr "type" "add")])
2067
2068
2069 (define_expand "one_cmpl<mode>2"
2070 [(set (match_operand:SDI 0 "gpc_reg_operand")
2071 (not:SDI (match_operand:SDI 1 "gpc_reg_operand")))]
2072 ""
2073 {
2074 if (<MODE>mode == DImode && !TARGET_POWERPC64)
2075 {
2076 rs6000_split_logical (operands, NOT, false, false, false);
2077 DONE;
2078 }
2079 })
2080
2081 (define_insn "*one_cmpl<mode>2"
2082 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2083 (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2084 ""
2085 "not %0,%1")
2086
2087 (define_insn_and_split "*one_cmpl<mode>2_dot"
2088 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2089 (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2090 (const_int 0)))
2091 (clobber (match_scratch:GPR 0 "=r,r"))]
2092 "<MODE>mode == Pmode"
2093 "@
2094 not. %0,%1
2095 #"
2096 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2097 [(set (match_dup 0)
2098 (not:GPR (match_dup 1)))
2099 (set (match_dup 2)
2100 (compare:CC (match_dup 0)
2101 (const_int 0)))]
2102 ""
2103 [(set_attr "type" "logical")
2104 (set_attr "dot" "yes")
2105 (set_attr "length" "4,8")])
2106
2107 (define_insn_and_split "*one_cmpl<mode>2_dot2"
2108 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2109 (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2110 (const_int 0)))
2111 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2112 (not:GPR (match_dup 1)))]
2113 "<MODE>mode == Pmode"
2114 "@
2115 not. %0,%1
2116 #"
2117 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2118 [(set (match_dup 0)
2119 (not:GPR (match_dup 1)))
2120 (set (match_dup 2)
2121 (compare:CC (match_dup 0)
2122 (const_int 0)))]
2123 ""
2124 [(set_attr "type" "logical")
2125 (set_attr "dot" "yes")
2126 (set_attr "length" "4,8")])
2127
2128
2129 (define_expand "sub<mode>3"
2130 [(set (match_operand:SDI 0 "gpc_reg_operand")
2131 (minus:SDI (match_operand:SDI 1 "reg_or_short_operand")
2132 (match_operand:SDI 2 "gpc_reg_operand")))]
2133 ""
2134 {
2135 if (<MODE>mode == DImode && !TARGET_POWERPC64)
2136 {
2137 rtx lo0 = gen_lowpart (SImode, operands[0]);
2138 rtx lo1 = gen_lowpart (SImode, operands[1]);
2139 rtx lo2 = gen_lowpart (SImode, operands[2]);
2140 rtx hi0 = gen_highpart (SImode, operands[0]);
2141 rtx hi1 = gen_highpart_mode (SImode, DImode, operands[1]);
2142 rtx hi2 = gen_highpart (SImode, operands[2]);
2143
2144 if (!reg_or_short_operand (lo1, SImode))
2145 lo1 = force_reg (SImode, lo1);
2146 if (!adde_operand (hi1, SImode))
2147 hi1 = force_reg (SImode, hi1);
2148
2149 emit_insn (gen_subfsi3_carry (lo0, lo2, lo1));
2150 emit_insn (gen_subfsi3_carry_in (hi0, hi2, hi1));
2151 DONE;
2152 }
2153
2154 if (short_cint_operand (operands[1], <MODE>mode))
2155 {
2156 emit_insn (gen_subf<mode>3_imm (operands[0], operands[2], operands[1]));
2157 DONE;
2158 }
2159 })
2160
2161 (define_insn "*subf<mode>3"
2162 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2163 (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r")
2164 (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2165 ""
2166 "subf %0,%1,%2"
2167 [(set_attr "type" "add")])
2168
2169 (define_insn_and_split "*subf<mode>3_dot"
2170 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2171 (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
2172 (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2173 (const_int 0)))
2174 (clobber (match_scratch:GPR 0 "=r,r"))]
2175 "<MODE>mode == Pmode"
2176 "@
2177 subf. %0,%1,%2
2178 #"
2179 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2180 [(set (match_dup 0)
2181 (minus:GPR (match_dup 2)
2182 (match_dup 1)))
2183 (set (match_dup 3)
2184 (compare:CC (match_dup 0)
2185 (const_int 0)))]
2186 ""
2187 [(set_attr "type" "add")
2188 (set_attr "dot" "yes")
2189 (set_attr "length" "4,8")])
2190
2191 (define_insn_and_split "*subf<mode>3_dot2"
2192 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2193 (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
2194 (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2195 (const_int 0)))
2196 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2197 (minus:GPR (match_dup 2)
2198 (match_dup 1)))]
2199 "<MODE>mode == Pmode"
2200 "@
2201 subf. %0,%1,%2
2202 #"
2203 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2204 [(set (match_dup 0)
2205 (minus:GPR (match_dup 2)
2206 (match_dup 1)))
2207 (set (match_dup 3)
2208 (compare:CC (match_dup 0)
2209 (const_int 0)))]
2210 ""
2211 [(set_attr "type" "add")
2212 (set_attr "dot" "yes")
2213 (set_attr "length" "4,8")])
2214
2215 (define_insn "subf<mode>3_imm"
2216 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2217 (minus:GPR (match_operand:GPR 2 "short_cint_operand" "I")
2218 (match_operand:GPR 1 "gpc_reg_operand" "r")))
2219 (clobber (reg:GPR CA_REGNO))]
2220 ""
2221 "subfic %0,%1,%2"
2222 [(set_attr "type" "add")])
2223
2224 (define_insn_and_split "subf<mode>3_carry_dot2"
2225 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2226 (compare:CC (minus:P (match_operand:P 2 "gpc_reg_operand" "r,r")
2227 (match_operand:P 1 "gpc_reg_operand" "r,r"))
2228 (const_int 0)))
2229 (set (match_operand:P 0 "gpc_reg_operand" "=r,r")
2230 (minus:P (match_dup 2)
2231 (match_dup 1)))
2232 (set (reg:P CA_REGNO)
2233 (leu:P (match_dup 1)
2234 (match_dup 2)))]
2235 "<MODE>mode == Pmode"
2236 "@
2237 subfc. %0,%1,%2
2238 #"
2239 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2240 [(parallel [(set (match_dup 0)
2241 (minus:P (match_dup 2)
2242 (match_dup 1)))
2243 (set (reg:P CA_REGNO)
2244 (leu:P (match_dup 1)
2245 (match_dup 2)))])
2246 (set (match_dup 3)
2247 (compare:CC (match_dup 0)
2248 (const_int 0)))]
2249 ""
2250 [(set_attr "type" "add")
2251 (set_attr "dot" "yes")
2252 (set_attr "length" "4,8")])
2253
2254 (define_insn "subf<mode>3_carry"
2255 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2256 (minus:P (match_operand:P 2 "reg_or_short_operand" "rI")
2257 (match_operand:P 1 "gpc_reg_operand" "r")))
2258 (set (reg:P CA_REGNO)
2259 (leu:P (match_dup 1)
2260 (match_dup 2)))]
2261 ""
2262 "subf%I2c %0,%1,%2"
2263 [(set_attr "type" "add")])
2264
2265 (define_insn "*subf<mode>3_imm_carry_0"
2266 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2267 (neg:P (match_operand:P 1 "gpc_reg_operand" "r")))
2268 (set (reg:P CA_REGNO)
2269 (eq:P (match_dup 1)
2270 (const_int 0)))]
2271 ""
2272 "subfic %0,%1,0"
2273 [(set_attr "type" "add")])
2274
2275 (define_insn "*subf<mode>3_imm_carry_m1"
2276 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2277 (not:P (match_operand:P 1 "gpc_reg_operand" "r")))
2278 (set (reg:P CA_REGNO)
2279 (const_int 1))]
2280 ""
2281 "subfic %0,%1,-1"
2282 [(set_attr "type" "add")])
2283
2284
2285 (define_expand "subf<mode>3_carry_in"
2286 [(parallel [
2287 (set (match_operand:GPR 0 "gpc_reg_operand")
2288 (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand"))
2289 (reg:GPR CA_REGNO))
2290 (match_operand:GPR 2 "adde_operand")))
2291 (clobber (reg:GPR CA_REGNO))])]
2292 ""
2293 {
2294 if (operands[2] == const0_rtx)
2295 {
2296 emit_insn (gen_subf<mode>3_carry_in_0 (operands[0], operands[1]));
2297 DONE;
2298 }
2299 if (operands[2] == constm1_rtx)
2300 {
2301 emit_insn (gen_subf<mode>3_carry_in_m1 (operands[0], operands[1]));
2302 DONE;
2303 }
2304 })
2305
2306 (define_insn "*subf<mode>3_carry_in_internal"
2307 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2308 (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
2309 (reg:GPR CA_REGNO))
2310 (match_operand:GPR 2 "gpc_reg_operand" "r")))
2311 (clobber (reg:GPR CA_REGNO))]
2312 ""
2313 "subfe %0,%1,%2"
2314 [(set_attr "type" "add")])
2315
2316 (define_insn "subf<mode>3_carry_in_0"
2317 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2318 (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
2319 (reg:GPR CA_REGNO)))
2320 (clobber (reg:GPR CA_REGNO))]
2321 ""
2322 "subfze %0,%1"
2323 [(set_attr "type" "add")])
2324
2325 (define_insn "subf<mode>3_carry_in_m1"
2326 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2327 (plus:GPR (minus:GPR (reg:GPR CA_REGNO)
2328 (match_operand:GPR 1 "gpc_reg_operand" "r"))
2329 (const_int -2)))
2330 (clobber (reg:GPR CA_REGNO))]
2331 ""
2332 "subfme %0,%1"
2333 [(set_attr "type" "add")])
2334
2335 (define_insn "subf<mode>3_carry_in_xx"
2336 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2337 (plus:GPR (reg:GPR CA_REGNO)
2338 (const_int -1)))
2339 (clobber (reg:GPR CA_REGNO))]
2340 ""
2341 "subfe %0,%0,%0"
2342 [(set_attr "type" "add")])
2343
2344 (define_insn_and_split "*subfsi3_carry_in_xx_64"
2345 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2346 (sign_extend:DI (plus:SI (reg:SI CA_REGNO)
2347 (const_int -1))))]
2348 "TARGET_POWERPC64"
2349 "#"
2350 "&&1"
2351 [(parallel [(set (match_dup 0)
2352 (plus:DI (reg:DI CA_REGNO)
2353 (const_int -1)))
2354 (clobber (reg:DI CA_REGNO))])]
2355 ""
2356 )
2357
2358 (define_insn "@neg<mode>2"
2359 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2360 (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2361 ""
2362 "neg %0,%1"
2363 [(set_attr "type" "add")])
2364
2365 (define_insn_and_split "*neg<mode>2_dot"
2366 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2367 (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2368 (const_int 0)))
2369 (clobber (match_scratch:GPR 0 "=r,r"))]
2370 "<MODE>mode == Pmode"
2371 "@
2372 neg. %0,%1
2373 #"
2374 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2375 [(set (match_dup 0)
2376 (neg:GPR (match_dup 1)))
2377 (set (match_dup 2)
2378 (compare:CC (match_dup 0)
2379 (const_int 0)))]
2380 ""
2381 [(set_attr "type" "add")
2382 (set_attr "dot" "yes")
2383 (set_attr "length" "4,8")])
2384
2385 (define_insn_and_split "*neg<mode>2_dot2"
2386 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2387 (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2388 (const_int 0)))
2389 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2390 (neg:GPR (match_dup 1)))]
2391 "<MODE>mode == Pmode"
2392 "@
2393 neg. %0,%1
2394 #"
2395 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2396 [(set (match_dup 0)
2397 (neg:GPR (match_dup 1)))
2398 (set (match_dup 2)
2399 (compare:CC (match_dup 0)
2400 (const_int 0)))]
2401 ""
2402 [(set_attr "type" "add")
2403 (set_attr "dot" "yes")
2404 (set_attr "length" "4,8")])
2405
2406
2407 (define_insn "clz<mode>2"
2408 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2409 (clz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2410 ""
2411 "cntlz<wd> %0,%1"
2412 [(set_attr "type" "cntlz")])
2413
2414 (define_expand "ctz<mode>2"
2415 [(set (match_operand:GPR 0 "gpc_reg_operand")
2416 (ctz:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2417 ""
2418 {
2419 if (TARGET_CTZ)
2420 {
2421 emit_insn (gen_ctz<mode>2_hw (operands[0], operands[1]));
2422 DONE;
2423 }
2424
2425 rtx tmp1 = gen_reg_rtx (<MODE>mode);
2426 rtx tmp2 = gen_reg_rtx (<MODE>mode);
2427 rtx tmp3 = gen_reg_rtx (<MODE>mode);
2428
2429 if (TARGET_POPCNTD)
2430 {
2431 emit_insn (gen_add<mode>3 (tmp1, operands[1], constm1_rtx));
2432 emit_insn (gen_one_cmpl<mode>2 (tmp2, operands[1]));
2433 emit_insn (gen_and<mode>3 (tmp3, tmp1, tmp2));
2434 emit_insn (gen_popcntd<mode>2 (operands[0], tmp3));
2435 }
2436 else
2437 {
2438 emit_insn (gen_neg<mode>2 (tmp1, operands[1]));
2439 emit_insn (gen_and<mode>3 (tmp2, operands[1], tmp1));
2440 emit_insn (gen_clz<mode>2 (tmp3, tmp2));
2441 emit_insn (gen_sub<mode>3 (operands[0], GEN_INT (<bits> - 1), tmp3));
2442 }
2443
2444 DONE;
2445 })
2446
2447 (define_insn "ctz<mode>2_hw"
2448 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2449 (ctz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2450 "TARGET_CTZ"
2451 "cnttz<wd> %0,%1"
2452 [(set_attr "type" "cntlz")])
2453
2454 (define_expand "ffs<mode>2"
2455 [(set (match_operand:GPR 0 "gpc_reg_operand")
2456 (ffs:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2457 ""
2458 {
2459 rtx tmp1 = gen_reg_rtx (<MODE>mode);
2460 rtx tmp2 = gen_reg_rtx (<MODE>mode);
2461 rtx tmp3 = gen_reg_rtx (<MODE>mode);
2462 emit_insn (gen_neg<mode>2 (tmp1, operands[1]));
2463 emit_insn (gen_and<mode>3 (tmp2, operands[1], tmp1));
2464 emit_insn (gen_clz<mode>2 (tmp3, tmp2));
2465 emit_insn (gen_sub<mode>3 (operands[0], GEN_INT (<bits>), tmp3));
2466 DONE;
2467 })
2468
2469
2470 (define_expand "popcount<mode>2"
2471 [(set (match_operand:GPR 0 "gpc_reg_operand")
2472 (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2473 "TARGET_POPCNTB || TARGET_POPCNTD"
2474 {
2475 rs6000_emit_popcount (operands[0], operands[1]);
2476 DONE;
2477 })
2478
2479 (define_insn "popcntb<mode>2"
2480 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2481 (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")]
2482 UNSPEC_POPCNTB))]
2483 "TARGET_POPCNTB"
2484 "popcntb %0,%1"
2485 [(set_attr "type" "popcnt")])
2486
2487 (define_insn "popcntd<mode>2"
2488 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2489 (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2490 "TARGET_POPCNTD"
2491 "popcnt<wd> %0,%1"
2492 [(set_attr "type" "popcnt")])
2493
2494
2495 (define_expand "parity<mode>2"
2496 [(set (match_operand:GPR 0 "gpc_reg_operand")
2497 (parity:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2498 "TARGET_POPCNTB"
2499 {
2500 rs6000_emit_parity (operands[0], operands[1]);
2501 DONE;
2502 })
2503
2504 (define_insn "parity<mode>2_cmpb"
2505 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2506 (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")] UNSPEC_PARITY))]
2507 "TARGET_CMPB && TARGET_POPCNTB"
2508 "prty<wd> %0,%1"
2509 [(set_attr "type" "popcnt")])
2510
2511 (define_insn "cfuged"
2512 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2513 (unspec:DI [(match_operand:DI 1 "gpc_reg_operand" "r")
2514 (match_operand:DI 2 "gpc_reg_operand" "r")]
2515 UNSPEC_CFUGED))]
2516 "TARGET_POWER10 && TARGET_64BIT"
2517 "cfuged %0,%1,%2"
2518 [(set_attr "type" "integer")])
2519
2520 (define_insn "cntlzdm"
2521 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2522 (unspec:DI [(match_operand:DI 1 "gpc_reg_operand" "r")
2523 (match_operand:DI 2 "gpc_reg_operand" "r")]
2524 UNSPEC_CNTLZDM))]
2525 "TARGET_POWER10 && TARGET_POWERPC64"
2526 "cntlzdm %0,%1,%2"
2527 [(set_attr "type" "integer")])
2528
2529 (define_insn "cnttzdm"
2530 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2531 (unspec:DI [(match_operand:DI 1 "gpc_reg_operand" "r")
2532 (match_operand:DI 2 "gpc_reg_operand" "r")]
2533 UNSPEC_CNTTZDM))]
2534 "TARGET_POWER10 && TARGET_POWERPC64"
2535 "cnttzdm %0,%1,%2"
2536 [(set_attr "type" "integer")])
2537
2538 (define_insn "pdepd"
2539 [(set (match_operand:DI 0 "register_operand" "=r")
2540 (unspec:DI [(match_operand:DI 1 "gpc_reg_operand" "r")
2541 (match_operand:DI 2 "gpc_reg_operand" "r")]
2542 UNSPEC_PDEPD))]
2543 "TARGET_POWER10 && TARGET_POWERPC64"
2544 "pdepd %0,%1,%2"
2545 [(set_attr "type" "integer")])
2546
2547 (define_insn "pextd"
2548 [(set (match_operand:DI 0 "register_operand" "=r")
2549 (unspec:DI [(match_operand:DI 1 "gpc_reg_operand" "r")
2550 (match_operand:DI 2 "gpc_reg_operand" "r")]
2551 UNSPEC_PEXTD))]
2552 "TARGET_POWER10 && TARGET_POWERPC64"
2553 "pextd %0,%1,%2"
2554 [(set_attr "type" "integer")])
2555
2556 (define_insn "cmpb<mode>3"
2557 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2558 (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")
2559 (match_operand:GPR 2 "gpc_reg_operand" "r")] UNSPEC_CMPB))]
2560 "TARGET_CMPB"
2561 "cmpb %0,%1,%2"
2562 [(set_attr "type" "cmp")])
2563
2564 ;; Since the hardware zeros the upper part of the register, save generating the
2565 ;; AND immediate if we are converting to unsigned
2566 (define_insn "*bswap<mode>2_extenddi"
2567 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2568 (zero_extend:DI
2569 (bswap:HSI (match_operand:HSI 1 "memory_operand" "Z"))))]
2570 "TARGET_POWERPC64"
2571 "l<wd>brx %0,%y1"
2572 [(set_attr "type" "load")])
2573
2574 (define_insn "*bswaphi2_extendsi"
2575 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2576 (zero_extend:SI
2577 (bswap:HI (match_operand:HI 1 "memory_operand" "Z"))))]
2578 ""
2579 "lhbrx %0,%y1"
2580 [(set_attr "type" "load")])
2581
2582 ;; Separate the bswap patterns into load, store, and gpr<-gpr. This prevents
2583 ;; the register allocator from converting a gpr<-gpr swap into a store and then
2584 ;; load with byte swap, which can be slower than doing it in the registers. It
2585 ;; also prevents certain failures with the RELOAD register allocator.
2586
2587 (define_expand "bswap<mode>2"
2588 [(use (match_operand:HSI 0 "reg_or_mem_operand"))
2589 (use (match_operand:HSI 1 "reg_or_mem_operand"))]
2590 ""
2591 {
2592 rtx dest = operands[0];
2593 rtx src = operands[1];
2594
2595 if (!REG_P (dest) && !REG_P (src))
2596 src = force_reg (<MODE>mode, src);
2597
2598 if (MEM_P (src))
2599 {
2600 src = rs6000_force_indexed_or_indirect_mem (src);
2601 emit_insn (gen_bswap<mode>2_load (dest, src));
2602 }
2603 else if (MEM_P (dest))
2604 {
2605 dest = rs6000_force_indexed_or_indirect_mem (dest);
2606 emit_insn (gen_bswap<mode>2_store (dest, src));
2607 }
2608 else
2609 emit_insn (gen_bswap<mode>2_reg (dest, src));
2610 DONE;
2611 })
2612
2613 (define_insn "bswap<mode>2_load"
2614 [(set (match_operand:HSI 0 "gpc_reg_operand" "=r")
2615 (bswap:HSI (match_operand:HSI 1 "memory_operand" "Z")))]
2616 ""
2617 "l<wd>brx %0,%y1"
2618 [(set_attr "type" "load")])
2619
2620 (define_insn "bswap<mode>2_store"
2621 [(set (match_operand:HSI 0 "memory_operand" "=Z")
2622 (bswap:HSI (match_operand:HSI 1 "gpc_reg_operand" "r")))]
2623 ""
2624 "st<wd>brx %1,%y0"
2625 [(set_attr "type" "store")])
2626
2627 (define_insn_and_split "bswaphi2_reg"
2628 [(set (match_operand:HI 0 "gpc_reg_operand" "=r,&r,wa")
2629 (bswap:HI
2630 (match_operand:HI 1 "gpc_reg_operand" "r,r,wa")))
2631 (clobber (match_scratch:SI 2 "=X,&r,X"))]
2632 ""
2633 "@
2634 brh %0,%1
2635 #
2636 xxbrh %x0,%x1"
2637 "reload_completed && !TARGET_POWER10 && int_reg_operand (operands[0], HImode)"
2638 [(set (match_dup 3)
2639 (and:SI (lshiftrt:SI (match_dup 4)
2640 (const_int 8))
2641 (const_int 255)))
2642 (set (match_dup 2)
2643 (and:SI (ashift:SI (match_dup 4)
2644 (const_int 8))
2645 (const_int 65280))) ;; 0xff00
2646 (set (match_dup 3)
2647 (ior:SI (match_dup 3)
2648 (match_dup 2)))]
2649 {
2650 operands[3] = simplify_gen_subreg (SImode, operands[0], HImode, 0);
2651 operands[4] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
2652 }
2653 [(set_attr "length" "*,12,*")
2654 (set_attr "type" "shift,*,vecperm")
2655 (set_attr "isa" "p10,*,p9v")])
2656
2657 ;; We are always BITS_BIG_ENDIAN, so the bit positions below in
2658 ;; zero_extract insns do not change for -mlittle.
2659 (define_insn_and_split "bswapsi2_reg"
2660 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,&r,wa")
2661 (bswap:SI
2662 (match_operand:SI 1 "gpc_reg_operand" "r,r,wa")))]
2663 ""
2664 "@
2665 brw %0,%1
2666 #
2667 xxbrw %x0,%x1"
2668 "reload_completed && !TARGET_POWER10 && int_reg_operand (operands[0], SImode)"
2669 [(set (match_dup 0) ; DABC
2670 (rotate:SI (match_dup 1)
2671 (const_int 24)))
2672 (set (match_dup 0) ; DCBC
2673 (ior:SI (and:SI (ashift:SI (match_dup 1)
2674 (const_int 8))
2675 (const_int 16711680))
2676 (and:SI (match_dup 0)
2677 (const_int -16711681))))
2678 (set (match_dup 0) ; DCBA
2679 (ior:SI (and:SI (lshiftrt:SI (match_dup 1)
2680 (const_int 24))
2681 (const_int 255))
2682 (and:SI (match_dup 0)
2683 (const_int -256))))]
2684 ""
2685 [(set_attr "length" "4,12,4")
2686 (set_attr "type" "shift,*,vecperm")
2687 (set_attr "isa" "p10,*,p9v")])
2688
2689 ;; On systems with LDBRX/STDBRX generate the loads/stores directly, just like
2690 ;; we do for L{H,W}BRX and ST{H,W}BRX above. If not, we have to generate more
2691 ;; complex code.
2692
2693 (define_expand "bswapdi2"
2694 [(parallel [(set (match_operand:DI 0 "reg_or_mem_operand")
2695 (bswap:DI
2696 (match_operand:DI 1 "reg_or_mem_operand")))
2697 (clobber (match_scratch:DI 2))
2698 (clobber (match_scratch:DI 3))])]
2699 ""
2700 {
2701 rtx dest = operands[0];
2702 rtx src = operands[1];
2703
2704 if (!REG_P (dest) && !REG_P (src))
2705 operands[1] = src = force_reg (DImode, src);
2706
2707 if (TARGET_POWERPC64 && TARGET_LDBRX)
2708 {
2709 if (MEM_P (src))
2710 {
2711 src = rs6000_force_indexed_or_indirect_mem (src);
2712 emit_insn (gen_bswapdi2_load (dest, src));
2713 }
2714 else if (MEM_P (dest))
2715 {
2716 dest = rs6000_force_indexed_or_indirect_mem (dest);
2717 emit_insn (gen_bswapdi2_store (dest, src));
2718 }
2719 else if (TARGET_P9_VECTOR)
2720 emit_insn (gen_bswapdi2_brd (dest, src));
2721 else
2722 emit_insn (gen_bswapdi2_reg (dest, src));
2723 DONE;
2724 }
2725
2726 if (!TARGET_POWERPC64)
2727 {
2728 /* 32-bit mode needs fewer scratch registers, but 32-bit addressing mode
2729 that uses 64-bit registers needs the same scratch registers as 64-bit
2730 mode. */
2731 emit_insn (gen_bswapdi2_32bit (dest, src));
2732 DONE;
2733 }
2734 })
2735
2736 ;; Power7/cell has ldbrx/stdbrx, so use it directly
2737 (define_insn "bswapdi2_load"
2738 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2739 (bswap:DI (match_operand:DI 1 "memory_operand" "Z")))]
2740 "TARGET_POWERPC64 && TARGET_LDBRX"
2741 "ldbrx %0,%y1"
2742 [(set_attr "type" "load")])
2743
2744 (define_insn "bswapdi2_store"
2745 [(set (match_operand:DI 0 "memory_operand" "=Z")
2746 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "r")))]
2747 "TARGET_POWERPC64 && TARGET_LDBRX"
2748 "stdbrx %1,%y0"
2749 [(set_attr "type" "store")])
2750
2751 (define_insn "bswapdi2_brd"
2752 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,wa")
2753 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "r,wa")))]
2754 "TARGET_P9_VECTOR"
2755 "@
2756 brd %0,%1
2757 xxbrd %x0,%x1"
2758 [(set_attr "type" "shift,vecperm")
2759 (set_attr "isa" "p10,p9v")])
2760
2761 (define_insn "bswapdi2_reg"
2762 [(set (match_operand:DI 0 "gpc_reg_operand" "=&r")
2763 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "r")))
2764 (clobber (match_scratch:DI 2 "=&r"))
2765 (clobber (match_scratch:DI 3 "=&r"))]
2766 "TARGET_POWERPC64 && TARGET_LDBRX && !TARGET_P9_VECTOR"
2767 "#"
2768 [(set_attr "length" "36")])
2769
2770 ;; Non-power7/cell, fall back to use lwbrx/stwbrx
2771 (define_insn "*bswapdi2_64bit"
2772 [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,&r")
2773 (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2774 (clobber (match_scratch:DI 2 "=&b,&b,&r"))
2775 (clobber (match_scratch:DI 3 "=&r,&r,&r"))]
2776 "TARGET_POWERPC64 && !TARGET_LDBRX
2777 && (REG_P (operands[0]) || REG_P (operands[1]))
2778 && !(MEM_P (operands[0]) && MEM_VOLATILE_P (operands[0]))
2779 && !(MEM_P (operands[1]) && MEM_VOLATILE_P (operands[1]))"
2780 "#"
2781 [(set_attr "length" "16,12,36")])
2782
2783 (define_split
2784 [(set (match_operand:DI 0 "gpc_reg_operand")
2785 (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand")))
2786 (clobber (match_operand:DI 2 "gpc_reg_operand"))
2787 (clobber (match_operand:DI 3 "gpc_reg_operand"))]
2788 "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2789 [(const_int 0)]
2790 {
2791 rtx dest = operands[0];
2792 rtx src = operands[1];
2793 rtx op2 = operands[2];
2794 rtx op3 = operands[3];
2795 rtx op3_32 = simplify_gen_subreg (SImode, op3, DImode,
2796 BYTES_BIG_ENDIAN ? 4 : 0);
2797 rtx dest_32 = simplify_gen_subreg (SImode, dest, DImode,
2798 BYTES_BIG_ENDIAN ? 4 : 0);
2799 rtx addr1;
2800 rtx addr2;
2801 rtx word1;
2802 rtx word2;
2803
2804 addr1 = XEXP (src, 0);
2805 if (GET_CODE (addr1) == PLUS)
2806 {
2807 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2808 if (TARGET_AVOID_XFORM)
2809 {
2810 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2811 addr2 = op2;
2812 }
2813 else
2814 addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2815 }
2816 else if (TARGET_AVOID_XFORM)
2817 {
2818 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2819 addr2 = op2;
2820 }
2821 else
2822 {
2823 emit_move_insn (op2, GEN_INT (4));
2824 addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2825 }
2826
2827 word1 = change_address (src, SImode, addr1);
2828 word2 = change_address (src, SImode, addr2);
2829
2830 if (BYTES_BIG_ENDIAN)
2831 {
2832 emit_insn (gen_bswapsi2 (op3_32, word2));
2833 emit_insn (gen_bswapsi2 (dest_32, word1));
2834 }
2835 else
2836 {
2837 emit_insn (gen_bswapsi2 (op3_32, word1));
2838 emit_insn (gen_bswapsi2 (dest_32, word2));
2839 }
2840
2841 emit_insn (gen_rotldi3_insert_3 (dest, op3, GEN_INT (32), dest,
2842 GEN_INT (0xffffffff)));
2843 DONE;
2844 })
2845
2846 (define_split
2847 [(set (match_operand:DI 0 "indexed_or_indirect_operand")
2848 (bswap:DI (match_operand:DI 1 "gpc_reg_operand")))
2849 (clobber (match_operand:DI 2 "gpc_reg_operand"))
2850 (clobber (match_operand:DI 3 "gpc_reg_operand"))]
2851 "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2852 [(const_int 0)]
2853 {
2854 rtx dest = operands[0];
2855 rtx src = operands[1];
2856 rtx op2 = operands[2];
2857 rtx op3 = operands[3];
2858 rtx src_si = simplify_gen_subreg (SImode, src, DImode,
2859 BYTES_BIG_ENDIAN ? 4 : 0);
2860 rtx op3_si = simplify_gen_subreg (SImode, op3, DImode,
2861 BYTES_BIG_ENDIAN ? 4 : 0);
2862 rtx addr1;
2863 rtx addr2;
2864 rtx word1;
2865 rtx word2;
2866
2867 addr1 = XEXP (dest, 0);
2868 if (GET_CODE (addr1) == PLUS)
2869 {
2870 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2871 if (TARGET_AVOID_XFORM)
2872 {
2873 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2874 addr2 = op2;
2875 }
2876 else
2877 addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2878 }
2879 else if (TARGET_AVOID_XFORM)
2880 {
2881 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2882 addr2 = op2;
2883 }
2884 else
2885 {
2886 emit_move_insn (op2, GEN_INT (4));
2887 addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2888 }
2889
2890 word1 = change_address (dest, SImode, addr1);
2891 word2 = change_address (dest, SImode, addr2);
2892
2893 emit_insn (gen_lshrdi3 (op3, src, GEN_INT (32)));
2894
2895 if (BYTES_BIG_ENDIAN)
2896 {
2897 emit_insn (gen_bswapsi2 (word1, src_si));
2898 emit_insn (gen_bswapsi2 (word2, op3_si));
2899 }
2900 else
2901 {
2902 emit_insn (gen_bswapsi2 (word2, src_si));
2903 emit_insn (gen_bswapsi2 (word1, op3_si));
2904 }
2905 DONE;
2906 })
2907
2908 (define_split
2909 [(set (match_operand:DI 0 "gpc_reg_operand")
2910 (bswap:DI (match_operand:DI 1 "gpc_reg_operand")))
2911 (clobber (match_operand:DI 2 "gpc_reg_operand"))
2912 (clobber (match_operand:DI 3 "gpc_reg_operand"))]
2913 "TARGET_POWERPC64 && !TARGET_P9_VECTOR && reload_completed"
2914 [(const_int 0)]
2915 {
2916 rtx dest = operands[0];
2917 rtx src = operands[1];
2918 rtx op2 = operands[2];
2919 rtx op3 = operands[3];
2920 int lo_off = BYTES_BIG_ENDIAN ? 4 : 0;
2921 rtx dest_si = simplify_gen_subreg (SImode, dest, DImode, lo_off);
2922 rtx src_si = simplify_gen_subreg (SImode, src, DImode, lo_off);
2923 rtx op2_si = simplify_gen_subreg (SImode, op2, DImode, lo_off);
2924 rtx op3_si = simplify_gen_subreg (SImode, op3, DImode, lo_off);
2925
2926 emit_insn (gen_lshrdi3 (op2, src, GEN_INT (32)));
2927 emit_insn (gen_bswapsi2 (op3_si, src_si));
2928 emit_insn (gen_bswapsi2 (dest_si, op2_si));
2929 emit_insn (gen_rotldi3_insert_3 (dest, op3, GEN_INT (32), dest,
2930 GEN_INT (0xffffffff)));
2931 DONE;
2932 })
2933
2934 (define_insn "bswapdi2_32bit"
2935 [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,?&r")
2936 (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2937 (clobber (match_scratch:SI 2 "=&b,&b,X"))]
2938 "!TARGET_POWERPC64 && (REG_P (operands[0]) || REG_P (operands[1]))"
2939 "#"
2940 [(set_attr "length" "16,12,36")])
2941
2942 (define_split
2943 [(set (match_operand:DI 0 "gpc_reg_operand")
2944 (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand")))
2945 (clobber (match_operand:SI 2 "gpc_reg_operand"))]
2946 "!TARGET_POWERPC64 && reload_completed"
2947 [(const_int 0)]
2948 {
2949 rtx dest = operands[0];
2950 rtx src = operands[1];
2951 rtx op2 = operands[2];
2952 rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
2953 rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
2954 rtx addr1;
2955 rtx addr2;
2956 rtx word1;
2957 rtx word2;
2958
2959 addr1 = XEXP (src, 0);
2960 if (GET_CODE (addr1) == PLUS)
2961 {
2962 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2963 if (TARGET_AVOID_XFORM
2964 || REGNO (XEXP (addr1, 1)) == REGNO (dest2))
2965 {
2966 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2967 addr2 = op2;
2968 }
2969 else
2970 addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
2971 }
2972 else if (TARGET_AVOID_XFORM
2973 || REGNO (addr1) == REGNO (dest2))
2974 {
2975 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2976 addr2 = op2;
2977 }
2978 else
2979 {
2980 emit_move_insn (op2, GEN_INT (4));
2981 addr2 = gen_rtx_PLUS (SImode, op2, addr1);
2982 }
2983
2984 word1 = change_address (src, SImode, addr1);
2985 word2 = change_address (src, SImode, addr2);
2986
2987 emit_insn (gen_bswapsi2 (dest2, word1));
2988 /* The REGNO (dest2) tests above ensure that addr2 has not been trashed,
2989 thus allowing us to omit an early clobber on the output. */
2990 emit_insn (gen_bswapsi2 (dest1, word2));
2991 DONE;
2992 })
2993
2994 (define_split
2995 [(set (match_operand:DI 0 "indexed_or_indirect_operand")
2996 (bswap:DI (match_operand:DI 1 "gpc_reg_operand")))
2997 (clobber (match_operand:SI 2 "gpc_reg_operand"))]
2998 "!TARGET_POWERPC64 && reload_completed"
2999 [(const_int 0)]
3000 {
3001 rtx dest = operands[0];
3002 rtx src = operands[1];
3003 rtx op2 = operands[2];
3004 rtx src1 = simplify_gen_subreg (SImode, src, DImode, 0);
3005 rtx src2 = simplify_gen_subreg (SImode, src, DImode, 4);
3006 rtx addr1;
3007 rtx addr2;
3008 rtx word1;
3009 rtx word2;
3010
3011 addr1 = XEXP (dest, 0);
3012 if (GET_CODE (addr1) == PLUS)
3013 {
3014 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
3015 if (TARGET_AVOID_XFORM)
3016 {
3017 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
3018 addr2 = op2;
3019 }
3020 else
3021 addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
3022 }
3023 else if (TARGET_AVOID_XFORM)
3024 {
3025 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
3026 addr2 = op2;
3027 }
3028 else
3029 {
3030 emit_move_insn (op2, GEN_INT (4));
3031 addr2 = gen_rtx_PLUS (SImode, op2, addr1);
3032 }
3033
3034 word1 = change_address (dest, SImode, addr1);
3035 word2 = change_address (dest, SImode, addr2);
3036
3037 emit_insn (gen_bswapsi2 (word2, src1));
3038 emit_insn (gen_bswapsi2 (word1, src2));
3039 DONE;
3040 })
3041
3042 (define_split
3043 [(set (match_operand:DI 0 "gpc_reg_operand")
3044 (bswap:DI (match_operand:DI 1 "gpc_reg_operand")))
3045 (clobber (match_operand:SI 2 ""))]
3046 "!TARGET_POWERPC64 && reload_completed"
3047 [(const_int 0)]
3048 {
3049 rtx dest = operands[0];
3050 rtx src = operands[1];
3051 rtx src1 = simplify_gen_subreg (SImode, src, DImode, 0);
3052 rtx src2 = simplify_gen_subreg (SImode, src, DImode, 4);
3053 rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
3054 rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
3055
3056 emit_insn (gen_bswapsi2 (dest1, src2));
3057 emit_insn (gen_bswapsi2 (dest2, src1));
3058 DONE;
3059 })
3060
3061
3062 (define_insn "mul<mode>3"
3063 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3064 (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3065 (match_operand:GPR 2 "reg_or_short_operand" "r,I")))]
3066 ""
3067 "@
3068 mull<wd> %0,%1,%2
3069 mulli %0,%1,%2"
3070 [(set_attr "type" "mul")
3071 (set (attr "size")
3072 (cond [(match_operand:GPR 2 "s8bit_cint_operand")
3073 (const_string "8")
3074 (match_operand:GPR 2 "short_cint_operand")
3075 (const_string "16")]
3076 (const_string "<bits>")))])
3077
3078 (define_insn_and_split "*mul<mode>3_dot"
3079 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3080 (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3081 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3082 (const_int 0)))
3083 (clobber (match_scratch:GPR 0 "=r,r"))]
3084 "<MODE>mode == Pmode"
3085 "@
3086 mull<wd>. %0,%1,%2
3087 #"
3088 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3089 [(set (match_dup 0)
3090 (mult:GPR (match_dup 1)
3091 (match_dup 2)))
3092 (set (match_dup 3)
3093 (compare:CC (match_dup 0)
3094 (const_int 0)))]
3095 ""
3096 [(set_attr "type" "mul")
3097 (set_attr "size" "<bits>")
3098 (set_attr "dot" "yes")
3099 (set_attr "length" "4,8")])
3100
3101 (define_insn_and_split "*mul<mode>3_dot2"
3102 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3103 (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3104 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3105 (const_int 0)))
3106 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3107 (mult:GPR (match_dup 1)
3108 (match_dup 2)))]
3109 "<MODE>mode == Pmode"
3110 "@
3111 mull<wd>. %0,%1,%2
3112 #"
3113 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3114 [(set (match_dup 0)
3115 (mult:GPR (match_dup 1)
3116 (match_dup 2)))
3117 (set (match_dup 3)
3118 (compare:CC (match_dup 0)
3119 (const_int 0)))]
3120 ""
3121 [(set_attr "type" "mul")
3122 (set_attr "size" "<bits>")
3123 (set_attr "dot" "yes")
3124 (set_attr "length" "4,8")])
3125
3126
3127 (define_expand "<su>mul<mode>3_highpart"
3128 [(set (match_operand:GPR 0 "gpc_reg_operand")
3129 (subreg:GPR
3130 (mult:<DMODE> (any_extend:<DMODE>
3131 (match_operand:GPR 1 "gpc_reg_operand"))
3132 (any_extend:<DMODE>
3133 (match_operand:GPR 2 "gpc_reg_operand")))
3134 0))]
3135 ""
3136 {
3137 if (<MODE>mode == SImode && TARGET_POWERPC64)
3138 {
3139 emit_insn (gen_<su>mulsi3_highpart_64 (operands[0], operands[1],
3140 operands[2]));
3141 DONE;
3142 }
3143
3144 if (!WORDS_BIG_ENDIAN)
3145 {
3146 emit_insn (gen_<su>mul<mode>3_highpart_le (operands[0], operands[1],
3147 operands[2]));
3148 DONE;
3149 }
3150 })
3151
3152 (define_insn "*<su>mul<mode>3_highpart"
3153 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3154 (subreg:GPR
3155 (mult:<DMODE> (any_extend:<DMODE>
3156 (match_operand:GPR 1 "gpc_reg_operand" "r"))
3157 (any_extend:<DMODE>
3158 (match_operand:GPR 2 "gpc_reg_operand" "r")))
3159 0))]
3160 "WORDS_BIG_ENDIAN && !(<MODE>mode == SImode && TARGET_POWERPC64)"
3161 "mulh<wd><u> %0,%1,%2"
3162 [(set_attr "type" "mul")
3163 (set_attr "size" "<bits>")])
3164
3165 (define_insn "<su>mulsi3_highpart_le"
3166 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
3167 (subreg:SI
3168 (mult:DI (any_extend:DI
3169 (match_operand:SI 1 "gpc_reg_operand" "r"))
3170 (any_extend:DI
3171 (match_operand:SI 2 "gpc_reg_operand" "r")))
3172 4))]
3173 "!WORDS_BIG_ENDIAN && !TARGET_POWERPC64"
3174 "mulhw<u> %0,%1,%2"
3175 [(set_attr "type" "mul")])
3176
3177 (define_insn "<su>muldi3_highpart_le"
3178 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3179 (subreg:DI
3180 (mult:TI (any_extend:TI
3181 (match_operand:DI 1 "gpc_reg_operand" "r"))
3182 (any_extend:TI
3183 (match_operand:DI 2 "gpc_reg_operand" "r")))
3184 8))]
3185 "!WORDS_BIG_ENDIAN && TARGET_POWERPC64"
3186 "mulhd<u> %0,%1,%2"
3187 [(set_attr "type" "mul")
3188 (set_attr "size" "64")])
3189
3190 (define_insn "<su>mulsi3_highpart_64"
3191 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
3192 (truncate:SI
3193 (lshiftrt:DI
3194 (mult:DI (any_extend:DI
3195 (match_operand:SI 1 "gpc_reg_operand" "r"))
3196 (any_extend:DI
3197 (match_operand:SI 2 "gpc_reg_operand" "r")))
3198 (const_int 32))))]
3199 "TARGET_POWERPC64"
3200 "mulhw<u> %0,%1,%2"
3201 [(set_attr "type" "mul")])
3202
3203 (define_expand "<u>mul<mode><dmode>3"
3204 [(set (match_operand:<DMODE> 0 "gpc_reg_operand")
3205 (mult:<DMODE> (any_extend:<DMODE>
3206 (match_operand:GPR 1 "gpc_reg_operand"))
3207 (any_extend:<DMODE>
3208 (match_operand:GPR 2 "gpc_reg_operand"))))]
3209 "!(<MODE>mode == SImode && TARGET_POWERPC64)"
3210 {
3211 rtx l = gen_reg_rtx (<MODE>mode);
3212 rtx h = gen_reg_rtx (<MODE>mode);
3213 emit_insn (gen_mul<mode>3 (l, operands[1], operands[2]));
3214 emit_insn (gen_<su>mul<mode>3_highpart (h, operands[1], operands[2]));
3215 emit_move_insn (gen_lowpart (<MODE>mode, operands[0]), l);
3216 emit_move_insn (gen_highpart (<MODE>mode, operands[0]), h);
3217 DONE;
3218 })
3219
3220 (define_insn "maddld<mode>4"
3221 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3222 (plus:GPR (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3223 (match_operand:GPR 2 "gpc_reg_operand" "r"))
3224 (match_operand:GPR 3 "gpc_reg_operand" "r")))]
3225 "TARGET_MADDLD"
3226 "maddld %0,%1,%2,%3"
3227 [(set_attr "type" "mul")])
3228
3229 (define_expand "<u>maddditi4"
3230 [(set (match_operand:TI 0 "gpc_reg_operand")
3231 (plus:TI
3232 (mult:TI (any_extend:TI (match_operand:DI 1 "gpc_reg_operand"))
3233 (any_extend:TI (match_operand:DI 2 "gpc_reg_operand")))
3234 (any_extend:TI (match_operand:DI 3 "gpc_reg_operand"))))]
3235 "TARGET_MADDLD && TARGET_POWERPC64"
3236 {
3237 rtx op0_lo = gen_rtx_SUBREG (DImode, operands[0], BYTES_BIG_ENDIAN ? 8 : 0);
3238 rtx op0_hi = gen_rtx_SUBREG (DImode, operands[0], BYTES_BIG_ENDIAN ? 0 : 8);
3239
3240 emit_insn (gen_maddlddi4 (op0_lo, operands[1], operands[2], operands[3]));
3241
3242 if (BYTES_BIG_ENDIAN)
3243 emit_insn (gen_<u>madddi4_highpart (op0_hi, operands[1], operands[2],
3244 operands[3]));
3245 else
3246 emit_insn (gen_<u>madddi4_highpart_le (op0_hi, operands[1], operands[2],
3247 operands[3]));
3248 DONE;
3249 })
3250
3251 (define_insn "<u>madddi4_highpart"
3252 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3253 (subreg:DI
3254 (plus:TI
3255 (mult:TI (any_extend:TI (match_operand:DI 1 "gpc_reg_operand" "r"))
3256 (any_extend:TI (match_operand:DI 2 "gpc_reg_operand" "r")))
3257 (any_extend:TI (match_operand:DI 3 "gpc_reg_operand" "r")))
3258 0))]
3259 "TARGET_MADDLD && BYTES_BIG_ENDIAN && TARGET_POWERPC64"
3260 "maddhd<u> %0,%1,%2,%3"
3261 [(set_attr "type" "mul")])
3262
3263 (define_insn "<u>madddi4_highpart_le"
3264 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3265 (subreg:DI
3266 (plus:TI
3267 (mult:TI (any_extend:TI (match_operand:DI 1 "gpc_reg_operand" "r"))
3268 (any_extend:TI (match_operand:DI 2 "gpc_reg_operand" "r")))
3269 (any_extend:TI (match_operand:DI 3 "gpc_reg_operand" "r")))
3270 8))]
3271 "TARGET_MADDLD && !BYTES_BIG_ENDIAN && TARGET_POWERPC64"
3272 "maddhd<u> %0,%1,%2,%3"
3273 [(set_attr "type" "mul")])
3274
3275 (define_insn "udiv<mode>3"
3276 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3277 (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3278 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3279 ""
3280 "div<wd>u %0,%1,%2"
3281 [(set_attr "type" "div")
3282 (set_attr "size" "<bits>")])
3283
3284 (define_insn "udivti3"
3285 [(set (match_operand:TI 0 "altivec_register_operand" "=v")
3286 (udiv:TI (match_operand:TI 1 "altivec_register_operand" "v")
3287 (match_operand:TI 2 "altivec_register_operand" "v")))]
3288 "TARGET_POWER10 && TARGET_POWERPC64"
3289 "vdivuq %0,%1,%2"
3290 [(set_attr "type" "vecdiv")
3291 (set_attr "size" "128")])
3292
3293 ;; For powers of two we can do sra[wd]i/addze for divide and then adjust for
3294 ;; modulus. If it isn't a power of two, force operands into register and do
3295 ;; a normal divide.
3296 (define_expand "div<mode>3"
3297 [(set (match_operand:GPR 0 "gpc_reg_operand")
3298 (div:GPR (match_operand:GPR 1 "gpc_reg_operand")
3299 (match_operand:GPR 2 "reg_or_cint_operand")))]
3300 ""
3301 {
3302 if (CONST_INT_P (operands[2])
3303 && INTVAL (operands[2]) > 0
3304 && exact_log2 (INTVAL (operands[2])) >= 0)
3305 {
3306 emit_insn (gen_div<mode>3_sra (operands[0], operands[1], operands[2]));
3307 DONE;
3308 }
3309
3310 operands[2] = force_reg (<MODE>mode, operands[2]);
3311 })
3312
3313 (define_insn "*div<mode>3"
3314 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3315 (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3316 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3317 ""
3318 "div<wd> %0,%1,%2"
3319 [(set_attr "type" "div")
3320 (set_attr "size" "<bits>")])
3321
3322 (define_insn "div<mode>3_sra"
3323 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3324 (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3325 (match_operand:GPR 2 "exact_log2_cint_operand" "N")))
3326 (clobber (reg:GPR CA_REGNO))]
3327 ""
3328 "sra<wd>i %0,%1,%p2\;addze %0,%0"
3329 [(set_attr "type" "two")
3330 (set_attr "length" "8")])
3331
3332 (define_insn_and_split "*div<mode>3_sra_dot"
3333 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3334 (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3335 (match_operand:GPR 2 "exact_log2_cint_operand" "N,N"))
3336 (const_int 0)))
3337 (clobber (match_scratch:GPR 0 "=r,r"))
3338 (clobber (reg:GPR CA_REGNO))]
3339 "<MODE>mode == Pmode"
3340 "@
3341 sra<wd>i %0,%1,%p2\;addze. %0,%0
3342 #"
3343 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3344 [(parallel [(set (match_dup 0)
3345 (div:GPR (match_dup 1)
3346 (match_dup 2)))
3347 (clobber (reg:GPR CA_REGNO))])
3348 (set (match_dup 3)
3349 (compare:CC (match_dup 0)
3350 (const_int 0)))]
3351 ""
3352 [(set_attr "type" "two")
3353 (set_attr "length" "8,12")
3354 (set_attr "cell_micro" "not")])
3355
3356 (define_insn_and_split "*div<mode>3_sra_dot2"
3357 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3358 (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3359 (match_operand:GPR 2 "exact_log2_cint_operand" "N,N"))
3360 (const_int 0)))
3361 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3362 (div:GPR (match_dup 1)
3363 (match_dup 2)))
3364 (clobber (reg:GPR CA_REGNO))]
3365 "<MODE>mode == Pmode"
3366 "@
3367 sra<wd>i %0,%1,%p2\;addze. %0,%0
3368 #"
3369 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3370 [(parallel [(set (match_dup 0)
3371 (div:GPR (match_dup 1)
3372 (match_dup 2)))
3373 (clobber (reg:GPR CA_REGNO))])
3374 (set (match_dup 3)
3375 (compare:CC (match_dup 0)
3376 (const_int 0)))]
3377 ""
3378 [(set_attr "type" "two")
3379 (set_attr "length" "8,12")
3380 (set_attr "cell_micro" "not")])
3381
3382 (define_insn "divti3"
3383 [(set (match_operand:TI 0 "altivec_register_operand" "=v")
3384 (div:TI (match_operand:TI 1 "altivec_register_operand" "v")
3385 (match_operand:TI 2 "altivec_register_operand" "v")))]
3386 "TARGET_POWER10 && TARGET_POWERPC64"
3387 "vdivsq %0,%1,%2"
3388 [(set_attr "type" "vecdiv")
3389 (set_attr "size" "128")])
3390
3391 (define_expand "mod<mode>3"
3392 [(set (match_operand:GPR 0 "gpc_reg_operand")
3393 (mod:GPR (match_operand:GPR 1 "gpc_reg_operand")
3394 (match_operand:GPR 2 "reg_or_cint_operand")))]
3395 ""
3396 {
3397 int i;
3398 rtx temp1;
3399 rtx temp2;
3400
3401 if (!CONST_INT_P (operands[2])
3402 || INTVAL (operands[2]) <= 0
3403 || (i = exact_log2 (INTVAL (operands[2]))) < 0)
3404 {
3405 if (!TARGET_MODULO)
3406 FAIL;
3407
3408 operands[2] = force_reg (<MODE>mode, operands[2]);
3409 }
3410 else
3411 {
3412 temp1 = gen_reg_rtx (<MODE>mode);
3413 temp2 = gen_reg_rtx (<MODE>mode);
3414
3415 emit_insn (gen_div<mode>3 (temp1, operands[1], operands[2]));
3416 emit_insn (gen_ashl<mode>3 (temp2, temp1, GEN_INT (i)));
3417 emit_insn (gen_sub<mode>3 (operands[0], operands[1], temp2));
3418 DONE;
3419 }
3420 })
3421
3422 ;; In order to enable using a peephole2 for combining div/mod to eliminate the
3423 ;; mod, prefer putting the result of mod into a different register
3424 (define_insn "*mod<mode>3"
3425 [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
3426 (mod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3427 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3428 "TARGET_MODULO"
3429 "mods<wd> %0,%1,%2"
3430 [(set_attr "type" "div")
3431 (set_attr "size" "<bits>")])
3432
3433
3434 (define_insn "umod<mode>3"
3435 [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
3436 (umod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3437 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3438 "TARGET_MODULO"
3439 "modu<wd> %0,%1,%2"
3440 [(set_attr "type" "div")
3441 (set_attr "size" "<bits>")])
3442
3443 ;; On machines with modulo support, do a combined div/mod the old fashioned
3444 ;; method, since the multiply/subtract is faster than doing the mod instruction
3445 ;; after a divide.
3446
3447 (define_peephole2
3448 [(set (match_operand:GPR 0 "gpc_reg_operand")
3449 (div:GPR (match_operand:GPR 1 "gpc_reg_operand")
3450 (match_operand:GPR 2 "gpc_reg_operand")))
3451 (set (match_operand:GPR 3 "gpc_reg_operand")
3452 (mod:GPR (match_dup 1)
3453 (match_dup 2)))]
3454 "TARGET_MODULO
3455 && ! reg_mentioned_p (operands[0], operands[1])
3456 && ! reg_mentioned_p (operands[0], operands[2])
3457 && ! reg_mentioned_p (operands[3], operands[1])
3458 && ! reg_mentioned_p (operands[3], operands[2])"
3459 [(set (match_dup 0)
3460 (div:GPR (match_dup 1)
3461 (match_dup 2)))
3462 (set (match_dup 3)
3463 (mult:GPR (match_dup 0)
3464 (match_dup 2)))
3465 (set (match_dup 3)
3466 (minus:GPR (match_dup 1)
3467 (match_dup 3)))])
3468
3469 (define_peephole2
3470 [(set (match_operand:GPR 0 "gpc_reg_operand")
3471 (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand")
3472 (match_operand:GPR 2 "gpc_reg_operand")))
3473 (set (match_operand:GPR 3 "gpc_reg_operand")
3474 (umod:GPR (match_dup 1)
3475 (match_dup 2)))]
3476 "TARGET_MODULO
3477 && ! reg_mentioned_p (operands[0], operands[1])
3478 && ! reg_mentioned_p (operands[0], operands[2])
3479 && ! reg_mentioned_p (operands[3], operands[1])
3480 && ! reg_mentioned_p (operands[3], operands[2])"
3481 [(set (match_dup 0)
3482 (udiv:GPR (match_dup 1)
3483 (match_dup 2)))
3484 (set (match_dup 3)
3485 (mult:GPR (match_dup 0)
3486 (match_dup 2)))
3487 (set (match_dup 3)
3488 (minus:GPR (match_dup 1)
3489 (match_dup 3)))])
3490
3491 (define_insn "umodti3"
3492 [(set (match_operand:TI 0 "altivec_register_operand" "=v")
3493 (umod:TI (match_operand:TI 1 "altivec_register_operand" "v")
3494 (match_operand:TI 2 "altivec_register_operand" "v")))]
3495 "TARGET_POWER10 && TARGET_POWERPC64"
3496 "vmoduq %0,%1,%2"
3497 [(set_attr "type" "vecdiv")
3498 (set_attr "size" "128")])
3499
3500 (define_insn "modti3"
3501 [(set (match_operand:TI 0 "altivec_register_operand" "=v")
3502 (mod:TI (match_operand:TI 1 "altivec_register_operand" "v")
3503 (match_operand:TI 2 "altivec_register_operand" "v")))]
3504 "TARGET_POWER10 && TARGET_POWERPC64"
3505 "vmodsq %0,%1,%2"
3506 [(set_attr "type" "vecdiv")
3507 (set_attr "size" "128")])
3508 \f
3509 ;; Logical instructions
3510 ;; The logical instructions are mostly combined by using match_operator,
3511 ;; but the plain AND insns are somewhat different because there is no
3512 ;; plain 'andi' (only 'andi.'), no plain 'andis', and there are all
3513 ;; those rotate-and-mask operations. Thus, the AND insns come first.
3514
3515 (define_expand "and<mode>3"
3516 [(set (match_operand:SDI 0 "gpc_reg_operand")
3517 (and:SDI (match_operand:SDI 1 "gpc_reg_operand")
3518 (match_operand:SDI 2 "reg_or_cint_operand")))]
3519 ""
3520 {
3521 if (<MODE>mode == DImode && !TARGET_POWERPC64)
3522 {
3523 rs6000_split_logical (operands, AND, false, false, false);
3524 DONE;
3525 }
3526
3527 if (CONST_INT_P (operands[2]))
3528 {
3529 if (rs6000_is_valid_and_mask (operands[2], <MODE>mode))
3530 {
3531 emit_insn (gen_and<mode>3_mask (operands[0], operands[1], operands[2]));
3532 DONE;
3533 }
3534
3535 if (logical_const_operand (operands[2], <MODE>mode))
3536 {
3537 emit_insn (gen_and<mode>3_imm (operands[0], operands[1], operands[2]));
3538 DONE;
3539 }
3540
3541 if (rs6000_is_valid_2insn_and (operands[2], <MODE>mode))
3542 {
3543 rs6000_emit_2insn_and (<MODE>mode, operands, true, 0);
3544 DONE;
3545 }
3546
3547 operands[2] = force_reg (<MODE>mode, operands[2]);
3548 }
3549 })
3550
3551
3552 (define_insn "and<mode>3_imm"
3553 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3554 (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3555 (match_operand:GPR 2 "logical_const_operand" "n")))
3556 (clobber (match_scratch:CC 3 "=x"))]
3557 "!rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3558 "andi%e2. %0,%1,%u2"
3559 [(set_attr "type" "logical")
3560 (set_attr "dot" "yes")])
3561
3562 (define_insn_and_split "*and<mode>3_imm_dot"
3563 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3564 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3565 (match_operand:GPR 2 "logical_const_operand" "n,n"))
3566 (const_int 0)))
3567 (clobber (match_scratch:GPR 0 "=r,r"))
3568 (clobber (match_scratch:CC 4 "=X,x"))]
3569 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3570 && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3571 "@
3572 andi%e2. %0,%1,%u2
3573 #"
3574 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3575 [(parallel [(set (match_dup 0)
3576 (and:GPR (match_dup 1)
3577 (match_dup 2)))
3578 (clobber (match_dup 4))])
3579 (set (match_dup 3)
3580 (compare:CC (match_dup 0)
3581 (const_int 0)))]
3582 ""
3583 [(set_attr "type" "logical")
3584 (set_attr "dot" "yes")
3585 (set_attr "length" "4,8")])
3586
3587 (define_insn_and_split "*and<mode>3_imm_dot2"
3588 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3589 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3590 (match_operand:GPR 2 "logical_const_operand" "n,n"))
3591 (const_int 0)))
3592 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3593 (and:GPR (match_dup 1)
3594 (match_dup 2)))
3595 (clobber (match_scratch:CC 4 "=X,x"))]
3596 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3597 && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3598 "@
3599 andi%e2. %0,%1,%u2
3600 #"
3601 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3602 [(parallel [(set (match_dup 0)
3603 (and:GPR (match_dup 1)
3604 (match_dup 2)))
3605 (clobber (match_dup 4))])
3606 (set (match_dup 3)
3607 (compare:CC (match_dup 0)
3608 (const_int 0)))]
3609 ""
3610 [(set_attr "type" "logical")
3611 (set_attr "dot" "yes")
3612 (set_attr "length" "4,8")])
3613
3614 (define_insn_and_split "*and<mode>3_imm_mask_dot"
3615 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3616 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3617 (match_operand:GPR 2 "logical_const_operand" "n,n"))
3618 (const_int 0)))
3619 (clobber (match_scratch:GPR 0 "=r,r"))]
3620 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3621 && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3622 "@
3623 andi%e2. %0,%1,%u2
3624 #"
3625 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3626 [(set (match_dup 0)
3627 (and:GPR (match_dup 1)
3628 (match_dup 2)))
3629 (set (match_dup 3)
3630 (compare:CC (match_dup 0)
3631 (const_int 0)))]
3632 ""
3633 [(set_attr "type" "logical")
3634 (set_attr "dot" "yes")
3635 (set_attr "length" "4,8")])
3636
3637 (define_insn_and_split "*and<mode>3_imm_mask_dot2"
3638 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3639 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3640 (match_operand:GPR 2 "logical_const_operand" "n,n"))
3641 (const_int 0)))
3642 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3643 (and:GPR (match_dup 1)
3644 (match_dup 2)))]
3645 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3646 && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3647 "@
3648 andi%e2. %0,%1,%u2
3649 #"
3650 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3651 [(set (match_dup 0)
3652 (and:GPR (match_dup 1)
3653 (match_dup 2)))
3654 (set (match_dup 3)
3655 (compare:CC (match_dup 0)
3656 (const_int 0)))]
3657 ""
3658 [(set_attr "type" "logical")
3659 (set_attr "dot" "yes")
3660 (set_attr "length" "4,8")])
3661
3662 (define_insn "*and<mode>3_imm_dot_shifted"
3663 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
3664 (compare:CC
3665 (and:GPR
3666 (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3667 (match_operand:SI 4 "const_int_operand" "n"))
3668 (match_operand:GPR 2 "const_int_operand" "n"))
3669 (const_int 0)))
3670 (clobber (match_scratch:GPR 0 "=r"))]
3671 "logical_const_operand (GEN_INT (UINTVAL (operands[2])
3672 << INTVAL (operands[4])),
3673 DImode)
3674 && (<MODE>mode == Pmode
3675 || (UINTVAL (operands[2]) << INTVAL (operands[4])) <= 0x7fffffff)"
3676 {
3677 operands[2] = GEN_INT (UINTVAL (operands[2]) << INTVAL (operands[4]));
3678 return "andi%e2. %0,%1,%u2";
3679 }
3680 [(set_attr "type" "logical")
3681 (set_attr "dot" "yes")])
3682
3683
3684 (define_insn "and<mode>3_mask"
3685 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3686 (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3687 (match_operand:GPR 2 "const_int_operand" "n")))]
3688 "rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3689 {
3690 return rs6000_insn_for_and_mask (<MODE>mode, operands, false);
3691 }
3692 [(set_attr "type" "shift")])
3693
3694 (define_insn_and_split "*and<mode>3_mask_dot"
3695 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3696 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3697 (match_operand:GPR 2 "const_int_operand" "n,n"))
3698 (const_int 0)))
3699 (clobber (match_scratch:GPR 0 "=r,r"))]
3700 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3701 && !logical_const_operand (operands[2], <MODE>mode)
3702 && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3703 {
3704 if (which_alternative == 0)
3705 return rs6000_insn_for_and_mask (<MODE>mode, operands, true);
3706 else
3707 return "#";
3708 }
3709 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3710 [(set (match_dup 0)
3711 (and:GPR (match_dup 1)
3712 (match_dup 2)))
3713 (set (match_dup 3)
3714 (compare:CC (match_dup 0)
3715 (const_int 0)))]
3716 ""
3717 [(set_attr "type" "shift")
3718 (set_attr "dot" "yes")
3719 (set_attr "length" "4,8")])
3720
3721 (define_insn_and_split "*and<mode>3_mask_dot2"
3722 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3723 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3724 (match_operand:GPR 2 "const_int_operand" "n,n"))
3725 (const_int 0)))
3726 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3727 (and:GPR (match_dup 1)
3728 (match_dup 2)))]
3729 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3730 && !logical_const_operand (operands[2], <MODE>mode)
3731 && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3732 {
3733 if (which_alternative == 0)
3734 return rs6000_insn_for_and_mask (<MODE>mode, operands, true);
3735 else
3736 return "#";
3737 }
3738 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3739 [(set (match_dup 0)
3740 (and:GPR (match_dup 1)
3741 (match_dup 2)))
3742 (set (match_dup 3)
3743 (compare:CC (match_dup 0)
3744 (const_int 0)))]
3745 ""
3746 [(set_attr "type" "shift")
3747 (set_attr "dot" "yes")
3748 (set_attr "length" "4,8")])
3749
3750
3751 (define_insn_and_split "*and<mode>3_2insn"
3752 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3753 (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3754 (match_operand:GPR 2 "const_int_operand" "n")))]
3755 "rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3756 && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3757 || logical_const_operand (operands[2], <MODE>mode))"
3758 "#"
3759 "&& 1"
3760 [(pc)]
3761 {
3762 rs6000_emit_2insn_and (<MODE>mode, operands, false, 0);
3763 DONE;
3764 }
3765 [(set_attr "type" "shift")
3766 (set_attr "length" "8")])
3767
3768 (define_insn_and_split "*and<mode>3_2insn_dot"
3769 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3770 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3771 (match_operand:GPR 2 "const_int_operand" "n,n"))
3772 (const_int 0)))
3773 (clobber (match_scratch:GPR 0 "=r,r"))]
3774 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3775 && rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3776 && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3777 || logical_const_operand (operands[2], <MODE>mode))"
3778 "#"
3779 "&& reload_completed"
3780 [(pc)]
3781 {
3782 rs6000_emit_2insn_and (<MODE>mode, operands, false, 1);
3783 DONE;
3784 }
3785 [(set_attr "type" "shift")
3786 (set_attr "dot" "yes")
3787 (set_attr "length" "8,12")])
3788
3789 (define_insn_and_split "*and<mode>3_2insn_dot2"
3790 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3791 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3792 (match_operand:GPR 2 "const_int_operand" "n,n"))
3793 (const_int 0)))
3794 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3795 (and:GPR (match_dup 1)
3796 (match_dup 2)))]
3797 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3798 && rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3799 && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3800 || logical_const_operand (operands[2], <MODE>mode))"
3801 "#"
3802 "&& reload_completed"
3803 [(pc)]
3804 {
3805 rs6000_emit_2insn_and (<MODE>mode, operands, false, 2);
3806 DONE;
3807 }
3808 [(set_attr "type" "shift")
3809 (set_attr "dot" "yes")
3810 (set_attr "length" "8,12")])
3811
3812 (define_insn_and_split "*branch_anddi3_dot"
3813 [(set (pc)
3814 (if_then_else (eq (and:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r")
3815 (match_operand:DI 2 "const_int_operand" "n,n"))
3816 (const_int 0))
3817 (label_ref (match_operand 3 ""))
3818 (pc)))
3819 (clobber (match_scratch:DI 0 "=r,r"))
3820 (clobber (reg:CC CR0_REGNO))]
3821 "rs6000_is_valid_rotate_dot_mask (operands[2], DImode)
3822 && TARGET_POWERPC64"
3823 "#"
3824 "&& reload_completed"
3825 [(pc)]
3826 {
3827 int nb, ne;
3828 if (rs6000_is_valid_mask (operands[2], &nb, &ne, DImode)
3829 && nb >= ne
3830 && ne > 0)
3831 {
3832 unsigned HOST_WIDE_INT val = INTVAL (operands[2]);
3833 int shift = 63 - nb;
3834 rtx tmp = gen_rtx_ASHIFT (DImode, operands[1], GEN_INT (shift));
3835 tmp = gen_rtx_AND (DImode, tmp, GEN_INT (val << shift));
3836 rtx cr0 = gen_rtx_REG (CCmode, CR0_REGNO);
3837 rs6000_emit_dot_insn (operands[0], tmp, 1, cr0);
3838 rtx loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands[3]);
3839 rtx cond = gen_rtx_EQ (CCEQmode, cr0, const0_rtx);
3840 rtx ite = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, loc_ref, pc_rtx);
3841 emit_jump_insn (gen_rtx_SET (pc_rtx, ite));
3842 DONE;
3843 }
3844 else
3845 FAIL;
3846 }
3847 [(set_attr "type" "shift")
3848 (set_attr "dot" "yes")
3849 (set_attr "length" "8,12")])
3850
3851 (define_expand "<code><mode>3"
3852 [(set (match_operand:SDI 0 "gpc_reg_operand")
3853 (iorxor:SDI (match_operand:SDI 1 "gpc_reg_operand")
3854 (match_operand:SDI 2 "reg_or_cint_operand")))]
3855 ""
3856 {
3857 if (<MODE>mode == DImode && !TARGET_POWERPC64)
3858 {
3859 rs6000_split_logical (operands, <CODE>, false, false, false);
3860 DONE;
3861 }
3862
3863 if (non_logical_cint_operand (operands[2], <MODE>mode))
3864 {
3865 rtx tmp = ((!can_create_pseudo_p ()
3866 || rtx_equal_p (operands[0], operands[1]))
3867 ? operands[0] : gen_reg_rtx (<MODE>mode));
3868
3869 HOST_WIDE_INT value = INTVAL (operands[2]);
3870 HOST_WIDE_INT lo = value & 0xffff;
3871 HOST_WIDE_INT hi = value - lo;
3872
3873 emit_insn (gen_<code><mode>3 (tmp, operands[1], GEN_INT (hi)));
3874 emit_insn (gen_<code><mode>3 (operands[0], tmp, GEN_INT (lo)));
3875 DONE;
3876 }
3877
3878 if (!reg_or_logical_cint_operand (operands[2], <MODE>mode))
3879 operands[2] = force_reg (<MODE>mode, operands[2]);
3880 })
3881
3882 (define_split
3883 [(set (match_operand:GPR 0 "gpc_reg_operand")
3884 (iorxor:GPR (match_operand:GPR 1 "gpc_reg_operand")
3885 (match_operand:GPR 2 "non_logical_cint_operand")))]
3886 ""
3887 [(set (match_dup 3)
3888 (iorxor:GPR (match_dup 1)
3889 (match_dup 4)))
3890 (set (match_dup 0)
3891 (iorxor:GPR (match_dup 3)
3892 (match_dup 5)))]
3893 {
3894 operands[3] = ((!can_create_pseudo_p ()
3895 || rtx_equal_p (operands[0], operands[1]))
3896 ? operands[0] : gen_reg_rtx (<MODE>mode));
3897
3898 HOST_WIDE_INT value = INTVAL (operands[2]);
3899 HOST_WIDE_INT lo = value & 0xffff;
3900 HOST_WIDE_INT hi = value - lo;
3901
3902 operands[4] = GEN_INT (hi);
3903 operands[5] = GEN_INT (lo);
3904 })
3905
3906 (define_insn "*bool<mode>3_imm"
3907 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3908 (match_operator:GPR 3 "boolean_or_operator"
3909 [(match_operand:GPR 1 "gpc_reg_operand" "%r")
3910 (match_operand:GPR 2 "logical_const_operand" "n")]))]
3911 ""
3912 "%q3i%e2 %0,%1,%u2"
3913 [(set_attr "type" "logical")])
3914
3915 (define_insn "*bool<mode>3"
3916 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3917 (match_operator:GPR 3 "boolean_operator"
3918 [(match_operand:GPR 1 "gpc_reg_operand" "r")
3919 (match_operand:GPR 2 "gpc_reg_operand" "r")]))]
3920 ""
3921 "%q3 %0,%1,%2"
3922 [(set_attr "type" "logical")])
3923
3924 (define_insn_and_split "*bool<mode>3_dot"
3925 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3926 (compare:CC (match_operator:GPR 3 "boolean_operator"
3927 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3928 (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
3929 (const_int 0)))
3930 (clobber (match_scratch:GPR 0 "=r,r"))]
3931 "<MODE>mode == Pmode"
3932 "@
3933 %q3. %0,%1,%2
3934 #"
3935 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3936 [(set (match_dup 0)
3937 (match_dup 3))
3938 (set (match_dup 4)
3939 (compare:CC (match_dup 0)
3940 (const_int 0)))]
3941 ""
3942 [(set_attr "type" "logical")
3943 (set_attr "dot" "yes")
3944 (set_attr "length" "4,8")])
3945
3946 (define_insn_and_split "*bool<mode>3_dot2"
3947 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3948 (compare:CC (match_operator:GPR 3 "boolean_operator"
3949 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3950 (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
3951 (const_int 0)))
3952 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3953 (match_dup 3))]
3954 "<MODE>mode == Pmode"
3955 "@
3956 %q3. %0,%1,%2
3957 #"
3958 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3959 [(set (match_dup 0)
3960 (match_dup 3))
3961 (set (match_dup 4)
3962 (compare:CC (match_dup 0)
3963 (const_int 0)))]
3964 ""
3965 [(set_attr "type" "logical")
3966 (set_attr "dot" "yes")
3967 (set_attr "length" "4,8")])
3968
3969
3970 (define_insn "*boolc<mode>3"
3971 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3972 (match_operator:GPR 3 "boolean_operator"
3973 [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))
3974 (match_operand:GPR 1 "gpc_reg_operand" "r")]))]
3975 ""
3976 "%q3 %0,%1,%2"
3977 [(set_attr "type" "logical")])
3978
3979 (define_insn_and_split "*boolc<mode>3_dot"
3980 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3981 (compare:CC (match_operator:GPR 3 "boolean_operator"
3982 [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3983 (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
3984 (const_int 0)))
3985 (clobber (match_scratch:GPR 0 "=r,r"))]
3986 "<MODE>mode == Pmode"
3987 "@
3988 %q3. %0,%1,%2
3989 #"
3990 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3991 [(set (match_dup 0)
3992 (match_dup 3))
3993 (set (match_dup 4)
3994 (compare:CC (match_dup 0)
3995 (const_int 0)))]
3996 ""
3997 [(set_attr "type" "logical")
3998 (set_attr "dot" "yes")
3999 (set_attr "length" "4,8")])
4000
4001 (define_insn_and_split "*boolc<mode>3_dot2"
4002 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
4003 (compare:CC (match_operator:GPR 3 "boolean_operator"
4004 [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
4005 (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
4006 (const_int 0)))
4007 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4008 (match_dup 3))]
4009 "<MODE>mode == Pmode"
4010 "@
4011 %q3. %0,%1,%2
4012 #"
4013 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
4014 [(set (match_dup 0)
4015 (match_dup 3))
4016 (set (match_dup 4)
4017 (compare:CC (match_dup 0)
4018 (const_int 0)))]
4019 ""
4020 [(set_attr "type" "logical")
4021 (set_attr "dot" "yes")
4022 (set_attr "length" "4,8")])
4023
4024
4025 (define_insn "*boolcc<mode>3"
4026 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4027 (match_operator:GPR 3 "boolean_operator"
4028 [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
4029 (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))]))]
4030 ""
4031 "%q3 %0,%1,%2"
4032 [(set_attr "type" "logical")])
4033
4034 (define_insn_and_split "*boolcc<mode>3_dot"
4035 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
4036 (compare:CC (match_operator:GPR 3 "boolean_operator"
4037 [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
4038 (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
4039 (const_int 0)))
4040 (clobber (match_scratch:GPR 0 "=r,r"))]
4041 "<MODE>mode == Pmode"
4042 "@
4043 %q3. %0,%1,%2
4044 #"
4045 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
4046 [(set (match_dup 0)
4047 (match_dup 3))
4048 (set (match_dup 4)
4049 (compare:CC (match_dup 0)
4050 (const_int 0)))]
4051 ""
4052 [(set_attr "type" "logical")
4053 (set_attr "dot" "yes")
4054 (set_attr "length" "4,8")])
4055
4056 (define_insn_and_split "*boolcc<mode>3_dot2"
4057 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
4058 (compare:CC (match_operator:GPR 3 "boolean_operator"
4059 [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
4060 (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
4061 (const_int 0)))
4062 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4063 (match_dup 3))]
4064 "<MODE>mode == Pmode"
4065 "@
4066 %q3. %0,%1,%2
4067 #"
4068 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
4069 [(set (match_dup 0)
4070 (match_dup 3))
4071 (set (match_dup 4)
4072 (compare:CC (match_dup 0)
4073 (const_int 0)))]
4074 ""
4075 [(set_attr "type" "logical")
4076 (set_attr "dot" "yes")
4077 (set_attr "length" "4,8")])
4078
4079
4080 ;; TODO: Should have dots of this as well.
4081 (define_insn "*eqv<mode>3"
4082 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4083 (not:GPR (xor:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4084 (match_operand:GPR 2 "gpc_reg_operand" "r"))))]
4085 ""
4086 "eqv %0,%1,%2"
4087 [(set_attr "type" "logical")])
4088 \f
4089 ;; Rotate-and-mask and insert.
4090
4091 (define_insn "*rotl<mode>3_mask"
4092 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4093 (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
4094 [(match_operand:GPR 1 "gpc_reg_operand" "r")
4095 (match_operand:SI 2 "reg_or_cint_operand" "rn")])
4096 (match_operand:GPR 3 "const_int_operand" "n")))]
4097 "rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
4098 {
4099 return rs6000_insn_for_shift_mask (<MODE>mode, operands, false);
4100 }
4101 [(set_attr "type" "shift")
4102 (set_attr "maybe_var_shift" "yes")])
4103
4104 (define_insn_and_split "*rotl<mode>3_mask_dot"
4105 [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y")
4106 (compare:CC
4107 (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
4108 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
4109 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")])
4110 (match_operand:GPR 3 "const_int_operand" "n,n"))
4111 (const_int 0)))
4112 (clobber (match_scratch:GPR 0 "=r,r"))]
4113 "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff)
4114 && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
4115 {
4116 if (which_alternative == 0)
4117 return rs6000_insn_for_shift_mask (<MODE>mode, operands, true);
4118 else
4119 return "#";
4120 }
4121 "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)"
4122 [(set (match_dup 0)
4123 (and:GPR (match_dup 4)
4124 (match_dup 3)))
4125 (set (match_dup 5)
4126 (compare:CC (match_dup 0)
4127 (const_int 0)))]
4128 ""
4129 [(set_attr "type" "shift")
4130 (set_attr "maybe_var_shift" "yes")
4131 (set_attr "dot" "yes")
4132 (set_attr "length" "4,8")])
4133
4134 (define_insn_and_split "*rotl<mode>3_mask_dot2"
4135 [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y")
4136 (compare:CC
4137 (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
4138 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
4139 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")])
4140 (match_operand:GPR 3 "const_int_operand" "n,n"))
4141 (const_int 0)))
4142 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4143 (and:GPR (match_dup 4)
4144 (match_dup 3)))]
4145 "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff)
4146 && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
4147 {
4148 if (which_alternative == 0)
4149 return rs6000_insn_for_shift_mask (<MODE>mode, operands, true);
4150 else
4151 return "#";
4152 }
4153 "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)"
4154 [(set (match_dup 0)
4155 (and:GPR (match_dup 4)
4156 (match_dup 3)))
4157 (set (match_dup 5)
4158 (compare:CC (match_dup 0)
4159 (const_int 0)))]
4160 ""
4161 [(set_attr "type" "shift")
4162 (set_attr "maybe_var_shift" "yes")
4163 (set_attr "dot" "yes")
4164 (set_attr "length" "4,8")])
4165
4166 ; Special case for less-than-0. We can do it with just one machine
4167 ; instruction, but the generic optimizers do not realise it is cheap.
4168 (define_insn "*lt0_<mode>di"
4169 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4170 (lt:GPR (match_operand:DI 1 "gpc_reg_operand" "r")
4171 (const_int 0)))]
4172 "TARGET_POWERPC64"
4173 "srdi %0,%1,63"
4174 [(set_attr "type" "shift")])
4175
4176 (define_insn "*lt0_<mode>si"
4177 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4178 (lt:GPR (match_operand:SI 1 "gpc_reg_operand" "r")
4179 (const_int 0)))]
4180 ""
4181 "rlwinm %0,%1,1,31,31"
4182 [(set_attr "type" "shift")])
4183
4184
4185
4186 ; Two forms for insert (the two arms of the IOR are not canonicalized,
4187 ; both are an AND so are the same precedence).
4188 (define_insn "*rotl<mode>3_insert"
4189 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4190 (ior:GPR (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
4191 [(match_operand:GPR 1 "gpc_reg_operand" "r")
4192 (match_operand:SI 2 "const_int_operand" "n")])
4193 (match_operand:GPR 3 "const_int_operand" "n"))
4194 (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0")
4195 (match_operand:GPR 6 "const_int_operand" "n"))))]
4196 "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode)
4197 && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0"
4198 {
4199 return rs6000_insn_for_insert_mask (<MODE>mode, operands, false);
4200 }
4201 [(set_attr "type" "insert")])
4202 ; FIXME: this needs an attr "size", so that the scheduler can see the
4203 ; difference between rlwimi and rldimi. We also might want dot forms,
4204 ; but not for rlwimi on POWER4 and similar processors.
4205
4206 (define_insn "*rotl<mode>3_insert_2"
4207 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4208 (ior:GPR (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0")
4209 (match_operand:GPR 6 "const_int_operand" "n"))
4210 (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
4211 [(match_operand:GPR 1 "gpc_reg_operand" "r")
4212 (match_operand:SI 2 "const_int_operand" "n")])
4213 (match_operand:GPR 3 "const_int_operand" "n"))))]
4214 "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode)
4215 && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0"
4216 {
4217 return rs6000_insn_for_insert_mask (<MODE>mode, operands, false);
4218 }
4219 [(set_attr "type" "insert")])
4220
4221 ; There are also some forms without one of the ANDs.
4222 (define_insn "rotl<mode>3_insert_3"
4223 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4224 (ior:GPR (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0")
4225 (match_operand:GPR 4 "const_int_operand" "n"))
4226 (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4227 (match_operand:SI 2 "const_int_operand" "n"))))]
4228 "INTVAL (operands[2]) > 0
4229 && INTVAL (operands[2]) == exact_log2 (UINTVAL (operands[4]) + 1)"
4230 {
4231 if (<MODE>mode == SImode)
4232 return "rlwimi %0,%1,%h2,0,31-%h2";
4233 else
4234 return "rldimi %0,%1,%H2,0";
4235 }
4236 [(set_attr "type" "insert")])
4237
4238 ; Canonicalize the PLUS and XOR forms to IOR for rotl<mode>3_insert_3
4239 (define_code_iterator plus_xor [plus xor])
4240
4241 (define_insn_and_split "*rotl<mode>3_insert_3_<code>"
4242 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4243 (plus_xor:GPR
4244 (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0")
4245 (match_operand:GPR 4 "const_int_operand" "n"))
4246 (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4247 (match_operand:SI 2 "const_int_operand" "n"))))]
4248 "INTVAL (operands[2]) > 0
4249 && INTVAL (operands[2]) == exact_log2 (UINTVAL (operands[4]) + 1)"
4250 "#"
4251 "&& 1"
4252 [(set (match_dup 0)
4253 (ior:GPR (and:GPR (match_dup 3) (match_dup 4))
4254 (ashift:GPR (match_dup 1) (match_dup 2))))])
4255
4256 (define_code_iterator plus_ior_xor [plus ior xor])
4257
4258 (define_split
4259 [(set (match_operand:GPR 0 "gpc_reg_operand")
4260 (plus_ior_xor:GPR (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand")
4261 (match_operand:SI 2 "const_int_operand"))
4262 (match_operand:GPR 3 "gpc_reg_operand")))]
4263 "nonzero_bits (operands[3], <MODE>mode)
4264 < HOST_WIDE_INT_1U << INTVAL (operands[2])"
4265 [(set (match_dup 0)
4266 (ior:GPR (and:GPR (match_dup 3)
4267 (match_dup 4))
4268 (ashift:GPR (match_dup 1)
4269 (match_dup 2))))]
4270 {
4271 operands[4] = GEN_INT ((HOST_WIDE_INT_1U << INTVAL (operands[2])) - 1);
4272 })
4273
4274 (define_insn "*rotlsi3_insert_4"
4275 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
4276 (ior:SI (and:SI (match_operand:SI 3 "gpc_reg_operand" "0")
4277 (match_operand:SI 4 "const_int_operand" "n"))
4278 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4279 (match_operand:SI 2 "const_int_operand" "n"))))]
4280 "INTVAL (operands[2]) + exact_log2 (-UINTVAL (operands[4])) == 32"
4281 "rlwimi %0,%1,32-%h2,%h2,31"
4282 [(set_attr "type" "insert")])
4283
4284 (define_insn "*rotlsi3_insert_5"
4285 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
4286 (ior:SI (and:SI (match_operand:SI 1 "gpc_reg_operand" "0,r")
4287 (match_operand:SI 2 "const_int_operand" "n,n"))
4288 (and:SI (match_operand:SI 3 "gpc_reg_operand" "r,0")
4289 (match_operand:SI 4 "const_int_operand" "n,n"))))]
4290 "rs6000_is_valid_mask (operands[2], NULL, NULL, SImode)
4291 && UINTVAL (operands[2]) != 0 && UINTVAL (operands[4]) != 0
4292 && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
4293 "@
4294 rlwimi %0,%3,0,%4
4295 rlwimi %0,%1,0,%2"
4296 [(set_attr "type" "insert")])
4297
4298 (define_insn "*rotldi3_insert_6"
4299 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4300 (ior:DI (and:DI (match_operand:DI 1 "gpc_reg_operand" "0")
4301 (match_operand:DI 2 "const_int_operand" "n"))
4302 (and:DI (match_operand:DI 3 "gpc_reg_operand" "r")
4303 (match_operand:DI 4 "const_int_operand" "n"))))]
4304 "exact_log2 (-UINTVAL (operands[2])) > 0
4305 && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
4306 {
4307 operands[5] = GEN_INT (64 - exact_log2 (-UINTVAL (operands[2])));
4308 return "rldimi %0,%3,0,%5";
4309 }
4310 [(set_attr "type" "insert")
4311 (set_attr "size" "64")])
4312
4313 (define_insn "*rotldi3_insert_7"
4314 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4315 (ior:DI (and:DI (match_operand:DI 3 "gpc_reg_operand" "r")
4316 (match_operand:DI 4 "const_int_operand" "n"))
4317 (and:DI (match_operand:DI 1 "gpc_reg_operand" "0")
4318 (match_operand:DI 2 "const_int_operand" "n"))))]
4319 "exact_log2 (-UINTVAL (operands[2])) > 0
4320 && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
4321 {
4322 operands[5] = GEN_INT (64 - exact_log2 (-UINTVAL (operands[2])));
4323 return "rldimi %0,%3,0,%5";
4324 }
4325 [(set_attr "type" "insert")
4326 (set_attr "size" "64")])
4327
4328
4329 ; This handles the important case of multiple-precision shifts. There is
4330 ; no canonicalization rule for ASHIFT vs. LSHIFTRT, so two patterns.
4331 (define_split
4332 [(set (match_operand:GPR 0 "gpc_reg_operand")
4333 (ior:GPR (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand")
4334 (match_operand:SI 3 "const_int_operand"))
4335 (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand")
4336 (match_operand:SI 4 "const_int_operand"))))]
4337 "can_create_pseudo_p ()
4338 && INTVAL (operands[3]) + INTVAL (operands[4])
4339 >= GET_MODE_PRECISION (<MODE>mode)"
4340 [(set (match_dup 5)
4341 (lshiftrt:GPR (match_dup 2)
4342 (match_dup 4)))
4343 (set (match_dup 0)
4344 (ior:GPR (and:GPR (match_dup 5)
4345 (match_dup 6))
4346 (ashift:GPR (match_dup 1)
4347 (match_dup 3))))]
4348 {
4349 unsigned HOST_WIDE_INT mask = 1;
4350 mask = (mask << INTVAL (operands[3])) - 1;
4351 operands[5] = gen_reg_rtx (<MODE>mode);
4352 operands[6] = GEN_INT (mask);
4353 })
4354
4355 (define_split
4356 [(set (match_operand:GPR 0 "gpc_reg_operand")
4357 (ior:GPR (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand")
4358 (match_operand:SI 4 "const_int_operand"))
4359 (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand")
4360 (match_operand:SI 3 "const_int_operand"))))]
4361 "can_create_pseudo_p ()
4362 && INTVAL (operands[3]) + INTVAL (operands[4])
4363 >= GET_MODE_PRECISION (<MODE>mode)"
4364 [(set (match_dup 5)
4365 (lshiftrt:GPR (match_dup 2)
4366 (match_dup 4)))
4367 (set (match_dup 0)
4368 (ior:GPR (and:GPR (match_dup 5)
4369 (match_dup 6))
4370 (ashift:GPR (match_dup 1)
4371 (match_dup 3))))]
4372 {
4373 unsigned HOST_WIDE_INT mask = 1;
4374 mask = (mask << INTVAL (operands[3])) - 1;
4375 operands[5] = gen_reg_rtx (<MODE>mode);
4376 operands[6] = GEN_INT (mask);
4377 })
4378
4379
4380 ; Another important case is setting some bits to 1; we can do that with
4381 ; an insert instruction, in many cases.
4382 (define_insn_and_split "*ior<mode>_mask"
4383 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4384 (ior:GPR (match_operand:GPR 1 "gpc_reg_operand" "0")
4385 (match_operand:GPR 2 "const_int_operand" "n")))
4386 (clobber (match_scratch:GPR 3 "=r"))]
4387 "!logical_const_operand (operands[2], <MODE>mode)
4388 && rs6000_is_valid_mask (operands[2], NULL, NULL, <MODE>mode)"
4389 "#"
4390 "&& 1"
4391 [(set (match_dup 3)
4392 (const_int -1))
4393 (set (match_dup 0)
4394 (ior:GPR (and:GPR (rotate:GPR (match_dup 3)
4395 (match_dup 4))
4396 (match_dup 2))
4397 (and:GPR (match_dup 1)
4398 (match_dup 5))))]
4399 {
4400 int nb, ne;
4401 rs6000_is_valid_mask (operands[2], &nb, &ne, <MODE>mode);
4402 if (GET_CODE (operands[3]) == SCRATCH)
4403 operands[3] = gen_reg_rtx (<MODE>mode);
4404 operands[4] = GEN_INT (ne);
4405 operands[5] = GEN_INT (~UINTVAL (operands[2]));
4406 }
4407 [(set_attr "type" "two")
4408 (set_attr "length" "8")])
4409
4410
4411 ; Yet another case is an rldimi with the second value coming from memory.
4412 ; The zero_extend that should become part of the rldimi is merged into the
4413 ; load from memory instead. Split things properly again.
4414 (define_split
4415 [(set (match_operand:DI 0 "gpc_reg_operand")
4416 (ior:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand")
4417 (match_operand:SI 2 "const_int_operand"))
4418 (zero_extend:DI (match_operand:QHSI 3 "memory_operand"))))]
4419 "INTVAL (operands[2]) == <bits>"
4420 [(set (match_dup 4)
4421 (zero_extend:DI (match_dup 3)))
4422 (set (match_dup 0)
4423 (ior:DI (and:DI (match_dup 4)
4424 (match_dup 5))
4425 (ashift:DI (match_dup 1)
4426 (match_dup 2))))]
4427 {
4428 operands[4] = gen_reg_rtx (DImode);
4429 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << <bits>) - 1);
4430 })
4431
4432 ; rldimi with UNSPEC_SI_FROM_SF.
4433 (define_insn_and_split "*rotldi3_insert_sf"
4434 [(set (match_operand:DI 0 "gpc_reg_operand")
4435 (ior:DI
4436 (ashift:DI (match_operand:DI 1 "gpc_reg_operand")
4437 (match_operand:SI 2 "const_int_operand"))
4438 (zero_extend:DI
4439 (unspec:QHSI
4440 [(match_operand:SF 3 "memory_operand")]
4441 UNSPEC_SI_FROM_SF))))
4442 (clobber (match_scratch:V4SF 4))]
4443 "TARGET_POWERPC64 && INTVAL (operands[2]) == <bits>"
4444 "#"
4445 "&& 1"
4446 [(parallel [(set (match_dup 5)
4447 (zero_extend:DI (unspec:QHSI [(match_dup 3)] UNSPEC_SI_FROM_SF)))
4448 (clobber (match_dup 4))])
4449 (set (match_dup 0)
4450 (ior:DI
4451 (and:DI (match_dup 5) (match_dup 6))
4452 (ashift:DI (match_dup 1) (match_dup 2))))]
4453 {
4454 operands[5] = gen_reg_rtx (DImode);
4455 operands[6] = GEN_INT ((HOST_WIDE_INT_1U << <bits>) - 1);
4456 })
4457
4458 ; rlwimi, too.
4459 (define_split
4460 [(set (match_operand:SI 0 "gpc_reg_operand")
4461 (ior:SI (ashift:SI (match_operand:SI 1 "gpc_reg_operand")
4462 (match_operand:SI 2 "const_int_operand"))
4463 (zero_extend:SI (match_operand:QHI 3 "memory_operand"))))]
4464 "INTVAL (operands[2]) == <bits>"
4465 [(set (match_dup 4)
4466 (zero_extend:SI (match_dup 3)))
4467 (set (match_dup 0)
4468 (ior:SI (and:SI (match_dup 4)
4469 (match_dup 5))
4470 (ashift:SI (match_dup 1)
4471 (match_dup 2))))]
4472 {
4473 operands[4] = gen_reg_rtx (SImode);
4474 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << <bits>) - 1);
4475 })
4476
4477
4478 ;; Now the simple shifts.
4479
4480 (define_insn "rotl<mode>3"
4481 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4482 (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4483 (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4484 ""
4485 "rotl<wd>%I2 %0,%1,%<hH>2"
4486 [(set_attr "type" "shift")
4487 (set_attr "maybe_var_shift" "yes")])
4488
4489 (define_insn "*rotlsi3_64"
4490 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4491 (zero_extend:DI
4492 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4493 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4494 "TARGET_POWERPC64"
4495 "rotlw%I2 %0,%1,%h2"
4496 [(set_attr "type" "shift")
4497 (set_attr "maybe_var_shift" "yes")])
4498
4499 (define_insn_and_split "*rotl<mode>3_dot"
4500 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4501 (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4502 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4503 (const_int 0)))
4504 (clobber (match_scratch:GPR 0 "=r,r"))]
4505 "<MODE>mode == Pmode"
4506 "@
4507 rotl<wd>%I2. %0,%1,%<hH>2
4508 #"
4509 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4510 [(set (match_dup 0)
4511 (rotate:GPR (match_dup 1)
4512 (match_dup 2)))
4513 (set (match_dup 3)
4514 (compare:CC (match_dup 0)
4515 (const_int 0)))]
4516 ""
4517 [(set_attr "type" "shift")
4518 (set_attr "maybe_var_shift" "yes")
4519 (set_attr "dot" "yes")
4520 (set_attr "length" "4,8")])
4521
4522 (define_insn_and_split "*rotl<mode>3_dot2"
4523 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4524 (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4525 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4526 (const_int 0)))
4527 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4528 (rotate:GPR (match_dup 1)
4529 (match_dup 2)))]
4530 "<MODE>mode == Pmode"
4531 "@
4532 rotl<wd>%I2. %0,%1,%<hH>2
4533 #"
4534 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4535 [(set (match_dup 0)
4536 (rotate:GPR (match_dup 1)
4537 (match_dup 2)))
4538 (set (match_dup 3)
4539 (compare:CC (match_dup 0)
4540 (const_int 0)))]
4541 ""
4542 [(set_attr "type" "shift")
4543 (set_attr "maybe_var_shift" "yes")
4544 (set_attr "dot" "yes")
4545 (set_attr "length" "4,8")])
4546
4547
4548 (define_insn "ashl<mode>3"
4549 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4550 (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4551 (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4552 ""
4553 "sl<wd>%I2 %0,%1,%<hH>2"
4554 [(set_attr "type" "shift")
4555 (set_attr "maybe_var_shift" "yes")])
4556
4557 (define_insn "*ashlsi3_64"
4558 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4559 (zero_extend:DI
4560 (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4561 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4562 "TARGET_POWERPC64"
4563 "slw%I2 %0,%1,%h2"
4564 [(set_attr "type" "shift")
4565 (set_attr "maybe_var_shift" "yes")])
4566
4567 (define_insn_and_split "*ashl<mode>3_dot"
4568 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4569 (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4570 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4571 (const_int 0)))
4572 (clobber (match_scratch:GPR 0 "=r,r"))]
4573 "<MODE>mode == Pmode"
4574 "@
4575 sl<wd>%I2. %0,%1,%<hH>2
4576 #"
4577 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4578 [(set (match_dup 0)
4579 (ashift:GPR (match_dup 1)
4580 (match_dup 2)))
4581 (set (match_dup 3)
4582 (compare:CC (match_dup 0)
4583 (const_int 0)))]
4584 ""
4585 [(set_attr "type" "shift")
4586 (set_attr "maybe_var_shift" "yes")
4587 (set_attr "dot" "yes")
4588 (set_attr "length" "4,8")])
4589
4590 (define_insn_and_split "*ashl<mode>3_dot2"
4591 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4592 (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4593 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4594 (const_int 0)))
4595 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4596 (ashift:GPR (match_dup 1)
4597 (match_dup 2)))]
4598 "<MODE>mode == Pmode"
4599 "@
4600 sl<wd>%I2. %0,%1,%<hH>2
4601 #"
4602 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4603 [(set (match_dup 0)
4604 (ashift:GPR (match_dup 1)
4605 (match_dup 2)))
4606 (set (match_dup 3)
4607 (compare:CC (match_dup 0)
4608 (const_int 0)))]
4609 ""
4610 [(set_attr "type" "shift")
4611 (set_attr "maybe_var_shift" "yes")
4612 (set_attr "dot" "yes")
4613 (set_attr "length" "4,8")])
4614
4615 ;; Pretend we have a memory form of extswsli until register allocation is done
4616 ;; so that we use LWZ to load the value from memory, instead of LWA.
4617 (define_insn_and_split "ashdi3_extswsli"
4618 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
4619 (ashift:DI
4620 (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,m"))
4621 (match_operand:DI 2 "u6bit_cint_operand" "n,n")))]
4622 "TARGET_EXTSWSLI"
4623 "@
4624 extswsli %0,%1,%2
4625 #"
4626 "&& reload_completed && MEM_P (operands[1])"
4627 [(set (match_dup 3)
4628 (match_dup 1))
4629 (set (match_dup 0)
4630 (ashift:DI (sign_extend:DI (match_dup 3))
4631 (match_dup 2)))]
4632 {
4633 operands[3] = gen_lowpart (SImode, operands[0]);
4634 }
4635 [(set_attr "type" "shift")
4636 (set_attr "maybe_var_shift" "no")])
4637
4638
4639 (define_insn_and_split "ashdi3_extswsli_dot"
4640 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y")
4641 (compare:CC
4642 (ashift:DI
4643 (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m"))
4644 (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n"))
4645 (const_int 0)))
4646 (clobber (match_scratch:DI 0 "=r,r,r,r"))]
4647 "TARGET_EXTSWSLI"
4648 "@
4649 extswsli. %0,%1,%2
4650 #
4651 #
4652 #"
4653 "&& reload_completed
4654 && (cc_reg_not_cr0_operand (operands[3], CCmode)
4655 || memory_operand (operands[1], SImode))"
4656 [(pc)]
4657 {
4658 rtx dest = operands[0];
4659 rtx src = operands[1];
4660 rtx shift = operands[2];
4661 rtx cr = operands[3];
4662 rtx src2;
4663
4664 if (!MEM_P (src))
4665 src2 = src;
4666 else
4667 {
4668 src2 = gen_lowpart (SImode, dest);
4669 emit_move_insn (src2, src);
4670 }
4671
4672 if (REGNO (cr) == CR0_REGNO)
4673 {
4674 emit_insn (gen_ashdi3_extswsli_dot2 (dest, src2, shift, cr));
4675 DONE;
4676 }
4677
4678 emit_insn (gen_ashdi3_extswsli (dest, src2, shift));
4679 emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx)));
4680 DONE;
4681 }
4682 [(set_attr "type" "shift")
4683 (set_attr "maybe_var_shift" "no")
4684 (set_attr "dot" "yes")
4685 (set_attr "length" "4,8,8,12")])
4686
4687 (define_insn_and_split "ashdi3_extswsli_dot2"
4688 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y")
4689 (compare:CC
4690 (ashift:DI
4691 (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m"))
4692 (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n"))
4693 (const_int 0)))
4694 (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r")
4695 (ashift:DI (sign_extend:DI (match_dup 1))
4696 (match_dup 2)))]
4697 "TARGET_EXTSWSLI"
4698 "@
4699 extswsli. %0,%1,%2
4700 #
4701 #
4702 #"
4703 "&& reload_completed
4704 && (cc_reg_not_cr0_operand (operands[3], CCmode)
4705 || memory_operand (operands[1], SImode))"
4706 [(pc)]
4707 {
4708 rtx dest = operands[0];
4709 rtx src = operands[1];
4710 rtx shift = operands[2];
4711 rtx cr = operands[3];
4712 rtx src2;
4713
4714 if (!MEM_P (src))
4715 src2 = src;
4716 else
4717 {
4718 src2 = gen_lowpart (SImode, dest);
4719 emit_move_insn (src2, src);
4720 }
4721
4722 if (REGNO (cr) == CR0_REGNO)
4723 {
4724 emit_insn (gen_ashdi3_extswsli_dot2 (dest, src2, shift, cr));
4725 DONE;
4726 }
4727
4728 emit_insn (gen_ashdi3_extswsli (dest, src2, shift));
4729 emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx)));
4730 DONE;
4731 }
4732 [(set_attr "type" "shift")
4733 (set_attr "maybe_var_shift" "no")
4734 (set_attr "dot" "yes")
4735 (set_attr "length" "4,8,8,12")])
4736
4737 (define_insn "lshr<mode>3"
4738 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4739 (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4740 (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4741 ""
4742 "sr<wd>%I2 %0,%1,%<hH>2"
4743 [(set_attr "type" "shift")
4744 (set_attr "maybe_var_shift" "yes")])
4745
4746 (define_insn "*lshrsi3_64"
4747 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4748 (zero_extend:DI
4749 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4750 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4751 "TARGET_POWERPC64"
4752 "srw%I2 %0,%1,%h2"
4753 [(set_attr "type" "shift")
4754 (set_attr "maybe_var_shift" "yes")])
4755
4756 (define_insn_and_split "*lshr<mode>3_dot"
4757 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4758 (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4759 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4760 (const_int 0)))
4761 (clobber (match_scratch:GPR 0 "=r,r"))]
4762 "<MODE>mode == Pmode"
4763 "@
4764 sr<wd>%I2. %0,%1,%<hH>2
4765 #"
4766 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4767 [(set (match_dup 0)
4768 (lshiftrt:GPR (match_dup 1)
4769 (match_dup 2)))
4770 (set (match_dup 3)
4771 (compare:CC (match_dup 0)
4772 (const_int 0)))]
4773 ""
4774 [(set_attr "type" "shift")
4775 (set_attr "maybe_var_shift" "yes")
4776 (set_attr "dot" "yes")
4777 (set_attr "length" "4,8")])
4778
4779 (define_insn_and_split "*lshr<mode>3_dot2"
4780 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4781 (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4782 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4783 (const_int 0)))
4784 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4785 (lshiftrt:GPR (match_dup 1)
4786 (match_dup 2)))]
4787 "<MODE>mode == Pmode"
4788 "@
4789 sr<wd>%I2. %0,%1,%<hH>2
4790 #"
4791 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4792 [(set (match_dup 0)
4793 (lshiftrt:GPR (match_dup 1)
4794 (match_dup 2)))
4795 (set (match_dup 3)
4796 (compare:CC (match_dup 0)
4797 (const_int 0)))]
4798 ""
4799 [(set_attr "type" "shift")
4800 (set_attr "maybe_var_shift" "yes")
4801 (set_attr "dot" "yes")
4802 (set_attr "length" "4,8")])
4803
4804
4805 (define_insn "ashr<mode>3"
4806 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4807 (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4808 (match_operand:SI 2 "reg_or_cint_operand" "rn")))
4809 (clobber (reg:GPR CA_REGNO))]
4810 ""
4811 "sra<wd>%I2 %0,%1,%<hH>2"
4812 [(set_attr "type" "shift")
4813 (set_attr "maybe_var_shift" "yes")])
4814
4815 (define_insn "*ashrsi3_64"
4816 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4817 (sign_extend:DI
4818 (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4819 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))
4820 (clobber (reg:SI CA_REGNO))]
4821 "TARGET_POWERPC64"
4822 "sraw%I2 %0,%1,%h2"
4823 [(set_attr "type" "shift")
4824 (set_attr "maybe_var_shift" "yes")])
4825
4826 (define_insn_and_split "*ashr<mode>3_dot"
4827 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4828 (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4829 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4830 (const_int 0)))
4831 (clobber (match_scratch:GPR 0 "=r,r"))
4832 (clobber (reg:GPR CA_REGNO))]
4833 "<MODE>mode == Pmode"
4834 "@
4835 sra<wd>%I2. %0,%1,%<hH>2
4836 #"
4837 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4838 [(parallel [(set (match_dup 0)
4839 (ashiftrt:GPR (match_dup 1)
4840 (match_dup 2)))
4841 (clobber (reg:GPR CA_REGNO))])
4842 (set (match_dup 3)
4843 (compare:CC (match_dup 0)
4844 (const_int 0)))]
4845 ""
4846 [(set_attr "type" "shift")
4847 (set_attr "maybe_var_shift" "yes")
4848 (set_attr "dot" "yes")
4849 (set_attr "length" "4,8")])
4850
4851 (define_insn_and_split "*ashr<mode>3_dot2"
4852 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4853 (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4854 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4855 (const_int 0)))
4856 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4857 (ashiftrt:GPR (match_dup 1)
4858 (match_dup 2)))
4859 (clobber (reg:GPR CA_REGNO))]
4860 "<MODE>mode == Pmode"
4861 "@
4862 sra<wd>%I2. %0,%1,%<hH>2
4863 #"
4864 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4865 [(parallel [(set (match_dup 0)
4866 (ashiftrt:GPR (match_dup 1)
4867 (match_dup 2)))
4868 (clobber (reg:GPR CA_REGNO))])
4869 (set (match_dup 3)
4870 (compare:CC (match_dup 0)
4871 (const_int 0)))]
4872 ""
4873 [(set_attr "type" "shift")
4874 (set_attr "maybe_var_shift" "yes")
4875 (set_attr "dot" "yes")
4876 (set_attr "length" "4,8")])
4877 \f
4878 ;; Builtins to replace a division to generate FRE reciprocal estimate
4879 ;; instructions and the necessary fixup instructions
4880 (define_expand "recip<mode>3"
4881 [(match_operand:RECIPF 0 "gpc_reg_operand")
4882 (match_operand:RECIPF 1 "gpc_reg_operand")
4883 (match_operand:RECIPF 2 "gpc_reg_operand")]
4884 "RS6000_RECIP_HAVE_RE_P (<MODE>mode)"
4885 {
4886 rs6000_emit_swdiv (operands[0], operands[1], operands[2], false);
4887 DONE;
4888 })
4889
4890 ;; Split to create division from FRE/FRES/etc. and fixup instead of the normal
4891 ;; hardware division. This is only done before register allocation and with
4892 ;; -ffast-math. This must appear before the divsf3/divdf3 insns.
4893 ;; We used to also check optimize_insn_for_speed_p () but problems with guessed
4894 ;; frequencies (pr68212/pr77536) yields that unreliable so it was removed.
4895 (define_split
4896 [(set (match_operand:RECIPF 0 "gpc_reg_operand")
4897 (div:RECIPF (match_operand 1 "gpc_reg_operand")
4898 (match_operand 2 "gpc_reg_operand")))]
4899 "RS6000_RECIP_AUTO_RE_P (<MODE>mode)
4900 && can_create_pseudo_p () && flag_finite_math_only
4901 && !flag_trapping_math && flag_reciprocal_math"
4902 [(const_int 0)]
4903 {
4904 rs6000_emit_swdiv (operands[0], operands[1], operands[2], true);
4905 DONE;
4906 })
4907
4908 ;; Builtins to replace 1/sqrt(x) with instructions using RSQRTE and the
4909 ;; appropriate fixup.
4910 (define_expand "rsqrt<mode>2"
4911 [(match_operand:RECIPF 0 "gpc_reg_operand")
4912 (match_operand:RECIPF 1 "gpc_reg_operand")]
4913 "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4914 {
4915 rs6000_emit_swsqrt (operands[0], operands[1], 1);
4916 DONE;
4917 })
4918 \f
4919 ;; Floating-point insns, excluding normal data motion. We combine the SF/DF
4920 ;; modes here, and also add in conditional vsx/power8-vector support to access
4921 ;; values in the traditional Altivec registers if the appropriate
4922 ;; -mupper-regs-{df,sf} option is enabled.
4923
4924 (define_expand "abs<mode>2"
4925 [(set (match_operand:SFDF 0 "gpc_reg_operand")
4926 (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))]
4927 "TARGET_HARD_FLOAT"
4928 "")
4929
4930 (define_insn "*abs<mode>2_fpr"
4931 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,wa")
4932 (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "d,wa")))]
4933 "TARGET_HARD_FLOAT"
4934 "@
4935 fabs %0,%1
4936 xsabsdp %x0,%x1"
4937 [(set_attr "type" "fpsimple")])
4938
4939 (define_insn "*nabs<mode>2_fpr"
4940 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,wa")
4941 (neg:SFDF
4942 (abs:SFDF
4943 (match_operand:SFDF 1 "gpc_reg_operand" "d,wa"))))]
4944 "TARGET_HARD_FLOAT"
4945 "@
4946 fnabs %0,%1
4947 xsnabsdp %x0,%x1"
4948 [(set_attr "type" "fpsimple")])
4949
4950 (define_expand "neg<mode>2"
4951 [(set (match_operand:SFDF 0 "gpc_reg_operand")
4952 (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))]
4953 "TARGET_HARD_FLOAT"
4954 "")
4955
4956 (define_insn "*neg<mode>2_fpr"
4957 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,wa")
4958 (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "d,wa")))]
4959 "TARGET_HARD_FLOAT"
4960 "@
4961 fneg %0,%1
4962 xsnegdp %x0,%x1"
4963 [(set_attr "type" "fpsimple")])
4964
4965 (define_expand "add<mode>3"
4966 [(set (match_operand:SFDF 0 "gpc_reg_operand")
4967 (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4968 (match_operand:SFDF 2 "gpc_reg_operand")))]
4969 "TARGET_HARD_FLOAT"
4970 "")
4971
4972 (define_insn "*add<mode>3_fpr"
4973 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,wa")
4974 (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%d,wa")
4975 (match_operand:SFDF 2 "gpc_reg_operand" "d,wa")))]
4976 "TARGET_HARD_FLOAT"
4977 "@
4978 fadd<s> %0,%1,%2
4979 xsadd<sd>p %x0,%x1,%x2"
4980 [(set_attr "type" "fp")
4981 (set_attr "isa" "*,<Fisa>")])
4982
4983 (define_expand "sub<mode>3"
4984 [(set (match_operand:SFDF 0 "gpc_reg_operand")
4985 (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4986 (match_operand:SFDF 2 "gpc_reg_operand")))]
4987 "TARGET_HARD_FLOAT"
4988 "")
4989
4990 (define_insn "*sub<mode>3_fpr"
4991 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,wa")
4992 (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "d,wa")
4993 (match_operand:SFDF 2 "gpc_reg_operand" "d,wa")))]
4994 "TARGET_HARD_FLOAT"
4995 "@
4996 fsub<s> %0,%1,%2
4997 xssub<sd>p %x0,%x1,%x2"
4998 [(set_attr "type" "fp")
4999 (set_attr "isa" "*,<Fisa>")])
5000
5001 (define_expand "mul<mode>3"
5002 [(set (match_operand:SFDF 0 "gpc_reg_operand")
5003 (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
5004 (match_operand:SFDF 2 "gpc_reg_operand")))]
5005 "TARGET_HARD_FLOAT"
5006 "")
5007
5008 (define_insn "*mul<mode>3_fpr"
5009 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,wa")
5010 (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%d,wa")
5011 (match_operand:SFDF 2 "gpc_reg_operand" "d,wa")))]
5012 "TARGET_HARD_FLOAT"
5013 "@
5014 fmul<s> %0,%1,%2
5015 xsmul<sd>p %x0,%x1,%x2"
5016 [(set_attr "type" "dmul")
5017 (set_attr "isa" "*,<Fisa>")])
5018
5019 (define_expand "div<mode>3"
5020 [(set (match_operand:SFDF 0 "gpc_reg_operand")
5021 (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
5022 (match_operand:SFDF 2 "gpc_reg_operand")))]
5023 "TARGET_HARD_FLOAT"
5024 {
5025 if (RS6000_RECIP_AUTO_RE_P (<MODE>mode)
5026 && can_create_pseudo_p () && flag_finite_math_only
5027 && !flag_trapping_math && flag_reciprocal_math)
5028 {
5029 rs6000_emit_swdiv (operands[0], operands[1], operands[2], true);
5030 DONE;
5031 }
5032 })
5033
5034 (define_insn "*div<mode>3_fpr"
5035 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,wa")
5036 (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "d,wa")
5037 (match_operand:SFDF 2 "gpc_reg_operand" "d,wa")))]
5038 "TARGET_HARD_FLOAT"
5039 "@
5040 fdiv<s> %0,%1,%2
5041 xsdiv<sd>p %x0,%x1,%x2"
5042 [(set_attr "type" "<sd>div")
5043 (set_attr "isa" "*,<Fisa>")])
5044
5045 (define_insn "*sqrt<mode>2_internal"
5046 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,wa")
5047 (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "d,wa")))]
5048 "TARGET_HARD_FLOAT && TARGET_PPC_GPOPT"
5049 "@
5050 fsqrt<s> %0,%1
5051 xssqrt<sd>p %x0,%x1"
5052 [(set_attr "type" "<sd>sqrt")
5053 (set_attr "isa" "*,<Fisa>")])
5054
5055 (define_expand "sqrt<mode>2"
5056 [(set (match_operand:SFDF 0 "gpc_reg_operand")
5057 (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))]
5058 "TARGET_HARD_FLOAT && TARGET_PPC_GPOPT"
5059 {
5060 if (<MODE>mode == SFmode
5061 && TARGET_RECIP_PRECISION
5062 && RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)
5063 && !optimize_function_for_size_p (cfun)
5064 && flag_finite_math_only && !flag_trapping_math
5065 && flag_unsafe_math_optimizations)
5066 {
5067 rs6000_emit_swsqrt (operands[0], operands[1], 0);
5068 DONE;
5069 }
5070 })
5071
5072 ;; Floating point reciprocal approximation
5073 (define_insn "fre<sd>"
5074 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,wa")
5075 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "d,wa")]
5076 UNSPEC_FRES))]
5077 "TARGET_<FFRE>"
5078 "@
5079 fre<s> %0,%1
5080 xsre<sd>p %x0,%x1"
5081 [(set_attr "type" "fp")
5082 (set_attr "isa" "*,<Fisa>")])
5083
5084 (define_expand "fmod<mode>3"
5085 [(use (match_operand:SFDF 0 "gpc_reg_operand"))
5086 (use (match_operand:SFDF 1 "gpc_reg_operand"))
5087 (use (match_operand:SFDF 2 "gpc_reg_operand"))]
5088 "TARGET_HARD_FLOAT
5089 && TARGET_FPRND
5090 && flag_unsafe_math_optimizations"
5091 {
5092 rtx div = gen_reg_rtx (<MODE>mode);
5093 emit_insn (gen_div<mode>3 (div, operands[1], operands[2]));
5094
5095 rtx friz = gen_reg_rtx (<MODE>mode);
5096 emit_insn (gen_btrunc<mode>2 (friz, div));
5097
5098 emit_insn (gen_nfms<mode>4 (operands[0], operands[2], friz, operands[1]));
5099 DONE;
5100 })
5101
5102 (define_expand "remainder<mode>3"
5103 [(use (match_operand:SFDF 0 "gpc_reg_operand"))
5104 (use (match_operand:SFDF 1 "gpc_reg_operand"))
5105 (use (match_operand:SFDF 2 "gpc_reg_operand"))]
5106 "TARGET_HARD_FLOAT
5107 && TARGET_FPRND
5108 && flag_unsafe_math_optimizations"
5109 {
5110 rtx div = gen_reg_rtx (<MODE>mode);
5111 emit_insn (gen_div<mode>3 (div, operands[1], operands[2]));
5112
5113 rtx frin = gen_reg_rtx (<MODE>mode);
5114 emit_insn (gen_round<mode>2 (frin, div));
5115
5116 emit_insn (gen_nfms<mode>4 (operands[0], operands[2], frin, operands[1]));
5117 DONE;
5118 })
5119
5120 (define_insn "*rsqrt<mode>2"
5121 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,wa")
5122 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "d,wa")]
5123 UNSPEC_RSQRT))]
5124 "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
5125 "@
5126 frsqrte<s> %0,%1
5127 xsrsqrte<sd>p %x0,%x1"
5128 [(set_attr "type" "fp")
5129 (set_attr "isa" "*,<Fisa>")])
5130
5131 ;; Floating point comparisons
5132 (define_insn "*cmp<mode>_fpr"
5133 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y,y")
5134 (compare:CCFP (match_operand:SFDF 1 "gpc_reg_operand" "d,wa")
5135 (match_operand:SFDF 2 "gpc_reg_operand" "d,wa")))]
5136 "TARGET_HARD_FLOAT"
5137 "@
5138 fcmpu %0,%1,%2
5139 xscmpudp %0,%x1,%x2"
5140 [(set_attr "type" "fpcompare")
5141 (set_attr "isa" "*,<Fisa>")])
5142
5143 ;; Floating point conversions
5144 (define_expand "extendsfdf2"
5145 [(set (match_operand:DF 0 "gpc_reg_operand")
5146 (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand")))]
5147 "TARGET_HARD_FLOAT"
5148 {
5149 if (HONOR_SNANS (SFmode))
5150 operands[1] = force_reg (SFmode, operands[1]);
5151 })
5152
5153 (define_insn_and_split "*extendsfdf2_fpr"
5154 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d,d,wa,?wa,wa,v")
5155 (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand" "0,f,m,0,wa,Z,wY")))]
5156 "TARGET_HARD_FLOAT && !HONOR_SNANS (SFmode)"
5157 "@
5158 #
5159 fmr %0,%1
5160 lfs%U1%X1 %0,%1
5161 #
5162 xscpsgndp %x0,%x1,%x1
5163 lxsspx %x0,%y1
5164 lxssp %0,%1"
5165 "&& reload_completed && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1])"
5166 [(const_int 0)]
5167 {
5168 emit_note (NOTE_INSN_DELETED);
5169 DONE;
5170 }
5171 [(set_attr "type" "fp,fpsimple,fpload,fp,fpsimple,fpload,fpload")
5172 (set_attr "isa" "*,*,*,*,p8v,p8v,p9v")])
5173
5174 (define_insn "*extendsfdf2_snan"
5175 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa")
5176 (float_extend:DF (match_operand:SF 1 "gpc_reg_operand" "f,wa")))]
5177 "TARGET_HARD_FLOAT && HONOR_SNANS (SFmode)"
5178 "@
5179 frsp %0,%1
5180 xsrsp %x0,%x1"
5181 [(set_attr "type" "fp")
5182 (set_attr "isa" "*,p8v")])
5183
5184 (define_expand "truncdfsf2"
5185 [(set (match_operand:SF 0 "gpc_reg_operand")
5186 (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand")))]
5187 "TARGET_HARD_FLOAT"
5188 "")
5189
5190 (define_insn "*truncdfsf2_fpr"
5191 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wa")
5192 (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "d,wa")))]
5193 "TARGET_HARD_FLOAT"
5194 "@
5195 frsp %0,%1
5196 xsrsp %x0,%x1"
5197 [(set_attr "type" "fp")
5198 (set_attr "isa" "*,p8v")])
5199
5200 ;; This expander is here to avoid FLOAT_WORDS_BIGENDIAN tests in
5201 ;; builtins.cc and optabs.cc that are not correct for IBM long double
5202 ;; when little-endian.
5203 (define_expand "signbit<mode>2"
5204 [(set (match_dup 2)
5205 (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand")))
5206 (set (match_dup 3)
5207 (subreg:DI (match_dup 2) 0))
5208 (set (match_dup 4)
5209 (match_dup 5))
5210 (set (match_operand:SI 0 "gpc_reg_operand")
5211 (match_dup 6))]
5212 "TARGET_HARD_FLOAT
5213 && (!FLOAT128_IEEE_P (<MODE>mode)
5214 || (TARGET_POWERPC64 && TARGET_DIRECT_MOVE))"
5215 {
5216 if (FLOAT128_IEEE_P (<MODE>mode))
5217 {
5218 rtx dest = operands[0];
5219 rtx src = operands[1];
5220 rtx tmp = gen_reg_rtx (DImode);
5221 rtx dest_di = gen_lowpart (DImode, dest);
5222
5223 emit_insn (gen_signbit2_dm (<MODE>mode, tmp, src));
5224 emit_insn (gen_lshrdi3 (dest_di, tmp, GEN_INT (63)));
5225 DONE;
5226 }
5227 operands[2] = gen_reg_rtx (DFmode);
5228 operands[3] = gen_reg_rtx (DImode);
5229 if (TARGET_POWERPC64)
5230 {
5231 operands[4] = gen_reg_rtx (DImode);
5232 operands[5] = gen_rtx_LSHIFTRT (DImode, operands[3], GEN_INT (63));
5233 operands[6] = gen_rtx_SUBREG (SImode, operands[4],
5234 WORDS_BIG_ENDIAN ? 4 : 0);
5235 }
5236 else
5237 {
5238 operands[4] = gen_reg_rtx (SImode);
5239 operands[5] = gen_rtx_SUBREG (SImode, operands[3],
5240 WORDS_BIG_ENDIAN ? 0 : 4);
5241 operands[6] = gen_rtx_LSHIFTRT (SImode, operands[4], GEN_INT (31));
5242 }
5243 })
5244
5245 ;; Optimize IEEE 128-bit signbit on 64-bit systems with direct move to avoid
5246 ;; multiple direct moves. If we used a SUBREG:DI of the Floa128 type, the
5247 ;; register allocator would typically move the entire _Float128 item to GPRs (2
5248 ;; instructions on ISA 3.0, 3-4 instructions on ISA 2.07).
5249 ;;
5250 ;; After register allocation, if the _Float128 had originally been in GPRs, the
5251 ;; split allows the post reload phases to eliminate the move, and do the shift
5252 ;; directly with the register that contains the signbit.
5253 (define_insn_and_split "@signbit<mode>2_dm"
5254 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
5255 (unspec:DI [(match_operand:SIGNBIT 1 "gpc_reg_operand" "wa,r")]
5256 UNSPEC_SIGNBIT))]
5257 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
5258 "@
5259 mfvsrd %0,%x1
5260 #"
5261 "&& reload_completed && int_reg_operand (operands[1], <MODE>mode)"
5262 [(set (match_dup 0)
5263 (match_dup 2))]
5264 {
5265 operands[2] = gen_highpart (DImode, operands[1]);
5266 }
5267 [(set_attr "type" "mfvsr,*")])
5268
5269 ;; Optimize IEEE 128-bit signbit on to avoid loading the value into a vector
5270 ;; register and then doing a direct move if the value comes from memory. On
5271 ;; little endian, we have to load the 2nd double-word to get the sign bit.
5272 (define_insn_and_split "*signbit<mode>2_dm_mem"
5273 [(set (match_operand:DI 0 "gpc_reg_operand" "=b")
5274 (unspec:DI [(match_operand:SIGNBIT 1 "memory_operand" "m")]
5275 UNSPEC_SIGNBIT))]
5276 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
5277 "#"
5278 "&& 1"
5279 [(set (match_dup 0)
5280 (match_dup 2))]
5281 {
5282 rtx dest = operands[0];
5283 rtx src = operands[1];
5284 rtx addr = XEXP (src, 0);
5285
5286 if (WORDS_BIG_ENDIAN)
5287 operands[2] = adjust_address (src, DImode, 0);
5288
5289 else if (REG_P (addr) || SUBREG_P (addr))
5290 operands[2] = adjust_address (src, DImode, 8);
5291
5292 else if (GET_CODE (addr) == PLUS && REG_P (XEXP (addr, 0))
5293 && CONST_INT_P (XEXP (addr, 1)) && mem_operand_gpr (src, DImode))
5294 operands[2] = adjust_address (src, DImode, 8);
5295
5296 else
5297 {
5298 rtx tmp = can_create_pseudo_p () ? gen_reg_rtx (DImode) : dest;
5299 emit_insn (gen_rtx_SET (tmp, addr));
5300 operands[2] = change_address (src, DImode,
5301 gen_rtx_PLUS (DImode, tmp, GEN_INT (8)));
5302 }
5303 })
5304
5305 (define_expand "copysign<mode>3"
5306 [(set (match_dup 3)
5307 (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))
5308 (set (match_dup 4)
5309 (neg:SFDF (abs:SFDF (match_dup 1))))
5310 (set (match_operand:SFDF 0 "gpc_reg_operand")
5311 (if_then_else:SFDF (ge (match_operand:SFDF 2 "gpc_reg_operand")
5312 (match_dup 5))
5313 (match_dup 3)
5314 (match_dup 4)))]
5315 "TARGET_HARD_FLOAT
5316 && ((TARGET_PPC_GFXOPT
5317 && !HONOR_NANS (<MODE>mode)
5318 && !HONOR_SIGNED_ZEROS (<MODE>mode))
5319 || TARGET_CMPB
5320 || VECTOR_UNIT_VSX_P (<MODE>mode))"
5321 {
5322 if (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode))
5323 {
5324 emit_insn (gen_copysign<mode>3_fcpsgn (operands[0], operands[1],
5325 operands[2]));
5326 DONE;
5327 }
5328
5329 operands[3] = gen_reg_rtx (<MODE>mode);
5330 operands[4] = gen_reg_rtx (<MODE>mode);
5331 operands[5] = CONST0_RTX (<MODE>mode);
5332 })
5333
5334 ;; Use an unspec rather providing an if-then-else in RTL, to prevent the
5335 ;; compiler from optimizing -0.0
5336 (define_insn "copysign<mode>3_fcpsgn"
5337 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,wa")
5338 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "d,wa")
5339 (match_operand:SFDF 2 "gpc_reg_operand" "d,wa")]
5340 UNSPEC_COPYSIGN))]
5341 "TARGET_HARD_FLOAT && (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode))"
5342 "@
5343 fcpsgn %0,%2,%1
5344 xscpsgndp %x0,%x2,%x1"
5345 [(set_attr "type" "fpsimple")])
5346
5347 ;; For MIN, MAX, and conditional move, we use DEFINE_EXPAND's that involve a
5348 ;; fsel instruction and some auxiliary computations. Then we just have a
5349 ;; single DEFINE_INSN for fsel and the define_splits to make them if made by
5350 ;; combine.
5351 ;; For MIN, MAX on non-VSX machines, and conditional move all of the time, we
5352 ;; use DEFINE_EXPAND's that involve a fsel instruction and some auxiliary
5353 ;; computations. Then we just have a single DEFINE_INSN for fsel and the
5354 ;; define_splits to make them if made by combine. On VSX machines we have the
5355 ;; min/max instructions.
5356 ;;
5357 ;; On VSX, we only check for TARGET_VSX instead of checking for a vsx/p8 vector
5358 ;; to allow either DF/SF to use only traditional registers.
5359
5360 (define_expand "s<minmax><mode>3"
5361 [(set (match_operand:SFDF 0 "gpc_reg_operand")
5362 (fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
5363 (match_operand:SFDF 2 "gpc_reg_operand")))]
5364 "TARGET_MINMAX"
5365 {
5366 rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]);
5367 DONE;
5368 })
5369
5370 (define_insn "*s<minmax><mode>3_vsx"
5371 [(set (match_operand:SFDF 0 "vsx_register_operand" "=wa")
5372 (fp_minmax:SFDF (match_operand:SFDF 1 "vsx_register_operand" "wa")
5373 (match_operand:SFDF 2 "vsx_register_operand" "wa")))]
5374 "TARGET_VSX && TARGET_HARD_FLOAT"
5375 {
5376 return (TARGET_P9_MINMAX
5377 ? "xs<minmax>cdp %x0,%x1,%x2"
5378 : "xs<minmax>dp %x0,%x1,%x2");
5379 }
5380 [(set_attr "type" "fp")])
5381
5382 ;; Min/max for ISA 3.1 IEEE 128-bit floating point
5383 (define_insn "s<minmax><mode>3"
5384 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
5385 (fp_minmax:IEEE128
5386 (match_operand:IEEE128 1 "altivec_register_operand" "v")
5387 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
5388 "TARGET_POWER10 && TARGET_FLOAT128_HW"
5389 "xs<minmax>cqp %0,%1,%2"
5390 [(set_attr "type" "vecfloat")
5391 (set_attr "size" "128")])
5392
5393 ;; The conditional move instructions allow us to perform max and min operations
5394 ;; even when we don't have the appropriate max/min instruction using the FSEL
5395 ;; instruction.
5396
5397 (define_insn_and_split "*s<minmax><mode>3_fpr"
5398 [(set (match_operand:SFDF 0 "gpc_reg_operand")
5399 (fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
5400 (match_operand:SFDF 2 "gpc_reg_operand")))]
5401 "!TARGET_VSX && TARGET_MINMAX"
5402 "#"
5403 "&& 1"
5404 [(const_int 0)]
5405 {
5406 rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]);
5407 DONE;
5408 })
5409
5410 (define_expand "mov<mode>cc"
5411 [(set (match_operand:GPR 0 "gpc_reg_operand")
5412 (if_then_else:GPR (match_operand 1 "comparison_operator")
5413 (match_operand:GPR 2 "gpc_reg_operand")
5414 (match_operand:GPR 3 "gpc_reg_operand")))]
5415 "TARGET_ISEL"
5416 {
5417 if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
5418 DONE;
5419 else
5420 FAIL;
5421 })
5422
5423 ;; We use the BASE_REGS for the isel input operands because, if rA is
5424 ;; 0, the value of 0 is placed in rD upon truth. Similarly for rB
5425 ;; because we may switch the operands and rB may end up being rA.
5426 ;;
5427 ;; We need 2 patterns: an unsigned and a signed pattern. We could
5428 ;; leave out the mode in operand 4 and use one pattern, but reload can
5429 ;; change the mode underneath our feet and then gets confused trying
5430 ;; to reload the value.
5431 (define_mode_iterator CCANY [CC CCUNS])
5432 (define_insn "isel_<CCANY:mode>_<GPR:mode>"
5433 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
5434 (if_then_else:GPR
5435 (match_operator 1 "scc_comparison_operator"
5436 [(match_operand:CCANY 4 "cc_reg_operand" "y,y")
5437 (const_int 0)])
5438 (match_operand:GPR 2 "reg_or_zero_operand" "O,b")
5439 (match_operand:GPR 3 "gpc_reg_operand" "r,r")))]
5440 "TARGET_ISEL"
5441 "isel %0,%2,%3,%j1"
5442 [(set_attr "type" "isel")])
5443
5444 ;; These patterns can be useful for combine; they let combine know that
5445 ;; isel can handle reversed comparisons so long as the operands are
5446 ;; registers.
5447
5448 (define_insn "*isel_reversed_<CCANY:mode>_<GPR:mode>"
5449 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
5450 (if_then_else:GPR
5451 (match_operator 1 "scc_rev_comparison_operator"
5452 [(match_operand:CCANY 4 "cc_reg_operand" "y,y")
5453 (const_int 0)])
5454 (match_operand:GPR 2 "gpc_reg_operand" "r,r")
5455 (match_operand:GPR 3 "reg_or_zero_operand" "O,b")))]
5456 "TARGET_ISEL"
5457 {
5458 PUT_CODE (operands[1], reverse_condition (GET_CODE (operands[1])));
5459 return "isel %0,%3,%2,%j1";
5460 }
5461 [(set_attr "type" "isel")])
5462
5463 ; Set Boolean Condition (Reverse)
5464 (define_insn "setbc_<CCANY:mode>_<GPR:mode>"
5465 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
5466 (match_operator:GPR 1 "scc_comparison_operator"
5467 [(match_operand:CCANY 2 "cc_reg_operand" "y")
5468 (const_int 0)]))]
5469 "TARGET_POWER10"
5470 "setbc %0,%j1"
5471 [(set_attr "type" "isel")])
5472
5473 (define_insn "*setbcr_<CCANY:mode>_<GPR:mode>"
5474 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
5475 (match_operator:GPR 1 "scc_rev_comparison_operator"
5476 [(match_operand:CCANY 2 "cc_reg_operand" "y")
5477 (const_int 0)]))]
5478 "TARGET_POWER10"
5479 "setbcr %0,%j1"
5480 [(set_attr "type" "isel")])
5481
5482 ; Set Negative Boolean Condition (Reverse)
5483 (define_insn "*setnbc_<CCANY:mode>_<GPR:mode>"
5484 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
5485 (neg:GPR (match_operator:GPR 1 "scc_comparison_operator"
5486 [(match_operand:CCANY 2 "cc_reg_operand" "y")
5487 (const_int 0)])))]
5488 "TARGET_POWER10"
5489 "setnbc %0,%j1"
5490 [(set_attr "type" "isel")])
5491
5492 (define_insn "*setnbcr_<CCANY:mode>_<GPR:mode>"
5493 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
5494 (neg:GPR (match_operator:GPR 1 "scc_rev_comparison_operator"
5495 [(match_operand:CCANY 2 "cc_reg_operand" "y")
5496 (const_int 0)])))]
5497 "TARGET_POWER10"
5498 "setnbcr %0,%j1"
5499 [(set_attr "type" "isel")])
5500
5501 ;; Floating point conditional move
5502 (define_expand "mov<mode>cc"
5503 [(set (match_operand:SFDF 0 "gpc_reg_operand")
5504 (if_then_else:SFDF (match_operand 1 "comparison_operator")
5505 (match_operand:SFDF 2 "gpc_reg_operand")
5506 (match_operand:SFDF 3 "gpc_reg_operand")))]
5507 "TARGET_HARD_FLOAT && TARGET_PPC_GFXOPT"
5508 {
5509 if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
5510 DONE;
5511 else
5512 FAIL;
5513 })
5514
5515 (define_insn "*fsel<SFDF:mode><SFDF2:mode>4"
5516 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=&<SFDF:rreg2>")
5517 (if_then_else:SFDF
5518 (ge (match_operand:SFDF2 1 "gpc_reg_operand" "<SFDF2:rreg2>")
5519 (match_operand:SFDF2 4 "zero_fp_constant" "F"))
5520 (match_operand:SFDF 2 "gpc_reg_operand" "<SFDF:rreg2>")
5521 (match_operand:SFDF 3 "gpc_reg_operand" "<SFDF:rreg2>")))]
5522 "TARGET_HARD_FLOAT && TARGET_PPC_GFXOPT"
5523 "fsel %0,%1,%2,%3"
5524 [(set_attr "type" "fp")])
5525
5526 (define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_p9"
5527 [(set (match_operand:SFDF 0 "vsx_register_operand" "=&wa,wa")
5528 (if_then_else:SFDF
5529 (match_operator:CCFP 1 "fpmask_comparison_operator"
5530 [(match_operand:SFDF2 2 "vsx_register_operand" "wa,wa")
5531 (match_operand:SFDF2 3 "vsx_register_operand" "wa,wa")])
5532 (match_operand:SFDF 4 "vsx_register_operand" "wa,wa")
5533 (match_operand:SFDF 5 "vsx_register_operand" "wa,wa")))
5534 (clobber (match_scratch:V2DI 6 "=0,&wa"))]
5535 "TARGET_P9_MINMAX"
5536 "#"
5537 "&& 1"
5538 [(set (match_dup 6)
5539 (if_then_else:V2DI (match_dup 1)
5540 (match_dup 7)
5541 (match_dup 8)))
5542 (set (match_dup 0)
5543 (if_then_else:SFDF (ne (match_dup 6)
5544 (match_dup 8))
5545 (match_dup 4)
5546 (match_dup 5)))]
5547 {
5548 if (GET_CODE (operands[6]) == SCRATCH)
5549 operands[6] = gen_reg_rtx (V2DImode);
5550
5551 operands[7] = CONSTM1_RTX (V2DImode);
5552 operands[8] = CONST0_RTX (V2DImode);
5553 }
5554 [(set_attr "length" "8")
5555 (set_attr "type" "vecperm")])
5556
5557 ;; Handle inverting the fpmask comparisons.
5558 (define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_invert_p9"
5559 [(set (match_operand:SFDF 0 "vsx_register_operand" "=&wa,wa")
5560 (if_then_else:SFDF
5561 (match_operator:CCFP 1 "invert_fpmask_comparison_operator"
5562 [(match_operand:SFDF2 2 "vsx_register_operand" "wa,wa")
5563 (match_operand:SFDF2 3 "vsx_register_operand" "wa,wa")])
5564 (match_operand:SFDF 4 "vsx_register_operand" "wa,wa")
5565 (match_operand:SFDF 5 "vsx_register_operand" "wa,wa")))
5566 (clobber (match_scratch:V2DI 6 "=0,&wa"))]
5567 "TARGET_P9_MINMAX"
5568 "#"
5569 "&& 1"
5570 [(set (match_dup 6)
5571 (if_then_else:V2DI (match_dup 9)
5572 (match_dup 7)
5573 (match_dup 8)))
5574 (set (match_dup 0)
5575 (if_then_else:SFDF (ne (match_dup 6)
5576 (match_dup 8))
5577 (match_dup 5)
5578 (match_dup 4)))]
5579 {
5580 rtx op1 = operands[1];
5581 enum rtx_code cond = reverse_condition_maybe_unordered (GET_CODE (op1));
5582
5583 if (GET_CODE (operands[6]) == SCRATCH)
5584 operands[6] = gen_reg_rtx (V2DImode);
5585
5586 operands[7] = CONSTM1_RTX (V2DImode);
5587 operands[8] = CONST0_RTX (V2DImode);
5588
5589 operands[9] = gen_rtx_fmt_ee (cond, CCFPmode, operands[2], operands[3]);
5590 }
5591 [(set_attr "length" "8")
5592 (set_attr "type" "vecperm")])
5593
5594 (define_insn "*fpmask<mode>"
5595 [(set (match_operand:V2DI 0 "vsx_register_operand" "=wa")
5596 (if_then_else:V2DI
5597 (match_operator:CCFP 1 "fpmask_comparison_operator"
5598 [(match_operand:SFDF 2 "vsx_register_operand" "wa")
5599 (match_operand:SFDF 3 "vsx_register_operand" "wa")])
5600 (match_operand:V2DI 4 "all_ones_constant" "")
5601 (match_operand:V2DI 5 "zero_constant" "")))]
5602 "TARGET_P9_MINMAX"
5603 "xscmp%V1dp %x0,%x2,%x3"
5604 [(set_attr "type" "fpcompare")])
5605
5606 (define_insn "*xxsel<mode>"
5607 [(set (match_operand:SFDF 0 "vsx_register_operand" "=wa")
5608 (if_then_else:SFDF (ne (match_operand:V2DI 1 "vsx_register_operand" "wa")
5609 (match_operand:V2DI 2 "zero_constant" ""))
5610 (match_operand:SFDF 3 "vsx_register_operand" "wa")
5611 (match_operand:SFDF 4 "vsx_register_operand" "wa")))]
5612 "TARGET_P9_MINMAX"
5613 "xxsel %x0,%x4,%x3,%x1"
5614 [(set_attr "type" "vecmove")])
5615
5616 ;; Support for ISA 3.1 IEEE 128-bit conditional move. The mode used in the
5617 ;; comparison must be the same as used in the move.
5618 (define_expand "mov<mode>cc"
5619 [(set (match_operand:IEEE128 0 "gpc_reg_operand")
5620 (if_then_else:IEEE128 (match_operand 1 "comparison_operator")
5621 (match_operand:IEEE128 2 "gpc_reg_operand")
5622 (match_operand:IEEE128 3 "gpc_reg_operand")))]
5623 "TARGET_POWER10 && TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
5624 {
5625 if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
5626 DONE;
5627 else
5628 FAIL;
5629 })
5630
5631 (define_insn_and_split "*mov<mode>cc_p10"
5632 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=&v,v")
5633 (if_then_else:IEEE128
5634 (match_operator:CCFP 1 "fpmask_comparison_operator"
5635 [(match_operand:IEEE128 2 "altivec_register_operand" "v,v")
5636 (match_operand:IEEE128 3 "altivec_register_operand" "v,v")])
5637 (match_operand:IEEE128 4 "altivec_register_operand" "v,v")
5638 (match_operand:IEEE128 5 "altivec_register_operand" "v,v")))
5639 (clobber (match_scratch:V2DI 6 "=0,&v"))]
5640 "TARGET_POWER10 && TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
5641 "#"
5642 "&& 1"
5643 [(set (match_dup 6)
5644 (if_then_else:V2DI (match_dup 1)
5645 (match_dup 7)
5646 (match_dup 8)))
5647 (set (match_dup 0)
5648 (if_then_else:IEEE128 (ne (match_dup 6)
5649 (match_dup 8))
5650 (match_dup 4)
5651 (match_dup 5)))]
5652 {
5653 if (GET_CODE (operands[6]) == SCRATCH)
5654 operands[6] = gen_reg_rtx (V2DImode);
5655
5656 operands[7] = CONSTM1_RTX (V2DImode);
5657 operands[8] = CONST0_RTX (V2DImode);
5658 }
5659 [(set_attr "length" "8")
5660 (set_attr "type" "vecperm")])
5661
5662 ;; Handle inverting the fpmask comparisons.
5663 (define_insn_and_split "*mov<mode>cc_invert_p10"
5664 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=&v,v")
5665 (if_then_else:IEEE128
5666 (match_operator:CCFP 1 "invert_fpmask_comparison_operator"
5667 [(match_operand:IEEE128 2 "altivec_register_operand" "v,v")
5668 (match_operand:IEEE128 3 "altivec_register_operand" "v,v")])
5669 (match_operand:IEEE128 4 "altivec_register_operand" "v,v")
5670 (match_operand:IEEE128 5 "altivec_register_operand" "v,v")))
5671 (clobber (match_scratch:V2DI 6 "=0,&v"))]
5672 "TARGET_POWER10 && TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
5673 "#"
5674 "&& 1"
5675 [(set (match_dup 6)
5676 (if_then_else:V2DI (match_dup 9)
5677 (match_dup 7)
5678 (match_dup 8)))
5679 (set (match_dup 0)
5680 (if_then_else:IEEE128 (ne (match_dup 6)
5681 (match_dup 8))
5682 (match_dup 5)
5683 (match_dup 4)))]
5684 {
5685 rtx op1 = operands[1];
5686 enum rtx_code cond = reverse_condition_maybe_unordered (GET_CODE (op1));
5687
5688 if (GET_CODE (operands[6]) == SCRATCH)
5689 operands[6] = gen_reg_rtx (V2DImode);
5690
5691 operands[7] = CONSTM1_RTX (V2DImode);
5692 operands[8] = CONST0_RTX (V2DImode);
5693
5694 operands[9] = gen_rtx_fmt_ee (cond, CCFPmode, operands[2], operands[3]);
5695 }
5696 [(set_attr "length" "8")
5697 (set_attr "type" "vecperm")])
5698
5699 (define_insn "*fpmask<mode>"
5700 [(set (match_operand:V2DI 0 "altivec_register_operand" "=v")
5701 (if_then_else:V2DI
5702 (match_operator:CCFP 1 "fpmask_comparison_operator"
5703 [(match_operand:IEEE128 2 "altivec_register_operand" "v")
5704 (match_operand:IEEE128 3 "altivec_register_operand" "v")])
5705 (match_operand:V2DI 4 "all_ones_constant" "")
5706 (match_operand:V2DI 5 "zero_constant" "")))]
5707 "TARGET_POWER10 && TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
5708 "xscmp%V1qp %0,%2,%3"
5709 [(set_attr "type" "fpcompare")])
5710
5711 (define_insn "*xxsel<mode>"
5712 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
5713 (if_then_else:IEEE128
5714 (ne (match_operand:V2DI 1 "altivec_register_operand" "v")
5715 (match_operand:V2DI 2 "zero_constant" ""))
5716 (match_operand:IEEE128 3 "altivec_register_operand" "v")
5717 (match_operand:IEEE128 4 "altivec_register_operand" "v")))]
5718 "TARGET_POWER10 && TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
5719 "xxsel %x0,%x4,%x3,%x1"
5720 [(set_attr "type" "vecmove")])
5721
5722 \f
5723 ;; Conversions to and from floating-point.
5724
5725 ; We don't define lfiwax/lfiwzx with the normal definition, because we
5726 ; don't want to support putting SImode in FPR registers.
5727 (define_insn "lfiwax"
5728 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa,wa,v")
5729 (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r,v")]
5730 UNSPEC_LFIWAX))]
5731 "TARGET_HARD_FLOAT && TARGET_LFIWAX"
5732 "@
5733 lfiwax %0,%y1
5734 lxsiwax %x0,%y1
5735 mtvsrwa %x0,%1
5736 vextsw2d %0,%1"
5737 [(set_attr "type" "fpload,fpload,mtvsr,vecexts")
5738 (set_attr "isa" "*,p8v,p8v,p9v")])
5739
5740 ; This split must be run before register allocation because it allocates the
5741 ; memory slot that is needed to move values to/from the FPR. We don't allocate
5742 ; it earlier to allow for the combiner to merge insns together where it might
5743 ; not be needed and also in case the insns are deleted as dead code.
5744
5745 (define_insn_and_split "floatsi<mode>2_lfiwax"
5746 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,wa")
5747 (float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r,r")))
5748 (clobber (match_scratch:DI 2 "=d,wa"))]
5749 "TARGET_HARD_FLOAT && TARGET_LFIWAX
5750 && <SI_CONVERT_FP> && can_create_pseudo_p ()"
5751 "#"
5752 "&& 1"
5753 [(pc)]
5754 {
5755 rtx dest = operands[0];
5756 rtx src = operands[1];
5757 rtx tmp;
5758
5759 if (!MEM_P (src) && TARGET_POWERPC64 && TARGET_DIRECT_MOVE)
5760 tmp = convert_to_mode (DImode, src, false);
5761 else
5762 {
5763 tmp = operands[2];
5764 if (GET_CODE (tmp) == SCRATCH)
5765 tmp = gen_reg_rtx (DImode);
5766 if (MEM_P (src))
5767 {
5768 src = rs6000_force_indexed_or_indirect_mem (src);
5769 emit_insn (gen_lfiwax (tmp, src));
5770 }
5771 else
5772 {
5773 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5774 emit_move_insn (stack, src);
5775 emit_insn (gen_lfiwax (tmp, stack));
5776 }
5777 }
5778 emit_insn (gen_floatdi<mode>2 (dest, tmp));
5779 DONE;
5780 }
5781 [(set_attr "length" "12")
5782 (set_attr "type" "fpload")])
5783
5784 (define_insn_and_split "floatsi<mode>2_lfiwax_mem"
5785 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,wa")
5786 (float:SFDF
5787 (sign_extend:DI
5788 (match_operand:SI 1 "indexed_or_indirect_operand" "Z,Z"))))
5789 (clobber (match_scratch:DI 2 "=d,wa"))]
5790 "TARGET_HARD_FLOAT && TARGET_LFIWAX && <SI_CONVERT_FP>"
5791 "#"
5792 "&& 1"
5793 [(pc)]
5794 {
5795 operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
5796 if (GET_CODE (operands[2]) == SCRATCH)
5797 operands[2] = gen_reg_rtx (DImode);
5798 if (TARGET_P8_VECTOR)
5799 emit_insn (gen_extendsidi2 (operands[2], operands[1]));
5800 else
5801 emit_insn (gen_lfiwax (operands[2], operands[1]));
5802 emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
5803 DONE;
5804 }
5805 [(set_attr "length" "8")
5806 (set_attr "type" "fpload")])
5807
5808 (define_insn_and_split "floatsi<SFDF:mode>2_lfiwax_<QHI:mode>_mem_zext"
5809 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,wa")
5810 (float:SFDF
5811 (zero_extend:SI
5812 (match_operand:QHI 1 "indexed_or_indirect_operand" "Z,Z"))))
5813 (clobber (match_scratch:DI 2 "=d,wa"))]
5814 "TARGET_HARD_FLOAT && <SI_CONVERT_FP> && TARGET_P9_VECTOR
5815 && TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
5816 "#"
5817 "&& 1"
5818 [(pc)]
5819 {
5820 if (GET_CODE (operands[2]) == SCRATCH)
5821 operands[2] = gen_reg_rtx (DImode);
5822 emit_insn (gen_zero_extendhidi2 (operands[2], operands[1]));
5823 emit_insn (gen_floatdi<SFDF:mode>2 (operands[0], operands[2]));
5824 DONE;
5825 }
5826 [(set_attr "length" "8")
5827 (set_attr "type" "fpload")])
5828
5829 (define_insn "lfiwzx"
5830 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa,wa,wa")
5831 (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r,wa")]
5832 UNSPEC_LFIWZX))]
5833 "TARGET_HARD_FLOAT && TARGET_LFIWZX"
5834 "@
5835 lfiwzx %0,%y1
5836 lxsiwzx %x0,%y1
5837 mtvsrwz %x0,%1
5838 xxextractuw %x0,%x1,4"
5839 [(set_attr "type" "fpload,fpload,mtvsr,vecexts")
5840 (set_attr "isa" "*,p8v,p8v,p9v")])
5841
5842 (define_insn_and_split "floatunssi<mode>2_lfiwzx"
5843 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,wa")
5844 (unsigned_float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r,r")))
5845 (clobber (match_scratch:DI 2 "=d,wa"))]
5846 "TARGET_HARD_FLOAT && TARGET_LFIWZX && <SI_CONVERT_FP>"
5847 "#"
5848 "&& 1"
5849 [(pc)]
5850 {
5851 rtx dest = operands[0];
5852 rtx src = operands[1];
5853 rtx tmp;
5854
5855 if (!MEM_P (src) && TARGET_POWERPC64 && TARGET_DIRECT_MOVE)
5856 tmp = convert_to_mode (DImode, src, true);
5857 else
5858 {
5859 tmp = operands[2];
5860 if (GET_CODE (tmp) == SCRATCH)
5861 tmp = gen_reg_rtx (DImode);
5862 if (MEM_P (src))
5863 {
5864 src = rs6000_force_indexed_or_indirect_mem (src);
5865 emit_insn (gen_lfiwzx (tmp, src));
5866 }
5867 else
5868 {
5869 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5870 emit_move_insn (stack, src);
5871 emit_insn (gen_lfiwzx (tmp, stack));
5872 }
5873 }
5874 emit_insn (gen_floatdi<mode>2 (dest, tmp));
5875 DONE;
5876 }
5877 [(set_attr "length" "12")
5878 (set_attr "type" "fpload")])
5879
5880 (define_insn_and_split "floatunssi<mode>2_lfiwzx_mem"
5881 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,wa")
5882 (unsigned_float:SFDF
5883 (zero_extend:DI
5884 (match_operand:SI 1 "indexed_or_indirect_operand" "Z,Z"))))
5885 (clobber (match_scratch:DI 2 "=d,wa"))]
5886 "TARGET_HARD_FLOAT && TARGET_LFIWZX && <SI_CONVERT_FP>"
5887 "#"
5888 "&& 1"
5889 [(pc)]
5890 {
5891 operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
5892 if (GET_CODE (operands[2]) == SCRATCH)
5893 operands[2] = gen_reg_rtx (DImode);
5894 if (TARGET_P8_VECTOR)
5895 emit_insn (gen_zero_extendsidi2 (operands[2], operands[1]));
5896 else
5897 emit_insn (gen_lfiwzx (operands[2], operands[1]));
5898 emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
5899 DONE;
5900 }
5901 [(set_attr "length" "8")
5902 (set_attr "type" "fpload")])
5903
5904 ; For each of these conversions, there is a define_expand, a define_insn
5905 ; with a '#' template, and a define_split (with C code). The idea is
5906 ; to allow constant folding with the template of the define_insn,
5907 ; then to have the insns split later (between sched1 and final).
5908
5909 (define_expand "floatsidf2"
5910 [(parallel [(set (match_operand:DF 0 "gpc_reg_operand")
5911 (float:DF (match_operand:SI 1 "nonimmediate_operand")))
5912 (use (match_dup 2))
5913 (use (match_dup 3))
5914 (clobber (match_dup 4))
5915 (clobber (match_dup 5))
5916 (clobber (match_dup 6))])]
5917 "TARGET_HARD_FLOAT"
5918 {
5919 if (TARGET_LFIWAX && TARGET_FCFID)
5920 {
5921 emit_insn (gen_floatsidf2_lfiwax (operands[0], operands[1]));
5922 DONE;
5923 }
5924 else if (TARGET_FCFID)
5925 {
5926 rtx dreg = operands[1];
5927 if (!REG_P (dreg))
5928 dreg = force_reg (SImode, dreg);
5929 dreg = convert_to_mode (DImode, dreg, false);
5930 emit_insn (gen_floatdidf2 (operands[0], dreg));
5931 DONE;
5932 }
5933
5934 if (!REG_P (operands[1]))
5935 operands[1] = force_reg (SImode, operands[1]);
5936 operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5937 operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503601774854144\", DFmode));
5938 operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5939 operands[5] = gen_reg_rtx (DFmode);
5940 operands[6] = gen_reg_rtx (SImode);
5941 })
5942
5943 (define_insn_and_split "*floatsidf2_internal"
5944 [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5945 (float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5946 (use (match_operand:SI 2 "gpc_reg_operand" "r"))
5947 (use (match_operand:DF 3 "gpc_reg_operand" "d"))
5948 (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
5949 (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))
5950 (clobber (match_operand:SI 6 "gpc_reg_operand" "=&r"))]
5951 "!TARGET_FCFID && TARGET_HARD_FLOAT"
5952 "#"
5953 "&& 1"
5954 [(pc)]
5955 {
5956 rtx lowword, highword;
5957 gcc_assert (MEM_P (operands[4]));
5958 highword = adjust_address (operands[4], SImode, 0);
5959 lowword = adjust_address (operands[4], SImode, 4);
5960 if (! WORDS_BIG_ENDIAN)
5961 std::swap (lowword, highword);
5962
5963 emit_insn (gen_xorsi3 (operands[6], operands[1],
5964 GEN_INT (~ (HOST_WIDE_INT) 0x7fffffff)));
5965 emit_move_insn (lowword, operands[6]);
5966 emit_move_insn (highword, operands[2]);
5967 emit_move_insn (operands[5], operands[4]);
5968 emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5969 DONE;
5970 }
5971 [(set_attr "length" "24")
5972 (set_attr "type" "fp")])
5973
5974 ;; If we don't have a direct conversion to single precision, don't enable this
5975 ;; conversion for 32-bit without fast math, because we don't have the insn to
5976 ;; generate the fixup swizzle to avoid double rounding problems.
5977 (define_expand "floatunssisf2"
5978 [(set (match_operand:SF 0 "gpc_reg_operand")
5979 (unsigned_float:SF (match_operand:SI 1 "nonimmediate_operand")))]
5980 "TARGET_HARD_FLOAT
5981 && ((TARGET_FCFIDUS && TARGET_LFIWZX)
5982 || (TARGET_FCFID
5983 && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))"
5984 {
5985 if (TARGET_LFIWZX && TARGET_FCFIDUS)
5986 {
5987 emit_insn (gen_floatunssisf2_lfiwzx (operands[0], operands[1]));
5988 DONE;
5989 }
5990 else
5991 {
5992 rtx dreg = operands[1];
5993 if (!REG_P (dreg))
5994 dreg = force_reg (SImode, dreg);
5995 dreg = convert_to_mode (DImode, dreg, true);
5996 emit_insn (gen_floatdisf2 (operands[0], dreg));
5997 DONE;
5998 }
5999 })
6000
6001 (define_expand "floatunssidf2"
6002 [(parallel [(set (match_operand:DF 0 "gpc_reg_operand")
6003 (unsigned_float:DF (match_operand:SI 1 "nonimmediate_operand")))
6004 (use (match_dup 2))
6005 (use (match_dup 3))
6006 (clobber (match_dup 4))
6007 (clobber (match_dup 5))])]
6008 "TARGET_HARD_FLOAT"
6009 {
6010 if (TARGET_LFIWZX && TARGET_FCFID)
6011 {
6012 emit_insn (gen_floatunssidf2_lfiwzx (operands[0], operands[1]));
6013 DONE;
6014 }
6015 else if (TARGET_FCFID)
6016 {
6017 rtx dreg = operands[1];
6018 if (!REG_P (dreg))
6019 dreg = force_reg (SImode, dreg);
6020 dreg = convert_to_mode (DImode, dreg, true);
6021 emit_insn (gen_floatdidf2 (operands[0], dreg));
6022 DONE;
6023 }
6024
6025 if (!REG_P (operands[1]))
6026 operands[1] = force_reg (SImode, operands[1]);
6027 operands[2] = force_reg (SImode, GEN_INT (0x43300000));
6028 operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503599627370496\", DFmode));
6029 operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
6030 operands[5] = gen_reg_rtx (DFmode);
6031 })
6032
6033 (define_insn_and_split "*floatunssidf2_internal"
6034 [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
6035 (unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
6036 (use (match_operand:SI 2 "gpc_reg_operand" "r"))
6037 (use (match_operand:DF 3 "gpc_reg_operand" "d"))
6038 (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
6039 (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))]
6040 "!TARGET_FCFIDU && TARGET_HARD_FLOAT
6041 && !(TARGET_FCFID && TARGET_POWERPC64)"
6042 "#"
6043 "&& 1"
6044 [(pc)]
6045 {
6046 rtx lowword, highword;
6047 gcc_assert (MEM_P (operands[4]));
6048 highword = adjust_address (operands[4], SImode, 0);
6049 lowword = adjust_address (operands[4], SImode, 4);
6050 if (! WORDS_BIG_ENDIAN)
6051 std::swap (lowword, highword);
6052
6053 emit_move_insn (lowword, operands[1]);
6054 emit_move_insn (highword, operands[2]);
6055 emit_move_insn (operands[5], operands[4]);
6056 emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
6057 DONE;
6058 }
6059 [(set_attr "length" "20")
6060 (set_attr "type" "fp")])
6061
6062 ;; ISA 3.0 adds instructions lxsi[bh]zx to directly load QImode and HImode to
6063 ;; vector registers. These insns favor doing the sign/zero extension in
6064 ;; the vector registers, rather then loading up a GPR, doing a sign/zero
6065 ;; extension and then a direct move.
6066
6067 (define_expand "float<QHI:mode><SFDF:mode>2"
6068 [(parallel [(set (match_operand:SFDF 0 "vsx_register_operand")
6069 (float:SFDF
6070 (match_operand:QHI 1 "input_operand")))
6071 (clobber (match_scratch:DI 2))
6072 (clobber (match_scratch:DI 3))
6073 (clobber (match_scratch:<QHI:MODE> 4))])]
6074 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
6075 {
6076 if (MEM_P (operands[1]))
6077 operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
6078 })
6079
6080 (define_insn_and_split "*float<QHI:mode><SFDF:mode>2_internal"
6081 [(set (match_operand:SFDF 0 "vsx_register_operand" "=wa,wa,wa")
6082 (float:SFDF
6083 (match_operand:QHI 1 "reg_or_indexed_operand" "v,r,Z")))
6084 (clobber (match_scratch:DI 2 "=v,wa,v"))
6085 (clobber (match_scratch:DI 3 "=X,r,X"))
6086 (clobber (match_scratch:<QHI:MODE> 4 "=X,X,v"))]
6087 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
6088 "#"
6089 "&& reload_completed"
6090 [(const_int 0)]
6091 {
6092 rtx result = operands[0];
6093 rtx input = operands[1];
6094 rtx di = operands[2];
6095
6096 if (!MEM_P (input))
6097 {
6098 rtx tmp = operands[3];
6099 if (altivec_register_operand (input, <QHI:MODE>mode))
6100 emit_insn (gen_extend<QHI:mode>di2 (di, input));
6101 else if (GET_CODE (tmp) == SCRATCH)
6102 emit_insn (gen_extend<QHI:mode>di2 (di, input));
6103 else
6104 {
6105 emit_insn (gen_extend<QHI:mode>di2 (tmp, input));
6106 emit_move_insn (di, tmp);
6107 }
6108 }
6109 else
6110 {
6111 rtx tmp = operands[4];
6112 emit_move_insn (tmp, input);
6113 emit_insn (gen_extend<QHI:mode>di2 (di, tmp));
6114 }
6115
6116 emit_insn (gen_floatdi<SFDF:mode>2 (result, di));
6117 DONE;
6118 }
6119 [(set_attr "isa" "p9v,*,p9v")])
6120
6121 (define_expand "floatuns<QHI:mode><SFDF:mode>2"
6122 [(parallel [(set (match_operand:SFDF 0 "vsx_register_operand")
6123 (unsigned_float:SFDF
6124 (match_operand:QHI 1 "input_operand")))
6125 (clobber (match_scratch:DI 2))
6126 (clobber (match_scratch:DI 3))])]
6127 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
6128 {
6129 if (MEM_P (operands[1]))
6130 operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
6131 })
6132
6133 (define_insn_and_split "*floatuns<QHI:mode><SFDF:mode>2_internal"
6134 [(set (match_operand:SFDF 0 "vsx_register_operand" "=wa,wa,wa")
6135 (unsigned_float:SFDF
6136 (match_operand:QHI 1 "reg_or_indexed_operand" "v,r,Z")))
6137 (clobber (match_scratch:DI 2 "=v,wa,wa"))
6138 (clobber (match_scratch:DI 3 "=X,r,X"))]
6139 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
6140 "#"
6141 "&& reload_completed"
6142 [(const_int 0)]
6143 {
6144 rtx result = operands[0];
6145 rtx input = operands[1];
6146 rtx di = operands[2];
6147
6148 if (MEM_P (input) || altivec_register_operand (input, <QHI:MODE>mode))
6149 emit_insn (gen_zero_extend<QHI:mode>di2 (di, input));
6150 else
6151 {
6152 rtx tmp = operands[3];
6153 if (GET_CODE (tmp) == SCRATCH)
6154 emit_insn (gen_extend<QHI:mode>di2 (di, input));
6155 else
6156 {
6157 emit_insn (gen_zero_extend<QHI:mode>di2 (tmp, input));
6158 emit_move_insn (di, tmp);
6159 }
6160 }
6161
6162 emit_insn (gen_floatdi<SFDF:mode>2 (result, di));
6163 DONE;
6164 }
6165 [(set_attr "isa" "p9v,*,p9v")])
6166
6167 (define_expand "fix_trunc<mode>si2"
6168 [(set (match_operand:SI 0 "gpc_reg_operand")
6169 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand")))]
6170 "TARGET_HARD_FLOAT"
6171 {
6172 if (!(TARGET_P8_VECTOR && TARGET_DIRECT_MOVE))
6173 {
6174 rtx src = force_reg (<MODE>mode, operands[1]);
6175
6176 if (TARGET_STFIWX)
6177 emit_insn (gen_fix_trunc<mode>si2_stfiwx (operands[0], src));
6178 else
6179 {
6180 rtx tmp = gen_reg_rtx (DImode);
6181 rtx stack = rs6000_allocate_stack_temp (DImode, true, false);
6182 emit_insn (gen_fix_trunc<mode>si2_internal (operands[0], src,
6183 tmp, stack));
6184 }
6185 DONE;
6186 }
6187 })
6188
6189 ; Like the convert to float patterns, this insn must be split before
6190 ; register allocation so that it can allocate the memory slot if it
6191 ; needed
6192 (define_insn_and_split "fix_trunc<mode>si2_stfiwx"
6193 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
6194 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
6195 (clobber (match_scratch:DI 2 "=d"))]
6196 "TARGET_HARD_FLOAT && TARGET_STFIWX && can_create_pseudo_p ()
6197 && !(TARGET_P8_VECTOR && TARGET_DIRECT_MOVE)"
6198 "#"
6199 "&& 1"
6200 [(pc)]
6201 {
6202 rtx dest = operands[0];
6203 rtx src = operands[1];
6204 rtx tmp = operands[2];
6205
6206 if (GET_CODE (tmp) == SCRATCH)
6207 tmp = gen_reg_rtx (DImode);
6208
6209 emit_insn (gen_fctiwz_<mode> (tmp, src));
6210 if (MEM_P (dest) && (TARGET_MFCRF || MEM_ALIGN (dest) >= 32))
6211 {
6212 dest = rs6000_force_indexed_or_indirect_mem (dest);
6213 emit_insn (gen_stfiwx (dest, tmp));
6214 DONE;
6215 }
6216 else if (TARGET_POWERPC64 && TARGET_DIRECT_MOVE && !MEM_P (dest))
6217 {
6218 dest = gen_lowpart (DImode, dest);
6219 emit_move_insn (dest, tmp);
6220 DONE;
6221 }
6222 else
6223 {
6224 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
6225 emit_insn (gen_stfiwx (stack, tmp));
6226 emit_move_insn (dest, stack);
6227 DONE;
6228 }
6229 }
6230 [(set_attr "length" "12")
6231 (set_attr "type" "fp")])
6232
6233 (define_insn_and_split "fix_trunc<mode>si2_internal"
6234 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,?r")
6235 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d,<rreg>")))
6236 (clobber (match_operand:DI 2 "gpc_reg_operand" "=1,d"))
6237 (clobber (match_operand:DI 3 "offsettable_mem_operand" "=o,o"))]
6238 "TARGET_HARD_FLOAT
6239 && !(TARGET_P8_VECTOR && TARGET_DIRECT_MOVE)"
6240 "#"
6241 "&& 1"
6242 [(pc)]
6243 {
6244 rtx lowword;
6245 gcc_assert (MEM_P (operands[3]));
6246 lowword = adjust_address (operands[3], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
6247
6248 emit_insn (gen_fctiwz_<mode> (operands[2], operands[1]));
6249 emit_move_insn (operands[3], operands[2]);
6250 emit_move_insn (operands[0], lowword);
6251 DONE;
6252 }
6253 [(set_attr "length" "16")
6254 (set_attr "type" "fp")])
6255
6256 (define_expand "fix_trunc<mode>di2"
6257 [(set (match_operand:DI 0 "gpc_reg_operand")
6258 (fix:DI (match_operand:SFDF 1 "gpc_reg_operand")))]
6259 "TARGET_HARD_FLOAT && TARGET_FCFID"
6260 "")
6261
6262 (define_insn "*fix_trunc<mode>di2_fctidz"
6263 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa")
6264 (fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "d,wa")))]
6265 "TARGET_HARD_FLOAT && TARGET_FCFID"
6266 "@
6267 fctidz %0,%1
6268 xscvdpsxds %x0,%x1"
6269 [(set_attr "type" "fp")])
6270
6271 ;; If we have ISA 3.0, QI/HImode values can go in both VSX registers and GPR
6272 ;; registers. If we have ISA 2.07, we don't allow QI/HImode values in the
6273 ;; vector registers, so we need to do direct moves to the GPRs, but SImode
6274 ;; values can go in VSX registers. Keeping the direct move part through
6275 ;; register allocation prevents the register allocator from doing a direct move
6276 ;; of the SImode value to a GPR, and then a store/load.
6277 (define_insn_and_split "fix<uns>_trunc<SFDF:mode><QHI:mode>2"
6278 [(set (match_operand:<QHI:MODE> 0 "gpc_reg_operand" "=d,wa,r")
6279 (any_fix:QHI (match_operand:SFDF 1 "gpc_reg_operand" "d,wa,wa")))
6280 (clobber (match_scratch:SI 2 "=X,X,wa"))]
6281 "TARGET_DIRECT_MOVE"
6282 "@
6283 fctiw<u>z %0,%1
6284 xscvdp<su>xws %x0,%x1
6285 #"
6286 "&& reload_completed && int_reg_operand (operands[0], <QHI:MODE>mode)"
6287 [(set (match_dup 2)
6288 (any_fix:SI (match_dup 1)))
6289 (set (match_dup 3)
6290 (match_dup 2))]
6291 {
6292 operands[3] = gen_rtx_REG (SImode, REGNO (operands[0]));
6293 }
6294 [(set_attr "type" "fp")
6295 (set_attr "length" "4,4,8")
6296 (set_attr "isa" "p9v,p9v,*")])
6297
6298 (define_insn "*fix<uns>_trunc<SFDF:mode>si2_p8"
6299 [(set (match_operand:SI 0 "gpc_reg_operand" "=d,wa")
6300 (any_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d,wa")))]
6301 "TARGET_DIRECT_MOVE"
6302 "@
6303 fctiw<u>z %0,%1
6304 xscvdp<su>xws %x0,%x1"
6305 [(set_attr "type" "fp")])
6306
6307 ;; Keep the convert and store together through register allocation to prevent
6308 ;; the register allocator from getting clever and doing a direct move to a GPR
6309 ;; and then store for reg+offset stores.
6310 (define_insn_and_split "*fix<uns>_trunc<SFDF:mode><QHSI:mode>2_mem"
6311 [(set (match_operand:QHSI 0 "memory_operand" "=Z")
6312 (any_fix:QHSI (match_operand:SFDF 1 "gpc_reg_operand" "wa")))
6313 (clobber (match_scratch:SI 2 "=wa"))]
6314 "(<QHSI:MODE>mode == SImode && TARGET_P8_VECTOR) || TARGET_P9_VECTOR"
6315 "#"
6316 "&& reload_completed"
6317 [(set (match_dup 2)
6318 (any_fix:SI (match_dup 1)))
6319 (set (match_dup 0)
6320 (match_dup 3))]
6321 {
6322 operands[3] = (<QHSI:MODE>mode == SImode
6323 ? operands[2]
6324 : gen_rtx_REG (<QHSI:MODE>mode, REGNO (operands[2])));
6325 })
6326
6327 (define_expand "fixuns_trunc<mode>si2"
6328 [(set (match_operand:SI 0 "gpc_reg_operand")
6329 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand")))]
6330 "TARGET_HARD_FLOAT && TARGET_FCTIWUZ && TARGET_STFIWX"
6331 {
6332 if (!TARGET_P8_VECTOR)
6333 {
6334 emit_insn (gen_fixuns_trunc<mode>si2_stfiwx (operands[0], operands[1]));
6335 DONE;
6336 }
6337 })
6338
6339 (define_insn_and_split "fixuns_trunc<mode>si2_stfiwx"
6340 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
6341 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
6342 (clobber (match_scratch:DI 2 "=d"))]
6343 "TARGET_HARD_FLOAT && TARGET_FCTIWUZ
6344 && TARGET_STFIWX && can_create_pseudo_p ()
6345 && !TARGET_P8_VECTOR"
6346 "#"
6347 "&& 1"
6348 [(pc)]
6349 {
6350 rtx dest = operands[0];
6351 rtx src = operands[1];
6352 rtx tmp = operands[2];
6353
6354 if (GET_CODE (tmp) == SCRATCH)
6355 tmp = gen_reg_rtx (DImode);
6356
6357 emit_insn (gen_fctiwuz_<mode> (tmp, src));
6358 if (MEM_P (dest))
6359 {
6360 dest = rs6000_force_indexed_or_indirect_mem (dest);
6361 emit_insn (gen_stfiwx (dest, tmp));
6362 DONE;
6363 }
6364 else if (TARGET_POWERPC64 && TARGET_DIRECT_MOVE)
6365 {
6366 dest = gen_lowpart (DImode, dest);
6367 emit_move_insn (dest, tmp);
6368 DONE;
6369 }
6370 else
6371 {
6372 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
6373 emit_insn (gen_stfiwx (stack, tmp));
6374 emit_move_insn (dest, stack);
6375 DONE;
6376 }
6377 }
6378 [(set_attr "length" "12")
6379 (set_attr "type" "fp")])
6380
6381 (define_insn "fixuns_trunc<mode>di2"
6382 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa")
6383 (unsigned_fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "d,wa")))]
6384 "TARGET_HARD_FLOAT && TARGET_FCTIDUZ"
6385 "@
6386 fctiduz %0,%1
6387 xscvdpuxds %x0,%x1"
6388 [(set_attr "type" "fp")])
6389
6390 (define_insn "rs6000_mtfsb0"
6391 [(unspec_volatile [(match_operand:SI 0 "u5bit_cint_operand" "n")]
6392 UNSPECV_MTFSB0)]
6393 "TARGET_HARD_FLOAT"
6394 "mtfsb0 %0"
6395 [(set_attr "type" "fp")])
6396
6397 (define_insn "rs6000_mtfsb1"
6398 [(unspec_volatile [(match_operand:SI 0 "u5bit_cint_operand" "n")]
6399 UNSPECV_MTFSB1)]
6400 "TARGET_HARD_FLOAT"
6401 "mtfsb1 %0"
6402 [(set_attr "type" "fp")])
6403
6404 (define_insn "rs6000_mffscrn"
6405 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
6406 (unspec_volatile:DF [(match_operand:DF 1 "gpc_reg_operand" "d")]
6407 UNSPECV_MFFSCRN))]
6408 "TARGET_P9_MISC"
6409 "mffscrn %0,%1"
6410 [(set_attr "type" "fp")])
6411
6412 (define_insn "rs6000_mffscrni"
6413 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
6414 (unspec_volatile:DF [(match_operand:SI 1 "const_0_to_3_operand" "n")]
6415 UNSPECV_MFFSCRN))]
6416 "TARGET_P9_MISC"
6417 "mffscrni %0,%1"
6418 [(set_attr "type" "fp")])
6419
6420 (define_insn "rs6000_mffscdrn"
6421 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
6422 (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFSCDRN))
6423 (use (match_operand:DF 1 "gpc_reg_operand" "d"))]
6424 "TARGET_P9_MISC"
6425 "mffscdrn %0,%1"
6426 [(set_attr "type" "fp")])
6427
6428 (define_expand "rs6000_set_fpscr_rn"
6429 [(match_operand:SI 0 "reg_or_cint_operand")]
6430 "TARGET_HARD_FLOAT"
6431 {
6432 rtx tmp_df = gen_reg_rtx (DFmode);
6433
6434 /* The floating point rounding control bits are FPSCR[62:63]. Put the
6435 new rounding mode bits from operands[0][62:63] into FPSCR[62:63]. */
6436 if (TARGET_P9_MISC)
6437 {
6438 if (const_0_to_3_operand (operands[0], VOIDmode))
6439 emit_insn (gen_rs6000_mffscrni (tmp_df, operands[0]));
6440 else
6441 {
6442 rtx op0 = convert_to_mode (DImode, operands[0], false);
6443 rtx src_df = simplify_gen_subreg (DFmode, op0, DImode, 0);
6444 emit_insn (gen_rs6000_mffscrn (tmp_df, src_df));
6445 }
6446 DONE;
6447 }
6448
6449 if (CONST_INT_P (operands[0]))
6450 {
6451 if ((INTVAL (operands[0]) & 0x1) == 0x1)
6452 emit_insn (gen_rs6000_mtfsb1 (GEN_INT (31)));
6453 else
6454 emit_insn (gen_rs6000_mtfsb0 (GEN_INT (31)));
6455
6456 if ((INTVAL (operands[0]) & 0x2) == 0x2)
6457 emit_insn (gen_rs6000_mtfsb1 (GEN_INT (30)));
6458 else
6459 emit_insn (gen_rs6000_mtfsb0 (GEN_INT (30)));
6460 }
6461 else
6462 {
6463 rtx tmp_rn = gen_reg_rtx (DImode);
6464 rtx tmp_di = gen_reg_rtx (DImode);
6465
6466 /* Extract new RN mode from operand. */
6467 rtx op0 = convert_to_mode (DImode, operands[0], false);
6468 emit_insn (gen_anddi3 (tmp_rn, op0, GEN_INT (3)));
6469
6470 /* Insert new RN mode into FSCPR. */
6471 emit_insn (gen_rs6000_mffs (tmp_df));
6472 tmp_di = simplify_gen_subreg (DImode, tmp_df, DFmode, 0);
6473 emit_insn (gen_anddi3 (tmp_di, tmp_di, GEN_INT (-4)));
6474 emit_insn (gen_iordi3 (tmp_di, tmp_di, tmp_rn));
6475
6476 /* Need to write to field k=15. The fields are [0:15]. Hence with
6477 L=0, W=0, FLM_i must be equal to 8, 16 = i + 8*(1-W). FLM is an
6478 8-bit field[0:7]. Need to set the bit that corresponds to the
6479 value of i that you want [0:7]. */
6480 tmp_df = simplify_gen_subreg (DFmode, tmp_di, DImode, 0);
6481 emit_insn (gen_rs6000_mtfsf (GEN_INT (0x01), tmp_df));
6482 }
6483 DONE;
6484 })
6485
6486 (define_expand "rs6000_set_fpscr_drn"
6487 [(match_operand:DI 0 "gpc_reg_operand")]
6488 "TARGET_HARD_FLOAT"
6489 {
6490 rtx tmp_df = gen_reg_rtx (DFmode);
6491
6492 /* The decimal floating point rounding control bits are FPSCR[29:31]. Put the
6493 new rounding mode bits from operands[0][61:63] into FPSCR[29:31]. */
6494 if (TARGET_P9_MISC)
6495 {
6496 rtx src_df = gen_reg_rtx (DFmode);
6497
6498 emit_insn (gen_ashldi3 (operands[0], operands[0], GEN_INT (32)));
6499 src_df = simplify_gen_subreg (DFmode, operands[0], DImode, 0);
6500 emit_insn (gen_rs6000_mffscdrn (tmp_df, src_df));
6501 }
6502 else
6503 {
6504 rtx tmp_rn = gen_reg_rtx (DImode);
6505 rtx tmp_di = gen_reg_rtx (DImode);
6506
6507 /* Extract new DRN mode from operand. */
6508 emit_insn (gen_anddi3 (tmp_rn, operands[0], GEN_INT (0x7)));
6509 emit_insn (gen_ashldi3 (tmp_rn, tmp_rn, GEN_INT (32)));
6510
6511 /* Insert new RN mode into FSCPR. */
6512 emit_insn (gen_rs6000_mffs (tmp_df));
6513 tmp_di = simplify_gen_subreg (DImode, tmp_df, DFmode, 0);
6514 emit_insn (gen_anddi3 (tmp_di, tmp_di, GEN_INT (0xFFFFFFF8FFFFFFFFULL)));
6515 emit_insn (gen_iordi3 (tmp_di, tmp_di, tmp_rn));
6516
6517 /* Need to write to field 7. The fields are [0:15]. The equation to
6518 select the field is i + 8*(1-W). Hence with L=0 and W=1, need to set
6519 i to 0x1 to get field 7 where i selects the field. */
6520 tmp_df = simplify_gen_subreg (DFmode, tmp_di, DImode, 0);
6521 emit_insn (gen_rs6000_mtfsf_hi (GEN_INT (0x01), tmp_df));
6522 }
6523 DONE;
6524 })
6525
6526 ;; Here, we use (set (reg) (unspec:DI [(fix:SI ...)] UNSPEC_FCTIWZ))
6527 ;; rather than (set (subreg:SI (reg)) (fix:SI ...))
6528 ;; because the first makes it clear that operand 0 is not live
6529 ;; before the instruction.
6530 (define_insn "fctiwz_<mode>"
6531 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa")
6532 (unspec:DI [(fix:SI
6533 (match_operand:SFDF 1 "gpc_reg_operand" "d,wa"))]
6534 UNSPEC_FCTIWZ))]
6535 "TARGET_HARD_FLOAT"
6536 "@
6537 fctiwz %0,%1
6538 xscvdpsxws %x0,%x1"
6539 [(set_attr "type" "fp")])
6540
6541 (define_insn "fctiwuz_<mode>"
6542 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa")
6543 (unspec:DI [(unsigned_fix:SI
6544 (match_operand:SFDF 1 "gpc_reg_operand" "d,wa"))]
6545 UNSPEC_FCTIWUZ))]
6546 "TARGET_HARD_FLOAT && TARGET_FCTIWUZ"
6547 "@
6548 fctiwuz %0,%1
6549 xscvdpuxws %x0,%x1"
6550 [(set_attr "type" "fp")])
6551
6552 ;; Only optimize (float (fix x)) -> frz if we are in fast-math mode, since
6553 ;; since the friz instruction does not truncate the value if the floating
6554 ;; point value is < LONG_MIN or > LONG_MAX.
6555 (define_insn "*friz"
6556 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa")
6557 (float:DF (fix:DI (match_operand:DF 1 "gpc_reg_operand" "d,wa"))))]
6558 "TARGET_HARD_FLOAT && TARGET_FPRND
6559 && flag_unsafe_math_optimizations && !flag_trapping_math && TARGET_FRIZ"
6560 "@
6561 friz %0,%1
6562 xsrdpiz %x0,%x1"
6563 [(set_attr "type" "fp")])
6564
6565 ;; Opitmize converting SF/DFmode to signed SImode and back to SF/DFmode. This
6566 ;; optimization prevents on ISA 2.06 systems and earlier having to store the
6567 ;; value from the FPR/vector unit to the stack, load the value into a GPR, sign
6568 ;; extend it, store it back on the stack from the GPR, load it back into the
6569 ;; FP/vector unit to do the rounding. If we have direct move (ISA 2.07),
6570 ;; disable using store and load to sign/zero extend the value.
6571 (define_insn_and_split "*round32<mode>2_fprs"
6572 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
6573 (float:SFDF
6574 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
6575 (clobber (match_scratch:DI 2 "=d"))
6576 (clobber (match_scratch:DI 3 "=d"))]
6577 "TARGET_HARD_FLOAT
6578 && <SI_CONVERT_FP> && TARGET_LFIWAX && TARGET_STFIWX && TARGET_FCFID
6579 && !TARGET_DIRECT_MOVE && can_create_pseudo_p ()"
6580 "#"
6581 "&& 1"
6582 [(pc)]
6583 {
6584 rtx dest = operands[0];
6585 rtx src = operands[1];
6586 rtx tmp1 = operands[2];
6587 rtx tmp2 = operands[3];
6588 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
6589
6590 if (GET_CODE (tmp1) == SCRATCH)
6591 tmp1 = gen_reg_rtx (DImode);
6592 if (GET_CODE (tmp2) == SCRATCH)
6593 tmp2 = gen_reg_rtx (DImode);
6594
6595 emit_insn (gen_fctiwz_<mode> (tmp1, src));
6596 emit_insn (gen_stfiwx (stack, tmp1));
6597 emit_insn (gen_lfiwax (tmp2, stack));
6598 emit_insn (gen_floatdi<mode>2 (dest, tmp2));
6599 DONE;
6600 }
6601 [(set_attr "type" "fpload")
6602 (set_attr "length" "16")])
6603
6604 (define_insn_and_split "*roundu32<mode>2_fprs"
6605 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
6606 (unsigned_float:SFDF
6607 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
6608 (clobber (match_scratch:DI 2 "=d"))
6609 (clobber (match_scratch:DI 3 "=d"))]
6610 "TARGET_HARD_FLOAT
6611 && TARGET_LFIWZX && TARGET_STFIWX && TARGET_FCFIDU && !TARGET_DIRECT_MOVE
6612 && can_create_pseudo_p ()"
6613 "#"
6614 "&& 1"
6615 [(pc)]
6616 {
6617 rtx dest = operands[0];
6618 rtx src = operands[1];
6619 rtx tmp1 = operands[2];
6620 rtx tmp2 = operands[3];
6621 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
6622
6623 if (GET_CODE (tmp1) == SCRATCH)
6624 tmp1 = gen_reg_rtx (DImode);
6625 if (GET_CODE (tmp2) == SCRATCH)
6626 tmp2 = gen_reg_rtx (DImode);
6627
6628 emit_insn (gen_fctiwuz_<mode> (tmp1, src));
6629 emit_insn (gen_stfiwx (stack, tmp1));
6630 emit_insn (gen_lfiwzx (tmp2, stack));
6631 emit_insn (gen_floatdi<mode>2 (dest, tmp2));
6632 DONE;
6633 }
6634 [(set_attr "type" "fpload")
6635 (set_attr "length" "16")])
6636
6637 ;; No VSX equivalent to fctid
6638 (define_insn "lrint<mode>di2"
6639 [(set (match_operand:DI 0 "gpc_reg_operand" "=d")
6640 (unspec:DI [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
6641 UNSPEC_FCTID))]
6642 "TARGET_HARD_FLOAT && TARGET_FPRND"
6643 "fctid %0,%1"
6644 [(set_attr "type" "fp")])
6645
6646 (define_insn "btrunc<mode>2"
6647 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,wa")
6648 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "d,wa")]
6649 UNSPEC_FRIZ))]
6650 "TARGET_HARD_FLOAT && TARGET_FPRND"
6651 "@
6652 friz %0,%1
6653 xsrdpiz %x0,%x1"
6654 [(set_attr "type" "fp")])
6655
6656 (define_insn "ceil<mode>2"
6657 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,wa")
6658 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "d,wa")]
6659 UNSPEC_FRIP))]
6660 "TARGET_HARD_FLOAT && TARGET_FPRND"
6661 "@
6662 frip %0,%1
6663 xsrdpip %x0,%x1"
6664 [(set_attr "type" "fp")])
6665
6666 (define_insn "floor<mode>2"
6667 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,wa")
6668 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "d,wa")]
6669 UNSPEC_FRIM))]
6670 "TARGET_HARD_FLOAT && TARGET_FPRND"
6671 "@
6672 frim %0,%1
6673 xsrdpim %x0,%x1"
6674 [(set_attr "type" "fp")])
6675
6676 ;; No VSX equivalent to frin
6677 (define_insn "round<mode>2"
6678 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<rreg2>")
6679 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
6680 UNSPEC_FRIN))]
6681 "TARGET_HARD_FLOAT && TARGET_FPRND"
6682 "frin %0,%1"
6683 [(set_attr "type" "fp")])
6684
6685 (define_insn "*xsrdpi<mode>2"
6686 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=wa")
6687 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "wa")]
6688 UNSPEC_XSRDPI))]
6689 "TARGET_HARD_FLOAT && TARGET_VSX"
6690 "xsrdpi %x0,%x1"
6691 [(set_attr "type" "fp")])
6692
6693 (define_expand "lround<mode>di2"
6694 [(set (match_dup 2)
6695 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand")]
6696 UNSPEC_XSRDPI))
6697 (set (match_operand:DI 0 "gpc_reg_operand")
6698 (unspec:DI [(match_dup 2)]
6699 UNSPEC_FCTID))]
6700 "TARGET_HARD_FLOAT && TARGET_VSX && TARGET_FPRND"
6701 {
6702 operands[2] = gen_reg_rtx (<MODE>mode);
6703 })
6704
6705 ; An UNSPEC is used so we don't have to support SImode in FP registers.
6706 (define_insn "stfiwx"
6707 [(set (match_operand:SI 0 "memory_operand" "=Z,Z")
6708 (unspec:SI [(match_operand:DI 1 "gpc_reg_operand" "d,wa")]
6709 UNSPEC_STFIWX))]
6710 "TARGET_PPC_GFXOPT"
6711 "@
6712 stfiwx %1,%y0
6713 stxsiwx %x1,%y0"
6714 [(set_attr "type" "fpstore")
6715 (set_attr "isa" "*,p8v")])
6716
6717 ;; If we don't have a direct conversion to single precision, don't enable this
6718 ;; conversion for 32-bit without fast math, because we don't have the insn to
6719 ;; generate the fixup swizzle to avoid double rounding problems.
6720 (define_expand "floatsisf2"
6721 [(set (match_operand:SF 0 "gpc_reg_operand")
6722 (float:SF (match_operand:SI 1 "nonimmediate_operand")))]
6723 "TARGET_HARD_FLOAT
6724 && ((TARGET_FCFIDS && TARGET_LFIWAX)
6725 || (TARGET_FCFID
6726 && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))"
6727 {
6728 if (TARGET_FCFIDS && TARGET_LFIWAX)
6729 {
6730 emit_insn (gen_floatsisf2_lfiwax (operands[0], operands[1]));
6731 DONE;
6732 }
6733 else if (TARGET_FCFID && TARGET_LFIWAX)
6734 {
6735 rtx dfreg = gen_reg_rtx (DFmode);
6736 emit_insn (gen_floatsidf2_lfiwax (dfreg, operands[1]));
6737 emit_insn (gen_truncdfsf2 (operands[0], dfreg));
6738 DONE;
6739 }
6740 else
6741 {
6742 rtx dreg = operands[1];
6743 if (!REG_P (dreg))
6744 dreg = force_reg (SImode, dreg);
6745 dreg = convert_to_mode (DImode, dreg, false);
6746 emit_insn (gen_floatdisf2 (operands[0], dreg));
6747 DONE;
6748 }
6749 })
6750
6751 (define_insn "floatdidf2"
6752 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa")
6753 (float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wa")))]
6754 "TARGET_FCFID && TARGET_HARD_FLOAT"
6755 "@
6756 fcfid %0,%1
6757 xscvsxddp %x0,%x1"
6758 [(set_attr "type" "fp")])
6759
6760 (define_insn "floatti<mode>2"
6761 [(set (match_operand:IEEE128 0 "vsx_register_operand" "=v")
6762 (float:IEEE128 (match_operand:TI 1 "vsx_register_operand" "v")))]
6763 "TARGET_POWER10"
6764 {
6765 return "xscvsqqp %0,%1";
6766 }
6767 [(set_attr "type" "fp")])
6768
6769 (define_insn "floatunsti<mode>2"
6770 [(set (match_operand:IEEE128 0 "vsx_register_operand" "=v")
6771 (unsigned_float:IEEE128 (match_operand:TI 1 "vsx_register_operand" "v")))]
6772 "TARGET_POWER10"
6773 {
6774 return "xscvuqqp %0,%1";
6775 }
6776 [(set_attr "type" "fp")])
6777
6778 (define_insn "fix_trunc<mode>ti2"
6779 [(set (match_operand:TI 0 "vsx_register_operand" "=v")
6780 (fix:TI (match_operand:IEEE128 1 "vsx_register_operand" "v")))]
6781 "TARGET_POWER10"
6782 {
6783 return "xscvqpsqz %0,%1";
6784 }
6785 [(set_attr "type" "fp")])
6786
6787 (define_insn "fixuns_trunc<mode>ti2"
6788 [(set (match_operand:TI 0 "vsx_register_operand" "=v")
6789 (unsigned_fix:TI (match_operand:IEEE128 1 "vsx_register_operand" "v")))]
6790 "TARGET_POWER10"
6791 {
6792 return "xscvqpuqz %0,%1";
6793 }
6794 [(set_attr "type" "fp")])
6795
6796 ; Allow the combiner to merge source memory operands to the conversion so that
6797 ; the optimizer/register allocator doesn't try to load the value too early in a
6798 ; GPR and then use store/load to move it to a FPR and suffer from a store-load
6799 ; hit. We will split after reload to avoid the trip through the GPRs
6800
6801 (define_insn_and_split "*floatdidf2_mem"
6802 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa")
6803 (float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
6804 (clobber (match_scratch:DI 2 "=d,wa"))]
6805 "TARGET_HARD_FLOAT && TARGET_FCFID"
6806 "#"
6807 "&& reload_completed"
6808 [(set (match_dup 2) (match_dup 1))
6809 (set (match_dup 0) (float:DF (match_dup 2)))]
6810 ""
6811 [(set_attr "length" "8")
6812 (set_attr "type" "fpload")])
6813
6814 (define_expand "floatunsdidf2"
6815 [(set (match_operand:DF 0 "gpc_reg_operand")
6816 (unsigned_float:DF
6817 (match_operand:DI 1 "gpc_reg_operand")))]
6818 "TARGET_HARD_FLOAT && TARGET_FCFIDU"
6819 "")
6820
6821 (define_insn "*floatunsdidf2_fcfidu"
6822 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa")
6823 (unsigned_float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wa")))]
6824 "TARGET_HARD_FLOAT && TARGET_FCFIDU"
6825 "@
6826 fcfidu %0,%1
6827 xscvuxddp %x0,%x1"
6828 [(set_attr "type" "fp")])
6829
6830 (define_insn_and_split "*floatunsdidf2_mem"
6831 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa")
6832 (unsigned_float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
6833 (clobber (match_scratch:DI 2 "=d,wa"))]
6834 "TARGET_HARD_FLOAT && (TARGET_FCFIDU || VECTOR_UNIT_VSX_P (DFmode))"
6835 "#"
6836 "&& reload_completed"
6837 [(set (match_dup 2) (match_dup 1))
6838 (set (match_dup 0) (unsigned_float:DF (match_dup 2)))]
6839 ""
6840 [(set_attr "length" "8")
6841 (set_attr "type" "fpload")])
6842
6843 (define_expand "floatdisf2"
6844 [(set (match_operand:SF 0 "gpc_reg_operand")
6845 (float:SF (match_operand:DI 1 "gpc_reg_operand")))]
6846 "TARGET_FCFID && TARGET_HARD_FLOAT
6847 && (TARGET_FCFIDS || TARGET_POWERPC64 || flag_unsafe_math_optimizations)"
6848 {
6849 if (!TARGET_FCFIDS)
6850 {
6851 rtx val = operands[1];
6852 if (!flag_unsafe_math_optimizations)
6853 {
6854 rtx label = gen_label_rtx ();
6855 val = gen_reg_rtx (DImode);
6856 emit_insn (gen_floatdisf2_internal2 (val, operands[1], label));
6857 emit_label (label);
6858 }
6859 emit_insn (gen_floatdisf2_internal1 (operands[0], val));
6860 DONE;
6861 }
6862 })
6863
6864 (define_insn "floatdisf2_fcfids"
6865 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wa")
6866 (float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wa")))]
6867 "TARGET_HARD_FLOAT && TARGET_FCFIDS"
6868 "@
6869 fcfids %0,%1
6870 xscvsxdsp %x0,%x1"
6871 [(set_attr "type" "fp")
6872 (set_attr "isa" "*,p8v")])
6873
6874 (define_insn_and_split "*floatdisf2_mem"
6875 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wa,wa")
6876 (float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
6877 (clobber (match_scratch:DI 2 "=d,d,wa"))]
6878 "TARGET_HARD_FLOAT && TARGET_FCFIDS"
6879 "#"
6880 "&& reload_completed"
6881 [(pc)]
6882 {
6883 emit_move_insn (operands[2], operands[1]);
6884 emit_insn (gen_floatdisf2_fcfids (operands[0], operands[2]));
6885 DONE;
6886 }
6887 [(set_attr "length" "8")
6888 (set_attr "isa" "*,p8v,p8v")])
6889
6890 ;; This is not IEEE compliant if rounding mode is "round to nearest".
6891 ;; If the DI->DF conversion is inexact, then it's possible to suffer
6892 ;; from double rounding.
6893 ;; Instead of creating a new cpu type for two FP operations, just use fp
6894 (define_insn_and_split "floatdisf2_internal1"
6895 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
6896 (float:SF (match_operand:DI 1 "gpc_reg_operand" "d")))
6897 (clobber (match_scratch:DF 2 "=d"))]
6898 "TARGET_FCFID && TARGET_HARD_FLOAT && !TARGET_FCFIDS"
6899 "#"
6900 "&& reload_completed"
6901 [(set (match_dup 2)
6902 (float:DF (match_dup 1)))
6903 (set (match_dup 0)
6904 (float_truncate:SF (match_dup 2)))]
6905 ""
6906 [(set_attr "length" "8")
6907 (set_attr "type" "fp")])
6908
6909 ;; Twiddles bits to avoid double rounding.
6910 ;; Bits that might be truncated when converting to DFmode are replaced
6911 ;; by a bit that won't be lost at that stage, but is below the SFmode
6912 ;; rounding position.
6913 (define_expand "floatdisf2_internal2"
6914 [(parallel [(set (match_dup 3) (ashiftrt:DI (match_operand:DI 1 "")
6915 (const_int 53)))
6916 (clobber (reg:DI CA_REGNO))])
6917 (set (match_operand:DI 0 "") (and:DI (match_dup 1)
6918 (const_int 2047)))
6919 (set (match_dup 3) (plus:DI (match_dup 3)
6920 (const_int 1)))
6921 (set (match_dup 0) (plus:DI (match_dup 0)
6922 (const_int 2047)))
6923 (set (match_dup 4) (compare:CCUNS (match_dup 3)
6924 (const_int 2)))
6925 (set (match_dup 0) (ior:DI (match_dup 0)
6926 (match_dup 1)))
6927 (set (match_dup 0) (and:DI (match_dup 0)
6928 (const_int -2048)))
6929 (set (pc) (if_then_else (geu (match_dup 4) (const_int 0))
6930 (label_ref (match_operand:DI 2 ""))
6931 (pc)))
6932 (set (match_dup 0) (match_dup 1))]
6933 "TARGET_POWERPC64 && TARGET_HARD_FLOAT && !TARGET_FCFIDS"
6934 {
6935 operands[3] = gen_reg_rtx (DImode);
6936 operands[4] = gen_reg_rtx (CCUNSmode);
6937 })
6938
6939 (define_expand "floatunsdisf2"
6940 [(set (match_operand:SF 0 "gpc_reg_operand")
6941 (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand")))]
6942 "TARGET_HARD_FLOAT && TARGET_FCFIDUS"
6943 "")
6944
6945 (define_insn "floatunsdisf2_fcfidus"
6946 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wa")
6947 (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wa")))]
6948 "TARGET_HARD_FLOAT && TARGET_FCFIDUS"
6949 "@
6950 fcfidus %0,%1
6951 xscvuxdsp %x0,%x1"
6952 [(set_attr "type" "fp")
6953 (set_attr "isa" "*,p8v")])
6954
6955 (define_insn_and_split "*floatunsdisf2_mem"
6956 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wa,wa")
6957 (unsigned_float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
6958 (clobber (match_scratch:DI 2 "=d,d,wa"))]
6959 "TARGET_HARD_FLOAT && TARGET_FCFIDUS"
6960 "#"
6961 "&& reload_completed"
6962 [(pc)]
6963 {
6964 emit_move_insn (operands[2], operands[1]);
6965 emit_insn (gen_floatunsdisf2_fcfidus (operands[0], operands[2]));
6966 DONE;
6967 }
6968 [(set_attr "type" "fpload")
6969 (set_attr "length" "8")
6970 (set_attr "isa" "*,p8v,p8v")])
6971
6972 ;; int fegetround(void)
6973 ;;
6974 ;; This expansion for the C99 function only expands for compatible
6975 ;; target libcs, because it needs to return one of FE_DOWNWARD,
6976 ;; FE_TONEAREST, FE_TOWARDZERO or FE_UPWARD with the values as defined
6977 ;; by the target libc, and since the libc is free to choose the values
6978 ;; (and they may differ from the hardware) and the expander needs to
6979 ;; know then beforehand, this expanded only expands for target libcs
6980 ;; that it can handle the values is knows.
6981 ;; Because of these restriction, this only expands on the desired
6982 ;; case and fallback to a call to libc otherwise.
6983 (define_expand "fegetroundsi"
6984 [(set (match_operand:SI 0 "gpc_reg_operand")
6985 (unspec_volatile:SI [(const_int 0)] UNSPECV_MFFSL))]
6986 "TARGET_HARD_FLOAT"
6987 {
6988 if (!OPTION_GLIBC)
6989 FAIL;
6990
6991 rtx tmp_df = gen_reg_rtx (DFmode);
6992 emit_insn (gen_rs6000_mffsl (tmp_df));
6993
6994 rtx tmp_di = simplify_gen_subreg (DImode, tmp_df, DFmode, 0);
6995 rtx tmp_di_2 = gen_reg_rtx (DImode);
6996 emit_insn (gen_anddi3 (tmp_di_2, tmp_di, GEN_INT (3)));
6997 rtx tmp_si = gen_reg_rtx (SImode);
6998 tmp_si = gen_lowpart (SImode, tmp_di_2);
6999 emit_move_insn (operands[0], tmp_si);
7000 DONE;
7001 })
7002
7003 ;; int feclearexcept(int excepts)
7004 ;;
7005 ;; This expansion for the C99 function only works when EXCEPTS is a
7006 ;; constant known at compile time and specifies any one of
7007 ;; FE_INEXACT, FE_DIVBYZERO, FE_UNDERFLOW and FE_OVERFLOW flags.
7008 ;; It doesn't handle values out of range, and always returns 0.
7009 ;; Note that FE_INVALID is unsupported because it maps to more than
7010 ;; one bit of the FPSCR register.
7011 ;; The FE_* are defined in the target libc, and since they are free to
7012 ;; choose the values and the expand needs to know them beforehand,
7013 ;; this expander only expands for target libcs that it can handle the
7014 ;; values it knows.
7015 ;; Because of these restrictions, this only expands on the desired
7016 ;; cases and fallback to a call to libc on any other case.
7017 (define_expand "feclearexceptsi"
7018 [(use (match_operand:SI 1 "const_int_operand" "n"))
7019 (set (match_operand:SI 0 "gpc_reg_operand")
7020 (const_int 0))]
7021 "TARGET_HARD_FLOAT"
7022 {
7023 if (!OPTION_GLIBC)
7024 FAIL;
7025
7026 unsigned int fe = INTVAL (operands[1]);
7027 if (fe != (fe & 0x1e000000))
7028 FAIL;
7029
7030 if (fe & 0x02000000) /* FE_INEXACT */
7031 emit_insn (gen_rs6000_mtfsb0 (gen_rtx_CONST_INT (SImode, 6)));
7032 if (fe & 0x04000000) /* FE_DIVBYZERO */
7033 emit_insn (gen_rs6000_mtfsb0 (gen_rtx_CONST_INT (SImode, 5)));
7034 if (fe & 0x08000000) /* FE_UNDERFLOW */
7035 emit_insn (gen_rs6000_mtfsb0 (gen_rtx_CONST_INT (SImode, 4)));
7036 if (fe & 0x10000000) /* FE_OVERFLOW */
7037 emit_insn (gen_rs6000_mtfsb0 (gen_rtx_CONST_INT (SImode, 3)));
7038
7039 emit_move_insn (operands[0], const0_rtx);
7040 DONE;
7041 })
7042
7043 ;; int feraiseexcept(int excepts)
7044 ;;
7045 ;; This expansion for the C99 function only works when excepts is a
7046 ;; constant known at compile time and specifies any one of
7047 ;; FE_INEXACT, FE_DIVBYZERO, FE_UNDERFLOW and FE_OVERFLOW flags.
7048 ;; It doesn't handle values out of range, and always returns 0.
7049 ;; Note that FE_INVALID is unsupported because it maps to more than
7050 ;; one bit of the FPSCR register.
7051 ;; The FE_* are defined in the target libc, and since they are free to
7052 ;; choose the values and the expand needs to know them beforehand,
7053 ;; this expander only expands for target libcs that it can handle the
7054 ;; values it knows.
7055 ;; Because of these restrictions, this only expands on the desired
7056 ;; cases and fallback to a call to libc on any other case.
7057 (define_expand "feraiseexceptsi"
7058 [(use (match_operand:SI 1 "const_int_operand" "n"))
7059 (set (match_operand:SI 0 "gpc_reg_operand")
7060 (const_int 0))]
7061 "TARGET_HARD_FLOAT"
7062 {
7063 if (!OPTION_GLIBC)
7064 FAIL;
7065
7066 unsigned int fe = INTVAL (operands[1]);
7067 if (fe != (fe & 0x1e000000))
7068 FAIL;
7069
7070 if (fe & 0x02000000) /* FE_INEXACT */
7071 emit_insn (gen_rs6000_mtfsb1 (gen_rtx_CONST_INT (SImode, 6)));
7072 if (fe & 0x04000000) /* FE_DIVBYZERO */
7073 emit_insn (gen_rs6000_mtfsb1 (gen_rtx_CONST_INT (SImode, 5)));
7074 if (fe & 0x08000000) /* FE_UNDERFLOW */
7075 emit_insn (gen_rs6000_mtfsb1 (gen_rtx_CONST_INT (SImode, 4)));
7076 if (fe & 0x10000000) /* FE_OVERFLOW */
7077 emit_insn (gen_rs6000_mtfsb1 (gen_rtx_CONST_INT (SImode, 3)));
7078
7079 emit_move_insn (operands[0], const0_rtx);
7080 DONE;
7081 })
7082 \f
7083 ;; Define the TImode operations that can be done in a small number
7084 ;; of instructions. The & constraints are to prevent the register
7085 ;; allocator from allocating registers that overlap with the inputs
7086 ;; (for example, having an input in 7,8 and an output in 6,7). We
7087 ;; also allow for the output being the same as one of the inputs.
7088
7089 (define_expand "addti3"
7090 [(set (match_operand:TI 0 "gpc_reg_operand")
7091 (plus:TI (match_operand:TI 1 "gpc_reg_operand")
7092 (match_operand:TI 2 "reg_or_short_operand")))]
7093 "TARGET_64BIT"
7094 {
7095 rtx lo0 = gen_lowpart (DImode, operands[0]);
7096 rtx lo1 = gen_lowpart (DImode, operands[1]);
7097 rtx lo2 = gen_lowpart (DImode, operands[2]);
7098 rtx hi0 = gen_highpart (DImode, operands[0]);
7099 rtx hi1 = gen_highpart (DImode, operands[1]);
7100 rtx hi2 = gen_highpart_mode (DImode, TImode, operands[2]);
7101
7102 if (!reg_or_short_operand (lo2, DImode))
7103 lo2 = force_reg (DImode, lo2);
7104 if (!adde_operand (hi2, DImode))
7105 hi2 = force_reg (DImode, hi2);
7106
7107 emit_insn (gen_adddi3_carry (lo0, lo1, lo2));
7108 emit_insn (gen_adddi3_carry_in (hi0, hi1, hi2));
7109 DONE;
7110 })
7111
7112 (define_expand "subti3"
7113 [(set (match_operand:TI 0 "gpc_reg_operand")
7114 (minus:TI (match_operand:TI 1 "reg_or_short_operand")
7115 (match_operand:TI 2 "gpc_reg_operand")))]
7116 "TARGET_64BIT"
7117 {
7118 rtx lo0 = gen_lowpart (DImode, operands[0]);
7119 rtx lo1 = gen_lowpart (DImode, operands[1]);
7120 rtx lo2 = gen_lowpart (DImode, operands[2]);
7121 rtx hi0 = gen_highpart (DImode, operands[0]);
7122 rtx hi1 = gen_highpart_mode (DImode, TImode, operands[1]);
7123 rtx hi2 = gen_highpart (DImode, operands[2]);
7124
7125 if (!reg_or_short_operand (lo1, DImode))
7126 lo1 = force_reg (DImode, lo1);
7127 if (!adde_operand (hi1, DImode))
7128 hi1 = force_reg (DImode, hi1);
7129
7130 emit_insn (gen_subfdi3_carry (lo0, lo2, lo1));
7131 emit_insn (gen_subfdi3_carry_in (hi0, hi2, hi1));
7132 DONE;
7133 })
7134 \f
7135 ;; 128-bit logical operations expanders
7136
7137 (define_expand "and<mode>3"
7138 [(set (match_operand:BOOL_128 0 "vlogical_operand")
7139 (and:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")
7140 (match_operand:BOOL_128 2 "vlogical_operand")))]
7141 ""
7142 "")
7143
7144 (define_expand "ior<mode>3"
7145 [(set (match_operand:BOOL_128 0 "vlogical_operand")
7146 (ior:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")
7147 (match_operand:BOOL_128 2 "vlogical_operand")))]
7148 ""
7149 "")
7150
7151 (define_expand "xor<mode>3"
7152 [(set (match_operand:BOOL_128 0 "vlogical_operand")
7153 (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")
7154 (match_operand:BOOL_128 2 "vlogical_operand")))]
7155 ""
7156 "")
7157
7158 (define_expand "nor<mode>3"
7159 [(set (match_operand:BOOL_128 0 "vlogical_operand")
7160 (and:BOOL_128
7161 (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand"))
7162 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))))]
7163 ""
7164 "")
7165
7166 (define_expand "andc<mode>3"
7167 [(set (match_operand:BOOL_128 0 "vlogical_operand")
7168 (and:BOOL_128
7169 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))
7170 (match_operand:BOOL_128 1 "vlogical_operand")))]
7171 ""
7172 "")
7173
7174 ;; Power8 vector logical instructions.
7175 (define_expand "eqv<mode>3"
7176 [(set (match_operand:BOOL_128 0 "vlogical_operand")
7177 (not:BOOL_128
7178 (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")
7179 (match_operand:BOOL_128 2 "vlogical_operand"))))]
7180 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
7181 "")
7182
7183 ;; Rewrite nand into canonical form
7184 (define_expand "nand<mode>3"
7185 [(set (match_operand:BOOL_128 0 "vlogical_operand")
7186 (ior:BOOL_128
7187 (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand"))
7188 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))))]
7189 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
7190 "")
7191
7192 ;; The canonical form is to have the negated element first, so we need to
7193 ;; reverse arguments.
7194 (define_expand "orc<mode>3"
7195 [(set (match_operand:BOOL_128 0 "vlogical_operand")
7196 (ior:BOOL_128
7197 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))
7198 (match_operand:BOOL_128 1 "vlogical_operand")))]
7199 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
7200 "")
7201
7202 ;; 128-bit logical operations insns and split operations
7203 (define_insn_and_split "*and<mode>3_internal"
7204 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
7205 (and:BOOL_128
7206 (match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
7207 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")))]
7208 ""
7209 {
7210 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
7211 return "xxland %x0,%x1,%x2";
7212
7213 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
7214 return "vand %0,%1,%2";
7215
7216 return "#";
7217 }
7218 "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
7219 [(const_int 0)]
7220 {
7221 rs6000_split_logical (operands, AND, false, false, false);
7222 DONE;
7223 }
7224 [(set (attr "type")
7225 (if_then_else
7226 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
7227 (const_string "veclogical")
7228 (const_string "integer")))
7229 (set (attr "length")
7230 (if_then_else
7231 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
7232 (const_string "4")
7233 (if_then_else
7234 (match_test "TARGET_POWERPC64")
7235 (const_string "8")
7236 (const_string "16"))))])
7237
7238 ;; 128-bit IOR/XOR
7239 (define_insn_and_split "*bool<mode>3_internal"
7240 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
7241 (match_operator:BOOL_128 3 "boolean_or_operator"
7242 [(match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
7243 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")]))]
7244 ""
7245 {
7246 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
7247 return "xxl%q3 %x0,%x1,%x2";
7248
7249 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
7250 return "v%q3 %0,%1,%2";
7251
7252 return "#";
7253 }
7254 "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
7255 [(const_int 0)]
7256 {
7257 rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, false);
7258 DONE;
7259 }
7260 [(set (attr "type")
7261 (if_then_else
7262 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
7263 (const_string "veclogical")
7264 (const_string "integer")))
7265 (set (attr "length")
7266 (if_then_else
7267 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
7268 (const_string "4")
7269 (if_then_else
7270 (match_test "TARGET_POWERPC64")
7271 (const_string "8")
7272 (const_string "16"))))])
7273
7274 ;; 128-bit ANDC/ORC
7275 (define_insn_and_split "*boolc<mode>3_internal1"
7276 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
7277 (match_operator:BOOL_128 3 "boolean_operator"
7278 [(not:BOOL_128
7279 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))
7280 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")]))]
7281 "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
7282 {
7283 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
7284 return "xxl%q3 %x0,%x1,%x2";
7285
7286 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
7287 return "v%q3 %0,%1,%2";
7288
7289 return "#";
7290 }
7291 "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
7292 && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
7293 [(const_int 0)]
7294 {
7295 rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
7296 DONE;
7297 }
7298 [(set (attr "type")
7299 (if_then_else
7300 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
7301 (const_string "veclogical")
7302 (const_string "integer")))
7303 (set (attr "length")
7304 (if_then_else
7305 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
7306 (const_string "4")
7307 (if_then_else
7308 (match_test "TARGET_POWERPC64")
7309 (const_string "8")
7310 (const_string "16"))))])
7311
7312 (define_insn_and_split "*boolc<mode>3_internal2"
7313 [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
7314 (match_operator:TI2 3 "boolean_operator"
7315 [(not:TI2
7316 (match_operand:TI2 2 "int_reg_operand" "r,0,r"))
7317 (match_operand:TI2 1 "int_reg_operand" "r,r,0")]))]
7318 "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
7319 "#"
7320 "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
7321 [(const_int 0)]
7322 {
7323 rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
7324 DONE;
7325 }
7326 [(set_attr "type" "integer")
7327 (set (attr "length")
7328 (if_then_else
7329 (match_test "TARGET_POWERPC64")
7330 (const_string "8")
7331 (const_string "16")))])
7332
7333 ;; 128-bit NAND/NOR
7334 (define_insn_and_split "*boolcc<mode>3_internal1"
7335 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
7336 (match_operator:BOOL_128 3 "boolean_operator"
7337 [(not:BOOL_128
7338 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>"))
7339 (not:BOOL_128
7340 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))]))]
7341 "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
7342 {
7343 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
7344 return "xxl%q3 %x0,%x1,%x2";
7345
7346 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
7347 return "v%q3 %0,%1,%2";
7348
7349 return "#";
7350 }
7351 "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
7352 && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
7353 [(const_int 0)]
7354 {
7355 rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
7356 DONE;
7357 }
7358 [(set (attr "type")
7359 (if_then_else
7360 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
7361 (const_string "veclogical")
7362 (const_string "integer")))
7363 (set (attr "length")
7364 (if_then_else
7365 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
7366 (const_string "4")
7367 (if_then_else
7368 (match_test "TARGET_POWERPC64")
7369 (const_string "8")
7370 (const_string "16"))))])
7371
7372 (define_insn_and_split "*boolcc<mode>3_internal2"
7373 [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
7374 (match_operator:TI2 3 "boolean_operator"
7375 [(not:TI2
7376 (match_operand:TI2 1 "int_reg_operand" "r,0,r"))
7377 (not:TI2
7378 (match_operand:TI2 2 "int_reg_operand" "r,r,0"))]))]
7379 "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
7380 "#"
7381 "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
7382 [(const_int 0)]
7383 {
7384 rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
7385 DONE;
7386 }
7387 [(set_attr "type" "integer")
7388 (set (attr "length")
7389 (if_then_else
7390 (match_test "TARGET_POWERPC64")
7391 (const_string "8")
7392 (const_string "16")))])
7393
7394
7395 ;; 128-bit EQV
7396 (define_insn_and_split "*eqv<mode>3_internal1"
7397 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
7398 (not:BOOL_128
7399 (xor:BOOL_128
7400 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")
7401 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))))]
7402 "TARGET_P8_VECTOR"
7403 {
7404 if (vsx_register_operand (operands[0], <MODE>mode))
7405 return "xxleqv %x0,%x1,%x2";
7406
7407 return "#";
7408 }
7409 "TARGET_P8_VECTOR && reload_completed
7410 && int_reg_operand (operands[0], <MODE>mode)"
7411 [(const_int 0)]
7412 {
7413 rs6000_split_logical (operands, XOR, true, false, false);
7414 DONE;
7415 }
7416 [(set (attr "type")
7417 (if_then_else
7418 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
7419 (const_string "veclogical")
7420 (const_string "integer")))
7421 (set (attr "length")
7422 (if_then_else
7423 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
7424 (const_string "4")
7425 (if_then_else
7426 (match_test "TARGET_POWERPC64")
7427 (const_string "8")
7428 (const_string "16"))))])
7429
7430 (define_insn_and_split "*eqv<mode>3_internal2"
7431 [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
7432 (not:TI2
7433 (xor:TI2
7434 (match_operand:TI2 1 "int_reg_operand" "r,0,r")
7435 (match_operand:TI2 2 "int_reg_operand" "r,r,0"))))]
7436 "!TARGET_P8_VECTOR"
7437 "#"
7438 "reload_completed && !TARGET_P8_VECTOR"
7439 [(const_int 0)]
7440 {
7441 rs6000_split_logical (operands, XOR, true, false, false);
7442 DONE;
7443 }
7444 [(set_attr "type" "integer")
7445 (set (attr "length")
7446 (if_then_else
7447 (match_test "TARGET_POWERPC64")
7448 (const_string "8")
7449 (const_string "16")))])
7450
7451 ;; 128-bit one's complement
7452 (define_insn_and_split "one_cmpl<mode>2"
7453 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
7454 (not:BOOL_128
7455 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_UNARY>")))]
7456 ""
7457 {
7458 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
7459 return "xxlnor %x0,%x1,%x1";
7460
7461 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
7462 return "vnor %0,%1,%1";
7463
7464 return "#";
7465 }
7466 "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
7467 [(const_int 0)]
7468 {
7469 rs6000_split_logical (operands, NOT, false, false, false);
7470 DONE;
7471 }
7472 [(set (attr "type")
7473 (if_then_else
7474 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
7475 (const_string "veclogical")
7476 (const_string "integer")))
7477 (set (attr "length")
7478 (if_then_else
7479 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
7480 (const_string "4")
7481 (if_then_else
7482 (match_test "TARGET_POWERPC64")
7483 (const_string "8")
7484 (const_string "16"))))])
7485
7486 \f
7487 ;; Now define ways of moving data around.
7488
7489 ;; Set up a register with a value from the GOT table
7490
7491 (define_expand "movsi_got"
7492 [(set (match_operand:SI 0 "gpc_reg_operand")
7493 (unspec:SI [(match_operand:SI 1 "got_operand")
7494 (match_dup 2)] UNSPEC_MOVSI_GOT))]
7495 "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
7496 {
7497 if (GET_CODE (operands[1]) == CONST)
7498 {
7499 rtx offset = const0_rtx;
7500 HOST_WIDE_INT value;
7501
7502 operands[1] = eliminate_constant_term (XEXP (operands[1], 0), &offset);
7503 value = INTVAL (offset);
7504 if (value != 0)
7505 {
7506 rtx tmp = (!can_create_pseudo_p ()
7507 ? operands[0]
7508 : gen_reg_rtx (Pmode));
7509 emit_insn (gen_movsi_got (tmp, operands[1]));
7510 emit_insn (gen_addsi3 (operands[0], tmp, offset));
7511 DONE;
7512 }
7513 }
7514
7515 operands[2] = rs6000_got_register (operands[1]);
7516 })
7517
7518 (define_insn "*movsi_got_internal"
7519 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
7520 (unspec:SI [(match_operand:SI 1 "got_no_const_operand" "")
7521 (match_operand:SI 2 "gpc_reg_operand" "b")]
7522 UNSPEC_MOVSI_GOT))]
7523 "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
7524 "lwz %0,%a1@got(%2)"
7525 [(set_attr "type" "load")])
7526
7527 ;; Used by sched, shorten_branches and final when the GOT pseudo reg
7528 ;; didn't get allocated to a hard register.
7529 (define_split
7530 [(set (match_operand:SI 0 "gpc_reg_operand")
7531 (unspec:SI [(match_operand:SI 1 "got_no_const_operand")
7532 (match_operand:SI 2 "memory_operand")]
7533 UNSPEC_MOVSI_GOT))]
7534 "DEFAULT_ABI == ABI_V4
7535 && flag_pic == 1
7536 && reload_completed"
7537 [(set (match_dup 0) (match_dup 2))
7538 (set (match_dup 0) (unspec:SI [(match_dup 1)(match_dup 0)]
7539 UNSPEC_MOVSI_GOT))]
7540 "")
7541
7542 ;; MR LA
7543 ;; LWZ LFIWZX LXSIWZX
7544 ;; STW STFIWX STXSIWX
7545 ;; LI LIS PLI #
7546 ;; XXLOR XXSPLTIB 0 XXSPLTIB -1 VSPLTISW
7547 ;; XXLXOR 0 XXLORC -1 P9 const
7548 ;; MTVSRWZ MFVSRWZ
7549 ;; MF%1 MT%0 NOP
7550
7551 (define_insn "*movsi_internal1"
7552 [(set (match_operand:SI 0 "nonimmediate_operand"
7553 "=r, r,
7554 r, d, v,
7555 m, ?Z, ?Z,
7556 r, r, r, r,
7557 wa, wa, wa, v,
7558 wa, v, v,
7559 wa, r,
7560 r, *h, *h")
7561 (match_operand:SI 1 "input_operand"
7562 "r, U,
7563 m, ?Z, ?Z,
7564 r, d, v,
7565 I, L, eI, n,
7566 wa, O, wM, wB,
7567 O, wM, wS,
7568 r, wa,
7569 *h, r, 0"))]
7570 "gpc_reg_operand (operands[0], SImode)
7571 || gpc_reg_operand (operands[1], SImode)"
7572 "@
7573 mr %0,%1
7574 la %0,%a1
7575 lwz%U1%X1 %0,%1
7576 lfiwzx %0,%y1
7577 lxsiwzx %x0,%y1
7578 stw%U0%X0 %1,%0
7579 stfiwx %1,%y0
7580 stxsiwx %x1,%y0
7581 li %0,%1
7582 lis %0,%v1
7583 li %0,%1
7584 #
7585 xxlor %x0,%x1,%x1
7586 xxspltib %x0,0
7587 xxspltib %x0,255
7588 vspltisw %0,%1
7589 xxlxor %x0,%x0,%x0
7590 xxlorc %x0,%x0,%x0
7591 #
7592 mtvsrwz %x0,%1
7593 mfvsrwz %0,%x1
7594 mf%1 %0
7595 mt%0 %1
7596 nop"
7597 [(set_attr "type"
7598 "*, *,
7599 load, fpload, fpload,
7600 store, fpstore, fpstore,
7601 *, *, *, *,
7602 veclogical, vecsimple, vecsimple, vecsimple,
7603 veclogical, veclogical, vecsimple,
7604 mtvsr, mfvsr,
7605 *, *, *")
7606 (set_attr "length"
7607 "*, *,
7608 *, *, *,
7609 *, *, *,
7610 *, *, *, 8,
7611 *, *, *, *,
7612 *, *, 8,
7613 *, *,
7614 *, *, *")
7615 (set_attr "isa"
7616 "*, *,
7617 *, p8v, p8v,
7618 *, p8v, p8v,
7619 *, *, p10, *,
7620 p8v, p9v, p9v, p8v,
7621 p9v, p8v, p9v,
7622 p8v, p8v,
7623 *, *, *")])
7624
7625 ;; Like movsi, but adjust a SF value to be used in a SI context, i.e.
7626 ;; (set (reg:SI ...) (subreg:SI (reg:SF ...) 0))
7627 ;;
7628 ;; Because SF values are actually stored as DF values within the vector
7629 ;; registers, we need to convert the value to the vector SF format when
7630 ;; we need to use the bits in a union or similar cases. We only need
7631 ;; to do this transformation when the value is a vector register. Loads,
7632 ;; stores, and transfers within GPRs are assumed to be safe.
7633 ;;
7634 ;; This is a more general case of reload_gpr_from_vsxsf. That insn must have
7635 ;; no alternatives, because the call is created as part of secondary_reload,
7636 ;; and operand #2's register class is used to allocate the temporary register.
7637 ;; This function is called before reload, and it creates the temporary as
7638 ;; needed.
7639
7640 ;; MR LWZ LFIWZX LXSIWZX STW
7641 ;; STFS STXSSP STXSSPX VSX->GPR VSX->VSX
7642 ;; MTVSRWZ
7643
7644 (define_insn_and_split "movsi_from_sf"
7645 [(set (match_operand:SI 0 "nonimmediate_operand"
7646 "=r, r, ?*d, ?*v, m,
7647 m, wY, Z, r, ?*wa,
7648 wa")
7649 (unspec:SI [(match_operand:SF 1 "input_operand"
7650 "r, m, Z, Z, r,
7651 f, v, wa, wa, wa,
7652 r")]
7653 UNSPEC_SI_FROM_SF))
7654 (clobber (match_scratch:V4SF 2
7655 "=X, X, X, X, X,
7656 X, X, X, wa, X,
7657 X"))]
7658 "TARGET_NO_SF_SUBREG
7659 && (register_operand (operands[0], SImode)
7660 || register_operand (operands[1], SFmode))"
7661 "@
7662 mr %0,%1
7663 lwz%U1%X1 %0,%1
7664 lfiwzx %0,%y1
7665 lxsiwzx %x0,%y1
7666 stw%U0%X0 %1,%0
7667 stfs%U0%X0 %1,%0
7668 stxssp %1,%0
7669 stxsspx %x1,%y0
7670 #
7671 xscvdpspn %x0,%x1
7672 mtvsrwz %x0,%1"
7673 "&& reload_completed
7674 && int_reg_operand (operands[0], SImode)
7675 && vsx_reg_sfsubreg_ok (operands[1], SFmode)"
7676 [(const_int 0)]
7677 {
7678 rtx op0 = operands[0];
7679 rtx op1 = operands[1];
7680 rtx op2 = operands[2];
7681 rtx op0_di = gen_rtx_REG (DImode, reg_or_subregno (op0));
7682 rtx op2_si = gen_rtx_REG (SImode, reg_or_subregno (op2));
7683
7684 emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
7685 emit_insn (gen_zero_extendsidi2 (op0_di, op2_si));
7686 DONE;
7687 }
7688 [(set_attr "type"
7689 "*, load, fpload, fpload, store,
7690 fpstore, fpstore, fpstore, mfvsr, fp,
7691 mtvsr")
7692 (set_attr "length"
7693 "*, *, *, *, *,
7694 *, *, *, 8, *,
7695 *")
7696 (set_attr "isa"
7697 "*, *, p8v, p8v, *,
7698 *, p9v, p8v, p8v, p8v,
7699 p8v")])
7700
7701 ;; movsi_from_sf with zero extension
7702 ;;
7703 ;; RLDICL LWZ LFIWZX LXSIWZX VSX->GPR
7704 ;; VSX->VSX MTVSRWZ
7705
7706 (define_insn_and_split "*movdi_from_sf_zero_ext"
7707 [(set (match_operand:DI 0 "gpc_reg_operand"
7708 "=r, r, ?*d, ?*v, r,
7709 ?v, wa")
7710 (zero_extend:DI
7711 (unspec:SI [(match_operand:SF 1 "input_operand"
7712 "r, m, Z, Z, wa,
7713 wa, r")]
7714 UNSPEC_SI_FROM_SF)))
7715 (clobber (match_scratch:V4SF 2
7716 "=X, X, X, X, wa,
7717 wa, X"))]
7718 "TARGET_DIRECT_MOVE_64BIT
7719 && (register_operand (operands[0], DImode)
7720 || register_operand (operands[1], SImode))"
7721 "@
7722 rldicl %0,%1,0,32
7723 lwz%U1%X1 %0,%1
7724 lfiwzx %0,%y1
7725 lxsiwzx %x0,%y1
7726 #
7727 #
7728 mtvsrwz %x0,%1"
7729 "&& reload_completed
7730 && register_operand (operands[0], DImode)
7731 && vsx_reg_sfsubreg_ok (operands[1], SFmode)"
7732 [(const_int 0)]
7733 {
7734 rtx op0 = operands[0];
7735 rtx op1 = operands[1];
7736 rtx op2 = operands[2];
7737 rtx op2_si = gen_rtx_REG (SImode, reg_or_subregno (op2));
7738
7739 emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
7740 emit_insn (gen_zero_extendsidi2 (op0, op2_si));
7741 DONE;
7742 }
7743 [(set_attr "type"
7744 "*, load, fpload, fpload, two,
7745 two, mtvsr")
7746 (set_attr "length"
7747 "*, *, *, *, 8,
7748 8, *")
7749 (set_attr "isa"
7750 "*, *, p8v, p8v, p8v,
7751 p9v, p8v")])
7752
7753 ;; Like movsi_from_sf, but combine a convert from DFmode to SFmode before
7754 ;; moving it to SImode. We cannot do a SFmode store without having to do the
7755 ;; conversion explicitly since that doesn't work in most cases if the input
7756 ;; isn't representable as SF. Use XSCVDPSP instead of XSCVDPSPN, since the
7757 ;; former handles cases where the input will not fit in a SFmode, and the
7758 ;; latter assumes the value has already been rounded.
7759 (define_insn "*movsi_from_df"
7760 [(set (match_operand:SI 0 "gpc_reg_operand" "=wa")
7761 (unspec:SI [(float_truncate:SF
7762 (match_operand:DF 1 "gpc_reg_operand" "wa"))]
7763 UNSPEC_SI_FROM_SF))]
7764 "TARGET_NO_SF_SUBREG"
7765 "xscvdpsp %x0,%x1"
7766 [(set_attr "type" "fp")])
7767
7768
7769 (define_code_iterator eqne [eq ne])
7770
7771 ;; "i == C" ==> "rotl(i,N) == rotl(C,N)"
7772 (define_insn_and_split "*rotate_on_cmpdi"
7773 [(set (pc)
7774 (if_then_else (eqne (match_operand:DI 1 "gpc_reg_operand" "r")
7775 (match_operand:DI 2 "const_int_operand" "n"))
7776 (label_ref (match_operand 0 ""))
7777 (pc)))
7778 (clobber (match_scratch:DI 3 "=r"))
7779 (clobber (match_scratch:CCUNS 4 "=y"))]
7780 "TARGET_POWERPC64 && num_insns_constant (operands[2], DImode) > 1
7781 && (can_be_rotated_to_positive_16bits (INTVAL (operands[2]))
7782 || can_be_rotated_to_negative_15bits (INTVAL (operands[2])))"
7783 "#"
7784 "&& 1"
7785 [(pc)]
7786 {
7787 bool sgn = false;
7788 unsigned HOST_WIDE_INT C = INTVAL (operands[2]);
7789 int rot;
7790
7791 /* cmpldi */
7792 if (!can_be_rotated_to_lowbits (C, 16, &rot))
7793 {
7794 /* cmpdi */
7795 sgn = true;
7796 bool res = can_be_rotated_to_lowbits (~C, 15, &rot);
7797 gcc_assert (res);
7798 }
7799
7800 rtx n = GEN_INT (rot);
7801
7802 /* i' = rotl (i, n) */
7803 rtx op0 = can_create_pseudo_p () ? gen_reg_rtx (DImode) : operands[3];
7804 emit_insn (gen_rtx_SET (op0, gen_rtx_ROTATE (DImode, operands[1], n)));
7805
7806 /* C' = rotl (C, n) */
7807 rtx op1 = GEN_INT ((C << rot) | (C >> (HOST_BITS_PER_WIDE_INT - rot)));
7808
7809 /* i' == C' */
7810 machine_mode comp_mode = sgn ? CCmode : CCUNSmode;
7811 rtx cc = can_create_pseudo_p () ? gen_reg_rtx (comp_mode) : operands[4];
7812 PUT_MODE (cc, comp_mode);
7813 emit_insn (gen_rtx_SET (cc, gen_rtx_COMPARE (comp_mode, op0, op1)));
7814 rtx cmp = gen_rtx_<eqne:CODE> (CCmode, cc, const0_rtx);
7815 rtx loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands[0]);
7816 emit_jump_insn (gen_rtx_SET (pc_rtx,
7817 gen_rtx_IF_THEN_ELSE (VOIDmode, cmp,
7818 loc_ref, pc_rtx)));
7819
7820 /* Keep the probability info for the prediction of the branch insn. */
7821 rtx note = find_reg_note (curr_insn, REG_BR_PROB, 0);
7822 if (note)
7823 {
7824 profile_probability prob
7825 = profile_probability::from_reg_br_prob_note (XINT (note, 0));
7826
7827 add_reg_br_prob_note (get_last_insn (), prob);
7828 }
7829
7830 DONE;
7831 })
7832
7833 ;; Split a load of a large constant into the appropriate two-insn
7834 ;; sequence.
7835
7836 (define_split
7837 [(set (match_operand:SI 0 "gpc_reg_operand")
7838 (match_operand:SI 1 "const_int_operand"))]
7839 "num_insns_constant (operands[1], SImode) > 1"
7840 [(pc)]
7841 {
7842 if (rs6000_emit_set_const (operands[0], operands[1]))
7843 DONE;
7844 else
7845 FAIL;
7846 })
7847
7848 ;; Split loading -128..127 to use XXSPLITB and VEXTSW2D
7849 (define_split
7850 [(set (match_operand:DI 0 "altivec_register_operand")
7851 (match_operand:DI 1 "xxspltib_constant_split"))]
7852 "TARGET_P9_VECTOR && reload_completed"
7853 [(const_int 0)]
7854 {
7855 rtx op0 = operands[0];
7856 rtx op1 = operands[1];
7857 int r = REGNO (op0);
7858 rtx op0_v16qi = gen_rtx_REG (V16QImode, r);
7859
7860 emit_insn (gen_xxspltib_v16qi (op0_v16qi, op1));
7861 emit_insn (gen_vsx_sign_extend_qi_si (operands[0], op0_v16qi));
7862 DONE;
7863 })
7864
7865 (define_insn "*mov<mode>_internal2"
7866 [(set (match_operand:CC 2 "cc_reg_operand" "=y,x,?y")
7867 (compare:CC (match_operand:P 1 "gpc_reg_operand" "0,r,r")
7868 (const_int 0)))
7869 (set (match_operand:P 0 "gpc_reg_operand" "=r,r,r") (match_dup 1))]
7870 ""
7871 "@
7872 cmp<wd>i %2,%0,0
7873 mr. %0,%1
7874 #"
7875 [(set_attr "type" "cmp,logical,cmp")
7876 (set_attr "dot" "yes")
7877 (set_attr "length" "4,4,8")])
7878
7879 (define_split
7880 [(set (match_operand:CC 2 "cc_reg_not_cr0_operand")
7881 (compare:CC (match_operand:P 1 "gpc_reg_operand")
7882 (const_int 0)))
7883 (set (match_operand:P 0 "gpc_reg_operand") (match_dup 1))]
7884 "reload_completed"
7885 [(set (match_dup 0) (match_dup 1))
7886 (set (match_dup 2)
7887 (compare:CC (match_dup 0)
7888 (const_int 0)))]
7889 "")
7890 \f
7891 (define_expand "mov<mode>"
7892 [(set (match_operand:INT 0 "general_operand")
7893 (match_operand:INT 1 "any_operand"))]
7894 ""
7895 {
7896 rs6000_emit_move (operands[0], operands[1], <MODE>mode);
7897 DONE;
7898 })
7899
7900 ;; MR LHZ/LBZ LXSI*ZX STH/STB STXSI*X LI
7901 ;; XXLOR load 0 load -1 VSPLTI* # MFVSRWZ
7902 ;; MTVSRWZ MF%1 MT%1 NOP
7903 (define_insn "*mov<mode>_internal"
7904 [(set (match_operand:QHI 0 "nonimmediate_operand"
7905 "=r, r, wa, m, ?Z, r,
7906 wa, wa, wa, v, ?v, r,
7907 wa, r, *c*l, *h")
7908 (match_operand:QHI 1 "input_operand"
7909 "r, m, ?Z, r, wa, i,
7910 wa, O, wM, wB, wS, wa,
7911 r, *h, r, 0"))]
7912 "gpc_reg_operand (operands[0], <MODE>mode)
7913 || gpc_reg_operand (operands[1], <MODE>mode)"
7914 "@
7915 mr %0,%1
7916 l<wd>z%U1%X1 %0,%1
7917 lxsi<wd>zx %x0,%y1
7918 st<wd>%U0%X0 %1,%0
7919 stxsi<wd>x %x1,%y0
7920 li %0,%1
7921 xxlor %x0,%x1,%x1
7922 xxspltib %x0,0
7923 xxspltib %x0,255
7924 vspltis<wd> %0,%1
7925 #
7926 mfvsrwz %0,%x1
7927 mtvsrwz %x0,%1
7928 mf%1 %0
7929 mt%0 %1
7930 nop"
7931 [(set_attr "type"
7932 "*, load, fpload, store, fpstore, *,
7933 vecsimple, vecperm, vecperm, vecperm, vecperm, mfvsr,
7934 mtvsr, mfjmpr, mtjmpr, *")
7935 (set_attr "length"
7936 "*, *, *, *, *, *,
7937 *, *, *, *, 8, *,
7938 *, *, *, *")
7939 (set_attr "isa"
7940 "*, *, p9v, *, p9v, *,
7941 p9v, p9v, p9v, p9v, p9v, p9v,
7942 p9v, *, *, *")])
7943
7944 \f
7945 ;; Here is how to move condition codes around. When we store CC data in
7946 ;; an integer register or memory, we store just the high-order 4 bits.
7947 ;; This lets us not shift in the most common case of CR0.
7948 (define_expand "movcc"
7949 [(set (match_operand:CC 0 "nonimmediate_operand")
7950 (match_operand:CC 1 "nonimmediate_operand"))]
7951 ""
7952 "")
7953
7954 (define_mode_iterator CC_any [CC CCUNS CCEQ CCFP])
7955
7956 (define_insn "*movcc_<mode>"
7957 [(set (match_operand:CC_any 0 "nonimmediate_operand"
7958 "=y,x,?y,y,r,r,r,r, r,*c*l,r,m")
7959 (match_operand:CC_any 1 "general_operand"
7960 " y,r, r,O,x,y,r,I,*h, r,m,r"))]
7961 "register_operand (operands[0], <MODE>mode)
7962 || register_operand (operands[1], <MODE>mode)"
7963 "@
7964 mcrf %0,%1
7965 mtcrf 128,%1
7966 rlwinm %1,%1,%F0,0xffffffff\;mtcrf %R0,%1\;rlwinm %1,%1,%f0,0xffffffff
7967 crxor %0,%0,%0
7968 mfcr %0%Q1
7969 mfcr %0%Q1\;rlwinm %0,%0,%f1,0xf0000000
7970 mr %0,%1
7971 li %0,%1
7972 mf%1 %0
7973 mt%0 %1
7974 lwz%U1%X1 %0,%1
7975 stw%U0%X0 %1,%0"
7976 [(set_attr_alternative "type"
7977 [(const_string "cr_logical")
7978 (const_string "mtcr")
7979 (const_string "mtcr")
7980 (const_string "cr_logical")
7981 (if_then_else (match_test "TARGET_MFCRF")
7982 (const_string "mfcrf") (const_string "mfcr"))
7983 (if_then_else (match_test "TARGET_MFCRF")
7984 (const_string "mfcrf") (const_string "mfcr"))
7985 (const_string "integer")
7986 (const_string "integer")
7987 (const_string "mfjmpr")
7988 (const_string "mtjmpr")
7989 (const_string "load")
7990 (const_string "store")])
7991 (set_attr "length" "*,*,12,*,*,8,*,*,*,*,*,*")])
7992 \f
7993 ;; For floating-point, we normally deal with the floating-point registers
7994 ;; unless -msoft-float is used. The sole exception is that parameter passing
7995 ;; can produce floating-point values in fixed-point registers. Unless the
7996 ;; value is a simple constant or already in memory, we deal with this by
7997 ;; allocating memory and copying the value explicitly via that memory location.
7998
7999 ;; Move 32-bit binary/decimal floating point
8000 (define_expand "mov<mode>"
8001 [(set (match_operand:FMOVE32 0 "nonimmediate_operand")
8002 (match_operand:FMOVE32 1 "any_operand"))]
8003 "<fmove_ok>"
8004 {
8005 rs6000_emit_move (operands[0], operands[1], <MODE>mode);
8006 DONE;
8007 })
8008
8009 (define_split
8010 [(set (match_operand:FMOVE32 0 "gpc_reg_operand")
8011 (match_operand:FMOVE32 1 "const_double_operand"))]
8012 "reload_completed
8013 && ((REG_P (operands[0]) && REGNO (operands[0]) <= 31)
8014 || (SUBREG_P (operands[0])
8015 && REG_P (SUBREG_REG (operands[0]))
8016 && REGNO (SUBREG_REG (operands[0])) <= 31))"
8017 [(set (match_dup 2) (match_dup 3))]
8018 {
8019 long l;
8020
8021 <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
8022
8023 if (! TARGET_POWERPC64)
8024 operands[2] = operand_subword (operands[0], 0, 0, <MODE>mode);
8025 else
8026 operands[2] = gen_lowpart (SImode, operands[0]);
8027
8028 operands[3] = gen_int_mode (l, SImode);
8029 })
8030
8031 ;; Originally, we tried to keep movsf and movsd common, but the differences
8032 ;; addressing was making it rather difficult to hide with mode attributes. In
8033 ;; particular for SFmode, on ISA 2.07 (power8) systems, having the GPR store
8034 ;; before the VSX stores meant that the register allocator would tend to do a
8035 ;; direct move to the GPR (which involves conversion from scalar to
8036 ;; vector/memory formats) to save values in the traditional Altivec registers,
8037 ;; while SDmode had problems on power6 if the GPR store was not first due to
8038 ;; the power6 not having an integer store operation.
8039 ;;
8040 ;; LWZ LFS LXSSP LXSSPX STFS STXSSP
8041 ;; STXSSPX STW XXLXOR LI FMR XSCPSGNDP
8042 ;; MR MT<x> MF<x> NOP XXSPLTIDP
8043
8044 (define_insn "movsf_hardfloat"
8045 [(set (match_operand:SF 0 "nonimmediate_operand"
8046 "=!r, f, v, wa, m, wY,
8047 Z, m, wa, !r, f, wa,
8048 !r, *c*l, !r, *h, wa")
8049 (match_operand:SF 1 "input_operand"
8050 "m, m, wY, Z, f, v,
8051 wa, r, j, j, f, wa,
8052 r, r, *h, 0, eP"))]
8053 "(register_operand (operands[0], SFmode)
8054 || register_operand (operands[1], SFmode))
8055 && TARGET_HARD_FLOAT
8056 && (TARGET_ALLOW_SF_SUBREG
8057 || valid_sf_si_move (operands[0], operands[1], SFmode))"
8058 "@
8059 lwz%U1%X1 %0,%1
8060 lfs%U1%X1 %0,%1
8061 lxssp %0,%1
8062 lxsspx %x0,%y1
8063 stfs%U0%X0 %1,%0
8064 stxssp %1,%0
8065 stxsspx %x1,%y0
8066 stw%U0%X0 %1,%0
8067 xxlxor %x0,%x0,%x0
8068 li %0,0
8069 fmr %0,%1
8070 xscpsgndp %x0,%x1,%x1
8071 mr %0,%1
8072 mt%0 %1
8073 mf%1 %0
8074 nop
8075 #"
8076 [(set_attr "type"
8077 "load, fpload, fpload, fpload, fpstore, fpstore,
8078 fpstore, store, veclogical, integer, fpsimple, fpsimple,
8079 *, mtjmpr, mfjmpr, *, vecperm")
8080 (set_attr "isa"
8081 "*, *, p9v, p8v, *, p9v,
8082 p8v, *, *, *, *, *,
8083 *, *, *, *, p10")
8084 (set_attr "prefixed"
8085 "*, *, *, *, *, *,
8086 *, *, *, *, *, *,
8087 *, *, *, *, yes")])
8088
8089 ;; LWZ LFIWZX STW STFIWX MTVSRWZ MFVSRWZ
8090 ;; FMR MR MT%0 MF%1 NOP
8091 (define_insn "movsd_hardfloat"
8092 [(set (match_operand:SD 0 "nonimmediate_operand"
8093 "=!r, d, m, ?Z, ?d, ?r,
8094 f, !r, *c*l, !r, *h")
8095 (match_operand:SD 1 "input_operand"
8096 "m, ?Z, r, wx, r, d,
8097 f, r, r, *h, 0"))]
8098 "(register_operand (operands[0], SDmode)
8099 || register_operand (operands[1], SDmode))
8100 && TARGET_HARD_FLOAT"
8101 "@
8102 lwz%U1%X1 %0,%1
8103 lfiwzx %0,%y1
8104 stw%U0%X0 %1,%0
8105 stfiwx %1,%y0
8106 mtvsrwz %x0,%1
8107 mfvsrwz %0,%x1
8108 fmr %0,%1
8109 mr %0,%1
8110 mt%0 %1
8111 mf%1 %0
8112 nop"
8113 [(set_attr "type"
8114 "load, fpload, store, fpstore, mtvsr, mfvsr,
8115 fpsimple, *, mtjmpr, mfjmpr, *")
8116 (set_attr "isa"
8117 "*, p7, *, *, p8v, p8v,
8118 *, *, *, *, *")])
8119
8120 ;; MR MT%0 MF%0 LWZ STW LI
8121 ;; LIS G-const. F/n-const NOP
8122 (define_insn "*mov<mode>_softfloat"
8123 [(set (match_operand:FMOVE32 0 "nonimmediate_operand"
8124 "=r, *c*l, r, r, m, r,
8125 r, r, r, *h")
8126
8127 (match_operand:FMOVE32 1 "input_operand"
8128 "r, r, *h, m, r, I,
8129 L, G, Fn, 0"))]
8130
8131 "(gpc_reg_operand (operands[0], <MODE>mode)
8132 || gpc_reg_operand (operands[1], <MODE>mode))
8133 && TARGET_SOFT_FLOAT"
8134 "@
8135 mr %0,%1
8136 mt%0 %1
8137 mf%1 %0
8138 lwz%U1%X1 %0,%1
8139 stw%U0%X0 %1,%0
8140 li %0,%1
8141 lis %0,%v1
8142 #
8143 #
8144 nop"
8145 [(set_attr "type"
8146 "*, mtjmpr, mfjmpr, load, store, *,
8147 *, *, *, *")
8148
8149 (set_attr "length"
8150 "*, *, *, *, *, *,
8151 *, *, 8, *")])
8152
8153 ;; Like movsf, but adjust a SI value to be used in a SF context, i.e.
8154 ;; (set (reg:SF ...) (subreg:SF (reg:SI ...) 0))
8155 ;;
8156 ;; Because SF values are actually stored as DF values within the vector
8157 ;; registers, we need to convert the value to the vector SF format when
8158 ;; we need to use the bits in a union or similar cases. We only need
8159 ;; to do this transformation when the value is a vector register. Loads,
8160 ;; stores, and transfers within GPRs are assumed to be safe.
8161 ;;
8162 ;; This is a more general case of reload_vsx_from_gprsf. That insn must have
8163 ;; no alternatives, because the call is created as part of secondary_reload,
8164 ;; and operand #2's register class is used to allocate the temporary register.
8165 ;; This function is called before reload, and it creates the temporary as
8166 ;; needed.
8167
8168 ;; LWZ LFS LXSSP LXSSPX STW STFIWX
8169 ;; STXSIWX GPR->VSX VSX->GPR GPR->GPR
8170 (define_insn_and_split "movsf_from_si"
8171 [(set (match_operand:SF 0 "nonimmediate_operand"
8172 "=!r, f, v, wa, m, Z,
8173 Z, wa, ?r, !r")
8174 (unspec:SF [(match_operand:SI 1 "input_operand"
8175 "m, m, wY, Z, r, f,
8176 wa, r, wa, r")]
8177 UNSPEC_SF_FROM_SI))
8178 (clobber (match_scratch:DI 2
8179 "=X, X, X, X, X, X,
8180 X, r, X, X"))]
8181 "TARGET_NO_SF_SUBREG
8182 && (register_operand (operands[0], SFmode)
8183 || register_operand (operands[1], SImode))"
8184 "@
8185 lwz%U1%X1 %0,%1
8186 lfs%U1%X1 %0,%1
8187 lxssp %0,%1
8188 lxsspx %x0,%y1
8189 stw%U0%X0 %1,%0
8190 stfiwx %1,%y0
8191 stxsiwx %x1,%y0
8192 #
8193 mfvsrwz %0,%x1
8194 mr %0,%1"
8195
8196 "&& reload_completed
8197 && vsx_reg_sfsubreg_ok (operands[0], SFmode)
8198 && int_reg_operand_not_pseudo (operands[1], SImode)"
8199 [(const_int 0)]
8200 {
8201 rtx op0 = operands[0];
8202 rtx op1 = operands[1];
8203 rtx op2 = operands[2];
8204 rtx op1_di = gen_rtx_REG (DImode, REGNO (op1));
8205
8206 /* Move SF value to upper 32-bits for xscvspdpn. */
8207 emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32)));
8208 emit_insn (gen_p8_mtvsrd_sf (op0, op2));
8209 emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0));
8210 DONE;
8211 }
8212 [(set_attr "length"
8213 "*, *, *, *, *, *,
8214 *, 12, *, *")
8215 (set_attr "type"
8216 "load, fpload, fpload, fpload, store, fpstore,
8217 fpstore, vecfloat, mfvsr, *")
8218 (set_attr "isa"
8219 "*, *, p9v, p8v, *, *,
8220 p8v, p8v, p8v, *")])
8221
8222 ;; For extracting high part element from DImode register like:
8223 ;; {%1:SF=unspec[r122:DI>>0x20#0] 86;clobber scratch;}
8224 ;; split it before reload with "and mask" to avoid generating shift right
8225 ;; 32 bit then shift left 32 bit.
8226 (define_insn_and_split "movsf_from_si2"
8227 [(set (match_operand:SF 0 "gpc_reg_operand" "=wa")
8228 (unspec:SF
8229 [(subreg:SI
8230 (ashiftrt:DI
8231 (match_operand:DI 1 "input_operand" "r")
8232 (const_int 32))
8233 0)]
8234 UNSPEC_SF_FROM_SI))
8235 (clobber (match_scratch:DI 2 "=r"))]
8236 "TARGET_NO_SF_SUBREG"
8237 "#"
8238 "&& 1"
8239 [(const_int 0)]
8240 {
8241 if (GET_CODE (operands[2]) == SCRATCH)
8242 operands[2] = gen_reg_rtx (DImode);
8243
8244 rtx mask = GEN_INT (HOST_WIDE_INT_M1U << 32);
8245 emit_insn (gen_anddi3 (operands[2], operands[1], mask));
8246 emit_insn (gen_p8_mtvsrd_sf (operands[0], operands[2]));
8247 emit_insn (gen_vsx_xscvspdpn_directmove (operands[0], operands[0]));
8248 DONE;
8249 }
8250 [(set_attr "length" "12")
8251 (set_attr "type" "vecfloat")
8252 (set_attr "isa" "p8v")])
8253 \f
8254 ;; Move 64-bit binary/decimal floating point
8255 (define_expand "mov<mode>"
8256 [(set (match_operand:FMOVE64 0 "nonimmediate_operand")
8257 (match_operand:FMOVE64 1 "any_operand"))]
8258 ""
8259 {
8260 rs6000_emit_move (operands[0], operands[1], <MODE>mode);
8261 DONE;
8262 })
8263
8264 (define_split
8265 [(set (match_operand:FMOVE64 0 "gpc_reg_operand")
8266 (match_operand:FMOVE64 1 "const_int_operand"))]
8267 "! TARGET_POWERPC64 && reload_completed
8268 && ((REG_P (operands[0]) && REGNO (operands[0]) <= 31)
8269 || (SUBREG_P (operands[0])
8270 && REG_P (SUBREG_REG (operands[0]))
8271 && REGNO (SUBREG_REG (operands[0])) <= 31))"
8272 [(set (match_dup 2) (match_dup 4))
8273 (set (match_dup 3) (match_dup 1))]
8274 {
8275 int endian = (WORDS_BIG_ENDIAN == 0);
8276 HOST_WIDE_INT value = INTVAL (operands[1]);
8277
8278 operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
8279 operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
8280 operands[4] = GEN_INT (value >> 32);
8281 operands[1] = GEN_INT (sext_hwi (value, 32));
8282 })
8283
8284 (define_split
8285 [(set (match_operand:FMOVE64 0 "gpc_reg_operand")
8286 (match_operand:FMOVE64 1 "const_double_operand"))]
8287 "! TARGET_POWERPC64 && reload_completed
8288 && ((REG_P (operands[0]) && REGNO (operands[0]) <= 31)
8289 || (SUBREG_P (operands[0])
8290 && REG_P (SUBREG_REG (operands[0]))
8291 && REGNO (SUBREG_REG (operands[0])) <= 31))"
8292 [(set (match_dup 2) (match_dup 4))
8293 (set (match_dup 3) (match_dup 5))]
8294 {
8295 int endian = (WORDS_BIG_ENDIAN == 0);
8296 long l[2];
8297
8298 <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
8299
8300 operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
8301 operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
8302 operands[4] = gen_int_mode (l[endian], SImode);
8303 operands[5] = gen_int_mode (l[1 - endian], SImode);
8304 })
8305
8306 (define_split
8307 [(set (match_operand:FMOVE64 0 "gpc_reg_operand")
8308 (match_operand:FMOVE64 1 "const_double_operand"))]
8309 "TARGET_POWERPC64 && reload_completed
8310 && ((REG_P (operands[0]) && REGNO (operands[0]) <= 31)
8311 || (SUBREG_P (operands[0])
8312 && REG_P (SUBREG_REG (operands[0]))
8313 && REGNO (SUBREG_REG (operands[0])) <= 31))"
8314 [(set (match_dup 2) (match_dup 3))]
8315 {
8316 int endian = (WORDS_BIG_ENDIAN == 0);
8317 long l[2];
8318 HOST_WIDE_INT val;
8319
8320 <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
8321
8322 operands[2] = gen_lowpart (DImode, operands[0]);
8323 /* HIGHPART is lower memory address when WORDS_BIG_ENDIAN. */
8324 val = ((HOST_WIDE_INT)(unsigned long)l[endian] << 32
8325 | ((HOST_WIDE_INT)(unsigned long)l[1 - endian]));
8326
8327 operands[3] = gen_int_mode (val, DImode);
8328 })
8329
8330 ;; Don't have reload use general registers to load a constant. It is
8331 ;; less efficient than loading the constant into an FP register, since
8332 ;; it will probably be used there.
8333
8334 ;; The move constraints are ordered to prefer floating point registers before
8335 ;; general purpose registers to avoid doing a store and a load to get the value
8336 ;; into a floating point register when it is needed for a floating point
8337 ;; operation. Prefer traditional floating point registers over VSX registers,
8338 ;; since the D-form version of the memory instructions does not need a GPR for
8339 ;; reloading. ISA 3.0 (power9) adds D-form addressing for scalars to Altivec
8340 ;; registers.
8341
8342 ;; If we have FPR registers, rs6000_emit_move has moved all constants to memory,
8343 ;; except for 0.0 which can be created on VSX with an xor instruction.
8344
8345 ;; STFD LFD FMR LXSD STXSD
8346 ;; LXSD STXSD XXLOR XXLXOR GPR<-0
8347 ;; LWZ STW MR XXSPLTIDP
8348
8349
8350 (define_insn "*mov<mode>_hardfloat32"
8351 [(set (match_operand:FMOVE64 0 "nonimmediate_operand"
8352 "=m, d, d, <f64_p9>, wY,
8353 <f64_av>, Z, <f64_vsx>, <f64_vsx>, !r,
8354 Y, r, !r, wa")
8355 (match_operand:FMOVE64 1 "input_operand"
8356 "d, m, d, wY, <f64_p9>,
8357 Z, <f64_av>, <f64_vsx>, <zero_fp>, <zero_fp>,
8358 r, Y, r, eP"))]
8359 "! TARGET_POWERPC64 && TARGET_HARD_FLOAT
8360 && (gpc_reg_operand (operands[0], <MODE>mode)
8361 || gpc_reg_operand (operands[1], <MODE>mode))"
8362 "@
8363 stfd%U0%X0 %1,%0
8364 lfd%U1%X1 %0,%1
8365 fmr %0,%1
8366 lxsd %0,%1
8367 stxsd %1,%0
8368 lxsdx %x0,%y1
8369 stxsdx %x1,%y0
8370 xxlor %x0,%x1,%x1
8371 xxlxor %x0,%x0,%x0
8372 #
8373 #
8374 #
8375 #
8376 #"
8377 [(set_attr "type"
8378 "fpstore, fpload, fpsimple, fpload, fpstore,
8379 fpload, fpstore, veclogical, veclogical, two,
8380 store, load, two, vecperm")
8381 (set_attr "size" "64")
8382 (set_attr "length"
8383 "*, *, *, *, *,
8384 *, *, *, *, 8,
8385 8, 8, 8, *")
8386 (set_attr "isa"
8387 "*, *, *, p9v, p9v,
8388 p7v, p7v, *, *, *,
8389 *, *, *, p10")
8390 (set_attr "prefixed"
8391 "*, *, *, *, *,
8392 *, *, *, *, *,
8393 *, *, *, yes")])
8394
8395 ;; STW LWZ MR G-const H-const F-const
8396
8397 (define_insn "*mov<mode>_softfloat32"
8398 [(set (match_operand:FMOVE64 0 "nonimmediate_operand"
8399 "=Y, r, r, r, r, r")
8400
8401 (match_operand:FMOVE64 1 "input_operand"
8402 "r, Y, r, G, H, F"))]
8403
8404 "!TARGET_POWERPC64
8405 && (gpc_reg_operand (operands[0], <MODE>mode)
8406 || gpc_reg_operand (operands[1], <MODE>mode))"
8407 "#"
8408 [(set_attr "type"
8409 "store, load, two, *, *, *")
8410
8411 (set_attr "length"
8412 "8, 8, 8, 8, 12, 16")])
8413
8414 ; ld/std require word-aligned displacements -> 'Y' constraint.
8415 ; List Y->r and r->Y before r->r for reload.
8416
8417 ;; STFD LFD FMR LXSD STXSD
8418 ;; LXSDX STXSDX XXLOR XXLXOR LI 0
8419 ;; STD LD MR MT{CTR,LR} MF{CTR,LR}
8420 ;; NOP MFVSRD MTVSRD XXSPLTIDP
8421
8422 (define_insn "*mov<mode>_hardfloat64"
8423 [(set (match_operand:FMOVE64 0 "nonimmediate_operand"
8424 "=m, d, d, <f64_p9>, wY,
8425 <f64_av>, Z, <f64_vsx>, <f64_vsx>, !r,
8426 YZ, r, !r, *c*l, !r,
8427 *h, r, <f64_dm>, wa")
8428 (match_operand:FMOVE64 1 "input_operand"
8429 "d, m, d, wY, <f64_p9>,
8430 Z, <f64_av>, <f64_vsx>, <zero_fp>, <zero_fp>,
8431 r, YZ, r, r, *h,
8432 0, <f64_dm>, r, eP"))]
8433 "TARGET_POWERPC64 && TARGET_HARD_FLOAT
8434 && (gpc_reg_operand (operands[0], <MODE>mode)
8435 || gpc_reg_operand (operands[1], <MODE>mode))"
8436 "@
8437 stfd%U0%X0 %1,%0
8438 lfd%U1%X1 %0,%1
8439 fmr %0,%1
8440 lxsd %0,%1
8441 stxsd %1,%0
8442 lxsdx %x0,%y1
8443 stxsdx %x1,%y0
8444 xxlor %x0,%x1,%x1
8445 xxlxor %x0,%x0,%x0
8446 li %0,0
8447 std%U0%X0 %1,%0
8448 ld%U1%X1 %0,%1
8449 mr %0,%1
8450 mt%0 %1
8451 mf%1 %0
8452 nop
8453 mfvsrd %0,%x1
8454 mtvsrd %x0,%1
8455 #"
8456 [(set_attr "type"
8457 "fpstore, fpload, fpsimple, fpload, fpstore,
8458 fpload, fpstore, veclogical, veclogical, integer,
8459 store, load, *, mtjmpr, mfjmpr,
8460 *, mfvsr, mtvsr, vecperm")
8461 (set_attr "size" "64")
8462 (set_attr "isa"
8463 "*, *, *, p9v, p9v,
8464 p7v, p7v, *, *, *,
8465 *, *, *, *, *,
8466 *, p8v, p8v, p10")
8467 (set_attr "prefixed"
8468 "*, *, *, *, *,
8469 *, *, *, *, *,
8470 *, *, *, *, *,
8471 *, *, *, *")])
8472
8473 ;; STD LD MR MT<SPR> MF<SPR> G-const
8474 ;; H-const F-const Special
8475
8476 (define_insn "*mov<mode>_softfloat64"
8477 [(set (match_operand:FMOVE64 0 "nonimmediate_operand"
8478 "=Y, r, r, *c*l, r, r,
8479 r, r, *h")
8480
8481 (match_operand:FMOVE64 1 "input_operand"
8482 "r, Y, r, r, *h, G,
8483 H, F, 0"))]
8484
8485 "TARGET_POWERPC64 && TARGET_SOFT_FLOAT
8486 && (gpc_reg_operand (operands[0], <MODE>mode)
8487 || gpc_reg_operand (operands[1], <MODE>mode))"
8488 "@
8489 std%U0%X0 %1,%0
8490 ld%U1%X1 %0,%1
8491 mr %0,%1
8492 mt%0 %1
8493 mf%1 %0
8494 #
8495 #
8496 #
8497 nop"
8498 [(set_attr "type"
8499 "store, load, *, mtjmpr, mfjmpr, *,
8500 *, *, *")
8501
8502 (set_attr "length"
8503 "*, *, *, *, *, 8,
8504 12, 16, *")])
8505
8506 ;; Split the VSX prefixed instruction to support SFmode and DFmode scalar
8507 ;; constants that look like DFmode floating point values where both elements
8508 ;; are the same. The constant has to be expressible as a SFmode constant that
8509 ;; is not a SFmode denormal value.
8510 ;;
8511 ;; We don't need splitters for the 128-bit types, since the function
8512 ;; rs6000_output_move_128bit handles the generation of XXSPLTIDP.
8513 (define_insn "xxspltidp_<mode>_internal"
8514 [(set (match_operand:SFDF 0 "register_operand" "=wa")
8515 (unspec:SFDF [(match_operand:SI 1 "c32bit_cint_operand" "n")]
8516 UNSPEC_XXSPLTIDP_CONST))]
8517 "TARGET_POWER10"
8518 "xxspltidp %x0,%1"
8519 [(set_attr "type" "vecperm")
8520 (set_attr "prefixed" "yes")])
8521
8522 (define_insn "xxspltiw_<mode>_internal"
8523 [(set (match_operand:SFDF 0 "register_operand" "=wa")
8524 (unspec:SFDF [(match_operand:SI 1 "c32bit_cint_operand" "n")]
8525 UNSPEC_XXSPLTIW_CONST))]
8526 "TARGET_POWER10"
8527 "xxspltiw %x0,%1"
8528 [(set_attr "type" "vecperm")
8529 (set_attr "prefixed" "yes")])
8530
8531 (define_split
8532 [(set (match_operand:SFDF 0 "vsx_register_operand")
8533 (match_operand:SFDF 1 "vsx_prefixed_constant"))]
8534 "TARGET_POWER10"
8535 [(pc)]
8536 {
8537 rtx dest = operands[0];
8538 rtx src = operands[1];
8539 vec_const_128bit_type vsx_const;
8540
8541 if (!vec_const_128bit_to_bytes (src, <MODE>mode, &vsx_const))
8542 gcc_unreachable ();
8543
8544 unsigned imm = constant_generates_xxspltidp (&vsx_const);
8545 if (imm)
8546 {
8547 emit_insn (gen_xxspltidp_<mode>_internal (dest, GEN_INT (imm)));
8548 DONE;
8549 }
8550
8551 imm = constant_generates_xxspltiw (&vsx_const);
8552 if (imm)
8553 {
8554 emit_insn (gen_xxspltiw_<mode>_internal (dest, GEN_INT (imm)));
8555 DONE;
8556 }
8557
8558 else
8559 gcc_unreachable ();
8560 })
8561 \f
8562 (define_expand "mov<mode>"
8563 [(set (match_operand:FMOVE128 0 "general_operand")
8564 (match_operand:FMOVE128 1 "any_operand"))]
8565 ""
8566 {
8567 rs6000_emit_move (operands[0], operands[1], <MODE>mode);
8568 DONE;
8569 })
8570
8571 ;; It's important to list Y->r and r->Y before r->r because otherwise
8572 ;; reload, given m->r, will try to pick r->r and reload it, which
8573 ;; doesn't make progress.
8574
8575 ;; We can't split little endian direct moves of TDmode, because the words are
8576 ;; not swapped like they are for TImode or TFmode. Subregs therefore are
8577 ;; problematical. Don't allow direct move for this case.
8578
8579 ;; FPR load FPR store FPR move FPR zero GPR load
8580 ;; GPR zero GPR store GPR move MFVSRD MTVSRD
8581
8582 (define_insn_and_split "*mov<mode>_64bit_dm"
8583 [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand"
8584 "=m, d, d, d, Y,
8585 r, r, r, r, d")
8586
8587 (match_operand:FMOVE128_FPR 1 "input_operand"
8588 "d, m, d, <zero_fp>, r,
8589 <zero_fp>, Y, r, d, r"))]
8590
8591 "TARGET_HARD_FLOAT && TARGET_POWERPC64 && FLOAT128_2REG_P (<MODE>mode)
8592 && (<MODE>mode != TDmode || WORDS_BIG_ENDIAN)
8593 && (gpc_reg_operand (operands[0], <MODE>mode)
8594 || gpc_reg_operand (operands[1], <MODE>mode))"
8595 "#"
8596 "&& reload_completed"
8597 [(pc)]
8598 {
8599 rs6000_split_multireg_move (operands[0], operands[1]);
8600 DONE;
8601 }
8602 [(set_attr "length" "8")
8603 (set_attr "isa" "*,*,*,*,*,*,*,*,p8v,p8v")
8604 (set_attr "max_prefixed_insns" "2")
8605 (set_attr "num_insns" "2")])
8606
8607 (define_insn_and_split "*movtd_64bit_nodm"
8608 [(set (match_operand:TD 0 "nonimmediate_operand" "=m,d,d,Y,r,r")
8609 (match_operand:TD 1 "input_operand" "d,m,d,r,Y,r"))]
8610 "TARGET_HARD_FLOAT && TARGET_POWERPC64 && !WORDS_BIG_ENDIAN
8611 && (gpc_reg_operand (operands[0], TDmode)
8612 || gpc_reg_operand (operands[1], TDmode))"
8613 "#"
8614 "&& reload_completed"
8615 [(pc)]
8616 {
8617 rs6000_split_multireg_move (operands[0], operands[1]);
8618 DONE;
8619 }
8620 [(set_attr "length" "8,8,8,12,12,8")
8621 (set_attr "max_prefixed_insns" "2")
8622 (set_attr "num_insns" "2,2,2,3,3,2")])
8623
8624 (define_insn_and_split "*mov<mode>_32bit"
8625 [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand" "=m,d,d,d,Y,r,r")
8626 (match_operand:FMOVE128_FPR 1 "input_operand" "d,m,d,<zero_fp>,r,<zero_fp>Y,r"))]
8627 "TARGET_HARD_FLOAT && !TARGET_POWERPC64
8628 && (FLOAT128_2REG_P (<MODE>mode)
8629 || int_reg_operand_not_pseudo (operands[0], <MODE>mode)
8630 || int_reg_operand_not_pseudo (operands[1], <MODE>mode))
8631 && (gpc_reg_operand (operands[0], <MODE>mode)
8632 || gpc_reg_operand (operands[1], <MODE>mode))"
8633 "#"
8634 "&& reload_completed"
8635 [(pc)]
8636 {
8637 rs6000_split_multireg_move (operands[0], operands[1]);
8638 DONE;
8639 }
8640 [(set_attr "length" "8,8,8,8,20,20,16")])
8641
8642 (define_insn_and_split "*mov<mode>_softfloat"
8643 [(set (match_operand:FMOVE128 0 "nonimmediate_operand" "=Y,r,r,r")
8644 (match_operand:FMOVE128 1 "input_operand" "r,Y,F,r"))]
8645 "TARGET_SOFT_FLOAT
8646 && (gpc_reg_operand (operands[0], <MODE>mode)
8647 || gpc_reg_operand (operands[1], <MODE>mode))"
8648 "#"
8649 "&& reload_completed"
8650 [(pc)]
8651 {
8652 rs6000_split_multireg_move (operands[0], operands[1]);
8653 DONE;
8654 }
8655 [(set_attr_alternative "length"
8656 [(if_then_else (match_test "TARGET_POWERPC64")
8657 (const_string "8")
8658 (const_string "16"))
8659 (if_then_else (match_test "TARGET_POWERPC64")
8660 (const_string "8")
8661 (const_string "16"))
8662 (if_then_else (match_test "TARGET_POWERPC64")
8663 (const_string "16")
8664 (const_string "32"))
8665 (if_then_else (match_test "TARGET_POWERPC64")
8666 (const_string "8")
8667 (const_string "16"))])])
8668
8669 (define_expand "@extenddf<mode>2"
8670 [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
8671 (float_extend:FLOAT128 (match_operand:DF 1 "gpc_reg_operand")))]
8672 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8673 {
8674 if (FLOAT128_IEEE_P (<MODE>mode))
8675 rs6000_expand_float128_convert (operands[0], operands[1], false);
8676 else if (TARGET_VSX)
8677 emit_insn (gen_extenddf2_vsx (<MODE>mode, operands[0], operands[1]));
8678 else
8679 {
8680 rtx zero = gen_reg_rtx (DFmode);
8681 rs6000_emit_move (zero, CONST0_RTX (DFmode), DFmode);
8682
8683 emit_insn (gen_extenddf2_fprs (<MODE>mode,
8684 operands[0], operands[1], zero));
8685 }
8686 DONE;
8687 })
8688
8689 ;; Allow memory operands for the source to be created by the combiner.
8690 (define_insn_and_split "@extenddf<mode>2_fprs"
8691 [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d,&d")
8692 (float_extend:IBM128
8693 (match_operand:DF 1 "nonimmediate_operand" "d,m,d")))
8694 (use (match_operand:DF 2 "nonimmediate_operand" "m,m,d"))]
8695 "!TARGET_VSX && TARGET_HARD_FLOAT
8696 && TARGET_LONG_DOUBLE_128 && FLOAT128_IBM_P (<MODE>mode)"
8697 "#"
8698 "&& reload_completed"
8699 [(set (match_dup 3) (match_dup 1))
8700 (set (match_dup 4) (match_dup 2))]
8701 {
8702 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
8703 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
8704
8705 operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
8706 operands[4] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
8707 })
8708
8709 (define_insn_and_split "@extenddf<mode>2_vsx"
8710 [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d")
8711 (float_extend:IBM128
8712 (match_operand:DF 1 "nonimmediate_operand" "wa,m")))]
8713 "TARGET_LONG_DOUBLE_128 && TARGET_VSX && FLOAT128_IBM_P (<MODE>mode)"
8714 "#"
8715 "&& reload_completed"
8716 [(set (match_dup 2) (match_dup 1))
8717 (set (match_dup 3) (match_dup 4))]
8718 {
8719 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
8720 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
8721
8722 operands[2] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
8723 operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
8724 operands[4] = CONST0_RTX (DFmode);
8725 })
8726
8727 (define_expand "extendsf<mode>2"
8728 [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
8729 (float_extend:FLOAT128 (match_operand:SF 1 "gpc_reg_operand")))]
8730 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8731 {
8732 if (FLOAT128_IEEE_P (<MODE>mode))
8733 rs6000_expand_float128_convert (operands[0], operands[1], false);
8734 else
8735 {
8736 rtx tmp = gen_reg_rtx (DFmode);
8737 emit_insn (gen_extendsfdf2 (tmp, operands[1]));
8738 emit_insn (gen_extenddf<mode>2 (operands[0], tmp));
8739 }
8740 DONE;
8741 })
8742
8743 (define_expand "trunc<mode>df2"
8744 [(set (match_operand:DF 0 "gpc_reg_operand")
8745 (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand")))]
8746 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8747 {
8748 if (FLOAT128_IEEE_P (<MODE>mode))
8749 {
8750 rs6000_expand_float128_convert (operands[0], operands[1], false);
8751 DONE;
8752 }
8753 })
8754
8755 (define_insn_and_split "trunc<mode>df2_internal1"
8756 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d")
8757 (float_truncate:DF
8758 (match_operand:IBM128 1 "gpc_reg_operand" "0,d")))]
8759 "FLOAT128_IBM_P (<MODE>mode) && !TARGET_XL_COMPAT
8760 && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8761 "@
8762 #
8763 fmr %0,%1"
8764 "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
8765 [(const_int 0)]
8766 {
8767 emit_note (NOTE_INSN_DELETED);
8768 DONE;
8769 }
8770 [(set_attr "type" "fpsimple")])
8771
8772 (define_insn "trunc<mode>df2_internal2"
8773 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
8774 (float_truncate:DF (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
8775 "FLOAT128_IBM_P (<MODE>mode) && TARGET_XL_COMPAT && TARGET_HARD_FLOAT
8776 && TARGET_LONG_DOUBLE_128"
8777 "fadd %0,%1,%L1"
8778 [(set_attr "type" "fp")])
8779
8780 (define_expand "trunc<mode>sf2"
8781 [(set (match_operand:SF 0 "gpc_reg_operand")
8782 (float_truncate:SF (match_operand:FLOAT128 1 "gpc_reg_operand")))]
8783 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8784 {
8785 if (FLOAT128_IEEE_P (<MODE>mode))
8786 rs6000_expand_float128_convert (operands[0], operands[1], false);
8787 else
8788 {
8789 rtx tmp = gen_reg_rtx (DFmode);
8790 emit_insn (gen_trunc<mode>df2 (tmp, operands[1]));
8791 emit_insn (gen_truncdfsf2 (operands[0], tmp));
8792 }
8793 DONE;
8794 })
8795
8796 (define_expand "floatsi<mode>2"
8797 [(parallel [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
8798 (float:FLOAT128 (match_operand:SI 1 "gpc_reg_operand")))
8799 (clobber (match_scratch:DI 2))])]
8800 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8801 {
8802 rtx op0 = operands[0];
8803 rtx op1 = operands[1];
8804
8805 if (TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode))
8806 ;
8807 else if (FLOAT128_IEEE_P (<MODE>mode))
8808 {
8809 rs6000_expand_float128_convert (op0, op1, false);
8810 DONE;
8811 }
8812 else
8813 {
8814 rtx tmp = gen_reg_rtx (DFmode);
8815 expand_float (tmp, op1, false);
8816 emit_insn (gen_extenddf2 (<MODE>mode, op0, tmp));
8817 DONE;
8818 }
8819 })
8820
8821 ; fadd, but rounding towards zero.
8822 ; This is probably not the optimal code sequence.
8823 (define_insn "fix_trunc_helper<mode>"
8824 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
8825 (unspec:DF [(match_operand:IBM128 1 "gpc_reg_operand" "d")]
8826 UNSPEC_FIX_TRUNC_TF))
8827 (clobber (match_operand:DF 2 "gpc_reg_operand" "=&d"))]
8828 "TARGET_HARD_FLOAT && FLOAT128_IBM_P (<MODE>mode)"
8829 "mffs %2\n\tmtfsb1 31\n\tmtfsb0 30\n\tfadd %0,%1,%L1\n\tmtfsf 1,%2"
8830 [(set_attr "type" "fp")
8831 (set_attr "length" "20")])
8832
8833 (define_expand "fix_trunc<mode>si2"
8834 [(set (match_operand:SI 0 "gpc_reg_operand")
8835 (fix:SI (match_operand:FLOAT128 1 "gpc_reg_operand")))]
8836 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8837 {
8838 rtx op0 = operands[0];
8839 rtx op1 = operands[1];
8840
8841 if (TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode))
8842 ;
8843 else
8844 {
8845 if (FLOAT128_IEEE_P (<MODE>mode))
8846 rs6000_expand_float128_convert (op0, op1, false);
8847 else
8848 emit_insn (gen_fix_truncsi2_fprs (<MODE>mode, op0, op1));
8849 DONE;
8850 }
8851 })
8852
8853 (define_expand "@fix_trunc<mode>si2_fprs"
8854 [(parallel [(set (match_operand:SI 0 "gpc_reg_operand")
8855 (fix:SI (match_operand:IBM128 1 "gpc_reg_operand")))
8856 (clobber (match_dup 2))
8857 (clobber (match_dup 3))
8858 (clobber (match_dup 4))
8859 (clobber (match_dup 5))])]
8860 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8861 {
8862 operands[2] = gen_reg_rtx (DFmode);
8863 operands[3] = gen_reg_rtx (DFmode);
8864 operands[4] = gen_reg_rtx (DImode);
8865 operands[5] = assign_stack_temp (DImode, GET_MODE_SIZE (DImode));
8866 })
8867
8868 (define_insn_and_split "*fix_trunc<mode>si2_internal"
8869 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
8870 (fix:SI (match_operand:IBM128 1 "gpc_reg_operand" "d")))
8871 (clobber (match_operand:DF 2 "gpc_reg_operand" "=d"))
8872 (clobber (match_operand:DF 3 "gpc_reg_operand" "=&d"))
8873 (clobber (match_operand:DI 4 "gpc_reg_operand" "=d"))
8874 (clobber (match_operand:DI 5 "offsettable_mem_operand" "=o"))]
8875 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8876 "#"
8877 "&& 1"
8878 [(pc)]
8879 {
8880 rtx lowword;
8881 emit_insn (gen_fix_trunc_helper<mode> (operands[2], operands[1],
8882 operands[3]));
8883
8884 gcc_assert (MEM_P (operands[5]));
8885 lowword = adjust_address (operands[5], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
8886
8887 emit_insn (gen_fctiwz_df (operands[4], operands[2]));
8888 emit_move_insn (operands[5], operands[4]);
8889 emit_move_insn (operands[0], lowword);
8890 DONE;
8891 })
8892
8893 (define_expand "fix_trunc<mode>di2"
8894 [(set (match_operand:DI 0 "gpc_reg_operand")
8895 (fix:DI (match_operand:IEEE128 1 "gpc_reg_operand")))]
8896 "TARGET_FLOAT128_TYPE"
8897 {
8898 if (!TARGET_FLOAT128_HW)
8899 {
8900 rs6000_expand_float128_convert (operands[0], operands[1], false);
8901 DONE;
8902 }
8903 })
8904
8905 (define_expand "fixuns_trunc<IEEE128:mode><SDI:mode>2"
8906 [(set (match_operand:SDI 0 "gpc_reg_operand")
8907 (unsigned_fix:SDI (match_operand:IEEE128 1 "gpc_reg_operand")))]
8908 "TARGET_FLOAT128_TYPE"
8909 {
8910 rs6000_expand_float128_convert (operands[0], operands[1], true);
8911 DONE;
8912 })
8913
8914 (define_expand "floatdi<mode>2"
8915 [(set (match_operand:IEEE128 0 "gpc_reg_operand")
8916 (float:IEEE128 (match_operand:DI 1 "gpc_reg_operand")))]
8917 "TARGET_FLOAT128_TYPE"
8918 {
8919 if (!TARGET_FLOAT128_HW)
8920 {
8921 rs6000_expand_float128_convert (operands[0], operands[1], false);
8922 DONE;
8923 }
8924 })
8925
8926 (define_expand "floatunsdi<IEEE128:mode>2"
8927 [(set (match_operand:IEEE128 0 "gpc_reg_operand")
8928 (unsigned_float:IEEE128 (match_operand:DI 1 "gpc_reg_operand")))]
8929 "TARGET_FLOAT128_TYPE"
8930 {
8931 if (!TARGET_FLOAT128_HW)
8932 {
8933 rs6000_expand_float128_convert (operands[0], operands[1], true);
8934 DONE;
8935 }
8936 })
8937
8938 (define_expand "floatuns<IEEE128:mode>2"
8939 [(set (match_operand:IEEE128 0 "gpc_reg_operand")
8940 (unsigned_float:IEEE128 (match_operand:SI 1 "gpc_reg_operand")))]
8941 "TARGET_FLOAT128_TYPE"
8942 {
8943 rtx op0 = operands[0];
8944 rtx op1 = operands[1];
8945
8946 if (TARGET_FLOAT128_HW)
8947 emit_insn (gen_floatuns_<IEEE128:mode>si2_hw (op0, op1));
8948 else
8949 rs6000_expand_float128_convert (op0, op1, true);
8950 DONE;
8951 })
8952
8953 (define_expand "neg<mode>2"
8954 [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
8955 (neg:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand")))]
8956 "FLOAT128_IEEE_P (<MODE>mode)
8957 || (FLOAT128_IBM_P (<MODE>mode) && TARGET_HARD_FLOAT)"
8958 {
8959 if (FLOAT128_IEEE_P (<MODE>mode))
8960 {
8961 if (TARGET_FLOAT128_HW)
8962 emit_insn (gen_neg2_hw (<MODE>mode, operands[0], operands[1]));
8963 else if (TARGET_FLOAT128_TYPE)
8964 emit_insn (gen_ieee_128bit_vsx_neg2 (<MODE>mode,
8965 operands[0], operands[1]));
8966 else
8967 {
8968 rtx libfunc = optab_libfunc (neg_optab, <MODE>mode);
8969 rtx target = emit_library_call_value (libfunc, operands[0], LCT_CONST,
8970 <MODE>mode,
8971 operands[1], <MODE>mode);
8972
8973 if (target && !rtx_equal_p (target, operands[0]))
8974 emit_move_insn (operands[0], target);
8975 }
8976 DONE;
8977 }
8978 })
8979
8980 (define_insn "neg<mode>2_internal"
8981 [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d")
8982 (neg:IBM128 (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
8983 "TARGET_HARD_FLOAT && FLOAT128_IBM_P (<MODE>mode)"
8984 {
8985 if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
8986 return "fneg %L0,%L1\;fneg %0,%1";
8987 else
8988 return "fneg %0,%1\;fneg %L0,%L1";
8989 }
8990 [(set_attr "type" "fpsimple")
8991 (set_attr "length" "8")])
8992
8993 (define_expand "abs<mode>2"
8994 [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
8995 (abs:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand")))]
8996 "FLOAT128_IEEE_P (<MODE>mode)
8997 || (FLOAT128_IBM_P (<MODE>mode) && TARGET_HARD_FLOAT)"
8998 {
8999 rtx label;
9000
9001 if (FLOAT128_IEEE_P (<MODE>mode))
9002 {
9003 if (TARGET_FLOAT128_HW)
9004 {
9005 emit_insn (gen_abs2_hw (<MODE>mode, operands[0], operands[1]));
9006 DONE;
9007 }
9008 else if (TARGET_FLOAT128_TYPE)
9009 {
9010 emit_insn (gen_ieee_128bit_vsx_abs2 (<MODE>mode,
9011 operands[0], operands[1]));
9012 DONE;
9013 }
9014 else
9015 FAIL;
9016 }
9017
9018 label = gen_label_rtx ();
9019 emit_insn (gen_abs2_internal (<MODE>mode, operands[0], operands[1], label));
9020 emit_label (label);
9021 DONE;
9022 })
9023
9024 (define_expand "@abs<mode>2_internal"
9025 [(set (match_operand:IBM128 0 "gpc_reg_operand")
9026 (match_operand:IBM128 1 "gpc_reg_operand"))
9027 (set (match_dup 3) (match_dup 5))
9028 (set (match_dup 5) (abs:DF (match_dup 5)))
9029 (set (match_dup 4) (compare:CCFP (match_dup 3) (match_dup 5)))
9030 (set (pc) (if_then_else (eq (match_dup 4) (const_int 0))
9031 (label_ref (match_operand 2 ""))
9032 (pc)))
9033 (set (match_dup 6) (neg:DF (match_dup 6)))]
9034 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
9035 {
9036 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
9037 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
9038 operands[3] = gen_reg_rtx (DFmode);
9039 operands[4] = gen_reg_rtx (CCFPmode);
9040 operands[5] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
9041 operands[6] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
9042 })
9043
9044 \f
9045 ;; Generate IEEE 128-bit -0.0 (0x80000000000000000000000000000000) in a vector
9046 ;; register
9047
9048 (define_expand "ieee_128bit_negative_zero"
9049 [(set (match_operand:V16QI 0 "register_operand") (match_dup 1))]
9050 "TARGET_FLOAT128_TYPE"
9051 {
9052 rtvec v = rtvec_alloc (16);
9053 int i, high;
9054
9055 for (i = 0; i < 16; i++)
9056 RTVEC_ELT (v, i) = const0_rtx;
9057
9058 high = (BYTES_BIG_ENDIAN) ? 0 : 15;
9059 RTVEC_ELT (v, high) = gen_int_mode (0x80, QImode);
9060
9061 rs6000_expand_vector_init (operands[0], gen_rtx_PARALLEL (V16QImode, v));
9062 DONE;
9063 })
9064
9065 ;; IEEE 128-bit negate
9066
9067 ;; We have 2 insns here for negate and absolute value. The first uses
9068 ;; match_scratch so that phases like combine can recognize neg/abs as generic
9069 ;; insns, and second insn after the first split pass loads up the bit to
9070 ;; twiddle the sign bit. Later GCSE passes can then combine multiple uses of
9071 ;; neg/abs to create the constant just once.
9072
9073 (define_insn_and_split "@ieee_128bit_vsx_neg<mode>2"
9074 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
9075 (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
9076 (clobber (match_scratch:V16QI 2 "=v"))]
9077 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
9078 "#"
9079 "&& 1"
9080 [(parallel [(set (match_dup 0)
9081 (neg:IEEE128 (match_dup 1)))
9082 (use (match_dup 2))])]
9083 {
9084 if (GET_CODE (operands[2]) == SCRATCH)
9085 operands[2] = gen_reg_rtx (V16QImode);
9086
9087 operands[3] = gen_reg_rtx (V16QImode);
9088 emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
9089 }
9090 [(set_attr "length" "8")
9091 (set_attr "type" "vecsimple")])
9092
9093 (define_insn "*ieee_128bit_vsx_neg<mode>2_internal"
9094 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
9095 (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
9096 (use (match_operand:V16QI 2 "register_operand" "v"))]
9097 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
9098 "xxlxor %x0,%x1,%x2"
9099 [(set_attr "type" "veclogical")])
9100
9101 ;; IEEE 128-bit absolute value
9102 (define_insn_and_split "@ieee_128bit_vsx_abs<mode>2"
9103 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
9104 (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
9105 (clobber (match_scratch:V16QI 2 "=v"))]
9106 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
9107 "#"
9108 "&& 1"
9109 [(parallel [(set (match_dup 0)
9110 (abs:IEEE128 (match_dup 1)))
9111 (use (match_dup 2))])]
9112 {
9113 if (GET_CODE (operands[2]) == SCRATCH)
9114 operands[2] = gen_reg_rtx (V16QImode);
9115
9116 operands[3] = gen_reg_rtx (V16QImode);
9117 emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
9118 }
9119 [(set_attr "length" "8")
9120 (set_attr "type" "vecsimple")])
9121
9122 (define_insn "*ieee_128bit_vsx_abs<mode>2_internal"
9123 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
9124 (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
9125 (use (match_operand:V16QI 2 "register_operand" "v"))]
9126 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
9127 "xxlandc %x0,%x1,%x2"
9128 [(set_attr "type" "veclogical")])
9129
9130 ;; IEEE 128-bit negative absolute value
9131 (define_insn_and_split "*ieee_128bit_vsx_nabs<mode>2"
9132 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
9133 (neg:IEEE128
9134 (abs:IEEE128
9135 (match_operand:IEEE128 1 "register_operand" "wa"))))
9136 (clobber (match_scratch:V16QI 2 "=v"))]
9137 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW
9138 && FLOAT128_IEEE_P (<MODE>mode)"
9139 "#"
9140 "&& 1"
9141 [(parallel [(set (match_dup 0)
9142 (neg:IEEE128 (abs:IEEE128 (match_dup 1))))
9143 (use (match_dup 2))])]
9144 {
9145 if (GET_CODE (operands[2]) == SCRATCH)
9146 operands[2] = gen_reg_rtx (V16QImode);
9147
9148 operands[3] = gen_reg_rtx (V16QImode);
9149 emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
9150 }
9151 [(set_attr "length" "8")
9152 (set_attr "type" "vecsimple")])
9153
9154 (define_insn "*ieee_128bit_vsx_nabs<mode>2_internal"
9155 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
9156 (neg:IEEE128
9157 (abs:IEEE128
9158 (match_operand:IEEE128 1 "register_operand" "wa"))))
9159 (use (match_operand:V16QI 2 "register_operand" "v"))]
9160 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
9161 "xxlor %x0,%x1,%x2"
9162 [(set_attr "type" "veclogical")])
9163
9164 ;; Float128 conversion functions. These expand to library function calls.
9165 ;; We use expand to convert from IBM double double to IEEE 128-bit
9166 ;; and trunc for the opposite.
9167 (define_expand "extendiftf2"
9168 [(set (match_operand:TF 0 "gpc_reg_operand")
9169 (float_extend:TF (match_operand:IF 1 "gpc_reg_operand")))]
9170 "TARGET_FLOAT128_TYPE"
9171 {
9172 rs6000_expand_float128_convert (operands[0], operands[1], false);
9173 DONE;
9174 })
9175
9176 (define_expand "extendifkf2"
9177 [(set (match_operand:KF 0 "gpc_reg_operand")
9178 (float_extend:KF (match_operand:IF 1 "gpc_reg_operand")))]
9179 "TARGET_FLOAT128_TYPE"
9180 {
9181 rs6000_expand_float128_convert (operands[0], operands[1], false);
9182 DONE;
9183 })
9184
9185 (define_expand "extendtfkf2"
9186 [(set (match_operand:KF 0 "gpc_reg_operand")
9187 (float_extend:KF (match_operand:TF 1 "gpc_reg_operand")))]
9188 "TARGET_FLOAT128_TYPE"
9189 {
9190 rs6000_expand_float128_convert (operands[0], operands[1], false);
9191 DONE;
9192 })
9193
9194 (define_expand "extendtfif2"
9195 [(set (match_operand:IF 0 "gpc_reg_operand")
9196 (float_extend:IF (match_operand:TF 1 "gpc_reg_operand")))]
9197 "TARGET_FLOAT128_TYPE"
9198 {
9199 rs6000_expand_float128_convert (operands[0], operands[1], false);
9200 DONE;
9201 })
9202
9203 (define_expand "trunciftf2"
9204 [(set (match_operand:TF 0 "gpc_reg_operand")
9205 (float_truncate:TF (match_operand:IF 1 "gpc_reg_operand")))]
9206 "TARGET_FLOAT128_TYPE"
9207 {
9208 rs6000_expand_float128_convert (operands[0], operands[1], false);
9209 DONE;
9210 })
9211
9212 (define_expand "truncifkf2"
9213 [(set (match_operand:KF 0 "gpc_reg_operand")
9214 (float_truncate:KF (match_operand:IF 1 "gpc_reg_operand")))]
9215 "TARGET_FLOAT128_TYPE"
9216 {
9217 rs6000_expand_float128_convert (operands[0], operands[1], false);
9218 DONE;
9219 })
9220
9221 (define_expand "trunckftf2"
9222 [(set (match_operand:TF 0 "gpc_reg_operand")
9223 (float_truncate:TF (match_operand:KF 1 "gpc_reg_operand")))]
9224 "TARGET_FLOAT128_TYPE"
9225 {
9226 rs6000_expand_float128_convert (operands[0], operands[1], false);
9227 DONE;
9228 })
9229
9230 (define_expand "trunctfif2"
9231 [(set (match_operand:IF 0 "gpc_reg_operand")
9232 (float_truncate:IF (match_operand:TF 1 "gpc_reg_operand")))]
9233 "TARGET_FLOAT128_TYPE"
9234 {
9235 rs6000_expand_float128_convert (operands[0], operands[1], false);
9236 DONE;
9237 })
9238
9239 (define_insn_and_split "*extend<mode>tf2_internal"
9240 [(set (match_operand:TF 0 "gpc_reg_operand" "=<IFKF_reg>")
9241 (float_extend:TF
9242 (match_operand:IFKF 1 "gpc_reg_operand" "<IFKF_reg>")))]
9243 "TARGET_FLOAT128_TYPE
9244 && FLOAT128_IBM_P (TFmode) == FLOAT128_IBM_P (<MODE>mode)"
9245 "#"
9246 "&& reload_completed"
9247 [(set (match_dup 0) (match_dup 2))]
9248 {
9249 operands[2] = gen_rtx_REG (TFmode, REGNO (operands[1]));
9250 })
9251
9252 (define_insn_and_split "*extendtf<mode>2_internal"
9253 [(set (match_operand:IFKF 0 "gpc_reg_operand" "=<IFKF_reg>")
9254 (float_extend:IFKF
9255 (match_operand:TF 1 "gpc_reg_operand" "<IFKF_reg>")))]
9256 "TARGET_FLOAT128_TYPE
9257 && FLOAT128_IBM_P (TFmode) == FLOAT128_IBM_P (<MODE>mode)"
9258 "#"
9259 "&& reload_completed"
9260 [(set (match_dup 0) (match_dup 2))]
9261 {
9262 operands[2] = gen_rtx_REG (<MODE>mode, REGNO (operands[1]));
9263 })
9264
9265 \f
9266 ;; Reload helper functions used by rs6000_secondary_reload. The patterns all
9267 ;; must have 3 arguments, and scratch register constraint must be a single
9268 ;; constraint.
9269
9270 ;; Reload patterns to support gpr load/store with misaligned mem.
9271 ;; and multiple gpr load/store at offset >= 0xfffc
9272 (define_expand "reload_<mode>_store"
9273 [(parallel [(match_operand 0 "memory_operand" "=m")
9274 (match_operand 1 "gpc_reg_operand" "r")
9275 (match_operand:GPR 2 "register_operand" "=&b")])]
9276 ""
9277 {
9278 rs6000_secondary_reload_gpr (operands[1], operands[0], operands[2], true);
9279 DONE;
9280 })
9281
9282 (define_expand "reload_<mode>_load"
9283 [(parallel [(match_operand 0 "gpc_reg_operand" "=r")
9284 (match_operand 1 "memory_operand" "m")
9285 (match_operand:GPR 2 "register_operand" "=b")])]
9286 ""
9287 {
9288 rs6000_secondary_reload_gpr (operands[0], operands[1], operands[2], false);
9289 DONE;
9290 })
9291
9292 \f
9293 ;; Reload patterns for various types using the vector registers. We may need
9294 ;; an additional base register to convert the reg+offset addressing to reg+reg
9295 ;; for vector registers and reg+reg or (reg+reg)&(-16) addressing to just an
9296 ;; index register for gpr registers.
9297 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_store"
9298 [(parallel [(match_operand:RELOAD 0 "memory_operand" "m")
9299 (match_operand:RELOAD 1 "gpc_reg_operand" "wa")
9300 (match_operand:P 2 "register_operand" "=b")])]
9301 "<P:tptrsize>"
9302 {
9303 rs6000_secondary_reload_inner (operands[1], operands[0], operands[2], true);
9304 DONE;
9305 })
9306
9307 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_load"
9308 [(parallel [(match_operand:RELOAD 0 "gpc_reg_operand" "wa")
9309 (match_operand:RELOAD 1 "memory_operand" "m")
9310 (match_operand:P 2 "register_operand" "=b")])]
9311 "<P:tptrsize>"
9312 {
9313 rs6000_secondary_reload_inner (operands[0], operands[1], operands[2], false);
9314 DONE;
9315 })
9316
9317
9318 ;; Reload sometimes tries to move the address to a GPR, and can generate
9319 ;; invalid RTL for addresses involving AND -16. Allow addresses involving
9320 ;; reg+reg, reg+small constant, or just reg, all wrapped in an AND -16.
9321
9322 (define_insn_and_split "*vec_reload_and_plus_<mptrsize>"
9323 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9324 (and:P (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
9325 (match_operand:P 2 "reg_or_cint_operand" "rI"))
9326 (const_int -16)))]
9327 "TARGET_ALTIVEC && reload_completed"
9328 "#"
9329 "&& reload_completed"
9330 [(set (match_dup 0)
9331 (plus:P (match_dup 1)
9332 (match_dup 2)))
9333 (set (match_dup 0)
9334 (and:P (match_dup 0)
9335 (const_int -16)))])
9336 \f
9337 ;; Power8 merge instructions to allow direct move to/from floating point
9338 ;; registers in 32-bit mode. We use TF mode to get two registers to move the
9339 ;; individual 32-bit parts across. Subreg doesn't work too well on the TF
9340 ;; value, since it is allocated in reload and not all of the flow information
9341 ;; is setup for it. We have two patterns to do the two moves between gprs and
9342 ;; fprs. There isn't a dependancy between the two, but we could potentially
9343 ;; schedule other instructions between the two instructions.
9344
9345 (define_insn "p8_fmrgow_<mode>"
9346 [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
9347 (unspec:FMOVE64X [
9348 (match_operand:DF 1 "register_operand" "d")
9349 (match_operand:DF 2 "register_operand" "d")]
9350 UNSPEC_P8V_FMRGOW))]
9351 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
9352 "fmrgow %0,%1,%2"
9353 [(set_attr "type" "fpsimple")])
9354
9355 (define_insn "p8_mtvsrwz"
9356 [(set (match_operand:DF 0 "register_operand" "=d")
9357 (unspec:DF [(match_operand:SI 1 "register_operand" "r")]
9358 UNSPEC_P8V_MTVSRWZ))]
9359 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
9360 "mtvsrwz %x0,%1"
9361 [(set_attr "type" "mtvsr")])
9362
9363 (define_insn "p8_mtvsrwz_v16qisi2"
9364 [(set (match_operand:V16QI 0 "register_operand" "=wa")
9365 (unspec:V16QI [(match_operand:SI 1 "register_operand" "r")]
9366 UNSPEC_P8V_MTVSRWZ))]
9367 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
9368 "mtvsrwz %x0,%1"
9369 [(set_attr "type" "mtvsr")])
9370
9371 (define_insn "p8_mtvsrd_v16qidi2"
9372 [(set (match_operand:V16QI 0 "register_operand" "=wa")
9373 (unspec:V16QI [(match_operand:DI 1 "register_operand" "r")]
9374 UNSPEC_P8V_MTVSRD))]
9375 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
9376 "mtvsrd %x0,%1"
9377 [(set_attr "type" "mtvsr")])
9378
9379 (define_insn_and_split "reload_fpr_from_gpr<mode>"
9380 [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
9381 (unspec:FMOVE64X [(match_operand:FMOVE64X 1 "register_operand" "r")]
9382 UNSPEC_P8V_RELOAD_FROM_GPR))
9383 (clobber (match_operand:IF 2 "register_operand" "=d"))]
9384 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
9385 "#"
9386 "&& reload_completed"
9387 [(const_int 0)]
9388 {
9389 rtx dest = operands[0];
9390 rtx src = operands[1];
9391 rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0);
9392 rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8);
9393 rtx gpr_hi_reg = gen_highpart (SImode, src);
9394 rtx gpr_lo_reg = gen_lowpart (SImode, src);
9395
9396 emit_insn (gen_p8_mtvsrwz (tmp_hi, gpr_hi_reg));
9397 emit_insn (gen_p8_mtvsrwz (tmp_lo, gpr_lo_reg));
9398 emit_insn (gen_p8_fmrgow_<mode> (dest, tmp_hi, tmp_lo));
9399 DONE;
9400 }
9401 [(set_attr "length" "12")
9402 (set_attr "type" "three")])
9403
9404 ;; Move 128 bit values from GPRs to VSX registers in 64-bit mode
9405 (define_insn "p8_mtvsrd_df"
9406 [(set (match_operand:DF 0 "register_operand" "=wa")
9407 (unspec:DF [(match_operand:DI 1 "register_operand" "r")]
9408 UNSPEC_P8V_MTVSRD))]
9409 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
9410 "mtvsrd %x0,%1"
9411 [(set_attr "type" "mtvsr")])
9412
9413 (define_insn "p8_xxpermdi_<mode>"
9414 [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
9415 (unspec:FMOVE128_GPR [
9416 (match_operand:DF 1 "register_operand" "wa")
9417 (match_operand:DF 2 "register_operand" "wa")]
9418 UNSPEC_P8V_XXPERMDI))]
9419 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
9420 "xxpermdi %x0,%x1,%x2,0"
9421 [(set_attr "type" "vecperm")])
9422
9423 (define_insn_and_split "reload_vsx_from_gpr<mode>"
9424 [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
9425 (unspec:FMOVE128_GPR
9426 [(match_operand:FMOVE128_GPR 1 "register_operand" "r")]
9427 UNSPEC_P8V_RELOAD_FROM_GPR))
9428 (clobber (match_operand:IF 2 "register_operand" "=wa"))]
9429 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
9430 "#"
9431 "&& reload_completed"
9432 [(const_int 0)]
9433 {
9434 rtx dest = operands[0];
9435 rtx src = operands[1];
9436 /* You might think that we could use op0 as one temp and a DF clobber
9437 as op2, but you'd be wrong. Secondary reload move patterns don't
9438 check for overlap of the clobber and the destination. */
9439 rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0);
9440 rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8);
9441 rtx gpr_hi_reg = gen_highpart (DImode, src);
9442 rtx gpr_lo_reg = gen_lowpart (DImode, src);
9443
9444 emit_insn (gen_p8_mtvsrd_df (tmp_hi, gpr_hi_reg));
9445 emit_insn (gen_p8_mtvsrd_df (tmp_lo, gpr_lo_reg));
9446 emit_insn (gen_p8_xxpermdi_<mode> (dest, tmp_hi, tmp_lo));
9447 DONE;
9448 }
9449 [(set_attr "length" "12")
9450 (set_attr "type" "three")])
9451
9452 (define_split
9453 [(set (match_operand:FMOVE128_GPR 0 "nonimmediate_operand")
9454 (match_operand:FMOVE128_GPR 1 "input_operand"))]
9455 "reload_completed
9456 && (int_reg_operand (operands[0], <MODE>mode)
9457 || int_reg_operand (operands[1], <MODE>mode))
9458 && (!TARGET_DIRECT_MOVE_128
9459 || (!vsx_register_operand (operands[0], <MODE>mode)
9460 && !vsx_register_operand (operands[1], <MODE>mode)))"
9461 [(pc)]
9462 {
9463 rs6000_split_multireg_move (operands[0], operands[1]);
9464 DONE;
9465 })
9466
9467 ;; Move SFmode to a VSX from a GPR register. Because scalar floating point
9468 ;; type is stored internally as double precision in the VSX registers, we have
9469 ;; to convert it from the vector format.
9470 (define_insn "p8_mtvsrd_sf"
9471 [(set (match_operand:SF 0 "register_operand" "=wa")
9472 (unspec:SF [(match_operand:DI 1 "register_operand" "r")]
9473 UNSPEC_P8V_MTVSRD))]
9474 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
9475 "mtvsrd %x0,%1"
9476 [(set_attr "type" "mtvsr")])
9477
9478 (define_insn_and_split "reload_vsx_from_gprsf"
9479 [(set (match_operand:SF 0 "register_operand" "=wa")
9480 (unspec:SF [(match_operand:SF 1 "register_operand" "r")]
9481 UNSPEC_P8V_RELOAD_FROM_GPR))
9482 (clobber (match_operand:DI 2 "register_operand" "=r"))]
9483 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
9484 "#"
9485 "&& reload_completed"
9486 [(const_int 0)]
9487 {
9488 rtx op0 = operands[0];
9489 rtx op1 = operands[1];
9490 rtx op2 = operands[2];
9491 rtx op1_di = simplify_gen_subreg (DImode, op1, SFmode, 0);
9492
9493 /* Move SF value to upper 32-bits for xscvspdpn. */
9494 emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32)));
9495 emit_insn (gen_p8_mtvsrd_sf (op0, op2));
9496 emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0));
9497 DONE;
9498 }
9499 [(set_attr "length" "8")
9500 (set_attr "type" "two")])
9501
9502 ;; Move 128 bit values from VSX registers to GPRs in 64-bit mode by doing a
9503 ;; normal 64-bit move, followed by an xxpermdi to get the bottom 64-bit value,
9504 ;; and then doing a move of that.
9505 (define_insn "p8_mfvsrd_3_<mode>"
9506 [(set (match_operand:DF 0 "register_operand" "=r")
9507 (unspec:DF [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
9508 UNSPEC_P8V_RELOAD_FROM_VSX))]
9509 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
9510 "mfvsrd %0,%x1"
9511 [(set_attr "type" "mfvsr")])
9512
9513 (define_insn_and_split "reload_gpr_from_vsx<mode>"
9514 [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=r")
9515 (unspec:FMOVE128_GPR
9516 [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
9517 UNSPEC_P8V_RELOAD_FROM_VSX))
9518 (clobber (match_operand:FMOVE128_GPR 2 "register_operand" "=wa"))]
9519 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
9520 "#"
9521 "&& reload_completed"
9522 [(const_int 0)]
9523 {
9524 rtx dest = operands[0];
9525 rtx src = operands[1];
9526 rtx tmp = operands[2];
9527 rtx gpr_hi_reg = gen_highpart (DFmode, dest);
9528 rtx gpr_lo_reg = gen_lowpart (DFmode, dest);
9529
9530 emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_hi_reg, src));
9531 emit_insn (gen_vsx_xxpermdi_<mode>_be (tmp, src, src, GEN_INT (3)));
9532 emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_lo_reg, tmp));
9533 DONE;
9534 }
9535 [(set_attr "length" "12")
9536 (set_attr "type" "three")])
9537
9538 ;; Move SFmode to a GPR from a VSX register. Because scalar floating point
9539 ;; type is stored internally as double precision, we have to convert it to the
9540 ;; vector format.
9541
9542 (define_insn_and_split "reload_gpr_from_vsxsf"
9543 [(set (match_operand:SF 0 "register_operand" "=r")
9544 (unspec:SF [(match_operand:SF 1 "register_operand" "wa")]
9545 UNSPEC_P8V_RELOAD_FROM_VSX))
9546 (clobber (match_operand:V4SF 2 "register_operand" "=wa"))]
9547 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
9548 "#"
9549 "&& reload_completed"
9550 [(const_int 0)]
9551 {
9552 rtx op0 = operands[0];
9553 rtx op1 = operands[1];
9554 rtx op2 = operands[2];
9555 rtx op0_di = gen_rtx_REG (DImode, reg_or_subregno (op0));
9556 rtx op2_si = gen_rtx_REG (SImode, reg_or_subregno (op2));
9557
9558 emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
9559 emit_insn (gen_zero_extendsidi2 (op0_di, op2_si));
9560 DONE;
9561 }
9562 [(set_attr "length" "8")
9563 (set_attr "type" "two")
9564 (set_attr "isa" "p8v")])
9565 \f
9566 ;; Next come the multi-word integer load and store and the load and store
9567 ;; multiple insns.
9568
9569 ;; List r->r after r->Y, otherwise reload will try to reload a
9570 ;; non-offsettable address by using r->r which won't make progress.
9571 ;; Use of fprs is disparaged slightly otherwise reload prefers to reload
9572 ;; a gpr into a fpr instead of reloading an invalid 'Y' address
9573
9574 ;; GPR store GPR load GPR move FPR store FPR load FPR move
9575 ;; GPR const AVX store AVX store AVX load AVX load VSX move
9576 ;; P9 0 P9 -1 AVX 0/-1 VSX 0 VSX -1 P9 const
9577 ;; AVX const
9578
9579 (define_insn "*movdi_internal32"
9580 [(set (match_operand:DI 0 "nonimmediate_operand"
9581 "=Y, r, r, m, ^d, ^d,
9582 r, wY, Z, ^v, $v, ^wa,
9583 wa, wa, v, wa, *i, v,
9584 v")
9585 (match_operand:DI 1 "input_operand"
9586 "r, Y, r, ^d, m, ^d,
9587 IJKnF, ^v, $v, wY, Z, ^wa,
9588 Oj, wM, OjwM, Oj, wM, wS,
9589 wB"))]
9590 "! TARGET_POWERPC64
9591 && (gpc_reg_operand (operands[0], DImode)
9592 || gpc_reg_operand (operands[1], DImode))"
9593 "@
9594 #
9595 #
9596 #
9597 stfd%U0%X0 %1,%0
9598 lfd%U1%X1 %0,%1
9599 fmr %0,%1
9600 #
9601 stxsd %1,%0
9602 stxsdx %x1,%y0
9603 lxsd %0,%1
9604 lxsdx %x0,%y1
9605 xxlor %x0,%x1,%x1
9606 xxspltib %x0,0
9607 xxspltib %x0,255
9608 vspltisw %0,%1
9609 xxlxor %x0,%x0,%x0
9610 xxlorc %x0,%x0,%x0
9611 #
9612 #"
9613 [(set_attr "type"
9614 "store, load, *, fpstore, fpload, fpsimple,
9615 *, fpstore, fpstore, fpload, fpload, veclogical,
9616 vecsimple, vecsimple, vecsimple, veclogical,veclogical,vecsimple,
9617 vecsimple")
9618 (set_attr "size" "64")
9619 (set_attr "length"
9620 "8, 8, 8, *, *, *,
9621 16, *, *, *, *, *,
9622 *, *, *, *, *, 8,
9623 *")
9624 (set_attr "isa"
9625 "*, *, *, *, *, *,
9626 *, p9v, p7v, p9v, p7v, *,
9627 p9v, p9v, p7v, *, *, p7v,
9628 p7v")])
9629
9630 (define_split
9631 [(set (match_operand:DI 0 "gpc_reg_operand")
9632 (match_operand:DI 1 "const_int_operand"))]
9633 "! TARGET_POWERPC64 && reload_completed
9634 && gpr_or_gpr_p (operands[0], operands[1])
9635 && !direct_move_p (operands[0], operands[1])"
9636 [(set (match_dup 2) (match_dup 4))
9637 (set (match_dup 3) (match_dup 1))]
9638 {
9639 HOST_WIDE_INT value = INTVAL (operands[1]);
9640 operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
9641 DImode);
9642 operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
9643 DImode);
9644 operands[4] = GEN_INT (value >> 32);
9645 operands[1] = GEN_INT (sext_hwi (value, 32));
9646 })
9647
9648 (define_split
9649 [(set (match_operand:DIFD 0 "nonimmediate_operand")
9650 (match_operand:DIFD 1 "input_operand"))]
9651 "reload_completed && !TARGET_POWERPC64
9652 && gpr_or_gpr_p (operands[0], operands[1])
9653 && !direct_move_p (operands[0], operands[1])"
9654 [(pc)]
9655 {
9656 rs6000_split_multireg_move (operands[0], operands[1]);
9657 DONE;
9658 })
9659
9660 ;; GPR store GPR load GPR move
9661 ;; GPR li GPR lis GPR pli GPR #
9662 ;; FPR store FPR load FPR move
9663 ;; AVX store AVX store AVX load AVX load VSX move
9664 ;; P9 0 P9 -1 AVX 0/-1 VSX 0 VSX -1
9665 ;; P9 const AVX const
9666 ;; From SPR To SPR SPR<->SPR
9667 ;; VSX->GPR GPR->VSX
9668 (define_insn "*movdi_internal64"
9669 [(set (match_operand:DI 0 "nonimmediate_operand"
9670 "=YZ, r, r,
9671 r, r, r, r,
9672 m, ^d, ^d,
9673 wY, Z, $v, $v, ^wa,
9674 wa, wa, v, wa, wa,
9675 v, v,
9676 r, *h, *h,
9677 ?r, ?wa")
9678 (match_operand:DI 1 "input_operand"
9679 "r, YZ, r,
9680 I, L, eI, nF,
9681 ^d, m, ^d,
9682 ^v, $v, wY, Z, ^wa,
9683 Oj, wM, OjwM, Oj, wM,
9684 wS, wB,
9685 *h, r, 0,
9686 wa, r"))]
9687 "TARGET_POWERPC64
9688 && (gpc_reg_operand (operands[0], DImode)
9689 || gpc_reg_operand (operands[1], DImode))"
9690 "@
9691 std%U0%X0 %1,%0
9692 ld%U1%X1 %0,%1
9693 mr %0,%1
9694 li %0,%1
9695 lis %0,%v1
9696 li %0,%1
9697 #
9698 stfd%U0%X0 %1,%0
9699 lfd%U1%X1 %0,%1
9700 fmr %0,%1
9701 stxsd %1,%0
9702 stxsdx %x1,%y0
9703 lxsd %0,%1
9704 lxsdx %x0,%y1
9705 xxlor %x0,%x1,%x1
9706 xxspltib %x0,0
9707 xxspltib %x0,255
9708 #
9709 xxlxor %x0,%x0,%x0
9710 xxlorc %x0,%x0,%x0
9711 #
9712 #
9713 mf%1 %0
9714 mt%0 %1
9715 nop
9716 mfvsrd %0,%x1
9717 mtvsrd %x0,%1"
9718 [(set_attr "type"
9719 "store, load, *,
9720 *, *, *, *,
9721 fpstore, fpload, fpsimple,
9722 fpstore, fpstore, fpload, fpload, veclogical,
9723 vecsimple, vecsimple, vecsimple, veclogical, veclogical,
9724 vecsimple, vecsimple,
9725 mfjmpr, mtjmpr, *,
9726 mfvsr, mtvsr")
9727 (set_attr "size" "64")
9728 (set_attr "length"
9729 "*, *, *,
9730 *, *, *, 20,
9731 *, *, *,
9732 *, *, *, *, *,
9733 *, *, *, *, *,
9734 8, *,
9735 *, *, *,
9736 *, *")
9737 (set_attr "isa"
9738 "*, *, *,
9739 *, *, p10, *,
9740 *, *, *,
9741 p9v, p7v, p9v, p7v, *,
9742 p9v, p9v, p7v, *, *,
9743 p7v, p7v,
9744 *, *, *,
9745 p8v, p8v")])
9746
9747 ; Some DImode loads are best done as a load of -1 followed by a mask
9748 ; instruction.
9749 (define_split
9750 [(set (match_operand:DI 0 "int_reg_operand")
9751 (match_operand:DI 1 "const_int_operand"))]
9752 "TARGET_POWERPC64
9753 && num_insns_constant (operands[1], DImode) > 1
9754 && !IN_RANGE (INTVAL (operands[1]), -0x80000000, 0xffffffff)
9755 && rs6000_is_valid_and_mask (operands[1], DImode)"
9756 [(set (match_dup 0)
9757 (const_int -1))
9758 (set (match_dup 0)
9759 (and:DI (match_dup 0)
9760 (match_dup 1)))]
9761 "")
9762
9763 ;; Split a load of a large constant into the appropriate five-instruction
9764 ;; sequence. Handle anything in a constant number of insns.
9765 ;; When non-easy constants can go in the TOC, this should use
9766 ;; easy_fp_constant predicate.
9767 (define_split
9768 [(set (match_operand:DI 0 "int_reg_operand")
9769 (match_operand:DI 1 "const_int_operand"))]
9770 "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
9771 [(pc)]
9772 {
9773 if (rs6000_emit_set_const (operands[0], operands[1]))
9774 DONE;
9775 else
9776 FAIL;
9777 })
9778
9779 (define_split
9780 [(set (match_operand:DI 0 "altivec_register_operand")
9781 (match_operand:DI 1 "s5bit_cint_operand"))]
9782 "TARGET_VSX && reload_completed"
9783 [(const_int 0)]
9784 {
9785 rtx op0 = operands[0];
9786 rtx op1 = operands[1];
9787 int r = REGNO (op0);
9788 rtx op0_v4si = gen_rtx_REG (V4SImode, r);
9789
9790 emit_insn (gen_altivec_vspltisw (op0_v4si, op1));
9791 if (op1 != const0_rtx && op1 != constm1_rtx)
9792 {
9793 rtx op0_v2di = gen_rtx_REG (V2DImode, r);
9794 emit_insn (gen_altivec_vupkhsw (op0_v2di, op0_v4si));
9795 }
9796 DONE;
9797 })
9798
9799 ;; Split integer constants that can be loaded with XXSPLTIB and a
9800 ;; sign extend operation.
9801 (define_split
9802 [(set (match_operand:INT_ISA3 0 "altivec_register_operand")
9803 (match_operand:INT_ISA3 1 "xxspltib_constant_split"))]
9804 "TARGET_P9_VECTOR && reload_completed"
9805 [(const_int 0)]
9806 {
9807 rtx op0 = operands[0];
9808 rtx op1 = operands[1];
9809 int r = REGNO (op0);
9810 rtx op0_v16qi = gen_rtx_REG (V16QImode, r);
9811
9812 emit_insn (gen_xxspltib_v16qi (op0_v16qi, op1));
9813 if (<MODE>mode == DImode)
9814 emit_insn (gen_vsx_sign_extend_qi_di (operands[0], op0_v16qi));
9815 else if (<MODE>mode == SImode)
9816 emit_insn (gen_vsx_sign_extend_qi_si (operands[0], op0_v16qi));
9817 else if (<MODE>mode == HImode)
9818 {
9819 rtx op0_v8hi = gen_rtx_REG (V8HImode, r);
9820 emit_insn (gen_altivec_vupkhsb (op0_v8hi, op0_v16qi));
9821 }
9822 DONE;
9823 })
9824
9825 \f
9826 ;; TImode/PTImode is similar, except that we usually want to compute the
9827 ;; address into a register and use lsi/stsi (the exception is during reload).
9828
9829 (define_insn "*mov<mode>_string"
9830 [(set (match_operand:TI2 0 "reg_or_mem_operand" "=Q,Y,????r,????r,????r,r")
9831 (match_operand:TI2 1 "input_operand" "r,r,Q,Y,r,n"))]
9832 "! TARGET_POWERPC64
9833 && (<MODE>mode != TImode || VECTOR_MEM_NONE_P (TImode))
9834 && (gpc_reg_operand (operands[0], <MODE>mode)
9835 || gpc_reg_operand (operands[1], <MODE>mode))"
9836 "#"
9837 [(set_attr "type" "store,store,load,load,*,*")
9838 (set_attr "update" "yes")
9839 (set_attr "indexed" "yes")
9840 (set_attr "cell_micro" "conditional")])
9841
9842 (define_insn "*mov<mode>_ppc64"
9843 [(set (match_operand:TI2 0 "nonimmediate_operand" "=wQ,Y,r,r,r,r")
9844 (match_operand:TI2 1 "input_operand" "r,r,wQ,Y,r,n"))]
9845 "(TARGET_POWERPC64 && VECTOR_MEM_NONE_P (<MODE>mode)
9846 && (gpc_reg_operand (operands[0], <MODE>mode)
9847 || gpc_reg_operand (operands[1], <MODE>mode)))"
9848 {
9849 return rs6000_output_move_128bit (operands);
9850 }
9851 [(set_attr "type" "store,store,load,load,*,*")
9852 (set_attr "length" "8")
9853 (set_attr "max_prefixed_insns" "2")])
9854
9855 (define_split
9856 [(set (match_operand:TI2 0 "int_reg_operand")
9857 (match_operand:TI2 1 "const_scalar_int_operand"))]
9858 "TARGET_POWERPC64
9859 && (VECTOR_MEM_NONE_P (<MODE>mode)
9860 || (reload_completed && INT_REGNO_P (REGNO (operands[0]))))"
9861 [(set (match_dup 2) (match_dup 4))
9862 (set (match_dup 3) (match_dup 5))]
9863 {
9864 operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
9865 <MODE>mode);
9866 operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
9867 <MODE>mode);
9868 if (CONST_WIDE_INT_P (operands[1]))
9869 {
9870 operands[4] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 1));
9871 operands[5] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 0));
9872 }
9873 else if (CONST_INT_P (operands[1]))
9874 {
9875 operands[4] = GEN_INT (- (INTVAL (operands[1]) < 0));
9876 operands[5] = operands[1];
9877 }
9878 else
9879 FAIL;
9880 })
9881
9882 (define_split
9883 [(set (match_operand:TI2 0 "nonimmediate_operand")
9884 (match_operand:TI2 1 "input_operand"))]
9885 "reload_completed
9886 && gpr_or_gpr_p (operands[0], operands[1])
9887 && !direct_move_p (operands[0], operands[1])
9888 && !quad_load_store_p (operands[0], operands[1])"
9889 [(pc)]
9890 {
9891 rs6000_split_multireg_move (operands[0], operands[1]);
9892 DONE;
9893 })
9894 \f
9895 (define_expand "setmemsi"
9896 [(parallel [(set (match_operand:BLK 0 "")
9897 (match_operand 2 "const_int_operand"))
9898 (use (match_operand:SI 1 ""))
9899 (use (match_operand:SI 3 ""))])]
9900 ""
9901 {
9902 /* If value to set is not zero, use the library routine. */
9903 if (operands[2] != const0_rtx)
9904 FAIL;
9905
9906 if (expand_block_clear (operands))
9907 DONE;
9908 else
9909 FAIL;
9910 })
9911
9912 ;; String compare N insn.
9913 ;; Argument 0 is the target (result)
9914 ;; Argument 1 is the destination
9915 ;; Argument 2 is the source
9916 ;; Argument 3 is the length
9917 ;; Argument 4 is the alignment
9918
9919 (define_expand "cmpstrnsi"
9920 [(parallel [(set (match_operand:SI 0)
9921 (compare:SI (match_operand:BLK 1)
9922 (match_operand:BLK 2)))
9923 (use (match_operand:SI 3))
9924 (use (match_operand:SI 4))])]
9925 "TARGET_CMPB && (BYTES_BIG_ENDIAN || TARGET_LDBRX)"
9926 {
9927 if (optimize_insn_for_size_p ())
9928 FAIL;
9929
9930 if (expand_strn_compare (operands, 0))
9931 DONE;
9932 else
9933 FAIL;
9934 })
9935
9936 ;; String compare insn.
9937 ;; Argument 0 is the target (result)
9938 ;; Argument 1 is the destination
9939 ;; Argument 2 is the source
9940 ;; Argument 3 is the alignment
9941
9942 (define_expand "cmpstrsi"
9943 [(parallel [(set (match_operand:SI 0)
9944 (compare:SI (match_operand:BLK 1)
9945 (match_operand:BLK 2)))
9946 (use (match_operand:SI 3))])]
9947 "TARGET_CMPB && (BYTES_BIG_ENDIAN || TARGET_LDBRX)"
9948 {
9949 if (optimize_insn_for_size_p ())
9950 FAIL;
9951
9952 if (expand_strn_compare (operands, 1))
9953 DONE;
9954 else
9955 FAIL;
9956 })
9957
9958 ;; Block compare insn.
9959 ;; Argument 0 is the target (result)
9960 ;; Argument 1 is the destination
9961 ;; Argument 2 is the source
9962 ;; Argument 3 is the length
9963 ;; Argument 4 is the alignment
9964
9965 (define_expand "cmpmemsi"
9966 [(parallel [(set (match_operand:SI 0)
9967 (compare:SI (match_operand:BLK 1)
9968 (match_operand:BLK 2)))
9969 (use (match_operand:SI 3))
9970 (use (match_operand:SI 4))])]
9971 "TARGET_POPCNTD"
9972 {
9973 if (expand_block_compare (operands))
9974 DONE;
9975 else
9976 FAIL;
9977 })
9978
9979 ;; String/block copy insn (source and destination must not overlap).
9980 ;; Argument 0 is the destination
9981 ;; Argument 1 is the source
9982 ;; Argument 2 is the length
9983 ;; Argument 3 is the alignment
9984
9985 (define_expand "cpymemsi"
9986 [(parallel [(set (match_operand:BLK 0 "")
9987 (match_operand:BLK 1 ""))
9988 (use (match_operand:SI 2 ""))
9989 (use (match_operand:SI 3 ""))])]
9990 ""
9991 {
9992 if (expand_block_move (operands, false))
9993 DONE;
9994 else
9995 FAIL;
9996 })
9997
9998 ;; String/block move insn (source and destination may overlap).
9999 ;; Argument 0 is the destination
10000 ;; Argument 1 is the source
10001 ;; Argument 2 is the length
10002 ;; Argument 3 is the alignment
10003
10004 (define_expand "movmemsi"
10005 [(parallel [(set (match_operand:BLK 0 "")
10006 (match_operand:BLK 1 ""))
10007 (use (match_operand:SI 2 ""))
10008 (use (match_operand:SI 3 ""))])]
10009 ""
10010 {
10011 if (expand_block_move (operands, true))
10012 DONE;
10013 else
10014 FAIL;
10015 })
10016
10017 \f
10018 ;; Define insns that do load or store with update. Some of these we can
10019 ;; get by using pre-decrement or pre-increment, but the hardware can also
10020 ;; do cases where the increment is not the size of the object.
10021 ;;
10022 ;; In all these cases, we use operands 0 and 1 for the register being
10023 ;; incremented because those are the operands that local-alloc will
10024 ;; tie and these are the pair most likely to be tieable (and the ones
10025 ;; that will benefit the most).
10026
10027 (define_insn "*movdi_update1"
10028 [(set (match_operand:DI 3 "gpc_reg_operand" "=r,r")
10029 (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
10030 (match_operand:P 2 "reg_or_aligned_short_operand" "r,I"))))
10031 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
10032 (plus:P (match_dup 1) (match_dup 2)))]
10033 "TARGET_POWERPC64 && TARGET_UPDATE
10034 && (!avoiding_indexed_address_p (DImode)
10035 || !gpc_reg_operand (operands[2], Pmode))"
10036 "@
10037 ldux %3,%0,%2
10038 ldu %3,%2(%0)"
10039 [(set_attr "type" "load")
10040 (set_attr "update" "yes")
10041 (set_attr "indexed" "yes,no")])
10042
10043 (define_insn "movdi_<mode>_update"
10044 [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
10045 (match_operand:P 2 "reg_or_aligned_short_operand" "r,I")))
10046 (match_operand:DI 3 "gpc_reg_operand" "r,r"))
10047 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
10048 (plus:P (match_dup 1) (match_dup 2)))]
10049 "TARGET_POWERPC64 && TARGET_UPDATE
10050 && (!avoiding_indexed_address_p (DImode)
10051 || !gpc_reg_operand (operands[2], Pmode)
10052 || (REG_P (operands[0])
10053 && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
10054 "@
10055 stdux %3,%0,%2
10056 stdu %3,%2(%0)"
10057 [(set_attr "type" "store")
10058 (set_attr "update" "yes")
10059 (set_attr "indexed" "yes,no")])
10060
10061 ;; This pattern is only conditional on TARGET_64BIT, as it is
10062 ;; needed for stack allocation, even if the user passes -mno-update.
10063 (define_insn "movdi_update_stack"
10064 [(set (mem:DI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0,0")
10065 (match_operand:DI 2 "reg_or_aligned_short_operand" "r,I")))
10066 (match_operand:DI 3 "gpc_reg_operand" "r,r"))
10067 (set (match_operand:DI 0 "gpc_reg_operand" "=b,b")
10068 (plus:DI (match_dup 1) (match_dup 2)))]
10069 "TARGET_64BIT"
10070 "@
10071 stdux %3,%0,%2
10072 stdu %3,%2(%0)"
10073 [(set_attr "type" "store")
10074 (set_attr "update" "yes")
10075 (set_attr "indexed" "yes,no")])
10076
10077 (define_insn "*movsi_update1"
10078 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
10079 (mem:SI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
10080 (match_operand:P 2 "reg_or_short_operand" "r,I"))))
10081 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
10082 (plus:P (match_dup 1) (match_dup 2)))]
10083 "TARGET_UPDATE
10084 && (!avoiding_indexed_address_p (SImode)
10085 || !gpc_reg_operand (operands[2], Pmode))"
10086 "@
10087 lwzux %3,%0,%2
10088 lwzu %3,%2(%0)"
10089 [(set_attr "type" "load")
10090 (set_attr "update" "yes")
10091 (set_attr "indexed" "yes,no")])
10092
10093 (define_insn "*movsi_update2"
10094 [(set (match_operand:EXTSI 3 "gpc_reg_operand" "=r")
10095 (sign_extend:EXTSI
10096 (mem:SI (plus:P (match_operand:P 1 "gpc_reg_operand" "0")
10097 (match_operand:P 2 "gpc_reg_operand" "r")))))
10098 (set (match_operand:P 0 "gpc_reg_operand" "=b")
10099 (plus:P (match_dup 1) (match_dup 2)))]
10100 "TARGET_POWERPC64 && !avoiding_indexed_address_p (DImode)"
10101 "lwaux %3,%0,%2"
10102 [(set_attr "type" "load")
10103 (set_attr "sign_extend" "yes")
10104 (set_attr "update" "yes")
10105 (set_attr "indexed" "yes")])
10106
10107 (define_insn "movsi_<mode>_update"
10108 [(set (mem:SI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
10109 (match_operand:P 2 "reg_or_short_operand" "r,I")))
10110 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
10111 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
10112 (plus:P (match_dup 1) (match_dup 2)))]
10113 "TARGET_UPDATE
10114 && (!avoiding_indexed_address_p (SImode)
10115 || !gpc_reg_operand (operands[2], Pmode)
10116 || (REG_P (operands[0])
10117 && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
10118 "@
10119 stwux %3,%0,%2
10120 stwu %3,%2(%0)"
10121 [(set_attr "type" "store")
10122 (set_attr "update" "yes")
10123 (set_attr "indexed" "yes,no")])
10124
10125 ;; This is an unconditional pattern; needed for stack allocation, even
10126 ;; if the user passes -mno-update.
10127 (define_insn "movsi_update_stack"
10128 [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
10129 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
10130 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
10131 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
10132 (plus:SI (match_dup 1) (match_dup 2)))]
10133 "TARGET_32BIT"
10134 "@
10135 stwux %3,%0,%2
10136 stwu %3,%2(%0)"
10137 [(set_attr "type" "store")
10138 (set_attr "update" "yes")
10139 (set_attr "indexed" "yes,no")])
10140
10141 (define_insn "*movhi_update1"
10142 [(set (match_operand:HI 3 "gpc_reg_operand" "=r,r")
10143 (mem:HI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
10144 (match_operand:P 2 "reg_or_short_operand" "r,I"))))
10145 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
10146 (plus:P (match_dup 1) (match_dup 2)))]
10147 "TARGET_UPDATE
10148 && (!avoiding_indexed_address_p (HImode)
10149 || !gpc_reg_operand (operands[2], SImode))"
10150 "@
10151 lhzux %3,%0,%2
10152 lhzu %3,%2(%0)"
10153 [(set_attr "type" "load")
10154 (set_attr "update" "yes")
10155 (set_attr "indexed" "yes,no")])
10156
10157 (define_insn "*movhi_update2"
10158 [(set (match_operand:EXTHI 3 "gpc_reg_operand" "=r,r")
10159 (zero_extend:EXTHI
10160 (mem:HI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
10161 (match_operand:P 2 "reg_or_short_operand" "r,I")))))
10162 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
10163 (plus:P (match_dup 1) (match_dup 2)))]
10164 "TARGET_UPDATE
10165 && (!avoiding_indexed_address_p (HImode)
10166 || !gpc_reg_operand (operands[2], Pmode))"
10167 "@
10168 lhzux %3,%0,%2
10169 lhzu %3,%2(%0)"
10170 [(set_attr "type" "load")
10171 (set_attr "update" "yes")
10172 (set_attr "indexed" "yes,no")])
10173
10174 (define_insn "*movhi_update3"
10175 [(set (match_operand:EXTHI 3 "gpc_reg_operand" "=r,r")
10176 (sign_extend:EXTHI
10177 (mem:HI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
10178 (match_operand:P 2 "reg_or_short_operand" "r,I")))))
10179 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
10180 (plus:P (match_dup 1) (match_dup 2)))]
10181 "TARGET_UPDATE
10182 && !(avoiding_indexed_address_p (HImode)
10183 && gpc_reg_operand (operands[2], Pmode))"
10184 "@
10185 lhaux %3,%0,%2
10186 lhau %3,%2(%0)"
10187 [(set_attr "type" "load")
10188 (set_attr "sign_extend" "yes")
10189 (set_attr "update" "yes")
10190 (set_attr "indexed" "yes,no")])
10191
10192 (define_insn "*movhi_update4"
10193 [(set (mem:HI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
10194 (match_operand:P 2 "reg_or_short_operand" "r,I")))
10195 (match_operand:HI 3 "gpc_reg_operand" "r,r"))
10196 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
10197 (plus:P (match_dup 1) (match_dup 2)))]
10198 "TARGET_UPDATE
10199 && (!avoiding_indexed_address_p (HImode)
10200 || !gpc_reg_operand (operands[2], Pmode))"
10201 "@
10202 sthux %3,%0,%2
10203 sthu %3,%2(%0)"
10204 [(set_attr "type" "store")
10205 (set_attr "update" "yes")
10206 (set_attr "indexed" "yes,no")])
10207
10208 (define_insn "*movqi_update1"
10209 [(set (match_operand:QI 3 "gpc_reg_operand" "=r,r")
10210 (mem:QI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
10211 (match_operand:P 2 "reg_or_short_operand" "r,I"))))
10212 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
10213 (plus:P (match_dup 1) (match_dup 2)))]
10214 "TARGET_UPDATE
10215 && (!avoiding_indexed_address_p (QImode)
10216 || !gpc_reg_operand (operands[2], Pmode))"
10217 "@
10218 lbzux %3,%0,%2
10219 lbzu %3,%2(%0)"
10220 [(set_attr "type" "load")
10221 (set_attr "update" "yes")
10222 (set_attr "indexed" "yes,no")])
10223
10224 (define_insn "*movqi_update2"
10225 [(set (match_operand:EXTQI 3 "gpc_reg_operand" "=r,r")
10226 (zero_extend:EXTQI
10227 (mem:QI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
10228 (match_operand:P 2 "reg_or_short_operand" "r,I")))))
10229 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
10230 (plus:P (match_dup 1) (match_dup 2)))]
10231 "TARGET_UPDATE
10232 && (!avoiding_indexed_address_p (QImode)
10233 || !gpc_reg_operand (operands[2], Pmode))"
10234 "@
10235 lbzux %3,%0,%2
10236 lbzu %3,%2(%0)"
10237 [(set_attr "type" "load")
10238 (set_attr "update" "yes")
10239 (set_attr "indexed" "yes,no")])
10240
10241 (define_insn "*movqi_update3"
10242 [(set (mem:QI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
10243 (match_operand:P 2 "reg_or_short_operand" "r,I")))
10244 (match_operand:QI 3 "gpc_reg_operand" "r,r"))
10245 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
10246 (plus:P (match_dup 1) (match_dup 2)))]
10247 "TARGET_UPDATE
10248 && (!avoiding_indexed_address_p (QImode)
10249 || !gpc_reg_operand (operands[2], Pmode))"
10250 "@
10251 stbux %3,%0,%2
10252 stbu %3,%2(%0)"
10253 [(set_attr "type" "store")
10254 (set_attr "update" "yes")
10255 (set_attr "indexed" "yes,no")])
10256
10257 (define_insn "*mov<SFDF:mode>_update1"
10258 [(set (match_operand:SFDF 3 "gpc_reg_operand" "=d,d")
10259 (mem:SFDF (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
10260 (match_operand:P 2 "reg_or_short_operand" "r,I"))))
10261 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
10262 (plus:P (match_dup 1) (match_dup 2)))]
10263 "TARGET_HARD_FLOAT && TARGET_UPDATE
10264 && (!avoiding_indexed_address_p (<SFDF:MODE>mode)
10265 || !gpc_reg_operand (operands[2], Pmode))"
10266 "@
10267 lf<sd>ux %3,%0,%2
10268 lf<sd>u %3,%2(%0)"
10269 [(set_attr "type" "fpload")
10270 (set_attr "update" "yes")
10271 (set_attr "indexed" "yes,no")
10272 (set_attr "size" "<SFDF:bits>")])
10273
10274 (define_insn "*mov<SFDF:mode>_update2"
10275 [(set (mem:SFDF (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
10276 (match_operand:P 2 "reg_or_short_operand" "r,I")))
10277 (match_operand:SFDF 3 "gpc_reg_operand" "d,d"))
10278 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
10279 (plus:P (match_dup 1) (match_dup 2)))]
10280 "TARGET_HARD_FLOAT && TARGET_UPDATE
10281 && (!avoiding_indexed_address_p (<SFDF:MODE>mode)
10282 || !gpc_reg_operand (operands[2], Pmode))"
10283 "@
10284 stf<sd>ux %3,%0,%2
10285 stf<sd>u %3,%2(%0)"
10286 [(set_attr "type" "fpstore")
10287 (set_attr "update" "yes")
10288 (set_attr "indexed" "yes,no")
10289 (set_attr "size" "<SFDF:bits>")])
10290
10291 (define_insn "*movsf_update3"
10292 [(set (match_operand:SF 3 "gpc_reg_operand" "=r,r")
10293 (mem:SF (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
10294 (match_operand:P 2 "reg_or_short_operand" "r,I"))))
10295 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
10296 (plus:P (match_dup 1) (match_dup 2)))]
10297 "TARGET_SOFT_FLOAT && TARGET_UPDATE
10298 && (!avoiding_indexed_address_p (SFmode)
10299 || !gpc_reg_operand (operands[2], Pmode))"
10300 "@
10301 lwzux %3,%0,%2
10302 lwzu %3,%2(%0)"
10303 [(set_attr "type" "load")
10304 (set_attr "update" "yes")
10305 (set_attr "indexed" "yes,no")])
10306
10307 (define_insn "*movsf_update4"
10308 [(set (mem:SF (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
10309 (match_operand:P 2 "reg_or_short_operand" "r,I")))
10310 (match_operand:SF 3 "gpc_reg_operand" "r,r"))
10311 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
10312 (plus:P (match_dup 1) (match_dup 2)))]
10313 "TARGET_SOFT_FLOAT && TARGET_UPDATE
10314 && (!avoiding_indexed_address_p (SFmode)
10315 || !gpc_reg_operand (operands[2], Pmode))"
10316 "@
10317 stwux %3,%0,%2
10318 stwu %3,%2(%0)"
10319 [(set_attr "type" "store")
10320 (set_attr "update" "yes")
10321 (set_attr "indexed" "yes,no")])
10322
10323
10324 ;; After inserting conditional returns we can sometimes have
10325 ;; unnecessary register moves. Unfortunately we cannot have a
10326 ;; modeless peephole here, because some single SImode sets have early
10327 ;; clobber outputs. Although those sets expand to multi-ppc-insn
10328 ;; sequences, using get_attr_length here will smash the operands
10329 ;; array. Neither is there an early_cobbler_p predicate.
10330 ;; Also this optimization interferes with scalars going into
10331 ;; altivec registers (the code does reloading through the FPRs).
10332 (define_peephole2
10333 [(set (match_operand:DF 0 "gpc_reg_operand")
10334 (match_operand:DF 1 "any_operand"))
10335 (set (match_operand:DF 2 "gpc_reg_operand")
10336 (match_dup 0))]
10337 "!TARGET_VSX
10338 && peep2_reg_dead_p (2, operands[0])"
10339 [(set (match_dup 2) (match_dup 1))])
10340
10341 (define_peephole2
10342 [(set (match_operand:SF 0 "gpc_reg_operand")
10343 (match_operand:SF 1 "any_operand"))
10344 (set (match_operand:SF 2 "gpc_reg_operand")
10345 (match_dup 0))]
10346 "!TARGET_P8_VECTOR
10347 && peep2_reg_dead_p (2, operands[0])"
10348 [(set (match_dup 2) (match_dup 1))])
10349
10350 \f
10351 ;; TLS support.
10352
10353 (define_insn "*tls_gd_pcrel<bits>"
10354 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
10355 (unspec:P [(match_operand:P 1 "rs6000_tls_symbol_ref" "")
10356 (const_int 0)]
10357 UNSPEC_TLSGD))]
10358 "HAVE_AS_TLS && TARGET_ELF"
10359 "la %0,%1@got@tlsgd@pcrel"
10360 [(set_attr "prefixed" "yes")])
10361
10362 (define_insn_and_split "*tls_gd<bits>"
10363 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
10364 (unspec:P [(match_operand:P 1 "rs6000_tls_symbol_ref" "")
10365 (match_operand:P 2 "gpc_reg_operand" "b")]
10366 UNSPEC_TLSGD))]
10367 "HAVE_AS_TLS && TARGET_ELF"
10368 "addi %0,%2,%1@got@tlsgd"
10369 "&& TARGET_CMODEL != CMODEL_SMALL"
10370 [(set (match_dup 3)
10371 (high:P
10372 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))
10373 (set (match_dup 0)
10374 (lo_sum:P (match_dup 3)
10375 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))]
10376 {
10377 operands[3] = gen_reg_rtx (<MODE>mode);
10378 }
10379 [(set (attr "length")
10380 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
10381 (const_int 8)
10382 (const_int 4)))])
10383
10384 (define_insn "*tls_gd_high<bits>"
10385 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
10386 (high:P
10387 (unspec:P [(match_operand:P 1 "rs6000_tls_symbol_ref" "")
10388 (match_operand:P 2 "gpc_reg_operand" "b")]
10389 UNSPEC_TLSGD)))]
10390 "HAVE_AS_TLS && TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10391 "addis %0,%2,%1@got@tlsgd@ha")
10392
10393 (define_insn "*tls_gd_low<bits>"
10394 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
10395 (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
10396 (unspec:P [(match_operand:P 2 "rs6000_tls_symbol_ref" "")
10397 (match_operand:P 3 "gpc_reg_operand" "b")]
10398 UNSPEC_TLSGD)))]
10399 "HAVE_AS_TLS && TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10400 "addi %0,%1,%2@got@tlsgd@l")
10401
10402 (define_insn "*tls_ld_pcrel<bits>"
10403 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
10404 (unspec:P [(const_int 0)]
10405 UNSPEC_TLSLD))]
10406 "HAVE_AS_TLS && TARGET_ELF"
10407 "la %0,%&@got@tlsld@pcrel"
10408 [(set_attr "prefixed" "yes")])
10409
10410 (define_insn_and_split "*tls_ld<bits>"
10411 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
10412 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")]
10413 UNSPEC_TLSLD))]
10414 "HAVE_AS_TLS && TARGET_ELF"
10415 "addi %0,%1,%&@got@tlsld"
10416 "&& TARGET_CMODEL != CMODEL_SMALL"
10417 [(set (match_dup 2)
10418 (high:P
10419 (unspec:P [(match_dup 1)] UNSPEC_TLSLD)))
10420 (set (match_dup 0)
10421 (lo_sum:P (match_dup 2)
10422 (unspec:P [(match_dup 1)] UNSPEC_TLSLD)))]
10423 {
10424 operands[2] = gen_reg_rtx (<MODE>mode);
10425 }
10426 [(set (attr "length")
10427 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
10428 (const_int 8)
10429 (const_int 4)))])
10430
10431 (define_insn "*tls_ld_high<bits>"
10432 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
10433 (high:P
10434 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")]
10435 UNSPEC_TLSLD)))]
10436 "HAVE_AS_TLS && TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10437 "addis %0,%1,%&@got@tlsld@ha")
10438
10439 (define_insn "*tls_ld_low<bits>"
10440 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
10441 (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
10442 (unspec:P [(match_operand:P 2 "gpc_reg_operand" "b")]
10443 UNSPEC_TLSLD)))]
10444 "HAVE_AS_TLS && TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10445 "addi %0,%1,%&@got@tlsld@l")
10446
10447 (define_insn "tls_dtprel_<bits>"
10448 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10449 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
10450 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
10451 UNSPEC_TLSDTPREL))]
10452 "HAVE_AS_TLS"
10453 "addi %0,%1,%2@dtprel"
10454 [(set (attr "prefixed")
10455 (if_then_else (match_test "rs6000_tls_size == 16")
10456 (const_string "no")
10457 (const_string "yes")))])
10458
10459 (define_insn "tls_dtprel_ha_<bits>"
10460 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10461 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
10462 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
10463 UNSPEC_TLSDTPRELHA))]
10464 "HAVE_AS_TLS"
10465 "addis %0,%1,%2@dtprel@ha")
10466
10467 (define_insn "tls_dtprel_lo_<bits>"
10468 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10469 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
10470 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
10471 UNSPEC_TLSDTPRELLO))]
10472 "HAVE_AS_TLS"
10473 "addi %0,%1,%2@dtprel@l")
10474
10475 (define_insn_and_split "tls_got_dtprel_<bits>"
10476 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10477 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
10478 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
10479 UNSPEC_TLSGOTDTPREL))]
10480 "HAVE_AS_TLS"
10481 "<ptrload> %0,%2@got@dtprel(%1)"
10482 "&& TARGET_CMODEL != CMODEL_SMALL"
10483 [(set (match_dup 3)
10484 (high:P
10485 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))
10486 (set (match_dup 0)
10487 (lo_sum:P (match_dup 3)
10488 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))]
10489 {
10490 operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
10491 }
10492 [(set (attr "length")
10493 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
10494 (const_int 8)
10495 (const_int 4)))])
10496
10497 (define_insn "*tls_got_dtprel_high<bits>"
10498 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
10499 (high:P
10500 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
10501 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
10502 UNSPEC_TLSGOTDTPREL)))]
10503 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
10504 "addis %0,%1,%2@got@dtprel@ha")
10505
10506 (define_insn "*tls_got_dtprel_low<bits>"
10507 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10508 (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
10509 (unspec:P [(match_operand:P 3 "gpc_reg_operand" "b")
10510 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
10511 UNSPEC_TLSGOTDTPREL)))]
10512 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
10513 "<ptrload> %0,%2@got@dtprel@l(%1)")
10514
10515 (define_insn "tls_tprel_<bits>"
10516 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10517 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
10518 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
10519 UNSPEC_TLSTPREL))]
10520 "HAVE_AS_TLS"
10521 "addi %0,%1,%2@tprel"
10522 [(set (attr "prefixed")
10523 (if_then_else (match_test "rs6000_tls_size == 16")
10524 (const_string "no")
10525 (const_string "yes")))])
10526
10527 (define_insn "tls_tprel_ha_<bits>"
10528 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10529 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
10530 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
10531 UNSPEC_TLSTPRELHA))]
10532 "HAVE_AS_TLS"
10533 "addis %0,%1,%2@tprel@ha")
10534
10535 (define_insn "tls_tprel_lo_<bits>"
10536 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10537 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
10538 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
10539 UNSPEC_TLSTPRELLO))]
10540 "HAVE_AS_TLS"
10541 "addi %0,%1,%2@tprel@l")
10542
10543 (define_insn "*tls_got_tprel_pcrel_<bits>"
10544 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
10545 (unspec:P [(const_int 0)
10546 (match_operand:P 1 "rs6000_tls_symbol_ref" "")]
10547 UNSPEC_TLSGOTTPREL))]
10548 "HAVE_AS_TLS"
10549 "<ptrload> %0,%1@got@tprel@pcrel"
10550 [(set_attr "prefixed" "yes")])
10551
10552 ;; "b" output constraint here and on tls_tls input to support linker tls
10553 ;; optimization. The linker may edit the instructions emitted by a
10554 ;; tls_got_tprel/tls_tls pair to addis,addi.
10555 (define_insn_and_split "tls_got_tprel_<bits>"
10556 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
10557 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
10558 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
10559 UNSPEC_TLSGOTTPREL))]
10560 "HAVE_AS_TLS"
10561 "<ptrload> %0,%2@got@tprel(%1)"
10562 "&& TARGET_CMODEL != CMODEL_SMALL"
10563 [(set (match_dup 3)
10564 (high:P
10565 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))
10566 (set (match_dup 0)
10567 (lo_sum:P (match_dup 3)
10568 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))]
10569 {
10570 operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
10571 }
10572 [(set (attr "length")
10573 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
10574 (const_int 8)
10575 (const_int 4)))])
10576
10577 (define_insn "*tls_got_tprel_high<bits>"
10578 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
10579 (high:P
10580 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
10581 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
10582 UNSPEC_TLSGOTTPREL)))]
10583 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
10584 "addis %0,%1,%2@got@tprel@ha")
10585
10586 (define_insn "*tls_got_tprel_low<bits>"
10587 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10588 (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
10589 (unspec:P [(match_operand:P 3 "gpc_reg_operand" "b")
10590 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
10591 UNSPEC_TLSGOTTPREL)))]
10592 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
10593 "<ptrload> %0,%2@got@tprel@l(%1)")
10594
10595 (define_insn "tls_tls_pcrel_<bits>"
10596 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10597 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
10598 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
10599 UNSPEC_TLSTLS_PCREL))]
10600 "TARGET_ELF && HAVE_AS_TLS"
10601 "add %0,%1,%2@tls@pcrel")
10602
10603 (define_insn "tls_tls_<bits>"
10604 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10605 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
10606 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
10607 UNSPEC_TLSTLS))]
10608 "TARGET_ELF && HAVE_AS_TLS"
10609 "add %0,%1,%2@tls")
10610
10611 (define_expand "tls_get_tpointer"
10612 [(set (match_operand:SI 0 "gpc_reg_operand")
10613 (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))]
10614 "TARGET_XCOFF && HAVE_AS_TLS"
10615 {
10616 emit_insn (gen_tls_get_tpointer_internal ());
10617 emit_move_insn (operands[0], gen_rtx_REG (SImode, 3));
10618 DONE;
10619 })
10620
10621 (define_insn "tls_get_tpointer_internal"
10622 [(set (reg:SI 3)
10623 (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))
10624 (clobber (reg:SI LR_REGNO))]
10625 "TARGET_XCOFF && HAVE_AS_TLS"
10626 "bla .__get_tpointer")
10627
10628 (define_expand "tls_get_addr<mode>"
10629 [(set (match_operand:P 0 "gpc_reg_operand")
10630 (unspec:P [(match_operand:P 1 "gpc_reg_operand")
10631 (match_operand:P 2 "gpc_reg_operand")] UNSPEC_TLSTLS))]
10632 "TARGET_XCOFF && HAVE_AS_TLS"
10633 {
10634 emit_move_insn (gen_rtx_REG (Pmode, 3), operands[1]);
10635 emit_move_insn (gen_rtx_REG (Pmode, 4), operands[2]);
10636 emit_insn (gen_tls_get_addr_internal<mode> ());
10637 emit_move_insn (operands[0], gen_rtx_REG (Pmode, 3));
10638 DONE;
10639 })
10640
10641 (define_insn "tls_get_addr_internal<mode>"
10642 [(set (reg:P 3)
10643 (unspec:P [(reg:P 3) (reg:P 4)] UNSPEC_TLSTLS))
10644 (clobber (reg:P 0))
10645 (clobber (reg:P 4))
10646 (clobber (reg:P 5))
10647 (clobber (reg:P 11))
10648 (clobber (reg:CC CR0_REGNO))
10649 (clobber (reg:P LR_REGNO))]
10650 "TARGET_XCOFF && HAVE_AS_TLS"
10651 "bla .__tls_get_addr")
10652 \f
10653 ;; Next come insns related to the calling sequence.
10654 ;;
10655 ;; First, an insn to allocate new stack space for dynamic use (e.g., alloca).
10656 ;; We move the back-chain and decrement the stack pointer.
10657 ;;
10658 ;; Operand1 is more naturally reg_or_short_operand. However, for a large
10659 ;; constant alloca, using that predicate will force the generic code to put
10660 ;; the constant size into a register before calling the expander.
10661 ;;
10662 ;; As a result the expander would not have the constant size information
10663 ;; in those cases and would have to generate less efficient code.
10664 ;;
10665 ;; Thus we allow reg_or_cint_operand instead so that the expander can see
10666 ;; the constant size. The value is forced into a register if necessary.
10667 ;;
10668 (define_expand "allocate_stack"
10669 [(set (match_operand 0 "gpc_reg_operand")
10670 (minus (reg 1) (match_operand 1 "reg_or_cint_operand")))
10671 (set (reg 1)
10672 (minus (reg 1) (match_dup 1)))]
10673 ""
10674 {
10675 rtx chain = gen_reg_rtx (Pmode);
10676 rtx stack_bot = gen_rtx_MEM (Pmode, stack_pointer_rtx);
10677 rtx neg_op0;
10678 rtx insn, par, set, mem;
10679
10680 /* By allowing reg_or_cint_operand as the predicate we can get
10681 better code for stack-clash-protection because we do not lose
10682 size information. But the rest of the code expects the operand
10683 to be reg_or_short_operand. If it isn't, then force it into
10684 a register. */
10685 rtx orig_op1 = operands[1];
10686 if (!reg_or_short_operand (operands[1], Pmode))
10687 operands[1] = force_reg (Pmode, operands[1]);
10688
10689 emit_move_insn (chain, stack_bot);
10690
10691 /* Check stack bounds if necessary. */
10692 if (crtl->limit_stack)
10693 {
10694 rtx available;
10695 available = expand_binop (Pmode, sub_optab,
10696 stack_pointer_rtx, stack_limit_rtx,
10697 NULL_RTX, 1, OPTAB_WIDEN);
10698 emit_insn (gen_cond_trap (LTU, available, operands[1], const0_rtx));
10699 }
10700
10701 /* Allocate and probe if requested.
10702 This may look similar to the loop we use for prologue allocations,
10703 but it is critically different. For the former we know the loop
10704 will iterate, but do not know that generally here. The former
10705 uses that knowledge to rotate the loop. Combining them would be
10706 possible with some performance cost. */
10707 if (flag_stack_clash_protection)
10708 {
10709 rtx rounded_size, last_addr, residual;
10710 HOST_WIDE_INT probe_interval;
10711 compute_stack_clash_protection_loop_data (&rounded_size, &last_addr,
10712 &residual, &probe_interval,
10713 orig_op1);
10714
10715 /* We do occasionally get in here with constant sizes, we might
10716 as well do a reasonable job when we obviously can. */
10717 if (rounded_size != const0_rtx)
10718 {
10719 rtx loop_lab, end_loop;
10720 bool rotated = CONST_INT_P (rounded_size);
10721 rtx update = GEN_INT (-probe_interval);
10722 if (probe_interval > 32768)
10723 update = force_reg (Pmode, update);
10724
10725 emit_stack_clash_protection_probe_loop_start (&loop_lab, &end_loop,
10726 last_addr, rotated);
10727
10728 if (TARGET_32BIT)
10729 emit_insn (gen_movsi_update_stack (stack_pointer_rtx,
10730 stack_pointer_rtx,
10731 update, chain));
10732 else
10733 emit_insn (gen_movdi_update_stack (stack_pointer_rtx,
10734 stack_pointer_rtx,
10735 update, chain));
10736 emit_stack_clash_protection_probe_loop_end (loop_lab, end_loop,
10737 last_addr, rotated);
10738 }
10739
10740 /* Now handle residuals. We just have to set operands[1] correctly
10741 and let the rest of the expander run. */
10742 operands[1] = residual;
10743 }
10744
10745 if (!(CONST_INT_P (operands[1])
10746 && IN_RANGE (INTVAL (operands[1]), -32767, 32768)))
10747 {
10748 operands[1] = force_reg (Pmode, operands[1]);
10749 neg_op0 = gen_reg_rtx (Pmode);
10750 emit_insn (gen_neg2 (Pmode, neg_op0, operands[1]));
10751 }
10752 else
10753 neg_op0 = GEN_INT (-INTVAL (operands[1]));
10754
10755 insn = emit_insn ((* ((TARGET_32BIT) ? gen_movsi_update_stack
10756 : gen_movdi_update_stack))
10757 (stack_pointer_rtx, stack_pointer_rtx, neg_op0,
10758 chain));
10759 /* Since we didn't use gen_frame_mem to generate the MEM, grab
10760 it now and set the alias set/attributes. The above gen_*_update
10761 calls will generate a PARALLEL with the MEM set being the first
10762 operation. */
10763 par = PATTERN (insn);
10764 gcc_assert (GET_CODE (par) == PARALLEL);
10765 set = XVECEXP (par, 0, 0);
10766 gcc_assert (GET_CODE (set) == SET);
10767 mem = SET_DEST (set);
10768 gcc_assert (MEM_P (mem));
10769 MEM_NOTRAP_P (mem) = 1;
10770 set_mem_alias_set (mem, get_frame_alias_set ());
10771
10772 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
10773 DONE;
10774 })
10775
10776 ;; These patterns say how to save and restore the stack pointer. We need not
10777 ;; save the stack pointer at function level since we are careful to
10778 ;; preserve the backchain. At block level, we have to restore the backchain
10779 ;; when we restore the stack pointer.
10780 ;;
10781 ;; For nonlocal gotos, we must save both the stack pointer and its
10782 ;; backchain and restore both. Note that in the nonlocal case, the
10783 ;; save area is a memory location.
10784
10785 (define_expand "save_stack_function"
10786 [(match_operand 0 "any_operand")
10787 (match_operand 1 "any_operand")]
10788 ""
10789 "DONE;")
10790
10791 (define_expand "restore_stack_function"
10792 [(match_operand 0 "any_operand")
10793 (match_operand 1 "any_operand")]
10794 ""
10795 "DONE;")
10796
10797 ;; Adjust stack pointer (op0) to a new value (op1).
10798 ;; First copy old stack backchain to new location, and ensure that the
10799 ;; scheduler won't reorder the sp assignment before the backchain write.
10800 (define_expand "restore_stack_block"
10801 [(set (match_dup 2) (match_dup 3))
10802 (set (match_dup 4) (match_dup 2))
10803 (match_dup 5)
10804 (set (match_operand 0 "register_operand")
10805 (match_operand 1 "register_operand"))]
10806 ""
10807 {
10808 rtvec p;
10809
10810 operands[1] = force_reg (Pmode, operands[1]);
10811 operands[2] = gen_reg_rtx (Pmode);
10812 operands[3] = gen_frame_mem (Pmode, operands[0]);
10813 operands[4] = gen_frame_mem (Pmode, operands[1]);
10814 p = rtvec_alloc (1);
10815 RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
10816 const0_rtx);
10817 operands[5] = gen_rtx_PARALLEL (VOIDmode, p);
10818 })
10819
10820 (define_expand "save_stack_nonlocal"
10821 [(set (match_dup 3) (match_dup 4))
10822 (set (match_operand 0 "memory_operand") (match_dup 3))
10823 (set (match_dup 2) (match_operand 1 "register_operand"))]
10824 ""
10825 {
10826 int units_per_word = (TARGET_32BIT) ? 4 : 8;
10827
10828 /* Copy the backchain to the first word, sp to the second. */
10829 operands[0] = adjust_address_nv (operands[0], Pmode, 0);
10830 operands[2] = adjust_address_nv (operands[0], Pmode, units_per_word);
10831 operands[3] = gen_reg_rtx (Pmode);
10832 operands[4] = gen_frame_mem (Pmode, operands[1]);
10833 })
10834
10835 (define_expand "restore_stack_nonlocal"
10836 [(set (match_dup 2) (match_operand 1 "memory_operand"))
10837 (set (match_dup 3) (match_dup 4))
10838 (set (match_dup 5) (match_dup 2))
10839 (match_dup 6)
10840 (set (match_operand 0 "register_operand") (match_dup 3))]
10841 ""
10842 {
10843 int units_per_word = (TARGET_32BIT) ? 4 : 8;
10844 rtvec p;
10845
10846 /* Restore the backchain from the first word, sp from the second. */
10847 operands[2] = gen_reg_rtx (Pmode);
10848 operands[3] = gen_reg_rtx (Pmode);
10849 operands[1] = adjust_address_nv (operands[1], Pmode, 0);
10850 operands[4] = adjust_address_nv (operands[1], Pmode, units_per_word);
10851 operands[5] = gen_frame_mem (Pmode, operands[3]);
10852 p = rtvec_alloc (1);
10853 RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
10854 const0_rtx);
10855 operands[6] = gen_rtx_PARALLEL (VOIDmode, p);
10856 })
10857 \f
10858 ;; Load up a PC-relative address. Print_operand_address will append a @pcrel
10859 ;; to the symbol or label.
10860 (define_insn "*pcrel_local_addr"
10861 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
10862 (match_operand:DI 1 "pcrel_local_address"))]
10863 "TARGET_PCREL"
10864 "la %0,%a1"
10865 [(set_attr "prefixed" "yes")])
10866
10867 ;; Load up a PC-relative address to an external symbol. If the symbol and the
10868 ;; program are both defined in the main program, the linker will optimize this
10869 ;; to a PADDI. Otherwise, it will create a GOT address that is relocated by
10870 ;; the dynamic linker and loaded up. Print_operand_address will append a
10871 ;; @got@pcrel to the symbol.
10872 (define_insn "*pcrel_extern_addr"
10873 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
10874 (match_operand:DI 1 "pcrel_external_address"))]
10875 "TARGET_PCREL"
10876 "ld %0,%a1"
10877 [(set_attr "prefixed" "yes")
10878 (set_attr "type" "load")
10879 (set_attr "loads_external_address" "yes")])
10880
10881 ;; TOC register handling.
10882
10883 ;; Code to initialize the TOC register...
10884
10885 (define_insn "load_toc_aix_si"
10886 [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10887 (unspec:SI [(const_int 0)] UNSPEC_TOC))
10888 (use (reg:SI 2))])]
10889 "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_32BIT"
10890 {
10891 char buf[30];
10892 extern int need_toc_init;
10893 need_toc_init = 1;
10894 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
10895 operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
10896 operands[2] = gen_rtx_REG (Pmode, 2);
10897 return "lwz %0,%1(%2)";
10898 }
10899 [(set_attr "type" "load")
10900 (set_attr "update" "no")
10901 (set_attr "indexed" "no")])
10902
10903 (define_insn "load_toc_aix_di"
10904 [(parallel [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
10905 (unspec:DI [(const_int 0)] UNSPEC_TOC))
10906 (use (reg:DI 2))])]
10907 "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_64BIT"
10908 {
10909 char buf[30];
10910 extern int need_toc_init;
10911 need_toc_init = 1;
10912 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC",
10913 !TARGET_ELF || !TARGET_MINIMAL_TOC);
10914 if (TARGET_ELF)
10915 strcat (buf, "@toc");
10916 operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
10917 operands[2] = gen_rtx_REG (Pmode, 2);
10918 return "ld %0,%1(%2)";
10919 }
10920 [(set_attr "type" "load")
10921 (set_attr "update" "no")
10922 (set_attr "indexed" "no")])
10923
10924 (define_insn "load_toc_v4_pic_si"
10925 [(set (reg:SI LR_REGNO)
10926 (unspec:SI [(const_int 0)] UNSPEC_TOC))]
10927 "DEFAULT_ABI == ABI_V4 && flag_pic == 1 && TARGET_32BIT"
10928 "bl _GLOBAL_OFFSET_TABLE_@local-4"
10929 [(set_attr "type" "branch")])
10930
10931 (define_expand "load_toc_v4_PIC_1"
10932 [(parallel [(set (reg:SI LR_REGNO)
10933 (match_operand:SI 0 "immediate_operand" "s"))
10934 (use (unspec [(match_dup 0)] UNSPEC_TOC))])]
10935 "TARGET_ELF && DEFAULT_ABI == ABI_V4
10936 && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10937 "")
10938
10939 (define_insn "load_toc_v4_PIC_1_normal"
10940 [(set (reg:SI LR_REGNO)
10941 (match_operand:SI 0 "immediate_operand" "s"))
10942 (use (unspec [(match_dup 0)] UNSPEC_TOC))]
10943 "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
10944 && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10945 "bcl 20,31,%0\n%0:"
10946 [(set_attr "type" "branch")
10947 (set_attr "cannot_copy" "yes")])
10948
10949 (define_insn "load_toc_v4_PIC_1_476"
10950 [(set (reg:SI LR_REGNO)
10951 (match_operand:SI 0 "immediate_operand" "s"))
10952 (use (unspec [(match_dup 0)] UNSPEC_TOC))]
10953 "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
10954 && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10955 {
10956 char name[32];
10957 static char templ[32];
10958
10959 get_ppc476_thunk_name (name);
10960 sprintf (templ, "bl %s\n%%0:", name);
10961 return templ;
10962 }
10963 [(set_attr "type" "branch")
10964 (set_attr "cannot_copy" "yes")])
10965
10966 (define_expand "load_toc_v4_PIC_1b"
10967 [(parallel [(set (reg:SI LR_REGNO)
10968 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10969 (label_ref (match_operand 1 ""))]
10970 UNSPEC_TOCPTR))
10971 (match_dup 1)])]
10972 "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10973 "")
10974
10975 (define_insn "load_toc_v4_PIC_1b_normal"
10976 [(set (reg:SI LR_REGNO)
10977 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10978 (label_ref (match_operand 1 "" ""))]
10979 UNSPEC_TOCPTR))
10980 (match_dup 1)]
10981 "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10982 "bcl 20,31,$+8\;.long %0-$"
10983 [(set_attr "type" "branch")
10984 (set_attr "length" "8")])
10985
10986 (define_insn "load_toc_v4_PIC_1b_476"
10987 [(set (reg:SI LR_REGNO)
10988 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10989 (label_ref (match_operand 1 "" ""))]
10990 UNSPEC_TOCPTR))
10991 (match_dup 1)]
10992 "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10993 {
10994 char name[32];
10995 static char templ[32];
10996
10997 get_ppc476_thunk_name (name);
10998 sprintf (templ, "bl %s\;b $+8\;.long %%0-$", name);
10999 return templ;
11000 }
11001 [(set_attr "type" "branch")
11002 (set_attr "length" "16")])
11003
11004 (define_insn "load_toc_v4_PIC_2"
11005 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11006 (mem:SI (plus:SI
11007 (match_operand:SI 1 "gpc_reg_operand" "b")
11008 (const
11009 (minus:SI (match_operand:SI 2 "immediate_operand" "s")
11010 (match_operand:SI 3 "immediate_operand" "s"))))))]
11011 "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
11012 "lwz %0,%2-%3(%1)"
11013 [(set_attr "type" "load")])
11014
11015 (define_insn "load_toc_v4_PIC_3b"
11016 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11017 (plus:SI
11018 (match_operand:SI 1 "gpc_reg_operand" "b")
11019 (high:SI
11020 (const
11021 (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
11022 (match_operand:SI 3 "symbol_ref_operand" "s"))))))]
11023 "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
11024 "addis %0,%1,%2-%3@ha")
11025
11026 (define_insn "load_toc_v4_PIC_3c"
11027 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11028 (lo_sum:SI
11029 (match_operand:SI 1 "gpc_reg_operand" "b")
11030 (const
11031 (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
11032 (match_operand:SI 3 "symbol_ref_operand" "s")))))]
11033 "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
11034 "addi %0,%1,%2-%3@l")
11035
11036 ;; If the TOC is shared over a translation unit, as happens with all
11037 ;; the kinds of PIC that we support, we need to restore the TOC
11038 ;; pointer only when jumping over units of translation.
11039 ;; On Darwin, we need to reload the picbase.
11040
11041 (define_expand "builtin_setjmp_receiver"
11042 [(use (label_ref (match_operand 0 "")))]
11043 "(DEFAULT_ABI == ABI_V4 && flag_pic == 1)
11044 || (TARGET_TOC && TARGET_MINIMAL_TOC)
11045 || (DEFAULT_ABI == ABI_DARWIN && flag_pic)"
11046 {
11047 #if TARGET_MACHO
11048 if (DEFAULT_ABI == ABI_DARWIN)
11049 {
11050 rtx picrtx = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME);
11051 rtx picreg = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
11052 rtx tmplabrtx;
11053 char tmplab[20];
11054
11055 crtl->uses_pic_offset_table = 1;
11056 ASM_GENERATE_INTERNAL_LABEL(tmplab, "LSJR",
11057 CODE_LABEL_NUMBER (operands[0]));
11058 tmplabrtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (tmplab));
11059
11060 emit_insn (gen_load_macho_picbase (Pmode, tmplabrtx));
11061 emit_move_insn (picreg, gen_rtx_REG (Pmode, LR_REGNO));
11062 emit_insn (gen_macho_correct_pic (Pmode, picreg, picreg,
11063 picrtx, tmplabrtx));
11064 }
11065 else
11066 #endif
11067 rs6000_emit_load_toc_table (FALSE);
11068 DONE;
11069 })
11070
11071 ;; Largetoc support
11072 (define_insn "*largetoc_high"
11073 [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
11074 (high:DI
11075 (unspec [(match_operand:DI 1 "" "")
11076 (match_operand:DI 2 "gpc_reg_operand" "b")]
11077 UNSPEC_TOCREL)))]
11078 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
11079 "addis %0,%2,%1@toc@ha")
11080
11081 (define_insn "*largetoc_high_aix<mode>"
11082 [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
11083 (high:P
11084 (unspec [(match_operand:P 1 "" "")
11085 (match_operand:P 2 "gpc_reg_operand" "b")]
11086 UNSPEC_TOCREL)))]
11087 "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
11088 "addis %0,%1@u(%2)")
11089
11090 (define_insn "*largetoc_high_plus"
11091 [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
11092 (high:DI
11093 (plus:DI
11094 (unspec [(match_operand:DI 1 "" "")
11095 (match_operand:DI 2 "gpc_reg_operand" "b")]
11096 UNSPEC_TOCREL)
11097 (match_operand:DI 3 "add_cint_operand" "n"))))]
11098 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
11099 "addis %0,%2,%1+%3@toc@ha")
11100
11101 (define_insn "*largetoc_high_plus_aix<mode>"
11102 [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
11103 (high:P
11104 (plus:P
11105 (unspec [(match_operand:P 1 "" "")
11106 (match_operand:P 2 "gpc_reg_operand" "b")]
11107 UNSPEC_TOCREL)
11108 (match_operand:P 3 "add_cint_operand" "n"))))]
11109 "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
11110 "addis %0,%1+%3@u(%2)")
11111
11112 (define_insn "*largetoc_low"
11113 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
11114 (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b")
11115 (match_operand:DI 2 "" "")))]
11116 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
11117 "addi %0,%1,%2@l")
11118
11119 (define_insn "*largetoc_low_aix<mode>"
11120 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11121 (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
11122 (match_operand:P 2 "" "")))]
11123 "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
11124 "la %0,%2@l(%1)")
11125
11126 (define_insn_and_split "*tocref<mode>"
11127 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
11128 (match_operand:P 1 "small_toc_ref" "R"))]
11129 "TARGET_TOC
11130 && legitimate_constant_pool_address_p (operands[1], QImode, false)"
11131 "la %0,%a1"
11132 "&& TARGET_CMODEL != CMODEL_SMALL && reload_completed"
11133 [(set (match_dup 0) (high:P (match_dup 1)))
11134 (set (match_dup 0) (lo_sum:P (match_dup 0) (match_dup 1)))])
11135
11136 ;; Elf specific ways of loading addresses for non-PIC code.
11137 ;; The output of this could be r0, but we make a very strong
11138 ;; preference for a base register because it will usually
11139 ;; be needed there.
11140 (define_insn "elf_high"
11141 [(set (match_operand:SI 0 "gpc_reg_operand" "=b*r")
11142 (high:SI (match_operand 1 "" "")))]
11143 "TARGET_ELF && !TARGET_64BIT && !flag_pic"
11144 "lis %0,%1@ha")
11145
11146 (define_insn "elf_low"
11147 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11148 (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
11149 (match_operand 2 "" "")))]
11150 "TARGET_ELF && !TARGET_64BIT && !flag_pic"
11151 "la %0,%2@l(%1)")
11152
11153 (define_insn "*pltseq_tocsave_<mode>"
11154 [(set (match_operand:P 0 "memory_operand" "=m")
11155 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
11156 (match_operand:P 2 "symbol_ref_operand" "s")
11157 (match_operand:P 3 "" "")]
11158 UNSPEC_PLTSEQ))]
11159 "TARGET_PLTSEQ
11160 && DEFAULT_ABI == ABI_ELFv2"
11161 {
11162 return rs6000_pltseq_template (operands, RS6000_PLTSEQ_TOCSAVE);
11163 })
11164
11165 (define_insn "*pltseq_plt16_ha_<mode>"
11166 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11167 (unspec:P [(match_operand:P 1 "" "")
11168 (match_operand:P 2 "symbol_ref_operand" "s")
11169 (match_operand:P 3 "" "")]
11170 UNSPEC_PLT16_HA))]
11171 "TARGET_PLTSEQ"
11172 {
11173 return rs6000_pltseq_template (operands, RS6000_PLTSEQ_PLT16_HA);
11174 })
11175
11176 (define_insn "*pltseq_plt16_lo_<mode>"
11177 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11178 (unspec_volatile:P [(match_operand:P 1 "gpc_reg_operand" "b")
11179 (match_operand:P 2 "symbol_ref_operand" "s")
11180 (match_operand:P 3 "" "")]
11181 UNSPECV_PLT16_LO))]
11182 "TARGET_PLTSEQ"
11183 {
11184 return rs6000_pltseq_template (operands, RS6000_PLTSEQ_PLT16_LO);
11185 }
11186 [(set_attr "type" "load")])
11187
11188 (define_insn "*pltseq_mtctr_<mode>"
11189 [(set (match_operand:P 0 "register_operand" "=c")
11190 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "r")
11191 (match_operand:P 2 "symbol_ref_operand" "s")
11192 (match_operand:P 3 "" "")]
11193 UNSPEC_PLTSEQ))]
11194 "TARGET_PLTSEQ"
11195 {
11196 return rs6000_pltseq_template (operands, RS6000_PLTSEQ_MTCTR);
11197 })
11198
11199 (define_insn "*pltseq_plt_pcrel<mode>"
11200 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11201 (unspec_volatile:P [(match_operand:P 1 "" "")
11202 (match_operand:P 2 "symbol_ref_operand" "s")
11203 (match_operand:P 3 "" "")]
11204 UNSPECV_PLT_PCREL))]
11205 "HAVE_AS_PLTSEQ && TARGET_ELF
11206 && rs6000_pcrel_p ()"
11207 {
11208 return rs6000_pltseq_template (operands, RS6000_PLTSEQ_PLT_PCREL34);
11209 }
11210 [(set_attr "type" "load")
11211 (set_attr "length" "12")])
11212 \f
11213 ;; Call and call_value insns
11214 ;; For the purposes of expanding calls, Darwin is very similar to SYSV.
11215 (define_expand "call"
11216 [(parallel [(call (mem:SI (match_operand 0 "address_operand"))
11217 (match_operand 1 ""))
11218 (use (match_operand 2 ""))
11219 (clobber (reg:SI LR_REGNO))])]
11220 ""
11221 {
11222 #if TARGET_MACHO
11223 if (MACHOPIC_INDIRECT)
11224 operands[0] = machopic_indirect_call_target (operands[0]);
11225 #endif
11226
11227 gcc_assert (MEM_P (operands[0]));
11228
11229 operands[0] = XEXP (operands[0], 0);
11230
11231 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
11232 rs6000_call_aix (NULL_RTX, operands[0], operands[1], operands[2]);
11233 else if (DEFAULT_ABI == ABI_V4)
11234 rs6000_call_sysv (NULL_RTX, operands[0], operands[1], operands[2]);
11235 else if (DEFAULT_ABI == ABI_DARWIN)
11236 rs6000_call_darwin (NULL_RTX, operands[0], operands[1], operands[2]);
11237 else
11238 gcc_unreachable ();
11239
11240 DONE;
11241 })
11242
11243 (define_expand "call_value"
11244 [(parallel [(set (match_operand 0 "")
11245 (call (mem:SI (match_operand 1 "address_operand"))
11246 (match_operand 2 "")))
11247 (use (match_operand 3 ""))
11248 (clobber (reg:SI LR_REGNO))])]
11249 ""
11250 {
11251 #if TARGET_MACHO
11252 if (MACHOPIC_INDIRECT)
11253 operands[1] = machopic_indirect_call_target (operands[1]);
11254 #endif
11255
11256 gcc_assert (MEM_P (operands[1]));
11257
11258 operands[1] = XEXP (operands[1], 0);
11259
11260 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
11261 rs6000_call_aix (operands[0], operands[1], operands[2], operands[3]);
11262 else if (DEFAULT_ABI == ABI_V4)
11263 rs6000_call_sysv (operands[0], operands[1], operands[2], operands[3]);
11264 else if (DEFAULT_ABI == ABI_DARWIN)
11265 rs6000_call_darwin (operands[0], operands[1], operands[2], operands[3]);
11266 else
11267 gcc_unreachable ();
11268
11269 DONE;
11270 })
11271
11272 ;; Call to function in current module. No TOC pointer reload needed.
11273 ;; Operand2 is nonzero if we are using the V.4 calling sequence and
11274 ;; either the function was not prototyped, or it was prototyped as a
11275 ;; variable argument function. It is > 0 if FP registers were passed
11276 ;; and < 0 if they were not.
11277
11278 (define_insn "*call_local<mode>"
11279 [(call (mem:SI (match_operand:P 0 "current_file_function_operand" "s,s"))
11280 (match_operand 1))
11281 (use (match_operand:SI 2 "immediate_operand" "O,n"))
11282 (clobber (reg:P LR_REGNO))]
11283 "(INTVAL (operands[2]) & CALL_LONG) == 0"
11284 {
11285 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
11286 output_asm_insn ("crxor 6,6,6", operands);
11287
11288 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
11289 output_asm_insn ("creqv 6,6,6", operands);
11290
11291 if (rs6000_pcrel_p ())
11292 return "bl %z0@notoc";
11293 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z0@local" : "bl %z0";
11294 }
11295 [(set_attr "type" "branch")
11296 (set_attr "length" "4,8")])
11297
11298 (define_insn "*call_value_local<mode>"
11299 [(set (match_operand 0 "" "")
11300 (call (mem:SI (match_operand:P 1 "current_file_function_operand" "s,s"))
11301 (match_operand 2)))
11302 (use (match_operand:SI 3 "immediate_operand" "O,n"))
11303 (clobber (reg:P LR_REGNO))]
11304 "(INTVAL (operands[3]) & CALL_LONG) == 0"
11305 {
11306 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11307 output_asm_insn ("crxor 6,6,6", operands);
11308
11309 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11310 output_asm_insn ("creqv 6,6,6", operands);
11311
11312 if (rs6000_pcrel_p ())
11313 return "bl %z1@notoc";
11314 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z1@local" : "bl %z1";
11315 }
11316 [(set_attr "type" "branch")
11317 (set_attr "length" "4,8")])
11318
11319
11320 ;; A function pointer under System V is just a normal pointer
11321 ;; operands[0] is the function pointer
11322 ;; operands[1] is the tls call arg
11323 ;; operands[2] is the value FUNCTION_ARG returns for the VOID argument
11324 ;; which indicates how to set cr1
11325
11326 (define_insn "*call_indirect_nonlocal_sysv<mode>"
11327 [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X"))
11328 (match_operand 1))
11329 (use (match_operand:SI 2 "immediate_operand" "n,n,n"))
11330 (clobber (reg:P LR_REGNO))]
11331 "DEFAULT_ABI == ABI_V4
11332 || DEFAULT_ABI == ABI_DARWIN"
11333 {
11334 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
11335 output_asm_insn ("crxor 6,6,6", operands);
11336
11337 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
11338 output_asm_insn ("creqv 6,6,6", operands);
11339
11340 return rs6000_indirect_call_template (operands, 0);
11341 }
11342 [(set_attr "type" "jmpreg")
11343 (set (attr "length")
11344 (cond [(and (and (match_test "!rs6000_speculate_indirect_jumps")
11345 (match_test "which_alternative != 1"))
11346 (match_test "(INTVAL (operands[2]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
11347 (const_string "12")
11348 (ior (and (match_test "!rs6000_speculate_indirect_jumps")
11349 (match_test "which_alternative != 1"))
11350 (match_test "(INTVAL (operands[2]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
11351 (const_string "8")]
11352 (const_string "4")))])
11353
11354 (define_insn "*call_nonlocal_sysv<mode>"
11355 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
11356 (match_operand 1))
11357 (use (match_operand:SI 2 "immediate_operand" "O,n"))
11358 (clobber (reg:P LR_REGNO))]
11359 "(DEFAULT_ABI == ABI_DARWIN
11360 || (DEFAULT_ABI == ABI_V4
11361 && (INTVAL (operands[2]) & CALL_LONG) == 0))"
11362 {
11363 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
11364 output_asm_insn ("crxor 6,6,6", operands);
11365
11366 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
11367 output_asm_insn ("creqv 6,6,6", operands);
11368
11369 return rs6000_call_template (operands, 0);
11370 }
11371 [(set_attr "type" "branch,branch")
11372 (set_attr "length" "4,8")])
11373
11374 (define_insn "*call_nonlocal_sysv_secure<mode>"
11375 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
11376 (match_operand 1))
11377 (use (match_operand:SI 2 "immediate_operand" "O,n"))
11378 (use (match_operand:SI 3 "register_operand" "r,r"))
11379 (clobber (reg:P LR_REGNO))]
11380 "(DEFAULT_ABI == ABI_V4
11381 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0])
11382 && (INTVAL (operands[2]) & CALL_LONG) == 0)"
11383 {
11384 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
11385 output_asm_insn ("crxor 6,6,6", operands);
11386
11387 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
11388 output_asm_insn ("creqv 6,6,6", operands);
11389
11390 return rs6000_call_template (operands, 0);
11391 }
11392 [(set_attr "type" "branch,branch")
11393 (set_attr "length" "4,8")])
11394
11395 (define_insn "*call_value_indirect_nonlocal_sysv<mode>"
11396 [(set (match_operand 0 "" "")
11397 (call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X"))
11398 (match_operand:P 2 "unspec_tls" "")))
11399 (use (match_operand:SI 3 "immediate_operand" "n,n,n"))
11400 (clobber (reg:P LR_REGNO))]
11401 "DEFAULT_ABI == ABI_V4
11402 || DEFAULT_ABI == ABI_DARWIN"
11403 {
11404 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11405 output_asm_insn ("crxor 6,6,6", operands);
11406
11407 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11408 output_asm_insn ("creqv 6,6,6", operands);
11409
11410 return rs6000_indirect_call_template (operands, 1);
11411 }
11412 [(set_attr "type" "jmpreg")
11413 (set (attr "length")
11414 (plus
11415 (if_then_else (match_test "IS_V4_FP_ARGS (operands[3])")
11416 (const_int 4)
11417 (const_int 0))
11418 (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
11419 (match_test "which_alternative != 1"))
11420 (const_int 8)
11421 (const_int 4))))])
11422
11423 (define_insn "*call_value_nonlocal_sysv<mode>"
11424 [(set (match_operand 0 "" "")
11425 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s"))
11426 (match_operand:P 2 "unspec_tls" "")))
11427 (use (match_operand:SI 3 "immediate_operand" "n"))
11428 (clobber (reg:P LR_REGNO))]
11429 "(DEFAULT_ABI == ABI_DARWIN
11430 || (DEFAULT_ABI == ABI_V4
11431 && (INTVAL (operands[3]) & CALL_LONG) == 0))"
11432 {
11433 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11434 output_asm_insn ("crxor 6,6,6", operands);
11435
11436 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11437 output_asm_insn ("creqv 6,6,6", operands);
11438
11439 return rs6000_call_template (operands, 1);
11440 }
11441 [(set_attr "type" "branch")
11442 (set (attr "length")
11443 (if_then_else (match_test "IS_V4_FP_ARGS (operands[3])")
11444 (const_int 8)
11445 (const_int 4)))])
11446
11447 (define_insn "*call_value_nonlocal_sysv_secure<mode>"
11448 [(set (match_operand 0 "" "")
11449 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s"))
11450 (match_operand:P 2 "unspec_tls" "")))
11451 (use (match_operand:SI 3 "immediate_operand" "n"))
11452 (use (match_operand:SI 4 "register_operand" "r"))
11453 (clobber (reg:P LR_REGNO))]
11454 "(DEFAULT_ABI == ABI_V4
11455 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1])
11456 && (INTVAL (operands[3]) & CALL_LONG) == 0)"
11457 {
11458 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11459 output_asm_insn ("crxor 6,6,6", operands);
11460
11461 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11462 output_asm_insn ("creqv 6,6,6", operands);
11463
11464 return rs6000_call_template (operands, 1);
11465 }
11466 [(set_attr "type" "branch")
11467 (set (attr "length")
11468 (if_then_else (match_test "IS_V4_FP_ARGS (operands[3])")
11469 (const_int 8)
11470 (const_int 4)))])
11471
11472 ;; Call to AIX abi function which may be in another module.
11473 ;; Restore the TOC pointer (r2) after the call.
11474
11475 (define_insn "*call_nonlocal_aix<mode>"
11476 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s"))
11477 (match_operand 1))
11478 (use (match_operand:SI 2 "immediate_operand" "n"))
11479 (clobber (reg:P LR_REGNO))]
11480 "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
11481 && (INTVAL (operands[2]) & CALL_LONG) == 0"
11482 {
11483 return rs6000_call_template (operands, 0);
11484 }
11485 [(set_attr "type" "branch")
11486 (set (attr "length")
11487 (if_then_else (match_test "rs6000_pcrel_p ()")
11488 (const_int 4)
11489 (const_int 8)))])
11490
11491 (define_insn "*call_value_nonlocal_aix<mode>"
11492 [(set (match_operand 0 "" "")
11493 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s"))
11494 (match_operand:P 2 "unspec_tls" "")))
11495 (use (match_operand:SI 3 "immediate_operand" "n"))
11496 (clobber (reg:P LR_REGNO))]
11497 "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
11498 && (INTVAL (operands[3]) & CALL_LONG) == 0"
11499 {
11500 return rs6000_call_template (operands, 1);
11501 }
11502 [(set_attr "type" "branch")
11503 (set (attr "length")
11504 (if_then_else (match_test "rs6000_pcrel_p ()")
11505 (const_int 4)
11506 (const_int 8)))])
11507
11508 ;; Call to indirect functions with the AIX abi using a 3 word descriptor.
11509 ;; Operand0 is the addresss of the function to call
11510 ;; Operand3 is the location in the function descriptor to load r2 from
11511 ;; Operand4 is the offset of the stack location holding the current TOC pointer
11512
11513 (define_insn "*call_indirect_aix<mode>"
11514 [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X"))
11515 (match_operand 1))
11516 (use (match_operand:SI 2 "immediate_operand" "n,n,n"))
11517 (use (match_operand:P 3 "memory_operand" "<ptrm>,<ptrm>,<ptrm>"))
11518 (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 4 "const_int_operand" "n,n,n")] UNSPEC_TOCSLOT))
11519 (clobber (reg:P LR_REGNO))]
11520 "DEFAULT_ABI == ABI_AIX"
11521 {
11522 return rs6000_indirect_call_template (operands, 0);
11523 }
11524 [(set_attr "type" "jmpreg")
11525 (set (attr "length")
11526 (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
11527 (match_test "which_alternative != 1"))
11528 (const_string "16")
11529 (const_string "12")))])
11530
11531 (define_insn "*call_value_indirect_aix<mode>"
11532 [(set (match_operand 0 "" "")
11533 (call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X"))
11534 (match_operand:P 2 "unspec_tls" "")))
11535 (use (match_operand:SI 3 "immediate_operand" "n,n,n"))
11536 (use (match_operand:P 4 "memory_operand" "<ptrm>,<ptrm>,<ptrm>"))
11537 (set (reg:P TOC_REGNUM)
11538 (unspec:P [(match_operand:P 5 "const_int_operand" "n,n,n")]
11539 UNSPEC_TOCSLOT))
11540 (clobber (reg:P LR_REGNO))]
11541 "DEFAULT_ABI == ABI_AIX"
11542 {
11543 return rs6000_indirect_call_template (operands, 1);
11544 }
11545 [(set_attr "type" "jmpreg")
11546 (set (attr "length")
11547 (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
11548 (match_test "which_alternative != 1"))
11549 (const_string "16")
11550 (const_string "12")))])
11551
11552 ;; Call to indirect functions with the ELFv2 ABI.
11553 ;; Operand0 is the addresss of the function to call
11554 ;; Operand3 is the offset of the stack location holding the current TOC pointer
11555
11556 (define_insn "*call_indirect_elfv2<mode>"
11557 [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X"))
11558 (match_operand 1))
11559 (use (match_operand:SI 2 "immediate_operand" "n,n,n"))
11560 (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 3 "const_int_operand" "n,n,n")] UNSPEC_TOCSLOT))
11561 (clobber (reg:P LR_REGNO))]
11562 "DEFAULT_ABI == ABI_ELFv2"
11563 {
11564 return rs6000_indirect_call_template (operands, 0);
11565 }
11566 [(set_attr "type" "jmpreg")
11567 (set (attr "length")
11568 (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
11569 (match_test "which_alternative != 1"))
11570 (const_string "12")
11571 (const_string "8")))])
11572
11573 (define_insn "*call_indirect_pcrel<mode>"
11574 [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X"))
11575 (match_operand 1))
11576 (use (match_operand:SI 2 "immediate_operand" "n,n,n"))
11577 (clobber (reg:P LR_REGNO))]
11578 "rs6000_pcrel_p ()"
11579 {
11580 return rs6000_indirect_call_template (operands, 0);
11581 }
11582 [(set_attr "type" "jmpreg")
11583 (set (attr "length")
11584 (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
11585 (match_test "which_alternative != 1"))
11586 (const_string "8")
11587 (const_string "4")))])
11588
11589 (define_insn "*call_value_indirect_elfv2<mode>"
11590 [(set (match_operand 0 "" "")
11591 (call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X"))
11592 (match_operand:P 2 "unspec_tls" "")))
11593 (use (match_operand:SI 3 "immediate_operand" "n,n,n"))
11594 (set (reg:P TOC_REGNUM)
11595 (unspec:P [(match_operand:P 4 "const_int_operand" "n,n,n")]
11596 UNSPEC_TOCSLOT))
11597 (clobber (reg:P LR_REGNO))]
11598 "DEFAULT_ABI == ABI_ELFv2"
11599 {
11600 return rs6000_indirect_call_template (operands, 1);
11601 }
11602 [(set_attr "type" "jmpreg")
11603 (set (attr "length")
11604 (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
11605 (match_test "which_alternative != 1"))
11606 (const_string "12")
11607 (const_string "8")))])
11608
11609 (define_insn "*call_value_indirect_pcrel<mode>"
11610 [(set (match_operand 0 "" "")
11611 (call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X"))
11612 (match_operand:P 2 "unspec_tls" "")))
11613 (use (match_operand:SI 3 "immediate_operand" "n,n,n"))
11614 (clobber (reg:P LR_REGNO))]
11615 "rs6000_pcrel_p ()"
11616 {
11617 return rs6000_indirect_call_template (operands, 1);
11618 }
11619 [(set_attr "type" "jmpreg")
11620 (set (attr "length")
11621 (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
11622 (match_test "which_alternative != 1"))
11623 (const_string "8")
11624 (const_string "4")))])
11625
11626 ;; Call subroutine returning any type.
11627 (define_expand "untyped_call"
11628 [(parallel [(call (match_operand 0 "")
11629 (const_int 0))
11630 (match_operand 1 "")
11631 (match_operand 2 "")])]
11632 ""
11633 {
11634 int i;
11635
11636 emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
11637
11638 for (int i = 0; i < XVECLEN (operands[2], 0); i++)
11639 emit_clobber (SET_SRC (XVECEXP (operands[2], 0, i)));
11640 emit_insn (gen_blockage ());
11641
11642 for (i = 0; i < XVECLEN (operands[2], 0); i++)
11643 {
11644 rtx set = XVECEXP (operands[2], 0, i);
11645 emit_move_insn (SET_DEST (set), SET_SRC (set));
11646 }
11647
11648 /* The optimizer does not know that the call sets the function value
11649 registers we stored in the result block. We avoid problems by
11650 claiming that all hard registers are used and clobbered at this
11651 point. */
11652 emit_insn (gen_blockage ());
11653
11654 DONE;
11655 })
11656
11657 ;; sibling call patterns
11658 (define_expand "sibcall"
11659 [(parallel [(call (mem:SI (match_operand 0 "address_operand"))
11660 (match_operand 1 ""))
11661 (use (match_operand 2 ""))
11662 (simple_return)])]
11663 ""
11664 {
11665 #if TARGET_MACHO
11666 if (MACHOPIC_INDIRECT)
11667 operands[0] = machopic_indirect_call_target (operands[0]);
11668 #endif
11669
11670 gcc_assert (MEM_P (operands[0]));
11671 gcc_assert (CONST_INT_P (operands[1]));
11672
11673 operands[0] = XEXP (operands[0], 0);
11674
11675 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
11676 rs6000_sibcall_aix (NULL_RTX, operands[0], operands[1], operands[2]);
11677 else if (DEFAULT_ABI == ABI_V4)
11678 rs6000_sibcall_sysv (NULL_RTX, operands[0], operands[1], operands[2]);
11679 else if (DEFAULT_ABI == ABI_DARWIN)
11680 rs6000_sibcall_darwin (NULL_RTX, operands[0], operands[1], operands[2]);
11681 else
11682 gcc_unreachable ();
11683
11684 DONE;
11685 })
11686
11687 (define_expand "sibcall_value"
11688 [(parallel [(set (match_operand 0 "register_operand")
11689 (call (mem:SI (match_operand 1 "address_operand"))
11690 (match_operand 2 "")))
11691 (use (match_operand 3 ""))
11692 (simple_return)])]
11693 ""
11694 {
11695 #if TARGET_MACHO
11696 if (MACHOPIC_INDIRECT)
11697 operands[1] = machopic_indirect_call_target (operands[1]);
11698 #endif
11699
11700 gcc_assert (MEM_P (operands[1]));
11701 gcc_assert (CONST_INT_P (operands[2]));
11702
11703 operands[1] = XEXP (operands[1], 0);
11704
11705 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
11706 rs6000_sibcall_aix (operands[0], operands[1], operands[2], operands[3]);
11707 else if (DEFAULT_ABI == ABI_V4)
11708 rs6000_sibcall_sysv (operands[0], operands[1], operands[2], operands[3]);
11709 else if (DEFAULT_ABI == ABI_DARWIN)
11710 rs6000_sibcall_darwin (operands[0], operands[1], operands[2], operands[3]);
11711 else
11712 gcc_unreachable ();
11713
11714 DONE;
11715 })
11716
11717 (define_insn "*sibcall_local<mode>"
11718 [(call (mem:SI (match_operand:P 0 "current_file_function_operand" "s,s"))
11719 (match_operand 1))
11720 (use (match_operand:SI 2 "immediate_operand" "O,n"))
11721 (simple_return)]
11722 "(INTVAL (operands[2]) & CALL_LONG) == 0"
11723 {
11724 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
11725 output_asm_insn ("crxor 6,6,6", operands);
11726
11727 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
11728 output_asm_insn ("creqv 6,6,6", operands);
11729
11730 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z0@local" : "b %z0";
11731 }
11732 [(set_attr "type" "branch")
11733 (set_attr "length" "4,8")])
11734
11735 (define_insn "*sibcall_value_local<mode>"
11736 [(set (match_operand 0 "" "")
11737 (call (mem:SI (match_operand:P 1 "current_file_function_operand" "s,s"))
11738 (match_operand 2)))
11739 (use (match_operand:SI 3 "immediate_operand" "O,n"))
11740 (simple_return)]
11741 "(INTVAL (operands[3]) & CALL_LONG) == 0"
11742 {
11743 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11744 output_asm_insn ("crxor 6,6,6", operands);
11745
11746 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11747 output_asm_insn ("creqv 6,6,6", operands);
11748
11749 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z1@local" : "b %z1";
11750 }
11751 [(set_attr "type" "branch")
11752 (set_attr "length" "4,8")])
11753
11754 (define_insn "*sibcall_indirect_nonlocal_sysv<mode>"
11755 [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X"))
11756 (match_operand 1))
11757 (use (match_operand:SI 2 "immediate_operand" "n,n,n"))
11758 (simple_return)]
11759 "DEFAULT_ABI == ABI_V4
11760 || DEFAULT_ABI == ABI_DARWIN"
11761 {
11762 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
11763 output_asm_insn ("crxor 6,6,6", operands);
11764
11765 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
11766 output_asm_insn ("creqv 6,6,6", operands);
11767
11768 return rs6000_indirect_sibcall_template (operands, 0);
11769 }
11770 [(set_attr "type" "jmpreg")
11771 (set (attr "length")
11772 (cond [(and (and (match_test "!rs6000_speculate_indirect_jumps")
11773 (match_test "which_alternative != 1"))
11774 (match_test "(INTVAL (operands[2]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
11775 (const_string "12")
11776 (ior (and (match_test "!rs6000_speculate_indirect_jumps")
11777 (match_test "which_alternative != 1"))
11778 (match_test "(INTVAL (operands[2]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
11779 (const_string "8")]
11780 (const_string "4")))])
11781
11782 (define_insn "*sibcall_nonlocal_sysv<mode>"
11783 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
11784 (match_operand 1))
11785 (use (match_operand 2 "immediate_operand" "O,n"))
11786 (simple_return)]
11787 "(DEFAULT_ABI == ABI_DARWIN
11788 || DEFAULT_ABI == ABI_V4)
11789 && (INTVAL (operands[2]) & CALL_LONG) == 0"
11790 {
11791 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
11792 output_asm_insn ("crxor 6,6,6", operands);
11793
11794 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
11795 output_asm_insn ("creqv 6,6,6", operands);
11796
11797 return rs6000_sibcall_template (operands, 0);
11798 }
11799 [(set_attr "type" "branch")
11800 (set_attr "length" "4,8")])
11801
11802 (define_insn "*sibcall_value_indirect_nonlocal_sysv<mode>"
11803 [(set (match_operand 0 "" "")
11804 (call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X"))
11805 (match_operand 2)))
11806 (use (match_operand:SI 3 "immediate_operand" "n,n,n"))
11807 (simple_return)]
11808 "DEFAULT_ABI == ABI_V4
11809 || DEFAULT_ABI == ABI_DARWIN"
11810 {
11811 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11812 output_asm_insn ("crxor 6,6,6", operands);
11813
11814 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11815 output_asm_insn ("creqv 6,6,6", operands);
11816
11817 return rs6000_indirect_sibcall_template (operands, 1);
11818 }
11819 [(set_attr "type" "jmpreg")
11820 (set (attr "length")
11821 (cond [(and (and (match_test "!rs6000_speculate_indirect_jumps")
11822 (match_test "which_alternative != 1"))
11823 (match_test "(INTVAL (operands[3]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
11824 (const_string "12")
11825 (ior (and (match_test "!rs6000_speculate_indirect_jumps")
11826 (match_test "which_alternative != 1"))
11827 (match_test "(INTVAL (operands[3]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
11828 (const_string "8")]
11829 (const_string "4")))])
11830
11831 (define_insn "*sibcall_value_nonlocal_sysv<mode>"
11832 [(set (match_operand 0 "" "")
11833 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
11834 (match_operand 2)))
11835 (use (match_operand:SI 3 "immediate_operand" "O,n"))
11836 (simple_return)]
11837 "(DEFAULT_ABI == ABI_DARWIN
11838 || DEFAULT_ABI == ABI_V4)
11839 && (INTVAL (operands[3]) & CALL_LONG) == 0"
11840 {
11841 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11842 output_asm_insn ("crxor 6,6,6", operands);
11843
11844 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11845 output_asm_insn ("creqv 6,6,6", operands);
11846
11847 return rs6000_sibcall_template (operands, 1);
11848 }
11849 [(set_attr "type" "branch")
11850 (set_attr "length" "4,8")])
11851
11852 ;; AIX ABI sibling call patterns.
11853
11854 (define_insn "*sibcall_aix<mode>"
11855 [(call (mem:SI (match_operand:P 0 "call_operand" "s,c"))
11856 (match_operand 1))
11857 (simple_return)]
11858 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11859 {
11860 if (which_alternative == 0)
11861 return rs6000_sibcall_template (operands, 0);
11862 else
11863 return "b%T0";
11864 }
11865 [(set_attr "type" "branch")])
11866
11867 (define_insn "*sibcall_value_aix<mode>"
11868 [(set (match_operand 0 "" "")
11869 (call (mem:SI (match_operand:P 1 "call_operand" "s,c"))
11870 (match_operand 2)))
11871 (simple_return)]
11872 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11873 {
11874 if (which_alternative == 0)
11875 return rs6000_sibcall_template (operands, 1);
11876 else
11877 return "b%T1";
11878 }
11879 [(set_attr "type" "branch")])
11880
11881 (define_expand "sibcall_epilogue"
11882 [(use (const_int 0))]
11883 ""
11884 {
11885 if (!TARGET_SCHED_PROLOG)
11886 emit_insn (gen_blockage ());
11887 rs6000_emit_epilogue (EPILOGUE_TYPE_SIBCALL);
11888 DONE;
11889 })
11890
11891 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11892 ;; all of memory. This blocks insns from being moved across this point.
11893
11894 (define_insn "blockage"
11895 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCK)]
11896 ""
11897 ""
11898 [(set_attr "length" "0")])
11899
11900 (define_expand "probe_stack_address"
11901 [(use (match_operand 0 "address_operand"))]
11902 ""
11903 {
11904 operands[0] = gen_rtx_MEM (Pmode, operands[0]);
11905 MEM_VOLATILE_P (operands[0]) = 1;
11906
11907 if (TARGET_64BIT)
11908 emit_insn (gen_probe_stack_di (operands[0]));
11909 else
11910 emit_insn (gen_probe_stack_si (operands[0]));
11911 DONE;
11912 })
11913
11914 (define_insn "probe_stack_<mode>"
11915 [(set (match_operand:P 0 "memory_operand" "=m")
11916 (unspec:P [(const_int 0)] UNSPEC_PROBE_STACK))]
11917 ""
11918 {
11919 operands[1] = gen_rtx_REG (Pmode, 0);
11920 return "st<wd>%U0%X0 %1,%0";
11921 }
11922 [(set_attr "type" "store")
11923 (set (attr "update")
11924 (if_then_else (match_operand 0 "update_address_mem")
11925 (const_string "yes")
11926 (const_string "no")))
11927 (set (attr "indexed")
11928 (if_then_else (match_operand 0 "indexed_address_mem")
11929 (const_string "yes")
11930 (const_string "no")))])
11931
11932 (define_insn "probe_stack_range<P:mode>"
11933 [(set (match_operand:P 0 "register_operand" "=&r")
11934 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
11935 (match_operand:P 2 "register_operand" "r")
11936 (match_operand:P 3 "register_operand" "r")]
11937 UNSPECV_PROBE_STACK_RANGE))]
11938 ""
11939 "* return output_probe_stack_range (operands[0], operands[2], operands[3]);"
11940 [(set_attr "type" "three")])
11941 \f
11942 ;; Compare insns are next. Note that the RS/6000 has two types of compares,
11943 ;; signed & unsigned, and one type of branch.
11944 ;;
11945 ;; Start with the DEFINE_EXPANDs to generate the rtl for compares, scc
11946 ;; insns, and branches.
11947
11948 (define_expand "cbranch<mode>4"
11949 [(use (match_operator 0 "comparison_operator"
11950 [(match_operand:GPR 1 "gpc_reg_operand")
11951 (match_operand:GPR 2 "reg_or_short_operand")]))
11952 (use (match_operand 3))]
11953 ""
11954 {
11955 /* Take care of the possibility that operands[2] might be negative but
11956 this might be a logical operation. That insn doesn't exist. */
11957 if (CONST_INT_P (operands[2])
11958 && INTVAL (operands[2]) < 0)
11959 {
11960 operands[2] = force_reg (<MODE>mode, operands[2]);
11961 operands[0] = gen_rtx_fmt_ee (GET_CODE (operands[0]),
11962 GET_MODE (operands[0]),
11963 operands[1], operands[2]);
11964 }
11965
11966 rs6000_emit_cbranch (<MODE>mode, operands);
11967 DONE;
11968 })
11969
11970 (define_expand "cbranch<mode>4"
11971 [(use (match_operator 0 "comparison_operator"
11972 [(match_operand:FP 1 "gpc_reg_operand")
11973 (match_operand:FP 2 "gpc_reg_operand")]))
11974 (use (match_operand 3))]
11975 ""
11976 {
11977 rs6000_emit_cbranch (<MODE>mode, operands);
11978 DONE;
11979 })
11980
11981 (define_expand "cbranchcc4"
11982 [(set (pc)
11983 (if_then_else (match_operator 0 "branch_comparison_operator"
11984 [(match_operand 1 "cc_reg_operand")
11985 (match_operand 2 "zero_constant")])
11986 (label_ref (match_operand 3))
11987 (pc)))]
11988 ""
11989 "")
11990
11991 (define_expand "cstore<mode>4_signed"
11992 [(use (match_operator 1 "signed_comparison_operator"
11993 [(match_operand:P 2 "gpc_reg_operand")
11994 (match_operand:P 3 "gpc_reg_operand")]))
11995 (clobber (match_operand:P 0 "gpc_reg_operand"))]
11996 ""
11997 {
11998 enum rtx_code cond_code = GET_CODE (operands[1]);
11999
12000 rtx op0 = operands[0];
12001 rtx op1 = operands[2];
12002 rtx op2 = operands[3];
12003
12004 if (cond_code == GE || cond_code == LT)
12005 {
12006 cond_code = swap_condition (cond_code);
12007 std::swap (op1, op2);
12008 }
12009
12010 rtx tmp1 = gen_reg_rtx (<MODE>mode);
12011 rtx tmp2 = gen_reg_rtx (<MODE>mode);
12012 rtx tmp3 = gen_reg_rtx (<MODE>mode);
12013
12014 int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
12015 emit_insn (gen_lshr<mode>3 (tmp1, op1, GEN_INT (sh)));
12016 emit_insn (gen_ashr<mode>3 (tmp2, op2, GEN_INT (sh)));
12017
12018 emit_insn (gen_subf<mode>3_carry (tmp3, op1, op2));
12019
12020 if (cond_code == LE)
12021 emit_insn (gen_add<mode>3_carry_in (op0, tmp1, tmp2));
12022 else
12023 {
12024 rtx tmp4 = gen_reg_rtx (<MODE>mode);
12025 emit_insn (gen_add<mode>3_carry_in (tmp4, tmp1, tmp2));
12026 emit_insn (gen_xor<mode>3 (op0, tmp4, const1_rtx));
12027 }
12028
12029 DONE;
12030 })
12031
12032 (define_expand "cstore<mode>4_unsigned"
12033 [(use (match_operator 1 "unsigned_comparison_operator"
12034 [(match_operand:P 2 "gpc_reg_operand")
12035 (match_operand:P 3 "reg_or_short_operand")]))
12036 (clobber (match_operand:P 0 "gpc_reg_operand"))]
12037 ""
12038 {
12039 enum rtx_code cond_code = GET_CODE (operands[1]);
12040
12041 rtx op0 = operands[0];
12042 rtx op1 = operands[2];
12043 rtx op2 = operands[3];
12044
12045 if (cond_code == GEU || cond_code == LTU)
12046 {
12047 cond_code = swap_condition (cond_code);
12048 std::swap (op1, op2);
12049 }
12050
12051 if (!gpc_reg_operand (op1, <MODE>mode))
12052 op1 = force_reg (<MODE>mode, op1);
12053 if (!reg_or_short_operand (op2, <MODE>mode))
12054 op2 = force_reg (<MODE>mode, op2);
12055
12056 rtx tmp = gen_reg_rtx (<MODE>mode);
12057 rtx tmp2 = gen_reg_rtx (<MODE>mode);
12058
12059 emit_insn (gen_subf<mode>3_carry (tmp, op1, op2));
12060 emit_insn (gen_subf<mode>3_carry_in_xx (tmp2));
12061
12062 if (cond_code == LEU)
12063 emit_insn (gen_add<mode>3 (op0, tmp2, const1_rtx));
12064 else
12065 emit_insn (gen_neg<mode>2 (op0, tmp2));
12066
12067 DONE;
12068 })
12069
12070 (define_expand "cstore_si_as_di"
12071 [(use (match_operator 1 "unsigned_comparison_operator"
12072 [(match_operand:SI 2 "gpc_reg_operand")
12073 (match_operand:SI 3 "reg_or_short_operand")]))
12074 (clobber (match_operand:SI 0 "gpc_reg_operand"))]
12075 ""
12076 {
12077 int uns_flag = unsigned_comparison_operator (operands[1], VOIDmode) ? 1 : 0;
12078 enum rtx_code cond_code = signed_condition (GET_CODE (operands[1]));
12079
12080 operands[2] = force_reg (SImode, operands[2]);
12081 operands[3] = force_reg (SImode, operands[3]);
12082 rtx op1 = gen_reg_rtx (DImode);
12083 rtx op2 = gen_reg_rtx (DImode);
12084 convert_move (op1, operands[2], uns_flag);
12085 convert_move (op2, operands[3], uns_flag);
12086
12087 if (cond_code == GT || cond_code == LE)
12088 {
12089 cond_code = swap_condition (cond_code);
12090 std::swap (op1, op2);
12091 }
12092
12093 rtx tmp = gen_reg_rtx (DImode);
12094 rtx tmp2 = gen_reg_rtx (DImode);
12095 emit_insn (gen_subdi3 (tmp, op1, op2));
12096 emit_insn (gen_lshrdi3 (tmp2, tmp, GEN_INT (63)));
12097
12098 rtx tmp3;
12099 switch (cond_code)
12100 {
12101 default:
12102 gcc_unreachable ();
12103 case LT:
12104 tmp3 = tmp2;
12105 break;
12106 case GE:
12107 tmp3 = gen_reg_rtx (DImode);
12108 emit_insn (gen_xordi3 (tmp3, tmp2, const1_rtx));
12109 break;
12110 }
12111
12112 convert_move (operands[0], tmp3, 1);
12113
12114 DONE;
12115 })
12116
12117 (define_expand "cstore<mode>4_signed_imm"
12118 [(use (match_operator 1 "signed_comparison_operator"
12119 [(match_operand:GPR 2 "gpc_reg_operand")
12120 (match_operand:GPR 3 "immediate_operand")]))
12121 (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
12122 ""
12123 {
12124 bool invert = false;
12125
12126 enum rtx_code cond_code = GET_CODE (operands[1]);
12127
12128 rtx op0 = operands[0];
12129 rtx op1 = operands[2];
12130 HOST_WIDE_INT val = INTVAL (operands[3]);
12131
12132 if (cond_code == GE || cond_code == GT)
12133 {
12134 cond_code = reverse_condition (cond_code);
12135 invert = true;
12136 }
12137
12138 if (cond_code == LE)
12139 val++;
12140
12141 rtx tmp = gen_reg_rtx (<MODE>mode);
12142 emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
12143 rtx x = gen_reg_rtx (<MODE>mode);
12144 if (val < 0)
12145 emit_insn (gen_and<mode>3 (x, op1, tmp));
12146 else
12147 emit_insn (gen_ior<mode>3 (x, op1, tmp));
12148
12149 if (invert)
12150 {
12151 rtx tmp = gen_reg_rtx (<MODE>mode);
12152 emit_insn (gen_one_cmpl<mode>2 (tmp, x));
12153 x = tmp;
12154 }
12155
12156 int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
12157 emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
12158
12159 DONE;
12160 })
12161
12162 (define_expand "cstore<mode>4_unsigned_imm"
12163 [(use (match_operator 1 "unsigned_comparison_operator"
12164 [(match_operand:GPR 2 "gpc_reg_operand")
12165 (match_operand:GPR 3 "immediate_operand")]))
12166 (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
12167 ""
12168 {
12169 bool invert = false;
12170
12171 enum rtx_code cond_code = GET_CODE (operands[1]);
12172
12173 rtx op0 = operands[0];
12174 rtx op1 = operands[2];
12175 HOST_WIDE_INT val = INTVAL (operands[3]);
12176
12177 if (cond_code == GEU || cond_code == GTU)
12178 {
12179 cond_code = reverse_condition (cond_code);
12180 invert = true;
12181 }
12182
12183 if (cond_code == LEU)
12184 val++;
12185
12186 rtx tmp = gen_reg_rtx (<MODE>mode);
12187 rtx tmp2 = gen_reg_rtx (<MODE>mode);
12188 emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
12189 emit_insn (gen_one_cmpl<mode>2 (tmp2, op1));
12190 rtx x = gen_reg_rtx (<MODE>mode);
12191 if (val < 0)
12192 emit_insn (gen_ior<mode>3 (x, tmp, tmp2));
12193 else
12194 emit_insn (gen_and<mode>3 (x, tmp, tmp2));
12195
12196 if (invert)
12197 {
12198 rtx tmp = gen_reg_rtx (<MODE>mode);
12199 emit_insn (gen_one_cmpl<mode>2 (tmp, x));
12200 x = tmp;
12201 }
12202
12203 int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
12204 emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
12205
12206 DONE;
12207 })
12208
12209 (define_expand "cstore<mode>4"
12210 [(use (match_operator 1 "comparison_operator"
12211 [(match_operand:GPR 2 "gpc_reg_operand")
12212 (match_operand:GPR 3 "reg_or_short_operand")]))
12213 (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
12214 ""
12215 {
12216 /* Everything is best done with setbc[r] if available. */
12217 if (TARGET_POWER10 && TARGET_ISEL)
12218 {
12219 rs6000_emit_int_cmove (operands[0], operands[1], const1_rtx, const0_rtx);
12220 DONE;
12221 }
12222
12223 /* Expanding EQ and NE directly to some machine instructions does not help
12224 but does hurt combine. So don't. */
12225 if (GET_CODE (operands[1]) == EQ)
12226 emit_insn (gen_eq<mode>3 (operands[0], operands[2], operands[3]));
12227 else if (<MODE>mode == Pmode
12228 && GET_CODE (operands[1]) == NE)
12229 emit_insn (gen_ne<mode>3 (operands[0], operands[2], operands[3]));
12230 else if (GET_CODE (operands[1]) == NE)
12231 {
12232 rtx tmp = gen_reg_rtx (<MODE>mode);
12233 emit_insn (gen_eq<mode>3 (tmp, operands[2], operands[3]));
12234 emit_insn (gen_xor<mode>3 (operands[0], tmp, const1_rtx));
12235 }
12236
12237 /* If ISEL is fast, expand to it. */
12238 else if (TARGET_ISEL)
12239 rs6000_emit_int_cmove (operands[0], operands[1], const1_rtx, const0_rtx);
12240
12241 /* Expanding the unsigned comparisons helps a lot: all the neg_ltu
12242 etc. combinations magically work out just right. */
12243 else if (<MODE>mode == Pmode
12244 && unsigned_comparison_operator (operands[1], VOIDmode))
12245 emit_insn (gen_cstore<mode>4_unsigned (operands[0], operands[1],
12246 operands[2], operands[3]));
12247
12248 /* For comparisons smaller than Pmode we can cheaply do things in Pmode. */
12249 else if (<MODE>mode == SImode && Pmode == DImode)
12250 emit_insn (gen_cstore_si_as_di (operands[0], operands[1],
12251 operands[2], operands[3]));
12252
12253 /* For signed comparisons against a constant, we can do some simple
12254 bit-twiddling. */
12255 else if (signed_comparison_operator (operands[1], VOIDmode)
12256 && CONST_INT_P (operands[3]))
12257 emit_insn (gen_cstore<mode>4_signed_imm (operands[0], operands[1],
12258 operands[2], operands[3]));
12259
12260 /* And similarly for unsigned comparisons. */
12261 else if (unsigned_comparison_operator (operands[1], VOIDmode)
12262 && CONST_INT_P (operands[3]))
12263 emit_insn (gen_cstore<mode>4_unsigned_imm (operands[0], operands[1],
12264 operands[2], operands[3]));
12265
12266 /* We also do not want to use mfcr for signed comparisons. */
12267 else if (<MODE>mode == Pmode
12268 && signed_comparison_operator (operands[1], VOIDmode))
12269 emit_insn (gen_cstore<mode>4_signed (operands[0], operands[1],
12270 operands[2], operands[3]));
12271
12272 /* Everything else, use the mfcr brute force. */
12273 else
12274 rs6000_emit_sCOND (<MODE>mode, operands);
12275
12276 DONE;
12277 })
12278
12279 (define_expand "cstore<mode>4"
12280 [(use (match_operator 1 "comparison_operator"
12281 [(match_operand:FP 2 "gpc_reg_operand")
12282 (match_operand:FP 3 "gpc_reg_operand")]))
12283 (clobber (match_operand:SI 0 "gpc_reg_operand"))]
12284 ""
12285 {
12286 rs6000_emit_sCOND (<MODE>mode, operands);
12287 DONE;
12288 })
12289
12290
12291 (define_expand "stack_protect_set"
12292 [(match_operand 0 "memory_operand")
12293 (match_operand 1 "memory_operand")]
12294 ""
12295 {
12296 if (rs6000_stack_protector_guard == SSP_TLS)
12297 {
12298 rtx reg = gen_rtx_REG (Pmode, rs6000_stack_protector_guard_reg);
12299 rtx offset = GEN_INT (rs6000_stack_protector_guard_offset);
12300 rtx addr = gen_rtx_PLUS (Pmode, reg, offset);
12301 operands[1] = gen_rtx_MEM (Pmode, addr);
12302 }
12303
12304 if (TARGET_64BIT)
12305 emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
12306 else
12307 emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
12308
12309 DONE;
12310 })
12311
12312 (define_insn "stack_protect_setsi"
12313 [(set (match_operand:SI 0 "memory_operand" "=m")
12314 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
12315 (set (match_scratch:SI 2 "=&r") (const_int 0))]
12316 "TARGET_32BIT"
12317 "lwz%U1%X1 %2,%1\;stw%U0%X0 %2,%0\;li %2,0"
12318 [(set_attr "type" "three")
12319 (set_attr "length" "12")])
12320
12321 ;; We can't use the prefixed attribute here because there are two memory
12322 ;; instructions. We can't split the insn due to the fact that this operation
12323 ;; needs to be done in one piece.
12324 (define_insn "stack_protect_setdi"
12325 [(set (match_operand:DI 0 "memory_operand" "=Y")
12326 (unspec:DI [(match_operand:DI 1 "memory_operand" "Y")] UNSPEC_SP_SET))
12327 (set (match_scratch:DI 2 "=&r") (const_int 0))]
12328 "TARGET_64BIT"
12329 {
12330 if (prefixed_memory (operands[1], DImode))
12331 output_asm_insn ("pld %2,%1", operands);
12332 else
12333 output_asm_insn ("ld%U1%X1 %2,%1", operands);
12334
12335 if (prefixed_memory (operands[0], DImode))
12336 output_asm_insn ("pstd %2,%0", operands);
12337 else
12338 output_asm_insn ("std%U0%X0 %2,%0", operands);
12339
12340 return "li %2,0";
12341 }
12342 [(set_attr "type" "three")
12343
12344 ;; Back to back prefixed memory instructions take 20 bytes (8 bytes for each
12345 ;; prefixed instruction + 4 bytes for the possible NOP). Add in 4 bytes for
12346 ;; the LI 0 at the end.
12347 (set_attr "prefixed" "no")
12348 (set_attr "num_insns" "3")
12349 (set (attr "length")
12350 (cond [(and (match_operand 0 "prefixed_memory")
12351 (match_operand 1 "prefixed_memory"))
12352 (const_int 24)
12353
12354 (ior (match_operand 0 "prefixed_memory")
12355 (match_operand 1 "prefixed_memory"))
12356 (const_int 20)]
12357
12358 (const_int 12)))])
12359
12360 (define_expand "stack_protect_test"
12361 [(match_operand 0 "memory_operand")
12362 (match_operand 1 "memory_operand")
12363 (match_operand 2 "")]
12364 ""
12365 {
12366 rtx guard = operands[1];
12367
12368 if (rs6000_stack_protector_guard == SSP_TLS)
12369 {
12370 rtx reg = gen_rtx_REG (Pmode, rs6000_stack_protector_guard_reg);
12371 rtx offset = GEN_INT (rs6000_stack_protector_guard_offset);
12372 rtx addr = gen_rtx_PLUS (Pmode, reg, offset);
12373 guard = gen_rtx_MEM (Pmode, addr);
12374 }
12375
12376 operands[1] = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, guard), UNSPEC_SP_TEST);
12377 rtx test = gen_rtx_EQ (VOIDmode, operands[0], operands[1]);
12378 rtx jump = gen_cbranchsi4 (test, operands[0], operands[1], operands[2]);
12379 emit_jump_insn (jump);
12380
12381 DONE;
12382 })
12383
12384 (define_insn "stack_protect_testsi"
12385 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
12386 (unspec:CCEQ [(match_operand:SI 1 "memory_operand" "m,m")
12387 (match_operand:SI 2 "memory_operand" "m,m")]
12388 UNSPEC_SP_TEST))
12389 (set (match_scratch:SI 4 "=r,r") (const_int 0))
12390 (clobber (match_scratch:SI 3 "=&r,&r"))]
12391 "TARGET_32BIT"
12392 "@
12393 lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0
12394 lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;cmplw %0,%3,%4\;li %3,0\;li %4,0"
12395 [(set_attr "length" "16,20")])
12396
12397 ;; We can't use the prefixed attribute here because there are two memory
12398 ;; instructions. We can't split the insn due to the fact that this operation
12399 ;; needs to be done in one piece.
12400 (define_insn "stack_protect_testdi"
12401 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
12402 (unspec:CCEQ [(match_operand:DI 1 "memory_operand" "Y,Y")
12403 (match_operand:DI 2 "memory_operand" "Y,Y")]
12404 UNSPEC_SP_TEST))
12405 (set (match_scratch:DI 4 "=r,r") (const_int 0))
12406 (clobber (match_scratch:DI 3 "=&r,&r"))]
12407 "TARGET_64BIT"
12408 {
12409 if (prefixed_memory (operands[1], DImode))
12410 output_asm_insn ("pld %3,%1", operands);
12411 else
12412 output_asm_insn ("ld%U1%X1 %3,%1", operands);
12413
12414 if (prefixed_memory (operands[2], DImode))
12415 output_asm_insn ("pld %4,%2", operands);
12416 else
12417 output_asm_insn ("ld%U2%X2 %4,%2", operands);
12418
12419 if (which_alternative == 0)
12420 output_asm_insn ("xor. %3,%3,%4", operands);
12421 else
12422 output_asm_insn ("cmpld %0,%3,%4\;li %3,0", operands);
12423
12424 return "li %4,0";
12425 }
12426 ;; Back to back prefixed memory instructions take 20 bytes (8 bytes for each
12427 ;; prefixed instruction + 4 bytes for the possible NOP). Add in either 4 or
12428 ;; 8 bytes to do the test.
12429 [(set_attr "prefixed" "no")
12430 (set_attr "num_insns" "4,5")
12431 (set (attr "length")
12432 (cond [(and (match_operand 1 "prefixed_memory")
12433 (match_operand 2 "prefixed_memory"))
12434 (if_then_else (eq_attr "alternative" "0")
12435 (const_int 28)
12436 (const_int 32))
12437
12438 (ior (match_operand 1 "prefixed_memory")
12439 (match_operand 2 "prefixed_memory"))
12440 (if_then_else (eq_attr "alternative" "0")
12441 (const_int 20)
12442 (const_int 24))]
12443
12444 (if_then_else (eq_attr "alternative" "0")
12445 (const_int 16)
12446 (const_int 20))))])
12447
12448 \f
12449 ;; Here are the actual compare insns.
12450 (define_insn "*cmp<mode>_signed"
12451 [(set (match_operand:CC 0 "cc_reg_operand" "=y")
12452 (compare:CC (match_operand:GPR 1 "gpc_reg_operand" "r")
12453 (match_operand:GPR 2 "reg_or_short_operand" "rI")))]
12454 ""
12455 "cmp<wd>%I2 %0,%1,%2"
12456 [(set_attr "type" "cmp")])
12457
12458 (define_insn "*cmp<mode>_unsigned"
12459 [(set (match_operand:CCUNS 0 "cc_reg_operand" "=y")
12460 (compare:CCUNS (match_operand:GPR 1 "gpc_reg_operand" "r")
12461 (match_operand:GPR 2 "reg_or_u_short_operand" "rK")))]
12462 ""
12463 "cmpl<wd>%I2 %0,%1,%2"
12464 [(set_attr "type" "cmp")])
12465
12466 ;; If we are comparing a register for equality with a large constant,
12467 ;; we can do this with an XOR followed by a compare. But this is profitable
12468 ;; only if the large constant is only used for the comparison (and in this
12469 ;; case we already have a register to reuse as scratch).
12470 ;;
12471 ;; For 64-bit registers, we could only do so if the constant's bit 15 is clear:
12472 ;; otherwise we'd need to XOR with FFFFFFFF????0000 which is not available.
12473
12474 (define_peephole2
12475 [(set (match_operand:SI 0 "register_operand")
12476 (match_operand:SI 1 "logical_const_operand"))
12477 (set (match_dup 0) (match_operator:SI 3 "boolean_or_operator"
12478 [(match_dup 0)
12479 (match_operand:SI 2 "logical_const_operand")]))
12480 (set (match_operand:CC 4 "cc_reg_operand")
12481 (compare:CC (match_operand:SI 5 "gpc_reg_operand")
12482 (match_dup 0)))
12483 (set (pc)
12484 (if_then_else (match_operator 6 "equality_operator"
12485 [(match_dup 4) (const_int 0)])
12486 (match_operand 7 "")
12487 (match_operand 8 "")))]
12488 "peep2_reg_dead_p (3, operands[0])
12489 && peep2_reg_dead_p (4, operands[4])
12490 && REGNO (operands[0]) != REGNO (operands[5])"
12491 [(set (match_dup 0) (xor:SI (match_dup 5) (match_dup 9)))
12492 (set (match_dup 4) (compare:CC (match_dup 0) (match_dup 10)))
12493 (set (pc) (if_then_else (match_dup 6) (match_dup 7) (match_dup 8)))]
12494
12495 {
12496 /* Get the constant we are comparing against, and see what it looks like
12497 when sign-extended from 16 to 32 bits. Then see what constant we could
12498 XOR with SEXTC to get the sign-extended value. */
12499 rtx cnst = simplify_const_binary_operation (GET_CODE (operands[3]),
12500 SImode,
12501 operands[1], operands[2]);
12502 HOST_WIDE_INT c = INTVAL (cnst);
12503 HOST_WIDE_INT sextc = sext_hwi (c, 16);
12504 HOST_WIDE_INT xorv = c ^ sextc;
12505
12506 operands[9] = GEN_INT (xorv);
12507 operands[10] = GEN_INT (sextc);
12508 })
12509
12510 ;; Only need to compare second words if first words equal
12511 (define_insn "*cmp<mode>_internal1"
12512 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
12513 (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
12514 (match_operand:IBM128 2 "gpc_reg_operand" "d")))]
12515 "!TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode)
12516 && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
12517 "fcmpu %0,%1,%2\;bne %0,$+8\;fcmpu %0,%L1,%L2"
12518 [(set_attr "type" "fpcompare")
12519 (set_attr "length" "12")])
12520
12521 (define_insn_and_split "*cmp<IBM128:mode>_internal2"
12522 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
12523 (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
12524 (match_operand:IBM128 2 "gpc_reg_operand" "d")))
12525 (clobber (match_scratch:DF 3 "=d"))
12526 (clobber (match_scratch:DF 4 "=d"))
12527 (clobber (match_scratch:DF 5 "=d"))
12528 (clobber (match_scratch:DF 6 "=d"))
12529 (clobber (match_scratch:DF 7 "=d"))
12530 (clobber (match_scratch:DF 8 "=d"))
12531 (clobber (match_scratch:DF 9 "=d"))
12532 (clobber (match_scratch:DF 10 "=d"))
12533 (clobber (match_scratch:GPR 11 "=b"))]
12534 "TARGET_XL_COMPAT && FLOAT128_IBM_P (<IBM128:MODE>mode)
12535 && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
12536 "#"
12537 "&& reload_completed"
12538 [(set (match_dup 3) (match_dup 14))
12539 (set (match_dup 4) (match_dup 15))
12540 (set (match_dup 9) (abs:DF (match_dup 5)))
12541 (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 3)))
12542 (set (pc) (if_then_else (ne (match_dup 0) (const_int 0))
12543 (label_ref (match_dup 12))
12544 (pc)))
12545 (set (match_dup 0) (compare:CCFP (match_dup 5) (match_dup 7)))
12546 (set (pc) (label_ref (match_dup 13)))
12547 (match_dup 12)
12548 (set (match_dup 10) (minus:DF (match_dup 5) (match_dup 7)))
12549 (set (match_dup 9) (minus:DF (match_dup 6) (match_dup 8)))
12550 (set (match_dup 9) (plus:DF (match_dup 10) (match_dup 9)))
12551 (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 4)))
12552 (match_dup 13)]
12553 {
12554 REAL_VALUE_TYPE rv;
12555 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
12556 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
12557
12558 operands[5] = simplify_gen_subreg (DFmode, operands[1],
12559 <IBM128:MODE>mode, hi_word);
12560 operands[6] = simplify_gen_subreg (DFmode, operands[1],
12561 <IBM128:MODE>mode, lo_word);
12562 operands[7] = simplify_gen_subreg (DFmode, operands[2],
12563 <IBM128:MODE>mode, hi_word);
12564 operands[8] = simplify_gen_subreg (DFmode, operands[2],
12565 <IBM128:MODE>mode, lo_word);
12566 operands[12] = gen_label_rtx ();
12567 operands[13] = gen_label_rtx ();
12568 real_inf (&rv);
12569 operands[14] = force_const_mem (DFmode,
12570 const_double_from_real_value (rv, DFmode));
12571 operands[15] = force_const_mem (DFmode,
12572 const_double_from_real_value (dconst0,
12573 DFmode));
12574 if (TARGET_TOC)
12575 {
12576 rtx tocref;
12577 tocref = create_TOC_reference (XEXP (operands[14], 0), operands[11]);
12578 operands[14] = gen_const_mem (DFmode, tocref);
12579 tocref = create_TOC_reference (XEXP (operands[15], 0), operands[11]);
12580 operands[15] = gen_const_mem (DFmode, tocref);
12581 set_mem_alias_set (operands[14], get_TOC_alias_set ());
12582 set_mem_alias_set (operands[15], get_TOC_alias_set ());
12583 }
12584 })
12585 \f
12586 ;; Now we have the scc insns. We can do some combinations because of the
12587 ;; way the machine works.
12588 ;;
12589 ;; Note that this is probably faster if we can put an insn between the
12590 ;; mfcr and rlinm, but this is tricky. Let's leave it for now. In most
12591 ;; cases the insns below which don't use an intermediate CR field will
12592 ;; be used instead.
12593 (define_insn "set<mode>_cc"
12594 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
12595 (match_operator:GPR 1 "scc_comparison_operator"
12596 [(match_operand 2 "cc_reg_operand" "y")
12597 (const_int 0)]))]
12598 ""
12599 "mfcr %0%Q2\;rlwinm %0,%0,%J1,1"
12600 [(set (attr "type")
12601 (cond [(match_test "TARGET_MFCRF")
12602 (const_string "mfcrf")
12603 ]
12604 (const_string "mfcr")))
12605 (set_attr "length" "8")])
12606
12607
12608 (define_code_iterator cmp [eq ne lt ltu gt gtu le leu ge geu])
12609 (define_code_attr UNS [(eq "CC")
12610 (ne "CC")
12611 (lt "CC") (ltu "CCUNS")
12612 (gt "CC") (gtu "CCUNS")
12613 (le "CC") (leu "CCUNS")
12614 (ge "CC") (geu "CCUNS")])
12615 (define_code_attr UNSu_ [(eq "")
12616 (ne "")
12617 (lt "") (ltu "u_")
12618 (gt "") (gtu "u_")
12619 (le "") (leu "u_")
12620 (ge "") (geu "u_")])
12621 (define_code_attr UNSIK [(eq "I")
12622 (ne "I")
12623 (lt "I") (ltu "K")
12624 (gt "I") (gtu "K")
12625 (le "I") (leu "K")
12626 (ge "I") (geu "K")])
12627
12628 (define_insn_and_split "<code><GPR:mode><GPR2:mode>2_isel"
12629 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
12630 (cmp:GPR (match_operand:GPR2 1 "gpc_reg_operand" "r")
12631 (match_operand:GPR2 2 "reg_or_<cmp:UNSu_>short_operand" "r<cmp:UNSIK>")))
12632 (clobber (match_scratch:GPR 3 "=r"))
12633 (clobber (match_scratch:GPR 4 "=r"))
12634 (clobber (match_scratch:<UNS> 5 "=y"))]
12635 "!TARGET_POWER10 && TARGET_ISEL
12636 && !(<CODE> == EQ && operands[2] == const0_rtx)
12637 && !(<CODE> == NE && operands[2] == const0_rtx
12638 && <GPR:MODE>mode == Pmode && <GPR2:MODE>mode == Pmode)"
12639 "#"
12640 "&& 1"
12641 [(pc)]
12642 {
12643 rtx_code code = <CODE>;
12644 if (CONST_INT_P (operands[2]) && code != EQ && code != NE)
12645 {
12646 HOST_WIDE_INT val = INTVAL (operands[2]);
12647 if (code == LT && val != -0x8000)
12648 {
12649 code = LE;
12650 val--;
12651 }
12652 if (code == GT && val != 0x7fff)
12653 {
12654 code = GE;
12655 val++;
12656 }
12657 if (code == LTU && val != 0)
12658 {
12659 code = LEU;
12660 val--;
12661 }
12662 if (code == GTU && val != 0xffff)
12663 {
12664 code = GEU;
12665 val++;
12666 }
12667 operands[2] = GEN_INT (val);
12668 }
12669
12670 if (code == NE || code == LE || code == GE || code == LEU || code == GEU)
12671 operands[3] = const0_rtx;
12672 else
12673 {
12674 if (GET_CODE (operands[3]) == SCRATCH)
12675 operands[3] = gen_reg_rtx (<GPR:MODE>mode);
12676 emit_move_insn (operands[3], const0_rtx);
12677 }
12678
12679 if (GET_CODE (operands[4]) == SCRATCH)
12680 operands[4] = gen_reg_rtx (<GPR:MODE>mode);
12681 emit_move_insn (operands[4], const1_rtx);
12682
12683 if (GET_CODE (operands[5]) == SCRATCH)
12684 operands[5] = gen_reg_rtx (<UNS>mode);
12685
12686 rtx c1 = gen_rtx_COMPARE (<UNS>mode, operands[1], operands[2]);
12687 emit_insn (gen_rtx_SET (operands[5], c1));
12688
12689 rtx c2 = gen_rtx_fmt_ee (code, <GPR:MODE>mode, operands[5], const0_rtx);
12690 rtx x = gen_rtx_IF_THEN_ELSE (<GPR:MODE>mode, c2, operands[4], operands[3]);
12691 emit_move_insn (operands[0], x);
12692
12693 DONE;
12694 }
12695 [(set (attr "cost")
12696 (if_then_else (match_test "(CONST_INT_P (operands[2]) && <CODE> != EQ)
12697 || <CODE> == NE
12698 || <CODE> == LE || <CODE> == GE
12699 || <CODE> == LEU || <CODE> == GEU")
12700 (const_string "9")
12701 (const_string "10")))])
12702
12703 (define_mode_attr scc_eq_op2 [(SI "rKLI")
12704 (DI "rKJI")])
12705
12706 (define_expand "eq<mode>3"
12707 [(parallel [
12708 (set (match_operand:GPR 0 "gpc_reg_operand" "=r")
12709 (eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
12710 (match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>")))
12711 (clobber (match_scratch:GPR 3 "=r"))
12712 (clobber (match_scratch:GPR 4 "=r"))])]
12713 ""
12714 {
12715 if (TARGET_POWER10)
12716 {
12717 rtx cc = gen_reg_rtx (CCmode);
12718 rtx compare = gen_rtx_COMPARE (CCmode, operands[1], operands[2]);
12719 emit_insn (gen_rtx_SET (cc, compare));
12720 rtx eq = gen_rtx_fmt_ee (EQ, <MODE>mode, cc, const0_rtx);
12721 emit_insn (gen_setbc_cc_<mode> (operands[0], eq, cc));
12722 DONE;
12723 }
12724
12725 if (TARGET_ISEL && operands[2] != const0_rtx)
12726 {
12727 emit_insn (gen_eq<mode><mode>2_isel (operands[0], operands[1],
12728 operands[2]));
12729 DONE;
12730 }
12731 })
12732
12733 (define_insn_and_split "*eq<mode>3"
12734 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
12735 (eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
12736 (match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>")))
12737 (clobber (match_scratch:GPR 3 "=r"))
12738 (clobber (match_scratch:GPR 4 "=r"))]
12739 "!TARGET_POWER10 && !(TARGET_ISEL && operands[2] != const0_rtx)"
12740 "#"
12741 "&& 1"
12742 [(set (match_dup 4)
12743 (clz:GPR (match_dup 3)))
12744 (set (match_dup 0)
12745 (lshiftrt:GPR (match_dup 4)
12746 (match_dup 5)))]
12747 {
12748 operands[3] = rs6000_emit_eqne (<MODE>mode,
12749 operands[1], operands[2], operands[3]);
12750
12751 if (GET_CODE (operands[4]) == SCRATCH)
12752 operands[4] = gen_reg_rtx (<MODE>mode);
12753
12754 operands[5] = GEN_INT (exact_log2 (GET_MODE_BITSIZE (<MODE>mode)));
12755 }
12756 [(set (attr "length")
12757 (if_then_else (match_test "operands[2] == const0_rtx")
12758 (const_string "8")
12759 (const_string "12")))])
12760
12761 (define_expand "ne<mode>3"
12762 [(parallel [
12763 (set (match_operand:GPR 0 "gpc_reg_operand" "=r")
12764 (ne:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
12765 (match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>")))
12766 (clobber (match_scratch:GPR 3 "=r"))
12767 (clobber (match_scratch:GPR 4 "=r"))
12768 (clobber (reg:GPR CA_REGNO))])]
12769 ""
12770 {
12771 if (TARGET_POWER10)
12772 {
12773 rtx cc = gen_reg_rtx (CCmode);
12774 rtx compare = gen_rtx_COMPARE (CCmode, operands[1], operands[2]);
12775 emit_insn (gen_rtx_SET (cc, compare));
12776 rtx ne = gen_rtx_fmt_ee (NE, <MODE>mode, cc, const0_rtx);
12777 emit_insn (gen_setbc_cc_<mode> (operands[0], ne, cc));
12778 DONE;
12779 }
12780
12781 if (<MODE>mode != Pmode)
12782 {
12783 rtx x = gen_reg_rtx (<MODE>mode);
12784 emit_insn (gen_eq<mode>3 (x, operands[1], operands[2]));
12785 emit_insn (gen_xor<mode>3 (operands[0], x, const1_rtx));
12786 DONE;
12787 }
12788
12789 if (TARGET_ISEL && operands[2] != const0_rtx)
12790 {
12791 emit_insn (gen_ne<mode><mode>2_isel (operands[0], operands[1],
12792 operands[2]));
12793 DONE;
12794 }
12795 })
12796
12797 (define_insn_and_split "*ne<mode>3"
12798 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12799 (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12800 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")))
12801 (clobber (match_scratch:P 3 "=r"))
12802 (clobber (match_scratch:P 4 "=r"))
12803 (clobber (reg:P CA_REGNO))]
12804 "!TARGET_POWER10 && !(TARGET_ISEL && operands[2] != const0_rtx)"
12805 "#"
12806 "&& 1"
12807 [(parallel [(set (match_dup 4)
12808 (plus:P (match_dup 3)
12809 (const_int -1)))
12810 (set (reg:P CA_REGNO)
12811 (ne:P (match_dup 3)
12812 (const_int 0)))])
12813 (parallel [(set (match_dup 0)
12814 (plus:P (plus:P (not:P (match_dup 4))
12815 (reg:P CA_REGNO))
12816 (match_dup 3)))
12817 (clobber (reg:P CA_REGNO))])]
12818 {
12819 operands[3] = rs6000_emit_eqne (<MODE>mode,
12820 operands[1], operands[2], operands[3]);
12821
12822 if (GET_CODE (operands[4]) == SCRATCH)
12823 operands[4] = gen_reg_rtx (<MODE>mode);
12824 }
12825 [(set (attr "length")
12826 (if_then_else (match_test "operands[2] == const0_rtx")
12827 (const_string "8")
12828 (const_string "12")))])
12829
12830 (define_insn_and_split "*neg_eq_<mode>"
12831 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12832 (neg:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12833 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12834 (clobber (match_scratch:P 3 "=r"))
12835 (clobber (match_scratch:P 4 "=r"))
12836 (clobber (reg:P CA_REGNO))]
12837 "!TARGET_POWER10"
12838 "#"
12839 "&& 1"
12840 [(parallel [(set (match_dup 4)
12841 (plus:P (match_dup 3)
12842 (const_int -1)))
12843 (set (reg:P CA_REGNO)
12844 (ne:P (match_dup 3)
12845 (const_int 0)))])
12846 (parallel [(set (match_dup 0)
12847 (plus:P (reg:P CA_REGNO)
12848 (const_int -1)))
12849 (clobber (reg:P CA_REGNO))])]
12850 {
12851 operands[3] = rs6000_emit_eqne (<MODE>mode,
12852 operands[1], operands[2], operands[3]);
12853
12854 if (GET_CODE (operands[4]) == SCRATCH)
12855 operands[4] = gen_reg_rtx (<MODE>mode);
12856 }
12857 [(set (attr "length")
12858 (if_then_else (match_test "operands[2] == const0_rtx")
12859 (const_string "8")
12860 (const_string "12")))])
12861
12862 (define_insn_and_split "*neg_ne_<mode>"
12863 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12864 (neg:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12865 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12866 (clobber (match_scratch:P 3 "=r"))
12867 (clobber (match_scratch:P 4 "=r"))
12868 (clobber (reg:P CA_REGNO))]
12869 "!TARGET_POWER10"
12870 "#"
12871 "&& 1"
12872 [(parallel [(set (match_dup 4)
12873 (neg:P (match_dup 3)))
12874 (set (reg:P CA_REGNO)
12875 (eq:P (match_dup 3)
12876 (const_int 0)))])
12877 (parallel [(set (match_dup 0)
12878 (plus:P (reg:P CA_REGNO)
12879 (const_int -1)))
12880 (clobber (reg:P CA_REGNO))])]
12881 {
12882 operands[3] = rs6000_emit_eqne (<MODE>mode,
12883 operands[1], operands[2], operands[3]);
12884
12885 if (GET_CODE (operands[4]) == SCRATCH)
12886 operands[4] = gen_reg_rtx (<MODE>mode);
12887 }
12888 [(set (attr "length")
12889 (if_then_else (match_test "operands[2] == const0_rtx")
12890 (const_string "8")
12891 (const_string "12")))])
12892
12893 (define_insn_and_split "*plus_eq_<mode>"
12894 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12895 (plus:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12896 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
12897 (match_operand:P 3 "gpc_reg_operand" "r")))
12898 (clobber (match_scratch:P 4 "=r"))
12899 (clobber (match_scratch:P 5 "=r"))
12900 (clobber (reg:P CA_REGNO))]
12901 ""
12902 "#"
12903 ""
12904 [(parallel [(set (match_dup 5)
12905 (neg:P (match_dup 4)))
12906 (set (reg:P CA_REGNO)
12907 (eq:P (match_dup 4)
12908 (const_int 0)))])
12909 (parallel [(set (match_dup 0)
12910 (plus:P (match_dup 3)
12911 (reg:P CA_REGNO)))
12912 (clobber (reg:P CA_REGNO))])]
12913 {
12914 operands[4] = rs6000_emit_eqne (<MODE>mode,
12915 operands[1], operands[2], operands[4]);
12916
12917 if (GET_CODE (operands[5]) == SCRATCH)
12918 operands[5] = gen_reg_rtx (<MODE>mode);
12919 }
12920 [(set (attr "length")
12921 (if_then_else (match_test "operands[2] == const0_rtx")
12922 (const_string "8")
12923 (const_string "12")))])
12924
12925 (define_insn_and_split "*plus_ne_<mode>"
12926 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12927 (plus:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12928 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
12929 (match_operand:P 3 "gpc_reg_operand" "r")))
12930 (clobber (match_scratch:P 4 "=r"))
12931 (clobber (match_scratch:P 5 "=r"))
12932 (clobber (reg:P CA_REGNO))]
12933 ""
12934 "#"
12935 ""
12936 [(parallel [(set (match_dup 5)
12937 (plus:P (match_dup 4)
12938 (const_int -1)))
12939 (set (reg:P CA_REGNO)
12940 (ne:P (match_dup 4)
12941 (const_int 0)))])
12942 (parallel [(set (match_dup 0)
12943 (plus:P (match_dup 3)
12944 (reg:P CA_REGNO)))
12945 (clobber (reg:P CA_REGNO))])]
12946 {
12947 operands[4] = rs6000_emit_eqne (<MODE>mode,
12948 operands[1], operands[2], operands[4]);
12949
12950 if (GET_CODE (operands[5]) == SCRATCH)
12951 operands[5] = gen_reg_rtx (<MODE>mode);
12952 }
12953 [(set (attr "length")
12954 (if_then_else (match_test "operands[2] == const0_rtx")
12955 (const_string "8")
12956 (const_string "12")))])
12957
12958 (define_insn_and_split "*minus_eq_<mode>"
12959 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12960 (minus:P (match_operand:P 3 "gpc_reg_operand" "r")
12961 (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12962 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12963 (clobber (match_scratch:P 4 "=r"))
12964 (clobber (match_scratch:P 5 "=r"))
12965 (clobber (reg:P CA_REGNO))]
12966 ""
12967 "#"
12968 ""
12969 [(parallel [(set (match_dup 5)
12970 (plus:P (match_dup 4)
12971 (const_int -1)))
12972 (set (reg:P CA_REGNO)
12973 (ne:P (match_dup 4)
12974 (const_int 0)))])
12975 (parallel [(set (match_dup 0)
12976 (plus:P (plus:P (match_dup 3)
12977 (reg:P CA_REGNO))
12978 (const_int -1)))
12979 (clobber (reg:P CA_REGNO))])]
12980 {
12981 operands[4] = rs6000_emit_eqne (<MODE>mode,
12982 operands[1], operands[2], operands[4]);
12983
12984 if (GET_CODE (operands[5]) == SCRATCH)
12985 operands[5] = gen_reg_rtx (<MODE>mode);
12986 }
12987 [(set (attr "length")
12988 (if_then_else (match_test "operands[2] == const0_rtx")
12989 (const_string "8")
12990 (const_string "12")))])
12991
12992 (define_insn_and_split "*minus_ne_<mode>"
12993 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12994 (minus:P (match_operand:P 3 "gpc_reg_operand" "r")
12995 (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12996 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12997 (clobber (match_scratch:P 4 "=r"))
12998 (clobber (match_scratch:P 5 "=r"))
12999 (clobber (reg:P CA_REGNO))]
13000 ""
13001 "#"
13002 ""
13003 [(parallel [(set (match_dup 5)
13004 (neg:P (match_dup 4)))
13005 (set (reg:P CA_REGNO)
13006 (eq:P (match_dup 4)
13007 (const_int 0)))])
13008 (parallel [(set (match_dup 0)
13009 (plus:P (plus:P (match_dup 3)
13010 (reg:P CA_REGNO))
13011 (const_int -1)))
13012 (clobber (reg:P CA_REGNO))])]
13013 {
13014 operands[4] = rs6000_emit_eqne (<MODE>mode,
13015 operands[1], operands[2], operands[4]);
13016
13017 if (GET_CODE (operands[5]) == SCRATCH)
13018 operands[5] = gen_reg_rtx (<MODE>mode);
13019 }
13020 [(set (attr "length")
13021 (if_then_else (match_test "operands[2] == const0_rtx")
13022 (const_string "8")
13023 (const_string "12")))])
13024
13025 (define_insn_and_split "*eqsi3_ext<mode>"
13026 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
13027 (eq:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
13028 (match_operand:SI 2 "scc_eq_operand" "rKLI")))
13029 (clobber (match_scratch:SI 3 "=r"))
13030 (clobber (match_scratch:SI 4 "=r"))]
13031 "!TARGET_POWER10"
13032 "#"
13033 "&& 1"
13034 [(set (match_dup 4)
13035 (clz:SI (match_dup 3)))
13036 (set (match_dup 0)
13037 (zero_extend:EXTSI
13038 (lshiftrt:SI (match_dup 4)
13039 (const_int 5))))]
13040 {
13041 operands[3] = rs6000_emit_eqne (SImode,
13042 operands[1], operands[2], operands[3]);
13043
13044 if (GET_CODE (operands[4]) == SCRATCH)
13045 operands[4] = gen_reg_rtx (SImode);
13046 }
13047 [(set (attr "length")
13048 (if_then_else (match_test "operands[2] == const0_rtx")
13049 (const_string "8")
13050 (const_string "12")))])
13051
13052 (define_insn_and_split "*nesi3_ext<mode>"
13053 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
13054 (ne:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
13055 (match_operand:SI 2 "scc_eq_operand" "rKLI")))
13056 (clobber (match_scratch:SI 3 "=r"))
13057 (clobber (match_scratch:SI 4 "=r"))
13058 (clobber (match_scratch:EXTSI 5 "=r"))]
13059 "!TARGET_ISEL"
13060 "#"
13061 "&& 1"
13062 [(set (match_dup 4)
13063 (clz:SI (match_dup 3)))
13064 (set (match_dup 5)
13065 (zero_extend:EXTSI
13066 (lshiftrt:SI (match_dup 4)
13067 (const_int 5))))
13068 (set (match_dup 0)
13069 (xor:EXTSI (match_dup 5)
13070 (const_int 1)))]
13071 {
13072 operands[3] = rs6000_emit_eqne (SImode,
13073 operands[1], operands[2], operands[3]);
13074
13075 if (GET_CODE (operands[4]) == SCRATCH)
13076 operands[4] = gen_reg_rtx (SImode);
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 "12")
13083 (const_string "16")))])
13084
13085
13086 (define_code_iterator fp_rev [ordered ne unle unge])
13087 (define_code_iterator fp_two [ltgt le ge unlt ungt uneq])
13088
13089 (define_insn_and_split "*<code><mode>_cc"
13090 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
13091 (fp_rev:GPR (match_operand:CCFP 1 "cc_reg_operand" "y")
13092 (const_int 0)))]
13093 "!flag_finite_math_only"
13094 "#"
13095 "&& 1"
13096 [(pc)]
13097 {
13098 rtx_code revcode = reverse_condition_maybe_unordered (<CODE>);
13099 rtx eq = gen_rtx_fmt_ee (revcode, <MODE>mode, operands[1], const0_rtx);
13100 rtx tmp = gen_reg_rtx (<MODE>mode);
13101 emit_move_insn (tmp, eq);
13102 emit_insn (gen_xor<mode>3 (operands[0], tmp, const1_rtx));
13103 DONE;
13104 }
13105 [(set_attr "length" "12")])
13106
13107 (define_insn_and_split "*<code><mode>_cc"
13108 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
13109 (fp_two:GPR (match_operand:CCFP 1 "cc_reg_operand" "y")
13110 (const_int 0)))]
13111 "!flag_finite_math_only"
13112 "#"
13113 "&& 1"
13114 [(pc)]
13115 {
13116 rtx cc = rs6000_emit_fp_cror (<CODE>, <MODE>mode, operands[1]);
13117
13118 emit_move_insn (operands[0], gen_rtx_EQ (<MODE>mode, cc, const0_rtx));
13119 DONE;
13120 }
13121 [(set_attr "length" "12")])
13122 \f
13123 ;; Conditional branches.
13124 ;; These either are a single bc insn, or a bc around a b.
13125
13126 (define_insn "*cbranch"
13127 [(set (pc)
13128 (if_then_else (match_operator 1 "branch_comparison_operator"
13129 [(match_operand 2 "cc_reg_operand" "y")
13130 (const_int 0)])
13131 (label_ref (match_operand 0))
13132 (pc)))]
13133 ""
13134 {
13135 return output_cbranch (operands[1], "%l0", 0, insn);
13136 }
13137 [(set_attr "type" "branch")
13138 (set (attr "length")
13139 (if_then_else (and (ge (minus (match_dup 0) (pc))
13140 (const_int -32768))
13141 (lt (minus (match_dup 0) (pc))
13142 (const_int 32764)))
13143 (const_int 4)
13144 (const_int 8)))])
13145
13146 (define_insn_and_split "*cbranch_2insn"
13147 [(set (pc)
13148 (if_then_else (match_operator 1 "extra_insn_branch_comparison_operator"
13149 [(match_operand 2 "cc_reg_operand" "y")
13150 (const_int 0)])
13151 (label_ref (match_operand 0))
13152 (pc)))]
13153 "!flag_finite_math_only"
13154 "#"
13155 "&& 1"
13156 [(pc)]
13157 {
13158 rtx cc = rs6000_emit_fp_cror (GET_CODE (operands[1]), SImode, operands[2]);
13159
13160 rtx note = find_reg_note (curr_insn, REG_BR_PROB, 0);
13161
13162 rtx loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands[0]);
13163 rtx cond = gen_rtx_EQ (CCEQmode, cc, const0_rtx);
13164 rtx ite = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, loc_ref, pc_rtx);
13165 emit_jump_insn (gen_rtx_SET (pc_rtx, ite));
13166
13167 if (note)
13168 {
13169 profile_probability prob
13170 = profile_probability::from_reg_br_prob_note (XINT (note, 0));
13171
13172 add_reg_br_prob_note (get_last_insn (), prob);
13173 }
13174
13175 DONE;
13176 }
13177 [(set_attr "type" "branch")
13178 (set (attr "length")
13179 (if_then_else (and (ge (minus (match_dup 0) (pc))
13180 (const_int -32764))
13181 (lt (minus (match_dup 0) (pc))
13182 (const_int 32760)))
13183 (const_int 8)
13184 (const_int 16)))])
13185
13186 ;; Conditional return.
13187 (define_insn "*creturn"
13188 [(set (pc)
13189 (if_then_else (match_operator 0 "branch_comparison_operator"
13190 [(match_operand 1 "cc_reg_operand" "y")
13191 (const_int 0)])
13192 (any_return)
13193 (pc)))]
13194 "<return_pred>"
13195 {
13196 return output_cbranch (operands[0], NULL, 0, insn);
13197 }
13198 [(set_attr "type" "jmpreg")])
13199
13200 ;; Logic on condition register values.
13201
13202 ; This pattern matches things like
13203 ; (set (reg:CCEQ 68) (compare:CCEQ (ior:SI (gt:SI (reg:CCFP 68) (const_int 0))
13204 ; (eq:SI (reg:CCFP 68) (const_int 0)))
13205 ; (const_int 1)))
13206 ; which are generated by the branch logic.
13207 ; Prefer destructive operations where BT = BB (for crXX BT,BA,BB)
13208
13209 (define_insn "@cceq_ior_compare_<mode>"
13210 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
13211 (compare:CCEQ (match_operator:GPR 1 "boolean_operator"
13212 [(match_operator:GPR 2
13213 "branch_positive_comparison_operator"
13214 [(match_operand 3
13215 "cc_reg_operand" "y,y")
13216 (const_int 0)])
13217 (match_operator:GPR 4
13218 "branch_positive_comparison_operator"
13219 [(match_operand 5
13220 "cc_reg_operand" "0,y")
13221 (const_int 0)])])
13222 (const_int 1)))]
13223 ""
13224 "cr%q1 %E0,%j2,%j4"
13225 [(set_attr "type" "cr_logical")
13226 (set_attr "cr_logical_3op" "no,yes")])
13227
13228 ; Why is the constant -1 here, but 1 in the previous pattern?
13229 ; Because ~1 has all but the low bit set.
13230 (define_insn "cceq_ior_compare_complement"
13231 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
13232 (compare:CCEQ (match_operator:SI 1 "boolean_operator"
13233 [(not:SI (match_operator:SI 2
13234 "branch_positive_comparison_operator"
13235 [(match_operand 3
13236 "cc_reg_operand" "y,y")
13237 (const_int 0)]))
13238 (match_operator:SI 4
13239 "branch_positive_comparison_operator"
13240 [(match_operand 5
13241 "cc_reg_operand" "0,y")
13242 (const_int 0)])])
13243 (const_int -1)))]
13244 ""
13245 "cr%q1 %E0,%j2,%j4"
13246 [(set_attr "type" "cr_logical")
13247 (set_attr "cr_logical_3op" "no,yes")])
13248
13249 (define_insn "@cceq_rev_compare_<mode>"
13250 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
13251 (compare:CCEQ (match_operator:GPR 1
13252 "branch_positive_comparison_operator"
13253 [(match_operand 2
13254 "cc_reg_operand" "0,y")
13255 (const_int 0)])
13256 (const_int 0)))]
13257 ""
13258 "crnot %E0,%j1"
13259 [(set_attr "type" "cr_logical")
13260 (set_attr "cr_logical_3op" "no,yes")])
13261
13262 ;; If we are comparing the result of two comparisons, this can be done
13263 ;; using creqv or crxor.
13264
13265 (define_insn_and_split ""
13266 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y")
13267 (compare:CCEQ (match_operator 1 "branch_comparison_operator"
13268 [(match_operand 2 "cc_reg_operand" "y")
13269 (const_int 0)])
13270 (match_operator 3 "branch_comparison_operator"
13271 [(match_operand 4 "cc_reg_operand" "y")
13272 (const_int 0)])))]
13273 ""
13274 "#"
13275 ""
13276 [(set (match_dup 0) (compare:CCEQ (xor:SI (match_dup 1) (match_dup 3))
13277 (match_dup 5)))]
13278 {
13279 int positive_1, positive_2;
13280
13281 positive_1 = branch_positive_comparison_operator (operands[1],
13282 GET_MODE (operands[1]));
13283 positive_2 = branch_positive_comparison_operator (operands[3],
13284 GET_MODE (operands[3]));
13285
13286 if (! positive_1)
13287 operands[1] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[2]),
13288 GET_CODE (operands[1])),
13289 SImode,
13290 operands[2], const0_rtx);
13291 else if (GET_MODE (operands[1]) != SImode)
13292 operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), SImode,
13293 operands[2], const0_rtx);
13294
13295 if (! positive_2)
13296 operands[3] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[4]),
13297 GET_CODE (operands[3])),
13298 SImode,
13299 operands[4], const0_rtx);
13300 else if (GET_MODE (operands[3]) != SImode)
13301 operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SImode,
13302 operands[4], const0_rtx);
13303
13304 if (positive_1 == positive_2)
13305 {
13306 operands[1] = gen_rtx_NOT (SImode, operands[1]);
13307 operands[5] = constm1_rtx;
13308 }
13309 else
13310 {
13311 operands[5] = const1_rtx;
13312 }
13313 })
13314
13315 ;; Unconditional branch and return.
13316
13317 (define_insn "jump"
13318 [(set (pc)
13319 (label_ref (match_operand 0)))]
13320 ""
13321 "b %l0"
13322 [(set_attr "type" "branch")])
13323
13324 (define_insn "<return_str>return"
13325 [(any_return)]
13326 "<return_pred>"
13327 "blr"
13328 [(set_attr "type" "jmpreg")])
13329
13330 (define_expand "indirect_jump"
13331 [(set (pc) (match_operand 0 "register_operand"))]
13332 ""
13333 {
13334 if (!rs6000_speculate_indirect_jumps) {
13335 rtx ccreg = gen_reg_rtx (CCmode);
13336 emit_jump_insn (gen_indirect_jump_nospec (Pmode, operands[0], ccreg));
13337 DONE;
13338 }
13339 })
13340
13341 (define_insn "*indirect_jump<mode>"
13342 [(set (pc)
13343 (match_operand:P 0 "register_operand" "c,*l"))]
13344 "rs6000_speculate_indirect_jumps"
13345 "b%T0"
13346 [(set_attr "type" "jmpreg")])
13347
13348 (define_insn "@indirect_jump<mode>_nospec"
13349 [(set (pc) (match_operand:P 0 "register_operand" "c,*l"))
13350 (clobber (match_operand:CC 1 "cc_reg_operand" "=y,y"))]
13351 "!rs6000_speculate_indirect_jumps"
13352 "crset %E1\;beq%T0- %1\;b $"
13353 [(set_attr "type" "jmpreg")
13354 (set_attr "length" "12")])
13355
13356 ;; Table jump for switch statements:
13357 (define_expand "tablejump"
13358 [(use (match_operand 0))
13359 (use (label_ref (match_operand 1)))]
13360 ""
13361 {
13362 if (rs6000_speculate_indirect_jumps)
13363 {
13364 if (rs6000_relative_jumptables)
13365 emit_jump_insn (gen_tablejump_normal (Pmode, operands[0], operands[1]));
13366 else
13367 emit_jump_insn (gen_tablejump_absolute (Pmode, operands[0],
13368 operands[1]));
13369 }
13370 else
13371 {
13372 rtx ccreg = gen_reg_rtx (CCmode);
13373 rtx jump;
13374 if (rs6000_relative_jumptables)
13375 jump = gen_tablejump_nospec (Pmode, operands[0], operands[1], ccreg);
13376 else
13377 jump = gen_tablejump_absolute_nospec (Pmode, operands[0], operands[1],
13378 ccreg);
13379 emit_jump_insn (jump);
13380 }
13381 DONE;
13382 })
13383
13384 (define_expand "@tablejump<mode>_normal"
13385 [(use (match_operand:SI 0))
13386 (use (match_operand:P 1))]
13387 "rs6000_speculate_indirect_jumps && rs6000_relative_jumptables"
13388 {
13389 rtx off = force_reg (SImode, operands[0]);
13390 if (<MODE>mode != SImode)
13391 {
13392 rtx src = gen_rtx_fmt_e (SIGN_EXTEND, Pmode, off);
13393 off = gen_reg_rtx (Pmode);
13394 emit_move_insn (off, src);
13395 }
13396
13397 rtx lab = force_reg (Pmode, gen_rtx_LABEL_REF (Pmode, operands[1]));
13398 rtx addr = gen_reg_rtx (Pmode);
13399
13400 emit_insn (gen_add<mode>3 (addr, off, lab));
13401 emit_jump_insn (gen_tablejump_insn_normal (Pmode, addr, operands[1]));
13402 DONE;
13403 })
13404
13405 (define_expand "@tablejump<mode>_absolute"
13406 [(use (match_operand:P 0))
13407 (use (match_operand:P 1))]
13408 "rs6000_speculate_indirect_jumps && !rs6000_relative_jumptables"
13409 {
13410 rtx addr = gen_reg_rtx (Pmode);
13411 emit_move_insn (addr, operands[0]);
13412
13413 emit_jump_insn (gen_tablejump_insn_normal (Pmode, addr, operands[1]));
13414 DONE;
13415 })
13416
13417 (define_expand "@tablejump<mode>_nospec"
13418 [(use (match_operand:SI 0))
13419 (use (match_operand:P 1))
13420 (use (match_operand:CC 2))]
13421 "!rs6000_speculate_indirect_jumps && rs6000_relative_jumptables"
13422 {
13423 rtx off = force_reg (SImode, operands[0]);
13424 if (<MODE>mode != SImode)
13425 {
13426 rtx src = gen_rtx_fmt_e (SIGN_EXTEND, Pmode, off);
13427 off = gen_reg_rtx (Pmode);
13428 emit_move_insn (off, src);
13429 }
13430
13431 rtx lab = force_reg (Pmode, gen_rtx_LABEL_REF (Pmode, operands[1]));
13432 rtx addr = gen_reg_rtx (Pmode);
13433
13434 emit_insn (gen_add<mode>3 (addr, off, lab));
13435 emit_jump_insn (gen_tablejump_insn_nospec (Pmode, addr, operands[1],
13436 operands[2]));
13437 DONE;
13438 })
13439
13440 (define_expand "@tablejump<mode>_absolute_nospec"
13441 [(use (match_operand:P 0))
13442 (use (match_operand:P 1))
13443 (use (match_operand:CC 2))]
13444 "!rs6000_speculate_indirect_jumps && !rs6000_relative_jumptables"
13445 {
13446 rtx addr = gen_reg_rtx (Pmode);
13447 emit_move_insn (addr, operands[0]);
13448
13449 emit_jump_insn (gen_tablejump_insn_nospec (Pmode, addr, operands[1],
13450 operands[2]));
13451 DONE;
13452 })
13453
13454 (define_insn "@tablejump<mode>_insn_normal"
13455 [(set (pc)
13456 (match_operand:P 0 "register_operand" "c,*l"))
13457 (use (label_ref (match_operand 1)))]
13458 "rs6000_speculate_indirect_jumps"
13459 "b%T0"
13460 [(set_attr "type" "jmpreg")])
13461
13462 (define_insn "@tablejump<mode>_insn_nospec"
13463 [(set (pc)
13464 (match_operand:P 0 "register_operand" "c,*l"))
13465 (use (label_ref (match_operand 1)))
13466 (clobber (match_operand:CC 2 "cc_reg_operand" "=y,y"))]
13467 "!rs6000_speculate_indirect_jumps"
13468 "crset %E2\;beq%T0- %2\;b $"
13469 [(set_attr "type" "jmpreg")
13470 (set_attr "length" "12")])
13471
13472 (define_insn "nop"
13473 [(unspec [(const_int 0)] UNSPEC_NOP)]
13474 ""
13475 "nop")
13476
13477 (define_insn "group_ending_nop"
13478 [(unspec [(const_int 0)] UNSPEC_GRP_END_NOP)]
13479 ""
13480 {
13481 operands[0] = gen_rtx_REG (Pmode,
13482 rs6000_tune == PROCESSOR_POWER6 ? 1 : 2);
13483 return "ori %0,%0,0";
13484 })
13485
13486 (define_insn "speculation_barrier"
13487 [(unspec_volatile:BLK [(const_int 0)] UNSPECV_SPEC_BARRIER)]
13488 ""
13489 {
13490 operands[0] = gen_rtx_REG (Pmode, 31);
13491 return "ori %0,%0,0";
13492 })
13493 \f
13494 ;; Define the subtract-one-and-jump insns, starting with the template
13495 ;; so loop.c knows what to generate.
13496
13497 (define_expand "doloop_end"
13498 [(use (match_operand 0)) ; loop pseudo
13499 (use (match_operand 1))] ; label
13500 ""
13501 {
13502 if (GET_MODE (operands[0]) != Pmode)
13503 FAIL;
13504
13505 emit_jump_insn (gen_ctr (Pmode, operands[0], operands[1]));
13506 DONE;
13507 })
13508
13509 (define_expand "@ctr<mode>"
13510 [(parallel [(set (pc)
13511 (if_then_else (ne (match_operand:P 0 "register_operand")
13512 (const_int 1))
13513 (label_ref (match_operand 1))
13514 (pc)))
13515 (set (match_dup 0)
13516 (plus:P (match_dup 0)
13517 (const_int -1)))
13518 (clobber (match_scratch:CC 2))
13519 (clobber (match_scratch:P 3))])]
13520 ""
13521 "")
13522
13523 ;; We need to be able to do this for any operand, including MEM, or we
13524 ;; will cause reload to blow up since we don't allow output reloads on
13525 ;; JUMP_INSNs.
13526 ;; For the length attribute to be calculated correctly, the
13527 ;; label MUST be operand 0.
13528 ;; rs6000_legitimate_combined_insn prevents combine creating any of
13529 ;; the ctr<mode> insns.
13530
13531 (define_code_attr bd [(eq "bdz") (ne "bdnz")])
13532 (define_code_attr bd_neg [(eq "bdnz") (ne "bdz")])
13533
13534 (define_insn "<bd>_<mode>"
13535 [(set (pc)
13536 (if_then_else (eqne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
13537 (const_int 1))
13538 (label_ref (match_operand 0))
13539 (pc)))
13540 (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wa*c*l")
13541 (plus:P (match_dup 1)
13542 (const_int -1)))
13543 (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
13544 (clobber (match_scratch:P 4 "=X,X,&r,r"))]
13545 ""
13546 {
13547 if (which_alternative != 0)
13548 return "#";
13549 else if (get_attr_length (insn) == 4)
13550 return "<bd> %l0";
13551 else
13552 return "<bd_neg> $+8\;b %l0";
13553 }
13554 [(set_attr "type" "branch")
13555 (set_attr_alternative "length"
13556 [(if_then_else (and (ge (minus (match_dup 0) (pc))
13557 (const_int -32768))
13558 (lt (minus (match_dup 0) (pc))
13559 (const_int 32764)))
13560 (const_int 4)
13561 (const_int 8))
13562 (const_string "16")
13563 (const_string "20")
13564 (const_string "20")])])
13565
13566 ;; Now the splitter if we could not allocate the CTR register
13567 (define_split
13568 [(set (pc)
13569 (if_then_else (match_operator 2 "comparison_operator"
13570 [(match_operand:P 1 "gpc_reg_operand")
13571 (const_int 1)])
13572 (match_operand 5)
13573 (match_operand 6)))
13574 (set (match_operand:P 0 "nonimmediate_operand")
13575 (plus:P (match_dup 1)
13576 (const_int -1)))
13577 (clobber (match_scratch:CC 3))
13578 (clobber (match_scratch:P 4))]
13579 "reload_completed"
13580 [(set (pc)
13581 (if_then_else (match_dup 7)
13582 (match_dup 5)
13583 (match_dup 6)))]
13584 {
13585 operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[2]), VOIDmode, operands[3],
13586 const0_rtx);
13587 emit_insn (gen_rtx_SET (operands[3],
13588 gen_rtx_COMPARE (CCmode, operands[1], const1_rtx)));
13589 if (int_reg_operand (operands[0], <MODE>mode))
13590 emit_insn (gen_add<mode>3 (operands[0], operands[1], constm1_rtx));
13591 else
13592 {
13593 emit_insn (gen_add<mode>3 (operands[4], operands[1], constm1_rtx));
13594 emit_move_insn (operands[0], operands[4]);
13595 }
13596 /* No DONE so branch comes from the pattern. */
13597 })
13598
13599 ;; patterns for bdnzt/bdnzf/bdzt/bdzf
13600 ;; Note that in the case of long branches we have to decompose this into
13601 ;; bdnz+bc. This is because bdnzt has an implied AND between the ctr condition
13602 ;; and the CR bit, which means there is no way to conveniently invert the
13603 ;; comparison as is done with plain bdnz/bdz.
13604
13605 (define_insn "<bd>tf_<mode>"
13606 [(set (pc)
13607 (if_then_else
13608 (and
13609 (eqne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
13610 (const_int 1))
13611 (match_operator 3 "branch_comparison_operator"
13612 [(match_operand 4 "cc_reg_operand" "y,y,y,y")
13613 (const_int 0)]))
13614 (label_ref (match_operand 0))
13615 (pc)))
13616 (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wa*c*l")
13617 (plus:P (match_dup 1)
13618 (const_int -1)))
13619 (clobber (match_scratch:P 5 "=X,X,&r,r"))
13620 (clobber (match_scratch:CC 6 "=X,&y,&y,&y"))
13621 (clobber (match_scratch:CCEQ 7 "=X,&y,&y,&y"))]
13622 ""
13623 {
13624 if (which_alternative != 0)
13625 return "#";
13626 else if (get_attr_length (insn) == 4)
13627 {
13628 if (branch_positive_comparison_operator (operands[3],
13629 GET_MODE (operands[3])))
13630 return "<bd>t %j3,%l0";
13631 else
13632 return "<bd>f %j3,%l0";
13633 }
13634 else
13635 {
13636 static char seq[96];
13637 char *bcs = output_cbranch (operands[3], ".Lshort%=", 1, insn);
13638 sprintf(seq, "<bd_neg> .Lshort%%=\;%s\;b %%l0\;.Lshort%%=:", bcs);
13639 return seq;
13640 }
13641 }
13642 [(set_attr "type" "branch")
13643 (set_attr_alternative "length"
13644 [(if_then_else (and (ge (minus (match_dup 0) (pc))
13645 (const_int -32768))
13646 (lt (minus (match_dup 0) (pc))
13647 (const_int 32764)))
13648 (const_int 4)
13649 (const_int 8))
13650 (const_string "16")
13651 (const_string "20")
13652 (const_string "20")])])
13653
13654 ;; Now the splitter if we could not allocate the CTR register
13655 (define_split
13656 [(set (pc)
13657 (if_then_else
13658 (and
13659 (match_operator 1 "comparison_operator"
13660 [(match_operand:P 0 "gpc_reg_operand")
13661 (const_int 1)])
13662 (match_operator 3 "branch_comparison_operator"
13663 [(match_operand 2 "cc_reg_operand")
13664 (const_int 0)]))
13665 (match_operand 4)
13666 (match_operand 5)))
13667 (set (match_operand:P 6 "nonimmediate_operand")
13668 (plus:P (match_dup 0)
13669 (const_int -1)))
13670 (clobber (match_scratch:P 7))
13671 (clobber (match_scratch:CC 8))
13672 (clobber (match_scratch:CCEQ 9))]
13673 "reload_completed"
13674 [(pc)]
13675 {
13676 rtx ctr = operands[0];
13677 rtx ctrcmp = operands[1];
13678 rtx ccin = operands[2];
13679 rtx cccmp = operands[3];
13680 rtx dst1 = operands[4];
13681 rtx dst2 = operands[5];
13682 rtx ctrout = operands[6];
13683 rtx ctrtmp = operands[7];
13684 enum rtx_code cmpcode = GET_CODE (ctrcmp);
13685 bool ispos = branch_positive_comparison_operator (ctrcmp, GET_MODE (ctrcmp));
13686 if (!ispos)
13687 cmpcode = reverse_condition (cmpcode);
13688 /* Generate crand/crandc here. */
13689 emit_insn (gen_rtx_SET (operands[8],
13690 gen_rtx_COMPARE (CCmode, ctr, const1_rtx)));
13691 rtx ctrcmpcc = gen_rtx_fmt_ee (cmpcode, SImode, operands[8], const0_rtx);
13692
13693 rtx andexpr = gen_rtx_AND (SImode, ctrcmpcc, cccmp);
13694 if (ispos)
13695 emit_insn (gen_cceq_ior_compare (SImode, operands[9], andexpr, ctrcmpcc,
13696 operands[8], cccmp, ccin));
13697 else
13698 emit_insn (gen_cceq_ior_compare_complement (operands[9], andexpr, ctrcmpcc,
13699 operands[8], cccmp, ccin));
13700 if (int_reg_operand (ctrout, <MODE>mode))
13701 emit_insn (gen_add<mode>3 (ctrout, ctr, constm1_rtx));
13702 else
13703 {
13704 emit_insn (gen_add<mode>3 (ctrtmp, ctr, constm1_rtx));
13705 emit_move_insn (ctrout, ctrtmp);
13706 }
13707 rtx cmp = gen_rtx_EQ (CCEQmode, operands[9], const0_rtx);
13708 emit_jump_insn (gen_rtx_SET (pc_rtx,
13709 gen_rtx_IF_THEN_ELSE (VOIDmode, cmp,
13710 dst1, dst2)));
13711 DONE;
13712 })
13713
13714 \f
13715 (define_insn "trap"
13716 [(trap_if (const_int 1) (const_int 0))]
13717 ""
13718 "trap"
13719 [(set_attr "type" "trap")])
13720
13721 (define_expand "ctrap<mode>4"
13722 [(trap_if (match_operator 0 "ordered_comparison_operator"
13723 [(match_operand:GPR 1 "register_operand")
13724 (match_operand:GPR 2 "reg_or_short_operand")])
13725 (match_operand 3 "zero_constant" ""))]
13726 ""
13727 "")
13728
13729 (define_insn ""
13730 [(trap_if (match_operator 0 "ordered_comparison_operator"
13731 [(match_operand:GPR 1 "register_operand" "r")
13732 (match_operand:GPR 2 "reg_or_short_operand" "rI")])
13733 (const_int 0))]
13734 ""
13735 "t<wd>%V0%I2 %1,%2"
13736 [(set_attr "type" "trap")])
13737 \f
13738 ;; Insns related to generating the function prologue and epilogue.
13739
13740 (define_expand "prologue"
13741 [(use (const_int 0))]
13742 ""
13743 {
13744 rs6000_emit_prologue ();
13745 if (!TARGET_SCHED_PROLOG)
13746 emit_insn (gen_blockage ());
13747 DONE;
13748 })
13749
13750 (define_insn "*movesi_from_cr_one"
13751 [(match_parallel 0 "mfcr_operation"
13752 [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
13753 (unspec:SI [(match_operand:CC 2 "cc_reg_operand" "y")
13754 (match_operand 3 "immediate_operand" "n")]
13755 UNSPEC_MOVESI_FROM_CR))])]
13756 "TARGET_MFCRF"
13757 {
13758 int mask = 0;
13759 int i;
13760 for (i = 0; i < XVECLEN (operands[0], 0); i++)
13761 {
13762 mask = INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
13763 operands[4] = GEN_INT (mask);
13764 output_asm_insn ("mfcr %1,%4", operands);
13765 }
13766 return "";
13767 }
13768 [(set_attr "type" "mfcrf")])
13769
13770 ;; Don't include the volatile CRs since their values are not used wrt CR save
13771 ;; in the prologue and doing so prevents shrink-wrapping because we can't move the
13772 ;; prologue past an insn (early exit test) that defines a register used in the
13773 ;; prologue.
13774 (define_insn "prologue_movesi_from_cr"
13775 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
13776 (unspec:SI [(reg:CC CR2_REGNO) (reg:CC CR3_REGNO)
13777 (reg:CC CR4_REGNO)]
13778 UNSPEC_MOVESI_FROM_CR))]
13779 ""
13780 "mfcr %0"
13781 [(set_attr "type" "mfcr")])
13782
13783 (define_insn "*crsave"
13784 [(match_parallel 0 "crsave_operation"
13785 [(set (match_operand:SI 1 "memory_operand" "=m")
13786 (match_operand:SI 2 "gpc_reg_operand" "r"))])]
13787 ""
13788 "stw %2,%1"
13789 [(set_attr "type" "store")])
13790
13791 (define_insn "*stmw"
13792 [(match_parallel 0 "stmw_operation"
13793 [(set (match_operand:SI 1 "memory_operand" "=m")
13794 (match_operand:SI 2 "gpc_reg_operand" "r"))])]
13795 "TARGET_MULTIPLE"
13796 "stmw %2,%1"
13797 [(set_attr "type" "store")
13798 (set_attr "update" "yes")
13799 (set_attr "indexed" "yes")])
13800
13801 ; The following comment applies to:
13802 ; save_gpregs_*
13803 ; save_fpregs_*
13804 ; restore_gpregs*
13805 ; return_and_restore_gpregs*
13806 ; return_and_restore_fpregs*
13807 ; return_and_restore_fpregs_aix*
13808 ;
13809 ; The out-of-line save / restore functions expects one input argument.
13810 ; Since those are not standard call_insn's, we must avoid using
13811 ; MATCH_OPERAND for that argument. That way the register rename
13812 ; optimization will not try to rename this register.
13813 ; Each pattern is repeated for each possible register number used in
13814 ; various ABIs (r11, r1, and for some functions r12)
13815
13816 (define_insn "*save_gpregs_<mode>_r11"
13817 [(match_parallel 0 "any_parallel_operand"
13818 [(clobber (reg:P LR_REGNO))
13819 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13820 (use (reg:P 11))
13821 (set (match_operand:P 2 "memory_operand" "=m")
13822 (match_operand:P 3 "gpc_reg_operand" "r"))])]
13823 ""
13824 "bl %1"
13825 [(set_attr "type" "branch")])
13826
13827 (define_insn "*save_gpregs_<mode>_r12"
13828 [(match_parallel 0 "any_parallel_operand"
13829 [(clobber (reg:P LR_REGNO))
13830 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13831 (use (reg:P 12))
13832 (set (match_operand:P 2 "memory_operand" "=m")
13833 (match_operand:P 3 "gpc_reg_operand" "r"))])]
13834 ""
13835 "bl %1"
13836 [(set_attr "type" "branch")])
13837
13838 (define_insn "*save_gpregs_<mode>_r1"
13839 [(match_parallel 0 "any_parallel_operand"
13840 [(clobber (reg:P LR_REGNO))
13841 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13842 (use (reg:P 1))
13843 (set (match_operand:P 2 "memory_operand" "=m")
13844 (match_operand:P 3 "gpc_reg_operand" "r"))])]
13845 ""
13846 "bl %1"
13847 [(set_attr "type" "branch")])
13848
13849 (define_insn "*save_fpregs_<mode>_r11"
13850 [(match_parallel 0 "any_parallel_operand"
13851 [(clobber (reg:P LR_REGNO))
13852 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13853 (use (reg:P 11))
13854 (set (match_operand:DF 2 "memory_operand" "=m")
13855 (match_operand:DF 3 "gpc_reg_operand" "d"))])]
13856 ""
13857 "bl %1"
13858 [(set_attr "type" "branch")])
13859
13860 (define_insn "*save_fpregs_<mode>_r12"
13861 [(match_parallel 0 "any_parallel_operand"
13862 [(clobber (reg:P LR_REGNO))
13863 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13864 (use (reg:P 12))
13865 (set (match_operand:DF 2 "memory_operand" "=m")
13866 (match_operand:DF 3 "gpc_reg_operand" "d"))])]
13867 ""
13868 "bl %1"
13869 [(set_attr "type" "branch")])
13870
13871 (define_insn "*save_fpregs_<mode>_r1"
13872 [(match_parallel 0 "any_parallel_operand"
13873 [(clobber (reg:P LR_REGNO))
13874 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13875 (use (reg:P 1))
13876 (set (match_operand:DF 2 "memory_operand" "=m")
13877 (match_operand:DF 3 "gpc_reg_operand" "d"))])]
13878 ""
13879 "bl %1"
13880 [(set_attr "type" "branch")])
13881
13882 ; This is to explain that changes to the stack pointer should
13883 ; not be moved over loads from or stores to stack memory.
13884 (define_insn "stack_tie"
13885 [(match_parallel 0 "tie_operand"
13886 [(set (mem:BLK (reg 1)) (const_int 0))])]
13887 ""
13888 ""
13889 [(set_attr "length" "0")])
13890
13891 ; Some 32-bit ABIs do not have a red zone, so the stack deallocation has to
13892 ; stay behind all restores from the stack, it cannot be reordered to before
13893 ; one. See PR77687. This insn is an add or mr, and a memory clobber.
13894 (define_insn "stack_restore_tie"
13895 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
13896 (plus:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
13897 (match_operand:SI 2 "reg_or_cint_operand" "O,rI")))
13898 (set (mem:BLK (scratch)) (const_int 0))]
13899 "TARGET_32BIT"
13900 "@
13901 mr %0,%1
13902 add%I2 %0,%1,%2"
13903 [(set_attr "type" "*,add")])
13904
13905 (define_expand "epilogue"
13906 [(use (const_int 0))]
13907 ""
13908 {
13909 if (!TARGET_SCHED_PROLOG)
13910 emit_insn (gen_blockage ());
13911 rs6000_emit_epilogue (EPILOGUE_TYPE_NORMAL);
13912 DONE;
13913 })
13914
13915 ; On some processors, doing the mtcrf one CC register at a time is
13916 ; faster (like on the 604e). On others, doing them all at once is
13917 ; faster; for instance, on the 601 and 750.
13918
13919 (define_expand "movsi_to_cr_one"
13920 [(set (match_operand:CC 0 "cc_reg_operand")
13921 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand")
13922 (match_dup 2)] UNSPEC_MOVESI_TO_CR))]
13923 ""
13924 "operands[2] = GEN_INT (1 << (7 - (REGNO (operands[0]) - CR0_REGNO)));")
13925
13926 (define_insn "*movsi_to_cr"
13927 [(match_parallel 0 "mtcrf_operation"
13928 [(set (match_operand:CC 1 "cc_reg_operand" "=y")
13929 (unspec:CC [(match_operand:SI 2 "gpc_reg_operand" "r")
13930 (match_operand 3 "immediate_operand" "n")]
13931 UNSPEC_MOVESI_TO_CR))])]
13932 ""
13933 {
13934 int mask = 0;
13935 int i;
13936 for (i = 0; i < XVECLEN (operands[0], 0); i++)
13937 mask |= INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
13938 operands[4] = GEN_INT (mask);
13939 return "mtcrf %4,%2";
13940 }
13941 [(set_attr "type" "mtcr")])
13942
13943 (define_insn "*mtcrfsi"
13944 [(set (match_operand:CC 0 "cc_reg_operand" "=y")
13945 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
13946 (match_operand 2 "immediate_operand" "n")]
13947 UNSPEC_MOVESI_TO_CR))]
13948 "REG_P (operands[0])
13949 && CR_REGNO_P (REGNO (operands[0]))
13950 && CONST_INT_P (operands[2])
13951 && INTVAL (operands[2]) == 1 << (7 - (REGNO (operands[0]) - CR0_REGNO))"
13952 "mtcrf %R0,%1"
13953 [(set_attr "type" "mtcr")])
13954
13955 ; The load-multiple instructions have similar properties.
13956 ; Note that "load_multiple" is a name known to the machine-independent
13957 ; code that actually corresponds to the PowerPC load-string.
13958
13959 (define_insn "*lmw"
13960 [(match_parallel 0 "lmw_operation"
13961 [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
13962 (match_operand:SI 2 "memory_operand" "m"))])]
13963 "TARGET_MULTIPLE"
13964 "lmw %1,%2"
13965 [(set_attr "type" "load")
13966 (set_attr "update" "yes")
13967 (set_attr "indexed" "yes")
13968 (set_attr "cell_micro" "always")])
13969
13970 ; FIXME: "any_parallel_operand" is a bit flexible...
13971
13972 ; The following comment applies to:
13973 ; save_gpregs_*
13974 ; save_fpregs_*
13975 ; restore_gpregs*
13976 ; return_and_restore_gpregs*
13977 ; return_and_restore_fpregs*
13978 ; return_and_restore_fpregs_aix*
13979 ;
13980 ; The out-of-line save / restore functions expects one input argument.
13981 ; Since those are not standard call_insn's, we must avoid using
13982 ; MATCH_OPERAND for that argument. That way the register rename
13983 ; optimization will not try to rename this register.
13984 ; Each pattern is repeated for each possible register number used in
13985 ; various ABIs (r11, r1, and for some functions r12)
13986
13987 (define_insn "*restore_gpregs_<mode>_r11"
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 11))
13992 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13993 (match_operand:P 3 "memory_operand" "m"))])]
13994 ""
13995 "bl %1"
13996 [(set_attr "type" "branch")])
13997
13998 (define_insn "*restore_gpregs_<mode>_r12"
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 12))
14003 (set (match_operand:P 2 "gpc_reg_operand" "=r")
14004 (match_operand:P 3 "memory_operand" "m"))])]
14005 ""
14006 "bl %1"
14007 [(set_attr "type" "branch")])
14008
14009 (define_insn "*restore_gpregs_<mode>_r1"
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 1))
14014 (set (match_operand:P 2 "gpc_reg_operand" "=r")
14015 (match_operand:P 3 "memory_operand" "m"))])]
14016 ""
14017 "bl %1"
14018 [(set_attr "type" "branch")])
14019
14020 (define_insn "*return_and_restore_gpregs_<mode>_r11"
14021 [(match_parallel 0 "any_parallel_operand"
14022 [(return)
14023 (clobber (reg:P LR_REGNO))
14024 (use (match_operand:P 1 "symbol_ref_operand" "s"))
14025 (use (reg:P 11))
14026 (set (match_operand:P 2 "gpc_reg_operand" "=r")
14027 (match_operand:P 3 "memory_operand" "m"))])]
14028 ""
14029 "b %1"
14030 [(set_attr "type" "branch")])
14031
14032 (define_insn "*return_and_restore_gpregs_<mode>_r12"
14033 [(match_parallel 0 "any_parallel_operand"
14034 [(return)
14035 (clobber (reg:P LR_REGNO))
14036 (use (match_operand:P 1 "symbol_ref_operand" "s"))
14037 (use (reg:P 12))
14038 (set (match_operand:P 2 "gpc_reg_operand" "=r")
14039 (match_operand:P 3 "memory_operand" "m"))])]
14040 ""
14041 "b %1"
14042 [(set_attr "type" "branch")])
14043
14044 (define_insn "*return_and_restore_gpregs_<mode>_r1"
14045 [(match_parallel 0 "any_parallel_operand"
14046 [(return)
14047 (clobber (reg:P LR_REGNO))
14048 (use (match_operand:P 1 "symbol_ref_operand" "s"))
14049 (use (reg:P 1))
14050 (set (match_operand:P 2 "gpc_reg_operand" "=r")
14051 (match_operand:P 3 "memory_operand" "m"))])]
14052 ""
14053 "b %1"
14054 [(set_attr "type" "branch")])
14055
14056 (define_insn "*return_and_restore_fpregs_<mode>_r11"
14057 [(match_parallel 0 "any_parallel_operand"
14058 [(return)
14059 (clobber (reg:P LR_REGNO))
14060 (use (match_operand:P 1 "symbol_ref_operand" "s"))
14061 (use (reg:P 11))
14062 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
14063 (match_operand:DF 3 "memory_operand" "m"))])]
14064 ""
14065 "b %1"
14066 [(set_attr "type" "branch")])
14067
14068 (define_insn "*return_and_restore_fpregs_<mode>_r12"
14069 [(match_parallel 0 "any_parallel_operand"
14070 [(return)
14071 (clobber (reg:P LR_REGNO))
14072 (use (match_operand:P 1 "symbol_ref_operand" "s"))
14073 (use (reg:P 12))
14074 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
14075 (match_operand:DF 3 "memory_operand" "m"))])]
14076 ""
14077 "b %1"
14078 [(set_attr "type" "branch")])
14079
14080 (define_insn "*return_and_restore_fpregs_<mode>_r1"
14081 [(match_parallel 0 "any_parallel_operand"
14082 [(return)
14083 (clobber (reg:P LR_REGNO))
14084 (use (match_operand:P 1 "symbol_ref_operand" "s"))
14085 (use (reg:P 1))
14086 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
14087 (match_operand:DF 3 "memory_operand" "m"))])]
14088 ""
14089 "b %1"
14090 [(set_attr "type" "branch")])
14091
14092 (define_insn "*return_and_restore_fpregs_aix_<mode>_r11"
14093 [(match_parallel 0 "any_parallel_operand"
14094 [(return)
14095 (use (match_operand:P 1 "symbol_ref_operand" "s"))
14096 (use (reg:P 11))
14097 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
14098 (match_operand:DF 3 "memory_operand" "m"))])]
14099 ""
14100 "b %1"
14101 [(set_attr "type" "branch")])
14102
14103 (define_insn "*return_and_restore_fpregs_aix_<mode>_r1"
14104 [(match_parallel 0 "any_parallel_operand"
14105 [(return)
14106 (use (match_operand:P 1 "symbol_ref_operand" "s"))
14107 (use (reg:P 1))
14108 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
14109 (match_operand:DF 3 "memory_operand" "m"))])]
14110 ""
14111 "b %1"
14112 [(set_attr "type" "branch")])
14113
14114 ; This is used in compiling the unwind routines.
14115 (define_expand "eh_return"
14116 [(use (match_operand 0 "general_operand"))]
14117 ""
14118 {
14119 emit_insn (gen_eh_set_lr (Pmode, operands[0]));
14120 DONE;
14121 })
14122
14123 ; We can't expand this before we know where the link register is stored.
14124 (define_insn_and_split "@eh_set_lr_<mode>"
14125 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")] UNSPECV_EH_RR)
14126 (clobber (match_scratch:P 1 "=&b"))]
14127 ""
14128 "#"
14129 "reload_completed"
14130 [(const_int 0)]
14131 {
14132 rs6000_emit_eh_reg_restore (operands[0], operands[1]);
14133 DONE;
14134 })
14135
14136 (define_insn "prefetch"
14137 [(prefetch (match_operand 0 "indexed_or_indirect_address" "a")
14138 (match_operand:SI 1 "const_int_operand" "n")
14139 (match_operand:SI 2 "const_int_operand" "n"))]
14140 ""
14141 {
14142
14143
14144 /* dcbtstt, dcbtt and TH=0b10000 support starts with ISA 2.06 (Power7).
14145 AIX does not support the dcbtstt and dcbtt extended mnemonics.
14146 The AIX assembler does not support the three operand form of dcbt
14147 and dcbtst on Power 7 (-mpwr7). */
14148 int inst_select = INTVAL (operands[2]) || !TARGET_DIRECT_MOVE;
14149
14150 if (REG_P (operands[0]))
14151 {
14152 if (INTVAL (operands[1]) == 0)
14153 return inst_select ? "dcbt 0,%0" : "dcbt 0,%0,16";
14154 else
14155 return inst_select ? "dcbtst 0,%0" : "dcbtst 0,%0,16";
14156 }
14157 else
14158 {
14159 if (INTVAL (operands[1]) == 0)
14160 return inst_select ? "dcbt %a0" : "dcbt %a0,16";
14161 else
14162 return inst_select ? "dcbtst %a0" : "dcbtst %a0,16";
14163 }
14164 }
14165 [(set_attr "type" "load")])
14166 \f
14167 ;; Handle -fsplit-stack.
14168
14169 (define_expand "split_stack_prologue"
14170 [(const_int 0)]
14171 ""
14172 {
14173 rs6000_expand_split_stack_prologue ();
14174 DONE;
14175 })
14176
14177 (define_expand "load_split_stack_limit"
14178 [(set (match_operand 0)
14179 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))]
14180 ""
14181 {
14182 emit_insn (gen_rtx_SET (operands[0],
14183 gen_rtx_UNSPEC (Pmode,
14184 gen_rtvec (1, const0_rtx),
14185 UNSPEC_STACK_CHECK)));
14186 DONE;
14187 })
14188
14189 (define_insn "load_split_stack_limit_di"
14190 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
14191 (unspec:DI [(const_int 0)] UNSPEC_STACK_CHECK))]
14192 "TARGET_64BIT"
14193 "ld %0,-0x7040(13)"
14194 [(set_attr "type" "load")
14195 (set_attr "update" "no")
14196 (set_attr "indexed" "no")])
14197
14198 (define_insn "load_split_stack_limit_si"
14199 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
14200 (unspec:SI [(const_int 0)] UNSPEC_STACK_CHECK))]
14201 "!TARGET_64BIT"
14202 "lwz %0,-0x7020(2)"
14203 [(set_attr "type" "load")
14204 (set_attr "update" "no")
14205 (set_attr "indexed" "no")])
14206
14207 ;; A return instruction which the middle-end doesn't see.
14208 ;; Use r0 to stop regrename twiddling with lr restore insns emitted
14209 ;; after the call to __morestack.
14210 (define_insn "split_stack_return"
14211 [(unspec_volatile [(reg:SI 0) (reg:SI LR_REGNO)] UNSPECV_SPLIT_STACK_RETURN)]
14212 ""
14213 "blr"
14214 [(set_attr "type" "jmpreg")])
14215
14216 ;; If there are operand 0 bytes available on the stack, jump to
14217 ;; operand 1.
14218 (define_expand "split_stack_space_check"
14219 [(set (match_dup 2)
14220 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
14221 (set (match_dup 3)
14222 (minus (reg STACK_POINTER_REGNUM)
14223 (match_operand 0)))
14224 (set (match_dup 4) (compare:CCUNS (match_dup 3) (match_dup 2)))
14225 (set (pc) (if_then_else
14226 (geu (match_dup 4) (const_int 0))
14227 (label_ref (match_operand 1))
14228 (pc)))]
14229 ""
14230 {
14231 rs6000_split_stack_space_check (operands[0], operands[1]);
14232 DONE;
14233 })
14234 \f
14235 (define_insn "bpermd_<mode>"
14236 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
14237 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "r")
14238 (match_operand:P 2 "gpc_reg_operand" "r")] UNSPEC_BPERM))]
14239 "TARGET_POPCNTD"
14240 "bpermd %0,%1,%2"
14241 [(set_attr "type" "popcnt")])
14242
14243 \f
14244 ;; Builtin fma support. Handle
14245 ;; Note that the conditions for expansion are in the FMA_F iterator.
14246
14247 (define_expand "fma<mode>4"
14248 [(set (match_operand:FMA_F 0 "gpc_reg_operand")
14249 (fma:FMA_F
14250 (match_operand:FMA_F 1 "gpc_reg_operand")
14251 (match_operand:FMA_F 2 "gpc_reg_operand")
14252 (match_operand:FMA_F 3 "gpc_reg_operand")))]
14253 ""
14254 "")
14255
14256 (define_insn "*fma<mode>4_fpr"
14257 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,wa,wa")
14258 (fma:SFDF
14259 (match_operand:SFDF 1 "gpc_reg_operand" "%d,wa,wa")
14260 (match_operand:SFDF 2 "gpc_reg_operand" "d,wa,0")
14261 (match_operand:SFDF 3 "gpc_reg_operand" "d,0,wa")))]
14262 "TARGET_HARD_FLOAT"
14263 "@
14264 fmadd<s> %0,%1,%2,%3
14265 xsmadda<sd>p %x0,%x1,%x2
14266 xsmaddm<sd>p %x0,%x1,%x3"
14267 [(set_attr "type" "fp")
14268 (set_attr "isa" "*,<Fisa>,<Fisa>")])
14269
14270 ; Altivec only has fma and nfms.
14271 (define_expand "fms<mode>4"
14272 [(set (match_operand:FMA_F 0 "gpc_reg_operand")
14273 (fma:FMA_F
14274 (match_operand:FMA_F 1 "gpc_reg_operand")
14275 (match_operand:FMA_F 2 "gpc_reg_operand")
14276 (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand"))))]
14277 "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
14278 "")
14279
14280 (define_insn "*fms<mode>4_fpr"
14281 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,wa,wa")
14282 (fma:SFDF
14283 (match_operand:SFDF 1 "gpc_reg_operand" "d,wa,wa")
14284 (match_operand:SFDF 2 "gpc_reg_operand" "d,wa,0")
14285 (neg:SFDF (match_operand:SFDF 3 "gpc_reg_operand" "d,0,wa"))))]
14286 "TARGET_HARD_FLOAT"
14287 "@
14288 fmsub<s> %0,%1,%2,%3
14289 xsmsuba<sd>p %x0,%x1,%x2
14290 xsmsubm<sd>p %x0,%x1,%x3"
14291 [(set_attr "type" "fp")
14292 (set_attr "isa" "*,<Fisa>,<Fisa>")])
14293
14294 ;; If signed zeros are ignored, -(a * b - c) = -a * b + c.
14295 (define_expand "fnma<mode>4"
14296 [(set (match_operand:FMA_F 0 "gpc_reg_operand")
14297 (neg:FMA_F
14298 (fma:FMA_F
14299 (match_operand:FMA_F 1 "gpc_reg_operand")
14300 (match_operand:FMA_F 2 "gpc_reg_operand")
14301 (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand")))))]
14302 "!HONOR_SIGNED_ZEROS (<MODE>mode)"
14303 "")
14304
14305 ;; If signed zeros are ignored, -(a * b + c) = -a * b - c.
14306 (define_expand "fnms<mode>4"
14307 [(set (match_operand:FMA_F 0 "gpc_reg_operand")
14308 (neg:FMA_F
14309 (fma:FMA_F
14310 (match_operand:FMA_F 1 "gpc_reg_operand")
14311 (match_operand:FMA_F 2 "gpc_reg_operand")
14312 (match_operand:FMA_F 3 "gpc_reg_operand"))))]
14313 "!HONOR_SIGNED_ZEROS (<MODE>mode) && !VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
14314 "")
14315
14316 ; Not an official optab name, but used from builtins.
14317 (define_expand "nfma<mode>4"
14318 [(set (match_operand:FMA_F 0 "gpc_reg_operand")
14319 (neg:FMA_F
14320 (fma:FMA_F
14321 (match_operand:FMA_F 1 "gpc_reg_operand")
14322 (match_operand:FMA_F 2 "gpc_reg_operand")
14323 (match_operand:FMA_F 3 "gpc_reg_operand"))))]
14324 "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
14325 "")
14326
14327 (define_insn "*nfma<mode>4_fpr"
14328 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,wa,wa")
14329 (neg:SFDF
14330 (fma:SFDF
14331 (match_operand:SFDF 1 "gpc_reg_operand" "d,wa,wa")
14332 (match_operand:SFDF 2 "gpc_reg_operand" "d,wa,0")
14333 (match_operand:SFDF 3 "gpc_reg_operand" "d,0,wa"))))]
14334 "TARGET_HARD_FLOAT"
14335 "@
14336 fnmadd<s> %0,%1,%2,%3
14337 xsnmadda<sd>p %x0,%x1,%x2
14338 xsnmaddm<sd>p %x0,%x1,%x3"
14339 [(set_attr "type" "fp")
14340 (set_attr "isa" "*,<Fisa>,<Fisa>")])
14341
14342 ; Not an official optab name, but used from builtins.
14343 (define_expand "nfms<mode>4"
14344 [(set (match_operand:FMA_F 0 "gpc_reg_operand")
14345 (neg:FMA_F
14346 (fma:FMA_F
14347 (match_operand:FMA_F 1 "gpc_reg_operand")
14348 (match_operand:FMA_F 2 "gpc_reg_operand")
14349 (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand")))))]
14350 ""
14351 "")
14352
14353 (define_insn "*nfmssf4_fpr"
14354 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,wa,wa")
14355 (neg:SFDF
14356 (fma:SFDF
14357 (match_operand:SFDF 1 "gpc_reg_operand" "d,wa,wa")
14358 (match_operand:SFDF 2 "gpc_reg_operand" "d,wa,0")
14359 (neg:SFDF
14360 (match_operand:SFDF 3 "gpc_reg_operand" "d,0,wa")))))]
14361 "TARGET_HARD_FLOAT"
14362 "@
14363 fnmsub<s> %0,%1,%2,%3
14364 xsnmsuba<sd>p %x0,%x1,%x2
14365 xsnmsubm<sd>p %x0,%x1,%x3"
14366 [(set_attr "type" "fp")
14367 (set_attr "isa" "*,<Fisa>,<Fisa>")])
14368 \f
14369 (define_expand "rs6000_get_timebase"
14370 [(use (match_operand:DI 0 "gpc_reg_operand"))]
14371 ""
14372 {
14373 if (TARGET_POWERPC64)
14374 emit_insn (gen_rs6000_mftb_di (operands[0]));
14375 else
14376 emit_insn (gen_rs6000_get_timebase_ppc32 (operands[0]));
14377 DONE;
14378 })
14379
14380 (define_insn "rs6000_get_timebase_ppc32"
14381 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
14382 (unspec_volatile:DI [(const_int 0)] UNSPECV_MFTB))
14383 (clobber (match_scratch:SI 1 "=r"))
14384 (clobber (match_scratch:CC 2 "=y"))]
14385 "!TARGET_POWERPC64"
14386 {
14387 if (WORDS_BIG_ENDIAN)
14388 if (TARGET_MFCRF)
14389 {
14390 return "mfspr %0,269\;"
14391 "mfspr %L0,268\;"
14392 "mfspr %1,269\;"
14393 "cmpw %2,%0,%1\;"
14394 "bne- %2,$-16";
14395 }
14396 else
14397 {
14398 return "mftbu %0\;"
14399 "mftb %L0\;"
14400 "mftbu %1\;"
14401 "cmpw %2,%0,%1\;"
14402 "bne- %2,$-16";
14403 }
14404 else
14405 if (TARGET_MFCRF)
14406 {
14407 return "mfspr %L0,269\;"
14408 "mfspr %0,268\;"
14409 "mfspr %1,269\;"
14410 "cmpw %2,%L0,%1\;"
14411 "bne- %2,$-16";
14412 }
14413 else
14414 {
14415 return "mftbu %L0\;"
14416 "mftb %0\;"
14417 "mftbu %1\;"
14418 "cmpw %2,%L0,%1\;"
14419 "bne- %2,$-16";
14420 }
14421 }
14422 [(set_attr "length" "20")])
14423
14424 (define_insn "rs6000_mftb_<mode>"
14425 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
14426 (unspec_volatile:GPR [(const_int 0)] UNSPECV_MFTB))]
14427 ""
14428 {
14429 if (TARGET_MFCRF)
14430 return "mfspr %0,268";
14431 else
14432 return "mftb %0";
14433 })
14434
14435 \f
14436 ;; The ISA 3.0 mffsl instruction is a lower latency instruction
14437 ;; for reading bits [29:31], [45:51] and [56:63] of the FPSCR.
14438 (define_insn "rs6000_mffsl_hw"
14439 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
14440 (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFSL))]
14441 "TARGET_HARD_FLOAT"
14442 "mffsl %0")
14443
14444 (define_expand "rs6000_mffsl"
14445 [(set (match_operand:DF 0 "gpc_reg_operand")
14446 (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFSL))]
14447 "TARGET_HARD_FLOAT"
14448 {
14449 /* If the low latency mffsl instruction (ISA 3.0) is available use it,
14450 otherwise fall back to the older mffs instruction to emulate the mffsl
14451 instruction. */
14452
14453 if (!TARGET_P9_MISC)
14454 {
14455 rtx tmp1 = gen_reg_rtx (DFmode);
14456
14457 /* The mffs instruction reads the entire FPSCR. Emulate the mffsl
14458 instruction using the mffs instruction and masking the result. */
14459 emit_insn (gen_rs6000_mffs (tmp1));
14460
14461 rtx tmp1di = simplify_gen_subreg (DImode, tmp1, DFmode, 0);
14462 rtx tmp2 = gen_reg_rtx (DImode);
14463 emit_insn (gen_anddi3 (tmp2, tmp1di, GEN_INT (0x70007f0ffLL)));
14464
14465 rtx tmp2df = simplify_gen_subreg (DFmode, tmp2, DImode, 0);
14466 emit_move_insn (operands[0], tmp2df);
14467 DONE;
14468 }
14469
14470 emit_insn (gen_rs6000_mffsl_hw (operands[0]));
14471 DONE;
14472 })
14473
14474 (define_insn "rs6000_mffs"
14475 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
14476 (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFS))]
14477 "TARGET_HARD_FLOAT"
14478 "mffs %0")
14479
14480 (define_insn "rs6000_mtfsf"
14481 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "i")
14482 (match_operand:DF 1 "gpc_reg_operand" "d")]
14483 UNSPECV_MTFSF)]
14484 "TARGET_HARD_FLOAT"
14485 "mtfsf %0,%1")
14486
14487 (define_insn "rs6000_mtfsf_hi"
14488 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "n")
14489 (match_operand:DF 1 "gpc_reg_operand" "d")]
14490 UNSPECV_MTFSF_HI)]
14491 "TARGET_HARD_FLOAT"
14492 "mtfsf %0,%1,0,1")
14493
14494 \f
14495 ;; Power8 fusion support for fusing an addis instruction with a D-form load of
14496 ;; a GPR. The addis instruction must be adjacent to the load, and use the same
14497 ;; register that is being loaded. The fused ops must be physically adjacent.
14498
14499 ;; On Power8 GPR loads, we try to use the register that is being load. The
14500 ;; peephole2 then gathers any other fused possibilities that it can find after
14501 ;; register allocation. If power9 fusion is selected, we also fuse floating
14502 ;; point loads/stores.
14503
14504 ;; Find cases where the addis that feeds into a load instruction is either used
14505 ;; once or is the same as the target register, and replace it with the fusion
14506 ;; insn
14507
14508 (define_peephole2
14509 [(set (match_operand:P 0 "base_reg_operand")
14510 (match_operand:P 1 "fusion_gpr_addis"))
14511 (set (match_operand:INT1 2 "base_reg_operand")
14512 (match_operand:INT1 3 "fusion_gpr_mem_load"))]
14513 "TARGET_P8_FUSION
14514 && fusion_gpr_load_p (operands[0], operands[1], operands[2],
14515 operands[3])"
14516 [(const_int 0)]
14517 {
14518 expand_fusion_gpr_load (operands);
14519 DONE;
14520 })
14521
14522 ;; Fusion insn, created by the define_peephole2 above (and eventually by
14523 ;; reload)
14524
14525 (define_insn "*fusion_gpr_load_<mode>"
14526 [(set (match_operand:INT1 0 "base_reg_operand" "=b")
14527 (unspec:INT1 [(match_operand:INT1 1 "fusion_addis_mem_combo_load" "wF")]
14528 UNSPEC_FUSION_GPR))]
14529 "TARGET_P8_FUSION"
14530 {
14531 return emit_fusion_gpr_load (operands[0], operands[1]);
14532 }
14533 [(set_attr "type" "load")
14534 (set_attr "length" "8")])
14535
14536 \f
14537 ;; Optimize cases where we want to do a D-form load (register+offset) on
14538 ;; ISA 2.06/2.07 to an Altivec register, and the register allocator
14539 ;; has generated:
14540 ;; LFD 0,32(3)
14541 ;; XXLOR 32,0,0
14542 ;;
14543 ;; and we change this to:
14544 ;; LI 0,32
14545 ;; LXSDX 32,3,9
14546
14547 (define_peephole2
14548 [(match_scratch:P 0 "b")
14549 (set (match_operand:ALTIVEC_DFORM 1 "fpr_reg_operand")
14550 (match_operand:ALTIVEC_DFORM 2 "simple_offsettable_mem_operand"))
14551 (set (match_operand:ALTIVEC_DFORM 3 "altivec_register_operand")
14552 (match_dup 1))]
14553 "TARGET_VSX && !TARGET_P9_VECTOR && peep2_reg_dead_p (2, operands[1])"
14554 [(set (match_dup 0)
14555 (match_dup 4))
14556 (set (match_dup 3)
14557 (match_dup 5))]
14558 {
14559 rtx tmp_reg = operands[0];
14560 rtx mem = operands[2];
14561 rtx addr = XEXP (mem, 0);
14562 rtx add_op0, add_op1, new_addr;
14563
14564 gcc_assert (GET_CODE (addr) == PLUS || GET_CODE (addr) == LO_SUM);
14565 add_op0 = XEXP (addr, 0);
14566 add_op1 = XEXP (addr, 1);
14567 gcc_assert (REG_P (add_op0));
14568 new_addr = gen_rtx_PLUS (Pmode, add_op0, tmp_reg);
14569
14570 operands[4] = add_op1;
14571 operands[5] = change_address (mem, <ALTIVEC_DFORM:MODE>mode, new_addr);
14572 })
14573
14574 ;; Optimize cases were want to do a D-form store on ISA 2.06/2.07 from an
14575 ;; Altivec register, and the register allocator has generated:
14576 ;; XXLOR 0,32,32
14577 ;; STFD 0,32(3)
14578 ;;
14579 ;; and we change this to:
14580 ;; LI 0,32
14581 ;; STXSDX 32,3,9
14582
14583 (define_peephole2
14584 [(match_scratch:P 0 "b")
14585 (set (match_operand:ALTIVEC_DFORM 1 "fpr_reg_operand")
14586 (match_operand:ALTIVEC_DFORM 2 "altivec_register_operand"))
14587 (set (match_operand:ALTIVEC_DFORM 3 "simple_offsettable_mem_operand")
14588 (match_dup 1))]
14589 "TARGET_VSX && !TARGET_P9_VECTOR && peep2_reg_dead_p (2, operands[1])"
14590 [(set (match_dup 0)
14591 (match_dup 4))
14592 (set (match_dup 5)
14593 (match_dup 2))]
14594 {
14595 rtx tmp_reg = operands[0];
14596 rtx mem = operands[3];
14597 rtx addr = XEXP (mem, 0);
14598 rtx add_op0, add_op1, new_addr;
14599
14600 gcc_assert (GET_CODE (addr) == PLUS || GET_CODE (addr) == LO_SUM);
14601 add_op0 = XEXP (addr, 0);
14602 add_op1 = XEXP (addr, 1);
14603 gcc_assert (REG_P (add_op0));
14604 new_addr = gen_rtx_PLUS (Pmode, add_op0, tmp_reg);
14605
14606 operands[4] = add_op1;
14607 operands[5] = change_address (mem, <ALTIVEC_DFORM:MODE>mode, new_addr);
14608 })
14609
14610 \f
14611 ;; Miscellaneous ISA 2.06 (power7) instructions
14612 (define_insn "addg6s"
14613 [(set (match_operand:SI 0 "register_operand" "=r")
14614 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
14615 (match_operand:SI 2 "register_operand" "r")]
14616 UNSPEC_ADDG6S))]
14617 "TARGET_POPCNTD"
14618 "addg6s %0,%1,%2"
14619 [(set_attr "type" "integer")])
14620
14621 (define_insn "cdtbcd"
14622 [(set (match_operand:SI 0 "register_operand" "=r")
14623 (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
14624 UNSPEC_CDTBCD))]
14625 "TARGET_POPCNTD"
14626 "cdtbcd %0,%1"
14627 [(set_attr "type" "integer")])
14628
14629 (define_insn "cbcdtd"
14630 [(set (match_operand:SI 0 "register_operand" "=r")
14631 (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
14632 UNSPEC_CBCDTD))]
14633 "TARGET_POPCNTD"
14634 "cbcdtd %0,%1"
14635 [(set_attr "type" "integer")])
14636
14637 (define_int_iterator UNSPEC_DIV_EXTEND [UNSPEC_DIVE
14638 UNSPEC_DIVEU])
14639
14640 (define_int_attr div_extend [(UNSPEC_DIVE "e")
14641 (UNSPEC_DIVEU "eu")])
14642
14643 (define_insn "div<div_extend>_<mode>"
14644 [(set (match_operand:GPR 0 "register_operand" "=r")
14645 (unspec:GPR [(match_operand:GPR 1 "register_operand" "r")
14646 (match_operand:GPR 2 "register_operand" "r")]
14647 UNSPEC_DIV_EXTEND))]
14648 "TARGET_POPCNTD"
14649 "div<wd><div_extend> %0,%1,%2"
14650 [(set_attr "type" "div")
14651 (set_attr "size" "<bits>")])
14652
14653 \f
14654 ;; Pack/unpack 128-bit floating point types that take 2 scalar registers
14655
14656 ; Type of the 64-bit part when packing/unpacking 128-bit floating point types
14657 (define_mode_attr FP128_64 [(TF "DF")
14658 (IF "DF")
14659 (TD "DI")
14660 (KF "DI")])
14661
14662 (define_expand "unpack<mode>"
14663 [(set (match_operand:<FP128_64> 0 "nonimmediate_operand")
14664 (unspec:<FP128_64>
14665 [(match_operand:FMOVE128 1 "register_operand")
14666 (match_operand:QI 2 "const_0_to_1_operand")]
14667 UNSPEC_UNPACK_128BIT))]
14668 "FLOAT128_2REG_P (<MODE>mode)"
14669 "")
14670
14671 (define_insn_and_split "unpack<mode>_dm"
14672 [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m,d,r,m")
14673 (unspec:<FP128_64>
14674 [(match_operand:FMOVE128 1 "register_operand" "d,d,r,d,r")
14675 (match_operand:QI 2 "const_0_to_1_operand" "i,i,i,i,i")]
14676 UNSPEC_UNPACK_128BIT))]
14677 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE && FLOAT128_2REG_P (<MODE>mode)"
14678 "#"
14679 "&& reload_completed"
14680 [(set (match_dup 0) (match_dup 3))]
14681 {
14682 unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
14683
14684 if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
14685 {
14686 emit_note (NOTE_INSN_DELETED);
14687 DONE;
14688 }
14689
14690 operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
14691 }
14692 [(set_attr "type" "fp,fpstore,mtvsr,mfvsr,store")])
14693
14694 (define_insn_and_split "unpack<mode>_nodm"
14695 [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m,m")
14696 (unspec:<FP128_64>
14697 [(match_operand:FMOVE128 1 "register_operand" "d,d,r")
14698 (match_operand:QI 2 "const_0_to_1_operand" "i,i,i")]
14699 UNSPEC_UNPACK_128BIT))]
14700 "(!TARGET_POWERPC64 || !TARGET_DIRECT_MOVE) && FLOAT128_2REG_P (<MODE>mode)"
14701 "#"
14702 "&& reload_completed"
14703 [(set (match_dup 0) (match_dup 3))]
14704 {
14705 unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
14706
14707 if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
14708 {
14709 emit_note (NOTE_INSN_DELETED);
14710 DONE;
14711 }
14712
14713 operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
14714 }
14715 [(set_attr "type" "fp,fpstore,store")])
14716
14717 (define_expand "pack<mode>"
14718 [(use (match_operand:FMOVE128 0 "register_operand"))
14719 (use (match_operand:<FP128_64> 1 "register_operand"))
14720 (use (match_operand:<FP128_64> 2 "register_operand"))]
14721 "FLOAT128_2REG_P (<MODE>mode)"
14722 {
14723 if (TARGET_HARD_FLOAT)
14724 emit_insn (gen_pack<mode>_hard (operands[0], operands[1], operands[2]));
14725 else
14726 emit_insn (gen_pack<mode>_soft (operands[0], operands[1], operands[2]));
14727 DONE;
14728 })
14729
14730 (define_insn_and_split "pack<mode>_hard"
14731 [(set (match_operand:FMOVE128 0 "register_operand" "=&d")
14732 (unspec:FMOVE128
14733 [(match_operand:<FP128_64> 1 "register_operand" "d")
14734 (match_operand:<FP128_64> 2 "register_operand" "d")]
14735 UNSPEC_PACK_128BIT))]
14736 "FLOAT128_2REG_P (<MODE>mode) && TARGET_HARD_FLOAT"
14737 "#"
14738 "&& reload_completed"
14739 [(set (match_dup 3) (match_dup 1))
14740 (set (match_dup 4) (match_dup 2))]
14741 {
14742 unsigned dest_hi = REGNO (operands[0]);
14743 unsigned dest_lo = dest_hi + 1;
14744
14745 gcc_assert (!IN_RANGE (REGNO (operands[1]), dest_hi, dest_lo));
14746 gcc_assert (!IN_RANGE (REGNO (operands[2]), dest_hi, dest_lo));
14747
14748 operands[3] = gen_rtx_REG (<FP128_64>mode, dest_hi);
14749 operands[4] = gen_rtx_REG (<FP128_64>mode, dest_lo);
14750 }
14751 [(set_attr "type" "fp")
14752 (set_attr "length" "8")])
14753
14754 (define_insn_and_split "pack<mode>_soft"
14755 [(set (match_operand:FMOVE128 0 "register_operand" "=&r")
14756 (unspec:FMOVE128
14757 [(match_operand:<FP128_64> 1 "register_operand" "r")
14758 (match_operand:<FP128_64> 2 "register_operand" "r")]
14759 UNSPEC_PACK_128BIT))]
14760 "FLOAT128_2REG_P (<MODE>mode) && TARGET_SOFT_FLOAT"
14761 "#"
14762 "&& reload_completed"
14763 [(set (match_dup 3) (match_dup 1))
14764 (set (match_dup 4) (match_dup 2))]
14765 {
14766 unsigned dest_hi = REGNO (operands[0]);
14767 unsigned dest_lo = dest_hi + (TARGET_POWERPC64 ? 1 : 2);
14768
14769 gcc_assert (!IN_RANGE (REGNO (operands[1]), dest_hi, dest_lo));
14770 gcc_assert (!IN_RANGE (REGNO (operands[2]), dest_hi, dest_lo));
14771
14772 operands[3] = gen_rtx_REG (<FP128_64>mode, dest_hi);
14773 operands[4] = gen_rtx_REG (<FP128_64>mode, dest_lo);
14774 }
14775 [(set_attr "type" "integer")
14776 (set (attr "length")
14777 (if_then_else
14778 (match_test "TARGET_POWERPC64")
14779 (const_string "8")
14780 (const_string "16")))])
14781
14782 (define_insn "unpack<mode>"
14783 [(set (match_operand:DI 0 "register_operand" "=wa,wa")
14784 (unspec:DI [(match_operand:FMOVE128_VSX 1 "register_operand" "0,wa")
14785 (match_operand:QI 2 "const_0_to_1_operand" "O,i")]
14786 UNSPEC_UNPACK_128BIT))]
14787 "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)"
14788 {
14789 if (REGNO (operands[0]) == REGNO (operands[1]) && INTVAL (operands[2]) == 0)
14790 return ASM_COMMENT_START " xxpermdi to same register";
14791
14792 operands[3] = GEN_INT (INTVAL (operands[2]) == 0 ? 0 : 3);
14793 return "xxpermdi %x0,%x1,%x1,%3";
14794 }
14795 [(set_attr "type" "vecperm")])
14796
14797 (define_insn "pack<mode>"
14798 [(set (match_operand:FMOVE128_VSX 0 "register_operand" "=wa")
14799 (unspec:FMOVE128_VSX
14800 [(match_operand:DI 1 "register_operand" "wa")
14801 (match_operand:DI 2 "register_operand" "wa")]
14802 UNSPEC_PACK_128BIT))]
14803 "TARGET_VSX"
14804 "xxpermdi %x0,%x1,%x2,0"
14805 [(set_attr "type" "vecperm")])
14806
14807
14808 \f
14809 ;; ISA 2.08 IEEE 128-bit floating point support.
14810
14811 (define_insn "add<mode>3"
14812 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14813 (plus:IEEE128
14814 (match_operand:IEEE128 1 "altivec_register_operand" "v")
14815 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14816 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14817 "xsaddqp %0,%1,%2"
14818 [(set_attr "type" "vecfloat")
14819 (set_attr "size" "128")])
14820
14821 (define_insn "sub<mode>3"
14822 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14823 (minus:IEEE128
14824 (match_operand:IEEE128 1 "altivec_register_operand" "v")
14825 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14826 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14827 "xssubqp %0,%1,%2"
14828 [(set_attr "type" "vecfloat")
14829 (set_attr "size" "128")])
14830
14831 (define_insn "mul<mode>3"
14832 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14833 (mult:IEEE128
14834 (match_operand:IEEE128 1 "altivec_register_operand" "v")
14835 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14836 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14837 "xsmulqp %0,%1,%2"
14838 [(set_attr "type" "qmul")
14839 (set_attr "size" "128")])
14840
14841 (define_insn "div<mode>3"
14842 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14843 (div:IEEE128
14844 (match_operand:IEEE128 1 "altivec_register_operand" "v")
14845 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14846 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14847 "xsdivqp %0,%1,%2"
14848 [(set_attr "type" "vecdiv")
14849 (set_attr "size" "128")])
14850
14851 (define_insn "sqrt<mode>2"
14852 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14853 (sqrt:IEEE128
14854 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14855 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14856 "xssqrtqp %0,%1"
14857 [(set_attr "type" "vecdiv")
14858 (set_attr "size" "128")])
14859
14860 (define_expand "copysign<mode>3"
14861 [(use (match_operand:IEEE128 0 "altivec_register_operand"))
14862 (use (match_operand:IEEE128 1 "altivec_register_operand"))
14863 (use (match_operand:IEEE128 2 "altivec_register_operand"))]
14864 "FLOAT128_IEEE_P (<MODE>mode)"
14865 {
14866 if (TARGET_FLOAT128_HW)
14867 emit_insn (gen_copysign<mode>3_hard (operands[0], operands[1],
14868 operands[2]));
14869 else
14870 emit_insn (gen_copysign<mode>3_soft (operands[0], operands[1],
14871 operands[2]));
14872 DONE;
14873 })
14874
14875 (define_insn "copysign<mode>3_hard"
14876 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14877 (unspec:IEEE128
14878 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14879 (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14880 UNSPEC_COPYSIGN))]
14881 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14882 "xscpsgnqp %0,%2,%1"
14883 [(set_attr "type" "vecmove")
14884 (set_attr "size" "128")])
14885
14886 (define_insn "copysign<mode>3_soft"
14887 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14888 (unspec:IEEE128
14889 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14890 (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14891 UNSPEC_COPYSIGN))
14892 (clobber (match_scratch:IEEE128 3 "=&v"))]
14893 "!TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14894 "xscpsgndp %x3,%x2,%x1\;xxpermdi %x0,%x3,%x1,1"
14895 [(set_attr "type" "veccomplex")
14896 (set_attr "length" "8")])
14897
14898 (define_insn "@neg<mode>2_hw"
14899 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14900 (neg:IEEE128
14901 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14902 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14903 "xsnegqp %0,%1"
14904 [(set_attr "type" "vecmove")
14905 (set_attr "size" "128")])
14906
14907
14908 (define_insn "@abs<mode>2_hw"
14909 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14910 (abs:IEEE128
14911 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14912 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14913 "xsabsqp %0,%1"
14914 [(set_attr "type" "vecmove")
14915 (set_attr "size" "128")])
14916
14917
14918 (define_insn "*nabs<mode>2_hw"
14919 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14920 (neg:IEEE128
14921 (abs:IEEE128
14922 (match_operand:IEEE128 1 "altivec_register_operand" "v"))))]
14923 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14924 "xsnabsqp %0,%1"
14925 [(set_attr "type" "vecmove")
14926 (set_attr "size" "128")])
14927
14928 ;; Initially don't worry about doing fusion
14929 (define_insn "fma<mode>4_hw"
14930 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14931 (fma:IEEE128
14932 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14933 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14934 (match_operand:IEEE128 3 "altivec_register_operand" "0")))]
14935 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14936 "xsmaddqp %0,%1,%2"
14937 [(set_attr "type" "qmul")
14938 (set_attr "size" "128")])
14939
14940 (define_insn "*fms<mode>4_hw"
14941 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14942 (fma:IEEE128
14943 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14944 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14945 (neg:IEEE128
14946 (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
14947 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14948 "xsmsubqp %0,%1,%2"
14949 [(set_attr "type" "qmul")
14950 (set_attr "size" "128")])
14951
14952 (define_insn "*nfma<mode>4_hw"
14953 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14954 (neg:IEEE128
14955 (fma:IEEE128
14956 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14957 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14958 (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
14959 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14960 "xsnmaddqp %0,%1,%2"
14961 [(set_attr "type" "qmul")
14962 (set_attr "size" "128")])
14963
14964 (define_insn "*nfms<mode>4_hw"
14965 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14966 (neg:IEEE128
14967 (fma:IEEE128
14968 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14969 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14970 (neg:IEEE128
14971 (match_operand:IEEE128 3 "altivec_register_operand" "0")))))]
14972 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14973 "xsnmsubqp %0,%1,%2"
14974 [(set_attr "type" "qmul")
14975 (set_attr "size" "128")])
14976
14977 (define_insn "extend<SFDF:mode><IEEE128:mode>2_hw"
14978 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14979 (float_extend:IEEE128
14980 (match_operand:SFDF 1 "altivec_register_operand" "v")))]
14981 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14982 "xscvdpqp %0,%1"
14983 [(set_attr "type" "vecfloat")
14984 (set_attr "size" "128")])
14985
14986 ;; Conversion between KFmode and TFmode if TFmode is ieee 128-bit floating
14987 ;; point is a simple copy.
14988 (define_insn_and_split "extendkftf2"
14989 [(set (match_operand:TF 0 "vsx_register_operand" "=wa,?wa")
14990 (float_extend:TF (match_operand:KF 1 "vsx_register_operand" "0,wa")))]
14991 "TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD"
14992 "@
14993 #
14994 xxlor %x0,%x1,%x1"
14995 "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
14996 [(const_int 0)]
14997 {
14998 emit_note (NOTE_INSN_DELETED);
14999 DONE;
15000 }
15001 [(set_attr "type" "*,veclogical")
15002 (set_attr "length" "0,4")])
15003
15004 (define_insn_and_split "trunctfkf2"
15005 [(set (match_operand:KF 0 "vsx_register_operand" "=wa,?wa")
15006 (float_extend:KF (match_operand:TF 1 "vsx_register_operand" "0,wa")))]
15007 "TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD"
15008 "@
15009 #
15010 xxlor %x0,%x1,%x1"
15011 "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
15012 [(const_int 0)]
15013 {
15014 emit_note (NOTE_INSN_DELETED);
15015 DONE;
15016 }
15017 [(set_attr "type" "*,veclogical")
15018 (set_attr "length" "0,4")])
15019
15020 (define_insn "trunc<mode>df2_hw"
15021 [(set (match_operand:DF 0 "altivec_register_operand" "=v")
15022 (float_truncate:DF
15023 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
15024 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
15025 "xscvqpdp %0,%1"
15026 [(set_attr "type" "vecfloat")
15027 (set_attr "size" "128")])
15028
15029 ;; There is no KFmode -> SFmode instruction. Preserve the accuracy by doing
15030 ;; the KFmode -> DFmode conversion using round to odd rather than the normal
15031 ;; conversion
15032 (define_insn_and_split "trunc<mode>sf2_hw"
15033 [(set (match_operand:SF 0 "vsx_register_operand" "=wa")
15034 (float_truncate:SF
15035 (match_operand:IEEE128 1 "altivec_register_operand" "v")))
15036 (clobber (match_scratch:DF 2 "=v"))]
15037 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
15038 "#"
15039 "&& 1"
15040 [(set (match_dup 2)
15041 (unspec:DF [(match_dup 1)]
15042 UNSPEC_TRUNC_ROUND_TO_ODD))
15043 (set (match_dup 0)
15044 (float_truncate:SF (match_dup 2)))]
15045 {
15046 if (GET_CODE (operands[2]) == SCRATCH)
15047 operands[2] = gen_reg_rtx (DFmode);
15048 }
15049 [(set_attr "type" "vecfloat")
15050 (set_attr "length" "8")
15051 (set_attr "isa" "p8v")])
15052
15053 ;; Conversion between IEEE 128-bit and integer types
15054
15055 ;; The fix function for DImode and SImode was declared earlier as a
15056 ;; define_expand. It calls into rs6000_expand_float128_convert if we don't
15057 ;; have IEEE 128-bit hardware support. QImode and HImode are not provided
15058 ;; unless we have the IEEE 128-bit hardware.
15059 ;;
15060 ;; Unlike the code for converting SFmode/DFmode to QImode/HImode, we don't have
15061 ;; to provide a GPR target that used direct move and a conversion in the GPR
15062 ;; which works around QImode/HImode not being allowed in vector registers in
15063 ;; ISA 2.07 (power8).
15064 (define_insn "fix<uns>_<IEEE128:mode><SDI:mode>2_hw"
15065 [(set (match_operand:SDI 0 "altivec_register_operand" "=v")
15066 (any_fix:SDI (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
15067 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
15068 "xscvqp<su><wd>z %0,%1"
15069 [(set_attr "type" "vecfloat")
15070 (set_attr "size" "128")])
15071
15072 (define_insn "fix<uns>_trunc<IEEE128:mode><QHI:mode>2"
15073 [(set (match_operand:QHI 0 "altivec_register_operand" "=v")
15074 (any_fix:QHI
15075 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
15076 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
15077 "xscvqp<su>wz %0,%1"
15078 [(set_attr "type" "vecfloat")
15079 (set_attr "size" "128")])
15080
15081 ;; Combiner patterns to prevent moving the result of converting an IEEE 128-bit
15082 ;; floating point value to 8/16/32-bit integer to GPR in order to save it.
15083 (define_insn_and_split "*fix<uns>_trunc<IEEE128:mode><QHSI:mode>2_mem"
15084 [(set (match_operand:QHSI 0 "memory_operand" "=Z")
15085 (any_fix:QHSI
15086 (match_operand:IEEE128 1 "altivec_register_operand" "v")))
15087 (clobber (match_scratch:QHSI 2 "=v"))]
15088 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
15089 "#"
15090 "&& reload_completed"
15091 [(set (match_dup 2)
15092 (any_fix:QHSI (match_dup 1)))
15093 (set (match_dup 0)
15094 (match_dup 2))])
15095
15096 (define_insn "float_<mode>di2_hw"
15097 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
15098 (float:IEEE128 (match_operand:DI 1 "altivec_register_operand" "v")))]
15099 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
15100 "xscvsdqp %0,%1"
15101 [(set_attr "type" "vecfloat")
15102 (set_attr "size" "128")])
15103
15104 (define_insn_and_split "float_<mode>si2_hw"
15105 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
15106 (float:IEEE128 (match_operand:SI 1 "nonimmediate_operand" "vrZ")))
15107 (clobber (match_scratch:DI 2 "=v"))]
15108 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
15109 "#"
15110 "&& 1"
15111 [(set (match_dup 2)
15112 (sign_extend:DI (match_dup 1)))
15113 (set (match_dup 0)
15114 (float:IEEE128 (match_dup 2)))]
15115 {
15116 if (GET_CODE (operands[2]) == SCRATCH)
15117 operands[2] = gen_reg_rtx (DImode);
15118
15119 if (MEM_P (operands[1]))
15120 operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
15121 })
15122
15123 (define_insn_and_split "float<QHI:mode><IEEE128:mode>2"
15124 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v")
15125 (float:IEEE128 (match_operand:QHI 1 "nonimmediate_operand" "v,r,Z")))
15126 (clobber (match_scratch:DI 2 "=X,r,X"))]
15127 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
15128 "#"
15129 "&& reload_completed"
15130 [(const_int 0)]
15131 {
15132 rtx dest = operands[0];
15133 rtx src = operands[1];
15134 rtx dest_di = gen_rtx_REG (DImode, REGNO (dest));
15135
15136 if (altivec_register_operand (src, <QHI:MODE>mode))
15137 emit_insn (gen_extend<QHI:mode>di2 (dest_di, src));
15138 else if (int_reg_operand (src, <QHI:MODE>mode))
15139 {
15140 rtx ext_di = operands[2];
15141 emit_insn (gen_extend<QHI:mode>di2 (ext_di, src));
15142 emit_move_insn (dest_di, ext_di);
15143 }
15144 else if (MEM_P (src))
15145 {
15146 rtx dest_qhi = gen_rtx_REG (<QHI:MODE>mode, REGNO (dest));
15147 emit_move_insn (dest_qhi, src);
15148 emit_insn (gen_extend<QHI:mode>di2 (dest_di, dest_qhi));
15149 }
15150 else
15151 gcc_unreachable ();
15152
15153 emit_insn (gen_float_<IEEE128:mode>di2_hw (dest, dest_di));
15154 DONE;
15155 }
15156 [(set_attr "length" "8,12,12")
15157 (set_attr "type" "vecfloat")
15158 (set_attr "size" "128")])
15159
15160 (define_insn "floatuns_<mode>di2_hw"
15161 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
15162 (unsigned_float:IEEE128
15163 (match_operand:DI 1 "altivec_register_operand" "v")))]
15164 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
15165 "xscvudqp %0,%1"
15166 [(set_attr "type" "vecfloat")
15167 (set_attr "size" "128")])
15168
15169 (define_insn_and_split "floatuns_<mode>si2_hw"
15170 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
15171 (unsigned_float:IEEE128
15172 (match_operand:SI 1 "nonimmediate_operand" "vrZ")))
15173 (clobber (match_scratch:DI 2 "=v"))]
15174 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
15175 "#"
15176 "&& 1"
15177 [(set (match_dup 2)
15178 (zero_extend:DI (match_dup 1)))
15179 (set (match_dup 0)
15180 (float:IEEE128 (match_dup 2)))]
15181 {
15182 if (GET_CODE (operands[2]) == SCRATCH)
15183 operands[2] = gen_reg_rtx (DImode);
15184
15185 if (MEM_P (operands[1]))
15186 operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
15187 })
15188
15189 (define_insn_and_split "floatuns<QHI:mode><IEEE128:mode>2"
15190 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v")
15191 (unsigned_float:IEEE128
15192 (match_operand:QHI 1 "nonimmediate_operand" "v,r,Z")))
15193 (clobber (match_scratch:DI 2 "=X,r,X"))]
15194 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
15195 "#"
15196 "&& reload_completed"
15197 [(const_int 0)]
15198 {
15199 rtx dest = operands[0];
15200 rtx src = operands[1];
15201 rtx dest_di = gen_rtx_REG (DImode, REGNO (dest));
15202
15203 if (altivec_register_operand (src, <QHI:MODE>mode) || MEM_P (src))
15204 emit_insn (gen_zero_extend<QHI:mode>di2 (dest_di, src));
15205 else if (int_reg_operand (src, <QHI:MODE>mode))
15206 {
15207 rtx ext_di = operands[2];
15208 emit_insn (gen_zero_extend<QHI:mode>di2 (ext_di, src));
15209 emit_move_insn (dest_di, ext_di);
15210 }
15211 else
15212 gcc_unreachable ();
15213
15214 emit_insn (gen_floatuns_<IEEE128:mode>di2_hw (dest, dest_di));
15215 DONE;
15216 }
15217 [(set_attr "length" "8,12,8")
15218 (set_attr "type" "vecfloat")
15219 (set_attr "size" "128")])
15220
15221 ;; IEEE 128-bit round to integer built-in functions
15222 (define_insn "floor<mode>2"
15223 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
15224 (unspec:IEEE128
15225 [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
15226 UNSPEC_FRIM))]
15227 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
15228 "xsrqpi 1,%0,%1,3"
15229 [(set_attr "type" "vecfloat")
15230 (set_attr "size" "128")])
15231
15232 (define_insn "ceil<mode>2"
15233 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
15234 (unspec:IEEE128
15235 [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
15236 UNSPEC_FRIP))]
15237 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
15238 "xsrqpi 1,%0,%1,2"
15239 [(set_attr "type" "vecfloat")
15240 (set_attr "size" "128")])
15241
15242 (define_insn "btrunc<mode>2"
15243 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
15244 (unspec:IEEE128
15245 [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
15246 UNSPEC_FRIZ))]
15247 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
15248 "xsrqpi 1,%0,%1,1"
15249 [(set_attr "type" "vecfloat")
15250 (set_attr "size" "128")])
15251
15252 (define_insn "round<mode>2"
15253 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
15254 (unspec:IEEE128
15255 [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
15256 UNSPEC_FRIN))]
15257 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
15258 "xsrqpi 0,%0,%1,0"
15259 [(set_attr "type" "vecfloat")
15260 (set_attr "size" "128")])
15261
15262 ;; IEEE 128-bit instructions with round to odd semantics
15263 (define_insn "add<mode>3_odd"
15264 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
15265 (unspec:IEEE128
15266 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
15267 (match_operand:IEEE128 2 "altivec_register_operand" "v")]
15268 UNSPEC_ADD_ROUND_TO_ODD))]
15269 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
15270 "xsaddqpo %0,%1,%2"
15271 [(set_attr "type" "vecfloat")
15272 (set_attr "size" "128")])
15273
15274 (define_insn "sub<mode>3_odd"
15275 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
15276 (unspec:IEEE128
15277 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
15278 (match_operand:IEEE128 2 "altivec_register_operand" "v")]
15279 UNSPEC_SUB_ROUND_TO_ODD))]
15280 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
15281 "xssubqpo %0,%1,%2"
15282 [(set_attr "type" "vecfloat")
15283 (set_attr "size" "128")])
15284
15285 (define_insn "mul<mode>3_odd"
15286 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
15287 (unspec:IEEE128
15288 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
15289 (match_operand:IEEE128 2 "altivec_register_operand" "v")]
15290 UNSPEC_MUL_ROUND_TO_ODD))]
15291 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
15292 "xsmulqpo %0,%1,%2"
15293 [(set_attr "type" "qmul")
15294 (set_attr "size" "128")])
15295
15296 (define_insn "div<mode>3_odd"
15297 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
15298 (unspec:IEEE128
15299 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
15300 (match_operand:IEEE128 2 "altivec_register_operand" "v")]
15301 UNSPEC_DIV_ROUND_TO_ODD))]
15302 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
15303 "xsdivqpo %0,%1,%2"
15304 [(set_attr "type" "vecdiv")
15305 (set_attr "size" "128")])
15306
15307 (define_insn "sqrt<mode>2_odd"
15308 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
15309 (unspec:IEEE128
15310 [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
15311 UNSPEC_SQRT_ROUND_TO_ODD))]
15312 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
15313 "xssqrtqpo %0,%1"
15314 [(set_attr "type" "vecdiv")
15315 (set_attr "size" "128")])
15316
15317 (define_insn "fma<mode>4_odd"
15318 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
15319 (unspec:IEEE128
15320 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
15321 (match_operand:IEEE128 2 "altivec_register_operand" "v")
15322 (match_operand:IEEE128 3 "altivec_register_operand" "0")]
15323 UNSPEC_FMA_ROUND_TO_ODD))]
15324 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
15325 "xsmaddqpo %0,%1,%2"
15326 [(set_attr "type" "qmul")
15327 (set_attr "size" "128")])
15328
15329 (define_insn "*fms<mode>4_odd"
15330 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
15331 (unspec:IEEE128
15332 [(match_operand:IEEE128 1 "altivec_register_operand" "%v")
15333 (match_operand:IEEE128 2 "altivec_register_operand" "v")
15334 (neg:IEEE128
15335 (match_operand:IEEE128 3 "altivec_register_operand" "0"))]
15336 UNSPEC_FMA_ROUND_TO_ODD))]
15337 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
15338 "xsmsubqpo %0,%1,%2"
15339 [(set_attr "type" "qmul")
15340 (set_attr "size" "128")])
15341
15342 (define_insn "*nfma<mode>4_odd"
15343 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
15344 (neg:IEEE128
15345 (unspec:IEEE128
15346 [(match_operand:IEEE128 1 "altivec_register_operand" "%v")
15347 (match_operand:IEEE128 2 "altivec_register_operand" "v")
15348 (match_operand:IEEE128 3 "altivec_register_operand" "0")]
15349 UNSPEC_FMA_ROUND_TO_ODD)))]
15350 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
15351 "xsnmaddqpo %0,%1,%2"
15352 [(set_attr "type" "qmul")
15353 (set_attr "size" "128")])
15354
15355 (define_insn "*nfms<mode>4_odd"
15356 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
15357 (neg:IEEE128
15358 (unspec:IEEE128
15359 [(match_operand:IEEE128 1 "altivec_register_operand" "%v")
15360 (match_operand:IEEE128 2 "altivec_register_operand" "v")
15361 (neg:IEEE128
15362 (match_operand:IEEE128 3 "altivec_register_operand" "0"))]
15363 UNSPEC_FMA_ROUND_TO_ODD)))]
15364 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
15365 "xsnmsubqpo %0,%1,%2"
15366 [(set_attr "type" "qmul")
15367 (set_attr "size" "128")])
15368
15369 (define_insn "trunc<mode>df2_odd"
15370 [(set (match_operand:DF 0 "vsx_register_operand" "=v")
15371 (unspec:DF [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
15372 UNSPEC_TRUNC_ROUND_TO_ODD))]
15373 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
15374 "xscvqpdpo %0,%1"
15375 [(set_attr "type" "vecfloat")
15376 (set_attr "size" "128")])
15377
15378 ;; IEEE 128-bit comparisons
15379 (define_insn "*cmp<mode>_hw"
15380 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
15381 (compare:CCFP (match_operand:IEEE128 1 "altivec_register_operand" "v")
15382 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
15383 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
15384 "xscmpuqp %0,%1,%2"
15385 [(set_attr "type" "veccmp")
15386 (set_attr "size" "128")])
15387 \f
15388 ;; Miscellaneous ISA 3.0 (power9) instructions
15389
15390 (define_expand "darn_32_<mode>"
15391 [(use (match_operand:GPR 0 "register_operand"))]
15392 "TARGET_P9_MISC"
15393 {
15394 emit_insn (gen_darn (<MODE>mode, operands[0], const0_rtx));
15395 DONE;
15396 })
15397
15398 (define_expand "darn_64_<mode>"
15399 [(use (match_operand:GPR 0 "register_operand"))]
15400 "TARGET_P9_MISC"
15401 {
15402 emit_insn (gen_darn (<MODE>mode, operands[0], const1_rtx));
15403 DONE;
15404 })
15405
15406 (define_expand "darn_raw_<mode>"
15407 [(use (match_operand:GPR 0 "register_operand"))]
15408 "TARGET_P9_MISC"
15409 {
15410 emit_insn (gen_darn (<MODE>mode, operands[0], const2_rtx));
15411 DONE;
15412 })
15413
15414 (define_insn "@darn<mode>"
15415 [(set (match_operand:GPR 0 "register_operand" "=r")
15416 (unspec_volatile:GPR [(match_operand 1 "const_int_operand" "n")]
15417 UNSPECV_DARN))]
15418 "TARGET_P9_MISC"
15419 "darn %0,%1"
15420 [(set_attr "type" "integer")])
15421
15422 ;; Test byte within range.
15423 ;;
15424 ;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx
15425 ;; represents a byte whose value is ignored in this context and
15426 ;; vv, the least significant byte, holds the byte value that is to
15427 ;; be tested for membership within the range specified by operand 2.
15428 ;; The bytes of operand 2 are organized as xx:xx:hi:lo.
15429 ;;
15430 ;; Return in target register operand 0 a value of 1 if lo <= vv and
15431 ;; vv <= hi. Otherwise, set register operand 0 to 0.
15432 ;;
15433 ;; Though the instructions to which this expansion maps operate on
15434 ;; 64-bit registers, the current implementation only operates on
15435 ;; SI-mode operands as the high-order bits provide no information
15436 ;; that is not already available in the low-order bits. To avoid the
15437 ;; costs of data widening operations, future enhancements might allow
15438 ;; DI mode for operand 0 and/or might allow operand 1 to be QI mode.
15439 (define_expand "cmprb"
15440 [(set (match_dup 3)
15441 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
15442 (match_operand:SI 2 "gpc_reg_operand" "r")]
15443 UNSPEC_CMPRB))
15444 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
15445 (if_then_else:SI (lt (match_dup 3)
15446 (const_int 0))
15447 (const_int -1)
15448 (if_then_else (gt (match_dup 3)
15449 (const_int 0))
15450 (const_int 1)
15451 (const_int 0))))]
15452 "TARGET_P9_MISC"
15453 {
15454 operands[3] = gen_reg_rtx (CCmode);
15455 })
15456
15457 ;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx
15458 ;; represents a byte whose value is ignored in this context and
15459 ;; vv, the least significant byte, holds the byte value that is to
15460 ;; be tested for membership within the range specified by operand 2.
15461 ;; The bytes of operand 2 are organized as xx:xx:hi:lo.
15462 ;;
15463 ;; Set bit 1 (the GT bit, 0x4) of CR register operand 0 to 1 if
15464 ;; lo <= vv and vv <= hi. Otherwise, set the GT bit to 0. The other
15465 ;; 3 bits of the target CR register are all set to 0.
15466 (define_insn "*cmprb_internal"
15467 [(set (match_operand:CC 0 "cc_reg_operand" "=y")
15468 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
15469 (match_operand:SI 2 "gpc_reg_operand" "r")]
15470 UNSPEC_CMPRB))]
15471 "TARGET_P9_MISC"
15472 "cmprb %0,0,%1,%2"
15473 [(set_attr "type" "logical")])
15474
15475 ;; Set operand 0 register to -1 if the LT bit (0x8) of condition
15476 ;; register operand 1 is on. Otherwise, set operand 0 register to 1
15477 ;; if the GT bit (0x4) of condition register operand 1 is on.
15478 ;; Otherwise, set operand 0 to 0. Note that the result stored into
15479 ;; register operand 0 is non-zero iff either the LT or GT bits are on
15480 ;; within condition register operand 1.
15481 (define_insn "setb_signed"
15482 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
15483 (if_then_else:SI (lt (match_operand:CC 1 "cc_reg_operand" "y")
15484 (const_int 0))
15485 (const_int -1)
15486 (if_then_else (gt (match_dup 1)
15487 (const_int 0))
15488 (const_int 1)
15489 (const_int 0))))]
15490 "TARGET_P9_MISC"
15491 "setb %0,%1"
15492 [(set_attr "type" "logical")])
15493
15494 (define_insn "setb_unsigned"
15495 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
15496 (if_then_else:SI (ltu (match_operand:CCUNS 1 "cc_reg_operand" "y")
15497 (const_int 0))
15498 (const_int -1)
15499 (if_then_else (gtu (match_dup 1)
15500 (const_int 0))
15501 (const_int 1)
15502 (const_int 0))))]
15503 "TARGET_P9_MISC"
15504 "setb %0,%1"
15505 [(set_attr "type" "logical")])
15506
15507 ;; Test byte within two ranges.
15508 ;;
15509 ;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx
15510 ;; represents a byte whose value is ignored in this context and
15511 ;; vv, the least significant byte, holds the byte value that is to
15512 ;; be tested for membership within the range specified by operand 2.
15513 ;; The bytes of operand 2 are organized as hi_1:lo_1:hi_2:lo_2.
15514 ;;
15515 ;; Return in target register operand 0 a value of 1 if (lo_1 <= vv and
15516 ;; vv <= hi_1) or if (lo_2 <= vv and vv <= hi_2). Otherwise, set register
15517 ;; operand 0 to 0.
15518 ;;
15519 ;; Though the instructions to which this expansion maps operate on
15520 ;; 64-bit registers, the current implementation only operates on
15521 ;; SI-mode operands as the high-order bits provide no information
15522 ;; that is not already available in the low-order bits. To avoid the
15523 ;; costs of data widening operations, future enhancements might allow
15524 ;; DI mode for operand 0 and/or might allow operand 1 to be QI mode.
15525 (define_expand "cmprb2"
15526 [(set (match_dup 3)
15527 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
15528 (match_operand:SI 2 "gpc_reg_operand" "r")]
15529 UNSPEC_CMPRB2))
15530 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
15531 (if_then_else:SI (lt (match_dup 3)
15532 (const_int 0))
15533 (const_int -1)
15534 (if_then_else (gt (match_dup 3)
15535 (const_int 0))
15536 (const_int 1)
15537 (const_int 0))))]
15538 "TARGET_P9_MISC"
15539 {
15540 operands[3] = gen_reg_rtx (CCmode);
15541 })
15542
15543 ;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx
15544 ;; represents a byte whose value is ignored in this context and
15545 ;; vv, the least significant byte, holds the byte value that is to
15546 ;; be tested for membership within the ranges specified by operand 2.
15547 ;; The bytes of operand 2 are organized as hi_1:lo_1:hi_2:lo_2.
15548 ;;
15549 ;; Set bit 1 (the GT bit, 0x4) of CR register operand 0 to 1 if
15550 ;; (lo_1 <= vv and vv <= hi_1) or if (lo_2 <= vv and vv <= hi_2).
15551 ;; Otherwise, set the GT bit to 0. The other 3 bits of the target
15552 ;; CR register are all set to 0.
15553 (define_insn "*cmprb2_internal"
15554 [(set (match_operand:CC 0 "cc_reg_operand" "=y")
15555 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
15556 (match_operand:SI 2 "gpc_reg_operand" "r")]
15557 UNSPEC_CMPRB2))]
15558 "TARGET_P9_MISC"
15559 "cmprb %0,1,%1,%2"
15560 [(set_attr "type" "logical")])
15561
15562 ;; Test byte membership within set of 8 bytes.
15563 ;;
15564 ;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx
15565 ;; represents a byte whose value is ignored in this context and
15566 ;; vv, the least significant byte, holds the byte value that is to
15567 ;; be tested for membership within the set specified by operand 2.
15568 ;; The bytes of operand 2 are organized as e0:e1:e2:e3:e4:e5:e6:e7.
15569 ;;
15570 ;; Return in target register operand 0 a value of 1 if vv equals one
15571 ;; of the values e0, e1, e2, e3, e4, e5, e6, or e7. Otherwise, set
15572 ;; register operand 0 to 0. Note that the 8 byte values held within
15573 ;; operand 2 need not be unique.
15574 ;;
15575 ;; Though the instructions to which this expansion maps operate on
15576 ;; 64-bit registers, the current implementation requires that operands
15577 ;; 0 and 1 have mode SI as the high-order bits provide no information
15578 ;; that is not already available in the low-order bits. To avoid the
15579 ;; costs of data widening operations, future enhancements might allow
15580 ;; DI mode for operand 0 and/or might allow operand 1 to be QI mode.
15581 (define_expand "cmpeqb"
15582 [(set (match_dup 3)
15583 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
15584 (match_operand:DI 2 "gpc_reg_operand" "r")]
15585 UNSPEC_CMPEQB))
15586 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
15587 (if_then_else:SI (lt (match_dup 3)
15588 (const_int 0))
15589 (const_int -1)
15590 (if_then_else (gt (match_dup 3)
15591 (const_int 0))
15592 (const_int 1)
15593 (const_int 0))))]
15594 "TARGET_P9_MISC && TARGET_64BIT"
15595 {
15596 operands[3] = gen_reg_rtx (CCmode);
15597 })
15598
15599 ;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx
15600 ;; represents a byte whose value is ignored in this context and
15601 ;; vv, the least significant byte, holds the byte value that is to
15602 ;; be tested for membership within the set specified by operand 2.
15603 ;; The bytes of operand 2 are organized as e0:e1:e2:e3:e4:e5:e6:e7.
15604 ;;
15605 ;; Set bit 1 (the GT bit, 0x4) of CR register operand 0 to 1 if vv
15606 ;; equals one of the values e0, e1, e2, e3, e4, e5, e6, or e7. Otherwise,
15607 ;; set the GT bit to zero. The other 3 bits of the target CR register
15608 ;; are all set to 0.
15609 (define_insn "*cmpeqb_internal"
15610 [(set (match_operand:CC 0 "cc_reg_operand" "=y")
15611 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
15612 (match_operand:DI 2 "gpc_reg_operand" "r")]
15613 UNSPEC_CMPEQB))]
15614 "TARGET_P9_MISC && TARGET_64BIT"
15615 "cmpeqb %0,%1,%2"
15616 [(set_attr "type" "logical")])
15617
15618
15619 ;; ROP mitigation instructions.
15620
15621 (define_insn "hashst"
15622 [(set (match_operand:DI 0 "simple_offsettable_mem_operand" "=m")
15623 (unspec_volatile:DI [(match_operand:DI 1 "int_reg_operand" "r")]
15624 UNSPEC_HASHST))]
15625 "TARGET_POWER10 && rs6000_rop_protect"
15626 {
15627 static char templ[32];
15628 const char *p = rs6000_privileged ? "p" : "";
15629 sprintf (templ, "hashst%s %%1,%%0", p);
15630 return templ;
15631 }
15632 [(set_attr "type" "store")])
15633
15634 (define_insn "hashchk"
15635 [(unspec_volatile [(match_operand:DI 0 "int_reg_operand" "r")
15636 (match_operand:DI 1 "simple_offsettable_mem_operand" "m")]
15637 UNSPEC_HASHCHK)]
15638 "TARGET_POWER10 && rs6000_rop_protect"
15639 {
15640 static char templ[32];
15641 const char *p = rs6000_privileged ? "p" : "";
15642 sprintf (templ, "hashchk%s %%0,%%1", p);
15643 return templ;
15644 }
15645 [(set_attr "type" "load")])
15646 \f
15647
15648 (include "sync.md")
15649 (include "vector.md")
15650 (include "vsx.md")
15651 (include "altivec.md")
15652 (include "mma.md")
15653 (include "dfp.md")
15654 (include "crypto.md")
15655 (include "htm.md")
15656 (include "fusion.md")
15657 (include "pcrel-opt.md")
This page took 0.707498 seconds and 6 git commands to generate.