]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/config/rs6000/rs6000.md
(decode_field_reference): Don't check TREE_CODE of EXP; let get_inner_reference decid...
[thirdparty/gcc.git] / gcc / config / rs6000 / rs6000.md
CommitLineData
996a5f59 1;; Machine description for IBM RISC System 6000 (POWER) for GNU C compiler
e8112008 2;; Copyright (C) 1990, 91, 92, 93, 94, 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"
242e8072
RK
1043 [(set (match_operand:SI 0 "gpc_reg_operand" "=&r")
1044 (ffs:SI (match_operand:SI 1 "gpc_reg_operand" "r")))]
1fd4e8c1 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 ""
242e8072 1767 [(set (match_operand:SI 0 "gpc_reg_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 1815 (const_int 0)))
242e8072 1816 (set (match_operand:SI 0 "gpc_reg_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
RK
2502;;
2503;; Note that when we store into a single-precision memory location, we need to
2504;; use the frsp insn first. If the register being stored isn't dead, we
2505;; need a scratch register for the frsp. But this is difficult when the store
2506;; is done by reload. It is not incorrect to do the frsp on the register in
2507;; this case, we just lose precision that we would have otherwise gotten but
2508;; is not guaranteed. Perhaps this should be tightened up at some point.
2509
e8112008 2510(define_insn "extendsfdf2"
cd2b37d9 2511 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
e8112008 2512 (float_extend:DF (match_operand:SF 1 "gpc_reg_operand" "f")))]
d14a6d05 2513 "TARGET_HARD_FLOAT"
e8112008 2514 "*
5c30aff8 2515{
e8112008
RK
2516 if (REGNO (operands[0]) == REGNO (operands[1]))
2517 return \"\";
2518 else
2519 return \"fmr %0,%1\";
2520}"
2521 [(set_attr "type" "fp")])
1fd4e8c1
RK
2522
2523(define_insn "truncdfsf2"
cd2b37d9
RK
2524 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
2525 (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "f")))]
d14a6d05 2526 "TARGET_HARD_FLOAT"
dcac138d 2527 "frsp %0,%1"
1fd4e8c1
RK
2528 [(set_attr "type" "fp")])
2529
2530(define_insn "negsf2"
cd2b37d9
RK
2531 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
2532 (neg:SF (match_operand:SF 1 "gpc_reg_operand" "f")))]
d14a6d05 2533 "TARGET_HARD_FLOAT"
1fd4e8c1
RK
2534 "fneg %0,%1"
2535 [(set_attr "type" "fp")])
2536
2537(define_insn "abssf2"
cd2b37d9
RK
2538 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
2539 (abs:SF (match_operand:SF 1 "gpc_reg_operand" "f")))]
d14a6d05 2540 "TARGET_HARD_FLOAT"
1fd4e8c1
RK
2541 "fabs %0,%1"
2542 [(set_attr "type" "fp")])
2543
2544(define_insn ""
cd2b37d9
RK
2545 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
2546 (neg:SF (abs:SF (match_operand:SF 1 "gpc_reg_operand" "f"))))]
d14a6d05 2547 "TARGET_HARD_FLOAT"
1fd4e8c1
RK
2548 "fnabs %0,%1"
2549 [(set_attr "type" "fp")])
2550
ca7f5001
RK
2551(define_expand "addsf3"
2552 [(set (match_operand:SF 0 "gpc_reg_operand" "")
2553 (plus:SF (match_operand:SF 1 "gpc_reg_operand" "")
2554 (match_operand:SF 2 "gpc_reg_operand" "")))]
d14a6d05 2555 "TARGET_HARD_FLOAT"
ca7f5001
RK
2556 "")
2557
2558(define_insn ""
cd2b37d9
RK
2559 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
2560 (plus:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
2561 (match_operand:SF 2 "gpc_reg_operand" "f")))]
d14a6d05 2562 "TARGET_POWERPC && TARGET_HARD_FLOAT"
b26c8351 2563 "fadds %0,%1,%2"
ca7f5001
RK
2564 [(set_attr "type" "fp")])
2565
2566(define_insn ""
2567 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
2568 (plus:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
2569 (match_operand:SF 2 "gpc_reg_operand" "f")))]
d14a6d05 2570 "! TARGET_POWERPC && TARGET_HARD_FLOAT"
b26c8351 2571 "{fa|fadd} %0,%1,%2"
ca7f5001
RK
2572 [(set_attr "type" "fp")])
2573
2574(define_expand "subsf3"
2575 [(set (match_operand:SF 0 "gpc_reg_operand" "")
2576 (minus:SF (match_operand:SF 1 "gpc_reg_operand" "")
2577 (match_operand:SF 2 "gpc_reg_operand" "")))]
d14a6d05 2578 "TARGET_HARD_FLOAT"
ca7f5001
RK
2579 "")
2580
2581(define_insn ""
2582 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
2583 (minus:SF (match_operand:SF 1 "gpc_reg_operand" "f")
2584 (match_operand:SF 2 "gpc_reg_operand" "f")))]
d14a6d05 2585 "TARGET_POWERPC && TARGET_HARD_FLOAT"
b26c8351 2586 "fsubs %0,%1,%2"
1fd4e8c1
RK
2587 [(set_attr "type" "fp")])
2588
ca7f5001 2589(define_insn ""
cd2b37d9
RK
2590 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
2591 (minus:SF (match_operand:SF 1 "gpc_reg_operand" "f")
2592 (match_operand:SF 2 "gpc_reg_operand" "f")))]
d14a6d05 2593 "! TARGET_POWERPC && TARGET_HARD_FLOAT"
b26c8351 2594 "{fs|fsub} %0,%1,%2"
ca7f5001
RK
2595 [(set_attr "type" "fp")])
2596
2597(define_expand "mulsf3"
2598 [(set (match_operand:SF 0 "gpc_reg_operand" "")
2599 (mult:SF (match_operand:SF 1 "gpc_reg_operand" "")
2600 (match_operand:SF 2 "gpc_reg_operand" "")))]
d14a6d05 2601 "TARGET_HARD_FLOAT"
ca7f5001
RK
2602 "")
2603
2604(define_insn ""
2605 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
2606 (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
2607 (match_operand:SF 2 "gpc_reg_operand" "f")))]
d14a6d05 2608 "TARGET_POWERPC && TARGET_HARD_FLOAT"
b26c8351 2609 "fmuls %0,%1,%2"
1fd4e8c1
RK
2610 [(set_attr "type" "fp")])
2611
ca7f5001 2612(define_insn ""
cd2b37d9
RK
2613 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
2614 (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
2615 (match_operand:SF 2 "gpc_reg_operand" "f")))]
d14a6d05 2616 "! TARGET_POWERPC && TARGET_HARD_FLOAT"
b26c8351 2617 "{fm|fmul} %0,%1,%2"
1fd4e8c1
RK
2618 [(set_attr "type" "fp")])
2619
ca7f5001
RK
2620(define_expand "divsf3"
2621 [(set (match_operand:SF 0 "gpc_reg_operand" "")
2622 (div:SF (match_operand:SF 1 "gpc_reg_operand" "")
2623 (match_operand:SF 2 "gpc_reg_operand" "")))]
d14a6d05 2624 "TARGET_HARD_FLOAT"
ca7f5001
RK
2625 "")
2626
2627(define_insn ""
cd2b37d9
RK
2628 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
2629 (div:SF (match_operand:SF 1 "gpc_reg_operand" "f")
2630 (match_operand:SF 2 "gpc_reg_operand" "f")))]
d14a6d05 2631 "TARGET_POWERPC && TARGET_HARD_FLOAT"
b26c8351 2632 "fdivs %0,%1,%2"
ca7f5001
RK
2633 [(set_attr "type" "sdiv")])
2634
2635(define_insn ""
2636 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
2637 (div:SF (match_operand:SF 1 "gpc_reg_operand" "f")
2638 (match_operand:SF 2 "gpc_reg_operand" "f")))]
d14a6d05 2639 "! TARGET_POWERPC && TARGET_HARD_FLOAT"
b26c8351 2640 "{fd|fdiv} %0,%1,%2"
cfb557c4 2641 [(set_attr "type" "sdiv")])
1fd4e8c1
RK
2642
2643(define_insn ""
cd2b37d9
RK
2644 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
2645 (plus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
2646 (match_operand:SF 2 "gpc_reg_operand" "f"))
2647 (match_operand:SF 3 "gpc_reg_operand" "f")))]
d14a6d05 2648 "TARGET_POWERPC && TARGET_HARD_FLOAT"
b26c8351 2649 "fmadds %0,%1,%2,%3"
ca7f5001
RK
2650 [(set_attr "type" "fp")])
2651
2652(define_insn ""
2653 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
2654 (plus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
2655 (match_operand:SF 2 "gpc_reg_operand" "f"))
2656 (match_operand:SF 3 "gpc_reg_operand" "f")))]
d14a6d05 2657 "! TARGET_POWERPC && TARGET_HARD_FLOAT"
b26c8351 2658 "{fma|fmadd} %0,%1,%2,%3"
1fd4e8c1
RK
2659 [(set_attr "type" "fp")])
2660
2661(define_insn ""
cd2b37d9
RK
2662 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
2663 (minus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
2664 (match_operand:SF 2 "gpc_reg_operand" "f"))
2665 (match_operand:SF 3 "gpc_reg_operand" "f")))]
d14a6d05 2666 "TARGET_POWERPC && TARGET_HARD_FLOAT"
b26c8351 2667 "fmsubs %0,%1,%2,%3"
ca7f5001
RK
2668 [(set_attr "type" "fp")])
2669
2670(define_insn ""
2671 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
2672 (minus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
2673 (match_operand:SF 2 "gpc_reg_operand" "f"))
2674 (match_operand:SF 3 "gpc_reg_operand" "f")))]
d14a6d05 2675 "! TARGET_POWERPC && TARGET_HARD_FLOAT"
b26c8351 2676 "{fms|fmsub} %0,%1,%2,%3"
1fd4e8c1
RK
2677 [(set_attr "type" "fp")])
2678
2679(define_insn ""
cd2b37d9
RK
2680 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
2681 (neg:SF (plus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
2682 (match_operand:SF 2 "gpc_reg_operand" "f"))
2683 (match_operand:SF 3 "gpc_reg_operand" "f"))))]
d14a6d05 2684 "TARGET_POWERPC && TARGET_HARD_FLOAT"
b26c8351 2685 "fnmadds %0,%1,%2,%3"
ca7f5001
RK
2686 [(set_attr "type" "fp")])
2687
2688(define_insn ""
2689 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
2690 (neg:SF (plus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
2691 (match_operand:SF 2 "gpc_reg_operand" "f"))
2692 (match_operand:SF 3 "gpc_reg_operand" "f"))))]
d14a6d05 2693 "! TARGET_POWERPC && TARGET_HARD_FLOAT"
b26c8351 2694 "{fnma|fnmadd} %0,%1,%2,%3"
1fd4e8c1
RK
2695 [(set_attr "type" "fp")])
2696
2697(define_insn ""
cd2b37d9
RK
2698 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
2699 (neg:SF (minus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
2700 (match_operand:SF 2 "gpc_reg_operand" "f"))
2701 (match_operand:SF 3 "gpc_reg_operand" "f"))))]
d14a6d05 2702 "TARGET_POWERPC && TARGET_HARD_FLOAT"
b26c8351 2703 "fnmsubs %0,%1,%2,%3"
ca7f5001
RK
2704 [(set_attr "type" "fp")])
2705
2706(define_insn ""
2707 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
2708 (neg:SF (minus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
2709 (match_operand:SF 2 "gpc_reg_operand" "f"))
2710 (match_operand:SF 3 "gpc_reg_operand" "f"))))]
d14a6d05 2711 "! TARGET_POWERPC && TARGET_HARD_FLOAT"
b26c8351 2712 "{fnms|fnmsub} %0,%1,%2,%3"
1fd4e8c1
RK
2713 [(set_attr "type" "fp")])
2714
ca7f5001
RK
2715(define_expand "sqrtsf2"
2716 [(set (match_operand:SF 0 "gpc_reg_operand" "")
2717 (sqrt:SF (match_operand:SF 1 "gpc_reg_operand" "")))]
d14a6d05 2718 "(TARGET_PPC_GPOPT || TARGET_POWER2) && TARGET_HARD_FLOAT"
ca7f5001
RK
2719 "")
2720
2721(define_insn ""
2722 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
2723 (sqrt:SF (match_operand:SF 1 "gpc_reg_operand" "f")))]
d14a6d05 2724 "TARGET_PPC_GPOPT && TARGET_HARD_FLOAT"
ca7f5001
RK
2725 "fsqrts %0,%1"
2726 [(set_attr "type" "ssqrt")])
2727
2728(define_insn ""
2729 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
2730 (sqrt:SF (match_operand:SF 1 "gpc_reg_operand" "f")))]
d14a6d05 2731 "TARGET_POWER2 && TARGET_HARD_FLOAT"
ca7f5001
RK
2732 "fsqrt %0,%1"
2733 [(set_attr "type" "dsqrt")])
2734
94d7001a
RK
2735;; For MIN, MAX, and conditional move, we use DEFINE_EXPAND's that involve a
2736;; fsel instruction and some auxiliary computations. Then we just have a
2737;; single DEFINE_INSN for fsel and the define_splits to make them if made by
8e871c05
RK
2738;; combine.
2739(define_expand "maxsf3"
2740 [(set (match_dup 3)
2741 (minus:SF (match_operand:SF 1 "gpc_reg_operand" "")
2742 (match_operand:SF 2 "gpc_reg_operand" "")))
2743 (set (match_operand:SF 0 "gpc_reg_operand" "")
2744 (if_then_else:SF (ge (match_dup 3)
2745 (const_int 0))
2746 (match_dup 1)
2747 (match_dup 2)))]
d14a6d05 2748 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT"
8e871c05
RK
2749 "
2750{ operands[3] = gen_reg_rtx (SFmode); }")
2f607b94 2751
8e871c05
RK
2752(define_split
2753 [(set (match_operand:SF 0 "gpc_reg_operand" "")
2754 (smax:SF (match_operand:SF 1 "gpc_reg_operand" "")
f63184ac 2755 (match_operand:SF 2 "gpc_reg_operand" "")))
8e871c05 2756 (clobber (match_operand:SF 3 "gpc_reg_operand" ""))]
d14a6d05 2757 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT"
8e871c05
RK
2758 [(set (match_dup 3)
2759 (minus:SF (match_dup 1) (match_dup 2)))
a81bd72f 2760 (set (match_dup 0)
8e871c05
RK
2761 (if_then_else:SF (ge (match_dup 3)
2762 (const_int 0))
2763 (match_dup 1)
2764 (match_dup 2)))]
2765 "")
2f607b94 2766
8e871c05
RK
2767(define_expand "minsf3"
2768 [(set (match_dup 3)
2769 (minus:SF (match_operand:SF 2 "gpc_reg_operand" "")
2770 (match_operand:SF 1 "gpc_reg_operand" "")))
2771 (set (match_operand:SF 0 "gpc_reg_operand" "")
2772 (if_then_else:SF (ge (match_dup 3)
2773 (const_int 0))
2774 (match_dup 1)
2775 (match_dup 2)))]
d14a6d05 2776 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT"
8e871c05
RK
2777 "
2778{ operands[3] = gen_reg_rtx (SFmode); }")
2f607b94 2779
8e871c05
RK
2780(define_split
2781 [(set (match_operand:SF 0 "gpc_reg_operand" "")
2782 (smin:SF (match_operand:SF 1 "gpc_reg_operand" "")
f63184ac 2783 (match_operand:SF 2 "gpc_reg_operand" "")))
8e871c05 2784 (clobber (match_operand:SF 3 "gpc_reg_operand" ""))]
d14a6d05 2785 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT"
8e871c05
RK
2786 [(set (match_dup 3)
2787 (minus:SF (match_dup 2) (match_dup 1)))
a81bd72f 2788 (set (match_dup 0)
8e871c05
RK
2789 (if_then_else:SF (ge (match_dup 3)
2790 (const_int 0))
2791 (match_dup 1)
2792 (match_dup 2)))]
2793 "")
2f607b94 2794
94d7001a
RK
2795(define_expand "movsfcc"
2796 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
2797 (if_then_else:SF (match_operand 1 "comparison_operator" "")
2798 (match_operand:SF 2 "gpc_reg_operand" "f")
2799 (match_operand:SF 3 "gpc_reg_operand" "f")))]
d14a6d05 2800 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT"
94d7001a
RK
2801 "
2802{
2803 rtx temp, op0, op1;
2804 enum rtx_code code = GET_CODE (operands[1]);
2805 if (! rs6000_compare_fp_p)
2806 FAIL;
2807 switch (code)
2808 {
2809 case GE: case EQ: case NE:
2810 op0 = rs6000_compare_op0;
2811 op1 = rs6000_compare_op1;
2812 break;
2813 case GT:
2814 op0 = rs6000_compare_op1;
2815 op1 = rs6000_compare_op0;
2816 temp = operands[2]; operands[2] = operands[3]; operands[3] = temp;
2817 break;
2818 case LE:
2819 op0 = rs6000_compare_op1;
2820 op1 = rs6000_compare_op0;
2821 break;
2822 case LT:
2823 op0 = rs6000_compare_op0;
2824 op1 = rs6000_compare_op1;
2825 temp = operands[2]; operands[2] = operands[3]; operands[3] = temp;
2826 break;
2827 default:
2828 FAIL;
2829 }
2830 if (GET_MODE (rs6000_compare_op0) == DFmode)
2831 {
2832 temp = gen_reg_rtx (DFmode);
2833 emit_insn (gen_subdf3 (temp, op0, op1));
2834 emit_insn (gen_fseldfsf4 (operands[0], temp, operands[2], operands[3]));
2835 if (code == EQ)
2836 {
2837 emit_insn (gen_negdf2 (temp, temp));
2838 emit_insn (gen_fseldfsf4 (operands[0], temp, operands[0], operands[3]));
2839 }
2840 if (code == NE)
2841 {
2842 emit_insn (gen_negdf2 (temp, temp));
2843 emit_insn (gen_fseldfsf4 (operands[0], temp, operands[3], operands[0]));
2844 }
2845 }
2846 else
2847 {
2848 temp = gen_reg_rtx (SFmode);
2849 emit_insn (gen_subsf3 (temp, op0, op1));
2850 emit_insn (gen_fselsfsf4 (operands[0], temp, operands[2], operands[3]));
2851 if (code == EQ)
2852 {
2853 emit_insn (gen_negsf2 (temp, temp));
2854 emit_insn (gen_fselsfsf4 (operands[0], temp, operands[0], operands[3]));
2855 }
2856 if (code == NE)
2857 {
2858 emit_insn (gen_negsf2 (temp, temp));
2859 emit_insn (gen_fselsfsf4 (operands[0], temp, operands[3], operands[0]));
2860 }
2861 }
2862 DONE;
2863}")
2864(define_insn "fselsfsf4"
8e871c05
RK
2865 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
2866 (if_then_else:SF (ge (match_operand:SF 1 "gpc_reg_operand" "f")
2867 (const_int 0))
2868 (match_operand:SF 2 "gpc_reg_operand" "f")
2869 (match_operand:SF 3 "gpc_reg_operand" "f")))]
d14a6d05 2870 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT"
8e871c05
RK
2871 "fsel %0,%1,%2,%3"
2872 [(set_attr "type" "fp")])
2f607b94 2873
94d7001a
RK
2874(define_insn "fseldfsf4"
2875 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
2876 (if_then_else:SF (ge (match_operand:DF 1 "gpc_reg_operand" "f")
2877 (const_int 0))
2878 (match_operand:SF 2 "gpc_reg_operand" "f")
2879 (match_operand:SF 3 "gpc_reg_operand" "f")))]
d14a6d05 2880 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT"
94d7001a
RK
2881 "fsel %0,%1,%2,%3"
2882 [(set_attr "type" "fp")])
1fd4e8c1 2883(define_insn "negdf2"
cd2b37d9
RK
2884 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
2885 (neg:DF (match_operand:DF 1 "gpc_reg_operand" "f")))]
d14a6d05 2886 "TARGET_HARD_FLOAT"
1fd4e8c1
RK
2887 "fneg %0,%1"
2888 [(set_attr "type" "fp")])
2889
2890(define_insn "absdf2"
cd2b37d9
RK
2891 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
2892 (abs:DF (match_operand:DF 1 "gpc_reg_operand" "f")))]
d14a6d05 2893 "TARGET_HARD_FLOAT"
1fd4e8c1
RK
2894 "fabs %0,%1"
2895 [(set_attr "type" "fp")])
2896
2897(define_insn ""
cd2b37d9
RK
2898 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
2899 (neg:DF (abs:DF (match_operand:DF 1 "gpc_reg_operand" "f"))))]
d14a6d05 2900 "TARGET_HARD_FLOAT"
1fd4e8c1
RK
2901 "fnabs %0,%1"
2902 [(set_attr "type" "fp")])
2903
2904(define_insn "adddf3"
cd2b37d9
RK
2905 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
2906 (plus:DF (match_operand:DF 1 "gpc_reg_operand" "%f")
2907 (match_operand:DF 2 "gpc_reg_operand" "f")))]
d14a6d05 2908 "TARGET_HARD_FLOAT"
ca7f5001 2909 "{fa|fadd} %0,%1,%2"
1fd4e8c1
RK
2910 [(set_attr "type" "fp")])
2911
2912(define_insn "subdf3"
cd2b37d9
RK
2913 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
2914 (minus:DF (match_operand:DF 1 "gpc_reg_operand" "f")
2915 (match_operand:DF 2 "gpc_reg_operand" "f")))]
d14a6d05 2916 "TARGET_HARD_FLOAT"
ca7f5001 2917 "{fs|fsub} %0,%1,%2"
1fd4e8c1
RK
2918 [(set_attr "type" "fp")])
2919
2920(define_insn "muldf3"
cd2b37d9
RK
2921 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
2922 (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%f")
2923 (match_operand:DF 2 "gpc_reg_operand" "f")))]
d14a6d05 2924 "TARGET_HARD_FLOAT"
ca7f5001 2925 "{fm|fmul} %0,%1,%2"
cfb557c4 2926 [(set_attr "type" "dmul")])
1fd4e8c1
RK
2927
2928(define_insn "divdf3"
cd2b37d9
RK
2929 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
2930 (div:DF (match_operand:DF 1 "gpc_reg_operand" "f")
2931 (match_operand:DF 2 "gpc_reg_operand" "f")))]
d14a6d05 2932 "TARGET_HARD_FLOAT"
ca7f5001 2933 "{fd|fdiv} %0,%1,%2"
cfb557c4 2934 [(set_attr "type" "ddiv")])
1fd4e8c1
RK
2935
2936(define_insn ""
cd2b37d9
RK
2937 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
2938 (plus:DF (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%f")
2939 (match_operand:DF 2 "gpc_reg_operand" "f"))
2940 (match_operand:DF 3 "gpc_reg_operand" "f")))]
d14a6d05 2941 "TARGET_HARD_FLOAT"
ca7f5001 2942 "{fma|fmadd} %0,%1,%2,%3"
cfb557c4 2943 [(set_attr "type" "dmul")])
1fd4e8c1
RK
2944
2945(define_insn ""
cd2b37d9
RK
2946 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
2947 (minus:DF (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%f")
2948 (match_operand:DF 2 "gpc_reg_operand" "f"))
2949 (match_operand:DF 3 "gpc_reg_operand" "f")))]
d14a6d05 2950 "TARGET_HARD_FLOAT"
ca7f5001 2951 "{fms|fmsub} %0,%1,%2,%3"
cfb557c4 2952 [(set_attr "type" "dmul")])
1fd4e8c1
RK
2953
2954(define_insn ""
cd2b37d9
RK
2955 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
2956 (neg:DF (plus:DF (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%f")
2957 (match_operand:DF 2 "gpc_reg_operand" "f"))
2958 (match_operand:DF 3 "gpc_reg_operand" "f"))))]
d14a6d05 2959 "TARGET_HARD_FLOAT"
ca7f5001 2960 "{fnma|fnmadd} %0,%1,%2,%3"
cfb557c4 2961 [(set_attr "type" "dmul")])
1fd4e8c1
RK
2962
2963(define_insn ""
cd2b37d9
RK
2964 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
2965 (neg:DF (minus:DF (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%f")
2966 (match_operand:DF 2 "gpc_reg_operand" "f"))
2967 (match_operand:DF 3 "gpc_reg_operand" "f"))))]
d14a6d05 2968 "TARGET_HARD_FLOAT"
ca7f5001 2969 "{fnms|fnmsub} %0,%1,%2,%3"
cfb557c4 2970 [(set_attr "type" "dmul")])
ca7f5001
RK
2971
2972(define_insn "sqrtdf2"
2973 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
2974 (sqrt:DF (match_operand:DF 1 "gpc_reg_operand" "f")))]
d14a6d05 2975 "(TARGET_PPC_GPOPT || TARGET_POWER2) && TARGET_HARD_FLOAT"
ca7f5001
RK
2976 "fsqrt %0,%1"
2977 [(set_attr "type" "dsqrt")])
b77dfefc 2978
94d7001a
RK
2979;; For MIN, MAX, and conditional move, we use DEFINE_EXPAND's that involve a
2980;; fsel instruction and some auxiliary computations. Then we just have a
2981;; single DEFINE_INSN for fsel and the define_splits to make them if made by
8e871c05 2982;; combine.
b77dfefc 2983
8e871c05
RK
2984(define_expand "maxdf3"
2985 [(set (match_dup 3)
2986 (minus:DF (match_operand:DF 1 "gpc_reg_operand" "")
2987 (match_operand:DF 2 "gpc_reg_operand" "")))
2988 (set (match_operand:DF 0 "gpc_reg_operand" "")
2989 (if_then_else:DF (ge (match_dup 3)
2990 (const_int 0))
2991 (match_dup 1)
2992 (match_dup 2)))]
d14a6d05 2993 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT"
8e871c05
RK
2994 "
2995{ operands[3] = gen_reg_rtx (DFmode); }")
b77dfefc 2996
8e871c05
RK
2997(define_split
2998 [(set (match_operand:DF 0 "gpc_reg_operand" "")
2999 (smax:DF (match_operand:DF 1 "gpc_reg_operand" "")
f63184ac 3000 (match_operand:DF 2 "gpc_reg_operand" "")))
8e871c05 3001 (clobber (match_operand:DF 3 "gpc_reg_operand" ""))]
d14a6d05 3002 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT"
8e871c05
RK
3003 [(set (match_dup 3)
3004 (minus:DF (match_dup 1) (match_dup 2)))
a81bd72f 3005 (set (match_dup 0)
8e871c05
RK
3006 (if_then_else:DF (ge (match_dup 3)
3007 (const_int 0))
3008 (match_dup 1)
3009 (match_dup 2)))]
3010 "")
b77dfefc 3011
8e871c05
RK
3012(define_expand "mindf3"
3013 [(set (match_dup 3)
3014 (minus:DF (match_operand:DF 2 "gpc_reg_operand" "")
3015 (match_operand:DF 1 "gpc_reg_operand" "")))
3016 (set (match_operand:DF 0 "gpc_reg_operand" "")
3017 (if_then_else:DF (ge (match_dup 3)
3018 (const_int 0))
3019 (match_dup 1)
3020 (match_dup 2)))]
d14a6d05 3021 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT"
8e871c05
RK
3022 "
3023{ operands[3] = gen_reg_rtx (DFmode); }")
b77dfefc 3024
8e871c05
RK
3025(define_split
3026 [(set (match_operand:DF 0 "gpc_reg_operand" "")
3027 (smin:DF (match_operand:DF 1 "gpc_reg_operand" "")
f63184ac 3028 (match_operand:DF 2 "gpc_reg_operand" "")))
8e871c05 3029 (clobber (match_operand:DF 3 "gpc_reg_operand" ""))]
d14a6d05 3030 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT"
8e871c05
RK
3031 [(set (match_dup 3)
3032 (minus:DF (match_dup 2) (match_dup 1)))
a81bd72f 3033 (set (match_dup 0)
8e871c05
RK
3034 (if_then_else:DF (ge (match_dup 3)
3035 (const_int 0))
3036 (match_dup 1)
3037 (match_dup 2)))]
3038 "")
b77dfefc 3039
94d7001a
RK
3040(define_expand "movdfcc"
3041 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
3042 (if_then_else:DF (match_operand 1 "comparison_operator" "")
3043 (match_operand:DF 2 "gpc_reg_operand" "f")
3044 (match_operand:DF 3 "gpc_reg_operand" "f")))]
d14a6d05 3045 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT"
94d7001a
RK
3046 "
3047{
3048 rtx temp, op0, op1;
3049 enum rtx_code code = GET_CODE (operands[1]);
3050 if (! rs6000_compare_fp_p)
3051 FAIL;
3052 switch (code)
3053 {
3054 case GE: case EQ: case NE:
3055 op0 = rs6000_compare_op0;
3056 op1 = rs6000_compare_op1;
3057 break;
3058 case GT:
3059 op0 = rs6000_compare_op1;
3060 op1 = rs6000_compare_op0;
3061 temp = operands[2]; operands[2] = operands[3]; operands[3] = temp;
3062 break;
3063 case LE:
3064 op0 = rs6000_compare_op1;
3065 op1 = rs6000_compare_op0;
3066 break;
3067 case LT:
3068 op0 = rs6000_compare_op0;
3069 op1 = rs6000_compare_op1;
3070 temp = operands[2]; operands[2] = operands[3]; operands[3] = temp;
3071 break;
3072 default:
3073 FAIL;
3074 }
3075 if (GET_MODE (rs6000_compare_op0) == DFmode)
3076 {
3077 temp = gen_reg_rtx (DFmode);
3078 emit_insn (gen_subdf3 (temp, op0, op1));
3079 emit_insn (gen_fseldfdf4 (operands[0], temp, operands[2], operands[3]));
3080 if (code == EQ)
3081 {
3082 emit_insn (gen_negdf2 (temp, temp));
3083 emit_insn (gen_fseldfdf4 (operands[0], temp, operands[0], operands[3]));
3084 }
3085 if (code == NE)
3086 {
3087 emit_insn (gen_negdf2 (temp, temp));
3088 emit_insn (gen_fseldfdf4 (operands[0], temp, operands[3], operands[0]));
3089 }
3090 }
3091 else
3092 {
3093 temp = gen_reg_rtx (SFmode);
3094 emit_insn (gen_subsf3 (temp, op0, op1));
3095 emit_insn (gen_fselsfdf4 (operands[0], temp, operands[2], operands[3]));
3096 if (code == EQ)
3097 {
3098 emit_insn (gen_negsf2 (temp, temp));
3099 emit_insn (gen_fselsfdf4 (operands[0], temp, operands[0], operands[3]));
3100 }
3101 if (code == NE)
3102 {
3103 emit_insn (gen_negsf2 (temp, temp));
3104 emit_insn (gen_fselsfdf4 (operands[0], temp, operands[3], operands[0]));
3105 }
3106 }
3107 DONE;
3108}")
3109(define_insn "fseldfdf4"
8e871c05
RK
3110 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
3111 (if_then_else:DF (ge (match_operand:DF 1 "gpc_reg_operand" "f")
3112 (const_int 0))
3113 (match_operand:DF 2 "gpc_reg_operand" "f")
3114 (match_operand:DF 3 "gpc_reg_operand" "f")))]
d14a6d05 3115 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT"
8e871c05
RK
3116 "fsel %0,%1,%2,%3"
3117 [(set_attr "type" "fp")])
94d7001a
RK
3118(define_insn "fselsfdf4"
3119 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
3120 (if_then_else:DF (ge (match_operand:SF 1 "gpc_reg_operand" "f")
3121 (const_int 0))
3122 (match_operand:DF 2 "gpc_reg_operand" "f")
3123 (match_operand:DF 3 "gpc_reg_operand" "f")))]
3124 "TARGET_PPC_GFXOPT"
3125 "fsel %0,%1,%2,%3"
3126 [(set_attr "type" "fp")])
1fd4e8c1
RK
3127\f
3128;; Conversions to and from floating-point.
3129(define_expand "floatsidf2"
3130 [(set (match_dup 2)
3131 (plus:DI (zero_extend:DI
cd2b37d9 3132 (xor:SI (match_operand:SI 1 "gpc_reg_operand" "")
1fd4e8c1
RK
3133 (match_dup 3)))
3134 (match_dup 4)))
cd2b37d9 3135 (set (match_operand:DF 0 "gpc_reg_operand" "")
1fd4e8c1
RK
3136 (minus:DF (subreg:DF (match_dup 2) 0)
3137 (match_dup 5)))]
dc4f83ca 3138 "! TARGET_POWERPC64 && TARGET_HARD_FLOAT"
1fd4e8c1
RK
3139 "
3140{
1fd4e8c1
RK
3141 operands[2] = gen_reg_rtx (DImode);
3142 operands[3] = gen_rtx (CONST_INT, VOIDmode, 0x80000000);
3143 operands[4] = immed_double_const (0, 0x43300000, DImode);
3144 operands[5] = force_reg (DFmode, immed_double_const (0x43300000,
3145 0x80000000, DFmode));
3146}")
3147
3148(define_expand "floatunssidf2"
3149 [(set (match_dup 2)
cd2b37d9 3150 (plus:DI (zero_extend:DI (match_operand:SI 1 "gpc_reg_operand" ""))
1fd4e8c1 3151 (match_dup 3)))
cd2b37d9 3152 (set (match_operand:DF 0 "gpc_reg_operand" "")
1fd4e8c1
RK
3153 (minus:DF (subreg:DF (match_dup 2) 0)
3154 (match_dup 4)))]
dc4f83ca 3155 "! TARGET_POWERPC64 && TARGET_HARD_FLOAT"
1fd4e8c1
RK
3156 "
3157{
1fd4e8c1
RK
3158 operands[2] = gen_reg_rtx (DImode);
3159 operands[3] = immed_double_const (0, 0x43300000, DImode);
3160 operands[4] = force_reg (DFmode, immed_double_const (0x43300000, 0, DFmode));
3161}")
3162
3163;; For the above two cases, we always split.
3164(define_split
cd2b37d9 3165 [(set (match_operand:DI 0 "gpc_reg_operand" "")
1fd4e8c1 3166 (plus:DI (zero_extend:DI
cd2b37d9 3167 (xor:SI (match_operand:SI 1 "gpc_reg_operand" "")
1fd4e8c1 3168 (match_operand:SI 2 "logical_operand" "")))
7a96832a
RK
3169 (match_operand:DI 3 "low_32_bit_operand" "")))]
3170 "reload_completed"
1fd4e8c1
RK
3171 [(set (match_dup 6) (xor:SI (match_dup 1) (match_dup 2)))
3172 (set (match_dup 4) (match_dup 5))]
3173 "
3174{ operands[4] = operand_subword (operands[0], 0, 0, DImode);
3175 operands[5] = operand_subword (operands[3], 0, 0, DImode);
3176 operands[6] = operand_subword (operands[0], 1, 0, DImode);
3177}")
3178
3179(define_insn ""
cd2b37d9 3180 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
1fd4e8c1 3181 (plus:DI (zero_extend:DI
cd2b37d9 3182 (xor:SI (match_operand:SI 1 "gpc_reg_operand" "%r")
1fd4e8c1 3183 (match_operand:SI 2 "logical_operand" "rKJ")))
7a96832a
RK
3184 (match_operand:DI 3 "low_32_bit_operand" "n")))]
3185 ""
baf97f86
RK
3186 "#"
3187 [(set_attr "length" "8")])
1fd4e8c1
RK
3188
3189(define_split
cd2b37d9
RK
3190 [(set (match_operand:DI 0 "gpc_reg_operand" "=")
3191 (plus:DI (zero_extend:DI (match_operand:SI 1 "gpc_reg_operand" ""))
7a96832a
RK
3192 (match_operand:DI 2 "low_32_bit_operand" "")))]
3193 "reload_completed"
1fd4e8c1
RK
3194 [(set (match_dup 3) (match_dup 4))
3195 (set (match_dup 5) (match_dup 1))]
3196 "
3197{ operands[3] = operand_subword (operands[0], 0, 0, DImode);
3198 operands[4] = operand_subword (operands[2], 0, 0, DImode);
3199 operands[5] = operand_subword (operands[0], 1, 0, DImode);
3200
3201 if (rtx_equal_p (operands[1], operands[5]))
3202 {
3203 emit_move_insn (operands[3], operands[4]);
3204 DONE;
3205 }
c283c989
RK
3206
3207 if (rtx_equal_p (operands[1], operands[3]))
3208 {
3209 rtx temp;
3210
3211 temp = operands[3]; operands[3] = operands[5]; operands[5] = temp;
3212 temp = operands[4]; operands[4] = operands[1]; operands[1] = temp;
3213 }
1fd4e8c1
RK
3214}")
3215
3216(define_insn ""
cd2b37d9
RK
3217 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3218 (plus:DI (zero_extend:DI (match_operand:SI 1 "gpc_reg_operand" "r"))
7a96832a
RK
3219 (match_operand:DI 2 "low_32_bit_operand" "n")))]
3220 ""
baf97f86
RK
3221 "#"
3222 [(set_attr "length" "8")])
1fd4e8c1
RK
3223
3224(define_expand "fix_truncdfsi2"
cd2b37d9 3225 [(set (match_operand:SI 0 "gpc_reg_operand" "")
b542afe9 3226 (fix:SI (match_operand:DF 1 "gpc_reg_operand" "")))]
d14a6d05 3227 "TARGET_HARD_FLOAT"
1fd4e8c1
RK
3228 "
3229{
8ffd9c51
RK
3230 if (TARGET_POWER2 || TARGET_POWERPC)
3231 {
425c176f
RK
3232 rtx stack_slot = assign_stack_temp (DImode, 8, 0),
3233 temp = gen_reg_rtx (DImode);
3234
8ffd9c51 3235 emit_insn (gen_fpcvtsi (temp, operands[1]));
8ffd9c51
RK
3236 emit_move_insn (stack_slot, temp);
3237 emit_move_insn (operands[0],
3238 operand_subword (stack_slot, 1, 0, DImode));
3239 DONE;
3240 }
3241 else
3242 {
3243 emit_insn (gen_trunc_call (operands[0], operands[1],
3244 gen_rtx (SYMBOL_REF, Pmode, RS6000_ITRUNC)));
3245 DONE;
3246 }
1fd4e8c1
RK
3247}")
3248
8ffd9c51
RK
3249(define_insn "fpcvtsi"
3250 [(set (match_operand:DI 0 "gpc_reg_operand" "=f")
3251 (sign_extend:DI
3252 (fix:SI (match_operand:DF 1 "gpc_reg_operand" "f"))))]
d14a6d05 3253 "(TARGET_POWER2 || TARGET_POWERPC) && TARGET_HARD_FLOAT"
8ffd9c51
RK
3254 "{fcirz|fctiwz} %0,%1"
3255 [(set_attr "type" "fp")])
deb9225a 3256
1fd4e8c1 3257(define_expand "fixuns_truncdfsi2"
cd2b37d9 3258 [(set (match_operand:SI 0 "gpc_reg_operand" "")
b542afe9 3259 (unsigned_fix:SI (match_operand:DF 1 "gpc_reg_operand" "")))]
d14a6d05 3260 "! TARGET_POWER2 && ! TARGET_POWERPC && TARGET_HARD_FLOAT"
1fd4e8c1
RK
3261 "
3262{
3263 emit_insn (gen_trunc_call (operands[0], operands[1],
3c64f04b 3264 gen_rtx (SYMBOL_REF, Pmode, RS6000_UITRUNC)));
1fd4e8c1
RK
3265 DONE;
3266}")
3267
1fd4e8c1
RK
3268(define_expand "trunc_call"
3269 [(parallel [(set (match_operand:SI 0 "" "")
b542afe9 3270 (fix:SI (match_operand:DF 1 "" "")))
1fd4e8c1 3271 (use (match_operand:SI 2 "" ""))])]
d14a6d05 3272 "TARGET_HARD_FLOAT"
1fd4e8c1
RK
3273 "
3274{
3275 rtx insns = gen_trunc_call_rtl (operands[0], operands[1], operands[2]);
3276 rtx first = XVECEXP (insns, 0, 0);
3277 rtx last = XVECEXP (insns, 0, XVECLEN (insns, 0) - 1);
3278
3279 REG_NOTES (first) = gen_rtx (INSN_LIST, REG_LIBCALL, last,
3280 REG_NOTES (first));
3281 REG_NOTES (last) = gen_rtx (INSN_LIST, REG_RETVAL, first, REG_NOTES (last));
3282
3283 emit_insn (insns);
3284 DONE;
3285}")
3286
3287(define_expand "trunc_call_rtl"
cd2b37d9 3288 [(set (reg:DF 33) (match_operand:DF 1 "gpc_reg_operand" ""))
1fd4e8c1
RK
3289 (use (reg:DF 33))
3290 (parallel [(set (reg:SI 3)
3291 (call (mem:SI (match_operand 2 "" "")) (const_int 0)))
3292 (clobber (scratch:SI))])
cd2b37d9 3293 (set (match_operand:SI 0 "gpc_reg_operand" "")
1fd4e8c1 3294 (reg:SI 3))]
d14a6d05 3295 "TARGET_HARD_FLOAT"
1fd4e8c1
RK
3296 "
3297{
3298 rs6000_trunc_used = 1;
3299}")
a473029f
RK
3300
3301(define_insn "floatdidf2"
3302 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
3303 (float:DF (match_operand:DI 1 "gpc_reg_operand" "f")))]
d14a6d05 3304 "TARGET_POWERPC64 && TARGET_HARD_FLOAT"
a473029f
RK
3305 "fcfid %0,%1"
3306 [(set_attr "type" "fp")])
3307
3308(define_insn "fix_truncdfdi2"
3309 [(set (match_operand:DI 0 "gpc_reg_operand" "=f")
3310 (fix:DI (match_operand:DF 1 "gpc_reg_operand" "f")))]
d14a6d05 3311 "TARGET_POWERPC64 && TARGET_HARD_FLOAT"
a473029f
RK
3312 "fctidz %0,%1"
3313 [(set_attr "type" "fp")])
1fd4e8c1
RK
3314\f
3315;; Define the DImode operations that can be done in a small number
3316;; of instructions.
ca7f5001
RK
3317(define_expand "adddi3"
3318 [(set (match_operand:DI 0 "gpc_reg_operand" "")
3319 (plus:DI (match_operand:DI 1 "gpc_reg_operand" "")
3320 (match_operand:DI 2 "reg_or_short_operand" "")))]
3321 ""
3322 "
3323{
51b8fc2c 3324 if (! TARGET_POWER && ! TARGET_POWERPC64
ca7f5001
RK
3325 && short_cint_operand (operands[2], DImode))
3326 FAIL;
3327}")
3328
3329(define_insn ""
fa5679bb
RK
3330 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
3331 (plus:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r")
3332 (match_operand:DI 2 "reg_or_short_operand" "r,I")))]
51b8fc2c 3333 "TARGET_POWER && ! TARGET_POWERPC64"
fa5679bb 3334 "@
ca7f5001
RK
3335 {a|addc} %L0,%L1,%L2\;{ae|adde} %0,%1,%2
3336 {ai|addic} %L0,%L1,%2\;{a%G2e|add%G2e} %0,%1"
b19003d8 3337 [(set_attr "length" "8")])
1fd4e8c1 3338
ca7f5001
RK
3339(define_insn ""
3340 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3341 (plus:DI (match_operand:DI 1 "gpc_reg_operand" "%r")
3342 (match_operand:DI 2 "gpc_reg_operand" "r")))]
51b8fc2c 3343 "! TARGET_POWER && ! TARGET_POWERPC64"
ca7f5001
RK
3344 "addc %L0,%L1,%L2\;adde %0,%1,%2"
3345 [(set_attr "length" "8")])
3346
3347(define_expand "subdi3"
fa5679bb
RK
3348 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
3349 (minus:DI (match_operand:DI 1 "reg_or_short_operand" "r,I")
3350 (match_operand:DI 2 "gpc_reg_operand" "r,r")))]
1fd4e8c1 3351 ""
ca7f5001
RK
3352 "
3353{
51b8fc2c 3354 if (! TARGET_POWER && ! TARGET_POWERPC64
ca7f5001
RK
3355 && short_cint_operand (operands[1], DImode))
3356 FAIL;
3357}")
3358
3359(define_insn ""
3360 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
3361 (minus:DI (match_operand:DI 1 "reg_or_short_operand" "r,I")
3362 (match_operand:DI 2 "gpc_reg_operand" "r,r")))]
51b8fc2c 3363 "TARGET_POWER && ! TARGET_POWERPC64"
fa5679bb 3364 "@
ca7f5001
RK
3365 {sf|subfc} %L0,%L2,%L1\;{sfe|subfe} %0,%2,%1
3366 {sfi|subfic} %L0,%L2,%1\;{sf%G1e|subf%G1e} %0,%2"
b19003d8 3367 [(set_attr "length" "8")])
1fd4e8c1 3368
ca7f5001
RK
3369(define_insn ""
3370 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3371 (minus:DI (match_operand:DI 1 "gpc_reg_operand" "r")
3372 (match_operand:DI 2 "gpc_reg_operand" "r")))]
51b8fc2c 3373 "! TARGET_POWER && ! TARGET_POWERPC64"
ca7f5001
RK
3374 "subfc %L0,%L2,%L1\;subfe %0,%2,%1"
3375 [(set_attr "length" "8")])
3376
3377(define_expand "negdi2"
cd2b37d9
RK
3378 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3379 (neg:DI (match_operand:DI 1 "gpc_reg_operand" "r")))]
1fd4e8c1 3380 ""
ca7f5001
RK
3381 "")
3382
3383(define_insn ""
3384 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3385 (neg:DI (match_operand:DI 1 "gpc_reg_operand" "r")))]
51b8fc2c 3386 "! TARGET_POWERPC64"
ca7f5001
RK
3387 "{sfi|subfic} %L0,%L1,0\;{sfze|subfze} %0,%1"
3388 [(set_attr "length" "8")])
3389
8ffd9c51
RK
3390(define_expand "mulsidi3"
3391 [(set (match_operand:DI 0 "gpc_reg_operand" "")
3392 (mult:DI (sign_extend:DI (match_operand:SI 1 "gpc_reg_operand" ""))
3393 (sign_extend:DI (match_operand:SI 2 "gpc_reg_operand" ""))))]
3394 ""
3395 "
3396{
3397 if (! TARGET_POWER && ! TARGET_POWERPC)
3398 {
3399 emit_move_insn (gen_rtx (REG, SImode, 3), operands[1]);
3400 emit_move_insn (gen_rtx (REG, SImode, 4), operands[2]);
3401 emit_insn (gen_mull_call ());
3402 emit_move_insn (operand_subword (operands[0], 0, 0, DImode),
3403 gen_rtx (REG, SImode, 3));
3404 emit_move_insn (operand_subword (operands[0], 1, 0, DImode),
3405 gen_rtx (REG, SImode, 4));
3406 DONE;
3407 }
3408 else if (TARGET_POWER)
3409 {
3410 emit_insn (gen_mulsidi3_mq (operands[0], operands[1], operands[2]));
3411 DONE;
3412 }
3413}")
deb9225a 3414
8ffd9c51 3415(define_insn "mulsidi3_mq"
cd2b37d9 3416 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
8ffd9c51 3417 (mult:DI (sign_extend:DI (match_operand:SI 1 "gpc_reg_operand" "%r"))
cd2b37d9 3418 (sign_extend:DI (match_operand:SI 2 "gpc_reg_operand" "r"))))
1fd4e8c1 3419 (clobber (match_scratch:SI 3 "=q"))]
ca7f5001 3420 "TARGET_POWER"
b19003d8 3421 "mul %0,%1,%2\;mfmq %L0"
8ffd9c51
RK
3422 [(set_attr "type" "imul")
3423 (set_attr "length" "8")])
deb9225a 3424
8ffd9c51 3425(define_insn ""
425c176f 3426 [(set (match_operand:DI 0 "gpc_reg_operand" "=&r")
8ffd9c51
RK
3427 (mult:DI (sign_extend:DI (match_operand:SI 1 "gpc_reg_operand" "%r"))
3428 (sign_extend:DI (match_operand:SI 2 "gpc_reg_operand" "r"))))]
425c176f 3429 "TARGET_POWERPC && ! TARGET_POWERPC64"
8ffd9c51
RK
3430 "mulhw %0,%1,%2\;mullw %L0,%1,%2"
3431 [(set_attr "type" "imul")
3432 (set_attr "length" "8")])
deb9225a 3433
8ffd9c51
RK
3434(define_expand "smulsi3_highpart"
3435 [(set (match_operand:SI 0 "gpc_reg_operand" "")
3436 (truncate:SI
3437 (lshiftrt:DI (mult:DI (sign_extend:DI
3438 (match_operand:SI 1 "gpc_reg_operand" "%r"))
3439 (sign_extend:DI
3440 (match_operand:SI 2 "gpc_reg_operand" "r")))
3441 (const_int 32))))]
3442 ""
3443 "
3444{
3445 if (! TARGET_POWER && ! TARGET_POWERPC)
3446 {
3447 emit_move_insn (gen_rtx (REG, SImode, 3), operands[1]);
3448 emit_move_insn (gen_rtx (REG, SImode, 4), operands[2]);
3449 emit_insn (gen_mulh_call ());
3450 emit_move_insn (operands[0], gen_rtx (REG, SImode, 3));
3451 DONE;
3452 }
3453 else if (TARGET_POWER)
3454 {
3455 emit_insn (gen_smulsi3_highpart_mq (operands[0], operands[1], operands[2]));
3456 DONE;
3457 }
3458}")
deb9225a 3459
8ffd9c51
RK
3460(define_insn "smulsi3_highpart_mq"
3461 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
3462 (truncate:SI
3463 (lshiftrt:DI (mult:DI (sign_extend:DI
3464 (match_operand:SI 1 "gpc_reg_operand" "%r"))
3465 (sign_extend:DI
3466 (match_operand:SI 2 "gpc_reg_operand" "r")))
3467 (const_int 32))))
3468 (clobber (match_scratch:SI 3 "=q"))]
3469 "TARGET_POWER"
3470 "mul %0,%1,%2"
3471 [(set_attr "type" "imul")])
deb9225a 3472
8ffd9c51
RK
3473(define_insn ""
3474 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
3475 (truncate:SI
3476 (lshiftrt:DI (mult:DI (sign_extend:DI
3477 (match_operand:SI 1 "gpc_reg_operand" "%r"))
3478 (sign_extend:DI
3479 (match_operand:SI 2 "gpc_reg_operand" "r")))
3480 (const_int 32))))]
3481 "TARGET_POWERPC"
3482 "mulhw %0,%1,%2"
3483 [(set_attr "type" "imul")])
deb9225a 3484
8ffd9c51
RK
3485(define_insn "umulsi3_highpart"
3486 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
3487 (truncate:SI
3488 (lshiftrt:DI (mult:DI (zero_extend:DI
3489 (match_operand:SI 1 "gpc_reg_operand" "%r"))
3490 (zero_extend:DI
3491 (match_operand:SI 2 "gpc_reg_operand" "r")))
3492 (const_int 32))))]
3493 "TARGET_POWERPC"
3494 "mulhwu %0,%1,%2"
3495 [(set_attr "type" "imul")])
1fd4e8c1
RK
3496
3497;; If operands 0 and 2 are in the same register, we have a problem. But
3498;; operands 0 and 1 (the usual case) can be in the same register. That's
3499;; why we have the strange constraints below.
3500(define_insn "ashldi3"
cd2b37d9
RK
3501 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,&r")
3502 (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,0,r")
1fd4e8c1
RK
3503 (match_operand:SI 2 "reg_or_cint_operand" "M,i,r,r")))
3504 (clobber (match_scratch:SI 3 "=X,q,q,q"))]
ca7f5001 3505 "TARGET_POWER"
1fd4e8c1 3506 "@
ca7f5001 3507 {sli|slwi} %0,%L1,%h2\;{cal %L0,0(0)|li %L0,0}
1fd4e8c1
RK
3508 sl%I2q %L0,%L1,%h2\;sll%I2q %0,%1,%h2
3509 sl%I2q %L0,%L1,%h2\;sll%I2q %0,%1,%h2
b19003d8
RK
3510 sl%I2q %L0,%L1,%h2\;sll%I2q %0,%1,%h2"
3511 [(set_attr "length" "8")])
1fd4e8c1
RK
3512
3513(define_insn "lshrdi3"
cd2b37d9
RK
3514 [(set (match_operand:DI 0 "gpc_reg_operand" "=&r,r,r,&r")
3515 (lshiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,0,r")
1fd4e8c1
RK
3516 (match_operand:SI 2 "reg_or_cint_operand" "M,i,r,r")))
3517 (clobber (match_scratch:SI 3 "=X,q,q,q"))]
ca7f5001 3518 "TARGET_POWER"
1fd4e8c1 3519 "@
ca7f5001 3520 {cal %0,0(0)|li %0,0}\;{s%A2i|s%A2wi} %L0,%1,%h2
46a48c7f
RK
3521 sr%I2q %0,%1,%h2\;srl%I2q %L0,%L1,%h2
3522 sr%I2q %0,%1,%h2\;srl%I2q %L0,%L1,%h2
b19003d8
RK
3523 sr%I2q %0,%1,%h2\;srl%I2q %L0,%L1,%h2"
3524 [(set_attr "length" "8")])
1fd4e8c1
RK
3525
3526;; Shift by a variable amount is too complex to be worth open-coding. We
3527;; just handle shifts by constants.
3528
3529(define_expand "ashrdi3"
a473029f 3530 [(parallel [(set (match_operand:DI 0 "gpc_reg_operand" "")
2bee0449
RK
3531 (ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "")
3532 (match_operand:SI 2 "general_operand" "")))
3533 (clobber (match_scratch:SI 3 ""))])]
3534 "TARGET_POWER"
1fd4e8c1 3535 "
2bee0449 3536{ if (GET_CODE (operands[2]) != CONST_INT)
1fd4e8c1
RK
3537 FAIL;
3538}")
3539
2bee0449 3540(define_insn ""
cd2b37d9
RK
3541 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
3542 (ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
1fd4e8c1
RK
3543 (match_operand:SI 2 "const_int_operand" "M,i")))
3544 (clobber (match_scratch:SI 3 "=X,q"))]
ca7f5001 3545 "TARGET_POWER"
1fd4e8c1 3546 "@
ca7f5001 3547 {srai|srawi} %0,%1,31\;{srai|srawi} %L0,%1,%h2
b19003d8
RK
3548 sraiq %0,%1,%h2\;srliq %L0,%L1,%h2"
3549 [(set_attr "length" "8")])
1fd4e8c1 3550\f
a473029f
RK
3551;; PowerPC64 DImode operations.
3552
3553(define_insn "ffsdi2"
242e8072
RK
3554 [(set (match_operand:DI 0 "gpc_reg_operand" "=&r")
3555 (ffs:DI (match_operand:DI 1 "gpc_reg_operand" "r")))]
a473029f
RK
3556 "TARGET_POWERPC64"
3557 "neg %0,%1\;and %0,%0,%1\;cntlzd %0,%0\;subfic %0,%0,64"
3558 [(set_attr "length" "16")])
3559
3560(define_insn "muldi3"
3561 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3562 (mult:DI (match_operand:DI 1 "gpc_reg_operand" "%r")
f63184ac 3563 (match_operand:DI 2 "gpc_reg_operand" "r")))]
a473029f
RK
3564 "TARGET_POWERPC64"
3565 "mulld %0,%1,%2"
3566 [(set_attr "type" "imul")])
3567
3568(define_insn "smuldi3_highpart"
3569 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3570 (truncate:DI
3571 (lshiftrt:TI (mult:TI (sign_extend:TI
3572 (match_operand:DI 1 "gpc_reg_operand" "%r"))
3573 (sign_extend:TI
3574 (match_operand:DI 2 "gpc_reg_operand" "r")))
3575 (const_int 64))))]
3576 "TARGET_POWERPC64"
3577 "mulhd %0,%1,%2"
3578 [(set_attr "type" "imul")])
3579
3580(define_insn "umuldi3_highpart"
3581 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3582 (truncate:DI
3583 (lshiftrt:TI (mult:TI (zero_extend:TI
3584 (match_operand:DI 1 "gpc_reg_operand" "%r"))
3585 (zero_extend:TI
3586 (match_operand:DI 2 "gpc_reg_operand" "r")))
3587 (const_int 64))))]
3588 "TARGET_POWERPC64"
3589 "mulhdu %0,%1,%2"
3590 [(set_attr "type" "imul")])
3591
3592(define_insn "divdi3"
3593 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3594 (div:DI (match_operand:DI 1 "gpc_reg_operand" "r")
3595 (match_operand:DI 2 "gpc_reg_operand" "r")))]
3596 "TARGET_POWERPC64"
3597 "divd %0,%1,%2"
3598 [(set_attr "type" "idiv")])
3599
3600(define_insn "udivdi3"
3601 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3602 (udiv:DI (match_operand:DI 1 "gpc_reg_operand" "r")
3603 (match_operand:DI 2 "gpc_reg_operand" "r")))]
3604 "TARGET_POWERPC64"
3605 "divdu %0,%1,%2"
3606 [(set_attr "type" "idiv")])
3607
3608(define_insn "rotldi3"
3609 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3610 (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r")
3611 (match_operand:DI 2 "reg_or_cint_operand" "ri")))]
3612 "TARGET_POWERPC64"
3613 "rld%I2cl %0,%1,%h2,0")
3614
3615(define_insn ""
3616 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
3617 (compare:CC (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r")
3618 (match_operand:DI 2 "reg_or_cint_operand" "ri"))
3619 (const_int 0)))
3620 (clobber (match_scratch:DI 3 "=r"))]
3621 "TARGET_POWERPC64"
3622 "rld%I2cl. %3,%1,%h2,0"
3623 [(set_attr "type" "delayed_compare")])
3624
3625(define_insn ""
3626 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
3627 (compare:CC (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r")
3628 (match_operand:DI 2 "reg_or_cint_operand" "ri"))
3629 (const_int 0)))
3630 (set (match_operand:DI 0 "gpc_reg_operand" "=r")
3631 (rotate:DI (match_dup 1) (match_dup 2)))]
3632 "TARGET_POWERPC64"
3633 "rld%I2cl. %0,%1,%h2,0"
3634 [(set_attr "type" "delayed_compare")])
3635\f
1fd4e8c1
RK
3636;; Now define ways of moving data around.
3637;;
3638;; For SI, we special-case integers that can't be loaded in one insn. We
3639;; do the load 16-bits at a time. We could do this by loading from memory,
3640;; and this is even supposed to be faster, but it is simpler not to get
3641;; integers in the TOC.
3642(define_expand "movsi"
3643 [(set (match_operand:SI 0 "general_operand" "")
3644 (match_operand:SI 1 "any_operand" ""))]
3645 ""
3646 "
3647{
3648 if (GET_CODE (operands[0]) != REG)
3649 operands[1] = force_reg (SImode, operands[1]);
3650
78b8d850
RK
3651 if (CONSTANT_P (operands[1]) && GET_CODE (operands[1]) != CONST_INT
3652 && ! LEGITIMATE_CONSTANT_POOL_ADDRESS_P (operands[1]))
b45863ec 3653 {
30a4619d
RK
3654 /* If we are to limit the number of things we put in the TOC and
3655 this is a symbol plus a constant we can add in one insn,
3656 just put the sumbol in the TOC and add the constant. Don't do
3657 this if reload is in progress. */
3658 if (GET_CODE (operands[1]) == CONST
3659 && TARGET_NO_SUM_IN_TOC && ! reload_in_progress
3660 && GET_CODE (XEXP (operands[1], 0)) == PLUS
3661 && add_operand (XEXP (XEXP (operands[1], 0), 1), SImode)
3662 && (GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == LABEL_REF
3663 || GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == SYMBOL_REF)
3664 && ! side_effects_p (operands[0]))
3665 {
3666 rtx sym = force_const_mem (SImode, XEXP (XEXP (operands[1], 0), 0));
3667 rtx other = XEXP (XEXP (operands[1], 0), 1);
3668
3669 emit_insn (gen_addsi3 (operands[0], force_reg (SImode, sym), other));
3670 DONE;
3671 }
3672
b45863ec
RK
3673 operands[1] = force_const_mem (SImode, operands[1]);
3674 if (! memory_address_p (SImode, XEXP (operands[1], 0))
3675 && ! reload_in_progress)
3676 operands[1] = change_address (operands[1], SImode,
3677 XEXP (operands[1], 0));
3678 }
1fd4e8c1
RK
3679
3680 if (GET_CODE (operands[1]) == CONST_INT
3681 && (unsigned) (INTVAL (operands[1]) + 0x8000) >= 0x10000
3682 && (INTVAL (operands[1]) & 0xffff) != 0)
3683 {
3684 emit_move_insn (operands[0],
3685 gen_rtx (CONST_INT, VOIDmode,
3686 INTVAL (operands[1]) & 0xffff0000));
3687 emit_insn (gen_iorsi3 (operands[0], operands[0],
3688 gen_rtx (CONST_INT, VOIDmode,
3689 INTVAL (operands[1]) & 0xffff)));
3690 DONE;
3691 }
3692}")
3693
3694(define_insn ""
015183c6
RK
3695 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,m,r,r,r,r,*q,*c*l,*h")
3696 (match_operand:SI 1 "input_operand" "r,m,r,I,J,R,*h,r,r,0"))]
19d5775a
RK
3697 "gpc_reg_operand (operands[0], SImode)
3698 || gpc_reg_operand (operands[1], SImode)"
1fd4e8c1 3699 "@
deb9225a 3700 mr %0,%1
ca7f5001
RK
3701 {l%U1%X1|lwz%U1%X1} %0,%1
3702 {st%U0%X0|stw%U0%X0} %1,%0
19d5775a
RK
3703 {lil|li} %0,%1
3704 {liu|lis} %0,%u1
57fa6739 3705 {cal|la} %0,%1(%*)
1fd4e8c1 3706 mf%1 %0
5c23c401 3707 mt%0 %1
e76e75bb
RK
3708 mt%0 %1
3709 cror 0,0,0"
015183c6 3710 [(set_attr "type" "*,load,*,*,*,*,*,*,mtjmpr,*")])
1fd4e8c1 3711
77fa0940
RK
3712;; Split a load of a large constant into the appropriate two-insn
3713;; sequence.
3714
3715(define_split
3716 [(set (match_operand:SI 0 "gpc_reg_operand" "")
3717 (match_operand:SI 1 "const_int_operand" ""))]
3718 "(unsigned) (INTVAL (operands[1]) + 0x8000) >= 0x10000
3719 && (INTVAL (operands[1]) & 0xffff) != 0"
3720 [(set (match_dup 0)
3721 (match_dup 2))
3722 (set (match_dup 0)
3723 (ior:SI (match_dup 0)
3724 (match_dup 3)))]
3725 "
3726{
3727 operands[2] = gen_rtx (CONST_INT, VOIDmode,
3728 INTVAL (operands[1]) & 0xffff0000);
3729 operands[3] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[1]) & 0xffff);
3730}")
3731
1fd4e8c1
RK
3732(define_insn ""
3733 [(set (match_operand:CC 2 "cc_reg_operand" "=x")
cd2b37d9 3734 (compare:CC (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 3735 (const_int 0)))
cd2b37d9 3736 (set (match_operand:SI 0 "gpc_reg_operand" "=r") (match_dup 1))]
1fd4e8c1 3737 ""
deb9225a 3738 "mr. %0,%1"
1fd4e8c1
RK
3739 [(set_attr "type" "compare")])
3740\f
3741(define_expand "movhi"
3742 [(set (match_operand:HI 0 "general_operand" "")
3743 (match_operand:HI 1 "any_operand" ""))]
3744 ""
3745 "
3746{
3747 if (GET_CODE (operands[0]) != REG)
3748 operands[1] = force_reg (HImode, operands[1]);
3749
3750 if (CONSTANT_P (operands[1]) && GET_CODE (operands[1]) != CONST_INT)
b45863ec
RK
3751 {
3752 operands[1] = force_const_mem (HImode, operands[1]);
3753 if (! memory_address_p (HImode, XEXP (operands[1], 0))
3754 && ! reload_in_progress)
3755 operands[1] = change_address (operands[1], HImode,
3756 XEXP (operands[1], 0));
3757 }
1fd4e8c1
RK
3758}")
3759
3760(define_insn ""
fb81d7ce
RK
3761 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,m,r,r,*q,*c*l,*h")
3762 (match_operand:HI 1 "input_operand" "r,m,r,i,*h,r,r,0"))]
19d5775a
RK
3763 "gpc_reg_operand (operands[0], HImode)
3764 || gpc_reg_operand (operands[1], HImode)"
1fd4e8c1 3765 "@
deb9225a 3766 mr %0,%1
1fd4e8c1
RK
3767 lhz%U1%X1 %0,%1
3768 sth%U0%X0 %1,%0
19d5775a 3769 {lil|li} %0,%w1
1fd4e8c1 3770 mf%1 %0
e76e75bb 3771 mt%0 %1
fb81d7ce 3772 mt%0 %1
e76e75bb 3773 cror 0,0,0"
fb81d7ce 3774 [(set_attr "type" "*,load,*,*,*,*,mtjmpr,*")])
1fd4e8c1
RK
3775
3776(define_expand "movqi"
3777 [(set (match_operand:QI 0 "general_operand" "")
3778 (match_operand:QI 1 "any_operand" ""))]
3779 ""
3780 "
3781{
3782 if (GET_CODE (operands[0]) != REG)
3783 operands[1] = force_reg (QImode, operands[1]);
3784
3785 if (CONSTANT_P (operands[1]) && GET_CODE (operands[1]) != CONST_INT)
b45863ec
RK
3786 {
3787 operands[1] = force_const_mem (QImode, operands[1]);
3788 if (! memory_address_p (QImode, XEXP (operands[1], 0))
3789 && ! reload_in_progress)
3790 operands[1] = change_address (operands[1], QImode,
3791 XEXP (operands[1], 0));
3792 }
1fd4e8c1
RK
3793}")
3794
3795(define_insn ""
fb81d7ce
RK
3796 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m,r,r,*q,*c*l,*h")
3797 (match_operand:QI 1 "input_operand" "r,m,r,i,*h,r,r,0"))]
19d5775a
RK
3798 "gpc_reg_operand (operands[0], QImode)
3799 || gpc_reg_operand (operands[1], QImode)"
1fd4e8c1 3800 "@
deb9225a 3801 mr %0,%1
1fd4e8c1
RK
3802 lbz%U1%X1 %0,%1
3803 stb%U0%X0 %1,%0
19d5775a 3804 {lil|li} %0,%1
1fd4e8c1 3805 mf%1 %0
e76e75bb 3806 mt%0 %1
fb81d7ce 3807 mt%0 %1
e76e75bb 3808 cror 0,0,0"
fb81d7ce 3809 [(set_attr "type" "*,load,*,*,*,*,mtjmpr,*")])
1fd4e8c1
RK
3810\f
3811;; Here is how to move condition codes around. When we store CC data in
3812;; an integer register or memory, we store just the high-order 4 bits.
3813;; This lets us not shift in the most common case of CR0.
3814(define_expand "movcc"
3815 [(set (match_operand:CC 0 "nonimmediate_operand" "")
3816 (match_operand:CC 1 "nonimmediate_operand" ""))]
3817 ""
3818 "")
3819
3820(define_insn ""
3821 [(set (match_operand:CC 0 "nonimmediate_operand" "=y,x,y,r,r,r,r,m")
3822 (match_operand:CC 1 "nonimmediate_operand" "y,r,r,x,y,r,m,r"))]
3823 "register_operand (operands[0], CCmode)
3824 || register_operand (operands[1], CCmode)"
3825 "@
3826 mcrf %0,%1
3827 mtcrf 128,%1
ca7f5001 3828 {rlinm|rlwinm} %1,%1,%F0,0xffffffff\;mtcrf %R0,%1\;{rlinm|rlwinm} %1,%1,%f0,0xffffffff
1fd4e8c1 3829 mfcr %0
ca7f5001 3830 mfcr %0\;{rlinm|rlwinm} %0,%0,%f1,0xf0000000
deb9225a 3831 mr %0,%1
ca7f5001
RK
3832 {l%U1%X1|lwz%U1%X1} %0,%1
3833 {st%U0%U1|stw%U0%U1} %1,%0"
b19003d8
RK
3834 [(set_attr "type" "*,*,*,compare,*,*,load,*")
3835 (set_attr "length" "*,*,12,*,8,*,*,*")])
1fd4e8c1
RK
3836\f
3837;; For floating-point, we normally deal with the floating-point registers.
3838;; The sole exception is that parameter passing can produce floating-point
3839;; values in fixed-point registers. Unless the value is a simple constant
3840;; or already in memory, we deal with this by allocating memory and copying
3841;; the value explicitly via that memory location.
3842(define_expand "movsf"
3843 [(set (match_operand:SF 0 "nonimmediate_operand" "")
3844 (match_operand:SF 1 "any_operand" ""))]
3845 ""
3846 "
3847{
3848 /* If we are called from reload, we might be getting a SUBREG of a hard
3849 reg. So expand it. */
3850 if (GET_CODE (operands[0]) == SUBREG
3851 && GET_CODE (SUBREG_REG (operands[0])) == REG
3852 && REGNO (SUBREG_REG (operands[0])) < FIRST_PSEUDO_REGISTER)
3853 operands[0] = alter_subreg (operands[0]);
3854 if (GET_CODE (operands[1]) == SUBREG
3855 && GET_CODE (SUBREG_REG (operands[1])) == REG
3856 && REGNO (SUBREG_REG (operands[1])) < FIRST_PSEUDO_REGISTER)
3857 operands[1] = alter_subreg (operands[1]);
3858
785e6a26 3859 if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) < 32)
1fd4e8c1 3860 {
785e6a26
RK
3861 /* If this is a store to memory or another integer register do the
3862 move directly. Otherwise store to a temporary stack slot and
3863 load from there into a floating point register. */
3864
1fd4e8c1
RK
3865 if (GET_CODE (operands[0]) == MEM
3866 || (GET_CODE (operands[0]) == REG
3867 && (REGNO (operands[0]) < 32
785e6a26
RK
3868 || (reload_in_progress
3869 && REGNO (operands[0]) >= FIRST_PSEUDO_REGISTER))))
1fd4e8c1
RK
3870 {
3871 emit_move_insn (operand_subword (operands[0], 0, 0, SFmode),
3872 operand_subword (operands[1], 0, 0, SFmode));
3873 DONE;
3874 }
f6ba0600
RK
3875 else
3876 {
3877 rtx stack_slot = assign_stack_temp (SFmode, 4, 0);
1fd4e8c1 3878
f6ba0600
RK
3879 emit_move_insn (stack_slot, operands[1]);
3880 emit_move_insn (operands[0], stack_slot);
3881 DONE;
3882 }
1fd4e8c1
RK
3883 }
3884
3885 if (GET_CODE (operands[0]) == MEM)
85fff2f3 3886 {
f2974b07
RK
3887 /* If operands[1] is a register, it may have double-precision data
3888 in it, so truncate it to single precision. We need not do
3889 this for POWERPC. */
3890 if (! TARGET_POWERPC && GET_CODE (operands[1]) == REG)
3891 {
3892 rtx newreg = reload_in_progress ? operands[1] : gen_reg_rtx (SFmode);
3893 emit_insn (gen_truncdfsf2 (newreg,
85fff2f3 3894 gen_rtx (SUBREG, DFmode, operands[1], 0)));
f2974b07
RK
3895 operands[1] = newreg;
3896 }
3897
3898 operands[1] = force_reg (SFmode, operands[1]);
85fff2f3 3899 }
1fd4e8c1
RK
3900
3901 if (GET_CODE (operands[0]) == REG && REGNO (operands[0]) < 32)
3902 {
1fd4e8c1
RK
3903 if (GET_CODE (operands[1]) == MEM
3904#if HOST_FLOAT_FORMAT == TARGET_FLOAT_FORMAT && ! defined(REAL_IS_NOT_DOUBLE)
3905 || GET_CODE (operands[1]) == CONST_DOUBLE
3906#endif
8ffd9c51
RK
3907 || (GET_CODE (operands[1]) == REG
3908 && (REGNO (operands[1]) < 32
3909 || (reload_in_progress
3910 && REGNO (operands[1]) >= FIRST_PSEUDO_REGISTER))))
1fd4e8c1
RK
3911 {
3912 emit_move_insn (operand_subword (operands[0], 0, 0, SFmode),
3913 operand_subword (operands[1], 0, 0, SFmode));
3914 DONE;
3915 }
f6ba0600
RK
3916 else
3917 {
3918 rtx stack_slot = assign_stack_temp (SFmode, 4, 0);
1fd4e8c1 3919
f6ba0600
RK
3920 emit_move_insn (stack_slot, operands[1]);
3921 emit_move_insn (operands[0], stack_slot);
3922 DONE;
3923 }
1fd4e8c1
RK
3924 }
3925
3926 if (CONSTANT_P (operands[1]))
3927 {
3928 operands[1] = force_const_mem (SFmode, operands[1]);
3929 if (! memory_address_p (SFmode, XEXP (operands[1], 0))
3930 && ! reload_in_progress)
3931 operands[1] = change_address (operands[1], SFmode,
3932 XEXP (operands[1], 0));
3933 }
3934}")
3935
1fd4e8c1 3936(define_split
cd2b37d9 3937 [(set (match_operand:SF 0 "gpc_reg_operand" "")
1fd4e8c1
RK
3938 (match_operand:SF 1 "easy_fp_constant" ""))]
3939 "reload_completed && REGNO (operands[0]) <= 31"
3940 [(set (match_dup 2) (match_dup 3))]
3941 "
3942{ operands[2] = operand_subword (operands[0], 0, 0, SFmode);
3943 operands[3] = operand_subword (operands[1], 0, 0, SFmode); }")
3944
3945(define_insn ""
3946 [(set (match_operand:SF 0 "fp_reg_or_mem_operand" "=f,f,m")
3947 (match_operand:SF 1 "input_operand" "f,m,f"))]
d14a6d05
MM
3948 "(gpc_reg_operand (operands[0], SFmode)
3949 || gpc_reg_operand (operands[1], SFmode)) && TARGET_HARD_FLOAT"
1fd4e8c1
RK
3950 "@
3951 fmr %0,%1
3952 lfs%U1%X1 %0,%1
85fff2f3 3953 stfs%U0%X0 %1,%0"
19d5775a 3954 [(set_attr "type" "fp,fpload,*")])
d14a6d05
MM
3955
3956(define_insn ""
3957 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m,r,r,r")
3958 (match_operand:SF 1 "input_operand" "r,m,r,I,J,R"))]
3959 "(gpc_reg_operand (operands[0], SFmode)
3960 || gpc_reg_operand (operands[1], SFmode)) && TARGET_SOFT_FLOAT"
3961 "@
3962 mr %0,%1
3963 {l%U1%X1|lwz%U1%X1} %0,%1
3964 {st%U0%X0|stw%U0%X0} %1,%0
3965 {lil|li} %0,%1
3966 {liu|lis} %0,%u1
3967 {cal|la} %0,%1(%*)"
3968 [(set_attr "type" "*,load,*,*,*,*")])
3969
1fd4e8c1
RK
3970\f
3971(define_expand "movdf"
3972 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3973 (match_operand:DF 1 "any_operand" ""))]
3974 ""
3975 "
3976{
e7113111 3977 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1fd4e8c1 3978 {
e7113111
RK
3979 emit_move_insn (operand_subword (operands[0], 1, 1, DFmode),
3980 operand_subword_force (operands[1], 1, DFmode));
3981 emit_move_insn (operand_subword (operands[0], 0, 1, DFmode),
3982 operand_subword_force (operands[1], 0, DFmode));
1fd4e8c1
RK
3983 DONE;
3984 }
3985
e7113111
RK
3986 if (GET_CODE (operands[0]) != REG)
3987 operands[1] = force_reg (DFmode, operands[1]);
1fd4e8c1 3988
e7113111 3989 if (CONSTANT_P (operands[1]) && ! easy_fp_constant (operands[1], DFmode))
1fd4e8c1
RK
3990 {
3991 operands[1] = force_const_mem (DFmode, operands[1]);
3992 if (! memory_address_p (DFmode, XEXP (operands[1], 0))
3993 && ! reload_in_progress)
3994 operands[1] = change_address (operands[1], DFmode,
3995 XEXP (operands[1], 0));
3996 }
e7113111 3997}")
1fd4e8c1
RK
3998
3999(define_split
cd2b37d9 4000 [(set (match_operand:DF 0 "gpc_reg_operand" "")
1fd4e8c1
RK
4001 (match_operand:DF 1 "easy_fp_constant" ""))]
4002 "reload_completed && REGNO (operands[0]) <= 31"
4003 [(set (match_dup 2) (match_dup 3))
4004 (set (match_dup 4) (match_dup 5))]
4005 "
4006{ operands[2] = operand_subword (operands[0], 0, 0, DFmode);
4007 operands[3] = operand_subword (operands[1], 0, 0, DFmode);
4008 operands[4] = operand_subword (operands[0], 1, 0, DFmode);
4009 operands[5] = operand_subword (operands[1], 1, 0, DFmode); }")
e7113111 4010
4eae5fe1
RK
4011;; Don't have reload use general registers to load a constant. First,
4012;; it might not work if the output operand has is the equivalent of
4013;; a non-offsettable memref, but also it is less efficient than loading
4014;; the constant into an FP register, since it will probably be used there.
4015;; The "??" is a kludge until we can figure out a more reasonable way
4016;; of handling these non-offsettable values.
4017(define_insn ""
4018 [(set (match_operand:DF 0 "nonimmediate_operand" "=!r,??r,o,!r,f,f,m")
e7113111 4019 (match_operand:DF 1 "input_operand" "r,o,r,G,f,m,f"))]
dc4f83ca
MM
4020 "! TARGET_POWERPC64 && TARGET_HARD_FLOAT
4021 && (register_operand (operands[0], DFmode)
4022 || register_operand (operands[1], DFmode))"
e7113111
RK
4023 "*
4024{
4025 switch (which_alternative)
4026 {
4027 case 0:
4028 /* We normally copy the low-numbered register first. However, if
4029 the first register operand 0 is the same as the second register of
4030 operand 1, we must copy in the opposite order. */
4031 if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
deb9225a 4032 return \"mr %L0,%L1\;mr %0,%1\";
e7113111 4033 else
deb9225a 4034 return \"mr %0,%1\;mr %L0,%L1\";
e7113111
RK
4035 case 1:
4036 /* If the low-address word is used in the address, we must load it
4037 last. Otherwise, load it first. Note that we cannot have
4038 auto-increment in that case since the address register is known to be
4039 dead. */
4040 if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
4041 operands [1], 0))
ca7f5001 4042 return \"{l|lwz} %L0,%L1\;{l|lwz} %0,%1\";
e7113111 4043 else
ca7f5001 4044 return \"{l%U1|lwz%U1} %0,%1\;{l|lwz} %L0,%L1\";
e7113111 4045 case 2:
ca7f5001 4046 return \"{st%U0|stw%U0} %1,%0\;{st|stw} %L1,%L0\";
e7113111
RK
4047 case 3:
4048 return \"#\";
4049 case 4:
4050 return \"fmr %0,%1\";
4051 case 5:
4052 return \"lfd%U1%X1 %0,%1\";
4053 case 6:
4054 return \"stfd%U0%X0 %1,%0\";
4055 }
4056}"
ca7f5001 4057 [(set_attr "type" "*,load,*,*,fp,fpload,*")
e7113111 4058 (set_attr "length" "8,8,8,8,*,*,*")])
51b8fc2c 4059
dc4f83ca
MM
4060(define_insn ""
4061 [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,o,r")
4062 (match_operand:DF 1 "input_operand" "r,o,r,G"))]
4063 "! TARGET_POWERPC64 && TARGET_SOFT_FLOAT
4064 && (register_operand (operands[0], DFmode)
4065 || register_operand (operands[1], DFmode))"
4066 "*
4067{
4068 switch (which_alternative)
4069 {
4070 case 0:
4071 /* We normally copy the low-numbered register first. However, if
4072 the first register operand 0 is the same as the second register of
4073 operand 1, we must copy in the opposite order. */
4074 if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
4075 return \"mr %L0,%L1\;mr %0,%1\";
4076 else
4077 return \"mr %0,%1\;mr %L0,%L1\";
4078 case 1:
4079 /* If the low-address word is used in the address, we must load it
4080 last. Otherwise, load it first. Note that we cannot have
4081 auto-increment in that case since the address register is known to be
4082 dead. */
4083 if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
4084 operands [1], 0))
4085 return \"{l|lwz} %L0,%L1\;{l|lwz} %0,%1\";
4086 else
4087 return \"{l%U1|lwz%U1} %0,%1\;{l|lwz} %L0,%L1\";
4088 case 2:
4089 return \"{st%U0|stw%U0} %1,%0\;{st|stw} %L1,%L0\";
4090 case 3:
4091 return \"#\";
4092 }
4093}"
4094 [(set_attr "type" "*,load,*,*")
4095 (set_attr "length" "8,8,8,8")])
4096
51b8fc2c
RK
4097(define_insn ""
4098 [(set (match_operand:DF 0 "nonimmediate_operand" "=!r,??r,o,!r,f,f,m")
4099 (match_operand:DF 1 "input_operand" "r,o,r,G,f,m,f"))]
dc4f83ca
MM
4100 "TARGET_POWERPC64 && TARGET_HARD_FLOAT
4101 && (register_operand (operands[0], DFmode)
4102 || register_operand (operands[1], DFmode))"
51b8fc2c 4103 "@
3d5570cb
RK
4104 mr %0,%1
4105 ld%U1%X1 %0,%1
4106 sd%U0%X0 %1,%0
4107 #
4108 fmr %0,%1
f63184ac 4109 lfd%U1%X1 %0,%1
3d5570cb 4110 stfd%U0%X0 %1,%0"
51b8fc2c 4111 [(set_attr "type" "*,load,*,*,fp,fpload,*")])
dc4f83ca
MM
4112
4113(define_insn ""
4114 [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,o,r")
4115 (match_operand:DF 1 "input_operand" "r,o,r,G"))]
4116 "TARGET_POWERPC64 && TARGET_SOFT_FLOAT
4117 && (register_operand (operands[0], DFmode)
4118 || register_operand (operands[1], DFmode))"
4119 "@
4120 mr %0,%1
4121 ld%U1%X1 %0,%1
4122 sd%U0%X0 %1,%0
4123 #"
4124 [(set_attr "type" "*,load,*,*")])
1fd4e8c1
RK
4125\f
4126;; Next come the multi-word integer load and store and the load and store
4127;; multiple insns.
4128(define_expand "movdi"
4129 [(set (match_operand:DI 0 "general_operand" "")
4130 (match_operand:DI 1 "general_operand" ""))]
4131 ""
4132 "
4133{
062284d8
RK
4134 if (GET_CODE (operands[1]) == CONST_DOUBLE
4135 || GET_CODE (operands[1]) == CONST_INT)
1fd4e8c1
RK
4136 {
4137 emit_move_insn (operand_subword (operands[0], 0, 0, DImode),
4138 operand_subword (operands[1], 0, 0, DImode));
4139 emit_move_insn (operand_subword (operands[0], 1, 0, DImode),
4140 operand_subword (operands[1], 1, 0, DImode));
4141 DONE;
4142 }
062284d8
RK
4143
4144 if (GET_CODE (operands[0]) == MEM)
4145 operands[1] = force_reg (DImode, operands[1]);
a473029f
RK
4146
4147 /* Stores between FPR and any non-FPR registers must go through a
4148 temporary stack slot. */
4149
4150 if (GET_CODE (operands[0]) == REG && GET_CODE (operands[1]) == REG
4151 && ((FP_REGNO_P (REGNO (operands[0]))
4152 && ! FP_REGNO_P (REGNO (operands[1])))
4153 || (FP_REGNO_P (REGNO (operands[1]))
4154 && ! FP_REGNO_P (REGNO (operands[0])))))
4155 {
425c176f 4156 rtx stack_slot = assign_stack_temp (DImode, 8, 0);
a473029f 4157
a473029f
RK
4158 emit_move_insn (stack_slot, operands[1]);
4159 emit_move_insn (operands[0], stack_slot);
4160 DONE;
4161 }
1fd4e8c1
RK
4162}")
4163
4164(define_insn ""
8ffd9c51
RK
4165 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m,f,f,m")
4166 (match_operand:DI 1 "input_operand" "r,m,r,f,m,f"))]
51b8fc2c
RK
4167 "! TARGET_POWERPC64 && (gpc_reg_operand (operands[0], DImode)
4168 || gpc_reg_operand (operands[1], DImode))"
1fd4e8c1
RK
4169 "*
4170{
4171 switch (which_alternative)
4172 {
4173 case 0:
4174 /* We normally copy the low-numbered register first. However, if
4175 the first register operand 0 is the same as the second register of
4176 operand 1, we must copy in the opposite order. */
4177 if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
deb9225a 4178 return \"mr %L0,%L1\;mr %0,%1\";
1fd4e8c1 4179 else
deb9225a 4180 return \"mr %0,%1\;mr %L0,%L1\";
1fd4e8c1
RK
4181 case 1:
4182 /* If the low-address word is used in the address, we must load it
4183 last. Otherwise, load it first. Note that we cannot have
4184 auto-increment in that case since the address register is known to be
4185 dead. */
4186 if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
4187 operands [1], 0))
ca7f5001 4188 return \"{l|lwz} %L0,%L1\;{l|lwz} %0,%1\";
1fd4e8c1 4189 else
ca7f5001 4190 return \"{l%U1|lwz%U1} %0,%1\;{l|lwz} %L0,%L1\";
1fd4e8c1 4191 case 2:
ca7f5001 4192 return \"{st%U0|stw%U0} %1,%0\;{st|stw} %L1,%L0\";
8ffd9c51
RK
4193 case 3:
4194 return \"fmr %0,%1\";
4195 case 4:
4196 return \"lfd%U1%X1 %0,%1\";
4197 case 5:
4198 return \"stfd%U0%X0 %1,%0\";
1fd4e8c1
RK
4199 }
4200}"
8ffd9c51
RK
4201 [(set_attr "type" "*,load,*,fp,fpload,*")
4202 (set_attr "length" "8,8,8,*,*,*")])
51b8fc2c
RK
4203
4204(define_insn ""
57fa6739
RK
4205 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m,r,r,r,f,f,m,r,*h")
4206 (match_operand:DI 1 "input_operand" "r,m,r,I,J,R,f,m,f,*h,r"))]
51b8fc2c
RK
4207 "TARGET_POWERPC64 && (gpc_reg_operand (operands[0], DImode)
4208 || gpc_reg_operand (operands[1], DImode))"
4209 "@
3d5570cb
RK
4210 mr %0,%1
4211 ld%U1%X1 %0,%1
4212 sd%U0%X0 %1,%0
4213 li %0,%1
4214 lis %0,%u1
57fa6739 4215 {cal|la} %0,%1(%*)
3d5570cb
RK
4216 fmr %0,%1
4217 lfd%U1%X1 %0,%1
4218 stfd%U0%X0 %1,%0
4219 mf%1 %0
4220 mt%0 %1"
57fa6739 4221 [(set_attr "type" "*,load,*,*,*,*,fp,fpload,*,*,mtjmpr")])
1fd4e8c1
RK
4222\f
4223;; TImode is similar, except that we usually want to compute the address into
4224;; a register and use lsi/stsi (the exception is during reload). MQ is also
ca7f5001 4225;; clobbered in stsi for POWER, so we need a SCRATCH for it.
1fd4e8c1
RK
4226(define_expand "movti"
4227 [(parallel [(set (match_operand:TI 0 "general_operand" "")
4228 (match_operand:TI 1 "general_operand" ""))
4229 (clobber (scratch:SI))])]
d14a6d05 4230 "TARGET_MULTIPLE || TARGET_POWERPC64"
1fd4e8c1
RK
4231 "
4232{
4233 if (GET_CODE (operands[0]) == MEM)
4234 operands[1] = force_reg (TImode, operands[1]);
4235
4236 if (GET_CODE (operands[0]) == MEM
4237 && GET_CODE (XEXP (operands[0], 0)) != REG
4238 && ! reload_in_progress)
4239 operands[0] = change_address (operands[0], TImode,
4240 copy_addr_to_reg (XEXP (operands[0], 0)));
4241
4242 if (GET_CODE (operands[1]) == MEM
4243 && GET_CODE (XEXP (operands[1], 0)) != REG
4244 && ! reload_in_progress)
4245 operands[1] = change_address (operands[1], TImode,
4246 copy_addr_to_reg (XEXP (operands[1], 0)));
4247}")
4248
4249;; We say that MQ is clobbered in the last alternative because the first
4250;; alternative would never get used otherwise since it would need a reload
4251;; while the 2nd alternative would not. We put memory cases first so they
4252;; are preferred. Otherwise, we'd try to reload the output instead of
4253;; giving the SCRATCH mq.
4254(define_insn ""
e1469d0d 4255 [(set (match_operand:TI 0 "reg_or_mem_operand" "=Q,m,????r,????r,????r")
1fd4e8c1
RK
4256 (match_operand:TI 1 "reg_or_mem_operand" "r,r,r,Q,m"))
4257 (clobber (match_scratch:SI 2 "=q,q#X,X,X,X"))]
dc4f83ca
MM
4258 "TARGET_MULTIPLE && TARGET_POWER && ! TARGET_POWERPC64
4259 && (gpc_reg_operand (operands[0], TImode) || gpc_reg_operand (operands[1], TImode))"
1fd4e8c1
RK
4260 "*
4261{
4262 switch (which_alternative)
4263 {
dc4f83ca
MM
4264 default:
4265 abort ();
4266
1fd4e8c1 4267 case 0:
ca7f5001 4268 return \"{stsi|stswi} %1,%P0,16\";
1fd4e8c1
RK
4269
4270 case 1:
ca7f5001 4271 return \"{st%U0|stw%U0} %1,%0\;{st|stw} %L1,%L0\;{st|stw} %Y1,%Y0\;{st|stw} %Z1,%Z0\";
1fd4e8c1
RK
4272
4273 case 2:
4274 /* Normally copy registers with lowest numbered register copied first.
4275 But copy in the other order if the first register of the output
4276 is the second, third, or fourth register in the input. */
4277 if (REGNO (operands[0]) >= REGNO (operands[1]) + 1
4278 && REGNO (operands[0]) <= REGNO (operands[1]) + 3)
deb9225a 4279 return \"mr %Z0,%Z1\;mr %Y0,%Y1\;mr %L0,%L1\;mr %0,%1\";
1fd4e8c1 4280 else
deb9225a 4281 return \"mr %0,%1\;mr %L0,%L1\;mr %Y0,%Y1\;mr %Z0,%Z1\";
1fd4e8c1
RK
4282 case 3:
4283 /* If the address is not used in the output, we can use lsi. Otherwise,
4284 fall through to generating four loads. */
4285 if (! reg_overlap_mentioned_p (operands[0], operands[1]))
ca7f5001 4286 return \"{lsi|lswi} %0,%P1,16\";
1fd4e8c1
RK
4287 /* ... fall through ... */
4288 case 4:
4289 /* If the address register is the same as the register for the lowest-
4290 addressed word, load it last. Similarly for the next two words.
4291 Otherwise load lowest address to highest. */
4292 if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
4293 operands[1], 0))
ca7f5001 4294 return \"{l|lwz} %L0,%L1\;{l|lwz} %Y0,%Y1\;{l|lwz} %Z0,%Z1\;{l|lwz} %0,%1\";
1fd4e8c1
RK
4295 else if (refers_to_regno_p (REGNO (operands[0]) + 1,
4296 REGNO (operands[0]) + 2, operands[1], 0))
ca7f5001 4297 return \"{l|lwz} %0,%1\;{l|lwz} %Y0,%Y1\;{l|lwz} %Z0,%Z1\;{l|lwz} %L0,%L1\";
1fd4e8c1
RK
4298 else if (refers_to_regno_p (REGNO (operands[0]) + 2,
4299 REGNO (operands[0]) + 3, operands[1], 0))
ca7f5001 4300 return \"{l|lwz} %0,%1\;{l|lwz} %L0,%L1\;{l|lwz} %Z0,%Z1\;{l|lwz} %Y0,%Y1\";
1fd4e8c1 4301 else
ca7f5001 4302 return \"{l%U1|lwz%U1} %0,%1\;{l|lwz} %L0,%L1\;{l|lwz} %Y0,%Y1\;{l|lwz} %Z0,%Z1\";
1fd4e8c1
RK
4303 }
4304}"
b19003d8
RK
4305 [(set_attr "type" "*,load,load,*,*")
4306 (set_attr "length" "*,16,16,*,16")])
51b8fc2c 4307
dc4f83ca
MM
4308(define_insn ""
4309 [(set (match_operand:TI 0 "reg_or_mem_operand" "=m,????r,????r")
4310 (match_operand:TI 1 "reg_or_mem_operand" "r,r,m"))
4311 (clobber (match_scratch:SI 2 "=X,X,X"))]
4312 "TARGET_MULTIPLE && !TARGET_POWER && ! TARGET_POWERPC64
4313 && (gpc_reg_operand (operands[0], TImode) || gpc_reg_operand (operands[1], TImode))"
4314 "*
4315{
4316 switch (which_alternative)
4317 {
4318 default:
4319 abort ();
4320
4321 case 0:
4322 return \"{st%U0|stw%U0} %1,%0\;{st|stw} %L1,%L0\;{st|stw} %Y1,%Y0\;{st|stw} %Z1,%Z0\";
4323
4324 case 1:
4325 /* Normally copy registers with lowest numbered register copied first.
4326 But copy in the other order if the first register of the output
4327 is the second, third, or fourth register in the input. */
4328 if (REGNO (operands[0]) >= REGNO (operands[1]) + 1
4329 && REGNO (operands[0]) <= REGNO (operands[1]) + 3)
4330 return \"mr %Z0,%Z1\;mr %Y0,%Y1\;mr %L0,%L1\;mr %0,%1\";
4331 else
4332 return \"mr %0,%1\;mr %L0,%L1\;mr %Y0,%Y1\;mr %Z0,%Z1\";
4333 case 2:
4334 /* If the address register is the same as the register for the lowest-
4335 addressed word, load it last. Similarly for the next two words.
4336 Otherwise load lowest address to highest. */
4337 if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
4338 operands[1], 0))
4339 return \"{l|lwz} %L0,%L1\;{l|lwz} %Y0,%Y1\;{l|lwz} %Z0,%Z1\;{l|lwz} %0,%1\";
4340 else if (refers_to_regno_p (REGNO (operands[0]) + 1,
4341 REGNO (operands[0]) + 2, operands[1], 0))
4342 return \"{l|lwz} %0,%1\;{l|lwz} %Y0,%Y1\;{l|lwz} %Z0,%Z1\;{l|lwz} %L0,%L1\";
4343 else if (refers_to_regno_p (REGNO (operands[0]) + 2,
4344 REGNO (operands[0]) + 3, operands[1], 0))
4345 return \"{l|lwz} %0,%1\;{l|lwz} %L0,%L1\;{l|lwz} %Z0,%Z1\;{l|lwz} %Y0,%Y1\";
4346 else
4347 return \"{l%U1|lwz%U1} %0,%1\;{l|lwz} %L0,%L1\;{l|lwz} %Y0,%Y1\;{l|lwz} %Z0,%Z1\";
4348 }
4349}"
4350 [(set_attr "type" "load,*,*")
4351 (set_attr "length" "16,16,16")])
4352
51b8fc2c
RK
4353(define_insn ""
4354 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,r,m")
4355 (match_operand:TI 1 "input_operand" "r,m,r"))]
4356 "TARGET_POWERPC64 && (gpc_reg_operand (operands[0], TImode)
4357 || gpc_reg_operand (operands[1], TImode))"
4358 "*
4359{
4360 switch (which_alternative)
4361 {
4362 case 0:
4363 /* We normally copy the low-numbered register first. However, if
4364 the first register operand 0 is the same as the second register of
4365 operand 1, we must copy in the opposite order. */
4366 if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
4367 return \"mr %L0,%L1\;mr %0,%1\";
4368 else
4369 return \"mr %0,%1\;mr %L0,%L1\";
4370 case 1:
4371 /* If the low-address word is used in the address, we must load it
4372 last. Otherwise, load it first. Note that we cannot have
4373 auto-increment in that case since the address register is known to be
4374 dead. */
4375 if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
4376 operands [1], 0))
4377 return \"ld %L0,%L1\;ld %0,%1\";
4378 else
4379 return \"ld%U1 %0,%1\;ld %L0,%L1\";
4380 case 2:
4381 return \"std%U0 %1,%0\;std %L1,%L0\";
4382 }
4383}"
4384 [(set_attr "type" "*,load,*")
4385 (set_attr "length" "8,8,8")])
1fd4e8c1
RK
4386\f
4387(define_expand "load_multiple"
2f622005
RK
4388 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
4389 (match_operand:SI 1 "" ""))
4390 (use (match_operand:SI 2 "" ""))])]
4d30c363 4391 "TARGET_MULTIPLE"
1fd4e8c1
RK
4392 "
4393{
4394 int regno;
4395 int count;
4396 rtx from;
4397 int i;
4398
4399 /* Support only loading a constant number of fixed-point registers from
4400 memory and only bother with this if more than two; the machine
4401 doesn't support more than eight. */
4402 if (GET_CODE (operands[2]) != CONST_INT
4403 || INTVAL (operands[2]) <= 2
4404 || INTVAL (operands[2]) > 8
4405 || GET_CODE (operands[1]) != MEM
4406 || GET_CODE (operands[0]) != REG
4407 || REGNO (operands[0]) >= 32)
4408 FAIL;
4409
4410 count = INTVAL (operands[2]);
4411 regno = REGNO (operands[0]);
4412
4413 operands[3] = gen_rtx (PARALLEL, VOIDmode, rtvec_alloc (count));
4414 from = force_reg (SImode, XEXP (operands[1], 0));
4415
4416 for (i = 0; i < count; i++)
4417 XVECEXP (operands[3], 0, i)
4418 = gen_rtx (SET, VOIDmode, gen_rtx (REG, SImode, regno + i),
4419 gen_rtx (MEM, SImode, plus_constant (from, i * 4)));
4420}")
4421
4422(define_insn ""
4423 [(match_parallel 0 "load_multiple_operation"
cd2b37d9 4424 [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
1fd4e8c1 4425 (match_operand:SI 2 "indirect_operand" "Q"))])]
4d30c363 4426 "TARGET_MULTIPLE"
1fd4e8c1
RK
4427 "*
4428{
4429 /* We have to handle the case where the pseudo used to contain the address
4430 is assigned to one of the output registers. In that case, do the
4431 lsi, but then load the correct value. This is a bit of a mess, but is
b19003d8
RK
4432 the best we can do.
4433 We set the length attribute to the maximum possible size (8 bytes). */
1fd4e8c1
RK
4434 static char result[100];
4435 char newload[40];
4436 int i;
4437
ca7f5001 4438 strcpy (result, \"{lsi|lswi} %1,%P2,%N0\");
1fd4e8c1
RK
4439 for (i = 0; i < XVECLEN (operands[0], 0); i++)
4440 if (refers_to_regno_p (REGNO (operands[1]) + i,
4441 REGNO (operands[1]) + i + 1, operands[2], 0))
4442 {
ca7f5001 4443 sprintf (newload, \"\;{l|lwz} %d,%d(%d)\",
1fd4e8c1
RK
4444 REGNO (operands[1]) + i,
4445 i * 4, REGNO (XEXP (operands[2], 0)));
4446 strcat (result, newload);
4447 }
4448
4449 return result;
4450}"
b19003d8
RK
4451 [(set_attr "type" "load")
4452 (set_attr "length" "8")])
1fd4e8c1 4453\f
b19003d8 4454
1fd4e8c1 4455(define_expand "store_multiple"
2f622005
RK
4456 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
4457 (match_operand:SI 1 "" ""))
4458 (clobber (scratch:SI))
4459 (use (match_operand:SI 2 "" ""))])]
4d30c363 4460 "TARGET_MULTIPLE"
1fd4e8c1
RK
4461 "
4462{
4463 int regno;
4464 int count;
4465 rtx to;
4466 int i;
4467
4468 /* Support only storing a constant number of fixed-point registers to
4469 memory and only bother with this if more than two; the machine
4470 doesn't support more than eight. */
4471 if (GET_CODE (operands[2]) != CONST_INT
4472 || INTVAL (operands[2]) <= 2
4473 || INTVAL (operands[2]) > 8
4474 || GET_CODE (operands[0]) != MEM
4475 || GET_CODE (operands[1]) != REG
4476 || REGNO (operands[1]) >= 32)
4477 FAIL;
4478
4479 count = INTVAL (operands[2]);
4480 regno = REGNO (operands[1]);
4481
4482 operands[3] = gen_rtx (PARALLEL, VOIDmode, rtvec_alloc (count + 1));
4483 to = force_reg (SImode, XEXP (operands[0], 0));
4484
4485 XVECEXP (operands[3], 0, 0)
4486 = gen_rtx (SET, VOIDmode, gen_rtx (MEM, SImode, to), operands[1]);
4487 XVECEXP (operands[3], 0, 1) = gen_rtx (CLOBBER, VOIDmode,
4488 gen_rtx (SCRATCH, SImode));
4489
4490 for (i = 1; i < count; i++)
4491 XVECEXP (operands[3], 0, i + 1)
4492 = gen_rtx (SET, VOIDmode,
4493 gen_rtx (MEM, SImode, plus_constant (to, i * 4)),
4494 gen_rtx (REG, SImode, regno + i));
4495}")
4496
4497(define_insn ""
4498 [(match_parallel 0 "store_multiple_operation"
4499 [(set (match_operand:SI 1 "indirect_operand" "=Q")
cd2b37d9 4500 (match_operand:SI 2 "gpc_reg_operand" "r"))
1fd4e8c1 4501 (clobber (match_scratch:SI 3 "=q"))])]
dc4f83ca 4502 "TARGET_MULTIPLE && TARGET_POWER"
d14a6d05
MM
4503 "{stsi|stswi} %2,%P1,%O0")
4504
4505(define_insn ""
4506 [(match_parallel 0 "store_multiple_operation"
4507 [(set (match_operand:SI 1 "indirect_operand" "=Q")
4508 (match_operand:SI 2 "gpc_reg_operand" "r"))
4509 (clobber (match_scratch:SI 3 "X"))])]
dc4f83ca 4510 "TARGET_MULTIPLE && !TARGET_POWER"
ca7f5001 4511 "{stsi|stswi} %2,%P1,%O0")
1fd4e8c1
RK
4512\f
4513;; Define insns that do load or store with update. Some of these we can
4514;; get by using pre-decrement or pre-increment, but the hardware can also
4515;; do cases where the increment is not the size of the object.
4516;;
4517;; In all these cases, we use operands 0 and 1 for the register being
4518;; incremented because those are the operands that local-alloc will
4519;; tie and these are the pair most likely to be tieable (and the ones
4520;; that will benefit the most).
4521
51b8fc2c
RK
4522(define_insn ""
4523 [(set (match_operand:DI 3 "gpc_reg_operand" "=r,r")
ad8bd902 4524 (mem:DI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0,0")
51b8fc2c
RK
4525 (match_operand:DI 2 "reg_or_short_operand" "r,I"))))
4526 (set (match_operand:DI 0 "gpc_reg_operand" "=b,b")
4527 (plus:DI (match_dup 1) (match_dup 2)))]
4528 "TARGET_POWERPC64"
4529 "@
4530 ldux %3,%0,%2
4531 ldu %3,%2(%0)"
4532 [(set_attr "type" "load")])
4533
287f13ff
RK
4534(define_insn ""
4535 [(set (match_operand:DI 3 "gpc_reg_operand" "=r")
4536 (sign_extend:DI
4537 (mem:SI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0")
4538 (match_operand:DI 2 "gpc_reg_operand" "r")))))
4539 (set (match_operand:DI 0 "gpc_reg_operand" "=b")
4540 (plus:DI (match_dup 1) (match_dup 2)))]
4541 "TARGET_POWERPC64"
4542 "lwaux %3,%0,%2"
4543 [(set_attr "type" "load")])
4544
51b8fc2c
RK
4545(define_insn ""
4546 [(set (mem:DI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0,0")
4547 (match_operand:DI 2 "reg_or_short_operand" "r,I")))
4548 (match_operand:DI 3 "gpc_reg_operand" "r,r"))
4549 (set (match_operand:DI 0 "gpc_reg_operand" "=b,b")
4550 (plus:DI (match_dup 1) (match_dup 2)))]
4551 "TARGET_POWERPC64"
4552 "@
4553 stdux %3,%0,%2
4554 stdu %3,%2(%0)")
4555
1fd4e8c1 4556(define_insn ""
cd2b37d9
RK
4557 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
4558 (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
1fd4e8c1 4559 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
cd2b37d9 4560 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
1fd4e8c1
RK
4561 (plus:SI (match_dup 1) (match_dup 2)))]
4562 ""
4563 "@
ca7f5001
RK
4564 {lux|lwzux} %3,%0,%2
4565 {lu|lwzu} %3,%2(%0)"
cfb557c4 4566 [(set_attr "type" "load")])
1fd4e8c1
RK
4567
4568(define_insn ""
cd2b37d9 4569 [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
1fd4e8c1 4570 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
cd2b37d9
RK
4571 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
4572 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
1fd4e8c1
RK
4573 (plus:SI (match_dup 1) (match_dup 2)))]
4574 ""
4575 "@
ca7f5001
RK
4576 {stux|stwux} %3,%0,%2
4577 {stu|stwu} %3,%2(%0)")
1fd4e8c1
RK
4578
4579(define_insn ""
cd2b37d9
RK
4580 [(set (match_operand:HI 3 "gpc_reg_operand" "=r,r")
4581 (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
1fd4e8c1 4582 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
cd2b37d9 4583 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
1fd4e8c1
RK
4584 (plus:SI (match_dup 1) (match_dup 2)))]
4585 ""
4586 "@
5f243543
RK
4587 lhzux %3,%0,%2
4588 lhzu %3,%2(%0)"
cfb557c4 4589 [(set_attr "type" "load")])
1fd4e8c1
RK
4590
4591(define_insn ""
cd2b37d9 4592 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
1fd4e8c1 4593 (zero_extend:SI
cd2b37d9 4594 (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
1fd4e8c1 4595 (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
cd2b37d9 4596 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
1fd4e8c1
RK
4597 (plus:SI (match_dup 1) (match_dup 2)))]
4598 ""
4599 "@
5f243543
RK
4600 lhzux %3,%0,%2
4601 lhzu %3,%2(%0)"
cfb557c4 4602 [(set_attr "type" "load")])
1fd4e8c1
RK
4603
4604(define_insn ""
cd2b37d9 4605 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
1fd4e8c1 4606 (sign_extend:SI
cd2b37d9 4607 (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
1fd4e8c1 4608 (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
cd2b37d9 4609 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
1fd4e8c1
RK
4610 (plus:SI (match_dup 1) (match_dup 2)))]
4611 ""
4612 "@
5f243543
RK
4613 lhaux %3,%0,%2
4614 lhau %3,%2(%0)"
cfb557c4 4615 [(set_attr "type" "load")])
1fd4e8c1
RK
4616
4617(define_insn ""
cd2b37d9 4618 [(set (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
1fd4e8c1 4619 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
cd2b37d9
RK
4620 (match_operand:HI 3 "gpc_reg_operand" "r,r"))
4621 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
1fd4e8c1
RK
4622 (plus:SI (match_dup 1) (match_dup 2)))]
4623 ""
4624 "@
5f243543 4625 sthux %3,%0,%2
cfb557c4 4626 sthu %3,%2(%0)")
1fd4e8c1
RK
4627
4628(define_insn ""
cd2b37d9
RK
4629 [(set (match_operand:QI 3 "gpc_reg_operand" "=r,r")
4630 (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
1fd4e8c1 4631 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
cd2b37d9 4632 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
1fd4e8c1
RK
4633 (plus:SI (match_dup 1) (match_dup 2)))]
4634 ""
4635 "@
5f243543
RK
4636 lbzux %3,%0,%2
4637 lbzu %3,%2(%0)"
cfb557c4 4638 [(set_attr "type" "load")])
1fd4e8c1
RK
4639
4640(define_insn ""
cd2b37d9 4641 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
1fd4e8c1 4642 (zero_extend:SI
cd2b37d9 4643 (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
1fd4e8c1 4644 (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
cd2b37d9 4645 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
1fd4e8c1
RK
4646 (plus:SI (match_dup 1) (match_dup 2)))]
4647 ""
4648 "@
5f243543
RK
4649 lbzux %3,%0,%2
4650 lbzu %3,%2(%0)"
cfb557c4 4651 [(set_attr "type" "load")])
1fd4e8c1
RK
4652
4653(define_insn ""
cd2b37d9 4654 [(set (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
1fd4e8c1 4655 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
cd2b37d9
RK
4656 (match_operand:QI 3 "gpc_reg_operand" "r,r"))
4657 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
1fd4e8c1
RK
4658 (plus:SI (match_dup 1) (match_dup 2)))]
4659 ""
4660 "@
5f243543
RK
4661 stbux %3,%0,%2
4662 stbu %3,%2(%0)")
1fd4e8c1
RK
4663
4664(define_insn ""
cd2b37d9 4665 [(set (match_operand:SF 3 "gpc_reg_operand" "=f,f")
df8b713c 4666 (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
1fd4e8c1 4667 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
cd2b37d9 4668 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
1fd4e8c1 4669 (plus:SI (match_dup 1) (match_dup 2)))]
d14a6d05 4670 "TARGET_HARD_FLOAT"
1fd4e8c1 4671 "@
5f243543
RK
4672 lfsux %3,%0,%2
4673 lfsu %3,%2(%0)"
cfb557c4 4674 [(set_attr "type" "fpload")])
1fd4e8c1
RK
4675
4676(define_insn ""
cd2b37d9 4677 [(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
1fd4e8c1 4678 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
cd2b37d9
RK
4679 (match_operand:SF 3 "gpc_reg_operand" "f,f"))
4680 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
1fd4e8c1 4681 (plus:SI (match_dup 1) (match_dup 2)))]
d14a6d05 4682 "TARGET_HARD_FLOAT"
1fd4e8c1 4683 "@
85fff2f3
RK
4684 stfsux %3,%0,%2
4685 stfsu %3,%2(%0)")
1fd4e8c1
RK
4686
4687(define_insn ""
cd2b37d9
RK
4688 [(set (match_operand:DF 3 "gpc_reg_operand" "=f,f")
4689 (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
1fd4e8c1 4690 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
cd2b37d9 4691 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
1fd4e8c1 4692 (plus:SI (match_dup 1) (match_dup 2)))]
d14a6d05 4693 "TARGET_HARD_FLOAT"
1fd4e8c1 4694 "@
5f243543
RK
4695 lfdux %3,%0,%2
4696 lfdu %3,%2(%0)"
cfb557c4 4697 [(set_attr "type" "fpload")])
1fd4e8c1
RK
4698
4699(define_insn ""
cd2b37d9 4700 [(set (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
1fd4e8c1 4701 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
cd2b37d9
RK
4702 (match_operand:DF 3 "gpc_reg_operand" "f,f"))
4703 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
1fd4e8c1 4704 (plus:SI (match_dup 1) (match_dup 2)))]
d14a6d05 4705 "TARGET_HARD_FLOAT"
1fd4e8c1 4706 "@
5f243543
RK
4707 stfdux %3,%0,%2
4708 stfdu %3,%2(%0)")
4c70a4f3
RK
4709
4710;; Peephole to convert two consecutive FP loads or stores into lfq/stfq.
4711
4712(define_peephole
4713 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
4714 (match_operand:DF 1 "memory_operand" ""))
4715 (set (match_operand:DF 2 "gpc_reg_operand" "=f")
4716 (match_operand:DF 3 "memory_operand" ""))]
4717 "TARGET_POWER2
d14a6d05 4718 && TARGET_HARD_FLOAT
4c70a4f3
RK
4719 && registers_ok_for_quad_peep (operands[0], operands[2])
4720 && ! MEM_VOLATILE_P (operands[1]) && ! MEM_VOLATILE_P (operands[3])
4721 && addrs_ok_for_quad_peep (XEXP (operands[1], 0), XEXP (operands[3], 0))"
4722 "lfq%U1%X1 %0,%1")
4723
4724(define_peephole
4725 [(set (match_operand:DF 0 "memory_operand" "")
4726 (match_operand:DF 1 "gpc_reg_operand" "f"))
4727 (set (match_operand:DF 2 "memory_operand" "")
4728 (match_operand:DF 3 "gpc_reg_operand" "f"))]
4729 "TARGET_POWER2
d14a6d05 4730 && TARGET_HARD_FLOAT
4c70a4f3
RK
4731 && registers_ok_for_quad_peep (operands[1], operands[3])
4732 && ! MEM_VOLATILE_P (operands[0]) && ! MEM_VOLATILE_P (operands[2])
4733 && addrs_ok_for_quad_peep (XEXP (operands[0], 0), XEXP (operands[2], 0))"
4734 "stfq%U0%X0 %1,%0")
1fd4e8c1
RK
4735\f
4736;; Next come insns related to the calling sequence.
4737;;
4738;; First, an insn to allocate new stack space for dynamic use (e.g., alloca).
59257ff7 4739;; We move the back-chain and decrement the stack pointer.
1fd4e8c1
RK
4740
4741(define_expand "allocate_stack"
4742 [(set (reg:SI 1)
01def764 4743 (minus:SI (reg:SI 1) (match_operand:SI 0 "reg_or_short_operand" "")))]
1fd4e8c1
RK
4744 ""
4745 "
4746{ rtx chain = gen_reg_rtx (SImode);
4747 rtx stack_bot = gen_rtx (MEM, Pmode, stack_pointer_rtx);
4748
4749 emit_move_insn (chain, stack_bot);
a0044fb1 4750 emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx, operands[0]));
1fd4e8c1
RK
4751 emit_move_insn (stack_bot, chain);
4752 DONE;
4753}")
59257ff7
RK
4754
4755;; These patterns say how to save and restore the stack pointer. We need not
4756;; save the stack pointer at function level since we are careful to
4757;; preserve the backchain. At block level, we have to restore the backchain
4758;; when we restore the stack pointer.
4759;;
4760;; For nonlocal gotos, we must save both the stack pointer and its
4761;; backchain and restore both. Note that in the nonlocal case, the
4762;; save area is a memory location.
4763
4764(define_expand "save_stack_function"
4765 [(use (const_int 0))]
4766 ""
4767 "")
4768
4769(define_expand "restore_stack_function"
4770 [(use (const_int 0))]
4771 ""
4772 "")
4773
4774(define_expand "restore_stack_block"
4775 [(set (match_dup 2) (mem:SI (match_operand:SI 0 "register_operand" "")))
4776 (set (match_dup 0) (match_operand:SI 1 "register_operand" ""))
4777 (set (mem:SI (match_dup 0)) (match_dup 2))]
4778 ""
4779 "
4780{ operands[2] = gen_reg_rtx (SImode); }")
4781
4782(define_expand "save_stack_nonlocal"
4783 [(match_operand:DI 0 "memory_operand" "")
4784 (match_operand:SI 1 "register_operand" "")]
4785 ""
4786 "
4787{
4788 rtx temp = gen_reg_rtx (SImode);
4789
4790 /* Copy the backchain to the first word, sp to the second. */
4791 emit_move_insn (temp, gen_rtx (MEM, SImode, operands[1]));
4792 emit_move_insn (operand_subword (operands[0], 0, 0, DImode), temp);
4793 emit_move_insn (operand_subword (operands[0], 1, 0, DImode), operands[1]);
4794 DONE;
4795}")
4796
4797(define_expand "restore_stack_nonlocal"
4798 [(match_operand:SI 0 "register_operand" "")
4799 (match_operand:DI 1 "memory_operand" "")]
4800 ""
4801 "
4802{
4803 rtx temp = gen_reg_rtx (SImode);
4804
4805 /* Restore the backchain from the first word, sp from the second. */
4806 emit_move_insn (temp, operand_subword (operands[1], 0, 0, DImode));
4807 emit_move_insn (operands[0], operand_subword (operands[1], 1, 0, DImode));
4808 emit_move_insn (gen_rtx (MEM, SImode, operands[0]), temp);
4809 DONE;
4810}")
1fd4e8c1
RK
4811\f
4812;; A function pointer is a pointer to a data area whose first word contains
4813;; the actual address of the function, whose second word contains a pointer
4814;; to its TOC, and whose third word contains a value to place in the static
4815;; chain register (r11). Note that if we load the static chain, our
4816;; "trampoline" need not have any executable code.
4817;;
4818;; operands[0] is an SImode pseudo in which we place the address of the
4819;; function.
4820;; operands[1] is the address of data area of the function to call
4821
4822(define_expand "call_via_ptr"
cd2b37d9
RK
4823 [(set (match_operand:SI 0 "gpc_reg_operand" "")
4824 (mem:SI (match_operand:SI 1 "gpc_reg_operand" "")))
1fd4e8c1
RK
4825 (set (mem:SI (plus:SI (reg:SI 1) (const_int 20)))
4826 (reg:SI 2))
4827 (set (reg:SI 2)
4828 (mem:SI (plus:SI (match_dup 1)
4829 (const_int 4))))
4830 (set (reg:SI 11)
4831 (mem:SI (plus:SI (match_dup 1)
4832 (const_int 8))))
4833 (use (reg:SI 2))
4834 (use (reg:SI 11))]
4835 ""
4836 "")
4837
4838(define_expand "call"
4839 [(parallel [(call (mem:SI (match_operand:SI 0 "address_operand" ""))
4840 (match_operand 1 "" ""))
4841 (clobber (scratch:SI))])]
4842 ""
4843 "
4844{
4845 if (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != CONST_INT)
4846 abort ();
4847
4848 operands[0] = XEXP (operands[0], 0);
4849 if (GET_CODE (operands[0]) != SYMBOL_REF)
4850 {
29bd4eb3
MM
4851#ifndef USING_SVR4_H
4852 /* AIX function pointers are really pointers to a three word area */
1fd4e8c1
RK
4853 rtx temp = gen_reg_rtx (SImode);
4854
4855 emit_insn (gen_call_via_ptr (temp, force_reg (SImode, operands[0])));
4856 operands[0] = temp;
29bd4eb3 4857#endif /* !USING_SVR4_H */
1fd4e8c1
RK
4858 }
4859}")
4860
4861(define_expand "call_value"
4862 [(parallel [(set (match_operand 0 "" "")
4863 (call (mem:SI (match_operand:SI 1 "address_operand" ""))
4864 (match_operand 2 "" "")))
4865 (clobber (scratch:SI))])]
4866 ""
4867 "
4868{
4869 if (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != CONST_INT)
4870 abort ();
4871
4872 operands[1] = XEXP (operands[1], 0);
4873 if (GET_CODE (operands[1]) != SYMBOL_REF)
4874 {
29bd4eb3
MM
4875#ifndef USING_SVR4_H
4876 /* AIX function pointers are really pointers to a three word area */
1fd4e8c1
RK
4877 rtx temp = gen_reg_rtx (SImode);
4878
4879 emit_insn (gen_call_via_ptr (temp, force_reg (SImode, operands[1])));
4880 operands[1] = temp;
29bd4eb3 4881#endif /* !USING_SVR4_H */
1fd4e8c1
RK
4882 }
4883}")
4884
04780ee7
RK
4885;; Call to function in current module. No TOC pointer reload needed.
4886
4887(define_insn ""
4888 [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s"))
4889 (match_operand 1 "" "g"))
4890 (clobber (match_scratch:SI 2 "=l"))]
4891 ""
4892 "bl %z0")
4893
4894;; Call to function which may be in another module. Restore the TOC
911f679c 4895;; pointer (r2) after the call unless this is System V.
04780ee7 4896
1fd4e8c1
RK
4897(define_insn ""
4898 [(call (mem:SI (match_operand:SI 0 "call_operand" "l,s"))
4899 (match_operand 1 "" "fg,fg"))
9482d6de 4900 (clobber (match_scratch:SI 2 "=l,l"))]
1fd4e8c1 4901 ""
911f679c
MM
4902 "*
4903{
4904 if (GET_CODE (operands[0]) == REG)
4905 {
4906#ifndef USING_SVR4_H
4907 return \"{brl|blrl}\;{l|lwz} 2,20(1)\";
4908#else
4909 return \"{brl|blrl}\";
4910#endif
4911 }
4912
4913 return \"bl %z0\;%.\";
4914}"
b19003d8 4915 [(set_attr "length" "8")])
1fd4e8c1 4916
04780ee7
RK
4917(define_insn ""
4918 [(set (match_operand 0 "" "=fg")
4919 (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s"))
4920 (match_operand 2 "" "g")))
4921 (clobber (match_scratch:SI 3 "=l"))]
4922 ""
4923 "bl %z1")
4924
1fd4e8c1 4925(define_insn ""
5f243543 4926 [(set (match_operand 0 "" "=fg,fg")
1fd4e8c1
RK
4927 (call (mem:SI (match_operand:SI 1 "call_operand" "l,s"))
4928 (match_operand 2 "" "fg,fg")))
4929 (clobber (match_scratch:SI 3 "=l,l"))]
4930 ""
911f679c
MM
4931 "*
4932{
4933 if (GET_CODE (operands[1]) == REG)
4934 {
4935#ifndef USING_SVR4_H
4936 return \"{brl|blrl}\;{l|lwz} 2,20(1)\";
4937#else
4938 return \"{brl|blrl}\";
4939#endif
4940 }
4941
4942 return \"bl %z1\;%.\";
4943}"
b19003d8 4944 [(set_attr "length" "8")])
e6f948e3
RK
4945
4946;; Call subroutine returning any type.
4947
4948(define_expand "untyped_call"
4949 [(parallel [(call (match_operand 0 "" "")
4950 (const_int 0))
4951 (match_operand 1 "" "")
4952 (match_operand 2 "" "")])]
4953 ""
4954 "
4955{
4956 int i;
4957
4958 emit_call_insn (gen_call (operands[0], const0_rtx, NULL, const0_rtx));
4959
4960 for (i = 0; i < XVECLEN (operands[2], 0); i++)
4961 {
4962 rtx set = XVECEXP (operands[2], 0, i);
4963 emit_move_insn (SET_DEST (set), SET_SRC (set));
4964 }
4965
4966 /* The optimizer does not know that the call sets the function value
4967 registers we stored in the result block. We avoid problems by
4968 claiming that all hard registers are used and clobbered at this
4969 point. */
4970 emit_insn (gen_blockage ());
4971
4972 DONE;
4973}")
4974
4975;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
4976;; all of memory. This blocks insns from being moved across this point.
4977
4978(define_insn "blockage"
4979 [(unspec_volatile [(const_int 0)] 0)]
4980 ""
4981 "")
1fd4e8c1
RK
4982\f
4983;; Compare insns are next. Note that the RS/6000 has two types of compares,
4984;; signed & unsigned, and one type of branch.
4985;;
4986;; Start with the DEFINE_EXPANDs to generate the rtl for compares, scc
4987;; insns, and branches. We store the operands of compares until we see
4988;; how it is used.
4989(define_expand "cmpsi"
4990 [(set (cc0)
cd2b37d9 4991 (compare (match_operand:SI 0 "gpc_reg_operand" "")
1fd4e8c1
RK
4992 (match_operand:SI 1 "reg_or_short_operand" "")))]
4993 ""
4994 "
4995{
4996 /* Take care of the possibility that operands[1] might be negative but
4997 this might be a logical operation. That insn doesn't exist. */
4998 if (GET_CODE (operands[1]) == CONST_INT
4999 && INTVAL (operands[1]) < 0)
5000 operands[1] = force_reg (SImode, operands[1]);
5001
5002 rs6000_compare_op0 = operands[0];
5003 rs6000_compare_op1 = operands[1];
5004 rs6000_compare_fp_p = 0;
5005 DONE;
5006}")
5007
5008(define_expand "cmpsf"
cd2b37d9
RK
5009 [(set (cc0) (compare (match_operand:SF 0 "gpc_reg_operand" "")
5010 (match_operand:SF 1 "gpc_reg_operand" "")))]
d14a6d05 5011 "TARGET_HARD_FLOAT"
1fd4e8c1
RK
5012 "
5013{
5014 rs6000_compare_op0 = operands[0];
5015 rs6000_compare_op1 = operands[1];
5016 rs6000_compare_fp_p = 1;
5017 DONE;
5018}")
5019
5020(define_expand "cmpdf"
cd2b37d9
RK
5021 [(set (cc0) (compare (match_operand:DF 0 "gpc_reg_operand" "")
5022 (match_operand:DF 1 "gpc_reg_operand" "")))]
d14a6d05 5023 "TARGET_HARD_FLOAT"
1fd4e8c1
RK
5024 "
5025{
5026 rs6000_compare_op0 = operands[0];
5027 rs6000_compare_op1 = operands[1];
5028 rs6000_compare_fp_p = 1;
5029 DONE;
5030}")
5031
5032(define_expand "beq"
5033 [(set (match_dup 2) (match_dup 1))
5034 (set (pc)
5035 (if_then_else (eq (match_dup 2)
5036 (const_int 0))
5037 (label_ref (match_operand 0 "" ""))
5038 (pc)))]
5039 ""
5040 "
5041{ enum machine_mode mode = rs6000_compare_fp_p ? CCFPmode : CCmode;
5042 operands[1] = gen_rtx (COMPARE, mode,
5043 rs6000_compare_op0, rs6000_compare_op1);
5044 operands[2] = gen_reg_rtx (mode);
5045}")
5046
5047(define_expand "bne"
5048 [(set (match_dup 2) (match_dup 1))
5049 (set (pc)
5050 (if_then_else (ne (match_dup 2)
5051 (const_int 0))
5052 (label_ref (match_operand 0 "" ""))
5053 (pc)))]
5054 ""
5055 "
5056{ enum machine_mode mode = rs6000_compare_fp_p ? CCFPmode : CCmode;
5057 operands[1] = gen_rtx (COMPARE, mode,
5058 rs6000_compare_op0, rs6000_compare_op1);
5059 operands[2] = gen_reg_rtx (mode);
5060}")
5061
5062(define_expand "blt"
5063 [(set (match_dup 2) (match_dup 1))
5064 (set (pc)
5065 (if_then_else (lt (match_dup 2)
5066 (const_int 0))
5067 (label_ref (match_operand 0 "" ""))
5068 (pc)))]
5069 ""
5070 "
5071{ enum machine_mode mode = rs6000_compare_fp_p ? CCFPmode : CCmode;
5072 operands[1] = gen_rtx (COMPARE, mode,
5073 rs6000_compare_op0, rs6000_compare_op1);
5074 operands[2] = gen_reg_rtx (mode);
5075}")
5076
5077(define_expand "bgt"
5078 [(set (match_dup 2) (match_dup 1))
5079 (set (pc)
5080 (if_then_else (gt (match_dup 2)
5081 (const_int 0))
5082 (label_ref (match_operand 0 "" ""))
5083 (pc)))]
5084 ""
5085 "
5086{ enum machine_mode mode = rs6000_compare_fp_p ? CCFPmode : CCmode;
5087 operands[1] = gen_rtx (COMPARE, mode,
5088 rs6000_compare_op0, rs6000_compare_op1);
5089 operands[2] = gen_reg_rtx (mode);
5090}")
5091
5092(define_expand "ble"
5093 [(set (match_dup 2) (match_dup 1))
5094 (set (pc)
5095 (if_then_else (le (match_dup 2)
5096 (const_int 0))
5097 (label_ref (match_operand 0 "" ""))
5098 (pc)))]
5099 ""
5100 "
5101{ enum machine_mode mode = rs6000_compare_fp_p ? CCFPmode : CCmode;
5102 operands[1] = gen_rtx (COMPARE, mode,
5103 rs6000_compare_op0, rs6000_compare_op1);
5104 operands[2] = gen_reg_rtx (mode);
5105}")
5106
5107(define_expand "bge"
5108 [(set (match_dup 2) (match_dup 1))
5109 (set (pc)
5110 (if_then_else (ge (match_dup 2)
5111 (const_int 0))
5112 (label_ref (match_operand 0 "" ""))
5113 (pc)))]
5114 ""
5115 "
5116{ enum machine_mode mode = rs6000_compare_fp_p ? CCFPmode : CCmode;
5117 operands[1] = gen_rtx (COMPARE, mode,
5118 rs6000_compare_op0, rs6000_compare_op1);
5119 operands[2] = gen_reg_rtx (mode);
5120}")
5121
5122(define_expand "bgtu"
5123 [(set (match_dup 2) (match_dup 1))
5124 (set (pc)
5125 (if_then_else (gtu (match_dup 2)
5126 (const_int 0))
5127 (label_ref (match_operand 0 "" ""))
5128 (pc)))]
5129 ""
5130 "
5131{ operands[1] = gen_rtx (COMPARE, CCUNSmode,
5132 rs6000_compare_op0, rs6000_compare_op1);
5133 operands[2] = gen_reg_rtx (CCUNSmode);
5134}")
5135
5136(define_expand "bltu"
5137 [(set (match_dup 2) (match_dup 1))
5138 (set (pc)
5139 (if_then_else (ltu (match_dup 2)
5140 (const_int 0))
5141 (label_ref (match_operand 0 "" ""))
5142 (pc)))]
5143 ""
5144 "
5145{ operands[1] = gen_rtx (COMPARE, CCUNSmode,
5146 rs6000_compare_op0, rs6000_compare_op1);
5147 operands[2] = gen_reg_rtx (CCUNSmode);
5148}")
5149
5150(define_expand "bgeu"
5151 [(set (match_dup 2) (match_dup 1))
5152 (set (pc)
5153 (if_then_else (geu (match_dup 2)
5154 (const_int 0))
5155 (label_ref (match_operand 0 "" ""))
5156 (pc)))]
5157 ""
5158 "
5159{ operands[1] = gen_rtx (COMPARE, CCUNSmode,
5160 rs6000_compare_op0, rs6000_compare_op1);
5161 operands[2] = gen_reg_rtx (CCUNSmode);
5162}")
5163
5164(define_expand "bleu"
5165 [(set (match_dup 2) (match_dup 1))
5166 (set (pc)
5167 (if_then_else (leu (match_dup 2)
5168 (const_int 0))
5169 (label_ref (match_operand 0 "" ""))
5170 (pc)))]
5171 ""
5172 "
5173{ operands[1] = gen_rtx (COMPARE, CCUNSmode,
5174 rs6000_compare_op0, rs6000_compare_op1);
5175 operands[2] = gen_reg_rtx (CCUNSmode);
5176}")
5177
5178;; For SNE, we would prefer that the xor/abs sequence be used for integers.
5179;; For SEQ, likewise, except that comparisons with zero should be done
5180;; with an scc insns. However, due to the order that combine see the
5181;; resulting insns, we must, in fact, allow SEQ for integers. Fail in
5182;; the cases we don't want to handle.
5183(define_expand "seq"
5184 [(set (match_dup 2) (match_dup 1))
cd2b37d9 5185 (set (match_operand:SI 0 "gpc_reg_operand" "")
1fd4e8c1
RK
5186 (eq:SI (match_dup 2) (const_int 0)))]
5187 ""
5188 "
5189{ enum machine_mode mode = rs6000_compare_fp_p ? CCFPmode : CCmode;
5190 operands[1] = gen_rtx (COMPARE, mode,
5191 rs6000_compare_op0, rs6000_compare_op1);
5192 operands[2] = gen_reg_rtx (mode);
5193}")
5194
5195(define_expand "sne"
5196 [(set (match_dup 2) (match_dup 1))
cd2b37d9 5197 (set (match_operand:SI 0 "gpc_reg_operand" "")
1fd4e8c1
RK
5198 (ne:SI (match_dup 2) (const_int 0)))]
5199 ""
5200 "
5201{ if (! rs6000_compare_fp_p)
5202 FAIL;
5203
5204 operands[1] = gen_rtx (COMPARE, CCFPmode,
5205 rs6000_compare_op0, rs6000_compare_op1);
5206 operands[2] = gen_reg_rtx (CCFPmode);
5207}")
5208
5209;; A > 0 is best done using the portable sequence, so fail in that case.
5210(define_expand "sgt"
5211 [(set (match_dup 2) (match_dup 1))
cd2b37d9 5212 (set (match_operand:SI 0 "gpc_reg_operand" "")
1fd4e8c1
RK
5213 (gt:SI (match_dup 2) (const_int 0)))]
5214 ""
5215 "
5216{ enum machine_mode mode = rs6000_compare_fp_p ? CCFPmode : CCmode;
5217
5218 if (! rs6000_compare_fp_p && rs6000_compare_op1 == const0_rtx)
5219 FAIL;
5220
5221 operands[1] = gen_rtx (COMPARE, mode,
5222 rs6000_compare_op0, rs6000_compare_op1);
5223 operands[2] = gen_reg_rtx (mode);
5224}")
5225
5226;; A < 0 is best done in the portable way for A an integer.
5227(define_expand "slt"
5228 [(set (match_dup 2) (match_dup 1))
cd2b37d9 5229 (set (match_operand:SI 0 "gpc_reg_operand" "")
1fd4e8c1
RK
5230 (lt:SI (match_dup 2) (const_int 0)))]
5231 ""
5232 "
5233{ enum machine_mode mode = rs6000_compare_fp_p ? CCFPmode : CCmode;
5234
5235 if (! rs6000_compare_fp_p && rs6000_compare_op1 == const0_rtx)
5236 FAIL;
5237
5238 operands[1] = gen_rtx (COMPARE, mode,
5239 rs6000_compare_op0, rs6000_compare_op1);
5240 operands[2] = gen_reg_rtx (mode);
5241}")
5242
5243(define_expand "sge"
5244 [(set (match_dup 2) (match_dup 1))
cd2b37d9 5245 (set (match_operand:SI 0 "gpc_reg_operand" "")
1fd4e8c1
RK
5246 (ge:SI (match_dup 2) (const_int 0)))]
5247 ""
5248 "
5249{ enum machine_mode mode = rs6000_compare_fp_p ? CCFPmode : CCmode;
5250 operands[1] = gen_rtx (COMPARE, mode,
5251 rs6000_compare_op0, rs6000_compare_op1);
5252 operands[2] = gen_reg_rtx (mode);
5253}")
5254
5255;; A <= 0 is best done the portable way for A an integer.
5256(define_expand "sle"
5257 [(set (match_dup 2) (match_dup 1))
cd2b37d9 5258 (set (match_operand:SI 0 "gpc_reg_operand" "")
1fd4e8c1
RK
5259 (le:SI (match_dup 2) (const_int 0)))]
5260 ""
5261 "
5262{ enum machine_mode mode = rs6000_compare_fp_p ? CCFPmode : CCmode;
5263
5264 if (! rs6000_compare_fp_p && rs6000_compare_op1 == const0_rtx)
5265 FAIL;
5266
5267 operands[1] = gen_rtx (COMPARE, mode,
5268 rs6000_compare_op0, rs6000_compare_op1);
5269 operands[2] = gen_reg_rtx (mode);
5270}")
5271
5272(define_expand "sgtu"
5273 [(set (match_dup 2) (match_dup 1))
cd2b37d9 5274 (set (match_operand:SI 0 "gpc_reg_operand" "")
1fd4e8c1
RK
5275 (gtu:SI (match_dup 2) (const_int 0)))]
5276 ""
5277 "
5278{ operands[1] = gen_rtx (COMPARE, CCUNSmode,
5279 rs6000_compare_op0, rs6000_compare_op1);
5280 operands[2] = gen_reg_rtx (CCUNSmode);
5281}")
5282
5283(define_expand "sltu"
5284 [(set (match_dup 2) (match_dup 1))
cd2b37d9 5285 (set (match_operand:SI 0 "gpc_reg_operand" "")
1fd4e8c1
RK
5286 (ltu:SI (match_dup 2) (const_int 0)))]
5287 ""
5288 "
5289{ operands[1] = gen_rtx (COMPARE, CCUNSmode,
5290 rs6000_compare_op0, rs6000_compare_op1);
5291 operands[2] = gen_reg_rtx (CCUNSmode);
5292}")
5293
5294(define_expand "sgeu"
5295 [(set (match_dup 2) (match_dup 1))
cd2b37d9 5296 (set (match_operand:SI 0 "gpc_reg_operand" "")
1fd4e8c1
RK
5297 (geu:SI (match_dup 2) (const_int 0)))]
5298 ""
5299 "
5300{ operands[1] = gen_rtx (COMPARE, CCUNSmode,
5301 rs6000_compare_op0, rs6000_compare_op1);
5302 operands[2] = gen_reg_rtx (CCUNSmode);
5303}")
5304
5305(define_expand "sleu"
5306 [(set (match_dup 2) (match_dup 1))
cd2b37d9 5307 (set (match_operand:SI 0 "gpc_reg_operand" "")
1fd4e8c1
RK
5308 (leu:SI (match_dup 2) (const_int 0)))]
5309 ""
5310 "
5311{ operands[1] = gen_rtx (COMPARE, CCUNSmode,
5312 rs6000_compare_op0, rs6000_compare_op1);
5313 operands[2] = gen_reg_rtx (CCUNSmode);
5314}")
5315\f
5316;; Here are the actual compare insns.
5317(define_insn ""
5318 [(set (match_operand:CC 0 "cc_reg_operand" "=y")
cd2b37d9 5319 (compare:CC (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
5320 (match_operand:SI 2 "reg_or_short_operand" "rI")))]
5321 ""
7f340546 5322 "{cmp%I2|cmpw%I2} %0,%1,%2"
1fd4e8c1
RK
5323 [(set_attr "type" "compare")])
5324
f357808b
RK
5325;; If we are comparing a register for equality with a large constant,
5326;; we can do this with an XOR followed by a compare. But we need a scratch
5327;; register for the result of the XOR.
5328
5329(define_split
5330 [(set (match_operand:CC 0 "cc_reg_operand" "")
cd2b37d9 5331 (compare:CC (match_operand:SI 1 "gpc_reg_operand" "")
f357808b 5332 (match_operand:SI 2 "non_short_cint_operand" "")))
cd2b37d9 5333 (clobber (match_operand:SI 3 "gpc_reg_operand" ""))]
f357808b
RK
5334 "find_single_use (operands[0], insn, 0)
5335 && (GET_CODE (*find_single_use (operands[0], insn, 0)) == EQ
5336 || GET_CODE (*find_single_use (operands[0], insn, 0)) == NE)"
5337 [(set (match_dup 3) (xor:SI (match_dup 1) (match_dup 4)))
5338 (set (match_dup 0) (compare:CC (match_dup 3) (match_dup 5)))]
5339 "
5340{
5341 /* Get the constant we are comparing against, C, and see what it looks like
5342 sign-extended to 16 bits. Then see what constant could be XOR'ed
5343 with C to get the sign-extended value. */
5344
5345 int c = INTVAL (operands[2]);
5346 int sextc = (c << 16) >> 16;
5347 int xorv = c ^ sextc;
5348
5349 operands[4] = gen_rtx (CONST_INT, VOIDmode, xorv);
5350 operands[5] = gen_rtx (CONST_INT, VOIDmode, sextc);
5351}")
5352
1fd4e8c1
RK
5353(define_insn ""
5354 [(set (match_operand:CCUNS 0 "cc_reg_operand" "=y")
cd2b37d9 5355 (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
5356 (match_operand:SI 2 "reg_or_u_short_operand" "rI")))]
5357 ""
7f340546 5358 "{cmpl%I2|cmplw%I2} %0,%1,%W2"
1fd4e8c1
RK
5359 [(set_attr "type" "compare")])
5360
5361;; The following two insns don't exist as single insns, but if we provide
5362;; them, we can swap an add and compare, which will enable us to overlap more
5363;; of the required delay between a compare and branch. We generate code for
5364;; them by splitting.
5365
5366(define_insn ""
5367 [(set (match_operand:CC 3 "cc_reg_operand" "=y")
cd2b37d9 5368 (compare:CC (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 5369 (match_operand:SI 2 "short_cint_operand" "i")))
cd2b37d9 5370 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
5371 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "i")))]
5372 ""
baf97f86
RK
5373 "#"
5374 [(set_attr "length" "8")])
1fd4e8c1
RK
5375
5376(define_insn ""
5377 [(set (match_operand:CCUNS 3 "cc_reg_operand" "=y")
cd2b37d9 5378 (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 5379 (match_operand:SI 2 "u_short_cint_operand" "i")))
cd2b37d9 5380 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
5381 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "i")))]
5382 ""
baf97f86
RK
5383 "#"
5384 [(set_attr "length" "8")])
1fd4e8c1
RK
5385
5386(define_split
5387 [(set (match_operand:CC 3 "cc_reg_operand" "")
cd2b37d9 5388 (compare:CC (match_operand:SI 1 "gpc_reg_operand" "")
1fd4e8c1 5389 (match_operand:SI 2 "short_cint_operand" "")))
cd2b37d9 5390 (set (match_operand:SI 0 "gpc_reg_operand" "")
1fd4e8c1
RK
5391 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "")))]
5392 ""
5393 [(set (match_dup 3) (compare:CC (match_dup 1) (match_dup 2)))
5394 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 4)))])
5395
5396(define_split
5397 [(set (match_operand:CCUNS 3 "cc_reg_operand" "")
cd2b37d9 5398 (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "")
1fd4e8c1 5399 (match_operand:SI 2 "u_short_cint_operand" "")))
cd2b37d9 5400 (set (match_operand:SI 0 "gpc_reg_operand" "")
1fd4e8c1
RK
5401 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "")))]
5402 ""
5403 [(set (match_dup 3) (compare:CCUNS (match_dup 1) (match_dup 2)))
5404 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 4)))])
5405
5406(define_insn ""
5407 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
cd2b37d9
RK
5408 (compare:CCFP (match_operand:SF 1 "gpc_reg_operand" "f")
5409 (match_operand:SF 2 "gpc_reg_operand" "f")))]
d14a6d05 5410 "TARGET_HARD_FLOAT"
1fd4e8c1
RK
5411 "fcmpu %0,%1,%2"
5412 [(set_attr "type" "fpcompare")])
5413
5414(define_insn ""
5415 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
cd2b37d9
RK
5416 (compare:CCFP (match_operand:DF 1 "gpc_reg_operand" "f")
5417 (match_operand:DF 2 "gpc_reg_operand" "f")))]
d14a6d05 5418 "TARGET_HARD_FLOAT"
1fd4e8c1
RK
5419 "fcmpu %0,%1,%2"
5420 [(set_attr "type" "fpcompare")])
5421\f
5422;; Now we have the scc insns. We can do some combinations because of the
5423;; way the machine works.
5424;;
5425;; Note that this is probably faster if we can put an insn between the
c5defebb
RK
5426;; mfcr and rlinm, but this is tricky. Let's leave it for now. In most
5427;; cases the insns below which don't use an intermediate CR field will
5428;; be used instead.
1fd4e8c1 5429(define_insn ""
cd2b37d9 5430 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
5431 (match_operator:SI 1 "scc_comparison_operator"
5432 [(match_operand 2 "cc_reg_operand" "y")
5433 (const_int 0)]))]
5434 ""
ca7f5001 5435 "%D1mfcr %0\;{rlinm|rlwinm} %0,%0,%J1,1"
b19003d8 5436 [(set_attr "length" "12")])
1fd4e8c1
RK
5437
5438(define_insn ""
5439 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
5440 (compare:CC (match_operator:SI 1 "scc_comparison_operator"
5441 [(match_operand 2 "cc_reg_operand" "y")
5442 (const_int 0)])
5443 (const_int 0)))
cd2b37d9 5444 (set (match_operand:SI 3 "gpc_reg_operand" "=r")
1fd4e8c1
RK
5445 (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
5446 ""
ca7f5001 5447 "%D1mfcr %3\;{rlinm.|rlwinm.} %3,%3,%J1,1"
b19003d8
RK
5448 [(set_attr "type" "delayed_compare")
5449 (set_attr "length" "12")])
1fd4e8c1
RK
5450
5451(define_insn ""
cd2b37d9 5452 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
5453 (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
5454 [(match_operand 2 "cc_reg_operand" "y")
5455 (const_int 0)])
5456 (match_operand:SI 3 "const_int_operand" "n")))]
5457 ""
5458 "*
5459{
5460 int is_bit = ccr_bit (operands[1], 1);
5461 int put_bit = 31 - (INTVAL (operands[3]) & 31);
5462 int count;
5463
5464 if (is_bit >= put_bit)
5465 count = is_bit - put_bit;
5466 else
5467 count = 32 - (put_bit - is_bit);
5468
5469 operands[4] = gen_rtx (CONST_INT, VOIDmode, count);
5470 operands[5] = gen_rtx (CONST_INT, VOIDmode, put_bit);
5471
ca7f5001 5472 return \"%D1mfcr %0\;{rlinm|rlwinm} %0,%0,%4,%5,%5\";
b19003d8
RK
5473}"
5474 [(set_attr "length" "12")])
1fd4e8c1
RK
5475
5476(define_insn ""
5477 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
5478 (compare:CC
5479 (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
5480 [(match_operand 2 "cc_reg_operand" "y")
5481 (const_int 0)])
5482 (match_operand:SI 3 "const_int_operand" "n"))
5483 (const_int 0)))
cd2b37d9 5484 (set (match_operand:SI 4 "gpc_reg_operand" "=r")
1fd4e8c1
RK
5485 (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
5486 (match_dup 3)))]
5487 ""
5488 "*
5489{
5490 int is_bit = ccr_bit (operands[1], 1);
5491 int put_bit = 31 - (INTVAL (operands[3]) & 31);
5492 int count;
5493
5494 if (is_bit >= put_bit)
5495 count = is_bit - put_bit;
5496 else
5497 count = 32 - (put_bit - is_bit);
5498
5499 operands[5] = gen_rtx (CONST_INT, VOIDmode, count);
5500 operands[6] = gen_rtx (CONST_INT, VOIDmode, put_bit);
5501
ca7f5001 5502 return \"%D1mfcr %4\;{rlinm.|rlwinm.} %4,%4,%5,%6,%6\";
1fd4e8c1 5503}"
b19003d8
RK
5504 [(set_attr "type" "delayed_compare")
5505 (set_attr "length" "12")])
1fd4e8c1 5506
c5defebb
RK
5507;; If we are comparing the result of two comparisons, this can be done
5508;; using creqv or crxor.
5509
5510(define_insn ""
5511 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y")
5512 (compare:CCEQ (match_operator 1 "scc_comparison_operator"
5513 [(match_operand 2 "cc_reg_operand" "y")
5514 (const_int 0)])
5515 (match_operator 3 "scc_comparison_operator"
5516 [(match_operand 4 "cc_reg_operand" "y")
5517 (const_int 0)])))]
5518 "REGNO (operands[2]) != REGNO (operands[4])"
5519 "*
5520{
5521 enum rtx_code code1, code2;
5522
5523 code1 = GET_CODE (operands[1]);
5524 code2 = GET_CODE (operands[3]);
5525
5526 if ((code1 == EQ || code1 == LT || code1 == GT
5527 || code1 == LTU || code1 == GTU
5528 || (code1 != NE && GET_MODE (operands[2]) == CCFPmode))
5529 !=
5530 (code2 == EQ || code2 == LT || code2 == GT
5531 || code2 == LTU || code2 == GTU
5532 || (code2 != NE && GET_MODE (operands[4]) == CCFPmode)))
5533 return \"%C1%C3crxor %E0,%j1,%j3\";
5534 else
5535 return \"%C1%C3creqv %E0,%j1,%j3\";
b19003d8
RK
5536}"
5537 [(set_attr "length" "12")])
c5defebb
RK
5538
5539;; There is a 3 cycle delay between consecutive mfcr instructions
5540;; so it is useful to combine 2 scc instructions to use only one mfcr.
5541
5542(define_peephole
cd2b37d9 5543 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
c5defebb
RK
5544 (match_operator:SI 1 "scc_comparison_operator"
5545 [(match_operand 2 "cc_reg_operand" "y")
5546 (const_int 0)]))
cd2b37d9 5547 (set (match_operand:SI 3 "gpc_reg_operand" "=r")
c5defebb
RK
5548 (match_operator:SI 4 "scc_comparison_operator"
5549 [(match_operand 5 "cc_reg_operand" "y")
5550 (const_int 0)]))]
5551 "REGNO (operands[2]) != REGNO (operands[5])"
ca7f5001 5552 "%D1%D4mfcr %3\;{rlinm|rlwinm} %0,%3,%J1,1\;{rlinm|rlwinm} %3,%3,%J4,1"
b19003d8 5553 [(set_attr "length" "20")])
c5defebb 5554
1fd4e8c1
RK
5555;; There are some scc insns that can be done directly, without a compare.
5556;; These are faster because they don't involve the communications between
5557;; the FXU and branch units. In fact, we will be replacing all of the
5558;; integer scc insns here or in the portable methods in emit_store_flag.
5559;;
5560;; Also support (neg (scc ..)) since that construct is used to replace
5561;; branches, (plus (scc ..) ..) since that construct is common and
5562;; takes no more insns than scc, and (and (neg (scc ..)) ..) in the
5563;; cases where it is no more expensive than (neg (scc ..)).
5564
5565;; Have reload force a constant into a register for the simple insns that
5566;; otherwise won't accept constants. We do this because it is faster than
5567;; the cmp/mfcr sequence we would otherwise generate.
5568
5569(define_insn ""
cd2b37d9
RK
5570 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r,r")
5571 (eq:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r")
1fd4e8c1
RK
5572 (match_operand:SI 2 "reg_or_cint_operand" "r,O,K,J,I")))
5573 (clobber (match_scratch:SI 3 "=r,&r,r,r,r"))]
5574 ""
5575 "@
ca7f5001 5576 xor %0,%1,%2\;{sfi|subfic} %3,%0,0\;{ae|adde} %0,%3,%0
71d2371f 5577 {sfi|subfic} %3,%1,0\;{ae|adde} %0,%3,%1
ca7f5001
RK
5578 {xoril|xori} %0,%1,%b2\;{sfi|subfic} %3,%0,0\;{ae|adde} %0,%3,%0
5579 {xoriu|xoris} %0,%1,%u2\;{sfi|subfic} %3,%0,0\;{ae|adde} %0,%3,%0
5580 {sfi|subfic} %0,%1,%2\;{sfi|subfic} %3,%0,0\;{ae|adde} %0,%3,%0"
b19003d8 5581 [(set_attr "length" "12,8,12,12,12")])
1fd4e8c1
RK
5582
5583(define_insn ""
5584 [(set (match_operand:CC 4 "cc_reg_operand" "=x,x,x,x,x")
5585 (compare:CC
cd2b37d9 5586 (eq:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r")
1fd4e8c1
RK
5587 (match_operand:SI 2 "reg_or_cint_operand" "r,O,K,J,I"))
5588 (const_int 0)))
cd2b37d9 5589 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r,r")
1fd4e8c1
RK
5590 (eq:SI (match_dup 1) (match_dup 2)))
5591 (clobber (match_scratch:SI 3 "=r,&r,r,r,r"))]
5592 ""
5593 "@
ca7f5001
RK
5594 xor %0,%1,%2\;{sfi|subfic} %3,%0,0\;{ae.|adde.} %0,%3,%0
5595 {sfi|subfic} %3,%1,0\;{ae.|adde.} %0,%3,%1
5596 {xoril|xori} %0,%1,%b2\;{sfi|subfic} %3,%0,0\;{ae.|adde.} %0,%3,%0
5597 {xoriu|xoris} %0,%1,%u2\;{sfi|subfic} %3,%0,0\;{ae.|adde.} %0,%3,%0
5598 {sfi|subfic} %0,%1,%2\;{sfi|subfic} %3,%0,0\;{ae.|adde.} %0,%3,%0"
b19003d8
RK
5599 [(set_attr "type" "compare")
5600 (set_attr "length" "12,8,12,12,12")])
5601
5602;; We have insns of the form shown by the first define_insn below. If
5603;; there is something inside the comparison operation, we must split it.
5604(define_split
5605 [(set (match_operand:SI 0 "gpc_reg_operand" "")
5606 (plus:SI (match_operator 1 "comparison_operator"
5607 [(match_operand:SI 2 "" "")
5608 (match_operand:SI 3
5609 "reg_or_cint_operand" "")])
5610 (match_operand:SI 4 "gpc_reg_operand" "")))
5611 (clobber (match_operand:SI 5 "register_operand" ""))]
5612 "! gpc_reg_operand (operands[2], SImode)"
5613 [(set (match_dup 5) (match_dup 2))
5614 (set (match_dup 2) (plus:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
5615 (match_dup 4)))])
1fd4e8c1
RK
5616
5617(define_insn ""
cd2b37d9
RK
5618 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r,r")
5619 (plus:SI (eq:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r")
1fd4e8c1 5620 (match_operand:SI 2 "reg_or_cint_operand" "r,O,K,J,I"))
cd2b37d9 5621 (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r,r")))
1fd4e8c1
RK
5622 (clobber (match_scratch:SI 4 "=&r,&r,&r,&r,&r"))]
5623 ""
5624 "@
ca7f5001
RK
5625 xor %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze|addze} %0,%3
5626 {sfi|subfic} %4,%1,0\;{aze|addze} %0,%3
5627 {xoril|xori} %4,%1,%b2\;{sfi|subfic} %4,%4,0\;{aze|addze} %0,%3
5628 {xoriu|xoris} %4,%1,%u2\;{sfi|subfic} %4,%4,0\;{aze|addze} %0,%3
d9d934ef 5629 {sfi|subfic} %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze|addze} %0,%3"
b19003d8 5630 [(set_attr "length" "12,8,12,12,12")])
1fd4e8c1
RK
5631
5632(define_insn ""
5633 [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,x,x,x")
5634 (compare:CC
5635 (plus:SI
cd2b37d9 5636 (eq:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r")
1fd4e8c1 5637 (match_operand:SI 2 "reg_or_cint_operand" "r,O,K,J,I"))
cd2b37d9 5638 (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r,r"))
1fd4e8c1
RK
5639 (const_int 0)))
5640 (clobber (match_scratch:SI 4 "=&r,&r,&r,&r,&r"))]
5641 ""
5642 "@
ca7f5001
RK
5643 xor %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %4,%3
5644 {sfi|subfic} %4,%1,0\;{aze.|addze.} %0,%3
5645 {xoril|xori} %4,%1,%b2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %4,%3
5646 {xoriu|xoris} %4,%1,%u2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %4,%3
5647 {sfi|subfic} %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %4,%3"
b19003d8
RK
5648 [(set_attr "type" "compare")
5649 (set_attr "length" "12,8,12,12,12")])
1fd4e8c1
RK
5650
5651(define_insn ""
5652 [(set (match_operand:CC 5 "cc_reg_operand" "=x,x,x,x,x")
5653 (compare:CC
5654 (plus:SI
cd2b37d9 5655 (eq:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r")
1fd4e8c1 5656 (match_operand:SI 2 "reg_or_cint_operand" "r,O,K,J,I"))
cd2b37d9 5657 (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r,r"))
1fd4e8c1 5658 (const_int 0)))
cd2b37d9 5659 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r,r")
1fd4e8c1
RK
5660 (plus:SI (eq:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
5661 (clobber (match_scratch:SI 4 "=&r,&r,&r,&r,&r"))]
5662 ""
5663 "@
ca7f5001
RK
5664 xor %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %0,%3
5665 {sfi|subfic} %4,%1,0\;{aze.|addze.} %4,%3
5666 {xoril|xori} %4,%1,%b2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %0,%3
5667 {xoriu|xoris} %4,%1,%u2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %0,%3
5668 {sfi|subfic} %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %0,%3"
b19003d8
RK
5669 [(set_attr "type" "compare")
5670 (set_attr "length" "12,8,12,12,12")])
1fd4e8c1
RK
5671
5672(define_insn ""
cd2b37d9 5673 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r,r")
deb9225a 5674 (neg:SI (eq:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r")
1fd4e8c1
RK
5675 (match_operand:SI 2 "reg_or_cint_operand" "r,O,K,J,I"))))]
5676 ""
5677 "@
ca7f5001
RK
5678 xor %0,%1,%2\;{ai|addic} %0,%0,-1\;{sfe|subfe} %0,%0,%0
5679 {ai|addic} %0,%1,-1\;{sfe|subfe} %0,%0,%0
5680 {xoril|xori} %0,%1,%b2\;{ai|addic} %0,%0,-1\;{sfe|subfe} %0,%0,%0
5681 {xoriu|xoris} %0,%1,%u2\;{ai|addic} %0,%0,-1\;{sfe|subfe} %0,%0,%0
5682 {sfi|subfic} %0,%1,%2\;{ai|addic} %0,%0,-1\;{sfe|subfe} %0,%0,%0"
b19003d8 5683 [(set_attr "length" "12,8,12,12,12")])
1fd4e8c1
RK
5684
5685;; This is what (plus (ne X (const_int 0)) Y) looks like.
5686(define_insn ""
cd2b37d9 5687 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1 5688 (plus:SI (lshiftrt:SI
cd2b37d9 5689 (neg:SI (abs:SI (match_operand:SI 1 "gpc_reg_operand" "r")))
1fd4e8c1 5690 (const_int 31))
cd2b37d9 5691 (match_operand:SI 2 "gpc_reg_operand" "r")))
1fd4e8c1
RK
5692 (clobber (match_scratch:SI 3 "=&r"))]
5693 ""
ca7f5001 5694 "{ai|addic} %3,%1,-1\;{aze|addze} %0,%2"
b19003d8 5695 [(set_attr "length" "8")])
1fd4e8c1
RK
5696
5697(define_insn ""
5698 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
5699 (compare:CC
5700 (plus:SI (lshiftrt:SI
cd2b37d9 5701 (neg:SI (abs:SI (match_operand:SI 1 "gpc_reg_operand" "r")))
1fd4e8c1 5702 (const_int 31))
cd2b37d9 5703 (match_operand:SI 2 "gpc_reg_operand" "r"))
1fd4e8c1
RK
5704 (const_int 0)))
5705 (clobber (match_scratch:SI 3 "=&r"))]
5706 ""
ca7f5001 5707 "{ai|addic} %3,%1,-1\;{aze.|addze.} %3,%2"
b19003d8
RK
5708 [(set_attr "type" "compare")
5709 (set_attr "length" "8")])
1fd4e8c1
RK
5710
5711(define_insn ""
5712 [(set (match_operand:CC 4 "cc_reg_operand" "=x")
5713 (compare:CC
5714 (plus:SI (lshiftrt:SI
cd2b37d9 5715 (neg:SI (abs:SI (match_operand:SI 1 "gpc_reg_operand" "r")))
1fd4e8c1 5716 (const_int 31))
cd2b37d9 5717 (match_operand:SI 2 "gpc_reg_operand" "r"))
1fd4e8c1 5718 (const_int 0)))
cd2b37d9 5719 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
5720 (plus:SI (lshiftrt:SI (neg:SI (abs:SI (match_dup 1))) (const_int 31))
5721 (match_dup 2)))
5722 (clobber (match_scratch:SI 3 "=&r"))]
5723 ""
ca7f5001 5724 "{ai|addic} %3,%1,-1\;{aze.|addze.} %0,%2"
b19003d8
RK
5725 [(set_attr "type" "compare")
5726 (set_attr "length" "8")])
1fd4e8c1
RK
5727
5728(define_insn ""
cd2b37d9
RK
5729 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
5730 (le:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1
RK
5731 (match_operand:SI 2 "reg_or_short_operand" "r,O")))
5732 (clobber (match_scratch:SI 3 "=r,X"))]
ca7f5001 5733 "TARGET_POWER"
1fd4e8c1 5734 "@
ca7f5001 5735 doz %3,%2,%1\;{sfi|subfic} %0,%3,0\;{ae|adde} %0,%0,%3
7f340546 5736 {ai|addic} %0,%1,-1\;{aze|addze} %0,%0\;{sri|srwi} %0,%0,31"
b19003d8 5737 [(set_attr "length" "12")])
1fd4e8c1
RK
5738
5739(define_insn ""
5740 [(set (match_operand:CC 4 "cc_reg_operand" "=x,x")
5741 (compare:CC
cd2b37d9 5742 (le:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1
RK
5743 (match_operand:SI 2 "reg_or_short_operand" "r,O"))
5744 (const_int 0)))
cd2b37d9 5745 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
1fd4e8c1
RK
5746 (le:SI (match_dup 1) (match_dup 2)))
5747 (clobber (match_scratch:SI 3 "=r,X"))]
ca7f5001 5748 "TARGET_POWER"
1fd4e8c1 5749 "@
ca7f5001 5750 doz %3,%2,%1\;{sfi|subfic} %0,%3,0\;{ae.|adde.} %0,%0,%3
7f340546 5751 {ai|addic} %0,%1,-1\;{aze|addze} %0,%0\;{sri.|srwi.} %0,%0,31"
a473029f 5752 [(set_attr "type" "compare,delayed_compare")
b19003d8 5753 (set_attr "length" "12")])
1fd4e8c1
RK
5754
5755(define_insn ""
cd2b37d9
RK
5756 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
5757 (plus:SI (le:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1 5758 (match_operand:SI 2 "reg_or_short_operand" "r,O"))
cd2b37d9 5759 (match_operand:SI 3 "gpc_reg_operand" "r,r")))
1fd4e8c1 5760 (clobber (match_scratch:SI 4 "=&r,&r"))]
ca7f5001 5761 "TARGET_POWER"
1fd4e8c1 5762 "@
ca7f5001
RK
5763 doz %4,%2,%1\;{sfi|subfic} %4,%4,0\;{aze|addze} %0,%3
5764 {srai|srawi} %4,%1,31\;{sf|subfc} %4,%1,%4\;{aze|addze} %0,%3"
b19003d8 5765 [(set_attr "length" "12")])
1fd4e8c1
RK
5766
5767(define_insn ""
5768 [(set (match_operand:CC 0 "cc_reg_operand" "=x,x")
5769 (compare:CC
cd2b37d9 5770 (plus:SI (le:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1 5771 (match_operand:SI 2 "reg_or_short_operand" "r,O"))
cd2b37d9 5772 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
1fd4e8c1
RK
5773 (const_int 0)))
5774 (clobber (match_scratch:SI 4 "=&r,&r"))]
ca7f5001 5775 "TARGET_POWER"
1fd4e8c1 5776 "@
ca7f5001
RK
5777 doz %4,%2,%1\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %4,%3
5778 {srai|srawi} %4,%1,31\;{sf|subfc} %4,%1,%4\;{aze.|addze.} %4,%3"
b19003d8
RK
5779 [(set_attr "type" "compare")
5780 (set_attr "length" "12")])
1fd4e8c1
RK
5781
5782(define_insn ""
5783 [(set (match_operand:CC 5 "cc_reg_operand" "=x,x")
5784 (compare:CC
cd2b37d9 5785 (plus:SI (le:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1 5786 (match_operand:SI 2 "reg_or_short_operand" "r,O"))
cd2b37d9 5787 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
1fd4e8c1 5788 (const_int 0)))
cd2b37d9 5789 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
1fd4e8c1
RK
5790 (plus:SI (le:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
5791 (clobber (match_scratch:SI 4 "=&r,&r"))]
ca7f5001 5792 "TARGET_POWER"
1fd4e8c1 5793 "@
ca7f5001
RK
5794 doz %4,%2,%1\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %0,%3
5795 {srai|srawi} %4,%1,31\;{sf|subfc} %4,%1,%4\;{aze.|addze.} %0,%3"
b19003d8
RK
5796 [(set_attr "type" "compare")
5797 (set_attr "length" "12")])
1fd4e8c1
RK
5798
5799(define_insn ""
cd2b37d9
RK
5800 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
5801 (neg:SI (le:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1 5802 (match_operand:SI 2 "reg_or_short_operand" "r,O"))))]
ca7f5001 5803 "TARGET_POWER"
1fd4e8c1 5804 "@
ca7f5001
RK
5805 doz %0,%2,%1\;{ai|addic} %0,%0,-1\;{sfe|subfe} %0,%0,%0
5806 {ai|addic} %0,%1,-1\;{aze|addze} %0,%0\;{srai|srawi} %0,%0,31"
b19003d8 5807 [(set_attr "length" "12")])
1fd4e8c1
RK
5808
5809(define_insn ""
cd2b37d9
RK
5810 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
5811 (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
5812 (match_operand:SI 2 "reg_or_short_operand" "rI")))]
5813 ""
ca7f5001 5814 "{sf%I2|subf%I2c} %0,%1,%2\;{cal %0,0(0)|li %0,0}\;{ae|adde} %0,%0,%0"
b19003d8 5815 [(set_attr "length" "12")])
1fd4e8c1
RK
5816
5817(define_insn ""
5818 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
5819 (compare:CC
cd2b37d9 5820 (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
5821 (match_operand:SI 2 "reg_or_short_operand" "rI"))
5822 (const_int 0)))
cd2b37d9 5823 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
5824 (leu:SI (match_dup 1) (match_dup 2)))]
5825 ""
ca7f5001 5826 "{sf%I2|subf%I2c} %0,%1,%2\;{cal %0,0(0)|li %0,0}\;{ae.|adde.} %0,%0,%0"
b19003d8
RK
5827 [(set_attr "type" "compare")
5828 (set_attr "length" "12")])
1fd4e8c1
RK
5829
5830(define_insn ""
cd2b37d9
RK
5831 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
5832 (plus:SI (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 5833 (match_operand:SI 2 "reg_or_short_operand" "rI"))
cd2b37d9 5834 (match_operand:SI 3 "gpc_reg_operand" "r")))
1fd4e8c1
RK
5835 (clobber (match_scratch:SI 4 "=&r"))]
5836 ""
ca7f5001 5837 "{sf%I2|subf%I2c} %4,%1,%2\;{aze|addze} %0,%3"
b19003d8 5838 [(set_attr "length" "8")])
1fd4e8c1
RK
5839
5840(define_insn ""
5841 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
5842 (compare:CC
cd2b37d9 5843 (plus:SI (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 5844 (match_operand:SI 2 "reg_or_short_operand" "rI"))
cd2b37d9 5845 (match_operand:SI 3 "gpc_reg_operand" "r"))
1fd4e8c1
RK
5846 (const_int 0)))
5847 (clobber (match_scratch:SI 4 "=&r"))]
5848 ""
ca7f5001 5849 "{sf%I2|subf%I2c} %4,%1,%2\;{aze.|addze.} %4,%3"
b19003d8
RK
5850 [(set_attr "type" "compare")
5851 (set_attr "length" "8")])
1fd4e8c1
RK
5852
5853(define_insn ""
5854 [(set (match_operand:CC 5 "cc_reg_operand" "=x")
5855 (compare:CC
cd2b37d9 5856 (plus:SI (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 5857 (match_operand:SI 2 "reg_or_short_operand" "rI"))
cd2b37d9 5858 (match_operand:SI 3 "gpc_reg_operand" "r"))
1fd4e8c1 5859 (const_int 0)))
cd2b37d9 5860 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
5861 (plus:SI (leu:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
5862 (clobber (match_scratch:SI 4 "=&r"))]
5863 ""
ca7f5001 5864 "{sf%I2|subf%I2c} %4,%1,%2\;{aze.|addze.} %0,%3"
b19003d8
RK
5865 [(set_attr "type" "compare")
5866 (set_attr "length" "8")])
1fd4e8c1
RK
5867
5868(define_insn ""
cd2b37d9
RK
5869 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
5870 (neg:SI (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
5871 (match_operand:SI 2 "reg_or_short_operand" "rI"))))]
5872 ""
ca7f5001 5873 "{sf%I2|subf%I2c} %0,%1,%2\;{sfe|subfe} %0,%0,%0\;nand %0,%0,%0"
b19003d8 5874 [(set_attr "length" "12")])
1fd4e8c1
RK
5875
5876(define_insn ""
cd2b37d9 5877 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1 5878 (and:SI (neg:SI
cd2b37d9 5879 (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 5880 (match_operand:SI 2 "reg_or_short_operand" "rI")))
cd2b37d9 5881 (match_operand:SI 3 "gpc_reg_operand" "r")))
1fd4e8c1
RK
5882 (clobber (match_scratch:SI 4 "=&r"))]
5883 ""
ca7f5001 5884 "{sf%I2|subf%I2c} %4,%1,%2\;{sfe|subfe} %4,%4,%4\;andc %0,%3,%4"
b19003d8 5885 [(set_attr "length" "12")])
1fd4e8c1
RK
5886
5887(define_insn ""
5888 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
5889 (compare:CC
5890 (and:SI (neg:SI
cd2b37d9 5891 (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 5892 (match_operand:SI 2 "reg_or_short_operand" "rI")))
cd2b37d9 5893 (match_operand:SI 3 "gpc_reg_operand" "r"))
1fd4e8c1
RK
5894 (const_int 0)))
5895 (clobber (match_scratch:SI 4 "=&r"))]
5896 ""
ca7f5001 5897 "{sf%I2|subf%I2c} %4,%1,%2\;{sfe|subfe} %4,%4,%4\;andc. %4,%3,%4"
b19003d8
RK
5898 [(set_attr "type" "compare")
5899 (set_attr "length" "12")])
1fd4e8c1
RK
5900
5901(define_insn ""
5902 [(set (match_operand:CC 5 "cc_reg_operand" "=x")
5903 (compare:CC
5904 (and:SI (neg:SI
cd2b37d9 5905 (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 5906 (match_operand:SI 2 "reg_or_short_operand" "rI")))
cd2b37d9 5907 (match_operand:SI 3 "gpc_reg_operand" "r"))
1fd4e8c1 5908 (const_int 0)))
cd2b37d9 5909 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
5910 (and:SI (neg:SI (leu:SI (match_dup 1) (match_dup 2))) (match_dup 3)))
5911 (clobber (match_scratch:SI 4 "=&r"))]
5912 ""
ca7f5001 5913 "{sf%I2|subf%I2c} %4,%1,%2\;{sfe|subfe} %4,%4,%4\;andc. %0,%3,%4"
b19003d8
RK
5914 [(set_attr "type" "compare")
5915 (set_attr "length" "12")])
1fd4e8c1
RK
5916
5917(define_insn ""
cd2b37d9
RK
5918 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
5919 (lt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 5920 (match_operand:SI 2 "reg_or_short_operand" "rI")))]
ca7f5001 5921 "TARGET_POWER"
7f340546 5922 "doz%I2 %0,%1,%2\;nabs %0,%0\;{sri|srwi} %0,%0,31"
b19003d8 5923 [(set_attr "length" "12")])
1fd4e8c1
RK
5924
5925(define_insn ""
ad8bd902 5926 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1fd4e8c1 5927 (compare:CC
cd2b37d9 5928 (lt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
5929 (match_operand:SI 2 "reg_or_short_operand" "rI"))
5930 (const_int 0)))
cd2b37d9 5931 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1 5932 (lt:SI (match_dup 1) (match_dup 2)))]
ca7f5001 5933 "TARGET_POWER"
7f340546 5934 "doz%I2 %0,%1,%2\;nabs %0,%0\;{sri.|srwi.} %0,%0,31"
b19003d8
RK
5935 [(set_attr "type" "delayed_compare")
5936 (set_attr "length" "12")])
1fd4e8c1
RK
5937
5938(define_insn ""
cd2b37d9
RK
5939 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
5940 (plus:SI (lt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 5941 (match_operand:SI 2 "reg_or_short_operand" "rI"))
cd2b37d9 5942 (match_operand:SI 3 "gpc_reg_operand" "r")))
1fd4e8c1 5943 (clobber (match_scratch:SI 4 "=&r"))]
ca7f5001
RK
5944 "TARGET_POWER"
5945 "doz%I2 %4,%1,%2\;{ai|addic} %4,%4,-1\;{aze|addze} %0,%3"
b19003d8 5946 [(set_attr "length" "12")])
1fd4e8c1
RK
5947
5948(define_insn ""
ad8bd902 5949 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
1fd4e8c1 5950 (compare:CC
cd2b37d9 5951 (plus:SI (lt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 5952 (match_operand:SI 2 "reg_or_short_operand" "rI"))
cd2b37d9 5953 (match_operand:SI 3 "gpc_reg_operand" "r"))
1fd4e8c1
RK
5954 (const_int 0)))
5955 (clobber (match_scratch:SI 4 "=&r"))]
ca7f5001
RK
5956 "TARGET_POWER"
5957 "doz%I2 %4,%1,%2\;{ai|addic} %4,%4,-1\;{aze.|addze.} %4,%3"
b19003d8
RK
5958 [(set_attr "type" "compare")
5959 (set_attr "length" "12")])
1fd4e8c1
RK
5960
5961(define_insn ""
ad8bd902 5962 [(set (match_operand:CC 5 "cc_reg_operand" "=x")
1fd4e8c1 5963 (compare:CC
cd2b37d9 5964 (plus:SI (lt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 5965 (match_operand:SI 2 "reg_or_short_operand" "rI"))
cd2b37d9 5966 (match_operand:SI 3 "gpc_reg_operand" "r"))
1fd4e8c1 5967 (const_int 0)))
cd2b37d9 5968 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
5969 (plus:SI (lt:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
5970 (clobber (match_scratch:SI 4 "=&r"))]
ca7f5001
RK
5971 "TARGET_POWER"
5972 "doz%I2 %4,%1,%2\;{ai|addic} %4,%4,-1\;{aze.|addze.} %0,%3"
b19003d8
RK
5973 [(set_attr "type" "compare")
5974 (set_attr "length" "12")])
1fd4e8c1
RK
5975
5976(define_insn ""
cd2b37d9
RK
5977 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
5978 (neg:SI (lt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 5979 (match_operand:SI 2 "reg_or_short_operand" "rI"))))]
ca7f5001
RK
5980 "TARGET_POWER"
5981 "doz%I2 %0,%1,%2\;nabs %0,%0\;{srai|srawi} %0,%0,31"
b19003d8 5982 [(set_attr "length" "12")])
1fd4e8c1
RK
5983
5984(define_insn ""
cd2b37d9
RK
5985 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
5986 (ltu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1
RK
5987 (match_operand:SI 2 "reg_or_neg_short_operand" "r,P")))]
5988 ""
5989 "@
ca7f5001
RK
5990 {sf|subfc} %0,%2,%1\;{sfe|subfe} %0,%0,%0\;neg %0,%0
5991 {ai|addic} %0,%1,%n2\;{sfe|subfe} %0,%0,%0\;neg %0,%0"
b19003d8 5992 [(set_attr "length" "12")])
1fd4e8c1
RK
5993
5994(define_insn ""
5995 [(set (match_operand:CC 3 "cc_reg_operand" "=x,x")
5996 (compare:CC
cd2b37d9 5997 (ltu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1
RK
5998 (match_operand:SI 2 "reg_or_neg_short_operand" "r,P"))
5999 (const_int 0)))
cd2b37d9 6000 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
1fd4e8c1
RK
6001 (ltu:SI (match_dup 1) (match_dup 2)))]
6002 ""
6003 "@
ca7f5001
RK
6004 {sf|subfc} %0,%2,%1\;{sfe|subfe} %0,%0,%0\;neg. %0,%0
6005 {ai|addic} %0,%1,%n2\;{sfe|subfe} %0,%0,%0\;neg. %0,%0"
b19003d8
RK
6006 [(set_attr "type" "compare")
6007 (set_attr "length" "12")])
1fd4e8c1
RK
6008
6009(define_insn ""
cd2b37d9
RK
6010 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r")
6011 (plus:SI (ltu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r")
1fd4e8c1
RK
6012 (match_operand:SI 2 "reg_or_neg_short_operand" "r,r,P,P"))
6013 (match_operand:SI 3 "reg_or_short_operand" "r,I,r,I")))
6014 (clobber (match_scratch:SI 4 "=&r,r,&r,r"))]
6015 ""
6016 "@
ca7f5001
RK
6017 {sf|subfc} %4,%2,%1\;{sfe|subfe} %4,%4,%4\;{sf%I3|subf%I3c} %0,%4,%3
6018 {sf|subfc} %4,%2,%1\;{sfe|subfe} %4,%4,%4\;{sf%I3|subf%I3c} %0,%4,%3
6019 {ai|addic} %4,%1,%n2\;{sfe|subfe} %4,%4,%4\;{sf%I3|subf%I3c} %0,%4,%3
6020 {ai|addic} %4,%1,%n2\;{sfe|subfe} %4,%4,%4\;{sf%I3|subf%I3c} %0,%4,%3"
b19003d8 6021 [(set_attr "length" "12")])
1fd4e8c1
RK
6022
6023(define_insn ""
3d91674b 6024 [(set (match_operand:CC 0 "cc_reg_operand" "=x,x")
1fd4e8c1 6025 (compare:CC
3d91674b
RK
6026 (plus:SI (ltu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
6027 (match_operand:SI 2 "reg_or_neg_short_operand" "r,P"))
6028 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
1fd4e8c1 6029 (const_int 0)))
3d91674b 6030 (clobber (match_scratch:SI 4 "=&r,&r"))]
1fd4e8c1
RK
6031 ""
6032 "@
ca7f5001
RK
6033 {sf|subfc} %4,%2,%1\;{sfe|subfe} %4,%4,%4\;{sf.|subfc.} %4,%4,%3
6034 {ai|addic} %4,%1,%n2\;{sfe|subfe} %4,%4,%4\;{sf.|subfc.} %4,%4,%3"
b19003d8
RK
6035 [(set_attr "type" "compare")
6036 (set_attr "length" "12")])
1fd4e8c1
RK
6037
6038(define_insn ""
3d91674b 6039 [(set (match_operand:CC 5 "cc_reg_operand" "=x,x")
1fd4e8c1 6040 (compare:CC
3d91674b
RK
6041 (plus:SI (ltu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
6042 (match_operand:SI 2 "reg_or_neg_short_operand" "r,P"))
6043 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
1fd4e8c1 6044 (const_int 0)))
3d91674b 6045 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
1fd4e8c1 6046 (plus:SI (ltu:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
3d91674b 6047 (clobber (match_scratch:SI 4 "=&r,&r"))]
1fd4e8c1
RK
6048 ""
6049 "@
ca7f5001
RK
6050 {sf|subfc} %4,%2,%1\;{sfe|subfe} %4,%4,%4\;{sf.|subfc.} %0,%4,%3
6051 {ai|addic} %4,%1,%n2\;{sfe|subfe} %4,%4,%4\;{sf.|subfc.} %0,%4,%3"
b19003d8
RK
6052 [(set_attr "type" "compare")
6053 (set_attr "length" "12")])
1fd4e8c1
RK
6054
6055(define_insn ""
cd2b37d9
RK
6056 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
6057 (neg:SI (ltu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1
RK
6058 (match_operand:SI 2 "reg_or_neg_short_operand" "r,P"))))]
6059 ""
6060 "@
ca7f5001
RK
6061 {sf|subfc} %0,%2,%1\;{sfe|subfe} %0,%0,%0
6062 {ai|addic} %0,%1,%n2\;{sfe|subfe} %0,%0,%0"
b19003d8 6063 [(set_attr "length" "8")])
1fd4e8c1
RK
6064
6065(define_insn ""
cd2b37d9
RK
6066 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6067 (ge:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
6068 (match_operand:SI 2 "reg_or_short_operand" "rI")))
6069 (clobber (match_scratch:SI 3 "=r"))]
ca7f5001
RK
6070 "TARGET_POWER"
6071 "doz%I2 %3,%1,%2\;{sfi|subfic} %0,%3,0\;{ae|adde} %0,%0,%3"
b19003d8 6072 [(set_attr "length" "12")])
1fd4e8c1
RK
6073
6074(define_insn ""
6075 [(set (match_operand:CC 4 "cc_reg_operand" "=x")
6076 (compare:CC
cd2b37d9 6077 (ge:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
6078 (match_operand:SI 2 "reg_or_short_operand" "rI"))
6079 (const_int 0)))
cd2b37d9 6080 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
6081 (ge:SI (match_dup 1) (match_dup 2)))
6082 (clobber (match_scratch:SI 3 "=r"))]
ca7f5001
RK
6083 "TARGET_POWER"
6084 "doz%I2 %3,%1,%2\;{sfi|subfic} %0,%3,0\;{ae.|adde.} %0,%0,%3"
b19003d8
RK
6085 [(set_attr "type" "compare")
6086 (set_attr "length" "12")])
1fd4e8c1
RK
6087
6088(define_insn ""
cd2b37d9
RK
6089 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6090 (plus:SI (ge:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 6091 (match_operand:SI 2 "reg_or_short_operand" "rI"))
cd2b37d9 6092 (match_operand:SI 3 "gpc_reg_operand" "r")))
1fd4e8c1 6093 (clobber (match_scratch:SI 4 "=&r"))]
ca7f5001
RK
6094 "TARGET_POWER"
6095 "doz%I2 %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze|addze} %0,%3"
b19003d8 6096 [(set_attr "length" "12")])
1fd4e8c1
RK
6097
6098(define_insn ""
6099 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
6100 (compare:CC
cd2b37d9 6101 (plus:SI (ge:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 6102 (match_operand:SI 2 "reg_or_short_operand" "rI"))
cd2b37d9 6103 (match_operand:SI 3 "gpc_reg_operand" "r"))
1fd4e8c1
RK
6104 (const_int 0)))
6105 (clobber (match_scratch:SI 4 "=&r"))]
ca7f5001
RK
6106 "TARGET_POWER"
6107 "doz%I2 %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %4,%3"
b19003d8
RK
6108 [(set_attr "type" "compare")
6109 (set_attr "length" "12")])
1fd4e8c1
RK
6110
6111(define_insn ""
6112 [(set (match_operand:CC 5 "cc_reg_operand" "=x")
6113 (compare:CC
cd2b37d9 6114 (plus:SI (ge:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 6115 (match_operand:SI 2 "reg_or_short_operand" "rI"))
cd2b37d9 6116 (match_operand:SI 3 "gpc_reg_operand" "r"))
1fd4e8c1 6117 (const_int 0)))
cd2b37d9 6118 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
6119 (plus:SI (ge:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
6120 (clobber (match_scratch:SI 4 "=&r"))]
ca7f5001
RK
6121 "TARGET_POWER"
6122 "doz%I2 %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %0,%3"
b19003d8
RK
6123 [(set_attr "type" "compare")
6124 (set_attr "length" "12")])
1fd4e8c1
RK
6125
6126(define_insn ""
cd2b37d9
RK
6127 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6128 (neg:SI (ge:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 6129 (match_operand:SI 2 "reg_or_short_operand" "rI"))))]
ca7f5001
RK
6130 "TARGET_POWER"
6131 "doz%I2 %0,%1,%2\;{ai|addic} %0,%0,-1\;{sfe|subfe} %0,%0,%0"
b19003d8 6132 [(set_attr "length" "12")])
1fd4e8c1
RK
6133
6134;; This is (and (neg (ge X (const_int 0))) Y).
6135(define_insn ""
cd2b37d9 6136 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
6137 (and:SI (neg:SI
6138 (lshiftrt:SI
cd2b37d9 6139 (not:SI (match_operand:SI 1 "gpc_reg_operand" "r"))
1fd4e8c1 6140 (const_int 31)))
cd2b37d9 6141 (match_operand:SI 2 "gpc_reg_operand" "r")))
1fd4e8c1
RK
6142 (clobber (match_scratch:SI 3 "=&r"))]
6143 ""
ca7f5001 6144 "{srai|srawi} %3,%1,31\;andc %0,%2,%3"
b19003d8 6145 [(set_attr "length" "8")])
1fd4e8c1
RK
6146
6147(define_insn ""
6148 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
6149 (compare:CC
6150 (and:SI (neg:SI
6151 (lshiftrt:SI
cd2b37d9 6152 (not:SI (match_operand:SI 1 "gpc_reg_operand" "r"))
1fd4e8c1 6153 (const_int 31)))
cd2b37d9 6154 (match_operand:SI 2 "gpc_reg_operand" "r"))
1fd4e8c1
RK
6155 (const_int 0)))
6156 (clobber (match_scratch:SI 3 "=&r"))]
6157 ""
ca7f5001 6158 "{srai|srawi} %3,%1,31\;andc. %3,%2,%3"
b19003d8
RK
6159 [(set_attr "type" "compare")
6160 (set_attr "length" "8")])
1fd4e8c1
RK
6161
6162(define_insn ""
6163 [(set (match_operand:CC 4 "cc_reg_operand" "=x")
6164 (compare:CC
6165 (and:SI (neg:SI
6166 (lshiftrt:SI
cd2b37d9 6167 (not:SI (match_operand:SI 1 "gpc_reg_operand" "r"))
1fd4e8c1 6168 (const_int 31)))
cd2b37d9 6169 (match_operand:SI 2 "gpc_reg_operand" "r"))
1fd4e8c1 6170 (const_int 0)))
cd2b37d9 6171 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
6172 (and:SI (neg:SI (lshiftrt:SI (not:SI (match_dup 1))
6173 (const_int 31)))
6174 (match_dup 2)))
6175 (clobber (match_scratch:SI 3 "=&r"))]
6176 ""
ca7f5001 6177 "{srai|srawi} %3,%1,31\;andc. %0,%2,%3"
b19003d8
RK
6178 [(set_attr "type" "compare")
6179 (set_attr "length" "8")])
1fd4e8c1
RK
6180
6181(define_insn ""
cd2b37d9
RK
6182 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
6183 (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1
RK
6184 (match_operand:SI 2 "reg_or_neg_short_operand" "r,P")))]
6185 ""
6186 "@
ca7f5001
RK
6187 {sf|subfc} %0,%2,%1\;{cal %0,0(0)|li %0,0}\;{ae|adde} %0,%0,%0
6188 {ai|addic} %0,%1,%n2\;{cal %0,0(0)|li %0,0}\;{ae|adde} %0,%0,%0"
b19003d8 6189 [(set_attr "length" "12")])
1fd4e8c1
RK
6190
6191(define_insn ""
6192 [(set (match_operand:CC 3 "cc_reg_operand" "=x,x")
6193 (compare:CC
cd2b37d9 6194 (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1
RK
6195 (match_operand:SI 2 "reg_or_neg_short_operand" "r,P"))
6196 (const_int 0)))
cd2b37d9 6197 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
1fd4e8c1
RK
6198 (geu:SI (match_dup 1) (match_dup 2)))]
6199 ""
6200 "@
ca7f5001
RK
6201 {sf|subfc} %0,%2,%1\;{cal %0,0(0)|li %0,0}\;{ae.|adde.} %0,%0,%0
6202 {ai|addic} %0,%1,%n2\;{cal %0,0(0)|li %0,0}\;{ae.|adde.} %0,%0,%0"
b19003d8
RK
6203 [(set_attr "type" "compare")
6204 (set_attr "length" "12")])
1fd4e8c1
RK
6205
6206(define_insn ""
cd2b37d9
RK
6207 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
6208 (plus:SI (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1 6209 (match_operand:SI 2 "reg_or_neg_short_operand" "r,P"))
cd2b37d9 6210 (match_operand:SI 3 "gpc_reg_operand" "r,r")))
1fd4e8c1
RK
6211 (clobber (match_scratch:SI 4 "=&r,&r"))]
6212 ""
6213 "@
ca7f5001
RK
6214 {sf|subfc} %4,%2,%1\;{aze|addze} %0,%3
6215 {ai|addic} %4,%1,%n2\;{aze|addze} %0,%3"
b19003d8 6216 [(set_attr "length" "8")])
1fd4e8c1
RK
6217
6218(define_insn ""
6219 [(set (match_operand:CC 0 "cc_reg_operand" "=x,x")
6220 (compare:CC
cd2b37d9 6221 (plus:SI (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1 6222 (match_operand:SI 2 "reg_or_neg_short_operand" "r,P"))
cd2b37d9 6223 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
1fd4e8c1
RK
6224 (const_int 0)))
6225 (clobber (match_scratch:SI 4 "=&r,&r"))]
6226 ""
6227 "@
ca7f5001
RK
6228 {sf|subfc} %4,%2,%1\;{aze.|addze.} %4,%3
6229 {ai|addic} %4,%1,%n2\;{aze.|addze.} %4,%3"
b19003d8
RK
6230 [(set_attr "type" "compare")
6231 (set_attr "length" "8")])
1fd4e8c1
RK
6232
6233(define_insn ""
6234 [(set (match_operand:CC 5 "cc_reg_operand" "=x,x")
6235 (compare:CC
cd2b37d9 6236 (plus:SI (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1 6237 (match_operand:SI 2 "reg_or_neg_short_operand" "r,P"))
cd2b37d9 6238 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
1fd4e8c1 6239 (const_int 0)))
cd2b37d9 6240 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
1fd4e8c1
RK
6241 (plus:SI (geu:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
6242 (clobber (match_scratch:SI 4 "=&r,&r"))]
6243 ""
6244 "@
ca7f5001
RK
6245 {sf|subfc} %4,%2,%1\;{aze.|addze.} %0,%3
6246 {ai|addic} %4,%1,%n2\;{aze.|addze.} %4,%3"
b19003d8
RK
6247 [(set_attr "type" "compare")
6248 (set_attr "length" "8")])
1fd4e8c1
RK
6249
6250(define_insn ""
cd2b37d9
RK
6251 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
6252 (neg:SI (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1
RK
6253 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))]
6254 ""
6255 "@
ca7f5001
RK
6256 {sf|subfc} %0,%2,%1\;{sfe|subfe} %0,%0,%0\;nand %0,%0,%0
6257 {sfi|subfic} %0,%1,-1\;a%I2 %0,%0,%2\;{sfe|subfe} %0,%0,%0"
b19003d8 6258 [(set_attr "length" "12")])
1fd4e8c1
RK
6259
6260(define_insn ""
cd2b37d9 6261 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
1fd4e8c1 6262 (and:SI (neg:SI
cd2b37d9 6263 (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1 6264 (match_operand:SI 2 "reg_or_neg_short_operand" "r,P")))
cd2b37d9 6265 (match_operand:SI 3 "gpc_reg_operand" "r,r")))
1fd4e8c1
RK
6266 (clobber (match_scratch:SI 4 "=&r,&r"))]
6267 ""
6268 "@
ca7f5001
RK
6269 {sf|subfc} %4,%2,%1\;{sfe|subfe} %4,%4,%4\;andc %0,%3,%4
6270 {ai|addic} %4,%1,%n2\;{sfe|subfe} %4,%4,%4\;andc %0,%3,%4"
b19003d8 6271 [(set_attr "length" "12")])
1fd4e8c1
RK
6272
6273(define_insn ""
6274 [(set (match_operand:CC 0 "cc_reg_operand" "=x,x")
6275 (compare:CC
6276 (and:SI (neg:SI
cd2b37d9 6277 (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1 6278 (match_operand:SI 2 "reg_or_neg_short_operand" "r,P")))
cd2b37d9 6279 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
1fd4e8c1
RK
6280 (const_int 0)))
6281 (clobber (match_scratch:SI 4 "=&r,&r"))]
6282 ""
6283 "@
ca7f5001
RK
6284 {sf|subfc} %4,%2,%1\;{sfe|subfe} %4,%4,%4\;andc. %4,%3,%4
6285 {ai|addic} %4,%1,%n2\;{sfe|subfe} %4,%4,%4\;andc. %4,%3,%4"
b19003d8
RK
6286 [(set_attr "type" "compare")
6287 (set_attr "length" "12")])
1fd4e8c1
RK
6288
6289(define_insn ""
6290 [(set (match_operand:CC 5 "cc_reg_operand" "=x,x")
6291 (compare:CC
6292 (and:SI (neg:SI
cd2b37d9 6293 (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1 6294 (match_operand:SI 2 "reg_or_neg_short_operand" "r,P")))
cd2b37d9 6295 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
1fd4e8c1 6296 (const_int 0)))
cd2b37d9 6297 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
1fd4e8c1
RK
6298 (and:SI (neg:SI (geu:SI (match_dup 1) (match_dup 2))) (match_dup 3)))
6299 (clobber (match_scratch:SI 4 "=&r,&r"))]
6300 ""
6301 "@
ca7f5001
RK
6302 {sf|subfc} %4,%2,%1\;{sfe|subfe} %4,%4,%4\;andc. %0,%3,%4
6303 {ai|addic} %4,%1,%n2\;{sfe|subfe} %4,%4,%4\;andc. %0,%3,%4"
b19003d8
RK
6304 [(set_attr "type" "compare")
6305 (set_attr "length" "12")])
1fd4e8c1
RK
6306
6307(define_insn ""
cd2b37d9
RK
6308 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6309 (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
6310 (const_int 0)))]
6311 ""
ca7f5001 6312 "{sfi|subfic} %0,%1,0\;{ame|addme} %0,%0\;{sri|srwi} %0,%0,31"
b19003d8 6313 [(set_attr "length" "12")])
1fd4e8c1
RK
6314
6315(define_insn ""
6316 [(set (match_operand:CC 2 "cc_reg_operand" "=x")
6317 (compare:CC
cd2b37d9 6318 (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
6319 (const_int 0))
6320 (const_int 0)))
cd2b37d9 6321 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
6322 (gt:SI (match_dup 1) (const_int 0)))]
6323 ""
ca7f5001 6324 "{sfi|subfic} %0,%1,0\;{ame|addme} %0,%0\;{sri.|srwi.} %0,%0,31"
b19003d8
RK
6325 [(set_attr "type" "delayed_compare")
6326 (set_attr "length" "12")])
1fd4e8c1
RK
6327
6328(define_insn ""
cd2b37d9
RK
6329 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6330 (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 6331 (match_operand:SI 2 "reg_or_short_operand" "r")))]
ca7f5001
RK
6332 "TARGET_POWER"
6333 "doz %0,%2,%1\;nabs %0,%0\;{sri|srwi} %0,%0,31"
b19003d8 6334 [(set_attr "length" "12")])
1fd4e8c1
RK
6335
6336(define_insn ""
6337 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
6338 (compare:CC
cd2b37d9 6339 (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
6340 (match_operand:SI 2 "reg_or_short_operand" "r"))
6341 (const_int 0)))
cd2b37d9 6342 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1 6343 (gt:SI (match_dup 1) (match_dup 2)))]
ca7f5001
RK
6344 "TARGET_POWER"
6345 "doz %0,%2,%1\;nabs %0,%0\;{sri.|srwi.} %0,%0,31"
b19003d8
RK
6346 [(set_attr "type" "delayed_compare")
6347 (set_attr "length" "12")])
1fd4e8c1
RK
6348
6349(define_insn ""
cd2b37d9
RK
6350 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6351 (plus:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 6352 (const_int 0))
cd2b37d9 6353 (match_operand:SI 2 "gpc_reg_operand" "r")))
1fd4e8c1
RK
6354 (clobber (match_scratch:SI 3 "=&r"))]
6355 ""
ca7f5001 6356 "{a|addc} %3,%1,%1\;{sfe|subfe} %3,%1,%3\;{aze|addze} %0,%2"
b19003d8 6357 [(set_attr "length" "12")])
1fd4e8c1
RK
6358
6359(define_insn ""
6360 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
6361 (compare:CC
cd2b37d9 6362 (plus:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 6363 (const_int 0))
cd2b37d9 6364 (match_operand:SI 2 "gpc_reg_operand" "r"))
1fd4e8c1
RK
6365 (const_int 0)))
6366 (clobber (match_scratch:SI 3 "=&r"))]
6367 ""
ca7f5001 6368 "{a|addc} %3,%1,%1\;{sfe|subfe} %3,%1,%3\;{aze.|addze.} %0,%2"
b19003d8
RK
6369 [(set_attr "type" "compare")
6370 (set_attr "length" "12")])
1fd4e8c1
RK
6371
6372(define_insn ""
6373 [(set (match_operand:CC 4 "cc_reg_operand" "=x")
6374 (compare:CC
cd2b37d9 6375 (plus:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 6376 (const_int 0))
cd2b37d9 6377 (match_operand:SI 2 "gpc_reg_operand" "r"))
1fd4e8c1 6378 (const_int 0)))
cd2b37d9 6379 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
6380 (plus:SI (gt:SI (match_dup 1) (const_int 0)) (match_dup 2)))
6381 (clobber (match_scratch:SI 3 "=&r"))]
6382 ""
ca7f5001 6383 "{a|addc} %3,%1,%1\;{sfe|subfe} %3,%1,%3\;{aze.|addze.} %3,%2"
b19003d8
RK
6384 [(set_attr "type" "compare")
6385 (set_attr "length" "12")])
1fd4e8c1
RK
6386
6387(define_insn ""
cd2b37d9
RK
6388 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6389 (plus:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 6390 (match_operand:SI 2 "reg_or_short_operand" "r"))
cd2b37d9 6391 (match_operand:SI 3 "gpc_reg_operand" "r")))
1fd4e8c1 6392 (clobber (match_scratch:SI 4 "=&r"))]
ca7f5001
RK
6393 "TARGET_POWER"
6394 "doz %4,%2,%1\;{ai|addic} %4,%4,-1\;{aze|addze} %0,%3"
b19003d8 6395 [(set_attr "length" "12")])
1fd4e8c1
RK
6396
6397(define_insn ""
6398 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
6399 (compare:CC
cd2b37d9 6400 (plus:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 6401 (match_operand:SI 2 "reg_or_short_operand" "r"))
cd2b37d9 6402 (match_operand:SI 3 "gpc_reg_operand" "r"))
1fd4e8c1
RK
6403 (const_int 0)))
6404 (clobber (match_scratch:SI 4 "=&r"))]
ca7f5001
RK
6405 "TARGET_POWER"
6406 "doz %4,%2,%1\;{ai|addic} %4,%4,-1\;{aze.|addze.} %4,%3"
b19003d8
RK
6407 [(set_attr "type" "compare")
6408 (set_attr "length" "12")])
1fd4e8c1
RK
6409
6410(define_insn ""
6411 [(set (match_operand:CC 5 "cc_reg_operand" "=x")
6412 (compare:CC
cd2b37d9 6413 (plus:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 6414 (match_operand:SI 2 "reg_or_short_operand" "r"))
cd2b37d9 6415 (match_operand:SI 3 "gpc_reg_operand" "r"))
1fd4e8c1 6416 (const_int 0)))
cd2b37d9 6417 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
6418 (plus:SI (gt:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
6419 (clobber (match_scratch:SI 4 "=&r"))]
ca7f5001
RK
6420 "TARGET_POWER"
6421 "doz %4,%2,%1\;{ai|addic} %4,%4,-1\;{aze.|addze.} %0,%3"
b19003d8
RK
6422 [(set_attr "type" "compare")
6423 (set_attr "length" "12")])
1fd4e8c1
RK
6424
6425(define_insn ""
cd2b37d9
RK
6426 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6427 (neg:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
6428 (const_int 0))))]
6429 ""
ca7f5001 6430 "{sfi|subfic} %0,%1,0\;{ame|addme} %0,%0\;{srai|srawi} %0,%0,31"
b19003d8 6431 [(set_attr "length" "12")])
1fd4e8c1
RK
6432
6433(define_insn ""
cd2b37d9
RK
6434 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6435 (neg:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 6436 (match_operand:SI 2 "reg_or_short_operand" "r"))))]
ca7f5001
RK
6437 "TARGET_POWER"
6438 "doz %0,%2,%1\;nabs %0,%0\;{srai|srawi} %0,%0,31"
b19003d8 6439 [(set_attr "length" "12")])
1fd4e8c1
RK
6440
6441(define_insn ""
cd2b37d9
RK
6442 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6443 (gtu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
6444 (match_operand:SI 2 "reg_or_short_operand" "rI")))]
6445 ""
ca7f5001 6446 "{sf%I2|subf%I2c} %0,%1,%2\;{sfe|subfe} %0,%0,%0\;neg %0,%0"
b19003d8 6447 [(set_attr "length" "12")])
1fd4e8c1
RK
6448
6449(define_insn ""
6450 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
6451 (compare:CC
cd2b37d9 6452 (gtu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
6453 (match_operand:SI 2 "reg_or_short_operand" "rI"))
6454 (const_int 0)))
cd2b37d9 6455 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
6456 (gtu:SI (match_dup 1) (match_dup 2)))]
6457 ""
ca7f5001 6458 "{sf%I2|subf%I2c} %0,%1,%2\;{sfe|subfe} %0,%0,%0\;neg. %0,%0"
b19003d8
RK
6459 [(set_attr "type" "compare")
6460 (set_attr "length" "12")])
1fd4e8c1
RK
6461
6462(define_insn ""
00751805
RK
6463 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r")
6464 (plus:SI (gtu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r")
6465 (match_operand:SI 2 "reg_or_short_operand" "I,r,rI"))
6466 (match_operand:SI 3 "reg_or_short_operand" "r,r,I")))
6467 (clobber (match_scratch:SI 4 "=&r,&r,&r"))]
1fd4e8c1 6468 ""
00751805 6469 "@
ca7f5001
RK
6470 {ai|addic} %4,%1,%k2\;{aze|addze} %0,%3
6471 {sf%I2|subf%I2c} %4,%1,%2\;{sfe|subfe} %4,%4,%4\;{sf%I3|subf%I3c} %0,%4,%3
6472 {sf%I2|subf%I2c} %4,%1,%2\;{sfe|subfe} %4,%4,%4\;{sf%I3|subf%I3c} %0,%4,%3"
b19003d8 6473 [(set_attr "length" "8,12,12")])
1fd4e8c1
RK
6474
6475(define_insn ""
3d91674b 6476 [(set (match_operand:CC 0 "cc_reg_operand" "=x,x")
1fd4e8c1 6477 (compare:CC
3d91674b
RK
6478 (plus:SI (gtu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
6479 (match_operand:SI 2 "reg_or_short_operand" "I,r"))
6480 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
1fd4e8c1 6481 (const_int 0)))
3d91674b 6482 (clobber (match_scratch:SI 4 "=&r,&r"))]
1fd4e8c1 6483 ""
00751805 6484 "@
ca7f5001
RK
6485 {ai|addic} %4,%1,%k2\;{aze.|addze.} %0,%3
6486 {sf%I2|subf%I2c} %4,%1,%2\;{sfe|subfe} %4,%4,%4\;{sf.|subfc.} %0,%4,%3"
b19003d8 6487 [(set_attr "type" "compare")
3d91674b 6488 (set_attr "length" "8,12")])
1fd4e8c1
RK
6489
6490(define_insn ""
3d91674b 6491 [(set (match_operand:CC 5 "cc_reg_operand" "=x,x")
1fd4e8c1 6492 (compare:CC
3d91674b
RK
6493 (plus:SI (gtu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
6494 (match_operand:SI 2 "reg_or_short_operand" "I,r"))
6495 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
1fd4e8c1 6496 (const_int 0)))
3d91674b 6497 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
1fd4e8c1 6498 (plus:SI (gtu:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
3d91674b 6499 (clobber (match_scratch:SI 4 "=&r,&r"))]
1fd4e8c1 6500 ""
00751805 6501 "@
ca7f5001
RK
6502 {ai|addic} %4,%1,%k2\;{aze.|addze.} %0,%3
6503 {sf%I2|subf%I2c} %4,%1,%2\;{sfe|subfe} %4,%4,%4\;{sf.|subfc.} %0,%4,%3"
b19003d8 6504 [(set_attr "type" "compare")
3d91674b 6505 (set_attr "length" "8,12")])
1fd4e8c1
RK
6506
6507(define_insn ""
cd2b37d9
RK
6508 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6509 (neg:SI (gtu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
6510 (match_operand:SI 2 "reg_or_short_operand" "rI"))))]
6511 ""
ca7f5001 6512 "{sf%I2|subf%I2c} %0,%1,%2\;{sfe|subfe} %0,%0,%0"
b19003d8 6513 [(set_attr "length" "8")])
1fd4e8c1
RK
6514\f
6515;; Define both directions of branch and return. If we need a reload
6516;; register, we'd rather use CR0 since it is much easier to copy a
6517;; register CC value to there.
6518
6519(define_insn ""
6520 [(set (pc)
6521 (if_then_else (match_operator 1 "branch_comparison_operator"
6522 [(match_operand 2
6523 "cc_reg_operand" "x,?y")
6524 (const_int 0)])
6525 (label_ref (match_operand 0 "" ""))
6526 (pc)))]
6527 ""
b19003d8
RK
6528 "*
6529{
6530 if (get_attr_length (insn) == 8)
6531 return \"%C1bc %t1,%j1,%l0\";
6532 else
6533 return \"%C1bc %T1,%j1,$+8\;b %l0\";
6534}"
6535 [(set_attr "type" "branch")])
6536
1fd4e8c1
RK
6537(define_insn ""
6538 [(set (pc)
6539 (if_then_else (match_operator 0 "branch_comparison_operator"
6540 [(match_operand 1
6541 "cc_reg_operand" "x,?y")
6542 (const_int 0)])
6543 (return)
6544 (pc)))]
6545 "direct_return ()"
ca7f5001 6546 "{%C0bcr|%C0bclr} %t0,%j0"
b19003d8 6547 [(set_attr "length" "8")])
1fd4e8c1
RK
6548
6549(define_insn ""
6550 [(set (pc)
6551 (if_then_else (match_operator 1 "branch_comparison_operator"
6552 [(match_operand 2
6553 "cc_reg_operand" "x,?y")
6554 (const_int 0)])
6555 (pc)
6556 (label_ref (match_operand 0 "" ""))))]
6557 ""
b19003d8
RK
6558 "*
6559{
6560 if (get_attr_length (insn) == 8)
6561 return \"%C1bc %T1,%j1,%l0\";
6562 else
6563 return \"%C1bc %t1,%j1,$+8\;b %l0\";
6564}"
6565 [(set_attr "type" "branch")])
1fd4e8c1
RK
6566
6567(define_insn ""
6568 [(set (pc)
6569 (if_then_else (match_operator 0 "branch_comparison_operator"
6570 [(match_operand 1
6571 "cc_reg_operand" "x,?y")
6572 (const_int 0)])
6573 (pc)
6574 (return)))]
6575 "direct_return ()"
ca7f5001 6576 "{%C0bcr|%C0bclr} %T0,%j0"
b19003d8 6577 [(set_attr "length" "8")])
1fd4e8c1
RK
6578
6579;; Unconditional branch and return.
6580
6581(define_insn "jump"
6582 [(set (pc)
6583 (label_ref (match_operand 0 "" "")))]
6584 ""
6585 "b %l0")
6586
6587(define_insn "return"
6588 [(return)]
6589 "direct_return ()"
324e52cc
TG
6590 "{br|blr}"
6591 [(set_attr "type" "jmpreg")])
1fd4e8c1
RK
6592
6593(define_insn "indirect_jump"
6594 [(set (pc) (match_operand:SI 0 "register_operand" "c,l"))]
6595 ""
6596 "@
6597 bctr
324e52cc
TG
6598 {br|blr}"
6599 [(set_attr "type" "jmpreg")])
1fd4e8c1
RK
6600
6601;; Table jump for switch statements:
6602(define_expand "tablejump"
6603 [(set (match_dup 3)
6604 (plus:SI (match_operand:SI 0 "" "")
6605 (match_dup 2)))
6606 (parallel [(set (pc) (match_dup 3))
6607 (use (label_ref (match_operand 1 "" "")))])]
6608 ""
6609 "
6610{ operands[0] = force_reg (SImode, operands[0]);
6611 operands[2] = force_reg (SImode, gen_rtx (LABEL_REF, VOIDmode, operands[1]));
6612 operands[3] = gen_reg_rtx (SImode);
6613}")
6614
6615(define_insn ""
6616 [(set (pc)
740ab4a2 6617 (match_operand:SI 0 "register_operand" "c,l"))
1fd4e8c1
RK
6618 (use (label_ref (match_operand 1 "" "")))]
6619 ""
6620 "@
6621 bctr
ca7f5001 6622 {br|blr}")
1fd4e8c1
RK
6623
6624(define_insn "nop"
6625 [(const_int 0)]
6626 ""
ca7f5001 6627 "{cror 0,0,0|nop}")
1fd4e8c1 6628\f
c225ba7b
RK
6629;; Define the subtract-one-and-jump insns, starting with the template
6630;; so loop.c knows what to generate.
6631
6632(define_expand "decrement_and_branchsi"
6633 [(parallel [(set (pc) (if_then_else (ne (match_operand:SI 0 "register_operand" "c")
6634 (const_int 1))
6635 (label_ref (match_operand 1 "" ""))
6636 (pc)))
6637 (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))])]
6638 ""
6639 "")
6640
1fd4e8c1
RK
6641;; We need to be able to do this for any operand, including MEM, or we
6642;; will cause reload to blow up since we don't allow output reloads on
6643;; JUMP_INSNs.
6644(define_insn ""
6645 [(set (pc)
6646 (if_then_else (ne (match_operand:SI 1 "register_operand" "0,*r,*r")
6647 (const_int 1))
6648 (label_ref (match_operand 2 "" ""))
6649 (pc)))
6650 (set (match_operand:SI 0 "register_operand" "=c,*r,m*q*c*l")
6651 (plus:SI (match_dup 1) (const_int -1)))
6652 (clobber (match_scratch:CC 3 "=X,&x,&x"))
6653 (clobber (match_scratch:SI 4 "=X,X,r"))]
6654 ""
b19003d8
RK
6655 "*
6656{
af87a13e 6657 if (which_alternative != 0)
b19003d8
RK
6658 return \"#\";
6659 else if (get_attr_length (insn) == 8)
ca7f5001 6660 return \"{bdn|bdnz} %l2\";
b19003d8
RK
6661 else
6662 return \"bdz $+8\;b %l2\";
6663}"
baf97f86
RK
6664 [(set_attr "type" "branch")
6665 (set_attr "length" "*,12,16")])
1fd4e8c1 6666
c225ba7b 6667;; Similar, but we can use GE since we have a REG_NONNEG.
1fd4e8c1
RK
6668(define_insn ""
6669 [(set (pc)
6670 (if_then_else (ge (match_operand:SI 1 "register_operand" "0,*r,*r")
6671 (const_int 0))
6672 (label_ref (match_operand 2 "" ""))
6673 (pc)))
6674 (set (match_operand:SI 0 "register_operand" "=c,*r,m*q*c*l")
6675 (plus:SI (match_dup 1) (const_int -1)))
6676 (clobber (match_scratch:CC 3 "=X,&x,&X"))
6677 (clobber (match_scratch:SI 4 "=X,X,r"))]
6678 "find_reg_note (insn, REG_NONNEG, 0)"
b19003d8
RK
6679 "*
6680{
af87a13e 6681 if (which_alternative != 0)
b19003d8
RK
6682 return \"#\";
6683 else if (get_attr_length (insn) == 8)
ca7f5001 6684 return \"{bdn|bdnz} %l2\";
b19003d8
RK
6685 else
6686 return \"bdz $+8\;b %l2\";
6687}"
baf97f86
RK
6688 [(set_attr "type" "branch")
6689 (set_attr "length" "*,12,16")])
1fd4e8c1
RK
6690
6691(define_insn ""
6692 [(set (pc)
6693 (if_then_else (eq (match_operand:SI 1 "register_operand" "0,*r,*r")
6694 (const_int 1))
6695 (label_ref (match_operand 2 "" ""))
6696 (pc)))
6697 (set (match_operand:SI 0 "register_operand" "=c,*r,m*q*c*l")
6698 (plus:SI (match_dup 1) (const_int -1)))
6699 (clobber (match_scratch:CC 3 "=X,&x,&x"))
6700 (clobber (match_scratch:SI 4 "=X,X,r"))]
6701 ""
b19003d8
RK
6702 "*
6703{
af87a13e 6704 if (which_alternative != 0)
b19003d8
RK
6705 return \"#\";
6706 else if (get_attr_length (insn) == 8)
6707 return \"bdz %l2\";
6708 else
ca7f5001 6709 return \"{bdn|bdnz} $+8\;b %l2\";
b19003d8 6710}"
baf97f86
RK
6711 [(set_attr "type" "branch")
6712 (set_attr "length" "*,12,16")])
1fd4e8c1
RK
6713
6714(define_split
6715 [(set (pc)
6716 (if_then_else (match_operator 2 "comparison_operator"
cd2b37d9 6717 [(match_operand:SI 1 "gpc_reg_operand" "")
1fd4e8c1
RK
6718 (const_int 1)])
6719 (match_operand 5 "" "")
6720 (match_operand 6 "" "")))
cd2b37d9 6721 (set (match_operand:SI 0 "gpc_reg_operand" "")
1fd4e8c1
RK
6722 (plus:SI (match_dup 1) (const_int -1)))
6723 (clobber (match_scratch:CC 3 ""))
6724 (clobber (match_scratch:SI 4 ""))]
6725 "reload_completed"
6726 [(parallel [(set (match_dup 3)
6727 (compare:CC (plus:SI (match_dup 1) (const_int -1))
6728 (const_int 0)))
6729 (set (match_dup 0) (plus:SI (match_dup 1) (const_int -1)))])
6730 (set (pc) (if_then_else (match_dup 7) (match_dup 5) (match_dup 6)))]
6731 "
6732{ operands[7] = gen_rtx (GET_CODE (operands[2]), VOIDmode, operands[3],
6733 const0_rtx); }")
6734
6735(define_split
6736 [(set (pc)
6737 (if_then_else (match_operator 2 "comparison_operator"
cd2b37d9 6738 [(match_operand:SI 1 "gpc_reg_operand" "")
1fd4e8c1
RK
6739 (const_int 1)])
6740 (match_operand 5 "" "")
6741 (match_operand 6 "" "")))
6742 (set (match_operand:SI 0 "general_operand" "")
6743 (plus:SI (match_dup 1) (const_int -1)))
6744 (clobber (match_scratch:CC 3 ""))
6745 (clobber (match_scratch:SI 4 ""))]
cd2b37d9 6746 "reload_completed && ! gpc_reg_operand (operands[0], SImode)"
1fd4e8c1
RK
6747 [(parallel [(set (match_dup 3)
6748 (compare:CC (plus:SI (match_dup 1) (const_int -1))
6749 (const_int 0)))
6750 (set (match_dup 4) (plus:SI (match_dup 1) (const_int -1)))])
6751 (set (match_dup 0) (match_dup 4))
6752 (set (pc) (if_then_else (match_dup 7) (match_dup 5) (match_dup 6)))]
6753 "
6754{ operands[7] = gen_rtx (GET_CODE (operands[2]), VOIDmode, operands[3],
6755 const0_rtx); }")