]> gcc.gnu.org Git - gcc.git/blob - gcc/config/rs6000/rs6000.md
8e9ac3bf833e917d493eb93528d7c4a5b9590adb
[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_MOVSI_GOT
73 UNSPEC_MV_CR_OV ; move_from_CR_ov_bit
74 UNSPEC_FCTIWZ
75 UNSPEC_FRIM
76 UNSPEC_FRIN
77 UNSPEC_FRIP
78 UNSPEC_FRIZ
79 UNSPEC_LD_MPIC ; load_macho_picbase
80 UNSPEC_RELD_MPIC ; re-load_macho_picbase
81 UNSPEC_MPIC_CORRECT ; macho_correct_pic
82 UNSPEC_TLSGD
83 UNSPEC_TLSLD
84 UNSPEC_MOVESI_FROM_CR
85 UNSPEC_MOVESI_TO_CR
86 UNSPEC_TLSDTPREL
87 UNSPEC_TLSDTPRELHA
88 UNSPEC_TLSDTPRELLO
89 UNSPEC_TLSGOTDTPREL
90 UNSPEC_TLSTPREL
91 UNSPEC_TLSTPRELHA
92 UNSPEC_TLSTPRELLO
93 UNSPEC_TLSGOTTPREL
94 UNSPEC_TLSTLS
95 UNSPEC_FIX_TRUNC_TF ; fadd, rounding towards zero
96 UNSPEC_MV_CR_GT ; move_from_CR_gt_bit
97 UNSPEC_STFIWX
98 UNSPEC_POPCNTB
99 UNSPEC_FRES
100 UNSPEC_SP_SET
101 UNSPEC_SP_TEST
102 UNSPEC_SYNC
103 UNSPEC_LWSYNC
104 UNSPEC_SYNC_OP
105 UNSPEC_ATOMIC
106 UNSPEC_CMPXCHG
107 UNSPEC_XCHG
108 UNSPEC_AND
109 UNSPEC_DLMZB
110 UNSPEC_DLMZB_CR
111 UNSPEC_DLMZB_STRLEN
112 UNSPEC_RSQRT
113 UNSPEC_TOCREL
114 UNSPEC_MACHOPIC_OFFSET
115 UNSPEC_BPERM
116 UNSPEC_COPYSIGN
117 UNSPEC_PARITY
118 UNSPEC_FCTIW
119 UNSPEC_FCTID
120 UNSPEC_LFIWAX
121 UNSPEC_LFIWZX
122 UNSPEC_FCTIWUZ
123 UNSPEC_GRP_END_NOP
124 UNSPEC_P8V_FMRGOW
125 UNSPEC_P8V_MTVSRWZ
126 UNSPEC_P8V_RELOAD_FROM_GPR
127 UNSPEC_P8V_MTVSRD
128 UNSPEC_P8V_XXPERMDI
129 UNSPEC_P8V_RELOAD_FROM_VSX
130 UNSPEC_ADDG6S
131 UNSPEC_CDTBCD
132 UNSPEC_CBCDTD
133 UNSPEC_DIVE
134 UNSPEC_DIVEO
135 UNSPEC_DIVEU
136 UNSPEC_DIVEUO
137 UNSPEC_UNPACK_128BIT
138 UNSPEC_PACK_128BIT
139 UNSPEC_LSQ
140 UNSPEC_FUSION_GPR
141 ])
142
143 ;;
144 ;; UNSPEC_VOLATILE usage
145 ;;
146
147 (define_c_enum "unspecv"
148 [UNSPECV_BLOCK
149 UNSPECV_LL ; load-locked
150 UNSPECV_SC ; store-conditional
151 UNSPECV_PROBE_STACK_RANGE ; probe range of stack addresses
152 UNSPECV_EH_RR ; eh_reg_restore
153 UNSPECV_ISYNC ; isync instruction
154 UNSPECV_MFTB ; move from time base
155 UNSPECV_NLGR ; non-local goto receiver
156 UNSPECV_MFFS ; Move from FPSCR
157 UNSPECV_MTFSF ; Move to FPSCR Fields
158 ])
159
160 \f
161 ;; Define an insn type attribute. This is used in function unit delay
162 ;; computations.
163 (define_attr "type"
164 "integer,two,three,
165 add,logical,shift,insert,
166 mul,halfmul,div,
167 exts,cntlz,popcnt,isel,
168 load,store,fpload,fpstore,vecload,vecstore,
169 cmp,
170 branch,jmpreg,mfjmpr,mtjmpr,trap,isync,sync,load_l,store_c,
171 cr_logical,delayed_cr,mfcr,mfcrf,mtcr,
172 fpcompare,fp,fpsimple,dmul,sdiv,ddiv,ssqrt,dsqrt,
173 brinc,
174 vecsimple,veccomplex,vecdiv,veccmp,veccmpsimple,vecperm,
175 vecfloat,vecfdiv,vecdouble,mffgpr,mftgpr,crypto,
176 htm"
177 (const_string "integer"))
178
179 ;; What data size does this instruction work on?
180 ;; This is used for insert, mul.
181 (define_attr "size" "8,16,32,64" (const_string "32"))
182
183 ;; Is this instruction record form ("dot", signed compare to 0, writing CR0)?
184 ;; This is used for add, logical, shift, exts, mul.
185 (define_attr "dot" "no,yes" (const_string "no"))
186
187 ;; Does this instruction sign-extend its result?
188 ;; This is used for load insns.
189 (define_attr "sign_extend" "no,yes" (const_string "no"))
190
191 ;; Does this instruction use indexed (that is, reg+reg) addressing?
192 ;; This is used for load and store insns. If operand 0 or 1 is a MEM
193 ;; it is automatically set based on that. If a load or store instruction
194 ;; has fewer than two operands it needs to set this attribute manually
195 ;; or the compiler will crash.
196 (define_attr "indexed" "no,yes"
197 (if_then_else (ior (match_operand 0 "indexed_address_mem")
198 (match_operand 1 "indexed_address_mem"))
199 (const_string "yes")
200 (const_string "no")))
201
202 ;; Does this instruction use update addressing?
203 ;; This is used for load and store insns. See the comments for "indexed".
204 (define_attr "update" "no,yes"
205 (if_then_else (ior (match_operand 0 "update_address_mem")
206 (match_operand 1 "update_address_mem"))
207 (const_string "yes")
208 (const_string "no")))
209
210 ;; Is this instruction using operands[2] as shift amount, and can that be a
211 ;; register?
212 ;; This is used for shift insns.
213 (define_attr "maybe_var_shift" "no,yes" (const_string "no"))
214
215 ;; Is this instruction using a shift amount from a register?
216 ;; This is used for shift insns.
217 (define_attr "var_shift" "no,yes"
218 (if_then_else (and (eq_attr "type" "shift")
219 (eq_attr "maybe_var_shift" "yes"))
220 (if_then_else (match_operand 2 "gpc_reg_operand")
221 (const_string "yes")
222 (const_string "no"))
223 (const_string "no")))
224
225 ;; Define floating point instruction sub-types for use with Xfpu.md
226 (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"))
227
228 ;; Length (in bytes).
229 ; '(pc)' in the following doesn't include the instruction itself; it is
230 ; calculated as if the instruction had zero size.
231 (define_attr "length" ""
232 (if_then_else (eq_attr "type" "branch")
233 (if_then_else (and (ge (minus (match_dup 0) (pc))
234 (const_int -32768))
235 (lt (minus (match_dup 0) (pc))
236 (const_int 32764)))
237 (const_int 4)
238 (const_int 8))
239 (const_int 4)))
240
241 ;; Processor type -- this attribute must exactly match the processor_type
242 ;; enumeration in rs6000-opts.h.
243 (define_attr "cpu"
244 "ppc601,ppc603,ppc604,ppc604e,ppc620,ppc630,
245 ppc750,ppc7400,ppc7450,
246 ppc403,ppc405,ppc440,ppc476,
247 ppc8540,ppc8548,ppce300c2,ppce300c3,ppce500mc,ppce500mc64,ppce5500,ppce6500,
248 power4,power5,power6,power7,power8,
249 rs64a,mpccore,cell,ppca2,titan"
250 (const (symbol_ref "rs6000_cpu_attr")))
251
252
253 ;; If this instruction is microcoded on the CELL processor
254 ; The default for load extended, the recorded instructions and rotate/shifts by a variable is always microcoded
255 (define_attr "cell_micro" "not,conditional,always"
256 (if_then_else (ior (and (eq_attr "type" "shift,exts,mul")
257 (eq_attr "dot" "yes"))
258 (and (eq_attr "type" "load")
259 (eq_attr "sign_extend" "yes"))
260 (and (eq_attr "type" "shift")
261 (eq_attr "var_shift" "yes")))
262 (const_string "always")
263 (const_string "not")))
264
265 (automata_option "ndfa")
266
267 (include "rs64.md")
268 (include "mpc.md")
269 (include "40x.md")
270 (include "440.md")
271 (include "476.md")
272 (include "601.md")
273 (include "603.md")
274 (include "6xx.md")
275 (include "7xx.md")
276 (include "7450.md")
277 (include "8540.md")
278 (include "e300c2c3.md")
279 (include "e500mc.md")
280 (include "e500mc64.md")
281 (include "e5500.md")
282 (include "e6500.md")
283 (include "power4.md")
284 (include "power5.md")
285 (include "power6.md")
286 (include "power7.md")
287 (include "power8.md")
288 (include "cell.md")
289 (include "xfpu.md")
290 (include "a2.md")
291 (include "titan.md")
292
293 (include "predicates.md")
294 (include "constraints.md")
295
296 (include "darwin.md")
297
298 \f
299 ;; Mode iterators
300
301 ; This mode iterator allows :GPR to be used to indicate the allowable size
302 ; of whole values in GPRs.
303 (define_mode_iterator GPR [SI (DI "TARGET_POWERPC64")])
304
305 ; Any supported integer mode.
306 (define_mode_iterator INT [QI HI SI DI TI PTI])
307
308 ; Any supported integer mode that fits in one register.
309 (define_mode_iterator INT1 [QI HI SI (DI "TARGET_POWERPC64")])
310
311 ; Everything we can extend QImode to.
312 (define_mode_iterator EXTQI [HI SI (DI "TARGET_POWERPC64")])
313
314 ; Everything we can extend HImode to.
315 (define_mode_iterator EXTHI [SI (DI "TARGET_POWERPC64")])
316
317 ; Everything we can extend SImode to.
318 (define_mode_iterator EXTSI [(DI "TARGET_POWERPC64")])
319
320 ; QImode or HImode for small atomic ops
321 (define_mode_iterator QHI [QI HI])
322
323 ; HImode or SImode for sign extended fusion ops
324 (define_mode_iterator HSI [HI SI])
325
326 ; SImode or DImode, even if DImode doesn't fit in GPRs.
327 (define_mode_iterator SDI [SI DI])
328
329 ; The size of a pointer. Also, the size of the value that a record-condition
330 ; (one with a '.') will compare; and the size used for arithmetic carries.
331 (define_mode_iterator P [(SI "TARGET_32BIT") (DI "TARGET_64BIT")])
332
333 ; Iterator to add PTImode along with TImode (TImode can go in VSX registers,
334 ; PTImode is GPR only)
335 (define_mode_iterator TI2 [TI PTI])
336
337 ; Any hardware-supported floating-point mode
338 (define_mode_iterator FP [
339 (SF "TARGET_HARD_FLOAT
340 && ((TARGET_FPRS && TARGET_SINGLE_FLOAT) || TARGET_E500_SINGLE)")
341 (DF "TARGET_HARD_FLOAT
342 && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)")
343 (TF "!TARGET_IEEEQUAD
344 && TARGET_HARD_FLOAT
345 && (TARGET_FPRS || TARGET_E500_DOUBLE)
346 && TARGET_LONG_DOUBLE_128")
347 (DD "TARGET_DFP")
348 (TD "TARGET_DFP")])
349
350 ; Any fma capable floating-point mode.
351 (define_mode_iterator FMA_F [
352 (SF "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT")
353 (DF "(TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
354 || VECTOR_UNIT_VSX_P (DFmode)")
355 (V2SF "TARGET_PAIRED_FLOAT")
356 (V4SF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)")
357 (V2DF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V2DFmode)")
358 ])
359
360 ; Floating point move iterators to combine binary and decimal moves
361 (define_mode_iterator FMOVE32 [SF SD])
362 (define_mode_iterator FMOVE64 [DF DD])
363 (define_mode_iterator FMOVE64X [DI DF DD])
364 (define_mode_iterator FMOVE128 [(TF "!TARGET_IEEEQUAD && TARGET_LONG_DOUBLE_128")
365 (TD "TARGET_HARD_FLOAT && TARGET_FPRS")])
366
367 ; Iterators for 128 bit types for direct move
368 (define_mode_iterator FMOVE128_GPR [(TI "TARGET_VSX_TIMODE")
369 (V16QI "")
370 (V8HI "")
371 (V4SI "")
372 (V4SF "")
373 (V2DI "")
374 (V2DF "")
375 (V1TI "")])
376
377 ; Whether a floating point move is ok, don't allow SD without hardware FP
378 (define_mode_attr fmove_ok [(SF "")
379 (DF "")
380 (SD "TARGET_HARD_FLOAT && TARGET_FPRS")
381 (DD "")])
382
383 ; Convert REAL_VALUE to the appropriate bits
384 (define_mode_attr real_value_to_target [(SF "REAL_VALUE_TO_TARGET_SINGLE")
385 (DF "REAL_VALUE_TO_TARGET_DOUBLE")
386 (SD "REAL_VALUE_TO_TARGET_DECIMAL32")
387 (DD "REAL_VALUE_TO_TARGET_DECIMAL64")])
388
389 ; Definitions for load to 32-bit fpr register
390 (define_mode_attr f32_lr [(SF "f") (SD "wz")])
391 (define_mode_attr f32_lm [(SF "m") (SD "Z")])
392 (define_mode_attr f32_li [(SF "lfs%U1%X1 %0,%1") (SD "lfiwzx %0,%y1")])
393 (define_mode_attr f32_lv [(SF "lxsspx %x0,%y1") (SD "lxsiwzx %x0,%y1")])
394
395 ; Definitions for store from 32-bit fpr register
396 (define_mode_attr f32_sr [(SF "f") (SD "wx")])
397 (define_mode_attr f32_sm [(SF "m") (SD "Z")])
398 (define_mode_attr f32_si [(SF "stfs%U0%X0 %1,%0") (SD "stfiwx %1,%y0")])
399 (define_mode_attr f32_sv [(SF "stxsspx %x1,%y0") (SD "stxsiwzx %x1,%y0")])
400
401 ; Definitions for 32-bit fpr direct move
402 ; At present, the decimal modes are not allowed in the traditional altivec
403 ; registers, so restrict the constraints to just the traditional FPRs.
404 (define_mode_attr f32_dm [(SF "wn") (SD "wh")])
405
406 ; Definitions for 32-bit VSX
407 (define_mode_attr f32_vsx [(SF "ww") (SD "wn")])
408
409 ; Definitions for 32-bit use of altivec registers
410 (define_mode_attr f32_av [(SF "wu") (SD "wn")])
411
412 ; Definitions for 64-bit VSX
413 (define_mode_attr f64_vsx [(DF "ws") (DD "wn")])
414
415 ; Definitions for 64-bit direct move
416 (define_mode_attr f64_dm [(DF "wk") (DD "wh")])
417
418 ; Definitions for 64-bit use of altivec registers
419 (define_mode_attr f64_av [(DF "wv") (DD "wn")])
420
421 ; These modes do not fit in integer registers in 32-bit mode.
422 ; but on e500v2, the gpr are 64 bit registers
423 (define_mode_iterator DIFD [DI (DF "!TARGET_E500_DOUBLE") DD])
424
425 ; Iterator for reciprocal estimate instructions
426 (define_mode_iterator RECIPF [SF DF V4SF V2DF])
427
428 ; Iterator for just SF/DF
429 (define_mode_iterator SFDF [SF DF])
430
431 ; SF/DF suffix for traditional floating instructions
432 (define_mode_attr Ftrad [(SF "s") (DF "")])
433
434 ; SF/DF suffix for VSX instructions
435 (define_mode_attr Fvsx [(SF "sp") (DF "dp")])
436
437 ; SF/DF constraint for arithmetic on traditional floating point registers
438 (define_mode_attr Ff [(SF "f") (DF "d")])
439
440 ; SF/DF constraint for arithmetic on VSX registers
441 (define_mode_attr Fv [(SF "wy") (DF "ws")])
442
443 ; SF/DF constraint for arithmetic on altivec registers
444 (define_mode_attr Fa [(SF "wu") (DF "wv")])
445
446 ; s/d suffix for things like fp_addsub_s/fp_addsub_d
447 (define_mode_attr Fs [(SF "s") (DF "d")])
448
449 ; FRE/FRES support
450 (define_mode_attr Ffre [(SF "fres") (DF "fre")])
451 (define_mode_attr FFRE [(SF "FRES") (DF "FRE")])
452
453 ; Conditional returns.
454 (define_code_iterator any_return [return simple_return])
455 (define_code_attr return_pred [(return "direct_return ()")
456 (simple_return "1")])
457 (define_code_attr return_str [(return "") (simple_return "simple_")])
458
459 ; Logical operators.
460 (define_code_iterator iorxor [ior xor])
461
462 ; Signed/unsigned variants of ops.
463 (define_code_iterator any_extend [sign_extend zero_extend])
464 (define_code_attr u [(sign_extend "") (zero_extend "u")])
465 (define_code_attr su [(sign_extend "s") (zero_extend "u")])
466
467 ; Various instructions that come in SI and DI forms.
468 ; A generic w/d attribute, for things like cmpw/cmpd.
469 (define_mode_attr wd [(QI "b")
470 (HI "h")
471 (SI "w")
472 (DI "d")
473 (V16QI "b")
474 (V8HI "h")
475 (V4SI "w")
476 (V2DI "d")])
477
478 ;; How many bits in this mode?
479 (define_mode_attr bits [(QI "8") (HI "16") (SI "32") (DI "64")])
480
481 ; DImode bits
482 (define_mode_attr dbits [(QI "56") (HI "48") (SI "32")])
483
484 ;; ISEL/ISEL64 target selection
485 (define_mode_attr sel [(SI "") (DI "64")])
486
487 ;; Bitmask for shift instructions
488 (define_mode_attr hH [(SI "h") (DI "H")])
489
490 ;; A mode twice the size of the given mode
491 (define_mode_attr dmode [(SI "di") (DI "ti")])
492 (define_mode_attr DMODE [(SI "DI") (DI "TI")])
493
494 ;; Suffix for reload patterns
495 (define_mode_attr ptrsize [(SI "32bit")
496 (DI "64bit")])
497
498 (define_mode_attr tptrsize [(SI "TARGET_32BIT")
499 (DI "TARGET_64BIT")])
500
501 (define_mode_attr mptrsize [(SI "si")
502 (DI "di")])
503
504 (define_mode_attr ptrload [(SI "lwz")
505 (DI "ld")])
506
507 (define_mode_attr ptrm [(SI "m")
508 (DI "Y")])
509
510 (define_mode_attr rreg [(SF "f")
511 (DF "ws")
512 (TF "f")
513 (TD "f")
514 (V4SF "wf")
515 (V2DF "wd")])
516
517 (define_mode_attr rreg2 [(SF "f")
518 (DF "d")])
519
520 (define_mode_attr SI_CONVERT_FP [(SF "TARGET_FCFIDS")
521 (DF "TARGET_FCFID")])
522
523 (define_mode_attr E500_CONVERT [(SF "!TARGET_FPRS")
524 (DF "TARGET_E500_DOUBLE")])
525
526 (define_mode_attr TARGET_FLOAT [(SF "TARGET_SINGLE_FLOAT")
527 (DF "TARGET_DOUBLE_FLOAT")])
528
529 ;; Mode iterator for logical operations on 128-bit types
530 (define_mode_iterator BOOL_128 [TI
531 PTI
532 (V16QI "TARGET_ALTIVEC")
533 (V8HI "TARGET_ALTIVEC")
534 (V4SI "TARGET_ALTIVEC")
535 (V4SF "TARGET_ALTIVEC")
536 (V2DI "TARGET_ALTIVEC")
537 (V2DF "TARGET_ALTIVEC")
538 (V1TI "TARGET_ALTIVEC")])
539
540 ;; For the GPRs we use 3 constraints for register outputs, two that are the
541 ;; same as the output register, and a third where the output register is an
542 ;; early clobber, so we don't have to deal with register overlaps. For the
543 ;; vector types, we prefer to use the vector registers. For TI mode, allow
544 ;; either.
545
546 ;; Mode attribute for boolean operation register constraints for output
547 (define_mode_attr BOOL_REGS_OUTPUT [(TI "&r,r,r,wt,v")
548 (PTI "&r,r,r")
549 (V16QI "wa,v,&?r,?r,?r")
550 (V8HI "wa,v,&?r,?r,?r")
551 (V4SI "wa,v,&?r,?r,?r")
552 (V4SF "wa,v,&?r,?r,?r")
553 (V2DI "wa,v,&?r,?r,?r")
554 (V2DF "wa,v,&?r,?r,?r")
555 (V1TI "wa,v,&?r,?r,?r")])
556
557 ;; Mode attribute for boolean operation register constraints for operand1
558 (define_mode_attr BOOL_REGS_OP1 [(TI "r,0,r,wt,v")
559 (PTI "r,0,r")
560 (V16QI "wa,v,r,0,r")
561 (V8HI "wa,v,r,0,r")
562 (V4SI "wa,v,r,0,r")
563 (V4SF "wa,v,r,0,r")
564 (V2DI "wa,v,r,0,r")
565 (V2DF "wa,v,r,0,r")
566 (V1TI "wa,v,r,0,r")])
567
568 ;; Mode attribute for boolean operation register constraints for operand2
569 (define_mode_attr BOOL_REGS_OP2 [(TI "r,r,0,wt,v")
570 (PTI "r,r,0")
571 (V16QI "wa,v,r,r,0")
572 (V8HI "wa,v,r,r,0")
573 (V4SI "wa,v,r,r,0")
574 (V4SF "wa,v,r,r,0")
575 (V2DI "wa,v,r,r,0")
576 (V2DF "wa,v,r,r,0")
577 (V1TI "wa,v,r,r,0")])
578
579 ;; Mode attribute for boolean operation register constraints for operand1
580 ;; for one_cmpl. To simplify things, we repeat the constraint where 0
581 ;; is used for operand1 or operand2
582 (define_mode_attr BOOL_REGS_UNARY [(TI "r,0,0,wt,v")
583 (PTI "r,0,0")
584 (V16QI "wa,v,r,0,0")
585 (V8HI "wa,v,r,0,0")
586 (V4SI "wa,v,r,0,0")
587 (V4SF "wa,v,r,0,0")
588 (V2DI "wa,v,r,0,0")
589 (V2DF "wa,v,r,0,0")
590 (V1TI "wa,v,r,0,0")])
591
592 ;; Reload iterator for creating the function to allocate a base register to
593 ;; supplement addressing modes.
594 (define_mode_iterator RELOAD [V16QI V8HI V4SI V2DI V4SF V2DF V1TI
595 SF SD SI DF DD DI TI PTI])
596
597 \f
598 ;; Start with fixed-point load and store insns. Here we put only the more
599 ;; complex forms. Basic data transfer is done later.
600
601 (define_insn "zero_extendqi<mode>2"
602 [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
603 (zero_extend:EXTQI (match_operand:QI 1 "reg_or_mem_operand" "m,r")))]
604 ""
605 "@
606 lbz%U1%X1 %0,%1
607 rlwinm %0,%1,0,0xff"
608 [(set_attr "type" "load,shift")])
609
610 (define_insn_and_split "*zero_extendqi<mode>2_dot"
611 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
612 (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
613 (const_int 0)))
614 (clobber (match_scratch:EXTQI 0 "=r,r"))]
615 "rs6000_gen_cell_microcode"
616 "@
617 andi. %0,%1,0xff
618 #"
619 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
620 [(set (match_dup 0)
621 (zero_extend:EXTQI (match_dup 1)))
622 (set (match_dup 2)
623 (compare:CC (match_dup 0)
624 (const_int 0)))]
625 ""
626 [(set_attr "type" "logical")
627 (set_attr "dot" "yes")
628 (set_attr "length" "4,8")])
629
630 (define_insn_and_split "*zero_extendqi<mode>2_dot2"
631 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
632 (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
633 (const_int 0)))
634 (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
635 (zero_extend:EXTQI (match_dup 1)))]
636 "rs6000_gen_cell_microcode"
637 "@
638 andi. %0,%1,0xff
639 #"
640 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
641 [(set (match_dup 0)
642 (zero_extend:EXTQI (match_dup 1)))
643 (set (match_dup 2)
644 (compare:CC (match_dup 0)
645 (const_int 0)))]
646 ""
647 [(set_attr "type" "logical")
648 (set_attr "dot" "yes")
649 (set_attr "length" "4,8")])
650
651
652 (define_insn "zero_extendhi<mode>2"
653 [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
654 (zero_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r")))]
655 ""
656 "@
657 lhz%U1%X1 %0,%1
658 rlwinm %0,%1,0,0xffff"
659 [(set_attr "type" "load,shift")])
660
661 (define_insn_and_split "*zero_extendhi<mode>2_dot"
662 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
663 (compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
664 (const_int 0)))
665 (clobber (match_scratch:EXTHI 0 "=r,r"))]
666 "rs6000_gen_cell_microcode"
667 "@
668 andi. %0,%1,0xffff
669 #"
670 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
671 [(set (match_dup 0)
672 (zero_extend:EXTHI (match_dup 1)))
673 (set (match_dup 2)
674 (compare:CC (match_dup 0)
675 (const_int 0)))]
676 ""
677 [(set_attr "type" "logical")
678 (set_attr "dot" "yes")
679 (set_attr "length" "4,8")])
680
681 (define_insn_and_split "*zero_extendhi<mode>2_dot2"
682 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
683 (compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
684 (const_int 0)))
685 (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
686 (zero_extend:EXTHI (match_dup 1)))]
687 "rs6000_gen_cell_microcode"
688 "@
689 andi. %0,%1,0xffff
690 #"
691 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
692 [(set (match_dup 0)
693 (zero_extend:EXTHI (match_dup 1)))
694 (set (match_dup 2)
695 (compare:CC (match_dup 0)
696 (const_int 0)))]
697 ""
698 [(set_attr "type" "logical")
699 (set_attr "dot" "yes")
700 (set_attr "length" "4,8")])
701
702
703 (define_insn "zero_extendsi<mode>2"
704 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r,??wj,!wz,!wu")
705 (zero_extend:EXTSI (match_operand:SI 1 "reg_or_mem_operand" "m,r,r,Z,Z")))]
706 ""
707 "@
708 lwz%U1%X1 %0,%1
709 rldicl %0,%1,0,32
710 mtvsrwz %x0,%1
711 lfiwzx %0,%y1
712 lxsiwzx %x0,%y1"
713 [(set_attr "type" "load,shift,mffgpr,fpload,fpload")])
714
715 (define_insn_and_split "*zero_extendsi<mode>2_dot"
716 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
717 (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
718 (const_int 0)))
719 (clobber (match_scratch:EXTSI 0 "=r,r"))]
720 "rs6000_gen_cell_microcode"
721 "@
722 rldicl. %0,%1,0,32
723 #"
724 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
725 [(set (match_dup 0)
726 (zero_extend:DI (match_dup 1)))
727 (set (match_dup 2)
728 (compare:CC (match_dup 0)
729 (const_int 0)))]
730 ""
731 [(set_attr "type" "shift")
732 (set_attr "dot" "yes")
733 (set_attr "length" "4,8")])
734
735 (define_insn_and_split "*zero_extendsi<mode>2_dot2"
736 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
737 (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
738 (const_int 0)))
739 (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
740 (zero_extend:EXTSI (match_dup 1)))]
741 "rs6000_gen_cell_microcode"
742 "@
743 rldicl. %0,%1,0,32
744 #"
745 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
746 [(set (match_dup 0)
747 (zero_extend:EXTSI (match_dup 1)))
748 (set (match_dup 2)
749 (compare:CC (match_dup 0)
750 (const_int 0)))]
751 ""
752 [(set_attr "type" "shift")
753 (set_attr "dot" "yes")
754 (set_attr "length" "4,8")])
755
756
757 (define_insn "extendqi<mode>2"
758 [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r")
759 (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r")))]
760 ""
761 "extsb %0,%1"
762 [(set_attr "type" "exts")])
763
764 (define_insn_and_split "*extendqi<mode>2_dot"
765 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
766 (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
767 (const_int 0)))
768 (clobber (match_scratch:EXTQI 0 "=r,r"))]
769 "rs6000_gen_cell_microcode"
770 "@
771 extsb. %0,%1
772 #"
773 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
774 [(set (match_dup 0)
775 (sign_extend:EXTQI (match_dup 1)))
776 (set (match_dup 2)
777 (compare:CC (match_dup 0)
778 (const_int 0)))]
779 ""
780 [(set_attr "type" "exts")
781 (set_attr "dot" "yes")
782 (set_attr "length" "4,8")])
783
784 (define_insn_and_split "*extendqi<mode>2_dot2"
785 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
786 (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
787 (const_int 0)))
788 (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
789 (sign_extend:EXTQI (match_dup 1)))]
790 "rs6000_gen_cell_microcode"
791 "@
792 extsb. %0,%1
793 #"
794 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
795 [(set (match_dup 0)
796 (sign_extend:EXTQI (match_dup 1)))
797 (set (match_dup 2)
798 (compare:CC (match_dup 0)
799 (const_int 0)))]
800 ""
801 [(set_attr "type" "exts")
802 (set_attr "dot" "yes")
803 (set_attr "length" "4,8")])
804
805
806 (define_expand "extendhi<mode>2"
807 [(set (match_operand:EXTHI 0 "gpc_reg_operand" "")
808 (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "")))]
809 ""
810 "")
811
812 (define_insn "*extendhi<mode>2"
813 [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
814 (sign_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r")))]
815 "rs6000_gen_cell_microcode"
816 "@
817 lha%U1%X1 %0,%1
818 extsh %0,%1"
819 [(set_attr "type" "load,exts")
820 (set_attr "sign_extend" "yes")])
821
822 (define_insn "*extendhi<mode>2_noload"
823 [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r")
824 (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r")))]
825 "!rs6000_gen_cell_microcode"
826 "extsh %0,%1"
827 [(set_attr "type" "exts")])
828
829 (define_insn_and_split "*extendhi<mode>2_dot"
830 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
831 (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
832 (const_int 0)))
833 (clobber (match_scratch:EXTHI 0 "=r,r"))]
834 "rs6000_gen_cell_microcode"
835 "@
836 extsh. %0,%1
837 #"
838 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
839 [(set (match_dup 0)
840 (sign_extend:EXTHI (match_dup 1)))
841 (set (match_dup 2)
842 (compare:CC (match_dup 0)
843 (const_int 0)))]
844 ""
845 [(set_attr "type" "exts")
846 (set_attr "dot" "yes")
847 (set_attr "length" "4,8")])
848
849 (define_insn_and_split "*extendhi<mode>2_dot2"
850 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
851 (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
852 (const_int 0)))
853 (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
854 (sign_extend:EXTHI (match_dup 1)))]
855 "rs6000_gen_cell_microcode"
856 "@
857 extsh. %0,%1
858 #"
859 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
860 [(set (match_dup 0)
861 (sign_extend:EXTHI (match_dup 1)))
862 (set (match_dup 2)
863 (compare:CC (match_dup 0)
864 (const_int 0)))]
865 ""
866 [(set_attr "type" "exts")
867 (set_attr "dot" "yes")
868 (set_attr "length" "4,8")])
869
870
871 (define_insn "extendsi<mode>2"
872 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r,??wj,!wl,!wu")
873 (sign_extend:EXTSI (match_operand:SI 1 "lwa_operand" "Y,r,r,Z,Z")))]
874 ""
875 "@
876 lwa%U1%X1 %0,%1
877 extsw %0,%1
878 mtvsrwa %x0,%1
879 lfiwax %0,%y1
880 lxsiwax %x0,%y1"
881 [(set_attr "type" "load,exts,mffgpr,fpload,fpload")
882 (set_attr "sign_extend" "yes")])
883
884 (define_insn_and_split "*extendsi<mode>2_dot"
885 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
886 (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
887 (const_int 0)))
888 (clobber (match_scratch:EXTSI 0 "=r,r"))]
889 "rs6000_gen_cell_microcode"
890 "@
891 extsw. %0,%1
892 #"
893 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
894 [(set (match_dup 0)
895 (sign_extend:EXTSI (match_dup 1)))
896 (set (match_dup 2)
897 (compare:CC (match_dup 0)
898 (const_int 0)))]
899 ""
900 [(set_attr "type" "exts")
901 (set_attr "dot" "yes")
902 (set_attr "length" "4,8")])
903
904 (define_insn_and_split "*extendsi<mode>2_dot2"
905 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
906 (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
907 (const_int 0)))
908 (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
909 (sign_extend:EXTSI (match_dup 1)))]
910 "rs6000_gen_cell_microcode"
911 "@
912 extsw. %0,%1
913 #"
914 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
915 [(set (match_dup 0)
916 (sign_extend:EXTSI (match_dup 1)))
917 (set (match_dup 2)
918 (compare:CC (match_dup 0)
919 (const_int 0)))]
920 ""
921 [(set_attr "type" "exts")
922 (set_attr "dot" "yes")
923 (set_attr "length" "4,8")])
924 \f
925 ;; IBM 405, 440, 464 and 476 half-word multiplication operations.
926
927 (define_insn "*macchwc"
928 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
929 (compare:CC (plus:SI (mult:SI (ashiftrt:SI
930 (match_operand:SI 2 "gpc_reg_operand" "r")
931 (const_int 16))
932 (sign_extend:SI
933 (match_operand:HI 1 "gpc_reg_operand" "r")))
934 (match_operand:SI 4 "gpc_reg_operand" "0"))
935 (const_int 0)))
936 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
937 (plus:SI (mult:SI (ashiftrt:SI
938 (match_dup 2)
939 (const_int 16))
940 (sign_extend:SI
941 (match_dup 1)))
942 (match_dup 4)))]
943 "TARGET_MULHW"
944 "macchw. %0,%1,%2"
945 [(set_attr "type" "halfmul")])
946
947 (define_insn "*macchw"
948 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
949 (plus:SI (mult:SI (ashiftrt:SI
950 (match_operand:SI 2 "gpc_reg_operand" "r")
951 (const_int 16))
952 (sign_extend:SI
953 (match_operand:HI 1 "gpc_reg_operand" "r")))
954 (match_operand:SI 3 "gpc_reg_operand" "0")))]
955 "TARGET_MULHW"
956 "macchw %0,%1,%2"
957 [(set_attr "type" "halfmul")])
958
959 (define_insn "*macchwuc"
960 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
961 (compare:CC (plus:SI (mult:SI (lshiftrt:SI
962 (match_operand:SI 2 "gpc_reg_operand" "r")
963 (const_int 16))
964 (zero_extend:SI
965 (match_operand:HI 1 "gpc_reg_operand" "r")))
966 (match_operand:SI 4 "gpc_reg_operand" "0"))
967 (const_int 0)))
968 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
969 (plus:SI (mult:SI (lshiftrt:SI
970 (match_dup 2)
971 (const_int 16))
972 (zero_extend:SI
973 (match_dup 1)))
974 (match_dup 4)))]
975 "TARGET_MULHW"
976 "macchwu. %0,%1,%2"
977 [(set_attr "type" "halfmul")])
978
979 (define_insn "*macchwu"
980 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
981 (plus:SI (mult:SI (lshiftrt:SI
982 (match_operand:SI 2 "gpc_reg_operand" "r")
983 (const_int 16))
984 (zero_extend:SI
985 (match_operand:HI 1 "gpc_reg_operand" "r")))
986 (match_operand:SI 3 "gpc_reg_operand" "0")))]
987 "TARGET_MULHW"
988 "macchwu %0,%1,%2"
989 [(set_attr "type" "halfmul")])
990
991 (define_insn "*machhwc"
992 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
993 (compare:CC (plus:SI (mult:SI (ashiftrt:SI
994 (match_operand:SI 1 "gpc_reg_operand" "%r")
995 (const_int 16))
996 (ashiftrt:SI
997 (match_operand:SI 2 "gpc_reg_operand" "r")
998 (const_int 16)))
999 (match_operand:SI 4 "gpc_reg_operand" "0"))
1000 (const_int 0)))
1001 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1002 (plus:SI (mult:SI (ashiftrt:SI
1003 (match_dup 1)
1004 (const_int 16))
1005 (ashiftrt:SI
1006 (match_dup 2)
1007 (const_int 16)))
1008 (match_dup 4)))]
1009 "TARGET_MULHW"
1010 "machhw. %0,%1,%2"
1011 [(set_attr "type" "halfmul")])
1012
1013 (define_insn "*machhw"
1014 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1015 (plus:SI (mult:SI (ashiftrt:SI
1016 (match_operand:SI 1 "gpc_reg_operand" "%r")
1017 (const_int 16))
1018 (ashiftrt:SI
1019 (match_operand:SI 2 "gpc_reg_operand" "r")
1020 (const_int 16)))
1021 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1022 "TARGET_MULHW"
1023 "machhw %0,%1,%2"
1024 [(set_attr "type" "halfmul")])
1025
1026 (define_insn "*machhwuc"
1027 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1028 (compare:CC (plus:SI (mult:SI (lshiftrt:SI
1029 (match_operand:SI 1 "gpc_reg_operand" "%r")
1030 (const_int 16))
1031 (lshiftrt:SI
1032 (match_operand:SI 2 "gpc_reg_operand" "r")
1033 (const_int 16)))
1034 (match_operand:SI 4 "gpc_reg_operand" "0"))
1035 (const_int 0)))
1036 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1037 (plus:SI (mult:SI (lshiftrt:SI
1038 (match_dup 1)
1039 (const_int 16))
1040 (lshiftrt:SI
1041 (match_dup 2)
1042 (const_int 16)))
1043 (match_dup 4)))]
1044 "TARGET_MULHW"
1045 "machhwu. %0,%1,%2"
1046 [(set_attr "type" "halfmul")])
1047
1048 (define_insn "*machhwu"
1049 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1050 (plus:SI (mult:SI (lshiftrt:SI
1051 (match_operand:SI 1 "gpc_reg_operand" "%r")
1052 (const_int 16))
1053 (lshiftrt:SI
1054 (match_operand:SI 2 "gpc_reg_operand" "r")
1055 (const_int 16)))
1056 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1057 "TARGET_MULHW"
1058 "machhwu %0,%1,%2"
1059 [(set_attr "type" "halfmul")])
1060
1061 (define_insn "*maclhwc"
1062 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1063 (compare:CC (plus:SI (mult:SI (sign_extend:SI
1064 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1065 (sign_extend:SI
1066 (match_operand:HI 2 "gpc_reg_operand" "r")))
1067 (match_operand:SI 4 "gpc_reg_operand" "0"))
1068 (const_int 0)))
1069 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1070 (plus:SI (mult:SI (sign_extend:SI
1071 (match_dup 1))
1072 (sign_extend:SI
1073 (match_dup 2)))
1074 (match_dup 4)))]
1075 "TARGET_MULHW"
1076 "maclhw. %0,%1,%2"
1077 [(set_attr "type" "halfmul")])
1078
1079 (define_insn "*maclhw"
1080 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1081 (plus:SI (mult:SI (sign_extend:SI
1082 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1083 (sign_extend:SI
1084 (match_operand:HI 2 "gpc_reg_operand" "r")))
1085 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1086 "TARGET_MULHW"
1087 "maclhw %0,%1,%2"
1088 [(set_attr "type" "halfmul")])
1089
1090 (define_insn "*maclhwuc"
1091 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1092 (compare:CC (plus:SI (mult:SI (zero_extend:SI
1093 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1094 (zero_extend:SI
1095 (match_operand:HI 2 "gpc_reg_operand" "r")))
1096 (match_operand:SI 4 "gpc_reg_operand" "0"))
1097 (const_int 0)))
1098 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1099 (plus:SI (mult:SI (zero_extend:SI
1100 (match_dup 1))
1101 (zero_extend:SI
1102 (match_dup 2)))
1103 (match_dup 4)))]
1104 "TARGET_MULHW"
1105 "maclhwu. %0,%1,%2"
1106 [(set_attr "type" "halfmul")])
1107
1108 (define_insn "*maclhwu"
1109 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1110 (plus:SI (mult:SI (zero_extend:SI
1111 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1112 (zero_extend:SI
1113 (match_operand:HI 2 "gpc_reg_operand" "r")))
1114 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1115 "TARGET_MULHW"
1116 "maclhwu %0,%1,%2"
1117 [(set_attr "type" "halfmul")])
1118
1119 (define_insn "*nmacchwc"
1120 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1121 (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1122 (mult:SI (ashiftrt:SI
1123 (match_operand:SI 2 "gpc_reg_operand" "r")
1124 (const_int 16))
1125 (sign_extend:SI
1126 (match_operand:HI 1 "gpc_reg_operand" "r"))))
1127 (const_int 0)))
1128 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1129 (minus:SI (match_dup 4)
1130 (mult:SI (ashiftrt:SI
1131 (match_dup 2)
1132 (const_int 16))
1133 (sign_extend:SI
1134 (match_dup 1)))))]
1135 "TARGET_MULHW"
1136 "nmacchw. %0,%1,%2"
1137 [(set_attr "type" "halfmul")])
1138
1139 (define_insn "*nmacchw"
1140 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1141 (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1142 (mult:SI (ashiftrt:SI
1143 (match_operand:SI 2 "gpc_reg_operand" "r")
1144 (const_int 16))
1145 (sign_extend:SI
1146 (match_operand:HI 1 "gpc_reg_operand" "r")))))]
1147 "TARGET_MULHW"
1148 "nmacchw %0,%1,%2"
1149 [(set_attr "type" "halfmul")])
1150
1151 (define_insn "*nmachhwc"
1152 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1153 (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1154 (mult:SI (ashiftrt:SI
1155 (match_operand:SI 1 "gpc_reg_operand" "%r")
1156 (const_int 16))
1157 (ashiftrt:SI
1158 (match_operand:SI 2 "gpc_reg_operand" "r")
1159 (const_int 16))))
1160 (const_int 0)))
1161 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1162 (minus:SI (match_dup 4)
1163 (mult:SI (ashiftrt:SI
1164 (match_dup 1)
1165 (const_int 16))
1166 (ashiftrt:SI
1167 (match_dup 2)
1168 (const_int 16)))))]
1169 "TARGET_MULHW"
1170 "nmachhw. %0,%1,%2"
1171 [(set_attr "type" "halfmul")])
1172
1173 (define_insn "*nmachhw"
1174 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1175 (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1176 (mult:SI (ashiftrt:SI
1177 (match_operand:SI 1 "gpc_reg_operand" "%r")
1178 (const_int 16))
1179 (ashiftrt:SI
1180 (match_operand:SI 2 "gpc_reg_operand" "r")
1181 (const_int 16)))))]
1182 "TARGET_MULHW"
1183 "nmachhw %0,%1,%2"
1184 [(set_attr "type" "halfmul")])
1185
1186 (define_insn "*nmaclhwc"
1187 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1188 (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1189 (mult:SI (sign_extend:SI
1190 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1191 (sign_extend:SI
1192 (match_operand:HI 2 "gpc_reg_operand" "r"))))
1193 (const_int 0)))
1194 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1195 (minus:SI (match_dup 4)
1196 (mult:SI (sign_extend:SI
1197 (match_dup 1))
1198 (sign_extend:SI
1199 (match_dup 2)))))]
1200 "TARGET_MULHW"
1201 "nmaclhw. %0,%1,%2"
1202 [(set_attr "type" "halfmul")])
1203
1204 (define_insn "*nmaclhw"
1205 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1206 (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1207 (mult:SI (sign_extend:SI
1208 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1209 (sign_extend:SI
1210 (match_operand:HI 2 "gpc_reg_operand" "r")))))]
1211 "TARGET_MULHW"
1212 "nmaclhw %0,%1,%2"
1213 [(set_attr "type" "halfmul")])
1214
1215 (define_insn "*mulchwc"
1216 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1217 (compare:CC (mult:SI (ashiftrt:SI
1218 (match_operand:SI 2 "gpc_reg_operand" "r")
1219 (const_int 16))
1220 (sign_extend:SI
1221 (match_operand:HI 1 "gpc_reg_operand" "r")))
1222 (const_int 0)))
1223 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
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 "mulchw. %0,%1,%2"
1231 [(set_attr "type" "halfmul")])
1232
1233 (define_insn "*mulchw"
1234 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1235 (mult:SI (ashiftrt:SI
1236 (match_operand:SI 2 "gpc_reg_operand" "r")
1237 (const_int 16))
1238 (sign_extend:SI
1239 (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1240 "TARGET_MULHW"
1241 "mulchw %0,%1,%2"
1242 [(set_attr "type" "halfmul")])
1243
1244 (define_insn "*mulchwuc"
1245 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1246 (compare:CC (mult:SI (lshiftrt:SI
1247 (match_operand:SI 2 "gpc_reg_operand" "r")
1248 (const_int 16))
1249 (zero_extend:SI
1250 (match_operand:HI 1 "gpc_reg_operand" "r")))
1251 (const_int 0)))
1252 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1253 (mult:SI (lshiftrt:SI
1254 (match_dup 2)
1255 (const_int 16))
1256 (zero_extend:SI
1257 (match_dup 1))))]
1258 "TARGET_MULHW"
1259 "mulchwu. %0,%1,%2"
1260 [(set_attr "type" "halfmul")])
1261
1262 (define_insn "*mulchwu"
1263 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1264 (mult:SI (lshiftrt:SI
1265 (match_operand:SI 2 "gpc_reg_operand" "r")
1266 (const_int 16))
1267 (zero_extend:SI
1268 (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1269 "TARGET_MULHW"
1270 "mulchwu %0,%1,%2"
1271 [(set_attr "type" "halfmul")])
1272
1273 (define_insn "*mulhhwc"
1274 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1275 (compare:CC (mult:SI (ashiftrt:SI
1276 (match_operand:SI 1 "gpc_reg_operand" "%r")
1277 (const_int 16))
1278 (ashiftrt:SI
1279 (match_operand:SI 2 "gpc_reg_operand" "r")
1280 (const_int 16)))
1281 (const_int 0)))
1282 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1283 (mult:SI (ashiftrt:SI
1284 (match_dup 1)
1285 (const_int 16))
1286 (ashiftrt:SI
1287 (match_dup 2)
1288 (const_int 16))))]
1289 "TARGET_MULHW"
1290 "mulhhw. %0,%1,%2"
1291 [(set_attr "type" "halfmul")])
1292
1293 (define_insn "*mulhhw"
1294 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1295 (mult:SI (ashiftrt:SI
1296 (match_operand:SI 1 "gpc_reg_operand" "%r")
1297 (const_int 16))
1298 (ashiftrt:SI
1299 (match_operand:SI 2 "gpc_reg_operand" "r")
1300 (const_int 16))))]
1301 "TARGET_MULHW"
1302 "mulhhw %0,%1,%2"
1303 [(set_attr "type" "halfmul")])
1304
1305 (define_insn "*mulhhwuc"
1306 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1307 (compare:CC (mult:SI (lshiftrt:SI
1308 (match_operand:SI 1 "gpc_reg_operand" "%r")
1309 (const_int 16))
1310 (lshiftrt:SI
1311 (match_operand:SI 2 "gpc_reg_operand" "r")
1312 (const_int 16)))
1313 (const_int 0)))
1314 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1315 (mult:SI (lshiftrt:SI
1316 (match_dup 1)
1317 (const_int 16))
1318 (lshiftrt:SI
1319 (match_dup 2)
1320 (const_int 16))))]
1321 "TARGET_MULHW"
1322 "mulhhwu. %0,%1,%2"
1323 [(set_attr "type" "halfmul")])
1324
1325 (define_insn "*mulhhwu"
1326 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1327 (mult:SI (lshiftrt:SI
1328 (match_operand:SI 1 "gpc_reg_operand" "%r")
1329 (const_int 16))
1330 (lshiftrt:SI
1331 (match_operand:SI 2 "gpc_reg_operand" "r")
1332 (const_int 16))))]
1333 "TARGET_MULHW"
1334 "mulhhwu %0,%1,%2"
1335 [(set_attr "type" "halfmul")])
1336
1337 (define_insn "*mullhwc"
1338 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1339 (compare:CC (mult:SI (sign_extend:SI
1340 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1341 (sign_extend:SI
1342 (match_operand:HI 2 "gpc_reg_operand" "r")))
1343 (const_int 0)))
1344 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1345 (mult:SI (sign_extend:SI
1346 (match_dup 1))
1347 (sign_extend:SI
1348 (match_dup 2))))]
1349 "TARGET_MULHW"
1350 "mullhw. %0,%1,%2"
1351 [(set_attr "type" "halfmul")])
1352
1353 (define_insn "*mullhw"
1354 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1355 (mult:SI (sign_extend:SI
1356 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1357 (sign_extend:SI
1358 (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1359 "TARGET_MULHW"
1360 "mullhw %0,%1,%2"
1361 [(set_attr "type" "halfmul")])
1362
1363 (define_insn "*mullhwuc"
1364 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1365 (compare:CC (mult:SI (zero_extend:SI
1366 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1367 (zero_extend:SI
1368 (match_operand:HI 2 "gpc_reg_operand" "r")))
1369 (const_int 0)))
1370 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1371 (mult:SI (zero_extend:SI
1372 (match_dup 1))
1373 (zero_extend:SI
1374 (match_dup 2))))]
1375 "TARGET_MULHW"
1376 "mullhwu. %0,%1,%2"
1377 [(set_attr "type" "halfmul")])
1378
1379 (define_insn "*mullhwu"
1380 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1381 (mult:SI (zero_extend:SI
1382 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1383 (zero_extend:SI
1384 (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1385 "TARGET_MULHW"
1386 "mullhwu %0,%1,%2"
1387 [(set_attr "type" "halfmul")])
1388 \f
1389 ;; IBM 405, 440, 464 and 476 string-search dlmzb instruction support.
1390 (define_insn "dlmzb"
1391 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1392 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
1393 (match_operand:SI 2 "gpc_reg_operand" "r")]
1394 UNSPEC_DLMZB_CR))
1395 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1396 (unspec:SI [(match_dup 1)
1397 (match_dup 2)]
1398 UNSPEC_DLMZB))]
1399 "TARGET_DLMZB"
1400 "dlmzb. %0,%1,%2")
1401
1402 (define_expand "strlensi"
1403 [(set (match_operand:SI 0 "gpc_reg_operand" "")
1404 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
1405 (match_operand:QI 2 "const_int_operand" "")
1406 (match_operand 3 "const_int_operand" "")]
1407 UNSPEC_DLMZB_STRLEN))
1408 (clobber (match_scratch:CC 4 "=x"))]
1409 "TARGET_DLMZB && WORDS_BIG_ENDIAN && !optimize_size"
1410 {
1411 rtx result = operands[0];
1412 rtx src = operands[1];
1413 rtx search_char = operands[2];
1414 rtx align = operands[3];
1415 rtx addr, scratch_string, word1, word2, scratch_dlmzb;
1416 rtx loop_label, end_label, mem, cr0, cond;
1417 if (search_char != const0_rtx
1418 || GET_CODE (align) != CONST_INT
1419 || INTVAL (align) < 8)
1420 FAIL;
1421 word1 = gen_reg_rtx (SImode);
1422 word2 = gen_reg_rtx (SImode);
1423 scratch_dlmzb = gen_reg_rtx (SImode);
1424 scratch_string = gen_reg_rtx (Pmode);
1425 loop_label = gen_label_rtx ();
1426 end_label = gen_label_rtx ();
1427 addr = force_reg (Pmode, XEXP (src, 0));
1428 emit_move_insn (scratch_string, addr);
1429 emit_label (loop_label);
1430 mem = change_address (src, SImode, scratch_string);
1431 emit_move_insn (word1, mem);
1432 emit_move_insn (word2, adjust_address (mem, SImode, 4));
1433 cr0 = gen_rtx_REG (CCmode, CR0_REGNO);
1434 emit_insn (gen_dlmzb (scratch_dlmzb, word1, word2, cr0));
1435 cond = gen_rtx_NE (VOIDmode, cr0, const0_rtx);
1436 emit_jump_insn (gen_rtx_SET (VOIDmode,
1437 pc_rtx,
1438 gen_rtx_IF_THEN_ELSE (VOIDmode,
1439 cond,
1440 gen_rtx_LABEL_REF
1441 (VOIDmode,
1442 end_label),
1443 pc_rtx)));
1444 emit_insn (gen_addsi3 (scratch_string, scratch_string, GEN_INT (8)));
1445 emit_jump_insn (gen_rtx_SET (VOIDmode,
1446 pc_rtx,
1447 gen_rtx_LABEL_REF (VOIDmode, loop_label)));
1448 emit_barrier ();
1449 emit_label (end_label);
1450 emit_insn (gen_addsi3 (scratch_string, scratch_string, scratch_dlmzb));
1451 emit_insn (gen_subsi3 (result, scratch_string, addr));
1452 emit_insn (gen_addsi3 (result, result, constm1_rtx));
1453 DONE;
1454 })
1455 \f
1456 ;; Fixed-point arithmetic insns.
1457
1458 (define_expand "add<mode>3"
1459 [(set (match_operand:SDI 0 "gpc_reg_operand" "")
1460 (plus:SDI (match_operand:SDI 1 "gpc_reg_operand" "")
1461 (match_operand:SDI 2 "reg_or_add_cint_operand" "")))]
1462 ""
1463 {
1464 if (<MODE>mode == DImode && !TARGET_POWERPC64)
1465 {
1466 rtx lo0 = gen_lowpart (SImode, operands[0]);
1467 rtx lo1 = gen_lowpart (SImode, operands[1]);
1468 rtx lo2 = gen_lowpart (SImode, operands[2]);
1469 rtx hi0 = gen_highpart (SImode, operands[0]);
1470 rtx hi1 = gen_highpart (SImode, operands[1]);
1471 rtx hi2 = gen_highpart_mode (SImode, DImode, operands[2]);
1472
1473 if (!reg_or_short_operand (lo2, SImode))
1474 lo2 = force_reg (SImode, lo2);
1475 if (!adde_operand (hi2, SImode))
1476 hi2 = force_reg (SImode, hi2);
1477
1478 emit_insn (gen_addsi3_carry (lo0, lo1, lo2));
1479 emit_insn (gen_addsi3_carry_in (hi0, hi1, hi2));
1480 DONE;
1481 }
1482
1483 if (CONST_INT_P (operands[2]) && !add_operand (operands[2], <MODE>mode))
1484 {
1485 rtx tmp = ((!can_create_pseudo_p ()
1486 || rtx_equal_p (operands[0], operands[1]))
1487 ? operands[0] : gen_reg_rtx (<MODE>mode));
1488
1489 HOST_WIDE_INT val = INTVAL (operands[2]);
1490 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1491 HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1492
1493 if (<MODE>mode == DImode && !satisfies_constraint_L (GEN_INT (rest)))
1494 FAIL;
1495
1496 /* The ordering here is important for the prolog expander.
1497 When space is allocated from the stack, adding 'low' first may
1498 produce a temporary deallocation (which would be bad). */
1499 emit_insn (gen_add<mode>3 (tmp, operands[1], GEN_INT (rest)));
1500 emit_insn (gen_add<mode>3 (operands[0], tmp, GEN_INT (low)));
1501 DONE;
1502 }
1503 })
1504
1505 (define_insn "*add<mode>3"
1506 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r,r")
1507 (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b,b")
1508 (match_operand:GPR 2 "add_operand" "r,I,L")))]
1509 ""
1510 "@
1511 add %0,%1,%2
1512 addi %0,%1,%2
1513 addis %0,%1,%v2"
1514 [(set_attr "type" "add")])
1515
1516 (define_insn "addsi3_high"
1517 [(set (match_operand:SI 0 "gpc_reg_operand" "=b")
1518 (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
1519 (high:SI (match_operand 2 "" ""))))]
1520 "TARGET_MACHO && !TARGET_64BIT"
1521 "addis %0,%1,ha16(%2)"
1522 [(set_attr "type" "add")])
1523
1524 (define_insn_and_split "*add<mode>3_dot"
1525 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1526 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
1527 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
1528 (const_int 0)))
1529 (clobber (match_scratch:GPR 0 "=r,r"))]
1530 "<MODE>mode == Pmode"
1531 "@
1532 add. %0,%1,%2
1533 #"
1534 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1535 [(set (match_dup 0)
1536 (plus:GPR (match_dup 1)
1537 (match_dup 2)))
1538 (set (match_dup 3)
1539 (compare:CC (match_dup 0)
1540 (const_int 0)))]
1541 ""
1542 [(set_attr "type" "add")
1543 (set_attr "dot" "yes")
1544 (set_attr "length" "4,8")])
1545
1546 (define_insn_and_split "*add<mode>3_dot2"
1547 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1548 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
1549 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
1550 (const_int 0)))
1551 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1552 (plus:GPR (match_dup 1)
1553 (match_dup 2)))]
1554 "<MODE>mode == Pmode"
1555 "@
1556 add. %0,%1,%2
1557 #"
1558 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1559 [(set (match_dup 0)
1560 (plus:GPR (match_dup 1)
1561 (match_dup 2)))
1562 (set (match_dup 3)
1563 (compare:CC (match_dup 0)
1564 (const_int 0)))]
1565 ""
1566 [(set_attr "type" "add")
1567 (set_attr "dot" "yes")
1568 (set_attr "length" "4,8")])
1569
1570 (define_insn_and_split "*add<mode>3_imm_dot"
1571 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1572 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b")
1573 (match_operand:GPR 2 "short_cint_operand" "I,I"))
1574 (const_int 0)))
1575 (clobber (match_scratch:GPR 0 "=r,r"))
1576 (clobber (reg:GPR CA_REGNO))]
1577 "<MODE>mode == Pmode"
1578 "@
1579 addic. %0,%1,%2
1580 #"
1581 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1582 [(set (match_dup 0)
1583 (plus:GPR (match_dup 1)
1584 (match_dup 2)))
1585 (set (match_dup 3)
1586 (compare:CC (match_dup 0)
1587 (const_int 0)))]
1588 ""
1589 [(set_attr "type" "add")
1590 (set_attr "dot" "yes")
1591 (set_attr "length" "4,8")])
1592
1593 (define_insn_and_split "*add<mode>3_imm_dot2"
1594 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1595 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b")
1596 (match_operand:GPR 2 "short_cint_operand" "I,I"))
1597 (const_int 0)))
1598 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1599 (plus:GPR (match_dup 1)
1600 (match_dup 2)))
1601 (clobber (reg:GPR CA_REGNO))]
1602 "<MODE>mode == Pmode"
1603 "@
1604 addic. %0,%1,%2
1605 #"
1606 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1607 [(set (match_dup 0)
1608 (plus:GPR (match_dup 1)
1609 (match_dup 2)))
1610 (set (match_dup 3)
1611 (compare:CC (match_dup 0)
1612 (const_int 0)))]
1613 ""
1614 [(set_attr "type" "add")
1615 (set_attr "dot" "yes")
1616 (set_attr "length" "4,8")])
1617
1618 ;; Split an add that we can't do in one insn into two insns, each of which
1619 ;; does one 16-bit part. This is used by combine. Note that the low-order
1620 ;; add should be last in case the result gets used in an address.
1621
1622 (define_split
1623 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
1624 (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
1625 (match_operand:GPR 2 "non_add_cint_operand" "")))]
1626 ""
1627 [(set (match_dup 0) (plus:GPR (match_dup 1) (match_dup 3)))
1628 (set (match_dup 0) (plus:GPR (match_dup 0) (match_dup 4)))]
1629 {
1630 HOST_WIDE_INT val = INTVAL (operands[2]);
1631 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1632 HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1633
1634 operands[4] = GEN_INT (low);
1635 if (<MODE>mode == SImode || satisfies_constraint_L (GEN_INT (rest)))
1636 operands[3] = GEN_INT (rest);
1637 else if (can_create_pseudo_p ())
1638 {
1639 operands[3] = gen_reg_rtx (DImode);
1640 emit_move_insn (operands[3], operands[2]);
1641 emit_insn (gen_adddi3 (operands[0], operands[1], operands[3]));
1642 DONE;
1643 }
1644 else
1645 FAIL;
1646 })
1647
1648
1649 (define_insn "add<mode>3_carry"
1650 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1651 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1652 (match_operand:P 2 "reg_or_short_operand" "rI")))
1653 (set (reg:P CA_REGNO)
1654 (ltu:P (plus:P (match_dup 1)
1655 (match_dup 2))
1656 (match_dup 1)))]
1657 ""
1658 "add%I2c %0,%1,%2"
1659 [(set_attr "type" "add")])
1660
1661 (define_insn "*add<mode>3_imm_carry_pos"
1662 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1663 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1664 (match_operand:P 2 "short_cint_operand" "n")))
1665 (set (reg:P CA_REGNO)
1666 (geu:P (match_dup 1)
1667 (match_operand:P 3 "const_int_operand" "n")))]
1668 "INTVAL (operands[2]) > 0
1669 && INTVAL (operands[2]) + INTVAL (operands[3]) == 0"
1670 "addic %0,%1,%2"
1671 [(set_attr "type" "add")])
1672
1673 (define_insn "*add<mode>3_imm_carry_0"
1674 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1675 (match_operand:P 1 "gpc_reg_operand" "r"))
1676 (set (reg:P CA_REGNO)
1677 (const_int 0))]
1678 ""
1679 "addic %0,%1,0"
1680 [(set_attr "type" "add")])
1681
1682 (define_insn "*add<mode>3_imm_carry_m1"
1683 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1684 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1685 (const_int -1)))
1686 (set (reg:P CA_REGNO)
1687 (ne:P (match_dup 1)
1688 (const_int 0)))]
1689 ""
1690 "addic %0,%1,-1"
1691 [(set_attr "type" "add")])
1692
1693 (define_insn "*add<mode>3_imm_carry_neg"
1694 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1695 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1696 (match_operand:P 2 "short_cint_operand" "n")))
1697 (set (reg:P CA_REGNO)
1698 (gtu:P (match_dup 1)
1699 (match_operand:P 3 "const_int_operand" "n")))]
1700 "INTVAL (operands[2]) < 0
1701 && INTVAL (operands[2]) + INTVAL (operands[3]) == -1"
1702 "addic %0,%1,%2"
1703 [(set_attr "type" "add")])
1704
1705
1706 (define_expand "add<mode>3_carry_in"
1707 [(parallel [
1708 (set (match_operand:GPR 0 "gpc_reg_operand")
1709 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand")
1710 (match_operand:GPR 2 "adde_operand"))
1711 (reg:GPR CA_REGNO)))
1712 (clobber (reg:GPR CA_REGNO))])]
1713 ""
1714 {
1715 if (operands[2] == const0_rtx)
1716 {
1717 emit_insn (gen_add<mode>3_carry_in_0 (operands[0], operands[1]));
1718 DONE;
1719 }
1720 if (operands[2] == constm1_rtx)
1721 {
1722 emit_insn (gen_add<mode>3_carry_in_m1 (operands[0], operands[1]));
1723 DONE;
1724 }
1725 })
1726
1727 (define_insn "*add<mode>3_carry_in_internal"
1728 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1729 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1730 (match_operand:GPR 2 "gpc_reg_operand" "r"))
1731 (reg:GPR CA_REGNO)))
1732 (clobber (reg:GPR CA_REGNO))]
1733 ""
1734 "adde %0,%1,%2"
1735 [(set_attr "type" "add")])
1736
1737 (define_insn "add<mode>3_carry_in_0"
1738 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1739 (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1740 (reg:GPR CA_REGNO)))
1741 (clobber (reg:GPR CA_REGNO))]
1742 ""
1743 "addze %0,%1"
1744 [(set_attr "type" "add")])
1745
1746 (define_insn "add<mode>3_carry_in_m1"
1747 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1748 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1749 (reg:GPR CA_REGNO))
1750 (const_int -1)))
1751 (clobber (reg:GPR CA_REGNO))]
1752 ""
1753 "addme %0,%1"
1754 [(set_attr "type" "add")])
1755
1756
1757 (define_expand "one_cmpl<mode>2"
1758 [(set (match_operand:SDI 0 "gpc_reg_operand" "")
1759 (not:SDI (match_operand:SDI 1 "gpc_reg_operand" "")))]
1760 ""
1761 {
1762 if (<MODE>mode == DImode && !TARGET_POWERPC64)
1763 {
1764 rs6000_split_logical (operands, NOT, false, false, false);
1765 DONE;
1766 }
1767 })
1768
1769 (define_insn "*one_cmpl<mode>2"
1770 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1771 (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
1772 ""
1773 "not %0,%1")
1774
1775 (define_insn_and_split "*one_cmpl<mode>2_dot"
1776 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1777 (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
1778 (const_int 0)))
1779 (clobber (match_scratch:GPR 0 "=r,r"))]
1780 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
1781 "@
1782 not. %0,%1
1783 #"
1784 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1785 [(set (match_dup 0)
1786 (not:GPR (match_dup 1)))
1787 (set (match_dup 2)
1788 (compare:CC (match_dup 0)
1789 (const_int 0)))]
1790 ""
1791 [(set_attr "type" "logical")
1792 (set_attr "dot" "yes")
1793 (set_attr "length" "4,8")])
1794
1795 (define_insn_and_split "*one_cmpl<mode>2_dot2"
1796 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1797 (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
1798 (const_int 0)))
1799 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1800 (not:GPR (match_dup 1)))]
1801 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
1802 "@
1803 not. %0,%1
1804 #"
1805 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1806 [(set (match_dup 0)
1807 (not:GPR (match_dup 1)))
1808 (set (match_dup 2)
1809 (compare:CC (match_dup 0)
1810 (const_int 0)))]
1811 ""
1812 [(set_attr "type" "logical")
1813 (set_attr "dot" "yes")
1814 (set_attr "length" "4,8")])
1815
1816
1817 (define_expand "sub<mode>3"
1818 [(set (match_operand:SDI 0 "gpc_reg_operand" "")
1819 (minus:SDI (match_operand:SDI 1 "reg_or_short_operand" "")
1820 (match_operand:SDI 2 "gpc_reg_operand" "")))]
1821 ""
1822 {
1823 if (<MODE>mode == DImode && !TARGET_POWERPC64)
1824 {
1825 rtx lo0 = gen_lowpart (SImode, operands[0]);
1826 rtx lo1 = gen_lowpart (SImode, operands[1]);
1827 rtx lo2 = gen_lowpart (SImode, operands[2]);
1828 rtx hi0 = gen_highpart (SImode, operands[0]);
1829 rtx hi1 = gen_highpart_mode (SImode, DImode, operands[1]);
1830 rtx hi2 = gen_highpart (SImode, operands[2]);
1831
1832 if (!reg_or_short_operand (lo1, SImode))
1833 lo1 = force_reg (SImode, lo1);
1834 if (!adde_operand (hi1, SImode))
1835 hi1 = force_reg (SImode, hi1);
1836
1837 emit_insn (gen_subfsi3_carry (lo0, lo2, lo1));
1838 emit_insn (gen_subfsi3_carry_in (hi0, hi2, hi1));
1839 DONE;
1840 }
1841
1842 if (short_cint_operand (operands[1], <MODE>mode))
1843 {
1844 emit_insn (gen_subf<mode>3_imm (operands[0], operands[2], operands[1]));
1845 DONE;
1846 }
1847 })
1848
1849 (define_insn "*subf<mode>3"
1850 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1851 (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r")
1852 (match_operand:GPR 1 "gpc_reg_operand" "r")))]
1853 ""
1854 "subf %0,%1,%2"
1855 [(set_attr "type" "add")])
1856
1857 (define_insn_and_split "*subf<mode>3_dot"
1858 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1859 (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
1860 (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
1861 (const_int 0)))
1862 (clobber (match_scratch:GPR 0 "=r,r"))]
1863 "<MODE>mode == Pmode"
1864 "@
1865 subf. %0,%1,%2
1866 #"
1867 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1868 [(set (match_dup 0)
1869 (minus:GPR (match_dup 2)
1870 (match_dup 1)))
1871 (set (match_dup 3)
1872 (compare:CC (match_dup 0)
1873 (const_int 0)))]
1874 ""
1875 [(set_attr "type" "add")
1876 (set_attr "dot" "yes")
1877 (set_attr "length" "4,8")])
1878
1879 (define_insn_and_split "*subf<mode>3_dot2"
1880 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1881 (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
1882 (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
1883 (const_int 0)))
1884 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1885 (minus:GPR (match_dup 2)
1886 (match_dup 1)))]
1887 "<MODE>mode == Pmode"
1888 "@
1889 subf. %0,%1,%2
1890 #"
1891 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1892 [(set (match_dup 0)
1893 (minus:GPR (match_dup 2)
1894 (match_dup 1)))
1895 (set (match_dup 3)
1896 (compare:CC (match_dup 0)
1897 (const_int 0)))]
1898 ""
1899 [(set_attr "type" "add")
1900 (set_attr "dot" "yes")
1901 (set_attr "length" "4,8")])
1902
1903 (define_insn "subf<mode>3_imm"
1904 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1905 (minus:GPR (match_operand:GPR 2 "short_cint_operand" "I")
1906 (match_operand:GPR 1 "gpc_reg_operand" "r")))
1907 (clobber (reg:GPR CA_REGNO))]
1908 ""
1909 "subfic %0,%1,%2"
1910 [(set_attr "type" "add")])
1911
1912
1913 (define_insn "subf<mode>3_carry"
1914 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1915 (minus:P (match_operand:P 2 "reg_or_short_operand" "rI")
1916 (match_operand:P 1 "gpc_reg_operand" "r")))
1917 (set (reg:P CA_REGNO)
1918 (leu:P (match_dup 1)
1919 (match_dup 2)))]
1920 ""
1921 "subf%I2c %0,%1,%2"
1922 [(set_attr "type" "add")])
1923
1924 (define_insn "*subf<mode>3_imm_carry_0"
1925 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1926 (neg:P (match_operand:P 1 "gpc_reg_operand" "r")))
1927 (set (reg:P CA_REGNO)
1928 (eq:P (match_dup 1)
1929 (const_int 0)))]
1930 ""
1931 "subfic %0,%1,0"
1932 [(set_attr "type" "add")])
1933
1934 (define_insn "*subf<mode>3_imm_carry_m1"
1935 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1936 (not:P (match_operand:P 1 "gpc_reg_operand" "r")))
1937 (set (reg:P CA_REGNO)
1938 (const_int 1))]
1939 ""
1940 "subfic %0,%1,-1"
1941 [(set_attr "type" "add")])
1942
1943
1944 (define_expand "subf<mode>3_carry_in"
1945 [(parallel [
1946 (set (match_operand:GPR 0 "gpc_reg_operand")
1947 (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand"))
1948 (reg:GPR CA_REGNO))
1949 (match_operand:GPR 2 "adde_operand")))
1950 (clobber (reg:GPR CA_REGNO))])]
1951 ""
1952 {
1953 if (operands[2] == const0_rtx)
1954 {
1955 emit_insn (gen_subf<mode>3_carry_in_0 (operands[0], operands[1]));
1956 DONE;
1957 }
1958 if (operands[2] == constm1_rtx)
1959 {
1960 emit_insn (gen_subf<mode>3_carry_in_m1 (operands[0], operands[1]));
1961 DONE;
1962 }
1963 })
1964
1965 (define_insn "*subf<mode>3_carry_in_internal"
1966 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1967 (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
1968 (reg:GPR CA_REGNO))
1969 (match_operand:GPR 2 "gpc_reg_operand" "r")))
1970 (clobber (reg:GPR CA_REGNO))]
1971 ""
1972 "subfe %0,%1,%2"
1973 [(set_attr "type" "add")])
1974
1975 (define_insn "subf<mode>3_carry_in_0"
1976 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1977 (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
1978 (reg:GPR CA_REGNO)))
1979 (clobber (reg:GPR CA_REGNO))]
1980 ""
1981 "subfze %0,%1"
1982 [(set_attr "type" "add")])
1983
1984 (define_insn "subf<mode>3_carry_in_m1"
1985 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1986 (plus:GPR (minus:GPR (reg:GPR CA_REGNO)
1987 (match_operand:GPR 1 "gpc_reg_operand" "r"))
1988 (const_int -2)))
1989 (clobber (reg:GPR CA_REGNO))]
1990 ""
1991 "subfme %0,%1"
1992 [(set_attr "type" "add")])
1993
1994 (define_insn "subf<mode>3_carry_in_xx"
1995 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1996 (plus:GPR (reg:GPR CA_REGNO)
1997 (const_int -1)))
1998 (clobber (reg:GPR CA_REGNO))]
1999 ""
2000 "subfe %0,%0,%0"
2001 [(set_attr "type" "add")])
2002
2003
2004 (define_insn "neg<mode>2"
2005 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2006 (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2007 ""
2008 "neg %0,%1"
2009 [(set_attr "type" "add")])
2010
2011 (define_insn_and_split "*neg<mode>2_dot"
2012 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2013 (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2014 (const_int 0)))
2015 (clobber (match_scratch:GPR 0 "=r,r"))]
2016 "<MODE>mode == Pmode"
2017 "@
2018 neg. %0,%1
2019 #"
2020 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2021 [(set (match_dup 0)
2022 (neg:GPR (match_dup 1)))
2023 (set (match_dup 2)
2024 (compare:CC (match_dup 0)
2025 (const_int 0)))]
2026 ""
2027 [(set_attr "type" "add")
2028 (set_attr "dot" "yes")
2029 (set_attr "length" "4,8")])
2030
2031 (define_insn_and_split "*neg<mode>2_dot2"
2032 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2033 (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2034 (const_int 0)))
2035 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2036 (neg:GPR (match_dup 1)))]
2037 "<MODE>mode == Pmode"
2038 "@
2039 neg. %0,%1
2040 #"
2041 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2042 [(set (match_dup 0)
2043 (neg:GPR (match_dup 1)))
2044 (set (match_dup 2)
2045 (compare:CC (match_dup 0)
2046 (const_int 0)))]
2047 ""
2048 [(set_attr "type" "add")
2049 (set_attr "dot" "yes")
2050 (set_attr "length" "4,8")])
2051
2052
2053 (define_insn "clz<mode>2"
2054 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2055 (clz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2056 ""
2057 "cntlz<wd> %0,%1"
2058 [(set_attr "type" "cntlz")])
2059
2060 (define_expand "ctz<mode>2"
2061 [(set (match_dup 2)
2062 (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))
2063 (set (match_dup 3)
2064 (and:GPR (match_dup 1)
2065 (match_dup 2)))
2066 (set (match_dup 4)
2067 (clz:GPR (match_dup 3)))
2068 (parallel [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2069 (minus:GPR (match_dup 5)
2070 (match_dup 4)))
2071 (clobber (reg:GPR CA_REGNO))])]
2072 ""
2073 {
2074 operands[2] = gen_reg_rtx (<MODE>mode);
2075 operands[3] = gen_reg_rtx (<MODE>mode);
2076 operands[4] = gen_reg_rtx (<MODE>mode);
2077 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - 1);
2078 })
2079
2080 (define_expand "ffs<mode>2"
2081 [(set (match_dup 2)
2082 (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))
2083 (set (match_dup 3)
2084 (and:GPR (match_dup 1)
2085 (match_dup 2)))
2086 (set (match_dup 4)
2087 (clz:GPR (match_dup 3)))
2088 (parallel [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2089 (minus:GPR (match_dup 5)
2090 (match_dup 4)))
2091 (clobber (reg:GPR CA_REGNO))])]
2092 ""
2093 {
2094 operands[2] = gen_reg_rtx (<MODE>mode);
2095 operands[3] = gen_reg_rtx (<MODE>mode);
2096 operands[4] = gen_reg_rtx (<MODE>mode);
2097 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
2098 })
2099
2100
2101 (define_expand "popcount<mode>2"
2102 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2103 (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))]
2104 "TARGET_POPCNTB || TARGET_POPCNTD"
2105 {
2106 rs6000_emit_popcount (operands[0], operands[1]);
2107 DONE;
2108 })
2109
2110 (define_insn "popcntb<mode>2"
2111 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2112 (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")]
2113 UNSPEC_POPCNTB))]
2114 "TARGET_POPCNTB"
2115 "popcntb %0,%1"
2116 [(set_attr "type" "popcnt")])
2117
2118 (define_insn "popcntd<mode>2"
2119 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2120 (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2121 "TARGET_POPCNTD"
2122 "popcnt<wd> %0,%1"
2123 [(set_attr "type" "popcnt")])
2124
2125
2126 (define_expand "parity<mode>2"
2127 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2128 (parity:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))]
2129 "TARGET_POPCNTB"
2130 {
2131 rs6000_emit_parity (operands[0], operands[1]);
2132 DONE;
2133 })
2134
2135 (define_insn "parity<mode>2_cmpb"
2136 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2137 (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")] UNSPEC_PARITY))]
2138 "TARGET_CMPB && TARGET_POPCNTB"
2139 "prty<wd> %0,%1"
2140 [(set_attr "type" "popcnt")])
2141
2142
2143 ;; Since the hardware zeros the upper part of the register, save generating the
2144 ;; AND immediate if we are converting to unsigned
2145 (define_insn "*bswaphi2_extenddi"
2146 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2147 (zero_extend:DI
2148 (bswap:HI (match_operand:HI 1 "memory_operand" "Z"))))]
2149 "TARGET_POWERPC64"
2150 "lhbrx %0,%y1"
2151 [(set_attr "length" "4")
2152 (set_attr "type" "load")])
2153
2154 (define_insn "*bswaphi2_extendsi"
2155 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2156 (zero_extend:SI
2157 (bswap:HI (match_operand:HI 1 "memory_operand" "Z"))))]
2158 ""
2159 "lhbrx %0,%y1"
2160 [(set_attr "length" "4")
2161 (set_attr "type" "load")])
2162
2163 (define_expand "bswaphi2"
2164 [(parallel [(set (match_operand:HI 0 "reg_or_mem_operand" "")
2165 (bswap:HI
2166 (match_operand:HI 1 "reg_or_mem_operand" "")))
2167 (clobber (match_scratch:SI 2 ""))])]
2168 ""
2169 {
2170 if (!REG_P (operands[0]) && !REG_P (operands[1]))
2171 operands[1] = force_reg (HImode, operands[1]);
2172 })
2173
2174 (define_insn "bswaphi2_internal"
2175 [(set (match_operand:HI 0 "reg_or_mem_operand" "=r,Z,&r")
2176 (bswap:HI
2177 (match_operand:HI 1 "reg_or_mem_operand" "Z,r,r")))
2178 (clobber (match_scratch:SI 2 "=X,X,&r"))]
2179 ""
2180 "@
2181 lhbrx %0,%y1
2182 sthbrx %1,%y0
2183 #"
2184 [(set_attr "length" "4,4,12")
2185 (set_attr "type" "load,store,*")])
2186
2187 ;; We are always BITS_BIG_ENDIAN, so the (const_int 16) below is
2188 ;; correct for -mlittle as well as -mbig.
2189 (define_split
2190 [(set (match_operand:HI 0 "gpc_reg_operand" "")
2191 (bswap:HI (match_operand:HI 1 "gpc_reg_operand" "")))
2192 (clobber (match_operand:SI 2 "gpc_reg_operand" ""))]
2193 "reload_completed"
2194 [(set (match_dup 3)
2195 (zero_extract:SI (match_dup 4)
2196 (const_int 8)
2197 (const_int 16)))
2198 (set (match_dup 2)
2199 (and:SI (ashift:SI (match_dup 4)
2200 (const_int 8))
2201 (const_int 65280))) ;; 0xff00
2202 (set (match_dup 3)
2203 (ior:SI (match_dup 3)
2204 (match_dup 2)))]
2205 "
2206 {
2207 operands[3] = simplify_gen_subreg (SImode, operands[0], HImode, 0);
2208 operands[4] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
2209 }")
2210
2211 (define_insn "*bswapsi2_extenddi"
2212 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2213 (zero_extend:DI
2214 (bswap:SI (match_operand:SI 1 "memory_operand" "Z"))))]
2215 "TARGET_POWERPC64"
2216 "lwbrx %0,%y1"
2217 [(set_attr "length" "4")
2218 (set_attr "type" "load")])
2219
2220 (define_expand "bswapsi2"
2221 [(set (match_operand:SI 0 "reg_or_mem_operand" "")
2222 (bswap:SI
2223 (match_operand:SI 1 "reg_or_mem_operand" "")))]
2224 ""
2225 {
2226 if (!REG_P (operands[0]) && !REG_P (operands[1]))
2227 operands[1] = force_reg (SImode, operands[1]);
2228 })
2229
2230 (define_insn "*bswapsi2_internal"
2231 [(set (match_operand:SI 0 "reg_or_mem_operand" "=r,Z,&r")
2232 (bswap:SI
2233 (match_operand:SI 1 "reg_or_mem_operand" "Z,r,r")))]
2234 ""
2235 "@
2236 lwbrx %0,%y1
2237 stwbrx %1,%y0
2238 #"
2239 [(set_attr "length" "4,4,12")
2240 (set_attr "type" "load,store,*")])
2241
2242 ;; We are always BITS_BIG_ENDIAN, so the bit positions below in
2243 ;; zero_extract insns do not change for -mlittle.
2244 (define_split
2245 [(set (match_operand:SI 0 "gpc_reg_operand" "")
2246 (bswap:SI (match_operand:SI 1 "gpc_reg_operand" "")))]
2247 "reload_completed"
2248 [(set (match_dup 0)
2249 (rotate:SI (match_dup 1) (const_int 8)))
2250 (set (zero_extract:SI (match_dup 0)
2251 (const_int 8)
2252 (const_int 0))
2253 (match_dup 1))
2254 (set (zero_extract:SI (match_dup 0)
2255 (const_int 8)
2256 (const_int 16))
2257 (rotate:SI (match_dup 1)
2258 (const_int 16)))]
2259 "")
2260
2261 (define_expand "bswapdi2"
2262 [(parallel [(set (match_operand:DI 0 "reg_or_mem_operand" "")
2263 (bswap:DI
2264 (match_operand:DI 1 "reg_or_mem_operand" "")))
2265 (clobber (match_scratch:DI 2 ""))
2266 (clobber (match_scratch:DI 3 ""))
2267 (clobber (match_scratch:DI 4 ""))])]
2268 ""
2269 {
2270 if (!REG_P (operands[0]) && !REG_P (operands[1]))
2271 operands[1] = force_reg (DImode, operands[1]);
2272
2273 if (!TARGET_POWERPC64)
2274 {
2275 /* 32-bit mode needs fewer scratch registers, but 32-bit addressing mode
2276 that uses 64-bit registers needs the same scratch registers as 64-bit
2277 mode. */
2278 emit_insn (gen_bswapdi2_32bit (operands[0], operands[1]));
2279 DONE;
2280 }
2281 })
2282
2283 ;; Power7/cell has ldbrx/stdbrx, so use it directly
2284 (define_insn "*bswapdi2_ldbrx"
2285 [(set (match_operand:DI 0 "reg_or_mem_operand" "=&r,Z,??&r")
2286 (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2287 (clobber (match_scratch:DI 2 "=X,X,&r"))
2288 (clobber (match_scratch:DI 3 "=X,X,&r"))
2289 (clobber (match_scratch:DI 4 "=X,X,&r"))]
2290 "TARGET_POWERPC64 && TARGET_LDBRX
2291 && (REG_P (operands[0]) || REG_P (operands[1]))"
2292 "@
2293 ldbrx %0,%y1
2294 stdbrx %1,%y0
2295 #"
2296 [(set_attr "length" "4,4,36")
2297 (set_attr "type" "load,store,*")])
2298
2299 ;; Non-power7/cell, fall back to use lwbrx/stwbrx
2300 (define_insn "*bswapdi2_64bit"
2301 [(set (match_operand:DI 0 "reg_or_mem_operand" "=&r,Z,&r")
2302 (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2303 (clobber (match_scratch:DI 2 "=&b,&b,&r"))
2304 (clobber (match_scratch:DI 3 "=&r,&r,&r"))
2305 (clobber (match_scratch:DI 4 "=&r,X,&r"))]
2306 "TARGET_POWERPC64 && !TARGET_LDBRX
2307 && (REG_P (operands[0]) || REG_P (operands[1]))
2308 && !(MEM_P (operands[0]) && MEM_VOLATILE_P (operands[0]))
2309 && !(MEM_P (operands[1]) && MEM_VOLATILE_P (operands[1]))"
2310 "#"
2311 [(set_attr "length" "16,12,36")])
2312
2313 (define_split
2314 [(set (match_operand:DI 0 "gpc_reg_operand" "")
2315 (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand" "")))
2316 (clobber (match_operand:DI 2 "gpc_reg_operand" ""))
2317 (clobber (match_operand:DI 3 "gpc_reg_operand" ""))
2318 (clobber (match_operand:DI 4 "gpc_reg_operand" ""))]
2319 "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2320 [(const_int 0)]
2321 "
2322 {
2323 rtx dest = operands[0];
2324 rtx src = operands[1];
2325 rtx op2 = operands[2];
2326 rtx op3 = operands[3];
2327 rtx op4 = operands[4];
2328 rtx op3_32 = simplify_gen_subreg (SImode, op3, DImode,
2329 BYTES_BIG_ENDIAN ? 4 : 0);
2330 rtx op4_32 = simplify_gen_subreg (SImode, op4, DImode,
2331 BYTES_BIG_ENDIAN ? 4 : 0);
2332 rtx addr1;
2333 rtx addr2;
2334 rtx word_high;
2335 rtx word_low;
2336
2337 addr1 = XEXP (src, 0);
2338 if (GET_CODE (addr1) == PLUS)
2339 {
2340 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2341 if (TARGET_AVOID_XFORM)
2342 {
2343 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2344 addr2 = op2;
2345 }
2346 else
2347 addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2348 }
2349 else if (TARGET_AVOID_XFORM)
2350 {
2351 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2352 addr2 = op2;
2353 }
2354 else
2355 {
2356 emit_move_insn (op2, GEN_INT (4));
2357 addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2358 }
2359
2360 if (BYTES_BIG_ENDIAN)
2361 {
2362 word_high = change_address (src, SImode, addr1);
2363 word_low = change_address (src, SImode, addr2);
2364 }
2365 else
2366 {
2367 word_high = change_address (src, SImode, addr2);
2368 word_low = change_address (src, SImode, addr1);
2369 }
2370
2371 emit_insn (gen_bswapsi2 (op3_32, word_low));
2372 emit_insn (gen_bswapsi2 (op4_32, word_high));
2373 emit_insn (gen_ashldi3 (dest, op3, GEN_INT (32)));
2374 emit_insn (gen_iordi3 (dest, dest, op4));
2375 DONE;
2376 }")
2377
2378 (define_split
2379 [(set (match_operand:DI 0 "indexed_or_indirect_operand" "")
2380 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2381 (clobber (match_operand:DI 2 "gpc_reg_operand" ""))
2382 (clobber (match_operand:DI 3 "gpc_reg_operand" ""))
2383 (clobber (match_operand:DI 4 "" ""))]
2384 "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2385 [(const_int 0)]
2386 "
2387 {
2388 rtx dest = operands[0];
2389 rtx src = operands[1];
2390 rtx op2 = operands[2];
2391 rtx op3 = operands[3];
2392 rtx src_si = simplify_gen_subreg (SImode, src, DImode,
2393 BYTES_BIG_ENDIAN ? 4 : 0);
2394 rtx op3_si = simplify_gen_subreg (SImode, op3, DImode,
2395 BYTES_BIG_ENDIAN ? 4 : 0);
2396 rtx addr1;
2397 rtx addr2;
2398 rtx word_high;
2399 rtx word_low;
2400
2401 addr1 = XEXP (dest, 0);
2402 if (GET_CODE (addr1) == PLUS)
2403 {
2404 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2405 if (TARGET_AVOID_XFORM)
2406 {
2407 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2408 addr2 = op2;
2409 }
2410 else
2411 addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2412 }
2413 else if (TARGET_AVOID_XFORM)
2414 {
2415 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2416 addr2 = op2;
2417 }
2418 else
2419 {
2420 emit_move_insn (op2, GEN_INT (4));
2421 addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2422 }
2423
2424 emit_insn (gen_lshrdi3 (op3, src, GEN_INT (32)));
2425 if (BYTES_BIG_ENDIAN)
2426 {
2427 word_high = change_address (dest, SImode, addr1);
2428 word_low = change_address (dest, SImode, addr2);
2429 }
2430 else
2431 {
2432 word_high = change_address (dest, SImode, addr2);
2433 word_low = change_address (dest, SImode, addr1);
2434 }
2435 emit_insn (gen_bswapsi2 (word_high, src_si));
2436 emit_insn (gen_bswapsi2 (word_low, op3_si));
2437 DONE;
2438 }")
2439
2440 (define_split
2441 [(set (match_operand:DI 0 "gpc_reg_operand" "")
2442 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2443 (clobber (match_operand:DI 2 "gpc_reg_operand" ""))
2444 (clobber (match_operand:DI 3 "gpc_reg_operand" ""))
2445 (clobber (match_operand:DI 4 "" ""))]
2446 "TARGET_POWERPC64 && reload_completed"
2447 [(const_int 0)]
2448 "
2449 {
2450 rtx dest = operands[0];
2451 rtx src = operands[1];
2452 rtx op2 = operands[2];
2453 rtx op3 = operands[3];
2454 int lo_off = BYTES_BIG_ENDIAN ? 4 : 0;
2455 rtx dest_si = simplify_gen_subreg (SImode, dest, DImode, lo_off);
2456 rtx src_si = simplify_gen_subreg (SImode, src, DImode, lo_off);
2457 rtx op2_si = simplify_gen_subreg (SImode, op2, DImode, lo_off);
2458 rtx op3_si = simplify_gen_subreg (SImode, op3, DImode, lo_off);
2459
2460 emit_insn (gen_lshrdi3 (op2, src, GEN_INT (32)));
2461 emit_insn (gen_bswapsi2 (dest_si, src_si));
2462 emit_insn (gen_bswapsi2 (op3_si, op2_si));
2463 emit_insn (gen_ashldi3 (dest, dest, GEN_INT (32)));
2464 emit_insn (gen_iordi3 (dest, dest, op3));
2465 DONE;
2466 }")
2467
2468 (define_insn "bswapdi2_32bit"
2469 [(set (match_operand:DI 0 "reg_or_mem_operand" "=&r,Z,&r")
2470 (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2471 (clobber (match_scratch:SI 2 "=&b,&b,X"))]
2472 "!TARGET_POWERPC64 && (REG_P (operands[0]) || REG_P (operands[1]))"
2473 "#"
2474 [(set_attr "length" "16,12,36")])
2475
2476 (define_split
2477 [(set (match_operand:DI 0 "gpc_reg_operand" "")
2478 (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand" "")))
2479 (clobber (match_operand:SI 2 "gpc_reg_operand" ""))]
2480 "!TARGET_POWERPC64 && reload_completed"
2481 [(const_int 0)]
2482 "
2483 {
2484 rtx dest = operands[0];
2485 rtx src = operands[1];
2486 rtx op2 = operands[2];
2487 rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
2488 rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
2489 rtx addr1;
2490 rtx addr2;
2491 rtx word1;
2492 rtx word2;
2493
2494 addr1 = XEXP (src, 0);
2495 if (GET_CODE (addr1) == PLUS)
2496 {
2497 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2498 if (TARGET_AVOID_XFORM)
2499 {
2500 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2501 addr2 = op2;
2502 }
2503 else
2504 addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
2505 }
2506 else if (TARGET_AVOID_XFORM)
2507 {
2508 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2509 addr2 = op2;
2510 }
2511 else
2512 {
2513 emit_move_insn (op2, GEN_INT (4));
2514 addr2 = gen_rtx_PLUS (SImode, op2, addr1);
2515 }
2516
2517 word1 = change_address (src, SImode, addr1);
2518 word2 = change_address (src, SImode, addr2);
2519
2520 emit_insn (gen_bswapsi2 (dest2, word1));
2521 emit_insn (gen_bswapsi2 (dest1, word2));
2522 DONE;
2523 }")
2524
2525 (define_split
2526 [(set (match_operand:DI 0 "indexed_or_indirect_operand" "")
2527 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2528 (clobber (match_operand:SI 2 "gpc_reg_operand" ""))]
2529 "!TARGET_POWERPC64 && reload_completed"
2530 [(const_int 0)]
2531 "
2532 {
2533 rtx dest = operands[0];
2534 rtx src = operands[1];
2535 rtx op2 = operands[2];
2536 rtx src1 = simplify_gen_subreg (SImode, src, DImode, 0);
2537 rtx src2 = simplify_gen_subreg (SImode, src, DImode, 4);
2538 rtx addr1;
2539 rtx addr2;
2540 rtx word1;
2541 rtx word2;
2542
2543 addr1 = XEXP (dest, 0);
2544 if (GET_CODE (addr1) == PLUS)
2545 {
2546 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2547 if (TARGET_AVOID_XFORM)
2548 {
2549 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2550 addr2 = op2;
2551 }
2552 else
2553 addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
2554 }
2555 else if (TARGET_AVOID_XFORM)
2556 {
2557 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2558 addr2 = op2;
2559 }
2560 else
2561 {
2562 emit_move_insn (op2, GEN_INT (4));
2563 addr2 = gen_rtx_PLUS (SImode, op2, addr1);
2564 }
2565
2566 word1 = change_address (dest, SImode, addr1);
2567 word2 = change_address (dest, SImode, addr2);
2568
2569 emit_insn (gen_bswapsi2 (word2, src1));
2570 emit_insn (gen_bswapsi2 (word1, src2));
2571 DONE;
2572 }")
2573
2574 (define_split
2575 [(set (match_operand:DI 0 "gpc_reg_operand" "")
2576 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2577 (clobber (match_operand:SI 2 "" ""))]
2578 "!TARGET_POWERPC64 && reload_completed"
2579 [(const_int 0)]
2580 "
2581 {
2582 rtx dest = operands[0];
2583 rtx src = operands[1];
2584 rtx src1 = simplify_gen_subreg (SImode, src, DImode, 0);
2585 rtx src2 = simplify_gen_subreg (SImode, src, DImode, 4);
2586 rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
2587 rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
2588
2589 emit_insn (gen_bswapsi2 (dest1, src2));
2590 emit_insn (gen_bswapsi2 (dest2, src1));
2591 DONE;
2592 }")
2593
2594
2595 (define_insn "mul<mode>3"
2596 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2597 (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
2598 (match_operand:GPR 2 "reg_or_short_operand" "r,I")))]
2599 ""
2600 "@
2601 mull<wd> %0,%1,%2
2602 mulli %0,%1,%2"
2603 [(set_attr "type" "mul")
2604 (set (attr "size")
2605 (cond [(match_operand:GPR 2 "s8bit_cint_operand" "")
2606 (const_string "8")
2607 (match_operand:GPR 2 "short_cint_operand" "")
2608 (const_string "16")]
2609 (const_string "<bits>")))])
2610
2611 (define_insn_and_split "*mul<mode>3_dot"
2612 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2613 (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2614 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
2615 (const_int 0)))
2616 (clobber (match_scratch:GPR 0 "=r,r"))]
2617 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
2618 "@
2619 mull<wd>. %0,%1,%2
2620 #"
2621 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2622 [(set (match_dup 0)
2623 (mult:GPR (match_dup 1)
2624 (match_dup 2)))
2625 (set (match_dup 3)
2626 (compare:CC (match_dup 0)
2627 (const_int 0)))]
2628 ""
2629 [(set_attr "type" "mul")
2630 (set_attr "size" "<bits>")
2631 (set_attr "dot" "yes")
2632 (set_attr "length" "4,8")])
2633
2634 (define_insn_and_split "*mul<mode>3_dot2"
2635 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2636 (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2637 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
2638 (const_int 0)))
2639 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2640 (mult:GPR (match_dup 1)
2641 (match_dup 2)))]
2642 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
2643 "@
2644 mull<wd>. %0,%1,%2
2645 #"
2646 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2647 [(set (match_dup 0)
2648 (mult:GPR (match_dup 1)
2649 (match_dup 2)))
2650 (set (match_dup 3)
2651 (compare:CC (match_dup 0)
2652 (const_int 0)))]
2653 ""
2654 [(set_attr "type" "mul")
2655 (set_attr "size" "<bits>")
2656 (set_attr "dot" "yes")
2657 (set_attr "length" "4,8")])
2658
2659
2660 (define_expand "<su>mul<mode>3_highpart"
2661 [(set (match_operand:GPR 0 "gpc_reg_operand")
2662 (subreg:GPR
2663 (mult:<DMODE> (any_extend:<DMODE>
2664 (match_operand:GPR 1 "gpc_reg_operand"))
2665 (any_extend:<DMODE>
2666 (match_operand:GPR 2 "gpc_reg_operand")))
2667 0))]
2668 ""
2669 {
2670 if (<MODE>mode == SImode && TARGET_POWERPC64)
2671 {
2672 emit_insn (gen_<su>mulsi3_highpart_64 (operands[0], operands[1],
2673 operands[2]));
2674 DONE;
2675 }
2676
2677 if (!WORDS_BIG_ENDIAN)
2678 {
2679 emit_insn (gen_<su>mul<mode>3_highpart_le (operands[0], operands[1],
2680 operands[2]));
2681 DONE;
2682 }
2683 })
2684
2685 (define_insn "*<su>mul<mode>3_highpart"
2686 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2687 (subreg:GPR
2688 (mult:<DMODE> (any_extend:<DMODE>
2689 (match_operand:GPR 1 "gpc_reg_operand" "r"))
2690 (any_extend:<DMODE>
2691 (match_operand:GPR 2 "gpc_reg_operand" "r")))
2692 0))]
2693 "WORDS_BIG_ENDIAN && !(<MODE>mode == SImode && TARGET_POWERPC64)"
2694 "mulh<wd><u> %0,%1,%2"
2695 [(set_attr "type" "mul")
2696 (set_attr "size" "<bits>")])
2697
2698 (define_insn "<su>mulsi3_highpart_le"
2699 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2700 (subreg:SI
2701 (mult:DI (any_extend:DI
2702 (match_operand:SI 1 "gpc_reg_operand" "r"))
2703 (any_extend:DI
2704 (match_operand:SI 2 "gpc_reg_operand" "r")))
2705 4))]
2706 "!WORDS_BIG_ENDIAN && !TARGET_POWERPC64"
2707 "mulhw<u> %0,%1,%2"
2708 [(set_attr "type" "mul")])
2709
2710 (define_insn "<su>muldi3_highpart_le"
2711 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2712 (subreg:DI
2713 (mult:TI (any_extend:TI
2714 (match_operand:DI 1 "gpc_reg_operand" "r"))
2715 (any_extend:TI
2716 (match_operand:DI 2 "gpc_reg_operand" "r")))
2717 8))]
2718 "!WORDS_BIG_ENDIAN && TARGET_POWERPC64"
2719 "mulhd<u> %0,%1,%2"
2720 [(set_attr "type" "mul")
2721 (set_attr "size" "64")])
2722
2723 (define_insn "<su>mulsi3_highpart_64"
2724 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2725 (truncate:SI
2726 (lshiftrt:DI
2727 (mult:DI (any_extend:DI
2728 (match_operand:SI 1 "gpc_reg_operand" "r"))
2729 (any_extend:DI
2730 (match_operand:SI 2 "gpc_reg_operand" "r")))
2731 (const_int 32))))]
2732 "TARGET_POWERPC64"
2733 "mulhw<u> %0,%1,%2"
2734 [(set_attr "type" "mul")])
2735
2736 (define_expand "<u>mul<mode><dmode>3"
2737 [(set (match_operand:<DMODE> 0 "gpc_reg_operand")
2738 (mult:<DMODE> (any_extend:<DMODE>
2739 (match_operand:GPR 1 "gpc_reg_operand"))
2740 (any_extend:<DMODE>
2741 (match_operand:GPR 2 "gpc_reg_operand"))))]
2742 "!(<MODE>mode == SImode && TARGET_POWERPC64)"
2743 {
2744 rtx l = gen_reg_rtx (<MODE>mode);
2745 rtx h = gen_reg_rtx (<MODE>mode);
2746 emit_insn (gen_mul<mode>3 (l, operands[1], operands[2]));
2747 emit_insn (gen_<su>mul<mode>3_highpart (h, operands[1], operands[2]));
2748 emit_move_insn (gen_lowpart (<MODE>mode, operands[0]), l);
2749 emit_move_insn (gen_highpart (<MODE>mode, operands[0]), h);
2750 DONE;
2751 })
2752
2753
2754 (define_insn "udiv<mode>3"
2755 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2756 (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
2757 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
2758 ""
2759 "div<wd>u %0,%1,%2"
2760 [(set_attr "type" "div")
2761 (set_attr "size" "<bits>")])
2762
2763
2764 ;; For powers of two we can do sra[wd]i/addze for divide and then adjust for
2765 ;; modulus. If it isn't a power of two, force operands into register and do
2766 ;; a normal divide.
2767 (define_expand "div<mode>3"
2768 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2769 (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
2770 (match_operand:GPR 2 "reg_or_cint_operand" "")))]
2771 ""
2772 {
2773 if (CONST_INT_P (operands[2])
2774 && INTVAL (operands[2]) > 0
2775 && exact_log2 (INTVAL (operands[2])) >= 0)
2776 {
2777 emit_insn (gen_div<mode>3_sra (operands[0], operands[1], operands[2]));
2778 DONE;
2779 }
2780
2781 operands[2] = force_reg (<MODE>mode, operands[2]);
2782 })
2783
2784 (define_insn "*div<mode>3"
2785 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2786 (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
2787 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
2788 ""
2789 "div<wd> %0,%1,%2"
2790 [(set_attr "type" "div")
2791 (set_attr "size" "<bits>")])
2792
2793 (define_insn "div<mode>3_sra"
2794 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2795 (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
2796 (match_operand:GPR 2 "exact_log2_cint_operand" "N")))
2797 (clobber (reg:GPR CA_REGNO))]
2798 ""
2799 "sra<wd>i %0,%1,%p2\;addze %0,%0"
2800 [(set_attr "type" "two")
2801 (set_attr "length" "8")])
2802
2803 (define_insn_and_split "*div<mode>3_sra_dot"
2804 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2805 (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2806 (match_operand:GPR 2 "exact_log2_cint_operand" "N,N"))
2807 (const_int 0)))
2808 (clobber (match_scratch:GPR 0 "=r,r"))
2809 (clobber (reg:GPR CA_REGNO))]
2810 "<MODE>mode == Pmode"
2811 "@
2812 sra<wd>i %0,%1,%p2\;addze. %0,%0
2813 #"
2814 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2815 [(parallel [(set (match_dup 0)
2816 (div:GPR (match_dup 1)
2817 (match_dup 2)))
2818 (clobber (reg:GPR CA_REGNO))])
2819 (set (match_dup 3)
2820 (compare:CC (match_dup 0)
2821 (const_int 0)))]
2822 ""
2823 [(set_attr "type" "two")
2824 (set_attr "length" "8,12")
2825 (set_attr "cell_micro" "not")])
2826
2827 (define_insn_and_split "*div<mode>3_sra_dot2"
2828 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2829 (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2830 (match_operand:GPR 2 "exact_log2_cint_operand" "N,N"))
2831 (const_int 0)))
2832 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2833 (div:GPR (match_dup 1)
2834 (match_dup 2)))
2835 (clobber (reg:GPR CA_REGNO))]
2836 "<MODE>mode == Pmode"
2837 "@
2838 sra<wd>i %0,%1,%p2\;addze. %0,%0
2839 #"
2840 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2841 [(parallel [(set (match_dup 0)
2842 (div:GPR (match_dup 1)
2843 (match_dup 2)))
2844 (clobber (reg:GPR CA_REGNO))])
2845 (set (match_dup 3)
2846 (compare:CC (match_dup 0)
2847 (const_int 0)))]
2848 ""
2849 [(set_attr "type" "two")
2850 (set_attr "length" "8,12")
2851 (set_attr "cell_micro" "not")])
2852
2853 (define_expand "mod<mode>3"
2854 [(use (match_operand:GPR 0 "gpc_reg_operand" ""))
2855 (use (match_operand:GPR 1 "gpc_reg_operand" ""))
2856 (use (match_operand:GPR 2 "reg_or_cint_operand" ""))]
2857 ""
2858 {
2859 int i;
2860 rtx temp1;
2861 rtx temp2;
2862
2863 if (GET_CODE (operands[2]) != CONST_INT
2864 || INTVAL (operands[2]) <= 0
2865 || (i = exact_log2 (INTVAL (operands[2]))) < 0)
2866 FAIL;
2867
2868 temp1 = gen_reg_rtx (<MODE>mode);
2869 temp2 = gen_reg_rtx (<MODE>mode);
2870
2871 emit_insn (gen_div<mode>3 (temp1, operands[1], operands[2]));
2872 emit_insn (gen_ashl<mode>3 (temp2, temp1, GEN_INT (i)));
2873 emit_insn (gen_sub<mode>3 (operands[0], operands[1], temp2));
2874 DONE;
2875 })
2876 \f
2877 ;; Logical instructions
2878 ;; The logical instructions are mostly combined by using match_operator,
2879 ;; but the plain AND insns are somewhat different because there is no
2880 ;; plain 'andi' (only 'andi.'), no plain 'andis', and there are all
2881 ;; those rotate-and-mask operations. Thus, the AND insns come first.
2882
2883 (define_expand "and<mode>3"
2884 [(set (match_operand:SDI 0 "gpc_reg_operand" "")
2885 (and:SDI (match_operand:SDI 1 "gpc_reg_operand" "")
2886 (match_operand:SDI 2 "reg_or_cint_operand" "")))]
2887 ""
2888 {
2889 if (<MODE>mode == DImode && !TARGET_POWERPC64)
2890 {
2891 rs6000_split_logical (operands, AND, false, false, false);
2892 DONE;
2893 }
2894
2895 if (logical_const_operand (operands[2], <MODE>mode)
2896 && !any_mask_operand (operands[2], <MODE>mode))
2897 {
2898 if (rs6000_gen_cell_microcode)
2899 {
2900 emit_insn (gen_and<mode>3_imm (operands[0], operands[1], operands[2]));
2901 DONE;
2902 }
2903 else
2904 operands[2] = force_reg (<MODE>mode, operands[2]);
2905 }
2906
2907 if ((<MODE>mode == DImode && !and64_2_operand (operands[2], <MODE>mode))
2908 || (<MODE>mode != DImode && !and_operand (operands[2], <MODE>mode)))
2909 operands[2] = force_reg (<MODE>mode, operands[2]);
2910 })
2911
2912
2913 (define_insn "and<mode>3_imm"
2914 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2915 (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
2916 (match_operand:GPR 2 "logical_const_operand" "n")))
2917 (clobber (match_scratch:CC 3 "=x"))]
2918 "rs6000_gen_cell_microcode
2919 && !any_mask_operand (operands[2], <MODE>mode)"
2920 "andi%e2. %0,%1,%u2"
2921 [(set_attr "type" "logical")
2922 (set_attr "dot" "yes")])
2923
2924 (define_insn_and_split "*and<mode>3_imm_dot"
2925 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
2926 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
2927 (match_operand:GPR 2 "logical_const_operand" "n,n"))
2928 (const_int 0)))
2929 (clobber (match_scratch:GPR 0 "=r,r"))
2930 (clobber (match_scratch:CC 4 "=X,x"))]
2931 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
2932 && rs6000_gen_cell_microcode
2933 && !any_mask_operand (operands[2], <MODE>mode)"
2934 "@
2935 andi%e2. %0,%1,%u2
2936 #"
2937 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2938 [(parallel [(set (match_dup 0)
2939 (and:GPR (match_dup 1)
2940 (match_dup 2)))
2941 (clobber (match_dup 4))])
2942 (set (match_dup 3)
2943 (compare:CC (match_dup 0)
2944 (const_int 0)))]
2945 ""
2946 [(set_attr "type" "logical")
2947 (set_attr "dot" "yes")
2948 (set_attr "length" "4,8")])
2949
2950 (define_insn_and_split "*and<mode>3_imm_dot2"
2951 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
2952 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
2953 (match_operand:GPR 2 "logical_const_operand" "n,n"))
2954 (const_int 0)))
2955 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2956 (and:GPR (match_dup 1)
2957 (match_dup 2)))
2958 (clobber (match_scratch:CC 4 "=X,x"))]
2959 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
2960 && rs6000_gen_cell_microcode
2961 && !any_mask_operand (operands[2], <MODE>mode)"
2962 "@
2963 andi%e2. %0,%1,%u2
2964 #"
2965 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2966 [(parallel [(set (match_dup 0)
2967 (and:GPR (match_dup 1)
2968 (match_dup 2)))
2969 (clobber (match_dup 4))])
2970 (set (match_dup 3)
2971 (compare:CC (match_dup 0)
2972 (const_int 0)))]
2973 ""
2974 [(set_attr "type" "logical")
2975 (set_attr "dot" "yes")
2976 (set_attr "length" "4,8")])
2977
2978 (define_insn_and_split "*and<mode>3_imm_mask_dot"
2979 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
2980 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
2981 (match_operand:GPR 2 "logical_const_operand" "n,n"))
2982 (const_int 0)))
2983 (clobber (match_scratch:GPR 0 "=r,r"))]
2984 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
2985 && rs6000_gen_cell_microcode
2986 && any_mask_operand (operands[2], <MODE>mode)"
2987 "@
2988 andi%e2. %0,%1,%u2
2989 #"
2990 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2991 [(set (match_dup 0)
2992 (and:GPR (match_dup 1)
2993 (match_dup 2)))
2994 (set (match_dup 3)
2995 (compare:CC (match_dup 0)
2996 (const_int 0)))]
2997 ""
2998 [(set_attr "type" "logical")
2999 (set_attr "dot" "yes")
3000 (set_attr "length" "4,8")])
3001
3002 (define_insn_and_split "*and<mode>3_imm_mask_dot2"
3003 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3004 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3005 (match_operand:GPR 2 "logical_const_operand" "n,n"))
3006 (const_int 0)))
3007 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3008 (and:GPR (match_dup 1)
3009 (match_dup 2)))]
3010 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3011 && rs6000_gen_cell_microcode
3012 && any_mask_operand (operands[2], <MODE>mode)"
3013 "@
3014 andi%e2. %0,%1,%u2
3015 #"
3016 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3017 [(set (match_dup 0)
3018 (and:GPR (match_dup 1)
3019 (match_dup 2)))
3020 (set (match_dup 3)
3021 (compare:CC (match_dup 0)
3022 (const_int 0)))]
3023 ""
3024 [(set_attr "type" "logical")
3025 (set_attr "dot" "yes")
3026 (set_attr "length" "4,8")])
3027
3028
3029 (define_insn "*and<mode>3_mask"
3030 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3031 (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3032 (match_operand:GPR 2 "any_mask_operand" "S,T")))]
3033 ""
3034 "@
3035 rldic%B2 %0,%1,0,%S2
3036 rlwinm %0,%1,0,%m2,%M2"
3037 [(set_attr "type" "shift")])
3038
3039 (define_insn_and_split "*and<mode>3_mask_dot"
3040 [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y")
3041 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r,r,r")
3042 (match_operand:GPR 2 "any_mask_operand" "S,T,S,T"))
3043 (const_int 0)))
3044 (clobber (match_scratch:GPR 0 "=r,r,r,r"))]
3045 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3046 && rs6000_gen_cell_microcode
3047 && !logical_const_operand (operands[2], <MODE>mode)"
3048 "@
3049 rldic%B2. %0,%1,0,%S2
3050 rlwinm. %0,%1,0,%m2,%M2
3051 #
3052 #"
3053 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3054 [(set (match_dup 0)
3055 (and:GPR (match_dup 1)
3056 (match_dup 2)))
3057 (set (match_dup 3)
3058 (compare:CC (match_dup 0)
3059 (const_int 0)))]
3060 ""
3061 [(set_attr "type" "shift")
3062 (set_attr "dot" "yes")
3063 (set_attr "length" "4,4,8,8")])
3064
3065 (define_insn_and_split "*and<mode>3_mask_dot2"
3066 [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y")
3067 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r,r,r")
3068 (match_operand:GPR 2 "any_mask_operand" "S,T,S,T"))
3069 (const_int 0)))
3070 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r,r,r")
3071 (and:GPR (match_dup 1)
3072 (match_dup 2)))]
3073 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3074 && rs6000_gen_cell_microcode
3075 && !logical_const_operand (operands[2], <MODE>mode)"
3076 "@
3077 rldic%B2. %0,%1,0,%S2
3078 rlwinm. %0,%1,0,%m2,%M2
3079 #
3080 #"
3081 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3082 [(set (match_dup 0)
3083 (and:GPR (match_dup 1)
3084 (match_dup 2)))
3085 (set (match_dup 3)
3086 (compare:CC (match_dup 0)
3087 (const_int 0)))]
3088 ""
3089 [(set_attr "type" "shift")
3090 (set_attr "dot" "yes")
3091 (set_attr "length" "4,4,8,8")])
3092
3093
3094
3095 (define_insn "andsi3_internal0_nomc"
3096 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
3097 (and:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r")
3098 (match_operand:SI 2 "and_operand" "?r,T")))]
3099 "!rs6000_gen_cell_microcode"
3100 "@
3101 and %0,%1,%2
3102 rlwinm %0,%1,0,%m2,%M2"
3103 [(set_attr "type" "logical,shift")])
3104
3105
3106 ;; Handle the PowerPC64 rlwinm corner case
3107
3108 (define_insn_and_split "*andsi3_internal6"
3109 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
3110 (and:SI (match_operand:SI 1 "gpc_reg_operand" "r")
3111 (match_operand:SI 2 "mask_operand_wrap" "i")))]
3112 "TARGET_POWERPC64"
3113 "#"
3114 "TARGET_POWERPC64"
3115 [(set (match_dup 0)
3116 (and:SI (rotate:SI (match_dup 1) (match_dup 3))
3117 (match_dup 4)))
3118 (set (match_dup 0)
3119 (rotate:SI (match_dup 0) (match_dup 5)))]
3120 "
3121 {
3122 int mb = extract_MB (operands[2]);
3123 int me = extract_ME (operands[2]);
3124 operands[3] = GEN_INT (me + 1);
3125 operands[5] = GEN_INT (32 - (me + 1));
3126 operands[4] = GEN_INT (~((HOST_WIDE_INT) -1 << (33 + me - mb)));
3127 }"
3128 [(set_attr "length" "8")])
3129
3130
3131 (define_expand "<code><mode>3"
3132 [(set (match_operand:SDI 0 "gpc_reg_operand" "")
3133 (iorxor:SDI (match_operand:SDI 1 "gpc_reg_operand" "")
3134 (match_operand:SDI 2 "reg_or_cint_operand" "")))]
3135 ""
3136 {
3137 if (<MODE>mode == DImode && !TARGET_POWERPC64)
3138 {
3139 rs6000_split_logical (operands, <CODE>, false, false, false);
3140 DONE;
3141 }
3142
3143 if (non_logical_cint_operand (operands[2], <MODE>mode))
3144 {
3145 rtx tmp = ((!can_create_pseudo_p ()
3146 || rtx_equal_p (operands[0], operands[1]))
3147 ? operands[0] : gen_reg_rtx (<MODE>mode));
3148
3149 HOST_WIDE_INT value = INTVAL (operands[2]);
3150 HOST_WIDE_INT lo = value & 0xffff;
3151 HOST_WIDE_INT hi = value - lo;
3152
3153 emit_insn (gen_<code><mode>3 (tmp, operands[1], GEN_INT (hi)));
3154 emit_insn (gen_<code><mode>3 (operands[0], tmp, GEN_INT (lo)));
3155 DONE;
3156 }
3157
3158 if (!reg_or_logical_cint_operand (operands[2], <MODE>mode))
3159 operands[2] = force_reg (<MODE>mode, operands[2]);
3160 })
3161
3162 (define_split
3163 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
3164 (iorxor:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
3165 (match_operand:GPR 2 "non_logical_cint_operand" "")))]
3166 ""
3167 [(set (match_dup 3)
3168 (iorxor:GPR (match_dup 1)
3169 (match_dup 4)))
3170 (set (match_dup 0)
3171 (iorxor:GPR (match_dup 3)
3172 (match_dup 5)))]
3173 {
3174 operands[3] = ((!can_create_pseudo_p ()
3175 || rtx_equal_p (operands[0], operands[1]))
3176 ? operands[0] : gen_reg_rtx (<MODE>mode));
3177
3178 HOST_WIDE_INT value = INTVAL (operands[2]);
3179 HOST_WIDE_INT lo = value & 0xffff;
3180 HOST_WIDE_INT hi = value - lo;
3181
3182 operands[4] = GEN_INT (hi);
3183 operands[5] = GEN_INT (lo);
3184 })
3185
3186 (define_insn "*bool<mode>3_imm"
3187 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3188 (match_operator:GPR 3 "boolean_or_operator"
3189 [(match_operand:GPR 1 "gpc_reg_operand" "%r")
3190 (match_operand:GPR 2 "logical_const_operand" "n")]))]
3191 ""
3192 "%q3i%e2 %0,%1,%u2"
3193 [(set_attr "type" "logical")])
3194
3195 (define_insn "*bool<mode>3"
3196 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3197 (match_operator:GPR 3 "boolean_operator"
3198 [(match_operand:GPR 1 "gpc_reg_operand" "r")
3199 (match_operand:GPR 2 "gpc_reg_operand" "r")]))]
3200 ""
3201 "%q3 %0,%1,%2"
3202 [(set_attr "type" "logical")])
3203
3204 (define_insn_and_split "*bool<mode>3_dot"
3205 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3206 (compare:CC (match_operator:GPR 3 "boolean_operator"
3207 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3208 (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
3209 (const_int 0)))
3210 (clobber (match_scratch:GPR 0 "=r,r"))]
3211 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3212 "@
3213 %q3. %0,%1,%2
3214 #"
3215 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3216 [(set (match_dup 0)
3217 (match_dup 3))
3218 (set (match_dup 4)
3219 (compare:CC (match_dup 0)
3220 (const_int 0)))]
3221 ""
3222 [(set_attr "type" "logical")
3223 (set_attr "dot" "yes")
3224 (set_attr "length" "4,8")])
3225
3226 (define_insn_and_split "*bool<mode>3_dot2"
3227 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3228 (compare:CC (match_operator:GPR 3 "boolean_operator"
3229 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3230 (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
3231 (const_int 0)))
3232 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3233 (match_dup 3))]
3234 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3235 "@
3236 %q3. %0,%1,%2
3237 #"
3238 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3239 [(set (match_dup 0)
3240 (match_dup 3))
3241 (set (match_dup 4)
3242 (compare:CC (match_dup 0)
3243 (const_int 0)))]
3244 ""
3245 [(set_attr "type" "logical")
3246 (set_attr "dot" "yes")
3247 (set_attr "length" "4,8")])
3248
3249
3250 (define_insn "*boolc<mode>3"
3251 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3252 (match_operator:GPR 3 "boolean_operator"
3253 [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))
3254 (match_operand:GPR 1 "gpc_reg_operand" "r")]))]
3255 ""
3256 "%q3 %0,%1,%2"
3257 [(set_attr "type" "logical")])
3258
3259 (define_insn_and_split "*boolc<mode>3_dot"
3260 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3261 (compare:CC (match_operator:GPR 3 "boolean_operator"
3262 [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3263 (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
3264 (const_int 0)))
3265 (clobber (match_scratch:GPR 0 "=r,r"))]
3266 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3267 "@
3268 %q3. %0,%1,%2
3269 #"
3270 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3271 [(set (match_dup 0)
3272 (match_dup 3))
3273 (set (match_dup 4)
3274 (compare:CC (match_dup 0)
3275 (const_int 0)))]
3276 ""
3277 [(set_attr "type" "logical")
3278 (set_attr "dot" "yes")
3279 (set_attr "length" "4,8")])
3280
3281 (define_insn_and_split "*boolc<mode>3_dot2"
3282 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3283 (compare:CC (match_operator:GPR 3 "boolean_operator"
3284 [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3285 (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
3286 (const_int 0)))
3287 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3288 (match_dup 3))]
3289 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3290 "@
3291 %q3. %0,%1,%2
3292 #"
3293 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3294 [(set (match_dup 0)
3295 (match_dup 3))
3296 (set (match_dup 4)
3297 (compare:CC (match_dup 0)
3298 (const_int 0)))]
3299 ""
3300 [(set_attr "type" "logical")
3301 (set_attr "dot" "yes")
3302 (set_attr "length" "4,8")])
3303
3304
3305 (define_insn "*boolcc<mode>3"
3306 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3307 (match_operator:GPR 3 "boolean_operator"
3308 [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
3309 (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))]))]
3310 ""
3311 "%q3 %0,%1,%2"
3312 [(set_attr "type" "logical")])
3313
3314 (define_insn_and_split "*boolcc<mode>3_dot"
3315 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3316 (compare:CC (match_operator:GPR 3 "boolean_operator"
3317 [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
3318 (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
3319 (const_int 0)))
3320 (clobber (match_scratch:GPR 0 "=r,r"))]
3321 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3322 "@
3323 %q3. %0,%1,%2
3324 #"
3325 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3326 [(set (match_dup 0)
3327 (match_dup 3))
3328 (set (match_dup 4)
3329 (compare:CC (match_dup 0)
3330 (const_int 0)))]
3331 ""
3332 [(set_attr "type" "logical")
3333 (set_attr "dot" "yes")
3334 (set_attr "length" "4,8")])
3335
3336 (define_insn_and_split "*boolcc<mode>3_dot2"
3337 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3338 (compare:CC (match_operator:GPR 3 "boolean_operator"
3339 [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
3340 (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
3341 (const_int 0)))
3342 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3343 (match_dup 3))]
3344 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3345 "@
3346 %q3. %0,%1,%2
3347 #"
3348 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3349 [(set (match_dup 0)
3350 (match_dup 3))
3351 (set (match_dup 4)
3352 (compare:CC (match_dup 0)
3353 (const_int 0)))]
3354 ""
3355 [(set_attr "type" "logical")
3356 (set_attr "dot" "yes")
3357 (set_attr "length" "4,8")])
3358
3359
3360 ;; TODO: Should have dots of this as well.
3361 (define_insn "*eqv<mode>3"
3362 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3363 (not:GPR (xor:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3364 (match_operand:GPR 2 "gpc_reg_operand" "r"))))]
3365 ""
3366 "eqv %0,%1,%2"
3367 [(set_attr "type" "logical")])
3368 \f
3369 ;; Rotate and shift insns, in all their variants. These support shifts,
3370 ;; field inserts and extracts, and various combinations thereof.
3371 (define_expand "insv"
3372 [(set (zero_extract (match_operand 0 "gpc_reg_operand" "")
3373 (match_operand:SI 1 "const_int_operand" "")
3374 (match_operand:SI 2 "const_int_operand" ""))
3375 (match_operand 3 "gpc_reg_operand" ""))]
3376 ""
3377 "
3378 {
3379 /* Do not handle 16/8 bit structures that fit in HI/QI modes directly, since
3380 the (SUBREG:SI (REG:HI xxx)) that is otherwise generated can confuse the
3381 compiler if the address of the structure is taken later. Likewise, do
3382 not handle invalid E500 subregs. */
3383 if (GET_CODE (operands[0]) == SUBREG
3384 && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (operands[0]))) < UNITS_PER_WORD
3385 || ((TARGET_E500_DOUBLE || TARGET_SPE)
3386 && invalid_e500_subreg (operands[0], GET_MODE (operands[0])))))
3387 FAIL;
3388
3389 if (TARGET_POWERPC64 && GET_MODE (operands[0]) == DImode)
3390 emit_insn (gen_insvdi_internal (operands[0], operands[1], operands[2],
3391 operands[3]));
3392 else
3393 emit_insn (gen_insvsi_internal (operands[0], operands[1], operands[2],
3394 operands[3]));
3395 DONE;
3396 }")
3397
3398 (define_insn "insvsi_internal"
3399 [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r")
3400 (match_operand:SI 1 "const_int_operand" "i")
3401 (match_operand:SI 2 "const_int_operand" "i"))
3402 (match_operand:SI 3 "gpc_reg_operand" "r"))]
3403 ""
3404 "*
3405 {
3406 int start = INTVAL (operands[2]) & 31;
3407 int size = INTVAL (operands[1]) & 31;
3408
3409 operands[4] = GEN_INT (32 - start - size);
3410 operands[1] = GEN_INT (start + size - 1);
3411 return \"rlwimi %0,%3,%h4,%h2,%h1\";
3412 }"
3413 [(set_attr "type" "insert")])
3414
3415 (define_insn "*insvsi_internal1"
3416 [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r")
3417 (match_operand:SI 1 "const_int_operand" "i")
3418 (match_operand:SI 2 "const_int_operand" "i"))
3419 (rotate:SI (match_operand:SI 3 "gpc_reg_operand" "r")
3420 (match_operand:SI 4 "const_int_operand" "i")))]
3421 "(32 - (INTVAL (operands[4]) & 31)) >= INTVAL (operands[1])"
3422 "*
3423 {
3424 int shift = INTVAL (operands[4]) & 31;
3425 int start = INTVAL (operands[2]) & 31;
3426 int size = INTVAL (operands[1]) & 31;
3427
3428 operands[4] = GEN_INT (shift - start - size);
3429 operands[1] = GEN_INT (start + size - 1);
3430 return \"rlwimi %0,%3,%h4,%h2,%h1\";
3431 }"
3432 [(set_attr "type" "insert")])
3433
3434 (define_insn "*insvsi_internal2"
3435 [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r")
3436 (match_operand:SI 1 "const_int_operand" "i")
3437 (match_operand:SI 2 "const_int_operand" "i"))
3438 (ashiftrt:SI (match_operand:SI 3 "gpc_reg_operand" "r")
3439 (match_operand:SI 4 "const_int_operand" "i")))]
3440 "(32 - (INTVAL (operands[4]) & 31)) >= INTVAL (operands[1])"
3441 "*
3442 {
3443 int shift = INTVAL (operands[4]) & 31;
3444 int start = INTVAL (operands[2]) & 31;
3445 int size = INTVAL (operands[1]) & 31;
3446
3447 operands[4] = GEN_INT (32 - shift - start - size);
3448 operands[1] = GEN_INT (start + size - 1);
3449 return \"rlwimi %0,%3,%h4,%h2,%h1\";
3450 }"
3451 [(set_attr "type" "insert")])
3452
3453 (define_insn "*insvsi_internal3"
3454 [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r")
3455 (match_operand:SI 1 "const_int_operand" "i")
3456 (match_operand:SI 2 "const_int_operand" "i"))
3457 (lshiftrt:SI (match_operand:SI 3 "gpc_reg_operand" "r")
3458 (match_operand:SI 4 "const_int_operand" "i")))]
3459 "(32 - (INTVAL (operands[4]) & 31)) >= INTVAL (operands[1])"
3460 "*
3461 {
3462 int shift = INTVAL (operands[4]) & 31;
3463 int start = INTVAL (operands[2]) & 31;
3464 int size = INTVAL (operands[1]) & 31;
3465
3466 operands[4] = GEN_INT (32 - shift - start - size);
3467 operands[1] = GEN_INT (start + size - 1);
3468 return \"rlwimi %0,%3,%h4,%h2,%h1\";
3469 }"
3470 [(set_attr "type" "insert")])
3471
3472 (define_insn "*insvsi_internal4"
3473 [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r")
3474 (match_operand:SI 1 "const_int_operand" "i")
3475 (match_operand:SI 2 "const_int_operand" "i"))
3476 (zero_extract:SI (match_operand:SI 3 "gpc_reg_operand" "r")
3477 (match_operand:SI 4 "const_int_operand" "i")
3478 (match_operand:SI 5 "const_int_operand" "i")))]
3479 "INTVAL (operands[4]) >= INTVAL (operands[1])"
3480 "*
3481 {
3482 int extract_start = INTVAL (operands[5]) & 31;
3483 int extract_size = INTVAL (operands[4]) & 31;
3484 int insert_start = INTVAL (operands[2]) & 31;
3485 int insert_size = INTVAL (operands[1]) & 31;
3486
3487 /* Align extract field with insert field */
3488 operands[5] = GEN_INT (extract_start + extract_size - insert_start - insert_size);
3489 operands[1] = GEN_INT (insert_start + insert_size - 1);
3490 return \"rlwimi %0,%3,%h5,%h2,%h1\";
3491 }"
3492 [(set_attr "type" "insert")])
3493
3494 ;; combine patterns for rlwimi
3495 (define_insn "*insvsi_internal5"
3496 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
3497 (ior:SI (and:SI (match_operand:SI 4 "gpc_reg_operand" "0")
3498 (match_operand:SI 1 "mask_operand" "i"))
3499 (and:SI (lshiftrt:SI (match_operand:SI 3 "gpc_reg_operand" "r")
3500 (match_operand:SI 2 "const_int_operand" "i"))
3501 (match_operand:SI 5 "mask_operand" "i"))))]
3502 "INTVAL(operands[1]) == ~INTVAL(operands[5])"
3503 "*
3504 {
3505 int me = extract_ME(operands[5]);
3506 int mb = extract_MB(operands[5]);
3507 operands[4] = GEN_INT(32 - INTVAL(operands[2]));
3508 operands[2] = GEN_INT(mb);
3509 operands[1] = GEN_INT(me);
3510 return \"rlwimi %0,%3,%h4,%h2,%h1\";
3511 }"
3512 [(set_attr "type" "insert")])
3513
3514 (define_insn "*insvsi_internal6"
3515 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
3516 (ior:SI (and:SI (lshiftrt:SI (match_operand:SI 3 "gpc_reg_operand" "r")
3517 (match_operand:SI 2 "const_int_operand" "i"))
3518 (match_operand:SI 5 "mask_operand" "i"))
3519 (and:SI (match_operand:SI 4 "gpc_reg_operand" "0")
3520 (match_operand:SI 1 "mask_operand" "i"))))]
3521 "INTVAL(operands[1]) == ~INTVAL(operands[5])"
3522 "*
3523 {
3524 int me = extract_ME(operands[5]);
3525 int mb = extract_MB(operands[5]);
3526 operands[4] = GEN_INT(32 - INTVAL(operands[2]));
3527 operands[2] = GEN_INT(mb);
3528 operands[1] = GEN_INT(me);
3529 return \"rlwimi %0,%3,%h4,%h2,%h1\";
3530 }"
3531 [(set_attr "type" "insert")])
3532
3533 (define_insn "insvdi_internal"
3534 [(set (zero_extract:DI (match_operand:DI 0 "gpc_reg_operand" "+r")
3535 (match_operand:SI 1 "const_int_operand" "i")
3536 (match_operand:SI 2 "const_int_operand" "i"))
3537 (match_operand:DI 3 "gpc_reg_operand" "r"))]
3538 "TARGET_POWERPC64"
3539 "*
3540 {
3541 int start = INTVAL (operands[2]) & 63;
3542 int size = INTVAL (operands[1]) & 63;
3543
3544 operands[1] = GEN_INT (64 - start - size);
3545 return \"rldimi %0,%3,%H1,%H2\";
3546 }"
3547 [(set_attr "type" "insert")
3548 (set_attr "size" "64")])
3549
3550 (define_insn "*insvdi_internal2"
3551 [(set (zero_extract:DI (match_operand:DI 0 "gpc_reg_operand" "+r")
3552 (match_operand:SI 1 "const_int_operand" "i")
3553 (match_operand:SI 2 "const_int_operand" "i"))
3554 (ashiftrt:DI (match_operand:DI 3 "gpc_reg_operand" "r")
3555 (match_operand:SI 4 "const_int_operand" "i")))]
3556 "TARGET_POWERPC64
3557 && insvdi_rshift_rlwimi_p (operands[1], operands[2], operands[4])"
3558 "*
3559 {
3560 int shift = INTVAL (operands[4]) & 63;
3561 int start = (INTVAL (operands[2]) & 63) - 32;
3562 int size = INTVAL (operands[1]) & 63;
3563
3564 operands[4] = GEN_INT (64 - shift - start - size);
3565 operands[2] = GEN_INT (start);
3566 operands[1] = GEN_INT (start + size - 1);
3567 return \"rlwimi %0,%3,%h4,%h2,%h1\";
3568 }")
3569
3570 (define_insn "*insvdi_internal3"
3571 [(set (zero_extract:DI (match_operand:DI 0 "gpc_reg_operand" "+r")
3572 (match_operand:SI 1 "const_int_operand" "i")
3573 (match_operand:SI 2 "const_int_operand" "i"))
3574 (lshiftrt:DI (match_operand:DI 3 "gpc_reg_operand" "r")
3575 (match_operand:SI 4 "const_int_operand" "i")))]
3576 "TARGET_POWERPC64
3577 && insvdi_rshift_rlwimi_p (operands[1], operands[2], operands[4])"
3578 "*
3579 {
3580 int shift = INTVAL (operands[4]) & 63;
3581 int start = (INTVAL (operands[2]) & 63) - 32;
3582 int size = INTVAL (operands[1]) & 63;
3583
3584 operands[4] = GEN_INT (64 - shift - start - size);
3585 operands[2] = GEN_INT (start);
3586 operands[1] = GEN_INT (start + size - 1);
3587 return \"rlwimi %0,%3,%h4,%h2,%h1\";
3588 }")
3589
3590 (define_expand "extzv"
3591 [(set (match_operand 0 "gpc_reg_operand" "")
3592 (zero_extract (match_operand 1 "gpc_reg_operand" "")
3593 (match_operand:SI 2 "const_int_operand" "")
3594 (match_operand:SI 3 "const_int_operand" "")))]
3595 ""
3596 "
3597 {
3598 /* Do not handle 16/8 bit structures that fit in HI/QI modes directly, since
3599 the (SUBREG:SI (REG:HI xxx)) that is otherwise generated can confuse the
3600 compiler if the address of the structure is taken later. */
3601 if (GET_CODE (operands[0]) == SUBREG
3602 && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (operands[0]))) < UNITS_PER_WORD))
3603 FAIL;
3604
3605 if (TARGET_POWERPC64 && GET_MODE (operands[1]) == DImode)
3606 emit_insn (gen_extzvdi_internal (operands[0], operands[1], operands[2],
3607 operands[3]));
3608 else
3609 emit_insn (gen_extzvsi_internal (operands[0], operands[1], operands[2],
3610 operands[3]));
3611 DONE;
3612 }")
3613
3614 (define_insn "extzvsi_internal"
3615 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
3616 (zero_extract:SI (match_operand:SI 1 "gpc_reg_operand" "r")
3617 (match_operand:SI 2 "const_int_operand" "i")
3618 (match_operand:SI 3 "const_int_operand" "i")))]
3619 ""
3620 "*
3621 {
3622 int start = INTVAL (operands[3]) & 31;
3623 int size = INTVAL (operands[2]) & 31;
3624
3625 if (start + size >= 32)
3626 operands[3] = const0_rtx;
3627 else
3628 operands[3] = GEN_INT (start + size);
3629 return \"rlwinm %0,%1,%3,%s2,31\";
3630 }"
3631 [(set_attr "type" "shift")])
3632
3633 (define_insn "*extzvsi_internal1"
3634 [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
3635 (compare:CC (zero_extract:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
3636 (match_operand:SI 2 "const_int_operand" "i,i")
3637 (match_operand:SI 3 "const_int_operand" "i,i"))
3638 (const_int 0)))
3639 (clobber (match_scratch:SI 4 "=r,r"))]
3640 ""
3641 "*
3642 {
3643 int start = INTVAL (operands[3]) & 31;
3644 int size = INTVAL (operands[2]) & 31;
3645
3646 /* Force split for non-cc0 compare. */
3647 if (which_alternative == 1)
3648 return \"#\";
3649
3650 /* If the bit-field being tested fits in the upper or lower half of a
3651 word, it is possible to use andiu. or andil. to test it. This is
3652 useful because the condition register set-use delay is smaller for
3653 andi[ul]. than for rlinm. This doesn't work when the starting bit
3654 position is 0 because the LT and GT bits may be set wrong. */
3655
3656 if ((start > 0 && start + size <= 16) || start >= 16)
3657 {
3658 operands[3] = GEN_INT (((1 << (16 - (start & 15)))
3659 - (1 << (16 - (start & 15) - size))));
3660 if (start < 16)
3661 return \"andis. %4,%1,%3\";
3662 else
3663 return \"andi. %4,%1,%3\";
3664 }
3665
3666 if (start + size >= 32)
3667 operands[3] = const0_rtx;
3668 else
3669 operands[3] = GEN_INT (start + size);
3670 return \"rlwinm. %4,%1,%3,%s2,31\";
3671 }"
3672 [(set_attr "type" "shift")
3673 (set_attr "dot" "yes")
3674 (set_attr "length" "4,8")])
3675
3676 (define_split
3677 [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
3678 (compare:CC (zero_extract:SI (match_operand:SI 1 "gpc_reg_operand" "")
3679 (match_operand:SI 2 "const_int_operand" "")
3680 (match_operand:SI 3 "const_int_operand" ""))
3681 (const_int 0)))
3682 (clobber (match_scratch:SI 4 ""))]
3683 "reload_completed"
3684 [(set (match_dup 4)
3685 (zero_extract:SI (match_dup 1) (match_dup 2)
3686 (match_dup 3)))
3687 (set (match_dup 0)
3688 (compare:CC (match_dup 4)
3689 (const_int 0)))]
3690 "")
3691
3692 (define_insn "*extzvsi_internal2"
3693 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3694 (compare:CC (zero_extract:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
3695 (match_operand:SI 2 "const_int_operand" "i,i")
3696 (match_operand:SI 3 "const_int_operand" "i,i"))
3697 (const_int 0)))
3698 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
3699 (zero_extract:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
3700 ""
3701 "*
3702 {
3703 int start = INTVAL (operands[3]) & 31;
3704 int size = INTVAL (operands[2]) & 31;
3705
3706 /* Force split for non-cc0 compare. */
3707 if (which_alternative == 1)
3708 return \"#\";
3709
3710 /* Since we are using the output value, we can't ignore any need for
3711 a shift. The bit-field must end at the LSB. */
3712 if (start >= 16 && start + size == 32)
3713 {
3714 operands[3] = GEN_INT ((1 << size) - 1);
3715 return \"andi. %0,%1,%3\";
3716 }
3717
3718 if (start + size >= 32)
3719 operands[3] = const0_rtx;
3720 else
3721 operands[3] = GEN_INT (start + size);
3722 return \"rlwinm. %0,%1,%3,%s2,31\";
3723 }"
3724 [(set_attr "type" "shift")
3725 (set_attr "dot" "yes")
3726 (set_attr "length" "4,8")])
3727
3728 (define_split
3729 [(set (match_operand:CC 4 "cc_reg_not_micro_cr0_operand" "")
3730 (compare:CC (zero_extract:SI (match_operand:SI 1 "gpc_reg_operand" "")
3731 (match_operand:SI 2 "const_int_operand" "")
3732 (match_operand:SI 3 "const_int_operand" ""))
3733 (const_int 0)))
3734 (set (match_operand:SI 0 "gpc_reg_operand" "")
3735 (zero_extract:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
3736 "reload_completed"
3737 [(set (match_dup 0)
3738 (zero_extract:SI (match_dup 1) (match_dup 2) (match_dup 3)))
3739 (set (match_dup 4)
3740 (compare:CC (match_dup 0)
3741 (const_int 0)))]
3742 "")
3743
3744 (define_insn "extzvdi_internal"
3745 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3746 (zero_extract:DI (match_operand:DI 1 "gpc_reg_operand" "r")
3747 (match_operand:SI 2 "const_int_operand" "i")
3748 (match_operand:SI 3 "const_int_operand" "i")))]
3749 "TARGET_POWERPC64"
3750 "*
3751 {
3752 int start = INTVAL (operands[3]) & 63;
3753 int size = INTVAL (operands[2]) & 63;
3754
3755 if (start + size >= 64)
3756 operands[3] = const0_rtx;
3757 else
3758 operands[3] = GEN_INT (start + size);
3759 operands[2] = GEN_INT (64 - size);
3760 return \"rldicl %0,%1,%3,%2\";
3761 }"
3762 [(set_attr "type" "shift")])
3763
3764 (define_insn "*extzvdi_internal1"
3765 [(set (match_operand:CC 0 "gpc_reg_operand" "=x")
3766 (compare:CC (zero_extract:DI (match_operand:DI 1 "gpc_reg_operand" "r")
3767 (match_operand:SI 2 "const_int_operand" "i")
3768 (match_operand:SI 3 "const_int_operand" "i"))
3769 (const_int 0)))
3770 (clobber (match_scratch:DI 4 "=r"))]
3771 "TARGET_64BIT && rs6000_gen_cell_microcode"
3772 "*
3773 {
3774 int start = INTVAL (operands[3]) & 63;
3775 int size = INTVAL (operands[2]) & 63;
3776
3777 if (start + size >= 64)
3778 operands[3] = const0_rtx;
3779 else
3780 operands[3] = GEN_INT (start + size);
3781 operands[2] = GEN_INT (64 - size);
3782 return \"rldicl. %4,%1,%3,%2\";
3783 }"
3784 [(set_attr "type" "shift")
3785 (set_attr "dot" "yes")])
3786
3787 (define_insn "*extzvdi_internal2"
3788 [(set (match_operand:CC 4 "gpc_reg_operand" "=x")
3789 (compare:CC (zero_extract:DI (match_operand:DI 1 "gpc_reg_operand" "r")
3790 (match_operand:SI 2 "const_int_operand" "i")
3791 (match_operand:SI 3 "const_int_operand" "i"))
3792 (const_int 0)))
3793 (set (match_operand:DI 0 "gpc_reg_operand" "=r")
3794 (zero_extract:DI (match_dup 1) (match_dup 2) (match_dup 3)))]
3795 "TARGET_64BIT && rs6000_gen_cell_microcode"
3796 "*
3797 {
3798 int start = INTVAL (operands[3]) & 63;
3799 int size = INTVAL (operands[2]) & 63;
3800
3801 if (start + size >= 64)
3802 operands[3] = const0_rtx;
3803 else
3804 operands[3] = GEN_INT (start + size);
3805 operands[2] = GEN_INT (64 - size);
3806 return \"rldicl. %0,%1,%3,%2\";
3807 }"
3808 [(set_attr "type" "shift")
3809 (set_attr "dot" "yes")])
3810
3811
3812 (define_insn "rotl<mode>3"
3813 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3814 (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3815 (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
3816 ""
3817 "rotl<wd>%I2 %0,%1,%<hH>2"
3818 [(set_attr "type" "shift")
3819 (set_attr "maybe_var_shift" "yes")])
3820
3821 (define_insn "*rotlsi3_64"
3822 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3823 (zero_extend:DI
3824 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
3825 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
3826 "TARGET_POWERPC64"
3827 "rotlw%I2 %0,%1,%h2"
3828 [(set_attr "type" "shift")
3829 (set_attr "maybe_var_shift" "yes")])
3830
3831 (define_insn_and_split "*rotl<mode>3_dot"
3832 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3833 (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3834 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
3835 (const_int 0)))
3836 (clobber (match_scratch:GPR 0 "=r,r"))]
3837 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3838 "@
3839 rotl<wd>%I2. %0,%1,%<hH>2
3840 #"
3841 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3842 [(set (match_dup 0)
3843 (rotate:GPR (match_dup 1)
3844 (match_dup 2)))
3845 (set (match_dup 3)
3846 (compare:CC (match_dup 0)
3847 (const_int 0)))]
3848 ""
3849 [(set_attr "type" "shift")
3850 (set_attr "maybe_var_shift" "yes")
3851 (set_attr "dot" "yes")
3852 (set_attr "length" "4,8")])
3853
3854 (define_insn_and_split "*rotl<mode>3_dot2"
3855 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3856 (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3857 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
3858 (const_int 0)))
3859 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3860 (rotate:GPR (match_dup 1)
3861 (match_dup 2)))]
3862 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3863 "@
3864 rotl<wd>%I2. %0,%1,%<hH>2
3865 #"
3866 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3867 [(set (match_dup 0)
3868 (rotate:GPR (match_dup 1)
3869 (match_dup 2)))
3870 (set (match_dup 3)
3871 (compare:CC (match_dup 0)
3872 (const_int 0)))]
3873 ""
3874 [(set_attr "type" "shift")
3875 (set_attr "maybe_var_shift" "yes")
3876 (set_attr "dot" "yes")
3877 (set_attr "length" "4,8")])
3878
3879
3880 (define_insn "*rotlsi3_internal4"
3881 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
3882 (and:SI (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
3883 (match_operand:SI 2 "reg_or_cint_operand" "rn"))
3884 (match_operand:SI 3 "mask_operand" "n")))]
3885 ""
3886 "rlw%I2nm %0,%1,%h2,%m3,%M3"
3887 [(set_attr "type" "shift")
3888 (set_attr "maybe_var_shift" "yes")])
3889
3890 (define_insn "*rotlsi3_internal5"
3891 [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
3892 (compare:CC (and:SI
3893 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
3894 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
3895 (match_operand:SI 3 "mask_operand" "n,n"))
3896 (const_int 0)))
3897 (clobber (match_scratch:SI 4 "=r,r"))]
3898 ""
3899 "@
3900 rlw%I2nm. %4,%1,%h2,%m3,%M3
3901 #"
3902 [(set_attr "type" "shift")
3903 (set_attr "maybe_var_shift" "yes")
3904 (set_attr "dot" "yes")
3905 (set_attr "length" "4,8")])
3906
3907 (define_split
3908 [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
3909 (compare:CC (and:SI
3910 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "")
3911 (match_operand:SI 2 "reg_or_cint_operand" ""))
3912 (match_operand:SI 3 "mask_operand" ""))
3913 (const_int 0)))
3914 (clobber (match_scratch:SI 4 ""))]
3915 "reload_completed"
3916 [(set (match_dup 4)
3917 (and:SI (rotate:SI (match_dup 1)
3918 (match_dup 2))
3919 (match_dup 3)))
3920 (set (match_dup 0)
3921 (compare:CC (match_dup 4)
3922 (const_int 0)))]
3923 "")
3924
3925 (define_insn "*rotlsi3_internal6"
3926 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3927 (compare:CC (and:SI
3928 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
3929 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
3930 (match_operand:SI 3 "mask_operand" "n,n"))
3931 (const_int 0)))
3932 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
3933 (and:SI (rotate:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
3934 ""
3935 "@
3936 rlw%I2nm. %0,%1,%h2,%m3,%M3
3937 #"
3938 [(set_attr "type" "shift")
3939 (set_attr "maybe_var_shift" "yes")
3940 (set_attr "dot" "yes")
3941 (set_attr "length" "4,8")])
3942
3943 (define_split
3944 [(set (match_operand:CC 4 "cc_reg_not_micro_cr0_operand" "")
3945 (compare:CC (and:SI
3946 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "")
3947 (match_operand:SI 2 "reg_or_cint_operand" ""))
3948 (match_operand:SI 3 "mask_operand" ""))
3949 (const_int 0)))
3950 (set (match_operand:SI 0 "gpc_reg_operand" "")
3951 (and:SI (rotate:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
3952 "reload_completed"
3953 [(set (match_dup 0)
3954 (and:SI (rotate:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
3955 (set (match_dup 4)
3956 (compare:CC (match_dup 0)
3957 (const_int 0)))]
3958 "")
3959
3960 (define_insn "*rotlsi3_internal7le"
3961 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
3962 (zero_extend:SI
3963 (subreg:QI
3964 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
3965 (match_operand:SI 2 "reg_or_cint_operand" "ri")) 0)))]
3966 "!BYTES_BIG_ENDIAN"
3967 "rlw%I2nm %0,%1,%h2,0xff"
3968 [(set (attr "cell_micro")
3969 (if_then_else (match_operand:SI 2 "const_int_operand" "")
3970 (const_string "not")
3971 (const_string "always")))
3972 (set_attr "type" "shift")])
3973
3974 (define_insn "*rotlsi3_internal7be"
3975 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
3976 (zero_extend:SI
3977 (subreg:QI
3978 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
3979 (match_operand:SI 2 "reg_or_cint_operand" "ri")) 3)))]
3980 "BYTES_BIG_ENDIAN"
3981 "rlw%I2nm %0,%1,%h2,0xff"
3982 [(set (attr "cell_micro")
3983 (if_then_else (match_operand:SI 2 "const_int_operand" "")
3984 (const_string "not")
3985 (const_string "always")))
3986 (set_attr "type" "shift")])
3987
3988 (define_insn "*rotlsi3_internal8le"
3989 [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
3990 (compare:CC (zero_extend:SI
3991 (subreg:QI
3992 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
3993 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")) 0))
3994 (const_int 0)))
3995 (clobber (match_scratch:SI 3 "=r,r"))]
3996 "!BYTES_BIG_ENDIAN"
3997 "@
3998 rlw%I2nm. %3,%1,%h2,0xff
3999 #"
4000 [(set_attr "type" "shift")
4001 (set_attr "maybe_var_shift" "yes")
4002 (set_attr "dot" "yes")
4003 (set_attr "length" "4,8")])
4004
4005 (define_insn "*rotlsi3_internal8be"
4006 [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
4007 (compare:CC (zero_extend:SI
4008 (subreg:QI
4009 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
4010 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")) 3))
4011 (const_int 0)))
4012 (clobber (match_scratch:SI 3 "=r,r"))]
4013 "BYTES_BIG_ENDIAN"
4014 "@
4015 rlw%I2nm. %3,%1,%h2,0xff
4016 #"
4017 [(set_attr "type" "shift")
4018 (set_attr "maybe_var_shift" "yes")
4019 (set_attr "dot" "yes")
4020 (set_attr "length" "4,8")])
4021
4022 (define_split
4023 [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
4024 (compare:CC (zero_extend:SI
4025 (subreg:QI
4026 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "")
4027 (match_operand:SI 2 "reg_or_cint_operand" "")) 0))
4028 (const_int 0)))
4029 (clobber (match_scratch:SI 3 ""))]
4030 "!BYTES_BIG_ENDIAN && reload_completed"
4031 [(set (match_dup 3)
4032 (zero_extend:SI (subreg:QI
4033 (rotate:SI (match_dup 1)
4034 (match_dup 2)) 0)))
4035 (set (match_dup 0)
4036 (compare:CC (match_dup 3)
4037 (const_int 0)))]
4038 "")
4039
4040 (define_split
4041 [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
4042 (compare:CC (zero_extend:SI
4043 (subreg:QI
4044 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "")
4045 (match_operand:SI 2 "reg_or_cint_operand" "")) 3))
4046 (const_int 0)))
4047 (clobber (match_scratch:SI 3 ""))]
4048 "BYTES_BIG_ENDIAN && reload_completed"
4049 [(set (match_dup 3)
4050 (zero_extend:SI (subreg:QI
4051 (rotate:SI (match_dup 1)
4052 (match_dup 2)) 3)))
4053 (set (match_dup 0)
4054 (compare:CC (match_dup 3)
4055 (const_int 0)))]
4056 "")
4057
4058 (define_insn "*rotlsi3_internal9le"
4059 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4060 (compare:CC (zero_extend:SI
4061 (subreg:QI
4062 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
4063 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")) 0))
4064 (const_int 0)))
4065 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
4066 (zero_extend:SI (subreg:QI (rotate:SI (match_dup 1) (match_dup 2)) 0)))]
4067 "!BYTES_BIG_ENDIAN"
4068 "@
4069 rlw%I2nm. %0,%1,%h2,0xff
4070 #"
4071 [(set_attr "type" "shift")
4072 (set_attr "maybe_var_shift" "yes")
4073 (set_attr "dot" "yes")
4074 (set_attr "length" "4,8")])
4075
4076 (define_insn "*rotlsi3_internal9be"
4077 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4078 (compare:CC (zero_extend:SI
4079 (subreg:QI
4080 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
4081 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")) 3))
4082 (const_int 0)))
4083 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
4084 (zero_extend:SI (subreg:QI (rotate:SI (match_dup 1) (match_dup 2)) 3)))]
4085 "BYTES_BIG_ENDIAN"
4086 "@
4087 rlw%I2nm. %0,%1,%h2,0xff
4088 #"
4089 [(set_attr "type" "shift")
4090 (set_attr "maybe_var_shift" "yes")
4091 (set_attr "dot" "yes")
4092 (set_attr "length" "4,8")])
4093
4094 (define_split
4095 [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "")
4096 (compare:CC (zero_extend:SI
4097 (subreg:QI
4098 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "")
4099 (match_operand:SI 2 "reg_or_cint_operand" "")) 0))
4100 (const_int 0)))
4101 (set (match_operand:SI 0 "gpc_reg_operand" "")
4102 (zero_extend:SI (subreg:QI (rotate:SI (match_dup 1) (match_dup 2)) 0)))]
4103 "!BYTES_BIG_ENDIAN && reload_completed"
4104 [(set (match_dup 0)
4105 (zero_extend:SI (subreg:QI (rotate:SI (match_dup 1) (match_dup 2)) 0)))
4106 (set (match_dup 3)
4107 (compare:CC (match_dup 0)
4108 (const_int 0)))]
4109 "")
4110
4111 (define_split
4112 [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "")
4113 (compare:CC (zero_extend:SI
4114 (subreg:QI
4115 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "")
4116 (match_operand:SI 2 "reg_or_cint_operand" "")) 3))
4117 (const_int 0)))
4118 (set (match_operand:SI 0 "gpc_reg_operand" "")
4119 (zero_extend:SI (subreg:QI (rotate:SI (match_dup 1) (match_dup 2)) 3)))]
4120 "BYTES_BIG_ENDIAN && reload_completed"
4121 [(set (match_dup 0)
4122 (zero_extend:SI (subreg:QI (rotate:SI (match_dup 1) (match_dup 2)) 3)))
4123 (set (match_dup 3)
4124 (compare:CC (match_dup 0)
4125 (const_int 0)))]
4126 "")
4127
4128 (define_insn "*rotlsi3_internal10le"
4129 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
4130 (zero_extend:SI
4131 (subreg:HI
4132 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4133 (match_operand:SI 2 "reg_or_cint_operand" "rn")) 0)))]
4134 "!BYTES_BIG_ENDIAN"
4135 "rlw%I2nm %0,%1,%h2,0xffff"
4136 [(set_attr "type" "shift")
4137 (set_attr "maybe_var_shift" "yes")])
4138
4139 (define_insn "*rotlsi3_internal10be"
4140 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
4141 (zero_extend:SI
4142 (subreg:HI
4143 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4144 (match_operand:SI 2 "reg_or_cint_operand" "rn")) 2)))]
4145 "BYTES_BIG_ENDIAN"
4146 "rlw%I2nm %0,%1,%h2,0xffff"
4147 [(set_attr "type" "shift")
4148 (set_attr "maybe_var_shift" "yes")])
4149
4150 (define_insn "*rotlsi3_internal11le"
4151 [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
4152 (compare:CC (zero_extend:SI
4153 (subreg:HI
4154 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
4155 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")) 0))
4156 (const_int 0)))
4157 (clobber (match_scratch:SI 3 "=r,r"))]
4158 "!BYTES_BIG_ENDIAN"
4159 "@
4160 rlw%I2nm. %3,%1,%h2,0xffff
4161 #"
4162 [(set_attr "type" "shift")
4163 (set_attr "maybe_var_shift" "yes")
4164 (set_attr "dot" "yes")
4165 (set_attr "length" "4,8")])
4166
4167 (define_insn "*rotlsi3_internal11be"
4168 [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
4169 (compare:CC (zero_extend:SI
4170 (subreg:HI
4171 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
4172 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")) 2))
4173 (const_int 0)))
4174 (clobber (match_scratch:SI 3 "=r,r"))]
4175 "BYTES_BIG_ENDIAN"
4176 "@
4177 rlw%I2nm. %3,%1,%h2,0xffff
4178 #"
4179 [(set_attr "type" "shift")
4180 (set_attr "maybe_var_shift" "yes")
4181 (set_attr "dot" "yes")
4182 (set_attr "length" "4,8")])
4183
4184 (define_split
4185 [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
4186 (compare:CC (zero_extend:SI
4187 (subreg:HI
4188 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "")
4189 (match_operand:SI 2 "reg_or_cint_operand" "")) 0))
4190 (const_int 0)))
4191 (clobber (match_scratch:SI 3 ""))]
4192 "!BYTES_BIG_ENDIAN && reload_completed"
4193 [(set (match_dup 3)
4194 (zero_extend:SI (subreg:HI
4195 (rotate:SI (match_dup 1)
4196 (match_dup 2)) 0)))
4197 (set (match_dup 0)
4198 (compare:CC (match_dup 3)
4199 (const_int 0)))]
4200 "")
4201
4202 (define_split
4203 [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
4204 (compare:CC (zero_extend:SI
4205 (subreg:HI
4206 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "")
4207 (match_operand:SI 2 "reg_or_cint_operand" "")) 2))
4208 (const_int 0)))
4209 (clobber (match_scratch:SI 3 ""))]
4210 "BYTES_BIG_ENDIAN && reload_completed"
4211 [(set (match_dup 3)
4212 (zero_extend:SI (subreg:HI
4213 (rotate:SI (match_dup 1)
4214 (match_dup 2)) 2)))
4215 (set (match_dup 0)
4216 (compare:CC (match_dup 3)
4217 (const_int 0)))]
4218 "")
4219
4220 (define_insn "*rotlsi3_internal12le"
4221 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4222 (compare:CC (zero_extend:SI
4223 (subreg:HI
4224 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
4225 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")) 0))
4226 (const_int 0)))
4227 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
4228 (zero_extend:SI (subreg:HI (rotate:SI (match_dup 1) (match_dup 2)) 0)))]
4229 "!BYTES_BIG_ENDIAN"
4230 "@
4231 rlw%I2nm. %0,%1,%h2,0xffff
4232 #"
4233 [(set_attr "type" "shift")
4234 (set_attr "maybe_var_shift" "yes")
4235 (set_attr "dot" "yes")
4236 (set_attr "length" "4,8")])
4237
4238 (define_insn "*rotlsi3_internal12be"
4239 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4240 (compare:CC (zero_extend:SI
4241 (subreg:HI
4242 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
4243 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")) 2))
4244 (const_int 0)))
4245 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
4246 (zero_extend:SI (subreg:HI (rotate:SI (match_dup 1) (match_dup 2)) 2)))]
4247 "BYTES_BIG_ENDIAN"
4248 "@
4249 rlw%I2nm. %0,%1,%h2,0xffff
4250 #"
4251 [(set_attr "type" "shift")
4252 (set_attr "maybe_var_shift" "yes")
4253 (set_attr "dot" "yes")
4254 (set_attr "length" "4,8")])
4255
4256 (define_split
4257 [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "")
4258 (compare:CC (zero_extend:SI
4259 (subreg:HI
4260 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "")
4261 (match_operand:SI 2 "reg_or_cint_operand" "")) 0))
4262 (const_int 0)))
4263 (set (match_operand:SI 0 "gpc_reg_operand" "")
4264 (zero_extend:SI (subreg:HI (rotate:SI (match_dup 1) (match_dup 2)) 0)))]
4265 "!BYTES_BIG_ENDIAN && reload_completed"
4266 [(set (match_dup 0)
4267 (zero_extend:SI (subreg:HI (rotate:SI (match_dup 1) (match_dup 2)) 0)))
4268 (set (match_dup 3)
4269 (compare:CC (match_dup 0)
4270 (const_int 0)))]
4271 "")
4272
4273 (define_split
4274 [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "")
4275 (compare:CC (zero_extend:SI
4276 (subreg:HI
4277 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "")
4278 (match_operand:SI 2 "reg_or_cint_operand" "")) 2))
4279 (const_int 0)))
4280 (set (match_operand:SI 0 "gpc_reg_operand" "")
4281 (zero_extend:SI (subreg:HI (rotate:SI (match_dup 1) (match_dup 2)) 2)))]
4282 "BYTES_BIG_ENDIAN && reload_completed"
4283 [(set (match_dup 0)
4284 (zero_extend:SI (subreg:HI (rotate:SI (match_dup 1) (match_dup 2)) 2)))
4285 (set (match_dup 3)
4286 (compare:CC (match_dup 0)
4287 (const_int 0)))]
4288 "")
4289
4290
4291 (define_insn "ashl<mode>3"
4292 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4293 (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4294 (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4295 ""
4296 "sl<wd>%I2 %0,%1,%<hH>2"
4297 [(set_attr "type" "shift")
4298 (set_attr "maybe_var_shift" "yes")])
4299
4300 (define_insn "*ashlsi3_64"
4301 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4302 (zero_extend:DI
4303 (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4304 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4305 "TARGET_POWERPC64"
4306 "slw%I2 %0,%1,%h2"
4307 [(set_attr "type" "shift")
4308 (set_attr "maybe_var_shift" "yes")])
4309
4310 (define_insn_and_split "*ashl<mode>3_dot"
4311 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4312 (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4313 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4314 (const_int 0)))
4315 (clobber (match_scratch:GPR 0 "=r,r"))]
4316 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4317 "@
4318 sl<wd>%I2. %0,%1,%<hH>2
4319 #"
4320 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4321 [(set (match_dup 0)
4322 (ashift:GPR (match_dup 1)
4323 (match_dup 2)))
4324 (set (match_dup 3)
4325 (compare:CC (match_dup 0)
4326 (const_int 0)))]
4327 ""
4328 [(set_attr "type" "shift")
4329 (set_attr "maybe_var_shift" "yes")
4330 (set_attr "dot" "yes")
4331 (set_attr "length" "4,8")])
4332
4333 (define_insn_and_split "*ashl<mode>3_dot2"
4334 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4335 (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4336 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4337 (const_int 0)))
4338 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4339 (ashift:GPR (match_dup 1)
4340 (match_dup 2)))]
4341 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4342 "@
4343 sl<wd>%I2. %0,%1,%<hH>2
4344 #"
4345 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4346 [(set (match_dup 0)
4347 (ashift:GPR (match_dup 1)
4348 (match_dup 2)))
4349 (set (match_dup 3)
4350 (compare:CC (match_dup 0)
4351 (const_int 0)))]
4352 ""
4353 [(set_attr "type" "shift")
4354 (set_attr "maybe_var_shift" "yes")
4355 (set_attr "dot" "yes")
4356 (set_attr "length" "4,8")])
4357
4358
4359 (define_insn "rlwinm"
4360 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
4361 (and:SI (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4362 (match_operand:SI 2 "const_int_operand" "i"))
4363 (match_operand:SI 3 "mask_operand" "n")))]
4364 "includes_lshift_p (operands[2], operands[3])"
4365 "rlwinm %0,%1,%h2,%m3,%M3"
4366 [(set_attr "type" "shift")])
4367
4368 (define_insn ""
4369 [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
4370 (compare:CC
4371 (and:SI (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
4372 (match_operand:SI 2 "const_int_operand" "i,i"))
4373 (match_operand:SI 3 "mask_operand" "n,n"))
4374 (const_int 0)))
4375 (clobber (match_scratch:SI 4 "=r,r"))]
4376 "includes_lshift_p (operands[2], operands[3])"
4377 "@
4378 rlwinm. %4,%1,%h2,%m3,%M3
4379 #"
4380 [(set_attr "type" "shift")
4381 (set_attr "dot" "yes")
4382 (set_attr "length" "4,8")])
4383
4384 (define_split
4385 [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
4386 (compare:CC
4387 (and:SI (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "")
4388 (match_operand:SI 2 "const_int_operand" ""))
4389 (match_operand:SI 3 "mask_operand" ""))
4390 (const_int 0)))
4391 (clobber (match_scratch:SI 4 ""))]
4392 "includes_lshift_p (operands[2], operands[3]) && reload_completed"
4393 [(set (match_dup 4)
4394 (and:SI (ashift:SI (match_dup 1) (match_dup 2))
4395 (match_dup 3)))
4396 (set (match_dup 0)
4397 (compare:CC (match_dup 4)
4398 (const_int 0)))]
4399 "")
4400
4401 (define_insn ""
4402 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
4403 (compare:CC
4404 (and:SI (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
4405 (match_operand:SI 2 "const_int_operand" "i,i"))
4406 (match_operand:SI 3 "mask_operand" "n,n"))
4407 (const_int 0)))
4408 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
4409 (and:SI (ashift:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
4410 "includes_lshift_p (operands[2], operands[3])"
4411 "@
4412 rlwinm. %0,%1,%h2,%m3,%M3
4413 #"
4414 [(set_attr "type" "shift")
4415 (set_attr "dot" "yes")
4416 (set_attr "length" "4,8")])
4417
4418 (define_split
4419 [(set (match_operand:CC 4 "cc_reg_not_micro_cr0_operand" "")
4420 (compare:CC
4421 (and:SI (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "")
4422 (match_operand:SI 2 "const_int_operand" ""))
4423 (match_operand:SI 3 "mask_operand" ""))
4424 (const_int 0)))
4425 (set (match_operand:SI 0 "gpc_reg_operand" "")
4426 (and:SI (ashift:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
4427 "includes_lshift_p (operands[2], operands[3]) && reload_completed"
4428 [(set (match_dup 0)
4429 (and:SI (ashift:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
4430 (set (match_dup 4)
4431 (compare:CC (match_dup 0)
4432 (const_int 0)))]
4433 "")
4434
4435
4436 (define_insn "lshr<mode>3"
4437 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4438 (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4439 (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4440 ""
4441 "sr<wd>%I2 %0,%1,%<hH>2"
4442 [(set_attr "type" "shift")
4443 (set_attr "maybe_var_shift" "yes")])
4444
4445 (define_insn "*lshrsi3_64"
4446 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4447 (zero_extend:DI
4448 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4449 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4450 "TARGET_POWERPC64"
4451 "srw%I2 %0,%1,%h2"
4452 [(set_attr "type" "shift")
4453 (set_attr "maybe_var_shift" "yes")])
4454
4455 (define_insn_and_split "*lshr<mode>3_dot"
4456 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4457 (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4458 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4459 (const_int 0)))
4460 (clobber (match_scratch:GPR 0 "=r,r"))]
4461 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4462 "@
4463 sr<wd>%I2. %0,%1,%<hH>2
4464 #"
4465 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4466 [(set (match_dup 0)
4467 (lshiftrt:GPR (match_dup 1)
4468 (match_dup 2)))
4469 (set (match_dup 3)
4470 (compare:CC (match_dup 0)
4471 (const_int 0)))]
4472 ""
4473 [(set_attr "type" "shift")
4474 (set_attr "maybe_var_shift" "yes")
4475 (set_attr "dot" "yes")
4476 (set_attr "length" "4,8")])
4477
4478 (define_insn_and_split "*lshr<mode>3_dot2"
4479 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4480 (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4481 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4482 (const_int 0)))
4483 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4484 (lshiftrt:GPR (match_dup 1)
4485 (match_dup 2)))]
4486 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4487 "@
4488 sr<wd>%I2. %0,%1,%<hH>2
4489 #"
4490 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4491 [(set (match_dup 0)
4492 (lshiftrt:GPR (match_dup 1)
4493 (match_dup 2)))
4494 (set (match_dup 3)
4495 (compare:CC (match_dup 0)
4496 (const_int 0)))]
4497 ""
4498 [(set_attr "type" "shift")
4499 (set_attr "maybe_var_shift" "yes")
4500 (set_attr "dot" "yes")
4501 (set_attr "length" "4,8")])
4502
4503
4504 (define_insn ""
4505 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
4506 (and:SI (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4507 (match_operand:SI 2 "const_int_operand" "i"))
4508 (match_operand:SI 3 "mask_operand" "n")))]
4509 "includes_rshift_p (operands[2], operands[3])"
4510 "rlwinm %0,%1,%s2,%m3,%M3"
4511 [(set_attr "type" "shift")])
4512
4513 (define_insn ""
4514 [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
4515 (compare:CC
4516 (and:SI (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
4517 (match_operand:SI 2 "const_int_operand" "i,i"))
4518 (match_operand:SI 3 "mask_operand" "n,n"))
4519 (const_int 0)))
4520 (clobber (match_scratch:SI 4 "=r,r"))]
4521 "includes_rshift_p (operands[2], operands[3])"
4522 "@
4523 rlwinm. %4,%1,%s2,%m3,%M3
4524 #"
4525 [(set_attr "type" "shift")
4526 (set_attr "dot" "yes")
4527 (set_attr "length" "4,8")])
4528
4529 (define_split
4530 [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
4531 (compare:CC
4532 (and:SI (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "")
4533 (match_operand:SI 2 "const_int_operand" ""))
4534 (match_operand:SI 3 "mask_operand" ""))
4535 (const_int 0)))
4536 (clobber (match_scratch:SI 4 ""))]
4537 "includes_rshift_p (operands[2], operands[3]) && reload_completed"
4538 [(set (match_dup 4)
4539 (and:SI (lshiftrt:SI (match_dup 1) (match_dup 2))
4540 (match_dup 3)))
4541 (set (match_dup 0)
4542 (compare:CC (match_dup 4)
4543 (const_int 0)))]
4544 "")
4545
4546 (define_insn ""
4547 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
4548 (compare:CC
4549 (and:SI (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
4550 (match_operand:SI 2 "const_int_operand" "i,i"))
4551 (match_operand:SI 3 "mask_operand" "n,n"))
4552 (const_int 0)))
4553 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
4554 (and:SI (lshiftrt:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
4555 "includes_rshift_p (operands[2], operands[3])"
4556 "@
4557 rlwinm. %0,%1,%s2,%m3,%M3
4558 #"
4559 [(set_attr "type" "shift")
4560 (set_attr "dot" "yes")
4561 (set_attr "length" "4,8")])
4562
4563 (define_split
4564 [(set (match_operand:CC 4 "cc_reg_not_micro_cr0_operand" "")
4565 (compare:CC
4566 (and:SI (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "")
4567 (match_operand:SI 2 "const_int_operand" ""))
4568 (match_operand:SI 3 "mask_operand" ""))
4569 (const_int 0)))
4570 (set (match_operand:SI 0 "gpc_reg_operand" "")
4571 (and:SI (lshiftrt:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
4572 "includes_rshift_p (operands[2], operands[3]) && reload_completed"
4573 [(set (match_dup 0)
4574 (and:SI (lshiftrt:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
4575 (set (match_dup 4)
4576 (compare:CC (match_dup 0)
4577 (const_int 0)))]
4578 "")
4579
4580 (define_insn "*lshiftrt_internal1le"
4581 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
4582 (zero_extend:SI
4583 (subreg:QI
4584 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4585 (match_operand:SI 2 "const_int_operand" "i")) 0)))]
4586 "!BYTES_BIG_ENDIAN && includes_rshift_p (operands[2], GEN_INT (255))"
4587 "rlwinm %0,%1,%s2,0xff"
4588 [(set_attr "type" "shift")])
4589
4590 (define_insn "*lshiftrt_internal1be"
4591 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
4592 (zero_extend:SI
4593 (subreg:QI
4594 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4595 (match_operand:SI 2 "const_int_operand" "i")) 3)))]
4596 "BYTES_BIG_ENDIAN && includes_rshift_p (operands[2], GEN_INT (255))"
4597 "rlwinm %0,%1,%s2,0xff"
4598 [(set_attr "type" "shift")])
4599
4600 (define_insn "*lshiftrt_internal2le"
4601 [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
4602 (compare:CC
4603 (zero_extend:SI
4604 (subreg:QI
4605 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
4606 (match_operand:SI 2 "const_int_operand" "i,i")) 0))
4607 (const_int 0)))
4608 (clobber (match_scratch:SI 3 "=r,r"))]
4609 "!BYTES_BIG_ENDIAN && includes_rshift_p (operands[2], GEN_INT (255))"
4610 "@
4611 rlwinm. %3,%1,%s2,0xff
4612 #"
4613 [(set_attr "type" "shift")
4614 (set_attr "dot" "yes")
4615 (set_attr "length" "4,8")])
4616
4617 (define_insn "*lshiftrt_internal2be"
4618 [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
4619 (compare:CC
4620 (zero_extend:SI
4621 (subreg:QI
4622 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
4623 (match_operand:SI 2 "const_int_operand" "i,i")) 3))
4624 (const_int 0)))
4625 (clobber (match_scratch:SI 3 "=r,r"))]
4626 "BYTES_BIG_ENDIAN && includes_rshift_p (operands[2], GEN_INT (255))"
4627 "@
4628 rlwinm. %3,%1,%s2,0xff
4629 #"
4630 [(set_attr "type" "shift")
4631 (set_attr "dot" "yes")
4632 (set_attr "length" "4,8")])
4633
4634 (define_split
4635 [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
4636 (compare:CC
4637 (zero_extend:SI
4638 (subreg:QI
4639 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "")
4640 (match_operand:SI 2 "const_int_operand" "")) 0))
4641 (const_int 0)))
4642 (clobber (match_scratch:SI 3 ""))]
4643 "!BYTES_BIG_ENDIAN && includes_rshift_p (operands[2], GEN_INT (255)) && reload_completed"
4644 [(set (match_dup 3)
4645 (zero_extend:SI (subreg:QI
4646 (lshiftrt:SI (match_dup 1)
4647 (match_dup 2)) 0)))
4648 (set (match_dup 0)
4649 (compare:CC (match_dup 3)
4650 (const_int 0)))]
4651 "")
4652
4653 (define_split
4654 [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
4655 (compare:CC
4656 (zero_extend:SI
4657 (subreg:QI
4658 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "")
4659 (match_operand:SI 2 "const_int_operand" "")) 3))
4660 (const_int 0)))
4661 (clobber (match_scratch:SI 3 ""))]
4662 "BYTES_BIG_ENDIAN && includes_rshift_p (operands[2], GEN_INT (255)) && reload_completed"
4663 [(set (match_dup 3)
4664 (zero_extend:SI (subreg:QI
4665 (lshiftrt:SI (match_dup 1)
4666 (match_dup 2)) 3)))
4667 (set (match_dup 0)
4668 (compare:CC (match_dup 3)
4669 (const_int 0)))]
4670 "")
4671
4672 (define_insn "*lshiftrt_internal3le"
4673 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4674 (compare:CC
4675 (zero_extend:SI
4676 (subreg:QI
4677 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
4678 (match_operand:SI 2 "const_int_operand" "i,i")) 0))
4679 (const_int 0)))
4680 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
4681 (zero_extend:SI (subreg:QI (lshiftrt:SI (match_dup 1) (match_dup 2)) 0)))]
4682 "!BYTES_BIG_ENDIAN && includes_rshift_p (operands[2], GEN_INT (255))"
4683 "@
4684 rlwinm. %0,%1,%s2,0xff
4685 #"
4686 [(set_attr "type" "shift")
4687 (set_attr "dot" "yes")
4688 (set_attr "length" "4,8")])
4689
4690 (define_insn "*lshiftrt_internal3be"
4691 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4692 (compare:CC
4693 (zero_extend:SI
4694 (subreg:QI
4695 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
4696 (match_operand:SI 2 "const_int_operand" "i,i")) 3))
4697 (const_int 0)))
4698 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
4699 (zero_extend:SI (subreg:QI (lshiftrt:SI (match_dup 1) (match_dup 2)) 3)))]
4700 "BYTES_BIG_ENDIAN && includes_rshift_p (operands[2], GEN_INT (255))"
4701 "@
4702 rlwinm. %0,%1,%s2,0xff
4703 #"
4704 [(set_attr "type" "shift")
4705 (set_attr "dot" "yes")
4706 (set_attr "length" "4,8")])
4707
4708 (define_split
4709 [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "")
4710 (compare:CC
4711 (zero_extend:SI
4712 (subreg:QI
4713 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "")
4714 (match_operand:SI 2 "const_int_operand" "")) 0))
4715 (const_int 0)))
4716 (set (match_operand:SI 0 "gpc_reg_operand" "")
4717 (zero_extend:SI (subreg:QI (lshiftrt:SI (match_dup 1) (match_dup 2)) 0)))]
4718 "!BYTES_BIG_ENDIAN && includes_rshift_p (operands[2], GEN_INT (255)) && reload_completed"
4719 [(set (match_dup 0)
4720 (zero_extend:SI (subreg:QI (lshiftrt:SI (match_dup 1) (match_dup 2)) 0)))
4721 (set (match_dup 3)
4722 (compare:CC (match_dup 0)
4723 (const_int 0)))]
4724 "")
4725
4726 (define_split
4727 [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "")
4728 (compare:CC
4729 (zero_extend:SI
4730 (subreg:QI
4731 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "")
4732 (match_operand:SI 2 "const_int_operand" "")) 3))
4733 (const_int 0)))
4734 (set (match_operand:SI 0 "gpc_reg_operand" "")
4735 (zero_extend:SI (subreg:QI (lshiftrt:SI (match_dup 1) (match_dup 2)) 3)))]
4736 "BYTES_BIG_ENDIAN && includes_rshift_p (operands[2], GEN_INT (255)) && reload_completed"
4737 [(set (match_dup 0)
4738 (zero_extend:SI (subreg:QI (lshiftrt:SI (match_dup 1) (match_dup 2)) 3)))
4739 (set (match_dup 3)
4740 (compare:CC (match_dup 0)
4741 (const_int 0)))]
4742 "")
4743
4744 (define_insn "*lshiftrt_internal4le"
4745 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
4746 (zero_extend:SI
4747 (subreg:HI
4748 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4749 (match_operand:SI 2 "const_int_operand" "i")) 0)))]
4750 "!BYTES_BIG_ENDIAN && includes_rshift_p (operands[2], GEN_INT (65535))"
4751 "rlwinm %0,%1,%s2,0xffff"
4752 [(set_attr "type" "shift")])
4753
4754 (define_insn "*lshiftrt_internal4be"
4755 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
4756 (zero_extend:SI
4757 (subreg:HI
4758 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4759 (match_operand:SI 2 "const_int_operand" "i")) 2)))]
4760 "BYTES_BIG_ENDIAN && includes_rshift_p (operands[2], GEN_INT (65535))"
4761 "rlwinm %0,%1,%s2,0xffff"
4762 [(set_attr "type" "shift")])
4763
4764 (define_insn "*lshiftrt_internal5le"
4765 [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
4766 (compare:CC
4767 (zero_extend:SI
4768 (subreg:HI
4769 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
4770 (match_operand:SI 2 "const_int_operand" "i,i")) 0))
4771 (const_int 0)))
4772 (clobber (match_scratch:SI 3 "=r,r"))]
4773 "!BYTES_BIG_ENDIAN && includes_rshift_p (operands[2], GEN_INT (65535))"
4774 "@
4775 rlwinm. %3,%1,%s2,0xffff
4776 #"
4777 [(set_attr "type" "shift")
4778 (set_attr "dot" "yes")
4779 (set_attr "length" "4,8")])
4780
4781 (define_insn "*lshiftrt_internal5be"
4782 [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
4783 (compare:CC
4784 (zero_extend:SI
4785 (subreg:HI
4786 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
4787 (match_operand:SI 2 "const_int_operand" "i,i")) 2))
4788 (const_int 0)))
4789 (clobber (match_scratch:SI 3 "=r,r"))]
4790 "BYTES_BIG_ENDIAN && includes_rshift_p (operands[2], GEN_INT (65535))"
4791 "@
4792 rlwinm. %3,%1,%s2,0xffff
4793 #"
4794 [(set_attr "type" "shift")
4795 (set_attr "dot" "yes")
4796 (set_attr "length" "4,8")])
4797
4798 (define_split
4799 [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
4800 (compare:CC
4801 (zero_extend:SI
4802 (subreg:HI
4803 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "")
4804 (match_operand:SI 2 "const_int_operand" "")) 0))
4805 (const_int 0)))
4806 (clobber (match_scratch:SI 3 ""))]
4807 "!BYTES_BIG_ENDIAN && includes_rshift_p (operands[2], GEN_INT (65535)) && reload_completed"
4808 [(set (match_dup 3)
4809 (zero_extend:SI (subreg:HI
4810 (lshiftrt:SI (match_dup 1)
4811 (match_dup 2)) 0)))
4812 (set (match_dup 0)
4813 (compare:CC (match_dup 3)
4814 (const_int 0)))]
4815 "")
4816
4817 (define_split
4818 [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
4819 (compare:CC
4820 (zero_extend:SI
4821 (subreg:HI
4822 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "")
4823 (match_operand:SI 2 "const_int_operand" "")) 2))
4824 (const_int 0)))
4825 (clobber (match_scratch:SI 3 ""))]
4826 "BYTES_BIG_ENDIAN && includes_rshift_p (operands[2], GEN_INT (65535)) && reload_completed"
4827 [(set (match_dup 3)
4828 (zero_extend:SI (subreg:HI
4829 (lshiftrt:SI (match_dup 1)
4830 (match_dup 2)) 2)))
4831 (set (match_dup 0)
4832 (compare:CC (match_dup 3)
4833 (const_int 0)))]
4834 "")
4835
4836 (define_insn "*lshiftrt_internal5le"
4837 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4838 (compare:CC
4839 (zero_extend:SI
4840 (subreg:HI
4841 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
4842 (match_operand:SI 2 "const_int_operand" "i,i")) 0))
4843 (const_int 0)))
4844 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
4845 (zero_extend:SI (subreg:HI (lshiftrt:SI (match_dup 1) (match_dup 2)) 0)))]
4846 "!BYTES_BIG_ENDIAN && includes_rshift_p (operands[2], GEN_INT (65535))"
4847 "@
4848 rlwinm. %0,%1,%s2,0xffff
4849 #"
4850 [(set_attr "type" "shift")
4851 (set_attr "dot" "yes")
4852 (set_attr "length" "4,8")])
4853
4854 (define_insn "*lshiftrt_internal5be"
4855 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4856 (compare:CC
4857 (zero_extend:SI
4858 (subreg:HI
4859 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
4860 (match_operand:SI 2 "const_int_operand" "i,i")) 2))
4861 (const_int 0)))
4862 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
4863 (zero_extend:SI (subreg:HI (lshiftrt:SI (match_dup 1) (match_dup 2)) 2)))]
4864 "BYTES_BIG_ENDIAN && includes_rshift_p (operands[2], GEN_INT (65535))"
4865 "@
4866 rlwinm. %0,%1,%s2,0xffff
4867 #"
4868 [(set_attr "type" "shift")
4869 (set_attr "dot" "yes")
4870 (set_attr "length" "4,8")])
4871
4872 (define_split
4873 [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "")
4874 (compare:CC
4875 (zero_extend:SI
4876 (subreg:HI
4877 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "")
4878 (match_operand:SI 2 "const_int_operand" "")) 0))
4879 (const_int 0)))
4880 (set (match_operand:SI 0 "gpc_reg_operand" "")
4881 (zero_extend:SI (subreg:HI (lshiftrt:SI (match_dup 1) (match_dup 2)) 0)))]
4882 "!BYTES_BIG_ENDIAN && includes_rshift_p (operands[2], GEN_INT (65535)) && reload_completed"
4883 [(set (match_dup 0)
4884 (zero_extend:SI (subreg:HI (lshiftrt:SI (match_dup 1) (match_dup 2)) 0)))
4885 (set (match_dup 3)
4886 (compare:CC (match_dup 0)
4887 (const_int 0)))]
4888 "")
4889
4890 (define_split
4891 [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "")
4892 (compare:CC
4893 (zero_extend:SI
4894 (subreg:HI
4895 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "")
4896 (match_operand:SI 2 "const_int_operand" "")) 2))
4897 (const_int 0)))
4898 (set (match_operand:SI 0 "gpc_reg_operand" "")
4899 (zero_extend:SI (subreg:HI (lshiftrt:SI (match_dup 1) (match_dup 2)) 2)))]
4900 "BYTES_BIG_ENDIAN && includes_rshift_p (operands[2], GEN_INT (65535)) && reload_completed"
4901 [(set (match_dup 0)
4902 (zero_extend:SI (subreg:HI (lshiftrt:SI (match_dup 1) (match_dup 2)) 2)))
4903 (set (match_dup 3)
4904 (compare:CC (match_dup 0)
4905 (const_int 0)))]
4906 "")
4907
4908
4909 (define_expand "ashr<mode>3"
4910 [(parallel [(set (match_operand:GPR 0 "gpc_reg_operand" "")
4911 (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
4912 (match_operand:SI 2 "reg_or_cint_operand" "")))
4913 (clobber (reg:GPR CA_REGNO))])]
4914 ""
4915 {
4916 /* The generic code does not generate optimal code for the low word
4917 (it should be a rlwimi and a rot). Until we have target code to
4918 solve this generically, keep this expander. */
4919
4920 if (<MODE>mode == DImode && !TARGET_POWERPC64)
4921 {
4922 if (CONST_INT_P (operands[2]))
4923 {
4924 emit_insn (gen_ashrdi3_no_power (operands[0], operands[1], operands[2]));
4925 DONE;
4926 }
4927 else
4928 FAIL;
4929 }
4930 })
4931
4932 (define_insn "*ashr<mode>3"
4933 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4934 (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4935 (match_operand:SI 2 "reg_or_cint_operand" "rn")))
4936 (clobber (reg:GPR CA_REGNO))]
4937 ""
4938 "sra<wd>%I2 %0,%1,%<hH>2"
4939 [(set_attr "type" "shift")
4940 (set_attr "maybe_var_shift" "yes")])
4941
4942 (define_insn "*ashrsi3_64"
4943 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4944 (sign_extend:DI
4945 (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4946 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))
4947 (clobber (reg:SI CA_REGNO))]
4948 "TARGET_POWERPC64"
4949 "sraw%I2 %0,%1,%h2"
4950 [(set_attr "type" "shift")
4951 (set_attr "maybe_var_shift" "yes")])
4952
4953 (define_insn_and_split "*ashr<mode>3_dot"
4954 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4955 (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4956 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4957 (const_int 0)))
4958 (clobber (match_scratch:GPR 0 "=r,r"))
4959 (clobber (reg:GPR CA_REGNO))]
4960 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4961 "@
4962 sra<wd>%I2. %0,%1,%<hH>2
4963 #"
4964 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4965 [(parallel [(set (match_dup 0)
4966 (ashiftrt:GPR (match_dup 1)
4967 (match_dup 2)))
4968 (clobber (reg:GPR CA_REGNO))])
4969 (set (match_dup 3)
4970 (compare:CC (match_dup 0)
4971 (const_int 0)))]
4972 ""
4973 [(set_attr "type" "shift")
4974 (set_attr "maybe_var_shift" "yes")
4975 (set_attr "dot" "yes")
4976 (set_attr "length" "4,8")])
4977
4978 (define_insn_and_split "*ashr<mode>3_dot2"
4979 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4980 (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4981 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4982 (const_int 0)))
4983 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4984 (ashiftrt:GPR (match_dup 1)
4985 (match_dup 2)))
4986 (clobber (reg:GPR CA_REGNO))]
4987 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4988 "@
4989 sra<wd>%I2. %0,%1,%<hH>2
4990 #"
4991 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4992 [(parallel [(set (match_dup 0)
4993 (ashiftrt:GPR (match_dup 1)
4994 (match_dup 2)))
4995 (clobber (reg:GPR CA_REGNO))])
4996 (set (match_dup 3)
4997 (compare:CC (match_dup 0)
4998 (const_int 0)))]
4999 ""
5000 [(set_attr "type" "shift")
5001 (set_attr "maybe_var_shift" "yes")
5002 (set_attr "dot" "yes")
5003 (set_attr "length" "4,8")])
5004 \f
5005 ;; Builtins to replace a division to generate FRE reciprocal estimate
5006 ;; instructions and the necessary fixup instructions
5007 (define_expand "recip<mode>3"
5008 [(match_operand:RECIPF 0 "gpc_reg_operand" "")
5009 (match_operand:RECIPF 1 "gpc_reg_operand" "")
5010 (match_operand:RECIPF 2 "gpc_reg_operand" "")]
5011 "RS6000_RECIP_HAVE_RE_P (<MODE>mode)"
5012 {
5013 rs6000_emit_swdiv (operands[0], operands[1], operands[2], false);
5014 DONE;
5015 })
5016
5017 ;; Split to create division from FRE/FRES/etc. and fixup instead of the normal
5018 ;; hardware division. This is only done before register allocation and with
5019 ;; -ffast-math. This must appear before the divsf3/divdf3 insns.
5020 (define_split
5021 [(set (match_operand:RECIPF 0 "gpc_reg_operand" "")
5022 (div:RECIPF (match_operand 1 "gpc_reg_operand" "")
5023 (match_operand 2 "gpc_reg_operand" "")))]
5024 "RS6000_RECIP_AUTO_RE_P (<MODE>mode)
5025 && can_create_pseudo_p () && optimize_insn_for_speed_p ()
5026 && flag_finite_math_only && !flag_trapping_math && flag_reciprocal_math"
5027 [(const_int 0)]
5028 {
5029 rs6000_emit_swdiv (operands[0], operands[1], operands[2], true);
5030 DONE;
5031 })
5032
5033 ;; Builtins to replace 1/sqrt(x) with instructions using RSQRTE and the
5034 ;; appropriate fixup.
5035 (define_expand "rsqrt<mode>2"
5036 [(match_operand:RECIPF 0 "gpc_reg_operand" "")
5037 (match_operand:RECIPF 1 "gpc_reg_operand" "")]
5038 "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
5039 {
5040 rs6000_emit_swrsqrt (operands[0], operands[1]);
5041 DONE;
5042 })
5043 \f
5044 ;; Floating-point insns, excluding normal data motion. We combine the SF/DF
5045 ;; modes here, and also add in conditional vsx/power8-vector support to access
5046 ;; values in the traditional Altivec registers if the appropriate
5047 ;; -mupper-regs-{df,sf} option is enabled.
5048
5049 (define_expand "abs<mode>2"
5050 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
5051 (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))]
5052 "TARGET_<MODE>_INSN"
5053 "")
5054
5055 (define_insn "*abs<mode>2_fpr"
5056 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5057 (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
5058 "TARGET_<MODE>_FPR"
5059 "@
5060 fabs %0,%1
5061 xsabsdp %x0,%x1"
5062 [(set_attr "type" "fp")
5063 (set_attr "fp_type" "fp_addsub_<Fs>")])
5064
5065 (define_insn "*nabs<mode>2_fpr"
5066 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5067 (neg:SFDF
5068 (abs:SFDF
5069 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))))]
5070 "TARGET_<MODE>_FPR"
5071 "@
5072 fnabs %0,%1
5073 xsnabsdp %x0,%x1"
5074 [(set_attr "type" "fp")
5075 (set_attr "fp_type" "fp_addsub_<Fs>")])
5076
5077 (define_expand "neg<mode>2"
5078 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
5079 (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))]
5080 "TARGET_<MODE>_INSN"
5081 "")
5082
5083 (define_insn "*neg<mode>2_fpr"
5084 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5085 (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
5086 "TARGET_<MODE>_FPR"
5087 "@
5088 fneg %0,%1
5089 xsnegdp %x0,%x1"
5090 [(set_attr "type" "fp")
5091 (set_attr "fp_type" "fp_addsub_<Fs>")])
5092
5093 (define_expand "add<mode>3"
5094 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
5095 (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
5096 (match_operand:SFDF 2 "gpc_reg_operand" "")))]
5097 "TARGET_<MODE>_INSN"
5098 "")
5099
5100 (define_insn "*add<mode>3_fpr"
5101 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5102 (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv>")
5103 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")))]
5104 "TARGET_<MODE>_FPR"
5105 "@
5106 fadd<Ftrad> %0,%1,%2
5107 xsadd<Fvsx> %x0,%x1,%x2"
5108 [(set_attr "type" "fp")
5109 (set_attr "fp_type" "fp_addsub_<Fs>")])
5110
5111 (define_expand "sub<mode>3"
5112 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
5113 (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
5114 (match_operand:SFDF 2 "gpc_reg_operand" "")))]
5115 "TARGET_<MODE>_INSN"
5116 "")
5117
5118 (define_insn "*sub<mode>3_fpr"
5119 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5120 (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")
5121 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")))]
5122 "TARGET_<MODE>_FPR"
5123 "@
5124 fsub<Ftrad> %0,%1,%2
5125 xssub<Fvsx> %x0,%x1,%x2"
5126 [(set_attr "type" "fp")
5127 (set_attr "fp_type" "fp_addsub_<Fs>")])
5128
5129 (define_expand "mul<mode>3"
5130 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
5131 (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
5132 (match_operand:SFDF 2 "gpc_reg_operand" "")))]
5133 "TARGET_<MODE>_INSN"
5134 "")
5135
5136 (define_insn "*mul<mode>3_fpr"
5137 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5138 (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv>")
5139 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")))]
5140 "TARGET_<MODE>_FPR"
5141 "@
5142 fmul<Ftrad> %0,%1,%2
5143 xsmul<Fvsx> %x0,%x1,%x2"
5144 [(set_attr "type" "dmul")
5145 (set_attr "fp_type" "fp_mul_<Fs>")])
5146
5147 (define_expand "div<mode>3"
5148 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
5149 (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
5150 (match_operand:SFDF 2 "gpc_reg_operand" "")))]
5151 "TARGET_<MODE>_INSN && !TARGET_SIMPLE_FPU"
5152 "")
5153
5154 (define_insn "*div<mode>3_fpr"
5155 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5156 (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")
5157 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")))]
5158 "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU"
5159 "@
5160 fdiv<Ftrad> %0,%1,%2
5161 xsdiv<Fvsx> %x0,%x1,%x2"
5162 [(set_attr "type" "<Fs>div")
5163 (set_attr "fp_type" "fp_div_<Fs>")])
5164
5165 (define_insn "sqrt<mode>2"
5166 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5167 (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
5168 "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU
5169 && (TARGET_PPC_GPOPT || (<MODE>mode == SFmode && TARGET_XILINX_FPU))"
5170 "@
5171 fsqrt<Ftrad> %0,%1
5172 xssqrt<Fvsx> %x0,%x1"
5173 [(set_attr "type" "<Fs>sqrt")
5174 (set_attr "fp_type" "fp_sqrt_<Fs>")])
5175
5176 ;; Floating point reciprocal approximation
5177 (define_insn "fre<Fs>"
5178 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5179 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
5180 UNSPEC_FRES))]
5181 "TARGET_<FFRE>"
5182 "@
5183 fre<Ftrad> %0,%1
5184 xsre<Fvsx> %x0,%x1"
5185 [(set_attr "type" "fp")])
5186
5187 (define_insn "*rsqrt<mode>2"
5188 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5189 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
5190 UNSPEC_RSQRT))]
5191 "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
5192 "@
5193 frsqrte<Ftrad> %0,%1
5194 xsrsqrte<Fvsx> %x0,%x1"
5195 [(set_attr "type" "fp")])
5196
5197 ;; Floating point comparisons
5198 (define_insn "*cmp<mode>_fpr"
5199 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y,y")
5200 (compare:CCFP (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")
5201 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")))]
5202 "TARGET_<MODE>_FPR"
5203 "@
5204 fcmpu %0,%1,%2
5205 xscmpudp %0,%x1,%x2"
5206 [(set_attr "type" "fpcompare")])
5207
5208 ;; Floating point conversions
5209 (define_expand "extendsfdf2"
5210 [(set (match_operand:DF 0 "gpc_reg_operand" "")
5211 (float_extend:DF (match_operand:SF 1 "reg_or_none500mem_operand" "")))]
5212 "TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
5213 "")
5214
5215 (define_insn_and_split "*extendsfdf2_fpr"
5216 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d,d,ws,?ws,wu")
5217 (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand" "0,f,m,0,wy,Z")))]
5218 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
5219 "@
5220 #
5221 fmr %0,%1
5222 lfs%U1%X1 %0,%1
5223 #
5224 xxlor %x0,%x1,%x1
5225 lxsspx %x0,%y1"
5226 "&& reload_completed && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1])"
5227 [(const_int 0)]
5228 {
5229 emit_note (NOTE_INSN_DELETED);
5230 DONE;
5231 }
5232 [(set_attr "type" "fp,fp,fpload,fp,vecsimple,fpload")])
5233
5234 (define_expand "truncdfsf2"
5235 [(set (match_operand:SF 0 "gpc_reg_operand" "")
5236 (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "")))]
5237 "TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
5238 "")
5239
5240 (define_insn "*truncdfsf2_fpr"
5241 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
5242 (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "d")))]
5243 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
5244 "frsp %0,%1"
5245 [(set_attr "type" "fp")])
5246
5247 ;; This expander is here to avoid FLOAT_WORDS_BIGENDIAN tests in
5248 ;; builtins.c and optabs.c that are not correct for IBM long double
5249 ;; when little-endian.
5250 (define_expand "signbittf2"
5251 [(set (match_dup 2)
5252 (float_truncate:DF (match_operand:TF 1 "gpc_reg_operand" "")))
5253 (set (match_dup 3)
5254 (subreg:DI (match_dup 2) 0))
5255 (set (match_dup 4)
5256 (match_dup 5))
5257 (set (match_operand:SI 0 "gpc_reg_operand" "")
5258 (match_dup 6))]
5259 "!TARGET_IEEEQUAD
5260 && TARGET_HARD_FLOAT
5261 && (TARGET_FPRS || TARGET_E500_DOUBLE)
5262 && TARGET_LONG_DOUBLE_128"
5263 {
5264 operands[2] = gen_reg_rtx (DFmode);
5265 operands[3] = gen_reg_rtx (DImode);
5266 if (TARGET_POWERPC64)
5267 {
5268 operands[4] = gen_reg_rtx (DImode);
5269 operands[5] = gen_rtx_LSHIFTRT (DImode, operands[3], GEN_INT (63));
5270 operands[6] = gen_rtx_SUBREG (SImode, operands[4],
5271 WORDS_BIG_ENDIAN ? 4 : 0);
5272 }
5273 else
5274 {
5275 operands[4] = gen_reg_rtx (SImode);
5276 operands[5] = gen_rtx_SUBREG (SImode, operands[3],
5277 WORDS_BIG_ENDIAN ? 0 : 4);
5278 operands[6] = gen_rtx_LSHIFTRT (SImode, operands[4], GEN_INT (31));
5279 }
5280 })
5281
5282 (define_expand "copysign<mode>3"
5283 [(set (match_dup 3)
5284 (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))
5285 (set (match_dup 4)
5286 (neg:SFDF (abs:SFDF (match_dup 1))))
5287 (set (match_operand:SFDF 0 "gpc_reg_operand" "")
5288 (if_then_else:SFDF (ge (match_operand:SFDF 2 "gpc_reg_operand" "")
5289 (match_dup 5))
5290 (match_dup 3)
5291 (match_dup 4)))]
5292 "TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT>
5293 && ((TARGET_PPC_GFXOPT
5294 && !HONOR_NANS (<MODE>mode)
5295 && !HONOR_SIGNED_ZEROS (<MODE>mode))
5296 || TARGET_CMPB
5297 || VECTOR_UNIT_VSX_P (<MODE>mode))"
5298 {
5299 if (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode))
5300 {
5301 emit_insn (gen_copysign<mode>3_fcpsgn (operands[0], operands[1],
5302 operands[2]));
5303 DONE;
5304 }
5305
5306 operands[3] = gen_reg_rtx (<MODE>mode);
5307 operands[4] = gen_reg_rtx (<MODE>mode);
5308 operands[5] = CONST0_RTX (<MODE>mode);
5309 })
5310
5311 ;; Use an unspec rather providing an if-then-else in RTL, to prevent the
5312 ;; compiler from optimizing -0.0
5313 (define_insn "copysign<mode>3_fcpsgn"
5314 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5315 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")
5316 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")]
5317 UNSPEC_COPYSIGN))]
5318 "TARGET_<MODE>_FPR && TARGET_CMPB"
5319 "@
5320 fcpsgn %0,%2,%1
5321 xscpsgndp %x0,%x2,%x1"
5322 [(set_attr "type" "fp")])
5323
5324 ;; For MIN, MAX, and conditional move, we use DEFINE_EXPAND's that involve a
5325 ;; fsel instruction and some auxiliary computations. Then we just have a
5326 ;; single DEFINE_INSN for fsel and the define_splits to make them if made by
5327 ;; combine.
5328 ;; For MIN, MAX on non-VSX machines, and conditional move all of the time, we
5329 ;; use DEFINE_EXPAND's that involve a fsel instruction and some auxiliary
5330 ;; computations. Then we just have a single DEFINE_INSN for fsel and the
5331 ;; define_splits to make them if made by combine. On VSX machines we have the
5332 ;; min/max instructions.
5333 ;;
5334 ;; On VSX, we only check for TARGET_VSX instead of checking for a vsx/p8 vector
5335 ;; to allow either DF/SF to use only traditional registers.
5336
5337 (define_expand "smax<mode>3"
5338 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
5339 (if_then_else:SFDF (ge (match_operand:SFDF 1 "gpc_reg_operand" "")
5340 (match_operand:SFDF 2 "gpc_reg_operand" ""))
5341 (match_dup 1)
5342 (match_dup 2)))]
5343 "TARGET_<MODE>_FPR && TARGET_PPC_GFXOPT && !flag_trapping_math"
5344 {
5345 rs6000_emit_minmax (operands[0], SMAX, operands[1], operands[2]);
5346 DONE;
5347 })
5348
5349 (define_insn "*smax<mode>3_vsx"
5350 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5351 (smax:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv>")
5352 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")))]
5353 "TARGET_<MODE>_FPR && TARGET_VSX"
5354 "xsmaxdp %x0,%x1,%x2"
5355 [(set_attr "type" "fp")])
5356
5357 (define_expand "smin<mode>3"
5358 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
5359 (if_then_else:SFDF (ge (match_operand:SFDF 1 "gpc_reg_operand" "")
5360 (match_operand:SFDF 2 "gpc_reg_operand" ""))
5361 (match_dup 2)
5362 (match_dup 1)))]
5363 "TARGET_<MODE>_FPR && TARGET_PPC_GFXOPT && !flag_trapping_math"
5364 {
5365 rs6000_emit_minmax (operands[0], SMIN, operands[1], operands[2]);
5366 DONE;
5367 })
5368
5369 (define_insn "*smin<mode>3_vsx"
5370 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5371 (smin:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv>")
5372 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")))]
5373 "TARGET_<MODE>_FPR && TARGET_VSX"
5374 "xsmindp %x0,%x1,%x2"
5375 [(set_attr "type" "fp")])
5376
5377 (define_split
5378 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
5379 (match_operator:SFDF 3 "min_max_operator"
5380 [(match_operand:SFDF 1 "gpc_reg_operand" "")
5381 (match_operand:SFDF 2 "gpc_reg_operand" "")]))]
5382 "TARGET_<MODE>_FPR && TARGET_PPC_GFXOPT && !flag_trapping_math
5383 && !TARGET_VSX"
5384 [(const_int 0)]
5385 {
5386 rs6000_emit_minmax (operands[0], GET_CODE (operands[3]), operands[1],
5387 operands[2]);
5388 DONE;
5389 })
5390
5391 (define_split
5392 [(set (match_operand:SF 0 "gpc_reg_operand" "")
5393 (match_operator:SF 3 "min_max_operator"
5394 [(match_operand:SF 1 "gpc_reg_operand" "")
5395 (match_operand:SF 2 "gpc_reg_operand" "")]))]
5396 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS
5397 && TARGET_SINGLE_FLOAT && !flag_trapping_math"
5398 [(const_int 0)]
5399 "
5400 { rs6000_emit_minmax (operands[0], GET_CODE (operands[3]),
5401 operands[1], operands[2]);
5402 DONE;
5403 }")
5404
5405 (define_expand "mov<mode>cc"
5406 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
5407 (if_then_else:GPR (match_operand 1 "comparison_operator" "")
5408 (match_operand:GPR 2 "gpc_reg_operand" "")
5409 (match_operand:GPR 3 "gpc_reg_operand" "")))]
5410 "TARGET_ISEL<sel>"
5411 "
5412 {
5413 if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
5414 DONE;
5415 else
5416 FAIL;
5417 }")
5418
5419 ;; We use the BASE_REGS for the isel input operands because, if rA is
5420 ;; 0, the value of 0 is placed in rD upon truth. Similarly for rB
5421 ;; because we may switch the operands and rB may end up being rA.
5422 ;;
5423 ;; We need 2 patterns: an unsigned and a signed pattern. We could
5424 ;; leave out the mode in operand 4 and use one pattern, but reload can
5425 ;; change the mode underneath our feet and then gets confused trying
5426 ;; to reload the value.
5427 (define_insn "isel_signed_<mode>"
5428 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
5429 (if_then_else:GPR
5430 (match_operator 1 "scc_comparison_operator"
5431 [(match_operand:CC 4 "cc_reg_operand" "y,y")
5432 (const_int 0)])
5433 (match_operand:GPR 2 "reg_or_cint_operand" "O,b")
5434 (match_operand:GPR 3 "gpc_reg_operand" "r,r")))]
5435 "TARGET_ISEL<sel>"
5436 "*
5437 { return output_isel (operands); }"
5438 [(set_attr "type" "isel")
5439 (set_attr "length" "4")])
5440
5441 (define_insn "isel_unsigned_<mode>"
5442 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
5443 (if_then_else:GPR
5444 (match_operator 1 "scc_comparison_operator"
5445 [(match_operand:CCUNS 4 "cc_reg_operand" "y,y")
5446 (const_int 0)])
5447 (match_operand:GPR 2 "reg_or_cint_operand" "O,b")
5448 (match_operand:GPR 3 "gpc_reg_operand" "r,r")))]
5449 "TARGET_ISEL<sel>"
5450 "*
5451 { return output_isel (operands); }"
5452 [(set_attr "type" "isel")
5453 (set_attr "length" "4")])
5454
5455 ;; These patterns can be useful for combine; they let combine know that
5456 ;; isel can handle reversed comparisons so long as the operands are
5457 ;; registers.
5458
5459 (define_insn "*isel_reversed_signed_<mode>"
5460 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
5461 (if_then_else:GPR
5462 (match_operator 1 "scc_rev_comparison_operator"
5463 [(match_operand:CC 4 "cc_reg_operand" "y")
5464 (const_int 0)])
5465 (match_operand:GPR 2 "gpc_reg_operand" "b")
5466 (match_operand:GPR 3 "gpc_reg_operand" "b")))]
5467 "TARGET_ISEL<sel>"
5468 "*
5469 { return output_isel (operands); }"
5470 [(set_attr "type" "isel")
5471 (set_attr "length" "4")])
5472
5473 (define_insn "*isel_reversed_unsigned_<mode>"
5474 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
5475 (if_then_else:GPR
5476 (match_operator 1 "scc_rev_comparison_operator"
5477 [(match_operand:CCUNS 4 "cc_reg_operand" "y")
5478 (const_int 0)])
5479 (match_operand:GPR 2 "gpc_reg_operand" "b")
5480 (match_operand:GPR 3 "gpc_reg_operand" "b")))]
5481 "TARGET_ISEL<sel>"
5482 "*
5483 { return output_isel (operands); }"
5484 [(set_attr "type" "isel")
5485 (set_attr "length" "4")])
5486
5487 (define_expand "movsfcc"
5488 [(set (match_operand:SF 0 "gpc_reg_operand" "")
5489 (if_then_else:SF (match_operand 1 "comparison_operator" "")
5490 (match_operand:SF 2 "gpc_reg_operand" "")
5491 (match_operand:SF 3 "gpc_reg_operand" "")))]
5492 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT"
5493 "
5494 {
5495 if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
5496 DONE;
5497 else
5498 FAIL;
5499 }")
5500
5501 (define_insn "*fselsfsf4"
5502 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
5503 (if_then_else:SF (ge (match_operand:SF 1 "gpc_reg_operand" "f")
5504 (match_operand:SF 4 "zero_fp_constant" "F"))
5505 (match_operand:SF 2 "gpc_reg_operand" "f")
5506 (match_operand:SF 3 "gpc_reg_operand" "f")))]
5507 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT"
5508 "fsel %0,%1,%2,%3"
5509 [(set_attr "type" "fp")])
5510
5511 (define_insn "*fseldfsf4"
5512 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
5513 (if_then_else:SF (ge (match_operand:DF 1 "gpc_reg_operand" "d")
5514 (match_operand:DF 4 "zero_fp_constant" "F"))
5515 (match_operand:SF 2 "gpc_reg_operand" "f")
5516 (match_operand:SF 3 "gpc_reg_operand" "f")))]
5517 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_SINGLE_FLOAT"
5518 "fsel %0,%1,%2,%3"
5519 [(set_attr "type" "fp")])
5520
5521 ;; The conditional move instructions allow us to perform max and min
5522 ;; operations even when
5523
5524 (define_split
5525 [(set (match_operand:DF 0 "gpc_reg_operand" "")
5526 (match_operator:DF 3 "min_max_operator"
5527 [(match_operand:DF 1 "gpc_reg_operand" "")
5528 (match_operand:DF 2 "gpc_reg_operand" "")]))]
5529 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5530 && !flag_trapping_math"
5531 [(const_int 0)]
5532 "
5533 { rs6000_emit_minmax (operands[0], GET_CODE (operands[3]),
5534 operands[1], operands[2]);
5535 DONE;
5536 }")
5537
5538 (define_expand "movdfcc"
5539 [(set (match_operand:DF 0 "gpc_reg_operand" "")
5540 (if_then_else:DF (match_operand 1 "comparison_operator" "")
5541 (match_operand:DF 2 "gpc_reg_operand" "")
5542 (match_operand:DF 3 "gpc_reg_operand" "")))]
5543 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
5544 "
5545 {
5546 if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
5547 DONE;
5548 else
5549 FAIL;
5550 }")
5551
5552 (define_insn "*fseldfdf4"
5553 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
5554 (if_then_else:DF (ge (match_operand:DF 1 "gpc_reg_operand" "d")
5555 (match_operand:DF 4 "zero_fp_constant" "F"))
5556 (match_operand:DF 2 "gpc_reg_operand" "d")
5557 (match_operand:DF 3 "gpc_reg_operand" "d")))]
5558 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
5559 "fsel %0,%1,%2,%3"
5560 [(set_attr "type" "fp")])
5561
5562 (define_insn "*fselsfdf4"
5563 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
5564 (if_then_else:DF (ge (match_operand:SF 1 "gpc_reg_operand" "f")
5565 (match_operand:SF 4 "zero_fp_constant" "F"))
5566 (match_operand:DF 2 "gpc_reg_operand" "d")
5567 (match_operand:DF 3 "gpc_reg_operand" "d")))]
5568 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_SINGLE_FLOAT"
5569 "fsel %0,%1,%2,%3"
5570 [(set_attr "type" "fp")])
5571 \f
5572 ;; Conversions to and from floating-point.
5573
5574 ; We don't define lfiwax/lfiwzx with the normal definition, because we
5575 ; don't want to support putting SImode in FPR registers.
5576 (define_insn "lfiwax"
5577 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wj,!wj")
5578 (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r")]
5579 UNSPEC_LFIWAX))]
5580 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX"
5581 "@
5582 lfiwax %0,%y1
5583 lxsiwax %x0,%y1
5584 mtvsrwa %x0,%1"
5585 [(set_attr "type" "fpload,fpload,mffgpr")])
5586
5587 ; This split must be run before register allocation because it allocates the
5588 ; memory slot that is needed to move values to/from the FPR. We don't allocate
5589 ; it earlier to allow for the combiner to merge insns together where it might
5590 ; not be needed and also in case the insns are deleted as dead code.
5591
5592 (define_insn_and_split "floatsi<mode>2_lfiwax"
5593 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5594 (float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r")))
5595 (clobber (match_scratch:DI 2 "=wj"))]
5596 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX
5597 && <SI_CONVERT_FP> && can_create_pseudo_p ()"
5598 "#"
5599 ""
5600 [(pc)]
5601 "
5602 {
5603 rtx dest = operands[0];
5604 rtx src = operands[1];
5605 rtx tmp;
5606
5607 if (!MEM_P (src) && TARGET_POWERPC64
5608 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5609 tmp = convert_to_mode (DImode, src, false);
5610 else
5611 {
5612 tmp = operands[2];
5613 if (GET_CODE (tmp) == SCRATCH)
5614 tmp = gen_reg_rtx (DImode);
5615 if (MEM_P (src))
5616 {
5617 src = rs6000_address_for_fpconvert (src);
5618 emit_insn (gen_lfiwax (tmp, src));
5619 }
5620 else
5621 {
5622 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5623 emit_move_insn (stack, src);
5624 emit_insn (gen_lfiwax (tmp, stack));
5625 }
5626 }
5627 emit_insn (gen_floatdi<mode>2 (dest, tmp));
5628 DONE;
5629 }"
5630 [(set_attr "length" "12")
5631 (set_attr "type" "fpload")])
5632
5633 (define_insn_and_split "floatsi<mode>2_lfiwax_mem"
5634 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fa>")
5635 (float:SFDF
5636 (sign_extend:DI
5637 (match_operand:SI 1 "indexed_or_indirect_operand" "Z,Z"))))
5638 (clobber (match_scratch:DI 2 "=0,d"))]
5639 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX
5640 && <SI_CONVERT_FP>"
5641 "#"
5642 ""
5643 [(pc)]
5644 "
5645 {
5646 operands[1] = rs6000_address_for_fpconvert (operands[1]);
5647 if (GET_CODE (operands[2]) == SCRATCH)
5648 operands[2] = gen_reg_rtx (DImode);
5649 emit_insn (gen_lfiwax (operands[2], operands[1]));
5650 emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
5651 DONE;
5652 }"
5653 [(set_attr "length" "8")
5654 (set_attr "type" "fpload")])
5655
5656 (define_insn "lfiwzx"
5657 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wj,!wj")
5658 (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r")]
5659 UNSPEC_LFIWZX))]
5660 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX"
5661 "@
5662 lfiwzx %0,%y1
5663 lxsiwzx %x0,%y1
5664 mtvsrwz %x0,%1"
5665 [(set_attr "type" "fpload,fpload,mftgpr")])
5666
5667 (define_insn_and_split "floatunssi<mode>2_lfiwzx"
5668 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5669 (unsigned_float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r")))
5670 (clobber (match_scratch:DI 2 "=wj"))]
5671 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX
5672 && <SI_CONVERT_FP>"
5673 "#"
5674 ""
5675 [(pc)]
5676 "
5677 {
5678 rtx dest = operands[0];
5679 rtx src = operands[1];
5680 rtx tmp;
5681
5682 if (!MEM_P (src) && TARGET_POWERPC64
5683 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5684 tmp = convert_to_mode (DImode, src, true);
5685 else
5686 {
5687 tmp = operands[2];
5688 if (GET_CODE (tmp) == SCRATCH)
5689 tmp = gen_reg_rtx (DImode);
5690 if (MEM_P (src))
5691 {
5692 src = rs6000_address_for_fpconvert (src);
5693 emit_insn (gen_lfiwzx (tmp, src));
5694 }
5695 else
5696 {
5697 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5698 emit_move_insn (stack, src);
5699 emit_insn (gen_lfiwzx (tmp, stack));
5700 }
5701 }
5702 emit_insn (gen_floatdi<mode>2 (dest, tmp));
5703 DONE;
5704 }"
5705 [(set_attr "length" "12")
5706 (set_attr "type" "fpload")])
5707
5708 (define_insn_and_split "floatunssi<mode>2_lfiwzx_mem"
5709 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fa>")
5710 (unsigned_float:SFDF
5711 (zero_extend:DI
5712 (match_operand:SI 1 "indexed_or_indirect_operand" "Z,Z"))))
5713 (clobber (match_scratch:DI 2 "=0,d"))]
5714 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX
5715 && <SI_CONVERT_FP>"
5716 "#"
5717 ""
5718 [(pc)]
5719 "
5720 {
5721 operands[1] = rs6000_address_for_fpconvert (operands[1]);
5722 if (GET_CODE (operands[2]) == SCRATCH)
5723 operands[2] = gen_reg_rtx (DImode);
5724 emit_insn (gen_lfiwzx (operands[2], operands[1]));
5725 emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
5726 DONE;
5727 }"
5728 [(set_attr "length" "8")
5729 (set_attr "type" "fpload")])
5730
5731 ; For each of these conversions, there is a define_expand, a define_insn
5732 ; with a '#' template, and a define_split (with C code). The idea is
5733 ; to allow constant folding with the template of the define_insn,
5734 ; then to have the insns split later (between sched1 and final).
5735
5736 (define_expand "floatsidf2"
5737 [(parallel [(set (match_operand:DF 0 "gpc_reg_operand" "")
5738 (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))
5739 (use (match_dup 2))
5740 (use (match_dup 3))
5741 (clobber (match_dup 4))
5742 (clobber (match_dup 5))
5743 (clobber (match_dup 6))])]
5744 "TARGET_HARD_FLOAT
5745 && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
5746 "
5747 {
5748 if (TARGET_E500_DOUBLE)
5749 {
5750 if (!REG_P (operands[1]))
5751 operands[1] = force_reg (SImode, operands[1]);
5752 emit_insn (gen_spe_floatsidf2 (operands[0], operands[1]));
5753 DONE;
5754 }
5755 else if (TARGET_LFIWAX && TARGET_FCFID)
5756 {
5757 emit_insn (gen_floatsidf2_lfiwax (operands[0], operands[1]));
5758 DONE;
5759 }
5760 else if (TARGET_FCFID)
5761 {
5762 rtx dreg = operands[1];
5763 if (!REG_P (dreg))
5764 dreg = force_reg (SImode, dreg);
5765 dreg = convert_to_mode (DImode, dreg, false);
5766 emit_insn (gen_floatdidf2 (operands[0], dreg));
5767 DONE;
5768 }
5769
5770 if (!REG_P (operands[1]))
5771 operands[1] = force_reg (SImode, operands[1]);
5772 operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5773 operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503601774854144\", DFmode));
5774 operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5775 operands[5] = gen_reg_rtx (DFmode);
5776 operands[6] = gen_reg_rtx (SImode);
5777 }")
5778
5779 (define_insn_and_split "*floatsidf2_internal"
5780 [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5781 (float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5782 (use (match_operand:SI 2 "gpc_reg_operand" "r"))
5783 (use (match_operand:DF 3 "gpc_reg_operand" "d"))
5784 (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
5785 (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))
5786 (clobber (match_operand:SI 6 "gpc_reg_operand" "=&r"))]
5787 "! TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
5788 "#"
5789 ""
5790 [(pc)]
5791 "
5792 {
5793 rtx lowword, highword;
5794 gcc_assert (MEM_P (operands[4]));
5795 highword = adjust_address (operands[4], SImode, 0);
5796 lowword = adjust_address (operands[4], SImode, 4);
5797 if (! WORDS_BIG_ENDIAN)
5798 std::swap (lowword, highword);
5799
5800 emit_insn (gen_xorsi3 (operands[6], operands[1],
5801 GEN_INT (~ (HOST_WIDE_INT) 0x7fffffff)));
5802 emit_move_insn (lowword, operands[6]);
5803 emit_move_insn (highword, operands[2]);
5804 emit_move_insn (operands[5], operands[4]);
5805 emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5806 DONE;
5807 }"
5808 [(set_attr "length" "24")
5809 (set_attr "type" "fp")])
5810
5811 ;; If we don't have a direct conversion to single precision, don't enable this
5812 ;; conversion for 32-bit without fast math, because we don't have the insn to
5813 ;; generate the fixup swizzle to avoid double rounding problems.
5814 (define_expand "floatunssisf2"
5815 [(set (match_operand:SF 0 "gpc_reg_operand" "")
5816 (unsigned_float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
5817 "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
5818 && (!TARGET_FPRS
5819 || (TARGET_FPRS
5820 && ((TARGET_FCFIDUS && TARGET_LFIWZX)
5821 || (TARGET_DOUBLE_FLOAT && TARGET_FCFID
5822 && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))))"
5823 "
5824 {
5825 if (!TARGET_FPRS)
5826 {
5827 if (!REG_P (operands[1]))
5828 operands[1] = force_reg (SImode, operands[1]);
5829 }
5830 else if (TARGET_LFIWZX && TARGET_FCFIDUS)
5831 {
5832 emit_insn (gen_floatunssisf2_lfiwzx (operands[0], operands[1]));
5833 DONE;
5834 }
5835 else
5836 {
5837 rtx dreg = operands[1];
5838 if (!REG_P (dreg))
5839 dreg = force_reg (SImode, dreg);
5840 dreg = convert_to_mode (DImode, dreg, true);
5841 emit_insn (gen_floatdisf2 (operands[0], dreg));
5842 DONE;
5843 }
5844 }")
5845
5846 (define_expand "floatunssidf2"
5847 [(parallel [(set (match_operand:DF 0 "gpc_reg_operand" "")
5848 (unsigned_float:DF (match_operand:SI 1 "nonimmediate_operand" "")))
5849 (use (match_dup 2))
5850 (use (match_dup 3))
5851 (clobber (match_dup 4))
5852 (clobber (match_dup 5))])]
5853 "TARGET_HARD_FLOAT
5854 && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
5855 "
5856 {
5857 if (TARGET_E500_DOUBLE)
5858 {
5859 if (!REG_P (operands[1]))
5860 operands[1] = force_reg (SImode, operands[1]);
5861 emit_insn (gen_spe_floatunssidf2 (operands[0], operands[1]));
5862 DONE;
5863 }
5864 else if (TARGET_LFIWZX && TARGET_FCFID)
5865 {
5866 emit_insn (gen_floatunssidf2_lfiwzx (operands[0], operands[1]));
5867 DONE;
5868 }
5869 else if (TARGET_FCFID)
5870 {
5871 rtx dreg = operands[1];
5872 if (!REG_P (dreg))
5873 dreg = force_reg (SImode, dreg);
5874 dreg = convert_to_mode (DImode, dreg, true);
5875 emit_insn (gen_floatdidf2 (operands[0], dreg));
5876 DONE;
5877 }
5878
5879 if (!REG_P (operands[1]))
5880 operands[1] = force_reg (SImode, operands[1]);
5881 operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5882 operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503599627370496\", DFmode));
5883 operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5884 operands[5] = gen_reg_rtx (DFmode);
5885 }")
5886
5887 (define_insn_and_split "*floatunssidf2_internal"
5888 [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5889 (unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5890 (use (match_operand:SI 2 "gpc_reg_operand" "r"))
5891 (use (match_operand:DF 3 "gpc_reg_operand" "d"))
5892 (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
5893 (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))]
5894 "! TARGET_FCFIDU && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5895 && !(TARGET_FCFID && TARGET_POWERPC64)"
5896 "#"
5897 ""
5898 [(pc)]
5899 "
5900 {
5901 rtx lowword, highword;
5902 gcc_assert (MEM_P (operands[4]));
5903 highword = adjust_address (operands[4], SImode, 0);
5904 lowword = adjust_address (operands[4], SImode, 4);
5905 if (! WORDS_BIG_ENDIAN)
5906 std::swap (lowword, highword);
5907
5908 emit_move_insn (lowword, operands[1]);
5909 emit_move_insn (highword, operands[2]);
5910 emit_move_insn (operands[5], operands[4]);
5911 emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5912 DONE;
5913 }"
5914 [(set_attr "length" "20")
5915 (set_attr "type" "fp")])
5916
5917 (define_expand "fix_trunc<mode>si2"
5918 [(set (match_operand:SI 0 "gpc_reg_operand" "")
5919 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "")))]
5920 "TARGET_HARD_FLOAT && ((TARGET_FPRS && <TARGET_FLOAT>) || <E500_CONVERT>)"
5921 "
5922 {
5923 if (!<E500_CONVERT>)
5924 {
5925 rtx tmp, stack;
5926
5927 if (TARGET_STFIWX)
5928 emit_insn (gen_fix_trunc<mode>si2_stfiwx (operands[0], operands[1]));
5929 else
5930 {
5931 tmp = gen_reg_rtx (DImode);
5932 stack = rs6000_allocate_stack_temp (DImode, true, false);
5933 emit_insn (gen_fix_trunc<mode>si2_internal (operands[0], operands[1],
5934 tmp, stack));
5935 }
5936 DONE;
5937 }
5938 }")
5939
5940 ; Like the convert to float patterns, this insn must be split before
5941 ; register allocation so that it can allocate the memory slot if it
5942 ; needed
5943 (define_insn_and_split "fix_trunc<mode>si2_stfiwx"
5944 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5945 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
5946 (clobber (match_scratch:DI 2 "=d"))]
5947 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5948 && (<MODE>mode != SFmode || TARGET_SINGLE_FLOAT)
5949 && TARGET_STFIWX && can_create_pseudo_p ()"
5950 "#"
5951 ""
5952 [(pc)]
5953 {
5954 rtx dest = operands[0];
5955 rtx src = operands[1];
5956 rtx tmp = operands[2];
5957
5958 if (GET_CODE (tmp) == SCRATCH)
5959 tmp = gen_reg_rtx (DImode);
5960
5961 emit_insn (gen_fctiwz_<mode> (tmp, src));
5962 if (MEM_P (dest))
5963 {
5964 dest = rs6000_address_for_fpconvert (dest);
5965 emit_insn (gen_stfiwx (dest, tmp));
5966 DONE;
5967 }
5968 else if (TARGET_POWERPC64 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5969 {
5970 dest = gen_lowpart (DImode, dest);
5971 emit_move_insn (dest, tmp);
5972 DONE;
5973 }
5974 else
5975 {
5976 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5977 emit_insn (gen_stfiwx (stack, tmp));
5978 emit_move_insn (dest, stack);
5979 DONE;
5980 }
5981 }
5982 [(set_attr "length" "12")
5983 (set_attr "type" "fp")])
5984
5985 (define_insn_and_split "fix_trunc<mode>si2_internal"
5986 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,?r")
5987 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d,<rreg>")))
5988 (clobber (match_operand:DI 2 "gpc_reg_operand" "=1,d"))
5989 (clobber (match_operand:DI 3 "offsettable_mem_operand" "=o,o"))]
5990 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
5991 "#"
5992 ""
5993 [(pc)]
5994 "
5995 {
5996 rtx lowword;
5997 gcc_assert (MEM_P (operands[3]));
5998 lowword = adjust_address (operands[3], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
5999
6000 emit_insn (gen_fctiwz_<mode> (operands[2], operands[1]));
6001 emit_move_insn (operands[3], operands[2]);
6002 emit_move_insn (operands[0], lowword);
6003 DONE;
6004 }"
6005 [(set_attr "length" "16")
6006 (set_attr "type" "fp")])
6007
6008 (define_expand "fix_trunc<mode>di2"
6009 [(set (match_operand:DI 0 "gpc_reg_operand" "")
6010 (fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "")))]
6011 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS
6012 && TARGET_FCFID"
6013 "")
6014
6015 (define_insn "*fix_trunc<mode>di2_fctidz"
6016 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
6017 (fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fa>")))]
6018 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS
6019 && TARGET_FCFID"
6020 "@
6021 fctidz %0,%1
6022 xscvdpsxds %x0,%x1"
6023 [(set_attr "type" "fp")])
6024
6025 (define_expand "fixuns_trunc<mode>si2"
6026 [(set (match_operand:SI 0 "gpc_reg_operand" "")
6027 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "")))]
6028 "TARGET_HARD_FLOAT
6029 && ((TARGET_FPRS && <TARGET_FLOAT> && TARGET_FCTIWUZ && TARGET_STFIWX)
6030 || <E500_CONVERT>)"
6031 "
6032 {
6033 if (!<E500_CONVERT>)
6034 {
6035 emit_insn (gen_fixuns_trunc<mode>si2_stfiwx (operands[0], operands[1]));
6036 DONE;
6037 }
6038 }")
6039
6040 (define_insn_and_split "fixuns_trunc<mode>si2_stfiwx"
6041 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
6042 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
6043 (clobber (match_scratch:DI 2 "=d"))]
6044 "TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT> && TARGET_FCTIWUZ
6045 && TARGET_STFIWX && can_create_pseudo_p ()"
6046 "#"
6047 ""
6048 [(pc)]
6049 {
6050 rtx dest = operands[0];
6051 rtx src = operands[1];
6052 rtx tmp = operands[2];
6053
6054 if (GET_CODE (tmp) == SCRATCH)
6055 tmp = gen_reg_rtx (DImode);
6056
6057 emit_insn (gen_fctiwuz_<mode> (tmp, src));
6058 if (MEM_P (dest))
6059 {
6060 dest = rs6000_address_for_fpconvert (dest);
6061 emit_insn (gen_stfiwx (dest, tmp));
6062 DONE;
6063 }
6064 else if (TARGET_POWERPC64 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
6065 {
6066 dest = gen_lowpart (DImode, dest);
6067 emit_move_insn (dest, tmp);
6068 DONE;
6069 }
6070 else
6071 {
6072 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
6073 emit_insn (gen_stfiwx (stack, tmp));
6074 emit_move_insn (dest, stack);
6075 DONE;
6076 }
6077 }
6078 [(set_attr "length" "12")
6079 (set_attr "type" "fp")])
6080
6081 (define_expand "fixuns_trunc<mode>di2"
6082 [(set (match_operand:DI 0 "register_operand" "")
6083 (unsigned_fix:DI (match_operand:SFDF 1 "register_operand" "")))]
6084 "TARGET_HARD_FLOAT && (TARGET_FCTIDUZ || VECTOR_UNIT_VSX_P (<MODE>mode))"
6085 "")
6086
6087 (define_insn "*fixuns_trunc<mode>di2_fctiduz"
6088 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
6089 (unsigned_fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fa>")))]
6090 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS
6091 && TARGET_FCTIDUZ"
6092 "@
6093 fctiduz %0,%1
6094 xscvdpuxds %x0,%x1"
6095 [(set_attr "type" "fp")])
6096
6097 ; Here, we use (set (reg) (unspec:DI [(fix:SI ...)] UNSPEC_FCTIWZ))
6098 ; rather than (set (subreg:SI (reg)) (fix:SI ...))
6099 ; because the first makes it clear that operand 0 is not live
6100 ; before the instruction.
6101 (define_insn "fctiwz_<mode>"
6102 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
6103 (unspec:DI [(fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
6104 UNSPEC_FCTIWZ))]
6105 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
6106 "@
6107 fctiwz %0,%1
6108 xscvdpsxws %x0,%x1"
6109 [(set_attr "type" "fp")])
6110
6111 (define_insn "fctiwuz_<mode>"
6112 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
6113 (unspec:DI [(unsigned_fix:SI
6114 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
6115 UNSPEC_FCTIWUZ))]
6116 "TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT> && TARGET_FCTIWUZ"
6117 "@
6118 fctiwuz %0,%1
6119 xscvdpuxws %x0,%x1"
6120 [(set_attr "type" "fp")])
6121
6122 ;; Only optimize (float (fix x)) -> frz if we are in fast-math mode, since
6123 ;; since the friz instruction does not truncate the value if the floating
6124 ;; point value is < LONG_MIN or > LONG_MAX.
6125 (define_insn "*friz"
6126 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
6127 (float:DF (fix:DI (match_operand:DF 1 "gpc_reg_operand" "d,ws"))))]
6128 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_FPRND
6129 && flag_unsafe_math_optimizations && !flag_trapping_math && TARGET_FRIZ"
6130 "@
6131 friz %0,%1
6132 xsrdpiz %x0,%x1"
6133 [(set_attr "type" "fp")])
6134
6135 ;; Since FCTIWZ doesn't sign extend the upper bits, we have to do a store and a
6136 ;; load to properly sign extend the value, but at least doing a store, load
6137 ;; into a GPR to sign extend, a store from the GPR and a load back into the FPR
6138 ;; if we have 32-bit memory ops
6139 (define_insn_and_split "*round32<mode>2_fprs"
6140 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
6141 (float:SFDF
6142 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
6143 (clobber (match_scratch:DI 2 "=d"))
6144 (clobber (match_scratch:DI 3 "=d"))]
6145 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
6146 && <SI_CONVERT_FP> && TARGET_LFIWAX && TARGET_STFIWX && TARGET_FCFID
6147 && can_create_pseudo_p ()"
6148 "#"
6149 ""
6150 [(pc)]
6151 {
6152 rtx dest = operands[0];
6153 rtx src = operands[1];
6154 rtx tmp1 = operands[2];
6155 rtx tmp2 = operands[3];
6156 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
6157
6158 if (GET_CODE (tmp1) == SCRATCH)
6159 tmp1 = gen_reg_rtx (DImode);
6160 if (GET_CODE (tmp2) == SCRATCH)
6161 tmp2 = gen_reg_rtx (DImode);
6162
6163 emit_insn (gen_fctiwz_<mode> (tmp1, src));
6164 emit_insn (gen_stfiwx (stack, tmp1));
6165 emit_insn (gen_lfiwax (tmp2, stack));
6166 emit_insn (gen_floatdi<mode>2 (dest, tmp2));
6167 DONE;
6168 }
6169 [(set_attr "type" "fpload")
6170 (set_attr "length" "16")])
6171
6172 (define_insn_and_split "*roundu32<mode>2_fprs"
6173 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
6174 (unsigned_float:SFDF
6175 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
6176 (clobber (match_scratch:DI 2 "=d"))
6177 (clobber (match_scratch:DI 3 "=d"))]
6178 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
6179 && TARGET_LFIWZX && TARGET_STFIWX && TARGET_FCFIDU
6180 && can_create_pseudo_p ()"
6181 "#"
6182 ""
6183 [(pc)]
6184 {
6185 rtx dest = operands[0];
6186 rtx src = operands[1];
6187 rtx tmp1 = operands[2];
6188 rtx tmp2 = operands[3];
6189 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
6190
6191 if (GET_CODE (tmp1) == SCRATCH)
6192 tmp1 = gen_reg_rtx (DImode);
6193 if (GET_CODE (tmp2) == SCRATCH)
6194 tmp2 = gen_reg_rtx (DImode);
6195
6196 emit_insn (gen_fctiwuz_<mode> (tmp1, src));
6197 emit_insn (gen_stfiwx (stack, tmp1));
6198 emit_insn (gen_lfiwzx (tmp2, stack));
6199 emit_insn (gen_floatdi<mode>2 (dest, tmp2));
6200 DONE;
6201 }
6202 [(set_attr "type" "fpload")
6203 (set_attr "length" "16")])
6204
6205 ;; No VSX equivalent to fctid
6206 (define_insn "lrint<mode>di2"
6207 [(set (match_operand:DI 0 "gpc_reg_operand" "=d")
6208 (unspec:DI [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
6209 UNSPEC_FCTID))]
6210 "TARGET_<MODE>_FPR && TARGET_FPRND"
6211 "fctid %0,%1"
6212 [(set_attr "type" "fp")])
6213
6214 (define_insn "btrunc<mode>2"
6215 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
6216 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
6217 UNSPEC_FRIZ))]
6218 "TARGET_<MODE>_FPR && TARGET_FPRND"
6219 "@
6220 friz %0,%1
6221 xsrdpiz %x0,%x1"
6222 [(set_attr "type" "fp")
6223 (set_attr "fp_type" "fp_addsub_<Fs>")])
6224
6225 (define_insn "ceil<mode>2"
6226 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
6227 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
6228 UNSPEC_FRIP))]
6229 "TARGET_<MODE>_FPR && TARGET_FPRND"
6230 "@
6231 frip %0,%1
6232 xsrdpip %x0,%x1"
6233 [(set_attr "type" "fp")
6234 (set_attr "fp_type" "fp_addsub_<Fs>")])
6235
6236 (define_insn "floor<mode>2"
6237 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
6238 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
6239 UNSPEC_FRIM))]
6240 "TARGET_<MODE>_FPR && TARGET_FPRND"
6241 "@
6242 frim %0,%1
6243 xsrdpim %x0,%x1"
6244 [(set_attr "type" "fp")
6245 (set_attr "fp_type" "fp_addsub_<Fs>")])
6246
6247 ;; No VSX equivalent to frin
6248 (define_insn "round<mode>2"
6249 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<rreg2>")
6250 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
6251 UNSPEC_FRIN))]
6252 "TARGET_<MODE>_FPR && TARGET_FPRND"
6253 "frin %0,%1"
6254 [(set_attr "type" "fp")
6255 (set_attr "fp_type" "fp_addsub_<Fs>")])
6256
6257 ; An UNSPEC is used so we don't have to support SImode in FP registers.
6258 (define_insn "stfiwx"
6259 [(set (match_operand:SI 0 "memory_operand" "=Z")
6260 (unspec:SI [(match_operand:DI 1 "gpc_reg_operand" "d")]
6261 UNSPEC_STFIWX))]
6262 "TARGET_PPC_GFXOPT"
6263 "stfiwx %1,%y0"
6264 [(set_attr "type" "fpstore")])
6265
6266 ;; If we don't have a direct conversion to single precision, don't enable this
6267 ;; conversion for 32-bit without fast math, because we don't have the insn to
6268 ;; generate the fixup swizzle to avoid double rounding problems.
6269 (define_expand "floatsisf2"
6270 [(set (match_operand:SF 0 "gpc_reg_operand" "")
6271 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
6272 "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
6273 && (!TARGET_FPRS
6274 || (TARGET_FPRS
6275 && ((TARGET_FCFIDS && TARGET_LFIWAX)
6276 || (TARGET_DOUBLE_FLOAT && TARGET_FCFID
6277 && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))))"
6278 "
6279 {
6280 if (!TARGET_FPRS)
6281 {
6282 if (!REG_P (operands[1]))
6283 operands[1] = force_reg (SImode, operands[1]);
6284 }
6285 else if (TARGET_FCFIDS && TARGET_LFIWAX)
6286 {
6287 emit_insn (gen_floatsisf2_lfiwax (operands[0], operands[1]));
6288 DONE;
6289 }
6290 else if (TARGET_FCFID && TARGET_LFIWAX)
6291 {
6292 rtx dfreg = gen_reg_rtx (DFmode);
6293 emit_insn (gen_floatsidf2_lfiwax (dfreg, operands[1]));
6294 emit_insn (gen_truncdfsf2 (operands[0], dfreg));
6295 DONE;
6296 }
6297 else
6298 {
6299 rtx dreg = operands[1];
6300 if (!REG_P (dreg))
6301 dreg = force_reg (SImode, dreg);
6302 dreg = convert_to_mode (DImode, dreg, false);
6303 emit_insn (gen_floatdisf2 (operands[0], dreg));
6304 DONE;
6305 }
6306 }")
6307
6308 (define_expand "floatdidf2"
6309 [(set (match_operand:DF 0 "gpc_reg_operand" "")
6310 (float:DF (match_operand:DI 1 "gpc_reg_operand" "")))]
6311 "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS"
6312 "")
6313
6314 (define_insn "*floatdidf2_fpr"
6315 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
6316 (float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
6317 "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS"
6318 "@
6319 fcfid %0,%1
6320 xscvsxddp %x0,%x1"
6321 [(set_attr "type" "fp")])
6322
6323 ; Allow the combiner to merge source memory operands to the conversion so that
6324 ; the optimizer/register allocator doesn't try to load the value too early in a
6325 ; GPR and then use store/load to move it to a FPR and suffer from a store-load
6326 ; hit. We will split after reload to avoid the trip through the GPRs
6327
6328 (define_insn_and_split "*floatdidf2_mem"
6329 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
6330 (float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
6331 (clobber (match_scratch:DI 2 "=d,wi"))]
6332 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS && TARGET_FCFID"
6333 "#"
6334 "&& reload_completed"
6335 [(set (match_dup 2) (match_dup 1))
6336 (set (match_dup 0) (float:DF (match_dup 2)))]
6337 ""
6338 [(set_attr "length" "8")
6339 (set_attr "type" "fpload")])
6340
6341 (define_expand "floatunsdidf2"
6342 [(set (match_operand:DF 0 "gpc_reg_operand" "")
6343 (unsigned_float:DF
6344 (match_operand:DI 1 "gpc_reg_operand" "")))]
6345 "TARGET_HARD_FLOAT && TARGET_FCFIDU"
6346 "")
6347
6348 (define_insn "*floatunsdidf2_fcfidu"
6349 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
6350 (unsigned_float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
6351 "TARGET_HARD_FLOAT && TARGET_FCFIDU"
6352 "@
6353 fcfidu %0,%1
6354 xscvuxddp %x0,%x1"
6355 [(set_attr "type" "fp")
6356 (set_attr "length" "4")])
6357
6358 (define_insn_and_split "*floatunsdidf2_mem"
6359 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
6360 (unsigned_float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
6361 (clobber (match_scratch:DI 2 "=d,wi"))]
6362 "TARGET_HARD_FLOAT && (TARGET_FCFIDU || VECTOR_UNIT_VSX_P (DFmode))"
6363 "#"
6364 "&& reload_completed"
6365 [(set (match_dup 2) (match_dup 1))
6366 (set (match_dup 0) (unsigned_float:DF (match_dup 2)))]
6367 ""
6368 [(set_attr "length" "8")
6369 (set_attr "type" "fpload")])
6370
6371 (define_expand "floatdisf2"
6372 [(set (match_operand:SF 0 "gpc_reg_operand" "")
6373 (float:SF (match_operand:DI 1 "gpc_reg_operand" "")))]
6374 "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
6375 && (TARGET_FCFIDS || TARGET_POWERPC64 || flag_unsafe_math_optimizations)"
6376 "
6377 {
6378 if (!TARGET_FCFIDS)
6379 {
6380 rtx val = operands[1];
6381 if (!flag_unsafe_math_optimizations)
6382 {
6383 rtx label = gen_label_rtx ();
6384 val = gen_reg_rtx (DImode);
6385 emit_insn (gen_floatdisf2_internal2 (val, operands[1], label));
6386 emit_label (label);
6387 }
6388 emit_insn (gen_floatdisf2_internal1 (operands[0], val));
6389 DONE;
6390 }
6391 }")
6392
6393 (define_insn "floatdisf2_fcfids"
6394 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy")
6395 (float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
6396 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
6397 && TARGET_DOUBLE_FLOAT && TARGET_FCFIDS"
6398 "@
6399 fcfids %0,%1
6400 xscvsxdsp %x0,%x1"
6401 [(set_attr "type" "fp")])
6402
6403 (define_insn_and_split "*floatdisf2_mem"
6404 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy,wy")
6405 (float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
6406 (clobber (match_scratch:DI 2 "=d,d,wi"))]
6407 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
6408 && TARGET_DOUBLE_FLOAT && TARGET_FCFIDS"
6409 "#"
6410 "&& reload_completed"
6411 [(pc)]
6412 "
6413 {
6414 emit_move_insn (operands[2], operands[1]);
6415 emit_insn (gen_floatdisf2_fcfids (operands[0], operands[2]));
6416 DONE;
6417 }"
6418 [(set_attr "length" "8")])
6419
6420 ;; This is not IEEE compliant if rounding mode is "round to nearest".
6421 ;; If the DI->DF conversion is inexact, then it's possible to suffer
6422 ;; from double rounding.
6423 ;; Instead of creating a new cpu type for two FP operations, just use fp
6424 (define_insn_and_split "floatdisf2_internal1"
6425 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
6426 (float:SF (match_operand:DI 1 "gpc_reg_operand" "d")))
6427 (clobber (match_scratch:DF 2 "=d"))]
6428 "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
6429 && !TARGET_FCFIDS"
6430 "#"
6431 "&& reload_completed"
6432 [(set (match_dup 2)
6433 (float:DF (match_dup 1)))
6434 (set (match_dup 0)
6435 (float_truncate:SF (match_dup 2)))]
6436 ""
6437 [(set_attr "length" "8")
6438 (set_attr "type" "fp")])
6439
6440 ;; Twiddles bits to avoid double rounding.
6441 ;; Bits that might be truncated when converting to DFmode are replaced
6442 ;; by a bit that won't be lost at that stage, but is below the SFmode
6443 ;; rounding position.
6444 (define_expand "floatdisf2_internal2"
6445 [(parallel [(set (match_dup 3) (ashiftrt:DI (match_operand:DI 1 "" "")
6446 (const_int 53)))
6447 (clobber (reg:DI CA_REGNO))])
6448 (set (match_operand:DI 0 "" "") (and:DI (match_dup 1)
6449 (const_int 2047)))
6450 (set (match_dup 3) (plus:DI (match_dup 3)
6451 (const_int 1)))
6452 (set (match_dup 0) (plus:DI (match_dup 0)
6453 (const_int 2047)))
6454 (set (match_dup 4) (compare:CCUNS (match_dup 3)
6455 (const_int 2)))
6456 (set (match_dup 0) (ior:DI (match_dup 0)
6457 (match_dup 1)))
6458 (set (match_dup 0) (and:DI (match_dup 0)
6459 (const_int -2048)))
6460 (set (pc) (if_then_else (geu (match_dup 4) (const_int 0))
6461 (label_ref (match_operand:DI 2 "" ""))
6462 (pc)))
6463 (set (match_dup 0) (match_dup 1))]
6464 "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
6465 && !TARGET_FCFIDS"
6466 "
6467 {
6468 operands[3] = gen_reg_rtx (DImode);
6469 operands[4] = gen_reg_rtx (CCUNSmode);
6470 }")
6471
6472 (define_expand "floatunsdisf2"
6473 [(set (match_operand:SF 0 "gpc_reg_operand" "")
6474 (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand" "")))]
6475 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
6476 && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
6477 "")
6478
6479 (define_insn "floatunsdisf2_fcfidus"
6480 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wu")
6481 (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
6482 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
6483 && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
6484 "@
6485 fcfidus %0,%1
6486 xscvuxdsp %x0,%x1"
6487 [(set_attr "type" "fp")])
6488
6489 (define_insn_and_split "*floatunsdisf2_mem"
6490 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy,wy")
6491 (unsigned_float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
6492 (clobber (match_scratch:DI 2 "=d,d,wi"))]
6493 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
6494 && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
6495 "#"
6496 "&& reload_completed"
6497 [(pc)]
6498 "
6499 {
6500 emit_move_insn (operands[2], operands[1]);
6501 emit_insn (gen_floatunsdisf2_fcfidus (operands[0], operands[2]));
6502 DONE;
6503 }"
6504 [(set_attr "length" "8")
6505 (set_attr "type" "fpload")])
6506 \f
6507 ;; Define the TImode operations that can be done in a small number
6508 ;; of instructions. The & constraints are to prevent the register
6509 ;; allocator from allocating registers that overlap with the inputs
6510 ;; (for example, having an input in 7,8 and an output in 6,7). We
6511 ;; also allow for the output being the same as one of the inputs.
6512
6513 (define_expand "addti3"
6514 [(set (match_operand:TI 0 "gpc_reg_operand" "")
6515 (plus:TI (match_operand:TI 1 "gpc_reg_operand" "")
6516 (match_operand:TI 2 "reg_or_short_operand" "")))]
6517 "TARGET_64BIT"
6518 {
6519 rtx lo0 = gen_lowpart (DImode, operands[0]);
6520 rtx lo1 = gen_lowpart (DImode, operands[1]);
6521 rtx lo2 = gen_lowpart (DImode, operands[2]);
6522 rtx hi0 = gen_highpart (DImode, operands[0]);
6523 rtx hi1 = gen_highpart (DImode, operands[1]);
6524 rtx hi2 = gen_highpart_mode (DImode, TImode, operands[2]);
6525
6526 if (!reg_or_short_operand (lo2, DImode))
6527 lo2 = force_reg (DImode, lo2);
6528 if (!adde_operand (hi2, DImode))
6529 hi2 = force_reg (DImode, hi2);
6530
6531 emit_insn (gen_adddi3_carry (lo0, lo1, lo2));
6532 emit_insn (gen_adddi3_carry_in (hi0, hi1, hi2));
6533 DONE;
6534 })
6535
6536 (define_expand "subti3"
6537 [(set (match_operand:TI 0 "gpc_reg_operand" "")
6538 (minus:TI (match_operand:TI 1 "reg_or_short_operand" "")
6539 (match_operand:TI 2 "gpc_reg_operand" "")))]
6540 "TARGET_64BIT"
6541 {
6542 rtx lo0 = gen_lowpart (DImode, operands[0]);
6543 rtx lo1 = gen_lowpart (DImode, operands[1]);
6544 rtx lo2 = gen_lowpart (DImode, operands[2]);
6545 rtx hi0 = gen_highpart (DImode, operands[0]);
6546 rtx hi1 = gen_highpart_mode (DImode, TImode, operands[1]);
6547 rtx hi2 = gen_highpart (DImode, operands[2]);
6548
6549 if (!reg_or_short_operand (lo1, DImode))
6550 lo1 = force_reg (DImode, lo1);
6551 if (!adde_operand (hi1, DImode))
6552 hi1 = force_reg (DImode, hi1);
6553
6554 emit_insn (gen_subfdi3_carry (lo0, lo2, lo1));
6555 emit_insn (gen_subfdi3_carry_in (hi0, hi2, hi1));
6556 DONE;
6557 })
6558
6559
6560 ;; Shift by a variable amount is too complex to be worth open-coding. We
6561 ;; just handle shifts by constants.
6562 (define_insn "ashrdi3_no_power"
6563 [(set (match_operand:DI 0 "gpc_reg_operand" "=&r,&r")
6564 (ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
6565 (match_operand:SI 2 "const_int_operand" "M,i")))
6566 (clobber (reg:SI CA_REGNO))]
6567 "!TARGET_POWERPC64"
6568 {
6569 switch (which_alternative)
6570 {
6571 default:
6572 gcc_unreachable ();
6573 case 0:
6574 if (WORDS_BIG_ENDIAN)
6575 return \"srawi %0,%1,31\;srawi %L0,%1,%h2\";
6576 else
6577 return \"srawi %L0,%L1,31\;srawi %0,%L1,%h2\";
6578 case 1:
6579 if (WORDS_BIG_ENDIAN)
6580 return \"srwi %L0,%L1,%h2\;insrwi %L0,%1,%h2,0\;srawi %0,%1,%h2\";
6581 else
6582 return \"srwi %0,%1,%h2\;insrwi %0,%L1,%h2,0\;srawi %L0,%L1,%h2\";
6583 }
6584 }
6585 [(set_attr "type" "two,three")
6586 (set_attr "length" "8,12")])
6587
6588 (define_insn "*ashrdisi3_noppc64be"
6589 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6590 (subreg:SI (ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r")
6591 (const_int 32)) 4))]
6592 "TARGET_32BIT && !TARGET_POWERPC64 && WORDS_BIG_ENDIAN"
6593 "*
6594 {
6595 if (REGNO (operands[0]) == REGNO (operands[1]))
6596 return \"\";
6597 else
6598 return \"mr %0,%1\";
6599 }"
6600 [(set_attr "length" "4")])
6601
6602 \f
6603 ;; PowerPC64 DImode operations.
6604
6605 (define_insn "*rotldi3_internal4"
6606 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
6607 (and:DI (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r")
6608 (match_operand:DI 2 "reg_or_cint_operand" "rn"))
6609 (match_operand:DI 3 "mask64_operand" "n")))]
6610 "TARGET_POWERPC64"
6611 "rld%I2c%B3 %0,%1,%H2,%S3"
6612 [(set_attr "type" "shift")
6613 (set_attr "maybe_var_shift" "yes")])
6614
6615 (define_insn "*rotldi3_internal5"
6616 [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
6617 (compare:CC (and:DI
6618 (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
6619 (match_operand:DI 2 "reg_or_cint_operand" "rn,rn"))
6620 (match_operand:DI 3 "mask64_operand" "n,n"))
6621 (const_int 0)))
6622 (clobber (match_scratch:DI 4 "=r,r"))]
6623 "TARGET_64BIT"
6624 "@
6625 rld%I2c%B3. %4,%1,%H2,%S3
6626 #"
6627 [(set_attr "type" "shift")
6628 (set_attr "maybe_var_shift" "yes")
6629 (set_attr "dot" "yes")
6630 (set_attr "length" "4,8")])
6631
6632 (define_split
6633 [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
6634 (compare:CC (and:DI
6635 (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "")
6636 (match_operand:DI 2 "reg_or_cint_operand" ""))
6637 (match_operand:DI 3 "mask64_operand" ""))
6638 (const_int 0)))
6639 (clobber (match_scratch:DI 4 ""))]
6640 "TARGET_POWERPC64 && reload_completed"
6641 [(set (match_dup 4)
6642 (and:DI (rotate:DI (match_dup 1)
6643 (match_dup 2))
6644 (match_dup 3)))
6645 (set (match_dup 0)
6646 (compare:CC (match_dup 4)
6647 (const_int 0)))]
6648 "")
6649
6650 (define_insn "*rotldi3_internal6"
6651 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
6652 (compare:CC (and:DI
6653 (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
6654 (match_operand:DI 2 "reg_or_cint_operand" "rn,rn"))
6655 (match_operand:DI 3 "mask64_operand" "n,n"))
6656 (const_int 0)))
6657 (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
6658 (and:DI (rotate:DI (match_dup 1) (match_dup 2)) (match_dup 3)))]
6659 "TARGET_64BIT"
6660 "@
6661 rld%I2c%B3. %0,%1,%H2,%S3
6662 #"
6663 [(set_attr "type" "shift")
6664 (set_attr "maybe_var_shift" "yes")
6665 (set_attr "dot" "yes")
6666 (set_attr "length" "4,8")])
6667
6668 (define_split
6669 [(set (match_operand:CC 4 "cc_reg_not_micro_cr0_operand" "")
6670 (compare:CC (and:DI
6671 (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "")
6672 (match_operand:DI 2 "reg_or_cint_operand" ""))
6673 (match_operand:DI 3 "mask64_operand" ""))
6674 (const_int 0)))
6675 (set (match_operand:DI 0 "gpc_reg_operand" "")
6676 (and:DI (rotate:DI (match_dup 1) (match_dup 2)) (match_dup 3)))]
6677 "TARGET_POWERPC64 && reload_completed"
6678 [(set (match_dup 0)
6679 (and:DI (rotate:DI (match_dup 1) (match_dup 2)) (match_dup 3)))
6680 (set (match_dup 4)
6681 (compare:CC (match_dup 0)
6682 (const_int 0)))]
6683 "")
6684
6685 (define_insn "*rotldi3_internal7le"
6686 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
6687 (zero_extend:DI
6688 (subreg:QI
6689 (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r")
6690 (match_operand:DI 2 "reg_or_cint_operand" "rn")) 0)))]
6691 "TARGET_POWERPC64 && !BYTES_BIG_ENDIAN"
6692 "rld%I2cl %0,%1,%H2,56"
6693 [(set_attr "type" "shift")
6694 (set_attr "maybe_var_shift" "yes")])
6695
6696 (define_insn "*rotldi3_internal7be"
6697 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
6698 (zero_extend:DI
6699 (subreg:QI
6700 (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r")
6701 (match_operand:DI 2 "reg_or_cint_operand" "rn")) 7)))]
6702 "TARGET_POWERPC64 && BYTES_BIG_ENDIAN"
6703 "rld%I2cl %0,%1,%H2,56"
6704 [(set_attr "type" "shift")
6705 (set_attr "maybe_var_shift" "yes")])
6706
6707 (define_insn "*rotldi3_internal8le"
6708 [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
6709 (compare:CC (zero_extend:DI
6710 (subreg:QI
6711 (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
6712 (match_operand:DI 2 "reg_or_cint_operand" "rn,rn")) 0))
6713 (const_int 0)))
6714 (clobber (match_scratch:DI 3 "=r,r"))]
6715 "TARGET_64BIT && !BYTES_BIG_ENDIAN"
6716 "@
6717 rld%I2cl. %3,%1,%H2,56
6718 #"
6719 [(set_attr "type" "shift")
6720 (set_attr "maybe_var_shift" "yes")
6721 (set_attr "dot" "yes")
6722 (set_attr "length" "4,8")])
6723
6724 (define_insn "*rotldi3_internal8be"
6725 [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
6726 (compare:CC (zero_extend:DI
6727 (subreg:QI
6728 (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
6729 (match_operand:DI 2 "reg_or_cint_operand" "rn,rn")) 7))
6730 (const_int 0)))
6731 (clobber (match_scratch:DI 3 "=r,r"))]
6732 "TARGET_64BIT && BYTES_BIG_ENDIAN"
6733 "@
6734 rld%I2cl. %3,%1,%H2,56
6735 #"
6736 [(set_attr "type" "shift")
6737 (set_attr "maybe_var_shift" "yes")
6738 (set_attr "dot" "yes")
6739 (set_attr "length" "4,8")])
6740
6741 (define_split
6742 [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
6743 (compare:CC (zero_extend:DI
6744 (subreg:QI
6745 (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "")
6746 (match_operand:DI 2 "reg_or_cint_operand" "")) 0))
6747 (const_int 0)))
6748 (clobber (match_scratch:DI 3 ""))]
6749 "TARGET_POWERPC64 && !BYTES_BIG_ENDIAN && reload_completed"
6750 [(set (match_dup 3)
6751 (zero_extend:DI (subreg:QI
6752 (rotate:DI (match_dup 1)
6753 (match_dup 2)) 0)))
6754 (set (match_dup 0)
6755 (compare:CC (match_dup 3)
6756 (const_int 0)))]
6757 "")
6758
6759 (define_split
6760 [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
6761 (compare:CC (zero_extend:DI
6762 (subreg:QI
6763 (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "")
6764 (match_operand:DI 2 "reg_or_cint_operand" "")) 7))
6765 (const_int 0)))
6766 (clobber (match_scratch:DI 3 ""))]
6767 "TARGET_POWERPC64 && BYTES_BIG_ENDIAN && reload_completed"
6768 [(set (match_dup 3)
6769 (zero_extend:DI (subreg:QI
6770 (rotate:DI (match_dup 1)
6771 (match_dup 2)) 7)))
6772 (set (match_dup 0)
6773 (compare:CC (match_dup 3)
6774 (const_int 0)))]
6775 "")
6776
6777 (define_insn "*rotldi3_internal9le"
6778 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
6779 (compare:CC (zero_extend:DI
6780 (subreg:QI
6781 (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
6782 (match_operand:DI 2 "reg_or_cint_operand" "rn,rn")) 0))
6783 (const_int 0)))
6784 (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
6785 (zero_extend:DI (subreg:QI (rotate:DI (match_dup 1) (match_dup 2)) 0)))]
6786 "TARGET_64BIT && !BYTES_BIG_ENDIAN"
6787 "@
6788 rld%I2cl. %0,%1,%H2,56
6789 #"
6790 [(set_attr "type" "shift")
6791 (set_attr "maybe_var_shift" "yes")
6792 (set_attr "dot" "yes")
6793 (set_attr "length" "4,8")])
6794
6795 (define_insn "*rotldi3_internal9be"
6796 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
6797 (compare:CC (zero_extend:DI
6798 (subreg:QI
6799 (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
6800 (match_operand:DI 2 "reg_or_cint_operand" "rn,rn")) 7))
6801 (const_int 0)))
6802 (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
6803 (zero_extend:DI (subreg:QI (rotate:DI (match_dup 1) (match_dup 2)) 7)))]
6804 "TARGET_64BIT && BYTES_BIG_ENDIAN"
6805 "@
6806 rld%I2cl. %0,%1,%H2,56
6807 #"
6808 [(set_attr "type" "shift")
6809 (set_attr "maybe_var_shift" "yes")
6810 (set_attr "dot" "yes")
6811 (set_attr "length" "4,8")])
6812
6813 (define_split
6814 [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "")
6815 (compare:CC (zero_extend:DI
6816 (subreg:QI
6817 (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "")
6818 (match_operand:DI 2 "reg_or_cint_operand" "")) 0))
6819 (const_int 0)))
6820 (set (match_operand:DI 0 "gpc_reg_operand" "")
6821 (zero_extend:DI (subreg:QI (rotate:DI (match_dup 1) (match_dup 2)) 0)))]
6822 "TARGET_POWERPC64 && !BYTES_BIG_ENDIAN && reload_completed"
6823 [(set (match_dup 0)
6824 (zero_extend:DI (subreg:QI (rotate:DI (match_dup 1) (match_dup 2)) 0)))
6825 (set (match_dup 3)
6826 (compare:CC (match_dup 0)
6827 (const_int 0)))]
6828 "")
6829
6830 (define_split
6831 [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "")
6832 (compare:CC (zero_extend:DI
6833 (subreg:QI
6834 (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "")
6835 (match_operand:DI 2 "reg_or_cint_operand" "")) 7))
6836 (const_int 0)))
6837 (set (match_operand:DI 0 "gpc_reg_operand" "")
6838 (zero_extend:DI (subreg:QI (rotate:DI (match_dup 1) (match_dup 2)) 7)))]
6839 "TARGET_POWERPC64 && BYTES_BIG_ENDIAN && reload_completed"
6840 [(set (match_dup 0)
6841 (zero_extend:DI (subreg:QI (rotate:DI (match_dup 1) (match_dup 2)) 7)))
6842 (set (match_dup 3)
6843 (compare:CC (match_dup 0)
6844 (const_int 0)))]
6845 "")
6846
6847 (define_insn "*rotldi3_internal10le"
6848 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
6849 (zero_extend:DI
6850 (subreg:HI
6851 (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r")
6852 (match_operand:DI 2 "reg_or_cint_operand" "rn")) 0)))]
6853 "TARGET_POWERPC64 && !BYTES_BIG_ENDIAN"
6854 "rld%I2cl %0,%1,%H2,48"
6855 [(set_attr "type" "shift")
6856 (set_attr "maybe_var_shift" "yes")])
6857
6858 (define_insn "*rotldi3_internal10be"
6859 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
6860 (zero_extend:DI
6861 (subreg:HI
6862 (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r")
6863 (match_operand:DI 2 "reg_or_cint_operand" "rn")) 6)))]
6864 "TARGET_POWERPC64 && BYTES_BIG_ENDIAN"
6865 "rld%I2cl %0,%1,%H2,48"
6866 [(set_attr "type" "shift")
6867 (set_attr "maybe_var_shift" "yes")])
6868
6869 (define_insn "*rotldi3_internal11le"
6870 [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
6871 (compare:CC (zero_extend:DI
6872 (subreg:HI
6873 (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
6874 (match_operand:DI 2 "reg_or_cint_operand" "rn,rn")) 0))
6875 (const_int 0)))
6876 (clobber (match_scratch:DI 3 "=r,r"))]
6877 "TARGET_64BIT && !BYTES_BIG_ENDIAN"
6878 "@
6879 rld%I2cl. %3,%1,%H2,48
6880 #"
6881 [(set_attr "type" "shift")
6882 (set_attr "maybe_var_shift" "yes")
6883 (set_attr "dot" "yes")
6884 (set_attr "length" "4,8")])
6885
6886 (define_insn "*rotldi3_internal11be"
6887 [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
6888 (compare:CC (zero_extend:DI
6889 (subreg:HI
6890 (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
6891 (match_operand:DI 2 "reg_or_cint_operand" "rn,rn")) 6))
6892 (const_int 0)))
6893 (clobber (match_scratch:DI 3 "=r,r"))]
6894 "TARGET_64BIT && BYTES_BIG_ENDIAN"
6895 "@
6896 rld%I2cl. %3,%1,%H2,48
6897 #"
6898 [(set_attr "type" "shift")
6899 (set_attr "maybe_var_shift" "yes")
6900 (set_attr "dot" "yes")
6901 (set_attr "length" "4,8")])
6902
6903 (define_split
6904 [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
6905 (compare:CC (zero_extend:DI
6906 (subreg:HI
6907 (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "")
6908 (match_operand:DI 2 "reg_or_cint_operand" "")) 0))
6909 (const_int 0)))
6910 (clobber (match_scratch:DI 3 ""))]
6911 "TARGET_POWERPC64 && !BYTES_BIG_ENDIAN && reload_completed"
6912 [(set (match_dup 3)
6913 (zero_extend:DI (subreg:HI
6914 (rotate:DI (match_dup 1)
6915 (match_dup 2)) 0)))
6916 (set (match_dup 0)
6917 (compare:CC (match_dup 3)
6918 (const_int 0)))]
6919 "")
6920
6921 (define_split
6922 [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
6923 (compare:CC (zero_extend:DI
6924 (subreg:HI
6925 (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "")
6926 (match_operand:DI 2 "reg_or_cint_operand" "")) 6))
6927 (const_int 0)))
6928 (clobber (match_scratch:DI 3 ""))]
6929 "TARGET_POWERPC64 && BYTES_BIG_ENDIAN && reload_completed"
6930 [(set (match_dup 3)
6931 (zero_extend:DI (subreg:HI
6932 (rotate:DI (match_dup 1)
6933 (match_dup 2)) 6)))
6934 (set (match_dup 0)
6935 (compare:CC (match_dup 3)
6936 (const_int 0)))]
6937 "")
6938
6939 (define_insn "*rotldi3_internal12le"
6940 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
6941 (compare:CC (zero_extend:DI
6942 (subreg:HI
6943 (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
6944 (match_operand:DI 2 "reg_or_cint_operand" "rn,rn")) 0))
6945 (const_int 0)))
6946 (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
6947 (zero_extend:DI (subreg:HI (rotate:DI (match_dup 1) (match_dup 2)) 0)))]
6948 "TARGET_64BIT && !BYTES_BIG_ENDIAN"
6949 "@
6950 rld%I2cl. %0,%1,%H2,48
6951 #"
6952 [(set_attr "type" "shift")
6953 (set_attr "maybe_var_shift" "yes")
6954 (set_attr "dot" "yes")
6955 (set_attr "length" "4,8")])
6956
6957 (define_insn "*rotldi3_internal12be"
6958 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
6959 (compare:CC (zero_extend:DI
6960 (subreg:HI
6961 (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
6962 (match_operand:DI 2 "reg_or_cint_operand" "rn,rn")) 6))
6963 (const_int 0)))
6964 (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
6965 (zero_extend:DI (subreg:HI (rotate:DI (match_dup 1) (match_dup 2)) 6)))]
6966 "TARGET_64BIT && BYTES_BIG_ENDIAN"
6967 "@
6968 rld%I2cl. %0,%1,%H2,48
6969 #"
6970 [(set_attr "type" "shift")
6971 (set_attr "maybe_var_shift" "yes")
6972 (set_attr "dot" "yes")
6973 (set_attr "length" "4,8")])
6974
6975 (define_split
6976 [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "")
6977 (compare:CC (zero_extend:DI
6978 (subreg:HI
6979 (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "")
6980 (match_operand:DI 2 "reg_or_cint_operand" "")) 0))
6981 (const_int 0)))
6982 (set (match_operand:DI 0 "gpc_reg_operand" "")
6983 (zero_extend:DI (subreg:HI (rotate:DI (match_dup 1) (match_dup 2)) 0)))]
6984 "TARGET_POWERPC64 && !BYTES_BIG_ENDIAN && reload_completed"
6985 [(set (match_dup 0)
6986 (zero_extend:DI (subreg:HI (rotate:DI (match_dup 1) (match_dup 2)) 0)))
6987 (set (match_dup 3)
6988 (compare:CC (match_dup 0)
6989 (const_int 0)))]
6990 "")
6991
6992 (define_split
6993 [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "")
6994 (compare:CC (zero_extend:DI
6995 (subreg:HI
6996 (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "")
6997 (match_operand:DI 2 "reg_or_cint_operand" "")) 6))
6998 (const_int 0)))
6999 (set (match_operand:DI 0 "gpc_reg_operand" "")
7000 (zero_extend:DI (subreg:HI (rotate:DI (match_dup 1) (match_dup 2)) 6)))]
7001 "TARGET_POWERPC64 && BYTES_BIG_ENDIAN && reload_completed"
7002 [(set (match_dup 0)
7003 (zero_extend:DI (subreg:HI (rotate:DI (match_dup 1) (match_dup 2)) 6)))
7004 (set (match_dup 3)
7005 (compare:CC (match_dup 0)
7006 (const_int 0)))]
7007 "")
7008
7009 (define_insn "*rotldi3_internal13le"
7010 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
7011 (zero_extend:DI
7012 (subreg:SI
7013 (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r")
7014 (match_operand:DI 2 "reg_or_cint_operand" "rn")) 0)))]
7015 "TARGET_POWERPC64 && !BYTES_BIG_ENDIAN"
7016 "rld%I2cl %0,%1,%H2,32"
7017 [(set_attr "type" "shift")
7018 (set_attr "maybe_var_shift" "yes")])
7019
7020 (define_insn "*rotldi3_internal13be"
7021 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
7022 (zero_extend:DI
7023 (subreg:SI
7024 (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r")
7025 (match_operand:DI 2 "reg_or_cint_operand" "rn")) 4)))]
7026 "TARGET_POWERPC64 && BYTES_BIG_ENDIAN"
7027 "rld%I2cl %0,%1,%H2,32"
7028 [(set_attr "type" "shift")
7029 (set_attr "maybe_var_shift" "yes")])
7030
7031 (define_insn "*rotldi3_internal14le"
7032 [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
7033 (compare:CC (zero_extend:DI
7034 (subreg:SI
7035 (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
7036 (match_operand:DI 2 "reg_or_cint_operand" "rn,rn")) 0))
7037 (const_int 0)))
7038 (clobber (match_scratch:DI 3 "=r,r"))]
7039 "TARGET_64BIT && !BYTES_BIG_ENDIAN"
7040 "@
7041 rld%I2cl. %3,%1,%H2,32
7042 #"
7043 [(set_attr "type" "shift")
7044 (set_attr "maybe_var_shift" "yes")
7045 (set_attr "dot" "yes")
7046 (set_attr "length" "4,8")])
7047
7048 (define_insn "*rotldi3_internal14be"
7049 [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
7050 (compare:CC (zero_extend:DI
7051 (subreg:SI
7052 (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
7053 (match_operand:DI 2 "reg_or_cint_operand" "rn,rn")) 4))
7054 (const_int 0)))
7055 (clobber (match_scratch:DI 3 "=r,r"))]
7056 "TARGET_64BIT && BYTES_BIG_ENDIAN"
7057 "@
7058 rld%I2cl. %3,%1,%H2,32
7059 #"
7060 [(set_attr "type" "shift")
7061 (set_attr "maybe_var_shift" "yes")
7062 (set_attr "dot" "yes")
7063 (set_attr "length" "4,8")])
7064
7065 (define_split
7066 [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
7067 (compare:CC (zero_extend:DI
7068 (subreg:SI
7069 (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "")
7070 (match_operand:DI 2 "reg_or_cint_operand" "")) 0))
7071 (const_int 0)))
7072 (clobber (match_scratch:DI 3 ""))]
7073 "TARGET_POWERPC64 && !BYTES_BIG_ENDIAN && reload_completed"
7074 [(set (match_dup 3)
7075 (zero_extend:DI (subreg:SI
7076 (rotate:DI (match_dup 1)
7077 (match_dup 2)) 0)))
7078 (set (match_dup 0)
7079 (compare:CC (match_dup 3)
7080 (const_int 0)))]
7081 "")
7082
7083 (define_split
7084 [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
7085 (compare:CC (zero_extend:DI
7086 (subreg:SI
7087 (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "")
7088 (match_operand:DI 2 "reg_or_cint_operand" "")) 4))
7089 (const_int 0)))
7090 (clobber (match_scratch:DI 3 ""))]
7091 "TARGET_POWERPC64 && BYTES_BIG_ENDIAN && reload_completed"
7092 [(set (match_dup 3)
7093 (zero_extend:DI (subreg:SI
7094 (rotate:DI (match_dup 1)
7095 (match_dup 2)) 4)))
7096 (set (match_dup 0)
7097 (compare:CC (match_dup 3)
7098 (const_int 0)))]
7099 "")
7100
7101 (define_insn "*rotldi3_internal15le"
7102 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
7103 (compare:CC (zero_extend:DI
7104 (subreg:SI
7105 (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
7106 (match_operand:DI 2 "reg_or_cint_operand" "rn,rn")) 0))
7107 (const_int 0)))
7108 (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
7109 (zero_extend:DI (subreg:SI (rotate:DI (match_dup 1) (match_dup 2)) 0)))]
7110 "TARGET_64BIT && !BYTES_BIG_ENDIAN"
7111 "@
7112 rld%I2cl. %0,%1,%H2,32
7113 #"
7114 [(set_attr "type" "shift")
7115 (set_attr "maybe_var_shift" "yes")
7116 (set_attr "dot" "yes")
7117 (set_attr "length" "4,8")])
7118
7119 (define_insn "*rotldi3_internal15be"
7120 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
7121 (compare:CC (zero_extend:DI
7122 (subreg:SI
7123 (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
7124 (match_operand:DI 2 "reg_or_cint_operand" "rn,rn")) 4))
7125 (const_int 0)))
7126 (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
7127 (zero_extend:DI (subreg:SI (rotate:DI (match_dup 1) (match_dup 2)) 4)))]
7128 "TARGET_64BIT && BYTES_BIG_ENDIAN"
7129 "@
7130 rld%I2cl. %0,%1,%H2,32
7131 #"
7132 [(set_attr "type" "shift")
7133 (set_attr "maybe_var_shift" "yes")
7134 (set_attr "dot" "yes")
7135 (set_attr "length" "4,8")])
7136
7137 (define_split
7138 [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "")
7139 (compare:CC (zero_extend:DI
7140 (subreg:SI
7141 (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "")
7142 (match_operand:DI 2 "reg_or_cint_operand" "")) 0))
7143 (const_int 0)))
7144 (set (match_operand:DI 0 "gpc_reg_operand" "")
7145 (zero_extend:DI (subreg:SI (rotate:DI (match_dup 1) (match_dup 2)) 0)))]
7146 "TARGET_POWERPC64 && !BYTES_BIG_ENDIAN && reload_completed"
7147 [(set (match_dup 0)
7148 (zero_extend:DI (subreg:SI (rotate:DI (match_dup 1) (match_dup 2)) 0)))
7149 (set (match_dup 3)
7150 (compare:CC (match_dup 0)
7151 (const_int 0)))]
7152 "")
7153
7154 (define_split
7155 [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "")
7156 (compare:CC (zero_extend:DI
7157 (subreg:SI
7158 (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "")
7159 (match_operand:DI 2 "reg_or_cint_operand" "")) 4))
7160 (const_int 0)))
7161 (set (match_operand:DI 0 "gpc_reg_operand" "")
7162 (zero_extend:DI (subreg:SI (rotate:DI (match_dup 1) (match_dup 2)) 4)))]
7163 "TARGET_POWERPC64 && BYTES_BIG_ENDIAN && reload_completed"
7164 [(set (match_dup 0)
7165 (zero_extend:DI (subreg:SI (rotate:DI (match_dup 1) (match_dup 2)) 4)))
7166 (set (match_dup 3)
7167 (compare:CC (match_dup 0)
7168 (const_int 0)))]
7169 "")
7170
7171 (define_insn "*ashldi3_internal4"
7172 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
7173 (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r")
7174 (match_operand:SI 2 "const_int_operand" "i"))
7175 (match_operand:DI 3 "const_int_operand" "n")))]
7176 "TARGET_POWERPC64 && includes_rldic_lshift_p (operands[2], operands[3])"
7177 "rldic %0,%1,%H2,%W3"
7178 [(set_attr "type" "shift")])
7179
7180 (define_insn "ashldi3_internal5"
7181 [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
7182 (compare:CC
7183 (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
7184 (match_operand:SI 2 "const_int_operand" "i,i"))
7185 (match_operand:DI 3 "const_int_operand" "n,n"))
7186 (const_int 0)))
7187 (clobber (match_scratch:DI 4 "=r,r"))]
7188 "TARGET_64BIT && includes_rldic_lshift_p (operands[2], operands[3])"
7189 "@
7190 rldic. %4,%1,%H2,%W3
7191 #"
7192 [(set_attr "type" "shift")
7193 (set_attr "dot" "yes")
7194 (set_attr "length" "4,8")])
7195
7196 (define_split
7197 [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
7198 (compare:CC
7199 (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "")
7200 (match_operand:SI 2 "const_int_operand" ""))
7201 (match_operand:DI 3 "const_int_operand" ""))
7202 (const_int 0)))
7203 (clobber (match_scratch:DI 4 ""))]
7204 "TARGET_POWERPC64 && reload_completed
7205 && includes_rldic_lshift_p (operands[2], operands[3])"
7206 [(set (match_dup 4)
7207 (and:DI (ashift:DI (match_dup 1) (match_dup 2))
7208 (match_dup 3)))
7209 (set (match_dup 0)
7210 (compare:CC (match_dup 4)
7211 (const_int 0)))]
7212 "")
7213
7214 (define_insn "*ashldi3_internal6"
7215 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
7216 (compare:CC
7217 (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
7218 (match_operand:SI 2 "const_int_operand" "i,i"))
7219 (match_operand:DI 3 "const_int_operand" "n,n"))
7220 (const_int 0)))
7221 (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
7222 (and:DI (ashift:DI (match_dup 1) (match_dup 2)) (match_dup 3)))]
7223 "TARGET_64BIT && includes_rldic_lshift_p (operands[2], operands[3])"
7224 "@
7225 rldic. %0,%1,%H2,%W3
7226 #"
7227 [(set_attr "type" "shift")
7228 (set_attr "dot" "yes")
7229 (set_attr "length" "4,8")])
7230
7231 (define_split
7232 [(set (match_operand:CC 4 "cc_reg_not_micro_cr0_operand" "")
7233 (compare:CC
7234 (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "")
7235 (match_operand:SI 2 "const_int_operand" ""))
7236 (match_operand:DI 3 "const_int_operand" ""))
7237 (const_int 0)))
7238 (set (match_operand:DI 0 "gpc_reg_operand" "")
7239 (and:DI (ashift:DI (match_dup 1) (match_dup 2)) (match_dup 3)))]
7240 "TARGET_POWERPC64 && reload_completed
7241 && includes_rldic_lshift_p (operands[2], operands[3])"
7242 [(set (match_dup 0)
7243 (and:DI (ashift:DI (match_dup 1) (match_dup 2))
7244 (match_dup 3)))
7245 (set (match_dup 4)
7246 (compare:CC (match_dup 0)
7247 (const_int 0)))]
7248 "")
7249
7250 (define_insn "*ashldi3_internal7"
7251 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
7252 (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r")
7253 (match_operand:SI 2 "const_int_operand" "i"))
7254 (match_operand:DI 3 "mask64_operand" "n")))]
7255 "TARGET_POWERPC64 && includes_rldicr_lshift_p (operands[2], operands[3])"
7256 "rldicr %0,%1,%H2,%S3"
7257 [(set_attr "type" "shift")])
7258
7259 (define_insn "ashldi3_internal8"
7260 [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
7261 (compare:CC
7262 (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
7263 (match_operand:SI 2 "const_int_operand" "i,i"))
7264 (match_operand:DI 3 "mask64_operand" "n,n"))
7265 (const_int 0)))
7266 (clobber (match_scratch:DI 4 "=r,r"))]
7267 "TARGET_64BIT && includes_rldicr_lshift_p (operands[2], operands[3])"
7268 "@
7269 rldicr. %4,%1,%H2,%S3
7270 #"
7271 [(set_attr "type" "shift")
7272 (set_attr "dot" "yes")
7273 (set_attr "length" "4,8")])
7274
7275 (define_split
7276 [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
7277 (compare:CC
7278 (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "")
7279 (match_operand:SI 2 "const_int_operand" ""))
7280 (match_operand:DI 3 "mask64_operand" ""))
7281 (const_int 0)))
7282 (clobber (match_scratch:DI 4 ""))]
7283 "TARGET_POWERPC64 && reload_completed
7284 && includes_rldicr_lshift_p (operands[2], operands[3])"
7285 [(set (match_dup 4)
7286 (and:DI (ashift:DI (match_dup 1) (match_dup 2))
7287 (match_dup 3)))
7288 (set (match_dup 0)
7289 (compare:CC (match_dup 4)
7290 (const_int 0)))]
7291 "")
7292
7293 (define_insn "*ashldi3_internal9"
7294 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
7295 (compare:CC
7296 (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
7297 (match_operand:SI 2 "const_int_operand" "i,i"))
7298 (match_operand:DI 3 "mask64_operand" "n,n"))
7299 (const_int 0)))
7300 (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
7301 (and:DI (ashift:DI (match_dup 1) (match_dup 2)) (match_dup 3)))]
7302 "TARGET_64BIT && includes_rldicr_lshift_p (operands[2], operands[3])"
7303 "@
7304 rldicr. %0,%1,%H2,%S3
7305 #"
7306 [(set_attr "type" "shift")
7307 (set_attr "dot" "yes")
7308 (set_attr "length" "4,8")])
7309
7310 (define_split
7311 [(set (match_operand:CC 4 "cc_reg_not_micro_cr0_operand" "")
7312 (compare:CC
7313 (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "")
7314 (match_operand:SI 2 "const_int_operand" ""))
7315 (match_operand:DI 3 "mask64_operand" ""))
7316 (const_int 0)))
7317 (set (match_operand:DI 0 "gpc_reg_operand" "")
7318 (and:DI (ashift:DI (match_dup 1) (match_dup 2)) (match_dup 3)))]
7319 "TARGET_POWERPC64 && reload_completed
7320 && includes_rldicr_lshift_p (operands[2], operands[3])"
7321 [(set (match_dup 0)
7322 (and:DI (ashift:DI (match_dup 1) (match_dup 2))
7323 (match_dup 3)))
7324 (set (match_dup 4)
7325 (compare:CC (match_dup 0)
7326 (const_int 0)))]
7327 "")
7328
7329
7330 (define_insn_and_split "*anddi3_2rld"
7331 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
7332 (and:DI (match_operand:DI 1 "gpc_reg_operand" "%r")
7333 (match_operand:DI 2 "and_2rld_operand" "n")))]
7334 "TARGET_POWERPC64"
7335 "#"
7336 ""
7337 [(set (match_dup 0)
7338 (and:DI (rotate:DI (match_dup 1)
7339 (match_dup 4))
7340 (match_dup 5)))
7341 (set (match_dup 0)
7342 (and:DI (rotate:DI (match_dup 0)
7343 (match_dup 6))
7344 (match_dup 7)))]
7345 {
7346 build_mask64_2_operands (operands[2], &operands[4]);
7347 }
7348 [(set_attr "length" "8")])
7349
7350 (define_insn_and_split "*anddi3_2rld_dot"
7351 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
7352 (compare:CC (and:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r")
7353 (match_operand:DI 2 "and_2rld_operand" "n,n"))
7354 (const_int 0)))
7355 (clobber (match_scratch:DI 0 "=r,r"))]
7356 "TARGET_64BIT && rs6000_gen_cell_microcode"
7357 "@
7358 #
7359 #"
7360 "&& reload_completed"
7361 [(set (match_dup 0)
7362 (and:DI (rotate:DI (match_dup 1)
7363 (match_dup 4))
7364 (match_dup 5)))
7365 (parallel [(set (match_dup 3)
7366 (compare:CC (and:DI (rotate:DI (match_dup 0)
7367 (match_dup 6))
7368 (match_dup 7))
7369 (const_int 0)))
7370 (clobber (match_dup 0))])]
7371 {
7372 build_mask64_2_operands (operands[2], &operands[4]);
7373 }
7374 [(set_attr "type" "two")
7375 (set_attr "dot" "yes")
7376 (set_attr "length" "8,12")])
7377
7378 (define_insn_and_split "*anddi3_2rld_dot2"
7379 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
7380 (compare:CC (and:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r")
7381 (match_operand:DI 2 "and_2rld_operand" "n,n"))
7382 (const_int 0)))
7383 (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
7384 (and:DI (match_dup 1)
7385 (match_dup 2)))]
7386 "TARGET_64BIT && rs6000_gen_cell_microcode"
7387 "@
7388 #
7389 #"
7390 "&& reload_completed"
7391 [(set (match_dup 0)
7392 (and:DI (rotate:DI (match_dup 1)
7393 (match_dup 4))
7394 (match_dup 5)))
7395 (parallel [(set (match_dup 3)
7396 (compare:CC (and:DI (rotate:DI (match_dup 0)
7397 (match_dup 6))
7398 (match_dup 7))
7399 (const_int 0)))
7400 (set (match_dup 0)
7401 (and:DI (rotate:DI (match_dup 0)
7402 (match_dup 6))
7403 (match_dup 7)))])]
7404 {
7405 build_mask64_2_operands (operands[2], &operands[4]);
7406 }
7407 [(set_attr "type" "two")
7408 (set_attr "dot" "yes")
7409 (set_attr "length" "8,12")])
7410 \f
7411 ;; 128-bit logical operations expanders
7412
7413 (define_expand "and<mode>3"
7414 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
7415 (and:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
7416 (match_operand:BOOL_128 2 "vlogical_operand" "")))]
7417 ""
7418 "")
7419
7420 (define_expand "ior<mode>3"
7421 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
7422 (ior:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
7423 (match_operand:BOOL_128 2 "vlogical_operand" "")))]
7424 ""
7425 "")
7426
7427 (define_expand "xor<mode>3"
7428 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
7429 (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
7430 (match_operand:BOOL_128 2 "vlogical_operand" "")))]
7431 ""
7432 "")
7433
7434 (define_expand "one_cmpl<mode>2"
7435 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
7436 (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")))]
7437 ""
7438 "")
7439
7440 (define_expand "nor<mode>3"
7441 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
7442 (and:BOOL_128
7443 (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" ""))
7444 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))))]
7445 ""
7446 "")
7447
7448 (define_expand "andc<mode>3"
7449 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
7450 (and:BOOL_128
7451 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))
7452 (match_operand:BOOL_128 1 "vlogical_operand" "")))]
7453 ""
7454 "")
7455
7456 ;; Power8 vector logical instructions.
7457 (define_expand "eqv<mode>3"
7458 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
7459 (not:BOOL_128
7460 (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
7461 (match_operand:BOOL_128 2 "vlogical_operand" ""))))]
7462 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
7463 "")
7464
7465 ;; Rewrite nand into canonical form
7466 (define_expand "nand<mode>3"
7467 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
7468 (ior:BOOL_128
7469 (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" ""))
7470 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))))]
7471 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
7472 "")
7473
7474 ;; The canonical form is to have the negated element first, so we need to
7475 ;; reverse arguments.
7476 (define_expand "orc<mode>3"
7477 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
7478 (ior:BOOL_128
7479 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))
7480 (match_operand:BOOL_128 1 "vlogical_operand" "")))]
7481 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
7482 "")
7483
7484 ;; 128-bit logical operations insns and split operations
7485 (define_insn_and_split "*and<mode>3_internal"
7486 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
7487 (and:BOOL_128
7488 (match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
7489 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")))]
7490 ""
7491 {
7492 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
7493 return "xxland %x0,%x1,%x2";
7494
7495 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
7496 return "vand %0,%1,%2";
7497
7498 return "#";
7499 }
7500 "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
7501 [(const_int 0)]
7502 {
7503 rs6000_split_logical (operands, AND, false, false, false);
7504 DONE;
7505 }
7506 [(set (attr "type")
7507 (if_then_else
7508 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
7509 (const_string "vecsimple")
7510 (const_string "integer")))
7511 (set (attr "length")
7512 (if_then_else
7513 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
7514 (const_string "4")
7515 (if_then_else
7516 (match_test "TARGET_POWERPC64")
7517 (const_string "8")
7518 (const_string "16"))))])
7519
7520 ;; 128-bit IOR/XOR
7521 (define_insn_and_split "*bool<mode>3_internal"
7522 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
7523 (match_operator:BOOL_128 3 "boolean_or_operator"
7524 [(match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
7525 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")]))]
7526 ""
7527 {
7528 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
7529 return "xxl%q3 %x0,%x1,%x2";
7530
7531 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
7532 return "v%q3 %0,%1,%2";
7533
7534 return "#";
7535 }
7536 "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
7537 [(const_int 0)]
7538 {
7539 rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, false);
7540 DONE;
7541 }
7542 [(set (attr "type")
7543 (if_then_else
7544 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
7545 (const_string "vecsimple")
7546 (const_string "integer")))
7547 (set (attr "length")
7548 (if_then_else
7549 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
7550 (const_string "4")
7551 (if_then_else
7552 (match_test "TARGET_POWERPC64")
7553 (const_string "8")
7554 (const_string "16"))))])
7555
7556 ;; 128-bit ANDC/ORC
7557 (define_insn_and_split "*boolc<mode>3_internal1"
7558 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
7559 (match_operator:BOOL_128 3 "boolean_operator"
7560 [(not:BOOL_128
7561 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))
7562 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")]))]
7563 "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
7564 {
7565 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
7566 return "xxl%q3 %x0,%x1,%x2";
7567
7568 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
7569 return "v%q3 %0,%1,%2";
7570
7571 return "#";
7572 }
7573 "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
7574 && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
7575 [(const_int 0)]
7576 {
7577 rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
7578 DONE;
7579 }
7580 [(set (attr "type")
7581 (if_then_else
7582 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
7583 (const_string "vecsimple")
7584 (const_string "integer")))
7585 (set (attr "length")
7586 (if_then_else
7587 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
7588 (const_string "4")
7589 (if_then_else
7590 (match_test "TARGET_POWERPC64")
7591 (const_string "8")
7592 (const_string "16"))))])
7593
7594 (define_insn_and_split "*boolc<mode>3_internal2"
7595 [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
7596 (match_operator:TI2 3 "boolean_operator"
7597 [(not:TI2
7598 (match_operand:TI2 2 "int_reg_operand" "r,0,r"))
7599 (match_operand:TI2 1 "int_reg_operand" "r,r,0")]))]
7600 "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
7601 "#"
7602 "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
7603 [(const_int 0)]
7604 {
7605 rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
7606 DONE;
7607 }
7608 [(set_attr "type" "integer")
7609 (set (attr "length")
7610 (if_then_else
7611 (match_test "TARGET_POWERPC64")
7612 (const_string "8")
7613 (const_string "16")))])
7614
7615 ;; 128-bit NAND/NOR
7616 (define_insn_and_split "*boolcc<mode>3_internal1"
7617 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
7618 (match_operator:BOOL_128 3 "boolean_operator"
7619 [(not:BOOL_128
7620 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>"))
7621 (not:BOOL_128
7622 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))]))]
7623 "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
7624 {
7625 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
7626 return "xxl%q3 %x0,%x1,%x2";
7627
7628 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
7629 return "v%q3 %0,%1,%2";
7630
7631 return "#";
7632 }
7633 "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
7634 && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
7635 [(const_int 0)]
7636 {
7637 rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
7638 DONE;
7639 }
7640 [(set (attr "type")
7641 (if_then_else
7642 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
7643 (const_string "vecsimple")
7644 (const_string "integer")))
7645 (set (attr "length")
7646 (if_then_else
7647 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
7648 (const_string "4")
7649 (if_then_else
7650 (match_test "TARGET_POWERPC64")
7651 (const_string "8")
7652 (const_string "16"))))])
7653
7654 (define_insn_and_split "*boolcc<mode>3_internal2"
7655 [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
7656 (match_operator:TI2 3 "boolean_operator"
7657 [(not:TI2
7658 (match_operand:TI2 1 "int_reg_operand" "r,0,r"))
7659 (not:TI2
7660 (match_operand:TI2 2 "int_reg_operand" "r,r,0"))]))]
7661 "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
7662 "#"
7663 "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
7664 [(const_int 0)]
7665 {
7666 rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
7667 DONE;
7668 }
7669 [(set_attr "type" "integer")
7670 (set (attr "length")
7671 (if_then_else
7672 (match_test "TARGET_POWERPC64")
7673 (const_string "8")
7674 (const_string "16")))])
7675
7676
7677 ;; 128-bit EQV
7678 (define_insn_and_split "*eqv<mode>3_internal1"
7679 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
7680 (not:BOOL_128
7681 (xor:BOOL_128
7682 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")
7683 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))))]
7684 "TARGET_P8_VECTOR"
7685 {
7686 if (vsx_register_operand (operands[0], <MODE>mode))
7687 return "xxleqv %x0,%x1,%x2";
7688
7689 return "#";
7690 }
7691 "TARGET_P8_VECTOR && reload_completed
7692 && int_reg_operand (operands[0], <MODE>mode)"
7693 [(const_int 0)]
7694 {
7695 rs6000_split_logical (operands, XOR, true, false, false);
7696 DONE;
7697 }
7698 [(set (attr "type")
7699 (if_then_else
7700 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
7701 (const_string "vecsimple")
7702 (const_string "integer")))
7703 (set (attr "length")
7704 (if_then_else
7705 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
7706 (const_string "4")
7707 (if_then_else
7708 (match_test "TARGET_POWERPC64")
7709 (const_string "8")
7710 (const_string "16"))))])
7711
7712 (define_insn_and_split "*eqv<mode>3_internal2"
7713 [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
7714 (not:TI2
7715 (xor:TI2
7716 (match_operand:TI2 1 "int_reg_operand" "r,0,r")
7717 (match_operand:TI2 2 "int_reg_operand" "r,r,0"))))]
7718 "!TARGET_P8_VECTOR"
7719 "#"
7720 "reload_completed && !TARGET_P8_VECTOR"
7721 [(const_int 0)]
7722 {
7723 rs6000_split_logical (operands, XOR, true, false, false);
7724 DONE;
7725 }
7726 [(set_attr "type" "integer")
7727 (set (attr "length")
7728 (if_then_else
7729 (match_test "TARGET_POWERPC64")
7730 (const_string "8")
7731 (const_string "16")))])
7732
7733 ;; 128-bit one's complement
7734 (define_insn_and_split "*one_cmpl<mode>3_internal"
7735 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
7736 (not:BOOL_128
7737 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_UNARY>")))]
7738 ""
7739 {
7740 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
7741 return "xxlnor %x0,%x1,%x1";
7742
7743 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
7744 return "vnor %0,%1,%1";
7745
7746 return "#";
7747 }
7748 "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
7749 [(const_int 0)]
7750 {
7751 rs6000_split_logical (operands, NOT, false, false, false);
7752 DONE;
7753 }
7754 [(set (attr "type")
7755 (if_then_else
7756 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
7757 (const_string "vecsimple")
7758 (const_string "integer")))
7759 (set (attr "length")
7760 (if_then_else
7761 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
7762 (const_string "4")
7763 (if_then_else
7764 (match_test "TARGET_POWERPC64")
7765 (const_string "8")
7766 (const_string "16"))))])
7767
7768 \f
7769 ;; Now define ways of moving data around.
7770
7771 ;; Set up a register with a value from the GOT table
7772
7773 (define_expand "movsi_got"
7774 [(set (match_operand:SI 0 "gpc_reg_operand" "")
7775 (unspec:SI [(match_operand:SI 1 "got_operand" "")
7776 (match_dup 2)] UNSPEC_MOVSI_GOT))]
7777 "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
7778 "
7779 {
7780 if (GET_CODE (operands[1]) == CONST)
7781 {
7782 rtx offset = const0_rtx;
7783 HOST_WIDE_INT value;
7784
7785 operands[1] = eliminate_constant_term (XEXP (operands[1], 0), &offset);
7786 value = INTVAL (offset);
7787 if (value != 0)
7788 {
7789 rtx tmp = (!can_create_pseudo_p ()
7790 ? operands[0]
7791 : gen_reg_rtx (Pmode));
7792 emit_insn (gen_movsi_got (tmp, operands[1]));
7793 emit_insn (gen_addsi3 (operands[0], tmp, offset));
7794 DONE;
7795 }
7796 }
7797
7798 operands[2] = rs6000_got_register (operands[1]);
7799 }")
7800
7801 (define_insn "*movsi_got_internal"
7802 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
7803 (unspec:SI [(match_operand:SI 1 "got_no_const_operand" "")
7804 (match_operand:SI 2 "gpc_reg_operand" "b")]
7805 UNSPEC_MOVSI_GOT))]
7806 "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
7807 "lwz %0,%a1@got(%2)"
7808 [(set_attr "type" "load")])
7809
7810 ;; Used by sched, shorten_branches and final when the GOT pseudo reg
7811 ;; didn't get allocated to a hard register.
7812 (define_split
7813 [(set (match_operand:SI 0 "gpc_reg_operand" "")
7814 (unspec:SI [(match_operand:SI 1 "got_no_const_operand" "")
7815 (match_operand:SI 2 "memory_operand" "")]
7816 UNSPEC_MOVSI_GOT))]
7817 "DEFAULT_ABI == ABI_V4
7818 && flag_pic == 1
7819 && (reload_in_progress || reload_completed)"
7820 [(set (match_dup 0) (match_dup 2))
7821 (set (match_dup 0) (unspec:SI [(match_dup 1)(match_dup 0)]
7822 UNSPEC_MOVSI_GOT))]
7823 "")
7824
7825 ;; For SI, we special-case integers that can't be loaded in one insn. We
7826 ;; do the load 16-bits at a time. We could do this by loading from memory,
7827 ;; and this is even supposed to be faster, but it is simpler not to get
7828 ;; integers in the TOC.
7829 (define_insn "movsi_low"
7830 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
7831 (mem:SI (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
7832 (match_operand 2 "" ""))))]
7833 "TARGET_MACHO && ! TARGET_64BIT"
7834 "lwz %0,lo16(%2)(%1)"
7835 [(set_attr "type" "load")
7836 (set_attr "length" "4")])
7837
7838 (define_insn "*movsi_internal1"
7839 [(set (match_operand:SI 0 "rs6000_nonimmediate_operand" "=r,r,r,m,r,r,r,r,*c*l,*h,*h")
7840 (match_operand:SI 1 "input_operand" "r,U,m,r,I,L,n,*h,r,r,0"))]
7841 "!TARGET_SINGLE_FPU &&
7842 (gpc_reg_operand (operands[0], SImode) || gpc_reg_operand (operands[1], SImode))"
7843 "@
7844 mr %0,%1
7845 la %0,%a1
7846 lwz%U1%X1 %0,%1
7847 stw%U0%X0 %1,%0
7848 li %0,%1
7849 lis %0,%v1
7850 #
7851 mf%1 %0
7852 mt%0 %1
7853 mt%0 %1
7854 nop"
7855 [(set_attr "type" "*,*,load,store,*,*,*,mfjmpr,mtjmpr,*,*")
7856 (set_attr "length" "4,4,4,4,4,4,8,4,4,4,4")])
7857
7858 (define_insn "*movsi_internal1_single"
7859 [(set (match_operand:SI 0 "rs6000_nonimmediate_operand" "=r,r,r,m,r,r,r,r,*c*l,*h,*h,m,*f")
7860 (match_operand:SI 1 "input_operand" "r,U,m,r,I,L,n,*h,r,r,0,f,m"))]
7861 "TARGET_SINGLE_FPU &&
7862 (gpc_reg_operand (operands[0], SImode) || gpc_reg_operand (operands[1], SImode))"
7863 "@
7864 mr %0,%1
7865 la %0,%a1
7866 lwz%U1%X1 %0,%1
7867 stw%U0%X0 %1,%0
7868 li %0,%1
7869 lis %0,%v1
7870 #
7871 mf%1 %0
7872 mt%0 %1
7873 mt%0 %1
7874 nop
7875 stfs%U0%X0 %1,%0
7876 lfs%U1%X1 %0,%1"
7877 [(set_attr "type" "*,*,load,store,*,*,*,mfjmpr,mtjmpr,*,*,fpstore,fpload")
7878 (set_attr "length" "4,4,4,4,4,4,8,4,4,4,4,4,4")])
7879
7880 ;; Split a load of a large constant into the appropriate two-insn
7881 ;; sequence.
7882
7883 (define_split
7884 [(set (match_operand:SI 0 "gpc_reg_operand" "")
7885 (match_operand:SI 1 "const_int_operand" ""))]
7886 "(unsigned HOST_WIDE_INT) (INTVAL (operands[1]) + 0x8000) >= 0x10000
7887 && (INTVAL (operands[1]) & 0xffff) != 0"
7888 [(set (match_dup 0)
7889 (match_dup 2))
7890 (set (match_dup 0)
7891 (ior:SI (match_dup 0)
7892 (match_dup 3)))]
7893 "
7894 {
7895 if (rs6000_emit_set_const (operands[0], operands[1]))
7896 DONE;
7897 else
7898 FAIL;
7899 }")
7900
7901 (define_insn "*mov<mode>_internal2"
7902 [(set (match_operand:CC 2 "cc_reg_operand" "=y,x,?y")
7903 (compare:CC (match_operand:P 1 "gpc_reg_operand" "0,r,r")
7904 (const_int 0)))
7905 (set (match_operand:P 0 "gpc_reg_operand" "=r,r,r") (match_dup 1))]
7906 ""
7907 "@
7908 cmp<wd>i %2,%0,0
7909 mr. %0,%1
7910 #"
7911 [(set_attr "type" "cmp,logical,cmp")
7912 (set_attr "dot" "yes")
7913 (set_attr "length" "4,4,8")])
7914
7915 (define_split
7916 [(set (match_operand:CC 2 "cc_reg_not_micro_cr0_operand" "")
7917 (compare:CC (match_operand:P 1 "gpc_reg_operand" "")
7918 (const_int 0)))
7919 (set (match_operand:P 0 "gpc_reg_operand" "") (match_dup 1))]
7920 "reload_completed"
7921 [(set (match_dup 0) (match_dup 1))
7922 (set (match_dup 2)
7923 (compare:CC (match_dup 0)
7924 (const_int 0)))]
7925 "")
7926 \f
7927 (define_insn "*movhi_internal"
7928 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,m,r,r,*c*l,*h")
7929 (match_operand:HI 1 "input_operand" "r,m,r,i,*h,r,0"))]
7930 "gpc_reg_operand (operands[0], HImode)
7931 || gpc_reg_operand (operands[1], HImode)"
7932 "@
7933 mr %0,%1
7934 lhz%U1%X1 %0,%1
7935 sth%U0%X0 %1,%0
7936 li %0,%w1
7937 mf%1 %0
7938 mt%0 %1
7939 nop"
7940 [(set_attr "type" "*,load,store,*,mfjmpr,mtjmpr,*")])
7941
7942 (define_expand "mov<mode>"
7943 [(set (match_operand:INT 0 "general_operand" "")
7944 (match_operand:INT 1 "any_operand" ""))]
7945 ""
7946 "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
7947
7948 (define_insn "*movqi_internal"
7949 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m,r,r,*c*l,*h")
7950 (match_operand:QI 1 "input_operand" "r,m,r,i,*h,r,0"))]
7951 "gpc_reg_operand (operands[0], QImode)
7952 || gpc_reg_operand (operands[1], QImode)"
7953 "@
7954 mr %0,%1
7955 lbz%U1%X1 %0,%1
7956 stb%U0%X0 %1,%0
7957 li %0,%1
7958 mf%1 %0
7959 mt%0 %1
7960 nop"
7961 [(set_attr "type" "*,load,store,*,mfjmpr,mtjmpr,*")])
7962 \f
7963 ;; Here is how to move condition codes around. When we store CC data in
7964 ;; an integer register or memory, we store just the high-order 4 bits.
7965 ;; This lets us not shift in the most common case of CR0.
7966 (define_expand "movcc"
7967 [(set (match_operand:CC 0 "nonimmediate_operand" "")
7968 (match_operand:CC 1 "nonimmediate_operand" ""))]
7969 ""
7970 "")
7971
7972 (define_insn "*movcc_internal1"
7973 [(set (match_operand:CC 0 "nonimmediate_operand" "=y,x,?y,y,r,r,r,r,r,cl,r,m")
7974 (match_operand:CC 1 "general_operand" "y,r,r,O,x,y,r,I,h,r,m,r"))]
7975 "register_operand (operands[0], CCmode)
7976 || register_operand (operands[1], CCmode)"
7977 "@
7978 mcrf %0,%1
7979 mtcrf 128,%1
7980 rlwinm %1,%1,%F0,0xffffffff\;mtcrf %R0,%1\;rlwinm %1,%1,%f0,0xffffffff
7981 crxor %0,%0,%0
7982 mfcr %0%Q1
7983 mfcr %0%Q1\;rlwinm %0,%0,%f1,0xf0000000
7984 mr %0,%1
7985 li %0,%1
7986 mf%1 %0
7987 mt%0 %1
7988 lwz%U1%X1 %0,%1
7989 stw%U0%X0 %1,%0"
7990 [(set (attr "type")
7991 (cond [(eq_attr "alternative" "0,3")
7992 (const_string "cr_logical")
7993 (eq_attr "alternative" "1,2")
7994 (const_string "mtcr")
7995 (eq_attr "alternative" "6,7")
7996 (const_string "integer")
7997 (eq_attr "alternative" "8")
7998 (const_string "mfjmpr")
7999 (eq_attr "alternative" "9")
8000 (const_string "mtjmpr")
8001 (eq_attr "alternative" "10")
8002 (const_string "load")
8003 (eq_attr "alternative" "11")
8004 (const_string "store")
8005 (match_test "TARGET_MFCRF")
8006 (const_string "mfcrf")
8007 ]
8008 (const_string "mfcr")))
8009 (set_attr "length" "4,4,12,4,4,8,4,4,4,4,4,4")])
8010 \f
8011 ;; For floating-point, we normally deal with the floating-point registers
8012 ;; unless -msoft-float is used. The sole exception is that parameter passing
8013 ;; can produce floating-point values in fixed-point registers. Unless the
8014 ;; value is a simple constant or already in memory, we deal with this by
8015 ;; allocating memory and copying the value explicitly via that memory location.
8016
8017 ;; Move 32-bit binary/decimal floating point
8018 (define_expand "mov<mode>"
8019 [(set (match_operand:FMOVE32 0 "nonimmediate_operand" "")
8020 (match_operand:FMOVE32 1 "any_operand" ""))]
8021 "<fmove_ok>"
8022 "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
8023
8024 (define_split
8025 [(set (match_operand:FMOVE32 0 "gpc_reg_operand" "")
8026 (match_operand:FMOVE32 1 "const_double_operand" ""))]
8027 "reload_completed
8028 && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
8029 || (GET_CODE (operands[0]) == SUBREG
8030 && GET_CODE (SUBREG_REG (operands[0])) == REG
8031 && REGNO (SUBREG_REG (operands[0])) <= 31))"
8032 [(set (match_dup 2) (match_dup 3))]
8033 "
8034 {
8035 long l;
8036 REAL_VALUE_TYPE rv;
8037
8038 REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]);
8039 <real_value_to_target> (rv, l);
8040
8041 if (! TARGET_POWERPC64)
8042 operands[2] = operand_subword (operands[0], 0, 0, <MODE>mode);
8043 else
8044 operands[2] = gen_lowpart (SImode, operands[0]);
8045
8046 operands[3] = gen_int_mode (l, SImode);
8047 }")
8048
8049 (define_insn "mov<mode>_hardfloat"
8050 [(set (match_operand:FMOVE32 0 "nonimmediate_operand" "=!r,!r,m,f,<f32_vsx>,<f32_vsx>,<f32_lr>,<f32_sm>,<f32_av>,Z,?<f32_dm>,?r,*c*l,!r,*h,!r,!r")
8051 (match_operand:FMOVE32 1 "input_operand" "r,m,r,f,<f32_vsx>,j,<f32_lm>,<f32_sr>,Z,<f32_av>,r,<f32_dm>,r,h,0,G,Fn"))]
8052 "(gpc_reg_operand (operands[0], <MODE>mode)
8053 || gpc_reg_operand (operands[1], <MODE>mode))
8054 && (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT)"
8055 "@
8056 mr %0,%1
8057 lwz%U1%X1 %0,%1
8058 stw%U0%X0 %1,%0
8059 fmr %0,%1
8060 xxlor %x0,%x1,%x1
8061 xxlxor %x0,%x0,%x0
8062 <f32_li>
8063 <f32_si>
8064 <f32_lv>
8065 <f32_sv>
8066 mtvsrwz %x0,%1
8067 mfvsrwz %0,%x1
8068 mt%0 %1
8069 mf%1 %0
8070 nop
8071 #
8072 #"
8073 [(set_attr "type" "*,load,store,fp,vecsimple,vecsimple,fpload,fpstore,fpload,fpstore,mftgpr,mffgpr,mtjmpr,mfjmpr,*,*,*")
8074 (set_attr "length" "4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,8")])
8075
8076 (define_insn "*mov<mode>_softfloat"
8077 [(set (match_operand:FMOVE32 0 "nonimmediate_operand" "=r,cl,r,r,m,r,r,r,r,*h")
8078 (match_operand:FMOVE32 1 "input_operand" "r,r,h,m,r,I,L,G,Fn,0"))]
8079 "(gpc_reg_operand (operands[0], <MODE>mode)
8080 || gpc_reg_operand (operands[1], <MODE>mode))
8081 && (TARGET_SOFT_FLOAT || !TARGET_FPRS)"
8082 "@
8083 mr %0,%1
8084 mt%0 %1
8085 mf%1 %0
8086 lwz%U1%X1 %0,%1
8087 stw%U0%X0 %1,%0
8088 li %0,%1
8089 lis %0,%v1
8090 #
8091 #
8092 nop"
8093 [(set_attr "type" "*,mtjmpr,mfjmpr,load,store,*,*,*,*,*")
8094 (set_attr "length" "4,4,4,4,4,4,4,4,8,4")])
8095
8096 \f
8097 ;; Move 64-bit binary/decimal floating point
8098 (define_expand "mov<mode>"
8099 [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "")
8100 (match_operand:FMOVE64 1 "any_operand" ""))]
8101 ""
8102 "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
8103
8104 (define_split
8105 [(set (match_operand:FMOVE64 0 "gpc_reg_operand" "")
8106 (match_operand:FMOVE64 1 "const_int_operand" ""))]
8107 "! TARGET_POWERPC64 && reload_completed
8108 && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
8109 || (GET_CODE (operands[0]) == SUBREG
8110 && GET_CODE (SUBREG_REG (operands[0])) == REG
8111 && REGNO (SUBREG_REG (operands[0])) <= 31))"
8112 [(set (match_dup 2) (match_dup 4))
8113 (set (match_dup 3) (match_dup 1))]
8114 "
8115 {
8116 int endian = (WORDS_BIG_ENDIAN == 0);
8117 HOST_WIDE_INT value = INTVAL (operands[1]);
8118
8119 operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
8120 operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
8121 operands[4] = GEN_INT (value >> 32);
8122 operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
8123 }")
8124
8125 (define_split
8126 [(set (match_operand:FMOVE64 0 "gpc_reg_operand" "")
8127 (match_operand:FMOVE64 1 "const_double_operand" ""))]
8128 "! TARGET_POWERPC64 && reload_completed
8129 && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
8130 || (GET_CODE (operands[0]) == SUBREG
8131 && GET_CODE (SUBREG_REG (operands[0])) == REG
8132 && REGNO (SUBREG_REG (operands[0])) <= 31))"
8133 [(set (match_dup 2) (match_dup 4))
8134 (set (match_dup 3) (match_dup 5))]
8135 "
8136 {
8137 int endian = (WORDS_BIG_ENDIAN == 0);
8138 long l[2];
8139 REAL_VALUE_TYPE rv;
8140
8141 REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]);
8142 <real_value_to_target> (rv, l);
8143
8144 operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
8145 operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
8146 operands[4] = gen_int_mode (l[endian], SImode);
8147 operands[5] = gen_int_mode (l[1 - endian], SImode);
8148 }")
8149
8150 (define_split
8151 [(set (match_operand:FMOVE64 0 "gpc_reg_operand" "")
8152 (match_operand:FMOVE64 1 "const_double_operand" ""))]
8153 "TARGET_POWERPC64 && reload_completed
8154 && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
8155 || (GET_CODE (operands[0]) == SUBREG
8156 && GET_CODE (SUBREG_REG (operands[0])) == REG
8157 && REGNO (SUBREG_REG (operands[0])) <= 31))"
8158 [(set (match_dup 2) (match_dup 3))]
8159 "
8160 {
8161 int endian = (WORDS_BIG_ENDIAN == 0);
8162 long l[2];
8163 REAL_VALUE_TYPE rv;
8164 HOST_WIDE_INT val;
8165
8166 REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]);
8167 <real_value_to_target> (rv, l);
8168
8169 operands[2] = gen_lowpart (DImode, operands[0]);
8170 /* HIGHPART is lower memory address when WORDS_BIG_ENDIAN. */
8171 val = ((HOST_WIDE_INT)(unsigned long)l[endian] << 32
8172 | ((HOST_WIDE_INT)(unsigned long)l[1 - endian]));
8173
8174 operands[3] = gen_int_mode (val, DImode);
8175 }")
8176
8177 ;; Don't have reload use general registers to load a constant. It is
8178 ;; less efficient than loading the constant into an FP register, since
8179 ;; it will probably be used there.
8180
8181 ;; The move constraints are ordered to prefer floating point registers before
8182 ;; general purpose registers to avoid doing a store and a load to get the value
8183 ;; into a floating point register when it is needed for a floating point
8184 ;; operation. Prefer traditional floating point registers over VSX registers,
8185 ;; since the D-form version of the memory instructions does not need a GPR for
8186 ;; reloading.
8187
8188 (define_insn "*mov<mode>_hardfloat32"
8189 [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=m,d,d,<f64_av>,Z,<f64_vsx>,<f64_vsx>,Y,r,!r,!r,!r,!r")
8190 (match_operand:FMOVE64 1 "input_operand" "d,m,d,Z,<f64_av>,<f64_vsx>,j,r,Y,r,G,H,F"))]
8191 "! TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
8192 && (gpc_reg_operand (operands[0], <MODE>mode)
8193 || gpc_reg_operand (operands[1], <MODE>mode))"
8194 "@
8195 stfd%U0%X0 %1,%0
8196 lfd%U1%X1 %0,%1
8197 fmr %0,%1
8198 lxsd%U1x %x0,%y1
8199 stxsd%U0x %x1,%y0
8200 xxlor %x0,%x1,%x1
8201 xxlxor %x0,%x0,%x0
8202 #
8203 #
8204 #
8205 #
8206 #
8207 #"
8208 [(set_attr "type" "fpstore,fpload,fp,fpload,fpstore,vecsimple,vecsimple,store,load,two,fp,fp,*")
8209 (set_attr "length" "4,4,4,4,4,4,4,8,8,8,8,12,16")])
8210
8211 (define_insn "*mov<mode>_softfloat32"
8212 [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=Y,r,r,r,r,r")
8213 (match_operand:FMOVE64 1 "input_operand" "r,Y,r,G,H,F"))]
8214 "! TARGET_POWERPC64
8215 && ((TARGET_FPRS && TARGET_SINGLE_FLOAT)
8216 || TARGET_SOFT_FLOAT || TARGET_E500_SINGLE
8217 || (<MODE>mode == DDmode && TARGET_E500_DOUBLE))
8218 && (gpc_reg_operand (operands[0], <MODE>mode)
8219 || gpc_reg_operand (operands[1], <MODE>mode))"
8220 "#"
8221 [(set_attr "type" "store,load,two,*,*,*")
8222 (set_attr "length" "8,8,8,8,12,16")])
8223
8224 ; ld/std require word-aligned displacements -> 'Y' constraint.
8225 ; List Y->r and r->Y before r->r for reload.
8226 (define_insn "*mov<mode>_hardfloat64"
8227 [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=m,d,d,<f64_av>,Z,<f64_vsx>,<f64_vsx>,Y,r,!r,*c*l,!r,*h,!r,!r,!r,r,wg,r,<f64_dm>")
8228 (match_operand:FMOVE64 1 "input_operand" "d,m,d,Z,<f64_av>,<f64_vsx>,j,r,Y,r,r,h,0,G,H,F,wg,r,<f64_dm>,r"))]
8229 "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
8230 && (gpc_reg_operand (operands[0], <MODE>mode)
8231 || gpc_reg_operand (operands[1], <MODE>mode))"
8232 "@
8233 stfd%U0%X0 %1,%0
8234 lfd%U1%X1 %0,%1
8235 fmr %0,%1
8236 lxsd%U1x %x0,%y1
8237 stxsd%U0x %x1,%y0
8238 xxlor %x0,%x1,%x1
8239 xxlxor %x0,%x0,%x0
8240 std%U0%X0 %1,%0
8241 ld%U1%X1 %0,%1
8242 mr %0,%1
8243 mt%0 %1
8244 mf%1 %0
8245 nop
8246 #
8247 #
8248 #
8249 mftgpr %0,%1
8250 mffgpr %0,%1
8251 mfvsrd %0,%x1
8252 mtvsrd %x0,%1"
8253 [(set_attr "type" "fpstore,fpload,fp,fpload,fpstore,vecsimple,vecsimple,store,load,*,mtjmpr,mfjmpr,*,*,*,*,mftgpr,mffgpr,mftgpr,mffgpr")
8254 (set_attr "length" "4,4,4,4,4,4,4,4,4,4,4,4,4,8,12,16,4,4,4,4")])
8255
8256 (define_insn "*mov<mode>_softfloat64"
8257 [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=Y,r,r,cl,r,r,r,r,*h")
8258 (match_operand:FMOVE64 1 "input_operand" "r,Y,r,r,h,G,H,F,0"))]
8259 "TARGET_POWERPC64 && (TARGET_SOFT_FLOAT || !TARGET_FPRS)
8260 && (gpc_reg_operand (operands[0], <MODE>mode)
8261 || gpc_reg_operand (operands[1], <MODE>mode))"
8262 "@
8263 std%U0%X0 %1,%0
8264 ld%U1%X1 %0,%1
8265 mr %0,%1
8266 mt%0 %1
8267 mf%1 %0
8268 #
8269 #
8270 #
8271 nop"
8272 [(set_attr "type" "store,load,*,mtjmpr,mfjmpr,*,*,*,*")
8273 (set_attr "length" "4,4,4,4,4,8,12,16,4")])
8274 \f
8275 (define_expand "mov<mode>"
8276 [(set (match_operand:FMOVE128 0 "general_operand" "")
8277 (match_operand:FMOVE128 1 "any_operand" ""))]
8278 ""
8279 "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
8280
8281 ;; It's important to list Y->r and r->Y before r->r because otherwise
8282 ;; reload, given m->r, will try to pick r->r and reload it, which
8283 ;; doesn't make progress.
8284
8285 ;; We can't split little endian direct moves of TDmode, because the words are
8286 ;; not swapped like they are for TImode or TFmode. Subregs therefore are
8287 ;; problematical. Don't allow direct move for this case.
8288
8289 (define_insn_and_split "*mov<mode>_64bit_dm"
8290 [(set (match_operand:FMOVE128 0 "nonimmediate_operand" "=m,d,d,ws,Y,r,r,r,wm")
8291 (match_operand:FMOVE128 1 "input_operand" "d,m,d,j,r,jYGHF,r,wm,r"))]
8292 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_POWERPC64
8293 && (<MODE>mode != TDmode || WORDS_BIG_ENDIAN)
8294 && (gpc_reg_operand (operands[0], <MODE>mode)
8295 || gpc_reg_operand (operands[1], <MODE>mode))"
8296 "#"
8297 "&& reload_completed"
8298 [(pc)]
8299 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
8300 [(set_attr "length" "8,8,8,8,12,12,8,8,8")])
8301
8302 (define_insn_and_split "*movtd_64bit_nodm"
8303 [(set (match_operand:TD 0 "nonimmediate_operand" "=m,d,d,ws,Y,r,r")
8304 (match_operand:TD 1 "input_operand" "d,m,d,j,r,jYGHF,r"))]
8305 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_POWERPC64 && !WORDS_BIG_ENDIAN
8306 && (gpc_reg_operand (operands[0], TDmode)
8307 || gpc_reg_operand (operands[1], TDmode))"
8308 "#"
8309 "&& reload_completed"
8310 [(pc)]
8311 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
8312 [(set_attr "length" "8,8,8,8,12,12,8")])
8313
8314 (define_insn_and_split "*mov<mode>_32bit"
8315 [(set (match_operand:FMOVE128 0 "nonimmediate_operand" "=m,d,d,ws,Y,r,r")
8316 (match_operand:FMOVE128 1 "input_operand" "d,m,d,j,r,jYGHF,r"))]
8317 "TARGET_HARD_FLOAT && TARGET_FPRS && !TARGET_POWERPC64
8318 && (gpc_reg_operand (operands[0], <MODE>mode)
8319 || gpc_reg_operand (operands[1], <MODE>mode))"
8320 "#"
8321 "&& reload_completed"
8322 [(pc)]
8323 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
8324 [(set_attr "length" "8,8,8,8,20,20,16")])
8325
8326 (define_insn_and_split "*mov<mode>_softfloat"
8327 [(set (match_operand:FMOVE128 0 "rs6000_nonimmediate_operand" "=Y,r,r")
8328 (match_operand:FMOVE128 1 "input_operand" "r,YGHF,r"))]
8329 "(TARGET_SOFT_FLOAT || !TARGET_FPRS)
8330 && (gpc_reg_operand (operands[0], <MODE>mode)
8331 || gpc_reg_operand (operands[1], <MODE>mode))"
8332 "#"
8333 "&& reload_completed"
8334 [(pc)]
8335 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
8336 [(set_attr "length" "20,20,16")])
8337
8338 ;; If we are using -ffast-math, easy_fp_constant assumes all constants are
8339 ;; 'easy' in order to allow for reciprocal estimation. Make sure the constant
8340 ;; is in the constant pool before reload occurs. This simplifies accessing
8341 ;; scalars in the traditional Altivec registers.
8342
8343 (define_split
8344 [(set (match_operand:SFDF 0 "register_operand" "")
8345 (match_operand:SFDF 1 "memory_fp_constant" ""))]
8346 "TARGET_<MODE>_FPR && flag_unsafe_math_optimizations
8347 && !reload_in_progress && !reload_completed && !lra_in_progress"
8348 [(set (match_dup 0) (match_dup 2))]
8349 {
8350 operands[2] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
8351 })
8352
8353 (define_expand "extenddftf2"
8354 [(set (match_operand:TF 0 "nonimmediate_operand" "")
8355 (float_extend:TF (match_operand:DF 1 "input_operand" "")))]
8356 "!TARGET_IEEEQUAD
8357 && TARGET_HARD_FLOAT
8358 && (TARGET_FPRS || TARGET_E500_DOUBLE)
8359 && TARGET_LONG_DOUBLE_128"
8360 {
8361 if (TARGET_E500_DOUBLE)
8362 emit_insn (gen_spe_extenddftf2 (operands[0], operands[1]));
8363 else
8364 emit_insn (gen_extenddftf2_fprs (operands[0], operands[1]));
8365 DONE;
8366 })
8367
8368 (define_expand "extenddftf2_fprs"
8369 [(parallel [(set (match_operand:TF 0 "nonimmediate_operand" "")
8370 (float_extend:TF (match_operand:DF 1 "input_operand" "")))
8371 (use (match_dup 2))])]
8372 "!TARGET_IEEEQUAD
8373 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
8374 && TARGET_LONG_DOUBLE_128"
8375 {
8376 operands[2] = CONST0_RTX (DFmode);
8377 /* Generate GOT reference early for SVR4 PIC. */
8378 if (DEFAULT_ABI == ABI_V4 && flag_pic)
8379 operands[2] = validize_mem (force_const_mem (DFmode, operands[2]));
8380 })
8381
8382 (define_insn_and_split "*extenddftf2_internal"
8383 [(set (match_operand:TF 0 "nonimmediate_operand" "=m,Y,d,&d,r")
8384 (float_extend:TF (match_operand:DF 1 "input_operand" "d,r,md,md,rmGHF")))
8385 (use (match_operand:DF 2 "zero_reg_mem_operand" "d,r,m,d,n"))]
8386 "!TARGET_IEEEQUAD
8387 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
8388 && TARGET_LONG_DOUBLE_128"
8389 "#"
8390 "&& reload_completed"
8391 [(pc)]
8392 {
8393 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
8394 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
8395 emit_move_insn (simplify_gen_subreg (DFmode, operands[0], TFmode, hi_word),
8396 operands[1]);
8397 emit_move_insn (simplify_gen_subreg (DFmode, operands[0], TFmode, lo_word),
8398 operands[2]);
8399 DONE;
8400 })
8401
8402 (define_expand "extendsftf2"
8403 [(set (match_operand:TF 0 "nonimmediate_operand" "")
8404 (float_extend:TF (match_operand:SF 1 "gpc_reg_operand" "")))]
8405 "!TARGET_IEEEQUAD
8406 && TARGET_HARD_FLOAT
8407 && (TARGET_FPRS || TARGET_E500_DOUBLE)
8408 && TARGET_LONG_DOUBLE_128"
8409 {
8410 rtx tmp = gen_reg_rtx (DFmode);
8411 emit_insn (gen_extendsfdf2 (tmp, operands[1]));
8412 emit_insn (gen_extenddftf2 (operands[0], tmp));
8413 DONE;
8414 })
8415
8416 (define_expand "trunctfdf2"
8417 [(set (match_operand:DF 0 "gpc_reg_operand" "")
8418 (float_truncate:DF (match_operand:TF 1 "gpc_reg_operand" "")))]
8419 "!TARGET_IEEEQUAD
8420 && TARGET_HARD_FLOAT
8421 && (TARGET_FPRS || TARGET_E500_DOUBLE)
8422 && TARGET_LONG_DOUBLE_128"
8423 "")
8424
8425 (define_insn_and_split "trunctfdf2_internal1"
8426 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d")
8427 (float_truncate:DF (match_operand:TF 1 "gpc_reg_operand" "0,d")))]
8428 "!TARGET_IEEEQUAD && !TARGET_XL_COMPAT
8429 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
8430 "@
8431 #
8432 fmr %0,%1"
8433 "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
8434 [(const_int 0)]
8435 {
8436 emit_note (NOTE_INSN_DELETED);
8437 DONE;
8438 }
8439 [(set_attr "type" "fp")])
8440
8441 (define_insn "trunctfdf2_internal2"
8442 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
8443 (float_truncate:DF (match_operand:TF 1 "gpc_reg_operand" "d")))]
8444 "!TARGET_IEEEQUAD && TARGET_XL_COMPAT
8445 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
8446 && TARGET_LONG_DOUBLE_128"
8447 "fadd %0,%1,%L1"
8448 [(set_attr "type" "fp")
8449 (set_attr "fp_type" "fp_addsub_d")])
8450
8451 (define_expand "trunctfsf2"
8452 [(set (match_operand:SF 0 "gpc_reg_operand" "")
8453 (float_truncate:SF (match_operand:TF 1 "gpc_reg_operand" "")))]
8454 "!TARGET_IEEEQUAD
8455 && TARGET_HARD_FLOAT
8456 && (TARGET_FPRS || TARGET_E500_DOUBLE)
8457 && TARGET_LONG_DOUBLE_128"
8458 {
8459 if (TARGET_E500_DOUBLE)
8460 emit_insn (gen_spe_trunctfsf2 (operands[0], operands[1]));
8461 else
8462 emit_insn (gen_trunctfsf2_fprs (operands[0], operands[1]));
8463 DONE;
8464 })
8465
8466 (define_insn_and_split "trunctfsf2_fprs"
8467 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
8468 (float_truncate:SF (match_operand:TF 1 "gpc_reg_operand" "d")))
8469 (clobber (match_scratch:DF 2 "=d"))]
8470 "!TARGET_IEEEQUAD
8471 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
8472 && TARGET_LONG_DOUBLE_128"
8473 "#"
8474 "&& reload_completed"
8475 [(set (match_dup 2)
8476 (float_truncate:DF (match_dup 1)))
8477 (set (match_dup 0)
8478 (float_truncate:SF (match_dup 2)))]
8479 "")
8480
8481 (define_expand "floatsitf2"
8482 [(set (match_operand:TF 0 "gpc_reg_operand" "")
8483 (float:TF (match_operand:SI 1 "gpc_reg_operand" "")))]
8484 "!TARGET_IEEEQUAD
8485 && TARGET_HARD_FLOAT
8486 && (TARGET_FPRS || TARGET_E500_DOUBLE)
8487 && TARGET_LONG_DOUBLE_128"
8488 {
8489 rtx tmp = gen_reg_rtx (DFmode);
8490 expand_float (tmp, operands[1], false);
8491 emit_insn (gen_extenddftf2 (operands[0], tmp));
8492 DONE;
8493 })
8494
8495 ; fadd, but rounding towards zero.
8496 ; This is probably not the optimal code sequence.
8497 (define_insn "fix_trunc_helper"
8498 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
8499 (unspec:DF [(match_operand:TF 1 "gpc_reg_operand" "d")]
8500 UNSPEC_FIX_TRUNC_TF))
8501 (clobber (match_operand:DF 2 "gpc_reg_operand" "=&d"))]
8502 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
8503 "mffs %2\n\tmtfsb1 31\n\tmtfsb0 30\n\tfadd %0,%1,%L1\n\tmtfsf 1,%2"
8504 [(set_attr "type" "fp")
8505 (set_attr "length" "20")])
8506
8507 (define_expand "fix_trunctfsi2"
8508 [(set (match_operand:SI 0 "gpc_reg_operand" "")
8509 (fix:SI (match_operand:TF 1 "gpc_reg_operand" "")))]
8510 "!TARGET_IEEEQUAD && TARGET_HARD_FLOAT
8511 && (TARGET_FPRS || TARGET_E500_DOUBLE) && TARGET_LONG_DOUBLE_128"
8512 {
8513 if (TARGET_E500_DOUBLE)
8514 emit_insn (gen_spe_fix_trunctfsi2 (operands[0], operands[1]));
8515 else
8516 emit_insn (gen_fix_trunctfsi2_fprs (operands[0], operands[1]));
8517 DONE;
8518 })
8519
8520 (define_expand "fix_trunctfsi2_fprs"
8521 [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "")
8522 (fix:SI (match_operand:TF 1 "gpc_reg_operand" "")))
8523 (clobber (match_dup 2))
8524 (clobber (match_dup 3))
8525 (clobber (match_dup 4))
8526 (clobber (match_dup 5))])]
8527 "!TARGET_IEEEQUAD
8528 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
8529 {
8530 operands[2] = gen_reg_rtx (DFmode);
8531 operands[3] = gen_reg_rtx (DFmode);
8532 operands[4] = gen_reg_rtx (DImode);
8533 operands[5] = assign_stack_temp (DImode, GET_MODE_SIZE (DImode));
8534 })
8535
8536 (define_insn_and_split "*fix_trunctfsi2_internal"
8537 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
8538 (fix:SI (match_operand:TF 1 "gpc_reg_operand" "d")))
8539 (clobber (match_operand:DF 2 "gpc_reg_operand" "=d"))
8540 (clobber (match_operand:DF 3 "gpc_reg_operand" "=&d"))
8541 (clobber (match_operand:DI 4 "gpc_reg_operand" "=d"))
8542 (clobber (match_operand:DI 5 "offsettable_mem_operand" "=o"))]
8543 "!TARGET_IEEEQUAD
8544 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
8545 "#"
8546 ""
8547 [(pc)]
8548 {
8549 rtx lowword;
8550 emit_insn (gen_fix_trunc_helper (operands[2], operands[1], operands[3]));
8551
8552 gcc_assert (MEM_P (operands[5]));
8553 lowword = adjust_address (operands[5], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
8554
8555 emit_insn (gen_fctiwz_df (operands[4], operands[2]));
8556 emit_move_insn (operands[5], operands[4]);
8557 emit_move_insn (operands[0], lowword);
8558 DONE;
8559 })
8560
8561 (define_expand "negtf2"
8562 [(set (match_operand:TF 0 "gpc_reg_operand" "")
8563 (neg:TF (match_operand:TF 1 "gpc_reg_operand" "")))]
8564 "!TARGET_IEEEQUAD
8565 && TARGET_HARD_FLOAT
8566 && (TARGET_FPRS || TARGET_E500_DOUBLE)
8567 && TARGET_LONG_DOUBLE_128"
8568 "")
8569
8570 (define_insn "negtf2_internal"
8571 [(set (match_operand:TF 0 "gpc_reg_operand" "=d")
8572 (neg:TF (match_operand:TF 1 "gpc_reg_operand" "d")))]
8573 "!TARGET_IEEEQUAD
8574 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
8575 "*
8576 {
8577 if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
8578 return \"fneg %L0,%L1\;fneg %0,%1\";
8579 else
8580 return \"fneg %0,%1\;fneg %L0,%L1\";
8581 }"
8582 [(set_attr "type" "fp")
8583 (set_attr "length" "8")])
8584
8585 (define_expand "abstf2"
8586 [(set (match_operand:TF 0 "gpc_reg_operand" "")
8587 (abs:TF (match_operand:TF 1 "gpc_reg_operand" "")))]
8588 "!TARGET_IEEEQUAD
8589 && TARGET_HARD_FLOAT
8590 && (TARGET_FPRS || TARGET_E500_DOUBLE)
8591 && TARGET_LONG_DOUBLE_128"
8592 "
8593 {
8594 rtx label = gen_label_rtx ();
8595 if (TARGET_E500_DOUBLE)
8596 {
8597 if (flag_finite_math_only && !flag_trapping_math)
8598 emit_insn (gen_spe_abstf2_tst (operands[0], operands[1], label));
8599 else
8600 emit_insn (gen_spe_abstf2_cmp (operands[0], operands[1], label));
8601 }
8602 else
8603 emit_insn (gen_abstf2_internal (operands[0], operands[1], label));
8604 emit_label (label);
8605 DONE;
8606 }")
8607
8608 (define_expand "abstf2_internal"
8609 [(set (match_operand:TF 0 "gpc_reg_operand" "")
8610 (match_operand:TF 1 "gpc_reg_operand" ""))
8611 (set (match_dup 3) (match_dup 5))
8612 (set (match_dup 5) (abs:DF (match_dup 5)))
8613 (set (match_dup 4) (compare:CCFP (match_dup 3) (match_dup 5)))
8614 (set (pc) (if_then_else (eq (match_dup 4) (const_int 0))
8615 (label_ref (match_operand 2 "" ""))
8616 (pc)))
8617 (set (match_dup 6) (neg:DF (match_dup 6)))]
8618 "!TARGET_IEEEQUAD
8619 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
8620 && TARGET_LONG_DOUBLE_128"
8621 "
8622 {
8623 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
8624 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
8625 operands[3] = gen_reg_rtx (DFmode);
8626 operands[4] = gen_reg_rtx (CCFPmode);
8627 operands[5] = simplify_gen_subreg (DFmode, operands[0], TFmode, hi_word);
8628 operands[6] = simplify_gen_subreg (DFmode, operands[0], TFmode, lo_word);
8629 }")
8630 \f
8631 ;; Reload helper functions used by rs6000_secondary_reload. The patterns all
8632 ;; must have 3 arguments, and scratch register constraint must be a single
8633 ;; constraint.
8634
8635 ;; Reload patterns to support gpr load/store with misaligned mem.
8636 ;; and multiple gpr load/store at offset >= 0xfffc
8637 (define_expand "reload_<mode>_store"
8638 [(parallel [(match_operand 0 "memory_operand" "=m")
8639 (match_operand 1 "gpc_reg_operand" "r")
8640 (match_operand:GPR 2 "register_operand" "=&b")])]
8641 ""
8642 {
8643 rs6000_secondary_reload_gpr (operands[1], operands[0], operands[2], true);
8644 DONE;
8645 })
8646
8647 (define_expand "reload_<mode>_load"
8648 [(parallel [(match_operand 0 "gpc_reg_operand" "=r")
8649 (match_operand 1 "memory_operand" "m")
8650 (match_operand:GPR 2 "register_operand" "=b")])]
8651 ""
8652 {
8653 rs6000_secondary_reload_gpr (operands[0], operands[1], operands[2], false);
8654 DONE;
8655 })
8656
8657 \f
8658 ;; Reload patterns for various types using the vector registers. We may need
8659 ;; an additional base register to convert the reg+offset addressing to reg+reg
8660 ;; for vector registers and reg+reg or (reg+reg)&(-16) addressing to just an
8661 ;; index register for gpr registers.
8662 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_store"
8663 [(parallel [(match_operand:RELOAD 0 "memory_operand" "m")
8664 (match_operand:RELOAD 1 "gpc_reg_operand" "wa")
8665 (match_operand:P 2 "register_operand" "=b")])]
8666 "<P:tptrsize>"
8667 {
8668 rs6000_secondary_reload_inner (operands[1], operands[0], operands[2], true);
8669 DONE;
8670 })
8671
8672 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_load"
8673 [(parallel [(match_operand:RELOAD 0 "gpc_reg_operand" "wa")
8674 (match_operand:RELOAD 1 "memory_operand" "m")
8675 (match_operand:P 2 "register_operand" "=b")])]
8676 "<P:tptrsize>"
8677 {
8678 rs6000_secondary_reload_inner (operands[0], operands[1], operands[2], false);
8679 DONE;
8680 })
8681
8682
8683 ;; Reload sometimes tries to move the address to a GPR, and can generate
8684 ;; invalid RTL for addresses involving AND -16. Allow addresses involving
8685 ;; reg+reg, reg+small constant, or just reg, all wrapped in an AND -16.
8686
8687 (define_insn_and_split "*vec_reload_and_plus_<mptrsize>"
8688 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
8689 (and:P (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
8690 (match_operand:P 2 "reg_or_cint_operand" "rI"))
8691 (const_int -16)))]
8692 "TARGET_ALTIVEC && (reload_in_progress || reload_completed)"
8693 "#"
8694 "&& reload_completed"
8695 [(set (match_dup 0)
8696 (plus:P (match_dup 1)
8697 (match_dup 2)))
8698 (set (match_dup 0)
8699 (and:P (match_dup 0)
8700 (const_int -16)))])
8701 \f
8702 ;; Power8 merge instructions to allow direct move to/from floating point
8703 ;; registers in 32-bit mode. We use TF mode to get two registers to move the
8704 ;; individual 32-bit parts across. Subreg doesn't work too well on the TF
8705 ;; value, since it is allocated in reload and not all of the flow information
8706 ;; is setup for it. We have two patterns to do the two moves between gprs and
8707 ;; fprs. There isn't a dependancy between the two, but we could potentially
8708 ;; schedule other instructions between the two instructions. TFmode is
8709 ;; currently limited to traditional FPR registers. If/when this is changed, we
8710 ;; will need to revist %L to make sure it works with VSX registers, or add an
8711 ;; %x version of %L.
8712
8713 (define_insn "p8_fmrgow_<mode>"
8714 [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
8715 (unspec:FMOVE64X [(match_operand:TF 1 "register_operand" "d")]
8716 UNSPEC_P8V_FMRGOW))]
8717 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8718 "fmrgow %0,%1,%L1"
8719 [(set_attr "type" "vecperm")])
8720
8721 (define_insn "p8_mtvsrwz_1"
8722 [(set (match_operand:TF 0 "register_operand" "=d")
8723 (unspec:TF [(match_operand:SI 1 "register_operand" "r")]
8724 UNSPEC_P8V_MTVSRWZ))]
8725 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8726 "mtvsrwz %x0,%1"
8727 [(set_attr "type" "mftgpr")])
8728
8729 (define_insn "p8_mtvsrwz_2"
8730 [(set (match_operand:TF 0 "register_operand" "+d")
8731 (unspec:TF [(match_dup 0)
8732 (match_operand:SI 1 "register_operand" "r")]
8733 UNSPEC_P8V_MTVSRWZ))]
8734 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8735 "mtvsrwz %L0,%1"
8736 [(set_attr "type" "mftgpr")])
8737
8738 (define_insn_and_split "reload_fpr_from_gpr<mode>"
8739 [(set (match_operand:FMOVE64X 0 "register_operand" "=ws")
8740 (unspec:FMOVE64X [(match_operand:FMOVE64X 1 "register_operand" "r")]
8741 UNSPEC_P8V_RELOAD_FROM_GPR))
8742 (clobber (match_operand:TF 2 "register_operand" "=d"))]
8743 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8744 "#"
8745 "&& reload_completed"
8746 [(const_int 0)]
8747 {
8748 rtx dest = operands[0];
8749 rtx src = operands[1];
8750 rtx tmp = operands[2];
8751 rtx gpr_hi_reg = gen_highpart (SImode, src);
8752 rtx gpr_lo_reg = gen_lowpart (SImode, src);
8753
8754 emit_insn (gen_p8_mtvsrwz_1 (tmp, gpr_hi_reg));
8755 emit_insn (gen_p8_mtvsrwz_2 (tmp, gpr_lo_reg));
8756 emit_insn (gen_p8_fmrgow_<mode> (dest, tmp));
8757 DONE;
8758 }
8759 [(set_attr "length" "12")
8760 (set_attr "type" "three")])
8761
8762 ;; Move 128 bit values from GPRs to VSX registers in 64-bit mode
8763 (define_insn "p8_mtvsrd_1"
8764 [(set (match_operand:TF 0 "register_operand" "=ws")
8765 (unspec:TF [(match_operand:DI 1 "register_operand" "r")]
8766 UNSPEC_P8V_MTVSRD))]
8767 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8768 "mtvsrd %0,%1"
8769 [(set_attr "type" "mftgpr")])
8770
8771 (define_insn "p8_mtvsrd_2"
8772 [(set (match_operand:TF 0 "register_operand" "+ws")
8773 (unspec:TF [(match_dup 0)
8774 (match_operand:DI 1 "register_operand" "r")]
8775 UNSPEC_P8V_MTVSRD))]
8776 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8777 "mtvsrd %L0,%1"
8778 [(set_attr "type" "mftgpr")])
8779
8780 (define_insn "p8_xxpermdi_<mode>"
8781 [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
8782 (unspec:FMOVE128_GPR [(match_operand:TF 1 "register_operand" "ws")]
8783 UNSPEC_P8V_XXPERMDI))]
8784 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8785 "xxpermdi %x0,%1,%L1,0"
8786 [(set_attr "type" "vecperm")])
8787
8788 (define_insn_and_split "reload_vsx_from_gpr<mode>"
8789 [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
8790 (unspec:FMOVE128_GPR
8791 [(match_operand:FMOVE128_GPR 1 "register_operand" "r")]
8792 UNSPEC_P8V_RELOAD_FROM_GPR))
8793 (clobber (match_operand:TF 2 "register_operand" "=ws"))]
8794 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8795 "#"
8796 "&& reload_completed"
8797 [(const_int 0)]
8798 {
8799 rtx dest = operands[0];
8800 rtx src = operands[1];
8801 rtx tmp = operands[2];
8802 rtx gpr_hi_reg = gen_highpart (DImode, src);
8803 rtx gpr_lo_reg = gen_lowpart (DImode, src);
8804
8805 emit_insn (gen_p8_mtvsrd_1 (tmp, gpr_hi_reg));
8806 emit_insn (gen_p8_mtvsrd_2 (tmp, gpr_lo_reg));
8807 emit_insn (gen_p8_xxpermdi_<mode> (dest, tmp));
8808 }
8809 [(set_attr "length" "12")
8810 (set_attr "type" "three")])
8811
8812 (define_split
8813 [(set (match_operand:FMOVE128_GPR 0 "nonimmediate_operand" "")
8814 (match_operand:FMOVE128_GPR 1 "input_operand" ""))]
8815 "reload_completed
8816 && (int_reg_operand (operands[0], <MODE>mode)
8817 || int_reg_operand (operands[1], <MODE>mode))"
8818 [(pc)]
8819 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
8820
8821 ;; Move SFmode to a VSX from a GPR register. Because scalar floating point
8822 ;; type is stored internally as double precision in the VSX registers, we have
8823 ;; to convert it from the vector format.
8824
8825 (define_insn_and_split "reload_vsx_from_gprsf"
8826 [(set (match_operand:SF 0 "register_operand" "=wa")
8827 (unspec:SF [(match_operand:SF 1 "register_operand" "r")]
8828 UNSPEC_P8V_RELOAD_FROM_GPR))
8829 (clobber (match_operand:DI 2 "register_operand" "=r"))]
8830 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8831 "#"
8832 "&& reload_completed"
8833 [(const_int 0)]
8834 {
8835 rtx op0 = operands[0];
8836 rtx op1 = operands[1];
8837 rtx op2 = operands[2];
8838 /* Also use the destination register to hold the unconverted DImode value.
8839 This is conceptually a separate value from OP0, so we use gen_rtx_REG
8840 rather than simplify_gen_subreg. */
8841 rtx op0_di = gen_rtx_REG (DImode, REGNO (op0));
8842 rtx op1_di = simplify_gen_subreg (DImode, op1, SFmode, 0);
8843
8844 /* Move SF value to upper 32-bits for xscvspdpn. */
8845 emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32)));
8846 emit_move_insn (op0_di, op2);
8847 emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0_di));
8848 DONE;
8849 }
8850 [(set_attr "length" "8")
8851 (set_attr "type" "two")])
8852
8853 ;; Move 128 bit values from VSX registers to GPRs in 64-bit mode by doing a
8854 ;; normal 64-bit move, followed by an xxpermdi to get the bottom 64-bit value,
8855 ;; and then doing a move of that.
8856 (define_insn "p8_mfvsrd_3_<mode>"
8857 [(set (match_operand:DF 0 "register_operand" "=r")
8858 (unspec:DF [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
8859 UNSPEC_P8V_RELOAD_FROM_VSX))]
8860 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8861 "mfvsrd %0,%x1"
8862 [(set_attr "type" "mftgpr")])
8863
8864 (define_insn_and_split "reload_gpr_from_vsx<mode>"
8865 [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=r")
8866 (unspec:FMOVE128_GPR
8867 [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
8868 UNSPEC_P8V_RELOAD_FROM_VSX))
8869 (clobber (match_operand:FMOVE128_GPR 2 "register_operand" "=wa"))]
8870 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8871 "#"
8872 "&& reload_completed"
8873 [(const_int 0)]
8874 {
8875 rtx dest = operands[0];
8876 rtx src = operands[1];
8877 rtx tmp = operands[2];
8878 rtx gpr_hi_reg = gen_highpart (DFmode, dest);
8879 rtx gpr_lo_reg = gen_lowpart (DFmode, dest);
8880
8881 emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_hi_reg, src));
8882 emit_insn (gen_vsx_xxpermdi_<mode> (tmp, src, src, GEN_INT (3)));
8883 emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_lo_reg, tmp));
8884 }
8885 [(set_attr "length" "12")
8886 (set_attr "type" "three")])
8887
8888 ;; Move SFmode to a GPR from a VSX register. Because scalar floating point
8889 ;; type is stored internally as double precision, we have to convert it to the
8890 ;; vector format.
8891
8892 (define_insn_and_split "reload_gpr_from_vsxsf"
8893 [(set (match_operand:SF 0 "register_operand" "=r")
8894 (unspec:SF [(match_operand:SF 1 "register_operand" "wa")]
8895 UNSPEC_P8V_RELOAD_FROM_VSX))
8896 (clobber (match_operand:V4SF 2 "register_operand" "=wa"))]
8897 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8898 "#"
8899 "&& reload_completed"
8900 [(const_int 0)]
8901 {
8902 rtx op0 = operands[0];
8903 rtx op1 = operands[1];
8904 rtx op2 = operands[2];
8905 rtx diop0 = simplify_gen_subreg (DImode, op0, SFmode, 0);
8906
8907 emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
8908 emit_insn (gen_p8_mfvsrd_4_disf (diop0, op2));
8909 emit_insn (gen_lshrdi3 (diop0, diop0, GEN_INT (32)));
8910 DONE;
8911 }
8912 [(set_attr "length" "12")
8913 (set_attr "type" "three")])
8914
8915 (define_insn "p8_mfvsrd_4_disf"
8916 [(set (match_operand:DI 0 "register_operand" "=r")
8917 (unspec:DI [(match_operand:V4SF 1 "register_operand" "wa")]
8918 UNSPEC_P8V_RELOAD_FROM_VSX))]
8919 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8920 "mfvsrd %0,%x1"
8921 [(set_attr "type" "mftgpr")])
8922
8923 \f
8924 ;; Next come the multi-word integer load and store and the load and store
8925 ;; multiple insns.
8926
8927 ;; List r->r after r->Y, otherwise reload will try to reload a
8928 ;; non-offsettable address by using r->r which won't make progress.
8929 ;; Use of fprs is disparaged slightly otherwise reload prefers to reload
8930 ;; a gpr into a fpr instead of reloading an invalid 'Y' address
8931 (define_insn "*movdi_internal32"
8932 [(set (match_operand:DI 0 "rs6000_nonimmediate_operand" "=Y,r,r,?m,?*d,?*d,r")
8933 (match_operand:DI 1 "input_operand" "r,Y,r,d,m,d,IJKnGHF"))]
8934 "! TARGET_POWERPC64
8935 && (gpc_reg_operand (operands[0], DImode)
8936 || gpc_reg_operand (operands[1], DImode))"
8937 "@
8938 #
8939 #
8940 #
8941 stfd%U0%X0 %1,%0
8942 lfd%U1%X1 %0,%1
8943 fmr %0,%1
8944 #"
8945 [(set_attr "type" "store,load,*,fpstore,fpload,fp,*")])
8946
8947 (define_split
8948 [(set (match_operand:DI 0 "gpc_reg_operand" "")
8949 (match_operand:DI 1 "const_int_operand" ""))]
8950 "! TARGET_POWERPC64 && reload_completed
8951 && gpr_or_gpr_p (operands[0], operands[1])
8952 && !direct_move_p (operands[0], operands[1])"
8953 [(set (match_dup 2) (match_dup 4))
8954 (set (match_dup 3) (match_dup 1))]
8955 "
8956 {
8957 HOST_WIDE_INT value = INTVAL (operands[1]);
8958 operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
8959 DImode);
8960 operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
8961 DImode);
8962 operands[4] = GEN_INT (value >> 32);
8963 operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
8964 }")
8965
8966 (define_split
8967 [(set (match_operand:DIFD 0 "rs6000_nonimmediate_operand" "")
8968 (match_operand:DIFD 1 "input_operand" ""))]
8969 "reload_completed && !TARGET_POWERPC64
8970 && gpr_or_gpr_p (operands[0], operands[1])
8971 && !direct_move_p (operands[0], operands[1])"
8972 [(pc)]
8973 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
8974
8975 (define_insn "*movdi_internal64"
8976 [(set (match_operand:DI 0 "nonimmediate_operand" "=Y,r,r,r,r,r,?m,?*d,?*d,r,*h,*h,r,?*wg,r,?*wj,?*wi")
8977 (match_operand:DI 1 "input_operand" "r,Y,r,I,L,nF,d,m,d,*h,r,0,*wg,r,*wj,r,O"))]
8978 "TARGET_POWERPC64
8979 && (gpc_reg_operand (operands[0], DImode)
8980 || gpc_reg_operand (operands[1], DImode))"
8981 "@
8982 std%U0%X0 %1,%0
8983 ld%U1%X1 %0,%1
8984 mr %0,%1
8985 li %0,%1
8986 lis %0,%v1
8987 #
8988 stfd%U0%X0 %1,%0
8989 lfd%U1%X1 %0,%1
8990 fmr %0,%1
8991 mf%1 %0
8992 mt%0 %1
8993 nop
8994 mftgpr %0,%1
8995 mffgpr %0,%1
8996 mfvsrd %0,%x1
8997 mtvsrd %x0,%1
8998 xxlxor %x0,%x0,%x0"
8999 [(set_attr "type" "store,load,*,*,*,*,fpstore,fpload,fp,mfjmpr,mtjmpr,*,mftgpr,mffgpr,mftgpr,mffgpr,vecsimple")
9000 (set_attr "length" "4,4,4,4,4,20,4,4,4,4,4,4,4,4,4,4,4")])
9001
9002 ;; Generate all one-bits and clear left or right.
9003 ;; Use (and:DI (rotate:DI ...)) to avoid anddi3 unnecessary clobber.
9004 (define_split
9005 [(set (match_operand:DI 0 "gpc_reg_operand" "")
9006 (match_operand:DI 1 "mask64_operand" ""))]
9007 "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
9008 [(set (match_dup 0) (const_int -1))
9009 (set (match_dup 0)
9010 (and:DI (rotate:DI (match_dup 0)
9011 (const_int 0))
9012 (match_dup 1)))]
9013 "")
9014
9015 ;; Split a load of a large constant into the appropriate five-instruction
9016 ;; sequence. Handle anything in a constant number of insns.
9017 ;; When non-easy constants can go in the TOC, this should use
9018 ;; easy_fp_constant predicate.
9019 (define_split
9020 [(set (match_operand:DI 0 "gpc_reg_operand" "")
9021 (match_operand:DI 1 "const_int_operand" ""))]
9022 "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
9023 [(set (match_dup 0) (match_dup 2))
9024 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
9025 "
9026 {
9027 if (rs6000_emit_set_const (operands[0], operands[1]))
9028 DONE;
9029 else
9030 FAIL;
9031 }")
9032
9033 (define_split
9034 [(set (match_operand:DI 0 "gpc_reg_operand" "")
9035 (match_operand:DI 1 "const_scalar_int_operand" ""))]
9036 "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
9037 [(set (match_dup 0) (match_dup 2))
9038 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
9039 "
9040 {
9041 if (rs6000_emit_set_const (operands[0], operands[1]))
9042 DONE;
9043 else
9044 FAIL;
9045 }")
9046 \f
9047 ;; TImode/PTImode is similar, except that we usually want to compute the
9048 ;; address into a register and use lsi/stsi (the exception is during reload).
9049
9050 (define_insn "*mov<mode>_string"
9051 [(set (match_operand:TI2 0 "reg_or_mem_operand" "=Q,Y,????r,????r,????r,r")
9052 (match_operand:TI2 1 "input_operand" "r,r,Q,Y,r,n"))]
9053 "! TARGET_POWERPC64
9054 && (<MODE>mode != TImode || VECTOR_MEM_NONE_P (TImode))
9055 && (gpc_reg_operand (operands[0], <MODE>mode)
9056 || gpc_reg_operand (operands[1], <MODE>mode))"
9057 "*
9058 {
9059 switch (which_alternative)
9060 {
9061 default:
9062 gcc_unreachable ();
9063 case 0:
9064 if (TARGET_STRING)
9065 return \"stswi %1,%P0,16\";
9066 case 1:
9067 return \"#\";
9068 case 2:
9069 /* If the address is not used in the output, we can use lsi. Otherwise,
9070 fall through to generating four loads. */
9071 if (TARGET_STRING
9072 && ! reg_overlap_mentioned_p (operands[0], operands[1]))
9073 return \"lswi %0,%P1,16\";
9074 /* ... fall through ... */
9075 case 3:
9076 case 4:
9077 case 5:
9078 return \"#\";
9079 }
9080 }"
9081 [(set_attr "type" "store,store,load,load,*,*")
9082 (set_attr "update" "yes")
9083 (set_attr "indexed" "yes")
9084 (set (attr "cell_micro") (if_then_else (match_test "TARGET_STRING")
9085 (const_string "always")
9086 (const_string "conditional")))])
9087
9088 (define_insn "*mov<mode>_ppc64"
9089 [(set (match_operand:TI2 0 "nonimmediate_operand" "=wQ,Y,r,r,r,r")
9090 (match_operand:TI2 1 "input_operand" "r,r,wQ,Y,r,n"))]
9091 "(TARGET_POWERPC64 && VECTOR_MEM_NONE_P (<MODE>mode)
9092 && (gpc_reg_operand (operands[0], <MODE>mode)
9093 || gpc_reg_operand (operands[1], <MODE>mode)))"
9094 {
9095 return rs6000_output_move_128bit (operands);
9096 }
9097 [(set_attr "type" "store,store,load,load,*,*")
9098 (set_attr "length" "8")])
9099
9100 (define_split
9101 [(set (match_operand:TI2 0 "int_reg_operand" "")
9102 (match_operand:TI2 1 "const_scalar_int_operand" ""))]
9103 "TARGET_POWERPC64
9104 && (VECTOR_MEM_NONE_P (<MODE>mode)
9105 || (reload_completed && INT_REGNO_P (REGNO (operands[0]))))"
9106 [(set (match_dup 2) (match_dup 4))
9107 (set (match_dup 3) (match_dup 5))]
9108 "
9109 {
9110 operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
9111 <MODE>mode);
9112 operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
9113 <MODE>mode);
9114 if (CONST_WIDE_INT_P (operands[1]))
9115 {
9116 operands[4] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 1));
9117 operands[5] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 0));
9118 }
9119 else if (CONST_INT_P (operands[1]))
9120 {
9121 operands[4] = GEN_INT (- (INTVAL (operands[1]) < 0));
9122 operands[5] = operands[1];
9123 }
9124 else
9125 FAIL;
9126 }")
9127
9128 (define_split
9129 [(set (match_operand:TI2 0 "nonimmediate_operand" "")
9130 (match_operand:TI2 1 "input_operand" ""))]
9131 "reload_completed
9132 && gpr_or_gpr_p (operands[0], operands[1])
9133 && !direct_move_p (operands[0], operands[1])
9134 && !quad_load_store_p (operands[0], operands[1])"
9135 [(pc)]
9136 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
9137 \f
9138 (define_expand "load_multiple"
9139 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
9140 (match_operand:SI 1 "" ""))
9141 (use (match_operand:SI 2 "" ""))])]
9142 "TARGET_STRING && !TARGET_POWERPC64"
9143 "
9144 {
9145 int regno;
9146 int count;
9147 rtx op1;
9148 int i;
9149
9150 /* Support only loading a constant number of fixed-point registers from
9151 memory and only bother with this if more than two; the machine
9152 doesn't support more than eight. */
9153 if (GET_CODE (operands[2]) != CONST_INT
9154 || INTVAL (operands[2]) <= 2
9155 || INTVAL (operands[2]) > 8
9156 || GET_CODE (operands[1]) != MEM
9157 || GET_CODE (operands[0]) != REG
9158 || REGNO (operands[0]) >= 32)
9159 FAIL;
9160
9161 count = INTVAL (operands[2]);
9162 regno = REGNO (operands[0]);
9163
9164 operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
9165 op1 = replace_equiv_address (operands[1],
9166 force_reg (SImode, XEXP (operands[1], 0)));
9167
9168 for (i = 0; i < count; i++)
9169 XVECEXP (operands[3], 0, i)
9170 = gen_rtx_SET (VOIDmode, gen_rtx_REG (SImode, regno + i),
9171 adjust_address_nv (op1, SImode, i * 4));
9172 }")
9173
9174 (define_insn "*ldmsi8"
9175 [(match_parallel 0 "load_multiple_operation"
9176 [(set (match_operand:SI 2 "gpc_reg_operand" "")
9177 (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
9178 (set (match_operand:SI 3 "gpc_reg_operand" "")
9179 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
9180 (set (match_operand:SI 4 "gpc_reg_operand" "")
9181 (mem:SI (plus:SI (match_dup 1) (const_int 8))))
9182 (set (match_operand:SI 5 "gpc_reg_operand" "")
9183 (mem:SI (plus:SI (match_dup 1) (const_int 12))))
9184 (set (match_operand:SI 6 "gpc_reg_operand" "")
9185 (mem:SI (plus:SI (match_dup 1) (const_int 16))))
9186 (set (match_operand:SI 7 "gpc_reg_operand" "")
9187 (mem:SI (plus:SI (match_dup 1) (const_int 20))))
9188 (set (match_operand:SI 8 "gpc_reg_operand" "")
9189 (mem:SI (plus:SI (match_dup 1) (const_int 24))))
9190 (set (match_operand:SI 9 "gpc_reg_operand" "")
9191 (mem:SI (plus:SI (match_dup 1) (const_int 28))))])]
9192 "TARGET_STRING && XVECLEN (operands[0], 0) == 8"
9193 "*
9194 { return rs6000_output_load_multiple (operands); }"
9195 [(set_attr "type" "load")
9196 (set_attr "update" "yes")
9197 (set_attr "indexed" "yes")
9198 (set_attr "length" "32")])
9199
9200 (define_insn "*ldmsi7"
9201 [(match_parallel 0 "load_multiple_operation"
9202 [(set (match_operand:SI 2 "gpc_reg_operand" "")
9203 (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
9204 (set (match_operand:SI 3 "gpc_reg_operand" "")
9205 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
9206 (set (match_operand:SI 4 "gpc_reg_operand" "")
9207 (mem:SI (plus:SI (match_dup 1) (const_int 8))))
9208 (set (match_operand:SI 5 "gpc_reg_operand" "")
9209 (mem:SI (plus:SI (match_dup 1) (const_int 12))))
9210 (set (match_operand:SI 6 "gpc_reg_operand" "")
9211 (mem:SI (plus:SI (match_dup 1) (const_int 16))))
9212 (set (match_operand:SI 7 "gpc_reg_operand" "")
9213 (mem:SI (plus:SI (match_dup 1) (const_int 20))))
9214 (set (match_operand:SI 8 "gpc_reg_operand" "")
9215 (mem:SI (plus:SI (match_dup 1) (const_int 24))))])]
9216 "TARGET_STRING && XVECLEN (operands[0], 0) == 7"
9217 "*
9218 { return rs6000_output_load_multiple (operands); }"
9219 [(set_attr "type" "load")
9220 (set_attr "update" "yes")
9221 (set_attr "indexed" "yes")
9222 (set_attr "length" "32")])
9223
9224 (define_insn "*ldmsi6"
9225 [(match_parallel 0 "load_multiple_operation"
9226 [(set (match_operand:SI 2 "gpc_reg_operand" "")
9227 (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
9228 (set (match_operand:SI 3 "gpc_reg_operand" "")
9229 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
9230 (set (match_operand:SI 4 "gpc_reg_operand" "")
9231 (mem:SI (plus:SI (match_dup 1) (const_int 8))))
9232 (set (match_operand:SI 5 "gpc_reg_operand" "")
9233 (mem:SI (plus:SI (match_dup 1) (const_int 12))))
9234 (set (match_operand:SI 6 "gpc_reg_operand" "")
9235 (mem:SI (plus:SI (match_dup 1) (const_int 16))))
9236 (set (match_operand:SI 7 "gpc_reg_operand" "")
9237 (mem:SI (plus:SI (match_dup 1) (const_int 20))))])]
9238 "TARGET_STRING && XVECLEN (operands[0], 0) == 6"
9239 "*
9240 { return rs6000_output_load_multiple (operands); }"
9241 [(set_attr "type" "load")
9242 (set_attr "update" "yes")
9243 (set_attr "indexed" "yes")
9244 (set_attr "length" "32")])
9245
9246 (define_insn "*ldmsi5"
9247 [(match_parallel 0 "load_multiple_operation"
9248 [(set (match_operand:SI 2 "gpc_reg_operand" "")
9249 (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
9250 (set (match_operand:SI 3 "gpc_reg_operand" "")
9251 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
9252 (set (match_operand:SI 4 "gpc_reg_operand" "")
9253 (mem:SI (plus:SI (match_dup 1) (const_int 8))))
9254 (set (match_operand:SI 5 "gpc_reg_operand" "")
9255 (mem:SI (plus:SI (match_dup 1) (const_int 12))))
9256 (set (match_operand:SI 6 "gpc_reg_operand" "")
9257 (mem:SI (plus:SI (match_dup 1) (const_int 16))))])]
9258 "TARGET_STRING && XVECLEN (operands[0], 0) == 5"
9259 "*
9260 { return rs6000_output_load_multiple (operands); }"
9261 [(set_attr "type" "load")
9262 (set_attr "update" "yes")
9263 (set_attr "indexed" "yes")
9264 (set_attr "length" "32")])
9265
9266 (define_insn "*ldmsi4"
9267 [(match_parallel 0 "load_multiple_operation"
9268 [(set (match_operand:SI 2 "gpc_reg_operand" "")
9269 (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
9270 (set (match_operand:SI 3 "gpc_reg_operand" "")
9271 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
9272 (set (match_operand:SI 4 "gpc_reg_operand" "")
9273 (mem:SI (plus:SI (match_dup 1) (const_int 8))))
9274 (set (match_operand:SI 5 "gpc_reg_operand" "")
9275 (mem:SI (plus:SI (match_dup 1) (const_int 12))))])]
9276 "TARGET_STRING && XVECLEN (operands[0], 0) == 4"
9277 "*
9278 { return rs6000_output_load_multiple (operands); }"
9279 [(set_attr "type" "load")
9280 (set_attr "update" "yes")
9281 (set_attr "indexed" "yes")
9282 (set_attr "length" "32")])
9283
9284 (define_insn "*ldmsi3"
9285 [(match_parallel 0 "load_multiple_operation"
9286 [(set (match_operand:SI 2 "gpc_reg_operand" "")
9287 (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
9288 (set (match_operand:SI 3 "gpc_reg_operand" "")
9289 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
9290 (set (match_operand:SI 4 "gpc_reg_operand" "")
9291 (mem:SI (plus:SI (match_dup 1) (const_int 8))))])]
9292 "TARGET_STRING && XVECLEN (operands[0], 0) == 3"
9293 "*
9294 { return rs6000_output_load_multiple (operands); }"
9295 [(set_attr "type" "load")
9296 (set_attr "update" "yes")
9297 (set_attr "indexed" "yes")
9298 (set_attr "length" "32")])
9299
9300 (define_expand "store_multiple"
9301 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
9302 (match_operand:SI 1 "" ""))
9303 (clobber (scratch:SI))
9304 (use (match_operand:SI 2 "" ""))])]
9305 "TARGET_STRING && !TARGET_POWERPC64"
9306 "
9307 {
9308 int regno;
9309 int count;
9310 rtx to;
9311 rtx op0;
9312 int i;
9313
9314 /* Support only storing a constant number of fixed-point registers to
9315 memory and only bother with this if more than two; the machine
9316 doesn't support more than eight. */
9317 if (GET_CODE (operands[2]) != CONST_INT
9318 || INTVAL (operands[2]) <= 2
9319 || INTVAL (operands[2]) > 8
9320 || GET_CODE (operands[0]) != MEM
9321 || GET_CODE (operands[1]) != REG
9322 || REGNO (operands[1]) >= 32)
9323 FAIL;
9324
9325 count = INTVAL (operands[2]);
9326 regno = REGNO (operands[1]);
9327
9328 operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count + 1));
9329 to = force_reg (SImode, XEXP (operands[0], 0));
9330 op0 = replace_equiv_address (operands[0], to);
9331
9332 XVECEXP (operands[3], 0, 0)
9333 = gen_rtx_SET (VOIDmode, adjust_address_nv (op0, SImode, 0), operands[1]);
9334 XVECEXP (operands[3], 0, 1) = gen_rtx_CLOBBER (VOIDmode,
9335 gen_rtx_SCRATCH (SImode));
9336
9337 for (i = 1; i < count; i++)
9338 XVECEXP (operands[3], 0, i + 1)
9339 = gen_rtx_SET (VOIDmode,
9340 adjust_address_nv (op0, SImode, i * 4),
9341 gen_rtx_REG (SImode, regno + i));
9342 }")
9343
9344 (define_insn "*stmsi8"
9345 [(match_parallel 0 "store_multiple_operation"
9346 [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
9347 (match_operand:SI 2 "gpc_reg_operand" "r"))
9348 (clobber (match_scratch:SI 3 "=X"))
9349 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
9350 (match_operand:SI 4 "gpc_reg_operand" "r"))
9351 (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
9352 (match_operand:SI 5 "gpc_reg_operand" "r"))
9353 (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
9354 (match_operand:SI 6 "gpc_reg_operand" "r"))
9355 (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
9356 (match_operand:SI 7 "gpc_reg_operand" "r"))
9357 (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
9358 (match_operand:SI 8 "gpc_reg_operand" "r"))
9359 (set (mem:SI (plus:SI (match_dup 1) (const_int 24)))
9360 (match_operand:SI 9 "gpc_reg_operand" "r"))
9361 (set (mem:SI (plus:SI (match_dup 1) (const_int 28)))
9362 (match_operand:SI 10 "gpc_reg_operand" "r"))])]
9363 "TARGET_STRING && XVECLEN (operands[0], 0) == 9"
9364 "stswi %2,%1,%O0"
9365 [(set_attr "type" "store")
9366 (set_attr "update" "yes")
9367 (set_attr "indexed" "yes")
9368 (set_attr "cell_micro" "always")])
9369
9370 (define_insn "*stmsi7"
9371 [(match_parallel 0 "store_multiple_operation"
9372 [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
9373 (match_operand:SI 2 "gpc_reg_operand" "r"))
9374 (clobber (match_scratch:SI 3 "=X"))
9375 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
9376 (match_operand:SI 4 "gpc_reg_operand" "r"))
9377 (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
9378 (match_operand:SI 5 "gpc_reg_operand" "r"))
9379 (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
9380 (match_operand:SI 6 "gpc_reg_operand" "r"))
9381 (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
9382 (match_operand:SI 7 "gpc_reg_operand" "r"))
9383 (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
9384 (match_operand:SI 8 "gpc_reg_operand" "r"))
9385 (set (mem:SI (plus:SI (match_dup 1) (const_int 24)))
9386 (match_operand:SI 9 "gpc_reg_operand" "r"))])]
9387 "TARGET_STRING && XVECLEN (operands[0], 0) == 8"
9388 "stswi %2,%1,%O0"
9389 [(set_attr "type" "store")
9390 (set_attr "update" "yes")
9391 (set_attr "indexed" "yes")
9392 (set_attr "cell_micro" "always")])
9393
9394 (define_insn "*stmsi6"
9395 [(match_parallel 0 "store_multiple_operation"
9396 [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
9397 (match_operand:SI 2 "gpc_reg_operand" "r"))
9398 (clobber (match_scratch:SI 3 "=X"))
9399 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
9400 (match_operand:SI 4 "gpc_reg_operand" "r"))
9401 (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
9402 (match_operand:SI 5 "gpc_reg_operand" "r"))
9403 (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
9404 (match_operand:SI 6 "gpc_reg_operand" "r"))
9405 (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
9406 (match_operand:SI 7 "gpc_reg_operand" "r"))
9407 (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
9408 (match_operand:SI 8 "gpc_reg_operand" "r"))])]
9409 "TARGET_STRING && XVECLEN (operands[0], 0) == 7"
9410 "stswi %2,%1,%O0"
9411 [(set_attr "type" "store")
9412 (set_attr "update" "yes")
9413 (set_attr "indexed" "yes")
9414 (set_attr "cell_micro" "always")])
9415
9416 (define_insn "*stmsi5"
9417 [(match_parallel 0 "store_multiple_operation"
9418 [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
9419 (match_operand:SI 2 "gpc_reg_operand" "r"))
9420 (clobber (match_scratch:SI 3 "=X"))
9421 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
9422 (match_operand:SI 4 "gpc_reg_operand" "r"))
9423 (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
9424 (match_operand:SI 5 "gpc_reg_operand" "r"))
9425 (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
9426 (match_operand:SI 6 "gpc_reg_operand" "r"))
9427 (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
9428 (match_operand:SI 7 "gpc_reg_operand" "r"))])]
9429 "TARGET_STRING && XVECLEN (operands[0], 0) == 6"
9430 "stswi %2,%1,%O0"
9431 [(set_attr "type" "store")
9432 (set_attr "update" "yes")
9433 (set_attr "indexed" "yes")
9434 (set_attr "cell_micro" "always")])
9435
9436 (define_insn "*stmsi4"
9437 [(match_parallel 0 "store_multiple_operation"
9438 [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
9439 (match_operand:SI 2 "gpc_reg_operand" "r"))
9440 (clobber (match_scratch:SI 3 "=X"))
9441 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
9442 (match_operand:SI 4 "gpc_reg_operand" "r"))
9443 (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
9444 (match_operand:SI 5 "gpc_reg_operand" "r"))
9445 (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
9446 (match_operand:SI 6 "gpc_reg_operand" "r"))])]
9447 "TARGET_STRING && XVECLEN (operands[0], 0) == 5"
9448 "stswi %2,%1,%O0"
9449 [(set_attr "type" "store")
9450 (set_attr "update" "yes")
9451 (set_attr "indexed" "yes")
9452 (set_attr "cell_micro" "always")])
9453
9454 (define_insn "*stmsi3"
9455 [(match_parallel 0 "store_multiple_operation"
9456 [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
9457 (match_operand:SI 2 "gpc_reg_operand" "r"))
9458 (clobber (match_scratch:SI 3 "=X"))
9459 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
9460 (match_operand:SI 4 "gpc_reg_operand" "r"))
9461 (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
9462 (match_operand:SI 5 "gpc_reg_operand" "r"))])]
9463 "TARGET_STRING && XVECLEN (operands[0], 0) == 4"
9464 "stswi %2,%1,%O0"
9465 [(set_attr "type" "store")
9466 (set_attr "update" "yes")
9467 (set_attr "indexed" "yes")
9468 (set_attr "cell_micro" "always")])
9469 \f
9470 (define_expand "setmemsi"
9471 [(parallel [(set (match_operand:BLK 0 "" "")
9472 (match_operand 2 "const_int_operand" ""))
9473 (use (match_operand:SI 1 "" ""))
9474 (use (match_operand:SI 3 "" ""))])]
9475 ""
9476 "
9477 {
9478 /* If value to set is not zero, use the library routine. */
9479 if (operands[2] != const0_rtx)
9480 FAIL;
9481
9482 if (expand_block_clear (operands))
9483 DONE;
9484 else
9485 FAIL;
9486 }")
9487
9488 ;; String/block move insn.
9489 ;; Argument 0 is the destination
9490 ;; Argument 1 is the source
9491 ;; Argument 2 is the length
9492 ;; Argument 3 is the alignment
9493
9494 (define_expand "movmemsi"
9495 [(parallel [(set (match_operand:BLK 0 "" "")
9496 (match_operand:BLK 1 "" ""))
9497 (use (match_operand:SI 2 "" ""))
9498 (use (match_operand:SI 3 "" ""))])]
9499 ""
9500 "
9501 {
9502 if (expand_block_move (operands))
9503 DONE;
9504 else
9505 FAIL;
9506 }")
9507
9508 ;; Move up to 32 bytes at a time. The fixed registers are needed because the
9509 ;; register allocator doesn't have a clue about allocating 8 word registers.
9510 ;; rD/rS = r5 is preferred, efficient form.
9511 (define_expand "movmemsi_8reg"
9512 [(parallel [(set (match_operand 0 "" "")
9513 (match_operand 1 "" ""))
9514 (use (match_operand 2 "" ""))
9515 (use (match_operand 3 "" ""))
9516 (clobber (reg:SI 5))
9517 (clobber (reg:SI 6))
9518 (clobber (reg:SI 7))
9519 (clobber (reg:SI 8))
9520 (clobber (reg:SI 9))
9521 (clobber (reg:SI 10))
9522 (clobber (reg:SI 11))
9523 (clobber (reg:SI 12))
9524 (clobber (match_scratch:SI 4 ""))])]
9525 "TARGET_STRING"
9526 "")
9527
9528 (define_insn ""
9529 [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
9530 (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
9531 (use (match_operand:SI 2 "immediate_operand" "i"))
9532 (use (match_operand:SI 3 "immediate_operand" "i"))
9533 (clobber (match_operand:SI 4 "gpc_reg_operand" "=&r"))
9534 (clobber (reg:SI 6))
9535 (clobber (reg:SI 7))
9536 (clobber (reg:SI 8))
9537 (clobber (reg:SI 9))
9538 (clobber (reg:SI 10))
9539 (clobber (reg:SI 11))
9540 (clobber (reg:SI 12))
9541 (clobber (match_scratch:SI 5 "=X"))]
9542 "TARGET_STRING
9543 && ((INTVAL (operands[2]) > 24 && INTVAL (operands[2]) < 32)
9544 || INTVAL (operands[2]) == 0)
9545 && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 12)
9546 && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 12)
9547 && REGNO (operands[4]) == 5"
9548 "lswi %4,%1,%2\;stswi %4,%0,%2"
9549 [(set_attr "type" "store")
9550 (set_attr "update" "yes")
9551 (set_attr "indexed" "yes")
9552 (set_attr "cell_micro" "always")
9553 (set_attr "length" "8")])
9554
9555 ;; Move up to 24 bytes at a time. The fixed registers are needed because the
9556 ;; register allocator doesn't have a clue about allocating 6 word registers.
9557 ;; rD/rS = r5 is preferred, efficient form.
9558 (define_expand "movmemsi_6reg"
9559 [(parallel [(set (match_operand 0 "" "")
9560 (match_operand 1 "" ""))
9561 (use (match_operand 2 "" ""))
9562 (use (match_operand 3 "" ""))
9563 (clobber (reg:SI 5))
9564 (clobber (reg:SI 6))
9565 (clobber (reg:SI 7))
9566 (clobber (reg:SI 8))
9567 (clobber (reg:SI 9))
9568 (clobber (reg:SI 10))
9569 (clobber (match_scratch:SI 4 ""))])]
9570 "TARGET_STRING"
9571 "")
9572
9573 (define_insn ""
9574 [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
9575 (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
9576 (use (match_operand:SI 2 "immediate_operand" "i"))
9577 (use (match_operand:SI 3 "immediate_operand" "i"))
9578 (clobber (match_operand:SI 4 "gpc_reg_operand" "=&r"))
9579 (clobber (reg:SI 6))
9580 (clobber (reg:SI 7))
9581 (clobber (reg:SI 8))
9582 (clobber (reg:SI 9))
9583 (clobber (reg:SI 10))
9584 (clobber (match_scratch:SI 5 "=X"))]
9585 "TARGET_STRING
9586 && INTVAL (operands[2]) > 16 && INTVAL (operands[2]) <= 32
9587 && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 10)
9588 && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 10)
9589 && REGNO (operands[4]) == 5"
9590 "lswi %4,%1,%2\;stswi %4,%0,%2"
9591 [(set_attr "type" "store")
9592 (set_attr "update" "yes")
9593 (set_attr "indexed" "yes")
9594 (set_attr "cell_micro" "always")
9595 (set_attr "length" "8")])
9596
9597 ;; Move up to 16 bytes at a time, using 4 fixed registers to avoid spill
9598 ;; problems with TImode.
9599 ;; rD/rS = r5 is preferred, efficient form.
9600 (define_expand "movmemsi_4reg"
9601 [(parallel [(set (match_operand 0 "" "")
9602 (match_operand 1 "" ""))
9603 (use (match_operand 2 "" ""))
9604 (use (match_operand 3 "" ""))
9605 (clobber (reg:SI 5))
9606 (clobber (reg:SI 6))
9607 (clobber (reg:SI 7))
9608 (clobber (reg:SI 8))
9609 (clobber (match_scratch:SI 4 ""))])]
9610 "TARGET_STRING"
9611 "")
9612
9613 (define_insn ""
9614 [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
9615 (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
9616 (use (match_operand:SI 2 "immediate_operand" "i"))
9617 (use (match_operand:SI 3 "immediate_operand" "i"))
9618 (clobber (match_operand:SI 4 "gpc_reg_operand" "=&r"))
9619 (clobber (reg:SI 6))
9620 (clobber (reg:SI 7))
9621 (clobber (reg:SI 8))
9622 (clobber (match_scratch:SI 5 "=X"))]
9623 "TARGET_STRING
9624 && INTVAL (operands[2]) > 8 && INTVAL (operands[2]) <= 16
9625 && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 8)
9626 && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 8)
9627 && REGNO (operands[4]) == 5"
9628 "lswi %4,%1,%2\;stswi %4,%0,%2"
9629 [(set_attr "type" "store")
9630 (set_attr "update" "yes")
9631 (set_attr "indexed" "yes")
9632 (set_attr "cell_micro" "always")
9633 (set_attr "length" "8")])
9634
9635 ;; Move up to 8 bytes at a time.
9636 (define_expand "movmemsi_2reg"
9637 [(parallel [(set (match_operand 0 "" "")
9638 (match_operand 1 "" ""))
9639 (use (match_operand 2 "" ""))
9640 (use (match_operand 3 "" ""))
9641 (clobber (match_scratch:DI 4 ""))
9642 (clobber (match_scratch:SI 5 ""))])]
9643 "TARGET_STRING && ! TARGET_POWERPC64"
9644 "")
9645
9646 (define_insn ""
9647 [(set (mem:BLK (match_operand:SI 0 "gpc_reg_operand" "b"))
9648 (mem:BLK (match_operand:SI 1 "gpc_reg_operand" "b")))
9649 (use (match_operand:SI 2 "immediate_operand" "i"))
9650 (use (match_operand:SI 3 "immediate_operand" "i"))
9651 (clobber (match_scratch:DI 4 "=&r"))
9652 (clobber (match_scratch:SI 5 "=X"))]
9653 "TARGET_STRING && ! TARGET_POWERPC64
9654 && INTVAL (operands[2]) > 4 && INTVAL (operands[2]) <= 8"
9655 "lswi %4,%1,%2\;stswi %4,%0,%2"
9656 [(set_attr "type" "store")
9657 (set_attr "update" "yes")
9658 (set_attr "indexed" "yes")
9659 (set_attr "cell_micro" "always")
9660 (set_attr "length" "8")])
9661
9662 ;; Move up to 4 bytes at a time.
9663 (define_expand "movmemsi_1reg"
9664 [(parallel [(set (match_operand 0 "" "")
9665 (match_operand 1 "" ""))
9666 (use (match_operand 2 "" ""))
9667 (use (match_operand 3 "" ""))
9668 (clobber (match_scratch:SI 4 ""))
9669 (clobber (match_scratch:SI 5 ""))])]
9670 "TARGET_STRING"
9671 "")
9672
9673 (define_insn ""
9674 [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
9675 (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
9676 (use (match_operand:SI 2 "immediate_operand" "i"))
9677 (use (match_operand:SI 3 "immediate_operand" "i"))
9678 (clobber (match_scratch:SI 4 "=&r"))
9679 (clobber (match_scratch:SI 5 "=X"))]
9680 "TARGET_STRING && INTVAL (operands[2]) > 0 && INTVAL (operands[2]) <= 4"
9681 "lswi %4,%1,%2\;stswi %4,%0,%2"
9682 [(set_attr "type" "store")
9683 (set_attr "update" "yes")
9684 (set_attr "indexed" "yes")
9685 (set_attr "cell_micro" "always")
9686 (set_attr "length" "8")])
9687 \f
9688 ;; Define insns that do load or store with update. Some of these we can
9689 ;; get by using pre-decrement or pre-increment, but the hardware can also
9690 ;; do cases where the increment is not the size of the object.
9691 ;;
9692 ;; In all these cases, we use operands 0 and 1 for the register being
9693 ;; incremented because those are the operands that local-alloc will
9694 ;; tie and these are the pair most likely to be tieable (and the ones
9695 ;; that will benefit the most).
9696
9697 (define_insn "*movdi_update1"
9698 [(set (match_operand:DI 3 "gpc_reg_operand" "=r,r")
9699 (mem:DI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0,0")
9700 (match_operand:DI 2 "reg_or_aligned_short_operand" "r,I"))))
9701 (set (match_operand:DI 0 "gpc_reg_operand" "=b,b")
9702 (plus:DI (match_dup 1) (match_dup 2)))]
9703 "TARGET_POWERPC64 && TARGET_UPDATE
9704 && (!avoiding_indexed_address_p (DImode)
9705 || !gpc_reg_operand (operands[2], DImode))"
9706 "@
9707 ldux %3,%0,%2
9708 ldu %3,%2(%0)"
9709 [(set_attr "type" "load")
9710 (set_attr "update" "yes")
9711 (set_attr "indexed" "yes,no")])
9712
9713 (define_insn "movdi_<mode>_update"
9714 [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9715 (match_operand:P 2 "reg_or_aligned_short_operand" "r,I")))
9716 (match_operand:DI 3 "gpc_reg_operand" "r,r"))
9717 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9718 (plus:P (match_dup 1) (match_dup 2)))]
9719 "TARGET_POWERPC64 && TARGET_UPDATE
9720 && (!avoiding_indexed_address_p (Pmode)
9721 || !gpc_reg_operand (operands[2], Pmode)
9722 || (REG_P (operands[0])
9723 && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
9724 "@
9725 stdux %3,%0,%2
9726 stdu %3,%2(%0)"
9727 [(set_attr "type" "store")
9728 (set_attr "update" "yes")
9729 (set_attr "indexed" "yes,no")])
9730
9731 ;; This pattern is only conditional on TARGET_POWERPC64, as it is
9732 ;; needed for stack allocation, even if the user passes -mno-update.
9733 (define_insn "movdi_<mode>_update_stack"
9734 [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9735 (match_operand:P 2 "reg_or_aligned_short_operand" "r,I")))
9736 (match_operand:DI 3 "gpc_reg_operand" "r,r"))
9737 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9738 (plus:P (match_dup 1) (match_dup 2)))]
9739 "TARGET_POWERPC64"
9740 "@
9741 stdux %3,%0,%2
9742 stdu %3,%2(%0)"
9743 [(set_attr "type" "store")
9744 (set_attr "update" "yes")
9745 (set_attr "indexed" "yes,no")])
9746
9747 (define_insn "*movsi_update1"
9748 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9749 (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9750 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9751 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9752 (plus:SI (match_dup 1) (match_dup 2)))]
9753 "TARGET_UPDATE
9754 && (!avoiding_indexed_address_p (SImode)
9755 || !gpc_reg_operand (operands[2], SImode))"
9756 "@
9757 lwzux %3,%0,%2
9758 lwzu %3,%2(%0)"
9759 [(set_attr "type" "load")
9760 (set_attr "update" "yes")
9761 (set_attr "indexed" "yes,no")])
9762
9763 (define_insn "*movsi_update2"
9764 [(set (match_operand:DI 3 "gpc_reg_operand" "=r")
9765 (sign_extend:DI
9766 (mem:SI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0")
9767 (match_operand:DI 2 "gpc_reg_operand" "r")))))
9768 (set (match_operand:DI 0 "gpc_reg_operand" "=b")
9769 (plus:DI (match_dup 1) (match_dup 2)))]
9770 "TARGET_POWERPC64 && rs6000_gen_cell_microcode
9771 && !avoiding_indexed_address_p (DImode)"
9772 "lwaux %3,%0,%2"
9773 [(set_attr "type" "load")
9774 (set_attr "sign_extend" "yes")
9775 (set_attr "update" "yes")
9776 (set_attr "indexed" "yes")])
9777
9778 (define_insn "movsi_update"
9779 [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9780 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9781 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
9782 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9783 (plus:SI (match_dup 1) (match_dup 2)))]
9784 "TARGET_UPDATE
9785 && (!avoiding_indexed_address_p (SImode)
9786 || !gpc_reg_operand (operands[2], SImode)
9787 || (REG_P (operands[0])
9788 && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
9789 "@
9790 stwux %3,%0,%2
9791 stwu %3,%2(%0)"
9792 [(set_attr "type" "store")
9793 (set_attr "update" "yes")
9794 (set_attr "indexed" "yes,no")])
9795
9796 ;; This is an unconditional pattern; needed for stack allocation, even
9797 ;; if the user passes -mno-update.
9798 (define_insn "movsi_update_stack"
9799 [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9800 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9801 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
9802 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9803 (plus:SI (match_dup 1) (match_dup 2)))]
9804 ""
9805 "@
9806 stwux %3,%0,%2
9807 stwu %3,%2(%0)"
9808 [(set_attr "type" "store")
9809 (set_attr "update" "yes")
9810 (set_attr "indexed" "yes,no")])
9811
9812 (define_insn "*movhi_update1"
9813 [(set (match_operand:HI 3 "gpc_reg_operand" "=r,r")
9814 (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9815 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9816 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9817 (plus:SI (match_dup 1) (match_dup 2)))]
9818 "TARGET_UPDATE
9819 && (!avoiding_indexed_address_p (SImode)
9820 || !gpc_reg_operand (operands[2], SImode))"
9821 "@
9822 lhzux %3,%0,%2
9823 lhzu %3,%2(%0)"
9824 [(set_attr "type" "load")
9825 (set_attr "update" "yes")
9826 (set_attr "indexed" "yes,no")])
9827
9828 (define_insn "*movhi_update2"
9829 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9830 (zero_extend:SI
9831 (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9832 (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
9833 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9834 (plus:SI (match_dup 1) (match_dup 2)))]
9835 "TARGET_UPDATE
9836 && (!avoiding_indexed_address_p (SImode)
9837 || !gpc_reg_operand (operands[2], SImode))"
9838 "@
9839 lhzux %3,%0,%2
9840 lhzu %3,%2(%0)"
9841 [(set_attr "type" "load")
9842 (set_attr "update" "yes")
9843 (set_attr "indexed" "yes,no")])
9844
9845 (define_insn "*movhi_update3"
9846 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9847 (sign_extend:SI
9848 (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9849 (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
9850 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9851 (plus:SI (match_dup 1) (match_dup 2)))]
9852 "TARGET_UPDATE && rs6000_gen_cell_microcode
9853 && (!avoiding_indexed_address_p (SImode)
9854 || !gpc_reg_operand (operands[2], SImode))"
9855 "@
9856 lhaux %3,%0,%2
9857 lhau %3,%2(%0)"
9858 [(set_attr "type" "load")
9859 (set_attr "sign_extend" "yes")
9860 (set_attr "update" "yes")
9861 (set_attr "indexed" "yes,no")])
9862
9863 (define_insn "*movhi_update4"
9864 [(set (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9865 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9866 (match_operand:HI 3 "gpc_reg_operand" "r,r"))
9867 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9868 (plus:SI (match_dup 1) (match_dup 2)))]
9869 "TARGET_UPDATE
9870 && (!avoiding_indexed_address_p (SImode)
9871 || !gpc_reg_operand (operands[2], SImode))"
9872 "@
9873 sthux %3,%0,%2
9874 sthu %3,%2(%0)"
9875 [(set_attr "type" "store")
9876 (set_attr "update" "yes")
9877 (set_attr "indexed" "yes,no")])
9878
9879 (define_insn "*movqi_update1"
9880 [(set (match_operand:QI 3 "gpc_reg_operand" "=r,r")
9881 (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9882 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9883 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9884 (plus:SI (match_dup 1) (match_dup 2)))]
9885 "TARGET_UPDATE
9886 && (!avoiding_indexed_address_p (SImode)
9887 || !gpc_reg_operand (operands[2], SImode))"
9888 "@
9889 lbzux %3,%0,%2
9890 lbzu %3,%2(%0)"
9891 [(set_attr "type" "load")
9892 (set_attr "update" "yes")
9893 (set_attr "indexed" "yes,no")])
9894
9895 (define_insn "*movqi_update2"
9896 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9897 (zero_extend:SI
9898 (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9899 (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
9900 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9901 (plus:SI (match_dup 1) (match_dup 2)))]
9902 "TARGET_UPDATE
9903 && (!avoiding_indexed_address_p (SImode)
9904 || !gpc_reg_operand (operands[2], SImode))"
9905 "@
9906 lbzux %3,%0,%2
9907 lbzu %3,%2(%0)"
9908 [(set_attr "type" "load")
9909 (set_attr "update" "yes")
9910 (set_attr "indexed" "yes,no")])
9911
9912 (define_insn "*movqi_update3"
9913 [(set (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9914 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9915 (match_operand:QI 3 "gpc_reg_operand" "r,r"))
9916 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9917 (plus:SI (match_dup 1) (match_dup 2)))]
9918 "TARGET_UPDATE
9919 && (!avoiding_indexed_address_p (SImode)
9920 || !gpc_reg_operand (operands[2], SImode))"
9921 "@
9922 stbux %3,%0,%2
9923 stbu %3,%2(%0)"
9924 [(set_attr "type" "store")
9925 (set_attr "update" "yes")
9926 (set_attr "indexed" "yes,no")])
9927
9928 (define_insn "*movsf_update1"
9929 [(set (match_operand:SF 3 "gpc_reg_operand" "=f,f")
9930 (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9931 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9932 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9933 (plus:SI (match_dup 1) (match_dup 2)))]
9934 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT && TARGET_UPDATE
9935 && (!avoiding_indexed_address_p (SImode)
9936 || !gpc_reg_operand (operands[2], SImode))"
9937 "@
9938 lfsux %3,%0,%2
9939 lfsu %3,%2(%0)"
9940 [(set_attr "type" "fpload")
9941 (set_attr "update" "yes")
9942 (set_attr "indexed" "yes,no")])
9943
9944 (define_insn "*movsf_update2"
9945 [(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9946 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9947 (match_operand:SF 3 "gpc_reg_operand" "f,f"))
9948 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9949 (plus:SI (match_dup 1) (match_dup 2)))]
9950 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT && TARGET_UPDATE
9951 && (!avoiding_indexed_address_p (SImode)
9952 || !gpc_reg_operand (operands[2], SImode))"
9953 "@
9954 stfsux %3,%0,%2
9955 stfsu %3,%2(%0)"
9956 [(set_attr "type" "fpstore")
9957 (set_attr "update" "yes")
9958 (set_attr "indexed" "yes,no")])
9959
9960 (define_insn "*movsf_update3"
9961 [(set (match_operand:SF 3 "gpc_reg_operand" "=r,r")
9962 (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9963 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9964 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9965 (plus:SI (match_dup 1) (match_dup 2)))]
9966 "(TARGET_SOFT_FLOAT || !TARGET_FPRS) && TARGET_UPDATE
9967 && (!avoiding_indexed_address_p (SImode)
9968 || !gpc_reg_operand (operands[2], SImode))"
9969 "@
9970 lwzux %3,%0,%2
9971 lwzu %3,%2(%0)"
9972 [(set_attr "type" "load")
9973 (set_attr "update" "yes")
9974 (set_attr "indexed" "yes,no")])
9975
9976 (define_insn "*movsf_update4"
9977 [(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9978 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9979 (match_operand:SF 3 "gpc_reg_operand" "r,r"))
9980 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9981 (plus:SI (match_dup 1) (match_dup 2)))]
9982 "(TARGET_SOFT_FLOAT || !TARGET_FPRS) && TARGET_UPDATE
9983 && (!avoiding_indexed_address_p (SImode)
9984 || !gpc_reg_operand (operands[2], SImode))"
9985 "@
9986 stwux %3,%0,%2
9987 stwu %3,%2(%0)"
9988 [(set_attr "type" "store")
9989 (set_attr "update" "yes")
9990 (set_attr "indexed" "yes,no")])
9991
9992 (define_insn "*movdf_update1"
9993 [(set (match_operand:DF 3 "gpc_reg_operand" "=d,d")
9994 (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9995 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9996 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9997 (plus:SI (match_dup 1) (match_dup 2)))]
9998 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_UPDATE
9999 && (!avoiding_indexed_address_p (SImode)
10000 || !gpc_reg_operand (operands[2], SImode))"
10001 "@
10002 lfdux %3,%0,%2
10003 lfdu %3,%2(%0)"
10004 [(set_attr "type" "fpload")
10005 (set_attr "update" "yes")
10006 (set_attr "indexed" "yes,no")])
10007
10008 (define_insn "*movdf_update2"
10009 [(set (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
10010 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
10011 (match_operand:DF 3 "gpc_reg_operand" "d,d"))
10012 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
10013 (plus:SI (match_dup 1) (match_dup 2)))]
10014 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_UPDATE
10015 && (!avoiding_indexed_address_p (SImode)
10016 || !gpc_reg_operand (operands[2], SImode))"
10017 "@
10018 stfdux %3,%0,%2
10019 stfdu %3,%2(%0)"
10020 [(set_attr "type" "fpstore")
10021 (set_attr "update" "yes")
10022 (set_attr "indexed" "yes,no")])
10023
10024
10025 ;; After inserting conditional returns we can sometimes have
10026 ;; unnecessary register moves. Unfortunately we cannot have a
10027 ;; modeless peephole here, because some single SImode sets have early
10028 ;; clobber outputs. Although those sets expand to multi-ppc-insn
10029 ;; sequences, using get_attr_length here will smash the operands
10030 ;; array. Neither is there an early_cobbler_p predicate.
10031 ;; Disallow subregs for E500 so we don't munge frob_di_df_2.
10032 ;; Also this optimization interferes with scalars going into
10033 ;; altivec registers (the code does reloading through the FPRs).
10034 (define_peephole2
10035 [(set (match_operand:DF 0 "gpc_reg_operand" "")
10036 (match_operand:DF 1 "any_operand" ""))
10037 (set (match_operand:DF 2 "gpc_reg_operand" "")
10038 (match_dup 0))]
10039 "!(TARGET_E500_DOUBLE && GET_CODE (operands[2]) == SUBREG)
10040 && !TARGET_UPPER_REGS_DF
10041 && peep2_reg_dead_p (2, operands[0])"
10042 [(set (match_dup 2) (match_dup 1))])
10043
10044 (define_peephole2
10045 [(set (match_operand:SF 0 "gpc_reg_operand" "")
10046 (match_operand:SF 1 "any_operand" ""))
10047 (set (match_operand:SF 2 "gpc_reg_operand" "")
10048 (match_dup 0))]
10049 "!TARGET_UPPER_REGS_SF
10050 && peep2_reg_dead_p (2, operands[0])"
10051 [(set (match_dup 2) (match_dup 1))])
10052
10053 \f
10054 ;; TLS support.
10055
10056 ;; Mode attributes for different ABIs.
10057 (define_mode_iterator TLSmode [(SI "! TARGET_64BIT") (DI "TARGET_64BIT")])
10058 (define_mode_attr tls_abi_suffix [(SI "32") (DI "64")])
10059 (define_mode_attr tls_sysv_suffix [(SI "si") (DI "di")])
10060 (define_mode_attr tls_insn_suffix [(SI "wz") (DI "d")])
10061
10062 (define_insn_and_split "tls_gd_aix<TLSmode:tls_abi_suffix>"
10063 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10064 (call (mem:TLSmode (match_operand:TLSmode 3 "symbol_ref_operand" "s"))
10065 (match_operand 4 "" "g")))
10066 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10067 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10068 UNSPEC_TLSGD)
10069 (clobber (reg:SI LR_REGNO))]
10070 "HAVE_AS_TLS && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
10071 {
10072 if (TARGET_CMODEL != CMODEL_SMALL)
10073 return "addis %0,%1,%2@got@tlsgd@ha\;addi %0,%0,%2@got@tlsgd@l\;"
10074 "bl %z3\;nop";
10075 else
10076 return "addi %0,%1,%2@got@tlsgd\;bl %z3\;nop";
10077 }
10078 "&& TARGET_TLS_MARKERS"
10079 [(set (match_dup 0)
10080 (unspec:TLSmode [(match_dup 1)
10081 (match_dup 2)]
10082 UNSPEC_TLSGD))
10083 (parallel [(set (match_dup 0)
10084 (call (mem:TLSmode (match_dup 3))
10085 (match_dup 4)))
10086 (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGD)
10087 (clobber (reg:SI LR_REGNO))])]
10088 ""
10089 [(set_attr "type" "two")
10090 (set (attr "length")
10091 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
10092 (const_int 16)
10093 (const_int 12)))])
10094
10095 (define_insn_and_split "tls_gd_sysv<TLSmode:tls_sysv_suffix>"
10096 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10097 (call (mem:TLSmode (match_operand:TLSmode 3 "symbol_ref_operand" "s"))
10098 (match_operand 4 "" "g")))
10099 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10100 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10101 UNSPEC_TLSGD)
10102 (clobber (reg:SI LR_REGNO))]
10103 "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4"
10104 {
10105 if (flag_pic)
10106 {
10107 if (TARGET_SECURE_PLT && flag_pic == 2)
10108 return "addi %0,%1,%2@got@tlsgd\;bl %z3+32768@plt";
10109 else
10110 return "addi %0,%1,%2@got@tlsgd\;bl %z3@plt";
10111 }
10112 else
10113 return "addi %0,%1,%2@got@tlsgd\;bl %z3";
10114 }
10115 "&& TARGET_TLS_MARKERS"
10116 [(set (match_dup 0)
10117 (unspec:TLSmode [(match_dup 1)
10118 (match_dup 2)]
10119 UNSPEC_TLSGD))
10120 (parallel [(set (match_dup 0)
10121 (call (mem:TLSmode (match_dup 3))
10122 (match_dup 4)))
10123 (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGD)
10124 (clobber (reg:SI LR_REGNO))])]
10125 ""
10126 [(set_attr "type" "two")
10127 (set_attr "length" "8")])
10128
10129 (define_insn_and_split "*tls_gd<TLSmode:tls_abi_suffix>"
10130 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10131 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10132 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10133 UNSPEC_TLSGD))]
10134 "HAVE_AS_TLS && TARGET_TLS_MARKERS"
10135 "addi %0,%1,%2@got@tlsgd"
10136 "&& TARGET_CMODEL != CMODEL_SMALL"
10137 [(set (match_dup 3)
10138 (high:TLSmode
10139 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))
10140 (set (match_dup 0)
10141 (lo_sum:TLSmode (match_dup 3)
10142 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))]
10143 "
10144 {
10145 operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
10146 }"
10147 [(set (attr "length")
10148 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
10149 (const_int 8)
10150 (const_int 4)))])
10151
10152 (define_insn "*tls_gd_high<TLSmode:tls_abi_suffix>"
10153 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10154 (high:TLSmode
10155 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10156 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10157 UNSPEC_TLSGD)))]
10158 "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
10159 "addis %0,%1,%2@got@tlsgd@ha"
10160 [(set_attr "length" "4")])
10161
10162 (define_insn "*tls_gd_low<TLSmode:tls_abi_suffix>"
10163 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10164 (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
10165 (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
10166 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10167 UNSPEC_TLSGD)))]
10168 "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
10169 "addi %0,%1,%2@got@tlsgd@l"
10170 [(set_attr "length" "4")])
10171
10172 (define_insn "*tls_gd_call_aix<TLSmode:tls_abi_suffix>"
10173 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10174 (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
10175 (match_operand 2 "" "g")))
10176 (unspec:TLSmode [(match_operand:TLSmode 3 "rs6000_tls_symbol_ref" "")]
10177 UNSPEC_TLSGD)
10178 (clobber (reg:SI LR_REGNO))]
10179 "HAVE_AS_TLS && TARGET_TLS_MARKERS
10180 && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
10181 "bl %z1(%3@tlsgd)\;nop"
10182 [(set_attr "type" "branch")
10183 (set_attr "length" "8")])
10184
10185 (define_insn "*tls_gd_call_sysv<TLSmode:tls_abi_suffix>"
10186 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10187 (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
10188 (match_operand 2 "" "g")))
10189 (unspec:TLSmode [(match_operand:TLSmode 3 "rs6000_tls_symbol_ref" "")]
10190 UNSPEC_TLSGD)
10191 (clobber (reg:SI LR_REGNO))]
10192 "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4 && TARGET_TLS_MARKERS"
10193 {
10194 if (flag_pic)
10195 {
10196 if (TARGET_SECURE_PLT && flag_pic == 2)
10197 return "bl %z1+32768(%3@tlsgd)@plt";
10198 return "bl %z1(%3@tlsgd)@plt";
10199 }
10200 return "bl %z1(%3@tlsgd)";
10201 }
10202 [(set_attr "type" "branch")
10203 (set_attr "length" "4")])
10204
10205 (define_insn_and_split "tls_ld_aix<TLSmode:tls_abi_suffix>"
10206 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10207 (call (mem:TLSmode (match_operand:TLSmode 2 "symbol_ref_operand" "s"))
10208 (match_operand 3 "" "g")))
10209 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
10210 UNSPEC_TLSLD)
10211 (clobber (reg:SI LR_REGNO))]
10212 "HAVE_AS_TLS && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
10213 {
10214 if (TARGET_CMODEL != CMODEL_SMALL)
10215 return "addis %0,%1,%&@got@tlsld@ha\;addi %0,%0,%&@got@tlsld@l\;"
10216 "bl %z2\;nop";
10217 else
10218 return "addi %0,%1,%&@got@tlsld\;bl %z2\;nop";
10219 }
10220 "&& TARGET_TLS_MARKERS"
10221 [(set (match_dup 0)
10222 (unspec:TLSmode [(match_dup 1)]
10223 UNSPEC_TLSLD))
10224 (parallel [(set (match_dup 0)
10225 (call (mem:TLSmode (match_dup 2))
10226 (match_dup 3)))
10227 (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
10228 (clobber (reg:SI LR_REGNO))])]
10229 ""
10230 [(set_attr "type" "two")
10231 (set (attr "length")
10232 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
10233 (const_int 16)
10234 (const_int 12)))])
10235
10236 (define_insn_and_split "tls_ld_sysv<TLSmode:tls_sysv_suffix>"
10237 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10238 (call (mem:TLSmode (match_operand:TLSmode 2 "symbol_ref_operand" "s"))
10239 (match_operand 3 "" "g")))
10240 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
10241 UNSPEC_TLSLD)
10242 (clobber (reg:SI LR_REGNO))]
10243 "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4"
10244 {
10245 if (flag_pic)
10246 {
10247 if (TARGET_SECURE_PLT && flag_pic == 2)
10248 return "addi %0,%1,%&@got@tlsld\;bl %z2+32768@plt";
10249 else
10250 return "addi %0,%1,%&@got@tlsld\;bl %z2@plt";
10251 }
10252 else
10253 return "addi %0,%1,%&@got@tlsld\;bl %z2";
10254 }
10255 "&& TARGET_TLS_MARKERS"
10256 [(set (match_dup 0)
10257 (unspec:TLSmode [(match_dup 1)]
10258 UNSPEC_TLSLD))
10259 (parallel [(set (match_dup 0)
10260 (call (mem:TLSmode (match_dup 2))
10261 (match_dup 3)))
10262 (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
10263 (clobber (reg:SI LR_REGNO))])]
10264 ""
10265 [(set_attr "length" "8")])
10266
10267 (define_insn_and_split "*tls_ld<TLSmode:tls_abi_suffix>"
10268 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10269 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
10270 UNSPEC_TLSLD))]
10271 "HAVE_AS_TLS && TARGET_TLS_MARKERS"
10272 "addi %0,%1,%&@got@tlsld"
10273 "&& TARGET_CMODEL != CMODEL_SMALL"
10274 [(set (match_dup 2)
10275 (high:TLSmode
10276 (unspec:TLSmode [(const_int 0) (match_dup 1)] UNSPEC_TLSLD)))
10277 (set (match_dup 0)
10278 (lo_sum:TLSmode (match_dup 2)
10279 (unspec:TLSmode [(const_int 0) (match_dup 1)] UNSPEC_TLSLD)))]
10280 "
10281 {
10282 operands[2] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
10283 }"
10284 [(set (attr "length")
10285 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
10286 (const_int 8)
10287 (const_int 4)))])
10288
10289 (define_insn "*tls_ld_high<TLSmode:tls_abi_suffix>"
10290 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10291 (high:TLSmode
10292 (unspec:TLSmode [(const_int 0)
10293 (match_operand:TLSmode 1 "gpc_reg_operand" "b")]
10294 UNSPEC_TLSLD)))]
10295 "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
10296 "addis %0,%1,%&@got@tlsld@ha"
10297 [(set_attr "length" "4")])
10298
10299 (define_insn "*tls_ld_low<TLSmode:tls_abi_suffix>"
10300 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10301 (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
10302 (unspec:TLSmode [(const_int 0)
10303 (match_operand:TLSmode 2 "gpc_reg_operand" "b")]
10304 UNSPEC_TLSLD)))]
10305 "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
10306 "addi %0,%1,%&@got@tlsld@l"
10307 [(set_attr "length" "4")])
10308
10309 (define_insn "*tls_ld_call_aix<TLSmode:tls_abi_suffix>"
10310 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10311 (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
10312 (match_operand 2 "" "g")))
10313 (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
10314 (clobber (reg:SI LR_REGNO))]
10315 "HAVE_AS_TLS && TARGET_TLS_MARKERS
10316 && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
10317 "bl %z1(%&@tlsld)\;nop"
10318 [(set_attr "type" "branch")
10319 (set_attr "length" "8")])
10320
10321 (define_insn "*tls_ld_call_sysv<TLSmode:tls_abi_suffix>"
10322 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10323 (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
10324 (match_operand 2 "" "g")))
10325 (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
10326 (clobber (reg:SI LR_REGNO))]
10327 "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4 && TARGET_TLS_MARKERS"
10328 {
10329 if (flag_pic)
10330 {
10331 if (TARGET_SECURE_PLT && flag_pic == 2)
10332 return "bl %z1+32768(%&@tlsld)@plt";
10333 return "bl %z1(%&@tlsld)@plt";
10334 }
10335 return "bl %z1(%&@tlsld)";
10336 }
10337 [(set_attr "type" "branch")
10338 (set_attr "length" "4")])
10339
10340 (define_insn "tls_dtprel_<TLSmode:tls_abi_suffix>"
10341 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10342 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10343 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10344 UNSPEC_TLSDTPREL))]
10345 "HAVE_AS_TLS"
10346 "addi %0,%1,%2@dtprel")
10347
10348 (define_insn "tls_dtprel_ha_<TLSmode:tls_abi_suffix>"
10349 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10350 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10351 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10352 UNSPEC_TLSDTPRELHA))]
10353 "HAVE_AS_TLS"
10354 "addis %0,%1,%2@dtprel@ha")
10355
10356 (define_insn "tls_dtprel_lo_<TLSmode:tls_abi_suffix>"
10357 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10358 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10359 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10360 UNSPEC_TLSDTPRELLO))]
10361 "HAVE_AS_TLS"
10362 "addi %0,%1,%2@dtprel@l")
10363
10364 (define_insn_and_split "tls_got_dtprel_<TLSmode:tls_abi_suffix>"
10365 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10366 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10367 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10368 UNSPEC_TLSGOTDTPREL))]
10369 "HAVE_AS_TLS"
10370 "l<TLSmode:tls_insn_suffix> %0,%2@got@dtprel(%1)"
10371 "&& TARGET_CMODEL != CMODEL_SMALL"
10372 [(set (match_dup 3)
10373 (high:TLSmode
10374 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))
10375 (set (match_dup 0)
10376 (lo_sum:TLSmode (match_dup 3)
10377 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))]
10378 "
10379 {
10380 operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
10381 }"
10382 [(set (attr "length")
10383 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
10384 (const_int 8)
10385 (const_int 4)))])
10386
10387 (define_insn "*tls_got_dtprel_high<TLSmode:tls_abi_suffix>"
10388 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10389 (high:TLSmode
10390 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10391 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10392 UNSPEC_TLSGOTDTPREL)))]
10393 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
10394 "addis %0,%1,%2@got@dtprel@ha"
10395 [(set_attr "length" "4")])
10396
10397 (define_insn "*tls_got_dtprel_low<TLSmode:tls_abi_suffix>"
10398 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10399 (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
10400 (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
10401 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10402 UNSPEC_TLSGOTDTPREL)))]
10403 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
10404 "l<TLSmode:tls_insn_suffix> %0,%2@got@dtprel@l(%1)"
10405 [(set_attr "length" "4")])
10406
10407 (define_insn "tls_tprel_<TLSmode:tls_abi_suffix>"
10408 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10409 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10410 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10411 UNSPEC_TLSTPREL))]
10412 "HAVE_AS_TLS"
10413 "addi %0,%1,%2@tprel")
10414
10415 (define_insn "tls_tprel_ha_<TLSmode:tls_abi_suffix>"
10416 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10417 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10418 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10419 UNSPEC_TLSTPRELHA))]
10420 "HAVE_AS_TLS"
10421 "addis %0,%1,%2@tprel@ha")
10422
10423 (define_insn "tls_tprel_lo_<TLSmode:tls_abi_suffix>"
10424 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10425 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10426 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10427 UNSPEC_TLSTPRELLO))]
10428 "HAVE_AS_TLS"
10429 "addi %0,%1,%2@tprel@l")
10430
10431 ;; "b" output constraint here and on tls_tls input to support linker tls
10432 ;; optimization. The linker may edit the instructions emitted by a
10433 ;; tls_got_tprel/tls_tls pair to addis,addi.
10434 (define_insn_and_split "tls_got_tprel_<TLSmode:tls_abi_suffix>"
10435 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10436 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10437 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10438 UNSPEC_TLSGOTTPREL))]
10439 "HAVE_AS_TLS"
10440 "l<TLSmode:tls_insn_suffix> %0,%2@got@tprel(%1)"
10441 "&& TARGET_CMODEL != CMODEL_SMALL"
10442 [(set (match_dup 3)
10443 (high:TLSmode
10444 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))
10445 (set (match_dup 0)
10446 (lo_sum:TLSmode (match_dup 3)
10447 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))]
10448 "
10449 {
10450 operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
10451 }"
10452 [(set (attr "length")
10453 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
10454 (const_int 8)
10455 (const_int 4)))])
10456
10457 (define_insn "*tls_got_tprel_high<TLSmode:tls_abi_suffix>"
10458 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10459 (high:TLSmode
10460 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10461 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10462 UNSPEC_TLSGOTTPREL)))]
10463 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
10464 "addis %0,%1,%2@got@tprel@ha"
10465 [(set_attr "length" "4")])
10466
10467 (define_insn "*tls_got_tprel_low<TLSmode:tls_abi_suffix>"
10468 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10469 (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
10470 (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
10471 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10472 UNSPEC_TLSGOTTPREL)))]
10473 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
10474 "l<TLSmode:tls_insn_suffix> %0,%2@got@tprel@l(%1)"
10475 [(set_attr "length" "4")])
10476
10477 (define_insn "tls_tls_<TLSmode:tls_abi_suffix>"
10478 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10479 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10480 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10481 UNSPEC_TLSTLS))]
10482 "TARGET_ELF && HAVE_AS_TLS"
10483 "add %0,%1,%2@tls")
10484
10485 (define_expand "tls_get_tpointer"
10486 [(set (match_operand:SI 0 "gpc_reg_operand" "")
10487 (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))]
10488 "TARGET_XCOFF && HAVE_AS_TLS"
10489 "
10490 {
10491 emit_insn (gen_tls_get_tpointer_internal ());
10492 emit_move_insn (operands[0], gen_rtx_REG (SImode, 3));
10493 DONE;
10494 }")
10495
10496 (define_insn "tls_get_tpointer_internal"
10497 [(set (reg:SI 3)
10498 (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))
10499 (clobber (reg:SI LR_REGNO))]
10500 "TARGET_XCOFF && HAVE_AS_TLS"
10501 "bla __get_tpointer")
10502
10503 (define_expand "tls_get_addr<mode>"
10504 [(set (match_operand:P 0 "gpc_reg_operand" "")
10505 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "")
10506 (match_operand:P 2 "gpc_reg_operand" "")] UNSPEC_TLSTLS))]
10507 "TARGET_XCOFF && HAVE_AS_TLS"
10508 "
10509 {
10510 emit_move_insn (gen_rtx_REG (Pmode, 3), operands[1]);
10511 emit_move_insn (gen_rtx_REG (Pmode, 4), operands[2]);
10512 emit_insn (gen_tls_get_addr_internal<mode> ());
10513 emit_move_insn (operands[0], gen_rtx_REG (Pmode, 3));
10514 DONE;
10515 }")
10516
10517 (define_insn "tls_get_addr_internal<mode>"
10518 [(set (reg:P 3)
10519 (unspec:P [(reg:P 3) (reg:P 4)] UNSPEC_TLSTLS))
10520 (clobber (reg:P 0))
10521 (clobber (reg:P 4))
10522 (clobber (reg:P 5))
10523 (clobber (reg:P 11))
10524 (clobber (reg:CC CR0_REGNO))
10525 (clobber (reg:P LR_REGNO))]
10526 "TARGET_XCOFF && HAVE_AS_TLS"
10527 "bla __tls_get_addr")
10528 \f
10529 ;; Next come insns related to the calling sequence.
10530 ;;
10531 ;; First, an insn to allocate new stack space for dynamic use (e.g., alloca).
10532 ;; We move the back-chain and decrement the stack pointer.
10533
10534 (define_expand "allocate_stack"
10535 [(set (match_operand 0 "gpc_reg_operand" "")
10536 (minus (reg 1) (match_operand 1 "reg_or_short_operand" "")))
10537 (set (reg 1)
10538 (minus (reg 1) (match_dup 1)))]
10539 ""
10540 "
10541 { rtx chain = gen_reg_rtx (Pmode);
10542 rtx stack_bot = gen_rtx_MEM (Pmode, stack_pointer_rtx);
10543 rtx neg_op0;
10544 rtx insn, par, set, mem;
10545
10546 emit_move_insn (chain, stack_bot);
10547
10548 /* Check stack bounds if necessary. */
10549 if (crtl->limit_stack)
10550 {
10551 rtx available;
10552 available = expand_binop (Pmode, sub_optab,
10553 stack_pointer_rtx, stack_limit_rtx,
10554 NULL_RTX, 1, OPTAB_WIDEN);
10555 emit_insn (gen_cond_trap (LTU, available, operands[1], const0_rtx));
10556 }
10557
10558 if (GET_CODE (operands[1]) != CONST_INT
10559 || INTVAL (operands[1]) < -32767
10560 || INTVAL (operands[1]) > 32768)
10561 {
10562 neg_op0 = gen_reg_rtx (Pmode);
10563 if (TARGET_32BIT)
10564 emit_insn (gen_negsi2 (neg_op0, operands[1]));
10565 else
10566 emit_insn (gen_negdi2 (neg_op0, operands[1]));
10567 }
10568 else
10569 neg_op0 = GEN_INT (- INTVAL (operands[1]));
10570
10571 insn = emit_insn ((* ((TARGET_32BIT) ? gen_movsi_update_stack
10572 : gen_movdi_di_update_stack))
10573 (stack_pointer_rtx, stack_pointer_rtx, neg_op0,
10574 chain));
10575 /* Since we didn't use gen_frame_mem to generate the MEM, grab
10576 it now and set the alias set/attributes. The above gen_*_update
10577 calls will generate a PARALLEL with the MEM set being the first
10578 operation. */
10579 par = PATTERN (insn);
10580 gcc_assert (GET_CODE (par) == PARALLEL);
10581 set = XVECEXP (par, 0, 0);
10582 gcc_assert (GET_CODE (set) == SET);
10583 mem = SET_DEST (set);
10584 gcc_assert (MEM_P (mem));
10585 MEM_NOTRAP_P (mem) = 1;
10586 set_mem_alias_set (mem, get_frame_alias_set ());
10587
10588 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
10589 DONE;
10590 }")
10591
10592 ;; These patterns say how to save and restore the stack pointer. We need not
10593 ;; save the stack pointer at function level since we are careful to
10594 ;; preserve the backchain. At block level, we have to restore the backchain
10595 ;; when we restore the stack pointer.
10596 ;;
10597 ;; For nonlocal gotos, we must save both the stack pointer and its
10598 ;; backchain and restore both. Note that in the nonlocal case, the
10599 ;; save area is a memory location.
10600
10601 (define_expand "save_stack_function"
10602 [(match_operand 0 "any_operand" "")
10603 (match_operand 1 "any_operand" "")]
10604 ""
10605 "DONE;")
10606
10607 (define_expand "restore_stack_function"
10608 [(match_operand 0 "any_operand" "")
10609 (match_operand 1 "any_operand" "")]
10610 ""
10611 "DONE;")
10612
10613 ;; Adjust stack pointer (op0) to a new value (op1).
10614 ;; First copy old stack backchain to new location, and ensure that the
10615 ;; scheduler won't reorder the sp assignment before the backchain write.
10616 (define_expand "restore_stack_block"
10617 [(set (match_dup 2) (match_dup 3))
10618 (set (match_dup 4) (match_dup 2))
10619 (match_dup 5)
10620 (set (match_operand 0 "register_operand" "")
10621 (match_operand 1 "register_operand" ""))]
10622 ""
10623 "
10624 {
10625 rtvec p;
10626
10627 operands[1] = force_reg (Pmode, operands[1]);
10628 operands[2] = gen_reg_rtx (Pmode);
10629 operands[3] = gen_frame_mem (Pmode, operands[0]);
10630 operands[4] = gen_frame_mem (Pmode, operands[1]);
10631 p = rtvec_alloc (1);
10632 RTVEC_ELT (p, 0) = gen_rtx_SET (VOIDmode,
10633 gen_frame_mem (BLKmode, operands[0]),
10634 const0_rtx);
10635 operands[5] = gen_rtx_PARALLEL (VOIDmode, p);
10636 }")
10637
10638 (define_expand "save_stack_nonlocal"
10639 [(set (match_dup 3) (match_dup 4))
10640 (set (match_operand 0 "memory_operand" "") (match_dup 3))
10641 (set (match_dup 2) (match_operand 1 "register_operand" ""))]
10642 ""
10643 "
10644 {
10645 int units_per_word = (TARGET_32BIT) ? 4 : 8;
10646
10647 /* Copy the backchain to the first word, sp to the second. */
10648 operands[0] = adjust_address_nv (operands[0], Pmode, 0);
10649 operands[2] = adjust_address_nv (operands[0], Pmode, units_per_word);
10650 operands[3] = gen_reg_rtx (Pmode);
10651 operands[4] = gen_frame_mem (Pmode, operands[1]);
10652 }")
10653
10654 (define_expand "restore_stack_nonlocal"
10655 [(set (match_dup 2) (match_operand 1 "memory_operand" ""))
10656 (set (match_dup 3) (match_dup 4))
10657 (set (match_dup 5) (match_dup 2))
10658 (match_dup 6)
10659 (set (match_operand 0 "register_operand" "") (match_dup 3))]
10660 ""
10661 "
10662 {
10663 int units_per_word = (TARGET_32BIT) ? 4 : 8;
10664 rtvec p;
10665
10666 /* Restore the backchain from the first word, sp from the second. */
10667 operands[2] = gen_reg_rtx (Pmode);
10668 operands[3] = gen_reg_rtx (Pmode);
10669 operands[1] = adjust_address_nv (operands[1], Pmode, 0);
10670 operands[4] = adjust_address_nv (operands[1], Pmode, units_per_word);
10671 operands[5] = gen_frame_mem (Pmode, operands[3]);
10672 p = rtvec_alloc (1);
10673 RTVEC_ELT (p, 0) = gen_rtx_SET (VOIDmode,
10674 gen_frame_mem (BLKmode, operands[0]),
10675 const0_rtx);
10676 operands[6] = gen_rtx_PARALLEL (VOIDmode, p);
10677 }")
10678 \f
10679 ;; TOC register handling.
10680
10681 ;; Code to initialize the TOC register...
10682
10683 (define_insn "load_toc_aix_si"
10684 [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10685 (unspec:SI [(const_int 0)] UNSPEC_TOC))
10686 (use (reg:SI 2))])]
10687 "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_32BIT"
10688 "*
10689 {
10690 char buf[30];
10691 ASM_GENERATE_INTERNAL_LABEL (buf, \"LCTOC\", 1);
10692 operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
10693 operands[2] = gen_rtx_REG (Pmode, 2);
10694 return \"lwz %0,%1(%2)\";
10695 }"
10696 [(set_attr "type" "load")
10697 (set_attr "update" "no")
10698 (set_attr "indexed" "no")])
10699
10700 (define_insn "load_toc_aix_di"
10701 [(parallel [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
10702 (unspec:DI [(const_int 0)] UNSPEC_TOC))
10703 (use (reg:DI 2))])]
10704 "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_64BIT"
10705 "*
10706 {
10707 char buf[30];
10708 #ifdef TARGET_RELOCATABLE
10709 ASM_GENERATE_INTERNAL_LABEL (buf, \"LCTOC\",
10710 !TARGET_MINIMAL_TOC || TARGET_RELOCATABLE);
10711 #else
10712 ASM_GENERATE_INTERNAL_LABEL (buf, \"LCTOC\", 1);
10713 #endif
10714 if (TARGET_ELF)
10715 strcat (buf, \"@toc\");
10716 operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
10717 operands[2] = gen_rtx_REG (Pmode, 2);
10718 return \"ld %0,%1(%2)\";
10719 }"
10720 [(set_attr "type" "load")
10721 (set_attr "update" "no")
10722 (set_attr "indexed" "no")])
10723
10724 (define_insn "load_toc_v4_pic_si"
10725 [(set (reg:SI LR_REGNO)
10726 (unspec:SI [(const_int 0)] UNSPEC_TOC))]
10727 "DEFAULT_ABI == ABI_V4 && flag_pic == 1 && TARGET_32BIT"
10728 "bl _GLOBAL_OFFSET_TABLE_@local-4"
10729 [(set_attr "type" "branch")
10730 (set_attr "length" "4")])
10731
10732 (define_expand "load_toc_v4_PIC_1"
10733 [(parallel [(set (reg:SI LR_REGNO)
10734 (match_operand:SI 0 "immediate_operand" "s"))
10735 (use (unspec [(match_dup 0)] UNSPEC_TOC))])]
10736 "TARGET_ELF && DEFAULT_ABI == ABI_V4
10737 && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10738 "")
10739
10740 (define_insn "load_toc_v4_PIC_1_normal"
10741 [(set (reg:SI LR_REGNO)
10742 (match_operand:SI 0 "immediate_operand" "s"))
10743 (use (unspec [(match_dup 0)] UNSPEC_TOC))]
10744 "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
10745 && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10746 "bcl 20,31,%0\\n%0:"
10747 [(set_attr "type" "branch")
10748 (set_attr "length" "4")])
10749
10750 (define_insn "load_toc_v4_PIC_1_476"
10751 [(set (reg:SI LR_REGNO)
10752 (match_operand:SI 0 "immediate_operand" "s"))
10753 (use (unspec [(match_dup 0)] UNSPEC_TOC))]
10754 "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
10755 && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10756 "*
10757 {
10758 char name[32];
10759 static char templ[32];
10760
10761 get_ppc476_thunk_name (name);
10762 sprintf (templ, \"bl %s\\n%%0:\", name);
10763 return templ;
10764 }"
10765 [(set_attr "type" "branch")
10766 (set_attr "length" "4")])
10767
10768 (define_expand "load_toc_v4_PIC_1b"
10769 [(parallel [(set (reg:SI LR_REGNO)
10770 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10771 (label_ref (match_operand 1 "" ""))]
10772 UNSPEC_TOCPTR))
10773 (match_dup 1)])]
10774 "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10775 "")
10776
10777 (define_insn "load_toc_v4_PIC_1b_normal"
10778 [(set (reg:SI LR_REGNO)
10779 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10780 (label_ref (match_operand 1 "" ""))]
10781 UNSPEC_TOCPTR))
10782 (match_dup 1)]
10783 "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10784 "bcl 20,31,$+8\;.long %0-$"
10785 [(set_attr "type" "branch")
10786 (set_attr "length" "8")])
10787
10788 (define_insn "load_toc_v4_PIC_1b_476"
10789 [(set (reg:SI LR_REGNO)
10790 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10791 (label_ref (match_operand 1 "" ""))]
10792 UNSPEC_TOCPTR))
10793 (match_dup 1)]
10794 "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10795 "*
10796 {
10797 char name[32];
10798 static char templ[32];
10799
10800 get_ppc476_thunk_name (name);
10801 sprintf (templ, \"bl %s\\n\\tb $+8\\n\\t.long %%0-$\", name);
10802 return templ;
10803 }"
10804 [(set_attr "type" "branch")
10805 (set_attr "length" "16")])
10806
10807 (define_insn "load_toc_v4_PIC_2"
10808 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10809 (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
10810 (minus:SI (match_operand:SI 2 "immediate_operand" "s")
10811 (match_operand:SI 3 "immediate_operand" "s")))))]
10812 "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10813 "lwz %0,%2-%3(%1)"
10814 [(set_attr "type" "load")])
10815
10816 (define_insn "load_toc_v4_PIC_3b"
10817 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10818 (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
10819 (high:SI
10820 (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
10821 (match_operand:SI 3 "symbol_ref_operand" "s")))))]
10822 "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
10823 "addis %0,%1,%2-%3@ha")
10824
10825 (define_insn "load_toc_v4_PIC_3c"
10826 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10827 (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
10828 (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
10829 (match_operand:SI 3 "symbol_ref_operand" "s"))))]
10830 "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
10831 "addi %0,%1,%2-%3@l")
10832
10833 ;; If the TOC is shared over a translation unit, as happens with all
10834 ;; the kinds of PIC that we support, we need to restore the TOC
10835 ;; pointer only when jumping over units of translation.
10836 ;; On Darwin, we need to reload the picbase.
10837
10838 (define_expand "builtin_setjmp_receiver"
10839 [(use (label_ref (match_operand 0 "" "")))]
10840 "(DEFAULT_ABI == ABI_V4 && flag_pic == 1)
10841 || (TARGET_TOC && TARGET_MINIMAL_TOC)
10842 || (DEFAULT_ABI == ABI_DARWIN && flag_pic)"
10843 "
10844 {
10845 #if TARGET_MACHO
10846 if (DEFAULT_ABI == ABI_DARWIN)
10847 {
10848 rtx picrtx = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME);
10849 rtx picreg = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
10850 rtx tmplabrtx;
10851 char tmplab[20];
10852
10853 crtl->uses_pic_offset_table = 1;
10854 ASM_GENERATE_INTERNAL_LABEL(tmplab, \"LSJR\",
10855 CODE_LABEL_NUMBER (operands[0]));
10856 tmplabrtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (tmplab));
10857
10858 emit_insn (gen_load_macho_picbase (tmplabrtx));
10859 emit_move_insn (picreg, gen_rtx_REG (Pmode, LR_REGNO));
10860 emit_insn (gen_macho_correct_pic (picreg, picreg, picrtx, tmplabrtx));
10861 }
10862 else
10863 #endif
10864 rs6000_emit_load_toc_table (FALSE);
10865 DONE;
10866 }")
10867
10868 ;; Largetoc support
10869 (define_insn "*largetoc_high"
10870 [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
10871 (high:DI
10872 (unspec [(match_operand:DI 1 "" "")
10873 (match_operand:DI 2 "gpc_reg_operand" "b")]
10874 UNSPEC_TOCREL)))]
10875 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10876 "addis %0,%2,%1@toc@ha")
10877
10878 (define_insn "*largetoc_high_aix<mode>"
10879 [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
10880 (high:P
10881 (unspec [(match_operand:P 1 "" "")
10882 (match_operand:P 2 "gpc_reg_operand" "b")]
10883 UNSPEC_TOCREL)))]
10884 "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10885 "addis %0,%1@u(%2)")
10886
10887 (define_insn "*largetoc_high_plus"
10888 [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
10889 (high:DI
10890 (plus:DI
10891 (unspec [(match_operand:DI 1 "" "")
10892 (match_operand:DI 2 "gpc_reg_operand" "b")]
10893 UNSPEC_TOCREL)
10894 (match_operand:DI 3 "add_cint_operand" "n"))))]
10895 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10896 "addis %0,%2,%1+%3@toc@ha")
10897
10898 (define_insn "*largetoc_high_plus_aix<mode>"
10899 [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
10900 (high:P
10901 (plus:P
10902 (unspec [(match_operand:P 1 "" "")
10903 (match_operand:P 2 "gpc_reg_operand" "b")]
10904 UNSPEC_TOCREL)
10905 (match_operand:P 3 "add_cint_operand" "n"))))]
10906 "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10907 "addis %0,%1+%3@u(%2)")
10908
10909 (define_insn "*largetoc_low"
10910 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
10911 (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b")
10912 (match_operand:DI 2 "" "")))]
10913 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10914 "addi %0,%1,%2@l")
10915
10916 (define_insn "*largetoc_low_aix<mode>"
10917 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10918 (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
10919 (match_operand:P 2 "" "")))]
10920 "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10921 "la %0,%2@l(%1)")
10922
10923 (define_insn_and_split "*tocref<mode>"
10924 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
10925 (match_operand:P 1 "small_toc_ref" "R"))]
10926 "TARGET_TOC"
10927 "la %0,%a1"
10928 "&& TARGET_CMODEL != CMODEL_SMALL && reload_completed"
10929 [(set (match_dup 0) (high:P (match_dup 1)))
10930 (set (match_dup 0) (lo_sum:P (match_dup 0) (match_dup 1)))])
10931
10932 ;; Elf specific ways of loading addresses for non-PIC code.
10933 ;; The output of this could be r0, but we make a very strong
10934 ;; preference for a base register because it will usually
10935 ;; be needed there.
10936 (define_insn "elf_high"
10937 [(set (match_operand:SI 0 "gpc_reg_operand" "=b*r")
10938 (high:SI (match_operand 1 "" "")))]
10939 "TARGET_ELF && ! TARGET_64BIT"
10940 "lis %0,%1@ha")
10941
10942 (define_insn "elf_low"
10943 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10944 (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
10945 (match_operand 2 "" "")))]
10946 "TARGET_ELF && ! TARGET_64BIT"
10947 "la %0,%2@l(%1)")
10948 \f
10949 ;; Call and call_value insns
10950 (define_expand "call"
10951 [(parallel [(call (mem:SI (match_operand 0 "address_operand" ""))
10952 (match_operand 1 "" ""))
10953 (use (match_operand 2 "" ""))
10954 (clobber (reg:SI LR_REGNO))])]
10955 ""
10956 "
10957 {
10958 #if TARGET_MACHO
10959 if (MACHOPIC_INDIRECT)
10960 operands[0] = machopic_indirect_call_target (operands[0]);
10961 #endif
10962
10963 gcc_assert (GET_CODE (operands[0]) == MEM);
10964 gcc_assert (GET_CODE (operands[1]) == CONST_INT);
10965
10966 operands[0] = XEXP (operands[0], 0);
10967
10968 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10969 {
10970 rs6000_call_aix (NULL_RTX, operands[0], operands[1], operands[2]);
10971 DONE;
10972 }
10973
10974 if (GET_CODE (operands[0]) != SYMBOL_REF
10975 || (DEFAULT_ABI != ABI_DARWIN && (INTVAL (operands[2]) & CALL_LONG) != 0))
10976 {
10977 if (INTVAL (operands[2]) & CALL_LONG)
10978 operands[0] = rs6000_longcall_ref (operands[0]);
10979
10980 switch (DEFAULT_ABI)
10981 {
10982 case ABI_V4:
10983 case ABI_DARWIN:
10984 operands[0] = force_reg (Pmode, operands[0]);
10985 break;
10986
10987 default:
10988 gcc_unreachable ();
10989 }
10990 }
10991 }")
10992
10993 (define_expand "call_value"
10994 [(parallel [(set (match_operand 0 "" "")
10995 (call (mem:SI (match_operand 1 "address_operand" ""))
10996 (match_operand 2 "" "")))
10997 (use (match_operand 3 "" ""))
10998 (clobber (reg:SI LR_REGNO))])]
10999 ""
11000 "
11001 {
11002 #if TARGET_MACHO
11003 if (MACHOPIC_INDIRECT)
11004 operands[1] = machopic_indirect_call_target (operands[1]);
11005 #endif
11006
11007 gcc_assert (GET_CODE (operands[1]) == MEM);
11008 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
11009
11010 operands[1] = XEXP (operands[1], 0);
11011
11012 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
11013 {
11014 rs6000_call_aix (operands[0], operands[1], operands[2], operands[3]);
11015 DONE;
11016 }
11017
11018 if (GET_CODE (operands[1]) != SYMBOL_REF
11019 || (DEFAULT_ABI != ABI_DARWIN && (INTVAL (operands[3]) & CALL_LONG) != 0))
11020 {
11021 if (INTVAL (operands[3]) & CALL_LONG)
11022 operands[1] = rs6000_longcall_ref (operands[1]);
11023
11024 switch (DEFAULT_ABI)
11025 {
11026 case ABI_V4:
11027 case ABI_DARWIN:
11028 operands[1] = force_reg (Pmode, operands[1]);
11029 break;
11030
11031 default:
11032 gcc_unreachable ();
11033 }
11034 }
11035 }")
11036
11037 ;; Call to function in current module. No TOC pointer reload needed.
11038 ;; Operand2 is nonzero if we are using the V.4 calling sequence and
11039 ;; either the function was not prototyped, or it was prototyped as a
11040 ;; variable argument function. It is > 0 if FP registers were passed
11041 ;; and < 0 if they were not.
11042
11043 (define_insn "*call_local32"
11044 [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
11045 (match_operand 1 "" "g,g"))
11046 (use (match_operand:SI 2 "immediate_operand" "O,n"))
11047 (clobber (reg:SI LR_REGNO))]
11048 "(INTVAL (operands[2]) & CALL_LONG) == 0"
11049 "*
11050 {
11051 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
11052 output_asm_insn (\"crxor 6,6,6\", operands);
11053
11054 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
11055 output_asm_insn (\"creqv 6,6,6\", operands);
11056
11057 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z0@local\" : \"bl %z0\";
11058 }"
11059 [(set_attr "type" "branch")
11060 (set_attr "length" "4,8")])
11061
11062 (define_insn "*call_local64"
11063 [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
11064 (match_operand 1 "" "g,g"))
11065 (use (match_operand:SI 2 "immediate_operand" "O,n"))
11066 (clobber (reg:SI LR_REGNO))]
11067 "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
11068 "*
11069 {
11070 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
11071 output_asm_insn (\"crxor 6,6,6\", operands);
11072
11073 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
11074 output_asm_insn (\"creqv 6,6,6\", operands);
11075
11076 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z0@local\" : \"bl %z0\";
11077 }"
11078 [(set_attr "type" "branch")
11079 (set_attr "length" "4,8")])
11080
11081 (define_insn "*call_value_local32"
11082 [(set (match_operand 0 "" "")
11083 (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
11084 (match_operand 2 "" "g,g")))
11085 (use (match_operand:SI 3 "immediate_operand" "O,n"))
11086 (clobber (reg:SI LR_REGNO))]
11087 "(INTVAL (operands[3]) & CALL_LONG) == 0"
11088 "*
11089 {
11090 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11091 output_asm_insn (\"crxor 6,6,6\", operands);
11092
11093 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11094 output_asm_insn (\"creqv 6,6,6\", operands);
11095
11096 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z1@local\" : \"bl %z1\";
11097 }"
11098 [(set_attr "type" "branch")
11099 (set_attr "length" "4,8")])
11100
11101
11102 (define_insn "*call_value_local64"
11103 [(set (match_operand 0 "" "")
11104 (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
11105 (match_operand 2 "" "g,g")))
11106 (use (match_operand:SI 3 "immediate_operand" "O,n"))
11107 (clobber (reg:SI LR_REGNO))]
11108 "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
11109 "*
11110 {
11111 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11112 output_asm_insn (\"crxor 6,6,6\", operands);
11113
11114 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11115 output_asm_insn (\"creqv 6,6,6\", operands);
11116
11117 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z1@local\" : \"bl %z1\";
11118 }"
11119 [(set_attr "type" "branch")
11120 (set_attr "length" "4,8")])
11121
11122
11123 ;; A function pointer under System V is just a normal pointer
11124 ;; operands[0] is the function pointer
11125 ;; operands[1] is the stack size to clean up
11126 ;; operands[2] is the value FUNCTION_ARG returns for the VOID argument
11127 ;; which indicates how to set cr1
11128
11129 (define_insn "*call_indirect_nonlocal_sysv<mode>"
11130 [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l,c,*l"))
11131 (match_operand 1 "" "g,g,g,g"))
11132 (use (match_operand:SI 2 "immediate_operand" "O,O,n,n"))
11133 (clobber (reg:SI LR_REGNO))]
11134 "DEFAULT_ABI == ABI_V4
11135 || DEFAULT_ABI == ABI_DARWIN"
11136 {
11137 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
11138 output_asm_insn ("crxor 6,6,6", operands);
11139
11140 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
11141 output_asm_insn ("creqv 6,6,6", operands);
11142
11143 return "b%T0l";
11144 }
11145 [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg")
11146 (set_attr "length" "4,4,8,8")])
11147
11148 (define_insn_and_split "*call_nonlocal_sysv<mode>"
11149 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
11150 (match_operand 1 "" "g,g"))
11151 (use (match_operand:SI 2 "immediate_operand" "O,n"))
11152 (clobber (reg:SI LR_REGNO))]
11153 "(DEFAULT_ABI == ABI_DARWIN
11154 || (DEFAULT_ABI == ABI_V4
11155 && (INTVAL (operands[2]) & CALL_LONG) == 0))"
11156 {
11157 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
11158 output_asm_insn ("crxor 6,6,6", operands);
11159
11160 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
11161 output_asm_insn ("creqv 6,6,6", operands);
11162
11163 #if TARGET_MACHO
11164 return output_call(insn, operands, 0, 2);
11165 #else
11166 if (DEFAULT_ABI == ABI_V4 && flag_pic)
11167 {
11168 gcc_assert (!TARGET_SECURE_PLT);
11169 return "bl %z0@plt";
11170 }
11171 else
11172 return "bl %z0";
11173 #endif
11174 }
11175 "DEFAULT_ABI == ABI_V4
11176 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0])
11177 && (INTVAL (operands[2]) & CALL_LONG) == 0"
11178 [(parallel [(call (mem:SI (match_dup 0))
11179 (match_dup 1))
11180 (use (match_dup 2))
11181 (use (match_dup 3))
11182 (clobber (reg:SI LR_REGNO))])]
11183 {
11184 operands[3] = pic_offset_table_rtx;
11185 }
11186 [(set_attr "type" "branch,branch")
11187 (set_attr "length" "4,8")])
11188
11189 (define_insn "*call_nonlocal_sysv_secure<mode>"
11190 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
11191 (match_operand 1 "" "g,g"))
11192 (use (match_operand:SI 2 "immediate_operand" "O,n"))
11193 (use (match_operand:SI 3 "register_operand" "r,r"))
11194 (clobber (reg:SI LR_REGNO))]
11195 "(DEFAULT_ABI == ABI_V4
11196 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0])
11197 && (INTVAL (operands[2]) & CALL_LONG) == 0)"
11198 {
11199 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
11200 output_asm_insn ("crxor 6,6,6", operands);
11201
11202 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
11203 output_asm_insn ("creqv 6,6,6", operands);
11204
11205 if (flag_pic == 2)
11206 /* The magic 32768 offset here and in the other sysv call insns
11207 corresponds to the offset of r30 in .got2, as given by LCTOC1.
11208 See sysv4.h:toc_section. */
11209 return "bl %z0+32768@plt";
11210 else
11211 return "bl %z0@plt";
11212 }
11213 [(set_attr "type" "branch,branch")
11214 (set_attr "length" "4,8")])
11215
11216 (define_insn "*call_value_indirect_nonlocal_sysv<mode>"
11217 [(set (match_operand 0 "" "")
11218 (call (mem:SI (match_operand:P 1 "register_operand" "c,*l,c,*l"))
11219 (match_operand 2 "" "g,g,g,g")))
11220 (use (match_operand:SI 3 "immediate_operand" "O,O,n,n"))
11221 (clobber (reg:SI LR_REGNO))]
11222 "DEFAULT_ABI == ABI_V4
11223 || DEFAULT_ABI == ABI_DARWIN"
11224 {
11225 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11226 output_asm_insn ("crxor 6,6,6", operands);
11227
11228 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11229 output_asm_insn ("creqv 6,6,6", operands);
11230
11231 return "b%T1l";
11232 }
11233 [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg")
11234 (set_attr "length" "4,4,8,8")])
11235
11236 (define_insn_and_split "*call_value_nonlocal_sysv<mode>"
11237 [(set (match_operand 0 "" "")
11238 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
11239 (match_operand 2 "" "g,g")))
11240 (use (match_operand:SI 3 "immediate_operand" "O,n"))
11241 (clobber (reg:SI LR_REGNO))]
11242 "(DEFAULT_ABI == ABI_DARWIN
11243 || (DEFAULT_ABI == ABI_V4
11244 && (INTVAL (operands[3]) & CALL_LONG) == 0))"
11245 {
11246 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11247 output_asm_insn ("crxor 6,6,6", operands);
11248
11249 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11250 output_asm_insn ("creqv 6,6,6", operands);
11251
11252 #if TARGET_MACHO
11253 return output_call(insn, operands, 1, 3);
11254 #else
11255 if (DEFAULT_ABI == ABI_V4 && flag_pic)
11256 {
11257 gcc_assert (!TARGET_SECURE_PLT);
11258 return "bl %z1@plt";
11259 }
11260 else
11261 return "bl %z1";
11262 #endif
11263 }
11264 "DEFAULT_ABI == ABI_V4
11265 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1])
11266 && (INTVAL (operands[3]) & CALL_LONG) == 0"
11267 [(parallel [(set (match_dup 0)
11268 (call (mem:SI (match_dup 1))
11269 (match_dup 2)))
11270 (use (match_dup 3))
11271 (use (match_dup 4))
11272 (clobber (reg:SI LR_REGNO))])]
11273 {
11274 operands[4] = pic_offset_table_rtx;
11275 }
11276 [(set_attr "type" "branch,branch")
11277 (set_attr "length" "4,8")])
11278
11279 (define_insn "*call_value_nonlocal_sysv_secure<mode>"
11280 [(set (match_operand 0 "" "")
11281 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
11282 (match_operand 2 "" "g,g")))
11283 (use (match_operand:SI 3 "immediate_operand" "O,n"))
11284 (use (match_operand:SI 4 "register_operand" "r,r"))
11285 (clobber (reg:SI LR_REGNO))]
11286 "(DEFAULT_ABI == ABI_V4
11287 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1])
11288 && (INTVAL (operands[3]) & CALL_LONG) == 0)"
11289 {
11290 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11291 output_asm_insn ("crxor 6,6,6", operands);
11292
11293 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11294 output_asm_insn ("creqv 6,6,6", operands);
11295
11296 if (flag_pic == 2)
11297 return "bl %z1+32768@plt";
11298 else
11299 return "bl %z1@plt";
11300 }
11301 [(set_attr "type" "branch,branch")
11302 (set_attr "length" "4,8")])
11303
11304
11305 ;; Call to AIX abi function in the same module.
11306
11307 (define_insn "*call_local_aix<mode>"
11308 [(call (mem:SI (match_operand:P 0 "current_file_function_operand" "s"))
11309 (match_operand 1 "" "g"))
11310 (clobber (reg:P LR_REGNO))]
11311 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11312 "bl %z0"
11313 [(set_attr "type" "branch")
11314 (set_attr "length" "4")])
11315
11316 (define_insn "*call_value_local_aix<mode>"
11317 [(set (match_operand 0 "" "")
11318 (call (mem:SI (match_operand:P 1 "current_file_function_operand" "s"))
11319 (match_operand 2 "" "g")))
11320 (clobber (reg:P LR_REGNO))]
11321 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11322 "bl %z1"
11323 [(set_attr "type" "branch")
11324 (set_attr "length" "4")])
11325
11326 ;; Call to AIX abi function which may be in another module.
11327 ;; Restore the TOC pointer (r2) after the call.
11328
11329 (define_insn "*call_nonlocal_aix<mode>"
11330 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s"))
11331 (match_operand 1 "" "g"))
11332 (clobber (reg:P LR_REGNO))]
11333 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11334 "bl %z0\;nop"
11335 [(set_attr "type" "branch")
11336 (set_attr "length" "8")])
11337
11338 (define_insn "*call_value_nonlocal_aix<mode>"
11339 [(set (match_operand 0 "" "")
11340 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s"))
11341 (match_operand 2 "" "g")))
11342 (clobber (reg:P LR_REGNO))]
11343 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11344 "bl %z1\;nop"
11345 [(set_attr "type" "branch")
11346 (set_attr "length" "8")])
11347
11348 ;; Call to indirect functions with the AIX abi using a 3 word descriptor.
11349 ;; Operand0 is the addresss of the function to call
11350 ;; Operand2 is the location in the function descriptor to load r2 from
11351 ;; Operand3 is the stack location to hold the current TOC pointer
11352
11353 (define_insn "*call_indirect_aix<mode>"
11354 [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
11355 (match_operand 1 "" "g,g"))
11356 (use (match_operand:P 2 "memory_operand" "<ptrm>,<ptrm>"))
11357 (set (reg:P TOC_REGNUM) (match_operand:P 3 "memory_operand" "<ptrm>,<ptrm>"))
11358 (clobber (reg:P LR_REGNO))]
11359 "DEFAULT_ABI == ABI_AIX"
11360 "<ptrload> 2,%2\;b%T0l\;<ptrload> 2,%3"
11361 [(set_attr "type" "jmpreg")
11362 (set_attr "length" "12")])
11363
11364 (define_insn "*call_value_indirect_aix<mode>"
11365 [(set (match_operand 0 "" "")
11366 (call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
11367 (match_operand 2 "" "g,g")))
11368 (use (match_operand:P 3 "memory_operand" "<ptrm>,<ptrm>"))
11369 (set (reg:P TOC_REGNUM) (match_operand:P 4 "memory_operand" "<ptrm>,<ptrm>"))
11370 (clobber (reg:P LR_REGNO))]
11371 "DEFAULT_ABI == ABI_AIX"
11372 "<ptrload> 2,%3\;b%T1l\;<ptrload> 2,%4"
11373 [(set_attr "type" "jmpreg")
11374 (set_attr "length" "12")])
11375
11376 ;; Call to indirect functions with the ELFv2 ABI.
11377 ;; Operand0 is the addresss of the function to call
11378 ;; Operand2 is the stack location to hold the current TOC pointer
11379
11380 (define_insn "*call_indirect_elfv2<mode>"
11381 [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
11382 (match_operand 1 "" "g,g"))
11383 (set (reg:P TOC_REGNUM) (match_operand:P 2 "memory_operand" "<ptrm>,<ptrm>"))
11384 (clobber (reg:P LR_REGNO))]
11385 "DEFAULT_ABI == ABI_ELFv2"
11386 "b%T0l\;<ptrload> 2,%2"
11387 [(set_attr "type" "jmpreg")
11388 (set_attr "length" "8")])
11389
11390 (define_insn "*call_value_indirect_elfv2<mode>"
11391 [(set (match_operand 0 "" "")
11392 (call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
11393 (match_operand 2 "" "g,g")))
11394 (set (reg:P TOC_REGNUM) (match_operand:P 3 "memory_operand" "<ptrm>,<ptrm>"))
11395 (clobber (reg:P LR_REGNO))]
11396 "DEFAULT_ABI == ABI_ELFv2"
11397 "b%T1l\;<ptrload> 2,%3"
11398 [(set_attr "type" "jmpreg")
11399 (set_attr "length" "8")])
11400
11401
11402 ;; Call subroutine returning any type.
11403 (define_expand "untyped_call"
11404 [(parallel [(call (match_operand 0 "" "")
11405 (const_int 0))
11406 (match_operand 1 "" "")
11407 (match_operand 2 "" "")])]
11408 ""
11409 "
11410 {
11411 int i;
11412
11413 emit_call_insn (GEN_CALL (operands[0], const0_rtx, const0_rtx, const0_rtx));
11414
11415 for (i = 0; i < XVECLEN (operands[2], 0); i++)
11416 {
11417 rtx set = XVECEXP (operands[2], 0, i);
11418 emit_move_insn (SET_DEST (set), SET_SRC (set));
11419 }
11420
11421 /* The optimizer does not know that the call sets the function value
11422 registers we stored in the result block. We avoid problems by
11423 claiming that all hard registers are used and clobbered at this
11424 point. */
11425 emit_insn (gen_blockage ());
11426
11427 DONE;
11428 }")
11429
11430 ;; sibling call patterns
11431 (define_expand "sibcall"
11432 [(parallel [(call (mem:SI (match_operand 0 "address_operand" ""))
11433 (match_operand 1 "" ""))
11434 (use (match_operand 2 "" ""))
11435 (use (reg:SI LR_REGNO))
11436 (simple_return)])]
11437 ""
11438 "
11439 {
11440 #if TARGET_MACHO
11441 if (MACHOPIC_INDIRECT)
11442 operands[0] = machopic_indirect_call_target (operands[0]);
11443 #endif
11444
11445 gcc_assert (GET_CODE (operands[0]) == MEM);
11446 gcc_assert (GET_CODE (operands[1]) == CONST_INT);
11447
11448 operands[0] = XEXP (operands[0], 0);
11449
11450 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
11451 {
11452 rs6000_sibcall_aix (NULL_RTX, operands[0], operands[1], operands[2]);
11453 DONE;
11454 }
11455 }")
11456
11457 (define_expand "sibcall_value"
11458 [(parallel [(set (match_operand 0 "register_operand" "")
11459 (call (mem:SI (match_operand 1 "address_operand" ""))
11460 (match_operand 2 "" "")))
11461 (use (match_operand 3 "" ""))
11462 (use (reg:SI LR_REGNO))
11463 (simple_return)])]
11464 ""
11465 "
11466 {
11467 #if TARGET_MACHO
11468 if (MACHOPIC_INDIRECT)
11469 operands[1] = machopic_indirect_call_target (operands[1]);
11470 #endif
11471
11472 gcc_assert (GET_CODE (operands[1]) == MEM);
11473 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
11474
11475 operands[1] = XEXP (operands[1], 0);
11476
11477 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
11478 {
11479 rs6000_sibcall_aix (operands[0], operands[1], operands[2], operands[3]);
11480 DONE;
11481 }
11482 }")
11483
11484 ;; this and similar patterns must be marked as using LR, otherwise
11485 ;; dataflow will try to delete the store into it. This is true
11486 ;; even when the actual reg to jump to is in CTR, when LR was
11487 ;; saved and restored around the PIC-setting BCL.
11488 (define_insn "*sibcall_local32"
11489 [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
11490 (match_operand 1 "" "g,g"))
11491 (use (match_operand:SI 2 "immediate_operand" "O,n"))
11492 (use (reg:SI LR_REGNO))
11493 (simple_return)]
11494 "(INTVAL (operands[2]) & CALL_LONG) == 0"
11495 "*
11496 {
11497 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
11498 output_asm_insn (\"crxor 6,6,6\", operands);
11499
11500 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
11501 output_asm_insn (\"creqv 6,6,6\", operands);
11502
11503 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z0@local\" : \"b %z0\";
11504 }"
11505 [(set_attr "type" "branch")
11506 (set_attr "length" "4,8")])
11507
11508 (define_insn "*sibcall_local64"
11509 [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
11510 (match_operand 1 "" "g,g"))
11511 (use (match_operand:SI 2 "immediate_operand" "O,n"))
11512 (use (reg:SI LR_REGNO))
11513 (simple_return)]
11514 "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
11515 "*
11516 {
11517 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
11518 output_asm_insn (\"crxor 6,6,6\", operands);
11519
11520 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
11521 output_asm_insn (\"creqv 6,6,6\", operands);
11522
11523 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z0@local\" : \"b %z0\";
11524 }"
11525 [(set_attr "type" "branch")
11526 (set_attr "length" "4,8")])
11527
11528 (define_insn "*sibcall_value_local32"
11529 [(set (match_operand 0 "" "")
11530 (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
11531 (match_operand 2 "" "g,g")))
11532 (use (match_operand:SI 3 "immediate_operand" "O,n"))
11533 (use (reg:SI LR_REGNO))
11534 (simple_return)]
11535 "(INTVAL (operands[3]) & CALL_LONG) == 0"
11536 "*
11537 {
11538 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11539 output_asm_insn (\"crxor 6,6,6\", operands);
11540
11541 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11542 output_asm_insn (\"creqv 6,6,6\", operands);
11543
11544 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z1@local\" : \"b %z1\";
11545 }"
11546 [(set_attr "type" "branch")
11547 (set_attr "length" "4,8")])
11548
11549 (define_insn "*sibcall_value_local64"
11550 [(set (match_operand 0 "" "")
11551 (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
11552 (match_operand 2 "" "g,g")))
11553 (use (match_operand:SI 3 "immediate_operand" "O,n"))
11554 (use (reg:SI LR_REGNO))
11555 (simple_return)]
11556 "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
11557 "*
11558 {
11559 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11560 output_asm_insn (\"crxor 6,6,6\", operands);
11561
11562 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11563 output_asm_insn (\"creqv 6,6,6\", operands);
11564
11565 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z1@local\" : \"b %z1\";
11566 }"
11567 [(set_attr "type" "branch")
11568 (set_attr "length" "4,8")])
11569
11570 (define_insn "*sibcall_nonlocal_sysv<mode>"
11571 [(call (mem:SI (match_operand:P 0 "call_operand" "s,s,c,c"))
11572 (match_operand 1 "" ""))
11573 (use (match_operand 2 "immediate_operand" "O,n,O,n"))
11574 (use (reg:SI LR_REGNO))
11575 (simple_return)]
11576 "(DEFAULT_ABI == ABI_DARWIN
11577 || DEFAULT_ABI == ABI_V4)
11578 && (INTVAL (operands[2]) & CALL_LONG) == 0"
11579 "*
11580 {
11581 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
11582 output_asm_insn (\"crxor 6,6,6\", operands);
11583
11584 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
11585 output_asm_insn (\"creqv 6,6,6\", operands);
11586
11587 if (which_alternative >= 2)
11588 return \"b%T0\";
11589 else if (DEFAULT_ABI == ABI_V4 && flag_pic)
11590 {
11591 gcc_assert (!TARGET_SECURE_PLT);
11592 return \"b %z0@plt\";
11593 }
11594 else
11595 return \"b %z0\";
11596 }"
11597 [(set_attr "type" "branch")
11598 (set_attr "length" "4,8,4,8")])
11599
11600 (define_insn "*sibcall_value_nonlocal_sysv<mode>"
11601 [(set (match_operand 0 "" "")
11602 (call (mem:SI (match_operand:P 1 "call_operand" "s,s,c,c"))
11603 (match_operand 2 "" "")))
11604 (use (match_operand:SI 3 "immediate_operand" "O,n,O,n"))
11605 (use (reg:SI LR_REGNO))
11606 (simple_return)]
11607 "(DEFAULT_ABI == ABI_DARWIN
11608 || DEFAULT_ABI == ABI_V4)
11609 && (INTVAL (operands[3]) & CALL_LONG) == 0"
11610 "*
11611 {
11612 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11613 output_asm_insn (\"crxor 6,6,6\", operands);
11614
11615 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11616 output_asm_insn (\"creqv 6,6,6\", operands);
11617
11618 if (which_alternative >= 2)
11619 return \"b%T1\";
11620 else if (DEFAULT_ABI == ABI_V4 && flag_pic)
11621 {
11622 gcc_assert (!TARGET_SECURE_PLT);
11623 return \"b %z1@plt\";
11624 }
11625 else
11626 return \"b %z1\";
11627 }"
11628 [(set_attr "type" "branch")
11629 (set_attr "length" "4,8,4,8")])
11630
11631 ;; AIX ABI sibling call patterns.
11632
11633 (define_insn "*sibcall_aix<mode>"
11634 [(call (mem:SI (match_operand:P 0 "call_operand" "s,c"))
11635 (match_operand 1 "" "g,g"))
11636 (simple_return)]
11637 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11638 "@
11639 b %z0
11640 b%T0"
11641 [(set_attr "type" "branch")
11642 (set_attr "length" "4")])
11643
11644 (define_insn "*sibcall_value_aix<mode>"
11645 [(set (match_operand 0 "" "")
11646 (call (mem:SI (match_operand:P 1 "call_operand" "s,c"))
11647 (match_operand 2 "" "g,g")))
11648 (simple_return)]
11649 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11650 "@
11651 b %z1
11652 b%T1"
11653 [(set_attr "type" "branch")
11654 (set_attr "length" "4")])
11655
11656 (define_expand "sibcall_epilogue"
11657 [(use (const_int 0))]
11658 ""
11659 {
11660 if (!TARGET_SCHED_PROLOG)
11661 emit_insn (gen_blockage ());
11662 rs6000_emit_epilogue (TRUE);
11663 DONE;
11664 })
11665
11666 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11667 ;; all of memory. This blocks insns from being moved across this point.
11668
11669 (define_insn "blockage"
11670 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCK)]
11671 ""
11672 "")
11673
11674 (define_expand "probe_stack"
11675 [(set (match_operand 0 "memory_operand" "=m")
11676 (unspec [(const_int 0)] UNSPEC_PROBE_STACK))]
11677 ""
11678 {
11679 if (TARGET_64BIT)
11680 emit_insn (gen_probe_stack_di (operands[0]));
11681 else
11682 emit_insn (gen_probe_stack_si (operands[0]));
11683 DONE;
11684 })
11685
11686 (define_insn "probe_stack_<mode>"
11687 [(set (match_operand:P 0 "memory_operand" "=m")
11688 (unspec:P [(const_int 0)] UNSPEC_PROBE_STACK))]
11689 ""
11690 {
11691 operands[1] = gen_rtx_REG (Pmode, 0);
11692 return "st<wd>%U0%X0 %1,%0";
11693 }
11694 [(set_attr "type" "store")
11695 (set (attr "update")
11696 (if_then_else (match_operand 0 "update_address_mem")
11697 (const_string "yes")
11698 (const_string "no")))
11699 (set (attr "indexed")
11700 (if_then_else (match_operand 0 "indexed_address_mem")
11701 (const_string "yes")
11702 (const_string "no")))
11703 (set_attr "length" "4")])
11704
11705 (define_insn "probe_stack_range<P:mode>"
11706 [(set (match_operand:P 0 "register_operand" "=r")
11707 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
11708 (match_operand:P 2 "register_operand" "r")]
11709 UNSPECV_PROBE_STACK_RANGE))]
11710 ""
11711 "* return output_probe_stack_range (operands[0], operands[2]);"
11712 [(set_attr "type" "three")])
11713 \f
11714 ;; Compare insns are next. Note that the RS/6000 has two types of compares,
11715 ;; signed & unsigned, and one type of branch.
11716 ;;
11717 ;; Start with the DEFINE_EXPANDs to generate the rtl for compares, scc
11718 ;; insns, and branches.
11719
11720 (define_expand "cbranch<mode>4"
11721 [(use (match_operator 0 "rs6000_cbranch_operator"
11722 [(match_operand:GPR 1 "gpc_reg_operand" "")
11723 (match_operand:GPR 2 "reg_or_short_operand" "")]))
11724 (use (match_operand 3 ""))]
11725 ""
11726 "
11727 {
11728 /* Take care of the possibility that operands[2] might be negative but
11729 this might be a logical operation. That insn doesn't exist. */
11730 if (GET_CODE (operands[2]) == CONST_INT
11731 && INTVAL (operands[2]) < 0)
11732 {
11733 operands[2] = force_reg (<MODE>mode, operands[2]);
11734 operands[0] = gen_rtx_fmt_ee (GET_CODE (operands[0]),
11735 GET_MODE (operands[0]),
11736 operands[1], operands[2]);
11737 }
11738
11739 rs6000_emit_cbranch (<MODE>mode, operands);
11740 DONE;
11741 }")
11742
11743 (define_expand "cbranch<mode>4"
11744 [(use (match_operator 0 "rs6000_cbranch_operator"
11745 [(match_operand:FP 1 "gpc_reg_operand" "")
11746 (match_operand:FP 2 "gpc_reg_operand" "")]))
11747 (use (match_operand 3 ""))]
11748 ""
11749 "
11750 {
11751 rs6000_emit_cbranch (<MODE>mode, operands);
11752 DONE;
11753 }")
11754
11755 (define_expand "cstore<mode>4_unsigned"
11756 [(use (match_operator 1 "unsigned_comparison_operator"
11757 [(match_operand:P 2 "gpc_reg_operand" "")
11758 (match_operand:P 3 "reg_or_short_operand" "")]))
11759 (clobber (match_operand:P 0 "register_operand"))]
11760 ""
11761 {
11762 enum rtx_code cond_code = GET_CODE (operands[1]);
11763
11764 rtx op0 = operands[0];
11765 rtx op1 = operands[2];
11766 rtx op2 = operands[3];
11767
11768 if (cond_code == GEU || cond_code == LTU)
11769 {
11770 cond_code = swap_condition (cond_code);
11771 op1 = operands[3];
11772 op2 = operands[2];
11773 }
11774
11775 if (!gpc_reg_operand (op1, <MODE>mode))
11776 op1 = force_reg (<MODE>mode, op1);
11777 if (!reg_or_short_operand (op2, <MODE>mode))
11778 op2 = force_reg (<MODE>mode, op2);
11779
11780 rtx tmp = gen_reg_rtx (<MODE>mode);
11781 rtx tmp2 = gen_reg_rtx (<MODE>mode);
11782
11783 emit_insn (gen_subf<mode>3_carry (tmp, op1, op2));
11784 emit_insn (gen_subf<mode>3_carry_in_xx (tmp2));
11785
11786 if (cond_code == LEU)
11787 emit_insn (gen_add<mode>3 (op0, tmp2, const1_rtx));
11788 else
11789 emit_insn (gen_neg<mode>2 (op0, tmp2));
11790
11791 DONE;
11792 })
11793
11794 (define_expand "cstore<mode>4"
11795 [(use (match_operator 1 "rs6000_cbranch_operator"
11796 [(match_operand:GPR 2 "gpc_reg_operand" "")
11797 (match_operand:GPR 3 "reg_or_short_operand" "")]))
11798 (clobber (match_operand:GPR 0 "register_operand"))]
11799 ""
11800 {
11801 /* Use ISEL if the user asked for it. */
11802 if (TARGET_ISEL)
11803 rs6000_emit_sISEL (<MODE>mode, operands);
11804
11805 /* Expanding EQ and NE directly to some machine instructions does not help
11806 but does hurt combine. So don't. */
11807 else if (GET_CODE (operands[1]) == EQ)
11808 emit_insn (gen_eq<mode>3 (operands[0], operands[2], operands[3]));
11809 else if (<MODE>mode == Pmode
11810 && GET_CODE (operands[1]) == NE)
11811 emit_insn (gen_ne<mode>3 (operands[0], operands[2], operands[3]));
11812 else if (GET_CODE (operands[1]) == NE)
11813 {
11814 rtx tmp = gen_reg_rtx (<MODE>mode);
11815 emit_insn (gen_eq<mode>3 (tmp, operands[2], operands[3]));
11816 emit_insn (gen_xor<mode>3 (operands[0], tmp, const1_rtx));
11817 }
11818
11819 /* Expanding the unsigned comparisons however helps a lot: all the neg_ltu
11820 etc. combinations magically work out just right. */
11821 else if (<MODE>mode == Pmode
11822 && unsigned_comparison_operator (operands[1], VOIDmode))
11823 emit_insn (gen_cstore<mode>4_unsigned (operands[0], operands[1],
11824 operands[2], operands[3]));
11825
11826 /* The generic code knows tricks to compute signed comparisons against
11827 zero. Let it do its thing. */
11828 else if (operands[3] == const0_rtx
11829 && signed_comparison_operator (operands[1], VOIDmode))
11830 FAIL;
11831
11832 /* Everything else, use the mfcr brute force. */
11833 else
11834 rs6000_emit_sCOND (<MODE>mode, operands);
11835
11836 DONE;
11837 })
11838
11839 (define_expand "cstore<mode>4"
11840 [(use (match_operator 1 "rs6000_cbranch_operator"
11841 [(match_operand:FP 2 "gpc_reg_operand" "")
11842 (match_operand:FP 3 "gpc_reg_operand" "")]))
11843 (clobber (match_operand:SI 0 "register_operand"))]
11844 ""
11845 {
11846 rs6000_emit_sCOND (<MODE>mode, operands);
11847 DONE;
11848 })
11849
11850
11851 (define_expand "stack_protect_set"
11852 [(match_operand 0 "memory_operand" "")
11853 (match_operand 1 "memory_operand" "")]
11854 ""
11855 {
11856 #ifdef TARGET_THREAD_SSP_OFFSET
11857 rtx tlsreg = gen_rtx_REG (Pmode, TARGET_64BIT ? 13 : 2);
11858 rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
11859 operands[1] = gen_rtx_MEM (Pmode, addr);
11860 #endif
11861 if (TARGET_64BIT)
11862 emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
11863 else
11864 emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
11865 DONE;
11866 })
11867
11868 (define_insn "stack_protect_setsi"
11869 [(set (match_operand:SI 0 "memory_operand" "=m")
11870 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
11871 (set (match_scratch:SI 2 "=&r") (const_int 0))]
11872 "TARGET_32BIT"
11873 "lwz%U1%X1 %2,%1\;stw%U0%X0 %2,%0\;li %2,0"
11874 [(set_attr "type" "three")
11875 (set_attr "length" "12")])
11876
11877 (define_insn "stack_protect_setdi"
11878 [(set (match_operand:DI 0 "memory_operand" "=Y")
11879 (unspec:DI [(match_operand:DI 1 "memory_operand" "Y")] UNSPEC_SP_SET))
11880 (set (match_scratch:DI 2 "=&r") (const_int 0))]
11881 "TARGET_64BIT"
11882 "ld%U1%X1 %2,%1\;std%U0%X0 %2,%0\;li %2,0"
11883 [(set_attr "type" "three")
11884 (set_attr "length" "12")])
11885
11886 (define_expand "stack_protect_test"
11887 [(match_operand 0 "memory_operand" "")
11888 (match_operand 1 "memory_operand" "")
11889 (match_operand 2 "" "")]
11890 ""
11891 {
11892 rtx test, op0, op1;
11893 #ifdef TARGET_THREAD_SSP_OFFSET
11894 rtx tlsreg = gen_rtx_REG (Pmode, TARGET_64BIT ? 13 : 2);
11895 rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
11896 operands[1] = gen_rtx_MEM (Pmode, addr);
11897 #endif
11898 op0 = operands[0];
11899 op1 = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, operands[1]), UNSPEC_SP_TEST);
11900 test = gen_rtx_EQ (VOIDmode, op0, op1);
11901 emit_jump_insn (gen_cbranchsi4 (test, op0, op1, operands[2]));
11902 DONE;
11903 })
11904
11905 (define_insn "stack_protect_testsi"
11906 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
11907 (unspec:CCEQ [(match_operand:SI 1 "memory_operand" "m,m")
11908 (match_operand:SI 2 "memory_operand" "m,m")]
11909 UNSPEC_SP_TEST))
11910 (set (match_scratch:SI 4 "=r,r") (const_int 0))
11911 (clobber (match_scratch:SI 3 "=&r,&r"))]
11912 "TARGET_32BIT"
11913 "@
11914 lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0
11915 lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;cmplw %0,%3,%4\;li %3,0\;li %4,0"
11916 [(set_attr "length" "16,20")])
11917
11918 (define_insn "stack_protect_testdi"
11919 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
11920 (unspec:CCEQ [(match_operand:DI 1 "memory_operand" "Y,Y")
11921 (match_operand:DI 2 "memory_operand" "Y,Y")]
11922 UNSPEC_SP_TEST))
11923 (set (match_scratch:DI 4 "=r,r") (const_int 0))
11924 (clobber (match_scratch:DI 3 "=&r,&r"))]
11925 "TARGET_64BIT"
11926 "@
11927 ld%U1%X1 %3,%1\;ld%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0
11928 ld%U1%X1 %3,%1\;ld%U2%X2 %4,%2\;cmpld %0,%3,%4\;li %3,0\;li %4,0"
11929 [(set_attr "length" "16,20")])
11930
11931 \f
11932 ;; Here are the actual compare insns.
11933 (define_insn "*cmp<mode>_internal1"
11934 [(set (match_operand:CC 0 "cc_reg_operand" "=y")
11935 (compare:CC (match_operand:GPR 1 "gpc_reg_operand" "r")
11936 (match_operand:GPR 2 "reg_or_short_operand" "rI")))]
11937 ""
11938 "cmp<wd>%I2 %0,%1,%2"
11939 [(set_attr "type" "cmp")])
11940
11941 ;; If we are comparing a register for equality with a large constant,
11942 ;; we can do this with an XOR followed by a compare. But this is profitable
11943 ;; only if the large constant is only used for the comparison (and in this
11944 ;; case we already have a register to reuse as scratch).
11945 ;;
11946 ;; For 64-bit registers, we could only do so if the constant's bit 15 is clear:
11947 ;; otherwise we'd need to XOR with FFFFFFFF????0000 which is not available.
11948
11949 (define_peephole2
11950 [(set (match_operand:SI 0 "register_operand")
11951 (match_operand:SI 1 "logical_const_operand" ""))
11952 (set (match_dup 0) (match_operator:SI 3 "boolean_or_operator"
11953 [(match_dup 0)
11954 (match_operand:SI 2 "logical_const_operand" "")]))
11955 (set (match_operand:CC 4 "cc_reg_operand" "")
11956 (compare:CC (match_operand:SI 5 "gpc_reg_operand" "")
11957 (match_dup 0)))
11958 (set (pc)
11959 (if_then_else (match_operator 6 "equality_operator"
11960 [(match_dup 4) (const_int 0)])
11961 (match_operand 7 "" "")
11962 (match_operand 8 "" "")))]
11963 "peep2_reg_dead_p (3, operands[0])
11964 && peep2_reg_dead_p (4, operands[4])"
11965 [(set (match_dup 0) (xor:SI (match_dup 5) (match_dup 9)))
11966 (set (match_dup 4) (compare:CC (match_dup 0) (match_dup 10)))
11967 (set (pc) (if_then_else (match_dup 6) (match_dup 7) (match_dup 8)))]
11968
11969 {
11970 /* Get the constant we are comparing against, and see what it looks like
11971 when sign-extended from 16 to 32 bits. Then see what constant we could
11972 XOR with SEXTC to get the sign-extended value. */
11973 rtx cnst = simplify_const_binary_operation (GET_CODE (operands[3]),
11974 SImode,
11975 operands[1], operands[2]);
11976 HOST_WIDE_INT c = INTVAL (cnst);
11977 HOST_WIDE_INT sextc = ((c & 0xffff) ^ 0x8000) - 0x8000;
11978 HOST_WIDE_INT xorv = c ^ sextc;
11979
11980 operands[9] = GEN_INT (xorv);
11981 operands[10] = GEN_INT (sextc);
11982 })
11983
11984 (define_insn "*cmpsi_internal2"
11985 [(set (match_operand:CCUNS 0 "cc_reg_operand" "=y")
11986 (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "r")
11987 (match_operand:SI 2 "reg_or_u_short_operand" "rK")))]
11988 ""
11989 "cmplw%I2 %0,%1,%b2"
11990 [(set_attr "type" "cmp")])
11991
11992 (define_insn "*cmpdi_internal2"
11993 [(set (match_operand:CCUNS 0 "cc_reg_operand" "=y")
11994 (compare:CCUNS (match_operand:DI 1 "gpc_reg_operand" "r")
11995 (match_operand:DI 2 "reg_or_u_short_operand" "rK")))]
11996 ""
11997 "cmpld%I2 %0,%1,%b2"
11998 [(set_attr "type" "cmp")])
11999
12000 ;; The following two insns don't exist as single insns, but if we provide
12001 ;; them, we can swap an add and compare, which will enable us to overlap more
12002 ;; of the required delay between a compare and branch. We generate code for
12003 ;; them by splitting.
12004
12005 (define_insn ""
12006 [(set (match_operand:CC 3 "cc_reg_operand" "=y")
12007 (compare:CC (match_operand:SI 1 "gpc_reg_operand" "r")
12008 (match_operand:SI 2 "short_cint_operand" "i")))
12009 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
12010 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "i")))]
12011 ""
12012 "#"
12013 [(set_attr "length" "8")])
12014
12015 (define_insn ""
12016 [(set (match_operand:CCUNS 3 "cc_reg_operand" "=y")
12017 (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "r")
12018 (match_operand:SI 2 "u_short_cint_operand" "i")))
12019 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
12020 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "i")))]
12021 ""
12022 "#"
12023 [(set_attr "length" "8")])
12024
12025 (define_split
12026 [(set (match_operand:CC 3 "cc_reg_operand" "")
12027 (compare:CC (match_operand:SI 1 "gpc_reg_operand" "")
12028 (match_operand:SI 2 "short_cint_operand" "")))
12029 (set (match_operand:SI 0 "gpc_reg_operand" "")
12030 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "")))]
12031 ""
12032 [(set (match_dup 3) (compare:CC (match_dup 1) (match_dup 2)))
12033 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 4)))])
12034
12035 (define_split
12036 [(set (match_operand:CCUNS 3 "cc_reg_operand" "")
12037 (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "")
12038 (match_operand:SI 2 "u_short_cint_operand" "")))
12039 (set (match_operand:SI 0 "gpc_reg_operand" "")
12040 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "")))]
12041 ""
12042 [(set (match_dup 3) (compare:CCUNS (match_dup 1) (match_dup 2)))
12043 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 4)))])
12044
12045 ;; Only need to compare second words if first words equal
12046 (define_insn "*cmptf_internal1"
12047 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
12048 (compare:CCFP (match_operand:TF 1 "gpc_reg_operand" "d")
12049 (match_operand:TF 2 "gpc_reg_operand" "d")))]
12050 "!TARGET_IEEEQUAD && !TARGET_XL_COMPAT
12051 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
12052 "fcmpu %0,%1,%2\;bne %0,$+8\;fcmpu %0,%L1,%L2"
12053 [(set_attr "type" "fpcompare")
12054 (set_attr "length" "12")])
12055
12056 (define_insn_and_split "*cmptf_internal2"
12057 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
12058 (compare:CCFP (match_operand:TF 1 "gpc_reg_operand" "d")
12059 (match_operand:TF 2 "gpc_reg_operand" "d")))
12060 (clobber (match_scratch:DF 3 "=d"))
12061 (clobber (match_scratch:DF 4 "=d"))
12062 (clobber (match_scratch:DF 5 "=d"))
12063 (clobber (match_scratch:DF 6 "=d"))
12064 (clobber (match_scratch:DF 7 "=d"))
12065 (clobber (match_scratch:DF 8 "=d"))
12066 (clobber (match_scratch:DF 9 "=d"))
12067 (clobber (match_scratch:DF 10 "=d"))
12068 (clobber (match_scratch:GPR 11 "=b"))]
12069 "!TARGET_IEEEQUAD && TARGET_XL_COMPAT
12070 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
12071 "#"
12072 "&& reload_completed"
12073 [(set (match_dup 3) (match_dup 14))
12074 (set (match_dup 4) (match_dup 15))
12075 (set (match_dup 9) (abs:DF (match_dup 5)))
12076 (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 3)))
12077 (set (pc) (if_then_else (ne (match_dup 0) (const_int 0))
12078 (label_ref (match_dup 12))
12079 (pc)))
12080 (set (match_dup 0) (compare:CCFP (match_dup 5) (match_dup 7)))
12081 (set (pc) (label_ref (match_dup 13)))
12082 (match_dup 12)
12083 (set (match_dup 10) (minus:DF (match_dup 5) (match_dup 7)))
12084 (set (match_dup 9) (minus:DF (match_dup 6) (match_dup 8)))
12085 (set (match_dup 9) (plus:DF (match_dup 10) (match_dup 9)))
12086 (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 4)))
12087 (match_dup 13)]
12088 {
12089 REAL_VALUE_TYPE rv;
12090 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
12091 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
12092
12093 operands[5] = simplify_gen_subreg (DFmode, operands[1], TFmode, hi_word);
12094 operands[6] = simplify_gen_subreg (DFmode, operands[1], TFmode, lo_word);
12095 operands[7] = simplify_gen_subreg (DFmode, operands[2], TFmode, hi_word);
12096 operands[8] = simplify_gen_subreg (DFmode, operands[2], TFmode, lo_word);
12097 operands[12] = gen_label_rtx ();
12098 operands[13] = gen_label_rtx ();
12099 real_inf (&rv);
12100 operands[14] = force_const_mem (DFmode,
12101 CONST_DOUBLE_FROM_REAL_VALUE (rv, DFmode));
12102 operands[15] = force_const_mem (DFmode,
12103 CONST_DOUBLE_FROM_REAL_VALUE (dconst0,
12104 DFmode));
12105 if (TARGET_TOC)
12106 {
12107 rtx tocref;
12108 tocref = create_TOC_reference (XEXP (operands[14], 0), operands[11]);
12109 operands[14] = gen_const_mem (DFmode, tocref);
12110 tocref = create_TOC_reference (XEXP (operands[15], 0), operands[11]);
12111 operands[15] = gen_const_mem (DFmode, tocref);
12112 set_mem_alias_set (operands[14], get_TOC_alias_set ());
12113 set_mem_alias_set (operands[15], get_TOC_alias_set ());
12114 }
12115 })
12116 \f
12117 ;; Now we have the scc insns. We can do some combinations because of the
12118 ;; way the machine works.
12119 ;;
12120 ;; Note that this is probably faster if we can put an insn between the
12121 ;; mfcr and rlinm, but this is tricky. Let's leave it for now. In most
12122 ;; cases the insns below which don't use an intermediate CR field will
12123 ;; be used instead.
12124 (define_insn ""
12125 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
12126 (match_operator:SI 1 "scc_comparison_operator"
12127 [(match_operand 2 "cc_reg_operand" "y")
12128 (const_int 0)]))]
12129 ""
12130 "mfcr %0%Q2\;rlwinm %0,%0,%J1,1"
12131 [(set (attr "type")
12132 (cond [(match_test "TARGET_MFCRF")
12133 (const_string "mfcrf")
12134 ]
12135 (const_string "mfcr")))
12136 (set_attr "length" "8")])
12137
12138 ;; Same as above, but get the GT bit.
12139 (define_insn "move_from_CR_gt_bit"
12140 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
12141 (unspec:SI [(match_operand 1 "cc_reg_operand" "y")] UNSPEC_MV_CR_GT))]
12142 "TARGET_HARD_FLOAT && !TARGET_FPRS"
12143 "mfcr %0\;rlwinm %0,%0,%D1,31,31"
12144 [(set_attr "type" "mfcr")
12145 (set_attr "length" "8")])
12146
12147 ;; Same as above, but get the OV/ORDERED bit.
12148 (define_insn "move_from_CR_ov_bit"
12149 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
12150 (unspec:SI [(match_operand:CC 1 "cc_reg_operand" "y")]
12151 UNSPEC_MV_CR_OV))]
12152 "TARGET_ISEL"
12153 "mfcr %0\;rlwinm %0,%0,%t1,1"
12154 [(set_attr "type" "mfcr")
12155 (set_attr "length" "8")])
12156
12157 (define_insn ""
12158 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
12159 (match_operator:DI 1 "scc_comparison_operator"
12160 [(match_operand 2 "cc_reg_operand" "y")
12161 (const_int 0)]))]
12162 "TARGET_POWERPC64"
12163 "mfcr %0%Q2\;rlwinm %0,%0,%J1,1"
12164 [(set (attr "type")
12165 (cond [(match_test "TARGET_MFCRF")
12166 (const_string "mfcrf")
12167 ]
12168 (const_string "mfcr")))
12169 (set_attr "length" "8")])
12170
12171 (define_insn ""
12172 [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
12173 (compare:CC (match_operator:SI 1 "scc_comparison_operator"
12174 [(match_operand 2 "cc_reg_operand" "y,y")
12175 (const_int 0)])
12176 (const_int 0)))
12177 (set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
12178 (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
12179 "TARGET_32BIT"
12180 "@
12181 mfcr %3%Q2\;rlwinm. %3,%3,%J1,1
12182 #"
12183 [(set_attr "type" "shift")
12184 (set_attr "dot" "yes")
12185 (set_attr "length" "8,16")])
12186
12187 (define_split
12188 [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
12189 (compare:CC (match_operator:SI 1 "scc_comparison_operator"
12190 [(match_operand 2 "cc_reg_operand" "")
12191 (const_int 0)])
12192 (const_int 0)))
12193 (set (match_operand:SI 3 "gpc_reg_operand" "")
12194 (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
12195 "TARGET_32BIT && reload_completed"
12196 [(set (match_dup 3)
12197 (match_op_dup 1 [(match_dup 2) (const_int 0)]))
12198 (set (match_dup 0)
12199 (compare:CC (match_dup 3)
12200 (const_int 0)))]
12201 "")
12202
12203 (define_insn ""
12204 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
12205 (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
12206 [(match_operand 2 "cc_reg_operand" "y")
12207 (const_int 0)])
12208 (match_operand:SI 3 "const_int_operand" "n")))]
12209 ""
12210 "*
12211 {
12212 int is_bit = ccr_bit (operands[1], 1);
12213 int put_bit = 31 - (INTVAL (operands[3]) & 31);
12214 int count;
12215
12216 if (is_bit >= put_bit)
12217 count = is_bit - put_bit;
12218 else
12219 count = 32 - (put_bit - is_bit);
12220
12221 operands[4] = GEN_INT (count);
12222 operands[5] = GEN_INT (put_bit);
12223
12224 return \"mfcr %0%Q2\;rlwinm %0,%0,%4,%5,%5\";
12225 }"
12226 [(set (attr "type")
12227 (cond [(match_test "TARGET_MFCRF")
12228 (const_string "mfcrf")
12229 ]
12230 (const_string "mfcr")))
12231 (set_attr "length" "8")])
12232
12233 (define_insn ""
12234 [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
12235 (compare:CC
12236 (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
12237 [(match_operand 2 "cc_reg_operand" "y,y")
12238 (const_int 0)])
12239 (match_operand:SI 3 "const_int_operand" "n,n"))
12240 (const_int 0)))
12241 (set (match_operand:SI 4 "gpc_reg_operand" "=r,r")
12242 (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
12243 (match_dup 3)))]
12244 ""
12245 "*
12246 {
12247 int is_bit = ccr_bit (operands[1], 1);
12248 int put_bit = 31 - (INTVAL (operands[3]) & 31);
12249 int count;
12250
12251 /* Force split for non-cc0 compare. */
12252 if (which_alternative == 1)
12253 return \"#\";
12254
12255 if (is_bit >= put_bit)
12256 count = is_bit - put_bit;
12257 else
12258 count = 32 - (put_bit - is_bit);
12259
12260 operands[5] = GEN_INT (count);
12261 operands[6] = GEN_INT (put_bit);
12262
12263 return \"mfcr %4%Q2\;rlwinm. %4,%4,%5,%6,%6\";
12264 }"
12265 [(set_attr "type" "shift")
12266 (set_attr "dot" "yes")
12267 (set_attr "length" "8,16")])
12268
12269 (define_split
12270 [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
12271 (compare:CC
12272 (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
12273 [(match_operand 2 "cc_reg_operand" "")
12274 (const_int 0)])
12275 (match_operand:SI 3 "const_int_operand" ""))
12276 (const_int 0)))
12277 (set (match_operand:SI 4 "gpc_reg_operand" "")
12278 (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
12279 (match_dup 3)))]
12280 "reload_completed"
12281 [(set (match_dup 4)
12282 (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
12283 (match_dup 3)))
12284 (set (match_dup 0)
12285 (compare:CC (match_dup 4)
12286 (const_int 0)))]
12287 "")
12288
12289 ;; There is a 3 cycle delay between consecutive mfcr instructions
12290 ;; so it is useful to combine 2 scc instructions to use only one mfcr.
12291
12292 (define_peephole
12293 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
12294 (match_operator:SI 1 "scc_comparison_operator"
12295 [(match_operand 2 "cc_reg_operand" "y")
12296 (const_int 0)]))
12297 (set (match_operand:SI 3 "gpc_reg_operand" "=r")
12298 (match_operator:SI 4 "scc_comparison_operator"
12299 [(match_operand 5 "cc_reg_operand" "y")
12300 (const_int 0)]))]
12301 "REGNO (operands[2]) != REGNO (operands[5])"
12302 "mfcr %3\;rlwinm %0,%3,%J1,1\;rlwinm %3,%3,%J4,1"
12303 [(set_attr "type" "mfcr")
12304 (set_attr "length" "12")])
12305
12306 (define_peephole
12307 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
12308 (match_operator:DI 1 "scc_comparison_operator"
12309 [(match_operand 2 "cc_reg_operand" "y")
12310 (const_int 0)]))
12311 (set (match_operand:DI 3 "gpc_reg_operand" "=r")
12312 (match_operator:DI 4 "scc_comparison_operator"
12313 [(match_operand 5 "cc_reg_operand" "y")
12314 (const_int 0)]))]
12315 "TARGET_POWERPC64 && REGNO (operands[2]) != REGNO (operands[5])"
12316 "mfcr %3\;rlwinm %0,%3,%J1,1\;rlwinm %3,%3,%J4,1"
12317 [(set_attr "type" "mfcr")
12318 (set_attr "length" "12")])
12319
12320
12321 (define_mode_attr scc_eq_op2 [(SI "rKLI")
12322 (DI "rKJI")])
12323
12324 (define_insn_and_split "eq<mode>3"
12325 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
12326 (eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
12327 (match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>")))
12328 (clobber (match_scratch:GPR 3 "=r"))
12329 (clobber (match_scratch:GPR 4 "=r"))]
12330 ""
12331 "#"
12332 ""
12333 [(set (match_dup 4)
12334 (clz:GPR (match_dup 3)))
12335 (set (match_dup 0)
12336 (lshiftrt:GPR (match_dup 4)
12337 (match_dup 5)))]
12338 {
12339 operands[3] = rs6000_emit_eqne (<MODE>mode,
12340 operands[1], operands[2], operands[3]);
12341
12342 if (GET_CODE (operands[4]) == SCRATCH)
12343 operands[4] = gen_reg_rtx (<MODE>mode);
12344
12345 operands[5] = GEN_INT (exact_log2 (GET_MODE_BITSIZE (<MODE>mode)));
12346 }
12347 [(set (attr "length")
12348 (if_then_else (match_test "operands[2] == const0_rtx")
12349 (const_string "8")
12350 (const_string "12")))])
12351
12352 (define_insn_and_split "ne<mode>3"
12353 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12354 (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12355 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")))
12356 (clobber (match_scratch:P 3 "=r"))
12357 (clobber (match_scratch:P 4 "=r"))
12358 (clobber (reg:P CA_REGNO))]
12359 "!TARGET_ISEL"
12360 "#"
12361 ""
12362 [(parallel [(set (match_dup 4)
12363 (plus:P (match_dup 3)
12364 (const_int -1)))
12365 (set (reg:P CA_REGNO)
12366 (ne:P (match_dup 3)
12367 (const_int 0)))])
12368 (parallel [(set (match_dup 0)
12369 (plus:P (plus:P (not:P (match_dup 4))
12370 (reg:P CA_REGNO))
12371 (match_dup 3)))
12372 (clobber (reg:P CA_REGNO))])]
12373 {
12374 operands[3] = rs6000_emit_eqne (<MODE>mode,
12375 operands[1], operands[2], operands[3]);
12376
12377 if (GET_CODE (operands[4]) == SCRATCH)
12378 operands[4] = gen_reg_rtx (<MODE>mode);
12379 }
12380 [(set (attr "length")
12381 (if_then_else (match_test "operands[2] == const0_rtx")
12382 (const_string "8")
12383 (const_string "12")))])
12384
12385 (define_insn_and_split "*neg_eq_<mode>"
12386 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12387 (neg:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12388 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12389 (clobber (match_scratch:P 3 "=r"))
12390 (clobber (match_scratch:P 4 "=r"))
12391 (clobber (reg:P CA_REGNO))]
12392 ""
12393 "#"
12394 ""
12395 [(parallel [(set (match_dup 4)
12396 (plus:P (match_dup 3)
12397 (const_int -1)))
12398 (set (reg:P CA_REGNO)
12399 (ne:P (match_dup 3)
12400 (const_int 0)))])
12401 (parallel [(set (match_dup 0)
12402 (plus:P (reg:P CA_REGNO)
12403 (const_int -1)))
12404 (clobber (reg:P CA_REGNO))])]
12405 {
12406 operands[3] = rs6000_emit_eqne (<MODE>mode,
12407 operands[1], operands[2], operands[3]);
12408
12409 if (GET_CODE (operands[4]) == SCRATCH)
12410 operands[4] = gen_reg_rtx (<MODE>mode);
12411 }
12412 [(set (attr "length")
12413 (if_then_else (match_test "operands[2] == const0_rtx")
12414 (const_string "8")
12415 (const_string "12")))])
12416
12417 (define_insn_and_split "*neg_ne_<mode>"
12418 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12419 (neg:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12420 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12421 (clobber (match_scratch:P 3 "=r"))
12422 (clobber (match_scratch:P 4 "=r"))
12423 (clobber (reg:P CA_REGNO))]
12424 ""
12425 "#"
12426 ""
12427 [(parallel [(set (match_dup 4)
12428 (neg:P (match_dup 3)))
12429 (set (reg:P CA_REGNO)
12430 (eq:P (match_dup 3)
12431 (const_int 0)))])
12432 (parallel [(set (match_dup 0)
12433 (plus:P (reg:P CA_REGNO)
12434 (const_int -1)))
12435 (clobber (reg:P CA_REGNO))])]
12436 {
12437 operands[3] = rs6000_emit_eqne (<MODE>mode,
12438 operands[1], operands[2], operands[3]);
12439
12440 if (GET_CODE (operands[4]) == SCRATCH)
12441 operands[4] = gen_reg_rtx (<MODE>mode);
12442 }
12443 [(set (attr "length")
12444 (if_then_else (match_test "operands[2] == const0_rtx")
12445 (const_string "8")
12446 (const_string "12")))])
12447
12448 (define_insn_and_split "*plus_eq_<mode>"
12449 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12450 (plus:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12451 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
12452 (match_operand:P 3 "gpc_reg_operand" "r")))
12453 (clobber (match_scratch:P 4 "=r"))
12454 (clobber (match_scratch:P 5 "=r"))
12455 (clobber (reg:P CA_REGNO))]
12456 ""
12457 "#"
12458 ""
12459 [(parallel [(set (match_dup 5)
12460 (neg:P (match_dup 4)))
12461 (set (reg:P CA_REGNO)
12462 (eq:P (match_dup 4)
12463 (const_int 0)))])
12464 (parallel [(set (match_dup 0)
12465 (plus:P (match_dup 3)
12466 (reg:P CA_REGNO)))
12467 (clobber (reg:P CA_REGNO))])]
12468 {
12469 operands[4] = rs6000_emit_eqne (<MODE>mode,
12470 operands[1], operands[2], operands[4]);
12471
12472 if (GET_CODE (operands[5]) == SCRATCH)
12473 operands[5] = gen_reg_rtx (<MODE>mode);
12474 }
12475 [(set (attr "length")
12476 (if_then_else (match_test "operands[2] == const0_rtx")
12477 (const_string "8")
12478 (const_string "12")))])
12479
12480 (define_insn_and_split "*plus_ne_<mode>"
12481 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12482 (plus:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12483 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
12484 (match_operand:P 3 "gpc_reg_operand" "r")))
12485 (clobber (match_scratch:P 4 "=r"))
12486 (clobber (match_scratch:P 5 "=r"))
12487 (clobber (reg:P CA_REGNO))]
12488 ""
12489 "#"
12490 ""
12491 [(parallel [(set (match_dup 5)
12492 (plus:P (match_dup 4)
12493 (const_int -1)))
12494 (set (reg:P CA_REGNO)
12495 (ne:P (match_dup 4)
12496 (const_int 0)))])
12497 (parallel [(set (match_dup 0)
12498 (plus:P (match_dup 3)
12499 (reg:P CA_REGNO)))
12500 (clobber (reg:P CA_REGNO))])]
12501 {
12502 operands[4] = rs6000_emit_eqne (<MODE>mode,
12503 operands[1], operands[2], operands[4]);
12504
12505 if (GET_CODE (operands[5]) == SCRATCH)
12506 operands[5] = gen_reg_rtx (<MODE>mode);
12507 }
12508 [(set (attr "length")
12509 (if_then_else (match_test "operands[2] == const0_rtx")
12510 (const_string "8")
12511 (const_string "12")))])
12512
12513 (define_insn_and_split "*minus_eq_<mode>"
12514 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12515 (minus:P (match_operand:P 3 "gpc_reg_operand" "r")
12516 (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12517 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12518 (clobber (match_scratch:P 4 "=r"))
12519 (clobber (match_scratch:P 5 "=r"))
12520 (clobber (reg:P CA_REGNO))]
12521 ""
12522 "#"
12523 ""
12524 [(parallel [(set (match_dup 5)
12525 (plus:P (match_dup 4)
12526 (const_int -1)))
12527 (set (reg:P CA_REGNO)
12528 (ne:P (match_dup 4)
12529 (const_int 0)))])
12530 (parallel [(set (match_dup 0)
12531 (plus:P (plus:P (match_dup 3)
12532 (reg:P CA_REGNO))
12533 (const_int -1)))
12534 (clobber (reg:P CA_REGNO))])]
12535 {
12536 operands[4] = rs6000_emit_eqne (<MODE>mode,
12537 operands[1], operands[2], operands[4]);
12538
12539 if (GET_CODE (operands[5]) == SCRATCH)
12540 operands[5] = gen_reg_rtx (<MODE>mode);
12541 }
12542 [(set (attr "length")
12543 (if_then_else (match_test "operands[2] == const0_rtx")
12544 (const_string "8")
12545 (const_string "12")))])
12546
12547 (define_insn_and_split "*minus_ne_<mode>"
12548 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12549 (minus:P (match_operand:P 3 "gpc_reg_operand" "r")
12550 (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12551 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12552 (clobber (match_scratch:P 4 "=r"))
12553 (clobber (match_scratch:P 5 "=r"))
12554 (clobber (reg:P CA_REGNO))]
12555 ""
12556 "#"
12557 ""
12558 [(parallel [(set (match_dup 5)
12559 (neg:P (match_dup 4)))
12560 (set (reg:P CA_REGNO)
12561 (eq:P (match_dup 4)
12562 (const_int 0)))])
12563 (parallel [(set (match_dup 0)
12564 (plus:P (plus:P (match_dup 3)
12565 (reg:P CA_REGNO))
12566 (const_int -1)))
12567 (clobber (reg:P CA_REGNO))])]
12568 {
12569 operands[4] = rs6000_emit_eqne (<MODE>mode,
12570 operands[1], operands[2], operands[4]);
12571
12572 if (GET_CODE (operands[5]) == SCRATCH)
12573 operands[5] = gen_reg_rtx (<MODE>mode);
12574 }
12575 [(set (attr "length")
12576 (if_then_else (match_test "operands[2] == const0_rtx")
12577 (const_string "8")
12578 (const_string "12")))])
12579 \f
12580 ;; Define both directions of branch and return. If we need a reload
12581 ;; register, we'd rather use CR0 since it is much easier to copy a
12582 ;; register CC value to there.
12583
12584 (define_insn ""
12585 [(set (pc)
12586 (if_then_else (match_operator 1 "branch_comparison_operator"
12587 [(match_operand 2
12588 "cc_reg_operand" "y")
12589 (const_int 0)])
12590 (label_ref (match_operand 0 "" ""))
12591 (pc)))]
12592 ""
12593 "*
12594 {
12595 return output_cbranch (operands[1], \"%l0\", 0, insn);
12596 }"
12597 [(set_attr "type" "branch")])
12598
12599 (define_insn ""
12600 [(set (pc)
12601 (if_then_else (match_operator 0 "branch_comparison_operator"
12602 [(match_operand 1
12603 "cc_reg_operand" "y")
12604 (const_int 0)])
12605 (any_return)
12606 (pc)))]
12607 "<return_pred>"
12608 "*
12609 {
12610 return output_cbranch (operands[0], NULL, 0, insn);
12611 }"
12612 [(set_attr "type" "jmpreg")
12613 (set_attr "length" "4")])
12614
12615 (define_insn ""
12616 [(set (pc)
12617 (if_then_else (match_operator 1 "branch_comparison_operator"
12618 [(match_operand 2
12619 "cc_reg_operand" "y")
12620 (const_int 0)])
12621 (pc)
12622 (label_ref (match_operand 0 "" ""))))]
12623 ""
12624 "*
12625 {
12626 return output_cbranch (operands[1], \"%l0\", 1, insn);
12627 }"
12628 [(set_attr "type" "branch")])
12629
12630 (define_insn ""
12631 [(set (pc)
12632 (if_then_else (match_operator 0 "branch_comparison_operator"
12633 [(match_operand 1
12634 "cc_reg_operand" "y")
12635 (const_int 0)])
12636 (pc)
12637 (any_return)))]
12638 "<return_pred>"
12639 "*
12640 {
12641 return output_cbranch (operands[0], NULL, 1, insn);
12642 }"
12643 [(set_attr "type" "jmpreg")
12644 (set_attr "length" "4")])
12645
12646 ;; Logic on condition register values.
12647
12648 ; This pattern matches things like
12649 ; (set (reg:CCEQ 68) (compare:CCEQ (ior:SI (gt:SI (reg:CCFP 68) (const_int 0))
12650 ; (eq:SI (reg:CCFP 68) (const_int 0)))
12651 ; (const_int 1)))
12652 ; which are generated by the branch logic.
12653 ; Prefer destructive operations where BT = BB (for crXX BT,BA,BB)
12654
12655 (define_insn "*cceq_ior_compare"
12656 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12657 (compare:CCEQ (match_operator:SI 1 "boolean_operator"
12658 [(match_operator:SI 2
12659 "branch_positive_comparison_operator"
12660 [(match_operand 3
12661 "cc_reg_operand" "y,y")
12662 (const_int 0)])
12663 (match_operator:SI 4
12664 "branch_positive_comparison_operator"
12665 [(match_operand 5
12666 "cc_reg_operand" "0,y")
12667 (const_int 0)])])
12668 (const_int 1)))]
12669 ""
12670 "cr%q1 %E0,%j2,%j4"
12671 [(set_attr "type" "cr_logical,delayed_cr")])
12672
12673 ; Why is the constant -1 here, but 1 in the previous pattern?
12674 ; Because ~1 has all but the low bit set.
12675 (define_insn ""
12676 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12677 (compare:CCEQ (match_operator:SI 1 "boolean_or_operator"
12678 [(not:SI (match_operator:SI 2
12679 "branch_positive_comparison_operator"
12680 [(match_operand 3
12681 "cc_reg_operand" "y,y")
12682 (const_int 0)]))
12683 (match_operator:SI 4
12684 "branch_positive_comparison_operator"
12685 [(match_operand 5
12686 "cc_reg_operand" "0,y")
12687 (const_int 0)])])
12688 (const_int -1)))]
12689 ""
12690 "cr%q1 %E0,%j2,%j4"
12691 [(set_attr "type" "cr_logical,delayed_cr")])
12692
12693 (define_insn "*cceq_rev_compare"
12694 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12695 (compare:CCEQ (match_operator:SI 1
12696 "branch_positive_comparison_operator"
12697 [(match_operand 2
12698 "cc_reg_operand" "0,y")
12699 (const_int 0)])
12700 (const_int 0)))]
12701 ""
12702 "crnot %E0,%j1"
12703 [(set_attr "type" "cr_logical,delayed_cr")])
12704
12705 ;; If we are comparing the result of two comparisons, this can be done
12706 ;; using creqv or crxor.
12707
12708 (define_insn_and_split ""
12709 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y")
12710 (compare:CCEQ (match_operator 1 "branch_comparison_operator"
12711 [(match_operand 2 "cc_reg_operand" "y")
12712 (const_int 0)])
12713 (match_operator 3 "branch_comparison_operator"
12714 [(match_operand 4 "cc_reg_operand" "y")
12715 (const_int 0)])))]
12716 ""
12717 "#"
12718 ""
12719 [(set (match_dup 0) (compare:CCEQ (xor:SI (match_dup 1) (match_dup 3))
12720 (match_dup 5)))]
12721 "
12722 {
12723 int positive_1, positive_2;
12724
12725 positive_1 = branch_positive_comparison_operator (operands[1],
12726 GET_MODE (operands[1]));
12727 positive_2 = branch_positive_comparison_operator (operands[3],
12728 GET_MODE (operands[3]));
12729
12730 if (! positive_1)
12731 operands[1] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[2]),
12732 GET_CODE (operands[1])),
12733 SImode,
12734 operands[2], const0_rtx);
12735 else if (GET_MODE (operands[1]) != SImode)
12736 operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), SImode,
12737 operands[2], const0_rtx);
12738
12739 if (! positive_2)
12740 operands[3] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[4]),
12741 GET_CODE (operands[3])),
12742 SImode,
12743 operands[4], const0_rtx);
12744 else if (GET_MODE (operands[3]) != SImode)
12745 operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SImode,
12746 operands[4], const0_rtx);
12747
12748 if (positive_1 == positive_2)
12749 {
12750 operands[1] = gen_rtx_NOT (SImode, operands[1]);
12751 operands[5] = constm1_rtx;
12752 }
12753 else
12754 {
12755 operands[5] = const1_rtx;
12756 }
12757 }")
12758
12759 ;; Unconditional branch and return.
12760
12761 (define_insn "jump"
12762 [(set (pc)
12763 (label_ref (match_operand 0 "" "")))]
12764 ""
12765 "b %l0"
12766 [(set_attr "type" "branch")])
12767
12768 (define_insn "<return_str>return"
12769 [(any_return)]
12770 "<return_pred>"
12771 "blr"
12772 [(set_attr "type" "jmpreg")])
12773
12774 (define_expand "indirect_jump"
12775 [(set (pc) (match_operand 0 "register_operand" ""))])
12776
12777 (define_insn "*indirect_jump<mode>"
12778 [(set (pc) (match_operand:P 0 "register_operand" "c,*l"))]
12779 ""
12780 "@
12781 bctr
12782 blr"
12783 [(set_attr "type" "jmpreg")])
12784
12785 ;; Table jump for switch statements:
12786 (define_expand "tablejump"
12787 [(use (match_operand 0 "" ""))
12788 (use (label_ref (match_operand 1 "" "")))]
12789 ""
12790 "
12791 {
12792 if (TARGET_32BIT)
12793 emit_jump_insn (gen_tablejumpsi (operands[0], operands[1]));
12794 else
12795 emit_jump_insn (gen_tablejumpdi (operands[0], operands[1]));
12796 DONE;
12797 }")
12798
12799 (define_expand "tablejumpsi"
12800 [(set (match_dup 3)
12801 (plus:SI (match_operand:SI 0 "" "")
12802 (match_dup 2)))
12803 (parallel [(set (pc) (match_dup 3))
12804 (use (label_ref (match_operand 1 "" "")))])]
12805 "TARGET_32BIT"
12806 "
12807 { operands[0] = force_reg (SImode, operands[0]);
12808 operands[2] = force_reg (SImode, gen_rtx_LABEL_REF (SImode, operands[1]));
12809 operands[3] = gen_reg_rtx (SImode);
12810 }")
12811
12812 (define_expand "tablejumpdi"
12813 [(set (match_dup 4)
12814 (sign_extend:DI (match_operand:SI 0 "lwa_operand" "")))
12815 (set (match_dup 3)
12816 (plus:DI (match_dup 4)
12817 (match_dup 2)))
12818 (parallel [(set (pc) (match_dup 3))
12819 (use (label_ref (match_operand 1 "" "")))])]
12820 "TARGET_64BIT"
12821 "
12822 { operands[2] = force_reg (DImode, gen_rtx_LABEL_REF (DImode, operands[1]));
12823 operands[3] = gen_reg_rtx (DImode);
12824 operands[4] = gen_reg_rtx (DImode);
12825 }")
12826
12827 (define_insn "*tablejump<mode>_internal1"
12828 [(set (pc)
12829 (match_operand:P 0 "register_operand" "c,*l"))
12830 (use (label_ref (match_operand 1 "" "")))]
12831 ""
12832 "@
12833 bctr
12834 blr"
12835 [(set_attr "type" "jmpreg")])
12836
12837 (define_insn "nop"
12838 [(const_int 0)]
12839 ""
12840 "nop")
12841
12842 (define_insn "group_ending_nop"
12843 [(unspec [(const_int 0)] UNSPEC_GRP_END_NOP)]
12844 ""
12845 "*
12846 {
12847 if (rs6000_cpu_attr == CPU_POWER6)
12848 return \"ori 1,1,0\";
12849 return \"ori 2,2,0\";
12850 }")
12851 \f
12852 ;; Define the subtract-one-and-jump insns, starting with the template
12853 ;; so loop.c knows what to generate.
12854
12855 (define_expand "doloop_end"
12856 [(use (match_operand 0 "" "")) ; loop pseudo
12857 (use (match_operand 1 "" ""))] ; label
12858 ""
12859 "
12860 {
12861 if (TARGET_64BIT)
12862 {
12863 if (GET_MODE (operands[0]) != DImode)
12864 FAIL;
12865 emit_jump_insn (gen_ctrdi (operands[0], operands[1]));
12866 }
12867 else
12868 {
12869 if (GET_MODE (operands[0]) != SImode)
12870 FAIL;
12871 emit_jump_insn (gen_ctrsi (operands[0], operands[1]));
12872 }
12873 DONE;
12874 }")
12875
12876 (define_expand "ctr<mode>"
12877 [(parallel [(set (pc)
12878 (if_then_else (ne (match_operand:P 0 "register_operand" "")
12879 (const_int 1))
12880 (label_ref (match_operand 1 "" ""))
12881 (pc)))
12882 (set (match_dup 0)
12883 (plus:P (match_dup 0)
12884 (const_int -1)))
12885 (clobber (match_scratch:CC 2 ""))
12886 (clobber (match_scratch:P 3 ""))])]
12887 ""
12888 "")
12889
12890 ;; We need to be able to do this for any operand, including MEM, or we
12891 ;; will cause reload to blow up since we don't allow output reloads on
12892 ;; JUMP_INSNs.
12893 ;; For the length attribute to be calculated correctly, the
12894 ;; label MUST be operand 0.
12895
12896 (define_insn "*ctr<mode>_internal1"
12897 [(set (pc)
12898 (if_then_else (ne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12899 (const_int 1))
12900 (label_ref (match_operand 0 "" ""))
12901 (pc)))
12902 (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*c*l")
12903 (plus:P (match_dup 1)
12904 (const_int -1)))
12905 (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
12906 (clobber (match_scratch:P 4 "=X,X,&r,r"))]
12907 ""
12908 "*
12909 {
12910 if (which_alternative != 0)
12911 return \"#\";
12912 else if (get_attr_length (insn) == 4)
12913 return \"bdnz %l0\";
12914 else
12915 return \"bdz $+8\;b %l0\";
12916 }"
12917 [(set_attr "type" "branch")
12918 (set_attr "length" "*,16,20,20")])
12919
12920 (define_insn "*ctr<mode>_internal2"
12921 [(set (pc)
12922 (if_then_else (ne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12923 (const_int 1))
12924 (pc)
12925 (label_ref (match_operand 0 "" ""))))
12926 (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*c*l")
12927 (plus:P (match_dup 1)
12928 (const_int -1)))
12929 (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
12930 (clobber (match_scratch:P 4 "=X,X,&r,r"))]
12931 ""
12932 "*
12933 {
12934 if (which_alternative != 0)
12935 return \"#\";
12936 else if (get_attr_length (insn) == 4)
12937 return \"bdz %l0\";
12938 else
12939 return \"bdnz $+8\;b %l0\";
12940 }"
12941 [(set_attr "type" "branch")
12942 (set_attr "length" "*,16,20,20")])
12943
12944 ;; Similar but use EQ
12945
12946 (define_insn "*ctr<mode>_internal5"
12947 [(set (pc)
12948 (if_then_else (eq (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12949 (const_int 1))
12950 (label_ref (match_operand 0 "" ""))
12951 (pc)))
12952 (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*c*l")
12953 (plus:P (match_dup 1)
12954 (const_int -1)))
12955 (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
12956 (clobber (match_scratch:P 4 "=X,X,&r,r"))]
12957 ""
12958 "*
12959 {
12960 if (which_alternative != 0)
12961 return \"#\";
12962 else if (get_attr_length (insn) == 4)
12963 return \"bdz %l0\";
12964 else
12965 return \"bdnz $+8\;b %l0\";
12966 }"
12967 [(set_attr "type" "branch")
12968 (set_attr "length" "*,16,20,20")])
12969
12970 (define_insn "*ctr<mode>_internal6"
12971 [(set (pc)
12972 (if_then_else (eq (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12973 (const_int 1))
12974 (pc)
12975 (label_ref (match_operand 0 "" ""))))
12976 (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*c*l")
12977 (plus:P (match_dup 1)
12978 (const_int -1)))
12979 (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
12980 (clobber (match_scratch:P 4 "=X,X,&r,r"))]
12981 ""
12982 "*
12983 {
12984 if (which_alternative != 0)
12985 return \"#\";
12986 else if (get_attr_length (insn) == 4)
12987 return \"bdnz %l0\";
12988 else
12989 return \"bdz $+8\;b %l0\";
12990 }"
12991 [(set_attr "type" "branch")
12992 (set_attr "length" "*,16,20,20")])
12993
12994 ;; Now the splitters if we could not allocate the CTR register
12995
12996 (define_split
12997 [(set (pc)
12998 (if_then_else (match_operator 2 "comparison_operator"
12999 [(match_operand:P 1 "gpc_reg_operand" "")
13000 (const_int 1)])
13001 (match_operand 5 "" "")
13002 (match_operand 6 "" "")))
13003 (set (match_operand:P 0 "gpc_reg_operand" "")
13004 (plus:P (match_dup 1) (const_int -1)))
13005 (clobber (match_scratch:CC 3 ""))
13006 (clobber (match_scratch:P 4 ""))]
13007 "reload_completed"
13008 [(set (match_dup 3)
13009 (compare:CC (match_dup 1)
13010 (const_int 1)))
13011 (set (match_dup 0)
13012 (plus:P (match_dup 1)
13013 (const_int -1)))
13014 (set (pc) (if_then_else (match_dup 7)
13015 (match_dup 5)
13016 (match_dup 6)))]
13017 "
13018 { operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[2]), VOIDmode,
13019 operands[3], const0_rtx); }")
13020
13021 (define_split
13022 [(set (pc)
13023 (if_then_else (match_operator 2 "comparison_operator"
13024 [(match_operand:P 1 "gpc_reg_operand" "")
13025 (const_int 1)])
13026 (match_operand 5 "" "")
13027 (match_operand 6 "" "")))
13028 (set (match_operand:P 0 "nonimmediate_operand" "")
13029 (plus:P (match_dup 1) (const_int -1)))
13030 (clobber (match_scratch:CC 3 ""))
13031 (clobber (match_scratch:P 4 ""))]
13032 "reload_completed && ! gpc_reg_operand (operands[0], SImode)"
13033 [(set (match_dup 3)
13034 (compare:CC (match_dup 1)
13035 (const_int 1)))
13036 (set (match_dup 4)
13037 (plus:P (match_dup 1)
13038 (const_int -1)))
13039 (set (match_dup 0)
13040 (match_dup 4))
13041 (set (pc) (if_then_else (match_dup 7)
13042 (match_dup 5)
13043 (match_dup 6)))]
13044 "
13045 { operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[2]), VOIDmode,
13046 operands[3], const0_rtx); }")
13047 \f
13048 (define_insn "trap"
13049 [(trap_if (const_int 1) (const_int 0))]
13050 ""
13051 "trap"
13052 [(set_attr "type" "trap")])
13053
13054 (define_expand "ctrap<mode>4"
13055 [(trap_if (match_operator 0 "ordered_comparison_operator"
13056 [(match_operand:GPR 1 "register_operand")
13057 (match_operand:GPR 2 "reg_or_short_operand")])
13058 (match_operand 3 "zero_constant" ""))]
13059 ""
13060 "")
13061
13062 (define_insn ""
13063 [(trap_if (match_operator 0 "ordered_comparison_operator"
13064 [(match_operand:GPR 1 "register_operand" "r")
13065 (match_operand:GPR 2 "reg_or_short_operand" "rI")])
13066 (const_int 0))]
13067 ""
13068 "t<wd>%V0%I2 %1,%2"
13069 [(set_attr "type" "trap")])
13070 \f
13071 ;; Insns related to generating the function prologue and epilogue.
13072
13073 (define_expand "prologue"
13074 [(use (const_int 0))]
13075 ""
13076 {
13077 rs6000_emit_prologue ();
13078 if (!TARGET_SCHED_PROLOG)
13079 emit_insn (gen_blockage ());
13080 DONE;
13081 })
13082
13083 (define_insn "*movesi_from_cr_one"
13084 [(match_parallel 0 "mfcr_operation"
13085 [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
13086 (unspec:SI [(match_operand:CC 2 "cc_reg_operand" "y")
13087 (match_operand 3 "immediate_operand" "n")]
13088 UNSPEC_MOVESI_FROM_CR))])]
13089 "TARGET_MFCRF"
13090 "*
13091 {
13092 int mask = 0;
13093 int i;
13094 for (i = 0; i < XVECLEN (operands[0], 0); i++)
13095 {
13096 mask = INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
13097 operands[4] = GEN_INT (mask);
13098 output_asm_insn (\"mfcr %1,%4\", operands);
13099 }
13100 return \"\";
13101 }"
13102 [(set_attr "type" "mfcrf")])
13103
13104 (define_insn "movesi_from_cr"
13105 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
13106 (unspec:SI [(reg:CC CR0_REGNO) (reg:CC CR1_REGNO)
13107 (reg:CC CR2_REGNO) (reg:CC CR3_REGNO)
13108 (reg:CC CR4_REGNO) (reg:CC CR5_REGNO)
13109 (reg:CC CR6_REGNO) (reg:CC CR7_REGNO)]
13110 UNSPEC_MOVESI_FROM_CR))]
13111 ""
13112 "mfcr %0"
13113 [(set_attr "type" "mfcr")])
13114
13115 (define_insn "*crsave"
13116 [(match_parallel 0 "crsave_operation"
13117 [(set (match_operand:SI 1 "memory_operand" "=m")
13118 (match_operand:SI 2 "gpc_reg_operand" "r"))])]
13119 ""
13120 "stw %2,%1"
13121 [(set_attr "type" "store")])
13122
13123 (define_insn "*stmw"
13124 [(match_parallel 0 "stmw_operation"
13125 [(set (match_operand:SI 1 "memory_operand" "=m")
13126 (match_operand:SI 2 "gpc_reg_operand" "r"))])]
13127 "TARGET_MULTIPLE"
13128 "stmw %2,%1"
13129 [(set_attr "type" "store")
13130 (set_attr "update" "yes")
13131 (set_attr "indexed" "yes")])
13132
13133 ; The following comment applies to:
13134 ; save_gpregs_*
13135 ; save_fpregs_*
13136 ; restore_gpregs*
13137 ; return_and_restore_gpregs*
13138 ; return_and_restore_fpregs*
13139 ; return_and_restore_fpregs_aix*
13140 ;
13141 ; The out-of-line save / restore functions expects one input argument.
13142 ; Since those are not standard call_insn's, we must avoid using
13143 ; MATCH_OPERAND for that argument. That way the register rename
13144 ; optimization will not try to rename this register.
13145 ; Each pattern is repeated for each possible register number used in
13146 ; various ABIs (r11, r1, and for some functions r12)
13147
13148 (define_insn "*save_gpregs_<mode>_r11"
13149 [(match_parallel 0 "any_parallel_operand"
13150 [(clobber (reg:P 65))
13151 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13152 (use (reg:P 11))
13153 (set (match_operand:P 2 "memory_operand" "=m")
13154 (match_operand:P 3 "gpc_reg_operand" "r"))])]
13155 ""
13156 "bl %1"
13157 [(set_attr "type" "branch")
13158 (set_attr "length" "4")])
13159
13160 (define_insn "*save_gpregs_<mode>_r12"
13161 [(match_parallel 0 "any_parallel_operand"
13162 [(clobber (reg:P 65))
13163 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13164 (use (reg:P 12))
13165 (set (match_operand:P 2 "memory_operand" "=m")
13166 (match_operand:P 3 "gpc_reg_operand" "r"))])]
13167 ""
13168 "bl %1"
13169 [(set_attr "type" "branch")
13170 (set_attr "length" "4")])
13171
13172 (define_insn "*save_gpregs_<mode>_r1"
13173 [(match_parallel 0 "any_parallel_operand"
13174 [(clobber (reg:P 65))
13175 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13176 (use (reg:P 1))
13177 (set (match_operand:P 2 "memory_operand" "=m")
13178 (match_operand:P 3 "gpc_reg_operand" "r"))])]
13179 ""
13180 "bl %1"
13181 [(set_attr "type" "branch")
13182 (set_attr "length" "4")])
13183
13184 (define_insn "*save_fpregs_<mode>_r11"
13185 [(match_parallel 0 "any_parallel_operand"
13186 [(clobber (reg:P 65))
13187 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13188 (use (reg:P 11))
13189 (set (match_operand:DF 2 "memory_operand" "=m")
13190 (match_operand:DF 3 "gpc_reg_operand" "d"))])]
13191 ""
13192 "bl %1"
13193 [(set_attr "type" "branch")
13194 (set_attr "length" "4")])
13195
13196 (define_insn "*save_fpregs_<mode>_r12"
13197 [(match_parallel 0 "any_parallel_operand"
13198 [(clobber (reg:P 65))
13199 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13200 (use (reg:P 12))
13201 (set (match_operand:DF 2 "memory_operand" "=m")
13202 (match_operand:DF 3 "gpc_reg_operand" "d"))])]
13203 ""
13204 "bl %1"
13205 [(set_attr "type" "branch")
13206 (set_attr "length" "4")])
13207
13208 (define_insn "*save_fpregs_<mode>_r1"
13209 [(match_parallel 0 "any_parallel_operand"
13210 [(clobber (reg:P 65))
13211 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13212 (use (reg:P 1))
13213 (set (match_operand:DF 2 "memory_operand" "=m")
13214 (match_operand:DF 3 "gpc_reg_operand" "d"))])]
13215 ""
13216 "bl %1"
13217 [(set_attr "type" "branch")
13218 (set_attr "length" "4")])
13219
13220 ; This is to explain that changes to the stack pointer should
13221 ; not be moved over loads from or stores to stack memory.
13222 (define_insn "stack_tie"
13223 [(match_parallel 0 "tie_operand"
13224 [(set (mem:BLK (reg 1)) (const_int 0))])]
13225 ""
13226 ""
13227 [(set_attr "length" "0")])
13228
13229 (define_expand "epilogue"
13230 [(use (const_int 0))]
13231 ""
13232 {
13233 if (!TARGET_SCHED_PROLOG)
13234 emit_insn (gen_blockage ());
13235 rs6000_emit_epilogue (FALSE);
13236 DONE;
13237 })
13238
13239 ; On some processors, doing the mtcrf one CC register at a time is
13240 ; faster (like on the 604e). On others, doing them all at once is
13241 ; faster; for instance, on the 601 and 750.
13242
13243 (define_expand "movsi_to_cr_one"
13244 [(set (match_operand:CC 0 "cc_reg_operand" "")
13245 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "")
13246 (match_dup 2)] UNSPEC_MOVESI_TO_CR))]
13247 ""
13248 "operands[2] = GEN_INT (1 << (75 - REGNO (operands[0])));")
13249
13250 (define_insn "*movsi_to_cr"
13251 [(match_parallel 0 "mtcrf_operation"
13252 [(set (match_operand:CC 1 "cc_reg_operand" "=y")
13253 (unspec:CC [(match_operand:SI 2 "gpc_reg_operand" "r")
13254 (match_operand 3 "immediate_operand" "n")]
13255 UNSPEC_MOVESI_TO_CR))])]
13256 ""
13257 "*
13258 {
13259 int mask = 0;
13260 int i;
13261 for (i = 0; i < XVECLEN (operands[0], 0); i++)
13262 mask |= INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
13263 operands[4] = GEN_INT (mask);
13264 return \"mtcrf %4,%2\";
13265 }"
13266 [(set_attr "type" "mtcr")])
13267
13268 (define_insn "*mtcrfsi"
13269 [(set (match_operand:CC 0 "cc_reg_operand" "=y")
13270 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
13271 (match_operand 2 "immediate_operand" "n")]
13272 UNSPEC_MOVESI_TO_CR))]
13273 "GET_CODE (operands[0]) == REG
13274 && CR_REGNO_P (REGNO (operands[0]))
13275 && GET_CODE (operands[2]) == CONST_INT
13276 && INTVAL (operands[2]) == 1 << (75 - REGNO (operands[0]))"
13277 "mtcrf %R0,%1"
13278 [(set_attr "type" "mtcr")])
13279
13280 ; The load-multiple instructions have similar properties.
13281 ; Note that "load_multiple" is a name known to the machine-independent
13282 ; code that actually corresponds to the PowerPC load-string.
13283
13284 (define_insn "*lmw"
13285 [(match_parallel 0 "lmw_operation"
13286 [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
13287 (match_operand:SI 2 "memory_operand" "m"))])]
13288 "TARGET_MULTIPLE"
13289 "lmw %1,%2"
13290 [(set_attr "type" "load")
13291 (set_attr "update" "yes")
13292 (set_attr "indexed" "yes")
13293 (set_attr "cell_micro" "always")])
13294
13295 (define_insn "*return_internal_<mode>"
13296 [(simple_return)
13297 (use (match_operand:P 0 "register_operand" "lc"))]
13298 ""
13299 "b%T0"
13300 [(set_attr "type" "jmpreg")])
13301
13302 ; FIXME: This would probably be somewhat simpler if the Cygnus sibcall
13303 ; stuff was in GCC. Oh, and "any_parallel_operand" is a bit flexible...
13304
13305 ; The following comment applies to:
13306 ; save_gpregs_*
13307 ; save_fpregs_*
13308 ; restore_gpregs*
13309 ; return_and_restore_gpregs*
13310 ; return_and_restore_fpregs*
13311 ; return_and_restore_fpregs_aix*
13312 ;
13313 ; The out-of-line save / restore functions expects one input argument.
13314 ; Since those are not standard call_insn's, we must avoid using
13315 ; MATCH_OPERAND for that argument. That way the register rename
13316 ; optimization will not try to rename this register.
13317 ; Each pattern is repeated for each possible register number used in
13318 ; various ABIs (r11, r1, and for some functions r12)
13319
13320 (define_insn "*restore_gpregs_<mode>_r11"
13321 [(match_parallel 0 "any_parallel_operand"
13322 [(clobber (match_operand:P 1 "register_operand" "=l"))
13323 (use (match_operand:P 2 "symbol_ref_operand" "s"))
13324 (use (reg:P 11))
13325 (set (match_operand:P 3 "gpc_reg_operand" "=r")
13326 (match_operand:P 4 "memory_operand" "m"))])]
13327 ""
13328 "bl %2"
13329 [(set_attr "type" "branch")
13330 (set_attr "length" "4")])
13331
13332 (define_insn "*restore_gpregs_<mode>_r12"
13333 [(match_parallel 0 "any_parallel_operand"
13334 [(clobber (match_operand:P 1 "register_operand" "=l"))
13335 (use (match_operand:P 2 "symbol_ref_operand" "s"))
13336 (use (reg:P 12))
13337 (set (match_operand:P 3 "gpc_reg_operand" "=r")
13338 (match_operand:P 4 "memory_operand" "m"))])]
13339 ""
13340 "bl %2"
13341 [(set_attr "type" "branch")
13342 (set_attr "length" "4")])
13343
13344 (define_insn "*restore_gpregs_<mode>_r1"
13345 [(match_parallel 0 "any_parallel_operand"
13346 [(clobber (match_operand:P 1 "register_operand" "=l"))
13347 (use (match_operand:P 2 "symbol_ref_operand" "s"))
13348 (use (reg:P 1))
13349 (set (match_operand:P 3 "gpc_reg_operand" "=r")
13350 (match_operand:P 4 "memory_operand" "m"))])]
13351 ""
13352 "bl %2"
13353 [(set_attr "type" "branch")
13354 (set_attr "length" "4")])
13355
13356 (define_insn "*return_and_restore_gpregs_<mode>_r11"
13357 [(match_parallel 0 "any_parallel_operand"
13358 [(return)
13359 (clobber (match_operand:P 1 "register_operand" "=l"))
13360 (use (match_operand:P 2 "symbol_ref_operand" "s"))
13361 (use (reg:P 11))
13362 (set (match_operand:P 3 "gpc_reg_operand" "=r")
13363 (match_operand:P 4 "memory_operand" "m"))])]
13364 ""
13365 "b %2"
13366 [(set_attr "type" "branch")
13367 (set_attr "length" "4")])
13368
13369 (define_insn "*return_and_restore_gpregs_<mode>_r12"
13370 [(match_parallel 0 "any_parallel_operand"
13371 [(return)
13372 (clobber (match_operand:P 1 "register_operand" "=l"))
13373 (use (match_operand:P 2 "symbol_ref_operand" "s"))
13374 (use (reg:P 12))
13375 (set (match_operand:P 3 "gpc_reg_operand" "=r")
13376 (match_operand:P 4 "memory_operand" "m"))])]
13377 ""
13378 "b %2"
13379 [(set_attr "type" "branch")
13380 (set_attr "length" "4")])
13381
13382 (define_insn "*return_and_restore_gpregs_<mode>_r1"
13383 [(match_parallel 0 "any_parallel_operand"
13384 [(return)
13385 (clobber (match_operand:P 1 "register_operand" "=l"))
13386 (use (match_operand:P 2 "symbol_ref_operand" "s"))
13387 (use (reg:P 1))
13388 (set (match_operand:P 3 "gpc_reg_operand" "=r")
13389 (match_operand:P 4 "memory_operand" "m"))])]
13390 ""
13391 "b %2"
13392 [(set_attr "type" "branch")
13393 (set_attr "length" "4")])
13394
13395 (define_insn "*return_and_restore_fpregs_<mode>_r11"
13396 [(match_parallel 0 "any_parallel_operand"
13397 [(return)
13398 (clobber (match_operand:P 1 "register_operand" "=l"))
13399 (use (match_operand:P 2 "symbol_ref_operand" "s"))
13400 (use (reg:P 11))
13401 (set (match_operand:DF 3 "gpc_reg_operand" "=d")
13402 (match_operand:DF 4 "memory_operand" "m"))])]
13403 ""
13404 "b %2"
13405 [(set_attr "type" "branch")
13406 (set_attr "length" "4")])
13407
13408 (define_insn "*return_and_restore_fpregs_<mode>_r12"
13409 [(match_parallel 0 "any_parallel_operand"
13410 [(return)
13411 (clobber (match_operand:P 1 "register_operand" "=l"))
13412 (use (match_operand:P 2 "symbol_ref_operand" "s"))
13413 (use (reg:P 12))
13414 (set (match_operand:DF 3 "gpc_reg_operand" "=d")
13415 (match_operand:DF 4 "memory_operand" "m"))])]
13416 ""
13417 "b %2"
13418 [(set_attr "type" "branch")
13419 (set_attr "length" "4")])
13420
13421 (define_insn "*return_and_restore_fpregs_<mode>_r1"
13422 [(match_parallel 0 "any_parallel_operand"
13423 [(return)
13424 (clobber (match_operand:P 1 "register_operand" "=l"))
13425 (use (match_operand:P 2 "symbol_ref_operand" "s"))
13426 (use (reg:P 1))
13427 (set (match_operand:DF 3 "gpc_reg_operand" "=d")
13428 (match_operand:DF 4 "memory_operand" "m"))])]
13429 ""
13430 "b %2"
13431 [(set_attr "type" "branch")
13432 (set_attr "length" "4")])
13433
13434 (define_insn "*return_and_restore_fpregs_aix_<mode>_r11"
13435 [(match_parallel 0 "any_parallel_operand"
13436 [(return)
13437 (use (match_operand:P 1 "register_operand" "l"))
13438 (use (match_operand:P 2 "symbol_ref_operand" "s"))
13439 (use (reg:P 11))
13440 (set (match_operand:DF 3 "gpc_reg_operand" "=d")
13441 (match_operand:DF 4 "memory_operand" "m"))])]
13442 ""
13443 "b %2"
13444 [(set_attr "type" "branch")
13445 (set_attr "length" "4")])
13446
13447 (define_insn "*return_and_restore_fpregs_aix_<mode>_r1"
13448 [(match_parallel 0 "any_parallel_operand"
13449 [(return)
13450 (use (match_operand:P 1 "register_operand" "l"))
13451 (use (match_operand:P 2 "symbol_ref_operand" "s"))
13452 (use (reg:P 1))
13453 (set (match_operand:DF 3 "gpc_reg_operand" "=d")
13454 (match_operand:DF 4 "memory_operand" "m"))])]
13455 ""
13456 "b %2"
13457 [(set_attr "type" "branch")
13458 (set_attr "length" "4")])
13459
13460 ; This is used in compiling the unwind routines.
13461 (define_expand "eh_return"
13462 [(use (match_operand 0 "general_operand" ""))]
13463 ""
13464 "
13465 {
13466 if (TARGET_32BIT)
13467 emit_insn (gen_eh_set_lr_si (operands[0]));
13468 else
13469 emit_insn (gen_eh_set_lr_di (operands[0]));
13470 DONE;
13471 }")
13472
13473 ; We can't expand this before we know where the link register is stored.
13474 (define_insn "eh_set_lr_<mode>"
13475 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
13476 UNSPECV_EH_RR)
13477 (clobber (match_scratch:P 1 "=&b"))]
13478 ""
13479 "#")
13480
13481 (define_split
13482 [(unspec_volatile [(match_operand 0 "register_operand" "")] UNSPECV_EH_RR)
13483 (clobber (match_scratch 1 ""))]
13484 "reload_completed"
13485 [(const_int 0)]
13486 "
13487 {
13488 rs6000_emit_eh_reg_restore (operands[0], operands[1]);
13489 DONE;
13490 }")
13491
13492 (define_insn "prefetch"
13493 [(prefetch (match_operand 0 "indexed_or_indirect_address" "a")
13494 (match_operand:SI 1 "const_int_operand" "n")
13495 (match_operand:SI 2 "const_int_operand" "n"))]
13496 ""
13497 "*
13498 {
13499 if (GET_CODE (operands[0]) == REG)
13500 return INTVAL (operands[1]) ? \"dcbtst 0,%0\" : \"dcbt 0,%0\";
13501 return INTVAL (operands[1]) ? \"dcbtst %a0\" : \"dcbt %a0\";
13502 }"
13503 [(set_attr "type" "load")])
13504 \f
13505 (define_insn "bpermd_<mode>"
13506 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
13507 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "r")
13508 (match_operand:P 2 "gpc_reg_operand" "r")] UNSPEC_BPERM))]
13509 "TARGET_POPCNTD"
13510 "bpermd %0,%1,%2"
13511 [(set_attr "type" "popcnt")])
13512
13513 \f
13514 ;; Builtin fma support. Handle
13515 ;; Note that the conditions for expansion are in the FMA_F iterator.
13516
13517 (define_expand "fma<mode>4"
13518 [(set (match_operand:FMA_F 0 "register_operand" "")
13519 (fma:FMA_F
13520 (match_operand:FMA_F 1 "register_operand" "")
13521 (match_operand:FMA_F 2 "register_operand" "")
13522 (match_operand:FMA_F 3 "register_operand" "")))]
13523 ""
13524 "")
13525
13526 (define_insn "*fma<mode>4_fpr"
13527 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>,<Fv>")
13528 (fma:SFDF
13529 (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv>,<Fv>")
13530 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>,0")
13531 (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv>")))]
13532 "TARGET_<MODE>_FPR"
13533 "@
13534 fmadd<Ftrad> %0,%1,%2,%3
13535 xsmadda<Fvsx> %x0,%x1,%x2
13536 xsmaddm<Fvsx> %x0,%x1,%x3"
13537 [(set_attr "type" "fp")
13538 (set_attr "fp_type" "fp_maddsub_<Fs>")])
13539
13540 ; Altivec only has fma and nfms.
13541 (define_expand "fms<mode>4"
13542 [(set (match_operand:FMA_F 0 "register_operand" "")
13543 (fma:FMA_F
13544 (match_operand:FMA_F 1 "register_operand" "")
13545 (match_operand:FMA_F 2 "register_operand" "")
13546 (neg:FMA_F (match_operand:FMA_F 3 "register_operand" ""))))]
13547 "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13548 "")
13549
13550 (define_insn "*fms<mode>4_fpr"
13551 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>,<Fv>")
13552 (fma:SFDF
13553 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>,<Fv>")
13554 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>,0")
13555 (neg:SFDF (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv>"))))]
13556 "TARGET_<MODE>_FPR"
13557 "@
13558 fmsub<Ftrad> %0,%1,%2,%3
13559 xsmsuba<Fvsx> %x0,%x1,%x2
13560 xsmsubm<Fvsx> %x0,%x1,%x3"
13561 [(set_attr "type" "fp")
13562 (set_attr "fp_type" "fp_maddsub_<Fs>")])
13563
13564 ;; If signed zeros are ignored, -(a * b - c) = -a * b + c.
13565 (define_expand "fnma<mode>4"
13566 [(set (match_operand:FMA_F 0 "register_operand" "")
13567 (neg:FMA_F
13568 (fma:FMA_F
13569 (match_operand:FMA_F 1 "register_operand" "")
13570 (match_operand:FMA_F 2 "register_operand" "")
13571 (neg:FMA_F (match_operand:FMA_F 3 "register_operand" "")))))]
13572 "!HONOR_SIGNED_ZEROS (<MODE>mode)"
13573 "")
13574
13575 ;; If signed zeros are ignored, -(a * b + c) = -a * b - c.
13576 (define_expand "fnms<mode>4"
13577 [(set (match_operand:FMA_F 0 "register_operand" "")
13578 (neg:FMA_F
13579 (fma:FMA_F
13580 (match_operand:FMA_F 1 "register_operand" "")
13581 (match_operand:FMA_F 2 "register_operand" "")
13582 (match_operand:FMA_F 3 "register_operand" ""))))]
13583 "!HONOR_SIGNED_ZEROS (<MODE>mode) && !VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13584 "")
13585
13586 ; Not an official optab name, but used from builtins.
13587 (define_expand "nfma<mode>4"
13588 [(set (match_operand:FMA_F 0 "register_operand" "")
13589 (neg:FMA_F
13590 (fma:FMA_F
13591 (match_operand:FMA_F 1 "register_operand" "")
13592 (match_operand:FMA_F 2 "register_operand" "")
13593 (match_operand:FMA_F 3 "register_operand" ""))))]
13594 "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13595 "")
13596
13597 (define_insn "*nfma<mode>4_fpr"
13598 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>,<Fv>")
13599 (neg:SFDF
13600 (fma:SFDF
13601 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>,<Fv>")
13602 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>,0")
13603 (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv>"))))]
13604 "TARGET_<MODE>_FPR"
13605 "@
13606 fnmadd<Ftrad> %0,%1,%2,%3
13607 xsnmadda<Fvsx> %x0,%x1,%x2
13608 xsnmaddm<Fvsx> %x0,%x1,%x3"
13609 [(set_attr "type" "fp")
13610 (set_attr "fp_type" "fp_maddsub_<Fs>")])
13611
13612 ; Not an official optab name, but used from builtins.
13613 (define_expand "nfms<mode>4"
13614 [(set (match_operand:FMA_F 0 "register_operand" "")
13615 (neg:FMA_F
13616 (fma:FMA_F
13617 (match_operand:FMA_F 1 "register_operand" "")
13618 (match_operand:FMA_F 2 "register_operand" "")
13619 (neg:FMA_F (match_operand:FMA_F 3 "register_operand" "")))))]
13620 ""
13621 "")
13622
13623 (define_insn "*nfmssf4_fpr"
13624 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>,<Fv>")
13625 (neg:SFDF
13626 (fma:SFDF
13627 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>,<Fv>")
13628 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>,0")
13629 (neg:SFDF
13630 (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv>")))))]
13631 "TARGET_<MODE>_FPR"
13632 "@
13633 fnmsub<Ftrad> %0,%1,%2,%3
13634 xsnmsuba<Fvsx> %x0,%x1,%x2
13635 xsnmsubm<Fvsx> %x0,%x1,%x3"
13636 [(set_attr "type" "fp")
13637 (set_attr "fp_type" "fp_maddsub_<Fs>")])
13638
13639 \f
13640 (define_expand "rs6000_get_timebase"
13641 [(use (match_operand:DI 0 "gpc_reg_operand" ""))]
13642 ""
13643 {
13644 if (TARGET_POWERPC64)
13645 emit_insn (gen_rs6000_mftb_di (operands[0]));
13646 else
13647 emit_insn (gen_rs6000_get_timebase_ppc32 (operands[0]));
13648 DONE;
13649 })
13650
13651 (define_insn "rs6000_get_timebase_ppc32"
13652 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
13653 (unspec_volatile:DI [(const_int 0)] UNSPECV_MFTB))
13654 (clobber (match_scratch:SI 1 "=r"))
13655 (clobber (match_scratch:CC 2 "=y"))]
13656 "!TARGET_POWERPC64"
13657 {
13658 if (WORDS_BIG_ENDIAN)
13659 if (TARGET_MFCRF)
13660 {
13661 return "mfspr %0,269\;"
13662 "mfspr %L0,268\;"
13663 "mfspr %1,269\;"
13664 "cmpw %2,%0,%1\;"
13665 "bne- %2,$-16";
13666 }
13667 else
13668 {
13669 return "mftbu %0\;"
13670 "mftb %L0\;"
13671 "mftbu %1\;"
13672 "cmpw %2,%0,%1\;"
13673 "bne- %2,$-16";
13674 }
13675 else
13676 if (TARGET_MFCRF)
13677 {
13678 return "mfspr %L0,269\;"
13679 "mfspr %0,268\;"
13680 "mfspr %1,269\;"
13681 "cmpw %2,%L0,%1\;"
13682 "bne- %2,$-16";
13683 }
13684 else
13685 {
13686 return "mftbu %L0\;"
13687 "mftb %0\;"
13688 "mftbu %1\;"
13689 "cmpw %2,%L0,%1\;"
13690 "bne- %2,$-16";
13691 }
13692 }
13693 [(set_attr "length" "20")])
13694
13695 (define_insn "rs6000_mftb_<mode>"
13696 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
13697 (unspec_volatile:GPR [(const_int 0)] UNSPECV_MFTB))]
13698 ""
13699 {
13700 if (TARGET_MFCRF)
13701 return "mfspr %0,268";
13702 else
13703 return "mftb %0";
13704 })
13705
13706 \f
13707 (define_insn "rs6000_mffs"
13708 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
13709 (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFS))]
13710 "TARGET_HARD_FLOAT && TARGET_FPRS"
13711 "mffs %0")
13712
13713 (define_insn "rs6000_mtfsf"
13714 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "i")
13715 (match_operand:DF 1 "gpc_reg_operand" "d")]
13716 UNSPECV_MTFSF)]
13717 "TARGET_HARD_FLOAT && TARGET_FPRS"
13718 "mtfsf %0,%1")
13719
13720 \f
13721 ;; Power8 fusion support for fusing an addis instruction with a D-form load of
13722 ;; a GPR. The addis instruction must be adjacent to the load, and use the same
13723 ;; register that is being loaded. The fused ops must be physically adjacent.
13724
13725 ;; Find cases where the addis that feeds into a load instruction is either used
13726 ;; once or is the same as the target register, and replace it with the fusion
13727 ;; insn
13728
13729 (define_peephole2
13730 [(set (match_operand:P 0 "base_reg_operand" "")
13731 (match_operand:P 1 "fusion_gpr_addis" ""))
13732 (set (match_operand:INT1 2 "base_reg_operand" "")
13733 (match_operand:INT1 3 "fusion_gpr_mem_load" ""))]
13734 "TARGET_P8_FUSION
13735 && fusion_gpr_load_p (operands[0], operands[1], operands[2],
13736 operands[3])"
13737 [(const_int 0)]
13738 {
13739 expand_fusion_gpr_load (operands);
13740 DONE;
13741 })
13742
13743 ;; Fusion insn, created by the define_peephole2 above (and eventually by
13744 ;; reload)
13745
13746 (define_insn "fusion_gpr_load_<mode>"
13747 [(set (match_operand:INT1 0 "base_reg_operand" "=&b")
13748 (unspec:INT1 [(match_operand:INT1 1 "fusion_gpr_mem_combo" "")]
13749 UNSPEC_FUSION_GPR))]
13750 "TARGET_P8_FUSION"
13751 {
13752 return emit_fusion_gpr_load (operands[0], operands[1]);
13753 }
13754 [(set_attr "type" "load")
13755 (set_attr "length" "8")])
13756
13757 \f
13758 ;; Miscellaneous ISA 2.06 (power7) instructions
13759 (define_insn "addg6s"
13760 [(set (match_operand:SI 0 "register_operand" "=r")
13761 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
13762 (match_operand:SI 2 "register_operand" "r")]
13763 UNSPEC_ADDG6S))]
13764 "TARGET_POPCNTD"
13765 "addg6s %0,%1,%2"
13766 [(set_attr "type" "integer")
13767 (set_attr "length" "4")])
13768
13769 (define_insn "cdtbcd"
13770 [(set (match_operand:SI 0 "register_operand" "=r")
13771 (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
13772 UNSPEC_CDTBCD))]
13773 "TARGET_POPCNTD"
13774 "cdtbcd %0,%1"
13775 [(set_attr "type" "integer")
13776 (set_attr "length" "4")])
13777
13778 (define_insn "cbcdtd"
13779 [(set (match_operand:SI 0 "register_operand" "=r")
13780 (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
13781 UNSPEC_CBCDTD))]
13782 "TARGET_POPCNTD"
13783 "cbcdtd %0,%1"
13784 [(set_attr "type" "integer")
13785 (set_attr "length" "4")])
13786
13787 (define_int_iterator UNSPEC_DIV_EXTEND [UNSPEC_DIVE
13788 UNSPEC_DIVEO
13789 UNSPEC_DIVEU
13790 UNSPEC_DIVEUO])
13791
13792 (define_int_attr div_extend [(UNSPEC_DIVE "e")
13793 (UNSPEC_DIVEO "eo")
13794 (UNSPEC_DIVEU "eu")
13795 (UNSPEC_DIVEUO "euo")])
13796
13797 (define_insn "div<div_extend>_<mode>"
13798 [(set (match_operand:GPR 0 "register_operand" "=r")
13799 (unspec:GPR [(match_operand:GPR 1 "register_operand" "r")
13800 (match_operand:GPR 2 "register_operand" "r")]
13801 UNSPEC_DIV_EXTEND))]
13802 "TARGET_POPCNTD"
13803 "div<wd><div_extend> %0,%1,%2"
13804 [(set_attr "type" "div")
13805 (set_attr "size" "<bits>")])
13806
13807 \f
13808 ;; Pack/unpack 128-bit floating point types that take 2 scalar registers
13809
13810 ; Type of the 64-bit part when packing/unpacking 128-bit floating point types
13811 (define_mode_attr FP128_64 [(TF "DF") (TD "DI")])
13812
13813 (define_expand "unpack<mode>"
13814 [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "")
13815 (unspec:<FP128_64>
13816 [(match_operand:FMOVE128 1 "register_operand" "")
13817 (match_operand:QI 2 "const_0_to_1_operand" "")]
13818 UNSPEC_UNPACK_128BIT))]
13819 ""
13820 "")
13821
13822 (define_insn_and_split "unpack<mode>_dm"
13823 [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m,d,r,m")
13824 (unspec:<FP128_64>
13825 [(match_operand:FMOVE128 1 "register_operand" "d,d,r,d,r")
13826 (match_operand:QI 2 "const_0_to_1_operand" "i,i,i,i,i")]
13827 UNSPEC_UNPACK_128BIT))]
13828 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
13829 "#"
13830 "&& reload_completed"
13831 [(set (match_dup 0) (match_dup 3))]
13832 {
13833 unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
13834
13835 if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
13836 {
13837 emit_note (NOTE_INSN_DELETED);
13838 DONE;
13839 }
13840
13841 operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
13842 }
13843 [(set_attr "type" "fp,fpstore,mffgpr,mftgpr,store")
13844 (set_attr "length" "4")])
13845
13846 (define_insn_and_split "unpack<mode>_nodm"
13847 [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m")
13848 (unspec:<FP128_64>
13849 [(match_operand:FMOVE128 1 "register_operand" "d,d")
13850 (match_operand:QI 2 "const_0_to_1_operand" "i,i")]
13851 UNSPEC_UNPACK_128BIT))]
13852 "!TARGET_POWERPC64 || !TARGET_DIRECT_MOVE"
13853 "#"
13854 "&& reload_completed"
13855 [(set (match_dup 0) (match_dup 3))]
13856 {
13857 unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
13858
13859 if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
13860 {
13861 emit_note (NOTE_INSN_DELETED);
13862 DONE;
13863 }
13864
13865 operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
13866 }
13867 [(set_attr "type" "fp,fpstore")
13868 (set_attr "length" "4")])
13869
13870 (define_insn_and_split "pack<mode>"
13871 [(set (match_operand:FMOVE128 0 "register_operand" "=d,&d")
13872 (unspec:FMOVE128
13873 [(match_operand:<FP128_64> 1 "register_operand" "0,d")
13874 (match_operand:<FP128_64> 2 "register_operand" "d,d")]
13875 UNSPEC_PACK_128BIT))]
13876 ""
13877 "@
13878 fmr %L0,%2
13879 #"
13880 "&& reload_completed && REGNO (operands[0]) != REGNO (operands[1])"
13881 [(set (match_dup 3) (match_dup 1))
13882 (set (match_dup 4) (match_dup 2))]
13883 {
13884 unsigned dest_hi = REGNO (operands[0]);
13885 unsigned dest_lo = dest_hi + 1;
13886
13887 gcc_assert (!IN_RANGE (REGNO (operands[1]), dest_hi, dest_lo));
13888 gcc_assert (!IN_RANGE (REGNO (operands[2]), dest_hi, dest_lo));
13889
13890 operands[3] = gen_rtx_REG (<FP128_64>mode, dest_hi);
13891 operands[4] = gen_rtx_REG (<FP128_64>mode, dest_lo);
13892 }
13893 [(set_attr "type" "fp,fp")
13894 (set_attr "length" "4,8")])
13895
13896 (define_insn "unpackv1ti"
13897 [(set (match_operand:DI 0 "register_operand" "=d,d")
13898 (unspec:DI [(match_operand:V1TI 1 "register_operand" "0,wa")
13899 (match_operand:QI 2 "const_0_to_1_operand" "O,i")]
13900 UNSPEC_UNPACK_128BIT))]
13901 "TARGET_VSX"
13902 {
13903 if (REGNO (operands[0]) == REGNO (operands[1]) && INTVAL (operands[2]) == 0)
13904 return ASM_COMMENT_START " xxpermdi to same register";
13905
13906 operands[3] = GEN_INT (INTVAL (operands[2]) == 0 ? 0 : 3);
13907 return "xxpermdi %x0,%x1,%x1,%3";
13908 }
13909 [(set_attr "type" "vecperm")
13910 (set_attr "length" "4")])
13911
13912 (define_insn "packv1ti"
13913 [(set (match_operand:V1TI 0 "register_operand" "=wa")
13914 (unspec:V1TI
13915 [(match_operand:DI 1 "register_operand" "d")
13916 (match_operand:DI 2 "register_operand" "d")]
13917 UNSPEC_PACK_128BIT))]
13918 "TARGET_VSX"
13919 "xxpermdi %x0,%x1,%x2,0"
13920 [(set_attr "type" "vecperm")
13921 (set_attr "length" "4")])
13922
13923 \f
13924
13925 (include "sync.md")
13926 (include "vector.md")
13927 (include "vsx.md")
13928 (include "altivec.md")
13929 (include "spe.md")
13930 (include "dfp.md")
13931 (include "paired.md")
13932 (include "crypto.md")
13933 (include "htm.md")
This page took 0.670112 seconds and 4 git commands to generate.