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