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