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