]> gcc.gnu.org Git - gcc.git/blob - gcc/config/rs6000/rs6000.md
(movdf): Don't copy a word at a time; nearly always loses.
[gcc.git] / gcc / config / rs6000 / rs6000.md
1 ;; Machine description for IBM RISC System 6000 (POWER) for GNU C compiler
2 ;; Copyright (C) 1990, 91, 92, 93, 94, 1995 Free Software Foundation, Inc.
3 ;; Contributed by Richard Kenner (kenner@vlsi1.ultra.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, 59 Temple Place - Suite 330,
20 ;; Boston, MA 02111-1307, USA.
21
22 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
23 \f
24 ;; Define an insn type attribute. This is used in function unit delay
25 ;; computations.
26 (define_attr "type" "integer,load,fpload,imul,idiv,branch,compare,delayed_compare,fpcompare,mtjmpr,fp,dmul,sdiv,ddiv,ssqrt,dsqrt,jmpreg"
27 (const_string "integer"))
28
29 ;; Length (in bytes).
30 (define_attr "length" ""
31 (if_then_else (eq_attr "type" "branch")
32 (if_then_else (and (ge (minus (pc) (match_dup 0))
33 (const_int -32768))
34 (lt (minus (pc) (match_dup 0))
35 (const_int 32767)))
36 (const_int 8)
37 (const_int 12))
38 (const_int 4)))
39
40 ;; Processor type -- this attribute must exactly match the processor_type
41 ;; enumeration in rs6000.h.
42
43 (define_attr "cpu" "rios1,rios2,ppc403,ppc601,ppc602,ppc603,ppc604,ppc620"
44 (const (symbol_ref "rs6000_cpu_attr")))
45
46 ; (define_function_unit NAME MULTIPLICITY SIMULTANEITY
47 ; TEST READY-DELAY ISSUE-DELAY [CONFLICT-LIST])
48
49 ; Load/Store Unit -- POWER/2 and pure PowerPC only
50 ; (POWER and 601 use Integer Unit)
51 (define_function_unit "lsu" 1 0
52 (and (eq_attr "type" "load")
53 (eq_attr "cpu" "ppc602,ppc603,ppc604,ppc620"))
54 2 1)
55
56 (define_function_unit "lsu" 1 0
57 (and (eq_attr "type" "fpload")
58 (eq_attr "cpu" "ppc604,ppc620"))
59 3 1)
60
61 (define_function_unit "lsu" 1 0
62 (and (eq_attr "type" "fpload")
63 (eq_attr "cpu" "ppc602,ppc603"))
64 2 1)
65
66 (define_function_unit "iu" 1 0
67 (and (eq_attr "type" "load")
68 (eq_attr "cpu" "rios1,ppc601,ppc403"))
69 2 1)
70
71 (define_function_unit "iu" 1 0
72 (and (eq_attr "type" "fpload")
73 (eq_attr "cpu" "rios1,ppc601"))
74 2 0)
75
76 ; Integer Unit (RIOS1, PPC601, PPC603)
77 ; Trivial operations take one cycle which need not be listed here.
78 (define_function_unit "iu" 1 0
79 (and (eq_attr "type" "integer")
80 (eq_attr "cpu" "rios1,ppc601"))
81 1 1)
82
83 (define_function_unit "iu" 1 0
84 (and (eq_attr "type" "imul")
85 (eq_attr "cpu" "rios1"))
86 3 3)
87
88 (define_function_unit "iu" 1 0
89 (and (eq_attr "type" "imul")
90 (eq_attr "cpu" "ppc403"))
91 4 4)
92
93 (define_function_unit "iu" 1 0
94 (and (eq_attr "type" "imul")
95 (eq_attr "cpu" "ppc601,ppc602,ppc603"))
96 5 5)
97
98 (define_function_unit "iu" 1 0
99 (and (eq_attr "type" "idiv")
100 (eq_attr "cpu" "rios1"))
101 19 19)
102
103 (define_function_unit "iu" 1 0
104 (and (eq_attr "type" "idiv")
105 (eq_attr "cpu" "ppc601"))
106 36 36)
107
108 (define_function_unit "iu" 1 0
109 (and (eq_attr "type" "idiv")
110 (eq_attr "cpu" "ppc403"))
111 33 33)
112
113 (define_function_unit "iu" 1 0
114 (and (eq_attr "type" "idiv")
115 (eq_attr "cpu" "ppc602,ppc603"))
116 37 36)
117
118 ; RIOS2 has two integer units: a primary one which can perform all
119 ; operations and a secondary one which is fed in lock step with the first
120 ; and can perform "simple" integer operations.
121 ; To catch this we define a 'dummy' imuldiv-unit that is also needed
122 ; for the complex insns.
123 (define_function_unit "iu2" 2 0
124 (and (eq_attr "type" "integer")
125 (eq_attr "cpu" "rios2"))
126 1 0)
127
128 (define_function_unit "iu2" 2 0
129 (and (eq_attr "type" "imul")
130 (eq_attr "cpu" "rios2"))
131 2 2)
132
133 (define_function_unit "iu2" 2 0
134 (and (eq_attr "type" "idiv")
135 (eq_attr "cpu" "rios2"))
136 13 13)
137
138 (define_function_unit "imuldiv" 1 0
139 (and (eq_attr "type" "imul")
140 (eq_attr "cpu" "rios2"))
141 2 2)
142
143
144 (define_function_unit "imuldiv" 1 0
145 (and (eq_attr "type" "idiv")
146 (eq_attr "cpu" "rios2"))
147 13 13)
148
149 ; PPC604 has two units that perform integer operations
150 ; and one unit for divide/multiply operations (and move
151 ; from/to spr).
152 (define_function_unit "iu2" 2 0
153 (and (eq_attr "type" "integer")
154 (eq_attr "cpu" "ppc604,ppc620"))
155 1 1
156 [(eq_attr "type" "imul,idiv")])
157
158 (define_function_unit "imuldiv" 1 0
159 (and (eq_attr "type" "imul")
160 (eq_attr "cpu" "ppc604,ppc620"))
161 4 2
162 [(eq_attr "type" "integer")])
163
164 (define_function_unit "imuldiv" 1 0
165 (and (eq_attr "type" "idiv")
166 (eq_attr "cpu" "ppc604,ppc620"))
167 20 19
168 [(eq_attr "type" "integer")])
169
170 ; compare is done on integer unit, but feeds insns which
171 ; execute on the branch unit. Ready-delay of the compare
172 ; on the branch unit is large (3-5 cycles). On the iu/fpu
173 ; it is 1. One drawback is that the compare will also be
174 ; assigned to the bpu, but this inaccuracy is worth for being
175 ; able to fill the compare-branch delay, with insns on iu/fpu.
176 (define_function_unit "iu" 1 0
177 (and (eq_attr "type" "compare")
178 (eq_attr "cpu" "rios1,ppc601"))
179 1 1)
180
181 (define_function_unit "iu2" 2 0
182 (and (eq_attr "type" "compare")
183 (eq_attr "cpu" "rios2"))
184 1 1)
185
186 (define_function_unit "bpu" 1 0
187 (and (eq_attr "type" "compare")
188 (eq_attr "cpu" "rios1,rios2,ppc403,ppc601,ppc603,ppc604,ppc620"))
189 4 1)
190
191 ; different machines have different compare timings
192 ; in ppc604, compare is done on the one of the two
193 ; main integer units.
194 (define_function_unit "iu2" 2 0
195 (and (eq_attr "type" "compare")
196 (eq_attr "cpu" "ppc604,ppc620"))
197 1 1)
198
199 (define_function_unit "bpu" 1 0
200 (eq_attr "type" "delayed_compare")
201 5 0)
202
203 ; fp compare uses fp unit
204 (define_function_unit "fpu" 1 0
205 (and (eq_attr "type" "fpcompare")
206 (eq_attr "cpu" "rios1"))
207 8 1)
208
209 ; rios1 and rios2 have different fpcompare delays
210 (define_function_unit "fpu2" 2 0
211 (and (eq_attr "type" "fpcompare")
212 (eq_attr "cpu" "rios2"))
213 5 1)
214
215 ; on ppc601 and ppc603, fpcompare takes also 2 cycles from
216 ; the integer unit
217 ; here we do not define delays, just occupy the unit. The dependencies
218 ; will be signed by the fpcompare definition in the fpu.
219 (define_function_unit "iu" 1 0
220 (and (eq_attr "type" "fpcompare")
221 (eq_attr "cpu" "ppc601,ppc602,ppc603"))
222 0 2)
223
224 ; fp compare uses fp unit
225 (define_function_unit "fpu" 1 0
226 (and (eq_attr "type" "fpcompare")
227 (eq_attr "cpu" "ppc601,ppc602,ppc603,ppc604,ppc620"))
228 5 1)
229
230 (define_function_unit "bpu" 1 0
231 (and (eq_attr "type" "mtjmpr")
232 (eq_attr "cpu" "rios1,rios2"))
233 5 0)
234
235 (define_function_unit "bpu" 1 0
236 (and (eq_attr "type" "mtjmpr")
237 (eq_attr "cpu" "ppc403,ppc601,ppc602,ppc603,ppc604,ppc620"))
238 4 0)
239
240 ; all jumps/branches are executing on the bpu, in 1 cycle, for all machines.
241 (define_function_unit "bpu" 1 0
242 (eq_attr "type" "jmpreg")
243 1 0)
244
245 (define_function_unit "bpu" 1 0
246 (eq_attr "type" "branch")
247 1 0)
248
249 ; Floating Point Unit (RIOS1, PPC601, PPC603, PPC604).
250 (define_function_unit "fpu" 1 0
251 (and (eq_attr "type" "fp,dmul")
252 (eq_attr "cpu" "rios1"))
253 2 0)
254
255 (define_function_unit "fpu" 1 0
256 (and (eq_attr "type" "fp")
257 (eq_attr "cpu" "ppc601"))
258 4 0)
259
260 (define_function_unit "fpu" 1 0
261 (and (eq_attr "type" "fp")
262 (eq_attr "cpu" "ppc602,ppc603,ppc604,ppc620"))
263 3 1)
264
265 (define_function_unit "fpu" 1 0
266 (and (eq_attr "type" "dmul")
267 (eq_attr "cpu" "ppc601"))
268 5 2)
269
270 ; is this true?
271 (define_function_unit "fpu" 1 0
272 (and (eq_attr "type" "dmul")
273 (eq_attr "cpu" "ppc602,ppc603"))
274 4 2)
275
276 (define_function_unit "fpu" 1 0
277 (and (eq_attr "type" "dmul")
278 (eq_attr "cpu" "ppc604,ppc620"))
279 3 1)
280
281 (define_function_unit "fpu" 1 0
282 (and (eq_attr "type" "sdiv,ddiv")
283 (eq_attr "cpu" "rios1"))
284 19 19)
285
286 (define_function_unit "fpu" 1 0
287 (and (eq_attr "type" "sdiv")
288 (eq_attr "cpu" "ppc601"))
289 17 17)
290
291 (define_function_unit "fpu" 1 0
292 (and (eq_attr "type" "sdiv")
293 (eq_attr "cpu" "ppc602,ppc603,ppc604,ppc620"))
294 18 18)
295
296 (define_function_unit "fpu" 1 0
297 (and (eq_attr "type" "ddiv")
298 (eq_attr "cpu" "ppc601,ppc604,ppc620"))
299 31 31)
300
301 (define_function_unit "fpu" 1 0
302 (and (eq_attr "type" "ddiv")
303 (eq_attr "cpu" "ppc602,ppc603"))
304 33 33)
305
306 (define_function_unit "fpu" 1 0
307 (and (eq_attr "type" "ssqrt")
308 (eq_attr "cpu" "ppc620"))
309 31 31)
310
311 (define_function_unit "fpu" 1 0
312 (and (eq_attr "type" "dsqrt")
313 (eq_attr "cpu" "ppc620"))
314 31 31)
315
316 ; RIOS2 has two symmetric FPUs.
317 (define_function_unit "fpu2" 2 0
318 (and (eq_attr "type" "fp")
319 (eq_attr "cpu" "rios2"))
320 2 0)
321
322 (define_function_unit "fpu2" 2 0
323 (and (eq_attr "type" "dmul")
324 (eq_attr "cpu" "rios2"))
325 2 0)
326
327 (define_function_unit "fpu2" 2 0
328 (and (eq_attr "type" "sdiv,ddiv")
329 (eq_attr "cpu" "rios2"))
330 17 17)
331
332 (define_function_unit "fpu2" 2 0
333 (and (eq_attr "type" "ssqrt,dsqrt")
334 (eq_attr "cpu" "rios2"))
335 26 26)
336
337 \f
338 ;; Start with fixed-point load and store insns. Here we put only the more
339 ;; complex forms. Basic data transfer is done later.
340
341 (define_expand "zero_extendqidi2"
342 [(set (match_operand:DI 0 "gpc_reg_operand" "")
343 (zero_extend:DI (match_operand:QI 1 "gpc_reg_operand" "")))]
344 "TARGET_POWERPC64"
345 "")
346
347 (define_insn ""
348 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
349 (zero_extend:DI (match_operand:QI 1 "reg_or_mem_operand" "m,r")))]
350 "TARGET_POWERPC64"
351 "@
352 lbz%U1%X1 %0,%1
353 rldicl %0,%1,0,56"
354 [(set_attr "type" "load,*")])
355
356 (define_insn ""
357 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
358 (compare:CC (zero_extend:DI (match_operand:QI 1 "gpc_reg_operand" "r"))
359 (const_int 0)))
360 (clobber (match_scratch:DI 2 "=r"))]
361 "TARGET_POWERPC64"
362 "rldicl. %2,%1,0,56"
363 [(set_attr "type" "compare")])
364
365 (define_insn ""
366 [(set (match_operand:CC 2 "cc_reg_operand" "=x")
367 (compare:CC (zero_extend:DI (match_operand:QI 1 "gpc_reg_operand" "r"))
368 (const_int 0)))
369 (set (match_operand:DI 0 "gpc_reg_operand" "=r")
370 (zero_extend:DI (match_dup 1)))]
371 "TARGET_POWERPC64"
372 "rldicl. %0,%1,0,56"
373 [(set_attr "type" "compare")])
374
375 (define_insn "extendqidi2"
376 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
377 (sign_extend:DI (match_operand:QI 1 "gpc_reg_operand" "r")))]
378 "TARGET_POWERPC64"
379 "extsb %0,%1")
380
381 (define_insn ""
382 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
383 (compare:CC (sign_extend:DI (match_operand:QI 1 "gpc_reg_operand" "r"))
384 (const_int 0)))
385 (clobber (match_scratch:DI 2 "=r"))]
386 "TARGET_POWERPC64"
387 "extsb. %2,%1"
388 [(set_attr "type" "compare")])
389
390 (define_insn ""
391 [(set (match_operand:CC 2 "cc_reg_operand" "=x")
392 (compare:CC (sign_extend:DI (match_operand:QI 1 "gpc_reg_operand" "r"))
393 (const_int 0)))
394 (set (match_operand:DI 0 "gpc_reg_operand" "=r")
395 (sign_extend:DI (match_dup 1)))]
396 "TARGET_POWERPC64"
397 "extsb. %0,%1"
398 [(set_attr "type" "compare")])
399
400 (define_expand "zero_extendhidi2"
401 [(set (match_operand:DI 0 "gpc_reg_operand" "")
402 (zero_extend:DI (match_operand:HI 1 "gpc_reg_operand" "")))]
403 "TARGET_POWERPC64"
404 "")
405
406 (define_insn ""
407 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
408 (zero_extend:DI (match_operand:HI 1 "reg_or_mem_operand" "m,r")))]
409 "TARGET_POWERPC64"
410 "@
411 lhz%U1%X1 %0,%1
412 rldicl %0,%1,0,48"
413 [(set_attr "type" "load,*")])
414
415 (define_insn ""
416 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
417 (compare:CC (zero_extend:DI (match_operand:HI 1 "gpc_reg_operand" "r"))
418 (const_int 0)))
419 (clobber (match_scratch:DI 2 "=r"))]
420 "TARGET_POWERPC64"
421 "rldicl. %2,%1,0,48"
422 [(set_attr "type" "compare")])
423
424 (define_insn ""
425 [(set (match_operand:CC 2 "cc_reg_operand" "=x")
426 (compare:CC (zero_extend:DI (match_operand:HI 1 "gpc_reg_operand" "r"))
427 (const_int 0)))
428 (set (match_operand:DI 0 "gpc_reg_operand" "=r")
429 (zero_extend:DI (match_dup 1)))]
430 "TARGET_POWERPC64"
431 "rldicl. %0,%1,0,48"
432 [(set_attr "type" "compare")])
433
434 (define_expand "extendhidi2"
435 [(set (match_operand:DI 0 "gpc_reg_operand" "")
436 (sign_extend:DI (match_operand:HI 1 "gpc_reg_operand" "")))]
437 "TARGET_POWERPC64"
438 "")
439
440 (define_insn ""
441 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
442 (sign_extend:DI (match_operand:HI 1 "reg_or_mem_operand" "m,r")))]
443 "TARGET_POWERPC64"
444 "@
445 lha%U1%X1 %0,%1
446 extsh %0,%1"
447 [(set_attr "type" "load,*")])
448
449 (define_insn ""
450 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
451 (compare:CC (sign_extend:DI (match_operand:HI 1 "gpc_reg_operand" "r"))
452 (const_int 0)))
453 (clobber (match_scratch:DI 2 "=r"))]
454 "TARGET_POWERPC64"
455 "extsh. %2,%1"
456 [(set_attr "type" "compare")])
457
458 (define_insn ""
459 [(set (match_operand:CC 2 "cc_reg_operand" "=x")
460 (compare:CC (sign_extend:DI (match_operand:HI 1 "gpc_reg_operand" "r"))
461 (const_int 0)))
462 (set (match_operand:DI 0 "gpc_reg_operand" "=r")
463 (sign_extend:DI (match_dup 1)))]
464 "TARGET_POWERPC64"
465 "extsh. %0,%1"
466 [(set_attr "type" "compare")])
467
468 (define_expand "zero_extendsidi2"
469 [(set (match_operand:DI 0 "gpc_reg_operand" "")
470 (zero_extend:DI (match_operand:SI 1 "gpc_reg_operand" "")))]
471 "TARGET_POWERPC64"
472 "")
473
474 (define_insn ""
475 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
476 (zero_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "m,r")))]
477 "TARGET_POWERPC64"
478 "@
479 lwz%U1%X1 %0,%1
480 rldicl %0,%1,0,32"
481 [(set_attr "type" "load,*")])
482
483 (define_insn ""
484 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
485 (compare:CC (zero_extend:DI (match_operand:SI 1 "gpc_reg_operand" "r"))
486 (const_int 0)))
487 (clobber (match_scratch:DI 2 "=r"))]
488 "TARGET_POWERPC64"
489 "rldicl. %2,%1,0,32"
490 [(set_attr "type" "compare")])
491
492 (define_insn ""
493 [(set (match_operand:CC 2 "cc_reg_operand" "=x")
494 (compare:CC (zero_extend:DI (match_operand:SI 1 "gpc_reg_operand" "r"))
495 (const_int 0)))
496 (set (match_operand:DI 0 "gpc_reg_operand" "=r")
497 (zero_extend:DI (match_dup 1)))]
498 "TARGET_POWERPC64"
499 "rldicl. %0,%1,0,32"
500 [(set_attr "type" "compare")])
501
502 (define_expand "extendsidi2"
503 [(set (match_operand:DI 0 "gpc_reg_operand" "")
504 (sign_extend:DI (match_operand:SI 1 "gpc_reg_operand" "")))]
505 "TARGET_POWERPC64"
506 "")
507
508 (define_insn ""
509 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
510 (sign_extend:DI (match_operand:SI 1 "lwa_operand" "m,r")))]
511 "TARGET_POWERPC64"
512 "@
513 lwa%U1%X1 %0,%1
514 extsw %0,%1"
515 [(set_attr "type" "load,*")])
516
517 (define_insn ""
518 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
519 (compare:CC (sign_extend:DI (match_operand:SI 1 "gpc_reg_operand" "r"))
520 (const_int 0)))
521 (clobber (match_scratch:DI 2 "=r"))]
522 "TARGET_POWERPC64"
523 "extsw. %2,%1"
524 [(set_attr "type" "compare")])
525
526 (define_insn ""
527 [(set (match_operand:CC 2 "cc_reg_operand" "=x")
528 (compare:CC (sign_extend:DI (match_operand:SI 1 "gpc_reg_operand" "r"))
529 (const_int 0)))
530 (set (match_operand:DI 0 "gpc_reg_operand" "=r")
531 (sign_extend:DI (match_dup 1)))]
532 "TARGET_POWERPC64"
533 "extsw. %0,%1"
534 [(set_attr "type" "compare")])
535
536 (define_expand "zero_extendqisi2"
537 [(set (match_operand:SI 0 "gpc_reg_operand" "")
538 (zero_extend:SI (match_operand:QI 1 "gpc_reg_operand" "")))]
539 ""
540 "")
541
542 (define_insn ""
543 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
544 (zero_extend:SI (match_operand:QI 1 "reg_or_mem_operand" "m,r")))]
545 ""
546 "@
547 lbz%U1%X1 %0,%1
548 {rlinm|rlwinm} %0,%1,0,0xff"
549 [(set_attr "type" "load,*")])
550
551 (define_insn ""
552 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
553 (compare:CC (zero_extend:SI (match_operand:QI 1 "gpc_reg_operand" "r"))
554 (const_int 0)))
555 (clobber (match_scratch:SI 2 "=r"))]
556 ""
557 "{andil.|andi.} %2,%1,0xff"
558 [(set_attr "type" "compare")])
559
560 (define_insn ""
561 [(set (match_operand:CC 2 "cc_reg_operand" "=x")
562 (compare:CC (zero_extend:SI (match_operand:QI 1 "gpc_reg_operand" "r"))
563 (const_int 0)))
564 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
565 (zero_extend:SI (match_dup 1)))]
566 ""
567 "{andil.|andi.} %0,%1,0xff"
568 [(set_attr "type" "compare")])
569
570 (define_expand "extendqisi2"
571 [(use (match_operand:SI 0 "gpc_reg_operand" ""))
572 (use (match_operand:QI 1 "gpc_reg_operand" ""))]
573 ""
574 "
575 {
576 if (TARGET_POWERPC)
577 emit_insn (gen_extendqisi2_ppc (operands[0], operands[1]));
578 else if (TARGET_POWER)
579 emit_insn (gen_extendqisi2_power (operands[0], operands[1]));
580 else
581 emit_insn (gen_extendqisi2_no_power (operands[0], operands[1]));
582 DONE;
583 }")
584
585 (define_insn "extendqisi2_ppc"
586 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
587 (sign_extend:SI (match_operand:QI 1 "gpc_reg_operand" "r")))]
588 "TARGET_POWERPC"
589 "extsb %0,%1")
590
591 (define_insn ""
592 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
593 (compare:CC (sign_extend:SI (match_operand:QI 1 "gpc_reg_operand" "r"))
594 (const_int 0)))
595 (clobber (match_scratch:SI 2 "=r"))]
596 "TARGET_POWERPC"
597 "extsb. %2,%1"
598 [(set_attr "type" "compare")])
599
600 (define_insn ""
601 [(set (match_operand:CC 2 "cc_reg_operand" "=x")
602 (compare:CC (sign_extend:SI (match_operand:QI 1 "gpc_reg_operand" "r"))
603 (const_int 0)))
604 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
605 (sign_extend:SI (match_dup 1)))]
606 "TARGET_POWERPC"
607 "extsb. %0,%1"
608 [(set_attr "type" "compare")])
609
610 (define_expand "extendqisi2_power"
611 [(parallel [(set (match_dup 2)
612 (ashift:SI (match_operand:QI 1 "gpc_reg_operand" "")
613 (const_int 24)))
614 (clobber (scratch:SI))])
615 (parallel [(set (match_operand:SI 0 "gpc_reg_operand" "")
616 (ashiftrt:SI (match_dup 2)
617 (const_int 24)))
618 (clobber (scratch:SI))])]
619 "TARGET_POWER"
620 "
621 { operands[1] = gen_lowpart (SImode, operands[1]);
622 operands[2] = gen_reg_rtx (SImode); }")
623
624 (define_expand "extendqisi2_no_power"
625 [(set (match_dup 2)
626 (ashift:SI (match_operand:QI 1 "gpc_reg_operand" "")
627 (const_int 24)))
628 (set (match_operand:SI 0 "gpc_reg_operand" "")
629 (ashiftrt:SI (match_dup 2)
630 (const_int 24)))]
631 "! TARGET_POWER && ! TARGET_POWERPC"
632 "
633 { operands[1] = gen_lowpart (SImode, operands[1]);
634 operands[2] = gen_reg_rtx (SImode); }")
635
636 (define_expand "zero_extendqihi2"
637 [(set (match_operand:HI 0 "gpc_reg_operand" "")
638 (zero_extend:HI (match_operand:QI 1 "gpc_reg_operand" "")))]
639 ""
640 "")
641
642 (define_insn ""
643 [(set (match_operand:HI 0 "gpc_reg_operand" "=r,r")
644 (zero_extend:HI (match_operand:QI 1 "reg_or_mem_operand" "m,r")))]
645 ""
646 "@
647 lbz%U1%X1 %0,%1
648 {rlinm|rlwinm} %0,%1,0,0xff"
649 [(set_attr "type" "load,*")])
650
651 (define_insn ""
652 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
653 (compare:CC (zero_extend:HI (match_operand:QI 1 "gpc_reg_operand" "r"))
654 (const_int 0)))
655 (clobber (match_scratch:HI 2 "=r"))]
656 ""
657 "{andil.|andi.} %2,%1,0xff"
658 [(set_attr "type" "compare")])
659
660 (define_insn ""
661 [(set (match_operand:CC 2 "cc_reg_operand" "=x")
662 (compare:CC (zero_extend:HI (match_operand:QI 1 "gpc_reg_operand" "r"))
663 (const_int 0)))
664 (set (match_operand:HI 0 "gpc_reg_operand" "=r")
665 (zero_extend:HI (match_dup 1)))]
666 ""
667 "{andil.|andi.} %0,%1,0xff"
668 [(set_attr "type" "compare")])
669
670 (define_expand "extendqihi2"
671 [(use (match_operand:HI 0 "gpc_reg_operand" ""))
672 (use (match_operand:QI 1 "gpc_reg_operand" ""))]
673 ""
674 "
675 {
676 if (TARGET_POWERPC)
677 emit_insn (gen_extendqihi2_ppc (operands[0], operands[1]));
678 else if (TARGET_POWER)
679 emit_insn (gen_extendqihi2_power (operands[0], operands[1]));
680 else
681 emit_insn (gen_extendqihi2_no_power (operands[0], operands[1]));
682 DONE;
683 }")
684
685 (define_insn "extendqihi2_ppc"
686 [(set (match_operand:HI 0 "gpc_reg_operand" "=r")
687 (sign_extend:HI (match_operand:QI 1 "gpc_reg_operand" "r")))]
688 "TARGET_POWERPC"
689 "extsb %0,%1")
690
691 (define_insn ""
692 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
693 (compare:CC (sign_extend:HI (match_operand:QI 1 "gpc_reg_operand" "r"))
694 (const_int 0)))
695 (clobber (match_scratch:HI 2 "=r"))]
696 "TARGET_POWERPC"
697 "extsb. %2,%1"
698 [(set_attr "type" "compare")])
699
700 (define_insn ""
701 [(set (match_operand:CC 2 "cc_reg_operand" "=x")
702 (compare:CC (sign_extend:HI (match_operand:QI 1 "gpc_reg_operand" "r"))
703 (const_int 0)))
704 (set (match_operand:HI 0 "gpc_reg_operand" "=r")
705 (sign_extend:HI (match_dup 1)))]
706 "TARGET_POWERPC"
707 "extsb. %0,%1"
708 [(set_attr "type" "compare")])
709
710 (define_expand "extendqihi2_power"
711 [(parallel [(set (match_dup 2)
712 (ashift:SI (match_operand:QI 1 "gpc_reg_operand" "")
713 (const_int 24)))
714 (clobber (scratch:SI))])
715 (parallel [(set (match_operand:HI 0 "gpc_reg_operand" "")
716 (ashiftrt:SI (match_dup 2)
717 (const_int 24)))
718 (clobber (scratch:SI))])]
719 "TARGET_POWER"
720 "
721 { operands[0] = gen_lowpart (SImode, operands[0]);
722 operands[1] = gen_lowpart (SImode, operands[1]);
723 operands[2] = gen_reg_rtx (SImode); }")
724
725 (define_expand "extendqihi2_no_power"
726 [(set (match_dup 2)
727 (ashift:SI (match_operand:QI 1 "gpc_reg_operand" "")
728 (const_int 24)))
729 (set (match_operand:HI 0 "gpc_reg_operand" "")
730 (ashiftrt:SI (match_dup 2)
731 (const_int 24)))]
732 "! TARGET_POWER && ! TARGET_POWERPC"
733 "
734 { operands[0] = gen_lowpart (SImode, operands[0]);
735 operands[1] = gen_lowpart (SImode, operands[1]);
736 operands[2] = gen_reg_rtx (SImode); }")
737
738 (define_expand "zero_extendhisi2"
739 [(set (match_operand:SI 0 "gpc_reg_operand" "")
740 (zero_extend:SI (match_operand:HI 1 "gpc_reg_operand" "")))]
741 ""
742 "")
743
744 (define_insn ""
745 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
746 (zero_extend:SI (match_operand:HI 1 "reg_or_mem_operand" "m,r")))]
747 ""
748 "@
749 lhz%U1%X1 %0,%1
750 {rlinm|rlwinm} %0,%1,0,0xffff"
751 [(set_attr "type" "load,*")])
752
753 (define_insn ""
754 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
755 (compare:CC (zero_extend:SI (match_operand:HI 1 "gpc_reg_operand" "r"))
756 (const_int 0)))
757 (clobber (match_scratch:SI 2 "=r"))]
758 ""
759 "{andil.|andi.} %2,%1,0xffff"
760 [(set_attr "type" "compare")])
761
762 (define_insn ""
763 [(set (match_operand:CC 2 "cc_reg_operand" "=x")
764 (compare:CC (zero_extend:SI (match_operand:HI 1 "gpc_reg_operand" "r"))
765 (const_int 0)))
766 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
767 (zero_extend:SI (match_dup 1)))]
768 ""
769 "{andil.|andi.} %0,%1,0xffff"
770 [(set_attr "type" "compare")])
771
772 (define_expand "extendhisi2"
773 [(set (match_operand:SI 0 "gpc_reg_operand" "")
774 (sign_extend:SI (match_operand:HI 1 "gpc_reg_operand" "")))]
775 ""
776 "")
777
778 (define_insn ""
779 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
780 (sign_extend:SI (match_operand:HI 1 "reg_or_mem_operand" "m,r")))]
781 ""
782 "@
783 lha%U1%X1 %0,%1
784 {exts|extsh} %0,%1"
785 [(set_attr "type" "load,*")])
786
787 (define_insn ""
788 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
789 (compare:CC (sign_extend:SI (match_operand:HI 1 "gpc_reg_operand" "r"))
790 (const_int 0)))
791 (clobber (match_scratch:SI 2 "=r"))]
792 ""
793 "{exts.|extsh.} %2,%1"
794 [(set_attr "type" "compare")])
795
796 (define_insn ""
797 [(set (match_operand:CC 2 "cc_reg_operand" "=x")
798 (compare:CC (sign_extend:SI (match_operand:HI 1 "gpc_reg_operand" "r"))
799 (const_int 0)))
800 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
801 (sign_extend:SI (match_dup 1)))]
802 ""
803 "{exts.|extsh.} %0,%1"
804 [(set_attr "type" "compare")])
805 \f
806 ;; Fixed-point arithmetic insns.
807
808 ;; Discourage ai/addic because of carry but provide it in an alternative
809 ;; allowing register zero as source.
810 (define_insn "addsi3"
811 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,?r,r")
812 (plus:SI (match_operand:SI 1 "gpc_reg_operand" "%r,b,r,b")
813 (match_operand:SI 2 "add_operand" "r,I,I,J")))]
814 ""
815 "@
816 {cax|add} %0,%1,%2
817 {cal %0,%2(%1)|addi %0,%1,%2}
818 {ai|addic} %0,%1,%2
819 {cau|addis} %0,%1,%u2")
820
821 (define_insn ""
822 [(set (match_operand:CC 0 "cc_reg_operand" "=x,x")
823 (compare:CC (plus:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r")
824 (match_operand:SI 2 "reg_or_short_operand" "r,I"))
825 (const_int 0)))
826 (clobber (match_scratch:SI 3 "=r,r"))]
827 ""
828 "@
829 {cax.|add.} %3,%1,%2
830 {ai.|addic.} %3,%1,%2"
831 [(set_attr "type" "compare")])
832
833 (define_insn ""
834 [(set (match_operand:CC 3 "cc_reg_operand" "=x,x")
835 (compare:CC (plus:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r")
836 (match_operand:SI 2 "reg_or_short_operand" "r,I"))
837 (const_int 0)))
838 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
839 (plus:SI (match_dup 1) (match_dup 2)))]
840 ""
841 "@
842 {cax.|add.} %0,%1,%2
843 {ai.|addic.} %0,%1,%2"
844 [(set_attr "type" "compare")])
845
846 ;; Split an add that we can't do in one insn into two insns, each of which
847 ;; does one 16-bit part. This is used by combine. Note that the low-order
848 ;; add should be last in case the result gets used in an address.
849
850 (define_split
851 [(set (match_operand:SI 0 "gpc_reg_operand" "")
852 (plus:SI (match_operand:SI 1 "gpc_reg_operand" "")
853 (match_operand:SI 2 "non_add_cint_operand" "")))]
854 ""
855 [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))
856 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 4)))]
857 "
858 {
859 int low = INTVAL (operands[2]) & 0xffff;
860 int high = (unsigned) INTVAL (operands[2]) >> 16;
861
862 if (low & 0x8000)
863 high++, low |= 0xffff0000;
864
865 operands[3] = gen_rtx (CONST_INT, VOIDmode, high << 16);
866 operands[4] = gen_rtx (CONST_INT, VOIDmode, low);
867 }")
868
869 (define_insn "one_cmplsi2"
870 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
871 (not:SI (match_operand:SI 1 "gpc_reg_operand" "r")))]
872 ""
873 "nor %0,%1,%1")
874
875 (define_insn ""
876 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
877 (compare:CC (not:SI (match_operand:SI 1 "gpc_reg_operand" "r"))
878 (const_int 0)))
879 (clobber (match_scratch:SI 2 "=r"))]
880 ""
881 "nor. %2,%1,%1"
882 [(set_attr "type" "compare")])
883
884 (define_insn ""
885 [(set (match_operand:CC 2 "cc_reg_operand" "=x")
886 (compare:CC (not:SI (match_operand:SI 1 "gpc_reg_operand" "r"))
887 (const_int 0)))
888 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
889 (not:SI (match_dup 1)))]
890 ""
891 "nor. %0,%2,%1"
892 [(set_attr "type" "compare")])
893
894 (define_insn ""
895 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
896 (minus:SI (match_operand:SI 1 "reg_or_short_operand" "rI")
897 (match_operand:SI 2 "gpc_reg_operand" "r")))]
898 "! TARGET_POWERPC"
899 "{sf%I1|subf%I1c} %0,%2,%1")
900
901 (define_insn ""
902 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
903 (minus:SI (match_operand:SI 1 "reg_or_short_operand" "r,I")
904 (match_operand:SI 2 "gpc_reg_operand" "r,r")))]
905 "TARGET_POWERPC"
906 "@
907 subf %0,%2,%1
908 subfic %0,%2,%1")
909
910 (define_insn ""
911 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
912 (compare:CC (minus:SI (match_operand:SI 1 "gpc_reg_operand" "r")
913 (match_operand:SI 2 "gpc_reg_operand" "r"))
914 (const_int 0)))
915 (clobber (match_scratch:SI 3 "=r"))]
916 "! TARGET_POWERPC"
917 "{sf.|subfc.} %3,%2,%1"
918 [(set_attr "type" "compare")])
919
920 (define_insn ""
921 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
922 (compare:CC (minus:SI (match_operand:SI 1 "gpc_reg_operand" "r")
923 (match_operand:SI 2 "gpc_reg_operand" "r"))
924 (const_int 0)))
925 (clobber (match_scratch:SI 3 "=r"))]
926 "TARGET_POWERPC"
927 "subf. %3,%2,%1"
928 [(set_attr "type" "compare")])
929
930 (define_insn ""
931 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
932 (compare:CC (minus:SI (match_operand:SI 1 "gpc_reg_operand" "r")
933 (match_operand:SI 2 "gpc_reg_operand" "r"))
934 (const_int 0)))
935 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
936 (minus:SI (match_dup 1) (match_dup 2)))]
937 "! TARGET_POWERPC"
938 "{sf.|subfc.} %0,%2,%1"
939 [(set_attr "type" "compare")])
940
941 (define_insn ""
942 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
943 (compare:CC (minus:SI (match_operand:SI 1 "gpc_reg_operand" "r")
944 (match_operand:SI 2 "gpc_reg_operand" "r"))
945 (const_int 0)))
946 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
947 (minus:SI (match_dup 1) (match_dup 2)))]
948 "TARGET_POWERPC"
949 "subf. %0,%2,%1"
950 [(set_attr "type" "compare")])
951
952 (define_expand "subsi3"
953 [(set (match_operand:SI 0 "gpc_reg_operand" "")
954 (minus:SI (match_operand:SI 1 "reg_or_short_operand" "")
955 (match_operand:SI 2 "reg_or_cint_operand" "")))]
956 ""
957 "
958 {
959 if (GET_CODE (operands[2]) == CONST_INT)
960 {
961 emit_insn (gen_addsi3 (operands[0], operands[1],
962 negate_rtx (SImode, operands[2])));
963 DONE;
964 }
965 }")
966
967 ;; For SMIN, SMAX, UMIN, and UMAX, we use DEFINE_EXPAND's that involve a doz[i]
968 ;; instruction and some auxiliary computations. Then we just have a single
969 ;; DEFINE_INSN for doz[i] and the define_splits to make them if made by
970 ;; combine.
971
972 (define_expand "sminsi3"
973 [(set (match_dup 3)
974 (if_then_else:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "")
975 (match_operand:SI 2 "reg_or_short_operand" ""))
976 (const_int 0)
977 (minus:SI (match_dup 2) (match_dup 1))))
978 (set (match_operand:SI 0 "gpc_reg_operand" "")
979 (minus:SI (match_dup 2) (match_dup 3)))]
980 "TARGET_POWER"
981 "
982 { operands[3] = gen_reg_rtx (SImode); }")
983
984 (define_split
985 [(set (match_operand:SI 0 "gpc_reg_operand" "")
986 (smin:SI (match_operand:SI 1 "gpc_reg_operand" "")
987 (match_operand:SI 2 "reg_or_short_operand" "")))
988 (clobber (match_operand:SI 3 "gpc_reg_operand" ""))]
989 "TARGET_POWER"
990 [(set (match_dup 3)
991 (if_then_else:SI (gt:SI (match_dup 1) (match_dup 2))
992 (const_int 0)
993 (minus:SI (match_dup 2) (match_dup 1))))
994 (set (match_dup 0) (minus:SI (match_dup 2) (match_dup 3)))]
995 "")
996
997 (define_expand "smaxsi3"
998 [(set (match_dup 3)
999 (if_then_else:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "")
1000 (match_operand:SI 2 "reg_or_short_operand" ""))
1001 (const_int 0)
1002 (minus:SI (match_dup 2) (match_dup 1))))
1003 (set (match_operand:SI 0 "gpc_reg_operand" "")
1004 (plus:SI (match_dup 3) (match_dup 1)))]
1005 "TARGET_POWER"
1006 "
1007 { operands[3] = gen_reg_rtx (SImode); }")
1008
1009 (define_split
1010 [(set (match_operand:SI 0 "gpc_reg_operand" "")
1011 (smax:SI (match_operand:SI 1 "gpc_reg_operand" "")
1012 (match_operand:SI 2 "reg_or_short_operand" "")))
1013 (clobber (match_operand:SI 3 "gpc_reg_operand" ""))]
1014 "TARGET_POWER"
1015 [(set (match_dup 3)
1016 (if_then_else:SI (gt:SI (match_dup 1) (match_dup 2))
1017 (const_int 0)
1018 (minus:SI (match_dup 2) (match_dup 1))))
1019 (set (match_dup 0) (plus:SI (match_dup 3) (match_dup 1)))]
1020 "")
1021
1022 (define_expand "uminsi3"
1023 [(set (match_dup 3) (xor:SI (match_operand:SI 1 "gpc_reg_operand" "")
1024 (match_dup 5)))
1025 (set (match_dup 4) (xor:SI (match_operand:SI 2 "gpc_reg_operand" "")
1026 (match_dup 5)))
1027 (set (match_dup 3) (if_then_else:SI (gt (match_dup 3) (match_dup 4))
1028 (const_int 0)
1029 (minus:SI (match_dup 4) (match_dup 3))))
1030 (set (match_operand:SI 0 "gpc_reg_operand" "")
1031 (minus:SI (match_dup 2) (match_dup 3)))]
1032 "TARGET_POWER"
1033 "
1034 {
1035 operands[3] = gen_reg_rtx (SImode);
1036 operands[4] = gen_reg_rtx (SImode);
1037 operands[5] = GEN_INT (-2147483647 - 1);
1038 }")
1039
1040 (define_expand "umaxsi3"
1041 [(set (match_dup 3) (xor:SI (match_operand:SI 1 "gpc_reg_operand" "")
1042 (match_dup 5)))
1043 (set (match_dup 4) (xor:SI (match_operand:SI 2 "gpc_reg_operand" "")
1044 (match_dup 5)))
1045 (set (match_dup 3) (if_then_else:SI (gt (match_dup 3) (match_dup 4))
1046 (const_int 0)
1047 (minus:SI (match_dup 4) (match_dup 3))))
1048 (set (match_operand:SI 0 "gpc_reg_operand" "")
1049 (plus:SI (match_dup 3) (match_dup 1)))]
1050 "TARGET_POWER"
1051 "
1052 {
1053 operands[3] = gen_reg_rtx (SImode);
1054 operands[4] = gen_reg_rtx (SImode);
1055 operands[5] = GEN_INT (-2147483647 - 1);
1056 }")
1057
1058 (define_insn ""
1059 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1060 (if_then_else:SI (gt (match_operand:SI 1 "gpc_reg_operand" "r")
1061 (match_operand:SI 2 "reg_or_short_operand" "rI"))
1062 (const_int 0)
1063 (minus:SI (match_dup 2) (match_dup 1))))]
1064 "TARGET_POWER"
1065 "doz%I2 %0,%1,%2")
1066
1067 (define_insn ""
1068 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
1069 (compare:CC
1070 (if_then_else:SI (gt (match_operand:SI 1 "gpc_reg_operand" "r")
1071 (match_operand:SI 2 "reg_or_short_operand" "rI"))
1072 (const_int 0)
1073 (minus:SI (match_dup 2) (match_dup 1)))
1074 (const_int 0)))
1075 (clobber (match_scratch:SI 3 "=r"))]
1076 "TARGET_POWER"
1077 "doz%I2. %3,%1,%2"
1078 [(set_attr "type" "delayed_compare")])
1079
1080 (define_insn ""
1081 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1082 (compare:CC
1083 (if_then_else:SI (gt (match_operand:SI 1 "gpc_reg_operand" "r")
1084 (match_operand:SI 2 "reg_or_short_operand" "rI"))
1085 (const_int 0)
1086 (minus:SI (match_dup 2) (match_dup 1)))
1087 (const_int 0)))
1088 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1089 (if_then_else:SI (gt (match_dup 1) (match_dup 2))
1090 (const_int 0)
1091 (minus:SI (match_dup 2) (match_dup 1))))]
1092 "TARGET_POWER"
1093 "doz%I2. %0,%1,%2"
1094 [(set_attr "type" "delayed_compare")])
1095
1096 ;; We don't need abs with condition code because such comparisons should
1097 ;; never be done.
1098 (define_expand "abssi2"
1099 [(set (match_operand:SI 0 "gpc_reg_operand" "")
1100 (abs:SI (match_operand:SI 1 "gpc_reg_operand" "")))]
1101 ""
1102 "
1103 {
1104 if (!TARGET_POWER)
1105 {
1106 emit_insn (gen_abssi2_nopower (operands[0], operands[1]));
1107 DONE;
1108 }
1109 }")
1110
1111 (define_insn "abssi2_power"
1112 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1113 (abs:SI (match_operand:SI 1 "gpc_reg_operand" "r")))]
1114 "TARGET_POWER"
1115 "abs %0,%1")
1116
1117 (define_insn "abssi2_nopower"
1118 [(set (match_operand:SI 0 "gpc_reg_operand" "=&r,r")
1119 (abs:SI (match_operand:SI 1 "gpc_reg_operand" "r,0")))
1120 (clobber (match_scratch:SI 2 "=&r,&r"))]
1121 "!TARGET_POWER"
1122 "*
1123 {
1124 return (TARGET_POWERPC)
1125 ? \"{srai|srawi} %2,%1,31\;xor %0,%2,%1\;subf %0,%2,%0\"
1126 : \"{srai|srawi} %2,%1,31\;xor %0,%2,%1\;{sf|subfc} %0,%2,%0\";
1127 }"
1128 [(set_attr "length" "12")])
1129
1130 (define_split
1131 [(set (match_operand:SI 0 "gpc_reg_operand" "=&r,r")
1132 (abs:SI (match_operand:SI 1 "gpc_reg_operand" "r,0")))
1133 (clobber (match_scratch:SI 2 "=&r,&r"))]
1134 "!TARGET_POWER && reload_completed"
1135 [(set (match_dup 2) (ashiftrt:SI (match_dup 1) (const_int 31)))
1136 (set (match_dup 0) (xor:SI (match_dup 2) (match_dup 1)))
1137 (set (match_dup 0) (minus:SI (match_dup 2) (match_dup 0)))]
1138 "")
1139
1140 (define_insn ""
1141 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1142 (neg:SI (abs:SI (match_operand:SI 1 "gpc_reg_operand" "r"))))]
1143 "TARGET_POWER"
1144 "nabs %0,%1")
1145
1146 (define_insn ""
1147 [(set (match_operand:SI 0 "gpc_reg_operand" "=&r,r")
1148 (neg:SI (abs:SI (match_operand:SI 1 "gpc_reg_operand" "r,0"))))
1149 (clobber (match_scratch:SI 2 "=&r,&r"))]
1150 "!TARGET_POWER"
1151 "*
1152 {
1153 return (TARGET_POWERPC)
1154 ? \"{srai|srawi} %2,%1,31\;xor %0,%2,%1\;subf %0,%0,%2\"
1155 : \"{srai|srawi} %2,%1,31\;xor %0,%2,%1\;{sf|subfc} %0,%0,%2\";
1156 }"
1157 [(set_attr "length" "12")])
1158
1159 (define_split
1160 [(set (match_operand:SI 0 "gpc_reg_operand" "=&r,r")
1161 (neg:SI (abs:SI (match_operand:SI 1 "gpc_reg_operand" "r,0"))))
1162 (clobber (match_scratch:SI 2 "=&r,&r"))]
1163 "!TARGET_POWER && reload_completed"
1164 [(set (match_dup 2) (ashiftrt:SI (match_dup 1) (const_int 31)))
1165 (set (match_dup 0) (xor:SI (match_dup 2) (match_dup 1)))
1166 (set (match_dup 0) (minus:SI (match_dup 0) (match_dup 2)))]
1167 "")
1168
1169 (define_insn "negsi2"
1170 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1171 (neg:SI (match_operand:SI 1 "gpc_reg_operand" "r")))]
1172 ""
1173 "neg %0,%1")
1174
1175 (define_insn ""
1176 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
1177 (compare:CC (neg:SI (match_operand:SI 1 "gpc_reg_operand" "r"))
1178 (const_int 0)))
1179 (clobber (match_scratch:SI 2 "=r"))]
1180 ""
1181 "neg. %2,%1"
1182 [(set_attr "type" "compare")])
1183
1184 (define_insn ""
1185 [(set (match_operand:CC 2 "cc_reg_operand" "=x")
1186 (compare:CC (neg:SI (match_operand:SI 1 "gpc_reg_operand" "r"))
1187 (const_int 0)))
1188 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1189 (neg:SI (match_dup 1)))]
1190 ""
1191 "neg. %0,%1"
1192 [(set_attr "type" "compare")])
1193
1194 (define_insn "ffssi2"
1195 [(set (match_operand:SI 0 "gpc_reg_operand" "=&r")
1196 (ffs:SI (match_operand:SI 1 "gpc_reg_operand" "r")))]
1197 ""
1198 "neg %0,%1\;and %0,%0,%1\;{cntlz|cntlzw} %0,%0\;{sfi|subfic} %0,%0,32"
1199 [(set_attr "length" "16")])
1200
1201 (define_expand "mulsi3"
1202 [(use (match_operand:SI 0 "gpc_reg_operand" ""))
1203 (use (match_operand:SI 1 "gpc_reg_operand" ""))
1204 (use (match_operand:SI 2 "reg_or_short_operand" ""))]
1205 ""
1206 "
1207 {
1208 if (TARGET_POWER)
1209 emit_insn (gen_mulsi3_mq (operands[0], operands[1], operands[2]));
1210 else
1211 emit_insn (gen_mulsi3_no_mq (operands[0], operands[1], operands[2]));
1212 DONE;
1213 }")
1214
1215 (define_insn "mulsi3_mq"
1216 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
1217 (mult:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r")
1218 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
1219 (clobber (match_scratch:SI 3 "=q,q"))]
1220 "TARGET_POWER"
1221 "@
1222 {muls|mullw} %0,%1,%2
1223 {muli|mulli} %0,%1,%2"
1224 [(set_attr "type" "imul")])
1225
1226 (define_insn "mulsi3_no_mq"
1227 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
1228 (mult:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r")
1229 (match_operand:SI 2 "reg_or_short_operand" "r,I")))]
1230 "! TARGET_POWER"
1231 "@
1232 {muls|mullw} %0,%1,%2
1233 {muli|mulli} %0,%1,%2"
1234 [(set_attr "type" "imul")])
1235
1236 (define_insn ""
1237 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
1238 (compare:CC (mult:SI (match_operand:SI 1 "gpc_reg_operand" "%r")
1239 (match_operand:SI 2 "gpc_reg_operand" "r"))
1240 (const_int 0)))
1241 (clobber (match_scratch:SI 3 "=r"))
1242 (clobber (match_scratch:SI 4 "=q"))]
1243 "TARGET_POWER"
1244 "{muls.|mullw.} %3,%1,%2"
1245 [(set_attr "type" "delayed_compare")])
1246
1247 (define_insn ""
1248 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
1249 (compare:CC (mult:SI (match_operand:SI 1 "gpc_reg_operand" "%r")
1250 (match_operand:SI 2 "gpc_reg_operand" "r"))
1251 (const_int 0)))
1252 (clobber (match_scratch:SI 3 "=r"))]
1253 "! TARGET_POWER"
1254 "{muls.|mullw.} %3,%1,%2"
1255 [(set_attr "type" "delayed_compare")])
1256
1257 (define_insn ""
1258 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1259 (compare:CC (mult:SI (match_operand:SI 1 "gpc_reg_operand" "%r")
1260 (match_operand:SI 2 "gpc_reg_operand" "r"))
1261 (const_int 0)))
1262 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1263 (mult:SI (match_dup 1) (match_dup 2)))
1264 (clobber (match_scratch:SI 4 "=q"))]
1265 "TARGET_POWER"
1266 "{muls.|mullw.} %0,%1,%2"
1267 [(set_attr "type" "delayed_compare")])
1268
1269 (define_insn ""
1270 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1271 (compare:CC (mult:SI (match_operand:SI 1 "gpc_reg_operand" "%r")
1272 (match_operand:SI 2 "gpc_reg_operand" "r"))
1273 (const_int 0)))
1274 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1275 (mult:SI (match_dup 1) (match_dup 2)))]
1276 "! TARGET_POWER"
1277 "{muls.|mullw.} %0,%1,%2"
1278 [(set_attr "type" "delayed_compare")])
1279
1280 ;; Operand 1 is divided by operand 2; quotient goes to operand
1281 ;; 0 and remainder to operand 3.
1282 ;; ??? At some point, see what, if anything, we can do about if (x % y == 0).
1283
1284 (define_expand "divmodsi4"
1285 [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "")
1286 (div:SI (match_operand:SI 1 "gpc_reg_operand" "")
1287 (match_operand:SI 2 "gpc_reg_operand" "")))
1288 (set (match_operand:SI 3 "gpc_reg_operand" "")
1289 (mod:SI (match_dup 1) (match_dup 2)))])]
1290 "TARGET_POWER || (! TARGET_POWER && ! TARGET_POWERPC)"
1291 "
1292 {
1293 if (! TARGET_POWER && ! TARGET_POWERPC)
1294 {
1295 emit_move_insn (gen_rtx (REG, SImode, 3), operands[1]);
1296 emit_move_insn (gen_rtx (REG, SImode, 4), operands[2]);
1297 emit_insn (gen_divss_call ());
1298 emit_move_insn (operands[0], gen_rtx (REG, SImode, 3));
1299 emit_move_insn (operands[3], gen_rtx (REG, SImode, 4));
1300 DONE;
1301 }
1302 }")
1303
1304 (define_insn ""
1305 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1306 (div:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1307 (match_operand:SI 2 "gpc_reg_operand" "r")))
1308 (set (match_operand:SI 3 "gpc_reg_operand" "=q")
1309 (mod:SI (match_dup 1) (match_dup 2)))]
1310 "TARGET_POWER"
1311 "divs %0,%1,%2"
1312 [(set_attr "type" "idiv")])
1313
1314 (define_insn ""
1315 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1316 (div:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1317 (match_operand:SI 2 "gpc_reg_operand" "r")))]
1318 "TARGET_POWERPC"
1319 "divw %0,%1,%2"
1320 [(set_attr "type" "idiv")])
1321
1322 (define_expand "udivsi3"
1323 [(set (match_operand:SI 0 "gpc_reg_operand" "")
1324 (udiv:SI (match_operand:SI 1 "gpc_reg_operand" "")
1325 (match_operand:SI 2 "gpc_reg_operand" "")))]
1326 "TARGET_POWERPC || (! TARGET_POWER && ! TARGET_POWERPC)"
1327 "
1328 {
1329 if (! TARGET_POWER && ! TARGET_POWERPC)
1330 {
1331 emit_move_insn (gen_rtx (REG, SImode, 3), operands[1]);
1332 emit_move_insn (gen_rtx (REG, SImode, 4), operands[2]);
1333 emit_insn (gen_quous_call ());
1334 emit_move_insn (operands[0], gen_rtx (REG, SImode, 3));
1335 DONE;
1336 }
1337 }")
1338
1339 (define_insn ""
1340 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1341 (udiv:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1342 (match_operand:SI 2 "gpc_reg_operand" "r")))]
1343 "TARGET_POWERPC"
1344 "divwu %0,%1,%2"
1345 [(set_attr "type" "idiv")])
1346
1347 ;; For powers of two we can do srai/aze for divide and then adjust for
1348 ;; modulus. If it isn't a power of two, FAIL on POWER so divmodsi4 will be
1349 ;; used; for PowerPC, force operands into register and do a normal divide;
1350 ;; for AIX common-mode, use quoss call on register operands.
1351 (define_expand "divsi3"
1352 [(set (match_operand:SI 0 "gpc_reg_operand" "")
1353 (div:SI (match_operand:SI 1 "gpc_reg_operand" "")
1354 (match_operand:SI 2 "reg_or_cint_operand" "")))]
1355 ""
1356 "
1357 {
1358 if (GET_CODE (operands[2]) == CONST_INT
1359 && exact_log2 (INTVAL (operands[2])) >= 0)
1360 ;
1361 else if (TARGET_POWERPC)
1362 operands[2] = force_reg (SImode, operands[2]);
1363 else if (TARGET_POWER)
1364 FAIL;
1365 else
1366 {
1367 emit_move_insn (gen_rtx (REG, SImode, 3), operands[1]);
1368 emit_move_insn (gen_rtx (REG, SImode, 4), operands[2]);
1369 emit_insn (gen_quoss_call ());
1370 emit_move_insn (operands[0], gen_rtx (REG, SImode, 3));
1371 DONE;
1372 }
1373 }")
1374
1375 (define_expand "modsi3"
1376 [(use (match_operand:SI 0 "gpc_reg_operand" ""))
1377 (use (match_operand:SI 1 "gpc_reg_operand" ""))
1378 (use (match_operand:SI 2 "reg_or_cint_operand" ""))]
1379 ""
1380 "
1381 {
1382 int i = exact_log2 (INTVAL (operands[2]));
1383 rtx temp1;
1384 rtx temp2;
1385
1386 if (GET_CODE (operands[2]) != CONST_INT || i < 0)
1387 FAIL;
1388
1389 temp1 = gen_reg_rtx (SImode);
1390 temp2 = gen_reg_rtx (SImode);
1391
1392 emit_insn (gen_divsi3 (temp1, operands[1], operands[2]));
1393 emit_insn (gen_ashlsi3 (temp2, temp1, GEN_INT (i)));
1394 emit_insn (gen_subsi3 (operands[0], operands[1], temp2));
1395 DONE;
1396 }")
1397
1398 (define_insn ""
1399 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1400 (div:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1401 (match_operand:SI 2 "const_int_operand" "N")))]
1402 "exact_log2 (INTVAL (operands[2])) >= 0"
1403 "{srai|srawi} %0,%1,%p2\;{aze|addze} %0,%0"
1404 [(set_attr "length" "8")])
1405
1406 (define_insn ""
1407 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
1408 (compare:CC (div:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1409 (match_operand:SI 2 "const_int_operand" "N"))
1410 (const_int 0)))
1411 (clobber (match_scratch:SI 3 "=r"))]
1412 "exact_log2 (INTVAL (operands[2])) >= 0"
1413 "{srai|srawi} %3,%1,%p2\;{aze.|addze.} %3,%3"
1414 [(set_attr "type" "compare")
1415 (set_attr "length" "8")])
1416
1417 (define_insn ""
1418 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1419 (compare:CC (div:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1420 (match_operand:SI 2 "const_int_operand" "N"))
1421 (const_int 0)))
1422 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1423 (div:SI (match_dup 1) (match_dup 2)))]
1424 "exact_log2 (INTVAL (operands[2])) >= 0"
1425 "{srai|srawi} %0,%1,%p2\;{aze.|addze.} %0,%0"
1426 [(set_attr "type" "compare")
1427 (set_attr "length" "8")])
1428
1429 (define_insn ""
1430 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1431 (udiv:SI
1432 (plus:DI (ashift:DI
1433 (zero_extend:DI (match_operand:SI 1 "gpc_reg_operand" "r"))
1434 (const_int 32))
1435 (zero_extend:DI (match_operand:SI 4 "register_operand" "2")))
1436 (match_operand:SI 3 "gpc_reg_operand" "r")))
1437 (set (match_operand:SI 2 "register_operand" "=*q")
1438 (umod:SI
1439 (plus:DI (ashift:DI
1440 (zero_extend:DI (match_dup 1)) (const_int 32))
1441 (zero_extend:DI (match_dup 4)))
1442 (match_dup 3)))]
1443 "TARGET_POWER"
1444 "div %0,%1,%3"
1445 [(set_attr "type" "idiv")])
1446
1447 ;; To do unsigned divide we handle the cases of the divisor looking like a
1448 ;; negative number. If it is a constant that is less than 2**31, we don't
1449 ;; have to worry about the branches. So make a few subroutines here.
1450 ;;
1451 ;; First comes the normal case.
1452 (define_expand "udivmodsi4_normal"
1453 [(set (match_dup 4) (const_int 0))
1454 (parallel [(set (match_operand:SI 0 "" "")
1455 (udiv:SI (plus:DI (ashift:DI (zero_extend:DI (match_dup 4))
1456 (const_int 32))
1457 (zero_extend:DI (match_operand:SI 1 "" "")))
1458 (match_operand:SI 2 "" "")))
1459 (set (match_operand:SI 3 "" "")
1460 (umod:SI (plus:DI (ashift:DI (zero_extend:DI (match_dup 4))
1461 (const_int 32))
1462 (zero_extend:DI (match_dup 1)))
1463 (match_dup 2)))])]
1464 "TARGET_POWER"
1465 "
1466 { operands[4] = gen_reg_rtx (SImode); }")
1467
1468 ;; This handles the branches.
1469 (define_expand "udivmodsi4_tests"
1470 [(set (match_operand:SI 0 "" "") (const_int 0))
1471 (set (match_operand:SI 3 "" "") (match_operand:SI 1 "" ""))
1472 (set (match_dup 5) (compare:CCUNS (match_dup 1) (match_operand:SI 2 "" "")))
1473 (set (pc) (if_then_else (ltu (match_dup 5) (const_int 0))
1474 (label_ref (match_operand:SI 4 "" "")) (pc)))
1475 (set (match_dup 0) (const_int 1))
1476 (set (match_dup 3) (minus:SI (match_dup 1) (match_dup 2)))
1477 (set (match_dup 6) (compare:CC (match_dup 2) (const_int 0)))
1478 (set (pc) (if_then_else (lt (match_dup 6) (const_int 0))
1479 (label_ref (match_dup 4)) (pc)))]
1480 "TARGET_POWER"
1481 "
1482 { operands[5] = gen_reg_rtx (CCUNSmode);
1483 operands[6] = gen_reg_rtx (CCmode);
1484 }")
1485
1486 (define_expand "udivmodsi4"
1487 [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "")
1488 (udiv:SI (match_operand:SI 1 "gpc_reg_operand" "")
1489 (match_operand:SI 2 "reg_or_cint_operand" "")))
1490 (set (match_operand:SI 3 "gpc_reg_operand" "")
1491 (umod:SI (match_dup 1) (match_dup 2)))])]
1492 ""
1493 "
1494 {
1495 rtx label = 0;
1496
1497 if (! TARGET_POWER)
1498 if (! TARGET_POWERPC)
1499 {
1500 emit_move_insn (gen_rtx (REG, SImode, 3), operands[1]);
1501 emit_move_insn (gen_rtx (REG, SImode, 4), operands[2]);
1502 emit_insn (gen_divus_call ());
1503 emit_move_insn (operands[0], gen_rtx (REG, SImode, 3));
1504 emit_move_insn (operands[3], gen_rtx (REG, SImode, 4));
1505 DONE;
1506 }
1507 else
1508 FAIL;
1509
1510 if (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) < 0)
1511 {
1512 operands[2] = force_reg (SImode, operands[2]);
1513 label = gen_label_rtx ();
1514 emit (gen_udivmodsi4_tests (operands[0], operands[1], operands[2],
1515 operands[3], label));
1516 }
1517 else
1518 operands[2] = force_reg (SImode, operands[2]);
1519
1520 emit (gen_udivmodsi4_normal (operands[0], operands[1], operands[2],
1521 operands[3]));
1522 if (label)
1523 emit_label (label);
1524
1525 DONE;
1526 }")
1527
1528 ;; AIX architecture-independent common-mode multiply (DImode),
1529 ;; divide/modulus, and quotient subroutine calls. Input operands in R3 and
1530 ;; R4; results in R3 and sometimes R4; link register always clobbered by bla
1531 ;; instruction; R0 sometimes clobbered; also, MQ sometimes clobbered but
1532 ;; assumed unused if generating common-mode, so ignore.
1533 (define_insn "mulh_call"
1534 [(set (reg:SI 3)
1535 (truncate:SI
1536 (lshiftrt:DI (mult:DI (sign_extend:DI (reg:SI 3))
1537 (sign_extend:DI (reg:SI 4)))
1538 (const_int 32))))
1539 (clobber (match_scratch:SI 0 "=l"))]
1540 "! TARGET_POWER && ! TARGET_POWERPC"
1541 "bla __mulh")
1542
1543 (define_insn "mull_call"
1544 [(set (reg:DI 3)
1545 (mult:DI (sign_extend:DI (reg:SI 3))
1546 (sign_extend:DI (reg:SI 4))))
1547 (clobber (match_scratch:SI 0 "=l"))
1548 (clobber (reg:SI 0))]
1549 "! TARGET_POWER && ! TARGET_POWERPC"
1550 "bla __mull")
1551
1552 (define_insn "divss_call"
1553 [(set (reg:SI 3)
1554 (div:SI (reg:SI 3) (reg:SI 4)))
1555 (set (reg:SI 4)
1556 (mod:SI (reg:SI 3) (reg:SI 4)))
1557 (clobber (match_scratch:SI 0 "=l"))
1558 (clobber (reg:SI 0))]
1559 "! TARGET_POWER && ! TARGET_POWERPC"
1560 "bla __divss")
1561
1562 (define_insn "divus_call"
1563 [(set (reg:SI 3)
1564 (udiv:SI (reg:SI 3) (reg:SI 4)))
1565 (set (reg:SI 4)
1566 (umod:SI (reg:SI 3) (reg:SI 4)))
1567 (clobber (match_scratch:SI 0 "=l"))
1568 (clobber (reg:SI 0))]
1569 "! TARGET_POWER && ! TARGET_POWERPC"
1570 "bla __divus")
1571
1572 (define_insn "quoss_call"
1573 [(set (reg:SI 3)
1574 (div:SI (reg:SI 3) (reg:SI 4)))
1575 (clobber (match_scratch:SI 0 "=l"))]
1576 "! TARGET_POWER && ! TARGET_POWERPC"
1577 "bla __quoss")
1578
1579 (define_insn "quous_call"
1580 [(set (reg:SI 3)
1581 (udiv:SI (reg:SI 3) (reg:SI 4)))
1582 (clobber (match_scratch:SI 0 "=l"))
1583 (clobber (reg:SI 0))]
1584 "! TARGET_POWER && ! TARGET_POWERPC"
1585 "bla __quous")
1586 \f
1587 (define_insn "andsi3"
1588 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r")
1589 (and:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r")
1590 (match_operand:SI 2 "and_operand" "?r,L,K,J")))
1591 (clobber (match_scratch:CC 3 "=X,X,x,x"))]
1592 ""
1593 "@
1594 and %0,%1,%2
1595 {rlinm|rlwinm} %0,%1,0,%m2,%M2
1596 {andil.|andi.} %0,%1,%b2
1597 {andiu.|andis.} %0,%1,%u2")
1598
1599 (define_insn ""
1600 [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,x,x")
1601 (compare:CC (and:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r")
1602 (match_operand:SI 2 "and_operand" "r,K,J,L"))
1603 (const_int 0)))
1604 (clobber (match_scratch:SI 3 "=r,r,r,r"))]
1605 ""
1606 "@
1607 and. %3,%1,%2
1608 {andil.|andi.} %3,%1,%b2
1609 {andiu.|andis.} %3,%1,%u2
1610 {rlinm.|rlwinm.} %3,%1,0,%m2,%M2"
1611 [(set_attr "type" "compare,compare,compare,delayed_compare")])
1612
1613 (define_insn ""
1614 [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,x,x")
1615 (compare:CC (and:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r")
1616 (match_operand:SI 2 "and_operand" "r,K,J,L"))
1617 (const_int 0)))
1618 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r")
1619 (and:SI (match_dup 1) (match_dup 2)))]
1620 ""
1621 "@
1622 and. %0,%1,%2
1623 {andil.|andi.} %0,%1,%b2
1624 {andiu.|andis.} %0,%1,%u2
1625 {rlinm.|rlwinm.} %0,%1,0,%m2,%M2"
1626 [(set_attr "type" "compare,compare,compare,delayed_compare")])
1627
1628 ;; Take a AND with a constant that cannot be done in a single insn and try to
1629 ;; split it into two insns. This does not verify that the insns are valid
1630 ;; since this need not be done as combine will do it.
1631
1632 (define_split
1633 [(set (match_operand:SI 0 "gpc_reg_operand" "")
1634 (and:SI (match_operand:SI 1 "gpc_reg_operand" "")
1635 (match_operand:SI 2 "non_and_cint_operand" "")))]
1636 ""
1637 [(set (match_dup 0) (and:SI (match_dup 1) (match_dup 3)))
1638 (set (match_dup 0) (and:SI (match_dup 0) (match_dup 4)))]
1639 "
1640 {
1641 int maskval = INTVAL (operands[2]);
1642 int i, transitions, last_bit_value;
1643 int orig = maskval, first_c = maskval, second_c;
1644
1645 /* We know that MASKVAL must have more than 2 bit-transitions. Start at
1646 the low-order bit and count for the third transition. When we get there,
1647 make a first mask that has everything to the left of that position
1648 a one. Then make the second mask to turn off whatever else is needed. */
1649
1650 for (i = 1, transitions = 0, last_bit_value = maskval & 1; i < 32; i++)
1651 {
1652 if (((maskval >>= 1) & 1) != last_bit_value)
1653 last_bit_value ^= 1, transitions++;
1654
1655 if (transitions > 2)
1656 {
1657 first_c |= (~0) << i;
1658 break;
1659 }
1660 }
1661
1662 second_c = orig | ~ first_c;
1663
1664 operands[3] = gen_rtx (CONST_INT, VOIDmode, first_c);
1665 operands[4] = gen_rtx (CONST_INT, VOIDmode, second_c);
1666 }")
1667
1668 (define_insn "iorsi3"
1669 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r")
1670 (ior:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r")
1671 (match_operand:SI 2 "logical_operand" "r,K,J")))]
1672 ""
1673 "@
1674 or %0,%1,%2
1675 {oril|ori} %0,%1,%b2
1676 {oriu|oris} %0,%1,%u2")
1677
1678 (define_insn ""
1679 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
1680 (compare:CC (ior:SI (match_operand:SI 1 "gpc_reg_operand" "%r")
1681 (match_operand:SI 2 "gpc_reg_operand" "r"))
1682 (const_int 0)))
1683 (clobber (match_scratch:SI 3 "=r"))]
1684 ""
1685 "or. %3,%1,%2"
1686 [(set_attr "type" "compare")])
1687
1688 (define_insn ""
1689 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1690 (compare:CC (ior:SI (match_operand:SI 1 "gpc_reg_operand" "%r")
1691 (match_operand:SI 2 "gpc_reg_operand" "r"))
1692 (const_int 0)))
1693 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1694 (ior:SI (match_dup 1) (match_dup 2)))]
1695 ""
1696 "or. %0,%1,%2"
1697 [(set_attr "type" "compare")])
1698
1699 ;; Split an IOR that we can't do in one insn into two insns, each of which
1700 ;; does one 16-bit part. This is used by combine.
1701
1702 (define_split
1703 [(set (match_operand:SI 0 "gpc_reg_operand" "")
1704 (ior:SI (match_operand:SI 1 "gpc_reg_operand" "")
1705 (match_operand:SI 2 "non_logical_cint_operand" "")))]
1706 ""
1707 [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 3)))
1708 (set (match_dup 0) (ior:SI (match_dup 0) (match_dup 4)))]
1709 "
1710 {
1711 operands[3] = gen_rtx (CONST_INT, VOIDmode,
1712 INTVAL (operands[2]) & 0xffff0000);
1713 operands[4] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) & 0xffff);
1714 }")
1715
1716 (define_insn "xorsi3"
1717 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r")
1718 (xor:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r")
1719 (match_operand:SI 2 "logical_operand" "r,K,J")))]
1720 ""
1721 "@
1722 xor %0,%1,%2
1723 {xoril|xori} %0,%1,%b2
1724 {xoriu|xoris} %0,%1,%u2")
1725
1726 (define_insn ""
1727 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
1728 (compare:CC (xor:SI (match_operand:SI 1 "gpc_reg_operand" "%r")
1729 (match_operand:SI 2 "gpc_reg_operand" "r"))
1730 (const_int 0)))
1731 (clobber (match_scratch:SI 3 "=r"))]
1732 ""
1733 "xor. %3,%1,%2"
1734 [(set_attr "type" "compare")])
1735
1736 (define_insn ""
1737 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1738 (compare:CC (xor:SI (match_operand:SI 1 "gpc_reg_operand" "%r")
1739 (match_operand:SI 2 "gpc_reg_operand" "r"))
1740 (const_int 0)))
1741 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1742 (xor:SI (match_dup 1) (match_dup 2)))]
1743 ""
1744 "xor. %0,%1,%2"
1745 [(set_attr "type" "compare")])
1746
1747 ;; Split an XOR that we can't do in one insn into two insns, each of which
1748 ;; does one 16-bit part. This is used by combine.
1749
1750 (define_split
1751 [(set (match_operand:SI 0 "gpc_reg_operand" "")
1752 (xor:SI (match_operand:SI 1 "gpc_reg_operand" "")
1753 (match_operand:SI 2 "non_logical_cint_operand" "")))]
1754 ""
1755 [(set (match_dup 0) (xor:SI (match_dup 1) (match_dup 3)))
1756 (set (match_dup 0) (xor:SI (match_dup 0) (match_dup 4)))]
1757 "
1758 {
1759 operands[3] = gen_rtx (CONST_INT, VOIDmode,
1760 INTVAL (operands[2]) & 0xffff0000);
1761 operands[4] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) & 0xffff);
1762 }")
1763
1764 (define_insn ""
1765 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1766 (not:SI (xor:SI (match_operand:SI 1 "gpc_reg_operand" "%r")
1767 (match_operand:SI 2 "gpc_reg_operand" "r"))))]
1768 ""
1769 "eqv %0,%1,%2")
1770
1771 (define_insn ""
1772 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
1773 (compare:CC (not:SI (xor:SI (match_operand:SI 1 "gpc_reg_operand" "%r")
1774 (match_operand:SI 2 "gpc_reg_operand" "r")))
1775 (const_int 0)))
1776 (clobber (match_scratch:SI 3 "=r"))]
1777 ""
1778 "eqv. %3,%1,%2"
1779 [(set_attr "type" "compare")])
1780
1781 (define_insn ""
1782 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1783 (compare:CC (not:SI (xor:SI (match_operand:SI 1 "gpc_reg_operand" "%r")
1784 (match_operand:SI 2 "gpc_reg_operand" "r")))
1785 (const_int 0)))
1786 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1787 (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
1788 ""
1789 "eqv. %0,%1,%2"
1790 [(set_attr "type" "compare")])
1791
1792 (define_insn ""
1793 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1794 (and:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "r"))
1795 (match_operand:SI 2 "gpc_reg_operand" "r")))]
1796 ""
1797 "andc %0,%2,%1")
1798
1799 (define_insn ""
1800 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
1801 (compare:CC (and:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "r"))
1802 (match_operand:SI 2 "gpc_reg_operand" "r"))
1803 (const_int 0)))
1804 (clobber (match_scratch:SI 3 "=r"))]
1805 ""
1806 "andc. %3,%2,%1"
1807 [(set_attr "type" "compare")])
1808
1809 (define_insn ""
1810 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1811 (compare:CC (and:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "r"))
1812 (match_operand:SI 2 "gpc_reg_operand" "r"))
1813 (const_int 0)))
1814 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1815 (and:SI (not:SI (match_dup 1)) (match_dup 2)))]
1816 ""
1817 "andc. %0,%2,%1"
1818 [(set_attr "type" "compare")])
1819
1820 (define_insn ""
1821 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1822 (ior:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "r"))
1823 (match_operand:SI 2 "gpc_reg_operand" "r")))]
1824 ""
1825 "orc %0,%2,%1")
1826
1827 (define_insn ""
1828 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
1829 (compare:CC (ior:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "r"))
1830 (match_operand:SI 2 "gpc_reg_operand" "r"))
1831 (const_int 0)))
1832 (clobber (match_scratch:SI 3 "=r"))]
1833 ""
1834 "orc. %3,%2,%1"
1835 [(set_attr "type" "compare")])
1836
1837 (define_insn ""
1838 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1839 (compare:CC (ior:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "r"))
1840 (match_operand:SI 2 "gpc_reg_operand" "r"))
1841 (const_int 0)))
1842 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1843 (ior:SI (not:SI (match_dup 1)) (match_dup 2)))]
1844 ""
1845 "orc. %0,%2,%1"
1846 [(set_attr "type" "compare")])
1847
1848 (define_insn ""
1849 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1850 (ior:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "%r"))
1851 (not:SI (match_operand:SI 2 "gpc_reg_operand" "r"))))]
1852 ""
1853 "nand %0,%1,%2")
1854
1855 (define_insn ""
1856 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
1857 (compare:CC (ior:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "%r"))
1858 (not:SI (match_operand:SI 2 "gpc_reg_operand" "r")))
1859 (const_int 0)))
1860 (clobber (match_scratch:SI 3 "=r"))]
1861 ""
1862 "nand. %3,%1,%2"
1863 [(set_attr "type" "compare")])
1864
1865 (define_insn ""
1866 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1867 (compare:CC (ior:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "%r"))
1868 (not:SI (match_operand:SI 2 "gpc_reg_operand" "r")))
1869 (const_int 0)))
1870 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1871 (ior:SI (not:SI (match_dup 1)) (not:SI (match_dup 2))))]
1872 ""
1873 "nand. %0,%1,%2"
1874 [(set_attr "type" "compare")])
1875
1876 (define_insn ""
1877 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1878 (and:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "%r"))
1879 (not:SI (match_operand:SI 2 "gpc_reg_operand" "r"))))]
1880 ""
1881 "nor %0,%1,%2")
1882
1883 (define_insn ""
1884 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
1885 (compare:CC (and:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "%r"))
1886 (not:SI (match_operand:SI 2 "gpc_reg_operand" "r")))
1887 (const_int 0)))
1888 (clobber (match_scratch:SI 3 "=r"))]
1889 ""
1890 "nor. %3,%1,%2"
1891 [(set_attr "type" "compare")])
1892
1893 (define_insn ""
1894 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1895 (compare:CC (and:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "%r"))
1896 (not:SI (match_operand:SI 2 "gpc_reg_operand" "r")))
1897 (const_int 0)))
1898 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1899 (and:SI (not:SI (match_dup 1)) (not:SI (match_dup 2))))]
1900 ""
1901 "nor. %0,%1,%2"
1902 [(set_attr "type" "compare")])
1903
1904 ;; maskir insn. We need four forms because things might be in arbitrary
1905 ;; orders. Don't define forms that only set CR fields because these
1906 ;; would modify an input register.
1907
1908 (define_insn ""
1909 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1910 (ior:SI (and:SI (not:SI (match_operand:SI 2 "gpc_reg_operand" "r"))
1911 (match_operand:SI 1 "gpc_reg_operand" "0"))
1912 (and:SI (match_dup 2)
1913 (match_operand:SI 3 "gpc_reg_operand" "r"))))]
1914 "TARGET_POWER"
1915 "maskir %0,%3,%2")
1916
1917 (define_insn ""
1918 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1919 (ior:SI (and:SI (not:SI (match_operand:SI 2 "gpc_reg_operand" "r"))
1920 (match_operand:SI 1 "gpc_reg_operand" "0"))
1921 (and:SI (match_operand:SI 3 "gpc_reg_operand" "r")
1922 (match_dup 2))))]
1923 "TARGET_POWER"
1924 "maskir %0,%3,%2")
1925
1926 (define_insn ""
1927 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1928 (ior:SI (and:SI (match_operand:SI 2 "gpc_reg_operand" "r")
1929 (match_operand:SI 3 "gpc_reg_operand" "r"))
1930 (and:SI (not:SI (match_dup 2))
1931 (match_operand:SI 1 "gpc_reg_operand" "0"))))]
1932 "TARGET_POWER"
1933 "maskir %0,%3,%2")
1934
1935 (define_insn ""
1936 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1937 (ior:SI (and:SI (match_operand:SI 3 "gpc_reg_operand" "r")
1938 (match_operand:SI 2 "gpc_reg_operand" "r"))
1939 (and:SI (not:SI (match_dup 2))
1940 (match_operand:SI 1 "gpc_reg_operand" "0"))))]
1941 "TARGET_POWER"
1942 "maskir %0,%3,%2")
1943
1944 (define_insn ""
1945 [(set (match_operand:CC 4 "cc_reg_operand" "=x")
1946 (compare:CC
1947 (ior:SI (and:SI (not:SI (match_operand:SI 2 "gpc_reg_operand" "r"))
1948 (match_operand:SI 1 "gpc_reg_operand" "0"))
1949 (and:SI (match_dup 2)
1950 (match_operand:SI 3 "gpc_reg_operand" "r")))
1951 (const_int 0)))
1952 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1953 (ior:SI (and:SI (not:SI (match_dup 2)) (match_dup 1))
1954 (and:SI (match_dup 2) (match_dup 3))))]
1955 "TARGET_POWER"
1956 "maskir. %0,%3,%2"
1957 [(set_attr "type" "compare")])
1958
1959 (define_insn ""
1960 [(set (match_operand:CC 4 "cc_reg_operand" "=x")
1961 (compare:CC
1962 (ior:SI (and:SI (not:SI (match_operand:SI 2 "gpc_reg_operand" "r"))
1963 (match_operand:SI 1 "gpc_reg_operand" "0"))
1964 (and:SI (match_operand:SI 3 "gpc_reg_operand" "r")
1965 (match_dup 2)))
1966 (const_int 0)))
1967 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1968 (ior:SI (and:SI (not:SI (match_dup 2)) (match_dup 1))
1969 (and:SI (match_dup 3) (match_dup 2))))]
1970 "TARGET_POWER"
1971 "maskir. %0,%3,%2"
1972 [(set_attr "type" "compare")])
1973
1974 (define_insn ""
1975 [(set (match_operand:CC 4 "cc_reg_operand" "=x")
1976 (compare:CC
1977 (ior:SI (and:SI (match_operand:SI 2 "gpc_reg_operand" "r")
1978 (match_operand:SI 3 "gpc_reg_operand" "r"))
1979 (and:SI (not:SI (match_dup 2))
1980 (match_operand:SI 1 "gpc_reg_operand" "0")))
1981 (const_int 0)))
1982 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1983 (ior:SI (and:SI (match_dup 2) (match_dup 3))
1984 (and:SI (not:SI (match_dup 2)) (match_dup 1))))]
1985 "TARGET_POWER"
1986 "maskir. %0,%3,%2"
1987 [(set_attr "type" "compare")])
1988
1989 (define_insn ""
1990 [(set (match_operand:CC 4 "cc_reg_operand" "=x")
1991 (compare:CC
1992 (ior:SI (and:SI (match_operand:SI 3 "gpc_reg_operand" "r")
1993 (match_operand:SI 2 "gpc_reg_operand" "r"))
1994 (and:SI (not:SI (match_dup 2))
1995 (match_operand:SI 1 "gpc_reg_operand" "0")))
1996 (const_int 0)))
1997 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1998 (ior:SI (and:SI (match_dup 3) (match_dup 2))
1999 (and:SI (not:SI (match_dup 2)) (match_dup 1))))]
2000 "TARGET_POWER"
2001 "maskir. %0,%3,%2"
2002 [(set_attr "type" "compare")])
2003 \f
2004 ;; Rotate and shift insns, in all their variants. These support shifts,
2005 ;; field inserts and extracts, and various combinations thereof.
2006 (define_expand "insv"
2007 [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r")
2008 (match_operand:SI 1 "const_int_operand" "i")
2009 (match_operand:SI 2 "const_int_operand" "i"))
2010 (match_operand:SI 3 "gpc_reg_operand" "r"))]
2011 ""
2012 "
2013 {
2014 /* Do not handle 16/8 bit structures that fit in HI/QI modes directly, since
2015 the (SUBREG:SI (REG:HI xxx)) that is otherwise generated can confuse the
2016 compiler if the address of the structure is taken later. */
2017 if (GET_CODE (operands[0]) == SUBREG
2018 && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (operands[0]))) < UNITS_PER_WORD))
2019 FAIL;
2020 }")
2021
2022 (define_insn ""
2023 [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r")
2024 (match_operand:SI 1 "const_int_operand" "i")
2025 (match_operand:SI 2 "const_int_operand" "i"))
2026 (match_operand:SI 3 "gpc_reg_operand" "r"))]
2027 ""
2028 "*
2029 {
2030 int start = INTVAL (operands[2]) & 31;
2031 int size = INTVAL (operands[1]) & 31;
2032
2033 operands[4] = gen_rtx (CONST_INT, VOIDmode, 32 - start - size);
2034 operands[1] = gen_rtx (CONST_INT, VOIDmode, start + size - 1);
2035 return \"{rlimi|rlwimi} %0,%3,%4,%h2,%h1\";
2036 }")
2037
2038 (define_insn ""
2039 [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r")
2040 (match_operand:SI 1 "const_int_operand" "i")
2041 (match_operand:SI 2 "const_int_operand" "i"))
2042 (ashift:SI (match_operand:SI 3 "gpc_reg_operand" "r")
2043 (match_operand:SI 4 "const_int_operand" "i")))]
2044 ""
2045 "*
2046 {
2047 int shift = INTVAL (operands[4]) & 31;
2048 int start = INTVAL (operands[2]) & 31;
2049 int size = INTVAL (operands[1]) & 31;
2050
2051 operands[4] = gen_rtx (CONST_INT, VOIDmode, (shift - start - size) & 31);
2052 operands[1] = gen_rtx (CONST_INT, VOIDmode, start + size - 1);
2053 return \"{rlimi|rlwimi} %0,%3,%4,%h2,%h1\";
2054 }")
2055
2056 (define_insn ""
2057 [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r")
2058 (match_operand:SI 1 "const_int_operand" "i")
2059 (match_operand:SI 2 "const_int_operand" "i"))
2060 (ashiftrt:SI (match_operand:SI 3 "gpc_reg_operand" "r")
2061 (match_operand:SI 4 "const_int_operand" "i")))]
2062 ""
2063 "*
2064 {
2065 int shift = INTVAL (operands[4]) & 31;
2066 int start = INTVAL (operands[2]) & 31;
2067 int size = INTVAL (operands[1]) & 31;
2068
2069 operands[4] = gen_rtx (CONST_INT, VOIDmode, (32 - shift - start - size) & 31);
2070 operands[1] = gen_rtx (CONST_INT, VOIDmode, start + size - 1);
2071 return \"{rlimi|rlwimi} %0,%3,%4,%h2,%h1\";
2072 }")
2073
2074 (define_insn ""
2075 [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r")
2076 (match_operand:SI 1 "const_int_operand" "i")
2077 (match_operand:SI 2 "const_int_operand" "i"))
2078 (lshiftrt:SI (match_operand:SI 3 "gpc_reg_operand" "r")
2079 (match_operand:SI 4 "const_int_operand" "i")))]
2080 ""
2081 "*
2082 {
2083 int shift = INTVAL (operands[4]) & 31;
2084 int start = INTVAL (operands[2]) & 31;
2085 int size = INTVAL (operands[1]) & 31;
2086
2087 operands[4] = gen_rtx (CONST_INT, VOIDmode, (32 - shift - start - size) & 31);
2088 operands[1] = gen_rtx (CONST_INT, VOIDmode, start + size - 1);
2089 return \"{rlimi|rlwimi} %0,%3,%4,%h2,%h1\";
2090 }")
2091
2092 (define_insn ""
2093 [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r")
2094 (match_operand:SI 1 "const_int_operand" "i")
2095 (match_operand:SI 2 "const_int_operand" "i"))
2096 (zero_extract:SI (match_operand:SI 3 "gpc_reg_operand" "r")
2097 (match_operand:SI 4 "const_int_operand" "i")
2098 (match_operand:SI 5 "const_int_operand" "i")))]
2099 "INTVAL (operands[4]) >= INTVAL (operands[1])"
2100 "*
2101 {
2102 int extract_start = INTVAL (operands[5]) & 31;
2103 int extract_size = INTVAL (operands[4]) & 31;
2104 int insert_start = INTVAL (operands[2]) & 31;
2105 int insert_size = INTVAL (operands[1]) & 31;
2106
2107 /* Align extract field with insert field */
2108 operands[5] = gen_rtx (CONST_INT, VOIDmode,
2109 (extract_start + extract_size - insert_start - insert_size) & 31);
2110 operands[1] = gen_rtx (CONST_INT, VOIDmode, insert_start + insert_size - 1);
2111 return \"{rlimi|rlwimi} %0,%3,%5,%h2,%h1\";
2112 }")
2113
2114 (define_expand "extzv"
2115 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2116 (zero_extract:SI (match_operand:SI 1 "gpc_reg_operand" "r")
2117 (match_operand:SI 2 "const_int_operand" "i")
2118 (match_operand:SI 3 "const_int_operand" "i")))]
2119 ""
2120 "
2121 {
2122 /* Do not handle 16/8 bit structures that fit in HI/QI modes directly, since
2123 the (SUBREG:SI (REG:HI xxx)) that is otherwise generated can confuse the
2124 compiler if the address of the structure is taken later. */
2125 if (GET_CODE (operands[0]) == SUBREG
2126 && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (operands[0]))) < UNITS_PER_WORD))
2127 FAIL;
2128 }")
2129
2130 (define_insn ""
2131 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2132 (zero_extract:SI (match_operand:SI 1 "gpc_reg_operand" "r")
2133 (match_operand:SI 2 "const_int_operand" "i")
2134 (match_operand:SI 3 "const_int_operand" "i")))]
2135 ""
2136 "*
2137 {
2138 int start = INTVAL (operands[3]) & 31;
2139 int size = INTVAL (operands[2]) & 31;
2140
2141 if (start + size >= 32)
2142 operands[3] = const0_rtx;
2143 else
2144 operands[3] = gen_rtx (CONST_INT, VOIDmode, start + size);
2145 return \"{rlinm|rlwinm} %0,%1,%3,%s2,31\";
2146 }")
2147
2148 (define_insn ""
2149 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
2150 (compare:CC (zero_extract:SI (match_operand:SI 1 "gpc_reg_operand" "r")
2151 (match_operand:SI 2 "const_int_operand" "i")
2152 (match_operand:SI 3 "const_int_operand" "i"))
2153 (const_int 0)))
2154 (clobber (match_scratch:SI 4 "=r"))]
2155 ""
2156 "*
2157 {
2158 int start = INTVAL (operands[3]) & 31;
2159 int size = INTVAL (operands[2]) & 31;
2160
2161 /* If the bitfield being tested fits in the upper or lower half of a
2162 word, it is possible to use andiu. or andil. to test it. This is
2163 useful because the condition register set-use delay is smaller for
2164 andi[ul]. than for rlinm. This doesn't work when the starting bit
2165 position is 0 because the LT and GT bits may be set wrong. */
2166
2167 if ((start > 0 && start + size <= 16) || start >= 16)
2168 {
2169 operands[3] = gen_rtx (CONST_INT, VOIDmode,
2170 ((1 << (16 - (start & 15)))
2171 - (1 << (16 - (start & 15) - size))));
2172 if (start < 16)
2173 return \"{andiu.|andis.} %4,%1,%3\";
2174 else
2175 return \"{andil.|andi.} %4,%1,%3\";
2176 }
2177
2178 if (start + size >= 32)
2179 operands[3] = const0_rtx;
2180 else
2181 operands[3] = gen_rtx (CONST_INT, VOIDmode, start + size);
2182 return \"{rlinm.|rlwinm.} %4,%1,%3,%s2,31\";
2183 }"
2184 [(set_attr "type" "compare")])
2185
2186 (define_insn ""
2187 [(set (match_operand:CC 4 "cc_reg_operand" "=x")
2188 (compare:CC (zero_extract:SI (match_operand:SI 1 "gpc_reg_operand" "r")
2189 (match_operand:SI 2 "const_int_operand" "i")
2190 (match_operand:SI 3 "const_int_operand" "i"))
2191 (const_int 0)))
2192 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
2193 (zero_extract:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
2194 ""
2195 "*
2196 {
2197 int start = INTVAL (operands[3]) & 31;
2198 int size = INTVAL (operands[2]) & 31;
2199
2200 if (start >= 16 && start + size == 32)
2201 {
2202 operands[3] = gen_rtx (CONST_INT, VOIDmode, (1 << (32 - start)) - 1);
2203 return \"{andil.|andi.} %0,%1,%3\";
2204 }
2205
2206 if (start + size >= 32)
2207 operands[3] = const0_rtx;
2208 else
2209 operands[3] = gen_rtx (CONST_INT, VOIDmode, start + size);
2210 return \"{rlinm.|rlwinm.} %0,%1,%3,%s2,31\";
2211 }"
2212 [(set_attr "type" "delayed_compare")])
2213
2214 (define_insn "rotlsi3"
2215 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2216 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
2217 (match_operand:SI 2 "reg_or_cint_operand" "ri")))]
2218 ""
2219 "{rl%I2nm|rlw%I2nm} %0,%1,%h2,0xffffffff")
2220
2221 (define_insn ""
2222 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
2223 (compare:CC (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
2224 (match_operand:SI 2 "reg_or_cint_operand" "ri"))
2225 (const_int 0)))
2226 (clobber (match_scratch:SI 3 "=r"))]
2227 ""
2228 "{rl%I2nm.|rlw%I2nm.} %3,%1,%h2,0xffffffff"
2229 [(set_attr "type" "delayed_compare")])
2230
2231 (define_insn ""
2232 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
2233 (compare:CC (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
2234 (match_operand:SI 2 "reg_or_cint_operand" "ri"))
2235 (const_int 0)))
2236 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
2237 (rotate:SI (match_dup 1) (match_dup 2)))]
2238 ""
2239 "{rl%I2nm.|rlw%I2nm.} %0,%1,%h2,0xffffffff"
2240 [(set_attr "type" "delayed_compare")])
2241
2242 (define_insn ""
2243 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2244 (and:SI (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
2245 (match_operand:SI 2 "reg_or_cint_operand" "ri"))
2246 (match_operand:SI 3 "mask_operand" "L")))]
2247 ""
2248 "{rl%I2nm|rlw%I2nm} %0,%1,%h2,%m3,%M3")
2249
2250 (define_insn ""
2251 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
2252 (compare:CC (and:SI
2253 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
2254 (match_operand:SI 2 "reg_or_cint_operand" "ri"))
2255 (match_operand:SI 3 "mask_operand" "L"))
2256 (const_int 0)))
2257 (clobber (match_scratch:SI 4 "=r"))]
2258 ""
2259 "{rl%I2nm.|rlw%I2nm.} %4,%1,%h2,%m3,%M3"
2260 [(set_attr "type" "delayed_compare")])
2261
2262 (define_insn ""
2263 [(set (match_operand:CC 4 "cc_reg_operand" "=x")
2264 (compare:CC (and:SI
2265 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
2266 (match_operand:SI 2 "reg_or_cint_operand" "ri"))
2267 (match_operand:SI 3 "mask_operand" "L"))
2268 (const_int 0)))
2269 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
2270 (and:SI (rotate:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
2271 ""
2272 "{rl%I2nm.|rlw%I2nm.} %0,%1,%h2,%m3,%M3"
2273 [(set_attr "type" "delayed_compare")])
2274
2275 (define_insn ""
2276 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2277 (zero_extend:SI
2278 (subreg:QI
2279 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
2280 (match_operand:SI 2 "reg_or_cint_operand" "ri")) 0)))]
2281 ""
2282 "{rl%I2nm|rlw%I2nm} %0,%1,%h2,0xff")
2283
2284 (define_insn ""
2285 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
2286 (compare:CC (zero_extend:SI
2287 (subreg:QI
2288 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
2289 (match_operand:SI 2 "reg_or_cint_operand" "ri")) 0))
2290 (const_int 0)))
2291 (clobber (match_scratch:SI 3 "=r"))]
2292 ""
2293 "{rl%I2nm.|rlw%I2nm.} %3,%1,%h2,0xff"
2294 [(set_attr "type" "delayed_compare")])
2295
2296 (define_insn ""
2297 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
2298 (compare:CC (zero_extend:SI
2299 (subreg:QI
2300 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
2301 (match_operand:SI 2 "reg_or_cint_operand" "ri")) 0))
2302 (const_int 0)))
2303 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
2304 (zero_extend:SI (subreg:QI (rotate:SI (match_dup 1) (match_dup 2)) 0)))]
2305 ""
2306 "{rl%I2nm.|rlw%I2nm.} %0,%1,%h2,0xff"
2307 [(set_attr "type" "delayed_compare")])
2308
2309 (define_insn ""
2310 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2311 (zero_extend:SI
2312 (subreg:HI
2313 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
2314 (match_operand:SI 2 "reg_or_cint_operand" "ri")) 0)))]
2315 ""
2316 "{rl%I2nm|rlw%I2nm} %0,%1,%h2,0xffff")
2317
2318 (define_insn ""
2319 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
2320 (compare:CC (zero_extend:SI
2321 (subreg:HI
2322 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
2323 (match_operand:SI 2 "reg_or_cint_operand" "ri")) 0))
2324 (const_int 0)))
2325 (clobber (match_scratch:SI 3 "=r"))]
2326 ""
2327 "{rl%I2nm.|rlw%I2nm.} %3,%1,%h2,0xffff"
2328 [(set_attr "type" "delayed_compare")])
2329
2330 (define_insn ""
2331 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
2332 (compare:CC (zero_extend:SI
2333 (subreg:HI
2334 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
2335 (match_operand:SI 2 "reg_or_cint_operand" "ri")) 0))
2336 (const_int 0)))
2337 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
2338 (zero_extend:SI (subreg:HI (rotate:SI (match_dup 1) (match_dup 2)) 0)))]
2339 ""
2340 "{rl%I2nm.|rlw%I2nm.} %0,%1,%h2,0xffff"
2341 [(set_attr "type" "delayed_compare")])
2342
2343 ;; Note that we use "sle." instead of "sl." so that we can set
2344 ;; SHIFT_COUNT_TRUNCATED.
2345
2346 (define_expand "ashlsi3"
2347 [(use (match_operand:SI 0 "gpc_reg_operand" ""))
2348 (use (match_operand:SI 1 "gpc_reg_operand" ""))
2349 (use (match_operand:SI 2 "reg_or_cint_operand" ""))]
2350 ""
2351 "
2352 {
2353 if (TARGET_POWER)
2354 emit_insn (gen_ashlsi3_power (operands[0], operands[1], operands[2]));
2355 else
2356 emit_insn (gen_ashlsi3_no_power (operands[0], operands[1], operands[2]));
2357 DONE;
2358 }")
2359
2360 (define_insn "ashlsi3_power"
2361 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
2362 (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
2363 (match_operand:SI 2 "reg_or_cint_operand" "r,i")))
2364 (clobber (match_scratch:SI 3 "=q,X"))]
2365 "TARGET_POWER"
2366 "@
2367 sle %0,%1,%2
2368 {sli|slwi} %0,%1,%h2"
2369 [(set_attr "length" "8")])
2370
2371 (define_insn "ashlsi3_no_power"
2372 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2373 (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r")
2374 (match_operand:SI 2 "reg_or_cint_operand" "ri")))]
2375 "! TARGET_POWER"
2376 "{sl|slw}%I2 %0,%1,%h2"
2377 [(set_attr "length" "8")])
2378
2379 (define_insn ""
2380 [(set (match_operand:CC 0 "cc_reg_operand" "=x,x")
2381 (compare:CC (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
2382 (match_operand:SI 2 "reg_or_cint_operand" "r,i"))
2383 (const_int 0)))
2384 (clobber (match_scratch:SI 3 "=r,r"))
2385 (clobber (match_scratch:SI 4 "=q,X"))]
2386 "TARGET_POWER"
2387 "@
2388 sle. %3,%1,%2
2389 {sli.|slwi.} %3,%1,%h2"
2390 [(set_attr "type" "delayed_compare")])
2391
2392 (define_insn ""
2393 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
2394 (compare:CC (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r")
2395 (match_operand:SI 2 "reg_or_cint_operand" "ri"))
2396 (const_int 0)))
2397 (clobber (match_scratch:SI 3 "=r"))]
2398 "! TARGET_POWER"
2399 "{sl|slw}%I2. %3,%1,%h2"
2400 [(set_attr "type" "delayed_compare")])
2401
2402 (define_insn ""
2403 [(set (match_operand:CC 3 "cc_reg_operand" "=x,x")
2404 (compare:CC (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
2405 (match_operand:SI 2 "reg_or_cint_operand" "r,i"))
2406 (const_int 0)))
2407 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
2408 (ashift:SI (match_dup 1) (match_dup 2)))
2409 (clobber (match_scratch:SI 4 "=q,X"))]
2410 "TARGET_POWER"
2411 "@
2412 sle. %0,%1,%2
2413 {sli.|slwi.} %0,%1,%h2"
2414 [(set_attr "type" "delayed_compare")])
2415
2416 (define_insn ""
2417 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
2418 (compare:CC (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r")
2419 (match_operand:SI 2 "reg_or_cint_operand" "ri"))
2420 (const_int 0)))
2421 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
2422 (ashift:SI (match_dup 1) (match_dup 2)))]
2423 "! TARGET_POWER"
2424 "{sl|slw}%I2. %0,%1,%h2"
2425 [(set_attr "type" "delayed_compare")])
2426
2427 (define_insn ""
2428 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2429 (and:SI (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r")
2430 (match_operand:SI 2 "const_int_operand" "i"))
2431 (match_operand:SI 3 "mask_operand" "L")))]
2432 "includes_lshift_p (operands[2], operands[3])"
2433 "{rlinm|rlwinm} %0,%1,%h2,%m3,%M3")
2434
2435 (define_insn ""
2436 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
2437 (compare:CC
2438 (and:SI (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r")
2439 (match_operand:SI 2 "const_int_operand" "i"))
2440 (match_operand:SI 3 "mask_operand" "L"))
2441 (const_int 0)))
2442 (clobber (match_scratch:SI 4 "=r"))]
2443 "includes_lshift_p (operands[2], operands[3])"
2444 "{rlinm.|rlwinm.} %4,%1,%h2,%m3,%M3"
2445 [(set_attr "type" "delayed_compare")])
2446
2447 (define_insn ""
2448 [(set (match_operand:CC 4 "cc_reg_operand" "=x")
2449 (compare:CC
2450 (and:SI (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r")
2451 (match_operand:SI 2 "const_int_operand" "i"))
2452 (match_operand:SI 3 "mask_operand" "L"))
2453 (const_int 0)))
2454 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
2455 (and:SI (ashift:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
2456 "includes_lshift_p (operands[2], operands[3])"
2457 "{rlinm.|rlwinm.} %0,%1,%h2,%m3,%M3"
2458 [(set_attr "type" "delayed_compare")])
2459
2460 ;; The AIX assembler mis-handles "sri x,x,0", so write that case as
2461 ;; "sli x,x,0".
2462 (define_expand "lshrsi3"
2463 [(use (match_operand:SI 0 "gpc_reg_operand" ""))
2464 (use (match_operand:SI 1 "gpc_reg_operand" ""))
2465 (use (match_operand:SI 2 "reg_or_cint_operand" ""))]
2466 ""
2467 "
2468 {
2469 if (TARGET_POWER)
2470 emit_insn (gen_lshrsi3_power (operands[0], operands[1], operands[2]));
2471 else
2472 emit_insn (gen_lshrsi3_no_power (operands[0], operands[1], operands[2]));
2473 DONE;
2474 }")
2475
2476 (define_insn "lshrsi3_power"
2477 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
2478 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
2479 (match_operand:SI 2 "reg_or_cint_operand" "r,i")))
2480 (clobber (match_scratch:SI 3 "=q,X"))]
2481 "TARGET_POWER"
2482 "@
2483 sre %0,%1,%2
2484 {s%A2i|s%A2wi} %0,%1,%h2")
2485
2486 (define_insn "lshrsi3_no_power"
2487 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2488 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
2489 (match_operand:SI 2 "reg_or_cint_operand" "ri")))]
2490 "! TARGET_POWER"
2491 "{sr|srw}%I2 %0,%1,%h2")
2492
2493 (define_insn ""
2494 [(set (match_operand:CC 0 "cc_reg_operand" "=x,x")
2495 (compare:CC (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
2496 (match_operand:SI 2 "reg_or_cint_operand" "r,i"))
2497 (const_int 0)))
2498 (clobber (match_scratch:SI 3 "=r,r"))
2499 (clobber (match_scratch:SI 4 "=q,X"))]
2500 "TARGET_POWER"
2501 "@
2502 sre. %3,%1,%2
2503 {s%A2i.|s%A2wi.} %3,%1,%h2"
2504 [(set_attr "type" "delayed_compare")])
2505
2506 (define_insn ""
2507 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
2508 (compare:CC (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
2509 (match_operand:SI 2 "reg_or_cint_operand" "ri"))
2510 (const_int 0)))
2511 (clobber (match_scratch:SI 3 "=r"))]
2512 "! TARGET_POWER"
2513 "{sr|srw}%I2. %3,%1,%h2"
2514 [(set_attr "type" "delayed_compare")])
2515
2516 (define_insn ""
2517 [(set (match_operand:CC 3 "cc_reg_operand" "=x,x")
2518 (compare:CC (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
2519 (match_operand:SI 2 "reg_or_cint_operand" "r,i"))
2520 (const_int 0)))
2521 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
2522 (lshiftrt:SI (match_dup 1) (match_dup 2)))
2523 (clobber (match_scratch:SI 4 "=q,X"))]
2524 "TARGET_POWER"
2525 "@
2526 sre. %0,%1,%2
2527 {s%A2i.|s%A2wi.} %0,%1,%h2"
2528 [(set_attr "type" "delayed_compare")])
2529
2530 (define_insn ""
2531 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
2532 (compare:CC (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
2533 (match_operand:SI 2 "reg_or_cint_operand" "ri"))
2534 (const_int 0)))
2535 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
2536 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
2537 "! TARGET_POWER"
2538 "{sr|srw}%I2. %0,%1,%h2"
2539 [(set_attr "type" "delayed_compare")])
2540
2541 (define_insn ""
2542 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2543 (and:SI (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
2544 (match_operand:SI 2 "const_int_operand" "i"))
2545 (match_operand:SI 3 "mask_operand" "L")))]
2546 "includes_rshift_p (operands[2], operands[3])"
2547 "{rlinm|rlwinm} %0,%1,%s2,%m3,%M3")
2548
2549 (define_insn ""
2550 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
2551 (compare:CC
2552 (and:SI (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
2553 (match_operand:SI 2 "const_int_operand" "i"))
2554 (match_operand:SI 3 "mask_operand" "L"))
2555 (const_int 0)))
2556 (clobber (match_scratch:SI 4 "=r"))]
2557 "includes_rshift_p (operands[2], operands[3])"
2558 "{rlinm.|rlwinm.} %4,%1,%s2,%m3,%M3"
2559 [(set_attr "type" "delayed_compare")])
2560
2561 (define_insn ""
2562 [(set (match_operand:CC 4 "cc_reg_operand" "=x")
2563 (compare:CC
2564 (and:SI (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
2565 (match_operand:SI 2 "const_int_operand" "i"))
2566 (match_operand:SI 3 "mask_operand" "L"))
2567 (const_int 0)))
2568 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
2569 (and:SI (lshiftrt:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
2570 "includes_rshift_p (operands[2], operands[3])"
2571 "{rlinm.|rlwinm.} %0,%1,%s2,%m3,%M3"
2572 [(set_attr "type" "delayed_compare")])
2573
2574 (define_insn ""
2575 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2576 (zero_extend:SI
2577 (subreg:QI
2578 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
2579 (match_operand:SI 2 "const_int_operand" "i")) 0)))]
2580 "includes_rshift_p (operands[2], gen_rtx (CONST_INT, VOIDmode, 255))"
2581 "{rlinm|rlwinm} %0,%1,%s2,0xff")
2582
2583 (define_insn ""
2584 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
2585 (compare:CC
2586 (zero_extend:SI
2587 (subreg:QI
2588 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
2589 (match_operand:SI 2 "const_int_operand" "i")) 0))
2590 (const_int 0)))
2591 (clobber (match_scratch:SI 3 "=r"))]
2592 "includes_rshift_p (operands[2], gen_rtx (CONST_INT, VOIDmode, 255))"
2593 "{rlinm.|rlwinm.} %3,%1,%s2,0xff"
2594 [(set_attr "type" "delayed_compare")])
2595
2596 (define_insn ""
2597 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
2598 (compare:CC
2599 (zero_extend:SI
2600 (subreg:QI
2601 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
2602 (match_operand:SI 2 "const_int_operand" "i")) 0))
2603 (const_int 0)))
2604 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
2605 (zero_extend:SI (subreg:QI (lshiftrt:SI (match_dup 1) (match_dup 2)) 0)))]
2606 "includes_rshift_p (operands[2], gen_rtx (CONST_INT, VOIDmode, 255))"
2607 "{rlinm.|rlwinm.} %0,%1,%s2,0xff"
2608 [(set_attr "type" "delayed_compare")])
2609
2610 (define_insn ""
2611 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2612 (zero_extend:SI
2613 (subreg:HI
2614 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
2615 (match_operand:SI 2 "const_int_operand" "i")) 0)))]
2616 "includes_rshift_p (operands[2], gen_rtx (CONST_INT, VOIDmode, 65535))"
2617 "{rlinm|rlwinm} %0,%1,%s2,0xffff")
2618
2619 (define_insn ""
2620 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
2621 (compare:CC
2622 (zero_extend:SI
2623 (subreg:HI
2624 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
2625 (match_operand:SI 2 "const_int_operand" "i")) 0))
2626 (const_int 0)))
2627 (clobber (match_scratch:SI 3 "=r"))]
2628 "includes_rshift_p (operands[2], gen_rtx (CONST_INT, VOIDmode, 65535))"
2629 "{rlinm.|rlwinm.} %3,%1,%s2,0xffff"
2630 [(set_attr "type" "delayed_compare")])
2631
2632 (define_insn ""
2633 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
2634 (compare:CC
2635 (zero_extend:SI
2636 (subreg:HI
2637 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
2638 (match_operand:SI 2 "const_int_operand" "i")) 0))
2639 (const_int 0)))
2640 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
2641 (zero_extend:SI (subreg:HI (lshiftrt:SI (match_dup 1) (match_dup 2)) 0)))]
2642 "includes_rshift_p (operands[2], gen_rtx (CONST_INT, VOIDmode, 65535))"
2643 "{rlinm.|rlwinm.} %0,%1,%s2,0xffff"
2644 [(set_attr "type" "delayed_compare")])
2645
2646 (define_insn ""
2647 [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r")
2648 (const_int 1)
2649 (match_operand:SI 1 "gpc_reg_operand" "r"))
2650 (ashiftrt:SI (match_operand:SI 2 "gpc_reg_operand" "r")
2651 (const_int 31)))]
2652 "TARGET_POWER"
2653 "rrib %0,%1,%2")
2654
2655 (define_insn ""
2656 [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r")
2657 (const_int 1)
2658 (match_operand:SI 1 "gpc_reg_operand" "r"))
2659 (lshiftrt:SI (match_operand:SI 2 "gpc_reg_operand" "r")
2660 (const_int 31)))]
2661 "TARGET_POWER"
2662 "rrib %0,%1,%2")
2663
2664 (define_insn ""
2665 [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r")
2666 (const_int 1)
2667 (match_operand:SI 1 "gpc_reg_operand" "r"))
2668 (zero_extract:SI (match_operand:SI 2 "gpc_reg_operand" "r")
2669 (const_int 1)
2670 (const_int 0)))]
2671 "TARGET_POWER"
2672 "rrib %0,%1,%2")
2673
2674 (define_expand "ashrsi3"
2675 [(set (match_operand:SI 0 "gpc_reg_operand" "")
2676 (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "")
2677 (match_operand:SI 2 "reg_or_cint_operand" "")))]
2678 ""
2679 "
2680 {
2681 if (TARGET_POWER)
2682 emit_insn (gen_ashrsi3_power (operands[0], operands[1], operands[2]));
2683 else
2684 emit_insn (gen_ashrsi3_no_power (operands[0], operands[1], operands[2]));
2685 DONE;
2686 }")
2687
2688 (define_insn "ashrsi3_power"
2689 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
2690 (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
2691 (match_operand:SI 2 "reg_or_cint_operand" "r,i")))
2692 (clobber (match_scratch:SI 3 "=q,X"))]
2693 "TARGET_POWER"
2694 "@
2695 srea %0,%1,%2
2696 {srai|srawi} %0,%1,%h2")
2697
2698 (define_insn "ashrsi3_no_power"
2699 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2700 (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
2701 (match_operand:SI 2 "reg_or_cint_operand" "ri")))]
2702 "! TARGET_POWER"
2703 "{sra|sraw}%I2 %0,%1,%h2")
2704
2705 (define_insn ""
2706 [(set (match_operand:CC 0 "cc_reg_operand" "=x,x")
2707 (compare:CC (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
2708 (match_operand:SI 2 "reg_or_cint_operand" "r,i"))
2709 (const_int 0)))
2710 (clobber (match_scratch:SI 3 "=r,r"))
2711 (clobber (match_scratch:SI 4 "=q,X"))]
2712 "TARGET_POWER"
2713 "@
2714 srea. %3,%1,%2
2715 {srai.|srawi.} %3,%1,%h2"
2716 [(set_attr "type" "delayed_compare")])
2717
2718 (define_insn ""
2719 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
2720 (compare:CC (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
2721 (match_operand:SI 2 "reg_or_cint_operand" "ri"))
2722 (const_int 0)))
2723 (clobber (match_scratch:SI 3 "=r"))]
2724 "! TARGET_POWER"
2725 "{sra|sraw}%I2. %3,%1,%h2"
2726 [(set_attr "type" "delayed_compare")])
2727
2728 (define_insn ""
2729 [(set (match_operand:CC 3 "cc_reg_operand" "=x,x")
2730 (compare:CC (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
2731 (match_operand:SI 2 "reg_or_cint_operand" "r,i"))
2732 (const_int 0)))
2733 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
2734 (ashiftrt:SI (match_dup 1) (match_dup 2)))
2735 (clobber (match_scratch:SI 4 "=q,X"))]
2736 "TARGET_POWER"
2737 "@
2738 srea. %0,%1,%2
2739 {srai.|srawi.} %0,%1,%h2"
2740 [(set_attr "type" "delayed_compare")])
2741
2742 (define_insn ""
2743 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
2744 (compare:CC (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
2745 (match_operand:SI 2 "reg_or_cint_operand" "ri"))
2746 (const_int 0)))
2747 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
2748 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
2749 "! TARGET_POWER"
2750 "{sra|sraw}%I2. %0,%1,%h2"
2751 [(set_attr "type" "delayed_compare")])
2752 \f
2753 ;; Floating-point insns, excluding normal data motion.
2754 ;;
2755 ;; PowerPC has a full set of single-precision floating point instructions.
2756 ;;
2757 ;; For the POWER architecture, we pretend that we have both SFmode and
2758 ;; DFmode insns, while, in fact, all fp insns are actually done in double.
2759 ;; The only conversions we will do will be when storing to memory. In that
2760 ;; case, we will use the "frsp" instruction before storing.
2761 ;;
2762 ;; Note that when we store into a single-precision memory location, we need to
2763 ;; use the frsp insn first. If the register being stored isn't dead, we
2764 ;; need a scratch register for the frsp. But this is difficult when the store
2765 ;; is done by reload. It is not incorrect to do the frsp on the register in
2766 ;; this case, we just lose precision that we would have otherwise gotten but
2767 ;; is not guaranteed. Perhaps this should be tightened up at some point.
2768
2769 (define_insn "extendsfdf2"
2770 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
2771 (float_extend:DF (match_operand:SF 1 "gpc_reg_operand" "f")))]
2772 "TARGET_HARD_FLOAT"
2773 "*
2774 {
2775 if (REGNO (operands[0]) == REGNO (operands[1]))
2776 return \"\";
2777 else
2778 return \"fmr %0,%1\";
2779 }"
2780 [(set_attr "type" "fp")])
2781
2782 (define_insn "truncdfsf2"
2783 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
2784 (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "f")))]
2785 "TARGET_HARD_FLOAT"
2786 "frsp %0,%1"
2787 [(set_attr "type" "fp")])
2788
2789 (define_insn "aux_truncdfsf2"
2790 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
2791 (unspec:SF [(match_operand:SF 1 "gpc_reg_operand" "f")] 0))]
2792 "! TARGET_POWERPC && TARGET_HARD_FLOAT"
2793 "frsp %0,%1"
2794 [(set_attr "type" "fp")])
2795
2796 (define_insn "negsf2"
2797 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
2798 (neg:SF (match_operand:SF 1 "gpc_reg_operand" "f")))]
2799 "TARGET_HARD_FLOAT"
2800 "fneg %0,%1"
2801 [(set_attr "type" "fp")])
2802
2803 (define_insn "abssf2"
2804 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
2805 (abs:SF (match_operand:SF 1 "gpc_reg_operand" "f")))]
2806 "TARGET_HARD_FLOAT"
2807 "fabs %0,%1"
2808 [(set_attr "type" "fp")])
2809
2810 (define_insn ""
2811 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
2812 (neg:SF (abs:SF (match_operand:SF 1 "gpc_reg_operand" "f"))))]
2813 "TARGET_HARD_FLOAT"
2814 "fnabs %0,%1"
2815 [(set_attr "type" "fp")])
2816
2817 (define_expand "addsf3"
2818 [(set (match_operand:SF 0 "gpc_reg_operand" "")
2819 (plus:SF (match_operand:SF 1 "gpc_reg_operand" "")
2820 (match_operand:SF 2 "gpc_reg_operand" "")))]
2821 "TARGET_HARD_FLOAT"
2822 "")
2823
2824 (define_insn ""
2825 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
2826 (plus:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
2827 (match_operand:SF 2 "gpc_reg_operand" "f")))]
2828 "TARGET_POWERPC && TARGET_HARD_FLOAT"
2829 "fadds %0,%1,%2"
2830 [(set_attr "type" "fp")])
2831
2832 (define_insn ""
2833 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
2834 (plus:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
2835 (match_operand:SF 2 "gpc_reg_operand" "f")))]
2836 "! TARGET_POWERPC && TARGET_HARD_FLOAT"
2837 "{fa|fadd} %0,%1,%2"
2838 [(set_attr "type" "fp")])
2839
2840 (define_expand "subsf3"
2841 [(set (match_operand:SF 0 "gpc_reg_operand" "")
2842 (minus:SF (match_operand:SF 1 "gpc_reg_operand" "")
2843 (match_operand:SF 2 "gpc_reg_operand" "")))]
2844 "TARGET_HARD_FLOAT"
2845 "")
2846
2847 (define_insn ""
2848 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
2849 (minus:SF (match_operand:SF 1 "gpc_reg_operand" "f")
2850 (match_operand:SF 2 "gpc_reg_operand" "f")))]
2851 "TARGET_POWERPC && TARGET_HARD_FLOAT"
2852 "fsubs %0,%1,%2"
2853 [(set_attr "type" "fp")])
2854
2855 (define_insn ""
2856 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
2857 (minus:SF (match_operand:SF 1 "gpc_reg_operand" "f")
2858 (match_operand:SF 2 "gpc_reg_operand" "f")))]
2859 "! TARGET_POWERPC && TARGET_HARD_FLOAT"
2860 "{fs|fsub} %0,%1,%2"
2861 [(set_attr "type" "fp")])
2862
2863 (define_expand "mulsf3"
2864 [(set (match_operand:SF 0 "gpc_reg_operand" "")
2865 (mult:SF (match_operand:SF 1 "gpc_reg_operand" "")
2866 (match_operand:SF 2 "gpc_reg_operand" "")))]
2867 "TARGET_HARD_FLOAT"
2868 "")
2869
2870 (define_insn ""
2871 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
2872 (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
2873 (match_operand:SF 2 "gpc_reg_operand" "f")))]
2874 "TARGET_POWERPC && TARGET_HARD_FLOAT"
2875 "fmuls %0,%1,%2"
2876 [(set_attr "type" "fp")])
2877
2878 (define_insn ""
2879 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
2880 (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
2881 (match_operand:SF 2 "gpc_reg_operand" "f")))]
2882 "! TARGET_POWERPC && TARGET_HARD_FLOAT"
2883 "{fm|fmul} %0,%1,%2"
2884 [(set_attr "type" "fp")])
2885
2886 (define_expand "divsf3"
2887 [(set (match_operand:SF 0 "gpc_reg_operand" "")
2888 (div:SF (match_operand:SF 1 "gpc_reg_operand" "")
2889 (match_operand:SF 2 "gpc_reg_operand" "")))]
2890 "TARGET_HARD_FLOAT"
2891 "")
2892
2893 (define_insn ""
2894 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
2895 (div:SF (match_operand:SF 1 "gpc_reg_operand" "f")
2896 (match_operand:SF 2 "gpc_reg_operand" "f")))]
2897 "TARGET_POWERPC && TARGET_HARD_FLOAT"
2898 "fdivs %0,%1,%2"
2899 [(set_attr "type" "sdiv")])
2900
2901 (define_insn ""
2902 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
2903 (div:SF (match_operand:SF 1 "gpc_reg_operand" "f")
2904 (match_operand:SF 2 "gpc_reg_operand" "f")))]
2905 "! TARGET_POWERPC && TARGET_HARD_FLOAT"
2906 "{fd|fdiv} %0,%1,%2"
2907 [(set_attr "type" "sdiv")])
2908
2909 (define_insn ""
2910 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
2911 (plus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
2912 (match_operand:SF 2 "gpc_reg_operand" "f"))
2913 (match_operand:SF 3 "gpc_reg_operand" "f")))]
2914 "TARGET_POWERPC && TARGET_HARD_FLOAT"
2915 "fmadds %0,%1,%2,%3"
2916 [(set_attr "type" "fp")])
2917
2918 (define_insn ""
2919 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
2920 (plus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
2921 (match_operand:SF 2 "gpc_reg_operand" "f"))
2922 (match_operand:SF 3 "gpc_reg_operand" "f")))]
2923 "! TARGET_POWERPC && TARGET_HARD_FLOAT"
2924 "{fma|fmadd} %0,%1,%2,%3"
2925 [(set_attr "type" "fp")])
2926
2927 (define_insn ""
2928 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
2929 (minus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
2930 (match_operand:SF 2 "gpc_reg_operand" "f"))
2931 (match_operand:SF 3 "gpc_reg_operand" "f")))]
2932 "TARGET_POWERPC && TARGET_HARD_FLOAT"
2933 "fmsubs %0,%1,%2,%3"
2934 [(set_attr "type" "fp")])
2935
2936 (define_insn ""
2937 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
2938 (minus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
2939 (match_operand:SF 2 "gpc_reg_operand" "f"))
2940 (match_operand:SF 3 "gpc_reg_operand" "f")))]
2941 "! TARGET_POWERPC && TARGET_HARD_FLOAT"
2942 "{fms|fmsub} %0,%1,%2,%3"
2943 [(set_attr "type" "fp")])
2944
2945 (define_insn ""
2946 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
2947 (neg:SF (plus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
2948 (match_operand:SF 2 "gpc_reg_operand" "f"))
2949 (match_operand:SF 3 "gpc_reg_operand" "f"))))]
2950 "TARGET_POWERPC && TARGET_HARD_FLOAT"
2951 "fnmadds %0,%1,%2,%3"
2952 [(set_attr "type" "fp")])
2953
2954 (define_insn ""
2955 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
2956 (neg:SF (plus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
2957 (match_operand:SF 2 "gpc_reg_operand" "f"))
2958 (match_operand:SF 3 "gpc_reg_operand" "f"))))]
2959 "! TARGET_POWERPC && TARGET_HARD_FLOAT"
2960 "{fnma|fnmadd} %0,%1,%2,%3"
2961 [(set_attr "type" "fp")])
2962
2963 (define_insn ""
2964 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
2965 (neg:SF (minus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
2966 (match_operand:SF 2 "gpc_reg_operand" "f"))
2967 (match_operand:SF 3 "gpc_reg_operand" "f"))))]
2968 "TARGET_POWERPC && TARGET_HARD_FLOAT"
2969 "fnmsubs %0,%1,%2,%3"
2970 [(set_attr "type" "fp")])
2971
2972 (define_insn ""
2973 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
2974 (neg:SF (minus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
2975 (match_operand:SF 2 "gpc_reg_operand" "f"))
2976 (match_operand:SF 3 "gpc_reg_operand" "f"))))]
2977 "! TARGET_POWERPC && TARGET_HARD_FLOAT"
2978 "{fnms|fnmsub} %0,%1,%2,%3"
2979 [(set_attr "type" "fp")])
2980
2981 (define_expand "sqrtsf2"
2982 [(set (match_operand:SF 0 "gpc_reg_operand" "")
2983 (sqrt:SF (match_operand:SF 1 "gpc_reg_operand" "")))]
2984 "(TARGET_PPC_GPOPT || TARGET_POWER2) && TARGET_HARD_FLOAT"
2985 "")
2986
2987 (define_insn ""
2988 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
2989 (sqrt:SF (match_operand:SF 1 "gpc_reg_operand" "f")))]
2990 "TARGET_PPC_GPOPT && TARGET_HARD_FLOAT"
2991 "fsqrts %0,%1"
2992 [(set_attr "type" "ssqrt")])
2993
2994 (define_insn ""
2995 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
2996 (sqrt:SF (match_operand:SF 1 "gpc_reg_operand" "f")))]
2997 "TARGET_POWER2 && TARGET_HARD_FLOAT"
2998 "fsqrt %0,%1"
2999 [(set_attr "type" "dsqrt")])
3000
3001 ;; For MIN, MAX, and conditional move, we use DEFINE_EXPAND's that involve a
3002 ;; fsel instruction and some auxiliary computations. Then we just have a
3003 ;; single DEFINE_INSN for fsel and the define_splits to make them if made by
3004 ;; combine.
3005 (define_expand "maxsf3"
3006 [(set (match_dup 3)
3007 (minus:SF (match_operand:SF 1 "gpc_reg_operand" "")
3008 (match_operand:SF 2 "gpc_reg_operand" "")))
3009 (set (match_operand:SF 0 "gpc_reg_operand" "")
3010 (if_then_else:SF (ge (match_dup 3)
3011 (const_int 0))
3012 (match_dup 1)
3013 (match_dup 2)))]
3014 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT"
3015 "
3016 { operands[3] = gen_reg_rtx (SFmode); }")
3017
3018 (define_split
3019 [(set (match_operand:SF 0 "gpc_reg_operand" "")
3020 (smax:SF (match_operand:SF 1 "gpc_reg_operand" "")
3021 (match_operand:SF 2 "gpc_reg_operand" "")))
3022 (clobber (match_operand:SF 3 "gpc_reg_operand" ""))]
3023 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT"
3024 [(set (match_dup 3)
3025 (minus:SF (match_dup 1) (match_dup 2)))
3026 (set (match_dup 0)
3027 (if_then_else:SF (ge (match_dup 3)
3028 (const_int 0))
3029 (match_dup 1)
3030 (match_dup 2)))]
3031 "")
3032
3033 (define_expand "minsf3"
3034 [(set (match_dup 3)
3035 (minus:SF (match_operand:SF 2 "gpc_reg_operand" "")
3036 (match_operand:SF 1 "gpc_reg_operand" "")))
3037 (set (match_operand:SF 0 "gpc_reg_operand" "")
3038 (if_then_else:SF (ge (match_dup 3)
3039 (const_int 0))
3040 (match_dup 1)
3041 (match_dup 2)))]
3042 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT"
3043 "
3044 { operands[3] = gen_reg_rtx (SFmode); }")
3045
3046 (define_split
3047 [(set (match_operand:SF 0 "gpc_reg_operand" "")
3048 (smin:SF (match_operand:SF 1 "gpc_reg_operand" "")
3049 (match_operand:SF 2 "gpc_reg_operand" "")))
3050 (clobber (match_operand:SF 3 "gpc_reg_operand" ""))]
3051 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT"
3052 [(set (match_dup 3)
3053 (minus:SF (match_dup 2) (match_dup 1)))
3054 (set (match_dup 0)
3055 (if_then_else:SF (ge (match_dup 3)
3056 (const_int 0))
3057 (match_dup 1)
3058 (match_dup 2)))]
3059 "")
3060
3061 (define_expand "movsfcc"
3062 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
3063 (if_then_else:SF (match_operand 1 "comparison_operator" "")
3064 (match_operand:SF 2 "gpc_reg_operand" "f")
3065 (match_operand:SF 3 "gpc_reg_operand" "f")))]
3066 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT"
3067 "
3068 {
3069 rtx temp, op0, op1;
3070 enum rtx_code code = GET_CODE (operands[1]);
3071 if (! rs6000_compare_fp_p)
3072 FAIL;
3073 switch (code)
3074 {
3075 case GE: case EQ: case NE:
3076 op0 = rs6000_compare_op0;
3077 op1 = rs6000_compare_op1;
3078 break;
3079 case GT:
3080 op0 = rs6000_compare_op1;
3081 op1 = rs6000_compare_op0;
3082 temp = operands[2]; operands[2] = operands[3]; operands[3] = temp;
3083 break;
3084 case LE:
3085 op0 = rs6000_compare_op1;
3086 op1 = rs6000_compare_op0;
3087 break;
3088 case LT:
3089 op0 = rs6000_compare_op0;
3090 op1 = rs6000_compare_op1;
3091 temp = operands[2]; operands[2] = operands[3]; operands[3] = temp;
3092 break;
3093 default:
3094 FAIL;
3095 }
3096 if (GET_MODE (rs6000_compare_op0) == DFmode)
3097 {
3098 temp = gen_reg_rtx (DFmode);
3099 emit_insn (gen_subdf3 (temp, op0, op1));
3100 emit_insn (gen_fseldfsf4 (operands[0], temp, operands[2], operands[3]));
3101 if (code == EQ)
3102 {
3103 emit_insn (gen_negdf2 (temp, temp));
3104 emit_insn (gen_fseldfsf4 (operands[0], temp, operands[0], operands[3]));
3105 }
3106 if (code == NE)
3107 {
3108 emit_insn (gen_negdf2 (temp, temp));
3109 emit_insn (gen_fseldfsf4 (operands[0], temp, operands[3], operands[0]));
3110 }
3111 }
3112 else
3113 {
3114 temp = gen_reg_rtx (SFmode);
3115 emit_insn (gen_subsf3 (temp, op0, op1));
3116 emit_insn (gen_fselsfsf4 (operands[0], temp, operands[2], operands[3]));
3117 if (code == EQ)
3118 {
3119 emit_insn (gen_negsf2 (temp, temp));
3120 emit_insn (gen_fselsfsf4 (operands[0], temp, operands[0], operands[3]));
3121 }
3122 if (code == NE)
3123 {
3124 emit_insn (gen_negsf2 (temp, temp));
3125 emit_insn (gen_fselsfsf4 (operands[0], temp, operands[3], operands[0]));
3126 }
3127 }
3128 DONE;
3129 }")
3130
3131 (define_insn "fselsfsf4"
3132 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
3133 (if_then_else:SF (ge (match_operand:SF 1 "gpc_reg_operand" "f")
3134 (const_int 0))
3135 (match_operand:SF 2 "gpc_reg_operand" "f")
3136 (match_operand:SF 3 "gpc_reg_operand" "f")))]
3137 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT"
3138 "fsel %0,%1,%2,%3"
3139 [(set_attr "type" "fp")])
3140
3141 (define_insn "fseldfsf4"
3142 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
3143 (if_then_else:SF (ge (match_operand:DF 1 "gpc_reg_operand" "f")
3144 (const_int 0))
3145 (match_operand:SF 2 "gpc_reg_operand" "f")
3146 (match_operand:SF 3 "gpc_reg_operand" "f")))]
3147 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT"
3148 "fsel %0,%1,%2,%3"
3149 [(set_attr "type" "fp")])
3150
3151 (define_insn "negdf2"
3152 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
3153 (neg:DF (match_operand:DF 1 "gpc_reg_operand" "f")))]
3154 "TARGET_HARD_FLOAT"
3155 "fneg %0,%1"
3156 [(set_attr "type" "fp")])
3157
3158 (define_insn "absdf2"
3159 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
3160 (abs:DF (match_operand:DF 1 "gpc_reg_operand" "f")))]
3161 "TARGET_HARD_FLOAT"
3162 "fabs %0,%1"
3163 [(set_attr "type" "fp")])
3164
3165 (define_insn ""
3166 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
3167 (neg:DF (abs:DF (match_operand:DF 1 "gpc_reg_operand" "f"))))]
3168 "TARGET_HARD_FLOAT"
3169 "fnabs %0,%1"
3170 [(set_attr "type" "fp")])
3171
3172 (define_insn "adddf3"
3173 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
3174 (plus:DF (match_operand:DF 1 "gpc_reg_operand" "%f")
3175 (match_operand:DF 2 "gpc_reg_operand" "f")))]
3176 "TARGET_HARD_FLOAT"
3177 "{fa|fadd} %0,%1,%2"
3178 [(set_attr "type" "fp")])
3179
3180 (define_insn "subdf3"
3181 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
3182 (minus:DF (match_operand:DF 1 "gpc_reg_operand" "f")
3183 (match_operand:DF 2 "gpc_reg_operand" "f")))]
3184 "TARGET_HARD_FLOAT"
3185 "{fs|fsub} %0,%1,%2"
3186 [(set_attr "type" "fp")])
3187
3188 (define_insn "muldf3"
3189 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
3190 (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%f")
3191 (match_operand:DF 2 "gpc_reg_operand" "f")))]
3192 "TARGET_HARD_FLOAT"
3193 "{fm|fmul} %0,%1,%2"
3194 [(set_attr "type" "dmul")])
3195
3196 (define_insn "divdf3"
3197 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
3198 (div:DF (match_operand:DF 1 "gpc_reg_operand" "f")
3199 (match_operand:DF 2 "gpc_reg_operand" "f")))]
3200 "TARGET_HARD_FLOAT"
3201 "{fd|fdiv} %0,%1,%2"
3202 [(set_attr "type" "ddiv")])
3203
3204 (define_insn ""
3205 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
3206 (plus:DF (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%f")
3207 (match_operand:DF 2 "gpc_reg_operand" "f"))
3208 (match_operand:DF 3 "gpc_reg_operand" "f")))]
3209 "TARGET_HARD_FLOAT"
3210 "{fma|fmadd} %0,%1,%2,%3"
3211 [(set_attr "type" "dmul")])
3212
3213 (define_insn ""
3214 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
3215 (minus:DF (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%f")
3216 (match_operand:DF 2 "gpc_reg_operand" "f"))
3217 (match_operand:DF 3 "gpc_reg_operand" "f")))]
3218 "TARGET_HARD_FLOAT"
3219 "{fms|fmsub} %0,%1,%2,%3"
3220 [(set_attr "type" "dmul")])
3221
3222 (define_insn ""
3223 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
3224 (neg:DF (plus:DF (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%f")
3225 (match_operand:DF 2 "gpc_reg_operand" "f"))
3226 (match_operand:DF 3 "gpc_reg_operand" "f"))))]
3227 "TARGET_HARD_FLOAT"
3228 "{fnma|fnmadd} %0,%1,%2,%3"
3229 [(set_attr "type" "dmul")])
3230
3231 (define_insn ""
3232 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
3233 (neg:DF (minus:DF (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%f")
3234 (match_operand:DF 2 "gpc_reg_operand" "f"))
3235 (match_operand:DF 3 "gpc_reg_operand" "f"))))]
3236 "TARGET_HARD_FLOAT"
3237 "{fnms|fnmsub} %0,%1,%2,%3"
3238 [(set_attr "type" "dmul")])
3239
3240 (define_insn "sqrtdf2"
3241 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
3242 (sqrt:DF (match_operand:DF 1 "gpc_reg_operand" "f")))]
3243 "(TARGET_PPC_GPOPT || TARGET_POWER2) && TARGET_HARD_FLOAT"
3244 "fsqrt %0,%1"
3245 [(set_attr "type" "dsqrt")])
3246
3247 ;; For MIN, MAX, and conditional move, we use DEFINE_EXPAND's that involve a
3248 ;; fsel instruction and some auxiliary computations. Then we just have a
3249 ;; single DEFINE_INSN for fsel and the define_splits to make them if made by
3250 ;; combine.
3251
3252 (define_expand "maxdf3"
3253 [(set (match_dup 3)
3254 (minus:DF (match_operand:DF 1 "gpc_reg_operand" "")
3255 (match_operand:DF 2 "gpc_reg_operand" "")))
3256 (set (match_operand:DF 0 "gpc_reg_operand" "")
3257 (if_then_else:DF (ge (match_dup 3)
3258 (const_int 0))
3259 (match_dup 1)
3260 (match_dup 2)))]
3261 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT"
3262 "
3263 { operands[3] = gen_reg_rtx (DFmode); }")
3264
3265 (define_split
3266 [(set (match_operand:DF 0 "gpc_reg_operand" "")
3267 (smax:DF (match_operand:DF 1 "gpc_reg_operand" "")
3268 (match_operand:DF 2 "gpc_reg_operand" "")))
3269 (clobber (match_operand:DF 3 "gpc_reg_operand" ""))]
3270 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT"
3271 [(set (match_dup 3)
3272 (minus:DF (match_dup 1) (match_dup 2)))
3273 (set (match_dup 0)
3274 (if_then_else:DF (ge (match_dup 3)
3275 (const_int 0))
3276 (match_dup 1)
3277 (match_dup 2)))]
3278 "")
3279
3280 (define_expand "mindf3"
3281 [(set (match_dup 3)
3282 (minus:DF (match_operand:DF 2 "gpc_reg_operand" "")
3283 (match_operand:DF 1 "gpc_reg_operand" "")))
3284 (set (match_operand:DF 0 "gpc_reg_operand" "")
3285 (if_then_else:DF (ge (match_dup 3)
3286 (const_int 0))
3287 (match_dup 1)
3288 (match_dup 2)))]
3289 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT"
3290 "
3291 { operands[3] = gen_reg_rtx (DFmode); }")
3292
3293 (define_split
3294 [(set (match_operand:DF 0 "gpc_reg_operand" "")
3295 (smin:DF (match_operand:DF 1 "gpc_reg_operand" "")
3296 (match_operand:DF 2 "gpc_reg_operand" "")))
3297 (clobber (match_operand:DF 3 "gpc_reg_operand" ""))]
3298 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT"
3299 [(set (match_dup 3)
3300 (minus:DF (match_dup 2) (match_dup 1)))
3301 (set (match_dup 0)
3302 (if_then_else:DF (ge (match_dup 3)
3303 (const_int 0))
3304 (match_dup 1)
3305 (match_dup 2)))]
3306 "")
3307
3308 (define_expand "movdfcc"
3309 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
3310 (if_then_else:DF (match_operand 1 "comparison_operator" "")
3311 (match_operand:DF 2 "gpc_reg_operand" "f")
3312 (match_operand:DF 3 "gpc_reg_operand" "f")))]
3313 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT"
3314 "
3315 {
3316 rtx temp, op0, op1;
3317 enum rtx_code code = GET_CODE (operands[1]);
3318 if (! rs6000_compare_fp_p)
3319 FAIL;
3320 switch (code)
3321 {
3322 case GE: case EQ: case NE:
3323 op0 = rs6000_compare_op0;
3324 op1 = rs6000_compare_op1;
3325 break;
3326 case GT:
3327 op0 = rs6000_compare_op1;
3328 op1 = rs6000_compare_op0;
3329 temp = operands[2]; operands[2] = operands[3]; operands[3] = temp;
3330 break;
3331 case LE:
3332 op0 = rs6000_compare_op1;
3333 op1 = rs6000_compare_op0;
3334 break;
3335 case LT:
3336 op0 = rs6000_compare_op0;
3337 op1 = rs6000_compare_op1;
3338 temp = operands[2]; operands[2] = operands[3]; operands[3] = temp;
3339 break;
3340 default:
3341 FAIL;
3342 }
3343 if (GET_MODE (rs6000_compare_op0) == DFmode)
3344 {
3345 temp = gen_reg_rtx (DFmode);
3346 emit_insn (gen_subdf3 (temp, op0, op1));
3347 emit_insn (gen_fseldfdf4 (operands[0], temp, operands[2], operands[3]));
3348 if (code == EQ)
3349 {
3350 emit_insn (gen_negdf2 (temp, temp));
3351 emit_insn (gen_fseldfdf4 (operands[0], temp, operands[0], operands[3]));
3352 }
3353 if (code == NE)
3354 {
3355 emit_insn (gen_negdf2 (temp, temp));
3356 emit_insn (gen_fseldfdf4 (operands[0], temp, operands[3], operands[0]));
3357 }
3358 }
3359 else
3360 {
3361 temp = gen_reg_rtx (SFmode);
3362 emit_insn (gen_subsf3 (temp, op0, op1));
3363 emit_insn (gen_fselsfdf4 (operands[0], temp, operands[2], operands[3]));
3364 if (code == EQ)
3365 {
3366 emit_insn (gen_negsf2 (temp, temp));
3367 emit_insn (gen_fselsfdf4 (operands[0], temp, operands[0], operands[3]));
3368 }
3369 if (code == NE)
3370 {
3371 emit_insn (gen_negsf2 (temp, temp));
3372 emit_insn (gen_fselsfdf4 (operands[0], temp, operands[3], operands[0]));
3373 }
3374 }
3375 DONE;
3376 }")
3377
3378 (define_insn "fseldfdf4"
3379 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
3380 (if_then_else:DF (ge (match_operand:DF 1 "gpc_reg_operand" "f")
3381 (const_int 0))
3382 (match_operand:DF 2 "gpc_reg_operand" "f")
3383 (match_operand:DF 3 "gpc_reg_operand" "f")))]
3384 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT"
3385 "fsel %0,%1,%2,%3"
3386 [(set_attr "type" "fp")])
3387
3388 (define_insn "fselsfdf4"
3389 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
3390 (if_then_else:DF (ge (match_operand:SF 1 "gpc_reg_operand" "f")
3391 (const_int 0))
3392 (match_operand:DF 2 "gpc_reg_operand" "f")
3393 (match_operand:DF 3 "gpc_reg_operand" "f")))]
3394 "TARGET_PPC_GFXOPT"
3395 "fsel %0,%1,%2,%3"
3396 [(set_attr "type" "fp")])
3397 \f
3398 ;; Conversions to and from floating-point.
3399 (define_expand "floatsidf2"
3400 [(set (match_operand:DF 0 "gpc_reg_operand" "")
3401 (float:DF (match_operand:SI 1 "gpc_reg_operand" "")))]
3402 "! TARGET_POWERPC64 && TARGET_HARD_FLOAT"
3403 "
3404 {
3405 if (operands[0])
3406 { /* prevent unused warning messages */
3407 rtx high = force_reg (SImode, GEN_INT (0x43300000));
3408 rtx low = gen_reg_rtx (SImode);
3409 rtx df = gen_reg_rtx (DFmode);
3410 rtx adjust = force_reg (DFmode, rs6000_float_const (\"4503601774854144\", DFmode));
3411
3412 emit_insn (gen_xorsi3 (low, operands[1], GEN_INT (0x80000000)));
3413 emit_insn (gen_move_to_float (df, low, high));
3414 emit_insn (gen_subdf3 (operands[0], df, adjust));
3415 DONE;
3416 }
3417 }")
3418
3419 (define_expand "floatunssidf2"
3420 [(set (match_operand:DF 0 "gpc_reg_operand" "")
3421 (unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" "")))]
3422 "! TARGET_POWERPC64 && TARGET_HARD_FLOAT"
3423 "
3424 {
3425 if (operands[0])
3426 { /* prevent unused warning messages */
3427 rtx high = force_reg (SImode, GEN_INT (0x43300000));
3428 rtx df = gen_reg_rtx (DFmode);
3429 rtx adjust = force_reg (DFmode, rs6000_float_const (\"4503599627370496\", DFmode));
3430
3431 emit_insn (gen_move_to_float (df, operands[1], high));
3432 emit_insn (gen_subdf3 (operands[0], df, adjust));
3433 DONE;
3434 }
3435 }")
3436
3437 (define_expand "move_to_float"
3438 [(set (match_operand:DF 0 "gpc_reg_operand" "")
3439 (unspec [(match_operand:SI 1 "gpc_reg_operand" "")
3440 (match_operand:SI 2 "gpc_reg_operand" "")
3441 (match_dup 3)] 2))]
3442 "! TARGET_POWERPC64 && TARGET_HARD_FLOAT"
3443 "
3444 {
3445 operands[3] = XEXP (rs6000_stack_temp (DFmode, 8, 1), 0);
3446 }")
3447
3448 (define_split
3449 [(set (match_operand:DF 0 "gpc_reg_operand" "")
3450 (unspec [(match_operand:SI 1 "gpc_reg_operand" "")
3451 (match_operand:SI 2 "gpc_reg_operand" "")
3452 (match_operand:SI 3 "offsettable_addr_operand" "")] 2))]
3453 "reload_completed"
3454 [(set (match_dup 4) (match_dup 1))
3455 (set (match_dup 5) (match_dup 2))
3456 (set (match_dup 0) (mem:DF (match_dup 3)))]
3457 "
3458 {
3459 rtx word1 = gen_rtx (MEM, SImode, operands[3]);
3460 rtx word2 = gen_rtx (MEM, SImode, plus_constant (operands[3], 4));
3461
3462 MEM_IN_STRUCT_P (word1) = 1;
3463 MEM_IN_STRUCT_P (word2) = 1;
3464
3465 if (WORDS_BIG_ENDIAN)
3466 {
3467 operands[4] = word2;
3468 operands[5] = word1;
3469 }
3470 else
3471 {
3472 operands[4] = word1;
3473 operands[5] = word2;
3474 }
3475 }")
3476
3477 (define_insn ""
3478 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
3479 (unspec [(match_operand:SI 1 "gpc_reg_operand" "r")
3480 (match_operand:SI 2 "gpc_reg_operand" "r")
3481 (match_operand:SI 3 "offsettable_addr_operand" "p")] 2))]
3482 "! TARGET_POWERPC64 && TARGET_HARD_FLOAT"
3483 "#"
3484 [(set_attr "length" "12")])
3485
3486 (define_expand "fix_truncdfsi2"
3487 [(set (match_operand:SI 0 "gpc_reg_operand" "")
3488 (fix:SI (match_operand:DF 1 "gpc_reg_operand" "")))]
3489 "TARGET_HARD_FLOAT"
3490 "
3491 {
3492 if (TARGET_POWER2 || TARGET_POWERPC)
3493 {
3494 int endian = (WORDS_BIG_ENDIAN == 0);
3495 rtx stack_slot = rs6000_stack_temp (DImode, 8, 1);
3496 rtx temp = gen_reg_rtx (DImode);
3497
3498 emit_insn (gen_fpcvtsi (temp, operands[1]));
3499 emit_move_insn (stack_slot, temp);
3500 emit_move_insn (operands[0],
3501 operand_subword (stack_slot, 1 - endian, 0, DImode));
3502 DONE;
3503 }
3504 else
3505 {
3506 emit_insn (gen_trunc_call (operands[0], operands[1],
3507 gen_rtx (SYMBOL_REF, Pmode, RS6000_ITRUNC)));
3508 DONE;
3509 }
3510 }")
3511
3512 (define_insn "fpcvtsi"
3513 [(set (match_operand:DI 0 "gpc_reg_operand" "=f")
3514 (sign_extend:DI
3515 (fix:SI (match_operand:DF 1 "gpc_reg_operand" "f"))))]
3516 "(TARGET_POWER2 || TARGET_POWERPC) && TARGET_HARD_FLOAT"
3517 "{fcirz|fctiwz} %0,%1"
3518 [(set_attr "type" "fp")])
3519
3520 (define_expand "fixuns_truncdfsi2"
3521 [(set (match_operand:SI 0 "gpc_reg_operand" "")
3522 (unsigned_fix:SI (match_operand:DF 1 "gpc_reg_operand" "")))]
3523 "! TARGET_POWER2 && ! TARGET_POWERPC && TARGET_HARD_FLOAT"
3524 "
3525 {
3526 emit_insn (gen_trunc_call (operands[0], operands[1],
3527 gen_rtx (SYMBOL_REF, Pmode, RS6000_UITRUNC)));
3528 DONE;
3529 }")
3530
3531 (define_expand "trunc_call"
3532 [(parallel [(set (match_operand:SI 0 "" "")
3533 (fix:SI (match_operand:DF 1 "" "")))
3534 (use (match_operand:SI 2 "" ""))])]
3535 "TARGET_HARD_FLOAT"
3536 "
3537 {
3538 rtx insns = gen_trunc_call_rtl (operands[0], operands[1], operands[2]);
3539 rtx first = XVECEXP (insns, 0, 0);
3540 rtx last = XVECEXP (insns, 0, XVECLEN (insns, 0) - 1);
3541
3542 REG_NOTES (first) = gen_rtx (INSN_LIST, REG_LIBCALL, last,
3543 REG_NOTES (first));
3544 REG_NOTES (last) = gen_rtx (INSN_LIST, REG_RETVAL, first, REG_NOTES (last));
3545
3546 emit_insn (insns);
3547 DONE;
3548 }")
3549
3550 (define_expand "trunc_call_rtl"
3551 [(set (reg:DF 33) (match_operand:DF 1 "gpc_reg_operand" ""))
3552 (use (reg:DF 33))
3553 (parallel [(set (reg:SI 3)
3554 (call (mem:SI (match_operand 2 "" "")) (const_int 0)))
3555 (use (const_int 0))
3556 (clobber (scratch:SI))])
3557 (set (match_operand:SI 0 "gpc_reg_operand" "")
3558 (reg:SI 3))]
3559 "TARGET_HARD_FLOAT"
3560 "
3561 {
3562 rs6000_trunc_used = 1;
3563 }")
3564
3565 (define_insn "floatdidf2"
3566 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
3567 (float:DF (match_operand:DI 1 "gpc_reg_operand" "f")))]
3568 "TARGET_POWERPC64 && TARGET_HARD_FLOAT"
3569 "fcfid %0,%1"
3570 [(set_attr "type" "fp")])
3571
3572 (define_insn "fix_truncdfdi2"
3573 [(set (match_operand:DI 0 "gpc_reg_operand" "=f")
3574 (fix:DI (match_operand:DF 1 "gpc_reg_operand" "f")))]
3575 "TARGET_POWERPC64 && TARGET_HARD_FLOAT"
3576 "fctidz %0,%1"
3577 [(set_attr "type" "fp")])
3578 \f
3579 ;; Define the DImode operations that can be done in a small number
3580 ;; of instructions. The & constraints are to prevent the register
3581 ;; allocator from allocating registers that overlap with the inputs
3582 ;; (for example, having an input in 7,8 and an output in 6,7). We
3583 ;; also allow for the the output being the same as one of the inputs.
3584
3585 (define_expand "adddi3"
3586 [(set (match_operand:DI 0 "gpc_reg_operand" "")
3587 (plus:DI (match_operand:DI 1 "gpc_reg_operand" "")
3588 (match_operand:DI 2 "reg_or_short_operand" "")))]
3589 ""
3590 "
3591 {
3592 if (! TARGET_POWER && ! TARGET_POWERPC64
3593 && short_cint_operand (operands[2], DImode))
3594 FAIL;
3595 }")
3596
3597 (define_insn ""
3598 [(set (match_operand:DI 0 "gpc_reg_operand" "=&r,&r,r,r")
3599 (plus:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,0,0")
3600 (match_operand:DI 2 "reg_or_short_operand" "r,I,r,I")))]
3601 "TARGET_POWER && ! TARGET_POWERPC64"
3602 "@
3603 {a|addc} %L0,%L1,%L2\;{ae|adde} %0,%1,%2
3604 {ai|addic} %L0,%L1,%2\;{a%G2e|add%G2e} %0,%1
3605 {a|addc} %L0,%L1,%L2\;{ae|adde} %0,%1,%2
3606 {ai|addic} %L0,%L1,%2\;{a%G2e|add%G2e} %0,%1"
3607 [(set_attr "length" "8")])
3608
3609 (define_insn ""
3610 [(set (match_operand:DI 0 "gpc_reg_operand" "=&r,r")
3611 (plus:DI (match_operand:DI 1 "gpc_reg_operand" "%r,0")
3612 (match_operand:DI 2 "gpc_reg_operand" "r,r")))]
3613 "! TARGET_POWER && ! TARGET_POWERPC64"
3614 "*
3615 {
3616 return (WORDS_BIG_ENDIAN)
3617 ? \"addc %L0,%L1,%L2\;adde %0,%1,%2\"
3618 : \"addc %0,%1,%2\;adde %L0,%L1,%L2\";
3619 }"
3620 [(set_attr "length" "8")])
3621
3622 (define_expand "subdi3"
3623 [(set (match_operand:DI 0 "gpc_reg_operand" "")
3624 (minus:DI (match_operand:DI 1 "reg_or_short_operand" "")
3625 (match_operand:DI 2 "gpc_reg_operand" "")))]
3626 ""
3627 "
3628 {
3629 if (! TARGET_POWER && ! TARGET_POWERPC64
3630 && short_cint_operand (operands[1], DImode))
3631 FAIL;
3632 }")
3633
3634 (define_insn ""
3635 [(set (match_operand:DI 0 "gpc_reg_operand" "=&r,&r,r,r,r")
3636 (minus:DI (match_operand:DI 1 "reg_or_short_operand" "r,I,0,r,I")
3637 (match_operand:DI 2 "gpc_reg_operand" "r,r,r,0,0")))]
3638 "TARGET_POWER && ! TARGET_POWERPC64"
3639 "@
3640 {sf|subfc} %L0,%L2,%L1\;{sfe|subfe} %0,%2,%1
3641 {sfi|subfic} %L0,%L2,%1\;{sf%G1e|subf%G1e} %0,%2
3642 {sf|subfc} %L0,%L2,%L1\;{sfe|subfe} %0,%2,%1
3643 {sf|subfc} %L0,%L2,%L1\;{sfe|subfe} %0,%2,%1
3644 {sfi|subfic} %L0,%L2,%1\;{sf%G1e|subf%G1e} %0,%2"
3645 [(set_attr "length" "8")])
3646
3647 (define_insn ""
3648 [(set (match_operand:DI 0 "gpc_reg_operand" "=&r,r,r")
3649 (minus:DI (match_operand:DI 1 "gpc_reg_operand" "r,0,r")
3650 (match_operand:DI 2 "gpc_reg_operand" "r,r,0")))]
3651 "! TARGET_POWER && ! TARGET_POWERPC64"
3652 "*
3653 {
3654 return (WORDS_BIG_ENDIAN)
3655 ? \"{sf|subfc} %L0,%L2,%L1\;{sfe|subfe} %0,%2,%1\"
3656 : \"{sf|subfc} %0,%2,%1\;{sfe|subfe} %L0,%L2,%L1\";
3657 }"
3658 [(set_attr "length" "8")])
3659
3660 (define_expand "negdi2"
3661 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3662 (neg:DI (match_operand:DI 1 "gpc_reg_operand" "r")))]
3663 ""
3664 "")
3665
3666 (define_insn ""
3667 [(set (match_operand:DI 0 "gpc_reg_operand" "=&r,r")
3668 (neg:DI (match_operand:DI 1 "gpc_reg_operand" "r,0")))]
3669 "! TARGET_POWERPC64"
3670 "*
3671 {
3672 return (WORDS_BIG_ENDIAN)
3673 ? \"{sfi|subfic} %L0,%L1,0\;{sfze|subfze} %0,%1\"
3674 : \"{sfi|subfic} %0,%1,0\;{sfze|subfze} %L0,%L1\";
3675 }"
3676 [(set_attr "length" "8")])
3677
3678 (define_expand "mulsidi3"
3679 [(set (match_operand:DI 0 "gpc_reg_operand" "")
3680 (mult:DI (sign_extend:DI (match_operand:SI 1 "gpc_reg_operand" ""))
3681 (sign_extend:DI (match_operand:SI 2 "gpc_reg_operand" ""))))]
3682 ""
3683 "
3684 {
3685 if (! TARGET_POWER && ! TARGET_POWERPC)
3686 {
3687 int endian = (WORDS_BIG_ENDIAN == 0);
3688 emit_move_insn (gen_rtx (REG, SImode, 3), operands[1]);
3689 emit_move_insn (gen_rtx (REG, SImode, 4), operands[2]);
3690 emit_insn (gen_mull_call ());
3691 emit_move_insn (operand_subword (operands[0], endian, 0, DImode),
3692 gen_rtx (REG, SImode, 3));
3693 emit_move_insn (operand_subword (operands[0], 1 - endian, 0, DImode),
3694 gen_rtx (REG, SImode, 4));
3695 DONE;
3696 }
3697 else if (TARGET_POWER)
3698 {
3699 emit_insn (gen_mulsidi3_mq (operands[0], operands[1], operands[2]));
3700 DONE;
3701 }
3702 }")
3703
3704 (define_insn "mulsidi3_mq"
3705 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3706 (mult:DI (sign_extend:DI (match_operand:SI 1 "gpc_reg_operand" "%r"))
3707 (sign_extend:DI (match_operand:SI 2 "gpc_reg_operand" "r"))))
3708 (clobber (match_scratch:SI 3 "=q"))]
3709 "TARGET_POWER"
3710 "mul %0,%1,%2\;mfmq %L0"
3711 [(set_attr "type" "imul")
3712 (set_attr "length" "8")])
3713
3714 (define_insn ""
3715 [(set (match_operand:DI 0 "gpc_reg_operand" "=&r")
3716 (mult:DI (sign_extend:DI (match_operand:SI 1 "gpc_reg_operand" "%r"))
3717 (sign_extend:DI (match_operand:SI 2 "gpc_reg_operand" "r"))))]
3718 "TARGET_POWERPC && ! TARGET_POWERPC64"
3719 "*
3720 {
3721 return (WORDS_BIG_ENDIAN)
3722 ? \"mulhw %0,%1,%2\;mullw %L0,%1,%2\"
3723 : \"mulhw %L0,%1,%2\;mullw %0,%1,%2\";
3724 }"
3725 [(set_attr "type" "imul")
3726 (set_attr "length" "8")])
3727
3728 (define_insn "umulsidi3"
3729 [(set (match_operand:DI 0 "gpc_reg_operand" "=&r")
3730 (mult:DI (zero_extend:DI (match_operand:SI 1 "gpc_reg_operand" "%r"))
3731 (zero_extend:DI (match_operand:SI 2 "gpc_reg_operand" "r"))))]
3732 "TARGET_POWERPC && ! TARGET_POWERPC64"
3733 "*
3734 {
3735 return (WORDS_BIG_ENDIAN)
3736 ? \"mulhwu %0,%1,%2\;mullw %L0,%1,%2\"
3737 : \"mulhwu %L0,%1,%2\;mullw %0,%1,%2\";
3738 }"
3739 [(set_attr "type" "imul")
3740 (set_attr "length" "8")])
3741
3742 (define_expand "smulsi3_highpart"
3743 [(set (match_operand:SI 0 "gpc_reg_operand" "")
3744 (truncate:SI
3745 (lshiftrt:DI (mult:DI (sign_extend:DI
3746 (match_operand:SI 1 "gpc_reg_operand" "%r"))
3747 (sign_extend:DI
3748 (match_operand:SI 2 "gpc_reg_operand" "r")))
3749 (const_int 32))))]
3750 ""
3751 "
3752 {
3753 if (! TARGET_POWER && ! TARGET_POWERPC)
3754 {
3755 emit_move_insn (gen_rtx (REG, SImode, 3), operands[1]);
3756 emit_move_insn (gen_rtx (REG, SImode, 4), operands[2]);
3757 emit_insn (gen_mulh_call ());
3758 emit_move_insn (operands[0], gen_rtx (REG, SImode, 3));
3759 DONE;
3760 }
3761 else if (TARGET_POWER)
3762 {
3763 emit_insn (gen_smulsi3_highpart_mq (operands[0], operands[1], operands[2]));
3764 DONE;
3765 }
3766 }")
3767
3768 (define_insn "smulsi3_highpart_mq"
3769 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
3770 (truncate:SI
3771 (lshiftrt:DI (mult:DI (sign_extend:DI
3772 (match_operand:SI 1 "gpc_reg_operand" "%r"))
3773 (sign_extend:DI
3774 (match_operand:SI 2 "gpc_reg_operand" "r")))
3775 (const_int 32))))
3776 (clobber (match_scratch:SI 3 "=q"))]
3777 "TARGET_POWER"
3778 "mul %0,%1,%2"
3779 [(set_attr "type" "imul")])
3780
3781 (define_insn ""
3782 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
3783 (truncate:SI
3784 (lshiftrt:DI (mult:DI (sign_extend:DI
3785 (match_operand:SI 1 "gpc_reg_operand" "%r"))
3786 (sign_extend:DI
3787 (match_operand:SI 2 "gpc_reg_operand" "r")))
3788 (const_int 32))))]
3789 "TARGET_POWERPC"
3790 "mulhw %0,%1,%2"
3791 [(set_attr "type" "imul")])
3792
3793 (define_insn "umulsi3_highpart"
3794 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
3795 (truncate:SI
3796 (lshiftrt:DI (mult:DI (zero_extend:DI
3797 (match_operand:SI 1 "gpc_reg_operand" "%r"))
3798 (zero_extend:DI
3799 (match_operand:SI 2 "gpc_reg_operand" "r")))
3800 (const_int 32))))]
3801 "TARGET_POWERPC"
3802 "mulhwu %0,%1,%2"
3803 [(set_attr "type" "imul")])
3804
3805 ;; If operands 0 and 2 are in the same register, we have a problem. But
3806 ;; operands 0 and 1 (the usual case) can be in the same register. That's
3807 ;; why we have the strange constraints below.
3808 (define_insn "ashldi3"
3809 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,&r")
3810 (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,0,r")
3811 (match_operand:SI 2 "reg_or_cint_operand" "M,i,r,r")))
3812 (clobber (match_scratch:SI 3 "=X,q,q,q"))]
3813 "TARGET_POWER"
3814 "@
3815 {sli|slwi} %0,%L1,%h2\;{cal %L0,0(0)|li %L0,0}
3816 sl%I2q %L0,%L1,%h2\;sll%I2q %0,%1,%h2
3817 sl%I2q %L0,%L1,%h2\;sll%I2q %0,%1,%h2
3818 sl%I2q %L0,%L1,%h2\;sll%I2q %0,%1,%h2"
3819 [(set_attr "length" "8")])
3820
3821 (define_insn "lshrdi3"
3822 [(set (match_operand:DI 0 "gpc_reg_operand" "=&r,r,r,&r")
3823 (lshiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,0,r")
3824 (match_operand:SI 2 "reg_or_cint_operand" "M,i,r,r")))
3825 (clobber (match_scratch:SI 3 "=X,q,q,q"))]
3826 "TARGET_POWER"
3827 "@
3828 {cal %0,0(0)|li %0,0}\;{s%A2i|s%A2wi} %L0,%1,%h2
3829 sr%I2q %0,%1,%h2\;srl%I2q %L0,%L1,%h2
3830 sr%I2q %0,%1,%h2\;srl%I2q %L0,%L1,%h2
3831 sr%I2q %0,%1,%h2\;srl%I2q %L0,%L1,%h2"
3832 [(set_attr "length" "8")])
3833
3834 ;; Shift by a variable amount is too complex to be worth open-coding. We
3835 ;; just handle shifts by constants.
3836
3837 (define_expand "ashrdi3"
3838 [(parallel [(set (match_operand:DI 0 "gpc_reg_operand" "")
3839 (ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "")
3840 (match_operand:SI 2 "general_operand" "")))
3841 (clobber (match_scratch:SI 3 ""))])]
3842 "TARGET_POWER"
3843 "
3844 { if (GET_CODE (operands[2]) != CONST_INT)
3845 FAIL;
3846 }")
3847
3848 (define_insn ""
3849 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
3850 (ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
3851 (match_operand:SI 2 "const_int_operand" "M,i")))
3852 (clobber (match_scratch:SI 3 "=X,q"))]
3853 "TARGET_POWER"
3854 "@
3855 {srai|srawi} %0,%1,31\;{srai|srawi} %L0,%1,%h2
3856 sraiq %0,%1,%h2\;srliq %L0,%L1,%h2"
3857 [(set_attr "length" "8")])
3858 \f
3859 ;; PowerPC64 DImode operations.
3860
3861 (define_insn "ffsdi2"
3862 [(set (match_operand:DI 0 "gpc_reg_operand" "=&r")
3863 (ffs:DI (match_operand:DI 1 "gpc_reg_operand" "r")))]
3864 "TARGET_POWERPC64"
3865 "neg %0,%1\;and %0,%0,%1\;cntlzd %0,%0\;subfic %0,%0,64"
3866 [(set_attr "length" "16")])
3867
3868 (define_insn "muldi3"
3869 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3870 (mult:DI (match_operand:DI 1 "gpc_reg_operand" "%r")
3871 (match_operand:DI 2 "gpc_reg_operand" "r")))]
3872 "TARGET_POWERPC64"
3873 "mulld %0,%1,%2"
3874 [(set_attr "type" "imul")])
3875
3876 (define_insn "smuldi3_highpart"
3877 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3878 (truncate:DI
3879 (lshiftrt:TI (mult:TI (sign_extend:TI
3880 (match_operand:DI 1 "gpc_reg_operand" "%r"))
3881 (sign_extend:TI
3882 (match_operand:DI 2 "gpc_reg_operand" "r")))
3883 (const_int 64))))]
3884 "TARGET_POWERPC64"
3885 "mulhd %0,%1,%2"
3886 [(set_attr "type" "imul")])
3887
3888 (define_insn "umuldi3_highpart"
3889 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3890 (truncate:DI
3891 (lshiftrt:TI (mult:TI (zero_extend:TI
3892 (match_operand:DI 1 "gpc_reg_operand" "%r"))
3893 (zero_extend:TI
3894 (match_operand:DI 2 "gpc_reg_operand" "r")))
3895 (const_int 64))))]
3896 "TARGET_POWERPC64"
3897 "mulhdu %0,%1,%2"
3898 [(set_attr "type" "imul")])
3899
3900 (define_insn "divdi3"
3901 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3902 (div:DI (match_operand:DI 1 "gpc_reg_operand" "r")
3903 (match_operand:DI 2 "gpc_reg_operand" "r")))]
3904 "TARGET_POWERPC64"
3905 "divd %0,%1,%2"
3906 [(set_attr "type" "idiv")])
3907
3908 (define_insn "udivdi3"
3909 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3910 (udiv:DI (match_operand:DI 1 "gpc_reg_operand" "r")
3911 (match_operand:DI 2 "gpc_reg_operand" "r")))]
3912 "TARGET_POWERPC64"
3913 "divdu %0,%1,%2"
3914 [(set_attr "type" "idiv")])
3915
3916 (define_insn "rotldi3"
3917 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3918 (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r")
3919 (match_operand:DI 2 "reg_or_cint_operand" "ri")))]
3920 "TARGET_POWERPC64"
3921 "rld%I2cl %0,%1,%h2,0")
3922
3923 (define_insn ""
3924 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
3925 (compare:CC (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r")
3926 (match_operand:DI 2 "reg_or_cint_operand" "ri"))
3927 (const_int 0)))
3928 (clobber (match_scratch:DI 3 "=r"))]
3929 "TARGET_POWERPC64"
3930 "rld%I2cl. %3,%1,%h2,0"
3931 [(set_attr "type" "delayed_compare")])
3932
3933 (define_insn ""
3934 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
3935 (compare:CC (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r")
3936 (match_operand:DI 2 "reg_or_cint_operand" "ri"))
3937 (const_int 0)))
3938 (set (match_operand:DI 0 "gpc_reg_operand" "=r")
3939 (rotate:DI (match_dup 1) (match_dup 2)))]
3940 "TARGET_POWERPC64"
3941 "rld%I2cl. %0,%1,%h2,0"
3942 [(set_attr "type" "delayed_compare")])
3943 \f
3944 ;; Now define ways of moving data around.
3945
3946 ;; Elf specific ways of loading addresses for non-PIC code.
3947 ;; The output of this could be r0, but we limit it to base
3948 ;; registers, since almost all uses of this will need it
3949 ;; in a base register shortly.
3950 (define_insn "elf_high"
3951 [(set (match_operand:SI 0 "register_operand" "=b")
3952 (high:SI (match_operand 1 "" "")))]
3953 "TARGET_ELF && !TARGET_64BIT"
3954 "{cau|addis} %0,0,%1@ha")
3955
3956 (define_insn "elf_low"
3957 [(set (match_operand:SI 0 "register_operand" "=r")
3958 (lo_sum:SI (match_operand:SI 1 "register_operand" "b")
3959 (match_operand 2 "" "")))]
3960 "TARGET_ELF && !TARGET_64BIT"
3961 "{cal %0,%a2@l(%1)|addi %0,%1,%2@l}")
3962
3963 ;; For SI, we special-case integers that can't be loaded in one insn. We
3964 ;; do the load 16-bits at a time. We could do this by loading from memory,
3965 ;; and this is even supposed to be faster, but it is simpler not to get
3966 ;; integers in the TOC.
3967 (define_expand "movsi"
3968 [(set (match_operand:SI 0 "general_operand" "")
3969 (match_operand:SI 1 "any_operand" ""))]
3970 ""
3971 "
3972 {
3973 if (GET_CODE (operands[0]) != REG)
3974 operands[1] = force_reg (SImode, operands[1]);
3975
3976 /* Convert a move of a CONST_DOUBLE into a CONST_INT */
3977 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3978 operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
3979
3980 if (TARGET_ELF && TARGET_NO_TOC && !TARGET_64BIT
3981 && CONSTANT_P (operands[1])
3982 && GET_CODE (operands[1]) != HIGH
3983 && GET_CODE (operands[1]) != CONST_INT)
3984 {
3985 rtx target = (reload_completed || reload_in_progress)
3986 ? operands[0] : gen_reg_rtx (SImode);
3987
3988 /* If this is a function address on -mcall-aixdesc or -mcall-nt,
3989 convert it to the address of the descriptor. */
3990 if ((DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_NT)
3991 && GET_CODE (operands[1]) == SYMBOL_REF
3992 && XSTR (operands[1], 0)[0] == '.')
3993 {
3994 char *name = XSTR (operands[1], 0);
3995 rtx new_ref;
3996 while (*name == '.')
3997 name++;
3998 new_ref = gen_rtx (SYMBOL_REF, Pmode, name);
3999 CONSTANT_POOL_ADDRESS_P (new_ref) = CONSTANT_POOL_ADDRESS_P (operands[1]);
4000 SYMBOL_REF_FLAG (new_ref) = SYMBOL_REF_FLAG (operands[1]);
4001 SYMBOL_REF_USED (new_ref) = SYMBOL_REF_USED (operands[1]);
4002 operands[1] = new_ref;
4003 }
4004
4005 emit_insn (gen_elf_high (target, operands[1]));
4006 emit_insn (gen_elf_low (operands[0], target, operands[1]));
4007 DONE;
4008 }
4009
4010 if (GET_CODE (operands[1]) == CONST
4011 && DEFAULT_ABI == ABI_NT
4012 && !side_effects_p (operands[0]))
4013 {
4014 rtx const_term = const0_rtx;
4015 rtx sym = eliminate_constant_term (XEXP (operands[1], 0), &const_term);
4016 if (sym && GET_CODE (const_term) == CONST_INT
4017 && (GET_CODE (sym) == SYMBOL_REF || GET_CODE (sym) == LABEL_REF))
4018 {
4019 emit_insn (gen_movsi (operands[0], sym));
4020 if (INTVAL (const_term) != 0)
4021 {
4022 unsigned HOST_WIDE_INT value = INTVAL (const_term);
4023 if (value + 0x8000 < 0x10000)
4024 emit_insn (gen_addsi3 (operands[0], operands[0], GEN_INT (value)));
4025 else
4026 {
4027 emit_insn (gen_addsi3 (operands[0], operands[0],
4028 GEN_INT ((value >> 16) + ((value >> 15) & 1))));
4029
4030 if ((value & 0xffff) != 0)
4031 emit_insn (gen_addsi3 (operands[0], operands[0],
4032 GEN_INT (value & 0xffff)));
4033 }
4034 }
4035 DONE;
4036 }
4037 else
4038 fatal_insn (\"bad address\", operands[1]);
4039 }
4040
4041 if ((!TARGET_WINDOWS_NT || DEFAULT_ABI != ABI_NT)
4042 && CONSTANT_P (operands[1])
4043 && GET_CODE (operands[1]) != CONST_INT
4044 && GET_CODE (operands[1]) != HIGH
4045 && ! LEGITIMATE_CONSTANT_POOL_ADDRESS_P (operands[1]))
4046 {
4047 /* If we are to limit the number of things we put in the TOC and
4048 this is a symbol plus a constant we can add in one insn,
4049 just put the symbol in the TOC and add the constant. Don't do
4050 this if reload is in progress. */
4051 if (GET_CODE (operands[1]) == CONST
4052 && TARGET_NO_SUM_IN_TOC && ! reload_in_progress
4053 && GET_CODE (XEXP (operands[1], 0)) == PLUS
4054 && add_operand (XEXP (XEXP (operands[1], 0), 1), SImode)
4055 && (GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == LABEL_REF
4056 || GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == SYMBOL_REF)
4057 && ! side_effects_p (operands[0]))
4058 {
4059 rtx sym = force_const_mem (SImode, XEXP (XEXP (operands[1], 0), 0));
4060 rtx other = XEXP (XEXP (operands[1], 0), 1);
4061
4062 emit_insn (gen_addsi3 (operands[0], force_reg (SImode, sym), other));
4063 DONE;
4064 }
4065
4066 operands[1] = force_const_mem (SImode, operands[1]);
4067 if (! memory_address_p (SImode, XEXP (operands[1], 0))
4068 && ! reload_in_progress)
4069 operands[1] = change_address (operands[1], SImode,
4070 XEXP (operands[1], 0));
4071 }
4072 }")
4073
4074 (define_insn ""
4075 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,m,r,r,r,r,r,*q,*c*l,*h")
4076 (match_operand:SI 1 "input_operand" "r,S,T,m,r,I,J,n,R,*h,r,r,0"))]
4077 "gpc_reg_operand (operands[0], SImode)
4078 || gpc_reg_operand (operands[1], SImode)"
4079 "@
4080 mr %0,%1
4081 {l|lwz} %0,[toc]%1(2)
4082 {l|lwz} %0,[toc]%l1(2)
4083 {l%U1%X1|lwz%U1%X1} %0,%1
4084 {st%U0%X0|stw%U0%X0} %1,%0
4085 {lil|li} %0,%1
4086 {liu|lis} %0,%u1
4087 #
4088 {cal|la} %0,%1(%*)
4089 mf%1 %0
4090 mt%0 %1
4091 mt%0 %1
4092 cror 0,0,0"
4093 [(set_attr "type" "*,load,load,load,*,*,*,*,*,*,*,mtjmpr,*")
4094 (set_attr "length" "4,4,4,4,4,4,4,8,4,4,4,4,4")])
4095
4096 ;; Split a load of a large constant into the appropriate two-insn
4097 ;; sequence.
4098
4099 (define_split
4100 [(set (match_operand:SI 0 "gpc_reg_operand" "")
4101 (match_operand:SI 1 "const_int_operand" ""))]
4102 "(unsigned) (INTVAL (operands[1]) + 0x8000) >= 0x10000
4103 && (INTVAL (operands[1]) & 0xffff) != 0"
4104 [(set (match_dup 0)
4105 (match_dup 2))
4106 (set (match_dup 0)
4107 (ior:SI (match_dup 0)
4108 (match_dup 3)))]
4109 "
4110 {
4111 operands[2] = gen_rtx (CONST_INT, VOIDmode,
4112 INTVAL (operands[1]) & 0xffff0000);
4113 operands[3] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[1]) & 0xffff);
4114 }")
4115
4116 (define_insn ""
4117 [(set (match_operand:CC 2 "cc_reg_operand" "=x")
4118 (compare:CC (match_operand:SI 1 "gpc_reg_operand" "r")
4119 (const_int 0)))
4120 (set (match_operand:SI 0 "gpc_reg_operand" "=r") (match_dup 1))]
4121 ""
4122 "mr. %0,%1"
4123 [(set_attr "type" "compare")])
4124 \f
4125 (define_expand "movhi"
4126 [(set (match_operand:HI 0 "general_operand" "")
4127 (match_operand:HI 1 "any_operand" ""))]
4128 ""
4129 "
4130 {
4131 if (GET_CODE (operands[0]) != REG)
4132 operands[1] = force_reg (HImode, operands[1]);
4133
4134 if (CONSTANT_P (operands[1]) && GET_CODE (operands[1]) != CONST_INT)
4135 {
4136 operands[1] = force_const_mem (HImode, operands[1]);
4137 if (! memory_address_p (HImode, XEXP (operands[1], 0))
4138 && ! reload_in_progress)
4139 operands[1] = change_address (operands[1], HImode,
4140 XEXP (operands[1], 0));
4141 }
4142 }")
4143
4144 (define_insn ""
4145 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,m,r,r,*q,*c*l,*h")
4146 (match_operand:HI 1 "input_operand" "r,m,r,i,*h,r,r,0"))]
4147 "gpc_reg_operand (operands[0], HImode)
4148 || gpc_reg_operand (operands[1], HImode)"
4149 "@
4150 mr %0,%1
4151 lhz%U1%X1 %0,%1
4152 sth%U0%X0 %1,%0
4153 {lil|li} %0,%w1
4154 mf%1 %0
4155 mt%0 %1
4156 mt%0 %1
4157 cror 0,0,0"
4158 [(set_attr "type" "*,load,*,*,*,*,mtjmpr,*")])
4159
4160 (define_expand "movqi"
4161 [(set (match_operand:QI 0 "general_operand" "")
4162 (match_operand:QI 1 "any_operand" ""))]
4163 ""
4164 "
4165 {
4166 if (GET_CODE (operands[0]) != REG)
4167 operands[1] = force_reg (QImode, operands[1]);
4168
4169 if (CONSTANT_P (operands[1]) && GET_CODE (operands[1]) != CONST_INT)
4170 {
4171 operands[1] = force_const_mem (QImode, operands[1]);
4172 if (! memory_address_p (QImode, XEXP (operands[1], 0))
4173 && ! reload_in_progress)
4174 operands[1] = change_address (operands[1], QImode,
4175 XEXP (operands[1], 0));
4176 }
4177 }")
4178
4179 (define_insn ""
4180 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m,r,r,*q,*c*l,*h")
4181 (match_operand:QI 1 "input_operand" "r,m,r,i,*h,r,r,0"))]
4182 "gpc_reg_operand (operands[0], QImode)
4183 || gpc_reg_operand (operands[1], QImode)"
4184 "@
4185 mr %0,%1
4186 lbz%U1%X1 %0,%1
4187 stb%U0%X0 %1,%0
4188 {lil|li} %0,%1
4189 mf%1 %0
4190 mt%0 %1
4191 mt%0 %1
4192 cror 0,0,0"
4193 [(set_attr "type" "*,load,*,*,*,*,mtjmpr,*")])
4194 \f
4195 ;; Here is how to move condition codes around. When we store CC data in
4196 ;; an integer register or memory, we store just the high-order 4 bits.
4197 ;; This lets us not shift in the most common case of CR0.
4198 (define_expand "movcc"
4199 [(set (match_operand:CC 0 "nonimmediate_operand" "")
4200 (match_operand:CC 1 "nonimmediate_operand" ""))]
4201 ""
4202 "")
4203
4204 (define_insn ""
4205 [(set (match_operand:CC 0 "nonimmediate_operand" "=y,x,y,r,r,r,r,m")
4206 (match_operand:CC 1 "nonimmediate_operand" "y,r,r,x,y,r,m,r"))]
4207 "register_operand (operands[0], CCmode)
4208 || register_operand (operands[1], CCmode)"
4209 "@
4210 mcrf %0,%1
4211 mtcrf 128,%1
4212 {rlinm|rlwinm} %1,%1,%F0,0xffffffff\;mtcrf %R0,%1\;{rlinm|rlwinm} %1,%1,%f0,0xffffffff
4213 mfcr %0
4214 mfcr %0\;{rlinm|rlwinm} %0,%0,%f1,0xf0000000
4215 mr %0,%1
4216 {l%U1%X1|lwz%U1%X1} %0,%1
4217 {st%U0%U1|stw%U0%U1} %1,%0"
4218 [(set_attr "type" "*,*,*,compare,*,*,load,*")
4219 (set_attr "length" "*,*,12,*,8,*,*,*")])
4220 \f
4221 ;; For floating-point, we normally deal with the floating-point registers
4222 ;; unless -msoft-float is used. The sole exception is that parameter passing
4223 ;; can produce floating-point values in fixed-point registers. Unless the
4224 ;; value is a simple constant or already in memory, we deal with this by
4225 ;; allocating memory and copying the value explicitly via that memory location.
4226 (define_expand "movsf"
4227 [(set (match_operand:SF 0 "nonimmediate_operand" "")
4228 (match_operand:SF 1 "any_operand" ""))]
4229 ""
4230 "
4231 {
4232 /* If we are called from reload, we might be getting a SUBREG of a hard
4233 reg. So expand it. */
4234 if (GET_CODE (operands[0]) == SUBREG
4235 && GET_CODE (SUBREG_REG (operands[0])) == REG
4236 && REGNO (SUBREG_REG (operands[0])) < FIRST_PSEUDO_REGISTER)
4237 operands[0] = alter_subreg (operands[0]);
4238 if (GET_CODE (operands[1]) == SUBREG
4239 && GET_CODE (SUBREG_REG (operands[1])) == REG
4240 && REGNO (SUBREG_REG (operands[1])) < FIRST_PSEUDO_REGISTER)
4241 operands[1] = alter_subreg (operands[1]);
4242
4243 if (TARGET_SOFT_FLOAT && GET_CODE (operands[0]) == MEM)
4244 operands[1] = force_reg (SFmode, operands[1]);
4245
4246 else if (TARGET_HARD_FLOAT)
4247 {
4248 if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) < 32)
4249 {
4250 /* If this is a store to memory or another integer register do the
4251 move directly. Otherwise store to a temporary stack slot and
4252 load from there into a floating point register. */
4253
4254 if (GET_CODE (operands[0]) == MEM
4255 || (GET_CODE (operands[0]) == REG
4256 && (REGNO (operands[0]) < 32
4257 || (reload_in_progress
4258 && REGNO (operands[0]) >= FIRST_PSEUDO_REGISTER))))
4259 {
4260 emit_move_insn (operand_subword (operands[0], 0, 0, SFmode),
4261 operand_subword (operands[1], 0, 0, SFmode));
4262 DONE;
4263 }
4264 else
4265 {
4266 rtx stack_slot = assign_stack_temp (SFmode, 4, 0);
4267
4268 emit_move_insn (stack_slot, operands[1]);
4269 emit_move_insn (operands[0], stack_slot);
4270 DONE;
4271 }
4272 }
4273
4274 if (GET_CODE (operands[0]) == MEM)
4275 {
4276 /* If operands[1] is a register, it may have double-precision data
4277 in it, so truncate it to single precision. We need not do
4278 this for POWERPC. */
4279 if (! TARGET_POWERPC && TARGET_HARD_FLOAT
4280 && GET_CODE (operands[1]) == REG)
4281 {
4282 rtx newreg
4283 = reload_in_progress ? operands[1] : gen_reg_rtx (SFmode);
4284 emit_insn (gen_aux_truncdfsf2 (newreg, operands[1]));
4285 operands[1] = newreg;
4286 }
4287
4288 operands[1] = force_reg (SFmode, operands[1]);
4289 }
4290
4291 if (GET_CODE (operands[0]) == REG && REGNO (operands[0]) < 32)
4292 {
4293 if (GET_CODE (operands[1]) == MEM
4294 #if HOST_FLOAT_FORMAT == TARGET_FLOAT_FORMAT && ! defined(REAL_IS_NOT_DOUBLE)
4295 || GET_CODE (operands[1]) == CONST_DOUBLE
4296 #endif
4297 || (GET_CODE (operands[1]) == REG
4298 && (REGNO (operands[1]) < 32
4299 || (reload_in_progress
4300 && REGNO (operands[1]) >= FIRST_PSEUDO_REGISTER))))
4301 {
4302 emit_move_insn (operand_subword (operands[0], 0, 0, SFmode),
4303 operand_subword (operands[1], 0, 0, SFmode));
4304 DONE;
4305 }
4306 else
4307 {
4308 rtx stack_slot = assign_stack_temp (SFmode, 4, 0);
4309
4310 emit_move_insn (stack_slot, operands[1]);
4311 emit_move_insn (operands[0], stack_slot);
4312 DONE;
4313 }
4314 }
4315 }
4316
4317 if (CONSTANT_P (operands[1]))
4318 {
4319 operands[1] = force_const_mem (SFmode, operands[1]);
4320 if (! memory_address_p (SFmode, XEXP (operands[1], 0))
4321 && ! reload_in_progress)
4322 operands[1] = change_address (operands[1], SFmode,
4323 XEXP (operands[1], 0));
4324 }
4325 }")
4326
4327 (define_split
4328 [(set (match_operand:SF 0 "gpc_reg_operand" "")
4329 (match_operand:SF 1 "easy_fp_constant" ""))]
4330 "reload_completed && REGNO (operands[0]) <= 31"
4331 [(set (match_dup 2) (match_dup 3))]
4332 "
4333 { operands[2] = operand_subword (operands[0], 0, 0, SFmode);
4334 operands[3] = operand_subword (operands[1], 0, 0, SFmode); }")
4335
4336 (define_insn ""
4337 [(set (match_operand:SF 0 "fp_reg_or_mem_operand" "=f,f,m")
4338 (match_operand:SF 1 "input_operand" "f,m,f"))]
4339 "(gpc_reg_operand (operands[0], SFmode)
4340 || gpc_reg_operand (operands[1], SFmode)) && TARGET_HARD_FLOAT"
4341 "@
4342 fmr %0,%1
4343 lfs%U1%X1 %0,%1
4344 stfs%U0%X0 %1,%0"
4345 [(set_attr "type" "fp,fpload,*")])
4346
4347 (define_insn ""
4348 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m,r,r,r")
4349 (match_operand:SF 1 "input_operand" "r,m,r,I,J,R"))]
4350 "(gpc_reg_operand (operands[0], SFmode)
4351 || gpc_reg_operand (operands[1], SFmode)) && TARGET_SOFT_FLOAT"
4352 "@
4353 mr %0,%1
4354 {l%U1%X1|lwz%U1%X1} %0,%1
4355 {st%U0%X0|stw%U0%X0} %1,%0
4356 {lil|li} %0,%1
4357 {liu|lis} %0,%u1
4358 {cal|la} %0,%1(%*)"
4359 [(set_attr "type" "*,load,*,*,*,*")])
4360
4361 \f
4362 (define_expand "movdf"
4363 [(set (match_operand:DF 0 "nonimmediate_operand" "")
4364 (match_operand:DF 1 "any_operand" ""))]
4365 ""
4366 "
4367 {
4368 if (GET_CODE (operands[0]) != REG)
4369 operands[1] = force_reg (DFmode, operands[1]);
4370
4371 if (CONSTANT_P (operands[1]) && ! easy_fp_constant (operands[1], DFmode))
4372 {
4373 operands[1] = force_const_mem (DFmode, operands[1]);
4374 if (! memory_address_p (DFmode, XEXP (operands[1], 0))
4375 && ! reload_in_progress)
4376 operands[1] = change_address (operands[1], DFmode,
4377 XEXP (operands[1], 0));
4378 }
4379 }")
4380
4381 (define_split
4382 [(set (match_operand:DF 0 "gpc_reg_operand" "")
4383 (match_operand:DF 1 "easy_fp_constant" ""))]
4384 "reload_completed && REGNO (operands[0]) <= 31"
4385 [(set (match_dup 2) (match_dup 3))
4386 (set (match_dup 4) (match_dup 5))]
4387 "
4388 { operands[2] = operand_subword (operands[0], 0, 0, DFmode);
4389 operands[3] = operand_subword (operands[1], 0, 0, DFmode);
4390 operands[4] = operand_subword (operands[0], 1, 0, DFmode);
4391 operands[5] = operand_subword (operands[1], 1, 0, DFmode); }")
4392
4393 ;; Don't have reload use general registers to load a constant. First,
4394 ;; it might not work if the output operand has is the equivalent of
4395 ;; a non-offsettable memref, but also it is less efficient than loading
4396 ;; the constant into an FP register, since it will probably be used there.
4397 ;; The "??" is a kludge until we can figure out a more reasonable way
4398 ;; of handling these non-offsettable values.
4399 (define_insn ""
4400 [(set (match_operand:DF 0 "nonimmediate_operand" "=!r,??r,o,!r,f,f,m")
4401 (match_operand:DF 1 "input_operand" "r,o,r,G,f,m,f"))]
4402 "! TARGET_POWERPC64 && TARGET_HARD_FLOAT
4403 && (register_operand (operands[0], DFmode)
4404 || register_operand (operands[1], DFmode))"
4405 "*
4406 {
4407 switch (which_alternative)
4408 {
4409 case 0:
4410 /* We normally copy the low-numbered register first. However, if
4411 the first register operand 0 is the same as the second register of
4412 operand 1, we must copy in the opposite order. */
4413 if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
4414 return \"mr %L0,%L1\;mr %0,%1\";
4415 else
4416 return \"mr %0,%1\;mr %L0,%L1\";
4417 case 1:
4418 /* If the low-address word is used in the address, we must load it
4419 last. Otherwise, load it first. Note that we cannot have
4420 auto-increment in that case since the address register is known to be
4421 dead. */
4422 if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
4423 operands [1], 0))
4424 return \"{l|lwz} %L0,%L1\;{l|lwz} %0,%1\";
4425 else
4426 return \"{l%U1|lwz%U1} %0,%1\;{l|lwz} %L0,%L1\";
4427 case 2:
4428 return \"{st%U0|stw%U0} %1,%0\;{st|stw} %L1,%L0\";
4429 case 3:
4430 return \"#\";
4431 case 4:
4432 return \"fmr %0,%1\";
4433 case 5:
4434 return \"lfd%U1%X1 %0,%1\";
4435 case 6:
4436 return \"stfd%U0%X0 %1,%0\";
4437 }
4438 }"
4439 [(set_attr "type" "*,load,*,*,fp,fpload,*")
4440 (set_attr "length" "8,8,8,8,*,*,*")])
4441
4442 (define_insn ""
4443 [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,o,r")
4444 (match_operand:DF 1 "input_operand" "r,o,r,G"))]
4445 "! TARGET_POWERPC64 && TARGET_SOFT_FLOAT
4446 && (register_operand (operands[0], DFmode)
4447 || register_operand (operands[1], DFmode))"
4448 "*
4449 {
4450 switch (which_alternative)
4451 {
4452 case 0:
4453 /* We normally copy the low-numbered register first. However, if
4454 the first register operand 0 is the same as the second register of
4455 operand 1, we must copy in the opposite order. */
4456 if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
4457 return \"mr %L0,%L1\;mr %0,%1\";
4458 else
4459 return \"mr %0,%1\;mr %L0,%L1\";
4460 case 1:
4461 /* If the low-address word is used in the address, we must load it
4462 last. Otherwise, load it first. Note that we cannot have
4463 auto-increment in that case since the address register is known to be
4464 dead. */
4465 if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
4466 operands [1], 0))
4467 return \"{l|lwz} %L0,%L1\;{l|lwz} %0,%1\";
4468 else
4469 return \"{l%U1|lwz%U1} %0,%1\;{l|lwz} %L0,%L1\";
4470 case 2:
4471 return \"{st%U0|stw%U0} %1,%0\;{st|stw} %L1,%L0\";
4472 case 3:
4473 return \"#\";
4474 }
4475 }"
4476 [(set_attr "type" "*,load,*,*")
4477 (set_attr "length" "8,8,8,8")])
4478
4479 (define_insn ""
4480 [(set (match_operand:DF 0 "nonimmediate_operand" "=!r,??r,o,!r,f,f,m")
4481 (match_operand:DF 1 "input_operand" "r,o,r,G,f,m,f"))]
4482 "TARGET_POWERPC64 && TARGET_HARD_FLOAT
4483 && (register_operand (operands[0], DFmode)
4484 || register_operand (operands[1], DFmode))"
4485 "@
4486 mr %0,%1
4487 ld%U1%X1 %0,%1
4488 sd%U0%X0 %1,%0
4489 #
4490 fmr %0,%1
4491 lfd%U1%X1 %0,%1
4492 stfd%U0%X0 %1,%0"
4493 [(set_attr "type" "*,load,*,*,fp,fpload,*")])
4494
4495 (define_insn ""
4496 [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,o,r")
4497 (match_operand:DF 1 "input_operand" "r,o,r,G"))]
4498 "TARGET_POWERPC64 && TARGET_SOFT_FLOAT
4499 && (register_operand (operands[0], DFmode)
4500 || register_operand (operands[1], DFmode))"
4501 "@
4502 mr %0,%1
4503 ld%U1%X1 %0,%1
4504 sd%U0%X0 %1,%0
4505 #"
4506 [(set_attr "type" "*,load,*,*")])
4507 \f
4508 ;; Next come the multi-word integer load and store and the load and store
4509 ;; multiple insns.
4510 (define_expand "movdi"
4511 [(set (match_operand:DI 0 "general_operand" "")
4512 (match_operand:DI 1 "general_operand" ""))]
4513 ""
4514 "
4515 {
4516 if (GET_CODE (operands[0]) == MEM)
4517 operands[1] = force_reg (DImode, operands[1]);
4518
4519 if (GET_CODE (operands[1]) == CONST_DOUBLE
4520 || GET_CODE (operands[1]) == CONST_INT)
4521 {
4522 HOST_WIDE_INT low;
4523 HOST_WIDE_INT high;
4524
4525 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4526 {
4527 low = CONST_DOUBLE_LOW (operands[1]);
4528 high = CONST_DOUBLE_HIGH (operands[1]);
4529 }
4530 else
4531 {
4532 low = INTVAL (operands[1]);
4533 high = (low < 0) ? ~0 : 0;
4534 }
4535
4536 emit_move_insn (gen_rtx (SUBREG, SImode, operands[0], WORDS_BIG_ENDIAN),
4537 GEN_INT (low));
4538
4539 emit_move_insn (gen_rtx (SUBREG, SImode, operands[0], !WORDS_BIG_ENDIAN),
4540 GEN_INT (high));
4541 DONE;
4542 }
4543
4544 /* Stores between FPR and any non-FPR registers must go through a
4545 temporary stack slot. */
4546
4547 if (GET_CODE (operands[0]) == REG && GET_CODE (operands[1]) == REG
4548 && ((FP_REGNO_P (REGNO (operands[0]))
4549 && ! FP_REGNO_P (REGNO (operands[1])))
4550 || (FP_REGNO_P (REGNO (operands[1]))
4551 && ! FP_REGNO_P (REGNO (operands[0])))))
4552 {
4553 rtx stack_slot = assign_stack_temp (DImode, 8, 0);
4554
4555 emit_move_insn (stack_slot, operands[1]);
4556 emit_move_insn (operands[0], stack_slot);
4557 DONE;
4558 }
4559 }")
4560
4561 (define_insn ""
4562 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m,f,f,m")
4563 (match_operand:DI 1 "input_operand" "r,m,r,f,m,f"))]
4564 "! TARGET_POWERPC64 && (gpc_reg_operand (operands[0], DImode)
4565 || gpc_reg_operand (operands[1], DImode))"
4566 "*
4567 {
4568 switch (which_alternative)
4569 {
4570 case 0:
4571 /* We normally copy the low-numbered register first. However, if
4572 the first register operand 0 is the same as the second register of
4573 operand 1, we must copy in the opposite order. */
4574 if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
4575 return \"mr %L0,%L1\;mr %0,%1\";
4576 else
4577 return \"mr %0,%1\;mr %L0,%L1\";
4578 case 1:
4579 /* If the low-address word is used in the address, we must load it
4580 last. Otherwise, load it first. Note that we cannot have
4581 auto-increment in that case since the address register is known to be
4582 dead. */
4583 if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
4584 operands [1], 0))
4585 return \"{l|lwz} %L0,%L1\;{l|lwz} %0,%1\";
4586 else
4587 return \"{l%U1|lwz%U1} %0,%1\;{l|lwz} %L0,%L1\";
4588 case 2:
4589 return \"{st%U0|stw%U0} %1,%0\;{st|stw} %L1,%L0\";
4590 case 3:
4591 return \"fmr %0,%1\";
4592 case 4:
4593 return \"lfd%U1%X1 %0,%1\";
4594 case 5:
4595 return \"stfd%U0%X0 %1,%0\";
4596 }
4597 }"
4598 [(set_attr "type" "*,load,*,fp,fpload,*")
4599 (set_attr "length" "8,8,8,*,*,*")])
4600
4601 (define_insn ""
4602 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m,r,r,r,f,f,m,r,*h")
4603 (match_operand:DI 1 "input_operand" "r,m,r,I,J,R,f,m,f,*h,r"))]
4604 "TARGET_POWERPC64 && (gpc_reg_operand (operands[0], DImode)
4605 || gpc_reg_operand (operands[1], DImode))"
4606 "@
4607 mr %0,%1
4608 ld%U1%X1 %0,%1
4609 sd%U0%X0 %1,%0
4610 li %0,%1
4611 lis %0,%u1
4612 {cal|la} %0,%1(%*)
4613 fmr %0,%1
4614 lfd%U1%X1 %0,%1
4615 stfd%U0%X0 %1,%0
4616 mf%1 %0
4617 mt%0 %1"
4618 [(set_attr "type" "*,load,*,*,*,*,fp,fpload,*,*,mtjmpr")])
4619 \f
4620 ;; TImode is similar, except that we usually want to compute the address into
4621 ;; a register and use lsi/stsi (the exception is during reload). MQ is also
4622 ;; clobbered in stsi for POWER, so we need a SCRATCH for it.
4623 (define_expand "movti"
4624 [(parallel [(set (match_operand:TI 0 "general_operand" "")
4625 (match_operand:TI 1 "general_operand" ""))
4626 (clobber (scratch:SI))])]
4627 "TARGET_STRING || TARGET_POWERPC64"
4628 "
4629 {
4630 if (GET_CODE (operands[0]) == MEM)
4631 operands[1] = force_reg (TImode, operands[1]);
4632
4633 if (GET_CODE (operands[0]) == MEM
4634 && GET_CODE (XEXP (operands[0], 0)) != REG
4635 && ! reload_in_progress)
4636 operands[0] = change_address (operands[0], TImode,
4637 copy_addr_to_reg (XEXP (operands[0], 0)));
4638
4639 if (GET_CODE (operands[1]) == MEM
4640 && GET_CODE (XEXP (operands[1], 0)) != REG
4641 && ! reload_in_progress)
4642 operands[1] = change_address (operands[1], TImode,
4643 copy_addr_to_reg (XEXP (operands[1], 0)));
4644 }")
4645
4646 ;; We say that MQ is clobbered in the last alternative because the first
4647 ;; alternative would never get used otherwise since it would need a reload
4648 ;; while the 2nd alternative would not. We put memory cases first so they
4649 ;; are preferred. Otherwise, we'd try to reload the output instead of
4650 ;; giving the SCRATCH mq.
4651 (define_insn ""
4652 [(set (match_operand:TI 0 "reg_or_mem_operand" "=Q,m,????r,????r,????r")
4653 (match_operand:TI 1 "reg_or_mem_operand" "r,r,r,Q,m"))
4654 (clobber (match_scratch:SI 2 "=q,q#X,X,X,X"))]
4655 "TARGET_STRING && TARGET_POWER && ! TARGET_POWERPC64
4656 && (gpc_reg_operand (operands[0], TImode) || gpc_reg_operand (operands[1], TImode))"
4657 "*
4658 {
4659 switch (which_alternative)
4660 {
4661 default:
4662 abort ();
4663
4664 case 0:
4665 return \"{stsi|stswi} %1,%P0,16\";
4666
4667 case 1:
4668 return \"{st%U0|stw%U0} %1,%0\;{st|stw} %L1,%L0\;{st|stw} %Y1,%Y0\;{st|stw} %Z1,%Z0\";
4669
4670 case 2:
4671 /* Normally copy registers with lowest numbered register copied first.
4672 But copy in the other order if the first register of the output
4673 is the second, third, or fourth register in the input. */
4674 if (REGNO (operands[0]) >= REGNO (operands[1]) + 1
4675 && REGNO (operands[0]) <= REGNO (operands[1]) + 3)
4676 return \"mr %Z0,%Z1\;mr %Y0,%Y1\;mr %L0,%L1\;mr %0,%1\";
4677 else
4678 return \"mr %0,%1\;mr %L0,%L1\;mr %Y0,%Y1\;mr %Z0,%Z1\";
4679 case 3:
4680 /* If the address is not used in the output, we can use lsi. Otherwise,
4681 fall through to generating four loads. */
4682 if (! reg_overlap_mentioned_p (operands[0], operands[1]))
4683 return \"{lsi|lswi} %0,%P1,16\";
4684 /* ... fall through ... */
4685 case 4:
4686 /* If the address register is the same as the register for the lowest-
4687 addressed word, load it last. Similarly for the next two words.
4688 Otherwise load lowest address to highest. */
4689 if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
4690 operands[1], 0))
4691 return \"{l|lwz} %L0,%L1\;{l|lwz} %Y0,%Y1\;{l|lwz} %Z0,%Z1\;{l|lwz} %0,%1\";
4692 else if (refers_to_regno_p (REGNO (operands[0]) + 1,
4693 REGNO (operands[0]) + 2, operands[1], 0))
4694 return \"{l|lwz} %0,%1\;{l|lwz} %Y0,%Y1\;{l|lwz} %Z0,%Z1\;{l|lwz} %L0,%L1\";
4695 else if (refers_to_regno_p (REGNO (operands[0]) + 2,
4696 REGNO (operands[0]) + 3, operands[1], 0))
4697 return \"{l|lwz} %0,%1\;{l|lwz} %L0,%L1\;{l|lwz} %Z0,%Z1\;{l|lwz} %Y0,%Y1\";
4698 else
4699 return \"{l%U1|lwz%U1} %0,%1\;{l|lwz} %L0,%L1\;{l|lwz} %Y0,%Y1\;{l|lwz} %Z0,%Z1\";
4700 }
4701 }"
4702 [(set_attr "type" "*,load,load,*,*")
4703 (set_attr "length" "*,16,16,*,16")])
4704
4705 (define_insn ""
4706 [(set (match_operand:TI 0 "reg_or_mem_operand" "=m,????r,????r")
4707 (match_operand:TI 1 "reg_or_mem_operand" "r,r,m"))
4708 (clobber (match_scratch:SI 2 "=X,X,X"))]
4709 "TARGET_STRING && !TARGET_POWER && ! TARGET_POWERPC64
4710 && (gpc_reg_operand (operands[0], TImode) || gpc_reg_operand (operands[1], TImode))"
4711 "*
4712 {
4713 switch (which_alternative)
4714 {
4715 default:
4716 abort ();
4717
4718 case 0:
4719 return \"{st%U0|stw%U0} %1,%0\;{st|stw} %L1,%L0\;{st|stw} %Y1,%Y0\;{st|stw} %Z1,%Z0\";
4720
4721 case 1:
4722 /* Normally copy registers with lowest numbered register copied first.
4723 But copy in the other order if the first register of the output
4724 is the second, third, or fourth register in the input. */
4725 if (REGNO (operands[0]) >= REGNO (operands[1]) + 1
4726 && REGNO (operands[0]) <= REGNO (operands[1]) + 3)
4727 return \"mr %Z0,%Z1\;mr %Y0,%Y1\;mr %L0,%L1\;mr %0,%1\";
4728 else
4729 return \"mr %0,%1\;mr %L0,%L1\;mr %Y0,%Y1\;mr %Z0,%Z1\";
4730 case 2:
4731 /* If the address register is the same as the register for the lowest-
4732 addressed word, load it last. Similarly for the next two words.
4733 Otherwise load lowest address to highest. */
4734 if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
4735 operands[1], 0))
4736 return \"{l|lwz} %L0,%L1\;{l|lwz} %Y0,%Y1\;{l|lwz} %Z0,%Z1\;{l|lwz} %0,%1\";
4737 else if (refers_to_regno_p (REGNO (operands[0]) + 1,
4738 REGNO (operands[0]) + 2, operands[1], 0))
4739 return \"{l|lwz} %0,%1\;{l|lwz} %Y0,%Y1\;{l|lwz} %Z0,%Z1\;{l|lwz} %L0,%L1\";
4740 else if (refers_to_regno_p (REGNO (operands[0]) + 2,
4741 REGNO (operands[0]) + 3, operands[1], 0))
4742 return \"{l|lwz} %0,%1\;{l|lwz} %L0,%L1\;{l|lwz} %Z0,%Z1\;{l|lwz} %Y0,%Y1\";
4743 else
4744 return \"{l%U1|lwz%U1} %0,%1\;{l|lwz} %L0,%L1\;{l|lwz} %Y0,%Y1\;{l|lwz} %Z0,%Z1\";
4745 }
4746 }"
4747 [(set_attr "type" "load,*,*")
4748 (set_attr "length" "16,16,16")])
4749
4750 (define_insn ""
4751 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,r,m")
4752 (match_operand:TI 1 "input_operand" "r,m,r"))]
4753 "TARGET_POWERPC64 && (gpc_reg_operand (operands[0], TImode)
4754 || gpc_reg_operand (operands[1], TImode))"
4755 "*
4756 {
4757 switch (which_alternative)
4758 {
4759 case 0:
4760 /* We normally copy the low-numbered register first. However, if
4761 the first register operand 0 is the same as the second register of
4762 operand 1, we must copy in the opposite order. */
4763 if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
4764 return \"mr %L0,%L1\;mr %0,%1\";
4765 else
4766 return \"mr %0,%1\;mr %L0,%L1\";
4767 case 1:
4768 /* If the low-address word is used in the address, we must load it
4769 last. Otherwise, load it first. Note that we cannot have
4770 auto-increment in that case since the address register is known to be
4771 dead. */
4772 if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
4773 operands [1], 0))
4774 return \"ld %L0,%L1\;ld %0,%1\";
4775 else
4776 return \"ld%U1 %0,%1\;ld %L0,%L1\";
4777 case 2:
4778 return \"std%U0 %1,%0\;std %L1,%L0\";
4779 }
4780 }"
4781 [(set_attr "type" "*,load,*")
4782 (set_attr "length" "8,8,8")])
4783 \f
4784 (define_expand "load_multiple"
4785 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
4786 (match_operand:SI 1 "" ""))
4787 (use (match_operand:SI 2 "" ""))])]
4788 "TARGET_STRING"
4789 "
4790 {
4791 int regno;
4792 int count;
4793 rtx from;
4794 int i;
4795
4796 /* Support only loading a constant number of fixed-point registers from
4797 memory and only bother with this if more than two; the machine
4798 doesn't support more than eight. */
4799 if (GET_CODE (operands[2]) != CONST_INT
4800 || INTVAL (operands[2]) <= 2
4801 || INTVAL (operands[2]) > 8
4802 || GET_CODE (operands[1]) != MEM
4803 || GET_CODE (operands[0]) != REG
4804 || REGNO (operands[0]) >= 32)
4805 FAIL;
4806
4807 count = INTVAL (operands[2]);
4808 regno = REGNO (operands[0]);
4809
4810 operands[3] = gen_rtx (PARALLEL, VOIDmode, rtvec_alloc (count));
4811 from = force_reg (SImode, XEXP (operands[1], 0));
4812
4813 for (i = 0; i < count; i++)
4814 XVECEXP (operands[3], 0, i)
4815 = gen_rtx (SET, VOIDmode, gen_rtx (REG, SImode, regno + i),
4816 gen_rtx (MEM, SImode, plus_constant (from, i * 4)));
4817 }")
4818
4819 (define_insn ""
4820 [(match_parallel 0 "load_multiple_operation"
4821 [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
4822 (mem:SI (match_operand:SI 2 "register_operand" "b")))])]
4823 "TARGET_STRING"
4824 "*
4825 {
4826 /* We have to handle the case where the pseudo used to contain the address
4827 is assigned to one of the output registers. */
4828 int i, j;
4829 int words = XVECLEN (operands[0], 0);
4830 rtx xop[10];
4831
4832 if (XVECLEN (operands[0], 0) == 1)
4833 return \"{l|lwz} %1,0(%2)\";
4834
4835 for (i = 0; i < words; i++)
4836 if (refers_to_regno_p (REGNO (operands[1]) + i,
4837 REGNO (operands[1]) + i + 1, operands[2], 0))
4838 {
4839 if (i == words-1)
4840 {
4841 xop[0] = operands[1];
4842 xop[1] = operands[2];
4843 xop[2] = GEN_INT (4 * (words-1));
4844 output_asm_insn (\"{lsi|lswi} %0,%1,%2\;{l|lwz} %1,%2(%1)\", xop);
4845 return \"\";
4846 }
4847 else if (i == 0)
4848 {
4849 xop[0] = operands[1];
4850 xop[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1);
4851 xop[2] = GEN_INT (4 * (words-1));
4852 output_asm_insn (\"{cal %0,4(%0)|addi %0,%0,4}\;{lsi|lswi} %1,%0,%2\;{l|lwz} %0,-4(%0)\", xop);
4853 return \"\";
4854 }
4855 else
4856 {
4857 for (j = 0; j < words; j++)
4858 if (j != i)
4859 {
4860 xop[0] = gen_rtx (REG, SImode, REGNO (operands[1]) + j);
4861 xop[1] = operands[2];
4862 xop[2] = GEN_INT (j * 4);
4863 output_asm_insn (\"{l|lwz} %0,%2(%1)\", xop);
4864 }
4865 xop[0] = operands[2];
4866 xop[1] = GEN_INT (i * 4);
4867 output_asm_insn (\"{l|lwz} %0,%1(%0)\", xop);
4868 return \"\";
4869 }
4870 }
4871
4872 return \"{lsi|lswi} %1,%2,%N0\";
4873 }"
4874 [(set_attr "type" "load")
4875 (set_attr "length" "32")])
4876 \f
4877
4878 (define_expand "store_multiple"
4879 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
4880 (match_operand:SI 1 "" ""))
4881 (clobber (scratch:SI))
4882 (use (match_operand:SI 2 "" ""))])]
4883 "TARGET_STRING"
4884 "
4885 {
4886 int regno;
4887 int count;
4888 rtx to;
4889 int i;
4890
4891 /* Support only storing a constant number of fixed-point registers to
4892 memory and only bother with this if more than two; the machine
4893 doesn't support more than eight. */
4894 if (GET_CODE (operands[2]) != CONST_INT
4895 || INTVAL (operands[2]) <= 2
4896 || INTVAL (operands[2]) > 8
4897 || GET_CODE (operands[0]) != MEM
4898 || GET_CODE (operands[1]) != REG
4899 || REGNO (operands[1]) >= 32)
4900 FAIL;
4901
4902 count = INTVAL (operands[2]);
4903 regno = REGNO (operands[1]);
4904
4905 operands[3] = gen_rtx (PARALLEL, VOIDmode, rtvec_alloc (count + 1));
4906 to = force_reg (SImode, XEXP (operands[0], 0));
4907
4908 XVECEXP (operands[3], 0, 0)
4909 = gen_rtx (SET, VOIDmode, gen_rtx (MEM, SImode, to), operands[1]);
4910 XVECEXP (operands[3], 0, 1) = gen_rtx (CLOBBER, VOIDmode,
4911 gen_rtx (SCRATCH, SImode));
4912
4913 for (i = 1; i < count; i++)
4914 XVECEXP (operands[3], 0, i + 1)
4915 = gen_rtx (SET, VOIDmode,
4916 gen_rtx (MEM, SImode, plus_constant (to, i * 4)),
4917 gen_rtx (REG, SImode, regno + i));
4918 }")
4919
4920 (define_insn ""
4921 [(match_parallel 0 "store_multiple_operation"
4922 [(set (match_operand:SI 1 "indirect_operand" "=Q")
4923 (match_operand:SI 2 "gpc_reg_operand" "r"))
4924 (clobber (match_scratch:SI 3 "=q"))])]
4925 "TARGET_STRING && TARGET_POWER"
4926 "{stsi|stswi} %2,%P1,%O0")
4927
4928 (define_insn ""
4929 [(match_parallel 0 "store_multiple_operation"
4930 [(set (mem:SI (match_operand:SI 1 "register_operand" "b"))
4931 (match_operand:SI 2 "gpc_reg_operand" "r"))
4932 (clobber (match_scratch:SI 3 "X"))])]
4933 "TARGET_STRING && !TARGET_POWER"
4934 "{stsi|stswi} %2,%1,%O0")
4935
4936 \f
4937 ;; String/block move insn.
4938 ;; Argument 0 is the destination
4939 ;; Argument 1 is the source
4940 ;; Argument 2 is the length
4941 ;; Argument 3 is the alignment
4942
4943 (define_expand "movstrsi"
4944 [(parallel [(set (match_operand:BLK 0 "" "")
4945 (match_operand:BLK 1 "" ""))
4946 (use (match_operand:SI 2 "" ""))
4947 (use (match_operand:SI 3 "" ""))])]
4948 ""
4949 "
4950 {
4951 if (expand_block_move (operands))
4952 DONE;
4953 else
4954 FAIL;
4955 }")
4956
4957 ;; Move up to 32 bytes at a time. The fixed registers are needed because the
4958 ;; register allocator doesn't have a clue about allocating 8 word registers
4959 (define_expand "movstrsi_8reg"
4960 [(parallel [(set (match_operand 0 "" "")
4961 (match_operand 1 "" ""))
4962 (use (match_operand 2 "" ""))
4963 (use (match_operand 3 "" ""))
4964 (clobber (reg:SI 5))
4965 (clobber (reg:SI 6))
4966 (clobber (reg:SI 7))
4967 (clobber (reg:SI 8))
4968 (clobber (reg:SI 9))
4969 (clobber (reg:SI 10))
4970 (clobber (reg:SI 11))
4971 (clobber (reg:SI 12))
4972 (clobber (match_scratch:SI 4 ""))])]
4973 "TARGET_STRING"
4974 "")
4975
4976 (define_insn ""
4977 [(set (mem:BLK (match_operand:SI 0 "register_operand" "b"))
4978 (mem:BLK (match_operand:SI 1 "register_operand" "b")))
4979 (use (match_operand:SI 2 "immediate_operand" "i"))
4980 (use (match_operand:SI 3 "immediate_operand" "i"))
4981 (clobber (match_operand:SI 4 "register_operand" "=r"))
4982 (clobber (reg:SI 6))
4983 (clobber (reg:SI 7))
4984 (clobber (reg:SI 8))
4985 (clobber (reg:SI 9))
4986 (clobber (reg:SI 10))
4987 (clobber (reg:SI 11))
4988 (clobber (reg:SI 12))
4989 (clobber (match_scratch:SI 5 "=q"))]
4990 "TARGET_STRING && TARGET_POWER
4991 && ((INTVAL (operands[2]) > 24 && INTVAL (operands[2]) < 32) || INTVAL (operands[2]) == 0)
4992 && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 12)
4993 && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 12)
4994 && REGNO (operands[4]) == 5"
4995 "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2"
4996 [(set_attr "length" "8")])
4997
4998 (define_insn ""
4999 [(set (mem:BLK (match_operand:SI 0 "register_operand" "b"))
5000 (mem:BLK (match_operand:SI 1 "register_operand" "b")))
5001 (use (match_operand:SI 2 "immediate_operand" "i"))
5002 (use (match_operand:SI 3 "immediate_operand" "i"))
5003 (clobber (match_operand:SI 4 "register_operand" "=r"))
5004 (clobber (reg:SI 6))
5005 (clobber (reg:SI 7))
5006 (clobber (reg:SI 8))
5007 (clobber (reg:SI 9))
5008 (clobber (reg:SI 10))
5009 (clobber (reg:SI 11))
5010 (clobber (reg:SI 12))
5011 (clobber (match_scratch:SI 5 "X"))]
5012 "TARGET_STRING && !TARGET_POWER
5013 && ((INTVAL (operands[2]) > 24 && INTVAL (operands[2]) < 32) || INTVAL (operands[2]) == 0)
5014 && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 12)
5015 && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 12)
5016 && REGNO (operands[4]) == 5"
5017 "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2"
5018 [(set_attr "length" "8")])
5019
5020 ;; Move up to 24 bytes at a time. The fixed registers are needed because the
5021 ;; register allocator doesn't have a clue about allocating 6 word registers
5022 (define_expand "movstrsi_6reg"
5023 [(parallel [(set (match_operand 0 "" "")
5024 (match_operand 1 "" ""))
5025 (use (match_operand 2 "" ""))
5026 (use (match_operand 3 "" ""))
5027 (clobber (reg:SI 7))
5028 (clobber (reg:SI 8))
5029 (clobber (reg:SI 9))
5030 (clobber (reg:SI 10))
5031 (clobber (reg:SI 11))
5032 (clobber (reg:SI 12))
5033 (clobber (match_scratch:SI 4 ""))])]
5034 "TARGET_STRING"
5035 "")
5036
5037 (define_insn ""
5038 [(set (mem:BLK (match_operand:SI 0 "register_operand" "b"))
5039 (mem:BLK (match_operand:SI 1 "register_operand" "b")))
5040 (use (match_operand:SI 2 "immediate_operand" "i"))
5041 (use (match_operand:SI 3 "immediate_operand" "i"))
5042 (clobber (match_operand:SI 4 "register_operand" "=r"))
5043 (clobber (reg:SI 8))
5044 (clobber (reg:SI 9))
5045 (clobber (reg:SI 10))
5046 (clobber (reg:SI 11))
5047 (clobber (reg:SI 12))
5048 (clobber (match_scratch:SI 5 "=q"))]
5049 "TARGET_STRING && TARGET_POWER
5050 && INTVAL (operands[2]) > 16 && INTVAL (operands[2]) <= 24
5051 && (REGNO (operands[0]) < 7 || REGNO (operands[0]) > 12)
5052 && (REGNO (operands[1]) < 7 || REGNO (operands[1]) > 12)
5053 && REGNO (operands[4]) == 7"
5054 "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2"
5055 [(set_attr "length" "8")])
5056
5057 (define_insn ""
5058 [(set (mem:BLK (match_operand:SI 0 "register_operand" "b"))
5059 (mem:BLK (match_operand:SI 1 "register_operand" "b")))
5060 (use (match_operand:SI 2 "immediate_operand" "i"))
5061 (use (match_operand:SI 3 "immediate_operand" "i"))
5062 (clobber (match_operand:SI 4 "register_operand" "=r"))
5063 (clobber (reg:SI 8))
5064 (clobber (reg:SI 9))
5065 (clobber (reg:SI 10))
5066 (clobber (reg:SI 11))
5067 (clobber (reg:SI 12))
5068 (clobber (match_scratch:SI 5 "X"))]
5069 "TARGET_STRING && !TARGET_POWER
5070 && INTVAL (operands[2]) > 16 && INTVAL (operands[2]) <= 32
5071 && (REGNO (operands[0]) < 7 || REGNO (operands[0]) > 12)
5072 && (REGNO (operands[1]) < 7 || REGNO (operands[1]) > 12)
5073 && REGNO (operands[4]) == 7"
5074 "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2"
5075 [(set_attr "length" "8")])
5076
5077 ;; Move up to 16 bytes at a time, using 4 fixed registers to avoid spill problems
5078 ;; with TImode
5079 (define_expand "movstrsi_4reg"
5080 [(parallel [(set (match_operand 0 "" "")
5081 (match_operand 1 "" ""))
5082 (use (match_operand 2 "" ""))
5083 (use (match_operand 3 "" ""))
5084 (clobber (reg:SI 9))
5085 (clobber (reg:SI 10))
5086 (clobber (reg:SI 11))
5087 (clobber (reg:SI 12))
5088 (clobber (match_scratch:SI 4 ""))])]
5089 "TARGET_STRING"
5090 "")
5091
5092 (define_insn ""
5093 [(set (mem:BLK (match_operand:SI 0 "register_operand" "b"))
5094 (mem:BLK (match_operand:SI 1 "register_operand" "b")))
5095 (use (match_operand:SI 2 "immediate_operand" "i"))
5096 (use (match_operand:SI 3 "immediate_operand" "i"))
5097 (clobber (match_operand:SI 4 "register_operand" "=r"))
5098 (clobber (reg:SI 10))
5099 (clobber (reg:SI 11))
5100 (clobber (reg:SI 12))
5101 (clobber (match_scratch:SI 5 "=q"))]
5102 "TARGET_STRING && TARGET_POWER
5103 && INTVAL (operands[2]) > 8 && INTVAL (operands[2]) <= 16
5104 && (REGNO (operands[0]) < 9 || REGNO (operands[0]) > 12)
5105 && (REGNO (operands[1]) < 9 || REGNO (operands[1]) > 12)
5106 && REGNO (operands[4]) == 9"
5107 "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2"
5108 [(set_attr "length" "8")])
5109
5110 (define_insn ""
5111 [(set (mem:BLK (match_operand:SI 0 "register_operand" "b"))
5112 (mem:BLK (match_operand:SI 1 "register_operand" "b")))
5113 (use (match_operand:SI 2 "immediate_operand" "i"))
5114 (use (match_operand:SI 3 "immediate_operand" "i"))
5115 (clobber (match_operand:SI 4 "register_operand" "=r"))
5116 (clobber (reg:SI 10))
5117 (clobber (reg:SI 11))
5118 (clobber (reg:SI 12))
5119 (clobber (match_scratch:SI 5 "X"))]
5120 "TARGET_STRING && !TARGET_POWER
5121 && INTVAL (operands[2]) > 8 && INTVAL (operands[2]) <= 16
5122 && (REGNO (operands[0]) < 9 || REGNO (operands[0]) > 12)
5123 && (REGNO (operands[1]) < 9 || REGNO (operands[1]) > 12)
5124 && REGNO (operands[4]) == 9"
5125 "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2"
5126 [(set_attr "length" "8")])
5127
5128 ;; Move up to 8 bytes at a time.
5129 (define_expand "movstrsi_2reg"
5130 [(parallel [(set (match_operand 0 "" "")
5131 (match_operand 1 "" ""))
5132 (use (match_operand 2 "" ""))
5133 (use (match_operand 3 "" ""))
5134 (clobber (match_scratch:DI 4 ""))
5135 (clobber (match_scratch:SI 5 ""))])]
5136 "TARGET_STRING && !TARGET_64BIT"
5137 "")
5138
5139 (define_insn ""
5140 [(set (mem:BLK (match_operand:SI 0 "register_operand" "b"))
5141 (mem:BLK (match_operand:SI 1 "register_operand" "b")))
5142 (use (match_operand:SI 2 "immediate_operand" "i"))
5143 (use (match_operand:SI 3 "immediate_operand" "i"))
5144 (clobber (match_scratch:DI 4 "=&r"))
5145 (clobber (match_scratch:SI 5 "=q"))]
5146 "TARGET_STRING && TARGET_POWER && !TARGET_64BIT
5147 && INTVAL (operands[2]) > 4 && INTVAL (operands[2]) <= 8"
5148 "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2"
5149 [(set_attr "length" "8")])
5150
5151 (define_insn ""
5152 [(set (mem:BLK (match_operand:SI 0 "register_operand" "b"))
5153 (mem:BLK (match_operand:SI 1 "register_operand" "b")))
5154 (use (match_operand:SI 2 "immediate_operand" "i"))
5155 (use (match_operand:SI 3 "immediate_operand" "i"))
5156 (clobber (match_scratch:DI 4 "=&r"))
5157 (clobber (match_scratch:SI 5 "X"))]
5158 "TARGET_STRING && !TARGET_POWER && !TARGET_64BIT
5159 && INTVAL (operands[2]) > 4 && INTVAL (operands[2]) <= 8"
5160 "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2"
5161 [(set_attr "length" "8")])
5162
5163 ;; Move up to 4 bytes at a time.
5164 (define_expand "movstrsi_1reg"
5165 [(parallel [(set (match_operand 0 "" "")
5166 (match_operand 1 "" ""))
5167 (use (match_operand 2 "" ""))
5168 (use (match_operand 3 "" ""))
5169 (clobber (match_scratch:SI 4 ""))
5170 (clobber (match_scratch:SI 5 ""))])]
5171 "TARGET_STRING"
5172 "")
5173
5174 (define_insn ""
5175 [(set (mem:BLK (match_operand:SI 0 "register_operand" "b"))
5176 (mem:BLK (match_operand:SI 1 "register_operand" "b")))
5177 (use (match_operand:SI 2 "immediate_operand" "i"))
5178 (use (match_operand:SI 3 "immediate_operand" "i"))
5179 (clobber (match_scratch:SI 4 "=&r"))
5180 (clobber (match_scratch:SI 5 "=q"))]
5181 "TARGET_STRING && TARGET_POWER
5182 && INTVAL (operands[2]) > 0 && INTVAL (operands[2]) <= 4"
5183 "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2"
5184 [(set_attr "length" "8")])
5185
5186 (define_insn ""
5187 [(set (mem:BLK (match_operand:SI 0 "register_operand" "b"))
5188 (mem:BLK (match_operand:SI 1 "register_operand" "b")))
5189 (use (match_operand:SI 2 "immediate_operand" "i"))
5190 (use (match_operand:SI 3 "immediate_operand" "i"))
5191 (clobber (match_scratch:SI 4 "=&r"))
5192 (clobber (match_scratch:SI 5 "X"))]
5193 "TARGET_STRING && !TARGET_POWER
5194 && INTVAL (operands[2]) > 0 && INTVAL (operands[2]) <= 4"
5195 "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2"
5196 [(set_attr "length" "8")])
5197
5198 \f
5199 ;; Define insns that do load or store with update. Some of these we can
5200 ;; get by using pre-decrement or pre-increment, but the hardware can also
5201 ;; do cases where the increment is not the size of the object.
5202 ;;
5203 ;; In all these cases, we use operands 0 and 1 for the register being
5204 ;; incremented because those are the operands that local-alloc will
5205 ;; tie and these are the pair most likely to be tieable (and the ones
5206 ;; that will benefit the most).
5207
5208 (define_insn ""
5209 [(set (match_operand:DI 3 "gpc_reg_operand" "=r,r")
5210 (mem:DI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0,0")
5211 (match_operand:DI 2 "reg_or_short_operand" "r,I"))))
5212 (set (match_operand:DI 0 "gpc_reg_operand" "=b,b")
5213 (plus:DI (match_dup 1) (match_dup 2)))]
5214 "TARGET_POWERPC64"
5215 "@
5216 ldux %3,%0,%2
5217 ldu %3,%2(%0)"
5218 [(set_attr "type" "load")])
5219
5220 (define_insn ""
5221 [(set (match_operand:DI 3 "gpc_reg_operand" "=r")
5222 (sign_extend:DI
5223 (mem:SI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0")
5224 (match_operand:DI 2 "gpc_reg_operand" "r")))))
5225 (set (match_operand:DI 0 "gpc_reg_operand" "=b")
5226 (plus:DI (match_dup 1) (match_dup 2)))]
5227 "TARGET_POWERPC64"
5228 "lwaux %3,%0,%2"
5229 [(set_attr "type" "load")])
5230
5231 (define_insn "movdi_update"
5232 [(set (mem:DI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0,0")
5233 (match_operand:DI 2 "reg_or_short_operand" "r,I")))
5234 (match_operand:DI 3 "gpc_reg_operand" "r,r"))
5235 (set (match_operand:DI 0 "gpc_reg_operand" "=b,b")
5236 (plus:DI (match_dup 1) (match_dup 2)))]
5237 "TARGET_POWERPC64"
5238 "@
5239 stdux %3,%0,%2
5240 stdu %3,%2(%0)")
5241
5242 (define_insn ""
5243 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
5244 (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
5245 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
5246 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
5247 (plus:SI (match_dup 1) (match_dup 2)))]
5248 ""
5249 "@
5250 {lux|lwzux} %3,%0,%2
5251 {lu|lwzu} %3,%2(%0)"
5252 [(set_attr "type" "load")])
5253
5254 (define_insn "movsi_update"
5255 [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
5256 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
5257 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
5258 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
5259 (plus:SI (match_dup 1) (match_dup 2)))]
5260 ""
5261 "@
5262 {stux|stwux} %3,%0,%2
5263 {stu|stwu} %3,%2(%0)")
5264
5265 (define_insn ""
5266 [(set (match_operand:HI 3 "gpc_reg_operand" "=r,r")
5267 (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
5268 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
5269 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
5270 (plus:SI (match_dup 1) (match_dup 2)))]
5271 ""
5272 "@
5273 lhzux %3,%0,%2
5274 lhzu %3,%2(%0)"
5275 [(set_attr "type" "load")])
5276
5277 (define_insn ""
5278 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
5279 (zero_extend:SI
5280 (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
5281 (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
5282 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
5283 (plus:SI (match_dup 1) (match_dup 2)))]
5284 ""
5285 "@
5286 lhzux %3,%0,%2
5287 lhzu %3,%2(%0)"
5288 [(set_attr "type" "load")])
5289
5290 (define_insn ""
5291 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
5292 (sign_extend:SI
5293 (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
5294 (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
5295 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
5296 (plus:SI (match_dup 1) (match_dup 2)))]
5297 ""
5298 "@
5299 lhaux %3,%0,%2
5300 lhau %3,%2(%0)"
5301 [(set_attr "type" "load")])
5302
5303 (define_insn ""
5304 [(set (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
5305 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
5306 (match_operand:HI 3 "gpc_reg_operand" "r,r"))
5307 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
5308 (plus:SI (match_dup 1) (match_dup 2)))]
5309 ""
5310 "@
5311 sthux %3,%0,%2
5312 sthu %3,%2(%0)")
5313
5314 (define_insn ""
5315 [(set (match_operand:QI 3 "gpc_reg_operand" "=r,r")
5316 (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
5317 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
5318 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
5319 (plus:SI (match_dup 1) (match_dup 2)))]
5320 ""
5321 "@
5322 lbzux %3,%0,%2
5323 lbzu %3,%2(%0)"
5324 [(set_attr "type" "load")])
5325
5326 (define_insn ""
5327 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
5328 (zero_extend:SI
5329 (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
5330 (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
5331 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
5332 (plus:SI (match_dup 1) (match_dup 2)))]
5333 ""
5334 "@
5335 lbzux %3,%0,%2
5336 lbzu %3,%2(%0)"
5337 [(set_attr "type" "load")])
5338
5339 (define_insn ""
5340 [(set (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
5341 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
5342 (match_operand:QI 3 "gpc_reg_operand" "r,r"))
5343 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
5344 (plus:SI (match_dup 1) (match_dup 2)))]
5345 ""
5346 "@
5347 stbux %3,%0,%2
5348 stbu %3,%2(%0)")
5349
5350 (define_insn ""
5351 [(set (match_operand:SF 3 "gpc_reg_operand" "=f,f")
5352 (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
5353 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
5354 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
5355 (plus:SI (match_dup 1) (match_dup 2)))]
5356 "TARGET_HARD_FLOAT"
5357 "@
5358 lfsux %3,%0,%2
5359 lfsu %3,%2(%0)"
5360 [(set_attr "type" "fpload")])
5361
5362 (define_insn ""
5363 [(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
5364 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
5365 (match_operand:SF 3 "gpc_reg_operand" "f,f"))
5366 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
5367 (plus:SI (match_dup 1) (match_dup 2)))]
5368 "TARGET_HARD_FLOAT"
5369 "@
5370 stfsux %3,%0,%2
5371 stfsu %3,%2(%0)")
5372
5373 (define_insn ""
5374 [(set (match_operand:DF 3 "gpc_reg_operand" "=f,f")
5375 (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
5376 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
5377 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
5378 (plus:SI (match_dup 1) (match_dup 2)))]
5379 "TARGET_HARD_FLOAT"
5380 "@
5381 lfdux %3,%0,%2
5382 lfdu %3,%2(%0)"
5383 [(set_attr "type" "fpload")])
5384
5385 (define_insn ""
5386 [(set (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
5387 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
5388 (match_operand:DF 3 "gpc_reg_operand" "f,f"))
5389 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
5390 (plus:SI (match_dup 1) (match_dup 2)))]
5391 "TARGET_HARD_FLOAT"
5392 "@
5393 stfdux %3,%0,%2
5394 stfdu %3,%2(%0)")
5395
5396 ;; Peephole to convert two consecutive FP loads or stores into lfq/stfq.
5397
5398 (define_peephole
5399 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
5400 (match_operand:DF 1 "memory_operand" ""))
5401 (set (match_operand:DF 2 "gpc_reg_operand" "=f")
5402 (match_operand:DF 3 "memory_operand" ""))]
5403 "TARGET_POWER2
5404 && TARGET_HARD_FLOAT
5405 && registers_ok_for_quad_peep (operands[0], operands[2])
5406 && ! MEM_VOLATILE_P (operands[1]) && ! MEM_VOLATILE_P (operands[3])
5407 && addrs_ok_for_quad_peep (XEXP (operands[1], 0), XEXP (operands[3], 0))"
5408 "lfq%U1%X1 %0,%1")
5409
5410 (define_peephole
5411 [(set (match_operand:DF 0 "memory_operand" "")
5412 (match_operand:DF 1 "gpc_reg_operand" "f"))
5413 (set (match_operand:DF 2 "memory_operand" "")
5414 (match_operand:DF 3 "gpc_reg_operand" "f"))]
5415 "TARGET_POWER2
5416 && TARGET_HARD_FLOAT
5417 && registers_ok_for_quad_peep (operands[1], operands[3])
5418 && ! MEM_VOLATILE_P (operands[0]) && ! MEM_VOLATILE_P (operands[2])
5419 && addrs_ok_for_quad_peep (XEXP (operands[0], 0), XEXP (operands[2], 0))"
5420 "stfq%U0%X0 %1,%0")
5421 \f
5422 ;; Next come insns related to the calling sequence.
5423 ;;
5424 ;; First, an insn to allocate new stack space for dynamic use (e.g., alloca).
5425 ;; We move the back-chain and decrement the stack pointer.
5426
5427 (define_expand "allocate_stack"
5428 [(set (reg:SI 1)
5429 (minus:SI (reg:SI 1) (match_operand:SI 0 "reg_or_short_operand" "")))]
5430 ""
5431 "
5432 { rtx chain = gen_reg_rtx (Pmode);
5433 rtx stack_bot = gen_rtx (MEM, Pmode, stack_pointer_rtx);
5434 rtx neg_op0;
5435
5436 emit_move_insn (chain, stack_bot);
5437
5438 if (GET_CODE (operands[0]) != CONST_INT
5439 || INTVAL (operands[0]) < -32767
5440 || INTVAL (operands[0]) > 32768)
5441 {
5442 neg_op0 = gen_reg_rtx (Pmode);
5443 if (TARGET_POWERPC64)
5444 emit_insn (gen_negdi2 (neg_op0, operands[0]));
5445 else
5446 emit_insn (gen_negsi2 (neg_op0, operands[0]));
5447 }
5448 else
5449 neg_op0 = GEN_INT (- INTVAL (operands[0]));
5450
5451 if (TARGET_POWERPC64)
5452 emit_insn (gen_movdi_update (stack_pointer_rtx, stack_pointer_rtx, neg_op0, chain));
5453 else
5454 emit_insn (gen_movsi_update (stack_pointer_rtx, stack_pointer_rtx, neg_op0, chain));
5455
5456 DONE;
5457 }")
5458
5459 ;; These patterns say how to save and restore the stack pointer. We need not
5460 ;; save the stack pointer at function level since we are careful to
5461 ;; preserve the backchain. At block level, we have to restore the backchain
5462 ;; when we restore the stack pointer.
5463 ;;
5464 ;; For nonlocal gotos, we must save both the stack pointer and its
5465 ;; backchain and restore both. Note that in the nonlocal case, the
5466 ;; save area is a memory location.
5467
5468 (define_expand "save_stack_function"
5469 [(use (const_int 0))]
5470 ""
5471 "")
5472
5473 (define_expand "restore_stack_function"
5474 [(use (const_int 0))]
5475 ""
5476 "")
5477
5478 (define_expand "restore_stack_block"
5479 [(set (match_dup 2) (mem:SI (match_operand:SI 0 "register_operand" "")))
5480 (set (match_dup 0) (match_operand:SI 1 "register_operand" ""))
5481 (set (mem:SI (match_dup 0)) (match_dup 2))]
5482 ""
5483 "
5484 { operands[2] = gen_reg_rtx (SImode); }")
5485
5486 (define_expand "save_stack_nonlocal"
5487 [(match_operand:DI 0 "memory_operand" "")
5488 (match_operand:SI 1 "register_operand" "")]
5489 ""
5490 "
5491 {
5492 rtx temp = gen_reg_rtx (SImode);
5493
5494 /* Copy the backchain to the first word, sp to the second. */
5495 emit_move_insn (temp, gen_rtx (MEM, SImode, operands[1]));
5496 emit_move_insn (operand_subword (operands[0], 0, 0, DImode), temp);
5497 emit_move_insn (operand_subword (operands[0], 1, 0, DImode), operands[1]);
5498 DONE;
5499 }")
5500
5501 (define_expand "restore_stack_nonlocal"
5502 [(match_operand:SI 0 "register_operand" "")
5503 (match_operand:DI 1 "memory_operand" "")]
5504 ""
5505 "
5506 {
5507 rtx temp = gen_reg_rtx (SImode);
5508
5509 /* Restore the backchain from the first word, sp from the second. */
5510 emit_move_insn (temp, operand_subword (operands[1], 0, 0, DImode));
5511 emit_move_insn (operands[0], operand_subword (operands[1], 1, 0, DImode));
5512 emit_move_insn (gen_rtx (MEM, SImode, operands[0]), temp);
5513 DONE;
5514 }")
5515 \f
5516
5517 ;; A function pointer under AIX is a pointer to a data area whose first word
5518 ;; contains the actual address of the function, whose second word contains a
5519 ;; pointer to its TOC, and whose third word contains a value to place in the
5520 ;; static chain register (r11). Note that if we load the static chain, our
5521 ;; "trampoline" need not have any executable code.
5522 ;;
5523 ;; operands[0] is a register pointing to the 3 word descriptor (aka, the function address)
5524 ;; operands[1] is the stack size to clean up
5525 ;; operands[2] is the value FUNCTION_ARG returns for the VOID argument (must be 0 for AIX)
5526 ;; operands[3] is location to store the TOC
5527 ;; operands[4] is the TOC register
5528 ;; operands[5] is the static chain register
5529 ;;
5530 ;; We do not break this into separate insns, so that the scheduler will not try
5531 ;; to move the load of the new TOC before any loads from the TOC.
5532
5533 (define_insn "call_indirect_aix"
5534 [(call (mem:SI (match_operand:SI 0 "register_operand" "b"))
5535 (match_operand 1 "const_int_operand" "n"))
5536 (use (match_operand 2 "const_int_operand" "O"))
5537 (use (match_operand 3 "offsettable_addr_operand" "p"))
5538 (use (match_operand 4 "register_operand" "r"))
5539 (clobber (match_operand 5 "register_operand" "=r"))
5540 (clobber (match_scratch:SI 6 "=&r"))
5541 (clobber (match_scratch:SI 7 "=l"))]
5542 "DEFAULT_ABI == ABI_AIX"
5543 "{st|stw} %4,%a3\;{l|lwz} %6,0(%0)\;{l|lwz} %4,4(%0);\;mt%7 %6\;{l|lwz} %5,8(%0)\;{brl|blrl}\;{l|lwz} %4,%a3"
5544 [(set_attr "length" "28")])
5545
5546 (define_insn "call_value_indirect_aix"
5547 [(set (match_operand 0 "register_operand" "fg")
5548 (call (mem:SI (match_operand:SI 1 "register_operand" "b"))
5549 (match_operand 2 "const_int_operand" "n")))
5550 (use (match_operand 3 "const_int_operand" "O"))
5551 (use (match_operand 4 "offsettable_addr_operand" "p"))
5552 (use (match_operand 5 "register_operand" "r"))
5553 (clobber (match_operand 6 "register_operand" "=r"))
5554 (clobber (match_scratch:SI 7 "=&r"))
5555 (clobber (match_scratch:SI 8 "=l"))]
5556 "DEFAULT_ABI == ABI_AIX"
5557 "{st|stw} %5,%a4\;{l|lwz} %7,0(%1)\;{l|lwz} %5,4(%1);\;mt%8 %7\;{l|lwz} %6,8(%1)\;{brl|blrl}\;{l|lwz} %5,%a4"
5558 [(set_attr "length" "28")])
5559
5560 ;; A function pointer undef NT is a pointer to a data area whose first word
5561 ;; contains the actual address of the function, whose second word contains a
5562 ;; pointer to its TOC. The static chain is not stored under NT, which means
5563 ;; that we need a trampoline.
5564 ;;
5565 ;; operands[0] is an SImode pseudo in which we place the address of the function.
5566 ;; operands[1] is the stack size to clean up
5567 ;; operands[2] is the value FUNCTION_ARG returns for the VOID argument (must be 0 for NT)
5568 ;; operands[3] is location to store the TOC
5569 ;; operands[4] is the TOC register
5570 ;;
5571 ;; We do not break this into separate insns, so that the scheduler will not try
5572 ;; to move the load of the new TOC before any loads from the TOC.
5573
5574 (define_insn "call_indirect_nt"
5575 [(call (mem:SI (match_operand:SI 0 "register_operand" "b"))
5576 (match_operand 1 "const_int_operand" "n"))
5577 (use (match_operand 2 "const_int_operand" "O"))
5578 (use (match_operand 3 "offsettable_addr_operand" "p"))
5579 (use (match_operand 4 "register_operand" "r"))
5580 (clobber (match_scratch:SI 5 "=&r"))
5581 (clobber (match_scratch:SI 6 "=l"))]
5582 "DEFAULT_ABI == ABI_NT"
5583 "{st|stw} %4,%a3\;{l|lwz} %6,0(%0)\;{l|lwz} %4,4(%0);\;mt%6 %5\;{brl|blrl}\;{l|lwz} %4,%a3"
5584 [(set_attr "length" "24")])
5585
5586 (define_insn "call_value_indirect_nt"
5587 [(set (match_operand 0 "register_operand" "fg")
5588 (call (mem:SI (match_operand:SI 1 "register_operand" "b"))
5589 (match_operand 2 "const_int_operand" "n")))
5590 (use (match_operand 3 "const_int_operand" "O"))
5591 (use (match_operand 4 "offsettable_addr_operand" "p"))
5592 (use (match_operand 5 "register_operand" "r"))
5593 (clobber (match_scratch:SI 6 "=&r"))
5594 (clobber (match_scratch:SI 7 "=l"))]
5595 "DEFAULT_ABI == ABI_NT"
5596 "{st|stw} %5,%a4\;{l|lwz} %6,0(%1)\;{l|lwz} %5,4(%1);\;mt%7 %6\;{brl|blrl}\;{l|lwz} %5,%a4"
5597 [(set_attr "length" "24")])
5598
5599 ;; A function pointer under System V is just a normal pointer
5600 ;; operands[0] is the function pointer
5601 ;; operands[1] is the stack size to clean up
5602 ;; operands[2] is the value FUNCTION_ARG returns for the VOID argument which indicates how to set cr1
5603
5604 (define_insn "call_indirect_sysv"
5605 [(call (mem:SI (match_operand:SI 0 "register_operand" "l,l"))
5606 (match_operand 1 "const_int_operand" "n,n"))
5607 (use (match_operand 2 "const_int_operand" "O,n"))
5608 (clobber (match_scratch:SI 3 "=l,l"))]
5609 "DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_AIX_NODESC"
5610 "*
5611 {
5612 if (INTVAL (operands[2]) > 0)
5613 return \"creqv 6,6,6\;{brl|blrl}\";
5614
5615 else if (INTVAL (operands[2]) < 0)
5616 return \"crxor 6,6,6\;{brl|blrl}\";
5617
5618 return \"{brl|blrl}\";
5619 }"
5620 [(set_attr "length" "4,8")])
5621
5622 (define_insn "call_value_indirect_sysv"
5623 [(set (match_operand 0 "register_operand" "=fg,fg")
5624 (call (mem:SI (match_operand:SI 1 "register_operand" "l,l"))
5625 (match_operand 2 "const_int_operand" "n,n")))
5626 (use (match_operand 3 "const_int_operand" "O,n"))
5627 (clobber (match_scratch:SI 4 "=l,l"))]
5628 "DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_AIX_NODESC"
5629 "*
5630 {
5631 if (INTVAL (operands[3]) > 0)
5632 return \"creqv 6,6,6\;{brl|blrl}\";
5633
5634 else if (INTVAL (operands[3]) < 0)
5635 return \"crxor 6,6,6\;{brl|blrl}\";
5636
5637 return \"{brl|blrl}\";
5638 }"
5639 [(set_attr "length" "4,8")])
5640
5641 ;; Now the definitions for the call and call_value insns
5642 (define_expand "call"
5643 [(parallel [(call (mem:SI (match_operand:SI 0 "address_operand" ""))
5644 (match_operand 1 "" ""))
5645 (use (match_operand 2 "" ""))
5646 (clobber (scratch:SI))])]
5647 ""
5648 "
5649 {
5650 if (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != CONST_INT)
5651 abort ();
5652
5653 operands[0] = XEXP (operands[0], 0);
5654 if (GET_CODE (operands[0]) != SYMBOL_REF)
5655 {
5656 if (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_AIX_NODESC)
5657 emit_call_insn (gen_call_indirect_sysv (force_reg (Pmode, operands[0]),
5658 operands[1], operands[2]));
5659 else
5660 {
5661 rtx toc_reg = gen_rtx (REG, Pmode, 2);
5662 rtx toc_addr = RS6000_SAVE_TOC;
5663
5664 if (DEFAULT_ABI == ABI_AIX)
5665 {
5666 /* AIX function pointers are really pointers to a three word area */
5667 rtx static_chain = gen_rtx (REG, Pmode, STATIC_CHAIN_REGNUM);
5668 emit_call_insn (gen_call_indirect_aix (force_reg (Pmode, operands[0]),
5669 operands[1], operands[2],
5670 toc_addr, toc_reg, static_chain));
5671 }
5672 else if (DEFAULT_ABI == ABI_NT)
5673 {
5674 /* NT function pointers are really pointers to a two word area */
5675 emit_call_insn (gen_call_indirect_nt (force_reg (Pmode, operands[0]),
5676 operands[1], operands[2],
5677 toc_addr, toc_reg));
5678 }
5679 else
5680 abort ();
5681 }
5682 DONE;
5683 }
5684 }")
5685
5686 (define_expand "call_value"
5687 [(parallel [(set (match_operand 0 "" "")
5688 (call (mem:SI (match_operand:SI 1 "address_operand" ""))
5689 (match_operand 2 "" "")))
5690 (use (match_operand 3 "" ""))
5691 (clobber (scratch:SI))])]
5692 ""
5693 "
5694 {
5695 if (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != CONST_INT)
5696 abort ();
5697
5698 operands[1] = XEXP (operands[1], 0);
5699 if (GET_CODE (operands[1]) != SYMBOL_REF)
5700 {
5701 if (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_AIX_NODESC)
5702 emit_call_insn (gen_call_value_indirect_sysv (operands[0], operands[1],
5703 operands[2], operands[3]));
5704 else
5705 {
5706 rtx toc_reg = gen_rtx (REG, Pmode, 2);
5707 rtx toc_addr = RS6000_SAVE_TOC;
5708
5709 if (DEFAULT_ABI == ABI_AIX)
5710 {
5711 /* AIX function pointers are really pointers to a three word area */
5712 rtx static_chain = gen_rtx (REG, Pmode, STATIC_CHAIN_REGNUM);
5713 emit_call_insn (gen_call_value_indirect_aix (operands[0],
5714 force_reg (Pmode, operands[1]),
5715 operands[2], operands[3],
5716 toc_addr, toc_reg, static_chain));
5717 }
5718 else if (DEFAULT_ABI == ABI_NT)
5719 {
5720 /* NT function pointers are really pointers to a two word area */
5721 emit_call_insn (gen_call_value_indirect_nt (operands[0],
5722 force_reg (Pmode, operands[1]),
5723 operands[2], operands[3],
5724 toc_addr, toc_reg));
5725 }
5726 else
5727 abort ();
5728 }
5729 DONE;
5730 }
5731 }")
5732
5733 ;; Call to function in current module. No TOC pointer reload needed.
5734 ;; Operand2 is non-zero if we are using the V.4 calling sequence and
5735 ;; either the function was not prototyped, or it was prototyped as a
5736 ;; variable argument function. It is > 0 if FP registers were passed
5737 ;; and < 0 if they were not.
5738
5739 (define_insn ""
5740 [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
5741 (match_operand 1 "" "g,g"))
5742 (use (match_operand:SI 2 "immediate_operand" "O,n"))
5743 (clobber (match_scratch:SI 3 "=l,l"))]
5744 ""
5745 "*
5746 {
5747 if (INTVAL (operands[2]) > 0)
5748 return \"creqv 6,6,6\;bl %z0\";
5749
5750 else if (INTVAL (operands[2]) < 0)
5751 return \"crxor 6,6,6\;bl %z0\";
5752
5753 return \"bl %z0\";
5754 }"
5755 [(set_attr "length" "4,8")])
5756
5757 ;; Call to function which may be in another module. Restore the TOC
5758 ;; pointer (r2) after the call unless this is System V.
5759 ;; Operand2 is non-zero if we are using the V.4 calling sequence and
5760 ;; either the function was not prototyped, or it was prototyped as a
5761 ;; variable argument function. It is > 0 if FP registers were passed
5762 ;; and < 0 if they were not.
5763
5764 (define_insn ""
5765 [(call (mem:SI (match_operand:SI 0 "call_operand" "s,s"))
5766 (match_operand 1 "" "fg,fg"))
5767 (use (match_operand:SI 2 "immediate_operand" "O,n"))
5768 (clobber (match_scratch:SI 3 "=l,l"))]
5769 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_NT"
5770 "*
5771 {
5772 if (INTVAL (operands[2]) > 0)
5773 output_asm_insn (\"creqv 6,6,6\", operands);
5774
5775 else if (INTVAL (operands[2]) < 0)
5776 output_asm_insn (\"crxor 6,6,6\", operands);
5777
5778 /* Indirect calls should go through call_indirect */
5779 if (GET_CODE (operands[0]) == REG)
5780 abort ();
5781
5782 return (TARGET_WINDOWS_NT) ? \"bl %z0\;.znop %z0\" : \"bl %z0\;%.\";
5783 }"
5784 [(set_attr "length" "8,12")])
5785
5786 (define_insn ""
5787 [(call (mem:SI (match_operand:SI 0 "call_operand" "s,s"))
5788 (match_operand 1 "" "fg,fg"))
5789 (use (match_operand:SI 2 "immediate_operand" "O,n"))
5790 (clobber (match_scratch:SI 3 "=l,l"))]
5791 "DEFAULT_ABI == ABI_AIX_NODESC || DEFAULT_ABI == ABI_V4"
5792 "*
5793 {
5794 if (INTVAL (operands[2]) > 0)
5795 output_asm_insn (\"creqv 6,6,6\", operands);
5796
5797 else if (INTVAL (operands[2]) < 0)
5798 output_asm_insn (\"crxor 6,6,6\", operands);
5799
5800 /* Indirect calls should go through call_indirect */
5801 if (GET_CODE (operands[0]) == REG)
5802 abort ();
5803
5804 return \"bl %z0\";
5805 }"
5806 [(set_attr "length" "4,8")])
5807
5808 (define_insn ""
5809 [(set (match_operand 0 "" "=fg,fg")
5810 (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
5811 (match_operand 2 "" "g,g")))
5812 (use (match_operand:SI 3 "immediate_operand" "O,n"))
5813 (clobber (match_scratch:SI 4 "=l,l"))]
5814 ""
5815 "*
5816 {
5817 if (INTVAL (operands[3]) > 0)
5818 return \"creqv 6,6,6\;bl %z1\";
5819
5820 else if (INTVAL (operands[3]) < 0)
5821 return \"crxor 6,6,6\;bl %z1\";
5822
5823 return \"bl %z1\";
5824 }"
5825 [(set_attr "length" "4,8")])
5826
5827 (define_insn ""
5828 [(set (match_operand 0 "" "=fg,fg")
5829 (call (mem:SI (match_operand:SI 1 "call_operand" "s,s"))
5830 (match_operand 2 "" "fg,fg")))
5831 (use (match_operand:SI 3 "immediate_operand" "O,n"))
5832 (clobber (match_scratch:SI 4 "=l,l"))]
5833 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_NT"
5834 "*
5835 {
5836 if (INTVAL (operands[3]) > 0)
5837 output_asm_insn (\"creqv 6,6,6\", operands);
5838
5839 else if (INTVAL (operands[3]) < 0)
5840 output_asm_insn (\"crxor 6,6,6\", operands);
5841
5842 /* This should be handled by call_value_indirect */
5843 if (GET_CODE (operands[1]) == REG)
5844 abort ();
5845
5846 return (TARGET_WINDOWS_NT) ? \"bl %z1\;.znop %z1\" : \"bl %z1\;%.\";
5847 }"
5848 [(set_attr "length" "8,12")])
5849
5850 (define_insn ""
5851 [(set (match_operand 0 "" "=fg,fg")
5852 (call (mem:SI (match_operand:SI 1 "call_operand" "s,s"))
5853 (match_operand 2 "" "fg,fg")))
5854 (use (match_operand:SI 3 "immediate_operand" "O,n"))
5855 (clobber (match_scratch:SI 4 "=l,l"))]
5856 "DEFAULT_ABI == ABI_AIX_NODESC || DEFAULT_ABI == ABI_V4"
5857 "*
5858 {
5859 if (INTVAL (operands[3]) > 0)
5860 output_asm_insn (\"creqv 6,6,6\", operands);
5861
5862 else if (INTVAL (operands[3]) < 0)
5863 output_asm_insn (\"crxor 6,6,6\", operands);
5864
5865 /* This should be handled by call_value_indirect */
5866 if (GET_CODE (operands[1]) == REG)
5867 abort ();
5868
5869 return \"bl %z1\";
5870 }"
5871 [(set_attr "length" "4,8")])
5872
5873
5874 ;; Call subroutine returning any type.
5875
5876 (define_expand "untyped_call"
5877 [(parallel [(call (match_operand 0 "" "")
5878 (const_int 0))
5879 (match_operand 1 "" "")
5880 (match_operand 2 "" "")])]
5881 ""
5882 "
5883 {
5884 int i;
5885
5886 emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx, const0_rtx));
5887
5888 for (i = 0; i < XVECLEN (operands[2], 0); i++)
5889 {
5890 rtx set = XVECEXP (operands[2], 0, i);
5891 emit_move_insn (SET_DEST (set), SET_SRC (set));
5892 }
5893
5894 /* The optimizer does not know that the call sets the function value
5895 registers we stored in the result block. We avoid problems by
5896 claiming that all hard registers are used and clobbered at this
5897 point. */
5898 emit_insn (gen_blockage ());
5899
5900 DONE;
5901 }")
5902
5903 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
5904 ;; all of memory. This blocks insns from being moved across this point.
5905
5906 (define_insn "blockage"
5907 [(unspec_volatile [(const_int 0)] 0)]
5908 ""
5909 "")
5910
5911 ;; Synchronize instructions/data caches for V.4 trampolines
5912 ;; The extra memory_operand is to prevent the optimizer from
5913 ;; deleting insns with "no" effect.
5914 (define_insn "icbi"
5915 [(unspec [(match_operand 0 "memory_operand" "=m")
5916 (match_operand 1 "register_operand" "b")
5917 (match_operand 2 "register_operand" "r")] 3)]
5918 "TARGET_POWERPC"
5919 "icbi %1,%2")
5920
5921 (define_insn "dcbst"
5922 [(unspec [(match_operand 0 "memory_operand" "=m")
5923 (match_operand 1 "register_operand" "b")
5924 (match_operand 2 "register_operand" "r")] 4)]
5925 "TARGET_POWERPC"
5926 "dcbst %1,%2")
5927
5928 (define_insn "sync"
5929 [(unspec [(match_operand 0 "memory_operand" "=m")] 5)]
5930 ""
5931 "{dcs|sync}")
5932
5933 (define_insn "isync"
5934 [(unspec [(match_operand 0 "memory_operand" "=m")] 6)]
5935 ""
5936 "{ics|isync}")
5937
5938 \f
5939 ;; Compare insns are next. Note that the RS/6000 has two types of compares,
5940 ;; signed & unsigned, and one type of branch.
5941 ;;
5942 ;; Start with the DEFINE_EXPANDs to generate the rtl for compares, scc
5943 ;; insns, and branches. We store the operands of compares until we see
5944 ;; how it is used.
5945 (define_expand "cmpsi"
5946 [(set (cc0)
5947 (compare (match_operand:SI 0 "gpc_reg_operand" "")
5948 (match_operand:SI 1 "reg_or_short_operand" "")))]
5949 ""
5950 "
5951 {
5952 /* Take care of the possibility that operands[1] might be negative but
5953 this might be a logical operation. That insn doesn't exist. */
5954 if (GET_CODE (operands[1]) == CONST_INT
5955 && INTVAL (operands[1]) < 0)
5956 operands[1] = force_reg (SImode, operands[1]);
5957
5958 rs6000_compare_op0 = operands[0];
5959 rs6000_compare_op1 = operands[1];
5960 rs6000_compare_fp_p = 0;
5961 DONE;
5962 }")
5963
5964 (define_expand "cmpsf"
5965 [(set (cc0) (compare (match_operand:SF 0 "gpc_reg_operand" "")
5966 (match_operand:SF 1 "gpc_reg_operand" "")))]
5967 "TARGET_HARD_FLOAT"
5968 "
5969 {
5970 rs6000_compare_op0 = operands[0];
5971 rs6000_compare_op1 = operands[1];
5972 rs6000_compare_fp_p = 1;
5973 DONE;
5974 }")
5975
5976 (define_expand "cmpdf"
5977 [(set (cc0) (compare (match_operand:DF 0 "gpc_reg_operand" "")
5978 (match_operand:DF 1 "gpc_reg_operand" "")))]
5979 "TARGET_HARD_FLOAT"
5980 "
5981 {
5982 rs6000_compare_op0 = operands[0];
5983 rs6000_compare_op1 = operands[1];
5984 rs6000_compare_fp_p = 1;
5985 DONE;
5986 }")
5987
5988 (define_expand "beq"
5989 [(set (match_dup 2) (match_dup 1))
5990 (set (pc)
5991 (if_then_else (eq (match_dup 2)
5992 (const_int 0))
5993 (label_ref (match_operand 0 "" ""))
5994 (pc)))]
5995 ""
5996 "
5997 { enum machine_mode mode = rs6000_compare_fp_p ? CCFPmode : CCmode;
5998 operands[1] = gen_rtx (COMPARE, mode,
5999 rs6000_compare_op0, rs6000_compare_op1);
6000 operands[2] = gen_reg_rtx (mode);
6001 }")
6002
6003 (define_expand "bne"
6004 [(set (match_dup 2) (match_dup 1))
6005 (set (pc)
6006 (if_then_else (ne (match_dup 2)
6007 (const_int 0))
6008 (label_ref (match_operand 0 "" ""))
6009 (pc)))]
6010 ""
6011 "
6012 { enum machine_mode mode = rs6000_compare_fp_p ? CCFPmode : CCmode;
6013 operands[1] = gen_rtx (COMPARE, mode,
6014 rs6000_compare_op0, rs6000_compare_op1);
6015 operands[2] = gen_reg_rtx (mode);
6016 }")
6017
6018 (define_expand "blt"
6019 [(set (match_dup 2) (match_dup 1))
6020 (set (pc)
6021 (if_then_else (lt (match_dup 2)
6022 (const_int 0))
6023 (label_ref (match_operand 0 "" ""))
6024 (pc)))]
6025 ""
6026 "
6027 { enum machine_mode mode = rs6000_compare_fp_p ? CCFPmode : CCmode;
6028 operands[1] = gen_rtx (COMPARE, mode,
6029 rs6000_compare_op0, rs6000_compare_op1);
6030 operands[2] = gen_reg_rtx (mode);
6031 }")
6032
6033 (define_expand "bgt"
6034 [(set (match_dup 2) (match_dup 1))
6035 (set (pc)
6036 (if_then_else (gt (match_dup 2)
6037 (const_int 0))
6038 (label_ref (match_operand 0 "" ""))
6039 (pc)))]
6040 ""
6041 "
6042 { enum machine_mode mode = rs6000_compare_fp_p ? CCFPmode : CCmode;
6043 operands[1] = gen_rtx (COMPARE, mode,
6044 rs6000_compare_op0, rs6000_compare_op1);
6045 operands[2] = gen_reg_rtx (mode);
6046 }")
6047
6048 (define_expand "ble"
6049 [(set (match_dup 2) (match_dup 1))
6050 (set (pc)
6051 (if_then_else (le (match_dup 2)
6052 (const_int 0))
6053 (label_ref (match_operand 0 "" ""))
6054 (pc)))]
6055 ""
6056 "
6057 { enum machine_mode mode = rs6000_compare_fp_p ? CCFPmode : CCmode;
6058 operands[1] = gen_rtx (COMPARE, mode,
6059 rs6000_compare_op0, rs6000_compare_op1);
6060 operands[2] = gen_reg_rtx (mode);
6061 }")
6062
6063 (define_expand "bge"
6064 [(set (match_dup 2) (match_dup 1))
6065 (set (pc)
6066 (if_then_else (ge (match_dup 2)
6067 (const_int 0))
6068 (label_ref (match_operand 0 "" ""))
6069 (pc)))]
6070 ""
6071 "
6072 { enum machine_mode mode = rs6000_compare_fp_p ? CCFPmode : CCmode;
6073 operands[1] = gen_rtx (COMPARE, mode,
6074 rs6000_compare_op0, rs6000_compare_op1);
6075 operands[2] = gen_reg_rtx (mode);
6076 }")
6077
6078 (define_expand "bgtu"
6079 [(set (match_dup 2) (match_dup 1))
6080 (set (pc)
6081 (if_then_else (gtu (match_dup 2)
6082 (const_int 0))
6083 (label_ref (match_operand 0 "" ""))
6084 (pc)))]
6085 ""
6086 "
6087 { operands[1] = gen_rtx (COMPARE, CCUNSmode,
6088 rs6000_compare_op0, rs6000_compare_op1);
6089 operands[2] = gen_reg_rtx (CCUNSmode);
6090 }")
6091
6092 (define_expand "bltu"
6093 [(set (match_dup 2) (match_dup 1))
6094 (set (pc)
6095 (if_then_else (ltu (match_dup 2)
6096 (const_int 0))
6097 (label_ref (match_operand 0 "" ""))
6098 (pc)))]
6099 ""
6100 "
6101 { operands[1] = gen_rtx (COMPARE, CCUNSmode,
6102 rs6000_compare_op0, rs6000_compare_op1);
6103 operands[2] = gen_reg_rtx (CCUNSmode);
6104 }")
6105
6106 (define_expand "bgeu"
6107 [(set (match_dup 2) (match_dup 1))
6108 (set (pc)
6109 (if_then_else (geu (match_dup 2)
6110 (const_int 0))
6111 (label_ref (match_operand 0 "" ""))
6112 (pc)))]
6113 ""
6114 "
6115 { operands[1] = gen_rtx (COMPARE, CCUNSmode,
6116 rs6000_compare_op0, rs6000_compare_op1);
6117 operands[2] = gen_reg_rtx (CCUNSmode);
6118 }")
6119
6120 (define_expand "bleu"
6121 [(set (match_dup 2) (match_dup 1))
6122 (set (pc)
6123 (if_then_else (leu (match_dup 2)
6124 (const_int 0))
6125 (label_ref (match_operand 0 "" ""))
6126 (pc)))]
6127 ""
6128 "
6129 { operands[1] = gen_rtx (COMPARE, CCUNSmode,
6130 rs6000_compare_op0, rs6000_compare_op1);
6131 operands[2] = gen_reg_rtx (CCUNSmode);
6132 }")
6133
6134 ;; For SNE, we would prefer that the xor/abs sequence be used for integers.
6135 ;; For SEQ, likewise, except that comparisons with zero should be done
6136 ;; with an scc insns. However, due to the order that combine see the
6137 ;; resulting insns, we must, in fact, allow SEQ for integers. Fail in
6138 ;; the cases we don't want to handle.
6139 (define_expand "seq"
6140 [(set (match_dup 2) (match_dup 1))
6141 (set (match_operand:SI 0 "gpc_reg_operand" "")
6142 (eq:SI (match_dup 2) (const_int 0)))]
6143 ""
6144 "
6145 { enum machine_mode mode = rs6000_compare_fp_p ? CCFPmode : CCmode;
6146 operands[1] = gen_rtx (COMPARE, mode,
6147 rs6000_compare_op0, rs6000_compare_op1);
6148 operands[2] = gen_reg_rtx (mode);
6149 }")
6150
6151 (define_expand "sne"
6152 [(set (match_dup 2) (match_dup 1))
6153 (set (match_operand:SI 0 "gpc_reg_operand" "")
6154 (ne:SI (match_dup 2) (const_int 0)))]
6155 ""
6156 "
6157 { if (! rs6000_compare_fp_p)
6158 FAIL;
6159
6160 operands[1] = gen_rtx (COMPARE, CCFPmode,
6161 rs6000_compare_op0, rs6000_compare_op1);
6162 operands[2] = gen_reg_rtx (CCFPmode);
6163 }")
6164
6165 ;; A > 0 is best done using the portable sequence, so fail in that case.
6166 (define_expand "sgt"
6167 [(set (match_dup 2) (match_dup 1))
6168 (set (match_operand:SI 0 "gpc_reg_operand" "")
6169 (gt:SI (match_dup 2) (const_int 0)))]
6170 ""
6171 "
6172 { enum machine_mode mode = rs6000_compare_fp_p ? CCFPmode : CCmode;
6173
6174 if (! rs6000_compare_fp_p && rs6000_compare_op1 == const0_rtx)
6175 FAIL;
6176
6177 operands[1] = gen_rtx (COMPARE, mode,
6178 rs6000_compare_op0, rs6000_compare_op1);
6179 operands[2] = gen_reg_rtx (mode);
6180 }")
6181
6182 ;; A < 0 is best done in the portable way for A an integer.
6183 (define_expand "slt"
6184 [(set (match_dup 2) (match_dup 1))
6185 (set (match_operand:SI 0 "gpc_reg_operand" "")
6186 (lt:SI (match_dup 2) (const_int 0)))]
6187 ""
6188 "
6189 { enum machine_mode mode = rs6000_compare_fp_p ? CCFPmode : CCmode;
6190
6191 if (! rs6000_compare_fp_p && rs6000_compare_op1 == const0_rtx)
6192 FAIL;
6193
6194 operands[1] = gen_rtx (COMPARE, mode,
6195 rs6000_compare_op0, rs6000_compare_op1);
6196 operands[2] = gen_reg_rtx (mode);
6197 }")
6198
6199 (define_expand "sge"
6200 [(set (match_dup 2) (match_dup 1))
6201 (set (match_operand:SI 0 "gpc_reg_operand" "")
6202 (ge:SI (match_dup 2) (const_int 0)))]
6203 ""
6204 "
6205 { enum machine_mode mode = rs6000_compare_fp_p ? CCFPmode : CCmode;
6206 operands[1] = gen_rtx (COMPARE, mode,
6207 rs6000_compare_op0, rs6000_compare_op1);
6208 operands[2] = gen_reg_rtx (mode);
6209 }")
6210
6211 ;; A <= 0 is best done the portable way for A an integer.
6212 (define_expand "sle"
6213 [(set (match_dup 2) (match_dup 1))
6214 (set (match_operand:SI 0 "gpc_reg_operand" "")
6215 (le:SI (match_dup 2) (const_int 0)))]
6216 ""
6217 "
6218 { enum machine_mode mode = rs6000_compare_fp_p ? CCFPmode : CCmode;
6219
6220 if (! rs6000_compare_fp_p && rs6000_compare_op1 == const0_rtx)
6221 FAIL;
6222
6223 operands[1] = gen_rtx (COMPARE, mode,
6224 rs6000_compare_op0, rs6000_compare_op1);
6225 operands[2] = gen_reg_rtx (mode);
6226 }")
6227
6228 (define_expand "sgtu"
6229 [(set (match_dup 2) (match_dup 1))
6230 (set (match_operand:SI 0 "gpc_reg_operand" "")
6231 (gtu:SI (match_dup 2) (const_int 0)))]
6232 ""
6233 "
6234 { operands[1] = gen_rtx (COMPARE, CCUNSmode,
6235 rs6000_compare_op0, rs6000_compare_op1);
6236 operands[2] = gen_reg_rtx (CCUNSmode);
6237 }")
6238
6239 (define_expand "sltu"
6240 [(set (match_dup 2) (match_dup 1))
6241 (set (match_operand:SI 0 "gpc_reg_operand" "")
6242 (ltu:SI (match_dup 2) (const_int 0)))]
6243 ""
6244 "
6245 { operands[1] = gen_rtx (COMPARE, CCUNSmode,
6246 rs6000_compare_op0, rs6000_compare_op1);
6247 operands[2] = gen_reg_rtx (CCUNSmode);
6248 }")
6249
6250 (define_expand "sgeu"
6251 [(set (match_dup 2) (match_dup 1))
6252 (set (match_operand:SI 0 "gpc_reg_operand" "")
6253 (geu:SI (match_dup 2) (const_int 0)))]
6254 ""
6255 "
6256 { operands[1] = gen_rtx (COMPARE, CCUNSmode,
6257 rs6000_compare_op0, rs6000_compare_op1);
6258 operands[2] = gen_reg_rtx (CCUNSmode);
6259 }")
6260
6261 (define_expand "sleu"
6262 [(set (match_dup 2) (match_dup 1))
6263 (set (match_operand:SI 0 "gpc_reg_operand" "")
6264 (leu:SI (match_dup 2) (const_int 0)))]
6265 ""
6266 "
6267 { operands[1] = gen_rtx (COMPARE, CCUNSmode,
6268 rs6000_compare_op0, rs6000_compare_op1);
6269 operands[2] = gen_reg_rtx (CCUNSmode);
6270 }")
6271 \f
6272 ;; Here are the actual compare insns.
6273 (define_insn ""
6274 [(set (match_operand:CC 0 "cc_reg_operand" "=y")
6275 (compare:CC (match_operand:SI 1 "gpc_reg_operand" "r")
6276 (match_operand:SI 2 "reg_or_short_operand" "rI")))]
6277 ""
6278 "{cmp%I2|cmpw%I2} %0,%1,%2"
6279 [(set_attr "type" "compare")])
6280
6281 ;; If we are comparing a register for equality with a large constant,
6282 ;; we can do this with an XOR followed by a compare. But we need a scratch
6283 ;; register for the result of the XOR.
6284
6285 (define_split
6286 [(set (match_operand:CC 0 "cc_reg_operand" "")
6287 (compare:CC (match_operand:SI 1 "gpc_reg_operand" "")
6288 (match_operand:SI 2 "non_short_cint_operand" "")))
6289 (clobber (match_operand:SI 3 "gpc_reg_operand" ""))]
6290 "find_single_use (operands[0], insn, 0)
6291 && (GET_CODE (*find_single_use (operands[0], insn, 0)) == EQ
6292 || GET_CODE (*find_single_use (operands[0], insn, 0)) == NE)"
6293 [(set (match_dup 3) (xor:SI (match_dup 1) (match_dup 4)))
6294 (set (match_dup 0) (compare:CC (match_dup 3) (match_dup 5)))]
6295 "
6296 {
6297 /* Get the constant we are comparing against, C, and see what it looks like
6298 sign-extended to 16 bits. Then see what constant could be XOR'ed
6299 with C to get the sign-extended value. */
6300
6301 int c = INTVAL (operands[2]);
6302 int sextc = (c << 16) >> 16;
6303 int xorv = c ^ sextc;
6304
6305 operands[4] = gen_rtx (CONST_INT, VOIDmode, xorv);
6306 operands[5] = gen_rtx (CONST_INT, VOIDmode, sextc);
6307 }")
6308
6309 (define_insn ""
6310 [(set (match_operand:CCUNS 0 "cc_reg_operand" "=y")
6311 (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "r")
6312 (match_operand:SI 2 "reg_or_u_short_operand" "rI")))]
6313 ""
6314 "{cmpl%I2|cmplw%I2} %0,%1,%W2"
6315 [(set_attr "type" "compare")])
6316
6317 ;; The following two insns don't exist as single insns, but if we provide
6318 ;; them, we can swap an add and compare, which will enable us to overlap more
6319 ;; of the required delay between a compare and branch. We generate code for
6320 ;; them by splitting.
6321
6322 (define_insn ""
6323 [(set (match_operand:CC 3 "cc_reg_operand" "=y")
6324 (compare:CC (match_operand:SI 1 "gpc_reg_operand" "r")
6325 (match_operand:SI 2 "short_cint_operand" "i")))
6326 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
6327 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "i")))]
6328 ""
6329 "#"
6330 [(set_attr "length" "8")])
6331
6332 (define_insn ""
6333 [(set (match_operand:CCUNS 3 "cc_reg_operand" "=y")
6334 (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "r")
6335 (match_operand:SI 2 "u_short_cint_operand" "i")))
6336 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
6337 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "i")))]
6338 ""
6339 "#"
6340 [(set_attr "length" "8")])
6341
6342 (define_split
6343 [(set (match_operand:CC 3 "cc_reg_operand" "")
6344 (compare:CC (match_operand:SI 1 "gpc_reg_operand" "")
6345 (match_operand:SI 2 "short_cint_operand" "")))
6346 (set (match_operand:SI 0 "gpc_reg_operand" "")
6347 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "")))]
6348 ""
6349 [(set (match_dup 3) (compare:CC (match_dup 1) (match_dup 2)))
6350 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 4)))])
6351
6352 (define_split
6353 [(set (match_operand:CCUNS 3 "cc_reg_operand" "")
6354 (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "")
6355 (match_operand:SI 2 "u_short_cint_operand" "")))
6356 (set (match_operand:SI 0 "gpc_reg_operand" "")
6357 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "")))]
6358 ""
6359 [(set (match_dup 3) (compare:CCUNS (match_dup 1) (match_dup 2)))
6360 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 4)))])
6361
6362 (define_insn ""
6363 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
6364 (compare:CCFP (match_operand:SF 1 "gpc_reg_operand" "f")
6365 (match_operand:SF 2 "gpc_reg_operand" "f")))]
6366 "TARGET_HARD_FLOAT"
6367 "fcmpu %0,%1,%2"
6368 [(set_attr "type" "fpcompare")])
6369
6370 (define_insn ""
6371 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
6372 (compare:CCFP (match_operand:DF 1 "gpc_reg_operand" "f")
6373 (match_operand:DF 2 "gpc_reg_operand" "f")))]
6374 "TARGET_HARD_FLOAT"
6375 "fcmpu %0,%1,%2"
6376 [(set_attr "type" "fpcompare")])
6377 \f
6378 ;; Now we have the scc insns. We can do some combinations because of the
6379 ;; way the machine works.
6380 ;;
6381 ;; Note that this is probably faster if we can put an insn between the
6382 ;; mfcr and rlinm, but this is tricky. Let's leave it for now. In most
6383 ;; cases the insns below which don't use an intermediate CR field will
6384 ;; be used instead.
6385 (define_insn ""
6386 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6387 (match_operator:SI 1 "scc_comparison_operator"
6388 [(match_operand 2 "cc_reg_operand" "y")
6389 (const_int 0)]))]
6390 ""
6391 "%D1mfcr %0\;{rlinm|rlwinm} %0,%0,%J1,1"
6392 [(set_attr "length" "12")])
6393
6394 (define_insn ""
6395 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
6396 (compare:CC (match_operator:SI 1 "scc_comparison_operator"
6397 [(match_operand 2 "cc_reg_operand" "y")
6398 (const_int 0)])
6399 (const_int 0)))
6400 (set (match_operand:SI 3 "gpc_reg_operand" "=r")
6401 (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
6402 ""
6403 "%D1mfcr %3\;{rlinm.|rlwinm.} %3,%3,%J1,1"
6404 [(set_attr "type" "delayed_compare")
6405 (set_attr "length" "12")])
6406
6407 (define_insn ""
6408 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6409 (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
6410 [(match_operand 2 "cc_reg_operand" "y")
6411 (const_int 0)])
6412 (match_operand:SI 3 "const_int_operand" "n")))]
6413 ""
6414 "*
6415 {
6416 int is_bit = ccr_bit (operands[1], 1);
6417 int put_bit = 31 - (INTVAL (operands[3]) & 31);
6418 int count;
6419
6420 if (is_bit >= put_bit)
6421 count = is_bit - put_bit;
6422 else
6423 count = 32 - (put_bit - is_bit);
6424
6425 operands[4] = gen_rtx (CONST_INT, VOIDmode, count);
6426 operands[5] = gen_rtx (CONST_INT, VOIDmode, put_bit);
6427
6428 return \"%D1mfcr %0\;{rlinm|rlwinm} %0,%0,%4,%5,%5\";
6429 }"
6430 [(set_attr "length" "12")])
6431
6432 (define_insn ""
6433 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
6434 (compare:CC
6435 (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
6436 [(match_operand 2 "cc_reg_operand" "y")
6437 (const_int 0)])
6438 (match_operand:SI 3 "const_int_operand" "n"))
6439 (const_int 0)))
6440 (set (match_operand:SI 4 "gpc_reg_operand" "=r")
6441 (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
6442 (match_dup 3)))]
6443 ""
6444 "*
6445 {
6446 int is_bit = ccr_bit (operands[1], 1);
6447 int put_bit = 31 - (INTVAL (operands[3]) & 31);
6448 int count;
6449
6450 if (is_bit >= put_bit)
6451 count = is_bit - put_bit;
6452 else
6453 count = 32 - (put_bit - is_bit);
6454
6455 operands[5] = gen_rtx (CONST_INT, VOIDmode, count);
6456 operands[6] = gen_rtx (CONST_INT, VOIDmode, put_bit);
6457
6458 return \"%D1mfcr %4\;{rlinm.|rlwinm.} %4,%4,%5,%6,%6\";
6459 }"
6460 [(set_attr "type" "delayed_compare")
6461 (set_attr "length" "12")])
6462
6463 ;; If we are comparing the result of two comparisons, this can be done
6464 ;; using creqv or crxor.
6465
6466 (define_insn ""
6467 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y")
6468 (compare:CCEQ (match_operator 1 "scc_comparison_operator"
6469 [(match_operand 2 "cc_reg_operand" "y")
6470 (const_int 0)])
6471 (match_operator 3 "scc_comparison_operator"
6472 [(match_operand 4 "cc_reg_operand" "y")
6473 (const_int 0)])))]
6474 "REGNO (operands[2]) != REGNO (operands[4])"
6475 "*
6476 {
6477 enum rtx_code code1, code2;
6478
6479 code1 = GET_CODE (operands[1]);
6480 code2 = GET_CODE (operands[3]);
6481
6482 if ((code1 == EQ || code1 == LT || code1 == GT
6483 || code1 == LTU || code1 == GTU
6484 || (code1 != NE && GET_MODE (operands[2]) == CCFPmode))
6485 !=
6486 (code2 == EQ || code2 == LT || code2 == GT
6487 || code2 == LTU || code2 == GTU
6488 || (code2 != NE && GET_MODE (operands[4]) == CCFPmode)))
6489 return \"%C1%C3crxor %E0,%j1,%j3\";
6490 else
6491 return \"%C1%C3creqv %E0,%j1,%j3\";
6492 }"
6493 [(set_attr "length" "12")])
6494
6495 ;; There is a 3 cycle delay between consecutive mfcr instructions
6496 ;; so it is useful to combine 2 scc instructions to use only one mfcr.
6497
6498 (define_peephole
6499 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6500 (match_operator:SI 1 "scc_comparison_operator"
6501 [(match_operand 2 "cc_reg_operand" "y")
6502 (const_int 0)]))
6503 (set (match_operand:SI 3 "gpc_reg_operand" "=r")
6504 (match_operator:SI 4 "scc_comparison_operator"
6505 [(match_operand 5 "cc_reg_operand" "y")
6506 (const_int 0)]))]
6507 "REGNO (operands[2]) != REGNO (operands[5])"
6508 "%D1%D4mfcr %3\;{rlinm|rlwinm} %0,%3,%J1,1\;{rlinm|rlwinm} %3,%3,%J4,1"
6509 [(set_attr "length" "20")])
6510
6511 ;; There are some scc insns that can be done directly, without a compare.
6512 ;; These are faster because they don't involve the communications between
6513 ;; the FXU and branch units. In fact, we will be replacing all of the
6514 ;; integer scc insns here or in the portable methods in emit_store_flag.
6515 ;;
6516 ;; Also support (neg (scc ..)) since that construct is used to replace
6517 ;; branches, (plus (scc ..) ..) since that construct is common and
6518 ;; takes no more insns than scc, and (and (neg (scc ..)) ..) in the
6519 ;; cases where it is no more expensive than (neg (scc ..)).
6520
6521 ;; Have reload force a constant into a register for the simple insns that
6522 ;; otherwise won't accept constants. We do this because it is faster than
6523 ;; the cmp/mfcr sequence we would otherwise generate.
6524
6525 (define_insn ""
6526 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r,r")
6527 (eq:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r")
6528 (match_operand:SI 2 "reg_or_cint_operand" "r,O,K,J,I")))
6529 (clobber (match_scratch:SI 3 "=r,&r,r,r,r"))]
6530 ""
6531 "@
6532 xor %0,%1,%2\;{sfi|subfic} %3,%0,0\;{ae|adde} %0,%3,%0
6533 {sfi|subfic} %3,%1,0\;{ae|adde} %0,%3,%1
6534 {xoril|xori} %0,%1,%b2\;{sfi|subfic} %3,%0,0\;{ae|adde} %0,%3,%0
6535 {xoriu|xoris} %0,%1,%u2\;{sfi|subfic} %3,%0,0\;{ae|adde} %0,%3,%0
6536 {sfi|subfic} %0,%1,%2\;{sfi|subfic} %3,%0,0\;{ae|adde} %0,%3,%0"
6537 [(set_attr "length" "12,8,12,12,12")])
6538
6539 (define_insn ""
6540 [(set (match_operand:CC 4 "cc_reg_operand" "=x,x,x,x,x")
6541 (compare:CC
6542 (eq:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r")
6543 (match_operand:SI 2 "reg_or_cint_operand" "r,O,K,J,I"))
6544 (const_int 0)))
6545 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r,r")
6546 (eq:SI (match_dup 1) (match_dup 2)))
6547 (clobber (match_scratch:SI 3 "=r,&r,r,r,r"))]
6548 ""
6549 "@
6550 xor %0,%1,%2\;{sfi|subfic} %3,%0,0\;{ae.|adde.} %0,%3,%0
6551 {sfi|subfic} %3,%1,0\;{ae.|adde.} %0,%3,%1
6552 {xoril|xori} %0,%1,%b2\;{sfi|subfic} %3,%0,0\;{ae.|adde.} %0,%3,%0
6553 {xoriu|xoris} %0,%1,%u2\;{sfi|subfic} %3,%0,0\;{ae.|adde.} %0,%3,%0
6554 {sfi|subfic} %0,%1,%2\;{sfi|subfic} %3,%0,0\;{ae.|adde.} %0,%3,%0"
6555 [(set_attr "type" "compare")
6556 (set_attr "length" "12,8,12,12,12")])
6557
6558 ;; We have insns of the form shown by the first define_insn below. If
6559 ;; there is something inside the comparison operation, we must split it.
6560 (define_split
6561 [(set (match_operand:SI 0 "gpc_reg_operand" "")
6562 (plus:SI (match_operator 1 "comparison_operator"
6563 [(match_operand:SI 2 "" "")
6564 (match_operand:SI 3
6565 "reg_or_cint_operand" "")])
6566 (match_operand:SI 4 "gpc_reg_operand" "")))
6567 (clobber (match_operand:SI 5 "register_operand" ""))]
6568 "! gpc_reg_operand (operands[2], SImode)"
6569 [(set (match_dup 5) (match_dup 2))
6570 (set (match_dup 2) (plus:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
6571 (match_dup 4)))])
6572
6573 (define_insn ""
6574 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r,r")
6575 (plus:SI (eq:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r")
6576 (match_operand:SI 2 "reg_or_cint_operand" "r,O,K,J,I"))
6577 (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r,r")))
6578 (clobber (match_scratch:SI 4 "=&r,&r,&r,&r,&r"))]
6579 ""
6580 "@
6581 xor %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze|addze} %0,%3
6582 {sfi|subfic} %4,%1,0\;{aze|addze} %0,%3
6583 {xoril|xori} %4,%1,%b2\;{sfi|subfic} %4,%4,0\;{aze|addze} %0,%3
6584 {xoriu|xoris} %4,%1,%u2\;{sfi|subfic} %4,%4,0\;{aze|addze} %0,%3
6585 {sfi|subfic} %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze|addze} %0,%3"
6586 [(set_attr "length" "12,8,12,12,12")])
6587
6588 (define_insn ""
6589 [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,x,x,x")
6590 (compare:CC
6591 (plus:SI
6592 (eq:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r")
6593 (match_operand:SI 2 "reg_or_cint_operand" "r,O,K,J,I"))
6594 (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r,r"))
6595 (const_int 0)))
6596 (clobber (match_scratch:SI 4 "=&r,&r,&r,&r,&r"))]
6597 ""
6598 "@
6599 xor %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %4,%3
6600 {sfi|subfic} %4,%1,0\;{aze.|addze.} %0,%3
6601 {xoril|xori} %4,%1,%b2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %4,%3
6602 {xoriu|xoris} %4,%1,%u2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %4,%3
6603 {sfi|subfic} %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %4,%3"
6604 [(set_attr "type" "compare")
6605 (set_attr "length" "12,8,12,12,12")])
6606
6607 (define_insn ""
6608 [(set (match_operand:CC 5 "cc_reg_operand" "=x,x,x,x,x")
6609 (compare:CC
6610 (plus:SI
6611 (eq:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r")
6612 (match_operand:SI 2 "reg_or_cint_operand" "r,O,K,J,I"))
6613 (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r,r"))
6614 (const_int 0)))
6615 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r,r")
6616 (plus:SI (eq:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
6617 (clobber (match_scratch:SI 4 "=&r,&r,&r,&r,&r"))]
6618 ""
6619 "@
6620 xor %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %0,%3
6621 {sfi|subfic} %4,%1,0\;{aze.|addze.} %4,%3
6622 {xoril|xori} %4,%1,%b2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %0,%3
6623 {xoriu|xoris} %4,%1,%u2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %0,%3
6624 {sfi|subfic} %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %0,%3"
6625 [(set_attr "type" "compare")
6626 (set_attr "length" "12,8,12,12,12")])
6627
6628 (define_insn ""
6629 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r,r")
6630 (neg:SI (eq:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r")
6631 (match_operand:SI 2 "reg_or_cint_operand" "r,O,K,J,I"))))]
6632 ""
6633 "@
6634 xor %0,%1,%2\;{ai|addic} %0,%0,-1\;{sfe|subfe} %0,%0,%0
6635 {ai|addic} %0,%1,-1\;{sfe|subfe} %0,%0,%0
6636 {xoril|xori} %0,%1,%b2\;{ai|addic} %0,%0,-1\;{sfe|subfe} %0,%0,%0
6637 {xoriu|xoris} %0,%1,%u2\;{ai|addic} %0,%0,-1\;{sfe|subfe} %0,%0,%0
6638 {sfi|subfic} %0,%1,%2\;{ai|addic} %0,%0,-1\;{sfe|subfe} %0,%0,%0"
6639 [(set_attr "length" "12,8,12,12,12")])
6640
6641 ;; Simplify (ne X (const_int 0)) on the PowerPC. No need to on the Power,
6642 ;; since it nabs/sr is just as fast.
6643 (define_insn ""
6644 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6645 (lshiftrt:SI (neg:SI (abs:SI (match_operand:SI 1 "gpc_reg_operand" "r")))
6646 (const_int 31)))
6647 (clobber (match_scratch:SI 2 "=&r"))]
6648 "!TARGET_POWER"
6649 "{ai|addic} %2,%1,-1\;{sfe|subfe} %0,%2,%1"
6650 [(set_attr "length" "8")])
6651
6652 ;; This is what (plus (ne X (const_int 0)) Y) looks like.
6653 (define_insn ""
6654 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6655 (plus:SI (lshiftrt:SI
6656 (neg:SI (abs:SI (match_operand:SI 1 "gpc_reg_operand" "r")))
6657 (const_int 31))
6658 (match_operand:SI 2 "gpc_reg_operand" "r")))
6659 (clobber (match_scratch:SI 3 "=&r"))]
6660 ""
6661 "{ai|addic} %3,%1,-1\;{aze|addze} %0,%2"
6662 [(set_attr "length" "8")])
6663
6664 (define_insn ""
6665 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
6666 (compare:CC
6667 (plus:SI (lshiftrt:SI
6668 (neg:SI (abs:SI (match_operand:SI 1 "gpc_reg_operand" "r")))
6669 (const_int 31))
6670 (match_operand:SI 2 "gpc_reg_operand" "r"))
6671 (const_int 0)))
6672 (clobber (match_scratch:SI 3 "=&r"))]
6673 ""
6674 "{ai|addic} %3,%1,-1\;{aze.|addze.} %3,%2"
6675 [(set_attr "type" "compare")
6676 (set_attr "length" "8")])
6677
6678 (define_insn ""
6679 [(set (match_operand:CC 4 "cc_reg_operand" "=x")
6680 (compare:CC
6681 (plus:SI (lshiftrt:SI
6682 (neg:SI (abs:SI (match_operand:SI 1 "gpc_reg_operand" "r")))
6683 (const_int 31))
6684 (match_operand:SI 2 "gpc_reg_operand" "r"))
6685 (const_int 0)))
6686 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
6687 (plus:SI (lshiftrt:SI (neg:SI (abs:SI (match_dup 1))) (const_int 31))
6688 (match_dup 2)))
6689 (clobber (match_scratch:SI 3 "=&r"))]
6690 ""
6691 "{ai|addic} %3,%1,-1\;{aze.|addze.} %0,%2"
6692 [(set_attr "type" "compare")
6693 (set_attr "length" "8")])
6694
6695 (define_insn ""
6696 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
6697 (le:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
6698 (match_operand:SI 2 "reg_or_short_operand" "r,O")))
6699 (clobber (match_scratch:SI 3 "=r,X"))]
6700 "TARGET_POWER"
6701 "@
6702 doz %3,%2,%1\;{sfi|subfic} %0,%3,0\;{ae|adde} %0,%0,%3
6703 {ai|addic} %0,%1,-1\;{aze|addze} %0,%0\;{sri|srwi} %0,%0,31"
6704 [(set_attr "length" "12")])
6705
6706 (define_insn ""
6707 [(set (match_operand:CC 4 "cc_reg_operand" "=x,x")
6708 (compare:CC
6709 (le:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
6710 (match_operand:SI 2 "reg_or_short_operand" "r,O"))
6711 (const_int 0)))
6712 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
6713 (le:SI (match_dup 1) (match_dup 2)))
6714 (clobber (match_scratch:SI 3 "=r,X"))]
6715 "TARGET_POWER"
6716 "@
6717 doz %3,%2,%1\;{sfi|subfic} %0,%3,0\;{ae.|adde.} %0,%0,%3
6718 {ai|addic} %0,%1,-1\;{aze|addze} %0,%0\;{sri.|srwi.} %0,%0,31"
6719 [(set_attr "type" "compare,delayed_compare")
6720 (set_attr "length" "12")])
6721
6722 (define_insn ""
6723 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
6724 (plus:SI (le:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
6725 (match_operand:SI 2 "reg_or_short_operand" "r,O"))
6726 (match_operand:SI 3 "gpc_reg_operand" "r,r")))
6727 (clobber (match_scratch:SI 4 "=&r,&r"))]
6728 "TARGET_POWER"
6729 "@
6730 doz %4,%2,%1\;{sfi|subfic} %4,%4,0\;{aze|addze} %0,%3
6731 {srai|srawi} %4,%1,31\;{sf|subfc} %4,%1,%4\;{aze|addze} %0,%3"
6732 [(set_attr "length" "12")])
6733
6734 (define_insn ""
6735 [(set (match_operand:CC 0 "cc_reg_operand" "=x,x")
6736 (compare:CC
6737 (plus:SI (le:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
6738 (match_operand:SI 2 "reg_or_short_operand" "r,O"))
6739 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
6740 (const_int 0)))
6741 (clobber (match_scratch:SI 4 "=&r,&r"))]
6742 "TARGET_POWER"
6743 "@
6744 doz %4,%2,%1\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %4,%3
6745 {srai|srawi} %4,%1,31\;{sf|subfc} %4,%1,%4\;{aze.|addze.} %4,%3"
6746 [(set_attr "type" "compare")
6747 (set_attr "length" "12")])
6748
6749 (define_insn ""
6750 [(set (match_operand:CC 5 "cc_reg_operand" "=x,x")
6751 (compare:CC
6752 (plus:SI (le:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
6753 (match_operand:SI 2 "reg_or_short_operand" "r,O"))
6754 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
6755 (const_int 0)))
6756 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
6757 (plus:SI (le:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
6758 (clobber (match_scratch:SI 4 "=&r,&r"))]
6759 "TARGET_POWER"
6760 "@
6761 doz %4,%2,%1\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %0,%3
6762 {srai|srawi} %4,%1,31\;{sf|subfc} %4,%1,%4\;{aze.|addze.} %0,%3"
6763 [(set_attr "type" "compare")
6764 (set_attr "length" "12")])
6765
6766 (define_insn ""
6767 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
6768 (neg:SI (le:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
6769 (match_operand:SI 2 "reg_or_short_operand" "r,O"))))]
6770 "TARGET_POWER"
6771 "@
6772 doz %0,%2,%1\;{ai|addic} %0,%0,-1\;{sfe|subfe} %0,%0,%0
6773 {ai|addic} %0,%1,-1\;{aze|addze} %0,%0\;{srai|srawi} %0,%0,31"
6774 [(set_attr "length" "12")])
6775
6776 (define_insn ""
6777 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6778 (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
6779 (match_operand:SI 2 "reg_or_short_operand" "rI")))]
6780 ""
6781 "{sf%I2|subf%I2c} %0,%1,%2\;{cal %0,0(0)|li %0,0}\;{ae|adde} %0,%0,%0"
6782 [(set_attr "length" "12")])
6783
6784 (define_insn ""
6785 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
6786 (compare:CC
6787 (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
6788 (match_operand:SI 2 "reg_or_short_operand" "rI"))
6789 (const_int 0)))
6790 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
6791 (leu:SI (match_dup 1) (match_dup 2)))]
6792 ""
6793 "{sf%I2|subf%I2c} %0,%1,%2\;{cal %0,0(0)|li %0,0}\;{ae.|adde.} %0,%0,%0"
6794 [(set_attr "type" "compare")
6795 (set_attr "length" "12")])
6796
6797 (define_insn ""
6798 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6799 (plus:SI (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
6800 (match_operand:SI 2 "reg_or_short_operand" "rI"))
6801 (match_operand:SI 3 "gpc_reg_operand" "r")))
6802 (clobber (match_scratch:SI 4 "=&r"))]
6803 ""
6804 "{sf%I2|subf%I2c} %4,%1,%2\;{aze|addze} %0,%3"
6805 [(set_attr "length" "8")])
6806
6807 (define_insn ""
6808 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
6809 (compare:CC
6810 (plus:SI (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
6811 (match_operand:SI 2 "reg_or_short_operand" "rI"))
6812 (match_operand:SI 3 "gpc_reg_operand" "r"))
6813 (const_int 0)))
6814 (clobber (match_scratch:SI 4 "=&r"))]
6815 ""
6816 "{sf%I2|subf%I2c} %4,%1,%2\;{aze.|addze.} %4,%3"
6817 [(set_attr "type" "compare")
6818 (set_attr "length" "8")])
6819
6820 (define_insn ""
6821 [(set (match_operand:CC 5 "cc_reg_operand" "=x")
6822 (compare:CC
6823 (plus:SI (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
6824 (match_operand:SI 2 "reg_or_short_operand" "rI"))
6825 (match_operand:SI 3 "gpc_reg_operand" "r"))
6826 (const_int 0)))
6827 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
6828 (plus:SI (leu:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
6829 (clobber (match_scratch:SI 4 "=&r"))]
6830 ""
6831 "{sf%I2|subf%I2c} %4,%1,%2\;{aze.|addze.} %0,%3"
6832 [(set_attr "type" "compare")
6833 (set_attr "length" "8")])
6834
6835 (define_insn ""
6836 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6837 (neg:SI (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
6838 (match_operand:SI 2 "reg_or_short_operand" "rI"))))]
6839 ""
6840 "{sf%I2|subf%I2c} %0,%1,%2\;{sfe|subfe} %0,%0,%0\;nand %0,%0,%0"
6841 [(set_attr "length" "12")])
6842
6843 (define_insn ""
6844 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6845 (and:SI (neg:SI
6846 (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
6847 (match_operand:SI 2 "reg_or_short_operand" "rI")))
6848 (match_operand:SI 3 "gpc_reg_operand" "r")))
6849 (clobber (match_scratch:SI 4 "=&r"))]
6850 ""
6851 "{sf%I2|subf%I2c} %4,%1,%2\;{sfe|subfe} %4,%4,%4\;andc %0,%3,%4"
6852 [(set_attr "length" "12")])
6853
6854 (define_insn ""
6855 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
6856 (compare:CC
6857 (and:SI (neg:SI
6858 (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
6859 (match_operand:SI 2 "reg_or_short_operand" "rI")))
6860 (match_operand:SI 3 "gpc_reg_operand" "r"))
6861 (const_int 0)))
6862 (clobber (match_scratch:SI 4 "=&r"))]
6863 ""
6864 "{sf%I2|subf%I2c} %4,%1,%2\;{sfe|subfe} %4,%4,%4\;andc. %4,%3,%4"
6865 [(set_attr "type" "compare")
6866 (set_attr "length" "12")])
6867
6868 (define_insn ""
6869 [(set (match_operand:CC 5 "cc_reg_operand" "=x")
6870 (compare:CC
6871 (and:SI (neg:SI
6872 (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
6873 (match_operand:SI 2 "reg_or_short_operand" "rI")))
6874 (match_operand:SI 3 "gpc_reg_operand" "r"))
6875 (const_int 0)))
6876 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
6877 (and:SI (neg:SI (leu:SI (match_dup 1) (match_dup 2))) (match_dup 3)))
6878 (clobber (match_scratch:SI 4 "=&r"))]
6879 ""
6880 "{sf%I2|subf%I2c} %4,%1,%2\;{sfe|subfe} %4,%4,%4\;andc. %0,%3,%4"
6881 [(set_attr "type" "compare")
6882 (set_attr "length" "12")])
6883
6884 (define_insn ""
6885 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6886 (lt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
6887 (match_operand:SI 2 "reg_or_short_operand" "rI")))]
6888 "TARGET_POWER"
6889 "doz%I2 %0,%1,%2\;nabs %0,%0\;{sri|srwi} %0,%0,31"
6890 [(set_attr "length" "12")])
6891
6892 (define_insn ""
6893 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
6894 (compare:CC
6895 (lt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
6896 (match_operand:SI 2 "reg_or_short_operand" "rI"))
6897 (const_int 0)))
6898 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
6899 (lt:SI (match_dup 1) (match_dup 2)))]
6900 "TARGET_POWER"
6901 "doz%I2 %0,%1,%2\;nabs %0,%0\;{sri.|srwi.} %0,%0,31"
6902 [(set_attr "type" "delayed_compare")
6903 (set_attr "length" "12")])
6904
6905 (define_insn ""
6906 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6907 (plus:SI (lt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
6908 (match_operand:SI 2 "reg_or_short_operand" "rI"))
6909 (match_operand:SI 3 "gpc_reg_operand" "r")))
6910 (clobber (match_scratch:SI 4 "=&r"))]
6911 "TARGET_POWER"
6912 "doz%I2 %4,%1,%2\;{ai|addic} %4,%4,-1\;{aze|addze} %0,%3"
6913 [(set_attr "length" "12")])
6914
6915 (define_insn ""
6916 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
6917 (compare:CC
6918 (plus:SI (lt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
6919 (match_operand:SI 2 "reg_or_short_operand" "rI"))
6920 (match_operand:SI 3 "gpc_reg_operand" "r"))
6921 (const_int 0)))
6922 (clobber (match_scratch:SI 4 "=&r"))]
6923 "TARGET_POWER"
6924 "doz%I2 %4,%1,%2\;{ai|addic} %4,%4,-1\;{aze.|addze.} %4,%3"
6925 [(set_attr "type" "compare")
6926 (set_attr "length" "12")])
6927
6928 (define_insn ""
6929 [(set (match_operand:CC 5 "cc_reg_operand" "=x")
6930 (compare:CC
6931 (plus:SI (lt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
6932 (match_operand:SI 2 "reg_or_short_operand" "rI"))
6933 (match_operand:SI 3 "gpc_reg_operand" "r"))
6934 (const_int 0)))
6935 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
6936 (plus:SI (lt:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
6937 (clobber (match_scratch:SI 4 "=&r"))]
6938 "TARGET_POWER"
6939 "doz%I2 %4,%1,%2\;{ai|addic} %4,%4,-1\;{aze.|addze.} %0,%3"
6940 [(set_attr "type" "compare")
6941 (set_attr "length" "12")])
6942
6943 (define_insn ""
6944 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6945 (neg:SI (lt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
6946 (match_operand:SI 2 "reg_or_short_operand" "rI"))))]
6947 "TARGET_POWER"
6948 "doz%I2 %0,%1,%2\;nabs %0,%0\;{srai|srawi} %0,%0,31"
6949 [(set_attr "length" "12")])
6950
6951 (define_insn ""
6952 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
6953 (ltu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
6954 (match_operand:SI 2 "reg_or_neg_short_operand" "r,P")))]
6955 ""
6956 "@
6957 {sf|subfc} %0,%2,%1\;{sfe|subfe} %0,%0,%0\;neg %0,%0
6958 {ai|addic} %0,%1,%n2\;{sfe|subfe} %0,%0,%0\;neg %0,%0"
6959 [(set_attr "length" "12")])
6960
6961 (define_insn ""
6962 [(set (match_operand:CC 3 "cc_reg_operand" "=x,x")
6963 (compare:CC
6964 (ltu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
6965 (match_operand:SI 2 "reg_or_neg_short_operand" "r,P"))
6966 (const_int 0)))
6967 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
6968 (ltu:SI (match_dup 1) (match_dup 2)))]
6969 ""
6970 "@
6971 {sf|subfc} %0,%2,%1\;{sfe|subfe} %0,%0,%0\;neg. %0,%0
6972 {ai|addic} %0,%1,%n2\;{sfe|subfe} %0,%0,%0\;neg. %0,%0"
6973 [(set_attr "type" "compare")
6974 (set_attr "length" "12")])
6975
6976 (define_insn ""
6977 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r")
6978 (plus:SI (ltu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r")
6979 (match_operand:SI 2 "reg_or_neg_short_operand" "r,r,P,P"))
6980 (match_operand:SI 3 "reg_or_short_operand" "r,I,r,I")))
6981 (clobber (match_scratch:SI 4 "=&r,r,&r,r"))]
6982 ""
6983 "@
6984 {sf|subfc} %4,%2,%1\;{sfe|subfe} %4,%4,%4\;{sf%I3|subf%I3c} %0,%4,%3
6985 {sf|subfc} %4,%2,%1\;{sfe|subfe} %4,%4,%4\;{sf%I3|subf%I3c} %0,%4,%3
6986 {ai|addic} %4,%1,%n2\;{sfe|subfe} %4,%4,%4\;{sf%I3|subf%I3c} %0,%4,%3
6987 {ai|addic} %4,%1,%n2\;{sfe|subfe} %4,%4,%4\;{sf%I3|subf%I3c} %0,%4,%3"
6988 [(set_attr "length" "12")])
6989
6990 (define_insn ""
6991 [(set (match_operand:CC 0 "cc_reg_operand" "=x,x")
6992 (compare:CC
6993 (plus:SI (ltu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
6994 (match_operand:SI 2 "reg_or_neg_short_operand" "r,P"))
6995 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
6996 (const_int 0)))
6997 (clobber (match_scratch:SI 4 "=&r,&r"))]
6998 ""
6999 "@
7000 {sf|subfc} %4,%2,%1\;{sfe|subfe} %4,%4,%4\;{sf.|subfc.} %4,%4,%3
7001 {ai|addic} %4,%1,%n2\;{sfe|subfe} %4,%4,%4\;{sf.|subfc.} %4,%4,%3"
7002 [(set_attr "type" "compare")
7003 (set_attr "length" "12")])
7004
7005 (define_insn ""
7006 [(set (match_operand:CC 5 "cc_reg_operand" "=x,x")
7007 (compare:CC
7008 (plus:SI (ltu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
7009 (match_operand:SI 2 "reg_or_neg_short_operand" "r,P"))
7010 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
7011 (const_int 0)))
7012 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
7013 (plus:SI (ltu:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
7014 (clobber (match_scratch:SI 4 "=&r,&r"))]
7015 ""
7016 "@
7017 {sf|subfc} %4,%2,%1\;{sfe|subfe} %4,%4,%4\;{sf.|subfc.} %0,%4,%3
7018 {ai|addic} %4,%1,%n2\;{sfe|subfe} %4,%4,%4\;{sf.|subfc.} %0,%4,%3"
7019 [(set_attr "type" "compare")
7020 (set_attr "length" "12")])
7021
7022 (define_insn ""
7023 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
7024 (neg:SI (ltu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
7025 (match_operand:SI 2 "reg_or_neg_short_operand" "r,P"))))]
7026 ""
7027 "@
7028 {sf|subfc} %0,%2,%1\;{sfe|subfe} %0,%0,%0
7029 {ai|addic} %0,%1,%n2\;{sfe|subfe} %0,%0,%0"
7030 [(set_attr "length" "8")])
7031
7032 (define_insn ""
7033 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
7034 (ge:SI (match_operand:SI 1 "gpc_reg_operand" "r")
7035 (match_operand:SI 2 "reg_or_short_operand" "rI")))
7036 (clobber (match_scratch:SI 3 "=r"))]
7037 "TARGET_POWER"
7038 "doz%I2 %3,%1,%2\;{sfi|subfic} %0,%3,0\;{ae|adde} %0,%0,%3"
7039 [(set_attr "length" "12")])
7040
7041 (define_insn ""
7042 [(set (match_operand:CC 4 "cc_reg_operand" "=x")
7043 (compare:CC
7044 (ge:SI (match_operand:SI 1 "gpc_reg_operand" "r")
7045 (match_operand:SI 2 "reg_or_short_operand" "rI"))
7046 (const_int 0)))
7047 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
7048 (ge:SI (match_dup 1) (match_dup 2)))
7049 (clobber (match_scratch:SI 3 "=r"))]
7050 "TARGET_POWER"
7051 "doz%I2 %3,%1,%2\;{sfi|subfic} %0,%3,0\;{ae.|adde.} %0,%0,%3"
7052 [(set_attr "type" "compare")
7053 (set_attr "length" "12")])
7054
7055 (define_insn ""
7056 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
7057 (plus:SI (ge:SI (match_operand:SI 1 "gpc_reg_operand" "r")
7058 (match_operand:SI 2 "reg_or_short_operand" "rI"))
7059 (match_operand:SI 3 "gpc_reg_operand" "r")))
7060 (clobber (match_scratch:SI 4 "=&r"))]
7061 "TARGET_POWER"
7062 "doz%I2 %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze|addze} %0,%3"
7063 [(set_attr "length" "12")])
7064
7065 (define_insn ""
7066 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
7067 (compare:CC
7068 (plus:SI (ge:SI (match_operand:SI 1 "gpc_reg_operand" "r")
7069 (match_operand:SI 2 "reg_or_short_operand" "rI"))
7070 (match_operand:SI 3 "gpc_reg_operand" "r"))
7071 (const_int 0)))
7072 (clobber (match_scratch:SI 4 "=&r"))]
7073 "TARGET_POWER"
7074 "doz%I2 %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %4,%3"
7075 [(set_attr "type" "compare")
7076 (set_attr "length" "12")])
7077
7078 (define_insn ""
7079 [(set (match_operand:CC 5 "cc_reg_operand" "=x")
7080 (compare:CC
7081 (plus:SI (ge:SI (match_operand:SI 1 "gpc_reg_operand" "r")
7082 (match_operand:SI 2 "reg_or_short_operand" "rI"))
7083 (match_operand:SI 3 "gpc_reg_operand" "r"))
7084 (const_int 0)))
7085 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
7086 (plus:SI (ge:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
7087 (clobber (match_scratch:SI 4 "=&r"))]
7088 "TARGET_POWER"
7089 "doz%I2 %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %0,%3"
7090 [(set_attr "type" "compare")
7091 (set_attr "length" "12")])
7092
7093 (define_insn ""
7094 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
7095 (neg:SI (ge:SI (match_operand:SI 1 "gpc_reg_operand" "r")
7096 (match_operand:SI 2 "reg_or_short_operand" "rI"))))]
7097 "TARGET_POWER"
7098 "doz%I2 %0,%1,%2\;{ai|addic} %0,%0,-1\;{sfe|subfe} %0,%0,%0"
7099 [(set_attr "length" "12")])
7100
7101 ;; This is (and (neg (ge X (const_int 0))) Y).
7102 (define_insn ""
7103 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
7104 (and:SI (neg:SI
7105 (lshiftrt:SI
7106 (not:SI (match_operand:SI 1 "gpc_reg_operand" "r"))
7107 (const_int 31)))
7108 (match_operand:SI 2 "gpc_reg_operand" "r")))
7109 (clobber (match_scratch:SI 3 "=&r"))]
7110 ""
7111 "{srai|srawi} %3,%1,31\;andc %0,%2,%3"
7112 [(set_attr "length" "8")])
7113
7114 (define_insn ""
7115 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
7116 (compare:CC
7117 (and:SI (neg:SI
7118 (lshiftrt:SI
7119 (not:SI (match_operand:SI 1 "gpc_reg_operand" "r"))
7120 (const_int 31)))
7121 (match_operand:SI 2 "gpc_reg_operand" "r"))
7122 (const_int 0)))
7123 (clobber (match_scratch:SI 3 "=&r"))]
7124 ""
7125 "{srai|srawi} %3,%1,31\;andc. %3,%2,%3"
7126 [(set_attr "type" "compare")
7127 (set_attr "length" "8")])
7128
7129 (define_insn ""
7130 [(set (match_operand:CC 4 "cc_reg_operand" "=x")
7131 (compare:CC
7132 (and:SI (neg:SI
7133 (lshiftrt:SI
7134 (not:SI (match_operand:SI 1 "gpc_reg_operand" "r"))
7135 (const_int 31)))
7136 (match_operand:SI 2 "gpc_reg_operand" "r"))
7137 (const_int 0)))
7138 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
7139 (and:SI (neg:SI (lshiftrt:SI (not:SI (match_dup 1))
7140 (const_int 31)))
7141 (match_dup 2)))
7142 (clobber (match_scratch:SI 3 "=&r"))]
7143 ""
7144 "{srai|srawi} %3,%1,31\;andc. %0,%2,%3"
7145 [(set_attr "type" "compare")
7146 (set_attr "length" "8")])
7147
7148 (define_insn ""
7149 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
7150 (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
7151 (match_operand:SI 2 "reg_or_neg_short_operand" "r,P")))]
7152 ""
7153 "@
7154 {sf|subfc} %0,%2,%1\;{cal %0,0(0)|li %0,0}\;{ae|adde} %0,%0,%0
7155 {ai|addic} %0,%1,%n2\;{cal %0,0(0)|li %0,0}\;{ae|adde} %0,%0,%0"
7156 [(set_attr "length" "12")])
7157
7158 (define_insn ""
7159 [(set (match_operand:CC 3 "cc_reg_operand" "=x,x")
7160 (compare:CC
7161 (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
7162 (match_operand:SI 2 "reg_or_neg_short_operand" "r,P"))
7163 (const_int 0)))
7164 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
7165 (geu:SI (match_dup 1) (match_dup 2)))]
7166 ""
7167 "@
7168 {sf|subfc} %0,%2,%1\;{cal %0,0(0)|li %0,0}\;{ae.|adde.} %0,%0,%0
7169 {ai|addic} %0,%1,%n2\;{cal %0,0(0)|li %0,0}\;{ae.|adde.} %0,%0,%0"
7170 [(set_attr "type" "compare")
7171 (set_attr "length" "12")])
7172
7173 (define_insn ""
7174 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
7175 (plus:SI (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
7176 (match_operand:SI 2 "reg_or_neg_short_operand" "r,P"))
7177 (match_operand:SI 3 "gpc_reg_operand" "r,r")))
7178 (clobber (match_scratch:SI 4 "=&r,&r"))]
7179 ""
7180 "@
7181 {sf|subfc} %4,%2,%1\;{aze|addze} %0,%3
7182 {ai|addic} %4,%1,%n2\;{aze|addze} %0,%3"
7183 [(set_attr "length" "8")])
7184
7185 (define_insn ""
7186 [(set (match_operand:CC 0 "cc_reg_operand" "=x,x")
7187 (compare:CC
7188 (plus:SI (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
7189 (match_operand:SI 2 "reg_or_neg_short_operand" "r,P"))
7190 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
7191 (const_int 0)))
7192 (clobber (match_scratch:SI 4 "=&r,&r"))]
7193 ""
7194 "@
7195 {sf|subfc} %4,%2,%1\;{aze.|addze.} %4,%3
7196 {ai|addic} %4,%1,%n2\;{aze.|addze.} %4,%3"
7197 [(set_attr "type" "compare")
7198 (set_attr "length" "8")])
7199
7200 (define_insn ""
7201 [(set (match_operand:CC 5 "cc_reg_operand" "=x,x")
7202 (compare:CC
7203 (plus:SI (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
7204 (match_operand:SI 2 "reg_or_neg_short_operand" "r,P"))
7205 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
7206 (const_int 0)))
7207 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
7208 (plus:SI (geu:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
7209 (clobber (match_scratch:SI 4 "=&r,&r"))]
7210 ""
7211 "@
7212 {sf|subfc} %4,%2,%1\;{aze.|addze.} %0,%3
7213 {ai|addic} %4,%1,%n2\;{aze.|addze.} %4,%3"
7214 [(set_attr "type" "compare")
7215 (set_attr "length" "8")])
7216
7217 (define_insn ""
7218 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
7219 (neg:SI (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
7220 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))]
7221 ""
7222 "@
7223 {sf|subfc} %0,%2,%1\;{sfe|subfe} %0,%0,%0\;nand %0,%0,%0
7224 {sfi|subfic} %0,%1,-1\;{a%I2|add%I2c} %0,%0,%2\;{sfe|subfe} %0,%0,%0"
7225 [(set_attr "length" "12")])
7226
7227 (define_insn ""
7228 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
7229 (and:SI (neg:SI
7230 (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
7231 (match_operand:SI 2 "reg_or_neg_short_operand" "r,P")))
7232 (match_operand:SI 3 "gpc_reg_operand" "r,r")))
7233 (clobber (match_scratch:SI 4 "=&r,&r"))]
7234 ""
7235 "@
7236 {sf|subfc} %4,%2,%1\;{sfe|subfe} %4,%4,%4\;andc %0,%3,%4
7237 {ai|addic} %4,%1,%n2\;{sfe|subfe} %4,%4,%4\;andc %0,%3,%4"
7238 [(set_attr "length" "12")])
7239
7240 (define_insn ""
7241 [(set (match_operand:CC 0 "cc_reg_operand" "=x,x")
7242 (compare:CC
7243 (and:SI (neg:SI
7244 (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
7245 (match_operand:SI 2 "reg_or_neg_short_operand" "r,P")))
7246 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
7247 (const_int 0)))
7248 (clobber (match_scratch:SI 4 "=&r,&r"))]
7249 ""
7250 "@
7251 {sf|subfc} %4,%2,%1\;{sfe|subfe} %4,%4,%4\;andc. %4,%3,%4
7252 {ai|addic} %4,%1,%n2\;{sfe|subfe} %4,%4,%4\;andc. %4,%3,%4"
7253 [(set_attr "type" "compare")
7254 (set_attr "length" "12")])
7255
7256 (define_insn ""
7257 [(set (match_operand:CC 5 "cc_reg_operand" "=x,x")
7258 (compare:CC
7259 (and:SI (neg:SI
7260 (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
7261 (match_operand:SI 2 "reg_or_neg_short_operand" "r,P")))
7262 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
7263 (const_int 0)))
7264 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
7265 (and:SI (neg:SI (geu:SI (match_dup 1) (match_dup 2))) (match_dup 3)))
7266 (clobber (match_scratch:SI 4 "=&r,&r"))]
7267 ""
7268 "@
7269 {sf|subfc} %4,%2,%1\;{sfe|subfe} %4,%4,%4\;andc. %0,%3,%4
7270 {ai|addic} %4,%1,%n2\;{sfe|subfe} %4,%4,%4\;andc. %0,%3,%4"
7271 [(set_attr "type" "compare")
7272 (set_attr "length" "12")])
7273
7274 (define_insn ""
7275 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
7276 (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
7277 (const_int 0)))]
7278 ""
7279 "{sfi|subfic} %0,%1,0\;{ame|addme} %0,%0\;{sri|srwi} %0,%0,31"
7280 [(set_attr "length" "12")])
7281
7282 (define_insn ""
7283 [(set (match_operand:CC 2 "cc_reg_operand" "=x")
7284 (compare:CC
7285 (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
7286 (const_int 0))
7287 (const_int 0)))
7288 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
7289 (gt:SI (match_dup 1) (const_int 0)))]
7290 ""
7291 "{sfi|subfic} %0,%1,0\;{ame|addme} %0,%0\;{sri.|srwi.} %0,%0,31"
7292 [(set_attr "type" "delayed_compare")
7293 (set_attr "length" "12")])
7294
7295 (define_insn ""
7296 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
7297 (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
7298 (match_operand:SI 2 "reg_or_short_operand" "r")))]
7299 "TARGET_POWER"
7300 "doz %0,%2,%1\;nabs %0,%0\;{sri|srwi} %0,%0,31"
7301 [(set_attr "length" "12")])
7302
7303 (define_insn ""
7304 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
7305 (compare:CC
7306 (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
7307 (match_operand:SI 2 "reg_or_short_operand" "r"))
7308 (const_int 0)))
7309 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
7310 (gt:SI (match_dup 1) (match_dup 2)))]
7311 "TARGET_POWER"
7312 "doz %0,%2,%1\;nabs %0,%0\;{sri.|srwi.} %0,%0,31"
7313 [(set_attr "type" "delayed_compare")
7314 (set_attr "length" "12")])
7315
7316 (define_insn ""
7317 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
7318 (plus:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
7319 (const_int 0))
7320 (match_operand:SI 2 "gpc_reg_operand" "r")))
7321 (clobber (match_scratch:SI 3 "=&r"))]
7322 ""
7323 "{a|addc} %3,%1,%1\;{sfe|subfe} %3,%1,%3\;{aze|addze} %0,%2"
7324 [(set_attr "length" "12")])
7325
7326 (define_insn ""
7327 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
7328 (compare:CC
7329 (plus:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
7330 (const_int 0))
7331 (match_operand:SI 2 "gpc_reg_operand" "r"))
7332 (const_int 0)))
7333 (clobber (match_scratch:SI 3 "=&r"))]
7334 ""
7335 "{a|addc} %3,%1,%1\;{sfe|subfe} %3,%1,%3\;{aze.|addze.} %0,%2"
7336 [(set_attr "type" "compare")
7337 (set_attr "length" "12")])
7338
7339 (define_insn ""
7340 [(set (match_operand:CC 4 "cc_reg_operand" "=x")
7341 (compare:CC
7342 (plus:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
7343 (const_int 0))
7344 (match_operand:SI 2 "gpc_reg_operand" "r"))
7345 (const_int 0)))
7346 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
7347 (plus:SI (gt:SI (match_dup 1) (const_int 0)) (match_dup 2)))
7348 (clobber (match_scratch:SI 3 "=&r"))]
7349 ""
7350 "{a|addc} %3,%1,%1\;{sfe|subfe} %3,%1,%3\;{aze.|addze.} %3,%2"
7351 [(set_attr "type" "compare")
7352 (set_attr "length" "12")])
7353
7354 (define_insn ""
7355 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
7356 (plus:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
7357 (match_operand:SI 2 "reg_or_short_operand" "r"))
7358 (match_operand:SI 3 "gpc_reg_operand" "r")))
7359 (clobber (match_scratch:SI 4 "=&r"))]
7360 "TARGET_POWER"
7361 "doz %4,%2,%1\;{ai|addic} %4,%4,-1\;{aze|addze} %0,%3"
7362 [(set_attr "length" "12")])
7363
7364 (define_insn ""
7365 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
7366 (compare:CC
7367 (plus:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
7368 (match_operand:SI 2 "reg_or_short_operand" "r"))
7369 (match_operand:SI 3 "gpc_reg_operand" "r"))
7370 (const_int 0)))
7371 (clobber (match_scratch:SI 4 "=&r"))]
7372 "TARGET_POWER"
7373 "doz %4,%2,%1\;{ai|addic} %4,%4,-1\;{aze.|addze.} %4,%3"
7374 [(set_attr "type" "compare")
7375 (set_attr "length" "12")])
7376
7377 (define_insn ""
7378 [(set (match_operand:CC 5 "cc_reg_operand" "=x")
7379 (compare:CC
7380 (plus:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
7381 (match_operand:SI 2 "reg_or_short_operand" "r"))
7382 (match_operand:SI 3 "gpc_reg_operand" "r"))
7383 (const_int 0)))
7384 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
7385 (plus:SI (gt:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
7386 (clobber (match_scratch:SI 4 "=&r"))]
7387 "TARGET_POWER"
7388 "doz %4,%2,%1\;{ai|addic} %4,%4,-1\;{aze.|addze.} %0,%3"
7389 [(set_attr "type" "compare")
7390 (set_attr "length" "12")])
7391
7392 (define_insn ""
7393 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
7394 (neg:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
7395 (const_int 0))))]
7396 ""
7397 "{sfi|subfic} %0,%1,0\;{ame|addme} %0,%0\;{srai|srawi} %0,%0,31"
7398 [(set_attr "length" "12")])
7399
7400 (define_insn ""
7401 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
7402 (neg:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
7403 (match_operand:SI 2 "reg_or_short_operand" "r"))))]
7404 "TARGET_POWER"
7405 "doz %0,%2,%1\;nabs %0,%0\;{srai|srawi} %0,%0,31"
7406 [(set_attr "length" "12")])
7407
7408 (define_insn ""
7409 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
7410 (gtu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
7411 (match_operand:SI 2 "reg_or_short_operand" "rI")))]
7412 ""
7413 "{sf%I2|subf%I2c} %0,%1,%2\;{sfe|subfe} %0,%0,%0\;neg %0,%0"
7414 [(set_attr "length" "12")])
7415
7416 (define_insn ""
7417 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
7418 (compare:CC
7419 (gtu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
7420 (match_operand:SI 2 "reg_or_short_operand" "rI"))
7421 (const_int 0)))
7422 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
7423 (gtu:SI (match_dup 1) (match_dup 2)))]
7424 ""
7425 "{sf%I2|subf%I2c} %0,%1,%2\;{sfe|subfe} %0,%0,%0\;neg. %0,%0"
7426 [(set_attr "type" "compare")
7427 (set_attr "length" "12")])
7428
7429 (define_insn ""
7430 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r")
7431 (plus:SI (gtu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r")
7432 (match_operand:SI 2 "reg_or_short_operand" "I,r,rI"))
7433 (match_operand:SI 3 "reg_or_short_operand" "r,r,I")))
7434 (clobber (match_scratch:SI 4 "=&r,&r,&r"))]
7435 ""
7436 "@
7437 {ai|addic} %4,%1,%k2\;{aze|addze} %0,%3
7438 {sf%I2|subf%I2c} %4,%1,%2\;{sfe|subfe} %4,%4,%4\;{sf%I3|subf%I3c} %0,%4,%3
7439 {sf%I2|subf%I2c} %4,%1,%2\;{sfe|subfe} %4,%4,%4\;{sf%I3|subf%I3c} %0,%4,%3"
7440 [(set_attr "length" "8,12,12")])
7441
7442 (define_insn ""
7443 [(set (match_operand:CC 0 "cc_reg_operand" "=x,x")
7444 (compare:CC
7445 (plus:SI (gtu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
7446 (match_operand:SI 2 "reg_or_short_operand" "I,r"))
7447 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
7448 (const_int 0)))
7449 (clobber (match_scratch:SI 4 "=&r,&r"))]
7450 ""
7451 "@
7452 {ai|addic} %4,%1,%k2\;{aze.|addze.} %0,%3
7453 {sf%I2|subf%I2c} %4,%1,%2\;{sfe|subfe} %4,%4,%4\;{sf.|subfc.} %0,%4,%3"
7454 [(set_attr "type" "compare")
7455 (set_attr "length" "8,12")])
7456
7457 (define_insn ""
7458 [(set (match_operand:CC 5 "cc_reg_operand" "=x,x")
7459 (compare:CC
7460 (plus:SI (gtu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
7461 (match_operand:SI 2 "reg_or_short_operand" "I,r"))
7462 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
7463 (const_int 0)))
7464 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
7465 (plus:SI (gtu:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
7466 (clobber (match_scratch:SI 4 "=&r,&r"))]
7467 ""
7468 "@
7469 {ai|addic} %4,%1,%k2\;{aze.|addze.} %0,%3
7470 {sf%I2|subf%I2c} %4,%1,%2\;{sfe|subfe} %4,%4,%4\;{sf.|subfc.} %0,%4,%3"
7471 [(set_attr "type" "compare")
7472 (set_attr "length" "8,12")])
7473
7474 (define_insn ""
7475 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
7476 (neg:SI (gtu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
7477 (match_operand:SI 2 "reg_or_short_operand" "rI"))))]
7478 ""
7479 "{sf%I2|subf%I2c} %0,%1,%2\;{sfe|subfe} %0,%0,%0"
7480 [(set_attr "length" "8")])
7481 \f
7482 ;; Define both directions of branch and return. If we need a reload
7483 ;; register, we'd rather use CR0 since it is much easier to copy a
7484 ;; register CC value to there.
7485
7486 (define_insn ""
7487 [(set (pc)
7488 (if_then_else (match_operator 1 "branch_comparison_operator"
7489 [(match_operand 2
7490 "cc_reg_operand" "x,?y")
7491 (const_int 0)])
7492 (label_ref (match_operand 0 "" ""))
7493 (pc)))]
7494 ""
7495 "*
7496 {
7497 if (get_attr_length (insn) == 8)
7498 return \"%C1bc %t1,%j1,%l0\";
7499 else
7500 return \"%C1bc %T1,%j1,$+8\;b %l0\";
7501 }"
7502 [(set_attr "type" "branch")])
7503
7504 (define_insn ""
7505 [(set (pc)
7506 (if_then_else (match_operator 0 "branch_comparison_operator"
7507 [(match_operand 1
7508 "cc_reg_operand" "x,?y")
7509 (const_int 0)])
7510 (return)
7511 (pc)))]
7512 "direct_return ()"
7513 "{%C0bcr|%C0bclr} %t0,%j0"
7514 [(set_attr "length" "8")])
7515
7516 (define_insn ""
7517 [(set (pc)
7518 (if_then_else (match_operator 1 "branch_comparison_operator"
7519 [(match_operand 2
7520 "cc_reg_operand" "x,?y")
7521 (const_int 0)])
7522 (pc)
7523 (label_ref (match_operand 0 "" ""))))]
7524 ""
7525 "*
7526 {
7527 if (get_attr_length (insn) == 8)
7528 return \"%C1bc %T1,%j1,%l0\";
7529 else
7530 return \"%C1bc %t1,%j1,$+8\;b %l0\";
7531 }"
7532 [(set_attr "type" "branch")])
7533
7534 (define_insn ""
7535 [(set (pc)
7536 (if_then_else (match_operator 0 "branch_comparison_operator"
7537 [(match_operand 1
7538 "cc_reg_operand" "x,?y")
7539 (const_int 0)])
7540 (pc)
7541 (return)))]
7542 "direct_return ()"
7543 "{%C0bcr|%C0bclr} %T0,%j0"
7544 [(set_attr "length" "8")])
7545
7546 ;; Unconditional branch and return.
7547
7548 (define_insn "jump"
7549 [(set (pc)
7550 (label_ref (match_operand 0 "" "")))]
7551 ""
7552 "b %l0")
7553
7554 (define_insn "return"
7555 [(return)]
7556 "direct_return ()"
7557 "{br|blr}"
7558 [(set_attr "type" "jmpreg")])
7559
7560 (define_insn "indirect_jump"
7561 [(set (pc) (match_operand:SI 0 "register_operand" "c,l"))]
7562 ""
7563 "@
7564 bctr
7565 {br|blr}"
7566 [(set_attr "type" "jmpreg")])
7567
7568 ;; Table jump for switch statements:
7569 (define_expand "tablejump"
7570 [(set (match_dup 3)
7571 (plus:SI (match_operand:SI 0 "" "")
7572 (match_dup 2)))
7573 (parallel [(set (pc) (match_dup 3))
7574 (use (label_ref (match_operand 1 "" "")))])]
7575 ""
7576 "
7577 { operands[0] = force_reg (SImode, operands[0]);
7578 operands[2] = force_reg (SImode, gen_rtx (LABEL_REF, VOIDmode, operands[1]));
7579 operands[3] = gen_reg_rtx (SImode);
7580 }")
7581
7582 (define_insn ""
7583 [(set (pc)
7584 (match_operand:SI 0 "register_operand" "c,l"))
7585 (use (label_ref (match_operand 1 "" "")))]
7586 ""
7587 "@
7588 bctr
7589 {br|blr}"
7590 [(set_attr "type" "jmpreg")])
7591
7592 (define_insn "nop"
7593 [(const_int 0)]
7594 ""
7595 "{cror 0,0,0|nop}")
7596 \f
7597 ;; Define the subtract-one-and-jump insns, starting with the template
7598 ;; so loop.c knows what to generate.
7599
7600 (define_expand "decrement_and_branch_on_count"
7601 [(parallel [(set (pc) (if_then_else (ne (match_operand:SI 0 "register_operand" "")
7602 (const_int 1))
7603 (label_ref (match_operand 1 "" ""))
7604 (pc)))
7605 (set (match_dup 0)
7606 (plus:SI (match_dup 0)
7607 (const_int -1)))
7608 (clobber (match_scratch:CC 2 ""))
7609 (clobber (match_scratch:SI 3 ""))])]
7610 ""
7611 "")
7612
7613 ;; We need to be able to do this for any operand, including MEM, or we
7614 ;; will cause reload to blow up since we don't allow output reloads on
7615 ;; JUMP_INSNs.
7616 ;; In order that the length attribute is calculated correctly, the
7617 ;; label MUST be operand 0.
7618
7619 (define_insn ""
7620 [(set (pc)
7621 (if_then_else (ne (match_operand:SI 1 "register_operand" "c,*r,*r")
7622 (const_int 1))
7623 (label_ref (match_operand 0 "" ""))
7624 (pc)))
7625 (set (match_operand:SI 2 "register_operand" "=1,*r,m*q*c*l")
7626 (plus:SI (match_dup 1)
7627 (const_int -1)))
7628 (clobber (match_scratch:CC 3 "=X,&x,&x"))
7629 (clobber (match_scratch:SI 4 "=X,X,r"))]
7630 ""
7631 "*
7632 {
7633 if (which_alternative != 0)
7634 return \"#\";
7635 else if (get_attr_length (insn) == 8)
7636 return \"{bdn|bdnz} %l0\";
7637 else
7638 return \"bdz $+8\;b %l0\";
7639 }"
7640 [(set_attr "type" "branch")
7641 (set_attr "length" "*,12,16")])
7642
7643 (define_insn ""
7644 [(set (pc)
7645 (if_then_else (ne (match_operand:SI 1 "register_operand" "c,*r,*r")
7646 (const_int 1))
7647 (pc)
7648 (label_ref (match_operand 0 "" ""))))
7649 (set (match_operand:SI 2 "register_operand" "=1,*r,m*q*c*l")
7650 (plus:SI (match_dup 1)
7651 (const_int -1)))
7652 (clobber (match_scratch:CC 3 "=X,&x,&x"))
7653 (clobber (match_scratch:SI 4 "=X,X,r"))]
7654 ""
7655 "*
7656 {
7657 if (which_alternative != 0)
7658 return \"#\";
7659 else if (get_attr_length (insn) == 8)
7660 return \"bdz %l0\";
7661 else
7662 return \"{bdn|bdnz} $+8\;b %l0\";
7663 }"
7664 [(set_attr "type" "branch")
7665 (set_attr "length" "*,12,16")])
7666
7667 ;; Similar, but we can use GE since we have a REG_NONNEG.
7668 (define_insn ""
7669 [(set (pc)
7670 (if_then_else (ge (match_operand:SI 1 "register_operand" "c,*r,*r")
7671 (const_int 0))
7672 (label_ref (match_operand 0 "" ""))
7673 (pc)))
7674 (set (match_operand:SI 2 "register_operand" "=1,*r,m*q*c*l")
7675 (plus:SI (match_dup 1)
7676 (const_int -1)))
7677 (clobber (match_scratch:CC 3 "=X,&x,&X"))
7678 (clobber (match_scratch:SI 4 "=X,X,r"))]
7679 "find_reg_note (insn, REG_NONNEG, 0)"
7680 "*
7681 {
7682 if (which_alternative != 0)
7683 return \"#\";
7684 else if (get_attr_length (insn) == 8)
7685 return \"{bdn|bdnz} %l0\";
7686 else
7687 return \"bdz $+8\;b %l0\";
7688 }"
7689 [(set_attr "type" "branch")
7690 (set_attr "length" "*,12,16")])
7691
7692 (define_insn ""
7693 [(set (pc)
7694 (if_then_else (ge (match_operand:SI 1 "register_operand" "c,*r,*r")
7695 (const_int 0))
7696 (pc)
7697 (label_ref (match_operand 0 "" ""))))
7698 (set (match_operand:SI 2 "register_operand" "=1,*r,m*q*c*l")
7699 (plus:SI (match_dup 1)
7700 (const_int -1)))
7701 (clobber (match_scratch:CC 3 "=X,&x,&X"))
7702 (clobber (match_scratch:SI 4 "=X,X,r"))]
7703 "find_reg_note (insn, REG_NONNEG, 0)"
7704 "*
7705 {
7706 if (which_alternative != 0)
7707 return \"#\";
7708 else if (get_attr_length (insn) == 8)
7709 return \"bdz %l0\";
7710 else
7711 return \"{bdn|bdnz} $+8\;b %l0\";
7712 }"
7713 [(set_attr "type" "branch")
7714 (set_attr "length" "*,12,16")])
7715
7716 (define_insn ""
7717 [(set (pc)
7718 (if_then_else (eq (match_operand:SI 1 "register_operand" "c,*r,*r")
7719 (const_int 1))
7720 (label_ref (match_operand 0 "" ""))
7721 (pc)))
7722 (set (match_operand:SI 2 "register_operand" "=1,*r,m*q*c*l")
7723 (plus:SI (match_dup 1)
7724 (const_int -1)))
7725 (clobber (match_scratch:CC 3 "=X,&x,&x"))
7726 (clobber (match_scratch:SI 4 "=X,X,r"))]
7727 ""
7728 "*
7729 {
7730 if (which_alternative != 0)
7731 return \"#\";
7732 else if (get_attr_length (insn) == 8)
7733 return \"bdz %l0\";
7734 else
7735 return \"{bdn|bdnz} $+8\;b %l0\";
7736 }"
7737 [(set_attr "type" "branch")
7738 (set_attr "length" "*,12,16")])
7739
7740 (define_insn ""
7741 [(set (pc)
7742 (if_then_else (eq (match_operand:SI 1 "register_operand" "c,*r,*r")
7743 (const_int 1))
7744 (pc)
7745 (label_ref (match_operand 0 "" ""))))
7746 (set (match_operand:SI 2 "register_operand" "=1,*r,m*q*c*l")
7747 (plus:SI (match_dup 1)
7748 (const_int -1)))
7749 (clobber (match_scratch:CC 3 "=X,&x,&x"))
7750 (clobber (match_scratch:SI 4 "=X,X,r"))]
7751 ""
7752 "*
7753 {
7754 if (which_alternative != 0)
7755 return \"#\";
7756 else if (get_attr_length (insn) == 8)
7757 return \"{bdn|bdnz} %l0\";
7758 else
7759 return \"bdz $+8\;b %l0\";
7760 }"
7761 [(set_attr "type" "branch")
7762 (set_attr "length" "*,12,16")])
7763
7764 (define_split
7765 [(set (pc)
7766 (if_then_else (match_operator 2 "comparison_operator"
7767 [(match_operand:SI 1 "gpc_reg_operand" "")
7768 (const_int 1)])
7769 (match_operand 5 "" "")
7770 (match_operand 6 "" "")))
7771 (set (match_operand:SI 0 "gpc_reg_operand" "")
7772 (plus:SI (match_dup 1)
7773 (const_int -1)))
7774 (clobber (match_scratch:CC 3 ""))
7775 (clobber (match_scratch:SI 4 ""))]
7776 "reload_completed"
7777 [(parallel [(set (match_dup 3)
7778 (compare:CC (plus:SI (match_dup 1)
7779 (const_int -1))
7780 (const_int 0)))
7781 (set (match_dup 0)
7782 (plus:SI (match_dup 1)
7783 (const_int -1)))])
7784 (set (pc) (if_then_else (match_dup 7)
7785 (match_dup 5)
7786 (match_dup 6)))]
7787 "
7788 { operands[7] = gen_rtx (GET_CODE (operands[2]), VOIDmode, operands[3],
7789 const0_rtx); }")
7790
7791 (define_split
7792 [(set (pc)
7793 (if_then_else (match_operator 2 "comparison_operator"
7794 [(match_operand:SI 1 "gpc_reg_operand" "")
7795 (const_int 1)])
7796 (match_operand 5 "" "")
7797 (match_operand 6 "" "")))
7798 (set (match_operand:SI 0 "general_operand" "")
7799 (plus:SI (match_dup 1) (const_int -1)))
7800 (clobber (match_scratch:CC 3 ""))
7801 (clobber (match_scratch:SI 4 ""))]
7802 "reload_completed && ! gpc_reg_operand (operands[0], SImode)"
7803 [(parallel [(set (match_dup 3)
7804 (compare:CC (plus:SI (match_dup 1)
7805 (const_int -1))
7806 (const_int 0)))
7807 (set (match_dup 4)
7808 (plus:SI (match_dup 1)
7809 (const_int -1)))])
7810 (set (match_dup 0)
7811 (match_dup 4))
7812 (set (pc) (if_then_else (match_dup 7)
7813 (match_dup 5)
7814 (match_dup 6)))]
7815 "
7816 { operands[7] = gen_rtx (GET_CODE (operands[2]), VOIDmode, operands[3],
7817 const0_rtx); }")
7818
This page took 0.377582 seconds and 6 git commands to generate.