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