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