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