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