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