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