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