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