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