]> gcc.gnu.org Git - gcc.git/blame - gcc/config/rs6000/rs6000.md
Add set_attr for "length" when we are going to split an insn at output time.
[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"
baf97f86
RK
2449 "#"
2450 [(set_attr "length" "8")])
1fd4e8c1
RK
2451
2452(define_split
cd2b37d9
RK
2453 [(set (match_operand:DI 0 "gpc_reg_operand" "=")
2454 (plus:DI (zero_extend:DI (match_operand:SI 1 "gpc_reg_operand" ""))
1fd4e8c1
RK
2455 (match_operand:DI 2 "immediate_operand" "")))]
2456 "reload_completed && HOST_BITS_PER_INT == BITS_PER_WORD
2457 && GET_CODE (operands[2]) == CONST_DOUBLE
2458 && CONST_DOUBLE_LOW (operands[2]) == 0"
2459 [(set (match_dup 3) (match_dup 4))
2460 (set (match_dup 5) (match_dup 1))]
2461 "
2462{ operands[3] = operand_subword (operands[0], 0, 0, DImode);
2463 operands[4] = operand_subword (operands[2], 0, 0, DImode);
2464 operands[5] = operand_subword (operands[0], 1, 0, DImode);
2465
2466 if (rtx_equal_p (operands[1], operands[5]))
2467 {
2468 emit_move_insn (operands[3], operands[4]);
2469 DONE;
2470 }
c283c989
RK
2471
2472 if (rtx_equal_p (operands[1], operands[3]))
2473 {
2474 rtx temp;
2475
2476 temp = operands[3]; operands[3] = operands[5]; operands[5] = temp;
2477 temp = operands[4]; operands[4] = operands[1]; operands[1] = temp;
2478 }
1fd4e8c1
RK
2479}")
2480
2481(define_insn ""
cd2b37d9
RK
2482 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2483 (plus:DI (zero_extend:DI (match_operand:SI 1 "gpc_reg_operand" "r"))
1fd4e8c1
RK
2484 (match_operand:DI 2 "immediate_operand" "n")))]
2485 "HOST_BITS_PER_INT == BITS_PER_WORD
2486 && GET_CODE (operands[2]) == CONST_DOUBLE
2487 && CONST_DOUBLE_LOW (operands[2]) == 0"
baf97f86
RK
2488 "#"
2489 [(set_attr "length" "8")])
1fd4e8c1
RK
2490
2491(define_expand "fix_truncdfsi2"
cd2b37d9 2492 [(set (match_operand:SI 0 "gpc_reg_operand" "")
b542afe9 2493 (fix:SI (match_operand:DF 1 "gpc_reg_operand" "")))]
1fd4e8c1
RK
2494 ""
2495 "
2496{
2497 emit_insn (gen_trunc_call (operands[0], operands[1],
2498 gen_rtx (SYMBOL_REF, Pmode, \"itrunc\")));
2499 DONE;
2500}")
2501
2502(define_expand "fixuns_truncdfsi2"
cd2b37d9 2503 [(set (match_operand:SI 0 "gpc_reg_operand" "")
b542afe9 2504 (unsigned_fix:SI (match_operand:DF 1 "gpc_reg_operand" "")))]
1fd4e8c1
RK
2505 ""
2506 "
2507{
2508 emit_insn (gen_trunc_call (operands[0], operands[1],
2509 gen_rtx (SYMBOL_REF, Pmode, \"uitrunc\")));
2510 DONE;
2511}")
2512
2513
2514(define_expand "trunc_call"
2515 [(parallel [(set (match_operand:SI 0 "" "")
b542afe9 2516 (fix:SI (match_operand:DF 1 "" "")))
1fd4e8c1
RK
2517 (use (match_operand:SI 2 "" ""))])]
2518 ""
2519 "
2520{
2521 rtx insns = gen_trunc_call_rtl (operands[0], operands[1], operands[2]);
2522 rtx first = XVECEXP (insns, 0, 0);
2523 rtx last = XVECEXP (insns, 0, XVECLEN (insns, 0) - 1);
2524
2525 REG_NOTES (first) = gen_rtx (INSN_LIST, REG_LIBCALL, last,
2526 REG_NOTES (first));
2527 REG_NOTES (last) = gen_rtx (INSN_LIST, REG_RETVAL, first, REG_NOTES (last));
2528
2529 emit_insn (insns);
2530 DONE;
2531}")
2532
2533(define_expand "trunc_call_rtl"
cd2b37d9 2534 [(set (reg:DF 33) (match_operand:DF 1 "gpc_reg_operand" ""))
1fd4e8c1
RK
2535 (use (reg:DF 33))
2536 (parallel [(set (reg:SI 3)
2537 (call (mem:SI (match_operand 2 "" "")) (const_int 0)))
2538 (clobber (scratch:SI))])
cd2b37d9 2539 (set (match_operand:SI 0 "gpc_reg_operand" "")
1fd4e8c1
RK
2540 (reg:SI 3))]
2541 ""
2542 "
2543{
2544 rs6000_trunc_used = 1;
2545}")
2546\f
2547;; Define the DImode operations that can be done in a small number
2548;; of instructions.
ca7f5001
RK
2549(define_expand "adddi3"
2550 [(set (match_operand:DI 0 "gpc_reg_operand" "")
2551 (plus:DI (match_operand:DI 1 "gpc_reg_operand" "")
2552 (match_operand:DI 2 "reg_or_short_operand" "")))]
2553 ""
2554 "
2555{
2556 if (TARGET_POWERPC
2557 && short_cint_operand (operands[2], DImode))
2558 FAIL;
2559}")
2560
2561(define_insn ""
fa5679bb
RK
2562 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
2563 (plus:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r")
2564 (match_operand:DI 2 "reg_or_short_operand" "r,I")))]
ca7f5001 2565 "TARGET_POWER"
fa5679bb 2566 "@
ca7f5001
RK
2567 {a|addc} %L0,%L1,%L2\;{ae|adde} %0,%1,%2
2568 {ai|addic} %L0,%L1,%2\;{a%G2e|add%G2e} %0,%1"
b19003d8 2569 [(set_attr "length" "8")])
1fd4e8c1 2570
ca7f5001
RK
2571(define_insn ""
2572 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2573 (plus:DI (match_operand:DI 1 "gpc_reg_operand" "%r")
2574 (match_operand:DI 2 "gpc_reg_operand" "r")))]
2575 "TARGET_POWERPC"
2576 "addc %L0,%L1,%L2\;adde %0,%1,%2"
2577 [(set_attr "length" "8")])
2578
2579(define_expand "subdi3"
fa5679bb
RK
2580 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
2581 (minus:DI (match_operand:DI 1 "reg_or_short_operand" "r,I")
2582 (match_operand:DI 2 "gpc_reg_operand" "r,r")))]
1fd4e8c1 2583 ""
ca7f5001
RK
2584 "
2585{
2586 if (TARGET_POWERPC
2587 && short_cint_operand (operands[1], DImode))
2588 FAIL;
2589}")
2590
2591(define_insn ""
2592 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
2593 (minus:DI (match_operand:DI 1 "reg_or_short_operand" "r,I")
2594 (match_operand:DI 2 "gpc_reg_operand" "r,r")))]
2595 "TARGET_POWER"
fa5679bb 2596 "@
ca7f5001
RK
2597 {sf|subfc} %L0,%L2,%L1\;{sfe|subfe} %0,%2,%1
2598 {sfi|subfic} %L0,%L2,%1\;{sf%G1e|subf%G1e} %0,%2"
b19003d8 2599 [(set_attr "length" "8")])
1fd4e8c1 2600
ca7f5001
RK
2601(define_insn ""
2602 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2603 (minus:DI (match_operand:DI 1 "gpc_reg_operand" "r")
2604 (match_operand:DI 2 "gpc_reg_operand" "r")))]
2605 "TARGET_POWERPC"
2606 "subfc %L0,%L2,%L1\;subfe %0,%2,%1"
2607 [(set_attr "length" "8")])
2608
2609(define_expand "negdi2"
cd2b37d9
RK
2610 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2611 (neg:DI (match_operand:DI 1 "gpc_reg_operand" "r")))]
1fd4e8c1 2612 ""
ca7f5001
RK
2613 "")
2614
2615(define_insn ""
2616 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2617 (neg:DI (match_operand:DI 1 "gpc_reg_operand" "r")))]
2618 "TARGET_POWER"
2619 "{sfi|subfic} %L0,%L1,0\;{sfze|subfze} %0,%1"
2620 [(set_attr "length" "8")])
2621
2622(define_insn ""
2623 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2624 (neg:DI (match_operand:DI 1 "gpc_reg_operand" "r")))]
2625 "TARGET_POWERPC"
2626 "subfic %L0,%L1,0\;subfze %0,%1"
b19003d8 2627 [(set_attr "length" "8")])
1fd4e8c1
RK
2628
2629(define_insn "mulsidi3"
cd2b37d9
RK
2630 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2631 (mult:DI (sign_extend:DI (match_operand:SI 1 "gpc_reg_operand" "r"))
2632 (sign_extend:DI (match_operand:SI 2 "gpc_reg_operand" "r"))))
1fd4e8c1 2633 (clobber (match_scratch:SI 3 "=q"))]
ca7f5001 2634 "TARGET_POWER"
b19003d8
RK
2635 "mul %0,%1,%2\;mfmq %L0"
2636 [(set_attr "length" "8")])
1fd4e8c1
RK
2637
2638;; If operands 0 and 2 are in the same register, we have a problem. But
2639;; operands 0 and 1 (the usual case) can be in the same register. That's
2640;; why we have the strange constraints below.
2641(define_insn "ashldi3"
cd2b37d9
RK
2642 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,&r")
2643 (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,0,r")
1fd4e8c1
RK
2644 (match_operand:SI 2 "reg_or_cint_operand" "M,i,r,r")))
2645 (clobber (match_scratch:SI 3 "=X,q,q,q"))]
ca7f5001 2646 "TARGET_POWER"
1fd4e8c1 2647 "@
ca7f5001 2648 {sli|slwi} %0,%L1,%h2\;{cal %L0,0(0)|li %L0,0}
1fd4e8c1
RK
2649 sl%I2q %L0,%L1,%h2\;sll%I2q %0,%1,%h2
2650 sl%I2q %L0,%L1,%h2\;sll%I2q %0,%1,%h2
b19003d8
RK
2651 sl%I2q %L0,%L1,%h2\;sll%I2q %0,%1,%h2"
2652 [(set_attr "length" "8")])
1fd4e8c1
RK
2653
2654(define_insn "lshrdi3"
cd2b37d9
RK
2655 [(set (match_operand:DI 0 "gpc_reg_operand" "=&r,r,r,&r")
2656 (lshiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,0,r")
1fd4e8c1
RK
2657 (match_operand:SI 2 "reg_or_cint_operand" "M,i,r,r")))
2658 (clobber (match_scratch:SI 3 "=X,q,q,q"))]
ca7f5001 2659 "TARGET_POWER"
1fd4e8c1 2660 "@
ca7f5001 2661 {cal %0,0(0)|li %0,0}\;{s%A2i|s%A2wi} %L0,%1,%h2
46a48c7f
RK
2662 sr%I2q %0,%1,%h2\;srl%I2q %L0,%L1,%h2
2663 sr%I2q %0,%1,%h2\;srl%I2q %L0,%L1,%h2
b19003d8
RK
2664 sr%I2q %0,%1,%h2\;srl%I2q %L0,%L1,%h2"
2665 [(set_attr "length" "8")])
1fd4e8c1
RK
2666
2667;; Shift by a variable amount is too complex to be worth open-coding. We
2668;; just handle shifts by constants.
2669
2670(define_expand "ashrdi3"
cd2b37d9
RK
2671 [(parallel [(set (match_operand:DI 0 "gpc_reg_operand" "=")
2672 (ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "")
1fd4e8c1
RK
2673 (match_operand:SI 2 "general_operand" "")))
2674 (clobber (match_scratch:SI 3 ""))])]
ca7f5001 2675 "TARGET_POWER"
1fd4e8c1
RK
2676 "
2677{ if (GET_CODE (operands[2]) != CONST_INT)
2678 FAIL;
2679}")
2680
2681(define_insn ""
cd2b37d9
RK
2682 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
2683 (ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
1fd4e8c1
RK
2684 (match_operand:SI 2 "const_int_operand" "M,i")))
2685 (clobber (match_scratch:SI 3 "=X,q"))]
ca7f5001 2686 "TARGET_POWER"
1fd4e8c1 2687 "@
ca7f5001 2688 {srai|srawi} %0,%1,31\;{srai|srawi} %L0,%1,%h2
b19003d8
RK
2689 sraiq %0,%1,%h2\;srliq %L0,%L1,%h2"
2690 [(set_attr "length" "8")])
1fd4e8c1
RK
2691\f
2692;; Now define ways of moving data around.
2693;;
2694;; For SI, we special-case integers that can't be loaded in one insn. We
2695;; do the load 16-bits at a time. We could do this by loading from memory,
2696;; and this is even supposed to be faster, but it is simpler not to get
2697;; integers in the TOC.
2698(define_expand "movsi"
2699 [(set (match_operand:SI 0 "general_operand" "")
2700 (match_operand:SI 1 "any_operand" ""))]
2701 ""
2702 "
2703{
2704 if (GET_CODE (operands[0]) != REG)
2705 operands[1] = force_reg (SImode, operands[1]);
2706
78b8d850
RK
2707 if (CONSTANT_P (operands[1]) && GET_CODE (operands[1]) != CONST_INT
2708 && ! LEGITIMATE_CONSTANT_POOL_ADDRESS_P (operands[1]))
b45863ec
RK
2709 {
2710 operands[1] = force_const_mem (SImode, operands[1]);
2711 if (! memory_address_p (SImode, XEXP (operands[1], 0))
2712 && ! reload_in_progress)
2713 operands[1] = change_address (operands[1], SImode,
2714 XEXP (operands[1], 0));
2715 }
1fd4e8c1
RK
2716
2717 if (GET_CODE (operands[1]) == CONST_INT
2718 && (unsigned) (INTVAL (operands[1]) + 0x8000) >= 0x10000
2719 && (INTVAL (operands[1]) & 0xffff) != 0)
2720 {
2721 emit_move_insn (operands[0],
2722 gen_rtx (CONST_INT, VOIDmode,
2723 INTVAL (operands[1]) & 0xffff0000));
2724 emit_insn (gen_iorsi3 (operands[0], operands[0],
2725 gen_rtx (CONST_INT, VOIDmode,
2726 INTVAL (operands[1]) & 0xffff)));
2727 DONE;
2728 }
2729}")
2730
2731(define_insn ""
e76e75bb
RK
2732 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,m,r,r,r,*c*q,*l,*h")
2733 (match_operand:SI 1 "input_operand" "r,m,r,I,J,*h,r,r,0"))]
ca7f5001
RK
2734 "TARGET_POWER && (gpc_reg_operand (operands[0], SImode)
2735 || gpc_reg_operand (operands[1], SImode))"
1fd4e8c1 2736 "@
ca7f5001
RK
2737 {ai|addic} %0,%1,0
2738 {l%U1%X1|lwz%U1%X1} %0,%1
2739 {st%U0%X0|stw%U0%X0} %1,%0
2740 {cal %0,%1(0)|li %0,%1}
2741 {cau %0,0,%u1|lis %0,%u1}
1fd4e8c1 2742 mf%1 %0
5c23c401 2743 mt%0 %1
e76e75bb
RK
2744 mt%0 %1
2745 cror 0,0,0"
2746 [(set_attr "type" "*,load,*,*,*,*,*,mtlr,*")])
1fd4e8c1 2747
ca7f5001
RK
2748(define_insn ""
2749 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,m,r,r,r,*h")
2750 (match_operand:SI 1 "input_operand" "r,m,r,I,J,*h,r"))]
2751 "TARGET_POWERPC && (gpc_reg_operand (operands[0], SImode)
2752 || gpc_reg_operand (operands[1], SImode))"
2753 "@
2754 mr %0,%1
2755 lwz%U1%X1 %0,%1
2756 stw%U0%X0 %1,%0
2757 li %0,%1
2758 lis %0,%u1
2759 mf%1 %0
2760 mt%0 %1"
2761 [(set_attr "type" "*,load,*,*,*,*,*")])
2762
77fa0940
RK
2763;; Split a load of a large constant into the appropriate two-insn
2764;; sequence.
2765
2766(define_split
2767 [(set (match_operand:SI 0 "gpc_reg_operand" "")
2768 (match_operand:SI 1 "const_int_operand" ""))]
2769 "(unsigned) (INTVAL (operands[1]) + 0x8000) >= 0x10000
2770 && (INTVAL (operands[1]) & 0xffff) != 0"
2771 [(set (match_dup 0)
2772 (match_dup 2))
2773 (set (match_dup 0)
2774 (ior:SI (match_dup 0)
2775 (match_dup 3)))]
2776 "
2777{
2778 operands[2] = gen_rtx (CONST_INT, VOIDmode,
2779 INTVAL (operands[1]) & 0xffff0000);
2780 operands[3] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[1]) & 0xffff);
2781}")
2782
1fd4e8c1
RK
2783(define_insn ""
2784 [(set (match_operand:CC 2 "cc_reg_operand" "=x")
cd2b37d9 2785 (compare:CC (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 2786 (const_int 0)))
cd2b37d9 2787 (set (match_operand:SI 0 "gpc_reg_operand" "=r") (match_dup 1))]
1fd4e8c1 2788 ""
ca7f5001 2789 "{ai.|addic.} %0,%1,0"
1fd4e8c1
RK
2790 [(set_attr "type" "compare")])
2791\f
2792(define_expand "movhi"
2793 [(set (match_operand:HI 0 "general_operand" "")
2794 (match_operand:HI 1 "any_operand" ""))]
2795 ""
2796 "
2797{
2798 if (GET_CODE (operands[0]) != REG)
2799 operands[1] = force_reg (HImode, operands[1]);
2800
2801 if (CONSTANT_P (operands[1]) && GET_CODE (operands[1]) != CONST_INT)
b45863ec
RK
2802 {
2803 operands[1] = force_const_mem (HImode, operands[1]);
2804 if (! memory_address_p (HImode, XEXP (operands[1], 0))
2805 && ! reload_in_progress)
2806 operands[1] = change_address (operands[1], HImode,
2807 XEXP (operands[1], 0));
2808 }
1fd4e8c1
RK
2809}")
2810
2811(define_insn ""
e76e75bb
RK
2812 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,m,r,r,*h,*h")
2813 (match_operand:HI 1 "input_operand" "r,m,r,i,*h,r,0"))]
ca7f5001
RK
2814 "TARGET_POWER && (gpc_reg_operand (operands[0], HImode)
2815 || gpc_reg_operand (operands[1], HImode))"
1fd4e8c1 2816 "@
ca7f5001 2817 {oril|ori} %0,%1,0
1fd4e8c1
RK
2818 lhz%U1%X1 %0,%1
2819 sth%U0%X0 %1,%0
ca7f5001 2820 {cal %0,%w1(0)|li %0,%w1}
1fd4e8c1 2821 mf%1 %0
e76e75bb
RK
2822 mt%0 %1
2823 cror 0,0,0"
2824 [(set_attr "type" "*,load,*,*,*,*,*")])
1fd4e8c1 2825
ca7f5001
RK
2826(define_insn ""
2827 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,m,r,r,*h")
2828 (match_operand:HI 1 "input_operand" "r,m,r,i,*h,r"))]
2829 "TARGET_POWERPC && (gpc_reg_operand (operands[0], HImode)
2830 || gpc_reg_operand (operands[1], HImode))"
2831 "@
2832 ori %0,%1,0
2833 lhz%U1%X1 %0,%1
2834 sth%U0%X0 %1,%0
2835 li %0,%w1
2836 mf%1 %0
2837 mt%0 %1"
2838 [(set_attr "type" "*,load,*,*,*,*")])
2839
1fd4e8c1
RK
2840(define_expand "movqi"
2841 [(set (match_operand:QI 0 "general_operand" "")
2842 (match_operand:QI 1 "any_operand" ""))]
2843 ""
2844 "
2845{
2846 if (GET_CODE (operands[0]) != REG)
2847 operands[1] = force_reg (QImode, operands[1]);
2848
2849 if (CONSTANT_P (operands[1]) && GET_CODE (operands[1]) != CONST_INT)
b45863ec
RK
2850 {
2851 operands[1] = force_const_mem (QImode, operands[1]);
2852 if (! memory_address_p (QImode, XEXP (operands[1], 0))
2853 && ! reload_in_progress)
2854 operands[1] = change_address (operands[1], QImode,
2855 XEXP (operands[1], 0));
2856 }
1fd4e8c1
RK
2857}")
2858
2859(define_insn ""
e76e75bb
RK
2860 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m,r,r,*h,*h")
2861 (match_operand:QI 1 "input_operand" "r,m,r,i,*h,r,0"))]
ca7f5001
RK
2862 "TARGET_POWER && (gpc_reg_operand (operands[0], QImode)
2863 || gpc_reg_operand (operands[1], QImode))"
1fd4e8c1 2864 "@
ca7f5001 2865 {oril|ori} %0,%1,0
1fd4e8c1
RK
2866 lbz%U1%X1 %0,%1
2867 stb%U0%X0 %1,%0
ca7f5001 2868 {cal %0,%1(0)|li %0,%1}
1fd4e8c1 2869 mf%1 %0
e76e75bb
RK
2870 mt%0 %1
2871 cror 0,0,0"
2872 [(set_attr "type" "*,load,*,*,*,*,*")])
ca7f5001
RK
2873
2874(define_insn ""
2875 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m,r,r,*h")
2876 (match_operand:QI 1 "input_operand" "r,m,r,i,*h,r"))]
2877 "TARGET_POWERPC && (gpc_reg_operand (operands[0], QImode)
2878 || gpc_reg_operand (operands[1], QImode))"
2879 "@
2880 mr %0,%1
2881 lbz%U1%X1 %0,%1
2882 stb%U0%X0 %1,%0
2883 li %0,%1
2884 mf%1 %0
2885 mt%0 %1"
2886 [(set_attr "type" "*,load,*,*,*,*")])
1fd4e8c1
RK
2887\f
2888;; Here is how to move condition codes around. When we store CC data in
2889;; an integer register or memory, we store just the high-order 4 bits.
2890;; This lets us not shift in the most common case of CR0.
2891(define_expand "movcc"
2892 [(set (match_operand:CC 0 "nonimmediate_operand" "")
2893 (match_operand:CC 1 "nonimmediate_operand" ""))]
2894 ""
2895 "")
2896
2897(define_insn ""
2898 [(set (match_operand:CC 0 "nonimmediate_operand" "=y,x,y,r,r,r,r,m")
2899 (match_operand:CC 1 "nonimmediate_operand" "y,r,r,x,y,r,m,r"))]
2900 "register_operand (operands[0], CCmode)
2901 || register_operand (operands[1], CCmode)"
2902 "@
2903 mcrf %0,%1
2904 mtcrf 128,%1
ca7f5001 2905 {rlinm|rlwinm} %1,%1,%F0,0xffffffff\;mtcrf %R0,%1\;{rlinm|rlwinm} %1,%1,%f0,0xffffffff
1fd4e8c1 2906 mfcr %0
ca7f5001
RK
2907 mfcr %0\;{rlinm|rlwinm} %0,%0,%f1,0xf0000000
2908 {ai %0,%1,0|mr %0,%1}
2909 {l%U1%X1|lwz%U1%X1} %0,%1
2910 {st%U0%U1|stw%U0%U1} %1,%0"
b19003d8
RK
2911 [(set_attr "type" "*,*,*,compare,*,*,load,*")
2912 (set_attr "length" "*,*,12,*,8,*,*,*")])
1fd4e8c1
RK
2913\f
2914;; For floating-point, we normally deal with the floating-point registers.
2915;; The sole exception is that parameter passing can produce floating-point
2916;; values in fixed-point registers. Unless the value is a simple constant
2917;; or already in memory, we deal with this by allocating memory and copying
2918;; the value explicitly via that memory location.
2919(define_expand "movsf"
2920 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2921 (match_operand:SF 1 "any_operand" ""))]
2922 ""
2923 "
2924{
2925 /* If we are called from reload, we might be getting a SUBREG of a hard
2926 reg. So expand it. */
2927 if (GET_CODE (operands[0]) == SUBREG
2928 && GET_CODE (SUBREG_REG (operands[0])) == REG
2929 && REGNO (SUBREG_REG (operands[0])) < FIRST_PSEUDO_REGISTER)
2930 operands[0] = alter_subreg (operands[0]);
2931 if (GET_CODE (operands[1]) == SUBREG
2932 && GET_CODE (SUBREG_REG (operands[1])) == REG
2933 && REGNO (SUBREG_REG (operands[1])) < FIRST_PSEUDO_REGISTER)
2934 operands[1] = alter_subreg (operands[1]);
2935
785e6a26 2936 if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) < 32)
1fd4e8c1
RK
2937 {
2938 rtx stack_slot;
2939
785e6a26
RK
2940 /* If this is a store to memory or another integer register do the
2941 move directly. Otherwise store to a temporary stack slot and
2942 load from there into a floating point register. */
2943
1fd4e8c1
RK
2944 if (GET_CODE (operands[0]) == MEM
2945 || (GET_CODE (operands[0]) == REG
2946 && (REGNO (operands[0]) < 32
785e6a26
RK
2947 || (reload_in_progress
2948 && REGNO (operands[0]) >= FIRST_PSEUDO_REGISTER))))
1fd4e8c1
RK
2949 {
2950 emit_move_insn (operand_subword (operands[0], 0, 0, SFmode),
2951 operand_subword (operands[1], 0, 0, SFmode));
2952 DONE;
2953 }
2954
2955 stack_slot = gen_rtx (MEM, SFmode, plus_constant (stack_pointer_rtx, 4));
2956 emit_move_insn (stack_slot, operands[1]);
2957 emit_move_insn (operands[0], stack_slot);
2958 DONE;
2959 }
2960
2961 if (GET_CODE (operands[0]) == MEM)
2962 operands[1] = force_reg (SFmode, operands[1]);
2963
2964 if (GET_CODE (operands[0]) == REG && REGNO (operands[0]) < 32)
2965 {
2966 rtx stack_slot;
2967
2968 if (GET_CODE (operands[1]) == MEM
2969#if HOST_FLOAT_FORMAT == TARGET_FLOAT_FORMAT && ! defined(REAL_IS_NOT_DOUBLE)
2970 || GET_CODE (operands[1]) == CONST_DOUBLE
2971#endif
2972 || (GET_CODE (operands[1]) == REG && REGNO (operands[1]) < 32)
2973 || (reload_in_progress && GET_CODE (operands[1]) == REG
2974 && REGNO (operands[1]) >= FIRST_PSEUDO_REGISTER))
2975 {
2976 emit_move_insn (operand_subword (operands[0], 0, 0, SFmode),
2977 operand_subword (operands[1], 0, 0, SFmode));
2978 DONE;
2979 }
2980
2981 if (reload_in_progress)
2982 stack_slot = gen_rtx (MEM, SFmode,
2983 plus_constant (stack_pointer_rtx, 4));
2984 else
2985 stack_slot = assign_stack_temp (SFmode, 4, 0);
2986 emit_move_insn (stack_slot, operands[1]);
2987 emit_move_insn (operands[0], stack_slot);
2988 DONE;
2989 }
2990
2991 if (CONSTANT_P (operands[1]))
2992 {
2993 operands[1] = force_const_mem (SFmode, operands[1]);
2994 if (! memory_address_p (SFmode, XEXP (operands[1], 0))
2995 && ! reload_in_progress)
2996 operands[1] = change_address (operands[1], SFmode,
2997 XEXP (operands[1], 0));
2998 }
2999}")
3000
1fd4e8c1 3001(define_split
cd2b37d9 3002 [(set (match_operand:SF 0 "gpc_reg_operand" "")
1fd4e8c1
RK
3003 (match_operand:SF 1 "easy_fp_constant" ""))]
3004 "reload_completed && REGNO (operands[0]) <= 31"
3005 [(set (match_dup 2) (match_dup 3))]
3006 "
3007{ operands[2] = operand_subword (operands[0], 0, 0, SFmode);
3008 operands[3] = operand_subword (operands[1], 0, 0, SFmode); }")
3009
3010(define_insn ""
3011 [(set (match_operand:SF 0 "fp_reg_or_mem_operand" "=f,f,m")
3012 (match_operand:SF 1 "input_operand" "f,m,f"))]
cd2b37d9
RK
3013 "gpc_reg_operand (operands[0], SFmode)
3014 || gpc_reg_operand (operands[1], SFmode)"
1fd4e8c1
RK
3015 "@
3016 fmr %0,%1
3017 lfs%U1%X1 %0,%1
3018 frsp %1,%1\;stfs%U0%X0 %1,%0"
cfb557c4 3019 [(set_attr "type" "fp,fpload,*")
b19003d8 3020 (set_attr "length" "*,*,8")])
1fd4e8c1
RK
3021\f
3022(define_expand "movdf"
3023 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3024 (match_operand:DF 1 "any_operand" ""))]
3025 ""
3026 "
3027{
e7113111 3028 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1fd4e8c1 3029 {
e7113111
RK
3030 emit_move_insn (operand_subword (operands[0], 1, 1, DFmode),
3031 operand_subword_force (operands[1], 1, DFmode));
3032 emit_move_insn (operand_subword (operands[0], 0, 1, DFmode),
3033 operand_subword_force (operands[1], 0, DFmode));
1fd4e8c1
RK
3034 DONE;
3035 }
3036
e7113111
RK
3037 if (GET_CODE (operands[0]) != REG)
3038 operands[1] = force_reg (DFmode, operands[1]);
1fd4e8c1 3039
e7113111 3040 if (CONSTANT_P (operands[1]) && ! easy_fp_constant (operands[1], DFmode))
1fd4e8c1
RK
3041 {
3042 operands[1] = force_const_mem (DFmode, operands[1]);
3043 if (! memory_address_p (DFmode, XEXP (operands[1], 0))
3044 && ! reload_in_progress)
3045 operands[1] = change_address (operands[1], DFmode,
3046 XEXP (operands[1], 0));
3047 }
e7113111 3048}")
1fd4e8c1
RK
3049
3050(define_split
cd2b37d9 3051 [(set (match_operand:DF 0 "gpc_reg_operand" "")
1fd4e8c1
RK
3052 (match_operand:DF 1 "easy_fp_constant" ""))]
3053 "reload_completed && REGNO (operands[0]) <= 31"
3054 [(set (match_dup 2) (match_dup 3))
3055 (set (match_dup 4) (match_dup 5))]
3056 "
3057{ operands[2] = operand_subword (operands[0], 0, 0, DFmode);
3058 operands[3] = operand_subword (operands[1], 0, 0, DFmode);
3059 operands[4] = operand_subword (operands[0], 1, 0, DFmode);
3060 operands[5] = operand_subword (operands[1], 1, 0, DFmode); }")
e7113111 3061
1fd4e8c1 3062(define_insn ""
e7113111
RK
3063 [(set (match_operand:DF 0 "nonimmediate_operand" "=!r,r,o,r,f,f,m")
3064 (match_operand:DF 1 "input_operand" "r,o,r,G,f,m,f"))]
3065 "register_operand (operands[0], DFmode)
3066 || register_operand (operands[1], DFmode)"
3067 "*
3068{
3069 switch (which_alternative)
3070 {
3071 case 0:
3072 /* We normally copy the low-numbered register first. However, if
3073 the first register operand 0 is the same as the second register of
3074 operand 1, we must copy in the opposite order. */
3075 if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
ca7f5001 3076 return \"{oril %L0,%L1,0|mr %L0,%L1}\;{oril %0,%1,0|mr %0,%1}\";
e7113111 3077 else
ca7f5001 3078 return \"{oril %0,%1,0|mr %0,%1}\;{oril %L0,%L1,0|mr %L0,%L1}\";
e7113111
RK
3079 case 1:
3080 /* If the low-address word is used in the address, we must load it
3081 last. Otherwise, load it first. Note that we cannot have
3082 auto-increment in that case since the address register is known to be
3083 dead. */
3084 if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
3085 operands [1], 0))
ca7f5001 3086 return \"{l|lwz} %L0,%L1\;{l|lwz} %0,%1\";
e7113111 3087 else
ca7f5001 3088 return \"{l%U1|lwz%U1} %0,%1\;{l|lwz} %L0,%L1\";
e7113111 3089 case 2:
ca7f5001 3090 return \"{st%U0|stw%U0} %1,%0\;{st|stw} %L1,%L0\";
e7113111
RK
3091 case 3:
3092 return \"#\";
3093 case 4:
3094 return \"fmr %0,%1\";
3095 case 5:
3096 return \"lfd%U1%X1 %0,%1\";
3097 case 6:
3098 return \"stfd%U0%X0 %1,%0\";
3099 }
3100}"
ca7f5001 3101 [(set_attr "type" "*,load,*,*,fp,fpload,*")
e7113111 3102 (set_attr "length" "8,8,8,8,*,*,*")])
1fd4e8c1
RK
3103\f
3104;; Next come the multi-word integer load and store and the load and store
3105;; multiple insns.
3106(define_expand "movdi"
3107 [(set (match_operand:DI 0 "general_operand" "")
3108 (match_operand:DI 1 "general_operand" ""))]
3109 ""
3110 "
3111{
062284d8
RK
3112 if (GET_CODE (operands[1]) == CONST_DOUBLE
3113 || GET_CODE (operands[1]) == CONST_INT)
1fd4e8c1
RK
3114 {
3115 emit_move_insn (operand_subword (operands[0], 0, 0, DImode),
3116 operand_subword (operands[1], 0, 0, DImode));
3117 emit_move_insn (operand_subword (operands[0], 1, 0, DImode),
3118 operand_subword (operands[1], 1, 0, DImode));
3119 DONE;
3120 }
062284d8
RK
3121
3122 if (GET_CODE (operands[0]) == MEM)
3123 operands[1] = force_reg (DImode, operands[1]);
1fd4e8c1
RK
3124}")
3125
3126(define_insn ""
3127 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m")
3128 (match_operand:DI 1 "input_operand" "r,m,r"))]
cd2b37d9
RK
3129 "gpc_reg_operand (operands[0], DImode)
3130 || gpc_reg_operand (operands[1], DImode)"
1fd4e8c1
RK
3131 "*
3132{
3133 switch (which_alternative)
3134 {
3135 case 0:
3136 /* We normally copy the low-numbered register first. However, if
3137 the first register operand 0 is the same as the second register of
3138 operand 1, we must copy in the opposite order. */
3139 if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
ca7f5001 3140 return \"{oril %L0,%L1,0|mr %L0,%L1}\;{oril %0,%1,0|mr %0,%1}\";
1fd4e8c1 3141 else
ca7f5001 3142 return \"{oril %0,%1,0|mr %0,%1}\;{oril %L0,%L1,0|mr %L0,%L1}\";
1fd4e8c1
RK
3143 case 1:
3144 /* If the low-address word is used in the address, we must load it
3145 last. Otherwise, load it first. Note that we cannot have
3146 auto-increment in that case since the address register is known to be
3147 dead. */
3148 if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
3149 operands [1], 0))
ca7f5001 3150 return \"{l|lwz} %L0,%L1\;{l|lwz} %0,%1\";
1fd4e8c1 3151 else
ca7f5001 3152 return \"{l%U1|lwz%U1} %0,%1\;{l|lwz} %L0,%L1\";
1fd4e8c1 3153 case 2:
ca7f5001 3154 return \"{st%U0|stw%U0} %1,%0\;{st|stw} %L1,%L0\";
1fd4e8c1
RK
3155 }
3156}"
b19003d8
RK
3157 [(set_attr "type" "*,load,*")
3158 (set_attr "length" "8")])
1fd4e8c1
RK
3159\f
3160;; TImode is similar, except that we usually want to compute the address into
3161;; a register and use lsi/stsi (the exception is during reload). MQ is also
ca7f5001 3162;; clobbered in stsi for POWER, so we need a SCRATCH for it.
1fd4e8c1
RK
3163(define_expand "movti"
3164 [(parallel [(set (match_operand:TI 0 "general_operand" "")
3165 (match_operand:TI 1 "general_operand" ""))
3166 (clobber (scratch:SI))])]
ca7f5001 3167 "TARGET_POWER"
1fd4e8c1
RK
3168 "
3169{
3170 if (GET_CODE (operands[0]) == MEM)
3171 operands[1] = force_reg (TImode, operands[1]);
3172
3173 if (GET_CODE (operands[0]) == MEM
3174 && GET_CODE (XEXP (operands[0], 0)) != REG
3175 && ! reload_in_progress)
3176 operands[0] = change_address (operands[0], TImode,
3177 copy_addr_to_reg (XEXP (operands[0], 0)));
3178
3179 if (GET_CODE (operands[1]) == MEM
3180 && GET_CODE (XEXP (operands[1], 0)) != REG
3181 && ! reload_in_progress)
3182 operands[1] = change_address (operands[1], TImode,
3183 copy_addr_to_reg (XEXP (operands[1], 0)));
3184}")
3185
3186;; We say that MQ is clobbered in the last alternative because the first
3187;; alternative would never get used otherwise since it would need a reload
3188;; while the 2nd alternative would not. We put memory cases first so they
3189;; are preferred. Otherwise, we'd try to reload the output instead of
3190;; giving the SCRATCH mq.
3191(define_insn ""
3192 [(set (match_operand:TI 0 "reg_or_mem_operand" "=Q,m,r,r,r")
3193 (match_operand:TI 1 "reg_or_mem_operand" "r,r,r,Q,m"))
3194 (clobber (match_scratch:SI 2 "=q,q#X,X,X,X"))]
ca7f5001
RK
3195 "TARGET_POWER && (gpc_reg_operand (operands[0], TImode)
3196 || gpc_reg_operand (operands[1], TImode))"
1fd4e8c1
RK
3197 "*
3198{
3199 switch (which_alternative)
3200 {
3201 case 0:
ca7f5001 3202 return \"{stsi|stswi} %1,%P0,16\";
1fd4e8c1
RK
3203
3204 case 1:
ca7f5001 3205 return \"{st%U0|stw%U0} %1,%0\;{st|stw} %L1,%L0\;{st|stw} %Y1,%Y0\;{st|stw} %Z1,%Z0\";
1fd4e8c1
RK
3206
3207 case 2:
3208 /* Normally copy registers with lowest numbered register copied first.
3209 But copy in the other order if the first register of the output
3210 is the second, third, or fourth register in the input. */
3211 if (REGNO (operands[0]) >= REGNO (operands[1]) + 1
3212 && REGNO (operands[0]) <= REGNO (operands[1]) + 3)
ca7f5001 3213 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 3214 else
ca7f5001 3215 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
3216 case 3:
3217 /* If the address is not used in the output, we can use lsi. Otherwise,
3218 fall through to generating four loads. */
3219 if (! reg_overlap_mentioned_p (operands[0], operands[1]))
ca7f5001 3220 return \"{lsi|lswi} %0,%P1,16\";
1fd4e8c1
RK
3221 /* ... fall through ... */
3222 case 4:
3223 /* If the address register is the same as the register for the lowest-
3224 addressed word, load it last. Similarly for the next two words.
3225 Otherwise load lowest address to highest. */
3226 if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
3227 operands[1], 0))
ca7f5001 3228 return \"{l|lwz} %L0,%L1\;{l|lwz} %Y0,%Y1\;{l|lwz} %Z0,%Z1\;{l|lwz} %0,%1\";
1fd4e8c1
RK
3229 else if (refers_to_regno_p (REGNO (operands[0]) + 1,
3230 REGNO (operands[0]) + 2, operands[1], 0))
ca7f5001 3231 return \"{l|lwz} %0,%1\;{l|lwz} %Y0,%Y1\;{l|lwz} %Z0,%Z1\;{l|lwz} %L0,%L1\";
1fd4e8c1
RK
3232 else if (refers_to_regno_p (REGNO (operands[0]) + 2,
3233 REGNO (operands[0]) + 3, operands[1], 0))
ca7f5001 3234 return \"{l|lwz} %0,%1\;{l|lwz} %L0,%L1\;{l|lwz} %Z0,%Z1\;{l|lwz} %Y0,%Y1\";
1fd4e8c1 3235 else
ca7f5001 3236 return \"{l%U1|lwz%U1} %0,%1\;{l|lwz} %L0,%L1\;{l|lwz} %Y0,%Y1\;{l|lwz} %Z0,%Z1\";
1fd4e8c1
RK
3237 }
3238}"
b19003d8
RK
3239 [(set_attr "type" "*,load,load,*,*")
3240 (set_attr "length" "*,16,16,*,16")])
1fd4e8c1
RK
3241\f
3242(define_expand "load_multiple"
2f622005
RK
3243 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
3244 (match_operand:SI 1 "" ""))
3245 (use (match_operand:SI 2 "" ""))])]
ca7f5001 3246 "TARGET_POWER"
1fd4e8c1
RK
3247 "
3248{
3249 int regno;
3250 int count;
3251 rtx from;
3252 int i;
3253
3254 /* Support only loading a constant number of fixed-point registers from
3255 memory and only bother with this if more than two; the machine
3256 doesn't support more than eight. */
3257 if (GET_CODE (operands[2]) != CONST_INT
3258 || INTVAL (operands[2]) <= 2
3259 || INTVAL (operands[2]) > 8
3260 || GET_CODE (operands[1]) != MEM
3261 || GET_CODE (operands[0]) != REG
3262 || REGNO (operands[0]) >= 32)
3263 FAIL;
3264
3265 count = INTVAL (operands[2]);
3266 regno = REGNO (operands[0]);
3267
3268 operands[3] = gen_rtx (PARALLEL, VOIDmode, rtvec_alloc (count));
3269 from = force_reg (SImode, XEXP (operands[1], 0));
3270
3271 for (i = 0; i < count; i++)
3272 XVECEXP (operands[3], 0, i)
3273 = gen_rtx (SET, VOIDmode, gen_rtx (REG, SImode, regno + i),
3274 gen_rtx (MEM, SImode, plus_constant (from, i * 4)));
3275}")
3276
3277(define_insn ""
3278 [(match_parallel 0 "load_multiple_operation"
cd2b37d9 3279 [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
1fd4e8c1 3280 (match_operand:SI 2 "indirect_operand" "Q"))])]
ca7f5001 3281 "TARGET_POWER"
1fd4e8c1
RK
3282 "*
3283{
3284 /* We have to handle the case where the pseudo used to contain the address
3285 is assigned to one of the output registers. In that case, do the
3286 lsi, but then load the correct value. This is a bit of a mess, but is
b19003d8
RK
3287 the best we can do.
3288 We set the length attribute to the maximum possible size (8 bytes). */
1fd4e8c1
RK
3289 static char result[100];
3290 char newload[40];
3291 int i;
3292
ca7f5001 3293 strcpy (result, \"{lsi|lswi} %1,%P2,%N0\");
1fd4e8c1
RK
3294 for (i = 0; i < XVECLEN (operands[0], 0); i++)
3295 if (refers_to_regno_p (REGNO (operands[1]) + i,
3296 REGNO (operands[1]) + i + 1, operands[2], 0))
3297 {
ca7f5001 3298 sprintf (newload, \"\;{l|lwz} %d,%d(%d)\",
1fd4e8c1
RK
3299 REGNO (operands[1]) + i,
3300 i * 4, REGNO (XEXP (operands[2], 0)));
3301 strcat (result, newload);
3302 }
3303
3304 return result;
3305}"
b19003d8
RK
3306 [(set_attr "type" "load")
3307 (set_attr "length" "8")])
1fd4e8c1 3308\f
b19003d8 3309
1fd4e8c1 3310(define_expand "store_multiple"
2f622005
RK
3311 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
3312 (match_operand:SI 1 "" ""))
3313 (clobber (scratch:SI))
3314 (use (match_operand:SI 2 "" ""))])]
ca7f5001 3315 "TARGET_POWER"
1fd4e8c1
RK
3316 "
3317{
3318 int regno;
3319 int count;
3320 rtx to;
3321 int i;
3322
3323 /* Support only storing a constant number of fixed-point registers to
3324 memory and only bother with this if more than two; the machine
3325 doesn't support more than eight. */
3326 if (GET_CODE (operands[2]) != CONST_INT
3327 || INTVAL (operands[2]) <= 2
3328 || INTVAL (operands[2]) > 8
3329 || GET_CODE (operands[0]) != MEM
3330 || GET_CODE (operands[1]) != REG
3331 || REGNO (operands[1]) >= 32)
3332 FAIL;
3333
3334 count = INTVAL (operands[2]);
3335 regno = REGNO (operands[1]);
3336
3337 operands[3] = gen_rtx (PARALLEL, VOIDmode, rtvec_alloc (count + 1));
3338 to = force_reg (SImode, XEXP (operands[0], 0));
3339
3340 XVECEXP (operands[3], 0, 0)
3341 = gen_rtx (SET, VOIDmode, gen_rtx (MEM, SImode, to), operands[1]);
3342 XVECEXP (operands[3], 0, 1) = gen_rtx (CLOBBER, VOIDmode,
3343 gen_rtx (SCRATCH, SImode));
3344
3345 for (i = 1; i < count; i++)
3346 XVECEXP (operands[3], 0, i + 1)
3347 = gen_rtx (SET, VOIDmode,
3348 gen_rtx (MEM, SImode, plus_constant (to, i * 4)),
3349 gen_rtx (REG, SImode, regno + i));
3350}")
3351
3352(define_insn ""
3353 [(match_parallel 0 "store_multiple_operation"
3354 [(set (match_operand:SI 1 "indirect_operand" "=Q")
cd2b37d9 3355 (match_operand:SI 2 "gpc_reg_operand" "r"))
1fd4e8c1 3356 (clobber (match_scratch:SI 3 "=q"))])]
ca7f5001
RK
3357 "TARGET_POWER"
3358 "{stsi|stswi} %2,%P1,%O0")
1fd4e8c1
RK
3359\f
3360;; Define insns that do load or store with update. Some of these we can
3361;; get by using pre-decrement or pre-increment, but the hardware can also
3362;; do cases where the increment is not the size of the object.
3363;;
3364;; In all these cases, we use operands 0 and 1 for the register being
3365;; incremented because those are the operands that local-alloc will
3366;; tie and these are the pair most likely to be tieable (and the ones
3367;; that will benefit the most).
3368
3369(define_insn ""
cd2b37d9
RK
3370 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
3371 (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
1fd4e8c1 3372 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
cd2b37d9 3373 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
1fd4e8c1
RK
3374 (plus:SI (match_dup 1) (match_dup 2)))]
3375 ""
3376 "@
ca7f5001
RK
3377 {lux|lwzux} %3,%0,%2
3378 {lu|lwzu} %3,%2(%0)"
cfb557c4 3379 [(set_attr "type" "load")])
1fd4e8c1
RK
3380
3381(define_insn ""
cd2b37d9 3382 [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
1fd4e8c1 3383 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
cd2b37d9
RK
3384 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
3385 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
1fd4e8c1
RK
3386 (plus:SI (match_dup 1) (match_dup 2)))]
3387 ""
3388 "@
ca7f5001
RK
3389 {stux|stwux} %3,%0,%2
3390 {stu|stwu} %3,%2(%0)")
1fd4e8c1
RK
3391
3392(define_insn ""
cd2b37d9
RK
3393 [(set (match_operand:HI 3 "gpc_reg_operand" "=r,r")
3394 (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
1fd4e8c1 3395 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
cd2b37d9 3396 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
1fd4e8c1
RK
3397 (plus:SI (match_dup 1) (match_dup 2)))]
3398 ""
3399 "@
5f243543
RK
3400 lhzux %3,%0,%2
3401 lhzu %3,%2(%0)"
cfb557c4 3402 [(set_attr "type" "load")])
1fd4e8c1
RK
3403
3404(define_insn ""
cd2b37d9 3405 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
1fd4e8c1 3406 (zero_extend:SI
cd2b37d9 3407 (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
1fd4e8c1 3408 (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
cd2b37d9 3409 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
1fd4e8c1
RK
3410 (plus:SI (match_dup 1) (match_dup 2)))]
3411 ""
3412 "@
5f243543
RK
3413 lhzux %3,%0,%2
3414 lhzu %3,%2(%0)"
cfb557c4 3415 [(set_attr "type" "load")])
1fd4e8c1
RK
3416
3417(define_insn ""
cd2b37d9 3418 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
1fd4e8c1 3419 (sign_extend:SI
cd2b37d9 3420 (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
1fd4e8c1 3421 (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
cd2b37d9 3422 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
1fd4e8c1
RK
3423 (plus:SI (match_dup 1) (match_dup 2)))]
3424 ""
3425 "@
5f243543
RK
3426 lhaux %3,%0,%2
3427 lhau %3,%2(%0)"
cfb557c4 3428 [(set_attr "type" "load")])
1fd4e8c1
RK
3429
3430(define_insn ""
cd2b37d9 3431 [(set (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
1fd4e8c1 3432 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
cd2b37d9
RK
3433 (match_operand:HI 3 "gpc_reg_operand" "r,r"))
3434 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
1fd4e8c1
RK
3435 (plus:SI (match_dup 1) (match_dup 2)))]
3436 ""
3437 "@
5f243543 3438 sthux %3,%0,%2
cfb557c4 3439 sthu %3,%2(%0)")
1fd4e8c1
RK
3440
3441(define_insn ""
cd2b37d9
RK
3442 [(set (match_operand:QI 3 "gpc_reg_operand" "=r,r")
3443 (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
1fd4e8c1 3444 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
cd2b37d9 3445 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
1fd4e8c1
RK
3446 (plus:SI (match_dup 1) (match_dup 2)))]
3447 ""
3448 "@
5f243543
RK
3449 lbzux %3,%0,%2
3450 lbzu %3,%2(%0)"
cfb557c4 3451 [(set_attr "type" "load")])
1fd4e8c1
RK
3452
3453(define_insn ""
cd2b37d9 3454 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
1fd4e8c1 3455 (zero_extend:SI
cd2b37d9 3456 (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
1fd4e8c1 3457 (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
cd2b37d9 3458 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
1fd4e8c1
RK
3459 (plus:SI (match_dup 1) (match_dup 2)))]
3460 ""
3461 "@
5f243543
RK
3462 lbzux %3,%0,%2
3463 lbzu %3,%2(%0)"
cfb557c4 3464 [(set_attr "type" "load")])
1fd4e8c1
RK
3465
3466(define_insn ""
cd2b37d9 3467 [(set (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
1fd4e8c1 3468 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
cd2b37d9
RK
3469 (match_operand:QI 3 "gpc_reg_operand" "r,r"))
3470 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
1fd4e8c1
RK
3471 (plus:SI (match_dup 1) (match_dup 2)))]
3472 ""
3473 "@
5f243543
RK
3474 stbux %3,%0,%2
3475 stbu %3,%2(%0)")
1fd4e8c1
RK
3476
3477(define_insn ""
cd2b37d9
RK
3478 [(set (match_operand:SF 3 "gpc_reg_operand" "=f,f")
3479 (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
1fd4e8c1 3480 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
cd2b37d9 3481 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
1fd4e8c1
RK
3482 (plus:SI (match_dup 1) (match_dup 2)))]
3483 ""
3484 "@
5f243543
RK
3485 lfsux %3,%0,%2
3486 lfsu %3,%2(%0)"
cfb557c4 3487 [(set_attr "type" "fpload")])
1fd4e8c1
RK
3488
3489(define_insn ""
cd2b37d9 3490 [(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
1fd4e8c1 3491 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
cd2b37d9
RK
3492 (match_operand:SF 3 "gpc_reg_operand" "f,f"))
3493 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
1fd4e8c1
RK
3494 (plus:SI (match_dup 1) (match_dup 2)))]
3495 ""
3496 "@
5f243543
RK
3497 frsp %3,%3\;stfsux %3,%0,%2
3498 frsp %3,%3\;stfsu %3,%2(%0)")
1fd4e8c1
RK
3499
3500(define_insn ""
cd2b37d9
RK
3501 [(set (match_operand:DF 3 "gpc_reg_operand" "=f,f")
3502 (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
1fd4e8c1 3503 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
cd2b37d9 3504 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
1fd4e8c1
RK
3505 (plus:SI (match_dup 1) (match_dup 2)))]
3506 ""
3507 "@
5f243543
RK
3508 lfdux %3,%0,%2
3509 lfdu %3,%2(%0)"
cfb557c4 3510 [(set_attr "type" "fpload")])
1fd4e8c1
RK
3511
3512(define_insn ""
cd2b37d9 3513 [(set (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
1fd4e8c1 3514 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
cd2b37d9
RK
3515 (match_operand:DF 3 "gpc_reg_operand" "f,f"))
3516 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
1fd4e8c1
RK
3517 (plus:SI (match_dup 1) (match_dup 2)))]
3518 ""
3519 "@
5f243543
RK
3520 stfdux %3,%0,%2
3521 stfdu %3,%2(%0)")
1fd4e8c1
RK
3522\f
3523;; Next come insns related to the calling sequence.
3524;;
3525;; First, an insn to allocate new stack space for dynamic use (e.g., alloca).
59257ff7 3526;; We move the back-chain and decrement the stack pointer.
1fd4e8c1
RK
3527
3528(define_expand "allocate_stack"
3529 [(set (reg:SI 1)
01def764 3530 (minus:SI (reg:SI 1) (match_operand:SI 0 "reg_or_short_operand" "")))]
1fd4e8c1
RK
3531 ""
3532 "
3533{ rtx chain = gen_reg_rtx (SImode);
3534 rtx stack_bot = gen_rtx (MEM, Pmode, stack_pointer_rtx);
3535
3536 emit_move_insn (chain, stack_bot);
a0044fb1 3537 emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx, operands[0]));
1fd4e8c1
RK
3538 emit_move_insn (stack_bot, chain);
3539 DONE;
3540}")
59257ff7
RK
3541
3542;; These patterns say how to save and restore the stack pointer. We need not
3543;; save the stack pointer at function level since we are careful to
3544;; preserve the backchain. At block level, we have to restore the backchain
3545;; when we restore the stack pointer.
3546;;
3547;; For nonlocal gotos, we must save both the stack pointer and its
3548;; backchain and restore both. Note that in the nonlocal case, the
3549;; save area is a memory location.
3550
3551(define_expand "save_stack_function"
3552 [(use (const_int 0))]
3553 ""
3554 "")
3555
3556(define_expand "restore_stack_function"
3557 [(use (const_int 0))]
3558 ""
3559 "")
3560
3561(define_expand "restore_stack_block"
3562 [(set (match_dup 2) (mem:SI (match_operand:SI 0 "register_operand" "")))
3563 (set (match_dup 0) (match_operand:SI 1 "register_operand" ""))
3564 (set (mem:SI (match_dup 0)) (match_dup 2))]
3565 ""
3566 "
3567{ operands[2] = gen_reg_rtx (SImode); }")
3568
3569(define_expand "save_stack_nonlocal"
3570 [(match_operand:DI 0 "memory_operand" "")
3571 (match_operand:SI 1 "register_operand" "")]
3572 ""
3573 "
3574{
3575 rtx temp = gen_reg_rtx (SImode);
3576
3577 /* Copy the backchain to the first word, sp to the second. */
3578 emit_move_insn (temp, gen_rtx (MEM, SImode, operands[1]));
3579 emit_move_insn (operand_subword (operands[0], 0, 0, DImode), temp);
3580 emit_move_insn (operand_subword (operands[0], 1, 0, DImode), operands[1]);
3581 DONE;
3582}")
3583
3584(define_expand "restore_stack_nonlocal"
3585 [(match_operand:SI 0 "register_operand" "")
3586 (match_operand:DI 1 "memory_operand" "")]
3587 ""
3588 "
3589{
3590 rtx temp = gen_reg_rtx (SImode);
3591
3592 /* Restore the backchain from the first word, sp from the second. */
3593 emit_move_insn (temp, operand_subword (operands[1], 0, 0, DImode));
3594 emit_move_insn (operands[0], operand_subword (operands[1], 1, 0, DImode));
3595 emit_move_insn (gen_rtx (MEM, SImode, operands[0]), temp);
3596 DONE;
3597}")
1fd4e8c1
RK
3598\f
3599;; A function pointer is a pointer to a data area whose first word contains
3600;; the actual address of the function, whose second word contains a pointer
3601;; to its TOC, and whose third word contains a value to place in the static
3602;; chain register (r11). Note that if we load the static chain, our
3603;; "trampoline" need not have any executable code.
3604;;
3605;; operands[0] is an SImode pseudo in which we place the address of the
3606;; function.
3607;; operands[1] is the address of data area of the function to call
3608
3609(define_expand "call_via_ptr"
cd2b37d9
RK
3610 [(set (match_operand:SI 0 "gpc_reg_operand" "")
3611 (mem:SI (match_operand:SI 1 "gpc_reg_operand" "")))
1fd4e8c1
RK
3612 (set (mem:SI (plus:SI (reg:SI 1) (const_int 20)))
3613 (reg:SI 2))
3614 (set (reg:SI 2)
3615 (mem:SI (plus:SI (match_dup 1)
3616 (const_int 4))))
3617 (set (reg:SI 11)
3618 (mem:SI (plus:SI (match_dup 1)
3619 (const_int 8))))
3620 (use (reg:SI 2))
3621 (use (reg:SI 11))]
3622 ""
3623 "")
3624
3625(define_expand "call"
3626 [(parallel [(call (mem:SI (match_operand:SI 0 "address_operand" ""))
3627 (match_operand 1 "" ""))
3628 (clobber (scratch:SI))])]
3629 ""
3630 "
3631{
3632 if (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != CONST_INT)
3633 abort ();
3634
3635 operands[0] = XEXP (operands[0], 0);
3636 if (GET_CODE (operands[0]) != SYMBOL_REF)
3637 {
3638 rtx temp = gen_reg_rtx (SImode);
3639
3640 emit_insn (gen_call_via_ptr (temp, force_reg (SImode, operands[0])));
3641 operands[0] = temp;
3642 }
3643}")
3644
3645(define_expand "call_value"
3646 [(parallel [(set (match_operand 0 "" "")
3647 (call (mem:SI (match_operand:SI 1 "address_operand" ""))
3648 (match_operand 2 "" "")))
3649 (clobber (scratch:SI))])]
3650 ""
3651 "
3652{
3653 if (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != CONST_INT)
3654 abort ();
3655
3656 operands[1] = XEXP (operands[1], 0);
3657 if (GET_CODE (operands[1]) != SYMBOL_REF)
3658 {
3659 rtx temp = gen_reg_rtx (SImode);
3660
3661 emit_insn (gen_call_via_ptr (temp, force_reg (SImode, operands[1])));
3662 operands[1] = temp;
3663 }
3664}")
3665
04780ee7
RK
3666;; Call to function in current module. No TOC pointer reload needed.
3667
3668(define_insn ""
3669 [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s"))
3670 (match_operand 1 "" "g"))
3671 (clobber (match_scratch:SI 2 "=l"))]
3672 ""
3673 "bl %z0")
3674
3675;; Call to function which may be in another module. Restore the TOC
3676;; pointer (r2) after the call.
3677
1fd4e8c1
RK
3678(define_insn ""
3679 [(call (mem:SI (match_operand:SI 0 "call_operand" "l,s"))
3680 (match_operand 1 "" "fg,fg"))
9482d6de 3681 (clobber (match_scratch:SI 2 "=l,l"))]
1fd4e8c1
RK
3682 ""
3683 "@
ca7f5001 3684 {brl|blrl}\;{l|lwz} 2,20(1)
a0292f62 3685 bl %z0\;%."
b19003d8 3686 [(set_attr "length" "8")])
1fd4e8c1 3687
04780ee7
RK
3688(define_insn ""
3689 [(set (match_operand 0 "" "=fg")
3690 (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s"))
3691 (match_operand 2 "" "g")))
3692 (clobber (match_scratch:SI 3 "=l"))]
3693 ""
3694 "bl %z1")
3695
1fd4e8c1 3696(define_insn ""
5f243543 3697 [(set (match_operand 0 "" "=fg,fg")
1fd4e8c1
RK
3698 (call (mem:SI (match_operand:SI 1 "call_operand" "l,s"))
3699 (match_operand 2 "" "fg,fg")))
3700 (clobber (match_scratch:SI 3 "=l,l"))]
3701 ""
3702 "@
ca7f5001 3703 {brl|blrl}\;{l|lwz} 2,20(1)
a0292f62 3704 bl %z1\;%."
b19003d8 3705 [(set_attr "length" "8")])
e6f948e3
RK
3706
3707;; Call subroutine returning any type.
3708
3709(define_expand "untyped_call"
3710 [(parallel [(call (match_operand 0 "" "")
3711 (const_int 0))
3712 (match_operand 1 "" "")
3713 (match_operand 2 "" "")])]
3714 ""
3715 "
3716{
3717 int i;
3718
3719 emit_call_insn (gen_call (operands[0], const0_rtx, NULL, const0_rtx));
3720
3721 for (i = 0; i < XVECLEN (operands[2], 0); i++)
3722 {
3723 rtx set = XVECEXP (operands[2], 0, i);
3724 emit_move_insn (SET_DEST (set), SET_SRC (set));
3725 }
3726
3727 /* The optimizer does not know that the call sets the function value
3728 registers we stored in the result block. We avoid problems by
3729 claiming that all hard registers are used and clobbered at this
3730 point. */
3731 emit_insn (gen_blockage ());
3732
3733 DONE;
3734}")
3735
3736;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
3737;; all of memory. This blocks insns from being moved across this point.
3738
3739(define_insn "blockage"
3740 [(unspec_volatile [(const_int 0)] 0)]
3741 ""
3742 "")
1fd4e8c1
RK
3743\f
3744;; Compare insns are next. Note that the RS/6000 has two types of compares,
3745;; signed & unsigned, and one type of branch.
3746;;
3747;; Start with the DEFINE_EXPANDs to generate the rtl for compares, scc
3748;; insns, and branches. We store the operands of compares until we see
3749;; how it is used.
3750(define_expand "cmpsi"
3751 [(set (cc0)
cd2b37d9 3752 (compare (match_operand:SI 0 "gpc_reg_operand" "")
1fd4e8c1
RK
3753 (match_operand:SI 1 "reg_or_short_operand" "")))]
3754 ""
3755 "
3756{
3757 /* Take care of the possibility that operands[1] might be negative but
3758 this might be a logical operation. That insn doesn't exist. */
3759 if (GET_CODE (operands[1]) == CONST_INT
3760 && INTVAL (operands[1]) < 0)
3761 operands[1] = force_reg (SImode, operands[1]);
3762
3763 rs6000_compare_op0 = operands[0];
3764 rs6000_compare_op1 = operands[1];
3765 rs6000_compare_fp_p = 0;
3766 DONE;
3767}")
3768
3769(define_expand "cmpsf"
cd2b37d9
RK
3770 [(set (cc0) (compare (match_operand:SF 0 "gpc_reg_operand" "")
3771 (match_operand:SF 1 "gpc_reg_operand" "")))]
1fd4e8c1
RK
3772 ""
3773 "
3774{
3775 rs6000_compare_op0 = operands[0];
3776 rs6000_compare_op1 = operands[1];
3777 rs6000_compare_fp_p = 1;
3778 DONE;
3779}")
3780
3781(define_expand "cmpdf"
cd2b37d9
RK
3782 [(set (cc0) (compare (match_operand:DF 0 "gpc_reg_operand" "")
3783 (match_operand:DF 1 "gpc_reg_operand" "")))]
1fd4e8c1
RK
3784 ""
3785 "
3786{
3787 rs6000_compare_op0 = operands[0];
3788 rs6000_compare_op1 = operands[1];
3789 rs6000_compare_fp_p = 1;
3790 DONE;
3791}")
3792
3793(define_expand "beq"
3794 [(set (match_dup 2) (match_dup 1))
3795 (set (pc)
3796 (if_then_else (eq (match_dup 2)
3797 (const_int 0))
3798 (label_ref (match_operand 0 "" ""))
3799 (pc)))]
3800 ""
3801 "
3802{ enum machine_mode mode = rs6000_compare_fp_p ? CCFPmode : CCmode;
3803 operands[1] = gen_rtx (COMPARE, mode,
3804 rs6000_compare_op0, rs6000_compare_op1);
3805 operands[2] = gen_reg_rtx (mode);
3806}")
3807
3808(define_expand "bne"
3809 [(set (match_dup 2) (match_dup 1))
3810 (set (pc)
3811 (if_then_else (ne (match_dup 2)
3812 (const_int 0))
3813 (label_ref (match_operand 0 "" ""))
3814 (pc)))]
3815 ""
3816 "
3817{ enum machine_mode mode = rs6000_compare_fp_p ? CCFPmode : CCmode;
3818 operands[1] = gen_rtx (COMPARE, mode,
3819 rs6000_compare_op0, rs6000_compare_op1);
3820 operands[2] = gen_reg_rtx (mode);
3821}")
3822
3823(define_expand "blt"
3824 [(set (match_dup 2) (match_dup 1))
3825 (set (pc)
3826 (if_then_else (lt (match_dup 2)
3827 (const_int 0))
3828 (label_ref (match_operand 0 "" ""))
3829 (pc)))]
3830 ""
3831 "
3832{ enum machine_mode mode = rs6000_compare_fp_p ? CCFPmode : CCmode;
3833 operands[1] = gen_rtx (COMPARE, mode,
3834 rs6000_compare_op0, rs6000_compare_op1);
3835 operands[2] = gen_reg_rtx (mode);
3836}")
3837
3838(define_expand "bgt"
3839 [(set (match_dup 2) (match_dup 1))
3840 (set (pc)
3841 (if_then_else (gt (match_dup 2)
3842 (const_int 0))
3843 (label_ref (match_operand 0 "" ""))
3844 (pc)))]
3845 ""
3846 "
3847{ enum machine_mode mode = rs6000_compare_fp_p ? CCFPmode : CCmode;
3848 operands[1] = gen_rtx (COMPARE, mode,
3849 rs6000_compare_op0, rs6000_compare_op1);
3850 operands[2] = gen_reg_rtx (mode);
3851}")
3852
3853(define_expand "ble"
3854 [(set (match_dup 2) (match_dup 1))
3855 (set (pc)
3856 (if_then_else (le (match_dup 2)
3857 (const_int 0))
3858 (label_ref (match_operand 0 "" ""))
3859 (pc)))]
3860 ""
3861 "
3862{ enum machine_mode mode = rs6000_compare_fp_p ? CCFPmode : CCmode;
3863 operands[1] = gen_rtx (COMPARE, mode,
3864 rs6000_compare_op0, rs6000_compare_op1);
3865 operands[2] = gen_reg_rtx (mode);
3866}")
3867
3868(define_expand "bge"
3869 [(set (match_dup 2) (match_dup 1))
3870 (set (pc)
3871 (if_then_else (ge (match_dup 2)
3872 (const_int 0))
3873 (label_ref (match_operand 0 "" ""))
3874 (pc)))]
3875 ""
3876 "
3877{ enum machine_mode mode = rs6000_compare_fp_p ? CCFPmode : CCmode;
3878 operands[1] = gen_rtx (COMPARE, mode,
3879 rs6000_compare_op0, rs6000_compare_op1);
3880 operands[2] = gen_reg_rtx (mode);
3881}")
3882
3883(define_expand "bgtu"
3884 [(set (match_dup 2) (match_dup 1))
3885 (set (pc)
3886 (if_then_else (gtu (match_dup 2)
3887 (const_int 0))
3888 (label_ref (match_operand 0 "" ""))
3889 (pc)))]
3890 ""
3891 "
3892{ operands[1] = gen_rtx (COMPARE, CCUNSmode,
3893 rs6000_compare_op0, rs6000_compare_op1);
3894 operands[2] = gen_reg_rtx (CCUNSmode);
3895}")
3896
3897(define_expand "bltu"
3898 [(set (match_dup 2) (match_dup 1))
3899 (set (pc)
3900 (if_then_else (ltu (match_dup 2)
3901 (const_int 0))
3902 (label_ref (match_operand 0 "" ""))
3903 (pc)))]
3904 ""
3905 "
3906{ operands[1] = gen_rtx (COMPARE, CCUNSmode,
3907 rs6000_compare_op0, rs6000_compare_op1);
3908 operands[2] = gen_reg_rtx (CCUNSmode);
3909}")
3910
3911(define_expand "bgeu"
3912 [(set (match_dup 2) (match_dup 1))
3913 (set (pc)
3914 (if_then_else (geu (match_dup 2)
3915 (const_int 0))
3916 (label_ref (match_operand 0 "" ""))
3917 (pc)))]
3918 ""
3919 "
3920{ operands[1] = gen_rtx (COMPARE, CCUNSmode,
3921 rs6000_compare_op0, rs6000_compare_op1);
3922 operands[2] = gen_reg_rtx (CCUNSmode);
3923}")
3924
3925(define_expand "bleu"
3926 [(set (match_dup 2) (match_dup 1))
3927 (set (pc)
3928 (if_then_else (leu (match_dup 2)
3929 (const_int 0))
3930 (label_ref (match_operand 0 "" ""))
3931 (pc)))]
3932 ""
3933 "
3934{ operands[1] = gen_rtx (COMPARE, CCUNSmode,
3935 rs6000_compare_op0, rs6000_compare_op1);
3936 operands[2] = gen_reg_rtx (CCUNSmode);
3937}")
3938
3939;; For SNE, we would prefer that the xor/abs sequence be used for integers.
3940;; For SEQ, likewise, except that comparisons with zero should be done
3941;; with an scc insns. However, due to the order that combine see the
3942;; resulting insns, we must, in fact, allow SEQ for integers. Fail in
3943;; the cases we don't want to handle.
3944(define_expand "seq"
3945 [(set (match_dup 2) (match_dup 1))
cd2b37d9 3946 (set (match_operand:SI 0 "gpc_reg_operand" "")
1fd4e8c1
RK
3947 (eq:SI (match_dup 2) (const_int 0)))]
3948 ""
3949 "
3950{ enum machine_mode mode = rs6000_compare_fp_p ? CCFPmode : CCmode;
3951 operands[1] = gen_rtx (COMPARE, mode,
3952 rs6000_compare_op0, rs6000_compare_op1);
3953 operands[2] = gen_reg_rtx (mode);
3954}")
3955
3956(define_expand "sne"
3957 [(set (match_dup 2) (match_dup 1))
cd2b37d9 3958 (set (match_operand:SI 0 "gpc_reg_operand" "")
1fd4e8c1
RK
3959 (ne:SI (match_dup 2) (const_int 0)))]
3960 ""
3961 "
3962{ if (! rs6000_compare_fp_p)
3963 FAIL;
3964
3965 operands[1] = gen_rtx (COMPARE, CCFPmode,
3966 rs6000_compare_op0, rs6000_compare_op1);
3967 operands[2] = gen_reg_rtx (CCFPmode);
3968}")
3969
3970;; A > 0 is best done using the portable sequence, so fail in that case.
3971(define_expand "sgt"
3972 [(set (match_dup 2) (match_dup 1))
cd2b37d9 3973 (set (match_operand:SI 0 "gpc_reg_operand" "")
1fd4e8c1
RK
3974 (gt:SI (match_dup 2) (const_int 0)))]
3975 ""
3976 "
3977{ enum machine_mode mode = rs6000_compare_fp_p ? CCFPmode : CCmode;
3978
3979 if (! rs6000_compare_fp_p && rs6000_compare_op1 == const0_rtx)
3980 FAIL;
3981
3982 operands[1] = gen_rtx (COMPARE, mode,
3983 rs6000_compare_op0, rs6000_compare_op1);
3984 operands[2] = gen_reg_rtx (mode);
3985}")
3986
3987;; A < 0 is best done in the portable way for A an integer.
3988(define_expand "slt"
3989 [(set (match_dup 2) (match_dup 1))
cd2b37d9 3990 (set (match_operand:SI 0 "gpc_reg_operand" "")
1fd4e8c1
RK
3991 (lt:SI (match_dup 2) (const_int 0)))]
3992 ""
3993 "
3994{ enum machine_mode mode = rs6000_compare_fp_p ? CCFPmode : CCmode;
3995
3996 if (! rs6000_compare_fp_p && rs6000_compare_op1 == const0_rtx)
3997 FAIL;
3998
3999 operands[1] = gen_rtx (COMPARE, mode,
4000 rs6000_compare_op0, rs6000_compare_op1);
4001 operands[2] = gen_reg_rtx (mode);
4002}")
4003
4004(define_expand "sge"
4005 [(set (match_dup 2) (match_dup 1))
cd2b37d9 4006 (set (match_operand:SI 0 "gpc_reg_operand" "")
1fd4e8c1
RK
4007 (ge:SI (match_dup 2) (const_int 0)))]
4008 ""
4009 "
4010{ enum machine_mode mode = rs6000_compare_fp_p ? CCFPmode : CCmode;
4011 operands[1] = gen_rtx (COMPARE, mode,
4012 rs6000_compare_op0, rs6000_compare_op1);
4013 operands[2] = gen_reg_rtx (mode);
4014}")
4015
4016;; A <= 0 is best done the portable way for A an integer.
4017(define_expand "sle"
4018 [(set (match_dup 2) (match_dup 1))
cd2b37d9 4019 (set (match_operand:SI 0 "gpc_reg_operand" "")
1fd4e8c1
RK
4020 (le:SI (match_dup 2) (const_int 0)))]
4021 ""
4022 "
4023{ enum machine_mode mode = rs6000_compare_fp_p ? CCFPmode : CCmode;
4024
4025 if (! rs6000_compare_fp_p && rs6000_compare_op1 == const0_rtx)
4026 FAIL;
4027
4028 operands[1] = gen_rtx (COMPARE, mode,
4029 rs6000_compare_op0, rs6000_compare_op1);
4030 operands[2] = gen_reg_rtx (mode);
4031}")
4032
4033(define_expand "sgtu"
4034 [(set (match_dup 2) (match_dup 1))
cd2b37d9 4035 (set (match_operand:SI 0 "gpc_reg_operand" "")
1fd4e8c1
RK
4036 (gtu:SI (match_dup 2) (const_int 0)))]
4037 ""
4038 "
4039{ operands[1] = gen_rtx (COMPARE, CCUNSmode,
4040 rs6000_compare_op0, rs6000_compare_op1);
4041 operands[2] = gen_reg_rtx (CCUNSmode);
4042}")
4043
4044(define_expand "sltu"
4045 [(set (match_dup 2) (match_dup 1))
cd2b37d9 4046 (set (match_operand:SI 0 "gpc_reg_operand" "")
1fd4e8c1
RK
4047 (ltu:SI (match_dup 2) (const_int 0)))]
4048 ""
4049 "
4050{ operands[1] = gen_rtx (COMPARE, CCUNSmode,
4051 rs6000_compare_op0, rs6000_compare_op1);
4052 operands[2] = gen_reg_rtx (CCUNSmode);
4053}")
4054
4055(define_expand "sgeu"
4056 [(set (match_dup 2) (match_dup 1))
cd2b37d9 4057 (set (match_operand:SI 0 "gpc_reg_operand" "")
1fd4e8c1
RK
4058 (geu:SI (match_dup 2) (const_int 0)))]
4059 ""
4060 "
4061{ operands[1] = gen_rtx (COMPARE, CCUNSmode,
4062 rs6000_compare_op0, rs6000_compare_op1);
4063 operands[2] = gen_reg_rtx (CCUNSmode);
4064}")
4065
4066(define_expand "sleu"
4067 [(set (match_dup 2) (match_dup 1))
cd2b37d9 4068 (set (match_operand:SI 0 "gpc_reg_operand" "")
1fd4e8c1
RK
4069 (leu:SI (match_dup 2) (const_int 0)))]
4070 ""
4071 "
4072{ operands[1] = gen_rtx (COMPARE, CCUNSmode,
4073 rs6000_compare_op0, rs6000_compare_op1);
4074 operands[2] = gen_reg_rtx (CCUNSmode);
4075}")
4076\f
4077;; Here are the actual compare insns.
4078(define_insn ""
4079 [(set (match_operand:CC 0 "cc_reg_operand" "=y")
cd2b37d9 4080 (compare:CC (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
4081 (match_operand:SI 2 "reg_or_short_operand" "rI")))]
4082 ""
4083 "cmp%I2 %0,%1,%2"
4084 [(set_attr "type" "compare")])
4085
f357808b
RK
4086;; If we are comparing a register for equality with a large constant,
4087;; we can do this with an XOR followed by a compare. But we need a scratch
4088;; register for the result of the XOR.
4089
4090(define_split
4091 [(set (match_operand:CC 0 "cc_reg_operand" "")
cd2b37d9 4092 (compare:CC (match_operand:SI 1 "gpc_reg_operand" "")
f357808b 4093 (match_operand:SI 2 "non_short_cint_operand" "")))
cd2b37d9 4094 (clobber (match_operand:SI 3 "gpc_reg_operand" ""))]
f357808b
RK
4095 "find_single_use (operands[0], insn, 0)
4096 && (GET_CODE (*find_single_use (operands[0], insn, 0)) == EQ
4097 || GET_CODE (*find_single_use (operands[0], insn, 0)) == NE)"
4098 [(set (match_dup 3) (xor:SI (match_dup 1) (match_dup 4)))
4099 (set (match_dup 0) (compare:CC (match_dup 3) (match_dup 5)))]
4100 "
4101{
4102 /* Get the constant we are comparing against, C, and see what it looks like
4103 sign-extended to 16 bits. Then see what constant could be XOR'ed
4104 with C to get the sign-extended value. */
4105
4106 int c = INTVAL (operands[2]);
4107 int sextc = (c << 16) >> 16;
4108 int xorv = c ^ sextc;
4109
4110 operands[4] = gen_rtx (CONST_INT, VOIDmode, xorv);
4111 operands[5] = gen_rtx (CONST_INT, VOIDmode, sextc);
4112}")
4113
1fd4e8c1
RK
4114(define_insn ""
4115 [(set (match_operand:CCUNS 0 "cc_reg_operand" "=y")
cd2b37d9 4116 (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
4117 (match_operand:SI 2 "reg_or_u_short_operand" "rI")))]
4118 ""
4119 "cmpl%I2 %0,%1,%W2"
4120 [(set_attr "type" "compare")])
4121
4122;; The following two insns don't exist as single insns, but if we provide
4123;; them, we can swap an add and compare, which will enable us to overlap more
4124;; of the required delay between a compare and branch. We generate code for
4125;; them by splitting.
4126
4127(define_insn ""
4128 [(set (match_operand:CC 3 "cc_reg_operand" "=y")
cd2b37d9 4129 (compare:CC (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 4130 (match_operand:SI 2 "short_cint_operand" "i")))
cd2b37d9 4131 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
4132 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "i")))]
4133 ""
baf97f86
RK
4134 "#"
4135 [(set_attr "length" "8")])
1fd4e8c1
RK
4136
4137(define_insn ""
4138 [(set (match_operand:CCUNS 3 "cc_reg_operand" "=y")
cd2b37d9 4139 (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 4140 (match_operand:SI 2 "u_short_cint_operand" "i")))
cd2b37d9 4141 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
4142 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "i")))]
4143 ""
baf97f86
RK
4144 "#"
4145 [(set_attr "length" "8")])
1fd4e8c1
RK
4146
4147(define_split
4148 [(set (match_operand:CC 3 "cc_reg_operand" "")
cd2b37d9 4149 (compare:CC (match_operand:SI 1 "gpc_reg_operand" "")
1fd4e8c1 4150 (match_operand:SI 2 "short_cint_operand" "")))
cd2b37d9 4151 (set (match_operand:SI 0 "gpc_reg_operand" "")
1fd4e8c1
RK
4152 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "")))]
4153 ""
4154 [(set (match_dup 3) (compare:CC (match_dup 1) (match_dup 2)))
4155 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 4)))])
4156
4157(define_split
4158 [(set (match_operand:CCUNS 3 "cc_reg_operand" "")
cd2b37d9 4159 (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "")
1fd4e8c1 4160 (match_operand:SI 2 "u_short_cint_operand" "")))
cd2b37d9 4161 (set (match_operand:SI 0 "gpc_reg_operand" "")
1fd4e8c1
RK
4162 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "")))]
4163 ""
4164 [(set (match_dup 3) (compare:CCUNS (match_dup 1) (match_dup 2)))
4165 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 4)))])
4166
4167(define_insn ""
4168 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
cd2b37d9
RK
4169 (compare:CCFP (match_operand:SF 1 "gpc_reg_operand" "f")
4170 (match_operand:SF 2 "gpc_reg_operand" "f")))]
1fd4e8c1
RK
4171 ""
4172 "fcmpu %0,%1,%2"
4173 [(set_attr "type" "fpcompare")])
4174
4175(define_insn ""
4176 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
cd2b37d9
RK
4177 (compare:CCFP (match_operand:DF 1 "gpc_reg_operand" "f")
4178 (match_operand:DF 2 "gpc_reg_operand" "f")))]
1fd4e8c1
RK
4179 ""
4180 "fcmpu %0,%1,%2"
4181 [(set_attr "type" "fpcompare")])
4182\f
4183;; Now we have the scc insns. We can do some combinations because of the
4184;; way the machine works.
4185;;
4186;; Note that this is probably faster if we can put an insn between the
c5defebb
RK
4187;; mfcr and rlinm, but this is tricky. Let's leave it for now. In most
4188;; cases the insns below which don't use an intermediate CR field will
4189;; be used instead.
1fd4e8c1 4190(define_insn ""
cd2b37d9 4191 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
4192 (match_operator:SI 1 "scc_comparison_operator"
4193 [(match_operand 2 "cc_reg_operand" "y")
4194 (const_int 0)]))]
4195 ""
ca7f5001 4196 "%D1mfcr %0\;{rlinm|rlwinm} %0,%0,%J1,1"
b19003d8 4197 [(set_attr "length" "12")])
1fd4e8c1
RK
4198
4199(define_insn ""
4200 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
4201 (compare:CC (match_operator:SI 1 "scc_comparison_operator"
4202 [(match_operand 2 "cc_reg_operand" "y")
4203 (const_int 0)])
4204 (const_int 0)))
cd2b37d9 4205 (set (match_operand:SI 3 "gpc_reg_operand" "=r")
1fd4e8c1
RK
4206 (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
4207 ""
ca7f5001 4208 "%D1mfcr %3\;{rlinm.|rlwinm.} %3,%3,%J1,1"
b19003d8
RK
4209 [(set_attr "type" "delayed_compare")
4210 (set_attr "length" "12")])
1fd4e8c1
RK
4211
4212(define_insn ""
cd2b37d9 4213 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
4214 (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
4215 [(match_operand 2 "cc_reg_operand" "y")
4216 (const_int 0)])
4217 (match_operand:SI 3 "const_int_operand" "n")))]
4218 ""
4219 "*
4220{
4221 int is_bit = ccr_bit (operands[1], 1);
4222 int put_bit = 31 - (INTVAL (operands[3]) & 31);
4223 int count;
4224
4225 if (is_bit >= put_bit)
4226 count = is_bit - put_bit;
4227 else
4228 count = 32 - (put_bit - is_bit);
4229
4230 operands[4] = gen_rtx (CONST_INT, VOIDmode, count);
4231 operands[5] = gen_rtx (CONST_INT, VOIDmode, put_bit);
4232
ca7f5001 4233 return \"%D1mfcr %0\;{rlinm|rlwinm} %0,%0,%4,%5,%5\";
b19003d8
RK
4234}"
4235 [(set_attr "length" "12")])
1fd4e8c1
RK
4236
4237(define_insn ""
4238 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
4239 (compare:CC
4240 (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
4241 [(match_operand 2 "cc_reg_operand" "y")
4242 (const_int 0)])
4243 (match_operand:SI 3 "const_int_operand" "n"))
4244 (const_int 0)))
cd2b37d9 4245 (set (match_operand:SI 4 "gpc_reg_operand" "=r")
1fd4e8c1
RK
4246 (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
4247 (match_dup 3)))]
4248 ""
4249 "*
4250{
4251 int is_bit = ccr_bit (operands[1], 1);
4252 int put_bit = 31 - (INTVAL (operands[3]) & 31);
4253 int count;
4254
4255 if (is_bit >= put_bit)
4256 count = is_bit - put_bit;
4257 else
4258 count = 32 - (put_bit - is_bit);
4259
4260 operands[5] = gen_rtx (CONST_INT, VOIDmode, count);
4261 operands[6] = gen_rtx (CONST_INT, VOIDmode, put_bit);
4262
ca7f5001 4263 return \"%D1mfcr %4\;{rlinm.|rlwinm.} %4,%4,%5,%6,%6\";
1fd4e8c1 4264}"
b19003d8
RK
4265 [(set_attr "type" "delayed_compare")
4266 (set_attr "length" "12")])
1fd4e8c1 4267
c5defebb
RK
4268;; If we are comparing the result of two comparisons, this can be done
4269;; using creqv or crxor.
4270
4271(define_insn ""
4272 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y")
4273 (compare:CCEQ (match_operator 1 "scc_comparison_operator"
4274 [(match_operand 2 "cc_reg_operand" "y")
4275 (const_int 0)])
4276 (match_operator 3 "scc_comparison_operator"
4277 [(match_operand 4 "cc_reg_operand" "y")
4278 (const_int 0)])))]
4279 "REGNO (operands[2]) != REGNO (operands[4])"
4280 "*
4281{
4282 enum rtx_code code1, code2;
4283
4284 code1 = GET_CODE (operands[1]);
4285 code2 = GET_CODE (operands[3]);
4286
4287 if ((code1 == EQ || code1 == LT || code1 == GT
4288 || code1 == LTU || code1 == GTU
4289 || (code1 != NE && GET_MODE (operands[2]) == CCFPmode))
4290 !=
4291 (code2 == EQ || code2 == LT || code2 == GT
4292 || code2 == LTU || code2 == GTU
4293 || (code2 != NE && GET_MODE (operands[4]) == CCFPmode)))
4294 return \"%C1%C3crxor %E0,%j1,%j3\";
4295 else
4296 return \"%C1%C3creqv %E0,%j1,%j3\";
b19003d8
RK
4297}"
4298 [(set_attr "length" "12")])
c5defebb
RK
4299
4300;; There is a 3 cycle delay between consecutive mfcr instructions
4301;; so it is useful to combine 2 scc instructions to use only one mfcr.
4302
4303(define_peephole
cd2b37d9 4304 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
c5defebb
RK
4305 (match_operator:SI 1 "scc_comparison_operator"
4306 [(match_operand 2 "cc_reg_operand" "y")
4307 (const_int 0)]))
cd2b37d9 4308 (set (match_operand:SI 3 "gpc_reg_operand" "=r")
c5defebb
RK
4309 (match_operator:SI 4 "scc_comparison_operator"
4310 [(match_operand 5 "cc_reg_operand" "y")
4311 (const_int 0)]))]
4312 "REGNO (operands[2]) != REGNO (operands[5])"
ca7f5001 4313 "%D1%D4mfcr %3\;{rlinm|rlwinm} %0,%3,%J1,1\;{rlinm|rlwinm} %3,%3,%J4,1"
b19003d8 4314 [(set_attr "length" "20")])
c5defebb 4315
1fd4e8c1
RK
4316;; There are some scc insns that can be done directly, without a compare.
4317;; These are faster because they don't involve the communications between
4318;; the FXU and branch units. In fact, we will be replacing all of the
4319;; integer scc insns here or in the portable methods in emit_store_flag.
4320;;
4321;; Also support (neg (scc ..)) since that construct is used to replace
4322;; branches, (plus (scc ..) ..) since that construct is common and
4323;; takes no more insns than scc, and (and (neg (scc ..)) ..) in the
4324;; cases where it is no more expensive than (neg (scc ..)).
4325
4326;; Have reload force a constant into a register for the simple insns that
4327;; otherwise won't accept constants. We do this because it is faster than
4328;; the cmp/mfcr sequence we would otherwise generate.
4329
4330(define_insn ""
cd2b37d9
RK
4331 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r,r")
4332 (eq:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r")
1fd4e8c1
RK
4333 (match_operand:SI 2 "reg_or_cint_operand" "r,O,K,J,I")))
4334 (clobber (match_scratch:SI 3 "=r,&r,r,r,r"))]
4335 ""
4336 "@
ca7f5001 4337 xor %0,%1,%2\;{sfi|subfic} %3,%0,0\;{ae|adde} %0,%3,%0
71d2371f 4338 {sfi|subfic} %3,%1,0\;{ae|adde} %0,%3,%1
ca7f5001
RK
4339 {xoril|xori} %0,%1,%b2\;{sfi|subfic} %3,%0,0\;{ae|adde} %0,%3,%0
4340 {xoriu|xoris} %0,%1,%u2\;{sfi|subfic} %3,%0,0\;{ae|adde} %0,%3,%0
4341 {sfi|subfic} %0,%1,%2\;{sfi|subfic} %3,%0,0\;{ae|adde} %0,%3,%0"
b19003d8 4342 [(set_attr "length" "12,8,12,12,12")])
1fd4e8c1
RK
4343
4344(define_insn ""
4345 [(set (match_operand:CC 4 "cc_reg_operand" "=x,x,x,x,x")
4346 (compare:CC
cd2b37d9 4347 (eq:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r")
1fd4e8c1
RK
4348 (match_operand:SI 2 "reg_or_cint_operand" "r,O,K,J,I"))
4349 (const_int 0)))
cd2b37d9 4350 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r,r")
1fd4e8c1
RK
4351 (eq:SI (match_dup 1) (match_dup 2)))
4352 (clobber (match_scratch:SI 3 "=r,&r,r,r,r"))]
4353 ""
4354 "@
ca7f5001
RK
4355 xor %0,%1,%2\;{sfi|subfic} %3,%0,0\;{ae.|adde.} %0,%3,%0
4356 {sfi|subfic} %3,%1,0\;{ae.|adde.} %0,%3,%1
4357 {xoril|xori} %0,%1,%b2\;{sfi|subfic} %3,%0,0\;{ae.|adde.} %0,%3,%0
4358 {xoriu|xoris} %0,%1,%u2\;{sfi|subfic} %3,%0,0\;{ae.|adde.} %0,%3,%0
4359 {sfi|subfic} %0,%1,%2\;{sfi|subfic} %3,%0,0\;{ae.|adde.} %0,%3,%0"
b19003d8
RK
4360 [(set_attr "type" "compare")
4361 (set_attr "length" "12,8,12,12,12")])
4362
4363;; We have insns of the form shown by the first define_insn below. If
4364;; there is something inside the comparison operation, we must split it.
4365(define_split
4366 [(set (match_operand:SI 0 "gpc_reg_operand" "")
4367 (plus:SI (match_operator 1 "comparison_operator"
4368 [(match_operand:SI 2 "" "")
4369 (match_operand:SI 3
4370 "reg_or_cint_operand" "")])
4371 (match_operand:SI 4 "gpc_reg_operand" "")))
4372 (clobber (match_operand:SI 5 "register_operand" ""))]
4373 "! gpc_reg_operand (operands[2], SImode)"
4374 [(set (match_dup 5) (match_dup 2))
4375 (set (match_dup 2) (plus:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
4376 (match_dup 4)))])
1fd4e8c1
RK
4377
4378(define_insn ""
cd2b37d9
RK
4379 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r,r")
4380 (plus:SI (eq:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r")
1fd4e8c1 4381 (match_operand:SI 2 "reg_or_cint_operand" "r,O,K,J,I"))
cd2b37d9 4382 (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r,r")))
1fd4e8c1
RK
4383 (clobber (match_scratch:SI 4 "=&r,&r,&r,&r,&r"))]
4384 ""
4385 "@
ca7f5001
RK
4386 xor %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze|addze} %0,%3
4387 {sfi|subfic} %4,%1,0\;{aze|addze} %0,%3
4388 {xoril|xori} %4,%1,%b2\;{sfi|subfic} %4,%4,0\;{aze|addze} %0,%3
4389 {xoriu|xoris} %4,%1,%u2\;{sfi|subfic} %4,%4,0\;{aze|addze} %0,%3
4390 {sfi|subfic} %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze|adddze} %0,%3"
b19003d8 4391 [(set_attr "length" "12,8,12,12,12")])
1fd4e8c1
RK
4392
4393(define_insn ""
4394 [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,x,x,x")
4395 (compare:CC
4396 (plus:SI
cd2b37d9 4397 (eq:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r")
1fd4e8c1 4398 (match_operand:SI 2 "reg_or_cint_operand" "r,O,K,J,I"))
cd2b37d9 4399 (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r,r"))
1fd4e8c1
RK
4400 (const_int 0)))
4401 (clobber (match_scratch:SI 4 "=&r,&r,&r,&r,&r"))]
4402 ""
4403 "@
ca7f5001
RK
4404 xor %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %4,%3
4405 {sfi|subfic} %4,%1,0\;{aze.|addze.} %0,%3
4406 {xoril|xori} %4,%1,%b2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %4,%3
4407 {xoriu|xoris} %4,%1,%u2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %4,%3
4408 {sfi|subfic} %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %4,%3"
b19003d8
RK
4409 [(set_attr "type" "compare")
4410 (set_attr "length" "12,8,12,12,12")])
1fd4e8c1
RK
4411
4412(define_insn ""
4413 [(set (match_operand:CC 5 "cc_reg_operand" "=x,x,x,x,x")
4414 (compare:CC
4415 (plus:SI
cd2b37d9 4416 (eq:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r")
1fd4e8c1 4417 (match_operand:SI 2 "reg_or_cint_operand" "r,O,K,J,I"))
cd2b37d9 4418 (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r,r"))
1fd4e8c1 4419 (const_int 0)))
cd2b37d9 4420 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r,r")
1fd4e8c1
RK
4421 (plus:SI (eq:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
4422 (clobber (match_scratch:SI 4 "=&r,&r,&r,&r,&r"))]
4423 ""
4424 "@
ca7f5001
RK
4425 xor %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %0,%3
4426 {sfi|subfic} %4,%1,0\;{aze.|addze.} %4,%3
4427 {xoril|xori} %4,%1,%b2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %0,%3
4428 {xoriu|xoris} %4,%1,%u2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %0,%3
4429 {sfi|subfic} %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %0,%3"
b19003d8
RK
4430 [(set_attr "type" "compare")
4431 (set_attr "length" "12,8,12,12,12")])
1fd4e8c1
RK
4432
4433(define_insn ""
cd2b37d9
RK
4434 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r,r")
4435 (neg:SI (eq:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r,r")
1fd4e8c1
RK
4436 (match_operand:SI 2 "reg_or_cint_operand" "r,O,K,J,I"))))]
4437 ""
4438 "@
ca7f5001
RK
4439 xor %0,%1,%2\;{ai|addic} %0,%0,-1\;{sfe|subfe} %0,%0,%0
4440 {ai|addic} %0,%1,-1\;{sfe|subfe} %0,%0,%0
4441 {xoril|xori} %0,%1,%b2\;{ai|addic} %0,%0,-1\;{sfe|subfe} %0,%0,%0
4442 {xoriu|xoris} %0,%1,%u2\;{ai|addic} %0,%0,-1\;{sfe|subfe} %0,%0,%0
4443 {sfi|subfic} %0,%1,%2\;{ai|addic} %0,%0,-1\;{sfe|subfe} %0,%0,%0"
b19003d8 4444 [(set_attr "length" "12,8,12,12,12")])
1fd4e8c1
RK
4445
4446;; This is what (plus (ne X (const_int 0)) Y) looks like.
4447(define_insn ""
cd2b37d9 4448 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1 4449 (plus:SI (lshiftrt:SI
cd2b37d9 4450 (neg:SI (abs:SI (match_operand:SI 1 "gpc_reg_operand" "r")))
1fd4e8c1 4451 (const_int 31))
cd2b37d9 4452 (match_operand:SI 2 "gpc_reg_operand" "r")))
1fd4e8c1
RK
4453 (clobber (match_scratch:SI 3 "=&r"))]
4454 ""
ca7f5001 4455 "{ai|addic} %3,%1,-1\;{aze|addze} %0,%2"
b19003d8 4456 [(set_attr "length" "8")])
1fd4e8c1
RK
4457
4458(define_insn ""
4459 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
4460 (compare:CC
4461 (plus:SI (lshiftrt:SI
cd2b37d9 4462 (neg:SI (abs:SI (match_operand:SI 1 "gpc_reg_operand" "r")))
1fd4e8c1 4463 (const_int 31))
cd2b37d9 4464 (match_operand:SI 2 "gpc_reg_operand" "r"))
1fd4e8c1
RK
4465 (const_int 0)))
4466 (clobber (match_scratch:SI 3 "=&r"))]
4467 ""
ca7f5001 4468 "{ai|addic} %3,%1,-1\;{aze.|addze.} %3,%2"
b19003d8
RK
4469 [(set_attr "type" "compare")
4470 (set_attr "length" "8")])
1fd4e8c1
RK
4471
4472(define_insn ""
4473 [(set (match_operand:CC 4 "cc_reg_operand" "=x")
4474 (compare:CC
4475 (plus:SI (lshiftrt:SI
cd2b37d9 4476 (neg:SI (abs:SI (match_operand:SI 1 "gpc_reg_operand" "r")))
1fd4e8c1 4477 (const_int 31))
cd2b37d9 4478 (match_operand:SI 2 "gpc_reg_operand" "r"))
1fd4e8c1 4479 (const_int 0)))
cd2b37d9 4480 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
4481 (plus:SI (lshiftrt:SI (neg:SI (abs:SI (match_dup 1))) (const_int 31))
4482 (match_dup 2)))
4483 (clobber (match_scratch:SI 3 "=&r"))]
4484 ""
ca7f5001 4485 "{ai|addic} %3,%1,-1\;{aze.|addze.} %0,%2"
b19003d8
RK
4486 [(set_attr "type" "compare")
4487 (set_attr "length" "8")])
1fd4e8c1
RK
4488
4489(define_insn ""
cd2b37d9
RK
4490 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
4491 (le:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1
RK
4492 (match_operand:SI 2 "reg_or_short_operand" "r,O")))
4493 (clobber (match_scratch:SI 3 "=r,X"))]
ca7f5001 4494 "TARGET_POWER"
1fd4e8c1 4495 "@
ca7f5001
RK
4496 doz %3,%2,%1\;{sfi|subfic} %0,%3,0\;{ae|adde} %0,%0,%3
4497 {ai|addic} %0,%1,-1\;{aze|addze} %0,%0\;sri %0,%0,31"
b19003d8 4498 [(set_attr "length" "12")])
1fd4e8c1
RK
4499
4500(define_insn ""
4501 [(set (match_operand:CC 4 "cc_reg_operand" "=x,x")
4502 (compare:CC
cd2b37d9 4503 (le:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1
RK
4504 (match_operand:SI 2 "reg_or_short_operand" "r,O"))
4505 (const_int 0)))
cd2b37d9 4506 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
1fd4e8c1
RK
4507 (le:SI (match_dup 1) (match_dup 2)))
4508 (clobber (match_scratch:SI 3 "=r,X"))]
ca7f5001 4509 "TARGET_POWER"
1fd4e8c1 4510 "@
ca7f5001
RK
4511 doz %3,%2,%1\;{sfi|subfic} %0,%3,0\;{ae.|adde.} %0,%0,%3
4512 {ai|addic} %0,%1,-1\;{aze|addze} %0,%0\;sri. %0,%0,31"
b19003d8
RK
4513 [(set_attr "type" "delayed_compare,compare")
4514 (set_attr "length" "12")])
1fd4e8c1
RK
4515
4516(define_insn ""
cd2b37d9
RK
4517 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
4518 (plus:SI (le:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1 4519 (match_operand:SI 2 "reg_or_short_operand" "r,O"))
cd2b37d9 4520 (match_operand:SI 3 "gpc_reg_operand" "r,r")))
1fd4e8c1 4521 (clobber (match_scratch:SI 4 "=&r,&r"))]
ca7f5001 4522 "TARGET_POWER"
1fd4e8c1 4523 "@
ca7f5001
RK
4524 doz %4,%2,%1\;{sfi|subfic} %4,%4,0\;{aze|addze} %0,%3
4525 {srai|srawi} %4,%1,31\;{sf|subfc} %4,%1,%4\;{aze|addze} %0,%3"
b19003d8 4526 [(set_attr "length" "12")])
1fd4e8c1
RK
4527
4528(define_insn ""
4529 [(set (match_operand:CC 0 "cc_reg_operand" "=x,x")
4530 (compare:CC
cd2b37d9 4531 (plus:SI (le:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1 4532 (match_operand:SI 2 "reg_or_short_operand" "r,O"))
cd2b37d9 4533 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
1fd4e8c1
RK
4534 (const_int 0)))
4535 (clobber (match_scratch:SI 4 "=&r,&r"))]
ca7f5001 4536 "TARGET_POWER"
1fd4e8c1 4537 "@
ca7f5001
RK
4538 doz %4,%2,%1\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %4,%3
4539 {srai|srawi} %4,%1,31\;{sf|subfc} %4,%1,%4\;{aze.|addze.} %4,%3"
b19003d8
RK
4540 [(set_attr "type" "compare")
4541 (set_attr "length" "12")])
1fd4e8c1
RK
4542
4543(define_insn ""
4544 [(set (match_operand:CC 5 "cc_reg_operand" "=x,x")
4545 (compare:CC
cd2b37d9 4546 (plus:SI (le:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1 4547 (match_operand:SI 2 "reg_or_short_operand" "r,O"))
cd2b37d9 4548 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
1fd4e8c1 4549 (const_int 0)))
cd2b37d9 4550 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
1fd4e8c1
RK
4551 (plus:SI (le:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
4552 (clobber (match_scratch:SI 4 "=&r,&r"))]
ca7f5001 4553 "TARGET_POWER"
1fd4e8c1 4554 "@
ca7f5001
RK
4555 doz %4,%2,%1\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %0,%3
4556 {srai|srawi} %4,%1,31\;{sf|subfc} %4,%1,%4\;{aze.|addze.} %0,%3"
b19003d8
RK
4557 [(set_attr "type" "compare")
4558 (set_attr "length" "12")])
1fd4e8c1
RK
4559
4560(define_insn ""
cd2b37d9
RK
4561 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
4562 (neg:SI (le:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1 4563 (match_operand:SI 2 "reg_or_short_operand" "r,O"))))]
ca7f5001 4564 "TARGET_POWER"
1fd4e8c1 4565 "@
ca7f5001
RK
4566 doz %0,%2,%1\;{ai|addic} %0,%0,-1\;{sfe|subfe} %0,%0,%0
4567 {ai|addic} %0,%1,-1\;{aze|addze} %0,%0\;{srai|srawi} %0,%0,31"
b19003d8 4568 [(set_attr "length" "12")])
1fd4e8c1
RK
4569
4570(define_insn ""
cd2b37d9
RK
4571 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
4572 (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
4573 (match_operand:SI 2 "reg_or_short_operand" "rI")))]
4574 ""
ca7f5001 4575 "{sf%I2|subf%I2c} %0,%1,%2\;{cal %0,0(0)|li %0,0}\;{ae|adde} %0,%0,%0"
b19003d8 4576 [(set_attr "length" "12")])
1fd4e8c1
RK
4577
4578(define_insn ""
4579 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
4580 (compare:CC
cd2b37d9 4581 (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
4582 (match_operand:SI 2 "reg_or_short_operand" "rI"))
4583 (const_int 0)))
cd2b37d9 4584 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
4585 (leu:SI (match_dup 1) (match_dup 2)))]
4586 ""
ca7f5001 4587 "{sf%I2|subf%I2c} %0,%1,%2\;{cal %0,0(0)|li %0,0}\;{ae.|adde.} %0,%0,%0"
b19003d8
RK
4588 [(set_attr "type" "compare")
4589 (set_attr "length" "12")])
1fd4e8c1
RK
4590
4591(define_insn ""
cd2b37d9
RK
4592 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
4593 (plus:SI (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 4594 (match_operand:SI 2 "reg_or_short_operand" "rI"))
cd2b37d9 4595 (match_operand:SI 3 "gpc_reg_operand" "r")))
1fd4e8c1
RK
4596 (clobber (match_scratch:SI 4 "=&r"))]
4597 ""
ca7f5001 4598 "{sf%I2|subf%I2c} %4,%1,%2\;{aze|addze} %0,%3"
b19003d8 4599 [(set_attr "length" "8")])
1fd4e8c1
RK
4600
4601(define_insn ""
4602 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
4603 (compare:CC
cd2b37d9 4604 (plus:SI (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 4605 (match_operand:SI 2 "reg_or_short_operand" "rI"))
cd2b37d9 4606 (match_operand:SI 3 "gpc_reg_operand" "r"))
1fd4e8c1
RK
4607 (const_int 0)))
4608 (clobber (match_scratch:SI 4 "=&r"))]
4609 ""
ca7f5001 4610 "{sf%I2|subf%I2c} %4,%1,%2\;{aze.|addze.} %4,%3"
b19003d8
RK
4611 [(set_attr "type" "compare")
4612 (set_attr "length" "8")])
1fd4e8c1
RK
4613
4614(define_insn ""
4615 [(set (match_operand:CC 5 "cc_reg_operand" "=x")
4616 (compare:CC
cd2b37d9 4617 (plus:SI (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 4618 (match_operand:SI 2 "reg_or_short_operand" "rI"))
cd2b37d9 4619 (match_operand:SI 3 "gpc_reg_operand" "r"))
1fd4e8c1 4620 (const_int 0)))
cd2b37d9 4621 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
4622 (plus:SI (leu:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
4623 (clobber (match_scratch:SI 4 "=&r"))]
4624 ""
ca7f5001 4625 "{sf%I2|subf%I2c} %4,%1,%2\;{aze.|addze.} %0,%3"
b19003d8
RK
4626 [(set_attr "type" "compare")
4627 (set_attr "length" "8")])
1fd4e8c1
RK
4628
4629(define_insn ""
cd2b37d9
RK
4630 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
4631 (neg:SI (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
4632 (match_operand:SI 2 "reg_or_short_operand" "rI"))))]
4633 ""
ca7f5001 4634 "{sf%I2|subf%I2c} %0,%1,%2\;{sfe|subfe} %0,%0,%0\;nand %0,%0,%0"
b19003d8 4635 [(set_attr "length" "12")])
1fd4e8c1
RK
4636
4637(define_insn ""
cd2b37d9 4638 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1 4639 (and:SI (neg:SI
cd2b37d9 4640 (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 4641 (match_operand:SI 2 "reg_or_short_operand" "rI")))
cd2b37d9 4642 (match_operand:SI 3 "gpc_reg_operand" "r")))
1fd4e8c1
RK
4643 (clobber (match_scratch:SI 4 "=&r"))]
4644 ""
ca7f5001 4645 "{sf%I2|subf%I2c} %4,%1,%2\;{sfe|subfe} %4,%4,%4\;andc %0,%3,%4"
b19003d8 4646 [(set_attr "length" "12")])
1fd4e8c1
RK
4647
4648(define_insn ""
4649 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
4650 (compare:CC
4651 (and:SI (neg:SI
cd2b37d9 4652 (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 4653 (match_operand:SI 2 "reg_or_short_operand" "rI")))
cd2b37d9 4654 (match_operand:SI 3 "gpc_reg_operand" "r"))
1fd4e8c1
RK
4655 (const_int 0)))
4656 (clobber (match_scratch:SI 4 "=&r"))]
4657 ""
ca7f5001 4658 "{sf%I2|subf%I2c} %4,%1,%2\;{sfe|subfe} %4,%4,%4\;andc. %4,%3,%4"
b19003d8
RK
4659 [(set_attr "type" "compare")
4660 (set_attr "length" "12")])
1fd4e8c1
RK
4661
4662(define_insn ""
4663 [(set (match_operand:CC 5 "cc_reg_operand" "=x")
4664 (compare:CC
4665 (and:SI (neg:SI
cd2b37d9 4666 (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 4667 (match_operand:SI 2 "reg_or_short_operand" "rI")))
cd2b37d9 4668 (match_operand:SI 3 "gpc_reg_operand" "r"))
1fd4e8c1 4669 (const_int 0)))
cd2b37d9 4670 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
4671 (and:SI (neg:SI (leu:SI (match_dup 1) (match_dup 2))) (match_dup 3)))
4672 (clobber (match_scratch:SI 4 "=&r"))]
4673 ""
ca7f5001 4674 "{sf%I2|subf%I2c} %4,%1,%2\;{sfe|subfe} %4,%4,%4\;andc. %0,%3,%4"
b19003d8
RK
4675 [(set_attr "type" "compare")
4676 (set_attr "length" "12")])
1fd4e8c1
RK
4677
4678(define_insn ""
cd2b37d9
RK
4679 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
4680 (lt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 4681 (match_operand:SI 2 "reg_or_short_operand" "rI")))]
ca7f5001 4682 "TARGET_POWER"
b19003d8
RK
4683 "doz%I2 %0,%1,%2\;nabs %0,%0\;sri %0,%0,31"
4684 [(set_attr "length" "12")])
1fd4e8c1
RK
4685
4686(define_insn ""
4687 [(set (match_operand:SI 3 "cc_reg_operand" "=x")
4688 (compare:CC
cd2b37d9 4689 (lt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
4690 (match_operand:SI 2 "reg_or_short_operand" "rI"))
4691 (const_int 0)))
cd2b37d9 4692 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1 4693 (lt:SI (match_dup 1) (match_dup 2)))]
ca7f5001 4694 "TARGET_POWER"
1fd4e8c1 4695 "doz%I2 %0,%1,%2\;nabs %0,%0\;sri. %0,%0,31"
b19003d8
RK
4696 [(set_attr "type" "delayed_compare")
4697 (set_attr "length" "12")])
1fd4e8c1
RK
4698
4699(define_insn ""
cd2b37d9
RK
4700 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
4701 (plus:SI (lt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 4702 (match_operand:SI 2 "reg_or_short_operand" "rI"))
cd2b37d9 4703 (match_operand:SI 3 "gpc_reg_operand" "r")))
1fd4e8c1 4704 (clobber (match_scratch:SI 4 "=&r"))]
ca7f5001
RK
4705 "TARGET_POWER"
4706 "doz%I2 %4,%1,%2\;{ai|addic} %4,%4,-1\;{aze|addze} %0,%3"
b19003d8 4707 [(set_attr "length" "12")])
1fd4e8c1
RK
4708
4709(define_insn ""
4710 [(set (match_operand:SI 0 "cc_reg_operand" "=x")
4711 (compare:CC
cd2b37d9 4712 (plus:SI (lt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 4713 (match_operand:SI 2 "reg_or_short_operand" "rI"))
cd2b37d9 4714 (match_operand:SI 3 "gpc_reg_operand" "r"))
1fd4e8c1
RK
4715 (const_int 0)))
4716 (clobber (match_scratch:SI 4 "=&r"))]
ca7f5001
RK
4717 "TARGET_POWER"
4718 "doz%I2 %4,%1,%2\;{ai|addic} %4,%4,-1\;{aze.|addze.} %4,%3"
b19003d8
RK
4719 [(set_attr "type" "compare")
4720 (set_attr "length" "12")])
1fd4e8c1
RK
4721
4722(define_insn ""
4723 [(set (match_operand:SI 5 "cc_reg_operand" "=x")
4724 (compare:CC
cd2b37d9 4725 (plus:SI (lt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 4726 (match_operand:SI 2 "reg_or_short_operand" "rI"))
cd2b37d9 4727 (match_operand:SI 3 "gpc_reg_operand" "r"))
1fd4e8c1 4728 (const_int 0)))
cd2b37d9 4729 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
4730 (plus:SI (lt:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
4731 (clobber (match_scratch:SI 4 "=&r"))]
ca7f5001
RK
4732 "TARGET_POWER"
4733 "doz%I2 %4,%1,%2\;{ai|addic} %4,%4,-1\;{aze.|addze.} %0,%3"
b19003d8
RK
4734 [(set_attr "type" "compare")
4735 (set_attr "length" "12")])
1fd4e8c1
RK
4736
4737(define_insn ""
cd2b37d9
RK
4738 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
4739 (neg:SI (lt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 4740 (match_operand:SI 2 "reg_or_short_operand" "rI"))))]
ca7f5001
RK
4741 "TARGET_POWER"
4742 "doz%I2 %0,%1,%2\;nabs %0,%0\;{srai|srawi} %0,%0,31"
b19003d8 4743 [(set_attr "length" "12")])
1fd4e8c1
RK
4744
4745(define_insn ""
cd2b37d9
RK
4746 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
4747 (ltu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1
RK
4748 (match_operand:SI 2 "reg_or_neg_short_operand" "r,P")))]
4749 ""
4750 "@
ca7f5001
RK
4751 {sf|subfc} %0,%2,%1\;{sfe|subfe} %0,%0,%0\;neg %0,%0
4752 {ai|addic} %0,%1,%n2\;{sfe|subfe} %0,%0,%0\;neg %0,%0"
b19003d8 4753 [(set_attr "length" "12")])
1fd4e8c1
RK
4754
4755(define_insn ""
4756 [(set (match_operand:CC 3 "cc_reg_operand" "=x,x")
4757 (compare:CC
cd2b37d9 4758 (ltu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1
RK
4759 (match_operand:SI 2 "reg_or_neg_short_operand" "r,P"))
4760 (const_int 0)))
cd2b37d9 4761 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
1fd4e8c1
RK
4762 (ltu:SI (match_dup 1) (match_dup 2)))]
4763 ""
4764 "@
ca7f5001
RK
4765 {sf|subfc} %0,%2,%1\;{sfe|subfe} %0,%0,%0\;neg. %0,%0
4766 {ai|addic} %0,%1,%n2\;{sfe|subfe} %0,%0,%0\;neg. %0,%0"
b19003d8
RK
4767 [(set_attr "type" "compare")
4768 (set_attr "length" "12")])
1fd4e8c1
RK
4769
4770(define_insn ""
cd2b37d9
RK
4771 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r")
4772 (plus:SI (ltu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r")
1fd4e8c1
RK
4773 (match_operand:SI 2 "reg_or_neg_short_operand" "r,r,P,P"))
4774 (match_operand:SI 3 "reg_or_short_operand" "r,I,r,I")))
4775 (clobber (match_scratch:SI 4 "=&r,r,&r,r"))]
4776 ""
4777 "@
ca7f5001
RK
4778 {sf|subfc} %4,%2,%1\;{sfe|subfe} %4,%4,%4\;{sf%I3|subf%I3c} %0,%4,%3
4779 {sf|subfc} %4,%2,%1\;{sfe|subfe} %4,%4,%4\;{sf%I3|subf%I3c} %0,%4,%3
4780 {ai|addic} %4,%1,%n2\;{sfe|subfe} %4,%4,%4\;{sf%I3|subf%I3c} %0,%4,%3
4781 {ai|addic} %4,%1,%n2\;{sfe|subfe} %4,%4,%4\;{sf%I3|subf%I3c} %0,%4,%3"
b19003d8 4782 [(set_attr "length" "12")])
1fd4e8c1
RK
4783
4784(define_insn ""
3d91674b 4785 [(set (match_operand:CC 0 "cc_reg_operand" "=x,x")
1fd4e8c1 4786 (compare:CC
3d91674b
RK
4787 (plus:SI (ltu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
4788 (match_operand:SI 2 "reg_or_neg_short_operand" "r,P"))
4789 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
1fd4e8c1 4790 (const_int 0)))
3d91674b 4791 (clobber (match_scratch:SI 4 "=&r,&r"))]
1fd4e8c1
RK
4792 ""
4793 "@
ca7f5001
RK
4794 {sf|subfc} %4,%2,%1\;{sfe|subfe} %4,%4,%4\;{sf.|subfc.} %4,%4,%3
4795 {ai|addic} %4,%1,%n2\;{sfe|subfe} %4,%4,%4\;{sf.|subfc.} %4,%4,%3"
b19003d8
RK
4796 [(set_attr "type" "compare")
4797 (set_attr "length" "12")])
1fd4e8c1
RK
4798
4799(define_insn ""
3d91674b 4800 [(set (match_operand:CC 5 "cc_reg_operand" "=x,x")
1fd4e8c1 4801 (compare:CC
3d91674b
RK
4802 (plus:SI (ltu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
4803 (match_operand:SI 2 "reg_or_neg_short_operand" "r,P"))
4804 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
1fd4e8c1 4805 (const_int 0)))
3d91674b 4806 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
1fd4e8c1 4807 (plus:SI (ltu:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
3d91674b 4808 (clobber (match_scratch:SI 4 "=&r,&r"))]
1fd4e8c1
RK
4809 ""
4810 "@
ca7f5001
RK
4811 {sf|subfc} %4,%2,%1\;{sfe|subfe} %4,%4,%4\;{sf.|subfc.} %0,%4,%3
4812 {ai|addic} %4,%1,%n2\;{sfe|subfe} %4,%4,%4\;{sf.|subfc.} %0,%4,%3"
b19003d8
RK
4813 [(set_attr "type" "compare")
4814 (set_attr "length" "12")])
1fd4e8c1
RK
4815
4816(define_insn ""
cd2b37d9
RK
4817 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
4818 (neg:SI (ltu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1
RK
4819 (match_operand:SI 2 "reg_or_neg_short_operand" "r,P"))))]
4820 ""
4821 "@
ca7f5001
RK
4822 {sf|subfc} %0,%2,%1\;{sfe|subfe} %0,%0,%0
4823 {ai|addic} %0,%1,%n2\;{sfe|subfe} %0,%0,%0"
b19003d8 4824 [(set_attr "length" "8")])
1fd4e8c1
RK
4825
4826(define_insn ""
cd2b37d9
RK
4827 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
4828 (ge:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
4829 (match_operand:SI 2 "reg_or_short_operand" "rI")))
4830 (clobber (match_scratch:SI 3 "=r"))]
ca7f5001
RK
4831 "TARGET_POWER"
4832 "doz%I2 %3,%1,%2\;{sfi|subfic} %0,%3,0\;{ae|adde} %0,%0,%3"
b19003d8 4833 [(set_attr "length" "12")])
1fd4e8c1
RK
4834
4835(define_insn ""
4836 [(set (match_operand:CC 4 "cc_reg_operand" "=x")
4837 (compare:CC
cd2b37d9 4838 (ge:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
4839 (match_operand:SI 2 "reg_or_short_operand" "rI"))
4840 (const_int 0)))
cd2b37d9 4841 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
4842 (ge:SI (match_dup 1) (match_dup 2)))
4843 (clobber (match_scratch:SI 3 "=r"))]
ca7f5001
RK
4844 "TARGET_POWER"
4845 "doz%I2 %3,%1,%2\;{sfi|subfic} %0,%3,0\;{ae.|adde.} %0,%0,%3"
b19003d8
RK
4846 [(set_attr "type" "compare")
4847 (set_attr "length" "12")])
1fd4e8c1
RK
4848
4849(define_insn ""
cd2b37d9
RK
4850 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
4851 (plus:SI (ge:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 4852 (match_operand:SI 2 "reg_or_short_operand" "rI"))
cd2b37d9 4853 (match_operand:SI 3 "gpc_reg_operand" "r")))
1fd4e8c1 4854 (clobber (match_scratch:SI 4 "=&r"))]
ca7f5001
RK
4855 "TARGET_POWER"
4856 "doz%I2 %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze|addze} %0,%3"
b19003d8 4857 [(set_attr "length" "12")])
1fd4e8c1
RK
4858
4859(define_insn ""
4860 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
4861 (compare:CC
cd2b37d9 4862 (plus:SI (ge:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 4863 (match_operand:SI 2 "reg_or_short_operand" "rI"))
cd2b37d9 4864 (match_operand:SI 3 "gpc_reg_operand" "r"))
1fd4e8c1
RK
4865 (const_int 0)))
4866 (clobber (match_scratch:SI 4 "=&r"))]
ca7f5001
RK
4867 "TARGET_POWER"
4868 "doz%I2 %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %4,%3"
b19003d8
RK
4869 [(set_attr "type" "compare")
4870 (set_attr "length" "12")])
1fd4e8c1
RK
4871
4872(define_insn ""
4873 [(set (match_operand:CC 5 "cc_reg_operand" "=x")
4874 (compare:CC
cd2b37d9 4875 (plus:SI (ge:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 4876 (match_operand:SI 2 "reg_or_short_operand" "rI"))
cd2b37d9 4877 (match_operand:SI 3 "gpc_reg_operand" "r"))
1fd4e8c1 4878 (const_int 0)))
cd2b37d9 4879 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
4880 (plus:SI (ge:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
4881 (clobber (match_scratch:SI 4 "=&r"))]
ca7f5001
RK
4882 "TARGET_POWER"
4883 "doz%I2 %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %0,%3"
b19003d8
RK
4884 [(set_attr "type" "compare")
4885 (set_attr "length" "12")])
1fd4e8c1
RK
4886
4887(define_insn ""
cd2b37d9
RK
4888 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
4889 (neg:SI (ge:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 4890 (match_operand:SI 2 "reg_or_short_operand" "rI"))))]
ca7f5001
RK
4891 "TARGET_POWER"
4892 "doz%I2 %0,%1,%2\;{ai|addic} %0,%0,-1\;{sfe|subfe} %0,%0,%0"
b19003d8 4893 [(set_attr "length" "12")])
1fd4e8c1
RK
4894
4895;; This is (and (neg (ge X (const_int 0))) Y).
4896(define_insn ""
cd2b37d9 4897 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
4898 (and:SI (neg:SI
4899 (lshiftrt:SI
cd2b37d9 4900 (not:SI (match_operand:SI 1 "gpc_reg_operand" "r"))
1fd4e8c1 4901 (const_int 31)))
cd2b37d9 4902 (match_operand:SI 2 "gpc_reg_operand" "r")))
1fd4e8c1
RK
4903 (clobber (match_scratch:SI 3 "=&r"))]
4904 ""
ca7f5001 4905 "{srai|srawi} %3,%1,31\;andc %0,%2,%3"
b19003d8 4906 [(set_attr "length" "8")])
1fd4e8c1
RK
4907
4908(define_insn ""
4909 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
4910 (compare:CC
4911 (and:SI (neg:SI
4912 (lshiftrt:SI
cd2b37d9 4913 (not:SI (match_operand:SI 1 "gpc_reg_operand" "r"))
1fd4e8c1 4914 (const_int 31)))
cd2b37d9 4915 (match_operand:SI 2 "gpc_reg_operand" "r"))
1fd4e8c1
RK
4916 (const_int 0)))
4917 (clobber (match_scratch:SI 3 "=&r"))]
4918 ""
ca7f5001 4919 "{srai|srawi} %3,%1,31\;andc. %3,%2,%3"
b19003d8
RK
4920 [(set_attr "type" "compare")
4921 (set_attr "length" "8")])
1fd4e8c1
RK
4922
4923(define_insn ""
4924 [(set (match_operand:CC 4 "cc_reg_operand" "=x")
4925 (compare:CC
4926 (and:SI (neg:SI
4927 (lshiftrt:SI
cd2b37d9 4928 (not:SI (match_operand:SI 1 "gpc_reg_operand" "r"))
1fd4e8c1 4929 (const_int 31)))
cd2b37d9 4930 (match_operand:SI 2 "gpc_reg_operand" "r"))
1fd4e8c1 4931 (const_int 0)))
cd2b37d9 4932 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
4933 (and:SI (neg:SI (lshiftrt:SI (not:SI (match_dup 1))
4934 (const_int 31)))
4935 (match_dup 2)))
4936 (clobber (match_scratch:SI 3 "=&r"))]
4937 ""
ca7f5001 4938 "{srai|srawi} %3,%1,31\;andc. %0,%2,%3"
b19003d8
RK
4939 [(set_attr "type" "compare")
4940 (set_attr "length" "8")])
1fd4e8c1
RK
4941
4942(define_insn ""
cd2b37d9
RK
4943 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
4944 (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1
RK
4945 (match_operand:SI 2 "reg_or_neg_short_operand" "r,P")))]
4946 ""
4947 "@
ca7f5001
RK
4948 {sf|subfc} %0,%2,%1\;{cal %0,0(0)|li %0,0}\;{ae|adde} %0,%0,%0
4949 {ai|addic} %0,%1,%n2\;{cal %0,0(0)|li %0,0}\;{ae|adde} %0,%0,%0"
b19003d8 4950 [(set_attr "length" "12")])
1fd4e8c1
RK
4951
4952(define_insn ""
4953 [(set (match_operand:CC 3 "cc_reg_operand" "=x,x")
4954 (compare:CC
cd2b37d9 4955 (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1
RK
4956 (match_operand:SI 2 "reg_or_neg_short_operand" "r,P"))
4957 (const_int 0)))
cd2b37d9 4958 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
1fd4e8c1
RK
4959 (geu:SI (match_dup 1) (match_dup 2)))]
4960 ""
4961 "@
ca7f5001
RK
4962 {sf|subfc} %0,%2,%1\;{cal %0,0(0)|li %0,0}\;{ae.|adde.} %0,%0,%0
4963 {ai|addic} %0,%1,%n2\;{cal %0,0(0)|li %0,0}\;{ae.|adde.} %0,%0,%0"
b19003d8
RK
4964 [(set_attr "type" "compare")
4965 (set_attr "length" "12")])
1fd4e8c1
RK
4966
4967(define_insn ""
cd2b37d9
RK
4968 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
4969 (plus:SI (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1 4970 (match_operand:SI 2 "reg_or_neg_short_operand" "r,P"))
cd2b37d9 4971 (match_operand:SI 3 "gpc_reg_operand" "r,r")))
1fd4e8c1
RK
4972 (clobber (match_scratch:SI 4 "=&r,&r"))]
4973 ""
4974 "@
ca7f5001
RK
4975 {sf|subfc} %4,%2,%1\;{aze|addze} %0,%3
4976 {ai|addic} %4,%1,%n2\;{aze|addze} %0,%3"
b19003d8 4977 [(set_attr "length" "8")])
1fd4e8c1
RK
4978
4979(define_insn ""
4980 [(set (match_operand:CC 0 "cc_reg_operand" "=x,x")
4981 (compare:CC
cd2b37d9 4982 (plus:SI (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1 4983 (match_operand:SI 2 "reg_or_neg_short_operand" "r,P"))
cd2b37d9 4984 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
1fd4e8c1
RK
4985 (const_int 0)))
4986 (clobber (match_scratch:SI 4 "=&r,&r"))]
4987 ""
4988 "@
ca7f5001
RK
4989 {sf|subfc} %4,%2,%1\;{aze.|addze.} %4,%3
4990 {ai|addic} %4,%1,%n2\;{aze.|addze.} %4,%3"
b19003d8
RK
4991 [(set_attr "type" "compare")
4992 (set_attr "length" "8")])
1fd4e8c1
RK
4993
4994(define_insn ""
4995 [(set (match_operand:CC 5 "cc_reg_operand" "=x,x")
4996 (compare:CC
cd2b37d9 4997 (plus:SI (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1 4998 (match_operand:SI 2 "reg_or_neg_short_operand" "r,P"))
cd2b37d9 4999 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
1fd4e8c1 5000 (const_int 0)))
cd2b37d9 5001 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
1fd4e8c1
RK
5002 (plus:SI (geu:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
5003 (clobber (match_scratch:SI 4 "=&r,&r"))]
5004 ""
5005 "@
ca7f5001
RK
5006 {sf|subfc} %4,%2,%1\;{aze.|addze.} %0,%3
5007 {ai|addic} %4,%1,%n2\;{aze.|addze.} %4,%3"
b19003d8
RK
5008 [(set_attr "type" "compare")
5009 (set_attr "length" "8")])
1fd4e8c1
RK
5010
5011(define_insn ""
cd2b37d9
RK
5012 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
5013 (neg:SI (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1
RK
5014 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))]
5015 ""
5016 "@
ca7f5001
RK
5017 {sf|subfc} %0,%2,%1\;{sfe|subfe} %0,%0,%0\;nand %0,%0,%0
5018 {sfi|subfic} %0,%1,-1\;a%I2 %0,%0,%2\;{sfe|subfe} %0,%0,%0"
b19003d8 5019 [(set_attr "length" "12")])
1fd4e8c1
RK
5020
5021(define_insn ""
cd2b37d9 5022 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
1fd4e8c1 5023 (and:SI (neg:SI
cd2b37d9 5024 (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1 5025 (match_operand:SI 2 "reg_or_neg_short_operand" "r,P")))
cd2b37d9 5026 (match_operand:SI 3 "gpc_reg_operand" "r,r")))
1fd4e8c1
RK
5027 (clobber (match_scratch:SI 4 "=&r,&r"))]
5028 ""
5029 "@
ca7f5001
RK
5030 {sf|subfc} %4,%2,%1\;{sfe|subfe} %4,%4,%4\;andc %0,%3,%4
5031 {ai|addic} %4,%1,%n2\;{sfe|subfe} %4,%4,%4\;andc %0,%3,%4"
b19003d8 5032 [(set_attr "length" "12")])
1fd4e8c1
RK
5033
5034(define_insn ""
5035 [(set (match_operand:CC 0 "cc_reg_operand" "=x,x")
5036 (compare:CC
5037 (and:SI (neg:SI
cd2b37d9 5038 (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1 5039 (match_operand:SI 2 "reg_or_neg_short_operand" "r,P")))
cd2b37d9 5040 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
1fd4e8c1
RK
5041 (const_int 0)))
5042 (clobber (match_scratch:SI 4 "=&r,&r"))]
5043 ""
5044 "@
ca7f5001
RK
5045 {sf|subfc} %4,%2,%1\;{sfe|subfe} %4,%4,%4\;andc. %4,%3,%4
5046 {ai|addic} %4,%1,%n2\;{sfe|subfe} %4,%4,%4\;andc. %4,%3,%4"
b19003d8
RK
5047 [(set_attr "type" "compare")
5048 (set_attr "length" "12")])
1fd4e8c1
RK
5049
5050(define_insn ""
5051 [(set (match_operand:CC 5 "cc_reg_operand" "=x,x")
5052 (compare:CC
5053 (and:SI (neg:SI
cd2b37d9 5054 (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1 5055 (match_operand:SI 2 "reg_or_neg_short_operand" "r,P")))
cd2b37d9 5056 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
1fd4e8c1 5057 (const_int 0)))
cd2b37d9 5058 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
1fd4e8c1
RK
5059 (and:SI (neg:SI (geu:SI (match_dup 1) (match_dup 2))) (match_dup 3)))
5060 (clobber (match_scratch:SI 4 "=&r,&r"))]
5061 ""
5062 "@
ca7f5001
RK
5063 {sf|subfc} %4,%2,%1\;{sfe|subfe} %4,%4,%4\;andc. %0,%3,%4
5064 {ai|addic} %4,%1,%n2\;{sfe|subfe} %4,%4,%4\;andc. %0,%3,%4"
b19003d8
RK
5065 [(set_attr "type" "compare")
5066 (set_attr "length" "12")])
1fd4e8c1
RK
5067
5068(define_insn ""
cd2b37d9
RK
5069 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
5070 (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
5071 (const_int 0)))]
5072 ""
ca7f5001 5073 "{sfi|subfic} %0,%1,0\;{ame|addme} %0,%0\;{sri|srwi} %0,%0,31"
b19003d8 5074 [(set_attr "length" "12")])
1fd4e8c1
RK
5075
5076(define_insn ""
5077 [(set (match_operand:CC 2 "cc_reg_operand" "=x")
5078 (compare:CC
cd2b37d9 5079 (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
5080 (const_int 0))
5081 (const_int 0)))
cd2b37d9 5082 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
5083 (gt:SI (match_dup 1) (const_int 0)))]
5084 ""
ca7f5001 5085 "{sfi|subfic} %0,%1,0\;{ame|addme} %0,%0\;{sri.|srwi.} %0,%0,31"
b19003d8
RK
5086 [(set_attr "type" "delayed_compare")
5087 (set_attr "length" "12")])
1fd4e8c1
RK
5088
5089(define_insn ""
cd2b37d9
RK
5090 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
5091 (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 5092 (match_operand:SI 2 "reg_or_short_operand" "r")))]
ca7f5001
RK
5093 "TARGET_POWER"
5094 "doz %0,%2,%1\;nabs %0,%0\;{sri|srwi} %0,%0,31"
b19003d8 5095 [(set_attr "length" "12")])
1fd4e8c1
RK
5096
5097(define_insn ""
5098 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
5099 (compare:CC
cd2b37d9 5100 (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
5101 (match_operand:SI 2 "reg_or_short_operand" "r"))
5102 (const_int 0)))
cd2b37d9 5103 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1 5104 (gt:SI (match_dup 1) (match_dup 2)))]
ca7f5001
RK
5105 "TARGET_POWER"
5106 "doz %0,%2,%1\;nabs %0,%0\;{sri.|srwi.} %0,%0,31"
b19003d8
RK
5107 [(set_attr "type" "delayed_compare")
5108 (set_attr "length" "12")])
1fd4e8c1
RK
5109
5110(define_insn ""
cd2b37d9
RK
5111 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
5112 (plus:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 5113 (const_int 0))
cd2b37d9 5114 (match_operand:SI 2 "gpc_reg_operand" "r")))
1fd4e8c1
RK
5115 (clobber (match_scratch:SI 3 "=&r"))]
5116 ""
ca7f5001 5117 "{a|addc} %3,%1,%1\;{sfe|subfe} %3,%1,%3\;{aze|addze} %0,%2"
b19003d8 5118 [(set_attr "length" "12")])
1fd4e8c1
RK
5119
5120(define_insn ""
5121 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
5122 (compare:CC
cd2b37d9 5123 (plus:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 5124 (const_int 0))
cd2b37d9 5125 (match_operand:SI 2 "gpc_reg_operand" "r"))
1fd4e8c1
RK
5126 (const_int 0)))
5127 (clobber (match_scratch:SI 3 "=&r"))]
5128 ""
ca7f5001 5129 "{a|addc} %3,%1,%1\;{sfe|subfe} %3,%1,%3\;{aze.|addze.} %0,%2"
b19003d8
RK
5130 [(set_attr "type" "compare")
5131 (set_attr "length" "12")])
1fd4e8c1
RK
5132
5133(define_insn ""
5134 [(set (match_operand:CC 4 "cc_reg_operand" "=x")
5135 (compare:CC
cd2b37d9 5136 (plus:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 5137 (const_int 0))
cd2b37d9 5138 (match_operand:SI 2 "gpc_reg_operand" "r"))
1fd4e8c1 5139 (const_int 0)))
cd2b37d9 5140 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
5141 (plus:SI (gt:SI (match_dup 1) (const_int 0)) (match_dup 2)))
5142 (clobber (match_scratch:SI 3 "=&r"))]
5143 ""
ca7f5001 5144 "{a|addc} %3,%1,%1\;{sfe|subfe} %3,%1,%3\;{aze.|addze.} %3,%2"
b19003d8
RK
5145 [(set_attr "type" "compare")
5146 (set_attr "length" "12")])
1fd4e8c1
RK
5147
5148(define_insn ""
cd2b37d9
RK
5149 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
5150 (plus:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 5151 (match_operand:SI 2 "reg_or_short_operand" "r"))
cd2b37d9 5152 (match_operand:SI 3 "gpc_reg_operand" "r")))
1fd4e8c1 5153 (clobber (match_scratch:SI 4 "=&r"))]
ca7f5001
RK
5154 "TARGET_POWER"
5155 "doz %4,%2,%1\;{ai|addic} %4,%4,-1\;{aze|addze} %0,%3"
b19003d8 5156 [(set_attr "length" "12")])
1fd4e8c1
RK
5157
5158(define_insn ""
5159 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
5160 (compare:CC
cd2b37d9 5161 (plus:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 5162 (match_operand:SI 2 "reg_or_short_operand" "r"))
cd2b37d9 5163 (match_operand:SI 3 "gpc_reg_operand" "r"))
1fd4e8c1
RK
5164 (const_int 0)))
5165 (clobber (match_scratch:SI 4 "=&r"))]
ca7f5001
RK
5166 "TARGET_POWER"
5167 "doz %4,%2,%1\;{ai|addic} %4,%4,-1\;{aze.|addze.} %4,%3"
b19003d8
RK
5168 [(set_attr "type" "compare")
5169 (set_attr "length" "12")])
1fd4e8c1
RK
5170
5171(define_insn ""
5172 [(set (match_operand:CC 5 "cc_reg_operand" "=x")
5173 (compare:CC
cd2b37d9 5174 (plus:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 5175 (match_operand:SI 2 "reg_or_short_operand" "r"))
cd2b37d9 5176 (match_operand:SI 3 "gpc_reg_operand" "r"))
1fd4e8c1 5177 (const_int 0)))
cd2b37d9 5178 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
5179 (plus:SI (gt:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
5180 (clobber (match_scratch:SI 4 "=&r"))]
ca7f5001
RK
5181 "TARGET_POWER"
5182 "doz %4,%2,%1\;{ai|addic} %4,%4,-1\;{aze.|addze.} %0,%3"
b19003d8
RK
5183 [(set_attr "type" "compare")
5184 (set_attr "length" "12")])
1fd4e8c1
RK
5185
5186(define_insn ""
cd2b37d9
RK
5187 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
5188 (neg:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
5189 (const_int 0))))]
5190 ""
ca7f5001 5191 "{sfi|subfic} %0,%1,0\;{ame|addme} %0,%0\;{srai|srawi} %0,%0,31"
b19003d8 5192 [(set_attr "length" "12")])
1fd4e8c1
RK
5193
5194(define_insn ""
cd2b37d9
RK
5195 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
5196 (neg:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 5197 (match_operand:SI 2 "reg_or_short_operand" "r"))))]
ca7f5001
RK
5198 "TARGET_POWER"
5199 "doz %0,%2,%1\;nabs %0,%0\;{srai|srawi} %0,%0,31"
b19003d8 5200 [(set_attr "length" "12")])
1fd4e8c1
RK
5201
5202(define_insn ""
cd2b37d9
RK
5203 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
5204 (gtu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
5205 (match_operand:SI 2 "reg_or_short_operand" "rI")))]
5206 ""
ca7f5001 5207 "{sf%I2|subf%I2c} %0,%1,%2\;{sfe|subfe} %0,%0,%0\;neg %0,%0"
b19003d8 5208 [(set_attr "length" "12")])
1fd4e8c1
RK
5209
5210(define_insn ""
5211 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
5212 (compare:CC
cd2b37d9 5213 (gtu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
5214 (match_operand:SI 2 "reg_or_short_operand" "rI"))
5215 (const_int 0)))
cd2b37d9 5216 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
5217 (gtu:SI (match_dup 1) (match_dup 2)))]
5218 ""
ca7f5001 5219 "{sf%I2|subf%I2c} %0,%1,%2\;{sfe|subfe} %0,%0,%0\;neg. %0,%0"
b19003d8
RK
5220 [(set_attr "type" "compare")
5221 (set_attr "length" "12")])
1fd4e8c1
RK
5222
5223(define_insn ""
00751805
RK
5224 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r")
5225 (plus:SI (gtu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r")
5226 (match_operand:SI 2 "reg_or_short_operand" "I,r,rI"))
5227 (match_operand:SI 3 "reg_or_short_operand" "r,r,I")))
5228 (clobber (match_scratch:SI 4 "=&r,&r,&r"))]
1fd4e8c1 5229 ""
00751805 5230 "@
ca7f5001
RK
5231 {ai|addic} %4,%1,%k2\;{aze|addze} %0,%3
5232 {sf%I2|subf%I2c} %4,%1,%2\;{sfe|subfe} %4,%4,%4\;{sf%I3|subf%I3c} %0,%4,%3
5233 {sf%I2|subf%I2c} %4,%1,%2\;{sfe|subfe} %4,%4,%4\;{sf%I3|subf%I3c} %0,%4,%3"
b19003d8 5234 [(set_attr "length" "8,12,12")])
1fd4e8c1
RK
5235
5236(define_insn ""
3d91674b 5237 [(set (match_operand:CC 0 "cc_reg_operand" "=x,x")
1fd4e8c1 5238 (compare:CC
3d91674b
RK
5239 (plus:SI (gtu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
5240 (match_operand:SI 2 "reg_or_short_operand" "I,r"))
5241 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
1fd4e8c1 5242 (const_int 0)))
3d91674b 5243 (clobber (match_scratch:SI 4 "=&r,&r"))]
1fd4e8c1 5244 ""
00751805 5245 "@
ca7f5001
RK
5246 {ai|addic} %4,%1,%k2\;{aze.|addze.} %0,%3
5247 {sf%I2|subf%I2c} %4,%1,%2\;{sfe|subfe} %4,%4,%4\;{sf.|subfc.} %0,%4,%3"
b19003d8 5248 [(set_attr "type" "compare")
3d91674b 5249 (set_attr "length" "8,12")])
1fd4e8c1
RK
5250
5251(define_insn ""
3d91674b 5252 [(set (match_operand:CC 5 "cc_reg_operand" "=x,x")
1fd4e8c1 5253 (compare:CC
3d91674b
RK
5254 (plus:SI (gtu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
5255 (match_operand:SI 2 "reg_or_short_operand" "I,r"))
5256 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
1fd4e8c1 5257 (const_int 0)))
3d91674b 5258 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
1fd4e8c1 5259 (plus:SI (gtu:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
3d91674b 5260 (clobber (match_scratch:SI 4 "=&r,&r"))]
1fd4e8c1 5261 ""
00751805 5262 "@
ca7f5001
RK
5263 {ai|addic} %4,%1,%k2\;{aze.|addze.} %0,%3
5264 {sf%I2|subf%I2c} %4,%1,%2\;{sfe|subfe} %4,%4,%4\;{sf.|subfc.} %0,%4,%3"
b19003d8 5265 [(set_attr "type" "compare")
3d91674b 5266 (set_attr "length" "8,12")])
1fd4e8c1
RK
5267
5268(define_insn ""
cd2b37d9
RK
5269 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
5270 (neg:SI (gtu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
5271 (match_operand:SI 2 "reg_or_short_operand" "rI"))))]
5272 ""
ca7f5001 5273 "{sf%I2|subf%I2c} %0,%1,%2\;{sfe|subfe} %0,%0,%0"
b19003d8 5274 [(set_attr "length" "8")])
1fd4e8c1
RK
5275\f
5276;; Define both directions of branch and return. If we need a reload
5277;; register, we'd rather use CR0 since it is much easier to copy a
5278;; register CC value to there.
5279
5280(define_insn ""
5281 [(set (pc)
5282 (if_then_else (match_operator 1 "branch_comparison_operator"
5283 [(match_operand 2
5284 "cc_reg_operand" "x,?y")
5285 (const_int 0)])
5286 (label_ref (match_operand 0 "" ""))
5287 (pc)))]
5288 ""
b19003d8
RK
5289 "*
5290{
5291 if (get_attr_length (insn) == 8)
5292 return \"%C1bc %t1,%j1,%l0\";
5293 else
5294 return \"%C1bc %T1,%j1,$+8\;b %l0\";
5295}"
5296 [(set_attr "type" "branch")])
5297
1fd4e8c1
RK
5298
5299(define_insn ""
5300 [(set (pc)
5301 (if_then_else (match_operator 0 "branch_comparison_operator"
5302 [(match_operand 1
5303 "cc_reg_operand" "x,?y")
5304 (const_int 0)])
5305 (return)
5306 (pc)))]
5307 "direct_return ()"
ca7f5001 5308 "{%C0bcr|%C0bclr} %t0,%j0"
b19003d8 5309 [(set_attr "length" "8")])
1fd4e8c1
RK
5310
5311(define_insn ""
5312 [(set (pc)
5313 (if_then_else (match_operator 1 "branch_comparison_operator"
5314 [(match_operand 2
5315 "cc_reg_operand" "x,?y")
5316 (const_int 0)])
5317 (pc)
5318 (label_ref (match_operand 0 "" ""))))]
5319 ""
b19003d8
RK
5320 "*
5321{
5322 if (get_attr_length (insn) == 8)
5323 return \"%C1bc %T1,%j1,%l0\";
5324 else
5325 return \"%C1bc %t1,%j1,$+8\;b %l0\";
5326}"
5327 [(set_attr "type" "branch")])
1fd4e8c1
RK
5328
5329(define_insn ""
5330 [(set (pc)
5331 (if_then_else (match_operator 0 "branch_comparison_operator"
5332 [(match_operand 1
5333 "cc_reg_operand" "x,?y")
5334 (const_int 0)])
5335 (pc)
5336 (return)))]
5337 "direct_return ()"
ca7f5001 5338 "{%C0bcr|%C0bclr} %T0,%j0"
b19003d8 5339 [(set_attr "length" "8")])
1fd4e8c1
RK
5340
5341;; Unconditional branch and return.
5342
5343(define_insn "jump"
5344 [(set (pc)
5345 (label_ref (match_operand 0 "" "")))]
5346 ""
5347 "b %l0")
5348
5349(define_insn "return"
5350 [(return)]
5351 "direct_return ()"
ca7f5001 5352 "{br|blr}")
1fd4e8c1
RK
5353
5354(define_insn "indirect_jump"
5355 [(set (pc) (match_operand:SI 0 "register_operand" "c,l"))]
5356 ""
5357 "@
5358 bctr
ca7f5001 5359 {br|blr}")
1fd4e8c1
RK
5360
5361;; Table jump for switch statements:
5362(define_expand "tablejump"
5363 [(set (match_dup 3)
5364 (plus:SI (match_operand:SI 0 "" "")
5365 (match_dup 2)))
5366 (parallel [(set (pc) (match_dup 3))
5367 (use (label_ref (match_operand 1 "" "")))])]
5368 ""
5369 "
5370{ operands[0] = force_reg (SImode, operands[0]);
5371 operands[2] = force_reg (SImode, gen_rtx (LABEL_REF, VOIDmode, operands[1]));
5372 operands[3] = gen_reg_rtx (SImode);
5373}")
5374
5375(define_insn ""
5376 [(set (pc)
740ab4a2 5377 (match_operand:SI 0 "register_operand" "c,l"))
1fd4e8c1
RK
5378 (use (label_ref (match_operand 1 "" "")))]
5379 ""
5380 "@
5381 bctr
ca7f5001 5382 {br|blr}")
1fd4e8c1
RK
5383
5384(define_insn "nop"
5385 [(const_int 0)]
5386 ""
ca7f5001 5387 "{cror 0,0,0|nop}")
1fd4e8c1 5388\f
c225ba7b
RK
5389;; Define the subtract-one-and-jump insns, starting with the template
5390;; so loop.c knows what to generate.
5391
5392(define_expand "decrement_and_branchsi"
5393 [(parallel [(set (pc) (if_then_else (ne (match_operand:SI 0 "register_operand" "c")
5394 (const_int 1))
5395 (label_ref (match_operand 1 "" ""))
5396 (pc)))
5397 (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))])]
5398 ""
5399 "")
5400
1fd4e8c1
RK
5401;; We need to be able to do this for any operand, including MEM, or we
5402;; will cause reload to blow up since we don't allow output reloads on
5403;; JUMP_INSNs.
5404(define_insn ""
5405 [(set (pc)
5406 (if_then_else (ne (match_operand:SI 1 "register_operand" "0,*r,*r")
5407 (const_int 1))
5408 (label_ref (match_operand 2 "" ""))
5409 (pc)))
5410 (set (match_operand:SI 0 "register_operand" "=c,*r,m*q*c*l")
5411 (plus:SI (match_dup 1) (const_int -1)))
5412 (clobber (match_scratch:CC 3 "=X,&x,&x"))
5413 (clobber (match_scratch:SI 4 "=X,X,r"))]
5414 ""
b19003d8
RK
5415 "*
5416{
af87a13e 5417 if (which_alternative != 0)
b19003d8
RK
5418 return \"#\";
5419 else if (get_attr_length (insn) == 8)
ca7f5001 5420 return \"{bdn|bdnz} %l2\";
b19003d8
RK
5421 else
5422 return \"bdz $+8\;b %l2\";
5423}"
baf97f86
RK
5424 [(set_attr "type" "branch")
5425 (set_attr "length" "*,12,16")])
1fd4e8c1 5426
c225ba7b 5427;; Similar, but we can use GE since we have a REG_NONNEG.
1fd4e8c1
RK
5428(define_insn ""
5429 [(set (pc)
5430 (if_then_else (ge (match_operand:SI 1 "register_operand" "0,*r,*r")
5431 (const_int 0))
5432 (label_ref (match_operand 2 "" ""))
5433 (pc)))
5434 (set (match_operand:SI 0 "register_operand" "=c,*r,m*q*c*l")
5435 (plus:SI (match_dup 1) (const_int -1)))
5436 (clobber (match_scratch:CC 3 "=X,&x,&X"))
5437 (clobber (match_scratch:SI 4 "=X,X,r"))]
5438 "find_reg_note (insn, REG_NONNEG, 0)"
b19003d8
RK
5439 "*
5440{
af87a13e 5441 if (which_alternative != 0)
b19003d8
RK
5442 return \"#\";
5443 else if (get_attr_length (insn) == 8)
ca7f5001 5444 return \"{bdn|bdnz} %l2\";
b19003d8
RK
5445 else
5446 return \"bdz $+8\;b %l2\";
5447}"
baf97f86
RK
5448 [(set_attr "type" "branch")
5449 (set_attr "length" "*,12,16")])
1fd4e8c1
RK
5450
5451(define_insn ""
5452 [(set (pc)
5453 (if_then_else (eq (match_operand:SI 1 "register_operand" "0,*r,*r")
5454 (const_int 1))
5455 (label_ref (match_operand 2 "" ""))
5456 (pc)))
5457 (set (match_operand:SI 0 "register_operand" "=c,*r,m*q*c*l")
5458 (plus:SI (match_dup 1) (const_int -1)))
5459 (clobber (match_scratch:CC 3 "=X,&x,&x"))
5460 (clobber (match_scratch:SI 4 "=X,X,r"))]
5461 ""
b19003d8
RK
5462 "*
5463{
af87a13e 5464 if (which_alternative != 0)
b19003d8
RK
5465 return \"#\";
5466 else if (get_attr_length (insn) == 8)
5467 return \"bdz %l2\";
5468 else
ca7f5001 5469 return \"{bdn|bdnz} $+8\;b %l2\";
b19003d8 5470}"
baf97f86
RK
5471 [(set_attr "type" "branch")
5472 (set_attr "length" "*,12,16")])
1fd4e8c1
RK
5473
5474(define_split
5475 [(set (pc)
5476 (if_then_else (match_operator 2 "comparison_operator"
cd2b37d9 5477 [(match_operand:SI 1 "gpc_reg_operand" "")
1fd4e8c1
RK
5478 (const_int 1)])
5479 (match_operand 5 "" "")
5480 (match_operand 6 "" "")))
cd2b37d9 5481 (set (match_operand:SI 0 "gpc_reg_operand" "")
1fd4e8c1
RK
5482 (plus:SI (match_dup 1) (const_int -1)))
5483 (clobber (match_scratch:CC 3 ""))
5484 (clobber (match_scratch:SI 4 ""))]
5485 "reload_completed"
5486 [(parallel [(set (match_dup 3)
5487 (compare:CC (plus:SI (match_dup 1) (const_int -1))
5488 (const_int 0)))
5489 (set (match_dup 0) (plus:SI (match_dup 1) (const_int -1)))])
5490 (set (pc) (if_then_else (match_dup 7) (match_dup 5) (match_dup 6)))]
5491 "
5492{ operands[7] = gen_rtx (GET_CODE (operands[2]), VOIDmode, operands[3],
5493 const0_rtx); }")
5494
5495(define_split
5496 [(set (pc)
5497 (if_then_else (match_operator 2 "comparison_operator"
cd2b37d9 5498 [(match_operand:SI 1 "gpc_reg_operand" "")
1fd4e8c1
RK
5499 (const_int 1)])
5500 (match_operand 5 "" "")
5501 (match_operand 6 "" "")))
5502 (set (match_operand:SI 0 "general_operand" "")
5503 (plus:SI (match_dup 1) (const_int -1)))
5504 (clobber (match_scratch:CC 3 ""))
5505 (clobber (match_scratch:SI 4 ""))]
cd2b37d9 5506 "reload_completed && ! gpc_reg_operand (operands[0], SImode)"
1fd4e8c1
RK
5507 [(parallel [(set (match_dup 3)
5508 (compare:CC (plus:SI (match_dup 1) (const_int -1))
5509 (const_int 0)))
5510 (set (match_dup 4) (plus:SI (match_dup 1) (const_int -1)))])
5511 (set (match_dup 0) (match_dup 4))
5512 (set (pc) (if_then_else (match_dup 7) (match_dup 5) (match_dup 6)))]
5513 "
5514{ operands[7] = gen_rtx (GET_CODE (operands[2]), VOIDmode, operands[3],
5515 const0_rtx); }")
This page took 0.831171 seconds and 5 git commands to generate.