]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/config/rs6000/rs6000.md
predicates.md (fusion_gpr_mem_load): Move testing for base_reg_operand to be common...
[thirdparty/gcc.git] / gcc / config / rs6000 / rs6000.md
1 ;; Machine description for IBM RISC System 6000 (POWER) for GNU C compiler
2 ;; Copyright (C) 1990-2014 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 compare,
172 cr_logical,delayed_cr,mfcr,mfcrf,mtcr,
173 fpcompare,fp,fpsimple,dmul,sdiv,ddiv,ssqrt,dsqrt,
174 brinc,
175 vecsimple,veccomplex,vecdiv,veccmp,veccmpsimple,vecperm,
176 vecfloat,vecfdiv,vecdouble,mffgpr,mftgpr,crypto,
177 htm"
178 (const_string "integer"))
179
180 ;; What data size does this instruction work on?
181 ;; This is used for insert, mul.
182 (define_attr "size" "8,16,32,64" (const_string "32"))
183
184 ;; Is this instruction record form ("dot", signed compare to 0, writing CR0)?
185 ;; This is used for add, logical, shift, exts, mul.
186 (define_attr "dot" "no,yes" (const_string "no"))
187
188 ;; Does this instruction sign-extend its result?
189 ;; This is used for load insns.
190 (define_attr "sign_extend" "no,yes" (const_string "no"))
191
192 ;; Does this instruction use indexed (that is, reg+reg) addressing?
193 ;; This is used for load and store insns. If operand 0 or 1 is a MEM
194 ;; it is automatically set based on that. If a load or store instruction
195 ;; has fewer than two operands it needs to set this attribute manually
196 ;; or the compiler will crash.
197 (define_attr "indexed" "no,yes"
198 (if_then_else (ior (match_operand 0 "indexed_address_mem")
199 (match_operand 1 "indexed_address_mem"))
200 (const_string "yes")
201 (const_string "no")))
202
203 ;; Does this instruction use update addressing?
204 ;; This is used for load and store insns. See the comments for "indexed".
205 (define_attr "update" "no,yes"
206 (if_then_else (ior (match_operand 0 "update_address_mem")
207 (match_operand 1 "update_address_mem"))
208 (const_string "yes")
209 (const_string "no")))
210
211 ;; Is this instruction using operands[2] as shift amount, and can that be a
212 ;; register?
213 ;; This is used for shift insns.
214 (define_attr "maybe_var_shift" "no,yes" (const_string "no"))
215
216 ;; Is this instruction using a shift amount from a register?
217 ;; This is used for shift insns.
218 (define_attr "var_shift" "no,yes"
219 (if_then_else (and (eq_attr "type" "shift")
220 (eq_attr "maybe_var_shift" "yes"))
221 (if_then_else (match_operand 2 "gpc_reg_operand")
222 (const_string "yes")
223 (const_string "no"))
224 (const_string "no")))
225
226 ;; Define floating point instruction sub-types for use with Xfpu.md
227 (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"))
228
229 ;; Length (in bytes).
230 ; '(pc)' in the following doesn't include the instruction itself; it is
231 ; calculated as if the instruction had zero size.
232 (define_attr "length" ""
233 (if_then_else (eq_attr "type" "branch")
234 (if_then_else (and (ge (minus (match_dup 0) (pc))
235 (const_int -32768))
236 (lt (minus (match_dup 0) (pc))
237 (const_int 32764)))
238 (const_int 4)
239 (const_int 8))
240 (const_int 4)))
241
242 ;; Processor type -- this attribute must exactly match the processor_type
243 ;; enumeration in rs6000-opts.h.
244 (define_attr "cpu"
245 "ppc601,ppc603,ppc604,ppc604e,ppc620,ppc630,
246 ppc750,ppc7400,ppc7450,
247 ppc403,ppc405,ppc440,ppc476,
248 ppc8540,ppc8548,ppce300c2,ppce300c3,ppce500mc,ppce500mc64,ppce5500,ppce6500,
249 power4,power5,power6,power7,power8,
250 rs64a,mpccore,cell,ppca2,titan"
251 (const (symbol_ref "rs6000_cpu_attr")))
252
253
254 ;; If this instruction is microcoded on the CELL processor
255 ; The default for load extended, the recorded instructions and rotate/shifts by a variable is always microcoded
256 (define_attr "cell_micro" "not,conditional,always"
257 (if_then_else (ior (eq_attr "type" "compare")
258 (and (eq_attr "type" "shift,exts,mul")
259 (eq_attr "dot" "yes"))
260 (and (eq_attr "type" "load")
261 (eq_attr "sign_extend" "yes"))
262 (and (eq_attr "type" "shift")
263 (eq_attr "var_shift" "yes")))
264 (const_string "always")
265 (const_string "not")))
266
267 (automata_option "ndfa")
268
269 (include "rs64.md")
270 (include "mpc.md")
271 (include "40x.md")
272 (include "440.md")
273 (include "476.md")
274 (include "601.md")
275 (include "603.md")
276 (include "6xx.md")
277 (include "7xx.md")
278 (include "7450.md")
279 (include "8540.md")
280 (include "e300c2c3.md")
281 (include "e500mc.md")
282 (include "e500mc64.md")
283 (include "e5500.md")
284 (include "e6500.md")
285 (include "power4.md")
286 (include "power5.md")
287 (include "power6.md")
288 (include "power7.md")
289 (include "power8.md")
290 (include "cell.md")
291 (include "xfpu.md")
292 (include "a2.md")
293 (include "titan.md")
294
295 (include "predicates.md")
296 (include "constraints.md")
297
298 (include "darwin.md")
299
300 \f
301 ;; Mode iterators
302
303 ; This mode iterator allows :GPR to be used to indicate the allowable size
304 ; of whole values in GPRs.
305 (define_mode_iterator GPR [SI (DI "TARGET_POWERPC64")])
306
307 ; Any supported integer mode.
308 (define_mode_iterator INT [QI HI SI DI TI PTI])
309
310 ; Any supported integer mode that fits in one register.
311 (define_mode_iterator INT1 [QI HI SI (DI "TARGET_POWERPC64")])
312
313 ; Everything we can extend QImode to.
314 (define_mode_iterator EXTQI [HI SI (DI "TARGET_POWERPC64")])
315
316 ; Everything we can extend HImode to.
317 (define_mode_iterator EXTHI [SI (DI "TARGET_POWERPC64")])
318
319 ; Everything we can extend SImode to.
320 (define_mode_iterator EXTSI [(DI "TARGET_POWERPC64")])
321
322 ; QImode or HImode for small atomic ops
323 (define_mode_iterator QHI [QI HI])
324
325 ; HImode or SImode for sign extended fusion ops
326 (define_mode_iterator HSI [HI SI])
327
328 ; SImode or DImode, even if DImode doesn't fit in GPRs.
329 (define_mode_iterator SDI [SI DI])
330
331 ; The size of a pointer. Also, the size of the value that a record-condition
332 ; (one with a '.') will compare; and the size used for arithmetic carries.
333 (define_mode_iterator P [(SI "TARGET_32BIT") (DI "TARGET_64BIT")])
334
335 ; Iterator to add PTImode along with TImode (TImode can go in VSX registers,
336 ; PTImode is GPR only)
337 (define_mode_iterator TI2 [TI PTI])
338
339 ; Any hardware-supported floating-point mode
340 (define_mode_iterator FP [
341 (SF "TARGET_HARD_FLOAT
342 && ((TARGET_FPRS && TARGET_SINGLE_FLOAT) || TARGET_E500_SINGLE)")
343 (DF "TARGET_HARD_FLOAT
344 && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)")
345 (TF "!TARGET_IEEEQUAD
346 && TARGET_HARD_FLOAT
347 && (TARGET_FPRS || TARGET_E500_DOUBLE)
348 && TARGET_LONG_DOUBLE_128")
349 (DD "TARGET_DFP")
350 (TD "TARGET_DFP")])
351
352 ; Any fma capable floating-point mode.
353 (define_mode_iterator FMA_F [
354 (SF "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT")
355 (DF "(TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
356 || VECTOR_UNIT_VSX_P (DFmode)")
357 (V2SF "TARGET_PAIRED_FLOAT")
358 (V4SF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)")
359 (V2DF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V2DFmode)")
360 ])
361
362 ; Floating point move iterators to combine binary and decimal moves
363 (define_mode_iterator FMOVE32 [SF SD])
364 (define_mode_iterator FMOVE64 [DF DD])
365 (define_mode_iterator FMOVE64X [DI DF DD])
366 (define_mode_iterator FMOVE128 [(TF "!TARGET_IEEEQUAD && TARGET_LONG_DOUBLE_128")
367 (TD "TARGET_HARD_FLOAT && TARGET_FPRS")])
368
369 ; Iterators for 128 bit types for direct move
370 (define_mode_iterator FMOVE128_GPR [(TI "TARGET_VSX_TIMODE")
371 (V16QI "")
372 (V8HI "")
373 (V4SI "")
374 (V4SF "")
375 (V2DI "")
376 (V2DF "")
377 (V1TI "")])
378
379 ; Whether a floating point move is ok, don't allow SD without hardware FP
380 (define_mode_attr fmove_ok [(SF "")
381 (DF "")
382 (SD "TARGET_HARD_FLOAT && TARGET_FPRS")
383 (DD "")])
384
385 ; Convert REAL_VALUE to the appropriate bits
386 (define_mode_attr real_value_to_target [(SF "REAL_VALUE_TO_TARGET_SINGLE")
387 (DF "REAL_VALUE_TO_TARGET_DOUBLE")
388 (SD "REAL_VALUE_TO_TARGET_DECIMAL32")
389 (DD "REAL_VALUE_TO_TARGET_DECIMAL64")])
390
391 ; Definitions for load to 32-bit fpr register
392 (define_mode_attr f32_lr [(SF "f") (SD "wz")])
393 (define_mode_attr f32_lm [(SF "m") (SD "Z")])
394 (define_mode_attr f32_li [(SF "lfs%U1%X1 %0,%1") (SD "lfiwzx %0,%y1")])
395 (define_mode_attr f32_lv [(SF "lxsspx %x0,%y1") (SD "lxsiwzx %x0,%y1")])
396
397 ; Definitions for store from 32-bit fpr register
398 (define_mode_attr f32_sr [(SF "f") (SD "wx")])
399 (define_mode_attr f32_sm [(SF "m") (SD "Z")])
400 (define_mode_attr f32_si [(SF "stfs%U0%X0 %1,%0") (SD "stfiwx %1,%y0")])
401 (define_mode_attr f32_sv [(SF "stxsspx %x1,%y0") (SD "stxsiwzx %x1,%y0")])
402
403 ; Definitions for 32-bit fpr direct move
404 (define_mode_attr f32_dm [(SF "wn") (SD "wh")])
405
406 ; These modes do not fit in integer registers in 32-bit mode.
407 ; but on e500v2, the gpr are 64 bit registers
408 (define_mode_iterator DIFD [DI (DF "!TARGET_E500_DOUBLE") DD])
409
410 ; Iterator for reciprocal estimate instructions
411 (define_mode_iterator RECIPF [SF DF V4SF V2DF])
412
413 ; Iterator for just SF/DF
414 (define_mode_iterator SFDF [SF DF])
415
416 ; SF/DF suffix for traditional floating instructions
417 (define_mode_attr Ftrad [(SF "s") (DF "")])
418
419 ; SF/DF suffix for VSX instructions
420 (define_mode_attr Fvsx [(SF "sp") (DF "dp")])
421
422 ; SF/DF constraint for arithmetic on traditional floating point registers
423 (define_mode_attr Ff [(SF "f") (DF "d")])
424
425 ; SF/DF constraint for arithmetic on VSX registers
426 (define_mode_attr Fv [(SF "wy") (DF "ws")])
427
428 ; s/d suffix for things like fp_addsub_s/fp_addsub_d
429 (define_mode_attr Fs [(SF "s") (DF "d")])
430
431 ; FRE/FRES support
432 (define_mode_attr Ffre [(SF "fres") (DF "fre")])
433 (define_mode_attr FFRE [(SF "FRES") (DF "FRE")])
434
435 ; Conditional returns.
436 (define_code_iterator any_return [return simple_return])
437 (define_code_attr return_pred [(return "direct_return ()")
438 (simple_return "1")])
439 (define_code_attr return_str [(return "") (simple_return "simple_")])
440
441 ; Signed/unsigned variants of ops.
442 (define_code_iterator any_extend [sign_extend zero_extend])
443 (define_code_attr u [(sign_extend "") (zero_extend "u")])
444 (define_code_attr su [(sign_extend "s") (zero_extend "u")])
445
446 ; Various instructions that come in SI and DI forms.
447 ; A generic w/d attribute, for things like cmpw/cmpd.
448 (define_mode_attr wd [(QI "b")
449 (HI "h")
450 (SI "w")
451 (DI "d")
452 (V16QI "b")
453 (V8HI "h")
454 (V4SI "w")
455 (V2DI "d")])
456
457 ;; How many bits in this mode?
458 (define_mode_attr bits [(QI "8") (HI "16") (SI "32") (DI "64")])
459
460 ; DImode bits
461 (define_mode_attr dbits [(QI "56") (HI "48") (SI "32")])
462
463 ;; ISEL/ISEL64 target selection
464 (define_mode_attr sel [(SI "") (DI "64")])
465
466 ;; Bitmask for shift instructions
467 (define_mode_attr hH [(SI "h") (DI "H")])
468
469 ;; A mode twice the size of the given mode
470 (define_mode_attr dmode [(SI "di") (DI "ti")])
471 (define_mode_attr DMODE [(SI "DI") (DI "TI")])
472
473 ;; Suffix for reload patterns
474 (define_mode_attr ptrsize [(SI "32bit")
475 (DI "64bit")])
476
477 (define_mode_attr tptrsize [(SI "TARGET_32BIT")
478 (DI "TARGET_64BIT")])
479
480 (define_mode_attr mptrsize [(SI "si")
481 (DI "di")])
482
483 (define_mode_attr ptrload [(SI "lwz")
484 (DI "ld")])
485
486 (define_mode_attr ptrm [(SI "m")
487 (DI "Y")])
488
489 (define_mode_attr rreg [(SF "f")
490 (DF "ws")
491 (TF "f")
492 (TD "f")
493 (V4SF "wf")
494 (V2DF "wd")])
495
496 (define_mode_attr rreg2 [(SF "f")
497 (DF "d")])
498
499 (define_mode_attr SI_CONVERT_FP [(SF "TARGET_FCFIDS")
500 (DF "TARGET_FCFID")])
501
502 (define_mode_attr E500_CONVERT [(SF "!TARGET_FPRS")
503 (DF "TARGET_E500_DOUBLE")])
504
505 (define_mode_attr TARGET_FLOAT [(SF "TARGET_SINGLE_FLOAT")
506 (DF "TARGET_DOUBLE_FLOAT")])
507
508 ;; Mode iterator for logical operations on 128-bit types
509 (define_mode_iterator BOOL_128 [TI
510 PTI
511 (V16QI "TARGET_ALTIVEC")
512 (V8HI "TARGET_ALTIVEC")
513 (V4SI "TARGET_ALTIVEC")
514 (V4SF "TARGET_ALTIVEC")
515 (V2DI "TARGET_ALTIVEC")
516 (V2DF "TARGET_ALTIVEC")
517 (V1TI "TARGET_ALTIVEC")])
518
519 ;; For the GPRs we use 3 constraints for register outputs, two that are the
520 ;; same as the output register, and a third where the output register is an
521 ;; early clobber, so we don't have to deal with register overlaps. For the
522 ;; vector types, we prefer to use the vector registers. For TI mode, allow
523 ;; either.
524
525 ;; Mode attribute for boolean operation register constraints for output
526 (define_mode_attr BOOL_REGS_OUTPUT [(TI "&r,r,r,wa,v")
527 (PTI "&r,r,r")
528 (V16QI "wa,v,&?r,?r,?r")
529 (V8HI "wa,v,&?r,?r,?r")
530 (V4SI "wa,v,&?r,?r,?r")
531 (V4SF "wa,v,&?r,?r,?r")
532 (V2DI "wa,v,&?r,?r,?r")
533 (V2DF "wa,v,&?r,?r,?r")
534 (V1TI "wa,v,&?r,?r,?r")])
535
536 ;; Mode attribute for boolean operation register constraints for operand1
537 (define_mode_attr BOOL_REGS_OP1 [(TI "r,0,r,wa,v")
538 (PTI "r,0,r")
539 (V16QI "wa,v,r,0,r")
540 (V8HI "wa,v,r,0,r")
541 (V4SI "wa,v,r,0,r")
542 (V4SF "wa,v,r,0,r")
543 (V2DI "wa,v,r,0,r")
544 (V2DF "wa,v,r,0,r")
545 (V1TI "wa,v,r,0,r")])
546
547 ;; Mode attribute for boolean operation register constraints for operand2
548 (define_mode_attr BOOL_REGS_OP2 [(TI "r,r,0,wa,v")
549 (PTI "r,r,0")
550 (V16QI "wa,v,r,r,0")
551 (V8HI "wa,v,r,r,0")
552 (V4SI "wa,v,r,r,0")
553 (V4SF "wa,v,r,r,0")
554 (V2DI "wa,v,r,r,0")
555 (V2DF "wa,v,r,r,0")
556 (V1TI "wa,v,r,r,0")])
557
558 ;; Mode attribute for boolean operation register constraints for operand1
559 ;; for one_cmpl. To simplify things, we repeat the constraint where 0
560 ;; is used for operand1 or operand2
561 (define_mode_attr BOOL_REGS_UNARY [(TI "r,0,0,wa,v")
562 (PTI "r,0,0")
563 (V16QI "wa,v,r,0,0")
564 (V8HI "wa,v,r,0,0")
565 (V4SI "wa,v,r,0,0")
566 (V4SF "wa,v,r,0,0")
567 (V2DI "wa,v,r,0,0")
568 (V2DF "wa,v,r,0,0")
569 (V1TI "wa,v,r,0,0")])
570 \f
571 ;; Start with fixed-point load and store insns. Here we put only the more
572 ;; complex forms. Basic data transfer is done later.
573
574 (define_insn "zero_extendqi<mode>2"
575 [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
576 (zero_extend:EXTQI (match_operand:QI 1 "reg_or_mem_operand" "m,r")))]
577 ""
578 "@
579 lbz%U1%X1 %0,%1
580 rlwinm %0,%1,0,0xff"
581 [(set_attr "type" "load,shift")])
582
583 (define_insn_and_split "*zero_extendqi<mode>2_dot"
584 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
585 (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
586 (const_int 0)))
587 (clobber (match_scratch:EXTQI 0 "=r,r"))]
588 "rs6000_gen_cell_microcode"
589 "@
590 andi. %0,%1,0xff
591 #"
592 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
593 [(set (match_dup 0)
594 (zero_extend:EXTQI (match_dup 1)))
595 (set (match_dup 2)
596 (compare:CC (match_dup 0)
597 (const_int 0)))]
598 ""
599 [(set_attr "type" "logical")
600 (set_attr "dot" "yes")
601 (set_attr "length" "4,8")])
602
603 (define_insn_and_split "*zero_extendqi<mode>2_dot2"
604 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
605 (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
606 (const_int 0)))
607 (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
608 (zero_extend:EXTQI (match_dup 1)))]
609 "rs6000_gen_cell_microcode"
610 "@
611 andi. %0,%1,0xff
612 #"
613 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
614 [(set (match_dup 0)
615 (zero_extend:EXTQI (match_dup 1)))
616 (set (match_dup 2)
617 (compare:CC (match_dup 0)
618 (const_int 0)))]
619 ""
620 [(set_attr "type" "logical")
621 (set_attr "dot" "yes")
622 (set_attr "length" "4,8")])
623
624
625 (define_insn "zero_extendhi<mode>2"
626 [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
627 (zero_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r")))]
628 ""
629 "@
630 lhz%U1%X1 %0,%1
631 rlwinm %0,%1,0,0xffff"
632 [(set_attr "type" "load,shift")])
633
634 (define_insn_and_split "*zero_extendhi<mode>2_dot"
635 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
636 (compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
637 (const_int 0)))
638 (clobber (match_scratch:EXTHI 0 "=r,r"))]
639 "rs6000_gen_cell_microcode"
640 "@
641 andi. %0,%1,0xffff
642 #"
643 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
644 [(set (match_dup 0)
645 (zero_extend:EXTHI (match_dup 1)))
646 (set (match_dup 2)
647 (compare:CC (match_dup 0)
648 (const_int 0)))]
649 ""
650 [(set_attr "type" "logical")
651 (set_attr "dot" "yes")
652 (set_attr "length" "4,8")])
653
654 (define_insn_and_split "*zero_extendhi<mode>2_dot2"
655 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
656 (compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
657 (const_int 0)))
658 (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
659 (zero_extend:EXTHI (match_dup 1)))]
660 "rs6000_gen_cell_microcode"
661 "@
662 andi. %0,%1,0xffff
663 #"
664 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
665 [(set (match_dup 0)
666 (zero_extend:EXTHI (match_dup 1)))
667 (set (match_dup 2)
668 (compare:CC (match_dup 0)
669 (const_int 0)))]
670 ""
671 [(set_attr "type" "logical")
672 (set_attr "dot" "yes")
673 (set_attr "length" "4,8")])
674
675
676 (define_insn "zero_extendsi<mode>2"
677 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r,??wj,!wz,!wu")
678 (zero_extend:EXTSI (match_operand:SI 1 "reg_or_mem_operand" "m,r,r,Z,Z")))]
679 ""
680 "@
681 lwz%U1%X1 %0,%1
682 rldicl %0,%1,0,32
683 mtvsrwz %x0,%1
684 lfiwzx %0,%y1
685 lxsiwzx %x0,%y1"
686 [(set_attr "type" "load,shift,mffgpr,fpload,fpload")])
687
688 (define_insn_and_split "*zero_extendsi<mode>2_dot"
689 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
690 (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
691 (const_int 0)))
692 (clobber (match_scratch:EXTSI 0 "=r,r"))]
693 "rs6000_gen_cell_microcode"
694 "@
695 rldicl. %0,%1,0,32
696 #"
697 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
698 [(set (match_dup 0)
699 (zero_extend:DI (match_dup 1)))
700 (set (match_dup 2)
701 (compare:CC (match_dup 0)
702 (const_int 0)))]
703 ""
704 [(set_attr "type" "shift")
705 (set_attr "dot" "yes")
706 (set_attr "length" "4,8")])
707
708 (define_insn_and_split "*zero_extendsi<mode>2_dot2"
709 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
710 (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
711 (const_int 0)))
712 (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
713 (zero_extend:EXTSI (match_dup 1)))]
714 "rs6000_gen_cell_microcode"
715 "@
716 rldicl. %0,%1,0,32
717 #"
718 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
719 [(set (match_dup 0)
720 (zero_extend:EXTSI (match_dup 1)))
721 (set (match_dup 2)
722 (compare:CC (match_dup 0)
723 (const_int 0)))]
724 ""
725 [(set_attr "type" "shift")
726 (set_attr "dot" "yes")
727 (set_attr "length" "4,8")])
728
729
730 (define_insn "extendqi<mode>2"
731 [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r")
732 (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r")))]
733 ""
734 "extsb %0,%1"
735 [(set_attr "type" "exts")])
736
737 (define_insn_and_split "*extendqi<mode>2_dot"
738 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
739 (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
740 (const_int 0)))
741 (clobber (match_scratch:EXTQI 0 "=r,r"))]
742 "rs6000_gen_cell_microcode"
743 "@
744 extsb. %0,%1
745 #"
746 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
747 [(set (match_dup 0)
748 (sign_extend:EXTQI (match_dup 1)))
749 (set (match_dup 2)
750 (compare:CC (match_dup 0)
751 (const_int 0)))]
752 ""
753 [(set_attr "type" "exts")
754 (set_attr "dot" "yes")
755 (set_attr "length" "4,8")])
756
757 (define_insn_and_split "*extendqi<mode>2_dot2"
758 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
759 (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
760 (const_int 0)))
761 (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
762 (sign_extend:EXTQI (match_dup 1)))]
763 "rs6000_gen_cell_microcode"
764 "@
765 extsb. %0,%1
766 #"
767 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
768 [(set (match_dup 0)
769 (sign_extend:EXTQI (match_dup 1)))
770 (set (match_dup 2)
771 (compare:CC (match_dup 0)
772 (const_int 0)))]
773 ""
774 [(set_attr "type" "exts")
775 (set_attr "dot" "yes")
776 (set_attr "length" "4,8")])
777
778
779 (define_expand "extendhi<mode>2"
780 [(set (match_operand:EXTHI 0 "gpc_reg_operand" "")
781 (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "")))]
782 ""
783 "")
784
785 (define_insn "*extendhi<mode>2"
786 [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
787 (sign_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r")))]
788 "rs6000_gen_cell_microcode"
789 "@
790 lha%U1%X1 %0,%1
791 extsh %0,%1"
792 [(set_attr "type" "load,exts")
793 (set_attr "sign_extend" "yes")])
794
795 (define_insn "*extendhi<mode>2_noload"
796 [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r")
797 (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r")))]
798 "!rs6000_gen_cell_microcode"
799 "extsh %0,%1"
800 [(set_attr "type" "exts")])
801
802 (define_insn_and_split "*extendhi<mode>2_dot"
803 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
804 (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
805 (const_int 0)))
806 (clobber (match_scratch:EXTHI 0 "=r,r"))]
807 "rs6000_gen_cell_microcode"
808 "@
809 extsh. %0,%1
810 #"
811 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
812 [(set (match_dup 0)
813 (sign_extend:EXTHI (match_dup 1)))
814 (set (match_dup 2)
815 (compare:CC (match_dup 0)
816 (const_int 0)))]
817 ""
818 [(set_attr "type" "exts")
819 (set_attr "dot" "yes")
820 (set_attr "length" "4,8")])
821
822 (define_insn_and_split "*extendhi<mode>2_dot2"
823 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
824 (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
825 (const_int 0)))
826 (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
827 (sign_extend:EXTHI (match_dup 1)))]
828 "rs6000_gen_cell_microcode"
829 "@
830 extsh. %0,%1
831 #"
832 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
833 [(set (match_dup 0)
834 (sign_extend:EXTHI (match_dup 1)))
835 (set (match_dup 2)
836 (compare:CC (match_dup 0)
837 (const_int 0)))]
838 ""
839 [(set_attr "type" "exts")
840 (set_attr "dot" "yes")
841 (set_attr "length" "4,8")])
842
843
844 (define_insn "extendsi<mode>2"
845 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r,??wj,!wl,!wu")
846 (sign_extend:EXTSI (match_operand:SI 1 "lwa_operand" "Y,r,r,Z,Z")))]
847 ""
848 "@
849 lwa%U1%X1 %0,%1
850 extsw %0,%1
851 mtvsrwa %x0,%1
852 lfiwax %0,%y1
853 lxsiwax %x0,%y1"
854 [(set_attr "type" "load,exts,mffgpr,fpload,fpload")
855 (set_attr "sign_extend" "yes")])
856
857 (define_insn_and_split "*extendsi<mode>2_dot"
858 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
859 (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
860 (const_int 0)))
861 (clobber (match_scratch:EXTSI 0 "=r,r"))]
862 "rs6000_gen_cell_microcode"
863 "@
864 extsw. %0,%1
865 #"
866 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
867 [(set (match_dup 0)
868 (sign_extend:EXTSI (match_dup 1)))
869 (set (match_dup 2)
870 (compare:CC (match_dup 0)
871 (const_int 0)))]
872 ""
873 [(set_attr "type" "exts")
874 (set_attr "dot" "yes")
875 (set_attr "length" "4,8")])
876
877 (define_insn_and_split "*extendsi<mode>2_dot2"
878 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
879 (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
880 (const_int 0)))
881 (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
882 (sign_extend:EXTSI (match_dup 1)))]
883 "rs6000_gen_cell_microcode"
884 "@
885 extsw. %0,%1
886 #"
887 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
888 [(set (match_dup 0)
889 (sign_extend:EXTSI (match_dup 1)))
890 (set (match_dup 2)
891 (compare:CC (match_dup 0)
892 (const_int 0)))]
893 ""
894 [(set_attr "type" "exts")
895 (set_attr "dot" "yes")
896 (set_attr "length" "4,8")])
897 \f
898 ;; IBM 405, 440, 464 and 476 half-word multiplication operations.
899
900 (define_insn "*macchwc"
901 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
902 (compare:CC (plus:SI (mult:SI (ashiftrt:SI
903 (match_operand:SI 2 "gpc_reg_operand" "r")
904 (const_int 16))
905 (sign_extend:SI
906 (match_operand:HI 1 "gpc_reg_operand" "r")))
907 (match_operand:SI 4 "gpc_reg_operand" "0"))
908 (const_int 0)))
909 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
910 (plus:SI (mult:SI (ashiftrt:SI
911 (match_dup 2)
912 (const_int 16))
913 (sign_extend:SI
914 (match_dup 1)))
915 (match_dup 4)))]
916 "TARGET_MULHW"
917 "macchw. %0,%1,%2"
918 [(set_attr "type" "halfmul")])
919
920 (define_insn "*macchw"
921 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
922 (plus:SI (mult:SI (ashiftrt:SI
923 (match_operand:SI 2 "gpc_reg_operand" "r")
924 (const_int 16))
925 (sign_extend:SI
926 (match_operand:HI 1 "gpc_reg_operand" "r")))
927 (match_operand:SI 3 "gpc_reg_operand" "0")))]
928 "TARGET_MULHW"
929 "macchw %0,%1,%2"
930 [(set_attr "type" "halfmul")])
931
932 (define_insn "*macchwuc"
933 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
934 (compare:CC (plus:SI (mult:SI (lshiftrt:SI
935 (match_operand:SI 2 "gpc_reg_operand" "r")
936 (const_int 16))
937 (zero_extend:SI
938 (match_operand:HI 1 "gpc_reg_operand" "r")))
939 (match_operand:SI 4 "gpc_reg_operand" "0"))
940 (const_int 0)))
941 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
942 (plus:SI (mult:SI (lshiftrt:SI
943 (match_dup 2)
944 (const_int 16))
945 (zero_extend:SI
946 (match_dup 1)))
947 (match_dup 4)))]
948 "TARGET_MULHW"
949 "macchwu. %0,%1,%2"
950 [(set_attr "type" "halfmul")])
951
952 (define_insn "*macchwu"
953 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
954 (plus:SI (mult:SI (lshiftrt:SI
955 (match_operand:SI 2 "gpc_reg_operand" "r")
956 (const_int 16))
957 (zero_extend:SI
958 (match_operand:HI 1 "gpc_reg_operand" "r")))
959 (match_operand:SI 3 "gpc_reg_operand" "0")))]
960 "TARGET_MULHW"
961 "macchwu %0,%1,%2"
962 [(set_attr "type" "halfmul")])
963
964 (define_insn "*machhwc"
965 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
966 (compare:CC (plus:SI (mult:SI (ashiftrt:SI
967 (match_operand:SI 1 "gpc_reg_operand" "%r")
968 (const_int 16))
969 (ashiftrt:SI
970 (match_operand:SI 2 "gpc_reg_operand" "r")
971 (const_int 16)))
972 (match_operand:SI 4 "gpc_reg_operand" "0"))
973 (const_int 0)))
974 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
975 (plus:SI (mult:SI (ashiftrt:SI
976 (match_dup 1)
977 (const_int 16))
978 (ashiftrt:SI
979 (match_dup 2)
980 (const_int 16)))
981 (match_dup 4)))]
982 "TARGET_MULHW"
983 "machhw. %0,%1,%2"
984 [(set_attr "type" "halfmul")])
985
986 (define_insn "*machhw"
987 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
988 (plus:SI (mult:SI (ashiftrt:SI
989 (match_operand:SI 1 "gpc_reg_operand" "%r")
990 (const_int 16))
991 (ashiftrt:SI
992 (match_operand:SI 2 "gpc_reg_operand" "r")
993 (const_int 16)))
994 (match_operand:SI 3 "gpc_reg_operand" "0")))]
995 "TARGET_MULHW"
996 "machhw %0,%1,%2"
997 [(set_attr "type" "halfmul")])
998
999 (define_insn "*machhwuc"
1000 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1001 (compare:CC (plus:SI (mult:SI (lshiftrt:SI
1002 (match_operand:SI 1 "gpc_reg_operand" "%r")
1003 (const_int 16))
1004 (lshiftrt:SI
1005 (match_operand:SI 2 "gpc_reg_operand" "r")
1006 (const_int 16)))
1007 (match_operand:SI 4 "gpc_reg_operand" "0"))
1008 (const_int 0)))
1009 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1010 (plus:SI (mult:SI (lshiftrt:SI
1011 (match_dup 1)
1012 (const_int 16))
1013 (lshiftrt:SI
1014 (match_dup 2)
1015 (const_int 16)))
1016 (match_dup 4)))]
1017 "TARGET_MULHW"
1018 "machhwu. %0,%1,%2"
1019 [(set_attr "type" "halfmul")])
1020
1021 (define_insn "*machhwu"
1022 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1023 (plus:SI (mult:SI (lshiftrt:SI
1024 (match_operand:SI 1 "gpc_reg_operand" "%r")
1025 (const_int 16))
1026 (lshiftrt:SI
1027 (match_operand:SI 2 "gpc_reg_operand" "r")
1028 (const_int 16)))
1029 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1030 "TARGET_MULHW"
1031 "machhwu %0,%1,%2"
1032 [(set_attr "type" "halfmul")])
1033
1034 (define_insn "*maclhwc"
1035 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1036 (compare:CC (plus:SI (mult:SI (sign_extend:SI
1037 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1038 (sign_extend:SI
1039 (match_operand:HI 2 "gpc_reg_operand" "r")))
1040 (match_operand:SI 4 "gpc_reg_operand" "0"))
1041 (const_int 0)))
1042 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1043 (plus:SI (mult:SI (sign_extend:SI
1044 (match_dup 1))
1045 (sign_extend:SI
1046 (match_dup 2)))
1047 (match_dup 4)))]
1048 "TARGET_MULHW"
1049 "maclhw. %0,%1,%2"
1050 [(set_attr "type" "halfmul")])
1051
1052 (define_insn "*maclhw"
1053 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1054 (plus:SI (mult:SI (sign_extend:SI
1055 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1056 (sign_extend:SI
1057 (match_operand:HI 2 "gpc_reg_operand" "r")))
1058 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1059 "TARGET_MULHW"
1060 "maclhw %0,%1,%2"
1061 [(set_attr "type" "halfmul")])
1062
1063 (define_insn "*maclhwuc"
1064 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1065 (compare:CC (plus:SI (mult:SI (zero_extend:SI
1066 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1067 (zero_extend:SI
1068 (match_operand:HI 2 "gpc_reg_operand" "r")))
1069 (match_operand:SI 4 "gpc_reg_operand" "0"))
1070 (const_int 0)))
1071 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1072 (plus:SI (mult:SI (zero_extend:SI
1073 (match_dup 1))
1074 (zero_extend:SI
1075 (match_dup 2)))
1076 (match_dup 4)))]
1077 "TARGET_MULHW"
1078 "maclhwu. %0,%1,%2"
1079 [(set_attr "type" "halfmul")])
1080
1081 (define_insn "*maclhwu"
1082 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1083 (plus:SI (mult:SI (zero_extend:SI
1084 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1085 (zero_extend:SI
1086 (match_operand:HI 2 "gpc_reg_operand" "r")))
1087 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1088 "TARGET_MULHW"
1089 "maclhwu %0,%1,%2"
1090 [(set_attr "type" "halfmul")])
1091
1092 (define_insn "*nmacchwc"
1093 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1094 (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1095 (mult:SI (ashiftrt:SI
1096 (match_operand:SI 2 "gpc_reg_operand" "r")
1097 (const_int 16))
1098 (sign_extend:SI
1099 (match_operand:HI 1 "gpc_reg_operand" "r"))))
1100 (const_int 0)))
1101 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1102 (minus:SI (match_dup 4)
1103 (mult:SI (ashiftrt:SI
1104 (match_dup 2)
1105 (const_int 16))
1106 (sign_extend:SI
1107 (match_dup 1)))))]
1108 "TARGET_MULHW"
1109 "nmacchw. %0,%1,%2"
1110 [(set_attr "type" "halfmul")])
1111
1112 (define_insn "*nmacchw"
1113 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1114 (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1115 (mult:SI (ashiftrt:SI
1116 (match_operand:SI 2 "gpc_reg_operand" "r")
1117 (const_int 16))
1118 (sign_extend:SI
1119 (match_operand:HI 1 "gpc_reg_operand" "r")))))]
1120 "TARGET_MULHW"
1121 "nmacchw %0,%1,%2"
1122 [(set_attr "type" "halfmul")])
1123
1124 (define_insn "*nmachhwc"
1125 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1126 (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1127 (mult:SI (ashiftrt:SI
1128 (match_operand:SI 1 "gpc_reg_operand" "%r")
1129 (const_int 16))
1130 (ashiftrt:SI
1131 (match_operand:SI 2 "gpc_reg_operand" "r")
1132 (const_int 16))))
1133 (const_int 0)))
1134 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1135 (minus:SI (match_dup 4)
1136 (mult:SI (ashiftrt:SI
1137 (match_dup 1)
1138 (const_int 16))
1139 (ashiftrt:SI
1140 (match_dup 2)
1141 (const_int 16)))))]
1142 "TARGET_MULHW"
1143 "nmachhw. %0,%1,%2"
1144 [(set_attr "type" "halfmul")])
1145
1146 (define_insn "*nmachhw"
1147 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1148 (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1149 (mult:SI (ashiftrt:SI
1150 (match_operand:SI 1 "gpc_reg_operand" "%r")
1151 (const_int 16))
1152 (ashiftrt:SI
1153 (match_operand:SI 2 "gpc_reg_operand" "r")
1154 (const_int 16)))))]
1155 "TARGET_MULHW"
1156 "nmachhw %0,%1,%2"
1157 [(set_attr "type" "halfmul")])
1158
1159 (define_insn "*nmaclhwc"
1160 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1161 (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1162 (mult:SI (sign_extend:SI
1163 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1164 (sign_extend:SI
1165 (match_operand:HI 2 "gpc_reg_operand" "r"))))
1166 (const_int 0)))
1167 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1168 (minus:SI (match_dup 4)
1169 (mult:SI (sign_extend:SI
1170 (match_dup 1))
1171 (sign_extend:SI
1172 (match_dup 2)))))]
1173 "TARGET_MULHW"
1174 "nmaclhw. %0,%1,%2"
1175 [(set_attr "type" "halfmul")])
1176
1177 (define_insn "*nmaclhw"
1178 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1179 (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1180 (mult:SI (sign_extend:SI
1181 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1182 (sign_extend:SI
1183 (match_operand:HI 2 "gpc_reg_operand" "r")))))]
1184 "TARGET_MULHW"
1185 "nmaclhw %0,%1,%2"
1186 [(set_attr "type" "halfmul")])
1187
1188 (define_insn "*mulchwc"
1189 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1190 (compare:CC (mult:SI (ashiftrt:SI
1191 (match_operand:SI 2 "gpc_reg_operand" "r")
1192 (const_int 16))
1193 (sign_extend:SI
1194 (match_operand:HI 1 "gpc_reg_operand" "r")))
1195 (const_int 0)))
1196 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1197 (mult:SI (ashiftrt:SI
1198 (match_dup 2)
1199 (const_int 16))
1200 (sign_extend:SI
1201 (match_dup 1))))]
1202 "TARGET_MULHW"
1203 "mulchw. %0,%1,%2"
1204 [(set_attr "type" "halfmul")])
1205
1206 (define_insn "*mulchw"
1207 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1208 (mult:SI (ashiftrt:SI
1209 (match_operand:SI 2 "gpc_reg_operand" "r")
1210 (const_int 16))
1211 (sign_extend:SI
1212 (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1213 "TARGET_MULHW"
1214 "mulchw %0,%1,%2"
1215 [(set_attr "type" "halfmul")])
1216
1217 (define_insn "*mulchwuc"
1218 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1219 (compare:CC (mult:SI (lshiftrt:SI
1220 (match_operand:SI 2 "gpc_reg_operand" "r")
1221 (const_int 16))
1222 (zero_extend:SI
1223 (match_operand:HI 1 "gpc_reg_operand" "r")))
1224 (const_int 0)))
1225 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1226 (mult:SI (lshiftrt:SI
1227 (match_dup 2)
1228 (const_int 16))
1229 (zero_extend:SI
1230 (match_dup 1))))]
1231 "TARGET_MULHW"
1232 "mulchwu. %0,%1,%2"
1233 [(set_attr "type" "halfmul")])
1234
1235 (define_insn "*mulchwu"
1236 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1237 (mult:SI (lshiftrt:SI
1238 (match_operand:SI 2 "gpc_reg_operand" "r")
1239 (const_int 16))
1240 (zero_extend:SI
1241 (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1242 "TARGET_MULHW"
1243 "mulchwu %0,%1,%2"
1244 [(set_attr "type" "halfmul")])
1245
1246 (define_insn "*mulhhwc"
1247 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1248 (compare:CC (mult:SI (ashiftrt:SI
1249 (match_operand:SI 1 "gpc_reg_operand" "%r")
1250 (const_int 16))
1251 (ashiftrt:SI
1252 (match_operand:SI 2 "gpc_reg_operand" "r")
1253 (const_int 16)))
1254 (const_int 0)))
1255 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1256 (mult:SI (ashiftrt:SI
1257 (match_dup 1)
1258 (const_int 16))
1259 (ashiftrt:SI
1260 (match_dup 2)
1261 (const_int 16))))]
1262 "TARGET_MULHW"
1263 "mulhhw. %0,%1,%2"
1264 [(set_attr "type" "halfmul")])
1265
1266 (define_insn "*mulhhw"
1267 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1268 (mult:SI (ashiftrt:SI
1269 (match_operand:SI 1 "gpc_reg_operand" "%r")
1270 (const_int 16))
1271 (ashiftrt:SI
1272 (match_operand:SI 2 "gpc_reg_operand" "r")
1273 (const_int 16))))]
1274 "TARGET_MULHW"
1275 "mulhhw %0,%1,%2"
1276 [(set_attr "type" "halfmul")])
1277
1278 (define_insn "*mulhhwuc"
1279 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1280 (compare:CC (mult:SI (lshiftrt:SI
1281 (match_operand:SI 1 "gpc_reg_operand" "%r")
1282 (const_int 16))
1283 (lshiftrt:SI
1284 (match_operand:SI 2 "gpc_reg_operand" "r")
1285 (const_int 16)))
1286 (const_int 0)))
1287 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1288 (mult:SI (lshiftrt:SI
1289 (match_dup 1)
1290 (const_int 16))
1291 (lshiftrt:SI
1292 (match_dup 2)
1293 (const_int 16))))]
1294 "TARGET_MULHW"
1295 "mulhhwu. %0,%1,%2"
1296 [(set_attr "type" "halfmul")])
1297
1298 (define_insn "*mulhhwu"
1299 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1300 (mult:SI (lshiftrt:SI
1301 (match_operand:SI 1 "gpc_reg_operand" "%r")
1302 (const_int 16))
1303 (lshiftrt:SI
1304 (match_operand:SI 2 "gpc_reg_operand" "r")
1305 (const_int 16))))]
1306 "TARGET_MULHW"
1307 "mulhhwu %0,%1,%2"
1308 [(set_attr "type" "halfmul")])
1309
1310 (define_insn "*mullhwc"
1311 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1312 (compare:CC (mult:SI (sign_extend:SI
1313 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1314 (sign_extend:SI
1315 (match_operand:HI 2 "gpc_reg_operand" "r")))
1316 (const_int 0)))
1317 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1318 (mult:SI (sign_extend:SI
1319 (match_dup 1))
1320 (sign_extend:SI
1321 (match_dup 2))))]
1322 "TARGET_MULHW"
1323 "mullhw. %0,%1,%2"
1324 [(set_attr "type" "halfmul")])
1325
1326 (define_insn "*mullhw"
1327 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1328 (mult:SI (sign_extend:SI
1329 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1330 (sign_extend:SI
1331 (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1332 "TARGET_MULHW"
1333 "mullhw %0,%1,%2"
1334 [(set_attr "type" "halfmul")])
1335
1336 (define_insn "*mullhwuc"
1337 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1338 (compare:CC (mult:SI (zero_extend:SI
1339 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1340 (zero_extend:SI
1341 (match_operand:HI 2 "gpc_reg_operand" "r")))
1342 (const_int 0)))
1343 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1344 (mult:SI (zero_extend:SI
1345 (match_dup 1))
1346 (zero_extend:SI
1347 (match_dup 2))))]
1348 "TARGET_MULHW"
1349 "mullhwu. %0,%1,%2"
1350 [(set_attr "type" "halfmul")])
1351
1352 (define_insn "*mullhwu"
1353 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1354 (mult:SI (zero_extend:SI
1355 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1356 (zero_extend:SI
1357 (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1358 "TARGET_MULHW"
1359 "mullhwu %0,%1,%2"
1360 [(set_attr "type" "halfmul")])
1361 \f
1362 ;; IBM 405, 440, 464 and 476 string-search dlmzb instruction support.
1363 (define_insn "dlmzb"
1364 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1365 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
1366 (match_operand:SI 2 "gpc_reg_operand" "r")]
1367 UNSPEC_DLMZB_CR))
1368 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1369 (unspec:SI [(match_dup 1)
1370 (match_dup 2)]
1371 UNSPEC_DLMZB))]
1372 "TARGET_DLMZB"
1373 "dlmzb. %0,%1,%2")
1374
1375 (define_expand "strlensi"
1376 [(set (match_operand:SI 0 "gpc_reg_operand" "")
1377 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
1378 (match_operand:QI 2 "const_int_operand" "")
1379 (match_operand 3 "const_int_operand" "")]
1380 UNSPEC_DLMZB_STRLEN))
1381 (clobber (match_scratch:CC 4 "=x"))]
1382 "TARGET_DLMZB && WORDS_BIG_ENDIAN && !optimize_size"
1383 {
1384 rtx result = operands[0];
1385 rtx src = operands[1];
1386 rtx search_char = operands[2];
1387 rtx align = operands[3];
1388 rtx addr, scratch_string, word1, word2, scratch_dlmzb;
1389 rtx loop_label, end_label, mem, cr0, cond;
1390 if (search_char != const0_rtx
1391 || GET_CODE (align) != CONST_INT
1392 || INTVAL (align) < 8)
1393 FAIL;
1394 word1 = gen_reg_rtx (SImode);
1395 word2 = gen_reg_rtx (SImode);
1396 scratch_dlmzb = gen_reg_rtx (SImode);
1397 scratch_string = gen_reg_rtx (Pmode);
1398 loop_label = gen_label_rtx ();
1399 end_label = gen_label_rtx ();
1400 addr = force_reg (Pmode, XEXP (src, 0));
1401 emit_move_insn (scratch_string, addr);
1402 emit_label (loop_label);
1403 mem = change_address (src, SImode, scratch_string);
1404 emit_move_insn (word1, mem);
1405 emit_move_insn (word2, adjust_address (mem, SImode, 4));
1406 cr0 = gen_rtx_REG (CCmode, CR0_REGNO);
1407 emit_insn (gen_dlmzb (scratch_dlmzb, word1, word2, cr0));
1408 cond = gen_rtx_NE (VOIDmode, cr0, const0_rtx);
1409 emit_jump_insn (gen_rtx_SET (VOIDmode,
1410 pc_rtx,
1411 gen_rtx_IF_THEN_ELSE (VOIDmode,
1412 cond,
1413 gen_rtx_LABEL_REF
1414 (VOIDmode,
1415 end_label),
1416 pc_rtx)));
1417 emit_insn (gen_addsi3 (scratch_string, scratch_string, GEN_INT (8)));
1418 emit_jump_insn (gen_rtx_SET (VOIDmode,
1419 pc_rtx,
1420 gen_rtx_LABEL_REF (VOIDmode, loop_label)));
1421 emit_barrier ();
1422 emit_label (end_label);
1423 emit_insn (gen_addsi3 (scratch_string, scratch_string, scratch_dlmzb));
1424 emit_insn (gen_subsi3 (result, scratch_string, addr));
1425 emit_insn (gen_subsi3 (result, result, const1_rtx));
1426 DONE;
1427 })
1428 \f
1429 ;; Fixed-point arithmetic insns.
1430
1431 (define_expand "add<mode>3"
1432 [(set (match_operand:SDI 0 "gpc_reg_operand" "")
1433 (plus:SDI (match_operand:SDI 1 "gpc_reg_operand" "")
1434 (match_operand:SDI 2 "reg_or_add_cint_operand" "")))]
1435 ""
1436 {
1437 if (<MODE>mode == DImode && ! TARGET_POWERPC64)
1438 {
1439 if (non_short_cint_operand (operands[2], DImode))
1440 FAIL;
1441 }
1442 else if (GET_CODE (operands[2]) == CONST_INT
1443 && ! add_operand (operands[2], <MODE>mode))
1444 {
1445 rtx tmp = ((!can_create_pseudo_p ()
1446 || rtx_equal_p (operands[0], operands[1]))
1447 ? operands[0] : gen_reg_rtx (<MODE>mode));
1448
1449 HOST_WIDE_INT val = INTVAL (operands[2]);
1450 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1451 HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1452
1453 if (<MODE>mode == DImode && !satisfies_constraint_L (GEN_INT (rest)))
1454 FAIL;
1455
1456 /* The ordering here is important for the prolog expander.
1457 When space is allocated from the stack, adding 'low' first may
1458 produce a temporary deallocation (which would be bad). */
1459 emit_insn (gen_add<mode>3 (tmp, operands[1], GEN_INT (rest)));
1460 emit_insn (gen_add<mode>3 (operands[0], tmp, GEN_INT (low)));
1461 DONE;
1462 }
1463 })
1464
1465 ;; Discourage ai/addic because of carry but provide it in an alternative
1466 ;; allowing register zero as source.
1467 (define_insn "*add<mode>3_internal1"
1468 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r,?r,r")
1469 (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b,r,b")
1470 (match_operand:GPR 2 "add_operand" "r,I,I,L")))]
1471 "!DECIMAL_FLOAT_MODE_P (GET_MODE (operands[0])) && !DECIMAL_FLOAT_MODE_P (GET_MODE (operands[1]))"
1472 "@
1473 add %0,%1,%2
1474 addi %0,%1,%2
1475 addic %0,%1,%2
1476 addis %0,%1,%v2"
1477 [(set_attr "type" "add")])
1478
1479 (define_insn "addsi3_high"
1480 [(set (match_operand:SI 0 "gpc_reg_operand" "=b")
1481 (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
1482 (high:SI (match_operand 2 "" ""))))]
1483 "TARGET_MACHO && !TARGET_64BIT"
1484 "addis %0,%1,ha16(%2)"
1485 [(set_attr "type" "add")])
1486
1487 (define_insn "*add<mode>3_internal2"
1488 [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y")
1489 (compare:CC (plus:P (match_operand:P 1 "gpc_reg_operand" "%r,r,r,r")
1490 (match_operand:P 2 "reg_or_short_operand" "r,I,r,I"))
1491 (const_int 0)))
1492 (clobber (match_scratch:P 3 "=r,r,r,r"))]
1493 ""
1494 "@
1495 add. %3,%1,%2
1496 addic. %3,%1,%2
1497 #
1498 #"
1499 [(set_attr "type" "add,compare,compare,compare")
1500 (set_attr "dot" "yes")
1501 (set_attr "length" "4,4,8,8")])
1502
1503 (define_split
1504 [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
1505 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
1506 (match_operand:GPR 2 "reg_or_short_operand" ""))
1507 (const_int 0)))
1508 (clobber (match_scratch:GPR 3 ""))]
1509 "reload_completed"
1510 [(set (match_dup 3)
1511 (plus:GPR (match_dup 1)
1512 (match_dup 2)))
1513 (set (match_dup 0)
1514 (compare:CC (match_dup 3)
1515 (const_int 0)))]
1516 "")
1517
1518 (define_insn "*add<mode>3_internal3"
1519 [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y")
1520 (compare:CC (plus:P (match_operand:P 1 "gpc_reg_operand" "%r,r,r,r")
1521 (match_operand:P 2 "reg_or_short_operand" "r,I,r,I"))
1522 (const_int 0)))
1523 (set (match_operand:P 0 "gpc_reg_operand" "=r,r,r,r")
1524 (plus:P (match_dup 1)
1525 (match_dup 2)))]
1526 ""
1527 "@
1528 add. %0,%1,%2
1529 addic. %0,%1,%2
1530 #
1531 #"
1532 [(set_attr "type" "add,compare,compare,compare")
1533 (set_attr "dot" "yes")
1534 (set_attr "length" "4,4,8,8")])
1535
1536 (define_split
1537 [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
1538 (compare:CC (plus:P (match_operand:P 1 "gpc_reg_operand" "")
1539 (match_operand:P 2 "reg_or_short_operand" ""))
1540 (const_int 0)))
1541 (set (match_operand:P 0 "gpc_reg_operand" "")
1542 (plus:P (match_dup 1) (match_dup 2)))]
1543 "reload_completed"
1544 [(set (match_dup 0)
1545 (plus:P (match_dup 1)
1546 (match_dup 2)))
1547 (set (match_dup 3)
1548 (compare:CC (match_dup 0)
1549 (const_int 0)))]
1550 "")
1551
1552 ;; Split an add that we can't do in one insn into two insns, each of which
1553 ;; does one 16-bit part. This is used by combine. Note that the low-order
1554 ;; add should be last in case the result gets used in an address.
1555
1556 (define_split
1557 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
1558 (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
1559 (match_operand:GPR 2 "non_add_cint_operand" "")))]
1560 ""
1561 [(set (match_dup 0) (plus:GPR (match_dup 1) (match_dup 3)))
1562 (set (match_dup 0) (plus:GPR (match_dup 0) (match_dup 4)))]
1563 {
1564 HOST_WIDE_INT val = INTVAL (operands[2]);
1565 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1566 HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1567
1568 operands[4] = GEN_INT (low);
1569 if (<MODE>mode == SImode || satisfies_constraint_L (GEN_INT (rest)))
1570 operands[3] = GEN_INT (rest);
1571 else if (can_create_pseudo_p ())
1572 {
1573 operands[3] = gen_reg_rtx (DImode);
1574 emit_move_insn (operands[3], operands[2]);
1575 emit_insn (gen_adddi3 (operands[0], operands[1], operands[3]));
1576 DONE;
1577 }
1578 else
1579 FAIL;
1580 })
1581
1582 (define_expand "one_cmpl<mode>2"
1583 [(set (match_operand:SDI 0 "gpc_reg_operand" "")
1584 (not:SDI (match_operand:SDI 1 "gpc_reg_operand" "")))]
1585 ""
1586 {
1587 if (<MODE>mode == DImode && !TARGET_POWERPC64)
1588 {
1589 rs6000_split_logical (operands, NOT, false, false, false);
1590 DONE;
1591 }
1592 })
1593
1594 (define_insn "*one_cmpl<mode>2"
1595 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1596 (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
1597 ""
1598 "nor %0,%1,%1")
1599
1600 (define_insn ""
1601 [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
1602 (compare:CC (not:P (match_operand:P 1 "gpc_reg_operand" "r,r"))
1603 (const_int 0)))
1604 (clobber (match_scratch:P 2 "=r,r"))]
1605 ""
1606 "@
1607 nor. %2,%1,%1
1608 #"
1609 [(set_attr "type" "logical,compare")
1610 (set_attr "dot" "yes")
1611 (set_attr "length" "4,8")])
1612
1613 (define_split
1614 [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
1615 (compare:CC (not:P (match_operand:P 1 "gpc_reg_operand" ""))
1616 (const_int 0)))
1617 (clobber (match_scratch:P 2 ""))]
1618 "reload_completed"
1619 [(set (match_dup 2)
1620 (not:P (match_dup 1)))
1621 (set (match_dup 0)
1622 (compare:CC (match_dup 2)
1623 (const_int 0)))]
1624 "")
1625
1626 (define_insn ""
1627 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1628 (compare:CC (not:P (match_operand:P 1 "gpc_reg_operand" "r,r"))
1629 (const_int 0)))
1630 (set (match_operand:P 0 "gpc_reg_operand" "=r,r")
1631 (not:P (match_dup 1)))]
1632 ""
1633 "@
1634 nor. %0,%1,%1
1635 #"
1636 [(set_attr "type" "logical,compare")
1637 (set_attr "dot" "yes")
1638 (set_attr "length" "4,8")])
1639
1640 (define_split
1641 [(set (match_operand:CC 2 "cc_reg_not_micro_cr0_operand" "")
1642 (compare:CC (not:P (match_operand:P 1 "gpc_reg_operand" ""))
1643 (const_int 0)))
1644 (set (match_operand:P 0 "gpc_reg_operand" "")
1645 (not:P (match_dup 1)))]
1646 "reload_completed"
1647 [(set (match_dup 0)
1648 (not:P (match_dup 1)))
1649 (set (match_dup 2)
1650 (compare:CC (match_dup 0)
1651 (const_int 0)))]
1652 "")
1653
1654 (define_insn ""
1655 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1656 (minus:GPR (match_operand:GPR 1 "reg_or_short_operand" "r,I")
1657 (match_operand:GPR 2 "gpc_reg_operand" "r,r")))]
1658 ""
1659 "@
1660 subf %0,%2,%1
1661 subfic %0,%2,%1"
1662 [(set_attr "type" "add")])
1663
1664 (define_insn ""
1665 [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
1666 (compare:CC (minus:P (match_operand:P 1 "gpc_reg_operand" "r,r")
1667 (match_operand:P 2 "gpc_reg_operand" "r,r"))
1668 (const_int 0)))
1669 (clobber (match_scratch:P 3 "=r,r"))]
1670 ""
1671 "@
1672 subf. %3,%2,%1
1673 #"
1674 [(set_attr "type" "add")
1675 (set_attr "dot" "yes")
1676 (set_attr "length" "4,8")])
1677
1678 (define_split
1679 [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
1680 (compare:CC (minus:P (match_operand:P 1 "gpc_reg_operand" "")
1681 (match_operand:P 2 "gpc_reg_operand" ""))
1682 (const_int 0)))
1683 (clobber (match_scratch:P 3 ""))]
1684 "reload_completed"
1685 [(set (match_dup 3)
1686 (minus:P (match_dup 1)
1687 (match_dup 2)))
1688 (set (match_dup 0)
1689 (compare:CC (match_dup 3)
1690 (const_int 0)))]
1691 "")
1692
1693 (define_insn ""
1694 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1695 (compare:CC (minus:P (match_operand:P 1 "gpc_reg_operand" "r,r")
1696 (match_operand:P 2 "gpc_reg_operand" "r,r"))
1697 (const_int 0)))
1698 (set (match_operand:P 0 "gpc_reg_operand" "=r,r")
1699 (minus:P (match_dup 1)
1700 (match_dup 2)))]
1701 ""
1702 "@
1703 subf. %0,%2,%1
1704 #"
1705 [(set_attr "type" "add")
1706 (set_attr "dot" "yes")
1707 (set_attr "length" "4,8")])
1708
1709 (define_split
1710 [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
1711 (compare:CC (minus:P (match_operand:P 1 "gpc_reg_operand" "")
1712 (match_operand:P 2 "gpc_reg_operand" ""))
1713 (const_int 0)))
1714 (set (match_operand:P 0 "gpc_reg_operand" "")
1715 (minus:P (match_dup 1)
1716 (match_dup 2)))]
1717 "reload_completed"
1718 [(set (match_dup 0)
1719 (minus:P (match_dup 1)
1720 (match_dup 2)))
1721 (set (match_dup 3)
1722 (compare:CC (match_dup 0)
1723 (const_int 0)))]
1724 "")
1725
1726 (define_expand "sub<mode>3"
1727 [(set (match_operand:SDI 0 "gpc_reg_operand" "")
1728 (minus:SDI (match_operand:SDI 1 "reg_or_short_operand" "")
1729 (match_operand:SDI 2 "reg_or_sub_cint_operand" "")))]
1730 ""
1731 "
1732 {
1733 if (GET_CODE (operands[2]) == CONST_INT)
1734 {
1735 emit_insn (gen_add<mode>3 (operands[0], operands[1],
1736 negate_rtx (<MODE>mode, operands[2])));
1737 DONE;
1738 }
1739 }")
1740
1741 (define_expand "neg<mode>2"
1742 [(set (match_operand:SDI 0 "gpc_reg_operand" "")
1743 (neg:SDI (match_operand:SDI 1 "gpc_reg_operand" "")))]
1744 ""
1745 "")
1746
1747 (define_insn "*neg<mode>2_internal"
1748 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1749 (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
1750 ""
1751 "neg %0,%1"
1752 [(set_attr "type" "add")])
1753
1754 (define_insn ""
1755 [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
1756 (compare:CC (neg:P (match_operand:P 1 "gpc_reg_operand" "r,r"))
1757 (const_int 0)))
1758 (clobber (match_scratch:P 2 "=r,r"))]
1759 ""
1760 "@
1761 neg. %2,%1
1762 #"
1763 [(set_attr "type" "add")
1764 (set_attr "dot" "yes")
1765 (set_attr "length" "4,8")])
1766
1767 (define_split
1768 [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
1769 (compare:CC (neg:P (match_operand:P 1 "gpc_reg_operand" ""))
1770 (const_int 0)))
1771 (clobber (match_scratch:P 2 ""))]
1772 "reload_completed"
1773 [(set (match_dup 2)
1774 (neg:P (match_dup 1)))
1775 (set (match_dup 0)
1776 (compare:CC (match_dup 2)
1777 (const_int 0)))]
1778 "")
1779
1780 (define_insn ""
1781 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1782 (compare:CC (neg:P (match_operand:P 1 "gpc_reg_operand" "r,r"))
1783 (const_int 0)))
1784 (set (match_operand:P 0 "gpc_reg_operand" "=r,r")
1785 (neg:P (match_dup 1)))]
1786 ""
1787 "@
1788 neg. %0,%1
1789 #"
1790 [(set_attr "type" "add")
1791 (set_attr "dot" "yes")
1792 (set_attr "length" "4,8")])
1793
1794 (define_split
1795 [(set (match_operand:CC 2 "cc_reg_not_cr0_operand" "")
1796 (compare:CC (neg:P (match_operand:P 1 "gpc_reg_operand" ""))
1797 (const_int 0)))
1798 (set (match_operand:P 0 "gpc_reg_operand" "")
1799 (neg:P (match_dup 1)))]
1800 "reload_completed"
1801 [(set (match_dup 0)
1802 (neg:P (match_dup 1)))
1803 (set (match_dup 2)
1804 (compare:CC (match_dup 0)
1805 (const_int 0)))]
1806 "")
1807
1808 (define_insn "clz<mode>2"
1809 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1810 (clz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
1811 ""
1812 "cntlz<wd> %0,%1"
1813 [(set_attr "type" "cntlz")])
1814
1815 (define_expand "ctz<mode>2"
1816 [(set (match_dup 2)
1817 (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))
1818 (set (match_dup 3)
1819 (and:GPR (match_dup 1)
1820 (match_dup 2)))
1821 (set (match_dup 4)
1822 (clz:GPR (match_dup 3)))
1823 (set (match_operand:GPR 0 "gpc_reg_operand" "")
1824 (minus:GPR (match_dup 5)
1825 (match_dup 4)))]
1826 ""
1827 {
1828 operands[2] = gen_reg_rtx (<MODE>mode);
1829 operands[3] = gen_reg_rtx (<MODE>mode);
1830 operands[4] = gen_reg_rtx (<MODE>mode);
1831 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - 1);
1832 })
1833
1834 (define_expand "ffs<mode>2"
1835 [(set (match_dup 2)
1836 (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))
1837 (set (match_dup 3)
1838 (and:GPR (match_dup 1)
1839 (match_dup 2)))
1840 (set (match_dup 4)
1841 (clz:GPR (match_dup 3)))
1842 (set (match_operand:GPR 0 "gpc_reg_operand" "")
1843 (minus:GPR (match_dup 5)
1844 (match_dup 4)))]
1845 ""
1846 {
1847 operands[2] = gen_reg_rtx (<MODE>mode);
1848 operands[3] = gen_reg_rtx (<MODE>mode);
1849 operands[4] = gen_reg_rtx (<MODE>mode);
1850 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
1851 })
1852
1853 (define_insn "popcntb<mode>2"
1854 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1855 (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")]
1856 UNSPEC_POPCNTB))]
1857 "TARGET_POPCNTB"
1858 "popcntb %0,%1"
1859 [(set_attr "length" "4")
1860 (set_attr "type" "popcnt")])
1861
1862 (define_insn "popcntd<mode>2"
1863 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1864 (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
1865 "TARGET_POPCNTD"
1866 "popcnt<wd> %0,%1"
1867 [(set_attr "length" "4")
1868 (set_attr "type" "popcnt")])
1869
1870 (define_expand "popcount<mode>2"
1871 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
1872 (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))]
1873 "TARGET_POPCNTB || TARGET_POPCNTD"
1874 {
1875 rs6000_emit_popcount (operands[0], operands[1]);
1876 DONE;
1877 })
1878
1879 (define_insn "parity<mode>2_cmpb"
1880 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1881 (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")] UNSPEC_PARITY))]
1882 "TARGET_CMPB && TARGET_POPCNTB"
1883 "prty<wd> %0,%1"
1884 [(set_attr "length" "4")
1885 (set_attr "type" "popcnt")])
1886
1887 (define_expand "parity<mode>2"
1888 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
1889 (parity:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))]
1890 "TARGET_POPCNTB"
1891 {
1892 rs6000_emit_parity (operands[0], operands[1]);
1893 DONE;
1894 })
1895
1896 ;; Since the hardware zeros the upper part of the register, save generating the
1897 ;; AND immediate if we are converting to unsigned
1898 (define_insn "*bswaphi2_extenddi"
1899 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
1900 (zero_extend:DI
1901 (bswap:HI (match_operand:HI 1 "memory_operand" "Z"))))]
1902 "TARGET_POWERPC64"
1903 "lhbrx %0,%y1"
1904 [(set_attr "length" "4")
1905 (set_attr "type" "load")])
1906
1907 (define_insn "*bswaphi2_extendsi"
1908 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1909 (zero_extend:SI
1910 (bswap:HI (match_operand:HI 1 "memory_operand" "Z"))))]
1911 ""
1912 "lhbrx %0,%y1"
1913 [(set_attr "length" "4")
1914 (set_attr "type" "load")])
1915
1916 (define_expand "bswaphi2"
1917 [(parallel [(set (match_operand:HI 0 "reg_or_mem_operand" "")
1918 (bswap:HI
1919 (match_operand:HI 1 "reg_or_mem_operand" "")))
1920 (clobber (match_scratch:SI 2 ""))])]
1921 ""
1922 {
1923 if (!REG_P (operands[0]) && !REG_P (operands[1]))
1924 operands[1] = force_reg (HImode, operands[1]);
1925 })
1926
1927 (define_insn "bswaphi2_internal"
1928 [(set (match_operand:HI 0 "reg_or_mem_operand" "=r,Z,&r")
1929 (bswap:HI
1930 (match_operand:HI 1 "reg_or_mem_operand" "Z,r,r")))
1931 (clobber (match_scratch:SI 2 "=X,X,&r"))]
1932 ""
1933 "@
1934 lhbrx %0,%y1
1935 sthbrx %1,%y0
1936 #"
1937 [(set_attr "length" "4,4,12")
1938 (set_attr "type" "load,store,*")])
1939
1940 ;; We are always BITS_BIG_ENDIAN, so the (const_int 16) below is
1941 ;; correct for -mlittle as well as -mbig.
1942 (define_split
1943 [(set (match_operand:HI 0 "gpc_reg_operand" "")
1944 (bswap:HI (match_operand:HI 1 "gpc_reg_operand" "")))
1945 (clobber (match_operand:SI 2 "gpc_reg_operand" ""))]
1946 "reload_completed"
1947 [(set (match_dup 3)
1948 (zero_extract:SI (match_dup 4)
1949 (const_int 8)
1950 (const_int 16)))
1951 (set (match_dup 2)
1952 (and:SI (ashift:SI (match_dup 4)
1953 (const_int 8))
1954 (const_int 65280))) ;; 0xff00
1955 (set (match_dup 3)
1956 (ior:SI (match_dup 3)
1957 (match_dup 2)))]
1958 "
1959 {
1960 operands[3] = simplify_gen_subreg (SImode, operands[0], HImode, 0);
1961 operands[4] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
1962 }")
1963
1964 (define_insn "*bswapsi2_extenddi"
1965 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
1966 (zero_extend:DI
1967 (bswap:SI (match_operand:SI 1 "memory_operand" "Z"))))]
1968 "TARGET_POWERPC64"
1969 "lwbrx %0,%y1"
1970 [(set_attr "length" "4")
1971 (set_attr "type" "load")])
1972
1973 (define_expand "bswapsi2"
1974 [(set (match_operand:SI 0 "reg_or_mem_operand" "")
1975 (bswap:SI
1976 (match_operand:SI 1 "reg_or_mem_operand" "")))]
1977 ""
1978 {
1979 if (!REG_P (operands[0]) && !REG_P (operands[1]))
1980 operands[1] = force_reg (SImode, operands[1]);
1981 })
1982
1983 (define_insn "*bswapsi2_internal"
1984 [(set (match_operand:SI 0 "reg_or_mem_operand" "=r,Z,&r")
1985 (bswap:SI
1986 (match_operand:SI 1 "reg_or_mem_operand" "Z,r,r")))]
1987 ""
1988 "@
1989 lwbrx %0,%y1
1990 stwbrx %1,%y0
1991 #"
1992 [(set_attr "length" "4,4,12")
1993 (set_attr "type" "load,store,*")])
1994
1995 ;; We are always BITS_BIG_ENDIAN, so the bit positions below in
1996 ;; zero_extract insns do not change for -mlittle.
1997 (define_split
1998 [(set (match_operand:SI 0 "gpc_reg_operand" "")
1999 (bswap:SI (match_operand:SI 1 "gpc_reg_operand" "")))]
2000 "reload_completed"
2001 [(set (match_dup 0)
2002 (rotate:SI (match_dup 1) (const_int 8)))
2003 (set (zero_extract:SI (match_dup 0)
2004 (const_int 8)
2005 (const_int 0))
2006 (match_dup 1))
2007 (set (zero_extract:SI (match_dup 0)
2008 (const_int 8)
2009 (const_int 16))
2010 (rotate:SI (match_dup 1)
2011 (const_int 16)))]
2012 "")
2013
2014 (define_expand "bswapdi2"
2015 [(parallel [(set (match_operand:DI 0 "reg_or_mem_operand" "")
2016 (bswap:DI
2017 (match_operand:DI 1 "reg_or_mem_operand" "")))
2018 (clobber (match_scratch:DI 2 ""))
2019 (clobber (match_scratch:DI 3 ""))
2020 (clobber (match_scratch:DI 4 ""))])]
2021 ""
2022 {
2023 if (!REG_P (operands[0]) && !REG_P (operands[1]))
2024 operands[1] = force_reg (DImode, operands[1]);
2025
2026 if (!TARGET_POWERPC64)
2027 {
2028 /* 32-bit mode needs fewer scratch registers, but 32-bit addressing mode
2029 that uses 64-bit registers needs the same scratch registers as 64-bit
2030 mode. */
2031 emit_insn (gen_bswapdi2_32bit (operands[0], operands[1]));
2032 DONE;
2033 }
2034 })
2035
2036 ;; Power7/cell has ldbrx/stdbrx, so use it directly
2037 (define_insn "*bswapdi2_ldbrx"
2038 [(set (match_operand:DI 0 "reg_or_mem_operand" "=&r,Z,??&r")
2039 (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2040 (clobber (match_scratch:DI 2 "=X,X,&r"))
2041 (clobber (match_scratch:DI 3 "=X,X,&r"))
2042 (clobber (match_scratch:DI 4 "=X,X,&r"))]
2043 "TARGET_POWERPC64 && TARGET_LDBRX
2044 && (REG_P (operands[0]) || REG_P (operands[1]))"
2045 "@
2046 ldbrx %0,%y1
2047 stdbrx %1,%y0
2048 #"
2049 [(set_attr "length" "4,4,36")
2050 (set_attr "type" "load,store,*")])
2051
2052 ;; Non-power7/cell, fall back to use lwbrx/stwbrx
2053 (define_insn "*bswapdi2_64bit"
2054 [(set (match_operand:DI 0 "reg_or_mem_operand" "=&r,Z,&r")
2055 (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2056 (clobber (match_scratch:DI 2 "=&b,&b,&r"))
2057 (clobber (match_scratch:DI 3 "=&r,&r,&r"))
2058 (clobber (match_scratch:DI 4 "=&r,X,&r"))]
2059 "TARGET_POWERPC64 && !TARGET_LDBRX
2060 && (REG_P (operands[0]) || REG_P (operands[1]))
2061 && !(MEM_P (operands[0]) && MEM_VOLATILE_P (operands[0]))
2062 && !(MEM_P (operands[1]) && MEM_VOLATILE_P (operands[1]))"
2063 "#"
2064 [(set_attr "length" "16,12,36")])
2065
2066 (define_split
2067 [(set (match_operand:DI 0 "gpc_reg_operand" "")
2068 (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand" "")))
2069 (clobber (match_operand:DI 2 "gpc_reg_operand" ""))
2070 (clobber (match_operand:DI 3 "gpc_reg_operand" ""))
2071 (clobber (match_operand:DI 4 "gpc_reg_operand" ""))]
2072 "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2073 [(const_int 0)]
2074 "
2075 {
2076 rtx dest = operands[0];
2077 rtx src = operands[1];
2078 rtx op2 = operands[2];
2079 rtx op3 = operands[3];
2080 rtx op4 = operands[4];
2081 rtx op3_32 = simplify_gen_subreg (SImode, op3, DImode,
2082 BYTES_BIG_ENDIAN ? 4 : 0);
2083 rtx op4_32 = simplify_gen_subreg (SImode, op4, DImode,
2084 BYTES_BIG_ENDIAN ? 4 : 0);
2085 rtx addr1;
2086 rtx addr2;
2087 rtx word_high;
2088 rtx word_low;
2089
2090 addr1 = XEXP (src, 0);
2091 if (GET_CODE (addr1) == PLUS)
2092 {
2093 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2094 if (TARGET_AVOID_XFORM)
2095 {
2096 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2097 addr2 = op2;
2098 }
2099 else
2100 addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2101 }
2102 else if (TARGET_AVOID_XFORM)
2103 {
2104 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2105 addr2 = op2;
2106 }
2107 else
2108 {
2109 emit_move_insn (op2, GEN_INT (4));
2110 addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2111 }
2112
2113 if (BYTES_BIG_ENDIAN)
2114 {
2115 word_high = change_address (src, SImode, addr1);
2116 word_low = change_address (src, SImode, addr2);
2117 }
2118 else
2119 {
2120 word_high = change_address (src, SImode, addr2);
2121 word_low = change_address (src, SImode, addr1);
2122 }
2123
2124 emit_insn (gen_bswapsi2 (op3_32, word_low));
2125 emit_insn (gen_bswapsi2 (op4_32, word_high));
2126 emit_insn (gen_ashldi3 (dest, op3, GEN_INT (32)));
2127 emit_insn (gen_iordi3 (dest, dest, op4));
2128 DONE;
2129 }")
2130
2131 (define_split
2132 [(set (match_operand:DI 0 "indexed_or_indirect_operand" "")
2133 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2134 (clobber (match_operand:DI 2 "gpc_reg_operand" ""))
2135 (clobber (match_operand:DI 3 "gpc_reg_operand" ""))
2136 (clobber (match_operand:DI 4 "" ""))]
2137 "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2138 [(const_int 0)]
2139 "
2140 {
2141 rtx dest = operands[0];
2142 rtx src = operands[1];
2143 rtx op2 = operands[2];
2144 rtx op3 = operands[3];
2145 rtx src_si = simplify_gen_subreg (SImode, src, DImode,
2146 BYTES_BIG_ENDIAN ? 4 : 0);
2147 rtx op3_si = simplify_gen_subreg (SImode, op3, DImode,
2148 BYTES_BIG_ENDIAN ? 4 : 0);
2149 rtx addr1;
2150 rtx addr2;
2151 rtx word_high;
2152 rtx word_low;
2153
2154 addr1 = XEXP (dest, 0);
2155 if (GET_CODE (addr1) == PLUS)
2156 {
2157 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2158 if (TARGET_AVOID_XFORM)
2159 {
2160 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2161 addr2 = op2;
2162 }
2163 else
2164 addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2165 }
2166 else if (TARGET_AVOID_XFORM)
2167 {
2168 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2169 addr2 = op2;
2170 }
2171 else
2172 {
2173 emit_move_insn (op2, GEN_INT (4));
2174 addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2175 }
2176
2177 emit_insn (gen_lshrdi3 (op3, src, GEN_INT (32)));
2178 if (BYTES_BIG_ENDIAN)
2179 {
2180 word_high = change_address (dest, SImode, addr1);
2181 word_low = change_address (dest, SImode, addr2);
2182 }
2183 else
2184 {
2185 word_high = change_address (dest, SImode, addr2);
2186 word_low = change_address (dest, SImode, addr1);
2187 }
2188 emit_insn (gen_bswapsi2 (word_high, src_si));
2189 emit_insn (gen_bswapsi2 (word_low, op3_si));
2190 DONE;
2191 }")
2192
2193 (define_split
2194 [(set (match_operand:DI 0 "gpc_reg_operand" "")
2195 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2196 (clobber (match_operand:DI 2 "gpc_reg_operand" ""))
2197 (clobber (match_operand:DI 3 "gpc_reg_operand" ""))
2198 (clobber (match_operand:DI 4 "" ""))]
2199 "TARGET_POWERPC64 && reload_completed"
2200 [(const_int 0)]
2201 "
2202 {
2203 rtx dest = operands[0];
2204 rtx src = operands[1];
2205 rtx op2 = operands[2];
2206 rtx op3 = operands[3];
2207 int lo_off = BYTES_BIG_ENDIAN ? 4 : 0;
2208 rtx dest_si = simplify_gen_subreg (SImode, dest, DImode, lo_off);
2209 rtx src_si = simplify_gen_subreg (SImode, src, DImode, lo_off);
2210 rtx op2_si = simplify_gen_subreg (SImode, op2, DImode, lo_off);
2211 rtx op3_si = simplify_gen_subreg (SImode, op3, DImode, lo_off);
2212
2213 emit_insn (gen_lshrdi3 (op2, src, GEN_INT (32)));
2214 emit_insn (gen_bswapsi2 (dest_si, src_si));
2215 emit_insn (gen_bswapsi2 (op3_si, op2_si));
2216 emit_insn (gen_ashldi3 (dest, dest, GEN_INT (32)));
2217 emit_insn (gen_iordi3 (dest, dest, op3));
2218 DONE;
2219 }")
2220
2221 (define_insn "bswapdi2_32bit"
2222 [(set (match_operand:DI 0 "reg_or_mem_operand" "=&r,Z,&r")
2223 (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2224 (clobber (match_scratch:SI 2 "=&b,&b,X"))]
2225 "!TARGET_POWERPC64 && (REG_P (operands[0]) || REG_P (operands[1]))"
2226 "#"
2227 [(set_attr "length" "16,12,36")])
2228
2229 (define_split
2230 [(set (match_operand:DI 0 "gpc_reg_operand" "")
2231 (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand" "")))
2232 (clobber (match_operand:SI 2 "gpc_reg_operand" ""))]
2233 "!TARGET_POWERPC64 && reload_completed"
2234 [(const_int 0)]
2235 "
2236 {
2237 rtx dest = operands[0];
2238 rtx src = operands[1];
2239 rtx op2 = operands[2];
2240 rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
2241 rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
2242 rtx addr1;
2243 rtx addr2;
2244 rtx word1;
2245 rtx word2;
2246
2247 addr1 = XEXP (src, 0);
2248 if (GET_CODE (addr1) == PLUS)
2249 {
2250 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2251 if (TARGET_AVOID_XFORM)
2252 {
2253 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2254 addr2 = op2;
2255 }
2256 else
2257 addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
2258 }
2259 else if (TARGET_AVOID_XFORM)
2260 {
2261 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2262 addr2 = op2;
2263 }
2264 else
2265 {
2266 emit_move_insn (op2, GEN_INT (4));
2267 addr2 = gen_rtx_PLUS (SImode, op2, addr1);
2268 }
2269
2270 word1 = change_address (src, SImode, addr1);
2271 word2 = change_address (src, SImode, addr2);
2272
2273 emit_insn (gen_bswapsi2 (dest2, word1));
2274 emit_insn (gen_bswapsi2 (dest1, word2));
2275 DONE;
2276 }")
2277
2278 (define_split
2279 [(set (match_operand:DI 0 "indexed_or_indirect_operand" "")
2280 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2281 (clobber (match_operand:SI 2 "gpc_reg_operand" ""))]
2282 "!TARGET_POWERPC64 && reload_completed"
2283 [(const_int 0)]
2284 "
2285 {
2286 rtx dest = operands[0];
2287 rtx src = operands[1];
2288 rtx op2 = operands[2];
2289 rtx src1 = simplify_gen_subreg (SImode, src, DImode, 0);
2290 rtx src2 = simplify_gen_subreg (SImode, src, DImode, 4);
2291 rtx addr1;
2292 rtx addr2;
2293 rtx word1;
2294 rtx word2;
2295
2296 addr1 = XEXP (dest, 0);
2297 if (GET_CODE (addr1) == PLUS)
2298 {
2299 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2300 if (TARGET_AVOID_XFORM)
2301 {
2302 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2303 addr2 = op2;
2304 }
2305 else
2306 addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
2307 }
2308 else if (TARGET_AVOID_XFORM)
2309 {
2310 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2311 addr2 = op2;
2312 }
2313 else
2314 {
2315 emit_move_insn (op2, GEN_INT (4));
2316 addr2 = gen_rtx_PLUS (SImode, op2, addr1);
2317 }
2318
2319 word1 = change_address (dest, SImode, addr1);
2320 word2 = change_address (dest, SImode, addr2);
2321
2322 emit_insn (gen_bswapsi2 (word2, src1));
2323 emit_insn (gen_bswapsi2 (word1, src2));
2324 DONE;
2325 }")
2326
2327 (define_split
2328 [(set (match_operand:DI 0 "gpc_reg_operand" "")
2329 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2330 (clobber (match_operand:SI 2 "" ""))]
2331 "!TARGET_POWERPC64 && reload_completed"
2332 [(const_int 0)]
2333 "
2334 {
2335 rtx dest = operands[0];
2336 rtx src = operands[1];
2337 rtx src1 = simplify_gen_subreg (SImode, src, DImode, 0);
2338 rtx src2 = simplify_gen_subreg (SImode, src, DImode, 4);
2339 rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
2340 rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
2341
2342 emit_insn (gen_bswapsi2 (dest1, src2));
2343 emit_insn (gen_bswapsi2 (dest2, src1));
2344 DONE;
2345 }")
2346
2347
2348 (define_insn "mul<mode>3"
2349 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2350 (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
2351 (match_operand:GPR 2 "reg_or_short_operand" "r,I")))]
2352 ""
2353 "@
2354 mull<wd> %0,%1,%2
2355 mulli %0,%1,%2"
2356 [(set_attr "type" "mul")
2357 (set (attr "size")
2358 (cond [(match_operand:GPR 2 "s8bit_cint_operand" "")
2359 (const_string "8")
2360 (match_operand:GPR 2 "short_cint_operand" "")
2361 (const_string "16")]
2362 (const_string "<bits>")))])
2363
2364 (define_insn_and_split "*mul<mode>3_dot"
2365 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2366 (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2367 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
2368 (const_int 0)))
2369 (clobber (match_scratch:GPR 0 "=r,r"))]
2370 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
2371 "@
2372 mull<wd>. %0,%1,%2
2373 #"
2374 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2375 [(set (match_dup 0)
2376 (mult:GPR (match_dup 1)
2377 (match_dup 2)))
2378 (set (match_dup 3)
2379 (compare:CC (match_dup 0)
2380 (const_int 0)))]
2381 ""
2382 [(set_attr "type" "mul")
2383 (set_attr "size" "<bits>")
2384 (set_attr "dot" "yes")
2385 (set_attr "length" "4,8")])
2386
2387 (define_insn_and_split "*mul<mode>3_dot2"
2388 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2389 (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2390 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
2391 (const_int 0)))
2392 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2393 (mult:GPR (match_dup 1)
2394 (match_dup 2)))]
2395 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
2396 "@
2397 mull<wd>. %0,%1,%2
2398 #"
2399 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2400 [(set (match_dup 0)
2401 (mult:GPR (match_dup 1)
2402 (match_dup 2)))
2403 (set (match_dup 3)
2404 (compare:CC (match_dup 0)
2405 (const_int 0)))]
2406 ""
2407 [(set_attr "type" "mul")
2408 (set_attr "size" "<bits>")
2409 (set_attr "dot" "yes")
2410 (set_attr "length" "4,8")])
2411
2412
2413 (define_expand "<su>mul<mode>3_highpart"
2414 [(set (match_operand:GPR 0 "gpc_reg_operand")
2415 (subreg:GPR
2416 (mult:<DMODE> (any_extend:<DMODE>
2417 (match_operand:GPR 1 "gpc_reg_operand"))
2418 (any_extend:<DMODE>
2419 (match_operand:GPR 2 "gpc_reg_operand")))
2420 0))]
2421 ""
2422 {
2423 if (<MODE>mode == SImode && TARGET_POWERPC64)
2424 {
2425 emit_insn (gen_<su>mulsi3_highpart_64 (operands[0], operands[1],
2426 operands[2]));
2427 DONE;
2428 }
2429
2430 if (!WORDS_BIG_ENDIAN)
2431 {
2432 emit_insn (gen_<su>mul<mode>3_highpart_le (operands[0], operands[1],
2433 operands[2]));
2434 DONE;
2435 }
2436 })
2437
2438 (define_insn "*<su>mul<mode>3_highpart"
2439 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2440 (subreg:GPR
2441 (mult:<DMODE> (any_extend:<DMODE>
2442 (match_operand:GPR 1 "gpc_reg_operand" "r"))
2443 (any_extend:<DMODE>
2444 (match_operand:GPR 2 "gpc_reg_operand" "r")))
2445 0))]
2446 "WORDS_BIG_ENDIAN && !(<MODE>mode == SImode && TARGET_POWERPC64)"
2447 "mulh<wd><u> %0,%1,%2"
2448 [(set_attr "type" "mul")
2449 (set_attr "size" "<bits>")])
2450
2451 (define_insn "<su>mulsi3_highpart_le"
2452 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2453 (subreg:SI
2454 (mult:DI (any_extend:DI
2455 (match_operand:SI 1 "gpc_reg_operand" "r"))
2456 (any_extend:DI
2457 (match_operand:SI 2 "gpc_reg_operand" "r")))
2458 4))]
2459 "!WORDS_BIG_ENDIAN && !TARGET_POWERPC64"
2460 "mulhw<u> %0,%1,%2"
2461 [(set_attr "type" "mul")])
2462
2463 (define_insn "<su>muldi3_highpart_le"
2464 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2465 (subreg:DI
2466 (mult:TI (any_extend:TI
2467 (match_operand:DI 1 "gpc_reg_operand" "r"))
2468 (any_extend:TI
2469 (match_operand:DI 2 "gpc_reg_operand" "r")))
2470 8))]
2471 "!WORDS_BIG_ENDIAN && TARGET_POWERPC64"
2472 "mulhd<u> %0,%1,%2"
2473 [(set_attr "type" "mul")
2474 (set_attr "size" "64")])
2475
2476 (define_insn "<su>mulsi3_highpart_64"
2477 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2478 (truncate:SI
2479 (lshiftrt:DI
2480 (mult:DI (any_extend:DI
2481 (match_operand:SI 1 "gpc_reg_operand" "r"))
2482 (any_extend:DI
2483 (match_operand:SI 2 "gpc_reg_operand" "r")))
2484 (const_int 32))))]
2485 "TARGET_POWERPC64"
2486 "mulhw<u> %0,%1,%2"
2487 [(set_attr "type" "mul")])
2488
2489 (define_expand "<u>mul<mode><dmode>3"
2490 [(set (match_operand:<DMODE> 0 "gpc_reg_operand")
2491 (mult:<DMODE> (any_extend:<DMODE>
2492 (match_operand:GPR 1 "gpc_reg_operand"))
2493 (any_extend:<DMODE>
2494 (match_operand:GPR 2 "gpc_reg_operand"))))]
2495 "!(<MODE>mode == SImode && TARGET_POWERPC64)"
2496 {
2497 rtx l = gen_reg_rtx (<MODE>mode);
2498 rtx h = gen_reg_rtx (<MODE>mode);
2499 emit_insn (gen_mul<mode>3 (l, operands[1], operands[2]));
2500 emit_insn (gen_<su>mul<mode>3_highpart (h, operands[1], operands[2]));
2501 emit_move_insn (gen_lowpart (<MODE>mode, operands[0]), l);
2502 emit_move_insn (gen_highpart (<MODE>mode, operands[0]), h);
2503 DONE;
2504 })
2505
2506
2507 (define_insn "udiv<mode>3"
2508 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2509 (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
2510 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
2511 ""
2512 "div<wd>u %0,%1,%2"
2513 [(set_attr "type" "div")
2514 (set_attr "size" "<bits>")])
2515
2516
2517 ;; For powers of two we can do srai/aze for divide and then adjust for
2518 ;; modulus. If it isn't a power of two, force operands into register and do
2519 ;; a normal divide.
2520 (define_expand "div<mode>3"
2521 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2522 (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
2523 (match_operand:GPR 2 "reg_or_cint_operand" "")))]
2524 ""
2525 {
2526 if (GET_CODE (operands[2]) != CONST_INT
2527 || INTVAL (operands[2]) <= 0
2528 || exact_log2 (INTVAL (operands[2])) < 0)
2529 operands[2] = force_reg (<MODE>mode, operands[2]);
2530 })
2531
2532 (define_insn "*div<mode>3"
2533 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2534 (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
2535 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
2536 ""
2537 "div<wd> %0,%1,%2"
2538 [(set_attr "type" "div")
2539 (set_attr "size" "<bits>")])
2540
2541 (define_expand "mod<mode>3"
2542 [(use (match_operand:GPR 0 "gpc_reg_operand" ""))
2543 (use (match_operand:GPR 1 "gpc_reg_operand" ""))
2544 (use (match_operand:GPR 2 "reg_or_cint_operand" ""))]
2545 ""
2546 "
2547 {
2548 int i;
2549 rtx temp1;
2550 rtx temp2;
2551
2552 if (GET_CODE (operands[2]) != CONST_INT
2553 || INTVAL (operands[2]) <= 0
2554 || (i = exact_log2 (INTVAL (operands[2]))) < 0)
2555 FAIL;
2556
2557 temp1 = gen_reg_rtx (<MODE>mode);
2558 temp2 = gen_reg_rtx (<MODE>mode);
2559
2560 emit_insn (gen_div<mode>3 (temp1, operands[1], operands[2]));
2561 emit_insn (gen_ashl<mode>3 (temp2, temp1, GEN_INT (i)));
2562 emit_insn (gen_sub<mode>3 (operands[0], operands[1], temp2));
2563 DONE;
2564 }")
2565
2566 (define_insn ""
2567 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2568 (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
2569 (match_operand:GPR 2 "exact_log2_cint_operand" "N")))]
2570 ""
2571 "sra<wd>i %0,%1,%p2\;addze %0,%0"
2572 [(set_attr "type" "two")
2573 (set_attr "length" "8")])
2574
2575 (define_insn ""
2576 [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
2577 (compare:CC (div:P (match_operand:P 1 "gpc_reg_operand" "r,r")
2578 (match_operand:P 2 "exact_log2_cint_operand" "N,N"))
2579 (const_int 0)))
2580 (clobber (match_scratch:P 3 "=r,r"))]
2581 ""
2582 "@
2583 sra<wd>i %3,%1,%p2\;addze. %3,%3
2584 #"
2585 [(set_attr "type" "compare")
2586 (set_attr "length" "8,12")
2587 (set_attr "cell_micro" "not")])
2588
2589 (define_split
2590 [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
2591 (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
2592 (match_operand:GPR 2 "exact_log2_cint_operand"
2593 ""))
2594 (const_int 0)))
2595 (clobber (match_scratch:GPR 3 ""))]
2596 "reload_completed"
2597 [(set (match_dup 3)
2598 (div:<MODE> (match_dup 1) (match_dup 2)))
2599 (set (match_dup 0)
2600 (compare:CC (match_dup 3)
2601 (const_int 0)))]
2602 "")
2603
2604 (define_insn ""
2605 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2606 (compare:CC (div:P (match_operand:P 1 "gpc_reg_operand" "r,r")
2607 (match_operand:P 2 "exact_log2_cint_operand" "N,N"))
2608 (const_int 0)))
2609 (set (match_operand:P 0 "gpc_reg_operand" "=r,r")
2610 (div:P (match_dup 1) (match_dup 2)))]
2611 ""
2612 "@
2613 sra<wd>i %0,%1,%p2\;addze. %0,%0
2614 #"
2615 [(set_attr "type" "compare")
2616 (set_attr "length" "8,12")
2617 (set_attr "cell_micro" "not")])
2618
2619 (define_split
2620 [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
2621 (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
2622 (match_operand:GPR 2 "exact_log2_cint_operand"
2623 ""))
2624 (const_int 0)))
2625 (set (match_operand:GPR 0 "gpc_reg_operand" "")
2626 (div:GPR (match_dup 1) (match_dup 2)))]
2627 "reload_completed"
2628 [(set (match_dup 0)
2629 (div:<MODE> (match_dup 1) (match_dup 2)))
2630 (set (match_dup 3)
2631 (compare:CC (match_dup 0)
2632 (const_int 0)))]
2633 "")
2634 \f
2635 ;; Logical instructions
2636 ;; The logical instructions are mostly combined by using match_operator,
2637 ;; but the plain AND insns are somewhat different because there is no
2638 ;; plain 'andi' (only 'andi.'), no plain 'andis', and there are all
2639 ;; those rotate-and-mask operations. Thus, the AND insns come first.
2640
2641 (define_expand "and<mode>3"
2642 [(set (match_operand:SDI 0 "gpc_reg_operand" "")
2643 (and:SDI (match_operand:SDI 1 "gpc_reg_operand" "")
2644 (match_operand:SDI 2 "reg_or_cint_operand" "")))]
2645 ""
2646 {
2647 if (<MODE>mode == DImode && !TARGET_POWERPC64)
2648 {
2649 rs6000_split_logical (operands, AND, false, false, false);
2650 DONE;
2651 }
2652
2653 if (logical_const_operand (operands[2], <MODE>mode)
2654 && !any_mask_operand (operands[2], <MODE>mode))
2655 {
2656 emit_insn (gen_and<mode>3_imm (operands[0], operands[1], operands[2]));
2657 DONE;
2658 }
2659
2660 if ((<MODE>mode == DImode && !and64_2_operand (operands[2], <MODE>mode))
2661 || (<MODE>mode != DImode && !and_operand (operands[2], <MODE>mode)))
2662 operands[2] = force_reg (<MODE>mode, operands[2]);
2663 })
2664
2665
2666 (define_insn "*and<mode>3"
2667 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2668 (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
2669 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
2670 ""
2671 "and %0,%1,%2"
2672 [(set_attr "type" "logical")])
2673
2674 (define_insn_and_split "*and<mode>3_dot"
2675 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2676 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2677 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
2678 (const_int 0)))
2679 (clobber (match_scratch:GPR 0 "=r,r"))]
2680 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
2681 "@
2682 and. %0,%1,%2
2683 #"
2684 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2685 [(set (match_dup 0)
2686 (and:GPR (match_dup 1)
2687 (match_dup 2)))
2688 (set (match_dup 3)
2689 (compare:CC (match_dup 0)
2690 (const_int 0)))]
2691 ""
2692 [(set_attr "type" "logical")
2693 (set_attr "dot" "yes")
2694 (set_attr "length" "4,8")])
2695
2696 (define_insn_and_split "*and<mode>3_dot2"
2697 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2698 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2699 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
2700 (const_int 0)))
2701 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2702 (and:GPR (match_dup 1)
2703 (match_dup 2)))]
2704 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
2705 "@
2706 and. %0,%1,%2
2707 #"
2708 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2709 [(set (match_dup 0)
2710 (and:GPR (match_dup 1)
2711 (match_dup 2)))
2712 (set (match_dup 3)
2713 (compare:CC (match_dup 0)
2714 (const_int 0)))]
2715 ""
2716 [(set_attr "type" "logical")
2717 (set_attr "dot" "yes")
2718 (set_attr "length" "4,8")])
2719
2720
2721 (define_insn "and<mode>3_imm"
2722 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2723 (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
2724 (match_operand:GPR 2 "logical_const_operand" "n")))
2725 (clobber (match_scratch:CC 3 "=x"))]
2726 "rs6000_gen_cell_microcode
2727 && !any_mask_operand (operands[2], <MODE>mode)"
2728 "andi%e2. %0,%1,%u2"
2729 [(set_attr "type" "logical")
2730 (set_attr "dot" "yes")])
2731
2732 (define_insn_and_split "*and<mode>3_imm_dot"
2733 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
2734 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
2735 (match_operand:GPR 2 "logical_const_operand" "n,n"))
2736 (const_int 0)))
2737 (clobber (match_scratch:GPR 0 "=r,r"))
2738 (clobber (match_scratch:CC 4 "=X,x"))]
2739 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
2740 && rs6000_gen_cell_microcode
2741 && !any_mask_operand (operands[2], <MODE>mode)"
2742 "@
2743 andi%e2. %0,%1,%u2
2744 #"
2745 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2746 [(parallel [(set (match_dup 0)
2747 (and:GPR (match_dup 1)
2748 (match_dup 2)))
2749 (clobber (match_dup 4))])
2750 (set (match_dup 3)
2751 (compare:CC (match_dup 0)
2752 (const_int 0)))]
2753 ""
2754 [(set_attr "type" "logical")
2755 (set_attr "dot" "yes")
2756 (set_attr "length" "4,8")])
2757
2758 (define_insn_and_split "*and<mode>3_imm_dot2"
2759 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
2760 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
2761 (match_operand:GPR 2 "logical_const_operand" "n,n"))
2762 (const_int 0)))
2763 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2764 (and:GPR (match_dup 1)
2765 (match_dup 2)))
2766 (clobber (match_scratch:CC 4 "=X,x"))]
2767 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
2768 && rs6000_gen_cell_microcode
2769 && !any_mask_operand (operands[2], <MODE>mode)"
2770 "@
2771 andi%e2. %0,%1,%u2
2772 #"
2773 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2774 [(parallel [(set (match_dup 0)
2775 (and:GPR (match_dup 1)
2776 (match_dup 2)))
2777 (clobber (match_dup 4))])
2778 (set (match_dup 3)
2779 (compare:CC (match_dup 0)
2780 (const_int 0)))]
2781 ""
2782 [(set_attr "type" "logical")
2783 (set_attr "dot" "yes")
2784 (set_attr "length" "4,8")])
2785
2786 (define_insn_and_split "*and<mode>3_imm_mask_dot"
2787 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
2788 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
2789 (match_operand:GPR 2 "logical_const_operand" "n,n"))
2790 (const_int 0)))
2791 (clobber (match_scratch:GPR 0 "=r,r"))]
2792 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
2793 && rs6000_gen_cell_microcode
2794 && any_mask_operand (operands[2], <MODE>mode)"
2795 "@
2796 andi%e2. %0,%1,%u2
2797 #"
2798 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2799 [(set (match_dup 0)
2800 (and:GPR (match_dup 1)
2801 (match_dup 2)))
2802 (set (match_dup 3)
2803 (compare:CC (match_dup 0)
2804 (const_int 0)))]
2805 ""
2806 [(set_attr "type" "logical")
2807 (set_attr "dot" "yes")
2808 (set_attr "length" "4,8")])
2809
2810 (define_insn_and_split "*and<mode>3_imm_mask_dot2"
2811 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
2812 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
2813 (match_operand:GPR 2 "logical_const_operand" "n,n"))
2814 (const_int 0)))
2815 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2816 (and:GPR (match_dup 1)
2817 (match_dup 2)))]
2818 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
2819 && rs6000_gen_cell_microcode
2820 && any_mask_operand (operands[2], <MODE>mode)"
2821 "@
2822 andi%e2. %0,%1,%u2
2823 #"
2824 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2825 [(set (match_dup 0)
2826 (and:GPR (match_dup 1)
2827 (match_dup 2)))
2828 (set (match_dup 3)
2829 (compare:CC (match_dup 0)
2830 (const_int 0)))]
2831 ""
2832 [(set_attr "type" "logical")
2833 (set_attr "dot" "yes")
2834 (set_attr "length" "4,8")])
2835
2836
2837 (define_insn "*and<mode>3_mask"
2838 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2839 (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
2840 (match_operand:GPR 2 "any_mask_operand" "S,T")))]
2841 ""
2842 "@
2843 rldic%B2 %0,%1,0,%S2
2844 rlwinm %0,%1,0,%m2,%M2"
2845 [(set_attr "type" "shift")])
2846
2847 (define_insn_and_split "*and<mode>3_mask_dot"
2848 [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y")
2849 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r,r,r")
2850 (match_operand:GPR 2 "any_mask_operand" "S,T,S,T"))
2851 (const_int 0)))
2852 (clobber (match_scratch:GPR 0 "=r,r,r,r"))]
2853 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
2854 && rs6000_gen_cell_microcode
2855 && !logical_const_operand (operands[2], <MODE>mode)"
2856 "@
2857 rldic%B2. %0,%1,0,%S2
2858 rlwinm. %0,%1,0,%m2,%M2
2859 #
2860 #"
2861 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2862 [(set (match_dup 0)
2863 (and:GPR (match_dup 1)
2864 (match_dup 2)))
2865 (set (match_dup 3)
2866 (compare:CC (match_dup 0)
2867 (const_int 0)))]
2868 ""
2869 [(set_attr "type" "shift")
2870 (set_attr "dot" "yes")
2871 (set_attr "length" "4,4,8,8")])
2872
2873 (define_insn_and_split "*and<mode>3_mask_dot2"
2874 [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y")
2875 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r,r,r")
2876 (match_operand:GPR 2 "any_mask_operand" "S,T,S,T"))
2877 (const_int 0)))
2878 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r,r,r")
2879 (and:GPR (match_dup 1)
2880 (match_dup 2)))]
2881 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
2882 && rs6000_gen_cell_microcode
2883 && !logical_const_operand (operands[2], <MODE>mode)"
2884 "@
2885 rldic%B2. %0,%1,0,%S2
2886 rlwinm. %0,%1,0,%m2,%M2
2887 #
2888 #"
2889 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2890 [(set (match_dup 0)
2891 (and:GPR (match_dup 1)
2892 (match_dup 2)))
2893 (set (match_dup 3)
2894 (compare:CC (match_dup 0)
2895 (const_int 0)))]
2896 ""
2897 [(set_attr "type" "shift")
2898 (set_attr "dot" "yes")
2899 (set_attr "length" "4,4,8,8")])
2900
2901
2902
2903 (define_insn "andsi3_internal0_nomc"
2904 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
2905 (and:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r")
2906 (match_operand:SI 2 "and_operand" "?r,T")))]
2907 "!rs6000_gen_cell_microcode"
2908 "@
2909 and %0,%1,%2
2910 rlwinm %0,%1,0,%m2,%M2"
2911 [(set_attr "type" "logical,shift")])
2912
2913
2914 ;; Handle the PowerPC64 rlwinm corner case
2915
2916 (define_insn_and_split "*andsi3_internal6"
2917 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2918 (and:SI (match_operand:SI 1 "gpc_reg_operand" "r")
2919 (match_operand:SI 2 "mask_operand_wrap" "i")))]
2920 "TARGET_POWERPC64"
2921 "#"
2922 "TARGET_POWERPC64"
2923 [(set (match_dup 0)
2924 (and:SI (rotate:SI (match_dup 1) (match_dup 3))
2925 (match_dup 4)))
2926 (set (match_dup 0)
2927 (rotate:SI (match_dup 0) (match_dup 5)))]
2928 "
2929 {
2930 int mb = extract_MB (operands[2]);
2931 int me = extract_ME (operands[2]);
2932 operands[3] = GEN_INT (me + 1);
2933 operands[5] = GEN_INT (32 - (me + 1));
2934 operands[4] = GEN_INT (~((HOST_WIDE_INT) -1 << (33 + me - mb)));
2935 }"
2936 [(set_attr "length" "8")])
2937
2938
2939 (define_expand "ior<mode>3"
2940 [(set (match_operand:SDI 0 "gpc_reg_operand" "")
2941 (ior:SDI (match_operand:SDI 1 "gpc_reg_operand" "")
2942 (match_operand:SDI 2 "reg_or_cint_operand" "")))]
2943 ""
2944 {
2945 if (<MODE>mode == DImode && !TARGET_POWERPC64)
2946 {
2947 rs6000_split_logical (operands, IOR, false, false, false);
2948 DONE;
2949 }
2950
2951 if (non_logical_cint_operand (operands[2], <MODE>mode))
2952 {
2953 rtx tmp = ((!can_create_pseudo_p ()
2954 || rtx_equal_p (operands[0], operands[1]))
2955 ? operands[0] : gen_reg_rtx (<MODE>mode));
2956 HOST_WIDE_INT value = INTVAL (operands[2]);
2957
2958 emit_insn (gen_ior<mode>3 (tmp, operands[1],
2959 GEN_INT (value & (~ (HOST_WIDE_INT) 0xffff))));
2960
2961 emit_insn (gen_ior<mode>3 (operands[0], tmp, GEN_INT (value & 0xffff)));
2962 DONE;
2963 }
2964
2965 if (!reg_or_logical_cint_operand (operands[2], <MODE>mode))
2966 operands[2] = force_reg (<MODE>mode, operands[2]);
2967 })
2968
2969 (define_expand "xor<mode>3"
2970 [(set (match_operand:SDI 0 "gpc_reg_operand" "")
2971 (xor:SDI (match_operand:SDI 1 "gpc_reg_operand" "")
2972 (match_operand:SDI 2 "reg_or_cint_operand" "")))]
2973 ""
2974 {
2975 if (<MODE>mode == DImode && !TARGET_POWERPC64)
2976 {
2977 rs6000_split_logical (operands, XOR, false, false, false);
2978 DONE;
2979 }
2980
2981 if (non_logical_cint_operand (operands[2], <MODE>mode))
2982 {
2983 rtx tmp = ((!can_create_pseudo_p ()
2984 || rtx_equal_p (operands[0], operands[1]))
2985 ? operands[0] : gen_reg_rtx (<MODE>mode));
2986 HOST_WIDE_INT value = INTVAL (operands[2]);
2987
2988 emit_insn (gen_xor<mode>3 (tmp, operands[1],
2989 GEN_INT (value & (~ (HOST_WIDE_INT) 0xffff))));
2990
2991 emit_insn (gen_xor<mode>3 (operands[0], tmp, GEN_INT (value & 0xffff)));
2992 DONE;
2993 }
2994
2995 if (!reg_or_logical_cint_operand (operands[2], <MODE>mode))
2996 operands[2] = force_reg (<MODE>mode, operands[2]);
2997 })
2998
2999 (define_insn "*bool<mode>3"
3000 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3001 (match_operator:GPR 3 "boolean_or_operator"
3002 [(match_operand:GPR 1 "gpc_reg_operand" "r")
3003 (match_operand:GPR 2 "gpc_reg_operand" "r")]))]
3004 ""
3005 "%q3 %0,%1,%2"
3006 [(set_attr "type" "logical")])
3007
3008 (define_insn "*bool<mode>3_imm"
3009 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3010 (match_operator:GPR 3 "boolean_or_operator"
3011 [(match_operand:GPR 1 "gpc_reg_operand" "%r")
3012 (match_operand:GPR 2 "logical_const_operand" "n")]))]
3013 ""
3014 "%q3i%e2 %0,%1,%u2"
3015 [(set_attr "type" "logical")])
3016
3017 (define_insn_and_split "*bool<mode>3_dot"
3018 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3019 (compare:CC (match_operator:GPR 3 "boolean_or_operator"
3020 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3021 (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
3022 (const_int 0)))
3023 (clobber (match_scratch:GPR 0 "=r,r"))]
3024 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3025 "@
3026 %q3. %0,%1,%2
3027 #"
3028 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3029 [(set (match_dup 0)
3030 (match_dup 3))
3031 (set (match_dup 4)
3032 (compare:CC (match_dup 0)
3033 (const_int 0)))]
3034 ""
3035 [(set_attr "type" "logical")
3036 (set_attr "dot" "yes")
3037 (set_attr "length" "4,8")])
3038
3039 (define_insn_and_split "*bool<mode>3_dot2"
3040 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3041 (compare:CC (match_operator:GPR 3 "boolean_or_operator"
3042 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3043 (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
3044 (const_int 0)))
3045 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3046 (match_dup 3))]
3047 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3048 "@
3049 %q3. %0,%1,%2
3050 #"
3051 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3052 [(set (match_dup 0)
3053 (match_dup 3))
3054 (set (match_dup 4)
3055 (compare:CC (match_dup 0)
3056 (const_int 0)))]
3057 ""
3058 [(set_attr "type" "logical")
3059 (set_attr "dot" "yes")
3060 (set_attr "length" "4,8")])
3061
3062 ;; Split a logical operation that we can't do in one insn into two insns,
3063 ;; each of which does one 16-bit part. This is used by combine.
3064
3065 (define_split
3066 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
3067 (match_operator:GPR 3 "boolean_or_operator"
3068 [(match_operand:GPR 1 "gpc_reg_operand" "")
3069 (match_operand:GPR 2 "non_logical_cint_operand" "")]))]
3070 ""
3071 [(set (match_dup 0) (match_dup 4))
3072 (set (match_dup 0) (match_dup 5))]
3073 {
3074 rtx i;
3075 i = GEN_INT (INTVAL (operands[2]) & (~ (HOST_WIDE_INT) 0xffff));
3076 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
3077 operands[1], i);
3078 i = GEN_INT (INTVAL (operands[2]) & 0xffff);
3079 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
3080 operands[0], i);
3081 })
3082
3083
3084 (define_insn "*boolc<mode>3"
3085 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3086 (match_operator:GPR 3 "boolean_operator"
3087 [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))
3088 (match_operand:GPR 1 "gpc_reg_operand" "r")]))]
3089 ""
3090 "%q3 %0,%1,%2"
3091 [(set_attr "type" "logical")])
3092
3093 (define_insn_and_split "*boolc<mode>3_dot"
3094 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3095 (compare:CC (match_operator:GPR 3 "boolean_operator"
3096 [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3097 (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
3098 (const_int 0)))
3099 (clobber (match_scratch:GPR 0 "=r,r"))]
3100 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3101 "@
3102 %q3. %0,%1,%2
3103 #"
3104 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3105 [(set (match_dup 0)
3106 (match_dup 3))
3107 (set (match_dup 4)
3108 (compare:CC (match_dup 0)
3109 (const_int 0)))]
3110 ""
3111 [(set_attr "type" "logical")
3112 (set_attr "dot" "yes")
3113 (set_attr "length" "4,8")])
3114
3115 (define_insn_and_split "*boolc<mode>3_dot2"
3116 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3117 (compare:CC (match_operator:GPR 3 "boolean_operator"
3118 [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3119 (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
3120 (const_int 0)))
3121 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3122 (match_dup 3))]
3123 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3124 "@
3125 %q3. %0,%1,%2
3126 #"
3127 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3128 [(set (match_dup 0)
3129 (match_dup 3))
3130 (set (match_dup 4)
3131 (compare:CC (match_dup 0)
3132 (const_int 0)))]
3133 ""
3134 [(set_attr "type" "logical")
3135 (set_attr "dot" "yes")
3136 (set_attr "length" "4,8")])
3137
3138
3139 (define_insn "*boolcc<mode>3"
3140 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3141 (match_operator:GPR 3 "boolean_operator"
3142 [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
3143 (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))]))]
3144 ""
3145 "%q3 %0,%1,%2"
3146 [(set_attr "type" "logical")])
3147
3148 (define_insn_and_split "*boolcc<mode>3_dot"
3149 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3150 (compare:CC (match_operator:GPR 3 "boolean_operator"
3151 [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
3152 (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
3153 (const_int 0)))
3154 (clobber (match_scratch:GPR 0 "=r,r"))]
3155 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3156 "@
3157 %q3. %0,%1,%2
3158 #"
3159 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3160 [(set (match_dup 0)
3161 (match_dup 3))
3162 (set (match_dup 4)
3163 (compare:CC (match_dup 0)
3164 (const_int 0)))]
3165 ""
3166 [(set_attr "type" "logical")
3167 (set_attr "dot" "yes")
3168 (set_attr "length" "4,8")])
3169
3170 (define_insn_and_split "*boolcc<mode>3_dot2"
3171 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3172 (compare:CC (match_operator:GPR 3 "boolean_operator"
3173 [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
3174 (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
3175 (const_int 0)))
3176 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3177 (match_dup 3))]
3178 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3179 "@
3180 %q3. %0,%1,%2
3181 #"
3182 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3183 [(set (match_dup 0)
3184 (match_dup 3))
3185 (set (match_dup 4)
3186 (compare:CC (match_dup 0)
3187 (const_int 0)))]
3188 ""
3189 [(set_attr "type" "logical")
3190 (set_attr "dot" "yes")
3191 (set_attr "length" "4,8")])
3192
3193
3194 ;; TODO: Should have dots of this as well.
3195 (define_insn "*eqv<mode>3"
3196 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3197 (not:GPR (xor:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3198 (match_operand:GPR 2 "gpc_reg_operand" "r"))))]
3199 ""
3200 "eqv %0,%1,%2"
3201 [(set_attr "type" "logical")])
3202 \f
3203 ;; Rotate and shift insns, in all their variants. These support shifts,
3204 ;; field inserts and extracts, and various combinations thereof.
3205 (define_expand "insv"
3206 [(set (zero_extract (match_operand 0 "gpc_reg_operand" "")
3207 (match_operand:SI 1 "const_int_operand" "")
3208 (match_operand:SI 2 "const_int_operand" ""))
3209 (match_operand 3 "gpc_reg_operand" ""))]
3210 ""
3211 "
3212 {
3213 /* Do not handle 16/8 bit structures that fit in HI/QI modes directly, since
3214 the (SUBREG:SI (REG:HI xxx)) that is otherwise generated can confuse the
3215 compiler if the address of the structure is taken later. Likewise, do
3216 not handle invalid E500 subregs. */
3217 if (GET_CODE (operands[0]) == SUBREG
3218 && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (operands[0]))) < UNITS_PER_WORD
3219 || ((TARGET_E500_DOUBLE || TARGET_SPE)
3220 && invalid_e500_subreg (operands[0], GET_MODE (operands[0])))))
3221 FAIL;
3222
3223 if (TARGET_POWERPC64 && GET_MODE (operands[0]) == DImode)
3224 emit_insn (gen_insvdi_internal (operands[0], operands[1], operands[2],
3225 operands[3]));
3226 else
3227 emit_insn (gen_insvsi_internal (operands[0], operands[1], operands[2],
3228 operands[3]));
3229 DONE;
3230 }")
3231
3232 (define_insn "insvsi_internal"
3233 [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r")
3234 (match_operand:SI 1 "const_int_operand" "i")
3235 (match_operand:SI 2 "const_int_operand" "i"))
3236 (match_operand:SI 3 "gpc_reg_operand" "r"))]
3237 ""
3238 "*
3239 {
3240 int start = INTVAL (operands[2]) & 31;
3241 int size = INTVAL (operands[1]) & 31;
3242
3243 operands[4] = GEN_INT (32 - start - size);
3244 operands[1] = GEN_INT (start + size - 1);
3245 return \"rlwimi %0,%3,%h4,%h2,%h1\";
3246 }"
3247 [(set_attr "type" "insert")])
3248
3249 (define_insn "*insvsi_internal1"
3250 [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r")
3251 (match_operand:SI 1 "const_int_operand" "i")
3252 (match_operand:SI 2 "const_int_operand" "i"))
3253 (rotate:SI (match_operand:SI 3 "gpc_reg_operand" "r")
3254 (match_operand:SI 4 "const_int_operand" "i")))]
3255 "(32 - (INTVAL (operands[4]) & 31)) >= INTVAL (operands[1])"
3256 "*
3257 {
3258 int shift = INTVAL (operands[4]) & 31;
3259 int start = INTVAL (operands[2]) & 31;
3260 int size = INTVAL (operands[1]) & 31;
3261
3262 operands[4] = GEN_INT (shift - start - size);
3263 operands[1] = GEN_INT (start + size - 1);
3264 return \"rlwimi %0,%3,%h4,%h2,%h1\";
3265 }"
3266 [(set_attr "type" "insert")])
3267
3268 (define_insn "*insvsi_internal2"
3269 [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r")
3270 (match_operand:SI 1 "const_int_operand" "i")
3271 (match_operand:SI 2 "const_int_operand" "i"))
3272 (ashiftrt:SI (match_operand:SI 3 "gpc_reg_operand" "r")
3273 (match_operand:SI 4 "const_int_operand" "i")))]
3274 "(32 - (INTVAL (operands[4]) & 31)) >= INTVAL (operands[1])"
3275 "*
3276 {
3277 int shift = INTVAL (operands[4]) & 31;
3278 int start = INTVAL (operands[2]) & 31;
3279 int size = INTVAL (operands[1]) & 31;
3280
3281 operands[4] = GEN_INT (32 - shift - start - size);
3282 operands[1] = GEN_INT (start + size - 1);
3283 return \"rlwimi %0,%3,%h4,%h2,%h1\";
3284 }"
3285 [(set_attr "type" "insert")])
3286
3287 (define_insn "*insvsi_internal3"
3288 [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r")
3289 (match_operand:SI 1 "const_int_operand" "i")
3290 (match_operand:SI 2 "const_int_operand" "i"))
3291 (lshiftrt:SI (match_operand:SI 3 "gpc_reg_operand" "r")
3292 (match_operand:SI 4 "const_int_operand" "i")))]
3293 "(32 - (INTVAL (operands[4]) & 31)) >= INTVAL (operands[1])"
3294 "*
3295 {
3296 int shift = INTVAL (operands[4]) & 31;
3297 int start = INTVAL (operands[2]) & 31;
3298 int size = INTVAL (operands[1]) & 31;
3299
3300 operands[4] = GEN_INT (32 - shift - start - size);
3301 operands[1] = GEN_INT (start + size - 1);
3302 return \"rlwimi %0,%3,%h4,%h2,%h1\";
3303 }"
3304 [(set_attr "type" "insert")])
3305
3306 (define_insn "*insvsi_internal4"
3307 [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r")
3308 (match_operand:SI 1 "const_int_operand" "i")
3309 (match_operand:SI 2 "const_int_operand" "i"))
3310 (zero_extract:SI (match_operand:SI 3 "gpc_reg_operand" "r")
3311 (match_operand:SI 4 "const_int_operand" "i")
3312 (match_operand:SI 5 "const_int_operand" "i")))]
3313 "INTVAL (operands[4]) >= INTVAL (operands[1])"
3314 "*
3315 {
3316 int extract_start = INTVAL (operands[5]) & 31;
3317 int extract_size = INTVAL (operands[4]) & 31;
3318 int insert_start = INTVAL (operands[2]) & 31;
3319 int insert_size = INTVAL (operands[1]) & 31;
3320
3321 /* Align extract field with insert field */
3322 operands[5] = GEN_INT (extract_start + extract_size - insert_start - insert_size);
3323 operands[1] = GEN_INT (insert_start + insert_size - 1);
3324 return \"rlwimi %0,%3,%h5,%h2,%h1\";
3325 }"
3326 [(set_attr "type" "insert")])
3327
3328 ;; combine patterns for rlwimi
3329 (define_insn "*insvsi_internal5"
3330 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
3331 (ior:SI (and:SI (match_operand:SI 4 "gpc_reg_operand" "0")
3332 (match_operand:SI 1 "mask_operand" "i"))
3333 (and:SI (lshiftrt:SI (match_operand:SI 3 "gpc_reg_operand" "r")
3334 (match_operand:SI 2 "const_int_operand" "i"))
3335 (match_operand:SI 5 "mask_operand" "i"))))]
3336 "INTVAL(operands[1]) == ~INTVAL(operands[5])"
3337 "*
3338 {
3339 int me = extract_ME(operands[5]);
3340 int mb = extract_MB(operands[5]);
3341 operands[4] = GEN_INT(32 - INTVAL(operands[2]));
3342 operands[2] = GEN_INT(mb);
3343 operands[1] = GEN_INT(me);
3344 return \"rlwimi %0,%3,%h4,%h2,%h1\";
3345 }"
3346 [(set_attr "type" "insert")])
3347
3348 (define_insn "*insvsi_internal6"
3349 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
3350 (ior:SI (and:SI (lshiftrt:SI (match_operand:SI 3 "gpc_reg_operand" "r")
3351 (match_operand:SI 2 "const_int_operand" "i"))
3352 (match_operand:SI 5 "mask_operand" "i"))
3353 (and:SI (match_operand:SI 4 "gpc_reg_operand" "0")
3354 (match_operand:SI 1 "mask_operand" "i"))))]
3355 "INTVAL(operands[1]) == ~INTVAL(operands[5])"
3356 "*
3357 {
3358 int me = extract_ME(operands[5]);
3359 int mb = extract_MB(operands[5]);
3360 operands[4] = GEN_INT(32 - INTVAL(operands[2]));
3361 operands[2] = GEN_INT(mb);
3362 operands[1] = GEN_INT(me);
3363 return \"rlwimi %0,%3,%h4,%h2,%h1\";
3364 }"
3365 [(set_attr "type" "insert")])
3366
3367 (define_insn "insvdi_internal"
3368 [(set (zero_extract:DI (match_operand:DI 0 "gpc_reg_operand" "+r")
3369 (match_operand:SI 1 "const_int_operand" "i")
3370 (match_operand:SI 2 "const_int_operand" "i"))
3371 (match_operand:DI 3 "gpc_reg_operand" "r"))]
3372 "TARGET_POWERPC64"
3373 "*
3374 {
3375 int start = INTVAL (operands[2]) & 63;
3376 int size = INTVAL (operands[1]) & 63;
3377
3378 operands[1] = GEN_INT (64 - start - size);
3379 return \"rldimi %0,%3,%H1,%H2\";
3380 }"
3381 [(set_attr "type" "insert")
3382 (set_attr "size" "64")])
3383
3384 (define_insn "*insvdi_internal2"
3385 [(set (zero_extract:DI (match_operand:DI 0 "gpc_reg_operand" "+r")
3386 (match_operand:SI 1 "const_int_operand" "i")
3387 (match_operand:SI 2 "const_int_operand" "i"))
3388 (ashiftrt:DI (match_operand:DI 3 "gpc_reg_operand" "r")
3389 (match_operand:SI 4 "const_int_operand" "i")))]
3390 "TARGET_POWERPC64
3391 && insvdi_rshift_rlwimi_p (operands[1], operands[2], operands[4])"
3392 "*
3393 {
3394 int shift = INTVAL (operands[4]) & 63;
3395 int start = (INTVAL (operands[2]) & 63) - 32;
3396 int size = INTVAL (operands[1]) & 63;
3397
3398 operands[4] = GEN_INT (64 - shift - start - size);
3399 operands[2] = GEN_INT (start);
3400 operands[1] = GEN_INT (start + size - 1);
3401 return \"rlwimi %0,%3,%h4,%h2,%h1\";
3402 }")
3403
3404 (define_insn "*insvdi_internal3"
3405 [(set (zero_extract:DI (match_operand:DI 0 "gpc_reg_operand" "+r")
3406 (match_operand:SI 1 "const_int_operand" "i")
3407 (match_operand:SI 2 "const_int_operand" "i"))
3408 (lshiftrt:DI (match_operand:DI 3 "gpc_reg_operand" "r")
3409 (match_operand:SI 4 "const_int_operand" "i")))]
3410 "TARGET_POWERPC64
3411 && insvdi_rshift_rlwimi_p (operands[1], operands[2], operands[4])"
3412 "*
3413 {
3414 int shift = INTVAL (operands[4]) & 63;
3415 int start = (INTVAL (operands[2]) & 63) - 32;
3416 int size = INTVAL (operands[1]) & 63;
3417
3418 operands[4] = GEN_INT (64 - shift - start - size);
3419 operands[2] = GEN_INT (start);
3420 operands[1] = GEN_INT (start + size - 1);
3421 return \"rlwimi %0,%3,%h4,%h2,%h1\";
3422 }")
3423
3424 (define_expand "extzv"
3425 [(set (match_operand 0 "gpc_reg_operand" "")
3426 (zero_extract (match_operand 1 "gpc_reg_operand" "")
3427 (match_operand:SI 2 "const_int_operand" "")
3428 (match_operand:SI 3 "const_int_operand" "")))]
3429 ""
3430 "
3431 {
3432 /* Do not handle 16/8 bit structures that fit in HI/QI modes directly, since
3433 the (SUBREG:SI (REG:HI xxx)) that is otherwise generated can confuse the
3434 compiler if the address of the structure is taken later. */
3435 if (GET_CODE (operands[0]) == SUBREG
3436 && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (operands[0]))) < UNITS_PER_WORD))
3437 FAIL;
3438
3439 if (TARGET_POWERPC64 && GET_MODE (operands[1]) == DImode)
3440 emit_insn (gen_extzvdi_internal (operands[0], operands[1], operands[2],
3441 operands[3]));
3442 else
3443 emit_insn (gen_extzvsi_internal (operands[0], operands[1], operands[2],
3444 operands[3]));
3445 DONE;
3446 }")
3447
3448 (define_insn "extzvsi_internal"
3449 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
3450 (zero_extract:SI (match_operand:SI 1 "gpc_reg_operand" "r")
3451 (match_operand:SI 2 "const_int_operand" "i")
3452 (match_operand:SI 3 "const_int_operand" "i")))]
3453 ""
3454 "*
3455 {
3456 int start = INTVAL (operands[3]) & 31;
3457 int size = INTVAL (operands[2]) & 31;
3458
3459 if (start + size >= 32)
3460 operands[3] = const0_rtx;
3461 else
3462 operands[3] = GEN_INT (start + size);
3463 return \"rlwinm %0,%1,%3,%s2,31\";
3464 }"
3465 [(set_attr "type" "shift")])
3466
3467 (define_insn "*extzvsi_internal1"
3468 [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
3469 (compare:CC (zero_extract:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
3470 (match_operand:SI 2 "const_int_operand" "i,i")
3471 (match_operand:SI 3 "const_int_operand" "i,i"))
3472 (const_int 0)))
3473 (clobber (match_scratch:SI 4 "=r,r"))]
3474 ""
3475 "*
3476 {
3477 int start = INTVAL (operands[3]) & 31;
3478 int size = INTVAL (operands[2]) & 31;
3479
3480 /* Force split for non-cc0 compare. */
3481 if (which_alternative == 1)
3482 return \"#\";
3483
3484 /* If the bit-field being tested fits in the upper or lower half of a
3485 word, it is possible to use andiu. or andil. to test it. This is
3486 useful because the condition register set-use delay is smaller for
3487 andi[ul]. than for rlinm. This doesn't work when the starting bit
3488 position is 0 because the LT and GT bits may be set wrong. */
3489
3490 if ((start > 0 && start + size <= 16) || start >= 16)
3491 {
3492 operands[3] = GEN_INT (((1 << (16 - (start & 15)))
3493 - (1 << (16 - (start & 15) - size))));
3494 if (start < 16)
3495 return \"andis. %4,%1,%3\";
3496 else
3497 return \"andi. %4,%1,%3\";
3498 }
3499
3500 if (start + size >= 32)
3501 operands[3] = const0_rtx;
3502 else
3503 operands[3] = GEN_INT (start + size);
3504 return \"rlwinm. %4,%1,%3,%s2,31\";
3505 }"
3506 [(set_attr "type" "shift")
3507 (set_attr "dot" "yes")
3508 (set_attr "length" "4,8")])
3509
3510 (define_split
3511 [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
3512 (compare:CC (zero_extract:SI (match_operand:SI 1 "gpc_reg_operand" "")
3513 (match_operand:SI 2 "const_int_operand" "")
3514 (match_operand:SI 3 "const_int_operand" ""))
3515 (const_int 0)))
3516 (clobber (match_scratch:SI 4 ""))]
3517 "reload_completed"
3518 [(set (match_dup 4)
3519 (zero_extract:SI (match_dup 1) (match_dup 2)
3520 (match_dup 3)))
3521 (set (match_dup 0)
3522 (compare:CC (match_dup 4)
3523 (const_int 0)))]
3524 "")
3525
3526 (define_insn "*extzvsi_internal2"
3527 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3528 (compare:CC (zero_extract:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
3529 (match_operand:SI 2 "const_int_operand" "i,i")
3530 (match_operand:SI 3 "const_int_operand" "i,i"))
3531 (const_int 0)))
3532 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
3533 (zero_extract:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
3534 ""
3535 "*
3536 {
3537 int start = INTVAL (operands[3]) & 31;
3538 int size = INTVAL (operands[2]) & 31;
3539
3540 /* Force split for non-cc0 compare. */
3541 if (which_alternative == 1)
3542 return \"#\";
3543
3544 /* Since we are using the output value, we can't ignore any need for
3545 a shift. The bit-field must end at the LSB. */
3546 if (start >= 16 && start + size == 32)
3547 {
3548 operands[3] = GEN_INT ((1 << size) - 1);
3549 return \"andi. %0,%1,%3\";
3550 }
3551
3552 if (start + size >= 32)
3553 operands[3] = const0_rtx;
3554 else
3555 operands[3] = GEN_INT (start + size);
3556 return \"rlwinm. %0,%1,%3,%s2,31\";
3557 }"
3558 [(set_attr "type" "shift")
3559 (set_attr "dot" "yes")
3560 (set_attr "length" "4,8")])
3561
3562 (define_split
3563 [(set (match_operand:CC 4 "cc_reg_not_micro_cr0_operand" "")
3564 (compare:CC (zero_extract:SI (match_operand:SI 1 "gpc_reg_operand" "")
3565 (match_operand:SI 2 "const_int_operand" "")
3566 (match_operand:SI 3 "const_int_operand" ""))
3567 (const_int 0)))
3568 (set (match_operand:SI 0 "gpc_reg_operand" "")
3569 (zero_extract:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
3570 "reload_completed"
3571 [(set (match_dup 0)
3572 (zero_extract:SI (match_dup 1) (match_dup 2) (match_dup 3)))
3573 (set (match_dup 4)
3574 (compare:CC (match_dup 0)
3575 (const_int 0)))]
3576 "")
3577
3578 (define_insn "extzvdi_internal"
3579 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3580 (zero_extract:DI (match_operand:DI 1 "gpc_reg_operand" "r")
3581 (match_operand:SI 2 "const_int_operand" "i")
3582 (match_operand:SI 3 "const_int_operand" "i")))]
3583 "TARGET_POWERPC64"
3584 "*
3585 {
3586 int start = INTVAL (operands[3]) & 63;
3587 int size = INTVAL (operands[2]) & 63;
3588
3589 if (start + size >= 64)
3590 operands[3] = const0_rtx;
3591 else
3592 operands[3] = GEN_INT (start + size);
3593 operands[2] = GEN_INT (64 - size);
3594 return \"rldicl %0,%1,%3,%2\";
3595 }"
3596 [(set_attr "type" "shift")])
3597
3598 (define_insn "*extzvdi_internal1"
3599 [(set (match_operand:CC 0 "gpc_reg_operand" "=x")
3600 (compare:CC (zero_extract:DI (match_operand:DI 1 "gpc_reg_operand" "r")
3601 (match_operand:SI 2 "const_int_operand" "i")
3602 (match_operand:SI 3 "const_int_operand" "i"))
3603 (const_int 0)))
3604 (clobber (match_scratch:DI 4 "=r"))]
3605 "TARGET_64BIT && rs6000_gen_cell_microcode"
3606 "*
3607 {
3608 int start = INTVAL (operands[3]) & 63;
3609 int size = INTVAL (operands[2]) & 63;
3610
3611 if (start + size >= 64)
3612 operands[3] = const0_rtx;
3613 else
3614 operands[3] = GEN_INT (start + size);
3615 operands[2] = GEN_INT (64 - size);
3616 return \"rldicl. %4,%1,%3,%2\";
3617 }"
3618 [(set_attr "type" "shift")
3619 (set_attr "dot" "yes")])
3620
3621 (define_insn "*extzvdi_internal2"
3622 [(set (match_operand:CC 4 "gpc_reg_operand" "=x")
3623 (compare:CC (zero_extract:DI (match_operand:DI 1 "gpc_reg_operand" "r")
3624 (match_operand:SI 2 "const_int_operand" "i")
3625 (match_operand:SI 3 "const_int_operand" "i"))
3626 (const_int 0)))
3627 (set (match_operand:DI 0 "gpc_reg_operand" "=r")
3628 (zero_extract:DI (match_dup 1) (match_dup 2) (match_dup 3)))]
3629 "TARGET_64BIT && rs6000_gen_cell_microcode"
3630 "*
3631 {
3632 int start = INTVAL (operands[3]) & 63;
3633 int size = INTVAL (operands[2]) & 63;
3634
3635 if (start + size >= 64)
3636 operands[3] = const0_rtx;
3637 else
3638 operands[3] = GEN_INT (start + size);
3639 operands[2] = GEN_INT (64 - size);
3640 return \"rldicl. %0,%1,%3,%2\";
3641 }"
3642 [(set_attr "type" "shift")
3643 (set_attr "dot" "yes")])
3644
3645
3646 (define_insn "rotl<mode>3"
3647 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3648 (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3649 (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
3650 ""
3651 "rotl<wd>%I2 %0,%1,%<hH>2"
3652 [(set_attr "type" "shift")
3653 (set_attr "maybe_var_shift" "yes")])
3654
3655 (define_insn "*rotlsi3_64"
3656 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3657 (zero_extend:DI
3658 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
3659 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
3660 "TARGET_POWERPC64"
3661 "rotlw%I2 %0,%1,%h2"
3662 [(set_attr "type" "shift")
3663 (set_attr "maybe_var_shift" "yes")])
3664
3665 (define_insn_and_split "*rotl<mode>3_dot"
3666 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3667 (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3668 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
3669 (const_int 0)))
3670 (clobber (match_scratch:GPR 0 "=r,r"))]
3671 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3672 "@
3673 rotl<wd>%I2. %0,%1,%<hH>2
3674 #"
3675 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3676 [(set (match_dup 0)
3677 (rotate:GPR (match_dup 1)
3678 (match_dup 2)))
3679 (set (match_dup 3)
3680 (compare:CC (match_dup 0)
3681 (const_int 0)))]
3682 ""
3683 [(set_attr "type" "shift")
3684 (set_attr "maybe_var_shift" "yes")
3685 (set_attr "dot" "yes")
3686 (set_attr "length" "4,8")])
3687
3688 (define_insn_and_split "*rotl<mode>3_dot2"
3689 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3690 (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3691 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
3692 (const_int 0)))
3693 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3694 (rotate:GPR (match_dup 1)
3695 (match_dup 2)))]
3696 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3697 "@
3698 rotl<wd>%I2. %0,%1,%<hH>2
3699 #"
3700 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3701 [(set (match_dup 0)
3702 (rotate:GPR (match_dup 1)
3703 (match_dup 2)))
3704 (set (match_dup 3)
3705 (compare:CC (match_dup 0)
3706 (const_int 0)))]
3707 ""
3708 [(set_attr "type" "shift")
3709 (set_attr "maybe_var_shift" "yes")
3710 (set_attr "dot" "yes")
3711 (set_attr "length" "4,8")])
3712
3713
3714 (define_insn "*rotlsi3_internal4"
3715 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
3716 (and:SI (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
3717 (match_operand:SI 2 "reg_or_cint_operand" "rn"))
3718 (match_operand:SI 3 "mask_operand" "n")))]
3719 ""
3720 "rlw%I2nm %0,%1,%h2,%m3,%M3"
3721 [(set_attr "type" "shift")
3722 (set_attr "maybe_var_shift" "yes")])
3723
3724 (define_insn "*rotlsi3_internal5"
3725 [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
3726 (compare:CC (and:SI
3727 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
3728 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
3729 (match_operand:SI 3 "mask_operand" "n,n"))
3730 (const_int 0)))
3731 (clobber (match_scratch:SI 4 "=r,r"))]
3732 ""
3733 "@
3734 rlw%I2nm. %4,%1,%h2,%m3,%M3
3735 #"
3736 [(set_attr "type" "shift")
3737 (set_attr "maybe_var_shift" "yes")
3738 (set_attr "dot" "yes")
3739 (set_attr "length" "4,8")])
3740
3741 (define_split
3742 [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
3743 (compare:CC (and:SI
3744 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "")
3745 (match_operand:SI 2 "reg_or_cint_operand" ""))
3746 (match_operand:SI 3 "mask_operand" ""))
3747 (const_int 0)))
3748 (clobber (match_scratch:SI 4 ""))]
3749 "reload_completed"
3750 [(set (match_dup 4)
3751 (and:SI (rotate:SI (match_dup 1)
3752 (match_dup 2))
3753 (match_dup 3)))
3754 (set (match_dup 0)
3755 (compare:CC (match_dup 4)
3756 (const_int 0)))]
3757 "")
3758
3759 (define_insn "*rotlsi3_internal6"
3760 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3761 (compare:CC (and:SI
3762 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
3763 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
3764 (match_operand:SI 3 "mask_operand" "n,n"))
3765 (const_int 0)))
3766 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
3767 (and:SI (rotate:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
3768 ""
3769 "@
3770 rlw%I2nm. %0,%1,%h2,%m3,%M3
3771 #"
3772 [(set_attr "type" "shift")
3773 (set_attr "maybe_var_shift" "yes")
3774 (set_attr "dot" "yes")
3775 (set_attr "length" "4,8")])
3776
3777 (define_split
3778 [(set (match_operand:CC 4 "cc_reg_not_micro_cr0_operand" "")
3779 (compare:CC (and:SI
3780 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "")
3781 (match_operand:SI 2 "reg_or_cint_operand" ""))
3782 (match_operand:SI 3 "mask_operand" ""))
3783 (const_int 0)))
3784 (set (match_operand:SI 0 "gpc_reg_operand" "")
3785 (and:SI (rotate:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
3786 "reload_completed"
3787 [(set (match_dup 0)
3788 (and:SI (rotate:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
3789 (set (match_dup 4)
3790 (compare:CC (match_dup 0)
3791 (const_int 0)))]
3792 "")
3793
3794 (define_insn "*rotlsi3_internal7le"
3795 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
3796 (zero_extend:SI
3797 (subreg:QI
3798 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
3799 (match_operand:SI 2 "reg_or_cint_operand" "ri")) 0)))]
3800 "!BYTES_BIG_ENDIAN"
3801 "rlw%I2nm %0,%1,%h2,0xff"
3802 [(set (attr "cell_micro")
3803 (if_then_else (match_operand:SI 2 "const_int_operand" "")
3804 (const_string "not")
3805 (const_string "always")))
3806 (set_attr "type" "shift")])
3807
3808 (define_insn "*rotlsi3_internal7be"
3809 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
3810 (zero_extend:SI
3811 (subreg:QI
3812 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
3813 (match_operand:SI 2 "reg_or_cint_operand" "ri")) 3)))]
3814 "BYTES_BIG_ENDIAN"
3815 "rlw%I2nm %0,%1,%h2,0xff"
3816 [(set (attr "cell_micro")
3817 (if_then_else (match_operand:SI 2 "const_int_operand" "")
3818 (const_string "not")
3819 (const_string "always")))
3820 (set_attr "type" "shift")])
3821
3822 (define_insn "*rotlsi3_internal8le"
3823 [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
3824 (compare:CC (zero_extend:SI
3825 (subreg:QI
3826 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
3827 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")) 0))
3828 (const_int 0)))
3829 (clobber (match_scratch:SI 3 "=r,r"))]
3830 "!BYTES_BIG_ENDIAN"
3831 "@
3832 rlw%I2nm. %3,%1,%h2,0xff
3833 #"
3834 [(set_attr "type" "shift")
3835 (set_attr "maybe_var_shift" "yes")
3836 (set_attr "dot" "yes")
3837 (set_attr "length" "4,8")])
3838
3839 (define_insn "*rotlsi3_internal8be"
3840 [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
3841 (compare:CC (zero_extend:SI
3842 (subreg:QI
3843 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
3844 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")) 3))
3845 (const_int 0)))
3846 (clobber (match_scratch:SI 3 "=r,r"))]
3847 "BYTES_BIG_ENDIAN"
3848 "@
3849 rlw%I2nm. %3,%1,%h2,0xff
3850 #"
3851 [(set_attr "type" "shift")
3852 (set_attr "maybe_var_shift" "yes")
3853 (set_attr "dot" "yes")
3854 (set_attr "length" "4,8")])
3855
3856 (define_split
3857 [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
3858 (compare:CC (zero_extend:SI
3859 (subreg:QI
3860 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "")
3861 (match_operand:SI 2 "reg_or_cint_operand" "")) 0))
3862 (const_int 0)))
3863 (clobber (match_scratch:SI 3 ""))]
3864 "!BYTES_BIG_ENDIAN && reload_completed"
3865 [(set (match_dup 3)
3866 (zero_extend:SI (subreg:QI
3867 (rotate:SI (match_dup 1)
3868 (match_dup 2)) 0)))
3869 (set (match_dup 0)
3870 (compare:CC (match_dup 3)
3871 (const_int 0)))]
3872 "")
3873
3874 (define_split
3875 [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
3876 (compare:CC (zero_extend:SI
3877 (subreg:QI
3878 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "")
3879 (match_operand:SI 2 "reg_or_cint_operand" "")) 3))
3880 (const_int 0)))
3881 (clobber (match_scratch:SI 3 ""))]
3882 "BYTES_BIG_ENDIAN && reload_completed"
3883 [(set (match_dup 3)
3884 (zero_extend:SI (subreg:QI
3885 (rotate:SI (match_dup 1)
3886 (match_dup 2)) 3)))
3887 (set (match_dup 0)
3888 (compare:CC (match_dup 3)
3889 (const_int 0)))]
3890 "")
3891
3892 (define_insn "*rotlsi3_internal9le"
3893 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3894 (compare:CC (zero_extend:SI
3895 (subreg:QI
3896 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
3897 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")) 0))
3898 (const_int 0)))
3899 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
3900 (zero_extend:SI (subreg:QI (rotate:SI (match_dup 1) (match_dup 2)) 0)))]
3901 "!BYTES_BIG_ENDIAN"
3902 "@
3903 rlw%I2nm. %0,%1,%h2,0xff
3904 #"
3905 [(set_attr "type" "shift")
3906 (set_attr "maybe_var_shift" "yes")
3907 (set_attr "dot" "yes")
3908 (set_attr "length" "4,8")])
3909
3910 (define_insn "*rotlsi3_internal9be"
3911 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3912 (compare:CC (zero_extend:SI
3913 (subreg:QI
3914 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
3915 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")) 3))
3916 (const_int 0)))
3917 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
3918 (zero_extend:SI (subreg:QI (rotate:SI (match_dup 1) (match_dup 2)) 3)))]
3919 "BYTES_BIG_ENDIAN"
3920 "@
3921 rlw%I2nm. %0,%1,%h2,0xff
3922 #"
3923 [(set_attr "type" "shift")
3924 (set_attr "maybe_var_shift" "yes")
3925 (set_attr "dot" "yes")
3926 (set_attr "length" "4,8")])
3927
3928 (define_split
3929 [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "")
3930 (compare:CC (zero_extend:SI
3931 (subreg:QI
3932 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "")
3933 (match_operand:SI 2 "reg_or_cint_operand" "")) 0))
3934 (const_int 0)))
3935 (set (match_operand:SI 0 "gpc_reg_operand" "")
3936 (zero_extend:SI (subreg:QI (rotate:SI (match_dup 1) (match_dup 2)) 0)))]
3937 "!BYTES_BIG_ENDIAN && reload_completed"
3938 [(set (match_dup 0)
3939 (zero_extend:SI (subreg:QI (rotate:SI (match_dup 1) (match_dup 2)) 0)))
3940 (set (match_dup 3)
3941 (compare:CC (match_dup 0)
3942 (const_int 0)))]
3943 "")
3944
3945 (define_split
3946 [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "")
3947 (compare:CC (zero_extend:SI
3948 (subreg:QI
3949 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "")
3950 (match_operand:SI 2 "reg_or_cint_operand" "")) 3))
3951 (const_int 0)))
3952 (set (match_operand:SI 0 "gpc_reg_operand" "")
3953 (zero_extend:SI (subreg:QI (rotate:SI (match_dup 1) (match_dup 2)) 3)))]
3954 "BYTES_BIG_ENDIAN && reload_completed"
3955 [(set (match_dup 0)
3956 (zero_extend:SI (subreg:QI (rotate:SI (match_dup 1) (match_dup 2)) 3)))
3957 (set (match_dup 3)
3958 (compare:CC (match_dup 0)
3959 (const_int 0)))]
3960 "")
3961
3962 (define_insn "*rotlsi3_internal10le"
3963 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
3964 (zero_extend:SI
3965 (subreg:HI
3966 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
3967 (match_operand:SI 2 "reg_or_cint_operand" "rn")) 0)))]
3968 "!BYTES_BIG_ENDIAN"
3969 "rlw%I2nm %0,%1,%h2,0xffff"
3970 [(set_attr "type" "shift")
3971 (set_attr "maybe_var_shift" "yes")])
3972
3973 (define_insn "*rotlsi3_internal10be"
3974 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
3975 (zero_extend:SI
3976 (subreg:HI
3977 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
3978 (match_operand:SI 2 "reg_or_cint_operand" "rn")) 2)))]
3979 "BYTES_BIG_ENDIAN"
3980 "rlw%I2nm %0,%1,%h2,0xffff"
3981 [(set_attr "type" "shift")
3982 (set_attr "maybe_var_shift" "yes")])
3983
3984 (define_insn "*rotlsi3_internal11le"
3985 [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
3986 (compare:CC (zero_extend:SI
3987 (subreg:HI
3988 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
3989 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")) 0))
3990 (const_int 0)))
3991 (clobber (match_scratch:SI 3 "=r,r"))]
3992 "!BYTES_BIG_ENDIAN"
3993 "@
3994 rlw%I2nm. %3,%1,%h2,0xffff
3995 #"
3996 [(set_attr "type" "shift")
3997 (set_attr "maybe_var_shift" "yes")
3998 (set_attr "dot" "yes")
3999 (set_attr "length" "4,8")])
4000
4001 (define_insn "*rotlsi3_internal11be"
4002 [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
4003 (compare:CC (zero_extend:SI
4004 (subreg:HI
4005 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
4006 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")) 2))
4007 (const_int 0)))
4008 (clobber (match_scratch:SI 3 "=r,r"))]
4009 "BYTES_BIG_ENDIAN"
4010 "@
4011 rlw%I2nm. %3,%1,%h2,0xffff
4012 #"
4013 [(set_attr "type" "shift")
4014 (set_attr "maybe_var_shift" "yes")
4015 (set_attr "dot" "yes")
4016 (set_attr "length" "4,8")])
4017
4018 (define_split
4019 [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
4020 (compare:CC (zero_extend:SI
4021 (subreg:HI
4022 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "")
4023 (match_operand:SI 2 "reg_or_cint_operand" "")) 0))
4024 (const_int 0)))
4025 (clobber (match_scratch:SI 3 ""))]
4026 "!BYTES_BIG_ENDIAN && reload_completed"
4027 [(set (match_dup 3)
4028 (zero_extend:SI (subreg:HI
4029 (rotate:SI (match_dup 1)
4030 (match_dup 2)) 0)))
4031 (set (match_dup 0)
4032 (compare:CC (match_dup 3)
4033 (const_int 0)))]
4034 "")
4035
4036 (define_split
4037 [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
4038 (compare:CC (zero_extend:SI
4039 (subreg:HI
4040 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "")
4041 (match_operand:SI 2 "reg_or_cint_operand" "")) 2))
4042 (const_int 0)))
4043 (clobber (match_scratch:SI 3 ""))]
4044 "BYTES_BIG_ENDIAN && reload_completed"
4045 [(set (match_dup 3)
4046 (zero_extend:SI (subreg:HI
4047 (rotate:SI (match_dup 1)
4048 (match_dup 2)) 2)))
4049 (set (match_dup 0)
4050 (compare:CC (match_dup 3)
4051 (const_int 0)))]
4052 "")
4053
4054 (define_insn "*rotlsi3_internal12le"
4055 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4056 (compare:CC (zero_extend:SI
4057 (subreg:HI
4058 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
4059 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")) 0))
4060 (const_int 0)))
4061 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
4062 (zero_extend:SI (subreg:HI (rotate:SI (match_dup 1) (match_dup 2)) 0)))]
4063 "!BYTES_BIG_ENDIAN"
4064 "@
4065 rlw%I2nm. %0,%1,%h2,0xffff
4066 #"
4067 [(set_attr "type" "shift")
4068 (set_attr "maybe_var_shift" "yes")
4069 (set_attr "dot" "yes")
4070 (set_attr "length" "4,8")])
4071
4072 (define_insn "*rotlsi3_internal12be"
4073 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4074 (compare:CC (zero_extend:SI
4075 (subreg:HI
4076 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
4077 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")) 2))
4078 (const_int 0)))
4079 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
4080 (zero_extend:SI (subreg:HI (rotate:SI (match_dup 1) (match_dup 2)) 2)))]
4081 "BYTES_BIG_ENDIAN"
4082 "@
4083 rlw%I2nm. %0,%1,%h2,0xffff
4084 #"
4085 [(set_attr "type" "shift")
4086 (set_attr "maybe_var_shift" "yes")
4087 (set_attr "dot" "yes")
4088 (set_attr "length" "4,8")])
4089
4090 (define_split
4091 [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "")
4092 (compare:CC (zero_extend:SI
4093 (subreg:HI
4094 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "")
4095 (match_operand:SI 2 "reg_or_cint_operand" "")) 0))
4096 (const_int 0)))
4097 (set (match_operand:SI 0 "gpc_reg_operand" "")
4098 (zero_extend:SI (subreg:HI (rotate:SI (match_dup 1) (match_dup 2)) 0)))]
4099 "!BYTES_BIG_ENDIAN && reload_completed"
4100 [(set (match_dup 0)
4101 (zero_extend:SI (subreg:HI (rotate:SI (match_dup 1) (match_dup 2)) 0)))
4102 (set (match_dup 3)
4103 (compare:CC (match_dup 0)
4104 (const_int 0)))]
4105 "")
4106
4107 (define_split
4108 [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "")
4109 (compare:CC (zero_extend:SI
4110 (subreg:HI
4111 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "")
4112 (match_operand:SI 2 "reg_or_cint_operand" "")) 2))
4113 (const_int 0)))
4114 (set (match_operand:SI 0 "gpc_reg_operand" "")
4115 (zero_extend:SI (subreg:HI (rotate:SI (match_dup 1) (match_dup 2)) 2)))]
4116 "BYTES_BIG_ENDIAN && reload_completed"
4117 [(set (match_dup 0)
4118 (zero_extend:SI (subreg:HI (rotate:SI (match_dup 1) (match_dup 2)) 2)))
4119 (set (match_dup 3)
4120 (compare:CC (match_dup 0)
4121 (const_int 0)))]
4122 "")
4123
4124
4125 (define_insn "ashl<mode>3"
4126 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4127 (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4128 (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4129 ""
4130 "sl<wd>%I2 %0,%1,%<hH>2"
4131 [(set_attr "type" "shift")
4132 (set_attr "maybe_var_shift" "yes")])
4133
4134 (define_insn "*ashlsi3_64"
4135 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4136 (zero_extend:DI
4137 (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4138 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4139 "TARGET_POWERPC64"
4140 "slw%I2 %0,%1,%h2"
4141 [(set_attr "type" "shift")
4142 (set_attr "maybe_var_shift" "yes")])
4143
4144 (define_insn_and_split "*ashl<mode>3_dot"
4145 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4146 (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4147 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4148 (const_int 0)))
4149 (clobber (match_scratch:GPR 0 "=r,r"))]
4150 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4151 "@
4152 sl<wd>%I2. %0,%1,%<hH>2
4153 #"
4154 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4155 [(set (match_dup 0)
4156 (ashift:GPR (match_dup 1)
4157 (match_dup 2)))
4158 (set (match_dup 3)
4159 (compare:CC (match_dup 0)
4160 (const_int 0)))]
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_and_split "*ashl<mode>3_dot2"
4168 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4169 (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4170 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4171 (const_int 0)))
4172 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4173 (ashift:GPR (match_dup 1)
4174 (match_dup 2)))]
4175 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4176 "@
4177 sl<wd>%I2. %0,%1,%<hH>2
4178 #"
4179 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4180 [(set (match_dup 0)
4181 (ashift:GPR (match_dup 1)
4182 (match_dup 2)))
4183 (set (match_dup 3)
4184 (compare:CC (match_dup 0)
4185 (const_int 0)))]
4186 ""
4187 [(set_attr "type" "shift")
4188 (set_attr "maybe_var_shift" "yes")
4189 (set_attr "dot" "yes")
4190 (set_attr "length" "4,8")])
4191
4192
4193 (define_insn "rlwinm"
4194 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
4195 (and:SI (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4196 (match_operand:SI 2 "const_int_operand" "i"))
4197 (match_operand:SI 3 "mask_operand" "n")))]
4198 "includes_lshift_p (operands[2], operands[3])"
4199 "rlwinm %0,%1,%h2,%m3,%M3"
4200 [(set_attr "type" "shift")])
4201
4202 (define_insn ""
4203 [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
4204 (compare:CC
4205 (and:SI (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
4206 (match_operand:SI 2 "const_int_operand" "i,i"))
4207 (match_operand:SI 3 "mask_operand" "n,n"))
4208 (const_int 0)))
4209 (clobber (match_scratch:SI 4 "=r,r"))]
4210 "includes_lshift_p (operands[2], operands[3])"
4211 "@
4212 rlwinm. %4,%1,%h2,%m3,%M3
4213 #"
4214 [(set_attr "type" "shift")
4215 (set_attr "dot" "yes")
4216 (set_attr "length" "4,8")])
4217
4218 (define_split
4219 [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
4220 (compare:CC
4221 (and:SI (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "")
4222 (match_operand:SI 2 "const_int_operand" ""))
4223 (match_operand:SI 3 "mask_operand" ""))
4224 (const_int 0)))
4225 (clobber (match_scratch:SI 4 ""))]
4226 "includes_lshift_p (operands[2], operands[3]) && reload_completed"
4227 [(set (match_dup 4)
4228 (and:SI (ashift:SI (match_dup 1) (match_dup 2))
4229 (match_dup 3)))
4230 (set (match_dup 0)
4231 (compare:CC (match_dup 4)
4232 (const_int 0)))]
4233 "")
4234
4235 (define_insn ""
4236 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
4237 (compare:CC
4238 (and:SI (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
4239 (match_operand:SI 2 "const_int_operand" "i,i"))
4240 (match_operand:SI 3 "mask_operand" "n,n"))
4241 (const_int 0)))
4242 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
4243 (and:SI (ashift:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
4244 "includes_lshift_p (operands[2], operands[3])"
4245 "@
4246 rlwinm. %0,%1,%h2,%m3,%M3
4247 #"
4248 [(set_attr "type" "shift")
4249 (set_attr "dot" "yes")
4250 (set_attr "length" "4,8")])
4251
4252 (define_split
4253 [(set (match_operand:CC 4 "cc_reg_not_micro_cr0_operand" "")
4254 (compare:CC
4255 (and:SI (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "")
4256 (match_operand:SI 2 "const_int_operand" ""))
4257 (match_operand:SI 3 "mask_operand" ""))
4258 (const_int 0)))
4259 (set (match_operand:SI 0 "gpc_reg_operand" "")
4260 (and:SI (ashift:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
4261 "includes_lshift_p (operands[2], operands[3]) && reload_completed"
4262 [(set (match_dup 0)
4263 (and:SI (ashift:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
4264 (set (match_dup 4)
4265 (compare:CC (match_dup 0)
4266 (const_int 0)))]
4267 "")
4268
4269
4270 (define_insn "lshr<mode>3"
4271 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4272 (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4273 (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4274 ""
4275 "sr<wd>%I2 %0,%1,%<hH>2"
4276 [(set_attr "type" "shift")
4277 (set_attr "maybe_var_shift" "yes")])
4278
4279 (define_insn "*lshrsi3_64"
4280 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4281 (zero_extend:DI
4282 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4283 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4284 "TARGET_POWERPC64"
4285 "srw%I2 %0,%1,%h2"
4286 [(set_attr "type" "shift")
4287 (set_attr "maybe_var_shift" "yes")])
4288
4289 (define_insn_and_split "*lshr<mode>3_dot"
4290 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4291 (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4292 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4293 (const_int 0)))
4294 (clobber (match_scratch:GPR 0 "=r,r"))]
4295 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4296 "@
4297 sr<wd>%I2. %0,%1,%<hH>2
4298 #"
4299 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4300 [(set (match_dup 0)
4301 (lshiftrt:GPR (match_dup 1)
4302 (match_dup 2)))
4303 (set (match_dup 3)
4304 (compare:CC (match_dup 0)
4305 (const_int 0)))]
4306 ""
4307 [(set_attr "type" "shift")
4308 (set_attr "maybe_var_shift" "yes")
4309 (set_attr "dot" "yes")
4310 (set_attr "length" "4,8")])
4311
4312 (define_insn_and_split "*lshr<mode>3_dot2"
4313 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4314 (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4315 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4316 (const_int 0)))
4317 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4318 (lshiftrt:GPR (match_dup 1)
4319 (match_dup 2)))]
4320 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4321 "@
4322 sr<wd>%I2. %0,%1,%<hH>2
4323 #"
4324 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4325 [(set (match_dup 0)
4326 (lshiftrt:GPR (match_dup 1)
4327 (match_dup 2)))
4328 (set (match_dup 3)
4329 (compare:CC (match_dup 0)
4330 (const_int 0)))]
4331 ""
4332 [(set_attr "type" "shift")
4333 (set_attr "maybe_var_shift" "yes")
4334 (set_attr "dot" "yes")
4335 (set_attr "length" "4,8")])
4336
4337
4338 (define_insn ""
4339 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
4340 (and:SI (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4341 (match_operand:SI 2 "const_int_operand" "i"))
4342 (match_operand:SI 3 "mask_operand" "n")))]
4343 "includes_rshift_p (operands[2], operands[3])"
4344 "rlwinm %0,%1,%s2,%m3,%M3"
4345 [(set_attr "type" "shift")])
4346
4347 (define_insn ""
4348 [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
4349 (compare:CC
4350 (and:SI (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
4351 (match_operand:SI 2 "const_int_operand" "i,i"))
4352 (match_operand:SI 3 "mask_operand" "n,n"))
4353 (const_int 0)))
4354 (clobber (match_scratch:SI 4 "=r,r"))]
4355 "includes_rshift_p (operands[2], operands[3])"
4356 "@
4357 rlwinm. %4,%1,%s2,%m3,%M3
4358 #"
4359 [(set_attr "type" "shift")
4360 (set_attr "dot" "yes")
4361 (set_attr "length" "4,8")])
4362
4363 (define_split
4364 [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
4365 (compare:CC
4366 (and:SI (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "")
4367 (match_operand:SI 2 "const_int_operand" ""))
4368 (match_operand:SI 3 "mask_operand" ""))
4369 (const_int 0)))
4370 (clobber (match_scratch:SI 4 ""))]
4371 "includes_rshift_p (operands[2], operands[3]) && reload_completed"
4372 [(set (match_dup 4)
4373 (and:SI (lshiftrt:SI (match_dup 1) (match_dup 2))
4374 (match_dup 3)))
4375 (set (match_dup 0)
4376 (compare:CC (match_dup 4)
4377 (const_int 0)))]
4378 "")
4379
4380 (define_insn ""
4381 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
4382 (compare:CC
4383 (and:SI (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
4384 (match_operand:SI 2 "const_int_operand" "i,i"))
4385 (match_operand:SI 3 "mask_operand" "n,n"))
4386 (const_int 0)))
4387 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
4388 (and:SI (lshiftrt:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
4389 "includes_rshift_p (operands[2], operands[3])"
4390 "@
4391 rlwinm. %0,%1,%s2,%m3,%M3
4392 #"
4393 [(set_attr "type" "shift")
4394 (set_attr "dot" "yes")
4395 (set_attr "length" "4,8")])
4396
4397 (define_split
4398 [(set (match_operand:CC 4 "cc_reg_not_micro_cr0_operand" "")
4399 (compare:CC
4400 (and:SI (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "")
4401 (match_operand:SI 2 "const_int_operand" ""))
4402 (match_operand:SI 3 "mask_operand" ""))
4403 (const_int 0)))
4404 (set (match_operand:SI 0 "gpc_reg_operand" "")
4405 (and:SI (lshiftrt:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
4406 "includes_rshift_p (operands[2], operands[3]) && reload_completed"
4407 [(set (match_dup 0)
4408 (and:SI (lshiftrt:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
4409 (set (match_dup 4)
4410 (compare:CC (match_dup 0)
4411 (const_int 0)))]
4412 "")
4413
4414 (define_insn "*lshiftrt_internal1le"
4415 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
4416 (zero_extend:SI
4417 (subreg:QI
4418 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4419 (match_operand:SI 2 "const_int_operand" "i")) 0)))]
4420 "!BYTES_BIG_ENDIAN && includes_rshift_p (operands[2], GEN_INT (255))"
4421 "rlwinm %0,%1,%s2,0xff"
4422 [(set_attr "type" "shift")])
4423
4424 (define_insn "*lshiftrt_internal1be"
4425 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
4426 (zero_extend:SI
4427 (subreg:QI
4428 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4429 (match_operand:SI 2 "const_int_operand" "i")) 3)))]
4430 "BYTES_BIG_ENDIAN && includes_rshift_p (operands[2], GEN_INT (255))"
4431 "rlwinm %0,%1,%s2,0xff"
4432 [(set_attr "type" "shift")])
4433
4434 (define_insn "*lshiftrt_internal2le"
4435 [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
4436 (compare:CC
4437 (zero_extend:SI
4438 (subreg:QI
4439 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
4440 (match_operand:SI 2 "const_int_operand" "i,i")) 0))
4441 (const_int 0)))
4442 (clobber (match_scratch:SI 3 "=r,r"))]
4443 "!BYTES_BIG_ENDIAN && includes_rshift_p (operands[2], GEN_INT (255))"
4444 "@
4445 rlwinm. %3,%1,%s2,0xff
4446 #"
4447 [(set_attr "type" "shift")
4448 (set_attr "dot" "yes")
4449 (set_attr "length" "4,8")])
4450
4451 (define_insn "*lshiftrt_internal2be"
4452 [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
4453 (compare:CC
4454 (zero_extend:SI
4455 (subreg:QI
4456 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
4457 (match_operand:SI 2 "const_int_operand" "i,i")) 3))
4458 (const_int 0)))
4459 (clobber (match_scratch:SI 3 "=r,r"))]
4460 "BYTES_BIG_ENDIAN && includes_rshift_p (operands[2], GEN_INT (255))"
4461 "@
4462 rlwinm. %3,%1,%s2,0xff
4463 #"
4464 [(set_attr "type" "shift")
4465 (set_attr "dot" "yes")
4466 (set_attr "length" "4,8")])
4467
4468 (define_split
4469 [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
4470 (compare:CC
4471 (zero_extend:SI
4472 (subreg:QI
4473 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "")
4474 (match_operand:SI 2 "const_int_operand" "")) 0))
4475 (const_int 0)))
4476 (clobber (match_scratch:SI 3 ""))]
4477 "!BYTES_BIG_ENDIAN && includes_rshift_p (operands[2], GEN_INT (255)) && reload_completed"
4478 [(set (match_dup 3)
4479 (zero_extend:SI (subreg:QI
4480 (lshiftrt:SI (match_dup 1)
4481 (match_dup 2)) 0)))
4482 (set (match_dup 0)
4483 (compare:CC (match_dup 3)
4484 (const_int 0)))]
4485 "")
4486
4487 (define_split
4488 [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
4489 (compare:CC
4490 (zero_extend:SI
4491 (subreg:QI
4492 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "")
4493 (match_operand:SI 2 "const_int_operand" "")) 3))
4494 (const_int 0)))
4495 (clobber (match_scratch:SI 3 ""))]
4496 "BYTES_BIG_ENDIAN && includes_rshift_p (operands[2], GEN_INT (255)) && reload_completed"
4497 [(set (match_dup 3)
4498 (zero_extend:SI (subreg:QI
4499 (lshiftrt:SI (match_dup 1)
4500 (match_dup 2)) 3)))
4501 (set (match_dup 0)
4502 (compare:CC (match_dup 3)
4503 (const_int 0)))]
4504 "")
4505
4506 (define_insn "*lshiftrt_internal3le"
4507 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4508 (compare:CC
4509 (zero_extend:SI
4510 (subreg:QI
4511 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
4512 (match_operand:SI 2 "const_int_operand" "i,i")) 0))
4513 (const_int 0)))
4514 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
4515 (zero_extend:SI (subreg:QI (lshiftrt:SI (match_dup 1) (match_dup 2)) 0)))]
4516 "!BYTES_BIG_ENDIAN && includes_rshift_p (operands[2], GEN_INT (255))"
4517 "@
4518 rlwinm. %0,%1,%s2,0xff
4519 #"
4520 [(set_attr "type" "shift")
4521 (set_attr "dot" "yes")
4522 (set_attr "length" "4,8")])
4523
4524 (define_insn "*lshiftrt_internal3be"
4525 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4526 (compare:CC
4527 (zero_extend:SI
4528 (subreg:QI
4529 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
4530 (match_operand:SI 2 "const_int_operand" "i,i")) 3))
4531 (const_int 0)))
4532 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
4533 (zero_extend:SI (subreg:QI (lshiftrt:SI (match_dup 1) (match_dup 2)) 3)))]
4534 "BYTES_BIG_ENDIAN && includes_rshift_p (operands[2], GEN_INT (255))"
4535 "@
4536 rlwinm. %0,%1,%s2,0xff
4537 #"
4538 [(set_attr "type" "shift")
4539 (set_attr "dot" "yes")
4540 (set_attr "length" "4,8")])
4541
4542 (define_split
4543 [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "")
4544 (compare:CC
4545 (zero_extend:SI
4546 (subreg:QI
4547 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "")
4548 (match_operand:SI 2 "const_int_operand" "")) 0))
4549 (const_int 0)))
4550 (set (match_operand:SI 0 "gpc_reg_operand" "")
4551 (zero_extend:SI (subreg:QI (lshiftrt:SI (match_dup 1) (match_dup 2)) 0)))]
4552 "!BYTES_BIG_ENDIAN && includes_rshift_p (operands[2], GEN_INT (255)) && reload_completed"
4553 [(set (match_dup 0)
4554 (zero_extend:SI (subreg:QI (lshiftrt:SI (match_dup 1) (match_dup 2)) 0)))
4555 (set (match_dup 3)
4556 (compare:CC (match_dup 0)
4557 (const_int 0)))]
4558 "")
4559
4560 (define_split
4561 [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "")
4562 (compare:CC
4563 (zero_extend:SI
4564 (subreg:QI
4565 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "")
4566 (match_operand:SI 2 "const_int_operand" "")) 3))
4567 (const_int 0)))
4568 (set (match_operand:SI 0 "gpc_reg_operand" "")
4569 (zero_extend:SI (subreg:QI (lshiftrt:SI (match_dup 1) (match_dup 2)) 3)))]
4570 "BYTES_BIG_ENDIAN && includes_rshift_p (operands[2], GEN_INT (255)) && reload_completed"
4571 [(set (match_dup 0)
4572 (zero_extend:SI (subreg:QI (lshiftrt:SI (match_dup 1) (match_dup 2)) 3)))
4573 (set (match_dup 3)
4574 (compare:CC (match_dup 0)
4575 (const_int 0)))]
4576 "")
4577
4578 (define_insn "*lshiftrt_internal4le"
4579 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
4580 (zero_extend:SI
4581 (subreg:HI
4582 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4583 (match_operand:SI 2 "const_int_operand" "i")) 0)))]
4584 "!BYTES_BIG_ENDIAN && includes_rshift_p (operands[2], GEN_INT (65535))"
4585 "rlwinm %0,%1,%s2,0xffff"
4586 [(set_attr "type" "shift")])
4587
4588 (define_insn "*lshiftrt_internal4be"
4589 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
4590 (zero_extend:SI
4591 (subreg:HI
4592 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4593 (match_operand:SI 2 "const_int_operand" "i")) 2)))]
4594 "BYTES_BIG_ENDIAN && includes_rshift_p (operands[2], GEN_INT (65535))"
4595 "rlwinm %0,%1,%s2,0xffff"
4596 [(set_attr "type" "shift")])
4597
4598 (define_insn "*lshiftrt_internal5le"
4599 [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
4600 (compare:CC
4601 (zero_extend:SI
4602 (subreg:HI
4603 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
4604 (match_operand:SI 2 "const_int_operand" "i,i")) 0))
4605 (const_int 0)))
4606 (clobber (match_scratch:SI 3 "=r,r"))]
4607 "!BYTES_BIG_ENDIAN && includes_rshift_p (operands[2], GEN_INT (65535))"
4608 "@
4609 rlwinm. %3,%1,%s2,0xffff
4610 #"
4611 [(set_attr "type" "shift")
4612 (set_attr "dot" "yes")
4613 (set_attr "length" "4,8")])
4614
4615 (define_insn "*lshiftrt_internal5be"
4616 [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
4617 (compare:CC
4618 (zero_extend:SI
4619 (subreg:HI
4620 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
4621 (match_operand:SI 2 "const_int_operand" "i,i")) 2))
4622 (const_int 0)))
4623 (clobber (match_scratch:SI 3 "=r,r"))]
4624 "BYTES_BIG_ENDIAN && includes_rshift_p (operands[2], GEN_INT (65535))"
4625 "@
4626 rlwinm. %3,%1,%s2,0xffff
4627 #"
4628 [(set_attr "type" "shift")
4629 (set_attr "dot" "yes")
4630 (set_attr "length" "4,8")])
4631
4632 (define_split
4633 [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
4634 (compare:CC
4635 (zero_extend:SI
4636 (subreg:HI
4637 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "")
4638 (match_operand:SI 2 "const_int_operand" "")) 0))
4639 (const_int 0)))
4640 (clobber (match_scratch:SI 3 ""))]
4641 "!BYTES_BIG_ENDIAN && includes_rshift_p (operands[2], GEN_INT (65535)) && reload_completed"
4642 [(set (match_dup 3)
4643 (zero_extend:SI (subreg:HI
4644 (lshiftrt:SI (match_dup 1)
4645 (match_dup 2)) 0)))
4646 (set (match_dup 0)
4647 (compare:CC (match_dup 3)
4648 (const_int 0)))]
4649 "")
4650
4651 (define_split
4652 [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
4653 (compare:CC
4654 (zero_extend:SI
4655 (subreg:HI
4656 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "")
4657 (match_operand:SI 2 "const_int_operand" "")) 2))
4658 (const_int 0)))
4659 (clobber (match_scratch:SI 3 ""))]
4660 "BYTES_BIG_ENDIAN && includes_rshift_p (operands[2], GEN_INT (65535)) && reload_completed"
4661 [(set (match_dup 3)
4662 (zero_extend:SI (subreg:HI
4663 (lshiftrt:SI (match_dup 1)
4664 (match_dup 2)) 2)))
4665 (set (match_dup 0)
4666 (compare:CC (match_dup 3)
4667 (const_int 0)))]
4668 "")
4669
4670 (define_insn "*lshiftrt_internal5le"
4671 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4672 (compare:CC
4673 (zero_extend:SI
4674 (subreg:HI
4675 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
4676 (match_operand:SI 2 "const_int_operand" "i,i")) 0))
4677 (const_int 0)))
4678 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
4679 (zero_extend:SI (subreg:HI (lshiftrt:SI (match_dup 1) (match_dup 2)) 0)))]
4680 "!BYTES_BIG_ENDIAN && includes_rshift_p (operands[2], GEN_INT (65535))"
4681 "@
4682 rlwinm. %0,%1,%s2,0xffff
4683 #"
4684 [(set_attr "type" "shift")
4685 (set_attr "dot" "yes")
4686 (set_attr "length" "4,8")])
4687
4688 (define_insn "*lshiftrt_internal5be"
4689 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4690 (compare:CC
4691 (zero_extend:SI
4692 (subreg:HI
4693 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
4694 (match_operand:SI 2 "const_int_operand" "i,i")) 2))
4695 (const_int 0)))
4696 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
4697 (zero_extend:SI (subreg:HI (lshiftrt:SI (match_dup 1) (match_dup 2)) 2)))]
4698 "BYTES_BIG_ENDIAN && includes_rshift_p (operands[2], GEN_INT (65535))"
4699 "@
4700 rlwinm. %0,%1,%s2,0xffff
4701 #"
4702 [(set_attr "type" "shift")
4703 (set_attr "dot" "yes")
4704 (set_attr "length" "4,8")])
4705
4706 (define_split
4707 [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "")
4708 (compare:CC
4709 (zero_extend:SI
4710 (subreg:HI
4711 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "")
4712 (match_operand:SI 2 "const_int_operand" "")) 0))
4713 (const_int 0)))
4714 (set (match_operand:SI 0 "gpc_reg_operand" "")
4715 (zero_extend:SI (subreg:HI (lshiftrt:SI (match_dup 1) (match_dup 2)) 0)))]
4716 "!BYTES_BIG_ENDIAN && includes_rshift_p (operands[2], GEN_INT (65535)) && reload_completed"
4717 [(set (match_dup 0)
4718 (zero_extend:SI (subreg:HI (lshiftrt:SI (match_dup 1) (match_dup 2)) 0)))
4719 (set (match_dup 3)
4720 (compare:CC (match_dup 0)
4721 (const_int 0)))]
4722 "")
4723
4724 (define_split
4725 [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "")
4726 (compare:CC
4727 (zero_extend:SI
4728 (subreg:HI
4729 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "")
4730 (match_operand:SI 2 "const_int_operand" "")) 2))
4731 (const_int 0)))
4732 (set (match_operand:SI 0 "gpc_reg_operand" "")
4733 (zero_extend:SI (subreg:HI (lshiftrt:SI (match_dup 1) (match_dup 2)) 2)))]
4734 "BYTES_BIG_ENDIAN && includes_rshift_p (operands[2], GEN_INT (65535)) && reload_completed"
4735 [(set (match_dup 0)
4736 (zero_extend:SI (subreg:HI (lshiftrt:SI (match_dup 1) (match_dup 2)) 2)))
4737 (set (match_dup 3)
4738 (compare:CC (match_dup 0)
4739 (const_int 0)))]
4740 "")
4741
4742
4743 (define_expand "ashr<mode>3"
4744 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
4745 (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
4746 (match_operand:SI 2 "reg_or_cint_operand" "")))]
4747 ""
4748 {
4749 /* The generic code does not generate optimal code for the low word
4750 (it should be a rlwimi and a rot). Until we have target code to
4751 solve this generically, keep this expander. */
4752
4753 if (<MODE>mode == DImode && !TARGET_POWERPC64)
4754 {
4755 if (CONST_INT_P (operands[2]))
4756 {
4757 emit_insn (gen_ashrdi3_no_power (operands[0], operands[1], operands[2]));
4758 DONE;
4759 }
4760 else
4761 FAIL;
4762 }
4763 })
4764
4765 (define_insn "*ashr<mode>3"
4766 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4767 (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4768 (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4769 ""
4770 "sra<wd>%I2 %0,%1,%<hH>2"
4771 [(set_attr "type" "shift")
4772 (set_attr "maybe_var_shift" "yes")])
4773
4774 (define_insn "*ashrsi3_64"
4775 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4776 (sign_extend:DI
4777 (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4778 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4779 "TARGET_POWERPC64"
4780 "sraw%I2 %0,%1,%h2"
4781 [(set_attr "type" "shift")
4782 (set_attr "maybe_var_shift" "yes")])
4783
4784 (define_insn_and_split "*ashr<mode>3_dot"
4785 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4786 (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4787 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4788 (const_int 0)))
4789 (clobber (match_scratch:GPR 0 "=r,r"))]
4790 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4791 "@
4792 sra<wd>%I2. %0,%1,%<hH>2
4793 #"
4794 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4795 [(set (match_dup 0)
4796 (ashiftrt:GPR (match_dup 1)
4797 (match_dup 2)))
4798 (set (match_dup 3)
4799 (compare:CC (match_dup 0)
4800 (const_int 0)))]
4801 ""
4802 [(set_attr "type" "shift")
4803 (set_attr "maybe_var_shift" "yes")
4804 (set_attr "dot" "yes")
4805 (set_attr "length" "4,8")])
4806
4807 (define_insn_and_split "*ashr<mode>3_dot2"
4808 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4809 (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4810 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4811 (const_int 0)))
4812 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4813 (ashiftrt:GPR (match_dup 1)
4814 (match_dup 2)))]
4815 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4816 "@
4817 sra<wd>%I2. %0,%1,%<hH>2
4818 #"
4819 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4820 [(set (match_dup 0)
4821 (ashiftrt:GPR (match_dup 1)
4822 (match_dup 2)))
4823 (set (match_dup 3)
4824 (compare:CC (match_dup 0)
4825 (const_int 0)))]
4826 ""
4827 [(set_attr "type" "shift")
4828 (set_attr "maybe_var_shift" "yes")
4829 (set_attr "dot" "yes")
4830 (set_attr "length" "4,8")])
4831 \f
4832 ;; Builtins to replace a division to generate FRE reciprocal estimate
4833 ;; instructions and the necessary fixup instructions
4834 (define_expand "recip<mode>3"
4835 [(match_operand:RECIPF 0 "gpc_reg_operand" "")
4836 (match_operand:RECIPF 1 "gpc_reg_operand" "")
4837 (match_operand:RECIPF 2 "gpc_reg_operand" "")]
4838 "RS6000_RECIP_HAVE_RE_P (<MODE>mode)"
4839 {
4840 rs6000_emit_swdiv (operands[0], operands[1], operands[2], false);
4841 DONE;
4842 })
4843
4844 ;; Split to create division from FRE/FRES/etc. and fixup instead of the normal
4845 ;; hardware division. This is only done before register allocation and with
4846 ;; -ffast-math. This must appear before the divsf3/divdf3 insns.
4847 (define_split
4848 [(set (match_operand:RECIPF 0 "gpc_reg_operand" "")
4849 (div:RECIPF (match_operand 1 "gpc_reg_operand" "")
4850 (match_operand 2 "gpc_reg_operand" "")))]
4851 "RS6000_RECIP_AUTO_RE_P (<MODE>mode)
4852 && can_create_pseudo_p () && optimize_insn_for_speed_p ()
4853 && flag_finite_math_only && !flag_trapping_math && flag_reciprocal_math"
4854 [(const_int 0)]
4855 {
4856 rs6000_emit_swdiv (operands[0], operands[1], operands[2], true);
4857 DONE;
4858 })
4859
4860 ;; Builtins to replace 1/sqrt(x) with instructions using RSQRTE and the
4861 ;; appropriate fixup.
4862 (define_expand "rsqrt<mode>2"
4863 [(match_operand:RECIPF 0 "gpc_reg_operand" "")
4864 (match_operand:RECIPF 1 "gpc_reg_operand" "")]
4865 "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4866 {
4867 rs6000_emit_swrsqrt (operands[0], operands[1]);
4868 DONE;
4869 })
4870 \f
4871 ;; Floating-point insns, excluding normal data motion. We combine the SF/DF
4872 ;; modes here, and also add in conditional vsx/power8-vector support to access
4873 ;; values in the traditional Altivec registers if the appropriate
4874 ;; -mupper-regs-{df,sf} option is enabled.
4875
4876 (define_expand "abs<mode>2"
4877 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4878 (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))]
4879 "TARGET_<MODE>_INSN"
4880 "")
4881
4882 (define_insn "*abs<mode>2_fpr"
4883 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4884 (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4885 "TARGET_<MODE>_FPR"
4886 "@
4887 fabs %0,%1
4888 xsabsdp %x0,%x1"
4889 [(set_attr "type" "fp")
4890 (set_attr "fp_type" "fp_addsub_<Fs>")])
4891
4892 (define_insn "*nabs<mode>2_fpr"
4893 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4894 (neg:SFDF
4895 (abs:SFDF
4896 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))))]
4897 "TARGET_<MODE>_FPR"
4898 "@
4899 fnabs %0,%1
4900 xsnabsdp %x0,%x1"
4901 [(set_attr "type" "fp")
4902 (set_attr "fp_type" "fp_addsub_<Fs>")])
4903
4904 (define_expand "neg<mode>2"
4905 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4906 (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))]
4907 "TARGET_<MODE>_INSN"
4908 "")
4909
4910 (define_insn "*neg<mode>2_fpr"
4911 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4912 (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4913 "TARGET_<MODE>_FPR"
4914 "@
4915 fneg %0,%1
4916 xsnegdp %x0,%x1"
4917 [(set_attr "type" "fp")
4918 (set_attr "fp_type" "fp_addsub_<Fs>")])
4919
4920 (define_expand "add<mode>3"
4921 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4922 (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4923 (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4924 "TARGET_<MODE>_INSN"
4925 "")
4926
4927 (define_insn "*add<mode>3_fpr"
4928 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4929 (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv>")
4930 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")))]
4931 "TARGET_<MODE>_FPR"
4932 "@
4933 fadd<Ftrad> %0,%1,%2
4934 xsadd<Fvsx> %x0,%x1,%x2"
4935 [(set_attr "type" "fp")
4936 (set_attr "fp_type" "fp_addsub_<Fs>")])
4937
4938 (define_expand "sub<mode>3"
4939 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4940 (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4941 (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4942 "TARGET_<MODE>_INSN"
4943 "")
4944
4945 (define_insn "*sub<mode>3_fpr"
4946 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4947 (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")
4948 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")))]
4949 "TARGET_<MODE>_FPR"
4950 "@
4951 fsub<Ftrad> %0,%1,%2
4952 xssub<Fvsx> %x0,%x1,%x2"
4953 [(set_attr "type" "fp")
4954 (set_attr "fp_type" "fp_addsub_<Fs>")])
4955
4956 (define_expand "mul<mode>3"
4957 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4958 (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4959 (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4960 "TARGET_<MODE>_INSN"
4961 "")
4962
4963 (define_insn "*mul<mode>3_fpr"
4964 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4965 (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv>")
4966 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")))]
4967 "TARGET_<MODE>_FPR"
4968 "@
4969 fmul<Ftrad> %0,%1,%2
4970 xsmul<Fvsx> %x0,%x1,%x2"
4971 [(set_attr "type" "dmul")
4972 (set_attr "fp_type" "fp_mul_<Fs>")])
4973
4974 (define_expand "div<mode>3"
4975 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4976 (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4977 (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4978 "TARGET_<MODE>_INSN && !TARGET_SIMPLE_FPU"
4979 "")
4980
4981 (define_insn "*div<mode>3_fpr"
4982 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4983 (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")
4984 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")))]
4985 "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU"
4986 "@
4987 fdiv<Ftrad> %0,%1,%2
4988 xsdiv<Fvsx> %x0,%x1,%x2"
4989 [(set_attr "type" "<Fs>div")
4990 (set_attr "fp_type" "fp_div_<Fs>")])
4991
4992 (define_insn "sqrt<mode>2"
4993 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4994 (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4995 "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU
4996 && (TARGET_PPC_GPOPT || (<MODE>mode == SFmode && TARGET_XILINX_FPU))"
4997 "@
4998 fsqrt<Ftrad> %0,%1
4999 xssqrt<Fvsx> %x0,%x1"
5000 [(set_attr "type" "<Fs>sqrt")
5001 (set_attr "fp_type" "fp_sqrt_<Fs>")])
5002
5003 ;; Floating point reciprocal approximation
5004 (define_insn "fre<Fs>"
5005 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5006 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
5007 UNSPEC_FRES))]
5008 "TARGET_<FFRE>"
5009 "@
5010 fre<Ftrad> %0,%1
5011 xsre<Fvsx> %x0,%x1"
5012 [(set_attr "type" "fp")])
5013
5014 (define_insn "*rsqrt<mode>2"
5015 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5016 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
5017 UNSPEC_RSQRT))]
5018 "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
5019 "@
5020 frsqrte<Ftrad> %0,%1
5021 xsrsqrte<Fvsx> %x0,%x1"
5022 [(set_attr "type" "fp")])
5023
5024 ;; Floating point comparisons
5025 (define_insn "*cmp<mode>_fpr"
5026 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y,y")
5027 (compare:CCFP (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")
5028 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")))]
5029 "TARGET_<MODE>_FPR"
5030 "@
5031 fcmpu %0,%1,%2
5032 xscmpudp %0,%x1,%x2"
5033 [(set_attr "type" "fpcompare")])
5034
5035 ;; Floating point conversions
5036 (define_expand "extendsfdf2"
5037 [(set (match_operand:DF 0 "gpc_reg_operand" "")
5038 (float_extend:DF (match_operand:SF 1 "reg_or_none500mem_operand" "")))]
5039 "TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
5040 "")
5041
5042 (define_insn_and_split "*extendsfdf2_fpr"
5043 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d,d,ws,?ws,wv")
5044 (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand" "0,f,m,0,wy,Z")))]
5045 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
5046 "@
5047 #
5048 fmr %0,%1
5049 lfs%U1%X1 %0,%1
5050 #
5051 xxlor %x0,%x1,%x1
5052 lxsspx %x0,%y1"
5053 "&& reload_completed && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1])"
5054 [(const_int 0)]
5055 {
5056 emit_note (NOTE_INSN_DELETED);
5057 DONE;
5058 }
5059 [(set_attr "type" "fp,fp,fpload,fp,vecsimple,fpload")])
5060
5061 (define_expand "truncdfsf2"
5062 [(set (match_operand:SF 0 "gpc_reg_operand" "")
5063 (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "")))]
5064 "TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
5065 "")
5066
5067 (define_insn "*truncdfsf2_fpr"
5068 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
5069 (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "d")))]
5070 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
5071 "frsp %0,%1"
5072 [(set_attr "type" "fp")])
5073
5074 ;; This expander is here to avoid FLOAT_WORDS_BIGENDIAN tests in
5075 ;; builtins.c and optabs.c that are not correct for IBM long double
5076 ;; when little-endian.
5077 (define_expand "signbittf2"
5078 [(set (match_dup 2)
5079 (float_truncate:DF (match_operand:TF 1 "gpc_reg_operand" "")))
5080 (set (match_dup 3)
5081 (subreg:DI (match_dup 2) 0))
5082 (set (match_dup 4)
5083 (match_dup 5))
5084 (set (match_operand:SI 0 "gpc_reg_operand" "")
5085 (match_dup 6))]
5086 "!TARGET_IEEEQUAD
5087 && TARGET_HARD_FLOAT
5088 && (TARGET_FPRS || TARGET_E500_DOUBLE)
5089 && TARGET_LONG_DOUBLE_128"
5090 {
5091 operands[2] = gen_reg_rtx (DFmode);
5092 operands[3] = gen_reg_rtx (DImode);
5093 if (TARGET_POWERPC64)
5094 {
5095 operands[4] = gen_reg_rtx (DImode);
5096 operands[5] = gen_rtx_LSHIFTRT (DImode, operands[3], GEN_INT (63));
5097 operands[6] = gen_rtx_SUBREG (SImode, operands[4],
5098 WORDS_BIG_ENDIAN ? 4 : 0);
5099 }
5100 else
5101 {
5102 operands[4] = gen_reg_rtx (SImode);
5103 operands[5] = gen_rtx_SUBREG (SImode, operands[3],
5104 WORDS_BIG_ENDIAN ? 0 : 4);
5105 operands[6] = gen_rtx_LSHIFTRT (SImode, operands[4], GEN_INT (31));
5106 }
5107 })
5108
5109 (define_expand "copysign<mode>3"
5110 [(set (match_dup 3)
5111 (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))
5112 (set (match_dup 4)
5113 (neg:SFDF (abs:SFDF (match_dup 1))))
5114 (set (match_operand:SFDF 0 "gpc_reg_operand" "")
5115 (if_then_else:SFDF (ge (match_operand:SFDF 2 "gpc_reg_operand" "")
5116 (match_dup 5))
5117 (match_dup 3)
5118 (match_dup 4)))]
5119 "TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT>
5120 && ((TARGET_PPC_GFXOPT
5121 && !HONOR_NANS (<MODE>mode)
5122 && !HONOR_SIGNED_ZEROS (<MODE>mode))
5123 || TARGET_CMPB
5124 || VECTOR_UNIT_VSX_P (<MODE>mode))"
5125 {
5126 if (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode))
5127 {
5128 emit_insn (gen_copysign<mode>3_fcpsgn (operands[0], operands[1],
5129 operands[2]));
5130 DONE;
5131 }
5132
5133 operands[3] = gen_reg_rtx (<MODE>mode);
5134 operands[4] = gen_reg_rtx (<MODE>mode);
5135 operands[5] = CONST0_RTX (<MODE>mode);
5136 })
5137
5138 ;; Use an unspec rather providing an if-then-else in RTL, to prevent the
5139 ;; compiler from optimizing -0.0
5140 (define_insn "copysign<mode>3_fcpsgn"
5141 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5142 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")
5143 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")]
5144 UNSPEC_COPYSIGN))]
5145 "TARGET_<MODE>_FPR && TARGET_CMPB"
5146 "@
5147 fcpsgn %0,%2,%1
5148 xscpsgn<Fvsx> %x0,%x2,%x1"
5149 [(set_attr "type" "fp")])
5150
5151 ;; For MIN, MAX, and conditional move, we use DEFINE_EXPAND's that involve a
5152 ;; fsel instruction and some auxiliary computations. Then we just have a
5153 ;; single DEFINE_INSN for fsel and the define_splits to make them if made by
5154 ;; combine.
5155 ;; For MIN, MAX on non-VSX machines, and conditional move all of the time, we
5156 ;; use DEFINE_EXPAND's that involve a fsel instruction and some auxiliary
5157 ;; computations. Then we just have a single DEFINE_INSN for fsel and the
5158 ;; define_splits to make them if made by combine. On VSX machines we have the
5159 ;; min/max instructions.
5160 ;;
5161 ;; On VSX, we only check for TARGET_VSX instead of checking for a vsx/p8 vector
5162 ;; to allow either DF/SF to use only traditional registers.
5163
5164 (define_expand "smax<mode>3"
5165 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
5166 (if_then_else:SFDF (ge (match_operand:SFDF 1 "gpc_reg_operand" "")
5167 (match_operand:SFDF 2 "gpc_reg_operand" ""))
5168 (match_dup 1)
5169 (match_dup 2)))]
5170 "TARGET_<MODE>_FPR && TARGET_PPC_GFXOPT && !flag_trapping_math"
5171 {
5172 rs6000_emit_minmax (operands[0], SMAX, operands[1], operands[2]);
5173 DONE;
5174 })
5175
5176 (define_insn "*smax<mode>3_vsx"
5177 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5178 (smax:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv>")
5179 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")))]
5180 "TARGET_<MODE>_FPR && TARGET_VSX"
5181 "xsmaxdp %x0,%x1,%x2"
5182 [(set_attr "type" "fp")])
5183
5184 (define_expand "smin<mode>3"
5185 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
5186 (if_then_else:SFDF (ge (match_operand:SFDF 1 "gpc_reg_operand" "")
5187 (match_operand:SFDF 2 "gpc_reg_operand" ""))
5188 (match_dup 2)
5189 (match_dup 1)))]
5190 "TARGET_<MODE>_FPR && TARGET_PPC_GFXOPT && !flag_trapping_math"
5191 {
5192 rs6000_emit_minmax (operands[0], SMIN, operands[1], operands[2]);
5193 DONE;
5194 })
5195
5196 (define_insn "*smin<mode>3_vsx"
5197 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5198 (smin:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv>")
5199 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")))]
5200 "TARGET_<MODE>_FPR && TARGET_VSX"
5201 "xsmindp %x0,%x1,%x2"
5202 [(set_attr "type" "fp")])
5203
5204 (define_split
5205 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
5206 (match_operator:SFDF 3 "min_max_operator"
5207 [(match_operand:SFDF 1 "gpc_reg_operand" "")
5208 (match_operand:SFDF 2 "gpc_reg_operand" "")]))]
5209 "TARGET_<MODE>_FPR && TARGET_PPC_GFXOPT && !flag_trapping_math
5210 && !TARGET_VSX"
5211 [(const_int 0)]
5212 {
5213 rs6000_emit_minmax (operands[0], GET_CODE (operands[3]), operands[1],
5214 operands[2]);
5215 DONE;
5216 })
5217
5218 (define_split
5219 [(set (match_operand:SF 0 "gpc_reg_operand" "")
5220 (match_operator:SF 3 "min_max_operator"
5221 [(match_operand:SF 1 "gpc_reg_operand" "")
5222 (match_operand:SF 2 "gpc_reg_operand" "")]))]
5223 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS
5224 && TARGET_SINGLE_FLOAT && !flag_trapping_math"
5225 [(const_int 0)]
5226 "
5227 { rs6000_emit_minmax (operands[0], GET_CODE (operands[3]),
5228 operands[1], operands[2]);
5229 DONE;
5230 }")
5231
5232 (define_expand "mov<mode>cc"
5233 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
5234 (if_then_else:GPR (match_operand 1 "comparison_operator" "")
5235 (match_operand:GPR 2 "gpc_reg_operand" "")
5236 (match_operand:GPR 3 "gpc_reg_operand" "")))]
5237 "TARGET_ISEL<sel>"
5238 "
5239 {
5240 if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
5241 DONE;
5242 else
5243 FAIL;
5244 }")
5245
5246 ;; We use the BASE_REGS for the isel input operands because, if rA is
5247 ;; 0, the value of 0 is placed in rD upon truth. Similarly for rB
5248 ;; because we may switch the operands and rB may end up being rA.
5249 ;;
5250 ;; We need 2 patterns: an unsigned and a signed pattern. We could
5251 ;; leave out the mode in operand 4 and use one pattern, but reload can
5252 ;; change the mode underneath our feet and then gets confused trying
5253 ;; to reload the value.
5254 (define_insn "isel_signed_<mode>"
5255 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
5256 (if_then_else:GPR
5257 (match_operator 1 "scc_comparison_operator"
5258 [(match_operand:CC 4 "cc_reg_operand" "y,y")
5259 (const_int 0)])
5260 (match_operand:GPR 2 "reg_or_cint_operand" "O,b")
5261 (match_operand:GPR 3 "gpc_reg_operand" "r,r")))]
5262 "TARGET_ISEL<sel>"
5263 "*
5264 { return output_isel (operands); }"
5265 [(set_attr "type" "isel")
5266 (set_attr "length" "4")])
5267
5268 (define_insn "isel_unsigned_<mode>"
5269 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
5270 (if_then_else:GPR
5271 (match_operator 1 "scc_comparison_operator"
5272 [(match_operand:CCUNS 4 "cc_reg_operand" "y,y")
5273 (const_int 0)])
5274 (match_operand:GPR 2 "reg_or_cint_operand" "O,b")
5275 (match_operand:GPR 3 "gpc_reg_operand" "r,r")))]
5276 "TARGET_ISEL<sel>"
5277 "*
5278 { return output_isel (operands); }"
5279 [(set_attr "type" "isel")
5280 (set_attr "length" "4")])
5281
5282 ;; These patterns can be useful for combine; they let combine know that
5283 ;; isel can handle reversed comparisons so long as the operands are
5284 ;; registers.
5285
5286 (define_insn "*isel_reversed_signed_<mode>"
5287 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
5288 (if_then_else:GPR
5289 (match_operator 1 "scc_rev_comparison_operator"
5290 [(match_operand:CC 4 "cc_reg_operand" "y")
5291 (const_int 0)])
5292 (match_operand:GPR 2 "gpc_reg_operand" "b")
5293 (match_operand:GPR 3 "gpc_reg_operand" "b")))]
5294 "TARGET_ISEL<sel>"
5295 "*
5296 { return output_isel (operands); }"
5297 [(set_attr "type" "isel")
5298 (set_attr "length" "4")])
5299
5300 (define_insn "*isel_reversed_unsigned_<mode>"
5301 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
5302 (if_then_else:GPR
5303 (match_operator 1 "scc_rev_comparison_operator"
5304 [(match_operand:CCUNS 4 "cc_reg_operand" "y")
5305 (const_int 0)])
5306 (match_operand:GPR 2 "gpc_reg_operand" "b")
5307 (match_operand:GPR 3 "gpc_reg_operand" "b")))]
5308 "TARGET_ISEL<sel>"
5309 "*
5310 { return output_isel (operands); }"
5311 [(set_attr "type" "isel")
5312 (set_attr "length" "4")])
5313
5314 (define_expand "movsfcc"
5315 [(set (match_operand:SF 0 "gpc_reg_operand" "")
5316 (if_then_else:SF (match_operand 1 "comparison_operator" "")
5317 (match_operand:SF 2 "gpc_reg_operand" "")
5318 (match_operand:SF 3 "gpc_reg_operand" "")))]
5319 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT"
5320 "
5321 {
5322 if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
5323 DONE;
5324 else
5325 FAIL;
5326 }")
5327
5328 (define_insn "*fselsfsf4"
5329 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
5330 (if_then_else:SF (ge (match_operand:SF 1 "gpc_reg_operand" "f")
5331 (match_operand:SF 4 "zero_fp_constant" "F"))
5332 (match_operand:SF 2 "gpc_reg_operand" "f")
5333 (match_operand:SF 3 "gpc_reg_operand" "f")))]
5334 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT"
5335 "fsel %0,%1,%2,%3"
5336 [(set_attr "type" "fp")])
5337
5338 (define_insn "*fseldfsf4"
5339 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
5340 (if_then_else:SF (ge (match_operand:DF 1 "gpc_reg_operand" "d")
5341 (match_operand:DF 4 "zero_fp_constant" "F"))
5342 (match_operand:SF 2 "gpc_reg_operand" "f")
5343 (match_operand:SF 3 "gpc_reg_operand" "f")))]
5344 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_SINGLE_FLOAT"
5345 "fsel %0,%1,%2,%3"
5346 [(set_attr "type" "fp")])
5347
5348 ;; The conditional move instructions allow us to perform max and min
5349 ;; operations even when
5350
5351 (define_split
5352 [(set (match_operand:DF 0 "gpc_reg_operand" "")
5353 (match_operator:DF 3 "min_max_operator"
5354 [(match_operand:DF 1 "gpc_reg_operand" "")
5355 (match_operand:DF 2 "gpc_reg_operand" "")]))]
5356 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5357 && !flag_trapping_math"
5358 [(const_int 0)]
5359 "
5360 { rs6000_emit_minmax (operands[0], GET_CODE (operands[3]),
5361 operands[1], operands[2]);
5362 DONE;
5363 }")
5364
5365 (define_expand "movdfcc"
5366 [(set (match_operand:DF 0 "gpc_reg_operand" "")
5367 (if_then_else:DF (match_operand 1 "comparison_operator" "")
5368 (match_operand:DF 2 "gpc_reg_operand" "")
5369 (match_operand:DF 3 "gpc_reg_operand" "")))]
5370 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
5371 "
5372 {
5373 if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
5374 DONE;
5375 else
5376 FAIL;
5377 }")
5378
5379 (define_insn "*fseldfdf4"
5380 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
5381 (if_then_else:DF (ge (match_operand:DF 1 "gpc_reg_operand" "d")
5382 (match_operand:DF 4 "zero_fp_constant" "F"))
5383 (match_operand:DF 2 "gpc_reg_operand" "d")
5384 (match_operand:DF 3 "gpc_reg_operand" "d")))]
5385 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
5386 "fsel %0,%1,%2,%3"
5387 [(set_attr "type" "fp")])
5388
5389 (define_insn "*fselsfdf4"
5390 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
5391 (if_then_else:DF (ge (match_operand:SF 1 "gpc_reg_operand" "f")
5392 (match_operand:SF 4 "zero_fp_constant" "F"))
5393 (match_operand:DF 2 "gpc_reg_operand" "d")
5394 (match_operand:DF 3 "gpc_reg_operand" "d")))]
5395 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_SINGLE_FLOAT"
5396 "fsel %0,%1,%2,%3"
5397 [(set_attr "type" "fp")])
5398 \f
5399 ;; Conversions to and from floating-point.
5400
5401 ; We don't define lfiwax/lfiwzx with the normal definition, because we
5402 ; don't want to support putting SImode in FPR registers.
5403 (define_insn "lfiwax"
5404 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wj,!wj")
5405 (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r")]
5406 UNSPEC_LFIWAX))]
5407 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX"
5408 "@
5409 lfiwax %0,%y1
5410 lxsiwax %x0,%y1
5411 mtvsrwa %x0,%1"
5412 [(set_attr "type" "fpload,fpload,mffgpr")])
5413
5414 ; This split must be run before register allocation because it allocates the
5415 ; memory slot that is needed to move values to/from the FPR. We don't allocate
5416 ; it earlier to allow for the combiner to merge insns together where it might
5417 ; not be needed and also in case the insns are deleted as dead code.
5418
5419 (define_insn_and_split "floatsi<mode>2_lfiwax"
5420 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
5421 (float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r")))
5422 (clobber (match_scratch:DI 2 "=d"))]
5423 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX
5424 && <SI_CONVERT_FP> && can_create_pseudo_p ()"
5425 "#"
5426 ""
5427 [(pc)]
5428 "
5429 {
5430 rtx dest = operands[0];
5431 rtx src = operands[1];
5432 rtx tmp;
5433
5434 if (!MEM_P (src) && TARGET_POWERPC64
5435 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5436 tmp = convert_to_mode (DImode, src, false);
5437 else
5438 {
5439 tmp = operands[2];
5440 if (GET_CODE (tmp) == SCRATCH)
5441 tmp = gen_reg_rtx (DImode);
5442 if (MEM_P (src))
5443 {
5444 src = rs6000_address_for_fpconvert (src);
5445 emit_insn (gen_lfiwax (tmp, src));
5446 }
5447 else
5448 {
5449 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5450 emit_move_insn (stack, src);
5451 emit_insn (gen_lfiwax (tmp, stack));
5452 }
5453 }
5454 emit_insn (gen_floatdi<mode>2 (dest, tmp));
5455 DONE;
5456 }"
5457 [(set_attr "length" "12")
5458 (set_attr "type" "fpload")])
5459
5460 (define_insn_and_split "floatsi<mode>2_lfiwax_mem"
5461 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,<rreg2>")
5462 (float:SFDF
5463 (sign_extend:DI
5464 (match_operand:SI 1 "indexed_or_indirect_operand" "Z,Z"))))
5465 (clobber (match_scratch:DI 2 "=0,d"))]
5466 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX
5467 && <SI_CONVERT_FP>"
5468 "#"
5469 ""
5470 [(pc)]
5471 "
5472 {
5473 operands[1] = rs6000_address_for_fpconvert (operands[1]);
5474 if (GET_CODE (operands[2]) == SCRATCH)
5475 operands[2] = gen_reg_rtx (DImode);
5476 emit_insn (gen_lfiwax (operands[2], operands[1]));
5477 emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
5478 DONE;
5479 }"
5480 [(set_attr "length" "8")
5481 (set_attr "type" "fpload")])
5482
5483 (define_insn "lfiwzx"
5484 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wj,!wj")
5485 (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r")]
5486 UNSPEC_LFIWZX))]
5487 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX"
5488 "@
5489 lfiwzx %0,%y1
5490 lxsiwzx %x0,%y1
5491 mtvsrwz %x0,%1"
5492 [(set_attr "type" "fpload,fpload,mftgpr")])
5493
5494 (define_insn_and_split "floatunssi<mode>2_lfiwzx"
5495 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
5496 (unsigned_float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r")))
5497 (clobber (match_scratch:DI 2 "=d"))]
5498 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX
5499 && <SI_CONVERT_FP>"
5500 "#"
5501 ""
5502 [(pc)]
5503 "
5504 {
5505 rtx dest = operands[0];
5506 rtx src = operands[1];
5507 rtx tmp;
5508
5509 if (!MEM_P (src) && TARGET_POWERPC64
5510 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5511 tmp = convert_to_mode (DImode, src, true);
5512 else
5513 {
5514 tmp = operands[2];
5515 if (GET_CODE (tmp) == SCRATCH)
5516 tmp = gen_reg_rtx (DImode);
5517 if (MEM_P (src))
5518 {
5519 src = rs6000_address_for_fpconvert (src);
5520 emit_insn (gen_lfiwzx (tmp, src));
5521 }
5522 else
5523 {
5524 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5525 emit_move_insn (stack, src);
5526 emit_insn (gen_lfiwzx (tmp, stack));
5527 }
5528 }
5529 emit_insn (gen_floatdi<mode>2 (dest, tmp));
5530 DONE;
5531 }"
5532 [(set_attr "length" "12")
5533 (set_attr "type" "fpload")])
5534
5535 (define_insn_and_split "floatunssi<mode>2_lfiwzx_mem"
5536 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,<rreg2>")
5537 (unsigned_float:SFDF
5538 (zero_extend:DI
5539 (match_operand:SI 1 "indexed_or_indirect_operand" "Z,Z"))))
5540 (clobber (match_scratch:DI 2 "=0,d"))]
5541 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX
5542 && <SI_CONVERT_FP>"
5543 "#"
5544 ""
5545 [(pc)]
5546 "
5547 {
5548 operands[1] = rs6000_address_for_fpconvert (operands[1]);
5549 if (GET_CODE (operands[2]) == SCRATCH)
5550 operands[2] = gen_reg_rtx (DImode);
5551 emit_insn (gen_lfiwzx (operands[2], operands[1]));
5552 emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
5553 DONE;
5554 }"
5555 [(set_attr "length" "8")
5556 (set_attr "type" "fpload")])
5557
5558 ; For each of these conversions, there is a define_expand, a define_insn
5559 ; with a '#' template, and a define_split (with C code). The idea is
5560 ; to allow constant folding with the template of the define_insn,
5561 ; then to have the insns split later (between sched1 and final).
5562
5563 (define_expand "floatsidf2"
5564 [(parallel [(set (match_operand:DF 0 "gpc_reg_operand" "")
5565 (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))
5566 (use (match_dup 2))
5567 (use (match_dup 3))
5568 (clobber (match_dup 4))
5569 (clobber (match_dup 5))
5570 (clobber (match_dup 6))])]
5571 "TARGET_HARD_FLOAT
5572 && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
5573 "
5574 {
5575 if (TARGET_E500_DOUBLE)
5576 {
5577 if (!REG_P (operands[1]))
5578 operands[1] = force_reg (SImode, operands[1]);
5579 emit_insn (gen_spe_floatsidf2 (operands[0], operands[1]));
5580 DONE;
5581 }
5582 else if (TARGET_LFIWAX && TARGET_FCFID)
5583 {
5584 emit_insn (gen_floatsidf2_lfiwax (operands[0], operands[1]));
5585 DONE;
5586 }
5587 else if (TARGET_FCFID)
5588 {
5589 rtx dreg = operands[1];
5590 if (!REG_P (dreg))
5591 dreg = force_reg (SImode, dreg);
5592 dreg = convert_to_mode (DImode, dreg, false);
5593 emit_insn (gen_floatdidf2 (operands[0], dreg));
5594 DONE;
5595 }
5596
5597 if (!REG_P (operands[1]))
5598 operands[1] = force_reg (SImode, operands[1]);
5599 operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5600 operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503601774854144\", DFmode));
5601 operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5602 operands[5] = gen_reg_rtx (DFmode);
5603 operands[6] = gen_reg_rtx (SImode);
5604 }")
5605
5606 (define_insn_and_split "*floatsidf2_internal"
5607 [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5608 (float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5609 (use (match_operand:SI 2 "gpc_reg_operand" "r"))
5610 (use (match_operand:DF 3 "gpc_reg_operand" "d"))
5611 (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
5612 (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))
5613 (clobber (match_operand:SI 6 "gpc_reg_operand" "=&r"))]
5614 "! TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
5615 "#"
5616 ""
5617 [(pc)]
5618 "
5619 {
5620 rtx lowword, highword;
5621 gcc_assert (MEM_P (operands[4]));
5622 highword = adjust_address (operands[4], SImode, 0);
5623 lowword = adjust_address (operands[4], SImode, 4);
5624 if (! WORDS_BIG_ENDIAN)
5625 {
5626 rtx tmp;
5627 tmp = highword; highword = lowword; lowword = tmp;
5628 }
5629
5630 emit_insn (gen_xorsi3 (operands[6], operands[1],
5631 GEN_INT (~ (HOST_WIDE_INT) 0x7fffffff)));
5632 emit_move_insn (lowword, operands[6]);
5633 emit_move_insn (highword, operands[2]);
5634 emit_move_insn (operands[5], operands[4]);
5635 emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5636 DONE;
5637 }"
5638 [(set_attr "length" "24")
5639 (set_attr "type" "fp")])
5640
5641 ;; If we don't have a direct conversion to single precision, don't enable this
5642 ;; conversion for 32-bit without fast math, because we don't have the insn to
5643 ;; generate the fixup swizzle to avoid double rounding problems.
5644 (define_expand "floatunssisf2"
5645 [(set (match_operand:SF 0 "gpc_reg_operand" "")
5646 (unsigned_float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
5647 "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
5648 && (!TARGET_FPRS
5649 || (TARGET_FPRS
5650 && ((TARGET_FCFIDUS && TARGET_LFIWZX)
5651 || (TARGET_DOUBLE_FLOAT && TARGET_FCFID
5652 && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))))"
5653 "
5654 {
5655 if (!TARGET_FPRS)
5656 {
5657 if (!REG_P (operands[1]))
5658 operands[1] = force_reg (SImode, operands[1]);
5659 }
5660 else if (TARGET_LFIWZX && TARGET_FCFIDUS)
5661 {
5662 emit_insn (gen_floatunssisf2_lfiwzx (operands[0], operands[1]));
5663 DONE;
5664 }
5665 else
5666 {
5667 rtx dreg = operands[1];
5668 if (!REG_P (dreg))
5669 dreg = force_reg (SImode, dreg);
5670 dreg = convert_to_mode (DImode, dreg, true);
5671 emit_insn (gen_floatdisf2 (operands[0], dreg));
5672 DONE;
5673 }
5674 }")
5675
5676 (define_expand "floatunssidf2"
5677 [(parallel [(set (match_operand:DF 0 "gpc_reg_operand" "")
5678 (unsigned_float:DF (match_operand:SI 1 "nonimmediate_operand" "")))
5679 (use (match_dup 2))
5680 (use (match_dup 3))
5681 (clobber (match_dup 4))
5682 (clobber (match_dup 5))])]
5683 "TARGET_HARD_FLOAT
5684 && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
5685 "
5686 {
5687 if (TARGET_E500_DOUBLE)
5688 {
5689 if (!REG_P (operands[1]))
5690 operands[1] = force_reg (SImode, operands[1]);
5691 emit_insn (gen_spe_floatunssidf2 (operands[0], operands[1]));
5692 DONE;
5693 }
5694 else if (TARGET_LFIWZX && TARGET_FCFID)
5695 {
5696 emit_insn (gen_floatunssidf2_lfiwzx (operands[0], operands[1]));
5697 DONE;
5698 }
5699 else if (TARGET_FCFID)
5700 {
5701 rtx dreg = operands[1];
5702 if (!REG_P (dreg))
5703 dreg = force_reg (SImode, dreg);
5704 dreg = convert_to_mode (DImode, dreg, true);
5705 emit_insn (gen_floatdidf2 (operands[0], dreg));
5706 DONE;
5707 }
5708
5709 if (!REG_P (operands[1]))
5710 operands[1] = force_reg (SImode, operands[1]);
5711 operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5712 operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503599627370496\", DFmode));
5713 operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5714 operands[5] = gen_reg_rtx (DFmode);
5715 }")
5716
5717 (define_insn_and_split "*floatunssidf2_internal"
5718 [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5719 (unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5720 (use (match_operand:SI 2 "gpc_reg_operand" "r"))
5721 (use (match_operand:DF 3 "gpc_reg_operand" "d"))
5722 (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
5723 (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))]
5724 "! TARGET_FCFIDU && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5725 && !(TARGET_FCFID && TARGET_POWERPC64)"
5726 "#"
5727 ""
5728 [(pc)]
5729 "
5730 {
5731 rtx lowword, highword;
5732 gcc_assert (MEM_P (operands[4]));
5733 highword = adjust_address (operands[4], SImode, 0);
5734 lowword = adjust_address (operands[4], SImode, 4);
5735 if (! WORDS_BIG_ENDIAN)
5736 {
5737 rtx tmp;
5738 tmp = highword; highword = lowword; lowword = tmp;
5739 }
5740
5741 emit_move_insn (lowword, operands[1]);
5742 emit_move_insn (highword, operands[2]);
5743 emit_move_insn (operands[5], operands[4]);
5744 emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5745 DONE;
5746 }"
5747 [(set_attr "length" "20")
5748 (set_attr "type" "fp")])
5749
5750 (define_expand "fix_trunc<mode>si2"
5751 [(set (match_operand:SI 0 "gpc_reg_operand" "")
5752 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "")))]
5753 "TARGET_HARD_FLOAT && ((TARGET_FPRS && <TARGET_FLOAT>) || <E500_CONVERT>)"
5754 "
5755 {
5756 if (!<E500_CONVERT>)
5757 {
5758 rtx tmp, stack;
5759
5760 if (TARGET_STFIWX)
5761 emit_insn (gen_fix_trunc<mode>si2_stfiwx (operands[0], operands[1]));
5762 else
5763 {
5764 tmp = gen_reg_rtx (DImode);
5765 stack = rs6000_allocate_stack_temp (DImode, true, false);
5766 emit_insn (gen_fix_trunc<mode>si2_internal (operands[0], operands[1],
5767 tmp, stack));
5768 }
5769 DONE;
5770 }
5771 }")
5772
5773 ; Like the convert to float patterns, this insn must be split before
5774 ; register allocation so that it can allocate the memory slot if it
5775 ; needed
5776 (define_insn_and_split "fix_trunc<mode>si2_stfiwx"
5777 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5778 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
5779 (clobber (match_scratch:DI 2 "=d"))]
5780 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5781 && (<MODE>mode != SFmode || TARGET_SINGLE_FLOAT)
5782 && TARGET_STFIWX && can_create_pseudo_p ()"
5783 "#"
5784 ""
5785 [(pc)]
5786 {
5787 rtx dest = operands[0];
5788 rtx src = operands[1];
5789 rtx tmp = operands[2];
5790
5791 if (GET_CODE (tmp) == SCRATCH)
5792 tmp = gen_reg_rtx (DImode);
5793
5794 emit_insn (gen_fctiwz_<mode> (tmp, src));
5795 if (MEM_P (dest))
5796 {
5797 dest = rs6000_address_for_fpconvert (dest);
5798 emit_insn (gen_stfiwx (dest, tmp));
5799 DONE;
5800 }
5801 else if (TARGET_POWERPC64 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5802 {
5803 dest = gen_lowpart (DImode, dest);
5804 emit_move_insn (dest, tmp);
5805 DONE;
5806 }
5807 else
5808 {
5809 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5810 emit_insn (gen_stfiwx (stack, tmp));
5811 emit_move_insn (dest, stack);
5812 DONE;
5813 }
5814 }
5815 [(set_attr "length" "12")
5816 (set_attr "type" "fp")])
5817
5818 (define_insn_and_split "fix_trunc<mode>si2_internal"
5819 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,?r")
5820 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d,<rreg>")))
5821 (clobber (match_operand:DI 2 "gpc_reg_operand" "=1,d"))
5822 (clobber (match_operand:DI 3 "offsettable_mem_operand" "=o,o"))]
5823 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
5824 "#"
5825 ""
5826 [(pc)]
5827 "
5828 {
5829 rtx lowword;
5830 gcc_assert (MEM_P (operands[3]));
5831 lowword = adjust_address (operands[3], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
5832
5833 emit_insn (gen_fctiwz_<mode> (operands[2], operands[1]));
5834 emit_move_insn (operands[3], operands[2]);
5835 emit_move_insn (operands[0], lowword);
5836 DONE;
5837 }"
5838 [(set_attr "length" "16")
5839 (set_attr "type" "fp")])
5840
5841 (define_expand "fix_trunc<mode>di2"
5842 [(set (match_operand:DI 0 "gpc_reg_operand" "")
5843 (fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "")))]
5844 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS
5845 && TARGET_FCFID"
5846 "")
5847
5848 (define_insn "*fix_trunc<mode>di2_fctidz"
5849 [(set (match_operand:DI 0 "gpc_reg_operand" "=d")
5850 (fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "d")))]
5851 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS
5852 && TARGET_FCFID && !VECTOR_UNIT_VSX_P (<MODE>mode)"
5853 "fctidz %0,%1"
5854 [(set_attr "type" "fp")])
5855
5856 (define_expand "fixuns_trunc<mode>si2"
5857 [(set (match_operand:SI 0 "gpc_reg_operand" "")
5858 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "")))]
5859 "TARGET_HARD_FLOAT
5860 && ((TARGET_FPRS && <TARGET_FLOAT> && TARGET_FCTIWUZ && TARGET_STFIWX)
5861 || <E500_CONVERT>)"
5862 "
5863 {
5864 if (!<E500_CONVERT>)
5865 {
5866 emit_insn (gen_fixuns_trunc<mode>si2_stfiwx (operands[0], operands[1]));
5867 DONE;
5868 }
5869 }")
5870
5871 (define_insn_and_split "fixuns_trunc<mode>si2_stfiwx"
5872 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5873 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
5874 (clobber (match_scratch:DI 2 "=d"))]
5875 "TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT> && TARGET_FCTIWUZ
5876 && TARGET_STFIWX && can_create_pseudo_p ()"
5877 "#"
5878 ""
5879 [(pc)]
5880 {
5881 rtx dest = operands[0];
5882 rtx src = operands[1];
5883 rtx tmp = operands[2];
5884
5885 if (GET_CODE (tmp) == SCRATCH)
5886 tmp = gen_reg_rtx (DImode);
5887
5888 emit_insn (gen_fctiwuz_<mode> (tmp, src));
5889 if (MEM_P (dest))
5890 {
5891 dest = rs6000_address_for_fpconvert (dest);
5892 emit_insn (gen_stfiwx (dest, tmp));
5893 DONE;
5894 }
5895 else if (TARGET_POWERPC64 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5896 {
5897 dest = gen_lowpart (DImode, dest);
5898 emit_move_insn (dest, tmp);
5899 DONE;
5900 }
5901 else
5902 {
5903 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5904 emit_insn (gen_stfiwx (stack, tmp));
5905 emit_move_insn (dest, stack);
5906 DONE;
5907 }
5908 }
5909 [(set_attr "length" "12")
5910 (set_attr "type" "fp")])
5911
5912 (define_expand "fixuns_trunc<mode>di2"
5913 [(set (match_operand:DI 0 "register_operand" "")
5914 (unsigned_fix:DI (match_operand:SFDF 1 "register_operand" "")))]
5915 "TARGET_HARD_FLOAT && (TARGET_FCTIDUZ || VECTOR_UNIT_VSX_P (<MODE>mode))"
5916 "")
5917
5918 (define_insn "*fixuns_trunc<mode>di2_fctiduz"
5919 [(set (match_operand:DI 0 "gpc_reg_operand" "=d")
5920 (unsigned_fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "d")))]
5921 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS
5922 && TARGET_FCTIDUZ && !VECTOR_UNIT_VSX_P (<MODE>mode)"
5923 "fctiduz %0,%1"
5924 [(set_attr "type" "fp")])
5925
5926 ; Here, we use (set (reg) (unspec:DI [(fix:SI ...)] UNSPEC_FCTIWZ))
5927 ; rather than (set (subreg:SI (reg)) (fix:SI ...))
5928 ; because the first makes it clear that operand 0 is not live
5929 ; before the instruction.
5930 (define_insn "fctiwz_<mode>"
5931 [(set (match_operand:DI 0 "gpc_reg_operand" "=d")
5932 (unspec:DI [(fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))]
5933 UNSPEC_FCTIWZ))]
5934 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
5935 "fctiwz %0,%1"
5936 [(set_attr "type" "fp")])
5937
5938 (define_insn "fctiwuz_<mode>"
5939 [(set (match_operand:DI 0 "gpc_reg_operand" "=d")
5940 (unspec:DI [(unsigned_fix:SI
5941 (match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>"))]
5942 UNSPEC_FCTIWUZ))]
5943 "TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT> && TARGET_FCTIWUZ"
5944 "fctiwuz %0,%1"
5945 [(set_attr "type" "fp")])
5946
5947 ;; Only optimize (float (fix x)) -> frz if we are in fast-math mode, since
5948 ;; since the friz instruction does not truncate the value if the floating
5949 ;; point value is < LONG_MIN or > LONG_MAX.
5950 (define_insn "*friz"
5951 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
5952 (float:DF (fix:DI (match_operand:DF 1 "gpc_reg_operand" "d"))))]
5953 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_FPRND
5954 && !VECTOR_UNIT_VSX_P (DFmode) && flag_unsafe_math_optimizations
5955 && !flag_trapping_math && TARGET_FRIZ"
5956 "friz %0,%1"
5957 [(set_attr "type" "fp")])
5958
5959 ;; Since FCTIWZ doesn't sign extend the upper bits, we have to do a store and a
5960 ;; load to properly sign extend the value, but at least doing a store, load
5961 ;; into a GPR to sign extend, a store from the GPR and a load back into the FPR
5962 ;; if we have 32-bit memory ops
5963 (define_insn_and_split "*round32<mode>2_fprs"
5964 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
5965 (float:SFDF
5966 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
5967 (clobber (match_scratch:DI 2 "=d"))
5968 (clobber (match_scratch:DI 3 "=d"))]
5969 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5970 && <SI_CONVERT_FP> && TARGET_LFIWAX && TARGET_STFIWX && TARGET_FCFID
5971 && can_create_pseudo_p ()"
5972 "#"
5973 ""
5974 [(pc)]
5975 {
5976 rtx dest = operands[0];
5977 rtx src = operands[1];
5978 rtx tmp1 = operands[2];
5979 rtx tmp2 = operands[3];
5980 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5981
5982 if (GET_CODE (tmp1) == SCRATCH)
5983 tmp1 = gen_reg_rtx (DImode);
5984 if (GET_CODE (tmp2) == SCRATCH)
5985 tmp2 = gen_reg_rtx (DImode);
5986
5987 emit_insn (gen_fctiwz_<mode> (tmp1, src));
5988 emit_insn (gen_stfiwx (stack, tmp1));
5989 emit_insn (gen_lfiwax (tmp2, stack));
5990 emit_insn (gen_floatdi<mode>2 (dest, tmp2));
5991 DONE;
5992 }
5993 [(set_attr "type" "fpload")
5994 (set_attr "length" "16")])
5995
5996 (define_insn_and_split "*roundu32<mode>2_fprs"
5997 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
5998 (unsigned_float:SFDF
5999 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
6000 (clobber (match_scratch:DI 2 "=d"))
6001 (clobber (match_scratch:DI 3 "=d"))]
6002 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
6003 && TARGET_LFIWZX && TARGET_STFIWX && TARGET_FCFIDU
6004 && can_create_pseudo_p ()"
6005 "#"
6006 ""
6007 [(pc)]
6008 {
6009 rtx dest = operands[0];
6010 rtx src = operands[1];
6011 rtx tmp1 = operands[2];
6012 rtx tmp2 = operands[3];
6013 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
6014
6015 if (GET_CODE (tmp1) == SCRATCH)
6016 tmp1 = gen_reg_rtx (DImode);
6017 if (GET_CODE (tmp2) == SCRATCH)
6018 tmp2 = gen_reg_rtx (DImode);
6019
6020 emit_insn (gen_fctiwuz_<mode> (tmp1, src));
6021 emit_insn (gen_stfiwx (stack, tmp1));
6022 emit_insn (gen_lfiwzx (tmp2, stack));
6023 emit_insn (gen_floatdi<mode>2 (dest, tmp2));
6024 DONE;
6025 }
6026 [(set_attr "type" "fpload")
6027 (set_attr "length" "16")])
6028
6029 ;; No VSX equivalent to fctid
6030 (define_insn "lrint<mode>di2"
6031 [(set (match_operand:DI 0 "gpc_reg_operand" "=d")
6032 (unspec:DI [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
6033 UNSPEC_FCTID))]
6034 "TARGET_<MODE>_FPR && TARGET_FPRND"
6035 "fctid %0,%1"
6036 [(set_attr "type" "fp")])
6037
6038 (define_insn "btrunc<mode>2"
6039 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
6040 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
6041 UNSPEC_FRIZ))]
6042 "TARGET_<MODE>_FPR && TARGET_FPRND"
6043 "@
6044 friz %0,%1
6045 xsrdpiz %x0,%x1"
6046 [(set_attr "type" "fp")
6047 (set_attr "fp_type" "fp_addsub_<Fs>")])
6048
6049 (define_insn "ceil<mode>2"
6050 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
6051 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
6052 UNSPEC_FRIP))]
6053 "TARGET_<MODE>_FPR && TARGET_FPRND"
6054 "@
6055 frip %0,%1
6056 xsrdpip %x0,%x1"
6057 [(set_attr "type" "fp")
6058 (set_attr "fp_type" "fp_addsub_<Fs>")])
6059
6060 (define_insn "floor<mode>2"
6061 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
6062 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
6063 UNSPEC_FRIM))]
6064 "TARGET_<MODE>_FPR && TARGET_FPRND"
6065 "@
6066 frim %0,%1
6067 xsrdpim %x0,%x1"
6068 [(set_attr "type" "fp")
6069 (set_attr "fp_type" "fp_addsub_<Fs>")])
6070
6071 ;; No VSX equivalent to frin
6072 (define_insn "round<mode>2"
6073 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<rreg2>")
6074 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
6075 UNSPEC_FRIN))]
6076 "TARGET_<MODE>_FPR && TARGET_FPRND"
6077 "frin %0,%1"
6078 [(set_attr "type" "fp")
6079 (set_attr "fp_type" "fp_addsub_<Fs>")])
6080
6081 ; An UNSPEC is used so we don't have to support SImode in FP registers.
6082 (define_insn "stfiwx"
6083 [(set (match_operand:SI 0 "memory_operand" "=Z")
6084 (unspec:SI [(match_operand:DI 1 "gpc_reg_operand" "d")]
6085 UNSPEC_STFIWX))]
6086 "TARGET_PPC_GFXOPT"
6087 "stfiwx %1,%y0"
6088 [(set_attr "type" "fpstore")])
6089
6090 ;; If we don't have a direct conversion to single precision, don't enable this
6091 ;; conversion for 32-bit without fast math, because we don't have the insn to
6092 ;; generate the fixup swizzle to avoid double rounding problems.
6093 (define_expand "floatsisf2"
6094 [(set (match_operand:SF 0 "gpc_reg_operand" "")
6095 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
6096 "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
6097 && (!TARGET_FPRS
6098 || (TARGET_FPRS
6099 && ((TARGET_FCFIDS && TARGET_LFIWAX)
6100 || (TARGET_DOUBLE_FLOAT && TARGET_FCFID
6101 && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))))"
6102 "
6103 {
6104 if (!TARGET_FPRS)
6105 {
6106 if (!REG_P (operands[1]))
6107 operands[1] = force_reg (SImode, operands[1]);
6108 }
6109 else if (TARGET_FCFIDS && TARGET_LFIWAX)
6110 {
6111 emit_insn (gen_floatsisf2_lfiwax (operands[0], operands[1]));
6112 DONE;
6113 }
6114 else if (TARGET_FCFID && TARGET_LFIWAX)
6115 {
6116 rtx dfreg = gen_reg_rtx (DFmode);
6117 emit_insn (gen_floatsidf2_lfiwax (dfreg, operands[1]));
6118 emit_insn (gen_truncdfsf2 (operands[0], dfreg));
6119 DONE;
6120 }
6121 else
6122 {
6123 rtx dreg = operands[1];
6124 if (!REG_P (dreg))
6125 dreg = force_reg (SImode, dreg);
6126 dreg = convert_to_mode (DImode, dreg, false);
6127 emit_insn (gen_floatdisf2 (operands[0], dreg));
6128 DONE;
6129 }
6130 }")
6131
6132 (define_expand "floatdidf2"
6133 [(set (match_operand:DF 0 "gpc_reg_operand" "")
6134 (float:DF (match_operand:DI 1 "gpc_reg_operand" "")))]
6135 "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS"
6136 "")
6137
6138 (define_insn "*floatdidf2_fpr"
6139 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
6140 (float:DF (match_operand:DI 1 "gpc_reg_operand" "d")))]
6141 "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS
6142 && !VECTOR_UNIT_VSX_P (DFmode)"
6143 "fcfid %0,%1"
6144 [(set_attr "type" "fp")])
6145
6146 ; Allow the combiner to merge source memory operands to the conversion so that
6147 ; the optimizer/register allocator doesn't try to load the value too early in a
6148 ; GPR and then use store/load to move it to a FPR and suffer from a store-load
6149 ; hit. We will split after reload to avoid the trip through the GPRs
6150
6151 (define_insn_and_split "*floatdidf2_mem"
6152 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
6153 (float:DF (match_operand:DI 1 "memory_operand" "m")))
6154 (clobber (match_scratch:DI 2 "=d"))]
6155 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS && TARGET_FCFID"
6156 "#"
6157 "&& reload_completed"
6158 [(set (match_dup 2) (match_dup 1))
6159 (set (match_dup 0) (float:DF (match_dup 2)))]
6160 ""
6161 [(set_attr "length" "8")
6162 (set_attr "type" "fpload")])
6163
6164 (define_expand "floatunsdidf2"
6165 [(set (match_operand:DF 0 "gpc_reg_operand" "")
6166 (unsigned_float:DF
6167 (match_operand:DI 1 "gpc_reg_operand" "")))]
6168 "TARGET_HARD_FLOAT && (TARGET_FCFIDU || VECTOR_UNIT_VSX_P (DFmode))"
6169 "")
6170
6171 (define_insn "*floatunsdidf2_fcfidu"
6172 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
6173 (unsigned_float:DF (match_operand:DI 1 "gpc_reg_operand" "d")))]
6174 "TARGET_HARD_FLOAT && TARGET_FCFIDU && !VECTOR_UNIT_VSX_P (DFmode)"
6175 "fcfidu %0,%1"
6176 [(set_attr "type" "fp")
6177 (set_attr "length" "4")])
6178
6179 (define_insn_and_split "*floatunsdidf2_mem"
6180 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
6181 (unsigned_float:DF (match_operand:DI 1 "memory_operand" "m")))
6182 (clobber (match_scratch:DI 2 "=d"))]
6183 "TARGET_HARD_FLOAT && (TARGET_FCFIDU || VECTOR_UNIT_VSX_P (DFmode))"
6184 "#"
6185 "&& reload_completed"
6186 [(set (match_dup 2) (match_dup 1))
6187 (set (match_dup 0) (unsigned_float:DF (match_dup 2)))]
6188 ""
6189 [(set_attr "length" "8")
6190 (set_attr "type" "fpload")])
6191
6192 (define_expand "floatdisf2"
6193 [(set (match_operand:SF 0 "gpc_reg_operand" "")
6194 (float:SF (match_operand:DI 1 "gpc_reg_operand" "")))]
6195 "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
6196 && (TARGET_FCFIDS || TARGET_POWERPC64 || flag_unsafe_math_optimizations)"
6197 "
6198 {
6199 if (!TARGET_FCFIDS)
6200 {
6201 rtx val = operands[1];
6202 if (!flag_unsafe_math_optimizations)
6203 {
6204 rtx label = gen_label_rtx ();
6205 val = gen_reg_rtx (DImode);
6206 emit_insn (gen_floatdisf2_internal2 (val, operands[1], label));
6207 emit_label (label);
6208 }
6209 emit_insn (gen_floatdisf2_internal1 (operands[0], val));
6210 DONE;
6211 }
6212 }")
6213
6214 (define_insn "floatdisf2_fcfids"
6215 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
6216 (float:SF (match_operand:DI 1 "gpc_reg_operand" "d")))]
6217 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
6218 && TARGET_DOUBLE_FLOAT && TARGET_FCFIDS"
6219 "fcfids %0,%1"
6220 [(set_attr "type" "fp")])
6221
6222 (define_insn_and_split "*floatdisf2_mem"
6223 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
6224 (float:SF (match_operand:DI 1 "memory_operand" "m")))
6225 (clobber (match_scratch:DI 2 "=f"))]
6226 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
6227 && TARGET_DOUBLE_FLOAT && TARGET_FCFIDS"
6228 "#"
6229 "&& reload_completed"
6230 [(pc)]
6231 "
6232 {
6233 emit_move_insn (operands[2], operands[1]);
6234 emit_insn (gen_floatdisf2_fcfids (operands[0], operands[2]));
6235 DONE;
6236 }"
6237 [(set_attr "length" "8")])
6238
6239 ;; This is not IEEE compliant if rounding mode is "round to nearest".
6240 ;; If the DI->DF conversion is inexact, then it's possible to suffer
6241 ;; from double rounding.
6242 ;; Instead of creating a new cpu type for two FP operations, just use fp
6243 (define_insn_and_split "floatdisf2_internal1"
6244 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
6245 (float:SF (match_operand:DI 1 "gpc_reg_operand" "d")))
6246 (clobber (match_scratch:DF 2 "=d"))]
6247 "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT"
6248 "#"
6249 "&& reload_completed"
6250 [(set (match_dup 2)
6251 (float:DF (match_dup 1)))
6252 (set (match_dup 0)
6253 (float_truncate:SF (match_dup 2)))]
6254 ""
6255 [(set_attr "length" "8")
6256 (set_attr "type" "fp")])
6257
6258 ;; Twiddles bits to avoid double rounding.
6259 ;; Bits that might be truncated when converting to DFmode are replaced
6260 ;; by a bit that won't be lost at that stage, but is below the SFmode
6261 ;; rounding position.
6262 (define_expand "floatdisf2_internal2"
6263 [(set (match_dup 3) (ashiftrt:DI (match_operand:DI 1 "" "")
6264 (const_int 53)))
6265 (set (match_operand:DI 0 "" "") (and:DI (match_dup 1)
6266 (const_int 2047)))
6267 (set (match_dup 3) (plus:DI (match_dup 3)
6268 (const_int 1)))
6269 (set (match_dup 0) (plus:DI (match_dup 0)
6270 (const_int 2047)))
6271 (set (match_dup 4) (compare:CCUNS (match_dup 3)
6272 (const_int 2)))
6273 (set (match_dup 0) (ior:DI (match_dup 0)
6274 (match_dup 1)))
6275 (set (match_dup 0) (and:DI (match_dup 0)
6276 (const_int -2048)))
6277 (set (pc) (if_then_else (geu (match_dup 4) (const_int 0))
6278 (label_ref (match_operand:DI 2 "" ""))
6279 (pc)))
6280 (set (match_dup 0) (match_dup 1))]
6281 "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT"
6282 "
6283 {
6284 operands[3] = gen_reg_rtx (DImode);
6285 operands[4] = gen_reg_rtx (CCUNSmode);
6286 }")
6287
6288 (define_expand "floatunsdisf2"
6289 [(set (match_operand:SF 0 "gpc_reg_operand" "")
6290 (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand" "")))]
6291 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
6292 && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
6293 "")
6294
6295 (define_insn "floatunsdisf2_fcfidus"
6296 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
6297 (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand" "d")))]
6298 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
6299 && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
6300 "fcfidus %0,%1"
6301 [(set_attr "type" "fp")])
6302
6303 (define_insn_and_split "*floatunsdisf2_mem"
6304 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
6305 (unsigned_float:SF (match_operand:DI 1 "memory_operand" "m")))
6306 (clobber (match_scratch:DI 2 "=f"))]
6307 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
6308 && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
6309 "#"
6310 "&& reload_completed"
6311 [(pc)]
6312 "
6313 {
6314 emit_move_insn (operands[2], operands[1]);
6315 emit_insn (gen_floatunsdisf2_fcfidus (operands[0], operands[2]));
6316 DONE;
6317 }"
6318 [(set_attr "length" "8")
6319 (set_attr "type" "fpload")])
6320 \f
6321 ;; Define the TImode operations that can be done in a small number
6322 ;; of instructions. The & constraints are to prevent the register
6323 ;; allocator from allocating registers that overlap with the inputs
6324 ;; (for example, having an input in 7,8 and an output in 6,7). We
6325 ;; also allow for the output being the same as one of the inputs.
6326
6327 (define_insn "addti3"
6328 [(set (match_operand:TI 0 "gpc_reg_operand" "=&r,&r,r,r")
6329 (plus:TI (match_operand:TI 1 "gpc_reg_operand" "%r,r,0,0")
6330 (match_operand:TI 2 "reg_or_short_operand" "r,I,r,I")))]
6331 "TARGET_64BIT"
6332 {
6333 if (WORDS_BIG_ENDIAN)
6334 return (GET_CODE (operands[2])) != CONST_INT
6335 ? \"addc %L0,%L1,%L2\;adde %0,%1,%2\"
6336 : \"addic %L0,%L1,%2\;add%G2e %0,%1\";
6337 else
6338 return (GET_CODE (operands[2])) != CONST_INT
6339 ? \"addc %0,%1,%2\;adde %L0,%L1,%L2\"
6340 : \"addic %0,%1,%2\;add%G2e %L0,%L1\";
6341 }
6342 [(set_attr "type" "two")
6343 (set_attr "length" "8")])
6344
6345 (define_insn "subti3"
6346 [(set (match_operand:TI 0 "gpc_reg_operand" "=&r,&r,r,r,r")
6347 (minus:TI (match_operand:TI 1 "reg_or_short_operand" "r,I,0,r,I")
6348 (match_operand:TI 2 "gpc_reg_operand" "r,r,r,0,0")))]
6349 "TARGET_64BIT"
6350 {
6351 if (WORDS_BIG_ENDIAN)
6352 return (GET_CODE (operands[1]) != CONST_INT)
6353 ? \"subfc %L0,%L2,%L1\;subfe %0,%2,%1\"
6354 : \"subfic %L0,%L2,%1\;subf%G1e %0,%2\";
6355 else
6356 return (GET_CODE (operands[1]) != CONST_INT)
6357 ? \"subfc %0,%2,%1\;subfe %L0,%L2,%L1\"
6358 : \"subfic %0,%2,%1\;subf%G1e %L0,%L2\";
6359 }
6360 [(set_attr "type" "two")
6361 (set_attr "length" "8")])
6362
6363
6364 ;; Define the DImode operations that can be done in a small number
6365 ;; of instructions. The & constraints are to prevent the register
6366 ;; allocator from allocating registers that overlap with the inputs
6367 ;; (for example, having an input in 7,8 and an output in 6,7). We
6368 ;; also allow for the output being the same as one of the inputs.
6369
6370 (define_insn "*adddi3_noppc64"
6371 [(set (match_operand:DI 0 "gpc_reg_operand" "=&r,&r,r,r")
6372 (plus:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,0,0")
6373 (match_operand:DI 2 "reg_or_short_operand" "r,I,r,I")))]
6374 "! TARGET_POWERPC64"
6375 "*
6376 {
6377 if (WORDS_BIG_ENDIAN)
6378 return (GET_CODE (operands[2])) != CONST_INT
6379 ? \"addc %L0,%L1,%L2\;adde %0,%1,%2\"
6380 : \"addic %L0,%L1,%2\;add%G2e %0,%1\";
6381 else
6382 return (GET_CODE (operands[2])) != CONST_INT
6383 ? \"addc %0,%1,%2\;adde %L0,%L1,%L2\"
6384 : \"addic %0,%1,%2\;add%G2e %L0,%L1\";
6385 }"
6386 [(set_attr "type" "two")
6387 (set_attr "length" "8")])
6388
6389 (define_insn "*subdi3_noppc64"
6390 [(set (match_operand:DI 0 "gpc_reg_operand" "=&r,&r,r,r,r")
6391 (minus:DI (match_operand:DI 1 "reg_or_short_operand" "r,I,0,r,I")
6392 (match_operand:DI 2 "gpc_reg_operand" "r,r,r,0,0")))]
6393 "! TARGET_POWERPC64"
6394 "*
6395 {
6396 if (WORDS_BIG_ENDIAN)
6397 return (GET_CODE (operands[1]) != CONST_INT)
6398 ? \"subfc %L0,%L2,%L1\;subfe %0,%2,%1\"
6399 : \"subfic %L0,%L2,%1\;subf%G1e %0,%2\";
6400 else
6401 return (GET_CODE (operands[1]) != CONST_INT)
6402 ? \"subfc %0,%2,%1\;subfe %L0,%L2,%L1\"
6403 : \"subfic %0,%2,%1\;subf%G1e %L0,%L2\";
6404 }"
6405 [(set_attr "type" "two")
6406 (set_attr "length" "8")])
6407
6408 (define_insn "*negdi2_noppc64"
6409 [(set (match_operand:DI 0 "gpc_reg_operand" "=&r,r")
6410 (neg:DI (match_operand:DI 1 "gpc_reg_operand" "r,0")))]
6411 "! TARGET_POWERPC64"
6412 "*
6413 {
6414 return (WORDS_BIG_ENDIAN)
6415 ? \"subfic %L0,%L1,0\;subfze %0,%1\"
6416 : \"subfic %0,%1,0\;subfze %L0,%L1\";
6417 }"
6418 [(set_attr "type" "two")
6419 (set_attr "length" "8")])
6420
6421
6422 ;; Shift by a variable amount is too complex to be worth open-coding. We
6423 ;; just handle shifts by constants.
6424 (define_insn "ashrdi3_no_power"
6425 [(set (match_operand:DI 0 "gpc_reg_operand" "=&r,&r")
6426 (ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
6427 (match_operand:SI 2 "const_int_operand" "M,i")))]
6428 "!TARGET_POWERPC64"
6429 "*
6430 {
6431 switch (which_alternative)
6432 {
6433 default:
6434 gcc_unreachable ();
6435 case 0:
6436 if (WORDS_BIG_ENDIAN)
6437 return \"srawi %0,%1,31\;srawi %L0,%1,%h2\";
6438 else
6439 return \"srawi %L0,%L1,31\;srawi %0,%L1,%h2\";
6440 case 1:
6441 if (WORDS_BIG_ENDIAN)
6442 return \"srwi %L0,%L1,%h2\;insrwi %L0,%1,%h2,0\;srawi %0,%1,%h2\";
6443 else
6444 return \"srwi %0,%1,%h2\;insrwi %0,%L1,%h2,0\;srawi %L0,%L1,%h2\";
6445 }
6446 }"
6447 [(set_attr "type" "two,three")
6448 (set_attr "length" "8,12")])
6449
6450 (define_insn "*ashrdisi3_noppc64be"
6451 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6452 (subreg:SI (ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r")
6453 (const_int 32)) 4))]
6454 "TARGET_32BIT && !TARGET_POWERPC64 && WORDS_BIG_ENDIAN"
6455 "*
6456 {
6457 if (REGNO (operands[0]) == REGNO (operands[1]))
6458 return \"\";
6459 else
6460 return \"mr %0,%1\";
6461 }"
6462 [(set_attr "length" "4")])
6463
6464 \f
6465 ;; PowerPC64 DImode operations.
6466
6467 (define_insn "*rotldi3_internal4"
6468 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
6469 (and:DI (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r")
6470 (match_operand:DI 2 "reg_or_cint_operand" "rn"))
6471 (match_operand:DI 3 "mask64_operand" "n")))]
6472 "TARGET_POWERPC64"
6473 "rld%I2c%B3 %0,%1,%H2,%S3"
6474 [(set_attr "type" "shift")
6475 (set_attr "maybe_var_shift" "yes")])
6476
6477 (define_insn "*rotldi3_internal5"
6478 [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
6479 (compare:CC (and:DI
6480 (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
6481 (match_operand:DI 2 "reg_or_cint_operand" "rn,rn"))
6482 (match_operand:DI 3 "mask64_operand" "n,n"))
6483 (const_int 0)))
6484 (clobber (match_scratch:DI 4 "=r,r"))]
6485 "TARGET_64BIT"
6486 "@
6487 rld%I2c%B3. %4,%1,%H2,%S3
6488 #"
6489 [(set_attr "type" "shift")
6490 (set_attr "maybe_var_shift" "yes")
6491 (set_attr "dot" "yes")
6492 (set_attr "length" "4,8")])
6493
6494 (define_split
6495 [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
6496 (compare:CC (and:DI
6497 (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "")
6498 (match_operand:DI 2 "reg_or_cint_operand" ""))
6499 (match_operand:DI 3 "mask64_operand" ""))
6500 (const_int 0)))
6501 (clobber (match_scratch:DI 4 ""))]
6502 "TARGET_POWERPC64 && reload_completed"
6503 [(set (match_dup 4)
6504 (and:DI (rotate:DI (match_dup 1)
6505 (match_dup 2))
6506 (match_dup 3)))
6507 (set (match_dup 0)
6508 (compare:CC (match_dup 4)
6509 (const_int 0)))]
6510 "")
6511
6512 (define_insn "*rotldi3_internal6"
6513 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
6514 (compare:CC (and:DI
6515 (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
6516 (match_operand:DI 2 "reg_or_cint_operand" "rn,rn"))
6517 (match_operand:DI 3 "mask64_operand" "n,n"))
6518 (const_int 0)))
6519 (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
6520 (and:DI (rotate:DI (match_dup 1) (match_dup 2)) (match_dup 3)))]
6521 "TARGET_64BIT"
6522 "@
6523 rld%I2c%B3. %0,%1,%H2,%S3
6524 #"
6525 [(set_attr "type" "shift")
6526 (set_attr "maybe_var_shift" "yes")
6527 (set_attr "dot" "yes")
6528 (set_attr "length" "4,8")])
6529
6530 (define_split
6531 [(set (match_operand:CC 4 "cc_reg_not_micro_cr0_operand" "")
6532 (compare:CC (and:DI
6533 (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "")
6534 (match_operand:DI 2 "reg_or_cint_operand" ""))
6535 (match_operand:DI 3 "mask64_operand" ""))
6536 (const_int 0)))
6537 (set (match_operand:DI 0 "gpc_reg_operand" "")
6538 (and:DI (rotate:DI (match_dup 1) (match_dup 2)) (match_dup 3)))]
6539 "TARGET_POWERPC64 && reload_completed"
6540 [(set (match_dup 0)
6541 (and:DI (rotate:DI (match_dup 1) (match_dup 2)) (match_dup 3)))
6542 (set (match_dup 4)
6543 (compare:CC (match_dup 0)
6544 (const_int 0)))]
6545 "")
6546
6547 (define_insn "*rotldi3_internal7le"
6548 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
6549 (zero_extend:DI
6550 (subreg:QI
6551 (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r")
6552 (match_operand:DI 2 "reg_or_cint_operand" "rn")) 0)))]
6553 "TARGET_POWERPC64 && !BYTES_BIG_ENDIAN"
6554 "rld%I2cl %0,%1,%H2,56"
6555 [(set_attr "type" "shift")
6556 (set_attr "maybe_var_shift" "yes")])
6557
6558 (define_insn "*rotldi3_internal7be"
6559 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
6560 (zero_extend:DI
6561 (subreg:QI
6562 (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r")
6563 (match_operand:DI 2 "reg_or_cint_operand" "rn")) 7)))]
6564 "TARGET_POWERPC64 && BYTES_BIG_ENDIAN"
6565 "rld%I2cl %0,%1,%H2,56"
6566 [(set_attr "type" "shift")
6567 (set_attr "maybe_var_shift" "yes")])
6568
6569 (define_insn "*rotldi3_internal8le"
6570 [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
6571 (compare:CC (zero_extend:DI
6572 (subreg:QI
6573 (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
6574 (match_operand:DI 2 "reg_or_cint_operand" "rn,rn")) 0))
6575 (const_int 0)))
6576 (clobber (match_scratch:DI 3 "=r,r"))]
6577 "TARGET_64BIT && !BYTES_BIG_ENDIAN"
6578 "@
6579 rld%I2cl. %3,%1,%H2,56
6580 #"
6581 [(set_attr "type" "shift")
6582 (set_attr "maybe_var_shift" "yes")
6583 (set_attr "dot" "yes")
6584 (set_attr "length" "4,8")])
6585
6586 (define_insn "*rotldi3_internal8be"
6587 [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
6588 (compare:CC (zero_extend:DI
6589 (subreg:QI
6590 (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
6591 (match_operand:DI 2 "reg_or_cint_operand" "rn,rn")) 7))
6592 (const_int 0)))
6593 (clobber (match_scratch:DI 3 "=r,r"))]
6594 "TARGET_64BIT && BYTES_BIG_ENDIAN"
6595 "@
6596 rld%I2cl. %3,%1,%H2,56
6597 #"
6598 [(set_attr "type" "shift")
6599 (set_attr "maybe_var_shift" "yes")
6600 (set_attr "dot" "yes")
6601 (set_attr "length" "4,8")])
6602
6603 (define_split
6604 [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
6605 (compare:CC (zero_extend:DI
6606 (subreg:QI
6607 (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "")
6608 (match_operand:DI 2 "reg_or_cint_operand" "")) 0))
6609 (const_int 0)))
6610 (clobber (match_scratch:DI 3 ""))]
6611 "TARGET_POWERPC64 && !BYTES_BIG_ENDIAN && reload_completed"
6612 [(set (match_dup 3)
6613 (zero_extend:DI (subreg:QI
6614 (rotate:DI (match_dup 1)
6615 (match_dup 2)) 0)))
6616 (set (match_dup 0)
6617 (compare:CC (match_dup 3)
6618 (const_int 0)))]
6619 "")
6620
6621 (define_split
6622 [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
6623 (compare:CC (zero_extend:DI
6624 (subreg:QI
6625 (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "")
6626 (match_operand:DI 2 "reg_or_cint_operand" "")) 7))
6627 (const_int 0)))
6628 (clobber (match_scratch:DI 3 ""))]
6629 "TARGET_POWERPC64 && BYTES_BIG_ENDIAN && reload_completed"
6630 [(set (match_dup 3)
6631 (zero_extend:DI (subreg:QI
6632 (rotate:DI (match_dup 1)
6633 (match_dup 2)) 7)))
6634 (set (match_dup 0)
6635 (compare:CC (match_dup 3)
6636 (const_int 0)))]
6637 "")
6638
6639 (define_insn "*rotldi3_internal9le"
6640 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
6641 (compare:CC (zero_extend:DI
6642 (subreg:QI
6643 (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
6644 (match_operand:DI 2 "reg_or_cint_operand" "rn,rn")) 0))
6645 (const_int 0)))
6646 (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
6647 (zero_extend:DI (subreg:QI (rotate:DI (match_dup 1) (match_dup 2)) 0)))]
6648 "TARGET_64BIT && !BYTES_BIG_ENDIAN"
6649 "@
6650 rld%I2cl. %0,%1,%H2,56
6651 #"
6652 [(set_attr "type" "shift")
6653 (set_attr "maybe_var_shift" "yes")
6654 (set_attr "dot" "yes")
6655 (set_attr "length" "4,8")])
6656
6657 (define_insn "*rotldi3_internal9be"
6658 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
6659 (compare:CC (zero_extend:DI
6660 (subreg:QI
6661 (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
6662 (match_operand:DI 2 "reg_or_cint_operand" "rn,rn")) 7))
6663 (const_int 0)))
6664 (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
6665 (zero_extend:DI (subreg:QI (rotate:DI (match_dup 1) (match_dup 2)) 7)))]
6666 "TARGET_64BIT && BYTES_BIG_ENDIAN"
6667 "@
6668 rld%I2cl. %0,%1,%H2,56
6669 #"
6670 [(set_attr "type" "shift")
6671 (set_attr "maybe_var_shift" "yes")
6672 (set_attr "dot" "yes")
6673 (set_attr "length" "4,8")])
6674
6675 (define_split
6676 [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "")
6677 (compare:CC (zero_extend:DI
6678 (subreg:QI
6679 (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "")
6680 (match_operand:DI 2 "reg_or_cint_operand" "")) 0))
6681 (const_int 0)))
6682 (set (match_operand:DI 0 "gpc_reg_operand" "")
6683 (zero_extend:DI (subreg:QI (rotate:DI (match_dup 1) (match_dup 2)) 0)))]
6684 "TARGET_POWERPC64 && !BYTES_BIG_ENDIAN && reload_completed"
6685 [(set (match_dup 0)
6686 (zero_extend:DI (subreg:QI (rotate:DI (match_dup 1) (match_dup 2)) 0)))
6687 (set (match_dup 3)
6688 (compare:CC (match_dup 0)
6689 (const_int 0)))]
6690 "")
6691
6692 (define_split
6693 [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "")
6694 (compare:CC (zero_extend:DI
6695 (subreg:QI
6696 (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "")
6697 (match_operand:DI 2 "reg_or_cint_operand" "")) 7))
6698 (const_int 0)))
6699 (set (match_operand:DI 0 "gpc_reg_operand" "")
6700 (zero_extend:DI (subreg:QI (rotate:DI (match_dup 1) (match_dup 2)) 7)))]
6701 "TARGET_POWERPC64 && BYTES_BIG_ENDIAN && reload_completed"
6702 [(set (match_dup 0)
6703 (zero_extend:DI (subreg:QI (rotate:DI (match_dup 1) (match_dup 2)) 7)))
6704 (set (match_dup 3)
6705 (compare:CC (match_dup 0)
6706 (const_int 0)))]
6707 "")
6708
6709 (define_insn "*rotldi3_internal10le"
6710 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
6711 (zero_extend:DI
6712 (subreg:HI
6713 (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r")
6714 (match_operand:DI 2 "reg_or_cint_operand" "rn")) 0)))]
6715 "TARGET_POWERPC64 && !BYTES_BIG_ENDIAN"
6716 "rld%I2cl %0,%1,%H2,48"
6717 [(set_attr "type" "shift")
6718 (set_attr "maybe_var_shift" "yes")])
6719
6720 (define_insn "*rotldi3_internal10be"
6721 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
6722 (zero_extend:DI
6723 (subreg:HI
6724 (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r")
6725 (match_operand:DI 2 "reg_or_cint_operand" "rn")) 6)))]
6726 "TARGET_POWERPC64 && BYTES_BIG_ENDIAN"
6727 "rld%I2cl %0,%1,%H2,48"
6728 [(set_attr "type" "shift")
6729 (set_attr "maybe_var_shift" "yes")])
6730
6731 (define_insn "*rotldi3_internal11le"
6732 [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
6733 (compare:CC (zero_extend:DI
6734 (subreg:HI
6735 (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
6736 (match_operand:DI 2 "reg_or_cint_operand" "rn,rn")) 0))
6737 (const_int 0)))
6738 (clobber (match_scratch:DI 3 "=r,r"))]
6739 "TARGET_64BIT && !BYTES_BIG_ENDIAN"
6740 "@
6741 rld%I2cl. %3,%1,%H2,48
6742 #"
6743 [(set_attr "type" "shift")
6744 (set_attr "maybe_var_shift" "yes")
6745 (set_attr "dot" "yes")
6746 (set_attr "length" "4,8")])
6747
6748 (define_insn "*rotldi3_internal11be"
6749 [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
6750 (compare:CC (zero_extend:DI
6751 (subreg:HI
6752 (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
6753 (match_operand:DI 2 "reg_or_cint_operand" "rn,rn")) 6))
6754 (const_int 0)))
6755 (clobber (match_scratch:DI 3 "=r,r"))]
6756 "TARGET_64BIT && BYTES_BIG_ENDIAN"
6757 "@
6758 rld%I2cl. %3,%1,%H2,48
6759 #"
6760 [(set_attr "type" "shift")
6761 (set_attr "maybe_var_shift" "yes")
6762 (set_attr "dot" "yes")
6763 (set_attr "length" "4,8")])
6764
6765 (define_split
6766 [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
6767 (compare:CC (zero_extend:DI
6768 (subreg:HI
6769 (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "")
6770 (match_operand:DI 2 "reg_or_cint_operand" "")) 0))
6771 (const_int 0)))
6772 (clobber (match_scratch:DI 3 ""))]
6773 "TARGET_POWERPC64 && !BYTES_BIG_ENDIAN && reload_completed"
6774 [(set (match_dup 3)
6775 (zero_extend:DI (subreg:HI
6776 (rotate:DI (match_dup 1)
6777 (match_dup 2)) 0)))
6778 (set (match_dup 0)
6779 (compare:CC (match_dup 3)
6780 (const_int 0)))]
6781 "")
6782
6783 (define_split
6784 [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
6785 (compare:CC (zero_extend:DI
6786 (subreg:HI
6787 (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "")
6788 (match_operand:DI 2 "reg_or_cint_operand" "")) 6))
6789 (const_int 0)))
6790 (clobber (match_scratch:DI 3 ""))]
6791 "TARGET_POWERPC64 && BYTES_BIG_ENDIAN && reload_completed"
6792 [(set (match_dup 3)
6793 (zero_extend:DI (subreg:HI
6794 (rotate:DI (match_dup 1)
6795 (match_dup 2)) 6)))
6796 (set (match_dup 0)
6797 (compare:CC (match_dup 3)
6798 (const_int 0)))]
6799 "")
6800
6801 (define_insn "*rotldi3_internal12le"
6802 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
6803 (compare:CC (zero_extend:DI
6804 (subreg:HI
6805 (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
6806 (match_operand:DI 2 "reg_or_cint_operand" "rn,rn")) 0))
6807 (const_int 0)))
6808 (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
6809 (zero_extend:DI (subreg:HI (rotate:DI (match_dup 1) (match_dup 2)) 0)))]
6810 "TARGET_64BIT && !BYTES_BIG_ENDIAN"
6811 "@
6812 rld%I2cl. %0,%1,%H2,48
6813 #"
6814 [(set_attr "type" "shift")
6815 (set_attr "maybe_var_shift" "yes")
6816 (set_attr "dot" "yes")
6817 (set_attr "length" "4,8")])
6818
6819 (define_insn "*rotldi3_internal12be"
6820 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
6821 (compare:CC (zero_extend:DI
6822 (subreg:HI
6823 (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
6824 (match_operand:DI 2 "reg_or_cint_operand" "rn,rn")) 6))
6825 (const_int 0)))
6826 (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
6827 (zero_extend:DI (subreg:HI (rotate:DI (match_dup 1) (match_dup 2)) 6)))]
6828 "TARGET_64BIT && BYTES_BIG_ENDIAN"
6829 "@
6830 rld%I2cl. %0,%1,%H2,48
6831 #"
6832 [(set_attr "type" "shift")
6833 (set_attr "maybe_var_shift" "yes")
6834 (set_attr "dot" "yes")
6835 (set_attr "length" "4,8")])
6836
6837 (define_split
6838 [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "")
6839 (compare:CC (zero_extend:DI
6840 (subreg:HI
6841 (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "")
6842 (match_operand:DI 2 "reg_or_cint_operand" "")) 0))
6843 (const_int 0)))
6844 (set (match_operand:DI 0 "gpc_reg_operand" "")
6845 (zero_extend:DI (subreg:HI (rotate:DI (match_dup 1) (match_dup 2)) 0)))]
6846 "TARGET_POWERPC64 && !BYTES_BIG_ENDIAN && reload_completed"
6847 [(set (match_dup 0)
6848 (zero_extend:DI (subreg:HI (rotate:DI (match_dup 1) (match_dup 2)) 0)))
6849 (set (match_dup 3)
6850 (compare:CC (match_dup 0)
6851 (const_int 0)))]
6852 "")
6853
6854 (define_split
6855 [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "")
6856 (compare:CC (zero_extend:DI
6857 (subreg:HI
6858 (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "")
6859 (match_operand:DI 2 "reg_or_cint_operand" "")) 6))
6860 (const_int 0)))
6861 (set (match_operand:DI 0 "gpc_reg_operand" "")
6862 (zero_extend:DI (subreg:HI (rotate:DI (match_dup 1) (match_dup 2)) 6)))]
6863 "TARGET_POWERPC64 && BYTES_BIG_ENDIAN && reload_completed"
6864 [(set (match_dup 0)
6865 (zero_extend:DI (subreg:HI (rotate:DI (match_dup 1) (match_dup 2)) 6)))
6866 (set (match_dup 3)
6867 (compare:CC (match_dup 0)
6868 (const_int 0)))]
6869 "")
6870
6871 (define_insn "*rotldi3_internal13le"
6872 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
6873 (zero_extend:DI
6874 (subreg:SI
6875 (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r")
6876 (match_operand:DI 2 "reg_or_cint_operand" "rn")) 0)))]
6877 "TARGET_POWERPC64 && !BYTES_BIG_ENDIAN"
6878 "rld%I2cl %0,%1,%H2,32"
6879 [(set_attr "type" "shift")
6880 (set_attr "maybe_var_shift" "yes")])
6881
6882 (define_insn "*rotldi3_internal13be"
6883 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
6884 (zero_extend:DI
6885 (subreg:SI
6886 (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r")
6887 (match_operand:DI 2 "reg_or_cint_operand" "rn")) 4)))]
6888 "TARGET_POWERPC64 && BYTES_BIG_ENDIAN"
6889 "rld%I2cl %0,%1,%H2,32"
6890 [(set_attr "type" "shift")
6891 (set_attr "maybe_var_shift" "yes")])
6892
6893 (define_insn "*rotldi3_internal14le"
6894 [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
6895 (compare:CC (zero_extend:DI
6896 (subreg:SI
6897 (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
6898 (match_operand:DI 2 "reg_or_cint_operand" "rn,rn")) 0))
6899 (const_int 0)))
6900 (clobber (match_scratch:DI 3 "=r,r"))]
6901 "TARGET_64BIT && !BYTES_BIG_ENDIAN"
6902 "@
6903 rld%I2cl. %3,%1,%H2,32
6904 #"
6905 [(set_attr "type" "shift")
6906 (set_attr "maybe_var_shift" "yes")
6907 (set_attr "dot" "yes")
6908 (set_attr "length" "4,8")])
6909
6910 (define_insn "*rotldi3_internal14be"
6911 [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
6912 (compare:CC (zero_extend:DI
6913 (subreg:SI
6914 (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
6915 (match_operand:DI 2 "reg_or_cint_operand" "rn,rn")) 4))
6916 (const_int 0)))
6917 (clobber (match_scratch:DI 3 "=r,r"))]
6918 "TARGET_64BIT && BYTES_BIG_ENDIAN"
6919 "@
6920 rld%I2cl. %3,%1,%H2,32
6921 #"
6922 [(set_attr "type" "shift")
6923 (set_attr "maybe_var_shift" "yes")
6924 (set_attr "dot" "yes")
6925 (set_attr "length" "4,8")])
6926
6927 (define_split
6928 [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
6929 (compare:CC (zero_extend:DI
6930 (subreg:SI
6931 (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "")
6932 (match_operand:DI 2 "reg_or_cint_operand" "")) 0))
6933 (const_int 0)))
6934 (clobber (match_scratch:DI 3 ""))]
6935 "TARGET_POWERPC64 && !BYTES_BIG_ENDIAN && reload_completed"
6936 [(set (match_dup 3)
6937 (zero_extend:DI (subreg:SI
6938 (rotate:DI (match_dup 1)
6939 (match_dup 2)) 0)))
6940 (set (match_dup 0)
6941 (compare:CC (match_dup 3)
6942 (const_int 0)))]
6943 "")
6944
6945 (define_split
6946 [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
6947 (compare:CC (zero_extend:DI
6948 (subreg:SI
6949 (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "")
6950 (match_operand:DI 2 "reg_or_cint_operand" "")) 4))
6951 (const_int 0)))
6952 (clobber (match_scratch:DI 3 ""))]
6953 "TARGET_POWERPC64 && BYTES_BIG_ENDIAN && reload_completed"
6954 [(set (match_dup 3)
6955 (zero_extend:DI (subreg:SI
6956 (rotate:DI (match_dup 1)
6957 (match_dup 2)) 4)))
6958 (set (match_dup 0)
6959 (compare:CC (match_dup 3)
6960 (const_int 0)))]
6961 "")
6962
6963 (define_insn "*rotldi3_internal15le"
6964 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
6965 (compare:CC (zero_extend:DI
6966 (subreg:SI
6967 (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
6968 (match_operand:DI 2 "reg_or_cint_operand" "rn,rn")) 0))
6969 (const_int 0)))
6970 (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
6971 (zero_extend:DI (subreg:SI (rotate:DI (match_dup 1) (match_dup 2)) 0)))]
6972 "TARGET_64BIT && !BYTES_BIG_ENDIAN"
6973 "@
6974 rld%I2cl. %0,%1,%H2,32
6975 #"
6976 [(set_attr "type" "shift")
6977 (set_attr "maybe_var_shift" "yes")
6978 (set_attr "dot" "yes")
6979 (set_attr "length" "4,8")])
6980
6981 (define_insn "*rotldi3_internal15be"
6982 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
6983 (compare:CC (zero_extend:DI
6984 (subreg:SI
6985 (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
6986 (match_operand:DI 2 "reg_or_cint_operand" "rn,rn")) 4))
6987 (const_int 0)))
6988 (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
6989 (zero_extend:DI (subreg:SI (rotate:DI (match_dup 1) (match_dup 2)) 4)))]
6990 "TARGET_64BIT && BYTES_BIG_ENDIAN"
6991 "@
6992 rld%I2cl. %0,%1,%H2,32
6993 #"
6994 [(set_attr "type" "shift")
6995 (set_attr "maybe_var_shift" "yes")
6996 (set_attr "dot" "yes")
6997 (set_attr "length" "4,8")])
6998
6999 (define_split
7000 [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "")
7001 (compare:CC (zero_extend:DI
7002 (subreg:SI
7003 (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "")
7004 (match_operand:DI 2 "reg_or_cint_operand" "")) 0))
7005 (const_int 0)))
7006 (set (match_operand:DI 0 "gpc_reg_operand" "")
7007 (zero_extend:DI (subreg:SI (rotate:DI (match_dup 1) (match_dup 2)) 0)))]
7008 "TARGET_POWERPC64 && !BYTES_BIG_ENDIAN && reload_completed"
7009 [(set (match_dup 0)
7010 (zero_extend:DI (subreg:SI (rotate:DI (match_dup 1) (match_dup 2)) 0)))
7011 (set (match_dup 3)
7012 (compare:CC (match_dup 0)
7013 (const_int 0)))]
7014 "")
7015
7016 (define_split
7017 [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "")
7018 (compare:CC (zero_extend:DI
7019 (subreg:SI
7020 (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "")
7021 (match_operand:DI 2 "reg_or_cint_operand" "")) 4))
7022 (const_int 0)))
7023 (set (match_operand:DI 0 "gpc_reg_operand" "")
7024 (zero_extend:DI (subreg:SI (rotate:DI (match_dup 1) (match_dup 2)) 4)))]
7025 "TARGET_POWERPC64 && BYTES_BIG_ENDIAN && reload_completed"
7026 [(set (match_dup 0)
7027 (zero_extend:DI (subreg:SI (rotate:DI (match_dup 1) (match_dup 2)) 4)))
7028 (set (match_dup 3)
7029 (compare:CC (match_dup 0)
7030 (const_int 0)))]
7031 "")
7032
7033 (define_insn "*ashldi3_internal4"
7034 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
7035 (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r")
7036 (match_operand:SI 2 "const_int_operand" "i"))
7037 (match_operand:DI 3 "const_int_operand" "n")))]
7038 "TARGET_POWERPC64 && includes_rldic_lshift_p (operands[2], operands[3])"
7039 "rldic %0,%1,%H2,%W3"
7040 [(set_attr "type" "shift")])
7041
7042 (define_insn "ashldi3_internal5"
7043 [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
7044 (compare:CC
7045 (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
7046 (match_operand:SI 2 "const_int_operand" "i,i"))
7047 (match_operand:DI 3 "const_int_operand" "n,n"))
7048 (const_int 0)))
7049 (clobber (match_scratch:DI 4 "=r,r"))]
7050 "TARGET_64BIT && includes_rldic_lshift_p (operands[2], operands[3])"
7051 "@
7052 rldic. %4,%1,%H2,%W3
7053 #"
7054 [(set_attr "type" "shift")
7055 (set_attr "dot" "yes")
7056 (set_attr "length" "4,8")])
7057
7058 (define_split
7059 [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
7060 (compare:CC
7061 (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "")
7062 (match_operand:SI 2 "const_int_operand" ""))
7063 (match_operand:DI 3 "const_int_operand" ""))
7064 (const_int 0)))
7065 (clobber (match_scratch:DI 4 ""))]
7066 "TARGET_POWERPC64 && reload_completed
7067 && includes_rldic_lshift_p (operands[2], operands[3])"
7068 [(set (match_dup 4)
7069 (and:DI (ashift:DI (match_dup 1) (match_dup 2))
7070 (match_dup 3)))
7071 (set (match_dup 0)
7072 (compare:CC (match_dup 4)
7073 (const_int 0)))]
7074 "")
7075
7076 (define_insn "*ashldi3_internal6"
7077 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
7078 (compare:CC
7079 (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
7080 (match_operand:SI 2 "const_int_operand" "i,i"))
7081 (match_operand:DI 3 "const_int_operand" "n,n"))
7082 (const_int 0)))
7083 (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
7084 (and:DI (ashift:DI (match_dup 1) (match_dup 2)) (match_dup 3)))]
7085 "TARGET_64BIT && includes_rldic_lshift_p (operands[2], operands[3])"
7086 "@
7087 rldic. %0,%1,%H2,%W3
7088 #"
7089 [(set_attr "type" "shift")
7090 (set_attr "dot" "yes")
7091 (set_attr "length" "4,8")])
7092
7093 (define_split
7094 [(set (match_operand:CC 4 "cc_reg_not_micro_cr0_operand" "")
7095 (compare:CC
7096 (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "")
7097 (match_operand:SI 2 "const_int_operand" ""))
7098 (match_operand:DI 3 "const_int_operand" ""))
7099 (const_int 0)))
7100 (set (match_operand:DI 0 "gpc_reg_operand" "")
7101 (and:DI (ashift:DI (match_dup 1) (match_dup 2)) (match_dup 3)))]
7102 "TARGET_POWERPC64 && reload_completed
7103 && includes_rldic_lshift_p (operands[2], operands[3])"
7104 [(set (match_dup 0)
7105 (and:DI (ashift:DI (match_dup 1) (match_dup 2))
7106 (match_dup 3)))
7107 (set (match_dup 4)
7108 (compare:CC (match_dup 0)
7109 (const_int 0)))]
7110 "")
7111
7112 (define_insn "*ashldi3_internal7"
7113 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
7114 (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r")
7115 (match_operand:SI 2 "const_int_operand" "i"))
7116 (match_operand:DI 3 "mask64_operand" "n")))]
7117 "TARGET_POWERPC64 && includes_rldicr_lshift_p (operands[2], operands[3])"
7118 "rldicr %0,%1,%H2,%S3"
7119 [(set_attr "type" "shift")])
7120
7121 (define_insn "ashldi3_internal8"
7122 [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
7123 (compare:CC
7124 (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
7125 (match_operand:SI 2 "const_int_operand" "i,i"))
7126 (match_operand:DI 3 "mask64_operand" "n,n"))
7127 (const_int 0)))
7128 (clobber (match_scratch:DI 4 "=r,r"))]
7129 "TARGET_64BIT && includes_rldicr_lshift_p (operands[2], operands[3])"
7130 "@
7131 rldicr. %4,%1,%H2,%S3
7132 #"
7133 [(set_attr "type" "shift")
7134 (set_attr "dot" "yes")
7135 (set_attr "length" "4,8")])
7136
7137 (define_split
7138 [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
7139 (compare:CC
7140 (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "")
7141 (match_operand:SI 2 "const_int_operand" ""))
7142 (match_operand:DI 3 "mask64_operand" ""))
7143 (const_int 0)))
7144 (clobber (match_scratch:DI 4 ""))]
7145 "TARGET_POWERPC64 && reload_completed
7146 && includes_rldicr_lshift_p (operands[2], operands[3])"
7147 [(set (match_dup 4)
7148 (and:DI (ashift:DI (match_dup 1) (match_dup 2))
7149 (match_dup 3)))
7150 (set (match_dup 0)
7151 (compare:CC (match_dup 4)
7152 (const_int 0)))]
7153 "")
7154
7155 (define_insn "*ashldi3_internal9"
7156 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
7157 (compare:CC
7158 (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
7159 (match_operand:SI 2 "const_int_operand" "i,i"))
7160 (match_operand:DI 3 "mask64_operand" "n,n"))
7161 (const_int 0)))
7162 (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
7163 (and:DI (ashift:DI (match_dup 1) (match_dup 2)) (match_dup 3)))]
7164 "TARGET_64BIT && includes_rldicr_lshift_p (operands[2], operands[3])"
7165 "@
7166 rldicr. %0,%1,%H2,%S3
7167 #"
7168 [(set_attr "type" "shift")
7169 (set_attr "dot" "yes")
7170 (set_attr "length" "4,8")])
7171
7172 (define_split
7173 [(set (match_operand:CC 4 "cc_reg_not_micro_cr0_operand" "")
7174 (compare:CC
7175 (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "")
7176 (match_operand:SI 2 "const_int_operand" ""))
7177 (match_operand:DI 3 "mask64_operand" ""))
7178 (const_int 0)))
7179 (set (match_operand:DI 0 "gpc_reg_operand" "")
7180 (and:DI (ashift:DI (match_dup 1) (match_dup 2)) (match_dup 3)))]
7181 "TARGET_POWERPC64 && reload_completed
7182 && includes_rldicr_lshift_p (operands[2], operands[3])"
7183 [(set (match_dup 0)
7184 (and:DI (ashift:DI (match_dup 1) (match_dup 2))
7185 (match_dup 3)))
7186 (set (match_dup 4)
7187 (compare:CC (match_dup 0)
7188 (const_int 0)))]
7189 "")
7190
7191
7192 (define_insn_and_split "*anddi3_2rld"
7193 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
7194 (and:DI (match_operand:DI 1 "gpc_reg_operand" "%r")
7195 (match_operand:DI 2 "and_2rld_operand" "n")))]
7196 "TARGET_POWERPC64"
7197 "#"
7198 ""
7199 [(set (match_dup 0)
7200 (and:DI (rotate:DI (match_dup 1)
7201 (match_dup 4))
7202 (match_dup 5)))
7203 (set (match_dup 0)
7204 (and:DI (rotate:DI (match_dup 0)
7205 (match_dup 6))
7206 (match_dup 7)))]
7207 {
7208 build_mask64_2_operands (operands[2], &operands[4]);
7209 }
7210 [(set_attr "length" "8")])
7211
7212 (define_insn_and_split "*anddi3_2rld_dot"
7213 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
7214 (compare:CC (and:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r")
7215 (match_operand:DI 2 "and_2rld_operand" "n,n"))
7216 (const_int 0)))
7217 (clobber (match_scratch:DI 0 "=r,r"))]
7218 "TARGET_64BIT && rs6000_gen_cell_microcode"
7219 "@
7220 #
7221 #"
7222 "&& reload_completed"
7223 [(set (match_dup 0)
7224 (and:DI (rotate:DI (match_dup 1)
7225 (match_dup 4))
7226 (match_dup 5)))
7227 (parallel [(set (match_dup 3)
7228 (compare:CC (and:DI (rotate:DI (match_dup 0)
7229 (match_dup 6))
7230 (match_dup 7))
7231 (const_int 0)))
7232 (clobber (match_dup 0))])]
7233 {
7234 build_mask64_2_operands (operands[2], &operands[4]);
7235 }
7236 [(set_attr "type" "compare")
7237 (set_attr "dot" "yes")
7238 (set_attr "length" "8,12")])
7239
7240 (define_insn_and_split "*anddi3_2rld_dot2"
7241 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
7242 (compare:CC (and:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r")
7243 (match_operand:DI 2 "and_2rld_operand" "n,n"))
7244 (const_int 0)))
7245 (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
7246 (and:DI (match_dup 1)
7247 (match_dup 2)))]
7248 "TARGET_64BIT && rs6000_gen_cell_microcode"
7249 "@
7250 #
7251 #"
7252 "&& reload_completed"
7253 [(set (match_dup 0)
7254 (and:DI (rotate:DI (match_dup 1)
7255 (match_dup 4))
7256 (match_dup 5)))
7257 (parallel [(set (match_dup 3)
7258 (compare:CC (and:DI (rotate:DI (match_dup 0)
7259 (match_dup 6))
7260 (match_dup 7))
7261 (const_int 0)))
7262 (set (match_dup 0)
7263 (and:DI (rotate:DI (match_dup 0)
7264 (match_dup 6))
7265 (match_dup 7)))])]
7266 {
7267 build_mask64_2_operands (operands[2], &operands[4]);
7268 }
7269 [(set_attr "type" "compare")
7270 (set_attr "dot" "yes")
7271 (set_attr "length" "8,12")])
7272 \f
7273 ;; 128-bit logical operations expanders
7274
7275 (define_expand "and<mode>3"
7276 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
7277 (and:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
7278 (match_operand:BOOL_128 2 "vlogical_operand" "")))]
7279 ""
7280 "")
7281
7282 (define_expand "ior<mode>3"
7283 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
7284 (ior:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
7285 (match_operand:BOOL_128 2 "vlogical_operand" "")))]
7286 ""
7287 "")
7288
7289 (define_expand "xor<mode>3"
7290 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
7291 (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
7292 (match_operand:BOOL_128 2 "vlogical_operand" "")))]
7293 ""
7294 "")
7295
7296 (define_expand "one_cmpl<mode>2"
7297 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
7298 (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")))]
7299 ""
7300 "")
7301
7302 (define_expand "nor<mode>3"
7303 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
7304 (and:BOOL_128
7305 (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" ""))
7306 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))))]
7307 ""
7308 "")
7309
7310 (define_expand "andc<mode>3"
7311 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
7312 (and:BOOL_128
7313 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))
7314 (match_operand:BOOL_128 1 "vlogical_operand" "")))]
7315 ""
7316 "")
7317
7318 ;; Power8 vector logical instructions.
7319 (define_expand "eqv<mode>3"
7320 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
7321 (not:BOOL_128
7322 (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
7323 (match_operand:BOOL_128 2 "vlogical_operand" ""))))]
7324 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
7325 "")
7326
7327 ;; Rewrite nand into canonical form
7328 (define_expand "nand<mode>3"
7329 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
7330 (ior:BOOL_128
7331 (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" ""))
7332 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))))]
7333 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
7334 "")
7335
7336 ;; The canonical form is to have the negated element first, so we need to
7337 ;; reverse arguments.
7338 (define_expand "orc<mode>3"
7339 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
7340 (ior:BOOL_128
7341 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))
7342 (match_operand:BOOL_128 1 "vlogical_operand" "")))]
7343 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
7344 "")
7345
7346 ;; 128-bit logical operations insns and split operations
7347 (define_insn_and_split "*and<mode>3_internal"
7348 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
7349 (and:BOOL_128
7350 (match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
7351 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")))]
7352 ""
7353 {
7354 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
7355 return "xxland %x0,%x1,%x2";
7356
7357 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
7358 return "vand %0,%1,%2";
7359
7360 return "#";
7361 }
7362 "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
7363 [(const_int 0)]
7364 {
7365 rs6000_split_logical (operands, AND, false, false, false);
7366 DONE;
7367 }
7368 [(set (attr "type")
7369 (if_then_else
7370 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
7371 (const_string "vecsimple")
7372 (const_string "integer")))
7373 (set (attr "length")
7374 (if_then_else
7375 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
7376 (const_string "4")
7377 (if_then_else
7378 (match_test "TARGET_POWERPC64")
7379 (const_string "8")
7380 (const_string "16"))))])
7381
7382 ;; 128-bit IOR/XOR
7383 (define_insn_and_split "*bool<mode>3_internal"
7384 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
7385 (match_operator:BOOL_128 3 "boolean_or_operator"
7386 [(match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
7387 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")]))]
7388 ""
7389 {
7390 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
7391 return "xxl%q3 %x0,%x1,%x2";
7392
7393 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
7394 return "v%q3 %0,%1,%2";
7395
7396 return "#";
7397 }
7398 "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
7399 [(const_int 0)]
7400 {
7401 rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, false);
7402 DONE;
7403 }
7404 [(set (attr "type")
7405 (if_then_else
7406 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
7407 (const_string "vecsimple")
7408 (const_string "integer")))
7409 (set (attr "length")
7410 (if_then_else
7411 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
7412 (const_string "4")
7413 (if_then_else
7414 (match_test "TARGET_POWERPC64")
7415 (const_string "8")
7416 (const_string "16"))))])
7417
7418 ;; 128-bit ANDC/ORC
7419 (define_insn_and_split "*boolc<mode>3_internal1"
7420 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
7421 (match_operator:BOOL_128 3 "boolean_operator"
7422 [(not:BOOL_128
7423 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP1>"))
7424 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP2>")]))]
7425 "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
7426 {
7427 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
7428 return "xxl%q3 %x0,%x1,%x2";
7429
7430 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
7431 return "v%q3 %0,%1,%2";
7432
7433 return "#";
7434 }
7435 "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
7436 && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
7437 [(const_int 0)]
7438 {
7439 rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, false);
7440 DONE;
7441 }
7442 [(set (attr "type")
7443 (if_then_else
7444 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
7445 (const_string "vecsimple")
7446 (const_string "integer")))
7447 (set (attr "length")
7448 (if_then_else
7449 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
7450 (const_string "4")
7451 (if_then_else
7452 (match_test "TARGET_POWERPC64")
7453 (const_string "8")
7454 (const_string "16"))))])
7455
7456 (define_insn_and_split "*boolc<mode>3_internal2"
7457 [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
7458 (match_operator:TI2 3 "boolean_operator"
7459 [(not:TI2
7460 (match_operand:TI2 1 "int_reg_operand" "r,0,r"))
7461 (match_operand:TI2 2 "int_reg_operand" "r,r,0")]))]
7462 "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
7463 "#"
7464 "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
7465 [(const_int 0)]
7466 {
7467 rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, false);
7468 DONE;
7469 }
7470 [(set_attr "type" "integer")
7471 (set (attr "length")
7472 (if_then_else
7473 (match_test "TARGET_POWERPC64")
7474 (const_string "8")
7475 (const_string "16")))])
7476
7477 ;; 128-bit NAND/NOR
7478 (define_insn_and_split "*boolcc<mode>3_internal1"
7479 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
7480 (match_operator:BOOL_128 3 "boolean_operator"
7481 [(not:BOOL_128
7482 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>"))
7483 (not:BOOL_128
7484 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))]))]
7485 "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
7486 {
7487 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
7488 return "xxl%q3 %x0,%x1,%x2";
7489
7490 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
7491 return "v%q3 %0,%1,%2";
7492
7493 return "#";
7494 }
7495 "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
7496 && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
7497 [(const_int 0)]
7498 {
7499 rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
7500 DONE;
7501 }
7502 [(set (attr "type")
7503 (if_then_else
7504 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
7505 (const_string "vecsimple")
7506 (const_string "integer")))
7507 (set (attr "length")
7508 (if_then_else
7509 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
7510 (const_string "4")
7511 (if_then_else
7512 (match_test "TARGET_POWERPC64")
7513 (const_string "8")
7514 (const_string "16"))))])
7515
7516 (define_insn_and_split "*boolcc<mode>3_internal2"
7517 [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
7518 (match_operator:TI2 3 "boolean_operator"
7519 [(not:TI2
7520 (match_operand:TI2 1 "int_reg_operand" "r,0,r"))
7521 (not:TI2
7522 (match_operand:TI2 2 "int_reg_operand" "r,r,0"))]))]
7523 "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
7524 "#"
7525 "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
7526 [(const_int 0)]
7527 {
7528 rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
7529 DONE;
7530 }
7531 [(set_attr "type" "integer")
7532 (set (attr "length")
7533 (if_then_else
7534 (match_test "TARGET_POWERPC64")
7535 (const_string "8")
7536 (const_string "16")))])
7537
7538
7539 ;; 128-bit EQV
7540 (define_insn_and_split "*eqv<mode>3_internal1"
7541 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
7542 (not:BOOL_128
7543 (xor:BOOL_128
7544 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")
7545 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))))]
7546 "TARGET_P8_VECTOR"
7547 {
7548 if (vsx_register_operand (operands[0], <MODE>mode))
7549 return "xxleqv %x0,%x1,%x2";
7550
7551 return "#";
7552 }
7553 "TARGET_P8_VECTOR && reload_completed
7554 && int_reg_operand (operands[0], <MODE>mode)"
7555 [(const_int 0)]
7556 {
7557 rs6000_split_logical (operands, XOR, true, false, false);
7558 DONE;
7559 }
7560 [(set (attr "type")
7561 (if_then_else
7562 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
7563 (const_string "vecsimple")
7564 (const_string "integer")))
7565 (set (attr "length")
7566 (if_then_else
7567 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
7568 (const_string "4")
7569 (if_then_else
7570 (match_test "TARGET_POWERPC64")
7571 (const_string "8")
7572 (const_string "16"))))])
7573
7574 (define_insn_and_split "*eqv<mode>3_internal2"
7575 [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
7576 (not:TI2
7577 (xor:TI2
7578 (match_operand:TI2 1 "int_reg_operand" "r,0,r")
7579 (match_operand:TI2 2 "int_reg_operand" "r,r,0"))))]
7580 "!TARGET_P8_VECTOR"
7581 "#"
7582 "reload_completed && !TARGET_P8_VECTOR"
7583 [(const_int 0)]
7584 {
7585 rs6000_split_logical (operands, XOR, true, false, false);
7586 DONE;
7587 }
7588 [(set_attr "type" "integer")
7589 (set (attr "length")
7590 (if_then_else
7591 (match_test "TARGET_POWERPC64")
7592 (const_string "8")
7593 (const_string "16")))])
7594
7595 ;; 128-bit one's complement
7596 (define_insn_and_split "*one_cmpl<mode>3_internal"
7597 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
7598 (not:BOOL_128
7599 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_UNARY>")))]
7600 ""
7601 {
7602 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
7603 return "xxlnor %x0,%x1,%x1";
7604
7605 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
7606 return "vnor %0,%1,%1";
7607
7608 return "#";
7609 }
7610 "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
7611 [(const_int 0)]
7612 {
7613 rs6000_split_logical (operands, NOT, false, false, false);
7614 DONE;
7615 }
7616 [(set (attr "type")
7617 (if_then_else
7618 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
7619 (const_string "vecsimple")
7620 (const_string "integer")))
7621 (set (attr "length")
7622 (if_then_else
7623 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
7624 (const_string "4")
7625 (if_then_else
7626 (match_test "TARGET_POWERPC64")
7627 (const_string "8")
7628 (const_string "16"))))])
7629
7630 \f
7631 ;; Now define ways of moving data around.
7632
7633 ;; Set up a register with a value from the GOT table
7634
7635 (define_expand "movsi_got"
7636 [(set (match_operand:SI 0 "gpc_reg_operand" "")
7637 (unspec:SI [(match_operand:SI 1 "got_operand" "")
7638 (match_dup 2)] UNSPEC_MOVSI_GOT))]
7639 "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
7640 "
7641 {
7642 if (GET_CODE (operands[1]) == CONST)
7643 {
7644 rtx offset = const0_rtx;
7645 HOST_WIDE_INT value;
7646
7647 operands[1] = eliminate_constant_term (XEXP (operands[1], 0), &offset);
7648 value = INTVAL (offset);
7649 if (value != 0)
7650 {
7651 rtx tmp = (!can_create_pseudo_p ()
7652 ? operands[0]
7653 : gen_reg_rtx (Pmode));
7654 emit_insn (gen_movsi_got (tmp, operands[1]));
7655 emit_insn (gen_addsi3 (operands[0], tmp, offset));
7656 DONE;
7657 }
7658 }
7659
7660 operands[2] = rs6000_got_register (operands[1]);
7661 }")
7662
7663 (define_insn "*movsi_got_internal"
7664 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
7665 (unspec:SI [(match_operand:SI 1 "got_no_const_operand" "")
7666 (match_operand:SI 2 "gpc_reg_operand" "b")]
7667 UNSPEC_MOVSI_GOT))]
7668 "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
7669 "lwz %0,%a1@got(%2)"
7670 [(set_attr "type" "load")])
7671
7672 ;; Used by sched, shorten_branches and final when the GOT pseudo reg
7673 ;; didn't get allocated to a hard register.
7674 (define_split
7675 [(set (match_operand:SI 0 "gpc_reg_operand" "")
7676 (unspec:SI [(match_operand:SI 1 "got_no_const_operand" "")
7677 (match_operand:SI 2 "memory_operand" "")]
7678 UNSPEC_MOVSI_GOT))]
7679 "DEFAULT_ABI == ABI_V4
7680 && flag_pic == 1
7681 && (reload_in_progress || reload_completed)"
7682 [(set (match_dup 0) (match_dup 2))
7683 (set (match_dup 0) (unspec:SI [(match_dup 1)(match_dup 0)]
7684 UNSPEC_MOVSI_GOT))]
7685 "")
7686
7687 ;; For SI, we special-case integers that can't be loaded in one insn. We
7688 ;; do the load 16-bits at a time. We could do this by loading from memory,
7689 ;; and this is even supposed to be faster, but it is simpler not to get
7690 ;; integers in the TOC.
7691 (define_insn "movsi_low"
7692 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
7693 (mem:SI (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
7694 (match_operand 2 "" ""))))]
7695 "TARGET_MACHO && ! TARGET_64BIT"
7696 "lwz %0,lo16(%2)(%1)"
7697 [(set_attr "type" "load")
7698 (set_attr "length" "4")])
7699
7700 (define_insn "*movsi_internal1"
7701 [(set (match_operand:SI 0 "rs6000_nonimmediate_operand" "=r,r,r,m,r,r,r,r,*c*l,*h,*h")
7702 (match_operand:SI 1 "input_operand" "r,U,m,r,I,L,n,*h,r,r,0"))]
7703 "!TARGET_SINGLE_FPU &&
7704 (gpc_reg_operand (operands[0], SImode) || gpc_reg_operand (operands[1], SImode))"
7705 "@
7706 mr %0,%1
7707 la %0,%a1
7708 lwz%U1%X1 %0,%1
7709 stw%U0%X0 %1,%0
7710 li %0,%1
7711 lis %0,%v1
7712 #
7713 mf%1 %0
7714 mt%0 %1
7715 mt%0 %1
7716 nop"
7717 [(set_attr "type" "*,*,load,store,*,*,*,mfjmpr,mtjmpr,*,*")
7718 (set_attr "length" "4,4,4,4,4,4,8,4,4,4,4")])
7719
7720 (define_insn "*movsi_internal1_single"
7721 [(set (match_operand:SI 0 "rs6000_nonimmediate_operand" "=r,r,r,m,r,r,r,r,*c*l,*h,*h,m,*f")
7722 (match_operand:SI 1 "input_operand" "r,U,m,r,I,L,n,*h,r,r,0,f,m"))]
7723 "TARGET_SINGLE_FPU &&
7724 (gpc_reg_operand (operands[0], SImode) || gpc_reg_operand (operands[1], SImode))"
7725 "@
7726 mr %0,%1
7727 la %0,%a1
7728 lwz%U1%X1 %0,%1
7729 stw%U0%X0 %1,%0
7730 li %0,%1
7731 lis %0,%v1
7732 #
7733 mf%1 %0
7734 mt%0 %1
7735 mt%0 %1
7736 nop
7737 stfs%U0%X0 %1,%0
7738 lfs%U1%X1 %0,%1"
7739 [(set_attr "type" "*,*,load,store,*,*,*,mfjmpr,mtjmpr,*,*,fpstore,fpload")
7740 (set_attr "length" "4,4,4,4,4,4,8,4,4,4,4,4,4")])
7741
7742 ;; Split a load of a large constant into the appropriate two-insn
7743 ;; sequence.
7744
7745 (define_split
7746 [(set (match_operand:SI 0 "gpc_reg_operand" "")
7747 (match_operand:SI 1 "const_int_operand" ""))]
7748 "(unsigned HOST_WIDE_INT) (INTVAL (operands[1]) + 0x8000) >= 0x10000
7749 && (INTVAL (operands[1]) & 0xffff) != 0"
7750 [(set (match_dup 0)
7751 (match_dup 2))
7752 (set (match_dup 0)
7753 (ior:SI (match_dup 0)
7754 (match_dup 3)))]
7755 "
7756 {
7757 if (rs6000_emit_set_const (operands[0], operands[1]))
7758 DONE;
7759 else
7760 FAIL;
7761 }")
7762
7763 (define_insn "*mov<mode>_internal2"
7764 [(set (match_operand:CC 2 "cc_reg_operand" "=y,x,?y")
7765 (compare:CC (match_operand:P 1 "gpc_reg_operand" "0,r,r")
7766 (const_int 0)))
7767 (set (match_operand:P 0 "gpc_reg_operand" "=r,r,r") (match_dup 1))]
7768 ""
7769 "@
7770 cmp<wd>i %2,%0,0
7771 mr. %0,%1
7772 #"
7773 [(set_attr "type" "cmp,logical,cmp")
7774 (set_attr "dot" "yes")
7775 (set_attr "length" "4,4,8")])
7776
7777 (define_split
7778 [(set (match_operand:CC 2 "cc_reg_not_micro_cr0_operand" "")
7779 (compare:CC (match_operand:P 1 "gpc_reg_operand" "")
7780 (const_int 0)))
7781 (set (match_operand:P 0 "gpc_reg_operand" "") (match_dup 1))]
7782 "reload_completed"
7783 [(set (match_dup 0) (match_dup 1))
7784 (set (match_dup 2)
7785 (compare:CC (match_dup 0)
7786 (const_int 0)))]
7787 "")
7788 \f
7789 (define_insn "*movhi_internal"
7790 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,m,r,r,*c*l,*h")
7791 (match_operand:HI 1 "input_operand" "r,m,r,i,*h,r,0"))]
7792 "gpc_reg_operand (operands[0], HImode)
7793 || gpc_reg_operand (operands[1], HImode)"
7794 "@
7795 mr %0,%1
7796 lhz%U1%X1 %0,%1
7797 sth%U0%X0 %1,%0
7798 li %0,%w1
7799 mf%1 %0
7800 mt%0 %1
7801 nop"
7802 [(set_attr "type" "*,load,store,*,mfjmpr,mtjmpr,*")])
7803
7804 (define_expand "mov<mode>"
7805 [(set (match_operand:INT 0 "general_operand" "")
7806 (match_operand:INT 1 "any_operand" ""))]
7807 ""
7808 "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
7809
7810 (define_insn "*movqi_internal"
7811 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m,r,r,*c*l,*h")
7812 (match_operand:QI 1 "input_operand" "r,m,r,i,*h,r,0"))]
7813 "gpc_reg_operand (operands[0], QImode)
7814 || gpc_reg_operand (operands[1], QImode)"
7815 "@
7816 mr %0,%1
7817 lbz%U1%X1 %0,%1
7818 stb%U0%X0 %1,%0
7819 li %0,%1
7820 mf%1 %0
7821 mt%0 %1
7822 nop"
7823 [(set_attr "type" "*,load,store,*,mfjmpr,mtjmpr,*")])
7824 \f
7825 ;; Here is how to move condition codes around. When we store CC data in
7826 ;; an integer register or memory, we store just the high-order 4 bits.
7827 ;; This lets us not shift in the most common case of CR0.
7828 (define_expand "movcc"
7829 [(set (match_operand:CC 0 "nonimmediate_operand" "")
7830 (match_operand:CC 1 "nonimmediate_operand" ""))]
7831 ""
7832 "")
7833
7834 (define_insn "*movcc_internal1"
7835 [(set (match_operand:CC 0 "nonimmediate_operand" "=y,x,?y,y,r,r,r,r,r,cl,r,m")
7836 (match_operand:CC 1 "general_operand" "y,r,r,O,x,y,r,I,h,r,m,r"))]
7837 "register_operand (operands[0], CCmode)
7838 || register_operand (operands[1], CCmode)"
7839 "@
7840 mcrf %0,%1
7841 mtcrf 128,%1
7842 rlwinm %1,%1,%F0,0xffffffff\;mtcrf %R0,%1\;rlwinm %1,%1,%f0,0xffffffff
7843 crxor %0,%0,%0
7844 mfcr %0%Q1
7845 mfcr %0%Q1\;rlwinm %0,%0,%f1,0xf0000000
7846 mr %0,%1
7847 li %0,%1
7848 mf%1 %0
7849 mt%0 %1
7850 lwz%U1%X1 %0,%1
7851 stw%U0%X0 %1,%0"
7852 [(set (attr "type")
7853 (cond [(eq_attr "alternative" "0,3")
7854 (const_string "cr_logical")
7855 (eq_attr "alternative" "1,2")
7856 (const_string "mtcr")
7857 (eq_attr "alternative" "6,7")
7858 (const_string "integer")
7859 (eq_attr "alternative" "8")
7860 (const_string "mfjmpr")
7861 (eq_attr "alternative" "9")
7862 (const_string "mtjmpr")
7863 (eq_attr "alternative" "10")
7864 (const_string "load")
7865 (eq_attr "alternative" "11")
7866 (const_string "store")
7867 (match_test "TARGET_MFCRF")
7868 (const_string "mfcrf")
7869 ]
7870 (const_string "mfcr")))
7871 (set_attr "length" "4,4,12,4,4,8,4,4,4,4,4,4")])
7872 \f
7873 ;; For floating-point, we normally deal with the floating-point registers
7874 ;; unless -msoft-float is used. The sole exception is that parameter passing
7875 ;; can produce floating-point values in fixed-point registers. Unless the
7876 ;; value is a simple constant or already in memory, we deal with this by
7877 ;; allocating memory and copying the value explicitly via that memory location.
7878
7879 ;; Move 32-bit binary/decimal floating point
7880 (define_expand "mov<mode>"
7881 [(set (match_operand:FMOVE32 0 "nonimmediate_operand" "")
7882 (match_operand:FMOVE32 1 "any_operand" ""))]
7883 "<fmove_ok>"
7884 "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
7885
7886 (define_split
7887 [(set (match_operand:FMOVE32 0 "gpc_reg_operand" "")
7888 (match_operand:FMOVE32 1 "const_double_operand" ""))]
7889 "reload_completed
7890 && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
7891 || (GET_CODE (operands[0]) == SUBREG
7892 && GET_CODE (SUBREG_REG (operands[0])) == REG
7893 && REGNO (SUBREG_REG (operands[0])) <= 31))"
7894 [(set (match_dup 2) (match_dup 3))]
7895 "
7896 {
7897 long l;
7898 REAL_VALUE_TYPE rv;
7899
7900 REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]);
7901 <real_value_to_target> (rv, l);
7902
7903 if (! TARGET_POWERPC64)
7904 operands[2] = operand_subword (operands[0], 0, 0, <MODE>mode);
7905 else
7906 operands[2] = gen_lowpart (SImode, operands[0]);
7907
7908 operands[3] = gen_int_mode (l, SImode);
7909 }")
7910
7911 (define_insn "mov<mode>_hardfloat"
7912 [(set (match_operand:FMOVE32 0 "nonimmediate_operand" "=!r,!r,m,f,wa,wa,<f32_lr>,<f32_sm>,wu,Z,?<f32_dm>,?r,*c*l,!r,*h,!r,!r")
7913 (match_operand:FMOVE32 1 "input_operand" "r,m,r,f,wa,j,<f32_lm>,<f32_sr>,Z,wu,r,<f32_dm>,r,h,0,G,Fn"))]
7914 "(gpc_reg_operand (operands[0], <MODE>mode)
7915 || gpc_reg_operand (operands[1], <MODE>mode))
7916 && (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT)"
7917 "@
7918 mr %0,%1
7919 lwz%U1%X1 %0,%1
7920 stw%U0%X0 %1,%0
7921 fmr %0,%1
7922 xxlor %x0,%x1,%x1
7923 xxlxor %x0,%x0,%x0
7924 <f32_li>
7925 <f32_si>
7926 <f32_lv>
7927 <f32_sv>
7928 mtvsrwz %x0,%1
7929 mfvsrwz %0,%x1
7930 mt%0 %1
7931 mf%1 %0
7932 nop
7933 #
7934 #"
7935 [(set_attr "type" "*,load,store,fp,vecsimple,vecsimple,fpload,fpstore,fpload,fpstore,mftgpr,mffgpr,mtjmpr,mfjmpr,*,*,*")
7936 (set_attr "length" "4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,8")])
7937
7938 (define_insn "*mov<mode>_softfloat"
7939 [(set (match_operand:FMOVE32 0 "nonimmediate_operand" "=r,cl,r,r,m,r,r,r,r,*h")
7940 (match_operand:FMOVE32 1 "input_operand" "r,r,h,m,r,I,L,G,Fn,0"))]
7941 "(gpc_reg_operand (operands[0], <MODE>mode)
7942 || gpc_reg_operand (operands[1], <MODE>mode))
7943 && (TARGET_SOFT_FLOAT || !TARGET_FPRS)"
7944 "@
7945 mr %0,%1
7946 mt%0 %1
7947 mf%1 %0
7948 lwz%U1%X1 %0,%1
7949 stw%U0%X0 %1,%0
7950 li %0,%1
7951 lis %0,%v1
7952 #
7953 #
7954 nop"
7955 [(set_attr "type" "*,mtjmpr,mfjmpr,load,store,*,*,*,*,*")
7956 (set_attr "length" "4,4,4,4,4,4,4,4,8,4")])
7957
7958 \f
7959 ;; Move 64-bit binary/decimal floating point
7960 (define_expand "mov<mode>"
7961 [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "")
7962 (match_operand:FMOVE64 1 "any_operand" ""))]
7963 ""
7964 "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
7965
7966 (define_split
7967 [(set (match_operand:FMOVE64 0 "gpc_reg_operand" "")
7968 (match_operand:FMOVE64 1 "const_int_operand" ""))]
7969 "! TARGET_POWERPC64 && reload_completed
7970 && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
7971 || (GET_CODE (operands[0]) == SUBREG
7972 && GET_CODE (SUBREG_REG (operands[0])) == REG
7973 && REGNO (SUBREG_REG (operands[0])) <= 31))"
7974 [(set (match_dup 2) (match_dup 4))
7975 (set (match_dup 3) (match_dup 1))]
7976 "
7977 {
7978 int endian = (WORDS_BIG_ENDIAN == 0);
7979 HOST_WIDE_INT value = INTVAL (operands[1]);
7980
7981 operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
7982 operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
7983 operands[4] = GEN_INT (value >> 32);
7984 operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
7985 }")
7986
7987 (define_split
7988 [(set (match_operand:FMOVE64 0 "gpc_reg_operand" "")
7989 (match_operand:FMOVE64 1 "const_double_operand" ""))]
7990 "! TARGET_POWERPC64 && reload_completed
7991 && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
7992 || (GET_CODE (operands[0]) == SUBREG
7993 && GET_CODE (SUBREG_REG (operands[0])) == REG
7994 && REGNO (SUBREG_REG (operands[0])) <= 31))"
7995 [(set (match_dup 2) (match_dup 4))
7996 (set (match_dup 3) (match_dup 5))]
7997 "
7998 {
7999 int endian = (WORDS_BIG_ENDIAN == 0);
8000 long l[2];
8001 REAL_VALUE_TYPE rv;
8002
8003 REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]);
8004 <real_value_to_target> (rv, l);
8005
8006 operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
8007 operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
8008 operands[4] = gen_int_mode (l[endian], SImode);
8009 operands[5] = gen_int_mode (l[1 - endian], SImode);
8010 }")
8011
8012 (define_split
8013 [(set (match_operand:FMOVE64 0 "gpc_reg_operand" "")
8014 (match_operand:FMOVE64 1 "const_double_operand" ""))]
8015 "TARGET_POWERPC64 && reload_completed
8016 && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
8017 || (GET_CODE (operands[0]) == SUBREG
8018 && GET_CODE (SUBREG_REG (operands[0])) == REG
8019 && REGNO (SUBREG_REG (operands[0])) <= 31))"
8020 [(set (match_dup 2) (match_dup 3))]
8021 "
8022 {
8023 int endian = (WORDS_BIG_ENDIAN == 0);
8024 long l[2];
8025 REAL_VALUE_TYPE rv;
8026 HOST_WIDE_INT val;
8027
8028 REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]);
8029 <real_value_to_target> (rv, l);
8030
8031 operands[2] = gen_lowpart (DImode, operands[0]);
8032 /* HIGHPART is lower memory address when WORDS_BIG_ENDIAN. */
8033 val = ((HOST_WIDE_INT)(unsigned long)l[endian] << 32
8034 | ((HOST_WIDE_INT)(unsigned long)l[1 - endian]));
8035
8036 operands[3] = gen_int_mode (val, DImode);
8037 }")
8038
8039 ;; Don't have reload use general registers to load a constant. It is
8040 ;; less efficient than loading the constant into an FP register, since
8041 ;; it will probably be used there.
8042
8043 ;; The move constraints are ordered to prefer floating point registers before
8044 ;; general purpose registers to avoid doing a store and a load to get the value
8045 ;; into a floating point register when it is needed for a floating point
8046 ;; operation. Prefer traditional floating point registers over VSX registers,
8047 ;; since the D-form version of the memory instructions does not need a GPR for
8048 ;; reloading.
8049
8050 (define_insn "*mov<mode>_hardfloat32"
8051 [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=m,d,d,wv,Z,wa,wa,Y,r,!r,!r,!r,!r")
8052 (match_operand:FMOVE64 1 "input_operand" "d,m,d,Z,wv,wa,j,r,Y,r,G,H,F"))]
8053 "! TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
8054 && (gpc_reg_operand (operands[0], <MODE>mode)
8055 || gpc_reg_operand (operands[1], <MODE>mode))"
8056 "@
8057 stfd%U0%X0 %1,%0
8058 lfd%U1%X1 %0,%1
8059 fmr %0,%1
8060 lxsd%U1x %x0,%y1
8061 stxsd%U0x %x1,%y0
8062 xxlor %x0,%x1,%x1
8063 xxlxor %x0,%x0,%x0
8064 #
8065 #
8066 #
8067 #
8068 #
8069 #"
8070 [(set_attr "type" "fpstore,fpload,fp,fpload,fpstore,vecsimple,vecsimple,store,load,two,fp,fp,*")
8071 (set_attr "length" "4,4,4,4,4,4,4,8,8,8,8,12,16")])
8072
8073 (define_insn "*mov<mode>_softfloat32"
8074 [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=Y,r,r,r,r,r")
8075 (match_operand:FMOVE64 1 "input_operand" "r,Y,r,G,H,F"))]
8076 "! TARGET_POWERPC64
8077 && ((TARGET_FPRS && TARGET_SINGLE_FLOAT)
8078 || TARGET_SOFT_FLOAT || TARGET_E500_SINGLE
8079 || (<MODE>mode == DDmode && TARGET_E500_DOUBLE))
8080 && (gpc_reg_operand (operands[0], <MODE>mode)
8081 || gpc_reg_operand (operands[1], <MODE>mode))"
8082 "#"
8083 [(set_attr "type" "store,load,two,*,*,*")
8084 (set_attr "length" "8,8,8,8,12,16")])
8085
8086 ; ld/std require word-aligned displacements -> 'Y' constraint.
8087 ; List Y->r and r->Y before r->r for reload.
8088 (define_insn "*mov<mode>_hardfloat64"
8089 [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=m,d,d,wv,Z,wa,wa,Y,r,!r,*c*l,!r,*h,!r,!r,!r,r,wg,r,wk")
8090 (match_operand:FMOVE64 1 "input_operand" "d,m,d,Z,wv,wa,j,r,Y,r,r,h,0,G,H,F,wg,r,wk,r"))]
8091 "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
8092 && (gpc_reg_operand (operands[0], <MODE>mode)
8093 || gpc_reg_operand (operands[1], <MODE>mode))"
8094 "@
8095 stfd%U0%X0 %1,%0
8096 lfd%U1%X1 %0,%1
8097 fmr %0,%1
8098 lxsd%U1x %x0,%y1
8099 stxsd%U0x %x1,%y0
8100 xxlor %x0,%x1,%x1
8101 xxlxor %x0,%x0,%x0
8102 std%U0%X0 %1,%0
8103 ld%U1%X1 %0,%1
8104 mr %0,%1
8105 mt%0 %1
8106 mf%1 %0
8107 nop
8108 #
8109 #
8110 #
8111 mftgpr %0,%1
8112 mffgpr %0,%1
8113 mfvsrd %0,%x1
8114 mtvsrd %x0,%1"
8115 [(set_attr "type" "fpstore,fpload,fp,fpload,fpstore,vecsimple,vecsimple,store,load,*,mtjmpr,mfjmpr,*,*,*,*,mftgpr,mffgpr,mftgpr,mffgpr")
8116 (set_attr "length" "4,4,4,4,4,4,4,4,4,4,4,4,4,8,12,16,4,4,4,4")])
8117
8118 (define_insn "*mov<mode>_softfloat64"
8119 [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=Y,r,r,cl,r,r,r,r,*h")
8120 (match_operand:FMOVE64 1 "input_operand" "r,Y,r,r,h,G,H,F,0"))]
8121 "TARGET_POWERPC64 && (TARGET_SOFT_FLOAT || !TARGET_FPRS)
8122 && (gpc_reg_operand (operands[0], <MODE>mode)
8123 || gpc_reg_operand (operands[1], <MODE>mode))"
8124 "@
8125 std%U0%X0 %1,%0
8126 ld%U1%X1 %0,%1
8127 mr %0,%1
8128 mt%0 %1
8129 mf%1 %0
8130 #
8131 #
8132 #
8133 nop"
8134 [(set_attr "type" "store,load,*,mtjmpr,mfjmpr,*,*,*,*")
8135 (set_attr "length" "4,4,4,4,4,8,12,16,4")])
8136 \f
8137 (define_expand "mov<mode>"
8138 [(set (match_operand:FMOVE128 0 "general_operand" "")
8139 (match_operand:FMOVE128 1 "any_operand" ""))]
8140 ""
8141 "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
8142
8143 ;; It's important to list Y->r and r->Y before r->r because otherwise
8144 ;; reload, given m->r, will try to pick r->r and reload it, which
8145 ;; doesn't make progress.
8146
8147 ;; We can't split little endian direct moves of TDmode, because the words are
8148 ;; not swapped like they are for TImode or TFmode. Subregs therefore are
8149 ;; problematical. Don't allow direct move for this case.
8150
8151 (define_insn_and_split "*mov<mode>_64bit_dm"
8152 [(set (match_operand:FMOVE128 0 "nonimmediate_operand" "=m,d,d,Y,r,r,r,wm")
8153 (match_operand:FMOVE128 1 "input_operand" "d,m,d,r,YGHF,r,wm,r"))]
8154 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_POWERPC64
8155 && (<MODE>mode != TDmode || WORDS_BIG_ENDIAN)
8156 && (gpc_reg_operand (operands[0], <MODE>mode)
8157 || gpc_reg_operand (operands[1], <MODE>mode))"
8158 "#"
8159 "&& reload_completed"
8160 [(pc)]
8161 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
8162 [(set_attr "length" "8,8,8,12,12,8,8,8")])
8163
8164 (define_insn_and_split "*movtd_64bit_nodm"
8165 [(set (match_operand:TD 0 "nonimmediate_operand" "=m,d,d,Y,r,r")
8166 (match_operand:TD 1 "input_operand" "d,m,d,r,YGHF,r"))]
8167 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_POWERPC64 && !WORDS_BIG_ENDIAN
8168 && (gpc_reg_operand (operands[0], TDmode)
8169 || gpc_reg_operand (operands[1], TDmode))"
8170 "#"
8171 "&& reload_completed"
8172 [(pc)]
8173 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
8174 [(set_attr "length" "8,8,8,12,12,8")])
8175
8176 (define_insn_and_split "*mov<mode>_32bit"
8177 [(set (match_operand:FMOVE128 0 "nonimmediate_operand" "=m,d,d,Y,r,r")
8178 (match_operand:FMOVE128 1 "input_operand" "d,m,d,r,YGHF,r"))]
8179 "TARGET_HARD_FLOAT && TARGET_FPRS && !TARGET_POWERPC64
8180 && (gpc_reg_operand (operands[0], <MODE>mode)
8181 || gpc_reg_operand (operands[1], <MODE>mode))"
8182 "#"
8183 "&& reload_completed"
8184 [(pc)]
8185 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
8186 [(set_attr "length" "8,8,8,20,20,16")])
8187
8188 (define_insn_and_split "*mov<mode>_softfloat"
8189 [(set (match_operand:FMOVE128 0 "rs6000_nonimmediate_operand" "=Y,r,r")
8190 (match_operand:FMOVE128 1 "input_operand" "r,YGHF,r"))]
8191 "(TARGET_SOFT_FLOAT || !TARGET_FPRS)
8192 && (gpc_reg_operand (operands[0], <MODE>mode)
8193 || gpc_reg_operand (operands[1], <MODE>mode))"
8194 "#"
8195 "&& reload_completed"
8196 [(pc)]
8197 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
8198 [(set_attr "length" "20,20,16")])
8199
8200 (define_expand "extenddftf2"
8201 [(set (match_operand:TF 0 "nonimmediate_operand" "")
8202 (float_extend:TF (match_operand:DF 1 "input_operand" "")))]
8203 "!TARGET_IEEEQUAD
8204 && TARGET_HARD_FLOAT
8205 && (TARGET_FPRS || TARGET_E500_DOUBLE)
8206 && TARGET_LONG_DOUBLE_128"
8207 {
8208 if (TARGET_E500_DOUBLE)
8209 emit_insn (gen_spe_extenddftf2 (operands[0], operands[1]));
8210 else
8211 emit_insn (gen_extenddftf2_fprs (operands[0], operands[1]));
8212 DONE;
8213 })
8214
8215 (define_expand "extenddftf2_fprs"
8216 [(parallel [(set (match_operand:TF 0 "nonimmediate_operand" "")
8217 (float_extend:TF (match_operand:DF 1 "input_operand" "")))
8218 (use (match_dup 2))])]
8219 "!TARGET_IEEEQUAD
8220 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
8221 && TARGET_LONG_DOUBLE_128"
8222 {
8223 operands[2] = CONST0_RTX (DFmode);
8224 /* Generate GOT reference early for SVR4 PIC. */
8225 if (DEFAULT_ABI == ABI_V4 && flag_pic)
8226 operands[2] = validize_mem (force_const_mem (DFmode, operands[2]));
8227 })
8228
8229 (define_insn_and_split "*extenddftf2_internal"
8230 [(set (match_operand:TF 0 "nonimmediate_operand" "=m,Y,d,&d,r")
8231 (float_extend:TF (match_operand:DF 1 "input_operand" "d,r,md,md,rmGHF")))
8232 (use (match_operand:DF 2 "zero_reg_mem_operand" "d,r,m,d,n"))]
8233 "!TARGET_IEEEQUAD
8234 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
8235 && TARGET_LONG_DOUBLE_128"
8236 "#"
8237 "&& reload_completed"
8238 [(pc)]
8239 {
8240 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
8241 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
8242 emit_move_insn (simplify_gen_subreg (DFmode, operands[0], TFmode, hi_word),
8243 operands[1]);
8244 emit_move_insn (simplify_gen_subreg (DFmode, operands[0], TFmode, lo_word),
8245 operands[2]);
8246 DONE;
8247 })
8248
8249 (define_expand "extendsftf2"
8250 [(set (match_operand:TF 0 "nonimmediate_operand" "")
8251 (float_extend:TF (match_operand:SF 1 "gpc_reg_operand" "")))]
8252 "!TARGET_IEEEQUAD
8253 && TARGET_HARD_FLOAT
8254 && (TARGET_FPRS || TARGET_E500_DOUBLE)
8255 && TARGET_LONG_DOUBLE_128"
8256 {
8257 rtx tmp = gen_reg_rtx (DFmode);
8258 emit_insn (gen_extendsfdf2 (tmp, operands[1]));
8259 emit_insn (gen_extenddftf2 (operands[0], tmp));
8260 DONE;
8261 })
8262
8263 (define_expand "trunctfdf2"
8264 [(set (match_operand:DF 0 "gpc_reg_operand" "")
8265 (float_truncate:DF (match_operand:TF 1 "gpc_reg_operand" "")))]
8266 "!TARGET_IEEEQUAD
8267 && TARGET_HARD_FLOAT
8268 && (TARGET_FPRS || TARGET_E500_DOUBLE)
8269 && TARGET_LONG_DOUBLE_128"
8270 "")
8271
8272 (define_insn_and_split "trunctfdf2_internal1"
8273 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d")
8274 (float_truncate:DF (match_operand:TF 1 "gpc_reg_operand" "0,d")))]
8275 "!TARGET_IEEEQUAD && !TARGET_XL_COMPAT
8276 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
8277 "@
8278 #
8279 fmr %0,%1"
8280 "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
8281 [(const_int 0)]
8282 {
8283 emit_note (NOTE_INSN_DELETED);
8284 DONE;
8285 }
8286 [(set_attr "type" "fp")])
8287
8288 (define_insn "trunctfdf2_internal2"
8289 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
8290 (float_truncate:DF (match_operand:TF 1 "gpc_reg_operand" "d")))]
8291 "!TARGET_IEEEQUAD && TARGET_XL_COMPAT
8292 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
8293 && TARGET_LONG_DOUBLE_128"
8294 "fadd %0,%1,%L1"
8295 [(set_attr "type" "fp")
8296 (set_attr "fp_type" "fp_addsub_d")])
8297
8298 (define_expand "trunctfsf2"
8299 [(set (match_operand:SF 0 "gpc_reg_operand" "")
8300 (float_truncate:SF (match_operand:TF 1 "gpc_reg_operand" "")))]
8301 "!TARGET_IEEEQUAD
8302 && TARGET_HARD_FLOAT
8303 && (TARGET_FPRS || TARGET_E500_DOUBLE)
8304 && TARGET_LONG_DOUBLE_128"
8305 {
8306 if (TARGET_E500_DOUBLE)
8307 emit_insn (gen_spe_trunctfsf2 (operands[0], operands[1]));
8308 else
8309 emit_insn (gen_trunctfsf2_fprs (operands[0], operands[1]));
8310 DONE;
8311 })
8312
8313 (define_insn_and_split "trunctfsf2_fprs"
8314 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
8315 (float_truncate:SF (match_operand:TF 1 "gpc_reg_operand" "d")))
8316 (clobber (match_scratch:DF 2 "=d"))]
8317 "!TARGET_IEEEQUAD
8318 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
8319 && TARGET_LONG_DOUBLE_128"
8320 "#"
8321 "&& reload_completed"
8322 [(set (match_dup 2)
8323 (float_truncate:DF (match_dup 1)))
8324 (set (match_dup 0)
8325 (float_truncate:SF (match_dup 2)))]
8326 "")
8327
8328 (define_expand "floatsitf2"
8329 [(set (match_operand:TF 0 "gpc_reg_operand" "")
8330 (float:TF (match_operand:SI 1 "gpc_reg_operand" "")))]
8331 "!TARGET_IEEEQUAD
8332 && TARGET_HARD_FLOAT
8333 && (TARGET_FPRS || TARGET_E500_DOUBLE)
8334 && TARGET_LONG_DOUBLE_128"
8335 {
8336 rtx tmp = gen_reg_rtx (DFmode);
8337 expand_float (tmp, operands[1], false);
8338 emit_insn (gen_extenddftf2 (operands[0], tmp));
8339 DONE;
8340 })
8341
8342 ; fadd, but rounding towards zero.
8343 ; This is probably not the optimal code sequence.
8344 (define_insn "fix_trunc_helper"
8345 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
8346 (unspec:DF [(match_operand:TF 1 "gpc_reg_operand" "d")]
8347 UNSPEC_FIX_TRUNC_TF))
8348 (clobber (match_operand:DF 2 "gpc_reg_operand" "=&d"))]
8349 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
8350 "mffs %2\n\tmtfsb1 31\n\tmtfsb0 30\n\tfadd %0,%1,%L1\n\tmtfsf 1,%2"
8351 [(set_attr "type" "fp")
8352 (set_attr "length" "20")])
8353
8354 (define_expand "fix_trunctfsi2"
8355 [(set (match_operand:SI 0 "gpc_reg_operand" "")
8356 (fix:SI (match_operand:TF 1 "gpc_reg_operand" "")))]
8357 "!TARGET_IEEEQUAD && TARGET_HARD_FLOAT
8358 && (TARGET_FPRS || TARGET_E500_DOUBLE) && TARGET_LONG_DOUBLE_128"
8359 {
8360 if (TARGET_E500_DOUBLE)
8361 emit_insn (gen_spe_fix_trunctfsi2 (operands[0], operands[1]));
8362 else
8363 emit_insn (gen_fix_trunctfsi2_fprs (operands[0], operands[1]));
8364 DONE;
8365 })
8366
8367 (define_expand "fix_trunctfsi2_fprs"
8368 [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "")
8369 (fix:SI (match_operand:TF 1 "gpc_reg_operand" "")))
8370 (clobber (match_dup 2))
8371 (clobber (match_dup 3))
8372 (clobber (match_dup 4))
8373 (clobber (match_dup 5))])]
8374 "!TARGET_IEEEQUAD
8375 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
8376 {
8377 operands[2] = gen_reg_rtx (DFmode);
8378 operands[3] = gen_reg_rtx (DFmode);
8379 operands[4] = gen_reg_rtx (DImode);
8380 operands[5] = assign_stack_temp (DImode, GET_MODE_SIZE (DImode));
8381 })
8382
8383 (define_insn_and_split "*fix_trunctfsi2_internal"
8384 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
8385 (fix:SI (match_operand:TF 1 "gpc_reg_operand" "d")))
8386 (clobber (match_operand:DF 2 "gpc_reg_operand" "=d"))
8387 (clobber (match_operand:DF 3 "gpc_reg_operand" "=&d"))
8388 (clobber (match_operand:DI 4 "gpc_reg_operand" "=d"))
8389 (clobber (match_operand:DI 5 "offsettable_mem_operand" "=o"))]
8390 "!TARGET_IEEEQUAD
8391 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
8392 "#"
8393 ""
8394 [(pc)]
8395 {
8396 rtx lowword;
8397 emit_insn (gen_fix_trunc_helper (operands[2], operands[1], operands[3]));
8398
8399 gcc_assert (MEM_P (operands[5]));
8400 lowword = adjust_address (operands[5], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
8401
8402 emit_insn (gen_fctiwz_df (operands[4], operands[2]));
8403 emit_move_insn (operands[5], operands[4]);
8404 emit_move_insn (operands[0], lowword);
8405 DONE;
8406 })
8407
8408 (define_expand "negtf2"
8409 [(set (match_operand:TF 0 "gpc_reg_operand" "")
8410 (neg:TF (match_operand:TF 1 "gpc_reg_operand" "")))]
8411 "!TARGET_IEEEQUAD
8412 && TARGET_HARD_FLOAT
8413 && (TARGET_FPRS || TARGET_E500_DOUBLE)
8414 && TARGET_LONG_DOUBLE_128"
8415 "")
8416
8417 (define_insn "negtf2_internal"
8418 [(set (match_operand:TF 0 "gpc_reg_operand" "=d")
8419 (neg:TF (match_operand:TF 1 "gpc_reg_operand" "d")))]
8420 "!TARGET_IEEEQUAD
8421 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
8422 "*
8423 {
8424 if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
8425 return \"fneg %L0,%L1\;fneg %0,%1\";
8426 else
8427 return \"fneg %0,%1\;fneg %L0,%L1\";
8428 }"
8429 [(set_attr "type" "fp")
8430 (set_attr "length" "8")])
8431
8432 (define_expand "abstf2"
8433 [(set (match_operand:TF 0 "gpc_reg_operand" "")
8434 (abs:TF (match_operand:TF 1 "gpc_reg_operand" "")))]
8435 "!TARGET_IEEEQUAD
8436 && TARGET_HARD_FLOAT
8437 && (TARGET_FPRS || TARGET_E500_DOUBLE)
8438 && TARGET_LONG_DOUBLE_128"
8439 "
8440 {
8441 rtx label = gen_label_rtx ();
8442 if (TARGET_E500_DOUBLE)
8443 {
8444 if (flag_finite_math_only && !flag_trapping_math)
8445 emit_insn (gen_spe_abstf2_tst (operands[0], operands[1], label));
8446 else
8447 emit_insn (gen_spe_abstf2_cmp (operands[0], operands[1], label));
8448 }
8449 else
8450 emit_insn (gen_abstf2_internal (operands[0], operands[1], label));
8451 emit_label (label);
8452 DONE;
8453 }")
8454
8455 (define_expand "abstf2_internal"
8456 [(set (match_operand:TF 0 "gpc_reg_operand" "")
8457 (match_operand:TF 1 "gpc_reg_operand" ""))
8458 (set (match_dup 3) (match_dup 5))
8459 (set (match_dup 5) (abs:DF (match_dup 5)))
8460 (set (match_dup 4) (compare:CCFP (match_dup 3) (match_dup 5)))
8461 (set (pc) (if_then_else (eq (match_dup 4) (const_int 0))
8462 (label_ref (match_operand 2 "" ""))
8463 (pc)))
8464 (set (match_dup 6) (neg:DF (match_dup 6)))]
8465 "!TARGET_IEEEQUAD
8466 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
8467 && TARGET_LONG_DOUBLE_128"
8468 "
8469 {
8470 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
8471 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
8472 operands[3] = gen_reg_rtx (DFmode);
8473 operands[4] = gen_reg_rtx (CCFPmode);
8474 operands[5] = simplify_gen_subreg (DFmode, operands[0], TFmode, hi_word);
8475 operands[6] = simplify_gen_subreg (DFmode, operands[0], TFmode, lo_word);
8476 }")
8477 \f
8478 ;; Reload helper functions used by rs6000_secondary_reload. The patterns all
8479 ;; must have 3 arguments, and scratch register constraint must be a single
8480 ;; constraint.
8481
8482 ;; Reload patterns to support gpr load/store with misaligned mem.
8483 ;; and multiple gpr load/store at offset >= 0xfffc
8484 (define_expand "reload_<mode>_store"
8485 [(parallel [(match_operand 0 "memory_operand" "=m")
8486 (match_operand 1 "gpc_reg_operand" "r")
8487 (match_operand:GPR 2 "register_operand" "=&b")])]
8488 ""
8489 {
8490 rs6000_secondary_reload_gpr (operands[1], operands[0], operands[2], true);
8491 DONE;
8492 })
8493
8494 (define_expand "reload_<mode>_load"
8495 [(parallel [(match_operand 0 "gpc_reg_operand" "=r")
8496 (match_operand 1 "memory_operand" "m")
8497 (match_operand:GPR 2 "register_operand" "=b")])]
8498 ""
8499 {
8500 rs6000_secondary_reload_gpr (operands[0], operands[1], operands[2], false);
8501 DONE;
8502 })
8503
8504 \f
8505 ;; Power8 merge instructions to allow direct move to/from floating point
8506 ;; registers in 32-bit mode. We use TF mode to get two registers to move the
8507 ;; individual 32-bit parts across. Subreg doesn't work too well on the TF
8508 ;; value, since it is allocated in reload and not all of the flow information
8509 ;; is setup for it. We have two patterns to do the two moves between gprs and
8510 ;; fprs. There isn't a dependancy between the two, but we could potentially
8511 ;; schedule other instructions between the two instructions. TFmode is
8512 ;; currently limited to traditional FPR registers. If/when this is changed, we
8513 ;; will need to revist %L to make sure it works with VSX registers, or add an
8514 ;; %x version of %L.
8515
8516 (define_insn "p8_fmrgow_<mode>"
8517 [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
8518 (unspec:FMOVE64X [(match_operand:TF 1 "register_operand" "d")]
8519 UNSPEC_P8V_FMRGOW))]
8520 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8521 "fmrgow %0,%1,%L1"
8522 [(set_attr "type" "vecperm")])
8523
8524 (define_insn "p8_mtvsrwz_1"
8525 [(set (match_operand:TF 0 "register_operand" "=d")
8526 (unspec:TF [(match_operand:SI 1 "register_operand" "r")]
8527 UNSPEC_P8V_MTVSRWZ))]
8528 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8529 "mtvsrwz %x0,%1"
8530 [(set_attr "type" "mftgpr")])
8531
8532 (define_insn "p8_mtvsrwz_2"
8533 [(set (match_operand:TF 0 "register_operand" "+d")
8534 (unspec:TF [(match_dup 0)
8535 (match_operand:SI 1 "register_operand" "r")]
8536 UNSPEC_P8V_MTVSRWZ))]
8537 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8538 "mtvsrwz %L0,%1"
8539 [(set_attr "type" "mftgpr")])
8540
8541 (define_insn_and_split "reload_fpr_from_gpr<mode>"
8542 [(set (match_operand:FMOVE64X 0 "register_operand" "=ws")
8543 (unspec:FMOVE64X [(match_operand:FMOVE64X 1 "register_operand" "r")]
8544 UNSPEC_P8V_RELOAD_FROM_GPR))
8545 (clobber (match_operand:TF 2 "register_operand" "=d"))]
8546 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8547 "#"
8548 "&& reload_completed"
8549 [(const_int 0)]
8550 {
8551 rtx dest = operands[0];
8552 rtx src = operands[1];
8553 rtx tmp = operands[2];
8554 rtx gpr_hi_reg = gen_highpart (SImode, src);
8555 rtx gpr_lo_reg = gen_lowpart (SImode, src);
8556
8557 emit_insn (gen_p8_mtvsrwz_1 (tmp, gpr_hi_reg));
8558 emit_insn (gen_p8_mtvsrwz_2 (tmp, gpr_lo_reg));
8559 emit_insn (gen_p8_fmrgow_<mode> (dest, tmp));
8560 DONE;
8561 }
8562 [(set_attr "length" "12")
8563 (set_attr "type" "three")])
8564
8565 ;; Move 128 bit values from GPRs to VSX registers in 64-bit mode
8566 (define_insn "p8_mtvsrd_1"
8567 [(set (match_operand:TF 0 "register_operand" "=ws")
8568 (unspec:TF [(match_operand:DI 1 "register_operand" "r")]
8569 UNSPEC_P8V_MTVSRD))]
8570 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8571 "mtvsrd %0,%1"
8572 [(set_attr "type" "mftgpr")])
8573
8574 (define_insn "p8_mtvsrd_2"
8575 [(set (match_operand:TF 0 "register_operand" "+ws")
8576 (unspec:TF [(match_dup 0)
8577 (match_operand:DI 1 "register_operand" "r")]
8578 UNSPEC_P8V_MTVSRD))]
8579 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8580 "mtvsrd %L0,%1"
8581 [(set_attr "type" "mftgpr")])
8582
8583 (define_insn "p8_xxpermdi_<mode>"
8584 [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
8585 (unspec:FMOVE128_GPR [(match_operand:TF 1 "register_operand" "ws")]
8586 UNSPEC_P8V_XXPERMDI))]
8587 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8588 "xxpermdi %x0,%1,%L1,0"
8589 [(set_attr "type" "vecperm")])
8590
8591 (define_insn_and_split "reload_vsx_from_gpr<mode>"
8592 [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
8593 (unspec:FMOVE128_GPR
8594 [(match_operand:FMOVE128_GPR 1 "register_operand" "r")]
8595 UNSPEC_P8V_RELOAD_FROM_GPR))
8596 (clobber (match_operand:TF 2 "register_operand" "=ws"))]
8597 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8598 "#"
8599 "&& reload_completed"
8600 [(const_int 0)]
8601 {
8602 rtx dest = operands[0];
8603 rtx src = operands[1];
8604 rtx tmp = operands[2];
8605 rtx gpr_hi_reg = gen_highpart (DImode, src);
8606 rtx gpr_lo_reg = gen_lowpart (DImode, src);
8607
8608 emit_insn (gen_p8_mtvsrd_1 (tmp, gpr_hi_reg));
8609 emit_insn (gen_p8_mtvsrd_2 (tmp, gpr_lo_reg));
8610 emit_insn (gen_p8_xxpermdi_<mode> (dest, tmp));
8611 }
8612 [(set_attr "length" "12")
8613 (set_attr "type" "three")])
8614
8615 (define_split
8616 [(set (match_operand:FMOVE128_GPR 0 "nonimmediate_operand" "")
8617 (match_operand:FMOVE128_GPR 1 "input_operand" ""))]
8618 "reload_completed
8619 && (int_reg_operand (operands[0], <MODE>mode)
8620 || int_reg_operand (operands[1], <MODE>mode))"
8621 [(pc)]
8622 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
8623
8624 ;; Move SFmode to a VSX from a GPR register. Because scalar floating point
8625 ;; type is stored internally as double precision in the VSX registers, we have
8626 ;; to convert it from the vector format.
8627
8628 (define_insn_and_split "reload_vsx_from_gprsf"
8629 [(set (match_operand:SF 0 "register_operand" "=wa")
8630 (unspec:SF [(match_operand:SF 1 "register_operand" "r")]
8631 UNSPEC_P8V_RELOAD_FROM_GPR))
8632 (clobber (match_operand:DI 2 "register_operand" "=r"))]
8633 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8634 "#"
8635 "&& reload_completed"
8636 [(const_int 0)]
8637 {
8638 rtx op0 = operands[0];
8639 rtx op1 = operands[1];
8640 rtx op2 = operands[2];
8641 /* Also use the destination register to hold the unconverted DImode value.
8642 This is conceptually a separate value from OP0, so we use gen_rtx_REG
8643 rather than simplify_gen_subreg. */
8644 rtx op0_di = gen_rtx_REG (DImode, REGNO (op0));
8645 rtx op1_di = simplify_gen_subreg (DImode, op1, SFmode, 0);
8646
8647 /* Move SF value to upper 32-bits for xscvspdpn. */
8648 emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32)));
8649 emit_move_insn (op0_di, op2);
8650 emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0_di));
8651 DONE;
8652 }
8653 [(set_attr "length" "8")
8654 (set_attr "type" "two")])
8655
8656 ;; Move 128 bit values from VSX registers to GPRs in 64-bit mode by doing a
8657 ;; normal 64-bit move, followed by an xxpermdi to get the bottom 64-bit value,
8658 ;; and then doing a move of that.
8659 (define_insn "p8_mfvsrd_3_<mode>"
8660 [(set (match_operand:DF 0 "register_operand" "=r")
8661 (unspec:DF [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
8662 UNSPEC_P8V_RELOAD_FROM_VSX))]
8663 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8664 "mfvsrd %0,%x1"
8665 [(set_attr "type" "mftgpr")])
8666
8667 (define_insn_and_split "reload_gpr_from_vsx<mode>"
8668 [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=r")
8669 (unspec:FMOVE128_GPR
8670 [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
8671 UNSPEC_P8V_RELOAD_FROM_VSX))
8672 (clobber (match_operand:FMOVE128_GPR 2 "register_operand" "=wa"))]
8673 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8674 "#"
8675 "&& reload_completed"
8676 [(const_int 0)]
8677 {
8678 rtx dest = operands[0];
8679 rtx src = operands[1];
8680 rtx tmp = operands[2];
8681 rtx gpr_hi_reg = gen_highpart (DFmode, dest);
8682 rtx gpr_lo_reg = gen_lowpart (DFmode, dest);
8683
8684 emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_hi_reg, src));
8685 emit_insn (gen_vsx_xxpermdi_<mode> (tmp, src, src, GEN_INT (3)));
8686 emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_lo_reg, tmp));
8687 }
8688 [(set_attr "length" "12")
8689 (set_attr "type" "three")])
8690
8691 ;; Move SFmode to a GPR from a VSX register. Because scalar floating point
8692 ;; type is stored internally as double precision, we have to convert it to the
8693 ;; vector format.
8694
8695 (define_insn_and_split "reload_gpr_from_vsxsf"
8696 [(set (match_operand:SF 0 "register_operand" "=r")
8697 (unspec:SF [(match_operand:SF 1 "register_operand" "wa")]
8698 UNSPEC_P8V_RELOAD_FROM_VSX))
8699 (clobber (match_operand:V4SF 2 "register_operand" "=wa"))]
8700 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8701 "#"
8702 "&& reload_completed"
8703 [(const_int 0)]
8704 {
8705 rtx op0 = operands[0];
8706 rtx op1 = operands[1];
8707 rtx op2 = operands[2];
8708 rtx diop0 = simplify_gen_subreg (DImode, op0, SFmode, 0);
8709
8710 emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
8711 emit_insn (gen_p8_mfvsrd_4_disf (diop0, op2));
8712 emit_insn (gen_lshrdi3 (diop0, diop0, GEN_INT (32)));
8713 DONE;
8714 }
8715 [(set_attr "length" "12")
8716 (set_attr "type" "three")])
8717
8718 (define_insn "p8_mfvsrd_4_disf"
8719 [(set (match_operand:DI 0 "register_operand" "=r")
8720 (unspec:DI [(match_operand:V4SF 1 "register_operand" "wa")]
8721 UNSPEC_P8V_RELOAD_FROM_VSX))]
8722 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8723 "mfvsrd %0,%x1"
8724 [(set_attr "type" "mftgpr")])
8725
8726 \f
8727 ;; Next come the multi-word integer load and store and the load and store
8728 ;; multiple insns.
8729
8730 ;; List r->r after r->Y, otherwise reload will try to reload a
8731 ;; non-offsettable address by using r->r which won't make progress.
8732 ;; Use of fprs is disparaged slightly otherwise reload prefers to reload
8733 ;; a gpr into a fpr instead of reloading an invalid 'Y' address
8734 (define_insn "*movdi_internal32"
8735 [(set (match_operand:DI 0 "rs6000_nonimmediate_operand" "=Y,r,r,?m,?*d,?*d,r")
8736 (match_operand:DI 1 "input_operand" "r,Y,r,d,m,d,IJKnGHF"))]
8737 "! TARGET_POWERPC64
8738 && (gpc_reg_operand (operands[0], DImode)
8739 || gpc_reg_operand (operands[1], DImode))"
8740 "@
8741 #
8742 #
8743 #
8744 stfd%U0%X0 %1,%0
8745 lfd%U1%X1 %0,%1
8746 fmr %0,%1
8747 #"
8748 [(set_attr "type" "store,load,*,fpstore,fpload,fp,*")])
8749
8750 (define_split
8751 [(set (match_operand:DI 0 "gpc_reg_operand" "")
8752 (match_operand:DI 1 "const_int_operand" ""))]
8753 "! TARGET_POWERPC64 && reload_completed
8754 && gpr_or_gpr_p (operands[0], operands[1])
8755 && !direct_move_p (operands[0], operands[1])"
8756 [(set (match_dup 2) (match_dup 4))
8757 (set (match_dup 3) (match_dup 1))]
8758 "
8759 {
8760 HOST_WIDE_INT value = INTVAL (operands[1]);
8761 operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
8762 DImode);
8763 operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
8764 DImode);
8765 operands[4] = GEN_INT (value >> 32);
8766 operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
8767 }")
8768
8769 (define_split
8770 [(set (match_operand:DIFD 0 "rs6000_nonimmediate_operand" "")
8771 (match_operand:DIFD 1 "input_operand" ""))]
8772 "reload_completed && !TARGET_POWERPC64
8773 && gpr_or_gpr_p (operands[0], operands[1])
8774 && !direct_move_p (operands[0], operands[1])"
8775 [(pc)]
8776 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
8777
8778 (define_insn "*movdi_internal64"
8779 [(set (match_operand:DI 0 "nonimmediate_operand" "=Y,r,r,r,r,r,?m,?*d,?*d,r,*h,*h,r,?*wg,r,?*wj,?*wi")
8780 (match_operand:DI 1 "input_operand" "r,Y,r,I,L,nF,d,m,d,*h,r,0,*wg,r,*wj,r,O"))]
8781 "TARGET_POWERPC64
8782 && (gpc_reg_operand (operands[0], DImode)
8783 || gpc_reg_operand (operands[1], DImode))"
8784 "@
8785 std%U0%X0 %1,%0
8786 ld%U1%X1 %0,%1
8787 mr %0,%1
8788 li %0,%1
8789 lis %0,%v1
8790 #
8791 stfd%U0%X0 %1,%0
8792 lfd%U1%X1 %0,%1
8793 fmr %0,%1
8794 mf%1 %0
8795 mt%0 %1
8796 nop
8797 mftgpr %0,%1
8798 mffgpr %0,%1
8799 mfvsrd %0,%x1
8800 mtvsrd %x0,%1
8801 xxlxor %x0,%x0,%x0"
8802 [(set_attr "type" "store,load,*,*,*,*,fpstore,fpload,fp,mfjmpr,mtjmpr,*,mftgpr,mffgpr,mftgpr,mffgpr,vecsimple")
8803 (set_attr "length" "4,4,4,4,4,20,4,4,4,4,4,4,4,4,4,4,4")])
8804
8805 ;; Generate all one-bits and clear left or right.
8806 ;; Use (and:DI (rotate:DI ...)) to avoid anddi3 unnecessary clobber.
8807 (define_split
8808 [(set (match_operand:DI 0 "gpc_reg_operand" "")
8809 (match_operand:DI 1 "mask64_operand" ""))]
8810 "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
8811 [(set (match_dup 0) (const_int -1))
8812 (set (match_dup 0)
8813 (and:DI (rotate:DI (match_dup 0)
8814 (const_int 0))
8815 (match_dup 1)))]
8816 "")
8817
8818 ;; Split a load of a large constant into the appropriate five-instruction
8819 ;; sequence. Handle anything in a constant number of insns.
8820 ;; When non-easy constants can go in the TOC, this should use
8821 ;; easy_fp_constant predicate.
8822 (define_split
8823 [(set (match_operand:DI 0 "gpc_reg_operand" "")
8824 (match_operand:DI 1 "const_int_operand" ""))]
8825 "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
8826 [(set (match_dup 0) (match_dup 2))
8827 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
8828 "
8829 {
8830 if (rs6000_emit_set_const (operands[0], operands[1]))
8831 DONE;
8832 else
8833 FAIL;
8834 }")
8835
8836 (define_split
8837 [(set (match_operand:DI 0 "gpc_reg_operand" "")
8838 (match_operand:DI 1 "const_scalar_int_operand" ""))]
8839 "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
8840 [(set (match_dup 0) (match_dup 2))
8841 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
8842 "
8843 {
8844 if (rs6000_emit_set_const (operands[0], operands[1]))
8845 DONE;
8846 else
8847 FAIL;
8848 }")
8849 \f
8850 ;; TImode/PTImode is similar, except that we usually want to compute the
8851 ;; address into a register and use lsi/stsi (the exception is during reload).
8852
8853 (define_insn "*mov<mode>_string"
8854 [(set (match_operand:TI2 0 "reg_or_mem_operand" "=Q,Y,????r,????r,????r,r")
8855 (match_operand:TI2 1 "input_operand" "r,r,Q,Y,r,n"))]
8856 "! TARGET_POWERPC64
8857 && (<MODE>mode != TImode || VECTOR_MEM_NONE_P (TImode))
8858 && (gpc_reg_operand (operands[0], <MODE>mode)
8859 || gpc_reg_operand (operands[1], <MODE>mode))"
8860 "*
8861 {
8862 switch (which_alternative)
8863 {
8864 default:
8865 gcc_unreachable ();
8866 case 0:
8867 if (TARGET_STRING)
8868 return \"stswi %1,%P0,16\";
8869 case 1:
8870 return \"#\";
8871 case 2:
8872 /* If the address is not used in the output, we can use lsi. Otherwise,
8873 fall through to generating four loads. */
8874 if (TARGET_STRING
8875 && ! reg_overlap_mentioned_p (operands[0], operands[1]))
8876 return \"lswi %0,%P1,16\";
8877 /* ... fall through ... */
8878 case 3:
8879 case 4:
8880 case 5:
8881 return \"#\";
8882 }
8883 }"
8884 [(set_attr "type" "store,store,load,load,*,*")
8885 (set_attr "update" "yes")
8886 (set_attr "indexed" "yes")
8887 (set (attr "cell_micro") (if_then_else (match_test "TARGET_STRING")
8888 (const_string "always")
8889 (const_string "conditional")))])
8890
8891 (define_insn "*mov<mode>_ppc64"
8892 [(set (match_operand:TI2 0 "nonimmediate_operand" "=wQ,Y,r,r,r,r")
8893 (match_operand:TI2 1 "input_operand" "r,r,wQ,Y,r,n"))]
8894 "(TARGET_POWERPC64 && VECTOR_MEM_NONE_P (<MODE>mode)
8895 && (gpc_reg_operand (operands[0], <MODE>mode)
8896 || gpc_reg_operand (operands[1], <MODE>mode)))"
8897 {
8898 return rs6000_output_move_128bit (operands);
8899 }
8900 [(set_attr "type" "store,store,load,load,*,*")
8901 (set_attr "length" "8")])
8902
8903 (define_split
8904 [(set (match_operand:TI2 0 "int_reg_operand" "")
8905 (match_operand:TI2 1 "const_scalar_int_operand" ""))]
8906 "TARGET_POWERPC64
8907 && (VECTOR_MEM_NONE_P (<MODE>mode)
8908 || (reload_completed && INT_REGNO_P (REGNO (operands[0]))))"
8909 [(set (match_dup 2) (match_dup 4))
8910 (set (match_dup 3) (match_dup 5))]
8911 "
8912 {
8913 operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
8914 <MODE>mode);
8915 operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
8916 <MODE>mode);
8917 if (CONST_WIDE_INT_P (operands[1]))
8918 {
8919 operands[4] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 1));
8920 operands[5] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 0));
8921 }
8922 else if (CONST_INT_P (operands[1]))
8923 {
8924 operands[4] = GEN_INT (- (INTVAL (operands[1]) < 0));
8925 operands[5] = operands[1];
8926 }
8927 else
8928 FAIL;
8929 }")
8930
8931 (define_split
8932 [(set (match_operand:TI2 0 "nonimmediate_operand" "")
8933 (match_operand:TI2 1 "input_operand" ""))]
8934 "reload_completed
8935 && gpr_or_gpr_p (operands[0], operands[1])
8936 && !direct_move_p (operands[0], operands[1])
8937 && !quad_load_store_p (operands[0], operands[1])"
8938 [(pc)]
8939 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
8940 \f
8941 (define_expand "load_multiple"
8942 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
8943 (match_operand:SI 1 "" ""))
8944 (use (match_operand:SI 2 "" ""))])]
8945 "TARGET_STRING && !TARGET_POWERPC64"
8946 "
8947 {
8948 int regno;
8949 int count;
8950 rtx op1;
8951 int i;
8952
8953 /* Support only loading a constant number of fixed-point registers from
8954 memory and only bother with this if more than two; the machine
8955 doesn't support more than eight. */
8956 if (GET_CODE (operands[2]) != CONST_INT
8957 || INTVAL (operands[2]) <= 2
8958 || INTVAL (operands[2]) > 8
8959 || GET_CODE (operands[1]) != MEM
8960 || GET_CODE (operands[0]) != REG
8961 || REGNO (operands[0]) >= 32)
8962 FAIL;
8963
8964 count = INTVAL (operands[2]);
8965 regno = REGNO (operands[0]);
8966
8967 operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
8968 op1 = replace_equiv_address (operands[1],
8969 force_reg (SImode, XEXP (operands[1], 0)));
8970
8971 for (i = 0; i < count; i++)
8972 XVECEXP (operands[3], 0, i)
8973 = gen_rtx_SET (VOIDmode, gen_rtx_REG (SImode, regno + i),
8974 adjust_address_nv (op1, SImode, i * 4));
8975 }")
8976
8977 (define_insn "*ldmsi8"
8978 [(match_parallel 0 "load_multiple_operation"
8979 [(set (match_operand:SI 2 "gpc_reg_operand" "")
8980 (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8981 (set (match_operand:SI 3 "gpc_reg_operand" "")
8982 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8983 (set (match_operand:SI 4 "gpc_reg_operand" "")
8984 (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8985 (set (match_operand:SI 5 "gpc_reg_operand" "")
8986 (mem:SI (plus:SI (match_dup 1) (const_int 12))))
8987 (set (match_operand:SI 6 "gpc_reg_operand" "")
8988 (mem:SI (plus:SI (match_dup 1) (const_int 16))))
8989 (set (match_operand:SI 7 "gpc_reg_operand" "")
8990 (mem:SI (plus:SI (match_dup 1) (const_int 20))))
8991 (set (match_operand:SI 8 "gpc_reg_operand" "")
8992 (mem:SI (plus:SI (match_dup 1) (const_int 24))))
8993 (set (match_operand:SI 9 "gpc_reg_operand" "")
8994 (mem:SI (plus:SI (match_dup 1) (const_int 28))))])]
8995 "TARGET_STRING && XVECLEN (operands[0], 0) == 8"
8996 "*
8997 { return rs6000_output_load_multiple (operands); }"
8998 [(set_attr "type" "load")
8999 (set_attr "update" "yes")
9000 (set_attr "indexed" "yes")
9001 (set_attr "length" "32")])
9002
9003 (define_insn "*ldmsi7"
9004 [(match_parallel 0 "load_multiple_operation"
9005 [(set (match_operand:SI 2 "gpc_reg_operand" "")
9006 (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
9007 (set (match_operand:SI 3 "gpc_reg_operand" "")
9008 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
9009 (set (match_operand:SI 4 "gpc_reg_operand" "")
9010 (mem:SI (plus:SI (match_dup 1) (const_int 8))))
9011 (set (match_operand:SI 5 "gpc_reg_operand" "")
9012 (mem:SI (plus:SI (match_dup 1) (const_int 12))))
9013 (set (match_operand:SI 6 "gpc_reg_operand" "")
9014 (mem:SI (plus:SI (match_dup 1) (const_int 16))))
9015 (set (match_operand:SI 7 "gpc_reg_operand" "")
9016 (mem:SI (plus:SI (match_dup 1) (const_int 20))))
9017 (set (match_operand:SI 8 "gpc_reg_operand" "")
9018 (mem:SI (plus:SI (match_dup 1) (const_int 24))))])]
9019 "TARGET_STRING && XVECLEN (operands[0], 0) == 7"
9020 "*
9021 { return rs6000_output_load_multiple (operands); }"
9022 [(set_attr "type" "load")
9023 (set_attr "update" "yes")
9024 (set_attr "indexed" "yes")
9025 (set_attr "length" "32")])
9026
9027 (define_insn "*ldmsi6"
9028 [(match_parallel 0 "load_multiple_operation"
9029 [(set (match_operand:SI 2 "gpc_reg_operand" "")
9030 (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
9031 (set (match_operand:SI 3 "gpc_reg_operand" "")
9032 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
9033 (set (match_operand:SI 4 "gpc_reg_operand" "")
9034 (mem:SI (plus:SI (match_dup 1) (const_int 8))))
9035 (set (match_operand:SI 5 "gpc_reg_operand" "")
9036 (mem:SI (plus:SI (match_dup 1) (const_int 12))))
9037 (set (match_operand:SI 6 "gpc_reg_operand" "")
9038 (mem:SI (plus:SI (match_dup 1) (const_int 16))))
9039 (set (match_operand:SI 7 "gpc_reg_operand" "")
9040 (mem:SI (plus:SI (match_dup 1) (const_int 20))))])]
9041 "TARGET_STRING && XVECLEN (operands[0], 0) == 6"
9042 "*
9043 { return rs6000_output_load_multiple (operands); }"
9044 [(set_attr "type" "load")
9045 (set_attr "update" "yes")
9046 (set_attr "indexed" "yes")
9047 (set_attr "length" "32")])
9048
9049 (define_insn "*ldmsi5"
9050 [(match_parallel 0 "load_multiple_operation"
9051 [(set (match_operand:SI 2 "gpc_reg_operand" "")
9052 (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
9053 (set (match_operand:SI 3 "gpc_reg_operand" "")
9054 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
9055 (set (match_operand:SI 4 "gpc_reg_operand" "")
9056 (mem:SI (plus:SI (match_dup 1) (const_int 8))))
9057 (set (match_operand:SI 5 "gpc_reg_operand" "")
9058 (mem:SI (plus:SI (match_dup 1) (const_int 12))))
9059 (set (match_operand:SI 6 "gpc_reg_operand" "")
9060 (mem:SI (plus:SI (match_dup 1) (const_int 16))))])]
9061 "TARGET_STRING && XVECLEN (operands[0], 0) == 5"
9062 "*
9063 { return rs6000_output_load_multiple (operands); }"
9064 [(set_attr "type" "load")
9065 (set_attr "update" "yes")
9066 (set_attr "indexed" "yes")
9067 (set_attr "length" "32")])
9068
9069 (define_insn "*ldmsi4"
9070 [(match_parallel 0 "load_multiple_operation"
9071 [(set (match_operand:SI 2 "gpc_reg_operand" "")
9072 (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
9073 (set (match_operand:SI 3 "gpc_reg_operand" "")
9074 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
9075 (set (match_operand:SI 4 "gpc_reg_operand" "")
9076 (mem:SI (plus:SI (match_dup 1) (const_int 8))))
9077 (set (match_operand:SI 5 "gpc_reg_operand" "")
9078 (mem:SI (plus:SI (match_dup 1) (const_int 12))))])]
9079 "TARGET_STRING && XVECLEN (operands[0], 0) == 4"
9080 "*
9081 { return rs6000_output_load_multiple (operands); }"
9082 [(set_attr "type" "load")
9083 (set_attr "update" "yes")
9084 (set_attr "indexed" "yes")
9085 (set_attr "length" "32")])
9086
9087 (define_insn "*ldmsi3"
9088 [(match_parallel 0 "load_multiple_operation"
9089 [(set (match_operand:SI 2 "gpc_reg_operand" "")
9090 (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
9091 (set (match_operand:SI 3 "gpc_reg_operand" "")
9092 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
9093 (set (match_operand:SI 4 "gpc_reg_operand" "")
9094 (mem:SI (plus:SI (match_dup 1) (const_int 8))))])]
9095 "TARGET_STRING && XVECLEN (operands[0], 0) == 3"
9096 "*
9097 { return rs6000_output_load_multiple (operands); }"
9098 [(set_attr "type" "load")
9099 (set_attr "update" "yes")
9100 (set_attr "indexed" "yes")
9101 (set_attr "length" "32")])
9102
9103 (define_expand "store_multiple"
9104 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
9105 (match_operand:SI 1 "" ""))
9106 (clobber (scratch:SI))
9107 (use (match_operand:SI 2 "" ""))])]
9108 "TARGET_STRING && !TARGET_POWERPC64"
9109 "
9110 {
9111 int regno;
9112 int count;
9113 rtx to;
9114 rtx op0;
9115 int i;
9116
9117 /* Support only storing a constant number of fixed-point registers to
9118 memory and only bother with this if more than two; the machine
9119 doesn't support more than eight. */
9120 if (GET_CODE (operands[2]) != CONST_INT
9121 || INTVAL (operands[2]) <= 2
9122 || INTVAL (operands[2]) > 8
9123 || GET_CODE (operands[0]) != MEM
9124 || GET_CODE (operands[1]) != REG
9125 || REGNO (operands[1]) >= 32)
9126 FAIL;
9127
9128 count = INTVAL (operands[2]);
9129 regno = REGNO (operands[1]);
9130
9131 operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count + 1));
9132 to = force_reg (SImode, XEXP (operands[0], 0));
9133 op0 = replace_equiv_address (operands[0], to);
9134
9135 XVECEXP (operands[3], 0, 0)
9136 = gen_rtx_SET (VOIDmode, adjust_address_nv (op0, SImode, 0), operands[1]);
9137 XVECEXP (operands[3], 0, 1) = gen_rtx_CLOBBER (VOIDmode,
9138 gen_rtx_SCRATCH (SImode));
9139
9140 for (i = 1; i < count; i++)
9141 XVECEXP (operands[3], 0, i + 1)
9142 = gen_rtx_SET (VOIDmode,
9143 adjust_address_nv (op0, SImode, i * 4),
9144 gen_rtx_REG (SImode, regno + i));
9145 }")
9146
9147 (define_insn "*stmsi8"
9148 [(match_parallel 0 "store_multiple_operation"
9149 [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
9150 (match_operand:SI 2 "gpc_reg_operand" "r"))
9151 (clobber (match_scratch:SI 3 "=X"))
9152 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
9153 (match_operand:SI 4 "gpc_reg_operand" "r"))
9154 (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
9155 (match_operand:SI 5 "gpc_reg_operand" "r"))
9156 (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
9157 (match_operand:SI 6 "gpc_reg_operand" "r"))
9158 (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
9159 (match_operand:SI 7 "gpc_reg_operand" "r"))
9160 (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
9161 (match_operand:SI 8 "gpc_reg_operand" "r"))
9162 (set (mem:SI (plus:SI (match_dup 1) (const_int 24)))
9163 (match_operand:SI 9 "gpc_reg_operand" "r"))
9164 (set (mem:SI (plus:SI (match_dup 1) (const_int 28)))
9165 (match_operand:SI 10 "gpc_reg_operand" "r"))])]
9166 "TARGET_STRING && XVECLEN (operands[0], 0) == 9"
9167 "stswi %2,%1,%O0"
9168 [(set_attr "type" "store")
9169 (set_attr "update" "yes")
9170 (set_attr "indexed" "yes")
9171 (set_attr "cell_micro" "always")])
9172
9173 (define_insn "*stmsi7"
9174 [(match_parallel 0 "store_multiple_operation"
9175 [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
9176 (match_operand:SI 2 "gpc_reg_operand" "r"))
9177 (clobber (match_scratch:SI 3 "=X"))
9178 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
9179 (match_operand:SI 4 "gpc_reg_operand" "r"))
9180 (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
9181 (match_operand:SI 5 "gpc_reg_operand" "r"))
9182 (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
9183 (match_operand:SI 6 "gpc_reg_operand" "r"))
9184 (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
9185 (match_operand:SI 7 "gpc_reg_operand" "r"))
9186 (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
9187 (match_operand:SI 8 "gpc_reg_operand" "r"))
9188 (set (mem:SI (plus:SI (match_dup 1) (const_int 24)))
9189 (match_operand:SI 9 "gpc_reg_operand" "r"))])]
9190 "TARGET_STRING && XVECLEN (operands[0], 0) == 8"
9191 "stswi %2,%1,%O0"
9192 [(set_attr "type" "store")
9193 (set_attr "update" "yes")
9194 (set_attr "indexed" "yes")
9195 (set_attr "cell_micro" "always")])
9196
9197 (define_insn "*stmsi6"
9198 [(match_parallel 0 "store_multiple_operation"
9199 [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
9200 (match_operand:SI 2 "gpc_reg_operand" "r"))
9201 (clobber (match_scratch:SI 3 "=X"))
9202 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
9203 (match_operand:SI 4 "gpc_reg_operand" "r"))
9204 (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
9205 (match_operand:SI 5 "gpc_reg_operand" "r"))
9206 (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
9207 (match_operand:SI 6 "gpc_reg_operand" "r"))
9208 (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
9209 (match_operand:SI 7 "gpc_reg_operand" "r"))
9210 (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
9211 (match_operand:SI 8 "gpc_reg_operand" "r"))])]
9212 "TARGET_STRING && XVECLEN (operands[0], 0) == 7"
9213 "stswi %2,%1,%O0"
9214 [(set_attr "type" "store")
9215 (set_attr "update" "yes")
9216 (set_attr "indexed" "yes")
9217 (set_attr "cell_micro" "always")])
9218
9219 (define_insn "*stmsi5"
9220 [(match_parallel 0 "store_multiple_operation"
9221 [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
9222 (match_operand:SI 2 "gpc_reg_operand" "r"))
9223 (clobber (match_scratch:SI 3 "=X"))
9224 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
9225 (match_operand:SI 4 "gpc_reg_operand" "r"))
9226 (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
9227 (match_operand:SI 5 "gpc_reg_operand" "r"))
9228 (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
9229 (match_operand:SI 6 "gpc_reg_operand" "r"))
9230 (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
9231 (match_operand:SI 7 "gpc_reg_operand" "r"))])]
9232 "TARGET_STRING && XVECLEN (operands[0], 0) == 6"
9233 "stswi %2,%1,%O0"
9234 [(set_attr "type" "store")
9235 (set_attr "update" "yes")
9236 (set_attr "indexed" "yes")
9237 (set_attr "cell_micro" "always")])
9238
9239 (define_insn "*stmsi4"
9240 [(match_parallel 0 "store_multiple_operation"
9241 [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
9242 (match_operand:SI 2 "gpc_reg_operand" "r"))
9243 (clobber (match_scratch:SI 3 "=X"))
9244 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
9245 (match_operand:SI 4 "gpc_reg_operand" "r"))
9246 (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
9247 (match_operand:SI 5 "gpc_reg_operand" "r"))
9248 (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
9249 (match_operand:SI 6 "gpc_reg_operand" "r"))])]
9250 "TARGET_STRING && XVECLEN (operands[0], 0) == 5"
9251 "stswi %2,%1,%O0"
9252 [(set_attr "type" "store")
9253 (set_attr "update" "yes")
9254 (set_attr "indexed" "yes")
9255 (set_attr "cell_micro" "always")])
9256
9257 (define_insn "*stmsi3"
9258 [(match_parallel 0 "store_multiple_operation"
9259 [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
9260 (match_operand:SI 2 "gpc_reg_operand" "r"))
9261 (clobber (match_scratch:SI 3 "=X"))
9262 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
9263 (match_operand:SI 4 "gpc_reg_operand" "r"))
9264 (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
9265 (match_operand:SI 5 "gpc_reg_operand" "r"))])]
9266 "TARGET_STRING && XVECLEN (operands[0], 0) == 4"
9267 "stswi %2,%1,%O0"
9268 [(set_attr "type" "store")
9269 (set_attr "update" "yes")
9270 (set_attr "indexed" "yes")
9271 (set_attr "cell_micro" "always")])
9272 \f
9273 (define_expand "setmemsi"
9274 [(parallel [(set (match_operand:BLK 0 "" "")
9275 (match_operand 2 "const_int_operand" ""))
9276 (use (match_operand:SI 1 "" ""))
9277 (use (match_operand:SI 3 "" ""))])]
9278 ""
9279 "
9280 {
9281 /* If value to set is not zero, use the library routine. */
9282 if (operands[2] != const0_rtx)
9283 FAIL;
9284
9285 if (expand_block_clear (operands))
9286 DONE;
9287 else
9288 FAIL;
9289 }")
9290
9291 ;; String/block move insn.
9292 ;; Argument 0 is the destination
9293 ;; Argument 1 is the source
9294 ;; Argument 2 is the length
9295 ;; Argument 3 is the alignment
9296
9297 (define_expand "movmemsi"
9298 [(parallel [(set (match_operand:BLK 0 "" "")
9299 (match_operand:BLK 1 "" ""))
9300 (use (match_operand:SI 2 "" ""))
9301 (use (match_operand:SI 3 "" ""))])]
9302 ""
9303 "
9304 {
9305 if (expand_block_move (operands))
9306 DONE;
9307 else
9308 FAIL;
9309 }")
9310
9311 ;; Move up to 32 bytes at a time. The fixed registers are needed because the
9312 ;; register allocator doesn't have a clue about allocating 8 word registers.
9313 ;; rD/rS = r5 is preferred, efficient form.
9314 (define_expand "movmemsi_8reg"
9315 [(parallel [(set (match_operand 0 "" "")
9316 (match_operand 1 "" ""))
9317 (use (match_operand 2 "" ""))
9318 (use (match_operand 3 "" ""))
9319 (clobber (reg:SI 5))
9320 (clobber (reg:SI 6))
9321 (clobber (reg:SI 7))
9322 (clobber (reg:SI 8))
9323 (clobber (reg:SI 9))
9324 (clobber (reg:SI 10))
9325 (clobber (reg:SI 11))
9326 (clobber (reg:SI 12))
9327 (clobber (match_scratch:SI 4 ""))])]
9328 "TARGET_STRING"
9329 "")
9330
9331 (define_insn ""
9332 [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
9333 (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
9334 (use (match_operand:SI 2 "immediate_operand" "i"))
9335 (use (match_operand:SI 3 "immediate_operand" "i"))
9336 (clobber (match_operand:SI 4 "gpc_reg_operand" "=&r"))
9337 (clobber (reg:SI 6))
9338 (clobber (reg:SI 7))
9339 (clobber (reg:SI 8))
9340 (clobber (reg:SI 9))
9341 (clobber (reg:SI 10))
9342 (clobber (reg:SI 11))
9343 (clobber (reg:SI 12))
9344 (clobber (match_scratch:SI 5 "=X"))]
9345 "TARGET_STRING
9346 && ((INTVAL (operands[2]) > 24 && INTVAL (operands[2]) < 32)
9347 || INTVAL (operands[2]) == 0)
9348 && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 12)
9349 && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 12)
9350 && REGNO (operands[4]) == 5"
9351 "lswi %4,%1,%2\;stswi %4,%0,%2"
9352 [(set_attr "type" "store")
9353 (set_attr "update" "yes")
9354 (set_attr "indexed" "yes")
9355 (set_attr "cell_micro" "always")
9356 (set_attr "length" "8")])
9357
9358 ;; Move up to 24 bytes at a time. The fixed registers are needed because the
9359 ;; register allocator doesn't have a clue about allocating 6 word registers.
9360 ;; rD/rS = r5 is preferred, efficient form.
9361 (define_expand "movmemsi_6reg"
9362 [(parallel [(set (match_operand 0 "" "")
9363 (match_operand 1 "" ""))
9364 (use (match_operand 2 "" ""))
9365 (use (match_operand 3 "" ""))
9366 (clobber (reg:SI 5))
9367 (clobber (reg:SI 6))
9368 (clobber (reg:SI 7))
9369 (clobber (reg:SI 8))
9370 (clobber (reg:SI 9))
9371 (clobber (reg:SI 10))
9372 (clobber (match_scratch:SI 4 ""))])]
9373 "TARGET_STRING"
9374 "")
9375
9376 (define_insn ""
9377 [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
9378 (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
9379 (use (match_operand:SI 2 "immediate_operand" "i"))
9380 (use (match_operand:SI 3 "immediate_operand" "i"))
9381 (clobber (match_operand:SI 4 "gpc_reg_operand" "=&r"))
9382 (clobber (reg:SI 6))
9383 (clobber (reg:SI 7))
9384 (clobber (reg:SI 8))
9385 (clobber (reg:SI 9))
9386 (clobber (reg:SI 10))
9387 (clobber (match_scratch:SI 5 "=X"))]
9388 "TARGET_STRING
9389 && INTVAL (operands[2]) > 16 && INTVAL (operands[2]) <= 32
9390 && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 10)
9391 && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 10)
9392 && REGNO (operands[4]) == 5"
9393 "lswi %4,%1,%2\;stswi %4,%0,%2"
9394 [(set_attr "type" "store")
9395 (set_attr "update" "yes")
9396 (set_attr "indexed" "yes")
9397 (set_attr "cell_micro" "always")
9398 (set_attr "length" "8")])
9399
9400 ;; Move up to 16 bytes at a time, using 4 fixed registers to avoid spill
9401 ;; problems with TImode.
9402 ;; rD/rS = r5 is preferred, efficient form.
9403 (define_expand "movmemsi_4reg"
9404 [(parallel [(set (match_operand 0 "" "")
9405 (match_operand 1 "" ""))
9406 (use (match_operand 2 "" ""))
9407 (use (match_operand 3 "" ""))
9408 (clobber (reg:SI 5))
9409 (clobber (reg:SI 6))
9410 (clobber (reg:SI 7))
9411 (clobber (reg:SI 8))
9412 (clobber (match_scratch:SI 4 ""))])]
9413 "TARGET_STRING"
9414 "")
9415
9416 (define_insn ""
9417 [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
9418 (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
9419 (use (match_operand:SI 2 "immediate_operand" "i"))
9420 (use (match_operand:SI 3 "immediate_operand" "i"))
9421 (clobber (match_operand:SI 4 "gpc_reg_operand" "=&r"))
9422 (clobber (reg:SI 6))
9423 (clobber (reg:SI 7))
9424 (clobber (reg:SI 8))
9425 (clobber (match_scratch:SI 5 "=X"))]
9426 "TARGET_STRING
9427 && INTVAL (operands[2]) > 8 && INTVAL (operands[2]) <= 16
9428 && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 8)
9429 && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 8)
9430 && REGNO (operands[4]) == 5"
9431 "lswi %4,%1,%2\;stswi %4,%0,%2"
9432 [(set_attr "type" "store")
9433 (set_attr "update" "yes")
9434 (set_attr "indexed" "yes")
9435 (set_attr "cell_micro" "always")
9436 (set_attr "length" "8")])
9437
9438 ;; Move up to 8 bytes at a time.
9439 (define_expand "movmemsi_2reg"
9440 [(parallel [(set (match_operand 0 "" "")
9441 (match_operand 1 "" ""))
9442 (use (match_operand 2 "" ""))
9443 (use (match_operand 3 "" ""))
9444 (clobber (match_scratch:DI 4 ""))
9445 (clobber (match_scratch:SI 5 ""))])]
9446 "TARGET_STRING && ! TARGET_POWERPC64"
9447 "")
9448
9449 (define_insn ""
9450 [(set (mem:BLK (match_operand:SI 0 "gpc_reg_operand" "b"))
9451 (mem:BLK (match_operand:SI 1 "gpc_reg_operand" "b")))
9452 (use (match_operand:SI 2 "immediate_operand" "i"))
9453 (use (match_operand:SI 3 "immediate_operand" "i"))
9454 (clobber (match_scratch:DI 4 "=&r"))
9455 (clobber (match_scratch:SI 5 "=X"))]
9456 "TARGET_STRING && ! TARGET_POWERPC64
9457 && INTVAL (operands[2]) > 4 && INTVAL (operands[2]) <= 8"
9458 "lswi %4,%1,%2\;stswi %4,%0,%2"
9459 [(set_attr "type" "store")
9460 (set_attr "update" "yes")
9461 (set_attr "indexed" "yes")
9462 (set_attr "cell_micro" "always")
9463 (set_attr "length" "8")])
9464
9465 ;; Move up to 4 bytes at a time.
9466 (define_expand "movmemsi_1reg"
9467 [(parallel [(set (match_operand 0 "" "")
9468 (match_operand 1 "" ""))
9469 (use (match_operand 2 "" ""))
9470 (use (match_operand 3 "" ""))
9471 (clobber (match_scratch:SI 4 ""))
9472 (clobber (match_scratch:SI 5 ""))])]
9473 "TARGET_STRING"
9474 "")
9475
9476 (define_insn ""
9477 [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
9478 (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
9479 (use (match_operand:SI 2 "immediate_operand" "i"))
9480 (use (match_operand:SI 3 "immediate_operand" "i"))
9481 (clobber (match_scratch:SI 4 "=&r"))
9482 (clobber (match_scratch:SI 5 "=X"))]
9483 "TARGET_STRING && INTVAL (operands[2]) > 0 && INTVAL (operands[2]) <= 4"
9484 "lswi %4,%1,%2\;stswi %4,%0,%2"
9485 [(set_attr "type" "store")
9486 (set_attr "update" "yes")
9487 (set_attr "indexed" "yes")
9488 (set_attr "cell_micro" "always")
9489 (set_attr "length" "8")])
9490 \f
9491 ;; Define insns that do load or store with update. Some of these we can
9492 ;; get by using pre-decrement or pre-increment, but the hardware can also
9493 ;; do cases where the increment is not the size of the object.
9494 ;;
9495 ;; In all these cases, we use operands 0 and 1 for the register being
9496 ;; incremented because those are the operands that local-alloc will
9497 ;; tie and these are the pair most likely to be tieable (and the ones
9498 ;; that will benefit the most).
9499
9500 (define_insn "*movdi_update1"
9501 [(set (match_operand:DI 3 "gpc_reg_operand" "=r,r")
9502 (mem:DI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0,0")
9503 (match_operand:DI 2 "reg_or_aligned_short_operand" "r,I"))))
9504 (set (match_operand:DI 0 "gpc_reg_operand" "=b,b")
9505 (plus:DI (match_dup 1) (match_dup 2)))]
9506 "TARGET_POWERPC64 && TARGET_UPDATE
9507 && (!avoiding_indexed_address_p (DImode)
9508 || !gpc_reg_operand (operands[2], DImode))"
9509 "@
9510 ldux %3,%0,%2
9511 ldu %3,%2(%0)"
9512 [(set_attr "type" "load")
9513 (set_attr "update" "yes")
9514 (set_attr "indexed" "yes,no")])
9515
9516 (define_insn "movdi_<mode>_update"
9517 [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9518 (match_operand:P 2 "reg_or_aligned_short_operand" "r,I")))
9519 (match_operand:DI 3 "gpc_reg_operand" "r,r"))
9520 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9521 (plus:P (match_dup 1) (match_dup 2)))]
9522 "TARGET_POWERPC64 && TARGET_UPDATE
9523 && (!avoiding_indexed_address_p (Pmode)
9524 || !gpc_reg_operand (operands[2], Pmode)
9525 || (REG_P (operands[0])
9526 && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
9527 "@
9528 stdux %3,%0,%2
9529 stdu %3,%2(%0)"
9530 [(set_attr "type" "store")
9531 (set_attr "update" "yes")
9532 (set_attr "indexed" "yes,no")])
9533
9534 ;; This pattern is only conditional on TARGET_POWERPC64, as it is
9535 ;; needed for stack allocation, even if the user passes -mno-update.
9536 (define_insn "movdi_<mode>_update_stack"
9537 [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9538 (match_operand:P 2 "reg_or_aligned_short_operand" "r,I")))
9539 (match_operand:DI 3 "gpc_reg_operand" "r,r"))
9540 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9541 (plus:P (match_dup 1) (match_dup 2)))]
9542 "TARGET_POWERPC64"
9543 "@
9544 stdux %3,%0,%2
9545 stdu %3,%2(%0)"
9546 [(set_attr "type" "store")
9547 (set_attr "update" "yes")
9548 (set_attr "indexed" "yes,no")])
9549
9550 (define_insn "*movsi_update1"
9551 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9552 (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9553 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9554 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9555 (plus:SI (match_dup 1) (match_dup 2)))]
9556 "TARGET_UPDATE
9557 && (!avoiding_indexed_address_p (SImode)
9558 || !gpc_reg_operand (operands[2], SImode))"
9559 "@
9560 lwzux %3,%0,%2
9561 lwzu %3,%2(%0)"
9562 [(set_attr "type" "load")
9563 (set_attr "update" "yes")
9564 (set_attr "indexed" "yes,no")])
9565
9566 (define_insn "*movsi_update2"
9567 [(set (match_operand:DI 3 "gpc_reg_operand" "=r")
9568 (sign_extend:DI
9569 (mem:SI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0")
9570 (match_operand:DI 2 "gpc_reg_operand" "r")))))
9571 (set (match_operand:DI 0 "gpc_reg_operand" "=b")
9572 (plus:DI (match_dup 1) (match_dup 2)))]
9573 "TARGET_POWERPC64 && rs6000_gen_cell_microcode
9574 && !avoiding_indexed_address_p (DImode)"
9575 "lwaux %3,%0,%2"
9576 [(set_attr "type" "load")
9577 (set_attr "sign_extend" "yes")
9578 (set_attr "update" "yes")
9579 (set_attr "indexed" "yes")])
9580
9581 (define_insn "movsi_update"
9582 [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9583 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9584 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
9585 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9586 (plus:SI (match_dup 1) (match_dup 2)))]
9587 "TARGET_UPDATE
9588 && (!avoiding_indexed_address_p (SImode)
9589 || !gpc_reg_operand (operands[2], SImode)
9590 || (REG_P (operands[0])
9591 && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
9592 "@
9593 stwux %3,%0,%2
9594 stwu %3,%2(%0)"
9595 [(set_attr "type" "store")
9596 (set_attr "update" "yes")
9597 (set_attr "indexed" "yes,no")])
9598
9599 ;; This is an unconditional pattern; needed for stack allocation, even
9600 ;; if the user passes -mno-update.
9601 (define_insn "movsi_update_stack"
9602 [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9603 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9604 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
9605 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9606 (plus:SI (match_dup 1) (match_dup 2)))]
9607 ""
9608 "@
9609 stwux %3,%0,%2
9610 stwu %3,%2(%0)"
9611 [(set_attr "type" "store")
9612 (set_attr "update" "yes")
9613 (set_attr "indexed" "yes,no")])
9614
9615 (define_insn "*movhi_update1"
9616 [(set (match_operand:HI 3 "gpc_reg_operand" "=r,r")
9617 (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9618 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9619 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9620 (plus:SI (match_dup 1) (match_dup 2)))]
9621 "TARGET_UPDATE
9622 && (!avoiding_indexed_address_p (SImode)
9623 || !gpc_reg_operand (operands[2], SImode))"
9624 "@
9625 lhzux %3,%0,%2
9626 lhzu %3,%2(%0)"
9627 [(set_attr "type" "load")
9628 (set_attr "update" "yes")
9629 (set_attr "indexed" "yes,no")])
9630
9631 (define_insn "*movhi_update2"
9632 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9633 (zero_extend:SI
9634 (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9635 (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
9636 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9637 (plus:SI (match_dup 1) (match_dup 2)))]
9638 "TARGET_UPDATE
9639 && (!avoiding_indexed_address_p (SImode)
9640 || !gpc_reg_operand (operands[2], SImode))"
9641 "@
9642 lhzux %3,%0,%2
9643 lhzu %3,%2(%0)"
9644 [(set_attr "type" "load")
9645 (set_attr "update" "yes")
9646 (set_attr "indexed" "yes,no")])
9647
9648 (define_insn "*movhi_update3"
9649 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9650 (sign_extend:SI
9651 (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9652 (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
9653 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9654 (plus:SI (match_dup 1) (match_dup 2)))]
9655 "TARGET_UPDATE && rs6000_gen_cell_microcode
9656 && (!avoiding_indexed_address_p (SImode)
9657 || !gpc_reg_operand (operands[2], SImode))"
9658 "@
9659 lhaux %3,%0,%2
9660 lhau %3,%2(%0)"
9661 [(set_attr "type" "load")
9662 (set_attr "sign_extend" "yes")
9663 (set_attr "update" "yes")
9664 (set_attr "indexed" "yes,no")])
9665
9666 (define_insn "*movhi_update4"
9667 [(set (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9668 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9669 (match_operand:HI 3 "gpc_reg_operand" "r,r"))
9670 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9671 (plus:SI (match_dup 1) (match_dup 2)))]
9672 "TARGET_UPDATE
9673 && (!avoiding_indexed_address_p (SImode)
9674 || !gpc_reg_operand (operands[2], SImode))"
9675 "@
9676 sthux %3,%0,%2
9677 sthu %3,%2(%0)"
9678 [(set_attr "type" "store")
9679 (set_attr "update" "yes")
9680 (set_attr "indexed" "yes,no")])
9681
9682 (define_insn "*movqi_update1"
9683 [(set (match_operand:QI 3 "gpc_reg_operand" "=r,r")
9684 (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9685 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9686 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9687 (plus:SI (match_dup 1) (match_dup 2)))]
9688 "TARGET_UPDATE
9689 && (!avoiding_indexed_address_p (SImode)
9690 || !gpc_reg_operand (operands[2], SImode))"
9691 "@
9692 lbzux %3,%0,%2
9693 lbzu %3,%2(%0)"
9694 [(set_attr "type" "load")
9695 (set_attr "update" "yes")
9696 (set_attr "indexed" "yes,no")])
9697
9698 (define_insn "*movqi_update2"
9699 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9700 (zero_extend:SI
9701 (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9702 (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
9703 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9704 (plus:SI (match_dup 1) (match_dup 2)))]
9705 "TARGET_UPDATE
9706 && (!avoiding_indexed_address_p (SImode)
9707 || !gpc_reg_operand (operands[2], SImode))"
9708 "@
9709 lbzux %3,%0,%2
9710 lbzu %3,%2(%0)"
9711 [(set_attr "type" "load")
9712 (set_attr "update" "yes")
9713 (set_attr "indexed" "yes,no")])
9714
9715 (define_insn "*movqi_update3"
9716 [(set (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9717 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9718 (match_operand:QI 3 "gpc_reg_operand" "r,r"))
9719 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9720 (plus:SI (match_dup 1) (match_dup 2)))]
9721 "TARGET_UPDATE
9722 && (!avoiding_indexed_address_p (SImode)
9723 || !gpc_reg_operand (operands[2], SImode))"
9724 "@
9725 stbux %3,%0,%2
9726 stbu %3,%2(%0)"
9727 [(set_attr "type" "store")
9728 (set_attr "update" "yes")
9729 (set_attr "indexed" "yes,no")])
9730
9731 (define_insn "*movsf_update1"
9732 [(set (match_operand:SF 3 "gpc_reg_operand" "=f,f")
9733 (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9734 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9735 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9736 (plus:SI (match_dup 1) (match_dup 2)))]
9737 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT && TARGET_UPDATE
9738 && (!avoiding_indexed_address_p (SImode)
9739 || !gpc_reg_operand (operands[2], SImode))"
9740 "@
9741 lfsux %3,%0,%2
9742 lfsu %3,%2(%0)"
9743 [(set_attr "type" "fpload")
9744 (set_attr "update" "yes")
9745 (set_attr "indexed" "yes,no")])
9746
9747 (define_insn "*movsf_update2"
9748 [(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9749 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9750 (match_operand:SF 3 "gpc_reg_operand" "f,f"))
9751 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9752 (plus:SI (match_dup 1) (match_dup 2)))]
9753 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT && TARGET_UPDATE
9754 && (!avoiding_indexed_address_p (SImode)
9755 || !gpc_reg_operand (operands[2], SImode))"
9756 "@
9757 stfsux %3,%0,%2
9758 stfsu %3,%2(%0)"
9759 [(set_attr "type" "fpstore")
9760 (set_attr "update" "yes")
9761 (set_attr "indexed" "yes,no")])
9762
9763 (define_insn "*movsf_update3"
9764 [(set (match_operand:SF 3 "gpc_reg_operand" "=r,r")
9765 (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9766 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9767 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9768 (plus:SI (match_dup 1) (match_dup 2)))]
9769 "(TARGET_SOFT_FLOAT || !TARGET_FPRS) && TARGET_UPDATE
9770 && (!avoiding_indexed_address_p (SImode)
9771 || !gpc_reg_operand (operands[2], SImode))"
9772 "@
9773 lwzux %3,%0,%2
9774 lwzu %3,%2(%0)"
9775 [(set_attr "type" "load")
9776 (set_attr "update" "yes")
9777 (set_attr "indexed" "yes,no")])
9778
9779 (define_insn "*movsf_update4"
9780 [(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9781 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9782 (match_operand:SF 3 "gpc_reg_operand" "r,r"))
9783 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9784 (plus:SI (match_dup 1) (match_dup 2)))]
9785 "(TARGET_SOFT_FLOAT || !TARGET_FPRS) && TARGET_UPDATE
9786 && (!avoiding_indexed_address_p (SImode)
9787 || !gpc_reg_operand (operands[2], SImode))"
9788 "@
9789 stwux %3,%0,%2
9790 stwu %3,%2(%0)"
9791 [(set_attr "type" "store")
9792 (set_attr "update" "yes")
9793 (set_attr "indexed" "yes,no")])
9794
9795 (define_insn "*movdf_update1"
9796 [(set (match_operand:DF 3 "gpc_reg_operand" "=d,d")
9797 (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9798 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9799 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9800 (plus:SI (match_dup 1) (match_dup 2)))]
9801 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_UPDATE
9802 && (!avoiding_indexed_address_p (SImode)
9803 || !gpc_reg_operand (operands[2], SImode))"
9804 "@
9805 lfdux %3,%0,%2
9806 lfdu %3,%2(%0)"
9807 [(set_attr "type" "fpload")
9808 (set_attr "update" "yes")
9809 (set_attr "indexed" "yes,no")])
9810
9811 (define_insn "*movdf_update2"
9812 [(set (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9813 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9814 (match_operand:DF 3 "gpc_reg_operand" "d,d"))
9815 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9816 (plus:SI (match_dup 1) (match_dup 2)))]
9817 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_UPDATE
9818 && (!avoiding_indexed_address_p (SImode)
9819 || !gpc_reg_operand (operands[2], SImode))"
9820 "@
9821 stfdux %3,%0,%2
9822 stfdu %3,%2(%0)"
9823 [(set_attr "type" "fpstore")
9824 (set_attr "update" "yes")
9825 (set_attr "indexed" "yes,no")])
9826
9827
9828 ;; After inserting conditional returns we can sometimes have
9829 ;; unnecessary register moves. Unfortunately we cannot have a
9830 ;; modeless peephole here, because some single SImode sets have early
9831 ;; clobber outputs. Although those sets expand to multi-ppc-insn
9832 ;; sequences, using get_attr_length here will smash the operands
9833 ;; array. Neither is there an early_cobbler_p predicate.
9834 ;; Disallow subregs for E500 so we don't munge frob_di_df_2.
9835 (define_peephole2
9836 [(set (match_operand:DF 0 "gpc_reg_operand" "")
9837 (match_operand:DF 1 "any_operand" ""))
9838 (set (match_operand:DF 2 "gpc_reg_operand" "")
9839 (match_dup 0))]
9840 "!(TARGET_E500_DOUBLE && GET_CODE (operands[2]) == SUBREG)
9841 && peep2_reg_dead_p (2, operands[0])"
9842 [(set (match_dup 2) (match_dup 1))])
9843
9844 (define_peephole2
9845 [(set (match_operand:SF 0 "gpc_reg_operand" "")
9846 (match_operand:SF 1 "any_operand" ""))
9847 (set (match_operand:SF 2 "gpc_reg_operand" "")
9848 (match_dup 0))]
9849 "peep2_reg_dead_p (2, operands[0])"
9850 [(set (match_dup 2) (match_dup 1))])
9851
9852 \f
9853 ;; TLS support.
9854
9855 ;; Mode attributes for different ABIs.
9856 (define_mode_iterator TLSmode [(SI "! TARGET_64BIT") (DI "TARGET_64BIT")])
9857 (define_mode_attr tls_abi_suffix [(SI "32") (DI "64")])
9858 (define_mode_attr tls_sysv_suffix [(SI "si") (DI "di")])
9859 (define_mode_attr tls_insn_suffix [(SI "wz") (DI "d")])
9860
9861 (define_insn_and_split "tls_gd_aix<TLSmode:tls_abi_suffix>"
9862 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9863 (call (mem:TLSmode (match_operand:TLSmode 3 "symbol_ref_operand" "s"))
9864 (match_operand 4 "" "g")))
9865 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9866 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9867 UNSPEC_TLSGD)
9868 (clobber (reg:SI LR_REGNO))]
9869 "HAVE_AS_TLS && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9870 {
9871 if (TARGET_CMODEL != CMODEL_SMALL)
9872 return "addis %0,%1,%2@got@tlsgd@ha\;addi %0,%0,%2@got@tlsgd@l\;"
9873 "bl %z3\;nop";
9874 else
9875 return "addi %0,%1,%2@got@tlsgd\;bl %z3\;nop";
9876 }
9877 "&& TARGET_TLS_MARKERS"
9878 [(set (match_dup 0)
9879 (unspec:TLSmode [(match_dup 1)
9880 (match_dup 2)]
9881 UNSPEC_TLSGD))
9882 (parallel [(set (match_dup 0)
9883 (call (mem:TLSmode (match_dup 3))
9884 (match_dup 4)))
9885 (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGD)
9886 (clobber (reg:SI LR_REGNO))])]
9887 ""
9888 [(set_attr "type" "two")
9889 (set (attr "length")
9890 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9891 (const_int 16)
9892 (const_int 12)))])
9893
9894 (define_insn_and_split "tls_gd_sysv<TLSmode:tls_sysv_suffix>"
9895 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9896 (call (mem:TLSmode (match_operand:TLSmode 3 "symbol_ref_operand" "s"))
9897 (match_operand 4 "" "g")))
9898 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9899 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9900 UNSPEC_TLSGD)
9901 (clobber (reg:SI LR_REGNO))]
9902 "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4"
9903 {
9904 if (flag_pic)
9905 {
9906 if (TARGET_SECURE_PLT && flag_pic == 2)
9907 return "addi %0,%1,%2@got@tlsgd\;bl %z3+32768@plt";
9908 else
9909 return "addi %0,%1,%2@got@tlsgd\;bl %z3@plt";
9910 }
9911 else
9912 return "addi %0,%1,%2@got@tlsgd\;bl %z3";
9913 }
9914 "&& TARGET_TLS_MARKERS"
9915 [(set (match_dup 0)
9916 (unspec:TLSmode [(match_dup 1)
9917 (match_dup 2)]
9918 UNSPEC_TLSGD))
9919 (parallel [(set (match_dup 0)
9920 (call (mem:TLSmode (match_dup 3))
9921 (match_dup 4)))
9922 (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGD)
9923 (clobber (reg:SI LR_REGNO))])]
9924 ""
9925 [(set_attr "type" "two")
9926 (set_attr "length" "8")])
9927
9928 (define_insn_and_split "*tls_gd<TLSmode:tls_abi_suffix>"
9929 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9930 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9931 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9932 UNSPEC_TLSGD))]
9933 "HAVE_AS_TLS && TARGET_TLS_MARKERS"
9934 "addi %0,%1,%2@got@tlsgd"
9935 "&& TARGET_CMODEL != CMODEL_SMALL"
9936 [(set (match_dup 3)
9937 (high:TLSmode
9938 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))
9939 (set (match_dup 0)
9940 (lo_sum:TLSmode (match_dup 3)
9941 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))]
9942 "
9943 {
9944 operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9945 }"
9946 [(set (attr "length")
9947 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9948 (const_int 8)
9949 (const_int 4)))])
9950
9951 (define_insn "*tls_gd_high<TLSmode:tls_abi_suffix>"
9952 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9953 (high:TLSmode
9954 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9955 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9956 UNSPEC_TLSGD)))]
9957 "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9958 "addis %0,%1,%2@got@tlsgd@ha"
9959 [(set_attr "length" "4")])
9960
9961 (define_insn "*tls_gd_low<TLSmode:tls_abi_suffix>"
9962 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9963 (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
9964 (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
9965 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9966 UNSPEC_TLSGD)))]
9967 "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9968 "addi %0,%1,%2@got@tlsgd@l"
9969 [(set_attr "length" "4")])
9970
9971 (define_insn "*tls_gd_call_aix<TLSmode:tls_abi_suffix>"
9972 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9973 (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9974 (match_operand 2 "" "g")))
9975 (unspec:TLSmode [(match_operand:TLSmode 3 "rs6000_tls_symbol_ref" "")]
9976 UNSPEC_TLSGD)
9977 (clobber (reg:SI LR_REGNO))]
9978 "HAVE_AS_TLS && TARGET_TLS_MARKERS
9979 && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9980 "bl %z1(%3@tlsgd)\;nop"
9981 [(set_attr "type" "branch")
9982 (set_attr "length" "8")])
9983
9984 (define_insn "*tls_gd_call_sysv<TLSmode:tls_abi_suffix>"
9985 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9986 (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9987 (match_operand 2 "" "g")))
9988 (unspec:TLSmode [(match_operand:TLSmode 3 "rs6000_tls_symbol_ref" "")]
9989 UNSPEC_TLSGD)
9990 (clobber (reg:SI LR_REGNO))]
9991 "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4 && TARGET_TLS_MARKERS"
9992 {
9993 if (flag_pic)
9994 {
9995 if (TARGET_SECURE_PLT && flag_pic == 2)
9996 return "bl %z1+32768(%3@tlsgd)@plt";
9997 return "bl %z1(%3@tlsgd)@plt";
9998 }
9999 return "bl %z1(%3@tlsgd)";
10000 }
10001 [(set_attr "type" "branch")
10002 (set_attr "length" "4")])
10003
10004 (define_insn_and_split "tls_ld_aix<TLSmode:tls_abi_suffix>"
10005 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10006 (call (mem:TLSmode (match_operand:TLSmode 2 "symbol_ref_operand" "s"))
10007 (match_operand 3 "" "g")))
10008 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
10009 UNSPEC_TLSLD)
10010 (clobber (reg:SI LR_REGNO))]
10011 "HAVE_AS_TLS && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
10012 {
10013 if (TARGET_CMODEL != CMODEL_SMALL)
10014 return "addis %0,%1,%&@got@tlsld@ha\;addi %0,%0,%&@got@tlsld@l\;"
10015 "bl %z2\;nop";
10016 else
10017 return "addi %0,%1,%&@got@tlsld\;bl %z2\;nop";
10018 }
10019 "&& TARGET_TLS_MARKERS"
10020 [(set (match_dup 0)
10021 (unspec:TLSmode [(match_dup 1)]
10022 UNSPEC_TLSLD))
10023 (parallel [(set (match_dup 0)
10024 (call (mem:TLSmode (match_dup 2))
10025 (match_dup 3)))
10026 (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
10027 (clobber (reg:SI LR_REGNO))])]
10028 ""
10029 [(set_attr "type" "two")
10030 (set (attr "length")
10031 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
10032 (const_int 16)
10033 (const_int 12)))])
10034
10035 (define_insn_and_split "tls_ld_sysv<TLSmode:tls_sysv_suffix>"
10036 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10037 (call (mem:TLSmode (match_operand:TLSmode 2 "symbol_ref_operand" "s"))
10038 (match_operand 3 "" "g")))
10039 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
10040 UNSPEC_TLSLD)
10041 (clobber (reg:SI LR_REGNO))]
10042 "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4"
10043 {
10044 if (flag_pic)
10045 {
10046 if (TARGET_SECURE_PLT && flag_pic == 2)
10047 return "addi %0,%1,%&@got@tlsld\;bl %z2+32768@plt";
10048 else
10049 return "addi %0,%1,%&@got@tlsld\;bl %z2@plt";
10050 }
10051 else
10052 return "addi %0,%1,%&@got@tlsld\;bl %z2";
10053 }
10054 "&& TARGET_TLS_MARKERS"
10055 [(set (match_dup 0)
10056 (unspec:TLSmode [(match_dup 1)]
10057 UNSPEC_TLSLD))
10058 (parallel [(set (match_dup 0)
10059 (call (mem:TLSmode (match_dup 2))
10060 (match_dup 3)))
10061 (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
10062 (clobber (reg:SI LR_REGNO))])]
10063 ""
10064 [(set_attr "length" "8")])
10065
10066 (define_insn_and_split "*tls_ld<TLSmode:tls_abi_suffix>"
10067 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10068 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
10069 UNSPEC_TLSLD))]
10070 "HAVE_AS_TLS && TARGET_TLS_MARKERS"
10071 "addi %0,%1,%&@got@tlsld"
10072 "&& TARGET_CMODEL != CMODEL_SMALL"
10073 [(set (match_dup 2)
10074 (high:TLSmode
10075 (unspec:TLSmode [(const_int 0) (match_dup 1)] UNSPEC_TLSLD)))
10076 (set (match_dup 0)
10077 (lo_sum:TLSmode (match_dup 2)
10078 (unspec:TLSmode [(const_int 0) (match_dup 1)] UNSPEC_TLSLD)))]
10079 "
10080 {
10081 operands[2] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
10082 }"
10083 [(set (attr "length")
10084 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
10085 (const_int 8)
10086 (const_int 4)))])
10087
10088 (define_insn "*tls_ld_high<TLSmode:tls_abi_suffix>"
10089 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10090 (high:TLSmode
10091 (unspec:TLSmode [(const_int 0)
10092 (match_operand:TLSmode 1 "gpc_reg_operand" "b")]
10093 UNSPEC_TLSLD)))]
10094 "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
10095 "addis %0,%1,%&@got@tlsld@ha"
10096 [(set_attr "length" "4")])
10097
10098 (define_insn "*tls_ld_low<TLSmode:tls_abi_suffix>"
10099 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10100 (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
10101 (unspec:TLSmode [(const_int 0)
10102 (match_operand:TLSmode 2 "gpc_reg_operand" "b")]
10103 UNSPEC_TLSLD)))]
10104 "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
10105 "addi %0,%1,%&@got@tlsld@l"
10106 [(set_attr "length" "4")])
10107
10108 (define_insn "*tls_ld_call_aix<TLSmode:tls_abi_suffix>"
10109 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10110 (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
10111 (match_operand 2 "" "g")))
10112 (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
10113 (clobber (reg:SI LR_REGNO))]
10114 "HAVE_AS_TLS && TARGET_TLS_MARKERS
10115 && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
10116 "bl %z1(%&@tlsld)\;nop"
10117 [(set_attr "type" "branch")
10118 (set_attr "length" "8")])
10119
10120 (define_insn "*tls_ld_call_sysv<TLSmode:tls_abi_suffix>"
10121 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10122 (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
10123 (match_operand 2 "" "g")))
10124 (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
10125 (clobber (reg:SI LR_REGNO))]
10126 "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4 && TARGET_TLS_MARKERS"
10127 {
10128 if (flag_pic)
10129 {
10130 if (TARGET_SECURE_PLT && flag_pic == 2)
10131 return "bl %z1+32768(%&@tlsld)@plt";
10132 return "bl %z1(%&@tlsld)@plt";
10133 }
10134 return "bl %z1(%&@tlsld)";
10135 }
10136 [(set_attr "type" "branch")
10137 (set_attr "length" "4")])
10138
10139 (define_insn "tls_dtprel_<TLSmode:tls_abi_suffix>"
10140 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10141 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10142 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10143 UNSPEC_TLSDTPREL))]
10144 "HAVE_AS_TLS"
10145 "addi %0,%1,%2@dtprel")
10146
10147 (define_insn "tls_dtprel_ha_<TLSmode:tls_abi_suffix>"
10148 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10149 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10150 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10151 UNSPEC_TLSDTPRELHA))]
10152 "HAVE_AS_TLS"
10153 "addis %0,%1,%2@dtprel@ha")
10154
10155 (define_insn "tls_dtprel_lo_<TLSmode:tls_abi_suffix>"
10156 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10157 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10158 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10159 UNSPEC_TLSDTPRELLO))]
10160 "HAVE_AS_TLS"
10161 "addi %0,%1,%2@dtprel@l")
10162
10163 (define_insn_and_split "tls_got_dtprel_<TLSmode:tls_abi_suffix>"
10164 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10165 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10166 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10167 UNSPEC_TLSGOTDTPREL))]
10168 "HAVE_AS_TLS"
10169 "l<TLSmode:tls_insn_suffix> %0,%2@got@dtprel(%1)"
10170 "&& TARGET_CMODEL != CMODEL_SMALL"
10171 [(set (match_dup 3)
10172 (high:TLSmode
10173 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))
10174 (set (match_dup 0)
10175 (lo_sum:TLSmode (match_dup 3)
10176 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))]
10177 "
10178 {
10179 operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
10180 }"
10181 [(set (attr "length")
10182 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
10183 (const_int 8)
10184 (const_int 4)))])
10185
10186 (define_insn "*tls_got_dtprel_high<TLSmode:tls_abi_suffix>"
10187 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10188 (high:TLSmode
10189 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10190 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10191 UNSPEC_TLSGOTDTPREL)))]
10192 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
10193 "addis %0,%1,%2@got@dtprel@ha"
10194 [(set_attr "length" "4")])
10195
10196 (define_insn "*tls_got_dtprel_low<TLSmode:tls_abi_suffix>"
10197 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10198 (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
10199 (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
10200 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10201 UNSPEC_TLSGOTDTPREL)))]
10202 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
10203 "l<TLSmode:tls_insn_suffix> %0,%2@got@dtprel@l(%1)"
10204 [(set_attr "length" "4")])
10205
10206 (define_insn "tls_tprel_<TLSmode:tls_abi_suffix>"
10207 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10208 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10209 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10210 UNSPEC_TLSTPREL))]
10211 "HAVE_AS_TLS"
10212 "addi %0,%1,%2@tprel")
10213
10214 (define_insn "tls_tprel_ha_<TLSmode:tls_abi_suffix>"
10215 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10216 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10217 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10218 UNSPEC_TLSTPRELHA))]
10219 "HAVE_AS_TLS"
10220 "addis %0,%1,%2@tprel@ha")
10221
10222 (define_insn "tls_tprel_lo_<TLSmode:tls_abi_suffix>"
10223 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10224 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10225 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10226 UNSPEC_TLSTPRELLO))]
10227 "HAVE_AS_TLS"
10228 "addi %0,%1,%2@tprel@l")
10229
10230 ;; "b" output constraint here and on tls_tls input to support linker tls
10231 ;; optimization. The linker may edit the instructions emitted by a
10232 ;; tls_got_tprel/tls_tls pair to addis,addi.
10233 (define_insn_and_split "tls_got_tprel_<TLSmode:tls_abi_suffix>"
10234 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10235 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10236 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10237 UNSPEC_TLSGOTTPREL))]
10238 "HAVE_AS_TLS"
10239 "l<TLSmode:tls_insn_suffix> %0,%2@got@tprel(%1)"
10240 "&& TARGET_CMODEL != CMODEL_SMALL"
10241 [(set (match_dup 3)
10242 (high:TLSmode
10243 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))
10244 (set (match_dup 0)
10245 (lo_sum:TLSmode (match_dup 3)
10246 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))]
10247 "
10248 {
10249 operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
10250 }"
10251 [(set (attr "length")
10252 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
10253 (const_int 8)
10254 (const_int 4)))])
10255
10256 (define_insn "*tls_got_tprel_high<TLSmode:tls_abi_suffix>"
10257 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10258 (high:TLSmode
10259 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10260 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10261 UNSPEC_TLSGOTTPREL)))]
10262 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
10263 "addis %0,%1,%2@got@tprel@ha"
10264 [(set_attr "length" "4")])
10265
10266 (define_insn "*tls_got_tprel_low<TLSmode:tls_abi_suffix>"
10267 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10268 (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
10269 (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
10270 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10271 UNSPEC_TLSGOTTPREL)))]
10272 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
10273 "l<TLSmode:tls_insn_suffix> %0,%2@got@tprel@l(%1)"
10274 [(set_attr "length" "4")])
10275
10276 (define_insn "tls_tls_<TLSmode:tls_abi_suffix>"
10277 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10278 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10279 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10280 UNSPEC_TLSTLS))]
10281 "TARGET_ELF && HAVE_AS_TLS"
10282 "add %0,%1,%2@tls")
10283
10284 (define_expand "tls_get_tpointer"
10285 [(set (match_operand:SI 0 "gpc_reg_operand" "")
10286 (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))]
10287 "TARGET_XCOFF && HAVE_AS_TLS"
10288 "
10289 {
10290 emit_insn (gen_tls_get_tpointer_internal ());
10291 emit_move_insn (operands[0], gen_rtx_REG (SImode, 3));
10292 DONE;
10293 }")
10294
10295 (define_insn "tls_get_tpointer_internal"
10296 [(set (reg:SI 3)
10297 (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))
10298 (clobber (reg:SI LR_REGNO))]
10299 "TARGET_XCOFF && HAVE_AS_TLS"
10300 "bla __get_tpointer")
10301
10302 (define_expand "tls_get_addr<mode>"
10303 [(set (match_operand:P 0 "gpc_reg_operand" "")
10304 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "")
10305 (match_operand:P 2 "gpc_reg_operand" "")] UNSPEC_TLSTLS))]
10306 "TARGET_XCOFF && HAVE_AS_TLS"
10307 "
10308 {
10309 emit_move_insn (gen_rtx_REG (Pmode, 3), operands[1]);
10310 emit_move_insn (gen_rtx_REG (Pmode, 4), operands[2]);
10311 emit_insn (gen_tls_get_addr_internal<mode> ());
10312 emit_move_insn (operands[0], gen_rtx_REG (Pmode, 3));
10313 DONE;
10314 }")
10315
10316 (define_insn "tls_get_addr_internal<mode>"
10317 [(set (reg:P 3)
10318 (unspec:P [(reg:P 3) (reg:P 4)] UNSPEC_TLSTLS))
10319 (clobber (reg:P 0))
10320 (clobber (reg:P 4))
10321 (clobber (reg:P 5))
10322 (clobber (reg:P 11))
10323 (clobber (reg:CC CR0_REGNO))
10324 (clobber (reg:P LR_REGNO))]
10325 "TARGET_XCOFF && HAVE_AS_TLS"
10326 "bla __tls_get_addr")
10327 \f
10328 ;; Next come insns related to the calling sequence.
10329 ;;
10330 ;; First, an insn to allocate new stack space for dynamic use (e.g., alloca).
10331 ;; We move the back-chain and decrement the stack pointer.
10332
10333 (define_expand "allocate_stack"
10334 [(set (match_operand 0 "gpc_reg_operand" "")
10335 (minus (reg 1) (match_operand 1 "reg_or_short_operand" "")))
10336 (set (reg 1)
10337 (minus (reg 1) (match_dup 1)))]
10338 ""
10339 "
10340 { rtx chain = gen_reg_rtx (Pmode);
10341 rtx stack_bot = gen_rtx_MEM (Pmode, stack_pointer_rtx);
10342 rtx neg_op0;
10343 rtx insn, par, set, mem;
10344
10345 emit_move_insn (chain, stack_bot);
10346
10347 /* Check stack bounds if necessary. */
10348 if (crtl->limit_stack)
10349 {
10350 rtx available;
10351 available = expand_binop (Pmode, sub_optab,
10352 stack_pointer_rtx, stack_limit_rtx,
10353 NULL_RTX, 1, OPTAB_WIDEN);
10354 emit_insn (gen_cond_trap (LTU, available, operands[1], const0_rtx));
10355 }
10356
10357 if (GET_CODE (operands[1]) != CONST_INT
10358 || INTVAL (operands[1]) < -32767
10359 || INTVAL (operands[1]) > 32768)
10360 {
10361 neg_op0 = gen_reg_rtx (Pmode);
10362 if (TARGET_32BIT)
10363 emit_insn (gen_negsi2 (neg_op0, operands[1]));
10364 else
10365 emit_insn (gen_negdi2 (neg_op0, operands[1]));
10366 }
10367 else
10368 neg_op0 = GEN_INT (- INTVAL (operands[1]));
10369
10370 insn = emit_insn ((* ((TARGET_32BIT) ? gen_movsi_update_stack
10371 : gen_movdi_di_update_stack))
10372 (stack_pointer_rtx, stack_pointer_rtx, neg_op0,
10373 chain));
10374 /* Since we didn't use gen_frame_mem to generate the MEM, grab
10375 it now and set the alias set/attributes. The above gen_*_update
10376 calls will generate a PARALLEL with the MEM set being the first
10377 operation. */
10378 par = PATTERN (insn);
10379 gcc_assert (GET_CODE (par) == PARALLEL);
10380 set = XVECEXP (par, 0, 0);
10381 gcc_assert (GET_CODE (set) == SET);
10382 mem = SET_DEST (set);
10383 gcc_assert (MEM_P (mem));
10384 MEM_NOTRAP_P (mem) = 1;
10385 set_mem_alias_set (mem, get_frame_alias_set ());
10386
10387 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
10388 DONE;
10389 }")
10390
10391 ;; These patterns say how to save and restore the stack pointer. We need not
10392 ;; save the stack pointer at function level since we are careful to
10393 ;; preserve the backchain. At block level, we have to restore the backchain
10394 ;; when we restore the stack pointer.
10395 ;;
10396 ;; For nonlocal gotos, we must save both the stack pointer and its
10397 ;; backchain and restore both. Note that in the nonlocal case, the
10398 ;; save area is a memory location.
10399
10400 (define_expand "save_stack_function"
10401 [(match_operand 0 "any_operand" "")
10402 (match_operand 1 "any_operand" "")]
10403 ""
10404 "DONE;")
10405
10406 (define_expand "restore_stack_function"
10407 [(match_operand 0 "any_operand" "")
10408 (match_operand 1 "any_operand" "")]
10409 ""
10410 "DONE;")
10411
10412 ;; Adjust stack pointer (op0) to a new value (op1).
10413 ;; First copy old stack backchain to new location, and ensure that the
10414 ;; scheduler won't reorder the sp assignment before the backchain write.
10415 (define_expand "restore_stack_block"
10416 [(set (match_dup 2) (match_dup 3))
10417 (set (match_dup 4) (match_dup 2))
10418 (match_dup 5)
10419 (set (match_operand 0 "register_operand" "")
10420 (match_operand 1 "register_operand" ""))]
10421 ""
10422 "
10423 {
10424 rtvec p;
10425
10426 operands[1] = force_reg (Pmode, operands[1]);
10427 operands[2] = gen_reg_rtx (Pmode);
10428 operands[3] = gen_frame_mem (Pmode, operands[0]);
10429 operands[4] = gen_frame_mem (Pmode, operands[1]);
10430 p = rtvec_alloc (1);
10431 RTVEC_ELT (p, 0) = gen_rtx_SET (VOIDmode,
10432 gen_frame_mem (BLKmode, operands[0]),
10433 const0_rtx);
10434 operands[5] = gen_rtx_PARALLEL (VOIDmode, p);
10435 }")
10436
10437 (define_expand "save_stack_nonlocal"
10438 [(set (match_dup 3) (match_dup 4))
10439 (set (match_operand 0 "memory_operand" "") (match_dup 3))
10440 (set (match_dup 2) (match_operand 1 "register_operand" ""))]
10441 ""
10442 "
10443 {
10444 int units_per_word = (TARGET_32BIT) ? 4 : 8;
10445
10446 /* Copy the backchain to the first word, sp to the second. */
10447 operands[0] = adjust_address_nv (operands[0], Pmode, 0);
10448 operands[2] = adjust_address_nv (operands[0], Pmode, units_per_word);
10449 operands[3] = gen_reg_rtx (Pmode);
10450 operands[4] = gen_frame_mem (Pmode, operands[1]);
10451 }")
10452
10453 (define_expand "restore_stack_nonlocal"
10454 [(set (match_dup 2) (match_operand 1 "memory_operand" ""))
10455 (set (match_dup 3) (match_dup 4))
10456 (set (match_dup 5) (match_dup 2))
10457 (match_dup 6)
10458 (set (match_operand 0 "register_operand" "") (match_dup 3))]
10459 ""
10460 "
10461 {
10462 int units_per_word = (TARGET_32BIT) ? 4 : 8;
10463 rtvec p;
10464
10465 /* Restore the backchain from the first word, sp from the second. */
10466 operands[2] = gen_reg_rtx (Pmode);
10467 operands[3] = gen_reg_rtx (Pmode);
10468 operands[1] = adjust_address_nv (operands[1], Pmode, 0);
10469 operands[4] = adjust_address_nv (operands[1], Pmode, units_per_word);
10470 operands[5] = gen_frame_mem (Pmode, operands[3]);
10471 p = rtvec_alloc (1);
10472 RTVEC_ELT (p, 0) = gen_rtx_SET (VOIDmode,
10473 gen_frame_mem (BLKmode, operands[0]),
10474 const0_rtx);
10475 operands[6] = gen_rtx_PARALLEL (VOIDmode, p);
10476 }")
10477 \f
10478 ;; TOC register handling.
10479
10480 ;; Code to initialize the TOC register...
10481
10482 (define_insn "load_toc_aix_si"
10483 [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10484 (unspec:SI [(const_int 0)] UNSPEC_TOC))
10485 (use (reg:SI 2))])]
10486 "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_32BIT"
10487 "*
10488 {
10489 char buf[30];
10490 ASM_GENERATE_INTERNAL_LABEL (buf, \"LCTOC\", 1);
10491 operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
10492 operands[2] = gen_rtx_REG (Pmode, 2);
10493 return \"lwz %0,%1(%2)\";
10494 }"
10495 [(set_attr "type" "load")
10496 (set_attr "update" "no")
10497 (set_attr "indexed" "no")])
10498
10499 (define_insn "load_toc_aix_di"
10500 [(parallel [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
10501 (unspec:DI [(const_int 0)] UNSPEC_TOC))
10502 (use (reg:DI 2))])]
10503 "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_64BIT"
10504 "*
10505 {
10506 char buf[30];
10507 #ifdef TARGET_RELOCATABLE
10508 ASM_GENERATE_INTERNAL_LABEL (buf, \"LCTOC\",
10509 !TARGET_MINIMAL_TOC || TARGET_RELOCATABLE);
10510 #else
10511 ASM_GENERATE_INTERNAL_LABEL (buf, \"LCTOC\", 1);
10512 #endif
10513 if (TARGET_ELF)
10514 strcat (buf, \"@toc\");
10515 operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
10516 operands[2] = gen_rtx_REG (Pmode, 2);
10517 return \"ld %0,%1(%2)\";
10518 }"
10519 [(set_attr "type" "load")
10520 (set_attr "update" "no")
10521 (set_attr "indexed" "no")])
10522
10523 (define_insn "load_toc_v4_pic_si"
10524 [(set (reg:SI LR_REGNO)
10525 (unspec:SI [(const_int 0)] UNSPEC_TOC))]
10526 "DEFAULT_ABI == ABI_V4 && flag_pic == 1 && TARGET_32BIT"
10527 "bl _GLOBAL_OFFSET_TABLE_@local-4"
10528 [(set_attr "type" "branch")
10529 (set_attr "length" "4")])
10530
10531 (define_expand "load_toc_v4_PIC_1"
10532 [(parallel [(set (reg:SI LR_REGNO)
10533 (match_operand:SI 0 "immediate_operand" "s"))
10534 (use (unspec [(match_dup 0)] UNSPEC_TOC))])]
10535 "TARGET_ELF && DEFAULT_ABI == ABI_V4
10536 && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10537 "")
10538
10539 (define_insn "load_toc_v4_PIC_1_normal"
10540 [(set (reg:SI LR_REGNO)
10541 (match_operand:SI 0 "immediate_operand" "s"))
10542 (use (unspec [(match_dup 0)] UNSPEC_TOC))]
10543 "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
10544 && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10545 "bcl 20,31,%0\\n%0:"
10546 [(set_attr "type" "branch")
10547 (set_attr "length" "4")])
10548
10549 (define_insn "load_toc_v4_PIC_1_476"
10550 [(set (reg:SI LR_REGNO)
10551 (match_operand:SI 0 "immediate_operand" "s"))
10552 (use (unspec [(match_dup 0)] UNSPEC_TOC))]
10553 "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
10554 && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10555 "*
10556 {
10557 char name[32];
10558 static char templ[32];
10559
10560 get_ppc476_thunk_name (name);
10561 sprintf (templ, \"bl %s\\n%%0:\", name);
10562 return templ;
10563 }"
10564 [(set_attr "type" "branch")
10565 (set_attr "length" "4")])
10566
10567 (define_expand "load_toc_v4_PIC_1b"
10568 [(parallel [(set (reg:SI LR_REGNO)
10569 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10570 (label_ref (match_operand 1 "" ""))]
10571 UNSPEC_TOCPTR))
10572 (match_dup 1)])]
10573 "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10574 "")
10575
10576 (define_insn "load_toc_v4_PIC_1b_normal"
10577 [(set (reg:SI LR_REGNO)
10578 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10579 (label_ref (match_operand 1 "" ""))]
10580 UNSPEC_TOCPTR))
10581 (match_dup 1)]
10582 "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10583 "bcl 20,31,$+8\;.long %0-$"
10584 [(set_attr "type" "branch")
10585 (set_attr "length" "8")])
10586
10587 (define_insn "load_toc_v4_PIC_1b_476"
10588 [(set (reg:SI LR_REGNO)
10589 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10590 (label_ref (match_operand 1 "" ""))]
10591 UNSPEC_TOCPTR))
10592 (match_dup 1)]
10593 "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10594 "*
10595 {
10596 char name[32];
10597 static char templ[32];
10598
10599 get_ppc476_thunk_name (name);
10600 sprintf (templ, \"bl %s\\n\\tb $+8\\n\\t.long %%0-$\", name);
10601 return templ;
10602 }"
10603 [(set_attr "type" "branch")
10604 (set_attr "length" "16")])
10605
10606 (define_insn "load_toc_v4_PIC_2"
10607 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10608 (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
10609 (minus:SI (match_operand:SI 2 "immediate_operand" "s")
10610 (match_operand:SI 3 "immediate_operand" "s")))))]
10611 "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10612 "lwz %0,%2-%3(%1)"
10613 [(set_attr "type" "load")])
10614
10615 (define_insn "load_toc_v4_PIC_3b"
10616 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10617 (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
10618 (high:SI
10619 (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
10620 (match_operand:SI 3 "symbol_ref_operand" "s")))))]
10621 "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
10622 "addis %0,%1,%2-%3@ha")
10623
10624 (define_insn "load_toc_v4_PIC_3c"
10625 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10626 (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
10627 (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
10628 (match_operand:SI 3 "symbol_ref_operand" "s"))))]
10629 "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
10630 "addi %0,%1,%2-%3@l")
10631
10632 ;; If the TOC is shared over a translation unit, as happens with all
10633 ;; the kinds of PIC that we support, we need to restore the TOC
10634 ;; pointer only when jumping over units of translation.
10635 ;; On Darwin, we need to reload the picbase.
10636
10637 (define_expand "builtin_setjmp_receiver"
10638 [(use (label_ref (match_operand 0 "" "")))]
10639 "(DEFAULT_ABI == ABI_V4 && flag_pic == 1)
10640 || (TARGET_TOC && TARGET_MINIMAL_TOC)
10641 || (DEFAULT_ABI == ABI_DARWIN && flag_pic)"
10642 "
10643 {
10644 #if TARGET_MACHO
10645 if (DEFAULT_ABI == ABI_DARWIN)
10646 {
10647 rtx picrtx = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME);
10648 rtx picreg = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
10649 rtx tmplabrtx;
10650 char tmplab[20];
10651
10652 crtl->uses_pic_offset_table = 1;
10653 ASM_GENERATE_INTERNAL_LABEL(tmplab, \"LSJR\",
10654 CODE_LABEL_NUMBER (operands[0]));
10655 tmplabrtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (tmplab));
10656
10657 emit_insn (gen_load_macho_picbase (tmplabrtx));
10658 emit_move_insn (picreg, gen_rtx_REG (Pmode, LR_REGNO));
10659 emit_insn (gen_macho_correct_pic (picreg, picreg, picrtx, tmplabrtx));
10660 }
10661 else
10662 #endif
10663 rs6000_emit_load_toc_table (FALSE);
10664 DONE;
10665 }")
10666
10667 ;; Largetoc support
10668 (define_insn "*largetoc_high"
10669 [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
10670 (high:DI
10671 (unspec [(match_operand:DI 1 "" "")
10672 (match_operand:DI 2 "gpc_reg_operand" "b")]
10673 UNSPEC_TOCREL)))]
10674 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10675 "addis %0,%2,%1@toc@ha")
10676
10677 (define_insn "*largetoc_high_aix<mode>"
10678 [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
10679 (high:P
10680 (unspec [(match_operand:P 1 "" "")
10681 (match_operand:P 2 "gpc_reg_operand" "b")]
10682 UNSPEC_TOCREL)))]
10683 "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10684 "addis %0,%1@u(%2)")
10685
10686 (define_insn "*largetoc_high_plus"
10687 [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
10688 (high:DI
10689 (plus:DI
10690 (unspec [(match_operand:DI 1 "" "")
10691 (match_operand:DI 2 "gpc_reg_operand" "b")]
10692 UNSPEC_TOCREL)
10693 (match_operand:DI 3 "add_cint_operand" "n"))))]
10694 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10695 "addis %0,%2,%1+%3@toc@ha")
10696
10697 (define_insn "*largetoc_high_plus_aix<mode>"
10698 [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
10699 (high:P
10700 (plus:P
10701 (unspec [(match_operand:P 1 "" "")
10702 (match_operand:P 2 "gpc_reg_operand" "b")]
10703 UNSPEC_TOCREL)
10704 (match_operand:P 3 "add_cint_operand" "n"))))]
10705 "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10706 "addis %0,%1+%3@u(%2)")
10707
10708 (define_insn "*largetoc_low"
10709 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
10710 (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b,!*r")
10711 (match_operand:DI 2 "" "")))]
10712 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10713 "@
10714 addi %0,%1,%2@l
10715 addic %0,%1,%2@l")
10716
10717 (define_insn "*largetoc_low_aix<mode>"
10718 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10719 (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
10720 (match_operand:P 2 "" "")))]
10721 "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10722 "la %0,%2@l(%1)")
10723
10724 (define_insn_and_split "*tocref<mode>"
10725 [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
10726 (match_operand:P 1 "small_toc_ref" "R"))]
10727 "TARGET_TOC"
10728 "la %0,%a1"
10729 "&& TARGET_CMODEL != CMODEL_SMALL && reload_completed"
10730 [(set (match_dup 0) (high:P (match_dup 1)))
10731 (set (match_dup 0) (lo_sum:P (match_dup 0) (match_dup 1)))])
10732
10733 ;; Elf specific ways of loading addresses for non-PIC code.
10734 ;; The output of this could be r0, but we make a very strong
10735 ;; preference for a base register because it will usually
10736 ;; be needed there.
10737 (define_insn "elf_high"
10738 [(set (match_operand:SI 0 "gpc_reg_operand" "=b*r")
10739 (high:SI (match_operand 1 "" "")))]
10740 "TARGET_ELF && ! TARGET_64BIT"
10741 "lis %0,%1@ha")
10742
10743 (define_insn "elf_low"
10744 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
10745 (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b,!*r")
10746 (match_operand 2 "" "")))]
10747 "TARGET_ELF && ! TARGET_64BIT"
10748 "@
10749 la %0,%2@l(%1)
10750 addic %0,%1,%K2")
10751 \f
10752 ;; Call and call_value insns
10753 (define_expand "call"
10754 [(parallel [(call (mem:SI (match_operand 0 "address_operand" ""))
10755 (match_operand 1 "" ""))
10756 (use (match_operand 2 "" ""))
10757 (clobber (reg:SI LR_REGNO))])]
10758 ""
10759 "
10760 {
10761 #if TARGET_MACHO
10762 if (MACHOPIC_INDIRECT)
10763 operands[0] = machopic_indirect_call_target (operands[0]);
10764 #endif
10765
10766 gcc_assert (GET_CODE (operands[0]) == MEM);
10767 gcc_assert (GET_CODE (operands[1]) == CONST_INT);
10768
10769 operands[0] = XEXP (operands[0], 0);
10770
10771 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10772 {
10773 rs6000_call_aix (NULL_RTX, operands[0], operands[1], operands[2]);
10774 DONE;
10775 }
10776
10777 if (GET_CODE (operands[0]) != SYMBOL_REF
10778 || (DEFAULT_ABI != ABI_DARWIN && (INTVAL (operands[2]) & CALL_LONG) != 0))
10779 {
10780 if (INTVAL (operands[2]) & CALL_LONG)
10781 operands[0] = rs6000_longcall_ref (operands[0]);
10782
10783 switch (DEFAULT_ABI)
10784 {
10785 case ABI_V4:
10786 case ABI_DARWIN:
10787 operands[0] = force_reg (Pmode, operands[0]);
10788 break;
10789
10790 default:
10791 gcc_unreachable ();
10792 }
10793 }
10794 }")
10795
10796 (define_expand "call_value"
10797 [(parallel [(set (match_operand 0 "" "")
10798 (call (mem:SI (match_operand 1 "address_operand" ""))
10799 (match_operand 2 "" "")))
10800 (use (match_operand 3 "" ""))
10801 (clobber (reg:SI LR_REGNO))])]
10802 ""
10803 "
10804 {
10805 #if TARGET_MACHO
10806 if (MACHOPIC_INDIRECT)
10807 operands[1] = machopic_indirect_call_target (operands[1]);
10808 #endif
10809
10810 gcc_assert (GET_CODE (operands[1]) == MEM);
10811 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10812
10813 operands[1] = XEXP (operands[1], 0);
10814
10815 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10816 {
10817 rs6000_call_aix (operands[0], operands[1], operands[2], operands[3]);
10818 DONE;
10819 }
10820
10821 if (GET_CODE (operands[1]) != SYMBOL_REF
10822 || (DEFAULT_ABI != ABI_DARWIN && (INTVAL (operands[3]) & CALL_LONG) != 0))
10823 {
10824 if (INTVAL (operands[3]) & CALL_LONG)
10825 operands[1] = rs6000_longcall_ref (operands[1]);
10826
10827 switch (DEFAULT_ABI)
10828 {
10829 case ABI_V4:
10830 case ABI_DARWIN:
10831 operands[1] = force_reg (Pmode, operands[1]);
10832 break;
10833
10834 default:
10835 gcc_unreachable ();
10836 }
10837 }
10838 }")
10839
10840 ;; Call to function in current module. No TOC pointer reload needed.
10841 ;; Operand2 is nonzero if we are using the V.4 calling sequence and
10842 ;; either the function was not prototyped, or it was prototyped as a
10843 ;; variable argument function. It is > 0 if FP registers were passed
10844 ;; and < 0 if they were not.
10845
10846 (define_insn "*call_local32"
10847 [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
10848 (match_operand 1 "" "g,g"))
10849 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10850 (clobber (reg:SI LR_REGNO))]
10851 "(INTVAL (operands[2]) & CALL_LONG) == 0"
10852 "*
10853 {
10854 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10855 output_asm_insn (\"crxor 6,6,6\", operands);
10856
10857 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10858 output_asm_insn (\"creqv 6,6,6\", operands);
10859
10860 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z0@local\" : \"bl %z0\";
10861 }"
10862 [(set_attr "type" "branch")
10863 (set_attr "length" "4,8")])
10864
10865 (define_insn "*call_local64"
10866 [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
10867 (match_operand 1 "" "g,g"))
10868 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10869 (clobber (reg:SI LR_REGNO))]
10870 "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
10871 "*
10872 {
10873 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10874 output_asm_insn (\"crxor 6,6,6\", operands);
10875
10876 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10877 output_asm_insn (\"creqv 6,6,6\", operands);
10878
10879 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z0@local\" : \"bl %z0\";
10880 }"
10881 [(set_attr "type" "branch")
10882 (set_attr "length" "4,8")])
10883
10884 (define_insn "*call_value_local32"
10885 [(set (match_operand 0 "" "")
10886 (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
10887 (match_operand 2 "" "g,g")))
10888 (use (match_operand:SI 3 "immediate_operand" "O,n"))
10889 (clobber (reg:SI LR_REGNO))]
10890 "(INTVAL (operands[3]) & CALL_LONG) == 0"
10891 "*
10892 {
10893 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10894 output_asm_insn (\"crxor 6,6,6\", operands);
10895
10896 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10897 output_asm_insn (\"creqv 6,6,6\", operands);
10898
10899 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z1@local\" : \"bl %z1\";
10900 }"
10901 [(set_attr "type" "branch")
10902 (set_attr "length" "4,8")])
10903
10904
10905 (define_insn "*call_value_local64"
10906 [(set (match_operand 0 "" "")
10907 (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
10908 (match_operand 2 "" "g,g")))
10909 (use (match_operand:SI 3 "immediate_operand" "O,n"))
10910 (clobber (reg:SI LR_REGNO))]
10911 "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
10912 "*
10913 {
10914 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10915 output_asm_insn (\"crxor 6,6,6\", operands);
10916
10917 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10918 output_asm_insn (\"creqv 6,6,6\", operands);
10919
10920 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z1@local\" : \"bl %z1\";
10921 }"
10922 [(set_attr "type" "branch")
10923 (set_attr "length" "4,8")])
10924
10925
10926 ;; A function pointer under System V is just a normal pointer
10927 ;; operands[0] is the function pointer
10928 ;; operands[1] is the stack size to clean up
10929 ;; operands[2] is the value FUNCTION_ARG returns for the VOID argument
10930 ;; which indicates how to set cr1
10931
10932 (define_insn "*call_indirect_nonlocal_sysv<mode>"
10933 [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l,c,*l"))
10934 (match_operand 1 "" "g,g,g,g"))
10935 (use (match_operand:SI 2 "immediate_operand" "O,O,n,n"))
10936 (clobber (reg:SI LR_REGNO))]
10937 "DEFAULT_ABI == ABI_V4
10938 || DEFAULT_ABI == ABI_DARWIN"
10939 {
10940 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10941 output_asm_insn ("crxor 6,6,6", operands);
10942
10943 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10944 output_asm_insn ("creqv 6,6,6", operands);
10945
10946 return "b%T0l";
10947 }
10948 [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg")
10949 (set_attr "length" "4,4,8,8")])
10950
10951 (define_insn_and_split "*call_nonlocal_sysv<mode>"
10952 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
10953 (match_operand 1 "" "g,g"))
10954 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10955 (clobber (reg:SI LR_REGNO))]
10956 "(DEFAULT_ABI == ABI_DARWIN
10957 || (DEFAULT_ABI == ABI_V4
10958 && (INTVAL (operands[2]) & CALL_LONG) == 0))"
10959 {
10960 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10961 output_asm_insn ("crxor 6,6,6", operands);
10962
10963 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10964 output_asm_insn ("creqv 6,6,6", operands);
10965
10966 #if TARGET_MACHO
10967 return output_call(insn, operands, 0, 2);
10968 #else
10969 if (DEFAULT_ABI == ABI_V4 && flag_pic)
10970 {
10971 gcc_assert (!TARGET_SECURE_PLT);
10972 return "bl %z0@plt";
10973 }
10974 else
10975 return "bl %z0";
10976 #endif
10977 }
10978 "DEFAULT_ABI == ABI_V4
10979 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0])
10980 && (INTVAL (operands[2]) & CALL_LONG) == 0"
10981 [(parallel [(call (mem:SI (match_dup 0))
10982 (match_dup 1))
10983 (use (match_dup 2))
10984 (use (match_dup 3))
10985 (clobber (reg:SI LR_REGNO))])]
10986 {
10987 operands[3] = pic_offset_table_rtx;
10988 }
10989 [(set_attr "type" "branch,branch")
10990 (set_attr "length" "4,8")])
10991
10992 (define_insn "*call_nonlocal_sysv_secure<mode>"
10993 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
10994 (match_operand 1 "" "g,g"))
10995 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10996 (use (match_operand:SI 3 "register_operand" "r,r"))
10997 (clobber (reg:SI LR_REGNO))]
10998 "(DEFAULT_ABI == ABI_V4
10999 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0])
11000 && (INTVAL (operands[2]) & CALL_LONG) == 0)"
11001 {
11002 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
11003 output_asm_insn ("crxor 6,6,6", operands);
11004
11005 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
11006 output_asm_insn ("creqv 6,6,6", operands);
11007
11008 if (flag_pic == 2)
11009 /* The magic 32768 offset here and in the other sysv call insns
11010 corresponds to the offset of r30 in .got2, as given by LCTOC1.
11011 See sysv4.h:toc_section. */
11012 return "bl %z0+32768@plt";
11013 else
11014 return "bl %z0@plt";
11015 }
11016 [(set_attr "type" "branch,branch")
11017 (set_attr "length" "4,8")])
11018
11019 (define_insn "*call_value_indirect_nonlocal_sysv<mode>"
11020 [(set (match_operand 0 "" "")
11021 (call (mem:SI (match_operand:P 1 "register_operand" "c,*l,c,*l"))
11022 (match_operand 2 "" "g,g,g,g")))
11023 (use (match_operand:SI 3 "immediate_operand" "O,O,n,n"))
11024 (clobber (reg:SI LR_REGNO))]
11025 "DEFAULT_ABI == ABI_V4
11026 || DEFAULT_ABI == ABI_DARWIN"
11027 {
11028 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11029 output_asm_insn ("crxor 6,6,6", operands);
11030
11031 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11032 output_asm_insn ("creqv 6,6,6", operands);
11033
11034 return "b%T1l";
11035 }
11036 [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg")
11037 (set_attr "length" "4,4,8,8")])
11038
11039 (define_insn_and_split "*call_value_nonlocal_sysv<mode>"
11040 [(set (match_operand 0 "" "")
11041 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
11042 (match_operand 2 "" "g,g")))
11043 (use (match_operand:SI 3 "immediate_operand" "O,n"))
11044 (clobber (reg:SI LR_REGNO))]
11045 "(DEFAULT_ABI == ABI_DARWIN
11046 || (DEFAULT_ABI == ABI_V4
11047 && (INTVAL (operands[3]) & CALL_LONG) == 0))"
11048 {
11049 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11050 output_asm_insn ("crxor 6,6,6", operands);
11051
11052 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11053 output_asm_insn ("creqv 6,6,6", operands);
11054
11055 #if TARGET_MACHO
11056 return output_call(insn, operands, 1, 3);
11057 #else
11058 if (DEFAULT_ABI == ABI_V4 && flag_pic)
11059 {
11060 gcc_assert (!TARGET_SECURE_PLT);
11061 return "bl %z1@plt";
11062 }
11063 else
11064 return "bl %z1";
11065 #endif
11066 }
11067 "DEFAULT_ABI == ABI_V4
11068 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1])
11069 && (INTVAL (operands[3]) & CALL_LONG) == 0"
11070 [(parallel [(set (match_dup 0)
11071 (call (mem:SI (match_dup 1))
11072 (match_dup 2)))
11073 (use (match_dup 3))
11074 (use (match_dup 4))
11075 (clobber (reg:SI LR_REGNO))])]
11076 {
11077 operands[4] = pic_offset_table_rtx;
11078 }
11079 [(set_attr "type" "branch,branch")
11080 (set_attr "length" "4,8")])
11081
11082 (define_insn "*call_value_nonlocal_sysv_secure<mode>"
11083 [(set (match_operand 0 "" "")
11084 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
11085 (match_operand 2 "" "g,g")))
11086 (use (match_operand:SI 3 "immediate_operand" "O,n"))
11087 (use (match_operand:SI 4 "register_operand" "r,r"))
11088 (clobber (reg:SI LR_REGNO))]
11089 "(DEFAULT_ABI == ABI_V4
11090 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1])
11091 && (INTVAL (operands[3]) & CALL_LONG) == 0)"
11092 {
11093 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11094 output_asm_insn ("crxor 6,6,6", operands);
11095
11096 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11097 output_asm_insn ("creqv 6,6,6", operands);
11098
11099 if (flag_pic == 2)
11100 return "bl %z1+32768@plt";
11101 else
11102 return "bl %z1@plt";
11103 }
11104 [(set_attr "type" "branch,branch")
11105 (set_attr "length" "4,8")])
11106
11107
11108 ;; Call to AIX abi function in the same module.
11109
11110 (define_insn "*call_local_aix<mode>"
11111 [(call (mem:SI (match_operand:P 0 "current_file_function_operand" "s"))
11112 (match_operand 1 "" "g"))
11113 (clobber (reg:P LR_REGNO))]
11114 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11115 "bl %z0"
11116 [(set_attr "type" "branch")
11117 (set_attr "length" "4")])
11118
11119 (define_insn "*call_value_local_aix<mode>"
11120 [(set (match_operand 0 "" "")
11121 (call (mem:SI (match_operand:P 1 "current_file_function_operand" "s"))
11122 (match_operand 2 "" "g")))
11123 (clobber (reg:P LR_REGNO))]
11124 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11125 "bl %z1"
11126 [(set_attr "type" "branch")
11127 (set_attr "length" "4")])
11128
11129 ;; Call to AIX abi function which may be in another module.
11130 ;; Restore the TOC pointer (r2) after the call.
11131
11132 (define_insn "*call_nonlocal_aix<mode>"
11133 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s"))
11134 (match_operand 1 "" "g"))
11135 (clobber (reg:P LR_REGNO))]
11136 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11137 "bl %z0\;nop"
11138 [(set_attr "type" "branch")
11139 (set_attr "length" "8")])
11140
11141 (define_insn "*call_value_nonlocal_aix<mode>"
11142 [(set (match_operand 0 "" "")
11143 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s"))
11144 (match_operand 2 "" "g")))
11145 (clobber (reg:P LR_REGNO))]
11146 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11147 "bl %z1\;nop"
11148 [(set_attr "type" "branch")
11149 (set_attr "length" "8")])
11150
11151 ;; Call to indirect functions with the AIX abi using a 3 word descriptor.
11152 ;; Operand0 is the addresss of the function to call
11153 ;; Operand2 is the location in the function descriptor to load r2 from
11154 ;; Operand3 is the stack location to hold the current TOC pointer
11155
11156 (define_insn "*call_indirect_aix<mode>"
11157 [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
11158 (match_operand 1 "" "g,g"))
11159 (use (match_operand:P 2 "memory_operand" "<ptrm>,<ptrm>"))
11160 (set (reg:P TOC_REGNUM) (match_operand:P 3 "memory_operand" "<ptrm>,<ptrm>"))
11161 (clobber (reg:P LR_REGNO))]
11162 "DEFAULT_ABI == ABI_AIX"
11163 "<ptrload> 2,%2\;b%T0l\;<ptrload> 2,%3"
11164 [(set_attr "type" "jmpreg")
11165 (set_attr "length" "12")])
11166
11167 (define_insn "*call_value_indirect_aix<mode>"
11168 [(set (match_operand 0 "" "")
11169 (call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
11170 (match_operand 2 "" "g,g")))
11171 (use (match_operand:P 3 "memory_operand" "<ptrm>,<ptrm>"))
11172 (set (reg:P TOC_REGNUM) (match_operand:P 4 "memory_operand" "<ptrm>,<ptrm>"))
11173 (clobber (reg:P LR_REGNO))]
11174 "DEFAULT_ABI == ABI_AIX"
11175 "<ptrload> 2,%3\;b%T1l\;<ptrload> 2,%4"
11176 [(set_attr "type" "jmpreg")
11177 (set_attr "length" "12")])
11178
11179 ;; Call to indirect functions with the ELFv2 ABI.
11180 ;; Operand0 is the addresss of the function to call
11181 ;; Operand2 is the stack location to hold the current TOC pointer
11182
11183 (define_insn "*call_indirect_elfv2<mode>"
11184 [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
11185 (match_operand 1 "" "g,g"))
11186 (set (reg:P TOC_REGNUM) (match_operand:P 2 "memory_operand" "<ptrm>,<ptrm>"))
11187 (clobber (reg:P LR_REGNO))]
11188 "DEFAULT_ABI == ABI_ELFv2"
11189 "b%T0l\;<ptrload> 2,%2"
11190 [(set_attr "type" "jmpreg")
11191 (set_attr "length" "8")])
11192
11193 (define_insn "*call_value_indirect_elfv2<mode>"
11194 [(set (match_operand 0 "" "")
11195 (call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
11196 (match_operand 2 "" "g,g")))
11197 (set (reg:P TOC_REGNUM) (match_operand:P 3 "memory_operand" "<ptrm>,<ptrm>"))
11198 (clobber (reg:P LR_REGNO))]
11199 "DEFAULT_ABI == ABI_ELFv2"
11200 "b%T1l\;<ptrload> 2,%3"
11201 [(set_attr "type" "jmpreg")
11202 (set_attr "length" "8")])
11203
11204
11205 ;; Call subroutine returning any type.
11206 (define_expand "untyped_call"
11207 [(parallel [(call (match_operand 0 "" "")
11208 (const_int 0))
11209 (match_operand 1 "" "")
11210 (match_operand 2 "" "")])]
11211 ""
11212 "
11213 {
11214 int i;
11215
11216 emit_call_insn (GEN_CALL (operands[0], const0_rtx, const0_rtx, const0_rtx));
11217
11218 for (i = 0; i < XVECLEN (operands[2], 0); i++)
11219 {
11220 rtx set = XVECEXP (operands[2], 0, i);
11221 emit_move_insn (SET_DEST (set), SET_SRC (set));
11222 }
11223
11224 /* The optimizer does not know that the call sets the function value
11225 registers we stored in the result block. We avoid problems by
11226 claiming that all hard registers are used and clobbered at this
11227 point. */
11228 emit_insn (gen_blockage ());
11229
11230 DONE;
11231 }")
11232
11233 ;; sibling call patterns
11234 (define_expand "sibcall"
11235 [(parallel [(call (mem:SI (match_operand 0 "address_operand" ""))
11236 (match_operand 1 "" ""))
11237 (use (match_operand 2 "" ""))
11238 (use (reg:SI LR_REGNO))
11239 (simple_return)])]
11240 ""
11241 "
11242 {
11243 #if TARGET_MACHO
11244 if (MACHOPIC_INDIRECT)
11245 operands[0] = machopic_indirect_call_target (operands[0]);
11246 #endif
11247
11248 gcc_assert (GET_CODE (operands[0]) == MEM);
11249 gcc_assert (GET_CODE (operands[1]) == CONST_INT);
11250
11251 operands[0] = XEXP (operands[0], 0);
11252
11253 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
11254 {
11255 rs6000_sibcall_aix (NULL_RTX, operands[0], operands[1], operands[2]);
11256 DONE;
11257 }
11258 }")
11259
11260 (define_expand "sibcall_value"
11261 [(parallel [(set (match_operand 0 "register_operand" "")
11262 (call (mem:SI (match_operand 1 "address_operand" ""))
11263 (match_operand 2 "" "")))
11264 (use (match_operand 3 "" ""))
11265 (use (reg:SI LR_REGNO))
11266 (simple_return)])]
11267 ""
11268 "
11269 {
11270 #if TARGET_MACHO
11271 if (MACHOPIC_INDIRECT)
11272 operands[1] = machopic_indirect_call_target (operands[1]);
11273 #endif
11274
11275 gcc_assert (GET_CODE (operands[1]) == MEM);
11276 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
11277
11278 operands[1] = XEXP (operands[1], 0);
11279
11280 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
11281 {
11282 rs6000_sibcall_aix (operands[0], operands[1], operands[2], operands[3]);
11283 DONE;
11284 }
11285 }")
11286
11287 ;; this and similar patterns must be marked as using LR, otherwise
11288 ;; dataflow will try to delete the store into it. This is true
11289 ;; even when the actual reg to jump to is in CTR, when LR was
11290 ;; saved and restored around the PIC-setting BCL.
11291 (define_insn "*sibcall_local32"
11292 [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
11293 (match_operand 1 "" "g,g"))
11294 (use (match_operand:SI 2 "immediate_operand" "O,n"))
11295 (use (reg:SI LR_REGNO))
11296 (simple_return)]
11297 "(INTVAL (operands[2]) & CALL_LONG) == 0"
11298 "*
11299 {
11300 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
11301 output_asm_insn (\"crxor 6,6,6\", operands);
11302
11303 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
11304 output_asm_insn (\"creqv 6,6,6\", operands);
11305
11306 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z0@local\" : \"b %z0\";
11307 }"
11308 [(set_attr "type" "branch")
11309 (set_attr "length" "4,8")])
11310
11311 (define_insn "*sibcall_local64"
11312 [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
11313 (match_operand 1 "" "g,g"))
11314 (use (match_operand:SI 2 "immediate_operand" "O,n"))
11315 (use (reg:SI LR_REGNO))
11316 (simple_return)]
11317 "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
11318 "*
11319 {
11320 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
11321 output_asm_insn (\"crxor 6,6,6\", operands);
11322
11323 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
11324 output_asm_insn (\"creqv 6,6,6\", operands);
11325
11326 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z0@local\" : \"b %z0\";
11327 }"
11328 [(set_attr "type" "branch")
11329 (set_attr "length" "4,8")])
11330
11331 (define_insn "*sibcall_value_local32"
11332 [(set (match_operand 0 "" "")
11333 (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
11334 (match_operand 2 "" "g,g")))
11335 (use (match_operand:SI 3 "immediate_operand" "O,n"))
11336 (use (reg:SI LR_REGNO))
11337 (simple_return)]
11338 "(INTVAL (operands[3]) & CALL_LONG) == 0"
11339 "*
11340 {
11341 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11342 output_asm_insn (\"crxor 6,6,6\", operands);
11343
11344 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11345 output_asm_insn (\"creqv 6,6,6\", operands);
11346
11347 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z1@local\" : \"b %z1\";
11348 }"
11349 [(set_attr "type" "branch")
11350 (set_attr "length" "4,8")])
11351
11352 (define_insn "*sibcall_value_local64"
11353 [(set (match_operand 0 "" "")
11354 (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
11355 (match_operand 2 "" "g,g")))
11356 (use (match_operand:SI 3 "immediate_operand" "O,n"))
11357 (use (reg:SI LR_REGNO))
11358 (simple_return)]
11359 "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
11360 "*
11361 {
11362 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11363 output_asm_insn (\"crxor 6,6,6\", operands);
11364
11365 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11366 output_asm_insn (\"creqv 6,6,6\", operands);
11367
11368 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z1@local\" : \"b %z1\";
11369 }"
11370 [(set_attr "type" "branch")
11371 (set_attr "length" "4,8")])
11372
11373 (define_insn "*sibcall_nonlocal_sysv<mode>"
11374 [(call (mem:SI (match_operand:P 0 "call_operand" "s,s,c,c"))
11375 (match_operand 1 "" ""))
11376 (use (match_operand 2 "immediate_operand" "O,n,O,n"))
11377 (use (reg:SI LR_REGNO))
11378 (simple_return)]
11379 "(DEFAULT_ABI == ABI_DARWIN
11380 || DEFAULT_ABI == ABI_V4)
11381 && (INTVAL (operands[2]) & CALL_LONG) == 0"
11382 "*
11383 {
11384 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
11385 output_asm_insn (\"crxor 6,6,6\", operands);
11386
11387 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
11388 output_asm_insn (\"creqv 6,6,6\", operands);
11389
11390 if (which_alternative >= 2)
11391 return \"b%T0\";
11392 else if (DEFAULT_ABI == ABI_V4 && flag_pic)
11393 {
11394 gcc_assert (!TARGET_SECURE_PLT);
11395 return \"b %z0@plt\";
11396 }
11397 else
11398 return \"b %z0\";
11399 }"
11400 [(set_attr "type" "branch")
11401 (set_attr "length" "4,8,4,8")])
11402
11403 (define_insn "*sibcall_value_nonlocal_sysv<mode>"
11404 [(set (match_operand 0 "" "")
11405 (call (mem:SI (match_operand:P 1 "call_operand" "s,s,c,c"))
11406 (match_operand 2 "" "")))
11407 (use (match_operand:SI 3 "immediate_operand" "O,n,O,n"))
11408 (use (reg:SI LR_REGNO))
11409 (simple_return)]
11410 "(DEFAULT_ABI == ABI_DARWIN
11411 || DEFAULT_ABI == ABI_V4)
11412 && (INTVAL (operands[3]) & CALL_LONG) == 0"
11413 "*
11414 {
11415 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11416 output_asm_insn (\"crxor 6,6,6\", operands);
11417
11418 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11419 output_asm_insn (\"creqv 6,6,6\", operands);
11420
11421 if (which_alternative >= 2)
11422 return \"b%T1\";
11423 else if (DEFAULT_ABI == ABI_V4 && flag_pic)
11424 {
11425 gcc_assert (!TARGET_SECURE_PLT);
11426 return \"b %z1@plt\";
11427 }
11428 else
11429 return \"b %z1\";
11430 }"
11431 [(set_attr "type" "branch")
11432 (set_attr "length" "4,8,4,8")])
11433
11434 ;; AIX ABI sibling call patterns.
11435
11436 (define_insn "*sibcall_aix<mode>"
11437 [(call (mem:SI (match_operand:P 0 "call_operand" "s,c"))
11438 (match_operand 1 "" "g,g"))
11439 (simple_return)]
11440 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11441 "@
11442 b %z0
11443 b%T0"
11444 [(set_attr "type" "branch")
11445 (set_attr "length" "4")])
11446
11447 (define_insn "*sibcall_value_aix<mode>"
11448 [(set (match_operand 0 "" "")
11449 (call (mem:SI (match_operand:P 1 "call_operand" "s,c"))
11450 (match_operand 2 "" "g,g")))
11451 (simple_return)]
11452 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11453 "@
11454 b %z1
11455 b%T1"
11456 [(set_attr "type" "branch")
11457 (set_attr "length" "4")])
11458
11459 (define_expand "sibcall_epilogue"
11460 [(use (const_int 0))]
11461 ""
11462 {
11463 if (!TARGET_SCHED_PROLOG)
11464 emit_insn (gen_blockage ());
11465 rs6000_emit_epilogue (TRUE);
11466 DONE;
11467 })
11468
11469 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11470 ;; all of memory. This blocks insns from being moved across this point.
11471
11472 (define_insn "blockage"
11473 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCK)]
11474 ""
11475 "")
11476
11477 (define_expand "probe_stack"
11478 [(set (match_operand 0 "memory_operand" "=m")
11479 (unspec [(const_int 0)] UNSPEC_PROBE_STACK))]
11480 ""
11481 {
11482 if (TARGET_64BIT)
11483 emit_insn (gen_probe_stack_di (operands[0]));
11484 else
11485 emit_insn (gen_probe_stack_si (operands[0]));
11486 DONE;
11487 })
11488
11489 (define_insn "probe_stack_<mode>"
11490 [(set (match_operand:P 0 "memory_operand" "=m")
11491 (unspec:P [(const_int 0)] UNSPEC_PROBE_STACK))]
11492 ""
11493 {
11494 operands[1] = gen_rtx_REG (Pmode, 0);
11495 return "st<wd>%U0%X0 %1,%0";
11496 }
11497 [(set_attr "type" "store")
11498 (set (attr "update")
11499 (if_then_else (match_operand 0 "update_address_mem")
11500 (const_string "yes")
11501 (const_string "no")))
11502 (set (attr "indexed")
11503 (if_then_else (match_operand 0 "indexed_address_mem")
11504 (const_string "yes")
11505 (const_string "no")))
11506 (set_attr "length" "4")])
11507
11508 (define_insn "probe_stack_range<P:mode>"
11509 [(set (match_operand:P 0 "register_operand" "=r")
11510 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
11511 (match_operand:P 2 "register_operand" "r")]
11512 UNSPECV_PROBE_STACK_RANGE))]
11513 ""
11514 "* return output_probe_stack_range (operands[0], operands[2]);"
11515 [(set_attr "type" "three")])
11516 \f
11517 ;; Compare insns are next. Note that the RS/6000 has two types of compares,
11518 ;; signed & unsigned, and one type of branch.
11519 ;;
11520 ;; Start with the DEFINE_EXPANDs to generate the rtl for compares, scc
11521 ;; insns, and branches.
11522
11523 (define_expand "cbranch<mode>4"
11524 [(use (match_operator 0 "rs6000_cbranch_operator"
11525 [(match_operand:GPR 1 "gpc_reg_operand" "")
11526 (match_operand:GPR 2 "reg_or_short_operand" "")]))
11527 (use (match_operand 3 ""))]
11528 ""
11529 "
11530 {
11531 /* Take care of the possibility that operands[2] might be negative but
11532 this might be a logical operation. That insn doesn't exist. */
11533 if (GET_CODE (operands[2]) == CONST_INT
11534 && INTVAL (operands[2]) < 0)
11535 {
11536 operands[2] = force_reg (<MODE>mode, operands[2]);
11537 operands[0] = gen_rtx_fmt_ee (GET_CODE (operands[0]),
11538 GET_MODE (operands[0]),
11539 operands[1], operands[2]);
11540 }
11541
11542 rs6000_emit_cbranch (<MODE>mode, operands);
11543 DONE;
11544 }")
11545
11546 (define_expand "cbranch<mode>4"
11547 [(use (match_operator 0 "rs6000_cbranch_operator"
11548 [(match_operand:FP 1 "gpc_reg_operand" "")
11549 (match_operand:FP 2 "gpc_reg_operand" "")]))
11550 (use (match_operand 3 ""))]
11551 ""
11552 "
11553 {
11554 rs6000_emit_cbranch (<MODE>mode, operands);
11555 DONE;
11556 }")
11557
11558 (define_expand "cstore<mode>4"
11559 [(use (match_operator 1 "rs6000_cbranch_operator"
11560 [(match_operand:GPR 2 "gpc_reg_operand" "")
11561 (match_operand:GPR 3 "reg_or_short_operand" "")]))
11562 (clobber (match_operand:SI 0 "register_operand"))]
11563 ""
11564 "
11565 {
11566 /* Take care of the possibility that operands[3] might be negative but
11567 this might be a logical operation. That insn doesn't exist. */
11568 if (GET_CODE (operands[3]) == CONST_INT
11569 && INTVAL (operands[3]) < 0)
11570 {
11571 operands[3] = force_reg (<MODE>mode, operands[3]);
11572 operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]),
11573 GET_MODE (operands[1]),
11574 operands[2], operands[3]);
11575 }
11576
11577 /* For SNE, we would prefer that the xor/abs sequence be used for integers.
11578 For SEQ, likewise, except that comparisons with zero should be done
11579 with an scc insns. However, due to the order that combine see the
11580 resulting insns, we must, in fact, allow SEQ for integers. Fail in
11581 the cases we don't want to handle or are best handled by portable
11582 code. */
11583 if (GET_CODE (operands[1]) == NE)
11584 FAIL;
11585 if ((GET_CODE (operands[1]) == LT || GET_CODE (operands[1]) == LE
11586 || GET_CODE (operands[1]) == GT || GET_CODE (operands[1]) == GE)
11587 && operands[3] == const0_rtx)
11588 FAIL;
11589 rs6000_emit_sCOND (<MODE>mode, operands);
11590 DONE;
11591 }")
11592
11593 (define_expand "cstore<mode>4"
11594 [(use (match_operator 1 "rs6000_cbranch_operator"
11595 [(match_operand:FP 2 "gpc_reg_operand" "")
11596 (match_operand:FP 3 "gpc_reg_operand" "")]))
11597 (clobber (match_operand:SI 0 "register_operand"))]
11598 ""
11599 "
11600 {
11601 rs6000_emit_sCOND (<MODE>mode, operands);
11602 DONE;
11603 }")
11604
11605
11606 (define_expand "stack_protect_set"
11607 [(match_operand 0 "memory_operand" "")
11608 (match_operand 1 "memory_operand" "")]
11609 ""
11610 {
11611 #ifdef TARGET_THREAD_SSP_OFFSET
11612 rtx tlsreg = gen_rtx_REG (Pmode, TARGET_64BIT ? 13 : 2);
11613 rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
11614 operands[1] = gen_rtx_MEM (Pmode, addr);
11615 #endif
11616 if (TARGET_64BIT)
11617 emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
11618 else
11619 emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
11620 DONE;
11621 })
11622
11623 (define_insn "stack_protect_setsi"
11624 [(set (match_operand:SI 0 "memory_operand" "=m")
11625 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
11626 (set (match_scratch:SI 2 "=&r") (const_int 0))]
11627 "TARGET_32BIT"
11628 "lwz%U1%X1 %2,%1\;stw%U0%X0 %2,%0\;li %2,0"
11629 [(set_attr "type" "three")
11630 (set_attr "length" "12")])
11631
11632 (define_insn "stack_protect_setdi"
11633 [(set (match_operand:DI 0 "memory_operand" "=Y")
11634 (unspec:DI [(match_operand:DI 1 "memory_operand" "Y")] UNSPEC_SP_SET))
11635 (set (match_scratch:DI 2 "=&r") (const_int 0))]
11636 "TARGET_64BIT"
11637 "ld%U1%X1 %2,%1\;std%U0%X0 %2,%0\;li %2,0"
11638 [(set_attr "type" "three")
11639 (set_attr "length" "12")])
11640
11641 (define_expand "stack_protect_test"
11642 [(match_operand 0 "memory_operand" "")
11643 (match_operand 1 "memory_operand" "")
11644 (match_operand 2 "" "")]
11645 ""
11646 {
11647 rtx test, op0, op1;
11648 #ifdef TARGET_THREAD_SSP_OFFSET
11649 rtx tlsreg = gen_rtx_REG (Pmode, TARGET_64BIT ? 13 : 2);
11650 rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
11651 operands[1] = gen_rtx_MEM (Pmode, addr);
11652 #endif
11653 op0 = operands[0];
11654 op1 = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, operands[1]), UNSPEC_SP_TEST);
11655 test = gen_rtx_EQ (VOIDmode, op0, op1);
11656 emit_jump_insn (gen_cbranchsi4 (test, op0, op1, operands[2]));
11657 DONE;
11658 })
11659
11660 (define_insn "stack_protect_testsi"
11661 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
11662 (unspec:CCEQ [(match_operand:SI 1 "memory_operand" "m,m")
11663 (match_operand:SI 2 "memory_operand" "m,m")]
11664 UNSPEC_SP_TEST))
11665 (set (match_scratch:SI 4 "=r,r") (const_int 0))
11666 (clobber (match_scratch:SI 3 "=&r,&r"))]
11667 "TARGET_32BIT"
11668 "@
11669 lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0
11670 lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;cmplw %0,%3,%4\;li %3,0\;li %4,0"
11671 [(set_attr "length" "16,20")])
11672
11673 (define_insn "stack_protect_testdi"
11674 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
11675 (unspec:CCEQ [(match_operand:DI 1 "memory_operand" "Y,Y")
11676 (match_operand:DI 2 "memory_operand" "Y,Y")]
11677 UNSPEC_SP_TEST))
11678 (set (match_scratch:DI 4 "=r,r") (const_int 0))
11679 (clobber (match_scratch:DI 3 "=&r,&r"))]
11680 "TARGET_64BIT"
11681 "@
11682 ld%U1%X1 %3,%1\;ld%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0
11683 ld%U1%X1 %3,%1\;ld%U2%X2 %4,%2\;cmpld %0,%3,%4\;li %3,0\;li %4,0"
11684 [(set_attr "length" "16,20")])
11685
11686 \f
11687 ;; Here are the actual compare insns.
11688 (define_insn "*cmp<mode>_internal1"
11689 [(set (match_operand:CC 0 "cc_reg_operand" "=y")
11690 (compare:CC (match_operand:GPR 1 "gpc_reg_operand" "r")
11691 (match_operand:GPR 2 "reg_or_short_operand" "rI")))]
11692 ""
11693 "cmp<wd>%I2 %0,%1,%2"
11694 [(set_attr "type" "cmp")])
11695
11696 ;; If we are comparing a register for equality with a large constant,
11697 ;; we can do this with an XOR followed by a compare. But this is profitable
11698 ;; only if the large constant is only used for the comparison (and in this
11699 ;; case we already have a register to reuse as scratch).
11700 ;;
11701 ;; For 64-bit registers, we could only do so if the constant's bit 15 is clear:
11702 ;; otherwise we'd need to XOR with FFFFFFFF????0000 which is not available.
11703
11704 (define_peephole2
11705 [(set (match_operand:SI 0 "register_operand")
11706 (match_operand:SI 1 "logical_const_operand" ""))
11707 (set (match_dup 0) (match_operator:SI 3 "boolean_or_operator"
11708 [(match_dup 0)
11709 (match_operand:SI 2 "logical_const_operand" "")]))
11710 (set (match_operand:CC 4 "cc_reg_operand" "")
11711 (compare:CC (match_operand:SI 5 "gpc_reg_operand" "")
11712 (match_dup 0)))
11713 (set (pc)
11714 (if_then_else (match_operator 6 "equality_operator"
11715 [(match_dup 4) (const_int 0)])
11716 (match_operand 7 "" "")
11717 (match_operand 8 "" "")))]
11718 "peep2_reg_dead_p (3, operands[0])
11719 && peep2_reg_dead_p (4, operands[4])"
11720 [(set (match_dup 0) (xor:SI (match_dup 5) (match_dup 9)))
11721 (set (match_dup 4) (compare:CC (match_dup 0) (match_dup 10)))
11722 (set (pc) (if_then_else (match_dup 6) (match_dup 7) (match_dup 8)))]
11723
11724 {
11725 /* Get the constant we are comparing against, and see what it looks like
11726 when sign-extended from 16 to 32 bits. Then see what constant we could
11727 XOR with SEXTC to get the sign-extended value. */
11728 rtx cnst = simplify_const_binary_operation (GET_CODE (operands[3]),
11729 SImode,
11730 operands[1], operands[2]);
11731 HOST_WIDE_INT c = INTVAL (cnst);
11732 HOST_WIDE_INT sextc = ((c & 0xffff) ^ 0x8000) - 0x8000;
11733 HOST_WIDE_INT xorv = c ^ sextc;
11734
11735 operands[9] = GEN_INT (xorv);
11736 operands[10] = GEN_INT (sextc);
11737 })
11738
11739 (define_insn "*cmpsi_internal2"
11740 [(set (match_operand:CCUNS 0 "cc_reg_operand" "=y")
11741 (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "r")
11742 (match_operand:SI 2 "reg_or_u_short_operand" "rK")))]
11743 ""
11744 "cmplw%I2 %0,%1,%b2"
11745 [(set_attr "type" "cmp")])
11746
11747 (define_insn "*cmpdi_internal2"
11748 [(set (match_operand:CCUNS 0 "cc_reg_operand" "=y")
11749 (compare:CCUNS (match_operand:DI 1 "gpc_reg_operand" "r")
11750 (match_operand:DI 2 "reg_or_u_short_operand" "rK")))]
11751 ""
11752 "cmpld%I2 %0,%1,%b2"
11753 [(set_attr "type" "cmp")])
11754
11755 ;; The following two insns don't exist as single insns, but if we provide
11756 ;; them, we can swap an add and compare, which will enable us to overlap more
11757 ;; of the required delay between a compare and branch. We generate code for
11758 ;; them by splitting.
11759
11760 (define_insn ""
11761 [(set (match_operand:CC 3 "cc_reg_operand" "=y")
11762 (compare:CC (match_operand:SI 1 "gpc_reg_operand" "r")
11763 (match_operand:SI 2 "short_cint_operand" "i")))
11764 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
11765 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "i")))]
11766 ""
11767 "#"
11768 [(set_attr "length" "8")])
11769
11770 (define_insn ""
11771 [(set (match_operand:CCUNS 3 "cc_reg_operand" "=y")
11772 (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "r")
11773 (match_operand:SI 2 "u_short_cint_operand" "i")))
11774 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
11775 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "i")))]
11776 ""
11777 "#"
11778 [(set_attr "length" "8")])
11779
11780 (define_split
11781 [(set (match_operand:CC 3 "cc_reg_operand" "")
11782 (compare:CC (match_operand:SI 1 "gpc_reg_operand" "")
11783 (match_operand:SI 2 "short_cint_operand" "")))
11784 (set (match_operand:SI 0 "gpc_reg_operand" "")
11785 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "")))]
11786 ""
11787 [(set (match_dup 3) (compare:CC (match_dup 1) (match_dup 2)))
11788 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 4)))])
11789
11790 (define_split
11791 [(set (match_operand:CCUNS 3 "cc_reg_operand" "")
11792 (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "")
11793 (match_operand:SI 2 "u_short_cint_operand" "")))
11794 (set (match_operand:SI 0 "gpc_reg_operand" "")
11795 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "")))]
11796 ""
11797 [(set (match_dup 3) (compare:CCUNS (match_dup 1) (match_dup 2)))
11798 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 4)))])
11799
11800 ;; Only need to compare second words if first words equal
11801 (define_insn "*cmptf_internal1"
11802 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
11803 (compare:CCFP (match_operand:TF 1 "gpc_reg_operand" "d")
11804 (match_operand:TF 2 "gpc_reg_operand" "d")))]
11805 "!TARGET_IEEEQUAD && !TARGET_XL_COMPAT
11806 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
11807 "fcmpu %0,%1,%2\;bne %0,$+8\;fcmpu %0,%L1,%L2"
11808 [(set_attr "type" "fpcompare")
11809 (set_attr "length" "12")])
11810
11811 (define_insn_and_split "*cmptf_internal2"
11812 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
11813 (compare:CCFP (match_operand:TF 1 "gpc_reg_operand" "d")
11814 (match_operand:TF 2 "gpc_reg_operand" "d")))
11815 (clobber (match_scratch:DF 3 "=d"))
11816 (clobber (match_scratch:DF 4 "=d"))
11817 (clobber (match_scratch:DF 5 "=d"))
11818 (clobber (match_scratch:DF 6 "=d"))
11819 (clobber (match_scratch:DF 7 "=d"))
11820 (clobber (match_scratch:DF 8 "=d"))
11821 (clobber (match_scratch:DF 9 "=d"))
11822 (clobber (match_scratch:DF 10 "=d"))
11823 (clobber (match_scratch:GPR 11 "=b"))]
11824 "!TARGET_IEEEQUAD && TARGET_XL_COMPAT
11825 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
11826 "#"
11827 "&& reload_completed"
11828 [(set (match_dup 3) (match_dup 14))
11829 (set (match_dup 4) (match_dup 15))
11830 (set (match_dup 9) (abs:DF (match_dup 5)))
11831 (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 3)))
11832 (set (pc) (if_then_else (ne (match_dup 0) (const_int 0))
11833 (label_ref (match_dup 12))
11834 (pc)))
11835 (set (match_dup 0) (compare:CCFP (match_dup 5) (match_dup 7)))
11836 (set (pc) (label_ref (match_dup 13)))
11837 (match_dup 12)
11838 (set (match_dup 10) (minus:DF (match_dup 5) (match_dup 7)))
11839 (set (match_dup 9) (minus:DF (match_dup 6) (match_dup 8)))
11840 (set (match_dup 9) (plus:DF (match_dup 10) (match_dup 9)))
11841 (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 4)))
11842 (match_dup 13)]
11843 {
11844 REAL_VALUE_TYPE rv;
11845 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
11846 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
11847
11848 operands[5] = simplify_gen_subreg (DFmode, operands[1], TFmode, hi_word);
11849 operands[6] = simplify_gen_subreg (DFmode, operands[1], TFmode, lo_word);
11850 operands[7] = simplify_gen_subreg (DFmode, operands[2], TFmode, hi_word);
11851 operands[8] = simplify_gen_subreg (DFmode, operands[2], TFmode, lo_word);
11852 operands[12] = gen_label_rtx ();
11853 operands[13] = gen_label_rtx ();
11854 real_inf (&rv);
11855 operands[14] = force_const_mem (DFmode,
11856 CONST_DOUBLE_FROM_REAL_VALUE (rv, DFmode));
11857 operands[15] = force_const_mem (DFmode,
11858 CONST_DOUBLE_FROM_REAL_VALUE (dconst0,
11859 DFmode));
11860 if (TARGET_TOC)
11861 {
11862 rtx tocref;
11863 tocref = create_TOC_reference (XEXP (operands[14], 0), operands[11]);
11864 operands[14] = gen_const_mem (DFmode, tocref);
11865 tocref = create_TOC_reference (XEXP (operands[15], 0), operands[11]);
11866 operands[15] = gen_const_mem (DFmode, tocref);
11867 set_mem_alias_set (operands[14], get_TOC_alias_set ());
11868 set_mem_alias_set (operands[15], get_TOC_alias_set ());
11869 }
11870 })
11871 \f
11872 ;; Now we have the scc insns. We can do some combinations because of the
11873 ;; way the machine works.
11874 ;;
11875 ;; Note that this is probably faster if we can put an insn between the
11876 ;; mfcr and rlinm, but this is tricky. Let's leave it for now. In most
11877 ;; cases the insns below which don't use an intermediate CR field will
11878 ;; be used instead.
11879 (define_insn ""
11880 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11881 (match_operator:SI 1 "scc_comparison_operator"
11882 [(match_operand 2 "cc_reg_operand" "y")
11883 (const_int 0)]))]
11884 ""
11885 "mfcr %0%Q2\;rlwinm %0,%0,%J1,1"
11886 [(set (attr "type")
11887 (cond [(match_test "TARGET_MFCRF")
11888 (const_string "mfcrf")
11889 ]
11890 (const_string "mfcr")))
11891 (set_attr "length" "8")])
11892
11893 ;; Same as above, but get the GT bit.
11894 (define_insn "move_from_CR_gt_bit"
11895 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11896 (unspec:SI [(match_operand 1 "cc_reg_operand" "y")] UNSPEC_MV_CR_GT))]
11897 "TARGET_HARD_FLOAT && !TARGET_FPRS"
11898 "mfcr %0\;rlwinm %0,%0,%D1,31,31"
11899 [(set_attr "type" "mfcr")
11900 (set_attr "length" "8")])
11901
11902 ;; Same as above, but get the OV/ORDERED bit.
11903 (define_insn "move_from_CR_ov_bit"
11904 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11905 (unspec:SI [(match_operand:CC 1 "cc_reg_operand" "y")]
11906 UNSPEC_MV_CR_OV))]
11907 "TARGET_ISEL"
11908 "mfcr %0\;rlwinm %0,%0,%t1,1"
11909 [(set_attr "type" "mfcr")
11910 (set_attr "length" "8")])
11911
11912 (define_insn ""
11913 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
11914 (match_operator:DI 1 "scc_comparison_operator"
11915 [(match_operand 2 "cc_reg_operand" "y")
11916 (const_int 0)]))]
11917 "TARGET_POWERPC64"
11918 "mfcr %0%Q2\;rlwinm %0,%0,%J1,1"
11919 [(set (attr "type")
11920 (cond [(match_test "TARGET_MFCRF")
11921 (const_string "mfcrf")
11922 ]
11923 (const_string "mfcr")))
11924 (set_attr "length" "8")])
11925
11926 (define_insn ""
11927 [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
11928 (compare:CC (match_operator:SI 1 "scc_comparison_operator"
11929 [(match_operand 2 "cc_reg_operand" "y,y")
11930 (const_int 0)])
11931 (const_int 0)))
11932 (set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
11933 (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
11934 "TARGET_32BIT"
11935 "@
11936 mfcr %3%Q2\;rlwinm. %3,%3,%J1,1
11937 #"
11938 [(set_attr "type" "shift")
11939 (set_attr "dot" "yes")
11940 (set_attr "length" "8,16")])
11941
11942 (define_split
11943 [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
11944 (compare:CC (match_operator:SI 1 "scc_comparison_operator"
11945 [(match_operand 2 "cc_reg_operand" "")
11946 (const_int 0)])
11947 (const_int 0)))
11948 (set (match_operand:SI 3 "gpc_reg_operand" "")
11949 (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
11950 "TARGET_32BIT && reload_completed"
11951 [(set (match_dup 3)
11952 (match_op_dup 1 [(match_dup 2) (const_int 0)]))
11953 (set (match_dup 0)
11954 (compare:CC (match_dup 3)
11955 (const_int 0)))]
11956 "")
11957
11958 (define_insn ""
11959 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11960 (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
11961 [(match_operand 2 "cc_reg_operand" "y")
11962 (const_int 0)])
11963 (match_operand:SI 3 "const_int_operand" "n")))]
11964 ""
11965 "*
11966 {
11967 int is_bit = ccr_bit (operands[1], 1);
11968 int put_bit = 31 - (INTVAL (operands[3]) & 31);
11969 int count;
11970
11971 if (is_bit >= put_bit)
11972 count = is_bit - put_bit;
11973 else
11974 count = 32 - (put_bit - is_bit);
11975
11976 operands[4] = GEN_INT (count);
11977 operands[5] = GEN_INT (put_bit);
11978
11979 return \"mfcr %0%Q2\;rlwinm %0,%0,%4,%5,%5\";
11980 }"
11981 [(set (attr "type")
11982 (cond [(match_test "TARGET_MFCRF")
11983 (const_string "mfcrf")
11984 ]
11985 (const_string "mfcr")))
11986 (set_attr "length" "8")])
11987
11988 (define_insn ""
11989 [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
11990 (compare:CC
11991 (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
11992 [(match_operand 2 "cc_reg_operand" "y,y")
11993 (const_int 0)])
11994 (match_operand:SI 3 "const_int_operand" "n,n"))
11995 (const_int 0)))
11996 (set (match_operand:SI 4 "gpc_reg_operand" "=r,r")
11997 (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
11998 (match_dup 3)))]
11999 ""
12000 "*
12001 {
12002 int is_bit = ccr_bit (operands[1], 1);
12003 int put_bit = 31 - (INTVAL (operands[3]) & 31);
12004 int count;
12005
12006 /* Force split for non-cc0 compare. */
12007 if (which_alternative == 1)
12008 return \"#\";
12009
12010 if (is_bit >= put_bit)
12011 count = is_bit - put_bit;
12012 else
12013 count = 32 - (put_bit - is_bit);
12014
12015 operands[5] = GEN_INT (count);
12016 operands[6] = GEN_INT (put_bit);
12017
12018 return \"mfcr %4%Q2\;rlwinm. %4,%4,%5,%6,%6\";
12019 }"
12020 [(set_attr "type" "shift")
12021 (set_attr "dot" "yes")
12022 (set_attr "length" "8,16")])
12023
12024 (define_split
12025 [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
12026 (compare:CC
12027 (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
12028 [(match_operand 2 "cc_reg_operand" "")
12029 (const_int 0)])
12030 (match_operand:SI 3 "const_int_operand" ""))
12031 (const_int 0)))
12032 (set (match_operand:SI 4 "gpc_reg_operand" "")
12033 (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
12034 (match_dup 3)))]
12035 "reload_completed"
12036 [(set (match_dup 4)
12037 (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
12038 (match_dup 3)))
12039 (set (match_dup 0)
12040 (compare:CC (match_dup 4)
12041 (const_int 0)))]
12042 "")
12043
12044 ;; There is a 3 cycle delay between consecutive mfcr instructions
12045 ;; so it is useful to combine 2 scc instructions to use only one mfcr.
12046
12047 (define_peephole
12048 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
12049 (match_operator:SI 1 "scc_comparison_operator"
12050 [(match_operand 2 "cc_reg_operand" "y")
12051 (const_int 0)]))
12052 (set (match_operand:SI 3 "gpc_reg_operand" "=r")
12053 (match_operator:SI 4 "scc_comparison_operator"
12054 [(match_operand 5 "cc_reg_operand" "y")
12055 (const_int 0)]))]
12056 "REGNO (operands[2]) != REGNO (operands[5])"
12057 "mfcr %3\;rlwinm %0,%3,%J1,1\;rlwinm %3,%3,%J4,1"
12058 [(set_attr "type" "mfcr")
12059 (set_attr "length" "12")])
12060
12061 (define_peephole
12062 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
12063 (match_operator:DI 1 "scc_comparison_operator"
12064 [(match_operand 2 "cc_reg_operand" "y")
12065 (const_int 0)]))
12066 (set (match_operand:DI 3 "gpc_reg_operand" "=r")
12067 (match_operator:DI 4 "scc_comparison_operator"
12068 [(match_operand 5 "cc_reg_operand" "y")
12069 (const_int 0)]))]
12070 "TARGET_POWERPC64 && REGNO (operands[2]) != REGNO (operands[5])"
12071 "mfcr %3\;rlwinm %0,%3,%J1,1\;rlwinm %3,%3,%J4,1"
12072 [(set_attr "type" "mfcr")
12073 (set_attr "length" "12")])
12074
12075 ;; There are some scc insns that can be done directly, without a compare.
12076 ;; These are faster because they don't involve the communications between
12077 ;; the FXU and branch units. In fact, we will be replacing all of the
12078 ;; integer scc insns here or in the portable methods in emit_store_flag.
12079 ;;
12080 ;; Also support (neg (scc ..)) since that construct is used to replace
12081 ;; branches, (plus (scc ..) ..) since that construct is common and
12082 ;; takes no more insns than scc, and (and (neg (scc ..)) ..) in the
12083 ;; cases where it is no more expensive than (neg (scc ..)).
12084
12085 ;; Have reload force a constant into a register for the simple insns that
12086 ;; otherwise won't accept constants. We do this because it is faster than
12087 ;; the cmp/mfcr sequence we would otherwise generate.
12088
12089 (define_mode_attr scc_eq_op2 [(SI "rKLI")
12090 (DI "rKJI")])
12091
12092 (define_insn_and_split "*eq<mode>"
12093 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
12094 (eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
12095 (match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>")))]
12096 ""
12097 "#"
12098 ""
12099 [(set (match_dup 0)
12100 (clz:GPR (match_dup 3)))
12101 (set (match_dup 0)
12102 (lshiftrt:GPR (match_dup 0) (match_dup 4)))]
12103 {
12104 if (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0)
12105 {
12106 /* Use output operand as intermediate. */
12107 operands[3] = operands[0];
12108
12109 if (logical_operand (operands[2], <MODE>mode))
12110 emit_insn (gen_rtx_SET (VOIDmode, operands[3],
12111 gen_rtx_XOR (<MODE>mode,
12112 operands[1], operands[2])));
12113 else
12114 emit_insn (gen_rtx_SET (VOIDmode, operands[3],
12115 gen_rtx_PLUS (<MODE>mode, operands[1],
12116 negate_rtx (<MODE>mode,
12117 operands[2]))));
12118 }
12119 else
12120 operands[3] = operands[1];
12121
12122 operands[4] = GEN_INT (exact_log2 (GET_MODE_BITSIZE (<MODE>mode)));
12123 })
12124
12125 (define_insn_and_split "*eq<mode>_compare"
12126 [(set (match_operand:CC 3 "cc_reg_operand" "=y")
12127 (compare:CC
12128 (eq:P (match_operand:P 1 "gpc_reg_operand" "=r")
12129 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
12130 (const_int 0)))
12131 (set (match_operand:P 0 "gpc_reg_operand" "=r")
12132 (eq:P (match_dup 1) (match_dup 2)))]
12133 "optimize_size"
12134 "#"
12135 "optimize_size"
12136 [(set (match_dup 0)
12137 (clz:P (match_dup 4)))
12138 (parallel [(set (match_dup 3)
12139 (compare:CC (lshiftrt:P (match_dup 0) (match_dup 5))
12140 (const_int 0)))
12141 (set (match_dup 0)
12142 (lshiftrt:P (match_dup 0) (match_dup 5)))])]
12143 {
12144 if (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0)
12145 {
12146 /* Use output operand as intermediate. */
12147 operands[4] = operands[0];
12148
12149 if (logical_operand (operands[2], <MODE>mode))
12150 emit_insn (gen_rtx_SET (VOIDmode, operands[4],
12151 gen_rtx_XOR (<MODE>mode,
12152 operands[1], operands[2])));
12153 else
12154 emit_insn (gen_rtx_SET (VOIDmode, operands[4],
12155 gen_rtx_PLUS (<MODE>mode, operands[1],
12156 negate_rtx (<MODE>mode,
12157 operands[2]))));
12158 }
12159 else
12160 operands[4] = operands[1];
12161
12162 operands[5] = GEN_INT (exact_log2 (GET_MODE_BITSIZE (<MODE>mode)));
12163 })
12164
12165 ;; We have insns of the form shown by the first define_insn below. If
12166 ;; there is something inside the comparison operation, we must split it.
12167 (define_split
12168 [(set (match_operand:SI 0 "gpc_reg_operand" "")
12169 (plus:SI (match_operator 1 "comparison_operator"
12170 [(match_operand:SI 2 "" "")
12171 (match_operand:SI 3
12172 "reg_or_cint_operand" "")])
12173 (match_operand:SI 4 "gpc_reg_operand" "")))
12174 (clobber (match_operand:SI 5 "register_operand" ""))]
12175 "! gpc_reg_operand (operands[2], SImode)"
12176 [(set (match_dup 5) (match_dup 2))
12177 (set (match_dup 0) (plus:SI (match_op_dup 1 [(match_dup 5) (match_dup 3)])
12178 (match_dup 4)))])
12179
12180 (define_insn "*plus_eqsi"
12181 [(set (match_operand:SI 0 "gpc_reg_operand" "=&r,&r,&r,&r,&r")
12182 (plus:SI (eq:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r")
12183 (match_operand:SI 2 "scc_eq_operand" "r,O,K,L,I"))
12184 (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r,r")))]
12185 "TARGET_32BIT"
12186 "@
12187 xor %0,%1,%2\;subfic %0,%0,0\;addze %0,%3
12188 subfic %0,%1,0\;addze %0,%3
12189 xori %0,%1,%b2\;subfic %0,%0,0\;addze %0,%3
12190 xoris %0,%1,%u2\;subfic %0,%0,0\;addze %0,%3
12191 subfic %0,%1,%2\;subfic %0,%0,0\;addze %0,%3"
12192 [(set_attr "type" "three,two,three,three,three")
12193 (set_attr "length" "12,8,12,12,12")])
12194
12195 (define_insn "*compare_plus_eqsi"
12196 [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,x,x,x,?y,?y,?y,?y,?y")
12197 (compare:CC
12198 (plus:SI
12199 (eq:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r,r,r,r,r,r")
12200 (match_operand:SI 2 "scc_eq_operand" "r,O,K,L,I,r,O,K,L,I"))
12201 (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r,r,r,r,r,r,r"))
12202 (const_int 0)))
12203 (clobber (match_scratch:SI 4 "=&r,&r,&r,&r,&r,&r,&r,&r,&r,&r"))]
12204 "TARGET_32BIT && optimize_size"
12205 "@
12206 xor %4,%1,%2\;subfic %4,%4,0\;addze. %4,%3
12207 subfic %4,%1,0\;addze. %4,%3
12208 xori %4,%1,%b2\;subfic %4,%4,0\;addze. %4,%3
12209 xoris %4,%1,%u2\;subfic %4,%4,0\;addze. %4,%3
12210 subfic %4,%1,%2\;subfic %4,%4,0\;addze. %4,%3
12211 #
12212 #
12213 #
12214 #
12215 #"
12216 [(set_attr "type" "compare")
12217 (set_attr "length" "12,8,12,12,12,16,12,16,16,16")])
12218
12219 (define_split
12220 [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
12221 (compare:CC
12222 (plus:SI
12223 (eq:SI (match_operand:SI 1 "gpc_reg_operand" "")
12224 (match_operand:SI 2 "scc_eq_operand" ""))
12225 (match_operand:SI 3 "gpc_reg_operand" ""))
12226 (const_int 0)))
12227 (clobber (match_scratch:SI 4 ""))]
12228 "TARGET_32BIT && optimize_size && reload_completed"
12229 [(set (match_dup 4)
12230 (plus:SI (eq:SI (match_dup 1)
12231 (match_dup 2))
12232 (match_dup 3)))
12233 (set (match_dup 0)
12234 (compare:CC (match_dup 4)
12235 (const_int 0)))]
12236 "")
12237
12238 (define_insn "*plus_eqsi_compare"
12239 [(set (match_operand:CC 4 "cc_reg_operand" "=x,x,x,x,x,?y,?y,?y,?y,?y")
12240 (compare:CC
12241 (plus:SI
12242 (eq:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r,r,r,r,r,r")
12243 (match_operand:SI 2 "scc_eq_operand" "r,O,K,L,I,r,O,K,L,I"))
12244 (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r,r,r,r,r,r,r"))
12245 (const_int 0)))
12246 (set (match_operand:SI 0 "gpc_reg_operand" "=&r,&r,&r,&r,&r,&r,&r,&r,&r,&r")
12247 (plus:SI (eq:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
12248 "TARGET_32BIT && optimize_size"
12249 "@
12250 xor %0,%1,%2\;subfic %0,%0,0\;addze. %0,%3
12251 subfic %0,%1,0\;addze. %0,%3
12252 xori %0,%1,%b2\;subfic %0,%0,0\;addze. %0,%3
12253 xoris %0,%1,%u2\;subfic %0,%0,0\;addze. %0,%3
12254 subfic %0,%1,%2\;subfic %0,%0,0\;addze. %0,%3
12255 #
12256 #
12257 #
12258 #
12259 #"
12260 [(set_attr "type" "compare")
12261 (set_attr "length" "12,8,12,12,12,16,12,16,16,16")])
12262
12263 (define_split
12264 [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "")
12265 (compare:CC
12266 (plus:SI
12267 (eq:SI (match_operand:SI 1 "gpc_reg_operand" "")
12268 (match_operand:SI 2 "scc_eq_operand" ""))
12269 (match_operand:SI 3 "gpc_reg_operand" ""))
12270 (const_int 0)))
12271 (set (match_operand:SI 0 "gpc_reg_operand" "")
12272 (plus:SI (eq:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
12273 "TARGET_32BIT && optimize_size && reload_completed"
12274 [(set (match_dup 0)
12275 (plus:SI (eq:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
12276 (set (match_dup 4)
12277 (compare:CC (match_dup 0)
12278 (const_int 0)))]
12279 "")
12280
12281 (define_insn "*neg_eq0<mode>"
12282 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12283 (neg:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12284 (const_int 0))))]
12285 ""
12286 "addic %0,%1,-1\;subfe %0,%0,%0"
12287 [(set_attr "type" "two")
12288 (set_attr "length" "8")])
12289
12290 (define_insn_and_split "*neg_eq<mode>"
12291 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12292 (neg:P (eq:P (match_operand:P 1 "gpc_reg_operand" "%r")
12293 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))]
12294 ""
12295 "#"
12296 ""
12297 [(set (match_dup 0) (neg:P (eq:P (match_dup 3) (const_int 0))))]
12298 {
12299 if (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0)
12300 {
12301 /* Use output operand as intermediate. */
12302 operands[3] = operands[0];
12303
12304 if (logical_operand (operands[2], <MODE>mode))
12305 emit_insn (gen_rtx_SET (VOIDmode, operands[3],
12306 gen_rtx_XOR (<MODE>mode,
12307 operands[1], operands[2])));
12308 else
12309 emit_insn (gen_rtx_SET (VOIDmode, operands[3],
12310 gen_rtx_PLUS (<MODE>mode, operands[1],
12311 negate_rtx (<MODE>mode,
12312 operands[2]))));
12313 }
12314 else
12315 operands[3] = operands[1];
12316 })
12317
12318 (define_insn "*ne0_<mode>"
12319 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12320 (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12321 (const_int 0)))
12322 (clobber (match_scratch:P 2 "=&r"))]
12323 "!(TARGET_32BIT && TARGET_ISEL)"
12324 "addic %2,%1,-1\;subfe %0,%2,%1"
12325 [(set_attr "type" "two")
12326 (set_attr "length" "8")])
12327
12328 (define_insn "*plus_ne0_<mode>"
12329 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12330 (plus:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12331 (const_int 0))
12332 (match_operand:P 2 "gpc_reg_operand" "r")))
12333 (clobber (match_scratch:P 3 "=&r"))]
12334 ""
12335 "addic %3,%1,-1\;addze %0,%2"
12336 [(set_attr "type" "two")
12337 (set_attr "length" "8")])
12338
12339 (define_insn "*compare_plus_ne0_<mode>"
12340 [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
12341 (compare:CC (plus:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r,r")
12342 (const_int 0))
12343 (match_operand:P 2 "gpc_reg_operand" "r,r"))
12344 (const_int 0)))
12345 (clobber (match_scratch:P 3 "=&r,&r"))
12346 (clobber (match_scratch:P 4 "=X,&r"))]
12347 ""
12348 "@
12349 addic %3,%1,-1\;addze. %3,%2
12350 #"
12351 [(set_attr "type" "compare")
12352 (set_attr "length" "8,12")])
12353
12354 (define_split
12355 [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
12356 (compare:CC (ne:P (match_operand:SI 1 "gpc_reg_operand" "")
12357 (const_int 0))
12358 (neg:P (match_operand:P 2 "gpc_reg_operand" ""))))
12359 (clobber (match_scratch:P 3 ""))
12360 (clobber (match_scratch:P 4 ""))]
12361 "reload_completed"
12362 [(parallel [(set (match_dup 3)
12363 (plus:P (ne:P (match_dup 1)
12364 (const_int 0))
12365 (match_dup 2)))
12366 (clobber (match_dup 4))])
12367 (set (match_dup 0)
12368 (compare:CC (match_dup 3)
12369 (const_int 0)))]
12370 "")
12371
12372 ; For combine.
12373 (define_insn "*compare_plus_ne0_<mode>_1"
12374 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
12375 (compare:CCEQ (ne:P (match_operand:P 1 "gpc_reg_operand" "r,r")
12376 (const_int 0))
12377 (neg:P (match_operand:P 2 "gpc_reg_operand" "r,r"))))
12378 (clobber (match_scratch:P 3 "=&r,&r"))
12379 (clobber (match_scratch:P 4 "=X,&r"))]
12380 ""
12381 "@
12382 addic %3,%1,-1\;addze. %3,%2
12383 #"
12384 [(set_attr "type" "compare")
12385 (set_attr "length" "8,12")])
12386
12387 (define_split
12388 [(set (match_operand:CCEQ 0 "cc_reg_not_micro_cr0_operand" "")
12389 (compare:CCEQ (ne:P (match_operand:SI 1 "gpc_reg_operand" "")
12390 (const_int 0))
12391 (neg:P (match_operand:P 2 "gpc_reg_operand" ""))))
12392 (clobber (match_scratch:P 3 ""))
12393 (clobber (match_scratch:P 4 ""))]
12394 "reload_completed"
12395 [(parallel [(set (match_dup 3)
12396 (plus:P (ne:P (match_dup 1)
12397 (const_int 0))
12398 (match_dup 2)))
12399 (clobber (match_dup 4))])
12400 (set (match_dup 0)
12401 (compare:CC (match_dup 3)
12402 (const_int 0)))]
12403 "")
12404
12405 (define_insn "*plus_ne0_<mode>_compare"
12406 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
12407 (compare:CC
12408 (plus:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r,r")
12409 (const_int 0))
12410 (match_operand:P 2 "gpc_reg_operand" "r,r"))
12411 (const_int 0)))
12412 (set (match_operand:P 0 "gpc_reg_operand" "=r,r")
12413 (plus:P (ne:P (match_dup 1)
12414 (const_int 0))
12415 (match_dup 2)))
12416 (clobber (match_scratch:P 3 "=&r,&r"))]
12417 ""
12418 "@
12419 addic %3,%1,-1\;addze. %0,%2
12420 #"
12421 [(set_attr "type" "compare")
12422 (set_attr "length" "8,12")])
12423
12424 (define_split
12425 [(set (match_operand:CC 4 "cc_reg_not_micro_cr0_operand" "")
12426 (compare:CC
12427 (plus:P (ne:P (match_operand:P 1 "gpc_reg_operand" "")
12428 (const_int 0))
12429 (match_operand:P 2 "gpc_reg_operand" ""))
12430 (const_int 0)))
12431 (set (match_operand:P 0 "gpc_reg_operand" "")
12432 (plus:P (ne:P (match_dup 1)
12433 (const_int 0))
12434 (match_dup 2)))
12435 (clobber (match_scratch:P 3 ""))]
12436 "reload_completed"
12437 [(parallel [(set (match_dup 0)
12438 (plus:P (ne:P (match_dup 1)
12439 (const_int 0))
12440 (match_dup 2)))
12441 (clobber (match_dup 3))])
12442 (set (match_dup 4)
12443 (compare:CC (match_dup 0)
12444 (const_int 0)))]
12445 "")
12446
12447 (define_insn "*leu<mode>"
12448 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12449 (leu:P (match_operand:P 1 "gpc_reg_operand" "r")
12450 (match_operand:P 2 "reg_or_short_operand" "rI")))]
12451 ""
12452 "subf%I2c %0,%1,%2\;li %0,0\;adde %0,%0,%0"
12453 [(set_attr "type" "three")
12454 (set_attr "length" "12")])
12455
12456 (define_insn "*leu<mode>_compare"
12457 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
12458 (compare:CC
12459 (leu:P (match_operand:P 1 "gpc_reg_operand" "r,r")
12460 (match_operand:P 2 "reg_or_short_operand" "rI,rI"))
12461 (const_int 0)))
12462 (set (match_operand:P 0 "gpc_reg_operand" "=r,r")
12463 (leu:P (match_dup 1) (match_dup 2)))]
12464 ""
12465 "@
12466 subf%I2c %0,%1,%2\;li %0,0\;adde. %0,%0,%0
12467 #"
12468 [(set_attr "type" "compare")
12469 (set_attr "length" "12,16")])
12470
12471 (define_split
12472 [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
12473 (compare:CC
12474 (leu:P (match_operand:P 1 "gpc_reg_operand" "")
12475 (match_operand:P 2 "reg_or_short_operand" ""))
12476 (const_int 0)))
12477 (set (match_operand:P 0 "gpc_reg_operand" "")
12478 (leu:P (match_dup 1) (match_dup 2)))]
12479 "reload_completed"
12480 [(set (match_dup 0)
12481 (leu:P (match_dup 1) (match_dup 2)))
12482 (set (match_dup 3)
12483 (compare:CC (match_dup 0)
12484 (const_int 0)))]
12485 "")
12486
12487 (define_insn "*plus_leu<mode>"
12488 [(set (match_operand:P 0 "gpc_reg_operand" "=&r")
12489 (plus:P (leu:P (match_operand:P 1 "gpc_reg_operand" "r")
12490 (match_operand:P 2 "reg_or_short_operand" "rI"))
12491 (match_operand:P 3 "gpc_reg_operand" "r")))]
12492 ""
12493 "subf%I2c %0,%1,%2\;addze %0,%3"
12494 [(set_attr "type" "two")
12495 (set_attr "length" "8")])
12496
12497 (define_insn ""
12498 [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
12499 (compare:CC
12500 (plus:SI (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
12501 (match_operand:SI 2 "reg_or_short_operand" "rI,rI"))
12502 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
12503 (const_int 0)))
12504 (clobber (match_scratch:SI 4 "=&r,&r"))]
12505 "TARGET_32BIT"
12506 "@
12507 subf%I2c %4,%1,%2\;addze. %4,%3
12508 #"
12509 [(set_attr "type" "compare")
12510 (set_attr "length" "8,12")])
12511
12512 (define_split
12513 [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
12514 (compare:CC
12515 (plus:SI (leu:SI (match_operand:SI 1 "gpc_reg_operand" "")
12516 (match_operand:SI 2 "reg_or_short_operand" ""))
12517 (match_operand:SI 3 "gpc_reg_operand" ""))
12518 (const_int 0)))
12519 (clobber (match_scratch:SI 4 ""))]
12520 "TARGET_32BIT && reload_completed"
12521 [(set (match_dup 4)
12522 (plus:SI (leu:SI (match_dup 1) (match_dup 2))
12523 (match_dup 3)))
12524 (set (match_dup 0)
12525 (compare:CC (match_dup 4)
12526 (const_int 0)))]
12527 "")
12528
12529 (define_insn ""
12530 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
12531 (compare:CC
12532 (plus:SI (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
12533 (match_operand:SI 2 "reg_or_short_operand" "rI,rI"))
12534 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
12535 (const_int 0)))
12536 (set (match_operand:SI 0 "gpc_reg_operand" "=&r,&r")
12537 (plus:SI (leu:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
12538 "TARGET_32BIT"
12539 "@
12540 subf%I2c %0,%1,%2\;addze. %0,%3
12541 #"
12542 [(set_attr "type" "compare")
12543 (set_attr "length" "8,12")])
12544
12545 (define_split
12546 [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "")
12547 (compare:CC
12548 (plus:SI (leu:SI (match_operand:SI 1 "gpc_reg_operand" "")
12549 (match_operand:SI 2 "reg_or_short_operand" ""))
12550 (match_operand:SI 3 "gpc_reg_operand" ""))
12551 (const_int 0)))
12552 (set (match_operand:SI 0 "gpc_reg_operand" "")
12553 (plus:SI (leu:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
12554 "TARGET_32BIT && reload_completed"
12555 [(set (match_dup 0)
12556 (plus:SI (leu:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
12557 (set (match_dup 4)
12558 (compare:CC (match_dup 0)
12559 (const_int 0)))]
12560 "")
12561
12562 (define_insn "*neg_leu<mode>"
12563 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12564 (neg:P (leu:P (match_operand:P 1 "gpc_reg_operand" "r")
12565 (match_operand:P 2 "reg_or_short_operand" "rI"))))]
12566 ""
12567 "subf%I2c %0,%1,%2\;subfe %0,%0,%0\;nand %0,%0,%0"
12568 [(set_attr "type" "three")
12569 (set_attr "length" "12")])
12570
12571 (define_insn "*and_neg_leu<mode>"
12572 [(set (match_operand:P 0 "gpc_reg_operand" "=&r")
12573 (and:P (neg:P
12574 (leu:P (match_operand:P 1 "gpc_reg_operand" "r")
12575 (match_operand:P 2 "reg_or_short_operand" "rI")))
12576 (match_operand:P 3 "gpc_reg_operand" "r")))]
12577 ""
12578 "subf%I2c %0,%1,%2\;subfe %0,%0,%0\;andc %0,%3,%0"
12579 [(set_attr "type" "three")
12580 (set_attr "length" "12")])
12581
12582 (define_insn ""
12583 [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
12584 (compare:CC
12585 (and:SI (neg:SI
12586 (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
12587 (match_operand:SI 2 "reg_or_short_operand" "rI,rI")))
12588 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
12589 (const_int 0)))
12590 (clobber (match_scratch:SI 4 "=&r,&r"))]
12591 "TARGET_32BIT"
12592 "@
12593 subf%I2c %4,%1,%2\;subfe %4,%4,%4\;andc. %4,%3,%4
12594 #"
12595 [(set_attr "type" "compare")
12596 (set_attr "length" "12,16")])
12597
12598 (define_split
12599 [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
12600 (compare:CC
12601 (and:SI (neg:SI
12602 (leu:SI (match_operand:SI 1 "gpc_reg_operand" "")
12603 (match_operand:SI 2 "reg_or_short_operand" "")))
12604 (match_operand:SI 3 "gpc_reg_operand" ""))
12605 (const_int 0)))
12606 (clobber (match_scratch:SI 4 ""))]
12607 "TARGET_32BIT && reload_completed"
12608 [(set (match_dup 4)
12609 (and:SI (neg:SI (leu:SI (match_dup 1) (match_dup 2)))
12610 (match_dup 3)))
12611 (set (match_dup 0)
12612 (compare:CC (match_dup 4)
12613 (const_int 0)))]
12614 "")
12615
12616 (define_insn ""
12617 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
12618 (compare:CC
12619 (and:SI (neg:SI
12620 (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
12621 (match_operand:SI 2 "reg_or_short_operand" "rI,rI")))
12622 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
12623 (const_int 0)))
12624 (set (match_operand:SI 0 "gpc_reg_operand" "=&r,&r")
12625 (and:SI (neg:SI (leu:SI (match_dup 1) (match_dup 2))) (match_dup 3)))]
12626 "TARGET_32BIT"
12627 "@
12628 subf%I2c %0,%1,%2\;subfe %0,%0,%0\;andc. %0,%3,%0
12629 #"
12630 [(set_attr "type" "compare")
12631 (set_attr "length" "12,16")])
12632
12633 (define_split
12634 [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "")
12635 (compare:CC
12636 (and:SI (neg:SI
12637 (leu:SI (match_operand:SI 1 "gpc_reg_operand" "")
12638 (match_operand:SI 2 "reg_or_short_operand" "")))
12639 (match_operand:SI 3 "gpc_reg_operand" ""))
12640 (const_int 0)))
12641 (set (match_operand:SI 0 "gpc_reg_operand" "")
12642 (and:SI (neg:SI (leu:SI (match_dup 1) (match_dup 2))) (match_dup 3)))]
12643 "TARGET_32BIT && reload_completed"
12644 [(set (match_dup 0)
12645 (and:SI (neg:SI (leu:SI (match_dup 1) (match_dup 2)))
12646 (match_dup 3)))
12647 (set (match_dup 4)
12648 (compare:CC (match_dup 0)
12649 (const_int 0)))]
12650 "")
12651
12652 (define_insn_and_split "*ltu<mode>"
12653 [(set (match_operand:P 0 "gpc_reg_operand" "=r,r")
12654 (ltu:P (match_operand:P 1 "gpc_reg_operand" "r,r")
12655 (match_operand:P 2 "reg_or_neg_short_operand" "r,P")))]
12656 ""
12657 "#"
12658 ""
12659 [(set (match_dup 0) (neg:P (ltu:P (match_dup 1) (match_dup 2))))
12660 (set (match_dup 0) (neg:P (match_dup 0)))]
12661 "")
12662
12663 (define_insn_and_split "*ltu<mode>_compare"
12664 [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y")
12665 (compare:CC
12666 (ltu:P (match_operand:P 1 "gpc_reg_operand" "r,r,r,r")
12667 (match_operand:P 2 "reg_or_neg_short_operand" "r,P,r,P"))
12668 (const_int 0)))
12669 (set (match_operand:P 0 "gpc_reg_operand" "=r,r,r,r")
12670 (ltu:P (match_dup 1) (match_dup 2)))]
12671 ""
12672 "#"
12673 ""
12674 [(set (match_dup 0) (neg:P (ltu:P (match_dup 1) (match_dup 2))))
12675 (parallel [(set (match_dup 3)
12676 (compare:CC (neg:P (match_dup 0)) (const_int 0)))
12677 (set (match_dup 0) (neg:P (match_dup 0)))])]
12678 "")
12679
12680 (define_insn_and_split "*plus_ltu<mode>"
12681 [(set (match_operand:P 0 "gpc_reg_operand" "=&r,r")
12682 (plus:P (ltu:P (match_operand:P 1 "gpc_reg_operand" "r,r")
12683 (match_operand:P 2 "reg_or_neg_short_operand" "r,P"))
12684 (match_operand:P 3 "reg_or_short_operand" "rI,rI")))]
12685 ""
12686 "#"
12687 "&& !reg_overlap_mentioned_p (operands[0], operands[3])"
12688 [(set (match_dup 0) (neg:P (ltu:P (match_dup 1) (match_dup 2))))
12689 (set (match_dup 0) (minus:P (match_dup 3) (match_dup 0)))]
12690 "")
12691
12692 (define_insn_and_split "*plus_ltu<mode>_compare"
12693 [(set (match_operand:CC 4 "cc_reg_operand" "=x,x,?y,?y")
12694 (compare:CC
12695 (plus:P (ltu:P (match_operand:P 1 "gpc_reg_operand" "r,r,r,r")
12696 (match_operand:P 2 "reg_or_neg_short_operand" "r,P,r,P"))
12697 (match_operand:P 3 "gpc_reg_operand" "r,r,r,r"))
12698 (const_int 0)))
12699 (set (match_operand:P 0 "gpc_reg_operand" "=&r,&r,&r,&r")
12700 (plus:P (ltu:P (match_dup 1) (match_dup 2)) (match_dup 3)))]
12701 ""
12702 "#"
12703 "&& !reg_overlap_mentioned_p (operands[0], operands[3])"
12704 [(set (match_dup 0) (neg:P (ltu:P (match_dup 1) (match_dup 2))))
12705 (parallel [(set (match_dup 4)
12706 (compare:CC (minus:P (match_dup 3) (match_dup 0))
12707 (const_int 0)))
12708 (set (match_dup 0) (minus:P (match_dup 3) (match_dup 0)))])]
12709 "")
12710
12711 (define_insn "*neg_ltu<mode>"
12712 [(set (match_operand:P 0 "gpc_reg_operand" "=r,r")
12713 (neg:P (ltu:P (match_operand:P 1 "gpc_reg_operand" "r,r")
12714 (match_operand:P 2 "reg_or_neg_short_operand" "r,P"))))]
12715 ""
12716 "@
12717 subfc %0,%2,%1\;subfe %0,%0,%0
12718 addic %0,%1,%n2\;subfe %0,%0,%0"
12719 [(set_attr "type" "two")
12720 (set_attr "length" "8")])
12721
12722 (define_insn "*geu<mode>"
12723 [(set (match_operand:P 0 "gpc_reg_operand" "=r,r")
12724 (geu:P (match_operand:P 1 "gpc_reg_operand" "r,r")
12725 (match_operand:P 2 "reg_or_neg_short_operand" "r,P")))]
12726 ""
12727 "@
12728 subfc %0,%2,%1\;li %0,0\;adde %0,%0,%0
12729 addic %0,%1,%n2\;li %0,0\;adde %0,%0,%0"
12730 [(set_attr "type" "three")
12731 (set_attr "length" "12")])
12732
12733 (define_insn "*geu<mode>_compare"
12734 [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y")
12735 (compare:CC
12736 (geu:P (match_operand:P 1 "gpc_reg_operand" "r,r,r,r")
12737 (match_operand:P 2 "reg_or_neg_short_operand" "r,P,r,P"))
12738 (const_int 0)))
12739 (set (match_operand:P 0 "gpc_reg_operand" "=r,r,r,r")
12740 (geu:P (match_dup 1) (match_dup 2)))]
12741 ""
12742 "@
12743 subfc %0,%2,%1\;li %0,0\;adde. %0,%0,%0
12744 addic %0,%1,%n2\;li %0,0\;adde. %0,%0,%0
12745 #
12746 #"
12747 [(set_attr "type" "compare")
12748 (set_attr "length" "12,12,16,16")])
12749
12750 (define_split
12751 [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "")
12752 (compare:CC
12753 (geu:P (match_operand:P 1 "gpc_reg_operand" "")
12754 (match_operand:P 2 "reg_or_neg_short_operand" ""))
12755 (const_int 0)))
12756 (set (match_operand:P 0 "gpc_reg_operand" "")
12757 (geu:P (match_dup 1) (match_dup 2)))]
12758 "reload_completed"
12759 [(set (match_dup 0)
12760 (geu:P (match_dup 1) (match_dup 2)))
12761 (set (match_dup 3)
12762 (compare:CC (match_dup 0)
12763 (const_int 0)))]
12764 "")
12765
12766 (define_insn "*plus_geu<mode>"
12767 [(set (match_operand:P 0 "gpc_reg_operand" "=&r,&r")
12768 (plus:P (geu:P (match_operand:P 1 "gpc_reg_operand" "r,r")
12769 (match_operand:P 2 "reg_or_neg_short_operand" "r,P"))
12770 (match_operand:P 3 "gpc_reg_operand" "r,r")))]
12771 ""
12772 "@
12773 subfc %0,%2,%1\;addze %0,%3
12774 addic %0,%1,%n2\;addze %0,%3"
12775 [(set_attr "type" "two")
12776 (set_attr "length" "8")])
12777
12778 (define_insn ""
12779 [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y")
12780 (compare:CC
12781 (plus:SI (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r")
12782 (match_operand:SI 2 "reg_or_neg_short_operand" "r,P,r,P"))
12783 (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r"))
12784 (const_int 0)))
12785 (clobber (match_scratch:SI 4 "=&r,&r,&r,&r"))]
12786 "TARGET_32BIT"
12787 "@
12788 subfc %4,%2,%1\;addze. %4,%3
12789 addic %4,%1,%n2\;addze. %4,%3
12790 #
12791 #"
12792 [(set_attr "type" "compare")
12793 (set_attr "length" "8,8,12,12")])
12794
12795 (define_split
12796 [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
12797 (compare:CC
12798 (plus:SI (geu:SI (match_operand:SI 1 "gpc_reg_operand" "")
12799 (match_operand:SI 2 "reg_or_neg_short_operand" ""))
12800 (match_operand:SI 3 "gpc_reg_operand" ""))
12801 (const_int 0)))
12802 (clobber (match_scratch:SI 4 ""))]
12803 "TARGET_32BIT && reload_completed"
12804 [(set (match_dup 4)
12805 (plus:SI (geu:SI (match_dup 1) (match_dup 2))
12806 (match_dup 3)))
12807 (set (match_dup 0)
12808 (compare:CC (match_dup 4)
12809 (const_int 0)))]
12810 "")
12811
12812 (define_insn ""
12813 [(set (match_operand:CC 4 "cc_reg_operand" "=x,x,?y,?y")
12814 (compare:CC
12815 (plus:SI (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r")
12816 (match_operand:SI 2 "reg_or_neg_short_operand" "r,P,r,P"))
12817 (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r"))
12818 (const_int 0)))
12819 (set (match_operand:SI 0 "gpc_reg_operand" "=&r,&r,&r,&r")
12820 (plus:SI (geu:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
12821 "TARGET_32BIT"
12822 "@
12823 subfc %0,%2,%1\;addze. %0,%3
12824 addic %0,%1,%n2\;addze. %0,%3
12825 #
12826 #"
12827 [(set_attr "type" "compare")
12828 (set_attr "length" "8,8,12,12")])
12829
12830 (define_split
12831 [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "")
12832 (compare:CC
12833 (plus:SI (geu:SI (match_operand:SI 1 "gpc_reg_operand" "")
12834 (match_operand:SI 2 "reg_or_neg_short_operand" ""))
12835 (match_operand:SI 3 "gpc_reg_operand" ""))
12836 (const_int 0)))
12837 (set (match_operand:SI 0 "gpc_reg_operand" "")
12838 (plus:SI (geu:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
12839 "TARGET_32BIT && reload_completed"
12840 [(set (match_dup 0)
12841 (plus:SI (geu:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
12842 (set (match_dup 4)
12843 (compare:CC (match_dup 0)
12844 (const_int 0)))]
12845 "")
12846
12847 (define_insn "*neg_geu<mode>"
12848 [(set (match_operand:P 0 "gpc_reg_operand" "=r,r")
12849 (neg:P (geu:P (match_operand:P 1 "gpc_reg_operand" "r,r")
12850 (match_operand:P 2 "reg_or_short_operand" "r,I"))))]
12851 ""
12852 "@
12853 subfc %0,%2,%1\;subfe %0,%0,%0\;nand %0,%0,%0
12854 subfic %0,%1,-1\;add%I2c %0,%0,%2\;subfe %0,%0,%0"
12855 [(set_attr "type" "three")
12856 (set_attr "length" "12")])
12857
12858 (define_insn "*and_neg_geu<mode>"
12859 [(set (match_operand:P 0 "gpc_reg_operand" "=&r,&r")
12860 (and:P (neg:P
12861 (geu:P (match_operand:P 1 "gpc_reg_operand" "r,r")
12862 (match_operand:P 2 "reg_or_neg_short_operand" "r,P")))
12863 (match_operand:P 3 "gpc_reg_operand" "r,r")))]
12864 ""
12865 "@
12866 subfc %0,%2,%1\;subfe %0,%0,%0\;andc %0,%3,%0
12867 addic %0,%1,%n2\;subfe %0,%0,%0\;andc %0,%3,%0"
12868 [(set_attr "type" "three")
12869 (set_attr "length" "12")])
12870
12871 (define_insn ""
12872 [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y")
12873 (compare:CC
12874 (and:SI (neg:SI
12875 (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r")
12876 (match_operand:SI 2 "reg_or_neg_short_operand" "r,P,r,P")))
12877 (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r"))
12878 (const_int 0)))
12879 (clobber (match_scratch:SI 4 "=&r,&r,&r,&r"))]
12880 "TARGET_32BIT"
12881 "@
12882 subfc %4,%2,%1\;subfe %4,%4,%4\;andc. %4,%3,%4
12883 addic %4,%1,%n2\;subfe %4,%4,%4\;andc. %4,%3,%4
12884 #
12885 #"
12886 [(set_attr "type" "compare")
12887 (set_attr "length" "12,12,16,16")])
12888
12889 (define_split
12890 [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
12891 (compare:CC
12892 (and:SI (neg:SI
12893 (geu:SI (match_operand:SI 1 "gpc_reg_operand" "")
12894 (match_operand:SI 2 "reg_or_neg_short_operand" "")))
12895 (match_operand:SI 3 "gpc_reg_operand" ""))
12896 (const_int 0)))
12897 (clobber (match_scratch:SI 4 ""))]
12898 "TARGET_32BIT && reload_completed"
12899 [(set (match_dup 4)
12900 (and:SI (neg:SI (geu:SI (match_dup 1) (match_dup 2)))
12901 (match_dup 3)))
12902 (set (match_dup 0)
12903 (compare:CC (match_dup 4)
12904 (const_int 0)))]
12905 "")
12906
12907 (define_insn ""
12908 [(set (match_operand:CC 4 "cc_reg_operand" "=x,x,?y,?y")
12909 (compare:CC
12910 (and:SI (neg:SI
12911 (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r")
12912 (match_operand:SI 2 "reg_or_neg_short_operand" "r,P,r,P")))
12913 (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r"))
12914 (const_int 0)))
12915 (set (match_operand:SI 0 "gpc_reg_operand" "=&r,&r,&r,&r")
12916 (and:SI (neg:SI (geu:SI (match_dup 1) (match_dup 2))) (match_dup 3)))]
12917 "TARGET_32BIT"
12918 "@
12919 subfc %0,%2,%1\;subfe %0,%0,%0\;andc. %0,%3,%0
12920 addic %0,%1,%n2\;subfe %0,%0,%0\;andc. %0,%3,%0
12921 #
12922 #"
12923 [(set_attr "type" "compare")
12924 (set_attr "length" "12,12,16,16")])
12925
12926 (define_split
12927 [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "")
12928 (compare:CC
12929 (and:SI (neg:SI
12930 (geu:SI (match_operand:SI 1 "gpc_reg_operand" "")
12931 (match_operand:SI 2 "reg_or_neg_short_operand" "")))
12932 (match_operand:SI 3 "gpc_reg_operand" ""))
12933 (const_int 0)))
12934 (set (match_operand:SI 0 "gpc_reg_operand" "")
12935 (and:SI (neg:SI (geu:SI (match_dup 1) (match_dup 2))) (match_dup 3)))]
12936 "TARGET_32BIT && reload_completed"
12937 [(set (match_dup 0)
12938 (and:SI (neg:SI (geu:SI (match_dup 1) (match_dup 2))) (match_dup 3)))
12939 (set (match_dup 4)
12940 (compare:CC (match_dup 0)
12941 (const_int 0)))]
12942 "")
12943
12944 (define_insn "*plus_gt0<mode>"
12945 [(set (match_operand:P 0 "gpc_reg_operand" "=&r")
12946 (plus:P (gt:P (match_operand:P 1 "gpc_reg_operand" "r")
12947 (const_int 0))
12948 (match_operand:P 2 "gpc_reg_operand" "r")))]
12949 ""
12950 "addc %0,%1,%1\;subfe %0,%1,%0\;addze %0,%2"
12951 [(set_attr "type" "three")
12952 (set_attr "length" "12")])
12953
12954 (define_insn ""
12955 [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
12956 (compare:CC
12957 (plus:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
12958 (const_int 0))
12959 (match_operand:SI 2 "gpc_reg_operand" "r,r"))
12960 (const_int 0)))
12961 (clobber (match_scratch:SI 3 "=&r,&r"))]
12962 "TARGET_32BIT"
12963 "@
12964 addc %3,%1,%1\;subfe %3,%1,%3\;addze. %3,%2
12965 #"
12966 [(set_attr "type" "compare")
12967 (set_attr "length" "12,16")])
12968
12969 (define_split
12970 [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
12971 (compare:CC
12972 (plus:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "")
12973 (const_int 0))
12974 (match_operand:SI 2 "gpc_reg_operand" ""))
12975 (const_int 0)))
12976 (clobber (match_scratch:SI 3 ""))]
12977 "TARGET_32BIT && reload_completed"
12978 [(set (match_dup 3)
12979 (plus:SI (gt:SI (match_dup 1) (const_int 0))
12980 (match_dup 2)))
12981 (set (match_dup 0)
12982 (compare:CC (match_dup 3)
12983 (const_int 0)))]
12984 "")
12985
12986 (define_insn ""
12987 [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
12988 (compare:CC
12989 (plus:DI (gt:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
12990 (const_int 0))
12991 (match_operand:DI 2 "gpc_reg_operand" "r,r"))
12992 (const_int 0)))
12993 (clobber (match_scratch:DI 3 "=&r,&r"))]
12994 "TARGET_64BIT"
12995 "@
12996 addc %3,%1,%1\;subfe %3,%1,%3\;addze. %3,%2
12997 #"
12998 [(set_attr "type" "compare")
12999 (set_attr "length" "12,16")])
13000
13001 (define_split
13002 [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
13003 (compare:CC
13004 (plus:DI (gt:DI (match_operand:DI 1 "gpc_reg_operand" "")
13005 (const_int 0))
13006 (match_operand:DI 2 "gpc_reg_operand" ""))
13007 (const_int 0)))
13008 (clobber (match_scratch:DI 3 ""))]
13009 "TARGET_64BIT && reload_completed"
13010 [(set (match_dup 3)
13011 (plus:DI (gt:DI (match_dup 1) (const_int 0))
13012 (match_dup 2)))
13013 (set (match_dup 0)
13014 (compare:CC (match_dup 3)
13015 (const_int 0)))]
13016 "")
13017
13018 (define_insn ""
13019 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
13020 (compare:CC
13021 (plus:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
13022 (const_int 0))
13023 (match_operand:SI 2 "gpc_reg_operand" "r,r"))
13024 (const_int 0)))
13025 (set (match_operand:SI 0 "gpc_reg_operand" "=&r,&r")
13026 (plus:SI (gt:SI (match_dup 1) (const_int 0)) (match_dup 2)))]
13027 "TARGET_32BIT"
13028 "@
13029 addc %0,%1,%1\;subfe %0,%1,%0\;addze. %0,%2
13030 #"
13031 [(set_attr "type" "compare")
13032 (set_attr "length" "12,16")])
13033
13034 (define_split
13035 [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
13036 (compare:CC
13037 (plus:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "")
13038 (const_int 0))
13039 (match_operand:SI 2 "gpc_reg_operand" ""))
13040 (const_int 0)))
13041 (set (match_operand:SI 0 "gpc_reg_operand" "")
13042 (plus:SI (gt:SI (match_dup 1) (const_int 0)) (match_dup 2)))]
13043 "TARGET_32BIT && reload_completed"
13044 [(set (match_dup 0)
13045 (plus:SI (gt:SI (match_dup 1) (const_int 0)) (match_dup 2)))
13046 (set (match_dup 3)
13047 (compare:CC (match_dup 0)
13048 (const_int 0)))]
13049 "")
13050
13051 (define_insn ""
13052 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
13053 (compare:CC
13054 (plus:DI (gt:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
13055 (const_int 0))
13056 (match_operand:DI 2 "gpc_reg_operand" "r,r"))
13057 (const_int 0)))
13058 (set (match_operand:DI 0 "gpc_reg_operand" "=&r,&r")
13059 (plus:DI (gt:DI (match_dup 1) (const_int 0)) (match_dup 2)))]
13060 "TARGET_64BIT"
13061 "@
13062 addc %0,%1,%1\;subfe %0,%1,%0\;addze. %0,%2
13063 #"
13064 [(set_attr "type" "compare")
13065 (set_attr "length" "12,16")])
13066
13067 (define_split
13068 [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "")
13069 (compare:CC
13070 (plus:DI (gt:DI (match_operand:DI 1 "gpc_reg_operand" "")
13071 (const_int 0))
13072 (match_operand:DI 2 "gpc_reg_operand" ""))
13073 (const_int 0)))
13074 (set (match_operand:DI 0 "gpc_reg_operand" "")
13075 (plus:DI (gt:DI (match_dup 1) (const_int 0)) (match_dup 2)))]
13076 "TARGET_64BIT && reload_completed"
13077 [(set (match_dup 0)
13078 (plus:DI (gt:DI (match_dup 1) (const_int 0)) (match_dup 2)))
13079 (set (match_dup 3)
13080 (compare:CC (match_dup 0)
13081 (const_int 0)))]
13082 "")
13083
13084 (define_insn_and_split "*gtu<mode>"
13085 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
13086 (gtu:P (match_operand:P 1 "gpc_reg_operand" "r")
13087 (match_operand:P 2 "reg_or_short_operand" "rI")))]
13088 ""
13089 "#"
13090 ""
13091 [(set (match_dup 0) (neg:P (gtu:P (match_dup 1) (match_dup 2))))
13092 (set (match_dup 0) (neg:P (match_dup 0)))]
13093 "")
13094
13095 (define_insn_and_split "*gtu<mode>_compare"
13096 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
13097 (compare:CC
13098 (gtu:P (match_operand:P 1 "gpc_reg_operand" "r,r")
13099 (match_operand:P 2 "reg_or_short_operand" "rI,rI"))
13100 (const_int 0)))
13101 (set (match_operand:P 0 "gpc_reg_operand" "=r,r")
13102 (gtu:P (match_dup 1) (match_dup 2)))]
13103 ""
13104 "#"
13105 ""
13106 [(set (match_dup 0) (neg:P (gtu:P (match_dup 1) (match_dup 2))))
13107 (parallel [(set (match_dup 3)
13108 (compare:CC (neg:P (match_dup 0)) (const_int 0)))
13109 (set (match_dup 0) (neg:P (match_dup 0)))])]
13110 "")
13111
13112 (define_insn_and_split "*plus_gtu<mode>"
13113 [(set (match_operand:P 0 "gpc_reg_operand" "=&r")
13114 (plus:P (gtu:P (match_operand:P 1 "gpc_reg_operand" "r")
13115 (match_operand:P 2 "reg_or_short_operand" "rI"))
13116 (match_operand:P 3 "reg_or_short_operand" "rI")))]
13117 ""
13118 "#"
13119 "&& !reg_overlap_mentioned_p (operands[0], operands[3])"
13120 [(set (match_dup 0) (neg:P (gtu:P (match_dup 1) (match_dup 2))))
13121 (set (match_dup 0) (minus:P (match_dup 3) (match_dup 0)))]
13122 "")
13123
13124 (define_insn_and_split "*plus_gtu<mode>_compare"
13125 [(set (match_operand:CC 4 "cc_reg_operand" "=x,x,?y,?y")
13126 (compare:CC
13127 (plus:P (gtu:P (match_operand:P 1 "gpc_reg_operand" "r,r,r,r")
13128 (match_operand:P 2 "reg_or_short_operand" "I,r,I,r"))
13129 (match_operand:P 3 "gpc_reg_operand" "r,r,r,r"))
13130 (const_int 0)))
13131 (set (match_operand:P 0 "gpc_reg_operand" "=&r,&r,&r,&r")
13132 (plus:P (gtu:P (match_dup 1) (match_dup 2)) (match_dup 3)))]
13133 ""
13134 "#"
13135 "&& !reg_overlap_mentioned_p (operands[0], operands[3])"
13136 [(set (match_dup 0) (neg:P (gtu:P (match_dup 1) (match_dup 2))))
13137 (parallel [(set (match_dup 4)
13138 (compare:CC (minus:P (match_dup 3) (match_dup 0))
13139 (const_int 0)))
13140 (set (match_dup 0) (minus:P (match_dup 3) (match_dup 0)))])]
13141 "")
13142
13143 (define_insn "*neg_gtu<mode>"
13144 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
13145 (neg:P (gtu:P (match_operand:P 1 "gpc_reg_operand" "r")
13146 (match_operand:P 2 "reg_or_short_operand" "rI"))))]
13147 ""
13148 "subf%I2c %0,%1,%2\;subfe %0,%0,%0"
13149 [(set_attr "type" "two")
13150 (set_attr "length" "8")])
13151
13152 \f
13153 ;; Define both directions of branch and return. If we need a reload
13154 ;; register, we'd rather use CR0 since it is much easier to copy a
13155 ;; register CC value to there.
13156
13157 (define_insn ""
13158 [(set (pc)
13159 (if_then_else (match_operator 1 "branch_comparison_operator"
13160 [(match_operand 2
13161 "cc_reg_operand" "y")
13162 (const_int 0)])
13163 (label_ref (match_operand 0 "" ""))
13164 (pc)))]
13165 ""
13166 "*
13167 {
13168 return output_cbranch (operands[1], \"%l0\", 0, insn);
13169 }"
13170 [(set_attr "type" "branch")])
13171
13172 (define_insn ""
13173 [(set (pc)
13174 (if_then_else (match_operator 0 "branch_comparison_operator"
13175 [(match_operand 1
13176 "cc_reg_operand" "y")
13177 (const_int 0)])
13178 (any_return)
13179 (pc)))]
13180 "<return_pred>"
13181 "*
13182 {
13183 return output_cbranch (operands[0], NULL, 0, insn);
13184 }"
13185 [(set_attr "type" "jmpreg")
13186 (set_attr "length" "4")])
13187
13188 (define_insn ""
13189 [(set (pc)
13190 (if_then_else (match_operator 1 "branch_comparison_operator"
13191 [(match_operand 2
13192 "cc_reg_operand" "y")
13193 (const_int 0)])
13194 (pc)
13195 (label_ref (match_operand 0 "" ""))))]
13196 ""
13197 "*
13198 {
13199 return output_cbranch (operands[1], \"%l0\", 1, insn);
13200 }"
13201 [(set_attr "type" "branch")])
13202
13203 (define_insn ""
13204 [(set (pc)
13205 (if_then_else (match_operator 0 "branch_comparison_operator"
13206 [(match_operand 1
13207 "cc_reg_operand" "y")
13208 (const_int 0)])
13209 (pc)
13210 (any_return)))]
13211 "<return_pred>"
13212 "*
13213 {
13214 return output_cbranch (operands[0], NULL, 1, insn);
13215 }"
13216 [(set_attr "type" "jmpreg")
13217 (set_attr "length" "4")])
13218
13219 ;; Logic on condition register values.
13220
13221 ; This pattern matches things like
13222 ; (set (reg:CCEQ 68) (compare:CCEQ (ior:SI (gt:SI (reg:CCFP 68) (const_int 0))
13223 ; (eq:SI (reg:CCFP 68) (const_int 0)))
13224 ; (const_int 1)))
13225 ; which are generated by the branch logic.
13226 ; Prefer destructive operations where BT = BB (for crXX BT,BA,BB)
13227
13228 (define_insn "*cceq_ior_compare"
13229 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
13230 (compare:CCEQ (match_operator:SI 1 "boolean_operator"
13231 [(match_operator:SI 2
13232 "branch_positive_comparison_operator"
13233 [(match_operand 3
13234 "cc_reg_operand" "y,y")
13235 (const_int 0)])
13236 (match_operator:SI 4
13237 "branch_positive_comparison_operator"
13238 [(match_operand 5
13239 "cc_reg_operand" "0,y")
13240 (const_int 0)])])
13241 (const_int 1)))]
13242 ""
13243 "cr%q1 %E0,%j2,%j4"
13244 [(set_attr "type" "cr_logical,delayed_cr")])
13245
13246 ; Why is the constant -1 here, but 1 in the previous pattern?
13247 ; Because ~1 has all but the low bit set.
13248 (define_insn ""
13249 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
13250 (compare:CCEQ (match_operator:SI 1 "boolean_or_operator"
13251 [(not:SI (match_operator:SI 2
13252 "branch_positive_comparison_operator"
13253 [(match_operand 3
13254 "cc_reg_operand" "y,y")
13255 (const_int 0)]))
13256 (match_operator:SI 4
13257 "branch_positive_comparison_operator"
13258 [(match_operand 5
13259 "cc_reg_operand" "0,y")
13260 (const_int 0)])])
13261 (const_int -1)))]
13262 ""
13263 "cr%q1 %E0,%j2,%j4"
13264 [(set_attr "type" "cr_logical,delayed_cr")])
13265
13266 (define_insn "*cceq_rev_compare"
13267 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
13268 (compare:CCEQ (match_operator:SI 1
13269 "branch_positive_comparison_operator"
13270 [(match_operand 2
13271 "cc_reg_operand" "0,y")
13272 (const_int 0)])
13273 (const_int 0)))]
13274 ""
13275 "crnot %E0,%j1"
13276 [(set_attr "type" "cr_logical,delayed_cr")])
13277
13278 ;; If we are comparing the result of two comparisons, this can be done
13279 ;; using creqv or crxor.
13280
13281 (define_insn_and_split ""
13282 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y")
13283 (compare:CCEQ (match_operator 1 "branch_comparison_operator"
13284 [(match_operand 2 "cc_reg_operand" "y")
13285 (const_int 0)])
13286 (match_operator 3 "branch_comparison_operator"
13287 [(match_operand 4 "cc_reg_operand" "y")
13288 (const_int 0)])))]
13289 ""
13290 "#"
13291 ""
13292 [(set (match_dup 0) (compare:CCEQ (xor:SI (match_dup 1) (match_dup 3))
13293 (match_dup 5)))]
13294 "
13295 {
13296 int positive_1, positive_2;
13297
13298 positive_1 = branch_positive_comparison_operator (operands[1],
13299 GET_MODE (operands[1]));
13300 positive_2 = branch_positive_comparison_operator (operands[3],
13301 GET_MODE (operands[3]));
13302
13303 if (! positive_1)
13304 operands[1] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[2]),
13305 GET_CODE (operands[1])),
13306 SImode,
13307 operands[2], const0_rtx);
13308 else if (GET_MODE (operands[1]) != SImode)
13309 operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), SImode,
13310 operands[2], const0_rtx);
13311
13312 if (! positive_2)
13313 operands[3] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[4]),
13314 GET_CODE (operands[3])),
13315 SImode,
13316 operands[4], const0_rtx);
13317 else if (GET_MODE (operands[3]) != SImode)
13318 operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SImode,
13319 operands[4], const0_rtx);
13320
13321 if (positive_1 == positive_2)
13322 {
13323 operands[1] = gen_rtx_NOT (SImode, operands[1]);
13324 operands[5] = constm1_rtx;
13325 }
13326 else
13327 {
13328 operands[5] = const1_rtx;
13329 }
13330 }")
13331
13332 ;; Unconditional branch and return.
13333
13334 (define_insn "jump"
13335 [(set (pc)
13336 (label_ref (match_operand 0 "" "")))]
13337 ""
13338 "b %l0"
13339 [(set_attr "type" "branch")])
13340
13341 (define_insn "<return_str>return"
13342 [(any_return)]
13343 "<return_pred>"
13344 "blr"
13345 [(set_attr "type" "jmpreg")])
13346
13347 (define_expand "indirect_jump"
13348 [(set (pc) (match_operand 0 "register_operand" ""))])
13349
13350 (define_insn "*indirect_jump<mode>"
13351 [(set (pc) (match_operand:P 0 "register_operand" "c,*l"))]
13352 ""
13353 "@
13354 bctr
13355 blr"
13356 [(set_attr "type" "jmpreg")])
13357
13358 ;; Table jump for switch statements:
13359 (define_expand "tablejump"
13360 [(use (match_operand 0 "" ""))
13361 (use (label_ref (match_operand 1 "" "")))]
13362 ""
13363 "
13364 {
13365 if (TARGET_32BIT)
13366 emit_jump_insn (gen_tablejumpsi (operands[0], operands[1]));
13367 else
13368 emit_jump_insn (gen_tablejumpdi (operands[0], operands[1]));
13369 DONE;
13370 }")
13371
13372 (define_expand "tablejumpsi"
13373 [(set (match_dup 3)
13374 (plus:SI (match_operand:SI 0 "" "")
13375 (match_dup 2)))
13376 (parallel [(set (pc) (match_dup 3))
13377 (use (label_ref (match_operand 1 "" "")))])]
13378 "TARGET_32BIT"
13379 "
13380 { operands[0] = force_reg (SImode, operands[0]);
13381 operands[2] = force_reg (SImode, gen_rtx_LABEL_REF (SImode, operands[1]));
13382 operands[3] = gen_reg_rtx (SImode);
13383 }")
13384
13385 (define_expand "tablejumpdi"
13386 [(set (match_dup 4)
13387 (sign_extend:DI (match_operand:SI 0 "lwa_operand" "")))
13388 (set (match_dup 3)
13389 (plus:DI (match_dup 4)
13390 (match_dup 2)))
13391 (parallel [(set (pc) (match_dup 3))
13392 (use (label_ref (match_operand 1 "" "")))])]
13393 "TARGET_64BIT"
13394 "
13395 { operands[2] = force_reg (DImode, gen_rtx_LABEL_REF (DImode, operands[1]));
13396 operands[3] = gen_reg_rtx (DImode);
13397 operands[4] = gen_reg_rtx (DImode);
13398 }")
13399
13400 (define_insn "*tablejump<mode>_internal1"
13401 [(set (pc)
13402 (match_operand:P 0 "register_operand" "c,*l"))
13403 (use (label_ref (match_operand 1 "" "")))]
13404 ""
13405 "@
13406 bctr
13407 blr"
13408 [(set_attr "type" "jmpreg")])
13409
13410 (define_insn "nop"
13411 [(const_int 0)]
13412 ""
13413 "nop")
13414
13415 (define_insn "group_ending_nop"
13416 [(unspec [(const_int 0)] UNSPEC_GRP_END_NOP)]
13417 ""
13418 "*
13419 {
13420 if (rs6000_cpu_attr == CPU_POWER6)
13421 return \"ori 1,1,0\";
13422 return \"ori 2,2,0\";
13423 }")
13424 \f
13425 ;; Define the subtract-one-and-jump insns, starting with the template
13426 ;; so loop.c knows what to generate.
13427
13428 (define_expand "doloop_end"
13429 [(use (match_operand 0 "" "")) ; loop pseudo
13430 (use (match_operand 1 "" ""))] ; label
13431 ""
13432 "
13433 {
13434 if (TARGET_64BIT)
13435 {
13436 if (GET_MODE (operands[0]) != DImode)
13437 FAIL;
13438 emit_jump_insn (gen_ctrdi (operands[0], operands[1]));
13439 }
13440 else
13441 {
13442 if (GET_MODE (operands[0]) != SImode)
13443 FAIL;
13444 emit_jump_insn (gen_ctrsi (operands[0], operands[1]));
13445 }
13446 DONE;
13447 }")
13448
13449 (define_expand "ctr<mode>"
13450 [(parallel [(set (pc)
13451 (if_then_else (ne (match_operand:P 0 "register_operand" "")
13452 (const_int 1))
13453 (label_ref (match_operand 1 "" ""))
13454 (pc)))
13455 (set (match_dup 0)
13456 (plus:P (match_dup 0)
13457 (const_int -1)))
13458 (clobber (match_scratch:CC 2 ""))
13459 (clobber (match_scratch:P 3 ""))])]
13460 ""
13461 "")
13462
13463 ;; We need to be able to do this for any operand, including MEM, or we
13464 ;; will cause reload to blow up since we don't allow output reloads on
13465 ;; JUMP_INSNs.
13466 ;; For the length attribute to be calculated correctly, the
13467 ;; label MUST be operand 0.
13468
13469 (define_insn "*ctr<mode>_internal1"
13470 [(set (pc)
13471 (if_then_else (ne (match_operand:P 1 "register_operand" "c,*r,*r,*r")
13472 (const_int 1))
13473 (label_ref (match_operand 0 "" ""))
13474 (pc)))
13475 (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*c*l")
13476 (plus:P (match_dup 1)
13477 (const_int -1)))
13478 (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
13479 (clobber (match_scratch:P 4 "=X,X,&r,r"))]
13480 ""
13481 "*
13482 {
13483 if (which_alternative != 0)
13484 return \"#\";
13485 else if (get_attr_length (insn) == 4)
13486 return \"bdnz %l0\";
13487 else
13488 return \"bdz $+8\;b %l0\";
13489 }"
13490 [(set_attr "type" "branch")
13491 (set_attr "length" "*,12,16,16")])
13492
13493 (define_insn "*ctr<mode>_internal2"
13494 [(set (pc)
13495 (if_then_else (ne (match_operand:P 1 "register_operand" "c,*r,*r,*r")
13496 (const_int 1))
13497 (pc)
13498 (label_ref (match_operand 0 "" ""))))
13499 (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*c*l")
13500 (plus:P (match_dup 1)
13501 (const_int -1)))
13502 (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
13503 (clobber (match_scratch:P 4 "=X,X,&r,r"))]
13504 ""
13505 "*
13506 {
13507 if (which_alternative != 0)
13508 return \"#\";
13509 else if (get_attr_length (insn) == 4)
13510 return \"bdz %l0\";
13511 else
13512 return \"bdnz $+8\;b %l0\";
13513 }"
13514 [(set_attr "type" "branch")
13515 (set_attr "length" "*,12,16,16")])
13516
13517 ;; Similar but use EQ
13518
13519 (define_insn "*ctr<mode>_internal5"
13520 [(set (pc)
13521 (if_then_else (eq (match_operand:P 1 "register_operand" "c,*r,*r,*r")
13522 (const_int 1))
13523 (label_ref (match_operand 0 "" ""))
13524 (pc)))
13525 (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*c*l")
13526 (plus:P (match_dup 1)
13527 (const_int -1)))
13528 (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
13529 (clobber (match_scratch:P 4 "=X,X,&r,r"))]
13530 ""
13531 "*
13532 {
13533 if (which_alternative != 0)
13534 return \"#\";
13535 else if (get_attr_length (insn) == 4)
13536 return \"bdz %l0\";
13537 else
13538 return \"bdnz $+8\;b %l0\";
13539 }"
13540 [(set_attr "type" "branch")
13541 (set_attr "length" "*,12,16,16")])
13542
13543 (define_insn "*ctr<mode>_internal6"
13544 [(set (pc)
13545 (if_then_else (eq (match_operand:P 1 "register_operand" "c,*r,*r,*r")
13546 (const_int 1))
13547 (pc)
13548 (label_ref (match_operand 0 "" ""))))
13549 (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*c*l")
13550 (plus:P (match_dup 1)
13551 (const_int -1)))
13552 (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
13553 (clobber (match_scratch:P 4 "=X,X,&r,r"))]
13554 ""
13555 "*
13556 {
13557 if (which_alternative != 0)
13558 return \"#\";
13559 else if (get_attr_length (insn) == 4)
13560 return \"bdnz %l0\";
13561 else
13562 return \"bdz $+8\;b %l0\";
13563 }"
13564 [(set_attr "type" "branch")
13565 (set_attr "length" "*,12,16,16")])
13566
13567 ;; Now the splitters if we could not allocate the CTR register
13568
13569 (define_split
13570 [(set (pc)
13571 (if_then_else (match_operator 2 "comparison_operator"
13572 [(match_operand:P 1 "gpc_reg_operand" "")
13573 (const_int 1)])
13574 (match_operand 5 "" "")
13575 (match_operand 6 "" "")))
13576 (set (match_operand:P 0 "gpc_reg_operand" "")
13577 (plus:P (match_dup 1) (const_int -1)))
13578 (clobber (match_scratch:CC 3 ""))
13579 (clobber (match_scratch:P 4 ""))]
13580 "reload_completed"
13581 [(parallel [(set (match_dup 3)
13582 (compare:CC (plus:P (match_dup 1)
13583 (const_int -1))
13584 (const_int 0)))
13585 (set (match_dup 0)
13586 (plus:P (match_dup 1)
13587 (const_int -1)))])
13588 (set (pc) (if_then_else (match_dup 7)
13589 (match_dup 5)
13590 (match_dup 6)))]
13591 "
13592 { operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[2]), VOIDmode,
13593 operands[3], const0_rtx); }")
13594
13595 (define_split
13596 [(set (pc)
13597 (if_then_else (match_operator 2 "comparison_operator"
13598 [(match_operand:P 1 "gpc_reg_operand" "")
13599 (const_int 1)])
13600 (match_operand 5 "" "")
13601 (match_operand 6 "" "")))
13602 (set (match_operand:P 0 "nonimmediate_operand" "")
13603 (plus:P (match_dup 1) (const_int -1)))
13604 (clobber (match_scratch:CC 3 ""))
13605 (clobber (match_scratch:P 4 ""))]
13606 "reload_completed && ! gpc_reg_operand (operands[0], SImode)"
13607 [(parallel [(set (match_dup 3)
13608 (compare:CC (plus:P (match_dup 1)
13609 (const_int -1))
13610 (const_int 0)))
13611 (set (match_dup 4)
13612 (plus:P (match_dup 1)
13613 (const_int -1)))])
13614 (set (match_dup 0)
13615 (match_dup 4))
13616 (set (pc) (if_then_else (match_dup 7)
13617 (match_dup 5)
13618 (match_dup 6)))]
13619 "
13620 { operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[2]), VOIDmode,
13621 operands[3], const0_rtx); }")
13622 \f
13623 (define_insn "trap"
13624 [(trap_if (const_int 1) (const_int 0))]
13625 ""
13626 "trap"
13627 [(set_attr "type" "trap")])
13628
13629 (define_expand "ctrap<mode>4"
13630 [(trap_if (match_operator 0 "ordered_comparison_operator"
13631 [(match_operand:GPR 1 "register_operand")
13632 (match_operand:GPR 2 "reg_or_short_operand")])
13633 (match_operand 3 "zero_constant" ""))]
13634 ""
13635 "")
13636
13637 (define_insn ""
13638 [(trap_if (match_operator 0 "ordered_comparison_operator"
13639 [(match_operand:GPR 1 "register_operand" "r")
13640 (match_operand:GPR 2 "reg_or_short_operand" "rI")])
13641 (const_int 0))]
13642 ""
13643 "t<wd>%V0%I2 %1,%2"
13644 [(set_attr "type" "trap")])
13645 \f
13646 ;; Insns related to generating the function prologue and epilogue.
13647
13648 (define_expand "prologue"
13649 [(use (const_int 0))]
13650 ""
13651 {
13652 rs6000_emit_prologue ();
13653 if (!TARGET_SCHED_PROLOG)
13654 emit_insn (gen_blockage ());
13655 DONE;
13656 })
13657
13658 (define_insn "*movesi_from_cr_one"
13659 [(match_parallel 0 "mfcr_operation"
13660 [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
13661 (unspec:SI [(match_operand:CC 2 "cc_reg_operand" "y")
13662 (match_operand 3 "immediate_operand" "n")]
13663 UNSPEC_MOVESI_FROM_CR))])]
13664 "TARGET_MFCRF"
13665 "*
13666 {
13667 int mask = 0;
13668 int i;
13669 for (i = 0; i < XVECLEN (operands[0], 0); i++)
13670 {
13671 mask = INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
13672 operands[4] = GEN_INT (mask);
13673 output_asm_insn (\"mfcr %1,%4\", operands);
13674 }
13675 return \"\";
13676 }"
13677 [(set_attr "type" "mfcrf")])
13678
13679 (define_insn "movesi_from_cr"
13680 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
13681 (unspec:SI [(reg:CC CR0_REGNO) (reg:CC CR1_REGNO)
13682 (reg:CC CR2_REGNO) (reg:CC CR3_REGNO)
13683 (reg:CC CR4_REGNO) (reg:CC CR5_REGNO)
13684 (reg:CC CR6_REGNO) (reg:CC CR7_REGNO)]
13685 UNSPEC_MOVESI_FROM_CR))]
13686 ""
13687 "mfcr %0"
13688 [(set_attr "type" "mfcr")])
13689
13690 (define_insn "*crsave"
13691 [(match_parallel 0 "crsave_operation"
13692 [(set (match_operand:SI 1 "memory_operand" "=m")
13693 (match_operand:SI 2 "gpc_reg_operand" "r"))])]
13694 ""
13695 "stw %2,%1"
13696 [(set_attr "type" "store")])
13697
13698 (define_insn "*stmw"
13699 [(match_parallel 0 "stmw_operation"
13700 [(set (match_operand:SI 1 "memory_operand" "=m")
13701 (match_operand:SI 2 "gpc_reg_operand" "r"))])]
13702 "TARGET_MULTIPLE"
13703 "stmw %2,%1"
13704 [(set_attr "type" "store")
13705 (set_attr "update" "yes")
13706 (set_attr "indexed" "yes")])
13707
13708 ; The following comment applies to:
13709 ; save_gpregs_*
13710 ; save_fpregs_*
13711 ; restore_gpregs*
13712 ; return_and_restore_gpregs*
13713 ; return_and_restore_fpregs*
13714 ; return_and_restore_fpregs_aix*
13715 ;
13716 ; The out-of-line save / restore functions expects one input argument.
13717 ; Since those are not standard call_insn's, we must avoid using
13718 ; MATCH_OPERAND for that argument. That way the register rename
13719 ; optimization will not try to rename this register.
13720 ; Each pattern is repeated for each possible register number used in
13721 ; various ABIs (r11, r1, and for some functions r12)
13722
13723 (define_insn "*save_gpregs_<mode>_r11"
13724 [(match_parallel 0 "any_parallel_operand"
13725 [(clobber (reg:P 65))
13726 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13727 (use (reg:P 11))
13728 (set (match_operand:P 2 "memory_operand" "=m")
13729 (match_operand:P 3 "gpc_reg_operand" "r"))])]
13730 ""
13731 "bl %1"
13732 [(set_attr "type" "branch")
13733 (set_attr "length" "4")])
13734
13735 (define_insn "*save_gpregs_<mode>_r12"
13736 [(match_parallel 0 "any_parallel_operand"
13737 [(clobber (reg:P 65))
13738 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13739 (use (reg:P 12))
13740 (set (match_operand:P 2 "memory_operand" "=m")
13741 (match_operand:P 3 "gpc_reg_operand" "r"))])]
13742 ""
13743 "bl %1"
13744 [(set_attr "type" "branch")
13745 (set_attr "length" "4")])
13746
13747 (define_insn "*save_gpregs_<mode>_r1"
13748 [(match_parallel 0 "any_parallel_operand"
13749 [(clobber (reg:P 65))
13750 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13751 (use (reg:P 1))
13752 (set (match_operand:P 2 "memory_operand" "=m")
13753 (match_operand:P 3 "gpc_reg_operand" "r"))])]
13754 ""
13755 "bl %1"
13756 [(set_attr "type" "branch")
13757 (set_attr "length" "4")])
13758
13759 (define_insn "*save_fpregs_<mode>_r11"
13760 [(match_parallel 0 "any_parallel_operand"
13761 [(clobber (reg:P 65))
13762 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13763 (use (reg:P 11))
13764 (set (match_operand:DF 2 "memory_operand" "=m")
13765 (match_operand:DF 3 "gpc_reg_operand" "d"))])]
13766 ""
13767 "bl %1"
13768 [(set_attr "type" "branch")
13769 (set_attr "length" "4")])
13770
13771 (define_insn "*save_fpregs_<mode>_r12"
13772 [(match_parallel 0 "any_parallel_operand"
13773 [(clobber (reg:P 65))
13774 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13775 (use (reg:P 12))
13776 (set (match_operand:DF 2 "memory_operand" "=m")
13777 (match_operand:DF 3 "gpc_reg_operand" "d"))])]
13778 ""
13779 "bl %1"
13780 [(set_attr "type" "branch")
13781 (set_attr "length" "4")])
13782
13783 (define_insn "*save_fpregs_<mode>_r1"
13784 [(match_parallel 0 "any_parallel_operand"
13785 [(clobber (reg:P 65))
13786 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13787 (use (reg:P 1))
13788 (set (match_operand:DF 2 "memory_operand" "=m")
13789 (match_operand:DF 3 "gpc_reg_operand" "d"))])]
13790 ""
13791 "bl %1"
13792 [(set_attr "type" "branch")
13793 (set_attr "length" "4")])
13794
13795 ; This is to explain that changes to the stack pointer should
13796 ; not be moved over loads from or stores to stack memory.
13797 (define_insn "stack_tie"
13798 [(match_parallel 0 "tie_operand"
13799 [(set (mem:BLK (reg 1)) (const_int 0))])]
13800 ""
13801 ""
13802 [(set_attr "length" "0")])
13803
13804 (define_expand "epilogue"
13805 [(use (const_int 0))]
13806 ""
13807 {
13808 if (!TARGET_SCHED_PROLOG)
13809 emit_insn (gen_blockage ());
13810 rs6000_emit_epilogue (FALSE);
13811 DONE;
13812 })
13813
13814 ; On some processors, doing the mtcrf one CC register at a time is
13815 ; faster (like on the 604e). On others, doing them all at once is
13816 ; faster; for instance, on the 601 and 750.
13817
13818 (define_expand "movsi_to_cr_one"
13819 [(set (match_operand:CC 0 "cc_reg_operand" "")
13820 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "")
13821 (match_dup 2)] UNSPEC_MOVESI_TO_CR))]
13822 ""
13823 "operands[2] = GEN_INT (1 << (75 - REGNO (operands[0])));")
13824
13825 (define_insn "*movsi_to_cr"
13826 [(match_parallel 0 "mtcrf_operation"
13827 [(set (match_operand:CC 1 "cc_reg_operand" "=y")
13828 (unspec:CC [(match_operand:SI 2 "gpc_reg_operand" "r")
13829 (match_operand 3 "immediate_operand" "n")]
13830 UNSPEC_MOVESI_TO_CR))])]
13831 ""
13832 "*
13833 {
13834 int mask = 0;
13835 int i;
13836 for (i = 0; i < XVECLEN (operands[0], 0); i++)
13837 mask |= INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
13838 operands[4] = GEN_INT (mask);
13839 return \"mtcrf %4,%2\";
13840 }"
13841 [(set_attr "type" "mtcr")])
13842
13843 (define_insn "*mtcrfsi"
13844 [(set (match_operand:CC 0 "cc_reg_operand" "=y")
13845 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
13846 (match_operand 2 "immediate_operand" "n")]
13847 UNSPEC_MOVESI_TO_CR))]
13848 "GET_CODE (operands[0]) == REG
13849 && CR_REGNO_P (REGNO (operands[0]))
13850 && GET_CODE (operands[2]) == CONST_INT
13851 && INTVAL (operands[2]) == 1 << (75 - REGNO (operands[0]))"
13852 "mtcrf %R0,%1"
13853 [(set_attr "type" "mtcr")])
13854
13855 ; The load-multiple instructions have similar properties.
13856 ; Note that "load_multiple" is a name known to the machine-independent
13857 ; code that actually corresponds to the PowerPC load-string.
13858
13859 (define_insn "*lmw"
13860 [(match_parallel 0 "lmw_operation"
13861 [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
13862 (match_operand:SI 2 "memory_operand" "m"))])]
13863 "TARGET_MULTIPLE"
13864 "lmw %1,%2"
13865 [(set_attr "type" "load")
13866 (set_attr "update" "yes")
13867 (set_attr "indexed" "yes")
13868 (set_attr "cell_micro" "always")])
13869
13870 (define_insn "*return_internal_<mode>"
13871 [(simple_return)
13872 (use (match_operand:P 0 "register_operand" "lc"))]
13873 ""
13874 "b%T0"
13875 [(set_attr "type" "jmpreg")])
13876
13877 ; FIXME: This would probably be somewhat simpler if the Cygnus sibcall
13878 ; stuff was in GCC. Oh, and "any_parallel_operand" is a bit flexible...
13879
13880 ; The following comment applies to:
13881 ; save_gpregs_*
13882 ; save_fpregs_*
13883 ; restore_gpregs*
13884 ; return_and_restore_gpregs*
13885 ; return_and_restore_fpregs*
13886 ; return_and_restore_fpregs_aix*
13887 ;
13888 ; The out-of-line save / restore functions expects one input argument.
13889 ; Since those are not standard call_insn's, we must avoid using
13890 ; MATCH_OPERAND for that argument. That way the register rename
13891 ; optimization will not try to rename this register.
13892 ; Each pattern is repeated for each possible register number used in
13893 ; various ABIs (r11, r1, and for some functions r12)
13894
13895 (define_insn "*restore_gpregs_<mode>_r11"
13896 [(match_parallel 0 "any_parallel_operand"
13897 [(clobber (match_operand:P 1 "register_operand" "=l"))
13898 (use (match_operand:P 2 "symbol_ref_operand" "s"))
13899 (use (reg:P 11))
13900 (set (match_operand:P 3 "gpc_reg_operand" "=r")
13901 (match_operand:P 4 "memory_operand" "m"))])]
13902 ""
13903 "bl %2"
13904 [(set_attr "type" "branch")
13905 (set_attr "length" "4")])
13906
13907 (define_insn "*restore_gpregs_<mode>_r12"
13908 [(match_parallel 0 "any_parallel_operand"
13909 [(clobber (match_operand:P 1 "register_operand" "=l"))
13910 (use (match_operand:P 2 "symbol_ref_operand" "s"))
13911 (use (reg:P 12))
13912 (set (match_operand:P 3 "gpc_reg_operand" "=r")
13913 (match_operand:P 4 "memory_operand" "m"))])]
13914 ""
13915 "bl %2"
13916 [(set_attr "type" "branch")
13917 (set_attr "length" "4")])
13918
13919 (define_insn "*restore_gpregs_<mode>_r1"
13920 [(match_parallel 0 "any_parallel_operand"
13921 [(clobber (match_operand:P 1 "register_operand" "=l"))
13922 (use (match_operand:P 2 "symbol_ref_operand" "s"))
13923 (use (reg:P 1))
13924 (set (match_operand:P 3 "gpc_reg_operand" "=r")
13925 (match_operand:P 4 "memory_operand" "m"))])]
13926 ""
13927 "bl %2"
13928 [(set_attr "type" "branch")
13929 (set_attr "length" "4")])
13930
13931 (define_insn "*return_and_restore_gpregs_<mode>_r11"
13932 [(match_parallel 0 "any_parallel_operand"
13933 [(return)
13934 (clobber (match_operand:P 1 "register_operand" "=l"))
13935 (use (match_operand:P 2 "symbol_ref_operand" "s"))
13936 (use (reg:P 11))
13937 (set (match_operand:P 3 "gpc_reg_operand" "=r")
13938 (match_operand:P 4 "memory_operand" "m"))])]
13939 ""
13940 "b %2"
13941 [(set_attr "type" "branch")
13942 (set_attr "length" "4")])
13943
13944 (define_insn "*return_and_restore_gpregs_<mode>_r12"
13945 [(match_parallel 0 "any_parallel_operand"
13946 [(return)
13947 (clobber (match_operand:P 1 "register_operand" "=l"))
13948 (use (match_operand:P 2 "symbol_ref_operand" "s"))
13949 (use (reg:P 12))
13950 (set (match_operand:P 3 "gpc_reg_operand" "=r")
13951 (match_operand:P 4 "memory_operand" "m"))])]
13952 ""
13953 "b %2"
13954 [(set_attr "type" "branch")
13955 (set_attr "length" "4")])
13956
13957 (define_insn "*return_and_restore_gpregs_<mode>_r1"
13958 [(match_parallel 0 "any_parallel_operand"
13959 [(return)
13960 (clobber (match_operand:P 1 "register_operand" "=l"))
13961 (use (match_operand:P 2 "symbol_ref_operand" "s"))
13962 (use (reg:P 1))
13963 (set (match_operand:P 3 "gpc_reg_operand" "=r")
13964 (match_operand:P 4 "memory_operand" "m"))])]
13965 ""
13966 "b %2"
13967 [(set_attr "type" "branch")
13968 (set_attr "length" "4")])
13969
13970 (define_insn "*return_and_restore_fpregs_<mode>_r11"
13971 [(match_parallel 0 "any_parallel_operand"
13972 [(return)
13973 (clobber (match_operand:P 1 "register_operand" "=l"))
13974 (use (match_operand:P 2 "symbol_ref_operand" "s"))
13975 (use (reg:P 11))
13976 (set (match_operand:DF 3 "gpc_reg_operand" "=d")
13977 (match_operand:DF 4 "memory_operand" "m"))])]
13978 ""
13979 "b %2"
13980 [(set_attr "type" "branch")
13981 (set_attr "length" "4")])
13982
13983 (define_insn "*return_and_restore_fpregs_<mode>_r12"
13984 [(match_parallel 0 "any_parallel_operand"
13985 [(return)
13986 (clobber (match_operand:P 1 "register_operand" "=l"))
13987 (use (match_operand:P 2 "symbol_ref_operand" "s"))
13988 (use (reg:P 12))
13989 (set (match_operand:DF 3 "gpc_reg_operand" "=d")
13990 (match_operand:DF 4 "memory_operand" "m"))])]
13991 ""
13992 "b %2"
13993 [(set_attr "type" "branch")
13994 (set_attr "length" "4")])
13995
13996 (define_insn "*return_and_restore_fpregs_<mode>_r1"
13997 [(match_parallel 0 "any_parallel_operand"
13998 [(return)
13999 (clobber (match_operand:P 1 "register_operand" "=l"))
14000 (use (match_operand:P 2 "symbol_ref_operand" "s"))
14001 (use (reg:P 1))
14002 (set (match_operand:DF 3 "gpc_reg_operand" "=d")
14003 (match_operand:DF 4 "memory_operand" "m"))])]
14004 ""
14005 "b %2"
14006 [(set_attr "type" "branch")
14007 (set_attr "length" "4")])
14008
14009 (define_insn "*return_and_restore_fpregs_aix_<mode>_r11"
14010 [(match_parallel 0 "any_parallel_operand"
14011 [(return)
14012 (use (match_operand:P 1 "register_operand" "l"))
14013 (use (match_operand:P 2 "symbol_ref_operand" "s"))
14014 (use (reg:P 11))
14015 (set (match_operand:DF 3 "gpc_reg_operand" "=d")
14016 (match_operand:DF 4 "memory_operand" "m"))])]
14017 ""
14018 "b %2"
14019 [(set_attr "type" "branch")
14020 (set_attr "length" "4")])
14021
14022 (define_insn "*return_and_restore_fpregs_aix_<mode>_r1"
14023 [(match_parallel 0 "any_parallel_operand"
14024 [(return)
14025 (use (match_operand:P 1 "register_operand" "l"))
14026 (use (match_operand:P 2 "symbol_ref_operand" "s"))
14027 (use (reg:P 1))
14028 (set (match_operand:DF 3 "gpc_reg_operand" "=d")
14029 (match_operand:DF 4 "memory_operand" "m"))])]
14030 ""
14031 "b %2"
14032 [(set_attr "type" "branch")
14033 (set_attr "length" "4")])
14034
14035 ; This is used in compiling the unwind routines.
14036 (define_expand "eh_return"
14037 [(use (match_operand 0 "general_operand" ""))]
14038 ""
14039 "
14040 {
14041 if (TARGET_32BIT)
14042 emit_insn (gen_eh_set_lr_si (operands[0]));
14043 else
14044 emit_insn (gen_eh_set_lr_di (operands[0]));
14045 DONE;
14046 }")
14047
14048 ; We can't expand this before we know where the link register is stored.
14049 (define_insn "eh_set_lr_<mode>"
14050 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
14051 UNSPECV_EH_RR)
14052 (clobber (match_scratch:P 1 "=&b"))]
14053 ""
14054 "#")
14055
14056 (define_split
14057 [(unspec_volatile [(match_operand 0 "register_operand" "")] UNSPECV_EH_RR)
14058 (clobber (match_scratch 1 ""))]
14059 "reload_completed"
14060 [(const_int 0)]
14061 "
14062 {
14063 rs6000_emit_eh_reg_restore (operands[0], operands[1]);
14064 DONE;
14065 }")
14066
14067 (define_insn "prefetch"
14068 [(prefetch (match_operand 0 "indexed_or_indirect_address" "a")
14069 (match_operand:SI 1 "const_int_operand" "n")
14070 (match_operand:SI 2 "const_int_operand" "n"))]
14071 ""
14072 "*
14073 {
14074 if (GET_CODE (operands[0]) == REG)
14075 return INTVAL (operands[1]) ? \"dcbtst 0,%0\" : \"dcbt 0,%0\";
14076 return INTVAL (operands[1]) ? \"dcbtst %a0\" : \"dcbt %a0\";
14077 }"
14078 [(set_attr "type" "load")])
14079 \f
14080 (define_insn "bpermd_<mode>"
14081 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
14082 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "r")
14083 (match_operand:P 2 "gpc_reg_operand" "r")] UNSPEC_BPERM))]
14084 "TARGET_POPCNTD"
14085 "bpermd %0,%1,%2"
14086 [(set_attr "type" "popcnt")])
14087
14088 \f
14089 ;; Builtin fma support. Handle
14090 ;; Note that the conditions for expansion are in the FMA_F iterator.
14091
14092 (define_expand "fma<mode>4"
14093 [(set (match_operand:FMA_F 0 "register_operand" "")
14094 (fma:FMA_F
14095 (match_operand:FMA_F 1 "register_operand" "")
14096 (match_operand:FMA_F 2 "register_operand" "")
14097 (match_operand:FMA_F 3 "register_operand" "")))]
14098 ""
14099 "")
14100
14101 (define_insn "*fma<mode>4_fpr"
14102 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>,<Fv>")
14103 (fma:SFDF
14104 (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv>,<Fv>")
14105 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>,0")
14106 (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv>")))]
14107 "TARGET_<MODE>_FPR"
14108 "@
14109 fmadd<Ftrad> %0,%1,%2,%3
14110 xsmadda<Fvsx> %x0,%x1,%x2
14111 xsmaddm<Fvsx> %x0,%x1,%x3"
14112 [(set_attr "type" "fp")
14113 (set_attr "fp_type" "fp_maddsub_<Fs>")])
14114
14115 ; Altivec only has fma and nfms.
14116 (define_expand "fms<mode>4"
14117 [(set (match_operand:FMA_F 0 "register_operand" "")
14118 (fma:FMA_F
14119 (match_operand:FMA_F 1 "register_operand" "")
14120 (match_operand:FMA_F 2 "register_operand" "")
14121 (neg:FMA_F (match_operand:FMA_F 3 "register_operand" ""))))]
14122 "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
14123 "")
14124
14125 (define_insn "*fms<mode>4_fpr"
14126 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>,<Fv>")
14127 (fma:SFDF
14128 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>,<Fv>")
14129 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>,0")
14130 (neg:SFDF (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv>"))))]
14131 "TARGET_<MODE>_FPR"
14132 "@
14133 fmsub<Ftrad> %0,%1,%2,%3
14134 xsmsuba<Fvsx> %x0,%x1,%x2
14135 xsmsubm<Fvsx> %x0,%x1,%x3"
14136 [(set_attr "type" "fp")
14137 (set_attr "fp_type" "fp_maddsub_<Fs>")])
14138
14139 ;; If signed zeros are ignored, -(a * b - c) = -a * b + c.
14140 (define_expand "fnma<mode>4"
14141 [(set (match_operand:FMA_F 0 "register_operand" "")
14142 (neg:FMA_F
14143 (fma:FMA_F
14144 (match_operand:FMA_F 1 "register_operand" "")
14145 (match_operand:FMA_F 2 "register_operand" "")
14146 (neg:FMA_F (match_operand:FMA_F 3 "register_operand" "")))))]
14147 "!HONOR_SIGNED_ZEROS (<MODE>mode)"
14148 "")
14149
14150 ;; If signed zeros are ignored, -(a * b + c) = -a * b - c.
14151 (define_expand "fnms<mode>4"
14152 [(set (match_operand:FMA_F 0 "register_operand" "")
14153 (neg:FMA_F
14154 (fma:FMA_F
14155 (match_operand:FMA_F 1 "register_operand" "")
14156 (match_operand:FMA_F 2 "register_operand" "")
14157 (match_operand:FMA_F 3 "register_operand" ""))))]
14158 "!HONOR_SIGNED_ZEROS (<MODE>mode) && !VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
14159 "")
14160
14161 ; Not an official optab name, but used from builtins.
14162 (define_expand "nfma<mode>4"
14163 [(set (match_operand:FMA_F 0 "register_operand" "")
14164 (neg:FMA_F
14165 (fma:FMA_F
14166 (match_operand:FMA_F 1 "register_operand" "")
14167 (match_operand:FMA_F 2 "register_operand" "")
14168 (match_operand:FMA_F 3 "register_operand" ""))))]
14169 "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
14170 "")
14171
14172 (define_insn "*nfma<mode>4_fpr"
14173 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>,<Fv>")
14174 (neg:SFDF
14175 (fma:SFDF
14176 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>,<Fv>")
14177 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>,0")
14178 (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv>"))))]
14179 "TARGET_<MODE>_FPR"
14180 "@
14181 fnmadd<Ftrad> %0,%1,%2,%3
14182 xsnmadda<Fvsx> %x0,%x1,%x2
14183 xsnmaddm<Fvsx> %x0,%x1,%x3"
14184 [(set_attr "type" "fp")
14185 (set_attr "fp_type" "fp_maddsub_<Fs>")])
14186
14187 ; Not an official optab name, but used from builtins.
14188 (define_expand "nfms<mode>4"
14189 [(set (match_operand:FMA_F 0 "register_operand" "")
14190 (neg:FMA_F
14191 (fma:FMA_F
14192 (match_operand:FMA_F 1 "register_operand" "")
14193 (match_operand:FMA_F 2 "register_operand" "")
14194 (neg:FMA_F (match_operand:FMA_F 3 "register_operand" "")))))]
14195 ""
14196 "")
14197
14198 (define_insn "*nfmssf4_fpr"
14199 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>,<Fv>")
14200 (neg:SFDF
14201 (fma:SFDF
14202 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>,<Fv>")
14203 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>,0")
14204 (neg:SFDF
14205 (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv>")))))]
14206 "TARGET_<MODE>_FPR"
14207 "@
14208 fnmsub<Ftrad> %0,%1,%2,%3
14209 xsnmsuba<Fvsx> %x0,%x1,%x2
14210 xsnmsubm<Fvsx> %x0,%x1,%x3"
14211 [(set_attr "type" "fp")
14212 (set_attr "fp_type" "fp_maddsub_<Fs>")])
14213
14214 \f
14215 (define_expand "rs6000_get_timebase"
14216 [(use (match_operand:DI 0 "gpc_reg_operand" ""))]
14217 ""
14218 {
14219 if (TARGET_POWERPC64)
14220 emit_insn (gen_rs6000_mftb_di (operands[0]));
14221 else
14222 emit_insn (gen_rs6000_get_timebase_ppc32 (operands[0]));
14223 DONE;
14224 })
14225
14226 (define_insn "rs6000_get_timebase_ppc32"
14227 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
14228 (unspec_volatile:DI [(const_int 0)] UNSPECV_MFTB))
14229 (clobber (match_scratch:SI 1 "=r"))
14230 (clobber (match_scratch:CC 2 "=y"))]
14231 "!TARGET_POWERPC64"
14232 {
14233 if (WORDS_BIG_ENDIAN)
14234 if (TARGET_MFCRF)
14235 {
14236 return "mfspr %0,269\;"
14237 "mfspr %L0,268\;"
14238 "mfspr %1,269\;"
14239 "cmpw %2,%0,%1\;"
14240 "bne- %2,$-16";
14241 }
14242 else
14243 {
14244 return "mftbu %0\;"
14245 "mftb %L0\;"
14246 "mftbu %1\;"
14247 "cmpw %2,%0,%1\;"
14248 "bne- %2,$-16";
14249 }
14250 else
14251 if (TARGET_MFCRF)
14252 {
14253 return "mfspr %L0,269\;"
14254 "mfspr %0,268\;"
14255 "mfspr %1,269\;"
14256 "cmpw %2,%L0,%1\;"
14257 "bne- %2,$-16";
14258 }
14259 else
14260 {
14261 return "mftbu %L0\;"
14262 "mftb %0\;"
14263 "mftbu %1\;"
14264 "cmpw %2,%L0,%1\;"
14265 "bne- %2,$-16";
14266 }
14267 }
14268 [(set_attr "length" "20")])
14269
14270 (define_insn "rs6000_mftb_<mode>"
14271 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
14272 (unspec_volatile:GPR [(const_int 0)] UNSPECV_MFTB))]
14273 ""
14274 {
14275 if (TARGET_MFCRF)
14276 return "mfspr %0,268";
14277 else
14278 return "mftb %0";
14279 })
14280
14281 \f
14282 (define_insn "rs6000_mffs"
14283 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
14284 (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFS))]
14285 "TARGET_HARD_FLOAT && TARGET_FPRS"
14286 "mffs %0")
14287
14288 (define_insn "rs6000_mtfsf"
14289 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "i")
14290 (match_operand:DF 1 "gpc_reg_operand" "d")]
14291 UNSPECV_MTFSF)]
14292 "TARGET_HARD_FLOAT && TARGET_FPRS"
14293 "mtfsf %0,%1")
14294
14295 \f
14296 ;; Power8 fusion support for fusing an addis instruction with a D-form load of
14297 ;; a GPR. The addis instruction must be adjacent to the load, and use the same
14298 ;; register that is being loaded. The fused ops must be physically adjacent.
14299
14300 ;; Find cases where the addis that feeds into a load instruction is either used
14301 ;; once or is the same as the target register, and replace it with the fusion
14302 ;; insn
14303
14304 (define_peephole2
14305 [(set (match_operand:P 0 "base_reg_operand" "")
14306 (match_operand:P 1 "fusion_gpr_addis" ""))
14307 (set (match_operand:INT1 2 "base_reg_operand" "")
14308 (match_operand:INT1 3 "fusion_gpr_mem_load" ""))]
14309 "TARGET_P8_FUSION
14310 && fusion_gpr_load_p (operands[0], operands[1], operands[2],
14311 operands[3])"
14312 [(const_int 0)]
14313 {
14314 expand_fusion_gpr_load (operands);
14315 DONE;
14316 })
14317
14318 ;; Fusion insn, created by the define_peephole2 above (and eventually by
14319 ;; reload)
14320
14321 (define_insn "fusion_gpr_load_<mode>"
14322 [(set (match_operand:INT1 0 "base_reg_operand" "=&b")
14323 (unspec:INT1 [(match_operand:INT1 1 "fusion_gpr_mem_combo" "")]
14324 UNSPEC_FUSION_GPR))]
14325 "TARGET_P8_FUSION"
14326 {
14327 return emit_fusion_gpr_load (operands[0], operands[1]);
14328 }
14329 [(set_attr "type" "load")
14330 (set_attr "length" "8")])
14331
14332 \f
14333 ;; Miscellaneous ISA 2.06 (power7) instructions
14334 (define_insn "addg6s"
14335 [(set (match_operand:SI 0 "register_operand" "=r")
14336 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
14337 (match_operand:SI 2 "register_operand" "r")]
14338 UNSPEC_ADDG6S))]
14339 "TARGET_POPCNTD"
14340 "addg6s %0,%1,%2"
14341 [(set_attr "type" "integer")
14342 (set_attr "length" "4")])
14343
14344 (define_insn "cdtbcd"
14345 [(set (match_operand:SI 0 "register_operand" "=r")
14346 (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
14347 UNSPEC_CDTBCD))]
14348 "TARGET_POPCNTD"
14349 "cdtbcd %0,%1"
14350 [(set_attr "type" "integer")
14351 (set_attr "length" "4")])
14352
14353 (define_insn "cbcdtd"
14354 [(set (match_operand:SI 0 "register_operand" "=r")
14355 (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
14356 UNSPEC_CBCDTD))]
14357 "TARGET_POPCNTD"
14358 "cbcdtd %0,%1"
14359 [(set_attr "type" "integer")
14360 (set_attr "length" "4")])
14361
14362 (define_int_iterator UNSPEC_DIV_EXTEND [UNSPEC_DIVE
14363 UNSPEC_DIVEO
14364 UNSPEC_DIVEU
14365 UNSPEC_DIVEUO])
14366
14367 (define_int_attr div_extend [(UNSPEC_DIVE "e")
14368 (UNSPEC_DIVEO "eo")
14369 (UNSPEC_DIVEU "eu")
14370 (UNSPEC_DIVEUO "euo")])
14371
14372 (define_insn "div<div_extend>_<mode>"
14373 [(set (match_operand:GPR 0 "register_operand" "=r")
14374 (unspec:GPR [(match_operand:GPR 1 "register_operand" "r")
14375 (match_operand:GPR 2 "register_operand" "r")]
14376 UNSPEC_DIV_EXTEND))]
14377 "TARGET_POPCNTD"
14378 "div<wd><div_extend> %0,%1,%2"
14379 [(set_attr "type" "div")
14380 (set_attr "size" "<bits>")])
14381
14382 \f
14383 ;; Pack/unpack 128-bit floating point types that take 2 scalar registers
14384
14385 ; Type of the 64-bit part when packing/unpacking 128-bit floating point types
14386 (define_mode_attr FP128_64 [(TF "DF") (TD "DI")])
14387
14388 (define_expand "unpack<mode>"
14389 [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "")
14390 (unspec:<FP128_64>
14391 [(match_operand:FMOVE128 1 "register_operand" "")
14392 (match_operand:QI 2 "const_0_to_1_operand" "")]
14393 UNSPEC_UNPACK_128BIT))]
14394 ""
14395 "")
14396
14397 (define_insn_and_split "unpack<mode>_dm"
14398 [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m,d,r,m")
14399 (unspec:<FP128_64>
14400 [(match_operand:FMOVE128 1 "register_operand" "d,d,r,d,r")
14401 (match_operand:QI 2 "const_0_to_1_operand" "i,i,i,i,i")]
14402 UNSPEC_UNPACK_128BIT))]
14403 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
14404 "#"
14405 "&& reload_completed"
14406 [(set (match_dup 0) (match_dup 3))]
14407 {
14408 unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
14409
14410 if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
14411 {
14412 emit_note (NOTE_INSN_DELETED);
14413 DONE;
14414 }
14415
14416 operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
14417 }
14418 [(set_attr "type" "fp,fpstore,mffgpr,mftgpr,store")
14419 (set_attr "length" "4")])
14420
14421 (define_insn_and_split "unpack<mode>_nodm"
14422 [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m")
14423 (unspec:<FP128_64>
14424 [(match_operand:FMOVE128 1 "register_operand" "d,d")
14425 (match_operand:QI 2 "const_0_to_1_operand" "i,i")]
14426 UNSPEC_UNPACK_128BIT))]
14427 "!TARGET_POWERPC64 || !TARGET_DIRECT_MOVE"
14428 "#"
14429 "&& reload_completed"
14430 [(set (match_dup 0) (match_dup 3))]
14431 {
14432 unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
14433
14434 if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
14435 {
14436 emit_note (NOTE_INSN_DELETED);
14437 DONE;
14438 }
14439
14440 operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
14441 }
14442 [(set_attr "type" "fp,fpstore")
14443 (set_attr "length" "4")])
14444
14445 (define_insn_and_split "pack<mode>"
14446 [(set (match_operand:FMOVE128 0 "register_operand" "=d,&d")
14447 (unspec:FMOVE128
14448 [(match_operand:<FP128_64> 1 "register_operand" "0,d")
14449 (match_operand:<FP128_64> 2 "register_operand" "d,d")]
14450 UNSPEC_PACK_128BIT))]
14451 ""
14452 "@
14453 fmr %L0,%2
14454 #"
14455 "&& reload_completed && REGNO (operands[0]) != REGNO (operands[1])"
14456 [(set (match_dup 3) (match_dup 1))
14457 (set (match_dup 4) (match_dup 2))]
14458 {
14459 unsigned dest_hi = REGNO (operands[0]);
14460 unsigned dest_lo = dest_hi + 1;
14461
14462 gcc_assert (!IN_RANGE (REGNO (operands[1]), dest_hi, dest_lo));
14463 gcc_assert (!IN_RANGE (REGNO (operands[2]), dest_hi, dest_lo));
14464
14465 operands[3] = gen_rtx_REG (<FP128_64>mode, dest_hi);
14466 operands[4] = gen_rtx_REG (<FP128_64>mode, dest_lo);
14467 }
14468 [(set_attr "type" "fp,fp")
14469 (set_attr "length" "4,8")])
14470
14471 (define_insn "unpackv1ti"
14472 [(set (match_operand:DI 0 "register_operand" "=d,d")
14473 (unspec:DI [(match_operand:V1TI 1 "register_operand" "0,wa")
14474 (match_operand:QI 2 "const_0_to_1_operand" "O,i")]
14475 UNSPEC_UNPACK_128BIT))]
14476 "TARGET_VSX"
14477 {
14478 if (REGNO (operands[0]) == REGNO (operands[1]) && INTVAL (operands[2]) == 0)
14479 return ASM_COMMENT_START " xxpermdi to same register";
14480
14481 operands[3] = GEN_INT (INTVAL (operands[2]) == 0 ? 0 : 3);
14482 return "xxpermdi %x0,%x1,%x1,%3";
14483 }
14484 [(set_attr "type" "vecperm")
14485 (set_attr "length" "4")])
14486
14487 (define_insn "packv1ti"
14488 [(set (match_operand:V1TI 0 "register_operand" "=wa")
14489 (unspec:V1TI
14490 [(match_operand:DI 1 "register_operand" "d")
14491 (match_operand:DI 2 "register_operand" "d")]
14492 UNSPEC_PACK_128BIT))]
14493 "TARGET_VSX"
14494 "xxpermdi %x0,%x1,%x2,0"
14495 [(set_attr "type" "vecperm")
14496 (set_attr "length" "4")])
14497
14498 \f
14499
14500 (include "sync.md")
14501 (include "vector.md")
14502 (include "vsx.md")
14503 (include "altivec.md")
14504 (include "spe.md")
14505 (include "dfp.md")
14506 (include "paired.md")
14507 (include "crypto.md")
14508 (include "htm.md")