26b0962ae7d4c62a85121f17538497f3faa8cd1b
[gcc.git] / gcc / config / rs6000 / rs6000.md
1 ;; Machine description for IBM RISC System 6000 (POWER) for GNU C compiler
2 ;; Copyright (C) 1990-2015 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 (SPE_ACC_REGNO 111)
54 (SPEFSCR_REGNO 112)
55 (FRAME_POINTER_REGNUM 113)
56 (TFHAR_REGNO 114)
57 (TFIAR_REGNO 115)
58 (TEXASR_REGNO 116)
59 (FIRST_SPE_HIGH_REGNO 117)
60 (LAST_SPE_HIGH_REGNO 148)
61 ])
62
63 ;;
64 ;; UNSPEC usage
65 ;;
66
67 (define_c_enum "unspec"
68 [UNSPEC_FRSP ; frsp for POWER machines
69 UNSPEC_PROBE_STACK ; probe stack memory reference
70 UNSPEC_TOCPTR ; address of a word pointing to the TOC
71 UNSPEC_TOC ; address of the TOC (more-or-less)
72 UNSPEC_TOCSLOT ; offset from r1 of toc pointer save slot
73 UNSPEC_MOVSI_GOT
74 UNSPEC_MV_CR_OV ; move_from_CR_ov_bit
75 UNSPEC_FCTIWZ
76 UNSPEC_FRIM
77 UNSPEC_FRIN
78 UNSPEC_FRIP
79 UNSPEC_FRIZ
80 UNSPEC_XSRDPI
81 UNSPEC_LD_MPIC ; load_macho_picbase
82 UNSPEC_RELD_MPIC ; re-load_macho_picbase
83 UNSPEC_MPIC_CORRECT ; macho_correct_pic
84 UNSPEC_TLSGD
85 UNSPEC_TLSLD
86 UNSPEC_MOVESI_FROM_CR
87 UNSPEC_MOVESI_TO_CR
88 UNSPEC_TLSDTPREL
89 UNSPEC_TLSDTPRELHA
90 UNSPEC_TLSDTPRELLO
91 UNSPEC_TLSGOTDTPREL
92 UNSPEC_TLSTPREL
93 UNSPEC_TLSTPRELHA
94 UNSPEC_TLSTPRELLO
95 UNSPEC_TLSGOTTPREL
96 UNSPEC_TLSTLS
97 UNSPEC_FIX_TRUNC_TF ; fadd, rounding towards zero
98 UNSPEC_MV_CR_GT ; move_from_CR_gt_bit
99 UNSPEC_STFIWX
100 UNSPEC_POPCNTB
101 UNSPEC_FRES
102 UNSPEC_SP_SET
103 UNSPEC_SP_TEST
104 UNSPEC_SYNC
105 UNSPEC_LWSYNC
106 UNSPEC_SYNC_OP
107 UNSPEC_ATOMIC
108 UNSPEC_CMPXCHG
109 UNSPEC_XCHG
110 UNSPEC_AND
111 UNSPEC_DLMZB
112 UNSPEC_DLMZB_CR
113 UNSPEC_DLMZB_STRLEN
114 UNSPEC_RSQRT
115 UNSPEC_TOCREL
116 UNSPEC_MACHOPIC_OFFSET
117 UNSPEC_BPERM
118 UNSPEC_COPYSIGN
119 UNSPEC_PARITY
120 UNSPEC_FCTIW
121 UNSPEC_FCTID
122 UNSPEC_LFIWAX
123 UNSPEC_LFIWZX
124 UNSPEC_FCTIWUZ
125 UNSPEC_NOP
126 UNSPEC_GRP_END_NOP
127 UNSPEC_P8V_FMRGOW
128 UNSPEC_P8V_MTVSRWZ
129 UNSPEC_P8V_RELOAD_FROM_GPR
130 UNSPEC_P8V_MTVSRD
131 UNSPEC_P8V_XXPERMDI
132 UNSPEC_P8V_RELOAD_FROM_VSX
133 UNSPEC_ADDG6S
134 UNSPEC_CDTBCD
135 UNSPEC_CBCDTD
136 UNSPEC_DIVE
137 UNSPEC_DIVEO
138 UNSPEC_DIVEU
139 UNSPEC_DIVEUO
140 UNSPEC_UNPACK_128BIT
141 UNSPEC_PACK_128BIT
142 UNSPEC_LSQ
143 UNSPEC_FUSION_GPR
144 UNSPEC_STACK_CHECK
145 UNSPEC_FUSION_P9
146 UNSPEC_FUSION_ADDIS
147 UNSPEC_ROUND_TO_ODD
148 UNSPEC_IEEE128_MOVE
149 UNSPEC_IEEE128_CONVERT
150 ])
151
152 ;;
153 ;; UNSPEC_VOLATILE usage
154 ;;
155
156 (define_c_enum "unspecv"
157 [UNSPECV_BLOCK
158 UNSPECV_LL ; load-locked
159 UNSPECV_SC ; store-conditional
160 UNSPECV_PROBE_STACK_RANGE ; probe range of stack addresses
161 UNSPECV_EH_RR ; eh_reg_restore
162 UNSPECV_ISYNC ; isync instruction
163 UNSPECV_MFTB ; move from time base
164 UNSPECV_NLGR ; non-local goto receiver
165 UNSPECV_MFFS ; Move from FPSCR
166 UNSPECV_MTFSF ; Move to FPSCR Fields
167 UNSPECV_SPLIT_STACK_RETURN ; A camouflaged return
168 ])
169
170 \f
171 ;; Define an insn type attribute. This is used in function unit delay
172 ;; computations.
173 (define_attr "type"
174 "integer,two,three,
175 add,logical,shift,insert,
176 mul,halfmul,div,
177 exts,cntlz,popcnt,isel,
178 load,store,fpload,fpstore,vecload,vecstore,
179 cmp,
180 branch,jmpreg,mfjmpr,mtjmpr,trap,isync,sync,load_l,store_c,
181 cr_logical,delayed_cr,mfcr,mfcrf,mtcr,
182 fpcompare,fp,fpsimple,dmul,sdiv,ddiv,ssqrt,dsqrt,
183 brinc,
184 vecsimple,veccomplex,vecdiv,veccmp,veccmpsimple,vecperm,
185 vecfloat,vecfdiv,vecdouble,mffgpr,mftgpr,crypto,
186 htm"
187 (const_string "integer"))
188
189 ;; What data size does this instruction work on?
190 ;; This is used for insert, mul.
191 (define_attr "size" "8,16,32,64" (const_string "32"))
192
193 ;; Is this instruction record form ("dot", signed compare to 0, writing CR0)?
194 ;; This is used for add, logical, shift, exts, mul.
195 (define_attr "dot" "no,yes" (const_string "no"))
196
197 ;; Does this instruction sign-extend its result?
198 ;; This is used for load insns.
199 (define_attr "sign_extend" "no,yes" (const_string "no"))
200
201 ;; Does this instruction use indexed (that is, reg+reg) addressing?
202 ;; This is used for load and store insns. If operand 0 or 1 is a MEM
203 ;; it is automatically set based on that. If a load or store instruction
204 ;; has fewer than two operands it needs to set this attribute manually
205 ;; or the compiler will crash.
206 (define_attr "indexed" "no,yes"
207 (if_then_else (ior (match_operand 0 "indexed_address_mem")
208 (match_operand 1 "indexed_address_mem"))
209 (const_string "yes")
210 (const_string "no")))
211
212 ;; Does this instruction use update addressing?
213 ;; This is used for load and store insns. See the comments for "indexed".
214 (define_attr "update" "no,yes"
215 (if_then_else (ior (match_operand 0 "update_address_mem")
216 (match_operand 1 "update_address_mem"))
217 (const_string "yes")
218 (const_string "no")))
219
220 ;; Is this instruction using operands[2] as shift amount, and can that be a
221 ;; register?
222 ;; This is used for shift insns.
223 (define_attr "maybe_var_shift" "no,yes" (const_string "no"))
224
225 ;; Is this instruction using a shift amount from a register?
226 ;; This is used for shift insns.
227 (define_attr "var_shift" "no,yes"
228 (if_then_else (and (eq_attr "type" "shift")
229 (eq_attr "maybe_var_shift" "yes"))
230 (if_then_else (match_operand 2 "gpc_reg_operand")
231 (const_string "yes")
232 (const_string "no"))
233 (const_string "no")))
234
235 ;; Is copying of this instruction disallowed?
236 (define_attr "cannot_copy" "no,yes" (const_string "no"))
237
238 ;; Define floating point instruction sub-types for use with Xfpu.md
239 (define_attr "fp_type" "fp_default,fp_addsub_s,fp_addsub_d,fp_mul_s,fp_mul_d,fp_div_s,fp_div_d,fp_maddsub_s,fp_maddsub_d,fp_sqrt_s,fp_sqrt_d" (const_string "fp_default"))
240
241 ;; Length (in bytes).
242 ; '(pc)' in the following doesn't include the instruction itself; it is
243 ; calculated as if the instruction had zero size.
244 (define_attr "length" ""
245 (if_then_else (eq_attr "type" "branch")
246 (if_then_else (and (ge (minus (match_dup 0) (pc))
247 (const_int -32768))
248 (lt (minus (match_dup 0) (pc))
249 (const_int 32764)))
250 (const_int 4)
251 (const_int 8))
252 (const_int 4)))
253
254 ;; Processor type -- this attribute must exactly match the processor_type
255 ;; enumeration in rs6000-opts.h.
256 (define_attr "cpu"
257 "ppc601,ppc603,ppc604,ppc604e,ppc620,ppc630,
258 ppc750,ppc7400,ppc7450,
259 ppc403,ppc405,ppc440,ppc476,
260 ppc8540,ppc8548,ppce300c2,ppce300c3,ppce500mc,ppce500mc64,ppce5500,ppce6500,
261 power4,power5,power6,power7,power8,power9,
262 rs64a,mpccore,cell,ppca2,titan"
263 (const (symbol_ref "rs6000_cpu_attr")))
264
265
266 ;; If this instruction is microcoded on the CELL processor
267 ; The default for load extended, the recorded instructions and rotate/shifts by a variable is always microcoded
268 (define_attr "cell_micro" "not,conditional,always"
269 (if_then_else (ior (and (eq_attr "type" "shift,exts,mul")
270 (eq_attr "dot" "yes"))
271 (and (eq_attr "type" "load")
272 (eq_attr "sign_extend" "yes"))
273 (and (eq_attr "type" "shift")
274 (eq_attr "var_shift" "yes")))
275 (const_string "always")
276 (const_string "not")))
277
278 (automata_option "ndfa")
279
280 (include "rs64.md")
281 (include "mpc.md")
282 (include "40x.md")
283 (include "440.md")
284 (include "476.md")
285 (include "601.md")
286 (include "603.md")
287 (include "6xx.md")
288 (include "7xx.md")
289 (include "7450.md")
290 (include "8540.md")
291 (include "e300c2c3.md")
292 (include "e500mc.md")
293 (include "e500mc64.md")
294 (include "e5500.md")
295 (include "e6500.md")
296 (include "power4.md")
297 (include "power5.md")
298 (include "power6.md")
299 (include "power7.md")
300 (include "power8.md")
301 (include "cell.md")
302 (include "xfpu.md")
303 (include "a2.md")
304 (include "titan.md")
305
306 (include "predicates.md")
307 (include "constraints.md")
308
309 (include "darwin.md")
310
311 \f
312 ;; Mode iterators
313
314 ; This mode iterator allows :GPR to be used to indicate the allowable size
315 ; of whole values in GPRs.
316 (define_mode_iterator GPR [SI (DI "TARGET_POWERPC64")])
317
318 ; Any supported integer mode.
319 (define_mode_iterator INT [QI HI SI DI TI PTI])
320
321 ; Any supported integer mode that fits in one register.
322 (define_mode_iterator INT1 [QI HI SI (DI "TARGET_POWERPC64")])
323
324 ; Everything we can extend QImode to.
325 (define_mode_iterator EXTQI [HI SI (DI "TARGET_POWERPC64")])
326
327 ; Everything we can extend HImode to.
328 (define_mode_iterator EXTHI [SI (DI "TARGET_POWERPC64")])
329
330 ; Everything we can extend SImode to.
331 (define_mode_iterator EXTSI [(DI "TARGET_POWERPC64")])
332
333 ; QImode or HImode for small atomic ops
334 (define_mode_iterator QHI [QI HI])
335
336 ; QImode, HImode, SImode for fused ops only for GPR loads
337 (define_mode_iterator QHSI [QI HI SI])
338
339 ; HImode or SImode for sign extended fusion ops
340 (define_mode_iterator HSI [HI SI])
341
342 ; SImode or DImode, even if DImode doesn't fit in GPRs.
343 (define_mode_iterator SDI [SI DI])
344
345 ; Types that can be fused with an ADDIS instruction to load or store a GPR
346 ; register that has reg+offset addressing.
347 (define_mode_iterator GPR_FUSION [QI
348 HI
349 SI
350 (DI "TARGET_POWERPC64")
351 SF
352 (DF "TARGET_POWERPC64")])
353
354 ; Types that can be fused with an ADDIS instruction to load or store a FPR
355 ; register that has reg+offset addressing.
356 (define_mode_iterator FPR_FUSION [DI SF DF])
357
358 ; The size of a pointer. Also, the size of the value that a record-condition
359 ; (one with a '.') will compare; and the size used for arithmetic carries.
360 (define_mode_iterator P [(SI "TARGET_32BIT") (DI "TARGET_64BIT")])
361
362 ; Iterator to add PTImode along with TImode (TImode can go in VSX registers,
363 ; PTImode is GPR only)
364 (define_mode_iterator TI2 [TI PTI])
365
366 ; Any hardware-supported floating-point mode
367 (define_mode_iterator FP [
368 (SF "TARGET_HARD_FLOAT
369 && ((TARGET_FPRS && TARGET_SINGLE_FLOAT) || TARGET_E500_SINGLE)")
370 (DF "TARGET_HARD_FLOAT
371 && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)")
372 (TF "TARGET_HARD_FLOAT
373 && (TARGET_FPRS || TARGET_E500_DOUBLE)
374 && TARGET_LONG_DOUBLE_128")
375 (IF "TARGET_FLOAT128")
376 (KF "TARGET_FLOAT128")
377 (DD "TARGET_DFP")
378 (TD "TARGET_DFP")])
379
380 ; Any fma capable floating-point mode.
381 (define_mode_iterator FMA_F [
382 (SF "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT")
383 (DF "(TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
384 || VECTOR_UNIT_VSX_P (DFmode)")
385 (V2SF "TARGET_PAIRED_FLOAT")
386 (V4SF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)")
387 (V2DF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V2DFmode)")
388 (KF "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (KFmode)")
389 (TF "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (TFmode)")
390 ])
391
392 ; Floating point move iterators to combine binary and decimal moves
393 (define_mode_iterator FMOVE32 [SF SD])
394 (define_mode_iterator FMOVE64 [DF DD])
395 (define_mode_iterator FMOVE64X [DI DF DD])
396 (define_mode_iterator FMOVE128 [(TF "TARGET_LONG_DOUBLE_128")
397 (IF "TARGET_LONG_DOUBLE_128")
398 (TD "TARGET_HARD_FLOAT && TARGET_FPRS")])
399
400 (define_mode_iterator FMOVE128_FPR [(TF "FLOAT128_2REG_P (TFmode)")
401 (IF "FLOAT128_2REG_P (IFmode)")
402 (TD "TARGET_HARD_FLOAT && TARGET_FPRS")])
403
404 ; Iterators for 128 bit types for direct move
405 (define_mode_iterator FMOVE128_GPR [(TI "TARGET_VSX_TIMODE")
406 (V16QI "")
407 (V8HI "")
408 (V4SI "")
409 (V4SF "")
410 (V2DI "")
411 (V2DF "")
412 (V1TI "")
413 (KF "FLOAT128_VECTOR_P (KFmode)")
414 (TF "FLOAT128_VECTOR_P (TFmode)")])
415
416 ; Iterator for 128-bit VSX types for pack/unpack
417 (define_mode_iterator FMOVE128_VSX [V1TI KF])
418
419 ; Whether a floating point move is ok, don't allow SD without hardware FP
420 (define_mode_attr fmove_ok [(SF "")
421 (DF "")
422 (SD "TARGET_HARD_FLOAT && TARGET_FPRS")
423 (DD "")])
424
425 ; Convert REAL_VALUE to the appropriate bits
426 (define_mode_attr real_value_to_target [(SF "REAL_VALUE_TO_TARGET_SINGLE")
427 (DF "REAL_VALUE_TO_TARGET_DOUBLE")
428 (SD "REAL_VALUE_TO_TARGET_DECIMAL32")
429 (DD "REAL_VALUE_TO_TARGET_DECIMAL64")])
430
431 ; Definitions for load to 32-bit fpr register
432 (define_mode_attr f32_lr [(SF "f") (SD "wz")])
433 (define_mode_attr f32_lr2 [(SF "wb") (SD "wn")])
434 (define_mode_attr f32_lm [(SF "m") (SD "Z")])
435 (define_mode_attr f32_lm2 [(SF "o") (SD "wn")])
436 (define_mode_attr f32_li [(SF "lfs%U1%X1 %0,%1") (SD "lfiwzx %0,%y1")])
437 (define_mode_attr f32_li2 [(SF "lxssp %0,%1") (SD "lfiwzx %0,%y1")])
438 (define_mode_attr f32_lv [(SF "lxsspx %x0,%y1") (SD "lxsiwzx %x0,%y1")])
439
440 ; Definitions for store from 32-bit fpr register
441 (define_mode_attr f32_sr [(SF "f") (SD "wx")])
442 (define_mode_attr f32_sr2 [(SF "wb") (SD "wn")])
443 (define_mode_attr f32_sm [(SF "m") (SD "Z")])
444 (define_mode_attr f32_sm2 [(SF "o") (SD "wn")])
445 (define_mode_attr f32_si [(SF "stfs%U0%X0 %1,%0") (SD "stfiwx %1,%y0")])
446 (define_mode_attr f32_si2 [(SF "stxssp %1,%0") (SD "stfiwx %1,%y0")])
447 (define_mode_attr f32_sv [(SF "stxsspx %x1,%y0") (SD "stxsiwzx %x1,%y0")])
448
449 ; Definitions for 32-bit fpr direct move
450 ; At present, the decimal modes are not allowed in the traditional altivec
451 ; registers, so restrict the constraints to just the traditional FPRs.
452 (define_mode_attr f32_dm [(SF "wn") (SD "wh")])
453
454 ; Definitions for 32-bit VSX
455 (define_mode_attr f32_vsx [(SF "ww") (SD "wn")])
456
457 ; Definitions for 32-bit use of altivec registers
458 (define_mode_attr f32_av [(SF "wu") (SD "wn")])
459
460 ; Definitions for 64-bit VSX
461 (define_mode_attr f64_vsx [(DF "ws") (DD "wn")])
462
463 ; Definitions for 64-bit direct move
464 (define_mode_attr f64_dm [(DF "wk") (DD "wh")])
465
466 ; Definitions for 64-bit use of altivec registers
467 (define_mode_attr f64_av [(DF "wv") (DD "wn")])
468
469 ; Definitions for 64-bit access to ISA 3.0 (power9) vector
470 (define_mode_attr f64_p9 [(DF "wb") (DD "wn")])
471
472 ; These modes do not fit in integer registers in 32-bit mode.
473 ; but on e500v2, the gpr are 64 bit registers
474 (define_mode_iterator DIFD [DI (DF "!TARGET_E500_DOUBLE") DD])
475
476 ; Iterator for reciprocal estimate instructions
477 (define_mode_iterator RECIPF [SF DF V4SF V2DF])
478
479 ; Iterator for just SF/DF
480 (define_mode_iterator SFDF [SF DF])
481
482 ; Iterator for 128-bit floating point that uses the IBM double-double format
483 (define_mode_iterator IBM128 [(IF "FLOAT128_IBM_P (IFmode)")
484 (TF "FLOAT128_IBM_P (TFmode)")])
485
486 ; Iterator for 128-bit floating point that uses IEEE 128-bit float
487 (define_mode_iterator IEEE128 [(KF "FLOAT128_IEEE_P (KFmode)")
488 (TF "FLOAT128_IEEE_P (TFmode)")])
489
490 ; Iterator for 128-bit floating point
491 (define_mode_iterator FLOAT128 [(KF "TARGET_FLOAT128")
492 (IF "TARGET_FLOAT128")
493 (TF "TARGET_LONG_DOUBLE_128")])
494
495 ; SF/DF suffix for traditional floating instructions
496 (define_mode_attr Ftrad [(SF "s") (DF "")])
497
498 ; SF/DF suffix for VSX instructions
499 (define_mode_attr Fvsx [(SF "sp") (DF "dp")])
500
501 ; SF/DF constraint for arithmetic on traditional floating point registers
502 (define_mode_attr Ff [(SF "f") (DF "d") (DI "d")])
503
504 ; SF/DF constraint for arithmetic on VSX registers using instructions added in
505 ; ISA 2.06 (power7). This includes instructions that normally target DF mode,
506 ; but are used on SFmode, since internally SFmode values are kept in the DFmode
507 ; format.
508 (define_mode_attr Fv [(SF "ww") (DF "ws") (DI "wi")])
509
510 ; SF/DF constraint for arithmetic on VSX registers. This is intended to be
511 ; used for DFmode instructions added in ISA 2.06 (power7) and SFmode
512 ; instructions added in ISA 2.07 (power8)
513 (define_mode_attr Fv2 [(SF "wy") (DF "ws") (DI "wi")])
514
515 ; SF/DF constraint for arithmetic on altivec registers
516 (define_mode_attr Fa [(SF "wu") (DF "wv")])
517
518 ; s/d suffix for things like fp_addsub_s/fp_addsub_d
519 (define_mode_attr Fs [(SF "s") (DF "d")])
520
521 ; FRE/FRES support
522 (define_mode_attr Ffre [(SF "fres") (DF "fre")])
523 (define_mode_attr FFRE [(SF "FRES") (DF "FRE")])
524
525 ; Conditional returns.
526 (define_code_iterator any_return [return simple_return])
527 (define_code_attr return_pred [(return "direct_return ()")
528 (simple_return "1")])
529 (define_code_attr return_str [(return "") (simple_return "simple_")])
530
531 ; Logical operators.
532 (define_code_iterator iorxor [ior xor])
533
534 ; Signed/unsigned variants of ops.
535 (define_code_iterator any_extend [sign_extend zero_extend])
536 (define_code_iterator any_fix [fix unsigned_fix])
537 (define_code_iterator any_float [float unsigned_float])
538
539 (define_code_attr u [(sign_extend "")
540 (zero_extend "u")])
541
542 (define_code_attr su [(sign_extend "s")
543 (zero_extend "u")
544 (fix "s")
545 (unsigned_fix "s")
546 (float "s")
547 (unsigned_float "u")])
548
549 (define_code_attr az [(sign_extend "a")
550 (zero_extend "z")
551 (fix "a")
552 (unsigned_fix "z")
553 (float "a")
554 (unsigned_float "z")])
555
556 (define_code_attr uns [(fix "")
557 (unsigned_fix "uns")
558 (float "")
559 (unsigned_float "uns")])
560
561 ; Various instructions that come in SI and DI forms.
562 ; A generic w/d attribute, for things like cmpw/cmpd.
563 (define_mode_attr wd [(QI "b")
564 (HI "h")
565 (SI "w")
566 (DI "d")
567 (V16QI "b")
568 (V8HI "h")
569 (V4SI "w")
570 (V2DI "d")])
571
572 ;; How many bits in this mode?
573 (define_mode_attr bits [(QI "8") (HI "16") (SI "32") (DI "64")])
574
575 ; DImode bits
576 (define_mode_attr dbits [(QI "56") (HI "48") (SI "32")])
577
578 ;; ISEL/ISEL64 target selection
579 (define_mode_attr sel [(SI "") (DI "64")])
580
581 ;; Bitmask for shift instructions
582 (define_mode_attr hH [(SI "h") (DI "H")])
583
584 ;; A mode twice the size of the given mode
585 (define_mode_attr dmode [(SI "di") (DI "ti")])
586 (define_mode_attr DMODE [(SI "DI") (DI "TI")])
587
588 ;; Suffix for reload patterns
589 (define_mode_attr ptrsize [(SI "32bit")
590 (DI "64bit")])
591
592 (define_mode_attr tptrsize [(SI "TARGET_32BIT")
593 (DI "TARGET_64BIT")])
594
595 (define_mode_attr mptrsize [(SI "si")
596 (DI "di")])
597
598 (define_mode_attr ptrload [(SI "lwz")
599 (DI "ld")])
600
601 (define_mode_attr ptrm [(SI "m")
602 (DI "Y")])
603
604 (define_mode_attr rreg [(SF "f")
605 (DF "ws")
606 (TF "f")
607 (TD "f")
608 (V4SF "wf")
609 (V2DF "wd")])
610
611 (define_mode_attr rreg2 [(SF "f")
612 (DF "d")])
613
614 (define_mode_attr SI_CONVERT_FP [(SF "TARGET_FCFIDS")
615 (DF "TARGET_FCFID")])
616
617 (define_mode_attr E500_CONVERT [(SF "!TARGET_FPRS")
618 (DF "TARGET_E500_DOUBLE")])
619
620 (define_mode_attr TARGET_FLOAT [(SF "TARGET_SINGLE_FLOAT")
621 (DF "TARGET_DOUBLE_FLOAT")])
622
623 ;; Mode iterator for logical operations on 128-bit types
624 (define_mode_iterator BOOL_128 [TI
625 PTI
626 (V16QI "TARGET_ALTIVEC")
627 (V8HI "TARGET_ALTIVEC")
628 (V4SI "TARGET_ALTIVEC")
629 (V4SF "TARGET_ALTIVEC")
630 (V2DI "TARGET_ALTIVEC")
631 (V2DF "TARGET_ALTIVEC")
632 (V1TI "TARGET_ALTIVEC")])
633
634 ;; For the GPRs we use 3 constraints for register outputs, two that are the
635 ;; same as the output register, and a third where the output register is an
636 ;; early clobber, so we don't have to deal with register overlaps. For the
637 ;; vector types, we prefer to use the vector registers. For TI mode, allow
638 ;; either.
639
640 ;; Mode attribute for boolean operation register constraints for output
641 (define_mode_attr BOOL_REGS_OUTPUT [(TI "&r,r,r,wt,v")
642 (PTI "&r,r,r")
643 (V16QI "wa,v,&?r,?r,?r")
644 (V8HI "wa,v,&?r,?r,?r")
645 (V4SI "wa,v,&?r,?r,?r")
646 (V4SF "wa,v,&?r,?r,?r")
647 (V2DI "wa,v,&?r,?r,?r")
648 (V2DF "wa,v,&?r,?r,?r")
649 (V1TI "wa,v,&?r,?r,?r")])
650
651 ;; Mode attribute for boolean operation register constraints for operand1
652 (define_mode_attr BOOL_REGS_OP1 [(TI "r,0,r,wt,v")
653 (PTI "r,0,r")
654 (V16QI "wa,v,r,0,r")
655 (V8HI "wa,v,r,0,r")
656 (V4SI "wa,v,r,0,r")
657 (V4SF "wa,v,r,0,r")
658 (V2DI "wa,v,r,0,r")
659 (V2DF "wa,v,r,0,r")
660 (V1TI "wa,v,r,0,r")])
661
662 ;; Mode attribute for boolean operation register constraints for operand2
663 (define_mode_attr BOOL_REGS_OP2 [(TI "r,r,0,wt,v")
664 (PTI "r,r,0")
665 (V16QI "wa,v,r,r,0")
666 (V8HI "wa,v,r,r,0")
667 (V4SI "wa,v,r,r,0")
668 (V4SF "wa,v,r,r,0")
669 (V2DI "wa,v,r,r,0")
670 (V2DF "wa,v,r,r,0")
671 (V1TI "wa,v,r,r,0")])
672
673 ;; Mode attribute for boolean operation register constraints for operand1
674 ;; for one_cmpl. To simplify things, we repeat the constraint where 0
675 ;; is used for operand1 or operand2
676 (define_mode_attr BOOL_REGS_UNARY [(TI "r,0,0,wt,v")
677 (PTI "r,0,0")
678 (V16QI "wa,v,r,0,0")
679 (V8HI "wa,v,r,0,0")
680 (V4SI "wa,v,r,0,0")
681 (V4SF "wa,v,r,0,0")
682 (V2DI "wa,v,r,0,0")
683 (V2DF "wa,v,r,0,0")
684 (V1TI "wa,v,r,0,0")])
685
686 ;; Reload iterator for creating the function to allocate a base register to
687 ;; supplement addressing modes.
688 (define_mode_iterator RELOAD [V16QI V8HI V4SI V2DI V4SF V2DF V1TI
689 SF SD SI DF DD DI TI PTI KF IF TF])
690
691 \f
692 ;; Start with fixed-point load and store insns. Here we put only the more
693 ;; complex forms. Basic data transfer is done later.
694
695 (define_insn "zero_extendqi<mode>2"
696 [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
697 (zero_extend:EXTQI (match_operand:QI 1 "reg_or_mem_operand" "m,r")))]
698 ""
699 "@
700 lbz%U1%X1 %0,%1
701 rlwinm %0,%1,0,0xff"
702 [(set_attr "type" "load,shift")])
703
704 (define_insn_and_split "*zero_extendqi<mode>2_dot"
705 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
706 (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
707 (const_int 0)))
708 (clobber (match_scratch:EXTQI 0 "=r,r"))]
709 "rs6000_gen_cell_microcode"
710 "@
711 andi. %0,%1,0xff
712 #"
713 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
714 [(set (match_dup 0)
715 (zero_extend:EXTQI (match_dup 1)))
716 (set (match_dup 2)
717 (compare:CC (match_dup 0)
718 (const_int 0)))]
719 ""
720 [(set_attr "type" "logical")
721 (set_attr "dot" "yes")
722 (set_attr "length" "4,8")])
723
724 (define_insn_and_split "*zero_extendqi<mode>2_dot2"
725 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
726 (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
727 (const_int 0)))
728 (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
729 (zero_extend:EXTQI (match_dup 1)))]
730 "rs6000_gen_cell_microcode"
731 "@
732 andi. %0,%1,0xff
733 #"
734 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
735 [(set (match_dup 0)
736 (zero_extend:EXTQI (match_dup 1)))
737 (set (match_dup 2)
738 (compare:CC (match_dup 0)
739 (const_int 0)))]
740 ""
741 [(set_attr "type" "logical")
742 (set_attr "dot" "yes")
743 (set_attr "length" "4,8")])
744
745
746 (define_insn "zero_extendhi<mode>2"
747 [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
748 (zero_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r")))]
749 ""
750 "@
751 lhz%U1%X1 %0,%1
752 rlwinm %0,%1,0,0xffff"
753 [(set_attr "type" "load,shift")])
754
755 (define_insn_and_split "*zero_extendhi<mode>2_dot"
756 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
757 (compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
758 (const_int 0)))
759 (clobber (match_scratch:EXTHI 0 "=r,r"))]
760 "rs6000_gen_cell_microcode"
761 "@
762 andi. %0,%1,0xffff
763 #"
764 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
765 [(set (match_dup 0)
766 (zero_extend:EXTHI (match_dup 1)))
767 (set (match_dup 2)
768 (compare:CC (match_dup 0)
769 (const_int 0)))]
770 ""
771 [(set_attr "type" "logical")
772 (set_attr "dot" "yes")
773 (set_attr "length" "4,8")])
774
775 (define_insn_and_split "*zero_extendhi<mode>2_dot2"
776 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
777 (compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
778 (const_int 0)))
779 (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
780 (zero_extend:EXTHI (match_dup 1)))]
781 "rs6000_gen_cell_microcode"
782 "@
783 andi. %0,%1,0xffff
784 #"
785 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
786 [(set (match_dup 0)
787 (zero_extend:EXTHI (match_dup 1)))
788 (set (match_dup 2)
789 (compare:CC (match_dup 0)
790 (const_int 0)))]
791 ""
792 [(set_attr "type" "logical")
793 (set_attr "dot" "yes")
794 (set_attr "length" "4,8")])
795
796
797 (define_insn "zero_extendsi<mode>2"
798 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r,??wj,!wz,!wu")
799 (zero_extend:EXTSI (match_operand:SI 1 "reg_or_mem_operand" "m,r,r,Z,Z")))]
800 ""
801 "@
802 lwz%U1%X1 %0,%1
803 rldicl %0,%1,0,32
804 mtvsrwz %x0,%1
805 lfiwzx %0,%y1
806 lxsiwzx %x0,%y1"
807 [(set_attr "type" "load,shift,mffgpr,fpload,fpload")])
808
809 (define_insn_and_split "*zero_extendsi<mode>2_dot"
810 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
811 (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
812 (const_int 0)))
813 (clobber (match_scratch:EXTSI 0 "=r,r"))]
814 "rs6000_gen_cell_microcode"
815 "@
816 rldicl. %0,%1,0,32
817 #"
818 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
819 [(set (match_dup 0)
820 (zero_extend:DI (match_dup 1)))
821 (set (match_dup 2)
822 (compare:CC (match_dup 0)
823 (const_int 0)))]
824 ""
825 [(set_attr "type" "shift")
826 (set_attr "dot" "yes")
827 (set_attr "length" "4,8")])
828
829 (define_insn_and_split "*zero_extendsi<mode>2_dot2"
830 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
831 (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
832 (const_int 0)))
833 (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
834 (zero_extend:EXTSI (match_dup 1)))]
835 "rs6000_gen_cell_microcode"
836 "@
837 rldicl. %0,%1,0,32
838 #"
839 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
840 [(set (match_dup 0)
841 (zero_extend:EXTSI (match_dup 1)))
842 (set (match_dup 2)
843 (compare:CC (match_dup 0)
844 (const_int 0)))]
845 ""
846 [(set_attr "type" "shift")
847 (set_attr "dot" "yes")
848 (set_attr "length" "4,8")])
849
850
851 (define_insn "extendqi<mode>2"
852 [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r")
853 (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r")))]
854 ""
855 "extsb %0,%1"
856 [(set_attr "type" "exts")])
857
858 (define_insn_and_split "*extendqi<mode>2_dot"
859 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
860 (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
861 (const_int 0)))
862 (clobber (match_scratch:EXTQI 0 "=r,r"))]
863 "rs6000_gen_cell_microcode"
864 "@
865 extsb. %0,%1
866 #"
867 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
868 [(set (match_dup 0)
869 (sign_extend:EXTQI (match_dup 1)))
870 (set (match_dup 2)
871 (compare:CC (match_dup 0)
872 (const_int 0)))]
873 ""
874 [(set_attr "type" "exts")
875 (set_attr "dot" "yes")
876 (set_attr "length" "4,8")])
877
878 (define_insn_and_split "*extendqi<mode>2_dot2"
879 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
880 (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
881 (const_int 0)))
882 (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
883 (sign_extend:EXTQI (match_dup 1)))]
884 "rs6000_gen_cell_microcode"
885 "@
886 extsb. %0,%1
887 #"
888 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
889 [(set (match_dup 0)
890 (sign_extend:EXTQI (match_dup 1)))
891 (set (match_dup 2)
892 (compare:CC (match_dup 0)
893 (const_int 0)))]
894 ""
895 [(set_attr "type" "exts")
896 (set_attr "dot" "yes")
897 (set_attr "length" "4,8")])
898
899
900 (define_expand "extendhi<mode>2"
901 [(set (match_operand:EXTHI 0 "gpc_reg_operand" "")
902 (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "")))]
903 ""
904 "")
905
906 (define_insn "*extendhi<mode>2"
907 [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
908 (sign_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r")))]
909 "rs6000_gen_cell_microcode"
910 "@
911 lha%U1%X1 %0,%1
912 extsh %0,%1"
913 [(set_attr "type" "load,exts")
914 (set_attr "sign_extend" "yes")])
915
916 (define_insn "*extendhi<mode>2_noload"
917 [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r")
918 (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r")))]
919 "!rs6000_gen_cell_microcode"
920 "extsh %0,%1"
921 [(set_attr "type" "exts")])
922
923 (define_insn_and_split "*extendhi<mode>2_dot"
924 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
925 (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
926 (const_int 0)))
927 (clobber (match_scratch:EXTHI 0 "=r,r"))]
928 "rs6000_gen_cell_microcode"
929 "@
930 extsh. %0,%1
931 #"
932 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
933 [(set (match_dup 0)
934 (sign_extend:EXTHI (match_dup 1)))
935 (set (match_dup 2)
936 (compare:CC (match_dup 0)
937 (const_int 0)))]
938 ""
939 [(set_attr "type" "exts")
940 (set_attr "dot" "yes")
941 (set_attr "length" "4,8")])
942
943 (define_insn_and_split "*extendhi<mode>2_dot2"
944 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
945 (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
946 (const_int 0)))
947 (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
948 (sign_extend:EXTHI (match_dup 1)))]
949 "rs6000_gen_cell_microcode"
950 "@
951 extsh. %0,%1
952 #"
953 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
954 [(set (match_dup 0)
955 (sign_extend:EXTHI (match_dup 1)))
956 (set (match_dup 2)
957 (compare:CC (match_dup 0)
958 (const_int 0)))]
959 ""
960 [(set_attr "type" "exts")
961 (set_attr "dot" "yes")
962 (set_attr "length" "4,8")])
963
964
965 (define_insn "extendsi<mode>2"
966 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r,??wj,!wl,!wu")
967 (sign_extend:EXTSI (match_operand:SI 1 "lwa_operand" "Y,r,r,Z,Z")))]
968 ""
969 "@
970 lwa%U1%X1 %0,%1
971 extsw %0,%1
972 mtvsrwa %x0,%1
973 lfiwax %0,%y1
974 lxsiwax %x0,%y1"
975 [(set_attr "type" "load,exts,mffgpr,fpload,fpload")
976 (set_attr "sign_extend" "yes")])
977
978 (define_insn_and_split "*extendsi<mode>2_dot"
979 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
980 (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
981 (const_int 0)))
982 (clobber (match_scratch:EXTSI 0 "=r,r"))]
983 "rs6000_gen_cell_microcode"
984 "@
985 extsw. %0,%1
986 #"
987 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
988 [(set (match_dup 0)
989 (sign_extend:EXTSI (match_dup 1)))
990 (set (match_dup 2)
991 (compare:CC (match_dup 0)
992 (const_int 0)))]
993 ""
994 [(set_attr "type" "exts")
995 (set_attr "dot" "yes")
996 (set_attr "length" "4,8")])
997
998 (define_insn_and_split "*extendsi<mode>2_dot2"
999 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1000 (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
1001 (const_int 0)))
1002 (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
1003 (sign_extend:EXTSI (match_dup 1)))]
1004 "rs6000_gen_cell_microcode"
1005 "@
1006 extsw. %0,%1
1007 #"
1008 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1009 [(set (match_dup 0)
1010 (sign_extend:EXTSI (match_dup 1)))
1011 (set (match_dup 2)
1012 (compare:CC (match_dup 0)
1013 (const_int 0)))]
1014 ""
1015 [(set_attr "type" "exts")
1016 (set_attr "dot" "yes")
1017 (set_attr "length" "4,8")])
1018 \f
1019 ;; IBM 405, 440, 464 and 476 half-word multiplication operations.
1020
1021 (define_insn "*macchwc"
1022 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1023 (compare:CC (plus:SI (mult:SI (ashiftrt:SI
1024 (match_operand:SI 2 "gpc_reg_operand" "r")
1025 (const_int 16))
1026 (sign_extend:SI
1027 (match_operand:HI 1 "gpc_reg_operand" "r")))
1028 (match_operand:SI 4 "gpc_reg_operand" "0"))
1029 (const_int 0)))
1030 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1031 (plus:SI (mult:SI (ashiftrt:SI
1032 (match_dup 2)
1033 (const_int 16))
1034 (sign_extend:SI
1035 (match_dup 1)))
1036 (match_dup 4)))]
1037 "TARGET_MULHW"
1038 "macchw. %0,%1,%2"
1039 [(set_attr "type" "halfmul")])
1040
1041 (define_insn "*macchw"
1042 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1043 (plus:SI (mult:SI (ashiftrt:SI
1044 (match_operand:SI 2 "gpc_reg_operand" "r")
1045 (const_int 16))
1046 (sign_extend:SI
1047 (match_operand:HI 1 "gpc_reg_operand" "r")))
1048 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1049 "TARGET_MULHW"
1050 "macchw %0,%1,%2"
1051 [(set_attr "type" "halfmul")])
1052
1053 (define_insn "*macchwuc"
1054 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1055 (compare:CC (plus:SI (mult:SI (lshiftrt:SI
1056 (match_operand:SI 2 "gpc_reg_operand" "r")
1057 (const_int 16))
1058 (zero_extend:SI
1059 (match_operand:HI 1 "gpc_reg_operand" "r")))
1060 (match_operand:SI 4 "gpc_reg_operand" "0"))
1061 (const_int 0)))
1062 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1063 (plus:SI (mult:SI (lshiftrt:SI
1064 (match_dup 2)
1065 (const_int 16))
1066 (zero_extend:SI
1067 (match_dup 1)))
1068 (match_dup 4)))]
1069 "TARGET_MULHW"
1070 "macchwu. %0,%1,%2"
1071 [(set_attr "type" "halfmul")])
1072
1073 (define_insn "*macchwu"
1074 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1075 (plus:SI (mult:SI (lshiftrt:SI
1076 (match_operand:SI 2 "gpc_reg_operand" "r")
1077 (const_int 16))
1078 (zero_extend:SI
1079 (match_operand:HI 1 "gpc_reg_operand" "r")))
1080 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1081 "TARGET_MULHW"
1082 "macchwu %0,%1,%2"
1083 [(set_attr "type" "halfmul")])
1084
1085 (define_insn "*machhwc"
1086 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1087 (compare:CC (plus:SI (mult:SI (ashiftrt:SI
1088 (match_operand:SI 1 "gpc_reg_operand" "%r")
1089 (const_int 16))
1090 (ashiftrt:SI
1091 (match_operand:SI 2 "gpc_reg_operand" "r")
1092 (const_int 16)))
1093 (match_operand:SI 4 "gpc_reg_operand" "0"))
1094 (const_int 0)))
1095 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1096 (plus:SI (mult:SI (ashiftrt:SI
1097 (match_dup 1)
1098 (const_int 16))
1099 (ashiftrt:SI
1100 (match_dup 2)
1101 (const_int 16)))
1102 (match_dup 4)))]
1103 "TARGET_MULHW"
1104 "machhw. %0,%1,%2"
1105 [(set_attr "type" "halfmul")])
1106
1107 (define_insn "*machhw"
1108 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1109 (plus:SI (mult:SI (ashiftrt:SI
1110 (match_operand:SI 1 "gpc_reg_operand" "%r")
1111 (const_int 16))
1112 (ashiftrt:SI
1113 (match_operand:SI 2 "gpc_reg_operand" "r")
1114 (const_int 16)))
1115 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1116 "TARGET_MULHW"
1117 "machhw %0,%1,%2"
1118 [(set_attr "type" "halfmul")])
1119
1120 (define_insn "*machhwuc"
1121 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1122 (compare:CC (plus:SI (mult:SI (lshiftrt:SI
1123 (match_operand:SI 1 "gpc_reg_operand" "%r")
1124 (const_int 16))
1125 (lshiftrt:SI
1126 (match_operand:SI 2 "gpc_reg_operand" "r")
1127 (const_int 16)))
1128 (match_operand:SI 4 "gpc_reg_operand" "0"))
1129 (const_int 0)))
1130 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1131 (plus:SI (mult:SI (lshiftrt:SI
1132 (match_dup 1)
1133 (const_int 16))
1134 (lshiftrt:SI
1135 (match_dup 2)
1136 (const_int 16)))
1137 (match_dup 4)))]
1138 "TARGET_MULHW"
1139 "machhwu. %0,%1,%2"
1140 [(set_attr "type" "halfmul")])
1141
1142 (define_insn "*machhwu"
1143 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1144 (plus:SI (mult:SI (lshiftrt:SI
1145 (match_operand:SI 1 "gpc_reg_operand" "%r")
1146 (const_int 16))
1147 (lshiftrt:SI
1148 (match_operand:SI 2 "gpc_reg_operand" "r")
1149 (const_int 16)))
1150 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1151 "TARGET_MULHW"
1152 "machhwu %0,%1,%2"
1153 [(set_attr "type" "halfmul")])
1154
1155 (define_insn "*maclhwc"
1156 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1157 (compare:CC (plus:SI (mult:SI (sign_extend:SI
1158 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1159 (sign_extend:SI
1160 (match_operand:HI 2 "gpc_reg_operand" "r")))
1161 (match_operand:SI 4 "gpc_reg_operand" "0"))
1162 (const_int 0)))
1163 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1164 (plus:SI (mult:SI (sign_extend:SI
1165 (match_dup 1))
1166 (sign_extend:SI
1167 (match_dup 2)))
1168 (match_dup 4)))]
1169 "TARGET_MULHW"
1170 "maclhw. %0,%1,%2"
1171 [(set_attr "type" "halfmul")])
1172
1173 (define_insn "*maclhw"
1174 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1175 (plus:SI (mult:SI (sign_extend:SI
1176 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1177 (sign_extend:SI
1178 (match_operand:HI 2 "gpc_reg_operand" "r")))
1179 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1180 "TARGET_MULHW"
1181 "maclhw %0,%1,%2"
1182 [(set_attr "type" "halfmul")])
1183
1184 (define_insn "*maclhwuc"
1185 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1186 (compare:CC (plus:SI (mult:SI (zero_extend:SI
1187 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1188 (zero_extend:SI
1189 (match_operand:HI 2 "gpc_reg_operand" "r")))
1190 (match_operand:SI 4 "gpc_reg_operand" "0"))
1191 (const_int 0)))
1192 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1193 (plus:SI (mult:SI (zero_extend:SI
1194 (match_dup 1))
1195 (zero_extend:SI
1196 (match_dup 2)))
1197 (match_dup 4)))]
1198 "TARGET_MULHW"
1199 "maclhwu. %0,%1,%2"
1200 [(set_attr "type" "halfmul")])
1201
1202 (define_insn "*maclhwu"
1203 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1204 (plus:SI (mult:SI (zero_extend:SI
1205 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1206 (zero_extend:SI
1207 (match_operand:HI 2 "gpc_reg_operand" "r")))
1208 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1209 "TARGET_MULHW"
1210 "maclhwu %0,%1,%2"
1211 [(set_attr "type" "halfmul")])
1212
1213 (define_insn "*nmacchwc"
1214 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1215 (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1216 (mult:SI (ashiftrt:SI
1217 (match_operand:SI 2 "gpc_reg_operand" "r")
1218 (const_int 16))
1219 (sign_extend:SI
1220 (match_operand:HI 1 "gpc_reg_operand" "r"))))
1221 (const_int 0)))
1222 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1223 (minus:SI (match_dup 4)
1224 (mult:SI (ashiftrt:SI
1225 (match_dup 2)
1226 (const_int 16))
1227 (sign_extend:SI
1228 (match_dup 1)))))]
1229 "TARGET_MULHW"
1230 "nmacchw. %0,%1,%2"
1231 [(set_attr "type" "halfmul")])
1232
1233 (define_insn "*nmacchw"
1234 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1235 (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1236 (mult:SI (ashiftrt:SI
1237 (match_operand:SI 2 "gpc_reg_operand" "r")
1238 (const_int 16))
1239 (sign_extend:SI
1240 (match_operand:HI 1 "gpc_reg_operand" "r")))))]
1241 "TARGET_MULHW"
1242 "nmacchw %0,%1,%2"
1243 [(set_attr "type" "halfmul")])
1244
1245 (define_insn "*nmachhwc"
1246 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1247 (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1248 (mult:SI (ashiftrt:SI
1249 (match_operand:SI 1 "gpc_reg_operand" "%r")
1250 (const_int 16))
1251 (ashiftrt:SI
1252 (match_operand:SI 2 "gpc_reg_operand" "r")
1253 (const_int 16))))
1254 (const_int 0)))
1255 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1256 (minus:SI (match_dup 4)
1257 (mult:SI (ashiftrt:SI
1258 (match_dup 1)
1259 (const_int 16))
1260 (ashiftrt:SI
1261 (match_dup 2)
1262 (const_int 16)))))]
1263 "TARGET_MULHW"
1264 "nmachhw. %0,%1,%2"
1265 [(set_attr "type" "halfmul")])
1266
1267 (define_insn "*nmachhw"
1268 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1269 (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1270 (mult:SI (ashiftrt:SI
1271 (match_operand:SI 1 "gpc_reg_operand" "%r")
1272 (const_int 16))
1273 (ashiftrt:SI
1274 (match_operand:SI 2 "gpc_reg_operand" "r")
1275 (const_int 16)))))]
1276 "TARGET_MULHW"
1277 "nmachhw %0,%1,%2"
1278 [(set_attr "type" "halfmul")])
1279
1280 (define_insn "*nmaclhwc"
1281 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1282 (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1283 (mult:SI (sign_extend:SI
1284 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1285 (sign_extend:SI
1286 (match_operand:HI 2 "gpc_reg_operand" "r"))))
1287 (const_int 0)))
1288 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1289 (minus:SI (match_dup 4)
1290 (mult:SI (sign_extend:SI
1291 (match_dup 1))
1292 (sign_extend:SI
1293 (match_dup 2)))))]
1294 "TARGET_MULHW"
1295 "nmaclhw. %0,%1,%2"
1296 [(set_attr "type" "halfmul")])
1297
1298 (define_insn "*nmaclhw"
1299 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1300 (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1301 (mult:SI (sign_extend:SI
1302 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1303 (sign_extend:SI
1304 (match_operand:HI 2 "gpc_reg_operand" "r")))))]
1305 "TARGET_MULHW"
1306 "nmaclhw %0,%1,%2"
1307 [(set_attr "type" "halfmul")])
1308
1309 (define_insn "*mulchwc"
1310 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1311 (compare:CC (mult:SI (ashiftrt:SI
1312 (match_operand:SI 2 "gpc_reg_operand" "r")
1313 (const_int 16))
1314 (sign_extend:SI
1315 (match_operand:HI 1 "gpc_reg_operand" "r")))
1316 (const_int 0)))
1317 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1318 (mult:SI (ashiftrt:SI
1319 (match_dup 2)
1320 (const_int 16))
1321 (sign_extend:SI
1322 (match_dup 1))))]
1323 "TARGET_MULHW"
1324 "mulchw. %0,%1,%2"
1325 [(set_attr "type" "halfmul")])
1326
1327 (define_insn "*mulchw"
1328 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1329 (mult:SI (ashiftrt:SI
1330 (match_operand:SI 2 "gpc_reg_operand" "r")
1331 (const_int 16))
1332 (sign_extend:SI
1333 (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1334 "TARGET_MULHW"
1335 "mulchw %0,%1,%2"
1336 [(set_attr "type" "halfmul")])
1337
1338 (define_insn "*mulchwuc"
1339 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1340 (compare:CC (mult:SI (lshiftrt:SI
1341 (match_operand:SI 2 "gpc_reg_operand" "r")
1342 (const_int 16))
1343 (zero_extend:SI
1344 (match_operand:HI 1 "gpc_reg_operand" "r")))
1345 (const_int 0)))
1346 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1347 (mult:SI (lshiftrt:SI
1348 (match_dup 2)
1349 (const_int 16))
1350 (zero_extend:SI
1351 (match_dup 1))))]
1352 "TARGET_MULHW"
1353 "mulchwu. %0,%1,%2"
1354 [(set_attr "type" "halfmul")])
1355
1356 (define_insn "*mulchwu"
1357 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1358 (mult:SI (lshiftrt:SI
1359 (match_operand:SI 2 "gpc_reg_operand" "r")
1360 (const_int 16))
1361 (zero_extend:SI
1362 (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1363 "TARGET_MULHW"
1364 "mulchwu %0,%1,%2"
1365 [(set_attr "type" "halfmul")])
1366
1367 (define_insn "*mulhhwc"
1368 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1369 (compare:CC (mult:SI (ashiftrt:SI
1370 (match_operand:SI 1 "gpc_reg_operand" "%r")
1371 (const_int 16))
1372 (ashiftrt:SI
1373 (match_operand:SI 2 "gpc_reg_operand" "r")
1374 (const_int 16)))
1375 (const_int 0)))
1376 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1377 (mult:SI (ashiftrt:SI
1378 (match_dup 1)
1379 (const_int 16))
1380 (ashiftrt:SI
1381 (match_dup 2)
1382 (const_int 16))))]
1383 "TARGET_MULHW"
1384 "mulhhw. %0,%1,%2"
1385 [(set_attr "type" "halfmul")])
1386
1387 (define_insn "*mulhhw"
1388 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1389 (mult:SI (ashiftrt:SI
1390 (match_operand:SI 1 "gpc_reg_operand" "%r")
1391 (const_int 16))
1392 (ashiftrt:SI
1393 (match_operand:SI 2 "gpc_reg_operand" "r")
1394 (const_int 16))))]
1395 "TARGET_MULHW"
1396 "mulhhw %0,%1,%2"
1397 [(set_attr "type" "halfmul")])
1398
1399 (define_insn "*mulhhwuc"
1400 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1401 (compare:CC (mult:SI (lshiftrt:SI
1402 (match_operand:SI 1 "gpc_reg_operand" "%r")
1403 (const_int 16))
1404 (lshiftrt:SI
1405 (match_operand:SI 2 "gpc_reg_operand" "r")
1406 (const_int 16)))
1407 (const_int 0)))
1408 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1409 (mult:SI (lshiftrt:SI
1410 (match_dup 1)
1411 (const_int 16))
1412 (lshiftrt:SI
1413 (match_dup 2)
1414 (const_int 16))))]
1415 "TARGET_MULHW"
1416 "mulhhwu. %0,%1,%2"
1417 [(set_attr "type" "halfmul")])
1418
1419 (define_insn "*mulhhwu"
1420 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1421 (mult:SI (lshiftrt:SI
1422 (match_operand:SI 1 "gpc_reg_operand" "%r")
1423 (const_int 16))
1424 (lshiftrt:SI
1425 (match_operand:SI 2 "gpc_reg_operand" "r")
1426 (const_int 16))))]
1427 "TARGET_MULHW"
1428 "mulhhwu %0,%1,%2"
1429 [(set_attr "type" "halfmul")])
1430
1431 (define_insn "*mullhwc"
1432 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1433 (compare:CC (mult:SI (sign_extend:SI
1434 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1435 (sign_extend:SI
1436 (match_operand:HI 2 "gpc_reg_operand" "r")))
1437 (const_int 0)))
1438 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1439 (mult:SI (sign_extend:SI
1440 (match_dup 1))
1441 (sign_extend:SI
1442 (match_dup 2))))]
1443 "TARGET_MULHW"
1444 "mullhw. %0,%1,%2"
1445 [(set_attr "type" "halfmul")])
1446
1447 (define_insn "*mullhw"
1448 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1449 (mult:SI (sign_extend:SI
1450 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1451 (sign_extend:SI
1452 (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1453 "TARGET_MULHW"
1454 "mullhw %0,%1,%2"
1455 [(set_attr "type" "halfmul")])
1456
1457 (define_insn "*mullhwuc"
1458 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1459 (compare:CC (mult:SI (zero_extend:SI
1460 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1461 (zero_extend:SI
1462 (match_operand:HI 2 "gpc_reg_operand" "r")))
1463 (const_int 0)))
1464 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1465 (mult:SI (zero_extend:SI
1466 (match_dup 1))
1467 (zero_extend:SI
1468 (match_dup 2))))]
1469 "TARGET_MULHW"
1470 "mullhwu. %0,%1,%2"
1471 [(set_attr "type" "halfmul")])
1472
1473 (define_insn "*mullhwu"
1474 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1475 (mult:SI (zero_extend:SI
1476 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1477 (zero_extend:SI
1478 (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1479 "TARGET_MULHW"
1480 "mullhwu %0,%1,%2"
1481 [(set_attr "type" "halfmul")])
1482 \f
1483 ;; IBM 405, 440, 464 and 476 string-search dlmzb instruction support.
1484 (define_insn "dlmzb"
1485 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1486 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
1487 (match_operand:SI 2 "gpc_reg_operand" "r")]
1488 UNSPEC_DLMZB_CR))
1489 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1490 (unspec:SI [(match_dup 1)
1491 (match_dup 2)]
1492 UNSPEC_DLMZB))]
1493 "TARGET_DLMZB"
1494 "dlmzb. %0,%1,%2")
1495
1496 (define_expand "strlensi"
1497 [(set (match_operand:SI 0 "gpc_reg_operand" "")
1498 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
1499 (match_operand:QI 2 "const_int_operand" "")
1500 (match_operand 3 "const_int_operand" "")]
1501 UNSPEC_DLMZB_STRLEN))
1502 (clobber (match_scratch:CC 4 "=x"))]
1503 "TARGET_DLMZB && WORDS_BIG_ENDIAN && !optimize_size"
1504 {
1505 rtx result = operands[0];
1506 rtx src = operands[1];
1507 rtx search_char = operands[2];
1508 rtx align = operands[3];
1509 rtx addr, scratch_string, word1, word2, scratch_dlmzb;
1510 rtx loop_label, end_label, mem, cr0, cond;
1511 if (search_char != const0_rtx
1512 || GET_CODE (align) != CONST_INT
1513 || INTVAL (align) < 8)
1514 FAIL;
1515 word1 = gen_reg_rtx (SImode);
1516 word2 = gen_reg_rtx (SImode);
1517 scratch_dlmzb = gen_reg_rtx (SImode);
1518 scratch_string = gen_reg_rtx (Pmode);
1519 loop_label = gen_label_rtx ();
1520 end_label = gen_label_rtx ();
1521 addr = force_reg (Pmode, XEXP (src, 0));
1522 emit_move_insn (scratch_string, addr);
1523 emit_label (loop_label);
1524 mem = change_address (src, SImode, scratch_string);
1525 emit_move_insn (word1, mem);
1526 emit_move_insn (word2, adjust_address (mem, SImode, 4));
1527 cr0 = gen_rtx_REG (CCmode, CR0_REGNO);
1528 emit_insn (gen_dlmzb (scratch_dlmzb, word1, word2, cr0));
1529 cond = gen_rtx_NE (VOIDmode, cr0, const0_rtx);
1530 emit_jump_insn (gen_rtx_SET (pc_rtx,
1531 gen_rtx_IF_THEN_ELSE (VOIDmode,
1532 cond,
1533 gen_rtx_LABEL_REF
1534 (VOIDmode,
1535 end_label),
1536 pc_rtx)));
1537 emit_insn (gen_addsi3 (scratch_string, scratch_string, GEN_INT (8)));
1538 emit_jump_insn (gen_rtx_SET (pc_rtx,
1539 gen_rtx_LABEL_REF (VOIDmode, loop_label)));
1540 emit_barrier ();
1541 emit_label (end_label);
1542 emit_insn (gen_addsi3 (scratch_string, scratch_string, scratch_dlmzb));
1543 emit_insn (gen_subsi3 (result, scratch_string, addr));
1544 emit_insn (gen_addsi3 (result, result, constm1_rtx));
1545 DONE;
1546 })
1547 \f
1548 ;; Fixed-point arithmetic insns.
1549
1550 (define_expand "add<mode>3"
1551 [(set (match_operand:SDI 0 "gpc_reg_operand" "")
1552 (plus:SDI (match_operand:SDI 1 "gpc_reg_operand" "")
1553 (match_operand:SDI 2 "reg_or_add_cint_operand" "")))]
1554 ""
1555 {
1556 if (<MODE>mode == DImode && !TARGET_POWERPC64)
1557 {
1558 rtx lo0 = gen_lowpart (SImode, operands[0]);
1559 rtx lo1 = gen_lowpart (SImode, operands[1]);
1560 rtx lo2 = gen_lowpart (SImode, operands[2]);
1561 rtx hi0 = gen_highpart (SImode, operands[0]);
1562 rtx hi1 = gen_highpart (SImode, operands[1]);
1563 rtx hi2 = gen_highpart_mode (SImode, DImode, operands[2]);
1564
1565 if (!reg_or_short_operand (lo2, SImode))
1566 lo2 = force_reg (SImode, lo2);
1567 if (!adde_operand (hi2, SImode))
1568 hi2 = force_reg (SImode, hi2);
1569
1570 emit_insn (gen_addsi3_carry (lo0, lo1, lo2));
1571 emit_insn (gen_addsi3_carry_in (hi0, hi1, hi2));
1572 DONE;
1573 }
1574
1575 if (CONST_INT_P (operands[2]) && !add_operand (operands[2], <MODE>mode))
1576 {
1577 rtx tmp = ((!can_create_pseudo_p ()
1578 || rtx_equal_p (operands[0], operands[1]))
1579 ? operands[0] : gen_reg_rtx (<MODE>mode));
1580
1581 HOST_WIDE_INT val = INTVAL (operands[2]);
1582 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1583 HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1584
1585 if (<MODE>mode == DImode && !satisfies_constraint_L (GEN_INT (rest)))
1586 FAIL;
1587
1588 /* The ordering here is important for the prolog expander.
1589 When space is allocated from the stack, adding 'low' first may
1590 produce a temporary deallocation (which would be bad). */
1591 emit_insn (gen_add<mode>3 (tmp, operands[1], GEN_INT (rest)));
1592 emit_insn (gen_add<mode>3 (operands[0], tmp, GEN_INT (low)));
1593 DONE;
1594 }
1595 })
1596
1597 (define_insn "*add<mode>3"
1598 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r,r")
1599 (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b,b")
1600 (match_operand:GPR 2 "add_operand" "r,I,L")))]
1601 ""
1602 "@
1603 add %0,%1,%2
1604 addi %0,%1,%2
1605 addis %0,%1,%v2"
1606 [(set_attr "type" "add")])
1607
1608 (define_insn "addsi3_high"
1609 [(set (match_operand:SI 0 "gpc_reg_operand" "=b")
1610 (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
1611 (high:SI (match_operand 2 "" ""))))]
1612 "TARGET_MACHO && !TARGET_64BIT"
1613 "addis %0,%1,ha16(%2)"
1614 [(set_attr "type" "add")])
1615
1616 (define_insn_and_split "*add<mode>3_dot"
1617 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1618 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
1619 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
1620 (const_int 0)))
1621 (clobber (match_scratch:GPR 0 "=r,r"))]
1622 "<MODE>mode == Pmode"
1623 "@
1624 add. %0,%1,%2
1625 #"
1626 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1627 [(set (match_dup 0)
1628 (plus:GPR (match_dup 1)
1629 (match_dup 2)))
1630 (set (match_dup 3)
1631 (compare:CC (match_dup 0)
1632 (const_int 0)))]
1633 ""
1634 [(set_attr "type" "add")
1635 (set_attr "dot" "yes")
1636 (set_attr "length" "4,8")])
1637
1638 (define_insn_and_split "*add<mode>3_dot2"
1639 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1640 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
1641 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
1642 (const_int 0)))
1643 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1644 (plus:GPR (match_dup 1)
1645 (match_dup 2)))]
1646 "<MODE>mode == Pmode"
1647 "@
1648 add. %0,%1,%2
1649 #"
1650 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1651 [(set (match_dup 0)
1652 (plus:GPR (match_dup 1)
1653 (match_dup 2)))
1654 (set (match_dup 3)
1655 (compare:CC (match_dup 0)
1656 (const_int 0)))]
1657 ""
1658 [(set_attr "type" "add")
1659 (set_attr "dot" "yes")
1660 (set_attr "length" "4,8")])
1661
1662 (define_insn_and_split "*add<mode>3_imm_dot"
1663 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1664 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b")
1665 (match_operand:GPR 2 "short_cint_operand" "I,I"))
1666 (const_int 0)))
1667 (clobber (match_scratch:GPR 0 "=r,r"))
1668 (clobber (reg:GPR CA_REGNO))]
1669 "<MODE>mode == Pmode"
1670 "@
1671 addic. %0,%1,%2
1672 #"
1673 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1674 [(set (match_dup 0)
1675 (plus:GPR (match_dup 1)
1676 (match_dup 2)))
1677 (set (match_dup 3)
1678 (compare:CC (match_dup 0)
1679 (const_int 0)))]
1680 ""
1681 [(set_attr "type" "add")
1682 (set_attr "dot" "yes")
1683 (set_attr "length" "4,8")])
1684
1685 (define_insn_and_split "*add<mode>3_imm_dot2"
1686 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1687 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b")
1688 (match_operand:GPR 2 "short_cint_operand" "I,I"))
1689 (const_int 0)))
1690 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1691 (plus:GPR (match_dup 1)
1692 (match_dup 2)))
1693 (clobber (reg:GPR CA_REGNO))]
1694 "<MODE>mode == Pmode"
1695 "@
1696 addic. %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 ;; Split an add that we can't do in one insn into two insns, each of which
1711 ;; does one 16-bit part. This is used by combine. Note that the low-order
1712 ;; add should be last in case the result gets used in an address.
1713
1714 (define_split
1715 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
1716 (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
1717 (match_operand:GPR 2 "non_add_cint_operand" "")))]
1718 ""
1719 [(set (match_dup 0) (plus:GPR (match_dup 1) (match_dup 3)))
1720 (set (match_dup 0) (plus:GPR (match_dup 0) (match_dup 4)))]
1721 {
1722 HOST_WIDE_INT val = INTVAL (operands[2]);
1723 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1724 HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1725
1726 operands[4] = GEN_INT (low);
1727 if (<MODE>mode == SImode || satisfies_constraint_L (GEN_INT (rest)))
1728 operands[3] = GEN_INT (rest);
1729 else if (can_create_pseudo_p ())
1730 {
1731 operands[3] = gen_reg_rtx (DImode);
1732 emit_move_insn (operands[3], operands[2]);
1733 emit_insn (gen_adddi3 (operands[0], operands[1], operands[3]));
1734 DONE;
1735 }
1736 else
1737 FAIL;
1738 })
1739
1740
1741 (define_insn "add<mode>3_carry"
1742 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1743 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1744 (match_operand:P 2 "reg_or_short_operand" "rI")))
1745 (set (reg:P CA_REGNO)
1746 (ltu:P (plus:P (match_dup 1)
1747 (match_dup 2))
1748 (match_dup 1)))]
1749 ""
1750 "add%I2c %0,%1,%2"
1751 [(set_attr "type" "add")])
1752
1753 (define_insn "*add<mode>3_imm_carry_pos"
1754 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1755 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1756 (match_operand:P 2 "short_cint_operand" "n")))
1757 (set (reg:P CA_REGNO)
1758 (geu:P (match_dup 1)
1759 (match_operand:P 3 "const_int_operand" "n")))]
1760 "INTVAL (operands[2]) > 0
1761 && INTVAL (operands[2]) + INTVAL (operands[3]) == 0"
1762 "addic %0,%1,%2"
1763 [(set_attr "type" "add")])
1764
1765 (define_insn "*add<mode>3_imm_carry_0"
1766 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1767 (match_operand:P 1 "gpc_reg_operand" "r"))
1768 (set (reg:P CA_REGNO)
1769 (const_int 0))]
1770 ""
1771 "addic %0,%1,0"
1772 [(set_attr "type" "add")])
1773
1774 (define_insn "*add<mode>3_imm_carry_m1"
1775 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1776 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1777 (const_int -1)))
1778 (set (reg:P CA_REGNO)
1779 (ne:P (match_dup 1)
1780 (const_int 0)))]
1781 ""
1782 "addic %0,%1,-1"
1783 [(set_attr "type" "add")])
1784
1785 (define_insn "*add<mode>3_imm_carry_neg"
1786 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1787 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1788 (match_operand:P 2 "short_cint_operand" "n")))
1789 (set (reg:P CA_REGNO)
1790 (gtu:P (match_dup 1)
1791 (match_operand:P 3 "const_int_operand" "n")))]
1792 "INTVAL (operands[2]) < 0
1793 && INTVAL (operands[2]) + INTVAL (operands[3]) == -1"
1794 "addic %0,%1,%2"
1795 [(set_attr "type" "add")])
1796
1797
1798 (define_expand "add<mode>3_carry_in"
1799 [(parallel [
1800 (set (match_operand:GPR 0 "gpc_reg_operand")
1801 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand")
1802 (match_operand:GPR 2 "adde_operand"))
1803 (reg:GPR CA_REGNO)))
1804 (clobber (reg:GPR CA_REGNO))])]
1805 ""
1806 {
1807 if (operands[2] == const0_rtx)
1808 {
1809 emit_insn (gen_add<mode>3_carry_in_0 (operands[0], operands[1]));
1810 DONE;
1811 }
1812 if (operands[2] == constm1_rtx)
1813 {
1814 emit_insn (gen_add<mode>3_carry_in_m1 (operands[0], operands[1]));
1815 DONE;
1816 }
1817 })
1818
1819 (define_insn "*add<mode>3_carry_in_internal"
1820 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1821 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1822 (match_operand:GPR 2 "gpc_reg_operand" "r"))
1823 (reg:GPR CA_REGNO)))
1824 (clobber (reg:GPR CA_REGNO))]
1825 ""
1826 "adde %0,%1,%2"
1827 [(set_attr "type" "add")])
1828
1829 (define_insn "add<mode>3_carry_in_0"
1830 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1831 (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1832 (reg:GPR CA_REGNO)))
1833 (clobber (reg:GPR CA_REGNO))]
1834 ""
1835 "addze %0,%1"
1836 [(set_attr "type" "add")])
1837
1838 (define_insn "add<mode>3_carry_in_m1"
1839 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1840 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1841 (reg:GPR CA_REGNO))
1842 (const_int -1)))
1843 (clobber (reg:GPR CA_REGNO))]
1844 ""
1845 "addme %0,%1"
1846 [(set_attr "type" "add")])
1847
1848
1849 (define_expand "one_cmpl<mode>2"
1850 [(set (match_operand:SDI 0 "gpc_reg_operand" "")
1851 (not:SDI (match_operand:SDI 1 "gpc_reg_operand" "")))]
1852 ""
1853 {
1854 if (<MODE>mode == DImode && !TARGET_POWERPC64)
1855 {
1856 rs6000_split_logical (operands, NOT, false, false, false);
1857 DONE;
1858 }
1859 })
1860
1861 (define_insn "*one_cmpl<mode>2"
1862 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1863 (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
1864 ""
1865 "not %0,%1")
1866
1867 (define_insn_and_split "*one_cmpl<mode>2_dot"
1868 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1869 (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
1870 (const_int 0)))
1871 (clobber (match_scratch:GPR 0 "=r,r"))]
1872 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
1873 "@
1874 not. %0,%1
1875 #"
1876 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1877 [(set (match_dup 0)
1878 (not:GPR (match_dup 1)))
1879 (set (match_dup 2)
1880 (compare:CC (match_dup 0)
1881 (const_int 0)))]
1882 ""
1883 [(set_attr "type" "logical")
1884 (set_attr "dot" "yes")
1885 (set_attr "length" "4,8")])
1886
1887 (define_insn_and_split "*one_cmpl<mode>2_dot2"
1888 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1889 (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
1890 (const_int 0)))
1891 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1892 (not:GPR (match_dup 1)))]
1893 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
1894 "@
1895 not. %0,%1
1896 #"
1897 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1898 [(set (match_dup 0)
1899 (not:GPR (match_dup 1)))
1900 (set (match_dup 2)
1901 (compare:CC (match_dup 0)
1902 (const_int 0)))]
1903 ""
1904 [(set_attr "type" "logical")
1905 (set_attr "dot" "yes")
1906 (set_attr "length" "4,8")])
1907
1908
1909 (define_expand "sub<mode>3"
1910 [(set (match_operand:SDI 0 "gpc_reg_operand" "")
1911 (minus:SDI (match_operand:SDI 1 "reg_or_short_operand" "")
1912 (match_operand:SDI 2 "gpc_reg_operand" "")))]
1913 ""
1914 {
1915 if (<MODE>mode == DImode && !TARGET_POWERPC64)
1916 {
1917 rtx lo0 = gen_lowpart (SImode, operands[0]);
1918 rtx lo1 = gen_lowpart (SImode, operands[1]);
1919 rtx lo2 = gen_lowpart (SImode, operands[2]);
1920 rtx hi0 = gen_highpart (SImode, operands[0]);
1921 rtx hi1 = gen_highpart_mode (SImode, DImode, operands[1]);
1922 rtx hi2 = gen_highpart (SImode, operands[2]);
1923
1924 if (!reg_or_short_operand (lo1, SImode))
1925 lo1 = force_reg (SImode, lo1);
1926 if (!adde_operand (hi1, SImode))
1927 hi1 = force_reg (SImode, hi1);
1928
1929 emit_insn (gen_subfsi3_carry (lo0, lo2, lo1));
1930 emit_insn (gen_subfsi3_carry_in (hi0, hi2, hi1));
1931 DONE;
1932 }
1933
1934 if (short_cint_operand (operands[1], <MODE>mode))
1935 {
1936 emit_insn (gen_subf<mode>3_imm (operands[0], operands[2], operands[1]));
1937 DONE;
1938 }
1939 })
1940
1941 (define_insn "*subf<mode>3"
1942 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1943 (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r")
1944 (match_operand:GPR 1 "gpc_reg_operand" "r")))]
1945 ""
1946 "subf %0,%1,%2"
1947 [(set_attr "type" "add")])
1948
1949 (define_insn_and_split "*subf<mode>3_dot"
1950 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1951 (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
1952 (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
1953 (const_int 0)))
1954 (clobber (match_scratch:GPR 0 "=r,r"))]
1955 "<MODE>mode == Pmode"
1956 "@
1957 subf. %0,%1,%2
1958 #"
1959 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1960 [(set (match_dup 0)
1961 (minus:GPR (match_dup 2)
1962 (match_dup 1)))
1963 (set (match_dup 3)
1964 (compare:CC (match_dup 0)
1965 (const_int 0)))]
1966 ""
1967 [(set_attr "type" "add")
1968 (set_attr "dot" "yes")
1969 (set_attr "length" "4,8")])
1970
1971 (define_insn_and_split "*subf<mode>3_dot2"
1972 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1973 (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
1974 (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
1975 (const_int 0)))
1976 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1977 (minus:GPR (match_dup 2)
1978 (match_dup 1)))]
1979 "<MODE>mode == Pmode"
1980 "@
1981 subf. %0,%1,%2
1982 #"
1983 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1984 [(set (match_dup 0)
1985 (minus:GPR (match_dup 2)
1986 (match_dup 1)))
1987 (set (match_dup 3)
1988 (compare:CC (match_dup 0)
1989 (const_int 0)))]
1990 ""
1991 [(set_attr "type" "add")
1992 (set_attr "dot" "yes")
1993 (set_attr "length" "4,8")])
1994
1995 (define_insn "subf<mode>3_imm"
1996 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1997 (minus:GPR (match_operand:GPR 2 "short_cint_operand" "I")
1998 (match_operand:GPR 1 "gpc_reg_operand" "r")))
1999 (clobber (reg:GPR CA_REGNO))]
2000 ""
2001 "subfic %0,%1,%2"
2002 [(set_attr "type" "add")])
2003
2004
2005 (define_insn "subf<mode>3_carry"
2006 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2007 (minus:P (match_operand:P 2 "reg_or_short_operand" "rI")
2008 (match_operand:P 1 "gpc_reg_operand" "r")))
2009 (set (reg:P CA_REGNO)
2010 (leu:P (match_dup 1)
2011 (match_dup 2)))]
2012 ""
2013 "subf%I2c %0,%1,%2"
2014 [(set_attr "type" "add")])
2015
2016 (define_insn "*subf<mode>3_imm_carry_0"
2017 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2018 (neg:P (match_operand:P 1 "gpc_reg_operand" "r")))
2019 (set (reg:P CA_REGNO)
2020 (eq:P (match_dup 1)
2021 (const_int 0)))]
2022 ""
2023 "subfic %0,%1,0"
2024 [(set_attr "type" "add")])
2025
2026 (define_insn "*subf<mode>3_imm_carry_m1"
2027 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2028 (not:P (match_operand:P 1 "gpc_reg_operand" "r")))
2029 (set (reg:P CA_REGNO)
2030 (const_int 1))]
2031 ""
2032 "subfic %0,%1,-1"
2033 [(set_attr "type" "add")])
2034
2035
2036 (define_expand "subf<mode>3_carry_in"
2037 [(parallel [
2038 (set (match_operand:GPR 0 "gpc_reg_operand")
2039 (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand"))
2040 (reg:GPR CA_REGNO))
2041 (match_operand:GPR 2 "adde_operand")))
2042 (clobber (reg:GPR CA_REGNO))])]
2043 ""
2044 {
2045 if (operands[2] == const0_rtx)
2046 {
2047 emit_insn (gen_subf<mode>3_carry_in_0 (operands[0], operands[1]));
2048 DONE;
2049 }
2050 if (operands[2] == constm1_rtx)
2051 {
2052 emit_insn (gen_subf<mode>3_carry_in_m1 (operands[0], operands[1]));
2053 DONE;
2054 }
2055 })
2056
2057 (define_insn "*subf<mode>3_carry_in_internal"
2058 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2059 (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
2060 (reg:GPR CA_REGNO))
2061 (match_operand:GPR 2 "gpc_reg_operand" "r")))
2062 (clobber (reg:GPR CA_REGNO))]
2063 ""
2064 "subfe %0,%1,%2"
2065 [(set_attr "type" "add")])
2066
2067 (define_insn "subf<mode>3_carry_in_0"
2068 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2069 (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
2070 (reg:GPR CA_REGNO)))
2071 (clobber (reg:GPR CA_REGNO))]
2072 ""
2073 "subfze %0,%1"
2074 [(set_attr "type" "add")])
2075
2076 (define_insn "subf<mode>3_carry_in_m1"
2077 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2078 (plus:GPR (minus:GPR (reg:GPR CA_REGNO)
2079 (match_operand:GPR 1 "gpc_reg_operand" "r"))
2080 (const_int -2)))
2081 (clobber (reg:GPR CA_REGNO))]
2082 ""
2083 "subfme %0,%1"
2084 [(set_attr "type" "add")])
2085
2086 (define_insn "subf<mode>3_carry_in_xx"
2087 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2088 (plus:GPR (reg:GPR CA_REGNO)
2089 (const_int -1)))
2090 (clobber (reg:GPR CA_REGNO))]
2091 ""
2092 "subfe %0,%0,%0"
2093 [(set_attr "type" "add")])
2094
2095
2096 (define_insn "neg<mode>2"
2097 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2098 (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2099 ""
2100 "neg %0,%1"
2101 [(set_attr "type" "add")])
2102
2103 (define_insn_and_split "*neg<mode>2_dot"
2104 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2105 (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2106 (const_int 0)))
2107 (clobber (match_scratch:GPR 0 "=r,r"))]
2108 "<MODE>mode == Pmode"
2109 "@
2110 neg. %0,%1
2111 #"
2112 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2113 [(set (match_dup 0)
2114 (neg:GPR (match_dup 1)))
2115 (set (match_dup 2)
2116 (compare:CC (match_dup 0)
2117 (const_int 0)))]
2118 ""
2119 [(set_attr "type" "add")
2120 (set_attr "dot" "yes")
2121 (set_attr "length" "4,8")])
2122
2123 (define_insn_and_split "*neg<mode>2_dot2"
2124 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2125 (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2126 (const_int 0)))
2127 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2128 (neg:GPR (match_dup 1)))]
2129 "<MODE>mode == Pmode"
2130 "@
2131 neg. %0,%1
2132 #"
2133 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2134 [(set (match_dup 0)
2135 (neg:GPR (match_dup 1)))
2136 (set (match_dup 2)
2137 (compare:CC (match_dup 0)
2138 (const_int 0)))]
2139 ""
2140 [(set_attr "type" "add")
2141 (set_attr "dot" "yes")
2142 (set_attr "length" "4,8")])
2143
2144
2145 (define_insn "clz<mode>2"
2146 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2147 (clz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2148 ""
2149 "cntlz<wd> %0,%1"
2150 [(set_attr "type" "cntlz")])
2151
2152 (define_expand "ctz<mode>2"
2153 [(set (match_dup 2)
2154 (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))
2155 (set (match_dup 3)
2156 (and:GPR (match_dup 1)
2157 (match_dup 2)))
2158 (set (match_dup 4)
2159 (clz:GPR (match_dup 3)))
2160 (parallel [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2161 (minus:GPR (match_dup 5)
2162 (match_dup 4)))
2163 (clobber (reg:GPR CA_REGNO))])]
2164 ""
2165 {
2166 if (TARGET_CTZ)
2167 {
2168 emit_insn (gen_ctz<mode>2_hw (operands[0], operands[1]));
2169 DONE;
2170 }
2171
2172 operands[2] = gen_reg_rtx (<MODE>mode);
2173 operands[3] = gen_reg_rtx (<MODE>mode);
2174 operands[4] = gen_reg_rtx (<MODE>mode);
2175 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - 1);
2176 })
2177
2178 (define_insn "ctz<mode>2_hw"
2179 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2180 (ctz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2181 "TARGET_CTZ"
2182 "cnttz<wd> %0,%1"
2183 [(set_attr "type" "cntlz")])
2184
2185 (define_expand "ffs<mode>2"
2186 [(set (match_dup 2)
2187 (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))
2188 (set (match_dup 3)
2189 (and:GPR (match_dup 1)
2190 (match_dup 2)))
2191 (set (match_dup 4)
2192 (clz:GPR (match_dup 3)))
2193 (parallel [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2194 (minus:GPR (match_dup 5)
2195 (match_dup 4)))
2196 (clobber (reg:GPR CA_REGNO))])]
2197 ""
2198 {
2199 operands[2] = gen_reg_rtx (<MODE>mode);
2200 operands[3] = gen_reg_rtx (<MODE>mode);
2201 operands[4] = gen_reg_rtx (<MODE>mode);
2202 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
2203 })
2204
2205
2206 (define_expand "popcount<mode>2"
2207 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2208 (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))]
2209 "TARGET_POPCNTB || TARGET_POPCNTD"
2210 {
2211 rs6000_emit_popcount (operands[0], operands[1]);
2212 DONE;
2213 })
2214
2215 (define_insn "popcntb<mode>2"
2216 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2217 (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")]
2218 UNSPEC_POPCNTB))]
2219 "TARGET_POPCNTB"
2220 "popcntb %0,%1"
2221 [(set_attr "type" "popcnt")])
2222
2223 (define_insn "popcntd<mode>2"
2224 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2225 (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2226 "TARGET_POPCNTD"
2227 "popcnt<wd> %0,%1"
2228 [(set_attr "type" "popcnt")])
2229
2230
2231 (define_expand "parity<mode>2"
2232 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2233 (parity:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))]
2234 "TARGET_POPCNTB"
2235 {
2236 rs6000_emit_parity (operands[0], operands[1]);
2237 DONE;
2238 })
2239
2240 (define_insn "parity<mode>2_cmpb"
2241 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2242 (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")] UNSPEC_PARITY))]
2243 "TARGET_CMPB && TARGET_POPCNTB"
2244 "prty<wd> %0,%1"
2245 [(set_attr "type" "popcnt")])
2246
2247
2248 ;; Since the hardware zeros the upper part of the register, save generating the
2249 ;; AND immediate if we are converting to unsigned
2250 (define_insn "*bswaphi2_extenddi"
2251 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2252 (zero_extend:DI
2253 (bswap:HI (match_operand:HI 1 "memory_operand" "Z"))))]
2254 "TARGET_POWERPC64"
2255 "lhbrx %0,%y1"
2256 [(set_attr "length" "4")
2257 (set_attr "type" "load")])
2258
2259 (define_insn "*bswaphi2_extendsi"
2260 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2261 (zero_extend:SI
2262 (bswap:HI (match_operand:HI 1 "memory_operand" "Z"))))]
2263 ""
2264 "lhbrx %0,%y1"
2265 [(set_attr "length" "4")
2266 (set_attr "type" "load")])
2267
2268 (define_expand "bswaphi2"
2269 [(parallel [(set (match_operand:HI 0 "reg_or_mem_operand" "")
2270 (bswap:HI
2271 (match_operand:HI 1 "reg_or_mem_operand" "")))
2272 (clobber (match_scratch:SI 2 ""))])]
2273 ""
2274 {
2275 if (!REG_P (operands[0]) && !REG_P (operands[1]))
2276 operands[1] = force_reg (HImode, operands[1]);
2277 })
2278
2279 (define_insn "bswaphi2_internal"
2280 [(set (match_operand:HI 0 "reg_or_mem_operand" "=r,Z,&r")
2281 (bswap:HI
2282 (match_operand:HI 1 "reg_or_mem_operand" "Z,r,r")))
2283 (clobber (match_scratch:SI 2 "=X,X,&r"))]
2284 ""
2285 "@
2286 lhbrx %0,%y1
2287 sthbrx %1,%y0
2288 #"
2289 [(set_attr "length" "4,4,12")
2290 (set_attr "type" "load,store,*")])
2291
2292 (define_split
2293 [(set (match_operand:HI 0 "gpc_reg_operand" "")
2294 (bswap:HI (match_operand:HI 1 "gpc_reg_operand" "")))
2295 (clobber (match_operand:SI 2 "gpc_reg_operand" ""))]
2296 "reload_completed"
2297 [(set (match_dup 3)
2298 (and:SI (lshiftrt:SI (match_dup 4)
2299 (const_int 8))
2300 (const_int 255)))
2301 (set (match_dup 2)
2302 (and:SI (ashift:SI (match_dup 4)
2303 (const_int 8))
2304 (const_int 65280))) ;; 0xff00
2305 (set (match_dup 3)
2306 (ior:SI (match_dup 3)
2307 (match_dup 2)))]
2308 "
2309 {
2310 operands[3] = simplify_gen_subreg (SImode, operands[0], HImode, 0);
2311 operands[4] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
2312 }")
2313
2314 (define_insn "*bswapsi2_extenddi"
2315 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2316 (zero_extend:DI
2317 (bswap:SI (match_operand:SI 1 "memory_operand" "Z"))))]
2318 "TARGET_POWERPC64"
2319 "lwbrx %0,%y1"
2320 [(set_attr "length" "4")
2321 (set_attr "type" "load")])
2322
2323 (define_expand "bswapsi2"
2324 [(set (match_operand:SI 0 "reg_or_mem_operand" "")
2325 (bswap:SI
2326 (match_operand:SI 1 "reg_or_mem_operand" "")))]
2327 ""
2328 {
2329 if (!REG_P (operands[0]) && !REG_P (operands[1]))
2330 operands[1] = force_reg (SImode, operands[1]);
2331 })
2332
2333 (define_insn "*bswapsi2_internal"
2334 [(set (match_operand:SI 0 "reg_or_mem_operand" "=r,Z,&r")
2335 (bswap:SI
2336 (match_operand:SI 1 "reg_or_mem_operand" "Z,r,r")))]
2337 ""
2338 "@
2339 lwbrx %0,%y1
2340 stwbrx %1,%y0
2341 #"
2342 [(set_attr "length" "4,4,12")
2343 (set_attr "type" "load,store,*")])
2344
2345 ;; We are always BITS_BIG_ENDIAN, so the bit positions below in
2346 ;; zero_extract insns do not change for -mlittle.
2347 (define_split
2348 [(set (match_operand:SI 0 "gpc_reg_operand" "")
2349 (bswap:SI (match_operand:SI 1 "gpc_reg_operand" "")))]
2350 "reload_completed"
2351 [(set (match_dup 0) ; DABC
2352 (rotate:SI (match_dup 1)
2353 (const_int 24)))
2354 (set (match_dup 0) ; DCBC
2355 (ior:SI (and:SI (ashift:SI (match_dup 1)
2356 (const_int 8))
2357 (const_int 16711680))
2358 (and:SI (match_dup 0)
2359 (const_int -16711681))))
2360 (set (match_dup 0) ; DCBA
2361 (ior:SI (and:SI (lshiftrt:SI (match_dup 1)
2362 (const_int 24))
2363 (const_int 255))
2364 (and:SI (match_dup 0)
2365 (const_int -256))))
2366
2367 ]
2368 "")
2369
2370 (define_expand "bswapdi2"
2371 [(parallel [(set (match_operand:DI 0 "reg_or_mem_operand" "")
2372 (bswap:DI
2373 (match_operand:DI 1 "reg_or_mem_operand" "")))
2374 (clobber (match_scratch:DI 2 ""))
2375 (clobber (match_scratch:DI 3 ""))])]
2376 ""
2377 {
2378 if (!REG_P (operands[0]) && !REG_P (operands[1]))
2379 operands[1] = force_reg (DImode, operands[1]);
2380
2381 if (!TARGET_POWERPC64)
2382 {
2383 /* 32-bit mode needs fewer scratch registers, but 32-bit addressing mode
2384 that uses 64-bit registers needs the same scratch registers as 64-bit
2385 mode. */
2386 emit_insn (gen_bswapdi2_32bit (operands[0], operands[1]));
2387 DONE;
2388 }
2389 })
2390
2391 ;; Power7/cell has ldbrx/stdbrx, so use it directly
2392 (define_insn "*bswapdi2_ldbrx"
2393 [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,&r")
2394 (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2395 (clobber (match_scratch:DI 2 "=X,X,&r"))
2396 (clobber (match_scratch:DI 3 "=X,X,&r"))]
2397 "TARGET_POWERPC64 && TARGET_LDBRX
2398 && (REG_P (operands[0]) || REG_P (operands[1]))"
2399 "@
2400 ldbrx %0,%y1
2401 stdbrx %1,%y0
2402 #"
2403 [(set_attr "length" "4,4,36")
2404 (set_attr "type" "load,store,*")])
2405
2406 ;; Non-power7/cell, fall back to use lwbrx/stwbrx
2407 (define_insn "*bswapdi2_64bit"
2408 [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,&r")
2409 (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2410 (clobber (match_scratch:DI 2 "=&b,&b,&r"))
2411 (clobber (match_scratch:DI 3 "=&r,&r,&r"))]
2412 "TARGET_POWERPC64 && !TARGET_LDBRX
2413 && (REG_P (operands[0]) || REG_P (operands[1]))
2414 && !(MEM_P (operands[0]) && MEM_VOLATILE_P (operands[0]))
2415 && !(MEM_P (operands[1]) && MEM_VOLATILE_P (operands[1]))"
2416 "#"
2417 [(set_attr "length" "16,12,36")])
2418
2419 (define_split
2420 [(set (match_operand:DI 0 "gpc_reg_operand" "")
2421 (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand" "")))
2422 (clobber (match_operand:DI 2 "gpc_reg_operand" ""))
2423 (clobber (match_operand:DI 3 "gpc_reg_operand" ""))]
2424 "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2425 [(const_int 0)]
2426 "
2427 {
2428 rtx dest = operands[0];
2429 rtx src = operands[1];
2430 rtx op2 = operands[2];
2431 rtx op3 = operands[3];
2432 rtx op3_32 = simplify_gen_subreg (SImode, op3, DImode,
2433 BYTES_BIG_ENDIAN ? 4 : 0);
2434 rtx dest_32 = simplify_gen_subreg (SImode, dest, DImode,
2435 BYTES_BIG_ENDIAN ? 4 : 0);
2436 rtx addr1;
2437 rtx addr2;
2438 rtx word1;
2439 rtx word2;
2440
2441 addr1 = XEXP (src, 0);
2442 if (GET_CODE (addr1) == PLUS)
2443 {
2444 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2445 if (TARGET_AVOID_XFORM)
2446 {
2447 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2448 addr2 = op2;
2449 }
2450 else
2451 addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2452 }
2453 else if (TARGET_AVOID_XFORM)
2454 {
2455 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2456 addr2 = op2;
2457 }
2458 else
2459 {
2460 emit_move_insn (op2, GEN_INT (4));
2461 addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2462 }
2463
2464 word1 = change_address (src, SImode, addr1);
2465 word2 = change_address (src, SImode, addr2);
2466
2467 if (BYTES_BIG_ENDIAN)
2468 {
2469 emit_insn (gen_bswapsi2 (op3_32, word2));
2470 emit_insn (gen_bswapsi2 (dest_32, word1));
2471 }
2472 else
2473 {
2474 emit_insn (gen_bswapsi2 (op3_32, word1));
2475 emit_insn (gen_bswapsi2 (dest_32, word2));
2476 }
2477
2478 emit_insn (gen_ashldi3 (op3, op3, GEN_INT (32)));
2479 emit_insn (gen_iordi3 (dest, dest, op3));
2480 DONE;
2481 }")
2482
2483 (define_split
2484 [(set (match_operand:DI 0 "indexed_or_indirect_operand" "")
2485 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2486 (clobber (match_operand:DI 2 "gpc_reg_operand" ""))
2487 (clobber (match_operand:DI 3 "gpc_reg_operand" ""))]
2488 "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2489 [(const_int 0)]
2490 "
2491 {
2492 rtx dest = operands[0];
2493 rtx src = operands[1];
2494 rtx op2 = operands[2];
2495 rtx op3 = operands[3];
2496 rtx src_si = simplify_gen_subreg (SImode, src, DImode,
2497 BYTES_BIG_ENDIAN ? 4 : 0);
2498 rtx op3_si = simplify_gen_subreg (SImode, op3, DImode,
2499 BYTES_BIG_ENDIAN ? 4 : 0);
2500 rtx addr1;
2501 rtx addr2;
2502 rtx word1;
2503 rtx word2;
2504
2505 addr1 = XEXP (dest, 0);
2506 if (GET_CODE (addr1) == PLUS)
2507 {
2508 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2509 if (TARGET_AVOID_XFORM)
2510 {
2511 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2512 addr2 = op2;
2513 }
2514 else
2515 addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2516 }
2517 else if (TARGET_AVOID_XFORM)
2518 {
2519 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2520 addr2 = op2;
2521 }
2522 else
2523 {
2524 emit_move_insn (op2, GEN_INT (4));
2525 addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2526 }
2527
2528 word1 = change_address (dest, SImode, addr1);
2529 word2 = change_address (dest, SImode, addr2);
2530
2531 emit_insn (gen_lshrdi3 (op3, src, GEN_INT (32)));
2532
2533 if (BYTES_BIG_ENDIAN)
2534 {
2535 emit_insn (gen_bswapsi2 (word1, src_si));
2536 emit_insn (gen_bswapsi2 (word2, op3_si));
2537 }
2538 else
2539 {
2540 emit_insn (gen_bswapsi2 (word2, src_si));
2541 emit_insn (gen_bswapsi2 (word1, op3_si));
2542 }
2543 DONE;
2544 }")
2545
2546 (define_split
2547 [(set (match_operand:DI 0 "gpc_reg_operand" "")
2548 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2549 (clobber (match_operand:DI 2 "gpc_reg_operand" ""))
2550 (clobber (match_operand:DI 3 "gpc_reg_operand" ""))]
2551 "TARGET_POWERPC64 && reload_completed"
2552 [(const_int 0)]
2553 "
2554 {
2555 rtx dest = operands[0];
2556 rtx src = operands[1];
2557 rtx op2 = operands[2];
2558 rtx op3 = operands[3];
2559 int lo_off = BYTES_BIG_ENDIAN ? 4 : 0;
2560 rtx dest_si = simplify_gen_subreg (SImode, dest, DImode, lo_off);
2561 rtx src_si = simplify_gen_subreg (SImode, src, DImode, lo_off);
2562 rtx op2_si = simplify_gen_subreg (SImode, op2, DImode, lo_off);
2563 rtx op3_si = simplify_gen_subreg (SImode, op3, DImode, lo_off);
2564
2565 emit_insn (gen_lshrdi3 (op2, src, GEN_INT (32)));
2566 emit_insn (gen_bswapsi2 (dest_si, src_si));
2567 emit_insn (gen_bswapsi2 (op3_si, op2_si));
2568 emit_insn (gen_ashldi3 (dest, dest, GEN_INT (32)));
2569 emit_insn (gen_iordi3 (dest, dest, op3));
2570 DONE;
2571 }")
2572
2573 (define_insn "bswapdi2_32bit"
2574 [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,?&r")
2575 (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2576 (clobber (match_scratch:SI 2 "=&b,&b,X"))]
2577 "!TARGET_POWERPC64 && (REG_P (operands[0]) || REG_P (operands[1]))"
2578 "#"
2579 [(set_attr "length" "16,12,36")])
2580
2581 (define_split
2582 [(set (match_operand:DI 0 "gpc_reg_operand" "")
2583 (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand" "")))
2584 (clobber (match_operand:SI 2 "gpc_reg_operand" ""))]
2585 "!TARGET_POWERPC64 && reload_completed"
2586 [(const_int 0)]
2587 "
2588 {
2589 rtx dest = operands[0];
2590 rtx src = operands[1];
2591 rtx op2 = operands[2];
2592 rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
2593 rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
2594 rtx addr1;
2595 rtx addr2;
2596 rtx word1;
2597 rtx word2;
2598
2599 addr1 = XEXP (src, 0);
2600 if (GET_CODE (addr1) == PLUS)
2601 {
2602 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2603 if (TARGET_AVOID_XFORM
2604 || REGNO (XEXP (addr1, 1)) == REGNO (dest2))
2605 {
2606 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2607 addr2 = op2;
2608 }
2609 else
2610 addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
2611 }
2612 else if (TARGET_AVOID_XFORM
2613 || REGNO (addr1) == REGNO (dest2))
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 (SImode, op2, addr1);
2622 }
2623
2624 word1 = change_address (src, SImode, addr1);
2625 word2 = change_address (src, SImode, addr2);
2626
2627 emit_insn (gen_bswapsi2 (dest2, word1));
2628 /* The REGNO (dest2) tests above ensure that addr2 has not been trashed,
2629 thus allowing us to omit an early clobber on the output. */
2630 emit_insn (gen_bswapsi2 (dest1, word2));
2631 DONE;
2632 }")
2633
2634 (define_split
2635 [(set (match_operand:DI 0 "indexed_or_indirect_operand" "")
2636 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2637 (clobber (match_operand:SI 2 "gpc_reg_operand" ""))]
2638 "!TARGET_POWERPC64 && reload_completed"
2639 [(const_int 0)]
2640 "
2641 {
2642 rtx dest = operands[0];
2643 rtx src = operands[1];
2644 rtx op2 = operands[2];
2645 rtx src1 = simplify_gen_subreg (SImode, src, DImode, 0);
2646 rtx src2 = simplify_gen_subreg (SImode, src, DImode, 4);
2647 rtx addr1;
2648 rtx addr2;
2649 rtx word1;
2650 rtx word2;
2651
2652 addr1 = XEXP (dest, 0);
2653 if (GET_CODE (addr1) == PLUS)
2654 {
2655 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2656 if (TARGET_AVOID_XFORM)
2657 {
2658 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2659 addr2 = op2;
2660 }
2661 else
2662 addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
2663 }
2664 else if (TARGET_AVOID_XFORM)
2665 {
2666 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2667 addr2 = op2;
2668 }
2669 else
2670 {
2671 emit_move_insn (op2, GEN_INT (4));
2672 addr2 = gen_rtx_PLUS (SImode, op2, addr1);
2673 }
2674
2675 word1 = change_address (dest, SImode, addr1);
2676 word2 = change_address (dest, SImode, addr2);
2677
2678 emit_insn (gen_bswapsi2 (word2, src1));
2679 emit_insn (gen_bswapsi2 (word1, src2));
2680 DONE;
2681 }")
2682
2683 (define_split
2684 [(set (match_operand:DI 0 "gpc_reg_operand" "")
2685 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2686 (clobber (match_operand:SI 2 "" ""))]
2687 "!TARGET_POWERPC64 && reload_completed"
2688 [(const_int 0)]
2689 "
2690 {
2691 rtx dest = operands[0];
2692 rtx src = operands[1];
2693 rtx src1 = simplify_gen_subreg (SImode, src, DImode, 0);
2694 rtx src2 = simplify_gen_subreg (SImode, src, DImode, 4);
2695 rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
2696 rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
2697
2698 emit_insn (gen_bswapsi2 (dest1, src2));
2699 emit_insn (gen_bswapsi2 (dest2, src1));
2700 DONE;
2701 }")
2702
2703
2704 (define_insn "mul<mode>3"
2705 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2706 (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
2707 (match_operand:GPR 2 "reg_or_short_operand" "r,I")))]
2708 ""
2709 "@
2710 mull<wd> %0,%1,%2
2711 mulli %0,%1,%2"
2712 [(set_attr "type" "mul")
2713 (set (attr "size")
2714 (cond [(match_operand:GPR 2 "s8bit_cint_operand" "")
2715 (const_string "8")
2716 (match_operand:GPR 2 "short_cint_operand" "")
2717 (const_string "16")]
2718 (const_string "<bits>")))])
2719
2720 (define_insn_and_split "*mul<mode>3_dot"
2721 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2722 (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2723 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
2724 (const_int 0)))
2725 (clobber (match_scratch:GPR 0 "=r,r"))]
2726 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
2727 "@
2728 mull<wd>. %0,%1,%2
2729 #"
2730 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2731 [(set (match_dup 0)
2732 (mult:GPR (match_dup 1)
2733 (match_dup 2)))
2734 (set (match_dup 3)
2735 (compare:CC (match_dup 0)
2736 (const_int 0)))]
2737 ""
2738 [(set_attr "type" "mul")
2739 (set_attr "size" "<bits>")
2740 (set_attr "dot" "yes")
2741 (set_attr "length" "4,8")])
2742
2743 (define_insn_and_split "*mul<mode>3_dot2"
2744 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2745 (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2746 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
2747 (const_int 0)))
2748 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2749 (mult:GPR (match_dup 1)
2750 (match_dup 2)))]
2751 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
2752 "@
2753 mull<wd>. %0,%1,%2
2754 #"
2755 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2756 [(set (match_dup 0)
2757 (mult:GPR (match_dup 1)
2758 (match_dup 2)))
2759 (set (match_dup 3)
2760 (compare:CC (match_dup 0)
2761 (const_int 0)))]
2762 ""
2763 [(set_attr "type" "mul")
2764 (set_attr "size" "<bits>")
2765 (set_attr "dot" "yes")
2766 (set_attr "length" "4,8")])
2767
2768
2769 (define_expand "<su>mul<mode>3_highpart"
2770 [(set (match_operand:GPR 0 "gpc_reg_operand")
2771 (subreg:GPR
2772 (mult:<DMODE> (any_extend:<DMODE>
2773 (match_operand:GPR 1 "gpc_reg_operand"))
2774 (any_extend:<DMODE>
2775 (match_operand:GPR 2 "gpc_reg_operand")))
2776 0))]
2777 ""
2778 {
2779 if (<MODE>mode == SImode && TARGET_POWERPC64)
2780 {
2781 emit_insn (gen_<su>mulsi3_highpart_64 (operands[0], operands[1],
2782 operands[2]));
2783 DONE;
2784 }
2785
2786 if (!WORDS_BIG_ENDIAN)
2787 {
2788 emit_insn (gen_<su>mul<mode>3_highpart_le (operands[0], operands[1],
2789 operands[2]));
2790 DONE;
2791 }
2792 })
2793
2794 (define_insn "*<su>mul<mode>3_highpart"
2795 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2796 (subreg:GPR
2797 (mult:<DMODE> (any_extend:<DMODE>
2798 (match_operand:GPR 1 "gpc_reg_operand" "r"))
2799 (any_extend:<DMODE>
2800 (match_operand:GPR 2 "gpc_reg_operand" "r")))
2801 0))]
2802 "WORDS_BIG_ENDIAN && !(<MODE>mode == SImode && TARGET_POWERPC64)"
2803 "mulh<wd><u> %0,%1,%2"
2804 [(set_attr "type" "mul")
2805 (set_attr "size" "<bits>")])
2806
2807 (define_insn "<su>mulsi3_highpart_le"
2808 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2809 (subreg:SI
2810 (mult:DI (any_extend:DI
2811 (match_operand:SI 1 "gpc_reg_operand" "r"))
2812 (any_extend:DI
2813 (match_operand:SI 2 "gpc_reg_operand" "r")))
2814 4))]
2815 "!WORDS_BIG_ENDIAN && !TARGET_POWERPC64"
2816 "mulhw<u> %0,%1,%2"
2817 [(set_attr "type" "mul")])
2818
2819 (define_insn "<su>muldi3_highpart_le"
2820 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2821 (subreg:DI
2822 (mult:TI (any_extend:TI
2823 (match_operand:DI 1 "gpc_reg_operand" "r"))
2824 (any_extend:TI
2825 (match_operand:DI 2 "gpc_reg_operand" "r")))
2826 8))]
2827 "!WORDS_BIG_ENDIAN && TARGET_POWERPC64"
2828 "mulhd<u> %0,%1,%2"
2829 [(set_attr "type" "mul")
2830 (set_attr "size" "64")])
2831
2832 (define_insn "<su>mulsi3_highpart_64"
2833 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2834 (truncate:SI
2835 (lshiftrt:DI
2836 (mult:DI (any_extend:DI
2837 (match_operand:SI 1 "gpc_reg_operand" "r"))
2838 (any_extend:DI
2839 (match_operand:SI 2 "gpc_reg_operand" "r")))
2840 (const_int 32))))]
2841 "TARGET_POWERPC64"
2842 "mulhw<u> %0,%1,%2"
2843 [(set_attr "type" "mul")])
2844
2845 (define_expand "<u>mul<mode><dmode>3"
2846 [(set (match_operand:<DMODE> 0 "gpc_reg_operand")
2847 (mult:<DMODE> (any_extend:<DMODE>
2848 (match_operand:GPR 1 "gpc_reg_operand"))
2849 (any_extend:<DMODE>
2850 (match_operand:GPR 2 "gpc_reg_operand"))))]
2851 "!(<MODE>mode == SImode && TARGET_POWERPC64)"
2852 {
2853 rtx l = gen_reg_rtx (<MODE>mode);
2854 rtx h = gen_reg_rtx (<MODE>mode);
2855 emit_insn (gen_mul<mode>3 (l, operands[1], operands[2]));
2856 emit_insn (gen_<su>mul<mode>3_highpart (h, operands[1], operands[2]));
2857 emit_move_insn (gen_lowpart (<MODE>mode, operands[0]), l);
2858 emit_move_insn (gen_highpart (<MODE>mode, operands[0]), h);
2859 DONE;
2860 })
2861
2862 (define_insn "*maddld4"
2863 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2864 (plus:DI (mult:DI (match_operand:DI 1 "gpc_reg_operand" "r")
2865 (match_operand:DI 2 "gpc_reg_operand" "r"))
2866 (match_operand:DI 3 "gpc_reg_operand" "r")))]
2867 "TARGET_MADDLD"
2868 "maddld %0,%1,%2,%3"
2869 [(set_attr "type" "mul")])
2870
2871 (define_insn "udiv<mode>3"
2872 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2873 (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
2874 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
2875 ""
2876 "div<wd>u %0,%1,%2"
2877 [(set_attr "type" "div")
2878 (set_attr "size" "<bits>")])
2879
2880
2881 ;; For powers of two we can do sra[wd]i/addze for divide and then adjust for
2882 ;; modulus. If it isn't a power of two, force operands into register and do
2883 ;; a normal divide.
2884 (define_expand "div<mode>3"
2885 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2886 (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
2887 (match_operand:GPR 2 "reg_or_cint_operand" "")))]
2888 ""
2889 {
2890 if (CONST_INT_P (operands[2])
2891 && INTVAL (operands[2]) > 0
2892 && exact_log2 (INTVAL (operands[2])) >= 0)
2893 {
2894 emit_insn (gen_div<mode>3_sra (operands[0], operands[1], operands[2]));
2895 DONE;
2896 }
2897
2898 operands[2] = force_reg (<MODE>mode, operands[2]);
2899 })
2900
2901 (define_insn "*div<mode>3"
2902 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2903 (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
2904 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
2905 ""
2906 "div<wd> %0,%1,%2"
2907 [(set_attr "type" "div")
2908 (set_attr "size" "<bits>")])
2909
2910 (define_insn "div<mode>3_sra"
2911 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2912 (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
2913 (match_operand:GPR 2 "exact_log2_cint_operand" "N")))
2914 (clobber (reg:GPR CA_REGNO))]
2915 ""
2916 "sra<wd>i %0,%1,%p2\;addze %0,%0"
2917 [(set_attr "type" "two")
2918 (set_attr "length" "8")])
2919
2920 (define_insn_and_split "*div<mode>3_sra_dot"
2921 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2922 (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2923 (match_operand:GPR 2 "exact_log2_cint_operand" "N,N"))
2924 (const_int 0)))
2925 (clobber (match_scratch:GPR 0 "=r,r"))
2926 (clobber (reg:GPR CA_REGNO))]
2927 "<MODE>mode == Pmode"
2928 "@
2929 sra<wd>i %0,%1,%p2\;addze. %0,%0
2930 #"
2931 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2932 [(parallel [(set (match_dup 0)
2933 (div:GPR (match_dup 1)
2934 (match_dup 2)))
2935 (clobber (reg:GPR CA_REGNO))])
2936 (set (match_dup 3)
2937 (compare:CC (match_dup 0)
2938 (const_int 0)))]
2939 ""
2940 [(set_attr "type" "two")
2941 (set_attr "length" "8,12")
2942 (set_attr "cell_micro" "not")])
2943
2944 (define_insn_and_split "*div<mode>3_sra_dot2"
2945 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2946 (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2947 (match_operand:GPR 2 "exact_log2_cint_operand" "N,N"))
2948 (const_int 0)))
2949 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2950 (div:GPR (match_dup 1)
2951 (match_dup 2)))
2952 (clobber (reg:GPR CA_REGNO))]
2953 "<MODE>mode == Pmode"
2954 "@
2955 sra<wd>i %0,%1,%p2\;addze. %0,%0
2956 #"
2957 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2958 [(parallel [(set (match_dup 0)
2959 (div:GPR (match_dup 1)
2960 (match_dup 2)))
2961 (clobber (reg:GPR CA_REGNO))])
2962 (set (match_dup 3)
2963 (compare:CC (match_dup 0)
2964 (const_int 0)))]
2965 ""
2966 [(set_attr "type" "two")
2967 (set_attr "length" "8,12")
2968 (set_attr "cell_micro" "not")])
2969
2970 (define_expand "mod<mode>3"
2971 [(set (match_operand:GPR 0 "gpc_reg_operand")
2972 (mod:GPR (match_operand:GPR 1 "gpc_reg_operand")
2973 (match_operand:GPR 2 "reg_or_cint_operand")))]
2974 ""
2975 {
2976 int i;
2977 rtx temp1;
2978 rtx temp2;
2979
2980 if (GET_CODE (operands[2]) != CONST_INT
2981 || INTVAL (operands[2]) <= 0
2982 || (i = exact_log2 (INTVAL (operands[2]))) < 0)
2983 {
2984 if (!TARGET_MODULO)
2985 FAIL;
2986
2987 operands[2] = force_reg (<MODE>mode, operands[2]);
2988 }
2989 else
2990 {
2991 temp1 = gen_reg_rtx (<MODE>mode);
2992 temp2 = gen_reg_rtx (<MODE>mode);
2993
2994 emit_insn (gen_div<mode>3 (temp1, operands[1], operands[2]));
2995 emit_insn (gen_ashl<mode>3 (temp2, temp1, GEN_INT (i)));
2996 emit_insn (gen_sub<mode>3 (operands[0], operands[1], temp2));
2997 DONE;
2998 }
2999 })
3000
3001 ;; In order to enable using a peephole2 for combining div/mod to eliminate the
3002 ;; mod, prefer putting the result of mod into a different register
3003 (define_insn "*mod<mode>3"
3004 [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
3005 (mod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3006 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3007 "TARGET_MODULO"
3008 "mods<wd> %0,%1,%2"
3009 [(set_attr "type" "div")
3010 (set_attr "size" "<bits>")])
3011
3012
3013 (define_insn "umod<mode>3"
3014 [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
3015 (umod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3016 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3017 "TARGET_MODULO"
3018 "modu<wd> %0,%1,%2"
3019 [(set_attr "type" "div")
3020 (set_attr "size" "<bits>")])
3021
3022 ;; On machines with modulo support, do a combined div/mod the old fashioned
3023 ;; method, since the multiply/subtract is faster than doing the mod instruction
3024 ;; after a divide.
3025
3026 (define_peephole2
3027 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
3028 (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
3029 (match_operand:GPR 2 "gpc_reg_operand" "")))
3030 (set (match_operand:GPR 3 "gpc_reg_operand" "")
3031 (mod:GPR (match_dup 1)
3032 (match_dup 2)))]
3033 "TARGET_MODULO
3034 && ! reg_mentioned_p (operands[0], operands[1])
3035 && ! reg_mentioned_p (operands[0], operands[2])
3036 && ! reg_mentioned_p (operands[3], operands[1])
3037 && ! reg_mentioned_p (operands[3], operands[2])"
3038 [(set (match_dup 0)
3039 (div:GPR (match_dup 1)
3040 (match_dup 2)))
3041 (set (match_dup 3)
3042 (mult:GPR (match_dup 0)
3043 (match_dup 2)))
3044 (set (match_dup 3)
3045 (minus:GPR (match_dup 1)
3046 (match_dup 3)))])
3047
3048 (define_peephole2
3049 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
3050 (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
3051 (match_operand:GPR 2 "gpc_reg_operand" "")))
3052 (set (match_operand:GPR 3 "gpc_reg_operand" "")
3053 (umod:GPR (match_dup 1)
3054 (match_dup 2)))]
3055 "TARGET_MODULO
3056 && ! reg_mentioned_p (operands[0], operands[1])
3057 && ! reg_mentioned_p (operands[0], operands[2])
3058 && ! reg_mentioned_p (operands[3], operands[1])
3059 && ! reg_mentioned_p (operands[3], operands[2])"
3060 [(set (match_dup 0)
3061 (div:GPR (match_dup 1)
3062 (match_dup 2)))
3063 (set (match_dup 3)
3064 (mult:GPR (match_dup 0)
3065 (match_dup 2)))
3066 (set (match_dup 3)
3067 (minus:GPR (match_dup 1)
3068 (match_dup 3)))])
3069
3070 \f
3071 ;; Logical instructions
3072 ;; The logical instructions are mostly combined by using match_operator,
3073 ;; but the plain AND insns are somewhat different because there is no
3074 ;; plain 'andi' (only 'andi.'), no plain 'andis', and there are all
3075 ;; those rotate-and-mask operations. Thus, the AND insns come first.
3076
3077 (define_expand "and<mode>3"
3078 [(set (match_operand:SDI 0 "gpc_reg_operand" "")
3079 (and:SDI (match_operand:SDI 1 "gpc_reg_operand" "")
3080 (match_operand:SDI 2 "reg_or_cint_operand" "")))]
3081 ""
3082 {
3083 if (<MODE>mode == DImode && !TARGET_POWERPC64)
3084 {
3085 rs6000_split_logical (operands, AND, false, false, false);
3086 DONE;
3087 }
3088
3089 if (CONST_INT_P (operands[2]))
3090 {
3091 if (rs6000_is_valid_and_mask (operands[2], <MODE>mode))
3092 {
3093 emit_insn (gen_and<mode>3_mask (operands[0], operands[1], operands[2]));
3094 DONE;
3095 }
3096
3097 if (logical_const_operand (operands[2], <MODE>mode)
3098 && rs6000_gen_cell_microcode)
3099 {
3100 emit_insn (gen_and<mode>3_imm (operands[0], operands[1], operands[2]));
3101 DONE;
3102 }
3103
3104 if (rs6000_is_valid_2insn_and (operands[2], <MODE>mode))
3105 {
3106 rs6000_emit_2insn_and (<MODE>mode, operands, true, 0);
3107 DONE;
3108 }
3109
3110 operands[2] = force_reg (<MODE>mode, operands[2]);
3111 }
3112 })
3113
3114
3115 (define_insn "and<mode>3_imm"
3116 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3117 (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3118 (match_operand:GPR 2 "logical_const_operand" "n")))
3119 (clobber (match_scratch:CC 3 "=x"))]
3120 "rs6000_gen_cell_microcode
3121 && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3122 "andi%e2. %0,%1,%u2"
3123 [(set_attr "type" "logical")
3124 (set_attr "dot" "yes")])
3125
3126 (define_insn_and_split "*and<mode>3_imm_dot"
3127 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3128 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3129 (match_operand:GPR 2 "logical_const_operand" "n,n"))
3130 (const_int 0)))
3131 (clobber (match_scratch:GPR 0 "=r,r"))
3132 (clobber (match_scratch:CC 4 "=X,x"))]
3133 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3134 && rs6000_gen_cell_microcode
3135 && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3136 "@
3137 andi%e2. %0,%1,%u2
3138 #"
3139 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3140 [(parallel [(set (match_dup 0)
3141 (and:GPR (match_dup 1)
3142 (match_dup 2)))
3143 (clobber (match_dup 4))])
3144 (set (match_dup 3)
3145 (compare:CC (match_dup 0)
3146 (const_int 0)))]
3147 ""
3148 [(set_attr "type" "logical")
3149 (set_attr "dot" "yes")
3150 (set_attr "length" "4,8")])
3151
3152 (define_insn_and_split "*and<mode>3_imm_dot2"
3153 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3154 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3155 (match_operand:GPR 2 "logical_const_operand" "n,n"))
3156 (const_int 0)))
3157 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3158 (and:GPR (match_dup 1)
3159 (match_dup 2)))
3160 (clobber (match_scratch:CC 4 "=X,x"))]
3161 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3162 && rs6000_gen_cell_microcode
3163 && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3164 "@
3165 andi%e2. %0,%1,%u2
3166 #"
3167 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3168 [(parallel [(set (match_dup 0)
3169 (and:GPR (match_dup 1)
3170 (match_dup 2)))
3171 (clobber (match_dup 4))])
3172 (set (match_dup 3)
3173 (compare:CC (match_dup 0)
3174 (const_int 0)))]
3175 ""
3176 [(set_attr "type" "logical")
3177 (set_attr "dot" "yes")
3178 (set_attr "length" "4,8")])
3179
3180 (define_insn_and_split "*and<mode>3_imm_mask_dot"
3181 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3182 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3183 (match_operand:GPR 2 "logical_const_operand" "n,n"))
3184 (const_int 0)))
3185 (clobber (match_scratch:GPR 0 "=r,r"))]
3186 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3187 && rs6000_gen_cell_microcode"
3188 "@
3189 andi%e2. %0,%1,%u2
3190 #"
3191 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3192 [(set (match_dup 0)
3193 (and:GPR (match_dup 1)
3194 (match_dup 2)))
3195 (set (match_dup 3)
3196 (compare:CC (match_dup 0)
3197 (const_int 0)))]
3198 ""
3199 [(set_attr "type" "logical")
3200 (set_attr "dot" "yes")
3201 (set_attr "length" "4,8")])
3202
3203 (define_insn_and_split "*and<mode>3_imm_mask_dot2"
3204 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3205 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3206 (match_operand:GPR 2 "logical_const_operand" "n,n"))
3207 (const_int 0)))
3208 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3209 (and:GPR (match_dup 1)
3210 (match_dup 2)))]
3211 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3212 && rs6000_gen_cell_microcode"
3213 "@
3214 andi%e2. %0,%1,%u2
3215 #"
3216 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3217 [(set (match_dup 0)
3218 (and:GPR (match_dup 1)
3219 (match_dup 2)))
3220 (set (match_dup 3)
3221 (compare:CC (match_dup 0)
3222 (const_int 0)))]
3223 ""
3224 [(set_attr "type" "logical")
3225 (set_attr "dot" "yes")
3226 (set_attr "length" "4,8")])
3227
3228 (define_insn "*and<mode>3_imm_dot_shifted"
3229 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
3230 (compare:CC
3231 (and:GPR
3232 (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3233 (match_operand:SI 4 "const_int_operand" "n"))
3234 (match_operand:GPR 2 "const_int_operand" "n"))
3235 (const_int 0)))
3236 (clobber (match_scratch:GPR 0 "=r"))]
3237 "logical_const_operand (GEN_INT (UINTVAL (operands[2])
3238 << INTVAL (operands[4])),
3239 DImode)
3240 && (<MODE>mode == Pmode
3241 || (UINTVAL (operands[2]) << INTVAL (operands[4])) <= 0x7fffffff)
3242 && rs6000_gen_cell_microcode"
3243 {
3244 operands[2] = GEN_INT (UINTVAL (operands[2]) << INTVAL (operands[4]));
3245 return "andi%e2. %0,%1,%u2";
3246 }
3247 [(set_attr "type" "logical")
3248 (set_attr "dot" "yes")])
3249
3250
3251 (define_insn "and<mode>3_mask"
3252 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3253 (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3254 (match_operand:GPR 2 "const_int_operand" "n")))]
3255 "rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3256 {
3257 return rs6000_insn_for_and_mask (<MODE>mode, operands, false);
3258 }
3259 [(set_attr "type" "shift")])
3260
3261 (define_insn_and_split "*and<mode>3_mask_dot"
3262 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3263 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3264 (match_operand:GPR 2 "const_int_operand" "n,n"))
3265 (const_int 0)))
3266 (clobber (match_scratch:GPR 0 "=r,r"))]
3267 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3268 && rs6000_gen_cell_microcode
3269 && !logical_const_operand (operands[2], <MODE>mode)
3270 && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3271 {
3272 if (which_alternative == 0)
3273 return rs6000_insn_for_and_mask (<MODE>mode, operands, true);
3274 else
3275 return "#";
3276 }
3277 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3278 [(set (match_dup 0)
3279 (and:GPR (match_dup 1)
3280 (match_dup 2)))
3281 (set (match_dup 3)
3282 (compare:CC (match_dup 0)
3283 (const_int 0)))]
3284 ""
3285 [(set_attr "type" "shift")
3286 (set_attr "dot" "yes")
3287 (set_attr "length" "4,8")])
3288
3289 (define_insn_and_split "*and<mode>3_mask_dot2"
3290 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3291 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3292 (match_operand:GPR 2 "const_int_operand" "n,n"))
3293 (const_int 0)))
3294 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3295 (and:GPR (match_dup 1)
3296 (match_dup 2)))]
3297 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3298 && rs6000_gen_cell_microcode
3299 && !logical_const_operand (operands[2], <MODE>mode)
3300 && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3301 {
3302 if (which_alternative == 0)
3303 return rs6000_insn_for_and_mask (<MODE>mode, operands, true);
3304 else
3305 return "#";
3306 }
3307 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3308 [(set (match_dup 0)
3309 (and:GPR (match_dup 1)
3310 (match_dup 2)))
3311 (set (match_dup 3)
3312 (compare:CC (match_dup 0)
3313 (const_int 0)))]
3314 ""
3315 [(set_attr "type" "shift")
3316 (set_attr "dot" "yes")
3317 (set_attr "length" "4,8")])
3318
3319
3320 (define_insn_and_split "*and<mode>3_2insn"
3321 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3322 (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3323 (match_operand:GPR 2 "const_int_operand" "n")))]
3324 "rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3325 && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3326 || (logical_const_operand (operands[2], <MODE>mode)
3327 && rs6000_gen_cell_microcode))"
3328 "#"
3329 "&& 1"
3330 [(pc)]
3331 {
3332 rs6000_emit_2insn_and (<MODE>mode, operands, false, 0);
3333 DONE;
3334 }
3335 [(set_attr "type" "shift")
3336 (set_attr "length" "8")])
3337
3338 (define_insn_and_split "*and<mode>3_2insn_dot"
3339 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3340 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3341 (match_operand:GPR 2 "const_int_operand" "n,n"))
3342 (const_int 0)))
3343 (clobber (match_scratch:GPR 0 "=r,r"))]
3344 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3345 && rs6000_gen_cell_microcode
3346 && rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3347 && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3348 || (logical_const_operand (operands[2], <MODE>mode)
3349 && rs6000_gen_cell_microcode))"
3350 "#"
3351 "&& reload_completed"
3352 [(pc)]
3353 {
3354 rs6000_emit_2insn_and (<MODE>mode, operands, false, 1);
3355 DONE;
3356 }
3357 [(set_attr "type" "shift")
3358 (set_attr "dot" "yes")
3359 (set_attr "length" "8,12")])
3360
3361 (define_insn_and_split "*and<mode>3_2insn_dot2"
3362 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3363 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3364 (match_operand:GPR 2 "const_int_operand" "n,n"))
3365 (const_int 0)))
3366 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3367 (and:GPR (match_dup 1)
3368 (match_dup 2)))]
3369 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3370 && rs6000_gen_cell_microcode
3371 && rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3372 && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3373 || (logical_const_operand (operands[2], <MODE>mode)
3374 && rs6000_gen_cell_microcode))"
3375 "#"
3376 "&& reload_completed"
3377 [(pc)]
3378 {
3379 rs6000_emit_2insn_and (<MODE>mode, operands, false, 2);
3380 DONE;
3381 }
3382 [(set_attr "type" "shift")
3383 (set_attr "dot" "yes")
3384 (set_attr "length" "8,12")])
3385
3386
3387 (define_expand "<code><mode>3"
3388 [(set (match_operand:SDI 0 "gpc_reg_operand" "")
3389 (iorxor:SDI (match_operand:SDI 1 "gpc_reg_operand" "")
3390 (match_operand:SDI 2 "reg_or_cint_operand" "")))]
3391 ""
3392 {
3393 if (<MODE>mode == DImode && !TARGET_POWERPC64)
3394 {
3395 rs6000_split_logical (operands, <CODE>, false, false, false);
3396 DONE;
3397 }
3398
3399 if (non_logical_cint_operand (operands[2], <MODE>mode))
3400 {
3401 rtx tmp = ((!can_create_pseudo_p ()
3402 || rtx_equal_p (operands[0], operands[1]))
3403 ? operands[0] : gen_reg_rtx (<MODE>mode));
3404
3405 HOST_WIDE_INT value = INTVAL (operands[2]);
3406 HOST_WIDE_INT lo = value & 0xffff;
3407 HOST_WIDE_INT hi = value - lo;
3408
3409 emit_insn (gen_<code><mode>3 (tmp, operands[1], GEN_INT (hi)));
3410 emit_insn (gen_<code><mode>3 (operands[0], tmp, GEN_INT (lo)));
3411 DONE;
3412 }
3413
3414 if (!reg_or_logical_cint_operand (operands[2], <MODE>mode))
3415 operands[2] = force_reg (<MODE>mode, operands[2]);
3416 })
3417
3418 (define_split
3419 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
3420 (iorxor:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
3421 (match_operand:GPR 2 "non_logical_cint_operand" "")))]
3422 ""
3423 [(set (match_dup 3)
3424 (iorxor:GPR (match_dup 1)
3425 (match_dup 4)))
3426 (set (match_dup 0)
3427 (iorxor:GPR (match_dup 3)
3428 (match_dup 5)))]
3429 {
3430 operands[3] = ((!can_create_pseudo_p ()
3431 || rtx_equal_p (operands[0], operands[1]))
3432 ? operands[0] : gen_reg_rtx (<MODE>mode));
3433
3434 HOST_WIDE_INT value = INTVAL (operands[2]);
3435 HOST_WIDE_INT lo = value & 0xffff;
3436 HOST_WIDE_INT hi = value - lo;
3437
3438 operands[4] = GEN_INT (hi);
3439 operands[5] = GEN_INT (lo);
3440 })
3441
3442 (define_insn "*bool<mode>3_imm"
3443 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3444 (match_operator:GPR 3 "boolean_or_operator"
3445 [(match_operand:GPR 1 "gpc_reg_operand" "%r")
3446 (match_operand:GPR 2 "logical_const_operand" "n")]))]
3447 ""
3448 "%q3i%e2 %0,%1,%u2"
3449 [(set_attr "type" "logical")])
3450
3451 (define_insn "*bool<mode>3"
3452 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3453 (match_operator:GPR 3 "boolean_operator"
3454 [(match_operand:GPR 1 "gpc_reg_operand" "r")
3455 (match_operand:GPR 2 "gpc_reg_operand" "r")]))]
3456 ""
3457 "%q3 %0,%1,%2"
3458 [(set_attr "type" "logical")])
3459
3460 (define_insn_and_split "*bool<mode>3_dot"
3461 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3462 (compare:CC (match_operator:GPR 3 "boolean_operator"
3463 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3464 (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
3465 (const_int 0)))
3466 (clobber (match_scratch:GPR 0 "=r,r"))]
3467 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3468 "@
3469 %q3. %0,%1,%2
3470 #"
3471 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3472 [(set (match_dup 0)
3473 (match_dup 3))
3474 (set (match_dup 4)
3475 (compare:CC (match_dup 0)
3476 (const_int 0)))]
3477 ""
3478 [(set_attr "type" "logical")
3479 (set_attr "dot" "yes")
3480 (set_attr "length" "4,8")])
3481
3482 (define_insn_and_split "*bool<mode>3_dot2"
3483 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3484 (compare:CC (match_operator:GPR 3 "boolean_operator"
3485 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3486 (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
3487 (const_int 0)))
3488 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3489 (match_dup 3))]
3490 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3491 "@
3492 %q3. %0,%1,%2
3493 #"
3494 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3495 [(set (match_dup 0)
3496 (match_dup 3))
3497 (set (match_dup 4)
3498 (compare:CC (match_dup 0)
3499 (const_int 0)))]
3500 ""
3501 [(set_attr "type" "logical")
3502 (set_attr "dot" "yes")
3503 (set_attr "length" "4,8")])
3504
3505
3506 (define_insn "*boolc<mode>3"
3507 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3508 (match_operator:GPR 3 "boolean_operator"
3509 [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))
3510 (match_operand:GPR 1 "gpc_reg_operand" "r")]))]
3511 ""
3512 "%q3 %0,%1,%2"
3513 [(set_attr "type" "logical")])
3514
3515 (define_insn_and_split "*boolc<mode>3_dot"
3516 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3517 (compare:CC (match_operator:GPR 3 "boolean_operator"
3518 [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3519 (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
3520 (const_int 0)))
3521 (clobber (match_scratch:GPR 0 "=r,r"))]
3522 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3523 "@
3524 %q3. %0,%1,%2
3525 #"
3526 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3527 [(set (match_dup 0)
3528 (match_dup 3))
3529 (set (match_dup 4)
3530 (compare:CC (match_dup 0)
3531 (const_int 0)))]
3532 ""
3533 [(set_attr "type" "logical")
3534 (set_attr "dot" "yes")
3535 (set_attr "length" "4,8")])
3536
3537 (define_insn_and_split "*boolc<mode>3_dot2"
3538 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3539 (compare:CC (match_operator:GPR 3 "boolean_operator"
3540 [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3541 (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
3542 (const_int 0)))
3543 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3544 (match_dup 3))]
3545 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3546 "@
3547 %q3. %0,%1,%2
3548 #"
3549 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3550 [(set (match_dup 0)
3551 (match_dup 3))
3552 (set (match_dup 4)
3553 (compare:CC (match_dup 0)
3554 (const_int 0)))]
3555 ""
3556 [(set_attr "type" "logical")
3557 (set_attr "dot" "yes")
3558 (set_attr "length" "4,8")])
3559
3560
3561 (define_insn "*boolcc<mode>3"
3562 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3563 (match_operator:GPR 3 "boolean_operator"
3564 [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
3565 (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))]))]
3566 ""
3567 "%q3 %0,%1,%2"
3568 [(set_attr "type" "logical")])
3569
3570 (define_insn_and_split "*boolcc<mode>3_dot"
3571 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3572 (compare:CC (match_operator:GPR 3 "boolean_operator"
3573 [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
3574 (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
3575 (const_int 0)))
3576 (clobber (match_scratch:GPR 0 "=r,r"))]
3577 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3578 "@
3579 %q3. %0,%1,%2
3580 #"
3581 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3582 [(set (match_dup 0)
3583 (match_dup 3))
3584 (set (match_dup 4)
3585 (compare:CC (match_dup 0)
3586 (const_int 0)))]
3587 ""
3588 [(set_attr "type" "logical")
3589 (set_attr "dot" "yes")
3590 (set_attr "length" "4,8")])
3591
3592 (define_insn_and_split "*boolcc<mode>3_dot2"
3593 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3594 (compare:CC (match_operator:GPR 3 "boolean_operator"
3595 [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
3596 (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
3597 (const_int 0)))
3598 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3599 (match_dup 3))]
3600 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3601 "@
3602 %q3. %0,%1,%2
3603 #"
3604 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3605 [(set (match_dup 0)
3606 (match_dup 3))
3607 (set (match_dup 4)
3608 (compare:CC (match_dup 0)
3609 (const_int 0)))]
3610 ""
3611 [(set_attr "type" "logical")
3612 (set_attr "dot" "yes")
3613 (set_attr "length" "4,8")])
3614
3615
3616 ;; TODO: Should have dots of this as well.
3617 (define_insn "*eqv<mode>3"
3618 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3619 (not:GPR (xor:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3620 (match_operand:GPR 2 "gpc_reg_operand" "r"))))]
3621 ""
3622 "eqv %0,%1,%2"
3623 [(set_attr "type" "logical")])
3624 \f
3625 ;; Rotate-and-mask and insert.
3626
3627 (define_insn "*rotl<mode>3_mask"
3628 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3629 (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3630 [(match_operand:GPR 1 "gpc_reg_operand" "r")
3631 (match_operand:SI 2 "reg_or_cint_operand" "rn")])
3632 (match_operand:GPR 3 "const_int_operand" "n")))]
3633 "rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3634 {
3635 return rs6000_insn_for_shift_mask (<MODE>mode, operands, false);
3636 }
3637 [(set_attr "type" "shift")
3638 (set_attr "maybe_var_shift" "yes")])
3639
3640 (define_insn_and_split "*rotl<mode>3_mask_dot"
3641 [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y")
3642 (compare:CC
3643 (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3644 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3645 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")])
3646 (match_operand:GPR 3 "const_int_operand" "n,n"))
3647 (const_int 0)))
3648 (clobber (match_scratch:GPR 0 "=r,r"))]
3649 "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff)
3650 && rs6000_gen_cell_microcode
3651 && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3652 {
3653 if (which_alternative == 0)
3654 return rs6000_insn_for_shift_mask (<MODE>mode, operands, true);
3655 else
3656 return "#";
3657 }
3658 "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)"
3659 [(set (match_dup 0)
3660 (and:GPR (match_dup 4)
3661 (match_dup 3)))
3662 (set (match_dup 5)
3663 (compare:CC (match_dup 0)
3664 (const_int 0)))]
3665 ""
3666 [(set_attr "type" "shift")
3667 (set_attr "maybe_var_shift" "yes")
3668 (set_attr "dot" "yes")
3669 (set_attr "length" "4,8")])
3670
3671 (define_insn_and_split "*rotl<mode>3_mask_dot2"
3672 [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y")
3673 (compare:CC
3674 (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3675 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3676 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")])
3677 (match_operand:GPR 3 "const_int_operand" "n,n"))
3678 (const_int 0)))
3679 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3680 (and:GPR (match_dup 4)
3681 (match_dup 3)))]
3682 "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff)
3683 && rs6000_gen_cell_microcode
3684 && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3685 {
3686 if (which_alternative == 0)
3687 return rs6000_insn_for_shift_mask (<MODE>mode, operands, true);
3688 else
3689 return "#";
3690 }
3691 "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)"
3692 [(set (match_dup 0)
3693 (and:GPR (match_dup 4)
3694 (match_dup 3)))
3695 (set (match_dup 5)
3696 (compare:CC (match_dup 0)
3697 (const_int 0)))]
3698 ""
3699 [(set_attr "type" "shift")
3700 (set_attr "maybe_var_shift" "yes")
3701 (set_attr "dot" "yes")
3702 (set_attr "length" "4,8")])
3703
3704 ; Special case for less-than-0. We can do it with just one machine
3705 ; instruction, but the generic optimizers do not realise it is cheap.
3706 (define_insn "*lt0_disi"
3707 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3708 (lt:DI (match_operand:SI 1 "gpc_reg_operand" "r")
3709 (const_int 0)))]
3710 "TARGET_POWERPC64"
3711 "rlwinm %0,%1,1,31,31"
3712 [(set_attr "type" "shift")])
3713
3714
3715
3716 ; Two forms for insert (the two arms of the IOR are not canonicalized,
3717 ; both are an AND so are the same precedence).
3718 (define_insn "*rotl<mode>3_insert"
3719 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3720 (ior:GPR (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3721 [(match_operand:GPR 1 "gpc_reg_operand" "r")
3722 (match_operand:SI 2 "const_int_operand" "n")])
3723 (match_operand:GPR 3 "const_int_operand" "n"))
3724 (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0")
3725 (match_operand:GPR 6 "const_int_operand" "n"))))]
3726 "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode)
3727 && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0"
3728 {
3729 return rs6000_insn_for_insert_mask (<MODE>mode, operands, false);
3730 }
3731 [(set_attr "type" "insert")])
3732 ; FIXME: this needs an attr "size", so that the scheduler can see the
3733 ; difference between rlwimi and rldimi. We also might want dot forms,
3734 ; but not for rlwimi on POWER4 and similar processors.
3735
3736 (define_insn "*rotl<mode>3_insert_2"
3737 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3738 (ior:GPR (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0")
3739 (match_operand:GPR 6 "const_int_operand" "n"))
3740 (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3741 [(match_operand:GPR 1 "gpc_reg_operand" "r")
3742 (match_operand:SI 2 "const_int_operand" "n")])
3743 (match_operand:GPR 3 "const_int_operand" "n"))))]
3744 "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode)
3745 && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0"
3746 {
3747 return rs6000_insn_for_insert_mask (<MODE>mode, operands, false);
3748 }
3749 [(set_attr "type" "insert")])
3750
3751 ; There are also some forms without one of the ANDs.
3752 (define_insn "*rotl<mode>3_insert_3"
3753 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3754 (ior:GPR (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0")
3755 (match_operand:GPR 4 "const_int_operand" "n"))
3756 (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3757 (match_operand:SI 2 "const_int_operand" "n"))))]
3758 "INTVAL (operands[2]) == exact_log2 (UINTVAL (operands[4]) + 1)"
3759 {
3760 if (<MODE>mode == SImode)
3761 return "rlwimi %0,%1,%h2,0,31-%h2";
3762 else
3763 return "rldimi %0,%1,%H2,0";
3764 }
3765 [(set_attr "type" "insert")])
3766
3767 (define_insn "*rotl<mode>3_insert_4"
3768 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3769 (ior:GPR (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0")
3770 (match_operand:GPR 4 "const_int_operand" "n"))
3771 (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3772 (match_operand:SI 2 "const_int_operand" "n"))))]
3773 "<MODE>mode == SImode &&
3774 GET_MODE_PRECISION (<MODE>mode)
3775 == INTVAL (operands[2]) + exact_log2 (-UINTVAL (operands[4]))"
3776 {
3777 operands[2] = GEN_INT (GET_MODE_PRECISION (<MODE>mode)
3778 - INTVAL (operands[2]));
3779 if (<MODE>mode == SImode)
3780 return "rlwimi %0,%1,%h2,32-%h2,31";
3781 else
3782 return "rldimi %0,%1,%H2,64-%H2";
3783 }
3784 [(set_attr "type" "insert")])
3785
3786
3787 ; This handles the important case of multiple-precision shifts. There is
3788 ; no canonicalization rule for ASHIFT vs. LSHIFTRT, so two patterns.
3789 (define_split
3790 [(set (match_operand:GPR 0 "gpc_reg_operand")
3791 (ior:GPR (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand")
3792 (match_operand:SI 3 "const_int_operand"))
3793 (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand")
3794 (match_operand:SI 4 "const_int_operand"))))]
3795 "can_create_pseudo_p ()
3796 && INTVAL (operands[3]) + INTVAL (operands[4])
3797 >= GET_MODE_PRECISION (<MODE>mode)"
3798 [(set (match_dup 5)
3799 (lshiftrt:GPR (match_dup 2)
3800 (match_dup 4)))
3801 (set (match_dup 0)
3802 (ior:GPR (and:GPR (match_dup 5)
3803 (match_dup 6))
3804 (ashift:GPR (match_dup 1)
3805 (match_dup 3))))]
3806 {
3807 unsigned HOST_WIDE_INT mask = 1;
3808 mask = (mask << INTVAL (operands[3])) - 1;
3809 operands[5] = gen_reg_rtx (<MODE>mode);
3810 operands[6] = GEN_INT (mask);
3811 })
3812
3813 (define_split
3814 [(set (match_operand:GPR 0 "gpc_reg_operand")
3815 (ior:GPR (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand")
3816 (match_operand:SI 4 "const_int_operand"))
3817 (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand")
3818 (match_operand:SI 3 "const_int_operand"))))]
3819 "can_create_pseudo_p ()
3820 && INTVAL (operands[3]) + INTVAL (operands[4])
3821 >= GET_MODE_PRECISION (<MODE>mode)"
3822 [(set (match_dup 5)
3823 (lshiftrt:GPR (match_dup 2)
3824 (match_dup 4)))
3825 (set (match_dup 0)
3826 (ior:GPR (and:GPR (match_dup 5)
3827 (match_dup 6))
3828 (ashift:GPR (match_dup 1)
3829 (match_dup 3))))]
3830 {
3831 unsigned HOST_WIDE_INT mask = 1;
3832 mask = (mask << INTVAL (operands[3])) - 1;
3833 operands[5] = gen_reg_rtx (<MODE>mode);
3834 operands[6] = GEN_INT (mask);
3835 })
3836
3837
3838 ; Another important case is setting some bits to 1; we can do that with
3839 ; an insert instruction, in many cases.
3840 (define_insn_and_split "*ior<mode>_mask"
3841 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3842 (ior:GPR (match_operand:GPR 1 "gpc_reg_operand" "0")
3843 (match_operand:GPR 2 "const_int_operand" "n")))
3844 (clobber (match_scratch:GPR 3 "=r"))]
3845 "!logical_const_operand (operands[2], <MODE>mode)
3846 && rs6000_is_valid_mask (operands[2], NULL, NULL, <MODE>mode)"
3847 "#"
3848 "&& 1"
3849 [(set (match_dup 3)
3850 (const_int -1))
3851 (set (match_dup 0)
3852 (ior:GPR (and:GPR (rotate:GPR (match_dup 3)
3853 (match_dup 4))
3854 (match_dup 2))
3855 (and:GPR (match_dup 1)
3856 (match_dup 5))))]
3857 {
3858 int nb, ne;
3859 rs6000_is_valid_mask (operands[2], &nb, &ne, <MODE>mode);
3860 if (GET_CODE (operands[3]) == SCRATCH)
3861 operands[3] = gen_reg_rtx (<MODE>mode);
3862 operands[4] = GEN_INT (ne);
3863 operands[5] = GEN_INT (~UINTVAL (operands[2]));
3864 }
3865 [(set_attr "type" "two")
3866 (set_attr "length" "8")])
3867
3868
3869 ;; Now the simple shifts.
3870
3871 (define_insn "rotl<mode>3"
3872 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3873 (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3874 (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
3875 ""
3876 "rotl<wd>%I2 %0,%1,%<hH>2"
3877 [(set_attr "type" "shift")
3878 (set_attr "maybe_var_shift" "yes")])
3879
3880 (define_insn "*rotlsi3_64"
3881 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3882 (zero_extend:DI
3883 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
3884 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
3885 "TARGET_POWERPC64"
3886 "rotlw%I2 %0,%1,%h2"
3887 [(set_attr "type" "shift")
3888 (set_attr "maybe_var_shift" "yes")])
3889
3890 (define_insn_and_split "*rotl<mode>3_dot"
3891 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3892 (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3893 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
3894 (const_int 0)))
3895 (clobber (match_scratch:GPR 0 "=r,r"))]
3896 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3897 "@
3898 rotl<wd>%I2. %0,%1,%<hH>2
3899 #"
3900 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3901 [(set (match_dup 0)
3902 (rotate:GPR (match_dup 1)
3903 (match_dup 2)))
3904 (set (match_dup 3)
3905 (compare:CC (match_dup 0)
3906 (const_int 0)))]
3907 ""
3908 [(set_attr "type" "shift")
3909 (set_attr "maybe_var_shift" "yes")
3910 (set_attr "dot" "yes")
3911 (set_attr "length" "4,8")])
3912
3913 (define_insn_and_split "*rotl<mode>3_dot2"
3914 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3915 (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3916 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
3917 (const_int 0)))
3918 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3919 (rotate:GPR (match_dup 1)
3920 (match_dup 2)))]
3921 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3922 "@
3923 rotl<wd>%I2. %0,%1,%<hH>2
3924 #"
3925 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3926 [(set (match_dup 0)
3927 (rotate:GPR (match_dup 1)
3928 (match_dup 2)))
3929 (set (match_dup 3)
3930 (compare:CC (match_dup 0)
3931 (const_int 0)))]
3932 ""
3933 [(set_attr "type" "shift")
3934 (set_attr "maybe_var_shift" "yes")
3935 (set_attr "dot" "yes")
3936 (set_attr "length" "4,8")])
3937
3938
3939 (define_insn "ashl<mode>3"
3940 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3941 (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3942 (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
3943 ""
3944 "sl<wd>%I2 %0,%1,%<hH>2"
3945 [(set_attr "type" "shift")
3946 (set_attr "maybe_var_shift" "yes")])
3947
3948 (define_insn "*ashlsi3_64"
3949 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3950 (zero_extend:DI
3951 (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r")
3952 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
3953 "TARGET_POWERPC64"
3954 "slw%I2 %0,%1,%h2"
3955 [(set_attr "type" "shift")
3956 (set_attr "maybe_var_shift" "yes")])
3957
3958 (define_insn_and_split "*ashl<mode>3_dot"
3959 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3960 (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3961 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
3962 (const_int 0)))
3963 (clobber (match_scratch:GPR 0 "=r,r"))]
3964 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3965 "@
3966 sl<wd>%I2. %0,%1,%<hH>2
3967 #"
3968 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3969 [(set (match_dup 0)
3970 (ashift:GPR (match_dup 1)
3971 (match_dup 2)))
3972 (set (match_dup 3)
3973 (compare:CC (match_dup 0)
3974 (const_int 0)))]
3975 ""
3976 [(set_attr "type" "shift")
3977 (set_attr "maybe_var_shift" "yes")
3978 (set_attr "dot" "yes")
3979 (set_attr "length" "4,8")])
3980
3981 (define_insn_and_split "*ashl<mode>3_dot2"
3982 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3983 (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3984 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
3985 (const_int 0)))
3986 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3987 (ashift:GPR (match_dup 1)
3988 (match_dup 2)))]
3989 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3990 "@
3991 sl<wd>%I2. %0,%1,%<hH>2
3992 #"
3993 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3994 [(set (match_dup 0)
3995 (ashift:GPR (match_dup 1)
3996 (match_dup 2)))
3997 (set (match_dup 3)
3998 (compare:CC (match_dup 0)
3999 (const_int 0)))]
4000 ""
4001 [(set_attr "type" "shift")
4002 (set_attr "maybe_var_shift" "yes")
4003 (set_attr "dot" "yes")
4004 (set_attr "length" "4,8")])
4005
4006 ;; Pretend we have a memory form of extswsli until register allocation is done
4007 ;; so that we use LWZ to load the value from memory, instead of LWA.
4008 (define_insn_and_split "ashdi3_extswsli"
4009 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
4010 (ashift:DI
4011 (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,m"))
4012 (match_operand:DI 2 "u6bit_cint_operand" "n,n")))]
4013 "TARGET_EXTSWSLI"
4014 "@
4015 extswsli %0,%1,%2
4016 #"
4017 "&& reload_completed && MEM_P (operands[1])"
4018 [(set (match_dup 3)
4019 (match_dup 1))
4020 (set (match_dup 0)
4021 (ashift:DI (sign_extend:DI (match_dup 3))
4022 (match_dup 2)))]
4023 {
4024 operands[3] = gen_lowpart (SImode, operands[0]);
4025 }
4026 [(set_attr "type" "shift")
4027 (set_attr "maybe_var_shift" "no")])
4028
4029
4030 (define_insn_and_split "ashdi3_extswsli_dot"
4031 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y")
4032 (compare:CC
4033 (ashift:DI
4034 (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m"))
4035 (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n"))
4036 (const_int 0)))
4037 (clobber (match_scratch:DI 0 "=r,r,r,r"))]
4038 "TARGET_EXTSWSLI"
4039 "@
4040 extswsli. %0,%1,%2
4041 #
4042 #
4043 #"
4044 "&& reload_completed
4045 && (cc_reg_not_cr0_operand (operands[3], CCmode)
4046 || memory_operand (operands[1], SImode))"
4047 [(pc)]
4048 {
4049 rtx dest = operands[0];
4050 rtx src = operands[1];
4051 rtx shift = operands[2];
4052 rtx cr = operands[3];
4053 rtx src2;
4054
4055 if (!MEM_P (src))
4056 src2 = src;
4057 else
4058 {
4059 src2 = gen_lowpart (SImode, dest);
4060 emit_move_insn (src2, src);
4061 }
4062
4063 if (REGNO (cr) == CR0_REGNO)
4064 {
4065 emit_insn (gen_ashdi3_extswsli_dot (dest, src2, shift, cr));
4066 DONE;
4067 }
4068
4069 emit_insn (gen_ashdi3_extswsli (dest, src2, shift));
4070 emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx)));
4071 DONE;
4072 }
4073 [(set_attr "type" "shift")
4074 (set_attr "maybe_var_shift" "no")
4075 (set_attr "dot" "yes")
4076 (set_attr "length" "4,8,8,12")])
4077
4078 (define_insn_and_split "ashdi3_extswsli_dot2"
4079 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y")
4080 (compare:CC
4081 (ashift:DI
4082 (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m"))
4083 (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n"))
4084 (const_int 0)))
4085 (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r")
4086 (ashift:DI (sign_extend:DI (match_dup 1))
4087 (match_dup 2)))]
4088 "TARGET_EXTSWSLI"
4089 "@
4090 extswsli. %0,%1,%2
4091 #
4092 #
4093 #"
4094 "&& reload_completed
4095 && (cc_reg_not_cr0_operand (operands[3], CCmode)
4096 || memory_operand (operands[1], SImode))"
4097 [(pc)]
4098 {
4099 rtx dest = operands[0];
4100 rtx src = operands[1];
4101 rtx shift = operands[2];
4102 rtx cr = operands[3];
4103 rtx src2;
4104
4105 if (!MEM_P (src))
4106 src2 = src;
4107 else
4108 {
4109 src2 = gen_lowpart (SImode, dest);
4110 emit_move_insn (src2, src);
4111 }
4112
4113 if (REGNO (cr) == CR0_REGNO)
4114 {
4115 emit_insn (gen_ashdi3_extswsli_dot2 (dest, src2, shift, cr));
4116 DONE;
4117 }
4118
4119 emit_insn (gen_ashdi3_extswsli (dest, src2, shift));
4120 emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx)));
4121 DONE;
4122 }
4123 [(set_attr "type" "shift")
4124 (set_attr "maybe_var_shift" "no")
4125 (set_attr "dot" "yes")
4126 (set_attr "length" "4,8,8,12")])
4127
4128 (define_insn "lshr<mode>3"
4129 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4130 (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4131 (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4132 ""
4133 "sr<wd>%I2 %0,%1,%<hH>2"
4134 [(set_attr "type" "shift")
4135 (set_attr "maybe_var_shift" "yes")])
4136
4137 (define_insn "*lshrsi3_64"
4138 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4139 (zero_extend:DI
4140 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4141 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4142 "TARGET_POWERPC64"
4143 "srw%I2 %0,%1,%h2"
4144 [(set_attr "type" "shift")
4145 (set_attr "maybe_var_shift" "yes")])
4146
4147 (define_insn_and_split "*lshr<mode>3_dot"
4148 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4149 (compare:CC (lshiftrt: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 (clobber (match_scratch:GPR 0 "=r,r"))]
4153 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4154 "@
4155 sr<wd>%I2. %0,%1,%<hH>2
4156 #"
4157 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4158 [(set (match_dup 0)
4159 (lshiftrt:GPR (match_dup 1)
4160 (match_dup 2)))
4161 (set (match_dup 3)
4162 (compare:CC (match_dup 0)
4163 (const_int 0)))]
4164 ""
4165 [(set_attr "type" "shift")
4166 (set_attr "maybe_var_shift" "yes")
4167 (set_attr "dot" "yes")
4168 (set_attr "length" "4,8")])
4169
4170 (define_insn_and_split "*lshr<mode>3_dot2"
4171 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4172 (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4173 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4174 (const_int 0)))
4175 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4176 (lshiftrt:GPR (match_dup 1)
4177 (match_dup 2)))]
4178 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4179 "@
4180 sr<wd>%I2. %0,%1,%<hH>2
4181 #"
4182 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4183 [(set (match_dup 0)
4184 (lshiftrt:GPR (match_dup 1)
4185 (match_dup 2)))
4186 (set (match_dup 3)
4187 (compare:CC (match_dup 0)
4188 (const_int 0)))]
4189 ""
4190 [(set_attr "type" "shift")
4191 (set_attr "maybe_var_shift" "yes")
4192 (set_attr "dot" "yes")
4193 (set_attr "length" "4,8")])
4194
4195
4196 (define_insn "ashr<mode>3"
4197 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4198 (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4199 (match_operand:SI 2 "reg_or_cint_operand" "rn")))
4200 (clobber (reg:GPR CA_REGNO))]
4201 ""
4202 "sra<wd>%I2 %0,%1,%<hH>2"
4203 [(set_attr "type" "shift")
4204 (set_attr "maybe_var_shift" "yes")])
4205
4206 (define_insn "*ashrsi3_64"
4207 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4208 (sign_extend:DI
4209 (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4210 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))
4211 (clobber (reg:SI CA_REGNO))]
4212 "TARGET_POWERPC64"
4213 "sraw%I2 %0,%1,%h2"
4214 [(set_attr "type" "shift")
4215 (set_attr "maybe_var_shift" "yes")])
4216
4217 (define_insn_and_split "*ashr<mode>3_dot"
4218 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4219 (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4220 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4221 (const_int 0)))
4222 (clobber (match_scratch:GPR 0 "=r,r"))
4223 (clobber (reg:GPR CA_REGNO))]
4224 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4225 "@
4226 sra<wd>%I2. %0,%1,%<hH>2
4227 #"
4228 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4229 [(parallel [(set (match_dup 0)
4230 (ashiftrt:GPR (match_dup 1)
4231 (match_dup 2)))
4232 (clobber (reg:GPR CA_REGNO))])
4233 (set (match_dup 3)
4234 (compare:CC (match_dup 0)
4235 (const_int 0)))]
4236 ""
4237 [(set_attr "type" "shift")
4238 (set_attr "maybe_var_shift" "yes")
4239 (set_attr "dot" "yes")
4240 (set_attr "length" "4,8")])
4241
4242 (define_insn_and_split "*ashr<mode>3_dot2"
4243 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4244 (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4245 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4246 (const_int 0)))
4247 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4248 (ashiftrt:GPR (match_dup 1)
4249 (match_dup 2)))
4250 (clobber (reg:GPR CA_REGNO))]
4251 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4252 "@
4253 sra<wd>%I2. %0,%1,%<hH>2
4254 #"
4255 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4256 [(parallel [(set (match_dup 0)
4257 (ashiftrt:GPR (match_dup 1)
4258 (match_dup 2)))
4259 (clobber (reg:GPR CA_REGNO))])
4260 (set (match_dup 3)
4261 (compare:CC (match_dup 0)
4262 (const_int 0)))]
4263 ""
4264 [(set_attr "type" "shift")
4265 (set_attr "maybe_var_shift" "yes")
4266 (set_attr "dot" "yes")
4267 (set_attr "length" "4,8")])
4268 \f
4269 ;; Builtins to replace a division to generate FRE reciprocal estimate
4270 ;; instructions and the necessary fixup instructions
4271 (define_expand "recip<mode>3"
4272 [(match_operand:RECIPF 0 "gpc_reg_operand" "")
4273 (match_operand:RECIPF 1 "gpc_reg_operand" "")
4274 (match_operand:RECIPF 2 "gpc_reg_operand" "")]
4275 "RS6000_RECIP_HAVE_RE_P (<MODE>mode)"
4276 {
4277 rs6000_emit_swdiv (operands[0], operands[1], operands[2], false);
4278 DONE;
4279 })
4280
4281 ;; Split to create division from FRE/FRES/etc. and fixup instead of the normal
4282 ;; hardware division. This is only done before register allocation and with
4283 ;; -ffast-math. This must appear before the divsf3/divdf3 insns.
4284 (define_split
4285 [(set (match_operand:RECIPF 0 "gpc_reg_operand" "")
4286 (div:RECIPF (match_operand 1 "gpc_reg_operand" "")
4287 (match_operand 2 "gpc_reg_operand" "")))]
4288 "RS6000_RECIP_AUTO_RE_P (<MODE>mode)
4289 && can_create_pseudo_p () && optimize_insn_for_speed_p ()
4290 && flag_finite_math_only && !flag_trapping_math && flag_reciprocal_math"
4291 [(const_int 0)]
4292 {
4293 rs6000_emit_swdiv (operands[0], operands[1], operands[2], true);
4294 DONE;
4295 })
4296
4297 ;; Builtins to replace 1/sqrt(x) with instructions using RSQRTE and the
4298 ;; appropriate fixup.
4299 (define_expand "rsqrt<mode>2"
4300 [(match_operand:RECIPF 0 "gpc_reg_operand" "")
4301 (match_operand:RECIPF 1 "gpc_reg_operand" "")]
4302 "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4303 {
4304 rs6000_emit_swrsqrt (operands[0], operands[1]);
4305 DONE;
4306 })
4307 \f
4308 ;; Floating-point insns, excluding normal data motion. We combine the SF/DF
4309 ;; modes here, and also add in conditional vsx/power8-vector support to access
4310 ;; values in the traditional Altivec registers if the appropriate
4311 ;; -mupper-regs-{df,sf} option is enabled.
4312
4313 (define_expand "abs<mode>2"
4314 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4315 (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))]
4316 "TARGET_<MODE>_INSN"
4317 "")
4318
4319 (define_insn "*abs<mode>2_fpr"
4320 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4321 (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4322 "TARGET_<MODE>_FPR"
4323 "@
4324 fabs %0,%1
4325 xsabsdp %x0,%x1"
4326 [(set_attr "type" "fp")
4327 (set_attr "fp_type" "fp_addsub_<Fs>")])
4328
4329 (define_insn "*nabs<mode>2_fpr"
4330 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4331 (neg:SFDF
4332 (abs:SFDF
4333 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))))]
4334 "TARGET_<MODE>_FPR"
4335 "@
4336 fnabs %0,%1
4337 xsnabsdp %x0,%x1"
4338 [(set_attr "type" "fp")
4339 (set_attr "fp_type" "fp_addsub_<Fs>")])
4340
4341 (define_expand "neg<mode>2"
4342 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4343 (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))]
4344 "TARGET_<MODE>_INSN"
4345 "")
4346
4347 (define_insn "*neg<mode>2_fpr"
4348 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4349 (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4350 "TARGET_<MODE>_FPR"
4351 "@
4352 fneg %0,%1
4353 xsnegdp %x0,%x1"
4354 [(set_attr "type" "fp")
4355 (set_attr "fp_type" "fp_addsub_<Fs>")])
4356
4357 (define_expand "add<mode>3"
4358 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4359 (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4360 (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4361 "TARGET_<MODE>_INSN"
4362 "")
4363
4364 (define_insn "*add<mode>3_fpr"
4365 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4366 (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>")
4367 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4368 "TARGET_<MODE>_FPR"
4369 "@
4370 fadd<Ftrad> %0,%1,%2
4371 xsadd<Fvsx> %x0,%x1,%x2"
4372 [(set_attr "type" "fp")
4373 (set_attr "fp_type" "fp_addsub_<Fs>")])
4374
4375 (define_expand "sub<mode>3"
4376 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4377 (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4378 (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4379 "TARGET_<MODE>_INSN"
4380 "")
4381
4382 (define_insn "*sub<mode>3_fpr"
4383 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4384 (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4385 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4386 "TARGET_<MODE>_FPR"
4387 "@
4388 fsub<Ftrad> %0,%1,%2
4389 xssub<Fvsx> %x0,%x1,%x2"
4390 [(set_attr "type" "fp")
4391 (set_attr "fp_type" "fp_addsub_<Fs>")])
4392
4393 (define_expand "mul<mode>3"
4394 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4395 (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4396 (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4397 "TARGET_<MODE>_INSN"
4398 "")
4399
4400 (define_insn "*mul<mode>3_fpr"
4401 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4402 (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>")
4403 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4404 "TARGET_<MODE>_FPR"
4405 "@
4406 fmul<Ftrad> %0,%1,%2
4407 xsmul<Fvsx> %x0,%x1,%x2"
4408 [(set_attr "type" "dmul")
4409 (set_attr "fp_type" "fp_mul_<Fs>")])
4410
4411 (define_expand "div<mode>3"
4412 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4413 (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4414 (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4415 "TARGET_<MODE>_INSN && !TARGET_SIMPLE_FPU"
4416 "")
4417
4418 (define_insn "*div<mode>3_fpr"
4419 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4420 (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4421 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4422 "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU"
4423 "@
4424 fdiv<Ftrad> %0,%1,%2
4425 xsdiv<Fvsx> %x0,%x1,%x2"
4426 [(set_attr "type" "<Fs>div")
4427 (set_attr "fp_type" "fp_div_<Fs>")])
4428
4429 (define_insn "sqrt<mode>2"
4430 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4431 (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4432 "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU
4433 && (TARGET_PPC_GPOPT || (<MODE>mode == SFmode && TARGET_XILINX_FPU))"
4434 "@
4435 fsqrt<Ftrad> %0,%1
4436 xssqrt<Fvsx> %x0,%x1"
4437 [(set_attr "type" "<Fs>sqrt")
4438 (set_attr "fp_type" "fp_sqrt_<Fs>")])
4439
4440 ;; Floating point reciprocal approximation
4441 (define_insn "fre<Fs>"
4442 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4443 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")]
4444 UNSPEC_FRES))]
4445 "TARGET_<FFRE>"
4446 "@
4447 fre<Ftrad> %0,%1
4448 xsre<Fvsx> %x0,%x1"
4449 [(set_attr "type" "fp")])
4450
4451 (define_insn "*rsqrt<mode>2"
4452 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4453 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")]
4454 UNSPEC_RSQRT))]
4455 "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4456 "@
4457 frsqrte<Ftrad> %0,%1
4458 xsrsqrte<Fvsx> %x0,%x1"
4459 [(set_attr "type" "fp")])
4460
4461 ;; Floating point comparisons
4462 (define_insn "*cmp<mode>_fpr"
4463 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y,y")
4464 (compare:CCFP (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4465 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4466 "TARGET_<MODE>_FPR"
4467 "@
4468 fcmpu %0,%1,%2
4469 xscmpudp %0,%x1,%x2"
4470 [(set_attr "type" "fpcompare")])
4471
4472 ;; Floating point conversions
4473 (define_expand "extendsfdf2"
4474 [(set (match_operand:DF 0 "gpc_reg_operand" "")
4475 (float_extend:DF (match_operand:SF 1 "reg_or_none500mem_operand" "")))]
4476 "TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
4477 "")
4478
4479 (define_insn_and_split "*extendsfdf2_fpr"
4480 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d,d,ws,?ws,wu,wb")
4481 (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand" "0,f,m,0,wy,Z,o")))]
4482 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
4483 "@
4484 #
4485 fmr %0,%1
4486 lfs%U1%X1 %0,%1
4487 #
4488 xscpsgndp %x0,%x1,%x1
4489 lxsspx %x0,%y1
4490 lxssp %0,%1"
4491 "&& reload_completed && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1])"
4492 [(const_int 0)]
4493 {
4494 emit_note (NOTE_INSN_DELETED);
4495 DONE;
4496 }
4497 [(set_attr "type" "fp,fp,fpload,fp,fp,fpload,fpload")])
4498
4499 (define_expand "truncdfsf2"
4500 [(set (match_operand:SF 0 "gpc_reg_operand" "")
4501 (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "")))]
4502 "TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
4503 "")
4504
4505 (define_insn "*truncdfsf2_fpr"
4506 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy")
4507 (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "d,ws")))]
4508 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
4509 "@
4510 frsp %0,%1
4511 xsrsp %x0,%x1"
4512 [(set_attr "type" "fp")])
4513
4514 ;; This expander is here to avoid FLOAT_WORDS_BIGENDIAN tests in
4515 ;; builtins.c and optabs.c that are not correct for IBM long double
4516 ;; when little-endian.
4517 (define_expand "signbit<mode>2"
4518 [(set (match_dup 2)
4519 (float_truncate:DF (match_operand:IBM128 1 "gpc_reg_operand" "")))
4520 (set (match_dup 3)
4521 (subreg:DI (match_dup 2) 0))
4522 (set (match_dup 4)
4523 (match_dup 5))
4524 (set (match_operand:SI 0 "gpc_reg_operand" "")
4525 (match_dup 6))]
4526 "TARGET_HARD_FLOAT
4527 && (TARGET_FPRS || TARGET_E500_DOUBLE)"
4528 {
4529 operands[2] = gen_reg_rtx (DFmode);
4530 operands[3] = gen_reg_rtx (DImode);
4531 if (TARGET_POWERPC64)
4532 {
4533 operands[4] = gen_reg_rtx (DImode);
4534 operands[5] = gen_rtx_LSHIFTRT (DImode, operands[3], GEN_INT (63));
4535 operands[6] = gen_rtx_SUBREG (SImode, operands[4],
4536 WORDS_BIG_ENDIAN ? 4 : 0);
4537 }
4538 else
4539 {
4540 operands[4] = gen_reg_rtx (SImode);
4541 operands[5] = gen_rtx_SUBREG (SImode, operands[3],
4542 WORDS_BIG_ENDIAN ? 0 : 4);
4543 operands[6] = gen_rtx_LSHIFTRT (SImode, operands[4], GEN_INT (31));
4544 }
4545 })
4546
4547 (define_expand "copysign<mode>3"
4548 [(set (match_dup 3)
4549 (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))
4550 (set (match_dup 4)
4551 (neg:SFDF (abs:SFDF (match_dup 1))))
4552 (set (match_operand:SFDF 0 "gpc_reg_operand" "")
4553 (if_then_else:SFDF (ge (match_operand:SFDF 2 "gpc_reg_operand" "")
4554 (match_dup 5))
4555 (match_dup 3)
4556 (match_dup 4)))]
4557 "TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT>
4558 && ((TARGET_PPC_GFXOPT
4559 && !HONOR_NANS (<MODE>mode)
4560 && !HONOR_SIGNED_ZEROS (<MODE>mode))
4561 || TARGET_CMPB
4562 || VECTOR_UNIT_VSX_P (<MODE>mode))"
4563 {
4564 if (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode))
4565 {
4566 emit_insn (gen_copysign<mode>3_fcpsgn (operands[0], operands[1],
4567 operands[2]));
4568 DONE;
4569 }
4570
4571 operands[3] = gen_reg_rtx (<MODE>mode);
4572 operands[4] = gen_reg_rtx (<MODE>mode);
4573 operands[5] = CONST0_RTX (<MODE>mode);
4574 })
4575
4576 ;; Use an unspec rather providing an if-then-else in RTL, to prevent the
4577 ;; compiler from optimizing -0.0
4578 (define_insn "copysign<mode>3_fcpsgn"
4579 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4580 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")
4581 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")]
4582 UNSPEC_COPYSIGN))]
4583 "TARGET_<MODE>_FPR && TARGET_CMPB"
4584 "@
4585 fcpsgn %0,%2,%1
4586 xscpsgndp %x0,%x2,%x1"
4587 [(set_attr "type" "fp")])
4588
4589 ;; For MIN, MAX, and conditional move, we use DEFINE_EXPAND's that involve a
4590 ;; fsel instruction and some auxiliary computations. Then we just have a
4591 ;; single DEFINE_INSN for fsel and the define_splits to make them if made by
4592 ;; combine.
4593 ;; For MIN, MAX on non-VSX machines, and conditional move all of the time, we
4594 ;; use DEFINE_EXPAND's that involve a fsel instruction and some auxiliary
4595 ;; computations. Then we just have a single DEFINE_INSN for fsel and the
4596 ;; define_splits to make them if made by combine. On VSX machines we have the
4597 ;; min/max instructions.
4598 ;;
4599 ;; On VSX, we only check for TARGET_VSX instead of checking for a vsx/p8 vector
4600 ;; to allow either DF/SF to use only traditional registers.
4601
4602 (define_expand "smax<mode>3"
4603 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4604 (if_then_else:SFDF (ge (match_operand:SFDF 1 "gpc_reg_operand" "")
4605 (match_operand:SFDF 2 "gpc_reg_operand" ""))
4606 (match_dup 1)
4607 (match_dup 2)))]
4608 "TARGET_<MODE>_FPR && TARGET_PPC_GFXOPT && !flag_trapping_math"
4609 {
4610 rs6000_emit_minmax (operands[0], SMAX, operands[1], operands[2]);
4611 DONE;
4612 })
4613
4614 (define_insn "*smax<mode>3_vsx"
4615 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4616 (smax:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv>")
4617 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")))]
4618 "TARGET_<MODE>_FPR && TARGET_VSX"
4619 "xsmaxdp %x0,%x1,%x2"
4620 [(set_attr "type" "fp")])
4621
4622 (define_expand "smin<mode>3"
4623 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4624 (if_then_else:SFDF (ge (match_operand:SFDF 1 "gpc_reg_operand" "")
4625 (match_operand:SFDF 2 "gpc_reg_operand" ""))
4626 (match_dup 2)
4627 (match_dup 1)))]
4628 "TARGET_<MODE>_FPR && TARGET_PPC_GFXOPT && !flag_trapping_math"
4629 {
4630 rs6000_emit_minmax (operands[0], SMIN, operands[1], operands[2]);
4631 DONE;
4632 })
4633
4634 (define_insn "*smin<mode>3_vsx"
4635 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4636 (smin:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv>")
4637 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")))]
4638 "TARGET_<MODE>_FPR && TARGET_VSX"
4639 "xsmindp %x0,%x1,%x2"
4640 [(set_attr "type" "fp")])
4641
4642 (define_split
4643 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4644 (match_operator:SFDF 3 "min_max_operator"
4645 [(match_operand:SFDF 1 "gpc_reg_operand" "")
4646 (match_operand:SFDF 2 "gpc_reg_operand" "")]))]
4647 "TARGET_<MODE>_FPR && TARGET_PPC_GFXOPT && !flag_trapping_math
4648 && !TARGET_VSX"
4649 [(const_int 0)]
4650 {
4651 rs6000_emit_minmax (operands[0], GET_CODE (operands[3]), operands[1],
4652 operands[2]);
4653 DONE;
4654 })
4655
4656 (define_split
4657 [(set (match_operand:SF 0 "gpc_reg_operand" "")
4658 (match_operator:SF 3 "min_max_operator"
4659 [(match_operand:SF 1 "gpc_reg_operand" "")
4660 (match_operand:SF 2 "gpc_reg_operand" "")]))]
4661 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS
4662 && TARGET_SINGLE_FLOAT && !flag_trapping_math"
4663 [(const_int 0)]
4664 "
4665 { rs6000_emit_minmax (operands[0], GET_CODE (operands[3]),
4666 operands[1], operands[2]);
4667 DONE;
4668 }")
4669
4670 (define_expand "mov<mode>cc"
4671 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
4672 (if_then_else:GPR (match_operand 1 "comparison_operator" "")
4673 (match_operand:GPR 2 "gpc_reg_operand" "")
4674 (match_operand:GPR 3 "gpc_reg_operand" "")))]
4675 "TARGET_ISEL<sel>"
4676 "
4677 {
4678 if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
4679 DONE;
4680 else
4681 FAIL;
4682 }")
4683
4684 ;; We use the BASE_REGS for the isel input operands because, if rA is
4685 ;; 0, the value of 0 is placed in rD upon truth. Similarly for rB
4686 ;; because we may switch the operands and rB may end up being rA.
4687 ;;
4688 ;; We need 2 patterns: an unsigned and a signed pattern. We could
4689 ;; leave out the mode in operand 4 and use one pattern, but reload can
4690 ;; change the mode underneath our feet and then gets confused trying
4691 ;; to reload the value.
4692 (define_insn "isel_signed_<mode>"
4693 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4694 (if_then_else:GPR
4695 (match_operator 1 "scc_comparison_operator"
4696 [(match_operand:CC 4 "cc_reg_operand" "y,y")
4697 (const_int 0)])
4698 (match_operand:GPR 2 "reg_or_cint_operand" "O,b")
4699 (match_operand:GPR 3 "gpc_reg_operand" "r,r")))]
4700 "TARGET_ISEL<sel>"
4701 "*
4702 { return output_isel (operands); }"
4703 [(set_attr "type" "isel")
4704 (set_attr "length" "4")])
4705
4706 (define_insn "isel_unsigned_<mode>"
4707 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4708 (if_then_else:GPR
4709 (match_operator 1 "scc_comparison_operator"
4710 [(match_operand:CCUNS 4 "cc_reg_operand" "y,y")
4711 (const_int 0)])
4712 (match_operand:GPR 2 "reg_or_cint_operand" "O,b")
4713 (match_operand:GPR 3 "gpc_reg_operand" "r,r")))]
4714 "TARGET_ISEL<sel>"
4715 "*
4716 { return output_isel (operands); }"
4717 [(set_attr "type" "isel")
4718 (set_attr "length" "4")])
4719
4720 ;; These patterns can be useful for combine; they let combine know that
4721 ;; isel can handle reversed comparisons so long as the operands are
4722 ;; registers.
4723
4724 (define_insn "*isel_reversed_signed_<mode>"
4725 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4726 (if_then_else:GPR
4727 (match_operator 1 "scc_rev_comparison_operator"
4728 [(match_operand:CC 4 "cc_reg_operand" "y")
4729 (const_int 0)])
4730 (match_operand:GPR 2 "gpc_reg_operand" "b")
4731 (match_operand:GPR 3 "gpc_reg_operand" "b")))]
4732 "TARGET_ISEL<sel>"
4733 "*
4734 { return output_isel (operands); }"
4735 [(set_attr "type" "isel")
4736 (set_attr "length" "4")])
4737
4738 (define_insn "*isel_reversed_unsigned_<mode>"
4739 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4740 (if_then_else:GPR
4741 (match_operator 1 "scc_rev_comparison_operator"
4742 [(match_operand:CCUNS 4 "cc_reg_operand" "y")
4743 (const_int 0)])
4744 (match_operand:GPR 2 "gpc_reg_operand" "b")
4745 (match_operand:GPR 3 "gpc_reg_operand" "b")))]
4746 "TARGET_ISEL<sel>"
4747 "*
4748 { return output_isel (operands); }"
4749 [(set_attr "type" "isel")
4750 (set_attr "length" "4")])
4751
4752 (define_expand "movsfcc"
4753 [(set (match_operand:SF 0 "gpc_reg_operand" "")
4754 (if_then_else:SF (match_operand 1 "comparison_operator" "")
4755 (match_operand:SF 2 "gpc_reg_operand" "")
4756 (match_operand:SF 3 "gpc_reg_operand" "")))]
4757 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT"
4758 "
4759 {
4760 if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
4761 DONE;
4762 else
4763 FAIL;
4764 }")
4765
4766 (define_insn "*fselsfsf4"
4767 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
4768 (if_then_else:SF (ge (match_operand:SF 1 "gpc_reg_operand" "f")
4769 (match_operand:SF 4 "zero_fp_constant" "F"))
4770 (match_operand:SF 2 "gpc_reg_operand" "f")
4771 (match_operand:SF 3 "gpc_reg_operand" "f")))]
4772 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT"
4773 "fsel %0,%1,%2,%3"
4774 [(set_attr "type" "fp")])
4775
4776 (define_insn "*fseldfsf4"
4777 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
4778 (if_then_else:SF (ge (match_operand:DF 1 "gpc_reg_operand" "d")
4779 (match_operand:DF 4 "zero_fp_constant" "F"))
4780 (match_operand:SF 2 "gpc_reg_operand" "f")
4781 (match_operand:SF 3 "gpc_reg_operand" "f")))]
4782 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_SINGLE_FLOAT"
4783 "fsel %0,%1,%2,%3"
4784 [(set_attr "type" "fp")])
4785
4786 ;; The conditional move instructions allow us to perform max and min
4787 ;; operations even when
4788
4789 (define_split
4790 [(set (match_operand:DF 0 "gpc_reg_operand" "")
4791 (match_operator:DF 3 "min_max_operator"
4792 [(match_operand:DF 1 "gpc_reg_operand" "")
4793 (match_operand:DF 2 "gpc_reg_operand" "")]))]
4794 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
4795 && !flag_trapping_math"
4796 [(const_int 0)]
4797 "
4798 { rs6000_emit_minmax (operands[0], GET_CODE (operands[3]),
4799 operands[1], operands[2]);
4800 DONE;
4801 }")
4802
4803 (define_expand "movdfcc"
4804 [(set (match_operand:DF 0 "gpc_reg_operand" "")
4805 (if_then_else:DF (match_operand 1 "comparison_operator" "")
4806 (match_operand:DF 2 "gpc_reg_operand" "")
4807 (match_operand:DF 3 "gpc_reg_operand" "")))]
4808 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
4809 "
4810 {
4811 if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
4812 DONE;
4813 else
4814 FAIL;
4815 }")
4816
4817 (define_insn "*fseldfdf4"
4818 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
4819 (if_then_else:DF (ge (match_operand:DF 1 "gpc_reg_operand" "d")
4820 (match_operand:DF 4 "zero_fp_constant" "F"))
4821 (match_operand:DF 2 "gpc_reg_operand" "d")
4822 (match_operand:DF 3 "gpc_reg_operand" "d")))]
4823 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
4824 "fsel %0,%1,%2,%3"
4825 [(set_attr "type" "fp")])
4826
4827 (define_insn "*fselsfdf4"
4828 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
4829 (if_then_else:DF (ge (match_operand:SF 1 "gpc_reg_operand" "f")
4830 (match_operand:SF 4 "zero_fp_constant" "F"))
4831 (match_operand:DF 2 "gpc_reg_operand" "d")
4832 (match_operand:DF 3 "gpc_reg_operand" "d")))]
4833 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_SINGLE_FLOAT"
4834 "fsel %0,%1,%2,%3"
4835 [(set_attr "type" "fp")])
4836 \f
4837 ;; Conversions to and from floating-point.
4838
4839 ; We don't define lfiwax/lfiwzx with the normal definition, because we
4840 ; don't want to support putting SImode in FPR registers.
4841 (define_insn "lfiwax"
4842 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wj,!wj")
4843 (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r")]
4844 UNSPEC_LFIWAX))]
4845 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX"
4846 "@
4847 lfiwax %0,%y1
4848 lxsiwax %x0,%y1
4849 mtvsrwa %x0,%1"
4850 [(set_attr "type" "fpload,fpload,mffgpr")])
4851
4852 ; This split must be run before register allocation because it allocates the
4853 ; memory slot that is needed to move values to/from the FPR. We don't allocate
4854 ; it earlier to allow for the combiner to merge insns together where it might
4855 ; not be needed and also in case the insns are deleted as dead code.
4856
4857 (define_insn_and_split "floatsi<mode>2_lfiwax"
4858 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
4859 (float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r")))
4860 (clobber (match_scratch:DI 2 "=wj"))]
4861 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX
4862 && <SI_CONVERT_FP> && can_create_pseudo_p ()"
4863 "#"
4864 ""
4865 [(pc)]
4866 "
4867 {
4868 rtx dest = operands[0];
4869 rtx src = operands[1];
4870 rtx tmp;
4871
4872 if (!MEM_P (src) && TARGET_POWERPC64
4873 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
4874 tmp = convert_to_mode (DImode, src, false);
4875 else
4876 {
4877 tmp = operands[2];
4878 if (GET_CODE (tmp) == SCRATCH)
4879 tmp = gen_reg_rtx (DImode);
4880 if (MEM_P (src))
4881 {
4882 src = rs6000_address_for_fpconvert (src);
4883 emit_insn (gen_lfiwax (tmp, src));
4884 }
4885 else
4886 {
4887 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
4888 emit_move_insn (stack, src);
4889 emit_insn (gen_lfiwax (tmp, stack));
4890 }
4891 }
4892 emit_insn (gen_floatdi<mode>2 (dest, tmp));
4893 DONE;
4894 }"
4895 [(set_attr "length" "12")
4896 (set_attr "type" "fpload")])
4897
4898 (define_insn_and_split "floatsi<mode>2_lfiwax_mem"
4899 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fa>")
4900 (float:SFDF
4901 (sign_extend:DI
4902 (match_operand:SI 1 "indexed_or_indirect_operand" "Z,Z"))))
4903 (clobber (match_scratch:DI 2 "=0,d"))]
4904 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX
4905 && <SI_CONVERT_FP>"
4906 "#"
4907 ""
4908 [(pc)]
4909 "
4910 {
4911 operands[1] = rs6000_address_for_fpconvert (operands[1]);
4912 if (GET_CODE (operands[2]) == SCRATCH)
4913 operands[2] = gen_reg_rtx (DImode);
4914 emit_insn (gen_lfiwax (operands[2], operands[1]));
4915 emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
4916 DONE;
4917 }"
4918 [(set_attr "length" "8")
4919 (set_attr "type" "fpload")])
4920
4921 (define_insn "lfiwzx"
4922 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wj,!wj")
4923 (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r")]
4924 UNSPEC_LFIWZX))]
4925 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX"
4926 "@
4927 lfiwzx %0,%y1
4928 lxsiwzx %x0,%y1
4929 mtvsrwz %x0,%1"
4930 [(set_attr "type" "fpload,fpload,mftgpr")])
4931
4932 (define_insn_and_split "floatunssi<mode>2_lfiwzx"
4933 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
4934 (unsigned_float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r")))
4935 (clobber (match_scratch:DI 2 "=wj"))]
4936 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX
4937 && <SI_CONVERT_FP>"
4938 "#"
4939 ""
4940 [(pc)]
4941 "
4942 {
4943 rtx dest = operands[0];
4944 rtx src = operands[1];
4945 rtx tmp;
4946
4947 if (!MEM_P (src) && TARGET_POWERPC64
4948 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
4949 tmp = convert_to_mode (DImode, src, true);
4950 else
4951 {
4952 tmp = operands[2];
4953 if (GET_CODE (tmp) == SCRATCH)
4954 tmp = gen_reg_rtx (DImode);
4955 if (MEM_P (src))
4956 {
4957 src = rs6000_address_for_fpconvert (src);
4958 emit_insn (gen_lfiwzx (tmp, src));
4959 }
4960 else
4961 {
4962 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
4963 emit_move_insn (stack, src);
4964 emit_insn (gen_lfiwzx (tmp, stack));
4965 }
4966 }
4967 emit_insn (gen_floatdi<mode>2 (dest, tmp));
4968 DONE;
4969 }"
4970 [(set_attr "length" "12")
4971 (set_attr "type" "fpload")])
4972
4973 (define_insn_and_split "floatunssi<mode>2_lfiwzx_mem"
4974 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fa>")
4975 (unsigned_float:SFDF
4976 (zero_extend:DI
4977 (match_operand:SI 1 "indexed_or_indirect_operand" "Z,Z"))))
4978 (clobber (match_scratch:DI 2 "=0,d"))]
4979 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX
4980 && <SI_CONVERT_FP>"
4981 "#"
4982 ""
4983 [(pc)]
4984 "
4985 {
4986 operands[1] = rs6000_address_for_fpconvert (operands[1]);
4987 if (GET_CODE (operands[2]) == SCRATCH)
4988 operands[2] = gen_reg_rtx (DImode);
4989 emit_insn (gen_lfiwzx (operands[2], operands[1]));
4990 emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
4991 DONE;
4992 }"
4993 [(set_attr "length" "8")
4994 (set_attr "type" "fpload")])
4995
4996 ; For each of these conversions, there is a define_expand, a define_insn
4997 ; with a '#' template, and a define_split (with C code). The idea is
4998 ; to allow constant folding with the template of the define_insn,
4999 ; then to have the insns split later (between sched1 and final).
5000
5001 (define_expand "floatsidf2"
5002 [(parallel [(set (match_operand:DF 0 "gpc_reg_operand" "")
5003 (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))
5004 (use (match_dup 2))
5005 (use (match_dup 3))
5006 (clobber (match_dup 4))
5007 (clobber (match_dup 5))
5008 (clobber (match_dup 6))])]
5009 "TARGET_HARD_FLOAT
5010 && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
5011 "
5012 {
5013 if (TARGET_E500_DOUBLE)
5014 {
5015 if (!REG_P (operands[1]))
5016 operands[1] = force_reg (SImode, operands[1]);
5017 emit_insn (gen_spe_floatsidf2 (operands[0], operands[1]));
5018 DONE;
5019 }
5020 else if (TARGET_LFIWAX && TARGET_FCFID)
5021 {
5022 emit_insn (gen_floatsidf2_lfiwax (operands[0], operands[1]));
5023 DONE;
5024 }
5025 else if (TARGET_FCFID)
5026 {
5027 rtx dreg = operands[1];
5028 if (!REG_P (dreg))
5029 dreg = force_reg (SImode, dreg);
5030 dreg = convert_to_mode (DImode, dreg, false);
5031 emit_insn (gen_floatdidf2 (operands[0], dreg));
5032 DONE;
5033 }
5034
5035 if (!REG_P (operands[1]))
5036 operands[1] = force_reg (SImode, operands[1]);
5037 operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5038 operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503601774854144\", DFmode));
5039 operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5040 operands[5] = gen_reg_rtx (DFmode);
5041 operands[6] = gen_reg_rtx (SImode);
5042 }")
5043
5044 (define_insn_and_split "*floatsidf2_internal"
5045 [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5046 (float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5047 (use (match_operand:SI 2 "gpc_reg_operand" "r"))
5048 (use (match_operand:DF 3 "gpc_reg_operand" "d"))
5049 (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
5050 (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))
5051 (clobber (match_operand:SI 6 "gpc_reg_operand" "=&r"))]
5052 "! TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
5053 "#"
5054 ""
5055 [(pc)]
5056 "
5057 {
5058 rtx lowword, highword;
5059 gcc_assert (MEM_P (operands[4]));
5060 highword = adjust_address (operands[4], SImode, 0);
5061 lowword = adjust_address (operands[4], SImode, 4);
5062 if (! WORDS_BIG_ENDIAN)
5063 std::swap (lowword, highword);
5064
5065 emit_insn (gen_xorsi3 (operands[6], operands[1],
5066 GEN_INT (~ (HOST_WIDE_INT) 0x7fffffff)));
5067 emit_move_insn (lowword, operands[6]);
5068 emit_move_insn (highword, operands[2]);
5069 emit_move_insn (operands[5], operands[4]);
5070 emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5071 DONE;
5072 }"
5073 [(set_attr "length" "24")
5074 (set_attr "type" "fp")])
5075
5076 ;; If we don't have a direct conversion to single precision, don't enable this
5077 ;; conversion for 32-bit without fast math, because we don't have the insn to
5078 ;; generate the fixup swizzle to avoid double rounding problems.
5079 (define_expand "floatunssisf2"
5080 [(set (match_operand:SF 0 "gpc_reg_operand" "")
5081 (unsigned_float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
5082 "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
5083 && (!TARGET_FPRS
5084 || (TARGET_FPRS
5085 && ((TARGET_FCFIDUS && TARGET_LFIWZX)
5086 || (TARGET_DOUBLE_FLOAT && TARGET_FCFID
5087 && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))))"
5088 "
5089 {
5090 if (!TARGET_FPRS)
5091 {
5092 if (!REG_P (operands[1]))
5093 operands[1] = force_reg (SImode, operands[1]);
5094 }
5095 else if (TARGET_LFIWZX && TARGET_FCFIDUS)
5096 {
5097 emit_insn (gen_floatunssisf2_lfiwzx (operands[0], operands[1]));
5098 DONE;
5099 }
5100 else
5101 {
5102 rtx dreg = operands[1];
5103 if (!REG_P (dreg))
5104 dreg = force_reg (SImode, dreg);
5105 dreg = convert_to_mode (DImode, dreg, true);
5106 emit_insn (gen_floatdisf2 (operands[0], dreg));
5107 DONE;
5108 }
5109 }")
5110
5111 (define_expand "floatunssidf2"
5112 [(parallel [(set (match_operand:DF 0 "gpc_reg_operand" "")
5113 (unsigned_float:DF (match_operand:SI 1 "nonimmediate_operand" "")))
5114 (use (match_dup 2))
5115 (use (match_dup 3))
5116 (clobber (match_dup 4))
5117 (clobber (match_dup 5))])]
5118 "TARGET_HARD_FLOAT
5119 && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
5120 "
5121 {
5122 if (TARGET_E500_DOUBLE)
5123 {
5124 if (!REG_P (operands[1]))
5125 operands[1] = force_reg (SImode, operands[1]);
5126 emit_insn (gen_spe_floatunssidf2 (operands[0], operands[1]));
5127 DONE;
5128 }
5129 else if (TARGET_LFIWZX && TARGET_FCFID)
5130 {
5131 emit_insn (gen_floatunssidf2_lfiwzx (operands[0], operands[1]));
5132 DONE;
5133 }
5134 else if (TARGET_FCFID)
5135 {
5136 rtx dreg = operands[1];
5137 if (!REG_P (dreg))
5138 dreg = force_reg (SImode, dreg);
5139 dreg = convert_to_mode (DImode, dreg, true);
5140 emit_insn (gen_floatdidf2 (operands[0], dreg));
5141 DONE;
5142 }
5143
5144 if (!REG_P (operands[1]))
5145 operands[1] = force_reg (SImode, operands[1]);
5146 operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5147 operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503599627370496\", DFmode));
5148 operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5149 operands[5] = gen_reg_rtx (DFmode);
5150 }")
5151
5152 (define_insn_and_split "*floatunssidf2_internal"
5153 [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5154 (unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5155 (use (match_operand:SI 2 "gpc_reg_operand" "r"))
5156 (use (match_operand:DF 3 "gpc_reg_operand" "d"))
5157 (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
5158 (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))]
5159 "! TARGET_FCFIDU && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5160 && !(TARGET_FCFID && TARGET_POWERPC64)"
5161 "#"
5162 ""
5163 [(pc)]
5164 "
5165 {
5166 rtx lowword, highword;
5167 gcc_assert (MEM_P (operands[4]));
5168 highword = adjust_address (operands[4], SImode, 0);
5169 lowword = adjust_address (operands[4], SImode, 4);
5170 if (! WORDS_BIG_ENDIAN)
5171 std::swap (lowword, highword);
5172
5173 emit_move_insn (lowword, operands[1]);
5174 emit_move_insn (highword, operands[2]);
5175 emit_move_insn (operands[5], operands[4]);
5176 emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5177 DONE;
5178 }"
5179 [(set_attr "length" "20")
5180 (set_attr "type" "fp")])
5181
5182 (define_expand "fix_trunc<mode>si2"
5183 [(set (match_operand:SI 0 "gpc_reg_operand" "")
5184 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "")))]
5185 "TARGET_HARD_FLOAT && ((TARGET_FPRS && <TARGET_FLOAT>) || <E500_CONVERT>)"
5186 "
5187 {
5188 if (!<E500_CONVERT>)
5189 {
5190 rtx tmp, stack;
5191
5192 if (TARGET_STFIWX)
5193 emit_insn (gen_fix_trunc<mode>si2_stfiwx (operands[0], operands[1]));
5194 else
5195 {
5196 tmp = gen_reg_rtx (DImode);
5197 stack = rs6000_allocate_stack_temp (DImode, true, false);
5198 emit_insn (gen_fix_trunc<mode>si2_internal (operands[0], operands[1],
5199 tmp, stack));
5200 }
5201 DONE;
5202 }
5203 }")
5204
5205 ; Like the convert to float patterns, this insn must be split before
5206 ; register allocation so that it can allocate the memory slot if it
5207 ; needed
5208 (define_insn_and_split "fix_trunc<mode>si2_stfiwx"
5209 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5210 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
5211 (clobber (match_scratch:DI 2 "=d"))]
5212 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5213 && (<MODE>mode != SFmode || TARGET_SINGLE_FLOAT)
5214 && TARGET_STFIWX && can_create_pseudo_p ()"
5215 "#"
5216 ""
5217 [(pc)]
5218 {
5219 rtx dest = operands[0];
5220 rtx src = operands[1];
5221 rtx tmp = operands[2];
5222
5223 if (GET_CODE (tmp) == SCRATCH)
5224 tmp = gen_reg_rtx (DImode);
5225
5226 emit_insn (gen_fctiwz_<mode> (tmp, src));
5227 if (MEM_P (dest))
5228 {
5229 dest = rs6000_address_for_fpconvert (dest);
5230 emit_insn (gen_stfiwx (dest, tmp));
5231 DONE;
5232 }
5233 else if (TARGET_POWERPC64 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5234 {
5235 dest = gen_lowpart (DImode, dest);
5236 emit_move_insn (dest, tmp);
5237 DONE;
5238 }
5239 else
5240 {
5241 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5242 emit_insn (gen_stfiwx (stack, tmp));
5243 emit_move_insn (dest, stack);
5244 DONE;
5245 }
5246 }
5247 [(set_attr "length" "12")
5248 (set_attr "type" "fp")])
5249
5250 (define_insn_and_split "fix_trunc<mode>si2_internal"
5251 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,?r")
5252 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d,<rreg>")))
5253 (clobber (match_operand:DI 2 "gpc_reg_operand" "=1,d"))
5254 (clobber (match_operand:DI 3 "offsettable_mem_operand" "=o,o"))]
5255 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
5256 "#"
5257 ""
5258 [(pc)]
5259 "
5260 {
5261 rtx lowword;
5262 gcc_assert (MEM_P (operands[3]));
5263 lowword = adjust_address (operands[3], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
5264
5265 emit_insn (gen_fctiwz_<mode> (operands[2], operands[1]));
5266 emit_move_insn (operands[3], operands[2]);
5267 emit_move_insn (operands[0], lowword);
5268 DONE;
5269 }"
5270 [(set_attr "length" "16")
5271 (set_attr "type" "fp")])
5272
5273 (define_expand "fix_trunc<mode>di2"
5274 [(set (match_operand:DI 0 "gpc_reg_operand" "")
5275 (fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "")))]
5276 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS
5277 && TARGET_FCFID"
5278 "")
5279
5280 (define_insn "*fix_trunc<mode>di2_fctidz"
5281 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5282 (fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fa>")))]
5283 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS
5284 && TARGET_FCFID"
5285 "@
5286 fctidz %0,%1
5287 xscvdpsxds %x0,%x1"
5288 [(set_attr "type" "fp")])
5289
5290 (define_expand "fixuns_trunc<mode>si2"
5291 [(set (match_operand:SI 0 "gpc_reg_operand" "")
5292 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "")))]
5293 "TARGET_HARD_FLOAT
5294 && ((TARGET_FPRS && <TARGET_FLOAT> && TARGET_FCTIWUZ && TARGET_STFIWX)
5295 || <E500_CONVERT>)"
5296 "
5297 {
5298 if (!<E500_CONVERT>)
5299 {
5300 emit_insn (gen_fixuns_trunc<mode>si2_stfiwx (operands[0], operands[1]));
5301 DONE;
5302 }
5303 }")
5304
5305 (define_insn_and_split "fixuns_trunc<mode>si2_stfiwx"
5306 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5307 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
5308 (clobber (match_scratch:DI 2 "=d"))]
5309 "TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT> && TARGET_FCTIWUZ
5310 && TARGET_STFIWX && can_create_pseudo_p ()"
5311 "#"
5312 ""
5313 [(pc)]
5314 {
5315 rtx dest = operands[0];
5316 rtx src = operands[1];
5317 rtx tmp = operands[2];
5318
5319 if (GET_CODE (tmp) == SCRATCH)
5320 tmp = gen_reg_rtx (DImode);
5321
5322 emit_insn (gen_fctiwuz_<mode> (tmp, src));
5323 if (MEM_P (dest))
5324 {
5325 dest = rs6000_address_for_fpconvert (dest);
5326 emit_insn (gen_stfiwx (dest, tmp));
5327 DONE;
5328 }
5329 else if (TARGET_POWERPC64 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5330 {
5331 dest = gen_lowpart (DImode, dest);
5332 emit_move_insn (dest, tmp);
5333 DONE;
5334 }
5335 else
5336 {
5337 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5338 emit_insn (gen_stfiwx (stack, tmp));
5339 emit_move_insn (dest, stack);
5340 DONE;
5341 }
5342 }
5343 [(set_attr "length" "12")
5344 (set_attr "type" "fp")])
5345
5346 (define_expand "fixuns_trunc<mode>di2"
5347 [(set (match_operand:DI 0 "register_operand" "")
5348 (unsigned_fix:DI (match_operand:SFDF 1 "register_operand" "")))]
5349 "TARGET_HARD_FLOAT && (TARGET_FCTIDUZ || VECTOR_UNIT_VSX_P (<MODE>mode))"
5350 "")
5351
5352 (define_insn "*fixuns_trunc<mode>di2_fctiduz"
5353 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5354 (unsigned_fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fa>")))]
5355 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS
5356 && TARGET_FCTIDUZ"
5357 "@
5358 fctiduz %0,%1
5359 xscvdpuxds %x0,%x1"
5360 [(set_attr "type" "fp")])
5361
5362 ; Here, we use (set (reg) (unspec:DI [(fix:SI ...)] UNSPEC_FCTIWZ))
5363 ; rather than (set (subreg:SI (reg)) (fix:SI ...))
5364 ; because the first makes it clear that operand 0 is not live
5365 ; before the instruction.
5366 (define_insn "fctiwz_<mode>"
5367 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5368 (unspec:DI [(fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
5369 UNSPEC_FCTIWZ))]
5370 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
5371 "@
5372 fctiwz %0,%1
5373 xscvdpsxws %x0,%x1"
5374 [(set_attr "type" "fp")])
5375
5376 (define_insn "fctiwuz_<mode>"
5377 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5378 (unspec:DI [(unsigned_fix:SI
5379 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
5380 UNSPEC_FCTIWUZ))]
5381 "TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT> && TARGET_FCTIWUZ"
5382 "@
5383 fctiwuz %0,%1
5384 xscvdpuxws %x0,%x1"
5385 [(set_attr "type" "fp")])
5386
5387 ;; Only optimize (float (fix x)) -> frz if we are in fast-math mode, since
5388 ;; since the friz instruction does not truncate the value if the floating
5389 ;; point value is < LONG_MIN or > LONG_MAX.
5390 (define_insn "*friz"
5391 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
5392 (float:DF (fix:DI (match_operand:DF 1 "gpc_reg_operand" "d,ws"))))]
5393 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_FPRND
5394 && flag_unsafe_math_optimizations && !flag_trapping_math && TARGET_FRIZ"
5395 "@
5396 friz %0,%1
5397 xsrdpiz %x0,%x1"
5398 [(set_attr "type" "fp")])
5399
5400 ;; Since FCTIWZ doesn't sign extend the upper bits, we have to do a store and a
5401 ;; load to properly sign extend the value, but at least doing a store, load
5402 ;; into a GPR to sign extend, a store from the GPR and a load back into the FPR
5403 ;; if we have 32-bit memory ops
5404 (define_insn_and_split "*round32<mode>2_fprs"
5405 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
5406 (float:SFDF
5407 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
5408 (clobber (match_scratch:DI 2 "=d"))
5409 (clobber (match_scratch:DI 3 "=d"))]
5410 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5411 && <SI_CONVERT_FP> && TARGET_LFIWAX && TARGET_STFIWX && TARGET_FCFID
5412 && can_create_pseudo_p ()"
5413 "#"
5414 ""
5415 [(pc)]
5416 {
5417 rtx dest = operands[0];
5418 rtx src = operands[1];
5419 rtx tmp1 = operands[2];
5420 rtx tmp2 = operands[3];
5421 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5422
5423 if (GET_CODE (tmp1) == SCRATCH)
5424 tmp1 = gen_reg_rtx (DImode);
5425 if (GET_CODE (tmp2) == SCRATCH)
5426 tmp2 = gen_reg_rtx (DImode);
5427
5428 emit_insn (gen_fctiwz_<mode> (tmp1, src));
5429 emit_insn (gen_stfiwx (stack, tmp1));
5430 emit_insn (gen_lfiwax (tmp2, stack));
5431 emit_insn (gen_floatdi<mode>2 (dest, tmp2));
5432 DONE;
5433 }
5434 [(set_attr "type" "fpload")
5435 (set_attr "length" "16")])
5436
5437 (define_insn_and_split "*roundu32<mode>2_fprs"
5438 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
5439 (unsigned_float:SFDF
5440 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
5441 (clobber (match_scratch:DI 2 "=d"))
5442 (clobber (match_scratch:DI 3 "=d"))]
5443 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5444 && TARGET_LFIWZX && TARGET_STFIWX && TARGET_FCFIDU
5445 && can_create_pseudo_p ()"
5446 "#"
5447 ""
5448 [(pc)]
5449 {
5450 rtx dest = operands[0];
5451 rtx src = operands[1];
5452 rtx tmp1 = operands[2];
5453 rtx tmp2 = operands[3];
5454 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5455
5456 if (GET_CODE (tmp1) == SCRATCH)
5457 tmp1 = gen_reg_rtx (DImode);
5458 if (GET_CODE (tmp2) == SCRATCH)
5459 tmp2 = gen_reg_rtx (DImode);
5460
5461 emit_insn (gen_fctiwuz_<mode> (tmp1, src));
5462 emit_insn (gen_stfiwx (stack, tmp1));
5463 emit_insn (gen_lfiwzx (tmp2, stack));
5464 emit_insn (gen_floatdi<mode>2 (dest, tmp2));
5465 DONE;
5466 }
5467 [(set_attr "type" "fpload")
5468 (set_attr "length" "16")])
5469
5470 ;; No VSX equivalent to fctid
5471 (define_insn "lrint<mode>di2"
5472 [(set (match_operand:DI 0 "gpc_reg_operand" "=d")
5473 (unspec:DI [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
5474 UNSPEC_FCTID))]
5475 "TARGET_<MODE>_FPR && TARGET_FPRND"
5476 "fctid %0,%1"
5477 [(set_attr "type" "fp")])
5478
5479 (define_insn "btrunc<mode>2"
5480 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5481 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
5482 UNSPEC_FRIZ))]
5483 "TARGET_<MODE>_FPR && TARGET_FPRND"
5484 "@
5485 friz %0,%1
5486 xsrdpiz %x0,%x1"
5487 [(set_attr "type" "fp")
5488 (set_attr "fp_type" "fp_addsub_<Fs>")])
5489
5490 (define_insn "ceil<mode>2"
5491 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5492 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
5493 UNSPEC_FRIP))]
5494 "TARGET_<MODE>_FPR && TARGET_FPRND"
5495 "@
5496 frip %0,%1
5497 xsrdpip %x0,%x1"
5498 [(set_attr "type" "fp")
5499 (set_attr "fp_type" "fp_addsub_<Fs>")])
5500
5501 (define_insn "floor<mode>2"
5502 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5503 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
5504 UNSPEC_FRIM))]
5505 "TARGET_<MODE>_FPR && TARGET_FPRND"
5506 "@
5507 frim %0,%1
5508 xsrdpim %x0,%x1"
5509 [(set_attr "type" "fp")
5510 (set_attr "fp_type" "fp_addsub_<Fs>")])
5511
5512 ;; No VSX equivalent to frin
5513 (define_insn "round<mode>2"
5514 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<rreg2>")
5515 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
5516 UNSPEC_FRIN))]
5517 "TARGET_<MODE>_FPR && TARGET_FPRND"
5518 "frin %0,%1"
5519 [(set_attr "type" "fp")
5520 (set_attr "fp_type" "fp_addsub_<Fs>")])
5521
5522 (define_insn "*xsrdpi<mode>2"
5523 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5524 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Fv>")]
5525 UNSPEC_XSRDPI))]
5526 "TARGET_<MODE>_FPR && TARGET_VSX"
5527 "xsrdpi %x0,%x1"
5528 [(set_attr "type" "fp")
5529 (set_attr "fp_type" "fp_addsub_<Fs>")])
5530
5531 (define_expand "lround<mode>di2"
5532 [(set (match_dup 2)
5533 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "")]
5534 UNSPEC_XSRDPI))
5535 (set (match_operand:DI 0 "gpc_reg_operand" "")
5536 (unspec:DI [(match_dup 2)]
5537 UNSPEC_FCTID))]
5538 "TARGET_<MODE>_FPR && TARGET_VSX"
5539 {
5540 operands[2] = gen_reg_rtx (<MODE>mode);
5541 })
5542
5543 ; An UNSPEC is used so we don't have to support SImode in FP registers.
5544 (define_insn "stfiwx"
5545 [(set (match_operand:SI 0 "memory_operand" "=Z")
5546 (unspec:SI [(match_operand:DI 1 "gpc_reg_operand" "d")]
5547 UNSPEC_STFIWX))]
5548 "TARGET_PPC_GFXOPT"
5549 "stfiwx %1,%y0"
5550 [(set_attr "type" "fpstore")])
5551
5552 ;; If we don't have a direct conversion to single precision, don't enable this
5553 ;; conversion for 32-bit without fast math, because we don't have the insn to
5554 ;; generate the fixup swizzle to avoid double rounding problems.
5555 (define_expand "floatsisf2"
5556 [(set (match_operand:SF 0 "gpc_reg_operand" "")
5557 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
5558 "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
5559 && (!TARGET_FPRS
5560 || (TARGET_FPRS
5561 && ((TARGET_FCFIDS && TARGET_LFIWAX)
5562 || (TARGET_DOUBLE_FLOAT && TARGET_FCFID
5563 && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))))"
5564 "
5565 {
5566 if (!TARGET_FPRS)
5567 {
5568 if (!REG_P (operands[1]))
5569 operands[1] = force_reg (SImode, operands[1]);
5570 }
5571 else if (TARGET_FCFIDS && TARGET_LFIWAX)
5572 {
5573 emit_insn (gen_floatsisf2_lfiwax (operands[0], operands[1]));
5574 DONE;
5575 }
5576 else if (TARGET_FCFID && TARGET_LFIWAX)
5577 {
5578 rtx dfreg = gen_reg_rtx (DFmode);
5579 emit_insn (gen_floatsidf2_lfiwax (dfreg, operands[1]));
5580 emit_insn (gen_truncdfsf2 (operands[0], dfreg));
5581 DONE;
5582 }
5583 else
5584 {
5585 rtx dreg = operands[1];
5586 if (!REG_P (dreg))
5587 dreg = force_reg (SImode, dreg);
5588 dreg = convert_to_mode (DImode, dreg, false);
5589 emit_insn (gen_floatdisf2 (operands[0], dreg));
5590 DONE;
5591 }
5592 }")
5593
5594 (define_expand "floatdidf2"
5595 [(set (match_operand:DF 0 "gpc_reg_operand" "")
5596 (float:DF (match_operand:DI 1 "gpc_reg_operand" "")))]
5597 "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS"
5598 "")
5599
5600 (define_insn "*floatdidf2_fpr"
5601 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
5602 (float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
5603 "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS"
5604 "@
5605 fcfid %0,%1
5606 xscvsxddp %x0,%x1"
5607 [(set_attr "type" "fp")])
5608
5609 ; Allow the combiner to merge source memory operands to the conversion so that
5610 ; the optimizer/register allocator doesn't try to load the value too early in a
5611 ; GPR and then use store/load to move it to a FPR and suffer from a store-load
5612 ; hit. We will split after reload to avoid the trip through the GPRs
5613
5614 (define_insn_and_split "*floatdidf2_mem"
5615 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
5616 (float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
5617 (clobber (match_scratch:DI 2 "=d,wi"))]
5618 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS && TARGET_FCFID"
5619 "#"
5620 "&& reload_completed"
5621 [(set (match_dup 2) (match_dup 1))
5622 (set (match_dup 0) (float:DF (match_dup 2)))]
5623 ""
5624 [(set_attr "length" "8")
5625 (set_attr "type" "fpload")])
5626
5627 (define_expand "floatunsdidf2"
5628 [(set (match_operand:DF 0 "gpc_reg_operand" "")
5629 (unsigned_float:DF
5630 (match_operand:DI 1 "gpc_reg_operand" "")))]
5631 "TARGET_HARD_FLOAT && TARGET_FCFIDU"
5632 "")
5633
5634 (define_insn "*floatunsdidf2_fcfidu"
5635 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
5636 (unsigned_float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
5637 "TARGET_HARD_FLOAT && TARGET_FCFIDU"
5638 "@
5639 fcfidu %0,%1
5640 xscvuxddp %x0,%x1"
5641 [(set_attr "type" "fp")
5642 (set_attr "length" "4")])
5643
5644 (define_insn_and_split "*floatunsdidf2_mem"
5645 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
5646 (unsigned_float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
5647 (clobber (match_scratch:DI 2 "=d,wi"))]
5648 "TARGET_HARD_FLOAT && (TARGET_FCFIDU || VECTOR_UNIT_VSX_P (DFmode))"
5649 "#"
5650 "&& reload_completed"
5651 [(set (match_dup 2) (match_dup 1))
5652 (set (match_dup 0) (unsigned_float:DF (match_dup 2)))]
5653 ""
5654 [(set_attr "length" "8")
5655 (set_attr "type" "fpload")])
5656
5657 (define_expand "floatdisf2"
5658 [(set (match_operand:SF 0 "gpc_reg_operand" "")
5659 (float:SF (match_operand:DI 1 "gpc_reg_operand" "")))]
5660 "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
5661 && (TARGET_FCFIDS || TARGET_POWERPC64 || flag_unsafe_math_optimizations)"
5662 "
5663 {
5664 if (!TARGET_FCFIDS)
5665 {
5666 rtx val = operands[1];
5667 if (!flag_unsafe_math_optimizations)
5668 {
5669 rtx label = gen_label_rtx ();
5670 val = gen_reg_rtx (DImode);
5671 emit_insn (gen_floatdisf2_internal2 (val, operands[1], label));
5672 emit_label (label);
5673 }
5674 emit_insn (gen_floatdisf2_internal1 (operands[0], val));
5675 DONE;
5676 }
5677 }")
5678
5679 (define_insn "floatdisf2_fcfids"
5680 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy")
5681 (float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
5682 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
5683 && TARGET_DOUBLE_FLOAT && TARGET_FCFIDS"
5684 "@
5685 fcfids %0,%1
5686 xscvsxdsp %x0,%x1"
5687 [(set_attr "type" "fp")])
5688
5689 (define_insn_and_split "*floatdisf2_mem"
5690 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy,wy")
5691 (float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
5692 (clobber (match_scratch:DI 2 "=d,d,wi"))]
5693 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
5694 && TARGET_DOUBLE_FLOAT && TARGET_FCFIDS"
5695 "#"
5696 "&& reload_completed"
5697 [(pc)]
5698 "
5699 {
5700 emit_move_insn (operands[2], operands[1]);
5701 emit_insn (gen_floatdisf2_fcfids (operands[0], operands[2]));
5702 DONE;
5703 }"
5704 [(set_attr "length" "8")])
5705
5706 ;; This is not IEEE compliant if rounding mode is "round to nearest".
5707 ;; If the DI->DF conversion is inexact, then it's possible to suffer
5708 ;; from double rounding.
5709 ;; Instead of creating a new cpu type for two FP operations, just use fp
5710 (define_insn_and_split "floatdisf2_internal1"
5711 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
5712 (float:SF (match_operand:DI 1 "gpc_reg_operand" "d")))
5713 (clobber (match_scratch:DF 2 "=d"))]
5714 "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
5715 && !TARGET_FCFIDS"
5716 "#"
5717 "&& reload_completed"
5718 [(set (match_dup 2)
5719 (float:DF (match_dup 1)))
5720 (set (match_dup 0)
5721 (float_truncate:SF (match_dup 2)))]
5722 ""
5723 [(set_attr "length" "8")
5724 (set_attr "type" "fp")])
5725
5726 ;; Twiddles bits to avoid double rounding.
5727 ;; Bits that might be truncated when converting to DFmode are replaced
5728 ;; by a bit that won't be lost at that stage, but is below the SFmode
5729 ;; rounding position.
5730 (define_expand "floatdisf2_internal2"
5731 [(parallel [(set (match_dup 3) (ashiftrt:DI (match_operand:DI 1 "" "")
5732 (const_int 53)))
5733 (clobber (reg:DI CA_REGNO))])
5734 (set (match_operand:DI 0 "" "") (and:DI (match_dup 1)
5735 (const_int 2047)))
5736 (set (match_dup 3) (plus:DI (match_dup 3)
5737 (const_int 1)))
5738 (set (match_dup 0) (plus:DI (match_dup 0)
5739 (const_int 2047)))
5740 (set (match_dup 4) (compare:CCUNS (match_dup 3)
5741 (const_int 2)))
5742 (set (match_dup 0) (ior:DI (match_dup 0)
5743 (match_dup 1)))
5744 (set (match_dup 0) (and:DI (match_dup 0)
5745 (const_int -2048)))
5746 (set (pc) (if_then_else (geu (match_dup 4) (const_int 0))
5747 (label_ref (match_operand:DI 2 "" ""))
5748 (pc)))
5749 (set (match_dup 0) (match_dup 1))]
5750 "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
5751 && !TARGET_FCFIDS"
5752 "
5753 {
5754 operands[3] = gen_reg_rtx (DImode);
5755 operands[4] = gen_reg_rtx (CCUNSmode);
5756 }")
5757
5758 (define_expand "floatunsdisf2"
5759 [(set (match_operand:SF 0 "gpc_reg_operand" "")
5760 (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand" "")))]
5761 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
5762 && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
5763 "")
5764
5765 (define_insn "floatunsdisf2_fcfidus"
5766 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wu")
5767 (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
5768 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
5769 && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
5770 "@
5771 fcfidus %0,%1
5772 xscvuxdsp %x0,%x1"
5773 [(set_attr "type" "fp")])
5774
5775 (define_insn_and_split "*floatunsdisf2_mem"
5776 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy,wy")
5777 (unsigned_float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
5778 (clobber (match_scratch:DI 2 "=d,d,wi"))]
5779 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
5780 && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
5781 "#"
5782 "&& reload_completed"
5783 [(pc)]
5784 "
5785 {
5786 emit_move_insn (operands[2], operands[1]);
5787 emit_insn (gen_floatunsdisf2_fcfidus (operands[0], operands[2]));
5788 DONE;
5789 }"
5790 [(set_attr "length" "8")
5791 (set_attr "type" "fpload")])
5792 \f
5793 ;; Define the TImode operations that can be done in a small number
5794 ;; of instructions. The & constraints are to prevent the register
5795 ;; allocator from allocating registers that overlap with the inputs
5796 ;; (for example, having an input in 7,8 and an output in 6,7). We
5797 ;; also allow for the output being the same as one of the inputs.
5798
5799 (define_expand "addti3"
5800 [(set (match_operand:TI 0 "gpc_reg_operand" "")
5801 (plus:TI (match_operand:TI 1 "gpc_reg_operand" "")
5802 (match_operand:TI 2 "reg_or_short_operand" "")))]
5803 "TARGET_64BIT"
5804 {
5805 rtx lo0 = gen_lowpart (DImode, operands[0]);
5806 rtx lo1 = gen_lowpart (DImode, operands[1]);
5807 rtx lo2 = gen_lowpart (DImode, operands[2]);
5808 rtx hi0 = gen_highpart (DImode, operands[0]);
5809 rtx hi1 = gen_highpart (DImode, operands[1]);
5810 rtx hi2 = gen_highpart_mode (DImode, TImode, operands[2]);
5811
5812 if (!reg_or_short_operand (lo2, DImode))
5813 lo2 = force_reg (DImode, lo2);
5814 if (!adde_operand (hi2, DImode))
5815 hi2 = force_reg (DImode, hi2);
5816
5817 emit_insn (gen_adddi3_carry (lo0, lo1, lo2));
5818 emit_insn (gen_adddi3_carry_in (hi0, hi1, hi2));
5819 DONE;
5820 })
5821
5822 (define_expand "subti3"
5823 [(set (match_operand:TI 0 "gpc_reg_operand" "")
5824 (minus:TI (match_operand:TI 1 "reg_or_short_operand" "")
5825 (match_operand:TI 2 "gpc_reg_operand" "")))]
5826 "TARGET_64BIT"
5827 {
5828 rtx lo0 = gen_lowpart (DImode, operands[0]);
5829 rtx lo1 = gen_lowpart (DImode, operands[1]);
5830 rtx lo2 = gen_lowpart (DImode, operands[2]);
5831 rtx hi0 = gen_highpart (DImode, operands[0]);
5832 rtx hi1 = gen_highpart_mode (DImode, TImode, operands[1]);
5833 rtx hi2 = gen_highpart (DImode, operands[2]);
5834
5835 if (!reg_or_short_operand (lo1, DImode))
5836 lo1 = force_reg (DImode, lo1);
5837 if (!adde_operand (hi1, DImode))
5838 hi1 = force_reg (DImode, hi1);
5839
5840 emit_insn (gen_subfdi3_carry (lo0, lo2, lo1));
5841 emit_insn (gen_subfdi3_carry_in (hi0, hi2, hi1));
5842 DONE;
5843 })
5844 \f
5845 ;; 128-bit logical operations expanders
5846
5847 (define_expand "and<mode>3"
5848 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
5849 (and:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
5850 (match_operand:BOOL_128 2 "vlogical_operand" "")))]
5851 ""
5852 "")
5853
5854 (define_expand "ior<mode>3"
5855 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
5856 (ior:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
5857 (match_operand:BOOL_128 2 "vlogical_operand" "")))]
5858 ""
5859 "")
5860
5861 (define_expand "xor<mode>3"
5862 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
5863 (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
5864 (match_operand:BOOL_128 2 "vlogical_operand" "")))]
5865 ""
5866 "")
5867
5868 (define_expand "one_cmpl<mode>2"
5869 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
5870 (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")))]
5871 ""
5872 "")
5873
5874 (define_expand "nor<mode>3"
5875 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
5876 (and:BOOL_128
5877 (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" ""))
5878 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))))]
5879 ""
5880 "")
5881
5882 (define_expand "andc<mode>3"
5883 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
5884 (and:BOOL_128
5885 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))
5886 (match_operand:BOOL_128 1 "vlogical_operand" "")))]
5887 ""
5888 "")
5889
5890 ;; Power8 vector logical instructions.
5891 (define_expand "eqv<mode>3"
5892 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
5893 (not:BOOL_128
5894 (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
5895 (match_operand:BOOL_128 2 "vlogical_operand" ""))))]
5896 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
5897 "")
5898
5899 ;; Rewrite nand into canonical form
5900 (define_expand "nand<mode>3"
5901 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
5902 (ior:BOOL_128
5903 (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" ""))
5904 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))))]
5905 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
5906 "")
5907
5908 ;; The canonical form is to have the negated element first, so we need to
5909 ;; reverse arguments.
5910 (define_expand "orc<mode>3"
5911 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
5912 (ior:BOOL_128
5913 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))
5914 (match_operand:BOOL_128 1 "vlogical_operand" "")))]
5915 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
5916 "")
5917
5918 ;; 128-bit logical operations insns and split operations
5919 (define_insn_and_split "*and<mode>3_internal"
5920 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
5921 (and:BOOL_128
5922 (match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
5923 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")))]
5924 ""
5925 {
5926 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
5927 return "xxland %x0,%x1,%x2";
5928
5929 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
5930 return "vand %0,%1,%2";
5931
5932 return "#";
5933 }
5934 "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
5935 [(const_int 0)]
5936 {
5937 rs6000_split_logical (operands, AND, false, false, false);
5938 DONE;
5939 }
5940 [(set (attr "type")
5941 (if_then_else
5942 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
5943 (const_string "vecsimple")
5944 (const_string "integer")))
5945 (set (attr "length")
5946 (if_then_else
5947 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
5948 (const_string "4")
5949 (if_then_else
5950 (match_test "TARGET_POWERPC64")
5951 (const_string "8")
5952 (const_string "16"))))])
5953
5954 ;; 128-bit IOR/XOR
5955 (define_insn_and_split "*bool<mode>3_internal"
5956 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
5957 (match_operator:BOOL_128 3 "boolean_or_operator"
5958 [(match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
5959 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")]))]
5960 ""
5961 {
5962 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
5963 return "xxl%q3 %x0,%x1,%x2";
5964
5965 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
5966 return "v%q3 %0,%1,%2";
5967
5968 return "#";
5969 }
5970 "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
5971 [(const_int 0)]
5972 {
5973 rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, false);
5974 DONE;
5975 }
5976 [(set (attr "type")
5977 (if_then_else
5978 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
5979 (const_string "vecsimple")
5980 (const_string "integer")))
5981 (set (attr "length")
5982 (if_then_else
5983 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
5984 (const_string "4")
5985 (if_then_else
5986 (match_test "TARGET_POWERPC64")
5987 (const_string "8")
5988 (const_string "16"))))])
5989
5990 ;; 128-bit ANDC/ORC
5991 (define_insn_and_split "*boolc<mode>3_internal1"
5992 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
5993 (match_operator:BOOL_128 3 "boolean_operator"
5994 [(not:BOOL_128
5995 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))
5996 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")]))]
5997 "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
5998 {
5999 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6000 return "xxl%q3 %x0,%x1,%x2";
6001
6002 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6003 return "v%q3 %0,%1,%2";
6004
6005 return "#";
6006 }
6007 "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
6008 && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6009 [(const_int 0)]
6010 {
6011 rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
6012 DONE;
6013 }
6014 [(set (attr "type")
6015 (if_then_else
6016 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6017 (const_string "vecsimple")
6018 (const_string "integer")))
6019 (set (attr "length")
6020 (if_then_else
6021 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6022 (const_string "4")
6023 (if_then_else
6024 (match_test "TARGET_POWERPC64")
6025 (const_string "8")
6026 (const_string "16"))))])
6027
6028 (define_insn_and_split "*boolc<mode>3_internal2"
6029 [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6030 (match_operator:TI2 3 "boolean_operator"
6031 [(not:TI2
6032 (match_operand:TI2 2 "int_reg_operand" "r,0,r"))
6033 (match_operand:TI2 1 "int_reg_operand" "r,r,0")]))]
6034 "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6035 "#"
6036 "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6037 [(const_int 0)]
6038 {
6039 rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
6040 DONE;
6041 }
6042 [(set_attr "type" "integer")
6043 (set (attr "length")
6044 (if_then_else
6045 (match_test "TARGET_POWERPC64")
6046 (const_string "8")
6047 (const_string "16")))])
6048
6049 ;; 128-bit NAND/NOR
6050 (define_insn_and_split "*boolcc<mode>3_internal1"
6051 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6052 (match_operator:BOOL_128 3 "boolean_operator"
6053 [(not:BOOL_128
6054 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>"))
6055 (not:BOOL_128
6056 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))]))]
6057 "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
6058 {
6059 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6060 return "xxl%q3 %x0,%x1,%x2";
6061
6062 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6063 return "v%q3 %0,%1,%2";
6064
6065 return "#";
6066 }
6067 "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
6068 && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6069 [(const_int 0)]
6070 {
6071 rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
6072 DONE;
6073 }
6074 [(set (attr "type")
6075 (if_then_else
6076 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6077 (const_string "vecsimple")
6078 (const_string "integer")))
6079 (set (attr "length")
6080 (if_then_else
6081 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6082 (const_string "4")
6083 (if_then_else
6084 (match_test "TARGET_POWERPC64")
6085 (const_string "8")
6086 (const_string "16"))))])
6087
6088 (define_insn_and_split "*boolcc<mode>3_internal2"
6089 [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6090 (match_operator:TI2 3 "boolean_operator"
6091 [(not:TI2
6092 (match_operand:TI2 1 "int_reg_operand" "r,0,r"))
6093 (not:TI2
6094 (match_operand:TI2 2 "int_reg_operand" "r,r,0"))]))]
6095 "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6096 "#"
6097 "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6098 [(const_int 0)]
6099 {
6100 rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
6101 DONE;
6102 }
6103 [(set_attr "type" "integer")
6104 (set (attr "length")
6105 (if_then_else
6106 (match_test "TARGET_POWERPC64")
6107 (const_string "8")
6108 (const_string "16")))])
6109
6110
6111 ;; 128-bit EQV
6112 (define_insn_and_split "*eqv<mode>3_internal1"
6113 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6114 (not:BOOL_128
6115 (xor:BOOL_128
6116 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")
6117 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))))]
6118 "TARGET_P8_VECTOR"
6119 {
6120 if (vsx_register_operand (operands[0], <MODE>mode))
6121 return "xxleqv %x0,%x1,%x2";
6122
6123 return "#";
6124 }
6125 "TARGET_P8_VECTOR && reload_completed
6126 && int_reg_operand (operands[0], <MODE>mode)"
6127 [(const_int 0)]
6128 {
6129 rs6000_split_logical (operands, XOR, true, false, false);
6130 DONE;
6131 }
6132 [(set (attr "type")
6133 (if_then_else
6134 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6135 (const_string "vecsimple")
6136 (const_string "integer")))
6137 (set (attr "length")
6138 (if_then_else
6139 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6140 (const_string "4")
6141 (if_then_else
6142 (match_test "TARGET_POWERPC64")
6143 (const_string "8")
6144 (const_string "16"))))])
6145
6146 (define_insn_and_split "*eqv<mode>3_internal2"
6147 [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6148 (not:TI2
6149 (xor:TI2
6150 (match_operand:TI2 1 "int_reg_operand" "r,0,r")
6151 (match_operand:TI2 2 "int_reg_operand" "r,r,0"))))]
6152 "!TARGET_P8_VECTOR"
6153 "#"
6154 "reload_completed && !TARGET_P8_VECTOR"
6155 [(const_int 0)]
6156 {
6157 rs6000_split_logical (operands, XOR, true, false, false);
6158 DONE;
6159 }
6160 [(set_attr "type" "integer")
6161 (set (attr "length")
6162 (if_then_else
6163 (match_test "TARGET_POWERPC64")
6164 (const_string "8")
6165 (const_string "16")))])
6166
6167 ;; 128-bit one's complement
6168 (define_insn_and_split "*one_cmpl<mode>3_internal"
6169 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6170 (not:BOOL_128
6171 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_UNARY>")))]
6172 ""
6173 {
6174 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6175 return "xxlnor %x0,%x1,%x1";
6176
6177 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6178 return "vnor %0,%1,%1";
6179
6180 return "#";
6181 }
6182 "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6183 [(const_int 0)]
6184 {
6185 rs6000_split_logical (operands, NOT, false, false, false);
6186 DONE;
6187 }
6188 [(set (attr "type")
6189 (if_then_else
6190 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6191 (const_string "vecsimple")
6192 (const_string "integer")))
6193 (set (attr "length")
6194 (if_then_else
6195 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6196 (const_string "4")
6197 (if_then_else
6198 (match_test "TARGET_POWERPC64")
6199 (const_string "8")
6200 (const_string "16"))))])
6201
6202 \f
6203 ;; Now define ways of moving data around.
6204
6205 ;; Set up a register with a value from the GOT table
6206
6207 (define_expand "movsi_got"
6208 [(set (match_operand:SI 0 "gpc_reg_operand" "")
6209 (unspec:SI [(match_operand:SI 1 "got_operand" "")
6210 (match_dup 2)] UNSPEC_MOVSI_GOT))]
6211 "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
6212 "
6213 {
6214 if (GET_CODE (operands[1]) == CONST)
6215 {
6216 rtx offset = const0_rtx;
6217 HOST_WIDE_INT value;
6218
6219 operands[1] = eliminate_constant_term (XEXP (operands[1], 0), &offset);
6220 value = INTVAL (offset);
6221 if (value != 0)
6222 {
6223 rtx tmp = (!can_create_pseudo_p ()
6224 ? operands[0]
6225 : gen_reg_rtx (Pmode));
6226 emit_insn (gen_movsi_got (tmp, operands[1]));
6227 emit_insn (gen_addsi3 (operands[0], tmp, offset));
6228 DONE;
6229 }
6230 }
6231
6232 operands[2] = rs6000_got_register (operands[1]);
6233 }")
6234
6235 (define_insn "*movsi_got_internal"
6236 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6237 (unspec:SI [(match_operand:SI 1 "got_no_const_operand" "")
6238 (match_operand:SI 2 "gpc_reg_operand" "b")]
6239 UNSPEC_MOVSI_GOT))]
6240 "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
6241 "lwz %0,%a1@got(%2)"
6242 [(set_attr "type" "load")])
6243
6244 ;; Used by sched, shorten_branches and final when the GOT pseudo reg
6245 ;; didn't get allocated to a hard register.
6246 (define_split
6247 [(set (match_operand:SI 0 "gpc_reg_operand" "")
6248 (unspec:SI [(match_operand:SI 1 "got_no_const_operand" "")
6249 (match_operand:SI 2 "memory_operand" "")]
6250 UNSPEC_MOVSI_GOT))]
6251 "DEFAULT_ABI == ABI_V4
6252 && flag_pic == 1
6253 && (reload_in_progress || reload_completed)"
6254 [(set (match_dup 0) (match_dup 2))
6255 (set (match_dup 0) (unspec:SI [(match_dup 1)(match_dup 0)]
6256 UNSPEC_MOVSI_GOT))]
6257 "")
6258
6259 ;; For SI, we special-case integers that can't be loaded in one insn. We
6260 ;; do the load 16-bits at a time. We could do this by loading from memory,
6261 ;; and this is even supposed to be faster, but it is simpler not to get
6262 ;; integers in the TOC.
6263 (define_insn "movsi_low"
6264 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6265 (mem:SI (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
6266 (match_operand 2 "" ""))))]
6267 "TARGET_MACHO && ! TARGET_64BIT"
6268 "lwz %0,lo16(%2)(%1)"
6269 [(set_attr "type" "load")
6270 (set_attr "length" "4")])
6271
6272 (define_insn "*movsi_internal1"
6273 [(set (match_operand:SI 0 "rs6000_nonimmediate_operand" "=r,r,r,m,r,r,r,r,*c*l,*h,*h")
6274 (match_operand:SI 1 "input_operand" "r,U,m,r,I,L,n,*h,r,r,0"))]
6275 "!TARGET_SINGLE_FPU &&
6276 (gpc_reg_operand (operands[0], SImode) || gpc_reg_operand (operands[1], SImode))"
6277 "@
6278 mr %0,%1
6279 la %0,%a1
6280 lwz%U1%X1 %0,%1
6281 stw%U0%X0 %1,%0
6282 li %0,%1
6283 lis %0,%v1
6284 #
6285 mf%1 %0
6286 mt%0 %1
6287 mt%0 %1
6288 nop"
6289 [(set_attr "type" "*,*,load,store,*,*,*,mfjmpr,mtjmpr,*,*")
6290 (set_attr "length" "4,4,4,4,4,4,8,4,4,4,4")])
6291
6292 (define_insn "*movsi_internal1_single"
6293 [(set (match_operand:SI 0 "rs6000_nonimmediate_operand" "=r,r,r,m,r,r,r,r,*c*l,*h,*h,m,*f")
6294 (match_operand:SI 1 "input_operand" "r,U,m,r,I,L,n,*h,r,r,0,f,m"))]
6295 "TARGET_SINGLE_FPU &&
6296 (gpc_reg_operand (operands[0], SImode) || gpc_reg_operand (operands[1], SImode))"
6297 "@
6298 mr %0,%1
6299 la %0,%a1
6300 lwz%U1%X1 %0,%1
6301 stw%U0%X0 %1,%0
6302 li %0,%1
6303 lis %0,%v1
6304 #
6305 mf%1 %0
6306 mt%0 %1
6307 mt%0 %1
6308 nop
6309 stfs%U0%X0 %1,%0
6310 lfs%U1%X1 %0,%1"
6311 [(set_attr "type" "*,*,load,store,*,*,*,mfjmpr,mtjmpr,*,*,fpstore,fpload")
6312 (set_attr "length" "4,4,4,4,4,4,8,4,4,4,4,4,4")])
6313
6314 ;; Split a load of a large constant into the appropriate two-insn
6315 ;; sequence.
6316
6317 (define_split
6318 [(set (match_operand:SI 0 "gpc_reg_operand" "")
6319 (match_operand:SI 1 "const_int_operand" ""))]
6320 "(unsigned HOST_WIDE_INT) (INTVAL (operands[1]) + 0x8000) >= 0x10000
6321 && (INTVAL (operands[1]) & 0xffff) != 0"
6322 [(set (match_dup 0)
6323 (match_dup 2))
6324 (set (match_dup 0)
6325 (ior:SI (match_dup 0)
6326 (match_dup 3)))]
6327 "
6328 {
6329 if (rs6000_emit_set_const (operands[0], operands[1]))
6330 DONE;
6331 else
6332 FAIL;
6333 }")
6334
6335 (define_insn "*mov<mode>_internal2"
6336 [(set (match_operand:CC 2 "cc_reg_operand" "=y,x,?y")
6337 (compare:CC (match_operand:P 1 "gpc_reg_operand" "0,r,r")
6338 (const_int 0)))
6339 (set (match_operand:P 0 "gpc_reg_operand" "=r,r,r") (match_dup 1))]
6340 ""
6341 "@
6342 cmp<wd>i %2,%0,0
6343 mr. %0,%1
6344 #"
6345 [(set_attr "type" "cmp,logical,cmp")
6346 (set_attr "dot" "yes")
6347 (set_attr "length" "4,4,8")])
6348
6349 (define_split
6350 [(set (match_operand:CC 2 "cc_reg_not_micro_cr0_operand" "")
6351 (compare:CC (match_operand:P 1 "gpc_reg_operand" "")
6352 (const_int 0)))
6353 (set (match_operand:P 0 "gpc_reg_operand" "") (match_dup 1))]
6354 "reload_completed"
6355 [(set (match_dup 0) (match_dup 1))
6356 (set (match_dup 2)
6357 (compare:CC (match_dup 0)
6358 (const_int 0)))]
6359 "")
6360 \f
6361 (define_insn "*movhi_internal"
6362 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,m,r,r,*c*l,*h")
6363 (match_operand:HI 1 "input_operand" "r,m,r,i,*h,r,0"))]
6364 "gpc_reg_operand (operands[0], HImode)
6365 || gpc_reg_operand (operands[1], HImode)"
6366 "@
6367 mr %0,%1
6368 lhz%U1%X1 %0,%1
6369 sth%U0%X0 %1,%0
6370 li %0,%w1
6371 mf%1 %0
6372 mt%0 %1
6373 nop"
6374 [(set_attr "type" "*,load,store,*,mfjmpr,mtjmpr,*")])
6375
6376 (define_expand "mov<mode>"
6377 [(set (match_operand:INT 0 "general_operand" "")
6378 (match_operand:INT 1 "any_operand" ""))]
6379 ""
6380 "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
6381
6382 (define_insn "*movqi_internal"
6383 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m,r,r,*c*l,*h")
6384 (match_operand:QI 1 "input_operand" "r,m,r,i,*h,r,0"))]
6385 "gpc_reg_operand (operands[0], QImode)
6386 || gpc_reg_operand (operands[1], QImode)"
6387 "@
6388 mr %0,%1
6389 lbz%U1%X1 %0,%1
6390 stb%U0%X0 %1,%0
6391 li %0,%1
6392 mf%1 %0
6393 mt%0 %1
6394 nop"
6395 [(set_attr "type" "*,load,store,*,mfjmpr,mtjmpr,*")])
6396 \f
6397 ;; Here is how to move condition codes around. When we store CC data in
6398 ;; an integer register or memory, we store just the high-order 4 bits.
6399 ;; This lets us not shift in the most common case of CR0.
6400 (define_expand "movcc"
6401 [(set (match_operand:CC 0 "nonimmediate_operand" "")
6402 (match_operand:CC 1 "nonimmediate_operand" ""))]
6403 ""
6404 "")
6405
6406 (define_insn "*movcc_internal1"
6407 [(set (match_operand:CC 0 "nonimmediate_operand" "=y,x,?y,y,r,r,r,r,r,cl,r,m")
6408 (match_operand:CC 1 "general_operand" "y,r,r,O,x,y,r,I,h,r,m,r"))]
6409 "register_operand (operands[0], CCmode)
6410 || register_operand (operands[1], CCmode)"
6411 "@
6412 mcrf %0,%1
6413 mtcrf 128,%1
6414 rlwinm %1,%1,%F0,0xffffffff\;mtcrf %R0,%1\;rlwinm %1,%1,%f0,0xffffffff
6415 crxor %0,%0,%0
6416 mfcr %0%Q1
6417 mfcr %0%Q1\;rlwinm %0,%0,%f1,0xf0000000
6418 mr %0,%1
6419 li %0,%1
6420 mf%1 %0
6421 mt%0 %1
6422 lwz%U1%X1 %0,%1
6423 stw%U0%X0 %1,%0"
6424 [(set (attr "type")
6425 (cond [(eq_attr "alternative" "0,3")
6426 (const_string "cr_logical")
6427 (eq_attr "alternative" "1,2")
6428 (const_string "mtcr")
6429 (eq_attr "alternative" "6,7")
6430 (const_string "integer")
6431 (eq_attr "alternative" "8")
6432 (const_string "mfjmpr")
6433 (eq_attr "alternative" "9")
6434 (const_string "mtjmpr")
6435 (eq_attr "alternative" "10")
6436 (const_string "load")
6437 (eq_attr "alternative" "11")
6438 (const_string "store")
6439 (match_test "TARGET_MFCRF")
6440 (const_string "mfcrf")
6441 ]
6442 (const_string "mfcr")))
6443 (set_attr "length" "4,4,12,4,4,8,4,4,4,4,4,4")])
6444 \f
6445 ;; For floating-point, we normally deal with the floating-point registers
6446 ;; unless -msoft-float is used. The sole exception is that parameter passing
6447 ;; can produce floating-point values in fixed-point registers. Unless the
6448 ;; value is a simple constant or already in memory, we deal with this by
6449 ;; allocating memory and copying the value explicitly via that memory location.
6450
6451 ;; Move 32-bit binary/decimal floating point
6452 (define_expand "mov<mode>"
6453 [(set (match_operand:FMOVE32 0 "nonimmediate_operand" "")
6454 (match_operand:FMOVE32 1 "any_operand" ""))]
6455 "<fmove_ok>"
6456 "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
6457
6458 (define_split
6459 [(set (match_operand:FMOVE32 0 "gpc_reg_operand" "")
6460 (match_operand:FMOVE32 1 "const_double_operand" ""))]
6461 "reload_completed
6462 && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
6463 || (GET_CODE (operands[0]) == SUBREG
6464 && GET_CODE (SUBREG_REG (operands[0])) == REG
6465 && REGNO (SUBREG_REG (operands[0])) <= 31))"
6466 [(set (match_dup 2) (match_dup 3))]
6467 "
6468 {
6469 long l;
6470
6471 <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
6472
6473 if (! TARGET_POWERPC64)
6474 operands[2] = operand_subword (operands[0], 0, 0, <MODE>mode);
6475 else
6476 operands[2] = gen_lowpart (SImode, operands[0]);
6477
6478 operands[3] = gen_int_mode (l, SImode);
6479 }")
6480
6481 (define_insn "mov<mode>_hardfloat"
6482 [(set (match_operand:FMOVE32 0 "nonimmediate_operand" "=!r,!r,m,f,<f32_vsx>,<f32_vsx>,!r,<f32_lr>,<f32_lr2>,<f32_sm>,<f32_sm2>,<f32_av>,Z,?<f32_dm>,?r,*c*l,!r,*h")
6483 (match_operand:FMOVE32 1 "input_operand" "r,m,r,f,<f32_vsx>,j,j,<f32_lm>,<f32_lm2>,<f32_sr>,<f32_sr2>,Z,<f32_av>,r,<f32_dm>,r,h,0"))]
6484 "(gpc_reg_operand (operands[0], <MODE>mode)
6485 || gpc_reg_operand (operands[1], <MODE>mode))
6486 && (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT)"
6487 "@
6488 mr %0,%1
6489 lwz%U1%X1 %0,%1
6490 stw%U0%X0 %1,%0
6491 fmr %0,%1
6492 xscpsgndp %x0,%x1,%x1
6493 xxlxor %x0,%x0,%x0
6494 li %0,0
6495 <f32_li>
6496 <f32_li2>
6497 <f32_si>
6498 <f32_si2>
6499 <f32_lv>
6500 <f32_sv>
6501 mtvsrwz %x0,%1
6502 mfvsrwz %0,%x1
6503 mt%0 %1
6504 mf%1 %0
6505 nop"
6506 [(set_attr "type" "*,load,store,fp,fp,vecsimple,integer,fpload,fpload,fpstore,fpstore,fpload,fpstore,mftgpr,mffgpr,mtjmpr,mfjmpr,*")
6507 (set_attr "length" "4")])
6508
6509 (define_insn "*mov<mode>_softfloat"
6510 [(set (match_operand:FMOVE32 0 "nonimmediate_operand" "=r,cl,r,r,m,r,r,r,r,*h")
6511 (match_operand:FMOVE32 1 "input_operand" "r,r,h,m,r,I,L,G,Fn,0"))]
6512 "(gpc_reg_operand (operands[0], <MODE>mode)
6513 || gpc_reg_operand (operands[1], <MODE>mode))
6514 && (TARGET_SOFT_FLOAT || !TARGET_FPRS)"
6515 "@
6516 mr %0,%1
6517 mt%0 %1
6518 mf%1 %0
6519 lwz%U1%X1 %0,%1
6520 stw%U0%X0 %1,%0
6521 li %0,%1
6522 lis %0,%v1
6523 #
6524 #
6525 nop"
6526 [(set_attr "type" "*,mtjmpr,mfjmpr,load,store,*,*,*,*,*")
6527 (set_attr "length" "4,4,4,4,4,4,4,4,8,4")])
6528
6529 \f
6530 ;; Move 64-bit binary/decimal floating point
6531 (define_expand "mov<mode>"
6532 [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "")
6533 (match_operand:FMOVE64 1 "any_operand" ""))]
6534 ""
6535 "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
6536
6537 (define_split
6538 [(set (match_operand:FMOVE64 0 "gpc_reg_operand" "")
6539 (match_operand:FMOVE64 1 "const_int_operand" ""))]
6540 "! TARGET_POWERPC64 && reload_completed
6541 && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
6542 || (GET_CODE (operands[0]) == SUBREG
6543 && GET_CODE (SUBREG_REG (operands[0])) == REG
6544 && REGNO (SUBREG_REG (operands[0])) <= 31))"
6545 [(set (match_dup 2) (match_dup 4))
6546 (set (match_dup 3) (match_dup 1))]
6547 "
6548 {
6549 int endian = (WORDS_BIG_ENDIAN == 0);
6550 HOST_WIDE_INT value = INTVAL (operands[1]);
6551
6552 operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
6553 operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
6554 operands[4] = GEN_INT (value >> 32);
6555 operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
6556 }")
6557
6558 (define_split
6559 [(set (match_operand:FMOVE64 0 "gpc_reg_operand" "")
6560 (match_operand:FMOVE64 1 "const_double_operand" ""))]
6561 "! TARGET_POWERPC64 && reload_completed
6562 && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
6563 || (GET_CODE (operands[0]) == SUBREG
6564 && GET_CODE (SUBREG_REG (operands[0])) == REG
6565 && REGNO (SUBREG_REG (operands[0])) <= 31))"
6566 [(set (match_dup 2) (match_dup 4))
6567 (set (match_dup 3) (match_dup 5))]
6568 "
6569 {
6570 int endian = (WORDS_BIG_ENDIAN == 0);
6571 long l[2];
6572
6573 <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
6574
6575 operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
6576 operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
6577 operands[4] = gen_int_mode (l[endian], SImode);
6578 operands[5] = gen_int_mode (l[1 - endian], SImode);
6579 }")
6580
6581 (define_split
6582 [(set (match_operand:FMOVE64 0 "gpc_reg_operand" "")
6583 (match_operand:FMOVE64 1 "const_double_operand" ""))]
6584 "TARGET_POWERPC64 && reload_completed
6585 && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
6586 || (GET_CODE (operands[0]) == SUBREG
6587 && GET_CODE (SUBREG_REG (operands[0])) == REG
6588 && REGNO (SUBREG_REG (operands[0])) <= 31))"
6589 [(set (match_dup 2) (match_dup 3))]
6590 "
6591 {
6592 int endian = (WORDS_BIG_ENDIAN == 0);
6593 long l[2];
6594 HOST_WIDE_INT val;
6595
6596 <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
6597
6598 operands[2] = gen_lowpart (DImode, operands[0]);
6599 /* HIGHPART is lower memory address when WORDS_BIG_ENDIAN. */
6600 val = ((HOST_WIDE_INT)(unsigned long)l[endian] << 32
6601 | ((HOST_WIDE_INT)(unsigned long)l[1 - endian]));
6602
6603 operands[3] = gen_int_mode (val, DImode);
6604 }")
6605
6606 ;; Don't have reload use general registers to load a constant. It is
6607 ;; less efficient than loading the constant into an FP register, since
6608 ;; it will probably be used there.
6609
6610 ;; The move constraints are ordered to prefer floating point registers before
6611 ;; general purpose registers to avoid doing a store and a load to get the value
6612 ;; into a floating point register when it is needed for a floating point
6613 ;; operation. Prefer traditional floating point registers over VSX registers,
6614 ;; since the D-form version of the memory instructions does not need a GPR for
6615 ;; reloading. ISA 3.0 (power9) adds D-form addressing for scalars to Altivec
6616 ;; registers.
6617
6618 ;; If we have FPR registers, rs6000_emit_move has moved all constants to memory,
6619 ;; except for 0.0 which can be created on VSX with an xor instruction.
6620
6621 (define_insn "*mov<mode>_hardfloat32"
6622 [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=m,d,d,<f64_av>,Z,<f64_p9>,o,<f64_vsx>,<f64_vsx>,!r,Y,r,!r")
6623 (match_operand:FMOVE64 1 "input_operand" "d,m,d,Z,<f64_av>,o,<f64_p9>,<f64_vsx>,j,j,r,Y,r"))]
6624 "! TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
6625 && (gpc_reg_operand (operands[0], <MODE>mode)
6626 || gpc_reg_operand (operands[1], <MODE>mode))"
6627 "@
6628 stfd%U0%X0 %1,%0
6629 lfd%U1%X1 %0,%1
6630 fmr %0,%1
6631 lxsd%U1x %x0,%y1
6632 stxsd%U0x %x1,%y0
6633 lxsd %0,%1
6634 stxsd %1,%0
6635 xxlor %x0,%x1,%x1
6636 xxlxor %x0,%x0,%x0
6637 #
6638 #
6639 #
6640 #"
6641 [(set_attr "type" "fpstore,fpload,fp,fpload,fpstore,fpload,fpstore,vecsimple,vecsimple,two,store,load,two")
6642 (set_attr "length" "4,4,4,4,4,4,4,4,4,8,8,8,8")])
6643
6644 (define_insn "*mov<mode>_softfloat32"
6645 [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=Y,r,r,r,r,r")
6646 (match_operand:FMOVE64 1 "input_operand" "r,Y,r,G,H,F"))]
6647 "! TARGET_POWERPC64
6648 && ((TARGET_FPRS && TARGET_SINGLE_FLOAT)
6649 || TARGET_SOFT_FLOAT || TARGET_E500_SINGLE
6650 || (<MODE>mode == DDmode && TARGET_E500_DOUBLE))
6651 && (gpc_reg_operand (operands[0], <MODE>mode)
6652 || gpc_reg_operand (operands[1], <MODE>mode))"
6653 "#"
6654 [(set_attr "type" "store,load,two,*,*,*")
6655 (set_attr "length" "8,8,8,8,12,16")])
6656
6657 ; ld/std require word-aligned displacements -> 'Y' constraint.
6658 ; List Y->r and r->Y before r->r for reload.
6659 (define_insn "*mov<mode>_hardfloat64"
6660 [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=m,d,d,<f64_p9>,o,<f64_av>,Z,<f64_vsx>,<f64_vsx>,!r,Y,r,!r,*c*l,!r,*h,r,wg,r,<f64_dm>")
6661 (match_operand:FMOVE64 1 "input_operand" "d,m,d,o,<f64_p9>,Z,<f64_av>,<f64_vsx>,j,j,r,Y,r,r,h,0,wg,r,<f64_dm>,r"))]
6662 "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
6663 && (gpc_reg_operand (operands[0], <MODE>mode)
6664 || gpc_reg_operand (operands[1], <MODE>mode))"
6665 "@
6666 stfd%U0%X0 %1,%0
6667 lfd%U1%X1 %0,%1
6668 fmr %0,%1
6669 lxsd %0,%1
6670 stxsd %1,%0
6671 lxsd%U1x %x0,%y1
6672 stxsd%U0x %x1,%y0
6673 xxlor %x0,%x1,%x1
6674 xxlxor %x0,%x0,%x0
6675 li %0,0
6676 std%U0%X0 %1,%0
6677 ld%U1%X1 %0,%1
6678 mr %0,%1
6679 mt%0 %1
6680 mf%1 %0
6681 nop
6682 mftgpr %0,%1
6683 mffgpr %0,%1
6684 mfvsrd %0,%x1
6685 mtvsrd %x0,%1"
6686 [(set_attr "type" "fpstore,fpload,fp,fpload,fpstore,fpload,fpstore,vecsimple,vecsimple,integer,store,load,*,mtjmpr,mfjmpr,*,mftgpr,mffgpr,mftgpr,mffgpr")
6687 (set_attr "length" "4")])
6688
6689 (define_insn "*mov<mode>_softfloat64"
6690 [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=Y,r,r,cl,r,r,r,r,*h")
6691 (match_operand:FMOVE64 1 "input_operand" "r,Y,r,r,h,G,H,F,0"))]
6692 "TARGET_POWERPC64 && (TARGET_SOFT_FLOAT || !TARGET_FPRS)
6693 && (gpc_reg_operand (operands[0], <MODE>mode)
6694 || gpc_reg_operand (operands[1], <MODE>mode))"
6695 "@
6696 std%U0%X0 %1,%0
6697 ld%U1%X1 %0,%1
6698 mr %0,%1
6699 mt%0 %1
6700 mf%1 %0
6701 #
6702 #
6703 #
6704 nop"
6705 [(set_attr "type" "store,load,*,mtjmpr,mfjmpr,*,*,*,*")
6706 (set_attr "length" "4,4,4,4,4,8,12,16,4")])
6707 \f
6708 (define_expand "mov<mode>"
6709 [(set (match_operand:FMOVE128 0 "general_operand" "")
6710 (match_operand:FMOVE128 1 "any_operand" ""))]
6711 ""
6712 "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
6713
6714 ;; It's important to list Y->r and r->Y before r->r because otherwise
6715 ;; reload, given m->r, will try to pick r->r and reload it, which
6716 ;; doesn't make progress.
6717
6718 ;; We can't split little endian direct moves of TDmode, because the words are
6719 ;; not swapped like they are for TImode or TFmode. Subregs therefore are
6720 ;; problematical. Don't allow direct move for this case.
6721
6722 (define_insn_and_split "*mov<mode>_64bit_dm"
6723 [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand" "=m,d,d,ws,Y,r,r,r,wm")
6724 (match_operand:FMOVE128_FPR 1 "input_operand" "d,m,d,j,r,jY,r,wm,r"))]
6725 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_POWERPC64
6726 && FLOAT128_2REG_P (<MODE>mode)
6727 && (<MODE>mode != TDmode || WORDS_BIG_ENDIAN)
6728 && (gpc_reg_operand (operands[0], <MODE>mode)
6729 || gpc_reg_operand (operands[1], <MODE>mode))"
6730 "#"
6731 "&& reload_completed"
6732 [(pc)]
6733 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
6734 [(set_attr "length" "8,8,8,8,12,12,8,8,8")])
6735
6736 (define_insn_and_split "*movtd_64bit_nodm"
6737 [(set (match_operand:TD 0 "nonimmediate_operand" "=m,d,d,ws,Y,r,r")
6738 (match_operand:TD 1 "input_operand" "d,m,d,j,r,jY,r"))]
6739 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_POWERPC64 && !WORDS_BIG_ENDIAN
6740 && (gpc_reg_operand (operands[0], TDmode)
6741 || gpc_reg_operand (operands[1], TDmode))"
6742 "#"
6743 "&& reload_completed"
6744 [(pc)]
6745 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
6746 [(set_attr "length" "8,8,8,8,12,12,8")])
6747
6748 (define_insn_and_split "*mov<mode>_32bit"
6749 [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand" "=m,d,d,ws,Y,r,r")
6750 (match_operand:FMOVE128_FPR 1 "input_operand" "d,m,d,j,r,jY,r"))]
6751 "TARGET_HARD_FLOAT && TARGET_FPRS && !TARGET_POWERPC64
6752 && (FLOAT128_2REG_P (<MODE>mode)
6753 || int_reg_operand_not_pseudo (operands[0], <MODE>mode)
6754 || int_reg_operand_not_pseudo (operands[1], <MODE>mode))
6755 && (gpc_reg_operand (operands[0], <MODE>mode)
6756 || gpc_reg_operand (operands[1], <MODE>mode))"
6757 "#"
6758 "&& reload_completed"
6759 [(pc)]
6760 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
6761 [(set_attr "length" "8,8,8,8,20,20,16")])
6762
6763 (define_insn_and_split "*mov<mode>_softfloat"
6764 [(set (match_operand:FMOVE128 0 "rs6000_nonimmediate_operand" "=Y,r,r")
6765 (match_operand:FMOVE128 1 "input_operand" "r,YGHF,r"))]
6766 "(TARGET_SOFT_FLOAT || !TARGET_FPRS)
6767 && (gpc_reg_operand (operands[0], <MODE>mode)
6768 || gpc_reg_operand (operands[1], <MODE>mode))"
6769 "#"
6770 "&& reload_completed"
6771 [(pc)]
6772 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
6773 [(set_attr "length" "20,20,16")])
6774
6775 (define_expand "extenddf<mode>2"
6776 [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
6777 (float_extend:FLOAT128 (match_operand:DF 1 "gpc_reg_operand" "")))]
6778 "TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)
6779 && TARGET_LONG_DOUBLE_128"
6780 {
6781 if (FLOAT128_IEEE_P (<MODE>mode))
6782 rs6000_expand_float128_convert (operands[0], operands[1], false);
6783 else if (TARGET_E500_DOUBLE)
6784 {
6785 gcc_assert (<MODE>mode == TFmode);
6786 emit_insn (gen_spe_extenddftf2 (operands[0], operands[1]));
6787 }
6788 else if (TARGET_VSX)
6789 {
6790 if (<MODE>mode == TFmode)
6791 emit_insn (gen_extenddftf2_vsx (operands[0], operands[1]));
6792 else if (<MODE>mode == IFmode)
6793 emit_insn (gen_extenddfif2_vsx (operands[0], operands[1]));
6794 else
6795 gcc_unreachable ();
6796 }
6797 else
6798 {
6799 rtx zero = gen_reg_rtx (DFmode);
6800 rs6000_emit_move (zero, CONST0_RTX (DFmode), DFmode);
6801
6802 if (<MODE>mode == TFmode)
6803 emit_insn (gen_extenddftf2_fprs (operands[0], operands[1], zero));
6804 else if (<MODE>mode == IFmode)
6805 emit_insn (gen_extenddfif2_fprs (operands[0], operands[1], zero));
6806 else
6807 gcc_unreachable ();
6808 }
6809 DONE;
6810 })
6811
6812 ;; Allow memory operands for the source to be created by the combiner.
6813 (define_insn_and_split "extenddf<mode>2_fprs"
6814 [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d,&d")
6815 (float_extend:IBM128
6816 (match_operand:DF 1 "nonimmediate_operand" "d,m,d")))
6817 (use (match_operand:DF 2 "nonimmediate_operand" "m,m,d"))]
6818 "!TARGET_VSX && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
6819 && TARGET_LONG_DOUBLE_128 && FLOAT128_IBM_P (<MODE>mode)"
6820 "#"
6821 "&& reload_completed"
6822 [(set (match_dup 3) (match_dup 1))
6823 (set (match_dup 4) (match_dup 2))]
6824 {
6825 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
6826 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
6827
6828 operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
6829 operands[4] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
6830 })
6831
6832 (define_insn_and_split "extenddf<mode>2_vsx"
6833 [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d")
6834 (float_extend:IBM128
6835 (match_operand:DF 1 "nonimmediate_operand" "ws,m")))]
6836 "TARGET_LONG_DOUBLE_128 && TARGET_VSX && FLOAT128_IBM_P (<MODE>mode)"
6837 "#"
6838 "&& reload_completed"
6839 [(set (match_dup 2) (match_dup 1))
6840 (set (match_dup 3) (match_dup 4))]
6841 {
6842 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
6843 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
6844
6845 operands[2] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
6846 operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
6847 operands[4] = CONST0_RTX (DFmode);
6848 })
6849
6850 (define_expand "extendsf<mode>2"
6851 [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
6852 (float_extend:FLOAT128 (match_operand:SF 1 "gpc_reg_operand" "")))]
6853 "TARGET_HARD_FLOAT
6854 && (TARGET_FPRS || TARGET_E500_DOUBLE)
6855 && TARGET_LONG_DOUBLE_128"
6856 {
6857 if (FLOAT128_IEEE_P (<MODE>mode))
6858 rs6000_expand_float128_convert (operands[0], operands[1], false);
6859 else
6860 {
6861 rtx tmp = gen_reg_rtx (DFmode);
6862 emit_insn (gen_extendsfdf2 (tmp, operands[1]));
6863 emit_insn (gen_extenddf<mode>2 (operands[0], tmp));
6864 }
6865 DONE;
6866 })
6867
6868 (define_expand "trunc<mode>df2"
6869 [(set (match_operand:DF 0 "gpc_reg_operand" "")
6870 (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
6871 "TARGET_HARD_FLOAT
6872 && (TARGET_FPRS || TARGET_E500_DOUBLE)
6873 && TARGET_LONG_DOUBLE_128"
6874 {
6875 if (FLOAT128_IEEE_P (<MODE>mode))
6876 {
6877 rs6000_expand_float128_convert (operands[0], operands[1], false);
6878 DONE;
6879 }
6880 })
6881
6882 (define_insn_and_split "trunc<mode>df2_internal1"
6883 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d")
6884 (float_truncate:DF
6885 (match_operand:IBM128 1 "gpc_reg_operand" "0,d")))]
6886 "FLOAT128_IBM_P (<MODE>mode) && !TARGET_XL_COMPAT
6887 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
6888 "@
6889 #
6890 fmr %0,%1"
6891 "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
6892 [(const_int 0)]
6893 {
6894 emit_note (NOTE_INSN_DELETED);
6895 DONE;
6896 }
6897 [(set_attr "type" "fp")])
6898
6899 (define_insn "trunc<mode>df2_internal2"
6900 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
6901 (float_truncate:DF (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
6902 "FLOAT128_IBM_P (<MODE>mode) && TARGET_XL_COMPAT && TARGET_HARD_FLOAT
6903 && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
6904 "fadd %0,%1,%L1"
6905 [(set_attr "type" "fp")
6906 (set_attr "fp_type" "fp_addsub_d")])
6907
6908 (define_expand "trunc<mode>sf2"
6909 [(set (match_operand:SF 0 "gpc_reg_operand" "")
6910 (float_truncate:SF (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
6911 "TARGET_HARD_FLOAT
6912 && (TARGET_FPRS || TARGET_E500_DOUBLE)
6913 && TARGET_LONG_DOUBLE_128"
6914 {
6915 if (FLOAT128_IEEE_P (<MODE>mode))
6916 rs6000_expand_float128_convert (operands[0], operands[1], false);
6917 else if (TARGET_E500_DOUBLE)
6918 {
6919 gcc_assert (<MODE>mode == TFmode);
6920 emit_insn (gen_spe_trunctfsf2 (operands[0], operands[1]));
6921 }
6922 else if (<MODE>mode == TFmode)
6923 emit_insn (gen_trunctfsf2_fprs (operands[0], operands[1]));
6924 else if (<MODE>mode == IFmode)
6925 emit_insn (gen_truncifsf2_fprs (operands[0], operands[1]));
6926 else
6927 gcc_unreachable ();
6928 DONE;
6929 })
6930
6931 (define_insn_and_split "trunc<mode>sf2_fprs"
6932 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
6933 (float_truncate:SF (match_operand:IBM128 1 "gpc_reg_operand" "d")))
6934 (clobber (match_scratch:DF 2 "=d"))]
6935 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
6936 && TARGET_LONG_DOUBLE_128 && FLOAT128_IBM_P (<MODE>mode)"
6937 "#"
6938 "&& reload_completed"
6939 [(set (match_dup 2)
6940 (float_truncate:DF (match_dup 1)))
6941 (set (match_dup 0)
6942 (float_truncate:SF (match_dup 2)))]
6943 "")
6944
6945 (define_expand "floatsi<mode>2"
6946 [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
6947 (float:FLOAT128 (match_operand:SI 1 "gpc_reg_operand" "")))]
6948 "TARGET_HARD_FLOAT
6949 && (TARGET_FPRS || TARGET_E500_DOUBLE)
6950 && TARGET_LONG_DOUBLE_128"
6951 {
6952 if (FLOAT128_IEEE_P (<MODE>mode))
6953 rs6000_expand_float128_convert (operands[0], operands[1], false);
6954 else
6955 {
6956 rtx tmp = gen_reg_rtx (DFmode);
6957 expand_float (tmp, operands[1], false);
6958 if (<MODE>mode == TFmode)
6959 emit_insn (gen_extenddftf2 (operands[0], tmp));
6960 else if (<MODE>mode == IFmode)
6961 emit_insn (gen_extenddfif2 (operands[0], tmp));
6962 else
6963 gcc_unreachable ();
6964 }
6965 DONE;
6966 })
6967
6968 ; fadd, but rounding towards zero.
6969 ; This is probably not the optimal code sequence.
6970 (define_insn "fix_trunc_helper<mode>"
6971 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
6972 (unspec:DF [(match_operand:IBM128 1 "gpc_reg_operand" "d")]
6973 UNSPEC_FIX_TRUNC_TF))
6974 (clobber (match_operand:DF 2 "gpc_reg_operand" "=&d"))]
6975 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
6976 && FLOAT128_IBM_P (<MODE>mode)"
6977 "mffs %2\n\tmtfsb1 31\n\tmtfsb0 30\n\tfadd %0,%1,%L1\n\tmtfsf 1,%2"
6978 [(set_attr "type" "fp")
6979 (set_attr "length" "20")])
6980
6981 (define_expand "fix_trunc<mode>si2"
6982 [(set (match_operand:SI 0 "gpc_reg_operand" "")
6983 (fix:SI (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
6984 "TARGET_HARD_FLOAT
6985 && (TARGET_FPRS || TARGET_E500_DOUBLE) && TARGET_LONG_DOUBLE_128"
6986 {
6987 if (FLOAT128_IEEE_P (<MODE>mode))
6988 rs6000_expand_float128_convert (operands[0], operands[1], false);
6989 else if (TARGET_E500_DOUBLE && <MODE>mode == TFmode)
6990 emit_insn (gen_spe_fix_trunctfsi2 (operands[0], operands[1]));
6991 else if (<MODE>mode == TFmode)
6992 emit_insn (gen_fix_trunctfsi2_fprs (operands[0], operands[1]));
6993 else if (<MODE>mode == IFmode)
6994 emit_insn (gen_fix_truncifsi2_fprs (operands[0], operands[1]));
6995 else
6996 gcc_unreachable ();
6997 DONE;
6998 })
6999
7000 (define_expand "fix_trunc<mode>si2_fprs"
7001 [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "")
7002 (fix:SI (match_operand:IBM128 1 "gpc_reg_operand" "")))
7003 (clobber (match_dup 2))
7004 (clobber (match_dup 3))
7005 (clobber (match_dup 4))
7006 (clobber (match_dup 5))])]
7007 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
7008 {
7009 operands[2] = gen_reg_rtx (DFmode);
7010 operands[3] = gen_reg_rtx (DFmode);
7011 operands[4] = gen_reg_rtx (DImode);
7012 operands[5] = assign_stack_temp (DImode, GET_MODE_SIZE (DImode));
7013 })
7014
7015 (define_insn_and_split "*fix_trunc<mode>si2_internal"
7016 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
7017 (fix:SI (match_operand:IBM128 1 "gpc_reg_operand" "d")))
7018 (clobber (match_operand:DF 2 "gpc_reg_operand" "=d"))
7019 (clobber (match_operand:DF 3 "gpc_reg_operand" "=&d"))
7020 (clobber (match_operand:DI 4 "gpc_reg_operand" "=d"))
7021 (clobber (match_operand:DI 5 "offsettable_mem_operand" "=o"))]
7022 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
7023 "#"
7024 ""
7025 [(pc)]
7026 {
7027 rtx lowword;
7028 emit_insn (gen_fix_trunc_helper<mode> (operands[2], operands[1],
7029 operands[3]));
7030
7031 gcc_assert (MEM_P (operands[5]));
7032 lowword = adjust_address (operands[5], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
7033
7034 emit_insn (gen_fctiwz_df (operands[4], operands[2]));
7035 emit_move_insn (operands[5], operands[4]);
7036 emit_move_insn (operands[0], lowword);
7037 DONE;
7038 })
7039
7040 (define_expand "fix_trunc<mode>di2"
7041 [(set (match_operand:DI 0 "gpc_reg_operand" "")
7042 (fix:DI (match_operand:IEEE128 1 "gpc_reg_operand" "")))]
7043 "TARGET_FLOAT128"
7044 {
7045 rs6000_expand_float128_convert (operands[0], operands[1], false);
7046 DONE;
7047 })
7048
7049 (define_expand "fixuns_trunc<IEEE128:mode><SDI:mode>2"
7050 [(set (match_operand:SDI 0 "gpc_reg_operand" "")
7051 (unsigned_fix:SDI (match_operand:IEEE128 1 "gpc_reg_operand" "")))]
7052 "TARGET_FLOAT128"
7053 {
7054 rs6000_expand_float128_convert (operands[0], operands[1], true);
7055 DONE;
7056 })
7057
7058 (define_expand "floatdi<mode>2"
7059 [(set (match_operand:IEEE128 0 "gpc_reg_operand" "")
7060 (float:IEEE128 (match_operand:DI 1 "gpc_reg_operand" "")))]
7061 "TARGET_FLOAT128"
7062 {
7063 rs6000_expand_float128_convert (operands[0], operands[1], false);
7064 DONE;
7065 })
7066
7067 (define_expand "floatuns<SDI:mode><IEEE128:mode>2"
7068 [(set (match_operand:IEEE128 0 "gpc_reg_operand" "")
7069 (unsigned_float:IEEE128 (match_operand:SDI 1 "gpc_reg_operand" "")))]
7070 "TARGET_FLOAT128"
7071 {
7072 rs6000_expand_float128_convert (operands[0], operands[1], true);
7073 DONE;
7074 })
7075
7076 (define_expand "neg<mode>2"
7077 [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
7078 (neg:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7079 "FLOAT128_IEEE_P (<MODE>mode)
7080 || (FLOAT128_IBM_P (<MODE>mode)
7081 && TARGET_HARD_FLOAT
7082 && (TARGET_FPRS || TARGET_E500_DOUBLE))"
7083 "
7084 {
7085 if (FLOAT128_IEEE_P (<MODE>mode))
7086 {
7087 if (TARGET_FLOAT128_HW)
7088 {
7089 if (<MODE>mode == TFmode)
7090 emit_insn (gen_negtf2_hw (operands[0], operands[1]));
7091 else if (<MODE>mode == KFmode)
7092 emit_insn (gen_negkf2_hw (operands[0], operands[1]));
7093 else
7094 gcc_unreachable ();
7095 }
7096 else if (TARGET_FLOAT128)
7097 {
7098 if (<MODE>mode == TFmode)
7099 emit_insn (gen_ieee_128bit_vsx_negtf2 (operands[0], operands[1]));
7100 else if (<MODE>mode == KFmode)
7101 emit_insn (gen_ieee_128bit_vsx_negkf2 (operands[0], operands[1]));
7102 else
7103 gcc_unreachable ();
7104 }
7105 else
7106 {
7107 rtx libfunc = optab_libfunc (neg_optab, <MODE>mode);
7108 rtx target = emit_library_call_value (libfunc, operands[0], LCT_CONST,
7109 <MODE>mode, 1,
7110 operands[1], <MODE>mode);
7111
7112 if (target && !rtx_equal_p (target, operands[0]))
7113 emit_move_insn (operands[0], target);
7114 }
7115 DONE;
7116 }
7117 }")
7118
7119 (define_insn "neg<mode>2_internal"
7120 [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d")
7121 (neg:IBM128 (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
7122 "TARGET_HARD_FLOAT && TARGET_FPRS && FLOAT128_IBM_P (TFmode)"
7123 "*
7124 {
7125 if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
7126 return \"fneg %L0,%L1\;fneg %0,%1\";
7127 else
7128 return \"fneg %0,%1\;fneg %L0,%L1\";
7129 }"
7130 [(set_attr "type" "fp")
7131 (set_attr "length" "8")])
7132
7133 (define_expand "abs<mode>2"
7134 [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
7135 (abs:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7136 "FLOAT128_IEEE_P (<MODE>mode)
7137 || (FLOAT128_IBM_P (<MODE>mode)
7138 && TARGET_HARD_FLOAT
7139 && (TARGET_FPRS || TARGET_E500_DOUBLE))"
7140 "
7141 {
7142 rtx label;
7143
7144 if (FLOAT128_IEEE_P (<MODE>mode))
7145 {
7146 if (TARGET_FLOAT128_HW)
7147 {
7148 if (<MODE>mode == TFmode)
7149 emit_insn (gen_abstf2_hw (operands[0], operands[1]));
7150 else if (<MODE>mode == KFmode)
7151 emit_insn (gen_abskf2_hw (operands[0], operands[1]));
7152 else
7153 FAIL;
7154 DONE;
7155 }
7156 else if (TARGET_FLOAT128)
7157 {
7158 if (<MODE>mode == TFmode)
7159 emit_insn (gen_ieee_128bit_vsx_abstf2 (operands[0], operands[1]));
7160 else if (<MODE>mode == KFmode)
7161 emit_insn (gen_ieee_128bit_vsx_abskf2 (operands[0], operands[1]));
7162 else
7163 FAIL;
7164 DONE;
7165 }
7166 else
7167 FAIL;
7168 }
7169
7170 label = gen_label_rtx ();
7171 if (TARGET_E500_DOUBLE && <MODE>mode == TFmode)
7172 {
7173 if (flag_finite_math_only && !flag_trapping_math)
7174 emit_insn (gen_spe_abstf2_tst (operands[0], operands[1], label));
7175 else
7176 emit_insn (gen_spe_abstf2_cmp (operands[0], operands[1], label));
7177 }
7178 else if (<MODE>mode == TFmode)
7179 emit_insn (gen_abstf2_internal (operands[0], operands[1], label));
7180 else if (<MODE>mode == TFmode)
7181 emit_insn (gen_absif2_internal (operands[0], operands[1], label));
7182 else
7183 FAIL;
7184 emit_label (label);
7185 DONE;
7186 }")
7187
7188 (define_expand "abs<mode>2_internal"
7189 [(set (match_operand:IBM128 0 "gpc_reg_operand" "")
7190 (match_operand:IBM128 1 "gpc_reg_operand" ""))
7191 (set (match_dup 3) (match_dup 5))
7192 (set (match_dup 5) (abs:DF (match_dup 5)))
7193 (set (match_dup 4) (compare:CCFP (match_dup 3) (match_dup 5)))
7194 (set (pc) (if_then_else (eq (match_dup 4) (const_int 0))
7195 (label_ref (match_operand 2 "" ""))
7196 (pc)))
7197 (set (match_dup 6) (neg:DF (match_dup 6)))]
7198 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
7199 && TARGET_LONG_DOUBLE_128"
7200 "
7201 {
7202 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7203 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7204 operands[3] = gen_reg_rtx (DFmode);
7205 operands[4] = gen_reg_rtx (CCFPmode);
7206 operands[5] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
7207 operands[6] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
7208 }")
7209
7210 \f
7211 ;; Generate IEEE 128-bit -0.0 (0x80000000000000000000000000000000) in a vector
7212 ;; register
7213
7214 (define_expand "ieee_128bit_negative_zero"
7215 [(set (match_operand:V16QI 0 "register_operand" "") (match_dup 1))]
7216 "TARGET_FLOAT128"
7217 {
7218 rtvec v = rtvec_alloc (16);
7219 int i, high;
7220
7221 for (i = 0; i < 16; i++)
7222 RTVEC_ELT (v, i) = const0_rtx;
7223
7224 high = (BYTES_BIG_ENDIAN) ? 0 : 15;
7225 RTVEC_ELT (v, high) = GEN_INT (0x80);
7226
7227 rs6000_expand_vector_init (operands[0], gen_rtx_PARALLEL (V16QImode, v));
7228 DONE;
7229 })
7230
7231 ;; IEEE 128-bit negate
7232
7233 ;; We have 2 insns here for negate and absolute value. The first uses
7234 ;; match_scratch so that phases like combine can recognize neg/abs as generic
7235 ;; insns, and second insn after the first split pass loads up the bit to
7236 ;; twiddle the sign bit. Later GCSE passes can then combine multiple uses of
7237 ;; neg/abs to create the constant just once.
7238
7239 (define_insn_and_split "ieee_128bit_vsx_neg<mode>2"
7240 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
7241 (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
7242 (clobber (match_scratch:V16QI 2 "=v"))]
7243 "TARGET_FLOAT128 && !TARGET_FLOAT128_HW"
7244 "#"
7245 "&& 1"
7246 [(parallel [(set (match_dup 0)
7247 (neg:IEEE128 (match_dup 1)))
7248 (use (match_dup 2))])]
7249 {
7250 if (GET_CODE (operands[2]) == SCRATCH)
7251 operands[2] = gen_reg_rtx (V16QImode);
7252
7253 operands[3] = gen_reg_rtx (V16QImode);
7254 emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
7255 }
7256 [(set_attr "length" "8")
7257 (set_attr "type" "vecsimple")])
7258
7259 (define_insn "*ieee_128bit_vsx_neg<mode>2_internal"
7260 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
7261 (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
7262 (use (match_operand:V16QI 2 "register_operand" "=v"))]
7263 "TARGET_FLOAT128 && !TARGET_FLOAT128_HW"
7264 "xxlxor %x0,%x1,%x2"
7265 [(set_attr "type" "vecsimple")])
7266
7267 ;; IEEE 128-bit absolute value
7268 (define_insn_and_split "ieee_128bit_vsx_abs<mode>2"
7269 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
7270 (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
7271 (clobber (match_scratch:V16QI 2 "=v"))]
7272 "TARGET_FLOAT128 && !TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
7273 "#"
7274 "&& 1"
7275 [(parallel [(set (match_dup 0)
7276 (abs:IEEE128 (match_dup 1)))
7277 (use (match_dup 2))])]
7278 {
7279 if (GET_CODE (operands[2]) == SCRATCH)
7280 operands[2] = gen_reg_rtx (V16QImode);
7281
7282 operands[3] = gen_reg_rtx (V16QImode);
7283 emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
7284 }
7285 [(set_attr "length" "8")
7286 (set_attr "type" "vecsimple")])
7287
7288 (define_insn "*ieee_128bit_vsx_abs<mode>2_internal"
7289 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
7290 (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
7291 (use (match_operand:V16QI 2 "register_operand" "=v"))]
7292 "TARGET_FLOAT128 && !TARGET_FLOAT128_HW"
7293 "xxlandc %x0,%x1,%x2"
7294 [(set_attr "type" "vecsimple")])
7295
7296 ;; IEEE 128-bit negative absolute value
7297 (define_insn_and_split "*ieee_128bit_vsx_nabs<mode>2"
7298 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
7299 (neg:IEEE128
7300 (abs:IEEE128
7301 (match_operand:IEEE128 1 "register_operand" "wa"))))
7302 (clobber (match_scratch:V16QI 2 "=v"))]
7303 "TARGET_FLOAT128 && !TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
7304 "#"
7305 "&& 1"
7306 [(parallel [(set (match_dup 0)
7307 (abs:IEEE128 (match_dup 1)))
7308 (use (match_dup 2))])]
7309 {
7310 if (GET_CODE (operands[2]) == SCRATCH)
7311 operands[2] = gen_reg_rtx (V16QImode);
7312
7313 operands[3] = gen_reg_rtx (V16QImode);
7314 emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
7315 }
7316 [(set_attr "length" "8")
7317 (set_attr "type" "vecsimple")])
7318
7319 (define_insn "*ieee_128bit_vsx_nabs<mode>2_internal"
7320 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
7321 (neg:IEEE128
7322 (abs:IEEE128
7323 (match_operand:IEEE128 1 "register_operand" "wa"))))
7324 (use (match_operand:V16QI 2 "register_operand" "=v"))]
7325 "TARGET_FLOAT128 && !TARGET_FLOAT128_HW"
7326 "xxlor %x0,%x1,%x2"
7327 [(set_attr "type" "vecsimple")])
7328
7329 ;; Float128 conversion functions. These expand to library function calls.
7330 ;; We use expand to convert from IBM double double to IEEE 128-bit
7331 ;; and trunc for the opposite.
7332 (define_expand "extendiftf2"
7333 [(set (match_operand:TF 0 "gpc_reg_operand" "")
7334 (float_extend:TF (match_operand:IF 1 "gpc_reg_operand" "")))]
7335 "TARGET_FLOAT128"
7336 {
7337 rs6000_expand_float128_convert (operands[0], operands[1], false);
7338 DONE;
7339 })
7340
7341 (define_expand "extendifkf2"
7342 [(set (match_operand:KF 0 "gpc_reg_operand" "")
7343 (float_extend:KF (match_operand:IF 1 "gpc_reg_operand" "")))]
7344 "TARGET_FLOAT128"
7345 {
7346 rs6000_expand_float128_convert (operands[0], operands[1], false);
7347 DONE;
7348 })
7349
7350 (define_expand "extendtfkf2"
7351 [(set (match_operand:KF 0 "gpc_reg_operand" "")
7352 (float_extend:KF (match_operand:TF 1 "gpc_reg_operand" "")))]
7353 "TARGET_FLOAT128"
7354 {
7355 rs6000_expand_float128_convert (operands[0], operands[1], false);
7356 DONE;
7357 })
7358
7359 (define_expand "trunciftf2"
7360 [(set (match_operand:IF 0 "gpc_reg_operand" "")
7361 (float_truncate:IF (match_operand:TF 1 "gpc_reg_operand" "")))]
7362 "TARGET_FLOAT128"
7363 {
7364 rs6000_expand_float128_convert (operands[0], operands[1], false);
7365 DONE;
7366 })
7367
7368 (define_expand "truncifkf2"
7369 [(set (match_operand:IF 0 "gpc_reg_operand" "")
7370 (float_truncate:IF (match_operand:KF 1 "gpc_reg_operand" "")))]
7371 "TARGET_FLOAT128"
7372 {
7373 rs6000_expand_float128_convert (operands[0], operands[1], false);
7374 DONE;
7375 })
7376
7377 (define_expand "trunckftf2"
7378 [(set (match_operand:TF 0 "gpc_reg_operand" "")
7379 (float_truncate:TF (match_operand:KF 1 "gpc_reg_operand" "")))]
7380 "TARGET_FLOAT128"
7381 {
7382 rs6000_expand_float128_convert (operands[0], operands[1], false);
7383 DONE;
7384 })
7385
7386 (define_expand "trunctfif2"
7387 [(set (match_operand:IF 0 "gpc_reg_operand" "")
7388 (float_truncate:IF (match_operand:TF 1 "gpc_reg_operand" "")))]
7389 "TARGET_FLOAT128"
7390 {
7391 rs6000_expand_float128_convert (operands[0], operands[1], false);
7392 DONE;
7393 })
7394
7395 \f
7396 ;; Reload helper functions used by rs6000_secondary_reload. The patterns all
7397 ;; must have 3 arguments, and scratch register constraint must be a single
7398 ;; constraint.
7399
7400 ;; Reload patterns to support gpr load/store with misaligned mem.
7401 ;; and multiple gpr load/store at offset >= 0xfffc
7402 (define_expand "reload_<mode>_store"
7403 [(parallel [(match_operand 0 "memory_operand" "=m")
7404 (match_operand 1 "gpc_reg_operand" "r")
7405 (match_operand:GPR 2 "register_operand" "=&b")])]
7406 ""
7407 {
7408 rs6000_secondary_reload_gpr (operands[1], operands[0], operands[2], true);
7409 DONE;
7410 })
7411
7412 (define_expand "reload_<mode>_load"
7413 [(parallel [(match_operand 0 "gpc_reg_operand" "=r")
7414 (match_operand 1 "memory_operand" "m")
7415 (match_operand:GPR 2 "register_operand" "=b")])]
7416 ""
7417 {
7418 rs6000_secondary_reload_gpr (operands[0], operands[1], operands[2], false);
7419 DONE;
7420 })
7421
7422 \f
7423 ;; Reload patterns for various types using the vector registers. We may need
7424 ;; an additional base register to convert the reg+offset addressing to reg+reg
7425 ;; for vector registers and reg+reg or (reg+reg)&(-16) addressing to just an
7426 ;; index register for gpr registers.
7427 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_store"
7428 [(parallel [(match_operand:RELOAD 0 "memory_operand" "m")
7429 (match_operand:RELOAD 1 "gpc_reg_operand" "wa")
7430 (match_operand:P 2 "register_operand" "=b")])]
7431 "<P:tptrsize>"
7432 {
7433 rs6000_secondary_reload_inner (operands[1], operands[0], operands[2], true);
7434 DONE;
7435 })
7436
7437 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_load"
7438 [(parallel [(match_operand:RELOAD 0 "gpc_reg_operand" "wa")
7439 (match_operand:RELOAD 1 "memory_operand" "m")
7440 (match_operand:P 2 "register_operand" "=b")])]
7441 "<P:tptrsize>"
7442 {
7443 rs6000_secondary_reload_inner (operands[0], operands[1], operands[2], false);
7444 DONE;
7445 })
7446
7447
7448 ;; Reload sometimes tries to move the address to a GPR, and can generate
7449 ;; invalid RTL for addresses involving AND -16. Allow addresses involving
7450 ;; reg+reg, reg+small constant, or just reg, all wrapped in an AND -16.
7451
7452 (define_insn_and_split "*vec_reload_and_plus_<mptrsize>"
7453 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
7454 (and:P (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
7455 (match_operand:P 2 "reg_or_cint_operand" "rI"))
7456 (const_int -16)))]
7457 "TARGET_ALTIVEC && (reload_in_progress || reload_completed)"
7458 "#"
7459 "&& reload_completed"
7460 [(set (match_dup 0)
7461 (plus:P (match_dup 1)
7462 (match_dup 2)))
7463 (set (match_dup 0)
7464 (and:P (match_dup 0)
7465 (const_int -16)))])
7466 \f
7467 ;; Power8 merge instructions to allow direct move to/from floating point
7468 ;; registers in 32-bit mode. We use TF mode to get two registers to move the
7469 ;; individual 32-bit parts across. Subreg doesn't work too well on the TF
7470 ;; value, since it is allocated in reload and not all of the flow information
7471 ;; is setup for it. We have two patterns to do the two moves between gprs and
7472 ;; fprs. There isn't a dependancy between the two, but we could potentially
7473 ;; schedule other instructions between the two instructions. TFmode is
7474 ;; currently limited to traditional FPR registers. If/when this is changed, we
7475 ;; will need to revist %L to make sure it works with VSX registers, or add an
7476 ;; %x version of %L.
7477
7478 (define_insn "p8_fmrgow_<mode>"
7479 [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
7480 (unspec:FMOVE64X [(match_operand:TF 1 "register_operand" "d")]
7481 UNSPEC_P8V_FMRGOW))]
7482 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7483 "fmrgow %0,%1,%L1"
7484 [(set_attr "type" "vecperm")])
7485
7486 (define_insn "p8_mtvsrwz_1"
7487 [(set (match_operand:TF 0 "register_operand" "=d")
7488 (unspec:TF [(match_operand:SI 1 "register_operand" "r")]
7489 UNSPEC_P8V_MTVSRWZ))]
7490 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7491 "mtvsrwz %x0,%1"
7492 [(set_attr "type" "mftgpr")])
7493
7494 (define_insn "p8_mtvsrwz_2"
7495 [(set (match_operand:TF 0 "register_operand" "+d")
7496 (unspec:TF [(match_dup 0)
7497 (match_operand:SI 1 "register_operand" "r")]
7498 UNSPEC_P8V_MTVSRWZ))]
7499 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7500 "mtvsrwz %L0,%1"
7501 [(set_attr "type" "mftgpr")])
7502
7503 (define_insn_and_split "reload_fpr_from_gpr<mode>"
7504 [(set (match_operand:FMOVE64X 0 "register_operand" "=ws")
7505 (unspec:FMOVE64X [(match_operand:FMOVE64X 1 "register_operand" "r")]
7506 UNSPEC_P8V_RELOAD_FROM_GPR))
7507 (clobber (match_operand:TF 2 "register_operand" "=d"))]
7508 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7509 "#"
7510 "&& reload_completed"
7511 [(const_int 0)]
7512 {
7513 rtx dest = operands[0];
7514 rtx src = operands[1];
7515 rtx tmp = operands[2];
7516 rtx gpr_hi_reg = gen_highpart (SImode, src);
7517 rtx gpr_lo_reg = gen_lowpart (SImode, src);
7518
7519 emit_insn (gen_p8_mtvsrwz_1 (tmp, gpr_hi_reg));
7520 emit_insn (gen_p8_mtvsrwz_2 (tmp, gpr_lo_reg));
7521 emit_insn (gen_p8_fmrgow_<mode> (dest, tmp));
7522 DONE;
7523 }
7524 [(set_attr "length" "12")
7525 (set_attr "type" "three")])
7526
7527 ;; Move 128 bit values from GPRs to VSX registers in 64-bit mode
7528 (define_insn "p8_mtvsrd_1"
7529 [(set (match_operand:TF 0 "register_operand" "=ws")
7530 (unspec:TF [(match_operand:DI 1 "register_operand" "r")]
7531 UNSPEC_P8V_MTVSRD))]
7532 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7533 "mtvsrd %0,%1"
7534 [(set_attr "type" "mftgpr")])
7535
7536 (define_insn "p8_mtvsrd_2"
7537 [(set (match_operand:TF 0 "register_operand" "+ws")
7538 (unspec:TF [(match_dup 0)
7539 (match_operand:DI 1 "register_operand" "r")]
7540 UNSPEC_P8V_MTVSRD))]
7541 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7542 "mtvsrd %L0,%1"
7543 [(set_attr "type" "mftgpr")])
7544
7545 (define_insn "p8_xxpermdi_<mode>"
7546 [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
7547 (unspec:FMOVE128_GPR [(match_operand:TF 1 "register_operand" "ws")]
7548 UNSPEC_P8V_XXPERMDI))]
7549 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7550 "xxpermdi %x0,%1,%L1,0"
7551 [(set_attr "type" "vecperm")])
7552
7553 (define_insn_and_split "reload_vsx_from_gpr<mode>"
7554 [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
7555 (unspec:FMOVE128_GPR
7556 [(match_operand:FMOVE128_GPR 1 "register_operand" "r")]
7557 UNSPEC_P8V_RELOAD_FROM_GPR))
7558 (clobber (match_operand:TF 2 "register_operand" "=ws"))]
7559 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7560 "#"
7561 "&& reload_completed"
7562 [(const_int 0)]
7563 {
7564 rtx dest = operands[0];
7565 rtx src = operands[1];
7566 rtx tmp = operands[2];
7567 rtx gpr_hi_reg = gen_highpart (DImode, src);
7568 rtx gpr_lo_reg = gen_lowpart (DImode, src);
7569
7570 emit_insn (gen_p8_mtvsrd_1 (tmp, gpr_hi_reg));
7571 emit_insn (gen_p8_mtvsrd_2 (tmp, gpr_lo_reg));
7572 emit_insn (gen_p8_xxpermdi_<mode> (dest, tmp));
7573 DONE;
7574 }
7575 [(set_attr "length" "12")
7576 (set_attr "type" "three")])
7577
7578 (define_split
7579 [(set (match_operand:FMOVE128_GPR 0 "nonimmediate_operand" "")
7580 (match_operand:FMOVE128_GPR 1 "input_operand" ""))]
7581 "reload_completed
7582 && (int_reg_operand (operands[0], <MODE>mode)
7583 || int_reg_operand (operands[1], <MODE>mode))
7584 && (!TARGET_DIRECT_MOVE_128
7585 || (!vsx_register_operand (operands[0], <MODE>mode)
7586 && !vsx_register_operand (operands[1], <MODE>mode)))"
7587 [(pc)]
7588 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
7589
7590 ;; Move SFmode to a VSX from a GPR register. Because scalar floating point
7591 ;; type is stored internally as double precision in the VSX registers, we have
7592 ;; to convert it from the vector format.
7593
7594 (define_insn_and_split "reload_vsx_from_gprsf"
7595 [(set (match_operand:SF 0 "register_operand" "=wa")
7596 (unspec:SF [(match_operand:SF 1 "register_operand" "r")]
7597 UNSPEC_P8V_RELOAD_FROM_GPR))
7598 (clobber (match_operand:DI 2 "register_operand" "=r"))]
7599 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7600 "#"
7601 "&& reload_completed"
7602 [(const_int 0)]
7603 {
7604 rtx op0 = operands[0];
7605 rtx op1 = operands[1];
7606 rtx op2 = operands[2];
7607 /* Also use the destination register to hold the unconverted DImode value.
7608 This is conceptually a separate value from OP0, so we use gen_rtx_REG
7609 rather than simplify_gen_subreg. */
7610 rtx op0_di = gen_rtx_REG (DImode, REGNO (op0));
7611 rtx op1_di = simplify_gen_subreg (DImode, op1, SFmode, 0);
7612
7613 /* Move SF value to upper 32-bits for xscvspdpn. */
7614 emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32)));
7615 emit_move_insn (op0_di, op2);
7616 emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0_di));
7617 DONE;
7618 }
7619 [(set_attr "length" "8")
7620 (set_attr "type" "two")])
7621
7622 ;; Move 128 bit values from VSX registers to GPRs in 64-bit mode by doing a
7623 ;; normal 64-bit move, followed by an xxpermdi to get the bottom 64-bit value,
7624 ;; and then doing a move of that.
7625 (define_insn "p8_mfvsrd_3_<mode>"
7626 [(set (match_operand:DF 0 "register_operand" "=r")
7627 (unspec:DF [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
7628 UNSPEC_P8V_RELOAD_FROM_VSX))]
7629 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7630 "mfvsrd %0,%x1"
7631 [(set_attr "type" "mftgpr")])
7632
7633 (define_insn_and_split "reload_gpr_from_vsx<mode>"
7634 [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=r")
7635 (unspec:FMOVE128_GPR
7636 [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
7637 UNSPEC_P8V_RELOAD_FROM_VSX))
7638 (clobber (match_operand:FMOVE128_GPR 2 "register_operand" "=wa"))]
7639 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7640 "#"
7641 "&& reload_completed"
7642 [(const_int 0)]
7643 {
7644 rtx dest = operands[0];
7645 rtx src = operands[1];
7646 rtx tmp = operands[2];
7647 rtx gpr_hi_reg = gen_highpart (DFmode, dest);
7648 rtx gpr_lo_reg = gen_lowpart (DFmode, dest);
7649
7650 emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_hi_reg, src));
7651 emit_insn (gen_vsx_xxpermdi_<mode> (tmp, src, src, GEN_INT (3)));
7652 emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_lo_reg, tmp));
7653 DONE;
7654 }
7655 [(set_attr "length" "12")
7656 (set_attr "type" "three")])
7657
7658 ;; Move SFmode to a GPR from a VSX register. Because scalar floating point
7659 ;; type is stored internally as double precision, we have to convert it to the
7660 ;; vector format.
7661
7662 (define_insn_and_split "reload_gpr_from_vsxsf"
7663 [(set (match_operand:SF 0 "register_operand" "=r")
7664 (unspec:SF [(match_operand:SF 1 "register_operand" "wa")]
7665 UNSPEC_P8V_RELOAD_FROM_VSX))
7666 (clobber (match_operand:V4SF 2 "register_operand" "=wa"))]
7667 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7668 "#"
7669 "&& reload_completed"
7670 [(const_int 0)]
7671 {
7672 rtx op0 = operands[0];
7673 rtx op1 = operands[1];
7674 rtx op2 = operands[2];
7675 rtx diop0 = simplify_gen_subreg (DImode, op0, SFmode, 0);
7676
7677 emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
7678 emit_insn (gen_p8_mfvsrd_4_disf (diop0, op2));
7679 emit_insn (gen_lshrdi3 (diop0, diop0, GEN_INT (32)));
7680 DONE;
7681 }
7682 [(set_attr "length" "12")
7683 (set_attr "type" "three")])
7684
7685 (define_insn "p8_mfvsrd_4_disf"
7686 [(set (match_operand:DI 0 "register_operand" "=r")
7687 (unspec:DI [(match_operand:V4SF 1 "register_operand" "wa")]
7688 UNSPEC_P8V_RELOAD_FROM_VSX))]
7689 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7690 "mfvsrd %0,%x1"
7691 [(set_attr "type" "mftgpr")])
7692
7693 \f
7694 ;; Next come the multi-word integer load and store and the load and store
7695 ;; multiple insns.
7696
7697 ;; List r->r after r->Y, otherwise reload will try to reload a
7698 ;; non-offsettable address by using r->r which won't make progress.
7699 ;; Use of fprs is disparaged slightly otherwise reload prefers to reload
7700 ;; a gpr into a fpr instead of reloading an invalid 'Y' address
7701 (define_insn "*movdi_internal32"
7702 [(set (match_operand:DI 0 "rs6000_nonimmediate_operand" "=Y,r,r,?m,?*d,?*d,r")
7703 (match_operand:DI 1 "input_operand" "r,Y,r,d,m,d,IJKnGHF"))]
7704 "! TARGET_POWERPC64
7705 && (gpc_reg_operand (operands[0], DImode)
7706 || gpc_reg_operand (operands[1], DImode))"
7707 "@
7708 #
7709 #
7710 #
7711 stfd%U0%X0 %1,%0
7712 lfd%U1%X1 %0,%1
7713 fmr %0,%1
7714 #"
7715 [(set_attr "type" "store,load,*,fpstore,fpload,fp,*")])
7716
7717 (define_split
7718 [(set (match_operand:DI 0 "gpc_reg_operand" "")
7719 (match_operand:DI 1 "const_int_operand" ""))]
7720 "! TARGET_POWERPC64 && reload_completed
7721 && gpr_or_gpr_p (operands[0], operands[1])
7722 && !direct_move_p (operands[0], operands[1])"
7723 [(set (match_dup 2) (match_dup 4))
7724 (set (match_dup 3) (match_dup 1))]
7725 "
7726 {
7727 HOST_WIDE_INT value = INTVAL (operands[1]);
7728 operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
7729 DImode);
7730 operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
7731 DImode);
7732 operands[4] = GEN_INT (value >> 32);
7733 operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
7734 }")
7735
7736 (define_split
7737 [(set (match_operand:DIFD 0 "rs6000_nonimmediate_operand" "")
7738 (match_operand:DIFD 1 "input_operand" ""))]
7739 "reload_completed && !TARGET_POWERPC64
7740 && gpr_or_gpr_p (operands[0], operands[1])
7741 && !direct_move_p (operands[0], operands[1])"
7742 [(pc)]
7743 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
7744
7745 (define_insn "*movdi_internal64"
7746 [(set (match_operand:DI 0 "nonimmediate_operand" "=Y,r,r,r,r,r,?m,?*d,?*d,r,*h,*h,r,?*wg,r,?*wj,?*wi")
7747 (match_operand:DI 1 "input_operand" "r,Y,r,I,L,nF,d,m,d,*h,r,0,*wg,r,*wj,r,O"))]
7748 "TARGET_POWERPC64
7749 && (gpc_reg_operand (operands[0], DImode)
7750 || gpc_reg_operand (operands[1], DImode))"
7751 "@
7752 std%U0%X0 %1,%0
7753 ld%U1%X1 %0,%1
7754 mr %0,%1
7755 li %0,%1
7756 lis %0,%v1
7757 #
7758 stfd%U0%X0 %1,%0
7759 lfd%U1%X1 %0,%1
7760 fmr %0,%1
7761 mf%1 %0
7762 mt%0 %1
7763 nop
7764 mftgpr %0,%1
7765 mffgpr %0,%1
7766 mfvsrd %0,%x1
7767 mtvsrd %x0,%1
7768 xxlxor %x0,%x0,%x0"
7769 [(set_attr "type" "store,load,*,*,*,*,fpstore,fpload,fp,mfjmpr,mtjmpr,*,mftgpr,mffgpr,mftgpr,mffgpr,vecsimple")
7770 (set_attr "length" "4,4,4,4,4,20,4,4,4,4,4,4,4,4,4,4,4")])
7771
7772 ; Some DImode loads are best done as a load of -1 followed by a mask
7773 ; instruction.
7774 (define_split
7775 [(set (match_operand:DI 0 "gpc_reg_operand")
7776 (match_operand:DI 1 "const_int_operand"))]
7777 "TARGET_POWERPC64
7778 && num_insns_constant (operands[1], DImode) > 1
7779 && rs6000_is_valid_and_mask (operands[1], DImode)"
7780 [(set (match_dup 0)
7781 (const_int -1))
7782 (set (match_dup 0)
7783 (and:DI (match_dup 0)
7784 (match_dup 1)))]
7785 "")
7786
7787 ;; Split a load of a large constant into the appropriate five-instruction
7788 ;; sequence. Handle anything in a constant number of insns.
7789 ;; When non-easy constants can go in the TOC, this should use
7790 ;; easy_fp_constant predicate.
7791 (define_split
7792 [(set (match_operand:DI 0 "gpc_reg_operand" "")
7793 (match_operand:DI 1 "const_int_operand" ""))]
7794 "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
7795 [(set (match_dup 0) (match_dup 2))
7796 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
7797 "
7798 {
7799 if (rs6000_emit_set_const (operands[0], operands[1]))
7800 DONE;
7801 else
7802 FAIL;
7803 }")
7804
7805 (define_split
7806 [(set (match_operand:DI 0 "gpc_reg_operand" "")
7807 (match_operand:DI 1 "const_scalar_int_operand" ""))]
7808 "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
7809 [(set (match_dup 0) (match_dup 2))
7810 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
7811 "
7812 {
7813 if (rs6000_emit_set_const (operands[0], operands[1]))
7814 DONE;
7815 else
7816 FAIL;
7817 }")
7818 \f
7819 ;; TImode/PTImode is similar, except that we usually want to compute the
7820 ;; address into a register and use lsi/stsi (the exception is during reload).
7821
7822 (define_insn "*mov<mode>_string"
7823 [(set (match_operand:TI2 0 "reg_or_mem_operand" "=Q,Y,????r,????r,????r,r")
7824 (match_operand:TI2 1 "input_operand" "r,r,Q,Y,r,n"))]
7825 "! TARGET_POWERPC64
7826 && (<MODE>mode != TImode || VECTOR_MEM_NONE_P (TImode))
7827 && (gpc_reg_operand (operands[0], <MODE>mode)
7828 || gpc_reg_operand (operands[1], <MODE>mode))"
7829 "*
7830 {
7831 switch (which_alternative)
7832 {
7833 default:
7834 gcc_unreachable ();
7835 case 0:
7836 if (TARGET_STRING)
7837 return \"stswi %1,%P0,16\";
7838 case 1:
7839 return \"#\";
7840 case 2:
7841 /* If the address is not used in the output, we can use lsi. Otherwise,
7842 fall through to generating four loads. */
7843 if (TARGET_STRING
7844 && ! reg_overlap_mentioned_p (operands[0], operands[1]))
7845 return \"lswi %0,%P1,16\";
7846 /* ... fall through ... */
7847 case 3:
7848 case 4:
7849 case 5:
7850 return \"#\";
7851 }
7852 }"
7853 [(set_attr "type" "store,store,load,load,*,*")
7854 (set_attr "update" "yes")
7855 (set_attr "indexed" "yes")
7856 (set (attr "cell_micro") (if_then_else (match_test "TARGET_STRING")
7857 (const_string "always")
7858 (const_string "conditional")))])
7859
7860 (define_insn "*mov<mode>_ppc64"
7861 [(set (match_operand:TI2 0 "nonimmediate_operand" "=wQ,Y,r,r,r,r")
7862 (match_operand:TI2 1 "input_operand" "r,r,wQ,Y,r,n"))]
7863 "(TARGET_POWERPC64 && VECTOR_MEM_NONE_P (<MODE>mode)
7864 && (gpc_reg_operand (operands[0], <MODE>mode)
7865 || gpc_reg_operand (operands[1], <MODE>mode)))"
7866 {
7867 return rs6000_output_move_128bit (operands);
7868 }
7869 [(set_attr "type" "store,store,load,load,*,*")
7870 (set_attr "length" "8")])
7871
7872 (define_split
7873 [(set (match_operand:TI2 0 "int_reg_operand" "")
7874 (match_operand:TI2 1 "const_scalar_int_operand" ""))]
7875 "TARGET_POWERPC64
7876 && (VECTOR_MEM_NONE_P (<MODE>mode)
7877 || (reload_completed && INT_REGNO_P (REGNO (operands[0]))))"
7878 [(set (match_dup 2) (match_dup 4))
7879 (set (match_dup 3) (match_dup 5))]
7880 "
7881 {
7882 operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
7883 <MODE>mode);
7884 operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
7885 <MODE>mode);
7886 if (CONST_WIDE_INT_P (operands[1]))
7887 {
7888 operands[4] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 1));
7889 operands[5] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 0));
7890 }
7891 else if (CONST_INT_P (operands[1]))
7892 {
7893 operands[4] = GEN_INT (- (INTVAL (operands[1]) < 0));
7894 operands[5] = operands[1];
7895 }
7896 else
7897 FAIL;
7898 }")
7899
7900 (define_split
7901 [(set (match_operand:TI2 0 "nonimmediate_operand" "")
7902 (match_operand:TI2 1 "input_operand" ""))]
7903 "reload_completed
7904 && gpr_or_gpr_p (operands[0], operands[1])
7905 && !direct_move_p (operands[0], operands[1])
7906 && !quad_load_store_p (operands[0], operands[1])"
7907 [(pc)]
7908 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
7909 \f
7910 (define_expand "load_multiple"
7911 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
7912 (match_operand:SI 1 "" ""))
7913 (use (match_operand:SI 2 "" ""))])]
7914 "TARGET_STRING && !TARGET_POWERPC64"
7915 "
7916 {
7917 int regno;
7918 int count;
7919 rtx op1;
7920 int i;
7921
7922 /* Support only loading a constant number of fixed-point registers from
7923 memory and only bother with this if more than two; the machine
7924 doesn't support more than eight. */
7925 if (GET_CODE (operands[2]) != CONST_INT
7926 || INTVAL (operands[2]) <= 2
7927 || INTVAL (operands[2]) > 8
7928 || GET_CODE (operands[1]) != MEM
7929 || GET_CODE (operands[0]) != REG
7930 || REGNO (operands[0]) >= 32)
7931 FAIL;
7932
7933 count = INTVAL (operands[2]);
7934 regno = REGNO (operands[0]);
7935
7936 operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
7937 op1 = replace_equiv_address (operands[1],
7938 force_reg (SImode, XEXP (operands[1], 0)));
7939
7940 for (i = 0; i < count; i++)
7941 XVECEXP (operands[3], 0, i)
7942 = gen_rtx_SET (gen_rtx_REG (SImode, regno + i),
7943 adjust_address_nv (op1, SImode, i * 4));
7944 }")
7945
7946 (define_insn "*ldmsi8"
7947 [(match_parallel 0 "load_multiple_operation"
7948 [(set (match_operand:SI 2 "gpc_reg_operand" "")
7949 (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
7950 (set (match_operand:SI 3 "gpc_reg_operand" "")
7951 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
7952 (set (match_operand:SI 4 "gpc_reg_operand" "")
7953 (mem:SI (plus:SI (match_dup 1) (const_int 8))))
7954 (set (match_operand:SI 5 "gpc_reg_operand" "")
7955 (mem:SI (plus:SI (match_dup 1) (const_int 12))))
7956 (set (match_operand:SI 6 "gpc_reg_operand" "")
7957 (mem:SI (plus:SI (match_dup 1) (const_int 16))))
7958 (set (match_operand:SI 7 "gpc_reg_operand" "")
7959 (mem:SI (plus:SI (match_dup 1) (const_int 20))))
7960 (set (match_operand:SI 8 "gpc_reg_operand" "")
7961 (mem:SI (plus:SI (match_dup 1) (const_int 24))))
7962 (set (match_operand:SI 9 "gpc_reg_operand" "")
7963 (mem:SI (plus:SI (match_dup 1) (const_int 28))))])]
7964 "TARGET_STRING && XVECLEN (operands[0], 0) == 8"
7965 "*
7966 { return rs6000_output_load_multiple (operands); }"
7967 [(set_attr "type" "load")
7968 (set_attr "update" "yes")
7969 (set_attr "indexed" "yes")
7970 (set_attr "length" "32")])
7971
7972 (define_insn "*ldmsi7"
7973 [(match_parallel 0 "load_multiple_operation"
7974 [(set (match_operand:SI 2 "gpc_reg_operand" "")
7975 (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
7976 (set (match_operand:SI 3 "gpc_reg_operand" "")
7977 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
7978 (set (match_operand:SI 4 "gpc_reg_operand" "")
7979 (mem:SI (plus:SI (match_dup 1) (const_int 8))))
7980 (set (match_operand:SI 5 "gpc_reg_operand" "")
7981 (mem:SI (plus:SI (match_dup 1) (const_int 12))))
7982 (set (match_operand:SI 6 "gpc_reg_operand" "")
7983 (mem:SI (plus:SI (match_dup 1) (const_int 16))))
7984 (set (match_operand:SI 7 "gpc_reg_operand" "")
7985 (mem:SI (plus:SI (match_dup 1) (const_int 20))))
7986 (set (match_operand:SI 8 "gpc_reg_operand" "")
7987 (mem:SI (plus:SI (match_dup 1) (const_int 24))))])]
7988 "TARGET_STRING && XVECLEN (operands[0], 0) == 7"
7989 "*
7990 { return rs6000_output_load_multiple (operands); }"
7991 [(set_attr "type" "load")
7992 (set_attr "update" "yes")
7993 (set_attr "indexed" "yes")
7994 (set_attr "length" "32")])
7995
7996 (define_insn "*ldmsi6"
7997 [(match_parallel 0 "load_multiple_operation"
7998 [(set (match_operand:SI 2 "gpc_reg_operand" "")
7999 (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8000 (set (match_operand:SI 3 "gpc_reg_operand" "")
8001 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8002 (set (match_operand:SI 4 "gpc_reg_operand" "")
8003 (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8004 (set (match_operand:SI 5 "gpc_reg_operand" "")
8005 (mem:SI (plus:SI (match_dup 1) (const_int 12))))
8006 (set (match_operand:SI 6 "gpc_reg_operand" "")
8007 (mem:SI (plus:SI (match_dup 1) (const_int 16))))
8008 (set (match_operand:SI 7 "gpc_reg_operand" "")
8009 (mem:SI (plus:SI (match_dup 1) (const_int 20))))])]
8010 "TARGET_STRING && XVECLEN (operands[0], 0) == 6"
8011 "*
8012 { return rs6000_output_load_multiple (operands); }"
8013 [(set_attr "type" "load")
8014 (set_attr "update" "yes")
8015 (set_attr "indexed" "yes")
8016 (set_attr "length" "32")])
8017
8018 (define_insn "*ldmsi5"
8019 [(match_parallel 0 "load_multiple_operation"
8020 [(set (match_operand:SI 2 "gpc_reg_operand" "")
8021 (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8022 (set (match_operand:SI 3 "gpc_reg_operand" "")
8023 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8024 (set (match_operand:SI 4 "gpc_reg_operand" "")
8025 (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8026 (set (match_operand:SI 5 "gpc_reg_operand" "")
8027 (mem:SI (plus:SI (match_dup 1) (const_int 12))))
8028 (set (match_operand:SI 6 "gpc_reg_operand" "")
8029 (mem:SI (plus:SI (match_dup 1) (const_int 16))))])]
8030 "TARGET_STRING && XVECLEN (operands[0], 0) == 5"
8031 "*
8032 { return rs6000_output_load_multiple (operands); }"
8033 [(set_attr "type" "load")
8034 (set_attr "update" "yes")
8035 (set_attr "indexed" "yes")
8036 (set_attr "length" "32")])
8037
8038 (define_insn "*ldmsi4"
8039 [(match_parallel 0 "load_multiple_operation"
8040 [(set (match_operand:SI 2 "gpc_reg_operand" "")
8041 (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8042 (set (match_operand:SI 3 "gpc_reg_operand" "")
8043 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8044 (set (match_operand:SI 4 "gpc_reg_operand" "")
8045 (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8046 (set (match_operand:SI 5 "gpc_reg_operand" "")
8047 (mem:SI (plus:SI (match_dup 1) (const_int 12))))])]
8048 "TARGET_STRING && XVECLEN (operands[0], 0) == 4"
8049 "*
8050 { return rs6000_output_load_multiple (operands); }"
8051 [(set_attr "type" "load")
8052 (set_attr "update" "yes")
8053 (set_attr "indexed" "yes")
8054 (set_attr "length" "32")])
8055
8056 (define_insn "*ldmsi3"
8057 [(match_parallel 0 "load_multiple_operation"
8058 [(set (match_operand:SI 2 "gpc_reg_operand" "")
8059 (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8060 (set (match_operand:SI 3 "gpc_reg_operand" "")
8061 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8062 (set (match_operand:SI 4 "gpc_reg_operand" "")
8063 (mem:SI (plus:SI (match_dup 1) (const_int 8))))])]
8064 "TARGET_STRING && XVECLEN (operands[0], 0) == 3"
8065 "*
8066 { return rs6000_output_load_multiple (operands); }"
8067 [(set_attr "type" "load")
8068 (set_attr "update" "yes")
8069 (set_attr "indexed" "yes")
8070 (set_attr "length" "32")])
8071
8072 (define_expand "store_multiple"
8073 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
8074 (match_operand:SI 1 "" ""))
8075 (clobber (scratch:SI))
8076 (use (match_operand:SI 2 "" ""))])]
8077 "TARGET_STRING && !TARGET_POWERPC64"
8078 "
8079 {
8080 int regno;
8081 int count;
8082 rtx to;
8083 rtx op0;
8084 int i;
8085
8086 /* Support only storing a constant number of fixed-point registers to
8087 memory and only bother with this if more than two; the machine
8088 doesn't support more than eight. */
8089 if (GET_CODE (operands[2]) != CONST_INT
8090 || INTVAL (operands[2]) <= 2
8091 || INTVAL (operands[2]) > 8
8092 || GET_CODE (operands[0]) != MEM
8093 || GET_CODE (operands[1]) != REG
8094 || REGNO (operands[1]) >= 32)
8095 FAIL;
8096
8097 count = INTVAL (operands[2]);
8098 regno = REGNO (operands[1]);
8099
8100 operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count + 1));
8101 to = force_reg (SImode, XEXP (operands[0], 0));
8102 op0 = replace_equiv_address (operands[0], to);
8103
8104 XVECEXP (operands[3], 0, 0)
8105 = gen_rtx_SET (adjust_address_nv (op0, SImode, 0), operands[1]);
8106 XVECEXP (operands[3], 0, 1) = gen_rtx_CLOBBER (VOIDmode,
8107 gen_rtx_SCRATCH (SImode));
8108
8109 for (i = 1; i < count; i++)
8110 XVECEXP (operands[3], 0, i + 1)
8111 = gen_rtx_SET (adjust_address_nv (op0, SImode, i * 4),
8112 gen_rtx_REG (SImode, regno + i));
8113 }")
8114
8115 (define_insn "*stmsi8"
8116 [(match_parallel 0 "store_multiple_operation"
8117 [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
8118 (match_operand:SI 2 "gpc_reg_operand" "r"))
8119 (clobber (match_scratch:SI 3 "=X"))
8120 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
8121 (match_operand:SI 4 "gpc_reg_operand" "r"))
8122 (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
8123 (match_operand:SI 5 "gpc_reg_operand" "r"))
8124 (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
8125 (match_operand:SI 6 "gpc_reg_operand" "r"))
8126 (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
8127 (match_operand:SI 7 "gpc_reg_operand" "r"))
8128 (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
8129 (match_operand:SI 8 "gpc_reg_operand" "r"))
8130 (set (mem:SI (plus:SI (match_dup 1) (const_int 24)))
8131 (match_operand:SI 9 "gpc_reg_operand" "r"))
8132 (set (mem:SI (plus:SI (match_dup 1) (const_int 28)))
8133 (match_operand:SI 10 "gpc_reg_operand" "r"))])]
8134 "TARGET_STRING && XVECLEN (operands[0], 0) == 9"
8135 "stswi %2,%1,%O0"
8136 [(set_attr "type" "store")
8137 (set_attr "update" "yes")
8138 (set_attr "indexed" "yes")
8139 (set_attr "cell_micro" "always")])
8140
8141 (define_insn "*stmsi7"
8142 [(match_parallel 0 "store_multiple_operation"
8143 [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
8144 (match_operand:SI 2 "gpc_reg_operand" "r"))
8145 (clobber (match_scratch:SI 3 "=X"))
8146 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
8147 (match_operand:SI 4 "gpc_reg_operand" "r"))
8148 (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
8149 (match_operand:SI 5 "gpc_reg_operand" "r"))
8150 (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
8151 (match_operand:SI 6 "gpc_reg_operand" "r"))
8152 (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
8153 (match_operand:SI 7 "gpc_reg_operand" "r"))
8154 (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
8155 (match_operand:SI 8 "gpc_reg_operand" "r"))
8156 (set (mem:SI (plus:SI (match_dup 1) (const_int 24)))
8157 (match_operand:SI 9 "gpc_reg_operand" "r"))])]
8158 "TARGET_STRING && XVECLEN (operands[0], 0) == 8"
8159 "stswi %2,%1,%O0"
8160 [(set_attr "type" "store")
8161 (set_attr "update" "yes")
8162 (set_attr "indexed" "yes")
8163 (set_attr "cell_micro" "always")])
8164
8165 (define_insn "*stmsi6"
8166 [(match_parallel 0 "store_multiple_operation"
8167 [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
8168 (match_operand:SI 2 "gpc_reg_operand" "r"))
8169 (clobber (match_scratch:SI 3 "=X"))
8170 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
8171 (match_operand:SI 4 "gpc_reg_operand" "r"))
8172 (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
8173 (match_operand:SI 5 "gpc_reg_operand" "r"))
8174 (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
8175 (match_operand:SI 6 "gpc_reg_operand" "r"))
8176 (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
8177 (match_operand:SI 7 "gpc_reg_operand" "r"))
8178 (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
8179 (match_operand:SI 8 "gpc_reg_operand" "r"))])]
8180 "TARGET_STRING && XVECLEN (operands[0], 0) == 7"
8181 "stswi %2,%1,%O0"
8182 [(set_attr "type" "store")
8183 (set_attr "update" "yes")
8184 (set_attr "indexed" "yes")
8185 (set_attr "cell_micro" "always")])
8186
8187 (define_insn "*stmsi5"
8188 [(match_parallel 0 "store_multiple_operation"
8189 [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
8190 (match_operand:SI 2 "gpc_reg_operand" "r"))
8191 (clobber (match_scratch:SI 3 "=X"))
8192 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
8193 (match_operand:SI 4 "gpc_reg_operand" "r"))
8194 (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
8195 (match_operand:SI 5 "gpc_reg_operand" "r"))
8196 (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
8197 (match_operand:SI 6 "gpc_reg_operand" "r"))
8198 (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
8199 (match_operand:SI 7 "gpc_reg_operand" "r"))])]
8200 "TARGET_STRING && XVECLEN (operands[0], 0) == 6"
8201 "stswi %2,%1,%O0"
8202 [(set_attr "type" "store")
8203 (set_attr "update" "yes")
8204 (set_attr "indexed" "yes")
8205 (set_attr "cell_micro" "always")])
8206
8207 (define_insn "*stmsi4"
8208 [(match_parallel 0 "store_multiple_operation"
8209 [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
8210 (match_operand:SI 2 "gpc_reg_operand" "r"))
8211 (clobber (match_scratch:SI 3 "=X"))
8212 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
8213 (match_operand:SI 4 "gpc_reg_operand" "r"))
8214 (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
8215 (match_operand:SI 5 "gpc_reg_operand" "r"))
8216 (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
8217 (match_operand:SI 6 "gpc_reg_operand" "r"))])]
8218 "TARGET_STRING && XVECLEN (operands[0], 0) == 5"
8219 "stswi %2,%1,%O0"
8220 [(set_attr "type" "store")
8221 (set_attr "update" "yes")
8222 (set_attr "indexed" "yes")
8223 (set_attr "cell_micro" "always")])
8224
8225 (define_insn "*stmsi3"
8226 [(match_parallel 0 "store_multiple_operation"
8227 [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
8228 (match_operand:SI 2 "gpc_reg_operand" "r"))
8229 (clobber (match_scratch:SI 3 "=X"))
8230 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
8231 (match_operand:SI 4 "gpc_reg_operand" "r"))
8232 (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
8233 (match_operand:SI 5 "gpc_reg_operand" "r"))])]
8234 "TARGET_STRING && XVECLEN (operands[0], 0) == 4"
8235 "stswi %2,%1,%O0"
8236 [(set_attr "type" "store")
8237 (set_attr "update" "yes")
8238 (set_attr "indexed" "yes")
8239 (set_attr "cell_micro" "always")])
8240 \f
8241 (define_expand "setmemsi"
8242 [(parallel [(set (match_operand:BLK 0 "" "")
8243 (match_operand 2 "const_int_operand" ""))
8244 (use (match_operand:SI 1 "" ""))
8245 (use (match_operand:SI 3 "" ""))])]
8246 ""
8247 "
8248 {
8249 /* If value to set is not zero, use the library routine. */
8250 if (operands[2] != const0_rtx)
8251 FAIL;
8252
8253 if (expand_block_clear (operands))
8254 DONE;
8255 else
8256 FAIL;
8257 }")
8258
8259 ;; String/block move insn.
8260 ;; Argument 0 is the destination
8261 ;; Argument 1 is the source
8262 ;; Argument 2 is the length
8263 ;; Argument 3 is the alignment
8264
8265 (define_expand "movmemsi"
8266 [(parallel [(set (match_operand:BLK 0 "" "")
8267 (match_operand:BLK 1 "" ""))
8268 (use (match_operand:SI 2 "" ""))
8269 (use (match_operand:SI 3 "" ""))])]
8270 ""
8271 "
8272 {
8273 if (expand_block_move (operands))
8274 DONE;
8275 else
8276 FAIL;
8277 }")
8278
8279 ;; Move up to 32 bytes at a time. The fixed registers are needed because the
8280 ;; register allocator doesn't have a clue about allocating 8 word registers.
8281 ;; rD/rS = r5 is preferred, efficient form.
8282 (define_expand "movmemsi_8reg"
8283 [(parallel [(set (match_operand 0 "" "")
8284 (match_operand 1 "" ""))
8285 (use (match_operand 2 "" ""))
8286 (use (match_operand 3 "" ""))
8287 (clobber (reg:SI 5))
8288 (clobber (reg:SI 6))
8289 (clobber (reg:SI 7))
8290 (clobber (reg:SI 8))
8291 (clobber (reg:SI 9))
8292 (clobber (reg:SI 10))
8293 (clobber (reg:SI 11))
8294 (clobber (reg:SI 12))
8295 (clobber (match_scratch:SI 4 ""))])]
8296 "TARGET_STRING"
8297 "")
8298
8299 (define_insn ""
8300 [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
8301 (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
8302 (use (match_operand:SI 2 "immediate_operand" "i"))
8303 (use (match_operand:SI 3 "immediate_operand" "i"))
8304 (clobber (match_operand:SI 4 "gpc_reg_operand" "=&r"))
8305 (clobber (reg:SI 6))
8306 (clobber (reg:SI 7))
8307 (clobber (reg:SI 8))
8308 (clobber (reg:SI 9))
8309 (clobber (reg:SI 10))
8310 (clobber (reg:SI 11))
8311 (clobber (reg:SI 12))
8312 (clobber (match_scratch:SI 5 "=X"))]
8313 "TARGET_STRING
8314 && ((INTVAL (operands[2]) > 24 && INTVAL (operands[2]) < 32)
8315 || INTVAL (operands[2]) == 0)
8316 && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 12)
8317 && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 12)
8318 && REGNO (operands[4]) == 5"
8319 "lswi %4,%1,%2\;stswi %4,%0,%2"
8320 [(set_attr "type" "store")
8321 (set_attr "update" "yes")
8322 (set_attr "indexed" "yes")
8323 (set_attr "cell_micro" "always")
8324 (set_attr "length" "8")])
8325
8326 ;; Move up to 24 bytes at a time. The fixed registers are needed because the
8327 ;; register allocator doesn't have a clue about allocating 6 word registers.
8328 ;; rD/rS = r5 is preferred, efficient form.
8329 (define_expand "movmemsi_6reg"
8330 [(parallel [(set (match_operand 0 "" "")
8331 (match_operand 1 "" ""))
8332 (use (match_operand 2 "" ""))
8333 (use (match_operand 3 "" ""))
8334 (clobber (reg:SI 5))
8335 (clobber (reg:SI 6))
8336 (clobber (reg:SI 7))
8337 (clobber (reg:SI 8))
8338 (clobber (reg:SI 9))
8339 (clobber (reg:SI 10))
8340 (clobber (match_scratch:SI 4 ""))])]
8341 "TARGET_STRING"
8342 "")
8343
8344 (define_insn ""
8345 [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
8346 (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
8347 (use (match_operand:SI 2 "immediate_operand" "i"))
8348 (use (match_operand:SI 3 "immediate_operand" "i"))
8349 (clobber (match_operand:SI 4 "gpc_reg_operand" "=&r"))
8350 (clobber (reg:SI 6))
8351 (clobber (reg:SI 7))
8352 (clobber (reg:SI 8))
8353 (clobber (reg:SI 9))
8354 (clobber (reg:SI 10))
8355 (clobber (match_scratch:SI 5 "=X"))]
8356 "TARGET_STRING
8357 && INTVAL (operands[2]) > 16 && INTVAL (operands[2]) <= 32
8358 && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 10)
8359 && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 10)
8360 && REGNO (operands[4]) == 5"
8361 "lswi %4,%1,%2\;stswi %4,%0,%2"
8362 [(set_attr "type" "store")
8363 (set_attr "update" "yes")
8364 (set_attr "indexed" "yes")
8365 (set_attr "cell_micro" "always")
8366 (set_attr "length" "8")])
8367
8368 ;; Move up to 16 bytes at a time, using 4 fixed registers to avoid spill
8369 ;; problems with TImode.
8370 ;; rD/rS = r5 is preferred, efficient form.
8371 (define_expand "movmemsi_4reg"
8372 [(parallel [(set (match_operand 0 "" "")
8373 (match_operand 1 "" ""))
8374 (use (match_operand 2 "" ""))
8375 (use (match_operand 3 "" ""))
8376 (clobber (reg:SI 5))
8377 (clobber (reg:SI 6))
8378 (clobber (reg:SI 7))
8379 (clobber (reg:SI 8))
8380 (clobber (match_scratch:SI 4 ""))])]
8381 "TARGET_STRING"
8382 "")
8383
8384 (define_insn ""
8385 [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
8386 (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
8387 (use (match_operand:SI 2 "immediate_operand" "i"))
8388 (use (match_operand:SI 3 "immediate_operand" "i"))
8389 (clobber (match_operand:SI 4 "gpc_reg_operand" "=&r"))
8390 (clobber (reg:SI 6))
8391 (clobber (reg:SI 7))
8392 (clobber (reg:SI 8))
8393 (clobber (match_scratch:SI 5 "=X"))]
8394 "TARGET_STRING
8395 && INTVAL (operands[2]) > 8 && INTVAL (operands[2]) <= 16
8396 && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 8)
8397 && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 8)
8398 && REGNO (operands[4]) == 5"
8399 "lswi %4,%1,%2\;stswi %4,%0,%2"
8400 [(set_attr "type" "store")
8401 (set_attr "update" "yes")
8402 (set_attr "indexed" "yes")
8403 (set_attr "cell_micro" "always")
8404 (set_attr "length" "8")])
8405
8406 ;; Move up to 8 bytes at a time.
8407 (define_expand "movmemsi_2reg"
8408 [(parallel [(set (match_operand 0 "" "")
8409 (match_operand 1 "" ""))
8410 (use (match_operand 2 "" ""))
8411 (use (match_operand 3 "" ""))
8412 (clobber (match_scratch:DI 4 ""))
8413 (clobber (match_scratch:SI 5 ""))])]
8414 "TARGET_STRING && ! TARGET_POWERPC64"
8415 "")
8416
8417 (define_insn ""
8418 [(set (mem:BLK (match_operand:SI 0 "gpc_reg_operand" "b"))
8419 (mem:BLK (match_operand:SI 1 "gpc_reg_operand" "b")))
8420 (use (match_operand:SI 2 "immediate_operand" "i"))
8421 (use (match_operand:SI 3 "immediate_operand" "i"))
8422 (clobber (match_scratch:DI 4 "=&r"))
8423 (clobber (match_scratch:SI 5 "=X"))]
8424 "TARGET_STRING && ! TARGET_POWERPC64
8425 && INTVAL (operands[2]) > 4 && INTVAL (operands[2]) <= 8"
8426 "lswi %4,%1,%2\;stswi %4,%0,%2"
8427 [(set_attr "type" "store")
8428 (set_attr "update" "yes")
8429 (set_attr "indexed" "yes")
8430 (set_attr "cell_micro" "always")
8431 (set_attr "length" "8")])
8432
8433 ;; Move up to 4 bytes at a time.
8434 (define_expand "movmemsi_1reg"
8435 [(parallel [(set (match_operand 0 "" "")
8436 (match_operand 1 "" ""))
8437 (use (match_operand 2 "" ""))
8438 (use (match_operand 3 "" ""))
8439 (clobber (match_scratch:SI 4 ""))
8440 (clobber (match_scratch:SI 5 ""))])]
8441 "TARGET_STRING"
8442 "")
8443
8444 (define_insn ""
8445 [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
8446 (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
8447 (use (match_operand:SI 2 "immediate_operand" "i"))
8448 (use (match_operand:SI 3 "immediate_operand" "i"))
8449 (clobber (match_scratch:SI 4 "=&r"))
8450 (clobber (match_scratch:SI 5 "=X"))]
8451 "TARGET_STRING && INTVAL (operands[2]) > 0 && INTVAL (operands[2]) <= 4"
8452 "lswi %4,%1,%2\;stswi %4,%0,%2"
8453 [(set_attr "type" "store")
8454 (set_attr "update" "yes")
8455 (set_attr "indexed" "yes")
8456 (set_attr "cell_micro" "always")
8457 (set_attr "length" "8")])
8458 \f
8459 ;; Define insns that do load or store with update. Some of these we can
8460 ;; get by using pre-decrement or pre-increment, but the hardware can also
8461 ;; do cases where the increment is not the size of the object.
8462 ;;
8463 ;; In all these cases, we use operands 0 and 1 for the register being
8464 ;; incremented because those are the operands that local-alloc will
8465 ;; tie and these are the pair most likely to be tieable (and the ones
8466 ;; that will benefit the most).
8467
8468 (define_insn "*movdi_update1"
8469 [(set (match_operand:DI 3 "gpc_reg_operand" "=r,r")
8470 (mem:DI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0,0")
8471 (match_operand:DI 2 "reg_or_aligned_short_operand" "r,I"))))
8472 (set (match_operand:DI 0 "gpc_reg_operand" "=b,b")
8473 (plus:DI (match_dup 1) (match_dup 2)))]
8474 "TARGET_POWERPC64 && TARGET_UPDATE
8475 && (!avoiding_indexed_address_p (DImode)
8476 || !gpc_reg_operand (operands[2], DImode))"
8477 "@
8478 ldux %3,%0,%2
8479 ldu %3,%2(%0)"
8480 [(set_attr "type" "load")
8481 (set_attr "update" "yes")
8482 (set_attr "indexed" "yes,no")])
8483
8484 (define_insn "movdi_<mode>_update"
8485 [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
8486 (match_operand:P 2 "reg_or_aligned_short_operand" "r,I")))
8487 (match_operand:DI 3 "gpc_reg_operand" "r,r"))
8488 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
8489 (plus:P (match_dup 1) (match_dup 2)))]
8490 "TARGET_POWERPC64 && TARGET_UPDATE
8491 && (!avoiding_indexed_address_p (Pmode)
8492 || !gpc_reg_operand (operands[2], Pmode)
8493 || (REG_P (operands[0])
8494 && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
8495 "@
8496 stdux %3,%0,%2
8497 stdu %3,%2(%0)"
8498 [(set_attr "type" "store")
8499 (set_attr "update" "yes")
8500 (set_attr "indexed" "yes,no")])
8501
8502 ;; This pattern is only conditional on TARGET_POWERPC64, as it is
8503 ;; needed for stack allocation, even if the user passes -mno-update.
8504 (define_insn "movdi_<mode>_update_stack"
8505 [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
8506 (match_operand:P 2 "reg_or_aligned_short_operand" "r,I")))
8507 (match_operand:DI 3 "gpc_reg_operand" "r,r"))
8508 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
8509 (plus:P (match_dup 1) (match_dup 2)))]
8510 "TARGET_POWERPC64"
8511 "@
8512 stdux %3,%0,%2
8513 stdu %3,%2(%0)"
8514 [(set_attr "type" "store")
8515 (set_attr "update" "yes")
8516 (set_attr "indexed" "yes,no")])
8517
8518 (define_insn "*movsi_update1"
8519 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
8520 (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8521 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
8522 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8523 (plus:SI (match_dup 1) (match_dup 2)))]
8524 "TARGET_UPDATE
8525 && (!avoiding_indexed_address_p (SImode)
8526 || !gpc_reg_operand (operands[2], SImode))"
8527 "@
8528 lwzux %3,%0,%2
8529 lwzu %3,%2(%0)"
8530 [(set_attr "type" "load")
8531 (set_attr "update" "yes")
8532 (set_attr "indexed" "yes,no")])
8533
8534 (define_insn "*movsi_update2"
8535 [(set (match_operand:DI 3 "gpc_reg_operand" "=r")
8536 (sign_extend:DI
8537 (mem:SI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0")
8538 (match_operand:DI 2 "gpc_reg_operand" "r")))))
8539 (set (match_operand:DI 0 "gpc_reg_operand" "=b")
8540 (plus:DI (match_dup 1) (match_dup 2)))]
8541 "TARGET_POWERPC64 && rs6000_gen_cell_microcode
8542 && !avoiding_indexed_address_p (DImode)"
8543 "lwaux %3,%0,%2"
8544 [(set_attr "type" "load")
8545 (set_attr "sign_extend" "yes")
8546 (set_attr "update" "yes")
8547 (set_attr "indexed" "yes")])
8548
8549 (define_insn "movsi_update"
8550 [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8551 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
8552 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
8553 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8554 (plus:SI (match_dup 1) (match_dup 2)))]
8555 "TARGET_UPDATE
8556 && (!avoiding_indexed_address_p (SImode)
8557 || !gpc_reg_operand (operands[2], SImode)
8558 || (REG_P (operands[0])
8559 && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
8560 "@
8561 stwux %3,%0,%2
8562 stwu %3,%2(%0)"
8563 [(set_attr "type" "store")
8564 (set_attr "update" "yes")
8565 (set_attr "indexed" "yes,no")])
8566
8567 ;; This is an unconditional pattern; needed for stack allocation, even
8568 ;; if the user passes -mno-update.
8569 (define_insn "movsi_update_stack"
8570 [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8571 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
8572 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
8573 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8574 (plus:SI (match_dup 1) (match_dup 2)))]
8575 ""
8576 "@
8577 stwux %3,%0,%2
8578 stwu %3,%2(%0)"
8579 [(set_attr "type" "store")
8580 (set_attr "update" "yes")
8581 (set_attr "indexed" "yes,no")])
8582
8583 (define_insn "*movhi_update1"
8584 [(set (match_operand:HI 3 "gpc_reg_operand" "=r,r")
8585 (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8586 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
8587 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8588 (plus:SI (match_dup 1) (match_dup 2)))]
8589 "TARGET_UPDATE
8590 && (!avoiding_indexed_address_p (SImode)
8591 || !gpc_reg_operand (operands[2], SImode))"
8592 "@
8593 lhzux %3,%0,%2
8594 lhzu %3,%2(%0)"
8595 [(set_attr "type" "load")
8596 (set_attr "update" "yes")
8597 (set_attr "indexed" "yes,no")])
8598
8599 (define_insn "*movhi_update2"
8600 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
8601 (zero_extend:SI
8602 (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8603 (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
8604 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8605 (plus:SI (match_dup 1) (match_dup 2)))]
8606 "TARGET_UPDATE
8607 && (!avoiding_indexed_address_p (SImode)
8608 || !gpc_reg_operand (operands[2], SImode))"
8609 "@
8610 lhzux %3,%0,%2
8611 lhzu %3,%2(%0)"
8612 [(set_attr "type" "load")
8613 (set_attr "update" "yes")
8614 (set_attr "indexed" "yes,no")])
8615
8616 (define_insn "*movhi_update3"
8617 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
8618 (sign_extend:SI
8619 (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8620 (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
8621 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8622 (plus:SI (match_dup 1) (match_dup 2)))]
8623 "TARGET_UPDATE && rs6000_gen_cell_microcode
8624 && (!avoiding_indexed_address_p (SImode)
8625 || !gpc_reg_operand (operands[2], SImode))"
8626 "@
8627 lhaux %3,%0,%2
8628 lhau %3,%2(%0)"
8629 [(set_attr "type" "load")
8630 (set_attr "sign_extend" "yes")
8631 (set_attr "update" "yes")
8632 (set_attr "indexed" "yes,no")])
8633
8634 (define_insn "*movhi_update4"
8635 [(set (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8636 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
8637 (match_operand:HI 3 "gpc_reg_operand" "r,r"))
8638 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8639 (plus:SI (match_dup 1) (match_dup 2)))]
8640 "TARGET_UPDATE
8641 && (!avoiding_indexed_address_p (SImode)
8642 || !gpc_reg_operand (operands[2], SImode))"
8643 "@
8644 sthux %3,%0,%2
8645 sthu %3,%2(%0)"
8646 [(set_attr "type" "store")
8647 (set_attr "update" "yes")
8648 (set_attr "indexed" "yes,no")])
8649
8650 (define_insn "*movqi_update1"
8651 [(set (match_operand:QI 3 "gpc_reg_operand" "=r,r")
8652 (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8653 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
8654 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8655 (plus:SI (match_dup 1) (match_dup 2)))]
8656 "TARGET_UPDATE
8657 && (!avoiding_indexed_address_p (SImode)
8658 || !gpc_reg_operand (operands[2], SImode))"
8659 "@
8660 lbzux %3,%0,%2
8661 lbzu %3,%2(%0)"
8662 [(set_attr "type" "load")
8663 (set_attr "update" "yes")
8664 (set_attr "indexed" "yes,no")])
8665
8666 (define_insn "*movqi_update2"
8667 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
8668 (zero_extend:SI
8669 (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8670 (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
8671 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8672 (plus:SI (match_dup 1) (match_dup 2)))]
8673 "TARGET_UPDATE
8674 && (!avoiding_indexed_address_p (SImode)
8675 || !gpc_reg_operand (operands[2], SImode))"
8676 "@
8677 lbzux %3,%0,%2
8678 lbzu %3,%2(%0)"
8679 [(set_attr "type" "load")
8680 (set_attr "update" "yes")
8681 (set_attr "indexed" "yes,no")])
8682
8683 (define_insn "*movqi_update3"
8684 [(set (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8685 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
8686 (match_operand:QI 3 "gpc_reg_operand" "r,r"))
8687 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8688 (plus:SI (match_dup 1) (match_dup 2)))]
8689 "TARGET_UPDATE
8690 && (!avoiding_indexed_address_p (SImode)
8691 || !gpc_reg_operand (operands[2], SImode))"
8692 "@
8693 stbux %3,%0,%2
8694 stbu %3,%2(%0)"
8695 [(set_attr "type" "store")
8696 (set_attr "update" "yes")
8697 (set_attr "indexed" "yes,no")])
8698
8699 (define_insn "*movsf_update1"
8700 [(set (match_operand:SF 3 "gpc_reg_operand" "=f,f")
8701 (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8702 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
8703 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8704 (plus:SI (match_dup 1) (match_dup 2)))]
8705 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT && TARGET_UPDATE
8706 && (!avoiding_indexed_address_p (SImode)
8707 || !gpc_reg_operand (operands[2], SImode))"
8708 "@
8709 lfsux %3,%0,%2
8710 lfsu %3,%2(%0)"
8711 [(set_attr "type" "fpload")
8712 (set_attr "update" "yes")
8713 (set_attr "indexed" "yes,no")])
8714
8715 (define_insn "*movsf_update2"
8716 [(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8717 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
8718 (match_operand:SF 3 "gpc_reg_operand" "f,f"))
8719 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8720 (plus:SI (match_dup 1) (match_dup 2)))]
8721 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT && TARGET_UPDATE
8722 && (!avoiding_indexed_address_p (SImode)
8723 || !gpc_reg_operand (operands[2], SImode))"
8724 "@
8725 stfsux %3,%0,%2
8726 stfsu %3,%2(%0)"
8727 [(set_attr "type" "fpstore")
8728 (set_attr "update" "yes")
8729 (set_attr "indexed" "yes,no")])
8730
8731 (define_insn "*movsf_update3"
8732 [(set (match_operand:SF 3 "gpc_reg_operand" "=r,r")
8733 (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8734 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
8735 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8736 (plus:SI (match_dup 1) (match_dup 2)))]
8737 "(TARGET_SOFT_FLOAT || !TARGET_FPRS) && TARGET_UPDATE
8738 && (!avoiding_indexed_address_p (SImode)
8739 || !gpc_reg_operand (operands[2], SImode))"
8740 "@
8741 lwzux %3,%0,%2
8742 lwzu %3,%2(%0)"
8743 [(set_attr "type" "load")
8744 (set_attr "update" "yes")
8745 (set_attr "indexed" "yes,no")])
8746
8747 (define_insn "*movsf_update4"
8748 [(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8749 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
8750 (match_operand:SF 3 "gpc_reg_operand" "r,r"))
8751 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8752 (plus:SI (match_dup 1) (match_dup 2)))]
8753 "(TARGET_SOFT_FLOAT || !TARGET_FPRS) && TARGET_UPDATE
8754 && (!avoiding_indexed_address_p (SImode)
8755 || !gpc_reg_operand (operands[2], SImode))"
8756 "@
8757 stwux %3,%0,%2
8758 stwu %3,%2(%0)"
8759 [(set_attr "type" "store")
8760 (set_attr "update" "yes")
8761 (set_attr "indexed" "yes,no")])
8762
8763 (define_insn "*movdf_update1"
8764 [(set (match_operand:DF 3 "gpc_reg_operand" "=d,d")
8765 (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8766 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
8767 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8768 (plus:SI (match_dup 1) (match_dup 2)))]
8769 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_UPDATE
8770 && (!avoiding_indexed_address_p (SImode)
8771 || !gpc_reg_operand (operands[2], SImode))"
8772 "@
8773 lfdux %3,%0,%2
8774 lfdu %3,%2(%0)"
8775 [(set_attr "type" "fpload")
8776 (set_attr "update" "yes")
8777 (set_attr "indexed" "yes,no")])
8778
8779 (define_insn "*movdf_update2"
8780 [(set (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8781 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
8782 (match_operand:DF 3 "gpc_reg_operand" "d,d"))
8783 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8784 (plus:SI (match_dup 1) (match_dup 2)))]
8785 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_UPDATE
8786 && (!avoiding_indexed_address_p (SImode)
8787 || !gpc_reg_operand (operands[2], SImode))"
8788 "@
8789 stfdux %3,%0,%2
8790 stfdu %3,%2(%0)"
8791 [(set_attr "type" "fpstore")
8792 (set_attr "update" "yes")
8793 (set_attr "indexed" "yes,no")])
8794
8795
8796 ;; After inserting conditional returns we can sometimes have
8797 ;; unnecessary register moves. Unfortunately we cannot have a
8798 ;; modeless peephole here, because some single SImode sets have early
8799 ;; clobber outputs. Although those sets expand to multi-ppc-insn
8800 ;; sequences, using get_attr_length here will smash the operands
8801 ;; array. Neither is there an early_cobbler_p predicate.
8802 ;; Disallow subregs for E500 so we don't munge frob_di_df_2.
8803 ;; Also this optimization interferes with scalars going into
8804 ;; altivec registers (the code does reloading through the FPRs).
8805 (define_peephole2
8806 [(set (match_operand:DF 0 "gpc_reg_operand" "")
8807 (match_operand:DF 1 "any_operand" ""))
8808 (set (match_operand:DF 2 "gpc_reg_operand" "")
8809 (match_dup 0))]
8810 "!(TARGET_E500_DOUBLE && GET_CODE (operands[2]) == SUBREG)
8811 && !TARGET_UPPER_REGS_DF
8812 && peep2_reg_dead_p (2, operands[0])"
8813 [(set (match_dup 2) (match_dup 1))])
8814
8815 (define_peephole2
8816 [(set (match_operand:SF 0 "gpc_reg_operand" "")
8817 (match_operand:SF 1 "any_operand" ""))
8818 (set (match_operand:SF 2 "gpc_reg_operand" "")
8819 (match_dup 0))]
8820 "!TARGET_UPPER_REGS_SF
8821 && peep2_reg_dead_p (2, operands[0])"
8822 [(set (match_dup 2) (match_dup 1))])
8823
8824 \f
8825 ;; TLS support.
8826
8827 ;; Mode attributes for different ABIs.
8828 (define_mode_iterator TLSmode [(SI "! TARGET_64BIT") (DI "TARGET_64BIT")])
8829 (define_mode_attr tls_abi_suffix [(SI "32") (DI "64")])
8830 (define_mode_attr tls_sysv_suffix [(SI "si") (DI "di")])
8831 (define_mode_attr tls_insn_suffix [(SI "wz") (DI "d")])
8832
8833 (define_insn_and_split "tls_gd_aix<TLSmode:tls_abi_suffix>"
8834 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
8835 (call (mem:TLSmode (match_operand:TLSmode 3 "symbol_ref_operand" "s"))
8836 (match_operand 4 "" "g")))
8837 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
8838 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
8839 UNSPEC_TLSGD)
8840 (clobber (reg:SI LR_REGNO))]
8841 "HAVE_AS_TLS && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
8842 {
8843 if (TARGET_CMODEL != CMODEL_SMALL)
8844 return "addis %0,%1,%2@got@tlsgd@ha\;addi %0,%0,%2@got@tlsgd@l\;"
8845 "bl %z3\;nop";
8846 else
8847 return "addi %0,%1,%2@got@tlsgd\;bl %z3\;nop";
8848 }
8849 "&& TARGET_TLS_MARKERS"
8850 [(set (match_dup 0)
8851 (unspec:TLSmode [(match_dup 1)
8852 (match_dup 2)]
8853 UNSPEC_TLSGD))
8854 (parallel [(set (match_dup 0)
8855 (call (mem:TLSmode (match_dup 3))
8856 (match_dup 4)))
8857 (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGD)
8858 (clobber (reg:SI LR_REGNO))])]
8859 ""
8860 [(set_attr "type" "two")
8861 (set (attr "length")
8862 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
8863 (const_int 16)
8864 (const_int 12)))])
8865
8866 (define_insn_and_split "tls_gd_sysv<TLSmode:tls_sysv_suffix>"
8867 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
8868 (call (mem:TLSmode (match_operand:TLSmode 3 "symbol_ref_operand" "s"))
8869 (match_operand 4 "" "g")))
8870 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
8871 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
8872 UNSPEC_TLSGD)
8873 (clobber (reg:SI LR_REGNO))]
8874 "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4"
8875 {
8876 if (flag_pic)
8877 {
8878 if (TARGET_SECURE_PLT && flag_pic == 2)
8879 return "addi %0,%1,%2@got@tlsgd\;bl %z3+32768@plt";
8880 else
8881 return "addi %0,%1,%2@got@tlsgd\;bl %z3@plt";
8882 }
8883 else
8884 return "addi %0,%1,%2@got@tlsgd\;bl %z3";
8885 }
8886 "&& TARGET_TLS_MARKERS"
8887 [(set (match_dup 0)
8888 (unspec:TLSmode [(match_dup 1)
8889 (match_dup 2)]
8890 UNSPEC_TLSGD))
8891 (parallel [(set (match_dup 0)
8892 (call (mem:TLSmode (match_dup 3))
8893 (match_dup 4)))
8894 (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGD)
8895 (clobber (reg:SI LR_REGNO))])]
8896 ""
8897 [(set_attr "type" "two")
8898 (set_attr "length" "8")])
8899
8900 (define_insn_and_split "*tls_gd<TLSmode:tls_abi_suffix>"
8901 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
8902 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
8903 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
8904 UNSPEC_TLSGD))]
8905 "HAVE_AS_TLS && TARGET_TLS_MARKERS"
8906 "addi %0,%1,%2@got@tlsgd"
8907 "&& TARGET_CMODEL != CMODEL_SMALL"
8908 [(set (match_dup 3)
8909 (high:TLSmode
8910 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))
8911 (set (match_dup 0)
8912 (lo_sum:TLSmode (match_dup 3)
8913 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))]
8914 "
8915 {
8916 operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
8917 }"
8918 [(set (attr "length")
8919 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
8920 (const_int 8)
8921 (const_int 4)))])
8922
8923 (define_insn "*tls_gd_high<TLSmode:tls_abi_suffix>"
8924 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
8925 (high:TLSmode
8926 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
8927 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
8928 UNSPEC_TLSGD)))]
8929 "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
8930 "addis %0,%1,%2@got@tlsgd@ha"
8931 [(set_attr "length" "4")])
8932
8933 (define_insn "*tls_gd_low<TLSmode:tls_abi_suffix>"
8934 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
8935 (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
8936 (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
8937 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
8938 UNSPEC_TLSGD)))]
8939 "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
8940 "addi %0,%1,%2@got@tlsgd@l"
8941 [(set_attr "length" "4")])
8942
8943 (define_insn "*tls_gd_call_aix<TLSmode:tls_abi_suffix>"
8944 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
8945 (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
8946 (match_operand 2 "" "g")))
8947 (unspec:TLSmode [(match_operand:TLSmode 3 "rs6000_tls_symbol_ref" "")]
8948 UNSPEC_TLSGD)
8949 (clobber (reg:SI LR_REGNO))]
8950 "HAVE_AS_TLS && TARGET_TLS_MARKERS
8951 && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
8952 "bl %z1(%3@tlsgd)\;nop"
8953 [(set_attr "type" "branch")
8954 (set_attr "length" "8")])
8955
8956 (define_insn "*tls_gd_call_sysv<TLSmode:tls_abi_suffix>"
8957 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
8958 (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
8959 (match_operand 2 "" "g")))
8960 (unspec:TLSmode [(match_operand:TLSmode 3 "rs6000_tls_symbol_ref" "")]
8961 UNSPEC_TLSGD)
8962 (clobber (reg:SI LR_REGNO))]
8963 "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4 && TARGET_TLS_MARKERS"
8964 {
8965 if (flag_pic)
8966 {
8967 if (TARGET_SECURE_PLT && flag_pic == 2)
8968 return "bl %z1+32768(%3@tlsgd)@plt";
8969 return "bl %z1(%3@tlsgd)@plt";
8970 }
8971 return "bl %z1(%3@tlsgd)";
8972 }
8973 [(set_attr "type" "branch")
8974 (set_attr "length" "4")])
8975
8976 (define_insn_and_split "tls_ld_aix<TLSmode:tls_abi_suffix>"
8977 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
8978 (call (mem:TLSmode (match_operand:TLSmode 2 "symbol_ref_operand" "s"))
8979 (match_operand 3 "" "g")))
8980 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
8981 UNSPEC_TLSLD)
8982 (clobber (reg:SI LR_REGNO))]
8983 "HAVE_AS_TLS && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
8984 {
8985 if (TARGET_CMODEL != CMODEL_SMALL)
8986 return "addis %0,%1,%&@got@tlsld@ha\;addi %0,%0,%&@got@tlsld@l\;"
8987 "bl %z2\;nop";
8988 else
8989 return "addi %0,%1,%&@got@tlsld\;bl %z2\;nop";
8990 }
8991 "&& TARGET_TLS_MARKERS"
8992 [(set (match_dup 0)
8993 (unspec:TLSmode [(match_dup 1)]
8994 UNSPEC_TLSLD))
8995 (parallel [(set (match_dup 0)
8996 (call (mem:TLSmode (match_dup 2))
8997 (match_dup 3)))
8998 (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
8999 (clobber (reg:SI LR_REGNO))])]
9000 ""
9001 [(set_attr "type" "two")
9002 (set (attr "length")
9003 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9004 (const_int 16)
9005 (const_int 12)))])
9006
9007 (define_insn_and_split "tls_ld_sysv<TLSmode:tls_sysv_suffix>"
9008 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9009 (call (mem:TLSmode (match_operand:TLSmode 2 "symbol_ref_operand" "s"))
9010 (match_operand 3 "" "g")))
9011 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9012 UNSPEC_TLSLD)
9013 (clobber (reg:SI LR_REGNO))]
9014 "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4"
9015 {
9016 if (flag_pic)
9017 {
9018 if (TARGET_SECURE_PLT && flag_pic == 2)
9019 return "addi %0,%1,%&@got@tlsld\;bl %z2+32768@plt";
9020 else
9021 return "addi %0,%1,%&@got@tlsld\;bl %z2@plt";
9022 }
9023 else
9024 return "addi %0,%1,%&@got@tlsld\;bl %z2";
9025 }
9026 "&& TARGET_TLS_MARKERS"
9027 [(set (match_dup 0)
9028 (unspec:TLSmode [(match_dup 1)]
9029 UNSPEC_TLSLD))
9030 (parallel [(set (match_dup 0)
9031 (call (mem:TLSmode (match_dup 2))
9032 (match_dup 3)))
9033 (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9034 (clobber (reg:SI LR_REGNO))])]
9035 ""
9036 [(set_attr "length" "8")])
9037
9038 (define_insn_and_split "*tls_ld<TLSmode:tls_abi_suffix>"
9039 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9040 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9041 UNSPEC_TLSLD))]
9042 "HAVE_AS_TLS && TARGET_TLS_MARKERS"
9043 "addi %0,%1,%&@got@tlsld"
9044 "&& TARGET_CMODEL != CMODEL_SMALL"
9045 [(set (match_dup 2)
9046 (high:TLSmode
9047 (unspec:TLSmode [(const_int 0) (match_dup 1)] UNSPEC_TLSLD)))
9048 (set (match_dup 0)
9049 (lo_sum:TLSmode (match_dup 2)
9050 (unspec:TLSmode [(const_int 0) (match_dup 1)] UNSPEC_TLSLD)))]
9051 "
9052 {
9053 operands[2] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9054 }"
9055 [(set (attr "length")
9056 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9057 (const_int 8)
9058 (const_int 4)))])
9059
9060 (define_insn "*tls_ld_high<TLSmode:tls_abi_suffix>"
9061 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9062 (high:TLSmode
9063 (unspec:TLSmode [(const_int 0)
9064 (match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9065 UNSPEC_TLSLD)))]
9066 "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9067 "addis %0,%1,%&@got@tlsld@ha"
9068 [(set_attr "length" "4")])
9069
9070 (define_insn "*tls_ld_low<TLSmode:tls_abi_suffix>"
9071 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9072 (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
9073 (unspec:TLSmode [(const_int 0)
9074 (match_operand:TLSmode 2 "gpc_reg_operand" "b")]
9075 UNSPEC_TLSLD)))]
9076 "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9077 "addi %0,%1,%&@got@tlsld@l"
9078 [(set_attr "length" "4")])
9079
9080 (define_insn "*tls_ld_call_aix<TLSmode:tls_abi_suffix>"
9081 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9082 (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9083 (match_operand 2 "" "g")))
9084 (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9085 (clobber (reg:SI LR_REGNO))]
9086 "HAVE_AS_TLS && TARGET_TLS_MARKERS
9087 && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9088 "bl %z1(%&@tlsld)\;nop"
9089 [(set_attr "type" "branch")
9090 (set_attr "length" "8")])
9091
9092 (define_insn "*tls_ld_call_sysv<TLSmode:tls_abi_suffix>"
9093 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9094 (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9095 (match_operand 2 "" "g")))
9096 (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9097 (clobber (reg:SI LR_REGNO))]
9098 "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4 && TARGET_TLS_MARKERS"
9099 {
9100 if (flag_pic)
9101 {
9102 if (TARGET_SECURE_PLT && flag_pic == 2)
9103 return "bl %z1+32768(%&@tlsld)@plt";
9104 return "bl %z1(%&@tlsld)@plt";
9105 }
9106 return "bl %z1(%&@tlsld)";
9107 }
9108 [(set_attr "type" "branch")
9109 (set_attr "length" "4")])
9110
9111 (define_insn "tls_dtprel_<TLSmode:tls_abi_suffix>"
9112 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9113 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9114 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9115 UNSPEC_TLSDTPREL))]
9116 "HAVE_AS_TLS"
9117 "addi %0,%1,%2@dtprel")
9118
9119 (define_insn "tls_dtprel_ha_<TLSmode:tls_abi_suffix>"
9120 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9121 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9122 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9123 UNSPEC_TLSDTPRELHA))]
9124 "HAVE_AS_TLS"
9125 "addis %0,%1,%2@dtprel@ha")
9126
9127 (define_insn "tls_dtprel_lo_<TLSmode:tls_abi_suffix>"
9128 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9129 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9130 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9131 UNSPEC_TLSDTPRELLO))]
9132 "HAVE_AS_TLS"
9133 "addi %0,%1,%2@dtprel@l")
9134
9135 (define_insn_and_split "tls_got_dtprel_<TLSmode:tls_abi_suffix>"
9136 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9137 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9138 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9139 UNSPEC_TLSGOTDTPREL))]
9140 "HAVE_AS_TLS"
9141 "l<TLSmode:tls_insn_suffix> %0,%2@got@dtprel(%1)"
9142 "&& TARGET_CMODEL != CMODEL_SMALL"
9143 [(set (match_dup 3)
9144 (high:TLSmode
9145 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))
9146 (set (match_dup 0)
9147 (lo_sum:TLSmode (match_dup 3)
9148 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))]
9149 "
9150 {
9151 operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9152 }"
9153 [(set (attr "length")
9154 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9155 (const_int 8)
9156 (const_int 4)))])
9157
9158 (define_insn "*tls_got_dtprel_high<TLSmode:tls_abi_suffix>"
9159 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9160 (high:TLSmode
9161 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9162 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9163 UNSPEC_TLSGOTDTPREL)))]
9164 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9165 "addis %0,%1,%2@got@dtprel@ha"
9166 [(set_attr "length" "4")])
9167
9168 (define_insn "*tls_got_dtprel_low<TLSmode:tls_abi_suffix>"
9169 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9170 (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
9171 (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
9172 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9173 UNSPEC_TLSGOTDTPREL)))]
9174 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9175 "l<TLSmode:tls_insn_suffix> %0,%2@got@dtprel@l(%1)"
9176 [(set_attr "length" "4")])
9177
9178 (define_insn "tls_tprel_<TLSmode:tls_abi_suffix>"
9179 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9180 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9181 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9182 UNSPEC_TLSTPREL))]
9183 "HAVE_AS_TLS"
9184 "addi %0,%1,%2@tprel")
9185
9186 (define_insn "tls_tprel_ha_<TLSmode:tls_abi_suffix>"
9187 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9188 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9189 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9190 UNSPEC_TLSTPRELHA))]
9191 "HAVE_AS_TLS"
9192 "addis %0,%1,%2@tprel@ha")
9193
9194 (define_insn "tls_tprel_lo_<TLSmode:tls_abi_suffix>"
9195 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9196 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9197 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9198 UNSPEC_TLSTPRELLO))]
9199 "HAVE_AS_TLS"
9200 "addi %0,%1,%2@tprel@l")
9201
9202 ;; "b" output constraint here and on tls_tls input to support linker tls
9203 ;; optimization. The linker may edit the instructions emitted by a
9204 ;; tls_got_tprel/tls_tls pair to addis,addi.
9205 (define_insn_and_split "tls_got_tprel_<TLSmode:tls_abi_suffix>"
9206 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9207 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9208 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9209 UNSPEC_TLSGOTTPREL))]
9210 "HAVE_AS_TLS"
9211 "l<TLSmode:tls_insn_suffix> %0,%2@got@tprel(%1)"
9212 "&& TARGET_CMODEL != CMODEL_SMALL"
9213 [(set (match_dup 3)
9214 (high:TLSmode
9215 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))
9216 (set (match_dup 0)
9217 (lo_sum:TLSmode (match_dup 3)
9218 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))]
9219 "
9220 {
9221 operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9222 }"
9223 [(set (attr "length")
9224 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9225 (const_int 8)
9226 (const_int 4)))])
9227
9228 (define_insn "*tls_got_tprel_high<TLSmode:tls_abi_suffix>"
9229 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9230 (high:TLSmode
9231 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9232 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9233 UNSPEC_TLSGOTTPREL)))]
9234 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9235 "addis %0,%1,%2@got@tprel@ha"
9236 [(set_attr "length" "4")])
9237
9238 (define_insn "*tls_got_tprel_low<TLSmode:tls_abi_suffix>"
9239 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9240 (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
9241 (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
9242 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9243 UNSPEC_TLSGOTTPREL)))]
9244 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9245 "l<TLSmode:tls_insn_suffix> %0,%2@got@tprel@l(%1)"
9246 [(set_attr "length" "4")])
9247
9248 (define_insn "tls_tls_<TLSmode:tls_abi_suffix>"
9249 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9250 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9251 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9252 UNSPEC_TLSTLS))]
9253 "TARGET_ELF && HAVE_AS_TLS"
9254 "add %0,%1,%2@tls")
9255
9256 (define_expand "tls_get_tpointer"
9257 [(set (match_operand:SI 0 "gpc_reg_operand" "")
9258 (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))]
9259 "TARGET_XCOFF && HAVE_AS_TLS"
9260 "
9261 {
9262 emit_insn (gen_tls_get_tpointer_internal ());
9263 emit_move_insn (operands[0], gen_rtx_REG (SImode, 3));
9264 DONE;
9265 }")
9266
9267 (define_insn "tls_get_tpointer_internal"
9268 [(set (reg:SI 3)
9269 (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))
9270 (clobber (reg:SI LR_REGNO))]
9271 "TARGET_XCOFF && HAVE_AS_TLS"
9272 "bla __get_tpointer")
9273
9274 (define_expand "tls_get_addr<mode>"
9275 [(set (match_operand:P 0 "gpc_reg_operand" "")
9276 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "")
9277 (match_operand:P 2 "gpc_reg_operand" "")] UNSPEC_TLSTLS))]
9278 "TARGET_XCOFF && HAVE_AS_TLS"
9279 "
9280 {
9281 emit_move_insn (gen_rtx_REG (Pmode, 3), operands[1]);
9282 emit_move_insn (gen_rtx_REG (Pmode, 4), operands[2]);
9283 emit_insn (gen_tls_get_addr_internal<mode> ());
9284 emit_move_insn (operands[0], gen_rtx_REG (Pmode, 3));
9285 DONE;
9286 }")
9287
9288 (define_insn "tls_get_addr_internal<mode>"
9289 [(set (reg:P 3)
9290 (unspec:P [(reg:P 3) (reg:P 4)] UNSPEC_TLSTLS))
9291 (clobber (reg:P 0))
9292 (clobber (reg:P 4))
9293 (clobber (reg:P 5))
9294 (clobber (reg:P 11))
9295 (clobber (reg:CC CR0_REGNO))
9296 (clobber (reg:P LR_REGNO))]
9297 "TARGET_XCOFF && HAVE_AS_TLS"
9298 "bla __tls_get_addr")
9299 \f
9300 ;; Next come insns related to the calling sequence.
9301 ;;
9302 ;; First, an insn to allocate new stack space for dynamic use (e.g., alloca).
9303 ;; We move the back-chain and decrement the stack pointer.
9304
9305 (define_expand "allocate_stack"
9306 [(set (match_operand 0 "gpc_reg_operand" "")
9307 (minus (reg 1) (match_operand 1 "reg_or_short_operand" "")))
9308 (set (reg 1)
9309 (minus (reg 1) (match_dup 1)))]
9310 ""
9311 "
9312 { rtx chain = gen_reg_rtx (Pmode);
9313 rtx stack_bot = gen_rtx_MEM (Pmode, stack_pointer_rtx);
9314 rtx neg_op0;
9315 rtx insn, par, set, mem;
9316
9317 emit_move_insn (chain, stack_bot);
9318
9319 /* Check stack bounds if necessary. */
9320 if (crtl->limit_stack)
9321 {
9322 rtx available;
9323 available = expand_binop (Pmode, sub_optab,
9324 stack_pointer_rtx, stack_limit_rtx,
9325 NULL_RTX, 1, OPTAB_WIDEN);
9326 emit_insn (gen_cond_trap (LTU, available, operands[1], const0_rtx));
9327 }
9328
9329 if (GET_CODE (operands[1]) != CONST_INT
9330 || INTVAL (operands[1]) < -32767
9331 || INTVAL (operands[1]) > 32768)
9332 {
9333 neg_op0 = gen_reg_rtx (Pmode);
9334 if (TARGET_32BIT)
9335 emit_insn (gen_negsi2 (neg_op0, operands[1]));
9336 else
9337 emit_insn (gen_negdi2 (neg_op0, operands[1]));
9338 }
9339 else
9340 neg_op0 = GEN_INT (- INTVAL (operands[1]));
9341
9342 insn = emit_insn ((* ((TARGET_32BIT) ? gen_movsi_update_stack
9343 : gen_movdi_di_update_stack))
9344 (stack_pointer_rtx, stack_pointer_rtx, neg_op0,
9345 chain));
9346 /* Since we didn't use gen_frame_mem to generate the MEM, grab
9347 it now and set the alias set/attributes. The above gen_*_update
9348 calls will generate a PARALLEL with the MEM set being the first
9349 operation. */
9350 par = PATTERN (insn);
9351 gcc_assert (GET_CODE (par) == PARALLEL);
9352 set = XVECEXP (par, 0, 0);
9353 gcc_assert (GET_CODE (set) == SET);
9354 mem = SET_DEST (set);
9355 gcc_assert (MEM_P (mem));
9356 MEM_NOTRAP_P (mem) = 1;
9357 set_mem_alias_set (mem, get_frame_alias_set ());
9358
9359 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
9360 DONE;
9361 }")
9362
9363 ;; These patterns say how to save and restore the stack pointer. We need not
9364 ;; save the stack pointer at function level since we are careful to
9365 ;; preserve the backchain. At block level, we have to restore the backchain
9366 ;; when we restore the stack pointer.
9367 ;;
9368 ;; For nonlocal gotos, we must save both the stack pointer and its
9369 ;; backchain and restore both. Note that in the nonlocal case, the
9370 ;; save area is a memory location.
9371
9372 (define_expand "save_stack_function"
9373 [(match_operand 0 "any_operand" "")
9374 (match_operand 1 "any_operand" "")]
9375 ""
9376 "DONE;")
9377
9378 (define_expand "restore_stack_function"
9379 [(match_operand 0 "any_operand" "")
9380 (match_operand 1 "any_operand" "")]
9381 ""
9382 "DONE;")
9383
9384 ;; Adjust stack pointer (op0) to a new value (op1).
9385 ;; First copy old stack backchain to new location, and ensure that the
9386 ;; scheduler won't reorder the sp assignment before the backchain write.
9387 (define_expand "restore_stack_block"
9388 [(set (match_dup 2) (match_dup 3))
9389 (set (match_dup 4) (match_dup 2))
9390 (match_dup 5)
9391 (set (match_operand 0 "register_operand" "")
9392 (match_operand 1 "register_operand" ""))]
9393 ""
9394 "
9395 {
9396 rtvec p;
9397
9398 operands[1] = force_reg (Pmode, operands[1]);
9399 operands[2] = gen_reg_rtx (Pmode);
9400 operands[3] = gen_frame_mem (Pmode, operands[0]);
9401 operands[4] = gen_frame_mem (Pmode, operands[1]);
9402 p = rtvec_alloc (1);
9403 RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
9404 const0_rtx);
9405 operands[5] = gen_rtx_PARALLEL (VOIDmode, p);
9406 }")
9407
9408 (define_expand "save_stack_nonlocal"
9409 [(set (match_dup 3) (match_dup 4))
9410 (set (match_operand 0 "memory_operand" "") (match_dup 3))
9411 (set (match_dup 2) (match_operand 1 "register_operand" ""))]
9412 ""
9413 "
9414 {
9415 int units_per_word = (TARGET_32BIT) ? 4 : 8;
9416
9417 /* Copy the backchain to the first word, sp to the second. */
9418 operands[0] = adjust_address_nv (operands[0], Pmode, 0);
9419 operands[2] = adjust_address_nv (operands[0], Pmode, units_per_word);
9420 operands[3] = gen_reg_rtx (Pmode);
9421 operands[4] = gen_frame_mem (Pmode, operands[1]);
9422 }")
9423
9424 (define_expand "restore_stack_nonlocal"
9425 [(set (match_dup 2) (match_operand 1 "memory_operand" ""))
9426 (set (match_dup 3) (match_dup 4))
9427 (set (match_dup 5) (match_dup 2))
9428 (match_dup 6)
9429 (set (match_operand 0 "register_operand" "") (match_dup 3))]
9430 ""
9431 "
9432 {
9433 int units_per_word = (TARGET_32BIT) ? 4 : 8;
9434 rtvec p;
9435
9436 /* Restore the backchain from the first word, sp from the second. */
9437 operands[2] = gen_reg_rtx (Pmode);
9438 operands[3] = gen_reg_rtx (Pmode);
9439 operands[1] = adjust_address_nv (operands[1], Pmode, 0);
9440 operands[4] = adjust_address_nv (operands[1], Pmode, units_per_word);
9441 operands[5] = gen_frame_mem (Pmode, operands[3]);
9442 p = rtvec_alloc (1);
9443 RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
9444 const0_rtx);
9445 operands[6] = gen_rtx_PARALLEL (VOIDmode, p);
9446 }")
9447 \f
9448 ;; TOC register handling.
9449
9450 ;; Code to initialize the TOC register...
9451
9452 (define_insn "load_toc_aix_si"
9453 [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
9454 (unspec:SI [(const_int 0)] UNSPEC_TOC))
9455 (use (reg:SI 2))])]
9456 "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_32BIT"
9457 "*
9458 {
9459 char buf[30];
9460 ASM_GENERATE_INTERNAL_LABEL (buf, \"LCTOC\", 1);
9461 operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
9462 operands[2] = gen_rtx_REG (Pmode, 2);
9463 return \"lwz %0,%1(%2)\";
9464 }"
9465 [(set_attr "type" "load")
9466 (set_attr "update" "no")
9467 (set_attr "indexed" "no")])
9468
9469 (define_insn "load_toc_aix_di"
9470 [(parallel [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
9471 (unspec:DI [(const_int 0)] UNSPEC_TOC))
9472 (use (reg:DI 2))])]
9473 "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_64BIT"
9474 "*
9475 {
9476 char buf[30];
9477 #ifdef TARGET_RELOCATABLE
9478 ASM_GENERATE_INTERNAL_LABEL (buf, \"LCTOC\",
9479 !TARGET_MINIMAL_TOC || TARGET_RELOCATABLE);
9480 #else
9481 ASM_GENERATE_INTERNAL_LABEL (buf, \"LCTOC\", 1);
9482 #endif
9483 if (TARGET_ELF)
9484 strcat (buf, \"@toc\");
9485 operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
9486 operands[2] = gen_rtx_REG (Pmode, 2);
9487 return \"ld %0,%1(%2)\";
9488 }"
9489 [(set_attr "type" "load")
9490 (set_attr "update" "no")
9491 (set_attr "indexed" "no")])
9492
9493 (define_insn "load_toc_v4_pic_si"
9494 [(set (reg:SI LR_REGNO)
9495 (unspec:SI [(const_int 0)] UNSPEC_TOC))]
9496 "DEFAULT_ABI == ABI_V4 && flag_pic == 1 && TARGET_32BIT"
9497 "bl _GLOBAL_OFFSET_TABLE_@local-4"
9498 [(set_attr "type" "branch")
9499 (set_attr "length" "4")])
9500
9501 (define_expand "load_toc_v4_PIC_1"
9502 [(parallel [(set (reg:SI LR_REGNO)
9503 (match_operand:SI 0 "immediate_operand" "s"))
9504 (use (unspec [(match_dup 0)] UNSPEC_TOC))])]
9505 "TARGET_ELF && DEFAULT_ABI == ABI_V4
9506 && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
9507 "")
9508
9509 (define_insn "load_toc_v4_PIC_1_normal"
9510 [(set (reg:SI LR_REGNO)
9511 (match_operand:SI 0 "immediate_operand" "s"))
9512 (use (unspec [(match_dup 0)] UNSPEC_TOC))]
9513 "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
9514 && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
9515 "bcl 20,31,%0\\n%0:"
9516 [(set_attr "type" "branch")
9517 (set_attr "length" "4")
9518 (set_attr "cannot_copy" "yes")])
9519
9520 (define_insn "load_toc_v4_PIC_1_476"
9521 [(set (reg:SI LR_REGNO)
9522 (match_operand:SI 0 "immediate_operand" "s"))
9523 (use (unspec [(match_dup 0)] UNSPEC_TOC))]
9524 "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
9525 && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
9526 "*
9527 {
9528 char name[32];
9529 static char templ[32];
9530
9531 get_ppc476_thunk_name (name);
9532 sprintf (templ, \"bl %s\\n%%0:\", name);
9533 return templ;
9534 }"
9535 [(set_attr "type" "branch")
9536 (set_attr "length" "4")
9537 (set_attr "cannot_copy" "yes")])
9538
9539 (define_expand "load_toc_v4_PIC_1b"
9540 [(parallel [(set (reg:SI LR_REGNO)
9541 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
9542 (label_ref (match_operand 1 "" ""))]
9543 UNSPEC_TOCPTR))
9544 (match_dup 1)])]
9545 "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
9546 "")
9547
9548 (define_insn "load_toc_v4_PIC_1b_normal"
9549 [(set (reg:SI LR_REGNO)
9550 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
9551 (label_ref (match_operand 1 "" ""))]
9552 UNSPEC_TOCPTR))
9553 (match_dup 1)]
9554 "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
9555 "bcl 20,31,$+8\;.long %0-$"
9556 [(set_attr "type" "branch")
9557 (set_attr "length" "8")])
9558
9559 (define_insn "load_toc_v4_PIC_1b_476"
9560 [(set (reg:SI LR_REGNO)
9561 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
9562 (label_ref (match_operand 1 "" ""))]
9563 UNSPEC_TOCPTR))
9564 (match_dup 1)]
9565 "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
9566 "*
9567 {
9568 char name[32];
9569 static char templ[32];
9570
9571 get_ppc476_thunk_name (name);
9572 sprintf (templ, \"bl %s\\n\\tb $+8\\n\\t.long %%0-$\", name);
9573 return templ;
9574 }"
9575 [(set_attr "type" "branch")
9576 (set_attr "length" "16")])
9577
9578 (define_insn "load_toc_v4_PIC_2"
9579 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
9580 (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
9581 (minus:SI (match_operand:SI 2 "immediate_operand" "s")
9582 (match_operand:SI 3 "immediate_operand" "s")))))]
9583 "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
9584 "lwz %0,%2-%3(%1)"
9585 [(set_attr "type" "load")])
9586
9587 (define_insn "load_toc_v4_PIC_3b"
9588 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
9589 (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
9590 (high:SI
9591 (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
9592 (match_operand:SI 3 "symbol_ref_operand" "s")))))]
9593 "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
9594 "addis %0,%1,%2-%3@ha")
9595
9596 (define_insn "load_toc_v4_PIC_3c"
9597 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
9598 (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
9599 (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
9600 (match_operand:SI 3 "symbol_ref_operand" "s"))))]
9601 "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
9602 "addi %0,%1,%2-%3@l")
9603
9604 ;; If the TOC is shared over a translation unit, as happens with all
9605 ;; the kinds of PIC that we support, we need to restore the TOC
9606 ;; pointer only when jumping over units of translation.
9607 ;; On Darwin, we need to reload the picbase.
9608
9609 (define_expand "builtin_setjmp_receiver"
9610 [(use (label_ref (match_operand 0 "" "")))]
9611 "(DEFAULT_ABI == ABI_V4 && flag_pic == 1)
9612 || (TARGET_TOC && TARGET_MINIMAL_TOC)
9613 || (DEFAULT_ABI == ABI_DARWIN && flag_pic)"
9614 "
9615 {
9616 #if TARGET_MACHO
9617 if (DEFAULT_ABI == ABI_DARWIN)
9618 {
9619 rtx picrtx = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME);
9620 rtx picreg = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
9621 rtx tmplabrtx;
9622 char tmplab[20];
9623
9624 crtl->uses_pic_offset_table = 1;
9625 ASM_GENERATE_INTERNAL_LABEL(tmplab, \"LSJR\",
9626 CODE_LABEL_NUMBER (operands[0]));
9627 tmplabrtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (tmplab));
9628
9629 emit_insn (gen_load_macho_picbase (tmplabrtx));
9630 emit_move_insn (picreg, gen_rtx_REG (Pmode, LR_REGNO));
9631 emit_insn (gen_macho_correct_pic (picreg, picreg, picrtx, tmplabrtx));
9632 }
9633 else
9634 #endif
9635 rs6000_emit_load_toc_table (FALSE);
9636 DONE;
9637 }")
9638
9639 ;; Largetoc support
9640 (define_insn "*largetoc_high"
9641 [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
9642 (high:DI
9643 (unspec [(match_operand:DI 1 "" "")
9644 (match_operand:DI 2 "gpc_reg_operand" "b")]
9645 UNSPEC_TOCREL)))]
9646 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
9647 "addis %0,%2,%1@toc@ha")
9648
9649 (define_insn "*largetoc_high_aix<mode>"
9650 [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
9651 (high:P
9652 (unspec [(match_operand:P 1 "" "")
9653 (match_operand:P 2 "gpc_reg_operand" "b")]
9654 UNSPEC_TOCREL)))]
9655 "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
9656 "addis %0,%1@u(%2)")
9657
9658 (define_insn "*largetoc_high_plus"
9659 [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
9660 (high:DI
9661 (plus:DI
9662 (unspec [(match_operand:DI 1 "" "")
9663 (match_operand:DI 2 "gpc_reg_operand" "b")]
9664 UNSPEC_TOCREL)
9665 (match_operand:DI 3 "add_cint_operand" "n"))))]
9666 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
9667 "addis %0,%2,%1+%3@toc@ha")
9668
9669 (define_insn "*largetoc_high_plus_aix<mode>"
9670 [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
9671 (high:P
9672 (plus:P
9673 (unspec [(match_operand:P 1 "" "")
9674 (match_operand:P 2 "gpc_reg_operand" "b")]
9675 UNSPEC_TOCREL)
9676 (match_operand:P 3 "add_cint_operand" "n"))))]
9677 "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
9678 "addis %0,%1+%3@u(%2)")
9679
9680 (define_insn "*largetoc_low"
9681 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
9682 (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b")
9683 (match_operand:DI 2 "" "")))]
9684 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
9685 "addi %0,%1,%2@l")
9686
9687 (define_insn "*largetoc_low_aix<mode>"
9688 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9689 (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
9690 (match_operand:P 2 "" "")))]
9691 "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
9692 "la %0,%2@l(%1)")
9693
9694 (define_insn_and_split "*tocref<mode>"
9695 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9696 (match_operand:P 1 "small_toc_ref" "R"))]
9697 "TARGET_TOC"
9698 "la %0,%a1"
9699 "&& TARGET_CMODEL != CMODEL_SMALL && reload_completed"
9700 [(set (match_dup 0) (high:P (match_dup 1)))
9701 (set (match_dup 0) (lo_sum:P (match_dup 0) (match_dup 1)))])
9702
9703 ;; Elf specific ways of loading addresses for non-PIC code.
9704 ;; The output of this could be r0, but we make a very strong
9705 ;; preference for a base register because it will usually
9706 ;; be needed there.
9707 (define_insn "elf_high"
9708 [(set (match_operand:SI 0 "gpc_reg_operand" "=b*r")
9709 (high:SI (match_operand 1 "" "")))]
9710 "TARGET_ELF && ! TARGET_64BIT"
9711 "lis %0,%1@ha")
9712
9713 (define_insn "elf_low"
9714 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
9715 (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
9716 (match_operand 2 "" "")))]
9717 "TARGET_ELF && ! TARGET_64BIT"
9718 "la %0,%2@l(%1)")
9719 \f
9720 ;; Call and call_value insns
9721 (define_expand "call"
9722 [(parallel [(call (mem:SI (match_operand 0 "address_operand" ""))
9723 (match_operand 1 "" ""))
9724 (use (match_operand 2 "" ""))
9725 (clobber (reg:SI LR_REGNO))])]
9726 ""
9727 "
9728 {
9729 #if TARGET_MACHO
9730 if (MACHOPIC_INDIRECT)
9731 operands[0] = machopic_indirect_call_target (operands[0]);
9732 #endif
9733
9734 gcc_assert (GET_CODE (operands[0]) == MEM);
9735 gcc_assert (GET_CODE (operands[1]) == CONST_INT);
9736
9737 operands[0] = XEXP (operands[0], 0);
9738
9739 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
9740 {
9741 rs6000_call_aix (NULL_RTX, operands[0], operands[1], operands[2]);
9742 DONE;
9743 }
9744
9745 if (GET_CODE (operands[0]) != SYMBOL_REF
9746 || (DEFAULT_ABI != ABI_DARWIN && (INTVAL (operands[2]) & CALL_LONG) != 0))
9747 {
9748 if (INTVAL (operands[2]) & CALL_LONG)
9749 operands[0] = rs6000_longcall_ref (operands[0]);
9750
9751 switch (DEFAULT_ABI)
9752 {
9753 case ABI_V4:
9754 case ABI_DARWIN:
9755 operands[0] = force_reg (Pmode, operands[0]);
9756 break;
9757
9758 default:
9759 gcc_unreachable ();
9760 }
9761 }
9762 }")
9763
9764 (define_expand "call_value"
9765 [(parallel [(set (match_operand 0 "" "")
9766 (call (mem:SI (match_operand 1 "address_operand" ""))
9767 (match_operand 2 "" "")))
9768 (use (match_operand 3 "" ""))
9769 (clobber (reg:SI LR_REGNO))])]
9770 ""
9771 "
9772 {
9773 #if TARGET_MACHO
9774 if (MACHOPIC_INDIRECT)
9775 operands[1] = machopic_indirect_call_target (operands[1]);
9776 #endif
9777
9778 gcc_assert (GET_CODE (operands[1]) == MEM);
9779 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
9780
9781 operands[1] = XEXP (operands[1], 0);
9782
9783 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
9784 {
9785 rs6000_call_aix (operands[0], operands[1], operands[2], operands[3]);
9786 DONE;
9787 }
9788
9789 if (GET_CODE (operands[1]) != SYMBOL_REF
9790 || (DEFAULT_ABI != ABI_DARWIN && (INTVAL (operands[3]) & CALL_LONG) != 0))
9791 {
9792 if (INTVAL (operands[3]) & CALL_LONG)
9793 operands[1] = rs6000_longcall_ref (operands[1]);
9794
9795 switch (DEFAULT_ABI)
9796 {
9797 case ABI_V4:
9798 case ABI_DARWIN:
9799 operands[1] = force_reg (Pmode, operands[1]);
9800 break;
9801
9802 default:
9803 gcc_unreachable ();
9804 }
9805 }
9806 }")
9807
9808 ;; Call to function in current module. No TOC pointer reload needed.
9809 ;; Operand2 is nonzero if we are using the V.4 calling sequence and
9810 ;; either the function was not prototyped, or it was prototyped as a
9811 ;; variable argument function. It is > 0 if FP registers were passed
9812 ;; and < 0 if they were not.
9813
9814 (define_insn "*call_local32"
9815 [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
9816 (match_operand 1 "" "g,g"))
9817 (use (match_operand:SI 2 "immediate_operand" "O,n"))
9818 (clobber (reg:SI LR_REGNO))]
9819 "(INTVAL (operands[2]) & CALL_LONG) == 0"
9820 "*
9821 {
9822 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
9823 output_asm_insn (\"crxor 6,6,6\", operands);
9824
9825 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
9826 output_asm_insn (\"creqv 6,6,6\", operands);
9827
9828 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z0@local\" : \"bl %z0\";
9829 }"
9830 [(set_attr "type" "branch")
9831 (set_attr "length" "4,8")])
9832
9833 (define_insn "*call_local64"
9834 [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
9835 (match_operand 1 "" "g,g"))
9836 (use (match_operand:SI 2 "immediate_operand" "O,n"))
9837 (clobber (reg:SI LR_REGNO))]
9838 "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
9839 "*
9840 {
9841 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
9842 output_asm_insn (\"crxor 6,6,6\", operands);
9843
9844 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
9845 output_asm_insn (\"creqv 6,6,6\", operands);
9846
9847 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z0@local\" : \"bl %z0\";
9848 }"
9849 [(set_attr "type" "branch")
9850 (set_attr "length" "4,8")])
9851
9852 (define_insn "*call_value_local32"
9853 [(set (match_operand 0 "" "")
9854 (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
9855 (match_operand 2 "" "g,g")))
9856 (use (match_operand:SI 3 "immediate_operand" "O,n"))
9857 (clobber (reg:SI LR_REGNO))]
9858 "(INTVAL (operands[3]) & CALL_LONG) == 0"
9859 "*
9860 {
9861 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
9862 output_asm_insn (\"crxor 6,6,6\", operands);
9863
9864 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
9865 output_asm_insn (\"creqv 6,6,6\", operands);
9866
9867 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z1@local\" : \"bl %z1\";
9868 }"
9869 [(set_attr "type" "branch")
9870 (set_attr "length" "4,8")])
9871
9872
9873 (define_insn "*call_value_local64"
9874 [(set (match_operand 0 "" "")
9875 (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
9876 (match_operand 2 "" "g,g")))
9877 (use (match_operand:SI 3 "immediate_operand" "O,n"))
9878 (clobber (reg:SI LR_REGNO))]
9879 "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
9880 "*
9881 {
9882 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
9883 output_asm_insn (\"crxor 6,6,6\", operands);
9884
9885 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
9886 output_asm_insn (\"creqv 6,6,6\", operands);
9887
9888 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z1@local\" : \"bl %z1\";
9889 }"
9890 [(set_attr "type" "branch")
9891 (set_attr "length" "4,8")])
9892
9893
9894 ;; A function pointer under System V is just a normal pointer
9895 ;; operands[0] is the function pointer
9896 ;; operands[1] is the stack size to clean up
9897 ;; operands[2] is the value FUNCTION_ARG returns for the VOID argument
9898 ;; which indicates how to set cr1
9899
9900 (define_insn "*call_indirect_nonlocal_sysv<mode>"
9901 [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l,c,*l"))
9902 (match_operand 1 "" "g,g,g,g"))
9903 (use (match_operand:SI 2 "immediate_operand" "O,O,n,n"))
9904 (clobber (reg:SI LR_REGNO))]
9905 "DEFAULT_ABI == ABI_V4
9906 || DEFAULT_ABI == ABI_DARWIN"
9907 {
9908 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
9909 output_asm_insn ("crxor 6,6,6", operands);
9910
9911 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
9912 output_asm_insn ("creqv 6,6,6", operands);
9913
9914 return "b%T0l";
9915 }
9916 [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg")
9917 (set_attr "length" "4,4,8,8")])
9918
9919 (define_insn_and_split "*call_nonlocal_sysv<mode>"
9920 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
9921 (match_operand 1 "" "g,g"))
9922 (use (match_operand:SI 2 "immediate_operand" "O,n"))
9923 (clobber (reg:SI LR_REGNO))]
9924 "(DEFAULT_ABI == ABI_DARWIN
9925 || (DEFAULT_ABI == ABI_V4
9926 && (INTVAL (operands[2]) & CALL_LONG) == 0))"
9927 {
9928 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
9929 output_asm_insn ("crxor 6,6,6", operands);
9930
9931 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
9932 output_asm_insn ("creqv 6,6,6", operands);
9933
9934 #if TARGET_MACHO
9935 return output_call(insn, operands, 0, 2);
9936 #else
9937 if (DEFAULT_ABI == ABI_V4 && flag_pic)
9938 {
9939 gcc_assert (!TARGET_SECURE_PLT);
9940 return "bl %z0@plt";
9941 }
9942 else
9943 return "bl %z0";
9944 #endif
9945 }
9946 "DEFAULT_ABI == ABI_V4
9947 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0])
9948 && (INTVAL (operands[2]) & CALL_LONG) == 0"
9949 [(parallel [(call (mem:SI (match_dup 0))
9950 (match_dup 1))
9951 (use (match_dup 2))
9952 (use (match_dup 3))
9953 (clobber (reg:SI LR_REGNO))])]
9954 {
9955 operands[3] = pic_offset_table_rtx;
9956 }
9957 [(set_attr "type" "branch,branch")
9958 (set_attr "length" "4,8")])
9959
9960 (define_insn "*call_nonlocal_sysv_secure<mode>"
9961 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
9962 (match_operand 1 "" "g,g"))
9963 (use (match_operand:SI 2 "immediate_operand" "O,n"))
9964 (use (match_operand:SI 3 "register_operand" "r,r"))
9965 (clobber (reg:SI LR_REGNO))]
9966 "(DEFAULT_ABI == ABI_V4
9967 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0])
9968 && (INTVAL (operands[2]) & CALL_LONG) == 0)"
9969 {
9970 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
9971 output_asm_insn ("crxor 6,6,6", operands);
9972
9973 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
9974 output_asm_insn ("creqv 6,6,6", operands);
9975
9976 if (flag_pic == 2)
9977 /* The magic 32768 offset here and in the other sysv call insns
9978 corresponds to the offset of r30 in .got2, as given by LCTOC1.
9979 See sysv4.h:toc_section. */
9980 return "bl %z0+32768@plt";
9981 else
9982 return "bl %z0@plt";
9983 }
9984 [(set_attr "type" "branch,branch")
9985 (set_attr "length" "4,8")])
9986
9987 (define_insn "*call_value_indirect_nonlocal_sysv<mode>"
9988 [(set (match_operand 0 "" "")
9989 (call (mem:SI (match_operand:P 1 "register_operand" "c,*l,c,*l"))
9990 (match_operand 2 "" "g,g,g,g")))
9991 (use (match_operand:SI 3 "immediate_operand" "O,O,n,n"))
9992 (clobber (reg:SI LR_REGNO))]
9993 "DEFAULT_ABI == ABI_V4
9994 || DEFAULT_ABI == ABI_DARWIN"
9995 {
9996 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
9997 output_asm_insn ("crxor 6,6,6", operands);
9998
9999 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10000 output_asm_insn ("creqv 6,6,6", operands);
10001
10002 return "b%T1l";
10003 }
10004 [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg")
10005 (set_attr "length" "4,4,8,8")])
10006
10007 (define_insn_and_split "*call_value_nonlocal_sysv<mode>"
10008 [(set (match_operand 0 "" "")
10009 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
10010 (match_operand 2 "" "g,g")))
10011 (use (match_operand:SI 3 "immediate_operand" "O,n"))
10012 (clobber (reg:SI LR_REGNO))]
10013 "(DEFAULT_ABI == ABI_DARWIN
10014 || (DEFAULT_ABI == ABI_V4
10015 && (INTVAL (operands[3]) & CALL_LONG) == 0))"
10016 {
10017 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10018 output_asm_insn ("crxor 6,6,6", operands);
10019
10020 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10021 output_asm_insn ("creqv 6,6,6", operands);
10022
10023 #if TARGET_MACHO
10024 return output_call(insn, operands, 1, 3);
10025 #else
10026 if (DEFAULT_ABI == ABI_V4 && flag_pic)
10027 {
10028 gcc_assert (!TARGET_SECURE_PLT);
10029 return "bl %z1@plt";
10030 }
10031 else
10032 return "bl %z1";
10033 #endif
10034 }
10035 "DEFAULT_ABI == ABI_V4
10036 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1])
10037 && (INTVAL (operands[3]) & CALL_LONG) == 0"
10038 [(parallel [(set (match_dup 0)
10039 (call (mem:SI (match_dup 1))
10040 (match_dup 2)))
10041 (use (match_dup 3))
10042 (use (match_dup 4))
10043 (clobber (reg:SI LR_REGNO))])]
10044 {
10045 operands[4] = pic_offset_table_rtx;
10046 }
10047 [(set_attr "type" "branch,branch")
10048 (set_attr "length" "4,8")])
10049
10050 (define_insn "*call_value_nonlocal_sysv_secure<mode>"
10051 [(set (match_operand 0 "" "")
10052 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
10053 (match_operand 2 "" "g,g")))
10054 (use (match_operand:SI 3 "immediate_operand" "O,n"))
10055 (use (match_operand:SI 4 "register_operand" "r,r"))
10056 (clobber (reg:SI LR_REGNO))]
10057 "(DEFAULT_ABI == ABI_V4
10058 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1])
10059 && (INTVAL (operands[3]) & CALL_LONG) == 0)"
10060 {
10061 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10062 output_asm_insn ("crxor 6,6,6", operands);
10063
10064 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10065 output_asm_insn ("creqv 6,6,6", operands);
10066
10067 if (flag_pic == 2)
10068 return "bl %z1+32768@plt";
10069 else
10070 return "bl %z1@plt";
10071 }
10072 [(set_attr "type" "branch,branch")
10073 (set_attr "length" "4,8")])
10074
10075
10076 ;; Call to AIX abi function in the same module.
10077
10078 (define_insn "*call_local_aix<mode>"
10079 [(call (mem:SI (match_operand:P 0 "current_file_function_operand" "s"))
10080 (match_operand 1 "" "g"))
10081 (clobber (reg:P LR_REGNO))]
10082 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10083 "bl %z0"
10084 [(set_attr "type" "branch")
10085 (set_attr "length" "4")])
10086
10087 (define_insn "*call_value_local_aix<mode>"
10088 [(set (match_operand 0 "" "")
10089 (call (mem:SI (match_operand:P 1 "current_file_function_operand" "s"))
10090 (match_operand 2 "" "g")))
10091 (clobber (reg:P LR_REGNO))]
10092 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10093 "bl %z1"
10094 [(set_attr "type" "branch")
10095 (set_attr "length" "4")])
10096
10097 ;; Call to AIX abi function which may be in another module.
10098 ;; Restore the TOC pointer (r2) after the call.
10099
10100 (define_insn "*call_nonlocal_aix<mode>"
10101 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s"))
10102 (match_operand 1 "" "g"))
10103 (clobber (reg:P LR_REGNO))]
10104 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10105 "bl %z0\;nop"
10106 [(set_attr "type" "branch")
10107 (set_attr "length" "8")])
10108
10109 (define_insn "*call_value_nonlocal_aix<mode>"
10110 [(set (match_operand 0 "" "")
10111 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s"))
10112 (match_operand 2 "" "g")))
10113 (clobber (reg:P LR_REGNO))]
10114 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10115 "bl %z1\;nop"
10116 [(set_attr "type" "branch")
10117 (set_attr "length" "8")])
10118
10119 ;; Call to indirect functions with the AIX abi using a 3 word descriptor.
10120 ;; Operand0 is the addresss of the function to call
10121 ;; Operand2 is the location in the function descriptor to load r2 from
10122 ;; Operand3 is the offset of the stack location holding the current TOC pointer
10123
10124 (define_insn "*call_indirect_aix<mode>"
10125 [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
10126 (match_operand 1 "" "g,g"))
10127 (use (match_operand:P 2 "memory_operand" "<ptrm>,<ptrm>"))
10128 (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10129 (clobber (reg:P LR_REGNO))]
10130 "DEFAULT_ABI == ABI_AIX"
10131 "<ptrload> 2,%2\;b%T0l\;<ptrload> 2,%3(1)"
10132 [(set_attr "type" "jmpreg")
10133 (set_attr "length" "12")])
10134
10135 (define_insn "*call_value_indirect_aix<mode>"
10136 [(set (match_operand 0 "" "")
10137 (call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
10138 (match_operand 2 "" "g,g")))
10139 (use (match_operand:P 3 "memory_operand" "<ptrm>,<ptrm>"))
10140 (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 4 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10141 (clobber (reg:P LR_REGNO))]
10142 "DEFAULT_ABI == ABI_AIX"
10143 "<ptrload> 2,%3\;b%T1l\;<ptrload> 2,%4(1)"
10144 [(set_attr "type" "jmpreg")
10145 (set_attr "length" "12")])
10146
10147 ;; Call to indirect functions with the ELFv2 ABI.
10148 ;; Operand0 is the addresss of the function to call
10149 ;; Operand2 is the offset of the stack location holding the current TOC pointer
10150
10151 (define_insn "*call_indirect_elfv2<mode>"
10152 [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
10153 (match_operand 1 "" "g,g"))
10154 (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 2 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10155 (clobber (reg:P LR_REGNO))]
10156 "DEFAULT_ABI == ABI_ELFv2"
10157 "b%T0l\;<ptrload> 2,%2(1)"
10158 [(set_attr "type" "jmpreg")
10159 (set_attr "length" "8")])
10160
10161 (define_insn "*call_value_indirect_elfv2<mode>"
10162 [(set (match_operand 0 "" "")
10163 (call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
10164 (match_operand 2 "" "g,g")))
10165 (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10166 (clobber (reg:P LR_REGNO))]
10167 "DEFAULT_ABI == ABI_ELFv2"
10168 "b%T1l\;<ptrload> 2,%3(1)"
10169 [(set_attr "type" "jmpreg")
10170 (set_attr "length" "8")])
10171
10172
10173 ;; Call subroutine returning any type.
10174 (define_expand "untyped_call"
10175 [(parallel [(call (match_operand 0 "" "")
10176 (const_int 0))
10177 (match_operand 1 "" "")
10178 (match_operand 2 "" "")])]
10179 ""
10180 "
10181 {
10182 int i;
10183
10184 emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
10185
10186 for (i = 0; i < XVECLEN (operands[2], 0); i++)
10187 {
10188 rtx set = XVECEXP (operands[2], 0, i);
10189 emit_move_insn (SET_DEST (set), SET_SRC (set));
10190 }
10191
10192 /* The optimizer does not know that the call sets the function value
10193 registers we stored in the result block. We avoid problems by
10194 claiming that all hard registers are used and clobbered at this
10195 point. */
10196 emit_insn (gen_blockage ());
10197
10198 DONE;
10199 }")
10200
10201 ;; sibling call patterns
10202 (define_expand "sibcall"
10203 [(parallel [(call (mem:SI (match_operand 0 "address_operand" ""))
10204 (match_operand 1 "" ""))
10205 (use (match_operand 2 "" ""))
10206 (use (reg:SI LR_REGNO))
10207 (simple_return)])]
10208 ""
10209 "
10210 {
10211 #if TARGET_MACHO
10212 if (MACHOPIC_INDIRECT)
10213 operands[0] = machopic_indirect_call_target (operands[0]);
10214 #endif
10215
10216 gcc_assert (GET_CODE (operands[0]) == MEM);
10217 gcc_assert (GET_CODE (operands[1]) == CONST_INT);
10218
10219 operands[0] = XEXP (operands[0], 0);
10220
10221 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10222 {
10223 rs6000_sibcall_aix (NULL_RTX, operands[0], operands[1], operands[2]);
10224 DONE;
10225 }
10226 }")
10227
10228 (define_expand "sibcall_value"
10229 [(parallel [(set (match_operand 0 "register_operand" "")
10230 (call (mem:SI (match_operand 1 "address_operand" ""))
10231 (match_operand 2 "" "")))
10232 (use (match_operand 3 "" ""))
10233 (use (reg:SI LR_REGNO))
10234 (simple_return)])]
10235 ""
10236 "
10237 {
10238 #if TARGET_MACHO
10239 if (MACHOPIC_INDIRECT)
10240 operands[1] = machopic_indirect_call_target (operands[1]);
10241 #endif
10242
10243 gcc_assert (GET_CODE (operands[1]) == MEM);
10244 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10245
10246 operands[1] = XEXP (operands[1], 0);
10247
10248 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10249 {
10250 rs6000_sibcall_aix (operands[0], operands[1], operands[2], operands[3]);
10251 DONE;
10252 }
10253 }")
10254
10255 ;; this and similar patterns must be marked as using LR, otherwise
10256 ;; dataflow will try to delete the store into it. This is true
10257 ;; even when the actual reg to jump to is in CTR, when LR was
10258 ;; saved and restored around the PIC-setting BCL.
10259 (define_insn "*sibcall_local32"
10260 [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
10261 (match_operand 1 "" "g,g"))
10262 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10263 (use (reg:SI LR_REGNO))
10264 (simple_return)]
10265 "(INTVAL (operands[2]) & CALL_LONG) == 0"
10266 "*
10267 {
10268 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10269 output_asm_insn (\"crxor 6,6,6\", operands);
10270
10271 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10272 output_asm_insn (\"creqv 6,6,6\", operands);
10273
10274 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z0@local\" : \"b %z0\";
10275 }"
10276 [(set_attr "type" "branch")
10277 (set_attr "length" "4,8")])
10278
10279 (define_insn "*sibcall_local64"
10280 [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
10281 (match_operand 1 "" "g,g"))
10282 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10283 (use (reg:SI LR_REGNO))
10284 (simple_return)]
10285 "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
10286 "*
10287 {
10288 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10289 output_asm_insn (\"crxor 6,6,6\", operands);
10290
10291 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10292 output_asm_insn (\"creqv 6,6,6\", operands);
10293
10294 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z0@local\" : \"b %z0\";
10295 }"
10296 [(set_attr "type" "branch")
10297 (set_attr "length" "4,8")])
10298
10299 (define_insn "*sibcall_value_local32"
10300 [(set (match_operand 0 "" "")
10301 (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
10302 (match_operand 2 "" "g,g")))
10303 (use (match_operand:SI 3 "immediate_operand" "O,n"))
10304 (use (reg:SI LR_REGNO))
10305 (simple_return)]
10306 "(INTVAL (operands[3]) & CALL_LONG) == 0"
10307 "*
10308 {
10309 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10310 output_asm_insn (\"crxor 6,6,6\", operands);
10311
10312 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10313 output_asm_insn (\"creqv 6,6,6\", operands);
10314
10315 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z1@local\" : \"b %z1\";
10316 }"
10317 [(set_attr "type" "branch")
10318 (set_attr "length" "4,8")])
10319
10320 (define_insn "*sibcall_value_local64"
10321 [(set (match_operand 0 "" "")
10322 (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
10323 (match_operand 2 "" "g,g")))
10324 (use (match_operand:SI 3 "immediate_operand" "O,n"))
10325 (use (reg:SI LR_REGNO))
10326 (simple_return)]
10327 "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
10328 "*
10329 {
10330 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10331 output_asm_insn (\"crxor 6,6,6\", operands);
10332
10333 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10334 output_asm_insn (\"creqv 6,6,6\", operands);
10335
10336 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z1@local\" : \"b %z1\";
10337 }"
10338 [(set_attr "type" "branch")
10339 (set_attr "length" "4,8")])
10340
10341 (define_insn "*sibcall_nonlocal_sysv<mode>"
10342 [(call (mem:SI (match_operand:P 0 "call_operand" "s,s,c,c"))
10343 (match_operand 1 "" ""))
10344 (use (match_operand 2 "immediate_operand" "O,n,O,n"))
10345 (use (reg:SI LR_REGNO))
10346 (simple_return)]
10347 "(DEFAULT_ABI == ABI_DARWIN
10348 || DEFAULT_ABI == ABI_V4)
10349 && (INTVAL (operands[2]) & CALL_LONG) == 0"
10350 "*
10351 {
10352 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10353 output_asm_insn (\"crxor 6,6,6\", operands);
10354
10355 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10356 output_asm_insn (\"creqv 6,6,6\", operands);
10357
10358 if (which_alternative >= 2)
10359 return \"b%T0\";
10360 else if (DEFAULT_ABI == ABI_V4 && flag_pic)
10361 {
10362 gcc_assert (!TARGET_SECURE_PLT);
10363 return \"b %z0@plt\";
10364 }
10365 else
10366 return \"b %z0\";
10367 }"
10368 [(set_attr "type" "branch")
10369 (set_attr "length" "4,8,4,8")])
10370
10371 (define_insn "*sibcall_value_nonlocal_sysv<mode>"
10372 [(set (match_operand 0 "" "")
10373 (call (mem:SI (match_operand:P 1 "call_operand" "s,s,c,c"))
10374 (match_operand 2 "" "")))
10375 (use (match_operand:SI 3 "immediate_operand" "O,n,O,n"))
10376 (use (reg:SI LR_REGNO))
10377 (simple_return)]
10378 "(DEFAULT_ABI == ABI_DARWIN
10379 || DEFAULT_ABI == ABI_V4)
10380 && (INTVAL (operands[3]) & CALL_LONG) == 0"
10381 "*
10382 {
10383 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10384 output_asm_insn (\"crxor 6,6,6\", operands);
10385
10386 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10387 output_asm_insn (\"creqv 6,6,6\", operands);
10388
10389 if (which_alternative >= 2)
10390 return \"b%T1\";
10391 else if (DEFAULT_ABI == ABI_V4 && flag_pic)
10392 {
10393 gcc_assert (!TARGET_SECURE_PLT);
10394 return \"b %z1@plt\";
10395 }
10396 else
10397 return \"b %z1\";
10398 }"
10399 [(set_attr "type" "branch")
10400 (set_attr "length" "4,8,4,8")])
10401
10402 ;; AIX ABI sibling call patterns.
10403
10404 (define_insn "*sibcall_aix<mode>"
10405 [(call (mem:SI (match_operand:P 0 "call_operand" "s,c"))
10406 (match_operand 1 "" "g,g"))
10407 (simple_return)]
10408 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10409 "@
10410 b %z0
10411 b%T0"
10412 [(set_attr "type" "branch")
10413 (set_attr "length" "4")])
10414
10415 (define_insn "*sibcall_value_aix<mode>"
10416 [(set (match_operand 0 "" "")
10417 (call (mem:SI (match_operand:P 1 "call_operand" "s,c"))
10418 (match_operand 2 "" "g,g")))
10419 (simple_return)]
10420 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10421 "@
10422 b %z1
10423 b%T1"
10424 [(set_attr "type" "branch")
10425 (set_attr "length" "4")])
10426
10427 (define_expand "sibcall_epilogue"
10428 [(use (const_int 0))]
10429 ""
10430 {
10431 if (!TARGET_SCHED_PROLOG)
10432 emit_insn (gen_blockage ());
10433 rs6000_emit_epilogue (TRUE);
10434 DONE;
10435 })
10436
10437 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
10438 ;; all of memory. This blocks insns from being moved across this point.
10439
10440 (define_insn "blockage"
10441 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCK)]
10442 ""
10443 "")
10444
10445 (define_expand "probe_stack_address"
10446 [(use (match_operand 0 "address_operand"))]
10447 ""
10448 {
10449 operands[0] = gen_rtx_MEM (Pmode, operands[0]);
10450 MEM_VOLATILE_P (operands[0]) = 1;
10451
10452 if (TARGET_64BIT)
10453 emit_insn (gen_probe_stack_di (operands[0]));
10454 else
10455 emit_insn (gen_probe_stack_si (operands[0]));
10456 DONE;
10457 })
10458
10459 (define_insn "probe_stack_<mode>"
10460 [(set (match_operand:P 0 "memory_operand" "=m")
10461 (unspec:P [(const_int 0)] UNSPEC_PROBE_STACK))]
10462 ""
10463 {
10464 operands[1] = gen_rtx_REG (Pmode, 0);
10465 return "st<wd>%U0%X0 %1,%0";
10466 }
10467 [(set_attr "type" "store")
10468 (set (attr "update")
10469 (if_then_else (match_operand 0 "update_address_mem")
10470 (const_string "yes")
10471 (const_string "no")))
10472 (set (attr "indexed")
10473 (if_then_else (match_operand 0 "indexed_address_mem")
10474 (const_string "yes")
10475 (const_string "no")))
10476 (set_attr "length" "4")])
10477
10478 (define_insn "probe_stack_range<P:mode>"
10479 [(set (match_operand:P 0 "register_operand" "=r")
10480 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
10481 (match_operand:P 2 "register_operand" "r")]
10482 UNSPECV_PROBE_STACK_RANGE))]
10483 ""
10484 "* return output_probe_stack_range (operands[0], operands[2]);"
10485 [(set_attr "type" "three")])
10486 \f
10487 ;; Compare insns are next. Note that the RS/6000 has two types of compares,
10488 ;; signed & unsigned, and one type of branch.
10489 ;;
10490 ;; Start with the DEFINE_EXPANDs to generate the rtl for compares, scc
10491 ;; insns, and branches.
10492
10493 (define_expand "cbranch<mode>4"
10494 [(use (match_operator 0 "rs6000_cbranch_operator"
10495 [(match_operand:GPR 1 "gpc_reg_operand" "")
10496 (match_operand:GPR 2 "reg_or_short_operand" "")]))
10497 (use (match_operand 3 ""))]
10498 ""
10499 "
10500 {
10501 /* Take care of the possibility that operands[2] might be negative but
10502 this might be a logical operation. That insn doesn't exist. */
10503 if (GET_CODE (operands[2]) == CONST_INT
10504 && INTVAL (operands[2]) < 0)
10505 {
10506 operands[2] = force_reg (<MODE>mode, operands[2]);
10507 operands[0] = gen_rtx_fmt_ee (GET_CODE (operands[0]),
10508 GET_MODE (operands[0]),
10509 operands[1], operands[2]);
10510 }
10511
10512 rs6000_emit_cbranch (<MODE>mode, operands);
10513 DONE;
10514 }")
10515
10516 (define_expand "cbranch<mode>4"
10517 [(use (match_operator 0 "rs6000_cbranch_operator"
10518 [(match_operand:FP 1 "gpc_reg_operand" "")
10519 (match_operand:FP 2 "gpc_reg_operand" "")]))
10520 (use (match_operand 3 ""))]
10521 ""
10522 "
10523 {
10524 rs6000_emit_cbranch (<MODE>mode, operands);
10525 DONE;
10526 }")
10527
10528 (define_expand "cstore<mode>4_unsigned"
10529 [(use (match_operator 1 "unsigned_comparison_operator"
10530 [(match_operand:P 2 "gpc_reg_operand" "")
10531 (match_operand:P 3 "reg_or_short_operand" "")]))
10532 (clobber (match_operand:P 0 "register_operand"))]
10533 ""
10534 {
10535 enum rtx_code cond_code = GET_CODE (operands[1]);
10536
10537 rtx op0 = operands[0];
10538 rtx op1 = operands[2];
10539 rtx op2 = operands[3];
10540
10541 if (cond_code == GEU || cond_code == LTU)
10542 {
10543 cond_code = swap_condition (cond_code);
10544 op1 = operands[3];
10545 op2 = operands[2];
10546 }
10547
10548 if (!gpc_reg_operand (op1, <MODE>mode))
10549 op1 = force_reg (<MODE>mode, op1);
10550 if (!reg_or_short_operand (op2, <MODE>mode))
10551 op2 = force_reg (<MODE>mode, op2);
10552
10553 rtx tmp = gen_reg_rtx (<MODE>mode);
10554 rtx tmp2 = gen_reg_rtx (<MODE>mode);
10555
10556 emit_insn (gen_subf<mode>3_carry (tmp, op1, op2));
10557 emit_insn (gen_subf<mode>3_carry_in_xx (tmp2));
10558
10559 if (cond_code == LEU)
10560 emit_insn (gen_add<mode>3 (op0, tmp2, const1_rtx));
10561 else
10562 emit_insn (gen_neg<mode>2 (op0, tmp2));
10563
10564 DONE;
10565 })
10566
10567 (define_expand "cstore_si_as_di"
10568 [(use (match_operator 1 "unsigned_comparison_operator"
10569 [(match_operand:SI 2 "gpc_reg_operand")
10570 (match_operand:SI 3 "reg_or_short_operand")]))
10571 (clobber (match_operand:SI 0 "register_operand"))]
10572 ""
10573 {
10574 int uns_flag = unsigned_comparison_operator (operands[1], VOIDmode) ? 1 : 0;
10575 enum rtx_code cond_code = signed_condition (GET_CODE (operands[1]));
10576
10577 rtx op1 = gen_reg_rtx (DImode);
10578 rtx op2 = gen_reg_rtx (DImode);
10579 convert_move (op1, operands[2], uns_flag);
10580 convert_move (op2, operands[3], uns_flag);
10581
10582 if (cond_code == GT || cond_code == LE)
10583 {
10584 cond_code = swap_condition (cond_code);
10585 std::swap (op1, op2);
10586 }
10587
10588 rtx tmp = gen_reg_rtx (DImode);
10589 rtx tmp2 = gen_reg_rtx (DImode);
10590 emit_insn (gen_subdi3 (tmp, op1, op2));
10591 emit_insn (gen_lshrdi3 (tmp2, tmp, GEN_INT (63)));
10592
10593 rtx tmp3;
10594 switch (cond_code)
10595 {
10596 default:
10597 gcc_unreachable ();
10598 case LT:
10599 tmp3 = tmp2;
10600 break;
10601 case GE:
10602 tmp3 = gen_reg_rtx (DImode);
10603 emit_insn (gen_xordi3 (tmp3, tmp2, const1_rtx));
10604 break;
10605 }
10606
10607 convert_move (operands[0], tmp3, 1);
10608
10609 DONE;
10610 })
10611
10612 (define_expand "cstore<mode>4_signed_imm"
10613 [(use (match_operator 1 "signed_comparison_operator"
10614 [(match_operand:GPR 2 "gpc_reg_operand")
10615 (match_operand:GPR 3 "immediate_operand")]))
10616 (clobber (match_operand:GPR 0 "register_operand"))]
10617 ""
10618 {
10619 bool invert = false;
10620
10621 enum rtx_code cond_code = GET_CODE (operands[1]);
10622
10623 rtx op0 = operands[0];
10624 rtx op1 = operands[2];
10625 HOST_WIDE_INT val = INTVAL (operands[3]);
10626
10627 if (cond_code == GE || cond_code == GT)
10628 {
10629 cond_code = reverse_condition (cond_code);
10630 invert = true;
10631 }
10632
10633 if (cond_code == LE)
10634 val++;
10635
10636 rtx tmp = gen_reg_rtx (<MODE>mode);
10637 emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
10638 rtx x = gen_reg_rtx (<MODE>mode);
10639 if (val < 0)
10640 emit_insn (gen_and<mode>3 (x, op1, tmp));
10641 else
10642 emit_insn (gen_ior<mode>3 (x, op1, tmp));
10643
10644 if (invert)
10645 {
10646 rtx tmp = gen_reg_rtx (<MODE>mode);
10647 emit_insn (gen_one_cmpl<mode>2 (tmp, x));
10648 x = tmp;
10649 }
10650
10651 int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
10652 emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
10653
10654 DONE;
10655 })
10656
10657 (define_expand "cstore<mode>4_unsigned_imm"
10658 [(use (match_operator 1 "unsigned_comparison_operator"
10659 [(match_operand:GPR 2 "gpc_reg_operand")
10660 (match_operand:GPR 3 "immediate_operand")]))
10661 (clobber (match_operand:GPR 0 "register_operand"))]
10662 ""
10663 {
10664 bool invert = false;
10665
10666 enum rtx_code cond_code = GET_CODE (operands[1]);
10667
10668 rtx op0 = operands[0];
10669 rtx op1 = operands[2];
10670 HOST_WIDE_INT val = INTVAL (operands[3]);
10671
10672 if (cond_code == GEU || cond_code == GTU)
10673 {
10674 cond_code = reverse_condition (cond_code);
10675 invert = true;
10676 }
10677
10678 if (cond_code == LEU)
10679 val++;
10680
10681 rtx tmp = gen_reg_rtx (<MODE>mode);
10682 rtx tmp2 = gen_reg_rtx (<MODE>mode);
10683 emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
10684 emit_insn (gen_one_cmpl<mode>2 (tmp2, op1));
10685 rtx x = gen_reg_rtx (<MODE>mode);
10686 if (val < 0)
10687 emit_insn (gen_ior<mode>3 (x, tmp, tmp2));
10688 else
10689 emit_insn (gen_and<mode>3 (x, tmp, tmp2));
10690
10691 if (invert)
10692 {
10693 rtx tmp = gen_reg_rtx (<MODE>mode);
10694 emit_insn (gen_one_cmpl<mode>2 (tmp, x));
10695 x = tmp;
10696 }
10697
10698 int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
10699 emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
10700
10701 DONE;
10702 })
10703
10704 (define_expand "cstore<mode>4"
10705 [(use (match_operator 1 "rs6000_cbranch_operator"
10706 [(match_operand:GPR 2 "gpc_reg_operand")
10707 (match_operand:GPR 3 "reg_or_short_operand")]))
10708 (clobber (match_operand:GPR 0 "register_operand"))]
10709 ""
10710 {
10711 /* Use ISEL if the user asked for it. */
10712 if (TARGET_ISEL)
10713 rs6000_emit_sISEL (<MODE>mode, operands);
10714
10715 /* Expanding EQ and NE directly to some machine instructions does not help
10716 but does hurt combine. So don't. */
10717 else if (GET_CODE (operands[1]) == EQ)
10718 emit_insn (gen_eq<mode>3 (operands[0], operands[2], operands[3]));
10719 else if (<MODE>mode == Pmode
10720 && GET_CODE (operands[1]) == NE)
10721 emit_insn (gen_ne<mode>3 (operands[0], operands[2], operands[3]));
10722 else if (GET_CODE (operands[1]) == NE)
10723 {
10724 rtx tmp = gen_reg_rtx (<MODE>mode);
10725 emit_insn (gen_eq<mode>3 (tmp, operands[2], operands[3]));
10726 emit_insn (gen_xor<mode>3 (operands[0], tmp, const1_rtx));
10727 }
10728
10729 /* Expanding the unsigned comparisons however helps a lot: all the neg_ltu
10730 etc. combinations magically work out just right. */
10731 else if (<MODE>mode == Pmode
10732 && unsigned_comparison_operator (operands[1], VOIDmode))
10733 emit_insn (gen_cstore<mode>4_unsigned (operands[0], operands[1],
10734 operands[2], operands[3]));
10735
10736 /* For comparisons smaller than Pmode we can cheaply do things in Pmode. */
10737 else if (<MODE>mode == SImode && Pmode == DImode)
10738 emit_insn (gen_cstore_si_as_di (operands[0], operands[1],
10739 operands[2], operands[3]));
10740
10741 /* For signed comparisons against a constant, we can do some simple
10742 bit-twiddling. */
10743 else if (signed_comparison_operator (operands[1], VOIDmode)
10744 && CONST_INT_P (operands[3]))
10745 emit_insn (gen_cstore<mode>4_signed_imm (operands[0], operands[1],
10746 operands[2], operands[3]));
10747
10748 /* And similarly for unsigned comparisons. */
10749 else if (unsigned_comparison_operator (operands[1], VOIDmode)
10750 && CONST_INT_P (operands[3]))
10751 emit_insn (gen_cstore<mode>4_unsigned_imm (operands[0], operands[1],
10752 operands[2], operands[3]));
10753
10754 /* Everything else, use the mfcr brute force. */
10755 else
10756 rs6000_emit_sCOND (<MODE>mode, operands);
10757
10758 DONE;
10759 })
10760
10761 (define_expand "cstore<mode>4"
10762 [(use (match_operator 1 "rs6000_cbranch_operator"
10763 [(match_operand:FP 2 "gpc_reg_operand" "")
10764 (match_operand:FP 3 "gpc_reg_operand" "")]))
10765 (clobber (match_operand:SI 0 "register_operand"))]
10766 ""
10767 {
10768 rs6000_emit_sCOND (<MODE>mode, operands);
10769 DONE;
10770 })
10771
10772
10773 (define_expand "stack_protect_set"
10774 [(match_operand 0 "memory_operand" "")
10775 (match_operand 1 "memory_operand" "")]
10776 ""
10777 {
10778 #ifdef TARGET_THREAD_SSP_OFFSET
10779 rtx tlsreg = gen_rtx_REG (Pmode, TARGET_64BIT ? 13 : 2);
10780 rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
10781 operands[1] = gen_rtx_MEM (Pmode, addr);
10782 #endif
10783 if (TARGET_64BIT)
10784 emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
10785 else
10786 emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
10787 DONE;
10788 })
10789
10790 (define_insn "stack_protect_setsi"
10791 [(set (match_operand:SI 0 "memory_operand" "=m")
10792 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
10793 (set (match_scratch:SI 2 "=&r") (const_int 0))]
10794 "TARGET_32BIT"
10795 "lwz%U1%X1 %2,%1\;stw%U0%X0 %2,%0\;li %2,0"
10796 [(set_attr "type" "three")
10797 (set_attr "length" "12")])
10798
10799 (define_insn "stack_protect_setdi"
10800 [(set (match_operand:DI 0 "memory_operand" "=Y")
10801 (unspec:DI [(match_operand:DI 1 "memory_operand" "Y")] UNSPEC_SP_SET))
10802 (set (match_scratch:DI 2 "=&r") (const_int 0))]
10803 "TARGET_64BIT"
10804 "ld%U1%X1 %2,%1\;std%U0%X0 %2,%0\;li %2,0"
10805 [(set_attr "type" "three")
10806 (set_attr "length" "12")])
10807
10808 (define_expand "stack_protect_test"
10809 [(match_operand 0 "memory_operand" "")
10810 (match_operand 1 "memory_operand" "")
10811 (match_operand 2 "" "")]
10812 ""
10813 {
10814 rtx test, op0, op1;
10815 #ifdef TARGET_THREAD_SSP_OFFSET
10816 rtx tlsreg = gen_rtx_REG (Pmode, TARGET_64BIT ? 13 : 2);
10817 rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
10818 operands[1] = gen_rtx_MEM (Pmode, addr);
10819 #endif
10820 op0 = operands[0];
10821 op1 = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, operands[1]), UNSPEC_SP_TEST);
10822 test = gen_rtx_EQ (VOIDmode, op0, op1);
10823 emit_jump_insn (gen_cbranchsi4 (test, op0, op1, operands[2]));
10824 DONE;
10825 })
10826
10827 (define_insn "stack_protect_testsi"
10828 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
10829 (unspec:CCEQ [(match_operand:SI 1 "memory_operand" "m,m")
10830 (match_operand:SI 2 "memory_operand" "m,m")]
10831 UNSPEC_SP_TEST))
10832 (set (match_scratch:SI 4 "=r,r") (const_int 0))
10833 (clobber (match_scratch:SI 3 "=&r,&r"))]
10834 "TARGET_32BIT"
10835 "@
10836 lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0
10837 lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;cmplw %0,%3,%4\;li %3,0\;li %4,0"
10838 [(set_attr "length" "16,20")])
10839
10840 (define_insn "stack_protect_testdi"
10841 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
10842 (unspec:CCEQ [(match_operand:DI 1 "memory_operand" "Y,Y")
10843 (match_operand:DI 2 "memory_operand" "Y,Y")]
10844 UNSPEC_SP_TEST))
10845 (set (match_scratch:DI 4 "=r,r") (const_int 0))
10846 (clobber (match_scratch:DI 3 "=&r,&r"))]
10847 "TARGET_64BIT"
10848 "@
10849 ld%U1%X1 %3,%1\;ld%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0
10850 ld%U1%X1 %3,%1\;ld%U2%X2 %4,%2\;cmpld %0,%3,%4\;li %3,0\;li %4,0"
10851 [(set_attr "length" "16,20")])
10852
10853 \f
10854 ;; Here are the actual compare insns.
10855 (define_insn "*cmp<mode>_signed"
10856 [(set (match_operand:CC 0 "cc_reg_operand" "=y")
10857 (compare:CC (match_operand:GPR 1 "gpc_reg_operand" "r")
10858 (match_operand:GPR 2 "reg_or_short_operand" "rI")))]
10859 ""
10860 "cmp<wd>%I2 %0,%1,%2"
10861 [(set_attr "type" "cmp")])
10862
10863 (define_insn "*cmp<mode>_unsigned"
10864 [(set (match_operand:CCUNS 0 "cc_reg_operand" "=y")
10865 (compare:CCUNS (match_operand:GPR 1 "gpc_reg_operand" "r")
10866 (match_operand:GPR 2 "reg_or_u_short_operand" "rK")))]
10867 ""
10868 "cmpl<wd>%I2 %0,%1,%2"
10869 [(set_attr "type" "cmp")])
10870
10871 ;; If we are comparing a register for equality with a large constant,
10872 ;; we can do this with an XOR followed by a compare. But this is profitable
10873 ;; only if the large constant is only used for the comparison (and in this
10874 ;; case we already have a register to reuse as scratch).
10875 ;;
10876 ;; For 64-bit registers, we could only do so if the constant's bit 15 is clear:
10877 ;; otherwise we'd need to XOR with FFFFFFFF????0000 which is not available.
10878
10879 (define_peephole2
10880 [(set (match_operand:SI 0 "register_operand")
10881 (match_operand:SI 1 "logical_const_operand" ""))
10882 (set (match_dup 0) (match_operator:SI 3 "boolean_or_operator"
10883 [(match_dup 0)
10884 (match_operand:SI 2 "logical_const_operand" "")]))
10885 (set (match_operand:CC 4 "cc_reg_operand" "")
10886 (compare:CC (match_operand:SI 5 "gpc_reg_operand" "")
10887 (match_dup 0)))
10888 (set (pc)
10889 (if_then_else (match_operator 6 "equality_operator"
10890 [(match_dup 4) (const_int 0)])
10891 (match_operand 7 "" "")
10892 (match_operand 8 "" "")))]
10893 "peep2_reg_dead_p (3, operands[0])
10894 && peep2_reg_dead_p (4, operands[4])
10895 && REGNO (operands[0]) != REGNO (operands[5])"
10896 [(set (match_dup 0) (xor:SI (match_dup 5) (match_dup 9)))
10897 (set (match_dup 4) (compare:CC (match_dup 0) (match_dup 10)))
10898 (set (pc) (if_then_else (match_dup 6) (match_dup 7) (match_dup 8)))]
10899
10900 {
10901 /* Get the constant we are comparing against, and see what it looks like
10902 when sign-extended from 16 to 32 bits. Then see what constant we could
10903 XOR with SEXTC to get the sign-extended value. */
10904 rtx cnst = simplify_const_binary_operation (GET_CODE (operands[3]),
10905 SImode,
10906 operands[1], operands[2]);
10907 HOST_WIDE_INT c = INTVAL (cnst);
10908 HOST_WIDE_INT sextc = ((c & 0xffff) ^ 0x8000) - 0x8000;
10909 HOST_WIDE_INT xorv = c ^ sextc;
10910
10911 operands[9] = GEN_INT (xorv);
10912 operands[10] = GEN_INT (sextc);
10913 })
10914
10915 ;; The following two insns don't exist as single insns, but if we provide
10916 ;; them, we can swap an add and compare, which will enable us to overlap more
10917 ;; of the required delay between a compare and branch. We generate code for
10918 ;; them by splitting.
10919
10920 (define_insn ""
10921 [(set (match_operand:CC 3 "cc_reg_operand" "=y")
10922 (compare:CC (match_operand:SI 1 "gpc_reg_operand" "r")
10923 (match_operand:SI 2 "short_cint_operand" "i")))
10924 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
10925 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "i")))]
10926 ""
10927 "#"
10928 [(set_attr "length" "8")])
10929
10930 (define_insn ""
10931 [(set (match_operand:CCUNS 3 "cc_reg_operand" "=y")
10932 (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "r")
10933 (match_operand:SI 2 "u_short_cint_operand" "i")))
10934 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
10935 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "i")))]
10936 ""
10937 "#"
10938 [(set_attr "length" "8")])
10939
10940 (define_split
10941 [(set (match_operand:CC 3 "cc_reg_operand" "")
10942 (compare:CC (match_operand:SI 1 "gpc_reg_operand" "")
10943 (match_operand:SI 2 "short_cint_operand" "")))
10944 (set (match_operand:SI 0 "gpc_reg_operand" "")
10945 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "")))]
10946 ""
10947 [(set (match_dup 3) (compare:CC (match_dup 1) (match_dup 2)))
10948 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 4)))])
10949
10950 (define_split
10951 [(set (match_operand:CCUNS 3 "cc_reg_operand" "")
10952 (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "")
10953 (match_operand:SI 2 "u_short_cint_operand" "")))
10954 (set (match_operand:SI 0 "gpc_reg_operand" "")
10955 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "")))]
10956 ""
10957 [(set (match_dup 3) (compare:CCUNS (match_dup 1) (match_dup 2)))
10958 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 4)))])
10959
10960 ;; Only need to compare second words if first words equal
10961 (define_insn "*cmp<mode>_internal1"
10962 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
10963 (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
10964 (match_operand:IBM128 2 "gpc_reg_operand" "d")))]
10965 "!TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode)
10966 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
10967 "fcmpu %0,%1,%2\;bne %0,$+8\;fcmpu %0,%L1,%L2"
10968 [(set_attr "type" "fpcompare")
10969 (set_attr "length" "12")])
10970
10971 (define_insn_and_split "*cmp<mode>_internal2"
10972 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
10973 (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
10974 (match_operand:IBM128 2 "gpc_reg_operand" "d")))
10975 (clobber (match_scratch:DF 3 "=d"))
10976 (clobber (match_scratch:DF 4 "=d"))
10977 (clobber (match_scratch:DF 5 "=d"))
10978 (clobber (match_scratch:DF 6 "=d"))
10979 (clobber (match_scratch:DF 7 "=d"))
10980 (clobber (match_scratch:DF 8 "=d"))
10981 (clobber (match_scratch:DF 9 "=d"))
10982 (clobber (match_scratch:DF 10 "=d"))
10983 (clobber (match_scratch:GPR 11 "=b"))]
10984 "TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode)
10985 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
10986 "#"
10987 "&& reload_completed"
10988 [(set (match_dup 3) (match_dup 14))
10989 (set (match_dup 4) (match_dup 15))
10990 (set (match_dup 9) (abs:DF (match_dup 5)))
10991 (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 3)))
10992 (set (pc) (if_then_else (ne (match_dup 0) (const_int 0))
10993 (label_ref (match_dup 12))
10994 (pc)))
10995 (set (match_dup 0) (compare:CCFP (match_dup 5) (match_dup 7)))
10996 (set (pc) (label_ref (match_dup 13)))
10997 (match_dup 12)
10998 (set (match_dup 10) (minus:DF (match_dup 5) (match_dup 7)))
10999 (set (match_dup 9) (minus:DF (match_dup 6) (match_dup 8)))
11000 (set (match_dup 9) (plus:DF (match_dup 10) (match_dup 9)))
11001 (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 4)))
11002 (match_dup 13)]
11003 {
11004 REAL_VALUE_TYPE rv;
11005 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
11006 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
11007
11008 operands[5] = simplify_gen_subreg (DFmode, operands[1], <MODE>mode, hi_word);
11009 operands[6] = simplify_gen_subreg (DFmode, operands[1], <MODE>mode, lo_word);
11010 operands[7] = simplify_gen_subreg (DFmode, operands[2], <MODE>mode, hi_word);
11011 operands[8] = simplify_gen_subreg (DFmode, operands[2], <MODE>mode, lo_word);
11012 operands[12] = gen_label_rtx ();
11013 operands[13] = gen_label_rtx ();
11014 real_inf (&rv);
11015 operands[14] = force_const_mem (DFmode,
11016 const_double_from_real_value (rv, DFmode));
11017 operands[15] = force_const_mem (DFmode,
11018 const_double_from_real_value (dconst0,
11019 DFmode));
11020 if (TARGET_TOC)
11021 {
11022 rtx tocref;
11023 tocref = create_TOC_reference (XEXP (operands[14], 0), operands[11]);
11024 operands[14] = gen_const_mem (DFmode, tocref);
11025 tocref = create_TOC_reference (XEXP (operands[15], 0), operands[11]);
11026 operands[15] = gen_const_mem (DFmode, tocref);
11027 set_mem_alias_set (operands[14], get_TOC_alias_set ());
11028 set_mem_alias_set (operands[15], get_TOC_alias_set ());
11029 }
11030 })
11031 \f
11032 ;; Now we have the scc insns. We can do some combinations because of the
11033 ;; way the machine works.
11034 ;;
11035 ;; Note that this is probably faster if we can put an insn between the
11036 ;; mfcr and rlinm, but this is tricky. Let's leave it for now. In most
11037 ;; cases the insns below which don't use an intermediate CR field will
11038 ;; be used instead.
11039 (define_insn ""
11040 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11041 (match_operator:SI 1 "scc_comparison_operator"
11042 [(match_operand 2 "cc_reg_operand" "y")
11043 (const_int 0)]))]
11044 ""
11045 "mfcr %0%Q2\;rlwinm %0,%0,%J1,1"
11046 [(set (attr "type")
11047 (cond [(match_test "TARGET_MFCRF")
11048 (const_string "mfcrf")
11049 ]
11050 (const_string "mfcr")))
11051 (set_attr "length" "8")])
11052
11053 ;; Same as above, but get the GT bit.
11054 (define_insn "move_from_CR_gt_bit"
11055 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11056 (unspec:SI [(match_operand 1 "cc_reg_operand" "y")] UNSPEC_MV_CR_GT))]
11057 "TARGET_HARD_FLOAT && !TARGET_FPRS"
11058 "mfcr %0\;rlwinm %0,%0,%D1,31,31"
11059 [(set_attr "type" "mfcr")
11060 (set_attr "length" "8")])
11061
11062 ;; Same as above, but get the OV/ORDERED bit.
11063 (define_insn "move_from_CR_ov_bit"
11064 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11065 (unspec:SI [(match_operand:CC 1 "cc_reg_operand" "y")]
11066 UNSPEC_MV_CR_OV))]
11067 "TARGET_ISEL"
11068 "mfcr %0\;rlwinm %0,%0,%t1,1"
11069 [(set_attr "type" "mfcr")
11070 (set_attr "length" "8")])
11071
11072 (define_insn ""
11073 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
11074 (match_operator:DI 1 "scc_comparison_operator"
11075 [(match_operand 2 "cc_reg_operand" "y")
11076 (const_int 0)]))]
11077 "TARGET_POWERPC64"
11078 "mfcr %0%Q2\;rlwinm %0,%0,%J1,1"
11079 [(set (attr "type")
11080 (cond [(match_test "TARGET_MFCRF")
11081 (const_string "mfcrf")
11082 ]
11083 (const_string "mfcr")))
11084 (set_attr "length" "8")])
11085
11086 (define_insn ""
11087 [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
11088 (compare:CC (match_operator:SI 1 "scc_comparison_operator"
11089 [(match_operand 2 "cc_reg_operand" "y,y")
11090 (const_int 0)])
11091 (const_int 0)))
11092 (set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
11093 (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
11094 "TARGET_32BIT"
11095 "@
11096 mfcr %3%Q2\;rlwinm. %3,%3,%J1,1
11097 #"
11098 [(set_attr "type" "shift")
11099 (set_attr "dot" "yes")
11100 (set_attr "length" "8,16")])
11101
11102 (define_split
11103 [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
11104 (compare:CC (match_operator:SI 1 "scc_comparison_operator"
11105 [(match_operand 2 "cc_reg_operand" "")
11106 (const_int 0)])
11107 (const_int 0)))
11108 (set (match_operand:SI 3 "gpc_reg_operand" "")
11109 (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
11110 "TARGET_32BIT && reload_completed"
11111 [(set (match_dup 3)
11112 (match_op_dup 1 [(match_dup 2) (const_int 0)]))
11113 (set (match_dup 0)
11114 (compare:CC (match_dup 3)
11115 (const_int 0)))]
11116 "")
11117
11118 (define_insn ""
11119 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11120 (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
11121 [(match_operand 2 "cc_reg_operand" "y")
11122 (const_int 0)])
11123 (match_operand:SI 3 "const_int_operand" "n")))]
11124 ""
11125 "*
11126 {
11127 int is_bit = ccr_bit (operands[1], 1);
11128 int put_bit = 31 - (INTVAL (operands[3]) & 31);
11129 int count;
11130
11131 if (is_bit >= put_bit)
11132 count = is_bit - put_bit;
11133 else
11134 count = 32 - (put_bit - is_bit);
11135
11136 operands[4] = GEN_INT (count);
11137 operands[5] = GEN_INT (put_bit);
11138
11139 return \"mfcr %0%Q2\;rlwinm %0,%0,%4,%5,%5\";
11140 }"
11141 [(set (attr "type")
11142 (cond [(match_test "TARGET_MFCRF")
11143 (const_string "mfcrf")
11144 ]
11145 (const_string "mfcr")))
11146 (set_attr "length" "8")])
11147
11148 (define_insn ""
11149 [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
11150 (compare:CC
11151 (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
11152 [(match_operand 2 "cc_reg_operand" "y,y")
11153 (const_int 0)])
11154 (match_operand:SI 3 "const_int_operand" "n,n"))
11155 (const_int 0)))
11156 (set (match_operand:SI 4 "gpc_reg_operand" "=r,r")
11157 (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
11158 (match_dup 3)))]
11159 ""
11160 "*
11161 {
11162 int is_bit = ccr_bit (operands[1], 1);
11163 int put_bit = 31 - (INTVAL (operands[3]) & 31);
11164 int count;
11165
11166 /* Force split for non-cc0 compare. */
11167 if (which_alternative == 1)
11168 return \"#\";
11169
11170 if (is_bit >= put_bit)
11171 count = is_bit - put_bit;
11172 else
11173 count = 32 - (put_bit - is_bit);
11174
11175 operands[5] = GEN_INT (count);
11176 operands[6] = GEN_INT (put_bit);
11177
11178 return \"mfcr %4%Q2\;rlwinm. %4,%4,%5,%6,%6\";
11179 }"
11180 [(set_attr "type" "shift")
11181 (set_attr "dot" "yes")
11182 (set_attr "length" "8,16")])
11183
11184 (define_split
11185 [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
11186 (compare:CC
11187 (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
11188 [(match_operand 2 "cc_reg_operand" "")
11189 (const_int 0)])
11190 (match_operand:SI 3 "const_int_operand" ""))
11191 (const_int 0)))
11192 (set (match_operand:SI 4 "gpc_reg_operand" "")
11193 (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
11194 (match_dup 3)))]
11195 "reload_completed"
11196 [(set (match_dup 4)
11197 (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
11198 (match_dup 3)))
11199 (set (match_dup 0)
11200 (compare:CC (match_dup 4)
11201 (const_int 0)))]
11202 "")
11203
11204 ;; There is a 3 cycle delay between consecutive mfcr instructions
11205 ;; so it is useful to combine 2 scc instructions to use only one mfcr.
11206
11207 (define_peephole
11208 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11209 (match_operator:SI 1 "scc_comparison_operator"
11210 [(match_operand 2 "cc_reg_operand" "y")
11211 (const_int 0)]))
11212 (set (match_operand:SI 3 "gpc_reg_operand" "=r")
11213 (match_operator:SI 4 "scc_comparison_operator"
11214 [(match_operand 5 "cc_reg_operand" "y")
11215 (const_int 0)]))]
11216 "REGNO (operands[2]) != REGNO (operands[5])"
11217 "mfcr %3\;rlwinm %0,%3,%J1,1\;rlwinm %3,%3,%J4,1"
11218 [(set_attr "type" "mfcr")
11219 (set_attr "length" "12")])
11220
11221 (define_peephole
11222 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
11223 (match_operator:DI 1 "scc_comparison_operator"
11224 [(match_operand 2 "cc_reg_operand" "y")
11225 (const_int 0)]))
11226 (set (match_operand:DI 3 "gpc_reg_operand" "=r")
11227 (match_operator:DI 4 "scc_comparison_operator"
11228 [(match_operand 5 "cc_reg_operand" "y")
11229 (const_int 0)]))]
11230 "TARGET_POWERPC64 && REGNO (operands[2]) != REGNO (operands[5])"
11231 "mfcr %3\;rlwinm %0,%3,%J1,1\;rlwinm %3,%3,%J4,1"
11232 [(set_attr "type" "mfcr")
11233 (set_attr "length" "12")])
11234
11235
11236 (define_mode_attr scc_eq_op2 [(SI "rKLI")
11237 (DI "rKJI")])
11238
11239 (define_insn_and_split "eq<mode>3"
11240 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
11241 (eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
11242 (match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>")))
11243 (clobber (match_scratch:GPR 3 "=r"))
11244 (clobber (match_scratch:GPR 4 "=r"))]
11245 ""
11246 "#"
11247 ""
11248 [(set (match_dup 4)
11249 (clz:GPR (match_dup 3)))
11250 (set (match_dup 0)
11251 (lshiftrt:GPR (match_dup 4)
11252 (match_dup 5)))]
11253 {
11254 operands[3] = rs6000_emit_eqne (<MODE>mode,
11255 operands[1], operands[2], operands[3]);
11256
11257 if (GET_CODE (operands[4]) == SCRATCH)
11258 operands[4] = gen_reg_rtx (<MODE>mode);
11259
11260 operands[5] = GEN_INT (exact_log2 (GET_MODE_BITSIZE (<MODE>mode)));
11261 }
11262 [(set (attr "length")
11263 (if_then_else (match_test "operands[2] == const0_rtx")
11264 (const_string "8")
11265 (const_string "12")))])
11266
11267 (define_insn_and_split "ne<mode>3"
11268 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11269 (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
11270 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")))
11271 (clobber (match_scratch:P 3 "=r"))
11272 (clobber (match_scratch:P 4 "=r"))
11273 (clobber (reg:P CA_REGNO))]
11274 "!TARGET_ISEL"
11275 "#"
11276 ""
11277 [(parallel [(set (match_dup 4)
11278 (plus:P (match_dup 3)
11279 (const_int -1)))
11280 (set (reg:P CA_REGNO)
11281 (ne:P (match_dup 3)
11282 (const_int 0)))])
11283 (parallel [(set (match_dup 0)
11284 (plus:P (plus:P (not:P (match_dup 4))
11285 (reg:P CA_REGNO))
11286 (match_dup 3)))
11287 (clobber (reg:P CA_REGNO))])]
11288 {
11289 operands[3] = rs6000_emit_eqne (<MODE>mode,
11290 operands[1], operands[2], operands[3]);
11291
11292 if (GET_CODE (operands[4]) == SCRATCH)
11293 operands[4] = gen_reg_rtx (<MODE>mode);
11294 }
11295 [(set (attr "length")
11296 (if_then_else (match_test "operands[2] == const0_rtx")
11297 (const_string "8")
11298 (const_string "12")))])
11299
11300 (define_insn_and_split "*neg_eq_<mode>"
11301 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11302 (neg:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
11303 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
11304 (clobber (match_scratch:P 3 "=r"))
11305 (clobber (match_scratch:P 4 "=r"))
11306 (clobber (reg:P CA_REGNO))]
11307 ""
11308 "#"
11309 ""
11310 [(parallel [(set (match_dup 4)
11311 (plus:P (match_dup 3)
11312 (const_int -1)))
11313 (set (reg:P CA_REGNO)
11314 (ne:P (match_dup 3)
11315 (const_int 0)))])
11316 (parallel [(set (match_dup 0)
11317 (plus:P (reg:P CA_REGNO)
11318 (const_int -1)))
11319 (clobber (reg:P CA_REGNO))])]
11320 {
11321 operands[3] = rs6000_emit_eqne (<MODE>mode,
11322 operands[1], operands[2], operands[3]);
11323
11324 if (GET_CODE (operands[4]) == SCRATCH)
11325 operands[4] = gen_reg_rtx (<MODE>mode);
11326 }
11327 [(set (attr "length")
11328 (if_then_else (match_test "operands[2] == const0_rtx")
11329 (const_string "8")
11330 (const_string "12")))])
11331
11332 (define_insn_and_split "*neg_ne_<mode>"
11333 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11334 (neg:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
11335 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
11336 (clobber (match_scratch:P 3 "=r"))
11337 (clobber (match_scratch:P 4 "=r"))
11338 (clobber (reg:P CA_REGNO))]
11339 ""
11340 "#"
11341 ""
11342 [(parallel [(set (match_dup 4)
11343 (neg:P (match_dup 3)))
11344 (set (reg:P CA_REGNO)
11345 (eq:P (match_dup 3)
11346 (const_int 0)))])
11347 (parallel [(set (match_dup 0)
11348 (plus:P (reg:P CA_REGNO)
11349 (const_int -1)))
11350 (clobber (reg:P CA_REGNO))])]
11351 {
11352 operands[3] = rs6000_emit_eqne (<MODE>mode,
11353 operands[1], operands[2], operands[3]);
11354
11355 if (GET_CODE (operands[4]) == SCRATCH)
11356 operands[4] = gen_reg_rtx (<MODE>mode);
11357 }
11358 [(set (attr "length")
11359 (if_then_else (match_test "operands[2] == const0_rtx")
11360 (const_string "8")
11361 (const_string "12")))])
11362
11363 (define_insn_and_split "*plus_eq_<mode>"
11364 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11365 (plus:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
11366 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
11367 (match_operand:P 3 "gpc_reg_operand" "r")))
11368 (clobber (match_scratch:P 4 "=r"))
11369 (clobber (match_scratch:P 5 "=r"))
11370 (clobber (reg:P CA_REGNO))]
11371 ""
11372 "#"
11373 ""
11374 [(parallel [(set (match_dup 5)
11375 (neg:P (match_dup 4)))
11376 (set (reg:P CA_REGNO)
11377 (eq:P (match_dup 4)
11378 (const_int 0)))])
11379 (parallel [(set (match_dup 0)
11380 (plus:P (match_dup 3)
11381 (reg:P CA_REGNO)))
11382 (clobber (reg:P CA_REGNO))])]
11383 {
11384 operands[4] = rs6000_emit_eqne (<MODE>mode,
11385 operands[1], operands[2], operands[4]);
11386
11387 if (GET_CODE (operands[5]) == SCRATCH)
11388 operands[5] = gen_reg_rtx (<MODE>mode);
11389 }
11390 [(set (attr "length")
11391 (if_then_else (match_test "operands[2] == const0_rtx")
11392 (const_string "8")
11393 (const_string "12")))])
11394
11395 (define_insn_and_split "*plus_ne_<mode>"
11396 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11397 (plus:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
11398 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
11399 (match_operand:P 3 "gpc_reg_operand" "r")))
11400 (clobber (match_scratch:P 4 "=r"))
11401 (clobber (match_scratch:P 5 "=r"))
11402 (clobber (reg:P CA_REGNO))]
11403 ""
11404 "#"
11405 ""
11406 [(parallel [(set (match_dup 5)
11407 (plus:P (match_dup 4)
11408 (const_int -1)))
11409 (set (reg:P CA_REGNO)
11410 (ne:P (match_dup 4)
11411 (const_int 0)))])
11412 (parallel [(set (match_dup 0)
11413 (plus:P (match_dup 3)
11414 (reg:P CA_REGNO)))
11415 (clobber (reg:P CA_REGNO))])]
11416 {
11417 operands[4] = rs6000_emit_eqne (<MODE>mode,
11418 operands[1], operands[2], operands[4]);
11419
11420 if (GET_CODE (operands[5]) == SCRATCH)
11421 operands[5] = gen_reg_rtx (<MODE>mode);
11422 }
11423 [(set (attr "length")
11424 (if_then_else (match_test "operands[2] == const0_rtx")
11425 (const_string "8")
11426 (const_string "12")))])
11427
11428 (define_insn_and_split "*minus_eq_<mode>"
11429 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11430 (minus:P (match_operand:P 3 "gpc_reg_operand" "r")
11431 (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
11432 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
11433 (clobber (match_scratch:P 4 "=r"))
11434 (clobber (match_scratch:P 5 "=r"))
11435 (clobber (reg:P CA_REGNO))]
11436 ""
11437 "#"
11438 ""
11439 [(parallel [(set (match_dup 5)
11440 (plus:P (match_dup 4)
11441 (const_int -1)))
11442 (set (reg:P CA_REGNO)
11443 (ne:P (match_dup 4)
11444 (const_int 0)))])
11445 (parallel [(set (match_dup 0)
11446 (plus:P (plus:P (match_dup 3)
11447 (reg:P CA_REGNO))
11448 (const_int -1)))
11449 (clobber (reg:P CA_REGNO))])]
11450 {
11451 operands[4] = rs6000_emit_eqne (<MODE>mode,
11452 operands[1], operands[2], operands[4]);
11453
11454 if (GET_CODE (operands[5]) == SCRATCH)
11455 operands[5] = gen_reg_rtx (<MODE>mode);
11456 }
11457 [(set (attr "length")
11458 (if_then_else (match_test "operands[2] == const0_rtx")
11459 (const_string "8")
11460 (const_string "12")))])
11461
11462 (define_insn_and_split "*minus_ne_<mode>"
11463 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11464 (minus:P (match_operand:P 3 "gpc_reg_operand" "r")
11465 (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
11466 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
11467 (clobber (match_scratch:P 4 "=r"))
11468 (clobber (match_scratch:P 5 "=r"))
11469 (clobber (reg:P CA_REGNO))]
11470 ""
11471 "#"
11472 ""
11473 [(parallel [(set (match_dup 5)
11474 (neg:P (match_dup 4)))
11475 (set (reg:P CA_REGNO)
11476 (eq:P (match_dup 4)
11477 (const_int 0)))])
11478 (parallel [(set (match_dup 0)
11479 (plus:P (plus:P (match_dup 3)
11480 (reg:P CA_REGNO))
11481 (const_int -1)))
11482 (clobber (reg:P CA_REGNO))])]
11483 {
11484 operands[4] = rs6000_emit_eqne (<MODE>mode,
11485 operands[1], operands[2], operands[4]);
11486
11487 if (GET_CODE (operands[5]) == SCRATCH)
11488 operands[5] = gen_reg_rtx (<MODE>mode);
11489 }
11490 [(set (attr "length")
11491 (if_then_else (match_test "operands[2] == const0_rtx")
11492 (const_string "8")
11493 (const_string "12")))])
11494
11495 (define_insn_and_split "*eqsi3_ext<mode>"
11496 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
11497 (eq:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
11498 (match_operand:SI 2 "scc_eq_operand" "rKLI")))
11499 (clobber (match_scratch:SI 3 "=r"))
11500 (clobber (match_scratch:SI 4 "=r"))]
11501 ""
11502 "#"
11503 ""
11504 [(set (match_dup 4)
11505 (clz:SI (match_dup 3)))
11506 (set (match_dup 0)
11507 (zero_extend:EXTSI
11508 (lshiftrt:SI (match_dup 4)
11509 (const_int 5))))]
11510 {
11511 operands[3] = rs6000_emit_eqne (SImode,
11512 operands[1], operands[2], operands[3]);
11513
11514 if (GET_CODE (operands[4]) == SCRATCH)
11515 operands[4] = gen_reg_rtx (SImode);
11516 }
11517 [(set (attr "length")
11518 (if_then_else (match_test "operands[2] == const0_rtx")
11519 (const_string "8")
11520 (const_string "12")))])
11521
11522 (define_insn_and_split "*nesi3_ext<mode>"
11523 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
11524 (ne:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
11525 (match_operand:SI 2 "scc_eq_operand" "rKLI")))
11526 (clobber (match_scratch:SI 3 "=r"))
11527 (clobber (match_scratch:SI 4 "=r"))
11528 (clobber (match_scratch:EXTSI 5 "=r"))]
11529 ""
11530 "#"
11531 ""
11532 [(set (match_dup 4)
11533 (clz:SI (match_dup 3)))
11534 (set (match_dup 5)
11535 (zero_extend:EXTSI
11536 (lshiftrt:SI (match_dup 4)
11537 (const_int 5))))
11538 (set (match_dup 0)
11539 (xor:EXTSI (match_dup 5)
11540 (const_int 1)))]
11541 {
11542 operands[3] = rs6000_emit_eqne (SImode,
11543 operands[1], operands[2], operands[3]);
11544
11545 if (GET_CODE (operands[4]) == SCRATCH)
11546 operands[4] = gen_reg_rtx (SImode);
11547 if (GET_CODE (operands[5]) == SCRATCH)
11548 operands[5] = gen_reg_rtx (<MODE>mode);
11549 }
11550 [(set (attr "length")
11551 (if_then_else (match_test "operands[2] == const0_rtx")
11552 (const_string "12")
11553 (const_string "16")))])
11554 \f
11555 ;; Define both directions of branch and return. If we need a reload
11556 ;; register, we'd rather use CR0 since it is much easier to copy a
11557 ;; register CC value to there.
11558
11559 (define_insn ""
11560 [(set (pc)
11561 (if_then_else (match_operator 1 "branch_comparison_operator"
11562 [(match_operand 2
11563 "cc_reg_operand" "y")
11564 (const_int 0)])
11565 (label_ref (match_operand 0 "" ""))
11566 (pc)))]
11567 ""
11568 "*
11569 {
11570 return output_cbranch (operands[1], \"%l0\", 0, insn);
11571 }"
11572 [(set_attr "type" "branch")])
11573
11574 (define_insn ""
11575 [(set (pc)
11576 (if_then_else (match_operator 0 "branch_comparison_operator"
11577 [(match_operand 1
11578 "cc_reg_operand" "y")
11579 (const_int 0)])
11580 (any_return)
11581 (pc)))]
11582 "<return_pred>"
11583 "*
11584 {
11585 return output_cbranch (operands[0], NULL, 0, insn);
11586 }"
11587 [(set_attr "type" "jmpreg")
11588 (set_attr "length" "4")])
11589
11590 (define_insn ""
11591 [(set (pc)
11592 (if_then_else (match_operator 1 "branch_comparison_operator"
11593 [(match_operand 2
11594 "cc_reg_operand" "y")
11595 (const_int 0)])
11596 (pc)
11597 (label_ref (match_operand 0 "" ""))))]
11598 ""
11599 "*
11600 {
11601 return output_cbranch (operands[1], \"%l0\", 1, insn);
11602 }"
11603 [(set_attr "type" "branch")])
11604
11605 (define_insn ""
11606 [(set (pc)
11607 (if_then_else (match_operator 0 "branch_comparison_operator"
11608 [(match_operand 1
11609 "cc_reg_operand" "y")
11610 (const_int 0)])
11611 (pc)
11612 (any_return)))]
11613 "<return_pred>"
11614 "*
11615 {
11616 return output_cbranch (operands[0], NULL, 1, insn);
11617 }"
11618 [(set_attr "type" "jmpreg")
11619 (set_attr "length" "4")])
11620
11621 ;; Logic on condition register values.
11622
11623 ; This pattern matches things like
11624 ; (set (reg:CCEQ 68) (compare:CCEQ (ior:SI (gt:SI (reg:CCFP 68) (const_int 0))
11625 ; (eq:SI (reg:CCFP 68) (const_int 0)))
11626 ; (const_int 1)))
11627 ; which are generated by the branch logic.
11628 ; Prefer destructive operations where BT = BB (for crXX BT,BA,BB)
11629
11630 (define_insn "*cceq_ior_compare"
11631 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
11632 (compare:CCEQ (match_operator:SI 1 "boolean_operator"
11633 [(match_operator:SI 2
11634 "branch_positive_comparison_operator"
11635 [(match_operand 3
11636 "cc_reg_operand" "y,y")
11637 (const_int 0)])
11638 (match_operator:SI 4
11639 "branch_positive_comparison_operator"
11640 [(match_operand 5
11641 "cc_reg_operand" "0,y")
11642 (const_int 0)])])
11643 (const_int 1)))]
11644 ""
11645 "cr%q1 %E0,%j2,%j4"
11646 [(set_attr "type" "cr_logical,delayed_cr")])
11647
11648 ; Why is the constant -1 here, but 1 in the previous pattern?
11649 ; Because ~1 has all but the low bit set.
11650 (define_insn ""
11651 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
11652 (compare:CCEQ (match_operator:SI 1 "boolean_or_operator"
11653 [(not:SI (match_operator:SI 2
11654 "branch_positive_comparison_operator"
11655 [(match_operand 3
11656 "cc_reg_operand" "y,y")
11657 (const_int 0)]))
11658 (match_operator:SI 4
11659 "branch_positive_comparison_operator"
11660 [(match_operand 5
11661 "cc_reg_operand" "0,y")
11662 (const_int 0)])])
11663 (const_int -1)))]
11664 ""
11665 "cr%q1 %E0,%j2,%j4"
11666 [(set_attr "type" "cr_logical,delayed_cr")])
11667
11668 (define_insn "*cceq_rev_compare"
11669 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
11670 (compare:CCEQ (match_operator:SI 1
11671 "branch_positive_comparison_operator"
11672 [(match_operand 2
11673 "cc_reg_operand" "0,y")
11674 (const_int 0)])
11675 (const_int 0)))]
11676 ""
11677 "crnot %E0,%j1"
11678 [(set_attr "type" "cr_logical,delayed_cr")])
11679
11680 ;; If we are comparing the result of two comparisons, this can be done
11681 ;; using creqv or crxor.
11682
11683 (define_insn_and_split ""
11684 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y")
11685 (compare:CCEQ (match_operator 1 "branch_comparison_operator"
11686 [(match_operand 2 "cc_reg_operand" "y")
11687 (const_int 0)])
11688 (match_operator 3 "branch_comparison_operator"
11689 [(match_operand 4 "cc_reg_operand" "y")
11690 (const_int 0)])))]
11691 ""
11692 "#"
11693 ""
11694 [(set (match_dup 0) (compare:CCEQ (xor:SI (match_dup 1) (match_dup 3))
11695 (match_dup 5)))]
11696 "
11697 {
11698 int positive_1, positive_2;
11699
11700 positive_1 = branch_positive_comparison_operator (operands[1],
11701 GET_MODE (operands[1]));
11702 positive_2 = branch_positive_comparison_operator (operands[3],
11703 GET_MODE (operands[3]));
11704
11705 if (! positive_1)
11706 operands[1] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[2]),
11707 GET_CODE (operands[1])),
11708 SImode,
11709 operands[2], const0_rtx);
11710 else if (GET_MODE (operands[1]) != SImode)
11711 operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), SImode,
11712 operands[2], const0_rtx);
11713
11714 if (! positive_2)
11715 operands[3] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[4]),
11716 GET_CODE (operands[3])),
11717 SImode,
11718 operands[4], const0_rtx);
11719 else if (GET_MODE (operands[3]) != SImode)
11720 operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SImode,
11721 operands[4], const0_rtx);
11722
11723 if (positive_1 == positive_2)
11724 {
11725 operands[1] = gen_rtx_NOT (SImode, operands[1]);
11726 operands[5] = constm1_rtx;
11727 }
11728 else
11729 {
11730 operands[5] = const1_rtx;
11731 }
11732 }")
11733
11734 ;; Unconditional branch and return.
11735
11736 (define_insn "jump"
11737 [(set (pc)
11738 (label_ref (match_operand 0 "" "")))]
11739 ""
11740 "b %l0"
11741 [(set_attr "type" "branch")])
11742
11743 (define_insn "<return_str>return"
11744 [(any_return)]
11745 "<return_pred>"
11746 "blr"
11747 [(set_attr "type" "jmpreg")])
11748
11749 (define_expand "indirect_jump"
11750 [(set (pc) (match_operand 0 "register_operand" ""))])
11751
11752 (define_insn "*indirect_jump<mode>"
11753 [(set (pc) (match_operand:P 0 "register_operand" "c,*l"))]
11754 ""
11755 "@
11756 bctr
11757 blr"
11758 [(set_attr "type" "jmpreg")])
11759
11760 ;; Table jump for switch statements:
11761 (define_expand "tablejump"
11762 [(use (match_operand 0 "" ""))
11763 (use (label_ref (match_operand 1 "" "")))]
11764 ""
11765 "
11766 {
11767 if (TARGET_32BIT)
11768 emit_jump_insn (gen_tablejumpsi (operands[0], operands[1]));
11769 else
11770 emit_jump_insn (gen_tablejumpdi (operands[0], operands[1]));
11771 DONE;
11772 }")
11773
11774 (define_expand "tablejumpsi"
11775 [(set (match_dup 3)
11776 (plus:SI (match_operand:SI 0 "" "")
11777 (match_dup 2)))
11778 (parallel [(set (pc) (match_dup 3))
11779 (use (label_ref (match_operand 1 "" "")))])]
11780 "TARGET_32BIT"
11781 "
11782 { operands[0] = force_reg (SImode, operands[0]);
11783 operands[2] = force_reg (SImode, gen_rtx_LABEL_REF (SImode, operands[1]));
11784 operands[3] = gen_reg_rtx (SImode);
11785 }")
11786
11787 (define_expand "tablejumpdi"
11788 [(set (match_dup 4)
11789 (sign_extend:DI (match_operand:SI 0 "lwa_operand" "")))
11790 (set (match_dup 3)
11791 (plus:DI (match_dup 4)
11792 (match_dup 2)))
11793 (parallel [(set (pc) (match_dup 3))
11794 (use (label_ref (match_operand 1 "" "")))])]
11795 "TARGET_64BIT"
11796 "
11797 { operands[2] = force_reg (DImode, gen_rtx_LABEL_REF (DImode, operands[1]));
11798 operands[3] = gen_reg_rtx (DImode);
11799 operands[4] = gen_reg_rtx (DImode);
11800 }")
11801
11802 (define_insn "*tablejump<mode>_internal1"
11803 [(set (pc)
11804 (match_operand:P 0 "register_operand" "c,*l"))
11805 (use (label_ref (match_operand 1 "" "")))]
11806 ""
11807 "@
11808 bctr
11809 blr"
11810 [(set_attr "type" "jmpreg")])
11811
11812 (define_insn "nop"
11813 [(unspec [(const_int 0)] UNSPEC_NOP)]
11814 ""
11815 "nop")
11816
11817 (define_insn "group_ending_nop"
11818 [(unspec [(const_int 0)] UNSPEC_GRP_END_NOP)]
11819 ""
11820 "*
11821 {
11822 if (rs6000_cpu_attr == CPU_POWER6)
11823 return \"ori 1,1,0\";
11824 return \"ori 2,2,0\";
11825 }")
11826 \f
11827 ;; Define the subtract-one-and-jump insns, starting with the template
11828 ;; so loop.c knows what to generate.
11829
11830 (define_expand "doloop_end"
11831 [(use (match_operand 0 "" "")) ; loop pseudo
11832 (use (match_operand 1 "" ""))] ; label
11833 ""
11834 "
11835 {
11836 if (TARGET_64BIT)
11837 {
11838 if (GET_MODE (operands[0]) != DImode)
11839 FAIL;
11840 emit_jump_insn (gen_ctrdi (operands[0], operands[1]));
11841 }
11842 else
11843 {
11844 if (GET_MODE (operands[0]) != SImode)
11845 FAIL;
11846 emit_jump_insn (gen_ctrsi (operands[0], operands[1]));
11847 }
11848 DONE;
11849 }")
11850
11851 (define_expand "ctr<mode>"
11852 [(parallel [(set (pc)
11853 (if_then_else (ne (match_operand:P 0 "register_operand" "")
11854 (const_int 1))
11855 (label_ref (match_operand 1 "" ""))
11856 (pc)))
11857 (set (match_dup 0)
11858 (plus:P (match_dup 0)
11859 (const_int -1)))
11860 (clobber (match_scratch:CC 2 ""))
11861 (clobber (match_scratch:P 3 ""))])]
11862 ""
11863 "")
11864
11865 ;; We need to be able to do this for any operand, including MEM, or we
11866 ;; will cause reload to blow up since we don't allow output reloads on
11867 ;; JUMP_INSNs.
11868 ;; For the length attribute to be calculated correctly, the
11869 ;; label MUST be operand 0.
11870
11871 (define_insn "*ctr<mode>_internal1"
11872 [(set (pc)
11873 (if_then_else (ne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
11874 (const_int 1))
11875 (label_ref (match_operand 0 "" ""))
11876 (pc)))
11877 (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*c*l")
11878 (plus:P (match_dup 1)
11879 (const_int -1)))
11880 (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
11881 (clobber (match_scratch:P 4 "=X,X,&r,r"))]
11882 ""
11883 "*
11884 {
11885 if (which_alternative != 0)
11886 return \"#\";
11887 else if (get_attr_length (insn) == 4)
11888 return \"bdnz %l0\";
11889 else
11890 return \"bdz $+8\;b %l0\";
11891 }"
11892 [(set_attr "type" "branch")
11893 (set_attr "length" "*,16,20,20")])
11894
11895 (define_insn "*ctr<mode>_internal2"
11896 [(set (pc)
11897 (if_then_else (ne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
11898 (const_int 1))
11899 (pc)
11900 (label_ref (match_operand 0 "" ""))))
11901 (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*c*l")
11902 (plus:P (match_dup 1)
11903 (const_int -1)))
11904 (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
11905 (clobber (match_scratch:P 4 "=X,X,&r,r"))]
11906 ""
11907 "*
11908 {
11909 if (which_alternative != 0)
11910 return \"#\";
11911 else if (get_attr_length (insn) == 4)
11912 return \"bdz %l0\";
11913 else
11914 return \"bdnz $+8\;b %l0\";
11915 }"
11916 [(set_attr "type" "branch")
11917 (set_attr "length" "*,16,20,20")])
11918
11919 ;; Similar but use EQ
11920
11921 (define_insn "*ctr<mode>_internal5"
11922 [(set (pc)
11923 (if_then_else (eq (match_operand:P 1 "register_operand" "c,*b,*b,*b")
11924 (const_int 1))
11925 (label_ref (match_operand 0 "" ""))
11926 (pc)))
11927 (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*c*l")
11928 (plus:P (match_dup 1)
11929 (const_int -1)))
11930 (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
11931 (clobber (match_scratch:P 4 "=X,X,&r,r"))]
11932 ""
11933 "*
11934 {
11935 if (which_alternative != 0)
11936 return \"#\";
11937 else if (get_attr_length (insn) == 4)
11938 return \"bdz %l0\";
11939 else
11940 return \"bdnz $+8\;b %l0\";
11941 }"
11942 [(set_attr "type" "branch")
11943 (set_attr "length" "*,16,20,20")])
11944
11945 (define_insn "*ctr<mode>_internal6"
11946 [(set (pc)
11947 (if_then_else (eq (match_operand:P 1 "register_operand" "c,*b,*b,*b")
11948 (const_int 1))
11949 (pc)
11950 (label_ref (match_operand 0 "" ""))))
11951 (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*c*l")
11952 (plus:P (match_dup 1)
11953 (const_int -1)))
11954 (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
11955 (clobber (match_scratch:P 4 "=X,X,&r,r"))]
11956 ""
11957 "*
11958 {
11959 if (which_alternative != 0)
11960 return \"#\";
11961 else if (get_attr_length (insn) == 4)
11962 return \"bdnz %l0\";
11963 else
11964 return \"bdz $+8\;b %l0\";
11965 }"
11966 [(set_attr "type" "branch")
11967 (set_attr "length" "*,16,20,20")])
11968
11969 ;; Now the splitters if we could not allocate the CTR register
11970
11971 (define_split
11972 [(set (pc)
11973 (if_then_else (match_operator 2 "comparison_operator"
11974 [(match_operand:P 1 "gpc_reg_operand" "")
11975 (const_int 1)])
11976 (match_operand 5 "" "")
11977 (match_operand 6 "" "")))
11978 (set (match_operand:P 0 "gpc_reg_operand" "")
11979 (plus:P (match_dup 1) (const_int -1)))
11980 (clobber (match_scratch:CC 3 ""))
11981 (clobber (match_scratch:P 4 ""))]
11982 "reload_completed"
11983 [(set (match_dup 3)
11984 (compare:CC (match_dup 1)
11985 (const_int 1)))
11986 (set (match_dup 0)
11987 (plus:P (match_dup 1)
11988 (const_int -1)))
11989 (set (pc) (if_then_else (match_dup 7)
11990 (match_dup 5)
11991 (match_dup 6)))]
11992 "
11993 { operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[2]), VOIDmode,
11994 operands[3], const0_rtx); }")
11995
11996 (define_split
11997 [(set (pc)
11998 (if_then_else (match_operator 2 "comparison_operator"
11999 [(match_operand:P 1 "gpc_reg_operand" "")
12000 (const_int 1)])
12001 (match_operand 5 "" "")
12002 (match_operand 6 "" "")))
12003 (set (match_operand:P 0 "nonimmediate_operand" "")
12004 (plus:P (match_dup 1) (const_int -1)))
12005 (clobber (match_scratch:CC 3 ""))
12006 (clobber (match_scratch:P 4 ""))]
12007 "reload_completed && ! gpc_reg_operand (operands[0], SImode)"
12008 [(set (match_dup 3)
12009 (compare:CC (match_dup 1)
12010 (const_int 1)))
12011 (set (match_dup 4)
12012 (plus:P (match_dup 1)
12013 (const_int -1)))
12014 (set (match_dup 0)
12015 (match_dup 4))
12016 (set (pc) (if_then_else (match_dup 7)
12017 (match_dup 5)
12018 (match_dup 6)))]
12019 "
12020 { operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[2]), VOIDmode,
12021 operands[3], const0_rtx); }")
12022 \f
12023 (define_insn "trap"
12024 [(trap_if (const_int 1) (const_int 0))]
12025 ""
12026 "trap"
12027 [(set_attr "type" "trap")])
12028
12029 (define_expand "ctrap<mode>4"
12030 [(trap_if (match_operator 0 "ordered_comparison_operator"
12031 [(match_operand:GPR 1 "register_operand")
12032 (match_operand:GPR 2 "reg_or_short_operand")])
12033 (match_operand 3 "zero_constant" ""))]
12034 ""
12035 "")
12036
12037 (define_insn ""
12038 [(trap_if (match_operator 0 "ordered_comparison_operator"
12039 [(match_operand:GPR 1 "register_operand" "r")
12040 (match_operand:GPR 2 "reg_or_short_operand" "rI")])
12041 (const_int 0))]
12042 ""
12043 "t<wd>%V0%I2 %1,%2"
12044 [(set_attr "type" "trap")])
12045 \f
12046 ;; Insns related to generating the function prologue and epilogue.
12047
12048 (define_expand "prologue"
12049 [(use (const_int 0))]
12050 ""
12051 {
12052 rs6000_emit_prologue ();
12053 if (!TARGET_SCHED_PROLOG)
12054 emit_insn (gen_blockage ());
12055 DONE;
12056 })
12057
12058 (define_insn "*movesi_from_cr_one"
12059 [(match_parallel 0 "mfcr_operation"
12060 [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
12061 (unspec:SI [(match_operand:CC 2 "cc_reg_operand" "y")
12062 (match_operand 3 "immediate_operand" "n")]
12063 UNSPEC_MOVESI_FROM_CR))])]
12064 "TARGET_MFCRF"
12065 "*
12066 {
12067 int mask = 0;
12068 int i;
12069 for (i = 0; i < XVECLEN (operands[0], 0); i++)
12070 {
12071 mask = INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
12072 operands[4] = GEN_INT (mask);
12073 output_asm_insn (\"mfcr %1,%4\", operands);
12074 }
12075 return \"\";
12076 }"
12077 [(set_attr "type" "mfcrf")])
12078
12079 (define_insn "movesi_from_cr"
12080 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
12081 (unspec:SI [(reg:CC CR0_REGNO) (reg:CC CR1_REGNO)
12082 (reg:CC CR2_REGNO) (reg:CC CR3_REGNO)
12083 (reg:CC CR4_REGNO) (reg:CC CR5_REGNO)
12084 (reg:CC CR6_REGNO) (reg:CC CR7_REGNO)]
12085 UNSPEC_MOVESI_FROM_CR))]
12086 ""
12087 "mfcr %0"
12088 [(set_attr "type" "mfcr")])
12089
12090 (define_insn "*crsave"
12091 [(match_parallel 0 "crsave_operation"
12092 [(set (match_operand:SI 1 "memory_operand" "=m")
12093 (match_operand:SI 2 "gpc_reg_operand" "r"))])]
12094 ""
12095 "stw %2,%1"
12096 [(set_attr "type" "store")])
12097
12098 (define_insn "*stmw"
12099 [(match_parallel 0 "stmw_operation"
12100 [(set (match_operand:SI 1 "memory_operand" "=m")
12101 (match_operand:SI 2 "gpc_reg_operand" "r"))])]
12102 "TARGET_MULTIPLE"
12103 "stmw %2,%1"
12104 [(set_attr "type" "store")
12105 (set_attr "update" "yes")
12106 (set_attr "indexed" "yes")])
12107
12108 ; The following comment applies to:
12109 ; save_gpregs_*
12110 ; save_fpregs_*
12111 ; restore_gpregs*
12112 ; return_and_restore_gpregs*
12113 ; return_and_restore_fpregs*
12114 ; return_and_restore_fpregs_aix*
12115 ;
12116 ; The out-of-line save / restore functions expects one input argument.
12117 ; Since those are not standard call_insn's, we must avoid using
12118 ; MATCH_OPERAND for that argument. That way the register rename
12119 ; optimization will not try to rename this register.
12120 ; Each pattern is repeated for each possible register number used in
12121 ; various ABIs (r11, r1, and for some functions r12)
12122
12123 (define_insn "*save_gpregs_<mode>_r11"
12124 [(match_parallel 0 "any_parallel_operand"
12125 [(clobber (reg:P 65))
12126 (use (match_operand:P 1 "symbol_ref_operand" "s"))
12127 (use (reg:P 11))
12128 (set (match_operand:P 2 "memory_operand" "=m")
12129 (match_operand:P 3 "gpc_reg_operand" "r"))])]
12130 ""
12131 "bl %1"
12132 [(set_attr "type" "branch")
12133 (set_attr "length" "4")])
12134
12135 (define_insn "*save_gpregs_<mode>_r12"
12136 [(match_parallel 0 "any_parallel_operand"
12137 [(clobber (reg:P 65))
12138 (use (match_operand:P 1 "symbol_ref_operand" "s"))
12139 (use (reg:P 12))
12140 (set (match_operand:P 2 "memory_operand" "=m")
12141 (match_operand:P 3 "gpc_reg_operand" "r"))])]
12142 ""
12143 "bl %1"
12144 [(set_attr "type" "branch")
12145 (set_attr "length" "4")])
12146
12147 (define_insn "*save_gpregs_<mode>_r1"
12148 [(match_parallel 0 "any_parallel_operand"
12149 [(clobber (reg:P 65))
12150 (use (match_operand:P 1 "symbol_ref_operand" "s"))
12151 (use (reg:P 1))
12152 (set (match_operand:P 2 "memory_operand" "=m")
12153 (match_operand:P 3 "gpc_reg_operand" "r"))])]
12154 ""
12155 "bl %1"
12156 [(set_attr "type" "branch")
12157 (set_attr "length" "4")])
12158
12159 (define_insn "*save_fpregs_<mode>_r11"
12160 [(match_parallel 0 "any_parallel_operand"
12161 [(clobber (reg:P 65))
12162 (use (match_operand:P 1 "symbol_ref_operand" "s"))
12163 (use (reg:P 11))
12164 (set (match_operand:DF 2 "memory_operand" "=m")
12165 (match_operand:DF 3 "gpc_reg_operand" "d"))])]
12166 ""
12167 "bl %1"
12168 [(set_attr "type" "branch")
12169 (set_attr "length" "4")])
12170
12171 (define_insn "*save_fpregs_<mode>_r12"
12172 [(match_parallel 0 "any_parallel_operand"
12173 [(clobber (reg:P 65))
12174 (use (match_operand:P 1 "symbol_ref_operand" "s"))
12175 (use (reg:P 12))
12176 (set (match_operand:DF 2 "memory_operand" "=m")
12177 (match_operand:DF 3 "gpc_reg_operand" "d"))])]
12178 ""
12179 "bl %1"
12180 [(set_attr "type" "branch")
12181 (set_attr "length" "4")])
12182
12183 (define_insn "*save_fpregs_<mode>_r1"
12184 [(match_parallel 0 "any_parallel_operand"
12185 [(clobber (reg:P 65))
12186 (use (match_operand:P 1 "symbol_ref_operand" "s"))
12187 (use (reg:P 1))
12188 (set (match_operand:DF 2 "memory_operand" "=m")
12189 (match_operand:DF 3 "gpc_reg_operand" "d"))])]
12190 ""
12191 "bl %1"
12192 [(set_attr "type" "branch")
12193 (set_attr "length" "4")])
12194
12195 ; This is to explain that changes to the stack pointer should
12196 ; not be moved over loads from or stores to stack memory.
12197 (define_insn "stack_tie"
12198 [(match_parallel 0 "tie_operand"
12199 [(set (mem:BLK (reg 1)) (const_int 0))])]
12200 ""
12201 ""
12202 [(set_attr "length" "0")])
12203
12204 (define_expand "epilogue"
12205 [(use (const_int 0))]
12206 ""
12207 {
12208 if (!TARGET_SCHED_PROLOG)
12209 emit_insn (gen_blockage ());
12210 rs6000_emit_epilogue (FALSE);
12211 DONE;
12212 })
12213
12214 ; On some processors, doing the mtcrf one CC register at a time is
12215 ; faster (like on the 604e). On others, doing them all at once is
12216 ; faster; for instance, on the 601 and 750.
12217
12218 (define_expand "movsi_to_cr_one"
12219 [(set (match_operand:CC 0 "cc_reg_operand" "")
12220 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "")
12221 (match_dup 2)] UNSPEC_MOVESI_TO_CR))]
12222 ""
12223 "operands[2] = GEN_INT (1 << (75 - REGNO (operands[0])));")
12224
12225 (define_insn "*movsi_to_cr"
12226 [(match_parallel 0 "mtcrf_operation"
12227 [(set (match_operand:CC 1 "cc_reg_operand" "=y")
12228 (unspec:CC [(match_operand:SI 2 "gpc_reg_operand" "r")
12229 (match_operand 3 "immediate_operand" "n")]
12230 UNSPEC_MOVESI_TO_CR))])]
12231 ""
12232 "*
12233 {
12234 int mask = 0;
12235 int i;
12236 for (i = 0; i < XVECLEN (operands[0], 0); i++)
12237 mask |= INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
12238 operands[4] = GEN_INT (mask);
12239 return \"mtcrf %4,%2\";
12240 }"
12241 [(set_attr "type" "mtcr")])
12242
12243 (define_insn "*mtcrfsi"
12244 [(set (match_operand:CC 0 "cc_reg_operand" "=y")
12245 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
12246 (match_operand 2 "immediate_operand" "n")]
12247 UNSPEC_MOVESI_TO_CR))]
12248 "GET_CODE (operands[0]) == REG
12249 && CR_REGNO_P (REGNO (operands[0]))
12250 && GET_CODE (operands[2]) == CONST_INT
12251 && INTVAL (operands[2]) == 1 << (75 - REGNO (operands[0]))"
12252 "mtcrf %R0,%1"
12253 [(set_attr "type" "mtcr")])
12254
12255 ; The load-multiple instructions have similar properties.
12256 ; Note that "load_multiple" is a name known to the machine-independent
12257 ; code that actually corresponds to the PowerPC load-string.
12258
12259 (define_insn "*lmw"
12260 [(match_parallel 0 "lmw_operation"
12261 [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
12262 (match_operand:SI 2 "memory_operand" "m"))])]
12263 "TARGET_MULTIPLE"
12264 "lmw %1,%2"
12265 [(set_attr "type" "load")
12266 (set_attr "update" "yes")
12267 (set_attr "indexed" "yes")
12268 (set_attr "cell_micro" "always")])
12269
12270 (define_insn "*return_internal_<mode>"
12271 [(simple_return)
12272 (use (match_operand:P 0 "register_operand" "lc"))]
12273 ""
12274 "b%T0"
12275 [(set_attr "type" "jmpreg")])
12276
12277 ; FIXME: This would probably be somewhat simpler if the Cygnus sibcall
12278 ; stuff was in GCC. Oh, and "any_parallel_operand" is a bit flexible...
12279
12280 ; The following comment applies to:
12281 ; save_gpregs_*
12282 ; save_fpregs_*
12283 ; restore_gpregs*
12284 ; return_and_restore_gpregs*
12285 ; return_and_restore_fpregs*
12286 ; return_and_restore_fpregs_aix*
12287 ;
12288 ; The out-of-line save / restore functions expects one input argument.
12289 ; Since those are not standard call_insn's, we must avoid using
12290 ; MATCH_OPERAND for that argument. That way the register rename
12291 ; optimization will not try to rename this register.
12292 ; Each pattern is repeated for each possible register number used in
12293 ; various ABIs (r11, r1, and for some functions r12)
12294
12295 (define_insn "*restore_gpregs_<mode>_r11"
12296 [(match_parallel 0 "any_parallel_operand"
12297 [(clobber (match_operand:P 1 "register_operand" "=l"))
12298 (use (match_operand:P 2 "symbol_ref_operand" "s"))
12299 (use (reg:P 11))
12300 (set (match_operand:P 3 "gpc_reg_operand" "=r")
12301 (match_operand:P 4 "memory_operand" "m"))])]
12302 ""
12303 "bl %2"
12304 [(set_attr "type" "branch")
12305 (set_attr "length" "4")])
12306
12307 (define_insn "*restore_gpregs_<mode>_r12"
12308 [(match_parallel 0 "any_parallel_operand"
12309 [(clobber (match_operand:P 1 "register_operand" "=l"))
12310 (use (match_operand:P 2 "symbol_ref_operand" "s"))
12311 (use (reg:P 12))
12312 (set (match_operand:P 3 "gpc_reg_operand" "=r")
12313 (match_operand:P 4 "memory_operand" "m"))])]
12314 ""
12315 "bl %2"
12316 [(set_attr "type" "branch")
12317 (set_attr "length" "4")])
12318
12319 (define_insn "*restore_gpregs_<mode>_r1"
12320 [(match_parallel 0 "any_parallel_operand"
12321 [(clobber (match_operand:P 1 "register_operand" "=l"))
12322 (use (match_operand:P 2 "symbol_ref_operand" "s"))
12323 (use (reg:P 1))
12324 (set (match_operand:P 3 "gpc_reg_operand" "=r")
12325 (match_operand:P 4 "memory_operand" "m"))])]
12326 ""
12327 "bl %2"
12328 [(set_attr "type" "branch")
12329 (set_attr "length" "4")])
12330
12331 (define_insn "*return_and_restore_gpregs_<mode>_r11"
12332 [(match_parallel 0 "any_parallel_operand"
12333 [(return)
12334 (clobber (match_operand:P 1 "register_operand" "=l"))
12335 (use (match_operand:P 2 "symbol_ref_operand" "s"))
12336 (use (reg:P 11))
12337 (set (match_operand:P 3 "gpc_reg_operand" "=r")
12338 (match_operand:P 4 "memory_operand" "m"))])]
12339 ""
12340 "b %2"
12341 [(set_attr "type" "branch")
12342 (set_attr "length" "4")])
12343
12344 (define_insn "*return_and_restore_gpregs_<mode>_r12"
12345 [(match_parallel 0 "any_parallel_operand"
12346 [(return)
12347 (clobber (match_operand:P 1 "register_operand" "=l"))
12348 (use (match_operand:P 2 "symbol_ref_operand" "s"))
12349 (use (reg:P 12))
12350 (set (match_operand:P 3 "gpc_reg_operand" "=r")
12351 (match_operand:P 4 "memory_operand" "m"))])]
12352 ""
12353 "b %2"
12354 [(set_attr "type" "branch")
12355 (set_attr "length" "4")])
12356
12357 (define_insn "*return_and_restore_gpregs_<mode>_r1"
12358 [(match_parallel 0 "any_parallel_operand"
12359 [(return)
12360 (clobber (match_operand:P 1 "register_operand" "=l"))
12361 (use (match_operand:P 2 "symbol_ref_operand" "s"))
12362 (use (reg:P 1))
12363 (set (match_operand:P 3 "gpc_reg_operand" "=r")
12364 (match_operand:P 4 "memory_operand" "m"))])]
12365 ""
12366 "b %2"
12367 [(set_attr "type" "branch")
12368 (set_attr "length" "4")])
12369
12370 (define_insn "*return_and_restore_fpregs_<mode>_r11"
12371 [(match_parallel 0 "any_parallel_operand"
12372 [(return)
12373 (clobber (match_operand:P 1 "register_operand" "=l"))
12374 (use (match_operand:P 2 "symbol_ref_operand" "s"))
12375 (use (reg:P 11))
12376 (set (match_operand:DF 3 "gpc_reg_operand" "=d")
12377 (match_operand:DF 4 "memory_operand" "m"))])]
12378 ""
12379 "b %2"
12380 [(set_attr "type" "branch")
12381 (set_attr "length" "4")])
12382
12383 (define_insn "*return_and_restore_fpregs_<mode>_r12"
12384 [(match_parallel 0 "any_parallel_operand"
12385 [(return)
12386 (clobber (match_operand:P 1 "register_operand" "=l"))
12387 (use (match_operand:P 2 "symbol_ref_operand" "s"))
12388 (use (reg:P 12))
12389 (set (match_operand:DF 3 "gpc_reg_operand" "=d")
12390 (match_operand:DF 4 "memory_operand" "m"))])]
12391 ""
12392 "b %2"
12393 [(set_attr "type" "branch")
12394 (set_attr "length" "4")])
12395
12396 (define_insn "*return_and_restore_fpregs_<mode>_r1"
12397 [(match_parallel 0 "any_parallel_operand"
12398 [(return)
12399 (clobber (match_operand:P 1 "register_operand" "=l"))
12400 (use (match_operand:P 2 "symbol_ref_operand" "s"))
12401 (use (reg:P 1))
12402 (set (match_operand:DF 3 "gpc_reg_operand" "=d")
12403 (match_operand:DF 4 "memory_operand" "m"))])]
12404 ""
12405 "b %2"
12406 [(set_attr "type" "branch")
12407 (set_attr "length" "4")])
12408
12409 (define_insn "*return_and_restore_fpregs_aix_<mode>_r11"
12410 [(match_parallel 0 "any_parallel_operand"
12411 [(return)
12412 (use (match_operand:P 1 "register_operand" "l"))
12413 (use (match_operand:P 2 "symbol_ref_operand" "s"))
12414 (use (reg:P 11))
12415 (set (match_operand:DF 3 "gpc_reg_operand" "=d")
12416 (match_operand:DF 4 "memory_operand" "m"))])]
12417 ""
12418 "b %2"
12419 [(set_attr "type" "branch")
12420 (set_attr "length" "4")])
12421
12422 (define_insn "*return_and_restore_fpregs_aix_<mode>_r1"
12423 [(match_parallel 0 "any_parallel_operand"
12424 [(return)
12425 (use (match_operand:P 1 "register_operand" "l"))
12426 (use (match_operand:P 2 "symbol_ref_operand" "s"))
12427 (use (reg:P 1))
12428 (set (match_operand:DF 3 "gpc_reg_operand" "=d")
12429 (match_operand:DF 4 "memory_operand" "m"))])]
12430 ""
12431 "b %2"
12432 [(set_attr "type" "branch")
12433 (set_attr "length" "4")])
12434
12435 ; This is used in compiling the unwind routines.
12436 (define_expand "eh_return"
12437 [(use (match_operand 0 "general_operand" ""))]
12438 ""
12439 "
12440 {
12441 if (TARGET_32BIT)
12442 emit_insn (gen_eh_set_lr_si (operands[0]));
12443 else
12444 emit_insn (gen_eh_set_lr_di (operands[0]));
12445 DONE;
12446 }")
12447
12448 ; We can't expand this before we know where the link register is stored.
12449 (define_insn "eh_set_lr_<mode>"
12450 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
12451 UNSPECV_EH_RR)
12452 (clobber (match_scratch:P 1 "=&b"))]
12453 ""
12454 "#")
12455
12456 (define_split
12457 [(unspec_volatile [(match_operand 0 "register_operand" "")] UNSPECV_EH_RR)
12458 (clobber (match_scratch 1 ""))]
12459 "reload_completed"
12460 [(const_int 0)]
12461 "
12462 {
12463 rs6000_emit_eh_reg_restore (operands[0], operands[1]);
12464 DONE;
12465 }")
12466
12467 (define_insn "prefetch"
12468 [(prefetch (match_operand 0 "indexed_or_indirect_address" "a")
12469 (match_operand:SI 1 "const_int_operand" "n")
12470 (match_operand:SI 2 "const_int_operand" "n"))]
12471 ""
12472 "*
12473 {
12474 if (GET_CODE (operands[0]) == REG)
12475 return INTVAL (operands[1]) ? \"dcbtst 0,%0\" : \"dcbt 0,%0\";
12476 return INTVAL (operands[1]) ? \"dcbtst %a0\" : \"dcbt %a0\";
12477 }"
12478 [(set_attr "type" "load")])
12479 \f
12480 ;; Handle -fsplit-stack.
12481
12482 (define_expand "split_stack_prologue"
12483 [(const_int 0)]
12484 ""
12485 {
12486 rs6000_expand_split_stack_prologue ();
12487 DONE;
12488 })
12489
12490 (define_expand "load_split_stack_limit"
12491 [(set (match_operand 0)
12492 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))]
12493 ""
12494 {
12495 emit_insn (gen_rtx_SET (operands[0],
12496 gen_rtx_UNSPEC (Pmode,
12497 gen_rtvec (1, const0_rtx),
12498 UNSPEC_STACK_CHECK)));
12499 DONE;
12500 })
12501
12502 (define_insn "load_split_stack_limit_di"
12503 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
12504 (unspec:DI [(const_int 0)] UNSPEC_STACK_CHECK))]
12505 "TARGET_64BIT"
12506 "ld %0,-0x7040(13)"
12507 [(set_attr "type" "load")
12508 (set_attr "update" "no")
12509 (set_attr "indexed" "no")])
12510
12511 (define_insn "load_split_stack_limit_si"
12512 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
12513 (unspec:SI [(const_int 0)] UNSPEC_STACK_CHECK))]
12514 "!TARGET_64BIT"
12515 "lwz %0,-0x7020(2)"
12516 [(set_attr "type" "load")
12517 (set_attr "update" "no")
12518 (set_attr "indexed" "no")])
12519
12520 ;; A return instruction which the middle-end doesn't see.
12521 (define_insn "split_stack_return"
12522 [(unspec_volatile [(const_int 0)] UNSPECV_SPLIT_STACK_RETURN)]
12523 ""
12524 "blr"
12525 [(set_attr "type" "jmpreg")])
12526
12527 ;; If there are operand 0 bytes available on the stack, jump to
12528 ;; operand 1.
12529 (define_expand "split_stack_space_check"
12530 [(set (match_dup 2)
12531 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
12532 (set (match_dup 3)
12533 (minus (reg STACK_POINTER_REGNUM)
12534 (match_operand 0)))
12535 (set (match_dup 4) (compare:CCUNS (match_dup 3) (match_dup 2)))
12536 (set (pc) (if_then_else
12537 (geu (match_dup 4) (const_int 0))
12538 (label_ref (match_operand 1))
12539 (pc)))]
12540 ""
12541 {
12542 rs6000_split_stack_space_check (operands[0], operands[1]);
12543 DONE;
12544 })
12545 \f
12546 (define_insn "bpermd_<mode>"
12547 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12548 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "r")
12549 (match_operand:P 2 "gpc_reg_operand" "r")] UNSPEC_BPERM))]
12550 "TARGET_POPCNTD"
12551 "bpermd %0,%1,%2"
12552 [(set_attr "type" "popcnt")])
12553
12554 \f
12555 ;; Builtin fma support. Handle
12556 ;; Note that the conditions for expansion are in the FMA_F iterator.
12557
12558 (define_expand "fma<mode>4"
12559 [(set (match_operand:FMA_F 0 "register_operand" "")
12560 (fma:FMA_F
12561 (match_operand:FMA_F 1 "register_operand" "")
12562 (match_operand:FMA_F 2 "register_operand" "")
12563 (match_operand:FMA_F 3 "register_operand" "")))]
12564 ""
12565 "")
12566
12567 (define_insn "*fma<mode>4_fpr"
12568 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
12569 (fma:SFDF
12570 (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>,<Fv2>")
12571 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
12572 (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>")))]
12573 "TARGET_<MODE>_FPR"
12574 "@
12575 fmadd<Ftrad> %0,%1,%2,%3
12576 xsmadda<Fvsx> %x0,%x1,%x2
12577 xsmaddm<Fvsx> %x0,%x1,%x3"
12578 [(set_attr "type" "fp")
12579 (set_attr "fp_type" "fp_maddsub_<Fs>")])
12580
12581 ; Altivec only has fma and nfms.
12582 (define_expand "fms<mode>4"
12583 [(set (match_operand:FMA_F 0 "register_operand" "")
12584 (fma:FMA_F
12585 (match_operand:FMA_F 1 "register_operand" "")
12586 (match_operand:FMA_F 2 "register_operand" "")
12587 (neg:FMA_F (match_operand:FMA_F 3 "register_operand" ""))))]
12588 "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
12589 "")
12590
12591 (define_insn "*fms<mode>4_fpr"
12592 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
12593 (fma:SFDF
12594 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
12595 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
12596 (neg:SFDF (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>"))))]
12597 "TARGET_<MODE>_FPR"
12598 "@
12599 fmsub<Ftrad> %0,%1,%2,%3
12600 xsmsuba<Fvsx> %x0,%x1,%x2
12601 xsmsubm<Fvsx> %x0,%x1,%x3"
12602 [(set_attr "type" "fp")
12603 (set_attr "fp_type" "fp_maddsub_<Fs>")])
12604
12605 ;; If signed zeros are ignored, -(a * b - c) = -a * b + c.
12606 (define_expand "fnma<mode>4"
12607 [(set (match_operand:FMA_F 0 "register_operand" "")
12608 (neg:FMA_F
12609 (fma:FMA_F
12610 (match_operand:FMA_F 1 "register_operand" "")
12611 (match_operand:FMA_F 2 "register_operand" "")
12612 (neg:FMA_F (match_operand:FMA_F 3 "register_operand" "")))))]
12613 "!HONOR_SIGNED_ZEROS (<MODE>mode)"
12614 "")
12615
12616 ;; If signed zeros are ignored, -(a * b + c) = -a * b - c.
12617 (define_expand "fnms<mode>4"
12618 [(set (match_operand:FMA_F 0 "register_operand" "")
12619 (neg:FMA_F
12620 (fma:FMA_F
12621 (match_operand:FMA_F 1 "register_operand" "")
12622 (match_operand:FMA_F 2 "register_operand" "")
12623 (match_operand:FMA_F 3 "register_operand" ""))))]
12624 "!HONOR_SIGNED_ZEROS (<MODE>mode) && !VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
12625 "")
12626
12627 ; Not an official optab name, but used from builtins.
12628 (define_expand "nfma<mode>4"
12629 [(set (match_operand:FMA_F 0 "register_operand" "")
12630 (neg:FMA_F
12631 (fma:FMA_F
12632 (match_operand:FMA_F 1 "register_operand" "")
12633 (match_operand:FMA_F 2 "register_operand" "")
12634 (match_operand:FMA_F 3 "register_operand" ""))))]
12635 "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
12636 "")
12637
12638 (define_insn "*nfma<mode>4_fpr"
12639 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
12640 (neg:SFDF
12641 (fma:SFDF
12642 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
12643 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
12644 (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>"))))]
12645 "TARGET_<MODE>_FPR"
12646 "@
12647 fnmadd<Ftrad> %0,%1,%2,%3
12648 xsnmadda<Fvsx> %x0,%x1,%x2
12649 xsnmaddm<Fvsx> %x0,%x1,%x3"
12650 [(set_attr "type" "fp")
12651 (set_attr "fp_type" "fp_maddsub_<Fs>")])
12652
12653 ; Not an official optab name, but used from builtins.
12654 (define_expand "nfms<mode>4"
12655 [(set (match_operand:FMA_F 0 "register_operand" "")
12656 (neg:FMA_F
12657 (fma:FMA_F
12658 (match_operand:FMA_F 1 "register_operand" "")
12659 (match_operand:FMA_F 2 "register_operand" "")
12660 (neg:FMA_F (match_operand:FMA_F 3 "register_operand" "")))))]
12661 ""
12662 "")
12663
12664 (define_insn "*nfmssf4_fpr"
12665 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
12666 (neg:SFDF
12667 (fma:SFDF
12668 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
12669 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
12670 (neg:SFDF
12671 (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>")))))]
12672 "TARGET_<MODE>_FPR"
12673 "@
12674 fnmsub<Ftrad> %0,%1,%2,%3
12675 xsnmsuba<Fvsx> %x0,%x1,%x2
12676 xsnmsubm<Fvsx> %x0,%x1,%x3"
12677 [(set_attr "type" "fp")
12678 (set_attr "fp_type" "fp_maddsub_<Fs>")])
12679
12680 \f
12681 (define_expand "rs6000_get_timebase"
12682 [(use (match_operand:DI 0 "gpc_reg_operand" ""))]
12683 ""
12684 {
12685 if (TARGET_POWERPC64)
12686 emit_insn (gen_rs6000_mftb_di (operands[0]));
12687 else
12688 emit_insn (gen_rs6000_get_timebase_ppc32 (operands[0]));
12689 DONE;
12690 })
12691
12692 (define_insn "rs6000_get_timebase_ppc32"
12693 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
12694 (unspec_volatile:DI [(const_int 0)] UNSPECV_MFTB))
12695 (clobber (match_scratch:SI 1 "=r"))
12696 (clobber (match_scratch:CC 2 "=y"))]
12697 "!TARGET_POWERPC64"
12698 {
12699 if (WORDS_BIG_ENDIAN)
12700 if (TARGET_MFCRF)
12701 {
12702 return "mfspr %0,269\;"
12703 "mfspr %L0,268\;"
12704 "mfspr %1,269\;"
12705 "cmpw %2,%0,%1\;"
12706 "bne- %2,$-16";
12707 }
12708 else
12709 {
12710 return "mftbu %0\;"
12711 "mftb %L0\;"
12712 "mftbu %1\;"
12713 "cmpw %2,%0,%1\;"
12714 "bne- %2,$-16";
12715 }
12716 else
12717 if (TARGET_MFCRF)
12718 {
12719 return "mfspr %L0,269\;"
12720 "mfspr %0,268\;"
12721 "mfspr %1,269\;"
12722 "cmpw %2,%L0,%1\;"
12723 "bne- %2,$-16";
12724 }
12725 else
12726 {
12727 return "mftbu %L0\;"
12728 "mftb %0\;"
12729 "mftbu %1\;"
12730 "cmpw %2,%L0,%1\;"
12731 "bne- %2,$-16";
12732 }
12733 }
12734 [(set_attr "length" "20")])
12735
12736 (define_insn "rs6000_mftb_<mode>"
12737 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
12738 (unspec_volatile:GPR [(const_int 0)] UNSPECV_MFTB))]
12739 ""
12740 {
12741 if (TARGET_MFCRF)
12742 return "mfspr %0,268";
12743 else
12744 return "mftb %0";
12745 })
12746
12747 \f
12748 (define_insn "rs6000_mffs"
12749 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
12750 (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFS))]
12751 "TARGET_HARD_FLOAT && TARGET_FPRS"
12752 "mffs %0")
12753
12754 (define_insn "rs6000_mtfsf"
12755 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "i")
12756 (match_operand:DF 1 "gpc_reg_operand" "d")]
12757 UNSPECV_MTFSF)]
12758 "TARGET_HARD_FLOAT && TARGET_FPRS"
12759 "mtfsf %0,%1")
12760
12761 \f
12762 ;; Power8 fusion support for fusing an addis instruction with a D-form load of
12763 ;; a GPR. The addis instruction must be adjacent to the load, and use the same
12764 ;; register that is being loaded. The fused ops must be physically adjacent.
12765
12766 ;; There are two parts to addis fusion. The support for fused TOCs occur
12767 ;; before register allocation, and is meant to reduce the lifetime for the
12768 ;; tempoary register that holds the ADDIS result. On Power8 GPR loads, we try
12769 ;; to use the register that is being load. The peephole2 then gathers any
12770 ;; other fused possibilities that it can find after register allocation. If
12771 ;; power9 fusion is selected, we also fuse floating point loads/stores.
12772
12773 ;; Fused TOC support: Replace simple GPR loads with a fused form. This is done
12774 ;; before register allocation, so that we can avoid allocating a temporary base
12775 ;; register that won't be used, and that we try to load into base registers,
12776 ;; and not register 0. If we can't get a fused GPR load, generate a P9 fusion
12777 ;; (addis followed by load) even on power8.
12778
12779 (define_split
12780 [(set (match_operand:INT1 0 "toc_fusion_or_p9_reg_operand" "")
12781 (match_operand:INT1 1 "toc_fusion_mem_raw" ""))]
12782 "TARGET_TOC_FUSION_INT && can_create_pseudo_p ()"
12783 [(parallel [(set (match_dup 0) (match_dup 2))
12784 (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS)
12785 (use (match_dup 3))
12786 (clobber (scratch:DI))])]
12787 {
12788 operands[2] = fusion_wrap_memory_address (operands[1]);
12789 operands[3] = gen_rtx_REG (Pmode, TOC_REGISTER);
12790 })
12791
12792 (define_insn "*toc_fusionload_<mode>"
12793 [(set (match_operand:QHSI 0 "int_reg_operand" "=&b,??r")
12794 (match_operand:QHSI 1 "toc_fusion_mem_wrapped" "wG,wG"))
12795 (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS)
12796 (use (match_operand:DI 2 "base_reg_operand" "r,r"))
12797 (clobber (match_scratch:DI 3 "=X,&b"))]
12798 "TARGET_TOC_FUSION_INT"
12799 {
12800 if (base_reg_operand (operands[0], <MODE>mode))
12801 return emit_fusion_gpr_load (operands[0], operands[1]);
12802
12803 return emit_fusion_p9_load (operands[0], operands[1], operands[3]);
12804 }
12805 [(set_attr "type" "load")
12806 (set_attr "length" "8")])
12807
12808 (define_insn "*toc_fusionload_di"
12809 [(set (match_operand:DI 0 "int_reg_operand" "=&b,??r,?d")
12810 (match_operand:DI 1 "toc_fusion_mem_wrapped" "wG,wG,wG"))
12811 (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS)
12812 (use (match_operand:DI 2 "base_reg_operand" "r,r,r"))
12813 (clobber (match_scratch:DI 3 "=X,&b,&b"))]
12814 "TARGET_TOC_FUSION_INT && TARGET_POWERPC64
12815 && (MEM_P (operands[1]) || int_reg_operand (operands[0], DImode))"
12816 {
12817 if (base_reg_operand (operands[0], DImode))
12818 return emit_fusion_gpr_load (operands[0], operands[1]);
12819
12820 return emit_fusion_p9_load (operands[0], operands[1], operands[3]);
12821 }
12822 [(set_attr "type" "load")
12823 (set_attr "length" "8")])
12824
12825 \f
12826 ;; Find cases where the addis that feeds into a load instruction is either used
12827 ;; once or is the same as the target register, and replace it with the fusion
12828 ;; insn
12829
12830 (define_peephole2
12831 [(set (match_operand:P 0 "base_reg_operand" "")
12832 (match_operand:P 1 "fusion_gpr_addis" ""))
12833 (set (match_operand:INT1 2 "base_reg_operand" "")
12834 (match_operand:INT1 3 "fusion_gpr_mem_load" ""))]
12835 "TARGET_P8_FUSION
12836 && fusion_gpr_load_p (operands[0], operands[1], operands[2],
12837 operands[3])"
12838 [(const_int 0)]
12839 {
12840 expand_fusion_gpr_load (operands);
12841 DONE;
12842 })
12843
12844 ;; Fusion insn, created by the define_peephole2 above (and eventually by
12845 ;; reload)
12846
12847 (define_insn "fusion_gpr_load_<mode>"
12848 [(set (match_operand:INT1 0 "base_reg_operand" "=&b")
12849 (unspec:INT1 [(match_operand:INT1 1 "fusion_addis_mem_combo_load" "")]
12850 UNSPEC_FUSION_GPR))]
12851 "TARGET_P8_FUSION"
12852 {
12853 return emit_fusion_gpr_load (operands[0], operands[1]);
12854 }
12855 [(set_attr "type" "load")
12856 (set_attr "length" "8")])
12857
12858 \f
12859 ;; ISA 3.0 (power9) fusion support
12860 ;; Merge addis with floating load/store to FPRs (or GPRs).
12861 (define_peephole2
12862 [(set (match_operand:P 0 "base_reg_operand" "")
12863 (match_operand:P 1 "fusion_gpr_addis" ""))
12864 (set (match_operand:SFDF 2 "toc_fusion_or_p9_reg_operand" "")
12865 (match_operand:SFDF 3 "fusion_offsettable_mem_operand" ""))]
12866 "TARGET_P9_FUSION && peep2_reg_dead_p (2, operands[0])
12867 && fusion_p9_p (operands[0], operands[1], operands[2], operands[3])"
12868 [(const_int 0)]
12869 {
12870 expand_fusion_p9_load (operands);
12871 DONE;
12872 })
12873
12874 (define_peephole2
12875 [(set (match_operand:P 0 "base_reg_operand" "")
12876 (match_operand:P 1 "fusion_gpr_addis" ""))
12877 (set (match_operand:SFDF 2 "offsettable_mem_operand" "")
12878 (match_operand:SFDF 3 "toc_fusion_or_p9_reg_operand" ""))]
12879 "TARGET_P9_FUSION && peep2_reg_dead_p (2, operands[0])
12880 && fusion_p9_p (operands[0], operands[1], operands[2], operands[3])"
12881 [(const_int 0)]
12882 {
12883 expand_fusion_p9_store (operands);
12884 DONE;
12885 })
12886
12887 (define_peephole2
12888 [(set (match_operand:SDI 0 "int_reg_operand" "")
12889 (match_operand:SDI 1 "upper16_cint_operand" ""))
12890 (set (match_dup 0)
12891 (ior:SDI (match_dup 0)
12892 (match_operand:SDI 2 "u_short_cint_operand" "")))]
12893 "TARGET_P9_FUSION"
12894 [(set (match_dup 0)
12895 (unspec:SDI [(match_dup 1)
12896 (match_dup 2)] UNSPEC_FUSION_P9))])
12897
12898 (define_peephole2
12899 [(set (match_operand:SDI 0 "int_reg_operand" "")
12900 (match_operand:SDI 1 "upper16_cint_operand" ""))
12901 (set (match_operand:SDI 2 "int_reg_operand" "")
12902 (ior:SDI (match_dup 0)
12903 (match_operand:SDI 3 "u_short_cint_operand" "")))]
12904 "TARGET_P9_FUSION
12905 && !rtx_equal_p (operands[0], operands[2])
12906 && peep2_reg_dead_p (2, operands[0])"
12907 [(set (match_dup 2)
12908 (unspec:SDI [(match_dup 1)
12909 (match_dup 3)] UNSPEC_FUSION_P9))])
12910
12911 ;; Fusion insns, created by the define_peephole2 above (and eventually by
12912 ;; reload). Because we want to eventually have secondary_reload generate
12913 ;; these, they have to have a single alternative that gives the register
12914 ;; classes. This means we need to have separate gpr/fpr/altivec versions.
12915 (define_insn "fusion_gpr_<P:mode>_<GPR_FUSION:mode>_load"
12916 [(set (match_operand:GPR_FUSION 0 "int_reg_operand" "=r")
12917 (unspec:GPR_FUSION
12918 [(match_operand:GPR_FUSION 1 "fusion_addis_mem_combo_load" "wF")]
12919 UNSPEC_FUSION_P9))
12920 (clobber (match_operand:P 2 "base_reg_operand" "=&b"))]
12921 "TARGET_P9_FUSION"
12922 {
12923 /* This insn is a secondary reload insn, which cannot have alternatives.
12924 If we are not loading up register 0, use the power8 fusion instead. */
12925 if (base_reg_operand (operands[0], <GPR_FUSION:MODE>mode))
12926 return emit_fusion_gpr_load (operands[0], operands[1]);
12927
12928 return emit_fusion_p9_load (operands[0], operands[1], operands[2]);
12929 }
12930 [(set_attr "type" "load")
12931 (set_attr "length" "8")])
12932
12933 (define_insn "fusion_gpr_<P:mode>_<GPR_FUSION:mode>_store"
12934 [(set (match_operand:GPR_FUSION 0 "fusion_addis_mem_combo_store" "=wF")
12935 (unspec:GPR_FUSION
12936 [(match_operand:GPR_FUSION 1 "int_reg_operand" "r")]
12937 UNSPEC_FUSION_P9))
12938 (clobber (match_operand:P 2 "base_reg_operand" "=&b"))]
12939 "TARGET_P9_FUSION"
12940 {
12941 return emit_fusion_p9_store (operands[0], operands[1], operands[2]);
12942 }
12943 [(set_attr "type" "store")
12944 (set_attr "length" "8")])
12945
12946 (define_insn "fusion_fpr_<P:mode>_<FPR_FUSION:mode>_load"
12947 [(set (match_operand:FPR_FUSION 0 "fpr_reg_operand" "=d")
12948 (unspec:FPR_FUSION
12949 [(match_operand:FPR_FUSION 1 "fusion_addis_mem_combo_load" "wF")]
12950 UNSPEC_FUSION_P9))
12951 (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
12952 "TARGET_P9_FUSION"
12953 {
12954 return emit_fusion_p9_load (operands[0], operands[1], operands[2]);
12955 }
12956 [(set_attr "type" "fpload")
12957 (set_attr "length" "8")])
12958
12959 (define_insn "fusion_fpr_<P:mode>_<FPR_FUSION:mode>_store"
12960 [(set (match_operand:FPR_FUSION 0 "fusion_addis_mem_combo_store" "=wF")
12961 (unspec:FPR_FUSION
12962 [(match_operand:FPR_FUSION 1 "fpr_reg_operand" "d")]
12963 UNSPEC_FUSION_P9))
12964 (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
12965 "TARGET_P9_FUSION"
12966 {
12967 return emit_fusion_p9_store (operands[0], operands[1], operands[2]);
12968 }
12969 [(set_attr "type" "fpstore")
12970 (set_attr "length" "8")])
12971
12972 (define_insn "*fusion_p9_<mode>_constant"
12973 [(set (match_operand:SDI 0 "int_reg_operand" "=r")
12974 (unspec:SDI [(match_operand:SDI 1 "upper16_cint_operand" "L")
12975 (match_operand:SDI 2 "u_short_cint_operand" "K")]
12976 UNSPEC_FUSION_P9))]
12977 "TARGET_P9_FUSION"
12978 {
12979 emit_fusion_addis (operands[0], operands[1], "constant", "<MODE>");
12980 return "ori %0,%0,%2";
12981 }
12982 [(set_attr "type" "two")
12983 (set_attr "length" "8")])
12984
12985 \f
12986 ;; Miscellaneous ISA 2.06 (power7) instructions
12987 (define_insn "addg6s"
12988 [(set (match_operand:SI 0 "register_operand" "=r")
12989 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
12990 (match_operand:SI 2 "register_operand" "r")]
12991 UNSPEC_ADDG6S))]
12992 "TARGET_POPCNTD"
12993 "addg6s %0,%1,%2"
12994 [(set_attr "type" "integer")
12995 (set_attr "length" "4")])
12996
12997 (define_insn "cdtbcd"
12998 [(set (match_operand:SI 0 "register_operand" "=r")
12999 (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
13000 UNSPEC_CDTBCD))]
13001 "TARGET_POPCNTD"
13002 "cdtbcd %0,%1"
13003 [(set_attr "type" "integer")
13004 (set_attr "length" "4")])
13005
13006 (define_insn "cbcdtd"
13007 [(set (match_operand:SI 0 "register_operand" "=r")
13008 (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
13009 UNSPEC_CBCDTD))]
13010 "TARGET_POPCNTD"
13011 "cbcdtd %0,%1"
13012 [(set_attr "type" "integer")
13013 (set_attr "length" "4")])
13014
13015 (define_int_iterator UNSPEC_DIV_EXTEND [UNSPEC_DIVE
13016 UNSPEC_DIVEO
13017 UNSPEC_DIVEU
13018 UNSPEC_DIVEUO])
13019
13020 (define_int_attr div_extend [(UNSPEC_DIVE "e")
13021 (UNSPEC_DIVEO "eo")
13022 (UNSPEC_DIVEU "eu")
13023 (UNSPEC_DIVEUO "euo")])
13024
13025 (define_insn "div<div_extend>_<mode>"
13026 [(set (match_operand:GPR 0 "register_operand" "=r")
13027 (unspec:GPR [(match_operand:GPR 1 "register_operand" "r")
13028 (match_operand:GPR 2 "register_operand" "r")]
13029 UNSPEC_DIV_EXTEND))]
13030 "TARGET_POPCNTD"
13031 "div<wd><div_extend> %0,%1,%2"
13032 [(set_attr "type" "div")
13033 (set_attr "size" "<bits>")])
13034
13035 \f
13036 ;; Pack/unpack 128-bit floating point types that take 2 scalar registers
13037
13038 ; Type of the 64-bit part when packing/unpacking 128-bit floating point types
13039 (define_mode_attr FP128_64 [(TF "DF")
13040 (IF "DF")
13041 (TD "DI")
13042 (KF "DI")])
13043
13044 (define_expand "unpack<mode>"
13045 [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "")
13046 (unspec:<FP128_64>
13047 [(match_operand:FMOVE128 1 "register_operand" "")
13048 (match_operand:QI 2 "const_0_to_1_operand" "")]
13049 UNSPEC_UNPACK_128BIT))]
13050 "FLOAT128_2REG_P (<MODE>mode)"
13051 "")
13052
13053 (define_insn_and_split "unpack<mode>_dm"
13054 [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m,d,r,m")
13055 (unspec:<FP128_64>
13056 [(match_operand:FMOVE128 1 "register_operand" "d,d,r,d,r")
13057 (match_operand:QI 2 "const_0_to_1_operand" "i,i,i,i,i")]
13058 UNSPEC_UNPACK_128BIT))]
13059 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE && FLOAT128_2REG_P (<MODE>mode)"
13060 "#"
13061 "&& reload_completed"
13062 [(set (match_dup 0) (match_dup 3))]
13063 {
13064 unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
13065
13066 if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
13067 {
13068 emit_note (NOTE_INSN_DELETED);
13069 DONE;
13070 }
13071
13072 operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
13073 }
13074 [(set_attr "type" "fp,fpstore,mffgpr,mftgpr,store")
13075 (set_attr "length" "4")])
13076
13077 (define_insn_and_split "unpack<mode>_nodm"
13078 [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m")
13079 (unspec:<FP128_64>
13080 [(match_operand:FMOVE128 1 "register_operand" "d,d")
13081 (match_operand:QI 2 "const_0_to_1_operand" "i,i")]
13082 UNSPEC_UNPACK_128BIT))]
13083 "(!TARGET_POWERPC64 || !TARGET_DIRECT_MOVE) && FLOAT128_2REG_P (<MODE>mode)"
13084 "#"
13085 "&& reload_completed"
13086 [(set (match_dup 0) (match_dup 3))]
13087 {
13088 unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
13089
13090 if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
13091 {
13092 emit_note (NOTE_INSN_DELETED);
13093 DONE;
13094 }
13095
13096 operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
13097 }
13098 [(set_attr "type" "fp,fpstore")
13099 (set_attr "length" "4")])
13100
13101 (define_insn_and_split "pack<mode>"
13102 [(set (match_operand:FMOVE128 0 "register_operand" "=d,&d")
13103 (unspec:FMOVE128
13104 [(match_operand:<FP128_64> 1 "register_operand" "0,d")
13105 (match_operand:<FP128_64> 2 "register_operand" "d,d")]
13106 UNSPEC_PACK_128BIT))]
13107 "FLOAT128_2REG_P (<MODE>mode)"
13108 "@
13109 fmr %L0,%2
13110 #"
13111 "&& reload_completed && REGNO (operands[0]) != REGNO (operands[1])"
13112 [(set (match_dup 3) (match_dup 1))
13113 (set (match_dup 4) (match_dup 2))]
13114 {
13115 unsigned dest_hi = REGNO (operands[0]);
13116 unsigned dest_lo = dest_hi + 1;
13117
13118 gcc_assert (!IN_RANGE (REGNO (operands[1]), dest_hi, dest_lo));
13119 gcc_assert (!IN_RANGE (REGNO (operands[2]), dest_hi, dest_lo));
13120
13121 operands[3] = gen_rtx_REG (<FP128_64>mode, dest_hi);
13122 operands[4] = gen_rtx_REG (<FP128_64>mode, dest_lo);
13123 }
13124 [(set_attr "type" "fp,fp")
13125 (set_attr "length" "4,8")])
13126
13127 (define_insn "unpack<mode>"
13128 [(set (match_operand:DI 0 "register_operand" "=d,d")
13129 (unspec:DI [(match_operand:FMOVE128_VSX 1 "register_operand" "0,wa")
13130 (match_operand:QI 2 "const_0_to_1_operand" "O,i")]
13131 UNSPEC_UNPACK_128BIT))]
13132 "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)"
13133 {
13134 if (REGNO (operands[0]) == REGNO (operands[1]) && INTVAL (operands[2]) == 0)
13135 return ASM_COMMENT_START " xxpermdi to same register";
13136
13137 operands[3] = GEN_INT (INTVAL (operands[2]) == 0 ? 0 : 3);
13138 return "xxpermdi %x0,%x1,%x1,%3";
13139 }
13140 [(set_attr "type" "vecperm")])
13141
13142 (define_insn "pack<mode>"
13143 [(set (match_operand:FMOVE128_VSX 0 "register_operand" "=wa")
13144 (unspec:FMOVE128_VSX
13145 [(match_operand:DI 1 "register_operand" "d")
13146 (match_operand:DI 2 "register_operand" "d")]
13147 UNSPEC_PACK_128BIT))]
13148 "TARGET_VSX"
13149 "xxpermdi %x0,%x1,%x2,0"
13150 [(set_attr "type" "vecperm")])
13151
13152
13153 \f
13154 ;; ISA 2.08 IEEE 128-bit floating point support.
13155
13156 (define_insn "add<mode>3"
13157 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13158 (plus:IEEE128
13159 (match_operand:IEEE128 1 "altivec_register_operand" "v")
13160 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13161 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13162 "xsaddqp %0,%1,%2"
13163 [(set_attr "type" "vecfloat")])
13164
13165 (define_insn "sub<mode>3"
13166 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13167 (minus:IEEE128
13168 (match_operand:IEEE128 1 "altivec_register_operand" "v")
13169 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13170 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13171 "xssubqp %0,%1,%2"
13172 [(set_attr "type" "vecfloat")])
13173
13174 (define_insn "mul<mode>3"
13175 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13176 (mult:IEEE128
13177 (match_operand:IEEE128 1 "altivec_register_operand" "v")
13178 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13179 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13180 "xsmulqp %0,%1,%2"
13181 [(set_attr "type" "vecfloat")])
13182
13183 (define_insn "div<mode>3"
13184 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13185 (div:IEEE128
13186 (match_operand:IEEE128 1 "altivec_register_operand" "v")
13187 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13188 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13189 "xsdivqp %0,%1,%2"
13190 [(set_attr "type" "vecdiv")])
13191
13192 (define_insn "sqrt<mode>2"
13193 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13194 (sqrt:IEEE128
13195 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
13196 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13197 "xssqrtqp %0,%1"
13198 [(set_attr "type" "vecdiv")])
13199
13200 (define_insn "copysign<mode>3"
13201 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13202 (unspec:IEEE128
13203 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
13204 (match_operand:IEEE128 2 "altivec_register_operand" "v")]
13205 UNSPEC_COPYSIGN))]
13206 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13207 "xscpsgnqp %0,%2,%1"
13208 [(set_attr "type" "vecsimple")])
13209
13210 (define_insn "neg<mode>2_hw"
13211 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13212 (neg:IEEE128
13213 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
13214 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13215 "xsnegqp %0,%1"
13216 [(set_attr "type" "vecfloat")])
13217
13218
13219 (define_insn "abs<mode>2_hw"
13220 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13221 (abs:IEEE128
13222 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
13223 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13224 "xsabsqp %0,%1"
13225 [(set_attr "type" "vecfloat")])
13226
13227
13228 (define_insn "*nabs<mode>2_hw"
13229 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13230 (neg:IEEE128
13231 (abs:IEEE128
13232 (match_operand:IEEE128 1 "altivec_register_operand" "v"))))]
13233 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13234 "xsnabsqp %0,%1"
13235 [(set_attr "type" "vecfloat")])
13236
13237 ;; Initially don't worry about doing fusion
13238 (define_insn "*fma<mode>4_hw"
13239 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13240 (fma:IEEE128
13241 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
13242 (match_operand:IEEE128 2 "altivec_register_operand" "v")
13243 (match_operand:IEEE128 3 "altivec_register_operand" "0")))]
13244 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13245 "xsmaddqp %0,%1,%2"
13246 [(set_attr "type" "vecfloat")])
13247
13248 (define_insn "*fms<mode>4_hw"
13249 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13250 (fma:IEEE128
13251 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
13252 (match_operand:IEEE128 2 "altivec_register_operand" "v")
13253 (neg:IEEE128
13254 (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
13255 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13256 "xsmsubqp %0,%1,%2"
13257 [(set_attr "type" "vecfloat")])
13258
13259 (define_insn "*nfma<mode>4_hw"
13260 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13261 (neg:IEEE128
13262 (fma:IEEE128
13263 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
13264 (match_operand:IEEE128 2 "altivec_register_operand" "v")
13265 (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
13266 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13267 "xsnmaddqp %0,%1,%2"
13268 [(set_attr "type" "vecfloat")])
13269
13270 (define_insn "*nfms<mode>4_hw"
13271 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13272 (neg:IEEE128
13273 (fma:IEEE128
13274 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
13275 (match_operand:IEEE128 2 "altivec_register_operand" "v")
13276 (neg:IEEE128
13277 (match_operand:IEEE128 3 "altivec_register_operand" "0")))))]
13278 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13279 "xsnmsubqp %0,%1,%2"
13280 [(set_attr "type" "vecfloat")])
13281
13282 (define_insn "extend<SFDF:mode><IEEE128:mode>2_hw"
13283 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13284 (float_extend:IEEE128
13285 (match_operand:SFDF 1 "altivec_register_operand" "v")))]
13286 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
13287 "xscvdpqp %0,%1"
13288 [(set_attr "type" "vecfloat")])
13289
13290 (define_insn "trunc<mode>df2_hw"
13291 [(set (match_operand:DF 0 "altivec_register_operand" "=v")
13292 (float_truncate:DF
13293 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
13294 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13295 "xscvqpdp %0,%1"
13296 [(set_attr "type" "vecfloat")])
13297
13298 ;; There is no KFmode -> SFmode instruction. Preserve the accuracy by doing
13299 ;; the KFmode -> DFmode conversion using round to odd rather than the normal
13300 ;; conversion
13301 (define_insn_and_split "trunc<mode>sf2_hw"
13302 [(set (match_operand:SF 0 "vsx_register_operand" "=wy")
13303 (float_truncate:SF
13304 (match_operand:IEEE128 1 "altivec_register_operand" "v")))
13305 (clobber (match_scratch:DF 2 "=v"))]
13306 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13307 "#"
13308 "&& 1"
13309 [(set (match_dup 2)
13310 (unspec:DF [(match_dup 1)] UNSPEC_ROUND_TO_ODD))
13311 (set (match_dup 0)
13312 (float_truncate:SF (match_dup 2)))]
13313 {
13314 if (GET_CODE (operands[2]) == SCRATCH)
13315 operands[2] = gen_reg_rtx (DFmode);
13316 }
13317 [(set_attr "type" "vecfloat")
13318 (set_attr "length" "8")])
13319
13320 ;; At present SImode is not allowed in VSX registers at all, and DImode is only
13321 ;; allowed in the traditional floating point registers. Use V2DImode so that
13322 ;; we can get a value in an Altivec register.
13323
13324 (define_insn_and_split "fix<uns>_<mode>si2_hw"
13325 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,Z")
13326 (any_fix:SI (match_operand:IEEE128 1 "altivec_register_operand" "v,v")))
13327 (clobber (match_scratch:V2DI 2 "=v,v"))]
13328 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13329 "#"
13330 "&& 1"
13331 [(pc)]
13332 {
13333 convert_float128_to_int (operands, <CODE>);
13334 DONE;
13335 }
13336 [(set_attr "length" "8")
13337 (set_attr "type" "mftgpr,fpstore")])
13338
13339 (define_insn_and_split "fix<uns>_<mode>di2_hw"
13340 [(set (match_operand:DI 0 "nonimmediate_operand" "=wr,wi,Z")
13341 (any_fix:DI (match_operand:IEEE128 1 "altivec_register_operand" "v,v,v")))
13342 (clobber (match_scratch:V2DI 2 "=v,v,v"))]
13343 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13344 "#"
13345 "&& 1"
13346 [(pc)]
13347 {
13348 convert_float128_to_int (operands, <CODE>);
13349 DONE;
13350 }
13351 [(set_attr "length" "8")
13352 (set_attr "type" "mftgpr,vecsimple,fpstore")])
13353
13354 (define_insn_and_split "float<uns>_<mode>si2_hw"
13355 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v")
13356 (any_float:IEEE128 (match_operand:SI 1 "nonimmediate_operand" "r,Z")))
13357 (clobber (match_scratch:V2DI 2 "=v,v"))]
13358 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13359 "#"
13360 "&& 1"
13361 [(pc)]
13362 {
13363 convert_int_to_float128 (operands, <CODE>);
13364 DONE;
13365 }
13366 [(set_attr "length" "8")
13367 (set_attr "type" "vecfloat")])
13368
13369 (define_insn_and_split "float<uns>_<mode>di2_hw"
13370 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v")
13371 (any_float:IEEE128 (match_operand:DI 1 "nonimmediate_operand" "wi,wr,Z")))
13372 (clobber (match_scratch:V2DI 2 "=v,v,v"))]
13373 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13374 "#"
13375 "&& 1"
13376 [(pc)]
13377 {
13378 convert_int_to_float128 (operands, <CODE>);
13379 DONE;
13380 }
13381 [(set_attr "length" "8")
13382 (set_attr "type" "vecfloat")])
13383
13384 ;; Integer conversion instructions, using V2DImode to get an Altivec register
13385 (define_insn "*xscvqp<su>wz_<mode>"
13386 [(set (match_operand:V2DI 0 "altivec_register_operand" "=v")
13387 (unspec:V2DI
13388 [(any_fix:SI
13389 (match_operand:IEEE128 1 "altivec_register_operand" "v"))]
13390 UNSPEC_IEEE128_CONVERT))]
13391 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13392 "xscvqp<su>wz %0,%1"
13393 [(set_attr "type" "vecfloat")])
13394
13395 (define_insn "*xscvqp<su>dz_<mode>"
13396 [(set (match_operand:V2DI 0 "altivec_register_operand" "=v")
13397 (unspec:V2DI
13398 [(any_fix:DI
13399 (match_operand:IEEE128 1 "altivec_register_operand" "v"))]
13400 UNSPEC_IEEE128_CONVERT))]
13401 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13402 "xscvqp<su>dz %0,%1"
13403 [(set_attr "type" "vecfloat")])
13404
13405 (define_insn "*xscv<su>dqp_<mode>"
13406 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13407 (any_float:IEEE128
13408 (unspec:DI [(match_operand:V2DI 1 "altivec_register_operand" "v")]
13409 UNSPEC_IEEE128_CONVERT)))]
13410 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13411 "xscv<su>dqp %0,%1"
13412 [(set_attr "type" "vecfloat")])
13413
13414 (define_insn "*ieee128_mfvsrd"
13415 [(set (match_operand:DI 0 "reg_or_indexed_operand" "=wr,Z,wi")
13416 (unspec:DI [(match_operand:V2DI 1 "altivec_register_operand" "v,v,v")]
13417 UNSPEC_IEEE128_MOVE))]
13418 "TARGET_FLOAT128_HW && TARGET_POWERPC64"
13419 "@
13420 mfvsrd %0,%x1
13421 stxsdx %x1,%y0
13422 xxlor %x0,%x1,%x1"
13423 [(set_attr "type" "mftgpr,vecsimple,fpstore")])
13424
13425 (define_insn "*ieee128_mfvsrwz"
13426 [(set (match_operand:SI 0 "reg_or_indexed_operand" "=r,Z")
13427 (unspec:SI [(match_operand:V2DI 1 "altivec_register_operand" "v,v")]
13428 UNSPEC_IEEE128_MOVE))]
13429 "TARGET_FLOAT128_HW"
13430 "@
13431 mfvsrwz %0,%x1
13432 stxsiwx %x1,%y0"
13433 [(set_attr "type" "mftgpr,fpstore")])
13434
13435 ;; 0 says do sign-extension, 1 says zero-extension
13436 (define_insn "*ieee128_mtvsrw"
13437 [(set (match_operand:V2DI 0 "altivec_register_operand" "=v,v,v,v")
13438 (unspec:V2DI [(match_operand:SI 1 "nonimmediate_operand" "r,Z,r,Z")
13439 (match_operand:SI 2 "const_0_to_1_operand" "O,O,n,n")]
13440 UNSPEC_IEEE128_MOVE))]
13441 "TARGET_FLOAT128_HW"
13442 "@
13443 mtvsrwa %x0,%1
13444 lxsiwax %x0,%y1
13445 mtvsrwz %x0,%1
13446 lxsiwzx %x0,%y1"
13447 [(set_attr "type" "mffgpr,fpload,mffgpr,fpload")])
13448
13449
13450 (define_insn "*ieee128_mtvsrd"
13451 [(set (match_operand:V2DI 0 "altivec_register_operand" "=v,v,v")
13452 (unspec:V2DI [(match_operand:DI 1 "nonimmediate_operand" "wr,Z,wi")]
13453 UNSPEC_IEEE128_MOVE))]
13454 "TARGET_FLOAT128_HW"
13455 "@
13456 mtvsrd %x0,%1
13457 lxsdx %x0,%y1
13458 xxlor %x0,%x1,%x1"
13459 [(set_attr "type" "mffgpr,fpload,vecsimple")])
13460
13461 ;; IEEE 128-bit instructions with round to odd semantics
13462 (define_insn "*trunc<mode>df2_odd"
13463 [(set (match_operand:DF 0 "vsx_register_operand" "=v")
13464 (unspec:DF [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
13465 UNSPEC_ROUND_TO_ODD))]
13466 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13467 "xscvqpdpo %0,%1"
13468 [(set_attr "type" "vecfloat")])
13469
13470 ;; IEEE 128-bit comparisons
13471 (define_insn "*cmp<mode>_hw"
13472 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
13473 (compare:CCFP (match_operand:IEEE128 1 "altivec_register_operand" "v")
13474 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13475 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13476 "xscmpuqp %0,%1,%2"
13477 [(set_attr "type" "fpcompare")])
13478
13479 \f
13480
13481 (include "sync.md")
13482 (include "vector.md")
13483 (include "vsx.md")
13484 (include "altivec.md")
13485 (include "spe.md")
13486 (include "dfp.md")
13487 (include "paired.md")
13488 (include "crypto.md")
13489 (include "htm.md")