]> gcc.gnu.org Git - gcc.git/blob - gcc/config/rs6000/rs6000.md
382a0a79abda763f1b01a37acb85838b4dcec924
[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, 95, 1996 Free Software Foundation, Inc.
3 ;; Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
4
5 ;; This file is part of GNU CC.
6
7 ;; GNU CC is free software; you can redistribute it and/or modify
8 ;; it under the terms of the GNU General Public License as published by
9 ;; the Free Software Foundation; either version 2, or (at your option)
10 ;; any later version.
11
12 ;; GNU CC is distributed in the hope that it will be useful,
13 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
14 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 ;; GNU General Public License for more details.
16
17 ;; You should have received a copy of the GNU General Public License
18 ;; along with GNU CC; see the file COPYING. If not, write to
19 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
20 ;; Boston, MA 02111-1307, USA.
21
22 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
23 \f
24 ;; Define an insn type attribute. This is used in function unit delay
25 ;; computations.
26 (define_attr "type" "integer,load,store,fpload,fpstore,imul,idiv,branch,compare,delayed_compare,fpcompare,mtjmpr,fp,dmul,sdiv,ddiv,ssqrt,dsqrt,jmpreg"
27 (const_string "integer"))
28
29 ;; Length (in bytes).
30 (define_attr "length" ""
31 (if_then_else (eq_attr "type" "branch")
32 (if_then_else (and (ge (minus (pc) (match_dup 0))
33 (const_int -32768))
34 (lt (minus (pc) (match_dup 0))
35 (const_int 32767)))
36 (const_int 8)
37 (const_int 12))
38 (const_int 4)))
39
40 ;; Processor type -- this attribute must exactly match the processor_type
41 ;; enumeration in rs6000.h.
42
43 (define_attr "cpu" "rios1,rios2,mpccore,ppc403,ppc601,ppc603,ppc604,ppc620"
44 (const (symbol_ref "rs6000_cpu_attr")))
45
46 ; (define_function_unit NAME MULTIPLICITY SIMULTANEITY
47 ; TEST READY-DELAY ISSUE-DELAY [CONFLICT-LIST])
48
49 ; Load/Store Unit -- pure PowerPC only
50 ; (POWER and 601 use Integer Unit)
51 (define_function_unit "lsu" 1 0
52 (and (eq_attr "type" "load")
53 (eq_attr "cpu" "mpccore,ppc603,ppc604,ppc620"))
54 2 1)
55
56 (define_function_unit "lsu" 1 0
57 (and (eq_attr "type" "store,fpstore")
58 (eq_attr "cpu" "mpccore,ppc603,ppc604,ppc620"))
59 1 1)
60
61 (define_function_unit "lsu" 1 0
62 (and (eq_attr "type" "fpload")
63 (eq_attr "cpu" "mpccore,ppc603"))
64 2 1)
65
66 (define_function_unit "lsu" 1 0
67 (and (eq_attr "type" "fpload")
68 (eq_attr "cpu" "ppc604,ppc620"))
69 3 1)
70
71 (define_function_unit "iu" 1 0
72 (and (eq_attr "type" "load")
73 (eq_attr "cpu" "rios1,ppc403,ppc601"))
74 2 1)
75
76 (define_function_unit "iu" 1 0
77 (and (eq_attr "type" "store,fpstore")
78 (eq_attr "cpu" "rios1,ppc403,ppc601"))
79 1 1)
80
81 (define_function_unit "fpu" 1 0
82 (and (eq_attr "type" "fpstore")
83 (eq_attr "cpu" "rios1,ppc601"))
84 0 1)
85
86 (define_function_unit "iu" 1 0
87 (and (eq_attr "type" "fpload")
88 (eq_attr "cpu" "rios1"))
89 2 1)
90
91 (define_function_unit "iu" 1 0
92 (and (eq_attr "type" "fpload")
93 (eq_attr "cpu" "ppc601"))
94 3 1)
95
96 (define_function_unit "iu2" 2 0
97 (and (eq_attr "type" "load,fpload")
98 (eq_attr "cpu" "rios2"))
99 2 1)
100
101 (define_function_unit "iu2" 2 0
102 (and (eq_attr "type" "store,fpstore")
103 (eq_attr "cpu" "rios2"))
104 1 1)
105
106 ; Integer Unit (RIOS1, PPC601, PPC603)
107 (define_function_unit "iu" 1 0
108 (and (eq_attr "type" "integer")
109 (eq_attr "cpu" "rios1,mpccore,ppc403,ppc601,ppc603"))
110 1 1)
111
112 (define_function_unit "iu" 1 0
113 (and (eq_attr "type" "imul")
114 (eq_attr "cpu" "ppc403"))
115 4 4)
116
117 (define_function_unit "iu" 1 0
118 (and (eq_attr "type" "imul")
119 (eq_attr "cpu" "rios1,ppc601,ppc603"))
120 5 5)
121
122 (define_function_unit "iu" 1 0
123 (and (eq_attr "type" "idiv")
124 (eq_attr "cpu" "rios1"))
125 19 19)
126
127 (define_function_unit "iu" 1 0
128 (and (eq_attr "type" "idiv")
129 (eq_attr "cpu" "ppc403"))
130 33 33)
131
132 (define_function_unit "iu" 1 0
133 (and (eq_attr "type" "idiv")
134 (eq_attr "cpu" "ppc601"))
135 36 36)
136
137 (define_function_unit "iu" 1 0
138 (and (eq_attr "type" "idiv")
139 (eq_attr "cpu" "ppc603"))
140 37 36)
141
142 ; RIOS2 has two integer units: a primary one which can perform all
143 ; operations and a secondary one which is fed in lock step with the first
144 ; and can perform "simple" integer operations.
145 ; To catch this we define a 'dummy' imuldiv-unit that is also needed
146 ; for the complex insns.
147 (define_function_unit "iu2" 2 0
148 (and (eq_attr "type" "integer")
149 (eq_attr "cpu" "rios2"))
150 1 1)
151
152 (define_function_unit "iu2" 2 0
153 (and (eq_attr "type" "imul")
154 (eq_attr "cpu" "rios2"))
155 2 2)
156
157 (define_function_unit "iu2" 2 0
158 (and (eq_attr "type" "idiv")
159 (eq_attr "cpu" "rios2"))
160 13 13)
161
162 (define_function_unit "imuldiv" 1 0
163 (and (eq_attr "type" "imul")
164 (eq_attr "cpu" "rios2"))
165 2 2)
166
167 (define_function_unit "imuldiv" 1 0
168 (and (eq_attr "type" "idiv")
169 (eq_attr "cpu" "rios2"))
170 13 13)
171
172 ; MPCCORE has separate IMUL/IDIV unit for multicycle instructions
173 ; Divide latency varies greatly from 2-11, use 6 as average
174 (define_function_unit "imuldiv" 1 0
175 (and (eq_attr "type" "imul")
176 (eq_attr "cpu" "mpccore"))
177 2 1)
178
179 (define_function_unit "imuldiv" 1 0
180 (and (eq_attr "type" "idiv")
181 (eq_attr "cpu" "mpccore"))
182 6 6)
183
184 ; PPC604 has two units that perform integer operations
185 ; and one unit for divide/multiply operations (and move
186 ; from/to spr).
187 (define_function_unit "iu2" 2 0
188 (and (eq_attr "type" "integer")
189 (eq_attr "cpu" "ppc604,ppc620"))
190 1 1)
191
192 (define_function_unit "imuldiv" 1 0
193 (and (eq_attr "type" "imul")
194 (eq_attr "cpu" "ppc604,ppc620"))
195 4 2)
196
197 (define_function_unit "imuldiv" 1 0
198 (and (eq_attr "type" "idiv")
199 (eq_attr "cpu" "ppc604,ppc620"))
200 20 19)
201
202 ; compare is done on integer unit, but feeds insns which
203 ; execute on the branch unit.
204 (define_function_unit "iu" 1 0
205 (and (eq_attr "type" "compare")
206 (eq_attr "cpu" "rios1"))
207 4 1)
208
209 (define_function_unit "iu" 1 0
210 (and (eq_attr "type" "delayed_compare")
211 (eq_attr "cpu" "rios1"))
212 5 1)
213
214 (define_function_unit "iu" 1 0
215 (and (eq_attr "type" "compare,delayed_compare")
216 (eq_attr "cpu" "mpccore,ppc403,ppc601,ppc603,ppc604,ppc620"))
217 3 1)
218
219 (define_function_unit "iu2" 2 0
220 (and (eq_attr "type" "compare,delayed_compare")
221 (eq_attr "cpu" "rios2"))
222 3 1)
223
224 (define_function_unit "iu2" 2 0
225 (and (eq_attr "type" "compare,delayed_compare")
226 (eq_attr "cpu" "ppc604,ppc620"))
227 1 1)
228
229 ; fp compare uses fp unit
230 (define_function_unit "fpu" 1 0
231 (and (eq_attr "type" "fpcompare")
232 (eq_attr "cpu" "rios1"))
233 9 1)
234
235 ; rios1 and rios2 have different fpcompare delays
236 (define_function_unit "fpu2" 2 0
237 (and (eq_attr "type" "fpcompare")
238 (eq_attr "cpu" "rios2"))
239 5 1)
240
241 ; on ppc601 and ppc603, fpcompare takes also 2 cycles from
242 ; the integer unit
243 ; here we do not define delays, just occupy the unit. The dependencies
244 ; will be assigned by the fpcompare definition in the fpu.
245 (define_function_unit "iu" 1 0
246 (and (eq_attr "type" "fpcompare")
247 (eq_attr "cpu" "ppc601,ppc603"))
248 0 2)
249
250 ; fp compare uses fp unit
251 (define_function_unit "fpu" 1 0
252 (and (eq_attr "type" "fpcompare")
253 (eq_attr "cpu" "ppc601,ppc603,ppc604,ppc620"))
254 5 1)
255
256 (define_function_unit "fpu" 1 0
257 (and (eq_attr "type" "fpcompare")
258 (eq_attr "cpu" "mpccore"))
259 1 1)
260
261 (define_function_unit "bpu" 1 0
262 (and (eq_attr "type" "mtjmpr")
263 (eq_attr "cpu" "rios1,rios2"))
264 5 1)
265
266 (define_function_unit "bpu" 1 0
267 (and (eq_attr "type" "mtjmpr")
268 (eq_attr "cpu" "mpccore,ppc403,ppc601,ppc603,ppc604,ppc620"))
269 4 1)
270
271 ; all jumps/branches are executing on the bpu, in 1 cycle, for all machines.
272 (define_function_unit "bpu" 1 0
273 (eq_attr "type" "jmpreg")
274 1 1)
275
276 (define_function_unit "bpu" 1 0
277 (eq_attr "type" "branch")
278 1 1)
279
280 ; Floating Point Unit
281 (define_function_unit "fpu" 1 0
282 (and (eq_attr "type" "fp,dmul")
283 (eq_attr "cpu" "rios1"))
284 2 1)
285
286 (define_function_unit "fpu" 1 0
287 (and (eq_attr "type" "fp")
288 (eq_attr "cpu" "mpccore"))
289 4 4)
290
291 (define_function_unit "fpu" 1 0
292 (and (eq_attr "type" "fp")
293 (eq_attr "cpu" "ppc601"))
294 4 1)
295
296 (define_function_unit "fpu" 1 0
297 (and (eq_attr "type" "fp")
298 (eq_attr "cpu" "ppc603,ppc604,ppc620"))
299 3 1)
300
301 (define_function_unit "fpu" 1 0
302 (and (eq_attr "type" "dmul")
303 (eq_attr "cpu" "mpccore"))
304 5 5)
305
306 (define_function_unit "fpu" 1 0
307 (and (eq_attr "type" "dmul")
308 (eq_attr "cpu" "ppc601"))
309 5 2)
310
311 ; is this true?
312 (define_function_unit "fpu" 1 0
313 (and (eq_attr "type" "dmul")
314 (eq_attr "cpu" "ppc603"))
315 4 2)
316
317 (define_function_unit "fpu" 1 0
318 (and (eq_attr "type" "dmul")
319 (eq_attr "cpu" "ppc604,ppc620"))
320 3 1)
321
322 (define_function_unit "fpu" 1 0
323 (and (eq_attr "type" "sdiv,ddiv")
324 (eq_attr "cpu" "rios1"))
325 19 19)
326
327 (define_function_unit "fpu" 1 0
328 (and (eq_attr "type" "sdiv")
329 (eq_attr "cpu" "ppc601"))
330 17 17)
331
332 (define_function_unit "fpu" 1 0
333 (and (eq_attr "type" "sdiv")
334 (eq_attr "cpu" "mpccore"))
335 10 10)
336
337 (define_function_unit "fpu" 1 0
338 (and (eq_attr "type" "sdiv")
339 (eq_attr "cpu" "ppc603,ppc604,ppc620"))
340 18 18)
341
342 (define_function_unit "fpu" 1 0
343 (and (eq_attr "type" "ddiv")
344 (eq_attr "cpu" "mpccore"))
345 17 17)
346
347 (define_function_unit "fpu" 1 0
348 (and (eq_attr "type" "ddiv")
349 (eq_attr "cpu" "ppc601,ppc604,ppc620"))
350 31 31)
351
352 (define_function_unit "fpu" 1 0
353 (and (eq_attr "type" "ddiv")
354 (eq_attr "cpu" "ppc603"))
355 33 33)
356
357 (define_function_unit "fpu" 1 0
358 (and (eq_attr "type" "ssqrt")
359 (eq_attr "cpu" "ppc620"))
360 31 31)
361
362 (define_function_unit "fpu" 1 0
363 (and (eq_attr "type" "dsqrt")
364 (eq_attr "cpu" "ppc620"))
365 31 31)
366
367 ; RIOS2 has two symmetric FPUs.
368 (define_function_unit "fpu2" 2 0
369 (and (eq_attr "type" "fp")
370 (eq_attr "cpu" "rios2"))
371 2 1)
372
373 (define_function_unit "fpu2" 2 0
374 (and (eq_attr "type" "dmul")
375 (eq_attr "cpu" "rios2"))
376 2 1)
377
378 (define_function_unit "fpu2" 2 0
379 (and (eq_attr "type" "sdiv,ddiv")
380 (eq_attr "cpu" "rios2"))
381 17 17)
382
383 (define_function_unit "fpu2" 2 0
384 (and (eq_attr "type" "ssqrt,dsqrt")
385 (eq_attr "cpu" "rios2"))
386 26 26)
387
388 \f
389 ;; Start with fixed-point load and store insns. Here we put only the more
390 ;; complex forms. Basic data transfer is done later.
391
392 (define_expand "zero_extendqidi2"
393 [(set (match_operand:DI 0 "gpc_reg_operand" "")
394 (zero_extend:DI (match_operand:QI 1 "gpc_reg_operand" "")))]
395 "TARGET_POWERPC64"
396 "")
397
398 (define_insn ""
399 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
400 (zero_extend:DI (match_operand:QI 1 "reg_or_mem_operand" "m,r")))]
401 "TARGET_POWERPC64"
402 "@
403 lbz%U1%X1 %0,%1
404 rldicl %0,%1,0,56"
405 [(set_attr "type" "load,*")])
406
407 (define_insn ""
408 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
409 (compare:CC (zero_extend:DI (match_operand:QI 1 "gpc_reg_operand" "r"))
410 (const_int 0)))
411 (clobber (match_scratch:DI 2 "=r"))]
412 "TARGET_POWERPC64"
413 "rldicl. %2,%1,0,56"
414 [(set_attr "type" "compare")])
415
416 (define_insn ""
417 [(set (match_operand:CC 2 "cc_reg_operand" "=x")
418 (compare:CC (zero_extend:DI (match_operand:QI 1 "gpc_reg_operand" "r"))
419 (const_int 0)))
420 (set (match_operand:DI 0 "gpc_reg_operand" "=r")
421 (zero_extend:DI (match_dup 1)))]
422 "TARGET_POWERPC64"
423 "rldicl. %0,%1,0,56"
424 [(set_attr "type" "compare")])
425
426 (define_insn "extendqidi2"
427 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
428 (sign_extend:DI (match_operand:QI 1 "gpc_reg_operand" "r")))]
429 "TARGET_POWERPC64"
430 "extsb %0,%1")
431
432 (define_insn ""
433 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
434 (compare:CC (sign_extend:DI (match_operand:QI 1 "gpc_reg_operand" "r"))
435 (const_int 0)))
436 (clobber (match_scratch:DI 2 "=r"))]
437 "TARGET_POWERPC64"
438 "extsb. %2,%1"
439 [(set_attr "type" "compare")])
440
441 (define_insn ""
442 [(set (match_operand:CC 2 "cc_reg_operand" "=x")
443 (compare:CC (sign_extend:DI (match_operand:QI 1 "gpc_reg_operand" "r"))
444 (const_int 0)))
445 (set (match_operand:DI 0 "gpc_reg_operand" "=r")
446 (sign_extend:DI (match_dup 1)))]
447 "TARGET_POWERPC64"
448 "extsb. %0,%1"
449 [(set_attr "type" "compare")])
450
451 (define_expand "zero_extendhidi2"
452 [(set (match_operand:DI 0 "gpc_reg_operand" "")
453 (zero_extend:DI (match_operand:HI 1 "gpc_reg_operand" "")))]
454 "TARGET_POWERPC64"
455 "")
456
457 (define_insn ""
458 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
459 (zero_extend:DI (match_operand:HI 1 "reg_or_mem_operand" "m,r")))]
460 "TARGET_POWERPC64"
461 "@
462 lhz%U1%X1 %0,%1
463 rldicl %0,%1,0,48"
464 [(set_attr "type" "load,*")])
465
466 (define_insn ""
467 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
468 (compare:CC (zero_extend:DI (match_operand:HI 1 "gpc_reg_operand" "r"))
469 (const_int 0)))
470 (clobber (match_scratch:DI 2 "=r"))]
471 "TARGET_POWERPC64"
472 "rldicl. %2,%1,0,48"
473 [(set_attr "type" "compare")])
474
475 (define_insn ""
476 [(set (match_operand:CC 2 "cc_reg_operand" "=x")
477 (compare:CC (zero_extend:DI (match_operand:HI 1 "gpc_reg_operand" "r"))
478 (const_int 0)))
479 (set (match_operand:DI 0 "gpc_reg_operand" "=r")
480 (zero_extend:DI (match_dup 1)))]
481 "TARGET_POWERPC64"
482 "rldicl. %0,%1,0,48"
483 [(set_attr "type" "compare")])
484
485 (define_expand "extendhidi2"
486 [(set (match_operand:DI 0 "gpc_reg_operand" "")
487 (sign_extend:DI (match_operand:HI 1 "gpc_reg_operand" "")))]
488 "TARGET_POWERPC64"
489 "")
490
491 (define_insn ""
492 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
493 (sign_extend:DI (match_operand:HI 1 "reg_or_mem_operand" "m,r")))]
494 "TARGET_POWERPC64"
495 "@
496 lha%U1%X1 %0,%1
497 extsh %0,%1"
498 [(set_attr "type" "load,*")])
499
500 (define_insn ""
501 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
502 (compare:CC (sign_extend:DI (match_operand:HI 1 "gpc_reg_operand" "r"))
503 (const_int 0)))
504 (clobber (match_scratch:DI 2 "=r"))]
505 "TARGET_POWERPC64"
506 "extsh. %2,%1"
507 [(set_attr "type" "compare")])
508
509 (define_insn ""
510 [(set (match_operand:CC 2 "cc_reg_operand" "=x")
511 (compare:CC (sign_extend:DI (match_operand:HI 1 "gpc_reg_operand" "r"))
512 (const_int 0)))
513 (set (match_operand:DI 0 "gpc_reg_operand" "=r")
514 (sign_extend:DI (match_dup 1)))]
515 "TARGET_POWERPC64"
516 "extsh. %0,%1"
517 [(set_attr "type" "compare")])
518
519 (define_expand "zero_extendsidi2"
520 [(set (match_operand:DI 0 "gpc_reg_operand" "")
521 (zero_extend:DI (match_operand:SI 1 "gpc_reg_operand" "")))]
522 "TARGET_POWERPC64"
523 "")
524
525 (define_insn ""
526 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
527 (zero_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "m,r")))]
528 "TARGET_POWERPC64"
529 "@
530 lwz%U1%X1 %0,%1
531 rldicl %0,%1,0,32"
532 [(set_attr "type" "load,*")])
533
534 (define_insn ""
535 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
536 (compare:CC (zero_extend:DI (match_operand:SI 1 "gpc_reg_operand" "r"))
537 (const_int 0)))
538 (clobber (match_scratch:DI 2 "=r"))]
539 "TARGET_POWERPC64"
540 "rldicl. %2,%1,0,32"
541 [(set_attr "type" "compare")])
542
543 (define_insn ""
544 [(set (match_operand:CC 2 "cc_reg_operand" "=x")
545 (compare:CC (zero_extend:DI (match_operand:SI 1 "gpc_reg_operand" "r"))
546 (const_int 0)))
547 (set (match_operand:DI 0 "gpc_reg_operand" "=r")
548 (zero_extend:DI (match_dup 1)))]
549 "TARGET_POWERPC64"
550 "rldicl. %0,%1,0,32"
551 [(set_attr "type" "compare")])
552
553 (define_expand "extendsidi2"
554 [(set (match_operand:DI 0 "gpc_reg_operand" "")
555 (sign_extend:DI (match_operand:SI 1 "gpc_reg_operand" "")))]
556 "TARGET_POWERPC64"
557 "")
558
559 (define_insn ""
560 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
561 (sign_extend:DI (match_operand:SI 1 "lwa_operand" "m,r")))]
562 "TARGET_POWERPC64"
563 "@
564 lwa%U1%X1 %0,%1
565 extsw %0,%1"
566 [(set_attr "type" "load,*")])
567
568 (define_insn ""
569 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
570 (compare:CC (sign_extend:DI (match_operand:SI 1 "gpc_reg_operand" "r"))
571 (const_int 0)))
572 (clobber (match_scratch:DI 2 "=r"))]
573 "TARGET_POWERPC64"
574 "extsw. %2,%1"
575 [(set_attr "type" "compare")])
576
577 (define_insn ""
578 [(set (match_operand:CC 2 "cc_reg_operand" "=x")
579 (compare:CC (sign_extend:DI (match_operand:SI 1 "gpc_reg_operand" "r"))
580 (const_int 0)))
581 (set (match_operand:DI 0 "gpc_reg_operand" "=r")
582 (sign_extend:DI (match_dup 1)))]
583 "TARGET_POWERPC64"
584 "extsw. %0,%1"
585 [(set_attr "type" "compare")])
586
587 (define_expand "zero_extendqisi2"
588 [(set (match_operand:SI 0 "gpc_reg_operand" "")
589 (zero_extend:SI (match_operand:QI 1 "gpc_reg_operand" "")))]
590 ""
591 "")
592
593 (define_insn ""
594 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
595 (zero_extend:SI (match_operand:QI 1 "reg_or_mem_operand" "m,r")))]
596 ""
597 "@
598 lbz%U1%X1 %0,%1
599 {rlinm|rlwinm} %0,%1,0,0xff"
600 [(set_attr "type" "load,*")])
601
602 (define_insn ""
603 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
604 (compare:CC (zero_extend:SI (match_operand:QI 1 "gpc_reg_operand" "r"))
605 (const_int 0)))
606 (clobber (match_scratch:SI 2 "=r"))]
607 ""
608 "{andil.|andi.} %2,%1,0xff"
609 [(set_attr "type" "compare")])
610
611 (define_insn ""
612 [(set (match_operand:CC 2 "cc_reg_operand" "=x")
613 (compare:CC (zero_extend:SI (match_operand:QI 1 "gpc_reg_operand" "r"))
614 (const_int 0)))
615 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
616 (zero_extend:SI (match_dup 1)))]
617 ""
618 "{andil.|andi.} %0,%1,0xff"
619 [(set_attr "type" "compare")])
620
621 (define_expand "extendqisi2"
622 [(use (match_operand:SI 0 "gpc_reg_operand" ""))
623 (use (match_operand:QI 1 "gpc_reg_operand" ""))]
624 ""
625 "
626 {
627 if (TARGET_POWERPC)
628 emit_insn (gen_extendqisi2_ppc (operands[0], operands[1]));
629 else if (TARGET_POWER)
630 emit_insn (gen_extendqisi2_power (operands[0], operands[1]));
631 else
632 emit_insn (gen_extendqisi2_no_power (operands[0], operands[1]));
633 DONE;
634 }")
635
636 (define_insn "extendqisi2_ppc"
637 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
638 (sign_extend:SI (match_operand:QI 1 "gpc_reg_operand" "r")))]
639 "TARGET_POWERPC"
640 "extsb %0,%1")
641
642 (define_insn ""
643 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
644 (compare:CC (sign_extend:SI (match_operand:QI 1 "gpc_reg_operand" "r"))
645 (const_int 0)))
646 (clobber (match_scratch:SI 2 "=r"))]
647 "TARGET_POWERPC"
648 "extsb. %2,%1"
649 [(set_attr "type" "compare")])
650
651 (define_insn ""
652 [(set (match_operand:CC 2 "cc_reg_operand" "=x")
653 (compare:CC (sign_extend:SI (match_operand:QI 1 "gpc_reg_operand" "r"))
654 (const_int 0)))
655 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
656 (sign_extend:SI (match_dup 1)))]
657 "TARGET_POWERPC"
658 "extsb. %0,%1"
659 [(set_attr "type" "compare")])
660
661 (define_expand "extendqisi2_power"
662 [(parallel [(set (match_dup 2)
663 (ashift:SI (match_operand:QI 1 "gpc_reg_operand" "")
664 (const_int 24)))
665 (clobber (scratch:SI))])
666 (parallel [(set (match_operand:SI 0 "gpc_reg_operand" "")
667 (ashiftrt:SI (match_dup 2)
668 (const_int 24)))
669 (clobber (scratch:SI))])]
670 "TARGET_POWER"
671 "
672 { operands[1] = gen_lowpart (SImode, operands[1]);
673 operands[2] = gen_reg_rtx (SImode); }")
674
675 (define_expand "extendqisi2_no_power"
676 [(set (match_dup 2)
677 (ashift:SI (match_operand:QI 1 "gpc_reg_operand" "")
678 (const_int 24)))
679 (set (match_operand:SI 0 "gpc_reg_operand" "")
680 (ashiftrt:SI (match_dup 2)
681 (const_int 24)))]
682 "! TARGET_POWER && ! TARGET_POWERPC"
683 "
684 { operands[1] = gen_lowpart (SImode, operands[1]);
685 operands[2] = gen_reg_rtx (SImode); }")
686
687 (define_expand "zero_extendqihi2"
688 [(set (match_operand:HI 0 "gpc_reg_operand" "")
689 (zero_extend:HI (match_operand:QI 1 "gpc_reg_operand" "")))]
690 ""
691 "")
692
693 (define_insn ""
694 [(set (match_operand:HI 0 "gpc_reg_operand" "=r,r")
695 (zero_extend:HI (match_operand:QI 1 "reg_or_mem_operand" "m,r")))]
696 ""
697 "@
698 lbz%U1%X1 %0,%1
699 {rlinm|rlwinm} %0,%1,0,0xff"
700 [(set_attr "type" "load,*")])
701
702 (define_insn ""
703 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
704 (compare:CC (zero_extend:HI (match_operand:QI 1 "gpc_reg_operand" "r"))
705 (const_int 0)))
706 (clobber (match_scratch:HI 2 "=r"))]
707 ""
708 "{andil.|andi.} %2,%1,0xff"
709 [(set_attr "type" "compare")])
710
711 (define_insn ""
712 [(set (match_operand:CC 2 "cc_reg_operand" "=x")
713 (compare:CC (zero_extend:HI (match_operand:QI 1 "gpc_reg_operand" "r"))
714 (const_int 0)))
715 (set (match_operand:HI 0 "gpc_reg_operand" "=r")
716 (zero_extend:HI (match_dup 1)))]
717 ""
718 "{andil.|andi.} %0,%1,0xff"
719 [(set_attr "type" "compare")])
720
721 (define_expand "extendqihi2"
722 [(use (match_operand:HI 0 "gpc_reg_operand" ""))
723 (use (match_operand:QI 1 "gpc_reg_operand" ""))]
724 ""
725 "
726 {
727 if (TARGET_POWERPC)
728 emit_insn (gen_extendqihi2_ppc (operands[0], operands[1]));
729 else if (TARGET_POWER)
730 emit_insn (gen_extendqihi2_power (operands[0], operands[1]));
731 else
732 emit_insn (gen_extendqihi2_no_power (operands[0], operands[1]));
733 DONE;
734 }")
735
736 (define_insn "extendqihi2_ppc"
737 [(set (match_operand:HI 0 "gpc_reg_operand" "=r")
738 (sign_extend:HI (match_operand:QI 1 "gpc_reg_operand" "r")))]
739 "TARGET_POWERPC"
740 "extsb %0,%1")
741
742 (define_insn ""
743 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
744 (compare:CC (sign_extend:HI (match_operand:QI 1 "gpc_reg_operand" "r"))
745 (const_int 0)))
746 (clobber (match_scratch:HI 2 "=r"))]
747 "TARGET_POWERPC"
748 "extsb. %2,%1"
749 [(set_attr "type" "compare")])
750
751 (define_insn ""
752 [(set (match_operand:CC 2 "cc_reg_operand" "=x")
753 (compare:CC (sign_extend:HI (match_operand:QI 1 "gpc_reg_operand" "r"))
754 (const_int 0)))
755 (set (match_operand:HI 0 "gpc_reg_operand" "=r")
756 (sign_extend:HI (match_dup 1)))]
757 "TARGET_POWERPC"
758 "extsb. %0,%1"
759 [(set_attr "type" "compare")])
760
761 (define_expand "extendqihi2_power"
762 [(parallel [(set (match_dup 2)
763 (ashift:SI (match_operand:QI 1 "gpc_reg_operand" "")
764 (const_int 24)))
765 (clobber (scratch:SI))])
766 (parallel [(set (match_operand:HI 0 "gpc_reg_operand" "")
767 (ashiftrt:SI (match_dup 2)
768 (const_int 24)))
769 (clobber (scratch:SI))])]
770 "TARGET_POWER"
771 "
772 { operands[0] = gen_lowpart (SImode, operands[0]);
773 operands[1] = gen_lowpart (SImode, operands[1]);
774 operands[2] = gen_reg_rtx (SImode); }")
775
776 (define_expand "extendqihi2_no_power"
777 [(set (match_dup 2)
778 (ashift:SI (match_operand:QI 1 "gpc_reg_operand" "")
779 (const_int 24)))
780 (set (match_operand:HI 0 "gpc_reg_operand" "")
781 (ashiftrt:SI (match_dup 2)
782 (const_int 24)))]
783 "! TARGET_POWER && ! TARGET_POWERPC"
784 "
785 { operands[0] = gen_lowpart (SImode, operands[0]);
786 operands[1] = gen_lowpart (SImode, operands[1]);
787 operands[2] = gen_reg_rtx (SImode); }")
788
789 (define_expand "zero_extendhisi2"
790 [(set (match_operand:SI 0 "gpc_reg_operand" "")
791 (zero_extend:SI (match_operand:HI 1 "gpc_reg_operand" "")))]
792 ""
793 "")
794
795 (define_insn ""
796 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
797 (zero_extend:SI (match_operand:HI 1 "reg_or_mem_operand" "m,r")))]
798 ""
799 "@
800 lhz%U1%X1 %0,%1
801 {rlinm|rlwinm} %0,%1,0,0xffff"
802 [(set_attr "type" "load,*")])
803
804 (define_insn ""
805 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
806 (compare:CC (zero_extend:SI (match_operand:HI 1 "gpc_reg_operand" "r"))
807 (const_int 0)))
808 (clobber (match_scratch:SI 2 "=r"))]
809 ""
810 "{andil.|andi.} %2,%1,0xffff"
811 [(set_attr "type" "compare")])
812
813 (define_insn ""
814 [(set (match_operand:CC 2 "cc_reg_operand" "=x")
815 (compare:CC (zero_extend:SI (match_operand:HI 1 "gpc_reg_operand" "r"))
816 (const_int 0)))
817 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
818 (zero_extend:SI (match_dup 1)))]
819 ""
820 "{andil.|andi.} %0,%1,0xffff"
821 [(set_attr "type" "compare")])
822
823 (define_expand "extendhisi2"
824 [(set (match_operand:SI 0 "gpc_reg_operand" "")
825 (sign_extend:SI (match_operand:HI 1 "gpc_reg_operand" "")))]
826 ""
827 "")
828
829 (define_insn ""
830 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
831 (sign_extend:SI (match_operand:HI 1 "reg_or_mem_operand" "m,r")))]
832 ""
833 "@
834 lha%U1%X1 %0,%1
835 {exts|extsh} %0,%1"
836 [(set_attr "type" "load,*")])
837
838 (define_insn ""
839 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
840 (compare:CC (sign_extend:SI (match_operand:HI 1 "gpc_reg_operand" "r"))
841 (const_int 0)))
842 (clobber (match_scratch:SI 2 "=r"))]
843 ""
844 "{exts.|extsh.} %2,%1"
845 [(set_attr "type" "compare")])
846
847 (define_insn ""
848 [(set (match_operand:CC 2 "cc_reg_operand" "=x")
849 (compare:CC (sign_extend:SI (match_operand:HI 1 "gpc_reg_operand" "r"))
850 (const_int 0)))
851 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
852 (sign_extend:SI (match_dup 1)))]
853 ""
854 "{exts.|extsh.} %0,%1"
855 [(set_attr "type" "compare")])
856 \f
857 ;; Fixed-point arithmetic insns.
858
859 ;; Discourage ai/addic because of carry but provide it in an alternative
860 ;; allowing register zero as source.
861 (define_insn "addsi3"
862 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,?r,r")
863 (plus:SI (match_operand:SI 1 "gpc_reg_operand" "%r,b,r,b")
864 (match_operand:SI 2 "add_operand" "r,I,I,J")))]
865 ""
866 "@
867 {cax|add} %0,%1,%2
868 {cal %0,%2(%1)|addi %0,%1,%2}
869 {ai|addic} %0,%1,%2
870 {cau|addis} %0,%1,%v2")
871
872 (define_insn ""
873 [(set (match_operand:CC 0 "cc_reg_operand" "=x,x")
874 (compare:CC (plus:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r")
875 (match_operand:SI 2 "reg_or_short_operand" "r,I"))
876 (const_int 0)))
877 (clobber (match_scratch:SI 3 "=r,r"))]
878 ""
879 "@
880 {cax.|add.} %3,%1,%2
881 {ai.|addic.} %3,%1,%2"
882 [(set_attr "type" "compare")])
883
884 (define_insn ""
885 [(set (match_operand:CC 3 "cc_reg_operand" "=x,x")
886 (compare:CC (plus:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r")
887 (match_operand:SI 2 "reg_or_short_operand" "r,I"))
888 (const_int 0)))
889 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
890 (plus:SI (match_dup 1) (match_dup 2)))]
891 ""
892 "@
893 {cax.|add.} %0,%1,%2
894 {ai.|addic.} %0,%1,%2"
895 [(set_attr "type" "compare")])
896
897 ;; Split an add that we can't do in one insn into two insns, each of which
898 ;; does one 16-bit part. This is used by combine. Note that the low-order
899 ;; add should be last in case the result gets used in an address.
900
901 (define_split
902 [(set (match_operand:SI 0 "gpc_reg_operand" "")
903 (plus:SI (match_operand:SI 1 "gpc_reg_operand" "")
904 (match_operand:SI 2 "non_add_cint_operand" "")))]
905 ""
906 [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))
907 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 4)))]
908 "
909 {
910 HOST_WIDE_INT low = INTVAL (operands[2]) & 0xffff;
911 HOST_WIDE_INT high = INTVAL (operands[2]) & (~ (HOST_WIDE_INT) 0xffff);
912
913 if (low & 0x8000)
914 high += 0x10000, low |= ((HOST_WIDE_INT) -1) << 16;
915
916 operands[3] = GEN_INT (high);
917 operands[4] = GEN_INT (low);
918 }")
919
920 (define_insn "one_cmplsi2"
921 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
922 (not:SI (match_operand:SI 1 "gpc_reg_operand" "r")))]
923 ""
924 "nor %0,%1,%1")
925
926 (define_insn ""
927 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
928 (compare:CC (not:SI (match_operand:SI 1 "gpc_reg_operand" "r"))
929 (const_int 0)))
930 (clobber (match_scratch:SI 2 "=r"))]
931 ""
932 "nor. %2,%1,%1"
933 [(set_attr "type" "compare")])
934
935 (define_insn ""
936 [(set (match_operand:CC 2 "cc_reg_operand" "=x")
937 (compare:CC (not:SI (match_operand:SI 1 "gpc_reg_operand" "r"))
938 (const_int 0)))
939 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
940 (not:SI (match_dup 1)))]
941 ""
942 "nor. %0,%1,%1"
943 [(set_attr "type" "compare")])
944
945 (define_insn ""
946 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
947 (minus:SI (match_operand:SI 1 "reg_or_short_operand" "rI")
948 (match_operand:SI 2 "gpc_reg_operand" "r")))]
949 "! TARGET_POWERPC"
950 "{sf%I1|subf%I1c} %0,%2,%1")
951
952 (define_insn ""
953 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
954 (minus:SI (match_operand:SI 1 "reg_or_short_operand" "r,I")
955 (match_operand:SI 2 "gpc_reg_operand" "r,r")))]
956 "TARGET_POWERPC"
957 "@
958 subf %0,%2,%1
959 subfic %0,%2,%1")
960
961 (define_insn ""
962 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
963 (compare:CC (minus:SI (match_operand:SI 1 "gpc_reg_operand" "r")
964 (match_operand:SI 2 "gpc_reg_operand" "r"))
965 (const_int 0)))
966 (clobber (match_scratch:SI 3 "=r"))]
967 "! TARGET_POWERPC"
968 "{sf.|subfc.} %3,%2,%1"
969 [(set_attr "type" "compare")])
970
971 (define_insn ""
972 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
973 (compare:CC (minus:SI (match_operand:SI 1 "gpc_reg_operand" "r")
974 (match_operand:SI 2 "gpc_reg_operand" "r"))
975 (const_int 0)))
976 (clobber (match_scratch:SI 3 "=r"))]
977 "TARGET_POWERPC"
978 "subf. %3,%2,%1"
979 [(set_attr "type" "compare")])
980
981 (define_insn ""
982 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
983 (compare:CC (minus:SI (match_operand:SI 1 "gpc_reg_operand" "r")
984 (match_operand:SI 2 "gpc_reg_operand" "r"))
985 (const_int 0)))
986 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
987 (minus:SI (match_dup 1) (match_dup 2)))]
988 "! TARGET_POWERPC"
989 "{sf.|subfc.} %0,%2,%1"
990 [(set_attr "type" "compare")])
991
992 (define_insn ""
993 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
994 (compare:CC (minus:SI (match_operand:SI 1 "gpc_reg_operand" "r")
995 (match_operand:SI 2 "gpc_reg_operand" "r"))
996 (const_int 0)))
997 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
998 (minus:SI (match_dup 1) (match_dup 2)))]
999 "TARGET_POWERPC"
1000 "subf. %0,%2,%1"
1001 [(set_attr "type" "compare")])
1002
1003 (define_expand "subsi3"
1004 [(set (match_operand:SI 0 "gpc_reg_operand" "")
1005 (minus:SI (match_operand:SI 1 "reg_or_short_operand" "")
1006 (match_operand:SI 2 "reg_or_cint_operand" "")))]
1007 ""
1008 "
1009 {
1010 if (GET_CODE (operands[2]) == CONST_INT)
1011 {
1012 emit_insn (gen_addsi3 (operands[0], operands[1],
1013 negate_rtx (SImode, operands[2])));
1014 DONE;
1015 }
1016 }")
1017
1018 ;; For SMIN, SMAX, UMIN, and UMAX, we use DEFINE_EXPAND's that involve a doz[i]
1019 ;; instruction and some auxiliary computations. Then we just have a single
1020 ;; DEFINE_INSN for doz[i] and the define_splits to make them if made by
1021 ;; combine.
1022
1023 (define_expand "sminsi3"
1024 [(set (match_dup 3)
1025 (if_then_else:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "")
1026 (match_operand:SI 2 "reg_or_short_operand" ""))
1027 (const_int 0)
1028 (minus:SI (match_dup 2) (match_dup 1))))
1029 (set (match_operand:SI 0 "gpc_reg_operand" "")
1030 (minus:SI (match_dup 2) (match_dup 3)))]
1031 "TARGET_POWER"
1032 "
1033 { operands[3] = gen_reg_rtx (SImode); }")
1034
1035 (define_split
1036 [(set (match_operand:SI 0 "gpc_reg_operand" "")
1037 (smin:SI (match_operand:SI 1 "gpc_reg_operand" "")
1038 (match_operand:SI 2 "reg_or_short_operand" "")))
1039 (clobber (match_operand:SI 3 "gpc_reg_operand" ""))]
1040 "TARGET_POWER"
1041 [(set (match_dup 3)
1042 (if_then_else:SI (gt:SI (match_dup 1) (match_dup 2))
1043 (const_int 0)
1044 (minus:SI (match_dup 2) (match_dup 1))))
1045 (set (match_dup 0) (minus:SI (match_dup 2) (match_dup 3)))]
1046 "")
1047
1048 (define_expand "smaxsi3"
1049 [(set (match_dup 3)
1050 (if_then_else:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "")
1051 (match_operand:SI 2 "reg_or_short_operand" ""))
1052 (const_int 0)
1053 (minus:SI (match_dup 2) (match_dup 1))))
1054 (set (match_operand:SI 0 "gpc_reg_operand" "")
1055 (plus:SI (match_dup 3) (match_dup 1)))]
1056 "TARGET_POWER"
1057 "
1058 { operands[3] = gen_reg_rtx (SImode); }")
1059
1060 (define_split
1061 [(set (match_operand:SI 0 "gpc_reg_operand" "")
1062 (smax:SI (match_operand:SI 1 "gpc_reg_operand" "")
1063 (match_operand:SI 2 "reg_or_short_operand" "")))
1064 (clobber (match_operand:SI 3 "gpc_reg_operand" ""))]
1065 "TARGET_POWER"
1066 [(set (match_dup 3)
1067 (if_then_else:SI (gt:SI (match_dup 1) (match_dup 2))
1068 (const_int 0)
1069 (minus:SI (match_dup 2) (match_dup 1))))
1070 (set (match_dup 0) (plus:SI (match_dup 3) (match_dup 1)))]
1071 "")
1072
1073 (define_expand "uminsi3"
1074 [(set (match_dup 3) (xor:SI (match_operand:SI 1 "gpc_reg_operand" "")
1075 (match_dup 5)))
1076 (set (match_dup 4) (xor:SI (match_operand:SI 2 "gpc_reg_operand" "")
1077 (match_dup 5)))
1078 (set (match_dup 3) (if_then_else:SI (gt (match_dup 3) (match_dup 4))
1079 (const_int 0)
1080 (minus:SI (match_dup 4) (match_dup 3))))
1081 (set (match_operand:SI 0 "gpc_reg_operand" "")
1082 (minus:SI (match_dup 2) (match_dup 3)))]
1083 "TARGET_POWER"
1084 "
1085 {
1086 operands[3] = gen_reg_rtx (SImode);
1087 operands[4] = gen_reg_rtx (SImode);
1088 operands[5] = GEN_INT (-2147483647 - 1);
1089 }")
1090
1091 (define_expand "umaxsi3"
1092 [(set (match_dup 3) (xor:SI (match_operand:SI 1 "gpc_reg_operand" "")
1093 (match_dup 5)))
1094 (set (match_dup 4) (xor:SI (match_operand:SI 2 "gpc_reg_operand" "")
1095 (match_dup 5)))
1096 (set (match_dup 3) (if_then_else:SI (gt (match_dup 3) (match_dup 4))
1097 (const_int 0)
1098 (minus:SI (match_dup 4) (match_dup 3))))
1099 (set (match_operand:SI 0 "gpc_reg_operand" "")
1100 (plus:SI (match_dup 3) (match_dup 1)))]
1101 "TARGET_POWER"
1102 "
1103 {
1104 operands[3] = gen_reg_rtx (SImode);
1105 operands[4] = gen_reg_rtx (SImode);
1106 operands[5] = GEN_INT (-2147483647 - 1);
1107 }")
1108
1109 (define_insn ""
1110 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1111 (if_then_else:SI (gt (match_operand:SI 1 "gpc_reg_operand" "r")
1112 (match_operand:SI 2 "reg_or_short_operand" "rI"))
1113 (const_int 0)
1114 (minus:SI (match_dup 2) (match_dup 1))))]
1115 "TARGET_POWER"
1116 "doz%I2 %0,%1,%2")
1117
1118 (define_insn ""
1119 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
1120 (compare:CC
1121 (if_then_else:SI (gt (match_operand:SI 1 "gpc_reg_operand" "r")
1122 (match_operand:SI 2 "reg_or_short_operand" "rI"))
1123 (const_int 0)
1124 (minus:SI (match_dup 2) (match_dup 1)))
1125 (const_int 0)))
1126 (clobber (match_scratch:SI 3 "=r"))]
1127 "TARGET_POWER"
1128 "doz%I2. %3,%1,%2"
1129 [(set_attr "type" "delayed_compare")])
1130
1131 (define_insn ""
1132 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1133 (compare:CC
1134 (if_then_else:SI (gt (match_operand:SI 1 "gpc_reg_operand" "r")
1135 (match_operand:SI 2 "reg_or_short_operand" "rI"))
1136 (const_int 0)
1137 (minus:SI (match_dup 2) (match_dup 1)))
1138 (const_int 0)))
1139 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1140 (if_then_else:SI (gt (match_dup 1) (match_dup 2))
1141 (const_int 0)
1142 (minus:SI (match_dup 2) (match_dup 1))))]
1143 "TARGET_POWER"
1144 "doz%I2. %0,%1,%2"
1145 [(set_attr "type" "delayed_compare")])
1146
1147 ;; We don't need abs with condition code because such comparisons should
1148 ;; never be done.
1149 (define_expand "abssi2"
1150 [(set (match_operand:SI 0 "gpc_reg_operand" "")
1151 (abs:SI (match_operand:SI 1 "gpc_reg_operand" "")))]
1152 ""
1153 "
1154 {
1155 if (!TARGET_POWER)
1156 {
1157 emit_insn (gen_abssi2_nopower (operands[0], operands[1]));
1158 DONE;
1159 }
1160 }")
1161
1162 (define_insn "abssi2_power"
1163 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1164 (abs:SI (match_operand:SI 1 "gpc_reg_operand" "r")))]
1165 "TARGET_POWER"
1166 "abs %0,%1")
1167
1168 (define_insn "abssi2_nopower"
1169 [(set (match_operand:SI 0 "gpc_reg_operand" "=&r,r")
1170 (abs:SI (match_operand:SI 1 "gpc_reg_operand" "r,0")))
1171 (clobber (match_scratch:SI 2 "=&r,&r"))]
1172 "!TARGET_POWER"
1173 "*
1174 {
1175 return (TARGET_POWERPC)
1176 ? \"{srai|srawi} %2,%1,31\;xor %0,%2,%1\;subf %0,%2,%0\"
1177 : \"{srai|srawi} %2,%1,31\;xor %0,%2,%1\;{sf|subfc} %0,%2,%0\";
1178 }"
1179 [(set_attr "length" "12")])
1180
1181 (define_split
1182 [(set (match_operand:SI 0 "gpc_reg_operand" "=&r,r")
1183 (abs:SI (match_operand:SI 1 "gpc_reg_operand" "r,0")))
1184 (clobber (match_scratch:SI 2 "=&r,&r"))]
1185 "!TARGET_POWER && reload_completed"
1186 [(set (match_dup 2) (ashiftrt:SI (match_dup 1) (const_int 31)))
1187 (set (match_dup 0) (xor:SI (match_dup 2) (match_dup 1)))
1188 (set (match_dup 0) (minus:SI (match_dup 2) (match_dup 0)))]
1189 "")
1190
1191 (define_insn ""
1192 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1193 (neg:SI (abs:SI (match_operand:SI 1 "gpc_reg_operand" "r"))))]
1194 "TARGET_POWER"
1195 "nabs %0,%1")
1196
1197 (define_insn ""
1198 [(set (match_operand:SI 0 "gpc_reg_operand" "=&r,r")
1199 (neg:SI (abs:SI (match_operand:SI 1 "gpc_reg_operand" "r,0"))))
1200 (clobber (match_scratch:SI 2 "=&r,&r"))]
1201 "!TARGET_POWER"
1202 "*
1203 {
1204 return (TARGET_POWERPC)
1205 ? \"{srai|srawi} %2,%1,31\;xor %0,%2,%1\;subf %0,%0,%2\"
1206 : \"{srai|srawi} %2,%1,31\;xor %0,%2,%1\;{sf|subfc} %0,%0,%2\";
1207 }"
1208 [(set_attr "length" "12")])
1209
1210 (define_split
1211 [(set (match_operand:SI 0 "gpc_reg_operand" "=&r,r")
1212 (neg:SI (abs:SI (match_operand:SI 1 "gpc_reg_operand" "r,0"))))
1213 (clobber (match_scratch:SI 2 "=&r,&r"))]
1214 "!TARGET_POWER && reload_completed"
1215 [(set (match_dup 2) (ashiftrt:SI (match_dup 1) (const_int 31)))
1216 (set (match_dup 0) (xor:SI (match_dup 2) (match_dup 1)))
1217 (set (match_dup 0) (minus:SI (match_dup 0) (match_dup 2)))]
1218 "")
1219
1220 (define_insn "negsi2"
1221 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1222 (neg:SI (match_operand:SI 1 "gpc_reg_operand" "r")))]
1223 ""
1224 "neg %0,%1")
1225
1226 (define_insn ""
1227 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
1228 (compare:CC (neg:SI (match_operand:SI 1 "gpc_reg_operand" "r"))
1229 (const_int 0)))
1230 (clobber (match_scratch:SI 2 "=r"))]
1231 ""
1232 "neg. %2,%1"
1233 [(set_attr "type" "compare")])
1234
1235 (define_insn ""
1236 [(set (match_operand:CC 2 "cc_reg_operand" "=x")
1237 (compare:CC (neg:SI (match_operand:SI 1 "gpc_reg_operand" "r"))
1238 (const_int 0)))
1239 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1240 (neg:SI (match_dup 1)))]
1241 ""
1242 "neg. %0,%1"
1243 [(set_attr "type" "compare")])
1244
1245 (define_insn "ffssi2"
1246 [(set (match_operand:SI 0 "gpc_reg_operand" "=&r")
1247 (ffs:SI (match_operand:SI 1 "gpc_reg_operand" "r")))]
1248 ""
1249 "neg %0,%1\;and %0,%0,%1\;{cntlz|cntlzw} %0,%0\;{sfi|subfic} %0,%0,32"
1250 [(set_attr "length" "16")])
1251
1252 (define_expand "mulsi3"
1253 [(use (match_operand:SI 0 "gpc_reg_operand" ""))
1254 (use (match_operand:SI 1 "gpc_reg_operand" ""))
1255 (use (match_operand:SI 2 "reg_or_short_operand" ""))]
1256 ""
1257 "
1258 {
1259 if (TARGET_POWER)
1260 emit_insn (gen_mulsi3_mq (operands[0], operands[1], operands[2]));
1261 else
1262 emit_insn (gen_mulsi3_no_mq (operands[0], operands[1], operands[2]));
1263 DONE;
1264 }")
1265
1266 (define_insn "mulsi3_mq"
1267 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
1268 (mult:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r")
1269 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
1270 (clobber (match_scratch:SI 3 "=q,q"))]
1271 "TARGET_POWER"
1272 "@
1273 {muls|mullw} %0,%1,%2
1274 {muli|mulli} %0,%1,%2"
1275 [(set_attr "type" "imul")])
1276
1277 (define_insn "mulsi3_no_mq"
1278 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
1279 (mult:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r")
1280 (match_operand:SI 2 "reg_or_short_operand" "r,I")))]
1281 "! TARGET_POWER"
1282 "@
1283 {muls|mullw} %0,%1,%2
1284 {muli|mulli} %0,%1,%2"
1285 [(set_attr "type" "imul")])
1286
1287 (define_insn ""
1288 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
1289 (compare:CC (mult:SI (match_operand:SI 1 "gpc_reg_operand" "%r")
1290 (match_operand:SI 2 "gpc_reg_operand" "r"))
1291 (const_int 0)))
1292 (clobber (match_scratch:SI 3 "=r"))
1293 (clobber (match_scratch:SI 4 "=q"))]
1294 "TARGET_POWER"
1295 "{muls.|mullw.} %3,%1,%2"
1296 [(set_attr "type" "delayed_compare")])
1297
1298 (define_insn ""
1299 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
1300 (compare:CC (mult:SI (match_operand:SI 1 "gpc_reg_operand" "%r")
1301 (match_operand:SI 2 "gpc_reg_operand" "r"))
1302 (const_int 0)))
1303 (clobber (match_scratch:SI 3 "=r"))]
1304 "! TARGET_POWER"
1305 "{muls.|mullw.} %3,%1,%2"
1306 [(set_attr "type" "delayed_compare")])
1307
1308 (define_insn ""
1309 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1310 (compare:CC (mult:SI (match_operand:SI 1 "gpc_reg_operand" "%r")
1311 (match_operand:SI 2 "gpc_reg_operand" "r"))
1312 (const_int 0)))
1313 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1314 (mult:SI (match_dup 1) (match_dup 2)))
1315 (clobber (match_scratch:SI 4 "=q"))]
1316 "TARGET_POWER"
1317 "{muls.|mullw.} %0,%1,%2"
1318 [(set_attr "type" "delayed_compare")])
1319
1320 (define_insn ""
1321 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1322 (compare:CC (mult:SI (match_operand:SI 1 "gpc_reg_operand" "%r")
1323 (match_operand:SI 2 "gpc_reg_operand" "r"))
1324 (const_int 0)))
1325 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1326 (mult:SI (match_dup 1) (match_dup 2)))]
1327 "! TARGET_POWER"
1328 "{muls.|mullw.} %0,%1,%2"
1329 [(set_attr "type" "delayed_compare")])
1330
1331 ;; Operand 1 is divided by operand 2; quotient goes to operand
1332 ;; 0 and remainder to operand 3.
1333 ;; ??? At some point, see what, if anything, we can do about if (x % y == 0).
1334
1335 (define_expand "divmodsi4"
1336 [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "")
1337 (div:SI (match_operand:SI 1 "gpc_reg_operand" "")
1338 (match_operand:SI 2 "gpc_reg_operand" "")))
1339 (set (match_operand:SI 3 "gpc_reg_operand" "")
1340 (mod:SI (match_dup 1) (match_dup 2)))])]
1341 "TARGET_POWER || (! TARGET_POWER && ! TARGET_POWERPC)"
1342 "
1343 {
1344 if (! TARGET_POWER && ! TARGET_POWERPC)
1345 {
1346 emit_move_insn (gen_rtx (REG, SImode, 3), operands[1]);
1347 emit_move_insn (gen_rtx (REG, SImode, 4), operands[2]);
1348 emit_insn (gen_divss_call ());
1349 emit_move_insn (operands[0], gen_rtx (REG, SImode, 3));
1350 emit_move_insn (operands[3], gen_rtx (REG, SImode, 4));
1351 DONE;
1352 }
1353 }")
1354
1355 (define_insn ""
1356 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1357 (div:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1358 (match_operand:SI 2 "gpc_reg_operand" "r")))
1359 (set (match_operand:SI 3 "gpc_reg_operand" "=q")
1360 (mod:SI (match_dup 1) (match_dup 2)))]
1361 "TARGET_POWER"
1362 "divs %0,%1,%2"
1363 [(set_attr "type" "idiv")])
1364
1365 (define_insn ""
1366 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1367 (div:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1368 (match_operand:SI 2 "gpc_reg_operand" "r")))]
1369 "TARGET_POWERPC"
1370 "divw %0,%1,%2"
1371 [(set_attr "type" "idiv")])
1372
1373 (define_expand "udivsi3"
1374 [(set (match_operand:SI 0 "gpc_reg_operand" "")
1375 (udiv:SI (match_operand:SI 1 "gpc_reg_operand" "")
1376 (match_operand:SI 2 "gpc_reg_operand" "")))]
1377 "TARGET_POWERPC || (! TARGET_POWER && ! TARGET_POWERPC)"
1378 "
1379 {
1380 if (! TARGET_POWER && ! TARGET_POWERPC)
1381 {
1382 emit_move_insn (gen_rtx (REG, SImode, 3), operands[1]);
1383 emit_move_insn (gen_rtx (REG, SImode, 4), operands[2]);
1384 emit_insn (gen_quous_call ());
1385 emit_move_insn (operands[0], gen_rtx (REG, SImode, 3));
1386 DONE;
1387 }
1388 }")
1389
1390 (define_insn ""
1391 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1392 (udiv:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1393 (match_operand:SI 2 "gpc_reg_operand" "r")))]
1394 "TARGET_POWERPC"
1395 "divwu %0,%1,%2"
1396 [(set_attr "type" "idiv")])
1397
1398 ;; For powers of two we can do srai/aze for divide and then adjust for
1399 ;; modulus. If it isn't a power of two, FAIL on POWER so divmodsi4 will be
1400 ;; used; for PowerPC, force operands into register and do a normal divide;
1401 ;; for AIX common-mode, use quoss call on register operands.
1402 (define_expand "divsi3"
1403 [(set (match_operand:SI 0 "gpc_reg_operand" "")
1404 (div:SI (match_operand:SI 1 "gpc_reg_operand" "")
1405 (match_operand:SI 2 "reg_or_cint_operand" "")))]
1406 ""
1407 "
1408 {
1409 if (GET_CODE (operands[2]) == CONST_INT
1410 && exact_log2 (INTVAL (operands[2])) >= 0)
1411 ;
1412 else if (TARGET_POWERPC)
1413 operands[2] = force_reg (SImode, operands[2]);
1414 else if (TARGET_POWER)
1415 FAIL;
1416 else
1417 {
1418 emit_move_insn (gen_rtx (REG, SImode, 3), operands[1]);
1419 emit_move_insn (gen_rtx (REG, SImode, 4), operands[2]);
1420 emit_insn (gen_quoss_call ());
1421 emit_move_insn (operands[0], gen_rtx (REG, SImode, 3));
1422 DONE;
1423 }
1424 }")
1425
1426 (define_expand "modsi3"
1427 [(use (match_operand:SI 0 "gpc_reg_operand" ""))
1428 (use (match_operand:SI 1 "gpc_reg_operand" ""))
1429 (use (match_operand:SI 2 "reg_or_cint_operand" ""))]
1430 ""
1431 "
1432 {
1433 int i = exact_log2 (INTVAL (operands[2]));
1434 rtx temp1;
1435 rtx temp2;
1436
1437 if (GET_CODE (operands[2]) != CONST_INT || i < 0)
1438 FAIL;
1439
1440 temp1 = gen_reg_rtx (SImode);
1441 temp2 = gen_reg_rtx (SImode);
1442
1443 emit_insn (gen_divsi3 (temp1, operands[1], operands[2]));
1444 emit_insn (gen_ashlsi3 (temp2, temp1, GEN_INT (i)));
1445 emit_insn (gen_subsi3 (operands[0], operands[1], temp2));
1446 DONE;
1447 }")
1448
1449 (define_insn ""
1450 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1451 (div:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1452 (match_operand:SI 2 "const_int_operand" "N")))]
1453 "exact_log2 (INTVAL (operands[2])) >= 0"
1454 "{srai|srawi} %0,%1,%p2\;{aze|addze} %0,%0"
1455 [(set_attr "length" "8")])
1456
1457 (define_insn ""
1458 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
1459 (compare:CC (div:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1460 (match_operand:SI 2 "const_int_operand" "N"))
1461 (const_int 0)))
1462 (clobber (match_scratch:SI 3 "=r"))]
1463 "exact_log2 (INTVAL (operands[2])) >= 0"
1464 "{srai|srawi} %3,%1,%p2\;{aze.|addze.} %3,%3"
1465 [(set_attr "type" "compare")
1466 (set_attr "length" "8")])
1467
1468 (define_insn ""
1469 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1470 (compare:CC (div:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1471 (match_operand:SI 2 "const_int_operand" "N"))
1472 (const_int 0)))
1473 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1474 (div:SI (match_dup 1) (match_dup 2)))]
1475 "exact_log2 (INTVAL (operands[2])) >= 0"
1476 "{srai|srawi} %0,%1,%p2\;{aze.|addze.} %0,%0"
1477 [(set_attr "type" "compare")
1478 (set_attr "length" "8")])
1479
1480 (define_insn ""
1481 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1482 (udiv:SI
1483 (plus:DI (ashift:DI
1484 (zero_extend:DI (match_operand:SI 1 "gpc_reg_operand" "r"))
1485 (const_int 32))
1486 (zero_extend:DI (match_operand:SI 4 "register_operand" "2")))
1487 (match_operand:SI 3 "gpc_reg_operand" "r")))
1488 (set (match_operand:SI 2 "register_operand" "=*q")
1489 (umod:SI
1490 (plus:DI (ashift:DI
1491 (zero_extend:DI (match_dup 1)) (const_int 32))
1492 (zero_extend:DI (match_dup 4)))
1493 (match_dup 3)))]
1494 "TARGET_POWER"
1495 "div %0,%1,%3"
1496 [(set_attr "type" "idiv")])
1497
1498 ;; To do unsigned divide we handle the cases of the divisor looking like a
1499 ;; negative number. If it is a constant that is less than 2**31, we don't
1500 ;; have to worry about the branches. So make a few subroutines here.
1501 ;;
1502 ;; First comes the normal case.
1503 (define_expand "udivmodsi4_normal"
1504 [(set (match_dup 4) (const_int 0))
1505 (parallel [(set (match_operand:SI 0 "" "")
1506 (udiv:SI (plus:DI (ashift:DI (zero_extend:DI (match_dup 4))
1507 (const_int 32))
1508 (zero_extend:DI (match_operand:SI 1 "" "")))
1509 (match_operand:SI 2 "" "")))
1510 (set (match_operand:SI 3 "" "")
1511 (umod:SI (plus:DI (ashift:DI (zero_extend:DI (match_dup 4))
1512 (const_int 32))
1513 (zero_extend:DI (match_dup 1)))
1514 (match_dup 2)))])]
1515 "TARGET_POWER"
1516 "
1517 { operands[4] = gen_reg_rtx (SImode); }")
1518
1519 ;; This handles the branches.
1520 (define_expand "udivmodsi4_tests"
1521 [(set (match_operand:SI 0 "" "") (const_int 0))
1522 (set (match_operand:SI 3 "" "") (match_operand:SI 1 "" ""))
1523 (set (match_dup 5) (compare:CCUNS (match_dup 1) (match_operand:SI 2 "" "")))
1524 (set (pc) (if_then_else (ltu (match_dup 5) (const_int 0))
1525 (label_ref (match_operand:SI 4 "" "")) (pc)))
1526 (set (match_dup 0) (const_int 1))
1527 (set (match_dup 3) (minus:SI (match_dup 1) (match_dup 2)))
1528 (set (match_dup 6) (compare:CC (match_dup 2) (const_int 0)))
1529 (set (pc) (if_then_else (lt (match_dup 6) (const_int 0))
1530 (label_ref (match_dup 4)) (pc)))]
1531 "TARGET_POWER"
1532 "
1533 { operands[5] = gen_reg_rtx (CCUNSmode);
1534 operands[6] = gen_reg_rtx (CCmode);
1535 }")
1536
1537 (define_expand "udivmodsi4"
1538 [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "")
1539 (udiv:SI (match_operand:SI 1 "gpc_reg_operand" "")
1540 (match_operand:SI 2 "reg_or_cint_operand" "")))
1541 (set (match_operand:SI 3 "gpc_reg_operand" "")
1542 (umod:SI (match_dup 1) (match_dup 2)))])]
1543 ""
1544 "
1545 {
1546 rtx label = 0;
1547
1548 if (! TARGET_POWER)
1549 if (! TARGET_POWERPC)
1550 {
1551 emit_move_insn (gen_rtx (REG, SImode, 3), operands[1]);
1552 emit_move_insn (gen_rtx (REG, SImode, 4), operands[2]);
1553 emit_insn (gen_divus_call ());
1554 emit_move_insn (operands[0], gen_rtx (REG, SImode, 3));
1555 emit_move_insn (operands[3], gen_rtx (REG, SImode, 4));
1556 DONE;
1557 }
1558 else
1559 FAIL;
1560
1561 if (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) < 0)
1562 {
1563 operands[2] = force_reg (SImode, operands[2]);
1564 label = gen_label_rtx ();
1565 emit (gen_udivmodsi4_tests (operands[0], operands[1], operands[2],
1566 operands[3], label));
1567 }
1568 else
1569 operands[2] = force_reg (SImode, operands[2]);
1570
1571 emit (gen_udivmodsi4_normal (operands[0], operands[1], operands[2],
1572 operands[3]));
1573 if (label)
1574 emit_label (label);
1575
1576 DONE;
1577 }")
1578
1579 ;; AIX architecture-independent common-mode multiply (DImode),
1580 ;; divide/modulus, and quotient subroutine calls. Input operands in R3 and
1581 ;; R4; results in R3 and sometimes R4; link register always clobbered by bla
1582 ;; instruction; R0 sometimes clobbered; also, MQ sometimes clobbered but
1583 ;; assumed unused if generating common-mode, so ignore.
1584 (define_insn "mulh_call"
1585 [(set (reg:SI 3)
1586 (truncate:SI
1587 (lshiftrt:DI (mult:DI (sign_extend:DI (reg:SI 3))
1588 (sign_extend:DI (reg:SI 4)))
1589 (const_int 32))))
1590 (clobber (match_scratch:SI 0 "=l"))]
1591 "! TARGET_POWER && ! TARGET_POWERPC"
1592 "bla __mulh"
1593 [(set_attr "type" "imul")])
1594
1595 (define_insn "mull_call"
1596 [(set (reg:DI 3)
1597 (mult:DI (sign_extend:DI (reg:SI 3))
1598 (sign_extend:DI (reg:SI 4))))
1599 (clobber (match_scratch:SI 0 "=l"))
1600 (clobber (reg:SI 0))]
1601 "! TARGET_POWER && ! TARGET_POWERPC"
1602 "bla __mull"
1603 [(set_attr "type" "imul")])
1604
1605 (define_insn "divss_call"
1606 [(set (reg:SI 3)
1607 (div:SI (reg:SI 3) (reg:SI 4)))
1608 (set (reg:SI 4)
1609 (mod:SI (reg:SI 3) (reg:SI 4)))
1610 (clobber (match_scratch:SI 0 "=l"))
1611 (clobber (reg:SI 0))]
1612 "! TARGET_POWER && ! TARGET_POWERPC"
1613 "bla __divss"
1614 [(set_attr "type" "idiv")])
1615
1616 (define_insn "divus_call"
1617 [(set (reg:SI 3)
1618 (udiv:SI (reg:SI 3) (reg:SI 4)))
1619 (set (reg:SI 4)
1620 (umod:SI (reg:SI 3) (reg:SI 4)))
1621 (clobber (match_scratch:SI 0 "=l"))
1622 (clobber (reg:SI 0))
1623 (clobber (match_scratch:CC 1 "=x"))
1624 (clobber (reg:CC 69))]
1625 "! TARGET_POWER && ! TARGET_POWERPC"
1626 "bla __divus"
1627 [(set_attr "type" "idiv")])
1628
1629 (define_insn "quoss_call"
1630 [(set (reg:SI 3)
1631 (div:SI (reg:SI 3) (reg:SI 4)))
1632 (clobber (match_scratch:SI 0 "=l"))]
1633 "! TARGET_POWER && ! TARGET_POWERPC"
1634 "bla __quoss"
1635 [(set_attr "type" "idiv")])
1636
1637 (define_insn "quous_call"
1638 [(set (reg:SI 3)
1639 (udiv:SI (reg:SI 3) (reg:SI 4)))
1640 (clobber (match_scratch:SI 0 "=l"))
1641 (clobber (reg:SI 0))
1642 (clobber (match_scratch:CC 1 "=x"))
1643 (clobber (reg:CC 69))]
1644 "! TARGET_POWER && ! TARGET_POWERPC"
1645 "bla __quous"
1646 [(set_attr "type" "idiv")])
1647 \f
1648 (define_insn "andsi3"
1649 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r")
1650 (and:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r")
1651 (match_operand:SI 2 "and_operand" "?r,L,K,J")))
1652 (clobber (match_scratch:CC 3 "=X,X,x,x"))]
1653 ""
1654 "@
1655 and %0,%1,%2
1656 {rlinm|rlwinm} %0,%1,0,%m2,%M2
1657 {andil.|andi.} %0,%1,%b2
1658 {andiu.|andis.} %0,%1,%u2")
1659
1660 (define_insn ""
1661 [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,x,x")
1662 (compare:CC (and:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r")
1663 (match_operand:SI 2 "and_operand" "r,K,J,L"))
1664 (const_int 0)))
1665 (clobber (match_scratch:SI 3 "=r,r,r,r"))]
1666 ""
1667 "@
1668 and. %3,%1,%2
1669 {andil.|andi.} %3,%1,%b2
1670 {andiu.|andis.} %3,%1,%u2
1671 {rlinm.|rlwinm.} %3,%1,0,%m2,%M2"
1672 [(set_attr "type" "compare,compare,compare,delayed_compare")])
1673
1674 (define_insn ""
1675 [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,x,x")
1676 (compare:CC (and:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r")
1677 (match_operand:SI 2 "and_operand" "r,K,J,L"))
1678 (const_int 0)))
1679 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r")
1680 (and:SI (match_dup 1) (match_dup 2)))]
1681 ""
1682 "@
1683 and. %0,%1,%2
1684 {andil.|andi.} %0,%1,%b2
1685 {andiu.|andis.} %0,%1,%u2
1686 {rlinm.|rlwinm.} %0,%1,0,%m2,%M2"
1687 [(set_attr "type" "compare,compare,compare,delayed_compare")])
1688
1689 ;; Take a AND with a constant that cannot be done in a single insn and try to
1690 ;; split it into two insns. This does not verify that the insns are valid
1691 ;; since this need not be done as combine will do it.
1692
1693 (define_split
1694 [(set (match_operand:SI 0 "gpc_reg_operand" "")
1695 (and:SI (match_operand:SI 1 "gpc_reg_operand" "")
1696 (match_operand:SI 2 "non_and_cint_operand" "")))]
1697 ""
1698 [(set (match_dup 0) (and:SI (match_dup 1) (match_dup 3)))
1699 (set (match_dup 0) (and:SI (match_dup 0) (match_dup 4)))]
1700 "
1701 {
1702 int maskval = INTVAL (operands[2]);
1703 int i, transitions, last_bit_value;
1704 int orig = maskval, first_c = maskval, second_c;
1705
1706 /* We know that MASKVAL must have more than 2 bit-transitions. Start at
1707 the low-order bit and count for the third transition. When we get there,
1708 make a first mask that has everything to the left of that position
1709 a one. Then make the second mask to turn off whatever else is needed. */
1710
1711 for (i = 1, transitions = 0, last_bit_value = maskval & 1; i < 32; i++)
1712 {
1713 if (((maskval >>= 1) & 1) != last_bit_value)
1714 last_bit_value ^= 1, transitions++;
1715
1716 if (transitions > 2)
1717 {
1718 first_c |= (~0) << i;
1719 break;
1720 }
1721 }
1722
1723 second_c = orig | ~ first_c;
1724
1725 operands[3] = gen_rtx (CONST_INT, VOIDmode, first_c);
1726 operands[4] = gen_rtx (CONST_INT, VOIDmode, second_c);
1727 }")
1728
1729 (define_insn "iorsi3"
1730 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r")
1731 (ior:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r")
1732 (match_operand:SI 2 "logical_operand" "r,K,J")))]
1733 ""
1734 "@
1735 or %0,%1,%2
1736 {oril|ori} %0,%1,%b2
1737 {oriu|oris} %0,%1,%u2")
1738
1739 (define_insn ""
1740 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
1741 (compare:CC (ior:SI (match_operand:SI 1 "gpc_reg_operand" "%r")
1742 (match_operand:SI 2 "gpc_reg_operand" "r"))
1743 (const_int 0)))
1744 (clobber (match_scratch:SI 3 "=r"))]
1745 ""
1746 "or. %3,%1,%2"
1747 [(set_attr "type" "compare")])
1748
1749 (define_insn ""
1750 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1751 (compare:CC (ior:SI (match_operand:SI 1 "gpc_reg_operand" "%r")
1752 (match_operand:SI 2 "gpc_reg_operand" "r"))
1753 (const_int 0)))
1754 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1755 (ior:SI (match_dup 1) (match_dup 2)))]
1756 ""
1757 "or. %0,%1,%2"
1758 [(set_attr "type" "compare")])
1759
1760 ;; Split an IOR that we can't do in one insn into two insns, each of which
1761 ;; does one 16-bit part. This is used by combine.
1762
1763 (define_split
1764 [(set (match_operand:SI 0 "gpc_reg_operand" "")
1765 (ior:SI (match_operand:SI 1 "gpc_reg_operand" "")
1766 (match_operand:SI 2 "non_logical_cint_operand" "")))]
1767 ""
1768 [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 3)))
1769 (set (match_dup 0) (ior:SI (match_dup 0) (match_dup 4)))]
1770 "
1771 {
1772 operands[3] = gen_rtx (CONST_INT, VOIDmode,
1773 INTVAL (operands[2]) & 0xffff0000);
1774 operands[4] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) & 0xffff);
1775 }")
1776
1777 (define_insn "xorsi3"
1778 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r")
1779 (xor:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r")
1780 (match_operand:SI 2 "logical_operand" "r,K,J")))]
1781 ""
1782 "@
1783 xor %0,%1,%2
1784 {xoril|xori} %0,%1,%b2
1785 {xoriu|xoris} %0,%1,%u2")
1786
1787 (define_insn ""
1788 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
1789 (compare:CC (xor:SI (match_operand:SI 1 "gpc_reg_operand" "%r")
1790 (match_operand:SI 2 "gpc_reg_operand" "r"))
1791 (const_int 0)))
1792 (clobber (match_scratch:SI 3 "=r"))]
1793 ""
1794 "xor. %3,%1,%2"
1795 [(set_attr "type" "compare")])
1796
1797 (define_insn ""
1798 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1799 (compare:CC (xor:SI (match_operand:SI 1 "gpc_reg_operand" "%r")
1800 (match_operand:SI 2 "gpc_reg_operand" "r"))
1801 (const_int 0)))
1802 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1803 (xor:SI (match_dup 1) (match_dup 2)))]
1804 ""
1805 "xor. %0,%1,%2"
1806 [(set_attr "type" "compare")])
1807
1808 ;; Split an XOR that we can't do in one insn into two insns, each of which
1809 ;; does one 16-bit part. This is used by combine.
1810
1811 (define_split
1812 [(set (match_operand:SI 0 "gpc_reg_operand" "")
1813 (xor:SI (match_operand:SI 1 "gpc_reg_operand" "")
1814 (match_operand:SI 2 "non_logical_cint_operand" "")))]
1815 ""
1816 [(set (match_dup 0) (xor:SI (match_dup 1) (match_dup 3)))
1817 (set (match_dup 0) (xor:SI (match_dup 0) (match_dup 4)))]
1818 "
1819 {
1820 operands[3] = gen_rtx (CONST_INT, VOIDmode,
1821 INTVAL (operands[2]) & 0xffff0000);
1822 operands[4] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) & 0xffff);
1823 }")
1824
1825 (define_insn ""
1826 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1827 (not:SI (xor:SI (match_operand:SI 1 "gpc_reg_operand" "%r")
1828 (match_operand:SI 2 "gpc_reg_operand" "r"))))]
1829 ""
1830 "eqv %0,%1,%2")
1831
1832 (define_insn ""
1833 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
1834 (compare:CC (not:SI (xor:SI (match_operand:SI 1 "gpc_reg_operand" "%r")
1835 (match_operand:SI 2 "gpc_reg_operand" "r")))
1836 (const_int 0)))
1837 (clobber (match_scratch:SI 3 "=r"))]
1838 ""
1839 "eqv. %3,%1,%2"
1840 [(set_attr "type" "compare")])
1841
1842 (define_insn ""
1843 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1844 (compare:CC (not:SI (xor:SI (match_operand:SI 1 "gpc_reg_operand" "%r")
1845 (match_operand:SI 2 "gpc_reg_operand" "r")))
1846 (const_int 0)))
1847 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1848 (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
1849 ""
1850 "eqv. %0,%1,%2"
1851 [(set_attr "type" "compare")])
1852
1853 (define_insn ""
1854 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1855 (and:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "r"))
1856 (match_operand:SI 2 "gpc_reg_operand" "r")))]
1857 ""
1858 "andc %0,%2,%1")
1859
1860 (define_insn ""
1861 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
1862 (compare:CC (and:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "r"))
1863 (match_operand:SI 2 "gpc_reg_operand" "r"))
1864 (const_int 0)))
1865 (clobber (match_scratch:SI 3 "=r"))]
1866 ""
1867 "andc. %3,%2,%1"
1868 [(set_attr "type" "compare")])
1869
1870 (define_insn ""
1871 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1872 (compare:CC (and:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "r"))
1873 (match_operand:SI 2 "gpc_reg_operand" "r"))
1874 (const_int 0)))
1875 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1876 (and:SI (not:SI (match_dup 1)) (match_dup 2)))]
1877 ""
1878 "andc. %0,%2,%1"
1879 [(set_attr "type" "compare")])
1880
1881 (define_insn ""
1882 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1883 (ior:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "r"))
1884 (match_operand:SI 2 "gpc_reg_operand" "r")))]
1885 ""
1886 "orc %0,%2,%1")
1887
1888 (define_insn ""
1889 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
1890 (compare:CC (ior:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "r"))
1891 (match_operand:SI 2 "gpc_reg_operand" "r"))
1892 (const_int 0)))
1893 (clobber (match_scratch:SI 3 "=r"))]
1894 ""
1895 "orc. %3,%2,%1"
1896 [(set_attr "type" "compare")])
1897
1898 (define_insn ""
1899 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1900 (compare:CC (ior:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "r"))
1901 (match_operand:SI 2 "gpc_reg_operand" "r"))
1902 (const_int 0)))
1903 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1904 (ior:SI (not:SI (match_dup 1)) (match_dup 2)))]
1905 ""
1906 "orc. %0,%2,%1"
1907 [(set_attr "type" "compare")])
1908
1909 (define_insn ""
1910 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1911 (ior:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "%r"))
1912 (not:SI (match_operand:SI 2 "gpc_reg_operand" "r"))))]
1913 ""
1914 "nand %0,%1,%2")
1915
1916 (define_insn ""
1917 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
1918 (compare:CC (ior:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "%r"))
1919 (not:SI (match_operand:SI 2 "gpc_reg_operand" "r")))
1920 (const_int 0)))
1921 (clobber (match_scratch:SI 3 "=r"))]
1922 ""
1923 "nand. %3,%1,%2"
1924 [(set_attr "type" "compare")])
1925
1926 (define_insn ""
1927 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1928 (compare:CC (ior:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "%r"))
1929 (not:SI (match_operand:SI 2 "gpc_reg_operand" "r")))
1930 (const_int 0)))
1931 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1932 (ior:SI (not:SI (match_dup 1)) (not:SI (match_dup 2))))]
1933 ""
1934 "nand. %0,%1,%2"
1935 [(set_attr "type" "compare")])
1936
1937 (define_insn ""
1938 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1939 (and:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "%r"))
1940 (not:SI (match_operand:SI 2 "gpc_reg_operand" "r"))))]
1941 ""
1942 "nor %0,%1,%2")
1943
1944 (define_insn ""
1945 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
1946 (compare:CC (and:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "%r"))
1947 (not:SI (match_operand:SI 2 "gpc_reg_operand" "r")))
1948 (const_int 0)))
1949 (clobber (match_scratch:SI 3 "=r"))]
1950 ""
1951 "nor. %3,%1,%2"
1952 [(set_attr "type" "compare")])
1953
1954 (define_insn ""
1955 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1956 (compare:CC (and:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "%r"))
1957 (not:SI (match_operand:SI 2 "gpc_reg_operand" "r")))
1958 (const_int 0)))
1959 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1960 (and:SI (not:SI (match_dup 1)) (not:SI (match_dup 2))))]
1961 ""
1962 "nor. %0,%1,%2"
1963 [(set_attr "type" "compare")])
1964
1965 ;; maskir insn. We need four forms because things might be in arbitrary
1966 ;; orders. Don't define forms that only set CR fields because these
1967 ;; would modify an input register.
1968
1969 (define_insn ""
1970 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1971 (ior:SI (and:SI (not:SI (match_operand:SI 2 "gpc_reg_operand" "r"))
1972 (match_operand:SI 1 "gpc_reg_operand" "0"))
1973 (and:SI (match_dup 2)
1974 (match_operand:SI 3 "gpc_reg_operand" "r"))))]
1975 "TARGET_POWER"
1976 "maskir %0,%3,%2")
1977
1978 (define_insn ""
1979 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1980 (ior:SI (and:SI (not:SI (match_operand:SI 2 "gpc_reg_operand" "r"))
1981 (match_operand:SI 1 "gpc_reg_operand" "0"))
1982 (and:SI (match_operand:SI 3 "gpc_reg_operand" "r")
1983 (match_dup 2))))]
1984 "TARGET_POWER"
1985 "maskir %0,%3,%2")
1986
1987 (define_insn ""
1988 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1989 (ior:SI (and:SI (match_operand:SI 2 "gpc_reg_operand" "r")
1990 (match_operand:SI 3 "gpc_reg_operand" "r"))
1991 (and:SI (not:SI (match_dup 2))
1992 (match_operand:SI 1 "gpc_reg_operand" "0"))))]
1993 "TARGET_POWER"
1994 "maskir %0,%3,%2")
1995
1996 (define_insn ""
1997 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1998 (ior:SI (and:SI (match_operand:SI 3 "gpc_reg_operand" "r")
1999 (match_operand:SI 2 "gpc_reg_operand" "r"))
2000 (and:SI (not:SI (match_dup 2))
2001 (match_operand:SI 1 "gpc_reg_operand" "0"))))]
2002 "TARGET_POWER"
2003 "maskir %0,%3,%2")
2004
2005 (define_insn ""
2006 [(set (match_operand:CC 4 "cc_reg_operand" "=x")
2007 (compare:CC
2008 (ior:SI (and:SI (not:SI (match_operand:SI 2 "gpc_reg_operand" "r"))
2009 (match_operand:SI 1 "gpc_reg_operand" "0"))
2010 (and:SI (match_dup 2)
2011 (match_operand:SI 3 "gpc_reg_operand" "r")))
2012 (const_int 0)))
2013 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
2014 (ior:SI (and:SI (not:SI (match_dup 2)) (match_dup 1))
2015 (and:SI (match_dup 2) (match_dup 3))))]
2016 "TARGET_POWER"
2017 "maskir. %0,%3,%2"
2018 [(set_attr "type" "compare")])
2019
2020 (define_insn ""
2021 [(set (match_operand:CC 4 "cc_reg_operand" "=x")
2022 (compare:CC
2023 (ior:SI (and:SI (not:SI (match_operand:SI 2 "gpc_reg_operand" "r"))
2024 (match_operand:SI 1 "gpc_reg_operand" "0"))
2025 (and:SI (match_operand:SI 3 "gpc_reg_operand" "r")
2026 (match_dup 2)))
2027 (const_int 0)))
2028 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
2029 (ior:SI (and:SI (not:SI (match_dup 2)) (match_dup 1))
2030 (and:SI (match_dup 3) (match_dup 2))))]
2031 "TARGET_POWER"
2032 "maskir. %0,%3,%2"
2033 [(set_attr "type" "compare")])
2034
2035 (define_insn ""
2036 [(set (match_operand:CC 4 "cc_reg_operand" "=x")
2037 (compare:CC
2038 (ior:SI (and:SI (match_operand:SI 2 "gpc_reg_operand" "r")
2039 (match_operand:SI 3 "gpc_reg_operand" "r"))
2040 (and:SI (not:SI (match_dup 2))
2041 (match_operand:SI 1 "gpc_reg_operand" "0")))
2042 (const_int 0)))
2043 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
2044 (ior:SI (and:SI (match_dup 2) (match_dup 3))
2045 (and:SI (not:SI (match_dup 2)) (match_dup 1))))]
2046 "TARGET_POWER"
2047 "maskir. %0,%3,%2"
2048 [(set_attr "type" "compare")])
2049
2050 (define_insn ""
2051 [(set (match_operand:CC 4 "cc_reg_operand" "=x")
2052 (compare:CC
2053 (ior:SI (and:SI (match_operand:SI 3 "gpc_reg_operand" "r")
2054 (match_operand:SI 2 "gpc_reg_operand" "r"))
2055 (and:SI (not:SI (match_dup 2))
2056 (match_operand:SI 1 "gpc_reg_operand" "0")))
2057 (const_int 0)))
2058 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
2059 (ior:SI (and:SI (match_dup 3) (match_dup 2))
2060 (and:SI (not:SI (match_dup 2)) (match_dup 1))))]
2061 "TARGET_POWER"
2062 "maskir. %0,%3,%2"
2063 [(set_attr "type" "compare")])
2064 \f
2065 ;; Rotate and shift insns, in all their variants. These support shifts,
2066 ;; field inserts and extracts, and various combinations thereof.
2067 (define_expand "insv"
2068 [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r")
2069 (match_operand:SI 1 "const_int_operand" "i")
2070 (match_operand:SI 2 "const_int_operand" "i"))
2071 (match_operand:SI 3 "gpc_reg_operand" "r"))]
2072 ""
2073 "
2074 {
2075 /* Do not handle 16/8 bit structures that fit in HI/QI modes directly, since
2076 the (SUBREG:SI (REG:HI xxx)) that is otherwise generated can confuse the
2077 compiler if the address of the structure is taken later. */
2078 if (GET_CODE (operands[0]) == SUBREG
2079 && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (operands[0]))) < UNITS_PER_WORD))
2080 FAIL;
2081 }")
2082
2083 (define_insn ""
2084 [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r")
2085 (match_operand:SI 1 "const_int_operand" "i")
2086 (match_operand:SI 2 "const_int_operand" "i"))
2087 (match_operand:SI 3 "gpc_reg_operand" "r"))]
2088 ""
2089 "*
2090 {
2091 int start = INTVAL (operands[2]) & 31;
2092 int size = INTVAL (operands[1]) & 31;
2093
2094 operands[4] = gen_rtx (CONST_INT, VOIDmode, 32 - start - size);
2095 operands[1] = gen_rtx (CONST_INT, VOIDmode, start + size - 1);
2096 return \"{rlimi|rlwimi} %0,%3,%h4,%h2,%h1\";
2097 }")
2098
2099 (define_insn ""
2100 [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r")
2101 (match_operand:SI 1 "const_int_operand" "i")
2102 (match_operand:SI 2 "const_int_operand" "i"))
2103 (ashift:SI (match_operand:SI 3 "gpc_reg_operand" "r")
2104 (match_operand:SI 4 "const_int_operand" "i")))]
2105 ""
2106 "*
2107 {
2108 int shift = INTVAL (operands[4]) & 31;
2109 int start = INTVAL (operands[2]) & 31;
2110 int size = INTVAL (operands[1]) & 31;
2111
2112 operands[4] = gen_rtx (CONST_INT, VOIDmode, shift - start - size);
2113 operands[1] = gen_rtx (CONST_INT, VOIDmode, start + size - 1);
2114 return \"{rlimi|rlwimi} %0,%3,%h4,%h2,%h1\";
2115 }")
2116
2117 (define_insn ""
2118 [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r")
2119 (match_operand:SI 1 "const_int_operand" "i")
2120 (match_operand:SI 2 "const_int_operand" "i"))
2121 (ashiftrt:SI (match_operand:SI 3 "gpc_reg_operand" "r")
2122 (match_operand:SI 4 "const_int_operand" "i")))]
2123 ""
2124 "*
2125 {
2126 int shift = INTVAL (operands[4]) & 31;
2127 int start = INTVAL (operands[2]) & 31;
2128 int size = INTVAL (operands[1]) & 31;
2129
2130 operands[4] = gen_rtx (CONST_INT, VOIDmode, 32 - shift - start - size);
2131 operands[1] = gen_rtx (CONST_INT, VOIDmode, start + size - 1);
2132 return \"{rlimi|rlwimi} %0,%3,%h4,%h2,%h1\";
2133 }")
2134
2135 (define_insn ""
2136 [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r")
2137 (match_operand:SI 1 "const_int_operand" "i")
2138 (match_operand:SI 2 "const_int_operand" "i"))
2139 (lshiftrt:SI (match_operand:SI 3 "gpc_reg_operand" "r")
2140 (match_operand:SI 4 "const_int_operand" "i")))]
2141 ""
2142 "*
2143 {
2144 int shift = INTVAL (operands[4]) & 31;
2145 int start = INTVAL (operands[2]) & 31;
2146 int size = INTVAL (operands[1]) & 31;
2147
2148 operands[4] = gen_rtx (CONST_INT, VOIDmode, 32 - shift - start - size);
2149 operands[1] = gen_rtx (CONST_INT, VOIDmode, start + size - 1);
2150 return \"{rlimi|rlwimi} %0,%3,%h4,%h2,%h1\";
2151 }")
2152
2153 (define_insn ""
2154 [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r")
2155 (match_operand:SI 1 "const_int_operand" "i")
2156 (match_operand:SI 2 "const_int_operand" "i"))
2157 (zero_extract:SI (match_operand:SI 3 "gpc_reg_operand" "r")
2158 (match_operand:SI 4 "const_int_operand" "i")
2159 (match_operand:SI 5 "const_int_operand" "i")))]
2160 "INTVAL (operands[4]) >= INTVAL (operands[1])"
2161 "*
2162 {
2163 int extract_start = INTVAL (operands[5]) & 31;
2164 int extract_size = INTVAL (operands[4]) & 31;
2165 int insert_start = INTVAL (operands[2]) & 31;
2166 int insert_size = INTVAL (operands[1]) & 31;
2167
2168 /* Align extract field with insert field */
2169 operands[5] = gen_rtx (CONST_INT, VOIDmode,
2170 extract_start + extract_size - insert_start - insert_size);
2171 operands[1] = gen_rtx (CONST_INT, VOIDmode, insert_start + insert_size - 1);
2172 return \"{rlimi|rlwimi} %0,%3,%h5,%h2,%h1\";
2173 }")
2174
2175 (define_insn ""
2176 [(set (zero_extract:DI (match_operand:DI 0 "gpc_reg_operand" "+r")
2177 (match_operand:DI 1 "const_int_operand" "i")
2178 (match_operand:DI 2 "const_int_operand" "i"))
2179 (match_operand:DI 3 "gpc_reg_operand" "r"))]
2180 "TARGET_POWERPC64"
2181 "*
2182 {
2183 int start = INTVAL (operands[2]) & 63;
2184 int size = INTVAL (operands[1]) & 63;
2185
2186 operands[2] = gen_rtx (CONST_INT, VOIDmode, 64 - start - size);
2187 return \"rldimi %0,%3,%H2,%H1\";
2188 }")
2189
2190 (define_expand "extzv"
2191 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2192 (zero_extract:SI (match_operand:SI 1 "gpc_reg_operand" "r")
2193 (match_operand:SI 2 "const_int_operand" "i")
2194 (match_operand:SI 3 "const_int_operand" "i")))]
2195 ""
2196 "
2197 {
2198 /* Do not handle 16/8 bit structures that fit in HI/QI modes directly, since
2199 the (SUBREG:SI (REG:HI xxx)) that is otherwise generated can confuse the
2200 compiler if the address of the structure is taken later. */
2201 if (GET_CODE (operands[0]) == SUBREG
2202 && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (operands[0]))) < UNITS_PER_WORD))
2203 FAIL;
2204 }")
2205
2206 (define_insn ""
2207 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2208 (zero_extract:SI (match_operand:SI 1 "gpc_reg_operand" "r")
2209 (match_operand:SI 2 "const_int_operand" "i")
2210 (match_operand:SI 3 "const_int_operand" "i")))]
2211 ""
2212 "*
2213 {
2214 int start = INTVAL (operands[3]) & 31;
2215 int size = INTVAL (operands[2]) & 31;
2216
2217 if (start + size >= 32)
2218 operands[3] = const0_rtx;
2219 else
2220 operands[3] = gen_rtx (CONST_INT, VOIDmode, start + size);
2221 return \"{rlinm|rlwinm} %0,%1,%3,%s2,31\";
2222 }")
2223
2224 (define_insn ""
2225 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
2226 (compare:CC (zero_extract:SI (match_operand:SI 1 "gpc_reg_operand" "r")
2227 (match_operand:SI 2 "const_int_operand" "i")
2228 (match_operand:SI 3 "const_int_operand" "i"))
2229 (const_int 0)))
2230 (clobber (match_scratch:SI 4 "=r"))]
2231 ""
2232 "*
2233 {
2234 int start = INTVAL (operands[3]) & 31;
2235 int size = INTVAL (operands[2]) & 31;
2236
2237 /* If the bitfield being tested fits in the upper or lower half of a
2238 word, it is possible to use andiu. or andil. to test it. This is
2239 useful because the condition register set-use delay is smaller for
2240 andi[ul]. than for rlinm. This doesn't work when the starting bit
2241 position is 0 because the LT and GT bits may be set wrong. */
2242
2243 if ((start > 0 && start + size <= 16) || start >= 16)
2244 {
2245 operands[3] = gen_rtx (CONST_INT, VOIDmode,
2246 ((1 << (16 - (start & 15)))
2247 - (1 << (16 - (start & 15) - size))));
2248 if (start < 16)
2249 return \"{andiu.|andis.} %4,%1,%3\";
2250 else
2251 return \"{andil.|andi.} %4,%1,%3\";
2252 }
2253
2254 if (start + size >= 32)
2255 operands[3] = const0_rtx;
2256 else
2257 operands[3] = gen_rtx (CONST_INT, VOIDmode, start + size);
2258 return \"{rlinm.|rlwinm.} %4,%1,%3,%s2,31\";
2259 }"
2260 [(set_attr "type" "compare")])
2261
2262 (define_insn ""
2263 [(set (match_operand:CC 4 "cc_reg_operand" "=x")
2264 (compare:CC (zero_extract:SI (match_operand:SI 1 "gpc_reg_operand" "r")
2265 (match_operand:SI 2 "const_int_operand" "i")
2266 (match_operand:SI 3 "const_int_operand" "i"))
2267 (const_int 0)))
2268 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
2269 (zero_extract:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
2270 ""
2271 "*
2272 {
2273 int start = INTVAL (operands[3]) & 31;
2274 int size = INTVAL (operands[2]) & 31;
2275
2276 if (start >= 16 && start + size == 32)
2277 {
2278 operands[3] = gen_rtx (CONST_INT, VOIDmode, (1 << (32 - start)) - 1);
2279 return \"{andil.|andi.} %0,%1,%3\";
2280 }
2281
2282 if (start + size >= 32)
2283 operands[3] = const0_rtx;
2284 else
2285 operands[3] = gen_rtx (CONST_INT, VOIDmode, start + size);
2286 return \"{rlinm.|rlwinm.} %0,%1,%3,%s2,31\";
2287 }"
2288 [(set_attr "type" "delayed_compare")])
2289
2290 (define_insn ""
2291 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2292 (zero_extract:DI (match_operand:DI 1 "gpc_reg_operand" "r")
2293 (match_operand:DI 2 "const_int_operand" "i")
2294 (match_operand:DI 3 "const_int_operand" "i")))]
2295 "TARGET_POWERPC64"
2296 "*
2297 {
2298 int start = INTVAL (operands[3]) & 63;
2299 int size = INTVAL (operands[2]) & 63;
2300
2301 if (start + size >= 64)
2302 operands[3] = const0_rtx;
2303 else
2304 operands[3] = gen_rtx (CONST_INT, VOIDmode, start + size);
2305 operands[2] = gen_rtx (CONST_INT, VOIDmode, 64 - size);
2306 return \"rldicl %0,%1,%3,%2\";
2307 }")
2308
2309 (define_insn ""
2310 [(set (match_operand:CC 0 "gpc_reg_operand" "=x")
2311 (compare:CC (zero_extract:DI (match_operand:DI 1 "gpc_reg_operand" "r")
2312 (match_operand:DI 2 "const_int_operand" "i")
2313 (match_operand:DI 3 "const_int_operand" "i"))
2314 (const_int 0)))
2315 (clobber (match_scratch:DI 4 "=r"))]
2316 "TARGET_POWERPC64"
2317 "*
2318 {
2319 int start = INTVAL (operands[3]) & 63;
2320 int size = INTVAL (operands[2]) & 63;
2321
2322 if (start + size >= 64)
2323 operands[3] = const0_rtx;
2324 else
2325 operands[3] = gen_rtx (CONST_INT, VOIDmode, start + size);
2326 operands[2] = gen_rtx (CONST_INT, VOIDmode, 64 - size);
2327 return \"rldicl. %4,%1,%3,%2\";
2328 }")
2329
2330 (define_insn ""
2331 [(set (match_operand:CC 4 "gpc_reg_operand" "=x")
2332 (compare:CC (zero_extract:DI (match_operand:DI 1 "gpc_reg_operand" "r")
2333 (match_operand:DI 2 "const_int_operand" "i")
2334 (match_operand:DI 3 "const_int_operand" "i"))
2335 (const_int 0)))
2336 (set (match_operand:DI 0 "gpc_reg_operand" "=r")
2337 (zero_extract:DI (match_dup 1) (match_dup 2) (match_dup 3)))]
2338 "TARGET_POWERPC64"
2339 "*
2340 {
2341 int start = INTVAL (operands[3]) & 63;
2342 int size = INTVAL (operands[2]) & 63;
2343
2344 if (start + size >= 64)
2345 operands[3] = const0_rtx;
2346 else
2347 operands[3] = gen_rtx (CONST_INT, VOIDmode, start + size);
2348 operands[2] = gen_rtx (CONST_INT, VOIDmode, 64 - size);
2349 return \"rldicl. %0,%1,%3,%2\";
2350 }")
2351
2352 (define_insn "rotlsi3"
2353 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2354 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
2355 (match_operand:SI 2 "reg_or_cint_operand" "ri")))]
2356 ""
2357 "{rl%I2nm|rlw%I2nm} %0,%1,%h2,0xffffffff")
2358
2359 (define_insn ""
2360 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
2361 (compare:CC (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
2362 (match_operand:SI 2 "reg_or_cint_operand" "ri"))
2363 (const_int 0)))
2364 (clobber (match_scratch:SI 3 "=r"))]
2365 ""
2366 "{rl%I2nm.|rlw%I2nm.} %3,%1,%h2,0xffffffff"
2367 [(set_attr "type" "delayed_compare")])
2368
2369 (define_insn ""
2370 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
2371 (compare:CC (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
2372 (match_operand:SI 2 "reg_or_cint_operand" "ri"))
2373 (const_int 0)))
2374 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
2375 (rotate:SI (match_dup 1) (match_dup 2)))]
2376 ""
2377 "{rl%I2nm.|rlw%I2nm.} %0,%1,%h2,0xffffffff"
2378 [(set_attr "type" "delayed_compare")])
2379
2380 (define_insn ""
2381 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2382 (and:SI (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
2383 (match_operand:SI 2 "reg_or_cint_operand" "ri"))
2384 (match_operand:SI 3 "mask_operand" "L")))]
2385 ""
2386 "{rl%I2nm|rlw%I2nm} %0,%1,%h2,%m3,%M3")
2387
2388 (define_insn ""
2389 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
2390 (compare:CC (and:SI
2391 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
2392 (match_operand:SI 2 "reg_or_cint_operand" "ri"))
2393 (match_operand:SI 3 "mask_operand" "L"))
2394 (const_int 0)))
2395 (clobber (match_scratch:SI 4 "=r"))]
2396 ""
2397 "{rl%I2nm.|rlw%I2nm.} %4,%1,%h2,%m3,%M3"
2398 [(set_attr "type" "delayed_compare")])
2399
2400 (define_insn ""
2401 [(set (match_operand:CC 4 "cc_reg_operand" "=x")
2402 (compare:CC (and:SI
2403 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
2404 (match_operand:SI 2 "reg_or_cint_operand" "ri"))
2405 (match_operand:SI 3 "mask_operand" "L"))
2406 (const_int 0)))
2407 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
2408 (and:SI (rotate:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
2409 ""
2410 "{rl%I2nm.|rlw%I2nm.} %0,%1,%h2,%m3,%M3"
2411 [(set_attr "type" "delayed_compare")])
2412
2413 (define_insn ""
2414 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2415 (zero_extend:SI
2416 (subreg:QI
2417 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
2418 (match_operand:SI 2 "reg_or_cint_operand" "ri")) 0)))]
2419 ""
2420 "{rl%I2nm|rlw%I2nm} %0,%1,%h2,0xff")
2421
2422 (define_insn ""
2423 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
2424 (compare:CC (zero_extend:SI
2425 (subreg:QI
2426 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
2427 (match_operand:SI 2 "reg_or_cint_operand" "ri")) 0))
2428 (const_int 0)))
2429 (clobber (match_scratch:SI 3 "=r"))]
2430 ""
2431 "{rl%I2nm.|rlw%I2nm.} %3,%1,%h2,0xff"
2432 [(set_attr "type" "delayed_compare")])
2433
2434 (define_insn ""
2435 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
2436 (compare:CC (zero_extend:SI
2437 (subreg:QI
2438 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
2439 (match_operand:SI 2 "reg_or_cint_operand" "ri")) 0))
2440 (const_int 0)))
2441 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
2442 (zero_extend:SI (subreg:QI (rotate:SI (match_dup 1) (match_dup 2)) 0)))]
2443 ""
2444 "{rl%I2nm.|rlw%I2nm.} %0,%1,%h2,0xff"
2445 [(set_attr "type" "delayed_compare")])
2446
2447 (define_insn ""
2448 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2449 (zero_extend:SI
2450 (subreg:HI
2451 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
2452 (match_operand:SI 2 "reg_or_cint_operand" "ri")) 0)))]
2453 ""
2454 "{rl%I2nm|rlw%I2nm} %0,%1,%h2,0xffff")
2455
2456 (define_insn ""
2457 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
2458 (compare:CC (zero_extend:SI
2459 (subreg:HI
2460 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
2461 (match_operand:SI 2 "reg_or_cint_operand" "ri")) 0))
2462 (const_int 0)))
2463 (clobber (match_scratch:SI 3 "=r"))]
2464 ""
2465 "{rl%I2nm.|rlw%I2nm.} %3,%1,%h2,0xffff"
2466 [(set_attr "type" "delayed_compare")])
2467
2468 (define_insn ""
2469 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
2470 (compare:CC (zero_extend:SI
2471 (subreg:HI
2472 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
2473 (match_operand:SI 2 "reg_or_cint_operand" "ri")) 0))
2474 (const_int 0)))
2475 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
2476 (zero_extend:SI (subreg:HI (rotate:SI (match_dup 1) (match_dup 2)) 0)))]
2477 ""
2478 "{rl%I2nm.|rlw%I2nm.} %0,%1,%h2,0xffff"
2479 [(set_attr "type" "delayed_compare")])
2480
2481 ;; Note that we use "sle." instead of "sl." so that we can set
2482 ;; SHIFT_COUNT_TRUNCATED.
2483
2484 (define_expand "ashlsi3"
2485 [(use (match_operand:SI 0 "gpc_reg_operand" ""))
2486 (use (match_operand:SI 1 "gpc_reg_operand" ""))
2487 (use (match_operand:SI 2 "reg_or_cint_operand" ""))]
2488 ""
2489 "
2490 {
2491 if (TARGET_POWER)
2492 emit_insn (gen_ashlsi3_power (operands[0], operands[1], operands[2]));
2493 else
2494 emit_insn (gen_ashlsi3_no_power (operands[0], operands[1], operands[2]));
2495 DONE;
2496 }")
2497
2498 (define_insn "ashlsi3_power"
2499 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
2500 (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
2501 (match_operand:SI 2 "reg_or_cint_operand" "r,i")))
2502 (clobber (match_scratch:SI 3 "=q,X"))]
2503 "TARGET_POWER"
2504 "@
2505 sle %0,%1,%2
2506 {sli|slwi} %0,%1,%h2"
2507 [(set_attr "length" "8")])
2508
2509 (define_insn "ashlsi3_no_power"
2510 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2511 (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r")
2512 (match_operand:SI 2 "reg_or_cint_operand" "ri")))]
2513 "! TARGET_POWER"
2514 "{sl|slw}%I2 %0,%1,%h2"
2515 [(set_attr "length" "8")])
2516
2517 (define_insn ""
2518 [(set (match_operand:CC 0 "cc_reg_operand" "=x,x")
2519 (compare:CC (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
2520 (match_operand:SI 2 "reg_or_cint_operand" "r,i"))
2521 (const_int 0)))
2522 (clobber (match_scratch:SI 3 "=r,r"))
2523 (clobber (match_scratch:SI 4 "=q,X"))]
2524 "TARGET_POWER"
2525 "@
2526 sle. %3,%1,%2
2527 {sli.|slwi.} %3,%1,%h2"
2528 [(set_attr "type" "delayed_compare")])
2529
2530 (define_insn ""
2531 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
2532 (compare:CC (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r")
2533 (match_operand:SI 2 "reg_or_cint_operand" "ri"))
2534 (const_int 0)))
2535 (clobber (match_scratch:SI 3 "=r"))]
2536 "! TARGET_POWER"
2537 "{sl|slw}%I2. %3,%1,%h2"
2538 [(set_attr "type" "delayed_compare")])
2539
2540 (define_insn ""
2541 [(set (match_operand:CC 3 "cc_reg_operand" "=x,x")
2542 (compare:CC (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
2543 (match_operand:SI 2 "reg_or_cint_operand" "r,i"))
2544 (const_int 0)))
2545 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
2546 (ashift:SI (match_dup 1) (match_dup 2)))
2547 (clobber (match_scratch:SI 4 "=q,X"))]
2548 "TARGET_POWER"
2549 "@
2550 sle. %0,%1,%2
2551 {sli.|slwi.} %0,%1,%h2"
2552 [(set_attr "type" "delayed_compare")])
2553
2554 (define_insn ""
2555 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
2556 (compare:CC (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r")
2557 (match_operand:SI 2 "reg_or_cint_operand" "ri"))
2558 (const_int 0)))
2559 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
2560 (ashift:SI (match_dup 1) (match_dup 2)))]
2561 "! TARGET_POWER"
2562 "{sl|slw}%I2. %0,%1,%h2"
2563 [(set_attr "type" "delayed_compare")])
2564
2565 (define_insn ""
2566 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2567 (and:SI (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r")
2568 (match_operand:SI 2 "const_int_operand" "i"))
2569 (match_operand:SI 3 "mask_operand" "L")))]
2570 "includes_lshift_p (operands[2], operands[3])"
2571 "{rlinm|rlwinm} %0,%1,%h2,%m3,%M3")
2572
2573 (define_insn ""
2574 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
2575 (compare:CC
2576 (and:SI (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r")
2577 (match_operand:SI 2 "const_int_operand" "i"))
2578 (match_operand:SI 3 "mask_operand" "L"))
2579 (const_int 0)))
2580 (clobber (match_scratch:SI 4 "=r"))]
2581 "includes_lshift_p (operands[2], operands[3])"
2582 "{rlinm.|rlwinm.} %4,%1,%h2,%m3,%M3"
2583 [(set_attr "type" "delayed_compare")])
2584
2585 (define_insn ""
2586 [(set (match_operand:CC 4 "cc_reg_operand" "=x")
2587 (compare:CC
2588 (and:SI (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r")
2589 (match_operand:SI 2 "const_int_operand" "i"))
2590 (match_operand:SI 3 "mask_operand" "L"))
2591 (const_int 0)))
2592 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
2593 (and:SI (ashift:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
2594 "includes_lshift_p (operands[2], operands[3])"
2595 "{rlinm.|rlwinm.} %0,%1,%h2,%m3,%M3"
2596 [(set_attr "type" "delayed_compare")])
2597
2598 ;; The AIX assembler mis-handles "sri x,x,0", so write that case as
2599 ;; "sli x,x,0".
2600 (define_expand "lshrsi3"
2601 [(use (match_operand:SI 0 "gpc_reg_operand" ""))
2602 (use (match_operand:SI 1 "gpc_reg_operand" ""))
2603 (use (match_operand:SI 2 "reg_or_cint_operand" ""))]
2604 ""
2605 "
2606 {
2607 if (TARGET_POWER)
2608 emit_insn (gen_lshrsi3_power (operands[0], operands[1], operands[2]));
2609 else
2610 emit_insn (gen_lshrsi3_no_power (operands[0], operands[1], operands[2]));
2611 DONE;
2612 }")
2613
2614 (define_insn "lshrsi3_power"
2615 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r")
2616 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r")
2617 (match_operand:SI 2 "reg_or_cint_operand" "r,O,i")))
2618 (clobber (match_scratch:SI 3 "=q,X,X"))]
2619 "TARGET_POWER"
2620 "@
2621 sre %0,%1,%2
2622 mr %0,%1
2623 {s%A2i|s%A2wi} %0,%1,%h2")
2624
2625 (define_insn "lshrsi3_no_power"
2626 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
2627 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
2628 (match_operand:SI 2 "reg_or_cint_operand" "O,ri")))]
2629 "! TARGET_POWER"
2630 "@
2631 mr %0,%1
2632 {sr|srw}%I2 %0,%1,%h2")
2633
2634 (define_insn ""
2635 [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,x")
2636 (compare:CC (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r")
2637 (match_operand:SI 2 "reg_or_cint_operand" "r,O,i"))
2638 (const_int 0)))
2639 (clobber (match_scratch:SI 3 "=r,X,r"))
2640 (clobber (match_scratch:SI 4 "=q,X,X"))]
2641 "TARGET_POWER"
2642 "@
2643 sre. %3,%1,%2
2644 mr. %1,%1
2645 {s%A2i.|s%A2wi.} %3,%1,%h2"
2646 [(set_attr "type" "delayed_compare")])
2647
2648 (define_insn ""
2649 [(set (match_operand:CC 0 "cc_reg_operand" "=x,x")
2650 (compare:CC (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
2651 (match_operand:SI 2 "reg_or_cint_operand" "O,ri"))
2652 (const_int 0)))
2653 (clobber (match_scratch:SI 3 "=X,r"))]
2654 "! TARGET_POWER"
2655 "@
2656 mr. %1,%1
2657 {sr|srw}%I2. %3,%1,%h2"
2658 [(set_attr "type" "delayed_compare")])
2659
2660 (define_insn ""
2661 [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,x")
2662 (compare:CC (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r")
2663 (match_operand:SI 2 "reg_or_cint_operand" "r,O,i"))
2664 (const_int 0)))
2665 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r")
2666 (lshiftrt:SI (match_dup 1) (match_dup 2)))
2667 (clobber (match_scratch:SI 4 "=q,X,X"))]
2668 "TARGET_POWER"
2669 "@
2670 sre. %0,%1,%2
2671 mr. %0,%1
2672 {s%A2i.|s%A2wi.} %0,%1,%h2"
2673 [(set_attr "type" "delayed_compare")])
2674
2675 (define_insn ""
2676 [(set (match_operand:CC 3 "cc_reg_operand" "=x,x")
2677 (compare:CC (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
2678 (match_operand:SI 2 "reg_or_cint_operand" "O,ri"))
2679 (const_int 0)))
2680 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
2681 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
2682 "! TARGET_POWER"
2683 "@
2684 mr. %0,%1
2685 {sr|srw}%I2. %0,%1,%h2"
2686 [(set_attr "type" "delayed_compare")])
2687
2688 (define_insn ""
2689 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2690 (and:SI (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
2691 (match_operand:SI 2 "const_int_operand" "i"))
2692 (match_operand:SI 3 "mask_operand" "L")))]
2693 "includes_rshift_p (operands[2], operands[3])"
2694 "{rlinm|rlwinm} %0,%1,%s2,%m3,%M3")
2695
2696 (define_insn ""
2697 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
2698 (compare:CC
2699 (and:SI (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
2700 (match_operand:SI 2 "const_int_operand" "i"))
2701 (match_operand:SI 3 "mask_operand" "L"))
2702 (const_int 0)))
2703 (clobber (match_scratch:SI 4 "=r"))]
2704 "includes_rshift_p (operands[2], operands[3])"
2705 "{rlinm.|rlwinm.} %4,%1,%s2,%m3,%M3"
2706 [(set_attr "type" "delayed_compare")])
2707
2708 (define_insn ""
2709 [(set (match_operand:CC 4 "cc_reg_operand" "=x")
2710 (compare:CC
2711 (and:SI (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
2712 (match_operand:SI 2 "const_int_operand" "i"))
2713 (match_operand:SI 3 "mask_operand" "L"))
2714 (const_int 0)))
2715 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
2716 (and:SI (lshiftrt:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
2717 "includes_rshift_p (operands[2], operands[3])"
2718 "{rlinm.|rlwinm.} %0,%1,%s2,%m3,%M3"
2719 [(set_attr "type" "delayed_compare")])
2720
2721 (define_insn ""
2722 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2723 (zero_extend:SI
2724 (subreg:QI
2725 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
2726 (match_operand:SI 2 "const_int_operand" "i")) 0)))]
2727 "includes_rshift_p (operands[2], gen_rtx (CONST_INT, VOIDmode, 255))"
2728 "{rlinm|rlwinm} %0,%1,%s2,0xff")
2729
2730 (define_insn ""
2731 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
2732 (compare:CC
2733 (zero_extend:SI
2734 (subreg:QI
2735 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
2736 (match_operand:SI 2 "const_int_operand" "i")) 0))
2737 (const_int 0)))
2738 (clobber (match_scratch:SI 3 "=r"))]
2739 "includes_rshift_p (operands[2], gen_rtx (CONST_INT, VOIDmode, 255))"
2740 "{rlinm.|rlwinm.} %3,%1,%s2,0xff"
2741 [(set_attr "type" "delayed_compare")])
2742
2743 (define_insn ""
2744 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
2745 (compare:CC
2746 (zero_extend:SI
2747 (subreg:QI
2748 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
2749 (match_operand:SI 2 "const_int_operand" "i")) 0))
2750 (const_int 0)))
2751 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
2752 (zero_extend:SI (subreg:QI (lshiftrt:SI (match_dup 1) (match_dup 2)) 0)))]
2753 "includes_rshift_p (operands[2], gen_rtx (CONST_INT, VOIDmode, 255))"
2754 "{rlinm.|rlwinm.} %0,%1,%s2,0xff"
2755 [(set_attr "type" "delayed_compare")])
2756
2757 (define_insn ""
2758 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2759 (zero_extend:SI
2760 (subreg:HI
2761 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
2762 (match_operand:SI 2 "const_int_operand" "i")) 0)))]
2763 "includes_rshift_p (operands[2], gen_rtx (CONST_INT, VOIDmode, 65535))"
2764 "{rlinm|rlwinm} %0,%1,%s2,0xffff")
2765
2766 (define_insn ""
2767 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
2768 (compare:CC
2769 (zero_extend:SI
2770 (subreg:HI
2771 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
2772 (match_operand:SI 2 "const_int_operand" "i")) 0))
2773 (const_int 0)))
2774 (clobber (match_scratch:SI 3 "=r"))]
2775 "includes_rshift_p (operands[2], gen_rtx (CONST_INT, VOIDmode, 65535))"
2776 "{rlinm.|rlwinm.} %3,%1,%s2,0xffff"
2777 [(set_attr "type" "delayed_compare")])
2778
2779 (define_insn ""
2780 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
2781 (compare:CC
2782 (zero_extend:SI
2783 (subreg:HI
2784 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
2785 (match_operand:SI 2 "const_int_operand" "i")) 0))
2786 (const_int 0)))
2787 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
2788 (zero_extend:SI (subreg:HI (lshiftrt:SI (match_dup 1) (match_dup 2)) 0)))]
2789 "includes_rshift_p (operands[2], gen_rtx (CONST_INT, VOIDmode, 65535))"
2790 "{rlinm.|rlwinm.} %0,%1,%s2,0xffff"
2791 [(set_attr "type" "delayed_compare")])
2792
2793 (define_insn ""
2794 [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r")
2795 (const_int 1)
2796 (match_operand:SI 1 "gpc_reg_operand" "r"))
2797 (ashiftrt:SI (match_operand:SI 2 "gpc_reg_operand" "r")
2798 (const_int 31)))]
2799 "TARGET_POWER"
2800 "rrib %0,%1,%2")
2801
2802 (define_insn ""
2803 [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r")
2804 (const_int 1)
2805 (match_operand:SI 1 "gpc_reg_operand" "r"))
2806 (lshiftrt:SI (match_operand:SI 2 "gpc_reg_operand" "r")
2807 (const_int 31)))]
2808 "TARGET_POWER"
2809 "rrib %0,%1,%2")
2810
2811 (define_insn ""
2812 [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r")
2813 (const_int 1)
2814 (match_operand:SI 1 "gpc_reg_operand" "r"))
2815 (zero_extract:SI (match_operand:SI 2 "gpc_reg_operand" "r")
2816 (const_int 1)
2817 (const_int 0)))]
2818 "TARGET_POWER"
2819 "rrib %0,%1,%2")
2820
2821 (define_expand "ashrsi3"
2822 [(set (match_operand:SI 0 "gpc_reg_operand" "")
2823 (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "")
2824 (match_operand:SI 2 "reg_or_cint_operand" "")))]
2825 ""
2826 "
2827 {
2828 if (TARGET_POWER)
2829 emit_insn (gen_ashrsi3_power (operands[0], operands[1], operands[2]));
2830 else
2831 emit_insn (gen_ashrsi3_no_power (operands[0], operands[1], operands[2]));
2832 DONE;
2833 }")
2834
2835 (define_insn "ashrsi3_power"
2836 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
2837 (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
2838 (match_operand:SI 2 "reg_or_cint_operand" "r,i")))
2839 (clobber (match_scratch:SI 3 "=q,X"))]
2840 "TARGET_POWER"
2841 "@
2842 srea %0,%1,%2
2843 {srai|srawi} %0,%1,%h2")
2844
2845 (define_insn "ashrsi3_no_power"
2846 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2847 (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
2848 (match_operand:SI 2 "reg_or_cint_operand" "ri")))]
2849 "! TARGET_POWER"
2850 "{sra|sraw}%I2 %0,%1,%h2")
2851
2852 (define_insn ""
2853 [(set (match_operand:CC 0 "cc_reg_operand" "=x,x")
2854 (compare:CC (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
2855 (match_operand:SI 2 "reg_or_cint_operand" "r,i"))
2856 (const_int 0)))
2857 (clobber (match_scratch:SI 3 "=r,r"))
2858 (clobber (match_scratch:SI 4 "=q,X"))]
2859 "TARGET_POWER"
2860 "@
2861 srea. %3,%1,%2
2862 {srai.|srawi.} %3,%1,%h2"
2863 [(set_attr "type" "delayed_compare")])
2864
2865 (define_insn ""
2866 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
2867 (compare:CC (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
2868 (match_operand:SI 2 "reg_or_cint_operand" "ri"))
2869 (const_int 0)))
2870 (clobber (match_scratch:SI 3 "=r"))]
2871 "! TARGET_POWER"
2872 "{sra|sraw}%I2. %3,%1,%h2"
2873 [(set_attr "type" "delayed_compare")])
2874
2875 (define_insn ""
2876 [(set (match_operand:CC 3 "cc_reg_operand" "=x,x")
2877 (compare:CC (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
2878 (match_operand:SI 2 "reg_or_cint_operand" "r,i"))
2879 (const_int 0)))
2880 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
2881 (ashiftrt:SI (match_dup 1) (match_dup 2)))
2882 (clobber (match_scratch:SI 4 "=q,X"))]
2883 "TARGET_POWER"
2884 "@
2885 srea. %0,%1,%2
2886 {srai.|srawi.} %0,%1,%h2"
2887 [(set_attr "type" "delayed_compare")])
2888
2889 (define_insn ""
2890 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
2891 (compare:CC (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
2892 (match_operand:SI 2 "reg_or_cint_operand" "ri"))
2893 (const_int 0)))
2894 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
2895 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
2896 "! TARGET_POWER"
2897 "{sra|sraw}%I2. %0,%1,%h2"
2898 [(set_attr "type" "delayed_compare")])
2899 \f
2900 ;; Floating-point insns, excluding normal data motion.
2901 ;;
2902 ;; PowerPC has a full set of single-precision floating point instructions.
2903 ;;
2904 ;; For the POWER architecture, we pretend that we have both SFmode and
2905 ;; DFmode insns, while, in fact, all fp insns are actually done in double.
2906 ;; The only conversions we will do will be when storing to memory. In that
2907 ;; case, we will use the "frsp" instruction before storing.
2908 ;;
2909 ;; Note that when we store into a single-precision memory location, we need to
2910 ;; use the frsp insn first. If the register being stored isn't dead, we
2911 ;; need a scratch register for the frsp. But this is difficult when the store
2912 ;; is done by reload. It is not incorrect to do the frsp on the register in
2913 ;; this case, we just lose precision that we would have otherwise gotten but
2914 ;; is not guaranteed. Perhaps this should be tightened up at some point.
2915
2916 (define_insn "extendsfdf2"
2917 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
2918 (float_extend:DF (match_operand:SF 1 "gpc_reg_operand" "f")))]
2919 "TARGET_HARD_FLOAT"
2920 "*
2921 {
2922 if (REGNO (operands[0]) == REGNO (operands[1]))
2923 return \"\";
2924 else
2925 return \"fmr %0,%1\";
2926 }"
2927 [(set_attr "type" "fp")])
2928
2929 (define_insn "truncdfsf2"
2930 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
2931 (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "f")))]
2932 "TARGET_HARD_FLOAT"
2933 "frsp %0,%1"
2934 [(set_attr "type" "fp")])
2935
2936 (define_insn "aux_truncdfsf2"
2937 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
2938 (unspec:SF [(match_operand:SF 1 "gpc_reg_operand" "f")] 0))]
2939 "! TARGET_POWERPC && TARGET_HARD_FLOAT"
2940 "frsp %0,%1"
2941 [(set_attr "type" "fp")])
2942
2943 (define_insn "negsf2"
2944 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
2945 (neg:SF (match_operand:SF 1 "gpc_reg_operand" "f")))]
2946 "TARGET_HARD_FLOAT"
2947 "fneg %0,%1"
2948 [(set_attr "type" "fp")])
2949
2950 (define_insn "abssf2"
2951 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
2952 (abs:SF (match_operand:SF 1 "gpc_reg_operand" "f")))]
2953 "TARGET_HARD_FLOAT"
2954 "fabs %0,%1"
2955 [(set_attr "type" "fp")])
2956
2957 (define_insn ""
2958 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
2959 (neg:SF (abs:SF (match_operand:SF 1 "gpc_reg_operand" "f"))))]
2960 "TARGET_HARD_FLOAT"
2961 "fnabs %0,%1"
2962 [(set_attr "type" "fp")])
2963
2964 (define_expand "addsf3"
2965 [(set (match_operand:SF 0 "gpc_reg_operand" "")
2966 (plus:SF (match_operand:SF 1 "gpc_reg_operand" "")
2967 (match_operand:SF 2 "gpc_reg_operand" "")))]
2968 "TARGET_HARD_FLOAT"
2969 "")
2970
2971 (define_insn ""
2972 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
2973 (plus:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
2974 (match_operand:SF 2 "gpc_reg_operand" "f")))]
2975 "TARGET_POWERPC && TARGET_HARD_FLOAT"
2976 "fadds %0,%1,%2"
2977 [(set_attr "type" "fp")])
2978
2979 (define_insn ""
2980 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
2981 (plus:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
2982 (match_operand:SF 2 "gpc_reg_operand" "f")))]
2983 "! TARGET_POWERPC && TARGET_HARD_FLOAT"
2984 "{fa|fadd} %0,%1,%2"
2985 [(set_attr "type" "fp")])
2986
2987 (define_expand "subsf3"
2988 [(set (match_operand:SF 0 "gpc_reg_operand" "")
2989 (minus:SF (match_operand:SF 1 "gpc_reg_operand" "")
2990 (match_operand:SF 2 "gpc_reg_operand" "")))]
2991 "TARGET_HARD_FLOAT"
2992 "")
2993
2994 (define_insn ""
2995 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
2996 (minus:SF (match_operand:SF 1 "gpc_reg_operand" "f")
2997 (match_operand:SF 2 "gpc_reg_operand" "f")))]
2998 "TARGET_POWERPC && TARGET_HARD_FLOAT"
2999 "fsubs %0,%1,%2"
3000 [(set_attr "type" "fp")])
3001
3002 (define_insn ""
3003 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
3004 (minus:SF (match_operand:SF 1 "gpc_reg_operand" "f")
3005 (match_operand:SF 2 "gpc_reg_operand" "f")))]
3006 "! TARGET_POWERPC && TARGET_HARD_FLOAT"
3007 "{fs|fsub} %0,%1,%2"
3008 [(set_attr "type" "fp")])
3009
3010 (define_expand "mulsf3"
3011 [(set (match_operand:SF 0 "gpc_reg_operand" "")
3012 (mult:SF (match_operand:SF 1 "gpc_reg_operand" "")
3013 (match_operand:SF 2 "gpc_reg_operand" "")))]
3014 "TARGET_HARD_FLOAT"
3015 "")
3016
3017 (define_insn ""
3018 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
3019 (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
3020 (match_operand:SF 2 "gpc_reg_operand" "f")))]
3021 "TARGET_POWERPC && TARGET_HARD_FLOAT"
3022 "fmuls %0,%1,%2"
3023 [(set_attr "type" "fp")])
3024
3025 (define_insn ""
3026 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
3027 (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
3028 (match_operand:SF 2 "gpc_reg_operand" "f")))]
3029 "! TARGET_POWERPC && TARGET_HARD_FLOAT"
3030 "{fm|fmul} %0,%1,%2"
3031 [(set_attr "type" "dmul")])
3032
3033 (define_expand "divsf3"
3034 [(set (match_operand:SF 0 "gpc_reg_operand" "")
3035 (div:SF (match_operand:SF 1 "gpc_reg_operand" "")
3036 (match_operand:SF 2 "gpc_reg_operand" "")))]
3037 "TARGET_HARD_FLOAT"
3038 "")
3039
3040 (define_insn ""
3041 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
3042 (div:SF (match_operand:SF 1 "gpc_reg_operand" "f")
3043 (match_operand:SF 2 "gpc_reg_operand" "f")))]
3044 "TARGET_POWERPC && TARGET_HARD_FLOAT"
3045 "fdivs %0,%1,%2"
3046 [(set_attr "type" "sdiv")])
3047
3048 (define_insn ""
3049 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
3050 (div:SF (match_operand:SF 1 "gpc_reg_operand" "f")
3051 (match_operand:SF 2 "gpc_reg_operand" "f")))]
3052 "! TARGET_POWERPC && TARGET_HARD_FLOAT"
3053 "{fd|fdiv} %0,%1,%2"
3054 [(set_attr "type" "ddiv")])
3055
3056 (define_insn ""
3057 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
3058 (plus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
3059 (match_operand:SF 2 "gpc_reg_operand" "f"))
3060 (match_operand:SF 3 "gpc_reg_operand" "f")))]
3061 "TARGET_POWERPC && TARGET_HARD_FLOAT"
3062 "fmadds %0,%1,%2,%3"
3063 [(set_attr "type" "fp")])
3064
3065 (define_insn ""
3066 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
3067 (plus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
3068 (match_operand:SF 2 "gpc_reg_operand" "f"))
3069 (match_operand:SF 3 "gpc_reg_operand" "f")))]
3070 "! TARGET_POWERPC && TARGET_HARD_FLOAT"
3071 "{fma|fmadd} %0,%1,%2,%3"
3072 [(set_attr "type" "dmul")])
3073
3074 (define_insn ""
3075 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
3076 (minus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
3077 (match_operand:SF 2 "gpc_reg_operand" "f"))
3078 (match_operand:SF 3 "gpc_reg_operand" "f")))]
3079 "TARGET_POWERPC && TARGET_HARD_FLOAT"
3080 "fmsubs %0,%1,%2,%3"
3081 [(set_attr "type" "fp")])
3082
3083 (define_insn ""
3084 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
3085 (minus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
3086 (match_operand:SF 2 "gpc_reg_operand" "f"))
3087 (match_operand:SF 3 "gpc_reg_operand" "f")))]
3088 "! TARGET_POWERPC && TARGET_HARD_FLOAT"
3089 "{fms|fmsub} %0,%1,%2,%3"
3090 [(set_attr "type" "dmul")])
3091
3092 (define_insn ""
3093 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
3094 (neg:SF (plus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
3095 (match_operand:SF 2 "gpc_reg_operand" "f"))
3096 (match_operand:SF 3 "gpc_reg_operand" "f"))))]
3097 "TARGET_POWERPC && TARGET_HARD_FLOAT"
3098 "fnmadds %0,%1,%2,%3"
3099 [(set_attr "type" "fp")])
3100
3101 (define_insn ""
3102 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
3103 (neg:SF (plus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
3104 (match_operand:SF 2 "gpc_reg_operand" "f"))
3105 (match_operand:SF 3 "gpc_reg_operand" "f"))))]
3106 "! TARGET_POWERPC && TARGET_HARD_FLOAT"
3107 "{fnma|fnmadd} %0,%1,%2,%3"
3108 [(set_attr "type" "dmul")])
3109
3110 (define_insn ""
3111 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
3112 (neg:SF (minus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
3113 (match_operand:SF 2 "gpc_reg_operand" "f"))
3114 (match_operand:SF 3 "gpc_reg_operand" "f"))))]
3115 "TARGET_POWERPC && TARGET_HARD_FLOAT"
3116 "fnmsubs %0,%1,%2,%3"
3117 [(set_attr "type" "fp")])
3118
3119 (define_insn ""
3120 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
3121 (neg:SF (minus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
3122 (match_operand:SF 2 "gpc_reg_operand" "f"))
3123 (match_operand:SF 3 "gpc_reg_operand" "f"))))]
3124 "! TARGET_POWERPC && TARGET_HARD_FLOAT"
3125 "{fnms|fnmsub} %0,%1,%2,%3"
3126 [(set_attr "type" "dmul")])
3127
3128 (define_expand "sqrtsf2"
3129 [(set (match_operand:SF 0 "gpc_reg_operand" "")
3130 (sqrt:SF (match_operand:SF 1 "gpc_reg_operand" "")))]
3131 "(TARGET_PPC_GPOPT || TARGET_POWER2) && TARGET_HARD_FLOAT"
3132 "")
3133
3134 (define_insn ""
3135 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
3136 (sqrt:SF (match_operand:SF 1 "gpc_reg_operand" "f")))]
3137 "TARGET_PPC_GPOPT && TARGET_HARD_FLOAT"
3138 "fsqrts %0,%1"
3139 [(set_attr "type" "ssqrt")])
3140
3141 (define_insn ""
3142 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
3143 (sqrt:SF (match_operand:SF 1 "gpc_reg_operand" "f")))]
3144 "TARGET_POWER2 && TARGET_HARD_FLOAT"
3145 "fsqrt %0,%1"
3146 [(set_attr "type" "dsqrt")])
3147
3148 ;; For MIN, MAX, and conditional move, we use DEFINE_EXPAND's that involve a
3149 ;; fsel instruction and some auxiliary computations. Then we just have a
3150 ;; single DEFINE_INSN for fsel and the define_splits to make them if made by
3151 ;; combine.
3152 (define_expand "maxsf3"
3153 [(set (match_dup 3)
3154 (minus:SF (match_operand:SF 1 "gpc_reg_operand" "")
3155 (match_operand:SF 2 "gpc_reg_operand" "")))
3156 (set (match_operand:SF 0 "gpc_reg_operand" "")
3157 (if_then_else:SF (ge (match_dup 3)
3158 (const_int 0))
3159 (match_dup 1)
3160 (match_dup 2)))]
3161 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT"
3162 "
3163 { operands[3] = gen_reg_rtx (SFmode); }")
3164
3165 (define_split
3166 [(set (match_operand:SF 0 "gpc_reg_operand" "")
3167 (smax:SF (match_operand:SF 1 "gpc_reg_operand" "")
3168 (match_operand:SF 2 "gpc_reg_operand" "")))
3169 (clobber (match_operand:SF 3 "gpc_reg_operand" ""))]
3170 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT"
3171 [(set (match_dup 3)
3172 (minus:SF (match_dup 1) (match_dup 2)))
3173 (set (match_dup 0)
3174 (if_then_else:SF (ge (match_dup 3)
3175 (const_int 0))
3176 (match_dup 1)
3177 (match_dup 2)))]
3178 "")
3179
3180 (define_expand "minsf3"
3181 [(set (match_dup 3)
3182 (minus:SF (match_operand:SF 2 "gpc_reg_operand" "")
3183 (match_operand:SF 1 "gpc_reg_operand" "")))
3184 (set (match_operand:SF 0 "gpc_reg_operand" "")
3185 (if_then_else:SF (ge (match_dup 3)
3186 (const_int 0))
3187 (match_dup 1)
3188 (match_dup 2)))]
3189 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT"
3190 "
3191 { operands[3] = gen_reg_rtx (SFmode); }")
3192
3193 (define_split
3194 [(set (match_operand:SF 0 "gpc_reg_operand" "")
3195 (smin:SF (match_operand:SF 1 "gpc_reg_operand" "")
3196 (match_operand:SF 2 "gpc_reg_operand" "")))
3197 (clobber (match_operand:SF 3 "gpc_reg_operand" ""))]
3198 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT"
3199 [(set (match_dup 3)
3200 (minus:SF (match_dup 2) (match_dup 1)))
3201 (set (match_dup 0)
3202 (if_then_else:SF (ge (match_dup 3)
3203 (const_int 0))
3204 (match_dup 1)
3205 (match_dup 2)))]
3206 "")
3207
3208 (define_expand "movsfcc"
3209 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
3210 (if_then_else:SF (match_operand 1 "comparison_operator" "")
3211 (match_operand:SF 2 "gpc_reg_operand" "f")
3212 (match_operand:SF 3 "gpc_reg_operand" "f")))]
3213 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT"
3214 "
3215 {
3216 rtx temp, op0, op1;
3217 enum rtx_code code = GET_CODE (operands[1]);
3218 if (! rs6000_compare_fp_p)
3219 FAIL;
3220 switch (code)
3221 {
3222 case GE: case EQ: case NE:
3223 op0 = rs6000_compare_op0;
3224 op1 = rs6000_compare_op1;
3225 break;
3226 case GT:
3227 op0 = rs6000_compare_op1;
3228 op1 = rs6000_compare_op0;
3229 temp = operands[2]; operands[2] = operands[3]; operands[3] = temp;
3230 break;
3231 case LE:
3232 op0 = rs6000_compare_op1;
3233 op1 = rs6000_compare_op0;
3234 break;
3235 case LT:
3236 op0 = rs6000_compare_op0;
3237 op1 = rs6000_compare_op1;
3238 temp = operands[2]; operands[2] = operands[3]; operands[3] = temp;
3239 break;
3240 default:
3241 FAIL;
3242 }
3243 if (GET_MODE (rs6000_compare_op0) == DFmode)
3244 {
3245 temp = gen_reg_rtx (DFmode);
3246 emit_insn (gen_subdf3 (temp, op0, op1));
3247 emit_insn (gen_fseldfsf4 (operands[0], temp, operands[2], operands[3]));
3248 if (code == EQ)
3249 {
3250 emit_insn (gen_negdf2 (temp, temp));
3251 emit_insn (gen_fseldfsf4 (operands[0], temp, operands[0], operands[3]));
3252 }
3253 if (code == NE)
3254 {
3255 emit_insn (gen_negdf2 (temp, temp));
3256 emit_insn (gen_fseldfsf4 (operands[0], temp, operands[3], operands[0]));
3257 }
3258 }
3259 else
3260 {
3261 temp = gen_reg_rtx (SFmode);
3262 emit_insn (gen_subsf3 (temp, op0, op1));
3263 emit_insn (gen_fselsfsf4 (operands[0], temp, operands[2], operands[3]));
3264 if (code == EQ)
3265 {
3266 emit_insn (gen_negsf2 (temp, temp));
3267 emit_insn (gen_fselsfsf4 (operands[0], temp, operands[0], operands[3]));
3268 }
3269 if (code == NE)
3270 {
3271 emit_insn (gen_negsf2 (temp, temp));
3272 emit_insn (gen_fselsfsf4 (operands[0], temp, operands[3], operands[0]));
3273 }
3274 }
3275 DONE;
3276 }")
3277
3278 (define_insn "fselsfsf4"
3279 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
3280 (if_then_else:SF (ge (match_operand:SF 1 "gpc_reg_operand" "f")
3281 (const_int 0))
3282 (match_operand:SF 2 "gpc_reg_operand" "f")
3283 (match_operand:SF 3 "gpc_reg_operand" "f")))]
3284 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT"
3285 "fsel %0,%1,%2,%3"
3286 [(set_attr "type" "fp")])
3287
3288 (define_insn "fseldfsf4"
3289 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
3290 (if_then_else:SF (ge (match_operand:DF 1 "gpc_reg_operand" "f")
3291 (const_int 0))
3292 (match_operand:SF 2 "gpc_reg_operand" "f")
3293 (match_operand:SF 3 "gpc_reg_operand" "f")))]
3294 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT"
3295 "fsel %0,%1,%2,%3"
3296 [(set_attr "type" "fp")])
3297
3298 (define_insn "negdf2"
3299 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
3300 (neg:DF (match_operand:DF 1 "gpc_reg_operand" "f")))]
3301 "TARGET_HARD_FLOAT"
3302 "fneg %0,%1"
3303 [(set_attr "type" "fp")])
3304
3305 (define_insn "absdf2"
3306 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
3307 (abs:DF (match_operand:DF 1 "gpc_reg_operand" "f")))]
3308 "TARGET_HARD_FLOAT"
3309 "fabs %0,%1"
3310 [(set_attr "type" "fp")])
3311
3312 (define_insn ""
3313 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
3314 (neg:DF (abs:DF (match_operand:DF 1 "gpc_reg_operand" "f"))))]
3315 "TARGET_HARD_FLOAT"
3316 "fnabs %0,%1"
3317 [(set_attr "type" "fp")])
3318
3319 (define_insn "adddf3"
3320 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
3321 (plus:DF (match_operand:DF 1 "gpc_reg_operand" "%f")
3322 (match_operand:DF 2 "gpc_reg_operand" "f")))]
3323 "TARGET_HARD_FLOAT"
3324 "{fa|fadd} %0,%1,%2"
3325 [(set_attr "type" "fp")])
3326
3327 (define_insn "subdf3"
3328 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
3329 (minus:DF (match_operand:DF 1 "gpc_reg_operand" "f")
3330 (match_operand:DF 2 "gpc_reg_operand" "f")))]
3331 "TARGET_HARD_FLOAT"
3332 "{fs|fsub} %0,%1,%2"
3333 [(set_attr "type" "fp")])
3334
3335 (define_insn "muldf3"
3336 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
3337 (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%f")
3338 (match_operand:DF 2 "gpc_reg_operand" "f")))]
3339 "TARGET_HARD_FLOAT"
3340 "{fm|fmul} %0,%1,%2"
3341 [(set_attr "type" "dmul")])
3342
3343 (define_insn "divdf3"
3344 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
3345 (div:DF (match_operand:DF 1 "gpc_reg_operand" "f")
3346 (match_operand:DF 2 "gpc_reg_operand" "f")))]
3347 "TARGET_HARD_FLOAT"
3348 "{fd|fdiv} %0,%1,%2"
3349 [(set_attr "type" "ddiv")])
3350
3351 (define_insn ""
3352 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
3353 (plus:DF (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%f")
3354 (match_operand:DF 2 "gpc_reg_operand" "f"))
3355 (match_operand:DF 3 "gpc_reg_operand" "f")))]
3356 "TARGET_HARD_FLOAT"
3357 "{fma|fmadd} %0,%1,%2,%3"
3358 [(set_attr "type" "dmul")])
3359
3360 (define_insn ""
3361 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
3362 (minus:DF (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%f")
3363 (match_operand:DF 2 "gpc_reg_operand" "f"))
3364 (match_operand:DF 3 "gpc_reg_operand" "f")))]
3365 "TARGET_HARD_FLOAT"
3366 "{fms|fmsub} %0,%1,%2,%3"
3367 [(set_attr "type" "dmul")])
3368
3369 (define_insn ""
3370 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
3371 (neg:DF (plus:DF (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%f")
3372 (match_operand:DF 2 "gpc_reg_operand" "f"))
3373 (match_operand:DF 3 "gpc_reg_operand" "f"))))]
3374 "TARGET_HARD_FLOAT"
3375 "{fnma|fnmadd} %0,%1,%2,%3"
3376 [(set_attr "type" "dmul")])
3377
3378 (define_insn ""
3379 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
3380 (neg:DF (minus:DF (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%f")
3381 (match_operand:DF 2 "gpc_reg_operand" "f"))
3382 (match_operand:DF 3 "gpc_reg_operand" "f"))))]
3383 "TARGET_HARD_FLOAT"
3384 "{fnms|fnmsub} %0,%1,%2,%3"
3385 [(set_attr "type" "dmul")])
3386
3387 (define_insn "sqrtdf2"
3388 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
3389 (sqrt:DF (match_operand:DF 1 "gpc_reg_operand" "f")))]
3390 "(TARGET_PPC_GPOPT || TARGET_POWER2) && TARGET_HARD_FLOAT"
3391 "fsqrt %0,%1"
3392 [(set_attr "type" "dsqrt")])
3393
3394 ;; For MIN, MAX, and conditional move, we use DEFINE_EXPAND's that involve a
3395 ;; fsel instruction and some auxiliary computations. Then we just have a
3396 ;; single DEFINE_INSN for fsel and the define_splits to make them if made by
3397 ;; combine.
3398
3399 (define_expand "maxdf3"
3400 [(set (match_dup 3)
3401 (minus:DF (match_operand:DF 1 "gpc_reg_operand" "")
3402 (match_operand:DF 2 "gpc_reg_operand" "")))
3403 (set (match_operand:DF 0 "gpc_reg_operand" "")
3404 (if_then_else:DF (ge (match_dup 3)
3405 (const_int 0))
3406 (match_dup 1)
3407 (match_dup 2)))]
3408 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT"
3409 "
3410 { operands[3] = gen_reg_rtx (DFmode); }")
3411
3412 (define_split
3413 [(set (match_operand:DF 0 "gpc_reg_operand" "")
3414 (smax:DF (match_operand:DF 1 "gpc_reg_operand" "")
3415 (match_operand:DF 2 "gpc_reg_operand" "")))
3416 (clobber (match_operand:DF 3 "gpc_reg_operand" ""))]
3417 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT"
3418 [(set (match_dup 3)
3419 (minus:DF (match_dup 1) (match_dup 2)))
3420 (set (match_dup 0)
3421 (if_then_else:DF (ge (match_dup 3)
3422 (const_int 0))
3423 (match_dup 1)
3424 (match_dup 2)))]
3425 "")
3426
3427 (define_expand "mindf3"
3428 [(set (match_dup 3)
3429 (minus:DF (match_operand:DF 2 "gpc_reg_operand" "")
3430 (match_operand:DF 1 "gpc_reg_operand" "")))
3431 (set (match_operand:DF 0 "gpc_reg_operand" "")
3432 (if_then_else:DF (ge (match_dup 3)
3433 (const_int 0))
3434 (match_dup 1)
3435 (match_dup 2)))]
3436 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT"
3437 "
3438 { operands[3] = gen_reg_rtx (DFmode); }")
3439
3440 (define_split
3441 [(set (match_operand:DF 0 "gpc_reg_operand" "")
3442 (smin:DF (match_operand:DF 1 "gpc_reg_operand" "")
3443 (match_operand:DF 2 "gpc_reg_operand" "")))
3444 (clobber (match_operand:DF 3 "gpc_reg_operand" ""))]
3445 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT"
3446 [(set (match_dup 3)
3447 (minus:DF (match_dup 2) (match_dup 1)))
3448 (set (match_dup 0)
3449 (if_then_else:DF (ge (match_dup 3)
3450 (const_int 0))
3451 (match_dup 1)
3452 (match_dup 2)))]
3453 "")
3454
3455 (define_expand "movdfcc"
3456 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
3457 (if_then_else:DF (match_operand 1 "comparison_operator" "")
3458 (match_operand:DF 2 "gpc_reg_operand" "f")
3459 (match_operand:DF 3 "gpc_reg_operand" "f")))]
3460 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT"
3461 "
3462 {
3463 rtx temp, op0, op1;
3464 enum rtx_code code = GET_CODE (operands[1]);
3465 if (! rs6000_compare_fp_p)
3466 FAIL;
3467 switch (code)
3468 {
3469 case GE: case EQ: case NE:
3470 op0 = rs6000_compare_op0;
3471 op1 = rs6000_compare_op1;
3472 break;
3473 case GT:
3474 op0 = rs6000_compare_op1;
3475 op1 = rs6000_compare_op0;
3476 temp = operands[2]; operands[2] = operands[3]; operands[3] = temp;
3477 break;
3478 case LE:
3479 op0 = rs6000_compare_op1;
3480 op1 = rs6000_compare_op0;
3481 break;
3482 case LT:
3483 op0 = rs6000_compare_op0;
3484 op1 = rs6000_compare_op1;
3485 temp = operands[2]; operands[2] = operands[3]; operands[3] = temp;
3486 break;
3487 default:
3488 FAIL;
3489 }
3490 if (GET_MODE (rs6000_compare_op0) == DFmode)
3491 {
3492 temp = gen_reg_rtx (DFmode);
3493 emit_insn (gen_subdf3 (temp, op0, op1));
3494 emit_insn (gen_fseldfdf4 (operands[0], temp, operands[2], operands[3]));
3495 if (code == EQ)
3496 {
3497 emit_insn (gen_negdf2 (temp, temp));
3498 emit_insn (gen_fseldfdf4 (operands[0], temp, operands[0], operands[3]));
3499 }
3500 if (code == NE)
3501 {
3502 emit_insn (gen_negdf2 (temp, temp));
3503 emit_insn (gen_fseldfdf4 (operands[0], temp, operands[3], operands[0]));
3504 }
3505 }
3506 else
3507 {
3508 temp = gen_reg_rtx (SFmode);
3509 emit_insn (gen_subsf3 (temp, op0, op1));
3510 emit_insn (gen_fselsfdf4 (operands[0], temp, operands[2], operands[3]));
3511 if (code == EQ)
3512 {
3513 emit_insn (gen_negsf2 (temp, temp));
3514 emit_insn (gen_fselsfdf4 (operands[0], temp, operands[0], operands[3]));
3515 }
3516 if (code == NE)
3517 {
3518 emit_insn (gen_negsf2 (temp, temp));
3519 emit_insn (gen_fselsfdf4 (operands[0], temp, operands[3], operands[0]));
3520 }
3521 }
3522 DONE;
3523 }")
3524
3525 (define_insn "fseldfdf4"
3526 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
3527 (if_then_else:DF (ge (match_operand:DF 1 "gpc_reg_operand" "f")
3528 (const_int 0))
3529 (match_operand:DF 2 "gpc_reg_operand" "f")
3530 (match_operand:DF 3 "gpc_reg_operand" "f")))]
3531 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT"
3532 "fsel %0,%1,%2,%3"
3533 [(set_attr "type" "fp")])
3534
3535 (define_insn "fselsfdf4"
3536 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
3537 (if_then_else:DF (ge (match_operand:SF 1 "gpc_reg_operand" "f")
3538 (const_int 0))
3539 (match_operand:DF 2 "gpc_reg_operand" "f")
3540 (match_operand:DF 3 "gpc_reg_operand" "f")))]
3541 "TARGET_PPC_GFXOPT"
3542 "fsel %0,%1,%2,%3"
3543 [(set_attr "type" "fp")])
3544 \f
3545 ;; Conversions to and from floating-point.
3546
3547 (define_expand "floatsidf2"
3548 [(parallel [(set (match_operand:DF 0 "gpc_reg_operand" "")
3549 (float:DF (match_operand:SI 1 "gpc_reg_operand" "")))
3550 (use (match_dup 2))
3551 (use (match_dup 3))
3552 (clobber (match_dup 4))
3553 (clobber (match_dup 5))
3554 (clobber (reg:DF 76))])]
3555 "! TARGET_POWERPC64 && TARGET_HARD_FLOAT"
3556 "
3557 {
3558 operands[2] = force_reg (SImode, GEN_INT (0x43300000));
3559 operands[3] = force_reg (DFmode, rs6000_float_const (\"4503601774854144\", DFmode));
3560 operands[4] = gen_reg_rtx (SImode);
3561 operands[5] = gen_reg_rtx (Pmode);
3562 }")
3563
3564 (define_insn "*floatsidf2_internal"
3565 [(set (match_operand:DF 0 "gpc_reg_operand" "=&f")
3566 (float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
3567 (use (match_operand:SI 2 "gpc_reg_operand" "r"))
3568 (use (match_operand:DF 3 "gpc_reg_operand" "f"))
3569 (clobber (match_operand:SI 4 "gpc_reg_operand" "=r"))
3570 (clobber (match_operand:SI 5 "gpc_reg_operand" "=b"))
3571 (clobber (reg:DF 76))]
3572 "! TARGET_POWERPC64 && TARGET_HARD_FLOAT"
3573 "#"
3574 [(set_attr "length" "24")])
3575
3576 (define_split
3577 [(set (match_operand:DF 0 "gpc_reg_operand" "")
3578 (float:DF (match_operand:SI 1 "gpc_reg_operand" "")))
3579 (use (match_operand:SI 2 "gpc_reg_operand" ""))
3580 (use (match_operand:DF 3 "gpc_reg_operand" ""))
3581 (clobber (match_operand:SI 4 "gpc_reg_operand" ""))
3582 (clobber (match_operand:SI 5 "gpc_reg_operand" ""))
3583 (clobber (reg:DF 76))]
3584 "! TARGET_POWERPC64 && TARGET_HARD_FLOAT"
3585 [(set (match_dup 4)
3586 (xor:SI (match_dup 1)
3587 (match_dup 6)))
3588 (set (match_dup 5)
3589 (unspec [(const_int 0)] 11))
3590 (set (match_dup 7)
3591 (unspec [(match_dup 4)
3592 (match_dup 5)] 12)) ;; low word
3593 (set (match_dup 7)
3594 (unspec [(match_dup 2)
3595 (match_dup 5)
3596 (match_dup 7)] 13)) ;; high word
3597 (set (match_dup 0)
3598 (unspec [(match_dup 7)
3599 (match_dup 5)] 14))
3600 (set (match_dup 0)
3601 (minus:DF (match_dup 0)
3602 (match_dup 3)))]
3603 "
3604 {
3605 operands[6] = GEN_INT (0x80000000);
3606 operands[7] = gen_rtx (REG, DFmode, FPMEM_REGNUM);
3607 }")
3608
3609 (define_expand "floatunssidf2"
3610 [(parallel [(set (match_operand:DF 0 "gpc_reg_operand" "")
3611 (unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" "")))
3612 (use (match_dup 2))
3613 (use (match_dup 3))
3614 (clobber (match_dup 4))
3615 (clobber (reg:DF 76))])]
3616 "! TARGET_POWERPC64 && TARGET_HARD_FLOAT"
3617 "
3618 {
3619 operands[2] = force_reg (SImode, GEN_INT (0x43300000));
3620 operands[3] = force_reg (DFmode, rs6000_float_const (\"4503599627370496\", DFmode));
3621 operands[4] = gen_reg_rtx (Pmode);
3622 }")
3623
3624 (define_insn "*floatunssidf2_internal"
3625 [(set (match_operand:DF 0 "gpc_reg_operand" "=&f")
3626 (unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
3627 (use (match_operand:SI 2 "gpc_reg_operand" "r"))
3628 (use (match_operand:DF 3 "gpc_reg_operand" "f"))
3629 (clobber (match_operand:SI 4 "gpc_reg_operand" "=b"))
3630 (clobber (reg:DF 76))]
3631 "! TARGET_POWERPC64 && TARGET_HARD_FLOAT"
3632 "#"
3633 [(set_attr "length" "20")])
3634
3635 (define_split
3636 [(set (match_operand:DF 0 "gpc_reg_operand" "")
3637 (unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" "")))
3638 (use (match_operand:SI 2 "gpc_reg_operand" ""))
3639 (use (match_operand:DF 3 "gpc_reg_operand" ""))
3640 (clobber (match_operand:SI 4 "gpc_reg_operand" "=b"))
3641 (clobber (reg:DF 76))]
3642 "! TARGET_POWERPC64 && TARGET_HARD_FLOAT"
3643 [(set (match_dup 4)
3644 (unspec [(const_int 0)] 11))
3645 (set (match_dup 5)
3646 (unspec [(match_dup 1)
3647 (match_dup 4)] 12)) ;; low word
3648 (set (match_dup 5)
3649 (unspec [(match_dup 2)
3650 (match_dup 4)
3651 (match_dup 5)] 13)) ;; high word
3652 (set (match_dup 0)
3653 (unspec [(match_dup 5)
3654 (reg:SI 1)] 14))
3655 (set (match_dup 0)
3656 (minus:DF (match_dup 0)
3657 (match_dup 3)))]
3658 "operands[5] = gen_rtx (REG, DFmode, FPMEM_REGNUM);")
3659
3660 ;; Load up scratch register with base address + offset if needed
3661 (define_insn "*floatsidf2_loadaddr"
3662 [(set (match_operand:SI 0 "gpc_reg_operand" "=b")
3663 (unspec [(const_int 0)] 11))]
3664 "TARGET_HARD_FLOAT"
3665 "*
3666 {
3667 if (rs6000_fpmem_offset > 32760)
3668 {
3669 rtx xop[3];
3670
3671 xop[0] = operands[0];
3672 xop[1] = (frame_pointer_needed) ? frame_pointer_rtx : stack_pointer_rtx;
3673 xop[2] = GEN_INT ((rs6000_fpmem_offset >> 16) + ((rs6000_fpmem_offset & 0x8000) >> 15));
3674 output_asm_insn (\"{cau %0,%2(%1)|addis %0,%1,%2}\", xop);
3675 }
3676 else if (rs6000_fpmem_offset < 0)
3677 abort ();
3678
3679 return \"\";
3680 }"
3681 [(set_attr "length" "4")])
3682
3683 (define_insn "*floatsidf2_store1"
3684 [(set (reg:DF 76)
3685 (unspec [(match_operand:SI 0 "gpc_reg_operand" "r")
3686 (match_operand:SI 1 "gpc_reg_operand" "r")] 12))]
3687 "! TARGET_POWERPC64 && TARGET_HARD_FLOAT"
3688 "*
3689 {
3690 rtx indx;
3691
3692 if (rs6000_fpmem_offset > 32760)
3693 indx = operands[1];
3694 else if (frame_pointer_needed)
3695 indx = frame_pointer_rtx;
3696 else
3697 indx = stack_pointer_rtx;
3698
3699 operands[2] = gen_rtx (MEM, SImode,
3700 gen_rtx (PLUS, Pmode,
3701 indx,
3702 GEN_INT ((((rs6000_fpmem_offset & 0xffff) ^ 0x8000) - 0x8000)
3703 + ((WORDS_BIG_ENDIAN != 0) * 4))));
3704
3705 return \"{st|stw} %0,%2\";
3706 }"
3707 [(set_attr "type" "store")])
3708
3709 (define_insn "*floatsidf2_store2"
3710 [(set (reg:DF 76)
3711 (unspec [(match_operand:SI 0 "gpc_reg_operand" "r")
3712 (match_operand:SI 1 "gpc_reg_operand" "r")
3713 (reg:DF 76)] 13))]
3714 "! TARGET_POWERPC64 && TARGET_HARD_FLOAT"
3715 "*
3716 {
3717 rtx indx;
3718
3719 if (rs6000_fpmem_offset > 32760)
3720 indx = operands[1];
3721 else if (frame_pointer_needed)
3722 indx = frame_pointer_rtx;
3723 else
3724 indx = stack_pointer_rtx;
3725
3726 operands[2] = gen_rtx (MEM, SImode,
3727 gen_rtx (PLUS, Pmode,
3728 indx,
3729 GEN_INT ((((rs6000_fpmem_offset & 0xffff) ^ 0x8000) - 0x8000)
3730 + ((WORDS_BIG_ENDIAN == 0) * 4))));
3731
3732 return \"{st|stw} %0,%2\";
3733 }"
3734 [(set_attr "type" "store")])
3735
3736 (define_insn "*floatsidf2_load"
3737 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
3738 (unspec [(reg:DF 76)
3739 (match_operand:SI 1 "gpc_reg_operand" "b")] 14))]
3740 "! TARGET_POWERPC64 && TARGET_HARD_FLOAT"
3741 "*
3742 {
3743 rtx indx;
3744 HOST_WIDE_INT offset = rs6000_fpmem_offset;
3745
3746 if (rs6000_fpmem_offset > 32760)
3747 {
3748 indx = operands[1];
3749 offset = (((offset & 0xffff) ^ 0x8000) - 0x8000);
3750 }
3751 else if (frame_pointer_needed)
3752 indx = frame_pointer_rtx;
3753 else
3754 indx = stack_pointer_rtx;
3755
3756 operands[2] = gen_rtx (MEM, SImode,
3757 gen_rtx (PLUS, Pmode, indx, GEN_INT (offset)));
3758
3759 return \"lfd %0,%2\";
3760 }"
3761 [(set_attr "type" "fpload")])
3762
3763 (define_expand "fix_truncdfsi2"
3764 [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "")
3765 (fix:SI (match_operand:DF 1 "gpc_reg_operand" "")))
3766 (clobber (match_dup 2))
3767 (clobber (match_dup 3))
3768 (clobber (match_dup 4))])]
3769 "TARGET_HARD_FLOAT"
3770 "
3771 {
3772 if (!TARGET_POWER2 && !TARGET_POWERPC)
3773 {
3774 emit_insn (gen_trunc_call (operands[0], operands[1],
3775 gen_rtx (SYMBOL_REF, Pmode, RS6000_ITRUNC)));
3776 DONE;
3777 }
3778
3779 operands[2] = gen_reg_rtx (DImode);
3780 operands[3] = gen_reg_rtx (Pmode);
3781 operands[4] = gen_rtx (REG, DImode, FPMEM_REGNUM);
3782 }")
3783
3784 (define_insn "*fix_truncdfsi2_internal"
3785 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
3786 (fix:SI (match_operand:DF 1 "gpc_reg_operand" "f")))
3787 (clobber (match_operand:DI 2 "gpc_reg_operand" "=f"))
3788 (clobber (match_operand:SI 3 "gpc_reg_operand" "=b"))
3789 (clobber (reg:DI 76))]
3790 "TARGET_HARD_FLOAT"
3791 "#"
3792 [(set_attr "length" "12")])
3793
3794 (define_split
3795 [(set (match_operand:SI 0 "gpc_reg_operand" "")
3796 (fix:SI (match_operand:DF 1 "gpc_reg_operand" "f")))
3797 (clobber (match_operand:DI 2 "gpc_reg_operand" ""))
3798 (clobber (match_operand:SI 3 "gpc_reg_operand" ""))
3799 (clobber (reg:DI 76))]
3800 "TARGET_HARD_FLOAT"
3801 [(set (match_dup 2)
3802 (sign_extend:DI (fix:SI (match_operand:DF 1 "gpc_reg_operand" ""))))
3803 (set (match_dup 3)
3804 (unspec [(const_int 0)] 11))
3805 (set (match_dup 4)
3806 (unspec [(match_dup 2)
3807 (match_dup 3)] 15))
3808 (set (match_operand:SI 0 "gpc_reg_operand" "")
3809 (unspec [(match_dup 4)
3810 (match_dup 3)] 16))]
3811 "operands[4] = gen_rtx (REG, DImode, FPMEM_REGNUM);")
3812
3813 (define_insn "*fctiwz"
3814 [(set (match_operand:DI 0 "gpc_reg_operand" "=f")
3815 (sign_extend:DI (fix:SI (match_operand:DF 1 "gpc_reg_operand" "f"))))]
3816 "(TARGET_POWER2 || TARGET_POWERPC) && TARGET_HARD_FLOAT"
3817 "{fcirz|fctiwz} %0,%1"
3818 [(set_attr "type" "fp")])
3819
3820 (define_insn "*fix_truncdfsi2_store"
3821 [(set (reg:DI 76)
3822 (unspec [(match_operand:DI 0 "gpc_reg_operand" "f")
3823 (match_operand:SI 1 "gpc_reg_operand" "b")] 15))]
3824 "(TARGET_POWER2 || TARGET_POWERPC) && TARGET_HARD_FLOAT"
3825 "*
3826 {
3827 rtx indx;
3828
3829 if (rs6000_fpmem_offset > 32760)
3830 indx = operands[1];
3831 else if (frame_pointer_needed)
3832 indx = frame_pointer_rtx;
3833 else
3834 indx = stack_pointer_rtx;
3835
3836 operands[2] = gen_rtx (MEM, DFmode,
3837 gen_rtx (PLUS, Pmode,
3838 indx,
3839 GEN_INT (rs6000_fpmem_offset)));
3840
3841 return \"stfd %0,%w2\";
3842 }"
3843 [(set_attr "type" "fpstore")])
3844
3845 (define_insn "*fix_truncdfsi2_load"
3846 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
3847 (unspec [(reg:DI 76)
3848 (match_operand:SI 1 "gpc_reg_operand" "b")] 16))]
3849 "(TARGET_POWER2 || TARGET_POWERPC) && TARGET_HARD_FLOAT"
3850 "*
3851 {
3852 rtx indx;
3853
3854 if (rs6000_fpmem_offset > 32760)
3855 indx = operands[1];
3856 else if (frame_pointer_needed)
3857 indx = frame_pointer_rtx;
3858 else
3859 indx = stack_pointer_rtx;
3860
3861 operands[2] = gen_rtx (MEM, DFmode,
3862 gen_rtx (PLUS, Pmode,
3863 indx,
3864 GEN_INT ((((rs6000_fpmem_offset & 0xffff) ^ 0x8000) - 0x8000)
3865 + ((WORDS_BIG_ENDIAN) ? 4 : 0))));
3866
3867 return \"{l|lwz} %0,%2\";
3868 }"
3869 [(set_attr "type" "load")])
3870
3871 (define_expand "fixuns_truncdfsi2"
3872 [(set (match_operand:SI 0 "gpc_reg_operand" "")
3873 (unsigned_fix:SI (match_operand:DF 1 "gpc_reg_operand" "")))]
3874 "! TARGET_POWER2 && ! TARGET_POWERPC && TARGET_HARD_FLOAT"
3875 "
3876 {
3877 emit_insn (gen_trunc_call (operands[0], operands[1],
3878 gen_rtx (SYMBOL_REF, Pmode, RS6000_UITRUNC)));
3879 DONE;
3880 }")
3881
3882 (define_expand "trunc_call"
3883 [(parallel [(set (match_operand:SI 0 "" "")
3884 (fix:SI (match_operand:DF 1 "" "")))
3885 (use (match_operand:SI 2 "" ""))])]
3886 "TARGET_HARD_FLOAT"
3887 "
3888 {
3889 rtx insns = gen_trunc_call_rtl (operands[0], operands[1], operands[2]);
3890 rtx first = XVECEXP (insns, 0, 0);
3891 rtx last = XVECEXP (insns, 0, XVECLEN (insns, 0) - 1);
3892
3893 REG_NOTES (first) = gen_rtx (INSN_LIST, REG_LIBCALL, last,
3894 REG_NOTES (first));
3895 REG_NOTES (last) = gen_rtx (INSN_LIST, REG_RETVAL, first, REG_NOTES (last));
3896
3897 emit_insn (insns);
3898 DONE;
3899 }")
3900
3901 (define_expand "trunc_call_rtl"
3902 [(set (reg:DF 33) (match_operand:DF 1 "gpc_reg_operand" ""))
3903 (use (reg:DF 33))
3904 (parallel [(set (reg:SI 3)
3905 (call (mem:SI (match_operand 2 "" "")) (const_int 0)))
3906 (use (const_int 0))
3907 (clobber (scratch:SI))])
3908 (set (match_operand:SI 0 "gpc_reg_operand" "")
3909 (reg:SI 3))]
3910 "TARGET_HARD_FLOAT"
3911 "
3912 {
3913 rs6000_trunc_used = 1;
3914 }")
3915
3916 (define_insn "floatdidf2"
3917 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
3918 (float:DF (match_operand:DI 1 "gpc_reg_operand" "f")))]
3919 "TARGET_POWERPC64 && TARGET_HARD_FLOAT"
3920 "fcfid %0,%1"
3921 [(set_attr "type" "fp")])
3922
3923 (define_insn "fix_truncdfdi2"
3924 [(set (match_operand:DI 0 "gpc_reg_operand" "=f")
3925 (fix:DI (match_operand:DF 1 "gpc_reg_operand" "f")))]
3926 "TARGET_POWERPC64 && TARGET_HARD_FLOAT"
3927 "fctidz %0,%1"
3928 [(set_attr "type" "fp")])
3929 \f
3930 ;; Define the DImode operations that can be done in a small number
3931 ;; of instructions. The & constraints are to prevent the register
3932 ;; allocator from allocating registers that overlap with the inputs
3933 ;; (for example, having an input in 7,8 and an output in 6,7). We
3934 ;; also allow for the the output being the same as one of the inputs.
3935
3936 (define_insn "*adddi3_noppc64"
3937 [(set (match_operand:DI 0 "gpc_reg_operand" "=&r,&r,r,r")
3938 (plus:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,0,0")
3939 (match_operand:DI 2 "reg_or_short_operand" "r,I,r,I")))]
3940 "! TARGET_POWERPC64"
3941 "*
3942 {
3943 if (WORDS_BIG_ENDIAN)
3944 return (GET_CODE (operands[2])) != CONST_INT
3945 ? \"{a|addc} %L0,%L1,%L2\;{ae|adde} %0,%1,%2\"
3946 : \"{ai|addic} %L0,%L1,%2\;{a%G2e|add%G2e} %0,%1\";
3947 else
3948 return (GET_CODE (operands[2])) != CONST_INT
3949 ? \"{a|addc} %0,%1,%2\;{ae|adde} %L0,%L1,%L2\"
3950 : \"{ai|addic} %0,%1,%2\;{a%G2e|add%G2e} %L0,%L1\";
3951 }"
3952 [(set_attr "length" "8")])
3953
3954 (define_insn "*subdi3_noppc64"
3955 [(set (match_operand:DI 0 "gpc_reg_operand" "=&r,&r,r,r,r")
3956 (minus:DI (match_operand:DI 1 "reg_or_short_operand" "r,I,0,r,I")
3957 (match_operand:DI 2 "gpc_reg_operand" "r,r,r,0,0")))]
3958 "! TARGET_POWERPC64"
3959 "*
3960 {
3961 if (WORDS_BIG_ENDIAN)
3962 return (GET_CODE (operands[1]) != CONST_INT)
3963 ? \"{sf|subfc} %L0,%L2,%L1\;{sfe|subfe} %0,%2,%1\"
3964 : \"{sfi|subfic} %L0,%L2,%1\;{sf%G1e|subf%G1e} %0,%2\";
3965 else
3966 return (GET_CODE (operands[1]) != CONST_INT)
3967 ? \"{sf|subfc} %0,%2,%1\;{sfe|subfe} %L0,%L2,%L1\"
3968 : \"{sfi|subfic} %0,%2,%1\;{sf%G1e|subf%G1e} %L0,%L2\";
3969 }"
3970 [(set_attr "length" "8")])
3971
3972 (define_insn "*negdi2_noppc64"
3973 [(set (match_operand:DI 0 "gpc_reg_operand" "=&r,r")
3974 (neg:DI (match_operand:DI 1 "gpc_reg_operand" "r,0")))]
3975 "! TARGET_POWERPC64"
3976 "*
3977 {
3978 return (WORDS_BIG_ENDIAN)
3979 ? \"{sfi|subfic} %L0,%L1,0\;{sfze|subfze} %0,%1\"
3980 : \"{sfi|subfic} %0,%1,0\;{sfze|subfze} %L0,%L1\";
3981 }"
3982 [(set_attr "length" "8")])
3983
3984 (define_expand "mulsidi3"
3985 [(set (match_operand:DI 0 "gpc_reg_operand" "")
3986 (mult:DI (sign_extend:DI (match_operand:SI 1 "gpc_reg_operand" ""))
3987 (sign_extend:DI (match_operand:SI 2 "gpc_reg_operand" ""))))]
3988 ""
3989 "
3990 {
3991 if (! TARGET_POWER && ! TARGET_POWERPC)
3992 {
3993 emit_move_insn (gen_rtx (REG, SImode, 3), operands[1]);
3994 emit_move_insn (gen_rtx (REG, SImode, 4), operands[2]);
3995 emit_insn (gen_mull_call ());
3996 if (WORDS_BIG_ENDIAN)
3997 emit_move_insn (operands[0], gen_rtx (REG, DImode, 3));
3998 else
3999 {
4000 emit_move_insn (operand_subword (operands[0], 0, 0, DImode),
4001 gen_rtx (REG, SImode, 3));
4002 emit_move_insn (operand_subword (operands[0], 1, 0, DImode),
4003 gen_rtx (REG, SImode, 4));
4004 }
4005 DONE;
4006 }
4007 else if (TARGET_POWER)
4008 {
4009 emit_insn (gen_mulsidi3_mq (operands[0], operands[1], operands[2]));
4010 DONE;
4011 }
4012 }")
4013
4014 (define_insn "mulsidi3_mq"
4015 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4016 (mult:DI (sign_extend:DI (match_operand:SI 1 "gpc_reg_operand" "%r"))
4017 (sign_extend:DI (match_operand:SI 2 "gpc_reg_operand" "r"))))
4018 (clobber (match_scratch:SI 3 "=q"))]
4019 "TARGET_POWER"
4020 "mul %0,%1,%2\;mfmq %L0"
4021 [(set_attr "type" "imul")
4022 (set_attr "length" "8")])
4023
4024 (define_insn "*mulsidi3_powerpc"
4025 [(set (match_operand:DI 0 "gpc_reg_operand" "=&r")
4026 (mult:DI (sign_extend:DI (match_operand:SI 1 "gpc_reg_operand" "%r"))
4027 (sign_extend:DI (match_operand:SI 2 "gpc_reg_operand" "r"))))]
4028 "TARGET_POWERPC && ! TARGET_POWERPC64"
4029 "*
4030 {
4031 return (WORDS_BIG_ENDIAN)
4032 ? \"mulhw %0,%1,%2\;mullw %L0,%1,%2\"
4033 : \"mulhw %L0,%1,%2\;mullw %0,%1,%2\";
4034 }"
4035 [(set_attr "type" "imul")
4036 (set_attr "length" "8")])
4037
4038 (define_split
4039 [(set (match_operand:DI 0 "gpc_reg_operand" "")
4040 (mult:DI (sign_extend:DI (match_operand:SI 1 "gpc_reg_operand" ""))
4041 (sign_extend:DI (match_operand:SI 2 "gpc_reg_operand" ""))))]
4042 "TARGET_POWERPC && ! TARGET_POWERPC64 && reload_completed"
4043 [(set (match_dup 3)
4044 (truncate:SI
4045 (lshiftrt:DI (mult:DI (sign_extend:DI (match_dup 1))
4046 (sign_extend:DI (match_dup 2)))
4047 (const_int 32))))
4048 (set (match_dup 4)
4049 (mult:SI (match_dup 1)
4050 (match_dup 2)))]
4051 "
4052 {
4053 int endian = (WORDS_BIG_ENDIAN == 0);
4054 operands[3] = operand_subword (operands[0], endian, 0, DImode);
4055 operands[4] = operand_subword (operands[0], 1 - endian, 0, DImode);
4056 }")
4057
4058 (define_insn "umulsidi3"
4059 [(set (match_operand:DI 0 "gpc_reg_operand" "=&r")
4060 (mult:DI (zero_extend:DI (match_operand:SI 1 "gpc_reg_operand" "%r"))
4061 (zero_extend:DI (match_operand:SI 2 "gpc_reg_operand" "r"))))]
4062 "TARGET_POWERPC && ! TARGET_POWERPC64"
4063 "*
4064 {
4065 return (WORDS_BIG_ENDIAN)
4066 ? \"mulhwu %0,%1,%2\;mullw %L0,%1,%2\"
4067 : \"mulhwu %L0,%1,%2\;mullw %0,%1,%2\";
4068 }"
4069 [(set_attr "type" "imul")
4070 (set_attr "length" "8")])
4071
4072 (define_split
4073 [(set (match_operand:DI 0 "gpc_reg_operand" "")
4074 (mult:DI (zero_extend:DI (match_operand:SI 1 "gpc_reg_operand" ""))
4075 (zero_extend:DI (match_operand:SI 2 "gpc_reg_operand" ""))))]
4076 "TARGET_POWERPC && ! TARGET_POWERPC64 && reload_completed"
4077 [(set (match_dup 3)
4078 (truncate:SI
4079 (lshiftrt:DI (mult:DI (zero_extend:DI (match_dup 1))
4080 (zero_extend:DI (match_dup 2)))
4081 (const_int 32))))
4082 (set (match_dup 4)
4083 (mult:SI (match_dup 1)
4084 (match_dup 2)))]
4085 "
4086 {
4087 int endian = (WORDS_BIG_ENDIAN == 0);
4088 operands[3] = operand_subword (operands[0], endian, 0, DImode);
4089 operands[4] = operand_subword (operands[0], 1 - endian, 0, DImode);
4090 }")
4091
4092 (define_expand "smulsi3_highpart"
4093 [(set (match_operand:SI 0 "gpc_reg_operand" "")
4094 (truncate:SI
4095 (lshiftrt:DI (mult:DI (sign_extend:DI
4096 (match_operand:SI 1 "gpc_reg_operand" "%r"))
4097 (sign_extend:DI
4098 (match_operand:SI 2 "gpc_reg_operand" "r")))
4099 (const_int 32))))]
4100 ""
4101 "
4102 {
4103 if (! TARGET_POWER && ! TARGET_POWERPC)
4104 {
4105 emit_move_insn (gen_rtx (REG, SImode, 3), operands[1]);
4106 emit_move_insn (gen_rtx (REG, SImode, 4), operands[2]);
4107 emit_insn (gen_mulh_call ());
4108 emit_move_insn (operands[0], gen_rtx (REG, SImode, 3));
4109 DONE;
4110 }
4111 else if (TARGET_POWER)
4112 {
4113 emit_insn (gen_smulsi3_highpart_mq (operands[0], operands[1], operands[2]));
4114 DONE;
4115 }
4116 }")
4117
4118 (define_insn "smulsi3_highpart_mq"
4119 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
4120 (truncate:SI
4121 (lshiftrt:DI (mult:DI (sign_extend:DI
4122 (match_operand:SI 1 "gpc_reg_operand" "%r"))
4123 (sign_extend:DI
4124 (match_operand:SI 2 "gpc_reg_operand" "r")))
4125 (const_int 32))))
4126 (clobber (match_scratch:SI 3 "=q"))]
4127 "TARGET_POWER"
4128 "mul %0,%1,%2"
4129 [(set_attr "type" "imul")])
4130
4131 (define_insn ""
4132 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
4133 (truncate:SI
4134 (lshiftrt:DI (mult:DI (sign_extend:DI
4135 (match_operand:SI 1 "gpc_reg_operand" "%r"))
4136 (sign_extend:DI
4137 (match_operand:SI 2 "gpc_reg_operand" "r")))
4138 (const_int 32))))]
4139 "TARGET_POWERPC"
4140 "mulhw %0,%1,%2"
4141 [(set_attr "type" "imul")])
4142
4143 (define_insn "umulsi3_highpart"
4144 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
4145 (truncate:SI
4146 (lshiftrt:DI (mult:DI (zero_extend:DI
4147 (match_operand:SI 1 "gpc_reg_operand" "%r"))
4148 (zero_extend:DI
4149 (match_operand:SI 2 "gpc_reg_operand" "r")))
4150 (const_int 32))))]
4151 "TARGET_POWERPC"
4152 "mulhwu %0,%1,%2"
4153 [(set_attr "type" "imul")])
4154
4155 ;; If operands 0 and 2 are in the same register, we have a problem. But
4156 ;; operands 0 and 1 (the usual case) can be in the same register. That's
4157 ;; why we have the strange constraints below.
4158 (define_insn "ashldi3_power"
4159 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,&r")
4160 (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,0,r")
4161 (match_operand:SI 2 "reg_or_cint_operand" "M,i,r,r")))
4162 (clobber (match_scratch:SI 3 "=X,q,q,q"))]
4163 "TARGET_POWER"
4164 "@
4165 {sli|slwi} %0,%L1,%h2\;{cal %L0,0(0)|li %L0,0}
4166 sl%I2q %L0,%L1,%h2\;sll%I2q %0,%1,%h2
4167 sl%I2q %L0,%L1,%h2\;sll%I2q %0,%1,%h2
4168 sl%I2q %L0,%L1,%h2\;sll%I2q %0,%1,%h2"
4169 [(set_attr "length" "8")])
4170
4171 (define_insn "lshrdi3_power"
4172 [(set (match_operand:DI 0 "gpc_reg_operand" "=&r,r,r,&r")
4173 (lshiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,0,r")
4174 (match_operand:SI 2 "reg_or_cint_operand" "M,i,r,r")))
4175 (clobber (match_scratch:SI 3 "=X,q,q,q"))]
4176 "TARGET_POWER"
4177 "@
4178 {cal %0,0(0)|li %0,0}\;{s%A2i|s%A2wi} %L0,%1,%h2
4179 sr%I2q %0,%1,%h2\;srl%I2q %L0,%L1,%h2
4180 sr%I2q %0,%1,%h2\;srl%I2q %L0,%L1,%h2
4181 sr%I2q %0,%1,%h2\;srl%I2q %L0,%L1,%h2"
4182 [(set_attr "length" "8")])
4183
4184 ;; Shift by a variable amount is too complex to be worth open-coding. We
4185 ;; just handle shifts by constants.
4186 (define_insn "ashrdi3_power"
4187 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
4188 (ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
4189 (match_operand:SI 2 "const_int_operand" "M,i")))
4190 (clobber (match_scratch:SI 3 "=X,q"))]
4191 "TARGET_POWER"
4192 "@
4193 {srai|srawi} %0,%1,31\;{srai|srawi} %L0,%1,%h2
4194 sraiq %0,%1,%h2\;srliq %L0,%L1,%h2"
4195 [(set_attr "length" "8")])
4196 \f
4197 ;; PowerPC64 DImode operations.
4198
4199 (define_expand "adddi3"
4200 [(set (match_operand:DI 0 "gpc_reg_operand" "")
4201 (plus:DI (match_operand:DI 1 "gpc_reg_operand" "")
4202 (match_operand:DI 2 "add_operand" "")))]
4203 ""
4204 "
4205 {
4206 if (! TARGET_POWERPC64 && non_add_cint_operand (operands[2], DImode))
4207 FAIL;
4208 }")
4209
4210 ;; Discourage ai/addic because of carry but provide it in an alternative
4211 ;; allowing register zero as source.
4212
4213 (define_insn ""
4214 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,?r,r")
4215 (plus:DI (match_operand:DI 1 "gpc_reg_operand" "%r,b,r,b")
4216 (match_operand:DI 2 "add_operand" "r,I,I,J")))]
4217 "TARGET_POWERPC64"
4218 "@
4219 add %0,%1,%2
4220 addi %0,%1,%2
4221 addic %0,%1,%2
4222 addis %0,%1,%v2")
4223
4224 (define_insn ""
4225 [(set (match_operand:CC 0 "cc_reg_operand" "=x,x")
4226 (compare:CC (plus:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r")
4227 (match_operand:DI 2 "reg_or_short_operand" "r,I"))
4228 (const_int 0)))
4229 (clobber (match_scratch:DI 3 "=r,r"))]
4230 "TARGET_POWERPC64"
4231 "@
4232 add. %3,%1,%2
4233 addic. %3,%1,%2"
4234 [(set_attr "type" "compare")])
4235
4236 (define_insn ""
4237 [(set (match_operand:CC 3 "cc_reg_operand" "=x,x")
4238 (compare:CC (plus:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r")
4239 (match_operand:DI 2 "reg_or_short_operand" "r,I"))
4240 (const_int 0)))
4241 (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
4242 (plus:DI (match_dup 1) (match_dup 2)))]
4243 "TARGET_POWERPC64"
4244 "@
4245 add. %0,%1,%2
4246 addic. %0,%1,%2"
4247 [(set_attr "type" "compare")])
4248
4249 ;; Split an add that we can't do in one insn into two insns, each of which
4250 ;; does one 16-bit part. This is used by combine. Note that the low-order
4251 ;; add should be last in case the result gets used in an address.
4252
4253 (define_split
4254 [(set (match_operand:DI 0 "gpc_reg_operand" "")
4255 (plus:DI (match_operand:DI 1 "gpc_reg_operand" "")
4256 (match_operand:DI 2 "non_add_cint_operand" "")))]
4257 "TARGET_POWERPC64"
4258 [(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 3)))
4259 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 4)))]
4260 "
4261 {
4262 HOST_WIDE_INT low = INTVAL (operands[2]) & 0xffff;
4263 HOST_WIDE_INT high = INTVAL (operands[2]) & (~ (HOST_WIDE_INT) 0xffff);
4264
4265 if (low & 0x8000)
4266 high+=0x10000, low |= ((HOST_WIDE_INT) -1) << 16;
4267
4268 operands[3] = GEN_INT (high);
4269 operands[4] = GEN_INT (low);
4270 }")
4271
4272 (define_insn "one_cmpldi2"
4273 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4274 (not:DI (match_operand:DI 1 "gpc_reg_operand" "r")))]
4275 "TARGET_POWERPC64"
4276 "nor %0,%1,%1")
4277
4278 (define_insn ""
4279 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
4280 (compare:CC (not:DI (match_operand:DI 1 "gpc_reg_operand" "r"))
4281 (const_int 0)))
4282 (clobber (match_scratch:DI 2 "=r"))]
4283 "TARGET_POWERPC64"
4284 "nor. %2,%1,%1"
4285 [(set_attr "type" "compare")])
4286
4287 (define_insn ""
4288 [(set (match_operand:CC 2 "cc_reg_operand" "=x")
4289 (compare:CC (not:DI (match_operand:DI 1 "gpc_reg_operand" "r"))
4290 (const_int 0)))
4291 (set (match_operand:DI 0 "gpc_reg_operand" "=r")
4292 (not:DI (match_dup 1)))]
4293 "TARGET_POWERPC64"
4294 "nor. %0,%1,%1"
4295 [(set_attr "type" "compare")])
4296
4297 (define_insn ""
4298 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
4299 (minus:DI (match_operand:DI 1 "reg_or_short_operand" "r,I")
4300 (match_operand:DI 2 "gpc_reg_operand" "r,r")))]
4301 "TARGET_POWERPC64"
4302 "@
4303 subf %0,%2,%1
4304 subfic %0,%2,%1")
4305
4306 (define_insn ""
4307 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
4308 (compare:CC (minus:DI (match_operand:DI 1 "gpc_reg_operand" "r")
4309 (match_operand:DI 2 "gpc_reg_operand" "r"))
4310 (const_int 0)))
4311 (clobber (match_scratch:DI 3 "=r"))]
4312 "TARGET_POWERPC64"
4313 "subf. %3,%2,%1"
4314 [(set_attr "type" "compare")])
4315
4316 (define_insn ""
4317 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
4318 (compare:CC (minus:DI (match_operand:DI 1 "gpc_reg_operand" "r")
4319 (match_operand:DI 2 "gpc_reg_operand" "r"))
4320 (const_int 0)))
4321 (set (match_operand:DI 0 "gpc_reg_operand" "=r")
4322 (minus:DI (match_dup 1) (match_dup 2)))]
4323 "TARGET_POWERPC64"
4324 "subf. %0,%2,%1"
4325 [(set_attr "type" "compare")])
4326
4327 (define_expand "subdi3"
4328 [(set (match_operand:DI 0 "gpc_reg_operand" "")
4329 (minus:DI (match_operand:DI 1 "reg_or_short_operand" "")
4330 (match_operand:DI 2 "reg_or_cint_operand" "")))]
4331 ""
4332 "
4333 {
4334 if (GET_CODE (operands[2]) == CONST_INT)
4335 {
4336 emit_insn (gen_adddi3 (operands[0], operands[1],
4337 negate_rtx (DImode, operands[2])));
4338 DONE;
4339 }
4340 }")
4341
4342 (define_insn "absdi2"
4343 [(set (match_operand:DI 0 "gpc_reg_operand" "=&r,r")
4344 (abs:DI (match_operand:DI 1 "gpc_reg_operand" "r,0")))
4345 (clobber (match_scratch:DI 2 "=&r,&r"))]
4346 "TARGET_POWERPC64"
4347 "sradi %2,%1,31\;xor %0,%2,%1\;subf %0,%2,%0"
4348 [(set_attr "length" "12")])
4349
4350 (define_split
4351 [(set (match_operand:DI 0 "gpc_reg_operand" "=&r,r")
4352 (abs:DI (match_operand:DI 1 "gpc_reg_operand" "r,0")))
4353 (clobber (match_scratch:DI 2 "=&r,&r"))]
4354 "TARGET_POWERPC64 && reload_completed"
4355 [(set (match_dup 2) (ashiftrt:DI (match_dup 1) (const_int 31)))
4356 (set (match_dup 0) (xor:DI (match_dup 2) (match_dup 1)))
4357 (set (match_dup 0) (minus:DI (match_dup 2) (match_dup 0)))]
4358 "")
4359
4360 (define_insn ""
4361 [(set (match_operand:DI 0 "gpc_reg_operand" "=&r,r")
4362 (neg:DI (abs:DI (match_operand:DI 1 "gpc_reg_operand" "r,0"))))
4363 (clobber (match_scratch:DI 2 "=&r,&r"))]
4364 "TARGET_POWERPC64"
4365 "sradi %2,%1,31\;xor %0,%2,%1\;subf %0,%0,%2"
4366 [(set_attr "length" "12")])
4367
4368 (define_split
4369 [(set (match_operand:DI 0 "gpc_reg_operand" "=&r,r")
4370 (neg:DI (abs:DI (match_operand:DI 1 "gpc_reg_operand" "r,0"))))
4371 (clobber (match_scratch:DI 2 "=&r,&r"))]
4372 "TARGET_POWERPC64 && reload_completed"
4373 [(set (match_dup 2) (ashiftrt:DI (match_dup 1) (const_int 31)))
4374 (set (match_dup 0) (xor:DI (match_dup 2) (match_dup 1)))
4375 (set (match_dup 0) (minus:DI (match_dup 0) (match_dup 2)))]
4376 "")
4377
4378 (define_expand "negdi2"
4379 [(set (match_operand:DI 0 "gpc_reg_operand" "")
4380 (neg:DI (match_operand:DI 1 "gpc_reg_operand" "")))]
4381 ""
4382 "")
4383
4384 (define_insn ""
4385 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4386 (neg:DI (match_operand:DI 1 "gpc_reg_operand" "r")))]
4387 "TARGET_POWERPC64"
4388 "neg %0,%1")
4389
4390 (define_insn ""
4391 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
4392 (compare:CC (neg:DI (match_operand:DI 1 "gpc_reg_operand" "r"))
4393 (const_int 0)))
4394 (clobber (match_scratch:DI 2 "=r"))]
4395 "TARGET_POWERPC64"
4396 "neg. %2,%1"
4397 [(set_attr "type" "compare")])
4398
4399 (define_insn ""
4400 [(set (match_operand:CC 2 "cc_reg_operand" "=x")
4401 (compare:CC (neg:DI (match_operand:DI 1 "gpc_reg_operand" "r"))
4402 (const_int 0)))
4403 (set (match_operand:DI 0 "gpc_reg_operand" "=r")
4404 (neg:DI (match_dup 1)))]
4405 "TARGET_POWERPC64"
4406 "neg. %0,%1"
4407 [(set_attr "type" "compare")])
4408
4409 (define_insn "ffsdi2"
4410 [(set (match_operand:DI 0 "gpc_reg_operand" "=&r")
4411 (ffs:DI (match_operand:DI 1 "gpc_reg_operand" "r")))]
4412 "TARGET_POWERPC64"
4413 "neg %0,%1\;and %0,%0,%1\;cntlzd %0,%0\;subfic %0,%0,64"
4414 [(set_attr "length" "16")])
4415
4416 (define_insn "muldi3"
4417 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4418 (mult:DI (match_operand:DI 1 "gpc_reg_operand" "%r")
4419 (match_operand:DI 2 "gpc_reg_operand" "r")))]
4420 "TARGET_POWERPC64"
4421 "mulld %0,%1,%2"
4422 [(set_attr "type" "imul")])
4423
4424 (define_insn "smuldi3_highpart"
4425 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4426 (truncate:DI
4427 (lshiftrt:TI (mult:TI (sign_extend:TI
4428 (match_operand:DI 1 "gpc_reg_operand" "%r"))
4429 (sign_extend:TI
4430 (match_operand:DI 2 "gpc_reg_operand" "r")))
4431 (const_int 64))))]
4432 "TARGET_POWERPC64"
4433 "mulhd %0,%1,%2"
4434 [(set_attr "type" "imul")])
4435
4436 (define_insn "umuldi3_highpart"
4437 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4438 (truncate:DI
4439 (lshiftrt:TI (mult:TI (zero_extend:TI
4440 (match_operand:DI 1 "gpc_reg_operand" "%r"))
4441 (zero_extend:TI
4442 (match_operand:DI 2 "gpc_reg_operand" "r")))
4443 (const_int 64))))]
4444 "TARGET_POWERPC64"
4445 "mulhdu %0,%1,%2"
4446 [(set_attr "type" "imul")])
4447
4448 (define_expand "divdi3"
4449 [(set (match_operand:DI 0 "gpc_reg_operand" "")
4450 (div:DI (match_operand:DI 1 "gpc_reg_operand" "")
4451 (match_operand:DI 2 "reg_or_cint_operand" "")))]
4452 "TARGET_POWERPC64"
4453 "
4454 {
4455 if (GET_CODE (operands[2]) == CONST_INT
4456 && exact_log2 (INTVAL (operands[2])) >= 0)
4457 ;
4458 else
4459 operands[2] = force_reg (DImode, operands[2]);
4460 }")
4461
4462 (define_expand "moddi3"
4463 [(use (match_operand:DI 0 "gpc_reg_operand" ""))
4464 (use (match_operand:DI 1 "gpc_reg_operand" ""))
4465 (use (match_operand:DI 2 "reg_or_cint_operand" ""))]
4466 "TARGET_POWERPC64"
4467 "
4468 {
4469 int i = exact_log2 (INTVAL (operands[2]));
4470 rtx temp1;
4471 rtx temp2;
4472
4473 if (GET_CODE (operands[2]) != CONST_INT || i < 0)
4474 FAIL;
4475
4476 temp1 = gen_reg_rtx (DImode);
4477 temp2 = gen_reg_rtx (DImode);
4478
4479 emit_insn (gen_divdi3 (temp1, operands[1], operands[2]));
4480 emit_insn (gen_ashldi3 (temp2, temp1, GEN_INT (i)));
4481 emit_insn (gen_subdi3 (operands[0], operands[1], temp2));
4482 DONE;
4483 }")
4484
4485 (define_insn ""
4486 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4487 (div:DI (match_operand:DI 1 "gpc_reg_operand" "r")
4488 (match_operand:DI 2 "const_int_operand" "N")))]
4489 "TARGET_POWERPC64 && exact_log2 (INTVAL (operands[2])) >= 0"
4490 "sradi %0,%1,%p2\;addze %0,%0"
4491 [(set_attr "length" "8")])
4492
4493 (define_insn ""
4494 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
4495 (compare:CC (div:DI (match_operand:DI 1 "gpc_reg_operand" "r")
4496 (match_operand:DI 2 "const_int_operand" "N"))
4497 (const_int 0)))
4498 (clobber (match_scratch:DI 3 "=r"))]
4499 "TARGET_POWERPC64 && exact_log2 (INTVAL (operands[2])) >= 0"
4500 "sradi %3,%1,%p2\;addze. %3,%3"
4501 [(set_attr "type" "compare")
4502 (set_attr "length" "8")])
4503
4504 (define_insn ""
4505 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
4506 (compare:CC (div:DI (match_operand:DI 1 "gpc_reg_operand" "r")
4507 (match_operand:DI 2 "const_int_operand" "N"))
4508 (const_int 0)))
4509 (set (match_operand:DI 0 "gpc_reg_operand" "=r")
4510 (div:DI (match_dup 1) (match_dup 2)))]
4511 "TARGET_POWERPC64 && exact_log2 (INTVAL (operands[2])) >= 0"
4512 "sradi %0,%1,%p2\;addze. %0,%0"
4513 [(set_attr "type" "compare")
4514 (set_attr "length" "8")])
4515
4516 (define_insn ""
4517 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4518 (div:DI (match_operand:DI 1 "gpc_reg_operand" "r")
4519 (match_operand:DI 2 "gpc_reg_operand" "r")))]
4520 "TARGET_POWERPC64"
4521 "divd %0,%1,%2"
4522 [(set_attr "type" "idiv")])
4523
4524 (define_insn "udivdi3"
4525 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4526 (udiv:DI (match_operand:DI 1 "gpc_reg_operand" "r")
4527 (match_operand:DI 2 "gpc_reg_operand" "r")))]
4528 "TARGET_POWERPC64"
4529 "divdu %0,%1,%2"
4530 [(set_attr "type" "idiv")])
4531
4532 (define_insn "rotldi3"
4533 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4534 (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r")
4535 (match_operand:DI 2 "reg_or_cint_operand" "ri")))]
4536 "TARGET_POWERPC64"
4537 "rld%I2cl %0,%1,%H2,0")
4538
4539 (define_insn ""
4540 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
4541 (compare:CC (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r")
4542 (match_operand:DI 2 "reg_or_cint_operand" "ri"))
4543 (const_int 0)))
4544 (clobber (match_scratch:DI 3 "=r"))]
4545 "TARGET_POWERPC64"
4546 "rld%I2cl. %3,%1,%H2,0"
4547 [(set_attr "type" "delayed_compare")])
4548
4549 (define_insn ""
4550 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
4551 (compare:CC (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r")
4552 (match_operand:DI 2 "reg_or_cint_operand" "ri"))
4553 (const_int 0)))
4554 (set (match_operand:DI 0 "gpc_reg_operand" "=r")
4555 (rotate:DI (match_dup 1) (match_dup 2)))]
4556 "TARGET_POWERPC64"
4557 "rld%I2cl. %0,%1,%H2,0"
4558 [(set_attr "type" "delayed_compare")])
4559
4560 (define_expand "ashldi3"
4561 [(set (match_operand:DI 0 "gpc_reg_operand" "")
4562 (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "")
4563 (match_operand:SI 2 "reg_or_cint_operand" "")))]
4564 "TARGET_POWERPC64 || TARGET_POWER"
4565 "
4566 {
4567 if (TARGET_POWERPC64)
4568 ;
4569 else if (TARGET_POWER)
4570 {
4571 emit_insn (gen_ashldi3_power (operands[0], operands[1], operands[2]));
4572 DONE;
4573 }
4574 else
4575 FAIL;
4576 }")
4577
4578 (define_insn ""
4579 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4580 (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r")
4581 (match_operand:SI 2 "reg_or_cint_operand" "ri")))]
4582 "TARGET_POWERPC64"
4583 "sld%I2 %0,%1,%H2"
4584 [(set_attr "length" "8")])
4585
4586 (define_insn ""
4587 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
4588 (compare:CC (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r")
4589 (match_operand:SI 2 "reg_or_cint_operand" "ri"))
4590 (const_int 0)))
4591 (clobber (match_scratch:DI 3 "=r"))]
4592 "TARGET_POWERPC64"
4593 "sld%I2. %3,%1,%H2"
4594 [(set_attr "type" "delayed_compare")])
4595
4596 (define_insn ""
4597 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
4598 (compare:CC (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r")
4599 (match_operand:SI 2 "reg_or_cint_operand" "ri"))
4600 (const_int 0)))
4601 (set (match_operand:DI 0 "gpc_reg_operand" "=r")
4602 (ashift:DI (match_dup 1) (match_dup 2)))]
4603 "TARGET_POWERPC64"
4604 "sld%I2. %0,%1,%H2"
4605 [(set_attr "type" "delayed_compare")])
4606
4607 (define_expand "lshrdi3"
4608 [(set (match_operand:DI 0 "gpc_reg_operand" "")
4609 (lshiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "")
4610 (match_operand:SI 2 "reg_or_cint_operand" "")))]
4611 "TARGET_POWERPC64 || TARGET_POWER"
4612 "
4613 {
4614 if (TARGET_POWERPC64)
4615 ;
4616 else if (TARGET_POWER)
4617 {
4618 emit_insn (gen_lshrdi3_power (operands[0], operands[1], operands[2]));
4619 DONE;
4620 }
4621 else
4622 FAIL;
4623 }")
4624
4625 (define_insn ""
4626 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4627 (lshiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r")
4628 (match_operand:SI 2 "reg_or_cint_operand" "ri")))]
4629 "TARGET_POWERPC64"
4630 "srd%I2 %0,%1,%H2")
4631
4632 (define_insn ""
4633 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
4634 (compare:CC (lshiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r")
4635 (match_operand:SI 2 "reg_or_cint_operand" "ri"))
4636 (const_int 0)))
4637 (clobber (match_scratch:DI 3 "=r"))]
4638 "TARGET_POWERPC64"
4639 "srd%I2. %3,%1,%H2"
4640 [(set_attr "type" "delayed_compare")])
4641
4642 (define_insn ""
4643 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
4644 (compare:CC (lshiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r")
4645 (match_operand:SI 2 "reg_or_cint_operand" "ri"))
4646 (const_int 0)))
4647 (set (match_operand:DI 0 "gpc_reg_operand" "=r")
4648 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
4649 "TARGET_POWERPC64"
4650 "srd%I2. %0,%1,%H2"
4651 [(set_attr "type" "delayed_compare")])
4652
4653 (define_expand "ashrdi3"
4654 [(set (match_operand:DI 0 "gpc_reg_operand" "")
4655 (ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "")
4656 (match_operand:SI 2 "reg_or_cint_operand" "")))]
4657 "TARGET_POWERPC64 || TARGET_POWER"
4658 "
4659 {
4660 if (TARGET_POWERPC64)
4661 ;
4662 else if (TARGET_POWER && GET_CODE (operands[2]) == CONST_INT)
4663 {
4664 emit_insn (gen_ashrdi3_power (operands[0], operands[1], operands[2]));
4665 DONE;
4666 }
4667 else
4668 FAIL;
4669 }")
4670
4671 (define_insn ""
4672 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4673 (ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r")
4674 (match_operand:SI 2 "reg_or_cint_operand" "ri")))]
4675 "TARGET_POWERPC64"
4676 "srad%I2 %0,%1,%H2")
4677
4678 (define_insn ""
4679 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
4680 (compare:CC (ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r")
4681 (match_operand:SI 2 "reg_or_cint_operand" "ri"))
4682 (const_int 0)))
4683 (clobber (match_scratch:DI 3 "=r"))]
4684 "TARGET_POWERPC64"
4685 "srad%I2. %3,%1,%H2"
4686 [(set_attr "type" "delayed_compare")])
4687
4688 (define_insn ""
4689 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
4690 (compare:CC (ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r")
4691 (match_operand:SI 2 "reg_or_cint_operand" "ri"))
4692 (const_int 0)))
4693 (set (match_operand:DI 0 "gpc_reg_operand" "=r")
4694 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
4695 "TARGET_POWERPC64"
4696 "srad%I2. %0,%1,%H2"
4697 [(set_attr "type" "delayed_compare")])
4698
4699 (define_insn "anddi3"
4700 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r")
4701 (and:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,r")
4702 (match_operand:DI 2 "and_operand" "?r,K,J")))
4703 (clobber (match_scratch:CC 3 "=X,x,x"))]
4704 "TARGET_POWERPC64"
4705 "@
4706 and %0,%1,%2
4707 andi. %0,%1,%b2
4708 andis. %0,%1,%u2")
4709
4710 (define_insn ""
4711 [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,x")
4712 (compare:CC (and:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,r")
4713 (match_operand:DI 2 "and_operand" "r,K,J"))
4714 (const_int 0)))
4715 (clobber (match_scratch:DI 3 "=r,r,r"))]
4716 "TARGET_POWERPC64"
4717 "@
4718 and. %3,%1,%2
4719 andi. %3,%1,%b2
4720 andis. %3,%1,%u2"
4721 [(set_attr "type" "compare,compare,compare")])
4722
4723 (define_insn ""
4724 [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,x")
4725 (compare:CC (and:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,r")
4726 (match_operand:DI 2 "and_operand" "r,K,J"))
4727 (const_int 0)))
4728 (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r")
4729 (and:DI (match_dup 1) (match_dup 2)))]
4730 "TARGET_POWERPC64"
4731 "@
4732 and. %0,%1,%2
4733 andi. %0,%1,%b2
4734 andis. %0,%1,%u2"
4735 [(set_attr "type" "compare,compare,compare")])
4736
4737 ;; Take a AND with a constant that cannot be done in a single insn and try to
4738 ;; split it into two insns. This does not verify that the insns are valid
4739 ;; since this need not be done as combine will do it.
4740
4741 (define_split
4742 [(set (match_operand:DI 0 "gpc_reg_operand" "")
4743 (and:DI (match_operand:DI 1 "gpc_reg_operand" "")
4744 (match_operand:DI 2 "non_and_cint_operand" "")))]
4745 "TARGET_POWERPC64"
4746 [(set (match_dup 0) (and:DI (match_dup 1) (match_dup 3)))
4747 (set (match_dup 0) (and:DI (match_dup 0) (match_dup 4)))]
4748 "
4749 {
4750 int maskval = INTVAL (operands[2]);
4751 int i, transitions, last_bit_value;
4752 int orig = maskval, first_c = maskval, second_c;
4753
4754 /* We know that MASKVAL must have more than 2 bit-transitions. Start at
4755 the low-order bit and count for the third transition. When we get there,
4756 make a first mask that has everything to the left of that position
4757 a one. Then make the second mask to turn off whatever else is needed. */
4758
4759 for (i = 1, transitions = 0, last_bit_value = maskval & 1; i < 32; i++)
4760 {
4761 if (((maskval >>= 1) & 1) != last_bit_value)
4762 last_bit_value ^= 1, transitions++;
4763
4764 if (transitions > 2)
4765 {
4766 first_c |= (~0) << i;
4767 break;
4768 }
4769 }
4770
4771 second_c = orig | ~ first_c;
4772
4773 operands[3] = gen_rtx (CONST_INT, VOIDmode, first_c);
4774 operands[4] = gen_rtx (CONST_INT, VOIDmode, second_c);
4775 }")
4776
4777 (define_insn "iordi3"
4778 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r")
4779 (ior:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,r")
4780 (match_operand:DI 2 "logical_operand" "r,K,J")))]
4781 "TARGET_POWERPC64"
4782 "@
4783 or %0,%1,%2
4784 ori %0,%1,%b2
4785 oris %0,%1,%u2")
4786
4787 (define_insn ""
4788 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
4789 (compare:CC (ior:DI (match_operand:DI 1 "gpc_reg_operand" "%r")
4790 (match_operand:DI 2 "gpc_reg_operand" "r"))
4791 (const_int 0)))
4792 (clobber (match_scratch:DI 3 "=r"))]
4793 "TARGET_POWERPC64"
4794 "or. %3,%1,%2"
4795 [(set_attr "type" "compare")])
4796
4797 (define_insn ""
4798 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
4799 (compare:CC (ior:DI (match_operand:DI 1 "gpc_reg_operand" "%r")
4800 (match_operand:DI 2 "gpc_reg_operand" "r"))
4801 (const_int 0)))
4802 (set (match_operand:DI 0 "gpc_reg_operand" "=r")
4803 (ior:DI (match_dup 1) (match_dup 2)))]
4804 "TARGET_POWERPC64"
4805 "or. %0,%1,%2"
4806 [(set_attr "type" "compare")])
4807
4808 ;; Split an IOR that we can't do in one insn into two insns, each of which
4809 ;; does one 16-bit part. This is used by combine.
4810
4811 (define_split
4812 [(set (match_operand:DI 0 "gpc_reg_operand" "")
4813 (ior:DI (match_operand:DI 1 "gpc_reg_operand" "")
4814 (match_operand:DI 2 "non_logical_cint_operand" "")))]
4815 "TARGET_POWERPC64"
4816 [(set (match_dup 0) (ior:DI (match_dup 1) (match_dup 3)))
4817 (set (match_dup 0) (ior:DI (match_dup 0) (match_dup 4)))]
4818 "
4819 {
4820 operands[3] = gen_rtx (CONST_INT, VOIDmode,
4821 INTVAL (operands[2]) & (~ (HOST_WIDE_INT) 0xffff));
4822 operands[4] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) & 0xffff);
4823 }")
4824
4825 (define_insn "xordi3"
4826 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r")
4827 (xor:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,r")
4828 (match_operand:DI 2 "logical_operand" "r,K,J")))]
4829 "TARGET_POWERPC64"
4830 "@
4831 xor %0,%1,%2
4832 xori %0,%1,%b2
4833 xoris %0,%1,%u2")
4834
4835 (define_insn ""
4836 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
4837 (compare:CC (xor:DI (match_operand:DI 1 "gpc_reg_operand" "%r")
4838 (match_operand:DI 2 "gpc_reg_operand" "r"))
4839 (const_int 0)))
4840 (clobber (match_scratch:DI 3 "=r"))]
4841 "TARGET_POWERPC64"
4842 "xor. %3,%1,%2"
4843 [(set_attr "type" "compare")])
4844
4845 (define_insn ""
4846 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
4847 (compare:CC (xor:DI (match_operand:DI 1 "gpc_reg_operand" "%r")
4848 (match_operand:DI 2 "gpc_reg_operand" "r"))
4849 (const_int 0)))
4850 (set (match_operand:DI 0 "gpc_reg_operand" "=r")
4851 (xor:DI (match_dup 1) (match_dup 2)))]
4852 "TARGET_POWERPC64"
4853 "xor. %0,%1,%2"
4854 [(set_attr "type" "compare")])
4855
4856 ;; Split an XOR that we can't do in one insn into two insns, each of which
4857 ;; does one 16-bit part. This is used by combine.
4858
4859 (define_split
4860 [(set (match_operand:DI 0 "gpc_reg_operand" "")
4861 (xor:DI (match_operand:DI 1 "gpc_reg_operand" "")
4862 (match_operand:DI 2 "non_logical_cint_operand" "")))]
4863 "TARGET_POWERPC64"
4864 [(set (match_dup 0) (xor:DI (match_dup 1) (match_dup 3)))
4865 (set (match_dup 0) (xor:DI (match_dup 0) (match_dup 4)))]
4866 "
4867 {
4868 operands[3] = gen_rtx (CONST_INT, VOIDmode,
4869 INTVAL (operands[2]) & 0xffff0000);
4870 operands[4] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) & 0xffff);
4871 }")
4872
4873 (define_insn ""
4874 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4875 (not:DI (xor:DI (match_operand:DI 1 "gpc_reg_operand" "%r")
4876 (match_operand:DI 2 "gpc_reg_operand" "r"))))]
4877 "TARGET_POWERPC64"
4878 "eqv %0,%1,%2")
4879
4880 (define_insn ""
4881 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
4882 (compare:CC (not:DI (xor:DI (match_operand:DI 1 "gpc_reg_operand" "%r")
4883 (match_operand:DI 2 "gpc_reg_operand" "r")))
4884 (const_int 0)))
4885 (clobber (match_scratch:DI 3 "=r"))]
4886 "TARGET_POWERPC64"
4887 "eqv. %3,%1,%2"
4888 [(set_attr "type" "compare")])
4889
4890 (define_insn ""
4891 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
4892 (compare:CC (not:DI (xor:DI (match_operand:DI 1 "gpc_reg_operand" "%r")
4893 (match_operand:DI 2 "gpc_reg_operand" "r")))
4894 (const_int 0)))
4895 (set (match_operand:DI 0 "gpc_reg_operand" "=r")
4896 (not:DI (xor:DI (match_dup 1) (match_dup 2))))]
4897 "TARGET_POWERPC64"
4898 "eqv. %0,%1,%2"
4899 [(set_attr "type" "compare")])
4900
4901 (define_insn ""
4902 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4903 (and:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "r"))
4904 (match_operand:DI 2 "gpc_reg_operand" "r")))]
4905 "TARGET_POWERPC64"
4906 "andc %0,%2,%1")
4907
4908 (define_insn ""
4909 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
4910 (compare:CC (and:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "r"))
4911 (match_operand:DI 2 "gpc_reg_operand" "r"))
4912 (const_int 0)))
4913 (clobber (match_scratch:DI 3 "=r"))]
4914 "TARGET_POWERPC64"
4915 "andc. %3,%2,%1"
4916 [(set_attr "type" "compare")])
4917
4918 (define_insn ""
4919 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
4920 (compare:CC (and:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "r"))
4921 (match_operand:DI 2 "gpc_reg_operand" "r"))
4922 (const_int 0)))
4923 (set (match_operand:DI 0 "gpc_reg_operand" "=r")
4924 (and:DI (not:DI (match_dup 1)) (match_dup 2)))]
4925 "TARGET_POWERPC64"
4926 "andc. %0,%2,%1"
4927 [(set_attr "type" "compare")])
4928
4929 (define_insn ""
4930 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4931 (ior:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "r"))
4932 (match_operand:DI 2 "gpc_reg_operand" "r")))]
4933 "TARGET_POWERPC64"
4934 "orc %0,%2,%1")
4935
4936 (define_insn ""
4937 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
4938 (compare:CC (ior:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "r"))
4939 (match_operand:DI 2 "gpc_reg_operand" "r"))
4940 (const_int 0)))
4941 (clobber (match_scratch:DI 3 "=r"))]
4942 "TARGET_POWERPC64"
4943 "orc. %3,%2,%1"
4944 [(set_attr "type" "compare")])
4945
4946 (define_insn ""
4947 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
4948 (compare:CC (ior:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "r"))
4949 (match_operand:DI 2 "gpc_reg_operand" "r"))
4950 (const_int 0)))
4951 (set (match_operand:DI 0 "gpc_reg_operand" "=r")
4952 (ior:DI (not:DI (match_dup 1)) (match_dup 2)))]
4953 "TARGET_POWERPC64"
4954 "orc. %0,%2,%1"
4955 [(set_attr "type" "compare")])
4956
4957 (define_insn ""
4958 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4959 (ior:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "%r"))
4960 (not:DI (match_operand:DI 2 "gpc_reg_operand" "r"))))]
4961 "TARGET_POWERPC64"
4962 "nand %0,%1,%2")
4963
4964 (define_insn ""
4965 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
4966 (compare:CC (ior:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "%r"))
4967 (not:DI (match_operand:DI 2 "gpc_reg_operand" "r")))
4968 (const_int 0)))
4969 (clobber (match_scratch:DI 3 "=r"))]
4970 "TARGET_POWERPC64"
4971 "nand. %3,%1,%2"
4972 [(set_attr "type" "compare")])
4973
4974 (define_insn ""
4975 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
4976 (compare:CC (ior:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "%r"))
4977 (not:DI (match_operand:DI 2 "gpc_reg_operand" "r")))
4978 (const_int 0)))
4979 (set (match_operand:DI 0 "gpc_reg_operand" "=r")
4980 (ior:DI (not:DI (match_dup 1)) (not:DI (match_dup 2))))]
4981 "TARGET_POWERPC64"
4982 "nand. %0,%1,%2"
4983 [(set_attr "type" "compare")])
4984
4985 (define_insn ""
4986 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4987 (and:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "%r"))
4988 (not:DI (match_operand:DI 2 "gpc_reg_operand" "r"))))]
4989 "TARGET_POWERPC64"
4990 "nor %0,%1,%2")
4991
4992 (define_insn ""
4993 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
4994 (compare:CC (and:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "%r"))
4995 (not:DI (match_operand:DI 2 "gpc_reg_operand" "r")))
4996 (const_int 0)))
4997 (clobber (match_scratch:DI 3 "=r"))]
4998 "TARGET_POWERPC64"
4999 "nor. %3,%1,%2"
5000 [(set_attr "type" "compare")])
5001
5002 (define_insn ""
5003 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
5004 (compare:CC (and:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "%r"))
5005 (not:DI (match_operand:DI 2 "gpc_reg_operand" "r")))
5006 (const_int 0)))
5007 (set (match_operand:DI 0 "gpc_reg_operand" "=r")
5008 (and:DI (not:DI (match_dup 1)) (not:DI (match_dup 2))))]
5009 "TARGET_POWERPC64"
5010 "nor. %0,%1,%2"
5011 [(set_attr "type" "compare")])
5012 \f
5013 ;; Now define ways of moving data around.
5014
5015 ;; Elf specific ways of loading addresses for non-PIC code.
5016 ;; The output of this could be r0, but we limit it to base
5017 ;; registers, since almost all uses of this will need it
5018 ;; in a base register shortly.
5019 (define_insn "elf_high"
5020 [(set (match_operand:SI 0 "register_operand" "=b")
5021 (high:SI (match_operand 1 "" "")))]
5022 "TARGET_ELF && !TARGET_64BIT"
5023 "{cau|addis} %0,0,%1@ha")
5024
5025 (define_insn "elf_low"
5026 [(set (match_operand:SI 0 "register_operand" "=r")
5027 (lo_sum:SI (match_operand:SI 1 "register_operand" "b")
5028 (match_operand 2 "" "")))]
5029 "TARGET_ELF && !TARGET_64BIT"
5030 "{cal %0,%a2@l(%1)|addi %0,%1,%2@l}")
5031
5032 ;; Set up a register with a value from the GOT table
5033
5034 (define_expand "movsi_got"
5035 [(set (match_operand:SI 0 "register_operand" "")
5036 (unspec [(match_operand:SI 1 "got_operand" "")
5037 (match_dup 2)] 8))]
5038 "(DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS) && flag_pic"
5039 "
5040 {
5041 operands[2] = rs6000_got_register (operands[1]);
5042 }")
5043
5044 (define_insn "*movsi_got_internal"
5045 [(set (match_operand:SI 0 "register_operand" "=r")
5046 (unspec [(match_operand:SI 1 "got_operand" "")
5047 (match_operand:SI 2 "register_operand" "b")] 8))]
5048 "(DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS) && flag_pic == 1"
5049 "{l|lwz} %0,%a1@got(%2)"
5050 [(set_attr "type" "load")])
5051
5052 ;; For SI, we special-case integers that can't be loaded in one insn. We
5053 ;; do the load 16-bits at a time. We could do this by loading from memory,
5054 ;; and this is even supposed to be faster, but it is simpler not to get
5055 ;; integers in the TOC.
5056 (define_expand "movsi"
5057 [(set (match_operand:SI 0 "general_operand" "")
5058 (match_operand:SI 1 "any_operand" ""))]
5059 ""
5060 "
5061 {
5062 if (GET_CODE (operands[0]) != REG)
5063 operands[1] = force_reg (SImode, operands[1]);
5064
5065 /* Convert a move of a CONST_DOUBLE into a CONST_INT */
5066 if (GET_CODE (operands[1]) == CONST_DOUBLE)
5067 operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
5068
5069 /* Use default pattern for address of ELF small data */
5070 if (TARGET_ELF
5071 && (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS)
5072 && (GET_CODE (operands[1]) == SYMBOL_REF || GET_CODE (operands[1]) == CONST)
5073 && small_data_operand (operands[1], SImode))
5074 {
5075 emit_insn (gen_rtx (SET, VOIDmode, operands[0], operands[1]));
5076 DONE;
5077 }
5078
5079 if ((DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS)
5080 && flag_pic == 1 && got_operand (operands[1], SImode))
5081 {
5082 emit_insn (gen_movsi_got (operands[0], operands[1]));
5083 DONE;
5084 }
5085
5086 if (TARGET_ELF && TARGET_NO_TOC && !TARGET_64BIT
5087 && CONSTANT_P (operands[1])
5088 && GET_CODE (operands[1]) != HIGH
5089 && GET_CODE (operands[1]) != CONST_INT)
5090 {
5091 rtx target = (reload_completed || reload_in_progress)
5092 ? operands[0] : gen_reg_rtx (SImode);
5093
5094 /* If this is a function address on -mcall-aixdesc or -mcall-nt,
5095 convert it to the address of the descriptor. */
5096 if ((DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_NT)
5097 && GET_CODE (operands[1]) == SYMBOL_REF
5098 && XSTR (operands[1], 0)[0] == '.')
5099 {
5100 char *name = XSTR (operands[1], 0);
5101 rtx new_ref;
5102 while (*name == '.')
5103 name++;
5104 new_ref = gen_rtx (SYMBOL_REF, Pmode, name);
5105 CONSTANT_POOL_ADDRESS_P (new_ref) = CONSTANT_POOL_ADDRESS_P (operands[1]);
5106 SYMBOL_REF_FLAG (new_ref) = SYMBOL_REF_FLAG (operands[1]);
5107 SYMBOL_REF_USED (new_ref) = SYMBOL_REF_USED (operands[1]);
5108 operands[1] = new_ref;
5109 }
5110
5111 emit_insn (gen_elf_high (target, operands[1]));
5112 emit_insn (gen_elf_low (operands[0], target, operands[1]));
5113 DONE;
5114 }
5115
5116 if (GET_CODE (operands[1]) == CONST
5117 && DEFAULT_ABI == ABI_NT
5118 && !side_effects_p (operands[0]))
5119 {
5120 rtx const_term = const0_rtx;
5121 rtx sym = eliminate_constant_term (XEXP (operands[1], 0), &const_term);
5122 if (sym && GET_CODE (const_term) == CONST_INT
5123 && (GET_CODE (sym) == SYMBOL_REF || GET_CODE (sym) == LABEL_REF))
5124 {
5125 unsigned HOST_WIDE_INT value = INTVAL (const_term);
5126 int new_reg_p = (flag_expensive_optimizations
5127 && !reload_completed
5128 && !reload_in_progress);
5129 rtx tmp1 = (new_reg_p && value != 0) ? gen_reg_rtx (SImode) : operands[0];
5130
5131 emit_insn (gen_movsi (tmp1, sym));
5132 if (INTVAL (const_term) != 0)
5133 {
5134 if (value + 0x8000 < 0x10000)
5135 emit_insn (gen_addsi3 (operands[0], tmp1, GEN_INT (value)));
5136
5137 else
5138 {
5139 HOST_WIDE_INT high_int = value & (~ (HOST_WIDE_INT) 0xffff);
5140 HOST_WIDE_INT low_int = value & 0xffff;
5141 rtx tmp2 = (!new_reg_p || !low_int) ? operands[0] : gen_reg_rtx (Pmode);
5142
5143 if (low_int & 0x8000)
5144 high_int += 0x10000, low_int |= ((HOST_WIDE_INT) -1) << 16;
5145
5146 emit_insn (gen_addsi3 (tmp2, tmp1, GEN_INT (high_int)));
5147 if (low_int)
5148 emit_insn (gen_addsi3 (operands[0], tmp2, GEN_INT (low_int)));
5149 }
5150 }
5151 DONE;
5152 }
5153 else
5154 fatal_insn (\"bad address\", operands[1]);
5155 }
5156
5157 if ((!TARGET_WINDOWS_NT || DEFAULT_ABI != ABI_NT)
5158 && CONSTANT_P (operands[1])
5159 && GET_CODE (operands[1]) != CONST_INT
5160 && GET_CODE (operands[1]) != HIGH
5161 && ! LEGITIMATE_CONSTANT_POOL_ADDRESS_P (operands[1]))
5162 {
5163 /* If we are to limit the number of things we put in the TOC and
5164 this is a symbol plus a constant we can add in one insn,
5165 just put the symbol in the TOC and add the constant. Don't do
5166 this if reload is in progress. */
5167 if (GET_CODE (operands[1]) == CONST
5168 && TARGET_NO_SUM_IN_TOC && ! reload_in_progress
5169 && GET_CODE (XEXP (operands[1], 0)) == PLUS
5170 && add_operand (XEXP (XEXP (operands[1], 0), 1), SImode)
5171 && (GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == LABEL_REF
5172 || GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == SYMBOL_REF)
5173 && ! side_effects_p (operands[0]))
5174 {
5175 rtx sym = force_const_mem (SImode, XEXP (XEXP (operands[1], 0), 0));
5176 rtx other = XEXP (XEXP (operands[1], 0), 1);
5177
5178 emit_insn (gen_addsi3 (operands[0], force_reg (SImode, sym), other));
5179 DONE;
5180 }
5181
5182 operands[1] = force_const_mem (SImode, operands[1]);
5183 if (! memory_address_p (SImode, XEXP (operands[1], 0))
5184 && ! reload_in_progress)
5185 operands[1] = change_address (operands[1], SImode,
5186 XEXP (operands[1], 0));
5187 }
5188 }")
5189
5190 (define_insn ""
5191 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,r,m,r,r,r,r,r,*q,*c*l,*h")
5192 (match_operand:SI 1 "input_operand" "r,S,T,U,m,r,I,J,n,R,*h,r,r,0"))]
5193 "gpc_reg_operand (operands[0], SImode)
5194 || gpc_reg_operand (operands[1], SImode)"
5195 "@
5196 mr %0,%1
5197 {l|lwz} %0,[toc]%1(2)
5198 {l|lwz} %0,[toc]%l1(2)
5199 {cal|la} %0,%a1
5200 {l%U1%X1|lwz%U1%X1} %0,%1
5201 {st%U0%X0|stw%U0%X0} %1,%0
5202 {lil|li} %0,%1
5203 {liu|lis} %0,%v1
5204 #
5205 {cal|la} %0,%1(%*)
5206 mf%1 %0
5207 mt%0 %1
5208 mt%0 %1
5209 cror 0,0,0"
5210 [(set_attr "type" "*,load,load,*,load,store,*,*,*,*,*,*,mtjmpr,*")
5211 (set_attr "length" "4,4,4,4,4,4,4,4,8,4,4,4,4,4")])
5212
5213 ;; Split a load of a large constant into the appropriate two-insn
5214 ;; sequence.
5215
5216 (define_split
5217 [(set (match_operand:SI 0 "gpc_reg_operand" "")
5218 (match_operand:SI 1 "const_int_operand" ""))]
5219 "(unsigned) (INTVAL (operands[1]) + 0x8000) >= 0x10000
5220 && (INTVAL (operands[1]) & 0xffff) != 0"
5221 [(set (match_dup 0)
5222 (match_dup 2))
5223 (set (match_dup 0)
5224 (ior:SI (match_dup 0)
5225 (match_dup 3)))]
5226 "
5227 {
5228 operands[2] = gen_rtx (CONST_INT, VOIDmode,
5229 INTVAL (operands[1]) & 0xffff0000);
5230 operands[3] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[1]) & 0xffff);
5231 }")
5232
5233 (define_insn ""
5234 [(set (match_operand:CC 2 "cc_reg_operand" "=x")
5235 (compare:CC (match_operand:SI 1 "gpc_reg_operand" "r")
5236 (const_int 0)))
5237 (set (match_operand:SI 0 "gpc_reg_operand" "=r") (match_dup 1))]
5238 ""
5239 "mr. %0,%1"
5240 [(set_attr "type" "compare")])
5241 \f
5242 (define_expand "movhi"
5243 [(set (match_operand:HI 0 "general_operand" "")
5244 (match_operand:HI 1 "any_operand" ""))]
5245 ""
5246 "
5247 {
5248 if (GET_CODE (operands[0]) != REG)
5249 operands[1] = force_reg (HImode, operands[1]);
5250
5251 if (CONSTANT_P (operands[1]) && GET_CODE (operands[1]) != CONST_INT)
5252 {
5253 operands[1] = force_const_mem (HImode, operands[1]);
5254 if (! memory_address_p (HImode, XEXP (operands[1], 0))
5255 && ! reload_in_progress)
5256 operands[1] = change_address (operands[1], HImode,
5257 XEXP (operands[1], 0));
5258 }
5259 }")
5260
5261 (define_insn ""
5262 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,m,r,r,*q,*c*l,*h")
5263 (match_operand:HI 1 "input_operand" "r,m,r,i,*h,r,r,0"))]
5264 "gpc_reg_operand (operands[0], HImode)
5265 || gpc_reg_operand (operands[1], HImode)"
5266 "@
5267 mr %0,%1
5268 lhz%U1%X1 %0,%1
5269 sth%U0%X0 %1,%0
5270 {lil|li} %0,%w1
5271 mf%1 %0
5272 mt%0 %1
5273 mt%0 %1
5274 cror 0,0,0"
5275 [(set_attr "type" "*,load,store,*,*,*,mtjmpr,*")])
5276
5277 (define_expand "movqi"
5278 [(set (match_operand:QI 0 "general_operand" "")
5279 (match_operand:QI 1 "any_operand" ""))]
5280 ""
5281 "
5282 {
5283 if (GET_CODE (operands[0]) != REG)
5284 operands[1] = force_reg (QImode, operands[1]);
5285
5286 if (CONSTANT_P (operands[1]) && GET_CODE (operands[1]) != CONST_INT)
5287 {
5288 operands[1] = force_const_mem (QImode, operands[1]);
5289 if (! memory_address_p (QImode, XEXP (operands[1], 0))
5290 && ! reload_in_progress)
5291 operands[1] = change_address (operands[1], QImode,
5292 XEXP (operands[1], 0));
5293 }
5294 }")
5295
5296 (define_insn ""
5297 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m,r,r,*q,*c*l,*h")
5298 (match_operand:QI 1 "input_operand" "r,m,r,i,*h,r,r,0"))]
5299 "gpc_reg_operand (operands[0], QImode)
5300 || gpc_reg_operand (operands[1], QImode)"
5301 "@
5302 mr %0,%1
5303 lbz%U1%X1 %0,%1
5304 stb%U0%X0 %1,%0
5305 {lil|li} %0,%1
5306 mf%1 %0
5307 mt%0 %1
5308 mt%0 %1
5309 cror 0,0,0"
5310 [(set_attr "type" "*,load,store,*,*,*,mtjmpr,*")])
5311 \f
5312 ;; Here is how to move condition codes around. When we store CC data in
5313 ;; an integer register or memory, we store just the high-order 4 bits.
5314 ;; This lets us not shift in the most common case of CR0.
5315 (define_expand "movcc"
5316 [(set (match_operand:CC 0 "nonimmediate_operand" "")
5317 (match_operand:CC 1 "nonimmediate_operand" ""))]
5318 ""
5319 "")
5320
5321 (define_insn ""
5322 [(set (match_operand:CC 0 "nonimmediate_operand" "=y,x,y,r,r,r,r,m")
5323 (match_operand:CC 1 "nonimmediate_operand" "y,r,r,x,y,r,m,r"))]
5324 "register_operand (operands[0], CCmode)
5325 || register_operand (operands[1], CCmode)"
5326 "@
5327 mcrf %0,%1
5328 mtcrf 128,%1
5329 {rlinm|rlwinm} %1,%1,%F0,0xffffffff\;mtcrf %R0,%1\;{rlinm|rlwinm} %1,%1,%f0,0xffffffff
5330 mfcr %0
5331 mfcr %0\;{rlinm|rlwinm} %0,%0,%f1,0xf0000000
5332 mr %0,%1
5333 {l%U1%X1|lwz%U1%X1} %0,%1
5334 {st%U0%U1|stw%U0%U1} %1,%0"
5335 [(set_attr "type" "*,*,*,compare,*,*,load,store")
5336 (set_attr "length" "*,*,12,*,8,*,*,*")])
5337 \f
5338 ;; For floating-point, we normally deal with the floating-point registers
5339 ;; unless -msoft-float is used. The sole exception is that parameter passing
5340 ;; can produce floating-point values in fixed-point registers. Unless the
5341 ;; value is a simple constant or already in memory, we deal with this by
5342 ;; allocating memory and copying the value explicitly via that memory location.
5343 (define_expand "movsf"
5344 [(set (match_operand:SF 0 "nonimmediate_operand" "")
5345 (match_operand:SF 1 "any_operand" ""))]
5346 ""
5347 "
5348 {
5349 /* If we are called from reload, we might be getting a SUBREG of a hard
5350 reg. So expand it. */
5351 if (GET_CODE (operands[0]) == SUBREG
5352 && GET_CODE (SUBREG_REG (operands[0])) == REG
5353 && REGNO (SUBREG_REG (operands[0])) < FIRST_PSEUDO_REGISTER)
5354 operands[0] = alter_subreg (operands[0]);
5355 if (GET_CODE (operands[1]) == SUBREG
5356 && GET_CODE (SUBREG_REG (operands[1])) == REG
5357 && REGNO (SUBREG_REG (operands[1])) < FIRST_PSEUDO_REGISTER)
5358 operands[1] = alter_subreg (operands[1]);
5359
5360 if (TARGET_SOFT_FLOAT && GET_CODE (operands[0]) == MEM)
5361 operands[1] = force_reg (SFmode, operands[1]);
5362
5363 else if (TARGET_HARD_FLOAT)
5364 {
5365 if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) < 32)
5366 {
5367 /* If this is a store to memory or another integer register do the
5368 move directly. Otherwise store to a temporary stack slot and
5369 load from there into a floating point register. */
5370
5371 if (GET_CODE (operands[0]) == MEM
5372 || (GET_CODE (operands[0]) == REG
5373 && (REGNO (operands[0]) < 32
5374 || (reload_in_progress
5375 && REGNO (operands[0]) >= FIRST_PSEUDO_REGISTER))))
5376 {
5377 emit_move_insn (operand_subword (operands[0], 0, 0, SFmode),
5378 operand_subword (operands[1], 0, 0, SFmode));
5379 DONE;
5380 }
5381 else
5382 {
5383 rtx stack_slot = assign_stack_temp (SFmode, 4, 0);
5384
5385 emit_move_insn (stack_slot, operands[1]);
5386 emit_move_insn (operands[0], stack_slot);
5387 DONE;
5388 }
5389 }
5390
5391 if (GET_CODE (operands[0]) == MEM)
5392 {
5393 /* If operands[1] is a register, it may have double-precision data
5394 in it, so truncate it to single precision. We need not do
5395 this for POWERPC. */
5396 if (! TARGET_POWERPC && TARGET_HARD_FLOAT
5397 && GET_CODE (operands[1]) == REG)
5398 {
5399 rtx newreg
5400 = reload_in_progress ? operands[1] : gen_reg_rtx (SFmode);
5401 emit_insn (gen_aux_truncdfsf2 (newreg, operands[1]));
5402 operands[1] = newreg;
5403 }
5404
5405 operands[1] = force_reg (SFmode, operands[1]);
5406 }
5407
5408 if (GET_CODE (operands[0]) == REG && REGNO (operands[0]) < 32)
5409 {
5410 if (GET_CODE (operands[1]) == MEM
5411 #if HOST_FLOAT_FORMAT == TARGET_FLOAT_FORMAT && ! defined(REAL_IS_NOT_DOUBLE)
5412 || GET_CODE (operands[1]) == CONST_DOUBLE
5413 #endif
5414 || (GET_CODE (operands[1]) == REG
5415 && (REGNO (operands[1]) < 32
5416 || (reload_in_progress
5417 && REGNO (operands[1]) >= FIRST_PSEUDO_REGISTER))))
5418 {
5419 emit_move_insn (operand_subword (operands[0], 0, 0, SFmode),
5420 operand_subword (operands[1], 0, 0, SFmode));
5421 DONE;
5422 }
5423 else
5424 {
5425 rtx stack_slot = assign_stack_temp (SFmode, 4, 0);
5426
5427 emit_move_insn (stack_slot, operands[1]);
5428 emit_move_insn (operands[0], stack_slot);
5429 DONE;
5430 }
5431 }
5432 }
5433
5434 if (CONSTANT_P (operands[1]) && TARGET_HARD_FLOAT)
5435 {
5436 operands[1] = force_const_mem (SFmode, operands[1]);
5437 if (! memory_address_p (SFmode, XEXP (operands[1], 0))
5438 && ! reload_in_progress)
5439 operands[1] = change_address (operands[1], SFmode,
5440 XEXP (operands[1], 0));
5441 }
5442 }")
5443
5444 (define_split
5445 [(set (match_operand:SF 0 "gpc_reg_operand" "")
5446 (match_operand:SF 1 "const_double_operand" ""))]
5447 "TARGET_32BIT && reload_completed && num_insns_constant (operands[1], SFmode) <= 1 && REGNO (operands[0]) <= 31"
5448 [(set (match_dup 2) (match_dup 3))]
5449 "
5450 {
5451 long l;
5452 REAL_VALUE_TYPE rv;
5453
5454 REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]);
5455 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
5456
5457 operands[2] = gen_rtx (SUBREG, SImode, operands[0], 0);
5458 operands[3] = GEN_INT(l);
5459 }")
5460
5461 (define_split
5462 [(set (match_operand:SF 0 "gpc_reg_operand" "")
5463 (match_operand:SF 1 "const_double_operand" ""))]
5464 "TARGET_32BIT && reload_completed && num_insns_constant (operands[1], SFmode) == 2 && REGNO (operands[0]) <= 31"
5465 [(set (match_dup 2) (match_dup 3))
5466 (set (match_dup 2) (ior:SI (match_dup 2) (match_dup 4)))]
5467 "
5468 {
5469 long l;
5470 REAL_VALUE_TYPE rv;
5471
5472 REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]);
5473 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
5474
5475 operands[2] = gen_rtx (SUBREG, SImode, operands[0], 0);
5476 operands[3] = GEN_INT(l & 0xffff0000);
5477 operands[4] = GEN_INT(l & 0x0000ffff);
5478 }")
5479
5480 (define_insn "*movsf_hardfloat"
5481 [(set (match_operand:SF 0 "fp_reg_or_mem_operand" "=f,f,m,!r,!r")
5482 (match_operand:SF 1 "input_operand" "f,m,f,G,Fn"))]
5483 "(gpc_reg_operand (operands[0], SFmode)
5484 || gpc_reg_operand (operands[1], SFmode)) && TARGET_HARD_FLOAT"
5485 "@
5486 fmr %0,%1
5487 lfs%U1%X1 %0,%1
5488 stfs%U0%X0 %1,%0
5489 #
5490 #"
5491 [(set_attr "type" "fp,fpload,fpstore,*,*")
5492 (set_attr "length" "4,4,4,4,8")])
5493
5494 (define_insn "*movsf_softfloat"
5495 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m,r,r,r,r,r")
5496 (match_operand:SF 1 "input_operand" "r,m,r,I,J,R,G,Fn"))]
5497 "(gpc_reg_operand (operands[0], SFmode)
5498 || gpc_reg_operand (operands[1], SFmode)) && TARGET_SOFT_FLOAT"
5499 "@
5500 mr %0,%1
5501 {l%U1%X1|lwz%U1%X1} %0,%1
5502 {st%U0%X0|stw%U0%X0} %1,%0
5503 {lil|li} %0,%1
5504 {liu|lis} %0,%v1
5505 {cal|la} %0,%1(%*)
5506 #
5507 #"
5508 [(set_attr "type" "*,load,store,*,*,*,*,*")
5509 (set_attr "length" "4,4,4,4,4,4,4,8")])
5510
5511 \f
5512 (define_expand "movdf"
5513 [(set (match_operand:DF 0 "nonimmediate_operand" "")
5514 (match_operand:DF 1 "any_operand" ""))]
5515 ""
5516 "
5517 {
5518 if (GET_CODE (operands[0]) != REG)
5519 operands[1] = force_reg (DFmode, operands[1]);
5520
5521 /* Stores between FPR and any non-FPR registers must go through a
5522 temporary stack slot. */
5523
5524 if (TARGET_POWERPC64
5525 && GET_CODE (operands[0]) == REG && GET_CODE (operands[1]) == REG
5526 && ((FP_REGNO_P (REGNO (operands[0]))
5527 && ! FP_REGNO_P (REGNO (operands[1])))
5528 || (FP_REGNO_P (REGNO (operands[1]))
5529 && ! FP_REGNO_P (REGNO (operands[0])))))
5530 {
5531 rtx stack_slot = assign_stack_temp (DFmode, 8, 0);
5532
5533 emit_move_insn (stack_slot, operands[1]);
5534 emit_move_insn (operands[0], stack_slot);
5535 DONE;
5536 }
5537
5538 if (CONSTANT_P (operands[1]) && ! easy_fp_constant (operands[1], DFmode))
5539 {
5540 operands[1] = force_const_mem (DFmode, operands[1]);
5541 if (! memory_address_p (DFmode, XEXP (operands[1], 0))
5542 && ! reload_in_progress)
5543 operands[1] = change_address (operands[1], DFmode,
5544 XEXP (operands[1], 0));
5545 }
5546 }")
5547
5548 (define_split
5549 [(set (match_operand:DF 0 "gpc_reg_operand" "")
5550 (match_operand:DF 1 "const_int_operand" ""))]
5551 "TARGET_32BIT && reload_completed && num_insns_constant (operands[1], DFmode) <= 1 && REGNO (operands[0]) <= 31"
5552 [(set (match_dup 2) (match_dup 4))
5553 (set (match_dup 3) (match_dup 1))]
5554 "
5555 {
5556 operands[2] = gen_rtx (SUBREG, SImode, operands[0], WORDS_BIG_ENDIAN == 0);
5557 operands[3] = gen_rtx (SUBREG, SImode, operands[0], WORDS_BIG_ENDIAN != 0);
5558 operands[4] = (INTVAL (operands[1]) & 0x80000000) ? constm1_rtx : const0_rtx;
5559 }")
5560
5561 (define_split
5562 [(set (match_operand:DF 0 "gpc_reg_operand" "")
5563 (match_operand:DF 1 "const_int_operand" ""))]
5564 "TARGET_32BIT && reload_completed && num_insns_constant (operands[1], DFmode) >= 2 && REGNO (operands[0]) <= 31"
5565 [(set (match_dup 3) (match_dup 5))
5566 (set (match_dup 2) (match_dup 4))
5567 (set (match_dup 3) (ior:SI (match_dup 3) (match_dup 6)))]
5568 "
5569 {
5570 HOST_WIDE_INT value = INTVAL (operands[1]);
5571 operands[2] = gen_rtx (SUBREG, SImode, operands[0], WORDS_BIG_ENDIAN == 0);
5572 operands[3] = gen_rtx (SUBREG, SImode, operands[0], WORDS_BIG_ENDIAN != 0);
5573 operands[4] = (value & 0x80000000) ? constm1_rtx : const0_rtx;
5574 operands[5] = GEN_INT (value & 0xffff0000);
5575 operands[6] = GEN_INT (value & 0x0000ffff);
5576 }")
5577
5578 (define_split
5579 [(set (match_operand:DF 0 "gpc_reg_operand" "")
5580 (match_operand:DF 1 "const_double_operand" ""))]
5581 "TARGET_32BIT && reload_completed && num_insns_constant (operands[1], DFmode) <= 2 && REGNO (operands[0]) <= 31"
5582 [(set (match_dup 2) (match_dup 4))
5583 (set (match_dup 3) (match_dup 5))]
5584 "
5585 {
5586 operands[2] = gen_rtx (SUBREG, SImode, operands[0], WORDS_BIG_ENDIAN == 0);
5587 operands[3] = gen_rtx (SUBREG, SImode, operands[0], WORDS_BIG_ENDIAN != 0);
5588
5589 #ifdef HOST_WORDS_BIG_ENDIAN
5590 operands[4] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
5591 operands[5] = GEN_INT (CONST_DOUBLE_HIGH (operands[1]));
5592 #else
5593 operands[4] = GEN_INT (CONST_DOUBLE_HIGH (operands[1]));
5594 operands[5] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
5595 #endif
5596 }")
5597
5598 (define_split
5599 [(set (match_operand:DF 0 "gpc_reg_operand" "")
5600 (match_operand:DF 1 "const_double_operand" ""))]
5601 "TARGET_32BIT && reload_completed && num_insns_constant (operands[1], DFmode) == 3 && REGNO (operands[0]) <= 31"
5602 [(set (match_dup 2) (match_dup 4))
5603 (set (match_dup 3) (match_dup 5))
5604 (set (match_dup 2) (ior:SI (match_dup 2) (match_dup 6)))]
5605 "
5606 {
5607 HOST_WIDE_INT high;
5608 HOST_WIDE_INT low;
5609 rtx high_reg = gen_rtx (SUBREG, SImode, operands[0], WORDS_BIG_ENDIAN == 0);
5610 rtx low_reg = gen_rtx (SUBREG, SImode, operands[0], WORDS_BIG_ENDIAN != 0);
5611
5612 #ifdef HOST_WORDS_BIG_ENDIAN
5613 high = CONST_DOUBLE_LOW (operands[1]);
5614 low = CONST_DOUBLE_HIGH (operands[1]);
5615 #else
5616 high = CONST_DOUBLE_HIGH (operands[1]);
5617 low = CONST_DOUBLE_LOW (operands[1]);
5618 #endif
5619
5620 if (((unsigned HOST_WIDE_INT) (low + 0x8000) < 0x10000)
5621 || (low & 0xffff) == 0)
5622 {
5623 operands[2] = high_reg;
5624 operands[3] = low_reg;
5625 operands[4] = GEN_INT (high & 0xffff0000);
5626 operands[5] = GEN_INT (low);
5627 operands[6] = GEN_INT (high & 0x0000ffff);
5628 }
5629 else
5630 {
5631 operands[2] = low_reg;
5632 operands[3] = high_reg;
5633 operands[4] = GEN_INT (low & 0xffff0000);
5634 operands[5] = GEN_INT (high);
5635 operands[6] = GEN_INT (low & 0x0000ffff);
5636 }
5637 }")
5638
5639 (define_split
5640 [(set (match_operand:DF 0 "gpc_reg_operand" "")
5641 (match_operand:DF 1 "const_double_operand" ""))]
5642 "TARGET_32BIT && reload_completed && num_insns_constant (operands[1], DFmode) >= 4 && REGNO (operands[0]) <= 31"
5643 [(set (match_dup 2) (match_dup 4))
5644 (set (match_dup 3) (match_dup 5))
5645 (set (match_dup 2) (ior:SI (match_dup 2) (match_dup 6)))
5646 (set (match_dup 3) (ior:SI (match_dup 3) (match_dup 7)))]
5647 "
5648 {
5649 HOST_WIDE_INT high = CONST_DOUBLE_HIGH (operands[1]);
5650 HOST_WIDE_INT low = CONST_DOUBLE_LOW (operands[1]);
5651
5652 operands[2] = gen_rtx (SUBREG, SImode, operands[0], WORDS_BIG_ENDIAN == 0);
5653 operands[3] = gen_rtx (SUBREG, SImode, operands[0], WORDS_BIG_ENDIAN != 0);
5654 operands[4] = GEN_INT (high & 0xffff0000);
5655 operands[5] = GEN_INT (low & 0xffff0000);
5656 operands[6] = GEN_INT (high & 0x0000ffff);
5657 operands[7] = GEN_INT (low & 0x0000ffff);
5658 }")
5659
5660 (define_split
5661 [(set (match_operand:DF 0 "gpc_reg_operand" "")
5662 (match_operand:DF 1 "easy_fp_constant" ""))]
5663 "TARGET_64BIT && reload_completed && REGNO (operands[0]) <= 31"
5664 [(set (subreg:DI (match_dup 0) 0) (subreg:DI (match_dup 1) 0))]
5665 "")
5666
5667 ;; Don't have reload use general registers to load a constant. First,
5668 ;; it might not work if the output operand has is the equivalent of
5669 ;; a non-offsettable memref, but also it is less efficient than loading
5670 ;; the constant into an FP register, since it will probably be used there.
5671 ;; The "??" is a kludge until we can figure out a more reasonable way
5672 ;; of handling these non-offsettable values.
5673 (define_insn "*movdf_hardfloat32"
5674 [(set (match_operand:DF 0 "nonimmediate_operand" "=!r,??r,o,!r,!r,!r,f,f,m")
5675 (match_operand:DF 1 "input_operand" "r,o,r,G,H,F,f,m,f"))]
5676 "! TARGET_POWERPC64 && TARGET_HARD_FLOAT
5677 && (register_operand (operands[0], DFmode)
5678 || register_operand (operands[1], DFmode))"
5679 "*
5680 {
5681 switch (which_alternative)
5682 {
5683 case 0:
5684 /* We normally copy the low-numbered register first. However, if
5685 the first register operand 0 is the same as the second register of
5686 operand 1, we must copy in the opposite order. */
5687 if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
5688 return \"mr %L0,%L1\;mr %0,%1\";
5689 else
5690 return \"mr %0,%1\;mr %L0,%L1\";
5691 case 1:
5692 /* If the low-address word is used in the address, we must load it
5693 last. Otherwise, load it first. Note that we cannot have
5694 auto-increment in that case since the address register is known to be
5695 dead. */
5696 if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
5697 operands [1], 0))
5698 return \"{l|lwz} %L0,%L1\;{l|lwz} %0,%1\";
5699 else
5700 return \"{l%U1|lwz%U1} %0,%1\;{l|lwz} %L0,%L1\";
5701 case 2:
5702 return \"{st%U0|stw%U0} %1,%0\;{st|stw} %L1,%L0\";
5703 case 3:
5704 case 4:
5705 case 5:
5706 return \"#\";
5707 case 6:
5708 return \"fmr %0,%1\";
5709 case 7:
5710 return \"lfd%U1%X1 %0,%1\";
5711 case 8:
5712 return \"stfd%U0%X0 %1,%0\";
5713 }
5714 }"
5715 [(set_attr "type" "*,load,store,*,*,*,fp,fpload,fpstore")
5716 (set_attr "length" "8,8,8,8,12,16,*,*,*")])
5717
5718 (define_insn "*movdf_softfloat32"
5719 [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,o,r,r,r")
5720 (match_operand:DF 1 "input_operand" "r,o,r,G,H,F"))]
5721 "! TARGET_POWERPC64 && TARGET_SOFT_FLOAT
5722 && (register_operand (operands[0], DFmode)
5723 || register_operand (operands[1], DFmode))"
5724 "*
5725 {
5726 switch (which_alternative)
5727 {
5728 case 0:
5729 /* We normally copy the low-numbered register first. However, if
5730 the first register operand 0 is the same as the second register of
5731 operand 1, we must copy in the opposite order. */
5732 if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
5733 return \"mr %L0,%L1\;mr %0,%1\";
5734 else
5735 return \"mr %0,%1\;mr %L0,%L1\";
5736 case 1:
5737 /* If the low-address word is used in the address, we must load it
5738 last. Otherwise, load it first. Note that we cannot have
5739 auto-increment in that case since the address register is known to be
5740 dead. */
5741 if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
5742 operands [1], 0))
5743 return \"{l|lwz} %L0,%L1\;{l|lwz} %0,%1\";
5744 else
5745 return \"{l%U1|lwz%U1} %0,%1\;{l|lwz} %L0,%L1\";
5746 case 2:
5747 return \"{st%U0|stw%U0} %1,%0\;{st|stw} %L1,%L0\";
5748 case 3:
5749 case 4:
5750 case 5:
5751 return \"#\";
5752 }
5753 }"
5754 [(set_attr "type" "*,load,store,*,*,*")
5755 (set_attr "length" "8,8,8,8,12,16")])
5756
5757 (define_insn "*movdf_hardfloat64"
5758 [(set (match_operand:DF 0 "nonimmediate_operand" "=!r,??r,o,!r,!r,!r,f,f,m")
5759 (match_operand:DF 1 "input_operand" "r,o,r,G,H,F,f,m,f"))]
5760 "TARGET_POWERPC64 && TARGET_HARD_FLOAT
5761 && (register_operand (operands[0], DFmode)
5762 || register_operand (operands[1], DFmode))"
5763 "@
5764 mr %0,%1
5765 ld%U1%X1 %0,%1
5766 std%U0%X0 %1,%0
5767 #
5768 #
5769 #
5770 fmr %0,%1
5771 lfd%U1%X1 %0,%1
5772 stfd%U0%X0 %1,%0"
5773 [(set_attr "type" "*,load,store,*,*,*,fp,fpload,fpstore")
5774 (set_attr "length" "4,4,4,8,12,16,4,4,4")])
5775
5776 (define_insn "*movdf_softfloat64"
5777 [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,o,r,r,r")
5778 (match_operand:DF 1 "input_operand" "r,o,r,G,H,F"))]
5779 "TARGET_POWERPC64 && TARGET_SOFT_FLOAT
5780 && (register_operand (operands[0], DFmode)
5781 || register_operand (operands[1], DFmode))"
5782 "@
5783 mr %0,%1
5784 ld%U1%X1 %0,%1
5785 std%U0%X0 %1,%0
5786 #
5787 #
5788 #"
5789 [(set_attr "type" "*,load,store,*,*,*")
5790 (set_attr "length" "*,*,*,8,12,16")])
5791 \f
5792 ;; Next come the multi-word integer load and store and the load and store
5793 ;; multiple insns.
5794 (define_expand "movdi"
5795 [(set (match_operand:DI 0 "general_operand" "")
5796 (match_operand:DI 1 "any_operand" ""))]
5797 ""
5798 "
5799 {
5800 if (GET_CODE (operands[0]) != REG)
5801 operands[1] = force_reg (DImode, operands[1]);
5802
5803 if (TARGET_64BIT
5804 && (GET_CODE (operands[1]) == CONST_DOUBLE
5805 || GET_CODE (operands[1]) == CONST_INT))
5806 {
5807 HOST_WIDE_INT low;
5808 HOST_WIDE_INT high;
5809
5810 if (GET_CODE (operands[1]) == CONST_DOUBLE)
5811 {
5812 low = CONST_DOUBLE_LOW (operands[1]);
5813 high = CONST_DOUBLE_HIGH (operands[1]);
5814 }
5815 else
5816 #if HOST_BITS_PER_WIDE_INT == 32
5817 {
5818 low = INTVAL (operands[1]);
5819 high = (low < 0) ? ~0 : 0;
5820 }
5821 #else
5822 {
5823 low = INTVAL (operands[1]) & 0xffffffff;
5824 high = (HOST_WIDE_INT) INTVAL (operands[1]) >> 32;
5825 }
5826 #endif
5827
5828 if (high)
5829 {
5830 emit_move_insn (operands[0], GEN_INT (high));
5831 emit_insn (gen_ashldi3 (operands[0], operands[0], GEN_INT(32)));
5832 if (low)
5833 {
5834 HOST_WIDE_INT low_low = low & 0xffff;
5835 HOST_WIDE_INT low_high = low & (~ (HOST_WIDE_INT) 0xffff);
5836 if (low_high)
5837 emit_insn (gen_iordi3 (operands[0], operands[0],
5838 GEN_INT (low_high)));
5839 if (low_low)
5840 emit_insn (gen_iordi3 (operands[0], operands[0],
5841 GEN_INT (low_low)));
5842 }
5843 DONE;
5844 }
5845 }
5846
5847 /* Stores between FPR and any non-FPR registers must go through a
5848 temporary stack slot. */
5849
5850 if (GET_CODE (operands[0]) == REG && GET_CODE (operands[1]) == REG
5851 && ((FP_REGNO_P (REGNO (operands[0]))
5852 && ! FP_REGNO_P (REGNO (operands[1])))
5853 || (FP_REGNO_P (REGNO (operands[1]))
5854 && ! FP_REGNO_P (REGNO (operands[0])))))
5855 {
5856 rtx stack_slot = assign_stack_temp (DImode, 8, 0);
5857
5858 emit_move_insn (stack_slot, operands[1]);
5859 emit_move_insn (operands[0], stack_slot);
5860 DONE;
5861 }
5862 }")
5863
5864 (define_insn "*movdi_32"
5865 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m,f,f,m,r,r,r,r,r")
5866 (match_operand:DI 1 "input_operand" "r,m,r,f,m,f,IJK,n,G,H,F"))]
5867 "TARGET_32BIT
5868 && (gpc_reg_operand (operands[0], DImode)
5869 || gpc_reg_operand (operands[1], DImode))"
5870 "*
5871 {
5872 switch (which_alternative)
5873 {
5874 case 0:
5875 /* We normally copy the low-numbered register first. However, if
5876 the first register operand 0 is the same as the second register of
5877 operand 1, we must copy in the opposite order. */
5878 if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
5879 return \"mr %L0,%L1\;mr %0,%1\";
5880 else
5881 return \"mr %0,%1\;mr %L0,%L1\";
5882 case 1:
5883 /* If the low-address word is used in the address, we must load it
5884 last. Otherwise, load it first. Note that we cannot have
5885 auto-increment in that case since the address register is known to be
5886 dead. */
5887 if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
5888 operands [1], 0))
5889 return \"{l|lwz} %L0,%L1\;{l|lwz} %0,%1\";
5890 else
5891 return \"{l%U1|lwz%U1} %0,%1\;{l|lwz} %L0,%L1\";
5892 case 2:
5893 return \"{st%U0|stw%U0} %1,%0\;{st|stw} %L1,%L0\";
5894 case 3:
5895 return \"fmr %0,%1\";
5896 case 4:
5897 return \"lfd%U1%X1 %0,%1\";
5898 case 5:
5899 return \"stfd%U0%X0 %1,%0\";
5900 case 6:
5901 case 7:
5902 case 8:
5903 case 9:
5904 case 10:
5905 return \"#\";
5906 }
5907 }"
5908 [(set_attr "type" "*,load,store,fp,fpload,fpstore,*,*,*,*,*")
5909 (set_attr "length" "8,8,8,*,*,*,8,12,8,12,16")])
5910
5911 (define_split
5912 [(set (match_operand:DI 0 "gpc_reg_operand" "")
5913 (match_operand:DI 1 "const_int_operand" ""))]
5914 "TARGET_32BIT && reload_completed && num_insns_constant (operands[1], DImode) <= 1"
5915 [(set (match_dup 2) (match_dup 4))
5916 (set (match_dup 3) (match_dup 1))]
5917 "
5918 {
5919 operands[2] = gen_rtx (SUBREG, SImode, operands[0], WORDS_BIG_ENDIAN == 0);
5920 operands[3] = gen_rtx (SUBREG, SImode, operands[0], WORDS_BIG_ENDIAN != 0);
5921 operands[4] = (INTVAL (operands[1]) & 0x80000000) ? constm1_rtx : const0_rtx;
5922 }")
5923
5924 (define_split
5925 [(set (match_operand:DI 0 "gpc_reg_operand" "")
5926 (match_operand:DI 1 "const_int_operand" ""))]
5927 "TARGET_32BIT && reload_completed && num_insns_constant (operands[1], DImode) >= 2"
5928 [(set (match_dup 3) (match_dup 5))
5929 (set (match_dup 2) (match_dup 4))
5930 (set (match_dup 3) (ior:SI (match_dup 3) (match_dup 6)))]
5931 "
5932 {
5933 HOST_WIDE_INT value = INTVAL (operands[1]);
5934 operands[2] = gen_rtx (SUBREG, SImode, operands[0], WORDS_BIG_ENDIAN == 0);
5935 operands[3] = gen_rtx (SUBREG, SImode, operands[0], WORDS_BIG_ENDIAN != 0);
5936 operands[4] = (value & 0x80000000) ? constm1_rtx : const0_rtx;
5937 operands[5] = GEN_INT (value & 0xffff0000);
5938 operands[6] = GEN_INT (value & 0x0000ffff);
5939 }")
5940
5941 (define_split
5942 [(set (match_operand:DI 0 "gpc_reg_operand" "")
5943 (match_operand:DI 1 "const_double_operand" ""))]
5944 "TARGET_32BIT && reload_completed && num_insns_constant (operands[1], DImode) <= 2"
5945 [(set (match_dup 2) (match_dup 4))
5946 (set (match_dup 3) (match_dup 5))]
5947 "
5948 {
5949 operands[2] = gen_rtx (SUBREG, SImode, operands[0], WORDS_BIG_ENDIAN == 0);
5950 operands[3] = gen_rtx (SUBREG, SImode, operands[0], WORDS_BIG_ENDIAN != 0);
5951 operands[4] = GEN_INT (CONST_DOUBLE_HIGH (operands[1]));
5952 operands[5] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
5953 }")
5954
5955 (define_split
5956 [(set (match_operand:DI 0 "gpc_reg_operand" "")
5957 (match_operand:DI 1 "const_double_operand" ""))]
5958 "TARGET_32BIT && reload_completed && num_insns_constant (operands[1], DImode) == 3"
5959 [(set (match_dup 2) (match_dup 4))
5960 (set (match_dup 3) (match_dup 5))
5961 (set (match_dup 2) (ior:SI (match_dup 2) (match_dup 6)))]
5962 "
5963 {
5964 HOST_WIDE_INT high = CONST_DOUBLE_HIGH (operands[1]);
5965 HOST_WIDE_INT low = CONST_DOUBLE_LOW (operands[1]);
5966 rtx high_reg = gen_rtx (SUBREG, SImode, operands[0], WORDS_BIG_ENDIAN == 0);
5967 rtx low_reg = gen_rtx (SUBREG, SImode, operands[0], WORDS_BIG_ENDIAN != 0);
5968
5969 if (((unsigned HOST_WIDE_INT) (low + 0x8000) < 0x10000)
5970 || (low & 0xffff) == 0)
5971 {
5972 operands[2] = high_reg;
5973 operands[3] = low_reg;
5974 operands[4] = GEN_INT (high & 0xffff0000);
5975 operands[5] = GEN_INT (low);
5976 operands[6] = GEN_INT (high & 0x0000ffff);
5977 }
5978 else
5979 {
5980 operands[2] = low_reg;
5981 operands[3] = high_reg;
5982 operands[4] = GEN_INT (low & 0xffff0000);
5983 operands[5] = GEN_INT (high);
5984 operands[6] = GEN_INT (low & 0x0000ffff);
5985 }
5986 }")
5987
5988 (define_split
5989 [(set (match_operand:DI 0 "gpc_reg_operand" "")
5990 (match_operand:DI 1 "const_double_operand" ""))]
5991 "TARGET_32BIT && reload_completed && num_insns_constant (operands[1], DImode) >= 4"
5992 [(set (match_dup 2) (match_dup 4))
5993 (set (match_dup 3) (match_dup 5))
5994 (set (match_dup 2) (ior:SI (match_dup 2) (match_dup 6)))
5995 (set (match_dup 3) (ior:SI (match_dup 3) (match_dup 7)))]
5996 "
5997 {
5998 HOST_WIDE_INT high = CONST_DOUBLE_HIGH (operands[1]);
5999 HOST_WIDE_INT low = CONST_DOUBLE_LOW (operands[1]);
6000
6001 operands[2] = gen_rtx (SUBREG, SImode, operands[0], WORDS_BIG_ENDIAN == 0);
6002 operands[3] = gen_rtx (SUBREG, SImode, operands[0], WORDS_BIG_ENDIAN != 0);
6003 operands[4] = GEN_INT (high & 0xffff0000);
6004 operands[5] = GEN_INT (low & 0xffff0000);
6005 operands[6] = GEN_INT (high & 0x0000ffff);
6006 operands[7] = GEN_INT (low & 0x0000ffff);
6007 }")
6008
6009 (define_insn "*movdi_64"
6010 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m,r,r,r,r,f,f,m,r,*h,*h")
6011 (match_operand:DI 1 "input_operand" "r,m,r,I,J,nF,R,f,m,f,*h,r,0"))]
6012 "TARGET_64BIT
6013 && (gpc_reg_operand (operands[0], DImode)
6014 || gpc_reg_operand (operands[1], DImode))"
6015 "@
6016 mr %0,%1
6017 ld%U1%X1 %0,%1
6018 std%U0%X0 %1,%0
6019 li %0,%1
6020 lis %0,%v1
6021 #
6022 {cal|la} %0,%1(%*)
6023 fmr %0,%1
6024 lfd%U1%X1 %0,%1
6025 stfd%U0%X0 %1,%0
6026 mf%1 %0
6027 mt%0 %1
6028 cror 0,0,0"
6029 [(set_attr "type" "*,load,store,*,*,*,*,fp,fpload,fpstore,*,mtjmpr,*")
6030 (set_attr "length" "4,4,4,4,4,20,4,4,4,4,4,4,4")])
6031
6032 ;; Split a load of a large constant into the appropriate five-instruction
6033 ;; sequence. The expansion in movdi tries to perform the minimum number of
6034 ;; steps, but here we have to handle anything in a constant number of insns.
6035
6036 (define_split
6037 [(set (match_operand:DI 0 "gpc_reg_operand" "")
6038 (match_operand:DI 1 "const_double_operand" ""))]
6039 "TARGET_64BIT && num_insns_constant (operands[1], DImode) > 1"
6040 [(set (match_dup 0)
6041 (match_dup 2))
6042 (set (match_dup 0)
6043 (ior:DI (match_dup 0)
6044 (match_dup 3)))
6045 (set (match_dup 0)
6046 (ashift:DI (match_dup 0)
6047 (const_int 32)))
6048 (set (match_dup 0)
6049 (ior:DI (match_dup 0)
6050 (match_dup 4)))
6051 (set (match_dup 0)
6052 (ior:DI (match_dup 0)
6053 (match_dup 5)))]
6054 "
6055 {
6056 HOST_WIDE_INT low;
6057 HOST_WIDE_INT high;
6058
6059 if (GET_CODE (operands[1]) == CONST_DOUBLE)
6060 {
6061 low = CONST_DOUBLE_LOW (operands[1]);
6062 high = CONST_DOUBLE_HIGH (operands[1]);
6063 }
6064 else
6065 #if HOST_BITS_PER_WIDE_INT == 32
6066 {
6067 low = INTVAL (operands[1]);
6068 high = (low < 0) ? ~0 : 0;
6069 }
6070 #else
6071 {
6072 low = INTVAL (operands[1]) & 0xffffffff;
6073 high = (HOST_WIDE_INT) INTVAL (operands[1]) >> 32;
6074 }
6075 #endif
6076
6077 if ((high + 0x8000) < 0x10000
6078 && ((low & 0xffff) == 0 || (low & (~ (HOST_WIDE_INT) 0xffff)) == 0))
6079 FAIL;
6080
6081 operands[2] = GEN_INT (high & (~ (HOST_WIDE_INT) 0xffff));
6082 operands[3] = GEN_INT (high & 0xffff);
6083 operands[4] = GEN_INT (low & (~ (HOST_WIDE_INT) 0xffff));
6084 operands[5] = GEN_INT (low & 0xffff);
6085 }")
6086
6087 (define_insn ""
6088 [(set (match_operand:CC 2 "cc_reg_operand" "=x")
6089 (compare:CC (match_operand:DI 1 "gpc_reg_operand" "r")
6090 (const_int 0)))
6091 (set (match_operand:DI 0 "gpc_reg_operand" "=r") (match_dup 1))]
6092 "TARGET_POWERPC64"
6093 "mr. %0,%1"
6094 [(set_attr "type" "compare")])
6095 \f
6096 ;; TImode is similar, except that we usually want to compute the address into
6097 ;; a register and use lsi/stsi (the exception is during reload). MQ is also
6098 ;; clobbered in stsi for POWER, so we need a SCRATCH for it.
6099 (define_expand "movti"
6100 [(parallel [(set (match_operand:TI 0 "general_operand" "")
6101 (match_operand:TI 1 "general_operand" ""))
6102 (clobber (scratch:SI))])]
6103 "TARGET_STRING || TARGET_POWERPC64"
6104 "
6105 {
6106 if (GET_CODE (operands[0]) == MEM)
6107 operands[1] = force_reg (TImode, operands[1]);
6108
6109 if (GET_CODE (operands[0]) == MEM
6110 && GET_CODE (XEXP (operands[0], 0)) != REG
6111 && ! reload_in_progress)
6112 operands[0] = change_address (operands[0], TImode,
6113 copy_addr_to_reg (XEXP (operands[0], 0)));
6114
6115 if (GET_CODE (operands[1]) == MEM
6116 && GET_CODE (XEXP (operands[1], 0)) != REG
6117 && ! reload_in_progress)
6118 operands[1] = change_address (operands[1], TImode,
6119 copy_addr_to_reg (XEXP (operands[1], 0)));
6120 }")
6121
6122 ;; We say that MQ is clobbered in the last alternative because the first
6123 ;; alternative would never get used otherwise since it would need a reload
6124 ;; while the 2nd alternative would not. We put memory cases first so they
6125 ;; are preferred. Otherwise, we'd try to reload the output instead of
6126 ;; giving the SCRATCH mq.
6127 (define_insn ""
6128 [(set (match_operand:TI 0 "reg_or_mem_operand" "=Q,m,????r,????r,????r")
6129 (match_operand:TI 1 "reg_or_mem_operand" "r,r,r,Q,m"))
6130 (clobber (match_scratch:SI 2 "=q,q#X,X,X,X"))]
6131 "TARGET_STRING && TARGET_POWER && ! TARGET_POWERPC64
6132 && (gpc_reg_operand (operands[0], TImode) || gpc_reg_operand (operands[1], TImode))"
6133 "*
6134 {
6135 switch (which_alternative)
6136 {
6137 default:
6138 abort ();
6139
6140 case 0:
6141 return \"{stsi|stswi} %1,%P0,16\";
6142
6143 case 1:
6144 return \"{st%U0|stw%U0} %1,%0\;{st|stw} %L1,%L0\;{st|stw} %Y1,%Y0\;{st|stw} %Z1,%Z0\";
6145
6146 case 2:
6147 /* Normally copy registers with lowest numbered register copied first.
6148 But copy in the other order if the first register of the output
6149 is the second, third, or fourth register in the input. */
6150 if (REGNO (operands[0]) >= REGNO (operands[1]) + 1
6151 && REGNO (operands[0]) <= REGNO (operands[1]) + 3)
6152 return \"mr %Z0,%Z1\;mr %Y0,%Y1\;mr %L0,%L1\;mr %0,%1\";
6153 else
6154 return \"mr %0,%1\;mr %L0,%L1\;mr %Y0,%Y1\;mr %Z0,%Z1\";
6155 case 3:
6156 /* If the address is not used in the output, we can use lsi. Otherwise,
6157 fall through to generating four loads. */
6158 if (! reg_overlap_mentioned_p (operands[0], operands[1]))
6159 return \"{lsi|lswi} %0,%P1,16\";
6160 /* ... fall through ... */
6161 case 4:
6162 /* If the address register is the same as the register for the lowest-
6163 addressed word, load it last. Similarly for the next two words.
6164 Otherwise load lowest address to highest. */
6165 if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
6166 operands[1], 0))
6167 return \"{l|lwz} %L0,%L1\;{l|lwz} %Y0,%Y1\;{l|lwz} %Z0,%Z1\;{l|lwz} %0,%1\";
6168 else if (refers_to_regno_p (REGNO (operands[0]) + 1,
6169 REGNO (operands[0]) + 2, operands[1], 0))
6170 return \"{l|lwz} %0,%1\;{l|lwz} %Y0,%Y1\;{l|lwz} %Z0,%Z1\;{l|lwz} %L0,%L1\";
6171 else if (refers_to_regno_p (REGNO (operands[0]) + 2,
6172 REGNO (operands[0]) + 3, operands[1], 0))
6173 return \"{l|lwz} %0,%1\;{l|lwz} %L0,%L1\;{l|lwz} %Z0,%Z1\;{l|lwz} %Y0,%Y1\";
6174 else
6175 return \"{l%U1|lwz%U1} %0,%1\;{l|lwz} %L0,%L1\;{l|lwz} %Y0,%Y1\;{l|lwz} %Z0,%Z1\";
6176 }
6177 }"
6178 [(set_attr "type" "store,store,*,load,load")
6179 (set_attr "length" "*,16,16,*,16")])
6180
6181 (define_insn ""
6182 [(set (match_operand:TI 0 "reg_or_mem_operand" "=m,????r,????r")
6183 (match_operand:TI 1 "reg_or_mem_operand" "r,r,m"))
6184 (clobber (match_scratch:SI 2 "=X,X,X"))]
6185 "TARGET_STRING && !TARGET_POWER && ! TARGET_POWERPC64
6186 && (gpc_reg_operand (operands[0], TImode) || gpc_reg_operand (operands[1], TImode))"
6187 "*
6188 {
6189 switch (which_alternative)
6190 {
6191 default:
6192 abort ();
6193
6194 case 0:
6195 return \"{st%U0|stw%U0} %1,%0\;{st|stw} %L1,%L0\;{st|stw} %Y1,%Y0\;{st|stw} %Z1,%Z0\";
6196
6197 case 1:
6198 /* Normally copy registers with lowest numbered register copied first.
6199 But copy in the other order if the first register of the output
6200 is the second, third, or fourth register in the input. */
6201 if (REGNO (operands[0]) >= REGNO (operands[1]) + 1
6202 && REGNO (operands[0]) <= REGNO (operands[1]) + 3)
6203 return \"mr %Z0,%Z1\;mr %Y0,%Y1\;mr %L0,%L1\;mr %0,%1\";
6204 else
6205 return \"mr %0,%1\;mr %L0,%L1\;mr %Y0,%Y1\;mr %Z0,%Z1\";
6206 case 2:
6207 /* If the address register is the same as the register for the lowest-
6208 addressed word, load it last. Similarly for the next two words.
6209 Otherwise load lowest address to highest. */
6210 if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
6211 operands[1], 0))
6212 return \"{l|lwz} %L0,%L1\;{l|lwz} %Y0,%Y1\;{l|lwz} %Z0,%Z1\;{l|lwz} %0,%1\";
6213 else if (refers_to_regno_p (REGNO (operands[0]) + 1,
6214 REGNO (operands[0]) + 2, operands[1], 0))
6215 return \"{l|lwz} %0,%1\;{l|lwz} %Y0,%Y1\;{l|lwz} %Z0,%Z1\;{l|lwz} %L0,%L1\";
6216 else if (refers_to_regno_p (REGNO (operands[0]) + 2,
6217 REGNO (operands[0]) + 3, operands[1], 0))
6218 return \"{l|lwz} %0,%1\;{l|lwz} %L0,%L1\;{l|lwz} %Z0,%Z1\;{l|lwz} %Y0,%Y1\";
6219 else
6220 return \"{l%U1|lwz%U1} %0,%1\;{l|lwz} %L0,%L1\;{l|lwz} %Y0,%Y1\;{l|lwz} %Z0,%Z1\";
6221 }
6222 }"
6223 [(set_attr "type" "store,*,load")
6224 (set_attr "length" "16,16,16")])
6225
6226 (define_insn ""
6227 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,r,m")
6228 (match_operand:TI 1 "input_operand" "r,m,r"))]
6229 "TARGET_POWERPC64 && (gpc_reg_operand (operands[0], TImode)
6230 || gpc_reg_operand (operands[1], TImode))"
6231 "*
6232 {
6233 switch (which_alternative)
6234 {
6235 case 0:
6236 /* We normally copy the low-numbered register first. However, if
6237 the first register operand 0 is the same as the second register of
6238 operand 1, we must copy in the opposite order. */
6239 if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
6240 return \"mr %L0,%L1\;mr %0,%1\";
6241 else
6242 return \"mr %0,%1\;mr %L0,%L1\";
6243 case 1:
6244 /* If the low-address word is used in the address, we must load it
6245 last. Otherwise, load it first. Note that we cannot have
6246 auto-increment in that case since the address register is known to be
6247 dead. */
6248 if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
6249 operands [1], 0))
6250 return \"ld %L0,%L1\;ld %0,%1\";
6251 else
6252 return \"ld%U1 %0,%1\;ld %L0,%L1\";
6253 case 2:
6254 return \"std%U0 %1,%0\;std %L1,%L0\";
6255 }
6256 }"
6257 [(set_attr "type" "*,load,store")
6258 (set_attr "length" "8,8,8")])
6259 \f
6260 (define_expand "load_multiple"
6261 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
6262 (match_operand:SI 1 "" ""))
6263 (use (match_operand:SI 2 "" ""))])]
6264 "TARGET_STRING"
6265 "
6266 {
6267 int regno;
6268 int count;
6269 rtx from;
6270 int i;
6271
6272 /* Support only loading a constant number of fixed-point registers from
6273 memory and only bother with this if more than two; the machine
6274 doesn't support more than eight. */
6275 if (GET_CODE (operands[2]) != CONST_INT
6276 || INTVAL (operands[2]) <= 2
6277 || INTVAL (operands[2]) > 8
6278 || GET_CODE (operands[1]) != MEM
6279 || GET_CODE (operands[0]) != REG
6280 || REGNO (operands[0]) >= 32)
6281 FAIL;
6282
6283 count = INTVAL (operands[2]);
6284 regno = REGNO (operands[0]);
6285
6286 operands[3] = gen_rtx (PARALLEL, VOIDmode, rtvec_alloc (count));
6287 from = force_reg (SImode, XEXP (operands[1], 0));
6288
6289 for (i = 0; i < count; i++)
6290 XVECEXP (operands[3], 0, i)
6291 = gen_rtx (SET, VOIDmode, gen_rtx (REG, SImode, regno + i),
6292 gen_rtx (MEM, SImode, plus_constant (from, i * 4)));
6293 }")
6294
6295 (define_insn ""
6296 [(match_parallel 0 "load_multiple_operation"
6297 [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
6298 (mem:SI (match_operand:SI 2 "register_operand" "b")))])]
6299 "TARGET_STRING"
6300 "*
6301 {
6302 /* We have to handle the case where the pseudo used to contain the address
6303 is assigned to one of the output registers. */
6304 int i, j;
6305 int words = XVECLEN (operands[0], 0);
6306 rtx xop[10];
6307
6308 if (XVECLEN (operands[0], 0) == 1)
6309 return \"{l|lwz} %1,0(%2)\";
6310
6311 for (i = 0; i < words; i++)
6312 if (refers_to_regno_p (REGNO (operands[1]) + i,
6313 REGNO (operands[1]) + i + 1, operands[2], 0))
6314 {
6315 if (i == words-1)
6316 {
6317 xop[0] = operands[1];
6318 xop[1] = operands[2];
6319 xop[2] = GEN_INT (4 * (words-1));
6320 output_asm_insn (\"{lsi|lswi} %0,%1,%2\;{l|lwz} %1,%2(%1)\", xop);
6321 return \"\";
6322 }
6323 else if (i == 0)
6324 {
6325 xop[0] = operands[1];
6326 xop[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1);
6327 xop[2] = GEN_INT (4 * (words-1));
6328 output_asm_insn (\"{cal %0,4(%0)|addi %0,%0,4}\;{lsi|lswi} %1,%0,%2\;{l|lwz} %0,-4(%0)\", xop);
6329 return \"\";
6330 }
6331 else
6332 {
6333 for (j = 0; j < words; j++)
6334 if (j != i)
6335 {
6336 xop[0] = gen_rtx (REG, SImode, REGNO (operands[1]) + j);
6337 xop[1] = operands[2];
6338 xop[2] = GEN_INT (j * 4);
6339 output_asm_insn (\"{l|lwz} %0,%2(%1)\", xop);
6340 }
6341 xop[0] = operands[2];
6342 xop[1] = GEN_INT (i * 4);
6343 output_asm_insn (\"{l|lwz} %0,%1(%0)\", xop);
6344 return \"\";
6345 }
6346 }
6347
6348 return \"{lsi|lswi} %1,%2,%N0\";
6349 }"
6350 [(set_attr "type" "load")
6351 (set_attr "length" "32")])
6352
6353 \f
6354 (define_expand "store_multiple"
6355 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
6356 (match_operand:SI 1 "" ""))
6357 (clobber (scratch:SI))
6358 (use (match_operand:SI 2 "" ""))])]
6359 "TARGET_STRING"
6360 "
6361 {
6362 int regno;
6363 int count;
6364 rtx to;
6365 int i;
6366
6367 /* Support only storing a constant number of fixed-point registers to
6368 memory and only bother with this if more than two; the machine
6369 doesn't support more than eight. */
6370 if (GET_CODE (operands[2]) != CONST_INT
6371 || INTVAL (operands[2]) <= 2
6372 || INTVAL (operands[2]) > 8
6373 || GET_CODE (operands[0]) != MEM
6374 || GET_CODE (operands[1]) != REG
6375 || REGNO (operands[1]) >= 32)
6376 FAIL;
6377
6378 count = INTVAL (operands[2]);
6379 regno = REGNO (operands[1]);
6380
6381 operands[3] = gen_rtx (PARALLEL, VOIDmode, rtvec_alloc (count + 1));
6382 to = force_reg (SImode, XEXP (operands[0], 0));
6383
6384 XVECEXP (operands[3], 0, 0)
6385 = gen_rtx (SET, VOIDmode, gen_rtx (MEM, SImode, to), operands[1]);
6386 XVECEXP (operands[3], 0, 1) = gen_rtx (CLOBBER, VOIDmode,
6387 gen_rtx (SCRATCH, SImode));
6388
6389 for (i = 1; i < count; i++)
6390 XVECEXP (operands[3], 0, i + 1)
6391 = gen_rtx (SET, VOIDmode,
6392 gen_rtx (MEM, SImode, plus_constant (to, i * 4)),
6393 gen_rtx (REG, SImode, regno + i));
6394 }")
6395
6396 (define_insn ""
6397 [(match_parallel 0 "store_multiple_operation"
6398 [(set (match_operand:SI 1 "indirect_operand" "=Q")
6399 (match_operand:SI 2 "gpc_reg_operand" "r"))
6400 (clobber (match_scratch:SI 3 "=q"))])]
6401 "TARGET_STRING && TARGET_POWER"
6402 "{stsi|stswi} %2,%P1,%O0"
6403 [(set_attr "type" "store")])
6404
6405 (define_insn ""
6406 [(match_parallel 0 "store_multiple_operation"
6407 [(set (mem:SI (match_operand:SI 1 "register_operand" "b"))
6408 (match_operand:SI 2 "gpc_reg_operand" "r"))
6409 (clobber (match_scratch:SI 3 "X"))])]
6410 "TARGET_STRING && !TARGET_POWER"
6411 "{stsi|stswi} %2,%1,%O0"
6412 [(set_attr "type" "store")])
6413
6414 \f
6415 ;; String/block move insn.
6416 ;; Argument 0 is the destination
6417 ;; Argument 1 is the source
6418 ;; Argument 2 is the length
6419 ;; Argument 3 is the alignment
6420
6421 (define_expand "movstrsi"
6422 [(parallel [(set (match_operand:BLK 0 "" "")
6423 (match_operand:BLK 1 "" ""))
6424 (use (match_operand:SI 2 "" ""))
6425 (use (match_operand:SI 3 "" ""))])]
6426 ""
6427 "
6428 {
6429 if (expand_block_move (operands))
6430 DONE;
6431 else
6432 FAIL;
6433 }")
6434
6435 ;; Move up to 32 bytes at a time. The fixed registers are needed because the
6436 ;; register allocator doesn't have a clue about allocating 8 word registers
6437 (define_expand "movstrsi_8reg"
6438 [(parallel [(set (match_operand 0 "" "")
6439 (match_operand 1 "" ""))
6440 (use (match_operand 2 "" ""))
6441 (use (match_operand 3 "" ""))
6442 (clobber (reg:SI 5))
6443 (clobber (reg:SI 6))
6444 (clobber (reg:SI 7))
6445 (clobber (reg:SI 8))
6446 (clobber (reg:SI 9))
6447 (clobber (reg:SI 10))
6448 (clobber (reg:SI 11))
6449 (clobber (reg:SI 12))
6450 (clobber (match_scratch:SI 4 ""))])]
6451 "TARGET_STRING"
6452 "")
6453
6454 (define_insn ""
6455 [(set (mem:BLK (match_operand:SI 0 "register_operand" "b"))
6456 (mem:BLK (match_operand:SI 1 "register_operand" "b")))
6457 (use (match_operand:SI 2 "immediate_operand" "i"))
6458 (use (match_operand:SI 3 "immediate_operand" "i"))
6459 (clobber (match_operand:SI 4 "register_operand" "=r"))
6460 (clobber (reg:SI 6))
6461 (clobber (reg:SI 7))
6462 (clobber (reg:SI 8))
6463 (clobber (reg:SI 9))
6464 (clobber (reg:SI 10))
6465 (clobber (reg:SI 11))
6466 (clobber (reg:SI 12))
6467 (clobber (match_scratch:SI 5 "=q"))]
6468 "TARGET_STRING && TARGET_POWER
6469 && ((INTVAL (operands[2]) > 24 && INTVAL (operands[2]) < 32) || INTVAL (operands[2]) == 0)
6470 && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 12)
6471 && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 12)
6472 && REGNO (operands[4]) == 5"
6473 "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2"
6474 [(set_attr "type" "load")
6475 (set_attr "length" "8")])
6476
6477 (define_insn ""
6478 [(set (mem:BLK (match_operand:SI 0 "register_operand" "b"))
6479 (mem:BLK (match_operand:SI 1 "register_operand" "b")))
6480 (use (match_operand:SI 2 "immediate_operand" "i"))
6481 (use (match_operand:SI 3 "immediate_operand" "i"))
6482 (clobber (match_operand:SI 4 "register_operand" "=r"))
6483 (clobber (reg:SI 6))
6484 (clobber (reg:SI 7))
6485 (clobber (reg:SI 8))
6486 (clobber (reg:SI 9))
6487 (clobber (reg:SI 10))
6488 (clobber (reg:SI 11))
6489 (clobber (reg:SI 12))
6490 (clobber (match_scratch:SI 5 "X"))]
6491 "TARGET_STRING && !TARGET_POWER
6492 && ((INTVAL (operands[2]) > 24 && INTVAL (operands[2]) < 32) || INTVAL (operands[2]) == 0)
6493 && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 12)
6494 && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 12)
6495 && REGNO (operands[4]) == 5"
6496 "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2"
6497 [(set_attr "type" "load")
6498 (set_attr "length" "8")])
6499
6500 ;; Move up to 24 bytes at a time. The fixed registers are needed because the
6501 ;; register allocator doesn't have a clue about allocating 6 word registers
6502 (define_expand "movstrsi_6reg"
6503 [(parallel [(set (match_operand 0 "" "")
6504 (match_operand 1 "" ""))
6505 (use (match_operand 2 "" ""))
6506 (use (match_operand 3 "" ""))
6507 (clobber (reg:SI 7))
6508 (clobber (reg:SI 8))
6509 (clobber (reg:SI 9))
6510 (clobber (reg:SI 10))
6511 (clobber (reg:SI 11))
6512 (clobber (reg:SI 12))
6513 (clobber (match_scratch:SI 4 ""))])]
6514 "TARGET_STRING"
6515 "")
6516
6517 (define_insn ""
6518 [(set (mem:BLK (match_operand:SI 0 "register_operand" "b"))
6519 (mem:BLK (match_operand:SI 1 "register_operand" "b")))
6520 (use (match_operand:SI 2 "immediate_operand" "i"))
6521 (use (match_operand:SI 3 "immediate_operand" "i"))
6522 (clobber (match_operand:SI 4 "register_operand" "=r"))
6523 (clobber (reg:SI 8))
6524 (clobber (reg:SI 9))
6525 (clobber (reg:SI 10))
6526 (clobber (reg:SI 11))
6527 (clobber (reg:SI 12))
6528 (clobber (match_scratch:SI 5 "=q"))]
6529 "TARGET_STRING && TARGET_POWER
6530 && INTVAL (operands[2]) > 16 && INTVAL (operands[2]) <= 24
6531 && (REGNO (operands[0]) < 7 || REGNO (operands[0]) > 12)
6532 && (REGNO (operands[1]) < 7 || REGNO (operands[1]) > 12)
6533 && REGNO (operands[4]) == 7"
6534 "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2"
6535 [(set_attr "type" "load")
6536 (set_attr "length" "8")])
6537
6538 (define_insn ""
6539 [(set (mem:BLK (match_operand:SI 0 "register_operand" "b"))
6540 (mem:BLK (match_operand:SI 1 "register_operand" "b")))
6541 (use (match_operand:SI 2 "immediate_operand" "i"))
6542 (use (match_operand:SI 3 "immediate_operand" "i"))
6543 (clobber (match_operand:SI 4 "register_operand" "=r"))
6544 (clobber (reg:SI 8))
6545 (clobber (reg:SI 9))
6546 (clobber (reg:SI 10))
6547 (clobber (reg:SI 11))
6548 (clobber (reg:SI 12))
6549 (clobber (match_scratch:SI 5 "X"))]
6550 "TARGET_STRING && !TARGET_POWER
6551 && INTVAL (operands[2]) > 16 && INTVAL (operands[2]) <= 32
6552 && (REGNO (operands[0]) < 7 || REGNO (operands[0]) > 12)
6553 && (REGNO (operands[1]) < 7 || REGNO (operands[1]) > 12)
6554 && REGNO (operands[4]) == 7"
6555 "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2"
6556 [(set_attr "type" "load")
6557 (set_attr "length" "8")])
6558
6559 ;; Move up to 16 bytes at a time, using 4 fixed registers to avoid spill problems
6560 ;; with TImode
6561 (define_expand "movstrsi_4reg"
6562 [(parallel [(set (match_operand 0 "" "")
6563 (match_operand 1 "" ""))
6564 (use (match_operand 2 "" ""))
6565 (use (match_operand 3 "" ""))
6566 (clobber (reg:SI 9))
6567 (clobber (reg:SI 10))
6568 (clobber (reg:SI 11))
6569 (clobber (reg:SI 12))
6570 (clobber (match_scratch:SI 4 ""))])]
6571 "TARGET_STRING"
6572 "")
6573
6574 (define_insn ""
6575 [(set (mem:BLK (match_operand:SI 0 "register_operand" "b"))
6576 (mem:BLK (match_operand:SI 1 "register_operand" "b")))
6577 (use (match_operand:SI 2 "immediate_operand" "i"))
6578 (use (match_operand:SI 3 "immediate_operand" "i"))
6579 (clobber (match_operand:SI 4 "register_operand" "=r"))
6580 (clobber (reg:SI 10))
6581 (clobber (reg:SI 11))
6582 (clobber (reg:SI 12))
6583 (clobber (match_scratch:SI 5 "=q"))]
6584 "TARGET_STRING && TARGET_POWER
6585 && INTVAL (operands[2]) > 8 && INTVAL (operands[2]) <= 16
6586 && (REGNO (operands[0]) < 9 || REGNO (operands[0]) > 12)
6587 && (REGNO (operands[1]) < 9 || REGNO (operands[1]) > 12)
6588 && REGNO (operands[4]) == 9"
6589 "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2"
6590 [(set_attr "type" "load")
6591 (set_attr "length" "8")])
6592
6593 (define_insn ""
6594 [(set (mem:BLK (match_operand:SI 0 "register_operand" "b"))
6595 (mem:BLK (match_operand:SI 1 "register_operand" "b")))
6596 (use (match_operand:SI 2 "immediate_operand" "i"))
6597 (use (match_operand:SI 3 "immediate_operand" "i"))
6598 (clobber (match_operand:SI 4 "register_operand" "=r"))
6599 (clobber (reg:SI 10))
6600 (clobber (reg:SI 11))
6601 (clobber (reg:SI 12))
6602 (clobber (match_scratch:SI 5 "X"))]
6603 "TARGET_STRING && !TARGET_POWER
6604 && INTVAL (operands[2]) > 8 && INTVAL (operands[2]) <= 16
6605 && (REGNO (operands[0]) < 9 || REGNO (operands[0]) > 12)
6606 && (REGNO (operands[1]) < 9 || REGNO (operands[1]) > 12)
6607 && REGNO (operands[4]) == 9"
6608 "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2"
6609 [(set_attr "type" "load")
6610 (set_attr "length" "8")])
6611
6612 ;; Move up to 8 bytes at a time.
6613 (define_expand "movstrsi_2reg"
6614 [(parallel [(set (match_operand 0 "" "")
6615 (match_operand 1 "" ""))
6616 (use (match_operand 2 "" ""))
6617 (use (match_operand 3 "" ""))
6618 (clobber (match_scratch:DI 4 ""))
6619 (clobber (match_scratch:SI 5 ""))])]
6620 "TARGET_STRING && !TARGET_64BIT"
6621 "")
6622
6623 (define_insn ""
6624 [(set (mem:BLK (match_operand:SI 0 "register_operand" "b"))
6625 (mem:BLK (match_operand:SI 1 "register_operand" "b")))
6626 (use (match_operand:SI 2 "immediate_operand" "i"))
6627 (use (match_operand:SI 3 "immediate_operand" "i"))
6628 (clobber (match_scratch:DI 4 "=&r"))
6629 (clobber (match_scratch:SI 5 "=q"))]
6630 "TARGET_STRING && TARGET_POWER && !TARGET_64BIT
6631 && INTVAL (operands[2]) > 4 && INTVAL (operands[2]) <= 8"
6632 "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2"
6633 [(set_attr "type" "load")
6634 (set_attr "length" "8")])
6635
6636 (define_insn ""
6637 [(set (mem:BLK (match_operand:SI 0 "register_operand" "b"))
6638 (mem:BLK (match_operand:SI 1 "register_operand" "b")))
6639 (use (match_operand:SI 2 "immediate_operand" "i"))
6640 (use (match_operand:SI 3 "immediate_operand" "i"))
6641 (clobber (match_scratch:DI 4 "=&r"))
6642 (clobber (match_scratch:SI 5 "X"))]
6643 "TARGET_STRING && !TARGET_POWER && !TARGET_64BIT
6644 && INTVAL (operands[2]) > 4 && INTVAL (operands[2]) <= 8"
6645 "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2"
6646 [(set_attr "type" "load")
6647 (set_attr "length" "8")])
6648
6649 ;; Move up to 4 bytes at a time.
6650 (define_expand "movstrsi_1reg"
6651 [(parallel [(set (match_operand 0 "" "")
6652 (match_operand 1 "" ""))
6653 (use (match_operand 2 "" ""))
6654 (use (match_operand 3 "" ""))
6655 (clobber (match_scratch:SI 4 ""))
6656 (clobber (match_scratch:SI 5 ""))])]
6657 "TARGET_STRING"
6658 "")
6659
6660 (define_insn ""
6661 [(set (mem:BLK (match_operand:SI 0 "register_operand" "b"))
6662 (mem:BLK (match_operand:SI 1 "register_operand" "b")))
6663 (use (match_operand:SI 2 "immediate_operand" "i"))
6664 (use (match_operand:SI 3 "immediate_operand" "i"))
6665 (clobber (match_scratch:SI 4 "=&r"))
6666 (clobber (match_scratch:SI 5 "=q"))]
6667 "TARGET_STRING && TARGET_POWER
6668 && INTVAL (operands[2]) > 0 && INTVAL (operands[2]) <= 4"
6669 "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2"
6670 [(set_attr "type" "load")
6671 (set_attr "length" "8")])
6672
6673 (define_insn ""
6674 [(set (mem:BLK (match_operand:SI 0 "register_operand" "b"))
6675 (mem:BLK (match_operand:SI 1 "register_operand" "b")))
6676 (use (match_operand:SI 2 "immediate_operand" "i"))
6677 (use (match_operand:SI 3 "immediate_operand" "i"))
6678 (clobber (match_scratch:SI 4 "=&r"))
6679 (clobber (match_scratch:SI 5 "X"))]
6680 "TARGET_STRING && !TARGET_POWER
6681 && INTVAL (operands[2]) > 0 && INTVAL (operands[2]) <= 4"
6682 "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2"
6683 [(set_attr "type" "load")
6684 (set_attr "length" "8")])
6685
6686 \f
6687 ;; Define insns that do load or store with update. Some of these we can
6688 ;; get by using pre-decrement or pre-increment, but the hardware can also
6689 ;; do cases where the increment is not the size of the object.
6690 ;;
6691 ;; In all these cases, we use operands 0 and 1 for the register being
6692 ;; incremented because those are the operands that local-alloc will
6693 ;; tie and these are the pair most likely to be tieable (and the ones
6694 ;; that will benefit the most).
6695
6696 (define_insn ""
6697 [(set (match_operand:DI 3 "gpc_reg_operand" "=r,r")
6698 (mem:DI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0,0")
6699 (match_operand:DI 2 "reg_or_short_operand" "r,I"))))
6700 (set (match_operand:DI 0 "gpc_reg_operand" "=b,b")
6701 (plus:DI (match_dup 1) (match_dup 2)))]
6702 "TARGET_POWERPC64"
6703 "@
6704 ldux %3,%0,%2
6705 ldu %3,%2(%0)"
6706 [(set_attr "type" "load")])
6707
6708 (define_insn ""
6709 [(set (match_operand:DI 3 "gpc_reg_operand" "=r")
6710 (sign_extend:DI
6711 (mem:SI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0")
6712 (match_operand:DI 2 "gpc_reg_operand" "r")))))
6713 (set (match_operand:DI 0 "gpc_reg_operand" "=b")
6714 (plus:DI (match_dup 1) (match_dup 2)))]
6715 "TARGET_POWERPC64"
6716 "lwaux %3,%0,%2"
6717 [(set_attr "type" "load")])
6718
6719 (define_insn "movdi_update"
6720 [(set (mem:DI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0,0")
6721 (match_operand:DI 2 "reg_or_short_operand" "r,I")))
6722 (match_operand:DI 3 "gpc_reg_operand" "r,r"))
6723 (set (match_operand:DI 0 "gpc_reg_operand" "=b,b")
6724 (plus:DI (match_dup 1) (match_dup 2)))]
6725 "TARGET_POWERPC64"
6726 "@
6727 stdux %3,%0,%2
6728 stdu %3,%2(%0)"
6729 [(set_attr "type" "store")])
6730
6731 (define_insn ""
6732 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
6733 (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
6734 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
6735 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
6736 (plus:SI (match_dup 1) (match_dup 2)))]
6737 ""
6738 "@
6739 {lux|lwzux} %3,%0,%2
6740 {lu|lwzu} %3,%2(%0)"
6741 [(set_attr "type" "load")])
6742
6743 (define_insn "movsi_update"
6744 [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
6745 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
6746 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
6747 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
6748 (plus:SI (match_dup 1) (match_dup 2)))]
6749 ""
6750 "@
6751 {stux|stwux} %3,%0,%2
6752 {stu|stwu} %3,%2(%0)"
6753 [(set_attr "type" "store")])
6754
6755 (define_insn ""
6756 [(set (match_operand:HI 3 "gpc_reg_operand" "=r,r")
6757 (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
6758 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
6759 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
6760 (plus:SI (match_dup 1) (match_dup 2)))]
6761 ""
6762 "@
6763 lhzux %3,%0,%2
6764 lhzu %3,%2(%0)"
6765 [(set_attr "type" "load")])
6766
6767 (define_insn ""
6768 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
6769 (zero_extend:SI
6770 (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
6771 (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
6772 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
6773 (plus:SI (match_dup 1) (match_dup 2)))]
6774 ""
6775 "@
6776 lhzux %3,%0,%2
6777 lhzu %3,%2(%0)"
6778 [(set_attr "type" "load")])
6779
6780 (define_insn ""
6781 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
6782 (sign_extend:SI
6783 (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
6784 (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
6785 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
6786 (plus:SI (match_dup 1) (match_dup 2)))]
6787 ""
6788 "@
6789 lhaux %3,%0,%2
6790 lhau %3,%2(%0)"
6791 [(set_attr "type" "load")])
6792
6793 (define_insn ""
6794 [(set (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
6795 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
6796 (match_operand:HI 3 "gpc_reg_operand" "r,r"))
6797 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
6798 (plus:SI (match_dup 1) (match_dup 2)))]
6799 ""
6800 "@
6801 sthux %3,%0,%2
6802 sthu %3,%2(%0)"
6803 [(set_attr "type" "store")])
6804
6805 (define_insn ""
6806 [(set (match_operand:QI 3 "gpc_reg_operand" "=r,r")
6807 (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
6808 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
6809 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
6810 (plus:SI (match_dup 1) (match_dup 2)))]
6811 ""
6812 "@
6813 lbzux %3,%0,%2
6814 lbzu %3,%2(%0)"
6815 [(set_attr "type" "load")])
6816
6817 (define_insn ""
6818 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
6819 (zero_extend:SI
6820 (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
6821 (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
6822 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
6823 (plus:SI (match_dup 1) (match_dup 2)))]
6824 ""
6825 "@
6826 lbzux %3,%0,%2
6827 lbzu %3,%2(%0)"
6828 [(set_attr "type" "load")])
6829
6830 (define_insn ""
6831 [(set (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
6832 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
6833 (match_operand:QI 3 "gpc_reg_operand" "r,r"))
6834 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
6835 (plus:SI (match_dup 1) (match_dup 2)))]
6836 ""
6837 "@
6838 stbux %3,%0,%2
6839 stbu %3,%2(%0)"
6840 [(set_attr "type" "store")])
6841
6842 (define_insn ""
6843 [(set (match_operand:SF 3 "gpc_reg_operand" "=f,f")
6844 (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
6845 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
6846 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
6847 (plus:SI (match_dup 1) (match_dup 2)))]
6848 "TARGET_HARD_FLOAT"
6849 "@
6850 lfsux %3,%0,%2
6851 lfsu %3,%2(%0)"
6852 [(set_attr "type" "fpload")])
6853
6854 (define_insn ""
6855 [(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
6856 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
6857 (match_operand:SF 3 "gpc_reg_operand" "f,f"))
6858 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
6859 (plus:SI (match_dup 1) (match_dup 2)))]
6860 "TARGET_HARD_FLOAT"
6861 "@
6862 stfsux %3,%0,%2
6863 stfsu %3,%2(%0)"
6864 [(set_attr "type" "fpstore")])
6865
6866 (define_insn ""
6867 [(set (match_operand:DF 3 "gpc_reg_operand" "=f,f")
6868 (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
6869 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
6870 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
6871 (plus:SI (match_dup 1) (match_dup 2)))]
6872 "TARGET_HARD_FLOAT"
6873 "@
6874 lfdux %3,%0,%2
6875 lfdu %3,%2(%0)"
6876 [(set_attr "type" "fpload")])
6877
6878 (define_insn ""
6879 [(set (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
6880 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
6881 (match_operand:DF 3 "gpc_reg_operand" "f,f"))
6882 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
6883 (plus:SI (match_dup 1) (match_dup 2)))]
6884 "TARGET_HARD_FLOAT"
6885 "@
6886 stfdux %3,%0,%2
6887 stfdu %3,%2(%0)"
6888 [(set_attr "type" "fpstore")])
6889
6890 ;; Peephole to convert two consecutive FP loads or stores into lfq/stfq.
6891
6892 (define_peephole
6893 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
6894 (match_operand:DF 1 "memory_operand" ""))
6895 (set (match_operand:DF 2 "gpc_reg_operand" "=f")
6896 (match_operand:DF 3 "memory_operand" ""))]
6897 "TARGET_POWER2
6898 && TARGET_HARD_FLOAT
6899 && registers_ok_for_quad_peep (operands[0], operands[2])
6900 && ! MEM_VOLATILE_P (operands[1]) && ! MEM_VOLATILE_P (operands[3])
6901 && addrs_ok_for_quad_peep (XEXP (operands[1], 0), XEXP (operands[3], 0))"
6902 "lfq%U1%X1 %0,%1")
6903
6904 (define_peephole
6905 [(set (match_operand:DF 0 "memory_operand" "")
6906 (match_operand:DF 1 "gpc_reg_operand" "f"))
6907 (set (match_operand:DF 2 "memory_operand" "")
6908 (match_operand:DF 3 "gpc_reg_operand" "f"))]
6909 "TARGET_POWER2
6910 && TARGET_HARD_FLOAT
6911 && registers_ok_for_quad_peep (operands[1], operands[3])
6912 && ! MEM_VOLATILE_P (operands[0]) && ! MEM_VOLATILE_P (operands[2])
6913 && addrs_ok_for_quad_peep (XEXP (operands[0], 0), XEXP (operands[2], 0))"
6914 "stfq%U0%X0 %1,%0")
6915 \f
6916 ;; Next come insns related to the calling sequence.
6917 ;;
6918 ;; First, an insn to allocate new stack space for dynamic use (e.g., alloca).
6919 ;; We move the back-chain and decrement the stack pointer.
6920
6921 (define_expand "allocate_stack"
6922 [(set (reg:SI 1)
6923 (minus:SI (reg:SI 1) (match_operand:SI 0 "reg_or_short_operand" "")))]
6924 ""
6925 "
6926 { rtx chain = gen_reg_rtx (Pmode);
6927 rtx stack_bot = gen_rtx (MEM, Pmode, stack_pointer_rtx);
6928 rtx neg_op0;
6929
6930 emit_move_insn (chain, stack_bot);
6931
6932 /* Under Windows NT, we need to add stack probes for large/variable allocations,
6933 so do it via a call to the external function alloca, instead of doing it
6934 inline. */
6935 if (DEFAULT_ABI == ABI_NT
6936 && (GET_CODE (operands[0]) != CONST_INT || INTVAL (operands[0]) > 4096))
6937 {
6938 rtx tmp = gen_reg_rtx (SImode);
6939 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"__allocate_stack\"),
6940 tmp, 0, SImode, 1, operands[0], Pmode);
6941 emit_insn (gen_set_sp (tmp));
6942 DONE;
6943 }
6944
6945 if (GET_CODE (operands[0]) != CONST_INT
6946 || INTVAL (operands[0]) < -32767
6947 || INTVAL (operands[0]) > 32768)
6948 {
6949 neg_op0 = gen_reg_rtx (Pmode);
6950 if (TARGET_32BIT)
6951 emit_insn (gen_negsi2 (neg_op0, operands[0]));
6952 else
6953 emit_insn (gen_negdi2 (neg_op0, operands[0]));
6954 }
6955 else
6956 neg_op0 = GEN_INT (- INTVAL (operands[0]));
6957
6958 if (TARGET_32BIT)
6959 emit_insn (gen_movsi_update (stack_pointer_rtx, stack_pointer_rtx, neg_op0, chain));
6960 else
6961 emit_insn (gen_movdi_update (stack_pointer_rtx, stack_pointer_rtx, neg_op0, chain));
6962
6963 DONE;
6964 }")
6965
6966 ;; Marker to indicate that the stack pointer was changed under NT in
6967 ;; ways not known to the compiler
6968
6969 (define_insn "set_sp"
6970 [(set (reg:SI 1)
6971 (unspec [(match_operand:SI 0 "register_operand" "r")] 7))]
6972 ""
6973 ""
6974 [(set_attr "length" "0")])
6975
6976 ;; These patterns say how to save and restore the stack pointer. We need not
6977 ;; save the stack pointer at function level since we are careful to
6978 ;; preserve the backchain. At block level, we have to restore the backchain
6979 ;; when we restore the stack pointer.
6980 ;;
6981 ;; For nonlocal gotos, we must save both the stack pointer and its
6982 ;; backchain and restore both. Note that in the nonlocal case, the
6983 ;; save area is a memory location.
6984
6985 (define_expand "save_stack_function"
6986 [(use (const_int 0))]
6987 ""
6988 "")
6989
6990 (define_expand "restore_stack_function"
6991 [(use (const_int 0))]
6992 ""
6993 "")
6994
6995 (define_expand "restore_stack_block"
6996 [(set (match_dup 2) (mem:SI (match_operand:SI 0 "register_operand" "")))
6997 (set (match_dup 0) (match_operand:SI 1 "register_operand" ""))
6998 (set (mem:SI (match_dup 0)) (match_dup 2))]
6999 ""
7000 "
7001 { operands[2] = gen_reg_rtx (SImode); }")
7002
7003 (define_expand "save_stack_nonlocal"
7004 [(match_operand:DI 0 "memory_operand" "")
7005 (match_operand:SI 1 "register_operand" "")]
7006 ""
7007 "
7008 {
7009 rtx temp = gen_reg_rtx (SImode);
7010
7011 /* Copy the backchain to the first word, sp to the second. */
7012 emit_move_insn (temp, gen_rtx (MEM, SImode, operands[1]));
7013 emit_move_insn (operand_subword (operands[0], 0, 0, DImode), temp);
7014 emit_move_insn (operand_subword (operands[0], 1, 0, DImode), operands[1]);
7015 DONE;
7016 }")
7017
7018 (define_expand "restore_stack_nonlocal"
7019 [(match_operand:SI 0 "register_operand" "")
7020 (match_operand:DI 1 "memory_operand" "")]
7021 ""
7022 "
7023 {
7024 rtx temp = gen_reg_rtx (SImode);
7025
7026 /* Restore the backchain from the first word, sp from the second. */
7027 emit_move_insn (temp, operand_subword (operands[1], 0, 0, DImode));
7028 emit_move_insn (operands[0], operand_subword (operands[1], 1, 0, DImode));
7029 emit_move_insn (gen_rtx (MEM, SImode, operands[0]), temp);
7030 DONE;
7031 }")
7032
7033 \f
7034 ;; A function pointer under AIX is a pointer to a data area whose first word
7035 ;; contains the actual address of the function, whose second word contains a
7036 ;; pointer to its TOC, and whose third word contains a value to place in the
7037 ;; static chain register (r11). Note that if we load the static chain, our
7038 ;; "trampoline" need not have any executable code.
7039 ;;
7040 ;; operands[0] is a register pointing to the 3 word descriptor (aka, the function address)
7041 ;; operands[1] is the stack size to clean up
7042 ;; operands[2] is the value FUNCTION_ARG returns for the VOID argument (must be 0 for AIX)
7043 ;; operands[3] is location to store the TOC
7044 ;; operands[4] is the TOC register
7045 ;; operands[5] is the static chain register
7046 ;;
7047 ;; We do not break this into separate insns, so that the scheduler will not try
7048 ;; to move the load of the new TOC before any loads from the TOC.
7049
7050 (define_insn "call_indirect_aix"
7051 [(call (mem:SI (match_operand:SI 0 "register_operand" "b"))
7052 (match_operand 1 "const_int_operand" "n"))
7053 (use (match_operand 2 "const_int_operand" "n"))
7054 (use (match_operand 3 "offsettable_addr_operand" "p"))
7055 (use (match_operand 4 "register_operand" "r"))
7056 (clobber (match_operand 5 "register_operand" "=r"))
7057 (clobber (match_scratch:SI 6 "=&r"))
7058 (clobber (match_scratch:SI 7 "=l"))]
7059 "DEFAULT_ABI == ABI_AIX
7060 && (INTVAL (operands[2]) == CALL_NORMAL || (INTVAL (operands[2]) & CALL_LONG) != 0)"
7061 "{st|stw} %4,%a3\;{l|lwz} %6,0(%0)\;{l|lwz} %4,4(%0)\;mt%7 %6\;{l|lwz} %5,8(%0)\;{brl|blrl}\;{l|lwz} %4,%a3"
7062 [(set_attr "type" "load")
7063 (set_attr "length" "28")])
7064
7065 (define_insn "call_value_indirect_aix"
7066 [(set (match_operand 0 "register_operand" "fg")
7067 (call (mem:SI (match_operand:SI 1 "register_operand" "b"))
7068 (match_operand 2 "const_int_operand" "n")))
7069 (use (match_operand 3 "const_int_operand" "n"))
7070 (use (match_operand 4 "offsettable_addr_operand" "p"))
7071 (use (match_operand 5 "register_operand" "r"))
7072 (clobber (match_operand 6 "register_operand" "=r"))
7073 (clobber (match_scratch:SI 7 "=&r"))
7074 (clobber (match_scratch:SI 8 "=l"))]
7075 "DEFAULT_ABI == ABI_AIX
7076 && (INTVAL (operands[3]) == CALL_NORMAL || (INTVAL (operands[3]) & CALL_LONG) != 0)"
7077 "{st|stw} %5,%a4\;{l|lwz} %7,0(%1)\;{l|lwz} %5,4(%1);\;mt%8 %7\;{l|lwz} %6,8(%1)\;{brl|blrl}\;{l|lwz} %5,%a4"
7078 [(set_attr "type" "load")
7079 (set_attr "length" "28")])
7080
7081 ;; A function pointer undef NT is a pointer to a data area whose first word
7082 ;; contains the actual address of the function, whose second word contains a
7083 ;; pointer to its TOC. The static chain is not stored under NT, which means
7084 ;; that we need a trampoline.
7085 ;;
7086 ;; operands[0] is an SImode pseudo in which we place the address of the function.
7087 ;; operands[1] is the stack size to clean up
7088 ;; operands[2] is the value FUNCTION_ARG returns for the VOID argument (must be 0 for NT)
7089 ;; operands[3] is location to store the TOC
7090 ;; operands[4] is the TOC register
7091 ;;
7092 ;; We do not break this into separate insns, so that the scheduler will not try
7093 ;; to move the load of the new TOC before any loads from the TOC.
7094
7095 (define_insn "call_indirect_nt"
7096 [(call (mem:SI (match_operand:SI 0 "register_operand" "b"))
7097 (match_operand 1 "const_int_operand" "n"))
7098 (use (match_operand 2 "const_int_operand" "n"))
7099 (use (match_operand 3 "offsettable_addr_operand" "p"))
7100 (use (match_operand 4 "register_operand" "r"))
7101 (clobber (match_scratch:SI 5 "=&r"))
7102 (clobber (match_scratch:SI 6 "=l"))]
7103 "DEFAULT_ABI == ABI_NT
7104 && (INTVAL (operands[2]) == CALL_NORMAL || (INTVAL (operands[2]) & CALL_LONG) != 0)"
7105 "{st|stw} %4,%a3\;{l|lwz} %5,0(%0)\;{l|lwz} %4,4(%0)\;mt%6 %5\;{brl|blrl}\;{l|lwz} %4,%a3"
7106 [(set_attr "type" "load")
7107 (set_attr "length" "24")])
7108
7109 (define_insn "call_value_indirect_nt"
7110 [(set (match_operand 0 "register_operand" "fg")
7111 (call (mem:SI (match_operand:SI 1 "register_operand" "b"))
7112 (match_operand 2 "const_int_operand" "n")))
7113 (use (match_operand 3 "const_int_operand" "n"))
7114 (use (match_operand 4 "offsettable_addr_operand" "p"))
7115 (use (match_operand 5 "register_operand" "r"))
7116 (clobber (match_scratch:SI 6 "=&r"))
7117 (clobber (match_scratch:SI 7 "=l"))]
7118 "DEFAULT_ABI == ABI_NT
7119 && (INTVAL (operands[3]) == CALL_NORMAL || (INTVAL (operands[3]) & CALL_LONG) != 0)"
7120 "{st|stw} %5,%a4\;{l|lwz} %6,0(%1)\;{l|lwz} %5,4(%1)\;mt%7 %6\;{brl|blrl}\;{l|lwz} %5,%a4"
7121 [(set_attr "type" "load")
7122 (set_attr "length" "24")])
7123
7124 ;; A function pointer under System V is just a normal pointer
7125 ;; operands[0] is the function pointer
7126 ;; operands[1] is the stack size to clean up
7127 ;; operands[2] is the value FUNCTION_ARG returns for the VOID argument which indicates how to set cr1
7128
7129 (define_insn "call_indirect_sysv"
7130 [(call (mem:SI (match_operand:SI 0 "register_operand" "l,l"))
7131 (match_operand 1 "const_int_operand" "n,n"))
7132 (use (match_operand 2 "const_int_operand" "O,n"))
7133 (clobber (match_scratch:SI 3 "=l,l"))]
7134 "DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS || DEFAULT_ABI == ABI_AIX_NODESC"
7135 "*
7136 {
7137 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
7138 output_asm_insn (\"crxor 6,6,6\", operands);
7139
7140 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
7141 output_asm_insn (\"creqv 6,6,6\", operands);
7142
7143 return \"{brl|blrl}\";
7144 }"
7145 [(set_attr "type" "jmpreg")
7146 (set_attr "length" "4,8")])
7147
7148 (define_insn "call_value_indirect_sysv"
7149 [(set (match_operand 0 "register_operand" "=fg,fg")
7150 (call (mem:SI (match_operand:SI 1 "register_operand" "l,l"))
7151 (match_operand 2 "const_int_operand" "n,n")))
7152 (use (match_operand 3 "const_int_operand" "O,n"))
7153 (clobber (match_scratch:SI 4 "=l,l"))]
7154 "DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS || DEFAULT_ABI == ABI_AIX_NODESC"
7155 "*
7156 {
7157 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
7158 output_asm_insn (\"crxor 6,6,6\", operands);
7159
7160 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
7161 output_asm_insn (\"creqv 6,6,6\", operands);
7162
7163 return \"{brl|blrl}\";
7164 }"
7165 [(set_attr "type" "jmpreg")
7166 (set_attr "length" "4,8")])
7167
7168 ;; Now the definitions for the call and call_value insns
7169 (define_expand "call"
7170 [(parallel [(call (mem:SI (match_operand:SI 0 "address_operand" ""))
7171 (match_operand 1 "" ""))
7172 (use (match_operand 2 "" ""))
7173 (clobber (scratch:SI))])]
7174 ""
7175 "
7176 {
7177 if (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != CONST_INT)
7178 abort ();
7179
7180 operands[0] = XEXP (operands[0], 0);
7181
7182 /* Convert NT DLL imports into an indirect call. */
7183 if (GET_CODE (operands[0]) == SYMBOL_REF
7184 && (INTVAL (operands[2]) & CALL_NT_DLLIMPORT) != 0)
7185 {
7186 operands[0] = rs6000_dll_import_ref (operands[0]);
7187 operands[2] = GEN_INT ((int)CALL_NORMAL);
7188 }
7189
7190 if (GET_CODE (operands[0]) != SYMBOL_REF
7191 || (INTVAL (operands[2]) & CALL_LONG) != 0)
7192 {
7193 if (INTVAL (operands[2]) & CALL_LONG)
7194 operands[0] = rs6000_longcall_ref (operands[0]);
7195
7196 if (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_AIX_NODESC || DEFAULT_ABI == ABI_SOLARIS)
7197 emit_call_insn (gen_call_indirect_sysv (force_reg (Pmode, operands[0]),
7198 operands[1], operands[2]));
7199 else
7200 {
7201 rtx toc_reg = gen_rtx (REG, Pmode, 2);
7202 rtx toc_addr = RS6000_SAVE_TOC;
7203
7204 if (DEFAULT_ABI == ABI_AIX)
7205 {
7206 /* AIX function pointers are really pointers to a three word area */
7207 rtx static_chain = gen_rtx (REG, Pmode, STATIC_CHAIN_REGNUM);
7208 emit_call_insn (gen_call_indirect_aix (force_reg (Pmode, operands[0]),
7209 operands[1], operands[2],
7210 toc_addr, toc_reg, static_chain));
7211 }
7212 else if (DEFAULT_ABI == ABI_NT)
7213 {
7214 /* NT function pointers are really pointers to a two word area */
7215 emit_call_insn (gen_call_indirect_nt (force_reg (Pmode, operands[0]),
7216 operands[1], operands[2],
7217 toc_addr, toc_reg));
7218 }
7219 else
7220 abort ();
7221 }
7222 DONE;
7223 }
7224 }")
7225
7226 (define_expand "call_value"
7227 [(parallel [(set (match_operand 0 "" "")
7228 (call (mem:SI (match_operand:SI 1 "address_operand" ""))
7229 (match_operand 2 "" "")))
7230 (use (match_operand 3 "" ""))
7231 (clobber (scratch:SI))])]
7232 ""
7233 "
7234 {
7235 if (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != CONST_INT)
7236 abort ();
7237
7238 operands[1] = XEXP (operands[1], 0);
7239
7240 /* Convert NT DLL imports into an indirect call. */
7241 if (GET_CODE (operands[1]) == SYMBOL_REF
7242 && (INTVAL (operands[3]) & CALL_NT_DLLIMPORT) != 0)
7243 {
7244 operands[1] = rs6000_dll_import_ref (operands[1]);
7245 operands[3] = GEN_INT ((int)CALL_NORMAL);
7246 }
7247
7248 if (GET_CODE (operands[1]) != SYMBOL_REF
7249 || (INTVAL (operands[3]) & CALL_LONG) != 0)
7250 {
7251 if (INTVAL (operands[2]) & CALL_LONG)
7252 operands[1] = rs6000_longcall_ref (operands[1]);
7253
7254 if (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_AIX_NODESC || DEFAULT_ABI == ABI_SOLARIS)
7255 emit_call_insn (gen_call_value_indirect_sysv (operands[0], operands[1],
7256 operands[2], operands[3]));
7257 else
7258 {
7259 rtx toc_reg = gen_rtx (REG, Pmode, 2);
7260 rtx toc_addr = RS6000_SAVE_TOC;
7261
7262 if (DEFAULT_ABI == ABI_AIX)
7263 {
7264 /* AIX function pointers are really pointers to a three word area */
7265 rtx static_chain = gen_rtx (REG, Pmode, STATIC_CHAIN_REGNUM);
7266 emit_call_insn (gen_call_value_indirect_aix (operands[0],
7267 force_reg (Pmode, operands[1]),
7268 operands[2], operands[3],
7269 toc_addr, toc_reg, static_chain));
7270 }
7271 else if (DEFAULT_ABI == ABI_NT)
7272 {
7273 /* NT function pointers are really pointers to a two word area */
7274 emit_call_insn (gen_call_value_indirect_nt (operands[0],
7275 force_reg (Pmode, operands[1]),
7276 operands[2], operands[3],
7277 toc_addr, toc_reg));
7278 }
7279 else
7280 abort ();
7281 }
7282 DONE;
7283 }
7284 }")
7285
7286 ;; Call to function in current module. No TOC pointer reload needed.
7287 ;; Operand2 is non-zero if we are using the V.4 calling sequence and
7288 ;; either the function was not prototyped, or it was prototyped as a
7289 ;; variable argument function. It is > 0 if FP registers were passed
7290 ;; and < 0 if they were not.
7291
7292 (define_insn ""
7293 [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
7294 (match_operand 1 "" "g,g"))
7295 (use (match_operand:SI 2 "immediate_operand" "O,n"))
7296 (clobber (match_scratch:SI 3 "=l,l"))]
7297 "(INTVAL (operands[2]) & CALL_LONG) == 0"
7298 "*
7299 {
7300 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
7301 output_asm_insn (\"crxor 6,6,6\", operands);
7302
7303 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
7304 output_asm_insn (\"creqv 6,6,6\", operands);
7305
7306 return \"bl %z0\";
7307 }"
7308 [(set_attr "type" "branch")
7309 (set_attr "length" "4,8")])
7310
7311 ;; Call to function which may be in another module. Restore the TOC
7312 ;; pointer (r2) after the call unless this is System V.
7313 ;; Operand2 is non-zero if we are using the V.4 calling sequence and
7314 ;; either the function was not prototyped, or it was prototyped as a
7315 ;; variable argument function. It is > 0 if FP registers were passed
7316 ;; and < 0 if they were not.
7317
7318 (define_insn ""
7319 [(call (mem:SI (match_operand:SI 0 "call_operand" "s,s"))
7320 (match_operand 1 "" "fg,fg"))
7321 (use (match_operand:SI 2 "immediate_operand" "O,n"))
7322 (clobber (match_scratch:SI 3 "=l,l"))]
7323 "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_NT)
7324 && (INTVAL (operands[2]) & CALL_LONG) == 0"
7325 "*
7326 {
7327 /* Indirect calls should go through call_indirect */
7328 if (GET_CODE (operands[0]) == REG)
7329 abort ();
7330
7331 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
7332 output_asm_insn (\"crxor 6,6,6\", operands);
7333
7334 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
7335 output_asm_insn (\"creqv 6,6,6\", operands);
7336
7337 return (TARGET_WINDOWS_NT) ? \"bl %z0\;.znop %z0\" : \"bl %z0\;%.\";
7338 }"
7339 [(set_attr "type" "branch")
7340 (set_attr "length" "8,12")])
7341
7342 (define_insn ""
7343 [(call (mem:SI (match_operand:SI 0 "call_operand" "s,s"))
7344 (match_operand 1 "" "fg,fg"))
7345 (use (match_operand:SI 2 "immediate_operand" "O,n"))
7346 (clobber (match_scratch:SI 3 "=l,l"))]
7347 "(DEFAULT_ABI == ABI_AIX_NODESC || DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS)
7348 && (INTVAL (operands[2]) & CALL_LONG) == 0"
7349 "*
7350 {
7351 /* Indirect calls should go through call_indirect */
7352 if (GET_CODE (operands[0]) == REG)
7353 abort ();
7354
7355 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
7356 output_asm_insn (\"crxor 6,6,6\", operands);
7357
7358 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
7359 output_asm_insn (\"creqv 6,6,6\", operands);
7360
7361 return \"bl %z0\";
7362 }"
7363 [(set_attr "type" "branch")
7364 (set_attr "length" "4,8")])
7365
7366 (define_insn ""
7367 [(set (match_operand 0 "" "=fg,fg")
7368 (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
7369 (match_operand 2 "" "g,g")))
7370 (use (match_operand:SI 3 "immediate_operand" "O,n"))
7371 (clobber (match_scratch:SI 4 "=l,l"))]
7372 "(INTVAL (operands[3]) & CALL_LONG) == 0"
7373 "*
7374 {
7375 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
7376 output_asm_insn (\"crxor 6,6,6\", operands);
7377
7378 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
7379 output_asm_insn (\"creqv 6,6,6\", operands);
7380
7381 return \"bl %z1\";
7382 }"
7383 [(set_attr "type" "branch")
7384 (set_attr "length" "4,8")])
7385
7386 (define_insn ""
7387 [(set (match_operand 0 "" "=fg,fg")
7388 (call (mem:SI (match_operand:SI 1 "call_operand" "s,s"))
7389 (match_operand 2 "" "fg,fg")))
7390 (use (match_operand:SI 3 "immediate_operand" "O,n"))
7391 (clobber (match_scratch:SI 4 "=l,l"))]
7392 "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_NT)
7393 && (INTVAL (operands[3]) & CALL_LONG) == 0"
7394 "*
7395 {
7396 /* This should be handled by call_value_indirect */
7397 if (GET_CODE (operands[1]) == REG)
7398 abort ();
7399
7400 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
7401 output_asm_insn (\"crxor 6,6,6\", operands);
7402
7403 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
7404 output_asm_insn (\"creqv 6,6,6\", operands);
7405
7406 return (TARGET_WINDOWS_NT) ? \"bl %z1\;.znop %z1\" : \"bl %z1\;%.\";
7407 }"
7408 [(set_attr "type" "branch")
7409 (set_attr "length" "8,12")])
7410
7411 (define_insn ""
7412 [(set (match_operand 0 "" "=fg,fg")
7413 (call (mem:SI (match_operand:SI 1 "call_operand" "s,s"))
7414 (match_operand 2 "" "fg,fg")))
7415 (use (match_operand:SI 3 "immediate_operand" "O,n"))
7416 (clobber (match_scratch:SI 4 "=l,l"))]
7417 "(DEFAULT_ABI == ABI_AIX_NODESC || DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS)
7418 && (INTVAL (operands[3]) & CALL_LONG) == 0"
7419 "*
7420 {
7421 /* This should be handled by call_value_indirect */
7422 if (GET_CODE (operands[1]) == REG)
7423 abort ();
7424
7425 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
7426 output_asm_insn (\"crxor 6,6,6\", operands);
7427
7428 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
7429 output_asm_insn (\"creqv 6,6,6\", operands);
7430
7431 return \"bl %z1\";
7432 }"
7433 [(set_attr "type" "branch")
7434 (set_attr "length" "4,8")])
7435
7436 ;; Call subroutine returning any type.
7437 (define_expand "untyped_call"
7438 [(parallel [(call (match_operand 0 "" "")
7439 (const_int 0))
7440 (match_operand 1 "" "")
7441 (match_operand 2 "" "")])]
7442 ""
7443 "
7444 {
7445 int i;
7446
7447 emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx, const0_rtx));
7448
7449 for (i = 0; i < XVECLEN (operands[2], 0); i++)
7450 {
7451 rtx set = XVECEXP (operands[2], 0, i);
7452 emit_move_insn (SET_DEST (set), SET_SRC (set));
7453 }
7454
7455 /* The optimizer does not know that the call sets the function value
7456 registers we stored in the result block. We avoid problems by
7457 claiming that all hard registers are used and clobbered at this
7458 point. */
7459 emit_insn (gen_blockage ());
7460
7461 DONE;
7462 }")
7463
7464 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
7465 ;; all of memory. This blocks insns from being moved across this point.
7466
7467 (define_insn "blockage"
7468 [(unspec_volatile [(const_int 0)] 0)]
7469 ""
7470 "")
7471
7472 ;; Synchronize instructions/data caches for V.4 trampolines
7473 ;; The extra memory_operand is to prevent the optimizer from
7474 ;; deleting insns with "no" effect.
7475 (define_insn "icbi"
7476 [(unspec [(match_operand 0 "memory_operand" "=m")
7477 (match_operand 1 "register_operand" "b")
7478 (match_operand 2 "register_operand" "r")] 3)]
7479 "TARGET_POWERPC"
7480 "icbi %1,%2")
7481
7482 (define_insn "dcbst"
7483 [(unspec [(match_operand 0 "memory_operand" "=m")
7484 (match_operand 1 "register_operand" "b")
7485 (match_operand 2 "register_operand" "r")] 4)]
7486 "TARGET_POWERPC"
7487 "dcbst %1,%2")
7488
7489 (define_insn "sync"
7490 [(unspec [(match_operand 0 "memory_operand" "=m")] 5)]
7491 ""
7492 "{dcs|sync}")
7493
7494 (define_insn "isync"
7495 [(unspec [(match_operand 0 "memory_operand" "=m")] 6)]
7496 ""
7497 "{ics|isync}")
7498
7499
7500 ;; V.4 specific code to initialize the PIC register
7501
7502 (define_insn "init_v4_pic"
7503 [(set (match_operand:SI 0 "register_operand" "=l")
7504 (unspec [(const_int 0)] 7))]
7505 "DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS"
7506 "bl _GLOBAL_OFFSET_TABLE_-4"
7507 [(set_attr "type" "branch")])
7508
7509 \f
7510 ;; Compare insns are next. Note that the RS/6000 has two types of compares,
7511 ;; signed & unsigned, and one type of branch.
7512 ;;
7513 ;; Start with the DEFINE_EXPANDs to generate the rtl for compares, scc
7514 ;; insns, and branches. We store the operands of compares until we see
7515 ;; how it is used.
7516 (define_expand "cmpsi"
7517 [(set (cc0)
7518 (compare (match_operand:SI 0 "gpc_reg_operand" "")
7519 (match_operand:SI 1 "reg_or_short_operand" "")))]
7520 ""
7521 "
7522 {
7523 /* Take care of the possibility that operands[1] might be negative but
7524 this might be a logical operation. That insn doesn't exist. */
7525 if (GET_CODE (operands[1]) == CONST_INT
7526 && INTVAL (operands[1]) < 0)
7527 operands[1] = force_reg (SImode, operands[1]);
7528
7529 rs6000_compare_op0 = operands[0];
7530 rs6000_compare_op1 = operands[1];
7531 rs6000_compare_fp_p = 0;
7532 DONE;
7533 }")
7534
7535 (define_expand "cmpdi"
7536 [(set (cc0)
7537 (compare (match_operand:DI 0 "gpc_reg_operand" "")
7538 (match_operand:DI 1 "reg_or_short_operand" "")))]
7539 "TARGET_POWERPC64"
7540 "
7541 {
7542 /* Take care of the possibility that operands[1] might be negative but
7543 this might be a logical operation. That insn doesn't exist. */
7544 if (GET_CODE (operands[1]) == CONST_INT
7545 && INTVAL (operands[1]) < 0)
7546 operands[1] = force_reg (DImode, operands[1]);
7547
7548 rs6000_compare_op0 = operands[0];
7549 rs6000_compare_op1 = operands[1];
7550 rs6000_compare_fp_p = 0;
7551 DONE;
7552 }")
7553
7554 (define_expand "cmpsf"
7555 [(set (cc0) (compare (match_operand:SF 0 "gpc_reg_operand" "")
7556 (match_operand:SF 1 "gpc_reg_operand" "")))]
7557 "TARGET_HARD_FLOAT"
7558 "
7559 {
7560 rs6000_compare_op0 = operands[0];
7561 rs6000_compare_op1 = operands[1];
7562 rs6000_compare_fp_p = 1;
7563 DONE;
7564 }")
7565
7566 (define_expand "cmpdf"
7567 [(set (cc0) (compare (match_operand:DF 0 "gpc_reg_operand" "")
7568 (match_operand:DF 1 "gpc_reg_operand" "")))]
7569 "TARGET_HARD_FLOAT"
7570 "
7571 {
7572 rs6000_compare_op0 = operands[0];
7573 rs6000_compare_op1 = operands[1];
7574 rs6000_compare_fp_p = 1;
7575 DONE;
7576 }")
7577
7578 (define_expand "beq"
7579 [(set (match_dup 2) (match_dup 1))
7580 (set (pc)
7581 (if_then_else (eq (match_dup 2)
7582 (const_int 0))
7583 (label_ref (match_operand 0 "" ""))
7584 (pc)))]
7585 ""
7586 "
7587 { enum machine_mode mode = rs6000_compare_fp_p ? CCFPmode : CCmode;
7588 operands[1] = gen_rtx (COMPARE, mode,
7589 rs6000_compare_op0, rs6000_compare_op1);
7590 operands[2] = gen_reg_rtx (mode);
7591 }")
7592
7593 (define_expand "bne"
7594 [(set (match_dup 2) (match_dup 1))
7595 (set (pc)
7596 (if_then_else (ne (match_dup 2)
7597 (const_int 0))
7598 (label_ref (match_operand 0 "" ""))
7599 (pc)))]
7600 ""
7601 "
7602 { enum machine_mode mode = rs6000_compare_fp_p ? CCFPmode : CCmode;
7603 operands[1] = gen_rtx (COMPARE, mode,
7604 rs6000_compare_op0, rs6000_compare_op1);
7605 operands[2] = gen_reg_rtx (mode);
7606 }")
7607
7608 (define_expand "blt"
7609 [(set (match_dup 2) (match_dup 1))
7610 (set (pc)
7611 (if_then_else (lt (match_dup 2)
7612 (const_int 0))
7613 (label_ref (match_operand 0 "" ""))
7614 (pc)))]
7615 ""
7616 "
7617 { enum machine_mode mode = rs6000_compare_fp_p ? CCFPmode : CCmode;
7618 operands[1] = gen_rtx (COMPARE, mode,
7619 rs6000_compare_op0, rs6000_compare_op1);
7620 operands[2] = gen_reg_rtx (mode);
7621 }")
7622
7623 (define_expand "bgt"
7624 [(set (match_dup 2) (match_dup 1))
7625 (set (pc)
7626 (if_then_else (gt (match_dup 2)
7627 (const_int 0))
7628 (label_ref (match_operand 0 "" ""))
7629 (pc)))]
7630 ""
7631 "
7632 { enum machine_mode mode = rs6000_compare_fp_p ? CCFPmode : CCmode;
7633 operands[1] = gen_rtx (COMPARE, mode,
7634 rs6000_compare_op0, rs6000_compare_op1);
7635 operands[2] = gen_reg_rtx (mode);
7636 }")
7637
7638 (define_expand "ble"
7639 [(set (match_dup 2) (match_dup 1))
7640 (set (pc)
7641 (if_then_else (le (match_dup 2)
7642 (const_int 0))
7643 (label_ref (match_operand 0 "" ""))
7644 (pc)))]
7645 ""
7646 "
7647 { enum machine_mode mode = rs6000_compare_fp_p ? CCFPmode : CCmode;
7648 operands[1] = gen_rtx (COMPARE, mode,
7649 rs6000_compare_op0, rs6000_compare_op1);
7650 operands[2] = gen_reg_rtx (mode);
7651 }")
7652
7653 (define_expand "bge"
7654 [(set (match_dup 2) (match_dup 1))
7655 (set (pc)
7656 (if_then_else (ge (match_dup 2)
7657 (const_int 0))
7658 (label_ref (match_operand 0 "" ""))
7659 (pc)))]
7660 ""
7661 "
7662 { enum machine_mode mode = rs6000_compare_fp_p ? CCFPmode : CCmode;
7663 operands[1] = gen_rtx (COMPARE, mode,
7664 rs6000_compare_op0, rs6000_compare_op1);
7665 operands[2] = gen_reg_rtx (mode);
7666 }")
7667
7668 (define_expand "bgtu"
7669 [(set (match_dup 2) (match_dup 1))
7670 (set (pc)
7671 (if_then_else (gtu (match_dup 2)
7672 (const_int 0))
7673 (label_ref (match_operand 0 "" ""))
7674 (pc)))]
7675 ""
7676 "
7677 { operands[1] = gen_rtx (COMPARE, CCUNSmode,
7678 rs6000_compare_op0, rs6000_compare_op1);
7679 operands[2] = gen_reg_rtx (CCUNSmode);
7680 }")
7681
7682 (define_expand "bltu"
7683 [(set (match_dup 2) (match_dup 1))
7684 (set (pc)
7685 (if_then_else (ltu (match_dup 2)
7686 (const_int 0))
7687 (label_ref (match_operand 0 "" ""))
7688 (pc)))]
7689 ""
7690 "
7691 { operands[1] = gen_rtx (COMPARE, CCUNSmode,
7692 rs6000_compare_op0, rs6000_compare_op1);
7693 operands[2] = gen_reg_rtx (CCUNSmode);
7694 }")
7695
7696 (define_expand "bgeu"
7697 [(set (match_dup 2) (match_dup 1))
7698 (set (pc)
7699 (if_then_else (geu (match_dup 2)
7700 (const_int 0))
7701 (label_ref (match_operand 0 "" ""))
7702 (pc)))]
7703 ""
7704 "
7705 { operands[1] = gen_rtx (COMPARE, CCUNSmode,
7706 rs6000_compare_op0, rs6000_compare_op1);
7707 operands[2] = gen_reg_rtx (CCUNSmode);
7708 }")
7709
7710 (define_expand "bleu"
7711 [(set (match_dup 2) (match_dup 1))
7712 (set (pc)
7713 (if_then_else (leu (match_dup 2)
7714 (const_int 0))
7715 (label_ref (match_operand 0 "" ""))
7716 (pc)))]
7717 ""
7718 "
7719 { operands[1] = gen_rtx (COMPARE, CCUNSmode,
7720 rs6000_compare_op0, rs6000_compare_op1);
7721 operands[2] = gen_reg_rtx (CCUNSmode);
7722 }")
7723
7724 ;; For SNE, we would prefer that the xor/abs sequence be used for integers.
7725 ;; For SEQ, likewise, except that comparisons with zero should be done
7726 ;; with an scc insns. However, due to the order that combine see the
7727 ;; resulting insns, we must, in fact, allow SEQ for integers. Fail in
7728 ;; the cases we don't want to handle.
7729 (define_expand "seq"
7730 [(set (match_dup 2) (match_dup 1))
7731 (set (match_operand:SI 0 "gpc_reg_operand" "")
7732 (eq:SI (match_dup 2) (const_int 0)))]
7733 ""
7734 "
7735 { enum machine_mode mode = rs6000_compare_fp_p ? CCFPmode : CCmode;
7736 operands[1] = gen_rtx (COMPARE, mode,
7737 rs6000_compare_op0, rs6000_compare_op1);
7738 operands[2] = gen_reg_rtx (mode);
7739 }")
7740
7741 (define_expand "sne"
7742 [(set (match_dup 2) (match_dup 1))
7743 (set (match_operand:SI 0 "gpc_reg_operand" "")
7744 (ne:SI (match_dup 2) (const_int 0)))]
7745 ""
7746 "
7747 { if (! rs6000_compare_fp_p)
7748 FAIL;
7749
7750 operands[1] = gen_rtx (COMPARE, CCFPmode,
7751 rs6000_compare_op0, rs6000_compare_op1);
7752 operands[2] = gen_reg_rtx (CCFPmode);
7753 }")
7754
7755 ;; A > 0 is best done using the portable sequence, so fail in that case.
7756 (define_expand "sgt"
7757 [(set (match_dup 2) (match_dup 1))
7758 (set (match_operand:SI 0 "gpc_reg_operand" "")
7759 (gt:SI (match_dup 2) (const_int 0)))]
7760 ""
7761 "
7762 { enum machine_mode mode = rs6000_compare_fp_p ? CCFPmode : CCmode;
7763
7764 if (! rs6000_compare_fp_p && rs6000_compare_op1 == const0_rtx)
7765 FAIL;
7766
7767 operands[1] = gen_rtx (COMPARE, mode,
7768 rs6000_compare_op0, rs6000_compare_op1);
7769 operands[2] = gen_reg_rtx (mode);
7770 }")
7771
7772 ;; A < 0 is best done in the portable way for A an integer.
7773 (define_expand "slt"
7774 [(set (match_dup 2) (match_dup 1))
7775 (set (match_operand:SI 0 "gpc_reg_operand" "")
7776 (lt:SI (match_dup 2) (const_int 0)))]
7777 ""
7778 "
7779 { enum machine_mode mode = rs6000_compare_fp_p ? CCFPmode : CCmode;
7780
7781 if (! rs6000_compare_fp_p && rs6000_compare_op1 == const0_rtx)
7782 FAIL;
7783
7784 operands[1] = gen_rtx (COMPARE, mode,
7785 rs6000_compare_op0, rs6000_compare_op1);
7786 operands[2] = gen_reg_rtx (mode);
7787 }")
7788
7789 (define_expand "sge"
7790 [(set (match_dup 2) (match_dup 1))
7791 (set (match_operand:SI 0 "gpc_reg_operand" "")
7792 (ge:SI (match_dup 2) (const_int 0)))]
7793 ""
7794 "
7795 { enum machine_mode mode = rs6000_compare_fp_p ? CCFPmode : CCmode;
7796 operands[1] = gen_rtx (COMPARE, mode,
7797 rs6000_compare_op0, rs6000_compare_op1);
7798 operands[2] = gen_reg_rtx (mode);
7799 }")
7800
7801 ;; A <= 0 is best done the portable way for A an integer.
7802 (define_expand "sle"
7803 [(set (match_dup 2) (match_dup 1))
7804 (set (match_operand:SI 0 "gpc_reg_operand" "")
7805 (le:SI (match_dup 2) (const_int 0)))]
7806 ""
7807 "
7808 { enum machine_mode mode = rs6000_compare_fp_p ? CCFPmode : CCmode;
7809
7810 if (! rs6000_compare_fp_p && rs6000_compare_op1 == const0_rtx)
7811 FAIL;
7812
7813 operands[1] = gen_rtx (COMPARE, mode,
7814 rs6000_compare_op0, rs6000_compare_op1);
7815 operands[2] = gen_reg_rtx (mode);
7816 }")
7817
7818 (define_expand "sgtu"
7819 [(set (match_dup 2) (match_dup 1))
7820 (set (match_operand:SI 0 "gpc_reg_operand" "")
7821 (gtu:SI (match_dup 2) (const_int 0)))]
7822 ""
7823 "
7824 { operands[1] = gen_rtx (COMPARE, CCUNSmode,
7825 rs6000_compare_op0, rs6000_compare_op1);
7826 operands[2] = gen_reg_rtx (CCUNSmode);
7827 }")
7828
7829 (define_expand "sltu"
7830 [(set (match_dup 2) (match_dup 1))
7831 (set (match_operand:SI 0 "gpc_reg_operand" "")
7832 (ltu:SI (match_dup 2) (const_int 0)))]
7833 ""
7834 "
7835 { operands[1] = gen_rtx (COMPARE, CCUNSmode,
7836 rs6000_compare_op0, rs6000_compare_op1);
7837 operands[2] = gen_reg_rtx (CCUNSmode);
7838 }")
7839
7840 (define_expand "sgeu"
7841 [(set (match_dup 2) (match_dup 1))
7842 (set (match_operand:SI 0 "gpc_reg_operand" "")
7843 (geu:SI (match_dup 2) (const_int 0)))]
7844 ""
7845 "
7846 { operands[1] = gen_rtx (COMPARE, CCUNSmode,
7847 rs6000_compare_op0, rs6000_compare_op1);
7848 operands[2] = gen_reg_rtx (CCUNSmode);
7849 }")
7850
7851 (define_expand "sleu"
7852 [(set (match_dup 2) (match_dup 1))
7853 (set (match_operand:SI 0 "gpc_reg_operand" "")
7854 (leu:SI (match_dup 2) (const_int 0)))]
7855 ""
7856 "
7857 { operands[1] = gen_rtx (COMPARE, CCUNSmode,
7858 rs6000_compare_op0, rs6000_compare_op1);
7859 operands[2] = gen_reg_rtx (CCUNSmode);
7860 }")
7861 \f
7862 ;; Here are the actual compare insns.
7863 (define_insn ""
7864 [(set (match_operand:CC 0 "cc_reg_operand" "=y")
7865 (compare:CC (match_operand:SI 1 "gpc_reg_operand" "r")
7866 (match_operand:SI 2 "reg_or_short_operand" "rI")))]
7867 ""
7868 "{cmp%I2|cmpw%I2} %0,%1,%2"
7869 [(set_attr "type" "compare")])
7870
7871 (define_insn ""
7872 [(set (match_operand:CC 0 "cc_reg_operand" "=y")
7873 (compare:CC (match_operand:DI 1 "gpc_reg_operand" "r")
7874 (match_operand:DI 2 "reg_or_short_operand" "rI")))]
7875 "TARGET_POWERPC64"
7876 "cmpd%I2 %0,%1,%2"
7877 [(set_attr "type" "compare")])
7878
7879 ;; If we are comparing a register for equality with a large constant,
7880 ;; we can do this with an XOR followed by a compare. But we need a scratch
7881 ;; register for the result of the XOR.
7882
7883 (define_split
7884 [(set (match_operand:CC 0 "cc_reg_operand" "")
7885 (compare:CC (match_operand:SI 1 "gpc_reg_operand" "")
7886 (match_operand:SI 2 "non_short_cint_operand" "")))
7887 (clobber (match_operand:SI 3 "gpc_reg_operand" ""))]
7888 "find_single_use (operands[0], insn, 0)
7889 && (GET_CODE (*find_single_use (operands[0], insn, 0)) == EQ
7890 || GET_CODE (*find_single_use (operands[0], insn, 0)) == NE)"
7891 [(set (match_dup 3) (xor:SI (match_dup 1) (match_dup 4)))
7892 (set (match_dup 0) (compare:CC (match_dup 3) (match_dup 5)))]
7893 "
7894 {
7895 /* Get the constant we are comparing against, C, and see what it looks like
7896 sign-extended to 16 bits. Then see what constant could be XOR'ed
7897 with C to get the sign-extended value. */
7898
7899 int c = INTVAL (operands[2]);
7900 int sextc = (c << 16) >> 16;
7901 int xorv = c ^ sextc;
7902
7903 operands[4] = gen_rtx (CONST_INT, VOIDmode, xorv);
7904 operands[5] = gen_rtx (CONST_INT, VOIDmode, sextc);
7905 }")
7906
7907 (define_insn ""
7908 [(set (match_operand:CCUNS 0 "cc_reg_operand" "=y")
7909 (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "r")
7910 (match_operand:SI 2 "reg_or_u_short_operand" "rI")))]
7911 ""
7912 "{cmpl%I2|cmplw%I2} %0,%1,%W2"
7913 [(set_attr "type" "compare")])
7914
7915 (define_insn ""
7916 [(set (match_operand:CCUNS 0 "cc_reg_operand" "=y")
7917 (compare:CCUNS (match_operand:DI 1 "gpc_reg_operand" "r")
7918 (match_operand:DI 2 "reg_or_u_short_operand" "rI")))]
7919 ""
7920 "cmpld%I2 %0,%1,%W2"
7921 [(set_attr "type" "compare")])
7922
7923 ;; The following two insns don't exist as single insns, but if we provide
7924 ;; them, we can swap an add and compare, which will enable us to overlap more
7925 ;; of the required delay between a compare and branch. We generate code for
7926 ;; them by splitting.
7927
7928 (define_insn ""
7929 [(set (match_operand:CC 3 "cc_reg_operand" "=y")
7930 (compare:CC (match_operand:SI 1 "gpc_reg_operand" "r")
7931 (match_operand:SI 2 "short_cint_operand" "i")))
7932 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
7933 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "i")))]
7934 ""
7935 "#"
7936 [(set_attr "length" "8")])
7937
7938 (define_insn ""
7939 [(set (match_operand:CCUNS 3 "cc_reg_operand" "=y")
7940 (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "r")
7941 (match_operand:SI 2 "u_short_cint_operand" "i")))
7942 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
7943 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "i")))]
7944 ""
7945 "#"
7946 [(set_attr "length" "8")])
7947
7948 (define_split
7949 [(set (match_operand:CC 3 "cc_reg_operand" "")
7950 (compare:CC (match_operand:SI 1 "gpc_reg_operand" "")
7951 (match_operand:SI 2 "short_cint_operand" "")))
7952 (set (match_operand:SI 0 "gpc_reg_operand" "")
7953 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "")))]
7954 ""
7955 [(set (match_dup 3) (compare:CC (match_dup 1) (match_dup 2)))
7956 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 4)))])
7957
7958 (define_split
7959 [(set (match_operand:CCUNS 3 "cc_reg_operand" "")
7960 (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "")
7961 (match_operand:SI 2 "u_short_cint_operand" "")))
7962 (set (match_operand:SI 0 "gpc_reg_operand" "")
7963 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "")))]
7964 ""
7965 [(set (match_dup 3) (compare:CCUNS (match_dup 1) (match_dup 2)))
7966 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 4)))])
7967
7968 (define_insn ""
7969 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
7970 (compare:CCFP (match_operand:SF 1 "gpc_reg_operand" "f")
7971 (match_operand:SF 2 "gpc_reg_operand" "f")))]
7972 "TARGET_HARD_FLOAT"
7973 "fcmpu %0,%1,%2"
7974 [(set_attr "type" "fpcompare")])
7975
7976 (define_insn ""
7977 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
7978 (compare:CCFP (match_operand:DF 1 "gpc_reg_operand" "f")
7979 (match_operand:DF 2 "gpc_reg_operand" "f")))]
7980 "TARGET_HARD_FLOAT"
7981 "fcmpu %0,%1,%2"
7982 [(set_attr "type" "fpcompare")])
7983 \f
7984 ;; Now we have the scc insns. We can do some combinations because of the
7985 ;; way the machine works.
7986 ;;
7987 ;; Note that this is probably faster if we can put an insn between the
7988 ;; mfcr and rlinm, but this is tricky. Let's leave it for now. In most
7989 ;; cases the insns below which don't use an intermediate CR field will
7990 ;; be used instead.
7991 (define_insn ""
7992 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
7993 (match_operator:SI 1 "scc_comparison_operator"
7994 [(match_operand 2 "cc_reg_operand" "y")
7995 (const_int 0)]))]
7996 ""
7997 "%D1mfcr %0\;{rlinm|rlwinm} %0,%0,%J1,1"
7998 [(set_attr "length" "12")])
7999
8000 (define_insn ""
8001 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
8002 (compare:CC (match_operator:SI 1 "scc_comparison_operator"
8003 [(match_operand 2 "cc_reg_operand" "y")
8004 (const_int 0)])
8005 (const_int 0)))
8006 (set (match_operand:SI 3 "gpc_reg_operand" "=r")
8007 (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8008 ""
8009 "%D1mfcr %3\;{rlinm.|rlwinm.} %3,%3,%J1,1"
8010 [(set_attr "type" "delayed_compare")
8011 (set_attr "length" "12")])
8012
8013 (define_insn ""
8014 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
8015 (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
8016 [(match_operand 2 "cc_reg_operand" "y")
8017 (const_int 0)])
8018 (match_operand:SI 3 "const_int_operand" "n")))]
8019 ""
8020 "*
8021 {
8022 int is_bit = ccr_bit (operands[1], 1);
8023 int put_bit = 31 - (INTVAL (operands[3]) & 31);
8024 int count;
8025
8026 if (is_bit >= put_bit)
8027 count = is_bit - put_bit;
8028 else
8029 count = 32 - (put_bit - is_bit);
8030
8031 operands[4] = gen_rtx (CONST_INT, VOIDmode, count);
8032 operands[5] = gen_rtx (CONST_INT, VOIDmode, put_bit);
8033
8034 return \"%D1mfcr %0\;{rlinm|rlwinm} %0,%0,%4,%5,%5\";
8035 }"
8036 [(set_attr "length" "12")])
8037
8038 (define_insn ""
8039 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
8040 (compare:CC
8041 (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
8042 [(match_operand 2 "cc_reg_operand" "y")
8043 (const_int 0)])
8044 (match_operand:SI 3 "const_int_operand" "n"))
8045 (const_int 0)))
8046 (set (match_operand:SI 4 "gpc_reg_operand" "=r")
8047 (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
8048 (match_dup 3)))]
8049 ""
8050 "*
8051 {
8052 int is_bit = ccr_bit (operands[1], 1);
8053 int put_bit = 31 - (INTVAL (operands[3]) & 31);
8054 int count;
8055
8056 if (is_bit >= put_bit)
8057 count = is_bit - put_bit;
8058 else
8059 count = 32 - (put_bit - is_bit);
8060
8061 operands[5] = gen_rtx (CONST_INT, VOIDmode, count);
8062 operands[6] = gen_rtx (CONST_INT, VOIDmode, put_bit);
8063
8064 return \"%D1mfcr %4\;{rlinm.|rlwinm.} %4,%4,%5,%6,%6\";
8065 }"
8066 [(set_attr "type" "delayed_compare")
8067 (set_attr "length" "12")])
8068
8069 ;; If we are comparing the result of two comparisons, this can be done
8070 ;; using creqv or crxor.
8071
8072 (define_insn ""
8073 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y")
8074 (compare:CCEQ (match_operator 1 "scc_comparison_operator"
8075 [(match_operand 2 "cc_reg_operand" "y")
8076 (const_int 0)])
8077 (match_operator 3 "scc_comparison_operator"
8078 [(match_operand 4 "cc_reg_operand" "y")
8079 (const_int 0)])))]
8080 "REGNO (operands[2]) != REGNO (operands[4])"
8081 "*
8082 {
8083 enum rtx_code code1, code2;
8084
8085 code1 = GET_CODE (operands[1]);
8086 code2 = GET_CODE (operands[3]);
8087
8088 if ((code1 == EQ || code1 == LT || code1 == GT
8089 || code1 == LTU || code1 == GTU
8090 || (code1 != NE && GET_MODE (operands[2]) == CCFPmode))
8091 !=
8092 (code2 == EQ || code2 == LT || code2 == GT
8093 || code2 == LTU || code2 == GTU
8094 || (code2 != NE && GET_MODE (operands[4]) == CCFPmode)))
8095 return \"%C1%C3crxor %E0,%j1,%j3\";
8096 else
8097 return \"%C1%C3creqv %E0,%j1,%j3\";
8098 }"
8099 [(set_attr "length" "12")])
8100
8101 ;; There is a 3 cycle delay between consecutive mfcr instructions
8102 ;; so it is useful to combine 2 scc instructions to use only one mfcr.
8103
8104 (define_peephole
8105 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
8106 (match_operator:SI 1 "scc_comparison_operator"
8107 [(match_operand 2 "cc_reg_operand" "y")
8108 (const_int 0)]))
8109 (set (match_operand:SI 3 "gpc_reg_operand" "=r")
8110 (match_operator:SI 4 "scc_comparison_operator"
8111 [(match_operand 5 "cc_reg_operand" "y")
8112 (const_int 0)]))]
8113 "REGNO (operands[2]) != REGNO (operands[5])"
8114 "%D1%D4mfcr %3\;{rlinm|rlwinm} %0,%3,%J1,1\;{rlinm|rlwinm} %3,%3,%J4,1"
8115 [(set_attr "length" "20")])
8116
8117 ;; There are some scc insns that can be done directly, without a compare.
8118 ;; These are faster because they don't involve the communications between
8119 ;; the FXU and branch units. In fact, we will be replacing all of the
8120 ;; integer scc insns here or in the portable methods in emit_store_flag.
8121 ;;
8122 ;; Also support (neg (scc ..)) since that construct is used to replace
8123 ;; branches, (plus (scc ..) ..) since that construct is common and
8124 ;; takes no more insns than scc, and (and (neg (scc ..)) ..) in the
8125 ;; cases where it is no more expensive than (neg (scc ..)).
8126
8127 ;; Have reload force a constant into a register for the simple insns that
8128 ;; otherwise won't accept constants. We do this because it is faster than
8129 ;; the cmp/mfcr sequence we would otherwise generate.
8130
8131 (define_insn ""
8132 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r,r")
8133 (eq:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r")
8134 (match_operand:SI 2 "reg_or_cint_operand" "r,O,K,J,I")))
8135 (clobber (match_scratch:SI 3 "=r,&r,r,r,r"))]
8136 ""
8137 "@
8138 xor %0,%1,%2\;{sfi|subfic} %3,%0,0\;{ae|adde} %0,%3,%0
8139 {sfi|subfic} %3,%1,0\;{ae|adde} %0,%3,%1
8140 {xoril|xori} %0,%1,%b2\;{sfi|subfic} %3,%0,0\;{ae|adde} %0,%3,%0
8141 {xoriu|xoris} %0,%1,%u2\;{sfi|subfic} %3,%0,0\;{ae|adde} %0,%3,%0
8142 {sfi|subfic} %0,%1,%2\;{sfi|subfic} %3,%0,0\;{ae|adde} %0,%3,%0"
8143 [(set_attr "length" "12,8,12,12,12")])
8144
8145 (define_insn ""
8146 [(set (match_operand:CC 4 "cc_reg_operand" "=x,x,x,x,x")
8147 (compare:CC
8148 (eq:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r")
8149 (match_operand:SI 2 "reg_or_cint_operand" "r,O,K,J,I"))
8150 (const_int 0)))
8151 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r,r")
8152 (eq:SI (match_dup 1) (match_dup 2)))
8153 (clobber (match_scratch:SI 3 "=r,&r,r,r,r"))]
8154 ""
8155 "@
8156 xor %0,%1,%2\;{sfi|subfic} %3,%0,0\;{ae.|adde.} %0,%3,%0
8157 {sfi|subfic} %3,%1,0\;{ae.|adde.} %0,%3,%1
8158 {xoril|xori} %0,%1,%b2\;{sfi|subfic} %3,%0,0\;{ae.|adde.} %0,%3,%0
8159 {xoriu|xoris} %0,%1,%u2\;{sfi|subfic} %3,%0,0\;{ae.|adde.} %0,%3,%0
8160 {sfi|subfic} %0,%1,%2\;{sfi|subfic} %3,%0,0\;{ae.|adde.} %0,%3,%0"
8161 [(set_attr "type" "compare")
8162 (set_attr "length" "12,8,12,12,12")])
8163
8164 ;; We have insns of the form shown by the first define_insn below. If
8165 ;; there is something inside the comparison operation, we must split it.
8166 (define_split
8167 [(set (match_operand:SI 0 "gpc_reg_operand" "")
8168 (plus:SI (match_operator 1 "comparison_operator"
8169 [(match_operand:SI 2 "" "")
8170 (match_operand:SI 3
8171 "reg_or_cint_operand" "")])
8172 (match_operand:SI 4 "gpc_reg_operand" "")))
8173 (clobber (match_operand:SI 5 "register_operand" ""))]
8174 "! gpc_reg_operand (operands[2], SImode)"
8175 [(set (match_dup 5) (match_dup 2))
8176 (set (match_dup 2) (plus:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
8177 (match_dup 4)))])
8178
8179 (define_insn ""
8180 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r,r")
8181 (plus:SI (eq:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r")
8182 (match_operand:SI 2 "reg_or_cint_operand" "r,O,K,J,I"))
8183 (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r,r")))
8184 (clobber (match_scratch:SI 4 "=&r,&r,&r,&r,&r"))]
8185 ""
8186 "@
8187 xor %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze|addze} %0,%3
8188 {sfi|subfic} %4,%1,0\;{aze|addze} %0,%3
8189 {xoril|xori} %4,%1,%b2\;{sfi|subfic} %4,%4,0\;{aze|addze} %0,%3
8190 {xoriu|xoris} %4,%1,%u2\;{sfi|subfic} %4,%4,0\;{aze|addze} %0,%3
8191 {sfi|subfic} %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze|addze} %0,%3"
8192 [(set_attr "length" "12,8,12,12,12")])
8193
8194 (define_insn ""
8195 [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,x,x,x")
8196 (compare:CC
8197 (plus:SI
8198 (eq:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r")
8199 (match_operand:SI 2 "reg_or_cint_operand" "r,O,K,J,I"))
8200 (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r,r"))
8201 (const_int 0)))
8202 (clobber (match_scratch:SI 4 "=&r,&r,&r,&r,&r"))]
8203 ""
8204 "@
8205 xor %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %4,%3
8206 {sfi|subfic} %4,%1,0\;{aze.|addze.} %0,%3
8207 {xoril|xori} %4,%1,%b2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %4,%3
8208 {xoriu|xoris} %4,%1,%u2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %4,%3
8209 {sfi|subfic} %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %4,%3"
8210 [(set_attr "type" "compare")
8211 (set_attr "length" "12,8,12,12,12")])
8212
8213 (define_insn ""
8214 [(set (match_operand:CC 5 "cc_reg_operand" "=x,x,x,x,x")
8215 (compare:CC
8216 (plus:SI
8217 (eq:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r")
8218 (match_operand:SI 2 "reg_or_cint_operand" "r,O,K,J,I"))
8219 (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r,r"))
8220 (const_int 0)))
8221 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r,r")
8222 (plus:SI (eq:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
8223 (clobber (match_scratch:SI 4 "=&r,&r,&r,&r,&r"))]
8224 ""
8225 "@
8226 xor %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %0,%3
8227 {sfi|subfic} %4,%1,0\;{aze.|addze.} %4,%3
8228 {xoril|xori} %4,%1,%b2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %0,%3
8229 {xoriu|xoris} %4,%1,%u2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %0,%3
8230 {sfi|subfic} %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %0,%3"
8231 [(set_attr "type" "compare")
8232 (set_attr "length" "12,8,12,12,12")])
8233
8234 (define_insn ""
8235 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r,r")
8236 (neg:SI (eq:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r")
8237 (match_operand:SI 2 "reg_or_cint_operand" "r,O,K,J,I"))))]
8238 ""
8239 "@
8240 xor %0,%1,%2\;{ai|addic} %0,%0,-1\;{sfe|subfe} %0,%0,%0
8241 {ai|addic} %0,%1,-1\;{sfe|subfe} %0,%0,%0
8242 {xoril|xori} %0,%1,%b2\;{ai|addic} %0,%0,-1\;{sfe|subfe} %0,%0,%0
8243 {xoriu|xoris} %0,%1,%u2\;{ai|addic} %0,%0,-1\;{sfe|subfe} %0,%0,%0
8244 {sfi|subfic} %0,%1,%2\;{ai|addic} %0,%0,-1\;{sfe|subfe} %0,%0,%0"
8245 [(set_attr "length" "12,8,12,12,12")])
8246
8247 ;; Simplify (ne X (const_int 0)) on the PowerPC. No need to on the Power,
8248 ;; since it nabs/sr is just as fast.
8249 (define_insn ""
8250 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
8251 (lshiftrt:SI (neg:SI (abs:SI (match_operand:SI 1 "gpc_reg_operand" "r")))
8252 (const_int 31)))
8253 (clobber (match_scratch:SI 2 "=&r"))]
8254 "!TARGET_POWER"
8255 "{ai|addic} %2,%1,-1\;{sfe|subfe} %0,%2,%1"
8256 [(set_attr "length" "8")])
8257
8258 ;; This is what (plus (ne X (const_int 0)) Y) looks like.
8259 (define_insn ""
8260 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
8261 (plus:SI (lshiftrt:SI
8262 (neg:SI (abs:SI (match_operand:SI 1 "gpc_reg_operand" "r")))
8263 (const_int 31))
8264 (match_operand:SI 2 "gpc_reg_operand" "r")))
8265 (clobber (match_scratch:SI 3 "=&r"))]
8266 ""
8267 "{ai|addic} %3,%1,-1\;{aze|addze} %0,%2"
8268 [(set_attr "length" "8")])
8269
8270 (define_insn ""
8271 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
8272 (compare:CC
8273 (plus:SI (lshiftrt:SI
8274 (neg:SI (abs:SI (match_operand:SI 1 "gpc_reg_operand" "r")))
8275 (const_int 31))
8276 (match_operand:SI 2 "gpc_reg_operand" "r"))
8277 (const_int 0)))
8278 (clobber (match_scratch:SI 3 "=&r"))]
8279 ""
8280 "{ai|addic} %3,%1,-1\;{aze.|addze.} %3,%2"
8281 [(set_attr "type" "compare")
8282 (set_attr "length" "8")])
8283
8284 (define_insn ""
8285 [(set (match_operand:CC 4 "cc_reg_operand" "=x")
8286 (compare:CC
8287 (plus:SI (lshiftrt:SI
8288 (neg:SI (abs:SI (match_operand:SI 1 "gpc_reg_operand" "r")))
8289 (const_int 31))
8290 (match_operand:SI 2 "gpc_reg_operand" "r"))
8291 (const_int 0)))
8292 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
8293 (plus:SI (lshiftrt:SI (neg:SI (abs:SI (match_dup 1))) (const_int 31))
8294 (match_dup 2)))
8295 (clobber (match_scratch:SI 3 "=&r"))]
8296 ""
8297 "{ai|addic} %3,%1,-1\;{aze.|addze.} %0,%2"
8298 [(set_attr "type" "compare")
8299 (set_attr "length" "8")])
8300
8301 (define_insn ""
8302 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
8303 (le:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
8304 (match_operand:SI 2 "reg_or_short_operand" "r,O")))
8305 (clobber (match_scratch:SI 3 "=r,X"))]
8306 "TARGET_POWER"
8307 "@
8308 doz %3,%2,%1\;{sfi|subfic} %0,%3,0\;{ae|adde} %0,%0,%3
8309 {ai|addic} %0,%1,-1\;{aze|addze} %0,%0\;{sri|srwi} %0,%0,31"
8310 [(set_attr "length" "12")])
8311
8312 (define_insn ""
8313 [(set (match_operand:CC 4 "cc_reg_operand" "=x,x")
8314 (compare:CC
8315 (le:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
8316 (match_operand:SI 2 "reg_or_short_operand" "r,O"))
8317 (const_int 0)))
8318 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
8319 (le:SI (match_dup 1) (match_dup 2)))
8320 (clobber (match_scratch:SI 3 "=r,X"))]
8321 "TARGET_POWER"
8322 "@
8323 doz %3,%2,%1\;{sfi|subfic} %0,%3,0\;{ae.|adde.} %0,%0,%3
8324 {ai|addic} %0,%1,-1\;{aze|addze} %0,%0\;{sri.|srwi.} %0,%0,31"
8325 [(set_attr "type" "compare,delayed_compare")
8326 (set_attr "length" "12")])
8327
8328 (define_insn ""
8329 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
8330 (plus:SI (le:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
8331 (match_operand:SI 2 "reg_or_short_operand" "r,O"))
8332 (match_operand:SI 3 "gpc_reg_operand" "r,r")))
8333 (clobber (match_scratch:SI 4 "=&r,&r"))]
8334 "TARGET_POWER"
8335 "@
8336 doz %4,%2,%1\;{sfi|subfic} %4,%4,0\;{aze|addze} %0,%3
8337 {srai|srawi} %4,%1,31\;{sf|subfc} %4,%1,%4\;{aze|addze} %0,%3"
8338 [(set_attr "length" "12")])
8339
8340 (define_insn ""
8341 [(set (match_operand:CC 0 "cc_reg_operand" "=x,x")
8342 (compare:CC
8343 (plus:SI (le:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
8344 (match_operand:SI 2 "reg_or_short_operand" "r,O"))
8345 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
8346 (const_int 0)))
8347 (clobber (match_scratch:SI 4 "=&r,&r"))]
8348 "TARGET_POWER"
8349 "@
8350 doz %4,%2,%1\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %4,%3
8351 {srai|srawi} %4,%1,31\;{sf|subfc} %4,%1,%4\;{aze.|addze.} %4,%3"
8352 [(set_attr "type" "compare")
8353 (set_attr "length" "12")])
8354
8355 (define_insn ""
8356 [(set (match_operand:CC 5 "cc_reg_operand" "=x,x")
8357 (compare:CC
8358 (plus:SI (le:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
8359 (match_operand:SI 2 "reg_or_short_operand" "r,O"))
8360 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
8361 (const_int 0)))
8362 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
8363 (plus:SI (le:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
8364 (clobber (match_scratch:SI 4 "=&r,&r"))]
8365 "TARGET_POWER"
8366 "@
8367 doz %4,%2,%1\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %0,%3
8368 {srai|srawi} %4,%1,31\;{sf|subfc} %4,%1,%4\;{aze.|addze.} %0,%3"
8369 [(set_attr "type" "compare")
8370 (set_attr "length" "12")])
8371
8372 (define_insn ""
8373 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
8374 (neg:SI (le:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
8375 (match_operand:SI 2 "reg_or_short_operand" "r,O"))))]
8376 "TARGET_POWER"
8377 "@
8378 doz %0,%2,%1\;{ai|addic} %0,%0,-1\;{sfe|subfe} %0,%0,%0
8379 {ai|addic} %0,%1,-1\;{aze|addze} %0,%0\;{srai|srawi} %0,%0,31"
8380 [(set_attr "length" "12")])
8381
8382 (define_insn ""
8383 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
8384 (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
8385 (match_operand:SI 2 "reg_or_short_operand" "rI")))]
8386 ""
8387 "{sf%I2|subf%I2c} %0,%1,%2\;{cal %0,0(0)|li %0,0}\;{ae|adde} %0,%0,%0"
8388 [(set_attr "length" "12")])
8389
8390 (define_insn ""
8391 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
8392 (compare:CC
8393 (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
8394 (match_operand:SI 2 "reg_or_short_operand" "rI"))
8395 (const_int 0)))
8396 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
8397 (leu:SI (match_dup 1) (match_dup 2)))]
8398 ""
8399 "{sf%I2|subf%I2c} %0,%1,%2\;{cal %0,0(0)|li %0,0}\;{ae.|adde.} %0,%0,%0"
8400 [(set_attr "type" "compare")
8401 (set_attr "length" "12")])
8402
8403 (define_insn ""
8404 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
8405 (plus:SI (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
8406 (match_operand:SI 2 "reg_or_short_operand" "rI"))
8407 (match_operand:SI 3 "gpc_reg_operand" "r")))
8408 (clobber (match_scratch:SI 4 "=&r"))]
8409 ""
8410 "{sf%I2|subf%I2c} %4,%1,%2\;{aze|addze} %0,%3"
8411 [(set_attr "length" "8")])
8412
8413 (define_insn ""
8414 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
8415 (compare:CC
8416 (plus:SI (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
8417 (match_operand:SI 2 "reg_or_short_operand" "rI"))
8418 (match_operand:SI 3 "gpc_reg_operand" "r"))
8419 (const_int 0)))
8420 (clobber (match_scratch:SI 4 "=&r"))]
8421 ""
8422 "{sf%I2|subf%I2c} %4,%1,%2\;{aze.|addze.} %4,%3"
8423 [(set_attr "type" "compare")
8424 (set_attr "length" "8")])
8425
8426 (define_insn ""
8427 [(set (match_operand:CC 5 "cc_reg_operand" "=x")
8428 (compare:CC
8429 (plus:SI (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
8430 (match_operand:SI 2 "reg_or_short_operand" "rI"))
8431 (match_operand:SI 3 "gpc_reg_operand" "r"))
8432 (const_int 0)))
8433 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
8434 (plus:SI (leu:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
8435 (clobber (match_scratch:SI 4 "=&r"))]
8436 ""
8437 "{sf%I2|subf%I2c} %4,%1,%2\;{aze.|addze.} %0,%3"
8438 [(set_attr "type" "compare")
8439 (set_attr "length" "8")])
8440
8441 (define_insn ""
8442 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
8443 (neg:SI (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
8444 (match_operand:SI 2 "reg_or_short_operand" "rI"))))]
8445 ""
8446 "{sf%I2|subf%I2c} %0,%1,%2\;{sfe|subfe} %0,%0,%0\;nand %0,%0,%0"
8447 [(set_attr "length" "12")])
8448
8449 (define_insn ""
8450 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
8451 (and:SI (neg:SI
8452 (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
8453 (match_operand:SI 2 "reg_or_short_operand" "rI")))
8454 (match_operand:SI 3 "gpc_reg_operand" "r")))
8455 (clobber (match_scratch:SI 4 "=&r"))]
8456 ""
8457 "{sf%I2|subf%I2c} %4,%1,%2\;{sfe|subfe} %4,%4,%4\;andc %0,%3,%4"
8458 [(set_attr "length" "12")])
8459
8460 (define_insn ""
8461 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
8462 (compare:CC
8463 (and:SI (neg:SI
8464 (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
8465 (match_operand:SI 2 "reg_or_short_operand" "rI")))
8466 (match_operand:SI 3 "gpc_reg_operand" "r"))
8467 (const_int 0)))
8468 (clobber (match_scratch:SI 4 "=&r"))]
8469 ""
8470 "{sf%I2|subf%I2c} %4,%1,%2\;{sfe|subfe} %4,%4,%4\;andc. %4,%3,%4"
8471 [(set_attr "type" "compare")
8472 (set_attr "length" "12")])
8473
8474 (define_insn ""
8475 [(set (match_operand:CC 5 "cc_reg_operand" "=x")
8476 (compare:CC
8477 (and:SI (neg:SI
8478 (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
8479 (match_operand:SI 2 "reg_or_short_operand" "rI")))
8480 (match_operand:SI 3 "gpc_reg_operand" "r"))
8481 (const_int 0)))
8482 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
8483 (and:SI (neg:SI (leu:SI (match_dup 1) (match_dup 2))) (match_dup 3)))
8484 (clobber (match_scratch:SI 4 "=&r"))]
8485 ""
8486 "{sf%I2|subf%I2c} %4,%1,%2\;{sfe|subfe} %4,%4,%4\;andc. %0,%3,%4"
8487 [(set_attr "type" "compare")
8488 (set_attr "length" "12")])
8489
8490 (define_insn ""
8491 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
8492 (lt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
8493 (match_operand:SI 2 "reg_or_short_operand" "rI")))]
8494 "TARGET_POWER"
8495 "doz%I2 %0,%1,%2\;nabs %0,%0\;{sri|srwi} %0,%0,31"
8496 [(set_attr "length" "12")])
8497
8498 (define_insn ""
8499 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
8500 (compare:CC
8501 (lt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
8502 (match_operand:SI 2 "reg_or_short_operand" "rI"))
8503 (const_int 0)))
8504 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
8505 (lt:SI (match_dup 1) (match_dup 2)))]
8506 "TARGET_POWER"
8507 "doz%I2 %0,%1,%2\;nabs %0,%0\;{sri.|srwi.} %0,%0,31"
8508 [(set_attr "type" "delayed_compare")
8509 (set_attr "length" "12")])
8510
8511 (define_insn ""
8512 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
8513 (plus:SI (lt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
8514 (match_operand:SI 2 "reg_or_short_operand" "rI"))
8515 (match_operand:SI 3 "gpc_reg_operand" "r")))
8516 (clobber (match_scratch:SI 4 "=&r"))]
8517 "TARGET_POWER"
8518 "doz%I2 %4,%1,%2\;{ai|addic} %4,%4,-1\;{aze|addze} %0,%3"
8519 [(set_attr "length" "12")])
8520
8521 (define_insn ""
8522 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
8523 (compare:CC
8524 (plus:SI (lt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
8525 (match_operand:SI 2 "reg_or_short_operand" "rI"))
8526 (match_operand:SI 3 "gpc_reg_operand" "r"))
8527 (const_int 0)))
8528 (clobber (match_scratch:SI 4 "=&r"))]
8529 "TARGET_POWER"
8530 "doz%I2 %4,%1,%2\;{ai|addic} %4,%4,-1\;{aze.|addze.} %4,%3"
8531 [(set_attr "type" "compare")
8532 (set_attr "length" "12")])
8533
8534 (define_insn ""
8535 [(set (match_operand:CC 5 "cc_reg_operand" "=x")
8536 (compare:CC
8537 (plus:SI (lt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
8538 (match_operand:SI 2 "reg_or_short_operand" "rI"))
8539 (match_operand:SI 3 "gpc_reg_operand" "r"))
8540 (const_int 0)))
8541 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
8542 (plus:SI (lt:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
8543 (clobber (match_scratch:SI 4 "=&r"))]
8544 "TARGET_POWER"
8545 "doz%I2 %4,%1,%2\;{ai|addic} %4,%4,-1\;{aze.|addze.} %0,%3"
8546 [(set_attr "type" "compare")
8547 (set_attr "length" "12")])
8548
8549 (define_insn ""
8550 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
8551 (neg:SI (lt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
8552 (match_operand:SI 2 "reg_or_short_operand" "rI"))))]
8553 "TARGET_POWER"
8554 "doz%I2 %0,%1,%2\;nabs %0,%0\;{srai|srawi} %0,%0,31"
8555 [(set_attr "length" "12")])
8556
8557 (define_insn ""
8558 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
8559 (ltu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
8560 (match_operand:SI 2 "reg_or_neg_short_operand" "r,P")))]
8561 ""
8562 "@
8563 {sf|subfc} %0,%2,%1\;{sfe|subfe} %0,%0,%0\;neg %0,%0
8564 {ai|addic} %0,%1,%n2\;{sfe|subfe} %0,%0,%0\;neg %0,%0"
8565 [(set_attr "length" "12")])
8566
8567 (define_insn ""
8568 [(set (match_operand:CC 3 "cc_reg_operand" "=x,x")
8569 (compare:CC
8570 (ltu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
8571 (match_operand:SI 2 "reg_or_neg_short_operand" "r,P"))
8572 (const_int 0)))
8573 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
8574 (ltu:SI (match_dup 1) (match_dup 2)))]
8575 ""
8576 "@
8577 {sf|subfc} %0,%2,%1\;{sfe|subfe} %0,%0,%0\;neg. %0,%0
8578 {ai|addic} %0,%1,%n2\;{sfe|subfe} %0,%0,%0\;neg. %0,%0"
8579 [(set_attr "type" "compare")
8580 (set_attr "length" "12")])
8581
8582 (define_insn ""
8583 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r")
8584 (plus:SI (ltu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r")
8585 (match_operand:SI 2 "reg_or_neg_short_operand" "r,r,P,P"))
8586 (match_operand:SI 3 "reg_or_short_operand" "r,I,r,I")))
8587 (clobber (match_scratch:SI 4 "=&r,r,&r,r"))]
8588 ""
8589 "@
8590 {sf|subfc} %4,%2,%1\;{sfe|subfe} %4,%4,%4\;{sf%I3|subf%I3c} %0,%4,%3
8591 {sf|subfc} %4,%2,%1\;{sfe|subfe} %4,%4,%4\;{sf%I3|subf%I3c} %0,%4,%3
8592 {ai|addic} %4,%1,%n2\;{sfe|subfe} %4,%4,%4\;{sf%I3|subf%I3c} %0,%4,%3
8593 {ai|addic} %4,%1,%n2\;{sfe|subfe} %4,%4,%4\;{sf%I3|subf%I3c} %0,%4,%3"
8594 [(set_attr "length" "12")])
8595
8596 (define_insn ""
8597 [(set (match_operand:CC 0 "cc_reg_operand" "=x,x")
8598 (compare:CC
8599 (plus:SI (ltu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
8600 (match_operand:SI 2 "reg_or_neg_short_operand" "r,P"))
8601 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
8602 (const_int 0)))
8603 (clobber (match_scratch:SI 4 "=&r,&r"))]
8604 ""
8605 "@
8606 {sf|subfc} %4,%2,%1\;{sfe|subfe} %4,%4,%4\;{sf.|subfc.} %4,%4,%3
8607 {ai|addic} %4,%1,%n2\;{sfe|subfe} %4,%4,%4\;{sf.|subfc.} %4,%4,%3"
8608 [(set_attr "type" "compare")
8609 (set_attr "length" "12")])
8610
8611 (define_insn ""
8612 [(set (match_operand:CC 5 "cc_reg_operand" "=x,x")
8613 (compare:CC
8614 (plus:SI (ltu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
8615 (match_operand:SI 2 "reg_or_neg_short_operand" "r,P"))
8616 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
8617 (const_int 0)))
8618 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
8619 (plus:SI (ltu:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
8620 (clobber (match_scratch:SI 4 "=&r,&r"))]
8621 ""
8622 "@
8623 {sf|subfc} %4,%2,%1\;{sfe|subfe} %4,%4,%4\;{sf.|subfc.} %0,%4,%3
8624 {ai|addic} %4,%1,%n2\;{sfe|subfe} %4,%4,%4\;{sf.|subfc.} %0,%4,%3"
8625 [(set_attr "type" "compare")
8626 (set_attr "length" "12")])
8627
8628 (define_insn ""
8629 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
8630 (neg:SI (ltu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
8631 (match_operand:SI 2 "reg_or_neg_short_operand" "r,P"))))]
8632 ""
8633 "@
8634 {sf|subfc} %0,%2,%1\;{sfe|subfe} %0,%0,%0
8635 {ai|addic} %0,%1,%n2\;{sfe|subfe} %0,%0,%0"
8636 [(set_attr "length" "8")])
8637
8638 (define_insn ""
8639 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
8640 (ge:SI (match_operand:SI 1 "gpc_reg_operand" "r")
8641 (match_operand:SI 2 "reg_or_short_operand" "rI")))
8642 (clobber (match_scratch:SI 3 "=r"))]
8643 "TARGET_POWER"
8644 "doz%I2 %3,%1,%2\;{sfi|subfic} %0,%3,0\;{ae|adde} %0,%0,%3"
8645 [(set_attr "length" "12")])
8646
8647 (define_insn ""
8648 [(set (match_operand:CC 4 "cc_reg_operand" "=x")
8649 (compare:CC
8650 (ge:SI (match_operand:SI 1 "gpc_reg_operand" "r")
8651 (match_operand:SI 2 "reg_or_short_operand" "rI"))
8652 (const_int 0)))
8653 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
8654 (ge:SI (match_dup 1) (match_dup 2)))
8655 (clobber (match_scratch:SI 3 "=r"))]
8656 "TARGET_POWER"
8657 "doz%I2 %3,%1,%2\;{sfi|subfic} %0,%3,0\;{ae.|adde.} %0,%0,%3"
8658 [(set_attr "type" "compare")
8659 (set_attr "length" "12")])
8660
8661 (define_insn ""
8662 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
8663 (plus:SI (ge:SI (match_operand:SI 1 "gpc_reg_operand" "r")
8664 (match_operand:SI 2 "reg_or_short_operand" "rI"))
8665 (match_operand:SI 3 "gpc_reg_operand" "r")))
8666 (clobber (match_scratch:SI 4 "=&r"))]
8667 "TARGET_POWER"
8668 "doz%I2 %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze|addze} %0,%3"
8669 [(set_attr "length" "12")])
8670
8671 (define_insn ""
8672 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
8673 (compare:CC
8674 (plus:SI (ge:SI (match_operand:SI 1 "gpc_reg_operand" "r")
8675 (match_operand:SI 2 "reg_or_short_operand" "rI"))
8676 (match_operand:SI 3 "gpc_reg_operand" "r"))
8677 (const_int 0)))
8678 (clobber (match_scratch:SI 4 "=&r"))]
8679 "TARGET_POWER"
8680 "doz%I2 %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %4,%3"
8681 [(set_attr "type" "compare")
8682 (set_attr "length" "12")])
8683
8684 (define_insn ""
8685 [(set (match_operand:CC 5 "cc_reg_operand" "=x")
8686 (compare:CC
8687 (plus:SI (ge:SI (match_operand:SI 1 "gpc_reg_operand" "r")
8688 (match_operand:SI 2 "reg_or_short_operand" "rI"))
8689 (match_operand:SI 3 "gpc_reg_operand" "r"))
8690 (const_int 0)))
8691 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
8692 (plus:SI (ge:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
8693 (clobber (match_scratch:SI 4 "=&r"))]
8694 "TARGET_POWER"
8695 "doz%I2 %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %0,%3"
8696 [(set_attr "type" "compare")
8697 (set_attr "length" "12")])
8698
8699 (define_insn ""
8700 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
8701 (neg:SI (ge:SI (match_operand:SI 1 "gpc_reg_operand" "r")
8702 (match_operand:SI 2 "reg_or_short_operand" "rI"))))]
8703 "TARGET_POWER"
8704 "doz%I2 %0,%1,%2\;{ai|addic} %0,%0,-1\;{sfe|subfe} %0,%0,%0"
8705 [(set_attr "length" "12")])
8706
8707 ;; This is (and (neg (ge X (const_int 0))) Y).
8708 (define_insn ""
8709 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
8710 (and:SI (neg:SI
8711 (lshiftrt:SI
8712 (not:SI (match_operand:SI 1 "gpc_reg_operand" "r"))
8713 (const_int 31)))
8714 (match_operand:SI 2 "gpc_reg_operand" "r")))
8715 (clobber (match_scratch:SI 3 "=&r"))]
8716 ""
8717 "{srai|srawi} %3,%1,31\;andc %0,%2,%3"
8718 [(set_attr "length" "8")])
8719
8720 (define_insn ""
8721 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
8722 (compare:CC
8723 (and:SI (neg:SI
8724 (lshiftrt:SI
8725 (not:SI (match_operand:SI 1 "gpc_reg_operand" "r"))
8726 (const_int 31)))
8727 (match_operand:SI 2 "gpc_reg_operand" "r"))
8728 (const_int 0)))
8729 (clobber (match_scratch:SI 3 "=&r"))]
8730 ""
8731 "{srai|srawi} %3,%1,31\;andc. %3,%2,%3"
8732 [(set_attr "type" "compare")
8733 (set_attr "length" "8")])
8734
8735 (define_insn ""
8736 [(set (match_operand:CC 4 "cc_reg_operand" "=x")
8737 (compare:CC
8738 (and:SI (neg:SI
8739 (lshiftrt:SI
8740 (not:SI (match_operand:SI 1 "gpc_reg_operand" "r"))
8741 (const_int 31)))
8742 (match_operand:SI 2 "gpc_reg_operand" "r"))
8743 (const_int 0)))
8744 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
8745 (and:SI (neg:SI (lshiftrt:SI (not:SI (match_dup 1))
8746 (const_int 31)))
8747 (match_dup 2)))
8748 (clobber (match_scratch:SI 3 "=&r"))]
8749 ""
8750 "{srai|srawi} %3,%1,31\;andc. %0,%2,%3"
8751 [(set_attr "type" "compare")
8752 (set_attr "length" "8")])
8753
8754 (define_insn ""
8755 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
8756 (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
8757 (match_operand:SI 2 "reg_or_neg_short_operand" "r,P")))]
8758 ""
8759 "@
8760 {sf|subfc} %0,%2,%1\;{cal %0,0(0)|li %0,0}\;{ae|adde} %0,%0,%0
8761 {ai|addic} %0,%1,%n2\;{cal %0,0(0)|li %0,0}\;{ae|adde} %0,%0,%0"
8762 [(set_attr "length" "12")])
8763
8764 (define_insn ""
8765 [(set (match_operand:CC 3 "cc_reg_operand" "=x,x")
8766 (compare:CC
8767 (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
8768 (match_operand:SI 2 "reg_or_neg_short_operand" "r,P"))
8769 (const_int 0)))
8770 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
8771 (geu:SI (match_dup 1) (match_dup 2)))]
8772 ""
8773 "@
8774 {sf|subfc} %0,%2,%1\;{cal %0,0(0)|li %0,0}\;{ae.|adde.} %0,%0,%0
8775 {ai|addic} %0,%1,%n2\;{cal %0,0(0)|li %0,0}\;{ae.|adde.} %0,%0,%0"
8776 [(set_attr "type" "compare")
8777 (set_attr "length" "12")])
8778
8779 (define_insn ""
8780 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
8781 (plus:SI (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
8782 (match_operand:SI 2 "reg_or_neg_short_operand" "r,P"))
8783 (match_operand:SI 3 "gpc_reg_operand" "r,r")))
8784 (clobber (match_scratch:SI 4 "=&r,&r"))]
8785 ""
8786 "@
8787 {sf|subfc} %4,%2,%1\;{aze|addze} %0,%3
8788 {ai|addic} %4,%1,%n2\;{aze|addze} %0,%3"
8789 [(set_attr "length" "8")])
8790
8791 (define_insn ""
8792 [(set (match_operand:CC 0 "cc_reg_operand" "=x,x")
8793 (compare:CC
8794 (plus:SI (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
8795 (match_operand:SI 2 "reg_or_neg_short_operand" "r,P"))
8796 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
8797 (const_int 0)))
8798 (clobber (match_scratch:SI 4 "=&r,&r"))]
8799 ""
8800 "@
8801 {sf|subfc} %4,%2,%1\;{aze.|addze.} %4,%3
8802 {ai|addic} %4,%1,%n2\;{aze.|addze.} %4,%3"
8803 [(set_attr "type" "compare")
8804 (set_attr "length" "8")])
8805
8806 (define_insn ""
8807 [(set (match_operand:CC 5 "cc_reg_operand" "=x,x")
8808 (compare:CC
8809 (plus:SI (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
8810 (match_operand:SI 2 "reg_or_neg_short_operand" "r,P"))
8811 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
8812 (const_int 0)))
8813 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
8814 (plus:SI (geu:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
8815 (clobber (match_scratch:SI 4 "=&r,&r"))]
8816 ""
8817 "@
8818 {sf|subfc} %4,%2,%1\;{aze.|addze.} %0,%3
8819 {ai|addic} %4,%1,%n2\;{aze.|addze.} %4,%3"
8820 [(set_attr "type" "compare")
8821 (set_attr "length" "8")])
8822
8823 (define_insn ""
8824 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
8825 (neg:SI (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
8826 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))]
8827 ""
8828 "@
8829 {sf|subfc} %0,%2,%1\;{sfe|subfe} %0,%0,%0\;nand %0,%0,%0
8830 {sfi|subfic} %0,%1,-1\;{a%I2|add%I2c} %0,%0,%2\;{sfe|subfe} %0,%0,%0"
8831 [(set_attr "length" "12")])
8832
8833 (define_insn ""
8834 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
8835 (and:SI (neg:SI
8836 (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
8837 (match_operand:SI 2 "reg_or_neg_short_operand" "r,P")))
8838 (match_operand:SI 3 "gpc_reg_operand" "r,r")))
8839 (clobber (match_scratch:SI 4 "=&r,&r"))]
8840 ""
8841 "@
8842 {sf|subfc} %4,%2,%1\;{sfe|subfe} %4,%4,%4\;andc %0,%3,%4
8843 {ai|addic} %4,%1,%n2\;{sfe|subfe} %4,%4,%4\;andc %0,%3,%4"
8844 [(set_attr "length" "12")])
8845
8846 (define_insn ""
8847 [(set (match_operand:CC 0 "cc_reg_operand" "=x,x")
8848 (compare:CC
8849 (and:SI (neg:SI
8850 (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
8851 (match_operand:SI 2 "reg_or_neg_short_operand" "r,P")))
8852 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
8853 (const_int 0)))
8854 (clobber (match_scratch:SI 4 "=&r,&r"))]
8855 ""
8856 "@
8857 {sf|subfc} %4,%2,%1\;{sfe|subfe} %4,%4,%4\;andc. %4,%3,%4
8858 {ai|addic} %4,%1,%n2\;{sfe|subfe} %4,%4,%4\;andc. %4,%3,%4"
8859 [(set_attr "type" "compare")
8860 (set_attr "length" "12")])
8861
8862 (define_insn ""
8863 [(set (match_operand:CC 5 "cc_reg_operand" "=x,x")
8864 (compare:CC
8865 (and:SI (neg:SI
8866 (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
8867 (match_operand:SI 2 "reg_or_neg_short_operand" "r,P")))
8868 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
8869 (const_int 0)))
8870 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
8871 (and:SI (neg:SI (geu:SI (match_dup 1) (match_dup 2))) (match_dup 3)))
8872 (clobber (match_scratch:SI 4 "=&r,&r"))]
8873 ""
8874 "@
8875 {sf|subfc} %4,%2,%1\;{sfe|subfe} %4,%4,%4\;andc. %0,%3,%4
8876 {ai|addic} %4,%1,%n2\;{sfe|subfe} %4,%4,%4\;andc. %0,%3,%4"
8877 [(set_attr "type" "compare")
8878 (set_attr "length" "12")])
8879
8880 (define_insn ""
8881 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
8882 (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
8883 (const_int 0)))]
8884 ""
8885 "{sfi|subfic} %0,%1,0\;{ame|addme} %0,%0\;{sri|srwi} %0,%0,31"
8886 [(set_attr "length" "12")])
8887
8888 (define_insn ""
8889 [(set (match_operand:CC 2 "cc_reg_operand" "=x")
8890 (compare:CC
8891 (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
8892 (const_int 0))
8893 (const_int 0)))
8894 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
8895 (gt:SI (match_dup 1) (const_int 0)))]
8896 ""
8897 "{sfi|subfic} %0,%1,0\;{ame|addme} %0,%0\;{sri.|srwi.} %0,%0,31"
8898 [(set_attr "type" "delayed_compare")
8899 (set_attr "length" "12")])
8900
8901 (define_insn ""
8902 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
8903 (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
8904 (match_operand:SI 2 "reg_or_short_operand" "r")))]
8905 "TARGET_POWER"
8906 "doz %0,%2,%1\;nabs %0,%0\;{sri|srwi} %0,%0,31"
8907 [(set_attr "length" "12")])
8908
8909 (define_insn ""
8910 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
8911 (compare:CC
8912 (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
8913 (match_operand:SI 2 "reg_or_short_operand" "r"))
8914 (const_int 0)))
8915 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
8916 (gt:SI (match_dup 1) (match_dup 2)))]
8917 "TARGET_POWER"
8918 "doz %0,%2,%1\;nabs %0,%0\;{sri.|srwi.} %0,%0,31"
8919 [(set_attr "type" "delayed_compare")
8920 (set_attr "length" "12")])
8921
8922 (define_insn ""
8923 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
8924 (plus:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
8925 (const_int 0))
8926 (match_operand:SI 2 "gpc_reg_operand" "r")))
8927 (clobber (match_scratch:SI 3 "=&r"))]
8928 ""
8929 "{a|addc} %3,%1,%1\;{sfe|subfe} %3,%1,%3\;{aze|addze} %0,%2"
8930 [(set_attr "length" "12")])
8931
8932 (define_insn ""
8933 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
8934 (compare:CC
8935 (plus:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
8936 (const_int 0))
8937 (match_operand:SI 2 "gpc_reg_operand" "r"))
8938 (const_int 0)))
8939 (clobber (match_scratch:SI 3 "=&r"))]
8940 ""
8941 "{a|addc} %3,%1,%1\;{sfe|subfe} %3,%1,%3\;{aze.|addze.} %0,%2"
8942 [(set_attr "type" "compare")
8943 (set_attr "length" "12")])
8944
8945 (define_insn ""
8946 [(set (match_operand:CC 4 "cc_reg_operand" "=x")
8947 (compare:CC
8948 (plus:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
8949 (const_int 0))
8950 (match_operand:SI 2 "gpc_reg_operand" "r"))
8951 (const_int 0)))
8952 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
8953 (plus:SI (gt:SI (match_dup 1) (const_int 0)) (match_dup 2)))
8954 (clobber (match_scratch:SI 3 "=&r"))]
8955 ""
8956 "{a|addc} %3,%1,%1\;{sfe|subfe} %3,%1,%3\;{aze.|addze.} %3,%2"
8957 [(set_attr "type" "compare")
8958 (set_attr "length" "12")])
8959
8960 (define_insn ""
8961 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
8962 (plus:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
8963 (match_operand:SI 2 "reg_or_short_operand" "r"))
8964 (match_operand:SI 3 "gpc_reg_operand" "r")))
8965 (clobber (match_scratch:SI 4 "=&r"))]
8966 "TARGET_POWER"
8967 "doz %4,%2,%1\;{ai|addic} %4,%4,-1\;{aze|addze} %0,%3"
8968 [(set_attr "length" "12")])
8969
8970 (define_insn ""
8971 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
8972 (compare:CC
8973 (plus:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
8974 (match_operand:SI 2 "reg_or_short_operand" "r"))
8975 (match_operand:SI 3 "gpc_reg_operand" "r"))
8976 (const_int 0)))
8977 (clobber (match_scratch:SI 4 "=&r"))]
8978 "TARGET_POWER"
8979 "doz %4,%2,%1\;{ai|addic} %4,%4,-1\;{aze.|addze.} %4,%3"
8980 [(set_attr "type" "compare")
8981 (set_attr "length" "12")])
8982
8983 (define_insn ""
8984 [(set (match_operand:CC 5 "cc_reg_operand" "=x")
8985 (compare:CC
8986 (plus:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
8987 (match_operand:SI 2 "reg_or_short_operand" "r"))
8988 (match_operand:SI 3 "gpc_reg_operand" "r"))
8989 (const_int 0)))
8990 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
8991 (plus:SI (gt:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
8992 (clobber (match_scratch:SI 4 "=&r"))]
8993 "TARGET_POWER"
8994 "doz %4,%2,%1\;{ai|addic} %4,%4,-1\;{aze.|addze.} %0,%3"
8995 [(set_attr "type" "compare")
8996 (set_attr "length" "12")])
8997
8998 (define_insn ""
8999 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
9000 (neg:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
9001 (const_int 0))))]
9002 ""
9003 "{sfi|subfic} %0,%1,0\;{ame|addme} %0,%0\;{srai|srawi} %0,%0,31"
9004 [(set_attr "length" "12")])
9005
9006 (define_insn ""
9007 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
9008 (neg:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
9009 (match_operand:SI 2 "reg_or_short_operand" "r"))))]
9010 "TARGET_POWER"
9011 "doz %0,%2,%1\;nabs %0,%0\;{srai|srawi} %0,%0,31"
9012 [(set_attr "length" "12")])
9013
9014 (define_insn ""
9015 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
9016 (gtu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
9017 (match_operand:SI 2 "reg_or_short_operand" "rI")))]
9018 ""
9019 "{sf%I2|subf%I2c} %0,%1,%2\;{sfe|subfe} %0,%0,%0\;neg %0,%0"
9020 [(set_attr "length" "12")])
9021
9022 (define_insn ""
9023 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
9024 (compare:CC
9025 (gtu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
9026 (match_operand:SI 2 "reg_or_short_operand" "rI"))
9027 (const_int 0)))
9028 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
9029 (gtu:SI (match_dup 1) (match_dup 2)))]
9030 ""
9031 "{sf%I2|subf%I2c} %0,%1,%2\;{sfe|subfe} %0,%0,%0\;neg. %0,%0"
9032 [(set_attr "type" "compare")
9033 (set_attr "length" "12")])
9034
9035 (define_insn ""
9036 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r")
9037 (plus:SI (gtu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r")
9038 (match_operand:SI 2 "reg_or_short_operand" "I,r,rI"))
9039 (match_operand:SI 3 "reg_or_short_operand" "r,r,I")))
9040 (clobber (match_scratch:SI 4 "=&r,&r,&r"))]
9041 ""
9042 "@
9043 {ai|addic} %4,%1,%k2\;{aze|addze} %0,%3
9044 {sf%I2|subf%I2c} %4,%1,%2\;{sfe|subfe} %4,%4,%4\;{sf%I3|subf%I3c} %0,%4,%3
9045 {sf%I2|subf%I2c} %4,%1,%2\;{sfe|subfe} %4,%4,%4\;{sf%I3|subf%I3c} %0,%4,%3"
9046 [(set_attr "length" "8,12,12")])
9047
9048 (define_insn ""
9049 [(set (match_operand:CC 0 "cc_reg_operand" "=x,x")
9050 (compare:CC
9051 (plus:SI (gtu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
9052 (match_operand:SI 2 "reg_or_short_operand" "I,r"))
9053 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
9054 (const_int 0)))
9055 (clobber (match_scratch:SI 4 "=&r,&r"))]
9056 ""
9057 "@
9058 {ai|addic} %4,%1,%k2\;{aze.|addze.} %0,%3
9059 {sf%I2|subf%I2c} %4,%1,%2\;{sfe|subfe} %4,%4,%4\;{sf.|subfc.} %0,%4,%3"
9060 [(set_attr "type" "compare")
9061 (set_attr "length" "8,12")])
9062
9063 (define_insn ""
9064 [(set (match_operand:CC 5 "cc_reg_operand" "=x,x")
9065 (compare:CC
9066 (plus:SI (gtu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
9067 (match_operand:SI 2 "reg_or_short_operand" "I,r"))
9068 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
9069 (const_int 0)))
9070 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
9071 (plus:SI (gtu:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
9072 (clobber (match_scratch:SI 4 "=&r,&r"))]
9073 ""
9074 "@
9075 {ai|addic} %4,%1,%k2\;{aze.|addze.} %0,%3
9076 {sf%I2|subf%I2c} %4,%1,%2\;{sfe|subfe} %4,%4,%4\;{sf.|subfc.} %0,%4,%3"
9077 [(set_attr "type" "compare")
9078 (set_attr "length" "8,12")])
9079
9080 (define_insn ""
9081 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
9082 (neg:SI (gtu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
9083 (match_operand:SI 2 "reg_or_short_operand" "rI"))))]
9084 ""
9085 "{sf%I2|subf%I2c} %0,%1,%2\;{sfe|subfe} %0,%0,%0"
9086 [(set_attr "length" "8")])
9087 \f
9088 ;; Define both directions of branch and return. If we need a reload
9089 ;; register, we'd rather use CR0 since it is much easier to copy a
9090 ;; register CC value to there.
9091
9092 (define_insn ""
9093 [(set (pc)
9094 (if_then_else (match_operator 1 "branch_comparison_operator"
9095 [(match_operand 2
9096 "cc_reg_operand" "x,?y")
9097 (const_int 0)])
9098 (label_ref (match_operand 0 "" ""))
9099 (pc)))]
9100 ""
9101 "*
9102 {
9103 if (get_attr_length (insn) == 8)
9104 return \"%C1bc %t1,%j1,%l0\";
9105 else
9106 return \"%C1bc %T1,%j1,%$+8\;b %l0\";
9107
9108 }"
9109 [(set_attr "type" "branch")])
9110
9111 (define_insn ""
9112 [(set (pc)
9113 (if_then_else (match_operator 0 "branch_comparison_operator"
9114 [(match_operand 1
9115 "cc_reg_operand" "x,?y")
9116 (const_int 0)])
9117 (return)
9118 (pc)))]
9119 "direct_return ()"
9120 "{%C0bcr|%C0bclr} %t0,%j0"
9121 [(set_attr "type" "branch")
9122 (set_attr "length" "8")])
9123
9124 (define_insn ""
9125 [(set (pc)
9126 (if_then_else (match_operator 1 "branch_comparison_operator"
9127 [(match_operand 2
9128 "cc_reg_operand" "x,?y")
9129 (const_int 0)])
9130 (pc)
9131 (label_ref (match_operand 0 "" ""))))]
9132 ""
9133 "*
9134 {
9135 if (get_attr_length (insn) == 8)
9136 return \"%C1bc %T1,%j1,%l0\";
9137 else
9138 return \"%C1bc %t1,%j1,%$+8\;b %l0\";
9139 }"
9140 [(set_attr "type" "branch")])
9141
9142 (define_insn ""
9143 [(set (pc)
9144 (if_then_else (match_operator 0 "branch_comparison_operator"
9145 [(match_operand 1
9146 "cc_reg_operand" "x,?y")
9147 (const_int 0)])
9148 (pc)
9149 (return)))]
9150 "direct_return ()"
9151 "{%C0bcr|%C0bclr} %T0,%j0"
9152 [(set_attr "type" "branch")
9153 (set_attr "length" "8")])
9154
9155 ;; Unconditional branch and return.
9156
9157 (define_insn "jump"
9158 [(set (pc)
9159 (label_ref (match_operand 0 "" "")))]
9160 ""
9161 "b %l0"
9162 [(set_attr "type" "branch")])
9163
9164 (define_insn "return"
9165 [(return)]
9166 "direct_return ()"
9167 "{br|blr}"
9168 [(set_attr "type" "jmpreg")])
9169
9170 (define_insn "indirect_jump"
9171 [(set (pc) (match_operand:SI 0 "register_operand" "c,l"))]
9172 ""
9173 "@
9174 bctr
9175 {br|blr}"
9176 [(set_attr "type" "jmpreg")])
9177
9178 (define_insn ""
9179 [(set (pc) (match_operand:DI 0 "register_operand" "c,l"))]
9180 "TARGET_POWERPC64"
9181 "@
9182 bctr
9183 {br|blr}"
9184 [(set_attr "type" "jmpreg")])
9185
9186 ;; Table jump for switch statements:
9187 (define_expand "tablejump"
9188 [(use (match_operand 0 "" ""))
9189 (use (label_ref (match_operand 1 "" "")))]
9190 ""
9191 "
9192 {
9193 if (TARGET_32BIT)
9194 emit_jump_insn (gen_tablejumpsi (operands[0], operands[1]));
9195 else
9196 emit_jump_insn (gen_tablejumpdi (operands[0], operands[1]));
9197 DONE;
9198 }")
9199
9200 (define_expand "tablejumpsi"
9201 [(set (match_dup 3)
9202 (plus:SI (match_operand:SI 0 "" "")
9203 (match_dup 2)))
9204 (parallel [(set (pc) (match_dup 3))
9205 (use (label_ref (match_operand 1 "" "")))])]
9206 ""
9207 "
9208 { operands[0] = force_reg (SImode, operands[0]);
9209 operands[2] = force_reg (SImode, gen_rtx (LABEL_REF, VOIDmode, operands[1]));
9210 operands[3] = gen_reg_rtx (SImode);
9211 }")
9212
9213 (define_expand "tablejumpdi"
9214 [(set (match_dup 3)
9215 (plus:DI (match_operand:DI 0 "" "")
9216 (match_dup 2)))
9217 (parallel [(set (pc) (match_dup 3))
9218 (use (label_ref (match_operand 1 "" "")))])]
9219 ""
9220 "
9221 { operands[0] = force_reg (DImode, operands[0]);
9222 operands[2] = force_reg (DImode, gen_rtx (LABEL_REF, VOIDmode, operands[1]));
9223 operands[3] = gen_reg_rtx (DImode);
9224 }")
9225
9226 (define_insn ""
9227 [(set (pc)
9228 (match_operand:SI 0 "register_operand" "c,l"))
9229 (use (label_ref (match_operand 1 "" "")))]
9230 ""
9231 "@
9232 bctr
9233 {br|blr}"
9234 [(set_attr "type" "jmpreg")])
9235
9236 (define_insn ""
9237 [(set (pc)
9238 (match_operand:DI 0 "register_operand" "c,l"))
9239 (use (label_ref (match_operand 1 "" "")))]
9240 "TARGET_POWERPC64"
9241 "@
9242 bctr
9243 {br|blr}"
9244 [(set_attr "type" "jmpreg")])
9245
9246 (define_insn "nop"
9247 [(const_int 0)]
9248 ""
9249 "{cror 0,0,0|nop}")
9250 \f
9251 ;; Define the subtract-one-and-jump insns, starting with the template
9252 ;; so loop.c knows what to generate.
9253
9254 (define_expand "decrement_and_branch_on_count"
9255 [(parallel [(set (pc) (if_then_else (ne (match_operand:SI 0 "register_operand" "")
9256 (const_int 1))
9257 (label_ref (match_operand 1 "" ""))
9258 (pc)))
9259 (set (match_dup 0)
9260 (plus:SI (match_dup 0)
9261 (const_int -1)))
9262 (clobber (match_scratch:CC 2 ""))
9263 (clobber (match_scratch:SI 3 ""))])]
9264 ""
9265 "")
9266
9267 ;; We need to be able to do this for any operand, including MEM, or we
9268 ;; will cause reload to blow up since we don't allow output reloads on
9269 ;; JUMP_INSNs.
9270 ;; In order that the length attribute is calculated correctly, the
9271 ;; label MUST be operand 0.
9272
9273 (define_insn ""
9274 [(set (pc)
9275 (if_then_else (ne (match_operand:SI 1 "register_operand" "c,*r,*r")
9276 (const_int 1))
9277 (label_ref (match_operand 0 "" ""))
9278 (pc)))
9279 (set (match_operand:SI 2 "register_operand" "=1,*r,m*q*c*l")
9280 (plus:SI (match_dup 1)
9281 (const_int -1)))
9282 (clobber (match_scratch:CC 3 "=X,&x,&x"))
9283 (clobber (match_scratch:SI 4 "=X,X,r"))]
9284 ""
9285 "*
9286 {
9287 if (which_alternative != 0)
9288 return \"#\";
9289 else if (get_attr_length (insn) == 8)
9290 return \"{bdn|bdnz} %l0\";
9291 else
9292 return \"bdz %$+8\;b %l0\";
9293 }"
9294 [(set_attr "type" "branch")
9295 (set_attr "length" "*,12,16")])
9296
9297 (define_insn ""
9298 [(set (pc)
9299 (if_then_else (ne (match_operand:SI 1 "register_operand" "c,*r,*r")
9300 (const_int 1))
9301 (pc)
9302 (label_ref (match_operand 0 "" ""))))
9303 (set (match_operand:SI 2 "register_operand" "=1,*r,m*q*c*l")
9304 (plus:SI (match_dup 1)
9305 (const_int -1)))
9306 (clobber (match_scratch:CC 3 "=X,&x,&x"))
9307 (clobber (match_scratch:SI 4 "=X,X,r"))]
9308 ""
9309 "*
9310 {
9311 if (which_alternative != 0)
9312 return \"#\";
9313 else if (get_attr_length (insn) == 8)
9314 return \"bdz %l0\";
9315 else
9316 return \"{bdn|bdnz} %$+8\;b %l0\";
9317 }"
9318 [(set_attr "type" "branch")
9319 (set_attr "length" "*,12,16")])
9320
9321 ;; Similar, but we can use GE since we have a REG_NONNEG.
9322 (define_insn ""
9323 [(set (pc)
9324 (if_then_else (ge (match_operand:SI 1 "register_operand" "c,*r,*r")
9325 (const_int 0))
9326 (label_ref (match_operand 0 "" ""))
9327 (pc)))
9328 (set (match_operand:SI 2 "register_operand" "=1,*r,m*q*c*l")
9329 (plus:SI (match_dup 1)
9330 (const_int -1)))
9331 (clobber (match_scratch:CC 3 "=X,&x,&X"))
9332 (clobber (match_scratch:SI 4 "=X,X,r"))]
9333 "find_reg_note (insn, REG_NONNEG, 0)"
9334 "*
9335 {
9336 if (which_alternative != 0)
9337 return \"#\";
9338 else if (get_attr_length (insn) == 8)
9339 return \"{bdn|bdnz} %l0\";
9340 else
9341 return \"bdz %$+8\;b %l0\";
9342 }"
9343 [(set_attr "type" "branch")
9344 (set_attr "length" "*,12,16")])
9345
9346 (define_insn ""
9347 [(set (pc)
9348 (if_then_else (ge (match_operand:SI 1 "register_operand" "c,*r,*r")
9349 (const_int 0))
9350 (pc)
9351 (label_ref (match_operand 0 "" ""))))
9352 (set (match_operand:SI 2 "register_operand" "=1,*r,m*q*c*l")
9353 (plus:SI (match_dup 1)
9354 (const_int -1)))
9355 (clobber (match_scratch:CC 3 "=X,&x,&X"))
9356 (clobber (match_scratch:SI 4 "=X,X,r"))]
9357 "find_reg_note (insn, REG_NONNEG, 0)"
9358 "*
9359 {
9360 if (which_alternative != 0)
9361 return \"#\";
9362 else if (get_attr_length (insn) == 8)
9363 return \"bdz %l0\";
9364 else
9365 return \"{bdn|bdnz} %$+8\;b %l0\";
9366 }"
9367 [(set_attr "type" "branch")
9368 (set_attr "length" "*,12,16")])
9369
9370 (define_insn ""
9371 [(set (pc)
9372 (if_then_else (eq (match_operand:SI 1 "register_operand" "c,*r,*r")
9373 (const_int 1))
9374 (label_ref (match_operand 0 "" ""))
9375 (pc)))
9376 (set (match_operand:SI 2 "register_operand" "=1,*r,m*q*c*l")
9377 (plus:SI (match_dup 1)
9378 (const_int -1)))
9379 (clobber (match_scratch:CC 3 "=X,&x,&x"))
9380 (clobber (match_scratch:SI 4 "=X,X,r"))]
9381 ""
9382 "*
9383 {
9384 if (which_alternative != 0)
9385 return \"#\";
9386 else if (get_attr_length (insn) == 8)
9387 return \"bdz %l0\";
9388 else
9389 return \"{bdn|bdnz} %$+8\;b %l0\";
9390 }"
9391 [(set_attr "type" "branch")
9392 (set_attr "length" "*,12,16")])
9393
9394 (define_insn ""
9395 [(set (pc)
9396 (if_then_else (eq (match_operand:SI 1 "register_operand" "c,*r,*r")
9397 (const_int 1))
9398 (pc)
9399 (label_ref (match_operand 0 "" ""))))
9400 (set (match_operand:SI 2 "register_operand" "=1,*r,m*q*c*l")
9401 (plus:SI (match_dup 1)
9402 (const_int -1)))
9403 (clobber (match_scratch:CC 3 "=X,&x,&x"))
9404 (clobber (match_scratch:SI 4 "=X,X,r"))]
9405 ""
9406 "*
9407 {
9408 if (which_alternative != 0)
9409 return \"#\";
9410 else if (get_attr_length (insn) == 8)
9411 return \"{bdn|bdnz} %l0\";
9412 else
9413 return \"bdz %$+8\;b %l0\";
9414 }"
9415 [(set_attr "type" "branch")
9416 (set_attr "length" "*,12,16")])
9417
9418 (define_split
9419 [(set (pc)
9420 (if_then_else (match_operator 2 "comparison_operator"
9421 [(match_operand:SI 1 "gpc_reg_operand" "")
9422 (const_int 1)])
9423 (match_operand 5 "" "")
9424 (match_operand 6 "" "")))
9425 (set (match_operand:SI 0 "gpc_reg_operand" "")
9426 (plus:SI (match_dup 1)
9427 (const_int -1)))
9428 (clobber (match_scratch:CC 3 ""))
9429 (clobber (match_scratch:SI 4 ""))]
9430 "reload_completed"
9431 [(parallel [(set (match_dup 3)
9432 (compare:CC (plus:SI (match_dup 1)
9433 (const_int -1))
9434 (const_int 0)))
9435 (set (match_dup 0)
9436 (plus:SI (match_dup 1)
9437 (const_int -1)))])
9438 (set (pc) (if_then_else (match_dup 7)
9439 (match_dup 5)
9440 (match_dup 6)))]
9441 "
9442 { operands[7] = gen_rtx (GET_CODE (operands[2]), VOIDmode, operands[3],
9443 const0_rtx); }")
9444
9445 (define_split
9446 [(set (pc)
9447 (if_then_else (match_operator 2 "comparison_operator"
9448 [(match_operand:SI 1 "gpc_reg_operand" "")
9449 (const_int 1)])
9450 (match_operand 5 "" "")
9451 (match_operand 6 "" "")))
9452 (set (match_operand:SI 0 "general_operand" "")
9453 (plus:SI (match_dup 1) (const_int -1)))
9454 (clobber (match_scratch:CC 3 ""))
9455 (clobber (match_scratch:SI 4 ""))]
9456 "reload_completed && ! gpc_reg_operand (operands[0], SImode)"
9457 [(parallel [(set (match_dup 3)
9458 (compare:CC (plus:SI (match_dup 1)
9459 (const_int -1))
9460 (const_int 0)))
9461 (set (match_dup 4)
9462 (plus:SI (match_dup 1)
9463 (const_int -1)))])
9464 (set (match_dup 0)
9465 (match_dup 4))
9466 (set (pc) (if_then_else (match_dup 7)
9467 (match_dup 5)
9468 (match_dup 6)))]
9469 "
9470 { operands[7] = gen_rtx (GET_CODE (operands[2]), VOIDmode, operands[3],
9471 const0_rtx); }")
This page took 0.482799 seconds and 5 git commands to generate.