]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/config/rs6000/rs6000.md
Update copyright years.
[thirdparty/gcc.git] / gcc / config / rs6000 / rs6000.md
1 ;; Machine description for IBM RISC System 6000 (POWER) for GNU C compiler
2 ;; Copyright (C) 1990-2019 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 (LR_REGNO 65)
37 (CTR_REGNO 66)
38 (ARG_POINTER_REGNUM 67)
39 (CR0_REGNO 68)
40 (CR1_REGNO 69)
41 (CR2_REGNO 70)
42 (CR3_REGNO 71)
43 (CR4_REGNO 72)
44 (CR5_REGNO 73)
45 (CR6_REGNO 74)
46 (CR7_REGNO 75)
47 (MAX_CR_REGNO 75)
48 (CA_REGNO 76)
49 (FIRST_ALTIVEC_REGNO 77)
50 (LAST_ALTIVEC_REGNO 108)
51 (VRSAVE_REGNO 109)
52 (VSCR_REGNO 110)
53 (FRAME_POINTER_REGNUM 111)
54 (TFHAR_REGNO 112)
55 (TFIAR_REGNO 113)
56 (TEXASR_REGNO 114)
57 ])
58
59 ;;
60 ;; UNSPEC usage
61 ;;
62
63 (define_c_enum "unspec"
64 [UNSPEC_FRSP ; frsp for POWER machines
65 UNSPEC_PROBE_STACK ; probe stack memory reference
66 UNSPEC_TOCPTR ; address of a word pointing to the TOC
67 UNSPEC_TOC ; address of the TOC (more-or-less)
68 UNSPEC_TOCSLOT ; offset from r1 of toc pointer save slot
69 UNSPEC_MOVSI_GOT
70 UNSPEC_MV_CR_OV ; move_from_CR_ov_bit
71 UNSPEC_FCTIWZ
72 UNSPEC_FRIM
73 UNSPEC_FRIN
74 UNSPEC_FRIP
75 UNSPEC_FRIZ
76 UNSPEC_XSRDPI
77 UNSPEC_LD_MPIC ; load_macho_picbase
78 UNSPEC_RELD_MPIC ; re-load_macho_picbase
79 UNSPEC_MPIC_CORRECT ; macho_correct_pic
80 UNSPEC_TLSGD
81 UNSPEC_TLSLD
82 UNSPEC_MOVESI_FROM_CR
83 UNSPEC_MOVESI_TO_CR
84 UNSPEC_TLSDTPREL
85 UNSPEC_TLSDTPRELHA
86 UNSPEC_TLSDTPRELLO
87 UNSPEC_TLSGOTDTPREL
88 UNSPEC_TLSTPREL
89 UNSPEC_TLSTPRELHA
90 UNSPEC_TLSTPRELLO
91 UNSPEC_TLSGOTTPREL
92 UNSPEC_TLSTLS
93 UNSPEC_FIX_TRUNC_TF ; fadd, rounding towards zero
94 UNSPEC_STFIWX
95 UNSPEC_POPCNTB
96 UNSPEC_FRES
97 UNSPEC_SP_SET
98 UNSPEC_SP_TEST
99 UNSPEC_SYNC
100 UNSPEC_LWSYNC
101 UNSPEC_SYNC_OP
102 UNSPEC_ATOMIC
103 UNSPEC_CMPXCHG
104 UNSPEC_XCHG
105 UNSPEC_AND
106 UNSPEC_DLMZB
107 UNSPEC_DLMZB_CR
108 UNSPEC_DLMZB_STRLEN
109 UNSPEC_RSQRT
110 UNSPEC_TOCREL
111 UNSPEC_MACHOPIC_OFFSET
112 UNSPEC_BPERM
113 UNSPEC_COPYSIGN
114 UNSPEC_PARITY
115 UNSPEC_CMPB
116 UNSPEC_FCTIW
117 UNSPEC_FCTID
118 UNSPEC_LFIWAX
119 UNSPEC_LFIWZX
120 UNSPEC_FCTIWUZ
121 UNSPEC_NOP
122 UNSPEC_GRP_END_NOP
123 UNSPEC_P8V_FMRGOW
124 UNSPEC_P8V_MTVSRWZ
125 UNSPEC_P8V_RELOAD_FROM_GPR
126 UNSPEC_P8V_MTVSRD
127 UNSPEC_P8V_XXPERMDI
128 UNSPEC_P8V_RELOAD_FROM_VSX
129 UNSPEC_ADDG6S
130 UNSPEC_CDTBCD
131 UNSPEC_CBCDTD
132 UNSPEC_DIVE
133 UNSPEC_DIVEU
134 UNSPEC_UNPACK_128BIT
135 UNSPEC_PACK_128BIT
136 UNSPEC_LSQ
137 UNSPEC_FUSION_GPR
138 UNSPEC_STACK_CHECK
139 UNSPEC_ADD_ROUND_TO_ODD
140 UNSPEC_SUB_ROUND_TO_ODD
141 UNSPEC_MUL_ROUND_TO_ODD
142 UNSPEC_DIV_ROUND_TO_ODD
143 UNSPEC_FMA_ROUND_TO_ODD
144 UNSPEC_SQRT_ROUND_TO_ODD
145 UNSPEC_TRUNC_ROUND_TO_ODD
146 UNSPEC_SIGNBIT
147 UNSPEC_SF_FROM_SI
148 UNSPEC_SI_FROM_SF
149 UNSPEC_PLTSEQ
150 UNSPEC_PLT16_HA
151 UNSPEC_PLT16_LO
152 ])
153
154 ;;
155 ;; UNSPEC_VOLATILE usage
156 ;;
157
158 (define_c_enum "unspecv"
159 [UNSPECV_BLOCK
160 UNSPECV_LL ; load-locked
161 UNSPECV_SC ; store-conditional
162 UNSPECV_PROBE_STACK_RANGE ; probe range of stack addresses
163 UNSPECV_EH_RR ; eh_reg_restore
164 UNSPECV_ISYNC ; isync instruction
165 UNSPECV_MFTB ; move from time base
166 UNSPECV_NLGR ; non-local goto receiver
167 UNSPECV_MFFS ; Move from FPSCR
168 UNSPECV_MFFSL ; Move from FPSCR light instruction version
169 UNSPECV_MFFSCRN ; Move from FPSCR float rounding mode
170 UNSPECV_MFFSCDRN ; Move from FPSCR decimal float rounding mode
171 UNSPECV_MTFSF ; Move to FPSCR Fields 8 to 15
172 UNSPECV_MTFSF_HI ; Move to FPSCR Fields 0 to 7
173 UNSPECV_MTFSB0 ; Set FPSCR Field bit to 0
174 UNSPECV_MTFSB1 ; Set FPSCR Field bit to 1
175 UNSPECV_SPLIT_STACK_RETURN ; A camouflaged return
176 UNSPECV_SPEC_BARRIER ; Speculation barrier
177 ])
178
179 \f
180 ;; Define an insn type attribute. This is used in function unit delay
181 ;; computations.
182 (define_attr "type"
183 "integer,two,three,
184 add,logical,shift,insert,
185 mul,halfmul,div,
186 exts,cntlz,popcnt,isel,
187 load,store,fpload,fpstore,vecload,vecstore,
188 cmp,
189 branch,jmpreg,mfjmpr,mtjmpr,trap,isync,sync,load_l,store_c,
190 cr_logical,mfcr,mfcrf,mtcr,
191 fpcompare,fp,fpsimple,dmul,qmul,sdiv,ddiv,ssqrt,dsqrt,
192 vecsimple,veccomplex,vecdiv,veccmp,veccmpsimple,vecperm,
193 vecfloat,vecfdiv,vecdouble,mffgpr,mftgpr,crypto,
194 veclogical,veccmpfx,vecexts,vecmove,
195 htm,htmsimple,dfp"
196 (const_string "integer"))
197
198 ;; What data size does this instruction work on?
199 ;; This is used for insert, mul and others as necessary.
200 (define_attr "size" "8,16,32,64,128" (const_string "32"))
201
202 ;; What is the insn_cost for this insn? The target hook can still override
203 ;; this. For optimizing for size the "length" attribute is used instead.
204 (define_attr "cost" "" (const_int 0))
205
206 ;; Is this instruction record form ("dot", signed compare to 0, writing CR0)?
207 ;; This is used for add, logical, shift, exts, mul.
208 (define_attr "dot" "no,yes" (const_string "no"))
209
210 ;; Does this instruction sign-extend its result?
211 ;; This is used for load insns.
212 (define_attr "sign_extend" "no,yes" (const_string "no"))
213
214 ;; Does this cr_logical instruction have three operands? That is, BT != BB.
215 (define_attr "cr_logical_3op" "no,yes" (const_string "no"))
216
217 ;; Does this instruction use indexed (that is, reg+reg) addressing?
218 ;; This is used for load and store insns. If operand 0 or 1 is a MEM
219 ;; it is automatically set based on that. If a load or store instruction
220 ;; has fewer than two operands it needs to set this attribute manually
221 ;; or the compiler will crash.
222 (define_attr "indexed" "no,yes"
223 (if_then_else (ior (match_operand 0 "indexed_address_mem")
224 (match_operand 1 "indexed_address_mem"))
225 (const_string "yes")
226 (const_string "no")))
227
228 ;; Does this instruction use update addressing?
229 ;; This is used for load and store insns. See the comments for "indexed".
230 (define_attr "update" "no,yes"
231 (if_then_else (ior (match_operand 0 "update_address_mem")
232 (match_operand 1 "update_address_mem"))
233 (const_string "yes")
234 (const_string "no")))
235
236 ;; Is this instruction using operands[2] as shift amount, and can that be a
237 ;; register?
238 ;; This is used for shift insns.
239 (define_attr "maybe_var_shift" "no,yes" (const_string "no"))
240
241 ;; Is this instruction using a shift amount from a register?
242 ;; This is used for shift insns.
243 (define_attr "var_shift" "no,yes"
244 (if_then_else (and (eq_attr "type" "shift")
245 (eq_attr "maybe_var_shift" "yes"))
246 (if_then_else (match_operand 2 "gpc_reg_operand")
247 (const_string "yes")
248 (const_string "no"))
249 (const_string "no")))
250
251 ;; Is copying of this instruction disallowed?
252 (define_attr "cannot_copy" "no,yes" (const_string "no"))
253
254 ;; Length of the instruction (in bytes).
255 (define_attr "length" "" (const_int 4))
256
257 ;; Processor type -- this attribute must exactly match the processor_type
258 ;; enumeration in rs6000-opts.h.
259 (define_attr "cpu"
260 "ppc601,ppc603,ppc604,ppc604e,ppc620,ppc630,
261 ppc750,ppc7400,ppc7450,
262 ppc403,ppc405,ppc440,ppc476,
263 ppc8540,ppc8548,ppce300c2,ppce300c3,ppce500mc,ppce500mc64,ppce5500,ppce6500,
264 power4,power5,power6,power7,power8,power9,
265 rs64a,mpccore,cell,ppca2,titan"
266 (const (symbol_ref "(enum attr_cpu) rs6000_tune")))
267
268
269 ;; If this instruction is microcoded on the CELL processor
270 ; The default for load extended, the recorded instructions and rotate/shifts by a variable is always microcoded
271 (define_attr "cell_micro" "not,conditional,always"
272 (if_then_else (ior (and (eq_attr "type" "shift,exts,mul")
273 (eq_attr "dot" "yes"))
274 (and (eq_attr "type" "load")
275 (eq_attr "sign_extend" "yes"))
276 (and (eq_attr "type" "shift")
277 (eq_attr "var_shift" "yes")))
278 (const_string "always")
279 (const_string "not")))
280
281 (automata_option "ndfa")
282
283 (include "rs64.md")
284 (include "mpc.md")
285 (include "40x.md")
286 (include "440.md")
287 (include "476.md")
288 (include "601.md")
289 (include "603.md")
290 (include "6xx.md")
291 (include "7xx.md")
292 (include "7450.md")
293 (include "8540.md")
294 (include "e300c2c3.md")
295 (include "e500mc.md")
296 (include "e500mc64.md")
297 (include "e5500.md")
298 (include "e6500.md")
299 (include "power4.md")
300 (include "power5.md")
301 (include "power6.md")
302 (include "power7.md")
303 (include "power8.md")
304 (include "power9.md")
305 (include "cell.md")
306 (include "a2.md")
307 (include "titan.md")
308
309 (include "predicates.md")
310 (include "constraints.md")
311
312 (include "darwin.md")
313
314 \f
315 ;; Mode iterators
316
317 ; This mode iterator allows :GPR to be used to indicate the allowable size
318 ; of whole values in GPRs.
319 (define_mode_iterator GPR [SI (DI "TARGET_POWERPC64")])
320
321 ; And again, for patterns that need two (potentially) different integer modes.
322 (define_mode_iterator GPR2 [SI (DI "TARGET_POWERPC64")])
323
324 ; Any supported integer mode.
325 (define_mode_iterator INT [QI HI SI DI TI PTI])
326
327 ; Any supported integer mode that fits in one register.
328 (define_mode_iterator INT1 [QI HI SI (DI "TARGET_POWERPC64")])
329
330 ; Integer modes supported in VSX registers with ISA 3.0 instructions
331 (define_mode_iterator INT_ISA3 [QI HI SI DI])
332
333 ; Everything we can extend QImode to.
334 (define_mode_iterator EXTQI [SI (DI "TARGET_POWERPC64")])
335
336 ; Everything we can extend HImode to.
337 (define_mode_iterator EXTHI [SI (DI "TARGET_POWERPC64")])
338
339 ; Everything we can extend SImode to.
340 (define_mode_iterator EXTSI [(DI "TARGET_POWERPC64")])
341
342 ; QImode or HImode for small integer moves and small atomic ops
343 (define_mode_iterator QHI [QI HI])
344
345 ; QImode, HImode, SImode for fused ops only for GPR loads
346 (define_mode_iterator QHSI [QI HI SI])
347
348 ; HImode or SImode for sign extended fusion ops
349 (define_mode_iterator HSI [HI SI])
350
351 ; SImode or DImode, even if DImode doesn't fit in GPRs.
352 (define_mode_iterator SDI [SI DI])
353
354 ; The size of a pointer. Also, the size of the value that a record-condition
355 ; (one with a '.') will compare; and the size used for arithmetic carries.
356 (define_mode_iterator P [(SI "TARGET_32BIT") (DI "TARGET_64BIT")])
357
358 ; Iterator to add PTImode along with TImode (TImode can go in VSX registers,
359 ; PTImode is GPR only)
360 (define_mode_iterator TI2 [TI PTI])
361
362 ; Any hardware-supported floating-point mode
363 (define_mode_iterator FP [
364 (SF "TARGET_HARD_FLOAT")
365 (DF "TARGET_HARD_FLOAT")
366 (TF "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128")
367 (IF "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128")
368 (KF "TARGET_FLOAT128_TYPE")
369 (DD "TARGET_DFP")
370 (TD "TARGET_DFP")])
371
372 ; Any fma capable floating-point mode.
373 (define_mode_iterator FMA_F [
374 (SF "TARGET_HARD_FLOAT")
375 (DF "TARGET_HARD_FLOAT || VECTOR_UNIT_VSX_P (DFmode)")
376 (V4SF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)")
377 (V2DF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V2DFmode)")
378 (KF "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (KFmode)")
379 (TF "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (TFmode)")
380 ])
381
382 ; Floating point move iterators to combine binary and decimal moves
383 (define_mode_iterator FMOVE32 [SF SD])
384 (define_mode_iterator FMOVE64 [DF DD])
385 (define_mode_iterator FMOVE64X [DI DF DD])
386 (define_mode_iterator FMOVE128 [(TF "TARGET_LONG_DOUBLE_128")
387 (IF "FLOAT128_IBM_P (IFmode)")
388 (TD "TARGET_HARD_FLOAT")])
389
390 (define_mode_iterator FMOVE128_FPR [(TF "FLOAT128_2REG_P (TFmode)")
391 (IF "FLOAT128_2REG_P (IFmode)")
392 (TD "TARGET_HARD_FLOAT")])
393
394 ; Iterators for 128 bit types for direct move
395 (define_mode_iterator FMOVE128_GPR [TI
396 V16QI
397 V8HI
398 V4SI
399 V4SF
400 V2DI
401 V2DF
402 V1TI
403 (KF "FLOAT128_VECTOR_P (KFmode)")
404 (TF "FLOAT128_VECTOR_P (TFmode)")])
405
406 ; Iterator for 128-bit VSX types for pack/unpack
407 (define_mode_iterator FMOVE128_VSX [V1TI KF])
408
409 ; Iterators for converting to/from TFmode
410 (define_mode_iterator IFKF [IF KF])
411
412 ; Constraints for moving IF/KFmode.
413 (define_mode_attr IFKF_reg [(IF "d") (KF "wa")])
414
415 ; Whether a floating point move is ok, don't allow SD without hardware FP
416 (define_mode_attr fmove_ok [(SF "")
417 (DF "")
418 (SD "TARGET_HARD_FLOAT")
419 (DD "")])
420
421 ; Convert REAL_VALUE to the appropriate bits
422 (define_mode_attr real_value_to_target [(SF "REAL_VALUE_TO_TARGET_SINGLE")
423 (DF "REAL_VALUE_TO_TARGET_DOUBLE")
424 (SD "REAL_VALUE_TO_TARGET_DECIMAL32")
425 (DD "REAL_VALUE_TO_TARGET_DECIMAL64")])
426
427 ; Whether 0.0 has an all-zero bit pattern
428 (define_mode_attr zero_fp [(SF "j")
429 (DF "j")
430 (TF "j")
431 (IF "j")
432 (KF "j")
433 (SD "wn")
434 (DD "wn")
435 (TD "wn")])
436
437 ; Definitions for 64-bit VSX
438 (define_mode_attr f64_vsx [(DF "ws") (DD "wn")])
439
440 ; Definitions for 64-bit direct move
441 (define_mode_attr f64_dm [(DF "wk") (DD "wh")])
442
443 ; Definitions for 64-bit use of altivec registers
444 (define_mode_attr f64_av [(DF "wv") (DD "wn")])
445
446 ; Definitions for 64-bit access to ISA 3.0 (power9) vector
447 (define_mode_attr f64_p9 [(DF "wb") (DD "wn")])
448
449 ; These modes do not fit in integer registers in 32-bit mode.
450 (define_mode_iterator DIFD [DI DF DD])
451
452 ; Iterator for reciprocal estimate instructions
453 (define_mode_iterator RECIPF [SF DF V4SF V2DF])
454
455 ; Iterator for just SF/DF
456 (define_mode_iterator SFDF [SF DF])
457
458 ; Like SFDF, but a different name to match conditional move where the
459 ; comparison operands may be a different mode than the input operands.
460 (define_mode_iterator SFDF2 [SF DF])
461
462 ; Iterator for 128-bit floating point that uses the IBM double-double format
463 (define_mode_iterator IBM128 [(IF "FLOAT128_IBM_P (IFmode)")
464 (TF "FLOAT128_IBM_P (TFmode)")])
465
466 ; Iterator for 128-bit floating point that uses IEEE 128-bit float
467 (define_mode_iterator IEEE128 [(KF "FLOAT128_IEEE_P (KFmode)")
468 (TF "FLOAT128_IEEE_P (TFmode)")])
469
470 ; Iterator for 128-bit floating point
471 (define_mode_iterator FLOAT128 [(KF "TARGET_FLOAT128_TYPE")
472 (IF "TARGET_FLOAT128_TYPE")
473 (TF "TARGET_LONG_DOUBLE_128")])
474
475 ; Iterator for signbit on 64-bit machines with direct move
476 (define_mode_iterator SIGNBIT [(KF "FLOAT128_VECTOR_P (KFmode)")
477 (TF "FLOAT128_VECTOR_P (TFmode)")])
478
479 ; Iterator for ISA 3.0 supported floating point types
480 (define_mode_iterator FP_ISA3 [SF DF])
481
482 ; SF/DF suffix for traditional floating instructions
483 (define_mode_attr Ftrad [(SF "s") (DF "")])
484
485 ; SF/DF suffix for VSX instructions
486 (define_mode_attr Fvsx [(SF "sp") (DF "dp")])
487
488 ; SF/DF constraint for arithmetic on traditional floating point registers
489 (define_mode_attr Ff [(SF "f") (DF "d") (DI "d")])
490
491 ; SF/DF constraint for arithmetic on VSX registers using instructions added in
492 ; ISA 2.06 (power7). This includes instructions that normally target DF mode,
493 ; but are used on SFmode, since internally SFmode values are kept in the DFmode
494 ; format.
495 (define_mode_attr Fv [(SF "ww") (DF "ws") (DI "wi")])
496
497 ; SF/DF constraint for arithmetic on VSX registers. This is intended to be
498 ; used for DFmode instructions added in ISA 2.06 (power7) and SFmode
499 ; instructions added in ISA 2.07 (power8)
500 (define_mode_attr Fv2 [(SF "wy") (DF "ws") (DI "wi")])
501
502 ; SF/DF constraint for arithmetic on altivec registers
503 (define_mode_attr Fa [(SF "wu") (DF "wv")])
504
505 ; s/d suffix for things like sdiv/ddiv
506 (define_mode_attr Fs [(SF "s") (DF "d")])
507
508 ; FRE/FRES support
509 (define_mode_attr Ffre [(SF "fres") (DF "fre")])
510 (define_mode_attr FFRE [(SF "FRES") (DF "FRE")])
511
512 ; Conditional returns.
513 (define_code_iterator any_return [return simple_return])
514 (define_code_attr return_pred [(return "direct_return ()")
515 (simple_return "1")])
516 (define_code_attr return_str [(return "") (simple_return "simple_")])
517
518 ; Logical operators.
519 (define_code_iterator iorxor [ior xor])
520 (define_code_iterator and_ior_xor [and ior xor])
521
522 ; Signed/unsigned variants of ops.
523 (define_code_iterator any_extend [sign_extend zero_extend])
524 (define_code_iterator any_fix [fix unsigned_fix])
525 (define_code_iterator any_float [float unsigned_float])
526
527 (define_code_attr u [(sign_extend "")
528 (zero_extend "u")
529 (fix "")
530 (unsigned_fix "u")])
531
532 (define_code_attr su [(sign_extend "s")
533 (zero_extend "u")
534 (fix "s")
535 (unsigned_fix "u")
536 (float "s")
537 (unsigned_float "u")])
538
539 (define_code_attr az [(sign_extend "a")
540 (zero_extend "z")
541 (fix "a")
542 (unsigned_fix "z")
543 (float "a")
544 (unsigned_float "z")])
545
546 (define_code_attr uns [(fix "")
547 (unsigned_fix "uns")
548 (float "")
549 (unsigned_float "uns")])
550
551 ; Various instructions that come in SI and DI forms.
552 ; A generic w/d attribute, for things like cmpw/cmpd.
553 (define_mode_attr wd [(QI "b")
554 (HI "h")
555 (SI "w")
556 (DI "d")
557 (V16QI "b")
558 (V8HI "h")
559 (V4SI "w")
560 (V2DI "d")
561 (V1TI "q")
562 (TI "q")])
563
564 ;; How many bits in this mode?
565 (define_mode_attr bits [(QI "8") (HI "16") (SI "32") (DI "64")])
566
567 ; DImode bits
568 (define_mode_attr dbits [(QI "56") (HI "48") (SI "32")])
569
570 ;; Bitmask for shift instructions
571 (define_mode_attr hH [(SI "h") (DI "H")])
572
573 ;; A mode twice the size of the given mode
574 (define_mode_attr dmode [(SI "di") (DI "ti")])
575 (define_mode_attr DMODE [(SI "DI") (DI "TI")])
576
577 ;; Suffix for reload patterns
578 (define_mode_attr ptrsize [(SI "32bit")
579 (DI "64bit")])
580
581 (define_mode_attr tptrsize [(SI "TARGET_32BIT")
582 (DI "TARGET_64BIT")])
583
584 (define_mode_attr mptrsize [(SI "si")
585 (DI "di")])
586
587 (define_mode_attr ptrload [(SI "lwz")
588 (DI "ld")])
589
590 (define_mode_attr ptrm [(SI "m")
591 (DI "Y")])
592
593 (define_mode_attr rreg [(SF "f")
594 (DF "ws")
595 (TF "f")
596 (TD "f")
597 (V4SF "wf")
598 (V2DF "wd")])
599
600 (define_mode_attr rreg2 [(SF "f")
601 (DF "d")])
602
603 (define_mode_attr SI_CONVERT_FP [(SF "TARGET_FCFIDS")
604 (DF "TARGET_FCFID")])
605
606 ;; Mode iterator for logical operations on 128-bit types
607 (define_mode_iterator BOOL_128 [TI
608 PTI
609 (V16QI "TARGET_ALTIVEC")
610 (V8HI "TARGET_ALTIVEC")
611 (V4SI "TARGET_ALTIVEC")
612 (V4SF "TARGET_ALTIVEC")
613 (V2DI "TARGET_ALTIVEC")
614 (V2DF "TARGET_ALTIVEC")
615 (V1TI "TARGET_ALTIVEC")])
616
617 ;; For the GPRs we use 3 constraints for register outputs, two that are the
618 ;; same as the output register, and a third where the output register is an
619 ;; early clobber, so we don't have to deal with register overlaps. For the
620 ;; vector types, we prefer to use the vector registers. For TI mode, allow
621 ;; either.
622
623 ;; Mode attribute for boolean operation register constraints for output
624 (define_mode_attr BOOL_REGS_OUTPUT [(TI "&r,r,r,wt,v")
625 (PTI "&r,r,r")
626 (V16QI "wa,v,&?r,?r,?r")
627 (V8HI "wa,v,&?r,?r,?r")
628 (V4SI "wa,v,&?r,?r,?r")
629 (V4SF "wa,v,&?r,?r,?r")
630 (V2DI "wa,v,&?r,?r,?r")
631 (V2DF "wa,v,&?r,?r,?r")
632 (V1TI "wa,v,&?r,?r,?r")])
633
634 ;; Mode attribute for boolean operation register constraints for operand1
635 (define_mode_attr BOOL_REGS_OP1 [(TI "r,0,r,wt,v")
636 (PTI "r,0,r")
637 (V16QI "wa,v,r,0,r")
638 (V8HI "wa,v,r,0,r")
639 (V4SI "wa,v,r,0,r")
640 (V4SF "wa,v,r,0,r")
641 (V2DI "wa,v,r,0,r")
642 (V2DF "wa,v,r,0,r")
643 (V1TI "wa,v,r,0,r")])
644
645 ;; Mode attribute for boolean operation register constraints for operand2
646 (define_mode_attr BOOL_REGS_OP2 [(TI "r,r,0,wt,v")
647 (PTI "r,r,0")
648 (V16QI "wa,v,r,r,0")
649 (V8HI "wa,v,r,r,0")
650 (V4SI "wa,v,r,r,0")
651 (V4SF "wa,v,r,r,0")
652 (V2DI "wa,v,r,r,0")
653 (V2DF "wa,v,r,r,0")
654 (V1TI "wa,v,r,r,0")])
655
656 ;; Mode attribute for boolean operation register constraints for operand1
657 ;; for one_cmpl. To simplify things, we repeat the constraint where 0
658 ;; is used for operand1 or operand2
659 (define_mode_attr BOOL_REGS_UNARY [(TI "r,0,0,wt,v")
660 (PTI "r,0,0")
661 (V16QI "wa,v,r,0,0")
662 (V8HI "wa,v,r,0,0")
663 (V4SI "wa,v,r,0,0")
664 (V4SF "wa,v,r,0,0")
665 (V2DI "wa,v,r,0,0")
666 (V2DF "wa,v,r,0,0")
667 (V1TI "wa,v,r,0,0")])
668
669 ;; Reload iterator for creating the function to allocate a base register to
670 ;; supplement addressing modes.
671 (define_mode_iterator RELOAD [V16QI V8HI V4SI V2DI V4SF V2DF V1TI
672 SF SD SI DF DD DI TI PTI KF IF TF])
673
674 ;; Iterate over smin, smax
675 (define_code_iterator fp_minmax [smin smax])
676
677 (define_code_attr minmax [(smin "min")
678 (smax "max")])
679
680 (define_code_attr SMINMAX [(smin "SMIN")
681 (smax "SMAX")])
682
683 ;; Iterator to optimize the following cases:
684 ;; D-form load to FPR register & move to Altivec register
685 ;; Move Altivec register to FPR register and store
686 (define_mode_iterator ALTIVEC_DFORM [DF
687 (SF "TARGET_P8_VECTOR")
688 (DI "TARGET_POWERPC64")])
689
690 \f
691 ;; Start with fixed-point load and store insns. Here we put only the more
692 ;; complex forms. Basic data transfer is done later.
693
694 (define_insn "zero_extendqi<mode>2"
695 [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r,^wJwK,^wK")
696 (zero_extend:EXTQI (match_operand:QI 1 "reg_or_mem_operand" "m,r,Z,wK")))]
697 ""
698 "@
699 lbz%U1%X1 %0,%1
700 rlwinm %0,%1,0,0xff
701 lxsibzx %x0,%y1
702 vextractub %0,%1,7"
703 [(set_attr "type" "load,shift,fpload,vecperm")])
704
705 (define_insn_and_split "*zero_extendqi<mode>2_dot"
706 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
707 (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
708 (const_int 0)))
709 (clobber (match_scratch:EXTQI 0 "=r,r"))]
710 ""
711 "@
712 andi. %0,%1,0xff
713 #"
714 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
715 [(set (match_dup 0)
716 (zero_extend:EXTQI (match_dup 1)))
717 (set (match_dup 2)
718 (compare:CC (match_dup 0)
719 (const_int 0)))]
720 ""
721 [(set_attr "type" "logical")
722 (set_attr "dot" "yes")
723 (set_attr "length" "4,8")])
724
725 (define_insn_and_split "*zero_extendqi<mode>2_dot2"
726 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
727 (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
728 (const_int 0)))
729 (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
730 (zero_extend:EXTQI (match_dup 1)))]
731 ""
732 "@
733 andi. %0,%1,0xff
734 #"
735 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
736 [(set (match_dup 0)
737 (zero_extend:EXTQI (match_dup 1)))
738 (set (match_dup 2)
739 (compare:CC (match_dup 0)
740 (const_int 0)))]
741 ""
742 [(set_attr "type" "logical")
743 (set_attr "dot" "yes")
744 (set_attr "length" "4,8")])
745
746
747 (define_insn "zero_extendhi<mode>2"
748 [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r,^wJwK,^wK")
749 (zero_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r,Z,wK")))]
750 ""
751 "@
752 lhz%U1%X1 %0,%1
753 rlwinm %0,%1,0,0xffff
754 lxsihzx %x0,%y1
755 vextractuh %0,%1,6"
756 [(set_attr "type" "load,shift,fpload,vecperm")])
757
758 (define_insn_and_split "*zero_extendhi<mode>2_dot"
759 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
760 (compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
761 (const_int 0)))
762 (clobber (match_scratch:EXTHI 0 "=r,r"))]
763 ""
764 "@
765 andi. %0,%1,0xffff
766 #"
767 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
768 [(set (match_dup 0)
769 (zero_extend:EXTHI (match_dup 1)))
770 (set (match_dup 2)
771 (compare:CC (match_dup 0)
772 (const_int 0)))]
773 ""
774 [(set_attr "type" "logical")
775 (set_attr "dot" "yes")
776 (set_attr "length" "4,8")])
777
778 (define_insn_and_split "*zero_extendhi<mode>2_dot2"
779 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
780 (compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
781 (const_int 0)))
782 (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
783 (zero_extend:EXTHI (match_dup 1)))]
784 ""
785 "@
786 andi. %0,%1,0xffff
787 #"
788 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
789 [(set (match_dup 0)
790 (zero_extend:EXTHI (match_dup 1)))
791 (set (match_dup 2)
792 (compare:CC (match_dup 0)
793 (const_int 0)))]
794 ""
795 [(set_attr "type" "logical")
796 (set_attr "dot" "yes")
797 (set_attr "length" "4,8")])
798
799
800 (define_insn "zero_extendsi<mode>2"
801 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r,wz,wu,wj,r,wJwK")
802 (zero_extend:EXTSI (match_operand:SI 1 "reg_or_mem_operand" "m,r,Z,Z,r,wIwH,wJwK")))]
803 ""
804 "@
805 lwz%U1%X1 %0,%1
806 rldicl %0,%1,0,32
807 lfiwzx %0,%y1
808 lxsiwzx %x0,%y1
809 mtvsrwz %x0,%1
810 mfvsrwz %0,%x1
811 xxextractuw %x0,%x1,4"
812 [(set_attr "type" "load,shift,fpload,fpload,mffgpr,mftgpr,vecexts")])
813
814 (define_insn_and_split "*zero_extendsi<mode>2_dot"
815 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
816 (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
817 (const_int 0)))
818 (clobber (match_scratch:EXTSI 0 "=r,r"))]
819 ""
820 "@
821 rldicl. %0,%1,0,32
822 #"
823 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
824 [(set (match_dup 0)
825 (zero_extend:DI (match_dup 1)))
826 (set (match_dup 2)
827 (compare:CC (match_dup 0)
828 (const_int 0)))]
829 ""
830 [(set_attr "type" "shift")
831 (set_attr "dot" "yes")
832 (set_attr "length" "4,8")])
833
834 (define_insn_and_split "*zero_extendsi<mode>2_dot2"
835 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
836 (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
837 (const_int 0)))
838 (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
839 (zero_extend:EXTSI (match_dup 1)))]
840 ""
841 "@
842 rldicl. %0,%1,0,32
843 #"
844 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
845 [(set (match_dup 0)
846 (zero_extend:EXTSI (match_dup 1)))
847 (set (match_dup 2)
848 (compare:CC (match_dup 0)
849 (const_int 0)))]
850 ""
851 [(set_attr "type" "shift")
852 (set_attr "dot" "yes")
853 (set_attr "length" "4,8")])
854
855
856 (define_insn "extendqi<mode>2"
857 [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,?*wK")
858 (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,?*wK")))]
859 ""
860 "@
861 extsb %0,%1
862 vextsb2d %0,%1"
863 [(set_attr "type" "exts,vecperm")])
864
865 (define_insn_and_split "*extendqi<mode>2_dot"
866 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
867 (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
868 (const_int 0)))
869 (clobber (match_scratch:EXTQI 0 "=r,r"))]
870 ""
871 "@
872 extsb. %0,%1
873 #"
874 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
875 [(set (match_dup 0)
876 (sign_extend:EXTQI (match_dup 1)))
877 (set (match_dup 2)
878 (compare:CC (match_dup 0)
879 (const_int 0)))]
880 ""
881 [(set_attr "type" "exts")
882 (set_attr "dot" "yes")
883 (set_attr "length" "4,8")])
884
885 (define_insn_and_split "*extendqi<mode>2_dot2"
886 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
887 (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
888 (const_int 0)))
889 (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
890 (sign_extend:EXTQI (match_dup 1)))]
891 ""
892 "@
893 extsb. %0,%1
894 #"
895 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
896 [(set (match_dup 0)
897 (sign_extend:EXTQI (match_dup 1)))
898 (set (match_dup 2)
899 (compare:CC (match_dup 0)
900 (const_int 0)))]
901 ""
902 [(set_attr "type" "exts")
903 (set_attr "dot" "yes")
904 (set_attr "length" "4,8")])
905
906
907 (define_expand "extendhi<mode>2"
908 [(set (match_operand:EXTHI 0 "gpc_reg_operand")
909 (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand")))]
910 ""
911 "")
912
913 (define_insn "*extendhi<mode>2"
914 [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r,?*wK,?*wK")
915 (sign_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r,Z,wK")))]
916 ""
917 "@
918 lha%U1%X1 %0,%1
919 extsh %0,%1
920 #
921 vextsh2d %0,%1"
922 [(set_attr "type" "load,exts,fpload,vecperm")
923 (set_attr "sign_extend" "yes")
924 (set_attr "length" "4,4,8,4")])
925
926 (define_split
927 [(set (match_operand:EXTHI 0 "altivec_register_operand")
928 (sign_extend:EXTHI
929 (match_operand:HI 1 "indexed_or_indirect_operand")))]
930 "TARGET_P9_VECTOR && reload_completed"
931 [(set (match_dup 2)
932 (match_dup 1))
933 (set (match_dup 0)
934 (sign_extend:EXTHI (match_dup 2)))]
935 {
936 operands[2] = gen_rtx_REG (HImode, REGNO (operands[0]));
937 })
938
939 (define_insn_and_split "*extendhi<mode>2_dot"
940 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
941 (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
942 (const_int 0)))
943 (clobber (match_scratch:EXTHI 0 "=r,r"))]
944 ""
945 "@
946 extsh. %0,%1
947 #"
948 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
949 [(set (match_dup 0)
950 (sign_extend:EXTHI (match_dup 1)))
951 (set (match_dup 2)
952 (compare:CC (match_dup 0)
953 (const_int 0)))]
954 ""
955 [(set_attr "type" "exts")
956 (set_attr "dot" "yes")
957 (set_attr "length" "4,8")])
958
959 (define_insn_and_split "*extendhi<mode>2_dot2"
960 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
961 (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
962 (const_int 0)))
963 (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
964 (sign_extend:EXTHI (match_dup 1)))]
965 ""
966 "@
967 extsh. %0,%1
968 #"
969 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
970 [(set (match_dup 0)
971 (sign_extend:EXTHI (match_dup 1)))
972 (set (match_dup 2)
973 (compare:CC (match_dup 0)
974 (const_int 0)))]
975 ""
976 [(set_attr "type" "exts")
977 (set_attr "dot" "yes")
978 (set_attr "length" "4,8")])
979
980
981 (define_insn "extendsi<mode>2"
982 [(set (match_operand:EXTSI 0 "gpc_reg_operand"
983 "=r, r, wl, wu, wj, wK, wH, wr")
984
985 (sign_extend:EXTSI (match_operand:SI 1 "lwa_operand"
986 "YZ, r, Z, Z, r, wK, wH, ?wIwH")))]
987 ""
988 "@
989 lwa%U1%X1 %0,%1
990 extsw %0,%1
991 lfiwax %0,%y1
992 lxsiwax %x0,%y1
993 mtvsrwa %x0,%1
994 vextsw2d %0,%1
995 #
996 #"
997 [(set_attr "type" "load,exts,fpload,fpload,mffgpr,vecexts,vecperm,mftgpr")
998 (set_attr "sign_extend" "yes")
999 (set_attr "length" "4,4,4,4,4,4,8,8")])
1000
1001 (define_split
1002 [(set (match_operand:EXTSI 0 "int_reg_operand")
1003 (sign_extend:EXTSI (match_operand:SI 1 "vsx_register_operand")))]
1004 "TARGET_DIRECT_MOVE_64BIT && reload_completed"
1005 [(set (match_dup 2)
1006 (match_dup 1))
1007 (set (match_dup 0)
1008 (sign_extend:DI (match_dup 2)))]
1009 {
1010 operands[2] = gen_rtx_REG (SImode, reg_or_subregno (operands[0]));
1011 })
1012
1013 (define_split
1014 [(set (match_operand:DI 0 "altivec_register_operand")
1015 (sign_extend:DI (match_operand:SI 1 "altivec_register_operand")))]
1016 "TARGET_P8_VECTOR && !TARGET_P9_VECTOR && reload_completed"
1017 [(const_int 0)]
1018 {
1019 rtx dest = operands[0];
1020 rtx src = operands[1];
1021 int dest_regno = REGNO (dest);
1022 int src_regno = REGNO (src);
1023 rtx dest_v2di = gen_rtx_REG (V2DImode, dest_regno);
1024 rtx src_v4si = gen_rtx_REG (V4SImode, src_regno);
1025
1026 if (BYTES_BIG_ENDIAN)
1027 {
1028 emit_insn (gen_altivec_vupkhsw (dest_v2di, src_v4si));
1029 emit_insn (gen_vsx_xxspltd_v2di (dest_v2di, dest_v2di, const1_rtx));
1030 }
1031 else
1032 {
1033 emit_insn (gen_altivec_vupklsw (dest_v2di, src_v4si));
1034 emit_insn (gen_vsx_xxspltd_v2di (dest_v2di, dest_v2di, const0_rtx));
1035 }
1036 DONE;
1037 })
1038
1039 (define_insn_and_split "*extendsi<mode>2_dot"
1040 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1041 (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
1042 (const_int 0)))
1043 (clobber (match_scratch:EXTSI 0 "=r,r"))]
1044 ""
1045 "@
1046 extsw. %0,%1
1047 #"
1048 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1049 [(set (match_dup 0)
1050 (sign_extend:EXTSI (match_dup 1)))
1051 (set (match_dup 2)
1052 (compare:CC (match_dup 0)
1053 (const_int 0)))]
1054 ""
1055 [(set_attr "type" "exts")
1056 (set_attr "dot" "yes")
1057 (set_attr "length" "4,8")])
1058
1059 (define_insn_and_split "*extendsi<mode>2_dot2"
1060 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1061 (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
1062 (const_int 0)))
1063 (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
1064 (sign_extend:EXTSI (match_dup 1)))]
1065 ""
1066 "@
1067 extsw. %0,%1
1068 #"
1069 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1070 [(set (match_dup 0)
1071 (sign_extend:EXTSI (match_dup 1)))
1072 (set (match_dup 2)
1073 (compare:CC (match_dup 0)
1074 (const_int 0)))]
1075 ""
1076 [(set_attr "type" "exts")
1077 (set_attr "dot" "yes")
1078 (set_attr "length" "4,8")])
1079 \f
1080 ;; IBM 405, 440, 464 and 476 half-word multiplication operations.
1081
1082 (define_insn "*macchwc"
1083 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1084 (compare:CC (plus:SI (mult:SI (ashiftrt:SI
1085 (match_operand:SI 2 "gpc_reg_operand" "r")
1086 (const_int 16))
1087 (sign_extend:SI
1088 (match_operand:HI 1 "gpc_reg_operand" "r")))
1089 (match_operand:SI 4 "gpc_reg_operand" "0"))
1090 (const_int 0)))
1091 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1092 (plus:SI (mult:SI (ashiftrt:SI
1093 (match_dup 2)
1094 (const_int 16))
1095 (sign_extend:SI
1096 (match_dup 1)))
1097 (match_dup 4)))]
1098 "TARGET_MULHW"
1099 "macchw. %0,%1,%2"
1100 [(set_attr "type" "halfmul")])
1101
1102 (define_insn "*macchw"
1103 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1104 (plus:SI (mult:SI (ashiftrt:SI
1105 (match_operand:SI 2 "gpc_reg_operand" "r")
1106 (const_int 16))
1107 (sign_extend:SI
1108 (match_operand:HI 1 "gpc_reg_operand" "r")))
1109 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1110 "TARGET_MULHW"
1111 "macchw %0,%1,%2"
1112 [(set_attr "type" "halfmul")])
1113
1114 (define_insn "*macchwuc"
1115 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1116 (compare:CC (plus:SI (mult:SI (lshiftrt:SI
1117 (match_operand:SI 2 "gpc_reg_operand" "r")
1118 (const_int 16))
1119 (zero_extend:SI
1120 (match_operand:HI 1 "gpc_reg_operand" "r")))
1121 (match_operand:SI 4 "gpc_reg_operand" "0"))
1122 (const_int 0)))
1123 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1124 (plus:SI (mult:SI (lshiftrt:SI
1125 (match_dup 2)
1126 (const_int 16))
1127 (zero_extend:SI
1128 (match_dup 1)))
1129 (match_dup 4)))]
1130 "TARGET_MULHW"
1131 "macchwu. %0,%1,%2"
1132 [(set_attr "type" "halfmul")])
1133
1134 (define_insn "*macchwu"
1135 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1136 (plus:SI (mult:SI (lshiftrt:SI
1137 (match_operand:SI 2 "gpc_reg_operand" "r")
1138 (const_int 16))
1139 (zero_extend:SI
1140 (match_operand:HI 1 "gpc_reg_operand" "r")))
1141 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1142 "TARGET_MULHW"
1143 "macchwu %0,%1,%2"
1144 [(set_attr "type" "halfmul")])
1145
1146 (define_insn "*machhwc"
1147 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1148 (compare:CC (plus:SI (mult:SI (ashiftrt:SI
1149 (match_operand:SI 1 "gpc_reg_operand" "%r")
1150 (const_int 16))
1151 (ashiftrt:SI
1152 (match_operand:SI 2 "gpc_reg_operand" "r")
1153 (const_int 16)))
1154 (match_operand:SI 4 "gpc_reg_operand" "0"))
1155 (const_int 0)))
1156 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1157 (plus:SI (mult:SI (ashiftrt:SI
1158 (match_dup 1)
1159 (const_int 16))
1160 (ashiftrt:SI
1161 (match_dup 2)
1162 (const_int 16)))
1163 (match_dup 4)))]
1164 "TARGET_MULHW"
1165 "machhw. %0,%1,%2"
1166 [(set_attr "type" "halfmul")])
1167
1168 (define_insn "*machhw"
1169 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1170 (plus:SI (mult:SI (ashiftrt:SI
1171 (match_operand:SI 1 "gpc_reg_operand" "%r")
1172 (const_int 16))
1173 (ashiftrt:SI
1174 (match_operand:SI 2 "gpc_reg_operand" "r")
1175 (const_int 16)))
1176 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1177 "TARGET_MULHW"
1178 "machhw %0,%1,%2"
1179 [(set_attr "type" "halfmul")])
1180
1181 (define_insn "*machhwuc"
1182 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1183 (compare:CC (plus:SI (mult:SI (lshiftrt:SI
1184 (match_operand:SI 1 "gpc_reg_operand" "%r")
1185 (const_int 16))
1186 (lshiftrt:SI
1187 (match_operand:SI 2 "gpc_reg_operand" "r")
1188 (const_int 16)))
1189 (match_operand:SI 4 "gpc_reg_operand" "0"))
1190 (const_int 0)))
1191 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1192 (plus:SI (mult:SI (lshiftrt:SI
1193 (match_dup 1)
1194 (const_int 16))
1195 (lshiftrt:SI
1196 (match_dup 2)
1197 (const_int 16)))
1198 (match_dup 4)))]
1199 "TARGET_MULHW"
1200 "machhwu. %0,%1,%2"
1201 [(set_attr "type" "halfmul")])
1202
1203 (define_insn "*machhwu"
1204 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1205 (plus:SI (mult:SI (lshiftrt:SI
1206 (match_operand:SI 1 "gpc_reg_operand" "%r")
1207 (const_int 16))
1208 (lshiftrt:SI
1209 (match_operand:SI 2 "gpc_reg_operand" "r")
1210 (const_int 16)))
1211 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1212 "TARGET_MULHW"
1213 "machhwu %0,%1,%2"
1214 [(set_attr "type" "halfmul")])
1215
1216 (define_insn "*maclhwc"
1217 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1218 (compare:CC (plus:SI (mult:SI (sign_extend:SI
1219 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1220 (sign_extend:SI
1221 (match_operand:HI 2 "gpc_reg_operand" "r")))
1222 (match_operand:SI 4 "gpc_reg_operand" "0"))
1223 (const_int 0)))
1224 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1225 (plus:SI (mult:SI (sign_extend:SI
1226 (match_dup 1))
1227 (sign_extend:SI
1228 (match_dup 2)))
1229 (match_dup 4)))]
1230 "TARGET_MULHW"
1231 "maclhw. %0,%1,%2"
1232 [(set_attr "type" "halfmul")])
1233
1234 (define_insn "*maclhw"
1235 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1236 (plus:SI (mult:SI (sign_extend:SI
1237 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1238 (sign_extend:SI
1239 (match_operand:HI 2 "gpc_reg_operand" "r")))
1240 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1241 "TARGET_MULHW"
1242 "maclhw %0,%1,%2"
1243 [(set_attr "type" "halfmul")])
1244
1245 (define_insn "*maclhwuc"
1246 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1247 (compare:CC (plus:SI (mult:SI (zero_extend:SI
1248 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1249 (zero_extend:SI
1250 (match_operand:HI 2 "gpc_reg_operand" "r")))
1251 (match_operand:SI 4 "gpc_reg_operand" "0"))
1252 (const_int 0)))
1253 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1254 (plus:SI (mult:SI (zero_extend:SI
1255 (match_dup 1))
1256 (zero_extend:SI
1257 (match_dup 2)))
1258 (match_dup 4)))]
1259 "TARGET_MULHW"
1260 "maclhwu. %0,%1,%2"
1261 [(set_attr "type" "halfmul")])
1262
1263 (define_insn "*maclhwu"
1264 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1265 (plus:SI (mult:SI (zero_extend:SI
1266 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1267 (zero_extend:SI
1268 (match_operand:HI 2 "gpc_reg_operand" "r")))
1269 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1270 "TARGET_MULHW"
1271 "maclhwu %0,%1,%2"
1272 [(set_attr "type" "halfmul")])
1273
1274 (define_insn "*nmacchwc"
1275 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1276 (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1277 (mult:SI (ashiftrt:SI
1278 (match_operand:SI 2 "gpc_reg_operand" "r")
1279 (const_int 16))
1280 (sign_extend:SI
1281 (match_operand:HI 1 "gpc_reg_operand" "r"))))
1282 (const_int 0)))
1283 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1284 (minus:SI (match_dup 4)
1285 (mult:SI (ashiftrt:SI
1286 (match_dup 2)
1287 (const_int 16))
1288 (sign_extend:SI
1289 (match_dup 1)))))]
1290 "TARGET_MULHW"
1291 "nmacchw. %0,%1,%2"
1292 [(set_attr "type" "halfmul")])
1293
1294 (define_insn "*nmacchw"
1295 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1296 (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1297 (mult:SI (ashiftrt:SI
1298 (match_operand:SI 2 "gpc_reg_operand" "r")
1299 (const_int 16))
1300 (sign_extend:SI
1301 (match_operand:HI 1 "gpc_reg_operand" "r")))))]
1302 "TARGET_MULHW"
1303 "nmacchw %0,%1,%2"
1304 [(set_attr "type" "halfmul")])
1305
1306 (define_insn "*nmachhwc"
1307 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1308 (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1309 (mult:SI (ashiftrt:SI
1310 (match_operand:SI 1 "gpc_reg_operand" "%r")
1311 (const_int 16))
1312 (ashiftrt:SI
1313 (match_operand:SI 2 "gpc_reg_operand" "r")
1314 (const_int 16))))
1315 (const_int 0)))
1316 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1317 (minus:SI (match_dup 4)
1318 (mult:SI (ashiftrt:SI
1319 (match_dup 1)
1320 (const_int 16))
1321 (ashiftrt:SI
1322 (match_dup 2)
1323 (const_int 16)))))]
1324 "TARGET_MULHW"
1325 "nmachhw. %0,%1,%2"
1326 [(set_attr "type" "halfmul")])
1327
1328 (define_insn "*nmachhw"
1329 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1330 (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1331 (mult:SI (ashiftrt:SI
1332 (match_operand:SI 1 "gpc_reg_operand" "%r")
1333 (const_int 16))
1334 (ashiftrt:SI
1335 (match_operand:SI 2 "gpc_reg_operand" "r")
1336 (const_int 16)))))]
1337 "TARGET_MULHW"
1338 "nmachhw %0,%1,%2"
1339 [(set_attr "type" "halfmul")])
1340
1341 (define_insn "*nmaclhwc"
1342 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1343 (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1344 (mult:SI (sign_extend:SI
1345 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1346 (sign_extend:SI
1347 (match_operand:HI 2 "gpc_reg_operand" "r"))))
1348 (const_int 0)))
1349 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1350 (minus:SI (match_dup 4)
1351 (mult:SI (sign_extend:SI
1352 (match_dup 1))
1353 (sign_extend:SI
1354 (match_dup 2)))))]
1355 "TARGET_MULHW"
1356 "nmaclhw. %0,%1,%2"
1357 [(set_attr "type" "halfmul")])
1358
1359 (define_insn "*nmaclhw"
1360 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1361 (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1362 (mult:SI (sign_extend:SI
1363 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1364 (sign_extend:SI
1365 (match_operand:HI 2 "gpc_reg_operand" "r")))))]
1366 "TARGET_MULHW"
1367 "nmaclhw %0,%1,%2"
1368 [(set_attr "type" "halfmul")])
1369
1370 (define_insn "*mulchwc"
1371 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1372 (compare:CC (mult:SI (ashiftrt:SI
1373 (match_operand:SI 2 "gpc_reg_operand" "r")
1374 (const_int 16))
1375 (sign_extend:SI
1376 (match_operand:HI 1 "gpc_reg_operand" "r")))
1377 (const_int 0)))
1378 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1379 (mult:SI (ashiftrt:SI
1380 (match_dup 2)
1381 (const_int 16))
1382 (sign_extend:SI
1383 (match_dup 1))))]
1384 "TARGET_MULHW"
1385 "mulchw. %0,%1,%2"
1386 [(set_attr "type" "halfmul")])
1387
1388 (define_insn "*mulchw"
1389 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1390 (mult:SI (ashiftrt:SI
1391 (match_operand:SI 2 "gpc_reg_operand" "r")
1392 (const_int 16))
1393 (sign_extend:SI
1394 (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1395 "TARGET_MULHW"
1396 "mulchw %0,%1,%2"
1397 [(set_attr "type" "halfmul")])
1398
1399 (define_insn "*mulchwuc"
1400 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1401 (compare:CC (mult:SI (lshiftrt:SI
1402 (match_operand:SI 2 "gpc_reg_operand" "r")
1403 (const_int 16))
1404 (zero_extend:SI
1405 (match_operand:HI 1 "gpc_reg_operand" "r")))
1406 (const_int 0)))
1407 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1408 (mult:SI (lshiftrt:SI
1409 (match_dup 2)
1410 (const_int 16))
1411 (zero_extend:SI
1412 (match_dup 1))))]
1413 "TARGET_MULHW"
1414 "mulchwu. %0,%1,%2"
1415 [(set_attr "type" "halfmul")])
1416
1417 (define_insn "*mulchwu"
1418 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1419 (mult:SI (lshiftrt:SI
1420 (match_operand:SI 2 "gpc_reg_operand" "r")
1421 (const_int 16))
1422 (zero_extend:SI
1423 (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1424 "TARGET_MULHW"
1425 "mulchwu %0,%1,%2"
1426 [(set_attr "type" "halfmul")])
1427
1428 (define_insn "*mulhhwc"
1429 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1430 (compare:CC (mult:SI (ashiftrt:SI
1431 (match_operand:SI 1 "gpc_reg_operand" "%r")
1432 (const_int 16))
1433 (ashiftrt:SI
1434 (match_operand:SI 2 "gpc_reg_operand" "r")
1435 (const_int 16)))
1436 (const_int 0)))
1437 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1438 (mult:SI (ashiftrt:SI
1439 (match_dup 1)
1440 (const_int 16))
1441 (ashiftrt:SI
1442 (match_dup 2)
1443 (const_int 16))))]
1444 "TARGET_MULHW"
1445 "mulhhw. %0,%1,%2"
1446 [(set_attr "type" "halfmul")])
1447
1448 (define_insn "*mulhhw"
1449 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1450 (mult:SI (ashiftrt:SI
1451 (match_operand:SI 1 "gpc_reg_operand" "%r")
1452 (const_int 16))
1453 (ashiftrt:SI
1454 (match_operand:SI 2 "gpc_reg_operand" "r")
1455 (const_int 16))))]
1456 "TARGET_MULHW"
1457 "mulhhw %0,%1,%2"
1458 [(set_attr "type" "halfmul")])
1459
1460 (define_insn "*mulhhwuc"
1461 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1462 (compare:CC (mult:SI (lshiftrt:SI
1463 (match_operand:SI 1 "gpc_reg_operand" "%r")
1464 (const_int 16))
1465 (lshiftrt:SI
1466 (match_operand:SI 2 "gpc_reg_operand" "r")
1467 (const_int 16)))
1468 (const_int 0)))
1469 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1470 (mult:SI (lshiftrt:SI
1471 (match_dup 1)
1472 (const_int 16))
1473 (lshiftrt:SI
1474 (match_dup 2)
1475 (const_int 16))))]
1476 "TARGET_MULHW"
1477 "mulhhwu. %0,%1,%2"
1478 [(set_attr "type" "halfmul")])
1479
1480 (define_insn "*mulhhwu"
1481 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1482 (mult:SI (lshiftrt:SI
1483 (match_operand:SI 1 "gpc_reg_operand" "%r")
1484 (const_int 16))
1485 (lshiftrt:SI
1486 (match_operand:SI 2 "gpc_reg_operand" "r")
1487 (const_int 16))))]
1488 "TARGET_MULHW"
1489 "mulhhwu %0,%1,%2"
1490 [(set_attr "type" "halfmul")])
1491
1492 (define_insn "*mullhwc"
1493 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1494 (compare:CC (mult:SI (sign_extend:SI
1495 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1496 (sign_extend:SI
1497 (match_operand:HI 2 "gpc_reg_operand" "r")))
1498 (const_int 0)))
1499 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1500 (mult:SI (sign_extend:SI
1501 (match_dup 1))
1502 (sign_extend:SI
1503 (match_dup 2))))]
1504 "TARGET_MULHW"
1505 "mullhw. %0,%1,%2"
1506 [(set_attr "type" "halfmul")])
1507
1508 (define_insn "*mullhw"
1509 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1510 (mult:SI (sign_extend:SI
1511 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1512 (sign_extend:SI
1513 (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1514 "TARGET_MULHW"
1515 "mullhw %0,%1,%2"
1516 [(set_attr "type" "halfmul")])
1517
1518 (define_insn "*mullhwuc"
1519 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1520 (compare:CC (mult:SI (zero_extend:SI
1521 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1522 (zero_extend:SI
1523 (match_operand:HI 2 "gpc_reg_operand" "r")))
1524 (const_int 0)))
1525 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1526 (mult:SI (zero_extend:SI
1527 (match_dup 1))
1528 (zero_extend:SI
1529 (match_dup 2))))]
1530 "TARGET_MULHW"
1531 "mullhwu. %0,%1,%2"
1532 [(set_attr "type" "halfmul")])
1533
1534 (define_insn "*mullhwu"
1535 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1536 (mult:SI (zero_extend:SI
1537 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1538 (zero_extend:SI
1539 (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1540 "TARGET_MULHW"
1541 "mullhwu %0,%1,%2"
1542 [(set_attr "type" "halfmul")])
1543 \f
1544 ;; IBM 405, 440, 464 and 476 string-search dlmzb instruction support.
1545 (define_insn "dlmzb"
1546 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1547 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
1548 (match_operand:SI 2 "gpc_reg_operand" "r")]
1549 UNSPEC_DLMZB_CR))
1550 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1551 (unspec:SI [(match_dup 1)
1552 (match_dup 2)]
1553 UNSPEC_DLMZB))]
1554 "TARGET_DLMZB"
1555 "dlmzb. %0,%1,%2")
1556
1557 (define_expand "strlensi"
1558 [(set (match_operand:SI 0 "gpc_reg_operand")
1559 (unspec:SI [(match_operand:BLK 1 "general_operand")
1560 (match_operand:QI 2 "const_int_operand")
1561 (match_operand 3 "const_int_operand")]
1562 UNSPEC_DLMZB_STRLEN))
1563 (clobber (match_scratch:CC 4))]
1564 "TARGET_DLMZB && WORDS_BIG_ENDIAN && !optimize_size"
1565 {
1566 rtx result = operands[0];
1567 rtx src = operands[1];
1568 rtx search_char = operands[2];
1569 rtx align = operands[3];
1570 rtx addr, scratch_string, word1, word2, scratch_dlmzb;
1571 rtx loop_label, end_label, mem, cr0, cond;
1572 if (search_char != const0_rtx
1573 || GET_CODE (align) != CONST_INT
1574 || INTVAL (align) < 8)
1575 FAIL;
1576 word1 = gen_reg_rtx (SImode);
1577 word2 = gen_reg_rtx (SImode);
1578 scratch_dlmzb = gen_reg_rtx (SImode);
1579 scratch_string = gen_reg_rtx (Pmode);
1580 loop_label = gen_label_rtx ();
1581 end_label = gen_label_rtx ();
1582 addr = force_reg (Pmode, XEXP (src, 0));
1583 emit_move_insn (scratch_string, addr);
1584 emit_label (loop_label);
1585 mem = change_address (src, SImode, scratch_string);
1586 emit_move_insn (word1, mem);
1587 emit_move_insn (word2, adjust_address (mem, SImode, 4));
1588 cr0 = gen_rtx_REG (CCmode, CR0_REGNO);
1589 emit_insn (gen_dlmzb (scratch_dlmzb, word1, word2, cr0));
1590 cond = gen_rtx_NE (VOIDmode, cr0, const0_rtx);
1591 emit_jump_insn (gen_rtx_SET (pc_rtx,
1592 gen_rtx_IF_THEN_ELSE (VOIDmode,
1593 cond,
1594 gen_rtx_LABEL_REF
1595 (VOIDmode,
1596 end_label),
1597 pc_rtx)));
1598 emit_insn (gen_addsi3 (scratch_string, scratch_string, GEN_INT (8)));
1599 emit_jump_insn (gen_rtx_SET (pc_rtx,
1600 gen_rtx_LABEL_REF (VOIDmode, loop_label)));
1601 emit_barrier ();
1602 emit_label (end_label);
1603 emit_insn (gen_addsi3 (scratch_string, scratch_string, scratch_dlmzb));
1604 emit_insn (gen_subsi3 (result, scratch_string, addr));
1605 emit_insn (gen_addsi3 (result, result, constm1_rtx));
1606 DONE;
1607 })
1608 \f
1609 ;; Fixed-point arithmetic insns.
1610
1611 (define_expand "add<mode>3"
1612 [(set (match_operand:SDI 0 "gpc_reg_operand")
1613 (plus:SDI (match_operand:SDI 1 "gpc_reg_operand")
1614 (match_operand:SDI 2 "reg_or_add_cint_operand")))]
1615 ""
1616 {
1617 if (<MODE>mode == DImode && !TARGET_POWERPC64)
1618 {
1619 rtx lo0 = gen_lowpart (SImode, operands[0]);
1620 rtx lo1 = gen_lowpart (SImode, operands[1]);
1621 rtx lo2 = gen_lowpart (SImode, operands[2]);
1622 rtx hi0 = gen_highpart (SImode, operands[0]);
1623 rtx hi1 = gen_highpart (SImode, operands[1]);
1624 rtx hi2 = gen_highpart_mode (SImode, DImode, operands[2]);
1625
1626 if (!reg_or_short_operand (lo2, SImode))
1627 lo2 = force_reg (SImode, lo2);
1628 if (!adde_operand (hi2, SImode))
1629 hi2 = force_reg (SImode, hi2);
1630
1631 emit_insn (gen_addsi3_carry (lo0, lo1, lo2));
1632 emit_insn (gen_addsi3_carry_in (hi0, hi1, hi2));
1633 DONE;
1634 }
1635
1636 if (CONST_INT_P (operands[2]) && !add_operand (operands[2], <MODE>mode))
1637 {
1638 rtx tmp = ((!can_create_pseudo_p ()
1639 || rtx_equal_p (operands[0], operands[1]))
1640 ? operands[0] : gen_reg_rtx (<MODE>mode));
1641
1642 /* Adding a constant to r0 is not a valid insn, so use a different
1643 strategy in that case. */
1644 if (reg_or_subregno (operands[1]) == 0 || reg_or_subregno (tmp) == 0)
1645 {
1646 if (operands[0] == operands[1])
1647 FAIL;
1648 rs6000_emit_move (operands[0], operands[2], <MODE>mode);
1649 emit_insn (gen_add<mode>3 (operands[0], operands[1], operands[0]));
1650 DONE;
1651 }
1652
1653 HOST_WIDE_INT val = INTVAL (operands[2]);
1654 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1655 HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1656
1657 if (<MODE>mode == DImode && !satisfies_constraint_L (GEN_INT (rest)))
1658 FAIL;
1659
1660 /* The ordering here is important for the prolog expander.
1661 When space is allocated from the stack, adding 'low' first may
1662 produce a temporary deallocation (which would be bad). */
1663 emit_insn (gen_add<mode>3 (tmp, operands[1], GEN_INT (rest)));
1664 emit_insn (gen_add<mode>3 (operands[0], tmp, GEN_INT (low)));
1665 DONE;
1666 }
1667 })
1668
1669 (define_insn "*add<mode>3"
1670 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r,r")
1671 (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b,b")
1672 (match_operand:GPR 2 "add_operand" "r,I,L")))]
1673 ""
1674 "@
1675 add %0,%1,%2
1676 addi %0,%1,%2
1677 addis %0,%1,%v2"
1678 [(set_attr "type" "add")])
1679
1680 (define_insn "*addsi3_high"
1681 [(set (match_operand:SI 0 "gpc_reg_operand" "=b")
1682 (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
1683 (high:SI (match_operand 2 "" ""))))]
1684 "TARGET_MACHO && !TARGET_64BIT"
1685 "addis %0,%1,ha16(%2)"
1686 [(set_attr "type" "add")])
1687
1688 (define_insn_and_split "*add<mode>3_dot"
1689 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1690 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
1691 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
1692 (const_int 0)))
1693 (clobber (match_scratch:GPR 0 "=r,r"))]
1694 "<MODE>mode == Pmode"
1695 "@
1696 add. %0,%1,%2
1697 #"
1698 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1699 [(set (match_dup 0)
1700 (plus:GPR (match_dup 1)
1701 (match_dup 2)))
1702 (set (match_dup 3)
1703 (compare:CC (match_dup 0)
1704 (const_int 0)))]
1705 ""
1706 [(set_attr "type" "add")
1707 (set_attr "dot" "yes")
1708 (set_attr "length" "4,8")])
1709
1710 (define_insn_and_split "*add<mode>3_dot2"
1711 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1712 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
1713 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
1714 (const_int 0)))
1715 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1716 (plus:GPR (match_dup 1)
1717 (match_dup 2)))]
1718 "<MODE>mode == Pmode"
1719 "@
1720 add. %0,%1,%2
1721 #"
1722 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1723 [(set (match_dup 0)
1724 (plus:GPR (match_dup 1)
1725 (match_dup 2)))
1726 (set (match_dup 3)
1727 (compare:CC (match_dup 0)
1728 (const_int 0)))]
1729 ""
1730 [(set_attr "type" "add")
1731 (set_attr "dot" "yes")
1732 (set_attr "length" "4,8")])
1733
1734 (define_insn_and_split "*add<mode>3_imm_dot"
1735 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1736 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b")
1737 (match_operand:GPR 2 "short_cint_operand" "I,I"))
1738 (const_int 0)))
1739 (clobber (match_scratch:GPR 0 "=r,r"))
1740 (clobber (reg:GPR CA_REGNO))]
1741 "<MODE>mode == Pmode"
1742 "@
1743 addic. %0,%1,%2
1744 #"
1745 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1746 [(set (match_dup 0)
1747 (plus:GPR (match_dup 1)
1748 (match_dup 2)))
1749 (set (match_dup 3)
1750 (compare:CC (match_dup 0)
1751 (const_int 0)))]
1752 ""
1753 [(set_attr "type" "add")
1754 (set_attr "dot" "yes")
1755 (set_attr "length" "4,8")])
1756
1757 (define_insn_and_split "*add<mode>3_imm_dot2"
1758 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1759 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b")
1760 (match_operand:GPR 2 "short_cint_operand" "I,I"))
1761 (const_int 0)))
1762 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1763 (plus:GPR (match_dup 1)
1764 (match_dup 2)))
1765 (clobber (reg:GPR CA_REGNO))]
1766 "<MODE>mode == Pmode"
1767 "@
1768 addic. %0,%1,%2
1769 #"
1770 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1771 [(set (match_dup 0)
1772 (plus:GPR (match_dup 1)
1773 (match_dup 2)))
1774 (set (match_dup 3)
1775 (compare:CC (match_dup 0)
1776 (const_int 0)))]
1777 ""
1778 [(set_attr "type" "add")
1779 (set_attr "dot" "yes")
1780 (set_attr "length" "4,8")])
1781
1782 ;; Split an add that we can't do in one insn into two insns, each of which
1783 ;; does one 16-bit part. This is used by combine. Note that the low-order
1784 ;; add should be last in case the result gets used in an address.
1785
1786 (define_split
1787 [(set (match_operand:GPR 0 "gpc_reg_operand")
1788 (plus:GPR (match_operand:GPR 1 "gpc_reg_operand")
1789 (match_operand:GPR 2 "non_add_cint_operand")))]
1790 ""
1791 [(set (match_dup 0) (plus:GPR (match_dup 1) (match_dup 3)))
1792 (set (match_dup 0) (plus:GPR (match_dup 0) (match_dup 4)))]
1793 {
1794 HOST_WIDE_INT val = INTVAL (operands[2]);
1795 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1796 HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1797
1798 operands[4] = GEN_INT (low);
1799 if (<MODE>mode == SImode || satisfies_constraint_L (GEN_INT (rest)))
1800 operands[3] = GEN_INT (rest);
1801 else if (can_create_pseudo_p ())
1802 {
1803 operands[3] = gen_reg_rtx (DImode);
1804 emit_move_insn (operands[3], operands[2]);
1805 emit_insn (gen_adddi3 (operands[0], operands[1], operands[3]));
1806 DONE;
1807 }
1808 else
1809 FAIL;
1810 })
1811
1812
1813 (define_insn "add<mode>3_carry"
1814 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1815 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1816 (match_operand:P 2 "reg_or_short_operand" "rI")))
1817 (set (reg:P CA_REGNO)
1818 (ltu:P (plus:P (match_dup 1)
1819 (match_dup 2))
1820 (match_dup 1)))]
1821 ""
1822 "add%I2c %0,%1,%2"
1823 [(set_attr "type" "add")])
1824
1825 (define_insn "*add<mode>3_imm_carry_pos"
1826 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1827 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1828 (match_operand:P 2 "short_cint_operand" "n")))
1829 (set (reg:P CA_REGNO)
1830 (geu:P (match_dup 1)
1831 (match_operand:P 3 "const_int_operand" "n")))]
1832 "INTVAL (operands[2]) > 0
1833 && INTVAL (operands[2]) + INTVAL (operands[3]) == 0"
1834 "addic %0,%1,%2"
1835 [(set_attr "type" "add")])
1836
1837 (define_insn "*add<mode>3_imm_carry_0"
1838 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1839 (match_operand:P 1 "gpc_reg_operand" "r"))
1840 (set (reg:P CA_REGNO)
1841 (const_int 0))]
1842 ""
1843 "addic %0,%1,0"
1844 [(set_attr "type" "add")])
1845
1846 (define_insn "*add<mode>3_imm_carry_m1"
1847 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1848 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1849 (const_int -1)))
1850 (set (reg:P CA_REGNO)
1851 (ne:P (match_dup 1)
1852 (const_int 0)))]
1853 ""
1854 "addic %0,%1,-1"
1855 [(set_attr "type" "add")])
1856
1857 (define_insn "*add<mode>3_imm_carry_neg"
1858 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1859 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1860 (match_operand:P 2 "short_cint_operand" "n")))
1861 (set (reg:P CA_REGNO)
1862 (gtu:P (match_dup 1)
1863 (match_operand:P 3 "const_int_operand" "n")))]
1864 "INTVAL (operands[2]) < 0
1865 && INTVAL (operands[2]) + INTVAL (operands[3]) == -1"
1866 "addic %0,%1,%2"
1867 [(set_attr "type" "add")])
1868
1869
1870 (define_expand "add<mode>3_carry_in"
1871 [(parallel [
1872 (set (match_operand:GPR 0 "gpc_reg_operand")
1873 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand")
1874 (match_operand:GPR 2 "adde_operand"))
1875 (reg:GPR CA_REGNO)))
1876 (clobber (reg:GPR CA_REGNO))])]
1877 ""
1878 {
1879 if (operands[2] == const0_rtx)
1880 {
1881 emit_insn (gen_add<mode>3_carry_in_0 (operands[0], operands[1]));
1882 DONE;
1883 }
1884 if (operands[2] == constm1_rtx)
1885 {
1886 emit_insn (gen_add<mode>3_carry_in_m1 (operands[0], operands[1]));
1887 DONE;
1888 }
1889 })
1890
1891 (define_insn "*add<mode>3_carry_in_internal"
1892 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1893 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1894 (match_operand:GPR 2 "gpc_reg_operand" "r"))
1895 (reg:GPR CA_REGNO)))
1896 (clobber (reg:GPR CA_REGNO))]
1897 ""
1898 "adde %0,%1,%2"
1899 [(set_attr "type" "add")])
1900
1901 (define_insn "*add<mode>3_carry_in_internal2"
1902 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1903 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1904 (reg:GPR CA_REGNO))
1905 (match_operand:GPR 2 "gpc_reg_operand" "r")))
1906 (clobber (reg:GPR CA_REGNO))]
1907 ""
1908 "adde %0,%1,%2"
1909 [(set_attr "type" "add")])
1910
1911 (define_insn "add<mode>3_carry_in_0"
1912 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1913 (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1914 (reg:GPR CA_REGNO)))
1915 (clobber (reg:GPR CA_REGNO))]
1916 ""
1917 "addze %0,%1"
1918 [(set_attr "type" "add")])
1919
1920 (define_insn "add<mode>3_carry_in_m1"
1921 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1922 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1923 (reg:GPR CA_REGNO))
1924 (const_int -1)))
1925 (clobber (reg:GPR CA_REGNO))]
1926 ""
1927 "addme %0,%1"
1928 [(set_attr "type" "add")])
1929
1930
1931 (define_expand "one_cmpl<mode>2"
1932 [(set (match_operand:SDI 0 "gpc_reg_operand")
1933 (not:SDI (match_operand:SDI 1 "gpc_reg_operand")))]
1934 ""
1935 {
1936 if (<MODE>mode == DImode && !TARGET_POWERPC64)
1937 {
1938 rs6000_split_logical (operands, NOT, false, false, false);
1939 DONE;
1940 }
1941 })
1942
1943 (define_insn "*one_cmpl<mode>2"
1944 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1945 (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
1946 ""
1947 "not %0,%1")
1948
1949 (define_insn_and_split "*one_cmpl<mode>2_dot"
1950 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1951 (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
1952 (const_int 0)))
1953 (clobber (match_scratch:GPR 0 "=r,r"))]
1954 "<MODE>mode == Pmode"
1955 "@
1956 not. %0,%1
1957 #"
1958 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1959 [(set (match_dup 0)
1960 (not:GPR (match_dup 1)))
1961 (set (match_dup 2)
1962 (compare:CC (match_dup 0)
1963 (const_int 0)))]
1964 ""
1965 [(set_attr "type" "logical")
1966 (set_attr "dot" "yes")
1967 (set_attr "length" "4,8")])
1968
1969 (define_insn_and_split "*one_cmpl<mode>2_dot2"
1970 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1971 (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
1972 (const_int 0)))
1973 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1974 (not:GPR (match_dup 1)))]
1975 "<MODE>mode == Pmode"
1976 "@
1977 not. %0,%1
1978 #"
1979 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1980 [(set (match_dup 0)
1981 (not:GPR (match_dup 1)))
1982 (set (match_dup 2)
1983 (compare:CC (match_dup 0)
1984 (const_int 0)))]
1985 ""
1986 [(set_attr "type" "logical")
1987 (set_attr "dot" "yes")
1988 (set_attr "length" "4,8")])
1989
1990
1991 (define_expand "sub<mode>3"
1992 [(set (match_operand:SDI 0 "gpc_reg_operand")
1993 (minus:SDI (match_operand:SDI 1 "reg_or_short_operand")
1994 (match_operand:SDI 2 "gpc_reg_operand")))]
1995 ""
1996 {
1997 if (<MODE>mode == DImode && !TARGET_POWERPC64)
1998 {
1999 rtx lo0 = gen_lowpart (SImode, operands[0]);
2000 rtx lo1 = gen_lowpart (SImode, operands[1]);
2001 rtx lo2 = gen_lowpart (SImode, operands[2]);
2002 rtx hi0 = gen_highpart (SImode, operands[0]);
2003 rtx hi1 = gen_highpart_mode (SImode, DImode, operands[1]);
2004 rtx hi2 = gen_highpart (SImode, operands[2]);
2005
2006 if (!reg_or_short_operand (lo1, SImode))
2007 lo1 = force_reg (SImode, lo1);
2008 if (!adde_operand (hi1, SImode))
2009 hi1 = force_reg (SImode, hi1);
2010
2011 emit_insn (gen_subfsi3_carry (lo0, lo2, lo1));
2012 emit_insn (gen_subfsi3_carry_in (hi0, hi2, hi1));
2013 DONE;
2014 }
2015
2016 if (short_cint_operand (operands[1], <MODE>mode))
2017 {
2018 emit_insn (gen_subf<mode>3_imm (operands[0], operands[2], operands[1]));
2019 DONE;
2020 }
2021 })
2022
2023 (define_insn "*subf<mode>3"
2024 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2025 (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r")
2026 (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2027 ""
2028 "subf %0,%1,%2"
2029 [(set_attr "type" "add")])
2030
2031 (define_insn_and_split "*subf<mode>3_dot"
2032 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2033 (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
2034 (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2035 (const_int 0)))
2036 (clobber (match_scratch:GPR 0 "=r,r"))]
2037 "<MODE>mode == Pmode"
2038 "@
2039 subf. %0,%1,%2
2040 #"
2041 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2042 [(set (match_dup 0)
2043 (minus:GPR (match_dup 2)
2044 (match_dup 1)))
2045 (set (match_dup 3)
2046 (compare:CC (match_dup 0)
2047 (const_int 0)))]
2048 ""
2049 [(set_attr "type" "add")
2050 (set_attr "dot" "yes")
2051 (set_attr "length" "4,8")])
2052
2053 (define_insn_and_split "*subf<mode>3_dot2"
2054 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2055 (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
2056 (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2057 (const_int 0)))
2058 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2059 (minus:GPR (match_dup 2)
2060 (match_dup 1)))]
2061 "<MODE>mode == Pmode"
2062 "@
2063 subf. %0,%1,%2
2064 #"
2065 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2066 [(set (match_dup 0)
2067 (minus:GPR (match_dup 2)
2068 (match_dup 1)))
2069 (set (match_dup 3)
2070 (compare:CC (match_dup 0)
2071 (const_int 0)))]
2072 ""
2073 [(set_attr "type" "add")
2074 (set_attr "dot" "yes")
2075 (set_attr "length" "4,8")])
2076
2077 (define_insn "subf<mode>3_imm"
2078 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2079 (minus:GPR (match_operand:GPR 2 "short_cint_operand" "I")
2080 (match_operand:GPR 1 "gpc_reg_operand" "r")))
2081 (clobber (reg:GPR CA_REGNO))]
2082 ""
2083 "subfic %0,%1,%2"
2084 [(set_attr "type" "add")])
2085
2086 (define_insn_and_split "subf<mode>3_carry_dot2"
2087 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2088 (compare:CC (minus:P (match_operand:P 2 "gpc_reg_operand" "r,r")
2089 (match_operand:P 1 "gpc_reg_operand" "r,r"))
2090 (const_int 0)))
2091 (set (match_operand:P 0 "gpc_reg_operand" "=r,r")
2092 (minus:P (match_dup 2)
2093 (match_dup 1)))
2094 (set (reg:P CA_REGNO)
2095 (leu:P (match_dup 1)
2096 (match_dup 2)))]
2097 "<MODE>mode == Pmode"
2098 "@
2099 subfc. %0,%1,%2
2100 #"
2101 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2102 [(parallel [(set (match_dup 0)
2103 (minus:P (match_dup 2)
2104 (match_dup 1)))
2105 (set (reg:P CA_REGNO)
2106 (leu:P (match_dup 1)
2107 (match_dup 2)))])
2108 (set (match_dup 3)
2109 (compare:CC (match_dup 0)
2110 (const_int 0)))]
2111 ""
2112 [(set_attr "type" "add")
2113 (set_attr "dot" "yes")
2114 (set_attr "length" "4,8")])
2115
2116 (define_insn "subf<mode>3_carry"
2117 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2118 (minus:P (match_operand:P 2 "reg_or_short_operand" "rI")
2119 (match_operand:P 1 "gpc_reg_operand" "r")))
2120 (set (reg:P CA_REGNO)
2121 (leu:P (match_dup 1)
2122 (match_dup 2)))]
2123 ""
2124 "subf%I2c %0,%1,%2"
2125 [(set_attr "type" "add")])
2126
2127 (define_insn "*subf<mode>3_imm_carry_0"
2128 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2129 (neg:P (match_operand:P 1 "gpc_reg_operand" "r")))
2130 (set (reg:P CA_REGNO)
2131 (eq:P (match_dup 1)
2132 (const_int 0)))]
2133 ""
2134 "subfic %0,%1,0"
2135 [(set_attr "type" "add")])
2136
2137 (define_insn "*subf<mode>3_imm_carry_m1"
2138 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2139 (not:P (match_operand:P 1 "gpc_reg_operand" "r")))
2140 (set (reg:P CA_REGNO)
2141 (const_int 1))]
2142 ""
2143 "subfic %0,%1,-1"
2144 [(set_attr "type" "add")])
2145
2146
2147 (define_expand "subf<mode>3_carry_in"
2148 [(parallel [
2149 (set (match_operand:GPR 0 "gpc_reg_operand")
2150 (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand"))
2151 (reg:GPR CA_REGNO))
2152 (match_operand:GPR 2 "adde_operand")))
2153 (clobber (reg:GPR CA_REGNO))])]
2154 ""
2155 {
2156 if (operands[2] == const0_rtx)
2157 {
2158 emit_insn (gen_subf<mode>3_carry_in_0 (operands[0], operands[1]));
2159 DONE;
2160 }
2161 if (operands[2] == constm1_rtx)
2162 {
2163 emit_insn (gen_subf<mode>3_carry_in_m1 (operands[0], operands[1]));
2164 DONE;
2165 }
2166 })
2167
2168 (define_insn "*subf<mode>3_carry_in_internal"
2169 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2170 (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
2171 (reg:GPR CA_REGNO))
2172 (match_operand:GPR 2 "gpc_reg_operand" "r")))
2173 (clobber (reg:GPR CA_REGNO))]
2174 ""
2175 "subfe %0,%1,%2"
2176 [(set_attr "type" "add")])
2177
2178 (define_insn "subf<mode>3_carry_in_0"
2179 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2180 (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
2181 (reg:GPR CA_REGNO)))
2182 (clobber (reg:GPR CA_REGNO))]
2183 ""
2184 "subfze %0,%1"
2185 [(set_attr "type" "add")])
2186
2187 (define_insn "subf<mode>3_carry_in_m1"
2188 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2189 (plus:GPR (minus:GPR (reg:GPR CA_REGNO)
2190 (match_operand:GPR 1 "gpc_reg_operand" "r"))
2191 (const_int -2)))
2192 (clobber (reg:GPR CA_REGNO))]
2193 ""
2194 "subfme %0,%1"
2195 [(set_attr "type" "add")])
2196
2197 (define_insn "subf<mode>3_carry_in_xx"
2198 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2199 (plus:GPR (reg:GPR CA_REGNO)
2200 (const_int -1)))
2201 (clobber (reg:GPR CA_REGNO))]
2202 ""
2203 "subfe %0,%0,%0"
2204 [(set_attr "type" "add")])
2205
2206
2207 (define_insn "neg<mode>2"
2208 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2209 (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2210 ""
2211 "neg %0,%1"
2212 [(set_attr "type" "add")])
2213
2214 (define_insn_and_split "*neg<mode>2_dot"
2215 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2216 (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2217 (const_int 0)))
2218 (clobber (match_scratch:GPR 0 "=r,r"))]
2219 "<MODE>mode == Pmode"
2220 "@
2221 neg. %0,%1
2222 #"
2223 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2224 [(set (match_dup 0)
2225 (neg:GPR (match_dup 1)))
2226 (set (match_dup 2)
2227 (compare:CC (match_dup 0)
2228 (const_int 0)))]
2229 ""
2230 [(set_attr "type" "add")
2231 (set_attr "dot" "yes")
2232 (set_attr "length" "4,8")])
2233
2234 (define_insn_and_split "*neg<mode>2_dot2"
2235 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2236 (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2237 (const_int 0)))
2238 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2239 (neg:GPR (match_dup 1)))]
2240 "<MODE>mode == Pmode"
2241 "@
2242 neg. %0,%1
2243 #"
2244 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2245 [(set (match_dup 0)
2246 (neg:GPR (match_dup 1)))
2247 (set (match_dup 2)
2248 (compare:CC (match_dup 0)
2249 (const_int 0)))]
2250 ""
2251 [(set_attr "type" "add")
2252 (set_attr "dot" "yes")
2253 (set_attr "length" "4,8")])
2254
2255
2256 (define_insn "clz<mode>2"
2257 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2258 (clz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2259 ""
2260 "cntlz<wd> %0,%1"
2261 [(set_attr "type" "cntlz")])
2262
2263 (define_expand "ctz<mode>2"
2264 [(set (match_operand:GPR 0 "gpc_reg_operand")
2265 (ctz:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2266 ""
2267 {
2268 if (TARGET_CTZ)
2269 {
2270 emit_insn (gen_ctz<mode>2_hw (operands[0], operands[1]));
2271 DONE;
2272 }
2273
2274 rtx tmp1 = gen_reg_rtx (<MODE>mode);
2275 rtx tmp2 = gen_reg_rtx (<MODE>mode);
2276 rtx tmp3 = gen_reg_rtx (<MODE>mode);
2277
2278 if (TARGET_POPCNTD)
2279 {
2280 emit_insn (gen_add<mode>3 (tmp1, operands[1], constm1_rtx));
2281 emit_insn (gen_one_cmpl<mode>2 (tmp2, operands[1]));
2282 emit_insn (gen_and<mode>3 (tmp3, tmp1, tmp2));
2283 emit_insn (gen_popcntd<mode>2 (operands[0], tmp3));
2284 }
2285 else
2286 {
2287 emit_insn (gen_neg<mode>2 (tmp1, operands[1]));
2288 emit_insn (gen_and<mode>3 (tmp2, operands[1], tmp1));
2289 emit_insn (gen_clz<mode>2 (tmp3, tmp2));
2290 emit_insn (gen_sub<mode>3 (operands[0], GEN_INT (<bits> - 1), tmp3));
2291 }
2292
2293 DONE;
2294 })
2295
2296 (define_insn "ctz<mode>2_hw"
2297 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2298 (ctz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2299 "TARGET_CTZ"
2300 "cnttz<wd> %0,%1"
2301 [(set_attr "type" "cntlz")])
2302
2303 (define_expand "ffs<mode>2"
2304 [(set (match_operand:GPR 0 "gpc_reg_operand")
2305 (ffs:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2306 ""
2307 {
2308 rtx tmp1 = gen_reg_rtx (<MODE>mode);
2309 rtx tmp2 = gen_reg_rtx (<MODE>mode);
2310 rtx tmp3 = gen_reg_rtx (<MODE>mode);
2311 emit_insn (gen_neg<mode>2 (tmp1, operands[1]));
2312 emit_insn (gen_and<mode>3 (tmp2, operands[1], tmp1));
2313 emit_insn (gen_clz<mode>2 (tmp3, tmp2));
2314 emit_insn (gen_sub<mode>3 (operands[0], GEN_INT (<bits>), tmp3));
2315 DONE;
2316 })
2317
2318
2319 (define_expand "popcount<mode>2"
2320 [(set (match_operand:GPR 0 "gpc_reg_operand")
2321 (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2322 "TARGET_POPCNTB || TARGET_POPCNTD"
2323 {
2324 rs6000_emit_popcount (operands[0], operands[1]);
2325 DONE;
2326 })
2327
2328 (define_insn "popcntb<mode>2"
2329 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2330 (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")]
2331 UNSPEC_POPCNTB))]
2332 "TARGET_POPCNTB"
2333 "popcntb %0,%1"
2334 [(set_attr "type" "popcnt")])
2335
2336 (define_insn "popcntd<mode>2"
2337 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2338 (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2339 "TARGET_POPCNTD"
2340 "popcnt<wd> %0,%1"
2341 [(set_attr "type" "popcnt")])
2342
2343
2344 (define_expand "parity<mode>2"
2345 [(set (match_operand:GPR 0 "gpc_reg_operand")
2346 (parity:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2347 "TARGET_POPCNTB"
2348 {
2349 rs6000_emit_parity (operands[0], operands[1]);
2350 DONE;
2351 })
2352
2353 (define_insn "parity<mode>2_cmpb"
2354 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2355 (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")] UNSPEC_PARITY))]
2356 "TARGET_CMPB && TARGET_POPCNTB"
2357 "prty<wd> %0,%1"
2358 [(set_attr "type" "popcnt")])
2359
2360 (define_insn "cmpb<mode>3"
2361 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2362 (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")
2363 (match_operand:GPR 2 "gpc_reg_operand" "r")] UNSPEC_CMPB))]
2364 "TARGET_CMPB"
2365 "cmpb %0,%1,%2"
2366 [(set_attr "type" "cmp")])
2367
2368 ;; Since the hardware zeros the upper part of the register, save generating the
2369 ;; AND immediate if we are converting to unsigned
2370 (define_insn "*bswap<mode>2_extenddi"
2371 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2372 (zero_extend:DI
2373 (bswap:HSI (match_operand:HSI 1 "memory_operand" "Z"))))]
2374 "TARGET_POWERPC64"
2375 "l<wd>brx %0,%y1"
2376 [(set_attr "type" "load")])
2377
2378 (define_insn "*bswaphi2_extendsi"
2379 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2380 (zero_extend:SI
2381 (bswap:HI (match_operand:HI 1 "memory_operand" "Z"))))]
2382 ""
2383 "lhbrx %0,%y1"
2384 [(set_attr "type" "load")])
2385
2386 ;; Separate the bswap patterns into load, store, and gpr<-gpr. This prevents
2387 ;; the register allocator from converting a gpr<-gpr swap into a store and then
2388 ;; load with byte swap, which can be slower than doing it in the registers. It
2389 ;; also prevents certain failures with the RELOAD register allocator.
2390
2391 (define_expand "bswap<mode>2"
2392 [(use (match_operand:HSI 0 "reg_or_mem_operand"))
2393 (use (match_operand:HSI 1 "reg_or_mem_operand"))]
2394 ""
2395 {
2396 rtx dest = operands[0];
2397 rtx src = operands[1];
2398
2399 if (!REG_P (dest) && !REG_P (src))
2400 src = force_reg (<MODE>mode, src);
2401
2402 if (MEM_P (src))
2403 {
2404 src = rs6000_force_indexed_or_indirect_mem (src);
2405 emit_insn (gen_bswap<mode>2_load (dest, src));
2406 }
2407 else if (MEM_P (dest))
2408 {
2409 dest = rs6000_force_indexed_or_indirect_mem (dest);
2410 emit_insn (gen_bswap<mode>2_store (dest, src));
2411 }
2412 else
2413 emit_insn (gen_bswap<mode>2_reg (dest, src));
2414 DONE;
2415 })
2416
2417 (define_insn "bswap<mode>2_load"
2418 [(set (match_operand:HSI 0 "gpc_reg_operand" "=r")
2419 (bswap:HSI (match_operand:HSI 1 "indexed_or_indirect_operand" "Z")))]
2420 ""
2421 "l<wd>brx %0,%y1"
2422 [(set_attr "type" "load")])
2423
2424 (define_insn "bswap<mode>2_store"
2425 [(set (match_operand:HSI 0 "indexed_or_indirect_operand" "=Z")
2426 (bswap:HSI (match_operand:HSI 1 "gpc_reg_operand" "r")))]
2427 ""
2428 "st<wd>brx %1,%y0"
2429 [(set_attr "type" "store")])
2430
2431 (define_insn_and_split "bswaphi2_reg"
2432 [(set (match_operand:HI 0 "gpc_reg_operand" "=&r,wo")
2433 (bswap:HI
2434 (match_operand:HI 1 "gpc_reg_operand" "r,wo")))
2435 (clobber (match_scratch:SI 2 "=&r,X"))]
2436 ""
2437 "@
2438 #
2439 xxbrh %x0,%x1"
2440 "reload_completed && int_reg_operand (operands[0], HImode)"
2441 [(set (match_dup 3)
2442 (and:SI (lshiftrt:SI (match_dup 4)
2443 (const_int 8))
2444 (const_int 255)))
2445 (set (match_dup 2)
2446 (and:SI (ashift:SI (match_dup 4)
2447 (const_int 8))
2448 (const_int 65280))) ;; 0xff00
2449 (set (match_dup 3)
2450 (ior:SI (match_dup 3)
2451 (match_dup 2)))]
2452 {
2453 operands[3] = simplify_gen_subreg (SImode, operands[0], HImode, 0);
2454 operands[4] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
2455 }
2456 [(set_attr "length" "12,4")
2457 (set_attr "type" "*,vecperm")])
2458
2459 ;; We are always BITS_BIG_ENDIAN, so the bit positions below in
2460 ;; zero_extract insns do not change for -mlittle.
2461 (define_insn_and_split "bswapsi2_reg"
2462 [(set (match_operand:SI 0 "gpc_reg_operand" "=&r,wo")
2463 (bswap:SI
2464 (match_operand:SI 1 "gpc_reg_operand" "r,wo")))]
2465 ""
2466 "@
2467 #
2468 xxbrw %x0,%x1"
2469 "reload_completed && int_reg_operand (operands[0], SImode)"
2470 [(set (match_dup 0) ; DABC
2471 (rotate:SI (match_dup 1)
2472 (const_int 24)))
2473 (set (match_dup 0) ; DCBC
2474 (ior:SI (and:SI (ashift:SI (match_dup 1)
2475 (const_int 8))
2476 (const_int 16711680))
2477 (and:SI (match_dup 0)
2478 (const_int -16711681))))
2479 (set (match_dup 0) ; DCBA
2480 (ior:SI (and:SI (lshiftrt:SI (match_dup 1)
2481 (const_int 24))
2482 (const_int 255))
2483 (and:SI (match_dup 0)
2484 (const_int -256))))]
2485 ""
2486 [(set_attr "length" "12,4")
2487 (set_attr "type" "*,vecperm")])
2488
2489 ;; On systems with LDBRX/STDBRX generate the loads/stores directly, just like
2490 ;; we do for L{H,W}BRX and ST{H,W}BRX above. If not, we have to generate more
2491 ;; complex code.
2492
2493 (define_expand "bswapdi2"
2494 [(parallel [(set (match_operand:DI 0 "reg_or_mem_operand")
2495 (bswap:DI
2496 (match_operand:DI 1 "reg_or_mem_operand")))
2497 (clobber (match_scratch:DI 2))
2498 (clobber (match_scratch:DI 3))])]
2499 ""
2500 {
2501 rtx dest = operands[0];
2502 rtx src = operands[1];
2503
2504 if (!REG_P (dest) && !REG_P (src))
2505 operands[1] = src = force_reg (DImode, src);
2506
2507 if (TARGET_POWERPC64 && TARGET_LDBRX)
2508 {
2509 if (MEM_P (src))
2510 {
2511 src = rs6000_force_indexed_or_indirect_mem (src);
2512 emit_insn (gen_bswapdi2_load (dest, src));
2513 }
2514 else if (MEM_P (dest))
2515 {
2516 dest = rs6000_force_indexed_or_indirect_mem (dest);
2517 emit_insn (gen_bswapdi2_store (dest, src));
2518 }
2519 else if (TARGET_P9_VECTOR)
2520 emit_insn (gen_bswapdi2_xxbrd (dest, src));
2521 else
2522 emit_insn (gen_bswapdi2_reg (dest, src));
2523 DONE;
2524 }
2525
2526 if (!TARGET_POWERPC64)
2527 {
2528 /* 32-bit mode needs fewer scratch registers, but 32-bit addressing mode
2529 that uses 64-bit registers needs the same scratch registers as 64-bit
2530 mode. */
2531 emit_insn (gen_bswapdi2_32bit (dest, src));
2532 DONE;
2533 }
2534 })
2535
2536 ;; Power7/cell has ldbrx/stdbrx, so use it directly
2537 (define_insn "bswapdi2_load"
2538 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2539 (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand" "Z")))]
2540 "TARGET_POWERPC64 && TARGET_LDBRX"
2541 "ldbrx %0,%y1"
2542 [(set_attr "type" "load")])
2543
2544 (define_insn "bswapdi2_store"
2545 [(set (match_operand:DI 0 "indexed_or_indirect_operand" "=Z")
2546 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "r")))]
2547 "TARGET_POWERPC64 && TARGET_LDBRX"
2548 "stdbrx %1,%y0"
2549 [(set_attr "type" "store")])
2550
2551 (define_insn "bswapdi2_xxbrd"
2552 [(set (match_operand:DI 0 "gpc_reg_operand" "=wo")
2553 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "wo")))]
2554 "TARGET_P9_VECTOR"
2555 "xxbrd %x0,%x1"
2556 [(set_attr "type" "vecperm")])
2557
2558 (define_insn "bswapdi2_reg"
2559 [(set (match_operand:DI 0 "gpc_reg_operand" "=&r")
2560 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "r")))
2561 (clobber (match_scratch:DI 2 "=&r"))
2562 (clobber (match_scratch:DI 3 "=&r"))]
2563 "TARGET_POWERPC64 && TARGET_LDBRX && !TARGET_P9_VECTOR"
2564 "#"
2565 [(set_attr "length" "36")])
2566
2567 ;; Non-power7/cell, fall back to use lwbrx/stwbrx
2568 (define_insn "*bswapdi2_64bit"
2569 [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,&r")
2570 (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2571 (clobber (match_scratch:DI 2 "=&b,&b,&r"))
2572 (clobber (match_scratch:DI 3 "=&r,&r,&r"))]
2573 "TARGET_POWERPC64 && !TARGET_LDBRX
2574 && (REG_P (operands[0]) || REG_P (operands[1]))
2575 && !(MEM_P (operands[0]) && MEM_VOLATILE_P (operands[0]))
2576 && !(MEM_P (operands[1]) && MEM_VOLATILE_P (operands[1]))"
2577 "#"
2578 [(set_attr "length" "16,12,36")])
2579
2580 (define_split
2581 [(set (match_operand:DI 0 "gpc_reg_operand")
2582 (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand")))
2583 (clobber (match_operand:DI 2 "gpc_reg_operand"))
2584 (clobber (match_operand:DI 3 "gpc_reg_operand"))]
2585 "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2586 [(const_int 0)]
2587 {
2588 rtx dest = operands[0];
2589 rtx src = operands[1];
2590 rtx op2 = operands[2];
2591 rtx op3 = operands[3];
2592 rtx op3_32 = simplify_gen_subreg (SImode, op3, DImode,
2593 BYTES_BIG_ENDIAN ? 4 : 0);
2594 rtx dest_32 = simplify_gen_subreg (SImode, dest, DImode,
2595 BYTES_BIG_ENDIAN ? 4 : 0);
2596 rtx addr1;
2597 rtx addr2;
2598 rtx word1;
2599 rtx word2;
2600
2601 addr1 = XEXP (src, 0);
2602 if (GET_CODE (addr1) == PLUS)
2603 {
2604 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2605 if (TARGET_AVOID_XFORM)
2606 {
2607 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2608 addr2 = op2;
2609 }
2610 else
2611 addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2612 }
2613 else if (TARGET_AVOID_XFORM)
2614 {
2615 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2616 addr2 = op2;
2617 }
2618 else
2619 {
2620 emit_move_insn (op2, GEN_INT (4));
2621 addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2622 }
2623
2624 word1 = change_address (src, SImode, addr1);
2625 word2 = change_address (src, SImode, addr2);
2626
2627 if (BYTES_BIG_ENDIAN)
2628 {
2629 emit_insn (gen_bswapsi2 (op3_32, word2));
2630 emit_insn (gen_bswapsi2 (dest_32, word1));
2631 }
2632 else
2633 {
2634 emit_insn (gen_bswapsi2 (op3_32, word1));
2635 emit_insn (gen_bswapsi2 (dest_32, word2));
2636 }
2637
2638 emit_insn (gen_ashldi3 (op3, op3, GEN_INT (32)));
2639 emit_insn (gen_iordi3 (dest, dest, op3));
2640 DONE;
2641 })
2642
2643 (define_split
2644 [(set (match_operand:DI 0 "indexed_or_indirect_operand")
2645 (bswap:DI (match_operand:DI 1 "gpc_reg_operand")))
2646 (clobber (match_operand:DI 2 "gpc_reg_operand"))
2647 (clobber (match_operand:DI 3 "gpc_reg_operand"))]
2648 "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2649 [(const_int 0)]
2650 {
2651 rtx dest = operands[0];
2652 rtx src = operands[1];
2653 rtx op2 = operands[2];
2654 rtx op3 = operands[3];
2655 rtx src_si = simplify_gen_subreg (SImode, src, DImode,
2656 BYTES_BIG_ENDIAN ? 4 : 0);
2657 rtx op3_si = simplify_gen_subreg (SImode, op3, DImode,
2658 BYTES_BIG_ENDIAN ? 4 : 0);
2659 rtx addr1;
2660 rtx addr2;
2661 rtx word1;
2662 rtx word2;
2663
2664 addr1 = XEXP (dest, 0);
2665 if (GET_CODE (addr1) == PLUS)
2666 {
2667 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2668 if (TARGET_AVOID_XFORM)
2669 {
2670 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2671 addr2 = op2;
2672 }
2673 else
2674 addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2675 }
2676 else if (TARGET_AVOID_XFORM)
2677 {
2678 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2679 addr2 = op2;
2680 }
2681 else
2682 {
2683 emit_move_insn (op2, GEN_INT (4));
2684 addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2685 }
2686
2687 word1 = change_address (dest, SImode, addr1);
2688 word2 = change_address (dest, SImode, addr2);
2689
2690 emit_insn (gen_lshrdi3 (op3, src, GEN_INT (32)));
2691
2692 if (BYTES_BIG_ENDIAN)
2693 {
2694 emit_insn (gen_bswapsi2 (word1, src_si));
2695 emit_insn (gen_bswapsi2 (word2, op3_si));
2696 }
2697 else
2698 {
2699 emit_insn (gen_bswapsi2 (word2, src_si));
2700 emit_insn (gen_bswapsi2 (word1, op3_si));
2701 }
2702 DONE;
2703 })
2704
2705 (define_split
2706 [(set (match_operand:DI 0 "gpc_reg_operand")
2707 (bswap:DI (match_operand:DI 1 "gpc_reg_operand")))
2708 (clobber (match_operand:DI 2 "gpc_reg_operand"))
2709 (clobber (match_operand:DI 3 "gpc_reg_operand"))]
2710 "TARGET_POWERPC64 && !TARGET_P9_VECTOR && reload_completed"
2711 [(const_int 0)]
2712 {
2713 rtx dest = operands[0];
2714 rtx src = operands[1];
2715 rtx op2 = operands[2];
2716 rtx op3 = operands[3];
2717 int lo_off = BYTES_BIG_ENDIAN ? 4 : 0;
2718 rtx dest_si = simplify_gen_subreg (SImode, dest, DImode, lo_off);
2719 rtx src_si = simplify_gen_subreg (SImode, src, DImode, lo_off);
2720 rtx op2_si = simplify_gen_subreg (SImode, op2, DImode, lo_off);
2721 rtx op3_si = simplify_gen_subreg (SImode, op3, DImode, lo_off);
2722
2723 emit_insn (gen_lshrdi3 (op2, src, GEN_INT (32)));
2724 emit_insn (gen_bswapsi2 (dest_si, src_si));
2725 emit_insn (gen_bswapsi2 (op3_si, op2_si));
2726 emit_insn (gen_ashldi3 (dest, dest, GEN_INT (32)));
2727 emit_insn (gen_iordi3 (dest, dest, op3));
2728 DONE;
2729 })
2730
2731 (define_insn "bswapdi2_32bit"
2732 [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,?&r")
2733 (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2734 (clobber (match_scratch:SI 2 "=&b,&b,X"))]
2735 "!TARGET_POWERPC64 && (REG_P (operands[0]) || REG_P (operands[1]))"
2736 "#"
2737 [(set_attr "length" "16,12,36")])
2738
2739 (define_split
2740 [(set (match_operand:DI 0 "gpc_reg_operand")
2741 (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand")))
2742 (clobber (match_operand:SI 2 "gpc_reg_operand"))]
2743 "!TARGET_POWERPC64 && reload_completed"
2744 [(const_int 0)]
2745 {
2746 rtx dest = operands[0];
2747 rtx src = operands[1];
2748 rtx op2 = operands[2];
2749 rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
2750 rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
2751 rtx addr1;
2752 rtx addr2;
2753 rtx word1;
2754 rtx word2;
2755
2756 addr1 = XEXP (src, 0);
2757 if (GET_CODE (addr1) == PLUS)
2758 {
2759 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2760 if (TARGET_AVOID_XFORM
2761 || REGNO (XEXP (addr1, 1)) == REGNO (dest2))
2762 {
2763 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2764 addr2 = op2;
2765 }
2766 else
2767 addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
2768 }
2769 else if (TARGET_AVOID_XFORM
2770 || REGNO (addr1) == REGNO (dest2))
2771 {
2772 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2773 addr2 = op2;
2774 }
2775 else
2776 {
2777 emit_move_insn (op2, GEN_INT (4));
2778 addr2 = gen_rtx_PLUS (SImode, op2, addr1);
2779 }
2780
2781 word1 = change_address (src, SImode, addr1);
2782 word2 = change_address (src, SImode, addr2);
2783
2784 emit_insn (gen_bswapsi2 (dest2, word1));
2785 /* The REGNO (dest2) tests above ensure that addr2 has not been trashed,
2786 thus allowing us to omit an early clobber on the output. */
2787 emit_insn (gen_bswapsi2 (dest1, word2));
2788 DONE;
2789 })
2790
2791 (define_split
2792 [(set (match_operand:DI 0 "indexed_or_indirect_operand")
2793 (bswap:DI (match_operand:DI 1 "gpc_reg_operand")))
2794 (clobber (match_operand:SI 2 "gpc_reg_operand"))]
2795 "!TARGET_POWERPC64 && reload_completed"
2796 [(const_int 0)]
2797 {
2798 rtx dest = operands[0];
2799 rtx src = operands[1];
2800 rtx op2 = operands[2];
2801 rtx src1 = simplify_gen_subreg (SImode, src, DImode, 0);
2802 rtx src2 = simplify_gen_subreg (SImode, src, DImode, 4);
2803 rtx addr1;
2804 rtx addr2;
2805 rtx word1;
2806 rtx word2;
2807
2808 addr1 = XEXP (dest, 0);
2809 if (GET_CODE (addr1) == PLUS)
2810 {
2811 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2812 if (TARGET_AVOID_XFORM)
2813 {
2814 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2815 addr2 = op2;
2816 }
2817 else
2818 addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
2819 }
2820 else if (TARGET_AVOID_XFORM)
2821 {
2822 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2823 addr2 = op2;
2824 }
2825 else
2826 {
2827 emit_move_insn (op2, GEN_INT (4));
2828 addr2 = gen_rtx_PLUS (SImode, op2, addr1);
2829 }
2830
2831 word1 = change_address (dest, SImode, addr1);
2832 word2 = change_address (dest, SImode, addr2);
2833
2834 emit_insn (gen_bswapsi2 (word2, src1));
2835 emit_insn (gen_bswapsi2 (word1, src2));
2836 DONE;
2837 })
2838
2839 (define_split
2840 [(set (match_operand:DI 0 "gpc_reg_operand")
2841 (bswap:DI (match_operand:DI 1 "gpc_reg_operand")))
2842 (clobber (match_operand:SI 2 ""))]
2843 "!TARGET_POWERPC64 && reload_completed"
2844 [(const_int 0)]
2845 {
2846 rtx dest = operands[0];
2847 rtx src = operands[1];
2848 rtx src1 = simplify_gen_subreg (SImode, src, DImode, 0);
2849 rtx src2 = simplify_gen_subreg (SImode, src, DImode, 4);
2850 rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
2851 rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
2852
2853 emit_insn (gen_bswapsi2 (dest1, src2));
2854 emit_insn (gen_bswapsi2 (dest2, src1));
2855 DONE;
2856 })
2857
2858
2859 (define_insn "mul<mode>3"
2860 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2861 (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
2862 (match_operand:GPR 2 "reg_or_short_operand" "r,I")))]
2863 ""
2864 "@
2865 mull<wd> %0,%1,%2
2866 mulli %0,%1,%2"
2867 [(set_attr "type" "mul")
2868 (set (attr "size")
2869 (cond [(match_operand:GPR 2 "s8bit_cint_operand")
2870 (const_string "8")
2871 (match_operand:GPR 2 "short_cint_operand")
2872 (const_string "16")]
2873 (const_string "<bits>")))])
2874
2875 (define_insn_and_split "*mul<mode>3_dot"
2876 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2877 (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2878 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
2879 (const_int 0)))
2880 (clobber (match_scratch:GPR 0 "=r,r"))]
2881 "<MODE>mode == Pmode"
2882 "@
2883 mull<wd>. %0,%1,%2
2884 #"
2885 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2886 [(set (match_dup 0)
2887 (mult:GPR (match_dup 1)
2888 (match_dup 2)))
2889 (set (match_dup 3)
2890 (compare:CC (match_dup 0)
2891 (const_int 0)))]
2892 ""
2893 [(set_attr "type" "mul")
2894 (set_attr "size" "<bits>")
2895 (set_attr "dot" "yes")
2896 (set_attr "length" "4,8")])
2897
2898 (define_insn_and_split "*mul<mode>3_dot2"
2899 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2900 (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2901 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
2902 (const_int 0)))
2903 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2904 (mult:GPR (match_dup 1)
2905 (match_dup 2)))]
2906 "<MODE>mode == Pmode"
2907 "@
2908 mull<wd>. %0,%1,%2
2909 #"
2910 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2911 [(set (match_dup 0)
2912 (mult:GPR (match_dup 1)
2913 (match_dup 2)))
2914 (set (match_dup 3)
2915 (compare:CC (match_dup 0)
2916 (const_int 0)))]
2917 ""
2918 [(set_attr "type" "mul")
2919 (set_attr "size" "<bits>")
2920 (set_attr "dot" "yes")
2921 (set_attr "length" "4,8")])
2922
2923
2924 (define_expand "<su>mul<mode>3_highpart"
2925 [(set (match_operand:GPR 0 "gpc_reg_operand")
2926 (subreg:GPR
2927 (mult:<DMODE> (any_extend:<DMODE>
2928 (match_operand:GPR 1 "gpc_reg_operand"))
2929 (any_extend:<DMODE>
2930 (match_operand:GPR 2 "gpc_reg_operand")))
2931 0))]
2932 ""
2933 {
2934 if (<MODE>mode == SImode && TARGET_POWERPC64)
2935 {
2936 emit_insn (gen_<su>mulsi3_highpart_64 (operands[0], operands[1],
2937 operands[2]));
2938 DONE;
2939 }
2940
2941 if (!WORDS_BIG_ENDIAN)
2942 {
2943 emit_insn (gen_<su>mul<mode>3_highpart_le (operands[0], operands[1],
2944 operands[2]));
2945 DONE;
2946 }
2947 })
2948
2949 (define_insn "*<su>mul<mode>3_highpart"
2950 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2951 (subreg:GPR
2952 (mult:<DMODE> (any_extend:<DMODE>
2953 (match_operand:GPR 1 "gpc_reg_operand" "r"))
2954 (any_extend:<DMODE>
2955 (match_operand:GPR 2 "gpc_reg_operand" "r")))
2956 0))]
2957 "WORDS_BIG_ENDIAN && !(<MODE>mode == SImode && TARGET_POWERPC64)"
2958 "mulh<wd><u> %0,%1,%2"
2959 [(set_attr "type" "mul")
2960 (set_attr "size" "<bits>")])
2961
2962 (define_insn "<su>mulsi3_highpart_le"
2963 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2964 (subreg:SI
2965 (mult:DI (any_extend:DI
2966 (match_operand:SI 1 "gpc_reg_operand" "r"))
2967 (any_extend:DI
2968 (match_operand:SI 2 "gpc_reg_operand" "r")))
2969 4))]
2970 "!WORDS_BIG_ENDIAN && !TARGET_POWERPC64"
2971 "mulhw<u> %0,%1,%2"
2972 [(set_attr "type" "mul")])
2973
2974 (define_insn "<su>muldi3_highpart_le"
2975 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2976 (subreg:DI
2977 (mult:TI (any_extend:TI
2978 (match_operand:DI 1 "gpc_reg_operand" "r"))
2979 (any_extend:TI
2980 (match_operand:DI 2 "gpc_reg_operand" "r")))
2981 8))]
2982 "!WORDS_BIG_ENDIAN && TARGET_POWERPC64"
2983 "mulhd<u> %0,%1,%2"
2984 [(set_attr "type" "mul")
2985 (set_attr "size" "64")])
2986
2987 (define_insn "<su>mulsi3_highpart_64"
2988 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2989 (truncate:SI
2990 (lshiftrt:DI
2991 (mult:DI (any_extend:DI
2992 (match_operand:SI 1 "gpc_reg_operand" "r"))
2993 (any_extend:DI
2994 (match_operand:SI 2 "gpc_reg_operand" "r")))
2995 (const_int 32))))]
2996 "TARGET_POWERPC64"
2997 "mulhw<u> %0,%1,%2"
2998 [(set_attr "type" "mul")])
2999
3000 (define_expand "<u>mul<mode><dmode>3"
3001 [(set (match_operand:<DMODE> 0 "gpc_reg_operand")
3002 (mult:<DMODE> (any_extend:<DMODE>
3003 (match_operand:GPR 1 "gpc_reg_operand"))
3004 (any_extend:<DMODE>
3005 (match_operand:GPR 2 "gpc_reg_operand"))))]
3006 "!(<MODE>mode == SImode && TARGET_POWERPC64)"
3007 {
3008 rtx l = gen_reg_rtx (<MODE>mode);
3009 rtx h = gen_reg_rtx (<MODE>mode);
3010 emit_insn (gen_mul<mode>3 (l, operands[1], operands[2]));
3011 emit_insn (gen_<su>mul<mode>3_highpart (h, operands[1], operands[2]));
3012 emit_move_insn (gen_lowpart (<MODE>mode, operands[0]), l);
3013 emit_move_insn (gen_highpart (<MODE>mode, operands[0]), h);
3014 DONE;
3015 })
3016
3017 (define_insn "*maddld4"
3018 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3019 (plus:DI (mult:DI (match_operand:DI 1 "gpc_reg_operand" "r")
3020 (match_operand:DI 2 "gpc_reg_operand" "r"))
3021 (match_operand:DI 3 "gpc_reg_operand" "r")))]
3022 "TARGET_MADDLD"
3023 "maddld %0,%1,%2,%3"
3024 [(set_attr "type" "mul")])
3025
3026 (define_insn "udiv<mode>3"
3027 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3028 (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3029 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3030 ""
3031 "div<wd>u %0,%1,%2"
3032 [(set_attr "type" "div")
3033 (set_attr "size" "<bits>")])
3034
3035
3036 ;; For powers of two we can do sra[wd]i/addze for divide and then adjust for
3037 ;; modulus. If it isn't a power of two, force operands into register and do
3038 ;; a normal divide.
3039 (define_expand "div<mode>3"
3040 [(set (match_operand:GPR 0 "gpc_reg_operand")
3041 (div:GPR (match_operand:GPR 1 "gpc_reg_operand")
3042 (match_operand:GPR 2 "reg_or_cint_operand")))]
3043 ""
3044 {
3045 if (CONST_INT_P (operands[2])
3046 && INTVAL (operands[2]) > 0
3047 && exact_log2 (INTVAL (operands[2])) >= 0)
3048 {
3049 emit_insn (gen_div<mode>3_sra (operands[0], operands[1], operands[2]));
3050 DONE;
3051 }
3052
3053 operands[2] = force_reg (<MODE>mode, operands[2]);
3054 })
3055
3056 (define_insn "*div<mode>3"
3057 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3058 (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3059 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3060 ""
3061 "div<wd> %0,%1,%2"
3062 [(set_attr "type" "div")
3063 (set_attr "size" "<bits>")])
3064
3065 (define_insn "div<mode>3_sra"
3066 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3067 (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3068 (match_operand:GPR 2 "exact_log2_cint_operand" "N")))
3069 (clobber (reg:GPR CA_REGNO))]
3070 ""
3071 "sra<wd>i %0,%1,%p2\;addze %0,%0"
3072 [(set_attr "type" "two")
3073 (set_attr "length" "8")])
3074
3075 (define_insn_and_split "*div<mode>3_sra_dot"
3076 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3077 (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3078 (match_operand:GPR 2 "exact_log2_cint_operand" "N,N"))
3079 (const_int 0)))
3080 (clobber (match_scratch:GPR 0 "=r,r"))
3081 (clobber (reg:GPR CA_REGNO))]
3082 "<MODE>mode == Pmode"
3083 "@
3084 sra<wd>i %0,%1,%p2\;addze. %0,%0
3085 #"
3086 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3087 [(parallel [(set (match_dup 0)
3088 (div:GPR (match_dup 1)
3089 (match_dup 2)))
3090 (clobber (reg:GPR CA_REGNO))])
3091 (set (match_dup 3)
3092 (compare:CC (match_dup 0)
3093 (const_int 0)))]
3094 ""
3095 [(set_attr "type" "two")
3096 (set_attr "length" "8,12")
3097 (set_attr "cell_micro" "not")])
3098
3099 (define_insn_and_split "*div<mode>3_sra_dot2"
3100 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3101 (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3102 (match_operand:GPR 2 "exact_log2_cint_operand" "N,N"))
3103 (const_int 0)))
3104 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3105 (div:GPR (match_dup 1)
3106 (match_dup 2)))
3107 (clobber (reg:GPR CA_REGNO))]
3108 "<MODE>mode == Pmode"
3109 "@
3110 sra<wd>i %0,%1,%p2\;addze. %0,%0
3111 #"
3112 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3113 [(parallel [(set (match_dup 0)
3114 (div:GPR (match_dup 1)
3115 (match_dup 2)))
3116 (clobber (reg:GPR CA_REGNO))])
3117 (set (match_dup 3)
3118 (compare:CC (match_dup 0)
3119 (const_int 0)))]
3120 ""
3121 [(set_attr "type" "two")
3122 (set_attr "length" "8,12")
3123 (set_attr "cell_micro" "not")])
3124
3125 (define_expand "mod<mode>3"
3126 [(set (match_operand:GPR 0 "gpc_reg_operand")
3127 (mod:GPR (match_operand:GPR 1 "gpc_reg_operand")
3128 (match_operand:GPR 2 "reg_or_cint_operand")))]
3129 ""
3130 {
3131 int i;
3132 rtx temp1;
3133 rtx temp2;
3134
3135 if (GET_CODE (operands[2]) != CONST_INT
3136 || INTVAL (operands[2]) <= 0
3137 || (i = exact_log2 (INTVAL (operands[2]))) < 0)
3138 {
3139 if (!TARGET_MODULO)
3140 FAIL;
3141
3142 operands[2] = force_reg (<MODE>mode, operands[2]);
3143 }
3144 else
3145 {
3146 temp1 = gen_reg_rtx (<MODE>mode);
3147 temp2 = gen_reg_rtx (<MODE>mode);
3148
3149 emit_insn (gen_div<mode>3 (temp1, operands[1], operands[2]));
3150 emit_insn (gen_ashl<mode>3 (temp2, temp1, GEN_INT (i)));
3151 emit_insn (gen_sub<mode>3 (operands[0], operands[1], temp2));
3152 DONE;
3153 }
3154 })
3155
3156 ;; In order to enable using a peephole2 for combining div/mod to eliminate the
3157 ;; mod, prefer putting the result of mod into a different register
3158 (define_insn "*mod<mode>3"
3159 [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
3160 (mod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3161 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3162 "TARGET_MODULO"
3163 "mods<wd> %0,%1,%2"
3164 [(set_attr "type" "div")
3165 (set_attr "size" "<bits>")])
3166
3167
3168 (define_insn "umod<mode>3"
3169 [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
3170 (umod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3171 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3172 "TARGET_MODULO"
3173 "modu<wd> %0,%1,%2"
3174 [(set_attr "type" "div")
3175 (set_attr "size" "<bits>")])
3176
3177 ;; On machines with modulo support, do a combined div/mod the old fashioned
3178 ;; method, since the multiply/subtract is faster than doing the mod instruction
3179 ;; after a divide.
3180
3181 (define_peephole2
3182 [(set (match_operand:GPR 0 "gpc_reg_operand")
3183 (div:GPR (match_operand:GPR 1 "gpc_reg_operand")
3184 (match_operand:GPR 2 "gpc_reg_operand")))
3185 (set (match_operand:GPR 3 "gpc_reg_operand")
3186 (mod:GPR (match_dup 1)
3187 (match_dup 2)))]
3188 "TARGET_MODULO
3189 && ! reg_mentioned_p (operands[0], operands[1])
3190 && ! reg_mentioned_p (operands[0], operands[2])
3191 && ! reg_mentioned_p (operands[3], operands[1])
3192 && ! reg_mentioned_p (operands[3], operands[2])"
3193 [(set (match_dup 0)
3194 (div:GPR (match_dup 1)
3195 (match_dup 2)))
3196 (set (match_dup 3)
3197 (mult:GPR (match_dup 0)
3198 (match_dup 2)))
3199 (set (match_dup 3)
3200 (minus:GPR (match_dup 1)
3201 (match_dup 3)))])
3202
3203 (define_peephole2
3204 [(set (match_operand:GPR 0 "gpc_reg_operand")
3205 (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand")
3206 (match_operand:GPR 2 "gpc_reg_operand")))
3207 (set (match_operand:GPR 3 "gpc_reg_operand")
3208 (umod:GPR (match_dup 1)
3209 (match_dup 2)))]
3210 "TARGET_MODULO
3211 && ! reg_mentioned_p (operands[0], operands[1])
3212 && ! reg_mentioned_p (operands[0], operands[2])
3213 && ! reg_mentioned_p (operands[3], operands[1])
3214 && ! reg_mentioned_p (operands[3], operands[2])"
3215 [(set (match_dup 0)
3216 (udiv:GPR (match_dup 1)
3217 (match_dup 2)))
3218 (set (match_dup 3)
3219 (mult:GPR (match_dup 0)
3220 (match_dup 2)))
3221 (set (match_dup 3)
3222 (minus:GPR (match_dup 1)
3223 (match_dup 3)))])
3224
3225 \f
3226 ;; Logical instructions
3227 ;; The logical instructions are mostly combined by using match_operator,
3228 ;; but the plain AND insns are somewhat different because there is no
3229 ;; plain 'andi' (only 'andi.'), no plain 'andis', and there are all
3230 ;; those rotate-and-mask operations. Thus, the AND insns come first.
3231
3232 (define_expand "and<mode>3"
3233 [(set (match_operand:SDI 0 "gpc_reg_operand")
3234 (and:SDI (match_operand:SDI 1 "gpc_reg_operand")
3235 (match_operand:SDI 2 "reg_or_cint_operand")))]
3236 ""
3237 {
3238 if (<MODE>mode == DImode && !TARGET_POWERPC64)
3239 {
3240 rs6000_split_logical (operands, AND, false, false, false);
3241 DONE;
3242 }
3243
3244 if (CONST_INT_P (operands[2]))
3245 {
3246 if (rs6000_is_valid_and_mask (operands[2], <MODE>mode))
3247 {
3248 emit_insn (gen_and<mode>3_mask (operands[0], operands[1], operands[2]));
3249 DONE;
3250 }
3251
3252 if (logical_const_operand (operands[2], <MODE>mode))
3253 {
3254 emit_insn (gen_and<mode>3_imm (operands[0], operands[1], operands[2]));
3255 DONE;
3256 }
3257
3258 if (rs6000_is_valid_2insn_and (operands[2], <MODE>mode))
3259 {
3260 rs6000_emit_2insn_and (<MODE>mode, operands, true, 0);
3261 DONE;
3262 }
3263
3264 operands[2] = force_reg (<MODE>mode, operands[2]);
3265 }
3266 })
3267
3268
3269 (define_insn "and<mode>3_imm"
3270 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3271 (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3272 (match_operand:GPR 2 "logical_const_operand" "n")))
3273 (clobber (match_scratch:CC 3 "=x"))]
3274 "!rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3275 "andi%e2. %0,%1,%u2"
3276 [(set_attr "type" "logical")
3277 (set_attr "dot" "yes")])
3278
3279 (define_insn_and_split "*and<mode>3_imm_dot"
3280 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3281 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3282 (match_operand:GPR 2 "logical_const_operand" "n,n"))
3283 (const_int 0)))
3284 (clobber (match_scratch:GPR 0 "=r,r"))
3285 (clobber (match_scratch:CC 4 "=X,x"))]
3286 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3287 && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3288 "@
3289 andi%e2. %0,%1,%u2
3290 #"
3291 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3292 [(parallel [(set (match_dup 0)
3293 (and:GPR (match_dup 1)
3294 (match_dup 2)))
3295 (clobber (match_dup 4))])
3296 (set (match_dup 3)
3297 (compare:CC (match_dup 0)
3298 (const_int 0)))]
3299 ""
3300 [(set_attr "type" "logical")
3301 (set_attr "dot" "yes")
3302 (set_attr "length" "4,8")])
3303
3304 (define_insn_and_split "*and<mode>3_imm_dot2"
3305 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3306 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3307 (match_operand:GPR 2 "logical_const_operand" "n,n"))
3308 (const_int 0)))
3309 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3310 (and:GPR (match_dup 1)
3311 (match_dup 2)))
3312 (clobber (match_scratch:CC 4 "=X,x"))]
3313 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3314 && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3315 "@
3316 andi%e2. %0,%1,%u2
3317 #"
3318 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3319 [(parallel [(set (match_dup 0)
3320 (and:GPR (match_dup 1)
3321 (match_dup 2)))
3322 (clobber (match_dup 4))])
3323 (set (match_dup 3)
3324 (compare:CC (match_dup 0)
3325 (const_int 0)))]
3326 ""
3327 [(set_attr "type" "logical")
3328 (set_attr "dot" "yes")
3329 (set_attr "length" "4,8")])
3330
3331 (define_insn_and_split "*and<mode>3_imm_mask_dot"
3332 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3333 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3334 (match_operand:GPR 2 "logical_const_operand" "n,n"))
3335 (const_int 0)))
3336 (clobber (match_scratch:GPR 0 "=r,r"))]
3337 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3338 && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3339 "@
3340 andi%e2. %0,%1,%u2
3341 #"
3342 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3343 [(set (match_dup 0)
3344 (and:GPR (match_dup 1)
3345 (match_dup 2)))
3346 (set (match_dup 3)
3347 (compare:CC (match_dup 0)
3348 (const_int 0)))]
3349 ""
3350 [(set_attr "type" "logical")
3351 (set_attr "dot" "yes")
3352 (set_attr "length" "4,8")])
3353
3354 (define_insn_and_split "*and<mode>3_imm_mask_dot2"
3355 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3356 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3357 (match_operand:GPR 2 "logical_const_operand" "n,n"))
3358 (const_int 0)))
3359 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3360 (and:GPR (match_dup 1)
3361 (match_dup 2)))]
3362 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3363 && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3364 "@
3365 andi%e2. %0,%1,%u2
3366 #"
3367 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3368 [(set (match_dup 0)
3369 (and:GPR (match_dup 1)
3370 (match_dup 2)))
3371 (set (match_dup 3)
3372 (compare:CC (match_dup 0)
3373 (const_int 0)))]
3374 ""
3375 [(set_attr "type" "logical")
3376 (set_attr "dot" "yes")
3377 (set_attr "length" "4,8")])
3378
3379 (define_insn "*and<mode>3_imm_dot_shifted"
3380 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
3381 (compare:CC
3382 (and:GPR
3383 (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3384 (match_operand:SI 4 "const_int_operand" "n"))
3385 (match_operand:GPR 2 "const_int_operand" "n"))
3386 (const_int 0)))
3387 (clobber (match_scratch:GPR 0 "=r"))]
3388 "logical_const_operand (GEN_INT (UINTVAL (operands[2])
3389 << INTVAL (operands[4])),
3390 DImode)
3391 && (<MODE>mode == Pmode
3392 || (UINTVAL (operands[2]) << INTVAL (operands[4])) <= 0x7fffffff)"
3393 {
3394 operands[2] = GEN_INT (UINTVAL (operands[2]) << INTVAL (operands[4]));
3395 return "andi%e2. %0,%1,%u2";
3396 }
3397 [(set_attr "type" "logical")
3398 (set_attr "dot" "yes")])
3399
3400
3401 (define_insn "and<mode>3_mask"
3402 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3403 (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3404 (match_operand:GPR 2 "const_int_operand" "n")))]
3405 "rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3406 {
3407 return rs6000_insn_for_and_mask (<MODE>mode, operands, false);
3408 }
3409 [(set_attr "type" "shift")])
3410
3411 (define_insn_and_split "*and<mode>3_mask_dot"
3412 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3413 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3414 (match_operand:GPR 2 "const_int_operand" "n,n"))
3415 (const_int 0)))
3416 (clobber (match_scratch:GPR 0 "=r,r"))]
3417 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3418 && !logical_const_operand (operands[2], <MODE>mode)
3419 && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3420 {
3421 if (which_alternative == 0)
3422 return rs6000_insn_for_and_mask (<MODE>mode, operands, true);
3423 else
3424 return "#";
3425 }
3426 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3427 [(set (match_dup 0)
3428 (and:GPR (match_dup 1)
3429 (match_dup 2)))
3430 (set (match_dup 3)
3431 (compare:CC (match_dup 0)
3432 (const_int 0)))]
3433 ""
3434 [(set_attr "type" "shift")
3435 (set_attr "dot" "yes")
3436 (set_attr "length" "4,8")])
3437
3438 (define_insn_and_split "*and<mode>3_mask_dot2"
3439 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3440 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3441 (match_operand:GPR 2 "const_int_operand" "n,n"))
3442 (const_int 0)))
3443 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3444 (and:GPR (match_dup 1)
3445 (match_dup 2)))]
3446 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3447 && !logical_const_operand (operands[2], <MODE>mode)
3448 && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3449 {
3450 if (which_alternative == 0)
3451 return rs6000_insn_for_and_mask (<MODE>mode, operands, true);
3452 else
3453 return "#";
3454 }
3455 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3456 [(set (match_dup 0)
3457 (and:GPR (match_dup 1)
3458 (match_dup 2)))
3459 (set (match_dup 3)
3460 (compare:CC (match_dup 0)
3461 (const_int 0)))]
3462 ""
3463 [(set_attr "type" "shift")
3464 (set_attr "dot" "yes")
3465 (set_attr "length" "4,8")])
3466
3467
3468 (define_insn_and_split "*and<mode>3_2insn"
3469 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3470 (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3471 (match_operand:GPR 2 "const_int_operand" "n")))]
3472 "rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3473 && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3474 || logical_const_operand (operands[2], <MODE>mode))"
3475 "#"
3476 "&& 1"
3477 [(pc)]
3478 {
3479 rs6000_emit_2insn_and (<MODE>mode, operands, false, 0);
3480 DONE;
3481 }
3482 [(set_attr "type" "shift")
3483 (set_attr "length" "8")])
3484
3485 (define_insn_and_split "*and<mode>3_2insn_dot"
3486 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3487 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3488 (match_operand:GPR 2 "const_int_operand" "n,n"))
3489 (const_int 0)))
3490 (clobber (match_scratch:GPR 0 "=r,r"))]
3491 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3492 && rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3493 && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3494 || logical_const_operand (operands[2], <MODE>mode))"
3495 "#"
3496 "&& reload_completed"
3497 [(pc)]
3498 {
3499 rs6000_emit_2insn_and (<MODE>mode, operands, false, 1);
3500 DONE;
3501 }
3502 [(set_attr "type" "shift")
3503 (set_attr "dot" "yes")
3504 (set_attr "length" "8,12")])
3505
3506 (define_insn_and_split "*and<mode>3_2insn_dot2"
3507 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3508 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3509 (match_operand:GPR 2 "const_int_operand" "n,n"))
3510 (const_int 0)))
3511 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3512 (and:GPR (match_dup 1)
3513 (match_dup 2)))]
3514 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3515 && rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3516 && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3517 || logical_const_operand (operands[2], <MODE>mode))"
3518 "#"
3519 "&& reload_completed"
3520 [(pc)]
3521 {
3522 rs6000_emit_2insn_and (<MODE>mode, operands, false, 2);
3523 DONE;
3524 }
3525 [(set_attr "type" "shift")
3526 (set_attr "dot" "yes")
3527 (set_attr "length" "8,12")])
3528
3529
3530 (define_expand "<code><mode>3"
3531 [(set (match_operand:SDI 0 "gpc_reg_operand")
3532 (iorxor:SDI (match_operand:SDI 1 "gpc_reg_operand")
3533 (match_operand:SDI 2 "reg_or_cint_operand")))]
3534 ""
3535 {
3536 if (<MODE>mode == DImode && !TARGET_POWERPC64)
3537 {
3538 rs6000_split_logical (operands, <CODE>, false, false, false);
3539 DONE;
3540 }
3541
3542 if (non_logical_cint_operand (operands[2], <MODE>mode))
3543 {
3544 rtx tmp = ((!can_create_pseudo_p ()
3545 || rtx_equal_p (operands[0], operands[1]))
3546 ? operands[0] : gen_reg_rtx (<MODE>mode));
3547
3548 HOST_WIDE_INT value = INTVAL (operands[2]);
3549 HOST_WIDE_INT lo = value & 0xffff;
3550 HOST_WIDE_INT hi = value - lo;
3551
3552 emit_insn (gen_<code><mode>3 (tmp, operands[1], GEN_INT (hi)));
3553 emit_insn (gen_<code><mode>3 (operands[0], tmp, GEN_INT (lo)));
3554 DONE;
3555 }
3556
3557 if (!reg_or_logical_cint_operand (operands[2], <MODE>mode))
3558 operands[2] = force_reg (<MODE>mode, operands[2]);
3559 })
3560
3561 (define_split
3562 [(set (match_operand:GPR 0 "gpc_reg_operand")
3563 (iorxor:GPR (match_operand:GPR 1 "gpc_reg_operand")
3564 (match_operand:GPR 2 "non_logical_cint_operand")))]
3565 ""
3566 [(set (match_dup 3)
3567 (iorxor:GPR (match_dup 1)
3568 (match_dup 4)))
3569 (set (match_dup 0)
3570 (iorxor:GPR (match_dup 3)
3571 (match_dup 5)))]
3572 {
3573 operands[3] = ((!can_create_pseudo_p ()
3574 || rtx_equal_p (operands[0], operands[1]))
3575 ? operands[0] : gen_reg_rtx (<MODE>mode));
3576
3577 HOST_WIDE_INT value = INTVAL (operands[2]);
3578 HOST_WIDE_INT lo = value & 0xffff;
3579 HOST_WIDE_INT hi = value - lo;
3580
3581 operands[4] = GEN_INT (hi);
3582 operands[5] = GEN_INT (lo);
3583 })
3584
3585 (define_insn "*bool<mode>3_imm"
3586 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3587 (match_operator:GPR 3 "boolean_or_operator"
3588 [(match_operand:GPR 1 "gpc_reg_operand" "%r")
3589 (match_operand:GPR 2 "logical_const_operand" "n")]))]
3590 ""
3591 "%q3i%e2 %0,%1,%u2"
3592 [(set_attr "type" "logical")])
3593
3594 (define_insn "*bool<mode>3"
3595 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3596 (match_operator:GPR 3 "boolean_operator"
3597 [(match_operand:GPR 1 "gpc_reg_operand" "r")
3598 (match_operand:GPR 2 "gpc_reg_operand" "r")]))]
3599 ""
3600 "%q3 %0,%1,%2"
3601 [(set_attr "type" "logical")])
3602
3603 (define_insn_and_split "*bool<mode>3_dot"
3604 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3605 (compare:CC (match_operator:GPR 3 "boolean_operator"
3606 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3607 (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
3608 (const_int 0)))
3609 (clobber (match_scratch:GPR 0 "=r,r"))]
3610 "<MODE>mode == Pmode"
3611 "@
3612 %q3. %0,%1,%2
3613 #"
3614 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3615 [(set (match_dup 0)
3616 (match_dup 3))
3617 (set (match_dup 4)
3618 (compare:CC (match_dup 0)
3619 (const_int 0)))]
3620 ""
3621 [(set_attr "type" "logical")
3622 (set_attr "dot" "yes")
3623 (set_attr "length" "4,8")])
3624
3625 (define_insn_and_split "*bool<mode>3_dot2"
3626 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3627 (compare:CC (match_operator:GPR 3 "boolean_operator"
3628 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3629 (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
3630 (const_int 0)))
3631 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3632 (match_dup 3))]
3633 "<MODE>mode == Pmode"
3634 "@
3635 %q3. %0,%1,%2
3636 #"
3637 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3638 [(set (match_dup 0)
3639 (match_dup 3))
3640 (set (match_dup 4)
3641 (compare:CC (match_dup 0)
3642 (const_int 0)))]
3643 ""
3644 [(set_attr "type" "logical")
3645 (set_attr "dot" "yes")
3646 (set_attr "length" "4,8")])
3647
3648
3649 (define_insn "*boolc<mode>3"
3650 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3651 (match_operator:GPR 3 "boolean_operator"
3652 [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))
3653 (match_operand:GPR 1 "gpc_reg_operand" "r")]))]
3654 ""
3655 "%q3 %0,%1,%2"
3656 [(set_attr "type" "logical")])
3657
3658 (define_insn_and_split "*boolc<mode>3_dot"
3659 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3660 (compare:CC (match_operator:GPR 3 "boolean_operator"
3661 [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3662 (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
3663 (const_int 0)))
3664 (clobber (match_scratch:GPR 0 "=r,r"))]
3665 "<MODE>mode == Pmode"
3666 "@
3667 %q3. %0,%1,%2
3668 #"
3669 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3670 [(set (match_dup 0)
3671 (match_dup 3))
3672 (set (match_dup 4)
3673 (compare:CC (match_dup 0)
3674 (const_int 0)))]
3675 ""
3676 [(set_attr "type" "logical")
3677 (set_attr "dot" "yes")
3678 (set_attr "length" "4,8")])
3679
3680 (define_insn_and_split "*boolc<mode>3_dot2"
3681 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3682 (compare:CC (match_operator:GPR 3 "boolean_operator"
3683 [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3684 (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
3685 (const_int 0)))
3686 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3687 (match_dup 3))]
3688 "<MODE>mode == Pmode"
3689 "@
3690 %q3. %0,%1,%2
3691 #"
3692 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3693 [(set (match_dup 0)
3694 (match_dup 3))
3695 (set (match_dup 4)
3696 (compare:CC (match_dup 0)
3697 (const_int 0)))]
3698 ""
3699 [(set_attr "type" "logical")
3700 (set_attr "dot" "yes")
3701 (set_attr "length" "4,8")])
3702
3703
3704 (define_insn "*boolcc<mode>3"
3705 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3706 (match_operator:GPR 3 "boolean_operator"
3707 [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
3708 (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))]))]
3709 ""
3710 "%q3 %0,%1,%2"
3711 [(set_attr "type" "logical")])
3712
3713 (define_insn_and_split "*boolcc<mode>3_dot"
3714 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3715 (compare:CC (match_operator:GPR 3 "boolean_operator"
3716 [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
3717 (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
3718 (const_int 0)))
3719 (clobber (match_scratch:GPR 0 "=r,r"))]
3720 "<MODE>mode == Pmode"
3721 "@
3722 %q3. %0,%1,%2
3723 #"
3724 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3725 [(set (match_dup 0)
3726 (match_dup 3))
3727 (set (match_dup 4)
3728 (compare:CC (match_dup 0)
3729 (const_int 0)))]
3730 ""
3731 [(set_attr "type" "logical")
3732 (set_attr "dot" "yes")
3733 (set_attr "length" "4,8")])
3734
3735 (define_insn_and_split "*boolcc<mode>3_dot2"
3736 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3737 (compare:CC (match_operator:GPR 3 "boolean_operator"
3738 [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
3739 (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
3740 (const_int 0)))
3741 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3742 (match_dup 3))]
3743 "<MODE>mode == Pmode"
3744 "@
3745 %q3. %0,%1,%2
3746 #"
3747 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3748 [(set (match_dup 0)
3749 (match_dup 3))
3750 (set (match_dup 4)
3751 (compare:CC (match_dup 0)
3752 (const_int 0)))]
3753 ""
3754 [(set_attr "type" "logical")
3755 (set_attr "dot" "yes")
3756 (set_attr "length" "4,8")])
3757
3758
3759 ;; TODO: Should have dots of this as well.
3760 (define_insn "*eqv<mode>3"
3761 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3762 (not:GPR (xor:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3763 (match_operand:GPR 2 "gpc_reg_operand" "r"))))]
3764 ""
3765 "eqv %0,%1,%2"
3766 [(set_attr "type" "logical")])
3767 \f
3768 ;; Rotate-and-mask and insert.
3769
3770 (define_insn "*rotl<mode>3_mask"
3771 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3772 (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3773 [(match_operand:GPR 1 "gpc_reg_operand" "r")
3774 (match_operand:SI 2 "reg_or_cint_operand" "rn")])
3775 (match_operand:GPR 3 "const_int_operand" "n")))]
3776 "rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3777 {
3778 return rs6000_insn_for_shift_mask (<MODE>mode, operands, false);
3779 }
3780 [(set_attr "type" "shift")
3781 (set_attr "maybe_var_shift" "yes")])
3782
3783 (define_insn_and_split "*rotl<mode>3_mask_dot"
3784 [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y")
3785 (compare:CC
3786 (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3787 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3788 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")])
3789 (match_operand:GPR 3 "const_int_operand" "n,n"))
3790 (const_int 0)))
3791 (clobber (match_scratch:GPR 0 "=r,r"))]
3792 "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff)
3793 && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3794 {
3795 if (which_alternative == 0)
3796 return rs6000_insn_for_shift_mask (<MODE>mode, operands, true);
3797 else
3798 return "#";
3799 }
3800 "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)"
3801 [(set (match_dup 0)
3802 (and:GPR (match_dup 4)
3803 (match_dup 3)))
3804 (set (match_dup 5)
3805 (compare:CC (match_dup 0)
3806 (const_int 0)))]
3807 ""
3808 [(set_attr "type" "shift")
3809 (set_attr "maybe_var_shift" "yes")
3810 (set_attr "dot" "yes")
3811 (set_attr "length" "4,8")])
3812
3813 (define_insn_and_split "*rotl<mode>3_mask_dot2"
3814 [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y")
3815 (compare:CC
3816 (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3817 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3818 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")])
3819 (match_operand:GPR 3 "const_int_operand" "n,n"))
3820 (const_int 0)))
3821 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3822 (and:GPR (match_dup 4)
3823 (match_dup 3)))]
3824 "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff)
3825 && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3826 {
3827 if (which_alternative == 0)
3828 return rs6000_insn_for_shift_mask (<MODE>mode, operands, true);
3829 else
3830 return "#";
3831 }
3832 "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)"
3833 [(set (match_dup 0)
3834 (and:GPR (match_dup 4)
3835 (match_dup 3)))
3836 (set (match_dup 5)
3837 (compare:CC (match_dup 0)
3838 (const_int 0)))]
3839 ""
3840 [(set_attr "type" "shift")
3841 (set_attr "maybe_var_shift" "yes")
3842 (set_attr "dot" "yes")
3843 (set_attr "length" "4,8")])
3844
3845 ; Special case for less-than-0. We can do it with just one machine
3846 ; instruction, but the generic optimizers do not realise it is cheap.
3847 (define_insn "*lt0_<mode>di"
3848 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3849 (lt:GPR (match_operand:DI 1 "gpc_reg_operand" "r")
3850 (const_int 0)))]
3851 "TARGET_POWERPC64"
3852 "srdi %0,%1,63"
3853 [(set_attr "type" "shift")])
3854
3855 (define_insn "*lt0_<mode>si"
3856 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3857 (lt:GPR (match_operand:SI 1 "gpc_reg_operand" "r")
3858 (const_int 0)))]
3859 ""
3860 "rlwinm %0,%1,1,31,31"
3861 [(set_attr "type" "shift")])
3862
3863
3864
3865 ; Two forms for insert (the two arms of the IOR are not canonicalized,
3866 ; both are an AND so are the same precedence).
3867 (define_insn "*rotl<mode>3_insert"
3868 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3869 (ior:GPR (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3870 [(match_operand:GPR 1 "gpc_reg_operand" "r")
3871 (match_operand:SI 2 "const_int_operand" "n")])
3872 (match_operand:GPR 3 "const_int_operand" "n"))
3873 (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0")
3874 (match_operand:GPR 6 "const_int_operand" "n"))))]
3875 "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode)
3876 && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0"
3877 {
3878 return rs6000_insn_for_insert_mask (<MODE>mode, operands, false);
3879 }
3880 [(set_attr "type" "insert")])
3881 ; FIXME: this needs an attr "size", so that the scheduler can see the
3882 ; difference between rlwimi and rldimi. We also might want dot forms,
3883 ; but not for rlwimi on POWER4 and similar processors.
3884
3885 (define_insn "*rotl<mode>3_insert_2"
3886 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3887 (ior:GPR (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0")
3888 (match_operand:GPR 6 "const_int_operand" "n"))
3889 (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3890 [(match_operand:GPR 1 "gpc_reg_operand" "r")
3891 (match_operand:SI 2 "const_int_operand" "n")])
3892 (match_operand:GPR 3 "const_int_operand" "n"))))]
3893 "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode)
3894 && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0"
3895 {
3896 return rs6000_insn_for_insert_mask (<MODE>mode, operands, false);
3897 }
3898 [(set_attr "type" "insert")])
3899
3900 ; There are also some forms without one of the ANDs.
3901 (define_insn "*rotl<mode>3_insert_3"
3902 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3903 (ior:GPR (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0")
3904 (match_operand:GPR 4 "const_int_operand" "n"))
3905 (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3906 (match_operand:SI 2 "const_int_operand" "n"))))]
3907 "INTVAL (operands[2]) == exact_log2 (UINTVAL (operands[4]) + 1)"
3908 {
3909 if (<MODE>mode == SImode)
3910 return "rlwimi %0,%1,%h2,0,31-%h2";
3911 else
3912 return "rldimi %0,%1,%H2,0";
3913 }
3914 [(set_attr "type" "insert")])
3915
3916 (define_insn "*rotl<mode>3_insert_4"
3917 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3918 (ior:GPR (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0")
3919 (match_operand:GPR 4 "const_int_operand" "n"))
3920 (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3921 (match_operand:SI 2 "const_int_operand" "n"))))]
3922 "<MODE>mode == SImode &&
3923 GET_MODE_PRECISION (<MODE>mode)
3924 == INTVAL (operands[2]) + exact_log2 (-UINTVAL (operands[4]))"
3925 {
3926 operands[2] = GEN_INT (GET_MODE_PRECISION (<MODE>mode)
3927 - INTVAL (operands[2]));
3928 if (<MODE>mode == SImode)
3929 return "rlwimi %0,%1,%h2,32-%h2,31";
3930 else
3931 return "rldimi %0,%1,%H2,64-%H2";
3932 }
3933 [(set_attr "type" "insert")])
3934
3935 (define_insn "*rotlsi3_insert_5"
3936 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
3937 (ior:SI (and:SI (match_operand:SI 1 "gpc_reg_operand" "0,r")
3938 (match_operand:SI 2 "const_int_operand" "n,n"))
3939 (and:SI (match_operand:SI 3 "gpc_reg_operand" "r,0")
3940 (match_operand:SI 4 "const_int_operand" "n,n"))))]
3941 "rs6000_is_valid_mask (operands[2], NULL, NULL, SImode)
3942 && UINTVAL (operands[2]) != 0 && UINTVAL (operands[4]) != 0
3943 && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
3944 "@
3945 rlwimi %0,%3,0,%4
3946 rlwimi %0,%1,0,%2"
3947 [(set_attr "type" "insert")])
3948
3949 (define_insn "*rotldi3_insert_6"
3950 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3951 (ior:DI (and:DI (match_operand:DI 1 "gpc_reg_operand" "0")
3952 (match_operand:DI 2 "const_int_operand" "n"))
3953 (and:DI (match_operand:DI 3 "gpc_reg_operand" "r")
3954 (match_operand:DI 4 "const_int_operand" "n"))))]
3955 "exact_log2 (-UINTVAL (operands[2])) > 0
3956 && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
3957 {
3958 operands[5] = GEN_INT (64 - exact_log2 (-UINTVAL (operands[2])));
3959 return "rldimi %0,%3,0,%5";
3960 }
3961 [(set_attr "type" "insert")
3962 (set_attr "size" "64")])
3963
3964 (define_insn "*rotldi3_insert_7"
3965 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3966 (ior:DI (and:DI (match_operand:DI 3 "gpc_reg_operand" "r")
3967 (match_operand:DI 4 "const_int_operand" "n"))
3968 (and:DI (match_operand:DI 1 "gpc_reg_operand" "0")
3969 (match_operand:DI 2 "const_int_operand" "n"))))]
3970 "exact_log2 (-UINTVAL (operands[2])) > 0
3971 && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
3972 {
3973 operands[5] = GEN_INT (64 - exact_log2 (-UINTVAL (operands[2])));
3974 return "rldimi %0,%3,0,%5";
3975 }
3976 [(set_attr "type" "insert")
3977 (set_attr "size" "64")])
3978
3979
3980 ; This handles the important case of multiple-precision shifts. There is
3981 ; no canonicalization rule for ASHIFT vs. LSHIFTRT, so two patterns.
3982 (define_split
3983 [(set (match_operand:GPR 0 "gpc_reg_operand")
3984 (ior:GPR (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand")
3985 (match_operand:SI 3 "const_int_operand"))
3986 (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand")
3987 (match_operand:SI 4 "const_int_operand"))))]
3988 "can_create_pseudo_p ()
3989 && INTVAL (operands[3]) + INTVAL (operands[4])
3990 >= GET_MODE_PRECISION (<MODE>mode)"
3991 [(set (match_dup 5)
3992 (lshiftrt:GPR (match_dup 2)
3993 (match_dup 4)))
3994 (set (match_dup 0)
3995 (ior:GPR (and:GPR (match_dup 5)
3996 (match_dup 6))
3997 (ashift:GPR (match_dup 1)
3998 (match_dup 3))))]
3999 {
4000 unsigned HOST_WIDE_INT mask = 1;
4001 mask = (mask << INTVAL (operands[3])) - 1;
4002 operands[5] = gen_reg_rtx (<MODE>mode);
4003 operands[6] = GEN_INT (mask);
4004 })
4005
4006 (define_split
4007 [(set (match_operand:GPR 0 "gpc_reg_operand")
4008 (ior:GPR (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand")
4009 (match_operand:SI 4 "const_int_operand"))
4010 (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand")
4011 (match_operand:SI 3 "const_int_operand"))))]
4012 "can_create_pseudo_p ()
4013 && INTVAL (operands[3]) + INTVAL (operands[4])
4014 >= GET_MODE_PRECISION (<MODE>mode)"
4015 [(set (match_dup 5)
4016 (lshiftrt:GPR (match_dup 2)
4017 (match_dup 4)))
4018 (set (match_dup 0)
4019 (ior:GPR (and:GPR (match_dup 5)
4020 (match_dup 6))
4021 (ashift:GPR (match_dup 1)
4022 (match_dup 3))))]
4023 {
4024 unsigned HOST_WIDE_INT mask = 1;
4025 mask = (mask << INTVAL (operands[3])) - 1;
4026 operands[5] = gen_reg_rtx (<MODE>mode);
4027 operands[6] = GEN_INT (mask);
4028 })
4029
4030
4031 ; Another important case is setting some bits to 1; we can do that with
4032 ; an insert instruction, in many cases.
4033 (define_insn_and_split "*ior<mode>_mask"
4034 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4035 (ior:GPR (match_operand:GPR 1 "gpc_reg_operand" "0")
4036 (match_operand:GPR 2 "const_int_operand" "n")))
4037 (clobber (match_scratch:GPR 3 "=r"))]
4038 "!logical_const_operand (operands[2], <MODE>mode)
4039 && rs6000_is_valid_mask (operands[2], NULL, NULL, <MODE>mode)"
4040 "#"
4041 "&& 1"
4042 [(set (match_dup 3)
4043 (const_int -1))
4044 (set (match_dup 0)
4045 (ior:GPR (and:GPR (rotate:GPR (match_dup 3)
4046 (match_dup 4))
4047 (match_dup 2))
4048 (and:GPR (match_dup 1)
4049 (match_dup 5))))]
4050 {
4051 int nb, ne;
4052 rs6000_is_valid_mask (operands[2], &nb, &ne, <MODE>mode);
4053 if (GET_CODE (operands[3]) == SCRATCH)
4054 operands[3] = gen_reg_rtx (<MODE>mode);
4055 operands[4] = GEN_INT (ne);
4056 operands[5] = GEN_INT (~UINTVAL (operands[2]));
4057 }
4058 [(set_attr "type" "two")
4059 (set_attr "length" "8")])
4060
4061
4062 ; Yet another case is an rldimi with the second value coming from memory.
4063 ; The zero_extend that should become part of the rldimi is merged into the
4064 ; load from memory instead. Split things properly again.
4065 (define_split
4066 [(set (match_operand:DI 0 "gpc_reg_operand")
4067 (ior:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand")
4068 (match_operand:SI 2 "const_int_operand"))
4069 (zero_extend:DI (match_operand:QHSI 3 "memory_operand"))))]
4070 "INTVAL (operands[2]) == <bits>"
4071 [(set (match_dup 4)
4072 (zero_extend:DI (match_dup 3)))
4073 (set (match_dup 0)
4074 (ior:DI (and:DI (match_dup 4)
4075 (match_dup 5))
4076 (ashift:DI (match_dup 1)
4077 (match_dup 2))))]
4078 {
4079 operands[4] = gen_reg_rtx (DImode);
4080 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << <bits>) - 1);
4081 })
4082
4083 ; rlwimi, too.
4084 (define_split
4085 [(set (match_operand:SI 0 "gpc_reg_operand")
4086 (ior:SI (ashift:SI (match_operand:SI 1 "gpc_reg_operand")
4087 (match_operand:SI 2 "const_int_operand"))
4088 (zero_extend:SI (match_operand:QHI 3 "memory_operand"))))]
4089 "INTVAL (operands[2]) == <bits>"
4090 [(set (match_dup 4)
4091 (zero_extend:SI (match_dup 3)))
4092 (set (match_dup 0)
4093 (ior:SI (and:SI (match_dup 4)
4094 (match_dup 5))
4095 (ashift:SI (match_dup 1)
4096 (match_dup 2))))]
4097 {
4098 operands[4] = gen_reg_rtx (SImode);
4099 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << <bits>) - 1);
4100 })
4101
4102
4103 ;; Now the simple shifts.
4104
4105 (define_insn "rotl<mode>3"
4106 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4107 (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4108 (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4109 ""
4110 "rotl<wd>%I2 %0,%1,%<hH>2"
4111 [(set_attr "type" "shift")
4112 (set_attr "maybe_var_shift" "yes")])
4113
4114 (define_insn "*rotlsi3_64"
4115 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4116 (zero_extend:DI
4117 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4118 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4119 "TARGET_POWERPC64"
4120 "rotlw%I2 %0,%1,%h2"
4121 [(set_attr "type" "shift")
4122 (set_attr "maybe_var_shift" "yes")])
4123
4124 (define_insn_and_split "*rotl<mode>3_dot"
4125 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4126 (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4127 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4128 (const_int 0)))
4129 (clobber (match_scratch:GPR 0 "=r,r"))]
4130 "<MODE>mode == Pmode"
4131 "@
4132 rotl<wd>%I2. %0,%1,%<hH>2
4133 #"
4134 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4135 [(set (match_dup 0)
4136 (rotate:GPR (match_dup 1)
4137 (match_dup 2)))
4138 (set (match_dup 3)
4139 (compare:CC (match_dup 0)
4140 (const_int 0)))]
4141 ""
4142 [(set_attr "type" "shift")
4143 (set_attr "maybe_var_shift" "yes")
4144 (set_attr "dot" "yes")
4145 (set_attr "length" "4,8")])
4146
4147 (define_insn_and_split "*rotl<mode>3_dot2"
4148 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4149 (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4150 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4151 (const_int 0)))
4152 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4153 (rotate:GPR (match_dup 1)
4154 (match_dup 2)))]
4155 "<MODE>mode == Pmode"
4156 "@
4157 rotl<wd>%I2. %0,%1,%<hH>2
4158 #"
4159 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4160 [(set (match_dup 0)
4161 (rotate:GPR (match_dup 1)
4162 (match_dup 2)))
4163 (set (match_dup 3)
4164 (compare:CC (match_dup 0)
4165 (const_int 0)))]
4166 ""
4167 [(set_attr "type" "shift")
4168 (set_attr "maybe_var_shift" "yes")
4169 (set_attr "dot" "yes")
4170 (set_attr "length" "4,8")])
4171
4172
4173 (define_insn "ashl<mode>3"
4174 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4175 (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4176 (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4177 ""
4178 "sl<wd>%I2 %0,%1,%<hH>2"
4179 [(set_attr "type" "shift")
4180 (set_attr "maybe_var_shift" "yes")])
4181
4182 (define_insn "*ashlsi3_64"
4183 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4184 (zero_extend:DI
4185 (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4186 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4187 "TARGET_POWERPC64"
4188 "slw%I2 %0,%1,%h2"
4189 [(set_attr "type" "shift")
4190 (set_attr "maybe_var_shift" "yes")])
4191
4192 (define_insn_and_split "*ashl<mode>3_dot"
4193 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4194 (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4195 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4196 (const_int 0)))
4197 (clobber (match_scratch:GPR 0 "=r,r"))]
4198 "<MODE>mode == Pmode"
4199 "@
4200 sl<wd>%I2. %0,%1,%<hH>2
4201 #"
4202 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4203 [(set (match_dup 0)
4204 (ashift:GPR (match_dup 1)
4205 (match_dup 2)))
4206 (set (match_dup 3)
4207 (compare:CC (match_dup 0)
4208 (const_int 0)))]
4209 ""
4210 [(set_attr "type" "shift")
4211 (set_attr "maybe_var_shift" "yes")
4212 (set_attr "dot" "yes")
4213 (set_attr "length" "4,8")])
4214
4215 (define_insn_and_split "*ashl<mode>3_dot2"
4216 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4217 (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4218 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4219 (const_int 0)))
4220 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4221 (ashift:GPR (match_dup 1)
4222 (match_dup 2)))]
4223 "<MODE>mode == Pmode"
4224 "@
4225 sl<wd>%I2. %0,%1,%<hH>2
4226 #"
4227 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4228 [(set (match_dup 0)
4229 (ashift:GPR (match_dup 1)
4230 (match_dup 2)))
4231 (set (match_dup 3)
4232 (compare:CC (match_dup 0)
4233 (const_int 0)))]
4234 ""
4235 [(set_attr "type" "shift")
4236 (set_attr "maybe_var_shift" "yes")
4237 (set_attr "dot" "yes")
4238 (set_attr "length" "4,8")])
4239
4240 ;; Pretend we have a memory form of extswsli until register allocation is done
4241 ;; so that we use LWZ to load the value from memory, instead of LWA.
4242 (define_insn_and_split "ashdi3_extswsli"
4243 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
4244 (ashift:DI
4245 (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,m"))
4246 (match_operand:DI 2 "u6bit_cint_operand" "n,n")))]
4247 "TARGET_EXTSWSLI"
4248 "@
4249 extswsli %0,%1,%2
4250 #"
4251 "&& reload_completed && MEM_P (operands[1])"
4252 [(set (match_dup 3)
4253 (match_dup 1))
4254 (set (match_dup 0)
4255 (ashift:DI (sign_extend:DI (match_dup 3))
4256 (match_dup 2)))]
4257 {
4258 operands[3] = gen_lowpart (SImode, operands[0]);
4259 }
4260 [(set_attr "type" "shift")
4261 (set_attr "maybe_var_shift" "no")])
4262
4263
4264 (define_insn_and_split "ashdi3_extswsli_dot"
4265 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y")
4266 (compare:CC
4267 (ashift:DI
4268 (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m"))
4269 (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n"))
4270 (const_int 0)))
4271 (clobber (match_scratch:DI 0 "=r,r,r,r"))]
4272 "TARGET_EXTSWSLI"
4273 "@
4274 extswsli. %0,%1,%2
4275 #
4276 #
4277 #"
4278 "&& reload_completed
4279 && (cc_reg_not_cr0_operand (operands[3], CCmode)
4280 || memory_operand (operands[1], SImode))"
4281 [(pc)]
4282 {
4283 rtx dest = operands[0];
4284 rtx src = operands[1];
4285 rtx shift = operands[2];
4286 rtx cr = operands[3];
4287 rtx src2;
4288
4289 if (!MEM_P (src))
4290 src2 = src;
4291 else
4292 {
4293 src2 = gen_lowpart (SImode, dest);
4294 emit_move_insn (src2, src);
4295 }
4296
4297 if (REGNO (cr) == CR0_REGNO)
4298 {
4299 emit_insn (gen_ashdi3_extswsli_dot2 (dest, src2, shift, cr));
4300 DONE;
4301 }
4302
4303 emit_insn (gen_ashdi3_extswsli (dest, src2, shift));
4304 emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx)));
4305 DONE;
4306 }
4307 [(set_attr "type" "shift")
4308 (set_attr "maybe_var_shift" "no")
4309 (set_attr "dot" "yes")
4310 (set_attr "length" "4,8,8,12")])
4311
4312 (define_insn_and_split "ashdi3_extswsli_dot2"
4313 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y")
4314 (compare:CC
4315 (ashift:DI
4316 (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m"))
4317 (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n"))
4318 (const_int 0)))
4319 (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r")
4320 (ashift:DI (sign_extend:DI (match_dup 1))
4321 (match_dup 2)))]
4322 "TARGET_EXTSWSLI"
4323 "@
4324 extswsli. %0,%1,%2
4325 #
4326 #
4327 #"
4328 "&& reload_completed
4329 && (cc_reg_not_cr0_operand (operands[3], CCmode)
4330 || memory_operand (operands[1], SImode))"
4331 [(pc)]
4332 {
4333 rtx dest = operands[0];
4334 rtx src = operands[1];
4335 rtx shift = operands[2];
4336 rtx cr = operands[3];
4337 rtx src2;
4338
4339 if (!MEM_P (src))
4340 src2 = src;
4341 else
4342 {
4343 src2 = gen_lowpart (SImode, dest);
4344 emit_move_insn (src2, src);
4345 }
4346
4347 if (REGNO (cr) == CR0_REGNO)
4348 {
4349 emit_insn (gen_ashdi3_extswsli_dot2 (dest, src2, shift, cr));
4350 DONE;
4351 }
4352
4353 emit_insn (gen_ashdi3_extswsli (dest, src2, shift));
4354 emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx)));
4355 DONE;
4356 }
4357 [(set_attr "type" "shift")
4358 (set_attr "maybe_var_shift" "no")
4359 (set_attr "dot" "yes")
4360 (set_attr "length" "4,8,8,12")])
4361
4362 (define_insn "lshr<mode>3"
4363 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4364 (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4365 (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4366 ""
4367 "sr<wd>%I2 %0,%1,%<hH>2"
4368 [(set_attr "type" "shift")
4369 (set_attr "maybe_var_shift" "yes")])
4370
4371 (define_insn "*lshrsi3_64"
4372 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4373 (zero_extend:DI
4374 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4375 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4376 "TARGET_POWERPC64"
4377 "srw%I2 %0,%1,%h2"
4378 [(set_attr "type" "shift")
4379 (set_attr "maybe_var_shift" "yes")])
4380
4381 (define_insn_and_split "*lshr<mode>3_dot"
4382 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4383 (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4384 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4385 (const_int 0)))
4386 (clobber (match_scratch:GPR 0 "=r,r"))]
4387 "<MODE>mode == Pmode"
4388 "@
4389 sr<wd>%I2. %0,%1,%<hH>2
4390 #"
4391 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4392 [(set (match_dup 0)
4393 (lshiftrt:GPR (match_dup 1)
4394 (match_dup 2)))
4395 (set (match_dup 3)
4396 (compare:CC (match_dup 0)
4397 (const_int 0)))]
4398 ""
4399 [(set_attr "type" "shift")
4400 (set_attr "maybe_var_shift" "yes")
4401 (set_attr "dot" "yes")
4402 (set_attr "length" "4,8")])
4403
4404 (define_insn_and_split "*lshr<mode>3_dot2"
4405 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4406 (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4407 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4408 (const_int 0)))
4409 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4410 (lshiftrt:GPR (match_dup 1)
4411 (match_dup 2)))]
4412 "<MODE>mode == Pmode"
4413 "@
4414 sr<wd>%I2. %0,%1,%<hH>2
4415 #"
4416 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4417 [(set (match_dup 0)
4418 (lshiftrt:GPR (match_dup 1)
4419 (match_dup 2)))
4420 (set (match_dup 3)
4421 (compare:CC (match_dup 0)
4422 (const_int 0)))]
4423 ""
4424 [(set_attr "type" "shift")
4425 (set_attr "maybe_var_shift" "yes")
4426 (set_attr "dot" "yes")
4427 (set_attr "length" "4,8")])
4428
4429
4430 (define_insn "ashr<mode>3"
4431 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4432 (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4433 (match_operand:SI 2 "reg_or_cint_operand" "rn")))
4434 (clobber (reg:GPR CA_REGNO))]
4435 ""
4436 "sra<wd>%I2 %0,%1,%<hH>2"
4437 [(set_attr "type" "shift")
4438 (set_attr "maybe_var_shift" "yes")])
4439
4440 (define_insn "*ashrsi3_64"
4441 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4442 (sign_extend:DI
4443 (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4444 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))
4445 (clobber (reg:SI CA_REGNO))]
4446 "TARGET_POWERPC64"
4447 "sraw%I2 %0,%1,%h2"
4448 [(set_attr "type" "shift")
4449 (set_attr "maybe_var_shift" "yes")])
4450
4451 (define_insn_and_split "*ashr<mode>3_dot"
4452 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4453 (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4454 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4455 (const_int 0)))
4456 (clobber (match_scratch:GPR 0 "=r,r"))
4457 (clobber (reg:GPR CA_REGNO))]
4458 "<MODE>mode == Pmode"
4459 "@
4460 sra<wd>%I2. %0,%1,%<hH>2
4461 #"
4462 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4463 [(parallel [(set (match_dup 0)
4464 (ashiftrt:GPR (match_dup 1)
4465 (match_dup 2)))
4466 (clobber (reg:GPR CA_REGNO))])
4467 (set (match_dup 3)
4468 (compare:CC (match_dup 0)
4469 (const_int 0)))]
4470 ""
4471 [(set_attr "type" "shift")
4472 (set_attr "maybe_var_shift" "yes")
4473 (set_attr "dot" "yes")
4474 (set_attr "length" "4,8")])
4475
4476 (define_insn_and_split "*ashr<mode>3_dot2"
4477 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4478 (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4479 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4480 (const_int 0)))
4481 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4482 (ashiftrt:GPR (match_dup 1)
4483 (match_dup 2)))
4484 (clobber (reg:GPR CA_REGNO))]
4485 "<MODE>mode == Pmode"
4486 "@
4487 sra<wd>%I2. %0,%1,%<hH>2
4488 #"
4489 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4490 [(parallel [(set (match_dup 0)
4491 (ashiftrt:GPR (match_dup 1)
4492 (match_dup 2)))
4493 (clobber (reg:GPR CA_REGNO))])
4494 (set (match_dup 3)
4495 (compare:CC (match_dup 0)
4496 (const_int 0)))]
4497 ""
4498 [(set_attr "type" "shift")
4499 (set_attr "maybe_var_shift" "yes")
4500 (set_attr "dot" "yes")
4501 (set_attr "length" "4,8")])
4502 \f
4503 ;; Builtins to replace a division to generate FRE reciprocal estimate
4504 ;; instructions and the necessary fixup instructions
4505 (define_expand "recip<mode>3"
4506 [(match_operand:RECIPF 0 "gpc_reg_operand")
4507 (match_operand:RECIPF 1 "gpc_reg_operand")
4508 (match_operand:RECIPF 2 "gpc_reg_operand")]
4509 "RS6000_RECIP_HAVE_RE_P (<MODE>mode)"
4510 {
4511 rs6000_emit_swdiv (operands[0], operands[1], operands[2], false);
4512 DONE;
4513 })
4514
4515 ;; Split to create division from FRE/FRES/etc. and fixup instead of the normal
4516 ;; hardware division. This is only done before register allocation and with
4517 ;; -ffast-math. This must appear before the divsf3/divdf3 insns.
4518 ;; We used to also check optimize_insn_for_speed_p () but problems with guessed
4519 ;; frequencies (pr68212/pr77536) yields that unreliable so it was removed.
4520 (define_split
4521 [(set (match_operand:RECIPF 0 "gpc_reg_operand")
4522 (div:RECIPF (match_operand 1 "gpc_reg_operand")
4523 (match_operand 2 "gpc_reg_operand")))]
4524 "RS6000_RECIP_AUTO_RE_P (<MODE>mode)
4525 && can_create_pseudo_p () && flag_finite_math_only
4526 && !flag_trapping_math && flag_reciprocal_math"
4527 [(const_int 0)]
4528 {
4529 rs6000_emit_swdiv (operands[0], operands[1], operands[2], true);
4530 DONE;
4531 })
4532
4533 ;; Builtins to replace 1/sqrt(x) with instructions using RSQRTE and the
4534 ;; appropriate fixup.
4535 (define_expand "rsqrt<mode>2"
4536 [(match_operand:RECIPF 0 "gpc_reg_operand")
4537 (match_operand:RECIPF 1 "gpc_reg_operand")]
4538 "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4539 {
4540 rs6000_emit_swsqrt (operands[0], operands[1], 1);
4541 DONE;
4542 })
4543 \f
4544 ;; Floating-point insns, excluding normal data motion. We combine the SF/DF
4545 ;; modes here, and also add in conditional vsx/power8-vector support to access
4546 ;; values in the traditional Altivec registers if the appropriate
4547 ;; -mupper-regs-{df,sf} option is enabled.
4548
4549 (define_expand "abs<mode>2"
4550 [(set (match_operand:SFDF 0 "gpc_reg_operand")
4551 (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))]
4552 "TARGET_HARD_FLOAT"
4553 "")
4554
4555 (define_insn "*abs<mode>2_fpr"
4556 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4557 (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4558 "TARGET_HARD_FLOAT"
4559 "@
4560 fabs %0,%1
4561 xsabsdp %x0,%x1"
4562 [(set_attr "type" "fpsimple")])
4563
4564 (define_insn "*nabs<mode>2_fpr"
4565 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4566 (neg:SFDF
4567 (abs:SFDF
4568 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))))]
4569 "TARGET_HARD_FLOAT"
4570 "@
4571 fnabs %0,%1
4572 xsnabsdp %x0,%x1"
4573 [(set_attr "type" "fpsimple")])
4574
4575 (define_expand "neg<mode>2"
4576 [(set (match_operand:SFDF 0 "gpc_reg_operand")
4577 (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))]
4578 "TARGET_HARD_FLOAT"
4579 "")
4580
4581 (define_insn "*neg<mode>2_fpr"
4582 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4583 (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4584 "TARGET_HARD_FLOAT"
4585 "@
4586 fneg %0,%1
4587 xsnegdp %x0,%x1"
4588 [(set_attr "type" "fpsimple")])
4589
4590 (define_expand "add<mode>3"
4591 [(set (match_operand:SFDF 0 "gpc_reg_operand")
4592 (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4593 (match_operand:SFDF 2 "gpc_reg_operand")))]
4594 "TARGET_HARD_FLOAT"
4595 "")
4596
4597 (define_insn "*add<mode>3_fpr"
4598 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4599 (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>")
4600 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4601 "TARGET_HARD_FLOAT"
4602 "@
4603 fadd<Ftrad> %0,%1,%2
4604 xsadd<Fvsx> %x0,%x1,%x2"
4605 [(set_attr "type" "fp")])
4606
4607 (define_expand "sub<mode>3"
4608 [(set (match_operand:SFDF 0 "gpc_reg_operand")
4609 (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4610 (match_operand:SFDF 2 "gpc_reg_operand")))]
4611 "TARGET_HARD_FLOAT"
4612 "")
4613
4614 (define_insn "*sub<mode>3_fpr"
4615 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4616 (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4617 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4618 "TARGET_HARD_FLOAT"
4619 "@
4620 fsub<Ftrad> %0,%1,%2
4621 xssub<Fvsx> %x0,%x1,%x2"
4622 [(set_attr "type" "fp")])
4623
4624 (define_expand "mul<mode>3"
4625 [(set (match_operand:SFDF 0 "gpc_reg_operand")
4626 (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4627 (match_operand:SFDF 2 "gpc_reg_operand")))]
4628 "TARGET_HARD_FLOAT"
4629 "")
4630
4631 (define_insn "*mul<mode>3_fpr"
4632 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4633 (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>")
4634 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4635 "TARGET_HARD_FLOAT"
4636 "@
4637 fmul<Ftrad> %0,%1,%2
4638 xsmul<Fvsx> %x0,%x1,%x2"
4639 [(set_attr "type" "dmul")])
4640
4641 (define_expand "div<mode>3"
4642 [(set (match_operand:SFDF 0 "gpc_reg_operand")
4643 (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4644 (match_operand:SFDF 2 "gpc_reg_operand")))]
4645 "TARGET_HARD_FLOAT"
4646 {
4647 if (RS6000_RECIP_AUTO_RE_P (<MODE>mode)
4648 && can_create_pseudo_p () && flag_finite_math_only
4649 && !flag_trapping_math && flag_reciprocal_math)
4650 {
4651 rs6000_emit_swdiv (operands[0], operands[1], operands[2], true);
4652 DONE;
4653 }
4654 })
4655
4656 (define_insn "*div<mode>3_fpr"
4657 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4658 (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4659 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4660 "TARGET_HARD_FLOAT"
4661 "@
4662 fdiv<Ftrad> %0,%1,%2
4663 xsdiv<Fvsx> %x0,%x1,%x2"
4664 [(set_attr "type" "<Fs>div")])
4665
4666 (define_insn "*sqrt<mode>2_internal"
4667 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4668 (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4669 "TARGET_HARD_FLOAT && TARGET_PPC_GPOPT"
4670 "@
4671 fsqrt<Ftrad> %0,%1
4672 xssqrt<Fvsx> %x0,%x1"
4673 [(set_attr "type" "<Fs>sqrt")])
4674
4675 (define_expand "sqrt<mode>2"
4676 [(set (match_operand:SFDF 0 "gpc_reg_operand")
4677 (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))]
4678 "TARGET_HARD_FLOAT && TARGET_PPC_GPOPT"
4679 {
4680 if (<MODE>mode == SFmode
4681 && TARGET_RECIP_PRECISION
4682 && RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)
4683 && !optimize_function_for_size_p (cfun)
4684 && flag_finite_math_only && !flag_trapping_math
4685 && flag_unsafe_math_optimizations)
4686 {
4687 rs6000_emit_swsqrt (operands[0], operands[1], 0);
4688 DONE;
4689 }
4690 })
4691
4692 ;; Floating point reciprocal approximation
4693 (define_insn "fre<Fs>"
4694 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4695 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")]
4696 UNSPEC_FRES))]
4697 "TARGET_<FFRE>"
4698 "@
4699 fre<Ftrad> %0,%1
4700 xsre<Fvsx> %x0,%x1"
4701 [(set_attr "type" "fp")])
4702
4703 (define_insn "*rsqrt<mode>2"
4704 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4705 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")]
4706 UNSPEC_RSQRT))]
4707 "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4708 "@
4709 frsqrte<Ftrad> %0,%1
4710 xsrsqrte<Fvsx> %x0,%x1"
4711 [(set_attr "type" "fp")])
4712
4713 ;; Floating point comparisons
4714 (define_insn "*cmp<mode>_fpr"
4715 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y,y")
4716 (compare:CCFP (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4717 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4718 "TARGET_HARD_FLOAT"
4719 "@
4720 fcmpu %0,%1,%2
4721 xscmpudp %0,%x1,%x2"
4722 [(set_attr "type" "fpcompare")])
4723
4724 ;; Floating point conversions
4725 (define_expand "extendsfdf2"
4726 [(set (match_operand:DF 0 "gpc_reg_operand")
4727 (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand")))]
4728 "TARGET_HARD_FLOAT"
4729 {
4730 if (HONOR_SNANS (SFmode))
4731 operands[1] = force_reg (SFmode, operands[1]);
4732 })
4733
4734 (define_insn_and_split "*extendsfdf2_fpr"
4735 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d,d,ws,?ws,wu,wb")
4736 (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand" "0,f,m,0,wy,Z,wY")))]
4737 "TARGET_HARD_FLOAT && !HONOR_SNANS (SFmode)"
4738 "@
4739 #
4740 fmr %0,%1
4741 lfs%U1%X1 %0,%1
4742 #
4743 xscpsgndp %x0,%x1,%x1
4744 lxsspx %x0,%y1
4745 lxssp %0,%1"
4746 "&& reload_completed && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1])"
4747 [(const_int 0)]
4748 {
4749 emit_note (NOTE_INSN_DELETED);
4750 DONE;
4751 }
4752 [(set_attr "type" "fp,fpsimple,fpload,fp,fpsimple,fpload,fpload")])
4753
4754 (define_insn "*extendsfdf2_snan"
4755 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
4756 (float_extend:DF (match_operand:SF 1 "gpc_reg_operand" "f,wy")))]
4757 "TARGET_HARD_FLOAT && HONOR_SNANS (SFmode)"
4758 "@
4759 frsp %0,%1
4760 xsrsp %x0,%x1"
4761 [(set_attr "type" "fp")])
4762
4763 (define_expand "truncdfsf2"
4764 [(set (match_operand:SF 0 "gpc_reg_operand")
4765 (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand")))]
4766 "TARGET_HARD_FLOAT"
4767 "")
4768
4769 (define_insn "*truncdfsf2_fpr"
4770 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy")
4771 (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "d,ws")))]
4772 "TARGET_HARD_FLOAT"
4773 "@
4774 frsp %0,%1
4775 xsrsp %x0,%x1"
4776 [(set_attr "type" "fp")])
4777
4778 ;; This expander is here to avoid FLOAT_WORDS_BIGENDIAN tests in
4779 ;; builtins.c and optabs.c that are not correct for IBM long double
4780 ;; when little-endian.
4781 (define_expand "signbit<mode>2"
4782 [(set (match_dup 2)
4783 (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand")))
4784 (set (match_dup 3)
4785 (subreg:DI (match_dup 2) 0))
4786 (set (match_dup 4)
4787 (match_dup 5))
4788 (set (match_operand:SI 0 "gpc_reg_operand")
4789 (match_dup 6))]
4790 "TARGET_HARD_FLOAT
4791 && (!FLOAT128_IEEE_P (<MODE>mode)
4792 || (TARGET_POWERPC64 && TARGET_DIRECT_MOVE))"
4793 {
4794 if (FLOAT128_IEEE_P (<MODE>mode))
4795 {
4796 rtx dest = operands[0];
4797 rtx src = operands[1];
4798 rtx tmp = gen_reg_rtx (DImode);
4799 rtx dest_di = gen_lowpart (DImode, dest);
4800
4801 if (<MODE>mode == KFmode)
4802 emit_insn (gen_signbitkf2_dm (tmp, src));
4803 else if (<MODE>mode == TFmode)
4804 emit_insn (gen_signbittf2_dm (tmp, src));
4805 else
4806 gcc_unreachable ();
4807
4808 emit_insn (gen_lshrdi3 (dest_di, tmp, GEN_INT (63)));
4809 DONE;
4810 }
4811 operands[2] = gen_reg_rtx (DFmode);
4812 operands[3] = gen_reg_rtx (DImode);
4813 if (TARGET_POWERPC64)
4814 {
4815 operands[4] = gen_reg_rtx (DImode);
4816 operands[5] = gen_rtx_LSHIFTRT (DImode, operands[3], GEN_INT (63));
4817 operands[6] = gen_rtx_SUBREG (SImode, operands[4],
4818 WORDS_BIG_ENDIAN ? 4 : 0);
4819 }
4820 else
4821 {
4822 operands[4] = gen_reg_rtx (SImode);
4823 operands[5] = gen_rtx_SUBREG (SImode, operands[3],
4824 WORDS_BIG_ENDIAN ? 0 : 4);
4825 operands[6] = gen_rtx_LSHIFTRT (SImode, operands[4], GEN_INT (31));
4826 }
4827 })
4828
4829 ;; Optimize IEEE 128-bit signbit on 64-bit systems with direct move to avoid
4830 ;; multiple direct moves. If we used a SUBREG:DI of the Floa128 type, the
4831 ;; register allocator would typically move the entire _Float128 item to GPRs (2
4832 ;; instructions on ISA 3.0, 3-4 instructions on ISA 2.07).
4833 ;;
4834 ;; After register allocation, if the _Float128 had originally been in GPRs, the
4835 ;; split allows the post reload phases to eliminate the move, and do the shift
4836 ;; directly with the register that contains the signbit.
4837 (define_insn_and_split "signbit<mode>2_dm"
4838 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
4839 (unspec:DI [(match_operand:SIGNBIT 1 "gpc_reg_operand" "wa,r")]
4840 UNSPEC_SIGNBIT))]
4841 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
4842 "@
4843 mfvsrd %0,%x1
4844 #"
4845 "&& reload_completed && int_reg_operand (operands[1], <MODE>mode)"
4846 [(set (match_dup 0)
4847 (match_dup 2))]
4848 {
4849 operands[2] = gen_highpart (DImode, operands[1]);
4850 }
4851 [(set_attr "type" "mftgpr,*")])
4852
4853 ;; Optimize IEEE 128-bit signbit on to avoid loading the value into a vector
4854 ;; register and then doing a direct move if the value comes from memory. On
4855 ;; little endian, we have to load the 2nd double-word to get the sign bit.
4856 (define_insn_and_split "*signbit<mode>2_dm_mem"
4857 [(set (match_operand:DI 0 "gpc_reg_operand" "=b")
4858 (unspec:DI [(match_operand:SIGNBIT 1 "memory_operand" "m")]
4859 UNSPEC_SIGNBIT))]
4860 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
4861 "#"
4862 "&& 1"
4863 [(set (match_dup 0)
4864 (match_dup 2))]
4865 {
4866 rtx dest = operands[0];
4867 rtx src = operands[1];
4868 rtx addr = XEXP (src, 0);
4869
4870 if (WORDS_BIG_ENDIAN)
4871 operands[2] = adjust_address (src, DImode, 0);
4872
4873 else if (REG_P (addr) || SUBREG_P (addr))
4874 operands[2] = adjust_address (src, DImode, 8);
4875
4876 else if (GET_CODE (addr) == PLUS && REG_P (XEXP (addr, 0))
4877 && CONST_INT_P (XEXP (addr, 1)) && mem_operand_gpr (src, DImode))
4878 operands[2] = adjust_address (src, DImode, 8);
4879
4880 else
4881 {
4882 rtx tmp = can_create_pseudo_p () ? gen_reg_rtx (DImode) : dest;
4883 emit_insn (gen_rtx_SET (tmp, addr));
4884 operands[2] = change_address (src, DImode,
4885 gen_rtx_PLUS (DImode, tmp, GEN_INT (8)));
4886 }
4887 })
4888
4889 (define_expand "copysign<mode>3"
4890 [(set (match_dup 3)
4891 (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))
4892 (set (match_dup 4)
4893 (neg:SFDF (abs:SFDF (match_dup 1))))
4894 (set (match_operand:SFDF 0 "gpc_reg_operand")
4895 (if_then_else:SFDF (ge (match_operand:SFDF 2 "gpc_reg_operand")
4896 (match_dup 5))
4897 (match_dup 3)
4898 (match_dup 4)))]
4899 "TARGET_HARD_FLOAT
4900 && ((TARGET_PPC_GFXOPT
4901 && !HONOR_NANS (<MODE>mode)
4902 && !HONOR_SIGNED_ZEROS (<MODE>mode))
4903 || TARGET_CMPB
4904 || VECTOR_UNIT_VSX_P (<MODE>mode))"
4905 {
4906 if (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode))
4907 {
4908 emit_insn (gen_copysign<mode>3_fcpsgn (operands[0], operands[1],
4909 operands[2]));
4910 DONE;
4911 }
4912
4913 operands[3] = gen_reg_rtx (<MODE>mode);
4914 operands[4] = gen_reg_rtx (<MODE>mode);
4915 operands[5] = CONST0_RTX (<MODE>mode);
4916 })
4917
4918 ;; Use an unspec rather providing an if-then-else in RTL, to prevent the
4919 ;; compiler from optimizing -0.0
4920 (define_insn "copysign<mode>3_fcpsgn"
4921 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4922 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")
4923 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")]
4924 UNSPEC_COPYSIGN))]
4925 "TARGET_HARD_FLOAT && (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode))"
4926 "@
4927 fcpsgn %0,%2,%1
4928 xscpsgndp %x0,%x2,%x1"
4929 [(set_attr "type" "fpsimple")])
4930
4931 ;; For MIN, MAX, and conditional move, we use DEFINE_EXPAND's that involve a
4932 ;; fsel instruction and some auxiliary computations. Then we just have a
4933 ;; single DEFINE_INSN for fsel and the define_splits to make them if made by
4934 ;; combine.
4935 ;; For MIN, MAX on non-VSX machines, and conditional move all of the time, we
4936 ;; use DEFINE_EXPAND's that involve a fsel instruction and some auxiliary
4937 ;; computations. Then we just have a single DEFINE_INSN for fsel and the
4938 ;; define_splits to make them if made by combine. On VSX machines we have the
4939 ;; min/max instructions.
4940 ;;
4941 ;; On VSX, we only check for TARGET_VSX instead of checking for a vsx/p8 vector
4942 ;; to allow either DF/SF to use only traditional registers.
4943
4944 (define_expand "s<minmax><mode>3"
4945 [(set (match_operand:SFDF 0 "gpc_reg_operand")
4946 (fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4947 (match_operand:SFDF 2 "gpc_reg_operand")))]
4948 "TARGET_MINMAX"
4949 {
4950 rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]);
4951 DONE;
4952 })
4953
4954 (define_insn "*s<minmax><mode>3_vsx"
4955 [(set (match_operand:SFDF 0 "vsx_register_operand" "=<Fv>")
4956 (fp_minmax:SFDF (match_operand:SFDF 1 "vsx_register_operand" "<Fv>")
4957 (match_operand:SFDF 2 "vsx_register_operand" "<Fv>")))]
4958 "TARGET_VSX && TARGET_HARD_FLOAT"
4959 {
4960 return (TARGET_P9_MINMAX
4961 ? "xs<minmax>cdp %x0,%x1,%x2"
4962 : "xs<minmax>dp %x0,%x1,%x2");
4963 }
4964 [(set_attr "type" "fp")])
4965
4966 ;; The conditional move instructions allow us to perform max and min operations
4967 ;; even when we don't have the appropriate max/min instruction using the FSEL
4968 ;; instruction.
4969
4970 (define_insn_and_split "*s<minmax><mode>3_fpr"
4971 [(set (match_operand:SFDF 0 "gpc_reg_operand")
4972 (fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4973 (match_operand:SFDF 2 "gpc_reg_operand")))]
4974 "!TARGET_VSX && TARGET_MINMAX"
4975 "#"
4976 "&& 1"
4977 [(const_int 0)]
4978 {
4979 rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]);
4980 DONE;
4981 })
4982
4983 (define_expand "mov<mode>cc"
4984 [(set (match_operand:GPR 0 "gpc_reg_operand")
4985 (if_then_else:GPR (match_operand 1 "comparison_operator")
4986 (match_operand:GPR 2 "gpc_reg_operand")
4987 (match_operand:GPR 3 "gpc_reg_operand")))]
4988 "TARGET_ISEL"
4989 {
4990 if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
4991 DONE;
4992 else
4993 FAIL;
4994 })
4995
4996 ;; We use the BASE_REGS for the isel input operands because, if rA is
4997 ;; 0, the value of 0 is placed in rD upon truth. Similarly for rB
4998 ;; because we may switch the operands and rB may end up being rA.
4999 ;;
5000 ;; We need 2 patterns: an unsigned and a signed pattern. We could
5001 ;; leave out the mode in operand 4 and use one pattern, but reload can
5002 ;; change the mode underneath our feet and then gets confused trying
5003 ;; to reload the value.
5004 (define_insn "isel_signed_<mode>"
5005 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
5006 (if_then_else:GPR
5007 (match_operator 1 "scc_comparison_operator"
5008 [(match_operand:CC 4 "cc_reg_operand" "y,y")
5009 (const_int 0)])
5010 (match_operand:GPR 2 "reg_or_zero_operand" "O,b")
5011 (match_operand:GPR 3 "gpc_reg_operand" "r,r")))]
5012 "TARGET_ISEL"
5013 "isel %0,%2,%3,%j1"
5014 [(set_attr "type" "isel")])
5015
5016 (define_insn "isel_unsigned_<mode>"
5017 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
5018 (if_then_else:GPR
5019 (match_operator 1 "scc_comparison_operator"
5020 [(match_operand:CCUNS 4 "cc_reg_operand" "y,y")
5021 (const_int 0)])
5022 (match_operand:GPR 2 "reg_or_zero_operand" "O,b")
5023 (match_operand:GPR 3 "gpc_reg_operand" "r,r")))]
5024 "TARGET_ISEL"
5025 "isel %0,%2,%3,%j1"
5026 [(set_attr "type" "isel")])
5027
5028 ;; These patterns can be useful for combine; they let combine know that
5029 ;; isel can handle reversed comparisons so long as the operands are
5030 ;; registers.
5031
5032 (define_insn "*isel_reversed_signed_<mode>"
5033 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
5034 (if_then_else:GPR
5035 (match_operator 1 "scc_rev_comparison_operator"
5036 [(match_operand:CC 4 "cc_reg_operand" "y,y")
5037 (const_int 0)])
5038 (match_operand:GPR 2 "gpc_reg_operand" "r,r")
5039 (match_operand:GPR 3 "reg_or_zero_operand" "O,b")))]
5040 "TARGET_ISEL"
5041 {
5042 PUT_CODE (operands[1], reverse_condition (GET_CODE (operands[1])));
5043 return "isel %0,%3,%2,%j1";
5044 }
5045 [(set_attr "type" "isel")])
5046
5047 (define_insn "*isel_reversed_unsigned_<mode>"
5048 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
5049 (if_then_else:GPR
5050 (match_operator 1 "scc_rev_comparison_operator"
5051 [(match_operand:CCUNS 4 "cc_reg_operand" "y,y")
5052 (const_int 0)])
5053 (match_operand:GPR 2 "gpc_reg_operand" "r,r")
5054 (match_operand:GPR 3 "reg_or_zero_operand" "O,b")))]
5055 "TARGET_ISEL"
5056 {
5057 PUT_CODE (operands[1], reverse_condition (GET_CODE (operands[1])));
5058 return "isel %0,%3,%2,%j1";
5059 }
5060 [(set_attr "type" "isel")])
5061
5062 ;; Floating point conditional move
5063 (define_expand "mov<mode>cc"
5064 [(set (match_operand:SFDF 0 "gpc_reg_operand")
5065 (if_then_else:SFDF (match_operand 1 "comparison_operator")
5066 (match_operand:SFDF 2 "gpc_reg_operand")
5067 (match_operand:SFDF 3 "gpc_reg_operand")))]
5068 "TARGET_HARD_FLOAT && TARGET_PPC_GFXOPT"
5069 {
5070 if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
5071 DONE;
5072 else
5073 FAIL;
5074 })
5075
5076 (define_insn "*fsel<SFDF:mode><SFDF2:mode>4"
5077 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=&<SFDF:rreg2>")
5078 (if_then_else:SFDF
5079 (ge (match_operand:SFDF2 1 "gpc_reg_operand" "<SFDF2:rreg2>")
5080 (match_operand:SFDF2 4 "zero_fp_constant" "F"))
5081 (match_operand:SFDF 2 "gpc_reg_operand" "<SFDF:rreg2>")
5082 (match_operand:SFDF 3 "gpc_reg_operand" "<SFDF:rreg2>")))]
5083 "TARGET_HARD_FLOAT && TARGET_PPC_GFXOPT"
5084 "fsel %0,%1,%2,%3"
5085 [(set_attr "type" "fp")])
5086
5087 (define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_p9"
5088 [(set (match_operand:SFDF 0 "vsx_register_operand" "=&<SFDF:Fv>,<SFDF:Fv>")
5089 (if_then_else:SFDF
5090 (match_operator:CCFP 1 "fpmask_comparison_operator"
5091 [(match_operand:SFDF2 2 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")
5092 (match_operand:SFDF2 3 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")])
5093 (match_operand:SFDF 4 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")
5094 (match_operand:SFDF 5 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")))
5095 (clobber (match_scratch:V2DI 6 "=0,&wa"))]
5096 "TARGET_P9_MINMAX"
5097 "#"
5098 ""
5099 [(set (match_dup 6)
5100 (if_then_else:V2DI (match_dup 1)
5101 (match_dup 7)
5102 (match_dup 8)))
5103 (set (match_dup 0)
5104 (if_then_else:SFDF (ne (match_dup 6)
5105 (match_dup 8))
5106 (match_dup 4)
5107 (match_dup 5)))]
5108 {
5109 if (GET_CODE (operands[6]) == SCRATCH)
5110 operands[6] = gen_reg_rtx (V2DImode);
5111
5112 operands[7] = CONSTM1_RTX (V2DImode);
5113 operands[8] = CONST0_RTX (V2DImode);
5114 }
5115 [(set_attr "length" "8")
5116 (set_attr "type" "vecperm")])
5117
5118 ;; Handle inverting the fpmask comparisons.
5119 (define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_invert_p9"
5120 [(set (match_operand:SFDF 0 "vsx_register_operand" "=&<SFDF:Fv>,<SFDF:Fv>")
5121 (if_then_else:SFDF
5122 (match_operator:CCFP 1 "invert_fpmask_comparison_operator"
5123 [(match_operand:SFDF2 2 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")
5124 (match_operand:SFDF2 3 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")])
5125 (match_operand:SFDF 4 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")
5126 (match_operand:SFDF 5 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")))
5127 (clobber (match_scratch:V2DI 6 "=0,&wa"))]
5128 "TARGET_P9_MINMAX"
5129 "#"
5130 "&& 1"
5131 [(set (match_dup 6)
5132 (if_then_else:V2DI (match_dup 9)
5133 (match_dup 7)
5134 (match_dup 8)))
5135 (set (match_dup 0)
5136 (if_then_else:SFDF (ne (match_dup 6)
5137 (match_dup 8))
5138 (match_dup 5)
5139 (match_dup 4)))]
5140 {
5141 rtx op1 = operands[1];
5142 enum rtx_code cond = reverse_condition_maybe_unordered (GET_CODE (op1));
5143
5144 if (GET_CODE (operands[6]) == SCRATCH)
5145 operands[6] = gen_reg_rtx (V2DImode);
5146
5147 operands[7] = CONSTM1_RTX (V2DImode);
5148 operands[8] = CONST0_RTX (V2DImode);
5149
5150 operands[9] = gen_rtx_fmt_ee (cond, CCFPmode, operands[2], operands[3]);
5151 }
5152 [(set_attr "length" "8")
5153 (set_attr "type" "vecperm")])
5154
5155 (define_insn "*fpmask<mode>"
5156 [(set (match_operand:V2DI 0 "vsx_register_operand" "=wa")
5157 (if_then_else:V2DI
5158 (match_operator:CCFP 1 "fpmask_comparison_operator"
5159 [(match_operand:SFDF 2 "vsx_register_operand" "<Fv>")
5160 (match_operand:SFDF 3 "vsx_register_operand" "<Fv>")])
5161 (match_operand:V2DI 4 "all_ones_constant" "")
5162 (match_operand:V2DI 5 "zero_constant" "")))]
5163 "TARGET_P9_MINMAX"
5164 "xscmp%V1dp %x0,%x2,%x3"
5165 [(set_attr "type" "fpcompare")])
5166
5167 (define_insn "*xxsel<mode>"
5168 [(set (match_operand:SFDF 0 "vsx_register_operand" "=<Fv>")
5169 (if_then_else:SFDF (ne (match_operand:V2DI 1 "vsx_register_operand" "wa")
5170 (match_operand:V2DI 2 "zero_constant" ""))
5171 (match_operand:SFDF 3 "vsx_register_operand" "<Fv>")
5172 (match_operand:SFDF 4 "vsx_register_operand" "<Fv>")))]
5173 "TARGET_P9_MINMAX"
5174 "xxsel %x0,%x4,%x3,%x1"
5175 [(set_attr "type" "vecmove")])
5176
5177 \f
5178 ;; Conversions to and from floating-point.
5179
5180 ; We don't define lfiwax/lfiwzx with the normal definition, because we
5181 ; don't want to support putting SImode in FPR registers.
5182 (define_insn "lfiwax"
5183 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wj,wj,wK")
5184 (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r,wK")]
5185 UNSPEC_LFIWAX))]
5186 "TARGET_HARD_FLOAT && TARGET_LFIWAX"
5187 "@
5188 lfiwax %0,%y1
5189 lxsiwax %x0,%y1
5190 mtvsrwa %x0,%1
5191 vextsw2d %0,%1"
5192 [(set_attr "type" "fpload,fpload,mffgpr,vecexts")])
5193
5194 ; This split must be run before register allocation because it allocates the
5195 ; memory slot that is needed to move values to/from the FPR. We don't allocate
5196 ; it earlier to allow for the combiner to merge insns together where it might
5197 ; not be needed and also in case the insns are deleted as dead code.
5198
5199 (define_insn_and_split "floatsi<mode>2_lfiwax"
5200 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5201 (float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r")))
5202 (clobber (match_scratch:DI 2 "=wi"))]
5203 "TARGET_HARD_FLOAT && TARGET_LFIWAX
5204 && <SI_CONVERT_FP> && can_create_pseudo_p ()"
5205 "#"
5206 ""
5207 [(pc)]
5208 {
5209 rtx dest = operands[0];
5210 rtx src = operands[1];
5211 rtx tmp;
5212
5213 if (!MEM_P (src) && TARGET_POWERPC64
5214 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5215 tmp = convert_to_mode (DImode, src, false);
5216 else
5217 {
5218 tmp = operands[2];
5219 if (GET_CODE (tmp) == SCRATCH)
5220 tmp = gen_reg_rtx (DImode);
5221 if (MEM_P (src))
5222 {
5223 src = rs6000_force_indexed_or_indirect_mem (src);
5224 emit_insn (gen_lfiwax (tmp, src));
5225 }
5226 else
5227 {
5228 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5229 emit_move_insn (stack, src);
5230 emit_insn (gen_lfiwax (tmp, stack));
5231 }
5232 }
5233 emit_insn (gen_floatdi<mode>2 (dest, tmp));
5234 DONE;
5235 }
5236 [(set_attr "length" "12")
5237 (set_attr "type" "fpload")])
5238
5239 (define_insn_and_split "floatsi<mode>2_lfiwax_mem"
5240 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5241 (float:SFDF
5242 (sign_extend:DI
5243 (match_operand:SI 1 "indexed_or_indirect_operand" "Z"))))
5244 (clobber (match_scratch:DI 2 "=wi"))]
5245 "TARGET_HARD_FLOAT && TARGET_LFIWAX && <SI_CONVERT_FP>"
5246 "#"
5247 ""
5248 [(pc)]
5249 {
5250 operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
5251 if (GET_CODE (operands[2]) == SCRATCH)
5252 operands[2] = gen_reg_rtx (DImode);
5253 if (TARGET_P8_VECTOR)
5254 emit_insn (gen_extendsidi2 (operands[2], operands[1]));
5255 else
5256 emit_insn (gen_lfiwax (operands[2], operands[1]));
5257 emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
5258 DONE;
5259 }
5260 [(set_attr "length" "8")
5261 (set_attr "type" "fpload")])
5262
5263 (define_insn "lfiwzx"
5264 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wj,wj,wJwK")
5265 (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r,wJwK")]
5266 UNSPEC_LFIWZX))]
5267 "TARGET_HARD_FLOAT && TARGET_LFIWZX"
5268 "@
5269 lfiwzx %0,%y1
5270 lxsiwzx %x0,%y1
5271 mtvsrwz %x0,%1
5272 xxextractuw %x0,%x1,4"
5273 [(set_attr "type" "fpload,fpload,mftgpr,vecexts")])
5274
5275 (define_insn_and_split "floatunssi<mode>2_lfiwzx"
5276 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5277 (unsigned_float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r")))
5278 (clobber (match_scratch:DI 2 "=wi"))]
5279 "TARGET_HARD_FLOAT && TARGET_LFIWZX && <SI_CONVERT_FP>"
5280 "#"
5281 ""
5282 [(pc)]
5283 {
5284 rtx dest = operands[0];
5285 rtx src = operands[1];
5286 rtx tmp;
5287
5288 if (!MEM_P (src) && TARGET_POWERPC64
5289 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5290 tmp = convert_to_mode (DImode, src, true);
5291 else
5292 {
5293 tmp = operands[2];
5294 if (GET_CODE (tmp) == SCRATCH)
5295 tmp = gen_reg_rtx (DImode);
5296 if (MEM_P (src))
5297 {
5298 src = rs6000_force_indexed_or_indirect_mem (src);
5299 emit_insn (gen_lfiwzx (tmp, src));
5300 }
5301 else
5302 {
5303 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5304 emit_move_insn (stack, src);
5305 emit_insn (gen_lfiwzx (tmp, stack));
5306 }
5307 }
5308 emit_insn (gen_floatdi<mode>2 (dest, tmp));
5309 DONE;
5310 }
5311 [(set_attr "length" "12")
5312 (set_attr "type" "fpload")])
5313
5314 (define_insn_and_split "floatunssi<mode>2_lfiwzx_mem"
5315 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5316 (unsigned_float:SFDF
5317 (zero_extend:DI
5318 (match_operand:SI 1 "indexed_or_indirect_operand" "Z"))))
5319 (clobber (match_scratch:DI 2 "=wi"))]
5320 "TARGET_HARD_FLOAT && TARGET_LFIWZX && <SI_CONVERT_FP>"
5321 "#"
5322 ""
5323 [(pc)]
5324 {
5325 operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
5326 if (GET_CODE (operands[2]) == SCRATCH)
5327 operands[2] = gen_reg_rtx (DImode);
5328 if (TARGET_P8_VECTOR)
5329 emit_insn (gen_zero_extendsidi2 (operands[2], operands[1]));
5330 else
5331 emit_insn (gen_lfiwzx (operands[2], operands[1]));
5332 emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
5333 DONE;
5334 }
5335 [(set_attr "length" "8")
5336 (set_attr "type" "fpload")])
5337
5338 ; For each of these conversions, there is a define_expand, a define_insn
5339 ; with a '#' template, and a define_split (with C code). The idea is
5340 ; to allow constant folding with the template of the define_insn,
5341 ; then to have the insns split later (between sched1 and final).
5342
5343 (define_expand "floatsidf2"
5344 [(parallel [(set (match_operand:DF 0 "gpc_reg_operand")
5345 (float:DF (match_operand:SI 1 "nonimmediate_operand")))
5346 (use (match_dup 2))
5347 (use (match_dup 3))
5348 (clobber (match_dup 4))
5349 (clobber (match_dup 5))
5350 (clobber (match_dup 6))])]
5351 "TARGET_HARD_FLOAT"
5352 {
5353 if (TARGET_LFIWAX && TARGET_FCFID)
5354 {
5355 emit_insn (gen_floatsidf2_lfiwax (operands[0], operands[1]));
5356 DONE;
5357 }
5358 else if (TARGET_FCFID)
5359 {
5360 rtx dreg = operands[1];
5361 if (!REG_P (dreg))
5362 dreg = force_reg (SImode, dreg);
5363 dreg = convert_to_mode (DImode, dreg, false);
5364 emit_insn (gen_floatdidf2 (operands[0], dreg));
5365 DONE;
5366 }
5367
5368 if (!REG_P (operands[1]))
5369 operands[1] = force_reg (SImode, operands[1]);
5370 operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5371 operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503601774854144\", DFmode));
5372 operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5373 operands[5] = gen_reg_rtx (DFmode);
5374 operands[6] = gen_reg_rtx (SImode);
5375 })
5376
5377 (define_insn_and_split "*floatsidf2_internal"
5378 [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5379 (float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5380 (use (match_operand:SI 2 "gpc_reg_operand" "r"))
5381 (use (match_operand:DF 3 "gpc_reg_operand" "d"))
5382 (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
5383 (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))
5384 (clobber (match_operand:SI 6 "gpc_reg_operand" "=&r"))]
5385 "!TARGET_FCFID && TARGET_HARD_FLOAT"
5386 "#"
5387 ""
5388 [(pc)]
5389 {
5390 rtx lowword, highword;
5391 gcc_assert (MEM_P (operands[4]));
5392 highword = adjust_address (operands[4], SImode, 0);
5393 lowword = adjust_address (operands[4], SImode, 4);
5394 if (! WORDS_BIG_ENDIAN)
5395 std::swap (lowword, highword);
5396
5397 emit_insn (gen_xorsi3 (operands[6], operands[1],
5398 GEN_INT (~ (HOST_WIDE_INT) 0x7fffffff)));
5399 emit_move_insn (lowword, operands[6]);
5400 emit_move_insn (highword, operands[2]);
5401 emit_move_insn (operands[5], operands[4]);
5402 emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5403 DONE;
5404 }
5405 [(set_attr "length" "24")
5406 (set_attr "type" "fp")])
5407
5408 ;; If we don't have a direct conversion to single precision, don't enable this
5409 ;; conversion for 32-bit without fast math, because we don't have the insn to
5410 ;; generate the fixup swizzle to avoid double rounding problems.
5411 (define_expand "floatunssisf2"
5412 [(set (match_operand:SF 0 "gpc_reg_operand")
5413 (unsigned_float:SF (match_operand:SI 1 "nonimmediate_operand")))]
5414 "TARGET_HARD_FLOAT
5415 && ((TARGET_FCFIDUS && TARGET_LFIWZX)
5416 || (TARGET_FCFID
5417 && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))"
5418 {
5419 if (TARGET_LFIWZX && TARGET_FCFIDUS)
5420 {
5421 emit_insn (gen_floatunssisf2_lfiwzx (operands[0], operands[1]));
5422 DONE;
5423 }
5424 else
5425 {
5426 rtx dreg = operands[1];
5427 if (!REG_P (dreg))
5428 dreg = force_reg (SImode, dreg);
5429 dreg = convert_to_mode (DImode, dreg, true);
5430 emit_insn (gen_floatdisf2 (operands[0], dreg));
5431 DONE;
5432 }
5433 })
5434
5435 (define_expand "floatunssidf2"
5436 [(parallel [(set (match_operand:DF 0 "gpc_reg_operand")
5437 (unsigned_float:DF (match_operand:SI 1 "nonimmediate_operand")))
5438 (use (match_dup 2))
5439 (use (match_dup 3))
5440 (clobber (match_dup 4))
5441 (clobber (match_dup 5))])]
5442 "TARGET_HARD_FLOAT"
5443 {
5444 if (TARGET_LFIWZX && TARGET_FCFID)
5445 {
5446 emit_insn (gen_floatunssidf2_lfiwzx (operands[0], operands[1]));
5447 DONE;
5448 }
5449 else if (TARGET_FCFID)
5450 {
5451 rtx dreg = operands[1];
5452 if (!REG_P (dreg))
5453 dreg = force_reg (SImode, dreg);
5454 dreg = convert_to_mode (DImode, dreg, true);
5455 emit_insn (gen_floatdidf2 (operands[0], dreg));
5456 DONE;
5457 }
5458
5459 if (!REG_P (operands[1]))
5460 operands[1] = force_reg (SImode, operands[1]);
5461 operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5462 operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503599627370496\", DFmode));
5463 operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5464 operands[5] = gen_reg_rtx (DFmode);
5465 })
5466
5467 (define_insn_and_split "*floatunssidf2_internal"
5468 [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5469 (unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5470 (use (match_operand:SI 2 "gpc_reg_operand" "r"))
5471 (use (match_operand:DF 3 "gpc_reg_operand" "d"))
5472 (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
5473 (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))]
5474 "!TARGET_FCFIDU && TARGET_HARD_FLOAT
5475 && !(TARGET_FCFID && TARGET_POWERPC64)"
5476 "#"
5477 ""
5478 [(pc)]
5479 {
5480 rtx lowword, highword;
5481 gcc_assert (MEM_P (operands[4]));
5482 highword = adjust_address (operands[4], SImode, 0);
5483 lowword = adjust_address (operands[4], SImode, 4);
5484 if (! WORDS_BIG_ENDIAN)
5485 std::swap (lowword, highword);
5486
5487 emit_move_insn (lowword, operands[1]);
5488 emit_move_insn (highword, operands[2]);
5489 emit_move_insn (operands[5], operands[4]);
5490 emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5491 DONE;
5492 }
5493 [(set_attr "length" "20")
5494 (set_attr "type" "fp")])
5495
5496 ;; ISA 3.0 adds instructions lxsi[bh]zx to directly load QImode and HImode to
5497 ;; vector registers. These insns favor doing the sign/zero extension in
5498 ;; the vector registers, rather then loading up a GPR, doing a sign/zero
5499 ;; extension and then a direct move.
5500
5501 (define_expand "float<QHI:mode><FP_ISA3:mode>2"
5502 [(parallel [(set (match_operand:FP_ISA3 0 "vsx_register_operand")
5503 (float:FP_ISA3
5504 (match_operand:QHI 1 "input_operand")))
5505 (clobber (match_scratch:DI 2))
5506 (clobber (match_scratch:DI 3))
5507 (clobber (match_scratch:<QHI:MODE> 4))])]
5508 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5509 {
5510 if (MEM_P (operands[1]))
5511 operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
5512 })
5513
5514 (define_insn_and_split "*float<QHI:mode><FP_ISA3:mode>2_internal"
5515 [(set (match_operand:FP_ISA3 0 "vsx_register_operand" "=<Fv>,<Fv>,<Fv>")
5516 (float:FP_ISA3
5517 (match_operand:QHI 1 "reg_or_indexed_operand" "wK,r,Z")))
5518 (clobber (match_scratch:DI 2 "=wK,wi,wK"))
5519 (clobber (match_scratch:DI 3 "=X,r,X"))
5520 (clobber (match_scratch:<QHI:MODE> 4 "=X,X,wK"))]
5521 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5522 "#"
5523 "&& reload_completed"
5524 [(const_int 0)]
5525 {
5526 rtx result = operands[0];
5527 rtx input = operands[1];
5528 rtx di = operands[2];
5529
5530 if (!MEM_P (input))
5531 {
5532 rtx tmp = operands[3];
5533 if (altivec_register_operand (input, <QHI:MODE>mode))
5534 emit_insn (gen_extend<QHI:mode>di2 (di, input));
5535 else if (GET_CODE (tmp) == SCRATCH)
5536 emit_insn (gen_extend<QHI:mode>di2 (di, input));
5537 else
5538 {
5539 emit_insn (gen_extend<QHI:mode>di2 (tmp, input));
5540 emit_move_insn (di, tmp);
5541 }
5542 }
5543 else
5544 {
5545 rtx tmp = operands[4];
5546 emit_move_insn (tmp, input);
5547 emit_insn (gen_extend<QHI:mode>di2 (di, tmp));
5548 }
5549
5550 emit_insn (gen_floatdi<FP_ISA3:mode>2 (result, di));
5551 DONE;
5552 })
5553
5554 (define_expand "floatuns<QHI:mode><FP_ISA3:mode>2"
5555 [(parallel [(set (match_operand:FP_ISA3 0 "vsx_register_operand")
5556 (unsigned_float:FP_ISA3
5557 (match_operand:QHI 1 "input_operand")))
5558 (clobber (match_scratch:DI 2))
5559 (clobber (match_scratch:DI 3))])]
5560 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5561 {
5562 if (MEM_P (operands[1]))
5563 operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
5564 })
5565
5566 (define_insn_and_split "*floatuns<QHI:mode><FP_ISA3:mode>2_internal"
5567 [(set (match_operand:FP_ISA3 0 "vsx_register_operand" "=<Fv>,<Fv>,<Fv>")
5568 (unsigned_float:FP_ISA3
5569 (match_operand:QHI 1 "reg_or_indexed_operand" "wK,r,Z")))
5570 (clobber (match_scratch:DI 2 "=wK,wi,wJwK"))
5571 (clobber (match_scratch:DI 3 "=X,r,X"))]
5572 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5573 "#"
5574 "&& reload_completed"
5575 [(const_int 0)]
5576 {
5577 rtx result = operands[0];
5578 rtx input = operands[1];
5579 rtx di = operands[2];
5580
5581 if (MEM_P (input) || altivec_register_operand (input, <QHI:MODE>mode))
5582 emit_insn (gen_zero_extend<QHI:mode>di2 (di, input));
5583 else
5584 {
5585 rtx tmp = operands[3];
5586 if (GET_CODE (tmp) == SCRATCH)
5587 emit_insn (gen_extend<QHI:mode>di2 (di, input));
5588 else
5589 {
5590 emit_insn (gen_zero_extend<QHI:mode>di2 (tmp, input));
5591 emit_move_insn (di, tmp);
5592 }
5593 }
5594
5595 emit_insn (gen_floatdi<FP_ISA3:mode>2 (result, di));
5596 DONE;
5597 })
5598
5599 (define_expand "fix_trunc<mode>si2"
5600 [(set (match_operand:SI 0 "gpc_reg_operand")
5601 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand")))]
5602 "TARGET_HARD_FLOAT"
5603 {
5604 if (!(TARGET_P8_VECTOR && TARGET_DIRECT_MOVE))
5605 {
5606 rtx src = force_reg (<MODE>mode, operands[1]);
5607
5608 if (TARGET_STFIWX)
5609 emit_insn (gen_fix_trunc<mode>si2_stfiwx (operands[0], src));
5610 else
5611 {
5612 rtx tmp = gen_reg_rtx (DImode);
5613 rtx stack = rs6000_allocate_stack_temp (DImode, true, false);
5614 emit_insn (gen_fix_trunc<mode>si2_internal (operands[0], src,
5615 tmp, stack));
5616 }
5617 DONE;
5618 }
5619 })
5620
5621 ; Like the convert to float patterns, this insn must be split before
5622 ; register allocation so that it can allocate the memory slot if it
5623 ; needed
5624 (define_insn_and_split "fix_trunc<mode>si2_stfiwx"
5625 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5626 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
5627 (clobber (match_scratch:DI 2 "=d"))]
5628 "TARGET_HARD_FLOAT && TARGET_STFIWX && can_create_pseudo_p ()
5629 && !(TARGET_P8_VECTOR && TARGET_DIRECT_MOVE)"
5630 "#"
5631 ""
5632 [(pc)]
5633 {
5634 rtx dest = operands[0];
5635 rtx src = operands[1];
5636 rtx tmp = operands[2];
5637
5638 if (GET_CODE (tmp) == SCRATCH)
5639 tmp = gen_reg_rtx (DImode);
5640
5641 emit_insn (gen_fctiwz_<mode> (tmp, src));
5642 if (MEM_P (dest))
5643 {
5644 dest = rs6000_force_indexed_or_indirect_mem (dest);
5645 emit_insn (gen_stfiwx (dest, tmp));
5646 DONE;
5647 }
5648 else if (TARGET_POWERPC64 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5649 {
5650 dest = gen_lowpart (DImode, dest);
5651 emit_move_insn (dest, tmp);
5652 DONE;
5653 }
5654 else
5655 {
5656 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5657 emit_insn (gen_stfiwx (stack, tmp));
5658 emit_move_insn (dest, stack);
5659 DONE;
5660 }
5661 }
5662 [(set_attr "length" "12")
5663 (set_attr "type" "fp")])
5664
5665 (define_insn_and_split "fix_trunc<mode>si2_internal"
5666 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,?r")
5667 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d,<rreg>")))
5668 (clobber (match_operand:DI 2 "gpc_reg_operand" "=1,d"))
5669 (clobber (match_operand:DI 3 "offsettable_mem_operand" "=o,o"))]
5670 "TARGET_HARD_FLOAT
5671 && !(TARGET_P8_VECTOR && TARGET_DIRECT_MOVE)"
5672 "#"
5673 ""
5674 [(pc)]
5675 {
5676 rtx lowword;
5677 gcc_assert (MEM_P (operands[3]));
5678 lowword = adjust_address (operands[3], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
5679
5680 emit_insn (gen_fctiwz_<mode> (operands[2], operands[1]));
5681 emit_move_insn (operands[3], operands[2]);
5682 emit_move_insn (operands[0], lowword);
5683 DONE;
5684 }
5685 [(set_attr "length" "16")
5686 (set_attr "type" "fp")])
5687
5688 (define_expand "fix_trunc<mode>di2"
5689 [(set (match_operand:DI 0 "gpc_reg_operand")
5690 (fix:DI (match_operand:SFDF 1 "gpc_reg_operand")))]
5691 "TARGET_HARD_FLOAT && TARGET_FCFID"
5692 "")
5693
5694 (define_insn "*fix_trunc<mode>di2_fctidz"
5695 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5696 (fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
5697 "TARGET_HARD_FLOAT && TARGET_FCFID"
5698 "@
5699 fctidz %0,%1
5700 xscvdpsxds %x0,%x1"
5701 [(set_attr "type" "fp")])
5702
5703 ;; If we have ISA 3.0, QI/HImode values can go in both VSX registers and GPR
5704 ;; registers. If we have ISA 2.07, we don't allow QI/HImode values in the
5705 ;; vector registers, so we need to do direct moves to the GPRs, but SImode
5706 ;; values can go in VSX registers. Keeping the direct move part through
5707 ;; register allocation prevents the register allocator from doing a direct move
5708 ;; of the SImode value to a GPR, and then a store/load.
5709 (define_insn_and_split "fix<uns>_trunc<SFDF:mode><QHI:mode>2"
5710 [(set (match_operand:<QHI:MODE> 0 "gpc_reg_operand" "=wJ,wJwK,r")
5711 (any_fix:QHI (match_operand:SFDF 1 "gpc_reg_operand" "wJ,wJwK,wa")))
5712 (clobber (match_scratch:SI 2 "=X,X,wi"))]
5713 "TARGET_DIRECT_MOVE"
5714 "@
5715 fctiw<u>z %0,%1
5716 xscvdp<su>xws %x0,%x1
5717 #"
5718 "&& reload_completed && int_reg_operand (operands[0], <QHI:MODE>mode)"
5719 [(set (match_dup 2)
5720 (any_fix:SI (match_dup 1)))
5721 (set (match_dup 3)
5722 (match_dup 2))]
5723 {
5724 operands[3] = gen_rtx_REG (SImode, REGNO (operands[0]));
5725 }
5726 [(set_attr "length" "4,4,8")
5727 (set_attr "type" "fp")])
5728
5729 (define_insn "*fix<uns>_trunc<SFDF:mode>si2_p8"
5730 [(set (match_operand:SI 0 "gpc_reg_operand" "=d,wa")
5731 (any_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d,wa")))]
5732 "TARGET_DIRECT_MOVE"
5733 "@
5734 fctiw<u>z %0,%1
5735 xscvdp<su>xws %x0,%x1"
5736 [(set_attr "type" "fp")])
5737
5738 ;; Keep the convert and store together through register allocation to prevent
5739 ;; the register allocator from getting clever and doing a direct move to a GPR
5740 ;; and then store for reg+offset stores.
5741 (define_insn_and_split "*fix<uns>_trunc<SFDF:mode><QHSI:mode>2_mem"
5742 [(set (match_operand:QHSI 0 "memory_operand" "=Z")
5743 (any_fix:QHSI (match_operand:SFDF 1 "gpc_reg_operand" "wa")))
5744 (clobber (match_scratch:SI 2 "=wa"))]
5745 "(<QHSI:MODE>mode == SImode && TARGET_P8_VECTOR) || TARGET_P9_VECTOR"
5746 "#"
5747 "&& reload_completed"
5748 [(set (match_dup 2)
5749 (any_fix:SI (match_dup 1)))
5750 (set (match_dup 0)
5751 (match_dup 3))]
5752 {
5753 operands[3] = (<QHSI:MODE>mode == SImode
5754 ? operands[2]
5755 : gen_rtx_REG (<QHSI:MODE>mode, REGNO (operands[2])));
5756 })
5757
5758 (define_expand "fixuns_trunc<mode>si2"
5759 [(set (match_operand:SI 0 "gpc_reg_operand")
5760 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand")))]
5761 "TARGET_HARD_FLOAT && TARGET_FCTIWUZ && TARGET_STFIWX"
5762 {
5763 if (!TARGET_P8_VECTOR)
5764 {
5765 emit_insn (gen_fixuns_trunc<mode>si2_stfiwx (operands[0], operands[1]));
5766 DONE;
5767 }
5768 })
5769
5770 (define_insn_and_split "fixuns_trunc<mode>si2_stfiwx"
5771 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5772 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
5773 (clobber (match_scratch:DI 2 "=d"))]
5774 "TARGET_HARD_FLOAT && TARGET_FCTIWUZ
5775 && TARGET_STFIWX && can_create_pseudo_p ()
5776 && !TARGET_P8_VECTOR"
5777 "#"
5778 ""
5779 [(pc)]
5780 {
5781 rtx dest = operands[0];
5782 rtx src = operands[1];
5783 rtx tmp = operands[2];
5784
5785 if (GET_CODE (tmp) == SCRATCH)
5786 tmp = gen_reg_rtx (DImode);
5787
5788 emit_insn (gen_fctiwuz_<mode> (tmp, src));
5789 if (MEM_P (dest))
5790 {
5791 dest = rs6000_force_indexed_or_indirect_mem (dest);
5792 emit_insn (gen_stfiwx (dest, tmp));
5793 DONE;
5794 }
5795 else if (TARGET_POWERPC64 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5796 {
5797 dest = gen_lowpart (DImode, dest);
5798 emit_move_insn (dest, tmp);
5799 DONE;
5800 }
5801 else
5802 {
5803 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5804 emit_insn (gen_stfiwx (stack, tmp));
5805 emit_move_insn (dest, stack);
5806 DONE;
5807 }
5808 }
5809 [(set_attr "length" "12")
5810 (set_attr "type" "fp")])
5811
5812 (define_insn "fixuns_trunc<mode>di2"
5813 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5814 (unsigned_fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
5815 "TARGET_HARD_FLOAT && TARGET_FCTIDUZ"
5816 "@
5817 fctiduz %0,%1
5818 xscvdpuxds %x0,%x1"
5819 [(set_attr "type" "fp")])
5820
5821 (define_insn "rs6000_mtfsb0"
5822 [(unspec_volatile [(match_operand:SI 0 "u5bit_cint_operand" "n")]
5823 UNSPECV_MTFSB0)]
5824 "TARGET_HARD_FLOAT"
5825 "mtfsb0 %0"
5826 [(set_attr "type" "fp")])
5827
5828 (define_insn "rs6000_mtfsb1"
5829 [(unspec_volatile [(match_operand:SI 0 "u5bit_cint_operand" "n")]
5830 UNSPECV_MTFSB1)]
5831 "TARGET_HARD_FLOAT"
5832 "mtfsb1 %0"
5833 [(set_attr "type" "fp")])
5834
5835 (define_insn "rs6000_mffscrn"
5836 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
5837 (unspec_volatile:DF [(match_operand:DF 1 "gpc_reg_operand" "d")]
5838 UNSPECV_MFFSCRN))]
5839 "TARGET_P9_MISC"
5840 "mffscrn %0,%1"
5841 [(set_attr "type" "fp")])
5842
5843 (define_insn "rs6000_mffscdrn"
5844 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
5845 (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFSCDRN))
5846 (use (match_operand:DF 1 "gpc_reg_operand" "d"))]
5847 "TARGET_P9_MISC"
5848 "mffscdrn %0,%1"
5849 [(set_attr "type" "fp")])
5850
5851 (define_expand "rs6000_set_fpscr_rn"
5852 [(match_operand:DI 0 "reg_or_cint_operand")]
5853 "TARGET_HARD_FLOAT"
5854 {
5855 rtx tmp_df = gen_reg_rtx (DFmode);
5856
5857 /* The floating point rounding control bits are FPSCR[62:63]. Put the
5858 new rounding mode bits from operands[0][62:63] into FPSCR[62:63]. */
5859 if (TARGET_P9_MISC)
5860 {
5861 rtx src_df = force_reg (DImode, operands[0]);
5862 src_df = simplify_gen_subreg (DFmode, src_df, DImode, 0);
5863 emit_insn (gen_rs6000_mffscrn (tmp_df, src_df));
5864 DONE;
5865 }
5866
5867 if (CONST_INT_P (operands[0]))
5868 {
5869 if ((INTVAL (operands[0]) & 0x1) == 0x1)
5870 emit_insn (gen_rs6000_mtfsb1 (GEN_INT (31)));
5871 else
5872 emit_insn (gen_rs6000_mtfsb0 (GEN_INT (31)));
5873
5874 if ((INTVAL (operands[0]) & 0x2) == 0x2)
5875 emit_insn (gen_rs6000_mtfsb1 (GEN_INT (30)));
5876 else
5877 emit_insn (gen_rs6000_mtfsb0 (GEN_INT (30)));
5878 }
5879 else
5880 {
5881 rtx tmp_rn = gen_reg_rtx (DImode);
5882 rtx tmp_di = gen_reg_rtx (DImode);
5883
5884 /* Extract new RN mode from operand. */
5885 emit_insn (gen_anddi3 (tmp_rn, operands[0], GEN_INT (0x3)));
5886
5887 /* Insert new RN mode into FSCPR. */
5888 emit_insn (gen_rs6000_mffs (tmp_df));
5889 tmp_di = simplify_gen_subreg (DImode, tmp_df, DFmode, 0);
5890 emit_insn (gen_anddi3 (tmp_di, tmp_di, GEN_INT (-4)));
5891 emit_insn (gen_iordi3 (tmp_di, tmp_di, tmp_rn));
5892
5893 /* Need to write to field k=15. The fields are [0:15]. Hence with
5894 L=0, W=0, FLM_i must be equal to 8, 16 = i + 8*(1-W). FLM is an
5895 8-bit field[0:7]. Need to set the bit that corresponds to the
5896 value of i that you want [0:7]. */
5897 tmp_df = simplify_gen_subreg (DFmode, tmp_di, DImode, 0);
5898 emit_insn (gen_rs6000_mtfsf (GEN_INT (0x01), tmp_df));
5899 }
5900 DONE;
5901 })
5902
5903 (define_expand "rs6000_set_fpscr_drn"
5904 [(match_operand:DI 0 "gpc_reg_operand")]
5905 "TARGET_HARD_FLOAT"
5906 {
5907 rtx tmp_df = gen_reg_rtx (DFmode);
5908
5909 /* The decimal floating point rounding control bits are FPSCR[29:31]. Put the
5910 new rounding mode bits from operands[0][61:63] into FPSCR[29:31]. */
5911 if (TARGET_P9_MISC)
5912 {
5913 rtx src_df = gen_reg_rtx (DFmode);
5914
5915 emit_insn (gen_ashldi3 (operands[0], operands[0], GEN_INT (32)));
5916 src_df = simplify_gen_subreg (DFmode, operands[0], DImode, 0);
5917 emit_insn (gen_rs6000_mffscdrn (tmp_df, src_df));
5918 }
5919 else
5920 {
5921 rtx tmp_rn = gen_reg_rtx (DImode);
5922 rtx tmp_di = gen_reg_rtx (DImode);
5923
5924 /* Extract new DRN mode from operand. */
5925 emit_insn (gen_anddi3 (tmp_rn, operands[0], GEN_INT (0x7)));
5926 emit_insn (gen_ashldi3 (tmp_rn, tmp_rn, GEN_INT (32)));
5927
5928 /* Insert new RN mode into FSCPR. */
5929 emit_insn (gen_rs6000_mffs (tmp_df));
5930 tmp_di = simplify_gen_subreg (DImode, tmp_df, DFmode, 0);
5931 emit_insn (gen_anddi3 (tmp_di, tmp_di, GEN_INT (0xFFFFFFF8FFFFFFFF)));
5932 emit_insn (gen_iordi3 (tmp_di, tmp_di, tmp_rn));
5933
5934 /* Need to write to field 7. The fields are [0:15]. The equation to
5935 select the field is i + 8*(1-W). Hence with L=0 and W=1, need to set
5936 i to 0x1 to get field 7 where i selects the field. */
5937 tmp_df = simplify_gen_subreg (DFmode, tmp_di, DImode, 0);
5938 emit_insn (gen_rs6000_mtfsf_hi (GEN_INT (0x01), tmp_df));
5939 }
5940 DONE;
5941 })
5942
5943 ;; Here, we use (set (reg) (unspec:DI [(fix:SI ...)] UNSPEC_FCTIWZ))
5944 ;; rather than (set (subreg:SI (reg)) (fix:SI ...))
5945 ;; because the first makes it clear that operand 0 is not live
5946 ;; before the instruction.
5947 (define_insn "fctiwz_<mode>"
5948 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5949 (unspec:DI [(fix:SI
5950 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
5951 UNSPEC_FCTIWZ))]
5952 "TARGET_HARD_FLOAT"
5953 "@
5954 fctiwz %0,%1
5955 xscvdpsxws %x0,%x1"
5956 [(set_attr "type" "fp")])
5957
5958 (define_insn "fctiwuz_<mode>"
5959 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5960 (unspec:DI [(unsigned_fix:SI
5961 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
5962 UNSPEC_FCTIWUZ))]
5963 "TARGET_HARD_FLOAT && TARGET_FCTIWUZ"
5964 "@
5965 fctiwuz %0,%1
5966 xscvdpuxws %x0,%x1"
5967 [(set_attr "type" "fp")])
5968
5969 ;; Only optimize (float (fix x)) -> frz if we are in fast-math mode, since
5970 ;; since the friz instruction does not truncate the value if the floating
5971 ;; point value is < LONG_MIN or > LONG_MAX.
5972 (define_insn "*friz"
5973 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
5974 (float:DF (fix:DI (match_operand:DF 1 "gpc_reg_operand" "d,ws"))))]
5975 "TARGET_HARD_FLOAT && TARGET_FPRND
5976 && flag_unsafe_math_optimizations && !flag_trapping_math && TARGET_FRIZ"
5977 "@
5978 friz %0,%1
5979 xsrdpiz %x0,%x1"
5980 [(set_attr "type" "fp")])
5981
5982 ;; Opitmize converting SF/DFmode to signed SImode and back to SF/DFmode. This
5983 ;; optimization prevents on ISA 2.06 systems and earlier having to store the
5984 ;; value from the FPR/vector unit to the stack, load the value into a GPR, sign
5985 ;; extend it, store it back on the stack from the GPR, load it back into the
5986 ;; FP/vector unit to do the rounding. If we have direct move (ISA 2.07),
5987 ;; disable using store and load to sign/zero extend the value.
5988 (define_insn_and_split "*round32<mode>2_fprs"
5989 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
5990 (float:SFDF
5991 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
5992 (clobber (match_scratch:DI 2 "=d"))
5993 (clobber (match_scratch:DI 3 "=d"))]
5994 "TARGET_HARD_FLOAT
5995 && <SI_CONVERT_FP> && TARGET_LFIWAX && TARGET_STFIWX && TARGET_FCFID
5996 && !TARGET_DIRECT_MOVE && can_create_pseudo_p ()"
5997 "#"
5998 ""
5999 [(pc)]
6000 {
6001 rtx dest = operands[0];
6002 rtx src = operands[1];
6003 rtx tmp1 = operands[2];
6004 rtx tmp2 = operands[3];
6005 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
6006
6007 if (GET_CODE (tmp1) == SCRATCH)
6008 tmp1 = gen_reg_rtx (DImode);
6009 if (GET_CODE (tmp2) == SCRATCH)
6010 tmp2 = gen_reg_rtx (DImode);
6011
6012 emit_insn (gen_fctiwz_<mode> (tmp1, src));
6013 emit_insn (gen_stfiwx (stack, tmp1));
6014 emit_insn (gen_lfiwax (tmp2, stack));
6015 emit_insn (gen_floatdi<mode>2 (dest, tmp2));
6016 DONE;
6017 }
6018 [(set_attr "type" "fpload")
6019 (set_attr "length" "16")])
6020
6021 (define_insn_and_split "*roundu32<mode>2_fprs"
6022 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
6023 (unsigned_float:SFDF
6024 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
6025 (clobber (match_scratch:DI 2 "=d"))
6026 (clobber (match_scratch:DI 3 "=d"))]
6027 "TARGET_HARD_FLOAT
6028 && TARGET_LFIWZX && TARGET_STFIWX && TARGET_FCFIDU && !TARGET_DIRECT_MOVE
6029 && can_create_pseudo_p ()"
6030 "#"
6031 ""
6032 [(pc)]
6033 {
6034 rtx dest = operands[0];
6035 rtx src = operands[1];
6036 rtx tmp1 = operands[2];
6037 rtx tmp2 = operands[3];
6038 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
6039
6040 if (GET_CODE (tmp1) == SCRATCH)
6041 tmp1 = gen_reg_rtx (DImode);
6042 if (GET_CODE (tmp2) == SCRATCH)
6043 tmp2 = gen_reg_rtx (DImode);
6044
6045 emit_insn (gen_fctiwuz_<mode> (tmp1, src));
6046 emit_insn (gen_stfiwx (stack, tmp1));
6047 emit_insn (gen_lfiwzx (tmp2, stack));
6048 emit_insn (gen_floatdi<mode>2 (dest, tmp2));
6049 DONE;
6050 }
6051 [(set_attr "type" "fpload")
6052 (set_attr "length" "16")])
6053
6054 ;; No VSX equivalent to fctid
6055 (define_insn "lrint<mode>di2"
6056 [(set (match_operand:DI 0 "gpc_reg_operand" "=d")
6057 (unspec:DI [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
6058 UNSPEC_FCTID))]
6059 "TARGET_HARD_FLOAT && TARGET_FPRND"
6060 "fctid %0,%1"
6061 [(set_attr "type" "fp")])
6062
6063 (define_insn "btrunc<mode>2"
6064 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
6065 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
6066 UNSPEC_FRIZ))]
6067 "TARGET_HARD_FLOAT && TARGET_FPRND"
6068 "@
6069 friz %0,%1
6070 xsrdpiz %x0,%x1"
6071 [(set_attr "type" "fp")])
6072
6073 (define_insn "ceil<mode>2"
6074 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
6075 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
6076 UNSPEC_FRIP))]
6077 "TARGET_HARD_FLOAT && TARGET_FPRND"
6078 "@
6079 frip %0,%1
6080 xsrdpip %x0,%x1"
6081 [(set_attr "type" "fp")])
6082
6083 (define_insn "floor<mode>2"
6084 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
6085 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
6086 UNSPEC_FRIM))]
6087 "TARGET_HARD_FLOAT && TARGET_FPRND"
6088 "@
6089 frim %0,%1
6090 xsrdpim %x0,%x1"
6091 [(set_attr "type" "fp")])
6092
6093 ;; No VSX equivalent to frin
6094 (define_insn "round<mode>2"
6095 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<rreg2>")
6096 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
6097 UNSPEC_FRIN))]
6098 "TARGET_HARD_FLOAT && TARGET_FPRND"
6099 "frin %0,%1"
6100 [(set_attr "type" "fp")])
6101
6102 (define_insn "*xsrdpi<mode>2"
6103 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
6104 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Fv>")]
6105 UNSPEC_XSRDPI))]
6106 "TARGET_HARD_FLOAT && TARGET_VSX"
6107 "xsrdpi %x0,%x1"
6108 [(set_attr "type" "fp")])
6109
6110 (define_expand "lround<mode>di2"
6111 [(set (match_dup 2)
6112 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand")]
6113 UNSPEC_XSRDPI))
6114 (set (match_operand:DI 0 "gpc_reg_operand")
6115 (unspec:DI [(match_dup 2)]
6116 UNSPEC_FCTID))]
6117 "TARGET_HARD_FLOAT && TARGET_VSX && TARGET_FPRND"
6118 {
6119 operands[2] = gen_reg_rtx (<MODE>mode);
6120 })
6121
6122 ; An UNSPEC is used so we don't have to support SImode in FP registers.
6123 ; The 'wu' constraint is used for the 2nd alternative to ensure stxsiwx
6124 ; is only generated for Power8 or later.
6125 (define_insn "stfiwx"
6126 [(set (match_operand:SI 0 "memory_operand" "=Z,Z")
6127 (unspec:SI [(match_operand:DI 1 "gpc_reg_operand" "d,wu")]
6128 UNSPEC_STFIWX))]
6129 "TARGET_PPC_GFXOPT"
6130 "@
6131 stfiwx %1,%y0
6132 stxsiwx %x1,%y0"
6133 [(set_attr "type" "fpstore")])
6134
6135 ;; If we don't have a direct conversion to single precision, don't enable this
6136 ;; conversion for 32-bit without fast math, because we don't have the insn to
6137 ;; generate the fixup swizzle to avoid double rounding problems.
6138 (define_expand "floatsisf2"
6139 [(set (match_operand:SF 0 "gpc_reg_operand")
6140 (float:SF (match_operand:SI 1 "nonimmediate_operand")))]
6141 "TARGET_HARD_FLOAT
6142 && ((TARGET_FCFIDS && TARGET_LFIWAX)
6143 || (TARGET_FCFID
6144 && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))"
6145 {
6146 if (TARGET_FCFIDS && TARGET_LFIWAX)
6147 {
6148 emit_insn (gen_floatsisf2_lfiwax (operands[0], operands[1]));
6149 DONE;
6150 }
6151 else if (TARGET_FCFID && TARGET_LFIWAX)
6152 {
6153 rtx dfreg = gen_reg_rtx (DFmode);
6154 emit_insn (gen_floatsidf2_lfiwax (dfreg, operands[1]));
6155 emit_insn (gen_truncdfsf2 (operands[0], dfreg));
6156 DONE;
6157 }
6158 else
6159 {
6160 rtx dreg = operands[1];
6161 if (!REG_P (dreg))
6162 dreg = force_reg (SImode, dreg);
6163 dreg = convert_to_mode (DImode, dreg, false);
6164 emit_insn (gen_floatdisf2 (operands[0], dreg));
6165 DONE;
6166 }
6167 })
6168
6169 (define_insn "floatdidf2"
6170 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
6171 (float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
6172 "TARGET_FCFID && TARGET_HARD_FLOAT"
6173 "@
6174 fcfid %0,%1
6175 xscvsxddp %x0,%x1"
6176 [(set_attr "type" "fp")])
6177
6178 ; Allow the combiner to merge source memory operands to the conversion so that
6179 ; the optimizer/register allocator doesn't try to load the value too early in a
6180 ; GPR and then use store/load to move it to a FPR and suffer from a store-load
6181 ; hit. We will split after reload to avoid the trip through the GPRs
6182
6183 (define_insn_and_split "*floatdidf2_mem"
6184 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
6185 (float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
6186 (clobber (match_scratch:DI 2 "=d,wi"))]
6187 "TARGET_HARD_FLOAT && TARGET_FCFID"
6188 "#"
6189 "&& reload_completed"
6190 [(set (match_dup 2) (match_dup 1))
6191 (set (match_dup 0) (float:DF (match_dup 2)))]
6192 ""
6193 [(set_attr "length" "8")
6194 (set_attr "type" "fpload")])
6195
6196 (define_expand "floatunsdidf2"
6197 [(set (match_operand:DF 0 "gpc_reg_operand")
6198 (unsigned_float:DF
6199 (match_operand:DI 1 "gpc_reg_operand")))]
6200 "TARGET_HARD_FLOAT && TARGET_FCFIDU"
6201 "")
6202
6203 (define_insn "*floatunsdidf2_fcfidu"
6204 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
6205 (unsigned_float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
6206 "TARGET_HARD_FLOAT && TARGET_FCFIDU"
6207 "@
6208 fcfidu %0,%1
6209 xscvuxddp %x0,%x1"
6210 [(set_attr "type" "fp")])
6211
6212 (define_insn_and_split "*floatunsdidf2_mem"
6213 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
6214 (unsigned_float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
6215 (clobber (match_scratch:DI 2 "=d,wi"))]
6216 "TARGET_HARD_FLOAT && (TARGET_FCFIDU || VECTOR_UNIT_VSX_P (DFmode))"
6217 "#"
6218 "&& reload_completed"
6219 [(set (match_dup 2) (match_dup 1))
6220 (set (match_dup 0) (unsigned_float:DF (match_dup 2)))]
6221 ""
6222 [(set_attr "length" "8")
6223 (set_attr "type" "fpload")])
6224
6225 (define_expand "floatdisf2"
6226 [(set (match_operand:SF 0 "gpc_reg_operand")
6227 (float:SF (match_operand:DI 1 "gpc_reg_operand")))]
6228 "TARGET_FCFID && TARGET_HARD_FLOAT
6229 && (TARGET_FCFIDS || TARGET_POWERPC64 || flag_unsafe_math_optimizations)"
6230 {
6231 if (!TARGET_FCFIDS)
6232 {
6233 rtx val = operands[1];
6234 if (!flag_unsafe_math_optimizations)
6235 {
6236 rtx label = gen_label_rtx ();
6237 val = gen_reg_rtx (DImode);
6238 emit_insn (gen_floatdisf2_internal2 (val, operands[1], label));
6239 emit_label (label);
6240 }
6241 emit_insn (gen_floatdisf2_internal1 (operands[0], val));
6242 DONE;
6243 }
6244 })
6245
6246 (define_insn "floatdisf2_fcfids"
6247 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy")
6248 (float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
6249 "TARGET_HARD_FLOAT && TARGET_FCFIDS"
6250 "@
6251 fcfids %0,%1
6252 xscvsxdsp %x0,%x1"
6253 [(set_attr "type" "fp")])
6254
6255 (define_insn_and_split "*floatdisf2_mem"
6256 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy,wy")
6257 (float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
6258 (clobber (match_scratch:DI 2 "=d,d,wi"))]
6259 "TARGET_HARD_FLOAT && TARGET_FCFIDS"
6260 "#"
6261 "&& reload_completed"
6262 [(pc)]
6263 {
6264 emit_move_insn (operands[2], operands[1]);
6265 emit_insn (gen_floatdisf2_fcfids (operands[0], operands[2]));
6266 DONE;
6267 }
6268 [(set_attr "length" "8")])
6269
6270 ;; This is not IEEE compliant if rounding mode is "round to nearest".
6271 ;; If the DI->DF conversion is inexact, then it's possible to suffer
6272 ;; from double rounding.
6273 ;; Instead of creating a new cpu type for two FP operations, just use fp
6274 (define_insn_and_split "floatdisf2_internal1"
6275 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
6276 (float:SF (match_operand:DI 1 "gpc_reg_operand" "d")))
6277 (clobber (match_scratch:DF 2 "=d"))]
6278 "TARGET_FCFID && TARGET_HARD_FLOAT && !TARGET_FCFIDS"
6279 "#"
6280 "&& reload_completed"
6281 [(set (match_dup 2)
6282 (float:DF (match_dup 1)))
6283 (set (match_dup 0)
6284 (float_truncate:SF (match_dup 2)))]
6285 ""
6286 [(set_attr "length" "8")
6287 (set_attr "type" "fp")])
6288
6289 ;; Twiddles bits to avoid double rounding.
6290 ;; Bits that might be truncated when converting to DFmode are replaced
6291 ;; by a bit that won't be lost at that stage, but is below the SFmode
6292 ;; rounding position.
6293 (define_expand "floatdisf2_internal2"
6294 [(parallel [(set (match_dup 3) (ashiftrt:DI (match_operand:DI 1 "")
6295 (const_int 53)))
6296 (clobber (reg:DI CA_REGNO))])
6297 (set (match_operand:DI 0 "") (and:DI (match_dup 1)
6298 (const_int 2047)))
6299 (set (match_dup 3) (plus:DI (match_dup 3)
6300 (const_int 1)))
6301 (set (match_dup 0) (plus:DI (match_dup 0)
6302 (const_int 2047)))
6303 (set (match_dup 4) (compare:CCUNS (match_dup 3)
6304 (const_int 2)))
6305 (set (match_dup 0) (ior:DI (match_dup 0)
6306 (match_dup 1)))
6307 (set (match_dup 0) (and:DI (match_dup 0)
6308 (const_int -2048)))
6309 (set (pc) (if_then_else (geu (match_dup 4) (const_int 0))
6310 (label_ref (match_operand:DI 2 ""))
6311 (pc)))
6312 (set (match_dup 0) (match_dup 1))]
6313 "TARGET_POWERPC64 && TARGET_HARD_FLOAT && !TARGET_FCFIDS"
6314 {
6315 operands[3] = gen_reg_rtx (DImode);
6316 operands[4] = gen_reg_rtx (CCUNSmode);
6317 })
6318
6319 (define_expand "floatunsdisf2"
6320 [(set (match_operand:SF 0 "gpc_reg_operand")
6321 (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand")))]
6322 "TARGET_HARD_FLOAT && TARGET_FCFIDUS"
6323 "")
6324
6325 (define_insn "floatunsdisf2_fcfidus"
6326 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wu")
6327 (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
6328 "TARGET_HARD_FLOAT && TARGET_FCFIDUS"
6329 "@
6330 fcfidus %0,%1
6331 xscvuxdsp %x0,%x1"
6332 [(set_attr "type" "fp")])
6333
6334 (define_insn_and_split "*floatunsdisf2_mem"
6335 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy,wy")
6336 (unsigned_float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
6337 (clobber (match_scratch:DI 2 "=d,d,wi"))]
6338 "TARGET_HARD_FLOAT && TARGET_FCFIDUS"
6339 "#"
6340 "&& reload_completed"
6341 [(pc)]
6342 {
6343 emit_move_insn (operands[2], operands[1]);
6344 emit_insn (gen_floatunsdisf2_fcfidus (operands[0], operands[2]));
6345 DONE;
6346 }
6347 [(set_attr "length" "8")
6348 (set_attr "type" "fpload")])
6349 \f
6350 ;; Define the TImode operations that can be done in a small number
6351 ;; of instructions. The & constraints are to prevent the register
6352 ;; allocator from allocating registers that overlap with the inputs
6353 ;; (for example, having an input in 7,8 and an output in 6,7). We
6354 ;; also allow for the output being the same as one of the inputs.
6355
6356 (define_expand "addti3"
6357 [(set (match_operand:TI 0 "gpc_reg_operand")
6358 (plus:TI (match_operand:TI 1 "gpc_reg_operand")
6359 (match_operand:TI 2 "reg_or_short_operand")))]
6360 "TARGET_64BIT"
6361 {
6362 rtx lo0 = gen_lowpart (DImode, operands[0]);
6363 rtx lo1 = gen_lowpart (DImode, operands[1]);
6364 rtx lo2 = gen_lowpart (DImode, operands[2]);
6365 rtx hi0 = gen_highpart (DImode, operands[0]);
6366 rtx hi1 = gen_highpart (DImode, operands[1]);
6367 rtx hi2 = gen_highpart_mode (DImode, TImode, operands[2]);
6368
6369 if (!reg_or_short_operand (lo2, DImode))
6370 lo2 = force_reg (DImode, lo2);
6371 if (!adde_operand (hi2, DImode))
6372 hi2 = force_reg (DImode, hi2);
6373
6374 emit_insn (gen_adddi3_carry (lo0, lo1, lo2));
6375 emit_insn (gen_adddi3_carry_in (hi0, hi1, hi2));
6376 DONE;
6377 })
6378
6379 (define_expand "subti3"
6380 [(set (match_operand:TI 0 "gpc_reg_operand")
6381 (minus:TI (match_operand:TI 1 "reg_or_short_operand")
6382 (match_operand:TI 2 "gpc_reg_operand")))]
6383 "TARGET_64BIT"
6384 {
6385 rtx lo0 = gen_lowpart (DImode, operands[0]);
6386 rtx lo1 = gen_lowpart (DImode, operands[1]);
6387 rtx lo2 = gen_lowpart (DImode, operands[2]);
6388 rtx hi0 = gen_highpart (DImode, operands[0]);
6389 rtx hi1 = gen_highpart_mode (DImode, TImode, operands[1]);
6390 rtx hi2 = gen_highpart (DImode, operands[2]);
6391
6392 if (!reg_or_short_operand (lo1, DImode))
6393 lo1 = force_reg (DImode, lo1);
6394 if (!adde_operand (hi1, DImode))
6395 hi1 = force_reg (DImode, hi1);
6396
6397 emit_insn (gen_subfdi3_carry (lo0, lo2, lo1));
6398 emit_insn (gen_subfdi3_carry_in (hi0, hi2, hi1));
6399 DONE;
6400 })
6401 \f
6402 ;; 128-bit logical operations expanders
6403
6404 (define_expand "and<mode>3"
6405 [(set (match_operand:BOOL_128 0 "vlogical_operand")
6406 (and:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")
6407 (match_operand:BOOL_128 2 "vlogical_operand")))]
6408 ""
6409 "")
6410
6411 (define_expand "ior<mode>3"
6412 [(set (match_operand:BOOL_128 0 "vlogical_operand")
6413 (ior:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")
6414 (match_operand:BOOL_128 2 "vlogical_operand")))]
6415 ""
6416 "")
6417
6418 (define_expand "xor<mode>3"
6419 [(set (match_operand:BOOL_128 0 "vlogical_operand")
6420 (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")
6421 (match_operand:BOOL_128 2 "vlogical_operand")))]
6422 ""
6423 "")
6424
6425 (define_expand "one_cmpl<mode>2"
6426 [(set (match_operand:BOOL_128 0 "vlogical_operand")
6427 (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")))]
6428 ""
6429 "")
6430
6431 (define_expand "nor<mode>3"
6432 [(set (match_operand:BOOL_128 0 "vlogical_operand")
6433 (and:BOOL_128
6434 (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand"))
6435 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))))]
6436 ""
6437 "")
6438
6439 (define_expand "andc<mode>3"
6440 [(set (match_operand:BOOL_128 0 "vlogical_operand")
6441 (and:BOOL_128
6442 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))
6443 (match_operand:BOOL_128 1 "vlogical_operand")))]
6444 ""
6445 "")
6446
6447 ;; Power8 vector logical instructions.
6448 (define_expand "eqv<mode>3"
6449 [(set (match_operand:BOOL_128 0 "vlogical_operand")
6450 (not:BOOL_128
6451 (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")
6452 (match_operand:BOOL_128 2 "vlogical_operand"))))]
6453 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6454 "")
6455
6456 ;; Rewrite nand into canonical form
6457 (define_expand "nand<mode>3"
6458 [(set (match_operand:BOOL_128 0 "vlogical_operand")
6459 (ior:BOOL_128
6460 (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand"))
6461 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))))]
6462 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6463 "")
6464
6465 ;; The canonical form is to have the negated element first, so we need to
6466 ;; reverse arguments.
6467 (define_expand "orc<mode>3"
6468 [(set (match_operand:BOOL_128 0 "vlogical_operand")
6469 (ior:BOOL_128
6470 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))
6471 (match_operand:BOOL_128 1 "vlogical_operand")))]
6472 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6473 "")
6474
6475 ;; 128-bit logical operations insns and split operations
6476 (define_insn_and_split "*and<mode>3_internal"
6477 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6478 (and:BOOL_128
6479 (match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
6480 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")))]
6481 ""
6482 {
6483 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6484 return "xxland %x0,%x1,%x2";
6485
6486 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6487 return "vand %0,%1,%2";
6488
6489 return "#";
6490 }
6491 "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6492 [(const_int 0)]
6493 {
6494 rs6000_split_logical (operands, AND, false, false, false);
6495 DONE;
6496 }
6497 [(set (attr "type")
6498 (if_then_else
6499 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6500 (const_string "veclogical")
6501 (const_string "integer")))
6502 (set (attr "length")
6503 (if_then_else
6504 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6505 (const_string "4")
6506 (if_then_else
6507 (match_test "TARGET_POWERPC64")
6508 (const_string "8")
6509 (const_string "16"))))])
6510
6511 ;; 128-bit IOR/XOR
6512 (define_insn_and_split "*bool<mode>3_internal"
6513 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6514 (match_operator:BOOL_128 3 "boolean_or_operator"
6515 [(match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
6516 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")]))]
6517 ""
6518 {
6519 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6520 return "xxl%q3 %x0,%x1,%x2";
6521
6522 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6523 return "v%q3 %0,%1,%2";
6524
6525 return "#";
6526 }
6527 "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6528 [(const_int 0)]
6529 {
6530 rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, false);
6531 DONE;
6532 }
6533 [(set (attr "type")
6534 (if_then_else
6535 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6536 (const_string "veclogical")
6537 (const_string "integer")))
6538 (set (attr "length")
6539 (if_then_else
6540 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6541 (const_string "4")
6542 (if_then_else
6543 (match_test "TARGET_POWERPC64")
6544 (const_string "8")
6545 (const_string "16"))))])
6546
6547 ;; 128-bit ANDC/ORC
6548 (define_insn_and_split "*boolc<mode>3_internal1"
6549 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6550 (match_operator:BOOL_128 3 "boolean_operator"
6551 [(not:BOOL_128
6552 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))
6553 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")]))]
6554 "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
6555 {
6556 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6557 return "xxl%q3 %x0,%x1,%x2";
6558
6559 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6560 return "v%q3 %0,%1,%2";
6561
6562 return "#";
6563 }
6564 "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
6565 && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6566 [(const_int 0)]
6567 {
6568 rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
6569 DONE;
6570 }
6571 [(set (attr "type")
6572 (if_then_else
6573 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6574 (const_string "veclogical")
6575 (const_string "integer")))
6576 (set (attr "length")
6577 (if_then_else
6578 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6579 (const_string "4")
6580 (if_then_else
6581 (match_test "TARGET_POWERPC64")
6582 (const_string "8")
6583 (const_string "16"))))])
6584
6585 (define_insn_and_split "*boolc<mode>3_internal2"
6586 [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6587 (match_operator:TI2 3 "boolean_operator"
6588 [(not:TI2
6589 (match_operand:TI2 2 "int_reg_operand" "r,0,r"))
6590 (match_operand:TI2 1 "int_reg_operand" "r,r,0")]))]
6591 "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6592 "#"
6593 "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6594 [(const_int 0)]
6595 {
6596 rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
6597 DONE;
6598 }
6599 [(set_attr "type" "integer")
6600 (set (attr "length")
6601 (if_then_else
6602 (match_test "TARGET_POWERPC64")
6603 (const_string "8")
6604 (const_string "16")))])
6605
6606 ;; 128-bit NAND/NOR
6607 (define_insn_and_split "*boolcc<mode>3_internal1"
6608 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6609 (match_operator:BOOL_128 3 "boolean_operator"
6610 [(not:BOOL_128
6611 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>"))
6612 (not:BOOL_128
6613 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))]))]
6614 "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
6615 {
6616 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6617 return "xxl%q3 %x0,%x1,%x2";
6618
6619 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6620 return "v%q3 %0,%1,%2";
6621
6622 return "#";
6623 }
6624 "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
6625 && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6626 [(const_int 0)]
6627 {
6628 rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
6629 DONE;
6630 }
6631 [(set (attr "type")
6632 (if_then_else
6633 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6634 (const_string "veclogical")
6635 (const_string "integer")))
6636 (set (attr "length")
6637 (if_then_else
6638 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6639 (const_string "4")
6640 (if_then_else
6641 (match_test "TARGET_POWERPC64")
6642 (const_string "8")
6643 (const_string "16"))))])
6644
6645 (define_insn_and_split "*boolcc<mode>3_internal2"
6646 [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6647 (match_operator:TI2 3 "boolean_operator"
6648 [(not:TI2
6649 (match_operand:TI2 1 "int_reg_operand" "r,0,r"))
6650 (not:TI2
6651 (match_operand:TI2 2 "int_reg_operand" "r,r,0"))]))]
6652 "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6653 "#"
6654 "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6655 [(const_int 0)]
6656 {
6657 rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
6658 DONE;
6659 }
6660 [(set_attr "type" "integer")
6661 (set (attr "length")
6662 (if_then_else
6663 (match_test "TARGET_POWERPC64")
6664 (const_string "8")
6665 (const_string "16")))])
6666
6667
6668 ;; 128-bit EQV
6669 (define_insn_and_split "*eqv<mode>3_internal1"
6670 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6671 (not:BOOL_128
6672 (xor:BOOL_128
6673 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")
6674 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))))]
6675 "TARGET_P8_VECTOR"
6676 {
6677 if (vsx_register_operand (operands[0], <MODE>mode))
6678 return "xxleqv %x0,%x1,%x2";
6679
6680 return "#";
6681 }
6682 "TARGET_P8_VECTOR && reload_completed
6683 && int_reg_operand (operands[0], <MODE>mode)"
6684 [(const_int 0)]
6685 {
6686 rs6000_split_logical (operands, XOR, true, false, false);
6687 DONE;
6688 }
6689 [(set (attr "type")
6690 (if_then_else
6691 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6692 (const_string "veclogical")
6693 (const_string "integer")))
6694 (set (attr "length")
6695 (if_then_else
6696 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6697 (const_string "4")
6698 (if_then_else
6699 (match_test "TARGET_POWERPC64")
6700 (const_string "8")
6701 (const_string "16"))))])
6702
6703 (define_insn_and_split "*eqv<mode>3_internal2"
6704 [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6705 (not:TI2
6706 (xor:TI2
6707 (match_operand:TI2 1 "int_reg_operand" "r,0,r")
6708 (match_operand:TI2 2 "int_reg_operand" "r,r,0"))))]
6709 "!TARGET_P8_VECTOR"
6710 "#"
6711 "reload_completed && !TARGET_P8_VECTOR"
6712 [(const_int 0)]
6713 {
6714 rs6000_split_logical (operands, XOR, true, false, false);
6715 DONE;
6716 }
6717 [(set_attr "type" "integer")
6718 (set (attr "length")
6719 (if_then_else
6720 (match_test "TARGET_POWERPC64")
6721 (const_string "8")
6722 (const_string "16")))])
6723
6724 ;; 128-bit one's complement
6725 (define_insn_and_split "*one_cmpl<mode>3_internal"
6726 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6727 (not:BOOL_128
6728 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_UNARY>")))]
6729 ""
6730 {
6731 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6732 return "xxlnor %x0,%x1,%x1";
6733
6734 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6735 return "vnor %0,%1,%1";
6736
6737 return "#";
6738 }
6739 "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6740 [(const_int 0)]
6741 {
6742 rs6000_split_logical (operands, NOT, false, false, false);
6743 DONE;
6744 }
6745 [(set (attr "type")
6746 (if_then_else
6747 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6748 (const_string "veclogical")
6749 (const_string "integer")))
6750 (set (attr "length")
6751 (if_then_else
6752 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6753 (const_string "4")
6754 (if_then_else
6755 (match_test "TARGET_POWERPC64")
6756 (const_string "8")
6757 (const_string "16"))))])
6758
6759 \f
6760 ;; Now define ways of moving data around.
6761
6762 ;; Set up a register with a value from the GOT table
6763
6764 (define_expand "movsi_got"
6765 [(set (match_operand:SI 0 "gpc_reg_operand")
6766 (unspec:SI [(match_operand:SI 1 "got_operand")
6767 (match_dup 2)] UNSPEC_MOVSI_GOT))]
6768 "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
6769 {
6770 if (GET_CODE (operands[1]) == CONST)
6771 {
6772 rtx offset = const0_rtx;
6773 HOST_WIDE_INT value;
6774
6775 operands[1] = eliminate_constant_term (XEXP (operands[1], 0), &offset);
6776 value = INTVAL (offset);
6777 if (value != 0)
6778 {
6779 rtx tmp = (!can_create_pseudo_p ()
6780 ? operands[0]
6781 : gen_reg_rtx (Pmode));
6782 emit_insn (gen_movsi_got (tmp, operands[1]));
6783 emit_insn (gen_addsi3 (operands[0], tmp, offset));
6784 DONE;
6785 }
6786 }
6787
6788 operands[2] = rs6000_got_register (operands[1]);
6789 })
6790
6791 (define_insn "*movsi_got_internal"
6792 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6793 (unspec:SI [(match_operand:SI 1 "got_no_const_operand" "")
6794 (match_operand:SI 2 "gpc_reg_operand" "b")]
6795 UNSPEC_MOVSI_GOT))]
6796 "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
6797 "lwz %0,%a1@got(%2)"
6798 [(set_attr "type" "load")])
6799
6800 ;; Used by sched, shorten_branches and final when the GOT pseudo reg
6801 ;; didn't get allocated to a hard register.
6802 (define_split
6803 [(set (match_operand:SI 0 "gpc_reg_operand")
6804 (unspec:SI [(match_operand:SI 1 "got_no_const_operand")
6805 (match_operand:SI 2 "memory_operand")]
6806 UNSPEC_MOVSI_GOT))]
6807 "DEFAULT_ABI == ABI_V4
6808 && flag_pic == 1
6809 && reload_completed"
6810 [(set (match_dup 0) (match_dup 2))
6811 (set (match_dup 0) (unspec:SI [(match_dup 1)(match_dup 0)]
6812 UNSPEC_MOVSI_GOT))]
6813 "")
6814
6815 ;; For SI, we special-case integers that can't be loaded in one insn. We
6816 ;; do the load 16-bits at a time. We could do this by loading from memory,
6817 ;; and this is even supposed to be faster, but it is simpler not to get
6818 ;; integers in the TOC.
6819 (define_insn "movsi_low"
6820 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6821 (mem:SI (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
6822 (match_operand 2 "" ""))))]
6823 "TARGET_MACHO && ! TARGET_64BIT"
6824 "lwz %0,lo16(%2)(%1)"
6825 [(set_attr "type" "load")])
6826
6827 ;; MR LA LWZ LFIWZX LXSIWZX
6828 ;; STW STFIWX STXSIWX LI LIS
6829 ;; # XXLOR XXSPLTIB 0 XXSPLTIB -1 VSPLTISW
6830 ;; XXLXOR 0 XXLORC -1 P9 const MTVSRWZ MFVSRWZ
6831 ;; MF%1 MT%0 NOP
6832 (define_insn "*movsi_internal1"
6833 [(set (match_operand:SI 0 "nonimmediate_operand"
6834 "=r, r, r, ?*wI, ?*wH,
6835 m, ?Z, ?Z, r, r,
6836 r, ?*wIwH, ?*wJwK, ?*wJwK, ?*wu,
6837 ?*wJwK, ?*wH, ?*wK, ?*wIwH, ?r,
6838 r, *h, *h")
6839
6840 (match_operand:SI 1 "input_operand"
6841 "r, U, m, Z, Z,
6842 r, wI, wH, I, L,
6843 n, wIwH, O, wM, wB,
6844 O, wM, wS, r, wIwH,
6845 *h, r, 0"))]
6846
6847 "gpc_reg_operand (operands[0], SImode)
6848 || gpc_reg_operand (operands[1], SImode)"
6849 "@
6850 mr %0,%1
6851 la %0,%a1
6852 lwz%U1%X1 %0,%1
6853 lfiwzx %0,%y1
6854 lxsiwzx %x0,%y1
6855 stw%U0%X0 %1,%0
6856 stfiwx %1,%y0
6857 stxsiwx %x1,%y0
6858 li %0,%1
6859 lis %0,%v1
6860 #
6861 xxlor %x0,%x1,%x1
6862 xxspltib %x0,0
6863 xxspltib %x0,255
6864 vspltisw %0,%1
6865 xxlxor %x0,%x0,%x0
6866 xxlorc %x0,%x0,%x0
6867 #
6868 mtvsrwz %x0,%1
6869 mfvsrwz %0,%x1
6870 mf%1 %0
6871 mt%0 %1
6872 nop"
6873 [(set_attr "type"
6874 "*, *, load, fpload, fpload,
6875 store, fpstore, fpstore, *, *,
6876 *, veclogical, vecsimple, vecsimple, vecsimple,
6877 veclogical, veclogical, vecsimple, mffgpr, mftgpr,
6878 *, *, *")
6879
6880 (set_attr "length"
6881 "4, 4, 4, 4, 4,
6882 4, 4, 4, 4, 4,
6883 8, 4, 4, 4, 4,
6884 4, 4, 8, 4, 4,
6885 4, 4, 4")])
6886
6887 ;; Like movsi, but adjust a SF value to be used in a SI context, i.e.
6888 ;; (set (reg:SI ...) (subreg:SI (reg:SF ...) 0))
6889 ;;
6890 ;; Because SF values are actually stored as DF values within the vector
6891 ;; registers, we need to convert the value to the vector SF format when
6892 ;; we need to use the bits in a union or similar cases. We only need
6893 ;; to do this transformation when the value is a vector register. Loads,
6894 ;; stores, and transfers within GPRs are assumed to be safe.
6895 ;;
6896 ;; This is a more general case of reload_gpr_from_vsxsf. That insn must have
6897 ;; no alternatives, because the call is created as part of secondary_reload,
6898 ;; and operand #2's register class is used to allocate the temporary register.
6899 ;; This function is called before reload, and it creates the temporary as
6900 ;; needed.
6901
6902 ;; MR LWZ LFIWZX LXSIWZX STW
6903 ;; STFS STXSSP STXSSPX VSX->GPR VSX->VSX
6904 ;; MTVSRWZ
6905
6906 (define_insn_and_split "movsi_from_sf"
6907 [(set (match_operand:SI 0 "nonimmediate_operand"
6908 "=r, r, ?*wI, ?*wH, m,
6909 m, wY, Z, r, ?*wIwH,
6910 wIwH")
6911
6912 (unspec:SI [(match_operand:SF 1 "input_operand"
6913 "r, m, Z, Z, r,
6914 f, wb, wu, wIwH, wIwH,
6915 r")]
6916 UNSPEC_SI_FROM_SF))
6917
6918 (clobber (match_scratch:V4SF 2
6919 "=X, X, X, X, X,
6920 X, X, X, wIwH, X,
6921 X"))]
6922
6923 "TARGET_NO_SF_SUBREG
6924 && (register_operand (operands[0], SImode)
6925 || register_operand (operands[1], SFmode))"
6926 "@
6927 mr %0,%1
6928 lwz%U1%X1 %0,%1
6929 lfiwzx %0,%y1
6930 lxsiwzx %x0,%y1
6931 stw%U0%X0 %1,%0
6932 stfs%U0%X0 %1,%0
6933 stxssp %1,%0
6934 stxsspx %x1,%y0
6935 #
6936 xscvdpspn %x0,%x1
6937 mtvsrwz %x0,%1"
6938 "&& reload_completed
6939 && int_reg_operand (operands[0], SImode)
6940 && vsx_reg_sfsubreg_ok (operands[1], SFmode)"
6941 [(const_int 0)]
6942 {
6943 rtx op0 = operands[0];
6944 rtx op1 = operands[1];
6945 rtx op2 = operands[2];
6946 rtx op0_di = gen_rtx_REG (DImode, reg_or_subregno (op0));
6947 rtx op2_si = gen_rtx_REG (SImode, reg_or_subregno (op2));
6948
6949 emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
6950 emit_insn (gen_zero_extendsidi2 (op0_di, op2_si));
6951 DONE;
6952 }
6953 [(set_attr "type"
6954 "*, load, fpload, fpload, store,
6955 fpstore, fpstore, fpstore, mftgpr, fp,
6956 mffgpr")
6957
6958 (set_attr "length"
6959 "4, 4, 4, 4, 4,
6960 4, 4, 4, 8, 4,
6961 4")])
6962
6963 ;; movsi_from_sf with zero extension
6964 ;;
6965 ;; RLDICL LWZ LFIWZX LXSIWZX VSX->GPR
6966 ;; VSX->VSX MTVSRWZ
6967
6968 (define_insn_and_split "*movdi_from_sf_zero_ext"
6969 [(set (match_operand:DI 0 "gpc_reg_operand"
6970 "=r, r, ?*wI, ?*wH, r,
6971 ?wK, wIwH")
6972
6973 (zero_extend:DI
6974 (unspec:SI [(match_operand:SF 1 "input_operand"
6975 "r, m, Z, Z, wIwH,
6976 wIwH, r")]
6977 UNSPEC_SI_FROM_SF)))
6978
6979 (clobber (match_scratch:V4SF 2
6980 "=X, X, X, X, wa,
6981 wIwH, X"))]
6982
6983 "TARGET_DIRECT_MOVE_64BIT
6984 && (register_operand (operands[0], DImode)
6985 || register_operand (operands[1], SImode))"
6986 "@
6987 rldicl %0,%1,0,32
6988 lwz%U1%X1 %0,%1
6989 lfiwzx %0,%y1
6990 lxsiwzx %x0,%y1
6991 #
6992 #
6993 mtvsrwz %x0,%1"
6994 "&& reload_completed
6995 && register_operand (operands[0], DImode)
6996 && vsx_reg_sfsubreg_ok (operands[1], SFmode)"
6997 [(const_int 0)]
6998 {
6999 rtx op0 = operands[0];
7000 rtx op1 = operands[1];
7001 rtx op2 = operands[2];
7002 rtx op2_si = gen_rtx_REG (SImode, reg_or_subregno (op2));
7003
7004 emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
7005 emit_insn (gen_zero_extendsidi2 (op0, op2_si));
7006 DONE;
7007 }
7008 [(set_attr "type"
7009 "*, load, fpload, fpload, two,
7010 two, mffgpr")
7011
7012 (set_attr "length"
7013 "4, 4, 4, 4, 8,
7014 8, 4")])
7015
7016 ;; Like movsi_from_sf, but combine a convert from DFmode to SFmode before
7017 ;; moving it to SImode. We can do a SFmode store without having to do the
7018 ;; conversion explicitly. If we are doing a register->register conversion, use
7019 ;; XSCVDPSP instead of XSCVDPSPN, since the former handles cases where the
7020 ;; input will not fit in a SFmode, and the later assumes the value has already
7021 ;; been rounded.
7022 (define_insn "*movsi_from_df"
7023 [(set (match_operand:SI 0 "nonimmediate_operand" "=wa,m,wY,Z")
7024 (unspec:SI [(float_truncate:SF
7025 (match_operand:DF 1 "gpc_reg_operand" "wa, f,wb,wa"))]
7026 UNSPEC_SI_FROM_SF))]
7027
7028 "TARGET_NO_SF_SUBREG"
7029 "@
7030 xscvdpsp %x0,%x1
7031 stfs%U0%X0 %1,%0
7032 stxssp %1,%0
7033 stxsspx %x1,%y0"
7034 [(set_attr "type" "fp,fpstore,fpstore,fpstore")])
7035
7036 ;; Split a load of a large constant into the appropriate two-insn
7037 ;; sequence.
7038
7039 (define_split
7040 [(set (match_operand:SI 0 "gpc_reg_operand")
7041 (match_operand:SI 1 "const_int_operand"))]
7042 "(unsigned HOST_WIDE_INT) (INTVAL (operands[1]) + 0x8000) >= 0x10000
7043 && (INTVAL (operands[1]) & 0xffff) != 0"
7044 [(set (match_dup 0)
7045 (match_dup 2))
7046 (set (match_dup 0)
7047 (ior:SI (match_dup 0)
7048 (match_dup 3)))]
7049 {
7050 if (rs6000_emit_set_const (operands[0], operands[1]))
7051 DONE;
7052 else
7053 FAIL;
7054 })
7055
7056 ;; Split loading -128..127 to use XXSPLITB and VEXTSW2D
7057 (define_split
7058 [(set (match_operand:DI 0 "altivec_register_operand")
7059 (match_operand:DI 1 "xxspltib_constant_split"))]
7060 "TARGET_P9_VECTOR && reload_completed"
7061 [(const_int 0)]
7062 {
7063 rtx op0 = operands[0];
7064 rtx op1 = operands[1];
7065 int r = REGNO (op0);
7066 rtx op0_v16qi = gen_rtx_REG (V16QImode, r);
7067
7068 emit_insn (gen_xxspltib_v16qi (op0_v16qi, op1));
7069 emit_insn (gen_vsx_sign_extend_qi_si (operands[0], op0_v16qi));
7070 DONE;
7071 })
7072
7073 (define_insn "*mov<mode>_internal2"
7074 [(set (match_operand:CC 2 "cc_reg_operand" "=y,x,?y")
7075 (compare:CC (match_operand:P 1 "gpc_reg_operand" "0,r,r")
7076 (const_int 0)))
7077 (set (match_operand:P 0 "gpc_reg_operand" "=r,r,r") (match_dup 1))]
7078 ""
7079 "@
7080 cmp<wd>i %2,%0,0
7081 mr. %0,%1
7082 #"
7083 [(set_attr "type" "cmp,logical,cmp")
7084 (set_attr "dot" "yes")
7085 (set_attr "length" "4,4,8")])
7086
7087 (define_split
7088 [(set (match_operand:CC 2 "cc_reg_not_cr0_operand")
7089 (compare:CC (match_operand:P 1 "gpc_reg_operand")
7090 (const_int 0)))
7091 (set (match_operand:P 0 "gpc_reg_operand") (match_dup 1))]
7092 "reload_completed"
7093 [(set (match_dup 0) (match_dup 1))
7094 (set (match_dup 2)
7095 (compare:CC (match_dup 0)
7096 (const_int 0)))]
7097 "")
7098 \f
7099 (define_expand "mov<mode>"
7100 [(set (match_operand:INT 0 "general_operand")
7101 (match_operand:INT 1 "any_operand"))]
7102 ""
7103 {
7104 rs6000_emit_move (operands[0], operands[1], <MODE>mode);
7105 DONE;
7106 })
7107
7108 ;; MR LHZ/LBZ LXSI*ZX STH/STB STXSI*X LI
7109 ;; XXLOR load 0 load -1 VSPLTI* # MFVSRWZ
7110 ;; MTVSRWZ MF%1 MT%1 NOP
7111 (define_insn "*mov<mode>_internal"
7112 [(set (match_operand:QHI 0 "nonimmediate_operand"
7113 "=r, r, ?*wJwK, m, Z, r,
7114 ?*wJwK, ?*wJwK, ?*wJwK, ?*wK, ?*wK, r,
7115 ?*wJwK, r, *c*l, *h")
7116
7117 (match_operand:QHI 1 "input_operand"
7118 "r, m, Z, r, wJwK, i,
7119 wJwK, O, wM, wB, wS, ?*wJwK,
7120 r, *h, r, 0"))]
7121
7122 "gpc_reg_operand (operands[0], <MODE>mode)
7123 || gpc_reg_operand (operands[1], <MODE>mode)"
7124 "@
7125 mr %0,%1
7126 l<wd>z%U1%X1 %0,%1
7127 lxsi<wd>zx %x0,%y1
7128 st<wd>%U0%X0 %1,%0
7129 stxsi<wd>x %x1,%y0
7130 li %0,%1
7131 xxlor %x0,%x1,%x1
7132 xxspltib %x0,0
7133 xxspltib %x0,255
7134 vspltis<wd> %0,%1
7135 #
7136 mfvsrwz %0,%x1
7137 mtvsrwz %x0,%1
7138 mf%1 %0
7139 mt%0 %1
7140 nop"
7141 [(set_attr "type"
7142 "*, load, fpload, store, fpstore, *,
7143 vecsimple, vecperm, vecperm, vecperm, vecperm, mftgpr,
7144 mffgpr, mfjmpr, mtjmpr, *")
7145
7146 (set_attr "length"
7147 "4, 4, 4, 4, 4, 4,
7148 4, 4, 4, 4, 8, 4,
7149 4, 4, 4, 4")])
7150
7151 \f
7152 ;; Here is how to move condition codes around. When we store CC data in
7153 ;; an integer register or memory, we store just the high-order 4 bits.
7154 ;; This lets us not shift in the most common case of CR0.
7155 (define_expand "movcc"
7156 [(set (match_operand:CC 0 "nonimmediate_operand")
7157 (match_operand:CC 1 "nonimmediate_operand"))]
7158 ""
7159 "")
7160
7161 (define_insn "*movcc_internal1"
7162 [(set (match_operand:CC 0 "nonimmediate_operand"
7163 "=y,x,?y,y,r,r,r,r, r,*c*l,r,m")
7164 (match_operand:CC 1 "general_operand"
7165 " y,r, r,O,x,y,r,I,*h, r,m,r"))]
7166 "register_operand (operands[0], CCmode)
7167 || register_operand (operands[1], CCmode)"
7168 "@
7169 mcrf %0,%1
7170 mtcrf 128,%1
7171 rlwinm %1,%1,%F0,0xffffffff\;mtcrf %R0,%1\;rlwinm %1,%1,%f0,0xffffffff
7172 crxor %0,%0,%0
7173 mfcr %0%Q1
7174 mfcr %0%Q1\;rlwinm %0,%0,%f1,0xf0000000
7175 mr %0,%1
7176 li %0,%1
7177 mf%1 %0
7178 mt%0 %1
7179 lwz%U1%X1 %0,%1
7180 stw%U0%X0 %1,%0"
7181 [(set_attr_alternative "type"
7182 [(const_string "cr_logical")
7183 (const_string "mtcr")
7184 (const_string "mtcr")
7185 (const_string "cr_logical")
7186 (if_then_else (match_test "TARGET_MFCRF")
7187 (const_string "mfcrf") (const_string "mfcr"))
7188 (if_then_else (match_test "TARGET_MFCRF")
7189 (const_string "mfcrf") (const_string "mfcr"))
7190 (const_string "integer")
7191 (const_string "integer")
7192 (const_string "mfjmpr")
7193 (const_string "mtjmpr")
7194 (const_string "load")
7195 (const_string "store")])
7196 (set_attr "length" "4,4,12,4,4,8,4,4,4,4,4,4")])
7197 \f
7198 ;; For floating-point, we normally deal with the floating-point registers
7199 ;; unless -msoft-float is used. The sole exception is that parameter passing
7200 ;; can produce floating-point values in fixed-point registers. Unless the
7201 ;; value is a simple constant or already in memory, we deal with this by
7202 ;; allocating memory and copying the value explicitly via that memory location.
7203
7204 ;; Move 32-bit binary/decimal floating point
7205 (define_expand "mov<mode>"
7206 [(set (match_operand:FMOVE32 0 "nonimmediate_operand")
7207 (match_operand:FMOVE32 1 "any_operand"))]
7208 "<fmove_ok>"
7209 {
7210 rs6000_emit_move (operands[0], operands[1], <MODE>mode);
7211 DONE;
7212 })
7213
7214 (define_split
7215 [(set (match_operand:FMOVE32 0 "gpc_reg_operand")
7216 (match_operand:FMOVE32 1 "const_double_operand"))]
7217 "reload_completed
7218 && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
7219 || (GET_CODE (operands[0]) == SUBREG
7220 && GET_CODE (SUBREG_REG (operands[0])) == REG
7221 && REGNO (SUBREG_REG (operands[0])) <= 31))"
7222 [(set (match_dup 2) (match_dup 3))]
7223 {
7224 long l;
7225
7226 <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7227
7228 if (! TARGET_POWERPC64)
7229 operands[2] = operand_subword (operands[0], 0, 0, <MODE>mode);
7230 else
7231 operands[2] = gen_lowpart (SImode, operands[0]);
7232
7233 operands[3] = gen_int_mode (l, SImode);
7234 })
7235
7236 ;; Originally, we tried to keep movsf and movsd common, but the differences
7237 ;; addressing was making it rather difficult to hide with mode attributes. In
7238 ;; particular for SFmode, on ISA 2.07 (power8) systems, having the GPR store
7239 ;; before the VSX stores meant that the register allocator would tend to do a
7240 ;; direct move to the GPR (which involves conversion from scalar to
7241 ;; vector/memory formats) to save values in the traditional Altivec registers,
7242 ;; while SDmode had problems on power6 if the GPR store was not first due to
7243 ;; the power6 not having an integer store operation.
7244 ;;
7245 ;; LWZ LFS LXSSP LXSSPX STFS STXSSP
7246 ;; STXSSPX STW XXLXOR LI FMR XSCPSGNDP
7247 ;; MR MT<x> MF<x> NOP
7248
7249 (define_insn "movsf_hardfloat"
7250 [(set (match_operand:SF 0 "nonimmediate_operand"
7251 "=!r, f, wb, wu, m, wY,
7252 Z, m, ww, !r, f, ww,
7253 !r, *c*l, !r, *h")
7254 (match_operand:SF 1 "input_operand"
7255 "m, m, wY, Z, f, wb,
7256 wu, r, j, j, f, ww,
7257 r, r, *h, 0"))]
7258 "(register_operand (operands[0], SFmode)
7259 || register_operand (operands[1], SFmode))
7260 && TARGET_HARD_FLOAT
7261 && (TARGET_ALLOW_SF_SUBREG
7262 || valid_sf_si_move (operands[0], operands[1], SFmode))"
7263 "@
7264 lwz%U1%X1 %0,%1
7265 lfs%U1%X1 %0,%1
7266 lxssp %0,%1
7267 lxsspx %x0,%y1
7268 stfs%U0%X0 %1,%0
7269 stxssp %1,%0
7270 stxsspx %x1,%y0
7271 stw%U0%X0 %1,%0
7272 xxlxor %x0,%x0,%x0
7273 li %0,0
7274 fmr %0,%1
7275 xscpsgndp %x0,%x1,%x1
7276 mr %0,%1
7277 mt%0 %1
7278 mf%1 %0
7279 nop"
7280 [(set_attr "type"
7281 "load, fpload, fpload, fpload, fpstore, fpstore,
7282 fpstore, store, veclogical, integer, fpsimple, fpsimple,
7283 *, mtjmpr, mfjmpr, *")])
7284
7285 ;; LWZ LFIWZX STW STFIWX MTVSRWZ MFVSRWZ
7286 ;; FMR MR MT%0 MF%1 NOP
7287 (define_insn "movsd_hardfloat"
7288 [(set (match_operand:SD 0 "nonimmediate_operand"
7289 "=!r, wz, m, Z, ?wh, ?r,
7290 f, !r, *c*l, !r, *h")
7291 (match_operand:SD 1 "input_operand"
7292 "m, Z, r, wx, r, wh,
7293 f, r, r, *h, 0"))]
7294 "(register_operand (operands[0], SDmode)
7295 || register_operand (operands[1], SDmode))
7296 && TARGET_HARD_FLOAT"
7297 "@
7298 lwz%U1%X1 %0,%1
7299 lfiwzx %0,%y1
7300 stw%U0%X0 %1,%0
7301 stfiwx %1,%y0
7302 mtvsrwz %x0,%1
7303 mfvsrwz %0,%x1
7304 fmr %0,%1
7305 mr %0,%1
7306 mt%0 %1
7307 mf%1 %0
7308 nop"
7309 [(set_attr "type"
7310 "load, fpload, store, fpstore, mffgpr, mftgpr,
7311 fpsimple, *, mtjmpr, mfjmpr, *")])
7312
7313 ;; MR MT%0 MF%0 LWZ STW LI
7314 ;; LIS G-const. F/n-const NOP
7315 (define_insn "*mov<mode>_softfloat"
7316 [(set (match_operand:FMOVE32 0 "nonimmediate_operand"
7317 "=r, *c*l, r, r, m, r,
7318 r, r, r, *h")
7319
7320 (match_operand:FMOVE32 1 "input_operand"
7321 "r, r, *h, m, r, I,
7322 L, G, Fn, 0"))]
7323
7324 "(gpc_reg_operand (operands[0], <MODE>mode)
7325 || gpc_reg_operand (operands[1], <MODE>mode))
7326 && TARGET_SOFT_FLOAT"
7327 "@
7328 mr %0,%1
7329 mt%0 %1
7330 mf%1 %0
7331 lwz%U1%X1 %0,%1
7332 stw%U0%X0 %1,%0
7333 li %0,%1
7334 lis %0,%v1
7335 #
7336 #
7337 nop"
7338 [(set_attr "type"
7339 "*, mtjmpr, mfjmpr, load, store, *,
7340 *, *, *, *")
7341
7342 (set_attr "length"
7343 "4, 4, 4, 4, 4, 4,
7344 4, 4, 8, 4")])
7345
7346 ;; Like movsf, but adjust a SI value to be used in a SF context, i.e.
7347 ;; (set (reg:SF ...) (subreg:SF (reg:SI ...) 0))
7348 ;;
7349 ;; Because SF values are actually stored as DF values within the vector
7350 ;; registers, we need to convert the value to the vector SF format when
7351 ;; we need to use the bits in a union or similar cases. We only need
7352 ;; to do this transformation when the value is a vector register. Loads,
7353 ;; stores, and transfers within GPRs are assumed to be safe.
7354 ;;
7355 ;; This is a more general case of reload_vsx_from_gprsf. That insn must have
7356 ;; no alternatives, because the call is created as part of secondary_reload,
7357 ;; and operand #2's register class is used to allocate the temporary register.
7358 ;; This function is called before reload, and it creates the temporary as
7359 ;; needed.
7360
7361 ;; LWZ LFS LXSSP LXSSPX STW STFIWX
7362 ;; STXSIWX GPR->VSX VSX->GPR GPR->GPR
7363 (define_insn_and_split "movsf_from_si"
7364 [(set (match_operand:SF 0 "nonimmediate_operand"
7365 "=!r, f, wb, wu, m, Z,
7366 Z, wy, ?r, !r")
7367
7368 (unspec:SF [(match_operand:SI 1 "input_operand"
7369 "m, m, wY, Z, r, f,
7370 wu, r, wy, r")]
7371 UNSPEC_SF_FROM_SI))
7372
7373 (clobber (match_scratch:DI 2
7374 "=X, X, X, X, X, X,
7375 X, r, X, X"))]
7376
7377 "TARGET_NO_SF_SUBREG
7378 && (register_operand (operands[0], SFmode)
7379 || register_operand (operands[1], SImode))"
7380 "@
7381 lwz%U1%X1 %0,%1
7382 lfs%U1%X1 %0,%1
7383 lxssp %0,%1
7384 lxsspx %x0,%y1
7385 stw%U0%X0 %1,%0
7386 stfiwx %1,%y0
7387 stxsiwx %x1,%y0
7388 #
7389 mfvsrwz %0,%x1
7390 mr %0,%1"
7391
7392 "&& reload_completed
7393 && vsx_reg_sfsubreg_ok (operands[0], SFmode)
7394 && int_reg_operand_not_pseudo (operands[1], SImode)"
7395 [(const_int 0)]
7396 {
7397 rtx op0 = operands[0];
7398 rtx op1 = operands[1];
7399 rtx op2 = operands[2];
7400 rtx op1_di = gen_rtx_REG (DImode, REGNO (op1));
7401
7402 /* Move SF value to upper 32-bits for xscvspdpn. */
7403 emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32)));
7404 emit_insn (gen_p8_mtvsrd_sf (op0, op2));
7405 emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0));
7406 DONE;
7407 }
7408 [(set_attr "length"
7409 "4, 4, 4, 4, 4, 4,
7410 4, 12, 4, 4")
7411 (set_attr "type"
7412 "load, fpload, fpload, fpload, store, fpstore,
7413 fpstore, vecfloat, mffgpr, *")])
7414
7415 \f
7416 ;; Move 64-bit binary/decimal floating point
7417 (define_expand "mov<mode>"
7418 [(set (match_operand:FMOVE64 0 "nonimmediate_operand")
7419 (match_operand:FMOVE64 1 "any_operand"))]
7420 ""
7421 {
7422 rs6000_emit_move (operands[0], operands[1], <MODE>mode);
7423 DONE;
7424 })
7425
7426 (define_split
7427 [(set (match_operand:FMOVE64 0 "gpc_reg_operand")
7428 (match_operand:FMOVE64 1 "const_int_operand"))]
7429 "! TARGET_POWERPC64 && reload_completed
7430 && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
7431 || (GET_CODE (operands[0]) == SUBREG
7432 && GET_CODE (SUBREG_REG (operands[0])) == REG
7433 && REGNO (SUBREG_REG (operands[0])) <= 31))"
7434 [(set (match_dup 2) (match_dup 4))
7435 (set (match_dup 3) (match_dup 1))]
7436 {
7437 int endian = (WORDS_BIG_ENDIAN == 0);
7438 HOST_WIDE_INT value = INTVAL (operands[1]);
7439
7440 operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
7441 operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
7442 operands[4] = GEN_INT (value >> 32);
7443 operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
7444 })
7445
7446 (define_split
7447 [(set (match_operand:FMOVE64 0 "gpc_reg_operand")
7448 (match_operand:FMOVE64 1 "const_double_operand"))]
7449 "! TARGET_POWERPC64 && reload_completed
7450 && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
7451 || (GET_CODE (operands[0]) == SUBREG
7452 && GET_CODE (SUBREG_REG (operands[0])) == REG
7453 && REGNO (SUBREG_REG (operands[0])) <= 31))"
7454 [(set (match_dup 2) (match_dup 4))
7455 (set (match_dup 3) (match_dup 5))]
7456 {
7457 int endian = (WORDS_BIG_ENDIAN == 0);
7458 long l[2];
7459
7460 <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7461
7462 operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
7463 operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
7464 operands[4] = gen_int_mode (l[endian], SImode);
7465 operands[5] = gen_int_mode (l[1 - endian], SImode);
7466 })
7467
7468 (define_split
7469 [(set (match_operand:FMOVE64 0 "gpc_reg_operand")
7470 (match_operand:FMOVE64 1 "const_double_operand"))]
7471 "TARGET_POWERPC64 && reload_completed
7472 && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
7473 || (GET_CODE (operands[0]) == SUBREG
7474 && GET_CODE (SUBREG_REG (operands[0])) == REG
7475 && REGNO (SUBREG_REG (operands[0])) <= 31))"
7476 [(set (match_dup 2) (match_dup 3))]
7477 {
7478 int endian = (WORDS_BIG_ENDIAN == 0);
7479 long l[2];
7480 HOST_WIDE_INT val;
7481
7482 <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7483
7484 operands[2] = gen_lowpart (DImode, operands[0]);
7485 /* HIGHPART is lower memory address when WORDS_BIG_ENDIAN. */
7486 val = ((HOST_WIDE_INT)(unsigned long)l[endian] << 32
7487 | ((HOST_WIDE_INT)(unsigned long)l[1 - endian]));
7488
7489 operands[3] = gen_int_mode (val, DImode);
7490 })
7491
7492 ;; Don't have reload use general registers to load a constant. It is
7493 ;; less efficient than loading the constant into an FP register, since
7494 ;; it will probably be used there.
7495
7496 ;; The move constraints are ordered to prefer floating point registers before
7497 ;; general purpose registers to avoid doing a store and a load to get the value
7498 ;; into a floating point register when it is needed for a floating point
7499 ;; operation. Prefer traditional floating point registers over VSX registers,
7500 ;; since the D-form version of the memory instructions does not need a GPR for
7501 ;; reloading. ISA 3.0 (power9) adds D-form addressing for scalars to Altivec
7502 ;; registers.
7503
7504 ;; If we have FPR registers, rs6000_emit_move has moved all constants to memory,
7505 ;; except for 0.0 which can be created on VSX with an xor instruction.
7506
7507 ;; STFD LFD FMR LXSD STXSD
7508 ;; LXSD STXSD XXLOR XXLXOR GPR<-0
7509 ;; LWZ STW MR
7510
7511
7512 (define_insn "*mov<mode>_hardfloat32"
7513 [(set (match_operand:FMOVE64 0 "nonimmediate_operand"
7514 "=m, d, d, <f64_p9>, wY,
7515 <f64_av>, Z, <f64_vsx>, <f64_vsx>, !r,
7516 Y, r, !r")
7517
7518 (match_operand:FMOVE64 1 "input_operand"
7519 "d, m, d, wY, <f64_p9>,
7520 Z, <f64_av>, <f64_vsx>, <zero_fp>, <zero_fp>,
7521 r, Y, r"))]
7522
7523 "! TARGET_POWERPC64 && TARGET_HARD_FLOAT
7524 && (gpc_reg_operand (operands[0], <MODE>mode)
7525 || gpc_reg_operand (operands[1], <MODE>mode))"
7526 "@
7527 stfd%U0%X0 %1,%0
7528 lfd%U1%X1 %0,%1
7529 fmr %0,%1
7530 lxsd %0,%1
7531 stxsd %1,%0
7532 lxsdx %x0,%y1
7533 stxsdx %x1,%y0
7534 xxlor %x0,%x1,%x1
7535 xxlxor %x0,%x0,%x0
7536 #
7537 #
7538 #
7539 #"
7540 [(set_attr "type"
7541 "fpstore, fpload, fpsimple, fpload, fpstore,
7542 fpload, fpstore, veclogical, veclogical, two,
7543 store, load, two")
7544
7545 (set_attr "size" "64")
7546 (set_attr "length"
7547 "4, 4, 4, 4, 4,
7548 4, 4, 4, 4, 8,
7549 8, 8, 8")])
7550
7551 ;; STW LWZ MR G-const H-const F-const
7552
7553 (define_insn "*mov<mode>_softfloat32"
7554 [(set (match_operand:FMOVE64 0 "nonimmediate_operand"
7555 "=Y, r, r, r, r, r")
7556
7557 (match_operand:FMOVE64 1 "input_operand"
7558 "r, Y, r, G, H, F"))]
7559
7560 "!TARGET_POWERPC64
7561 && (gpc_reg_operand (operands[0], <MODE>mode)
7562 || gpc_reg_operand (operands[1], <MODE>mode))"
7563 "#"
7564 [(set_attr "type"
7565 "store, load, two, *, *, *")
7566
7567 (set_attr "length"
7568 "8, 8, 8, 8, 12, 16")])
7569
7570 ; ld/std require word-aligned displacements -> 'Y' constraint.
7571 ; List Y->r and r->Y before r->r for reload.
7572
7573 ;; STFD LFD FMR LXSD STXSD
7574 ;; LXSDX STXSDX XXLOR XXLXOR LI 0
7575 ;; STD LD MR MT{CTR,LR} MF{CTR,LR}
7576 ;; NOP MFTGPR MFFGPR MFVSRD MTVSRD
7577
7578 (define_insn "*mov<mode>_hardfloat64"
7579 [(set (match_operand:FMOVE64 0 "nonimmediate_operand"
7580 "=m, d, d, <f64_p9>, wY,
7581 <f64_av>, Z, <f64_vsx>, <f64_vsx>, !r,
7582 YZ, r, !r, *c*l, !r,
7583 *h, r, wg, r, <f64_dm>")
7584
7585 (match_operand:FMOVE64 1 "input_operand"
7586 "d, m, d, wY, <f64_p9>,
7587 Z, <f64_av>, <f64_vsx>, <zero_fp>, <zero_fp>,
7588 r, YZ, r, r, *h,
7589 0, wg, r, <f64_dm>, r"))]
7590
7591 "TARGET_POWERPC64 && TARGET_HARD_FLOAT
7592 && (gpc_reg_operand (operands[0], <MODE>mode)
7593 || gpc_reg_operand (operands[1], <MODE>mode))"
7594 "@
7595 stfd%U0%X0 %1,%0
7596 lfd%U1%X1 %0,%1
7597 fmr %0,%1
7598 lxsd %0,%1
7599 stxsd %1,%0
7600 lxsdx %x0,%y1
7601 stxsdx %x1,%y0
7602 xxlor %x0,%x1,%x1
7603 xxlxor %x0,%x0,%x0
7604 li %0,0
7605 std%U0%X0 %1,%0
7606 ld%U1%X1 %0,%1
7607 mr %0,%1
7608 mt%0 %1
7609 mf%1 %0
7610 nop
7611 mftgpr %0,%1
7612 mffgpr %0,%1
7613 mfvsrd %0,%x1
7614 mtvsrd %x0,%1"
7615 [(set_attr "type"
7616 "fpstore, fpload, fpsimple, fpload, fpstore,
7617 fpload, fpstore, veclogical, veclogical, integer,
7618 store, load, *, mtjmpr, mfjmpr,
7619 *, mftgpr, mffgpr, mftgpr, mffgpr")
7620
7621 (set_attr "size" "64")
7622 (set_attr "length" "4")])
7623
7624 ;; STD LD MR MT<SPR> MF<SPR> G-const
7625 ;; H-const F-const Special
7626
7627 (define_insn "*mov<mode>_softfloat64"
7628 [(set (match_operand:FMOVE64 0 "nonimmediate_operand"
7629 "=Y, r, r, *c*l, r, r,
7630 r, r, *h")
7631
7632 (match_operand:FMOVE64 1 "input_operand"
7633 "r, Y, r, r, *h, G,
7634 H, F, 0"))]
7635
7636 "TARGET_POWERPC64 && TARGET_SOFT_FLOAT
7637 && (gpc_reg_operand (operands[0], <MODE>mode)
7638 || gpc_reg_operand (operands[1], <MODE>mode))"
7639 "@
7640 std%U0%X0 %1,%0
7641 ld%U1%X1 %0,%1
7642 mr %0,%1
7643 mt%0 %1
7644 mf%1 %0
7645 #
7646 #
7647 #
7648 nop"
7649 [(set_attr "type"
7650 "store, load, *, mtjmpr, mfjmpr, *,
7651 *, *, *")
7652
7653 (set_attr "length"
7654 "4, 4, 4, 4, 4, 8,
7655 12, 16, 4")])
7656 \f
7657 (define_expand "mov<mode>"
7658 [(set (match_operand:FMOVE128 0 "general_operand")
7659 (match_operand:FMOVE128 1 "any_operand"))]
7660 ""
7661 {
7662 rs6000_emit_move (operands[0], operands[1], <MODE>mode);
7663 DONE;
7664 })
7665
7666 ;; It's important to list Y->r and r->Y before r->r because otherwise
7667 ;; reload, given m->r, will try to pick r->r and reload it, which
7668 ;; doesn't make progress.
7669
7670 ;; We can't split little endian direct moves of TDmode, because the words are
7671 ;; not swapped like they are for TImode or TFmode. Subregs therefore are
7672 ;; problematical. Don't allow direct move for this case.
7673
7674 (define_insn_and_split "*mov<mode>_64bit_dm"
7675 [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand" "=m,d,d,d,Y,r,r,r,wh")
7676 (match_operand:FMOVE128_FPR 1 "input_operand" "d,m,d,<zero_fp>,r,<zero_fp>Y,r,wh,r"))]
7677 "TARGET_HARD_FLOAT && TARGET_POWERPC64 && FLOAT128_2REG_P (<MODE>mode)
7678 && (<MODE>mode != TDmode || WORDS_BIG_ENDIAN)
7679 && (gpc_reg_operand (operands[0], <MODE>mode)
7680 || gpc_reg_operand (operands[1], <MODE>mode))"
7681 "#"
7682 "&& reload_completed"
7683 [(pc)]
7684 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7685 [(set_attr "length" "8,8,8,8,12,12,8,8,8")])
7686
7687 (define_insn_and_split "*movtd_64bit_nodm"
7688 [(set (match_operand:TD 0 "nonimmediate_operand" "=m,d,d,Y,r,r")
7689 (match_operand:TD 1 "input_operand" "d,m,d,r,Y,r"))]
7690 "TARGET_HARD_FLOAT && TARGET_POWERPC64 && !WORDS_BIG_ENDIAN
7691 && (gpc_reg_operand (operands[0], TDmode)
7692 || gpc_reg_operand (operands[1], TDmode))"
7693 "#"
7694 "&& reload_completed"
7695 [(pc)]
7696 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7697 [(set_attr "length" "8,8,8,12,12,8")])
7698
7699 (define_insn_and_split "*mov<mode>_32bit"
7700 [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand" "=m,d,d,d,Y,r,r")
7701 (match_operand:FMOVE128_FPR 1 "input_operand" "d,m,d,<zero_fp>,r,<zero_fp>Y,r"))]
7702 "TARGET_HARD_FLOAT && !TARGET_POWERPC64
7703 && (FLOAT128_2REG_P (<MODE>mode)
7704 || int_reg_operand_not_pseudo (operands[0], <MODE>mode)
7705 || int_reg_operand_not_pseudo (operands[1], <MODE>mode))
7706 && (gpc_reg_operand (operands[0], <MODE>mode)
7707 || gpc_reg_operand (operands[1], <MODE>mode))"
7708 "#"
7709 "&& reload_completed"
7710 [(pc)]
7711 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7712 [(set_attr "length" "8,8,8,8,20,20,16")])
7713
7714 (define_insn_and_split "*mov<mode>_softfloat"
7715 [(set (match_operand:FMOVE128 0 "nonimmediate_operand" "=Y,r,r,r")
7716 (match_operand:FMOVE128 1 "input_operand" "r,Y,F,r"))]
7717 "TARGET_SOFT_FLOAT
7718 && (gpc_reg_operand (operands[0], <MODE>mode)
7719 || gpc_reg_operand (operands[1], <MODE>mode))"
7720 "#"
7721 "&& reload_completed"
7722 [(pc)]
7723 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7724 [(set_attr_alternative "length"
7725 [(if_then_else (match_test "TARGET_POWERPC64")
7726 (const_string "8")
7727 (const_string "16"))
7728 (if_then_else (match_test "TARGET_POWERPC64")
7729 (const_string "8")
7730 (const_string "16"))
7731 (if_then_else (match_test "TARGET_POWERPC64")
7732 (const_string "16")
7733 (const_string "32"))
7734 (if_then_else (match_test "TARGET_POWERPC64")
7735 (const_string "8")
7736 (const_string "16"))])])
7737
7738 (define_expand "extenddf<mode>2"
7739 [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
7740 (float_extend:FLOAT128 (match_operand:DF 1 "gpc_reg_operand")))]
7741 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7742 {
7743 if (FLOAT128_IEEE_P (<MODE>mode))
7744 rs6000_expand_float128_convert (operands[0], operands[1], false);
7745 else if (TARGET_VSX)
7746 {
7747 if (<MODE>mode == TFmode)
7748 emit_insn (gen_extenddftf2_vsx (operands[0], operands[1]));
7749 else if (<MODE>mode == IFmode)
7750 emit_insn (gen_extenddfif2_vsx (operands[0], operands[1]));
7751 else
7752 gcc_unreachable ();
7753 }
7754 else
7755 {
7756 rtx zero = gen_reg_rtx (DFmode);
7757 rs6000_emit_move (zero, CONST0_RTX (DFmode), DFmode);
7758
7759 if (<MODE>mode == TFmode)
7760 emit_insn (gen_extenddftf2_fprs (operands[0], operands[1], zero));
7761 else if (<MODE>mode == IFmode)
7762 emit_insn (gen_extenddfif2_fprs (operands[0], operands[1], zero));
7763 else
7764 gcc_unreachable ();
7765 }
7766 DONE;
7767 })
7768
7769 ;; Allow memory operands for the source to be created by the combiner.
7770 (define_insn_and_split "extenddf<mode>2_fprs"
7771 [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d,&d")
7772 (float_extend:IBM128
7773 (match_operand:DF 1 "nonimmediate_operand" "d,m,d")))
7774 (use (match_operand:DF 2 "nonimmediate_operand" "m,m,d"))]
7775 "!TARGET_VSX && TARGET_HARD_FLOAT
7776 && TARGET_LONG_DOUBLE_128 && FLOAT128_IBM_P (<MODE>mode)"
7777 "#"
7778 "&& reload_completed"
7779 [(set (match_dup 3) (match_dup 1))
7780 (set (match_dup 4) (match_dup 2))]
7781 {
7782 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7783 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7784
7785 operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
7786 operands[4] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
7787 })
7788
7789 (define_insn_and_split "extenddf<mode>2_vsx"
7790 [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d")
7791 (float_extend:IBM128
7792 (match_operand:DF 1 "nonimmediate_operand" "ws,m")))]
7793 "TARGET_LONG_DOUBLE_128 && TARGET_VSX && FLOAT128_IBM_P (<MODE>mode)"
7794 "#"
7795 "&& reload_completed"
7796 [(set (match_dup 2) (match_dup 1))
7797 (set (match_dup 3) (match_dup 4))]
7798 {
7799 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7800 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7801
7802 operands[2] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
7803 operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
7804 operands[4] = CONST0_RTX (DFmode);
7805 })
7806
7807 (define_expand "extendsf<mode>2"
7808 [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
7809 (float_extend:FLOAT128 (match_operand:SF 1 "gpc_reg_operand")))]
7810 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7811 {
7812 if (FLOAT128_IEEE_P (<MODE>mode))
7813 rs6000_expand_float128_convert (operands[0], operands[1], false);
7814 else
7815 {
7816 rtx tmp = gen_reg_rtx (DFmode);
7817 emit_insn (gen_extendsfdf2 (tmp, operands[1]));
7818 emit_insn (gen_extenddf<mode>2 (operands[0], tmp));
7819 }
7820 DONE;
7821 })
7822
7823 (define_expand "trunc<mode>df2"
7824 [(set (match_operand:DF 0 "gpc_reg_operand")
7825 (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand")))]
7826 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7827 {
7828 if (FLOAT128_IEEE_P (<MODE>mode))
7829 {
7830 rs6000_expand_float128_convert (operands[0], operands[1], false);
7831 DONE;
7832 }
7833 })
7834
7835 (define_insn_and_split "trunc<mode>df2_internal1"
7836 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d")
7837 (float_truncate:DF
7838 (match_operand:IBM128 1 "gpc_reg_operand" "0,d")))]
7839 "FLOAT128_IBM_P (<MODE>mode) && !TARGET_XL_COMPAT
7840 && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7841 "@
7842 #
7843 fmr %0,%1"
7844 "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
7845 [(const_int 0)]
7846 {
7847 emit_note (NOTE_INSN_DELETED);
7848 DONE;
7849 }
7850 [(set_attr "type" "fpsimple")])
7851
7852 (define_insn "trunc<mode>df2_internal2"
7853 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
7854 (float_truncate:DF (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
7855 "FLOAT128_IBM_P (<MODE>mode) && TARGET_XL_COMPAT && TARGET_HARD_FLOAT
7856 && TARGET_LONG_DOUBLE_128"
7857 "fadd %0,%1,%L1"
7858 [(set_attr "type" "fp")])
7859
7860 (define_expand "trunc<mode>sf2"
7861 [(set (match_operand:SF 0 "gpc_reg_operand")
7862 (float_truncate:SF (match_operand:FLOAT128 1 "gpc_reg_operand")))]
7863 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7864 {
7865 if (FLOAT128_IEEE_P (<MODE>mode))
7866 rs6000_expand_float128_convert (operands[0], operands[1], false);
7867 else
7868 {
7869 rtx tmp = gen_reg_rtx (DFmode);
7870 emit_insn (gen_trunc<mode>df2 (tmp, operands[1]));
7871 emit_insn (gen_truncdfsf2 (operands[0], tmp));
7872 }
7873 DONE;
7874 })
7875
7876 (define_expand "floatsi<mode>2"
7877 [(parallel [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
7878 (float:FLOAT128 (match_operand:SI 1 "gpc_reg_operand")))
7879 (clobber (match_scratch:DI 2))])]
7880 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7881 {
7882 rtx op0 = operands[0];
7883 rtx op1 = operands[1];
7884
7885 if (TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode))
7886 ;
7887 else if (FLOAT128_IEEE_P (<MODE>mode))
7888 {
7889 rs6000_expand_float128_convert (op0, op1, false);
7890 DONE;
7891 }
7892 else
7893 {
7894 rtx tmp = gen_reg_rtx (DFmode);
7895 expand_float (tmp, op1, false);
7896 if (<MODE>mode == TFmode)
7897 emit_insn (gen_extenddftf2 (op0, tmp));
7898 else if (<MODE>mode == IFmode)
7899 emit_insn (gen_extenddfif2 (op0, tmp));
7900 else
7901 gcc_unreachable ();
7902 DONE;
7903 }
7904 })
7905
7906 ; fadd, but rounding towards zero.
7907 ; This is probably not the optimal code sequence.
7908 (define_insn "fix_trunc_helper<mode>"
7909 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
7910 (unspec:DF [(match_operand:IBM128 1 "gpc_reg_operand" "d")]
7911 UNSPEC_FIX_TRUNC_TF))
7912 (clobber (match_operand:DF 2 "gpc_reg_operand" "=&d"))]
7913 "TARGET_HARD_FLOAT && FLOAT128_IBM_P (<MODE>mode)"
7914 "mffs %2\n\tmtfsb1 31\n\tmtfsb0 30\n\tfadd %0,%1,%L1\n\tmtfsf 1,%2"
7915 [(set_attr "type" "fp")
7916 (set_attr "length" "20")])
7917
7918 (define_expand "fix_trunc<mode>si2"
7919 [(set (match_operand:SI 0 "gpc_reg_operand")
7920 (fix:SI (match_operand:FLOAT128 1 "gpc_reg_operand")))]
7921 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7922 {
7923 rtx op0 = operands[0];
7924 rtx op1 = operands[1];
7925
7926 if (TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode))
7927 ;
7928 else
7929 {
7930 if (FLOAT128_IEEE_P (<MODE>mode))
7931 rs6000_expand_float128_convert (op0, op1, false);
7932 else if (<MODE>mode == TFmode)
7933 emit_insn (gen_fix_trunctfsi2_fprs (op0, op1));
7934 else if (<MODE>mode == IFmode)
7935 emit_insn (gen_fix_truncifsi2_fprs (op0, op1));
7936 else
7937 gcc_unreachable ();
7938 DONE;
7939 }
7940 })
7941
7942 (define_expand "fix_trunc<mode>si2_fprs"
7943 [(parallel [(set (match_operand:SI 0 "gpc_reg_operand")
7944 (fix:SI (match_operand:IBM128 1 "gpc_reg_operand")))
7945 (clobber (match_dup 2))
7946 (clobber (match_dup 3))
7947 (clobber (match_dup 4))
7948 (clobber (match_dup 5))])]
7949 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7950 {
7951 operands[2] = gen_reg_rtx (DFmode);
7952 operands[3] = gen_reg_rtx (DFmode);
7953 operands[4] = gen_reg_rtx (DImode);
7954 operands[5] = assign_stack_temp (DImode, GET_MODE_SIZE (DImode));
7955 })
7956
7957 (define_insn_and_split "*fix_trunc<mode>si2_internal"
7958 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
7959 (fix:SI (match_operand:IBM128 1 "gpc_reg_operand" "d")))
7960 (clobber (match_operand:DF 2 "gpc_reg_operand" "=d"))
7961 (clobber (match_operand:DF 3 "gpc_reg_operand" "=&d"))
7962 (clobber (match_operand:DI 4 "gpc_reg_operand" "=d"))
7963 (clobber (match_operand:DI 5 "offsettable_mem_operand" "=o"))]
7964 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7965 "#"
7966 ""
7967 [(pc)]
7968 {
7969 rtx lowword;
7970 emit_insn (gen_fix_trunc_helper<mode> (operands[2], operands[1],
7971 operands[3]));
7972
7973 gcc_assert (MEM_P (operands[5]));
7974 lowword = adjust_address (operands[5], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
7975
7976 emit_insn (gen_fctiwz_df (operands[4], operands[2]));
7977 emit_move_insn (operands[5], operands[4]);
7978 emit_move_insn (operands[0], lowword);
7979 DONE;
7980 })
7981
7982 (define_expand "fix_trunc<mode>di2"
7983 [(set (match_operand:DI 0 "gpc_reg_operand")
7984 (fix:DI (match_operand:IEEE128 1 "gpc_reg_operand")))]
7985 "TARGET_FLOAT128_TYPE"
7986 {
7987 if (!TARGET_FLOAT128_HW)
7988 {
7989 rs6000_expand_float128_convert (operands[0], operands[1], false);
7990 DONE;
7991 }
7992 })
7993
7994 (define_expand "fixuns_trunc<IEEE128:mode><SDI:mode>2"
7995 [(set (match_operand:SDI 0 "gpc_reg_operand")
7996 (unsigned_fix:SDI (match_operand:IEEE128 1 "gpc_reg_operand")))]
7997 "TARGET_FLOAT128_TYPE"
7998 {
7999 rs6000_expand_float128_convert (operands[0], operands[1], true);
8000 DONE;
8001 })
8002
8003 (define_expand "floatdi<mode>2"
8004 [(set (match_operand:IEEE128 0 "gpc_reg_operand")
8005 (float:IEEE128 (match_operand:DI 1 "gpc_reg_operand")))]
8006 "TARGET_FLOAT128_TYPE"
8007 {
8008 if (!TARGET_FLOAT128_HW)
8009 {
8010 rs6000_expand_float128_convert (operands[0], operands[1], false);
8011 DONE;
8012 }
8013 })
8014
8015 (define_expand "floatunsdi<IEEE128:mode>2"
8016 [(set (match_operand:IEEE128 0 "gpc_reg_operand")
8017 (unsigned_float:IEEE128 (match_operand:DI 1 "gpc_reg_operand")))]
8018 "TARGET_FLOAT128_TYPE"
8019 {
8020 if (!TARGET_FLOAT128_HW)
8021 {
8022 rs6000_expand_float128_convert (operands[0], operands[1], true);
8023 DONE;
8024 }
8025 })
8026
8027 (define_expand "floatuns<IEEE128:mode>2"
8028 [(set (match_operand:IEEE128 0 "gpc_reg_operand")
8029 (unsigned_float:IEEE128 (match_operand:SI 1 "gpc_reg_operand")))]
8030 "TARGET_FLOAT128_TYPE"
8031 {
8032 rtx op0 = operands[0];
8033 rtx op1 = operands[1];
8034
8035 if (TARGET_FLOAT128_HW)
8036 emit_insn (gen_floatuns_<IEEE128:mode>si2_hw (op0, op1));
8037 else
8038 rs6000_expand_float128_convert (op0, op1, true);
8039 DONE;
8040 })
8041
8042 (define_expand "neg<mode>2"
8043 [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
8044 (neg:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand")))]
8045 "FLOAT128_IEEE_P (<MODE>mode)
8046 || (FLOAT128_IBM_P (<MODE>mode) && TARGET_HARD_FLOAT)"
8047 {
8048 if (FLOAT128_IEEE_P (<MODE>mode))
8049 {
8050 if (TARGET_FLOAT128_HW)
8051 {
8052 if (<MODE>mode == TFmode)
8053 emit_insn (gen_negtf2_hw (operands[0], operands[1]));
8054 else if (<MODE>mode == KFmode)
8055 emit_insn (gen_negkf2_hw (operands[0], operands[1]));
8056 else
8057 gcc_unreachable ();
8058 }
8059 else if (TARGET_FLOAT128_TYPE)
8060 {
8061 if (<MODE>mode == TFmode)
8062 emit_insn (gen_ieee_128bit_vsx_negtf2 (operands[0], operands[1]));
8063 else if (<MODE>mode == KFmode)
8064 emit_insn (gen_ieee_128bit_vsx_negkf2 (operands[0], operands[1]));
8065 else
8066 gcc_unreachable ();
8067 }
8068 else
8069 {
8070 rtx libfunc = optab_libfunc (neg_optab, <MODE>mode);
8071 rtx target = emit_library_call_value (libfunc, operands[0], LCT_CONST,
8072 <MODE>mode,
8073 operands[1], <MODE>mode);
8074
8075 if (target && !rtx_equal_p (target, operands[0]))
8076 emit_move_insn (operands[0], target);
8077 }
8078 DONE;
8079 }
8080 })
8081
8082 (define_insn "neg<mode>2_internal"
8083 [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d")
8084 (neg:IBM128 (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
8085 "TARGET_HARD_FLOAT && FLOAT128_IBM_P (<MODE>mode)"
8086 {
8087 if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
8088 return "fneg %L0,%L1\;fneg %0,%1";
8089 else
8090 return "fneg %0,%1\;fneg %L0,%L1";
8091 }
8092 [(set_attr "type" "fpsimple")
8093 (set_attr "length" "8")])
8094
8095 (define_expand "abs<mode>2"
8096 [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
8097 (abs:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand")))]
8098 "FLOAT128_IEEE_P (<MODE>mode)
8099 || (FLOAT128_IBM_P (<MODE>mode) && TARGET_HARD_FLOAT)"
8100 {
8101 rtx label;
8102
8103 if (FLOAT128_IEEE_P (<MODE>mode))
8104 {
8105 if (TARGET_FLOAT128_HW)
8106 {
8107 if (<MODE>mode == TFmode)
8108 emit_insn (gen_abstf2_hw (operands[0], operands[1]));
8109 else if (<MODE>mode == KFmode)
8110 emit_insn (gen_abskf2_hw (operands[0], operands[1]));
8111 else
8112 FAIL;
8113 DONE;
8114 }
8115 else if (TARGET_FLOAT128_TYPE)
8116 {
8117 if (<MODE>mode == TFmode)
8118 emit_insn (gen_ieee_128bit_vsx_abstf2 (operands[0], operands[1]));
8119 else if (<MODE>mode == KFmode)
8120 emit_insn (gen_ieee_128bit_vsx_abskf2 (operands[0], operands[1]));
8121 else
8122 FAIL;
8123 DONE;
8124 }
8125 else
8126 FAIL;
8127 }
8128
8129 label = gen_label_rtx ();
8130 if (<MODE>mode == TFmode)
8131 emit_insn (gen_abstf2_internal (operands[0], operands[1], label));
8132 else if (<MODE>mode == IFmode)
8133 emit_insn (gen_absif2_internal (operands[0], operands[1], label));
8134 else
8135 FAIL;
8136 emit_label (label);
8137 DONE;
8138 })
8139
8140 (define_expand "abs<mode>2_internal"
8141 [(set (match_operand:IBM128 0 "gpc_reg_operand")
8142 (match_operand:IBM128 1 "gpc_reg_operand"))
8143 (set (match_dup 3) (match_dup 5))
8144 (set (match_dup 5) (abs:DF (match_dup 5)))
8145 (set (match_dup 4) (compare:CCFP (match_dup 3) (match_dup 5)))
8146 (set (pc) (if_then_else (eq (match_dup 4) (const_int 0))
8147 (label_ref (match_operand 2 ""))
8148 (pc)))
8149 (set (match_dup 6) (neg:DF (match_dup 6)))]
8150 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8151 {
8152 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
8153 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
8154 operands[3] = gen_reg_rtx (DFmode);
8155 operands[4] = gen_reg_rtx (CCFPmode);
8156 operands[5] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
8157 operands[6] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
8158 })
8159
8160 \f
8161 ;; Generate IEEE 128-bit -0.0 (0x80000000000000000000000000000000) in a vector
8162 ;; register
8163
8164 (define_expand "ieee_128bit_negative_zero"
8165 [(set (match_operand:V16QI 0 "register_operand") (match_dup 1))]
8166 "TARGET_FLOAT128_TYPE"
8167 {
8168 rtvec v = rtvec_alloc (16);
8169 int i, high;
8170
8171 for (i = 0; i < 16; i++)
8172 RTVEC_ELT (v, i) = const0_rtx;
8173
8174 high = (BYTES_BIG_ENDIAN) ? 0 : 15;
8175 RTVEC_ELT (v, high) = gen_int_mode (0x80, QImode);
8176
8177 rs6000_expand_vector_init (operands[0], gen_rtx_PARALLEL (V16QImode, v));
8178 DONE;
8179 })
8180
8181 ;; IEEE 128-bit negate
8182
8183 ;; We have 2 insns here for negate and absolute value. The first uses
8184 ;; match_scratch so that phases like combine can recognize neg/abs as generic
8185 ;; insns, and second insn after the first split pass loads up the bit to
8186 ;; twiddle the sign bit. Later GCSE passes can then combine multiple uses of
8187 ;; neg/abs to create the constant just once.
8188
8189 (define_insn_and_split "ieee_128bit_vsx_neg<mode>2"
8190 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8191 (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8192 (clobber (match_scratch:V16QI 2 "=v"))]
8193 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8194 "#"
8195 "&& 1"
8196 [(parallel [(set (match_dup 0)
8197 (neg:IEEE128 (match_dup 1)))
8198 (use (match_dup 2))])]
8199 {
8200 if (GET_CODE (operands[2]) == SCRATCH)
8201 operands[2] = gen_reg_rtx (V16QImode);
8202
8203 operands[3] = gen_reg_rtx (V16QImode);
8204 emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8205 }
8206 [(set_attr "length" "8")
8207 (set_attr "type" "vecsimple")])
8208
8209 (define_insn "*ieee_128bit_vsx_neg<mode>2_internal"
8210 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8211 (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8212 (use (match_operand:V16QI 2 "register_operand" "v"))]
8213 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8214 "xxlxor %x0,%x1,%x2"
8215 [(set_attr "type" "veclogical")])
8216
8217 ;; IEEE 128-bit absolute value
8218 (define_insn_and_split "ieee_128bit_vsx_abs<mode>2"
8219 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8220 (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8221 (clobber (match_scratch:V16QI 2 "=v"))]
8222 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
8223 "#"
8224 "&& 1"
8225 [(parallel [(set (match_dup 0)
8226 (abs:IEEE128 (match_dup 1)))
8227 (use (match_dup 2))])]
8228 {
8229 if (GET_CODE (operands[2]) == SCRATCH)
8230 operands[2] = gen_reg_rtx (V16QImode);
8231
8232 operands[3] = gen_reg_rtx (V16QImode);
8233 emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8234 }
8235 [(set_attr "length" "8")
8236 (set_attr "type" "vecsimple")])
8237
8238 (define_insn "*ieee_128bit_vsx_abs<mode>2_internal"
8239 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8240 (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8241 (use (match_operand:V16QI 2 "register_operand" "v"))]
8242 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8243 "xxlandc %x0,%x1,%x2"
8244 [(set_attr "type" "veclogical")])
8245
8246 ;; IEEE 128-bit negative absolute value
8247 (define_insn_and_split "*ieee_128bit_vsx_nabs<mode>2"
8248 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8249 (neg:IEEE128
8250 (abs:IEEE128
8251 (match_operand:IEEE128 1 "register_operand" "wa"))))
8252 (clobber (match_scratch:V16QI 2 "=v"))]
8253 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW
8254 && FLOAT128_IEEE_P (<MODE>mode)"
8255 "#"
8256 "&& 1"
8257 [(parallel [(set (match_dup 0)
8258 (neg:IEEE128 (abs:IEEE128 (match_dup 1))))
8259 (use (match_dup 2))])]
8260 {
8261 if (GET_CODE (operands[2]) == SCRATCH)
8262 operands[2] = gen_reg_rtx (V16QImode);
8263
8264 operands[3] = gen_reg_rtx (V16QImode);
8265 emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8266 }
8267 [(set_attr "length" "8")
8268 (set_attr "type" "vecsimple")])
8269
8270 (define_insn "*ieee_128bit_vsx_nabs<mode>2_internal"
8271 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8272 (neg:IEEE128
8273 (abs:IEEE128
8274 (match_operand:IEEE128 1 "register_operand" "wa"))))
8275 (use (match_operand:V16QI 2 "register_operand" "v"))]
8276 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8277 "xxlor %x0,%x1,%x2"
8278 [(set_attr "type" "veclogical")])
8279
8280 ;; Float128 conversion functions. These expand to library function calls.
8281 ;; We use expand to convert from IBM double double to IEEE 128-bit
8282 ;; and trunc for the opposite.
8283 (define_expand "extendiftf2"
8284 [(set (match_operand:TF 0 "gpc_reg_operand")
8285 (float_extend:TF (match_operand:IF 1 "gpc_reg_operand")))]
8286 "TARGET_FLOAT128_TYPE"
8287 {
8288 rs6000_expand_float128_convert (operands[0], operands[1], false);
8289 DONE;
8290 })
8291
8292 (define_expand "extendifkf2"
8293 [(set (match_operand:KF 0 "gpc_reg_operand")
8294 (float_extend:KF (match_operand:IF 1 "gpc_reg_operand")))]
8295 "TARGET_FLOAT128_TYPE"
8296 {
8297 rs6000_expand_float128_convert (operands[0], operands[1], false);
8298 DONE;
8299 })
8300
8301 (define_expand "extendtfkf2"
8302 [(set (match_operand:KF 0 "gpc_reg_operand")
8303 (float_extend:KF (match_operand:TF 1 "gpc_reg_operand")))]
8304 "TARGET_FLOAT128_TYPE"
8305 {
8306 rs6000_expand_float128_convert (operands[0], operands[1], false);
8307 DONE;
8308 })
8309
8310 (define_expand "extendtfif2"
8311 [(set (match_operand:IF 0 "gpc_reg_operand")
8312 (float_extend:IF (match_operand:TF 1 "gpc_reg_operand")))]
8313 "TARGET_FLOAT128_TYPE"
8314 {
8315 rs6000_expand_float128_convert (operands[0], operands[1], false);
8316 DONE;
8317 })
8318
8319 (define_expand "trunciftf2"
8320 [(set (match_operand:TF 0 "gpc_reg_operand")
8321 (float_truncate:TF (match_operand:IF 1 "gpc_reg_operand")))]
8322 "TARGET_FLOAT128_TYPE"
8323 {
8324 rs6000_expand_float128_convert (operands[0], operands[1], false);
8325 DONE;
8326 })
8327
8328 (define_expand "truncifkf2"
8329 [(set (match_operand:KF 0 "gpc_reg_operand")
8330 (float_truncate:KF (match_operand:IF 1 "gpc_reg_operand")))]
8331 "TARGET_FLOAT128_TYPE"
8332 {
8333 rs6000_expand_float128_convert (operands[0], operands[1], false);
8334 DONE;
8335 })
8336
8337 (define_expand "trunckftf2"
8338 [(set (match_operand:TF 0 "gpc_reg_operand")
8339 (float_truncate:TF (match_operand:KF 1 "gpc_reg_operand")))]
8340 "TARGET_FLOAT128_TYPE"
8341 {
8342 rs6000_expand_float128_convert (operands[0], operands[1], false);
8343 DONE;
8344 })
8345
8346 (define_expand "trunctfif2"
8347 [(set (match_operand:IF 0 "gpc_reg_operand")
8348 (float_truncate:IF (match_operand:TF 1 "gpc_reg_operand")))]
8349 "TARGET_FLOAT128_TYPE"
8350 {
8351 rs6000_expand_float128_convert (operands[0], operands[1], false);
8352 DONE;
8353 })
8354
8355 (define_insn_and_split "*extend<mode>tf2_internal"
8356 [(set (match_operand:TF 0 "gpc_reg_operand" "=<IFKF_reg>")
8357 (float_extend:TF
8358 (match_operand:IFKF 1 "gpc_reg_operand" "<IFKF_reg>")))]
8359 "TARGET_FLOAT128_TYPE
8360 && FLOAT128_IBM_P (TFmode) == FLOAT128_IBM_P (<MODE>mode)"
8361 "#"
8362 "&& reload_completed"
8363 [(set (match_dup 0) (match_dup 2))]
8364 {
8365 operands[2] = gen_rtx_REG (TFmode, REGNO (operands[1]));
8366 })
8367
8368 (define_insn_and_split "*extendtf<mode>2_internal"
8369 [(set (match_operand:IFKF 0 "gpc_reg_operand" "=<IFKF_reg>")
8370 (float_extend:IFKF
8371 (match_operand:TF 1 "gpc_reg_operand" "<IFKF_reg>")))]
8372 "TARGET_FLOAT128_TYPE
8373 && FLOAT128_IBM_P (TFmode) == FLOAT128_IBM_P (<MODE>mode)"
8374 "#"
8375 "&& reload_completed"
8376 [(set (match_dup 0) (match_dup 2))]
8377 {
8378 operands[2] = gen_rtx_REG (<MODE>mode, REGNO (operands[1]));
8379 })
8380
8381 \f
8382 ;; Reload helper functions used by rs6000_secondary_reload. The patterns all
8383 ;; must have 3 arguments, and scratch register constraint must be a single
8384 ;; constraint.
8385
8386 ;; Reload patterns to support gpr load/store with misaligned mem.
8387 ;; and multiple gpr load/store at offset >= 0xfffc
8388 (define_expand "reload_<mode>_store"
8389 [(parallel [(match_operand 0 "memory_operand" "=m")
8390 (match_operand 1 "gpc_reg_operand" "r")
8391 (match_operand:GPR 2 "register_operand" "=&b")])]
8392 ""
8393 {
8394 rs6000_secondary_reload_gpr (operands[1], operands[0], operands[2], true);
8395 DONE;
8396 })
8397
8398 (define_expand "reload_<mode>_load"
8399 [(parallel [(match_operand 0 "gpc_reg_operand" "=r")
8400 (match_operand 1 "memory_operand" "m")
8401 (match_operand:GPR 2 "register_operand" "=b")])]
8402 ""
8403 {
8404 rs6000_secondary_reload_gpr (operands[0], operands[1], operands[2], false);
8405 DONE;
8406 })
8407
8408 \f
8409 ;; Reload patterns for various types using the vector registers. We may need
8410 ;; an additional base register to convert the reg+offset addressing to reg+reg
8411 ;; for vector registers and reg+reg or (reg+reg)&(-16) addressing to just an
8412 ;; index register for gpr registers.
8413 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_store"
8414 [(parallel [(match_operand:RELOAD 0 "memory_operand" "m")
8415 (match_operand:RELOAD 1 "gpc_reg_operand" "wa")
8416 (match_operand:P 2 "register_operand" "=b")])]
8417 "<P:tptrsize>"
8418 {
8419 rs6000_secondary_reload_inner (operands[1], operands[0], operands[2], true);
8420 DONE;
8421 })
8422
8423 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_load"
8424 [(parallel [(match_operand:RELOAD 0 "gpc_reg_operand" "wa")
8425 (match_operand:RELOAD 1 "memory_operand" "m")
8426 (match_operand:P 2 "register_operand" "=b")])]
8427 "<P:tptrsize>"
8428 {
8429 rs6000_secondary_reload_inner (operands[0], operands[1], operands[2], false);
8430 DONE;
8431 })
8432
8433
8434 ;; Reload sometimes tries to move the address to a GPR, and can generate
8435 ;; invalid RTL for addresses involving AND -16. Allow addresses involving
8436 ;; reg+reg, reg+small constant, or just reg, all wrapped in an AND -16.
8437
8438 (define_insn_and_split "*vec_reload_and_plus_<mptrsize>"
8439 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
8440 (and:P (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
8441 (match_operand:P 2 "reg_or_cint_operand" "rI"))
8442 (const_int -16)))]
8443 "TARGET_ALTIVEC && reload_completed"
8444 "#"
8445 "&& reload_completed"
8446 [(set (match_dup 0)
8447 (plus:P (match_dup 1)
8448 (match_dup 2)))
8449 (set (match_dup 0)
8450 (and:P (match_dup 0)
8451 (const_int -16)))])
8452 \f
8453 ;; Power8 merge instructions to allow direct move to/from floating point
8454 ;; registers in 32-bit mode. We use TF mode to get two registers to move the
8455 ;; individual 32-bit parts across. Subreg doesn't work too well on the TF
8456 ;; value, since it is allocated in reload and not all of the flow information
8457 ;; is setup for it. We have two patterns to do the two moves between gprs and
8458 ;; fprs. There isn't a dependancy between the two, but we could potentially
8459 ;; schedule other instructions between the two instructions.
8460
8461 (define_insn "p8_fmrgow_<mode>"
8462 [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
8463 (unspec:FMOVE64X [
8464 (match_operand:DF 1 "register_operand" "d")
8465 (match_operand:DF 2 "register_operand" "d")]
8466 UNSPEC_P8V_FMRGOW))]
8467 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8468 "fmrgow %0,%1,%2"
8469 [(set_attr "type" "fpsimple")])
8470
8471 (define_insn "p8_mtvsrwz"
8472 [(set (match_operand:DF 0 "register_operand" "=d")
8473 (unspec:DF [(match_operand:SI 1 "register_operand" "r")]
8474 UNSPEC_P8V_MTVSRWZ))]
8475 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8476 "mtvsrwz %x0,%1"
8477 [(set_attr "type" "mftgpr")])
8478
8479 (define_insn_and_split "reload_fpr_from_gpr<mode>"
8480 [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
8481 (unspec:FMOVE64X [(match_operand:FMOVE64X 1 "register_operand" "r")]
8482 UNSPEC_P8V_RELOAD_FROM_GPR))
8483 (clobber (match_operand:IF 2 "register_operand" "=d"))]
8484 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8485 "#"
8486 "&& reload_completed"
8487 [(const_int 0)]
8488 {
8489 rtx dest = operands[0];
8490 rtx src = operands[1];
8491 rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0);
8492 rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8);
8493 rtx gpr_hi_reg = gen_highpart (SImode, src);
8494 rtx gpr_lo_reg = gen_lowpart (SImode, src);
8495
8496 emit_insn (gen_p8_mtvsrwz (tmp_hi, gpr_hi_reg));
8497 emit_insn (gen_p8_mtvsrwz (tmp_lo, gpr_lo_reg));
8498 emit_insn (gen_p8_fmrgow_<mode> (dest, tmp_hi, tmp_lo));
8499 DONE;
8500 }
8501 [(set_attr "length" "12")
8502 (set_attr "type" "three")])
8503
8504 ;; Move 128 bit values from GPRs to VSX registers in 64-bit mode
8505 (define_insn "p8_mtvsrd_df"
8506 [(set (match_operand:DF 0 "register_operand" "=wa")
8507 (unspec:DF [(match_operand:DI 1 "register_operand" "r")]
8508 UNSPEC_P8V_MTVSRD))]
8509 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8510 "mtvsrd %x0,%1"
8511 [(set_attr "type" "mftgpr")])
8512
8513 (define_insn "p8_xxpermdi_<mode>"
8514 [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
8515 (unspec:FMOVE128_GPR [
8516 (match_operand:DF 1 "register_operand" "wa")
8517 (match_operand:DF 2 "register_operand" "wa")]
8518 UNSPEC_P8V_XXPERMDI))]
8519 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8520 "xxpermdi %x0,%x1,%x2,0"
8521 [(set_attr "type" "vecperm")])
8522
8523 (define_insn_and_split "reload_vsx_from_gpr<mode>"
8524 [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
8525 (unspec:FMOVE128_GPR
8526 [(match_operand:FMOVE128_GPR 1 "register_operand" "r")]
8527 UNSPEC_P8V_RELOAD_FROM_GPR))
8528 (clobber (match_operand:IF 2 "register_operand" "=wa"))]
8529 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8530 "#"
8531 "&& reload_completed"
8532 [(const_int 0)]
8533 {
8534 rtx dest = operands[0];
8535 rtx src = operands[1];
8536 /* You might think that we could use op0 as one temp and a DF clobber
8537 as op2, but you'd be wrong. Secondary reload move patterns don't
8538 check for overlap of the clobber and the destination. */
8539 rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0);
8540 rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8);
8541 rtx gpr_hi_reg = gen_highpart (DImode, src);
8542 rtx gpr_lo_reg = gen_lowpart (DImode, src);
8543
8544 emit_insn (gen_p8_mtvsrd_df (tmp_hi, gpr_hi_reg));
8545 emit_insn (gen_p8_mtvsrd_df (tmp_lo, gpr_lo_reg));
8546 emit_insn (gen_p8_xxpermdi_<mode> (dest, tmp_hi, tmp_lo));
8547 DONE;
8548 }
8549 [(set_attr "length" "12")
8550 (set_attr "type" "three")])
8551
8552 (define_split
8553 [(set (match_operand:FMOVE128_GPR 0 "nonimmediate_operand")
8554 (match_operand:FMOVE128_GPR 1 "input_operand"))]
8555 "reload_completed
8556 && (int_reg_operand (operands[0], <MODE>mode)
8557 || int_reg_operand (operands[1], <MODE>mode))
8558 && (!TARGET_DIRECT_MOVE_128
8559 || (!vsx_register_operand (operands[0], <MODE>mode)
8560 && !vsx_register_operand (operands[1], <MODE>mode)))"
8561 [(pc)]
8562 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
8563
8564 ;; Move SFmode to a VSX from a GPR register. Because scalar floating point
8565 ;; type is stored internally as double precision in the VSX registers, we have
8566 ;; to convert it from the vector format.
8567 (define_insn "p8_mtvsrd_sf"
8568 [(set (match_operand:SF 0 "register_operand" "=wa")
8569 (unspec:SF [(match_operand:DI 1 "register_operand" "r")]
8570 UNSPEC_P8V_MTVSRD))]
8571 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8572 "mtvsrd %x0,%1"
8573 [(set_attr "type" "mftgpr")])
8574
8575 (define_insn_and_split "reload_vsx_from_gprsf"
8576 [(set (match_operand:SF 0 "register_operand" "=wa")
8577 (unspec:SF [(match_operand:SF 1 "register_operand" "r")]
8578 UNSPEC_P8V_RELOAD_FROM_GPR))
8579 (clobber (match_operand:DI 2 "register_operand" "=r"))]
8580 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8581 "#"
8582 "&& reload_completed"
8583 [(const_int 0)]
8584 {
8585 rtx op0 = operands[0];
8586 rtx op1 = operands[1];
8587 rtx op2 = operands[2];
8588 rtx op1_di = simplify_gen_subreg (DImode, op1, SFmode, 0);
8589
8590 /* Move SF value to upper 32-bits for xscvspdpn. */
8591 emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32)));
8592 emit_insn (gen_p8_mtvsrd_sf (op0, op2));
8593 emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0));
8594 DONE;
8595 }
8596 [(set_attr "length" "8")
8597 (set_attr "type" "two")])
8598
8599 ;; Move 128 bit values from VSX registers to GPRs in 64-bit mode by doing a
8600 ;; normal 64-bit move, followed by an xxpermdi to get the bottom 64-bit value,
8601 ;; and then doing a move of that.
8602 (define_insn "p8_mfvsrd_3_<mode>"
8603 [(set (match_operand:DF 0 "register_operand" "=r")
8604 (unspec:DF [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
8605 UNSPEC_P8V_RELOAD_FROM_VSX))]
8606 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8607 "mfvsrd %0,%x1"
8608 [(set_attr "type" "mftgpr")])
8609
8610 (define_insn_and_split "reload_gpr_from_vsx<mode>"
8611 [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=r")
8612 (unspec:FMOVE128_GPR
8613 [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
8614 UNSPEC_P8V_RELOAD_FROM_VSX))
8615 (clobber (match_operand:FMOVE128_GPR 2 "register_operand" "=wa"))]
8616 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8617 "#"
8618 "&& reload_completed"
8619 [(const_int 0)]
8620 {
8621 rtx dest = operands[0];
8622 rtx src = operands[1];
8623 rtx tmp = operands[2];
8624 rtx gpr_hi_reg = gen_highpart (DFmode, dest);
8625 rtx gpr_lo_reg = gen_lowpart (DFmode, dest);
8626
8627 emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_hi_reg, src));
8628 emit_insn (gen_vsx_xxpermdi_<mode>_be (tmp, src, src, GEN_INT (3)));
8629 emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_lo_reg, tmp));
8630 DONE;
8631 }
8632 [(set_attr "length" "12")
8633 (set_attr "type" "three")])
8634
8635 ;; Move SFmode to a GPR from a VSX register. Because scalar floating point
8636 ;; type is stored internally as double precision, we have to convert it to the
8637 ;; vector format.
8638
8639 (define_insn_and_split "reload_gpr_from_vsxsf"
8640 [(set (match_operand:SF 0 "register_operand" "=r")
8641 (unspec:SF [(match_operand:SF 1 "register_operand" "ww")]
8642 UNSPEC_P8V_RELOAD_FROM_VSX))
8643 (clobber (match_operand:V4SF 2 "register_operand" "=wIwH"))]
8644 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8645 "#"
8646 "&& reload_completed"
8647 [(const_int 0)]
8648 {
8649 rtx op0 = operands[0];
8650 rtx op1 = operands[1];
8651 rtx op2 = operands[2];
8652 rtx op0_di = gen_rtx_REG (DImode, reg_or_subregno (op0));
8653 rtx op2_si = gen_rtx_REG (SImode, reg_or_subregno (op2));
8654
8655 emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
8656 emit_insn (gen_zero_extendsidi2 (op0_di, op2_si));
8657 DONE;
8658 }
8659 [(set_attr "length" "8")
8660 (set_attr "type" "two")])
8661
8662 \f
8663 ;; Next come the multi-word integer load and store and the load and store
8664 ;; multiple insns.
8665
8666 ;; List r->r after r->Y, otherwise reload will try to reload a
8667 ;; non-offsettable address by using r->r which won't make progress.
8668 ;; Use of fprs is disparaged slightly otherwise reload prefers to reload
8669 ;; a gpr into a fpr instead of reloading an invalid 'Y' address
8670
8671 ;; GPR store GPR load GPR move FPR store FPR load FPR move
8672 ;; GPR const AVX store AVX store AVX load AVX load VSX move
8673 ;; P9 0 P9 -1 AVX 0/-1 VSX 0 VSX -1 P9 const
8674 ;; AVX const
8675
8676 (define_insn "*movdi_internal32"
8677 [(set (match_operand:DI 0 "nonimmediate_operand"
8678 "=Y, r, r, m, ^d, ^d,
8679 r, wY, Z, ^wb, $wv, ^wi,
8680 *wo, *wo, *wv, *wi, *wi, *wv,
8681 *wv")
8682
8683 (match_operand:DI 1 "input_operand"
8684 "r, Y, r, ^d, m, ^d,
8685 IJKnF, ^wb, $wv, wY, Z, ^wi,
8686 Oj, wM, OjwM, Oj, wM, wS,
8687 wB"))]
8688
8689 "! TARGET_POWERPC64
8690 && (gpc_reg_operand (operands[0], DImode)
8691 || gpc_reg_operand (operands[1], DImode))"
8692 "@
8693 #
8694 #
8695 #
8696 stfd%U0%X0 %1,%0
8697 lfd%U1%X1 %0,%1
8698 fmr %0,%1
8699 #
8700 stxsd %1,%0
8701 stxsdx %x1,%y0
8702 lxsd %0,%1
8703 lxsdx %x0,%y1
8704 xxlor %x0,%x1,%x1
8705 xxspltib %x0,0
8706 xxspltib %x0,255
8707 vspltisw %0,%1
8708 xxlxor %x0,%x0,%x0
8709 xxlorc %x0,%x0,%x0
8710 #
8711 #"
8712 [(set_attr "type"
8713 "store, load, *, fpstore, fpload, fpsimple,
8714 *, fpstore, fpstore, fpload, fpload, veclogical,
8715 vecsimple, vecsimple, vecsimple, veclogical,veclogical,vecsimple,
8716 vecsimple")
8717 (set_attr "size" "64")
8718 (set_attr "length"
8719 "8, 8, 8, 4, 4, 4,
8720 16, 4, 4, 4, 4, 4,
8721 4, 4, 4, 4, 4, 8,
8722 4")])
8723
8724 (define_split
8725 [(set (match_operand:DI 0 "gpc_reg_operand")
8726 (match_operand:DI 1 "const_int_operand"))]
8727 "! TARGET_POWERPC64 && reload_completed
8728 && gpr_or_gpr_p (operands[0], operands[1])
8729 && !direct_move_p (operands[0], operands[1])"
8730 [(set (match_dup 2) (match_dup 4))
8731 (set (match_dup 3) (match_dup 1))]
8732 {
8733 HOST_WIDE_INT value = INTVAL (operands[1]);
8734 operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
8735 DImode);
8736 operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
8737 DImode);
8738 operands[4] = GEN_INT (value >> 32);
8739 operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
8740 })
8741
8742 (define_split
8743 [(set (match_operand:DIFD 0 "nonimmediate_operand")
8744 (match_operand:DIFD 1 "input_operand"))]
8745 "reload_completed && !TARGET_POWERPC64
8746 && gpr_or_gpr_p (operands[0], operands[1])
8747 && !direct_move_p (operands[0], operands[1])"
8748 [(pc)]
8749 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
8750
8751 ;; GPR store GPR load GPR move GPR li GPR lis GPR #
8752 ;; FPR store FPR load FPR move AVX store AVX store AVX load
8753 ;; AVX load VSX move P9 0 P9 -1 AVX 0/-1 VSX 0
8754 ;; VSX -1 P9 const AVX const From SPR To SPR SPR<->SPR
8755 ;; FPR->GPR GPR->FPR VSX->GPR GPR->VSX
8756 (define_insn "*movdi_internal64"
8757 [(set (match_operand:DI 0 "nonimmediate_operand"
8758 "=YZ, r, r, r, r, r,
8759 m, ^d, ^d, wY, Z, $wb,
8760 $wv, ^wi, *wo, *wo, *wv, *wi,
8761 *wi, *wv, *wv, r, *h, *h,
8762 ?*r, ?*wg, ?*r, ?*wj")
8763
8764 (match_operand:DI 1 "input_operand"
8765 "r, YZ, r, I, L, nF,
8766 ^d, m, ^d, ^wb, $wv, wY,
8767 Z, ^wi, Oj, wM, OjwM, Oj,
8768 wM, wS, wB, *h, r, 0,
8769 wg, r, wj, r"))]
8770
8771 "TARGET_POWERPC64
8772 && (gpc_reg_operand (operands[0], DImode)
8773 || gpc_reg_operand (operands[1], DImode))"
8774 "@
8775 std%U0%X0 %1,%0
8776 ld%U1%X1 %0,%1
8777 mr %0,%1
8778 li %0,%1
8779 lis %0,%v1
8780 #
8781 stfd%U0%X0 %1,%0
8782 lfd%U1%X1 %0,%1
8783 fmr %0,%1
8784 stxsd %1,%0
8785 stxsdx %x1,%y0
8786 lxsd %0,%1
8787 lxsdx %x0,%y1
8788 xxlor %x0,%x1,%x1
8789 xxspltib %x0,0
8790 xxspltib %x0,255
8791 #
8792 xxlxor %x0,%x0,%x0
8793 xxlorc %x0,%x0,%x0
8794 #
8795 #
8796 mf%1 %0
8797 mt%0 %1
8798 nop
8799 mftgpr %0,%1
8800 mffgpr %0,%1
8801 mfvsrd %0,%x1
8802 mtvsrd %x0,%1"
8803 [(set_attr "type"
8804 "store, load, *, *, *, *,
8805 fpstore, fpload, fpsimple, fpstore, fpstore, fpload,
8806 fpload, veclogical, vecsimple, vecsimple, vecsimple, veclogical,
8807 veclogical, vecsimple, vecsimple, mfjmpr, mtjmpr, *,
8808 mftgpr, mffgpr, mftgpr, mffgpr")
8809
8810 (set_attr "size" "64")
8811 (set_attr "length"
8812 "4, 4, 4, 4, 4, 20,
8813 4, 4, 4, 4, 4, 4,
8814 4, 4, 4, 4, 4, 4,
8815 4, 8, 4, 4, 4, 4,
8816 4, 4, 4, 4")])
8817
8818 ; Some DImode loads are best done as a load of -1 followed by a mask
8819 ; instruction.
8820 (define_split
8821 [(set (match_operand:DI 0 "int_reg_operand_not_pseudo")
8822 (match_operand:DI 1 "const_int_operand"))]
8823 "TARGET_POWERPC64
8824 && num_insns_constant (operands[1], DImode) > 1
8825 && !IN_RANGE (INTVAL (operands[1]), -0x80000000, 0xffffffff)
8826 && rs6000_is_valid_and_mask (operands[1], DImode)"
8827 [(set (match_dup 0)
8828 (const_int -1))
8829 (set (match_dup 0)
8830 (and:DI (match_dup 0)
8831 (match_dup 1)))]
8832 "")
8833
8834 ;; Split a load of a large constant into the appropriate five-instruction
8835 ;; sequence. Handle anything in a constant number of insns.
8836 ;; When non-easy constants can go in the TOC, this should use
8837 ;; easy_fp_constant predicate.
8838 (define_split
8839 [(set (match_operand:DI 0 "int_reg_operand_not_pseudo")
8840 (match_operand:DI 1 "const_int_operand"))]
8841 "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
8842 [(set (match_dup 0) (match_dup 2))
8843 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
8844 {
8845 if (rs6000_emit_set_const (operands[0], operands[1]))
8846 DONE;
8847 else
8848 FAIL;
8849 })
8850
8851 (define_split
8852 [(set (match_operand:DI 0 "int_reg_operand_not_pseudo")
8853 (match_operand:DI 1 "const_scalar_int_operand"))]
8854 "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
8855 [(set (match_dup 0) (match_dup 2))
8856 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
8857 {
8858 if (rs6000_emit_set_const (operands[0], operands[1]))
8859 DONE;
8860 else
8861 FAIL;
8862 })
8863
8864 (define_split
8865 [(set (match_operand:DI 0 "altivec_register_operand")
8866 (match_operand:DI 1 "s5bit_cint_operand"))]
8867 "TARGET_VSX && reload_completed"
8868 [(const_int 0)]
8869 {
8870 rtx op0 = operands[0];
8871 rtx op1 = operands[1];
8872 int r = REGNO (op0);
8873 rtx op0_v4si = gen_rtx_REG (V4SImode, r);
8874
8875 emit_insn (gen_altivec_vspltisw (op0_v4si, op1));
8876 if (op1 != const0_rtx && op1 != constm1_rtx)
8877 {
8878 rtx op0_v2di = gen_rtx_REG (V2DImode, r);
8879 emit_insn (gen_altivec_vupkhsw (op0_v2di, op0_v4si));
8880 }
8881 DONE;
8882 })
8883
8884 ;; Split integer constants that can be loaded with XXSPLTIB and a
8885 ;; sign extend operation.
8886 (define_split
8887 [(set (match_operand:INT_ISA3 0 "altivec_register_operand")
8888 (match_operand:INT_ISA3 1 "xxspltib_constant_split"))]
8889 "TARGET_P9_VECTOR && reload_completed"
8890 [(const_int 0)]
8891 {
8892 rtx op0 = operands[0];
8893 rtx op1 = operands[1];
8894 int r = REGNO (op0);
8895 rtx op0_v16qi = gen_rtx_REG (V16QImode, r);
8896
8897 emit_insn (gen_xxspltib_v16qi (op0_v16qi, op1));
8898 if (<MODE>mode == DImode)
8899 emit_insn (gen_vsx_sign_extend_qi_di (operands[0], op0_v16qi));
8900 else if (<MODE>mode == SImode)
8901 emit_insn (gen_vsx_sign_extend_qi_si (operands[0], op0_v16qi));
8902 else if (<MODE>mode == HImode)
8903 {
8904 rtx op0_v8hi = gen_rtx_REG (V8HImode, r);
8905 emit_insn (gen_altivec_vupkhsb (op0_v8hi, op0_v16qi));
8906 }
8907 DONE;
8908 })
8909
8910 \f
8911 ;; TImode/PTImode is similar, except that we usually want to compute the
8912 ;; address into a register and use lsi/stsi (the exception is during reload).
8913
8914 (define_insn "*mov<mode>_string"
8915 [(set (match_operand:TI2 0 "reg_or_mem_operand" "=Q,Y,????r,????r,????r,r")
8916 (match_operand:TI2 1 "input_operand" "r,r,Q,Y,r,n"))]
8917 "! TARGET_POWERPC64
8918 && (<MODE>mode != TImode || VECTOR_MEM_NONE_P (TImode))
8919 && (gpc_reg_operand (operands[0], <MODE>mode)
8920 || gpc_reg_operand (operands[1], <MODE>mode))"
8921 "#"
8922 [(set_attr "type" "store,store,load,load,*,*")
8923 (set_attr "update" "yes")
8924 (set_attr "indexed" "yes")
8925 (set_attr "cell_micro" "conditional")])
8926
8927 (define_insn "*mov<mode>_ppc64"
8928 [(set (match_operand:TI2 0 "nonimmediate_operand" "=wQ,Y,r,r,r,r")
8929 (match_operand:TI2 1 "input_operand" "r,r,wQ,Y,r,n"))]
8930 "(TARGET_POWERPC64 && VECTOR_MEM_NONE_P (<MODE>mode)
8931 && (gpc_reg_operand (operands[0], <MODE>mode)
8932 || gpc_reg_operand (operands[1], <MODE>mode)))"
8933 {
8934 return rs6000_output_move_128bit (operands);
8935 }
8936 [(set_attr "type" "store,store,load,load,*,*")
8937 (set_attr "length" "8")])
8938
8939 (define_split
8940 [(set (match_operand:TI2 0 "int_reg_operand")
8941 (match_operand:TI2 1 "const_scalar_int_operand"))]
8942 "TARGET_POWERPC64
8943 && (VECTOR_MEM_NONE_P (<MODE>mode)
8944 || (reload_completed && INT_REGNO_P (REGNO (operands[0]))))"
8945 [(set (match_dup 2) (match_dup 4))
8946 (set (match_dup 3) (match_dup 5))]
8947 {
8948 operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
8949 <MODE>mode);
8950 operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
8951 <MODE>mode);
8952 if (CONST_WIDE_INT_P (operands[1]))
8953 {
8954 operands[4] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 1));
8955 operands[5] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 0));
8956 }
8957 else if (CONST_INT_P (operands[1]))
8958 {
8959 operands[4] = GEN_INT (- (INTVAL (operands[1]) < 0));
8960 operands[5] = operands[1];
8961 }
8962 else
8963 FAIL;
8964 })
8965
8966 (define_split
8967 [(set (match_operand:TI2 0 "nonimmediate_operand")
8968 (match_operand:TI2 1 "input_operand"))]
8969 "reload_completed
8970 && gpr_or_gpr_p (operands[0], operands[1])
8971 && !direct_move_p (operands[0], operands[1])
8972 && !quad_load_store_p (operands[0], operands[1])"
8973 [(pc)]
8974 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
8975 \f
8976 (define_expand "setmemsi"
8977 [(parallel [(set (match_operand:BLK 0 "")
8978 (match_operand 2 "const_int_operand"))
8979 (use (match_operand:SI 1 ""))
8980 (use (match_operand:SI 3 ""))])]
8981 ""
8982 {
8983 /* If value to set is not zero, use the library routine. */
8984 if (operands[2] != const0_rtx)
8985 FAIL;
8986
8987 if (expand_block_clear (operands))
8988 DONE;
8989 else
8990 FAIL;
8991 })
8992
8993 ;; String compare N insn.
8994 ;; Argument 0 is the target (result)
8995 ;; Argument 1 is the destination
8996 ;; Argument 2 is the source
8997 ;; Argument 3 is the length
8998 ;; Argument 4 is the alignment
8999
9000 (define_expand "cmpstrnsi"
9001 [(parallel [(set (match_operand:SI 0)
9002 (compare:SI (match_operand:BLK 1)
9003 (match_operand:BLK 2)))
9004 (use (match_operand:SI 3))
9005 (use (match_operand:SI 4))])]
9006 "TARGET_CMPB && (BYTES_BIG_ENDIAN || TARGET_LDBRX)"
9007 {
9008 if (optimize_insn_for_size_p ())
9009 FAIL;
9010
9011 if (expand_strn_compare (operands, 0))
9012 DONE;
9013 else
9014 FAIL;
9015 })
9016
9017 ;; String compare insn.
9018 ;; Argument 0 is the target (result)
9019 ;; Argument 1 is the destination
9020 ;; Argument 2 is the source
9021 ;; Argument 3 is the alignment
9022
9023 (define_expand "cmpstrsi"
9024 [(parallel [(set (match_operand:SI 0)
9025 (compare:SI (match_operand:BLK 1)
9026 (match_operand:BLK 2)))
9027 (use (match_operand:SI 3))])]
9028 "TARGET_CMPB && (BYTES_BIG_ENDIAN || TARGET_LDBRX)"
9029 {
9030 if (optimize_insn_for_size_p ())
9031 FAIL;
9032
9033 if (expand_strn_compare (operands, 1))
9034 DONE;
9035 else
9036 FAIL;
9037 })
9038
9039 ;; Block compare insn.
9040 ;; Argument 0 is the target (result)
9041 ;; Argument 1 is the destination
9042 ;; Argument 2 is the source
9043 ;; Argument 3 is the length
9044 ;; Argument 4 is the alignment
9045
9046 (define_expand "cmpmemsi"
9047 [(parallel [(set (match_operand:SI 0)
9048 (compare:SI (match_operand:BLK 1)
9049 (match_operand:BLK 2)))
9050 (use (match_operand:SI 3))
9051 (use (match_operand:SI 4))])]
9052 "TARGET_POPCNTD"
9053 {
9054 if (expand_block_compare (operands))
9055 DONE;
9056 else
9057 FAIL;
9058 })
9059
9060 ;; String/block move insn.
9061 ;; Argument 0 is the destination
9062 ;; Argument 1 is the source
9063 ;; Argument 2 is the length
9064 ;; Argument 3 is the alignment
9065
9066 (define_expand "movmemsi"
9067 [(parallel [(set (match_operand:BLK 0 "")
9068 (match_operand:BLK 1 ""))
9069 (use (match_operand:SI 2 ""))
9070 (use (match_operand:SI 3 ""))])]
9071 ""
9072 {
9073 if (expand_block_move (operands))
9074 DONE;
9075 else
9076 FAIL;
9077 })
9078 \f
9079 ;; Define insns that do load or store with update. Some of these we can
9080 ;; get by using pre-decrement or pre-increment, but the hardware can also
9081 ;; do cases where the increment is not the size of the object.
9082 ;;
9083 ;; In all these cases, we use operands 0 and 1 for the register being
9084 ;; incremented because those are the operands that local-alloc will
9085 ;; tie and these are the pair most likely to be tieable (and the ones
9086 ;; that will benefit the most).
9087
9088 (define_insn "*movdi_update1"
9089 [(set (match_operand:DI 3 "gpc_reg_operand" "=r,r")
9090 (mem:DI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0,0")
9091 (match_operand:DI 2 "reg_or_aligned_short_operand" "r,I"))))
9092 (set (match_operand:DI 0 "gpc_reg_operand" "=b,b")
9093 (plus:DI (match_dup 1) (match_dup 2)))]
9094 "TARGET_POWERPC64 && TARGET_UPDATE
9095 && (!avoiding_indexed_address_p (DImode)
9096 || !gpc_reg_operand (operands[2], DImode))"
9097 "@
9098 ldux %3,%0,%2
9099 ldu %3,%2(%0)"
9100 [(set_attr "type" "load")
9101 (set_attr "update" "yes")
9102 (set_attr "indexed" "yes,no")])
9103
9104 (define_insn "movdi_<mode>_update"
9105 [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9106 (match_operand:P 2 "reg_or_aligned_short_operand" "r,I")))
9107 (match_operand:DI 3 "gpc_reg_operand" "r,r"))
9108 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9109 (plus:P (match_dup 1) (match_dup 2)))]
9110 "TARGET_POWERPC64 && TARGET_UPDATE
9111 && (!avoiding_indexed_address_p (Pmode)
9112 || !gpc_reg_operand (operands[2], Pmode)
9113 || (REG_P (operands[0])
9114 && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
9115 "@
9116 stdux %3,%0,%2
9117 stdu %3,%2(%0)"
9118 [(set_attr "type" "store")
9119 (set_attr "update" "yes")
9120 (set_attr "indexed" "yes,no")])
9121
9122 ;; This pattern is only conditional on TARGET_POWERPC64, as it is
9123 ;; needed for stack allocation, even if the user passes -mno-update.
9124 (define_insn "movdi_<mode>_update_stack"
9125 [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9126 (match_operand:P 2 "reg_or_aligned_short_operand" "r,I")))
9127 (match_operand:DI 3 "gpc_reg_operand" "r,r"))
9128 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9129 (plus:P (match_dup 1) (match_dup 2)))]
9130 "TARGET_POWERPC64"
9131 "@
9132 stdux %3,%0,%2
9133 stdu %3,%2(%0)"
9134 [(set_attr "type" "store")
9135 (set_attr "update" "yes")
9136 (set_attr "indexed" "yes,no")])
9137
9138 (define_insn "*movsi_update1"
9139 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9140 (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9141 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9142 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9143 (plus:SI (match_dup 1) (match_dup 2)))]
9144 "TARGET_UPDATE
9145 && (!avoiding_indexed_address_p (SImode)
9146 || !gpc_reg_operand (operands[2], SImode))"
9147 "@
9148 lwzux %3,%0,%2
9149 lwzu %3,%2(%0)"
9150 [(set_attr "type" "load")
9151 (set_attr "update" "yes")
9152 (set_attr "indexed" "yes,no")])
9153
9154 (define_insn "*movsi_update2"
9155 [(set (match_operand:DI 3 "gpc_reg_operand" "=r")
9156 (sign_extend:DI
9157 (mem:SI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0")
9158 (match_operand:DI 2 "gpc_reg_operand" "r")))))
9159 (set (match_operand:DI 0 "gpc_reg_operand" "=b")
9160 (plus:DI (match_dup 1) (match_dup 2)))]
9161 "TARGET_POWERPC64 && !avoiding_indexed_address_p (DImode)"
9162 "lwaux %3,%0,%2"
9163 [(set_attr "type" "load")
9164 (set_attr "sign_extend" "yes")
9165 (set_attr "update" "yes")
9166 (set_attr "indexed" "yes")])
9167
9168 (define_insn "movsi_update"
9169 [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9170 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9171 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
9172 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9173 (plus:SI (match_dup 1) (match_dup 2)))]
9174 "TARGET_UPDATE
9175 && (!avoiding_indexed_address_p (SImode)
9176 || !gpc_reg_operand (operands[2], SImode)
9177 || (REG_P (operands[0])
9178 && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
9179 "@
9180 stwux %3,%0,%2
9181 stwu %3,%2(%0)"
9182 [(set_attr "type" "store")
9183 (set_attr "update" "yes")
9184 (set_attr "indexed" "yes,no")])
9185
9186 ;; This is an unconditional pattern; needed for stack allocation, even
9187 ;; if the user passes -mno-update.
9188 (define_insn "movsi_update_stack"
9189 [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9190 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9191 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
9192 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9193 (plus:SI (match_dup 1) (match_dup 2)))]
9194 ""
9195 "@
9196 stwux %3,%0,%2
9197 stwu %3,%2(%0)"
9198 [(set_attr "type" "store")
9199 (set_attr "update" "yes")
9200 (set_attr "indexed" "yes,no")])
9201
9202 (define_insn "*movhi_update1"
9203 [(set (match_operand:HI 3 "gpc_reg_operand" "=r,r")
9204 (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9205 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9206 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9207 (plus:SI (match_dup 1) (match_dup 2)))]
9208 "TARGET_UPDATE
9209 && (!avoiding_indexed_address_p (SImode)
9210 || !gpc_reg_operand (operands[2], SImode))"
9211 "@
9212 lhzux %3,%0,%2
9213 lhzu %3,%2(%0)"
9214 [(set_attr "type" "load")
9215 (set_attr "update" "yes")
9216 (set_attr "indexed" "yes,no")])
9217
9218 (define_insn "*movhi_update2"
9219 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9220 (zero_extend:SI
9221 (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9222 (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
9223 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9224 (plus:SI (match_dup 1) (match_dup 2)))]
9225 "TARGET_UPDATE
9226 && (!avoiding_indexed_address_p (SImode)
9227 || !gpc_reg_operand (operands[2], SImode))"
9228 "@
9229 lhzux %3,%0,%2
9230 lhzu %3,%2(%0)"
9231 [(set_attr "type" "load")
9232 (set_attr "update" "yes")
9233 (set_attr "indexed" "yes,no")])
9234
9235 (define_insn "*movhi_update3"
9236 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9237 (sign_extend:SI
9238 (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9239 (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
9240 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9241 (plus:SI (match_dup 1) (match_dup 2)))]
9242 "TARGET_UPDATE
9243 && !(avoiding_indexed_address_p (SImode)
9244 && gpc_reg_operand (operands[2], SImode))"
9245 "@
9246 lhaux %3,%0,%2
9247 lhau %3,%2(%0)"
9248 [(set_attr "type" "load")
9249 (set_attr "sign_extend" "yes")
9250 (set_attr "update" "yes")
9251 (set_attr "indexed" "yes,no")])
9252
9253 (define_insn "*movhi_update4"
9254 [(set (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9255 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9256 (match_operand:HI 3 "gpc_reg_operand" "r,r"))
9257 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9258 (plus:SI (match_dup 1) (match_dup 2)))]
9259 "TARGET_UPDATE
9260 && (!avoiding_indexed_address_p (SImode)
9261 || !gpc_reg_operand (operands[2], SImode))"
9262 "@
9263 sthux %3,%0,%2
9264 sthu %3,%2(%0)"
9265 [(set_attr "type" "store")
9266 (set_attr "update" "yes")
9267 (set_attr "indexed" "yes,no")])
9268
9269 (define_insn "*movqi_update1"
9270 [(set (match_operand:QI 3 "gpc_reg_operand" "=r,r")
9271 (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9272 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9273 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9274 (plus:SI (match_dup 1) (match_dup 2)))]
9275 "TARGET_UPDATE
9276 && (!avoiding_indexed_address_p (SImode)
9277 || !gpc_reg_operand (operands[2], SImode))"
9278 "@
9279 lbzux %3,%0,%2
9280 lbzu %3,%2(%0)"
9281 [(set_attr "type" "load")
9282 (set_attr "update" "yes")
9283 (set_attr "indexed" "yes,no")])
9284
9285 (define_insn "*movqi_update2"
9286 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9287 (zero_extend:SI
9288 (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9289 (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
9290 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9291 (plus:SI (match_dup 1) (match_dup 2)))]
9292 "TARGET_UPDATE
9293 && (!avoiding_indexed_address_p (SImode)
9294 || !gpc_reg_operand (operands[2], SImode))"
9295 "@
9296 lbzux %3,%0,%2
9297 lbzu %3,%2(%0)"
9298 [(set_attr "type" "load")
9299 (set_attr "update" "yes")
9300 (set_attr "indexed" "yes,no")])
9301
9302 (define_insn "*movqi_update3"
9303 [(set (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9304 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9305 (match_operand:QI 3 "gpc_reg_operand" "r,r"))
9306 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9307 (plus:SI (match_dup 1) (match_dup 2)))]
9308 "TARGET_UPDATE
9309 && (!avoiding_indexed_address_p (SImode)
9310 || !gpc_reg_operand (operands[2], SImode))"
9311 "@
9312 stbux %3,%0,%2
9313 stbu %3,%2(%0)"
9314 [(set_attr "type" "store")
9315 (set_attr "update" "yes")
9316 (set_attr "indexed" "yes,no")])
9317
9318 (define_insn "*movsf_update1"
9319 [(set (match_operand:SF 3 "gpc_reg_operand" "=f,f")
9320 (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9321 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9322 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9323 (plus:SI (match_dup 1) (match_dup 2)))]
9324 "TARGET_HARD_FLOAT && TARGET_UPDATE
9325 && (!avoiding_indexed_address_p (SImode)
9326 || !gpc_reg_operand (operands[2], SImode))"
9327 "@
9328 lfsux %3,%0,%2
9329 lfsu %3,%2(%0)"
9330 [(set_attr "type" "fpload")
9331 (set_attr "update" "yes")
9332 (set_attr "indexed" "yes,no")])
9333
9334 (define_insn "*movsf_update2"
9335 [(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9336 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9337 (match_operand:SF 3 "gpc_reg_operand" "f,f"))
9338 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9339 (plus:SI (match_dup 1) (match_dup 2)))]
9340 "TARGET_HARD_FLOAT && TARGET_UPDATE
9341 && (!avoiding_indexed_address_p (SImode)
9342 || !gpc_reg_operand (operands[2], SImode))"
9343 "@
9344 stfsux %3,%0,%2
9345 stfsu %3,%2(%0)"
9346 [(set_attr "type" "fpstore")
9347 (set_attr "update" "yes")
9348 (set_attr "indexed" "yes,no")])
9349
9350 (define_insn "*movsf_update3"
9351 [(set (match_operand:SF 3 "gpc_reg_operand" "=r,r")
9352 (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9353 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9354 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9355 (plus:SI (match_dup 1) (match_dup 2)))]
9356 "TARGET_SOFT_FLOAT && TARGET_UPDATE
9357 && (!avoiding_indexed_address_p (SImode)
9358 || !gpc_reg_operand (operands[2], SImode))"
9359 "@
9360 lwzux %3,%0,%2
9361 lwzu %3,%2(%0)"
9362 [(set_attr "type" "load")
9363 (set_attr "update" "yes")
9364 (set_attr "indexed" "yes,no")])
9365
9366 (define_insn "*movsf_update4"
9367 [(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9368 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9369 (match_operand:SF 3 "gpc_reg_operand" "r,r"))
9370 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9371 (plus:SI (match_dup 1) (match_dup 2)))]
9372 "TARGET_SOFT_FLOAT && TARGET_UPDATE
9373 && (!avoiding_indexed_address_p (SImode)
9374 || !gpc_reg_operand (operands[2], SImode))"
9375 "@
9376 stwux %3,%0,%2
9377 stwu %3,%2(%0)"
9378 [(set_attr "type" "store")
9379 (set_attr "update" "yes")
9380 (set_attr "indexed" "yes,no")])
9381
9382 (define_insn "*movdf_update1"
9383 [(set (match_operand:DF 3 "gpc_reg_operand" "=d,d")
9384 (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9385 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9386 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9387 (plus:SI (match_dup 1) (match_dup 2)))]
9388 "TARGET_HARD_FLOAT && TARGET_UPDATE
9389 && (!avoiding_indexed_address_p (SImode)
9390 || !gpc_reg_operand (operands[2], SImode))"
9391 "@
9392 lfdux %3,%0,%2
9393 lfdu %3,%2(%0)"
9394 [(set_attr "type" "fpload")
9395 (set_attr "update" "yes")
9396 (set_attr "indexed" "yes,no")
9397 (set_attr "size" "64")])
9398
9399 (define_insn "*movdf_update2"
9400 [(set (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9401 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9402 (match_operand:DF 3 "gpc_reg_operand" "d,d"))
9403 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9404 (plus:SI (match_dup 1) (match_dup 2)))]
9405 "TARGET_HARD_FLOAT && TARGET_UPDATE
9406 && (!avoiding_indexed_address_p (SImode)
9407 || !gpc_reg_operand (operands[2], SImode))"
9408 "@
9409 stfdux %3,%0,%2
9410 stfdu %3,%2(%0)"
9411 [(set_attr "type" "fpstore")
9412 (set_attr "update" "yes")
9413 (set_attr "indexed" "yes,no")])
9414
9415
9416 ;; After inserting conditional returns we can sometimes have
9417 ;; unnecessary register moves. Unfortunately we cannot have a
9418 ;; modeless peephole here, because some single SImode sets have early
9419 ;; clobber outputs. Although those sets expand to multi-ppc-insn
9420 ;; sequences, using get_attr_length here will smash the operands
9421 ;; array. Neither is there an early_cobbler_p predicate.
9422 ;; Also this optimization interferes with scalars going into
9423 ;; altivec registers (the code does reloading through the FPRs).
9424 (define_peephole2
9425 [(set (match_operand:DF 0 "gpc_reg_operand")
9426 (match_operand:DF 1 "any_operand"))
9427 (set (match_operand:DF 2 "gpc_reg_operand")
9428 (match_dup 0))]
9429 "!TARGET_VSX
9430 && peep2_reg_dead_p (2, operands[0])"
9431 [(set (match_dup 2) (match_dup 1))])
9432
9433 (define_peephole2
9434 [(set (match_operand:SF 0 "gpc_reg_operand")
9435 (match_operand:SF 1 "any_operand"))
9436 (set (match_operand:SF 2 "gpc_reg_operand")
9437 (match_dup 0))]
9438 "!TARGET_P8_VECTOR
9439 && peep2_reg_dead_p (2, operands[0])"
9440 [(set (match_dup 2) (match_dup 1))])
9441
9442 \f
9443 ;; TLS support.
9444
9445 (define_insn "*tls_gdld_nomark<bits>"
9446 [(match_parallel 3 ""
9447 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9448 (call (mem:SI (match_operand:P 1))
9449 (match_operand:P 2 "unspec_tls")))
9450 (match_dup 2)])]
9451 "HAVE_AS_TLS && !TARGET_TLS_MARKERS && DEFAULT_ABI != ABI_DARWIN"
9452 {
9453 rtx op[3];
9454 op[0] = operands[0];
9455 op[1] = XVECEXP (operands[2], 0, 0);
9456 if (XINT (operands[2], 1) == UNSPEC_TLSGD)
9457 {
9458 op[2] = XVECEXP (operands[2], 0, 1);
9459 if (TARGET_CMODEL != CMODEL_SMALL)
9460 output_asm_insn ("addis %0,%2,%1@got@tlsgd@ha\;"
9461 "addi %0,%0,%1@got@tlsgd@l", op);
9462 else
9463 output_asm_insn ("addi %0,%2,%1@got@tlsgd", op);
9464 }
9465 else
9466 {
9467 if (TARGET_CMODEL != CMODEL_SMALL)
9468 output_asm_insn ("addis %0,%1,%&@got@tlsld@ha\;"
9469 "addi %0,%0,%&@got@tlsld@l", op);
9470 else
9471 output_asm_insn ("addi %0,%1,%&@got@tlsld", op);
9472 }
9473 return rs6000_call_template (operands, 1);
9474 }
9475 [(set_attr "type" "two")
9476 (set (attr "length")
9477 (cond [(match_test "TARGET_CMODEL != CMODEL_SMALL")
9478 (const_int 16)
9479 (match_test "DEFAULT_ABI != ABI_V4")
9480 (const_int 12)]
9481 (const_int 8)))])
9482
9483 (define_insn_and_split "*tls_gd<bits>"
9484 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9485 (unspec:P [(match_operand:P 1 "rs6000_tls_symbol_ref" "")
9486 (match_operand:P 2 "gpc_reg_operand" "b")]
9487 UNSPEC_TLSGD))]
9488 "HAVE_AS_TLS && TARGET_TLS_MARKERS"
9489 "addi %0,%2,%1@got@tlsgd"
9490 "&& TARGET_CMODEL != CMODEL_SMALL"
9491 [(set (match_dup 3)
9492 (high:P
9493 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))
9494 (set (match_dup 0)
9495 (lo_sum:P (match_dup 3)
9496 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))]
9497 {
9498 operands[3] = gen_reg_rtx (<MODE>mode);
9499 }
9500 [(set (attr "length")
9501 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9502 (const_int 8)
9503 (const_int 4)))])
9504
9505 (define_insn "*tls_gd_high<bits>"
9506 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9507 (high:P
9508 (unspec:P [(match_operand:P 1 "rs6000_tls_symbol_ref" "")
9509 (match_operand:P 2 "gpc_reg_operand" "b")]
9510 UNSPEC_TLSGD)))]
9511 "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9512 "addis %0,%2,%1@got@tlsgd@ha")
9513
9514 (define_insn "*tls_gd_low<bits>"
9515 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9516 (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
9517 (unspec:P [(match_operand:P 2 "rs6000_tls_symbol_ref" "")
9518 (match_operand:P 3 "gpc_reg_operand" "b")]
9519 UNSPEC_TLSGD)))]
9520 "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9521 "addi %0,%1,%2@got@tlsgd@l")
9522
9523 (define_insn_and_split "*tls_ld<bits>"
9524 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9525 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")]
9526 UNSPEC_TLSLD))]
9527 "HAVE_AS_TLS && TARGET_TLS_MARKERS"
9528 "addi %0,%1,%&@got@tlsld"
9529 "&& TARGET_CMODEL != CMODEL_SMALL"
9530 [(set (match_dup 2)
9531 (high:P
9532 (unspec:P [(match_dup 1)] UNSPEC_TLSLD)))
9533 (set (match_dup 0)
9534 (lo_sum:P (match_dup 2)
9535 (unspec:P [(match_dup 1)] UNSPEC_TLSLD)))]
9536 {
9537 operands[2] = gen_reg_rtx (<MODE>mode);
9538 }
9539 [(set (attr "length")
9540 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9541 (const_int 8)
9542 (const_int 4)))])
9543
9544 (define_insn "*tls_ld_high<bits>"
9545 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9546 (high:P
9547 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")]
9548 UNSPEC_TLSLD)))]
9549 "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9550 "addis %0,%1,%&@got@tlsld@ha")
9551
9552 (define_insn "*tls_ld_low<bits>"
9553 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9554 (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
9555 (unspec:P [(match_operand:P 2 "gpc_reg_operand" "b")]
9556 UNSPEC_TLSLD)))]
9557 "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9558 "addi %0,%1,%&@got@tlsld@l")
9559
9560 (define_insn "tls_dtprel_<bits>"
9561 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9562 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9563 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9564 UNSPEC_TLSDTPREL))]
9565 "HAVE_AS_TLS"
9566 "addi %0,%1,%2@dtprel")
9567
9568 (define_insn "tls_dtprel_ha_<bits>"
9569 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9570 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9571 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9572 UNSPEC_TLSDTPRELHA))]
9573 "HAVE_AS_TLS"
9574 "addis %0,%1,%2@dtprel@ha")
9575
9576 (define_insn "tls_dtprel_lo_<bits>"
9577 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9578 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9579 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9580 UNSPEC_TLSDTPRELLO))]
9581 "HAVE_AS_TLS"
9582 "addi %0,%1,%2@dtprel@l")
9583
9584 (define_insn_and_split "tls_got_dtprel_<bits>"
9585 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9586 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9587 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9588 UNSPEC_TLSGOTDTPREL))]
9589 "HAVE_AS_TLS"
9590 "<ptrload> %0,%2@got@dtprel(%1)"
9591 "&& TARGET_CMODEL != CMODEL_SMALL"
9592 [(set (match_dup 3)
9593 (high:P
9594 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))
9595 (set (match_dup 0)
9596 (lo_sum:P (match_dup 3)
9597 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))]
9598 {
9599 operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9600 }
9601 [(set (attr "length")
9602 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9603 (const_int 8)
9604 (const_int 4)))])
9605
9606 (define_insn "*tls_got_dtprel_high<bits>"
9607 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9608 (high:P
9609 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9610 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9611 UNSPEC_TLSGOTDTPREL)))]
9612 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9613 "addis %0,%1,%2@got@dtprel@ha")
9614
9615 (define_insn "*tls_got_dtprel_low<bits>"
9616 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9617 (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
9618 (unspec:P [(match_operand:P 3 "gpc_reg_operand" "b")
9619 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9620 UNSPEC_TLSGOTDTPREL)))]
9621 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9622 "<ptrload> %0,%2@got@dtprel@l(%1)")
9623
9624 (define_insn "tls_tprel_<bits>"
9625 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9626 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9627 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9628 UNSPEC_TLSTPREL))]
9629 "HAVE_AS_TLS"
9630 "addi %0,%1,%2@tprel")
9631
9632 (define_insn "tls_tprel_ha_<bits>"
9633 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9634 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9635 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9636 UNSPEC_TLSTPRELHA))]
9637 "HAVE_AS_TLS"
9638 "addis %0,%1,%2@tprel@ha")
9639
9640 (define_insn "tls_tprel_lo_<bits>"
9641 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9642 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9643 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9644 UNSPEC_TLSTPRELLO))]
9645 "HAVE_AS_TLS"
9646 "addi %0,%1,%2@tprel@l")
9647
9648 ;; "b" output constraint here and on tls_tls input to support linker tls
9649 ;; optimization. The linker may edit the instructions emitted by a
9650 ;; tls_got_tprel/tls_tls pair to addis,addi.
9651 (define_insn_and_split "tls_got_tprel_<bits>"
9652 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9653 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9654 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9655 UNSPEC_TLSGOTTPREL))]
9656 "HAVE_AS_TLS"
9657 "<ptrload> %0,%2@got@tprel(%1)"
9658 "&& TARGET_CMODEL != CMODEL_SMALL"
9659 [(set (match_dup 3)
9660 (high:P
9661 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))
9662 (set (match_dup 0)
9663 (lo_sum:P (match_dup 3)
9664 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))]
9665 {
9666 operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9667 }
9668 [(set (attr "length")
9669 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9670 (const_int 8)
9671 (const_int 4)))])
9672
9673 (define_insn "*tls_got_tprel_high<bits>"
9674 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9675 (high:P
9676 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9677 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9678 UNSPEC_TLSGOTTPREL)))]
9679 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9680 "addis %0,%1,%2@got@tprel@ha")
9681
9682 (define_insn "*tls_got_tprel_low<bits>"
9683 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9684 (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
9685 (unspec:P [(match_operand:P 3 "gpc_reg_operand" "b")
9686 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9687 UNSPEC_TLSGOTTPREL)))]
9688 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9689 "<ptrload> %0,%2@got@tprel@l(%1)")
9690
9691 (define_insn "tls_tls_<bits>"
9692 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9693 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9694 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9695 UNSPEC_TLSTLS))]
9696 "TARGET_ELF && HAVE_AS_TLS"
9697 "add %0,%1,%2@tls")
9698
9699 (define_expand "tls_get_tpointer"
9700 [(set (match_operand:SI 0 "gpc_reg_operand")
9701 (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))]
9702 "TARGET_XCOFF && HAVE_AS_TLS"
9703 {
9704 emit_insn (gen_tls_get_tpointer_internal ());
9705 emit_move_insn (operands[0], gen_rtx_REG (SImode, 3));
9706 DONE;
9707 })
9708
9709 (define_insn "tls_get_tpointer_internal"
9710 [(set (reg:SI 3)
9711 (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))
9712 (clobber (reg:SI LR_REGNO))]
9713 "TARGET_XCOFF && HAVE_AS_TLS"
9714 "bla __get_tpointer")
9715
9716 (define_expand "tls_get_addr<mode>"
9717 [(set (match_operand:P 0 "gpc_reg_operand")
9718 (unspec:P [(match_operand:P 1 "gpc_reg_operand")
9719 (match_operand:P 2 "gpc_reg_operand")] UNSPEC_TLSTLS))]
9720 "TARGET_XCOFF && HAVE_AS_TLS"
9721 {
9722 emit_move_insn (gen_rtx_REG (Pmode, 3), operands[1]);
9723 emit_move_insn (gen_rtx_REG (Pmode, 4), operands[2]);
9724 emit_insn (gen_tls_get_addr_internal<mode> ());
9725 emit_move_insn (operands[0], gen_rtx_REG (Pmode, 3));
9726 DONE;
9727 })
9728
9729 (define_insn "tls_get_addr_internal<mode>"
9730 [(set (reg:P 3)
9731 (unspec:P [(reg:P 3) (reg:P 4)] UNSPEC_TLSTLS))
9732 (clobber (reg:P 0))
9733 (clobber (reg:P 4))
9734 (clobber (reg:P 5))
9735 (clobber (reg:P 11))
9736 (clobber (reg:CC CR0_REGNO))
9737 (clobber (reg:P LR_REGNO))]
9738 "TARGET_XCOFF && HAVE_AS_TLS"
9739 "bla __tls_get_addr")
9740 \f
9741 ;; Next come insns related to the calling sequence.
9742 ;;
9743 ;; First, an insn to allocate new stack space for dynamic use (e.g., alloca).
9744 ;; We move the back-chain and decrement the stack pointer.
9745 ;;
9746 ;; Operand1 is more naturally reg_or_short_operand. However, for a large
9747 ;; constant alloca, using that predicate will force the generic code to put
9748 ;; the constant size into a register before calling the expander.
9749 ;;
9750 ;; As a result the expander would not have the constant size information
9751 ;; in those cases and would have to generate less efficient code.
9752 ;;
9753 ;; Thus we allow reg_or_cint_operand instead so that the expander can see
9754 ;; the constant size. The value is forced into a register if necessary.
9755 ;;
9756 (define_expand "allocate_stack"
9757 [(set (match_operand 0 "gpc_reg_operand")
9758 (minus (reg 1) (match_operand 1 "reg_or_cint_operand")))
9759 (set (reg 1)
9760 (minus (reg 1) (match_dup 1)))]
9761 ""
9762 {
9763 rtx chain = gen_reg_rtx (Pmode);
9764 rtx stack_bot = gen_rtx_MEM (Pmode, stack_pointer_rtx);
9765 rtx neg_op0;
9766 rtx insn, par, set, mem;
9767
9768 /* By allowing reg_or_cint_operand as the predicate we can get
9769 better code for stack-clash-protection because we do not lose
9770 size information. But the rest of the code expects the operand
9771 to be reg_or_short_operand. If it isn't, then force it into
9772 a register. */
9773 rtx orig_op1 = operands[1];
9774 if (!reg_or_short_operand (operands[1], Pmode))
9775 operands[1] = force_reg (Pmode, operands[1]);
9776
9777 emit_move_insn (chain, stack_bot);
9778
9779 /* Check stack bounds if necessary. */
9780 if (crtl->limit_stack)
9781 {
9782 rtx available;
9783 available = expand_binop (Pmode, sub_optab,
9784 stack_pointer_rtx, stack_limit_rtx,
9785 NULL_RTX, 1, OPTAB_WIDEN);
9786 emit_insn (gen_cond_trap (LTU, available, operands[1], const0_rtx));
9787 }
9788
9789 /* Allocate and probe if requested.
9790 This may look similar to the loop we use for prologue allocations,
9791 but it is critically different. For the former we know the loop
9792 will iterate, but do not know that generally here. The former
9793 uses that knowledge to rotate the loop. Combining them would be
9794 possible with some performance cost. */
9795 if (flag_stack_clash_protection)
9796 {
9797 rtx rounded_size, last_addr, residual;
9798 HOST_WIDE_INT probe_interval;
9799 compute_stack_clash_protection_loop_data (&rounded_size, &last_addr,
9800 &residual, &probe_interval,
9801 orig_op1);
9802
9803 /* We do occasionally get in here with constant sizes, we might
9804 as well do a reasonable job when we obviously can. */
9805 if (rounded_size != const0_rtx)
9806 {
9807 rtx loop_lab, end_loop;
9808 bool rotated = CONST_INT_P (rounded_size);
9809 rtx update = GEN_INT (-probe_interval);
9810 if (probe_interval > 32768)
9811 update = force_reg (Pmode, update);
9812
9813 emit_stack_clash_protection_probe_loop_start (&loop_lab, &end_loop,
9814 last_addr, rotated);
9815
9816 if (Pmode == SImode)
9817 emit_insn (gen_movsi_update_stack (stack_pointer_rtx,
9818 stack_pointer_rtx,
9819 update, chain));
9820 else
9821 emit_insn (gen_movdi_di_update_stack (stack_pointer_rtx,
9822 stack_pointer_rtx,
9823 update, chain));
9824 emit_stack_clash_protection_probe_loop_end (loop_lab, end_loop,
9825 last_addr, rotated);
9826 }
9827
9828 /* Now handle residuals. We just have to set operands[1] correctly
9829 and let the rest of the expander run. */
9830 operands[1] = residual;
9831 }
9832
9833 if (!(CONST_INT_P (operands[1])
9834 && IN_RANGE (INTVAL (operands[1]), -32767, 32768)))
9835 {
9836 operands[1] = force_reg (Pmode, operands[1]);
9837 neg_op0 = gen_reg_rtx (Pmode);
9838 if (TARGET_32BIT)
9839 emit_insn (gen_negsi2 (neg_op0, operands[1]));
9840 else
9841 emit_insn (gen_negdi2 (neg_op0, operands[1]));
9842 }
9843 else
9844 neg_op0 = GEN_INT (-INTVAL (operands[1]));
9845
9846 insn = emit_insn ((* ((TARGET_32BIT) ? gen_movsi_update_stack
9847 : gen_movdi_di_update_stack))
9848 (stack_pointer_rtx, stack_pointer_rtx, neg_op0,
9849 chain));
9850 /* Since we didn't use gen_frame_mem to generate the MEM, grab
9851 it now and set the alias set/attributes. The above gen_*_update
9852 calls will generate a PARALLEL with the MEM set being the first
9853 operation. */
9854 par = PATTERN (insn);
9855 gcc_assert (GET_CODE (par) == PARALLEL);
9856 set = XVECEXP (par, 0, 0);
9857 gcc_assert (GET_CODE (set) == SET);
9858 mem = SET_DEST (set);
9859 gcc_assert (MEM_P (mem));
9860 MEM_NOTRAP_P (mem) = 1;
9861 set_mem_alias_set (mem, get_frame_alias_set ());
9862
9863 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
9864 DONE;
9865 })
9866
9867 ;; These patterns say how to save and restore the stack pointer. We need not
9868 ;; save the stack pointer at function level since we are careful to
9869 ;; preserve the backchain. At block level, we have to restore the backchain
9870 ;; when we restore the stack pointer.
9871 ;;
9872 ;; For nonlocal gotos, we must save both the stack pointer and its
9873 ;; backchain and restore both. Note that in the nonlocal case, the
9874 ;; save area is a memory location.
9875
9876 (define_expand "save_stack_function"
9877 [(match_operand 0 "any_operand")
9878 (match_operand 1 "any_operand")]
9879 ""
9880 "DONE;")
9881
9882 (define_expand "restore_stack_function"
9883 [(match_operand 0 "any_operand")
9884 (match_operand 1 "any_operand")]
9885 ""
9886 "DONE;")
9887
9888 ;; Adjust stack pointer (op0) to a new value (op1).
9889 ;; First copy old stack backchain to new location, and ensure that the
9890 ;; scheduler won't reorder the sp assignment before the backchain write.
9891 (define_expand "restore_stack_block"
9892 [(set (match_dup 2) (match_dup 3))
9893 (set (match_dup 4) (match_dup 2))
9894 (match_dup 5)
9895 (set (match_operand 0 "register_operand")
9896 (match_operand 1 "register_operand"))]
9897 ""
9898 {
9899 rtvec p;
9900
9901 operands[1] = force_reg (Pmode, operands[1]);
9902 operands[2] = gen_reg_rtx (Pmode);
9903 operands[3] = gen_frame_mem (Pmode, operands[0]);
9904 operands[4] = gen_frame_mem (Pmode, operands[1]);
9905 p = rtvec_alloc (1);
9906 RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
9907 const0_rtx);
9908 operands[5] = gen_rtx_PARALLEL (VOIDmode, p);
9909 })
9910
9911 (define_expand "save_stack_nonlocal"
9912 [(set (match_dup 3) (match_dup 4))
9913 (set (match_operand 0 "memory_operand") (match_dup 3))
9914 (set (match_dup 2) (match_operand 1 "register_operand"))]
9915 ""
9916 {
9917 int units_per_word = (TARGET_32BIT) ? 4 : 8;
9918
9919 /* Copy the backchain to the first word, sp to the second. */
9920 operands[0] = adjust_address_nv (operands[0], Pmode, 0);
9921 operands[2] = adjust_address_nv (operands[0], Pmode, units_per_word);
9922 operands[3] = gen_reg_rtx (Pmode);
9923 operands[4] = gen_frame_mem (Pmode, operands[1]);
9924 })
9925
9926 (define_expand "restore_stack_nonlocal"
9927 [(set (match_dup 2) (match_operand 1 "memory_operand"))
9928 (set (match_dup 3) (match_dup 4))
9929 (set (match_dup 5) (match_dup 2))
9930 (match_dup 6)
9931 (set (match_operand 0 "register_operand") (match_dup 3))]
9932 ""
9933 {
9934 int units_per_word = (TARGET_32BIT) ? 4 : 8;
9935 rtvec p;
9936
9937 /* Restore the backchain from the first word, sp from the second. */
9938 operands[2] = gen_reg_rtx (Pmode);
9939 operands[3] = gen_reg_rtx (Pmode);
9940 operands[1] = adjust_address_nv (operands[1], Pmode, 0);
9941 operands[4] = adjust_address_nv (operands[1], Pmode, units_per_word);
9942 operands[5] = gen_frame_mem (Pmode, operands[3]);
9943 p = rtvec_alloc (1);
9944 RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
9945 const0_rtx);
9946 operands[6] = gen_rtx_PARALLEL (VOIDmode, p);
9947 })
9948 \f
9949 ;; TOC register handling.
9950
9951 ;; Code to initialize the TOC register...
9952
9953 (define_insn "load_toc_aix_si"
9954 [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
9955 (unspec:SI [(const_int 0)] UNSPEC_TOC))
9956 (use (reg:SI 2))])]
9957 "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_32BIT"
9958 {
9959 char buf[30];
9960 extern int need_toc_init;
9961 need_toc_init = 1;
9962 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
9963 operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
9964 operands[2] = gen_rtx_REG (Pmode, 2);
9965 return "lwz %0,%1(%2)";
9966 }
9967 [(set_attr "type" "load")
9968 (set_attr "update" "no")
9969 (set_attr "indexed" "no")])
9970
9971 (define_insn "load_toc_aix_di"
9972 [(parallel [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
9973 (unspec:DI [(const_int 0)] UNSPEC_TOC))
9974 (use (reg:DI 2))])]
9975 "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_64BIT"
9976 {
9977 char buf[30];
9978 extern int need_toc_init;
9979 need_toc_init = 1;
9980 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC",
9981 !TARGET_ELF || !TARGET_MINIMAL_TOC);
9982 if (TARGET_ELF)
9983 strcat (buf, "@toc");
9984 operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
9985 operands[2] = gen_rtx_REG (Pmode, 2);
9986 return "ld %0,%1(%2)";
9987 }
9988 [(set_attr "type" "load")
9989 (set_attr "update" "no")
9990 (set_attr "indexed" "no")])
9991
9992 (define_insn "load_toc_v4_pic_si"
9993 [(set (reg:SI LR_REGNO)
9994 (unspec:SI [(const_int 0)] UNSPEC_TOC))]
9995 "DEFAULT_ABI == ABI_V4 && flag_pic == 1 && TARGET_32BIT"
9996 "bl _GLOBAL_OFFSET_TABLE_@local-4"
9997 [(set_attr "type" "branch")])
9998
9999 (define_expand "load_toc_v4_PIC_1"
10000 [(parallel [(set (reg:SI LR_REGNO)
10001 (match_operand:SI 0 "immediate_operand" "s"))
10002 (use (unspec [(match_dup 0)] UNSPEC_TOC))])]
10003 "TARGET_ELF && DEFAULT_ABI == ABI_V4
10004 && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10005 "")
10006
10007 (define_insn "load_toc_v4_PIC_1_normal"
10008 [(set (reg:SI LR_REGNO)
10009 (match_operand:SI 0 "immediate_operand" "s"))
10010 (use (unspec [(match_dup 0)] UNSPEC_TOC))]
10011 "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
10012 && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10013 "bcl 20,31,%0\n%0:"
10014 [(set_attr "type" "branch")
10015 (set_attr "cannot_copy" "yes")])
10016
10017 (define_insn "load_toc_v4_PIC_1_476"
10018 [(set (reg:SI LR_REGNO)
10019 (match_operand:SI 0 "immediate_operand" "s"))
10020 (use (unspec [(match_dup 0)] UNSPEC_TOC))]
10021 "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
10022 && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10023 {
10024 char name[32];
10025 static char templ[32];
10026
10027 get_ppc476_thunk_name (name);
10028 sprintf (templ, "bl %s\n%%0:", name);
10029 return templ;
10030 }
10031 [(set_attr "type" "branch")
10032 (set_attr "cannot_copy" "yes")])
10033
10034 (define_expand "load_toc_v4_PIC_1b"
10035 [(parallel [(set (reg:SI LR_REGNO)
10036 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10037 (label_ref (match_operand 1 ""))]
10038 UNSPEC_TOCPTR))
10039 (match_dup 1)])]
10040 "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10041 "")
10042
10043 (define_insn "load_toc_v4_PIC_1b_normal"
10044 [(set (reg:SI LR_REGNO)
10045 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10046 (label_ref (match_operand 1 "" ""))]
10047 UNSPEC_TOCPTR))
10048 (match_dup 1)]
10049 "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10050 "bcl 20,31,$+8\;.long %0-$"
10051 [(set_attr "type" "branch")
10052 (set_attr "length" "8")])
10053
10054 (define_insn "load_toc_v4_PIC_1b_476"
10055 [(set (reg:SI LR_REGNO)
10056 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10057 (label_ref (match_operand 1 "" ""))]
10058 UNSPEC_TOCPTR))
10059 (match_dup 1)]
10060 "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10061 {
10062 char name[32];
10063 static char templ[32];
10064
10065 get_ppc476_thunk_name (name);
10066 sprintf (templ, "bl %s\;b $+8\;.long %%0-$", name);
10067 return templ;
10068 }
10069 [(set_attr "type" "branch")
10070 (set_attr "length" "16")])
10071
10072 (define_insn "load_toc_v4_PIC_2"
10073 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10074 (mem:SI (plus:SI
10075 (match_operand:SI 1 "gpc_reg_operand" "b")
10076 (const
10077 (minus:SI (match_operand:SI 2 "immediate_operand" "s")
10078 (match_operand:SI 3 "immediate_operand" "s"))))))]
10079 "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10080 "lwz %0,%2-%3(%1)"
10081 [(set_attr "type" "load")])
10082
10083 (define_insn "load_toc_v4_PIC_3b"
10084 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10085 (plus:SI
10086 (match_operand:SI 1 "gpc_reg_operand" "b")
10087 (high:SI
10088 (const
10089 (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
10090 (match_operand:SI 3 "symbol_ref_operand" "s"))))))]
10091 "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
10092 "addis %0,%1,%2-%3@ha")
10093
10094 (define_insn "load_toc_v4_PIC_3c"
10095 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10096 (lo_sum:SI
10097 (match_operand:SI 1 "gpc_reg_operand" "b")
10098 (const
10099 (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
10100 (match_operand:SI 3 "symbol_ref_operand" "s")))))]
10101 "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
10102 "addi %0,%1,%2-%3@l")
10103
10104 ;; If the TOC is shared over a translation unit, as happens with all
10105 ;; the kinds of PIC that we support, we need to restore the TOC
10106 ;; pointer only when jumping over units of translation.
10107 ;; On Darwin, we need to reload the picbase.
10108
10109 (define_expand "builtin_setjmp_receiver"
10110 [(use (label_ref (match_operand 0 "")))]
10111 "(DEFAULT_ABI == ABI_V4 && flag_pic == 1)
10112 || (TARGET_TOC && TARGET_MINIMAL_TOC)
10113 || (DEFAULT_ABI == ABI_DARWIN && flag_pic)"
10114 {
10115 #if TARGET_MACHO
10116 if (DEFAULT_ABI == ABI_DARWIN)
10117 {
10118 rtx picrtx = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME);
10119 rtx picreg = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
10120 rtx tmplabrtx;
10121 char tmplab[20];
10122
10123 crtl->uses_pic_offset_table = 1;
10124 ASM_GENERATE_INTERNAL_LABEL(tmplab, "LSJR",
10125 CODE_LABEL_NUMBER (operands[0]));
10126 tmplabrtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (tmplab));
10127
10128 emit_insn (gen_load_macho_picbase (tmplabrtx));
10129 emit_move_insn (picreg, gen_rtx_REG (Pmode, LR_REGNO));
10130 emit_insn (gen_macho_correct_pic (picreg, picreg, picrtx, tmplabrtx));
10131 }
10132 else
10133 #endif
10134 rs6000_emit_load_toc_table (FALSE);
10135 DONE;
10136 })
10137
10138 ;; Largetoc support
10139 (define_insn "*largetoc_high"
10140 [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
10141 (high:DI
10142 (unspec [(match_operand:DI 1 "" "")
10143 (match_operand:DI 2 "gpc_reg_operand" "b")]
10144 UNSPEC_TOCREL)))]
10145 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10146 "addis %0,%2,%1@toc@ha")
10147
10148 (define_insn "*largetoc_high_aix<mode>"
10149 [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
10150 (high:P
10151 (unspec [(match_operand:P 1 "" "")
10152 (match_operand:P 2 "gpc_reg_operand" "b")]
10153 UNSPEC_TOCREL)))]
10154 "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10155 "addis %0,%1@u(%2)")
10156
10157 (define_insn "*largetoc_high_plus"
10158 [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
10159 (high:DI
10160 (plus:DI
10161 (unspec [(match_operand:DI 1 "" "")
10162 (match_operand:DI 2 "gpc_reg_operand" "b")]
10163 UNSPEC_TOCREL)
10164 (match_operand:DI 3 "add_cint_operand" "n"))))]
10165 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10166 "addis %0,%2,%1+%3@toc@ha")
10167
10168 (define_insn "*largetoc_high_plus_aix<mode>"
10169 [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
10170 (high:P
10171 (plus:P
10172 (unspec [(match_operand:P 1 "" "")
10173 (match_operand:P 2 "gpc_reg_operand" "b")]
10174 UNSPEC_TOCREL)
10175 (match_operand:P 3 "add_cint_operand" "n"))))]
10176 "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10177 "addis %0,%1+%3@u(%2)")
10178
10179 (define_insn "*largetoc_low"
10180 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
10181 (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b")
10182 (match_operand:DI 2 "" "")))]
10183 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10184 "addi %0,%1,%2@l")
10185
10186 (define_insn "*largetoc_low_aix<mode>"
10187 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10188 (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
10189 (match_operand:P 2 "" "")))]
10190 "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10191 "la %0,%2@l(%1)")
10192
10193 (define_insn_and_split "*tocref<mode>"
10194 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
10195 (match_operand:P 1 "small_toc_ref" "R"))]
10196 "TARGET_TOC"
10197 "la %0,%a1"
10198 "&& TARGET_CMODEL != CMODEL_SMALL && reload_completed"
10199 [(set (match_dup 0) (high:P (match_dup 1)))
10200 (set (match_dup 0) (lo_sum:P (match_dup 0) (match_dup 1)))])
10201
10202 ;; Elf specific ways of loading addresses for non-PIC code.
10203 ;; The output of this could be r0, but we make a very strong
10204 ;; preference for a base register because it will usually
10205 ;; be needed there.
10206 (define_insn "elf_high"
10207 [(set (match_operand:SI 0 "gpc_reg_operand" "=b*r")
10208 (high:SI (match_operand 1 "" "")))]
10209 "TARGET_ELF && !TARGET_64BIT && !flag_pic"
10210 "lis %0,%1@ha")
10211
10212 (define_insn "elf_low"
10213 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10214 (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
10215 (match_operand 2 "" "")))]
10216 "TARGET_ELF && !TARGET_64BIT && !flag_pic"
10217 "la %0,%2@l(%1)")
10218
10219 (define_insn "*pltseq_tocsave_<mode>"
10220 [(set (match_operand:P 0 "memory_operand" "=m")
10221 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
10222 (match_operand:P 2 "symbol_ref_operand" "s")
10223 (match_operand:P 3 "" "")]
10224 UNSPEC_PLTSEQ))]
10225 "HAVE_AS_PLTSEQ && TARGET_TLS_MARKERS
10226 && DEFAULT_ABI == ABI_ELFv2"
10227 {
10228 return rs6000_pltseq_template (operands, 0);
10229 })
10230
10231 (define_insn "*pltseq_plt16_ha_<mode>"
10232 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10233 (unspec:P [(match_operand:P 1 "" "")
10234 (match_operand:P 2 "symbol_ref_operand" "s")
10235 (match_operand:P 3 "" "")]
10236 UNSPEC_PLT16_HA))]
10237 "HAVE_AS_PLTSEQ && TARGET_TLS_MARKERS
10238 && (DEFAULT_ABI == ABI_ELFv2 || DEFAULT_ABI == ABI_V4)"
10239 {
10240 return rs6000_pltseq_template (operands, 1);
10241 })
10242
10243 (define_insn "*pltseq_plt16_lo_<mode>"
10244 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10245 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
10246 (match_operand:P 2 "symbol_ref_operand" "s")
10247 (match_operand:P 3 "" "")]
10248 UNSPEC_PLT16_LO))]
10249 "HAVE_AS_PLTSEQ && TARGET_TLS_MARKERS
10250 && (DEFAULT_ABI == ABI_ELFv2 || DEFAULT_ABI == ABI_V4)"
10251 {
10252 return rs6000_pltseq_template (operands, 2);
10253 }
10254 [(set_attr "type" "load")])
10255
10256 (define_insn "*pltseq_mtctr_<mode>"
10257 [(set (match_operand:P 0 "register_operand" "=c")
10258 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "r")
10259 (match_operand:P 2 "symbol_ref_operand" "s")
10260 (match_operand:P 3 "" "")]
10261 UNSPEC_PLTSEQ))]
10262 "HAVE_AS_PLTSEQ && TARGET_TLS_MARKERS
10263 && (DEFAULT_ABI == ABI_ELFv2 || DEFAULT_ABI == ABI_V4)"
10264 {
10265 return rs6000_pltseq_template (operands, 3);
10266 })
10267 \f
10268 ;; Call and call_value insns
10269 ;; For the purposes of expanding calls, Darwin is very similar to SYSV.
10270 (define_expand "call"
10271 [(parallel [(call (mem:SI (match_operand 0 "address_operand"))
10272 (match_operand 1 ""))
10273 (use (match_operand 2 ""))
10274 (clobber (reg:SI LR_REGNO))])]
10275 ""
10276 {
10277 #if TARGET_MACHO
10278 if (MACHOPIC_INDIRECT)
10279 operands[0] = machopic_indirect_call_target (operands[0]);
10280 #endif
10281
10282 gcc_assert (GET_CODE (operands[0]) == MEM);
10283
10284 operands[0] = XEXP (operands[0], 0);
10285
10286 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10287 rs6000_call_aix (NULL_RTX, operands[0], operands[1], operands[2]);
10288 else if (DEFAULT_ABI == ABI_V4)
10289 rs6000_call_sysv (NULL_RTX, operands[0], operands[1], operands[2]);
10290 else if (DEFAULT_ABI == ABI_DARWIN)
10291 rs6000_call_darwin (NULL_RTX, operands[0], operands[1], operands[2]);
10292 else
10293 gcc_unreachable ();
10294
10295 DONE;
10296 })
10297
10298 (define_expand "call_value"
10299 [(parallel [(set (match_operand 0 "")
10300 (call (mem:SI (match_operand 1 "address_operand"))
10301 (match_operand 2 "")))
10302 (use (match_operand 3 ""))
10303 (clobber (reg:SI LR_REGNO))])]
10304 ""
10305 {
10306 #if TARGET_MACHO
10307 if (MACHOPIC_INDIRECT)
10308 operands[1] = machopic_indirect_call_target (operands[1]);
10309 #endif
10310
10311 gcc_assert (GET_CODE (operands[1]) == MEM);
10312
10313 operands[1] = XEXP (operands[1], 0);
10314
10315 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10316 rs6000_call_aix (operands[0], operands[1], operands[2], operands[3]);
10317 else if (DEFAULT_ABI == ABI_V4)
10318 rs6000_call_sysv (operands[0], operands[1], operands[2], operands[3]);
10319 else if (DEFAULT_ABI == ABI_DARWIN)
10320 rs6000_call_darwin (operands[0], operands[1], operands[2], operands[3]);
10321 else
10322 gcc_unreachable ();
10323
10324 DONE;
10325 })
10326
10327 ;; Call to function in current module. No TOC pointer reload needed.
10328 ;; Operand2 is nonzero if we are using the V.4 calling sequence and
10329 ;; either the function was not prototyped, or it was prototyped as a
10330 ;; variable argument function. It is > 0 if FP registers were passed
10331 ;; and < 0 if they were not.
10332
10333 (define_insn "*call_local32"
10334 [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
10335 (match_operand 1))
10336 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10337 (clobber (reg:SI LR_REGNO))]
10338 "(INTVAL (operands[2]) & CALL_LONG) == 0"
10339 {
10340 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10341 output_asm_insn ("crxor 6,6,6", operands);
10342
10343 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10344 output_asm_insn ("creqv 6,6,6", operands);
10345
10346 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z0@local" : "bl %z0";
10347 }
10348 [(set_attr "type" "branch")
10349 (set_attr "length" "4,8")])
10350
10351 (define_insn "*call_local64"
10352 [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
10353 (match_operand 1))
10354 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10355 (clobber (reg:DI LR_REGNO))]
10356 "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
10357 {
10358 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10359 output_asm_insn ("crxor 6,6,6", operands);
10360
10361 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10362 output_asm_insn ("creqv 6,6,6", operands);
10363
10364 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z0@local" : "bl %z0";
10365 }
10366 [(set_attr "type" "branch")
10367 (set_attr "length" "4,8")])
10368
10369 (define_insn "*call_value_local32"
10370 [(set (match_operand 0 "" "")
10371 (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
10372 (match_operand 2)))
10373 (use (match_operand:SI 3 "immediate_operand" "O,n"))
10374 (clobber (reg:SI LR_REGNO))]
10375 "(INTVAL (operands[3]) & CALL_LONG) == 0"
10376 {
10377 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10378 output_asm_insn ("crxor 6,6,6", operands);
10379
10380 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10381 output_asm_insn ("creqv 6,6,6", operands);
10382
10383 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z1@local" : "bl %z1";
10384 }
10385 [(set_attr "type" "branch")
10386 (set_attr "length" "4,8")])
10387
10388
10389 (define_insn "*call_value_local64"
10390 [(set (match_operand 0 "" "")
10391 (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
10392 (match_operand 2)))
10393 (use (match_operand:SI 3 "immediate_operand" "O,n"))
10394 (clobber (reg:DI LR_REGNO))]
10395 "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
10396 {
10397 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10398 output_asm_insn ("crxor 6,6,6", operands);
10399
10400 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10401 output_asm_insn ("creqv 6,6,6", operands);
10402
10403 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z1@local" : "bl %z1";
10404 }
10405 [(set_attr "type" "branch")
10406 (set_attr "length" "4,8")])
10407
10408
10409 ;; A function pointer under System V is just a normal pointer
10410 ;; operands[0] is the function pointer
10411 ;; operands[1] is the tls call arg
10412 ;; operands[2] is the value FUNCTION_ARG returns for the VOID argument
10413 ;; which indicates how to set cr1
10414
10415 (define_insn "*call_indirect_nonlocal_sysv<mode>"
10416 [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X"))
10417 (match_operand 1))
10418 (use (match_operand:SI 2 "immediate_operand" "n,n,n"))
10419 (clobber (reg:P LR_REGNO))]
10420 "DEFAULT_ABI == ABI_V4
10421 || DEFAULT_ABI == ABI_DARWIN"
10422 {
10423 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10424 output_asm_insn ("crxor 6,6,6", operands);
10425
10426 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10427 output_asm_insn ("creqv 6,6,6", operands);
10428
10429 return rs6000_indirect_call_template (operands, 0);
10430 }
10431 [(set_attr "type" "jmpreg")
10432 (set (attr "length")
10433 (cond [(and (and (match_test "!rs6000_speculate_indirect_jumps")
10434 (match_test "which_alternative != 1"))
10435 (match_test "(INTVAL (operands[2]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
10436 (const_string "12")
10437 (ior (and (match_test "!rs6000_speculate_indirect_jumps")
10438 (match_test "which_alternative != 1"))
10439 (match_test "(INTVAL (operands[2]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
10440 (const_string "8")]
10441 (const_string "4")))])
10442
10443 (define_insn_and_split "*call_nonlocal_sysv<mode>"
10444 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
10445 (match_operand 1))
10446 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10447 (clobber (reg:P LR_REGNO))]
10448 "(DEFAULT_ABI == ABI_DARWIN
10449 || (DEFAULT_ABI == ABI_V4
10450 && (INTVAL (operands[2]) & CALL_LONG) == 0))"
10451 {
10452 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10453 output_asm_insn ("crxor 6,6,6", operands);
10454
10455 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10456 output_asm_insn ("creqv 6,6,6", operands);
10457
10458 return rs6000_call_template (operands, 0);
10459 }
10460 "DEFAULT_ABI == ABI_V4
10461 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0])
10462 && (INTVAL (operands[2]) & CALL_LONG) == 0"
10463 [(parallel [(call (mem:SI (match_dup 0))
10464 (match_dup 1))
10465 (use (match_dup 2))
10466 (use (match_dup 3))
10467 (clobber (reg:SI LR_REGNO))])]
10468 {
10469 operands[3] = pic_offset_table_rtx;
10470 }
10471 [(set_attr "type" "branch,branch")
10472 (set_attr "length" "4,8")])
10473
10474 (define_insn "*call_nonlocal_sysv_secure<mode>"
10475 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
10476 (match_operand 1))
10477 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10478 (use (match_operand:SI 3 "register_operand" "r,r"))
10479 (clobber (reg:P LR_REGNO))]
10480 "(DEFAULT_ABI == ABI_V4
10481 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0])
10482 && (INTVAL (operands[2]) & CALL_LONG) == 0)"
10483 {
10484 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10485 output_asm_insn ("crxor 6,6,6", operands);
10486
10487 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10488 output_asm_insn ("creqv 6,6,6", operands);
10489
10490 return rs6000_call_template (operands, 0);
10491 }
10492 [(set_attr "type" "branch,branch")
10493 (set_attr "length" "4,8")])
10494
10495 (define_insn "*call_value_indirect_nonlocal_sysv<mode>"
10496 [(set (match_operand 0 "" "")
10497 (call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X"))
10498 (match_operand 2)))
10499 (use (match_operand:SI 3 "immediate_operand" "n,n,n"))
10500 (clobber (reg:P LR_REGNO))]
10501 "DEFAULT_ABI == ABI_V4
10502 || DEFAULT_ABI == ABI_DARWIN"
10503 {
10504 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10505 output_asm_insn ("crxor 6,6,6", operands);
10506
10507 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10508 output_asm_insn ("creqv 6,6,6", operands);
10509
10510 return rs6000_indirect_call_template (operands, 1);
10511 }
10512 [(set_attr "type" "jmpreg")
10513 (set (attr "length")
10514 (cond [(and (and (match_test "!rs6000_speculate_indirect_jumps")
10515 (match_test "which_alternative != 1"))
10516 (match_test "(INTVAL (operands[3]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
10517 (const_string "12")
10518 (ior (and (match_test "!rs6000_speculate_indirect_jumps")
10519 (match_test "which_alternative != 1"))
10520 (match_test "(INTVAL (operands[3]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
10521 (const_string "8")]
10522 (const_string "4")))])
10523
10524 (define_insn_and_split "*call_value_nonlocal_sysv<mode>"
10525 [(set (match_operand 0 "" "")
10526 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
10527 (match_operand 2)))
10528 (use (match_operand:SI 3 "immediate_operand" "O,n"))
10529 (clobber (reg:P LR_REGNO))]
10530 "(DEFAULT_ABI == ABI_DARWIN
10531 || (DEFAULT_ABI == ABI_V4
10532 && (INTVAL (operands[3]) & CALL_LONG) == 0))"
10533 {
10534 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10535 output_asm_insn ("crxor 6,6,6", operands);
10536
10537 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10538 output_asm_insn ("creqv 6,6,6", operands);
10539
10540 return rs6000_call_template (operands, 1);
10541 }
10542 "DEFAULT_ABI == ABI_V4
10543 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1])
10544 && (INTVAL (operands[3]) & CALL_LONG) == 0"
10545 [(parallel [(set (match_dup 0)
10546 (call (mem:SI (match_dup 1))
10547 (match_dup 2)))
10548 (use (match_dup 3))
10549 (use (match_dup 4))
10550 (clobber (reg:SI LR_REGNO))])]
10551 {
10552 operands[4] = pic_offset_table_rtx;
10553 }
10554 [(set_attr "type" "branch,branch")
10555 (set_attr "length" "4,8")])
10556
10557 (define_insn "*call_value_nonlocal_sysv_secure<mode>"
10558 [(set (match_operand 0 "" "")
10559 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
10560 (match_operand 2)))
10561 (use (match_operand:SI 3 "immediate_operand" "O,n"))
10562 (use (match_operand:SI 4 "register_operand" "r,r"))
10563 (clobber (reg:P LR_REGNO))]
10564 "(DEFAULT_ABI == ABI_V4
10565 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1])
10566 && (INTVAL (operands[3]) & CALL_LONG) == 0)"
10567 {
10568 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10569 output_asm_insn ("crxor 6,6,6", operands);
10570
10571 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10572 output_asm_insn ("creqv 6,6,6", operands);
10573
10574 return rs6000_call_template (operands, 1);
10575 }
10576 [(set_attr "type" "branch,branch")
10577 (set_attr "length" "4,8")])
10578
10579
10580 ;; Call to AIX abi function in the same module.
10581
10582 (define_insn "*call_local_aix<mode>"
10583 [(call (mem:SI (match_operand:P 0 "current_file_function_operand" "s"))
10584 (match_operand 1))
10585 (clobber (reg:P LR_REGNO))]
10586 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10587 "bl %z0"
10588 [(set_attr "type" "branch")])
10589
10590 (define_insn "*call_value_local_aix<mode>"
10591 [(set (match_operand 0 "" "")
10592 (call (mem:SI (match_operand:P 1 "current_file_function_operand" "s"))
10593 (match_operand 2)))
10594 (clobber (reg:P LR_REGNO))]
10595 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10596 "bl %z1"
10597 [(set_attr "type" "branch")])
10598
10599 ;; Call to AIX abi function which may be in another module.
10600 ;; Restore the TOC pointer (r2) after the call.
10601
10602 (define_insn "*call_nonlocal_aix<mode>"
10603 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s"))
10604 (match_operand 1))
10605 (clobber (reg:P LR_REGNO))]
10606 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10607 {
10608 return rs6000_call_template (operands, 0);
10609 }
10610 [(set_attr "type" "branch")
10611 (set_attr "length" "8")])
10612
10613 (define_insn "*call_value_nonlocal_aix<mode>"
10614 [(set (match_operand 0 "" "")
10615 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s"))
10616 (match_operand 2)))
10617 (clobber (reg:P LR_REGNO))]
10618 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10619 {
10620 return rs6000_call_template (operands, 1);
10621 }
10622 [(set_attr "type" "branch")
10623 (set_attr "length" "8")])
10624
10625 ;; Call to indirect functions with the AIX abi using a 3 word descriptor.
10626 ;; Operand0 is the addresss of the function to call
10627 ;; Operand2 is the location in the function descriptor to load r2 from
10628 ;; Operand3 is the offset of the stack location holding the current TOC pointer
10629
10630 (define_insn "*call_indirect_aix<mode>"
10631 [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X"))
10632 (match_operand 1))
10633 (use (match_operand:P 2 "memory_operand" "<ptrm>,<ptrm>,<ptrm>"))
10634 (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 3 "const_int_operand" "n,n,n")] UNSPEC_TOCSLOT))
10635 (clobber (reg:P LR_REGNO))]
10636 "DEFAULT_ABI == ABI_AIX"
10637 {
10638 return rs6000_indirect_call_template (operands, 0);
10639 }
10640 [(set_attr "type" "jmpreg")
10641 (set (attr "length")
10642 (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
10643 (match_test "which_alternative != 1"))
10644 (const_string "16")
10645 (const_string "12")))])
10646
10647 (define_insn "*call_value_indirect_aix<mode>"
10648 [(set (match_operand 0 "" "")
10649 (call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X"))
10650 (match_operand 2)))
10651 (use (match_operand:P 3 "memory_operand" "<ptrm>,<ptrm>,<ptrm>"))
10652 (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 4 "const_int_operand" "n,n,n")] UNSPEC_TOCSLOT))
10653 (clobber (reg:P LR_REGNO))]
10654 "DEFAULT_ABI == ABI_AIX"
10655 {
10656 return rs6000_indirect_call_template (operands, 1);
10657 }
10658 [(set_attr "type" "jmpreg")
10659 (set (attr "length")
10660 (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
10661 (match_test "which_alternative != 1"))
10662 (const_string "16")
10663 (const_string "12")))])
10664
10665 ;; Call to indirect functions with the ELFv2 ABI.
10666 ;; Operand0 is the addresss of the function to call
10667 ;; Operand2 is the offset of the stack location holding the current TOC pointer
10668
10669 (define_insn "*call_indirect_elfv2<mode>"
10670 [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X"))
10671 (match_operand 1))
10672 (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 2 "const_int_operand" "n,n,n")] UNSPEC_TOCSLOT))
10673 (clobber (reg:P LR_REGNO))]
10674 "DEFAULT_ABI == ABI_ELFv2"
10675 {
10676 return rs6000_indirect_call_template (operands, 0);
10677 }
10678 [(set_attr "type" "jmpreg")
10679 (set (attr "length")
10680 (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
10681 (match_test "which_alternative != 1"))
10682 (const_string "12")
10683 (const_string "8")))])
10684
10685 (define_insn "*call_value_indirect_elfv2<mode>"
10686 [(set (match_operand 0 "" "")
10687 (call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X"))
10688 (match_operand 2)))
10689 (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 3 "const_int_operand" "n,n,n")] UNSPEC_TOCSLOT))
10690 (clobber (reg:P LR_REGNO))]
10691 "DEFAULT_ABI == ABI_ELFv2"
10692 {
10693 return rs6000_indirect_call_template (operands, 1);
10694 }
10695 [(set_attr "type" "jmpreg")
10696 (set (attr "length")
10697 (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
10698 (match_test "which_alternative != 1"))
10699 (const_string "12")
10700 (const_string "8")))])
10701
10702 ;; Call subroutine returning any type.
10703 (define_expand "untyped_call"
10704 [(parallel [(call (match_operand 0 "")
10705 (const_int 0))
10706 (match_operand 1 "")
10707 (match_operand 2 "")])]
10708 ""
10709 {
10710 int i;
10711
10712 emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
10713
10714 for (i = 0; i < XVECLEN (operands[2], 0); i++)
10715 {
10716 rtx set = XVECEXP (operands[2], 0, i);
10717 emit_move_insn (SET_DEST (set), SET_SRC (set));
10718 }
10719
10720 /* The optimizer does not know that the call sets the function value
10721 registers we stored in the result block. We avoid problems by
10722 claiming that all hard registers are used and clobbered at this
10723 point. */
10724 emit_insn (gen_blockage ());
10725
10726 DONE;
10727 })
10728
10729 ;; sibling call patterns
10730 (define_expand "sibcall"
10731 [(parallel [(call (mem:SI (match_operand 0 "address_operand"))
10732 (match_operand 1 ""))
10733 (use (match_operand 2 ""))
10734 (simple_return)])]
10735 ""
10736 {
10737 #if TARGET_MACHO
10738 if (MACHOPIC_INDIRECT)
10739 operands[0] = machopic_indirect_call_target (operands[0]);
10740 #endif
10741
10742 gcc_assert (GET_CODE (operands[0]) == MEM);
10743 gcc_assert (GET_CODE (operands[1]) == CONST_INT);
10744
10745 operands[0] = XEXP (operands[0], 0);
10746
10747 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10748 rs6000_sibcall_aix (NULL_RTX, operands[0], operands[1], operands[2]);
10749 else if (DEFAULT_ABI == ABI_V4)
10750 rs6000_sibcall_sysv (NULL_RTX, operands[0], operands[1], operands[2]);
10751 else if (DEFAULT_ABI == ABI_DARWIN)
10752 rs6000_sibcall_darwin (NULL_RTX, operands[0], operands[1], operands[2]);
10753 else
10754 gcc_unreachable ();
10755
10756 DONE;
10757 })
10758
10759 (define_expand "sibcall_value"
10760 [(parallel [(set (match_operand 0 "register_operand")
10761 (call (mem:SI (match_operand 1 "address_operand"))
10762 (match_operand 2 "")))
10763 (use (match_operand 3 ""))
10764 (simple_return)])]
10765 ""
10766 {
10767 #if TARGET_MACHO
10768 if (MACHOPIC_INDIRECT)
10769 operands[1] = machopic_indirect_call_target (operands[1]);
10770 #endif
10771
10772 gcc_assert (GET_CODE (operands[1]) == MEM);
10773 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10774
10775 operands[1] = XEXP (operands[1], 0);
10776
10777 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10778 rs6000_sibcall_aix (operands[0], operands[1], operands[2], operands[3]);
10779 else if (DEFAULT_ABI == ABI_V4)
10780 rs6000_sibcall_sysv (operands[0], operands[1], operands[2], operands[3]);
10781 else if (DEFAULT_ABI == ABI_DARWIN)
10782 rs6000_sibcall_darwin (operands[0], operands[1], operands[2], operands[3]);
10783 else
10784 gcc_unreachable ();
10785
10786 DONE;
10787 })
10788
10789 (define_insn "*sibcall_local32"
10790 [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
10791 (match_operand 1))
10792 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10793 (simple_return)]
10794 "(INTVAL (operands[2]) & CALL_LONG) == 0"
10795 {
10796 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10797 output_asm_insn ("crxor 6,6,6", operands);
10798
10799 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10800 output_asm_insn ("creqv 6,6,6", operands);
10801
10802 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z0@local" : "b %z0";
10803 }
10804 [(set_attr "type" "branch")
10805 (set_attr "length" "4,8")])
10806
10807 (define_insn "*sibcall_local64"
10808 [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
10809 (match_operand 1))
10810 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10811 (simple_return)]
10812 "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
10813 {
10814 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10815 output_asm_insn ("crxor 6,6,6", operands);
10816
10817 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10818 output_asm_insn ("creqv 6,6,6", operands);
10819
10820 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z0@local" : "b %z0";
10821 }
10822 [(set_attr "type" "branch")
10823 (set_attr "length" "4,8")])
10824
10825 (define_insn "*sibcall_value_local32"
10826 [(set (match_operand 0 "" "")
10827 (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
10828 (match_operand 2)))
10829 (use (match_operand:SI 3 "immediate_operand" "O,n"))
10830 (simple_return)]
10831 "(INTVAL (operands[3]) & CALL_LONG) == 0"
10832 {
10833 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10834 output_asm_insn ("crxor 6,6,6", operands);
10835
10836 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10837 output_asm_insn ("creqv 6,6,6", operands);
10838
10839 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z1@local" : "b %z1";
10840 }
10841 [(set_attr "type" "branch")
10842 (set_attr "length" "4,8")])
10843
10844 (define_insn "*sibcall_value_local64"
10845 [(set (match_operand 0 "" "")
10846 (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
10847 (match_operand 2)))
10848 (use (match_operand:SI 3 "immediate_operand" "O,n"))
10849 (simple_return)]
10850 "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
10851 {
10852 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10853 output_asm_insn ("crxor 6,6,6", operands);
10854
10855 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10856 output_asm_insn ("creqv 6,6,6", operands);
10857
10858 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z1@local" : "b %z1";
10859 }
10860 [(set_attr "type" "branch")
10861 (set_attr "length" "4,8")])
10862
10863 (define_insn "*sibcall_indirect_nonlocal_sysv<mode>"
10864 [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X"))
10865 (match_operand 1))
10866 (use (match_operand:SI 2 "immediate_operand" "n,n,n"))
10867 (simple_return)]
10868 "DEFAULT_ABI == ABI_V4
10869 || DEFAULT_ABI == ABI_DARWIN"
10870 {
10871 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10872 output_asm_insn ("crxor 6,6,6", operands);
10873
10874 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10875 output_asm_insn ("creqv 6,6,6", operands);
10876
10877 return rs6000_indirect_sibcall_template (operands, 0);
10878 }
10879 [(set_attr "type" "jmpreg")
10880 (set (attr "length")
10881 (cond [(and (and (match_test "!rs6000_speculate_indirect_jumps")
10882 (match_test "which_alternative != 1"))
10883 (match_test "(INTVAL (operands[2]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
10884 (const_string "12")
10885 (ior (and (match_test "!rs6000_speculate_indirect_jumps")
10886 (match_test "which_alternative != 1"))
10887 (match_test "(INTVAL (operands[2]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
10888 (const_string "8")]
10889 (const_string "4")))])
10890
10891 (define_insn "*sibcall_nonlocal_sysv<mode>"
10892 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
10893 (match_operand 1))
10894 (use (match_operand 2 "immediate_operand" "O,n"))
10895 (simple_return)]
10896 "(DEFAULT_ABI == ABI_DARWIN
10897 || DEFAULT_ABI == ABI_V4)
10898 && (INTVAL (operands[2]) & CALL_LONG) == 0"
10899 {
10900 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10901 output_asm_insn ("crxor 6,6,6", operands);
10902
10903 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10904 output_asm_insn ("creqv 6,6,6", operands);
10905
10906 return rs6000_sibcall_template (operands, 0);
10907 }
10908 [(set_attr "type" "branch")
10909 (set_attr "length" "4,8")])
10910
10911 (define_insn "*sibcall_value_indirect_nonlocal_sysv<mode>"
10912 [(set (match_operand 0 "" "")
10913 (call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X"))
10914 (match_operand 2)))
10915 (use (match_operand:SI 3 "immediate_operand" "n,n,n"))
10916 (simple_return)]
10917 "DEFAULT_ABI == ABI_V4
10918 || DEFAULT_ABI == ABI_DARWIN"
10919 {
10920 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10921 output_asm_insn ("crxor 6,6,6", operands);
10922
10923 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10924 output_asm_insn ("creqv 6,6,6", operands);
10925
10926 return rs6000_indirect_sibcall_template (operands, 1);
10927 }
10928 [(set_attr "type" "jmpreg")
10929 (set (attr "length")
10930 (cond [(and (and (match_test "!rs6000_speculate_indirect_jumps")
10931 (match_test "which_alternative != 1"))
10932 (match_test "(INTVAL (operands[3]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
10933 (const_string "12")
10934 (ior (and (match_test "!rs6000_speculate_indirect_jumps")
10935 (match_test "which_alternative != 1"))
10936 (match_test "(INTVAL (operands[3]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
10937 (const_string "8")]
10938 (const_string "4")))])
10939
10940 (define_insn "*sibcall_value_nonlocal_sysv<mode>"
10941 [(set (match_operand 0 "" "")
10942 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
10943 (match_operand 2)))
10944 (use (match_operand:SI 3 "immediate_operand" "O,n"))
10945 (simple_return)]
10946 "(DEFAULT_ABI == ABI_DARWIN
10947 || DEFAULT_ABI == ABI_V4)
10948 && (INTVAL (operands[3]) & CALL_LONG) == 0"
10949 {
10950 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10951 output_asm_insn ("crxor 6,6,6", operands);
10952
10953 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10954 output_asm_insn ("creqv 6,6,6", operands);
10955
10956 return rs6000_sibcall_template (operands, 1);
10957 }
10958 [(set_attr "type" "branch")
10959 (set_attr "length" "4,8")])
10960
10961 ;; AIX ABI sibling call patterns.
10962
10963 (define_insn "*sibcall_aix<mode>"
10964 [(call (mem:SI (match_operand:P 0 "call_operand" "s,c"))
10965 (match_operand 1))
10966 (simple_return)]
10967 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10968 {
10969 if (which_alternative == 0)
10970 return rs6000_sibcall_template (operands, 0);
10971 else
10972 return "b%T0";
10973 }
10974 [(set_attr "type" "branch")])
10975
10976 (define_insn "*sibcall_value_aix<mode>"
10977 [(set (match_operand 0 "" "")
10978 (call (mem:SI (match_operand:P 1 "call_operand" "s,c"))
10979 (match_operand 2)))
10980 (simple_return)]
10981 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10982 {
10983 if (which_alternative == 0)
10984 return rs6000_sibcall_template (operands, 1);
10985 else
10986 return "b%T1";
10987 }
10988 [(set_attr "type" "branch")])
10989
10990 (define_expand "sibcall_epilogue"
10991 [(use (const_int 0))]
10992 ""
10993 {
10994 if (!TARGET_SCHED_PROLOG)
10995 emit_insn (gen_blockage ());
10996 rs6000_emit_epilogue (TRUE);
10997 DONE;
10998 })
10999
11000 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11001 ;; all of memory. This blocks insns from being moved across this point.
11002
11003 (define_insn "blockage"
11004 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCK)]
11005 ""
11006 ""
11007 [(set_attr "length" "0")])
11008
11009 (define_expand "probe_stack_address"
11010 [(use (match_operand 0 "address_operand"))]
11011 ""
11012 {
11013 operands[0] = gen_rtx_MEM (Pmode, operands[0]);
11014 MEM_VOLATILE_P (operands[0]) = 1;
11015
11016 if (TARGET_64BIT)
11017 emit_insn (gen_probe_stack_di (operands[0]));
11018 else
11019 emit_insn (gen_probe_stack_si (operands[0]));
11020 DONE;
11021 })
11022
11023 (define_insn "probe_stack_<mode>"
11024 [(set (match_operand:P 0 "memory_operand" "=m")
11025 (unspec:P [(const_int 0)] UNSPEC_PROBE_STACK))]
11026 ""
11027 {
11028 operands[1] = gen_rtx_REG (Pmode, 0);
11029 return "st<wd>%U0%X0 %1,%0";
11030 }
11031 [(set_attr "type" "store")
11032 (set (attr "update")
11033 (if_then_else (match_operand 0 "update_address_mem")
11034 (const_string "yes")
11035 (const_string "no")))
11036 (set (attr "indexed")
11037 (if_then_else (match_operand 0 "indexed_address_mem")
11038 (const_string "yes")
11039 (const_string "no")))])
11040
11041 (define_insn "probe_stack_range<P:mode>"
11042 [(set (match_operand:P 0 "register_operand" "=&r")
11043 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
11044 (match_operand:P 2 "register_operand" "r")
11045 (match_operand:P 3 "register_operand" "r")]
11046 UNSPECV_PROBE_STACK_RANGE))]
11047 ""
11048 "* return output_probe_stack_range (operands[0], operands[2], operands[3]);"
11049 [(set_attr "type" "three")])
11050 \f
11051 ;; Compare insns are next. Note that the RS/6000 has two types of compares,
11052 ;; signed & unsigned, and one type of branch.
11053 ;;
11054 ;; Start with the DEFINE_EXPANDs to generate the rtl for compares, scc
11055 ;; insns, and branches.
11056
11057 (define_expand "cbranch<mode>4"
11058 [(use (match_operator 0 "comparison_operator"
11059 [(match_operand:GPR 1 "gpc_reg_operand")
11060 (match_operand:GPR 2 "reg_or_short_operand")]))
11061 (use (match_operand 3))]
11062 ""
11063 {
11064 /* Take care of the possibility that operands[2] might be negative but
11065 this might be a logical operation. That insn doesn't exist. */
11066 if (GET_CODE (operands[2]) == CONST_INT
11067 && INTVAL (operands[2]) < 0)
11068 {
11069 operands[2] = force_reg (<MODE>mode, operands[2]);
11070 operands[0] = gen_rtx_fmt_ee (GET_CODE (operands[0]),
11071 GET_MODE (operands[0]),
11072 operands[1], operands[2]);
11073 }
11074
11075 rs6000_emit_cbranch (<MODE>mode, operands);
11076 DONE;
11077 })
11078
11079 (define_expand "cbranch<mode>4"
11080 [(use (match_operator 0 "comparison_operator"
11081 [(match_operand:FP 1 "gpc_reg_operand")
11082 (match_operand:FP 2 "gpc_reg_operand")]))
11083 (use (match_operand 3))]
11084 ""
11085 {
11086 rs6000_emit_cbranch (<MODE>mode, operands);
11087 DONE;
11088 })
11089
11090 (define_expand "cstore<mode>4_signed"
11091 [(use (match_operator 1 "signed_comparison_operator"
11092 [(match_operand:P 2 "gpc_reg_operand")
11093 (match_operand:P 3 "gpc_reg_operand")]))
11094 (clobber (match_operand:P 0 "gpc_reg_operand"))]
11095 ""
11096 {
11097 enum rtx_code cond_code = GET_CODE (operands[1]);
11098
11099 rtx op0 = operands[0];
11100 rtx op1 = operands[2];
11101 rtx op2 = operands[3];
11102
11103 if (cond_code == GE || cond_code == LT)
11104 {
11105 cond_code = swap_condition (cond_code);
11106 std::swap (op1, op2);
11107 }
11108
11109 rtx tmp1 = gen_reg_rtx (<MODE>mode);
11110 rtx tmp2 = gen_reg_rtx (<MODE>mode);
11111 rtx tmp3 = gen_reg_rtx (<MODE>mode);
11112
11113 int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11114 emit_insn (gen_lshr<mode>3 (tmp1, op1, GEN_INT (sh)));
11115 emit_insn (gen_ashr<mode>3 (tmp2, op2, GEN_INT (sh)));
11116
11117 emit_insn (gen_subf<mode>3_carry (tmp3, op1, op2));
11118
11119 if (cond_code == LE)
11120 emit_insn (gen_add<mode>3_carry_in (op0, tmp1, tmp2));
11121 else
11122 {
11123 rtx tmp4 = gen_reg_rtx (<MODE>mode);
11124 emit_insn (gen_add<mode>3_carry_in (tmp4, tmp1, tmp2));
11125 emit_insn (gen_xor<mode>3 (op0, tmp4, const1_rtx));
11126 }
11127
11128 DONE;
11129 })
11130
11131 (define_expand "cstore<mode>4_unsigned"
11132 [(use (match_operator 1 "unsigned_comparison_operator"
11133 [(match_operand:P 2 "gpc_reg_operand")
11134 (match_operand:P 3 "reg_or_short_operand")]))
11135 (clobber (match_operand:P 0 "gpc_reg_operand"))]
11136 ""
11137 {
11138 enum rtx_code cond_code = GET_CODE (operands[1]);
11139
11140 rtx op0 = operands[0];
11141 rtx op1 = operands[2];
11142 rtx op2 = operands[3];
11143
11144 if (cond_code == GEU || cond_code == LTU)
11145 {
11146 cond_code = swap_condition (cond_code);
11147 std::swap (op1, op2);
11148 }
11149
11150 if (!gpc_reg_operand (op1, <MODE>mode))
11151 op1 = force_reg (<MODE>mode, op1);
11152 if (!reg_or_short_operand (op2, <MODE>mode))
11153 op2 = force_reg (<MODE>mode, op2);
11154
11155 rtx tmp = gen_reg_rtx (<MODE>mode);
11156 rtx tmp2 = gen_reg_rtx (<MODE>mode);
11157
11158 emit_insn (gen_subf<mode>3_carry (tmp, op1, op2));
11159 emit_insn (gen_subf<mode>3_carry_in_xx (tmp2));
11160
11161 if (cond_code == LEU)
11162 emit_insn (gen_add<mode>3 (op0, tmp2, const1_rtx));
11163 else
11164 emit_insn (gen_neg<mode>2 (op0, tmp2));
11165
11166 DONE;
11167 })
11168
11169 (define_expand "cstore_si_as_di"
11170 [(use (match_operator 1 "unsigned_comparison_operator"
11171 [(match_operand:SI 2 "gpc_reg_operand")
11172 (match_operand:SI 3 "reg_or_short_operand")]))
11173 (clobber (match_operand:SI 0 "gpc_reg_operand"))]
11174 ""
11175 {
11176 int uns_flag = unsigned_comparison_operator (operands[1], VOIDmode) ? 1 : 0;
11177 enum rtx_code cond_code = signed_condition (GET_CODE (operands[1]));
11178
11179 operands[2] = force_reg (SImode, operands[2]);
11180 operands[3] = force_reg (SImode, operands[3]);
11181 rtx op1 = gen_reg_rtx (DImode);
11182 rtx op2 = gen_reg_rtx (DImode);
11183 convert_move (op1, operands[2], uns_flag);
11184 convert_move (op2, operands[3], uns_flag);
11185
11186 if (cond_code == GT || cond_code == LE)
11187 {
11188 cond_code = swap_condition (cond_code);
11189 std::swap (op1, op2);
11190 }
11191
11192 rtx tmp = gen_reg_rtx (DImode);
11193 rtx tmp2 = gen_reg_rtx (DImode);
11194 emit_insn (gen_subdi3 (tmp, op1, op2));
11195 emit_insn (gen_lshrdi3 (tmp2, tmp, GEN_INT (63)));
11196
11197 rtx tmp3;
11198 switch (cond_code)
11199 {
11200 default:
11201 gcc_unreachable ();
11202 case LT:
11203 tmp3 = tmp2;
11204 break;
11205 case GE:
11206 tmp3 = gen_reg_rtx (DImode);
11207 emit_insn (gen_xordi3 (tmp3, tmp2, const1_rtx));
11208 break;
11209 }
11210
11211 convert_move (operands[0], tmp3, 1);
11212
11213 DONE;
11214 })
11215
11216 (define_expand "cstore<mode>4_signed_imm"
11217 [(use (match_operator 1 "signed_comparison_operator"
11218 [(match_operand:GPR 2 "gpc_reg_operand")
11219 (match_operand:GPR 3 "immediate_operand")]))
11220 (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11221 ""
11222 {
11223 bool invert = false;
11224
11225 enum rtx_code cond_code = GET_CODE (operands[1]);
11226
11227 rtx op0 = operands[0];
11228 rtx op1 = operands[2];
11229 HOST_WIDE_INT val = INTVAL (operands[3]);
11230
11231 if (cond_code == GE || cond_code == GT)
11232 {
11233 cond_code = reverse_condition (cond_code);
11234 invert = true;
11235 }
11236
11237 if (cond_code == LE)
11238 val++;
11239
11240 rtx tmp = gen_reg_rtx (<MODE>mode);
11241 emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
11242 rtx x = gen_reg_rtx (<MODE>mode);
11243 if (val < 0)
11244 emit_insn (gen_and<mode>3 (x, op1, tmp));
11245 else
11246 emit_insn (gen_ior<mode>3 (x, op1, tmp));
11247
11248 if (invert)
11249 {
11250 rtx tmp = gen_reg_rtx (<MODE>mode);
11251 emit_insn (gen_one_cmpl<mode>2 (tmp, x));
11252 x = tmp;
11253 }
11254
11255 int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11256 emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
11257
11258 DONE;
11259 })
11260
11261 (define_expand "cstore<mode>4_unsigned_imm"
11262 [(use (match_operator 1 "unsigned_comparison_operator"
11263 [(match_operand:GPR 2 "gpc_reg_operand")
11264 (match_operand:GPR 3 "immediate_operand")]))
11265 (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11266 ""
11267 {
11268 bool invert = false;
11269
11270 enum rtx_code cond_code = GET_CODE (operands[1]);
11271
11272 rtx op0 = operands[0];
11273 rtx op1 = operands[2];
11274 HOST_WIDE_INT val = INTVAL (operands[3]);
11275
11276 if (cond_code == GEU || cond_code == GTU)
11277 {
11278 cond_code = reverse_condition (cond_code);
11279 invert = true;
11280 }
11281
11282 if (cond_code == LEU)
11283 val++;
11284
11285 rtx tmp = gen_reg_rtx (<MODE>mode);
11286 rtx tmp2 = gen_reg_rtx (<MODE>mode);
11287 emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
11288 emit_insn (gen_one_cmpl<mode>2 (tmp2, op1));
11289 rtx x = gen_reg_rtx (<MODE>mode);
11290 if (val < 0)
11291 emit_insn (gen_ior<mode>3 (x, tmp, tmp2));
11292 else
11293 emit_insn (gen_and<mode>3 (x, tmp, tmp2));
11294
11295 if (invert)
11296 {
11297 rtx tmp = gen_reg_rtx (<MODE>mode);
11298 emit_insn (gen_one_cmpl<mode>2 (tmp, x));
11299 x = tmp;
11300 }
11301
11302 int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11303 emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
11304
11305 DONE;
11306 })
11307
11308 (define_expand "cstore<mode>4"
11309 [(use (match_operator 1 "comparison_operator"
11310 [(match_operand:GPR 2 "gpc_reg_operand")
11311 (match_operand:GPR 3 "reg_or_short_operand")]))
11312 (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11313 ""
11314 {
11315 /* Expanding EQ and NE directly to some machine instructions does not help
11316 but does hurt combine. So don't. */
11317 if (GET_CODE (operands[1]) == EQ)
11318 emit_insn (gen_eq<mode>3 (operands[0], operands[2], operands[3]));
11319 else if (<MODE>mode == Pmode
11320 && GET_CODE (operands[1]) == NE)
11321 emit_insn (gen_ne<mode>3 (operands[0], operands[2], operands[3]));
11322 else if (GET_CODE (operands[1]) == NE)
11323 {
11324 rtx tmp = gen_reg_rtx (<MODE>mode);
11325 emit_insn (gen_eq<mode>3 (tmp, operands[2], operands[3]));
11326 emit_insn (gen_xor<mode>3 (operands[0], tmp, const1_rtx));
11327 }
11328
11329 /* If ISEL is fast, expand to it. */
11330 else if (TARGET_ISEL)
11331 rs6000_emit_int_cmove (operands[0], operands[1], const1_rtx, const0_rtx);
11332
11333 /* Expanding the unsigned comparisons helps a lot: all the neg_ltu
11334 etc. combinations magically work out just right. */
11335 else if (<MODE>mode == Pmode
11336 && unsigned_comparison_operator (operands[1], VOIDmode))
11337 emit_insn (gen_cstore<mode>4_unsigned (operands[0], operands[1],
11338 operands[2], operands[3]));
11339
11340 /* For comparisons smaller than Pmode we can cheaply do things in Pmode. */
11341 else if (<MODE>mode == SImode && Pmode == DImode)
11342 emit_insn (gen_cstore_si_as_di (operands[0], operands[1],
11343 operands[2], operands[3]));
11344
11345 /* For signed comparisons against a constant, we can do some simple
11346 bit-twiddling. */
11347 else if (signed_comparison_operator (operands[1], VOIDmode)
11348 && CONST_INT_P (operands[3]))
11349 emit_insn (gen_cstore<mode>4_signed_imm (operands[0], operands[1],
11350 operands[2], operands[3]));
11351
11352 /* And similarly for unsigned comparisons. */
11353 else if (unsigned_comparison_operator (operands[1], VOIDmode)
11354 && CONST_INT_P (operands[3]))
11355 emit_insn (gen_cstore<mode>4_unsigned_imm (operands[0], operands[1],
11356 operands[2], operands[3]));
11357
11358 /* We also do not want to use mfcr for signed comparisons. */
11359 else if (<MODE>mode == Pmode
11360 && signed_comparison_operator (operands[1], VOIDmode))
11361 emit_insn (gen_cstore<mode>4_signed (operands[0], operands[1],
11362 operands[2], operands[3]));
11363
11364 /* Everything else, use the mfcr brute force. */
11365 else
11366 rs6000_emit_sCOND (<MODE>mode, operands);
11367
11368 DONE;
11369 })
11370
11371 (define_expand "cstore<mode>4"
11372 [(use (match_operator 1 "comparison_operator"
11373 [(match_operand:FP 2 "gpc_reg_operand")
11374 (match_operand:FP 3 "gpc_reg_operand")]))
11375 (clobber (match_operand:SI 0 "gpc_reg_operand"))]
11376 ""
11377 {
11378 rs6000_emit_sCOND (<MODE>mode, operands);
11379 DONE;
11380 })
11381
11382
11383 (define_expand "stack_protect_set"
11384 [(match_operand 0 "memory_operand")
11385 (match_operand 1 "memory_operand")]
11386 ""
11387 {
11388 if (rs6000_stack_protector_guard == SSP_TLS)
11389 {
11390 rtx reg = gen_rtx_REG (Pmode, rs6000_stack_protector_guard_reg);
11391 rtx offset = GEN_INT (rs6000_stack_protector_guard_offset);
11392 rtx addr = gen_rtx_PLUS (Pmode, reg, offset);
11393 operands[1] = gen_rtx_MEM (Pmode, addr);
11394 }
11395
11396 if (TARGET_64BIT)
11397 emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
11398 else
11399 emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
11400
11401 DONE;
11402 })
11403
11404 (define_insn "stack_protect_setsi"
11405 [(set (match_operand:SI 0 "memory_operand" "=m")
11406 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
11407 (set (match_scratch:SI 2 "=&r") (const_int 0))]
11408 "TARGET_32BIT"
11409 "lwz%U1%X1 %2,%1\;stw%U0%X0 %2,%0\;li %2,0"
11410 [(set_attr "type" "three")
11411 (set_attr "length" "12")])
11412
11413 (define_insn "stack_protect_setdi"
11414 [(set (match_operand:DI 0 "memory_operand" "=Y")
11415 (unspec:DI [(match_operand:DI 1 "memory_operand" "Y")] UNSPEC_SP_SET))
11416 (set (match_scratch:DI 2 "=&r") (const_int 0))]
11417 "TARGET_64BIT"
11418 "ld%U1%X1 %2,%1\;std%U0%X0 %2,%0\;li %2,0"
11419 [(set_attr "type" "three")
11420 (set_attr "length" "12")])
11421
11422 (define_expand "stack_protect_test"
11423 [(match_operand 0 "memory_operand")
11424 (match_operand 1 "memory_operand")
11425 (match_operand 2 "")]
11426 ""
11427 {
11428 rtx guard = operands[1];
11429
11430 if (rs6000_stack_protector_guard == SSP_TLS)
11431 {
11432 rtx reg = gen_rtx_REG (Pmode, rs6000_stack_protector_guard_reg);
11433 rtx offset = GEN_INT (rs6000_stack_protector_guard_offset);
11434 rtx addr = gen_rtx_PLUS (Pmode, reg, offset);
11435 guard = gen_rtx_MEM (Pmode, addr);
11436 }
11437
11438 operands[1] = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, guard), UNSPEC_SP_TEST);
11439 rtx test = gen_rtx_EQ (VOIDmode, operands[0], operands[1]);
11440 rtx jump = gen_cbranchsi4 (test, operands[0], operands[1], operands[2]);
11441 emit_jump_insn (jump);
11442
11443 DONE;
11444 })
11445
11446 (define_insn "stack_protect_testsi"
11447 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
11448 (unspec:CCEQ [(match_operand:SI 1 "memory_operand" "m,m")
11449 (match_operand:SI 2 "memory_operand" "m,m")]
11450 UNSPEC_SP_TEST))
11451 (set (match_scratch:SI 4 "=r,r") (const_int 0))
11452 (clobber (match_scratch:SI 3 "=&r,&r"))]
11453 "TARGET_32BIT"
11454 "@
11455 lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0
11456 lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;cmplw %0,%3,%4\;li %3,0\;li %4,0"
11457 [(set_attr "length" "16,20")])
11458
11459 (define_insn "stack_protect_testdi"
11460 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
11461 (unspec:CCEQ [(match_operand:DI 1 "memory_operand" "Y,Y")
11462 (match_operand:DI 2 "memory_operand" "Y,Y")]
11463 UNSPEC_SP_TEST))
11464 (set (match_scratch:DI 4 "=r,r") (const_int 0))
11465 (clobber (match_scratch:DI 3 "=&r,&r"))]
11466 "TARGET_64BIT"
11467 "@
11468 ld%U1%X1 %3,%1\;ld%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0
11469 ld%U1%X1 %3,%1\;ld%U2%X2 %4,%2\;cmpld %0,%3,%4\;li %3,0\;li %4,0"
11470 [(set_attr "length" "16,20")])
11471
11472 \f
11473 ;; Here are the actual compare insns.
11474 (define_insn "*cmp<mode>_signed"
11475 [(set (match_operand:CC 0 "cc_reg_operand" "=y")
11476 (compare:CC (match_operand:GPR 1 "gpc_reg_operand" "r")
11477 (match_operand:GPR 2 "reg_or_short_operand" "rI")))]
11478 ""
11479 "cmp<wd>%I2 %0,%1,%2"
11480 [(set_attr "type" "cmp")])
11481
11482 (define_insn "*cmp<mode>_unsigned"
11483 [(set (match_operand:CCUNS 0 "cc_reg_operand" "=y")
11484 (compare:CCUNS (match_operand:GPR 1 "gpc_reg_operand" "r")
11485 (match_operand:GPR 2 "reg_or_u_short_operand" "rK")))]
11486 ""
11487 "cmpl<wd>%I2 %0,%1,%2"
11488 [(set_attr "type" "cmp")])
11489
11490 ;; If we are comparing a register for equality with a large constant,
11491 ;; we can do this with an XOR followed by a compare. But this is profitable
11492 ;; only if the large constant is only used for the comparison (and in this
11493 ;; case we already have a register to reuse as scratch).
11494 ;;
11495 ;; For 64-bit registers, we could only do so if the constant's bit 15 is clear:
11496 ;; otherwise we'd need to XOR with FFFFFFFF????0000 which is not available.
11497
11498 (define_peephole2
11499 [(set (match_operand:SI 0 "register_operand")
11500 (match_operand:SI 1 "logical_const_operand"))
11501 (set (match_dup 0) (match_operator:SI 3 "boolean_or_operator"
11502 [(match_dup 0)
11503 (match_operand:SI 2 "logical_const_operand")]))
11504 (set (match_operand:CC 4 "cc_reg_operand")
11505 (compare:CC (match_operand:SI 5 "gpc_reg_operand")
11506 (match_dup 0)))
11507 (set (pc)
11508 (if_then_else (match_operator 6 "equality_operator"
11509 [(match_dup 4) (const_int 0)])
11510 (match_operand 7 "")
11511 (match_operand 8 "")))]
11512 "peep2_reg_dead_p (3, operands[0])
11513 && peep2_reg_dead_p (4, operands[4])
11514 && REGNO (operands[0]) != REGNO (operands[5])"
11515 [(set (match_dup 0) (xor:SI (match_dup 5) (match_dup 9)))
11516 (set (match_dup 4) (compare:CC (match_dup 0) (match_dup 10)))
11517 (set (pc) (if_then_else (match_dup 6) (match_dup 7) (match_dup 8)))]
11518
11519 {
11520 /* Get the constant we are comparing against, and see what it looks like
11521 when sign-extended from 16 to 32 bits. Then see what constant we could
11522 XOR with SEXTC to get the sign-extended value. */
11523 rtx cnst = simplify_const_binary_operation (GET_CODE (operands[3]),
11524 SImode,
11525 operands[1], operands[2]);
11526 HOST_WIDE_INT c = INTVAL (cnst);
11527 HOST_WIDE_INT sextc = ((c & 0xffff) ^ 0x8000) - 0x8000;
11528 HOST_WIDE_INT xorv = c ^ sextc;
11529
11530 operands[9] = GEN_INT (xorv);
11531 operands[10] = GEN_INT (sextc);
11532 })
11533
11534 ;; Only need to compare second words if first words equal
11535 (define_insn "*cmp<mode>_internal1"
11536 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
11537 (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
11538 (match_operand:IBM128 2 "gpc_reg_operand" "d")))]
11539 "!TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode)
11540 && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
11541 "fcmpu %0,%1,%2\;bne %0,$+8\;fcmpu %0,%L1,%L2"
11542 [(set_attr "type" "fpcompare")
11543 (set_attr "length" "12")])
11544
11545 (define_insn_and_split "*cmp<mode>_internal2"
11546 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
11547 (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
11548 (match_operand:IBM128 2 "gpc_reg_operand" "d")))
11549 (clobber (match_scratch:DF 3 "=d"))
11550 (clobber (match_scratch:DF 4 "=d"))
11551 (clobber (match_scratch:DF 5 "=d"))
11552 (clobber (match_scratch:DF 6 "=d"))
11553 (clobber (match_scratch:DF 7 "=d"))
11554 (clobber (match_scratch:DF 8 "=d"))
11555 (clobber (match_scratch:DF 9 "=d"))
11556 (clobber (match_scratch:DF 10 "=d"))
11557 (clobber (match_scratch:GPR 11 "=b"))]
11558 "TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode)
11559 && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
11560 "#"
11561 "&& reload_completed"
11562 [(set (match_dup 3) (match_dup 14))
11563 (set (match_dup 4) (match_dup 15))
11564 (set (match_dup 9) (abs:DF (match_dup 5)))
11565 (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 3)))
11566 (set (pc) (if_then_else (ne (match_dup 0) (const_int 0))
11567 (label_ref (match_dup 12))
11568 (pc)))
11569 (set (match_dup 0) (compare:CCFP (match_dup 5) (match_dup 7)))
11570 (set (pc) (label_ref (match_dup 13)))
11571 (match_dup 12)
11572 (set (match_dup 10) (minus:DF (match_dup 5) (match_dup 7)))
11573 (set (match_dup 9) (minus:DF (match_dup 6) (match_dup 8)))
11574 (set (match_dup 9) (plus:DF (match_dup 10) (match_dup 9)))
11575 (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 4)))
11576 (match_dup 13)]
11577 {
11578 REAL_VALUE_TYPE rv;
11579 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
11580 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
11581
11582 operands[5] = simplify_gen_subreg (DFmode, operands[1], <MODE>mode, hi_word);
11583 operands[6] = simplify_gen_subreg (DFmode, operands[1], <MODE>mode, lo_word);
11584 operands[7] = simplify_gen_subreg (DFmode, operands[2], <MODE>mode, hi_word);
11585 operands[8] = simplify_gen_subreg (DFmode, operands[2], <MODE>mode, lo_word);
11586 operands[12] = gen_label_rtx ();
11587 operands[13] = gen_label_rtx ();
11588 real_inf (&rv);
11589 operands[14] = force_const_mem (DFmode,
11590 const_double_from_real_value (rv, DFmode));
11591 operands[15] = force_const_mem (DFmode,
11592 const_double_from_real_value (dconst0,
11593 DFmode));
11594 if (TARGET_TOC)
11595 {
11596 rtx tocref;
11597 tocref = create_TOC_reference (XEXP (operands[14], 0), operands[11]);
11598 operands[14] = gen_const_mem (DFmode, tocref);
11599 tocref = create_TOC_reference (XEXP (operands[15], 0), operands[11]);
11600 operands[15] = gen_const_mem (DFmode, tocref);
11601 set_mem_alias_set (operands[14], get_TOC_alias_set ());
11602 set_mem_alias_set (operands[15], get_TOC_alias_set ());
11603 }
11604 })
11605 \f
11606 ;; Now we have the scc insns. We can do some combinations because of the
11607 ;; way the machine works.
11608 ;;
11609 ;; Note that this is probably faster if we can put an insn between the
11610 ;; mfcr and rlinm, but this is tricky. Let's leave it for now. In most
11611 ;; cases the insns below which don't use an intermediate CR field will
11612 ;; be used instead.
11613 (define_insn ""
11614 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
11615 (match_operator:GPR 1 "scc_comparison_operator"
11616 [(match_operand 2 "cc_reg_operand" "y")
11617 (const_int 0)]))]
11618 ""
11619 "mfcr %0%Q2\;rlwinm %0,%0,%J1,1"
11620 [(set (attr "type")
11621 (cond [(match_test "TARGET_MFCRF")
11622 (const_string "mfcrf")
11623 ]
11624 (const_string "mfcr")))
11625 (set_attr "length" "8")])
11626
11627 (define_insn_and_split ""
11628 [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
11629 (compare:CC (match_operator:SI 1 "scc_comparison_operator"
11630 [(match_operand 2 "cc_reg_operand" "y,y")
11631 (const_int 0)])
11632 (const_int 0)))
11633 (set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
11634 (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
11635 "TARGET_32BIT"
11636 "@
11637 mfcr %3%Q2\;rlwinm. %3,%3,%J1,1
11638 #"
11639 "&& reload_completed"
11640 [(set (match_dup 3)
11641 (match_op_dup 1 [(match_dup 2) (const_int 0)]))
11642 (set (match_dup 0)
11643 (compare:CC (match_dup 3)
11644 (const_int 0)))]
11645 ""
11646 [(set_attr "type" "shift")
11647 (set_attr "dot" "yes")
11648 (set_attr "length" "8,16")])
11649
11650 (define_insn ""
11651 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11652 (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
11653 [(match_operand 2 "cc_reg_operand" "y")
11654 (const_int 0)])
11655 (match_operand:SI 3 "const_int_operand" "n")))]
11656 ""
11657 {
11658 int is_bit = ccr_bit (operands[1], 1);
11659 int put_bit = 31 - (INTVAL (operands[3]) & 31);
11660 int count;
11661
11662 gcc_assert (is_bit != -1);
11663 if (is_bit >= put_bit)
11664 count = is_bit - put_bit;
11665 else
11666 count = 32 - (put_bit - is_bit);
11667
11668 operands[4] = GEN_INT (count);
11669 operands[5] = GEN_INT (put_bit);
11670
11671 return "mfcr %0%Q2\;rlwinm %0,%0,%4,%5,%5";
11672 }
11673 [(set (attr "type")
11674 (cond [(match_test "TARGET_MFCRF")
11675 (const_string "mfcrf")
11676 ]
11677 (const_string "mfcr")))
11678 (set_attr "length" "8")])
11679
11680 (define_insn ""
11681 [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
11682 (compare:CC
11683 (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
11684 [(match_operand 2 "cc_reg_operand" "y,y")
11685 (const_int 0)])
11686 (match_operand:SI 3 "const_int_operand" "n,n"))
11687 (const_int 0)))
11688 (set (match_operand:SI 4 "gpc_reg_operand" "=r,r")
11689 (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
11690 (match_dup 3)))]
11691 ""
11692 {
11693 int is_bit = ccr_bit (operands[1], 1);
11694 int put_bit = 31 - (INTVAL (operands[3]) & 31);
11695 int count;
11696
11697 gcc_assert (is_bit != -1);
11698 /* Force split for non-cc0 compare. */
11699 if (which_alternative == 1)
11700 return "#";
11701
11702 if (is_bit >= put_bit)
11703 count = is_bit - put_bit;
11704 else
11705 count = 32 - (put_bit - is_bit);
11706
11707 operands[5] = GEN_INT (count);
11708 operands[6] = GEN_INT (put_bit);
11709
11710 return "mfcr %4%Q2\;rlwinm. %4,%4,%5,%6,%6";
11711 }
11712 [(set_attr "type" "shift")
11713 (set_attr "dot" "yes")
11714 (set_attr "length" "8,16")])
11715
11716 (define_split
11717 [(set (match_operand:CC 0 "cc_reg_not_cr0_operand")
11718 (compare:CC
11719 (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
11720 [(match_operand 2 "cc_reg_operand")
11721 (const_int 0)])
11722 (match_operand:SI 3 "const_int_operand"))
11723 (const_int 0)))
11724 (set (match_operand:SI 4 "gpc_reg_operand")
11725 (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
11726 (match_dup 3)))]
11727 "reload_completed"
11728 [(set (match_dup 4)
11729 (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
11730 (match_dup 3)))
11731 (set (match_dup 0)
11732 (compare:CC (match_dup 4)
11733 (const_int 0)))]
11734 "")
11735
11736
11737 (define_code_iterator cmp [eq ne lt ltu gt gtu le leu ge geu])
11738 (define_code_attr UNS [(eq "CC")
11739 (ne "CC")
11740 (lt "CC") (ltu "CCUNS")
11741 (gt "CC") (gtu "CCUNS")
11742 (le "CC") (leu "CCUNS")
11743 (ge "CC") (geu "CCUNS")])
11744 (define_code_attr UNSu_ [(eq "")
11745 (ne "")
11746 (lt "") (ltu "u_")
11747 (gt "") (gtu "u_")
11748 (le "") (leu "u_")
11749 (ge "") (geu "u_")])
11750 (define_code_attr UNSIK [(eq "I")
11751 (ne "I")
11752 (lt "I") (ltu "K")
11753 (gt "I") (gtu "K")
11754 (le "I") (leu "K")
11755 (ge "I") (geu "K")])
11756
11757 (define_insn_and_split "<code><GPR:mode><GPR2:mode>2_isel"
11758 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
11759 (cmp:GPR (match_operand:GPR2 1 "gpc_reg_operand" "r")
11760 (match_operand:GPR2 2 "reg_or_<cmp:UNSu_>short_operand" "r<cmp:UNSIK>")))
11761 (clobber (match_scratch:GPR 3 "=r"))
11762 (clobber (match_scratch:GPR 4 "=r"))
11763 (clobber (match_scratch:<UNS> 5 "=y"))]
11764 "TARGET_ISEL
11765 && !(<CODE> == EQ && operands[2] == const0_rtx)
11766 && !(<CODE> == NE && operands[2] == const0_rtx
11767 && <GPR:MODE>mode == Pmode && <GPR2:MODE>mode == Pmode)"
11768 "#"
11769 "&& 1"
11770 [(pc)]
11771 {
11772 rtx_code code = <CODE>;
11773 if (CONST_INT_P (operands[2]) && code != EQ && code != NE)
11774 {
11775 HOST_WIDE_INT val = INTVAL (operands[2]);
11776 if (code == LT && val != -0x8000)
11777 {
11778 code = LE;
11779 val--;
11780 }
11781 if (code == GT && val != 0x7fff)
11782 {
11783 code = GE;
11784 val++;
11785 }
11786 if (code == LTU && val != 0)
11787 {
11788 code = LEU;
11789 val--;
11790 }
11791 if (code == GTU && val != 0xffff)
11792 {
11793 code = GEU;
11794 val++;
11795 }
11796 operands[2] = GEN_INT (val);
11797 }
11798
11799 if (code == NE || code == LE || code == GE || code == LEU || code == GEU)
11800 operands[3] = const0_rtx;
11801 else
11802 {
11803 if (GET_CODE (operands[3]) == SCRATCH)
11804 operands[3] = gen_reg_rtx (<GPR:MODE>mode);
11805 emit_move_insn (operands[3], const0_rtx);
11806 }
11807
11808 if (GET_CODE (operands[4]) == SCRATCH)
11809 operands[4] = gen_reg_rtx (<GPR:MODE>mode);
11810 emit_move_insn (operands[4], const1_rtx);
11811
11812 if (GET_CODE (operands[5]) == SCRATCH)
11813 operands[5] = gen_reg_rtx (<UNS>mode);
11814
11815 rtx c1 = gen_rtx_COMPARE (<UNS>mode, operands[1], operands[2]);
11816 emit_insn (gen_rtx_SET (operands[5], c1));
11817
11818 rtx c2 = gen_rtx_fmt_ee (code, <GPR:MODE>mode, operands[5], const0_rtx);
11819 rtx x = gen_rtx_IF_THEN_ELSE (<GPR:MODE>mode, c2, operands[4], operands[3]);
11820 emit_move_insn (operands[0], x);
11821
11822 DONE;
11823 }
11824 [(set (attr "cost")
11825 (if_then_else (match_test "(CONST_INT_P (operands[2]) && <CODE> != EQ)
11826 || <CODE> == NE
11827 || <CODE> == LE || <CODE> == GE
11828 || <CODE> == LEU || <CODE> == GEU")
11829 (const_string "9")
11830 (const_string "10")))])
11831
11832 (define_mode_attr scc_eq_op2 [(SI "rKLI")
11833 (DI "rKJI")])
11834
11835 (define_expand "eq<mode>3"
11836 [(parallel [
11837 (set (match_operand:GPR 0 "gpc_reg_operand" "=r")
11838 (eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
11839 (match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>")))
11840 (clobber (match_scratch:GPR 3 "=r"))
11841 (clobber (match_scratch:GPR 4 "=r"))])]
11842 ""
11843 {
11844 if (TARGET_ISEL && operands[2] != const0_rtx)
11845 {
11846 emit_insn (gen_eq<mode><mode>2_isel (operands[0], operands[1],
11847 operands[2]));
11848 DONE;
11849 }
11850 })
11851
11852 (define_insn_and_split "*eq<mode>3"
11853 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
11854 (eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
11855 (match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>")))
11856 (clobber (match_scratch:GPR 3 "=r"))
11857 (clobber (match_scratch:GPR 4 "=r"))]
11858 "!(TARGET_ISEL && operands[2] != const0_rtx)"
11859 "#"
11860 "&& 1"
11861 [(set (match_dup 4)
11862 (clz:GPR (match_dup 3)))
11863 (set (match_dup 0)
11864 (lshiftrt:GPR (match_dup 4)
11865 (match_dup 5)))]
11866 {
11867 operands[3] = rs6000_emit_eqne (<MODE>mode,
11868 operands[1], operands[2], operands[3]);
11869
11870 if (GET_CODE (operands[4]) == SCRATCH)
11871 operands[4] = gen_reg_rtx (<MODE>mode);
11872
11873 operands[5] = GEN_INT (exact_log2 (GET_MODE_BITSIZE (<MODE>mode)));
11874 }
11875 [(set (attr "length")
11876 (if_then_else (match_test "operands[2] == const0_rtx")
11877 (const_string "8")
11878 (const_string "12")))])
11879
11880 (define_expand "ne<mode>3"
11881 [(parallel [
11882 (set (match_operand:P 0 "gpc_reg_operand" "=r")
11883 (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
11884 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")))
11885 (clobber (match_scratch:P 3 "=r"))
11886 (clobber (match_scratch:P 4 "=r"))
11887 (clobber (reg:P CA_REGNO))])]
11888 ""
11889 {
11890 if (TARGET_ISEL && operands[2] != const0_rtx)
11891 {
11892 emit_insn (gen_ne<mode><mode>2_isel (operands[0], operands[1],
11893 operands[2]));
11894 DONE;
11895 }
11896 })
11897
11898 (define_insn_and_split "*ne<mode>3"
11899 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11900 (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
11901 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")))
11902 (clobber (match_scratch:P 3 "=r"))
11903 (clobber (match_scratch:P 4 "=r"))
11904 (clobber (reg:P CA_REGNO))]
11905 "!(TARGET_ISEL && operands[2] != const0_rtx)"
11906 "#"
11907 "&& 1"
11908 [(parallel [(set (match_dup 4)
11909 (plus:P (match_dup 3)
11910 (const_int -1)))
11911 (set (reg:P CA_REGNO)
11912 (ne:P (match_dup 3)
11913 (const_int 0)))])
11914 (parallel [(set (match_dup 0)
11915 (plus:P (plus:P (not:P (match_dup 4))
11916 (reg:P CA_REGNO))
11917 (match_dup 3)))
11918 (clobber (reg:P CA_REGNO))])]
11919 {
11920 operands[3] = rs6000_emit_eqne (<MODE>mode,
11921 operands[1], operands[2], operands[3]);
11922
11923 if (GET_CODE (operands[4]) == SCRATCH)
11924 operands[4] = gen_reg_rtx (<MODE>mode);
11925 }
11926 [(set (attr "length")
11927 (if_then_else (match_test "operands[2] == const0_rtx")
11928 (const_string "8")
11929 (const_string "12")))])
11930
11931 (define_insn_and_split "*neg_eq_<mode>"
11932 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11933 (neg:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
11934 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
11935 (clobber (match_scratch:P 3 "=r"))
11936 (clobber (match_scratch:P 4 "=r"))
11937 (clobber (reg:P CA_REGNO))]
11938 ""
11939 "#"
11940 ""
11941 [(parallel [(set (match_dup 4)
11942 (plus:P (match_dup 3)
11943 (const_int -1)))
11944 (set (reg:P CA_REGNO)
11945 (ne:P (match_dup 3)
11946 (const_int 0)))])
11947 (parallel [(set (match_dup 0)
11948 (plus:P (reg:P CA_REGNO)
11949 (const_int -1)))
11950 (clobber (reg:P CA_REGNO))])]
11951 {
11952 operands[3] = rs6000_emit_eqne (<MODE>mode,
11953 operands[1], operands[2], operands[3]);
11954
11955 if (GET_CODE (operands[4]) == SCRATCH)
11956 operands[4] = gen_reg_rtx (<MODE>mode);
11957 }
11958 [(set (attr "length")
11959 (if_then_else (match_test "operands[2] == const0_rtx")
11960 (const_string "8")
11961 (const_string "12")))])
11962
11963 (define_insn_and_split "*neg_ne_<mode>"
11964 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11965 (neg:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
11966 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
11967 (clobber (match_scratch:P 3 "=r"))
11968 (clobber (match_scratch:P 4 "=r"))
11969 (clobber (reg:P CA_REGNO))]
11970 ""
11971 "#"
11972 ""
11973 [(parallel [(set (match_dup 4)
11974 (neg:P (match_dup 3)))
11975 (set (reg:P CA_REGNO)
11976 (eq:P (match_dup 3)
11977 (const_int 0)))])
11978 (parallel [(set (match_dup 0)
11979 (plus:P (reg:P CA_REGNO)
11980 (const_int -1)))
11981 (clobber (reg:P CA_REGNO))])]
11982 {
11983 operands[3] = rs6000_emit_eqne (<MODE>mode,
11984 operands[1], operands[2], operands[3]);
11985
11986 if (GET_CODE (operands[4]) == SCRATCH)
11987 operands[4] = gen_reg_rtx (<MODE>mode);
11988 }
11989 [(set (attr "length")
11990 (if_then_else (match_test "operands[2] == const0_rtx")
11991 (const_string "8")
11992 (const_string "12")))])
11993
11994 (define_insn_and_split "*plus_eq_<mode>"
11995 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11996 (plus:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
11997 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
11998 (match_operand:P 3 "gpc_reg_operand" "r")))
11999 (clobber (match_scratch:P 4 "=r"))
12000 (clobber (match_scratch:P 5 "=r"))
12001 (clobber (reg:P CA_REGNO))]
12002 ""
12003 "#"
12004 ""
12005 [(parallel [(set (match_dup 5)
12006 (neg:P (match_dup 4)))
12007 (set (reg:P CA_REGNO)
12008 (eq:P (match_dup 4)
12009 (const_int 0)))])
12010 (parallel [(set (match_dup 0)
12011 (plus:P (match_dup 3)
12012 (reg:P CA_REGNO)))
12013 (clobber (reg:P CA_REGNO))])]
12014 {
12015 operands[4] = rs6000_emit_eqne (<MODE>mode,
12016 operands[1], operands[2], operands[4]);
12017
12018 if (GET_CODE (operands[5]) == SCRATCH)
12019 operands[5] = gen_reg_rtx (<MODE>mode);
12020 }
12021 [(set (attr "length")
12022 (if_then_else (match_test "operands[2] == const0_rtx")
12023 (const_string "8")
12024 (const_string "12")))])
12025
12026 (define_insn_and_split "*plus_ne_<mode>"
12027 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12028 (plus:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12029 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
12030 (match_operand:P 3 "gpc_reg_operand" "r")))
12031 (clobber (match_scratch:P 4 "=r"))
12032 (clobber (match_scratch:P 5 "=r"))
12033 (clobber (reg:P CA_REGNO))]
12034 ""
12035 "#"
12036 ""
12037 [(parallel [(set (match_dup 5)
12038 (plus:P (match_dup 4)
12039 (const_int -1)))
12040 (set (reg:P CA_REGNO)
12041 (ne:P (match_dup 4)
12042 (const_int 0)))])
12043 (parallel [(set (match_dup 0)
12044 (plus:P (match_dup 3)
12045 (reg:P CA_REGNO)))
12046 (clobber (reg:P CA_REGNO))])]
12047 {
12048 operands[4] = rs6000_emit_eqne (<MODE>mode,
12049 operands[1], operands[2], operands[4]);
12050
12051 if (GET_CODE (operands[5]) == SCRATCH)
12052 operands[5] = gen_reg_rtx (<MODE>mode);
12053 }
12054 [(set (attr "length")
12055 (if_then_else (match_test "operands[2] == const0_rtx")
12056 (const_string "8")
12057 (const_string "12")))])
12058
12059 (define_insn_and_split "*minus_eq_<mode>"
12060 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12061 (minus:P (match_operand:P 3 "gpc_reg_operand" "r")
12062 (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12063 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12064 (clobber (match_scratch:P 4 "=r"))
12065 (clobber (match_scratch:P 5 "=r"))
12066 (clobber (reg:P CA_REGNO))]
12067 ""
12068 "#"
12069 ""
12070 [(parallel [(set (match_dup 5)
12071 (plus:P (match_dup 4)
12072 (const_int -1)))
12073 (set (reg:P CA_REGNO)
12074 (ne:P (match_dup 4)
12075 (const_int 0)))])
12076 (parallel [(set (match_dup 0)
12077 (plus:P (plus:P (match_dup 3)
12078 (reg:P CA_REGNO))
12079 (const_int -1)))
12080 (clobber (reg:P CA_REGNO))])]
12081 {
12082 operands[4] = rs6000_emit_eqne (<MODE>mode,
12083 operands[1], operands[2], operands[4]);
12084
12085 if (GET_CODE (operands[5]) == SCRATCH)
12086 operands[5] = gen_reg_rtx (<MODE>mode);
12087 }
12088 [(set (attr "length")
12089 (if_then_else (match_test "operands[2] == const0_rtx")
12090 (const_string "8")
12091 (const_string "12")))])
12092
12093 (define_insn_and_split "*minus_ne_<mode>"
12094 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12095 (minus:P (match_operand:P 3 "gpc_reg_operand" "r")
12096 (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12097 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12098 (clobber (match_scratch:P 4 "=r"))
12099 (clobber (match_scratch:P 5 "=r"))
12100 (clobber (reg:P CA_REGNO))]
12101 ""
12102 "#"
12103 ""
12104 [(parallel [(set (match_dup 5)
12105 (neg:P (match_dup 4)))
12106 (set (reg:P CA_REGNO)
12107 (eq:P (match_dup 4)
12108 (const_int 0)))])
12109 (parallel [(set (match_dup 0)
12110 (plus:P (plus:P (match_dup 3)
12111 (reg:P CA_REGNO))
12112 (const_int -1)))
12113 (clobber (reg:P CA_REGNO))])]
12114 {
12115 operands[4] = rs6000_emit_eqne (<MODE>mode,
12116 operands[1], operands[2], operands[4]);
12117
12118 if (GET_CODE (operands[5]) == SCRATCH)
12119 operands[5] = gen_reg_rtx (<MODE>mode);
12120 }
12121 [(set (attr "length")
12122 (if_then_else (match_test "operands[2] == const0_rtx")
12123 (const_string "8")
12124 (const_string "12")))])
12125
12126 (define_insn_and_split "*eqsi3_ext<mode>"
12127 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
12128 (eq:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
12129 (match_operand:SI 2 "scc_eq_operand" "rKLI")))
12130 (clobber (match_scratch:SI 3 "=r"))
12131 (clobber (match_scratch:SI 4 "=r"))]
12132 ""
12133 "#"
12134 ""
12135 [(set (match_dup 4)
12136 (clz:SI (match_dup 3)))
12137 (set (match_dup 0)
12138 (zero_extend:EXTSI
12139 (lshiftrt:SI (match_dup 4)
12140 (const_int 5))))]
12141 {
12142 operands[3] = rs6000_emit_eqne (SImode,
12143 operands[1], operands[2], operands[3]);
12144
12145 if (GET_CODE (operands[4]) == SCRATCH)
12146 operands[4] = gen_reg_rtx (SImode);
12147 }
12148 [(set (attr "length")
12149 (if_then_else (match_test "operands[2] == const0_rtx")
12150 (const_string "8")
12151 (const_string "12")))])
12152
12153 (define_insn_and_split "*nesi3_ext<mode>"
12154 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
12155 (ne:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
12156 (match_operand:SI 2 "scc_eq_operand" "rKLI")))
12157 (clobber (match_scratch:SI 3 "=r"))
12158 (clobber (match_scratch:SI 4 "=r"))
12159 (clobber (match_scratch:EXTSI 5 "=r"))]
12160 "!TARGET_ISEL"
12161 "#"
12162 "&& 1"
12163 [(set (match_dup 4)
12164 (clz:SI (match_dup 3)))
12165 (set (match_dup 5)
12166 (zero_extend:EXTSI
12167 (lshiftrt:SI (match_dup 4)
12168 (const_int 5))))
12169 (set (match_dup 0)
12170 (xor:EXTSI (match_dup 5)
12171 (const_int 1)))]
12172 {
12173 operands[3] = rs6000_emit_eqne (SImode,
12174 operands[1], operands[2], operands[3]);
12175
12176 if (GET_CODE (operands[4]) == SCRATCH)
12177 operands[4] = gen_reg_rtx (SImode);
12178 if (GET_CODE (operands[5]) == SCRATCH)
12179 operands[5] = gen_reg_rtx (<MODE>mode);
12180 }
12181 [(set (attr "length")
12182 (if_then_else (match_test "operands[2] == const0_rtx")
12183 (const_string "12")
12184 (const_string "16")))])
12185 \f
12186 ;; Conditional branches.
12187 ;; These either are a single bc insn, or a bc around a b.
12188
12189 (define_insn "*cbranch"
12190 [(set (pc)
12191 (if_then_else (match_operator 1 "branch_comparison_operator"
12192 [(match_operand 2 "cc_reg_operand" "y")
12193 (const_int 0)])
12194 (label_ref (match_operand 0))
12195 (pc)))]
12196 ""
12197 {
12198 return output_cbranch (operands[1], "%l0", 0, insn);
12199 }
12200 [(set_attr "type" "branch")
12201 (set (attr "length")
12202 (if_then_else (and (ge (minus (match_dup 0) (pc))
12203 (const_int -32768))
12204 (lt (minus (match_dup 0) (pc))
12205 (const_int 32764)))
12206 (const_int 4)
12207 (const_int 8)))])
12208
12209 ;; Conditional return.
12210 (define_insn "*creturn"
12211 [(set (pc)
12212 (if_then_else (match_operator 0 "branch_comparison_operator"
12213 [(match_operand 1 "cc_reg_operand" "y")
12214 (const_int 0)])
12215 (any_return)
12216 (pc)))]
12217 "<return_pred>"
12218 {
12219 return output_cbranch (operands[0], NULL, 0, insn);
12220 }
12221 [(set_attr "type" "jmpreg")])
12222
12223 ;; Logic on condition register values.
12224
12225 ; This pattern matches things like
12226 ; (set (reg:CCEQ 68) (compare:CCEQ (ior:SI (gt:SI (reg:CCFP 68) (const_int 0))
12227 ; (eq:SI (reg:CCFP 68) (const_int 0)))
12228 ; (const_int 1)))
12229 ; which are generated by the branch logic.
12230 ; Prefer destructive operations where BT = BB (for crXX BT,BA,BB)
12231
12232 (define_insn "cceq_ior_compare"
12233 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12234 (compare:CCEQ (match_operator:SI 1 "boolean_operator"
12235 [(match_operator:SI 2
12236 "branch_positive_comparison_operator"
12237 [(match_operand 3
12238 "cc_reg_operand" "y,y")
12239 (const_int 0)])
12240 (match_operator:SI 4
12241 "branch_positive_comparison_operator"
12242 [(match_operand 5
12243 "cc_reg_operand" "0,y")
12244 (const_int 0)])])
12245 (const_int 1)))]
12246 ""
12247 "cr%q1 %E0,%j2,%j4"
12248 [(set_attr "type" "cr_logical")
12249 (set_attr "cr_logical_3op" "no,yes")])
12250
12251 ; Why is the constant -1 here, but 1 in the previous pattern?
12252 ; Because ~1 has all but the low bit set.
12253 (define_insn "cceq_ior_compare_complement"
12254 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12255 (compare:CCEQ (match_operator:SI 1 "boolean_operator"
12256 [(not:SI (match_operator:SI 2
12257 "branch_positive_comparison_operator"
12258 [(match_operand 3
12259 "cc_reg_operand" "y,y")
12260 (const_int 0)]))
12261 (match_operator:SI 4
12262 "branch_positive_comparison_operator"
12263 [(match_operand 5
12264 "cc_reg_operand" "0,y")
12265 (const_int 0)])])
12266 (const_int -1)))]
12267 ""
12268 "cr%q1 %E0,%j2,%j4"
12269 [(set_attr "type" "cr_logical")
12270 (set_attr "cr_logical_3op" "no,yes")])
12271
12272 (define_insn "*cceq_rev_compare"
12273 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12274 (compare:CCEQ (match_operator:SI 1
12275 "branch_positive_comparison_operator"
12276 [(match_operand 2
12277 "cc_reg_operand" "0,y")
12278 (const_int 0)])
12279 (const_int 0)))]
12280 ""
12281 "crnot %E0,%j1"
12282 [(set_attr "type" "cr_logical")
12283 (set_attr "cr_logical_3op" "no,yes")])
12284
12285 ;; If we are comparing the result of two comparisons, this can be done
12286 ;; using creqv or crxor.
12287
12288 (define_insn_and_split ""
12289 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y")
12290 (compare:CCEQ (match_operator 1 "branch_comparison_operator"
12291 [(match_operand 2 "cc_reg_operand" "y")
12292 (const_int 0)])
12293 (match_operator 3 "branch_comparison_operator"
12294 [(match_operand 4 "cc_reg_operand" "y")
12295 (const_int 0)])))]
12296 ""
12297 "#"
12298 ""
12299 [(set (match_dup 0) (compare:CCEQ (xor:SI (match_dup 1) (match_dup 3))
12300 (match_dup 5)))]
12301 {
12302 int positive_1, positive_2;
12303
12304 positive_1 = branch_positive_comparison_operator (operands[1],
12305 GET_MODE (operands[1]));
12306 positive_2 = branch_positive_comparison_operator (operands[3],
12307 GET_MODE (operands[3]));
12308
12309 if (! positive_1)
12310 operands[1] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[2]),
12311 GET_CODE (operands[1])),
12312 SImode,
12313 operands[2], const0_rtx);
12314 else if (GET_MODE (operands[1]) != SImode)
12315 operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), SImode,
12316 operands[2], const0_rtx);
12317
12318 if (! positive_2)
12319 operands[3] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[4]),
12320 GET_CODE (operands[3])),
12321 SImode,
12322 operands[4], const0_rtx);
12323 else if (GET_MODE (operands[3]) != SImode)
12324 operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SImode,
12325 operands[4], const0_rtx);
12326
12327 if (positive_1 == positive_2)
12328 {
12329 operands[1] = gen_rtx_NOT (SImode, operands[1]);
12330 operands[5] = constm1_rtx;
12331 }
12332 else
12333 {
12334 operands[5] = const1_rtx;
12335 }
12336 })
12337
12338 ;; Unconditional branch and return.
12339
12340 (define_insn "jump"
12341 [(set (pc)
12342 (label_ref (match_operand 0)))]
12343 ""
12344 "b %l0"
12345 [(set_attr "type" "branch")])
12346
12347 (define_insn "<return_str>return"
12348 [(any_return)]
12349 "<return_pred>"
12350 "blr"
12351 [(set_attr "type" "jmpreg")])
12352
12353 (define_expand "indirect_jump"
12354 [(set (pc) (match_operand 0 "register_operand"))]
12355 ""
12356 {
12357 if (!rs6000_speculate_indirect_jumps) {
12358 rtx ccreg = gen_reg_rtx (CCmode);
12359 if (Pmode == DImode)
12360 emit_jump_insn (gen_indirect_jumpdi_nospec (operands[0], ccreg));
12361 else
12362 emit_jump_insn (gen_indirect_jumpsi_nospec (operands[0], ccreg));
12363 DONE;
12364 }
12365 })
12366
12367 (define_insn "*indirect_jump<mode>"
12368 [(set (pc)
12369 (match_operand:P 0 "register_operand" "c,*l"))]
12370 "rs6000_speculate_indirect_jumps"
12371 "b%T0"
12372 [(set_attr "type" "jmpreg")])
12373
12374 (define_insn "indirect_jump<mode>_nospec"
12375 [(set (pc) (match_operand:P 0 "register_operand" "c,*l"))
12376 (clobber (match_operand:CC 1 "cc_reg_operand" "=y,y"))]
12377 "!rs6000_speculate_indirect_jumps"
12378 "crset %E1\;beq%T0- %1\;b $"
12379 [(set_attr "type" "jmpreg")
12380 (set_attr "length" "12")])
12381
12382 ;; Table jump for switch statements:
12383 (define_expand "tablejump"
12384 [(use (match_operand 0))
12385 (use (label_ref (match_operand 1)))]
12386 ""
12387 {
12388 if (rs6000_speculate_indirect_jumps)
12389 {
12390 if (TARGET_32BIT)
12391 emit_jump_insn (gen_tablejumpsi (operands[0], operands[1]));
12392 else
12393 emit_jump_insn (gen_tablejumpdi (operands[0], operands[1]));
12394 }
12395 else
12396 {
12397 rtx ccreg = gen_reg_rtx (CCmode);
12398 rtx jump;
12399 if (TARGET_32BIT)
12400 jump = gen_tablejumpsi_nospec (operands[0], operands[1], ccreg);
12401 else
12402 jump = gen_tablejumpdi_nospec (operands[0], operands[1], ccreg);
12403 emit_jump_insn (jump);
12404 }
12405 DONE;
12406 })
12407
12408 (define_expand "tablejumpsi"
12409 [(set (match_dup 3)
12410 (plus:SI (match_operand:SI 0)
12411 (match_dup 2)))
12412 (parallel [(set (pc)
12413 (match_dup 3))
12414 (use (label_ref (match_operand 1)))])]
12415 "TARGET_32BIT && rs6000_speculate_indirect_jumps"
12416 {
12417 operands[0] = force_reg (SImode, operands[0]);
12418 operands[2] = force_reg (SImode, gen_rtx_LABEL_REF (SImode, operands[1]));
12419 operands[3] = gen_reg_rtx (SImode);
12420 })
12421
12422 (define_expand "tablejumpsi_nospec"
12423 [(set (match_dup 4)
12424 (plus:SI (match_operand:SI 0)
12425 (match_dup 3)))
12426 (parallel [(set (pc)
12427 (match_dup 4))
12428 (use (label_ref (match_operand 1)))
12429 (clobber (match_operand 2))])]
12430 "TARGET_32BIT && !rs6000_speculate_indirect_jumps"
12431 {
12432 operands[0] = force_reg (SImode, operands[0]);
12433 operands[3] = force_reg (SImode, gen_rtx_LABEL_REF (SImode, operands[1]));
12434 operands[4] = gen_reg_rtx (SImode);
12435 })
12436
12437 (define_expand "tablejumpdi"
12438 [(set (match_dup 4)
12439 (sign_extend:DI (match_operand:SI 0 "lwa_operand")))
12440 (set (match_dup 3)
12441 (plus:DI (match_dup 4)
12442 (match_dup 2)))
12443 (parallel [(set (pc)
12444 (match_dup 3))
12445 (use (label_ref (match_operand 1)))])]
12446 "TARGET_64BIT && rs6000_speculate_indirect_jumps"
12447 {
12448 operands[2] = force_reg (DImode, gen_rtx_LABEL_REF (DImode, operands[1]));
12449 operands[3] = gen_reg_rtx (DImode);
12450 operands[4] = gen_reg_rtx (DImode);
12451 })
12452
12453 (define_expand "tablejumpdi_nospec"
12454 [(set (match_dup 5)
12455 (sign_extend:DI (match_operand:SI 0 "lwa_operand")))
12456 (set (match_dup 4)
12457 (plus:DI (match_dup 5)
12458 (match_dup 3)))
12459 (parallel [(set (pc)
12460 (match_dup 4))
12461 (use (label_ref (match_operand 1)))
12462 (clobber (match_operand 2))])]
12463 "TARGET_64BIT && !rs6000_speculate_indirect_jumps"
12464 {
12465 operands[3] = force_reg (DImode, gen_rtx_LABEL_REF (DImode, operands[1]));
12466 operands[4] = gen_reg_rtx (DImode);
12467 operands[5] = gen_reg_rtx (DImode);
12468 })
12469
12470 (define_insn "*tablejump<mode>_internal1"
12471 [(set (pc)
12472 (match_operand:P 0 "register_operand" "c,*l"))
12473 (use (label_ref (match_operand 1)))]
12474 "rs6000_speculate_indirect_jumps"
12475 "b%T0"
12476 [(set_attr "type" "jmpreg")])
12477
12478 (define_insn "*tablejump<mode>_internal1_nospec"
12479 [(set (pc)
12480 (match_operand:P 0 "register_operand" "c,*l"))
12481 (use (label_ref (match_operand 1)))
12482 (clobber (match_operand:CC 2 "cc_reg_operand" "=y,y"))]
12483 "!rs6000_speculate_indirect_jumps"
12484 "crset %E2\;beq%T0- %2\;b $"
12485 [(set_attr "type" "jmpreg")
12486 (set_attr "length" "12")])
12487
12488 (define_insn "nop"
12489 [(unspec [(const_int 0)] UNSPEC_NOP)]
12490 ""
12491 "nop")
12492
12493 (define_insn "group_ending_nop"
12494 [(unspec [(const_int 0)] UNSPEC_GRP_END_NOP)]
12495 ""
12496 {
12497 if (rs6000_tune == PROCESSOR_POWER6)
12498 return "ori 1,1,0";
12499 return "ori 2,2,0";
12500 })
12501
12502 (define_insn "speculation_barrier"
12503 [(unspec_volatile:BLK [(const_int 0)] UNSPECV_SPEC_BARRIER)]
12504 ""
12505 "ori 31,31,0")
12506 \f
12507 ;; Define the subtract-one-and-jump insns, starting with the template
12508 ;; so loop.c knows what to generate.
12509
12510 (define_expand "doloop_end"
12511 [(use (match_operand 0)) ; loop pseudo
12512 (use (match_operand 1))] ; label
12513 ""
12514 {
12515 if (TARGET_64BIT)
12516 {
12517 if (GET_MODE (operands[0]) != DImode)
12518 FAIL;
12519 emit_jump_insn (gen_ctrdi (operands[0], operands[1]));
12520 }
12521 else
12522 {
12523 if (GET_MODE (operands[0]) != SImode)
12524 FAIL;
12525 emit_jump_insn (gen_ctrsi (operands[0], operands[1]));
12526 }
12527 DONE;
12528 })
12529
12530 (define_expand "ctr<mode>"
12531 [(parallel [(set (pc)
12532 (if_then_else (ne (match_operand:P 0 "register_operand")
12533 (const_int 1))
12534 (label_ref (match_operand 1))
12535 (pc)))
12536 (set (match_dup 0)
12537 (plus:P (match_dup 0)
12538 (const_int -1)))
12539 (clobber (match_scratch:CC 2))
12540 (clobber (match_scratch:P 3))])]
12541 ""
12542 "")
12543
12544 ;; We need to be able to do this for any operand, including MEM, or we
12545 ;; will cause reload to blow up since we don't allow output reloads on
12546 ;; JUMP_INSNs.
12547 ;; For the length attribute to be calculated correctly, the
12548 ;; label MUST be operand 0.
12549 ;; rs6000_legitimate_combined_insn prevents combine creating any of
12550 ;; the ctr<mode> insns.
12551
12552 (define_code_iterator eqne [eq ne])
12553 (define_code_attr bd [(eq "bdz") (ne "bdnz")])
12554 (define_code_attr bd_neg [(eq "bdnz") (ne "bdz")])
12555
12556 (define_insn "<bd>_<mode>"
12557 [(set (pc)
12558 (if_then_else (eqne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12559 (const_int 1))
12560 (label_ref (match_operand 0))
12561 (pc)))
12562 (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
12563 (plus:P (match_dup 1)
12564 (const_int -1)))
12565 (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
12566 (clobber (match_scratch:P 4 "=X,X,&r,r"))]
12567 ""
12568 {
12569 if (which_alternative != 0)
12570 return "#";
12571 else if (get_attr_length (insn) == 4)
12572 return "<bd> %l0";
12573 else
12574 return "<bd_neg> $+8\;b %l0";
12575 }
12576 [(set_attr "type" "branch")
12577 (set_attr_alternative "length"
12578 [(if_then_else (and (ge (minus (match_dup 0) (pc))
12579 (const_int -32768))
12580 (lt (minus (match_dup 0) (pc))
12581 (const_int 32764)))
12582 (const_int 4)
12583 (const_int 8))
12584 (const_string "16")
12585 (const_string "20")
12586 (const_string "20")])])
12587
12588 ;; Now the splitter if we could not allocate the CTR register
12589 (define_split
12590 [(set (pc)
12591 (if_then_else (match_operator 2 "comparison_operator"
12592 [(match_operand:P 1 "gpc_reg_operand")
12593 (const_int 1)])
12594 (match_operand 5)
12595 (match_operand 6)))
12596 (set (match_operand:P 0 "nonimmediate_operand")
12597 (plus:P (match_dup 1)
12598 (const_int -1)))
12599 (clobber (match_scratch:CC 3))
12600 (clobber (match_scratch:P 4))]
12601 "reload_completed"
12602 [(set (pc)
12603 (if_then_else (match_dup 7)
12604 (match_dup 5)
12605 (match_dup 6)))]
12606 {
12607 operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[2]), VOIDmode, operands[3],
12608 const0_rtx);
12609 emit_insn (gen_rtx_SET (operands[3],
12610 gen_rtx_COMPARE (CCmode, operands[1], const1_rtx)));
12611 if (gpc_reg_operand (operands[0], <MODE>mode))
12612 emit_insn (gen_add<mode>3 (operands[0], operands[1], constm1_rtx));
12613 else
12614 {
12615 emit_insn (gen_add<mode>3 (operands[4], operands[1], constm1_rtx));
12616 emit_move_insn (operands[0], operands[4]);
12617 }
12618 /* No DONE so branch comes from the pattern. */
12619 })
12620
12621 ;; patterns for bdnzt/bdnzf/bdzt/bdzf
12622 ;; Note that in the case of long branches we have to decompose this into
12623 ;; bdnz+bc. This is because bdnzt has an implied AND between the ctr condition
12624 ;; and the CR bit, which means there is no way to conveniently invert the
12625 ;; comparison as is done with plain bdnz/bdz.
12626
12627 (define_insn "<bd>tf_<mode>"
12628 [(set (pc)
12629 (if_then_else
12630 (and
12631 (eqne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12632 (const_int 1))
12633 (match_operator 3 "branch_comparison_operator"
12634 [(match_operand 4 "cc_reg_operand" "y,y,y,y")
12635 (const_int 0)]))
12636 (label_ref (match_operand 0))
12637 (pc)))
12638 (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
12639 (plus:P (match_dup 1)
12640 (const_int -1)))
12641 (clobber (match_scratch:P 5 "=X,X,&r,r"))
12642 (clobber (match_scratch:CC 6 "=X,&y,&y,&y"))
12643 (clobber (match_scratch:CCEQ 7 "=X,&y,&y,&y"))]
12644 ""
12645 {
12646 if (which_alternative != 0)
12647 return "#";
12648 else if (get_attr_length (insn) == 4)
12649 {
12650 if (branch_positive_comparison_operator (operands[3],
12651 GET_MODE (operands[3])))
12652 return "<bd>t %j3,%l0";
12653 else
12654 return "<bd>f %j3,%l0";
12655 }
12656 else
12657 {
12658 static char seq[96];
12659 char *bcs = output_cbranch (operands[3], "$+8", 1, insn);
12660 sprintf(seq, "<bd_neg> $+12\;%s;b %%l0", bcs);
12661 return seq;
12662 }
12663 }
12664 [(set_attr "type" "branch")
12665 (set_attr_alternative "length"
12666 [(if_then_else (and (ge (minus (match_dup 0) (pc))
12667 (const_int -32768))
12668 (lt (minus (match_dup 0) (pc))
12669 (const_int 32764)))
12670 (const_int 4)
12671 (const_int 8))
12672 (const_string "16")
12673 (const_string "20")
12674 (const_string "20")])])
12675
12676 ;; Now the splitter if we could not allocate the CTR register
12677 (define_split
12678 [(set (pc)
12679 (if_then_else
12680 (and
12681 (match_operator 1 "comparison_operator"
12682 [(match_operand:P 0 "gpc_reg_operand")
12683 (const_int 1)])
12684 (match_operator 3 "branch_comparison_operator"
12685 [(match_operand 2 "cc_reg_operand")
12686 (const_int 0)]))
12687 (match_operand 4)
12688 (match_operand 5)))
12689 (set (match_operand:P 6 "int_reg_operand")
12690 (plus:P (match_dup 0)
12691 (const_int -1)))
12692 (clobber (match_scratch:P 7))
12693 (clobber (match_scratch:CC 8))
12694 (clobber (match_scratch:CCEQ 9))]
12695 "reload_completed"
12696 [(pc)]
12697 {
12698 rtx ctr = operands[0];
12699 rtx ctrcmp = operands[1];
12700 rtx ccin = operands[2];
12701 rtx cccmp = operands[3];
12702 rtx dst1 = operands[4];
12703 rtx dst2 = operands[5];
12704 rtx ctrout = operands[6];
12705 rtx ctrtmp = operands[7];
12706 enum rtx_code cmpcode = GET_CODE (ctrcmp);
12707 bool ispos = branch_positive_comparison_operator (ctrcmp, GET_MODE (ctrcmp));
12708 if (!ispos)
12709 cmpcode = reverse_condition (cmpcode);
12710 /* Generate crand/crandc here. */
12711 emit_insn (gen_rtx_SET (operands[8],
12712 gen_rtx_COMPARE (CCmode, ctr, const1_rtx)));
12713 rtx ctrcmpcc = gen_rtx_fmt_ee (cmpcode, SImode, operands[8], const0_rtx);
12714
12715 rtx andexpr = gen_rtx_AND (SImode, ctrcmpcc, cccmp);
12716 if (ispos)
12717 emit_insn (gen_cceq_ior_compare (operands[9], andexpr, ctrcmpcc,
12718 operands[8], cccmp, ccin));
12719 else
12720 emit_insn (gen_cceq_ior_compare_complement (operands[9], andexpr, ctrcmpcc,
12721 operands[8], cccmp, ccin));
12722 if (gpc_reg_operand (operands[0], <MODE>mode))
12723 emit_insn (gen_add<mode>3 (ctrout, ctr, constm1_rtx));
12724 else
12725 {
12726 emit_insn (gen_add<mode>3 (ctrtmp, ctr, constm1_rtx));
12727 emit_move_insn (ctrout, ctrtmp);
12728 }
12729 rtx cmp = gen_rtx_EQ (CCEQmode, operands[9], const0_rtx);
12730 emit_jump_insn (gen_rtx_SET (pc_rtx,
12731 gen_rtx_IF_THEN_ELSE (VOIDmode, cmp,
12732 dst1, dst2)));
12733 DONE;
12734 })
12735
12736 \f
12737 (define_insn "trap"
12738 [(trap_if (const_int 1) (const_int 0))]
12739 ""
12740 "trap"
12741 [(set_attr "type" "trap")])
12742
12743 (define_expand "ctrap<mode>4"
12744 [(trap_if (match_operator 0 "ordered_comparison_operator"
12745 [(match_operand:GPR 1 "register_operand")
12746 (match_operand:GPR 2 "reg_or_short_operand")])
12747 (match_operand 3 "zero_constant" ""))]
12748 ""
12749 "")
12750
12751 (define_insn ""
12752 [(trap_if (match_operator 0 "ordered_comparison_operator"
12753 [(match_operand:GPR 1 "register_operand" "r")
12754 (match_operand:GPR 2 "reg_or_short_operand" "rI")])
12755 (const_int 0))]
12756 ""
12757 "t<wd>%V0%I2 %1,%2"
12758 [(set_attr "type" "trap")])
12759 \f
12760 ;; Insns related to generating the function prologue and epilogue.
12761
12762 (define_expand "prologue"
12763 [(use (const_int 0))]
12764 ""
12765 {
12766 rs6000_emit_prologue ();
12767 if (!TARGET_SCHED_PROLOG)
12768 emit_insn (gen_blockage ());
12769 DONE;
12770 })
12771
12772 (define_insn "*movesi_from_cr_one"
12773 [(match_parallel 0 "mfcr_operation"
12774 [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
12775 (unspec:SI [(match_operand:CC 2 "cc_reg_operand" "y")
12776 (match_operand 3 "immediate_operand" "n")]
12777 UNSPEC_MOVESI_FROM_CR))])]
12778 "TARGET_MFCRF"
12779 {
12780 int mask = 0;
12781 int i;
12782 for (i = 0; i < XVECLEN (operands[0], 0); i++)
12783 {
12784 mask = INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
12785 operands[4] = GEN_INT (mask);
12786 output_asm_insn ("mfcr %1,%4", operands);
12787 }
12788 return "";
12789 }
12790 [(set_attr "type" "mfcrf")])
12791
12792 ;; Don't include the volatile CRs since their values are not used wrt CR save
12793 ;; in the prologue and doing so prevents shrink-wrapping because we can't move the
12794 ;; prologue past an insn (early exit test) that defines a register used in the
12795 ;; prologue.
12796 (define_insn "prologue_movesi_from_cr"
12797 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
12798 (unspec:SI [(reg:CC CR2_REGNO) (reg:CC CR3_REGNO)
12799 (reg:CC CR4_REGNO)]
12800 UNSPEC_MOVESI_FROM_CR))]
12801 ""
12802 "mfcr %0"
12803 [(set_attr "type" "mfcr")])
12804
12805 (define_insn "*crsave"
12806 [(match_parallel 0 "crsave_operation"
12807 [(set (match_operand:SI 1 "memory_operand" "=m")
12808 (match_operand:SI 2 "gpc_reg_operand" "r"))])]
12809 ""
12810 "stw %2,%1"
12811 [(set_attr "type" "store")])
12812
12813 (define_insn "*stmw"
12814 [(match_parallel 0 "stmw_operation"
12815 [(set (match_operand:SI 1 "memory_operand" "=m")
12816 (match_operand:SI 2 "gpc_reg_operand" "r"))])]
12817 "TARGET_MULTIPLE"
12818 "stmw %2,%1"
12819 [(set_attr "type" "store")
12820 (set_attr "update" "yes")
12821 (set_attr "indexed" "yes")])
12822
12823 ; The following comment applies to:
12824 ; save_gpregs_*
12825 ; save_fpregs_*
12826 ; restore_gpregs*
12827 ; return_and_restore_gpregs*
12828 ; return_and_restore_fpregs*
12829 ; return_and_restore_fpregs_aix*
12830 ;
12831 ; The out-of-line save / restore functions expects one input argument.
12832 ; Since those are not standard call_insn's, we must avoid using
12833 ; MATCH_OPERAND for that argument. That way the register rename
12834 ; optimization will not try to rename this register.
12835 ; Each pattern is repeated for each possible register number used in
12836 ; various ABIs (r11, r1, and for some functions r12)
12837
12838 (define_insn "*save_gpregs_<mode>_r11"
12839 [(match_parallel 0 "any_parallel_operand"
12840 [(clobber (reg:P LR_REGNO))
12841 (use (match_operand:P 1 "symbol_ref_operand" "s"))
12842 (use (reg:P 11))
12843 (set (match_operand:P 2 "memory_operand" "=m")
12844 (match_operand:P 3 "gpc_reg_operand" "r"))])]
12845 ""
12846 "bl %1"
12847 [(set_attr "type" "branch")])
12848
12849 (define_insn "*save_gpregs_<mode>_r12"
12850 [(match_parallel 0 "any_parallel_operand"
12851 [(clobber (reg:P LR_REGNO))
12852 (use (match_operand:P 1 "symbol_ref_operand" "s"))
12853 (use (reg:P 12))
12854 (set (match_operand:P 2 "memory_operand" "=m")
12855 (match_operand:P 3 "gpc_reg_operand" "r"))])]
12856 ""
12857 "bl %1"
12858 [(set_attr "type" "branch")])
12859
12860 (define_insn "*save_gpregs_<mode>_r1"
12861 [(match_parallel 0 "any_parallel_operand"
12862 [(clobber (reg:P LR_REGNO))
12863 (use (match_operand:P 1 "symbol_ref_operand" "s"))
12864 (use (reg:P 1))
12865 (set (match_operand:P 2 "memory_operand" "=m")
12866 (match_operand:P 3 "gpc_reg_operand" "r"))])]
12867 ""
12868 "bl %1"
12869 [(set_attr "type" "branch")])
12870
12871 (define_insn "*save_fpregs_<mode>_r11"
12872 [(match_parallel 0 "any_parallel_operand"
12873 [(clobber (reg:P LR_REGNO))
12874 (use (match_operand:P 1 "symbol_ref_operand" "s"))
12875 (use (reg:P 11))
12876 (set (match_operand:DF 2 "memory_operand" "=m")
12877 (match_operand:DF 3 "gpc_reg_operand" "d"))])]
12878 ""
12879 "bl %1"
12880 [(set_attr "type" "branch")])
12881
12882 (define_insn "*save_fpregs_<mode>_r12"
12883 [(match_parallel 0 "any_parallel_operand"
12884 [(clobber (reg:P LR_REGNO))
12885 (use (match_operand:P 1 "symbol_ref_operand" "s"))
12886 (use (reg:P 12))
12887 (set (match_operand:DF 2 "memory_operand" "=m")
12888 (match_operand:DF 3 "gpc_reg_operand" "d"))])]
12889 ""
12890 "bl %1"
12891 [(set_attr "type" "branch")])
12892
12893 (define_insn "*save_fpregs_<mode>_r1"
12894 [(match_parallel 0 "any_parallel_operand"
12895 [(clobber (reg:P LR_REGNO))
12896 (use (match_operand:P 1 "symbol_ref_operand" "s"))
12897 (use (reg:P 1))
12898 (set (match_operand:DF 2 "memory_operand" "=m")
12899 (match_operand:DF 3 "gpc_reg_operand" "d"))])]
12900 ""
12901 "bl %1"
12902 [(set_attr "type" "branch")])
12903
12904 ; This is to explain that changes to the stack pointer should
12905 ; not be moved over loads from or stores to stack memory.
12906 (define_insn "stack_tie"
12907 [(match_parallel 0 "tie_operand"
12908 [(set (mem:BLK (reg 1)) (const_int 0))])]
12909 ""
12910 ""
12911 [(set_attr "length" "0")])
12912
12913 ; Some 32-bit ABIs do not have a red zone, so the stack deallocation has to
12914 ; stay behind all restores from the stack, it cannot be reordered to before
12915 ; one. See PR77687. This insn is an add or mr, and a memory clobber.
12916 (define_insn "stack_restore_tie"
12917 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
12918 (plus:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
12919 (match_operand:SI 2 "reg_or_cint_operand" "O,rI")))
12920 (set (mem:BLK (scratch)) (const_int 0))]
12921 "TARGET_32BIT"
12922 "@
12923 mr %0,%1
12924 add%I2 %0,%1,%2"
12925 [(set_attr "type" "*,add")])
12926
12927 (define_expand "epilogue"
12928 [(use (const_int 0))]
12929 ""
12930 {
12931 if (!TARGET_SCHED_PROLOG)
12932 emit_insn (gen_blockage ());
12933 rs6000_emit_epilogue (FALSE);
12934 DONE;
12935 })
12936
12937 ; On some processors, doing the mtcrf one CC register at a time is
12938 ; faster (like on the 604e). On others, doing them all at once is
12939 ; faster; for instance, on the 601 and 750.
12940
12941 (define_expand "movsi_to_cr_one"
12942 [(set (match_operand:CC 0 "cc_reg_operand")
12943 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand")
12944 (match_dup 2)] UNSPEC_MOVESI_TO_CR))]
12945 ""
12946 "operands[2] = GEN_INT (1 << (75 - REGNO (operands[0])));")
12947
12948 (define_insn "*movsi_to_cr"
12949 [(match_parallel 0 "mtcrf_operation"
12950 [(set (match_operand:CC 1 "cc_reg_operand" "=y")
12951 (unspec:CC [(match_operand:SI 2 "gpc_reg_operand" "r")
12952 (match_operand 3 "immediate_operand" "n")]
12953 UNSPEC_MOVESI_TO_CR))])]
12954 ""
12955 {
12956 int mask = 0;
12957 int i;
12958 for (i = 0; i < XVECLEN (operands[0], 0); i++)
12959 mask |= INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
12960 operands[4] = GEN_INT (mask);
12961 return "mtcrf %4,%2";
12962 }
12963 [(set_attr "type" "mtcr")])
12964
12965 (define_insn "*mtcrfsi"
12966 [(set (match_operand:CC 0 "cc_reg_operand" "=y")
12967 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
12968 (match_operand 2 "immediate_operand" "n")]
12969 UNSPEC_MOVESI_TO_CR))]
12970 "GET_CODE (operands[0]) == REG
12971 && CR_REGNO_P (REGNO (operands[0]))
12972 && GET_CODE (operands[2]) == CONST_INT
12973 && INTVAL (operands[2]) == 1 << (75 - REGNO (operands[0]))"
12974 "mtcrf %R0,%1"
12975 [(set_attr "type" "mtcr")])
12976
12977 ; The load-multiple instructions have similar properties.
12978 ; Note that "load_multiple" is a name known to the machine-independent
12979 ; code that actually corresponds to the PowerPC load-string.
12980
12981 (define_insn "*lmw"
12982 [(match_parallel 0 "lmw_operation"
12983 [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
12984 (match_operand:SI 2 "memory_operand" "m"))])]
12985 "TARGET_MULTIPLE"
12986 "lmw %1,%2"
12987 [(set_attr "type" "load")
12988 (set_attr "update" "yes")
12989 (set_attr "indexed" "yes")
12990 (set_attr "cell_micro" "always")])
12991
12992 ; FIXME: "any_parallel_operand" is a bit flexible...
12993
12994 ; The following comment applies to:
12995 ; save_gpregs_*
12996 ; save_fpregs_*
12997 ; restore_gpregs*
12998 ; return_and_restore_gpregs*
12999 ; return_and_restore_fpregs*
13000 ; return_and_restore_fpregs_aix*
13001 ;
13002 ; The out-of-line save / restore functions expects one input argument.
13003 ; Since those are not standard call_insn's, we must avoid using
13004 ; MATCH_OPERAND for that argument. That way the register rename
13005 ; optimization will not try to rename this register.
13006 ; Each pattern is repeated for each possible register number used in
13007 ; various ABIs (r11, r1, and for some functions r12)
13008
13009 (define_insn "*restore_gpregs_<mode>_r11"
13010 [(match_parallel 0 "any_parallel_operand"
13011 [(clobber (reg:P LR_REGNO))
13012 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13013 (use (reg:P 11))
13014 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13015 (match_operand:P 3 "memory_operand" "m"))])]
13016 ""
13017 "bl %1"
13018 [(set_attr "type" "branch")])
13019
13020 (define_insn "*restore_gpregs_<mode>_r12"
13021 [(match_parallel 0 "any_parallel_operand"
13022 [(clobber (reg:P LR_REGNO))
13023 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13024 (use (reg:P 12))
13025 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13026 (match_operand:P 3 "memory_operand" "m"))])]
13027 ""
13028 "bl %1"
13029 [(set_attr "type" "branch")])
13030
13031 (define_insn "*restore_gpregs_<mode>_r1"
13032 [(match_parallel 0 "any_parallel_operand"
13033 [(clobber (reg:P LR_REGNO))
13034 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13035 (use (reg:P 1))
13036 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13037 (match_operand:P 3 "memory_operand" "m"))])]
13038 ""
13039 "bl %1"
13040 [(set_attr "type" "branch")])
13041
13042 (define_insn "*return_and_restore_gpregs_<mode>_r11"
13043 [(match_parallel 0 "any_parallel_operand"
13044 [(return)
13045 (clobber (reg:P LR_REGNO))
13046 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13047 (use (reg:P 11))
13048 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13049 (match_operand:P 3 "memory_operand" "m"))])]
13050 ""
13051 "b %1"
13052 [(set_attr "type" "branch")])
13053
13054 (define_insn "*return_and_restore_gpregs_<mode>_r12"
13055 [(match_parallel 0 "any_parallel_operand"
13056 [(return)
13057 (clobber (reg:P LR_REGNO))
13058 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13059 (use (reg:P 12))
13060 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13061 (match_operand:P 3 "memory_operand" "m"))])]
13062 ""
13063 "b %1"
13064 [(set_attr "type" "branch")])
13065
13066 (define_insn "*return_and_restore_gpregs_<mode>_r1"
13067 [(match_parallel 0 "any_parallel_operand"
13068 [(return)
13069 (clobber (reg:P LR_REGNO))
13070 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13071 (use (reg:P 1))
13072 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13073 (match_operand:P 3 "memory_operand" "m"))])]
13074 ""
13075 "b %1"
13076 [(set_attr "type" "branch")])
13077
13078 (define_insn "*return_and_restore_fpregs_<mode>_r11"
13079 [(match_parallel 0 "any_parallel_operand"
13080 [(return)
13081 (clobber (reg:P LR_REGNO))
13082 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13083 (use (reg:P 11))
13084 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13085 (match_operand:DF 3 "memory_operand" "m"))])]
13086 ""
13087 "b %1"
13088 [(set_attr "type" "branch")])
13089
13090 (define_insn "*return_and_restore_fpregs_<mode>_r12"
13091 [(match_parallel 0 "any_parallel_operand"
13092 [(return)
13093 (clobber (reg:P LR_REGNO))
13094 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13095 (use (reg:P 12))
13096 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13097 (match_operand:DF 3 "memory_operand" "m"))])]
13098 ""
13099 "b %1"
13100 [(set_attr "type" "branch")])
13101
13102 (define_insn "*return_and_restore_fpregs_<mode>_r1"
13103 [(match_parallel 0 "any_parallel_operand"
13104 [(return)
13105 (clobber (reg:P LR_REGNO))
13106 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13107 (use (reg:P 1))
13108 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13109 (match_operand:DF 3 "memory_operand" "m"))])]
13110 ""
13111 "b %1"
13112 [(set_attr "type" "branch")])
13113
13114 (define_insn "*return_and_restore_fpregs_aix_<mode>_r11"
13115 [(match_parallel 0 "any_parallel_operand"
13116 [(return)
13117 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13118 (use (reg:P 11))
13119 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13120 (match_operand:DF 3 "memory_operand" "m"))])]
13121 ""
13122 "b %1"
13123 [(set_attr "type" "branch")])
13124
13125 (define_insn "*return_and_restore_fpregs_aix_<mode>_r1"
13126 [(match_parallel 0 "any_parallel_operand"
13127 [(return)
13128 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13129 (use (reg:P 1))
13130 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13131 (match_operand:DF 3 "memory_operand" "m"))])]
13132 ""
13133 "b %1"
13134 [(set_attr "type" "branch")])
13135
13136 ; This is used in compiling the unwind routines.
13137 (define_expand "eh_return"
13138 [(use (match_operand 0 "general_operand"))]
13139 ""
13140 {
13141 if (TARGET_32BIT)
13142 emit_insn (gen_eh_set_lr_si (operands[0]));
13143 else
13144 emit_insn (gen_eh_set_lr_di (operands[0]));
13145 DONE;
13146 })
13147
13148 ; We can't expand this before we know where the link register is stored.
13149 (define_insn "eh_set_lr_<mode>"
13150 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
13151 UNSPECV_EH_RR)
13152 (clobber (match_scratch:P 1 "=&b"))]
13153 ""
13154 "#")
13155
13156 (define_split
13157 [(unspec_volatile [(match_operand 0 "register_operand")] UNSPECV_EH_RR)
13158 (clobber (match_scratch 1))]
13159 "reload_completed"
13160 [(const_int 0)]
13161 {
13162 rs6000_emit_eh_reg_restore (operands[0], operands[1]);
13163 DONE;
13164 })
13165
13166 (define_insn "prefetch"
13167 [(prefetch (match_operand 0 "indexed_or_indirect_address" "a")
13168 (match_operand:SI 1 "const_int_operand" "n")
13169 (match_operand:SI 2 "const_int_operand" "n"))]
13170 ""
13171 {
13172
13173
13174 /* dcbtstt, dcbtt and TH=0b10000 support starts with ISA 2.06 (Power7).
13175 AIX does not support the dcbtstt and dcbtt extended mnemonics.
13176 The AIX assembler does not support the three operand form of dcbt
13177 and dcbtst on Power 7 (-mpwr7). */
13178 int inst_select = INTVAL (operands[2]) || !TARGET_DIRECT_MOVE;
13179
13180 if (REG_P (operands[0]))
13181 {
13182 if (INTVAL (operands[1]) == 0)
13183 return inst_select ? "dcbt 0,%0" : "dcbt 0,%0,16";
13184 else
13185 return inst_select ? "dcbtst 0,%0" : "dcbtst 0,%0,16";
13186 }
13187 else
13188 {
13189 if (INTVAL (operands[1]) == 0)
13190 return inst_select ? "dcbt %a0" : "dcbt %a0,16";
13191 else
13192 return inst_select ? "dcbtst %a0" : "dcbtst %a0,16";
13193 }
13194 }
13195 [(set_attr "type" "load")])
13196 \f
13197 ;; Handle -fsplit-stack.
13198
13199 (define_expand "split_stack_prologue"
13200 [(const_int 0)]
13201 ""
13202 {
13203 rs6000_expand_split_stack_prologue ();
13204 DONE;
13205 })
13206
13207 (define_expand "load_split_stack_limit"
13208 [(set (match_operand 0)
13209 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))]
13210 ""
13211 {
13212 emit_insn (gen_rtx_SET (operands[0],
13213 gen_rtx_UNSPEC (Pmode,
13214 gen_rtvec (1, const0_rtx),
13215 UNSPEC_STACK_CHECK)));
13216 DONE;
13217 })
13218
13219 (define_insn "load_split_stack_limit_di"
13220 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
13221 (unspec:DI [(const_int 0)] UNSPEC_STACK_CHECK))]
13222 "TARGET_64BIT"
13223 "ld %0,-0x7040(13)"
13224 [(set_attr "type" "load")
13225 (set_attr "update" "no")
13226 (set_attr "indexed" "no")])
13227
13228 (define_insn "load_split_stack_limit_si"
13229 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
13230 (unspec:SI [(const_int 0)] UNSPEC_STACK_CHECK))]
13231 "!TARGET_64BIT"
13232 "lwz %0,-0x7020(2)"
13233 [(set_attr "type" "load")
13234 (set_attr "update" "no")
13235 (set_attr "indexed" "no")])
13236
13237 ;; A return instruction which the middle-end doesn't see.
13238 ;; Use r0 to stop regrename twiddling with lr restore insns emitted
13239 ;; after the call to __morestack.
13240 (define_insn "split_stack_return"
13241 [(unspec_volatile [(reg:SI 0) (reg:SI LR_REGNO)] UNSPECV_SPLIT_STACK_RETURN)]
13242 ""
13243 "blr"
13244 [(set_attr "type" "jmpreg")])
13245
13246 ;; If there are operand 0 bytes available on the stack, jump to
13247 ;; operand 1.
13248 (define_expand "split_stack_space_check"
13249 [(set (match_dup 2)
13250 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
13251 (set (match_dup 3)
13252 (minus (reg STACK_POINTER_REGNUM)
13253 (match_operand 0)))
13254 (set (match_dup 4) (compare:CCUNS (match_dup 3) (match_dup 2)))
13255 (set (pc) (if_then_else
13256 (geu (match_dup 4) (const_int 0))
13257 (label_ref (match_operand 1))
13258 (pc)))]
13259 ""
13260 {
13261 rs6000_split_stack_space_check (operands[0], operands[1]);
13262 DONE;
13263 })
13264 \f
13265 (define_insn "bpermd_<mode>"
13266 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
13267 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "r")
13268 (match_operand:P 2 "gpc_reg_operand" "r")] UNSPEC_BPERM))]
13269 "TARGET_POPCNTD"
13270 "bpermd %0,%1,%2"
13271 [(set_attr "type" "popcnt")])
13272
13273 \f
13274 ;; Builtin fma support. Handle
13275 ;; Note that the conditions for expansion are in the FMA_F iterator.
13276
13277 (define_expand "fma<mode>4"
13278 [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13279 (fma:FMA_F
13280 (match_operand:FMA_F 1 "gpc_reg_operand")
13281 (match_operand:FMA_F 2 "gpc_reg_operand")
13282 (match_operand:FMA_F 3 "gpc_reg_operand")))]
13283 ""
13284 "")
13285
13286 (define_insn "*fma<mode>4_fpr"
13287 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13288 (fma:SFDF
13289 (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>,<Fv2>")
13290 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13291 (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>")))]
13292 "TARGET_HARD_FLOAT"
13293 "@
13294 fmadd<Ftrad> %0,%1,%2,%3
13295 xsmadda<Fvsx> %x0,%x1,%x2
13296 xsmaddm<Fvsx> %x0,%x1,%x3"
13297 [(set_attr "type" "fp")])
13298
13299 ; Altivec only has fma and nfms.
13300 (define_expand "fms<mode>4"
13301 [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13302 (fma:FMA_F
13303 (match_operand:FMA_F 1 "gpc_reg_operand")
13304 (match_operand:FMA_F 2 "gpc_reg_operand")
13305 (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand"))))]
13306 "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13307 "")
13308
13309 (define_insn "*fms<mode>4_fpr"
13310 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13311 (fma:SFDF
13312 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
13313 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13314 (neg:SFDF (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>"))))]
13315 "TARGET_HARD_FLOAT"
13316 "@
13317 fmsub<Ftrad> %0,%1,%2,%3
13318 xsmsuba<Fvsx> %x0,%x1,%x2
13319 xsmsubm<Fvsx> %x0,%x1,%x3"
13320 [(set_attr "type" "fp")])
13321
13322 ;; If signed zeros are ignored, -(a * b - c) = -a * b + c.
13323 (define_expand "fnma<mode>4"
13324 [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13325 (neg:FMA_F
13326 (fma:FMA_F
13327 (match_operand:FMA_F 1 "gpc_reg_operand")
13328 (match_operand:FMA_F 2 "gpc_reg_operand")
13329 (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand")))))]
13330 "!HONOR_SIGNED_ZEROS (<MODE>mode)"
13331 "")
13332
13333 ;; If signed zeros are ignored, -(a * b + c) = -a * b - c.
13334 (define_expand "fnms<mode>4"
13335 [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13336 (neg:FMA_F
13337 (fma:FMA_F
13338 (match_operand:FMA_F 1 "gpc_reg_operand")
13339 (match_operand:FMA_F 2 "gpc_reg_operand")
13340 (match_operand:FMA_F 3 "gpc_reg_operand"))))]
13341 "!HONOR_SIGNED_ZEROS (<MODE>mode) && !VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13342 "")
13343
13344 ; Not an official optab name, but used from builtins.
13345 (define_expand "nfma<mode>4"
13346 [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13347 (neg:FMA_F
13348 (fma:FMA_F
13349 (match_operand:FMA_F 1 "gpc_reg_operand")
13350 (match_operand:FMA_F 2 "gpc_reg_operand")
13351 (match_operand:FMA_F 3 "gpc_reg_operand"))))]
13352 "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13353 "")
13354
13355 (define_insn "*nfma<mode>4_fpr"
13356 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13357 (neg:SFDF
13358 (fma:SFDF
13359 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
13360 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13361 (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>"))))]
13362 "TARGET_HARD_FLOAT"
13363 "@
13364 fnmadd<Ftrad> %0,%1,%2,%3
13365 xsnmadda<Fvsx> %x0,%x1,%x2
13366 xsnmaddm<Fvsx> %x0,%x1,%x3"
13367 [(set_attr "type" "fp")])
13368
13369 ; Not an official optab name, but used from builtins.
13370 (define_expand "nfms<mode>4"
13371 [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13372 (neg:FMA_F
13373 (fma:FMA_F
13374 (match_operand:FMA_F 1 "gpc_reg_operand")
13375 (match_operand:FMA_F 2 "gpc_reg_operand")
13376 (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand")))))]
13377 ""
13378 "")
13379
13380 (define_insn "*nfmssf4_fpr"
13381 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13382 (neg:SFDF
13383 (fma:SFDF
13384 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
13385 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13386 (neg:SFDF
13387 (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>")))))]
13388 "TARGET_HARD_FLOAT"
13389 "@
13390 fnmsub<Ftrad> %0,%1,%2,%3
13391 xsnmsuba<Fvsx> %x0,%x1,%x2
13392 xsnmsubm<Fvsx> %x0,%x1,%x3"
13393 [(set_attr "type" "fp")])
13394
13395 \f
13396 (define_expand "rs6000_get_timebase"
13397 [(use (match_operand:DI 0 "gpc_reg_operand"))]
13398 ""
13399 {
13400 if (TARGET_POWERPC64)
13401 emit_insn (gen_rs6000_mftb_di (operands[0]));
13402 else
13403 emit_insn (gen_rs6000_get_timebase_ppc32 (operands[0]));
13404 DONE;
13405 })
13406
13407 (define_insn "rs6000_get_timebase_ppc32"
13408 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
13409 (unspec_volatile:DI [(const_int 0)] UNSPECV_MFTB))
13410 (clobber (match_scratch:SI 1 "=r"))
13411 (clobber (match_scratch:CC 2 "=y"))]
13412 "!TARGET_POWERPC64"
13413 {
13414 if (WORDS_BIG_ENDIAN)
13415 if (TARGET_MFCRF)
13416 {
13417 return "mfspr %0,269\;"
13418 "mfspr %L0,268\;"
13419 "mfspr %1,269\;"
13420 "cmpw %2,%0,%1\;"
13421 "bne- %2,$-16";
13422 }
13423 else
13424 {
13425 return "mftbu %0\;"
13426 "mftb %L0\;"
13427 "mftbu %1\;"
13428 "cmpw %2,%0,%1\;"
13429 "bne- %2,$-16";
13430 }
13431 else
13432 if (TARGET_MFCRF)
13433 {
13434 return "mfspr %L0,269\;"
13435 "mfspr %0,268\;"
13436 "mfspr %1,269\;"
13437 "cmpw %2,%L0,%1\;"
13438 "bne- %2,$-16";
13439 }
13440 else
13441 {
13442 return "mftbu %L0\;"
13443 "mftb %0\;"
13444 "mftbu %1\;"
13445 "cmpw %2,%L0,%1\;"
13446 "bne- %2,$-16";
13447 }
13448 }
13449 [(set_attr "length" "20")])
13450
13451 (define_insn "rs6000_mftb_<mode>"
13452 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
13453 (unspec_volatile:GPR [(const_int 0)] UNSPECV_MFTB))]
13454 ""
13455 {
13456 if (TARGET_MFCRF)
13457 return "mfspr %0,268";
13458 else
13459 return "mftb %0";
13460 })
13461
13462 \f
13463 ;; The ISA 3.0 mffsl instruction is a lower latency instruction
13464 ;; for reading bits [29:31], [45:51] and [56:63] of the FPSCR.
13465 (define_insn "rs6000_mffsl_hw"
13466 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
13467 (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFSL))]
13468 "TARGET_HARD_FLOAT"
13469 "mffsl %0")
13470
13471 (define_expand "rs6000_mffsl"
13472 [(set (match_operand:DF 0 "gpc_reg_operand")
13473 (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFSL))]
13474 "TARGET_HARD_FLOAT"
13475 {
13476 /* If the low latency mffsl instruction (ISA 3.0) is available use it,
13477 otherwise fall back to the older mffs instruction to emulate the mffsl
13478 instruction. */
13479
13480 if (!TARGET_P9_MISC)
13481 {
13482 rtx tmp_di = gen_reg_rtx (DImode);
13483 rtx tmp_df = gen_reg_rtx (DFmode);
13484
13485 /* The mffs instruction reads the entire FPSCR. Emulate the mffsl
13486 instruction using the mffs instruction and masking off the bits
13487 the mmsl instruciton actually reads. */
13488 emit_insn (gen_rs6000_mffs (tmp_df));
13489 tmp_di = simplify_gen_subreg (DImode, tmp_df, DFmode, 0);
13490 emit_insn (gen_anddi3 (tmp_di, tmp_di, GEN_INT (0x70007f0ffLL)));
13491
13492 operands[0] = simplify_gen_subreg (DFmode, tmp_di, DImode, 0);
13493 DONE;
13494 }
13495
13496 emit_insn (gen_rs6000_mffsl_hw (operands[0]));
13497 DONE;
13498 })
13499
13500 (define_insn "rs6000_mffs"
13501 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
13502 (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFS))]
13503 "TARGET_HARD_FLOAT"
13504 "mffs %0")
13505
13506 (define_insn "rs6000_mtfsf"
13507 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "i")
13508 (match_operand:DF 1 "gpc_reg_operand" "d")]
13509 UNSPECV_MTFSF)]
13510 "TARGET_HARD_FLOAT"
13511 "mtfsf %0,%1")
13512
13513 (define_insn "rs6000_mtfsf_hi"
13514 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "n")
13515 (match_operand:DF 1 "gpc_reg_operand" "d")]
13516 UNSPECV_MTFSF_HI)]
13517 "TARGET_HARD_FLOAT"
13518 "mtfsf %0,%1,0,1")
13519
13520 \f
13521 ;; Power8 fusion support for fusing an addis instruction with a D-form load of
13522 ;; a GPR. The addis instruction must be adjacent to the load, and use the same
13523 ;; register that is being loaded. The fused ops must be physically adjacent.
13524
13525 ;; On Power8 GPR loads, we try to use the register that is being load. The
13526 ;; peephole2 then gathers any other fused possibilities that it can find after
13527 ;; register allocation. If power9 fusion is selected, we also fuse floating
13528 ;; point loads/stores.
13529
13530 ;; Find cases where the addis that feeds into a load instruction is either used
13531 ;; once or is the same as the target register, and replace it with the fusion
13532 ;; insn
13533
13534 (define_peephole2
13535 [(set (match_operand:P 0 "base_reg_operand")
13536 (match_operand:P 1 "fusion_gpr_addis"))
13537 (set (match_operand:INT1 2 "base_reg_operand")
13538 (match_operand:INT1 3 "fusion_gpr_mem_load"))]
13539 "TARGET_P8_FUSION
13540 && fusion_gpr_load_p (operands[0], operands[1], operands[2],
13541 operands[3])"
13542 [(const_int 0)]
13543 {
13544 expand_fusion_gpr_load (operands);
13545 DONE;
13546 })
13547
13548 ;; Fusion insn, created by the define_peephole2 above (and eventually by
13549 ;; reload)
13550
13551 (define_insn "*fusion_gpr_load_<mode>"
13552 [(set (match_operand:INT1 0 "base_reg_operand" "=b")
13553 (unspec:INT1 [(match_operand:INT1 1 "fusion_addis_mem_combo_load" "wF")]
13554 UNSPEC_FUSION_GPR))]
13555 "TARGET_P8_FUSION"
13556 {
13557 return emit_fusion_gpr_load (operands[0], operands[1]);
13558 }
13559 [(set_attr "type" "load")
13560 (set_attr "length" "8")])
13561
13562 \f
13563 ;; Optimize cases where we want to do a D-form load (register+offset) on
13564 ;; ISA 2.06/2.07 to an Altivec register, and the register allocator
13565 ;; has generated:
13566 ;; LFD 0,32(3)
13567 ;; XXLOR 32,0,0
13568 ;;
13569 ;; and we change this to:
13570 ;; LI 0,32
13571 ;; LXSDX 32,3,9
13572
13573 (define_peephole2
13574 [(match_scratch:P 0 "b")
13575 (set (match_operand:ALTIVEC_DFORM 1 "fpr_reg_operand")
13576 (match_operand:ALTIVEC_DFORM 2 "simple_offsettable_mem_operand"))
13577 (set (match_operand:ALTIVEC_DFORM 3 "altivec_register_operand")
13578 (match_dup 1))]
13579 "TARGET_VSX && !TARGET_P9_VECTOR && peep2_reg_dead_p (2, operands[1])"
13580 [(set (match_dup 0)
13581 (match_dup 4))
13582 (set (match_dup 3)
13583 (match_dup 5))]
13584 {
13585 rtx tmp_reg = operands[0];
13586 rtx mem = operands[2];
13587 rtx addr = XEXP (mem, 0);
13588 rtx add_op0, add_op1, new_addr;
13589
13590 gcc_assert (GET_CODE (addr) == PLUS || GET_CODE (addr) == LO_SUM);
13591 add_op0 = XEXP (addr, 0);
13592 add_op1 = XEXP (addr, 1);
13593 gcc_assert (REG_P (add_op0));
13594 new_addr = gen_rtx_PLUS (Pmode, add_op0, tmp_reg);
13595
13596 operands[4] = add_op1;
13597 operands[5] = change_address (mem, <MODE>mode, new_addr);
13598 })
13599
13600 ;; Optimize cases were want to do a D-form store on ISA 2.06/2.07 from an
13601 ;; Altivec register, and the register allocator has generated:
13602 ;; XXLOR 0,32,32
13603 ;; STFD 0,32(3)
13604 ;;
13605 ;; and we change this to:
13606 ;; LI 0,32
13607 ;; STXSDX 32,3,9
13608
13609 (define_peephole2
13610 [(match_scratch:P 0 "b")
13611 (set (match_operand:ALTIVEC_DFORM 1 "fpr_reg_operand")
13612 (match_operand:ALTIVEC_DFORM 2 "altivec_register_operand"))
13613 (set (match_operand:ALTIVEC_DFORM 3 "simple_offsettable_mem_operand")
13614 (match_dup 1))]
13615 "TARGET_VSX && !TARGET_P9_VECTOR && peep2_reg_dead_p (2, operands[1])"
13616 [(set (match_dup 0)
13617 (match_dup 4))
13618 (set (match_dup 5)
13619 (match_dup 2))]
13620 {
13621 rtx tmp_reg = operands[0];
13622 rtx mem = operands[3];
13623 rtx addr = XEXP (mem, 0);
13624 rtx add_op0, add_op1, new_addr;
13625
13626 gcc_assert (GET_CODE (addr) == PLUS || GET_CODE (addr) == LO_SUM);
13627 add_op0 = XEXP (addr, 0);
13628 add_op1 = XEXP (addr, 1);
13629 gcc_assert (REG_P (add_op0));
13630 new_addr = gen_rtx_PLUS (Pmode, add_op0, tmp_reg);
13631
13632 operands[4] = add_op1;
13633 operands[5] = change_address (mem, <MODE>mode, new_addr);
13634 })
13635
13636 \f
13637 ;; Miscellaneous ISA 2.06 (power7) instructions
13638 (define_insn "addg6s"
13639 [(set (match_operand:SI 0 "register_operand" "=r")
13640 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
13641 (match_operand:SI 2 "register_operand" "r")]
13642 UNSPEC_ADDG6S))]
13643 "TARGET_POPCNTD"
13644 "addg6s %0,%1,%2"
13645 [(set_attr "type" "integer")])
13646
13647 (define_insn "cdtbcd"
13648 [(set (match_operand:SI 0 "register_operand" "=r")
13649 (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
13650 UNSPEC_CDTBCD))]
13651 "TARGET_POPCNTD"
13652 "cdtbcd %0,%1"
13653 [(set_attr "type" "integer")])
13654
13655 (define_insn "cbcdtd"
13656 [(set (match_operand:SI 0 "register_operand" "=r")
13657 (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
13658 UNSPEC_CBCDTD))]
13659 "TARGET_POPCNTD"
13660 "cbcdtd %0,%1"
13661 [(set_attr "type" "integer")])
13662
13663 (define_int_iterator UNSPEC_DIV_EXTEND [UNSPEC_DIVE
13664 UNSPEC_DIVEU])
13665
13666 (define_int_attr div_extend [(UNSPEC_DIVE "e")
13667 (UNSPEC_DIVEU "eu")])
13668
13669 (define_insn "div<div_extend>_<mode>"
13670 [(set (match_operand:GPR 0 "register_operand" "=r")
13671 (unspec:GPR [(match_operand:GPR 1 "register_operand" "r")
13672 (match_operand:GPR 2 "register_operand" "r")]
13673 UNSPEC_DIV_EXTEND))]
13674 "TARGET_POPCNTD"
13675 "div<wd><div_extend> %0,%1,%2"
13676 [(set_attr "type" "div")
13677 (set_attr "size" "<bits>")])
13678
13679 \f
13680 ;; Pack/unpack 128-bit floating point types that take 2 scalar registers
13681
13682 ; Type of the 64-bit part when packing/unpacking 128-bit floating point types
13683 (define_mode_attr FP128_64 [(TF "DF")
13684 (IF "DF")
13685 (TD "DI")
13686 (KF "DI")])
13687
13688 (define_expand "unpack<mode>"
13689 [(set (match_operand:<FP128_64> 0 "nonimmediate_operand")
13690 (unspec:<FP128_64>
13691 [(match_operand:FMOVE128 1 "register_operand")
13692 (match_operand:QI 2 "const_0_to_1_operand")]
13693 UNSPEC_UNPACK_128BIT))]
13694 "FLOAT128_2REG_P (<MODE>mode)"
13695 "")
13696
13697 (define_insn_and_split "unpack<mode>_dm"
13698 [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m,d,r,m")
13699 (unspec:<FP128_64>
13700 [(match_operand:FMOVE128 1 "register_operand" "d,d,r,d,r")
13701 (match_operand:QI 2 "const_0_to_1_operand" "i,i,i,i,i")]
13702 UNSPEC_UNPACK_128BIT))]
13703 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE && FLOAT128_2REG_P (<MODE>mode)"
13704 "#"
13705 "&& reload_completed"
13706 [(set (match_dup 0) (match_dup 3))]
13707 {
13708 unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
13709
13710 if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
13711 {
13712 emit_note (NOTE_INSN_DELETED);
13713 DONE;
13714 }
13715
13716 operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
13717 }
13718 [(set_attr "type" "fp,fpstore,mffgpr,mftgpr,store")])
13719
13720 (define_insn_and_split "unpack<mode>_nodm"
13721 [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m")
13722 (unspec:<FP128_64>
13723 [(match_operand:FMOVE128 1 "register_operand" "d,d")
13724 (match_operand:QI 2 "const_0_to_1_operand" "i,i")]
13725 UNSPEC_UNPACK_128BIT))]
13726 "(!TARGET_POWERPC64 || !TARGET_DIRECT_MOVE) && FLOAT128_2REG_P (<MODE>mode)"
13727 "#"
13728 "&& reload_completed"
13729 [(set (match_dup 0) (match_dup 3))]
13730 {
13731 unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
13732
13733 if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
13734 {
13735 emit_note (NOTE_INSN_DELETED);
13736 DONE;
13737 }
13738
13739 operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
13740 }
13741 [(set_attr "type" "fp,fpstore")])
13742
13743 (define_insn_and_split "pack<mode>"
13744 [(set (match_operand:FMOVE128 0 "register_operand" "=&d")
13745 (unspec:FMOVE128
13746 [(match_operand:<FP128_64> 1 "register_operand" "d")
13747 (match_operand:<FP128_64> 2 "register_operand" "d")]
13748 UNSPEC_PACK_128BIT))]
13749 "FLOAT128_2REG_P (<MODE>mode)"
13750 "#"
13751 "&& reload_completed"
13752 [(set (match_dup 3) (match_dup 1))
13753 (set (match_dup 4) (match_dup 2))]
13754 {
13755 unsigned dest_hi = REGNO (operands[0]);
13756 unsigned dest_lo = dest_hi + 1;
13757
13758 gcc_assert (!IN_RANGE (REGNO (operands[1]), dest_hi, dest_lo));
13759 gcc_assert (!IN_RANGE (REGNO (operands[2]), dest_hi, dest_lo));
13760
13761 operands[3] = gen_rtx_REG (<FP128_64>mode, dest_hi);
13762 operands[4] = gen_rtx_REG (<FP128_64>mode, dest_lo);
13763 }
13764 [(set_attr "type" "fp")
13765 (set_attr "length" "8")])
13766
13767 (define_insn "unpack<mode>"
13768 [(set (match_operand:DI 0 "register_operand" "=wa,wa")
13769 (unspec:DI [(match_operand:FMOVE128_VSX 1 "register_operand" "0,wa")
13770 (match_operand:QI 2 "const_0_to_1_operand" "O,i")]
13771 UNSPEC_UNPACK_128BIT))]
13772 "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)"
13773 {
13774 if (REGNO (operands[0]) == REGNO (operands[1]) && INTVAL (operands[2]) == 0)
13775 return ASM_COMMENT_START " xxpermdi to same register";
13776
13777 operands[3] = GEN_INT (INTVAL (operands[2]) == 0 ? 0 : 3);
13778 return "xxpermdi %x0,%x1,%x1,%3";
13779 }
13780 [(set_attr "type" "vecperm")])
13781
13782 (define_insn "pack<mode>"
13783 [(set (match_operand:FMOVE128_VSX 0 "register_operand" "=wa")
13784 (unspec:FMOVE128_VSX
13785 [(match_operand:DI 1 "register_operand" "wa")
13786 (match_operand:DI 2 "register_operand" "wa")]
13787 UNSPEC_PACK_128BIT))]
13788 "TARGET_VSX"
13789 "xxpermdi %x0,%x1,%x2,0"
13790 [(set_attr "type" "vecperm")])
13791
13792
13793 \f
13794 ;; ISA 2.08 IEEE 128-bit floating point support.
13795
13796 (define_insn "add<mode>3"
13797 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13798 (plus:IEEE128
13799 (match_operand:IEEE128 1 "altivec_register_operand" "v")
13800 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13801 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13802 "xsaddqp %0,%1,%2"
13803 [(set_attr "type" "vecfloat")
13804 (set_attr "size" "128")])
13805
13806 (define_insn "sub<mode>3"
13807 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13808 (minus:IEEE128
13809 (match_operand:IEEE128 1 "altivec_register_operand" "v")
13810 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13811 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13812 "xssubqp %0,%1,%2"
13813 [(set_attr "type" "vecfloat")
13814 (set_attr "size" "128")])
13815
13816 (define_insn "mul<mode>3"
13817 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13818 (mult:IEEE128
13819 (match_operand:IEEE128 1 "altivec_register_operand" "v")
13820 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13821 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13822 "xsmulqp %0,%1,%2"
13823 [(set_attr "type" "qmul")
13824 (set_attr "size" "128")])
13825
13826 (define_insn "div<mode>3"
13827 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13828 (div:IEEE128
13829 (match_operand:IEEE128 1 "altivec_register_operand" "v")
13830 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13831 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13832 "xsdivqp %0,%1,%2"
13833 [(set_attr "type" "vecdiv")
13834 (set_attr "size" "128")])
13835
13836 (define_insn "sqrt<mode>2"
13837 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13838 (sqrt:IEEE128
13839 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
13840 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13841 "xssqrtqp %0,%1"
13842 [(set_attr "type" "vecdiv")
13843 (set_attr "size" "128")])
13844
13845 (define_expand "copysign<mode>3"
13846 [(use (match_operand:IEEE128 0 "altivec_register_operand"))
13847 (use (match_operand:IEEE128 1 "altivec_register_operand"))
13848 (use (match_operand:IEEE128 2 "altivec_register_operand"))]
13849 "FLOAT128_IEEE_P (<MODE>mode)"
13850 {
13851 if (TARGET_FLOAT128_HW)
13852 emit_insn (gen_copysign<mode>3_hard (operands[0], operands[1],
13853 operands[2]));
13854 else
13855 emit_insn (gen_copysign<mode>3_soft (operands[0], operands[1],
13856 operands[2]));
13857 DONE;
13858 })
13859
13860 (define_insn "copysign<mode>3_hard"
13861 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13862 (unspec:IEEE128
13863 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
13864 (match_operand:IEEE128 2 "altivec_register_operand" "v")]
13865 UNSPEC_COPYSIGN))]
13866 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13867 "xscpsgnqp %0,%2,%1"
13868 [(set_attr "type" "vecmove")
13869 (set_attr "size" "128")])
13870
13871 (define_insn "copysign<mode>3_soft"
13872 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13873 (unspec:IEEE128
13874 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
13875 (match_operand:IEEE128 2 "altivec_register_operand" "v")]
13876 UNSPEC_COPYSIGN))
13877 (clobber (match_scratch:IEEE128 3 "=&v"))]
13878 "!TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13879 "xscpsgndp %x3,%x2,%x1\;xxpermdi %x0,%x3,%x1,1"
13880 [(set_attr "type" "veccomplex")
13881 (set_attr "length" "8")])
13882
13883 (define_insn "neg<mode>2_hw"
13884 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13885 (neg:IEEE128
13886 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
13887 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13888 "xsnegqp %0,%1"
13889 [(set_attr "type" "vecmove")
13890 (set_attr "size" "128")])
13891
13892
13893 (define_insn "abs<mode>2_hw"
13894 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13895 (abs:IEEE128
13896 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
13897 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13898 "xsabsqp %0,%1"
13899 [(set_attr "type" "vecmove")
13900 (set_attr "size" "128")])
13901
13902
13903 (define_insn "*nabs<mode>2_hw"
13904 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13905 (neg:IEEE128
13906 (abs:IEEE128
13907 (match_operand:IEEE128 1 "altivec_register_operand" "v"))))]
13908 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13909 "xsnabsqp %0,%1"
13910 [(set_attr "type" "vecmove")
13911 (set_attr "size" "128")])
13912
13913 ;; Initially don't worry about doing fusion
13914 (define_insn "fma<mode>4_hw"
13915 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13916 (fma:IEEE128
13917 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
13918 (match_operand:IEEE128 2 "altivec_register_operand" "v")
13919 (match_operand:IEEE128 3 "altivec_register_operand" "0")))]
13920 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13921 "xsmaddqp %0,%1,%2"
13922 [(set_attr "type" "qmul")
13923 (set_attr "size" "128")])
13924
13925 (define_insn "*fms<mode>4_hw"
13926 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13927 (fma:IEEE128
13928 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
13929 (match_operand:IEEE128 2 "altivec_register_operand" "v")
13930 (neg:IEEE128
13931 (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
13932 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13933 "xsmsubqp %0,%1,%2"
13934 [(set_attr "type" "qmul")
13935 (set_attr "size" "128")])
13936
13937 (define_insn "*nfma<mode>4_hw"
13938 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13939 (neg:IEEE128
13940 (fma:IEEE128
13941 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
13942 (match_operand:IEEE128 2 "altivec_register_operand" "v")
13943 (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
13944 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13945 "xsnmaddqp %0,%1,%2"
13946 [(set_attr "type" "qmul")
13947 (set_attr "size" "128")])
13948
13949 (define_insn "*nfms<mode>4_hw"
13950 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13951 (neg:IEEE128
13952 (fma:IEEE128
13953 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
13954 (match_operand:IEEE128 2 "altivec_register_operand" "v")
13955 (neg:IEEE128
13956 (match_operand:IEEE128 3 "altivec_register_operand" "0")))))]
13957 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13958 "xsnmsubqp %0,%1,%2"
13959 [(set_attr "type" "qmul")
13960 (set_attr "size" "128")])
13961
13962 (define_insn "extend<SFDF:mode><IEEE128:mode>2_hw"
13963 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13964 (float_extend:IEEE128
13965 (match_operand:SFDF 1 "altivec_register_operand" "v")))]
13966 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
13967 "xscvdpqp %0,%1"
13968 [(set_attr "type" "vecfloat")
13969 (set_attr "size" "128")])
13970
13971 ;; Conversion between KFmode and TFmode if TFmode is ieee 128-bit floating
13972 ;; point is a simple copy.
13973 (define_insn_and_split "extendkftf2"
13974 [(set (match_operand:TF 0 "vsx_register_operand" "=wa,?wa")
13975 (float_extend:TF (match_operand:KF 1 "vsx_register_operand" "0,wa")))]
13976 "TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD"
13977 "@
13978 #
13979 xxlor %x0,%x1,%x1"
13980 "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
13981 [(const_int 0)]
13982 {
13983 emit_note (NOTE_INSN_DELETED);
13984 DONE;
13985 }
13986 [(set_attr "type" "*,veclogical")
13987 (set_attr "length" "0,4")])
13988
13989 (define_insn_and_split "trunctfkf2"
13990 [(set (match_operand:KF 0 "vsx_register_operand" "=wa,?wa")
13991 (float_extend:KF (match_operand:TF 1 "vsx_register_operand" "0,wa")))]
13992 "TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD"
13993 "@
13994 #
13995 xxlor %x0,%x1,%x1"
13996 "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
13997 [(const_int 0)]
13998 {
13999 emit_note (NOTE_INSN_DELETED);
14000 DONE;
14001 }
14002 [(set_attr "type" "*,veclogical")
14003 (set_attr "length" "0,4")])
14004
14005 (define_insn "trunc<mode>df2_hw"
14006 [(set (match_operand:DF 0 "altivec_register_operand" "=v")
14007 (float_truncate:DF
14008 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14009 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14010 "xscvqpdp %0,%1"
14011 [(set_attr "type" "vecfloat")
14012 (set_attr "size" "128")])
14013
14014 ;; There is no KFmode -> SFmode instruction. Preserve the accuracy by doing
14015 ;; the KFmode -> DFmode conversion using round to odd rather than the normal
14016 ;; conversion
14017 (define_insn_and_split "trunc<mode>sf2_hw"
14018 [(set (match_operand:SF 0 "vsx_register_operand" "=wy")
14019 (float_truncate:SF
14020 (match_operand:IEEE128 1 "altivec_register_operand" "v")))
14021 (clobber (match_scratch:DF 2 "=v"))]
14022 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14023 "#"
14024 "&& 1"
14025 [(set (match_dup 2)
14026 (unspec:DF [(match_dup 1)]
14027 UNSPEC_TRUNC_ROUND_TO_ODD))
14028 (set (match_dup 0)
14029 (float_truncate:SF (match_dup 2)))]
14030 {
14031 if (GET_CODE (operands[2]) == SCRATCH)
14032 operands[2] = gen_reg_rtx (DFmode);
14033 }
14034 [(set_attr "type" "vecfloat")
14035 (set_attr "length" "8")])
14036
14037 ;; Conversion between IEEE 128-bit and integer types
14038
14039 ;; The fix function for DImode and SImode was declared earlier as a
14040 ;; define_expand. It calls into rs6000_expand_float128_convert if we don't
14041 ;; have IEEE 128-bit hardware support. QImode and HImode are not provided
14042 ;; unless we have the IEEE 128-bit hardware.
14043 ;;
14044 ;; Unlike the code for converting SFmode/DFmode to QImode/HImode, we don't have
14045 ;; to provide a GPR target that used direct move and a conversion in the GPR
14046 ;; which works around QImode/HImode not being allowed in vector registers in
14047 ;; ISA 2.07 (power8).
14048 (define_insn "fix<uns>_<IEEE128:mode><SDI:mode>2_hw"
14049 [(set (match_operand:SDI 0 "altivec_register_operand" "=v")
14050 (any_fix:SDI (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14051 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14052 "xscvqp<su><wd>z %0,%1"
14053 [(set_attr "type" "vecfloat")
14054 (set_attr "size" "128")])
14055
14056 (define_insn "fix<uns>_trunc<IEEE128:mode><QHI:mode>2"
14057 [(set (match_operand:QHI 0 "altivec_register_operand" "=v")
14058 (any_fix:QHI
14059 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14060 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14061 "xscvqp<su>wz %0,%1"
14062 [(set_attr "type" "vecfloat")
14063 (set_attr "size" "128")])
14064
14065 ;; Combiner patterns to prevent moving the result of converting an IEEE 128-bit
14066 ;; floating point value to 8/16/32-bit integer to GPR in order to save it.
14067 (define_insn_and_split "*fix<uns>_trunc<IEEE128:mode><QHSI:mode>2_mem"
14068 [(set (match_operand:QHSI 0 "memory_operand" "=Z")
14069 (any_fix:QHSI
14070 (match_operand:IEEE128 1 "altivec_register_operand" "v")))
14071 (clobber (match_scratch:QHSI 2 "=v"))]
14072 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14073 "#"
14074 "&& reload_completed"
14075 [(set (match_dup 2)
14076 (any_fix:QHSI (match_dup 1)))
14077 (set (match_dup 0)
14078 (match_dup 2))])
14079
14080 (define_insn "float_<mode>di2_hw"
14081 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14082 (float:IEEE128 (match_operand:DI 1 "altivec_register_operand" "v")))]
14083 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14084 "xscvsdqp %0,%1"
14085 [(set_attr "type" "vecfloat")
14086 (set_attr "size" "128")])
14087
14088 (define_insn_and_split "float_<mode>si2_hw"
14089 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14090 (float:IEEE128 (match_operand:SI 1 "nonimmediate_operand" "vrZ")))
14091 (clobber (match_scratch:DI 2 "=v"))]
14092 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14093 "#"
14094 "&& 1"
14095 [(set (match_dup 2)
14096 (sign_extend:DI (match_dup 1)))
14097 (set (match_dup 0)
14098 (float:IEEE128 (match_dup 2)))]
14099 {
14100 if (GET_CODE (operands[2]) == SCRATCH)
14101 operands[2] = gen_reg_rtx (DImode);
14102
14103 if (MEM_P (operands[1]))
14104 operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
14105 })
14106
14107 (define_insn_and_split "float<QHI:mode><IEEE128:mode>2"
14108 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v")
14109 (float:IEEE128 (match_operand:QHI 1 "nonimmediate_operand" "v,r,Z")))
14110 (clobber (match_scratch:DI 2 "=X,r,X"))]
14111 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14112 "#"
14113 "&& reload_completed"
14114 [(const_int 0)]
14115 {
14116 rtx dest = operands[0];
14117 rtx src = operands[1];
14118 rtx dest_di = gen_rtx_REG (DImode, REGNO (dest));
14119
14120 if (altivec_register_operand (src, <QHI:MODE>mode))
14121 emit_insn (gen_extend<QHI:mode>di2 (dest_di, src));
14122 else if (int_reg_operand (src, <QHI:MODE>mode))
14123 {
14124 rtx ext_di = operands[2];
14125 emit_insn (gen_extend<QHI:mode>di2 (ext_di, src));
14126 emit_move_insn (dest_di, ext_di);
14127 }
14128 else if (MEM_P (src))
14129 {
14130 rtx dest_qhi = gen_rtx_REG (<QHI:MODE>mode, REGNO (dest));
14131 emit_move_insn (dest_qhi, src);
14132 emit_insn (gen_extend<QHI:mode>di2 (dest_di, dest_qhi));
14133 }
14134 else
14135 gcc_unreachable ();
14136
14137 emit_insn (gen_float_<IEEE128:mode>di2_hw (dest, dest_di));
14138 DONE;
14139 }
14140 [(set_attr "length" "8,12,12")
14141 (set_attr "type" "vecfloat")
14142 (set_attr "size" "128")])
14143
14144 (define_insn "floatuns_<mode>di2_hw"
14145 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14146 (unsigned_float:IEEE128
14147 (match_operand:DI 1 "altivec_register_operand" "v")))]
14148 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14149 "xscvudqp %0,%1"
14150 [(set_attr "type" "vecfloat")
14151 (set_attr "size" "128")])
14152
14153 (define_insn_and_split "floatuns_<mode>si2_hw"
14154 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14155 (unsigned_float:IEEE128
14156 (match_operand:SI 1 "nonimmediate_operand" "vrZ")))
14157 (clobber (match_scratch:DI 2 "=v"))]
14158 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14159 "#"
14160 "&& 1"
14161 [(set (match_dup 2)
14162 (zero_extend:DI (match_dup 1)))
14163 (set (match_dup 0)
14164 (float:IEEE128 (match_dup 2)))]
14165 {
14166 if (GET_CODE (operands[2]) == SCRATCH)
14167 operands[2] = gen_reg_rtx (DImode);
14168
14169 if (MEM_P (operands[1]))
14170 operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
14171 })
14172
14173 (define_insn_and_split "floatuns<QHI:mode><IEEE128:mode>2"
14174 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v")
14175 (unsigned_float:IEEE128
14176 (match_operand:QHI 1 "nonimmediate_operand" "v,r,Z")))
14177 (clobber (match_scratch:DI 2 "=X,r,X"))]
14178 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14179 "#"
14180 "&& reload_completed"
14181 [(const_int 0)]
14182 {
14183 rtx dest = operands[0];
14184 rtx src = operands[1];
14185 rtx dest_di = gen_rtx_REG (DImode, REGNO (dest));
14186
14187 if (altivec_register_operand (src, <QHI:MODE>mode) || MEM_P (src))
14188 emit_insn (gen_zero_extend<QHI:mode>di2 (dest_di, src));
14189 else if (int_reg_operand (src, <QHI:MODE>mode))
14190 {
14191 rtx ext_di = operands[2];
14192 emit_insn (gen_zero_extend<QHI:mode>di2 (ext_di, src));
14193 emit_move_insn (dest_di, ext_di);
14194 }
14195 else
14196 gcc_unreachable ();
14197
14198 emit_insn (gen_floatuns_<IEEE128:mode>di2_hw (dest, dest_di));
14199 DONE;
14200 }
14201 [(set_attr "length" "8,12,8")
14202 (set_attr "type" "vecfloat")
14203 (set_attr "size" "128")])
14204
14205 ;; IEEE 128-bit round to integer built-in functions
14206 (define_insn "floor<mode>2"
14207 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14208 (unspec:IEEE128
14209 [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14210 UNSPEC_FRIM))]
14211 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14212 "xsrqpi 1,%0,%1,3"
14213 [(set_attr "type" "vecfloat")
14214 (set_attr "size" "128")])
14215
14216 (define_insn "ceil<mode>2"
14217 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14218 (unspec:IEEE128
14219 [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14220 UNSPEC_FRIP))]
14221 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14222 "xsrqpi 1,%0,%1,2"
14223 [(set_attr "type" "vecfloat")
14224 (set_attr "size" "128")])
14225
14226 (define_insn "btrunc<mode>2"
14227 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14228 (unspec:IEEE128
14229 [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14230 UNSPEC_FRIZ))]
14231 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14232 "xsrqpi 1,%0,%1,1"
14233 [(set_attr "type" "vecfloat")
14234 (set_attr "size" "128")])
14235
14236 (define_insn "round<mode>2"
14237 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14238 (unspec:IEEE128
14239 [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14240 UNSPEC_FRIN))]
14241 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14242 "xsrqpi 0,%0,%1,0"
14243 [(set_attr "type" "vecfloat")
14244 (set_attr "size" "128")])
14245
14246 ;; IEEE 128-bit instructions with round to odd semantics
14247 (define_insn "add<mode>3_odd"
14248 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14249 (unspec:IEEE128
14250 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14251 (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14252 UNSPEC_ADD_ROUND_TO_ODD))]
14253 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14254 "xsaddqpo %0,%1,%2"
14255 [(set_attr "type" "vecfloat")
14256 (set_attr "size" "128")])
14257
14258 (define_insn "sub<mode>3_odd"
14259 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14260 (unspec:IEEE128
14261 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14262 (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14263 UNSPEC_SUB_ROUND_TO_ODD))]
14264 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14265 "xssubqpo %0,%1,%2"
14266 [(set_attr "type" "vecfloat")
14267 (set_attr "size" "128")])
14268
14269 (define_insn "mul<mode>3_odd"
14270 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14271 (unspec:IEEE128
14272 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14273 (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14274 UNSPEC_MUL_ROUND_TO_ODD))]
14275 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14276 "xsmulqpo %0,%1,%2"
14277 [(set_attr "type" "qmul")
14278 (set_attr "size" "128")])
14279
14280 (define_insn "div<mode>3_odd"
14281 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14282 (unspec:IEEE128
14283 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14284 (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14285 UNSPEC_DIV_ROUND_TO_ODD))]
14286 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14287 "xsdivqpo %0,%1,%2"
14288 [(set_attr "type" "vecdiv")
14289 (set_attr "size" "128")])
14290
14291 (define_insn "sqrt<mode>2_odd"
14292 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14293 (unspec:IEEE128
14294 [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14295 UNSPEC_SQRT_ROUND_TO_ODD))]
14296 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14297 "xssqrtqpo %0,%1"
14298 [(set_attr "type" "vecdiv")
14299 (set_attr "size" "128")])
14300
14301 (define_insn "fma<mode>4_odd"
14302 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14303 (unspec:IEEE128
14304 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14305 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14306 (match_operand:IEEE128 3 "altivec_register_operand" "0")]
14307 UNSPEC_FMA_ROUND_TO_ODD))]
14308 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14309 "xsmaddqpo %0,%1,%2"
14310 [(set_attr "type" "qmul")
14311 (set_attr "size" "128")])
14312
14313 (define_insn "*fms<mode>4_odd"
14314 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14315 (unspec:IEEE128
14316 [(match_operand:IEEE128 1 "altivec_register_operand" "%v")
14317 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14318 (neg:IEEE128
14319 (match_operand:IEEE128 3 "altivec_register_operand" "0"))]
14320 UNSPEC_FMA_ROUND_TO_ODD))]
14321 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14322 "xsmsubqpo %0,%1,%2"
14323 [(set_attr "type" "qmul")
14324 (set_attr "size" "128")])
14325
14326 (define_insn "*nfma<mode>4_odd"
14327 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14328 (neg:IEEE128
14329 (unspec:IEEE128
14330 [(match_operand:IEEE128 1 "altivec_register_operand" "%v")
14331 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14332 (match_operand:IEEE128 3 "altivec_register_operand" "0")]
14333 UNSPEC_FMA_ROUND_TO_ODD)))]
14334 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14335 "xsnmaddqpo %0,%1,%2"
14336 [(set_attr "type" "qmul")
14337 (set_attr "size" "128")])
14338
14339 (define_insn "*nfms<mode>4_odd"
14340 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14341 (neg:IEEE128
14342 (unspec:IEEE128
14343 [(match_operand:IEEE128 1 "altivec_register_operand" "%v")
14344 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14345 (neg:IEEE128
14346 (match_operand:IEEE128 3 "altivec_register_operand" "0"))]
14347 UNSPEC_FMA_ROUND_TO_ODD)))]
14348 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14349 "xsnmsubqpo %0,%1,%2"
14350 [(set_attr "type" "qmul")
14351 (set_attr "size" "128")])
14352
14353 (define_insn "trunc<mode>df2_odd"
14354 [(set (match_operand:DF 0 "vsx_register_operand" "=v")
14355 (unspec:DF [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14356 UNSPEC_TRUNC_ROUND_TO_ODD))]
14357 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14358 "xscvqpdpo %0,%1"
14359 [(set_attr "type" "vecfloat")
14360 (set_attr "size" "128")])
14361
14362 ;; IEEE 128-bit comparisons
14363 (define_insn "*cmp<mode>_hw"
14364 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
14365 (compare:CCFP (match_operand:IEEE128 1 "altivec_register_operand" "v")
14366 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14367 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14368 "xscmpuqp %0,%1,%2"
14369 [(set_attr "type" "veccmp")
14370 (set_attr "size" "128")])
14371
14372 \f
14373
14374 (include "sync.md")
14375 (include "vector.md")
14376 (include "vsx.md")
14377 (include "altivec.md")
14378 (include "dfp.md")
14379 (include "crypto.md")
14380 (include "htm.md")