]> gcc.gnu.org Git - gcc.git/blame_incremental - gcc/config/rs6000/rs6000.md
Add set_attr for "length" when we are going to split an insn at output time.
[gcc.git] / gcc / config / rs6000 / rs6000.md
... / ...
CommitLineData
1;;- Machine description for IBM RISC System 6000 (POWER) for GNU C compiler
2;; Copyright (C) 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
3;; Contributed by Richard Kenner (kenner@nyu.edu)
4
5;; This file is part of GNU CC.
6
7;; GNU CC is free software; you can redistribute it and/or modify
8;; it under the terms of the GNU General Public License as published by
9;; the Free Software Foundation; either version 2, or (at your option)
10;; any later version.
11
12;; GNU CC is distributed in the hope that it will be useful,
13;; but WITHOUT ANY WARRANTY; without even the implied warranty of
14;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15;; GNU General Public License for more details.
16
17;; You should have received a copy of the GNU General Public License
18;; along with GNU CC; see the file COPYING. If not, write to
19;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
20
21;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
22\f
23;; Define an insn type attribute. This is used in function unit delay
24;; computations.
25(define_attr "type" "integer,load,fpload,imul,idiv,branch,compare,delayed_compare,fpcompare,mtlr,fp,dmul,sdiv,ddiv,ssqrt,dsqrt"
26 (const_string "integer"))
27
28;; Length (in bytes).
29(define_attr "length" ""
30 (if_then_else (eq_attr "type" "branch")
31 (if_then_else (and (ge (minus (pc) (match_dup 0))
32 (const_int -32768))
33 (lt (minus (pc) (match_dup 0))
34 (const_int 32767)))
35 (const_int 8)
36 (const_int 12))
37 (const_int 4)))
38
39;; Processor type -- this attribute must exactly match the processor_type
40;; enumeration in rs6000.h.
41
42(define_attr "cpu" "rios1,rios2,ppc601,ppc603,ppc604,ppc620"
43 (const (symbol_ref "rs6000_cpu_attr")))
44
45; (define_function_unit NAME MULTIPLICITY SIMULTANEITY
46; TEST READY-DELAY ISSUE-DELAY [CONFLICT-LIST])
47
48(define_function_unit "lsu" 1 0
49 (and (eq_attr "type" "load")
50 (eq_attr "cpu" "rios2,ppc603,ppc604,ppc620"))
51 2 0)
52
53(define_function_unit "lsu" 1 0
54 (and (eq_attr "type" "fpload")
55 (eq_attr "cpu" "rios2,ppc603,ppc604,ppc620"))
56 2 0)
57
58(define_function_unit "iu" 1 0
59 (and (eq_attr "type" "load")
60 (eq_attr "cpu" "rios1"))
61 2 0)
62
63(define_function_unit "iu" 1 0
64 (and (eq_attr "type" "fpload")
65 (eq_attr "cpu" "rios1"))
66 3 0)
67
68(define_function_unit "iu" 1 0
69 (and (eq_attr "type" "imul")
70 (eq_attr "cpu" "rios1"))
71 3 0)
72
73(define_function_unit "iu" 1 0
74 (and (eq_attr "type" "imul")
75 (eq_attr "cpu" "ppc601,ppc603,ppc604,ppc620"))
76 5 0)
77
78(define_function_unit "iu" 1 0
79 (and (eq_attr "type" "idiv")
80 (eq_attr "cpu" "rios1"))
81 19 0)
82
83(define_function_unit "iu" 1 0
84 (and (eq_attr "type" "idiv")
85 (eq_attr "cpu" "ppc601,ppc603,ppc604,ppc620"))
86 36 0)
87
88(define_function_unit "bpu" 1 0
89 (eq_attr "type" "compare")
90 4 0)
91
92(define_function_unit "bpu" 1 0
93 (eq_attr "type" "delayed_compare")
94 5 0)
95
96(define_function_unit "bpu" 1 0
97 (and (eq_attr "type" "fpcompare")
98 (eq_attr "cpu" "rios1,rios2"))
99 8 0)
100
101(define_function_unit "bpu" 1 0
102 (and (eq_attr "type" "fpcompare")
103 (eq_attr "cpu" "ppc601,ppc603,ppc604,ppc620"))
104 4 0)
105
106(define_function_unit "bpu" 1 0
107 (and (eq_attr "type" "mtlr")
108 (eq_attr "cpu" "rios1,rios2"))
109 5 0)
110
111(define_function_unit "bpu" 1 0
112 (and (eq_attr "type" "mtlr")
113 (eq_attr "cpu" "ppc601,ppc603,ppc604,ppc620"))
114 4 0)
115
116(define_function_unit "fpu" 1 0
117 (and (eq_attr "type" "fp")
118 (eq_attr "cpu" "rios1"))
119 2 0)
120
121(define_function_unit "fpu" 1 0
122 (and (eq_attr "type" "fp")
123 (eq_attr "cpu" "ppc601,ppc603,ppc604,ppc620"))
124 4 0)
125
126(define_function_unit "fpu" 1 0
127 (and (eq_attr "type" "dmul")
128 (eq_attr "cpu" "rios1"))
129 2 0)
130
131(define_function_unit "fpu" 1 0
132 (and (eq_attr "type" "dmul")
133 (eq_attr "cpu" "ppc601,ppc603,ppc604,ppc620"))
134 5 0)
135
136(define_function_unit "fpu" 1 0
137 (and (eq_attr "type" "sdiv")
138 (eq_attr "cpu" "rios1"))
139 19 0)
140
141(define_function_unit "fpu" 1 0
142 (and (eq_attr "type" "sdiv")
143 (eq_attr "cpu" "ppc601,ppc603,ppc604,ppc620"))
144 17 0)
145
146(define_function_unit "fpu" 1 0
147 (and (eq_attr "type" "ddiv")
148 (eq_attr "cpu" "rios1"))
149 19 0)
150
151(define_function_unit "fpu" 1 0
152 (and (eq_attr "type" "ddiv")
153 (eq_attr "cpu" "ppc601,ppc603,ppc604,ppc620"))
154 31 0)
155
156(define_function_unit "fpu" 1 0
157 (and (eq_attr "type" "ssqrt")
158 (eq_attr "cpu" "ppc603,ppc604,ppc620"))
159 31 0)
160
161(define_function_unit "fpu" 1 0
162 (and (eq_attr "type" "dsqrt")
163 (eq_attr "cpu" "ppc603,ppc604,ppc620"))
164 31 0)
165
166(define_function_unit "iu2" 2 0
167 (and (eq_attr "type" "integer")
168 (eq_attr "cpu" "rios2"))
169 1 0
170 [(eq_attr "type" "imul,idiv")])
171
172(define_function_unit "imuldiv" 1 0
173 (and (eq_attr "type" "imul")
174 (eq_attr "cpu" "rios2"))
175 2 0
176 [(eq_attr "type" "integer")])
177
178(define_function_unit "imuldiv" 1 0
179 (and (eq_attr "type" "idiv")
180 (eq_attr "cpu" "rios2"))
181 13 0
182 [(eq_attr "type" "integer")])
183
184(define_function_unit "fpu2" 2 0
185 (and (eq_attr "type" "fp")
186 (eq_attr "cpu" "rios2"))
187 2 0)
188
189(define_function_unit "fpu2" 2 0
190 (and (eq_attr "type" "dmul")
191 (eq_attr "cpu" "rios2"))
192 2 0)
193
194(define_function_unit "fpu2" 2 0
195 (and (eq_attr "type" "sdiv")
196 (eq_attr "cpu" "rios2"))
197 17 0)
198
199(define_function_unit "fpu2" 2 0
200 (and (eq_attr "type" "ddiv")
201 (eq_attr "cpu" "rios2"))
202 17 0)
203
204(define_function_unit "fpu2" 2 0
205 (and (eq_attr "type" "ssqrt")
206 (eq_attr "cpu" "rios2"))
207 26 0)
208
209(define_function_unit "fpu2" 2 0
210 (and (eq_attr "type" "dsqrt")
211 (eq_attr "cpu" "rios2"))
212 26 0)
213\f
214;; Start with fixed-point load and store insns. Here we put only the more
215;; complex forms. Basic data transfer is done later.
216
217(define_expand "zero_extendqisi2"
218 [(set (match_operand:SI 0 "gpc_reg_operand" "")
219 (zero_extend:SI (match_operand:QI 1 "gpc_reg_operand" "")))]
220 ""
221 "")
222
223(define_insn ""
224 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
225 (zero_extend:SI (match_operand:QI 1 "reg_or_mem_operand" "m,r")))]
226 ""
227 "@
228 lbz%U1%X1 %0,%1
229 {rlinm|rlwinm} %0,%1,0,0xff"
230 [(set_attr "type" "load,*")])
231
232(define_insn ""
233 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
234 (compare:CC (zero_extend:SI (match_operand:QI 1 "gpc_reg_operand" "r"))
235 (const_int 0)))
236 (clobber (match_scratch:SI 2 "=r"))]
237 ""
238 "{andil.|andi.} %2,%1,0xff"
239 [(set_attr "type" "compare")])
240
241(define_insn ""
242 [(set (match_operand:CC 2 "cc_reg_operand" "=x")
243 (compare:CC (zero_extend:SI (match_operand:QI 1 "gpc_reg_operand" "r"))
244 (const_int 0)))
245 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
246 (zero_extend:SI (match_dup 1)))]
247 ""
248 "{andil.|andi.} %0,%1,0xff"
249 [(set_attr "type" "compare")])
250
251(define_expand "zero_extendqihi2"
252 [(set (match_operand:HI 0 "gpc_reg_operand" "")
253 (zero_extend:HI (match_operand:QI 1 "gpc_reg_operand" "")))]
254 ""
255 "")
256
257(define_insn ""
258 [(set (match_operand:HI 0 "gpc_reg_operand" "=r,r")
259 (zero_extend:HI (match_operand:QI 1 "reg_or_mem_operand" "m,r")))]
260 ""
261 "@
262 lbz%U1%X1 %0,%1
263 {rlinm|rlwinm} %0,%1,0,0xff"
264 [(set_attr "type" "load,*")])
265
266(define_expand "zero_extendhisi2"
267 [(set (match_operand:SI 0 "gpc_reg_operand" "")
268 (zero_extend:SI (match_operand:HI 1 "gpc_reg_operand" "")))]
269 ""
270 "")
271
272(define_insn ""
273 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
274 (zero_extend:SI (match_operand:HI 1 "reg_or_mem_operand" "m,r")))]
275 ""
276 "@
277 lhz%U1%X1 %0,%1
278 {rlinm|rlwinm} %0,%1,0,0xffff"
279 [(set_attr "type" "load,*")])
280
281(define_insn ""
282 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
283 (compare:CC (zero_extend:SI (match_operand:HI 1 "gpc_reg_operand" "r"))
284 (const_int 0)))
285 (clobber (match_scratch:SI 2 "=r"))]
286 ""
287 "{andil.|andi.} %2,%1,0xffff"
288 [(set_attr "type" "compare")])
289
290(define_insn ""
291 [(set (match_operand:CC 2 "cc_reg_operand" "=x")
292 (compare:CC (zero_extend:SI (match_operand:HI 1 "gpc_reg_operand" "r"))
293 (const_int 0)))
294 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
295 (zero_extend:SI (match_dup 1)))]
296 ""
297 "{andil.|andi.} %0,%1,0xffff"
298 [(set_attr "type" "compare")])
299
300(define_expand "extendhisi2"
301 [(set (match_operand:SI 0 "gpc_reg_operand" "")
302 (sign_extend:SI (match_operand:HI 1 "gpc_reg_operand" "")))]
303 ""
304 "")
305
306(define_insn ""
307 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
308 (sign_extend:SI (match_operand:HI 1 "reg_or_mem_operand" "m,r")))]
309 ""
310 "@
311 lha%U1%X1 %0,%1
312 {exts|extsh} %0,%1"
313 [(set_attr "type" "load,*")])
314
315(define_insn ""
316 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
317 (compare:CC (sign_extend:SI (match_operand:HI 1 "gpc_reg_operand" "r"))
318 (const_int 0)))
319 (clobber (match_scratch:SI 2 "=r"))]
320 ""
321 "{exts.|extsh.} %2,%1"
322 [(set_attr "type" "compare")])
323
324(define_insn ""
325 [(set (match_operand:CC 2 "cc_reg_operand" "=x")
326 (compare:CC (sign_extend:SI (match_operand:HI 1 "gpc_reg_operand" "r"))
327 (const_int 0)))
328 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
329 (sign_extend:SI (match_dup 1)))]
330 ""
331 "{exts.|extsh.} %0,%1"
332 [(set_attr "type" "compare")])
333\f
334;; Fixed-point arithmetic insns.
335(define_insn "addsi3"
336 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
337 (plus:SI (match_operand:SI 1 "gpc_reg_operand" "%r,b")
338 (match_operand:SI 2 "add_operand" "rI,J")))]
339 ""
340 "@
341 {a%I2|add%I2c} %0,%1,%2
342 {cau|addis} %0,%1,%u2")
343
344(define_insn ""
345 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
346 (compare:CC (plus:SI (match_operand:SI 1 "gpc_reg_operand" "r")
347 (match_operand:SI 2 "reg_or_short_operand" "rI"))
348 (const_int 0)))
349 (clobber (match_scratch:SI 3 "=r"))]
350 ""
351 "{a%I2.|add%I2c.} %3,%1,%2"
352 [(set_attr "type" "compare")])
353
354(define_insn ""
355 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
356 (compare:CC (plus:SI (match_operand:SI 1 "gpc_reg_operand" "r")
357 (match_operand:SI 2 "reg_or_short_operand" "rI"))
358 (const_int 0)))
359 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
360 (plus:SI (match_dup 1) (match_dup 2)))]
361 ""
362 "{a%I2.|add%I2c.} %0,%1,%2"
363 [(set_attr "type" "compare")])
364
365;; Split an add that we can't do in one insn into two insns, each of which
366;; does one 16-bit part. This is used by combine. Note that the low-order
367;; add should be last in case the result gets used in an address.
368
369(define_split
370 [(set (match_operand:SI 0 "gpc_reg_operand" "")
371 (plus:SI (match_operand:SI 1 "gpc_reg_operand" "")
372 (match_operand:SI 2 "non_add_cint_operand" "")))]
373 ""
374 [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))
375 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 4)))]
376"
377{
378 int low = INTVAL (operands[2]) & 0xffff;
379 int high = (unsigned) INTVAL (operands[2]) >> 16;
380
381 if (low & 0x8000)
382 high++, low |= 0xffff0000;
383
384 operands[3] = gen_rtx (CONST_INT, VOIDmode, high << 16);
385 operands[4] = gen_rtx (CONST_INT, VOIDmode, low);
386}")
387
388(define_expand "one_cmplsi2"
389 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
390 (not:SI (match_operand:SI 1 "gpc_reg_operand" "r")))]
391 ""
392 "")
393
394(define_insn ""
395 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
396 (not:SI (match_operand:SI 1 "gpc_reg_operand" "r")))]
397 "TARGET_POWER"
398 "{sfi|subfic} %0,%1,-1")
399
400(define_insn ""
401 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
402 (not:SI (match_operand:SI 1 "gpc_reg_operand" "r")))]
403 "! TARGET_POWER"
404 "nor %0,%1,%1")
405
406(define_insn ""
407 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
408 (compare:CC (not:SI (match_operand:SI 1 "gpc_reg_operand" "r"))
409 (const_int 0)))
410 (clobber (match_scratch:SI 2 "=r"))]
411 ""
412 "nor. %2,%1,%1"
413 [(set_attr "type" "compare")])
414
415(define_insn ""
416 [(set (match_operand:CC 2 "cc_reg_operand" "=-x")
417 (compare:CC (not:SI (match_operand:SI 1 "gpc_reg_operand" "r"))
418 (const_int 0)))
419 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
420 (not:SI (match_dup 1)))]
421 ""
422 "nor. %0,%2,%1"
423 [(set_attr "type" "compare")])
424
425(define_insn ""
426 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
427 (minus:SI (match_operand:SI 1 "reg_or_short_operand" "rI")
428 (match_operand:SI 2 "gpc_reg_operand" "r")))]
429 ""
430 "{sf%I1|subf%I1c} %0,%2,%1")
431
432(define_insn ""
433 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
434 (compare:CC (minus:SI (match_operand:SI 1 "gpc_reg_operand" "r")
435 (match_operand:SI 2 "gpc_reg_operand" "r"))
436 (const_int 0)))
437 (clobber (match_scratch:SI 3 "=r"))]
438 ""
439 "{sf.|subfc.} %3,%2,%1"
440 [(set_attr "type" "compare")])
441
442(define_insn ""
443 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
444 (compare:CC (minus:SI (match_operand:SI 1 "gpc_reg_operand" "r")
445 (match_operand:SI 2 "gpc_reg_operand" "r"))
446 (const_int 0)))
447 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
448 (minus:SI (match_dup 1) (match_dup 2)))]
449 ""
450 "{sf.|subfc.} %0,%2,%1"
451 [(set_attr "type" "compare")])
452
453(define_expand "subsi3"
454 [(set (match_operand:SI 0 "gpc_reg_operand" "")
455 (minus:SI (match_operand:SI 1 "reg_or_short_operand" "")
456 (match_operand:SI 2 "reg_or_cint_operand" "")))]
457 ""
458 "
459{
460 if (GET_CODE (operands[2]) == CONST_INT)
461 {
462 emit_insn (gen_addsi3 (operands[0], operands[1],
463 negate_rtx (SImode, operands[2])));
464 DONE;
465 }
466}")
467
468;; For SMIN, SMAX, UMIN, and UMAX, we use DEFINE_EXPAND's that involve a doz[i]
469;; instruction and some auxiliary computations. Then we just have a single
470;; DEFINE_INSN for doz[i] and the define_splits to make them if made by
471;; combine.
472
473(define_expand "sminsi3"
474 [(set (match_dup 3)
475 (if_then_else:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "")
476 (match_operand:SI 2 "reg_or_short_operand" ""))
477 (const_int 0)
478 (minus:SI (match_dup 2) (match_dup 1))))
479 (set (match_operand:SI 0 "gpc_reg_operand" "")
480 (minus:SI (match_dup 2) (match_dup 3)))]
481 "TARGET_POWER"
482 "
483{ operands[3] = gen_reg_rtx (SImode); }")
484
485(define_split
486 [(set (match_operand:SI 0 "gpc_reg_operand" "")
487 (smin:SI (match_operand:SI 1 "gpc_reg_operand" "")
488 (match_operand:SI 2 "reg_or_short_operand" "")))
489 (clobber (match_operand:SI 3 "gpc_reg_operand" ""))]
490 "TARGET_POWER"
491 [(set (match_dup 3)
492 (if_then_else:SI (gt:SI (match_dup 1) (match_dup 2))
493 (const_int 0)
494 (minus:SI (match_dup 2) (match_dup 1))))
495 (set (match_dup 0) (minus:SI (match_dup 2) (match_dup 3)))]
496 "")
497
498(define_expand "smaxsi3"
499 [(set (match_dup 3)
500 (if_then_else:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "")
501 (match_operand:SI 2 "reg_or_short_operand" ""))
502 (const_int 0)
503 (minus:SI (match_dup 2) (match_dup 1))))
504 (set (match_operand:SI 0 "gpc_reg_operand" "")
505 (plus:SI (match_dup 3) (match_dup 1)))]
506 "TARGET_POWER"
507 "
508{ operands[3] = gen_reg_rtx (SImode); }")
509
510(define_split
511 [(set (match_operand:SI 0 "gpc_reg_operand" "")
512 (smax:SI (match_operand:SI 1 "gpc_reg_operand" "")
513 (match_operand:SI 2 "reg_or_short_operand" "")))
514 (clobber (match_operand:SI 3 "gpc_reg_operand" ""))]
515 "TARGET_POWER"
516 [(set (match_dup 3)
517 (if_then_else:SI (gt:SI (match_dup 1) (match_dup 2))
518 (const_int 0)
519 (minus:SI (match_dup 2) (match_dup 1))))
520 (set (match_dup 0) (plus:SI (match_dup 3) (match_dup 1)))]
521 "")
522
523(define_expand "uminsi3"
524 [(set (match_dup 3) (xor:SI (match_operand:SI 1 "gpc_reg_operand" "")
525 (const_int -2147483648)))
526 (set (match_dup 4) (xor:SI (match_operand:SI 2 "gpc_reg_operand" "")
527 (const_int -2147483648)))
528 (set (match_dup 3) (if_then_else:SI (gt (match_dup 3) (match_dup 4))
529 (const_int 0)
530 (minus:SI (match_dup 4) (match_dup 3))))
531 (set (match_operand:SI 0 "gpc_reg_operand" "")
532 (minus:SI (match_dup 2) (match_dup 3)))]
533 "TARGET_POWER"
534 "
535{ operands[3] = gen_reg_rtx (SImode); operands[4] = gen_reg_rtx (SImode); }")
536
537(define_expand "umaxsi3"
538 [(set (match_dup 3) (xor:SI (match_operand:SI 1 "gpc_reg_operand" "")
539 (const_int -2147483648)))
540 (set (match_dup 4) (xor:SI (match_operand:SI 2 "gpc_reg_operand" "")
541 (const_int -2147483648)))
542 (set (match_dup 3) (if_then_else:SI (gt (match_dup 3) (match_dup 4))
543 (const_int 0)
544 (minus:SI (match_dup 4) (match_dup 3))))
545 (set (match_operand:SI 0 "gpc_reg_operand" "")
546 (plus:SI (match_dup 3) (match_dup 1)))]
547 "TARGET_POWER"
548 "
549{ operands[3] = gen_reg_rtx (SImode); operands[4] = gen_reg_rtx (SImode); }")
550
551(define_insn ""
552 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
553 (if_then_else:SI (gt (match_operand:SI 1 "gpc_reg_operand" "r")
554 (match_operand:SI 2 "reg_or_short_operand" "rI"))
555 (const_int 0)
556 (minus:SI (match_dup 2) (match_dup 1))))]
557 "TARGET_POWER"
558 "doz%I2 %0,%1,%2")
559
560(define_insn ""
561 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
562 (compare:CC
563 (if_then_else:SI (gt (match_operand:SI 1 "gpc_reg_operand" "r")
564 (match_operand:SI 2 "reg_or_short_operand" "rI"))
565 (const_int 0)
566 (minus:SI (match_dup 2) (match_dup 1)))
567 (const_int 0)))
568 (clobber (match_scratch:SI 3 "=r"))]
569 "TARGET_POWER"
570 "doz%I2. %3,%1,%2"
571 [(set_attr "type" "delayed_compare")])
572
573(define_insn ""
574 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
575 (compare:CC
576 (if_then_else:SI (gt (match_operand:SI 1 "gpc_reg_operand" "r")
577 (match_operand:SI 2 "reg_or_short_operand" "rI"))
578 (const_int 0)
579 (minus:SI (match_dup 2) (match_dup 1)))
580 (const_int 0)))
581 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
582 (if_then_else:SI (gt (match_dup 1) (match_dup 2))
583 (const_int 0)
584 (minus:SI (match_dup 2) (match_dup 1))))]
585 "TARGET_POWER"
586 "doz%I2. %0,%1,%2"
587 [(set_attr "type" "delayed_compare")])
588
589;; We don't need abs with condition code because such comparisons should
590;; never be done.
591(define_insn "abssi2"
592 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
593 (abs:SI (match_operand:SI 1 "gpc_reg_operand" "r")))]
594 "TARGET_POWER"
595 "abs %0,%1")
596
597(define_insn ""
598 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
599 (neg:SI (abs:SI (match_operand:SI 1 "gpc_reg_operand" "r"))))]
600 "TARGET_POWER"
601 "nabs %0,%1")
602
603(define_insn "negsi2"
604 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
605 (neg:SI (match_operand:SI 1 "gpc_reg_operand" "r")))]
606 ""
607 "neg %0,%1")
608
609(define_insn ""
610 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
611 (compare:CC (neg:SI (match_operand:SI 1 "gpc_reg_operand" "r"))
612 (const_int 0)))
613 (clobber (match_scratch:SI 2 "=r"))]
614 ""
615 "neg. %2,%1"
616 [(set_attr "type" "compare")])
617
618(define_insn ""
619 [(set (match_operand:CC 2 "cc_reg_operand" "=x")
620 (compare:CC (neg:SI (match_operand:SI 1 "gpc_reg_operand" "r"))
621 (const_int 0)))
622 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
623 (neg:SI (match_dup 1)))]
624 ""
625 "neg. %0,%1"
626 [(set_attr "type" "compare")])
627
628(define_insn "ffssi2"
629 [(set (match_operand:SI 0 "register_operand" "=&r")
630 (ffs:SI (match_operand:SI 1 "register_operand" "r")))]
631 ""
632 "neg %0,%1\;and %0,%0,%1\;cntlz %0,%0\;{sfi|subfic} %0,%0,32"
633 [(set_attr "length" "16")])
634
635(define_expand "mulsi3"
636 [(use (match_operand:SI 0 "gpc_reg_operand" ""))
637 (use (match_operand:SI 1 "gpc_reg_operand" ""))
638 (use (match_operand:SI 2 "reg_or_short_operand" ""))]
639 ""
640 "
641{
642 if (TARGET_POWER)
643 emit_insn (gen_mulsi3_mq (operands[0], operands[1], operands[2]));
644 else
645 emit_insn (gen_mulsi3_no_mq (operands[0], operands[1], operands[2]));
646 DONE;
647}")
648
649(define_insn "mulsi3_mq"
650 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
651 (mult:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r")
652 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
653 (clobber (match_scratch:SI 3 "=q,q"))]
654 "TARGET_POWER"
655 "@
656 {muls|mullw} %0,%1,%2
657 {muli|mulli} %0,%1,%2"
658 [(set_attr "type" "imul")])
659
660(define_insn "mulsi3_no_mq"
661 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
662 (mult:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r")
663 (match_operand:SI 2 "reg_or_short_operand" "r,I")))]
664 "! TARGET_POWER"
665 "@
666 mullw %0,%1,%2
667 mulli %0,%1,%2"
668 [(set_attr "type" "imul")])
669
670(define_insn ""
671 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
672 (compare:CC (mult:SI (match_operand:SI 1 "gpc_reg_operand" "r")
673 (match_operand:SI 2 "gpc_reg_operand" "r"))
674 (const_int 0)))
675 (clobber (match_scratch:SI 3 "=r"))
676 (clobber (match_scratch:SI 4 "=q"))]
677 "TARGET_POWER"
678 "{muls.|mullw.} %3,%1,%2"
679 [(set_attr "type" "delayed_compare")])
680
681(define_insn ""
682 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
683 (compare:CC (mult:SI (match_operand:SI 1 "gpc_reg_operand" "r")
684 (match_operand:SI 2 "gpc_reg_operand" "r"))
685 (const_int 0)))
686 (clobber (match_scratch:SI 3 "=r"))]
687 "TARGET_POWERPC"
688 "mullw. %3,%1,%2"
689 [(set_attr "type" "delayed_compare")])
690
691(define_insn ""
692 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
693 (compare:CC (mult:SI (match_operand:SI 1 "gpc_reg_operand" "r")
694 (match_operand:SI 2 "gpc_reg_operand" "r"))
695 (const_int 0)))
696 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
697 (mult:SI (match_dup 1) (match_dup 2)))
698 (clobber (match_scratch:SI 4 "=q"))]
699 "TARGET_POWER"
700 "{muls.|mullw.} %0,%1,%2"
701 [(set_attr "type" "delayed_compare")])
702
703(define_insn ""
704 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
705 (compare:CC (mult:SI (match_operand:SI 1 "gpc_reg_operand" "r")
706 (match_operand:SI 2 "gpc_reg_operand" "r"))
707 (const_int 0)))
708 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
709 (mult:SI (match_dup 1) (match_dup 2)))]
710 "TARGET_POWERPC"
711 "mullw. %0,%1,%2"
712 [(set_attr "type" "delayed_compare")])
713
714;; Operand 1 is divided by operand 2; quotient goes to operand
715;; 0 and remainder to operand 3.
716;; ??? At some point, see what, if anything, we can do about if (x % y == 0).
717
718(define_insn "divmodsi4"
719 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
720 (div:SI (match_operand:SI 1 "gpc_reg_operand" "r")
721 (match_operand:SI 2 "gpc_reg_operand" "r")))
722 (set (match_operand:SI 3 "gpc_reg_operand" "=q")
723 (mod:SI (match_dup 1) (match_dup 2)))]
724 "TARGET_POWER"
725 "divs %0,%1,%2"
726 [(set_attr "type" "idiv")])
727
728(define_insn ""
729 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
730 (div:SI (match_operand:SI 1 "gpc_reg_operand" "r")
731 (match_operand:SI 2 "gpc_reg_operand" "r")))]
732 "TARGET_POWERPC"
733 "divw %0, %1, %2"
734 [(set_attr "type" "idiv")])
735
736(define_insn "udivsi3"
737 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
738 (udiv:SI (match_operand:SI 1 "gpc_reg_operand" "r")
739 (match_operand:SI 2 "gpc_reg_operand" "r")))]
740 "TARGET_POWERPC"
741 "divwu %0, %1, %2"
742 [(set_attr "type" "idiv")])
743
744;; For powers of two we can do srai/aze for divide and then adjust for
745;; modulus. If it isn't a power of two, FAIL on POWER so divmodsi4 will be
746;; used; for PowerPC, force operands into register and do a normal divide.
747(define_expand "divsi3"
748 [(set (match_operand:SI 0 "gpc_reg_operand" "")
749 (div:SI (match_operand:SI 1 "gpc_reg_operand" "")
750 (match_operand:SI 2 "reg_or_cint_operand" "")))]
751 ""
752 "
753{
754 if (GET_CODE (operands[2]) == CONST_INT
755 && exact_log2 (INTVAL (operands[2])) >= 0)
756 ;
757
758 else if (TARGET_POWER)
759 FAIL;
760
761 else if (TARGET_POWERPC)
762 operands[2] = force_reg (SImode, operands[2]);
763}")
764
765(define_expand "modsi3"
766 [(set (match_dup 3)
767 (div:SI (match_operand:SI 1 "gpc_reg_operand" "")
768 (match_operand:SI 2 "reg_or_cint_operand" "")))
769 (parallel [(set (match_dup 4) (ashift:SI (match_dup 3) (match_dup 5)))
770 (clobber (scratch:SI))])
771 (set (match_operand:SI 0 "gpc_reg_operand" "")
772 (minus:SI (match_dup 1) (match_dup 4)))]
773 ""
774 "
775{
776 int i = exact_log2 (INTVAL (operands[2]));
777
778 if (GET_CODE (operands[2]) != CONST_INT || i < 0)
779 FAIL;
780
781 operands[3] = gen_reg_rtx (SImode);
782 operands[4] = gen_reg_rtx (SImode);
783 operands[5] = gen_rtx (CONST_INT, VOIDmode, i);
784}")
785
786(define_insn ""
787 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
788 (div:SI (match_operand:SI 1 "gpc_reg_operand" "r")
789 (match_operand:SI 2 "const_int_operand" "N")))]
790 "exact_log2 (INTVAL (operands[2])) >= 0"
791 "{srai|srawi} %0,%1,%p2\;{aze|addze} %0,%0"
792 [(set_attr "length" "8")])
793
794(define_insn ""
795 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
796 (div:SI (match_operand:SI 1 "gpc_reg_operand" "r")
797 (match_operand:SI 2 "const_int_operand" "N")))
798 (clobber (match_scratch:SI 3 "=r"))]
799 "exact_log2 (INTVAL (operands[2])) >= 0"
800 "{srai|srawi} %3,%1,%p2\;{aze.|addze.} %3,%3"
801 [(set_attr "type" "compare")
802 (set_attr "length" "8")])
803
804(define_insn ""
805 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
806 (div:SI (match_operand:SI 1 "gpc_reg_operand" "r")
807 (match_operand:SI 2 "const_int_operand" "N")))
808 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
809 (div:SI (match_dup 1) (match_dup 2)))]
810 "exact_log2 (INTVAL (operands[2])) >= 0"
811 "{srai|srawi} %0,%1,%p2\;{aze.|addze.} %0,%0"
812 [(set_attr "type" "compare")
813 (set_attr "length" "8")])
814
815(define_insn ""
816 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
817 (udiv:SI
818 (plus:DI (lshift:DI
819 (zero_extend:DI (match_operand:SI 1 "gpc_reg_operand" "r"))
820 (const_int 32))
821 (zero_extend:DI (match_operand:SI 4 "register_operand" "2")))
822 (match_operand:SI 3 "gpc_reg_operand" "r")))
823 (set (match_operand:SI 2 "register_operand" "=*q")
824 (umod:SI
825 (plus:DI (lshift:DI
826 (zero_extend:DI (match_dup 1)) (const_int 32))
827 (zero_extend:DI (match_dup 4)))
828 (match_dup 3)))]
829
830 "TARGET_POWER"
831 "div %0,%1,%3"
832 [(set_attr "type" "idiv")])
833
834;; To do unsigned divide we handle the cases of the divisor looking like a
835;; negative number. If it is a constant that is less than 2**31, we don't
836;; have to worry about the branches. So make a few subroutines here.
837;;
838;; First comes the normal case.
839(define_expand "udivmodsi4_normal"
840 [(set (match_dup 4) (const_int 0))
841 (parallel [(set (match_operand:SI 0 "" "")
842 (udiv:SI (plus:DI (lshift:DI (zero_extend:DI (match_dup 4))
843 (const_int 32))
844 (zero_extend:DI (match_operand:SI 1 "" "")))
845 (match_operand:SI 2 "" "")))
846 (set (match_operand:SI 3 "" "")
847 (umod:SI (plus:DI (lshift:DI (zero_extend:DI (match_dup 4))
848 (const_int 32))
849 (zero_extend:DI (match_dup 1)))
850 (match_dup 2)))])]
851 "TARGET_POWER"
852 "
853{ operands[4] = gen_reg_rtx (SImode); }")
854
855;; This handles the branches.
856(define_expand "udivmodsi4_tests"
857 [(set (match_operand:SI 0 "" "") (const_int 0))
858 (set (match_operand:SI 3 "" "") (match_operand:SI 1 "" ""))
859 (set (match_dup 5) (compare:CCUNS (match_dup 1) (match_operand:SI 2 "" "")))
860 (set (pc) (if_then_else (ltu (match_dup 5) (const_int 0))
861 (label_ref (match_operand:SI 4 "" "")) (pc)))
862 (set (match_dup 0) (const_int 1))
863 (set (match_dup 3) (minus:SI (match_dup 1) (match_dup 2)))
864 (set (match_dup 6) (compare:CC (match_dup 2) (const_int 0)))
865 (set (pc) (if_then_else (lt (match_dup 6) (const_int 0))
866 (label_ref (match_dup 4)) (pc)))]
867 "TARGET_POWER"
868 "
869{ operands[5] = gen_reg_rtx (CCUNSmode);
870 operands[6] = gen_reg_rtx (CCmode);
871}")
872
873(define_expand "udivmodsi4"
874 [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "")
875 (udiv:SI (match_operand:SI 1 "gpc_reg_operand" "")
876 (match_operand:SI 2 "reg_or_cint_operand" "")))
877 (set (match_operand:SI 3 "gpc_reg_operand" "")
878 (umod:SI (match_dup 1) (match_dup 2)))])]
879 "TARGET_POWER"
880 "
881{
882 rtx label = 0;
883
884 if (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) < 0)
885 {
886 operands[2] = force_reg (SImode, operands[2]);
887 label = gen_label_rtx ();
888 emit (gen_udivmodsi4_tests (operands[0], operands[1], operands[2],
889 operands[3], label));
890 }
891 else
892 operands[2] = force_reg (SImode, operands[2]);
893
894 emit (gen_udivmodsi4_normal (operands[0], operands[1], operands[2],
895 operands[3]));
896 if (label)
897 emit_label (label);
898
899 DONE;
900}")
901
902(define_insn "andsi3"
903 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r")
904 (and:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r")
905 (match_operand:SI 2 "and_operand" "?r,L,K,J")))
906 (clobber (match_scratch:CC 3 "=X,X,x,x"))]
907 ""
908 "@
909 and %0,%1,%2
910 {rlinm|rlwinm} %0,%1,0,%m2,%M2
911 {andil.|andi.} %0,%1,%b2
912 {andiu.|andis.} %0,%1,%u2")
913
914(define_insn ""
915 [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,x,x")
916 (compare:CC (and:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r")
917 (match_operand:SI 2 "and_operand" "r,K,J,L"))
918 (const_int 0)))
919 (clobber (match_scratch:SI 3 "=r,r,r,r"))]
920 ""
921 "@
922 and. %3,%1,%2
923 {andil.|andi.} %3,%1,%b2
924 {andiu.|andis.} %3,%1,%u2
925 {rlinm.|rlwinm.} %3,%1,0,%m2,%M2"
926 [(set_attr "type" "compare,compare,compare,delayed_compare")])
927
928(define_insn ""
929 [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,x,x")
930 (compare:CC (and:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r")
931 (match_operand:SI 2 "and_operand" "r,K,J,L"))
932 (const_int 0)))
933 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r")
934 (and:SI (match_dup 1) (match_dup 2)))]
935 ""
936 "@
937 and. %0,%1,%2
938 {andil.|andi.} %0,%1,%b2
939 {andiu.|andis.} %0,%1,%u2
940 {rlinm.|rlwinm.} %0,%1,0,%m2,%M2"
941 [(set_attr "type" "compare,compare,compare,delayed_compare")])
942
943;; Take a AND with a constant that cannot be done in a single insn and try to
944;; split it into two insns. This does not verify that the insns are valid
945;; since this need not be done as combine will do it.
946
947(define_split
948 [(set (match_operand:SI 0 "gpc_reg_operand" "")
949 (and:SI (match_operand:SI 1 "gpc_reg_operand" "")
950 (match_operand:SI 2 "non_and_cint_operand" "")))]
951 ""
952 [(set (match_dup 0) (and:SI (match_dup 1) (match_dup 3)))
953 (set (match_dup 0) (and:SI (match_dup 0) (match_dup 4)))]
954 "
955{
956 int maskval = INTVAL (operands[2]);
957 int i, transitions, last_bit_value;
958 int orig = maskval, first_c = maskval, second_c;
959
960 /* We know that MASKVAL must have more than 2 bit-transitions. Start at
961 the low-order bit and count for the third transition. When we get there,
962 make a first mask that has everything to the left of that position
963 a one. Then make the second mask to turn off whatever else is needed. */
964
965 for (i = 1, transitions = 0, last_bit_value = maskval & 1; i < 32; i++)
966 {
967 if (((maskval >>= 1) & 1) != last_bit_value)
968 last_bit_value ^= 1, transitions++;
969
970 if (transitions > 2)
971 {
972 first_c |= (~0) << i;
973 break;
974 }
975 }
976
977 second_c = orig | ~ first_c;
978
979 operands[3] = gen_rtx (CONST_INT, VOIDmode, first_c);
980 operands[4] = gen_rtx (CONST_INT, VOIDmode, second_c);
981}")
982
983(define_insn "iorsi3"
984 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r")
985 (ior:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r")
986 (match_operand:SI 2 "logical_operand" "r,K,J")))]
987 ""
988 "@
989 or %0,%1,%2
990 {oril|ori} %0,%1,%b2
991 {oriu|oris} %0,%1,%u2")
992
993(define_insn ""
994 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
995 (compare:CC (ior:SI (match_operand:SI 1 "gpc_reg_operand" "r")
996 (match_operand:SI 2 "gpc_reg_operand" "r"))
997 (const_int 0)))
998 (clobber (match_scratch:SI 3 "=r"))]
999 ""
1000 "or. %3,%1,%2"
1001 [(set_attr "type" "compare")])
1002
1003(define_insn ""
1004 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1005 (compare:CC (ior:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1006 (match_operand:SI 2 "gpc_reg_operand" "r"))
1007 (const_int 0)))
1008 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1009 (ior:SI (match_dup 1) (match_dup 2)))]
1010 ""
1011 "or. %0,%1,%2"
1012 [(set_attr "type" "compare")])
1013
1014;; Split an IOR that we can't do in one insn into two insns, each of which
1015;; does one 16-bit part. This is used by combine.
1016
1017(define_split
1018 [(set (match_operand:SI 0 "gpc_reg_operand" "")
1019 (ior:SI (match_operand:SI 1 "gpc_reg_operand" "")
1020 (match_operand:SI 2 "non_logical_cint_operand" "")))]
1021 ""
1022 [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 3)))
1023 (set (match_dup 0) (ior:SI (match_dup 0) (match_dup 4)))]
1024"
1025{
1026 operands[3] = gen_rtx (CONST_INT, VOIDmode,
1027 INTVAL (operands[2]) & 0xffff0000);
1028 operands[4] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) & 0xffff);
1029}")
1030
1031(define_insn "xorsi3"
1032 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r")
1033 (xor:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r")
1034 (match_operand:SI 2 "logical_operand" "r,K,J")))]
1035 ""
1036 "@
1037 xor %0,%1,%2
1038 {xoril|xori} %0,%1,%b2
1039 {xoriu|xoris} %0,%1,%u2")
1040
1041(define_insn ""
1042 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
1043 (compare:CC (xor:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1044 (match_operand:SI 2 "gpc_reg_operand" "r"))
1045 (const_int 0)))
1046 (clobber (match_scratch:SI 3 "=r"))]
1047 ""
1048 "xor. %3,%1,%2"
1049 [(set_attr "type" "compare")])
1050
1051(define_insn ""
1052 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1053 (compare:CC (xor:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1054 (match_operand:SI 2 "gpc_reg_operand" "r"))
1055 (const_int 0)))
1056 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1057 (xor:SI (match_dup 1) (match_dup 2)))]
1058 ""
1059 "xor. %0,%1,%2"
1060 [(set_attr "type" "compare")])
1061
1062;; Split an XOR that we can't do in one insn into two insns, each of which
1063;; does one 16-bit part. This is used by combine.
1064
1065(define_split
1066 [(set (match_operand:SI 0 "gpc_reg_operand" "")
1067 (xor:SI (match_operand:SI 1 "gpc_reg_operand" "")
1068 (match_operand:SI 2 "non_logical_cint_operand" "")))]
1069 ""
1070 [(set (match_dup 0) (xor:SI (match_dup 1) (match_dup 3)))
1071 (set (match_dup 0) (xor:SI (match_dup 0) (match_dup 4)))]
1072"
1073{
1074 operands[3] = gen_rtx (CONST_INT, VOIDmode,
1075 INTVAL (operands[2]) & 0xffff0000);
1076 operands[4] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) & 0xffff);
1077}")
1078
1079(define_insn ""
1080 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1081 (not:SI (xor:SI (match_operand:SI 1 "gpc_reg_operand" "%r")
1082 (match_operand:SI 2 "gpc_reg_operand" "r"))))]
1083 ""
1084 "eqv %0,%1,%2")
1085
1086(define_insn ""
1087 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
1088 (compare:CC (not:SI (xor:SI (match_operand:SI 1 "gpc_reg_operand" "%r")
1089 (match_operand:SI 2 "gpc_reg_operand" "r")))
1090 (const_int 0)))
1091 (clobber (match_scratch:SI 3 "=r"))]
1092 ""
1093 "eqv. %3,%1,%2"
1094 [(set_attr "type" "compare")])
1095
1096(define_insn ""
1097 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1098 (compare:CC (not:SI (xor:SI (match_operand:SI 1 "gpc_reg_operand" "%r")
1099 (match_operand:SI 2 "gpc_reg_operand" "r")))
1100 (const_int 0)))
1101 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1102 (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
1103 ""
1104 "eqv. %0,%1,%2"
1105 [(set_attr "type" "compare")])
1106
1107(define_insn ""
1108 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1109 (and:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "r"))
1110 (match_operand:SI 2 "gpc_reg_operand" "r")))]
1111 ""
1112 "andc %0,%2,%1")
1113
1114(define_insn ""
1115 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
1116 (compare:CC (and:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "r"))
1117 (match_operand:SI 2 "gpc_reg_operand" "r"))
1118 (const_int 0)))
1119 (clobber (match_scratch:SI 3 "=r"))]
1120 ""
1121 "andc. %3,%2,%1"
1122 [(set_attr "type" "compare")])
1123
1124(define_insn ""
1125 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1126 (compare:CC (and:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "r"))
1127 (match_operand:SI 2 "gpc_reg_operand" "r"))
1128 (const_int 0)))
1129 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1130 (and:SI (not:SI (match_dup 1)) (match_dup 2)))]
1131 ""
1132 "andc. %0,%2,%1"
1133 [(set_attr "type" "compare")])
1134
1135(define_insn ""
1136 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1137 (ior:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "r"))
1138 (match_operand:SI 2 "gpc_reg_operand" "r")))]
1139 ""
1140 "orc %0,%2,%1")
1141
1142(define_insn ""
1143 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
1144 (compare:CC (ior:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "r"))
1145 (match_operand:SI 2 "gpc_reg_operand" "r"))
1146 (const_int 0)))
1147 (clobber (match_scratch:SI 3 "=r"))]
1148 ""
1149 "orc. %3,%2,%1"
1150 [(set_attr "type" "compare")])
1151
1152(define_insn ""
1153 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1154 (compare:CC (ior:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "r"))
1155 (match_operand:SI 2 "gpc_reg_operand" "r"))
1156 (const_int 0)))
1157 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1158 (ior:SI (not:SI (match_dup 1)) (match_dup 2)))]
1159 ""
1160 "orc. %0,%2,%1"
1161 [(set_attr "type" "compare")])
1162
1163(define_insn ""
1164 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1165 (ior:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "r"))
1166 (not:SI (match_operand:SI 2 "gpc_reg_operand" "r"))))]
1167 ""
1168 "nand %0,%1,%2")
1169
1170(define_insn ""
1171 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
1172 (compare:CC (ior:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "r"))
1173 (not:SI (match_operand:SI 2 "gpc_reg_operand" "r")))
1174 (const_int 0)))
1175 (clobber (match_scratch:SI 3 "=r"))]
1176 ""
1177 "nand. %3,%1,%2"
1178 [(set_attr "type" "compare")])
1179
1180(define_insn ""
1181 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1182 (compare:CC (ior:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "r"))
1183 (not:SI (match_operand:SI 2 "gpc_reg_operand" "r")))
1184 (const_int 0)))
1185 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1186 (ior:SI (not:SI (match_dup 1)) (not:SI (match_dup 2))))]
1187 ""
1188 "nand. %0,%1,%2"
1189 [(set_attr "type" "compare")])
1190
1191(define_insn ""
1192 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1193 (and:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "r"))
1194 (not:SI (match_operand:SI 2 "gpc_reg_operand" "r"))))]
1195 ""
1196 "nor %0,%1,%2")
1197
1198(define_insn ""
1199 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
1200 (compare:CC (and:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "r"))
1201 (not:SI (match_operand:SI 2 "gpc_reg_operand" "r")))
1202 (const_int 0)))
1203 (clobber (match_scratch:SI 3 "=r"))]
1204 ""
1205 "nor. %3,%1,%2"
1206 [(set_attr "type" "compare")])
1207
1208(define_insn ""
1209 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1210 (compare:CC (and:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "r"))
1211 (not:SI (match_operand:SI 2 "gpc_reg_operand" "r")))
1212 (const_int 0)))
1213 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1214 (and:SI (not:SI (match_dup 1)) (not:SI (match_dup 2))))]
1215 ""
1216 "nor. %0,%1,%2"
1217 [(set_attr "type" "compare")])
1218
1219;; maskir insn. We need four forms because things might be in arbitrary
1220;; orders. Don't define forms that only set CR fields because these
1221;; would modify an input register.
1222
1223(define_insn ""
1224 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1225 (ior:SI (and:SI (not:SI (match_operand:SI 2 "gpc_reg_operand" "r"))
1226 (match_operand:SI 1 "gpc_reg_operand" "0"))
1227 (and:SI (match_dup 2)
1228 (match_operand:SI 3 "gpc_reg_operand" "r"))))]
1229 "TARGET_POWER"
1230 "maskir %0,%3,%2")
1231
1232(define_insn ""
1233 [(set (match_operand:SI 0 "register_operand" "=r")
1234 (ior:SI (and:SI (not:SI (match_operand:SI 2 "gpc_reg_operand" "r"))
1235 (match_operand:SI 1 "gpc_reg_operand" "0"))
1236 (and:SI (match_operand:SI 3 "gpc_reg_operand" "r")
1237 (match_dup 2))))]
1238 "TARGET_POWER"
1239 "maskir %0,%3,%2")
1240
1241(define_insn ""
1242 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1243 (ior:SI (and:SI (match_operand:SI 2 "gpc_reg_operand" "r")
1244 (match_operand:SI 3 "gpc_reg_operand" "r"))
1245 (and:SI (not:SI (match_dup 2))
1246 (match_operand:SI 1 "gpc_reg_operand" "0"))))]
1247 "TARGET_POWER"
1248 "maskir %0,%3,%2")
1249
1250(define_insn ""
1251 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1252 (ior:SI (and:SI (match_operand:SI 3 "gpc_reg_operand" "r")
1253 (match_operand:SI 2 "gpc_reg_operand" "r"))
1254 (and:SI (not:SI (match_dup 2))
1255 (match_operand:SI 1 "gpc_reg_operand" "0"))))]
1256 "TARGET_POWER"
1257 "maskir %0,%3,%2")
1258
1259(define_insn ""
1260 [(set (match_operand:CC 4 "cc_reg_operand" "=x")
1261 (compare:CC
1262 (ior:SI (and:SI (not:SI (match_operand:SI 2 "gpc_reg_operand" "r"))
1263 (match_operand:SI 1 "gpc_reg_operand" "0"))
1264 (and:SI (match_dup 2)
1265 (match_operand:SI 3 "gpc_reg_operand" "r")))
1266 (const_int 0)))
1267 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1268 (ior:SI (and:SI (not:SI (match_dup 2)) (match_dup 1))
1269 (and:SI (match_dup 2) (match_dup 3))))]
1270 "TARGET_POWER"
1271 "maskir. %0,%3,%2"
1272 [(set_attr "type" "compare")])
1273
1274(define_insn ""
1275 [(set (match_operand:CC 4 "cc_reg_operand" "=x")
1276 (compare:CC
1277 (ior:SI (and:SI (not:SI (match_operand:SI 2 "gpc_reg_operand" "r"))
1278 (match_operand:SI 1 "gpc_reg_operand" "0"))
1279 (and:SI (match_operand:SI 3 "gpc_reg_operand" "r")
1280 (match_dup 2)))
1281 (const_int 0)))
1282 (set (match_operand:SI 0 "register_operand" "=r")
1283 (ior:SI (and:SI (not:SI (match_dup 2)) (match_dup 1))
1284 (and:SI (match_dup 3) (match_dup 2))))]
1285 "TARGET_POWER"
1286 "maskir. %0,%3,%2"
1287 [(set_attr "type" "compare")])
1288
1289(define_insn ""
1290 [(set (match_operand:CC 4 "cc_reg_operand" "=x")
1291 (compare:CC
1292 (ior:SI (and:SI (match_operand:SI 2 "gpc_reg_operand" "r")
1293 (match_operand:SI 3 "gpc_reg_operand" "r"))
1294 (and:SI (not:SI (match_dup 2))
1295 (match_operand:SI 1 "gpc_reg_operand" "0")))
1296 (const_int 0)))
1297 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1298 (ior:SI (and:SI (match_dup 2) (match_dup 3))
1299 (and:SI (not:SI (match_dup 2)) (match_dup 1))))]
1300 "TARGET_POWER"
1301 "maskir. %0,%3,%2"
1302 [(set_attr "type" "compare")])
1303
1304(define_insn ""
1305 [(set (match_operand:CC 4 "cc_reg_operand" "=x")
1306 (compare:CC
1307 (ior:SI (and:SI (match_operand:SI 3 "gpc_reg_operand" "r")
1308 (match_operand:SI 2 "gpc_reg_operand" "r"))
1309 (and:SI (not:SI (match_dup 2))
1310 (match_operand:SI 1 "gpc_reg_operand" "0")))
1311 (const_int 0)))
1312 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1313 (ior:SI (and:SI (match_dup 3) (match_dup 2))
1314 (and:SI (not:SI (match_dup 2)) (match_dup 1))))]
1315 "TARGET_POWER"
1316 "maskir. %0,%3,%2"
1317 [(set_attr "type" "compare")])
1318\f
1319;; Rotate and shift insns, in all their variants. These support shifts,
1320;; field inserts and extracts, and various combinations thereof.
1321(define_insn "insv"
1322 [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r")
1323 (match_operand:SI 1 "const_int_operand" "i")
1324 (match_operand:SI 2 "const_int_operand" "i"))
1325 (match_operand:SI 3 "gpc_reg_operand" "r"))]
1326 ""
1327 "*
1328{
1329 int start = INTVAL (operands[2]) & 31;
1330 int size = INTVAL (operands[1]) & 31;
1331
1332 operands[4] = gen_rtx (CONST_INT, VOIDmode, 32 - start - size);
1333 operands[1] = gen_rtx (CONST_INT, VOIDmode, start + size - 1);
1334 return \"{rlimi|rlwimi} %0,%3,%4,%h2,%h1\";
1335}")
1336
1337(define_insn "extzv"
1338 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1339 (zero_extract:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1340 (match_operand:SI 2 "const_int_operand" "i")
1341 (match_operand:SI 3 "const_int_operand" "i")))]
1342 ""
1343 "*
1344{
1345 int start = INTVAL (operands[3]) & 31;
1346 int size = INTVAL (operands[2]) & 31;
1347
1348 if (start + size >= 32)
1349 operands[3] = const0_rtx;
1350 else
1351 operands[3] = gen_rtx (CONST_INT, VOIDmode, start + size);
1352 return \"{rlinm|rlwinm} %0,%1,%3,%s2,31\";
1353}")
1354
1355(define_insn ""
1356 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
1357 (compare:CC (zero_extract:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1358 (match_operand:SI 2 "const_int_operand" "i")
1359 (match_operand:SI 3 "const_int_operand" "i"))
1360 (const_int 0)))
1361 (clobber (match_scratch:SI 4 "=r"))]
1362 ""
1363 "*
1364{
1365 int start = INTVAL (operands[3]) & 31;
1366 int size = INTVAL (operands[2]) & 31;
1367
1368 /* If the bitfield being tested fits in the upper or lower half of a
1369 word, it is possible to use andiu. or andil. to test it. This is
1370 useful because the condition register set-use delay is smaller for
1371 andi[ul]. than for rlinm. This doesn't work when the starting bit
1372 position is 0 because the LT and GT bits may be set wrong. */
1373
1374 if ((start > 0 && start + size <= 16) || start >= 16)
1375 {
1376 operands[3] = gen_rtx (CONST_INT, VOIDmode,
1377 ((1 << (16 - (start & 15)))
1378 - (1 << (16 - (start & 15) - size))));
1379 if (start < 16)
1380 return \"{andiu.|andis.} %4,%1,%3\";
1381 else
1382 return \"{andil.|andi.} %4,%1,%3\";
1383 }
1384
1385 if (start + size >= 32)
1386 operands[3] = const0_rtx;
1387 else
1388 operands[3] = gen_rtx (CONST_INT, VOIDmode, start + size);
1389 return \"{rlinm.|rlwinm.} %4,%1,%3,%s2,31\";
1390}"
1391 [(set_attr "type" "compare")])
1392
1393(define_insn ""
1394 [(set (match_operand:CC 4 "cc_reg_operand" "=x")
1395 (compare:CC (zero_extract:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1396 (match_operand:SI 2 "const_int_operand" "i")
1397 (match_operand:SI 3 "const_int_operand" "i"))
1398 (const_int 0)))
1399 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1400 (zero_extract:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
1401 ""
1402 "*
1403{
1404 int start = INTVAL (operands[3]) & 31;
1405 int size = INTVAL (operands[2]) & 31;
1406
1407 if (start >= 16 && start + size == 32)
1408 {
1409 operands[3] = gen_rtx (CONST_INT, VOIDmode, (1 << (32 - start)) - 1);
1410 return \"{andil.|andi.} %0,%1,%3\";
1411 }
1412
1413 if (start + size >= 32)
1414 operands[3] = const0_rtx;
1415 else
1416 operands[3] = gen_rtx (CONST_INT, VOIDmode, start + size);
1417 return \"{rlinm.|rlwinm.} %0,%1,%3,%s2,31\";
1418}"
1419 [(set_attr "type" "delayed_compare")])
1420
1421(define_insn "rotlsi3"
1422 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1423 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1424 (match_operand:SI 2 "reg_or_cint_operand" "ri")))]
1425 ""
1426 "{rl%I2nm|rlw%I2nm} %0,%1,%h2,0xffffffff")
1427
1428(define_insn ""
1429 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
1430 (compare:CC (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1431 (match_operand:SI 2 "reg_or_cint_operand" "ri"))
1432 (const_int 0)))
1433 (clobber (match_scratch:SI 3 "=r"))]
1434 ""
1435 "{rl%I2nm.|rlw%I2nm.} %3,%1,%h2,0xffffffff"
1436 [(set_attr "type" "delayed_compare")])
1437
1438(define_insn ""
1439 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1440 (compare:CC (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1441 (match_operand:SI 2 "reg_or_cint_operand" "ri"))
1442 (const_int 0)))
1443 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1444 (rotate:SI (match_dup 1) (match_dup 2)))]
1445 ""
1446 "{rl%I2nm.|rlw%I2nm.} %0,%1,%h2,0xffffffff"
1447 [(set_attr "type" "delayed_compare")])
1448
1449(define_insn ""
1450 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1451 (and:SI (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1452 (match_operand:SI 2 "reg_or_cint_operand" "ri"))
1453 (match_operand:SI 3 "mask_operand" "L")))]
1454 ""
1455 "{rl%I2nm|rlw%I2nm} %0,%1,%h2,%m3,%M3")
1456
1457(define_insn ""
1458 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
1459 (compare:CC (and:SI
1460 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1461 (match_operand:SI 2 "reg_or_cint_operand" "ri"))
1462 (match_operand:SI 3 "mask_operand" "L"))
1463 (const_int 0)))
1464 (clobber (match_scratch:SI 4 "=r"))]
1465 ""
1466 "{rl%I2nm.|rlw%I2nm.} %4,%1,%h2,%m3,%M3"
1467 [(set_attr "type" "delayed_compare")])
1468
1469(define_insn ""
1470 [(set (match_operand:CC 4 "cc_reg_operand" "=x")
1471 (compare:CC (and:SI
1472 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1473 (match_operand:SI 2 "reg_or_cint_operand" "ri"))
1474 (match_operand:SI 3 "mask_operand" "L"))
1475 (const_int 0)))
1476 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1477 (and:SI (rotate:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
1478 ""
1479 "{rl%I2nm.|rlw%I2nm.} %0,%1,%h2,%m3,%M3"
1480 [(set_attr "type" "delayed_compare")])
1481
1482(define_insn ""
1483 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1484 (zero_extend:SI
1485 (subreg:QI
1486 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1487 (match_operand:SI 2 "reg_or_cint_operand" "ri")) 0)))]
1488 ""
1489 "{rl%I2nm|rlw%I2nm} %0,%1,%h2,0xff")
1490
1491(define_insn ""
1492 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
1493 (compare:CC (zero_extend:SI
1494 (subreg:QI
1495 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1496 (match_operand:SI 2 "reg_or_cint_operand" "ri")) 0))
1497 (const_int 0)))
1498 (clobber (match_scratch:SI 3 "=r"))]
1499 ""
1500 "{rl%I2nm.|rlw%I2nm.} %3,%1,%h2,0xff"
1501 [(set_attr "type" "delayed_compare")])
1502
1503(define_insn ""
1504 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1505 (compare:CC (zero_extend:SI
1506 (subreg:QI
1507 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1508 (match_operand:SI 2 "reg_or_cint_operand" "ri")) 0))
1509 (const_int 0)))
1510 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1511 (zero_extend:SI (subreg:QI (rotate:SI (match_dup 1) (match_dup 2)) 0)))]
1512 ""
1513 "{rl%I2nm.|rlw%I2nm.} %0,%1,%h2,0xff"
1514 [(set_attr "type" "delayed_compare")])
1515
1516(define_insn ""
1517 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1518 (zero_extend:SI
1519 (subreg:HI
1520 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1521 (match_operand:SI 2 "reg_or_cint_operand" "ri")) 0)))]
1522 ""
1523 "{rl%I2nm|rlw%I2nm} %0,%1,%h2,0xffff")
1524
1525(define_insn ""
1526 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
1527 (compare:CC (zero_extend:SI
1528 (subreg:HI
1529 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1530 (match_operand:SI 2 "reg_or_cint_operand" "ri")) 0))
1531 (const_int 0)))
1532 (clobber (match_scratch:SI 3 "=r"))]
1533 ""
1534 "{rl%I2nm.|rlw%I2nm.} %3,%1,%h2,0xffff"
1535 [(set_attr "type" "delayed_compare")])
1536
1537(define_insn ""
1538 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1539 (compare:CC (zero_extend:SI
1540 (subreg:HI
1541 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1542 (match_operand:SI 2 "reg_or_cint_operand" "ri")) 0))
1543 (const_int 0)))
1544 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1545 (zero_extend:SI (subreg:HI (rotate:SI (match_dup 1) (match_dup 2)) 0)))]
1546 ""
1547 "{rl%I2nm.|rlw%I2nm.} %0,%1,%h2,0xffff"
1548 [(set_attr "type" "delayed_compare")])
1549
1550;; Note that we use "sle." instead of "sl." so that we can set
1551;; SHIFT_COUNT_TRUNCATED.
1552
1553(define_expand "ashlsi3"
1554 [(use (match_operand:SI 0 "gpc_reg_operand" ""))
1555 (use (match_operand:SI 1 "gpc_reg_operand" ""))
1556 (use (match_operand:SI 2 "reg_or_cint_operand" ""))]
1557 ""
1558 "
1559{
1560 if (TARGET_POWER)
1561 emit_insn (gen_ashlsi3_power (operands[0], operands[1], operands[2]));
1562 else
1563 emit_insn (gen_ashlsi3_powerpc (operands[0], operands[1], operands[2]));
1564 DONE;
1565}")
1566
1567(define_insn "ashlsi3_power"
1568 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
1569 (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1570 (match_operand:SI 2 "reg_or_cint_operand" "r,i")))
1571 (clobber (match_scratch:SI 3 "=q,X"))]
1572 "TARGET_POWER"
1573 "@
1574 sle %0,%1,%2
1575 {sli|slwi} %0,%1,%h2"
1576 [(set_attr "length" "8")])
1577
1578(define_insn "ashlsi3_powerpc"
1579 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1580 (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1581 (match_operand:SI 2 "reg_or_cint_operand" "ri")))]
1582 "TARGET_POWERPC"
1583 "slw%I2 %0,%1,%2"
1584 [(set_attr "length" "8")])
1585
1586(define_insn ""
1587 [(set (match_operand:CC 0 "cc_reg_operand" "=x,x")
1588 (compare:CC (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1589 (match_operand:SI 2 "reg_or_cint_operand" "r,i"))
1590 (const_int 0)))
1591 (clobber (match_scratch:SI 3 "=r,r"))
1592 (clobber (match_scratch:SI 4 "=q,X"))]
1593 "TARGET_POWER"
1594 "@
1595 sle. %3,%1,%2
1596 {sli.|slwi.} %3,%1,%h2"
1597 [(set_attr "type" "delayed_compare")])
1598(define_insn ""
1599 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
1600 (compare:CC (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1601 (match_operand:SI 2 "reg_or_cint_operand" "ri"))
1602 (const_int 0)))
1603 (clobber (match_scratch:SI 3 "=r"))]
1604 "TARGET_POWERPC"
1605 "slw%I2. %3,%1,%2"
1606 [(set_attr "type" "delayed_compare")])
1607
1608(define_insn ""
1609 [(set (match_operand:CC 3 "cc_reg_operand" "=x,x")
1610 (compare:CC (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1611 (match_operand:SI 2 "reg_or_cint_operand" "r,i"))
1612 (const_int 0)))
1613 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
1614 (ashift:SI (match_dup 1) (match_dup 2)))
1615 (clobber (match_scratch:SI 4 "=q,X"))]
1616 "TARGET_POWER"
1617 "@
1618 sle. %0,%1,%2
1619 {sli.|slwi.} %0,%1,%h2"
1620 [(set_attr "type" "delayed_compare")])
1621(define_insn ""
1622 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1623 (compare:CC (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1624 (match_operand:SI 2 "reg_or_cint_operand" "ri"))
1625 (const_int 0)))
1626 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1627 (ashift:SI (match_dup 1) (match_dup 2)))]
1628 "TARGET_POWERPC"
1629 "slw%I2. %0,%1,%2"
1630 [(set_attr "type" "delayed_compare")])
1631
1632(define_insn ""
1633 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1634 (and:SI (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1635 (match_operand:SI 2 "const_int_operand" "i"))
1636 (match_operand:SI 3 "mask_operand" "L")))]
1637 "includes_lshift_p (operands[2], operands[3])"
1638 "{rlinm|rlwinm} %0,%h1,%h2,%m3,%M3")
1639
1640(define_insn ""
1641 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
1642 (compare:CC
1643 (and:SI (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1644 (match_operand:SI 2 "const_int_operand" "i"))
1645 (match_operand:SI 3 "mask_operand" "L"))
1646 (const_int 0)))
1647 (clobber (match_scratch:SI 4 "=r"))]
1648 "includes_lshift_p (operands[2], operands[3])"
1649 "{rlinm.|rlwinm.} %4,%h1,%h2,%m3,%M3"
1650 [(set_attr "type" "delayed_compare")])
1651
1652(define_insn ""
1653 [(set (match_operand:CC 4 "cc_reg_operand" "=x")
1654 (compare:CC
1655 (and:SI (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1656 (match_operand:SI 2 "const_int_operand" "i"))
1657 (match_operand:SI 3 "mask_operand" "L"))
1658 (const_int 0)))
1659 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1660 (and:SI (ashift:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
1661 "includes_lshift_p (operands[2], operands[3])"
1662 "{rlinm.|rlwinm.} %0,%h1,%h2,%m3,%M3"
1663 [(set_attr "type" "delayed_compare")])
1664
1665;; The AIX assembler mis-handles "sri x,x,0", so write that case as
1666;; "sli x,x,0".
1667(define_expand "lshrsi3"
1668 [(use (match_operand:SI 0 "gpc_reg_operand" ""))
1669 (use (match_operand:SI 1 "gpc_reg_operand" ""))
1670 (use (match_operand:SI 2 "reg_or_cint_operand" ""))]
1671 ""
1672 "
1673{
1674 if (TARGET_POWER)
1675 emit_insn (gen_lshrsi3_power (operands[0], operands[1], operands[2]));
1676 else
1677 emit_insn (gen_lshrsi3_powerpc (operands[0], operands[1], operands[2]));
1678 DONE;
1679}")
1680
1681(define_insn "lshrsi3_power"
1682 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
1683 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1684 (match_operand:SI 2 "reg_or_cint_operand" "r,i")))
1685 (clobber (match_scratch:SI 3 "=q,X"))]
1686 "TARGET_POWER"
1687 "@
1688 sre %0,%1,%2
1689 {s%A2i|s%A2wi} %0,%1,%h2")
1690
1691(define_insn "lshrsi3_powerpc"
1692 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1693 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1694 (match_operand:SI 2 "reg_or_cint_operand" "ri")))]
1695 "TARGET_POWERPC"
1696 "srw%I2 %0,%1,%2")
1697
1698(define_insn ""
1699 [(set (match_operand:CC 0 "cc_reg_operand" "=x,x")
1700 (compare:CC (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1701 (match_operand:SI 2 "reg_or_cint_operand" "r,i"))
1702 (const_int 0)))
1703 (clobber (match_scratch:SI 3 "=r,r"))
1704 (clobber (match_scratch:SI 4 "=q,X"))]
1705 "TARGET_POWER"
1706 "@
1707 sre. %3,%1,%2
1708 {s%A2i.|s%A2wi.} %3,%1,%h2"
1709 [(set_attr "type" "delayed_compare")])
1710
1711(define_insn ""
1712 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
1713 (compare:CC (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1714 (match_operand:SI 2 "reg_or_cint_operand" "ri"))
1715 (const_int 0)))
1716 (clobber (match_scratch:SI 3 "=r"))]
1717 "TARGET_POWERPC"
1718 "srw%I2. %3,%1,%2"
1719 [(set_attr "type" "delayed_compare")])
1720
1721(define_insn ""
1722 [(set (match_operand:CC 3 "cc_reg_operand" "=x,x")
1723 (compare:CC (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1724 (match_operand:SI 2 "reg_or_cint_operand" "r,i"))
1725 (const_int 0)))
1726 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
1727 (lshiftrt:SI (match_dup 1) (match_dup 2)))
1728 (clobber (match_scratch:SI 4 "=q,X"))]
1729 "TARGET_POWER"
1730 "@
1731 sre. %0,%1,%2
1732 {s%A2i.|s%A2wi.} %0,%1,%h2"
1733 [(set_attr "type" "delayed_compare")])
1734
1735(define_insn ""
1736 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1737 (compare:CC (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1738 (match_operand:SI 2 "reg_or_cint_operand" "ri"))
1739 (const_int 0)))
1740 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1741 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
1742 "TARGET_POWERPC"
1743 "srw%I2. %0,%1,%2"
1744 [(set_attr "type" "delayed_compare")])
1745
1746(define_insn ""
1747 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1748 (and:SI (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1749 (match_operand:SI 2 "const_int_operand" "i"))
1750 (match_operand:SI 3 "mask_operand" "L")))]
1751 "includes_rshift_p (operands[2], operands[3])"
1752 "{rlinm|rlwinm} %0,%1,%s2,%m3,%M3")
1753
1754(define_insn ""
1755 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
1756 (compare:CC
1757 (and:SI (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1758 (match_operand:SI 2 "const_int_operand" "i"))
1759 (match_operand:SI 3 "mask_operand" "L"))
1760 (const_int 0)))
1761 (clobber (match_scratch:SI 4 "=r"))]
1762 "includes_rshift_p (operands[2], operands[3])"
1763 "{rlinm.|rlwinm.} %4,%1,%s2,%m3,%M3"
1764 [(set_attr "type" "delayed_compare")])
1765
1766(define_insn ""
1767 [(set (match_operand:CC 4 "cc_reg_operand" "=x")
1768 (compare:CC
1769 (and:SI (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1770 (match_operand:SI 2 "const_int_operand" "i"))
1771 (match_operand:SI 3 "mask_operand" "L"))
1772 (const_int 0)))
1773 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1774 (and:SI (lshiftrt:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
1775 "includes_rshift_p (operands[2], operands[3])"
1776 "{rlinm.|rlwinm.} %0,%1,%s2,%m3,%M3"
1777 [(set_attr "type" "delayed_compare")])
1778
1779(define_insn ""
1780 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1781 (zero_extend:SI
1782 (subreg:QI
1783 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1784 (match_operand:SI 2 "const_int_operand" "i")) 0)))]
1785 "includes_rshift_p (operands[2], gen_rtx (CONST_INT, VOIDmode, 255))"
1786 "{rlinm|rlwinm} %0,%1,%s2,0xff")
1787
1788(define_insn ""
1789 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
1790 (compare:CC
1791 (zero_extend:SI
1792 (subreg:QI
1793 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1794 (match_operand:SI 2 "const_int_operand" "i")) 0))
1795 (const_int 0)))
1796 (clobber (match_scratch:SI 3 "=r"))]
1797 "includes_rshift_p (operands[2], gen_rtx (CONST_INT, VOIDmode, 255))"
1798 "{rlinm.|rlwinm.} %3,%1,%s2,0xff"
1799 [(set_attr "type" "delayed_compare")])
1800
1801(define_insn ""
1802 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1803 (compare:CC
1804 (zero_extend:SI
1805 (subreg:QI
1806 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1807 (match_operand:SI 2 "const_int_operand" "i")) 0))
1808 (const_int 0)))
1809 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1810 (zero_extend:SI (subreg:QI (lshiftrt:SI (match_dup 1) (match_dup 2)) 0)))]
1811 "includes_rshift_p (operands[2], gen_rtx (CONST_INT, VOIDmode, 255))"
1812 "{rlinm.|rlwinm.} %0,%1,%s2,0xff"
1813 [(set_attr "type" "delayed_compare")])
1814
1815(define_insn ""
1816 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1817 (zero_extend:SI
1818 (subreg:HI
1819 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1820 (match_operand:SI 2 "const_int_operand" "i")) 0)))]
1821 "includes_rshift_p (operands[2], gen_rtx (CONST_INT, VOIDmode, 65535))"
1822 "{rlinm|rlwinm} %0,%1,%s2,0xffff")
1823
1824(define_insn ""
1825 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
1826 (compare:CC
1827 (zero_extend:SI
1828 (subreg:HI
1829 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1830 (match_operand:SI 2 "const_int_operand" "i")) 0))
1831 (const_int 0)))
1832 (clobber (match_scratch:SI 3 "=r"))]
1833 "includes_rshift_p (operands[2], gen_rtx (CONST_INT, VOIDmode, 65535))"
1834 "{rlinm.|rlwinm.} %3,%1,%s2,0xffff"
1835 [(set_attr "type" "delayed_compare")])
1836
1837(define_insn ""
1838 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1839 (compare:CC
1840 (zero_extend:SI
1841 (subreg:HI
1842 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1843 (match_operand:SI 2 "const_int_operand" "i")) 0))
1844 (const_int 0)))
1845 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1846 (zero_extend:SI (subreg:HI (lshiftrt:SI (match_dup 1) (match_dup 2)) 0)))]
1847 "includes_rshift_p (operands[2], gen_rtx (CONST_INT, VOIDmode, 65535))"
1848 "{rlinm.|rlwinm.} %0,%1,%s2,0xffff"
1849 [(set_attr "type" "delayed_compare")])
1850
1851(define_insn ""
1852 [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r")
1853 (const_int 1)
1854 (match_operand:SI 1 "gpc_reg_operand" "r"))
1855 (ashiftrt:SI (match_operand:SI 2 "gpc_reg_operand" "r")
1856 (const_int 31)))]
1857 "TARGET_POWER"
1858 "rrib %0,%1,%2")
1859
1860(define_insn ""
1861 [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r")
1862 (const_int 1)
1863 (match_operand:SI 1 "gpc_reg_operand" "r"))
1864 (lshiftrt:SI (match_operand:SI 2 "gpc_reg_operand" "r")
1865 (const_int 31)))]
1866 "TARGET_POWER"
1867 "rrib %0,%1,%2")
1868
1869(define_insn ""
1870 [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r")
1871 (const_int 1)
1872 (match_operand:SI 1 "gpc_reg_operand" "r"))
1873 (zero_extract:SI (match_operand:SI 2 "gpc_reg_operand" "r")
1874 (const_int 1)
1875 (const_int 0)))]
1876 "TARGET_POWER"
1877 "rrib %0,%1,%2")
1878
1879(define_expand "ashrsi3"
1880 [(set (match_operand:SI 0 "gpc_reg_operand" "")
1881 (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "")
1882 (match_operand:SI 2 "reg_or_cint_operand" "")))]
1883 ""
1884 "
1885{
1886 if (TARGET_POWER)
1887 emit_insn (gen_ashrsi3_power (operands[0], operands[1], operands[2]));
1888 else
1889 emit_insn (gen_ashrsi3_powerpc (operands[0], operands[1], operands[2]));
1890 DONE;
1891}")
1892
1893(define_insn "ashrsi3_power"
1894 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
1895 (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1896 (match_operand:SI 2 "reg_or_cint_operand" "r,i")))
1897 (clobber (match_scratch:SI 3 "=q,X"))]
1898 "TARGET_POWER"
1899 "@
1900 srea %0,%1,%2
1901 {srai|srawi} %0,%1,%h2")
1902
1903(define_insn "ashrsi3_powerpc"
1904 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1905 (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1906 (match_operand:SI 2 "reg_or_cint_operand" "ri")))]
1907 "TARGET_POWERPC"
1908 "sraw%I2 %0,%1,%2")
1909
1910(define_insn ""
1911 [(set (match_operand:CC 0 "cc_reg_operand" "=x,x")
1912 (compare:CC (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1913 (match_operand:SI 2 "reg_or_cint_operand" "r,i"))
1914 (const_int 0)))
1915 (clobber (match_scratch:SI 3 "=r,r"))
1916 (clobber (match_scratch:SI 4 "=q,X"))]
1917 "TARGET_POWER"
1918 "@
1919 srea. %3,%1,%2
1920 {srai.|srawi.} %3,%1,%h2"
1921 [(set_attr "type" "delayed_compare")])
1922
1923(define_insn ""
1924 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
1925 (compare:CC (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1926 (match_operand:SI 2 "reg_or_cint_operand" "ri"))
1927 (const_int 0)))
1928 (clobber (match_scratch:SI 3 "=r"))]
1929 "TARGET_POWERPC"
1930 "sraw%I2. %3,%1,%2"
1931 [(set_attr "type" "delayed_compare")])
1932
1933(define_insn ""
1934 [(set (match_operand:CC 3 "cc_reg_operand" "=x,x")
1935 (compare:CC (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1936 (match_operand:SI 2 "reg_or_cint_operand" "r,i"))
1937 (const_int 0)))
1938 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
1939 (ashiftrt:SI (match_dup 1) (match_dup 2)))
1940 (clobber (match_scratch:SI 4 "=q,X"))]
1941 "TARGET_POWER"
1942 "@
1943 srea. %0,%1,%2
1944 srai. %0,%1,%h2"
1945 [(set_attr "type" "delayed_compare")])
1946
1947(define_insn ""
1948 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1949 (compare:CC (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1950 (match_operand:SI 2 "reg_or_cint_operand" "ri"))
1951 (const_int 0)))
1952 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1953 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
1954 "TARGET_POWERPC"
1955 "sraw%I2. %0,%1,%2"
1956 [(set_attr "type" "delayed_compare")])
1957
1958(define_expand "extendqisi2"
1959 [(use (match_operand:SI 0 "gpc_reg_operand" ""))
1960 (use (match_operand:QI 1 "gpc_reg_operand" ""))]
1961 ""
1962 "
1963{
1964 if (TARGET_POWER)
1965 emit_insn (gen_extendqisi2_power (operands[0], operands[1]));
1966 else
1967 emit_insn (gen_extendqisi2_powerpc (operands[0], operands[1]));
1968 DONE;
1969}")
1970
1971(define_expand "extendqisi2_power"
1972 [(parallel [(set (match_dup 2)
1973 (ashift:SI (match_operand:QI 1 "gpc_reg_operand" "")
1974 (const_int 24)))
1975 (clobber (scratch:SI))])
1976 (parallel [(set (match_operand:SI 0 "gpc_reg_operand" "")
1977 (ashiftrt:SI (match_dup 2)
1978 (const_int 24)))
1979 (clobber (scratch:SI))])]
1980 "TARGET_POWER"
1981 "
1982{ operands[1] = gen_lowpart (SImode, operands[1]);
1983 operands[2] = gen_reg_rtx (SImode); }")
1984
1985(define_expand "extendqisi2_powerpc"
1986 [(set (match_dup 2)
1987 (ashift:SI (match_operand:QI 1 "gpc_reg_operand" "")
1988 (const_int 24)))
1989 (set (match_operand:SI 0 "gpc_reg_operand" "")
1990 (ashiftrt:SI (match_dup 2)
1991 (const_int 24)))]
1992 "TARGET_POWERPC"
1993 "
1994{ operands[1] = gen_lowpart (SImode, operands[1]);
1995 operands[2] = gen_reg_rtx (SImode); }")
1996
1997(define_expand "extendqihi2"
1998 [(use (match_operand:HI 0 "gpc_reg_operand" ""))
1999 (use (match_operand:QI 1 "gpc_reg_operand" ""))]
2000 ""
2001 "
2002{
2003 if (TARGET_POWER)
2004 emit_insn (gen_extendqihi2_power (operands[0], operands[1]));
2005 else
2006 emit_insn (gen_extendqihi2_powerpc (operands[0], operands[1]));
2007 DONE;
2008}")
2009
2010(define_expand "extendqihi2_power"
2011 [(parallel [(set (match_dup 2)
2012 (ashift:SI (match_operand:QI 1 "gpc_reg_operand" "")
2013 (const_int 24)))
2014 (clobber (scratch:SI))])
2015 (parallel [(set (match_operand:HI 0 "gpc_reg_operand" "")
2016 (ashiftrt:SI (match_dup 2)
2017 (const_int 24)))
2018 (clobber (scratch:SI))])]
2019 "TARGET_POWER"
2020 "
2021{ operands[0] = gen_lowpart (SImode, operands[0]);
2022 operands[1] = gen_lowpart (SImode, operands[1]);
2023 operands[2] = gen_reg_rtx (SImode); }")
2024
2025(define_expand "extendqihi2_powerpc"
2026 [(set (match_dup 2)
2027 (ashift:SI (match_operand:QI 1 "gpc_reg_operand" "")
2028 (const_int 24)))
2029 (set (match_operand:HI 0 "gpc_reg_operand" "")
2030 (ashiftrt:SI (match_dup 2)
2031 (const_int 24)))]
2032 "TARGET_POWERPC"
2033 "
2034{ operands[0] = gen_lowpart (SImode, operands[0]);
2035 operands[1] = gen_lowpart (SImode, operands[1]);
2036 operands[2] = gen_reg_rtx (SImode); }")
2037\f
2038;; Floating-point insns, excluding normal data motion.
2039;;
2040;; PowerPC has a full set of single-precision floating point instructions.
2041;;
2042;; For the POWER architecture, we pretend that we have both SFmode and
2043;; DFmode insns, while, in fact, all fp insns are actually done in double.
2044;; The only conversions we will do will be when storing to memory. In that
2045;; case, we will use the "frsp" instruction before storing.
2046;;
2047;; Note that when we store into a single-precision memory location, we need to
2048;; use the frsp insn first. If the register being stored isn't dead, we
2049;; need a scratch register for the frsp. But this is difficult when the store
2050;; is done by reload. It is not incorrect to do the frsp on the register in
2051;; this case, we just lose precision that we would have otherwise gotten but
2052;; is not guaranteed. Perhaps this should be tightened up at some point.
2053
2054(define_insn "extendsfdf2"
2055 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
2056 (float_extend:DF (match_operand:SF 1 "gpc_reg_operand" "f")))]
2057 ""
2058 "*
2059{
2060 if (REGNO (operands[0]) == REGNO (operands[1]))
2061 return \"\";
2062 else
2063 return \"fmr %0,%1\";
2064}"
2065 [(set_attr "type" "fp")])
2066
2067(define_insn "truncdfsf2"
2068 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
2069 (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "f")))]
2070 ""
2071 "frsp %0,%1"
2072 [(set_attr "type" "fp")])
2073
2074(define_insn "negsf2"
2075 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
2076 (neg:SF (match_operand:SF 1 "gpc_reg_operand" "f")))]
2077 ""
2078 "fneg %0,%1"
2079 [(set_attr "type" "fp")])
2080
2081(define_insn "abssf2"
2082 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
2083 (abs:SF (match_operand:SF 1 "gpc_reg_operand" "f")))]
2084 ""
2085 "fabs %0,%1"
2086 [(set_attr "type" "fp")])
2087
2088(define_insn ""
2089 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
2090 (neg:SF (abs:SF (match_operand:SF 1 "gpc_reg_operand" "f"))))]
2091 ""
2092 "fnabs %0,%1"
2093 [(set_attr "type" "fp")])
2094
2095(define_expand "addsf3"
2096 [(set (match_operand:SF 0 "gpc_reg_operand" "")
2097 (plus:SF (match_operand:SF 1 "gpc_reg_operand" "")
2098 (match_operand:SF 2 "gpc_reg_operand" "")))]
2099 ""
2100 "")
2101
2102(define_insn ""
2103 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
2104 (plus:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
2105 (match_operand:SF 2 "gpc_reg_operand" "f")))]
2106 "TARGET_POWERPC"
2107 "fadds %0,%1,%2"
2108 [(set_attr "type" "fp")])
2109
2110(define_insn ""
2111 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
2112 (plus:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
2113 (match_operand:SF 2 "gpc_reg_operand" "f")))]
2114 "TARGET_POWER"
2115 "{fa|fadd} %0,%1,%2"
2116 [(set_attr "type" "fp")])
2117
2118(define_expand "subsf3"
2119 [(set (match_operand:SF 0 "gpc_reg_operand" "")
2120 (minus:SF (match_operand:SF 1 "gpc_reg_operand" "")
2121 (match_operand:SF 2 "gpc_reg_operand" "")))]
2122 ""
2123 "")
2124
2125(define_insn ""
2126 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
2127 (minus:SF (match_operand:SF 1 "gpc_reg_operand" "f")
2128 (match_operand:SF 2 "gpc_reg_operand" "f")))]
2129 "TARGET_POWERPC"
2130 "fsubs %0,%1,%2"
2131 [(set_attr "type" "fp")])
2132
2133(define_insn ""
2134 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
2135 (minus:SF (match_operand:SF 1 "gpc_reg_operand" "f")
2136 (match_operand:SF 2 "gpc_reg_operand" "f")))]
2137 "TARGET_POWER"
2138 "{fs|fsub} %0,%1,%2"
2139 [(set_attr "type" "fp")])
2140
2141(define_expand "mulsf3"
2142 [(set (match_operand:SF 0 "gpc_reg_operand" "")
2143 (mult:SF (match_operand:SF 1 "gpc_reg_operand" "")
2144 (match_operand:SF 2 "gpc_reg_operand" "")))]
2145 ""
2146 "")
2147
2148(define_insn ""
2149 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
2150 (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
2151 (match_operand:SF 2 "gpc_reg_operand" "f")))]
2152 "TARGET_POWERPC"
2153 "fmuls %0,%1,%2"
2154 [(set_attr "type" "fp")])
2155
2156(define_insn ""
2157 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
2158 (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
2159 (match_operand:SF 2 "gpc_reg_operand" "f")))]
2160 "TARGET_POWER"
2161 "{fm|fmul} %0,%1,%2"
2162 [(set_attr "type" "fp")])
2163
2164(define_expand "divsf3"
2165 [(set (match_operand:SF 0 "gpc_reg_operand" "")
2166 (div:SF (match_operand:SF 1 "gpc_reg_operand" "")
2167 (match_operand:SF 2 "gpc_reg_operand" "")))]
2168 ""
2169 "")
2170
2171(define_insn ""
2172 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
2173 (div:SF (match_operand:SF 1 "gpc_reg_operand" "f")
2174 (match_operand:SF 2 "gpc_reg_operand" "f")))]
2175 "TARGET_POWERPC"
2176 "fdivs %0,%1,%2"
2177 [(set_attr "type" "sdiv")])
2178
2179(define_insn ""
2180 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
2181 (div:SF (match_operand:SF 1 "gpc_reg_operand" "f")
2182 (match_operand:SF 2 "gpc_reg_operand" "f")))]
2183 "TARGET_POWER"
2184 "{fd|fdiv} %0,%1,%2"
2185 [(set_attr "type" "sdiv")])
2186
2187(define_insn ""
2188 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
2189 (plus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
2190 (match_operand:SF 2 "gpc_reg_operand" "f"))
2191 (match_operand:SF 3 "gpc_reg_operand" "f")))]
2192 "TARGET_POWERPC"
2193 "fmadds %0,%1,%2,%3"
2194 [(set_attr "type" "fp")])
2195
2196(define_insn ""
2197 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
2198 (plus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
2199 (match_operand:SF 2 "gpc_reg_operand" "f"))
2200 (match_operand:SF 3 "gpc_reg_operand" "f")))]
2201 "TARGET_POWER"
2202 "{fma|fmadd} %0,%1,%2,%3"
2203 [(set_attr "type" "fp")])
2204
2205(define_insn ""
2206 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
2207 (minus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
2208 (match_operand:SF 2 "gpc_reg_operand" "f"))
2209 (match_operand:SF 3 "gpc_reg_operand" "f")))]
2210 "TARGET_POWERPC"
2211 "fmsubs %0,%1,%2,%3"
2212 [(set_attr "type" "fp")])
2213
2214(define_insn ""
2215 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
2216 (minus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
2217 (match_operand:SF 2 "gpc_reg_operand" "f"))
2218 (match_operand:SF 3 "gpc_reg_operand" "f")))]
2219 "TARGET_POWER"
2220 "{fms|fmsub} %0,%1,%2,%3"
2221 [(set_attr "type" "fp")])
2222
2223(define_insn ""
2224 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
2225 (neg:SF (plus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
2226 (match_operand:SF 2 "gpc_reg_operand" "f"))
2227 (match_operand:SF 3 "gpc_reg_operand" "f"))))]
2228 "TARGET_POWERPC"
2229 "fnmadds %0,%1,%2,%3"
2230 [(set_attr "type" "fp")])
2231
2232(define_insn ""
2233 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
2234 (neg:SF (plus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
2235 (match_operand:SF 2 "gpc_reg_operand" "f"))
2236 (match_operand:SF 3 "gpc_reg_operand" "f"))))]
2237 "TARGET_POWER"
2238 "{fnma|fnmadd} %0,%1,%2,%3"
2239 [(set_attr "type" "fp")])
2240
2241(define_insn ""
2242 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
2243 (neg:SF (minus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
2244 (match_operand:SF 2 "gpc_reg_operand" "f"))
2245 (match_operand:SF 3 "gpc_reg_operand" "f"))))]
2246 "TARGET_POWERPC"
2247 "fnmsubs %0,%1,%2,%3"
2248 [(set_attr "type" "fp")])
2249
2250(define_insn ""
2251 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
2252 (neg:SF (minus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
2253 (match_operand:SF 2 "gpc_reg_operand" "f"))
2254 (match_operand:SF 3 "gpc_reg_operand" "f"))))]
2255 "TARGET_POWER"
2256 "{fnms|fnmsub} %0,%1,%2,%3"
2257 [(set_attr "type" "fp")])
2258
2259(define_expand "sqrtsf2"
2260 [(set (match_operand:SF 0 "gpc_reg_operand" "")
2261 (sqrt:SF (match_operand:SF 1 "gpc_reg_operand" "")))]
2262 "TARGET_POWERPCSQR || TARGET_POWER2"
2263 "")
2264
2265(define_insn ""
2266 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
2267 (sqrt:SF (match_operand:SF 1 "gpc_reg_operand" "f")))]
2268 "TARGET_POWERPCSQR"
2269 "fsqrts %0,%1"
2270 [(set_attr "type" "ssqrt")])
2271
2272(define_insn ""
2273 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
2274 (sqrt:SF (match_operand:SF 1 "gpc_reg_operand" "f")))]
2275 "TARGET_POWER2"
2276 "fsqrt %0,%1"
2277 [(set_attr "type" "dsqrt")])
2278
2279(define_insn "negdf2"
2280 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
2281 (neg:DF (match_operand:DF 1 "gpc_reg_operand" "f")))]
2282 ""
2283 "fneg %0,%1"
2284 [(set_attr "type" "fp")])
2285
2286(define_insn "absdf2"
2287 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
2288 (abs:DF (match_operand:DF 1 "gpc_reg_operand" "f")))]
2289 ""
2290 "fabs %0,%1"
2291 [(set_attr "type" "fp")])
2292
2293(define_insn ""
2294 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
2295 (neg:DF (abs:DF (match_operand:DF 1 "gpc_reg_operand" "f"))))]
2296 ""
2297 "fnabs %0,%1"
2298 [(set_attr "type" "fp")])
2299
2300(define_insn "adddf3"
2301 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
2302 (plus:DF (match_operand:DF 1 "gpc_reg_operand" "%f")
2303 (match_operand:DF 2 "gpc_reg_operand" "f")))]
2304 ""
2305 "{fa|fadd} %0,%1,%2"
2306 [(set_attr "type" "fp")])
2307
2308(define_insn "subdf3"
2309 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
2310 (minus:DF (match_operand:DF 1 "gpc_reg_operand" "f")
2311 (match_operand:DF 2 "gpc_reg_operand" "f")))]
2312 ""
2313 "{fs|fsub} %0,%1,%2"
2314 [(set_attr "type" "fp")])
2315
2316(define_insn "muldf3"
2317 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
2318 (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%f")
2319 (match_operand:DF 2 "gpc_reg_operand" "f")))]
2320 ""
2321 "{fm|fmul} %0,%1,%2"
2322 [(set_attr "type" "dmul")])
2323
2324(define_insn "divdf3"
2325 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
2326 (div:DF (match_operand:DF 1 "gpc_reg_operand" "f")
2327 (match_operand:DF 2 "gpc_reg_operand" "f")))]
2328 ""
2329 "{fd|fdiv} %0,%1,%2"
2330 [(set_attr "type" "ddiv")])
2331
2332(define_insn ""
2333 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
2334 (plus:DF (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%f")
2335 (match_operand:DF 2 "gpc_reg_operand" "f"))
2336 (match_operand:DF 3 "gpc_reg_operand" "f")))]
2337 ""
2338 "{fma|fmadd} %0,%1,%2,%3"
2339 [(set_attr "type" "dmul")])
2340
2341(define_insn ""
2342 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
2343 (minus:DF (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%f")
2344 (match_operand:DF 2 "gpc_reg_operand" "f"))
2345 (match_operand:DF 3 "gpc_reg_operand" "f")))]
2346 ""
2347 "{fms|fmsub} %0,%1,%2,%3"
2348 [(set_attr "type" "dmul")])
2349
2350(define_insn ""
2351 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
2352 (neg:DF (plus:DF (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%f")
2353 (match_operand:DF 2 "gpc_reg_operand" "f"))
2354 (match_operand:DF 3 "gpc_reg_operand" "f"))))]
2355 ""
2356 "{fnma|fnmadd} %0,%1,%2,%3"
2357 [(set_attr "type" "dmul")])
2358
2359(define_insn ""
2360 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
2361 (neg:DF (minus:DF (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%f")
2362 (match_operand:DF 2 "gpc_reg_operand" "f"))
2363 (match_operand:DF 3 "gpc_reg_operand" "f"))))]
2364 ""
2365 "{fnms|fnmsub} %0,%1,%2,%3"
2366 [(set_attr "type" "dmul")])
2367
2368(define_insn "sqrtdf2"
2369 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
2370 (sqrt:DF (match_operand:DF 1 "gpc_reg_operand" "f")))]
2371 "TARGET_POWERPCSQR | TARGET_POWER2"
2372 "fsqrt %0,%1"
2373 [(set_attr "type" "dsqrt")])
2374\f
2375;; Conversions to and from floating-point.
2376(define_expand "floatsidf2"
2377 [(set (match_dup 2)
2378 (plus:DI (zero_extend:DI
2379 (xor:SI (match_operand:SI 1 "gpc_reg_operand" "")
2380 (match_dup 3)))
2381 (match_dup 4)))
2382 (set (match_operand:DF 0 "gpc_reg_operand" "")
2383 (minus:DF (subreg:DF (match_dup 2) 0)
2384 (match_dup 5)))]
2385 ""
2386 "
2387{
2388#if HOST_BITS_PER_INT != BITS_PER_WORD
2389 /* Maybe someone can figure out how to do this in that case. I don't
2390 want to right now. */
2391 abort ();
2392#endif
2393
2394 operands[2] = gen_reg_rtx (DImode);
2395 operands[3] = gen_rtx (CONST_INT, VOIDmode, 0x80000000);
2396 operands[4] = immed_double_const (0, 0x43300000, DImode);
2397 operands[5] = force_reg (DFmode, immed_double_const (0x43300000,
2398 0x80000000, DFmode));
2399}")
2400
2401(define_expand "floatunssidf2"
2402 [(set (match_dup 2)
2403 (plus:DI (zero_extend:DI (match_operand:SI 1 "gpc_reg_operand" ""))
2404 (match_dup 3)))
2405 (set (match_operand:DF 0 "gpc_reg_operand" "")
2406 (minus:DF (subreg:DF (match_dup 2) 0)
2407 (match_dup 4)))]
2408 ""
2409 "
2410{
2411#if HOST_BITS_PER_INT != BITS_PER_WORD
2412 /* Maybe someone can figure out how to do this in that case. I don't
2413 want to right now. */
2414 abort ();
2415#endif
2416
2417 operands[2] = gen_reg_rtx (DImode);
2418 operands[3] = immed_double_const (0, 0x43300000, DImode);
2419 operands[4] = force_reg (DFmode, immed_double_const (0x43300000, 0, DFmode));
2420}")
2421
2422;; For the above two cases, we always split.
2423(define_split
2424 [(set (match_operand:DI 0 "gpc_reg_operand" "")
2425 (plus:DI (zero_extend:DI
2426 (xor:SI (match_operand:SI 1 "gpc_reg_operand" "")
2427 (match_operand:SI 2 "logical_operand" "")))
2428 (match_operand:DI 3 "immediate_operand" "")))]
2429 "reload_completed && HOST_BITS_PER_INT == BITS_PER_WORD
2430 && GET_CODE (operands[3]) == CONST_DOUBLE
2431 && CONST_DOUBLE_LOW (operands[3]) == 0"
2432 [(set (match_dup 6) (xor:SI (match_dup 1) (match_dup 2)))
2433 (set (match_dup 4) (match_dup 5))]
2434 "
2435{ operands[4] = operand_subword (operands[0], 0, 0, DImode);
2436 operands[5] = operand_subword (operands[3], 0, 0, DImode);
2437 operands[6] = operand_subword (operands[0], 1, 0, DImode);
2438}")
2439
2440(define_insn ""
2441 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2442 (plus:DI (zero_extend:DI
2443 (xor:SI (match_operand:SI 1 "gpc_reg_operand" "%r")
2444 (match_operand:SI 2 "logical_operand" "rKJ")))
2445 (match_operand:DI 3 "immediate_operand" "n")))]
2446 "HOST_BITS_PER_INT == BITS_PER_WORD
2447 && GET_CODE (operands[3]) == CONST_DOUBLE
2448 && CONST_DOUBLE_LOW (operands[3]) == 0"
2449 "#"
2450 [(set_attr "length" "8")])
2451
2452(define_split
2453 [(set (match_operand:DI 0 "gpc_reg_operand" "=")
2454 (plus:DI (zero_extend:DI (match_operand:SI 1 "gpc_reg_operand" ""))
2455 (match_operand:DI 2 "immediate_operand" "")))]
2456 "reload_completed && HOST_BITS_PER_INT == BITS_PER_WORD
2457 && GET_CODE (operands[2]) == CONST_DOUBLE
2458 && CONST_DOUBLE_LOW (operands[2]) == 0"
2459 [(set (match_dup 3) (match_dup 4))
2460 (set (match_dup 5) (match_dup 1))]
2461 "
2462{ operands[3] = operand_subword (operands[0], 0, 0, DImode);
2463 operands[4] = operand_subword (operands[2], 0, 0, DImode);
2464 operands[5] = operand_subword (operands[0], 1, 0, DImode);
2465
2466 if (rtx_equal_p (operands[1], operands[5]))
2467 {
2468 emit_move_insn (operands[3], operands[4]);
2469 DONE;
2470 }
2471
2472 if (rtx_equal_p (operands[1], operands[3]))
2473 {
2474 rtx temp;
2475
2476 temp = operands[3]; operands[3] = operands[5]; operands[5] = temp;
2477 temp = operands[4]; operands[4] = operands[1]; operands[1] = temp;
2478 }
2479}")
2480
2481(define_insn ""
2482 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2483 (plus:DI (zero_extend:DI (match_operand:SI 1 "gpc_reg_operand" "r"))
2484 (match_operand:DI 2 "immediate_operand" "n")))]
2485 "HOST_BITS_PER_INT == BITS_PER_WORD
2486 && GET_CODE (operands[2]) == CONST_DOUBLE
2487 && CONST_DOUBLE_LOW (operands[2]) == 0"
2488 "#"
2489 [(set_attr "length" "8")])
2490
2491(define_expand "fix_truncdfsi2"
2492 [(set (match_operand:SI 0 "gpc_reg_operand" "")
2493 (fix:SI (match_operand:DF 1 "gpc_reg_operand" "")))]
2494 ""
2495 "
2496{
2497 emit_insn (gen_trunc_call (operands[0], operands[1],
2498 gen_rtx (SYMBOL_REF, Pmode, \"itrunc\")));
2499 DONE;
2500}")
2501
2502(define_expand "fixuns_truncdfsi2"
2503 [(set (match_operand:SI 0 "gpc_reg_operand" "")
2504 (unsigned_fix:SI (match_operand:DF 1 "gpc_reg_operand" "")))]
2505 ""
2506 "
2507{
2508 emit_insn (gen_trunc_call (operands[0], operands[1],
2509 gen_rtx (SYMBOL_REF, Pmode, \"uitrunc\")));
2510 DONE;
2511}")
2512
2513
2514(define_expand "trunc_call"
2515 [(parallel [(set (match_operand:SI 0 "" "")
2516 (fix:SI (match_operand:DF 1 "" "")))
2517 (use (match_operand:SI 2 "" ""))])]
2518 ""
2519 "
2520{
2521 rtx insns = gen_trunc_call_rtl (operands[0], operands[1], operands[2]);
2522 rtx first = XVECEXP (insns, 0, 0);
2523 rtx last = XVECEXP (insns, 0, XVECLEN (insns, 0) - 1);
2524
2525 REG_NOTES (first) = gen_rtx (INSN_LIST, REG_LIBCALL, last,
2526 REG_NOTES (first));
2527 REG_NOTES (last) = gen_rtx (INSN_LIST, REG_RETVAL, first, REG_NOTES (last));
2528
2529 emit_insn (insns);
2530 DONE;
2531}")
2532
2533(define_expand "trunc_call_rtl"
2534 [(set (reg:DF 33) (match_operand:DF 1 "gpc_reg_operand" ""))
2535 (use (reg:DF 33))
2536 (parallel [(set (reg:SI 3)
2537 (call (mem:SI (match_operand 2 "" "")) (const_int 0)))
2538 (clobber (scratch:SI))])
2539 (set (match_operand:SI 0 "gpc_reg_operand" "")
2540 (reg:SI 3))]
2541 ""
2542 "
2543{
2544 rs6000_trunc_used = 1;
2545}")
2546\f
2547;; Define the DImode operations that can be done in a small number
2548;; of instructions.
2549(define_expand "adddi3"
2550 [(set (match_operand:DI 0 "gpc_reg_operand" "")
2551 (plus:DI (match_operand:DI 1 "gpc_reg_operand" "")
2552 (match_operand:DI 2 "reg_or_short_operand" "")))]
2553 ""
2554 "
2555{
2556 if (TARGET_POWERPC
2557 && short_cint_operand (operands[2], DImode))
2558 FAIL;
2559}")
2560
2561(define_insn ""
2562 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
2563 (plus:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r")
2564 (match_operand:DI 2 "reg_or_short_operand" "r,I")))]
2565 "TARGET_POWER"
2566 "@
2567 {a|addc} %L0,%L1,%L2\;{ae|adde} %0,%1,%2
2568 {ai|addic} %L0,%L1,%2\;{a%G2e|add%G2e} %0,%1"
2569 [(set_attr "length" "8")])
2570
2571(define_insn ""
2572 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2573 (plus:DI (match_operand:DI 1 "gpc_reg_operand" "%r")
2574 (match_operand:DI 2 "gpc_reg_operand" "r")))]
2575 "TARGET_POWERPC"
2576 "addc %L0,%L1,%L2\;adde %0,%1,%2"
2577 [(set_attr "length" "8")])
2578
2579(define_expand "subdi3"
2580 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
2581 (minus:DI (match_operand:DI 1 "reg_or_short_operand" "r,I")
2582 (match_operand:DI 2 "gpc_reg_operand" "r,r")))]
2583 ""
2584 "
2585{
2586 if (TARGET_POWERPC
2587 && short_cint_operand (operands[1], DImode))
2588 FAIL;
2589}")
2590
2591(define_insn ""
2592 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
2593 (minus:DI (match_operand:DI 1 "reg_or_short_operand" "r,I")
2594 (match_operand:DI 2 "gpc_reg_operand" "r,r")))]
2595 "TARGET_POWER"
2596 "@
2597 {sf|subfc} %L0,%L2,%L1\;{sfe|subfe} %0,%2,%1
2598 {sfi|subfic} %L0,%L2,%1\;{sf%G1e|subf%G1e} %0,%2"
2599 [(set_attr "length" "8")])
2600
2601(define_insn ""
2602 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2603 (minus:DI (match_operand:DI 1 "gpc_reg_operand" "r")
2604 (match_operand:DI 2 "gpc_reg_operand" "r")))]
2605 "TARGET_POWERPC"
2606 "subfc %L0,%L2,%L1\;subfe %0,%2,%1"
2607 [(set_attr "length" "8")])
2608
2609(define_expand "negdi2"
2610 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2611 (neg:DI (match_operand:DI 1 "gpc_reg_operand" "r")))]
2612 ""
2613 "")
2614
2615(define_insn ""
2616 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2617 (neg:DI (match_operand:DI 1 "gpc_reg_operand" "r")))]
2618 "TARGET_POWER"
2619 "{sfi|subfic} %L0,%L1,0\;{sfze|subfze} %0,%1"
2620 [(set_attr "length" "8")])
2621
2622(define_insn ""
2623 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2624 (neg:DI (match_operand:DI 1 "gpc_reg_operand" "r")))]
2625 "TARGET_POWERPC"
2626 "subfic %L0,%L1,0\;subfze %0,%1"
2627 [(set_attr "length" "8")])
2628
2629(define_insn "mulsidi3"
2630 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2631 (mult:DI (sign_extend:DI (match_operand:SI 1 "gpc_reg_operand" "r"))
2632 (sign_extend:DI (match_operand:SI 2 "gpc_reg_operand" "r"))))
2633 (clobber (match_scratch:SI 3 "=q"))]
2634 "TARGET_POWER"
2635 "mul %0,%1,%2\;mfmq %L0"
2636 [(set_attr "length" "8")])
2637
2638;; If operands 0 and 2 are in the same register, we have a problem. But
2639;; operands 0 and 1 (the usual case) can be in the same register. That's
2640;; why we have the strange constraints below.
2641(define_insn "ashldi3"
2642 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,&r")
2643 (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,0,r")
2644 (match_operand:SI 2 "reg_or_cint_operand" "M,i,r,r")))
2645 (clobber (match_scratch:SI 3 "=X,q,q,q"))]
2646 "TARGET_POWER"
2647 "@
2648 {sli|slwi} %0,%L1,%h2\;{cal %L0,0(0)|li %L0,0}
2649 sl%I2q %L0,%L1,%h2\;sll%I2q %0,%1,%h2
2650 sl%I2q %L0,%L1,%h2\;sll%I2q %0,%1,%h2
2651 sl%I2q %L0,%L1,%h2\;sll%I2q %0,%1,%h2"
2652 [(set_attr "length" "8")])
2653
2654(define_insn "lshrdi3"
2655 [(set (match_operand:DI 0 "gpc_reg_operand" "=&r,r,r,&r")
2656 (lshiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,0,r")
2657 (match_operand:SI 2 "reg_or_cint_operand" "M,i,r,r")))
2658 (clobber (match_scratch:SI 3 "=X,q,q,q"))]
2659 "TARGET_POWER"
2660 "@
2661 {cal %0,0(0)|li %0,0}\;{s%A2i|s%A2wi} %L0,%1,%h2
2662 sr%I2q %0,%1,%h2\;srl%I2q %L0,%L1,%h2
2663 sr%I2q %0,%1,%h2\;srl%I2q %L0,%L1,%h2
2664 sr%I2q %0,%1,%h2\;srl%I2q %L0,%L1,%h2"
2665 [(set_attr "length" "8")])
2666
2667;; Shift by a variable amount is too complex to be worth open-coding. We
2668;; just handle shifts by constants.
2669
2670(define_expand "ashrdi3"
2671 [(parallel [(set (match_operand:DI 0 "gpc_reg_operand" "=")
2672 (ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "")
2673 (match_operand:SI 2 "general_operand" "")))
2674 (clobber (match_scratch:SI 3 ""))])]
2675 "TARGET_POWER"
2676 "
2677{ if (GET_CODE (operands[2]) != CONST_INT)
2678 FAIL;
2679}")
2680
2681(define_insn ""
2682 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
2683 (ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
2684 (match_operand:SI 2 "const_int_operand" "M,i")))
2685 (clobber (match_scratch:SI 3 "=X,q"))]
2686 "TARGET_POWER"
2687 "@
2688 {srai|srawi} %0,%1,31\;{srai|srawi} %L0,%1,%h2
2689 sraiq %0,%1,%h2\;srliq %L0,%L1,%h2"
2690 [(set_attr "length" "8")])
2691\f
2692;; Now define ways of moving data around.
2693;;
2694;; For SI, we special-case integers that can't be loaded in one insn. We
2695;; do the load 16-bits at a time. We could do this by loading from memory,
2696;; and this is even supposed to be faster, but it is simpler not to get
2697;; integers in the TOC.
2698(define_expand "movsi"
2699 [(set (match_operand:SI 0 "general_operand" "")
2700 (match_operand:SI 1 "any_operand" ""))]
2701 ""
2702 "
2703{
2704 if (GET_CODE (operands[0]) != REG)
2705 operands[1] = force_reg (SImode, operands[1]);
2706
2707 if (CONSTANT_P (operands[1]) && GET_CODE (operands[1]) != CONST_INT
2708 && ! LEGITIMATE_CONSTANT_POOL_ADDRESS_P (operands[1]))
2709 {
2710 operands[1] = force_const_mem (SImode, operands[1]);
2711 if (! memory_address_p (SImode, XEXP (operands[1], 0))
2712 && ! reload_in_progress)
2713 operands[1] = change_address (operands[1], SImode,
2714 XEXP (operands[1], 0));
2715 }
2716
2717 if (GET_CODE (operands[1]) == CONST_INT
2718 && (unsigned) (INTVAL (operands[1]) + 0x8000) >= 0x10000
2719 && (INTVAL (operands[1]) & 0xffff) != 0)
2720 {
2721 emit_move_insn (operands[0],
2722 gen_rtx (CONST_INT, VOIDmode,
2723 INTVAL (operands[1]) & 0xffff0000));
2724 emit_insn (gen_iorsi3 (operands[0], operands[0],
2725 gen_rtx (CONST_INT, VOIDmode,
2726 INTVAL (operands[1]) & 0xffff)));
2727 DONE;
2728 }
2729}")
2730
2731(define_insn ""
2732 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,m,r,r,r,*c*q,*l,*h")
2733 (match_operand:SI 1 "input_operand" "r,m,r,I,J,*h,r,r,0"))]
2734 "TARGET_POWER && (gpc_reg_operand (operands[0], SImode)
2735 || gpc_reg_operand (operands[1], SImode))"
2736 "@
2737 {ai|addic} %0,%1,0
2738 {l%U1%X1|lwz%U1%X1} %0,%1
2739 {st%U0%X0|stw%U0%X0} %1,%0
2740 {cal %0,%1(0)|li %0,%1}
2741 {cau %0,0,%u1|lis %0,%u1}
2742 mf%1 %0
2743 mt%0 %1
2744 mt%0 %1
2745 cror 0,0,0"
2746 [(set_attr "type" "*,load,*,*,*,*,*,mtlr,*")])
2747
2748(define_insn ""
2749 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,m,r,r,r,*h")
2750 (match_operand:SI 1 "input_operand" "r,m,r,I,J,*h,r"))]
2751 "TARGET_POWERPC && (gpc_reg_operand (operands[0], SImode)
2752 || gpc_reg_operand (operands[1], SImode))"
2753 "@
2754 mr %0,%1
2755 lwz%U1%X1 %0,%1
2756 stw%U0%X0 %1,%0
2757 li %0,%1
2758 lis %0,%u1
2759 mf%1 %0
2760 mt%0 %1"
2761 [(set_attr "type" "*,load,*,*,*,*,*")])
2762
2763;; Split a load of a large constant into the appropriate two-insn
2764;; sequence.
2765
2766(define_split
2767 [(set (match_operand:SI 0 "gpc_reg_operand" "")
2768 (match_operand:SI 1 "const_int_operand" ""))]
2769 "(unsigned) (INTVAL (operands[1]) + 0x8000) >= 0x10000
2770 && (INTVAL (operands[1]) & 0xffff) != 0"
2771 [(set (match_dup 0)
2772 (match_dup 2))
2773 (set (match_dup 0)
2774 (ior:SI (match_dup 0)
2775 (match_dup 3)))]
2776 "
2777{
2778 operands[2] = gen_rtx (CONST_INT, VOIDmode,
2779 INTVAL (operands[1]) & 0xffff0000);
2780 operands[3] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[1]) & 0xffff);
2781}")
2782
2783(define_insn ""
2784 [(set (match_operand:CC 2 "cc_reg_operand" "=x")
2785 (compare:CC (match_operand:SI 1 "gpc_reg_operand" "r")
2786 (const_int 0)))
2787 (set (match_operand:SI 0 "gpc_reg_operand" "=r") (match_dup 1))]
2788 ""
2789 "{ai.|addic.} %0,%1,0"
2790 [(set_attr "type" "compare")])
2791\f
2792(define_expand "movhi"
2793 [(set (match_operand:HI 0 "general_operand" "")
2794 (match_operand:HI 1 "any_operand" ""))]
2795 ""
2796 "
2797{
2798 if (GET_CODE (operands[0]) != REG)
2799 operands[1] = force_reg (HImode, operands[1]);
2800
2801 if (CONSTANT_P (operands[1]) && GET_CODE (operands[1]) != CONST_INT)
2802 {
2803 operands[1] = force_const_mem (HImode, operands[1]);
2804 if (! memory_address_p (HImode, XEXP (operands[1], 0))
2805 && ! reload_in_progress)
2806 operands[1] = change_address (operands[1], HImode,
2807 XEXP (operands[1], 0));
2808 }
2809}")
2810
2811(define_insn ""
2812 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,m,r,r,*h,*h")
2813 (match_operand:HI 1 "input_operand" "r,m,r,i,*h,r,0"))]
2814 "TARGET_POWER && (gpc_reg_operand (operands[0], HImode)
2815 || gpc_reg_operand (operands[1], HImode))"
2816 "@
2817 {oril|ori} %0,%1,0
2818 lhz%U1%X1 %0,%1
2819 sth%U0%X0 %1,%0
2820 {cal %0,%w1(0)|li %0,%w1}
2821 mf%1 %0
2822 mt%0 %1
2823 cror 0,0,0"
2824 [(set_attr "type" "*,load,*,*,*,*,*")])
2825
2826(define_insn ""
2827 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,m,r,r,*h")
2828 (match_operand:HI 1 "input_operand" "r,m,r,i,*h,r"))]
2829 "TARGET_POWERPC && (gpc_reg_operand (operands[0], HImode)
2830 || gpc_reg_operand (operands[1], HImode))"
2831 "@
2832 ori %0,%1,0
2833 lhz%U1%X1 %0,%1
2834 sth%U0%X0 %1,%0
2835 li %0,%w1
2836 mf%1 %0
2837 mt%0 %1"
2838 [(set_attr "type" "*,load,*,*,*,*")])
2839
2840(define_expand "movqi"
2841 [(set (match_operand:QI 0 "general_operand" "")
2842 (match_operand:QI 1 "any_operand" ""))]
2843 ""
2844 "
2845{
2846 if (GET_CODE (operands[0]) != REG)
2847 operands[1] = force_reg (QImode, operands[1]);
2848
2849 if (CONSTANT_P (operands[1]) && GET_CODE (operands[1]) != CONST_INT)
2850 {
2851 operands[1] = force_const_mem (QImode, operands[1]);
2852 if (! memory_address_p (QImode, XEXP (operands[1], 0))
2853 && ! reload_in_progress)
2854 operands[1] = change_address (operands[1], QImode,
2855 XEXP (operands[1], 0));
2856 }
2857}")
2858
2859(define_insn ""
2860 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m,r,r,*h,*h")
2861 (match_operand:QI 1 "input_operand" "r,m,r,i,*h,r,0"))]
2862 "TARGET_POWER && (gpc_reg_operand (operands[0], QImode)
2863 || gpc_reg_operand (operands[1], QImode))"
2864 "@
2865 {oril|ori} %0,%1,0
2866 lbz%U1%X1 %0,%1
2867 stb%U0%X0 %1,%0
2868 {cal %0,%1(0)|li %0,%1}
2869 mf%1 %0
2870 mt%0 %1
2871 cror 0,0,0"
2872 [(set_attr "type" "*,load,*,*,*,*,*")])
2873
2874(define_insn ""
2875 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m,r,r,*h")
2876 (match_operand:QI 1 "input_operand" "r,m,r,i,*h,r"))]
2877 "TARGET_POWERPC && (gpc_reg_operand (operands[0], QImode)
2878 || gpc_reg_operand (operands[1], QImode))"
2879 "@
2880 mr %0,%1
2881 lbz%U1%X1 %0,%1
2882 stb%U0%X0 %1,%0
2883 li %0,%1
2884 mf%1 %0
2885 mt%0 %1"
2886 [(set_attr "type" "*,load,*,*,*,*")])
2887\f
2888;; Here is how to move condition codes around. When we store CC data in
2889;; an integer register or memory, we store just the high-order 4 bits.
2890;; This lets us not shift in the most common case of CR0.
2891(define_expand "movcc"
2892 [(set (match_operand:CC 0 "nonimmediate_operand" "")
2893 (match_operand:CC 1 "nonimmediate_operand" ""))]
2894 ""
2895 "")
2896
2897(define_insn ""
2898 [(set (match_operand:CC 0 "nonimmediate_operand" "=y,x,y,r,r,r,r,m")
2899 (match_operand:CC 1 "nonimmediate_operand" "y,r,r,x,y,r,m,r"))]
2900 "register_operand (operands[0], CCmode)
2901 || register_operand (operands[1], CCmode)"
2902 "@
2903 mcrf %0,%1
2904 mtcrf 128,%1
2905 {rlinm|rlwinm} %1,%1,%F0,0xffffffff\;mtcrf %R0,%1\;{rlinm|rlwinm} %1,%1,%f0,0xffffffff
2906 mfcr %0
2907 mfcr %0\;{rlinm|rlwinm} %0,%0,%f1,0xf0000000
2908 {ai %0,%1,0|mr %0,%1}
2909 {l%U1%X1|lwz%U1%X1} %0,%1
2910 {st%U0%U1|stw%U0%U1} %1,%0"
2911 [(set_attr "type" "*,*,*,compare,*,*,load,*")
2912 (set_attr "length" "*,*,12,*,8,*,*,*")])
2913\f
2914;; For floating-point, we normally deal with the floating-point registers.
2915;; The sole exception is that parameter passing can produce floating-point
2916;; values in fixed-point registers. Unless the value is a simple constant
2917;; or already in memory, we deal with this by allocating memory and copying
2918;; the value explicitly via that memory location.
2919(define_expand "movsf"
2920 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2921 (match_operand:SF 1 "any_operand" ""))]
2922 ""
2923 "
2924{
2925 /* If we are called from reload, we might be getting a SUBREG of a hard
2926 reg. So expand it. */
2927 if (GET_CODE (operands[0]) == SUBREG
2928 && GET_CODE (SUBREG_REG (operands[0])) == REG
2929 && REGNO (SUBREG_REG (operands[0])) < FIRST_PSEUDO_REGISTER)
2930 operands[0] = alter_subreg (operands[0]);
2931 if (GET_CODE (operands[1]) == SUBREG
2932 && GET_CODE (SUBREG_REG (operands[1])) == REG
2933 && REGNO (SUBREG_REG (operands[1])) < FIRST_PSEUDO_REGISTER)
2934 operands[1] = alter_subreg (operands[1]);
2935
2936 if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) < 32)
2937 {
2938 rtx stack_slot;
2939
2940 /* If this is a store to memory or another integer register do the
2941 move directly. Otherwise store to a temporary stack slot and
2942 load from there into a floating point register. */
2943
2944 if (GET_CODE (operands[0]) == MEM
2945 || (GET_CODE (operands[0]) == REG
2946 && (REGNO (operands[0]) < 32
2947 || (reload_in_progress
2948 && REGNO (operands[0]) >= FIRST_PSEUDO_REGISTER))))
2949 {
2950 emit_move_insn (operand_subword (operands[0], 0, 0, SFmode),
2951 operand_subword (operands[1], 0, 0, SFmode));
2952 DONE;
2953 }
2954
2955 stack_slot = gen_rtx (MEM, SFmode, plus_constant (stack_pointer_rtx, 4));
2956 emit_move_insn (stack_slot, operands[1]);
2957 emit_move_insn (operands[0], stack_slot);
2958 DONE;
2959 }
2960
2961 if (GET_CODE (operands[0]) == MEM)
2962 operands[1] = force_reg (SFmode, operands[1]);
2963
2964 if (GET_CODE (operands[0]) == REG && REGNO (operands[0]) < 32)
2965 {
2966 rtx stack_slot;
2967
2968 if (GET_CODE (operands[1]) == MEM
2969#if HOST_FLOAT_FORMAT == TARGET_FLOAT_FORMAT && ! defined(REAL_IS_NOT_DOUBLE)
2970 || GET_CODE (operands[1]) == CONST_DOUBLE
2971#endif
2972 || (GET_CODE (operands[1]) == REG && REGNO (operands[1]) < 32)
2973 || (reload_in_progress && GET_CODE (operands[1]) == REG
2974 && REGNO (operands[1]) >= FIRST_PSEUDO_REGISTER))
2975 {
2976 emit_move_insn (operand_subword (operands[0], 0, 0, SFmode),
2977 operand_subword (operands[1], 0, 0, SFmode));
2978 DONE;
2979 }
2980
2981 if (reload_in_progress)
2982 stack_slot = gen_rtx (MEM, SFmode,
2983 plus_constant (stack_pointer_rtx, 4));
2984 else
2985 stack_slot = assign_stack_temp (SFmode, 4, 0);
2986 emit_move_insn (stack_slot, operands[1]);
2987 emit_move_insn (operands[0], stack_slot);
2988 DONE;
2989 }
2990
2991 if (CONSTANT_P (operands[1]))
2992 {
2993 operands[1] = force_const_mem (SFmode, operands[1]);
2994 if (! memory_address_p (SFmode, XEXP (operands[1], 0))
2995 && ! reload_in_progress)
2996 operands[1] = change_address (operands[1], SFmode,
2997 XEXP (operands[1], 0));
2998 }
2999}")
3000
3001(define_split
3002 [(set (match_operand:SF 0 "gpc_reg_operand" "")
3003 (match_operand:SF 1 "easy_fp_constant" ""))]
3004 "reload_completed && REGNO (operands[0]) <= 31"
3005 [(set (match_dup 2) (match_dup 3))]
3006 "
3007{ operands[2] = operand_subword (operands[0], 0, 0, SFmode);
3008 operands[3] = operand_subword (operands[1], 0, 0, SFmode); }")
3009
3010(define_insn ""
3011 [(set (match_operand:SF 0 "fp_reg_or_mem_operand" "=f,f,m")
3012 (match_operand:SF 1 "input_operand" "f,m,f"))]
3013 "gpc_reg_operand (operands[0], SFmode)
3014 || gpc_reg_operand (operands[1], SFmode)"
3015 "@
3016 fmr %0,%1
3017 lfs%U1%X1 %0,%1
3018 frsp %1,%1\;stfs%U0%X0 %1,%0"
3019 [(set_attr "type" "fp,fpload,*")
3020 (set_attr "length" "*,*,8")])
3021\f
3022(define_expand "movdf"
3023 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3024 (match_operand:DF 1 "any_operand" ""))]
3025 ""
3026 "
3027{
3028 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3029 {
3030 emit_move_insn (operand_subword (operands[0], 1, 1, DFmode),
3031 operand_subword_force (operands[1], 1, DFmode));
3032 emit_move_insn (operand_subword (operands[0], 0, 1, DFmode),
3033 operand_subword_force (operands[1], 0, DFmode));
3034 DONE;
3035 }
3036
3037 if (GET_CODE (operands[0]) != REG)
3038 operands[1] = force_reg (DFmode, operands[1]);
3039
3040 if (CONSTANT_P (operands[1]) && ! easy_fp_constant (operands[1], DFmode))
3041 {
3042 operands[1] = force_const_mem (DFmode, operands[1]);
3043 if (! memory_address_p (DFmode, XEXP (operands[1], 0))
3044 && ! reload_in_progress)
3045 operands[1] = change_address (operands[1], DFmode,
3046 XEXP (operands[1], 0));
3047 }
3048}")
3049
3050(define_split
3051 [(set (match_operand:DF 0 "gpc_reg_operand" "")
3052 (match_operand:DF 1 "easy_fp_constant" ""))]
3053 "reload_completed && REGNO (operands[0]) <= 31"
3054 [(set (match_dup 2) (match_dup 3))
3055 (set (match_dup 4) (match_dup 5))]
3056 "
3057{ operands[2] = operand_subword (operands[0], 0, 0, DFmode);
3058 operands[3] = operand_subword (operands[1], 0, 0, DFmode);
3059 operands[4] = operand_subword (operands[0], 1, 0, DFmode);
3060 operands[5] = operand_subword (operands[1], 1, 0, DFmode); }")
3061
3062(define_insn ""
3063 [(set (match_operand:DF 0 "nonimmediate_operand" "=!r,r,o,r,f,f,m")
3064 (match_operand:DF 1 "input_operand" "r,o,r,G,f,m,f"))]
3065 "register_operand (operands[0], DFmode)
3066 || register_operand (operands[1], DFmode)"
3067 "*
3068{
3069 switch (which_alternative)
3070 {
3071 case 0:
3072 /* We normally copy the low-numbered register first. However, if
3073 the first register operand 0 is the same as the second register of
3074 operand 1, we must copy in the opposite order. */
3075 if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
3076 return \"{oril %L0,%L1,0|mr %L0,%L1}\;{oril %0,%1,0|mr %0,%1}\";
3077 else
3078 return \"{oril %0,%1,0|mr %0,%1}\;{oril %L0,%L1,0|mr %L0,%L1}\";
3079 case 1:
3080 /* If the low-address word is used in the address, we must load it
3081 last. Otherwise, load it first. Note that we cannot have
3082 auto-increment in that case since the address register is known to be
3083 dead. */
3084 if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
3085 operands [1], 0))
3086 return \"{l|lwz} %L0,%L1\;{l|lwz} %0,%1\";
3087 else
3088 return \"{l%U1|lwz%U1} %0,%1\;{l|lwz} %L0,%L1\";
3089 case 2:
3090 return \"{st%U0|stw%U0} %1,%0\;{st|stw} %L1,%L0\";
3091 case 3:
3092 return \"#\";
3093 case 4:
3094 return \"fmr %0,%1\";
3095 case 5:
3096 return \"lfd%U1%X1 %0,%1\";
3097 case 6:
3098 return \"stfd%U0%X0 %1,%0\";
3099 }
3100}"
3101 [(set_attr "type" "*,load,*,*,fp,fpload,*")
3102 (set_attr "length" "8,8,8,8,*,*,*")])
3103\f
3104;; Next come the multi-word integer load and store and the load and store
3105;; multiple insns.
3106(define_expand "movdi"
3107 [(set (match_operand:DI 0 "general_operand" "")
3108 (match_operand:DI 1 "general_operand" ""))]
3109 ""
3110 "
3111{
3112 if (GET_CODE (operands[1]) == CONST_DOUBLE
3113 || GET_CODE (operands[1]) == CONST_INT)
3114 {
3115 emit_move_insn (operand_subword (operands[0], 0, 0, DImode),
3116 operand_subword (operands[1], 0, 0, DImode));
3117 emit_move_insn (operand_subword (operands[0], 1, 0, DImode),
3118 operand_subword (operands[1], 1, 0, DImode));
3119 DONE;
3120 }
3121
3122 if (GET_CODE (operands[0]) == MEM)
3123 operands[1] = force_reg (DImode, operands[1]);
3124}")
3125
3126(define_insn ""
3127 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m")
3128 (match_operand:DI 1 "input_operand" "r,m,r"))]
3129 "gpc_reg_operand (operands[0], DImode)
3130 || gpc_reg_operand (operands[1], DImode)"
3131 "*
3132{
3133 switch (which_alternative)
3134 {
3135 case 0:
3136 /* We normally copy the low-numbered register first. However, if
3137 the first register operand 0 is the same as the second register of
3138 operand 1, we must copy in the opposite order. */
3139 if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
3140 return \"{oril %L0,%L1,0|mr %L0,%L1}\;{oril %0,%1,0|mr %0,%1}\";
3141 else
3142 return \"{oril %0,%1,0|mr %0,%1}\;{oril %L0,%L1,0|mr %L0,%L1}\";
3143 case 1:
3144 /* If the low-address word is used in the address, we must load it
3145 last. Otherwise, load it first. Note that we cannot have
3146 auto-increment in that case since the address register is known to be
3147 dead. */
3148 if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
3149 operands [1], 0))
3150 return \"{l|lwz} %L0,%L1\;{l|lwz} %0,%1\";
3151 else
3152 return \"{l%U1|lwz%U1} %0,%1\;{l|lwz} %L0,%L1\";
3153 case 2:
3154 return \"{st%U0|stw%U0} %1,%0\;{st|stw} %L1,%L0\";
3155 }
3156}"
3157 [(set_attr "type" "*,load,*")
3158 (set_attr "length" "8")])
3159\f
3160;; TImode is similar, except that we usually want to compute the address into
3161;; a register and use lsi/stsi (the exception is during reload). MQ is also
3162;; clobbered in stsi for POWER, so we need a SCRATCH for it.
3163(define_expand "movti"
3164 [(parallel [(set (match_operand:TI 0 "general_operand" "")
3165 (match_operand:TI 1 "general_operand" ""))
3166 (clobber (scratch:SI))])]
3167 "TARGET_POWER"
3168 "
3169{
3170 if (GET_CODE (operands[0]) == MEM)
3171 operands[1] = force_reg (TImode, operands[1]);
3172
3173 if (GET_CODE (operands[0]) == MEM
3174 && GET_CODE (XEXP (operands[0], 0)) != REG
3175 && ! reload_in_progress)
3176 operands[0] = change_address (operands[0], TImode,
3177 copy_addr_to_reg (XEXP (operands[0], 0)));
3178
3179 if (GET_CODE (operands[1]) == MEM
3180 && GET_CODE (XEXP (operands[1], 0)) != REG
3181 && ! reload_in_progress)
3182 operands[1] = change_address (operands[1], TImode,
3183 copy_addr_to_reg (XEXP (operands[1], 0)));
3184}")
3185
3186;; We say that MQ is clobbered in the last alternative because the first
3187;; alternative would never get used otherwise since it would need a reload
3188;; while the 2nd alternative would not. We put memory cases first so they
3189;; are preferred. Otherwise, we'd try to reload the output instead of
3190;; giving the SCRATCH mq.
3191(define_insn ""
3192 [(set (match_operand:TI 0 "reg_or_mem_operand" "=Q,m,r,r,r")
3193 (match_operand:TI 1 "reg_or_mem_operand" "r,r,r,Q,m"))
3194 (clobber (match_scratch:SI 2 "=q,q#X,X,X,X"))]
3195 "TARGET_POWER && (gpc_reg_operand (operands[0], TImode)
3196 || gpc_reg_operand (operands[1], TImode))"
3197 "*
3198{
3199 switch (which_alternative)
3200 {
3201 case 0:
3202 return \"{stsi|stswi} %1,%P0,16\";
3203
3204 case 1:
3205 return \"{st%U0|stw%U0} %1,%0\;{st|stw} %L1,%L0\;{st|stw} %Y1,%Y0\;{st|stw} %Z1,%Z0\";
3206
3207 case 2:
3208 /* Normally copy registers with lowest numbered register copied first.
3209 But copy in the other order if the first register of the output
3210 is the second, third, or fourth register in the input. */
3211 if (REGNO (operands[0]) >= REGNO (operands[1]) + 1
3212 && REGNO (operands[0]) <= REGNO (operands[1]) + 3)
3213 return \"{oril %Z0,%Z1,0|mr %Z0,%Z1}\;{oril %Y0,%Y1,0|mr %Y0,%Y1}\;{oril %L0,%L1,0|mr %L0,%L1}\;{oril %0,%1,0|mr %0,%1}\";
3214 else
3215 return \"{oril %0,%1,0|mr %0,%1}\;{oril %L0,%L1,0|mr %L0,%L1}\;{oril %Y0,%Y1,0|mr %Y0,%Y1}\;{oril %Z0,%Z1,0|mr %Z0,%Z1}\";
3216 case 3:
3217 /* If the address is not used in the output, we can use lsi. Otherwise,
3218 fall through to generating four loads. */
3219 if (! reg_overlap_mentioned_p (operands[0], operands[1]))
3220 return \"{lsi|lswi} %0,%P1,16\";
3221 /* ... fall through ... */
3222 case 4:
3223 /* If the address register is the same as the register for the lowest-
3224 addressed word, load it last. Similarly for the next two words.
3225 Otherwise load lowest address to highest. */
3226 if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
3227 operands[1], 0))
3228 return \"{l|lwz} %L0,%L1\;{l|lwz} %Y0,%Y1\;{l|lwz} %Z0,%Z1\;{l|lwz} %0,%1\";
3229 else if (refers_to_regno_p (REGNO (operands[0]) + 1,
3230 REGNO (operands[0]) + 2, operands[1], 0))
3231 return \"{l|lwz} %0,%1\;{l|lwz} %Y0,%Y1\;{l|lwz} %Z0,%Z1\;{l|lwz} %L0,%L1\";
3232 else if (refers_to_regno_p (REGNO (operands[0]) + 2,
3233 REGNO (operands[0]) + 3, operands[1], 0))
3234 return \"{l|lwz} %0,%1\;{l|lwz} %L0,%L1\;{l|lwz} %Z0,%Z1\;{l|lwz} %Y0,%Y1\";
3235 else
3236 return \"{l%U1|lwz%U1} %0,%1\;{l|lwz} %L0,%L1\;{l|lwz} %Y0,%Y1\;{l|lwz} %Z0,%Z1\";
3237 }
3238}"
3239 [(set_attr "type" "*,load,load,*,*")
3240 (set_attr "length" "*,16,16,*,16")])
3241\f
3242(define_expand "load_multiple"
3243 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
3244 (match_operand:SI 1 "" ""))
3245 (use (match_operand:SI 2 "" ""))])]
3246 "TARGET_POWER"
3247 "
3248{
3249 int regno;
3250 int count;
3251 rtx from;
3252 int i;
3253
3254 /* Support only loading a constant number of fixed-point registers from
3255 memory and only bother with this if more than two; the machine
3256 doesn't support more than eight. */
3257 if (GET_CODE (operands[2]) != CONST_INT
3258 || INTVAL (operands[2]) <= 2
3259 || INTVAL (operands[2]) > 8
3260 || GET_CODE (operands[1]) != MEM
3261 || GET_CODE (operands[0]) != REG
3262 || REGNO (operands[0]) >= 32)
3263 FAIL;
3264
3265 count = INTVAL (operands[2]);
3266 regno = REGNO (operands[0]);
3267
3268 operands[3] = gen_rtx (PARALLEL, VOIDmode, rtvec_alloc (count));
3269 from = force_reg (SImode, XEXP (operands[1], 0));
3270
3271 for (i = 0; i < count; i++)
3272 XVECEXP (operands[3], 0, i)
3273 = gen_rtx (SET, VOIDmode, gen_rtx (REG, SImode, regno + i),
3274 gen_rtx (MEM, SImode, plus_constant (from, i * 4)));
3275}")
3276
3277(define_insn ""
3278 [(match_parallel 0 "load_multiple_operation"
3279 [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
3280 (match_operand:SI 2 "indirect_operand" "Q"))])]
3281 "TARGET_POWER"
3282 "*
3283{
3284 /* We have to handle the case where the pseudo used to contain the address
3285 is assigned to one of the output registers. In that case, do the
3286 lsi, but then load the correct value. This is a bit of a mess, but is
3287 the best we can do.
3288 We set the length attribute to the maximum possible size (8 bytes). */
3289 static char result[100];
3290 char newload[40];
3291 int i;
3292
3293 strcpy (result, \"{lsi|lswi} %1,%P2,%N0\");
3294 for (i = 0; i < XVECLEN (operands[0], 0); i++)
3295 if (refers_to_regno_p (REGNO (operands[1]) + i,
3296 REGNO (operands[1]) + i + 1, operands[2], 0))
3297 {
3298 sprintf (newload, \"\;{l|lwz} %d,%d(%d)\",
3299 REGNO (operands[1]) + i,
3300 i * 4, REGNO (XEXP (operands[2], 0)));
3301 strcat (result, newload);
3302 }
3303
3304 return result;
3305}"
3306 [(set_attr "type" "load")
3307 (set_attr "length" "8")])
3308\f
3309
3310(define_expand "store_multiple"
3311 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
3312 (match_operand:SI 1 "" ""))
3313 (clobber (scratch:SI))
3314 (use (match_operand:SI 2 "" ""))])]
3315 "TARGET_POWER"
3316 "
3317{
3318 int regno;
3319 int count;
3320 rtx to;
3321 int i;
3322
3323 /* Support only storing a constant number of fixed-point registers to
3324 memory and only bother with this if more than two; the machine
3325 doesn't support more than eight. */
3326 if (GET_CODE (operands[2]) != CONST_INT
3327 || INTVAL (operands[2]) <= 2
3328 || INTVAL (operands[2]) > 8
3329 || GET_CODE (operands[0]) != MEM
3330 || GET_CODE (operands[1]) != REG
3331 || REGNO (operands[1]) >= 32)
3332 FAIL;
3333
3334 count = INTVAL (operands[2]);
3335 regno = REGNO (operands[1]);
3336
3337 operands[3] = gen_rtx (PARALLEL, VOIDmode, rtvec_alloc (count + 1));
3338 to = force_reg (SImode, XEXP (operands[0], 0));
3339
3340 XVECEXP (operands[3], 0, 0)
3341 = gen_rtx (SET, VOIDmode, gen_rtx (MEM, SImode, to), operands[1]);
3342 XVECEXP (operands[3], 0, 1) = gen_rtx (CLOBBER, VOIDmode,
3343 gen_rtx (SCRATCH, SImode));
3344
3345 for (i = 1; i < count; i++)
3346 XVECEXP (operands[3], 0, i + 1)
3347 = gen_rtx (SET, VOIDmode,
3348 gen_rtx (MEM, SImode, plus_constant (to, i * 4)),
3349 gen_rtx (REG, SImode, regno + i));
3350}")
3351
3352(define_insn ""
3353 [(match_parallel 0 "store_multiple_operation"
3354 [(set (match_operand:SI 1 "indirect_operand" "=Q")
3355 (match_operand:SI 2 "gpc_reg_operand" "r"))
3356 (clobber (match_scratch:SI 3 "=q"))])]
3357 "TARGET_POWER"
3358 "{stsi|stswi} %2,%P1,%O0")
3359\f
3360;; Define insns that do load or store with update. Some of these we can
3361;; get by using pre-decrement or pre-increment, but the hardware can also
3362;; do cases where the increment is not the size of the object.
3363;;
3364;; In all these cases, we use operands 0 and 1 for the register being
3365;; incremented because those are the operands that local-alloc will
3366;; tie and these are the pair most likely to be tieable (and the ones
3367;; that will benefit the most).
3368
3369(define_insn ""
3370 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
3371 (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
3372 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
3373 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
3374 (plus:SI (match_dup 1) (match_dup 2)))]
3375 ""
3376 "@
3377 {lux|lwzux} %3,%0,%2
3378 {lu|lwzu} %3,%2(%0)"
3379 [(set_attr "type" "load")])
3380
3381(define_insn ""
3382 [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
3383 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
3384 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
3385 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
3386 (plus:SI (match_dup 1) (match_dup 2)))]
3387 ""
3388 "@
3389 {stux|stwux} %3,%0,%2
3390 {stu|stwu} %3,%2(%0)")
3391
3392(define_insn ""
3393 [(set (match_operand:HI 3 "gpc_reg_operand" "=r,r")
3394 (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
3395 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
3396 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
3397 (plus:SI (match_dup 1) (match_dup 2)))]
3398 ""
3399 "@
3400 lhzux %3,%0,%2
3401 lhzu %3,%2(%0)"
3402 [(set_attr "type" "load")])
3403
3404(define_insn ""
3405 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
3406 (zero_extend:SI
3407 (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
3408 (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
3409 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
3410 (plus:SI (match_dup 1) (match_dup 2)))]
3411 ""
3412 "@
3413 lhzux %3,%0,%2
3414 lhzu %3,%2(%0)"
3415 [(set_attr "type" "load")])
3416
3417(define_insn ""
3418 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
3419 (sign_extend:SI
3420 (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
3421 (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
3422 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
3423 (plus:SI (match_dup 1) (match_dup 2)))]
3424 ""
3425 "@
3426 lhaux %3,%0,%2
3427 lhau %3,%2(%0)"
3428 [(set_attr "type" "load")])
3429
3430(define_insn ""
3431 [(set (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
3432 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
3433 (match_operand:HI 3 "gpc_reg_operand" "r,r"))
3434 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
3435 (plus:SI (match_dup 1) (match_dup 2)))]
3436 ""
3437 "@
3438 sthux %3,%0,%2
3439 sthu %3,%2(%0)")
3440
3441(define_insn ""
3442 [(set (match_operand:QI 3 "gpc_reg_operand" "=r,r")
3443 (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
3444 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
3445 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
3446 (plus:SI (match_dup 1) (match_dup 2)))]
3447 ""
3448 "@
3449 lbzux %3,%0,%2
3450 lbzu %3,%2(%0)"
3451 [(set_attr "type" "load")])
3452
3453(define_insn ""
3454 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
3455 (zero_extend:SI
3456 (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
3457 (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
3458 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
3459 (plus:SI (match_dup 1) (match_dup 2)))]
3460 ""
3461 "@
3462 lbzux %3,%0,%2
3463 lbzu %3,%2(%0)"
3464 [(set_attr "type" "load")])
3465
3466(define_insn ""
3467 [(set (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
3468 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
3469 (match_operand:QI 3 "gpc_reg_operand" "r,r"))
3470 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
3471 (plus:SI (match_dup 1) (match_dup 2)))]
3472 ""
3473 "@
3474 stbux %3,%0,%2
3475 stbu %3,%2(%0)")
3476
3477(define_insn ""
3478 [(set (match_operand:SF 3 "gpc_reg_operand" "=f,f")
3479 (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
3480 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
3481 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
3482 (plus:SI (match_dup 1) (match_dup 2)))]
3483 ""
3484 "@
3485 lfsux %3,%0,%2
3486 lfsu %3,%2(%0)"
3487 [(set_attr "type" "fpload")])
3488
3489(define_insn ""
3490 [(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
3491 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
3492 (match_operand:SF 3 "gpc_reg_operand" "f,f"))
3493 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
3494 (plus:SI (match_dup 1) (match_dup 2)))]
3495 ""
3496 "@
3497 frsp %3,%3\;stfsux %3,%0,%2
3498 frsp %3,%3\;stfsu %3,%2(%0)")
3499
3500(define_insn ""
3501 [(set (match_operand:DF 3 "gpc_reg_operand" "=f,f")
3502 (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
3503 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
3504 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
3505 (plus:SI (match_dup 1) (match_dup 2)))]
3506 ""
3507 "@
3508 lfdux %3,%0,%2
3509 lfdu %3,%2(%0)"
3510 [(set_attr "type" "fpload")])
3511
3512(define_insn ""
3513 [(set (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
3514 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
3515 (match_operand:DF 3 "gpc_reg_operand" "f,f"))
3516 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
3517 (plus:SI (match_dup 1) (match_dup 2)))]
3518 ""
3519 "@
3520 stfdux %3,%0,%2
3521 stfdu %3,%2(%0)")
3522\f
3523;; Next come insns related to the calling sequence.
3524;;
3525;; First, an insn to allocate new stack space for dynamic use (e.g., alloca).
3526;; We move the back-chain and decrement the stack pointer.
3527
3528(define_expand "allocate_stack"
3529 [(set (reg:SI 1)
3530 (minus:SI (reg:SI 1) (match_operand:SI 0 "reg_or_short_operand" "")))]
3531 ""
3532 "
3533{ rtx chain = gen_reg_rtx (SImode);
3534 rtx stack_bot = gen_rtx (MEM, Pmode, stack_pointer_rtx);
3535
3536 emit_move_insn (chain, stack_bot);
3537 emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx, operands[0]));
3538 emit_move_insn (stack_bot, chain);
3539 DONE;
3540}")
3541
3542;; These patterns say how to save and restore the stack pointer. We need not
3543;; save the stack pointer at function level since we are careful to
3544;; preserve the backchain. At block level, we have to restore the backchain
3545;; when we restore the stack pointer.
3546;;
3547;; For nonlocal gotos, we must save both the stack pointer and its
3548;; backchain and restore both. Note that in the nonlocal case, the
3549;; save area is a memory location.
3550
3551(define_expand "save_stack_function"
3552 [(use (const_int 0))]
3553 ""
3554 "")
3555
3556(define_expand "restore_stack_function"
3557 [(use (const_int 0))]
3558 ""
3559 "")
3560
3561(define_expand "restore_stack_block"
3562 [(set (match_dup 2) (mem:SI (match_operand:SI 0 "register_operand" "")))
3563 (set (match_dup 0) (match_operand:SI 1 "register_operand" ""))
3564 (set (mem:SI (match_dup 0)) (match_dup 2))]
3565 ""
3566 "
3567{ operands[2] = gen_reg_rtx (SImode); }")
3568
3569(define_expand "save_stack_nonlocal"
3570 [(match_operand:DI 0 "memory_operand" "")
3571 (match_operand:SI 1 "register_operand" "")]
3572 ""
3573 "
3574{
3575 rtx temp = gen_reg_rtx (SImode);
3576
3577 /* Copy the backchain to the first word, sp to the second. */
3578 emit_move_insn (temp, gen_rtx (MEM, SImode, operands[1]));
3579 emit_move_insn (operand_subword (operands[0], 0, 0, DImode), temp);
3580 emit_move_insn (operand_subword (operands[0], 1, 0, DImode), operands[1]);
3581 DONE;
3582}")
3583
3584(define_expand "restore_stack_nonlocal"
3585 [(match_operand:SI 0 "register_operand" "")
3586 (match_operand:DI 1 "memory_operand" "")]
3587 ""
3588 "
3589{
3590 rtx temp = gen_reg_rtx (SImode);
3591
3592 /* Restore the backchain from the first word, sp from the second. */
3593 emit_move_insn (temp, operand_subword (operands[1], 0, 0, DImode));
3594 emit_move_insn (operands[0], operand_subword (operands[1], 1, 0, DImode));
3595 emit_move_insn (gen_rtx (MEM, SImode, operands[0]), temp);
3596 DONE;
3597}")
3598\f
3599;; A function pointer is a pointer to a data area whose first word contains
3600;; the actual address of the function, whose second word contains a pointer
3601;; to its TOC, and whose third word contains a value to place in the static
3602;; chain register (r11). Note that if we load the static chain, our
3603;; "trampoline" need not have any executable code.
3604;;
3605;; operands[0] is an SImode pseudo in which we place the address of the
3606;; function.
3607;; operands[1] is the address of data area of the function to call
3608
3609(define_expand "call_via_ptr"
3610 [(set (match_operand:SI 0 "gpc_reg_operand" "")
3611 (mem:SI (match_operand:SI 1 "gpc_reg_operand" "")))
3612 (set (mem:SI (plus:SI (reg:SI 1) (const_int 20)))
3613 (reg:SI 2))
3614 (set (reg:SI 2)
3615 (mem:SI (plus:SI (match_dup 1)
3616 (const_int 4))))
3617 (set (reg:SI 11)
3618 (mem:SI (plus:SI (match_dup 1)
3619 (const_int 8))))
3620 (use (reg:SI 2))
3621 (use (reg:SI 11))]
3622 ""
3623 "")
3624
3625(define_expand "call"
3626 [(parallel [(call (mem:SI (match_operand:SI 0 "address_operand" ""))
3627 (match_operand 1 "" ""))
3628 (clobber (scratch:SI))])]
3629 ""
3630 "
3631{
3632 if (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != CONST_INT)
3633 abort ();
3634
3635 operands[0] = XEXP (operands[0], 0);
3636 if (GET_CODE (operands[0]) != SYMBOL_REF)
3637 {
3638 rtx temp = gen_reg_rtx (SImode);
3639
3640 emit_insn (gen_call_via_ptr (temp, force_reg (SImode, operands[0])));
3641 operands[0] = temp;
3642 }
3643}")
3644
3645(define_expand "call_value"
3646 [(parallel [(set (match_operand 0 "" "")
3647 (call (mem:SI (match_operand:SI 1 "address_operand" ""))
3648 (match_operand 2 "" "")))
3649 (clobber (scratch:SI))])]
3650 ""
3651 "
3652{
3653 if (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != CONST_INT)
3654 abort ();
3655
3656 operands[1] = XEXP (operands[1], 0);
3657 if (GET_CODE (operands[1]) != SYMBOL_REF)
3658 {
3659 rtx temp = gen_reg_rtx (SImode);
3660
3661 emit_insn (gen_call_via_ptr (temp, force_reg (SImode, operands[1])));
3662 operands[1] = temp;
3663 }
3664}")
3665
3666;; Call to function in current module. No TOC pointer reload needed.
3667
3668(define_insn ""
3669 [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s"))
3670 (match_operand 1 "" "g"))
3671 (clobber (match_scratch:SI 2 "=l"))]
3672 ""
3673 "bl %z0")
3674
3675;; Call to function which may be in another module. Restore the TOC
3676;; pointer (r2) after the call.
3677
3678(define_insn ""
3679 [(call (mem:SI (match_operand:SI 0 "call_operand" "l,s"))
3680 (match_operand 1 "" "fg,fg"))
3681 (clobber (match_scratch:SI 2 "=l,l"))]
3682 ""
3683 "@
3684 {brl|blrl}\;{l|lwz} 2,20(1)
3685 bl %z0\;%."
3686 [(set_attr "length" "8")])
3687
3688(define_insn ""
3689 [(set (match_operand 0 "" "=fg")
3690 (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s"))
3691 (match_operand 2 "" "g")))
3692 (clobber (match_scratch:SI 3 "=l"))]
3693 ""
3694 "bl %z1")
3695
3696(define_insn ""
3697 [(set (match_operand 0 "" "=fg,fg")
3698 (call (mem:SI (match_operand:SI 1 "call_operand" "l,s"))
3699 (match_operand 2 "" "fg,fg")))
3700 (clobber (match_scratch:SI 3 "=l,l"))]
3701 ""
3702 "@
3703 {brl|blrl}\;{l|lwz} 2,20(1)
3704 bl %z1\;%."
3705 [(set_attr "length" "8")])
3706
3707;; Call subroutine returning any type.
3708
3709(define_expand "untyped_call"
3710 [(parallel [(call (match_operand 0 "" "")
3711 (const_int 0))
3712 (match_operand 1 "" "")
3713 (match_operand 2 "" "")])]
3714 ""
3715 "
3716{
3717 int i;
3718
3719 emit_call_insn (gen_call (operands[0], const0_rtx, NULL, const0_rtx));
3720
3721 for (i = 0; i < XVECLEN (operands[2], 0); i++)
3722 {
3723 rtx set = XVECEXP (operands[2], 0, i);
3724 emit_move_insn (SET_DEST (set), SET_SRC (set));
3725 }
3726
3727 /* The optimizer does not know that the call sets the function value
3728 registers we stored in the result block. We avoid problems by
3729 claiming that all hard registers are used and clobbered at this
3730 point. */
3731 emit_insn (gen_blockage ());
3732
3733 DONE;
3734}")
3735
3736;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
3737;; all of memory. This blocks insns from being moved across this point.
3738
3739(define_insn "blockage"
3740 [(unspec_volatile [(const_int 0)] 0)]
3741 ""
3742 "")
3743\f
3744;; Compare insns are next. Note that the RS/6000 has two types of compares,
3745;; signed & unsigned, and one type of branch.
3746;;
3747;; Start with the DEFINE_EXPANDs to generate the rtl for compares, scc
3748;; insns, and branches. We store the operands of compares until we see
3749;; how it is used.
3750(define_expand "cmpsi"
3751 [(set (cc0)
3752 (compare (match_operand:SI 0 "gpc_reg_operand" "")
3753 (match_operand:SI 1 "reg_or_short_operand" "")))]
3754 ""
3755 "
3756{
3757 /* Take care of the possibility that operands[1] might be negative but
3758 this might be a logical operation. That insn doesn't exist. */
3759 if (GET_CODE (operands[1]) == CONST_INT
3760 && INTVAL (operands[1]) < 0)
3761 operands[1] = force_reg (SImode, operands[1]);
3762
3763 rs6000_compare_op0 = operands[0];
3764 rs6000_compare_op1 = operands[1];
3765 rs6000_compare_fp_p = 0;
3766 DONE;
3767}")
3768
3769(define_expand "cmpsf"
3770 [(set (cc0) (compare (match_operand:SF 0 "gpc_reg_operand" "")
3771 (match_operand:SF 1 "gpc_reg_operand" "")))]
3772 ""
3773 "
3774{
3775 rs6000_compare_op0 = operands[0];
3776 rs6000_compare_op1 = operands[1];
3777 rs6000_compare_fp_p = 1;
3778 DONE;
3779}")
3780
3781(define_expand "cmpdf"
3782 [(set (cc0) (compare (match_operand:DF 0 "gpc_reg_operand" "")
3783 (match_operand:DF 1 "gpc_reg_operand" "")))]
3784 ""
3785 "
3786{
3787 rs6000_compare_op0 = operands[0];
3788 rs6000_compare_op1 = operands[1];
3789 rs6000_compare_fp_p = 1;
3790 DONE;
3791}")
3792
3793(define_expand "beq"
3794 [(set (match_dup 2) (match_dup 1))
3795 (set (pc)
3796 (if_then_else (eq (match_dup 2)
3797 (const_int 0))
3798 (label_ref (match_operand 0 "" ""))
3799 (pc)))]
3800 ""
3801 "
3802{ enum machine_mode mode = rs6000_compare_fp_p ? CCFPmode : CCmode;
3803 operands[1] = gen_rtx (COMPARE, mode,
3804 rs6000_compare_op0, rs6000_compare_op1);
3805 operands[2] = gen_reg_rtx (mode);
3806}")
3807
3808(define_expand "bne"
3809 [(set (match_dup 2) (match_dup 1))
3810 (set (pc)
3811 (if_then_else (ne (match_dup 2)
3812 (const_int 0))
3813 (label_ref (match_operand 0 "" ""))
3814 (pc)))]
3815 ""
3816 "
3817{ enum machine_mode mode = rs6000_compare_fp_p ? CCFPmode : CCmode;
3818 operands[1] = gen_rtx (COMPARE, mode,
3819 rs6000_compare_op0, rs6000_compare_op1);
3820 operands[2] = gen_reg_rtx (mode);
3821}")
3822
3823(define_expand "blt"
3824 [(set (match_dup 2) (match_dup 1))
3825 (set (pc)
3826 (if_then_else (lt (match_dup 2)
3827 (const_int 0))
3828 (label_ref (match_operand 0 "" ""))
3829 (pc)))]
3830 ""
3831 "
3832{ enum machine_mode mode = rs6000_compare_fp_p ? CCFPmode : CCmode;
3833 operands[1] = gen_rtx (COMPARE, mode,
3834 rs6000_compare_op0, rs6000_compare_op1);
3835 operands[2] = gen_reg_rtx (mode);
3836}")
3837
3838(define_expand "bgt"
3839 [(set (match_dup 2) (match_dup 1))
3840 (set (pc)
3841 (if_then_else (gt (match_dup 2)
3842 (const_int 0))
3843 (label_ref (match_operand 0 "" ""))
3844 (pc)))]
3845 ""
3846 "
3847{ enum machine_mode mode = rs6000_compare_fp_p ? CCFPmode : CCmode;
3848 operands[1] = gen_rtx (COMPARE, mode,
3849 rs6000_compare_op0, rs6000_compare_op1);
3850 operands[2] = gen_reg_rtx (mode);
3851}")
3852
3853(define_expand "ble"
3854 [(set (match_dup 2) (match_dup 1))
3855 (set (pc)
3856 (if_then_else (le (match_dup 2)
3857 (const_int 0))
3858 (label_ref (match_operand 0 "" ""))
3859 (pc)))]
3860 ""
3861 "
3862{ enum machine_mode mode = rs6000_compare_fp_p ? CCFPmode : CCmode;
3863 operands[1] = gen_rtx (COMPARE, mode,
3864 rs6000_compare_op0, rs6000_compare_op1);
3865 operands[2] = gen_reg_rtx (mode);
3866}")
3867
3868(define_expand "bge"
3869 [(set (match_dup 2) (match_dup 1))
3870 (set (pc)
3871 (if_then_else (ge (match_dup 2)
3872 (const_int 0))
3873 (label_ref (match_operand 0 "" ""))
3874 (pc)))]
3875 ""
3876 "
3877{ enum machine_mode mode = rs6000_compare_fp_p ? CCFPmode : CCmode;
3878 operands[1] = gen_rtx (COMPARE, mode,
3879 rs6000_compare_op0, rs6000_compare_op1);
3880 operands[2] = gen_reg_rtx (mode);
3881}")
3882
3883(define_expand "bgtu"
3884 [(set (match_dup 2) (match_dup 1))
3885 (set (pc)
3886 (if_then_else (gtu (match_dup 2)
3887 (const_int 0))
3888 (label_ref (match_operand 0 "" ""))
3889 (pc)))]
3890 ""
3891 "
3892{ operands[1] = gen_rtx (COMPARE, CCUNSmode,
3893 rs6000_compare_op0, rs6000_compare_op1);
3894 operands[2] = gen_reg_rtx (CCUNSmode);
3895}")
3896
3897(define_expand "bltu"
3898 [(set (match_dup 2) (match_dup 1))
3899 (set (pc)
3900 (if_then_else (ltu (match_dup 2)
3901 (const_int 0))
3902 (label_ref (match_operand 0 "" ""))
3903 (pc)))]
3904 ""
3905 "
3906{ operands[1] = gen_rtx (COMPARE, CCUNSmode,
3907 rs6000_compare_op0, rs6000_compare_op1);
3908 operands[2] = gen_reg_rtx (CCUNSmode);
3909}")
3910
3911(define_expand "bgeu"
3912 [(set (match_dup 2) (match_dup 1))
3913 (set (pc)
3914 (if_then_else (geu (match_dup 2)
3915 (const_int 0))
3916 (label_ref (match_operand 0 "" ""))
3917 (pc)))]
3918 ""
3919 "
3920{ operands[1] = gen_rtx (COMPARE, CCUNSmode,
3921 rs6000_compare_op0, rs6000_compare_op1);
3922 operands[2] = gen_reg_rtx (CCUNSmode);
3923}")
3924
3925(define_expand "bleu"
3926 [(set (match_dup 2) (match_dup 1))
3927 (set (pc)
3928 (if_then_else (leu (match_dup 2)
3929 (const_int 0))
3930 (label_ref (match_operand 0 "" ""))
3931 (pc)))]
3932 ""
3933 "
3934{ operands[1] = gen_rtx (COMPARE, CCUNSmode,
3935 rs6000_compare_op0, rs6000_compare_op1);
3936 operands[2] = gen_reg_rtx (CCUNSmode);
3937}")
3938
3939;; For SNE, we would prefer that the xor/abs sequence be used for integers.
3940;; For SEQ, likewise, except that comparisons with zero should be done
3941;; with an scc insns. However, due to the order that combine see the
3942;; resulting insns, we must, in fact, allow SEQ for integers. Fail in
3943;; the cases we don't want to handle.
3944(define_expand "seq"
3945 [(set (match_dup 2) (match_dup 1))
3946 (set (match_operand:SI 0 "gpc_reg_operand" "")
3947 (eq:SI (match_dup 2) (const_int 0)))]
3948 ""
3949 "
3950{ enum machine_mode mode = rs6000_compare_fp_p ? CCFPmode : CCmode;
3951 operands[1] = gen_rtx (COMPARE, mode,
3952 rs6000_compare_op0, rs6000_compare_op1);
3953 operands[2] = gen_reg_rtx (mode);
3954}")
3955
3956(define_expand "sne"
3957 [(set (match_dup 2) (match_dup 1))
3958 (set (match_operand:SI 0 "gpc_reg_operand" "")
3959 (ne:SI (match_dup 2) (const_int 0)))]
3960 ""
3961 "
3962{ if (! rs6000_compare_fp_p)
3963 FAIL;
3964
3965 operands[1] = gen_rtx (COMPARE, CCFPmode,
3966 rs6000_compare_op0, rs6000_compare_op1);
3967 operands[2] = gen_reg_rtx (CCFPmode);
3968}")
3969
3970;; A > 0 is best done using the portable sequence, so fail in that case.
3971(define_expand "sgt"
3972 [(set (match_dup 2) (match_dup 1))
3973 (set (match_operand:SI 0 "gpc_reg_operand" "")
3974 (gt:SI (match_dup 2) (const_int 0)))]
3975 ""
3976 "
3977{ enum machine_mode mode = rs6000_compare_fp_p ? CCFPmode : CCmode;
3978
3979 if (! rs6000_compare_fp_p && rs6000_compare_op1 == const0_rtx)
3980 FAIL;
3981
3982 operands[1] = gen_rtx (COMPARE, mode,
3983 rs6000_compare_op0, rs6000_compare_op1);
3984 operands[2] = gen_reg_rtx (mode);
3985}")
3986
3987;; A < 0 is best done in the portable way for A an integer.
3988(define_expand "slt"
3989 [(set (match_dup 2) (match_dup 1))
3990 (set (match_operand:SI 0 "gpc_reg_operand" "")
3991 (lt:SI (match_dup 2) (const_int 0)))]
3992 ""
3993 "
3994{ enum machine_mode mode = rs6000_compare_fp_p ? CCFPmode : CCmode;
3995
3996 if (! rs6000_compare_fp_p && rs6000_compare_op1 == const0_rtx)
3997 FAIL;
3998
3999 operands[1] = gen_rtx (COMPARE, mode,
4000 rs6000_compare_op0, rs6000_compare_op1);
4001 operands[2] = gen_reg_rtx (mode);
4002}")
4003
4004(define_expand "sge"
4005 [(set (match_dup 2) (match_dup 1))
4006 (set (match_operand:SI 0 "gpc_reg_operand" "")
4007 (ge:SI (match_dup 2) (const_int 0)))]
4008 ""
4009 "
4010{ enum machine_mode mode = rs6000_compare_fp_p ? CCFPmode : CCmode;
4011 operands[1] = gen_rtx (COMPARE, mode,
4012 rs6000_compare_op0, rs6000_compare_op1);
4013 operands[2] = gen_reg_rtx (mode);
4014}")
4015
4016;; A <= 0 is best done the portable way for A an integer.
4017(define_expand "sle"
4018 [(set (match_dup 2) (match_dup 1))
4019 (set (match_operand:SI 0 "gpc_reg_operand" "")
4020 (le:SI (match_dup 2) (const_int 0)))]
4021 ""
4022 "
4023{ enum machine_mode mode = rs6000_compare_fp_p ? CCFPmode : CCmode;
4024
4025 if (! rs6000_compare_fp_p && rs6000_compare_op1 == const0_rtx)
4026 FAIL;
4027
4028 operands[1] = gen_rtx (COMPARE, mode,
4029 rs6000_compare_op0, rs6000_compare_op1);
4030 operands[2] = gen_reg_rtx (mode);
4031}")
4032
4033(define_expand "sgtu"
4034 [(set (match_dup 2) (match_dup 1))
4035 (set (match_operand:SI 0 "gpc_reg_operand" "")
4036 (gtu:SI (match_dup 2) (const_int 0)))]
4037 ""
4038 "
4039{ operands[1] = gen_rtx (COMPARE, CCUNSmode,
4040 rs6000_compare_op0, rs6000_compare_op1);
4041 operands[2] = gen_reg_rtx (CCUNSmode);
4042}")
4043
4044(define_expand "sltu"
4045 [(set (match_dup 2) (match_dup 1))
4046 (set (match_operand:SI 0 "gpc_reg_operand" "")
4047 (ltu:SI (match_dup 2) (const_int 0)))]
4048 ""
4049 "
4050{ operands[1] = gen_rtx (COMPARE, CCUNSmode,
4051 rs6000_compare_op0, rs6000_compare_op1);
4052 operands[2] = gen_reg_rtx (CCUNSmode);
4053}")
4054
4055(define_expand "sgeu"
4056 [(set (match_dup 2) (match_dup 1))
4057 (set (match_operand:SI 0 "gpc_reg_operand" "")
4058 (geu:SI (match_dup 2) (const_int 0)))]
4059 ""
4060 "
4061{ operands[1] = gen_rtx (COMPARE, CCUNSmode,
4062 rs6000_compare_op0, rs6000_compare_op1);
4063 operands[2] = gen_reg_rtx (CCUNSmode);
4064}")
4065
4066(define_expand "sleu"
4067 [(set (match_dup 2) (match_dup 1))
4068 (set (match_operand:SI 0 "gpc_reg_operand" "")
4069 (leu:SI (match_dup 2) (const_int 0)))]
4070 ""
4071 "
4072{ operands[1] = gen_rtx (COMPARE, CCUNSmode,
4073 rs6000_compare_op0, rs6000_compare_op1);
4074 operands[2] = gen_reg_rtx (CCUNSmode);
4075}")
4076\f
4077;; Here are the actual compare insns.
4078(define_insn ""
4079 [(set (match_operand:CC 0 "cc_reg_operand" "=y")
4080 (compare:CC (match_operand:SI 1 "gpc_reg_operand" "r")
4081 (match_operand:SI 2 "reg_or_short_operand" "rI")))]
4082 ""
4083 "cmp%I2 %0,%1,%2"
4084 [(set_attr "type" "compare")])
4085
4086;; If we are comparing a register for equality with a large constant,
4087;; we can do this with an XOR followed by a compare. But we need a scratch
4088;; register for the result of the XOR.
4089
4090(define_split
4091 [(set (match_operand:CC 0 "cc_reg_operand" "")
4092 (compare:CC (match_operand:SI 1 "gpc_reg_operand" "")
4093 (match_operand:SI 2 "non_short_cint_operand" "")))
4094 (clobber (match_operand:SI 3 "gpc_reg_operand" ""))]
4095 "find_single_use (operands[0], insn, 0)
4096 && (GET_CODE (*find_single_use (operands[0], insn, 0)) == EQ
4097 || GET_CODE (*find_single_use (operands[0], insn, 0)) == NE)"
4098 [(set (match_dup 3) (xor:SI (match_dup 1) (match_dup 4)))
4099 (set (match_dup 0) (compare:CC (match_dup 3) (match_dup 5)))]
4100 "
4101{
4102 /* Get the constant we are comparing against, C, and see what it looks like
4103 sign-extended to 16 bits. Then see what constant could be XOR'ed
4104 with C to get the sign-extended value. */
4105
4106 int c = INTVAL (operands[2]);
4107 int sextc = (c << 16) >> 16;
4108 int xorv = c ^ sextc;
4109
4110 operands[4] = gen_rtx (CONST_INT, VOIDmode, xorv);
4111 operands[5] = gen_rtx (CONST_INT, VOIDmode, sextc);
4112}")
4113
4114(define_insn ""
4115 [(set (match_operand:CCUNS 0 "cc_reg_operand" "=y")
4116 (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "r")
4117 (match_operand:SI 2 "reg_or_u_short_operand" "rI")))]
4118 ""
4119 "cmpl%I2 %0,%1,%W2"
4120 [(set_attr "type" "compare")])
4121
4122;; The following two insns don't exist as single insns, but if we provide
4123;; them, we can swap an add and compare, which will enable us to overlap more
4124;; of the required delay between a compare and branch. We generate code for
4125;; them by splitting.
4126
4127(define_insn ""
4128 [(set (match_operand:CC 3 "cc_reg_operand" "=y")
4129 (compare:CC (match_operand:SI 1 "gpc_reg_operand" "r")
4130 (match_operand:SI 2 "short_cint_operand" "i")))
4131 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
4132 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "i")))]
4133 ""
4134 "#"
4135 [(set_attr "length" "8")])
4136
4137(define_insn ""
4138 [(set (match_operand:CCUNS 3 "cc_reg_operand" "=y")
4139 (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "r")
4140 (match_operand:SI 2 "u_short_cint_operand" "i")))
4141 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
4142 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "i")))]
4143 ""
4144 "#"
4145 [(set_attr "length" "8")])
4146
4147(define_split
4148 [(set (match_operand:CC 3 "cc_reg_operand" "")
4149 (compare:CC (match_operand:SI 1 "gpc_reg_operand" "")
4150 (match_operand:SI 2 "short_cint_operand" "")))
4151 (set (match_operand:SI 0 "gpc_reg_operand" "")
4152 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "")))]
4153 ""
4154 [(set (match_dup 3) (compare:CC (match_dup 1) (match_dup 2)))
4155 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 4)))])
4156
4157(define_split
4158 [(set (match_operand:CCUNS 3 "cc_reg_operand" "")
4159 (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "")
4160 (match_operand:SI 2 "u_short_cint_operand" "")))
4161 (set (match_operand:SI 0 "gpc_reg_operand" "")
4162 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "")))]
4163 ""
4164 [(set (match_dup 3) (compare:CCUNS (match_dup 1) (match_dup 2)))
4165 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 4)))])
4166
4167(define_insn ""
4168 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
4169 (compare:CCFP (match_operand:SF 1 "gpc_reg_operand" "f")
4170 (match_operand:SF 2 "gpc_reg_operand" "f")))]
4171 ""
4172 "fcmpu %0,%1,%2"
4173 [(set_attr "type" "fpcompare")])
4174
4175(define_insn ""
4176 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
4177 (compare:CCFP (match_operand:DF 1 "gpc_reg_operand" "f")
4178 (match_operand:DF 2 "gpc_reg_operand" "f")))]
4179 ""
4180 "fcmpu %0,%1,%2"
4181 [(set_attr "type" "fpcompare")])
4182\f
4183;; Now we have the scc insns. We can do some combinations because of the
4184;; way the machine works.
4185;;
4186;; Note that this is probably faster if we can put an insn between the
4187;; mfcr and rlinm, but this is tricky. Let's leave it for now. In most
4188;; cases the insns below which don't use an intermediate CR field will
4189;; be used instead.
4190(define_insn ""
4191 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
4192 (match_operator:SI 1 "scc_comparison_operator"
4193 [(match_operand 2 "cc_reg_operand" "y")
4194 (const_int 0)]))]
4195 ""
4196 "%D1mfcr %0\;{rlinm|rlwinm} %0,%0,%J1,1"
4197 [(set_attr "length" "12")])
4198
4199(define_insn ""
4200 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
4201 (compare:CC (match_operator:SI 1 "scc_comparison_operator"
4202 [(match_operand 2 "cc_reg_operand" "y")
4203 (const_int 0)])
4204 (const_int 0)))
4205 (set (match_operand:SI 3 "gpc_reg_operand" "=r")
4206 (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
4207 ""
4208 "%D1mfcr %3\;{rlinm.|rlwinm.} %3,%3,%J1,1"
4209 [(set_attr "type" "delayed_compare")
4210 (set_attr "length" "12")])
4211
4212(define_insn ""
4213 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
4214 (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
4215 [(match_operand 2 "cc_reg_operand" "y")
4216 (const_int 0)])
4217 (match_operand:SI 3 "const_int_operand" "n")))]
4218 ""
4219 "*
4220{
4221 int is_bit = ccr_bit (operands[1], 1);
4222 int put_bit = 31 - (INTVAL (operands[3]) & 31);
4223 int count;
4224
4225 if (is_bit >= put_bit)
4226 count = is_bit - put_bit;
4227 else
4228 count = 32 - (put_bit - is_bit);
4229
4230 operands[4] = gen_rtx (CONST_INT, VOIDmode, count);
4231 operands[5] = gen_rtx (CONST_INT, VOIDmode, put_bit);
4232
4233 return \"%D1mfcr %0\;{rlinm|rlwinm} %0,%0,%4,%5,%5\";
4234}"
4235 [(set_attr "length" "12")])
4236
4237(define_insn ""
4238 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
4239 (compare:CC
4240 (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
4241 [(match_operand 2 "cc_reg_operand" "y")
4242 (const_int 0)])
4243 (match_operand:SI 3 "const_int_operand" "n"))
4244 (const_int 0)))
4245 (set (match_operand:SI 4 "gpc_reg_operand" "=r")
4246 (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
4247 (match_dup 3)))]
4248 ""
4249 "*
4250{
4251 int is_bit = ccr_bit (operands[1], 1);
4252 int put_bit = 31 - (INTVAL (operands[3]) & 31);
4253 int count;
4254
4255 if (is_bit >= put_bit)
4256 count = is_bit - put_bit;
4257 else
4258 count = 32 - (put_bit - is_bit);
4259
4260 operands[5] = gen_rtx (CONST_INT, VOIDmode, count);
4261 operands[6] = gen_rtx (CONST_INT, VOIDmode, put_bit);
4262
4263 return \"%D1mfcr %4\;{rlinm.|rlwinm.} %4,%4,%5,%6,%6\";
4264}"
4265 [(set_attr "type" "delayed_compare")
4266 (set_attr "length" "12")])
4267
4268;; If we are comparing the result of two comparisons, this can be done
4269;; using creqv or crxor.
4270
4271(define_insn ""
4272 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y")
4273 (compare:CCEQ (match_operator 1 "scc_comparison_operator"
4274 [(match_operand 2 "cc_reg_operand" "y")
4275 (const_int 0)])
4276 (match_operator 3 "scc_comparison_operator"
4277 [(match_operand 4 "cc_reg_operand" "y")
4278 (const_int 0)])))]
4279 "REGNO (operands[2]) != REGNO (operands[4])"
4280 "*
4281{
4282 enum rtx_code code1, code2;
4283
4284 code1 = GET_CODE (operands[1]);
4285 code2 = GET_CODE (operands[3]);
4286
4287 if ((code1 == EQ || code1 == LT || code1 == GT
4288 || code1 == LTU || code1 == GTU
4289 || (code1 != NE && GET_MODE (operands[2]) == CCFPmode))
4290 !=
4291 (code2 == EQ || code2 == LT || code2 == GT
4292 || code2 == LTU || code2 == GTU
4293 || (code2 != NE && GET_MODE (operands[4]) == CCFPmode)))
4294 return \"%C1%C3crxor %E0,%j1,%j3\";
4295 else
4296 return \"%C1%C3creqv %E0,%j1,%j3\";
4297}"
4298 [(set_attr "length" "12")])
4299
4300;; There is a 3 cycle delay between consecutive mfcr instructions
4301;; so it is useful to combine 2 scc instructions to use only one mfcr.
4302
4303(define_peephole
4304 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
4305 (match_operator:SI 1 "scc_comparison_operator"
4306 [(match_operand 2 "cc_reg_operand" "y")
4307 (const_int 0)]))
4308 (set (match_operand:SI 3 "gpc_reg_operand" "=r")
4309 (match_operator:SI 4 "scc_comparison_operator"
4310 [(match_operand 5 "cc_reg_operand" "y")
4311 (const_int 0)]))]
4312 "REGNO (operands[2]) != REGNO (operands[5])"
4313 "%D1%D4mfcr %3\;{rlinm|rlwinm} %0,%3,%J1,1\;{rlinm|rlwinm} %3,%3,%J4,1"
4314 [(set_attr "length" "20")])
4315
4316;; There are some scc insns that can be done directly, without a compare.
4317;; These are faster because they don't involve the communications between
4318;; the FXU and branch units. In fact, we will be replacing all of the
4319;; integer scc insns here or in the portable methods in emit_store_flag.
4320;;
4321;; Also support (neg (scc ..)) since that construct is used to replace
4322;; branches, (plus (scc ..) ..) since that construct is common and
4323;; takes no more insns than scc, and (and (neg (scc ..)) ..) in the
4324;; cases where it is no more expensive than (neg (scc ..)).
4325
4326;; Have reload force a constant into a register for the simple insns that
4327;; otherwise won't accept constants. We do this because it is faster than
4328;; the cmp/mfcr sequence we would otherwise generate.
4329
4330(define_insn ""
4331 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r,r")
4332 (eq:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r")
4333 (match_operand:SI 2 "reg_or_cint_operand" "r,O,K,J,I")))
4334 (clobber (match_scratch:SI 3 "=r,&r,r,r,r"))]
4335 ""
4336 "@
4337 xor %0,%1,%2\;{sfi|subfic} %3,%0,0\;{ae|adde} %0,%3,%0
4338 {sfi|subfic} %3,%1,0\;{ae|adde} %0,%3,%1
4339 {xoril|xori} %0,%1,%b2\;{sfi|subfic} %3,%0,0\;{ae|adde} %0,%3,%0
4340 {xoriu|xoris} %0,%1,%u2\;{sfi|subfic} %3,%0,0\;{ae|adde} %0,%3,%0
4341 {sfi|subfic} %0,%1,%2\;{sfi|subfic} %3,%0,0\;{ae|adde} %0,%3,%0"
4342 [(set_attr "length" "12,8,12,12,12")])
4343
4344(define_insn ""
4345 [(set (match_operand:CC 4 "cc_reg_operand" "=x,x,x,x,x")
4346 (compare:CC
4347 (eq:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r")
4348 (match_operand:SI 2 "reg_or_cint_operand" "r,O,K,J,I"))
4349 (const_int 0)))
4350 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r,r")
4351 (eq:SI (match_dup 1) (match_dup 2)))
4352 (clobber (match_scratch:SI 3 "=r,&r,r,r,r"))]
4353 ""
4354 "@
4355 xor %0,%1,%2\;{sfi|subfic} %3,%0,0\;{ae.|adde.} %0,%3,%0
4356 {sfi|subfic} %3,%1,0\;{ae.|adde.} %0,%3,%1
4357 {xoril|xori} %0,%1,%b2\;{sfi|subfic} %3,%0,0\;{ae.|adde.} %0,%3,%0
4358 {xoriu|xoris} %0,%1,%u2\;{sfi|subfic} %3,%0,0\;{ae.|adde.} %0,%3,%0
4359 {sfi|subfic} %0,%1,%2\;{sfi|subfic} %3,%0,0\;{ae.|adde.} %0,%3,%0"
4360 [(set_attr "type" "compare")
4361 (set_attr "length" "12,8,12,12,12")])
4362
4363;; We have insns of the form shown by the first define_insn below. If
4364;; there is something inside the comparison operation, we must split it.
4365(define_split
4366 [(set (match_operand:SI 0 "gpc_reg_operand" "")
4367 (plus:SI (match_operator 1 "comparison_operator"
4368 [(match_operand:SI 2 "" "")
4369 (match_operand:SI 3
4370 "reg_or_cint_operand" "")])
4371 (match_operand:SI 4 "gpc_reg_operand" "")))
4372 (clobber (match_operand:SI 5 "register_operand" ""))]
4373 "! gpc_reg_operand (operands[2], SImode)"
4374 [(set (match_dup 5) (match_dup 2))
4375 (set (match_dup 2) (plus:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
4376 (match_dup 4)))])
4377
4378(define_insn ""
4379 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r,r")
4380 (plus:SI (eq:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r")
4381 (match_operand:SI 2 "reg_or_cint_operand" "r,O,K,J,I"))
4382 (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r,r")))
4383 (clobber (match_scratch:SI 4 "=&r,&r,&r,&r,&r"))]
4384 ""
4385 "@
4386 xor %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze|addze} %0,%3
4387 {sfi|subfic} %4,%1,0\;{aze|addze} %0,%3
4388 {xoril|xori} %4,%1,%b2\;{sfi|subfic} %4,%4,0\;{aze|addze} %0,%3
4389 {xoriu|xoris} %4,%1,%u2\;{sfi|subfic} %4,%4,0\;{aze|addze} %0,%3
4390 {sfi|subfic} %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze|adddze} %0,%3"
4391 [(set_attr "length" "12,8,12,12,12")])
4392
4393(define_insn ""
4394 [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,x,x,x")
4395 (compare:CC
4396 (plus:SI
4397 (eq:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r")
4398 (match_operand:SI 2 "reg_or_cint_operand" "r,O,K,J,I"))
4399 (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r,r"))
4400 (const_int 0)))
4401 (clobber (match_scratch:SI 4 "=&r,&r,&r,&r,&r"))]
4402 ""
4403 "@
4404 xor %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %4,%3
4405 {sfi|subfic} %4,%1,0\;{aze.|addze.} %0,%3
4406 {xoril|xori} %4,%1,%b2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %4,%3
4407 {xoriu|xoris} %4,%1,%u2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %4,%3
4408 {sfi|subfic} %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %4,%3"
4409 [(set_attr "type" "compare")
4410 (set_attr "length" "12,8,12,12,12")])
4411
4412(define_insn ""
4413 [(set (match_operand:CC 5 "cc_reg_operand" "=x,x,x,x,x")
4414 (compare:CC
4415 (plus:SI
4416 (eq:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r")
4417 (match_operand:SI 2 "reg_or_cint_operand" "r,O,K,J,I"))
4418 (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r,r"))
4419 (const_int 0)))
4420 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r,r")
4421 (plus:SI (eq:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
4422 (clobber (match_scratch:SI 4 "=&r,&r,&r,&r,&r"))]
4423 ""
4424 "@
4425 xor %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %0,%3
4426 {sfi|subfic} %4,%1,0\;{aze.|addze.} %4,%3
4427 {xoril|xori} %4,%1,%b2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %0,%3
4428 {xoriu|xoris} %4,%1,%u2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %0,%3
4429 {sfi|subfic} %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %0,%3"
4430 [(set_attr "type" "compare")
4431 (set_attr "length" "12,8,12,12,12")])
4432
4433(define_insn ""
4434 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r,r")
4435 (neg:SI (eq:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r,r")
4436 (match_operand:SI 2 "reg_or_cint_operand" "r,O,K,J,I"))))]
4437 ""
4438 "@
4439 xor %0,%1,%2\;{ai|addic} %0,%0,-1\;{sfe|subfe} %0,%0,%0
4440 {ai|addic} %0,%1,-1\;{sfe|subfe} %0,%0,%0
4441 {xoril|xori} %0,%1,%b2\;{ai|addic} %0,%0,-1\;{sfe|subfe} %0,%0,%0
4442 {xoriu|xoris} %0,%1,%u2\;{ai|addic} %0,%0,-1\;{sfe|subfe} %0,%0,%0
4443 {sfi|subfic} %0,%1,%2\;{ai|addic} %0,%0,-1\;{sfe|subfe} %0,%0,%0"
4444 [(set_attr "length" "12,8,12,12,12")])
4445
4446;; This is what (plus (ne X (const_int 0)) Y) looks like.
4447(define_insn ""
4448 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
4449 (plus:SI (lshiftrt:SI
4450 (neg:SI (abs:SI (match_operand:SI 1 "gpc_reg_operand" "r")))
4451 (const_int 31))
4452 (match_operand:SI 2 "gpc_reg_operand" "r")))
4453 (clobber (match_scratch:SI 3 "=&r"))]
4454 ""
4455 "{ai|addic} %3,%1,-1\;{aze|addze} %0,%2"
4456 [(set_attr "length" "8")])
4457
4458(define_insn ""
4459 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
4460 (compare:CC
4461 (plus:SI (lshiftrt:SI
4462 (neg:SI (abs:SI (match_operand:SI 1 "gpc_reg_operand" "r")))
4463 (const_int 31))
4464 (match_operand:SI 2 "gpc_reg_operand" "r"))
4465 (const_int 0)))
4466 (clobber (match_scratch:SI 3 "=&r"))]
4467 ""
4468 "{ai|addic} %3,%1,-1\;{aze.|addze.} %3,%2"
4469 [(set_attr "type" "compare")
4470 (set_attr "length" "8")])
4471
4472(define_insn ""
4473 [(set (match_operand:CC 4 "cc_reg_operand" "=x")
4474 (compare:CC
4475 (plus:SI (lshiftrt:SI
4476 (neg:SI (abs:SI (match_operand:SI 1 "gpc_reg_operand" "r")))
4477 (const_int 31))
4478 (match_operand:SI 2 "gpc_reg_operand" "r"))
4479 (const_int 0)))
4480 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
4481 (plus:SI (lshiftrt:SI (neg:SI (abs:SI (match_dup 1))) (const_int 31))
4482 (match_dup 2)))
4483 (clobber (match_scratch:SI 3 "=&r"))]
4484 ""
4485 "{ai|addic} %3,%1,-1\;{aze.|addze.} %0,%2"
4486 [(set_attr "type" "compare")
4487 (set_attr "length" "8")])
4488
4489(define_insn ""
4490 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
4491 (le:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
4492 (match_operand:SI 2 "reg_or_short_operand" "r,O")))
4493 (clobber (match_scratch:SI 3 "=r,X"))]
4494 "TARGET_POWER"
4495 "@
4496 doz %3,%2,%1\;{sfi|subfic} %0,%3,0\;{ae|adde} %0,%0,%3
4497 {ai|addic} %0,%1,-1\;{aze|addze} %0,%0\;sri %0,%0,31"
4498 [(set_attr "length" "12")])
4499
4500(define_insn ""
4501 [(set (match_operand:CC 4 "cc_reg_operand" "=x,x")
4502 (compare:CC
4503 (le:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
4504 (match_operand:SI 2 "reg_or_short_operand" "r,O"))
4505 (const_int 0)))
4506 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
4507 (le:SI (match_dup 1) (match_dup 2)))
4508 (clobber (match_scratch:SI 3 "=r,X"))]
4509 "TARGET_POWER"
4510 "@
4511 doz %3,%2,%1\;{sfi|subfic} %0,%3,0\;{ae.|adde.} %0,%0,%3
4512 {ai|addic} %0,%1,-1\;{aze|addze} %0,%0\;sri. %0,%0,31"
4513 [(set_attr "type" "delayed_compare,compare")
4514 (set_attr "length" "12")])
4515
4516(define_insn ""
4517 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
4518 (plus:SI (le:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
4519 (match_operand:SI 2 "reg_or_short_operand" "r,O"))
4520 (match_operand:SI 3 "gpc_reg_operand" "r,r")))
4521 (clobber (match_scratch:SI 4 "=&r,&r"))]
4522 "TARGET_POWER"
4523 "@
4524 doz %4,%2,%1\;{sfi|subfic} %4,%4,0\;{aze|addze} %0,%3
4525 {srai|srawi} %4,%1,31\;{sf|subfc} %4,%1,%4\;{aze|addze} %0,%3"
4526 [(set_attr "length" "12")])
4527
4528(define_insn ""
4529 [(set (match_operand:CC 0 "cc_reg_operand" "=x,x")
4530 (compare:CC
4531 (plus:SI (le:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
4532 (match_operand:SI 2 "reg_or_short_operand" "r,O"))
4533 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
4534 (const_int 0)))
4535 (clobber (match_scratch:SI 4 "=&r,&r"))]
4536 "TARGET_POWER"
4537 "@
4538 doz %4,%2,%1\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %4,%3
4539 {srai|srawi} %4,%1,31\;{sf|subfc} %4,%1,%4\;{aze.|addze.} %4,%3"
4540 [(set_attr "type" "compare")
4541 (set_attr "length" "12")])
4542
4543(define_insn ""
4544 [(set (match_operand:CC 5 "cc_reg_operand" "=x,x")
4545 (compare:CC
4546 (plus:SI (le:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
4547 (match_operand:SI 2 "reg_or_short_operand" "r,O"))
4548 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
4549 (const_int 0)))
4550 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
4551 (plus:SI (le:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
4552 (clobber (match_scratch:SI 4 "=&r,&r"))]
4553 "TARGET_POWER"
4554 "@
4555 doz %4,%2,%1\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %0,%3
4556 {srai|srawi} %4,%1,31\;{sf|subfc} %4,%1,%4\;{aze.|addze.} %0,%3"
4557 [(set_attr "type" "compare")
4558 (set_attr "length" "12")])
4559
4560(define_insn ""
4561 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
4562 (neg:SI (le:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
4563 (match_operand:SI 2 "reg_or_short_operand" "r,O"))))]
4564 "TARGET_POWER"
4565 "@
4566 doz %0,%2,%1\;{ai|addic} %0,%0,-1\;{sfe|subfe} %0,%0,%0
4567 {ai|addic} %0,%1,-1\;{aze|addze} %0,%0\;{srai|srawi} %0,%0,31"
4568 [(set_attr "length" "12")])
4569
4570(define_insn ""
4571 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
4572 (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4573 (match_operand:SI 2 "reg_or_short_operand" "rI")))]
4574 ""
4575 "{sf%I2|subf%I2c} %0,%1,%2\;{cal %0,0(0)|li %0,0}\;{ae|adde} %0,%0,%0"
4576 [(set_attr "length" "12")])
4577
4578(define_insn ""
4579 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
4580 (compare:CC
4581 (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4582 (match_operand:SI 2 "reg_or_short_operand" "rI"))
4583 (const_int 0)))
4584 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
4585 (leu:SI (match_dup 1) (match_dup 2)))]
4586 ""
4587 "{sf%I2|subf%I2c} %0,%1,%2\;{cal %0,0(0)|li %0,0}\;{ae.|adde.} %0,%0,%0"
4588 [(set_attr "type" "compare")
4589 (set_attr "length" "12")])
4590
4591(define_insn ""
4592 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
4593 (plus:SI (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4594 (match_operand:SI 2 "reg_or_short_operand" "rI"))
4595 (match_operand:SI 3 "gpc_reg_operand" "r")))
4596 (clobber (match_scratch:SI 4 "=&r"))]
4597 ""
4598 "{sf%I2|subf%I2c} %4,%1,%2\;{aze|addze} %0,%3"
4599 [(set_attr "length" "8")])
4600
4601(define_insn ""
4602 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
4603 (compare:CC
4604 (plus:SI (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4605 (match_operand:SI 2 "reg_or_short_operand" "rI"))
4606 (match_operand:SI 3 "gpc_reg_operand" "r"))
4607 (const_int 0)))
4608 (clobber (match_scratch:SI 4 "=&r"))]
4609 ""
4610 "{sf%I2|subf%I2c} %4,%1,%2\;{aze.|addze.} %4,%3"
4611 [(set_attr "type" "compare")
4612 (set_attr "length" "8")])
4613
4614(define_insn ""
4615 [(set (match_operand:CC 5 "cc_reg_operand" "=x")
4616 (compare:CC
4617 (plus:SI (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4618 (match_operand:SI 2 "reg_or_short_operand" "rI"))
4619 (match_operand:SI 3 "gpc_reg_operand" "r"))
4620 (const_int 0)))
4621 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
4622 (plus:SI (leu:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
4623 (clobber (match_scratch:SI 4 "=&r"))]
4624 ""
4625 "{sf%I2|subf%I2c} %4,%1,%2\;{aze.|addze.} %0,%3"
4626 [(set_attr "type" "compare")
4627 (set_attr "length" "8")])
4628
4629(define_insn ""
4630 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
4631 (neg:SI (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4632 (match_operand:SI 2 "reg_or_short_operand" "rI"))))]
4633 ""
4634 "{sf%I2|subf%I2c} %0,%1,%2\;{sfe|subfe} %0,%0,%0\;nand %0,%0,%0"
4635 [(set_attr "length" "12")])
4636
4637(define_insn ""
4638 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
4639 (and:SI (neg:SI
4640 (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4641 (match_operand:SI 2 "reg_or_short_operand" "rI")))
4642 (match_operand:SI 3 "gpc_reg_operand" "r")))
4643 (clobber (match_scratch:SI 4 "=&r"))]
4644 ""
4645 "{sf%I2|subf%I2c} %4,%1,%2\;{sfe|subfe} %4,%4,%4\;andc %0,%3,%4"
4646 [(set_attr "length" "12")])
4647
4648(define_insn ""
4649 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
4650 (compare:CC
4651 (and:SI (neg:SI
4652 (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4653 (match_operand:SI 2 "reg_or_short_operand" "rI")))
4654 (match_operand:SI 3 "gpc_reg_operand" "r"))
4655 (const_int 0)))
4656 (clobber (match_scratch:SI 4 "=&r"))]
4657 ""
4658 "{sf%I2|subf%I2c} %4,%1,%2\;{sfe|subfe} %4,%4,%4\;andc. %4,%3,%4"
4659 [(set_attr "type" "compare")
4660 (set_attr "length" "12")])
4661
4662(define_insn ""
4663 [(set (match_operand:CC 5 "cc_reg_operand" "=x")
4664 (compare:CC
4665 (and:SI (neg:SI
4666 (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4667 (match_operand:SI 2 "reg_or_short_operand" "rI")))
4668 (match_operand:SI 3 "gpc_reg_operand" "r"))
4669 (const_int 0)))
4670 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
4671 (and:SI (neg:SI (leu:SI (match_dup 1) (match_dup 2))) (match_dup 3)))
4672 (clobber (match_scratch:SI 4 "=&r"))]
4673 ""
4674 "{sf%I2|subf%I2c} %4,%1,%2\;{sfe|subfe} %4,%4,%4\;andc. %0,%3,%4"
4675 [(set_attr "type" "compare")
4676 (set_attr "length" "12")])
4677
4678(define_insn ""
4679 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
4680 (lt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4681 (match_operand:SI 2 "reg_or_short_operand" "rI")))]
4682 "TARGET_POWER"
4683 "doz%I2 %0,%1,%2\;nabs %0,%0\;sri %0,%0,31"
4684 [(set_attr "length" "12")])
4685
4686(define_insn ""
4687 [(set (match_operand:SI 3 "cc_reg_operand" "=x")
4688 (compare:CC
4689 (lt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4690 (match_operand:SI 2 "reg_or_short_operand" "rI"))
4691 (const_int 0)))
4692 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
4693 (lt:SI (match_dup 1) (match_dup 2)))]
4694 "TARGET_POWER"
4695 "doz%I2 %0,%1,%2\;nabs %0,%0\;sri. %0,%0,31"
4696 [(set_attr "type" "delayed_compare")
4697 (set_attr "length" "12")])
4698
4699(define_insn ""
4700 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
4701 (plus:SI (lt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4702 (match_operand:SI 2 "reg_or_short_operand" "rI"))
4703 (match_operand:SI 3 "gpc_reg_operand" "r")))
4704 (clobber (match_scratch:SI 4 "=&r"))]
4705 "TARGET_POWER"
4706 "doz%I2 %4,%1,%2\;{ai|addic} %4,%4,-1\;{aze|addze} %0,%3"
4707 [(set_attr "length" "12")])
4708
4709(define_insn ""
4710 [(set (match_operand:SI 0 "cc_reg_operand" "=x")
4711 (compare:CC
4712 (plus:SI (lt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4713 (match_operand:SI 2 "reg_or_short_operand" "rI"))
4714 (match_operand:SI 3 "gpc_reg_operand" "r"))
4715 (const_int 0)))
4716 (clobber (match_scratch:SI 4 "=&r"))]
4717 "TARGET_POWER"
4718 "doz%I2 %4,%1,%2\;{ai|addic} %4,%4,-1\;{aze.|addze.} %4,%3"
4719 [(set_attr "type" "compare")
4720 (set_attr "length" "12")])
4721
4722(define_insn ""
4723 [(set (match_operand:SI 5 "cc_reg_operand" "=x")
4724 (compare:CC
4725 (plus:SI (lt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4726 (match_operand:SI 2 "reg_or_short_operand" "rI"))
4727 (match_operand:SI 3 "gpc_reg_operand" "r"))
4728 (const_int 0)))
4729 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
4730 (plus:SI (lt:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
4731 (clobber (match_scratch:SI 4 "=&r"))]
4732 "TARGET_POWER"
4733 "doz%I2 %4,%1,%2\;{ai|addic} %4,%4,-1\;{aze.|addze.} %0,%3"
4734 [(set_attr "type" "compare")
4735 (set_attr "length" "12")])
4736
4737(define_insn ""
4738 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
4739 (neg:SI (lt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4740 (match_operand:SI 2 "reg_or_short_operand" "rI"))))]
4741 "TARGET_POWER"
4742 "doz%I2 %0,%1,%2\;nabs %0,%0\;{srai|srawi} %0,%0,31"
4743 [(set_attr "length" "12")])
4744
4745(define_insn ""
4746 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
4747 (ltu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
4748 (match_operand:SI 2 "reg_or_neg_short_operand" "r,P")))]
4749 ""
4750 "@
4751 {sf|subfc} %0,%2,%1\;{sfe|subfe} %0,%0,%0\;neg %0,%0
4752 {ai|addic} %0,%1,%n2\;{sfe|subfe} %0,%0,%0\;neg %0,%0"
4753 [(set_attr "length" "12")])
4754
4755(define_insn ""
4756 [(set (match_operand:CC 3 "cc_reg_operand" "=x,x")
4757 (compare:CC
4758 (ltu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
4759 (match_operand:SI 2 "reg_or_neg_short_operand" "r,P"))
4760 (const_int 0)))
4761 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
4762 (ltu:SI (match_dup 1) (match_dup 2)))]
4763 ""
4764 "@
4765 {sf|subfc} %0,%2,%1\;{sfe|subfe} %0,%0,%0\;neg. %0,%0
4766 {ai|addic} %0,%1,%n2\;{sfe|subfe} %0,%0,%0\;neg. %0,%0"
4767 [(set_attr "type" "compare")
4768 (set_attr "length" "12")])
4769
4770(define_insn ""
4771 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r")
4772 (plus:SI (ltu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r")
4773 (match_operand:SI 2 "reg_or_neg_short_operand" "r,r,P,P"))
4774 (match_operand:SI 3 "reg_or_short_operand" "r,I,r,I")))
4775 (clobber (match_scratch:SI 4 "=&r,r,&r,r"))]
4776 ""
4777 "@
4778 {sf|subfc} %4,%2,%1\;{sfe|subfe} %4,%4,%4\;{sf%I3|subf%I3c} %0,%4,%3
4779 {sf|subfc} %4,%2,%1\;{sfe|subfe} %4,%4,%4\;{sf%I3|subf%I3c} %0,%4,%3
4780 {ai|addic} %4,%1,%n2\;{sfe|subfe} %4,%4,%4\;{sf%I3|subf%I3c} %0,%4,%3
4781 {ai|addic} %4,%1,%n2\;{sfe|subfe} %4,%4,%4\;{sf%I3|subf%I3c} %0,%4,%3"
4782 [(set_attr "length" "12")])
4783
4784(define_insn ""
4785 [(set (match_operand:CC 0 "cc_reg_operand" "=x,x")
4786 (compare:CC
4787 (plus:SI (ltu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
4788 (match_operand:SI 2 "reg_or_neg_short_operand" "r,P"))
4789 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
4790 (const_int 0)))
4791 (clobber (match_scratch:SI 4 "=&r,&r"))]
4792 ""
4793 "@
4794 {sf|subfc} %4,%2,%1\;{sfe|subfe} %4,%4,%4\;{sf.|subfc.} %4,%4,%3
4795 {ai|addic} %4,%1,%n2\;{sfe|subfe} %4,%4,%4\;{sf.|subfc.} %4,%4,%3"
4796 [(set_attr "type" "compare")
4797 (set_attr "length" "12")])
4798
4799(define_insn ""
4800 [(set (match_operand:CC 5 "cc_reg_operand" "=x,x")
4801 (compare:CC
4802 (plus:SI (ltu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
4803 (match_operand:SI 2 "reg_or_neg_short_operand" "r,P"))
4804 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
4805 (const_int 0)))
4806 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
4807 (plus:SI (ltu:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
4808 (clobber (match_scratch:SI 4 "=&r,&r"))]
4809 ""
4810 "@
4811 {sf|subfc} %4,%2,%1\;{sfe|subfe} %4,%4,%4\;{sf.|subfc.} %0,%4,%3
4812 {ai|addic} %4,%1,%n2\;{sfe|subfe} %4,%4,%4\;{sf.|subfc.} %0,%4,%3"
4813 [(set_attr "type" "compare")
4814 (set_attr "length" "12")])
4815
4816(define_insn ""
4817 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
4818 (neg:SI (ltu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
4819 (match_operand:SI 2 "reg_or_neg_short_operand" "r,P"))))]
4820 ""
4821 "@
4822 {sf|subfc} %0,%2,%1\;{sfe|subfe} %0,%0,%0
4823 {ai|addic} %0,%1,%n2\;{sfe|subfe} %0,%0,%0"
4824 [(set_attr "length" "8")])
4825
4826(define_insn ""
4827 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
4828 (ge:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4829 (match_operand:SI 2 "reg_or_short_operand" "rI")))
4830 (clobber (match_scratch:SI 3 "=r"))]
4831 "TARGET_POWER"
4832 "doz%I2 %3,%1,%2\;{sfi|subfic} %0,%3,0\;{ae|adde} %0,%0,%3"
4833 [(set_attr "length" "12")])
4834
4835(define_insn ""
4836 [(set (match_operand:CC 4 "cc_reg_operand" "=x")
4837 (compare:CC
4838 (ge:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4839 (match_operand:SI 2 "reg_or_short_operand" "rI"))
4840 (const_int 0)))
4841 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
4842 (ge:SI (match_dup 1) (match_dup 2)))
4843 (clobber (match_scratch:SI 3 "=r"))]
4844 "TARGET_POWER"
4845 "doz%I2 %3,%1,%2\;{sfi|subfic} %0,%3,0\;{ae.|adde.} %0,%0,%3"
4846 [(set_attr "type" "compare")
4847 (set_attr "length" "12")])
4848
4849(define_insn ""
4850 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
4851 (plus:SI (ge:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4852 (match_operand:SI 2 "reg_or_short_operand" "rI"))
4853 (match_operand:SI 3 "gpc_reg_operand" "r")))
4854 (clobber (match_scratch:SI 4 "=&r"))]
4855 "TARGET_POWER"
4856 "doz%I2 %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze|addze} %0,%3"
4857 [(set_attr "length" "12")])
4858
4859(define_insn ""
4860 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
4861 (compare:CC
4862 (plus:SI (ge:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4863 (match_operand:SI 2 "reg_or_short_operand" "rI"))
4864 (match_operand:SI 3 "gpc_reg_operand" "r"))
4865 (const_int 0)))
4866 (clobber (match_scratch:SI 4 "=&r"))]
4867 "TARGET_POWER"
4868 "doz%I2 %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %4,%3"
4869 [(set_attr "type" "compare")
4870 (set_attr "length" "12")])
4871
4872(define_insn ""
4873 [(set (match_operand:CC 5 "cc_reg_operand" "=x")
4874 (compare:CC
4875 (plus:SI (ge:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4876 (match_operand:SI 2 "reg_or_short_operand" "rI"))
4877 (match_operand:SI 3 "gpc_reg_operand" "r"))
4878 (const_int 0)))
4879 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
4880 (plus:SI (ge:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
4881 (clobber (match_scratch:SI 4 "=&r"))]
4882 "TARGET_POWER"
4883 "doz%I2 %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %0,%3"
4884 [(set_attr "type" "compare")
4885 (set_attr "length" "12")])
4886
4887(define_insn ""
4888 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
4889 (neg:SI (ge:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4890 (match_operand:SI 2 "reg_or_short_operand" "rI"))))]
4891 "TARGET_POWER"
4892 "doz%I2 %0,%1,%2\;{ai|addic} %0,%0,-1\;{sfe|subfe} %0,%0,%0"
4893 [(set_attr "length" "12")])
4894
4895;; This is (and (neg (ge X (const_int 0))) Y).
4896(define_insn ""
4897 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
4898 (and:SI (neg:SI
4899 (lshiftrt:SI
4900 (not:SI (match_operand:SI 1 "gpc_reg_operand" "r"))
4901 (const_int 31)))
4902 (match_operand:SI 2 "gpc_reg_operand" "r")))
4903 (clobber (match_scratch:SI 3 "=&r"))]
4904 ""
4905 "{srai|srawi} %3,%1,31\;andc %0,%2,%3"
4906 [(set_attr "length" "8")])
4907
4908(define_insn ""
4909 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
4910 (compare:CC
4911 (and:SI (neg:SI
4912 (lshiftrt:SI
4913 (not:SI (match_operand:SI 1 "gpc_reg_operand" "r"))
4914 (const_int 31)))
4915 (match_operand:SI 2 "gpc_reg_operand" "r"))
4916 (const_int 0)))
4917 (clobber (match_scratch:SI 3 "=&r"))]
4918 ""
4919 "{srai|srawi} %3,%1,31\;andc. %3,%2,%3"
4920 [(set_attr "type" "compare")
4921 (set_attr "length" "8")])
4922
4923(define_insn ""
4924 [(set (match_operand:CC 4 "cc_reg_operand" "=x")
4925 (compare:CC
4926 (and:SI (neg:SI
4927 (lshiftrt:SI
4928 (not:SI (match_operand:SI 1 "gpc_reg_operand" "r"))
4929 (const_int 31)))
4930 (match_operand:SI 2 "gpc_reg_operand" "r"))
4931 (const_int 0)))
4932 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
4933 (and:SI (neg:SI (lshiftrt:SI (not:SI (match_dup 1))
4934 (const_int 31)))
4935 (match_dup 2)))
4936 (clobber (match_scratch:SI 3 "=&r"))]
4937 ""
4938 "{srai|srawi} %3,%1,31\;andc. %0,%2,%3"
4939 [(set_attr "type" "compare")
4940 (set_attr "length" "8")])
4941
4942(define_insn ""
4943 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
4944 (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
4945 (match_operand:SI 2 "reg_or_neg_short_operand" "r,P")))]
4946 ""
4947 "@
4948 {sf|subfc} %0,%2,%1\;{cal %0,0(0)|li %0,0}\;{ae|adde} %0,%0,%0
4949 {ai|addic} %0,%1,%n2\;{cal %0,0(0)|li %0,0}\;{ae|adde} %0,%0,%0"
4950 [(set_attr "length" "12")])
4951
4952(define_insn ""
4953 [(set (match_operand:CC 3 "cc_reg_operand" "=x,x")
4954 (compare:CC
4955 (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
4956 (match_operand:SI 2 "reg_or_neg_short_operand" "r,P"))
4957 (const_int 0)))
4958 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
4959 (geu:SI (match_dup 1) (match_dup 2)))]
4960 ""
4961 "@
4962 {sf|subfc} %0,%2,%1\;{cal %0,0(0)|li %0,0}\;{ae.|adde.} %0,%0,%0
4963 {ai|addic} %0,%1,%n2\;{cal %0,0(0)|li %0,0}\;{ae.|adde.} %0,%0,%0"
4964 [(set_attr "type" "compare")
4965 (set_attr "length" "12")])
4966
4967(define_insn ""
4968 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
4969 (plus:SI (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
4970 (match_operand:SI 2 "reg_or_neg_short_operand" "r,P"))
4971 (match_operand:SI 3 "gpc_reg_operand" "r,r")))
4972 (clobber (match_scratch:SI 4 "=&r,&r"))]
4973 ""
4974 "@
4975 {sf|subfc} %4,%2,%1\;{aze|addze} %0,%3
4976 {ai|addic} %4,%1,%n2\;{aze|addze} %0,%3"
4977 [(set_attr "length" "8")])
4978
4979(define_insn ""
4980 [(set (match_operand:CC 0 "cc_reg_operand" "=x,x")
4981 (compare:CC
4982 (plus:SI (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
4983 (match_operand:SI 2 "reg_or_neg_short_operand" "r,P"))
4984 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
4985 (const_int 0)))
4986 (clobber (match_scratch:SI 4 "=&r,&r"))]
4987 ""
4988 "@
4989 {sf|subfc} %4,%2,%1\;{aze.|addze.} %4,%3
4990 {ai|addic} %4,%1,%n2\;{aze.|addze.} %4,%3"
4991 [(set_attr "type" "compare")
4992 (set_attr "length" "8")])
4993
4994(define_insn ""
4995 [(set (match_operand:CC 5 "cc_reg_operand" "=x,x")
4996 (compare:CC
4997 (plus:SI (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
4998 (match_operand:SI 2 "reg_or_neg_short_operand" "r,P"))
4999 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
5000 (const_int 0)))
5001 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
5002 (plus:SI (geu:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
5003 (clobber (match_scratch:SI 4 "=&r,&r"))]
5004 ""
5005 "@
5006 {sf|subfc} %4,%2,%1\;{aze.|addze.} %0,%3
5007 {ai|addic} %4,%1,%n2\;{aze.|addze.} %4,%3"
5008 [(set_attr "type" "compare")
5009 (set_attr "length" "8")])
5010
5011(define_insn ""
5012 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
5013 (neg:SI (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
5014 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))]
5015 ""
5016 "@
5017 {sf|subfc} %0,%2,%1\;{sfe|subfe} %0,%0,%0\;nand %0,%0,%0
5018 {sfi|subfic} %0,%1,-1\;a%I2 %0,%0,%2\;{sfe|subfe} %0,%0,%0"
5019 [(set_attr "length" "12")])
5020
5021(define_insn ""
5022 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
5023 (and:SI (neg:SI
5024 (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
5025 (match_operand:SI 2 "reg_or_neg_short_operand" "r,P")))
5026 (match_operand:SI 3 "gpc_reg_operand" "r,r")))
5027 (clobber (match_scratch:SI 4 "=&r,&r"))]
5028 ""
5029 "@
5030 {sf|subfc} %4,%2,%1\;{sfe|subfe} %4,%4,%4\;andc %0,%3,%4
5031 {ai|addic} %4,%1,%n2\;{sfe|subfe} %4,%4,%4\;andc %0,%3,%4"
5032 [(set_attr "length" "12")])
5033
5034(define_insn ""
5035 [(set (match_operand:CC 0 "cc_reg_operand" "=x,x")
5036 (compare:CC
5037 (and:SI (neg:SI
5038 (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
5039 (match_operand:SI 2 "reg_or_neg_short_operand" "r,P")))
5040 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
5041 (const_int 0)))
5042 (clobber (match_scratch:SI 4 "=&r,&r"))]
5043 ""
5044 "@
5045 {sf|subfc} %4,%2,%1\;{sfe|subfe} %4,%4,%4\;andc. %4,%3,%4
5046 {ai|addic} %4,%1,%n2\;{sfe|subfe} %4,%4,%4\;andc. %4,%3,%4"
5047 [(set_attr "type" "compare")
5048 (set_attr "length" "12")])
5049
5050(define_insn ""
5051 [(set (match_operand:CC 5 "cc_reg_operand" "=x,x")
5052 (compare:CC
5053 (and:SI (neg:SI
5054 (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
5055 (match_operand:SI 2 "reg_or_neg_short_operand" "r,P")))
5056 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
5057 (const_int 0)))
5058 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
5059 (and:SI (neg:SI (geu:SI (match_dup 1) (match_dup 2))) (match_dup 3)))
5060 (clobber (match_scratch:SI 4 "=&r,&r"))]
5061 ""
5062 "@
5063 {sf|subfc} %4,%2,%1\;{sfe|subfe} %4,%4,%4\;andc. %0,%3,%4
5064 {ai|addic} %4,%1,%n2\;{sfe|subfe} %4,%4,%4\;andc. %0,%3,%4"
5065 [(set_attr "type" "compare")
5066 (set_attr "length" "12")])
5067
5068(define_insn ""
5069 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
5070 (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
5071 (const_int 0)))]
5072 ""
5073 "{sfi|subfic} %0,%1,0\;{ame|addme} %0,%0\;{sri|srwi} %0,%0,31"
5074 [(set_attr "length" "12")])
5075
5076(define_insn ""
5077 [(set (match_operand:CC 2 "cc_reg_operand" "=x")
5078 (compare:CC
5079 (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
5080 (const_int 0))
5081 (const_int 0)))
5082 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
5083 (gt:SI (match_dup 1) (const_int 0)))]
5084 ""
5085 "{sfi|subfic} %0,%1,0\;{ame|addme} %0,%0\;{sri.|srwi.} %0,%0,31"
5086 [(set_attr "type" "delayed_compare")
5087 (set_attr "length" "12")])
5088
5089(define_insn ""
5090 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
5091 (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
5092 (match_operand:SI 2 "reg_or_short_operand" "r")))]
5093 "TARGET_POWER"
5094 "doz %0,%2,%1\;nabs %0,%0\;{sri|srwi} %0,%0,31"
5095 [(set_attr "length" "12")])
5096
5097(define_insn ""
5098 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
5099 (compare:CC
5100 (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
5101 (match_operand:SI 2 "reg_or_short_operand" "r"))
5102 (const_int 0)))
5103 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
5104 (gt:SI (match_dup 1) (match_dup 2)))]
5105 "TARGET_POWER"
5106 "doz %0,%2,%1\;nabs %0,%0\;{sri.|srwi.} %0,%0,31"
5107 [(set_attr "type" "delayed_compare")
5108 (set_attr "length" "12")])
5109
5110(define_insn ""
5111 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
5112 (plus:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
5113 (const_int 0))
5114 (match_operand:SI 2 "gpc_reg_operand" "r")))
5115 (clobber (match_scratch:SI 3 "=&r"))]
5116 ""
5117 "{a|addc} %3,%1,%1\;{sfe|subfe} %3,%1,%3\;{aze|addze} %0,%2"
5118 [(set_attr "length" "12")])
5119
5120(define_insn ""
5121 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
5122 (compare:CC
5123 (plus:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
5124 (const_int 0))
5125 (match_operand:SI 2 "gpc_reg_operand" "r"))
5126 (const_int 0)))
5127 (clobber (match_scratch:SI 3 "=&r"))]
5128 ""
5129 "{a|addc} %3,%1,%1\;{sfe|subfe} %3,%1,%3\;{aze.|addze.} %0,%2"
5130 [(set_attr "type" "compare")
5131 (set_attr "length" "12")])
5132
5133(define_insn ""
5134 [(set (match_operand:CC 4 "cc_reg_operand" "=x")
5135 (compare:CC
5136 (plus:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
5137 (const_int 0))
5138 (match_operand:SI 2 "gpc_reg_operand" "r"))
5139 (const_int 0)))
5140 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
5141 (plus:SI (gt:SI (match_dup 1) (const_int 0)) (match_dup 2)))
5142 (clobber (match_scratch:SI 3 "=&r"))]
5143 ""
5144 "{a|addc} %3,%1,%1\;{sfe|subfe} %3,%1,%3\;{aze.|addze.} %3,%2"
5145 [(set_attr "type" "compare")
5146 (set_attr "length" "12")])
5147
5148(define_insn ""
5149 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
5150 (plus:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
5151 (match_operand:SI 2 "reg_or_short_operand" "r"))
5152 (match_operand:SI 3 "gpc_reg_operand" "r")))
5153 (clobber (match_scratch:SI 4 "=&r"))]
5154 "TARGET_POWER"
5155 "doz %4,%2,%1\;{ai|addic} %4,%4,-1\;{aze|addze} %0,%3"
5156 [(set_attr "length" "12")])
5157
5158(define_insn ""
5159 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
5160 (compare:CC
5161 (plus:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
5162 (match_operand:SI 2 "reg_or_short_operand" "r"))
5163 (match_operand:SI 3 "gpc_reg_operand" "r"))
5164 (const_int 0)))
5165 (clobber (match_scratch:SI 4 "=&r"))]
5166 "TARGET_POWER"
5167 "doz %4,%2,%1\;{ai|addic} %4,%4,-1\;{aze.|addze.} %4,%3"
5168 [(set_attr "type" "compare")
5169 (set_attr "length" "12")])
5170
5171(define_insn ""
5172 [(set (match_operand:CC 5 "cc_reg_operand" "=x")
5173 (compare:CC
5174 (plus:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
5175 (match_operand:SI 2 "reg_or_short_operand" "r"))
5176 (match_operand:SI 3 "gpc_reg_operand" "r"))
5177 (const_int 0)))
5178 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
5179 (plus:SI (gt:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
5180 (clobber (match_scratch:SI 4 "=&r"))]
5181 "TARGET_POWER"
5182 "doz %4,%2,%1\;{ai|addic} %4,%4,-1\;{aze.|addze.} %0,%3"
5183 [(set_attr "type" "compare")
5184 (set_attr "length" "12")])
5185
5186(define_insn ""
5187 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
5188 (neg:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
5189 (const_int 0))))]
5190 ""
5191 "{sfi|subfic} %0,%1,0\;{ame|addme} %0,%0\;{srai|srawi} %0,%0,31"
5192 [(set_attr "length" "12")])
5193
5194(define_insn ""
5195 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
5196 (neg:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
5197 (match_operand:SI 2 "reg_or_short_operand" "r"))))]
5198 "TARGET_POWER"
5199 "doz %0,%2,%1\;nabs %0,%0\;{srai|srawi} %0,%0,31"
5200 [(set_attr "length" "12")])
5201
5202(define_insn ""
5203 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
5204 (gtu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
5205 (match_operand:SI 2 "reg_or_short_operand" "rI")))]
5206 ""
5207 "{sf%I2|subf%I2c} %0,%1,%2\;{sfe|subfe} %0,%0,%0\;neg %0,%0"
5208 [(set_attr "length" "12")])
5209
5210(define_insn ""
5211 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
5212 (compare:CC
5213 (gtu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
5214 (match_operand:SI 2 "reg_or_short_operand" "rI"))
5215 (const_int 0)))
5216 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
5217 (gtu:SI (match_dup 1) (match_dup 2)))]
5218 ""
5219 "{sf%I2|subf%I2c} %0,%1,%2\;{sfe|subfe} %0,%0,%0\;neg. %0,%0"
5220 [(set_attr "type" "compare")
5221 (set_attr "length" "12")])
5222
5223(define_insn ""
5224 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r")
5225 (plus:SI (gtu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r")
5226 (match_operand:SI 2 "reg_or_short_operand" "I,r,rI"))
5227 (match_operand:SI 3 "reg_or_short_operand" "r,r,I")))
5228 (clobber (match_scratch:SI 4 "=&r,&r,&r"))]
5229 ""
5230 "@
5231 {ai|addic} %4,%1,%k2\;{aze|addze} %0,%3
5232 {sf%I2|subf%I2c} %4,%1,%2\;{sfe|subfe} %4,%4,%4\;{sf%I3|subf%I3c} %0,%4,%3
5233 {sf%I2|subf%I2c} %4,%1,%2\;{sfe|subfe} %4,%4,%4\;{sf%I3|subf%I3c} %0,%4,%3"
5234 [(set_attr "length" "8,12,12")])
5235
5236(define_insn ""
5237 [(set (match_operand:CC 0 "cc_reg_operand" "=x,x")
5238 (compare:CC
5239 (plus:SI (gtu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
5240 (match_operand:SI 2 "reg_or_short_operand" "I,r"))
5241 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
5242 (const_int 0)))
5243 (clobber (match_scratch:SI 4 "=&r,&r"))]
5244 ""
5245 "@
5246 {ai|addic} %4,%1,%k2\;{aze.|addze.} %0,%3
5247 {sf%I2|subf%I2c} %4,%1,%2\;{sfe|subfe} %4,%4,%4\;{sf.|subfc.} %0,%4,%3"
5248 [(set_attr "type" "compare")
5249 (set_attr "length" "8,12")])
5250
5251(define_insn ""
5252 [(set (match_operand:CC 5 "cc_reg_operand" "=x,x")
5253 (compare:CC
5254 (plus:SI (gtu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
5255 (match_operand:SI 2 "reg_or_short_operand" "I,r"))
5256 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
5257 (const_int 0)))
5258 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
5259 (plus:SI (gtu:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
5260 (clobber (match_scratch:SI 4 "=&r,&r"))]
5261 ""
5262 "@
5263 {ai|addic} %4,%1,%k2\;{aze.|addze.} %0,%3
5264 {sf%I2|subf%I2c} %4,%1,%2\;{sfe|subfe} %4,%4,%4\;{sf.|subfc.} %0,%4,%3"
5265 [(set_attr "type" "compare")
5266 (set_attr "length" "8,12")])
5267
5268(define_insn ""
5269 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
5270 (neg:SI (gtu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
5271 (match_operand:SI 2 "reg_or_short_operand" "rI"))))]
5272 ""
5273 "{sf%I2|subf%I2c} %0,%1,%2\;{sfe|subfe} %0,%0,%0"
5274 [(set_attr "length" "8")])
5275\f
5276;; Define both directions of branch and return. If we need a reload
5277;; register, we'd rather use CR0 since it is much easier to copy a
5278;; register CC value to there.
5279
5280(define_insn ""
5281 [(set (pc)
5282 (if_then_else (match_operator 1 "branch_comparison_operator"
5283 [(match_operand 2
5284 "cc_reg_operand" "x,?y")
5285 (const_int 0)])
5286 (label_ref (match_operand 0 "" ""))
5287 (pc)))]
5288 ""
5289 "*
5290{
5291 if (get_attr_length (insn) == 8)
5292 return \"%C1bc %t1,%j1,%l0\";
5293 else
5294 return \"%C1bc %T1,%j1,$+8\;b %l0\";
5295}"
5296 [(set_attr "type" "branch")])
5297
5298
5299(define_insn ""
5300 [(set (pc)
5301 (if_then_else (match_operator 0 "branch_comparison_operator"
5302 [(match_operand 1
5303 "cc_reg_operand" "x,?y")
5304 (const_int 0)])
5305 (return)
5306 (pc)))]
5307 "direct_return ()"
5308 "{%C0bcr|%C0bclr} %t0,%j0"
5309 [(set_attr "length" "8")])
5310
5311(define_insn ""
5312 [(set (pc)
5313 (if_then_else (match_operator 1 "branch_comparison_operator"
5314 [(match_operand 2
5315 "cc_reg_operand" "x,?y")
5316 (const_int 0)])
5317 (pc)
5318 (label_ref (match_operand 0 "" ""))))]
5319 ""
5320 "*
5321{
5322 if (get_attr_length (insn) == 8)
5323 return \"%C1bc %T1,%j1,%l0\";
5324 else
5325 return \"%C1bc %t1,%j1,$+8\;b %l0\";
5326}"
5327 [(set_attr "type" "branch")])
5328
5329(define_insn ""
5330 [(set (pc)
5331 (if_then_else (match_operator 0 "branch_comparison_operator"
5332 [(match_operand 1
5333 "cc_reg_operand" "x,?y")
5334 (const_int 0)])
5335 (pc)
5336 (return)))]
5337 "direct_return ()"
5338 "{%C0bcr|%C0bclr} %T0,%j0"
5339 [(set_attr "length" "8")])
5340
5341;; Unconditional branch and return.
5342
5343(define_insn "jump"
5344 [(set (pc)
5345 (label_ref (match_operand 0 "" "")))]
5346 ""
5347 "b %l0")
5348
5349(define_insn "return"
5350 [(return)]
5351 "direct_return ()"
5352 "{br|blr}")
5353
5354(define_insn "indirect_jump"
5355 [(set (pc) (match_operand:SI 0 "register_operand" "c,l"))]
5356 ""
5357 "@
5358 bctr
5359 {br|blr}")
5360
5361;; Table jump for switch statements:
5362(define_expand "tablejump"
5363 [(set (match_dup 3)
5364 (plus:SI (match_operand:SI 0 "" "")
5365 (match_dup 2)))
5366 (parallel [(set (pc) (match_dup 3))
5367 (use (label_ref (match_operand 1 "" "")))])]
5368 ""
5369 "
5370{ operands[0] = force_reg (SImode, operands[0]);
5371 operands[2] = force_reg (SImode, gen_rtx (LABEL_REF, VOIDmode, operands[1]));
5372 operands[3] = gen_reg_rtx (SImode);
5373}")
5374
5375(define_insn ""
5376 [(set (pc)
5377 (match_operand:SI 0 "register_operand" "c,l"))
5378 (use (label_ref (match_operand 1 "" "")))]
5379 ""
5380 "@
5381 bctr
5382 {br|blr}")
5383
5384(define_insn "nop"
5385 [(const_int 0)]
5386 ""
5387 "{cror 0,0,0|nop}")
5388\f
5389;; Define the subtract-one-and-jump insns, starting with the template
5390;; so loop.c knows what to generate.
5391
5392(define_expand "decrement_and_branchsi"
5393 [(parallel [(set (pc) (if_then_else (ne (match_operand:SI 0 "register_operand" "c")
5394 (const_int 1))
5395 (label_ref (match_operand 1 "" ""))
5396 (pc)))
5397 (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))])]
5398 ""
5399 "")
5400
5401;; We need to be able to do this for any operand, including MEM, or we
5402;; will cause reload to blow up since we don't allow output reloads on
5403;; JUMP_INSNs.
5404(define_insn ""
5405 [(set (pc)
5406 (if_then_else (ne (match_operand:SI 1 "register_operand" "0,*r,*r")
5407 (const_int 1))
5408 (label_ref (match_operand 2 "" ""))
5409 (pc)))
5410 (set (match_operand:SI 0 "register_operand" "=c,*r,m*q*c*l")
5411 (plus:SI (match_dup 1) (const_int -1)))
5412 (clobber (match_scratch:CC 3 "=X,&x,&x"))
5413 (clobber (match_scratch:SI 4 "=X,X,r"))]
5414 ""
5415 "*
5416{
5417 if (which_alternative != 0)
5418 return \"#\";
5419 else if (get_attr_length (insn) == 8)
5420 return \"{bdn|bdnz} %l2\";
5421 else
5422 return \"bdz $+8\;b %l2\";
5423}"
5424 [(set_attr "type" "branch")
5425 (set_attr "length" "*,12,16")])
5426
5427;; Similar, but we can use GE since we have a REG_NONNEG.
5428(define_insn ""
5429 [(set (pc)
5430 (if_then_else (ge (match_operand:SI 1 "register_operand" "0,*r,*r")
5431 (const_int 0))
5432 (label_ref (match_operand 2 "" ""))
5433 (pc)))
5434 (set (match_operand:SI 0 "register_operand" "=c,*r,m*q*c*l")
5435 (plus:SI (match_dup 1) (const_int -1)))
5436 (clobber (match_scratch:CC 3 "=X,&x,&X"))
5437 (clobber (match_scratch:SI 4 "=X,X,r"))]
5438 "find_reg_note (insn, REG_NONNEG, 0)"
5439 "*
5440{
5441 if (which_alternative != 0)
5442 return \"#\";
5443 else if (get_attr_length (insn) == 8)
5444 return \"{bdn|bdnz} %l2\";
5445 else
5446 return \"bdz $+8\;b %l2\";
5447}"
5448 [(set_attr "type" "branch")
5449 (set_attr "length" "*,12,16")])
5450
5451(define_insn ""
5452 [(set (pc)
5453 (if_then_else (eq (match_operand:SI 1 "register_operand" "0,*r,*r")
5454 (const_int 1))
5455 (label_ref (match_operand 2 "" ""))
5456 (pc)))
5457 (set (match_operand:SI 0 "register_operand" "=c,*r,m*q*c*l")
5458 (plus:SI (match_dup 1) (const_int -1)))
5459 (clobber (match_scratch:CC 3 "=X,&x,&x"))
5460 (clobber (match_scratch:SI 4 "=X,X,r"))]
5461 ""
5462 "*
5463{
5464 if (which_alternative != 0)
5465 return \"#\";
5466 else if (get_attr_length (insn) == 8)
5467 return \"bdz %l2\";
5468 else
5469 return \"{bdn|bdnz} $+8\;b %l2\";
5470}"
5471 [(set_attr "type" "branch")
5472 (set_attr "length" "*,12,16")])
5473
5474(define_split
5475 [(set (pc)
5476 (if_then_else (match_operator 2 "comparison_operator"
5477 [(match_operand:SI 1 "gpc_reg_operand" "")
5478 (const_int 1)])
5479 (match_operand 5 "" "")
5480 (match_operand 6 "" "")))
5481 (set (match_operand:SI 0 "gpc_reg_operand" "")
5482 (plus:SI (match_dup 1) (const_int -1)))
5483 (clobber (match_scratch:CC 3 ""))
5484 (clobber (match_scratch:SI 4 ""))]
5485 "reload_completed"
5486 [(parallel [(set (match_dup 3)
5487 (compare:CC (plus:SI (match_dup 1) (const_int -1))
5488 (const_int 0)))
5489 (set (match_dup 0) (plus:SI (match_dup 1) (const_int -1)))])
5490 (set (pc) (if_then_else (match_dup 7) (match_dup 5) (match_dup 6)))]
5491 "
5492{ operands[7] = gen_rtx (GET_CODE (operands[2]), VOIDmode, operands[3],
5493 const0_rtx); }")
5494
5495(define_split
5496 [(set (pc)
5497 (if_then_else (match_operator 2 "comparison_operator"
5498 [(match_operand:SI 1 "gpc_reg_operand" "")
5499 (const_int 1)])
5500 (match_operand 5 "" "")
5501 (match_operand 6 "" "")))
5502 (set (match_operand:SI 0 "general_operand" "")
5503 (plus:SI (match_dup 1) (const_int -1)))
5504 (clobber (match_scratch:CC 3 ""))
5505 (clobber (match_scratch:SI 4 ""))]
5506 "reload_completed && ! gpc_reg_operand (operands[0], SImode)"
5507 [(parallel [(set (match_dup 3)
5508 (compare:CC (plus:SI (match_dup 1) (const_int -1))
5509 (const_int 0)))
5510 (set (match_dup 4) (plus:SI (match_dup 1) (const_int -1)))])
5511 (set (match_dup 0) (match_dup 4))
5512 (set (pc) (if_then_else (match_dup 7) (match_dup 5) (match_dup 6)))]
5513 "
5514{ operands[7] = gen_rtx (GET_CODE (operands[2]), VOIDmode, operands[3],
5515 const0_rtx); }")
This page took 0.070663 seconds and 5 git commands to generate.