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