]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/config/rs6000/rs6000.md
Rewrite to use EXTRA_SPECS.
[thirdparty/gcc.git] / gcc / config / rs6000 / rs6000.md
CommitLineData
996a5f59 1;; Machine description for IBM RISC System 6000 (POWER) for GNU C compiler
cf27b467 2;; Copyright (C) 1990, 91, 92, 93, 94, 95, 1996 Free Software Foundation, Inc.
996a5f59 3;; Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
1fd4e8c1
RK
4
5;; This file is part of GNU CC.
6
7;; GNU CC is free software; you can redistribute it and/or modify
8;; it under the terms of the GNU General Public License as published by
9;; the Free Software Foundation; either version 2, or (at your option)
10;; any later version.
11
12;; GNU CC is distributed in the hope that it will be useful,
13;; but WITHOUT ANY WARRANTY; without even the implied warranty of
14;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15;; GNU General Public License for more details.
16
17;; You should have received a copy of the GNU General Public License
18;; along with GNU CC; see the file COPYING. If not, write to
3f63df56
RK
19;; the Free Software Foundation, 59 Temple Place - Suite 330,
20;; Boston, MA 02111-1307, USA.
1fd4e8c1
RK
21
22;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
23\f
24;; Define an insn type attribute. This is used in function unit delay
25;; computations.
324e52cc 26(define_attr "type" "integer,load,fpload,imul,idiv,branch,compare,delayed_compare,fpcompare,mtjmpr,fp,dmul,sdiv,ddiv,ssqrt,dsqrt,jmpreg"
1fd4e8c1
RK
27 (const_string "integer"))
28
b19003d8
RK
29;; Length (in bytes).
30(define_attr "length" ""
31 (if_then_else (eq_attr "type" "branch")
32 (if_then_else (and (ge (minus (pc) (match_dup 0))
33 (const_int -32768))
34 (lt (minus (pc) (match_dup 0))
35 (const_int 32767)))
36 (const_int 8)
37 (const_int 12))
38 (const_int 4)))
39
cfb557c4
RK
40;; Processor type -- this attribute must exactly match the processor_type
41;; enumeration in rs6000.h.
42
cf27b467 43(define_attr "cpu" "rios1,rios2,mpccore,ppc403,ppc601,ppc602,ppc603,ppc604,ppc620"
cfb557c4
RK
44 (const (symbol_ref "rs6000_cpu_attr")))
45
46; (define_function_unit NAME MULTIPLICITY SIMULTANEITY
47; TEST READY-DELAY ISSUE-DELAY [CONFLICT-LIST])
48
51b8fc2c
RK
49; Load/Store Unit -- POWER/2 and pure PowerPC only
50; (POWER and 601 use Integer Unit)
cfb557c4
RK
51(define_function_unit "lsu" 1 0
52 (and (eq_attr "type" "load")
cf27b467 53 (eq_attr "cpu" "mpccore,ppc602,ppc603,ppc604,ppc620"))
b6c9286a 54 2 1)
cfb557c4
RK
55
56(define_function_unit "lsu" 1 0
57 (and (eq_attr "type" "fpload")
b6c9286a
MM
58 (eq_attr "cpu" "ppc604,ppc620"))
59 3 1)
60
61(define_function_unit "lsu" 1 0
62 (and (eq_attr "type" "fpload")
cf27b467 63 (eq_attr "cpu" "mpccore,ppc602,ppc603"))
b6c9286a 64 2 1)
cfb557c4
RK
65
66(define_function_unit "iu" 1 0
67 (and (eq_attr "type" "load")
da0ae67f 68 (eq_attr "cpu" "rios1,ppc601,ppc403"))
b6c9286a 69 2 1)
cfb557c4
RK
70
71(define_function_unit "iu" 1 0
72 (and (eq_attr "type" "fpload")
3624a679 73 (eq_attr "cpu" "rios1,ppc601"))
b6c9286a 74 2 0)
cfb557c4 75
51b8fc2c
RK
76; Integer Unit (RIOS1, PPC601, PPC603)
77; Trivial operations take one cycle which need not be listed here.
49a0b204
MM
78(define_function_unit "iu" 1 0
79 (and (eq_attr "type" "imul")
b6c9286a
MM
80 (eq_attr "cpu" "rios1"))
81 3 3)
49a0b204 82
da0ae67f
MM
83(define_function_unit "iu" 1 0
84 (and (eq_attr "type" "imul")
85 (eq_attr "cpu" "ppc403"))
86 4 4)
87
cfb557c4
RK
88(define_function_unit "iu" 1 0
89 (and (eq_attr "type" "imul")
b6c9286a 90 (eq_attr "cpu" "ppc601,ppc602,ppc603"))
51b8fc2c 91 5 5)
cfb557c4
RK
92
93(define_function_unit "iu" 1 0
94 (and (eq_attr "type" "idiv")
ca7f5001 95 (eq_attr "cpu" "rios1"))
51b8fc2c 96 19 19)
cfb557c4
RK
97
98(define_function_unit "iu" 1 0
99 (and (eq_attr "type" "idiv")
51b8fc2c
RK
100 (eq_attr "cpu" "ppc601"))
101 36 36)
102
da0ae67f
MM
103(define_function_unit "iu" 1 0
104 (and (eq_attr "type" "idiv")
105 (eq_attr "cpu" "ppc403"))
106 33 33)
107
51b8fc2c
RK
108(define_function_unit "iu" 1 0
109 (and (eq_attr "type" "idiv")
b6c9286a 110 (eq_attr "cpu" "ppc602,ppc603"))
51b8fc2c
RK
111 37 36)
112
113; RIOS2 has two integer units: a primary one which can perform all
114; operations and a secondary one which is fed in lock step with the first
b6c9286a
MM
115; and can perform "simple" integer operations.
116; To catch this we define a 'dummy' imuldiv-unit that is also needed
117; for the complex insns.
51b8fc2c
RK
118(define_function_unit "iu2" 2 0
119 (and (eq_attr "type" "integer")
120 (eq_attr "cpu" "rios2"))
b6c9286a
MM
121 1 0)
122
123(define_function_unit "iu2" 2 0
124 (and (eq_attr "type" "imul")
125 (eq_attr "cpu" "rios2"))
126 2 2)
127
128(define_function_unit "iu2" 2 0
129 (and (eq_attr "type" "idiv")
130 (eq_attr "cpu" "rios2"))
131 13 13)
51b8fc2c
RK
132
133(define_function_unit "imuldiv" 1 0
134 (and (eq_attr "type" "imul")
135 (eq_attr "cpu" "rios2"))
b6c9286a
MM
136 2 2)
137
51b8fc2c
RK
138
139(define_function_unit "imuldiv" 1 0
140 (and (eq_attr "type" "idiv")
141 (eq_attr "cpu" "rios2"))
b6c9286a 142 13 13)
51b8fc2c 143
cf27b467
MM
144; MPCCORE has separate IMUL/IDIV unit for multicycle instructions
145; Divide latency varies greatly from 2-11, use 6 as average
146(define_function_unit "imuldiv" 1 0
147 (and (eq_attr "type" "imul")
148 (eq_attr "cpu" "mpccore"))
149 2 1)
150
151(define_function_unit "imuldiv" 1 0
152 (and (eq_attr "type" "idiv")
153 (eq_attr "cpu" "mpccore"))
154 6 6)
155
b6c9286a
MM
156; PPC604 has two units that perform integer operations
157; and one unit for divide/multiply operations (and move
158; from/to spr).
159(define_function_unit "iu2" 2 0
51b8fc2c
RK
160 (and (eq_attr "type" "integer")
161 (eq_attr "cpu" "ppc604,ppc620"))
b6c9286a 162 1 1
51b8fc2c
RK
163 [(eq_attr "type" "imul,idiv")])
164
165(define_function_unit "imuldiv" 1 0
166 (and (eq_attr "type" "imul")
167 (eq_attr "cpu" "ppc604,ppc620"))
168 4 2
169 [(eq_attr "type" "integer")])
170
171(define_function_unit "imuldiv" 1 0
172 (and (eq_attr "type" "idiv")
173 (eq_attr "cpu" "ppc604,ppc620"))
174 20 19
175 [(eq_attr "type" "integer")])
cfb557c4 176
b6c9286a
MM
177; compare is done on integer unit, but feeds insns which
178; execute on the branch unit. Ready-delay of the compare
179; on the branch unit is large (3-5 cycles). On the iu/fpu
180; it is 1. One drawback is that the compare will also be
181; assigned to the bpu, but this inaccuracy is worth for being
182; able to fill the compare-branch delay, with insns on iu/fpu.
183(define_function_unit "iu" 1 0
184 (and (eq_attr "type" "compare")
cf27b467 185 (eq_attr "cpu" "rios1,mpccore,ppc601"))
b6c9286a
MM
186 1 1)
187
188(define_function_unit "iu2" 2 0
189 (and (eq_attr "type" "compare")
190 (eq_attr "cpu" "rios2"))
191 1 1)
192
193(define_function_unit "bpu" 1 0
194 (and (eq_attr "type" "compare")
cf27b467 195 (eq_attr "cpu" "rios1,rios2,ppc403,mpccore,ppc601,ppc603,ppc604,ppc620"))
b6c9286a
MM
196 4 1)
197
198; different machines have different compare timings
199; in ppc604, compare is done on the one of the two
200; main integer units.
201(define_function_unit "iu2" 2 0
202 (and (eq_attr "type" "compare")
203 (eq_attr "cpu" "ppc604,ppc620"))
204 1 1)
cfb557c4
RK
205
206(define_function_unit "bpu" 1 0
207 (eq_attr "type" "delayed_compare")
208 5 0)
209
b6c9286a
MM
210; fp compare uses fp unit
211(define_function_unit "fpu" 1 0
cfb557c4 212 (and (eq_attr "type" "fpcompare")
b6c9286a
MM
213 (eq_attr "cpu" "rios1"))
214 8 1)
cfb557c4 215
b6c9286a
MM
216; rios1 and rios2 have different fpcompare delays
217(define_function_unit "fpu2" 2 0
cfb557c4 218 (and (eq_attr "type" "fpcompare")
b6c9286a
MM
219 (eq_attr "cpu" "rios2"))
220 5 1)
221
222; on ppc601 and ppc603, fpcompare takes also 2 cycles from
223; the integer unit
224; here we do not define delays, just occupy the unit. The dependencies
225; will be signed by the fpcompare definition in the fpu.
226(define_function_unit "iu" 1 0
227 (and (eq_attr "type" "fpcompare")
228 (eq_attr "cpu" "ppc601,ppc602,ppc603"))
229 0 2)
230
231; fp compare uses fp unit
232(define_function_unit "fpu" 1 0
233 (and (eq_attr "type" "fpcompare")
234 (eq_attr "cpu" "ppc601,ppc602,ppc603,ppc604,ppc620"))
235 5 1)
cfb557c4 236
cf27b467
MM
237(define_function_unit "fpu" 1 0
238 (and (eq_attr "type" "fpcompare")
239 (eq_attr "cpu" "mpccore"))
240 1 1)
241
cfb557c4 242(define_function_unit "bpu" 1 0
324e52cc 243 (and (eq_attr "type" "mtjmpr")
2661cdd9 244 (eq_attr "cpu" "rios1,rios2"))
cfb557c4
RK
245 5 0)
246
247(define_function_unit "bpu" 1 0
324e52cc 248 (and (eq_attr "type" "mtjmpr")
cf27b467 249 (eq_attr "cpu" "ppc403,mpccore,ppc601,ppc602,ppc603,ppc604,ppc620"))
cfb557c4
RK
250 4 0)
251
b6c9286a
MM
252; all jumps/branches are executing on the bpu, in 1 cycle, for all machines.
253(define_function_unit "bpu" 1 0
254 (eq_attr "type" "jmpreg")
255 1 0)
256
257(define_function_unit "bpu" 1 0
258 (eq_attr "type" "branch")
259 1 0)
260
cf27b467 261; Floating Point Unit
cfb557c4 262(define_function_unit "fpu" 1 0
51b8fc2c 263 (and (eq_attr "type" "fp,dmul")
2661cdd9 264 (eq_attr "cpu" "rios1"))
cfb557c4
RK
265 2 0)
266
cf27b467
MM
267(define_function_unit "fpu" 1 0
268 (and (eq_attr "type" "fp")
269 (eq_attr "cpu" "mpccore"))
270 4 4)
271
cfb557c4
RK
272(define_function_unit "fpu" 1 0
273 (and (eq_attr "type" "fp")
51b8fc2c 274 (eq_attr "cpu" "ppc601"))
cfb557c4
RK
275 4 0)
276
51b8fc2c
RK
277(define_function_unit "fpu" 1 0
278 (and (eq_attr "type" "fp")
b6c9286a
MM
279 (eq_attr "cpu" "ppc602,ppc603,ppc604,ppc620"))
280 3 1)
51b8fc2c 281
cf27b467
MM
282(define_function_unit "fpu" 1 0
283 (and (eq_attr "type" "dmul")
284 (eq_attr "cpu" "mpccore"))
285 5 5)
286
cfb557c4
RK
287(define_function_unit "fpu" 1 0
288 (and (eq_attr "type" "dmul")
51b8fc2c 289 (eq_attr "cpu" "ppc601"))
b6c9286a 290 5 2)
cfb557c4 291
b6c9286a 292; is this true?
cfb557c4
RK
293(define_function_unit "fpu" 1 0
294 (and (eq_attr "type" "dmul")
b6c9286a 295 (eq_attr "cpu" "ppc602,ppc603"))
51b8fc2c 296 4 2)
cfb557c4
RK
297
298(define_function_unit "fpu" 1 0
51b8fc2c
RK
299 (and (eq_attr "type" "dmul")
300 (eq_attr "cpu" "ppc604,ppc620"))
b6c9286a 301 3 1)
51b8fc2c
RK
302
303(define_function_unit "fpu" 1 0
304 (and (eq_attr "type" "sdiv,ddiv")
2661cdd9 305 (eq_attr "cpu" "rios1"))
51b8fc2c 306 19 19)
cfb557c4
RK
307
308(define_function_unit "fpu" 1 0
309 (and (eq_attr "type" "sdiv")
51b8fc2c
RK
310 (eq_attr "cpu" "ppc601"))
311 17 17)
312
cf27b467
MM
313(define_function_unit "fpu" 1 0
314 (and (eq_attr "type" "sdiv")
315 (eq_attr "cpu" "mpccore"))
316 10 10)
317
51b8fc2c
RK
318(define_function_unit "fpu" 1 0
319 (and (eq_attr "type" "sdiv")
b6c9286a 320 (eq_attr "cpu" "ppc602,ppc603,ppc604,ppc620"))
51b8fc2c 321 18 18)
cfb557c4 322
cf27b467
MM
323(define_function_unit "fpu" 1 0
324 (and (eq_attr "type" "ddiv")
325 (eq_attr "cpu" "mpccore"))
326 17 17)
327
cfb557c4
RK
328(define_function_unit "fpu" 1 0
329 (and (eq_attr "type" "ddiv")
51b8fc2c
RK
330 (eq_attr "cpu" "ppc601,ppc604,ppc620"))
331 31 31)
cfb557c4
RK
332
333(define_function_unit "fpu" 1 0
334 (and (eq_attr "type" "ddiv")
b6c9286a 335 (eq_attr "cpu" "ppc602,ppc603"))
51b8fc2c 336 33 33)
cfb557c4
RK
337
338(define_function_unit "fpu" 1 0
339 (and (eq_attr "type" "ssqrt")
a473029f 340 (eq_attr "cpu" "ppc620"))
51b8fc2c 341 31 31)
cfb557c4
RK
342
343(define_function_unit "fpu" 1 0
344 (and (eq_attr "type" "dsqrt")
a473029f 345 (eq_attr "cpu" "ppc620"))
51b8fc2c 346 31 31)
b73d04f2 347
51b8fc2c 348; RIOS2 has two symmetric FPUs.
cfb557c4
RK
349(define_function_unit "fpu2" 2 0
350 (and (eq_attr "type" "fp")
4652f1d4 351 (eq_attr "cpu" "rios2"))
cfb557c4
RK
352 2 0)
353
354(define_function_unit "fpu2" 2 0
355 (and (eq_attr "type" "dmul")
356 (eq_attr "cpu" "rios2"))
357 2 0)
358
359(define_function_unit "fpu2" 2 0
51b8fc2c 360 (and (eq_attr "type" "sdiv,ddiv")
cfb557c4 361 (eq_attr "cpu" "rios2"))
51b8fc2c 362 17 17)
ca7f5001
RK
363
364(define_function_unit "fpu2" 2 0
51b8fc2c 365 (and (eq_attr "type" "ssqrt,dsqrt")
ca7f5001 366 (eq_attr "cpu" "rios2"))
51b8fc2c 367 26 26)
b6c9286a 368
1fd4e8c1
RK
369\f
370;; Start with fixed-point load and store insns. Here we put only the more
371;; complex forms. Basic data transfer is done later.
372
51b8fc2c
RK
373(define_expand "zero_extendqidi2"
374 [(set (match_operand:DI 0 "gpc_reg_operand" "")
375 (zero_extend:DI (match_operand:QI 1 "gpc_reg_operand" "")))]
376 "TARGET_POWERPC64"
377 "")
378
379(define_insn ""
380 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
381 (zero_extend:DI (match_operand:QI 1 "reg_or_mem_operand" "m,r")))]
382 "TARGET_POWERPC64"
383 "@
384 lbz%U1%X1 %0,%1
4371f8af 385 rldicl %0,%1,0,56"
51b8fc2c
RK
386 [(set_attr "type" "load,*")])
387
388(define_insn ""
389 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
390 (compare:CC (zero_extend:DI (match_operand:QI 1 "gpc_reg_operand" "r"))
391 (const_int 0)))
392 (clobber (match_scratch:DI 2 "=r"))]
58e09803 393 "TARGET_POWERPC64"
4371f8af 394 "rldicl. %2,%1,0,56"
51b8fc2c
RK
395 [(set_attr "type" "compare")])
396
397(define_insn ""
398 [(set (match_operand:CC 2 "cc_reg_operand" "=x")
399 (compare:CC (zero_extend:DI (match_operand:QI 1 "gpc_reg_operand" "r"))
400 (const_int 0)))
401 (set (match_operand:DI 0 "gpc_reg_operand" "=r")
402 (zero_extend:DI (match_dup 1)))]
58e09803 403 "TARGET_POWERPC64"
4371f8af 404 "rldicl. %0,%1,0,56"
51b8fc2c
RK
405 [(set_attr "type" "compare")])
406
2bee0449
RK
407(define_insn "extendqidi2"
408 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
409 (sign_extend:DI (match_operand:QI 1 "gpc_reg_operand" "r")))]
51b8fc2c 410 "TARGET_POWERPC64"
2bee0449 411 "extsb %0,%1")
51b8fc2c
RK
412
413(define_insn ""
414 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
415 (compare:CC (sign_extend:DI (match_operand:QI 1 "gpc_reg_operand" "r"))
416 (const_int 0)))
417 (clobber (match_scratch:DI 2 "=r"))]
418 "TARGET_POWERPC64"
419 "extsb. %2,%1"
420 [(set_attr "type" "compare")])
421
422(define_insn ""
423 [(set (match_operand:CC 2 "cc_reg_operand" "=x")
424 (compare:CC (sign_extend:DI (match_operand:QI 1 "gpc_reg_operand" "r"))
425 (const_int 0)))
426 (set (match_operand:DI 0 "gpc_reg_operand" "=r")
427 (sign_extend:DI (match_dup 1)))]
428 "TARGET_POWERPC64"
429 "extsb. %0,%1"
430 [(set_attr "type" "compare")])
431
432(define_expand "zero_extendhidi2"
433 [(set (match_operand:DI 0 "gpc_reg_operand" "")
434 (zero_extend:DI (match_operand:HI 1 "gpc_reg_operand" "")))]
435 "TARGET_POWERPC64"
436 "")
437
438(define_insn ""
439 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
440 (zero_extend:DI (match_operand:HI 1 "reg_or_mem_operand" "m,r")))]
441 "TARGET_POWERPC64"
442 "@
443 lhz%U1%X1 %0,%1
4371f8af 444 rldicl %0,%1,0,48"
51b8fc2c
RK
445 [(set_attr "type" "load,*")])
446
447(define_insn ""
448 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
449 (compare:CC (zero_extend:DI (match_operand:HI 1 "gpc_reg_operand" "r"))
450 (const_int 0)))
451 (clobber (match_scratch:DI 2 "=r"))]
452 "TARGET_POWERPC64"
4371f8af 453 "rldicl. %2,%1,0,48"
51b8fc2c
RK
454 [(set_attr "type" "compare")])
455
456(define_insn ""
457 [(set (match_operand:CC 2 "cc_reg_operand" "=x")
458 (compare:CC (zero_extend:DI (match_operand:HI 1 "gpc_reg_operand" "r"))
459 (const_int 0)))
460 (set (match_operand:DI 0 "gpc_reg_operand" "=r")
461 (zero_extend:DI (match_dup 1)))]
462 "TARGET_POWERPC64"
4371f8af 463 "rldicl. %0,%1,0,48"
51b8fc2c
RK
464 [(set_attr "type" "compare")])
465
466(define_expand "extendhidi2"
467 [(set (match_operand:DI 0 "gpc_reg_operand" "")
468 (sign_extend:DI (match_operand:HI 1 "gpc_reg_operand" "")))]
469 "TARGET_POWERPC64"
470 "")
471
472(define_insn ""
473 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
474 (sign_extend:DI (match_operand:HI 1 "reg_or_mem_operand" "m,r")))]
475 "TARGET_POWERPC64"
476 "@
477 lha%U1%X1 %0,%1
478 extsh %0,%1"
479 [(set_attr "type" "load,*")])
480
481(define_insn ""
482 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
483 (compare:CC (sign_extend:DI (match_operand:HI 1 "gpc_reg_operand" "r"))
484 (const_int 0)))
485 (clobber (match_scratch:DI 2 "=r"))]
486 "TARGET_POWERPC64"
487 "extsh. %2,%1"
488 [(set_attr "type" "compare")])
489
490(define_insn ""
491 [(set (match_operand:CC 2 "cc_reg_operand" "=x")
492 (compare:CC (sign_extend:DI (match_operand:HI 1 "gpc_reg_operand" "r"))
493 (const_int 0)))
494 (set (match_operand:DI 0 "gpc_reg_operand" "=r")
495 (sign_extend:DI (match_dup 1)))]
496 "TARGET_POWERPC64"
497 "extsh. %0,%1"
498 [(set_attr "type" "compare")])
499
500(define_expand "zero_extendsidi2"
501 [(set (match_operand:DI 0 "gpc_reg_operand" "")
502 (zero_extend:DI (match_operand:SI 1 "gpc_reg_operand" "")))]
503 "TARGET_POWERPC64"
504 "")
505
506(define_insn ""
507 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
508 (zero_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "m,r")))]
509 "TARGET_POWERPC64"
510 "@
511 lwz%U1%X1 %0,%1
512 rldicl %0,%1,0,32"
513 [(set_attr "type" "load,*")])
514
515(define_insn ""
516 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
517 (compare:CC (zero_extend:DI (match_operand:SI 1 "gpc_reg_operand" "r"))
518 (const_int 0)))
519 (clobber (match_scratch:DI 2 "=r"))]
520 "TARGET_POWERPC64"
521 "rldicl. %2,%1,0,32"
522 [(set_attr "type" "compare")])
523
524(define_insn ""
525 [(set (match_operand:CC 2 "cc_reg_operand" "=x")
526 (compare:CC (zero_extend:DI (match_operand:SI 1 "gpc_reg_operand" "r"))
527 (const_int 0)))
528 (set (match_operand:DI 0 "gpc_reg_operand" "=r")
529 (zero_extend:DI (match_dup 1)))]
530 "TARGET_POWERPC64"
531 "rldicl. %0,%1,0,32"
532 [(set_attr "type" "compare")])
533
534(define_expand "extendsidi2"
535 [(set (match_operand:DI 0 "gpc_reg_operand" "")
536 (sign_extend:DI (match_operand:SI 1 "gpc_reg_operand" "")))]
537 "TARGET_POWERPC64"
538 "")
539
540(define_insn ""
541 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
287f13ff 542 (sign_extend:DI (match_operand:SI 1 "lwa_operand" "m,r")))]
51b8fc2c
RK
543 "TARGET_POWERPC64"
544 "@
545 lwa%U1%X1 %0,%1
546 extsw %0,%1"
547 [(set_attr "type" "load,*")])
548
549(define_insn ""
550 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
551 (compare:CC (sign_extend:DI (match_operand:SI 1 "gpc_reg_operand" "r"))
552 (const_int 0)))
553 (clobber (match_scratch:DI 2 "=r"))]
554 "TARGET_POWERPC64"
555 "extsw. %2,%1"
556 [(set_attr "type" "compare")])
557
558(define_insn ""
559 [(set (match_operand:CC 2 "cc_reg_operand" "=x")
560 (compare:CC (sign_extend:DI (match_operand:SI 1 "gpc_reg_operand" "r"))
561 (const_int 0)))
562 (set (match_operand:DI 0 "gpc_reg_operand" "=r")
563 (sign_extend:DI (match_dup 1)))]
564 "TARGET_POWERPC64"
565 "extsw. %0,%1"
566 [(set_attr "type" "compare")])
567
1fd4e8c1 568(define_expand "zero_extendqisi2"
cd2b37d9
RK
569 [(set (match_operand:SI 0 "gpc_reg_operand" "")
570 (zero_extend:SI (match_operand:QI 1 "gpc_reg_operand" "")))]
1fd4e8c1
RK
571 ""
572 "")
573
574(define_insn ""
cd2b37d9 575 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
1fd4e8c1
RK
576 (zero_extend:SI (match_operand:QI 1 "reg_or_mem_operand" "m,r")))]
577 ""
578 "@
579 lbz%U1%X1 %0,%1
005a35b9 580 {rlinm|rlwinm} %0,%1,0,0xff"
1fd4e8c1
RK
581 [(set_attr "type" "load,*")])
582
583(define_insn ""
584 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
cd2b37d9 585 (compare:CC (zero_extend:SI (match_operand:QI 1 "gpc_reg_operand" "r"))
1fd4e8c1
RK
586 (const_int 0)))
587 (clobber (match_scratch:SI 2 "=r"))]
588 ""
ca7f5001 589 "{andil.|andi.} %2,%1,0xff"
1fd4e8c1
RK
590 [(set_attr "type" "compare")])
591
592(define_insn ""
593 [(set (match_operand:CC 2 "cc_reg_operand" "=x")
cd2b37d9 594 (compare:CC (zero_extend:SI (match_operand:QI 1 "gpc_reg_operand" "r"))
1fd4e8c1 595 (const_int 0)))
cd2b37d9 596 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
597 (zero_extend:SI (match_dup 1)))]
598 ""
ca7f5001 599 "{andil.|andi.} %0,%1,0xff"
1fd4e8c1
RK
600 [(set_attr "type" "compare")])
601
51b8fc2c
RK
602(define_expand "extendqisi2"
603 [(use (match_operand:SI 0 "gpc_reg_operand" ""))
604 (use (match_operand:QI 1 "gpc_reg_operand" ""))]
605 ""
606 "
607{
608 if (TARGET_POWERPC)
609 emit_insn (gen_extendqisi2_ppc (operands[0], operands[1]));
610 else if (TARGET_POWER)
611 emit_insn (gen_extendqisi2_power (operands[0], operands[1]));
612 else
613 emit_insn (gen_extendqisi2_no_power (operands[0], operands[1]));
614 DONE;
615}")
616
617(define_insn "extendqisi2_ppc"
2bee0449
RK
618 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
619 (sign_extend:SI (match_operand:QI 1 "gpc_reg_operand" "r")))]
51b8fc2c 620 "TARGET_POWERPC"
2bee0449 621 "extsb %0,%1")
51b8fc2c
RK
622
623(define_insn ""
624 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
625 (compare:CC (sign_extend:SI (match_operand:QI 1 "gpc_reg_operand" "r"))
626 (const_int 0)))
627 (clobber (match_scratch:SI 2 "=r"))]
628 "TARGET_POWERPC"
629 "extsb. %2,%1"
630 [(set_attr "type" "compare")])
631
632(define_insn ""
633 [(set (match_operand:CC 2 "cc_reg_operand" "=x")
634 (compare:CC (sign_extend:SI (match_operand:QI 1 "gpc_reg_operand" "r"))
635 (const_int 0)))
636 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
637 (sign_extend:SI (match_dup 1)))]
638 "TARGET_POWERPC"
639 "extsb. %0,%1"
640 [(set_attr "type" "compare")])
641
642(define_expand "extendqisi2_power"
643 [(parallel [(set (match_dup 2)
644 (ashift:SI (match_operand:QI 1 "gpc_reg_operand" "")
645 (const_int 24)))
646 (clobber (scratch:SI))])
647 (parallel [(set (match_operand:SI 0 "gpc_reg_operand" "")
648 (ashiftrt:SI (match_dup 2)
649 (const_int 24)))
650 (clobber (scratch:SI))])]
651 "TARGET_POWER"
652 "
653{ operands[1] = gen_lowpart (SImode, operands[1]);
654 operands[2] = gen_reg_rtx (SImode); }")
655
656(define_expand "extendqisi2_no_power"
657 [(set (match_dup 2)
658 (ashift:SI (match_operand:QI 1 "gpc_reg_operand" "")
659 (const_int 24)))
660 (set (match_operand:SI 0 "gpc_reg_operand" "")
661 (ashiftrt:SI (match_dup 2)
662 (const_int 24)))]
663 "! TARGET_POWER && ! TARGET_POWERPC"
664 "
665{ operands[1] = gen_lowpart (SImode, operands[1]);
666 operands[2] = gen_reg_rtx (SImode); }")
667
1fd4e8c1 668(define_expand "zero_extendqihi2"
cd2b37d9
RK
669 [(set (match_operand:HI 0 "gpc_reg_operand" "")
670 (zero_extend:HI (match_operand:QI 1 "gpc_reg_operand" "")))]
1fd4e8c1
RK
671 ""
672 "")
673
674(define_insn ""
cd2b37d9 675 [(set (match_operand:HI 0 "gpc_reg_operand" "=r,r")
1fd4e8c1
RK
676 (zero_extend:HI (match_operand:QI 1 "reg_or_mem_operand" "m,r")))]
677 ""
678 "@
679 lbz%U1%X1 %0,%1
005a35b9 680 {rlinm|rlwinm} %0,%1,0,0xff"
51b8fc2c
RK
681 [(set_attr "type" "load,*")])
682
683(define_insn ""
684 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
685 (compare:CC (zero_extend:HI (match_operand:QI 1 "gpc_reg_operand" "r"))
686 (const_int 0)))
687 (clobber (match_scratch:HI 2 "=r"))]
688 ""
689 "{andil.|andi.} %2,%1,0xff"
690 [(set_attr "type" "compare")])
691
692(define_insn ""
693 [(set (match_operand:CC 2 "cc_reg_operand" "=x")
694 (compare:CC (zero_extend:HI (match_operand:QI 1 "gpc_reg_operand" "r"))
695 (const_int 0)))
696 (set (match_operand:HI 0 "gpc_reg_operand" "=r")
697 (zero_extend:HI (match_dup 1)))]
698 ""
699 "{andil.|andi.} %0,%1,0xff"
700 [(set_attr "type" "compare")])
701
702(define_expand "extendqihi2"
703 [(use (match_operand:HI 0 "gpc_reg_operand" ""))
704 (use (match_operand:QI 1 "gpc_reg_operand" ""))]
705 ""
706 "
707{
708 if (TARGET_POWERPC)
709 emit_insn (gen_extendqihi2_ppc (operands[0], operands[1]));
710 else if (TARGET_POWER)
711 emit_insn (gen_extendqihi2_power (operands[0], operands[1]));
712 else
713 emit_insn (gen_extendqihi2_no_power (operands[0], operands[1]));
714 DONE;
715}")
716
717(define_insn "extendqihi2_ppc"
2bee0449
RK
718 [(set (match_operand:HI 0 "gpc_reg_operand" "=r")
719 (sign_extend:HI (match_operand:QI 1 "gpc_reg_operand" "r")))]
51b8fc2c 720 "TARGET_POWERPC"
2bee0449 721 "extsb %0,%1")
1fd4e8c1 722
51b8fc2c
RK
723(define_insn ""
724 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
725 (compare:CC (sign_extend:HI (match_operand:QI 1 "gpc_reg_operand" "r"))
726 (const_int 0)))
727 (clobber (match_scratch:HI 2 "=r"))]
728 "TARGET_POWERPC"
729 "extsb. %2,%1"
730 [(set_attr "type" "compare")])
731
732(define_insn ""
733 [(set (match_operand:CC 2 "cc_reg_operand" "=x")
734 (compare:CC (sign_extend:HI (match_operand:QI 1 "gpc_reg_operand" "r"))
735 (const_int 0)))
736 (set (match_operand:HI 0 "gpc_reg_operand" "=r")
737 (sign_extend:HI (match_dup 1)))]
738 "TARGET_POWERPC"
739 "extsb. %0,%1"
740 [(set_attr "type" "compare")])
741
742(define_expand "extendqihi2_power"
743 [(parallel [(set (match_dup 2)
744 (ashift:SI (match_operand:QI 1 "gpc_reg_operand" "")
745 (const_int 24)))
746 (clobber (scratch:SI))])
747 (parallel [(set (match_operand:HI 0 "gpc_reg_operand" "")
748 (ashiftrt:SI (match_dup 2)
749 (const_int 24)))
750 (clobber (scratch:SI))])]
751 "TARGET_POWER"
752 "
753{ operands[0] = gen_lowpart (SImode, operands[0]);
754 operands[1] = gen_lowpart (SImode, operands[1]);
755 operands[2] = gen_reg_rtx (SImode); }")
756
757(define_expand "extendqihi2_no_power"
758 [(set (match_dup 2)
759 (ashift:SI (match_operand:QI 1 "gpc_reg_operand" "")
760 (const_int 24)))
761 (set (match_operand:HI 0 "gpc_reg_operand" "")
762 (ashiftrt:SI (match_dup 2)
763 (const_int 24)))]
764 "! TARGET_POWER && ! TARGET_POWERPC"
765 "
766{ operands[0] = gen_lowpart (SImode, operands[0]);
767 operands[1] = gen_lowpart (SImode, operands[1]);
768 operands[2] = gen_reg_rtx (SImode); }")
769
1fd4e8c1 770(define_expand "zero_extendhisi2"
5f243543 771 [(set (match_operand:SI 0 "gpc_reg_operand" "")
cd2b37d9 772 (zero_extend:SI (match_operand:HI 1 "gpc_reg_operand" "")))]
1fd4e8c1
RK
773 ""
774 "")
775
776(define_insn ""
cd2b37d9 777 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
1fd4e8c1
RK
778 (zero_extend:SI (match_operand:HI 1 "reg_or_mem_operand" "m,r")))]
779 ""
780 "@
781 lhz%U1%X1 %0,%1
005a35b9 782 {rlinm|rlwinm} %0,%1,0,0xffff"
1fd4e8c1
RK
783 [(set_attr "type" "load,*")])
784
785(define_insn ""
786 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
cd2b37d9 787 (compare:CC (zero_extend:SI (match_operand:HI 1 "gpc_reg_operand" "r"))
1fd4e8c1
RK
788 (const_int 0)))
789 (clobber (match_scratch:SI 2 "=r"))]
790 ""
ca7f5001 791 "{andil.|andi.} %2,%1,0xffff"
1fd4e8c1
RK
792 [(set_attr "type" "compare")])
793
794(define_insn ""
795 [(set (match_operand:CC 2 "cc_reg_operand" "=x")
cd2b37d9 796 (compare:CC (zero_extend:SI (match_operand:HI 1 "gpc_reg_operand" "r"))
1fd4e8c1 797 (const_int 0)))
cd2b37d9 798 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
799 (zero_extend:SI (match_dup 1)))]
800 ""
ca7f5001 801 "{andil.|andi.} %0,%1,0xffff"
1fd4e8c1
RK
802 [(set_attr "type" "compare")])
803
804(define_expand "extendhisi2"
cd2b37d9
RK
805 [(set (match_operand:SI 0 "gpc_reg_operand" "")
806 (sign_extend:SI (match_operand:HI 1 "gpc_reg_operand" "")))]
1fd4e8c1
RK
807 ""
808 "")
809
810(define_insn ""
cd2b37d9 811 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
1fd4e8c1
RK
812 (sign_extend:SI (match_operand:HI 1 "reg_or_mem_operand" "m,r")))]
813 ""
814 "@
815 lha%U1%X1 %0,%1
ca7f5001 816 {exts|extsh} %0,%1"
1fd4e8c1
RK
817 [(set_attr "type" "load,*")])
818
819(define_insn ""
820 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
cd2b37d9 821 (compare:CC (sign_extend:SI (match_operand:HI 1 "gpc_reg_operand" "r"))
1fd4e8c1
RK
822 (const_int 0)))
823 (clobber (match_scratch:SI 2 "=r"))]
824 ""
ca7f5001 825 "{exts.|extsh.} %2,%1"
1fd4e8c1
RK
826 [(set_attr "type" "compare")])
827
828(define_insn ""
829 [(set (match_operand:CC 2 "cc_reg_operand" "=x")
cd2b37d9 830 (compare:CC (sign_extend:SI (match_operand:HI 1 "gpc_reg_operand" "r"))
1fd4e8c1 831 (const_int 0)))
cd2b37d9 832 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
833 (sign_extend:SI (match_dup 1)))]
834 ""
ca7f5001 835 "{exts.|extsh.} %0,%1"
1fd4e8c1
RK
836 [(set_attr "type" "compare")])
837\f
838;; Fixed-point arithmetic insns.
deb9225a
RK
839
840;; Discourage ai/addic because of carry but provide it in an alternative
841;; allowing register zero as source.
f357808b 842(define_insn "addsi3"
deb9225a
RK
843 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,?r,r")
844 (plus:SI (match_operand:SI 1 "gpc_reg_operand" "%r,b,r,b")
845 (match_operand:SI 2 "add_operand" "r,I,I,J")))]
1fd4e8c1
RK
846 ""
847 "@
deb9225a
RK
848 {cax|add} %0,%1,%2
849 {cal %0,%2(%1)|addi %0,%1,%2}
850 {ai|addic} %0,%1,%2
ca7f5001 851 {cau|addis} %0,%1,%u2")
1fd4e8c1
RK
852
853(define_insn ""
deb9225a
RK
854 [(set (match_operand:CC 0 "cc_reg_operand" "=x,x")
855 (compare:CC (plus:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r")
856 (match_operand:SI 2 "reg_or_short_operand" "r,I"))
1fd4e8c1 857 (const_int 0)))
deb9225a 858 (clobber (match_scratch:SI 3 "=r,r"))]
1fd4e8c1 859 ""
deb9225a
RK
860 "@
861 {cax.|add.} %3,%1,%2
862 {ai.|addic.} %3,%1,%2"
1fd4e8c1 863 [(set_attr "type" "compare")])
7e69e155 864
1fd4e8c1 865(define_insn ""
deb9225a
RK
866 [(set (match_operand:CC 3 "cc_reg_operand" "=x,x")
867 (compare:CC (plus:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r")
868 (match_operand:SI 2 "reg_or_short_operand" "r,I"))
1fd4e8c1 869 (const_int 0)))
deb9225a 870 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
1fd4e8c1
RK
871 (plus:SI (match_dup 1) (match_dup 2)))]
872 ""
deb9225a
RK
873 "@
874 {cax.|add.} %0,%1,%2
875 {ai.|addic.} %0,%1,%2"
1fd4e8c1 876 [(set_attr "type" "compare")])
7e69e155 877
f357808b
RK
878;; Split an add that we can't do in one insn into two insns, each of which
879;; does one 16-bit part. This is used by combine. Note that the low-order
880;; add should be last in case the result gets used in an address.
881
882(define_split
cd2b37d9
RK
883 [(set (match_operand:SI 0 "gpc_reg_operand" "")
884 (plus:SI (match_operand:SI 1 "gpc_reg_operand" "")
f357808b 885 (match_operand:SI 2 "non_add_cint_operand" "")))]
1fd4e8c1 886 ""
f357808b
RK
887 [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))
888 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 4)))]
889"
1fd4e8c1 890{
f357808b
RK
891 int low = INTVAL (operands[2]) & 0xffff;
892 int high = (unsigned) INTVAL (operands[2]) >> 16;
1fd4e8c1 893
f357808b
RK
894 if (low & 0x8000)
895 high++, low |= 0xffff0000;
1fd4e8c1 896
f357808b
RK
897 operands[3] = gen_rtx (CONST_INT, VOIDmode, high << 16);
898 operands[4] = gen_rtx (CONST_INT, VOIDmode, low);
1fd4e8c1
RK
899}")
900
8de2a197 901(define_insn "one_cmplsi2"
cd2b37d9
RK
902 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
903 (not:SI (match_operand:SI 1 "gpc_reg_operand" "r")))]
1fd4e8c1 904 ""
ca7f5001
RK
905 "nor %0,%1,%1")
906
907(define_insn ""
908 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
909 (compare:CC (not:SI (match_operand:SI 1 "gpc_reg_operand" "r"))
910 (const_int 0)))
911 (clobber (match_scratch:SI 2 "=r"))]
912 ""
913 "nor. %2,%1,%1"
914 [(set_attr "type" "compare")])
915
916(define_insn ""
8de2a197 917 [(set (match_operand:CC 2 "cc_reg_operand" "=x")
ca7f5001
RK
918 (compare:CC (not:SI (match_operand:SI 1 "gpc_reg_operand" "r"))
919 (const_int 0)))
920 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
921 (not:SI (match_dup 1)))]
922 ""
923 "nor. %0,%2,%1"
924 [(set_attr "type" "compare")])
1fd4e8c1
RK
925
926(define_insn ""
3d91674b
RK
927 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
928 (minus:SI (match_operand:SI 1 "reg_or_short_operand" "rI")
929 (match_operand:SI 2 "gpc_reg_operand" "r")))]
deb9225a 930 "! TARGET_POWERPC"
ca7f5001 931 "{sf%I1|subf%I1c} %0,%2,%1")
1fd4e8c1 932
deb9225a
RK
933(define_insn ""
934 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
935 (minus:SI (match_operand:SI 1 "reg_or_short_operand" "r,I")
936 (match_operand:SI 2 "gpc_reg_operand" "r,r")))]
937 "TARGET_POWERPC"
938 "@
939 subf %0,%2,%1
940 subfic %0,%2,%1")
941
1fd4e8c1
RK
942(define_insn ""
943 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
cd2b37d9
RK
944 (compare:CC (minus:SI (match_operand:SI 1 "gpc_reg_operand" "r")
945 (match_operand:SI 2 "gpc_reg_operand" "r"))
1fd4e8c1
RK
946 (const_int 0)))
947 (clobber (match_scratch:SI 3 "=r"))]
deb9225a 948 "! TARGET_POWERPC"
ca7f5001 949 "{sf.|subfc.} %3,%2,%1"
1fd4e8c1
RK
950 [(set_attr "type" "compare")])
951
deb9225a
RK
952(define_insn ""
953 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
954 (compare:CC (minus:SI (match_operand:SI 1 "gpc_reg_operand" "r")
955 (match_operand:SI 2 "gpc_reg_operand" "r"))
956 (const_int 0)))
957 (clobber (match_scratch:SI 3 "=r"))]
958 "TARGET_POWERPC"
959 "subf. %3,%2,%1"
960 [(set_attr "type" "compare")])
961
1fd4e8c1
RK
962(define_insn ""
963 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
cd2b37d9
RK
964 (compare:CC (minus:SI (match_operand:SI 1 "gpc_reg_operand" "r")
965 (match_operand:SI 2 "gpc_reg_operand" "r"))
1fd4e8c1 966 (const_int 0)))
cd2b37d9 967 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1 968 (minus:SI (match_dup 1) (match_dup 2)))]
deb9225a 969 "! TARGET_POWERPC"
ca7f5001 970 "{sf.|subfc.} %0,%2,%1"
1fd4e8c1
RK
971 [(set_attr "type" "compare")])
972
deb9225a
RK
973(define_insn ""
974 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
975 (compare:CC (minus:SI (match_operand:SI 1 "gpc_reg_operand" "r")
976 (match_operand:SI 2 "gpc_reg_operand" "r"))
977 (const_int 0)))
978 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
979 (minus:SI (match_dup 1) (match_dup 2)))]
980 "TARGET_POWERPC"
981 "subf. %0,%2,%1"
982 [(set_attr "type" "compare")])
983
1fd4e8c1 984(define_expand "subsi3"
cd2b37d9 985 [(set (match_operand:SI 0 "gpc_reg_operand" "")
1fd4e8c1
RK
986 (minus:SI (match_operand:SI 1 "reg_or_short_operand" "")
987 (match_operand:SI 2 "reg_or_cint_operand" "")))]
988 ""
a0044fb1
RK
989 "
990{
991 if (GET_CODE (operands[2]) == CONST_INT)
992 {
993 emit_insn (gen_addsi3 (operands[0], operands[1],
994 negate_rtx (SImode, operands[2])));
995 DONE;
996 }
997}")
1fd4e8c1
RK
998
999;; For SMIN, SMAX, UMIN, and UMAX, we use DEFINE_EXPAND's that involve a doz[i]
1000;; instruction and some auxiliary computations. Then we just have a single
95ac8e67
RK
1001;; DEFINE_INSN for doz[i] and the define_splits to make them if made by
1002;; combine.
1fd4e8c1
RK
1003
1004(define_expand "sminsi3"
1005 [(set (match_dup 3)
cd2b37d9 1006 (if_then_else:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "")
1fd4e8c1
RK
1007 (match_operand:SI 2 "reg_or_short_operand" ""))
1008 (const_int 0)
1009 (minus:SI (match_dup 2) (match_dup 1))))
cd2b37d9 1010 (set (match_operand:SI 0 "gpc_reg_operand" "")
1fd4e8c1 1011 (minus:SI (match_dup 2) (match_dup 3)))]
ca7f5001 1012 "TARGET_POWER"
1fd4e8c1
RK
1013 "
1014{ operands[3] = gen_reg_rtx (SImode); }")
1015
95ac8e67
RK
1016(define_split
1017 [(set (match_operand:SI 0 "gpc_reg_operand" "")
1018 (smin:SI (match_operand:SI 1 "gpc_reg_operand" "")
1019 (match_operand:SI 2 "reg_or_short_operand" "")))
1020 (clobber (match_operand:SI 3 "gpc_reg_operand" ""))]
ca7f5001 1021 "TARGET_POWER"
95ac8e67
RK
1022 [(set (match_dup 3)
1023 (if_then_else:SI (gt:SI (match_dup 1) (match_dup 2))
1024 (const_int 0)
1025 (minus:SI (match_dup 2) (match_dup 1))))
1026 (set (match_dup 0) (minus:SI (match_dup 2) (match_dup 3)))]
1027 "")
1028
1fd4e8c1
RK
1029(define_expand "smaxsi3"
1030 [(set (match_dup 3)
cd2b37d9 1031 (if_then_else:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "")
1fd4e8c1
RK
1032 (match_operand:SI 2 "reg_or_short_operand" ""))
1033 (const_int 0)
1034 (minus:SI (match_dup 2) (match_dup 1))))
cd2b37d9 1035 (set (match_operand:SI 0 "gpc_reg_operand" "")
1fd4e8c1 1036 (plus:SI (match_dup 3) (match_dup 1)))]
ca7f5001 1037 "TARGET_POWER"
1fd4e8c1
RK
1038 "
1039{ operands[3] = gen_reg_rtx (SImode); }")
1040
95ac8e67
RK
1041(define_split
1042 [(set (match_operand:SI 0 "gpc_reg_operand" "")
1043 (smax:SI (match_operand:SI 1 "gpc_reg_operand" "")
1044 (match_operand:SI 2 "reg_or_short_operand" "")))
1045 (clobber (match_operand:SI 3 "gpc_reg_operand" ""))]
ca7f5001 1046 "TARGET_POWER"
95ac8e67
RK
1047 [(set (match_dup 3)
1048 (if_then_else:SI (gt:SI (match_dup 1) (match_dup 2))
1049 (const_int 0)
1050 (minus:SI (match_dup 2) (match_dup 1))))
1051 (set (match_dup 0) (plus:SI (match_dup 3) (match_dup 1)))]
1052 "")
1053
1fd4e8c1 1054(define_expand "uminsi3"
cd2b37d9 1055 [(set (match_dup 3) (xor:SI (match_operand:SI 1 "gpc_reg_operand" "")
bb68ff55 1056 (match_dup 5)))
cd2b37d9 1057 (set (match_dup 4) (xor:SI (match_operand:SI 2 "gpc_reg_operand" "")
bb68ff55 1058 (match_dup 5)))
1fd4e8c1
RK
1059 (set (match_dup 3) (if_then_else:SI (gt (match_dup 3) (match_dup 4))
1060 (const_int 0)
1061 (minus:SI (match_dup 4) (match_dup 3))))
cd2b37d9 1062 (set (match_operand:SI 0 "gpc_reg_operand" "")
1fd4e8c1 1063 (minus:SI (match_dup 2) (match_dup 3)))]
ca7f5001 1064 "TARGET_POWER"
1fd4e8c1 1065 "
bb68ff55
MM
1066{
1067 operands[3] = gen_reg_rtx (SImode);
1068 operands[4] = gen_reg_rtx (SImode);
1069 operands[5] = GEN_INT (-2147483647 - 1);
1070}")
1fd4e8c1
RK
1071
1072(define_expand "umaxsi3"
cd2b37d9 1073 [(set (match_dup 3) (xor:SI (match_operand:SI 1 "gpc_reg_operand" "")
bb68ff55 1074 (match_dup 5)))
cd2b37d9 1075 (set (match_dup 4) (xor:SI (match_operand:SI 2 "gpc_reg_operand" "")
bb68ff55 1076 (match_dup 5)))
1fd4e8c1
RK
1077 (set (match_dup 3) (if_then_else:SI (gt (match_dup 3) (match_dup 4))
1078 (const_int 0)
1079 (minus:SI (match_dup 4) (match_dup 3))))
cd2b37d9 1080 (set (match_operand:SI 0 "gpc_reg_operand" "")
1fd4e8c1 1081 (plus:SI (match_dup 3) (match_dup 1)))]
ca7f5001 1082 "TARGET_POWER"
1fd4e8c1 1083 "
bb68ff55
MM
1084{
1085 operands[3] = gen_reg_rtx (SImode);
1086 operands[4] = gen_reg_rtx (SImode);
1087 operands[5] = GEN_INT (-2147483647 - 1);
1088}")
1fd4e8c1
RK
1089
1090(define_insn ""
cd2b37d9
RK
1091 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1092 (if_then_else:SI (gt (match_operand:SI 1 "gpc_reg_operand" "r")
5c23c401 1093 (match_operand:SI 2 "reg_or_short_operand" "rI"))
1fd4e8c1
RK
1094 (const_int 0)
1095 (minus:SI (match_dup 2) (match_dup 1))))]
ca7f5001 1096 "TARGET_POWER"
1fd4e8c1
RK
1097 "doz%I2 %0,%1,%2")
1098
1099(define_insn ""
1100 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
1101 (compare:CC
cd2b37d9 1102 (if_then_else:SI (gt (match_operand:SI 1 "gpc_reg_operand" "r")
5c23c401 1103 (match_operand:SI 2 "reg_or_short_operand" "rI"))
1fd4e8c1
RK
1104 (const_int 0)
1105 (minus:SI (match_dup 2) (match_dup 1)))
1106 (const_int 0)))
1107 (clobber (match_scratch:SI 3 "=r"))]
ca7f5001 1108 "TARGET_POWER"
1fd4e8c1
RK
1109 "doz%I2. %3,%1,%2"
1110 [(set_attr "type" "delayed_compare")])
1111
1112(define_insn ""
1113 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1114 (compare:CC
cd2b37d9 1115 (if_then_else:SI (gt (match_operand:SI 1 "gpc_reg_operand" "r")
5c23c401 1116 (match_operand:SI 2 "reg_or_short_operand" "rI"))
1fd4e8c1
RK
1117 (const_int 0)
1118 (minus:SI (match_dup 2) (match_dup 1)))
1119 (const_int 0)))
cd2b37d9 1120 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
1121 (if_then_else:SI (gt (match_dup 1) (match_dup 2))
1122 (const_int 0)
1123 (minus:SI (match_dup 2) (match_dup 1))))]
ca7f5001 1124 "TARGET_POWER"
1fd4e8c1
RK
1125 "doz%I2. %0,%1,%2"
1126 [(set_attr "type" "delayed_compare")])
1127
1128;; We don't need abs with condition code because such comparisons should
1129;; never be done.
ea9be077
MM
1130(define_expand "abssi2"
1131 [(set (match_operand:SI 0 "gpc_reg_operand" "")
1132 (abs:SI (match_operand:SI 1 "gpc_reg_operand" "")))]
1133 ""
1134 "
1135{
1136 if (!TARGET_POWER)
1137 {
1138 emit_insn (gen_abssi2_nopower (operands[0], operands[1]));
1139 DONE;
1140 }
1141}")
1142
1143(define_insn "abssi2_power"
cd2b37d9
RK
1144 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1145 (abs:SI (match_operand:SI 1 "gpc_reg_operand" "r")))]
ca7f5001 1146 "TARGET_POWER"
1fd4e8c1
RK
1147 "abs %0,%1")
1148
ea9be077
MM
1149(define_insn "abssi2_nopower"
1150 [(set (match_operand:SI 0 "gpc_reg_operand" "=&r,r")
1151 (abs:SI (match_operand:SI 1 "gpc_reg_operand" "r,0")))
1152 (clobber (match_scratch:SI 2 "=&r,&r"))]
1153 "!TARGET_POWER"
3595d104
MM
1154 "*
1155{
1156 return (TARGET_POWERPC)
1157 ? \"{srai|srawi} %2,%1,31\;xor %0,%2,%1\;subf %0,%2,%0\"
1158 : \"{srai|srawi} %2,%1,31\;xor %0,%2,%1\;{sf|subfc} %0,%2,%0\";
1159}"
ea9be077
MM
1160 [(set_attr "length" "12")])
1161
1162(define_split
1163 [(set (match_operand:SI 0 "gpc_reg_operand" "=&r,r")
1164 (abs:SI (match_operand:SI 1 "gpc_reg_operand" "r,0")))
1165 (clobber (match_scratch:SI 2 "=&r,&r"))]
1166 "!TARGET_POWER && reload_completed"
1167 [(set (match_dup 2) (ashiftrt:SI (match_dup 1) (const_int 31)))
1168 (set (match_dup 0) (xor:SI (match_dup 2) (match_dup 1)))
1169 (set (match_dup 0) (minus:SI (match_dup 2) (match_dup 0)))]
1170 "")
1171
1fd4e8c1 1172(define_insn ""
cd2b37d9
RK
1173 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1174 (neg:SI (abs:SI (match_operand:SI 1 "gpc_reg_operand" "r"))))]
ca7f5001 1175 "TARGET_POWER"
1fd4e8c1
RK
1176 "nabs %0,%1")
1177
ea9be077
MM
1178(define_insn ""
1179 [(set (match_operand:SI 0 "gpc_reg_operand" "=&r,r")
1180 (neg:SI (abs:SI (match_operand:SI 1 "gpc_reg_operand" "r,0"))))
1181 (clobber (match_scratch:SI 2 "=&r,&r"))]
1182 "!TARGET_POWER"
3595d104
MM
1183 "*
1184{
1185 return (TARGET_POWERPC)
1186 ? \"{srai|srawi} %2,%1,31\;xor %0,%2,%1\;subf %0,%0,%2\"
1187 : \"{srai|srawi} %2,%1,31\;xor %0,%2,%1\;{sf|subfc} %0,%0,%2\";
1188}"
ea9be077
MM
1189 [(set_attr "length" "12")])
1190
1191(define_split
1192 [(set (match_operand:SI 0 "gpc_reg_operand" "=&r,r")
1193 (neg:SI (abs:SI (match_operand:SI 1 "gpc_reg_operand" "r,0"))))
1194 (clobber (match_scratch:SI 2 "=&r,&r"))]
1195 "!TARGET_POWER && reload_completed"
1196 [(set (match_dup 2) (ashiftrt:SI (match_dup 1) (const_int 31)))
1197 (set (match_dup 0) (xor:SI (match_dup 2) (match_dup 1)))
1198 (set (match_dup 0) (minus:SI (match_dup 0) (match_dup 2)))]
1199 "")
1200
1fd4e8c1 1201(define_insn "negsi2"
cd2b37d9
RK
1202 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1203 (neg:SI (match_operand:SI 1 "gpc_reg_operand" "r")))]
1fd4e8c1
RK
1204 ""
1205 "neg %0,%1")
1206
1207(define_insn ""
1208 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
cd2b37d9 1209 (compare:CC (neg:SI (match_operand:SI 1 "gpc_reg_operand" "r"))
1fd4e8c1
RK
1210 (const_int 0)))
1211 (clobber (match_scratch:SI 2 "=r"))]
1212 ""
1213 "neg. %2,%1"
1214 [(set_attr "type" "compare")])
1215
1216(define_insn ""
1217 [(set (match_operand:CC 2 "cc_reg_operand" "=x")
cd2b37d9 1218 (compare:CC (neg:SI (match_operand:SI 1 "gpc_reg_operand" "r"))
1fd4e8c1 1219 (const_int 0)))
cd2b37d9 1220 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
1221 (neg:SI (match_dup 1)))]
1222 ""
1223 "neg. %0,%1"
1224 [(set_attr "type" "compare")])
1225
1226(define_insn "ffssi2"
242e8072
RK
1227 [(set (match_operand:SI 0 "gpc_reg_operand" "=&r")
1228 (ffs:SI (match_operand:SI 1 "gpc_reg_operand" "r")))]
1fd4e8c1 1229 ""
7f340546 1230 "neg %0,%1\;and %0,%0,%1\;{cntlz|cntlzw} %0,%0\;{sfi|subfic} %0,%0,32"
b19003d8 1231 [(set_attr "length" "16")])
1fd4e8c1 1232
ca7f5001
RK
1233(define_expand "mulsi3"
1234 [(use (match_operand:SI 0 "gpc_reg_operand" ""))
1235 (use (match_operand:SI 1 "gpc_reg_operand" ""))
1236 (use (match_operand:SI 2 "reg_or_short_operand" ""))]
1237 ""
1238 "
1239{
1240 if (TARGET_POWER)
68b40e7e 1241 emit_insn (gen_mulsi3_mq (operands[0], operands[1], operands[2]));
ca7f5001 1242 else
68b40e7e 1243 emit_insn (gen_mulsi3_no_mq (operands[0], operands[1], operands[2]));
ca7f5001
RK
1244 DONE;
1245}")
1246
68b40e7e 1247(define_insn "mulsi3_mq"
cd2b37d9
RK
1248 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
1249 (mult:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r")
1fd4e8c1
RK
1250 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
1251 (clobber (match_scratch:SI 3 "=q,q"))]
ca7f5001
RK
1252 "TARGET_POWER"
1253 "@
1254 {muls|mullw} %0,%1,%2
1255 {muli|mulli} %0,%1,%2"
1256 [(set_attr "type" "imul")])
1257
68b40e7e 1258(define_insn "mulsi3_no_mq"
ca7f5001
RK
1259 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
1260 (mult:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r")
1261 (match_operand:SI 2 "reg_or_short_operand" "r,I")))]
68b40e7e 1262 "! TARGET_POWER"
1fd4e8c1 1263 "@
d904e9ed
RK
1264 {muls|mullw} %0,%1,%2
1265 {muli|mulli} %0,%1,%2"
cfb557c4 1266 [(set_attr "type" "imul")])
1fd4e8c1
RK
1267
1268(define_insn ""
1269 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
deb9225a 1270 (compare:CC (mult:SI (match_operand:SI 1 "gpc_reg_operand" "%r")
cd2b37d9 1271 (match_operand:SI 2 "gpc_reg_operand" "r"))
1fd4e8c1
RK
1272 (const_int 0)))
1273 (clobber (match_scratch:SI 3 "=r"))
1274 (clobber (match_scratch:SI 4 "=q"))]
ca7f5001
RK
1275 "TARGET_POWER"
1276 "{muls.|mullw.} %3,%1,%2"
1277 [(set_attr "type" "delayed_compare")])
1278
1279(define_insn ""
1280 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
deb9225a 1281 (compare:CC (mult:SI (match_operand:SI 1 "gpc_reg_operand" "%r")
ca7f5001
RK
1282 (match_operand:SI 2 "gpc_reg_operand" "r"))
1283 (const_int 0)))
1284 (clobber (match_scratch:SI 3 "=r"))]
25c341fa 1285 "! TARGET_POWER"
d904e9ed 1286 "{muls.|mullw.} %3,%1,%2"
1fd4e8c1
RK
1287 [(set_attr "type" "delayed_compare")])
1288
1289(define_insn ""
1290 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
deb9225a 1291 (compare:CC (mult:SI (match_operand:SI 1 "gpc_reg_operand" "%r")
cd2b37d9 1292 (match_operand:SI 2 "gpc_reg_operand" "r"))
1fd4e8c1 1293 (const_int 0)))
cd2b37d9 1294 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
1295 (mult:SI (match_dup 1) (match_dup 2)))
1296 (clobber (match_scratch:SI 4 "=q"))]
ca7f5001
RK
1297 "TARGET_POWER"
1298 "{muls.|mullw.} %0,%1,%2"
1299 [(set_attr "type" "delayed_compare")])
1300
1301(define_insn ""
1302 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
deb9225a 1303 (compare:CC (mult:SI (match_operand:SI 1 "gpc_reg_operand" "%r")
ca7f5001
RK
1304 (match_operand:SI 2 "gpc_reg_operand" "r"))
1305 (const_int 0)))
1306 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1307 (mult:SI (match_dup 1) (match_dup 2)))]
25c341fa 1308 "! TARGET_POWER"
d904e9ed 1309 "{muls.|mullw.} %0,%1,%2"
1fd4e8c1
RK
1310 [(set_attr "type" "delayed_compare")])
1311
1312;; Operand 1 is divided by operand 2; quotient goes to operand
1313;; 0 and remainder to operand 3.
1314;; ??? At some point, see what, if anything, we can do about if (x % y == 0).
1315
8ffd9c51
RK
1316(define_expand "divmodsi4"
1317 [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "")
1318 (div:SI (match_operand:SI 1 "gpc_reg_operand" "")
1319 (match_operand:SI 2 "gpc_reg_operand" "")))
1320 (set (match_operand:SI 3 "gpc_reg_operand" "")
1321 (mod:SI (match_dup 1) (match_dup 2)))])]
1322 "TARGET_POWER || (! TARGET_POWER && ! TARGET_POWERPC)"
1323 "
1324{
1325 if (! TARGET_POWER && ! TARGET_POWERPC)
1326 {
1327 emit_move_insn (gen_rtx (REG, SImode, 3), operands[1]);
1328 emit_move_insn (gen_rtx (REG, SImode, 4), operands[2]);
fada905b 1329 emit_insn (gen_divss_call ());
8ffd9c51
RK
1330 emit_move_insn (operands[0], gen_rtx (REG, SImode, 3));
1331 emit_move_insn (operands[3], gen_rtx (REG, SImode, 4));
1332 DONE;
1333 }
1334}")
deb9225a 1335
fada905b 1336(define_insn ""
cd2b37d9
RK
1337 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1338 (div:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1339 (match_operand:SI 2 "gpc_reg_operand" "r")))
1340 (set (match_operand:SI 3 "gpc_reg_operand" "=q")
1fd4e8c1 1341 (mod:SI (match_dup 1) (match_dup 2)))]
ca7f5001 1342 "TARGET_POWER"
cfb557c4
RK
1343 "divs %0,%1,%2"
1344 [(set_attr "type" "idiv")])
1fd4e8c1 1345
fada905b 1346(define_insn ""
ca7f5001
RK
1347 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1348 (div:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1349 (match_operand:SI 2 "gpc_reg_operand" "r")))]
1350 "TARGET_POWERPC"
a473029f 1351 "divw %0,%1,%2"
ca7f5001
RK
1352 [(set_attr "type" "idiv")])
1353
8ffd9c51
RK
1354(define_expand "udivsi3"
1355 [(set (match_operand:SI 0 "gpc_reg_operand" "")
1356 (udiv:SI (match_operand:SI 1 "gpc_reg_operand" "")
1357 (match_operand:SI 2 "gpc_reg_operand" "")))]
1358 "TARGET_POWERPC || (! TARGET_POWER && ! TARGET_POWERPC)"
1359 "
1360{
1361 if (! TARGET_POWER && ! TARGET_POWERPC)
1362 {
1363 emit_move_insn (gen_rtx (REG, SImode, 3), operands[1]);
1364 emit_move_insn (gen_rtx (REG, SImode, 4), operands[2]);
fada905b 1365 emit_insn (gen_quous_call ());
8ffd9c51
RK
1366 emit_move_insn (operands[0], gen_rtx (REG, SImode, 3));
1367 DONE;
1368 }
1369}")
deb9225a 1370
fada905b 1371(define_insn ""
ca7f5001
RK
1372 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1373 (udiv:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1374 (match_operand:SI 2 "gpc_reg_operand" "r")))]
1375 "TARGET_POWERPC"
a473029f 1376 "divwu %0,%1,%2"
ca7f5001
RK
1377 [(set_attr "type" "idiv")])
1378
1fd4e8c1 1379;; For powers of two we can do srai/aze for divide and then adjust for
ca7f5001 1380;; modulus. If it isn't a power of two, FAIL on POWER so divmodsi4 will be
8ffd9c51
RK
1381;; used; for PowerPC, force operands into register and do a normal divide;
1382;; for AIX common-mode, use quoss call on register operands.
1fd4e8c1 1383(define_expand "divsi3"
cd2b37d9
RK
1384 [(set (match_operand:SI 0 "gpc_reg_operand" "")
1385 (div:SI (match_operand:SI 1 "gpc_reg_operand" "")
1fd4e8c1
RK
1386 (match_operand:SI 2 "reg_or_cint_operand" "")))]
1387 ""
1388 "
1389{
ca7f5001
RK
1390 if (GET_CODE (operands[2]) == CONST_INT
1391 && exact_log2 (INTVAL (operands[2])) >= 0)
1392 ;
b6c9286a
MM
1393 else if (TARGET_POWERPC)
1394 operands[2] = force_reg (SImode, operands[2]);
1395 else if (TARGET_POWER)
1fd4e8c1 1396 FAIL;
405c5495 1397 else
8ffd9c51
RK
1398 {
1399 emit_move_insn (gen_rtx (REG, SImode, 3), operands[1]);
1400 emit_move_insn (gen_rtx (REG, SImode, 4), operands[2]);
fada905b 1401 emit_insn (gen_quoss_call ());
8ffd9c51
RK
1402 emit_move_insn (operands[0], gen_rtx (REG, SImode, 3));
1403 DONE;
1404 }
1fd4e8c1
RK
1405}")
1406
1407(define_expand "modsi3"
85644414
RK
1408 [(use (match_operand:SI 0 "gpc_reg_operand" ""))
1409 (use (match_operand:SI 1 "gpc_reg_operand" ""))
405c5495 1410 (use (match_operand:SI 2 "reg_or_cint_operand" ""))]
39b52ba2 1411 ""
1fd4e8c1
RK
1412 "
1413{
39b52ba2
RK
1414 int i = exact_log2 (INTVAL (operands[2]));
1415 rtx temp1;
1416 rtx temp2;
1417
405c5495 1418 if (GET_CODE (operands[2]) != CONST_INT || i < 0)
39b52ba2
RK
1419 FAIL;
1420
1421 temp1 = gen_reg_rtx (SImode);
1422 temp2 = gen_reg_rtx (SImode);
1fd4e8c1 1423
85644414 1424 emit_insn (gen_divsi3 (temp1, operands[1], operands[2]));
39b52ba2 1425 emit_insn (gen_ashlsi3 (temp2, temp1, GEN_INT (i)));
85644414
RK
1426 emit_insn (gen_subsi3 (operands[0], operands[1], temp2));
1427 DONE;
1fd4e8c1
RK
1428}")
1429
1430(define_insn ""
cd2b37d9
RK
1431 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1432 (div:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
1433 (match_operand:SI 2 "const_int_operand" "N")))]
1434 "exact_log2 (INTVAL (operands[2])) >= 0"
ca7f5001 1435 "{srai|srawi} %0,%1,%p2\;{aze|addze} %0,%0"
b19003d8 1436 [(set_attr "length" "8")])
1fd4e8c1
RK
1437
1438(define_insn ""
1439 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
b6b12107
RK
1440 (compare:CC (div:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1441 (match_operand:SI 2 "const_int_operand" "N"))
1442 (const_int 0)))
1fd4e8c1
RK
1443 (clobber (match_scratch:SI 3 "=r"))]
1444 "exact_log2 (INTVAL (operands[2])) >= 0"
ca7f5001 1445 "{srai|srawi} %3,%1,%p2\;{aze.|addze.} %3,%3"
b19003d8
RK
1446 [(set_attr "type" "compare")
1447 (set_attr "length" "8")])
1fd4e8c1
RK
1448
1449(define_insn ""
1450 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
b6b12107
RK
1451 (compare:CC (div:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1452 (match_operand:SI 2 "const_int_operand" "N"))
1453 (const_int 0)))
cd2b37d9 1454 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
1455 (div:SI (match_dup 1) (match_dup 2)))]
1456 "exact_log2 (INTVAL (operands[2])) >= 0"
ca7f5001 1457 "{srai|srawi} %0,%1,%p2\;{aze.|addze.} %0,%0"
b19003d8
RK
1458 [(set_attr "type" "compare")
1459 (set_attr "length" "8")])
1fd4e8c1
RK
1460
1461(define_insn ""
cd2b37d9 1462 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1 1463 (udiv:SI
996a5f59 1464 (plus:DI (ashift:DI
cd2b37d9 1465 (zero_extend:DI (match_operand:SI 1 "gpc_reg_operand" "r"))
1fd4e8c1 1466 (const_int 32))
23a900dc 1467 (zero_extend:DI (match_operand:SI 4 "register_operand" "2")))
cd2b37d9 1468 (match_operand:SI 3 "gpc_reg_operand" "r")))
740ab4a2 1469 (set (match_operand:SI 2 "register_operand" "=*q")
1fd4e8c1 1470 (umod:SI
996a5f59 1471 (plus:DI (ashift:DI
1fd4e8c1 1472 (zero_extend:DI (match_dup 1)) (const_int 32))
740ab4a2 1473 (zero_extend:DI (match_dup 4)))
1fd4e8c1 1474 (match_dup 3)))]
ca7f5001 1475 "TARGET_POWER"
cfb557c4
RK
1476 "div %0,%1,%3"
1477 [(set_attr "type" "idiv")])
1fd4e8c1
RK
1478
1479;; To do unsigned divide we handle the cases of the divisor looking like a
1480;; negative number. If it is a constant that is less than 2**31, we don't
1481;; have to worry about the branches. So make a few subroutines here.
1482;;
1483;; First comes the normal case.
1484(define_expand "udivmodsi4_normal"
1485 [(set (match_dup 4) (const_int 0))
1486 (parallel [(set (match_operand:SI 0 "" "")
996a5f59 1487 (udiv:SI (plus:DI (ashift:DI (zero_extend:DI (match_dup 4))
1fd4e8c1
RK
1488 (const_int 32))
1489 (zero_extend:DI (match_operand:SI 1 "" "")))
1490 (match_operand:SI 2 "" "")))
1491 (set (match_operand:SI 3 "" "")
996a5f59 1492 (umod:SI (plus:DI (ashift:DI (zero_extend:DI (match_dup 4))
1fd4e8c1
RK
1493 (const_int 32))
1494 (zero_extend:DI (match_dup 1)))
1495 (match_dup 2)))])]
ca7f5001 1496 "TARGET_POWER"
1fd4e8c1
RK
1497 "
1498{ operands[4] = gen_reg_rtx (SImode); }")
1499
1500;; This handles the branches.
1501(define_expand "udivmodsi4_tests"
1502 [(set (match_operand:SI 0 "" "") (const_int 0))
1503 (set (match_operand:SI 3 "" "") (match_operand:SI 1 "" ""))
1504 (set (match_dup 5) (compare:CCUNS (match_dup 1) (match_operand:SI 2 "" "")))
1505 (set (pc) (if_then_else (ltu (match_dup 5) (const_int 0))
1506 (label_ref (match_operand:SI 4 "" "")) (pc)))
1507 (set (match_dup 0) (const_int 1))
1508 (set (match_dup 3) (minus:SI (match_dup 1) (match_dup 2)))
1509 (set (match_dup 6) (compare:CC (match_dup 2) (const_int 0)))
1510 (set (pc) (if_then_else (lt (match_dup 6) (const_int 0))
1511 (label_ref (match_dup 4)) (pc)))]
ca7f5001 1512 "TARGET_POWER"
1fd4e8c1
RK
1513 "
1514{ operands[5] = gen_reg_rtx (CCUNSmode);
1515 operands[6] = gen_reg_rtx (CCmode);
1516}")
1517
1518(define_expand "udivmodsi4"
cd2b37d9
RK
1519 [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "")
1520 (udiv:SI (match_operand:SI 1 "gpc_reg_operand" "")
1fd4e8c1 1521 (match_operand:SI 2 "reg_or_cint_operand" "")))
cd2b37d9 1522 (set (match_operand:SI 3 "gpc_reg_operand" "")
1fd4e8c1 1523 (umod:SI (match_dup 1) (match_dup 2)))])]
8ffd9c51 1524 ""
1fd4e8c1
RK
1525 "
1526{
1527 rtx label = 0;
1528
8ffd9c51
RK
1529 if (! TARGET_POWER)
1530 if (! TARGET_POWERPC)
1531 {
1532 emit_move_insn (gen_rtx (REG, SImode, 3), operands[1]);
1533 emit_move_insn (gen_rtx (REG, SImode, 4), operands[2]);
fada905b 1534 emit_insn (gen_divus_call ());
8ffd9c51
RK
1535 emit_move_insn (operands[0], gen_rtx (REG, SImode, 3));
1536 emit_move_insn (operands[3], gen_rtx (REG, SImode, 4));
1537 DONE;
1538 }
1539 else
1540 FAIL;
0081a354 1541
1fd4e8c1
RK
1542 if (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) < 0)
1543 {
1544 operands[2] = force_reg (SImode, operands[2]);
1545 label = gen_label_rtx ();
1546 emit (gen_udivmodsi4_tests (operands[0], operands[1], operands[2],
1547 operands[3], label));
1548 }
1549 else
1550 operands[2] = force_reg (SImode, operands[2]);
1551
1552 emit (gen_udivmodsi4_normal (operands[0], operands[1], operands[2],
1553 operands[3]));
1554 if (label)
1555 emit_label (label);
1556
1557 DONE;
1558}")
0081a354 1559
fada905b
MM
1560;; AIX architecture-independent common-mode multiply (DImode),
1561;; divide/modulus, and quotient subroutine calls. Input operands in R3 and
1562;; R4; results in R3 and sometimes R4; link register always clobbered by bla
1563;; instruction; R0 sometimes clobbered; also, MQ sometimes clobbered but
1564;; assumed unused if generating common-mode, so ignore.
1565(define_insn "mulh_call"
1566 [(set (reg:SI 3)
1567 (truncate:SI
1568 (lshiftrt:DI (mult:DI (sign_extend:DI (reg:SI 3))
1569 (sign_extend:DI (reg:SI 4)))
1570 (const_int 32))))
cf27b467 1571 (clobber (match_scratch:SI 0 "=l"))]
fada905b
MM
1572 "! TARGET_POWER && ! TARGET_POWERPC"
1573 "bla __mulh")
1574
1575(define_insn "mull_call"
1576 [(set (reg:DI 3)
1577 (mult:DI (sign_extend:DI (reg:SI 3))
1578 (sign_extend:DI (reg:SI 4))))
1579 (clobber (match_scratch:SI 0 "=l"))
1580 (clobber (reg:SI 0))]
1581 "! TARGET_POWER && ! TARGET_POWERPC"
1582 "bla __mull")
1583
1584(define_insn "divss_call"
1585 [(set (reg:SI 3)
1586 (div:SI (reg:SI 3) (reg:SI 4)))
1587 (set (reg:SI 4)
1588 (mod:SI (reg:SI 3) (reg:SI 4)))
1589 (clobber (match_scratch:SI 0 "=l"))
1590 (clobber (reg:SI 0))]
1591 "! TARGET_POWER && ! TARGET_POWERPC"
1592 "bla __divss")
1593
1594(define_insn "divus_call"
8ffd9c51
RK
1595 [(set (reg:SI 3)
1596 (udiv:SI (reg:SI 3) (reg:SI 4)))
1597 (set (reg:SI 4)
1598 (umod:SI (reg:SI 3) (reg:SI 4)))
1599 (clobber (match_scratch:SI 0 "=l"))
fada905b
MM
1600 (clobber (reg:SI 0))
1601 (clobber (match_scratch:CC 1 "=x"))
1602 (clobber (reg:CC 69))]
1603 "! TARGET_POWER && ! TARGET_POWERPC"
1604 "bla __divus")
1605
1606(define_insn "quoss_call"
1607 [(set (reg:SI 3)
1608 (div:SI (reg:SI 3) (reg:SI 4)))
cf27b467 1609 (clobber (match_scratch:SI 0 "=l"))]
8ffd9c51 1610 "! TARGET_POWER && ! TARGET_POWERPC"
fada905b 1611 "bla __quoss")
0081a354 1612
fada905b
MM
1613(define_insn "quous_call"
1614 [(set (reg:SI 3)
1615 (udiv:SI (reg:SI 3) (reg:SI 4)))
1616 (clobber (match_scratch:SI 0 "=l"))
1617 (clobber (reg:SI 0))
1618 (clobber (match_scratch:CC 1 "=x"))
1619 (clobber (reg:CC 69))]
1620 "! TARGET_POWER && ! TARGET_POWERPC"
1621 "bla __quous")
8ffd9c51 1622\f
1fd4e8c1 1623(define_insn "andsi3"
cd2b37d9
RK
1624 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r")
1625 (and:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r")
1fd4e8c1
RK
1626 (match_operand:SI 2 "and_operand" "?r,L,K,J")))
1627 (clobber (match_scratch:CC 3 "=X,X,x,x"))]
1628 ""
1629 "@
1630 and %0,%1,%2
ca7f5001
RK
1631 {rlinm|rlwinm} %0,%1,0,%m2,%M2
1632 {andil.|andi.} %0,%1,%b2
1633 {andiu.|andis.} %0,%1,%u2")
1fd4e8c1
RK
1634
1635(define_insn ""
1636 [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,x,x")
cd2b37d9 1637 (compare:CC (and:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r")
1fd4e8c1
RK
1638 (match_operand:SI 2 "and_operand" "r,K,J,L"))
1639 (const_int 0)))
1640 (clobber (match_scratch:SI 3 "=r,r,r,r"))]
1641 ""
1642 "@
1643 and. %3,%1,%2
ca7f5001
RK
1644 {andil.|andi.} %3,%1,%b2
1645 {andiu.|andis.} %3,%1,%u2
1646 {rlinm.|rlwinm.} %3,%1,0,%m2,%M2"
1fd4e8c1
RK
1647 [(set_attr "type" "compare,compare,compare,delayed_compare")])
1648
1649(define_insn ""
1650 [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,x,x")
cd2b37d9 1651 (compare:CC (and:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r")
1fd4e8c1
RK
1652 (match_operand:SI 2 "and_operand" "r,K,J,L"))
1653 (const_int 0)))
cd2b37d9 1654 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r")
1fd4e8c1
RK
1655 (and:SI (match_dup 1) (match_dup 2)))]
1656 ""
1657 "@
1658 and. %0,%1,%2
ca7f5001
RK
1659 {andil.|andi.} %0,%1,%b2
1660 {andiu.|andis.} %0,%1,%u2
1661 {rlinm.|rlwinm.} %0,%1,0,%m2,%M2"
b19003d8 1662 [(set_attr "type" "compare,compare,compare,delayed_compare")])
1fd4e8c1 1663
f357808b
RK
1664;; Take a AND with a constant that cannot be done in a single insn and try to
1665;; split it into two insns. This does not verify that the insns are valid
1666;; since this need not be done as combine will do it.
1667
1668(define_split
cd2b37d9
RK
1669 [(set (match_operand:SI 0 "gpc_reg_operand" "")
1670 (and:SI (match_operand:SI 1 "gpc_reg_operand" "")
f357808b
RK
1671 (match_operand:SI 2 "non_and_cint_operand" "")))]
1672 ""
1673 [(set (match_dup 0) (and:SI (match_dup 1) (match_dup 3)))
1674 (set (match_dup 0) (and:SI (match_dup 0) (match_dup 4)))]
1675 "
1676{
1677 int maskval = INTVAL (operands[2]);
1678 int i, transitions, last_bit_value;
1679 int orig = maskval, first_c = maskval, second_c;
1680
1681 /* We know that MASKVAL must have more than 2 bit-transitions. Start at
1682 the low-order bit and count for the third transition. When we get there,
1683 make a first mask that has everything to the left of that position
1684 a one. Then make the second mask to turn off whatever else is needed. */
1685
1686 for (i = 1, transitions = 0, last_bit_value = maskval & 1; i < 32; i++)
1687 {
1688 if (((maskval >>= 1) & 1) != last_bit_value)
1689 last_bit_value ^= 1, transitions++;
1690
1691 if (transitions > 2)
1692 {
1693 first_c |= (~0) << i;
1694 break;
1695 }
1696 }
1697
1698 second_c = orig | ~ first_c;
1699
1700 operands[3] = gen_rtx (CONST_INT, VOIDmode, first_c);
1701 operands[4] = gen_rtx (CONST_INT, VOIDmode, second_c);
1702}")
1703
1704(define_insn "iorsi3"
cd2b37d9
RK
1705 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r")
1706 (ior:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r")
1fd4e8c1
RK
1707 (match_operand:SI 2 "logical_operand" "r,K,J")))]
1708 ""
1709 "@
1710 or %0,%1,%2
ca7f5001
RK
1711 {oril|ori} %0,%1,%b2
1712 {oriu|oris} %0,%1,%u2")
1fd4e8c1
RK
1713
1714(define_insn ""
1715 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
deb9225a 1716 (compare:CC (ior:SI (match_operand:SI 1 "gpc_reg_operand" "%r")
cd2b37d9 1717 (match_operand:SI 2 "gpc_reg_operand" "r"))
1fd4e8c1
RK
1718 (const_int 0)))
1719 (clobber (match_scratch:SI 3 "=r"))]
1720 ""
1721 "or. %3,%1,%2"
1722 [(set_attr "type" "compare")])
1723
1724(define_insn ""
1725 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
deb9225a 1726 (compare:CC (ior:SI (match_operand:SI 1 "gpc_reg_operand" "%r")
cd2b37d9 1727 (match_operand:SI 2 "gpc_reg_operand" "r"))
1fd4e8c1 1728 (const_int 0)))
cd2b37d9 1729 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
1730 (ior:SI (match_dup 1) (match_dup 2)))]
1731 ""
1732 "or. %0,%1,%2"
1733 [(set_attr "type" "compare")])
1734
f357808b
RK
1735;; Split an IOR that we can't do in one insn into two insns, each of which
1736;; does one 16-bit part. This is used by combine.
1737
1738(define_split
cd2b37d9
RK
1739 [(set (match_operand:SI 0 "gpc_reg_operand" "")
1740 (ior:SI (match_operand:SI 1 "gpc_reg_operand" "")
f357808b 1741 (match_operand:SI 2 "non_logical_cint_operand" "")))]
1fd4e8c1 1742 ""
f357808b
RK
1743 [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 3)))
1744 (set (match_dup 0) (ior:SI (match_dup 0) (match_dup 4)))]
1745"
1fd4e8c1 1746{
f357808b
RK
1747 operands[3] = gen_rtx (CONST_INT, VOIDmode,
1748 INTVAL (operands[2]) & 0xffff0000);
1749 operands[4] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) & 0xffff);
1fd4e8c1
RK
1750}")
1751
f357808b 1752(define_insn "xorsi3"
cd2b37d9
RK
1753 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r")
1754 (xor:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r")
1fd4e8c1
RK
1755 (match_operand:SI 2 "logical_operand" "r,K,J")))]
1756 ""
1757 "@
1758 xor %0,%1,%2
ca7f5001
RK
1759 {xoril|xori} %0,%1,%b2
1760 {xoriu|xoris} %0,%1,%u2")
1fd4e8c1
RK
1761
1762(define_insn ""
1763 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
deb9225a 1764 (compare:CC (xor:SI (match_operand:SI 1 "gpc_reg_operand" "%r")
cd2b37d9 1765 (match_operand:SI 2 "gpc_reg_operand" "r"))
1fd4e8c1
RK
1766 (const_int 0)))
1767 (clobber (match_scratch:SI 3 "=r"))]
1768 ""
1769 "xor. %3,%1,%2"
1770 [(set_attr "type" "compare")])
1771
1772(define_insn ""
1773 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
deb9225a 1774 (compare:CC (xor:SI (match_operand:SI 1 "gpc_reg_operand" "%r")
cd2b37d9 1775 (match_operand:SI 2 "gpc_reg_operand" "r"))
1fd4e8c1 1776 (const_int 0)))
cd2b37d9 1777 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
1778 (xor:SI (match_dup 1) (match_dup 2)))]
1779 ""
1780 "xor. %0,%1,%2"
1781 [(set_attr "type" "compare")])
1782
f357808b
RK
1783;; Split an XOR that we can't do in one insn into two insns, each of which
1784;; does one 16-bit part. This is used by combine.
1785
1786(define_split
cd2b37d9
RK
1787 [(set (match_operand:SI 0 "gpc_reg_operand" "")
1788 (xor:SI (match_operand:SI 1 "gpc_reg_operand" "")
f357808b 1789 (match_operand:SI 2 "non_logical_cint_operand" "")))]
1fd4e8c1 1790 ""
f357808b
RK
1791 [(set (match_dup 0) (xor:SI (match_dup 1) (match_dup 3)))
1792 (set (match_dup 0) (xor:SI (match_dup 0) (match_dup 4)))]
1793"
1fd4e8c1 1794{
f357808b
RK
1795 operands[3] = gen_rtx (CONST_INT, VOIDmode,
1796 INTVAL (operands[2]) & 0xffff0000);
1797 operands[4] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) & 0xffff);
1fd4e8c1
RK
1798}")
1799
1800(define_insn ""
cd2b37d9
RK
1801 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1802 (not:SI (xor:SI (match_operand:SI 1 "gpc_reg_operand" "%r")
1803 (match_operand:SI 2 "gpc_reg_operand" "r"))))]
1fd4e8c1
RK
1804 ""
1805 "eqv %0,%1,%2")
1806
1807(define_insn ""
1808 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
cd2b37d9
RK
1809 (compare:CC (not:SI (xor:SI (match_operand:SI 1 "gpc_reg_operand" "%r")
1810 (match_operand:SI 2 "gpc_reg_operand" "r")))
1fd4e8c1
RK
1811 (const_int 0)))
1812 (clobber (match_scratch:SI 3 "=r"))]
1813 ""
1814 "eqv. %3,%1,%2"
1815 [(set_attr "type" "compare")])
1816
1817(define_insn ""
1818 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
cd2b37d9
RK
1819 (compare:CC (not:SI (xor:SI (match_operand:SI 1 "gpc_reg_operand" "%r")
1820 (match_operand:SI 2 "gpc_reg_operand" "r")))
1fd4e8c1 1821 (const_int 0)))
cd2b37d9 1822 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
1823 (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
1824 ""
1825 "eqv. %0,%1,%2"
1826 [(set_attr "type" "compare")])
1827
1828(define_insn ""
cd2b37d9
RK
1829 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1830 (and:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "r"))
1831 (match_operand:SI 2 "gpc_reg_operand" "r")))]
1fd4e8c1
RK
1832 ""
1833 "andc %0,%2,%1")
1834
1835(define_insn ""
1836 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
cd2b37d9
RK
1837 (compare:CC (and:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "r"))
1838 (match_operand:SI 2 "gpc_reg_operand" "r"))
1fd4e8c1
RK
1839 (const_int 0)))
1840 (clobber (match_scratch:SI 3 "=r"))]
1841 ""
1842 "andc. %3,%2,%1"
1843 [(set_attr "type" "compare")])
1844
1845(define_insn ""
1846 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
cd2b37d9
RK
1847 (compare:CC (and:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "r"))
1848 (match_operand:SI 2 "gpc_reg_operand" "r"))
1fd4e8c1 1849 (const_int 0)))
cd2b37d9 1850 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
1851 (and:SI (not:SI (match_dup 1)) (match_dup 2)))]
1852 ""
1853 "andc. %0,%2,%1"
1854 [(set_attr "type" "compare")])
1855
1856(define_insn ""
cd2b37d9
RK
1857 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1858 (ior:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "r"))
1859 (match_operand:SI 2 "gpc_reg_operand" "r")))]
1fd4e8c1
RK
1860 ""
1861 "orc %0,%2,%1")
1862
1863(define_insn ""
1864 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
cd2b37d9
RK
1865 (compare:CC (ior:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "r"))
1866 (match_operand:SI 2 "gpc_reg_operand" "r"))
1fd4e8c1
RK
1867 (const_int 0)))
1868 (clobber (match_scratch:SI 3 "=r"))]
1869 ""
1870 "orc. %3,%2,%1"
1871 [(set_attr "type" "compare")])
1872
1873(define_insn ""
1874 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
cd2b37d9
RK
1875 (compare:CC (ior:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "r"))
1876 (match_operand:SI 2 "gpc_reg_operand" "r"))
1fd4e8c1 1877 (const_int 0)))
cd2b37d9 1878 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
1879 (ior:SI (not:SI (match_dup 1)) (match_dup 2)))]
1880 ""
1881 "orc. %0,%2,%1"
1882 [(set_attr "type" "compare")])
1883
1884(define_insn ""
cd2b37d9 1885 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
deb9225a 1886 (ior:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "%r"))
cd2b37d9 1887 (not:SI (match_operand:SI 2 "gpc_reg_operand" "r"))))]
1fd4e8c1
RK
1888 ""
1889 "nand %0,%1,%2")
1890
1891(define_insn ""
1892 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
deb9225a 1893 (compare:CC (ior:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "%r"))
cd2b37d9 1894 (not:SI (match_operand:SI 2 "gpc_reg_operand" "r")))
1fd4e8c1
RK
1895 (const_int 0)))
1896 (clobber (match_scratch:SI 3 "=r"))]
1897 ""
1898 "nand. %3,%1,%2"
1899 [(set_attr "type" "compare")])
1900
1901(define_insn ""
1902 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
deb9225a 1903 (compare:CC (ior:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "%r"))
cd2b37d9 1904 (not:SI (match_operand:SI 2 "gpc_reg_operand" "r")))
1fd4e8c1 1905 (const_int 0)))
cd2b37d9 1906 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
1907 (ior:SI (not:SI (match_dup 1)) (not:SI (match_dup 2))))]
1908 ""
1909 "nand. %0,%1,%2"
1910 [(set_attr "type" "compare")])
1911
1912(define_insn ""
cd2b37d9 1913 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
deb9225a 1914 (and:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "%r"))
cd2b37d9 1915 (not:SI (match_operand:SI 2 "gpc_reg_operand" "r"))))]
1fd4e8c1
RK
1916 ""
1917 "nor %0,%1,%2")
1918
1919(define_insn ""
1920 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
deb9225a 1921 (compare:CC (and:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "%r"))
cd2b37d9 1922 (not:SI (match_operand:SI 2 "gpc_reg_operand" "r")))
1fd4e8c1
RK
1923 (const_int 0)))
1924 (clobber (match_scratch:SI 3 "=r"))]
1925 ""
1926 "nor. %3,%1,%2"
1927 [(set_attr "type" "compare")])
1928
1929(define_insn ""
1930 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
deb9225a 1931 (compare:CC (and:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "%r"))
cd2b37d9 1932 (not:SI (match_operand:SI 2 "gpc_reg_operand" "r")))
1fd4e8c1 1933 (const_int 0)))
cd2b37d9 1934 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
1935 (and:SI (not:SI (match_dup 1)) (not:SI (match_dup 2))))]
1936 ""
1937 "nor. %0,%1,%2"
1938 [(set_attr "type" "compare")])
1939
1940;; maskir insn. We need four forms because things might be in arbitrary
1941;; orders. Don't define forms that only set CR fields because these
1942;; would modify an input register.
1943
1944(define_insn ""
cd2b37d9 1945 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
01def764
RK
1946 (ior:SI (and:SI (not:SI (match_operand:SI 2 "gpc_reg_operand" "r"))
1947 (match_operand:SI 1 "gpc_reg_operand" "0"))
1948 (and:SI (match_dup 2)
cd2b37d9 1949 (match_operand:SI 3 "gpc_reg_operand" "r"))))]
ca7f5001 1950 "TARGET_POWER"
01def764 1951 "maskir %0,%3,%2")
1fd4e8c1
RK
1952
1953(define_insn ""
242e8072 1954 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
01def764
RK
1955 (ior:SI (and:SI (not:SI (match_operand:SI 2 "gpc_reg_operand" "r"))
1956 (match_operand:SI 1 "gpc_reg_operand" "0"))
cd2b37d9 1957 (and:SI (match_operand:SI 3 "gpc_reg_operand" "r")
01def764 1958 (match_dup 2))))]
ca7f5001 1959 "TARGET_POWER"
01def764 1960 "maskir %0,%3,%2")
1fd4e8c1
RK
1961
1962(define_insn ""
cd2b37d9 1963 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
01def764 1964 (ior:SI (and:SI (match_operand:SI 2 "gpc_reg_operand" "r")
cd2b37d9 1965 (match_operand:SI 3 "gpc_reg_operand" "r"))
01def764
RK
1966 (and:SI (not:SI (match_dup 2))
1967 (match_operand:SI 1 "gpc_reg_operand" "0"))))]
ca7f5001 1968 "TARGET_POWER"
01def764 1969 "maskir %0,%3,%2")
1fd4e8c1
RK
1970
1971(define_insn ""
cd2b37d9
RK
1972 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1973 (ior:SI (and:SI (match_operand:SI 3 "gpc_reg_operand" "r")
01def764
RK
1974 (match_operand:SI 2 "gpc_reg_operand" "r"))
1975 (and:SI (not:SI (match_dup 2))
1976 (match_operand:SI 1 "gpc_reg_operand" "0"))))]
ca7f5001 1977 "TARGET_POWER"
01def764 1978 "maskir %0,%3,%2")
1fd4e8c1
RK
1979
1980(define_insn ""
1981 [(set (match_operand:CC 4 "cc_reg_operand" "=x")
1982 (compare:CC
01def764
RK
1983 (ior:SI (and:SI (not:SI (match_operand:SI 2 "gpc_reg_operand" "r"))
1984 (match_operand:SI 1 "gpc_reg_operand" "0"))
1985 (and:SI (match_dup 2)
cd2b37d9 1986 (match_operand:SI 3 "gpc_reg_operand" "r")))
1fd4e8c1 1987 (const_int 0)))
cd2b37d9 1988 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
01def764
RK
1989 (ior:SI (and:SI (not:SI (match_dup 2)) (match_dup 1))
1990 (and:SI (match_dup 2) (match_dup 3))))]
ca7f5001 1991 "TARGET_POWER"
01def764 1992 "maskir. %0,%3,%2"
1fd4e8c1
RK
1993 [(set_attr "type" "compare")])
1994
1995(define_insn ""
1996 [(set (match_operand:CC 4 "cc_reg_operand" "=x")
1997 (compare:CC
01def764
RK
1998 (ior:SI (and:SI (not:SI (match_operand:SI 2 "gpc_reg_operand" "r"))
1999 (match_operand:SI 1 "gpc_reg_operand" "0"))
cd2b37d9 2000 (and:SI (match_operand:SI 3 "gpc_reg_operand" "r")
01def764 2001 (match_dup 2)))
1fd4e8c1 2002 (const_int 0)))
242e8072 2003 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
01def764
RK
2004 (ior:SI (and:SI (not:SI (match_dup 2)) (match_dup 1))
2005 (and:SI (match_dup 3) (match_dup 2))))]
ca7f5001 2006 "TARGET_POWER"
01def764 2007 "maskir. %0,%3,%2"
1fd4e8c1
RK
2008 [(set_attr "type" "compare")])
2009
2010(define_insn ""
2011 [(set (match_operand:CC 4 "cc_reg_operand" "=x")
2012 (compare:CC
01def764 2013 (ior:SI (and:SI (match_operand:SI 2 "gpc_reg_operand" "r")
cd2b37d9 2014 (match_operand:SI 3 "gpc_reg_operand" "r"))
01def764
RK
2015 (and:SI (not:SI (match_dup 2))
2016 (match_operand:SI 1 "gpc_reg_operand" "0")))
1fd4e8c1 2017 (const_int 0)))
cd2b37d9 2018 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
01def764
RK
2019 (ior:SI (and:SI (match_dup 2) (match_dup 3))
2020 (and:SI (not:SI (match_dup 2)) (match_dup 1))))]
ca7f5001 2021 "TARGET_POWER"
01def764 2022 "maskir. %0,%3,%2"
1fd4e8c1
RK
2023 [(set_attr "type" "compare")])
2024
2025(define_insn ""
2026 [(set (match_operand:CC 4 "cc_reg_operand" "=x")
2027 (compare:CC
cd2b37d9 2028 (ior:SI (and:SI (match_operand:SI 3 "gpc_reg_operand" "r")
01def764
RK
2029 (match_operand:SI 2 "gpc_reg_operand" "r"))
2030 (and:SI (not:SI (match_dup 2))
2031 (match_operand:SI 1 "gpc_reg_operand" "0")))
1fd4e8c1 2032 (const_int 0)))
cd2b37d9 2033 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
01def764
RK
2034 (ior:SI (and:SI (match_dup 3) (match_dup 2))
2035 (and:SI (not:SI (match_dup 2)) (match_dup 1))))]
ca7f5001 2036 "TARGET_POWER"
01def764 2037 "maskir. %0,%3,%2"
1fd4e8c1
RK
2038 [(set_attr "type" "compare")])
2039\f
2040;; Rotate and shift insns, in all their variants. These support shifts,
2041;; field inserts and extracts, and various combinations thereof.
034c1be0
MM
2042(define_expand "insv"
2043 [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r")
2044 (match_operand:SI 1 "const_int_operand" "i")
2045 (match_operand:SI 2 "const_int_operand" "i"))
2046 (match_operand:SI 3 "gpc_reg_operand" "r"))]
2047 ""
2048 "
2049{
2050 /* Do not handle 16/8 bit structures that fit in HI/QI modes directly, since
2051 the (SUBREG:SI (REG:HI xxx)) that is otherwise generated can confuse the
2052 compiler if the address of the structure is taken later. */
2053 if (GET_CODE (operands[0]) == SUBREG
2054 && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (operands[0]))) < UNITS_PER_WORD))
2055 FAIL;
2056}")
2057
2058(define_insn ""
cd2b37d9 2059 [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r")
1fd4e8c1
RK
2060 (match_operand:SI 1 "const_int_operand" "i")
2061 (match_operand:SI 2 "const_int_operand" "i"))
cd2b37d9 2062 (match_operand:SI 3 "gpc_reg_operand" "r"))]
1fd4e8c1
RK
2063 ""
2064 "*
2065{
2066 int start = INTVAL (operands[2]) & 31;
2067 int size = INTVAL (operands[1]) & 31;
2068
2069 operands[4] = gen_rtx (CONST_INT, VOIDmode, 32 - start - size);
2070 operands[1] = gen_rtx (CONST_INT, VOIDmode, start + size - 1);
ca7f5001 2071 return \"{rlimi|rlwimi} %0,%3,%4,%h2,%h1\";
1fd4e8c1
RK
2072}")
2073
d56d506a
RK
2074(define_insn ""
2075 [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r")
2076 (match_operand:SI 1 "const_int_operand" "i")
2077 (match_operand:SI 2 "const_int_operand" "i"))
2078 (ashift:SI (match_operand:SI 3 "gpc_reg_operand" "r")
2079 (match_operand:SI 4 "const_int_operand" "i")))]
2080 ""
2081 "*
2082{
2083 int shift = INTVAL (operands[4]) & 31;
2084 int start = INTVAL (operands[2]) & 31;
2085 int size = INTVAL (operands[1]) & 31;
2086
2087 operands[4] = gen_rtx (CONST_INT, VOIDmode, (shift - start - size) & 31);
2088 operands[1] = gen_rtx (CONST_INT, VOIDmode, start + size - 1);
2089 return \"{rlimi|rlwimi} %0,%3,%4,%h2,%h1\";
2090}")
2091
2092(define_insn ""
2093 [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r")
2094 (match_operand:SI 1 "const_int_operand" "i")
2095 (match_operand:SI 2 "const_int_operand" "i"))
2096 (ashiftrt:SI (match_operand:SI 3 "gpc_reg_operand" "r")
2097 (match_operand:SI 4 "const_int_operand" "i")))]
2098 ""
2099 "*
2100{
2101 int shift = INTVAL (operands[4]) & 31;
2102 int start = INTVAL (operands[2]) & 31;
2103 int size = INTVAL (operands[1]) & 31;
2104
2105 operands[4] = gen_rtx (CONST_INT, VOIDmode, (32 - shift - start - size) & 31);
2106 operands[1] = gen_rtx (CONST_INT, VOIDmode, start + size - 1);
2107 return \"{rlimi|rlwimi} %0,%3,%4,%h2,%h1\";
2108}")
2109
2110(define_insn ""
2111 [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r")
2112 (match_operand:SI 1 "const_int_operand" "i")
2113 (match_operand:SI 2 "const_int_operand" "i"))
2114 (lshiftrt:SI (match_operand:SI 3 "gpc_reg_operand" "r")
2115 (match_operand:SI 4 "const_int_operand" "i")))]
2116 ""
2117 "*
2118{
2119 int shift = INTVAL (operands[4]) & 31;
2120 int start = INTVAL (operands[2]) & 31;
2121 int size = INTVAL (operands[1]) & 31;
2122
2123 operands[4] = gen_rtx (CONST_INT, VOIDmode, (32 - shift - start - size) & 31);
2124 operands[1] = gen_rtx (CONST_INT, VOIDmode, start + size - 1);
2125 return \"{rlimi|rlwimi} %0,%3,%4,%h2,%h1\";
2126}")
2127
2128(define_insn ""
2129 [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r")
2130 (match_operand:SI 1 "const_int_operand" "i")
2131 (match_operand:SI 2 "const_int_operand" "i"))
2132 (zero_extract:SI (match_operand:SI 3 "gpc_reg_operand" "r")
2133 (match_operand:SI 4 "const_int_operand" "i")
2134 (match_operand:SI 5 "const_int_operand" "i")))]
2135 "INTVAL (operands[4]) >= INTVAL (operands[1])"
2136 "*
2137{
2138 int extract_start = INTVAL (operands[5]) & 31;
2139 int extract_size = INTVAL (operands[4]) & 31;
2140 int insert_start = INTVAL (operands[2]) & 31;
2141 int insert_size = INTVAL (operands[1]) & 31;
2142
2143/* Align extract field with insert field */
2144 operands[5] = gen_rtx (CONST_INT, VOIDmode,
2145 (extract_start + extract_size - insert_start - insert_size) & 31);
2146 operands[1] = gen_rtx (CONST_INT, VOIDmode, insert_start + insert_size - 1);
2147 return \"{rlimi|rlwimi} %0,%3,%5,%h2,%h1\";
2148}")
2149
034c1be0
MM
2150(define_expand "extzv"
2151 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2152 (zero_extract:SI (match_operand:SI 1 "gpc_reg_operand" "r")
2153 (match_operand:SI 2 "const_int_operand" "i")
2154 (match_operand:SI 3 "const_int_operand" "i")))]
2155 ""
2156 "
2157{
2158 /* Do not handle 16/8 bit structures that fit in HI/QI modes directly, since
2159 the (SUBREG:SI (REG:HI xxx)) that is otherwise generated can confuse the
2160 compiler if the address of the structure is taken later. */
2161 if (GET_CODE (operands[0]) == SUBREG
2162 && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (operands[0]))) < UNITS_PER_WORD))
2163 FAIL;
2164}")
2165
2166(define_insn ""
cd2b37d9
RK
2167 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2168 (zero_extract:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
2169 (match_operand:SI 2 "const_int_operand" "i")
2170 (match_operand:SI 3 "const_int_operand" "i")))]
2171 ""
2172 "*
2173{
2174 int start = INTVAL (operands[3]) & 31;
2175 int size = INTVAL (operands[2]) & 31;
2176
2177 if (start + size >= 32)
2178 operands[3] = const0_rtx;
2179 else
2180 operands[3] = gen_rtx (CONST_INT, VOIDmode, start + size);
ca7f5001 2181 return \"{rlinm|rlwinm} %0,%1,%3,%s2,31\";
1fd4e8c1
RK
2182}")
2183
2184(define_insn ""
2185 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
cd2b37d9 2186 (compare:CC (zero_extract:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
2187 (match_operand:SI 2 "const_int_operand" "i")
2188 (match_operand:SI 3 "const_int_operand" "i"))
2189 (const_int 0)))
2190 (clobber (match_scratch:SI 4 "=r"))]
2191 ""
2192 "*
2193{
2194 int start = INTVAL (operands[3]) & 31;
2195 int size = INTVAL (operands[2]) & 31;
2196
a7a975e1
RK
2197 /* If the bitfield being tested fits in the upper or lower half of a
2198 word, it is possible to use andiu. or andil. to test it. This is
2199 useful because the condition register set-use delay is smaller for
2200 andi[ul]. than for rlinm. This doesn't work when the starting bit
2201 position is 0 because the LT and GT bits may be set wrong. */
2202
2203 if ((start > 0 && start + size <= 16) || start >= 16)
df031c43
RK
2204 {
2205 operands[3] = gen_rtx (CONST_INT, VOIDmode,
2206 ((1 << (16 - (start & 15)))
2207 - (1 << (16 - (start & 15) - size))));
2208 if (start < 16)
ca7f5001 2209 return \"{andiu.|andis.} %4,%1,%3\";
df031c43 2210 else
ca7f5001 2211 return \"{andil.|andi.} %4,%1,%3\";
df031c43 2212 }
7e69e155 2213
1fd4e8c1
RK
2214 if (start + size >= 32)
2215 operands[3] = const0_rtx;
2216 else
2217 operands[3] = gen_rtx (CONST_INT, VOIDmode, start + size);
ca7f5001 2218 return \"{rlinm.|rlwinm.} %4,%1,%3,%s2,31\";
1fd4e8c1
RK
2219}"
2220 [(set_attr "type" "compare")])
2221
2222(define_insn ""
2223 [(set (match_operand:CC 4 "cc_reg_operand" "=x")
cd2b37d9 2224 (compare:CC (zero_extract:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
2225 (match_operand:SI 2 "const_int_operand" "i")
2226 (match_operand:SI 3 "const_int_operand" "i"))
2227 (const_int 0)))
cd2b37d9 2228 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
2229 (zero_extract:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
2230 ""
2231 "*
2232{
2233 int start = INTVAL (operands[3]) & 31;
2234 int size = INTVAL (operands[2]) & 31;
2235
a7a975e1 2236 if (start >= 16 && start + size == 32)
df031c43 2237 {
a7a975e1 2238 operands[3] = gen_rtx (CONST_INT, VOIDmode, (1 << (32 - start)) - 1);
ca7f5001 2239 return \"{andil.|andi.} %0,%1,%3\";
df031c43 2240 }
7e69e155 2241
1fd4e8c1
RK
2242 if (start + size >= 32)
2243 operands[3] = const0_rtx;
2244 else
2245 operands[3] = gen_rtx (CONST_INT, VOIDmode, start + size);
ca7f5001 2246 return \"{rlinm.|rlwinm.} %0,%1,%3,%s2,31\";
1fd4e8c1
RK
2247}"
2248 [(set_attr "type" "delayed_compare")])
2249
2250(define_insn "rotlsi3"
cd2b37d9
RK
2251 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2252 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
2253 (match_operand:SI 2 "reg_or_cint_operand" "ri")))]
2254 ""
ca7f5001 2255 "{rl%I2nm|rlw%I2nm} %0,%1,%h2,0xffffffff")
1fd4e8c1
RK
2256
2257(define_insn ""
2258 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
cd2b37d9 2259 (compare:CC (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
2260 (match_operand:SI 2 "reg_or_cint_operand" "ri"))
2261 (const_int 0)))
2262 (clobber (match_scratch:SI 3 "=r"))]
2263 ""
ca7f5001 2264 "{rl%I2nm.|rlw%I2nm.} %3,%1,%h2,0xffffffff"
1fd4e8c1
RK
2265 [(set_attr "type" "delayed_compare")])
2266
2267(define_insn ""
2268 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
cd2b37d9 2269 (compare:CC (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
2270 (match_operand:SI 2 "reg_or_cint_operand" "ri"))
2271 (const_int 0)))
cd2b37d9 2272 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
2273 (rotate:SI (match_dup 1) (match_dup 2)))]
2274 ""
ca7f5001 2275 "{rl%I2nm.|rlw%I2nm.} %0,%1,%h2,0xffffffff"
1fd4e8c1
RK
2276 [(set_attr "type" "delayed_compare")])
2277
2278(define_insn ""
cd2b37d9
RK
2279 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2280 (and:SI (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
2281 (match_operand:SI 2 "reg_or_cint_operand" "ri"))
2282 (match_operand:SI 3 "mask_operand" "L")))]
2283 ""
ca7f5001 2284 "{rl%I2nm|rlw%I2nm} %0,%1,%h2,%m3,%M3")
1fd4e8c1
RK
2285
2286(define_insn ""
2287 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
2288 (compare:CC (and:SI
cd2b37d9 2289 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
2290 (match_operand:SI 2 "reg_or_cint_operand" "ri"))
2291 (match_operand:SI 3 "mask_operand" "L"))
2292 (const_int 0)))
2293 (clobber (match_scratch:SI 4 "=r"))]
2294 ""
ca7f5001 2295 "{rl%I2nm.|rlw%I2nm.} %4,%1,%h2,%m3,%M3"
1fd4e8c1
RK
2296 [(set_attr "type" "delayed_compare")])
2297
2298(define_insn ""
2299 [(set (match_operand:CC 4 "cc_reg_operand" "=x")
2300 (compare:CC (and:SI
cd2b37d9 2301 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
2302 (match_operand:SI 2 "reg_or_cint_operand" "ri"))
2303 (match_operand:SI 3 "mask_operand" "L"))
2304 (const_int 0)))
cd2b37d9 2305 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
2306 (and:SI (rotate:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
2307 ""
ca7f5001 2308 "{rl%I2nm.|rlw%I2nm.} %0,%1,%h2,%m3,%M3"
1fd4e8c1
RK
2309 [(set_attr "type" "delayed_compare")])
2310
2311(define_insn ""
cd2b37d9 2312 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
2313 (zero_extend:SI
2314 (subreg:QI
cd2b37d9 2315 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
2316 (match_operand:SI 2 "reg_or_cint_operand" "ri")) 0)))]
2317 ""
ca7f5001 2318 "{rl%I2nm|rlw%I2nm} %0,%1,%h2,0xff")
1fd4e8c1
RK
2319
2320(define_insn ""
2321 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
2322 (compare:CC (zero_extend:SI
2323 (subreg:QI
cd2b37d9 2324 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
2325 (match_operand:SI 2 "reg_or_cint_operand" "ri")) 0))
2326 (const_int 0)))
2327 (clobber (match_scratch:SI 3 "=r"))]
2328 ""
ca7f5001 2329 "{rl%I2nm.|rlw%I2nm.} %3,%1,%h2,0xff"
1fd4e8c1
RK
2330 [(set_attr "type" "delayed_compare")])
2331
2332(define_insn ""
2333 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
2334 (compare:CC (zero_extend:SI
2335 (subreg:QI
cd2b37d9 2336 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
2337 (match_operand:SI 2 "reg_or_cint_operand" "ri")) 0))
2338 (const_int 0)))
cd2b37d9 2339 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
2340 (zero_extend:SI (subreg:QI (rotate:SI (match_dup 1) (match_dup 2)) 0)))]
2341 ""
ca7f5001 2342 "{rl%I2nm.|rlw%I2nm.} %0,%1,%h2,0xff"
1fd4e8c1
RK
2343 [(set_attr "type" "delayed_compare")])
2344
2345(define_insn ""
cd2b37d9 2346 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
2347 (zero_extend:SI
2348 (subreg:HI
cd2b37d9 2349 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
2350 (match_operand:SI 2 "reg_or_cint_operand" "ri")) 0)))]
2351 ""
ca7f5001 2352 "{rl%I2nm|rlw%I2nm} %0,%1,%h2,0xffff")
1fd4e8c1
RK
2353
2354(define_insn ""
2355 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
2356 (compare:CC (zero_extend:SI
2357 (subreg:HI
cd2b37d9 2358 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
2359 (match_operand:SI 2 "reg_or_cint_operand" "ri")) 0))
2360 (const_int 0)))
2361 (clobber (match_scratch:SI 3 "=r"))]
2362 ""
ca7f5001 2363 "{rl%I2nm.|rlw%I2nm.} %3,%1,%h2,0xffff"
1fd4e8c1
RK
2364 [(set_attr "type" "delayed_compare")])
2365
2366(define_insn ""
2367 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
2368 (compare:CC (zero_extend:SI
2369 (subreg:HI
cd2b37d9 2370 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
2371 (match_operand:SI 2 "reg_or_cint_operand" "ri")) 0))
2372 (const_int 0)))
cd2b37d9 2373 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
2374 (zero_extend:SI (subreg:HI (rotate:SI (match_dup 1) (match_dup 2)) 0)))]
2375 ""
ca7f5001 2376 "{rl%I2nm.|rlw%I2nm.} %0,%1,%h2,0xffff"
1fd4e8c1
RK
2377 [(set_attr "type" "delayed_compare")])
2378
2379;; Note that we use "sle." instead of "sl." so that we can set
2380;; SHIFT_COUNT_TRUNCATED.
2381
ca7f5001
RK
2382(define_expand "ashlsi3"
2383 [(use (match_operand:SI 0 "gpc_reg_operand" ""))
2384 (use (match_operand:SI 1 "gpc_reg_operand" ""))
2385 (use (match_operand:SI 2 "reg_or_cint_operand" ""))]
2386 ""
2387 "
2388{
2389 if (TARGET_POWER)
2390 emit_insn (gen_ashlsi3_power (operands[0], operands[1], operands[2]));
2391 else
25c341fa 2392 emit_insn (gen_ashlsi3_no_power (operands[0], operands[1], operands[2]));
ca7f5001
RK
2393 DONE;
2394}")
2395
2396(define_insn "ashlsi3_power"
cd2b37d9
RK
2397 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
2398 (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1
RK
2399 (match_operand:SI 2 "reg_or_cint_operand" "r,i")))
2400 (clobber (match_scratch:SI 3 "=q,X"))]
ca7f5001 2401 "TARGET_POWER"
1fd4e8c1
RK
2402 "@
2403 sle %0,%1,%2
ca7f5001
RK
2404 {sli|slwi} %0,%1,%h2"
2405 [(set_attr "length" "8")])
2406
25c341fa 2407(define_insn "ashlsi3_no_power"
ca7f5001
RK
2408 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2409 (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r")
2410 (match_operand:SI 2 "reg_or_cint_operand" "ri")))]
25c341fa 2411 "! TARGET_POWER"
d904e9ed 2412 "{sl|slw}%I2 %0,%1,%h2"
b19003d8 2413 [(set_attr "length" "8")])
1fd4e8c1
RK
2414
2415(define_insn ""
2416 [(set (match_operand:CC 0 "cc_reg_operand" "=x,x")
cd2b37d9 2417 (compare:CC (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1
RK
2418 (match_operand:SI 2 "reg_or_cint_operand" "r,i"))
2419 (const_int 0)))
2420 (clobber (match_scratch:SI 3 "=r,r"))
2421 (clobber (match_scratch:SI 4 "=q,X"))]
ca7f5001 2422 "TARGET_POWER"
1fd4e8c1
RK
2423 "@
2424 sle. %3,%1,%2
ca7f5001
RK
2425 {sli.|slwi.} %3,%1,%h2"
2426 [(set_attr "type" "delayed_compare")])
25c341fa 2427
ca7f5001
RK
2428(define_insn ""
2429 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
2430 (compare:CC (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r")
2431 (match_operand:SI 2 "reg_or_cint_operand" "ri"))
2432 (const_int 0)))
2433 (clobber (match_scratch:SI 3 "=r"))]
8ffd9c51 2434 "! TARGET_POWER"
d904e9ed 2435 "{sl|slw}%I2. %3,%1,%h2"
1fd4e8c1
RK
2436 [(set_attr "type" "delayed_compare")])
2437
2438(define_insn ""
2439 [(set (match_operand:CC 3 "cc_reg_operand" "=x,x")
cd2b37d9 2440 (compare:CC (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1
RK
2441 (match_operand:SI 2 "reg_or_cint_operand" "r,i"))
2442 (const_int 0)))
cd2b37d9 2443 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
1fd4e8c1
RK
2444 (ashift:SI (match_dup 1) (match_dup 2)))
2445 (clobber (match_scratch:SI 4 "=q,X"))]
ca7f5001 2446 "TARGET_POWER"
1fd4e8c1
RK
2447 "@
2448 sle. %0,%1,%2
ca7f5001
RK
2449 {sli.|slwi.} %0,%1,%h2"
2450 [(set_attr "type" "delayed_compare")])
25c341fa 2451
ca7f5001
RK
2452(define_insn ""
2453 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
2454 (compare:CC (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r")
2455 (match_operand:SI 2 "reg_or_cint_operand" "ri"))
2456 (const_int 0)))
2457 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
2458 (ashift:SI (match_dup 1) (match_dup 2)))]
8ffd9c51 2459 "! TARGET_POWER"
d904e9ed 2460 "{sl|slw}%I2. %0,%1,%h2"
1fd4e8c1
RK
2461 [(set_attr "type" "delayed_compare")])
2462
2463(define_insn ""
cd2b37d9
RK
2464 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2465 (and:SI (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
2466 (match_operand:SI 2 "const_int_operand" "i"))
2467 (match_operand:SI 3 "mask_operand" "L")))]
2468 "includes_lshift_p (operands[2], operands[3])"
d56d506a 2469 "{rlinm|rlwinm} %0,%1,%h2,%m3,%M3")
1fd4e8c1
RK
2470
2471(define_insn ""
2472 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
2473 (compare:CC
cd2b37d9 2474 (and:SI (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
2475 (match_operand:SI 2 "const_int_operand" "i"))
2476 (match_operand:SI 3 "mask_operand" "L"))
2477 (const_int 0)))
2478 (clobber (match_scratch:SI 4 "=r"))]
2479 "includes_lshift_p (operands[2], operands[3])"
d56d506a 2480 "{rlinm.|rlwinm.} %4,%1,%h2,%m3,%M3"
1fd4e8c1
RK
2481 [(set_attr "type" "delayed_compare")])
2482
2483(define_insn ""
2484 [(set (match_operand:CC 4 "cc_reg_operand" "=x")
2485 (compare:CC
cd2b37d9 2486 (and:SI (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
2487 (match_operand:SI 2 "const_int_operand" "i"))
2488 (match_operand:SI 3 "mask_operand" "L"))
2489 (const_int 0)))
cd2b37d9 2490 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
2491 (and:SI (ashift:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
2492 "includes_lshift_p (operands[2], operands[3])"
d56d506a 2493 "{rlinm.|rlwinm.} %0,%1,%h2,%m3,%M3"
1fd4e8c1
RK
2494 [(set_attr "type" "delayed_compare")])
2495
ca7f5001 2496;; The AIX assembler mis-handles "sri x,x,0", so write that case as
5c23c401 2497;; "sli x,x,0".
ca7f5001
RK
2498(define_expand "lshrsi3"
2499 [(use (match_operand:SI 0 "gpc_reg_operand" ""))
2500 (use (match_operand:SI 1 "gpc_reg_operand" ""))
2501 (use (match_operand:SI 2 "reg_or_cint_operand" ""))]
2502 ""
2503 "
2504{
2505 if (TARGET_POWER)
2506 emit_insn (gen_lshrsi3_power (operands[0], operands[1], operands[2]));
2507 else
25c341fa 2508 emit_insn (gen_lshrsi3_no_power (operands[0], operands[1], operands[2]));
ca7f5001
RK
2509 DONE;
2510}")
2511
2512(define_insn "lshrsi3_power"
cd2b37d9
RK
2513 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
2514 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1
RK
2515 (match_operand:SI 2 "reg_or_cint_operand" "r,i")))
2516 (clobber (match_scratch:SI 3 "=q,X"))]
ca7f5001 2517 "TARGET_POWER"
1fd4e8c1
RK
2518 "@
2519 sre %0,%1,%2
ca7f5001
RK
2520 {s%A2i|s%A2wi} %0,%1,%h2")
2521
25c341fa 2522(define_insn "lshrsi3_no_power"
ca7f5001
RK
2523 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2524 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
2525 (match_operand:SI 2 "reg_or_cint_operand" "ri")))]
25c341fa 2526 "! TARGET_POWER"
d904e9ed 2527 "{sr|srw}%I2 %0,%1,%h2")
1fd4e8c1
RK
2528
2529(define_insn ""
2530 [(set (match_operand:CC 0 "cc_reg_operand" "=x,x")
cd2b37d9 2531 (compare:CC (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1
RK
2532 (match_operand:SI 2 "reg_or_cint_operand" "r,i"))
2533 (const_int 0)))
2534 (clobber (match_scratch:SI 3 "=r,r"))
2535 (clobber (match_scratch:SI 4 "=q,X"))]
ca7f5001 2536 "TARGET_POWER"
1fd4e8c1
RK
2537 "@
2538 sre. %3,%1,%2
ca7f5001
RK
2539 {s%A2i.|s%A2wi.} %3,%1,%h2"
2540 [(set_attr "type" "delayed_compare")])
2541
2542(define_insn ""
2543 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
2544 (compare:CC (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
2545 (match_operand:SI 2 "reg_or_cint_operand" "ri"))
2546 (const_int 0)))
2547 (clobber (match_scratch:SI 3 "=r"))]
25c341fa 2548 "! TARGET_POWER"
d904e9ed 2549 "{sr|srw}%I2. %3,%1,%h2"
1fd4e8c1
RK
2550 [(set_attr "type" "delayed_compare")])
2551
2552(define_insn ""
2553 [(set (match_operand:CC 3 "cc_reg_operand" "=x,x")
cd2b37d9 2554 (compare:CC (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1
RK
2555 (match_operand:SI 2 "reg_or_cint_operand" "r,i"))
2556 (const_int 0)))
cd2b37d9 2557 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
1fd4e8c1
RK
2558 (lshiftrt:SI (match_dup 1) (match_dup 2)))
2559 (clobber (match_scratch:SI 4 "=q,X"))]
ca7f5001 2560 "TARGET_POWER"
1fd4e8c1
RK
2561 "@
2562 sre. %0,%1,%2
ca7f5001
RK
2563 {s%A2i.|s%A2wi.} %0,%1,%h2"
2564 [(set_attr "type" "delayed_compare")])
2565
2566(define_insn ""
2567 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
2568 (compare:CC (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
2569 (match_operand:SI 2 "reg_or_cint_operand" "ri"))
2570 (const_int 0)))
2571 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
2572 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
25c341fa 2573 "! TARGET_POWER"
d904e9ed 2574 "{sr|srw}%I2. %0,%1,%h2"
1fd4e8c1
RK
2575 [(set_attr "type" "delayed_compare")])
2576
2577(define_insn ""
cd2b37d9
RK
2578 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2579 (and:SI (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
2580 (match_operand:SI 2 "const_int_operand" "i"))
2581 (match_operand:SI 3 "mask_operand" "L")))]
2582 "includes_rshift_p (operands[2], operands[3])"
ca7f5001 2583 "{rlinm|rlwinm} %0,%1,%s2,%m3,%M3")
1fd4e8c1
RK
2584
2585(define_insn ""
2586 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
2587 (compare:CC
cd2b37d9 2588 (and:SI (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
2589 (match_operand:SI 2 "const_int_operand" "i"))
2590 (match_operand:SI 3 "mask_operand" "L"))
2591 (const_int 0)))
2592 (clobber (match_scratch:SI 4 "=r"))]
2593 "includes_rshift_p (operands[2], operands[3])"
ca7f5001 2594 "{rlinm.|rlwinm.} %4,%1,%s2,%m3,%M3"
1fd4e8c1
RK
2595 [(set_attr "type" "delayed_compare")])
2596
2597(define_insn ""
2598 [(set (match_operand:CC 4 "cc_reg_operand" "=x")
2599 (compare:CC
cd2b37d9 2600 (and:SI (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
2601 (match_operand:SI 2 "const_int_operand" "i"))
2602 (match_operand:SI 3 "mask_operand" "L"))
2603 (const_int 0)))
cd2b37d9 2604 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
2605 (and:SI (lshiftrt:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
2606 "includes_rshift_p (operands[2], operands[3])"
ca7f5001 2607 "{rlinm.|rlwinm.} %0,%1,%s2,%m3,%M3"
1fd4e8c1
RK
2608 [(set_attr "type" "delayed_compare")])
2609
2610(define_insn ""
cd2b37d9 2611 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
2612 (zero_extend:SI
2613 (subreg:QI
cd2b37d9 2614 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
2615 (match_operand:SI 2 "const_int_operand" "i")) 0)))]
2616 "includes_rshift_p (operands[2], gen_rtx (CONST_INT, VOIDmode, 255))"
ca7f5001 2617 "{rlinm|rlwinm} %0,%1,%s2,0xff")
1fd4e8c1
RK
2618
2619(define_insn ""
2620 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
2621 (compare:CC
2622 (zero_extend:SI
2623 (subreg:QI
cd2b37d9 2624 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
2625 (match_operand:SI 2 "const_int_operand" "i")) 0))
2626 (const_int 0)))
2627 (clobber (match_scratch:SI 3 "=r"))]
2628 "includes_rshift_p (operands[2], gen_rtx (CONST_INT, VOIDmode, 255))"
ca7f5001 2629 "{rlinm.|rlwinm.} %3,%1,%s2,0xff"
1fd4e8c1
RK
2630 [(set_attr "type" "delayed_compare")])
2631
2632(define_insn ""
2633 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
2634 (compare:CC
2635 (zero_extend:SI
2636 (subreg:QI
cd2b37d9 2637 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
2638 (match_operand:SI 2 "const_int_operand" "i")) 0))
2639 (const_int 0)))
cd2b37d9 2640 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
2641 (zero_extend:SI (subreg:QI (lshiftrt:SI (match_dup 1) (match_dup 2)) 0)))]
2642 "includes_rshift_p (operands[2], gen_rtx (CONST_INT, VOIDmode, 255))"
ca7f5001 2643 "{rlinm.|rlwinm.} %0,%1,%s2,0xff"
1fd4e8c1
RK
2644 [(set_attr "type" "delayed_compare")])
2645
2646(define_insn ""
cd2b37d9 2647 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
2648 (zero_extend:SI
2649 (subreg:HI
cd2b37d9 2650 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
2651 (match_operand:SI 2 "const_int_operand" "i")) 0)))]
2652 "includes_rshift_p (operands[2], gen_rtx (CONST_INT, VOIDmode, 65535))"
ca7f5001 2653 "{rlinm|rlwinm} %0,%1,%s2,0xffff")
1fd4e8c1
RK
2654
2655(define_insn ""
2656 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
2657 (compare:CC
2658 (zero_extend:SI
2659 (subreg:HI
cd2b37d9 2660 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
2661 (match_operand:SI 2 "const_int_operand" "i")) 0))
2662 (const_int 0)))
2663 (clobber (match_scratch:SI 3 "=r"))]
2664 "includes_rshift_p (operands[2], gen_rtx (CONST_INT, VOIDmode, 65535))"
ca7f5001 2665 "{rlinm.|rlwinm.} %3,%1,%s2,0xffff"
1fd4e8c1
RK
2666 [(set_attr "type" "delayed_compare")])
2667
2668(define_insn ""
2669 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
2670 (compare:CC
2671 (zero_extend:SI
2672 (subreg:HI
cd2b37d9 2673 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
2674 (match_operand:SI 2 "const_int_operand" "i")) 0))
2675 (const_int 0)))
cd2b37d9 2676 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
2677 (zero_extend:SI (subreg:HI (lshiftrt:SI (match_dup 1) (match_dup 2)) 0)))]
2678 "includes_rshift_p (operands[2], gen_rtx (CONST_INT, VOIDmode, 65535))"
ca7f5001 2679 "{rlinm.|rlwinm.} %0,%1,%s2,0xffff"
1fd4e8c1
RK
2680 [(set_attr "type" "delayed_compare")])
2681
2682(define_insn ""
cd2b37d9 2683 [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r")
1fd4e8c1 2684 (const_int 1)
cd2b37d9
RK
2685 (match_operand:SI 1 "gpc_reg_operand" "r"))
2686 (ashiftrt:SI (match_operand:SI 2 "gpc_reg_operand" "r")
1fd4e8c1 2687 (const_int 31)))]
ca7f5001 2688 "TARGET_POWER"
1fd4e8c1
RK
2689 "rrib %0,%1,%2")
2690
2691(define_insn ""
cd2b37d9 2692 [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r")
1fd4e8c1 2693 (const_int 1)
cd2b37d9
RK
2694 (match_operand:SI 1 "gpc_reg_operand" "r"))
2695 (lshiftrt:SI (match_operand:SI 2 "gpc_reg_operand" "r")
1fd4e8c1 2696 (const_int 31)))]
ca7f5001 2697 "TARGET_POWER"
1fd4e8c1
RK
2698 "rrib %0,%1,%2")
2699
2700(define_insn ""
cd2b37d9 2701 [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r")
1fd4e8c1 2702 (const_int 1)
cd2b37d9
RK
2703 (match_operand:SI 1 "gpc_reg_operand" "r"))
2704 (zero_extract:SI (match_operand:SI 2 "gpc_reg_operand" "r")
1fd4e8c1
RK
2705 (const_int 1)
2706 (const_int 0)))]
ca7f5001 2707 "TARGET_POWER"
1fd4e8c1
RK
2708 "rrib %0,%1,%2")
2709
ca7f5001
RK
2710(define_expand "ashrsi3"
2711 [(set (match_operand:SI 0 "gpc_reg_operand" "")
2712 (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "")
2713 (match_operand:SI 2 "reg_or_cint_operand" "")))]
2714 ""
2715 "
2716{
2717 if (TARGET_POWER)
2718 emit_insn (gen_ashrsi3_power (operands[0], operands[1], operands[2]));
2719 else
25c341fa 2720 emit_insn (gen_ashrsi3_no_power (operands[0], operands[1], operands[2]));
ca7f5001
RK
2721 DONE;
2722}")
2723
2724(define_insn "ashrsi3_power"
cd2b37d9
RK
2725 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
2726 (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1
RK
2727 (match_operand:SI 2 "reg_or_cint_operand" "r,i")))
2728 (clobber (match_scratch:SI 3 "=q,X"))]
ca7f5001 2729 "TARGET_POWER"
1fd4e8c1
RK
2730 "@
2731 srea %0,%1,%2
ca7f5001
RK
2732 {srai|srawi} %0,%1,%h2")
2733
25c341fa 2734(define_insn "ashrsi3_no_power"
ca7f5001
RK
2735 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2736 (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
2737 (match_operand:SI 2 "reg_or_cint_operand" "ri")))]
25c341fa 2738 "! TARGET_POWER"
d904e9ed 2739 "{sra|sraw}%I2 %0,%1,%h2")
1fd4e8c1
RK
2740
2741(define_insn ""
2742 [(set (match_operand:CC 0 "cc_reg_operand" "=x,x")
cd2b37d9 2743 (compare:CC (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1
RK
2744 (match_operand:SI 2 "reg_or_cint_operand" "r,i"))
2745 (const_int 0)))
2746 (clobber (match_scratch:SI 3 "=r,r"))
2747 (clobber (match_scratch:SI 4 "=q,X"))]
ca7f5001 2748 "TARGET_POWER"
1fd4e8c1
RK
2749 "@
2750 srea. %3,%1,%2
ca7f5001
RK
2751 {srai.|srawi.} %3,%1,%h2"
2752 [(set_attr "type" "delayed_compare")])
2753
2754(define_insn ""
2755 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
2756 (compare:CC (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
2757 (match_operand:SI 2 "reg_or_cint_operand" "ri"))
2758 (const_int 0)))
2759 (clobber (match_scratch:SI 3 "=r"))]
25c341fa 2760 "! TARGET_POWER"
d904e9ed 2761 "{sra|sraw}%I2. %3,%1,%h2"
1fd4e8c1
RK
2762 [(set_attr "type" "delayed_compare")])
2763
2764(define_insn ""
2765 [(set (match_operand:CC 3 "cc_reg_operand" "=x,x")
cd2b37d9 2766 (compare:CC (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1
RK
2767 (match_operand:SI 2 "reg_or_cint_operand" "r,i"))
2768 (const_int 0)))
cd2b37d9 2769 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
1fd4e8c1
RK
2770 (ashiftrt:SI (match_dup 1) (match_dup 2)))
2771 (clobber (match_scratch:SI 4 "=q,X"))]
ca7f5001 2772 "TARGET_POWER"
1fd4e8c1
RK
2773 "@
2774 srea. %0,%1,%2
7f340546 2775 {srai.|srawi.} %0,%1,%h2"
1fd4e8c1
RK
2776 [(set_attr "type" "delayed_compare")])
2777
ca7f5001
RK
2778(define_insn ""
2779 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
2780 (compare:CC (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
2781 (match_operand:SI 2 "reg_or_cint_operand" "ri"))
2782 (const_int 0)))
2783 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
2784 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
25c341fa 2785 "! TARGET_POWER"
d904e9ed 2786 "{sra|sraw}%I2. %0,%1,%h2"
ca7f5001 2787 [(set_attr "type" "delayed_compare")])
1fd4e8c1
RK
2788\f
2789;; Floating-point insns, excluding normal data motion.
2790;;
ca7f5001
RK
2791;; PowerPC has a full set of single-precision floating point instructions.
2792;;
2793;; For the POWER architecture, we pretend that we have both SFmode and
2794;; DFmode insns, while, in fact, all fp insns are actually done in double.
2795;; The only conversions we will do will be when storing to memory. In that
2796;; case, we will use the "frsp" instruction before storing.
1fd4e8c1
RK
2797;;
2798;; Note that when we store into a single-precision memory location, we need to
2799;; use the frsp insn first. If the register being stored isn't dead, we
2800;; need a scratch register for the frsp. But this is difficult when the store
2801;; is done by reload. It is not incorrect to do the frsp on the register in
2802;; this case, we just lose precision that we would have otherwise gotten but
2803;; is not guaranteed. Perhaps this should be tightened up at some point.
2804
e8112008 2805(define_insn "extendsfdf2"
cd2b37d9 2806 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
e8112008 2807 (float_extend:DF (match_operand:SF 1 "gpc_reg_operand" "f")))]
d14a6d05 2808 "TARGET_HARD_FLOAT"
e8112008 2809 "*
5c30aff8 2810{
e8112008
RK
2811 if (REGNO (operands[0]) == REGNO (operands[1]))
2812 return \"\";
2813 else
2814 return \"fmr %0,%1\";
2815}"
2816 [(set_attr "type" "fp")])
1fd4e8c1
RK
2817
2818(define_insn "truncdfsf2"
cd2b37d9
RK
2819 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
2820 (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "f")))]
d14a6d05 2821 "TARGET_HARD_FLOAT"
dcac138d 2822 "frsp %0,%1"
1fd4e8c1
RK
2823 [(set_attr "type" "fp")])
2824
455350f4
RK
2825(define_insn "aux_truncdfsf2"
2826 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
2827 (unspec:SF [(match_operand:SF 1 "gpc_reg_operand" "f")] 0))]
2828 "! TARGET_POWERPC && TARGET_HARD_FLOAT"
2829 "frsp %0,%1"
2830 [(set_attr "type" "fp")])
2831
1fd4e8c1 2832(define_insn "negsf2"
cd2b37d9
RK
2833 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
2834 (neg:SF (match_operand:SF 1 "gpc_reg_operand" "f")))]
d14a6d05 2835 "TARGET_HARD_FLOAT"
1fd4e8c1
RK
2836 "fneg %0,%1"
2837 [(set_attr "type" "fp")])
2838
2839(define_insn "abssf2"
cd2b37d9
RK
2840 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
2841 (abs:SF (match_operand:SF 1 "gpc_reg_operand" "f")))]
d14a6d05 2842 "TARGET_HARD_FLOAT"
1fd4e8c1
RK
2843 "fabs %0,%1"
2844 [(set_attr "type" "fp")])
2845
2846(define_insn ""
cd2b37d9
RK
2847 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
2848 (neg:SF (abs:SF (match_operand:SF 1 "gpc_reg_operand" "f"))))]
d14a6d05 2849 "TARGET_HARD_FLOAT"
1fd4e8c1
RK
2850 "fnabs %0,%1"
2851 [(set_attr "type" "fp")])
2852
ca7f5001
RK
2853(define_expand "addsf3"
2854 [(set (match_operand:SF 0 "gpc_reg_operand" "")
2855 (plus:SF (match_operand:SF 1 "gpc_reg_operand" "")
2856 (match_operand:SF 2 "gpc_reg_operand" "")))]
d14a6d05 2857 "TARGET_HARD_FLOAT"
ca7f5001
RK
2858 "")
2859
2860(define_insn ""
cd2b37d9
RK
2861 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
2862 (plus:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
2863 (match_operand:SF 2 "gpc_reg_operand" "f")))]
d14a6d05 2864 "TARGET_POWERPC && TARGET_HARD_FLOAT"
b26c8351 2865 "fadds %0,%1,%2"
ca7f5001
RK
2866 [(set_attr "type" "fp")])
2867
2868(define_insn ""
2869 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
2870 (plus:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
2871 (match_operand:SF 2 "gpc_reg_operand" "f")))]
d14a6d05 2872 "! TARGET_POWERPC && TARGET_HARD_FLOAT"
b26c8351 2873 "{fa|fadd} %0,%1,%2"
ca7f5001
RK
2874 [(set_attr "type" "fp")])
2875
2876(define_expand "subsf3"
2877 [(set (match_operand:SF 0 "gpc_reg_operand" "")
2878 (minus:SF (match_operand:SF 1 "gpc_reg_operand" "")
2879 (match_operand:SF 2 "gpc_reg_operand" "")))]
d14a6d05 2880 "TARGET_HARD_FLOAT"
ca7f5001
RK
2881 "")
2882
2883(define_insn ""
2884 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
2885 (minus:SF (match_operand:SF 1 "gpc_reg_operand" "f")
2886 (match_operand:SF 2 "gpc_reg_operand" "f")))]
d14a6d05 2887 "TARGET_POWERPC && TARGET_HARD_FLOAT"
b26c8351 2888 "fsubs %0,%1,%2"
1fd4e8c1
RK
2889 [(set_attr "type" "fp")])
2890
ca7f5001 2891(define_insn ""
cd2b37d9
RK
2892 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
2893 (minus:SF (match_operand:SF 1 "gpc_reg_operand" "f")
2894 (match_operand:SF 2 "gpc_reg_operand" "f")))]
d14a6d05 2895 "! TARGET_POWERPC && TARGET_HARD_FLOAT"
b26c8351 2896 "{fs|fsub} %0,%1,%2"
ca7f5001
RK
2897 [(set_attr "type" "fp")])
2898
2899(define_expand "mulsf3"
2900 [(set (match_operand:SF 0 "gpc_reg_operand" "")
2901 (mult:SF (match_operand:SF 1 "gpc_reg_operand" "")
2902 (match_operand:SF 2 "gpc_reg_operand" "")))]
d14a6d05 2903 "TARGET_HARD_FLOAT"
ca7f5001
RK
2904 "")
2905
2906(define_insn ""
2907 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
2908 (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
2909 (match_operand:SF 2 "gpc_reg_operand" "f")))]
d14a6d05 2910 "TARGET_POWERPC && TARGET_HARD_FLOAT"
b26c8351 2911 "fmuls %0,%1,%2"
1fd4e8c1
RK
2912 [(set_attr "type" "fp")])
2913
ca7f5001 2914(define_insn ""
cd2b37d9
RK
2915 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
2916 (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
2917 (match_operand:SF 2 "gpc_reg_operand" "f")))]
d14a6d05 2918 "! TARGET_POWERPC && TARGET_HARD_FLOAT"
b26c8351 2919 "{fm|fmul} %0,%1,%2"
0780f386 2920 [(set_attr "type" "dmul")])
1fd4e8c1 2921
ca7f5001
RK
2922(define_expand "divsf3"
2923 [(set (match_operand:SF 0 "gpc_reg_operand" "")
2924 (div:SF (match_operand:SF 1 "gpc_reg_operand" "")
2925 (match_operand:SF 2 "gpc_reg_operand" "")))]
d14a6d05 2926 "TARGET_HARD_FLOAT"
ca7f5001
RK
2927 "")
2928
2929(define_insn ""
cd2b37d9
RK
2930 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
2931 (div:SF (match_operand:SF 1 "gpc_reg_operand" "f")
2932 (match_operand:SF 2 "gpc_reg_operand" "f")))]
d14a6d05 2933 "TARGET_POWERPC && TARGET_HARD_FLOAT"
b26c8351 2934 "fdivs %0,%1,%2"
ca7f5001
RK
2935 [(set_attr "type" "sdiv")])
2936
2937(define_insn ""
2938 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
2939 (div:SF (match_operand:SF 1 "gpc_reg_operand" "f")
2940 (match_operand:SF 2 "gpc_reg_operand" "f")))]
d14a6d05 2941 "! TARGET_POWERPC && TARGET_HARD_FLOAT"
b26c8351 2942 "{fd|fdiv} %0,%1,%2"
0780f386 2943 [(set_attr "type" "ddiv")])
1fd4e8c1
RK
2944
2945(define_insn ""
cd2b37d9
RK
2946 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
2947 (plus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
2948 (match_operand:SF 2 "gpc_reg_operand" "f"))
2949 (match_operand:SF 3 "gpc_reg_operand" "f")))]
d14a6d05 2950 "TARGET_POWERPC && TARGET_HARD_FLOAT"
b26c8351 2951 "fmadds %0,%1,%2,%3"
ca7f5001
RK
2952 [(set_attr "type" "fp")])
2953
2954(define_insn ""
2955 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
2956 (plus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
2957 (match_operand:SF 2 "gpc_reg_operand" "f"))
2958 (match_operand:SF 3 "gpc_reg_operand" "f")))]
d14a6d05 2959 "! TARGET_POWERPC && TARGET_HARD_FLOAT"
b26c8351 2960 "{fma|fmadd} %0,%1,%2,%3"
cf27b467 2961 [(set_attr "type" "dmul")])
1fd4e8c1
RK
2962
2963(define_insn ""
cd2b37d9
RK
2964 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
2965 (minus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
2966 (match_operand:SF 2 "gpc_reg_operand" "f"))
2967 (match_operand:SF 3 "gpc_reg_operand" "f")))]
d14a6d05 2968 "TARGET_POWERPC && TARGET_HARD_FLOAT"
b26c8351 2969 "fmsubs %0,%1,%2,%3"
ca7f5001
RK
2970 [(set_attr "type" "fp")])
2971
2972(define_insn ""
2973 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
2974 (minus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
2975 (match_operand:SF 2 "gpc_reg_operand" "f"))
2976 (match_operand:SF 3 "gpc_reg_operand" "f")))]
d14a6d05 2977 "! TARGET_POWERPC && TARGET_HARD_FLOAT"
b26c8351 2978 "{fms|fmsub} %0,%1,%2,%3"
cf27b467 2979 [(set_attr "type" "dmul")])
1fd4e8c1
RK
2980
2981(define_insn ""
cd2b37d9
RK
2982 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
2983 (neg:SF (plus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
2984 (match_operand:SF 2 "gpc_reg_operand" "f"))
2985 (match_operand:SF 3 "gpc_reg_operand" "f"))))]
d14a6d05 2986 "TARGET_POWERPC && TARGET_HARD_FLOAT"
b26c8351 2987 "fnmadds %0,%1,%2,%3"
ca7f5001
RK
2988 [(set_attr "type" "fp")])
2989
2990(define_insn ""
2991 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
2992 (neg:SF (plus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
2993 (match_operand:SF 2 "gpc_reg_operand" "f"))
2994 (match_operand:SF 3 "gpc_reg_operand" "f"))))]
d14a6d05 2995 "! TARGET_POWERPC && TARGET_HARD_FLOAT"
b26c8351 2996 "{fnma|fnmadd} %0,%1,%2,%3"
cf27b467 2997 [(set_attr "type" "dmul")])
1fd4e8c1
RK
2998
2999(define_insn ""
cd2b37d9
RK
3000 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
3001 (neg:SF (minus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
3002 (match_operand:SF 2 "gpc_reg_operand" "f"))
3003 (match_operand:SF 3 "gpc_reg_operand" "f"))))]
d14a6d05 3004 "TARGET_POWERPC && TARGET_HARD_FLOAT"
b26c8351 3005 "fnmsubs %0,%1,%2,%3"
ca7f5001
RK
3006 [(set_attr "type" "fp")])
3007
3008(define_insn ""
3009 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
3010 (neg:SF (minus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
3011 (match_operand:SF 2 "gpc_reg_operand" "f"))
3012 (match_operand:SF 3 "gpc_reg_operand" "f"))))]
d14a6d05 3013 "! TARGET_POWERPC && TARGET_HARD_FLOAT"
b26c8351 3014 "{fnms|fnmsub} %0,%1,%2,%3"
cf27b467 3015 [(set_attr "type" "dmul")])
1fd4e8c1 3016
ca7f5001
RK
3017(define_expand "sqrtsf2"
3018 [(set (match_operand:SF 0 "gpc_reg_operand" "")
3019 (sqrt:SF (match_operand:SF 1 "gpc_reg_operand" "")))]
d14a6d05 3020 "(TARGET_PPC_GPOPT || TARGET_POWER2) && TARGET_HARD_FLOAT"
ca7f5001
RK
3021 "")
3022
3023(define_insn ""
3024 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
3025 (sqrt:SF (match_operand:SF 1 "gpc_reg_operand" "f")))]
d14a6d05 3026 "TARGET_PPC_GPOPT && TARGET_HARD_FLOAT"
ca7f5001
RK
3027 "fsqrts %0,%1"
3028 [(set_attr "type" "ssqrt")])
3029
3030(define_insn ""
3031 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
3032 (sqrt:SF (match_operand:SF 1 "gpc_reg_operand" "f")))]
d14a6d05 3033 "TARGET_POWER2 && TARGET_HARD_FLOAT"
ca7f5001
RK
3034 "fsqrt %0,%1"
3035 [(set_attr "type" "dsqrt")])
3036
94d7001a
RK
3037;; For MIN, MAX, and conditional move, we use DEFINE_EXPAND's that involve a
3038;; fsel instruction and some auxiliary computations. Then we just have a
3039;; single DEFINE_INSN for fsel and the define_splits to make them if made by
8e871c05
RK
3040;; combine.
3041(define_expand "maxsf3"
3042 [(set (match_dup 3)
3043 (minus:SF (match_operand:SF 1 "gpc_reg_operand" "")
3044 (match_operand:SF 2 "gpc_reg_operand" "")))
3045 (set (match_operand:SF 0 "gpc_reg_operand" "")
3046 (if_then_else:SF (ge (match_dup 3)
3047 (const_int 0))
3048 (match_dup 1)
3049 (match_dup 2)))]
d14a6d05 3050 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT"
8e871c05
RK
3051 "
3052{ operands[3] = gen_reg_rtx (SFmode); }")
2f607b94 3053
8e871c05
RK
3054(define_split
3055 [(set (match_operand:SF 0 "gpc_reg_operand" "")
3056 (smax:SF (match_operand:SF 1 "gpc_reg_operand" "")
f63184ac 3057 (match_operand:SF 2 "gpc_reg_operand" "")))
8e871c05 3058 (clobber (match_operand:SF 3 "gpc_reg_operand" ""))]
d14a6d05 3059 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT"
8e871c05
RK
3060 [(set (match_dup 3)
3061 (minus:SF (match_dup 1) (match_dup 2)))
a81bd72f 3062 (set (match_dup 0)
8e871c05
RK
3063 (if_then_else:SF (ge (match_dup 3)
3064 (const_int 0))
3065 (match_dup 1)
3066 (match_dup 2)))]
3067 "")
2f607b94 3068
8e871c05
RK
3069(define_expand "minsf3"
3070 [(set (match_dup 3)
3071 (minus:SF (match_operand:SF 2 "gpc_reg_operand" "")
3072 (match_operand:SF 1 "gpc_reg_operand" "")))
3073 (set (match_operand:SF 0 "gpc_reg_operand" "")
3074 (if_then_else:SF (ge (match_dup 3)
3075 (const_int 0))
3076 (match_dup 1)
3077 (match_dup 2)))]
d14a6d05 3078 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT"
8e871c05
RK
3079 "
3080{ operands[3] = gen_reg_rtx (SFmode); }")
2f607b94 3081
8e871c05
RK
3082(define_split
3083 [(set (match_operand:SF 0 "gpc_reg_operand" "")
3084 (smin:SF (match_operand:SF 1 "gpc_reg_operand" "")
f63184ac 3085 (match_operand:SF 2 "gpc_reg_operand" "")))
8e871c05 3086 (clobber (match_operand:SF 3 "gpc_reg_operand" ""))]
d14a6d05 3087 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT"
8e871c05
RK
3088 [(set (match_dup 3)
3089 (minus:SF (match_dup 2) (match_dup 1)))
a81bd72f 3090 (set (match_dup 0)
8e871c05
RK
3091 (if_then_else:SF (ge (match_dup 3)
3092 (const_int 0))
3093 (match_dup 1)
3094 (match_dup 2)))]
3095 "")
2f607b94 3096
94d7001a
RK
3097(define_expand "movsfcc"
3098 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
3099 (if_then_else:SF (match_operand 1 "comparison_operator" "")
3100 (match_operand:SF 2 "gpc_reg_operand" "f")
3101 (match_operand:SF 3 "gpc_reg_operand" "f")))]
d14a6d05 3102 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT"
94d7001a
RK
3103 "
3104{
3105 rtx temp, op0, op1;
3106 enum rtx_code code = GET_CODE (operands[1]);
3107 if (! rs6000_compare_fp_p)
3108 FAIL;
3109 switch (code)
3110 {
3111 case GE: case EQ: case NE:
3112 op0 = rs6000_compare_op0;
3113 op1 = rs6000_compare_op1;
3114 break;
3115 case GT:
3116 op0 = rs6000_compare_op1;
3117 op1 = rs6000_compare_op0;
3118 temp = operands[2]; operands[2] = operands[3]; operands[3] = temp;
3119 break;
3120 case LE:
3121 op0 = rs6000_compare_op1;
3122 op1 = rs6000_compare_op0;
3123 break;
3124 case LT:
3125 op0 = rs6000_compare_op0;
3126 op1 = rs6000_compare_op1;
3127 temp = operands[2]; operands[2] = operands[3]; operands[3] = temp;
3128 break;
3129 default:
3130 FAIL;
3131 }
3132 if (GET_MODE (rs6000_compare_op0) == DFmode)
3133 {
3134 temp = gen_reg_rtx (DFmode);
3135 emit_insn (gen_subdf3 (temp, op0, op1));
3136 emit_insn (gen_fseldfsf4 (operands[0], temp, operands[2], operands[3]));
3137 if (code == EQ)
3138 {
3139 emit_insn (gen_negdf2 (temp, temp));
3140 emit_insn (gen_fseldfsf4 (operands[0], temp, operands[0], operands[3]));
3141 }
3142 if (code == NE)
3143 {
3144 emit_insn (gen_negdf2 (temp, temp));
3145 emit_insn (gen_fseldfsf4 (operands[0], temp, operands[3], operands[0]));
3146 }
3147 }
3148 else
3149 {
3150 temp = gen_reg_rtx (SFmode);
3151 emit_insn (gen_subsf3 (temp, op0, op1));
3152 emit_insn (gen_fselsfsf4 (operands[0], temp, operands[2], operands[3]));
3153 if (code == EQ)
3154 {
3155 emit_insn (gen_negsf2 (temp, temp));
3156 emit_insn (gen_fselsfsf4 (operands[0], temp, operands[0], operands[3]));
3157 }
3158 if (code == NE)
3159 {
3160 emit_insn (gen_negsf2 (temp, temp));
3161 emit_insn (gen_fselsfsf4 (operands[0], temp, operands[3], operands[0]));
3162 }
3163 }
3164 DONE;
3165}")
d56d506a 3166
94d7001a 3167(define_insn "fselsfsf4"
8e871c05
RK
3168 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
3169 (if_then_else:SF (ge (match_operand:SF 1 "gpc_reg_operand" "f")
3170 (const_int 0))
3171 (match_operand:SF 2 "gpc_reg_operand" "f")
3172 (match_operand:SF 3 "gpc_reg_operand" "f")))]
d14a6d05 3173 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT"
8e871c05
RK
3174 "fsel %0,%1,%2,%3"
3175 [(set_attr "type" "fp")])
2f607b94 3176
94d7001a
RK
3177(define_insn "fseldfsf4"
3178 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
3179 (if_then_else:SF (ge (match_operand:DF 1 "gpc_reg_operand" "f")
3180 (const_int 0))
3181 (match_operand:SF 2 "gpc_reg_operand" "f")
3182 (match_operand:SF 3 "gpc_reg_operand" "f")))]
d14a6d05 3183 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT"
94d7001a
RK
3184 "fsel %0,%1,%2,%3"
3185 [(set_attr "type" "fp")])
d56d506a 3186
1fd4e8c1 3187(define_insn "negdf2"
cd2b37d9
RK
3188 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
3189 (neg:DF (match_operand:DF 1 "gpc_reg_operand" "f")))]
d14a6d05 3190 "TARGET_HARD_FLOAT"
1fd4e8c1
RK
3191 "fneg %0,%1"
3192 [(set_attr "type" "fp")])
3193
3194(define_insn "absdf2"
cd2b37d9
RK
3195 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
3196 (abs:DF (match_operand:DF 1 "gpc_reg_operand" "f")))]
d14a6d05 3197 "TARGET_HARD_FLOAT"
1fd4e8c1
RK
3198 "fabs %0,%1"
3199 [(set_attr "type" "fp")])
3200
3201(define_insn ""
cd2b37d9
RK
3202 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
3203 (neg:DF (abs:DF (match_operand:DF 1 "gpc_reg_operand" "f"))))]
d14a6d05 3204 "TARGET_HARD_FLOAT"
1fd4e8c1
RK
3205 "fnabs %0,%1"
3206 [(set_attr "type" "fp")])
3207
3208(define_insn "adddf3"
cd2b37d9
RK
3209 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
3210 (plus:DF (match_operand:DF 1 "gpc_reg_operand" "%f")
3211 (match_operand:DF 2 "gpc_reg_operand" "f")))]
d14a6d05 3212 "TARGET_HARD_FLOAT"
ca7f5001 3213 "{fa|fadd} %0,%1,%2"
1fd4e8c1
RK
3214 [(set_attr "type" "fp")])
3215
3216(define_insn "subdf3"
cd2b37d9
RK
3217 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
3218 (minus:DF (match_operand:DF 1 "gpc_reg_operand" "f")
3219 (match_operand:DF 2 "gpc_reg_operand" "f")))]
d14a6d05 3220 "TARGET_HARD_FLOAT"
ca7f5001 3221 "{fs|fsub} %0,%1,%2"
1fd4e8c1
RK
3222 [(set_attr "type" "fp")])
3223
3224(define_insn "muldf3"
cd2b37d9
RK
3225 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
3226 (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%f")
3227 (match_operand:DF 2 "gpc_reg_operand" "f")))]
d14a6d05 3228 "TARGET_HARD_FLOAT"
ca7f5001 3229 "{fm|fmul} %0,%1,%2"
cfb557c4 3230 [(set_attr "type" "dmul")])
1fd4e8c1
RK
3231
3232(define_insn "divdf3"
cd2b37d9
RK
3233 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
3234 (div:DF (match_operand:DF 1 "gpc_reg_operand" "f")
3235 (match_operand:DF 2 "gpc_reg_operand" "f")))]
d14a6d05 3236 "TARGET_HARD_FLOAT"
ca7f5001 3237 "{fd|fdiv} %0,%1,%2"
cfb557c4 3238 [(set_attr "type" "ddiv")])
1fd4e8c1
RK
3239
3240(define_insn ""
cd2b37d9
RK
3241 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
3242 (plus:DF (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%f")
3243 (match_operand:DF 2 "gpc_reg_operand" "f"))
3244 (match_operand:DF 3 "gpc_reg_operand" "f")))]
d14a6d05 3245 "TARGET_HARD_FLOAT"
ca7f5001 3246 "{fma|fmadd} %0,%1,%2,%3"
cfb557c4 3247 [(set_attr "type" "dmul")])
1fd4e8c1
RK
3248
3249(define_insn ""
cd2b37d9
RK
3250 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
3251 (minus:DF (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%f")
3252 (match_operand:DF 2 "gpc_reg_operand" "f"))
3253 (match_operand:DF 3 "gpc_reg_operand" "f")))]
d14a6d05 3254 "TARGET_HARD_FLOAT"
ca7f5001 3255 "{fms|fmsub} %0,%1,%2,%3"
cfb557c4 3256 [(set_attr "type" "dmul")])
1fd4e8c1
RK
3257
3258(define_insn ""
cd2b37d9
RK
3259 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
3260 (neg:DF (plus:DF (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%f")
3261 (match_operand:DF 2 "gpc_reg_operand" "f"))
3262 (match_operand:DF 3 "gpc_reg_operand" "f"))))]
d14a6d05 3263 "TARGET_HARD_FLOAT"
ca7f5001 3264 "{fnma|fnmadd} %0,%1,%2,%3"
cfb557c4 3265 [(set_attr "type" "dmul")])
1fd4e8c1
RK
3266
3267(define_insn ""
cd2b37d9
RK
3268 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
3269 (neg:DF (minus:DF (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%f")
3270 (match_operand:DF 2 "gpc_reg_operand" "f"))
3271 (match_operand:DF 3 "gpc_reg_operand" "f"))))]
d14a6d05 3272 "TARGET_HARD_FLOAT"
ca7f5001 3273 "{fnms|fnmsub} %0,%1,%2,%3"
cfb557c4 3274 [(set_attr "type" "dmul")])
ca7f5001
RK
3275
3276(define_insn "sqrtdf2"
3277 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
3278 (sqrt:DF (match_operand:DF 1 "gpc_reg_operand" "f")))]
d14a6d05 3279 "(TARGET_PPC_GPOPT || TARGET_POWER2) && TARGET_HARD_FLOAT"
ca7f5001
RK
3280 "fsqrt %0,%1"
3281 [(set_attr "type" "dsqrt")])
b77dfefc 3282
94d7001a
RK
3283;; For MIN, MAX, and conditional move, we use DEFINE_EXPAND's that involve a
3284;; fsel instruction and some auxiliary computations. Then we just have a
3285;; single DEFINE_INSN for fsel and the define_splits to make them if made by
8e871c05 3286;; combine.
b77dfefc 3287
8e871c05
RK
3288(define_expand "maxdf3"
3289 [(set (match_dup 3)
3290 (minus:DF (match_operand:DF 1 "gpc_reg_operand" "")
3291 (match_operand:DF 2 "gpc_reg_operand" "")))
3292 (set (match_operand:DF 0 "gpc_reg_operand" "")
3293 (if_then_else:DF (ge (match_dup 3)
3294 (const_int 0))
3295 (match_dup 1)
3296 (match_dup 2)))]
d14a6d05 3297 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT"
8e871c05
RK
3298 "
3299{ operands[3] = gen_reg_rtx (DFmode); }")
b77dfefc 3300
8e871c05
RK
3301(define_split
3302 [(set (match_operand:DF 0 "gpc_reg_operand" "")
3303 (smax:DF (match_operand:DF 1 "gpc_reg_operand" "")
f63184ac 3304 (match_operand:DF 2 "gpc_reg_operand" "")))
8e871c05 3305 (clobber (match_operand:DF 3 "gpc_reg_operand" ""))]
d14a6d05 3306 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT"
8e871c05
RK
3307 [(set (match_dup 3)
3308 (minus:DF (match_dup 1) (match_dup 2)))
a81bd72f 3309 (set (match_dup 0)
8e871c05
RK
3310 (if_then_else:DF (ge (match_dup 3)
3311 (const_int 0))
3312 (match_dup 1)
3313 (match_dup 2)))]
3314 "")
b77dfefc 3315
8e871c05
RK
3316(define_expand "mindf3"
3317 [(set (match_dup 3)
3318 (minus:DF (match_operand:DF 2 "gpc_reg_operand" "")
3319 (match_operand:DF 1 "gpc_reg_operand" "")))
3320 (set (match_operand:DF 0 "gpc_reg_operand" "")
3321 (if_then_else:DF (ge (match_dup 3)
3322 (const_int 0))
3323 (match_dup 1)
3324 (match_dup 2)))]
d14a6d05 3325 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT"
8e871c05
RK
3326 "
3327{ operands[3] = gen_reg_rtx (DFmode); }")
b77dfefc 3328
8e871c05
RK
3329(define_split
3330 [(set (match_operand:DF 0 "gpc_reg_operand" "")
3331 (smin:DF (match_operand:DF 1 "gpc_reg_operand" "")
f63184ac 3332 (match_operand:DF 2 "gpc_reg_operand" "")))
8e871c05 3333 (clobber (match_operand:DF 3 "gpc_reg_operand" ""))]
d14a6d05 3334 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT"
8e871c05
RK
3335 [(set (match_dup 3)
3336 (minus:DF (match_dup 2) (match_dup 1)))
a81bd72f 3337 (set (match_dup 0)
8e871c05
RK
3338 (if_then_else:DF (ge (match_dup 3)
3339 (const_int 0))
3340 (match_dup 1)
3341 (match_dup 2)))]
3342 "")
b77dfefc 3343
94d7001a
RK
3344(define_expand "movdfcc"
3345 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
3346 (if_then_else:DF (match_operand 1 "comparison_operator" "")
3347 (match_operand:DF 2 "gpc_reg_operand" "f")
3348 (match_operand:DF 3 "gpc_reg_operand" "f")))]
d14a6d05 3349 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT"
94d7001a
RK
3350 "
3351{
3352 rtx temp, op0, op1;
3353 enum rtx_code code = GET_CODE (operands[1]);
3354 if (! rs6000_compare_fp_p)
3355 FAIL;
3356 switch (code)
3357 {
3358 case GE: case EQ: case NE:
3359 op0 = rs6000_compare_op0;
3360 op1 = rs6000_compare_op1;
3361 break;
3362 case GT:
3363 op0 = rs6000_compare_op1;
3364 op1 = rs6000_compare_op0;
3365 temp = operands[2]; operands[2] = operands[3]; operands[3] = temp;
3366 break;
3367 case LE:
3368 op0 = rs6000_compare_op1;
3369 op1 = rs6000_compare_op0;
3370 break;
3371 case LT:
3372 op0 = rs6000_compare_op0;
3373 op1 = rs6000_compare_op1;
3374 temp = operands[2]; operands[2] = operands[3]; operands[3] = temp;
3375 break;
3376 default:
3377 FAIL;
3378 }
3379 if (GET_MODE (rs6000_compare_op0) == DFmode)
3380 {
3381 temp = gen_reg_rtx (DFmode);
3382 emit_insn (gen_subdf3 (temp, op0, op1));
3383 emit_insn (gen_fseldfdf4 (operands[0], temp, operands[2], operands[3]));
3384 if (code == EQ)
3385 {
3386 emit_insn (gen_negdf2 (temp, temp));
3387 emit_insn (gen_fseldfdf4 (operands[0], temp, operands[0], operands[3]));
3388 }
3389 if (code == NE)
3390 {
3391 emit_insn (gen_negdf2 (temp, temp));
3392 emit_insn (gen_fseldfdf4 (operands[0], temp, operands[3], operands[0]));
3393 }
3394 }
3395 else
3396 {
3397 temp = gen_reg_rtx (SFmode);
3398 emit_insn (gen_subsf3 (temp, op0, op1));
3399 emit_insn (gen_fselsfdf4 (operands[0], temp, operands[2], operands[3]));
3400 if (code == EQ)
3401 {
3402 emit_insn (gen_negsf2 (temp, temp));
3403 emit_insn (gen_fselsfdf4 (operands[0], temp, operands[0], operands[3]));
3404 }
3405 if (code == NE)
3406 {
3407 emit_insn (gen_negsf2 (temp, temp));
3408 emit_insn (gen_fselsfdf4 (operands[0], temp, operands[3], operands[0]));
3409 }
3410 }
3411 DONE;
3412}")
d56d506a 3413
94d7001a 3414(define_insn "fseldfdf4"
8e871c05
RK
3415 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
3416 (if_then_else:DF (ge (match_operand:DF 1 "gpc_reg_operand" "f")
3417 (const_int 0))
3418 (match_operand:DF 2 "gpc_reg_operand" "f")
3419 (match_operand:DF 3 "gpc_reg_operand" "f")))]
d14a6d05 3420 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT"
8e871c05
RK
3421 "fsel %0,%1,%2,%3"
3422 [(set_attr "type" "fp")])
d56d506a 3423
94d7001a
RK
3424(define_insn "fselsfdf4"
3425 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
3426 (if_then_else:DF (ge (match_operand:SF 1 "gpc_reg_operand" "f")
3427 (const_int 0))
3428 (match_operand:DF 2 "gpc_reg_operand" "f")
3429 (match_operand:DF 3 "gpc_reg_operand" "f")))]
3430 "TARGET_PPC_GFXOPT"
3431 "fsel %0,%1,%2,%3"
3432 [(set_attr "type" "fp")])
1fd4e8c1
RK
3433\f
3434;; Conversions to and from floating-point.
3435(define_expand "floatsidf2"
dbe3df29
RK
3436 [(set (match_operand:DF 0 "gpc_reg_operand" "")
3437 (float:DF (match_operand:SI 1 "gpc_reg_operand" "")))]
dc4f83ca 3438 "! TARGET_POWERPC64 && TARGET_HARD_FLOAT"
1fd4e8c1
RK
3439 "
3440{
dbe3df29
RK
3441 if (operands[0])
3442 { /* prevent unused warning messages */
3443 rtx high = force_reg (SImode, GEN_INT (0x43300000));
3444 rtx low = gen_reg_rtx (SImode);
3445 rtx df = gen_reg_rtx (DFmode);
3446 rtx adjust = force_reg (DFmode, rs6000_float_const (\"4503601774854144\", DFmode));
3447
3448 emit_insn (gen_xorsi3 (low, operands[1], GEN_INT (0x80000000)));
3449 emit_insn (gen_move_to_float (df, low, high));
3450 emit_insn (gen_subdf3 (operands[0], df, adjust));
3451 DONE;
3452 }
1fd4e8c1
RK
3453}")
3454
3455(define_expand "floatunssidf2"
dbe3df29
RK
3456 [(set (match_operand:DF 0 "gpc_reg_operand" "")
3457 (unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" "")))]
dc4f83ca 3458 "! TARGET_POWERPC64 && TARGET_HARD_FLOAT"
1fd4e8c1
RK
3459 "
3460{
dbe3df29
RK
3461 if (operands[0])
3462 { /* prevent unused warning messages */
3463 rtx high = force_reg (SImode, GEN_INT (0x43300000));
3464 rtx df = gen_reg_rtx (DFmode);
3465 rtx adjust = force_reg (DFmode, rs6000_float_const (\"4503599627370496\", DFmode));
3466
3467 emit_insn (gen_move_to_float (df, operands[1], high));
3468 emit_insn (gen_subdf3 (operands[0], df, adjust));
3469 DONE;
3470 }
1fd4e8c1
RK
3471}")
3472
dbe3df29 3473(define_expand "move_to_float"
d904e9ed
RK
3474 [(set (match_operand:DF 0 "gpc_reg_operand" "")
3475 (unspec [(match_operand:SI 1 "gpc_reg_operand" "")
3476 (match_operand:SI 2 "gpc_reg_operand" "")
3477 (match_dup 3)] 2))]
dbe3df29 3478 "! TARGET_POWERPC64 && TARGET_HARD_FLOAT"
1fd4e8c1 3479 "
dbe3df29 3480{
d904e9ed 3481 operands[3] = XEXP (rs6000_stack_temp (DFmode, 8, 1), 0);
dbe3df29 3482}")
7e69e155 3483
1fd4e8c1 3484(define_split
dbe3df29
RK
3485 [(set (match_operand:DF 0 "gpc_reg_operand" "")
3486 (unspec [(match_operand:SI 1 "gpc_reg_operand" "")
d904e9ed
RK
3487 (match_operand:SI 2 "gpc_reg_operand" "")
3488 (match_operand:SI 3 "offsettable_addr_operand" "")] 2))]
7a96832a 3489 "reload_completed"
dbe3df29
RK
3490 [(set (match_dup 4) (match_dup 1))
3491 (set (match_dup 5) (match_dup 2))
d904e9ed 3492 (set (match_dup 0) (mem:DF (match_dup 3)))]
1fd4e8c1 3493 "
dbe3df29 3494{
d904e9ed
RK
3495 rtx word1 = gen_rtx (MEM, SImode, operands[3]);
3496 rtx word2 = gen_rtx (MEM, SImode, plus_constant (operands[3], 4));
3497
3498 MEM_IN_STRUCT_P (word1) = 1;
3499 MEM_IN_STRUCT_P (word2) = 1;
c283c989 3500
d904e9ed
RK
3501 if (WORDS_BIG_ENDIAN)
3502 {
3503 operands[4] = word2;
3504 operands[5] = word1;
3505 }
3506 else
3507 {
3508 operands[4] = word1;
3509 operands[5] = word2;
3510 }
1fd4e8c1
RK
3511}")
3512
3513(define_insn ""
dbe3df29
RK
3514 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
3515 (unspec [(match_operand:SI 1 "gpc_reg_operand" "r")
d904e9ed
RK
3516 (match_operand:SI 2 "gpc_reg_operand" "r")
3517 (match_operand:SI 3 "offsettable_addr_operand" "p")] 2))]
dbe3df29 3518 "! TARGET_POWERPC64 && TARGET_HARD_FLOAT"
baf97f86 3519 "#"
dbe3df29 3520 [(set_attr "length" "12")])
1fd4e8c1
RK
3521
3522(define_expand "fix_truncdfsi2"
cd2b37d9 3523 [(set (match_operand:SI 0 "gpc_reg_operand" "")
b542afe9 3524 (fix:SI (match_operand:DF 1 "gpc_reg_operand" "")))]
d14a6d05 3525 "TARGET_HARD_FLOAT"
1fd4e8c1
RK
3526 "
3527{
8ffd9c51
RK
3528 if (TARGET_POWER2 || TARGET_POWERPC)
3529 {
dbe3df29 3530 int endian = (WORDS_BIG_ENDIAN == 0);
d904e9ed 3531 rtx stack_slot = rs6000_stack_temp (DImode, 8, 1);
dbe3df29 3532 rtx temp = gen_reg_rtx (DImode);
425c176f 3533
8ffd9c51 3534 emit_insn (gen_fpcvtsi (temp, operands[1]));
8ffd9c51
RK
3535 emit_move_insn (stack_slot, temp);
3536 emit_move_insn (operands[0],
dbe3df29 3537 operand_subword (stack_slot, 1 - endian, 0, DImode));
8ffd9c51
RK
3538 DONE;
3539 }
3540 else
3541 {
3542 emit_insn (gen_trunc_call (operands[0], operands[1],
3543 gen_rtx (SYMBOL_REF, Pmode, RS6000_ITRUNC)));
3544 DONE;
3545 }
1fd4e8c1
RK
3546}")
3547
8ffd9c51
RK
3548(define_insn "fpcvtsi"
3549 [(set (match_operand:DI 0 "gpc_reg_operand" "=f")
3550 (sign_extend:DI
3551 (fix:SI (match_operand:DF 1 "gpc_reg_operand" "f"))))]
d14a6d05 3552 "(TARGET_POWER2 || TARGET_POWERPC) && TARGET_HARD_FLOAT"
8ffd9c51
RK
3553 "{fcirz|fctiwz} %0,%1"
3554 [(set_attr "type" "fp")])
deb9225a 3555
1fd4e8c1 3556(define_expand "fixuns_truncdfsi2"
cd2b37d9 3557 [(set (match_operand:SI 0 "gpc_reg_operand" "")
b542afe9 3558 (unsigned_fix:SI (match_operand:DF 1 "gpc_reg_operand" "")))]
d14a6d05 3559 "! TARGET_POWER2 && ! TARGET_POWERPC && TARGET_HARD_FLOAT"
1fd4e8c1
RK
3560 "
3561{
3562 emit_insn (gen_trunc_call (operands[0], operands[1],
3c64f04b 3563 gen_rtx (SYMBOL_REF, Pmode, RS6000_UITRUNC)));
1fd4e8c1
RK
3564 DONE;
3565}")
3566
1fd4e8c1
RK
3567(define_expand "trunc_call"
3568 [(parallel [(set (match_operand:SI 0 "" "")
b542afe9 3569 (fix:SI (match_operand:DF 1 "" "")))
1fd4e8c1 3570 (use (match_operand:SI 2 "" ""))])]
d14a6d05 3571 "TARGET_HARD_FLOAT"
1fd4e8c1
RK
3572 "
3573{
3574 rtx insns = gen_trunc_call_rtl (operands[0], operands[1], operands[2]);
3575 rtx first = XVECEXP (insns, 0, 0);
3576 rtx last = XVECEXP (insns, 0, XVECLEN (insns, 0) - 1);
3577
3578 REG_NOTES (first) = gen_rtx (INSN_LIST, REG_LIBCALL, last,
3579 REG_NOTES (first));
3580 REG_NOTES (last) = gen_rtx (INSN_LIST, REG_RETVAL, first, REG_NOTES (last));
3581
3582 emit_insn (insns);
3583 DONE;
3584}")
3585
3586(define_expand "trunc_call_rtl"
cd2b37d9 3587 [(set (reg:DF 33) (match_operand:DF 1 "gpc_reg_operand" ""))
1fd4e8c1
RK
3588 (use (reg:DF 33))
3589 (parallel [(set (reg:SI 3)
3590 (call (mem:SI (match_operand 2 "" "")) (const_int 0)))
4697a36c 3591 (use (const_int 0))
1fd4e8c1 3592 (clobber (scratch:SI))])
cd2b37d9 3593 (set (match_operand:SI 0 "gpc_reg_operand" "")
1fd4e8c1 3594 (reg:SI 3))]
d14a6d05 3595 "TARGET_HARD_FLOAT"
1fd4e8c1 3596 "
7e69e155 3597{
1fd4e8c1
RK
3598 rs6000_trunc_used = 1;
3599}")
a473029f
RK
3600
3601(define_insn "floatdidf2"
3602 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
3603 (float:DF (match_operand:DI 1 "gpc_reg_operand" "f")))]
d14a6d05 3604 "TARGET_POWERPC64 && TARGET_HARD_FLOAT"
a473029f
RK
3605 "fcfid %0,%1"
3606 [(set_attr "type" "fp")])
3607
3608(define_insn "fix_truncdfdi2"
3609 [(set (match_operand:DI 0 "gpc_reg_operand" "=f")
3610 (fix:DI (match_operand:DF 1 "gpc_reg_operand" "f")))]
d14a6d05 3611 "TARGET_POWERPC64 && TARGET_HARD_FLOAT"
a473029f
RK
3612 "fctidz %0,%1"
3613 [(set_attr "type" "fp")])
1fd4e8c1
RK
3614\f
3615;; Define the DImode operations that can be done in a small number
a6ec530c
RK
3616;; of instructions. The & constraints are to prevent the register
3617;; allocator from allocating registers that overlap with the inputs
3618;; (for example, having an input in 7,8 and an output in 6,7). We
3619;; also allow for the the output being the same as one of the inputs.
3620
266eb58a 3621(define_insn "*adddi3_noppc64"
a6ec530c
RK
3622 [(set (match_operand:DI 0 "gpc_reg_operand" "=&r,&r,r,r")
3623 (plus:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,0,0")
3624 (match_operand:DI 2 "reg_or_short_operand" "r,I,r,I")))]
e1f83b4d 3625 "! TARGET_POWERPC64"
0f645302
MM
3626 "*
3627{
3628 if (WORDS_BIG_ENDIAN)
3629 return (GET_CODE (operands[2])) != CONST_INT
3630 ? \"{a|addc} %L0,%L1,%L2\;{ae|adde} %0,%1,%2\"
3631 : \"{ai|addic} %L0,%L1,%2\;{a%G2e|add%G2e} %0,%1\";
3632 else
3633 return (GET_CODE (operands[2])) != CONST_INT
3634 ? \"{a|addc} %0,%1,%2\;{ae|adde} %L0,%L1,%L2\"
3635 : \"{ai|addic} %0,%1,%2\;{a%G2e|add%G2e} %L0,%L1\";
3636}"
b19003d8 3637 [(set_attr "length" "8")])
1fd4e8c1 3638
266eb58a 3639(define_insn "*subdi3_noppc64"
e7e5df70
RK
3640 [(set (match_operand:DI 0 "gpc_reg_operand" "=&r,&r,r,r,r")
3641 (minus:DI (match_operand:DI 1 "reg_or_short_operand" "r,I,0,r,I")
3642 (match_operand:DI 2 "gpc_reg_operand" "r,r,r,0,0")))]
266eb58a 3643 "! TARGET_POWERPC64"
5502823b
RK
3644 "*
3645{
0f645302
MM
3646 if (WORDS_BIG_ENDIAN)
3647 return (GET_CODE (operands[1]) != CONST_INT)
3648 ? \"{sf|subfc} %L0,%L2,%L1\;{sfe|subfe} %0,%2,%1\"
3649 : \"{sfi|subfic} %L0,%L2,%1\;{sf%G1e|subf%G1e} %0,%2\";
3650 else
3651 return (GET_CODE (operands[1]) != CONST_INT)
3652 ? \"{sf|subfc} %0,%2,%1\;{sfe|subfe} %L0,%L2,%L1\"
3653 : \"{sfi|subfic} %0,%2,%1\;{sf%G1e|subf%G1e} %L0,%L2\";
5502823b 3654}"
ca7f5001
RK
3655 [(set_attr "length" "8")])
3656
266eb58a 3657(define_insn "*negdi2_noppc64"
a6ec530c
RK
3658 [(set (match_operand:DI 0 "gpc_reg_operand" "=&r,r")
3659 (neg:DI (match_operand:DI 1 "gpc_reg_operand" "r,0")))]
51b8fc2c 3660 "! TARGET_POWERPC64"
5502823b
RK
3661 "*
3662{
3663 return (WORDS_BIG_ENDIAN)
3664 ? \"{sfi|subfic} %L0,%L1,0\;{sfze|subfze} %0,%1\"
3665 : \"{sfi|subfic} %0,%1,0\;{sfze|subfze} %L0,%L1\";
3666}"
ca7f5001
RK
3667 [(set_attr "length" "8")])
3668
8ffd9c51
RK
3669(define_expand "mulsidi3"
3670 [(set (match_operand:DI 0 "gpc_reg_operand" "")
3671 (mult:DI (sign_extend:DI (match_operand:SI 1 "gpc_reg_operand" ""))
3672 (sign_extend:DI (match_operand:SI 2 "gpc_reg_operand" ""))))]
3673 ""
3674 "
3675{
3676 if (! TARGET_POWER && ! TARGET_POWERPC)
3677 {
4c0c634c
MM
3678 emit_move_insn (gen_rtx (REG, SImode, 3), operands[1]);
3679 emit_move_insn (gen_rtx (REG, SImode, 4), operands[2]);
fada905b 3680 emit_insn (gen_mull_call ());
cf27b467
MM
3681 if (WORDS_BIG_ENDIAN)
3682 emit_move_insn (operands[0], gen_rtx (REG, DImode, 3));
3683 else
3684 {
3685 emit_move_insn (operand_subword (operands[0], 0, 0, DImode),
3686 gen_rtx (REG, SImode, 3));
3687 emit_move_insn (operand_subword (operands[0], 1, 0, DImode),
3688 gen_rtx (REG, SImode, 4));
3689 }
8ffd9c51
RK
3690 DONE;
3691 }
3692 else if (TARGET_POWER)
3693 {
3694 emit_insn (gen_mulsidi3_mq (operands[0], operands[1], operands[2]));
3695 DONE;
3696 }
3697}")
deb9225a 3698
8ffd9c51 3699(define_insn "mulsidi3_mq"
cd2b37d9 3700 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
8ffd9c51 3701 (mult:DI (sign_extend:DI (match_operand:SI 1 "gpc_reg_operand" "%r"))
cd2b37d9 3702 (sign_extend:DI (match_operand:SI 2 "gpc_reg_operand" "r"))))
1fd4e8c1 3703 (clobber (match_scratch:SI 3 "=q"))]
ca7f5001 3704 "TARGET_POWER"
b19003d8 3705 "mul %0,%1,%2\;mfmq %L0"
8ffd9c51
RK
3706 [(set_attr "type" "imul")
3707 (set_attr "length" "8")])
deb9225a 3708
ebedb4dd 3709(define_insn "*mulsidi3_powerpc"
425c176f 3710 [(set (match_operand:DI 0 "gpc_reg_operand" "=&r")
8ffd9c51
RK
3711 (mult:DI (sign_extend:DI (match_operand:SI 1 "gpc_reg_operand" "%r"))
3712 (sign_extend:DI (match_operand:SI 2 "gpc_reg_operand" "r"))))]
425c176f 3713 "TARGET_POWERPC && ! TARGET_POWERPC64"
5502823b
RK
3714 "*
3715{
3716 return (WORDS_BIG_ENDIAN)
3717 ? \"mulhw %0,%1,%2\;mullw %L0,%1,%2\"
3718 : \"mulhw %L0,%1,%2\;mullw %0,%1,%2\";
3719}"
8ffd9c51
RK
3720 [(set_attr "type" "imul")
3721 (set_attr "length" "8")])
deb9225a 3722
ebedb4dd
MM
3723(define_split
3724 [(set (match_operand:DI 0 "gpc_reg_operand" "")
3725 (mult:DI (sign_extend:DI (match_operand:SI 1 "gpc_reg_operand" ""))
3726 (sign_extend:DI (match_operand:SI 2 "gpc_reg_operand" ""))))]
cf27b467 3727 "TARGET_POWERPC && ! TARGET_POWERPC64 && reload_completed"
ebedb4dd
MM
3728 [(set (match_dup 3)
3729 (truncate:SI
3730 (lshiftrt:DI (mult:DI (sign_extend:DI (match_dup 1))
3731 (sign_extend:DI (match_dup 2)))
3732 (const_int 32))))
3733 (set (match_dup 4)
3734 (mult:SI (match_dup 1)
3735 (match_dup 2)))]
3736 "
3737{
3738 int endian = (WORDS_BIG_ENDIAN == 0);
3739 operands[3] = operand_subword (operands[0], endian, 0, DImode);
3740 operands[4] = operand_subword (operands[0], 1 - endian, 0, DImode);
3741}")
3742
8106dc08
MM
3743(define_insn "umulsidi3"
3744 [(set (match_operand:DI 0 "gpc_reg_operand" "=&r")
3745 (mult:DI (zero_extend:DI (match_operand:SI 1 "gpc_reg_operand" "%r"))
3746 (zero_extend:DI (match_operand:SI 2 "gpc_reg_operand" "r"))))]
3747 "TARGET_POWERPC && ! TARGET_POWERPC64"
3748 "*
3749{
3750 return (WORDS_BIG_ENDIAN)
3751 ? \"mulhwu %0,%1,%2\;mullw %L0,%1,%2\"
3752 : \"mulhwu %L0,%1,%2\;mullw %0,%1,%2\";
3753}"
3754 [(set_attr "type" "imul")
3755 (set_attr "length" "8")])
3756
ebedb4dd
MM
3757(define_split
3758 [(set (match_operand:DI 0 "gpc_reg_operand" "")
3759 (mult:DI (zero_extend:DI (match_operand:SI 1 "gpc_reg_operand" ""))
3760 (zero_extend:DI (match_operand:SI 2 "gpc_reg_operand" ""))))]
cf27b467 3761 "TARGET_POWERPC && ! TARGET_POWERPC64 && reload_completed"
ebedb4dd
MM
3762 [(set (match_dup 3)
3763 (truncate:SI
3764 (lshiftrt:DI (mult:DI (zero_extend:DI (match_dup 1))
3765 (zero_extend:DI (match_dup 2)))
3766 (const_int 32))))
3767 (set (match_dup 4)
3768 (mult:SI (match_dup 1)
3769 (match_dup 2)))]
3770 "
3771{
3772 int endian = (WORDS_BIG_ENDIAN == 0);
3773 operands[3] = operand_subword (operands[0], endian, 0, DImode);
3774 operands[4] = operand_subword (operands[0], 1 - endian, 0, DImode);
3775}")
3776
8ffd9c51
RK
3777(define_expand "smulsi3_highpart"
3778 [(set (match_operand:SI 0 "gpc_reg_operand" "")
3779 (truncate:SI
3780 (lshiftrt:DI (mult:DI (sign_extend:DI
3781 (match_operand:SI 1 "gpc_reg_operand" "%r"))
3782 (sign_extend:DI
3783 (match_operand:SI 2 "gpc_reg_operand" "r")))
3784 (const_int 32))))]
3785 ""
3786 "
3787{
3788 if (! TARGET_POWER && ! TARGET_POWERPC)
3789 {
3790 emit_move_insn (gen_rtx (REG, SImode, 3), operands[1]);
3791 emit_move_insn (gen_rtx (REG, SImode, 4), operands[2]);
fada905b 3792 emit_insn (gen_mulh_call ());
8ffd9c51
RK
3793 emit_move_insn (operands[0], gen_rtx (REG, SImode, 3));
3794 DONE;
3795 }
3796 else if (TARGET_POWER)
3797 {
3798 emit_insn (gen_smulsi3_highpart_mq (operands[0], operands[1], operands[2]));
3799 DONE;
3800 }
3801}")
deb9225a 3802
8ffd9c51
RK
3803(define_insn "smulsi3_highpart_mq"
3804 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
3805 (truncate:SI
fada905b
MM
3806 (lshiftrt:DI (mult:DI (sign_extend:DI
3807 (match_operand:SI 1 "gpc_reg_operand" "%r"))
3808 (sign_extend:DI
3809 (match_operand:SI 2 "gpc_reg_operand" "r")))
8ffd9c51
RK
3810 (const_int 32))))
3811 (clobber (match_scratch:SI 3 "=q"))]
3812 "TARGET_POWER"
3813 "mul %0,%1,%2"
3814 [(set_attr "type" "imul")])
deb9225a 3815
fada905b 3816(define_insn ""
8ffd9c51
RK
3817 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
3818 (truncate:SI
fada905b
MM
3819 (lshiftrt:DI (mult:DI (sign_extend:DI
3820 (match_operand:SI 1 "gpc_reg_operand" "%r"))
3821 (sign_extend:DI
3822 (match_operand:SI 2 "gpc_reg_operand" "r")))
8ffd9c51
RK
3823 (const_int 32))))]
3824 "TARGET_POWERPC"
3825 "mulhw %0,%1,%2"
3826 [(set_attr "type" "imul")])
deb9225a 3827
266eb58a
DE
3828(define_insn "umulsi3_highpart"
3829 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
3830 (truncate:SI
3831 (lshiftrt:DI (mult:DI (zero_extend:DI
3832 (match_operand:SI 1 "gpc_reg_operand" "%r"))
3833 (zero_extend:DI
3834 (match_operand:SI 2 "gpc_reg_operand" "r")))
3835 (const_int 32))))]
3836 "TARGET_POWERPC"
3837 "mulhwu %0,%1,%2"
3838 [(set_attr "type" "imul")])
3839
3840;; If operands 0 and 2 are in the same register, we have a problem. But
3841;; operands 0 and 1 (the usual case) can be in the same register. That's
3842;; why we have the strange constraints below.
3843(define_insn "ashldi3_power"
3844 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,&r")
3845 (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,0,r")
3846 (match_operand:SI 2 "reg_or_cint_operand" "M,i,r,r")))
3847 (clobber (match_scratch:SI 3 "=X,q,q,q"))]
3848 "TARGET_POWER"
3849 "@
3850 {sli|slwi} %0,%L1,%h2\;{cal %L0,0(0)|li %L0,0}
3851 sl%I2q %L0,%L1,%h2\;sll%I2q %0,%1,%h2
3852 sl%I2q %L0,%L1,%h2\;sll%I2q %0,%1,%h2
3853 sl%I2q %L0,%L1,%h2\;sll%I2q %0,%1,%h2"
3854 [(set_attr "length" "8")])
3855
3856(define_insn "lshrdi3_power"
3857 [(set (match_operand:DI 0 "gpc_reg_operand" "=&r,r,r,&r")
3858 (lshiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,0,r")
3859 (match_operand:SI 2 "reg_or_cint_operand" "M,i,r,r")))
3860 (clobber (match_scratch:SI 3 "=X,q,q,q"))]
3861 "TARGET_POWER"
3862 "@
3863 {cal %0,0(0)|li %0,0}\;{s%A2i|s%A2wi} %L0,%1,%h2
3864 sr%I2q %0,%1,%h2\;srl%I2q %L0,%L1,%h2
3865 sr%I2q %0,%1,%h2\;srl%I2q %L0,%L1,%h2
3866 sr%I2q %0,%1,%h2\;srl%I2q %L0,%L1,%h2"
3867 [(set_attr "length" "8")])
3868
3869;; Shift by a variable amount is too complex to be worth open-coding. We
3870;; just handle shifts by constants.
3871(define_insn "ashrdi3_power"
3872 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
3873 (ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
3874 (match_operand:SI 2 "const_int_operand" "M,i")))
3875 (clobber (match_scratch:SI 3 "=X,q"))]
3876 "TARGET_POWER"
3877 "@
3878 {srai|srawi} %0,%1,31\;{srai|srawi} %L0,%1,%h2
3879 sraiq %0,%1,%h2\;srliq %L0,%L1,%h2"
3880 [(set_attr "length" "8")])
3881\f
3882;; PowerPC64 DImode operations.
3883
3884(define_expand "adddi3"
3885 [(set (match_operand:DI 0 "gpc_reg_operand" "")
3886 (plus:DI (match_operand:DI 1 "gpc_reg_operand" "")
3887 (match_operand:DI 2 "add_operand" "")))]
3888 ""
3889 "
3890{
3891 if (! TARGET_POWERPC64 && non_add_cint_operand (operands[2], DImode))
3892 FAIL;
3893}")
3894
3895;; Discourage ai/addic because of carry but provide it in an alternative
3896;; allowing register zero as source.
3897
3898(define_insn ""
3899 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,?r,r")
3900 (plus:DI (match_operand:DI 1 "gpc_reg_operand" "%r,b,r,b")
3901 (match_operand:DI 2 "add_operand" "r,I,I,J")))]
3902 "TARGET_POWERPC64"
3903 "@
3904 add %0,%1,%2
3905 addi %0,%1,%2
3906 addic %0,%1,%2
3907 addis %0,%1,%u2")
3908
3909(define_insn ""
3910 [(set (match_operand:CC 0 "cc_reg_operand" "=x,x")
3911 (compare:CC (plus:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r")
3912 (match_operand:DI 2 "reg_or_short_operand" "r,I"))
3913 (const_int 0)))
3914 (clobber (match_scratch:DI 3 "=r,r"))]
3915 "TARGET_POWERPC64"
3916 "@
3917 add. %3,%1,%2
3918 addic. %3,%1,%2"
3919 [(set_attr "type" "compare")])
3920
3921(define_insn ""
3922 [(set (match_operand:CC 3 "cc_reg_operand" "=x,x")
3923 (compare:CC (plus:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r")
3924 (match_operand:DI 2 "reg_or_short_operand" "r,I"))
3925 (const_int 0)))
3926 (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
3927 (plus:DI (match_dup 1) (match_dup 2)))]
3928 "TARGET_POWERPC64"
3929 "@
3930 add. %0,%1,%2
3931 addic. %0,%1,%2"
3932 [(set_attr "type" "compare")])
3933
3934;; Split an add that we can't do in one insn into two insns, each of which
3935;; does one 16-bit part. This is used by combine. Note that the low-order
3936;; add should be last in case the result gets used in an address.
3937
3938(define_split
3939 [(set (match_operand:DI 0 "gpc_reg_operand" "")
3940 (plus:DI (match_operand:DI 1 "gpc_reg_operand" "")
3941 (match_operand:DI 2 "non_add_cint_operand" "")))]
3942 "TARGET_POWERPC64"
3943 [(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 3)))
3944 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 4)))]
3945"
3946{
3947 int low = INTVAL (operands[2]) & 0xffff;
3948 int high = (unsigned) INTVAL (operands[2]) >> 16;
3949
3950 if (low & 0x8000)
3951 high++, low |= 0xffff0000;
3952
3953 operands[3] = gen_rtx (CONST_INT, VOIDmode, high << 16);
3954 operands[4] = gen_rtx (CONST_INT, VOIDmode, low);
3955}")
3956
3957(define_insn "one_cmpldi2"
3958 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3959 (not:DI (match_operand:DI 1 "gpc_reg_operand" "r")))]
3960 "TARGET_POWERPC64"
3961 "nor %0,%1,%1")
3962
3963(define_insn ""
3964 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
3965 (compare:CC (not:DI (match_operand:DI 1 "gpc_reg_operand" "r"))
3966 (const_int 0)))
3967 (clobber (match_scratch:DI 2 "=r"))]
3968 "TARGET_POWERPC64"
3969 "nor. %2,%1,%1"
3970 [(set_attr "type" "compare")])
3971
3972(define_insn ""
3973 [(set (match_operand:CC 2 "cc_reg_operand" "=x")
3974 (compare:CC (not:DI (match_operand:DI 1 "gpc_reg_operand" "r"))
3975 (const_int 0)))
3976 (set (match_operand:DI 0 "gpc_reg_operand" "=r")
3977 (not:DI (match_dup 1)))]
3978 "TARGET_POWERPC64"
3979 "nor. %0,%2,%1"
3980 [(set_attr "type" "compare")])
3981
3982(define_insn ""
3983 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
3984 (minus:DI (match_operand:DI 1 "reg_or_short_operand" "r,I")
3985 (match_operand:DI 2 "gpc_reg_operand" "r,r")))]
3986 "TARGET_POWERPC64"
3987 "@
3988 subf %0,%2,%1
3989 subfic %0,%2,%1")
3990
3991(define_insn ""
3992 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
3993 (compare:CC (minus:DI (match_operand:DI 1 "gpc_reg_operand" "r")
3994 (match_operand:DI 2 "gpc_reg_operand" "r"))
3995 (const_int 0)))
3996 (clobber (match_scratch:DI 3 "=r"))]
3997 "TARGET_POWERPC64"
3998 "subf. %3,%2,%1"
3999 [(set_attr "type" "compare")])
4000
4001(define_insn ""
4002 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
4003 (compare:CC (minus:DI (match_operand:DI 1 "gpc_reg_operand" "r")
4004 (match_operand:DI 2 "gpc_reg_operand" "r"))
4005 (const_int 0)))
4006 (set (match_operand:DI 0 "gpc_reg_operand" "=r")
4007 (minus:DI (match_dup 1) (match_dup 2)))]
4008 "TARGET_POWERPC64"
4009 "subf. %0,%2,%1"
4010 [(set_attr "type" "compare")])
4011
4012(define_expand "subdi3"
4013 [(set (match_operand:DI 0 "gpc_reg_operand" "")
4014 (minus:DI (match_operand:DI 1 "reg_or_short_operand" "")
4015 (match_operand:DI 2 "reg_or_cint_operand" "")))]
4016 ""
4017 "
4018{
4019 if (GET_CODE (operands[2]) == CONST_INT)
4020 {
4021 emit_insn (gen_adddi3 (operands[0], operands[1],
4022 negate_rtx (DImode, operands[2])));
4023 DONE;
4024 }
4025}")
4026
4027(define_insn "absdi2"
4028 [(set (match_operand:DI 0 "gpc_reg_operand" "=&r,r")
4029 (abs:DI (match_operand:DI 1 "gpc_reg_operand" "r,0")))
4030 (clobber (match_scratch:DI 2 "=&r,&r"))]
4031 "TARGET_POWERPC64"
4032 "sradi %2,%1,31\;xor %0,%2,%1\;subf %0,%2,%0"
4033 [(set_attr "length" "12")])
4034
4035(define_split
4036 [(set (match_operand:DI 0 "gpc_reg_operand" "=&r,r")
4037 (abs:DI (match_operand:DI 1 "gpc_reg_operand" "r,0")))
4038 (clobber (match_scratch:DI 2 "=&r,&r"))]
4039 "TARGET_POWERPC64 && reload_completed"
4040 [(set (match_dup 2) (ashiftrt:DI (match_dup 1) (const_int 31)))
4041 (set (match_dup 0) (xor:DI (match_dup 2) (match_dup 1)))
4042 (set (match_dup 0) (minus:DI (match_dup 2) (match_dup 0)))]
4043 "")
4044
4045(define_insn ""
4046 [(set (match_operand:DI 0 "gpc_reg_operand" "=&r,r")
4047 (neg:DI (abs:DI (match_operand:DI 1 "gpc_reg_operand" "r,0"))))
4048 (clobber (match_scratch:DI 2 "=&r,&r"))]
4049 "TARGET_POWERPC64"
4050 "sradi %2,%1,31\;xor %0,%2,%1\;subf %0,%0,%2"
4051 [(set_attr "length" "12")])
4052
4053(define_split
4054 [(set (match_operand:DI 0 "gpc_reg_operand" "=&r,r")
4055 (neg:DI (abs:DI (match_operand:DI 1 "gpc_reg_operand" "r,0"))))
4056 (clobber (match_scratch:DI 2 "=&r,&r"))]
4057 "TARGET_POWERPC64 && reload_completed"
4058 [(set (match_dup 2) (ashiftrt:DI (match_dup 1) (const_int 31)))
4059 (set (match_dup 0) (xor:DI (match_dup 2) (match_dup 1)))
4060 (set (match_dup 0) (minus:DI (match_dup 0) (match_dup 2)))]
4061 "")
4062
4063(define_expand "negdi2"
4064 [(set (match_operand:DI 0 "gpc_reg_operand" "")
4065 (neg:DI (match_operand:DI 1 "gpc_reg_operand" "")))]
4066 ""
4067 "")
4068
4069(define_insn ""
4070 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4071 (neg:DI (match_operand:DI 1 "gpc_reg_operand" "r")))]
4072 "TARGET_POWERPC64"
4073 "neg %0,%1")
4074
4075(define_insn ""
4076 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
4077 (compare:CC (neg:DI (match_operand:DI 1 "gpc_reg_operand" "r"))
4078 (const_int 0)))
4079 (clobber (match_scratch:DI 2 "=r"))]
4080 "TARGET_POWERPC64"
4081 "neg. %2,%1"
4082 [(set_attr "type" "compare")])
4083
4084(define_insn ""
4085 [(set (match_operand:CC 2 "cc_reg_operand" "=x")
4086 (compare:CC (neg:DI (match_operand:DI 1 "gpc_reg_operand" "r"))
4087 (const_int 0)))
4088 (set (match_operand:DI 0 "gpc_reg_operand" "=r")
4089 (neg:DI (match_dup 1)))]
4090 "TARGET_POWERPC64"
4091 "neg. %0,%1"
4092 [(set_attr "type" "compare")])
4093
4094(define_insn "ffsdi2"
4095 [(set (match_operand:DI 0 "gpc_reg_operand" "=&r")
4096 (ffs:DI (match_operand:DI 1 "gpc_reg_operand" "r")))]
4097 "TARGET_POWERPC64"
4098 "neg %0,%1\;and %0,%0,%1\;cntlzd %0,%0\;subfic %0,%0,64"
4099 [(set_attr "length" "16")])
4100
4101(define_insn "muldi3"
4102 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4103 (mult:DI (match_operand:DI 1 "gpc_reg_operand" "%r")
4104 (match_operand:DI 2 "gpc_reg_operand" "r")))]
4105 "TARGET_POWERPC64"
4106 "mulld %0,%1,%2"
4107 [(set_attr "type" "imul")])
4108
4109(define_insn "smuldi3_highpart"
4110 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4111 (truncate:DI
4112 (lshiftrt:TI (mult:TI (sign_extend:TI
4113 (match_operand:DI 1 "gpc_reg_operand" "%r"))
4114 (sign_extend:TI
4115 (match_operand:DI 2 "gpc_reg_operand" "r")))
4116 (const_int 64))))]
4117 "TARGET_POWERPC64"
4118 "mulhd %0,%1,%2"
4119 [(set_attr "type" "imul")])
4120
4121(define_insn "umuldi3_highpart"
4122 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4123 (truncate:DI
4124 (lshiftrt:TI (mult:TI (zero_extend:TI
4125 (match_operand:DI 1 "gpc_reg_operand" "%r"))
4126 (zero_extend:TI
4127 (match_operand:DI 2 "gpc_reg_operand" "r")))
4128 (const_int 64))))]
4129 "TARGET_POWERPC64"
4130 "mulhdu %0,%1,%2"
4131 [(set_attr "type" "imul")])
4132
4133(define_expand "divdi3"
4134 [(set (match_operand:DI 0 "gpc_reg_operand" "")
4135 (div:DI (match_operand:DI 1 "gpc_reg_operand" "")
4136 (match_operand:DI 2 "reg_or_cint_operand" "")))]
4137 "TARGET_POWERPC64"
4138 "
4139{
4140 if (GET_CODE (operands[2]) == CONST_INT
4141 && exact_log2 (INTVAL (operands[2])) >= 0)
4142 ;
4143 else
4144 operands[2] = force_reg (DImode, operands[2]);
4145}")
4146
4147(define_expand "moddi3"
4148 [(use (match_operand:DI 0 "gpc_reg_operand" ""))
4149 (use (match_operand:DI 1 "gpc_reg_operand" ""))
4150 (use (match_operand:DI 2 "reg_or_cint_operand" ""))]
4151 "TARGET_POWERPC64"
4152 "
4153{
4154 int i = exact_log2 (INTVAL (operands[2]));
4155 rtx temp1;
4156 rtx temp2;
4157
4158 if (GET_CODE (operands[2]) != CONST_INT || i < 0)
4159 FAIL;
4160
4161 temp1 = gen_reg_rtx (DImode);
4162 temp2 = gen_reg_rtx (DImode);
4163
4164 emit_insn (gen_divdi3 (temp1, operands[1], operands[2]));
4165 emit_insn (gen_ashldi3 (temp2, temp1, GEN_INT (i)));
4166 emit_insn (gen_subdi3 (operands[0], operands[1], temp2));
4167 DONE;
4168}")
4169
4170(define_insn ""
4171 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4172 (div:DI (match_operand:DI 1 "gpc_reg_operand" "r")
4173 (match_operand:DI 2 "const_int_operand" "N")))]
4174 "TARGET_POWERPC64 && exact_log2 (INTVAL (operands[2])) >= 0"
4175 "sradi %0,%1,%p2\;addze %0,%0"
4176 [(set_attr "length" "8")])
4177
4178(define_insn ""
4179 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
4180 (compare:CC (div:DI (match_operand:DI 1 "gpc_reg_operand" "r")
4181 (match_operand:DI 2 "const_int_operand" "N"))
4182 (const_int 0)))
4183 (clobber (match_scratch:DI 3 "=r"))]
4184 "TARGET_POWERPC64 && exact_log2 (INTVAL (operands[2])) >= 0"
4185 "sradi %3,%1,%p2\;addze. %3,%3"
4186 [(set_attr "type" "compare")
4187 (set_attr "length" "8")])
4188
4189(define_insn ""
4190 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
4191 (compare:CC (div:DI (match_operand:DI 1 "gpc_reg_operand" "r")
4192 (match_operand:DI 2 "const_int_operand" "N"))
4193 (const_int 0)))
4194 (set (match_operand:DI 0 "gpc_reg_operand" "=r")
4195 (div:DI (match_dup 1) (match_dup 2)))]
4196 "TARGET_POWERPC64 && exact_log2 (INTVAL (operands[2])) >= 0"
4197 "sradi %0,%1,%p2\;addze. %0,%0"
4198 [(set_attr "type" "compare")
4199 (set_attr "length" "8")])
4200
4201(define_insn ""
4202 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4203 (div:DI (match_operand:DI 1 "gpc_reg_operand" "r")
4204 (match_operand:DI 2 "gpc_reg_operand" "r")))]
4205 "TARGET_POWERPC64"
4206 "divd %0,%1,%2"
4207 [(set_attr "type" "idiv")])
4208
4209(define_insn "udivdi3"
4210 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4211 (udiv:DI (match_operand:DI 1 "gpc_reg_operand" "r")
4212 (match_operand:DI 2 "gpc_reg_operand" "r")))]
4213 "TARGET_POWERPC64"
4214 "divdu %0,%1,%2"
4215 [(set_attr "type" "idiv")])
4216
4217(define_insn "rotldi3"
4218 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4219 (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r")
4220 (match_operand:DI 2 "reg_or_cint_operand" "ri")))]
4221 "TARGET_POWERPC64"
4222 "rld%I2cl %0,%1,%h2,0")
4223
4224(define_insn ""
4225 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
4226 (compare:CC (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r")
4227 (match_operand:DI 2 "reg_or_cint_operand" "ri"))
4228 (const_int 0)))
4229 (clobber (match_scratch:DI 3 "=r"))]
4230 "TARGET_POWERPC64"
4231 "rld%I2cl. %3,%1,%h2,0"
4232 [(set_attr "type" "delayed_compare")])
4233
4234(define_insn ""
4235 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
4236 (compare:CC (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r")
4237 (match_operand:DI 2 "reg_or_cint_operand" "ri"))
4238 (const_int 0)))
4239 (set (match_operand:DI 0 "gpc_reg_operand" "=r")
4240 (rotate:DI (match_dup 1) (match_dup 2)))]
4241 "TARGET_POWERPC64"
4242 "rld%I2cl. %0,%1,%h2,0"
4243 [(set_attr "type" "delayed_compare")])
4244
4245(define_expand "ashldi3"
4246 [(set (match_operand:DI 0 "gpc_reg_operand" "")
4247 (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "")
4248 (match_operand:SI 2 "reg_or_cint_operand" "")))]
4249 "TARGET_POWERPC64 || TARGET_POWER"
4250 "
4251{
4252 if (TARGET_POWERPC64)
4253 ;
4254 else if (TARGET_POWER)
4255 {
4256 emit_insn (gen_ashldi3_power (operands[0], operands[1], operands[2]));
4257 DONE;
4258 }
4259 else
4260 FAIL;
4261}")
4262
4263(define_insn ""
4264 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4265 (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r")
4266 (match_operand:SI 2 "reg_or_cint_operand" "ri")))]
4267 "TARGET_POWERPC64"
4268 "sld%I2 %0,%1,%2"
4269 [(set_attr "length" "8")])
4270
4271(define_insn ""
4272 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
4273 (compare:CC (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r")
4274 (match_operand:SI 2 "reg_or_cint_operand" "ri"))
4275 (const_int 0)))
4276 (clobber (match_scratch:DI 3 "=r"))]
4277 "TARGET_POWERPC64"
4278 "sld%I2. %3,%1,%2"
4279 [(set_attr "type" "delayed_compare")])
4280
4281(define_insn ""
4282 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
4283 (compare:CC (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r")
4284 (match_operand:SI 2 "reg_or_cint_operand" "ri"))
4285 (const_int 0)))
4286 (set (match_operand:DI 0 "gpc_reg_operand" "=r")
4287 (ashift:DI (match_dup 1) (match_dup 2)))]
4288 "TARGET_POWERPC64"
4289 "sld%I2. %0,%1,%2"
4290 [(set_attr "type" "delayed_compare")])
4291
4292(define_expand "lshrdi3"
4293 [(set (match_operand:DI 0 "gpc_reg_operand" "")
4294 (lshiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "")
4295 (match_operand:SI 2 "reg_or_cint_operand" "")))]
4296 "TARGET_POWERPC64 || TARGET_POWER"
4297 "
4298{
4299 if (TARGET_POWERPC64)
4300 ;
4301 else if (TARGET_POWER)
4302 {
4303 emit_insn (gen_lshrdi3_power (operands[0], operands[1], operands[2]));
4304 DONE;
4305 }
4306 else
4307 FAIL;
4308}")
4309
4310(define_insn ""
4311 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4312 (lshiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r")
4313 (match_operand:SI 2 "reg_or_cint_operand" "ri")))]
4314 "TARGET_POWERPC64"
4315 "srd%I2 %0,%1,%2")
4316
4317(define_insn ""
4318 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
4319 (compare:CC (lshiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r")
4320 (match_operand:SI 2 "reg_or_cint_operand" "ri"))
4321 (const_int 0)))
4322 (clobber (match_scratch:DI 3 "=r"))]
4323 "TARGET_POWERPC64"
4324 "srd%I2. %3,%1,%2"
4325 [(set_attr "type" "delayed_compare")])
4326
4327(define_insn ""
4328 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
4329 (compare:CC (lshiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r")
4330 (match_operand:SI 2 "reg_or_cint_operand" "ri"))
4331 (const_int 0)))
4332 (set (match_operand:DI 0 "gpc_reg_operand" "=r")
4333 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
4334 "TARGET_POWERPC64"
4335 "srd%I2. %0,%1,%2"
4336 [(set_attr "type" "delayed_compare")])
4337
4338(define_expand "ashrdi3"
4339 [(set (match_operand:DI 0 "gpc_reg_operand" "")
4340 (ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "")
4341 (match_operand:SI 2 "reg_or_cint_operand" "")))]
4342 "TARGET_POWERPC64 || TARGET_POWER"
4343 "
4344{
4345 if (TARGET_POWERPC64)
4346 ;
4347 else if (TARGET_POWER && GET_CODE (operands[2]) == CONST_INT)
4348 {
4349 emit_insn (gen_ashrdi3_power (operands[0], operands[1], operands[2]));
4350 DONE;
4351 }
4352 else
4353 FAIL;
4354}")
4355
4356(define_insn ""
4357 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4358 (ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r")
4359 (match_operand:SI 2 "reg_or_cint_operand" "ri")))]
4360 "TARGET_POWERPC64"
4361 "srad%I2 %0,%1,%2")
4362
4363(define_insn ""
4364 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
4365 (compare:CC (ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r")
4366 (match_operand:SI 2 "reg_or_cint_operand" "ri"))
4367 (const_int 0)))
4368 (clobber (match_scratch:DI 3 "=r"))]
4369 "TARGET_POWERPC64"
4370 "srad%I2. %3,%1,%2"
4371 [(set_attr "type" "delayed_compare")])
4372
4373(define_insn ""
4374 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
4375 (compare:CC (ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r")
4376 (match_operand:SI 2 "reg_or_cint_operand" "ri"))
4377 (const_int 0)))
4378 (set (match_operand:DI 0 "gpc_reg_operand" "=r")
4379 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
4380 "TARGET_POWERPC64"
4381 "srad%I2. %0,%1,%2"
4382 [(set_attr "type" "delayed_compare")])
4383
4384(define_insn "anddi3"
4385 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r")
4386 (and:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,r")
4387 (match_operand:DI 2 "and_operand" "?r,K,J")))
4388 (clobber (match_scratch:CC 3 "=X,x,x"))]
4389 "TARGET_POWERPC64"
4390 "@
4391 and %0,%1,%2
4392 andi. %0,%1,%b2
4393 andis. %0,%1,%u2")
4394
4395(define_insn ""
4396 [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,x")
4397 (compare:CC (and:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,r")
4398 (match_operand:DI 2 "and_operand" "r,K,J"))
4399 (const_int 0)))
4400 (clobber (match_scratch:DI 3 "=r,r,r"))]
4401 "TARGET_POWERPC64"
4402 "@
4403 and. %3,%1,%2
4404 andi. %3,%1,%b2
4405 andis. %3,%1,%u2"
4406 [(set_attr "type" "compare,compare,compare")])
4407
4408(define_insn ""
4409 [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,x")
4410 (compare:CC (and:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,r")
4411 (match_operand:DI 2 "and_operand" "r,K,J"))
4412 (const_int 0)))
4413 (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r")
4414 (and:DI (match_dup 1) (match_dup 2)))]
4415 "TARGET_POWERPC64"
4416 "@
4417 and. %0,%1,%2
4418 andi. %0,%1,%b2
4419 andis. %0,%1,%u2"
4420 [(set_attr "type" "compare,compare,compare")])
4421
4422;; Take a AND with a constant that cannot be done in a single insn and try to
4423;; split it into two insns. This does not verify that the insns are valid
4424;; since this need not be done as combine will do it.
4425
4426(define_split
4427 [(set (match_operand:DI 0 "gpc_reg_operand" "")
4428 (and:DI (match_operand:DI 1 "gpc_reg_operand" "")
4429 (match_operand:DI 2 "non_and_cint_operand" "")))]
4430 "TARGET_POWERPC64"
4431 [(set (match_dup 0) (and:DI (match_dup 1) (match_dup 3)))
4432 (set (match_dup 0) (and:DI (match_dup 0) (match_dup 4)))]
4433 "
4434{
4435 int maskval = INTVAL (operands[2]);
4436 int i, transitions, last_bit_value;
4437 int orig = maskval, first_c = maskval, second_c;
4438
4439 /* We know that MASKVAL must have more than 2 bit-transitions. Start at
4440 the low-order bit and count for the third transition. When we get there,
4441 make a first mask that has everything to the left of that position
4442 a one. Then make the second mask to turn off whatever else is needed. */
4443
4444 for (i = 1, transitions = 0, last_bit_value = maskval & 1; i < 32; i++)
4445 {
4446 if (((maskval >>= 1) & 1) != last_bit_value)
4447 last_bit_value ^= 1, transitions++;
4448
4449 if (transitions > 2)
4450 {
4451 first_c |= (~0) << i;
4452 break;
4453 }
4454 }
4455
4456 second_c = orig | ~ first_c;
4457
4458 operands[3] = gen_rtx (CONST_INT, VOIDmode, first_c);
4459 operands[4] = gen_rtx (CONST_INT, VOIDmode, second_c);
4460}")
4461
4462(define_insn "iordi3"
4463 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r")
4464 (ior:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,r")
4465 (match_operand:DI 2 "logical_operand" "r,K,J")))]
4466 "TARGET_POWERPC64"
4467 "@
4468 or %0,%1,%2
4469 ori %0,%1,%b2
4470 oris %0,%1,%u2")
4471
4472(define_insn ""
4473 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
4474 (compare:CC (ior:DI (match_operand:DI 1 "gpc_reg_operand" "%r")
4475 (match_operand:DI 2 "gpc_reg_operand" "r"))
4476 (const_int 0)))
4477 (clobber (match_scratch:DI 3 "=r"))]
4478 "TARGET_POWERPC64"
4479 "or. %3,%1,%2"
4480 [(set_attr "type" "compare")])
4481
4482(define_insn ""
4483 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
4484 (compare:CC (ior:DI (match_operand:DI 1 "gpc_reg_operand" "%r")
4485 (match_operand:DI 2 "gpc_reg_operand" "r"))
4486 (const_int 0)))
4487 (set (match_operand:DI 0 "gpc_reg_operand" "=r")
4488 (ior:DI (match_dup 1) (match_dup 2)))]
4489 "TARGET_POWERPC64"
4490 "or. %0,%1,%2"
4491 [(set_attr "type" "compare")])
4492
4493;; Split an IOR that we can't do in one insn into two insns, each of which
4494;; does one 16-bit part. This is used by combine.
4495
4496(define_split
4497 [(set (match_operand:DI 0 "gpc_reg_operand" "")
4498 (ior:DI (match_operand:DI 1 "gpc_reg_operand" "")
4499 (match_operand:DI 2 "non_logical_cint_operand" "")))]
4500 "TARGET_POWERPC64"
4501 [(set (match_dup 0) (ior:DI (match_dup 1) (match_dup 3)))
4502 (set (match_dup 0) (ior:DI (match_dup 0) (match_dup 4)))]
4503"
4504{
4505 operands[3] = gen_rtx (CONST_INT, VOIDmode,
4506 INTVAL (operands[2]) & 0xffff0000);
4507 operands[4] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) & 0xffff);
4508}")
1fd4e8c1 4509
266eb58a
DE
4510(define_insn "xordi3"
4511 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r")
4512 (xor:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,r")
4513 (match_operand:DI 2 "logical_operand" "r,K,J")))]
4514 "TARGET_POWERPC64"
1fd4e8c1 4515 "@
266eb58a
DE
4516 xor %0,%1,%2
4517 xori %0,%1,%b2
4518 xoris %0,%1,%u2")
1fd4e8c1 4519
266eb58a
DE
4520(define_insn ""
4521 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
4522 (compare:CC (xor:DI (match_operand:DI 1 "gpc_reg_operand" "%r")
4523 (match_operand:DI 2 "gpc_reg_operand" "r"))
4524 (const_int 0)))
4525 (clobber (match_scratch:DI 3 "=r"))]
4526 "TARGET_POWERPC64"
4527 "xor. %3,%1,%2"
4528 [(set_attr "type" "compare")])
1fd4e8c1 4529
266eb58a
DE
4530(define_insn ""
4531 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
4532 (compare:CC (xor:DI (match_operand:DI 1 "gpc_reg_operand" "%r")
4533 (match_operand:DI 2 "gpc_reg_operand" "r"))
4534 (const_int 0)))
4535 (set (match_operand:DI 0 "gpc_reg_operand" "=r")
4536 (xor:DI (match_dup 1) (match_dup 2)))]
4537 "TARGET_POWERPC64"
4538 "xor. %0,%1,%2"
4539 [(set_attr "type" "compare")])
1fd4e8c1 4540
266eb58a
DE
4541;; Split an XOR that we can't do in one insn into two insns, each of which
4542;; does one 16-bit part. This is used by combine.
4543
4544(define_split
4545 [(set (match_operand:DI 0 "gpc_reg_operand" "")
4546 (xor:DI (match_operand:DI 1 "gpc_reg_operand" "")
4547 (match_operand:DI 2 "non_logical_cint_operand" "")))]
4548 "TARGET_POWERPC64"
4549 [(set (match_dup 0) (xor:DI (match_dup 1) (match_dup 3)))
4550 (set (match_dup 0) (xor:DI (match_dup 0) (match_dup 4)))]
4551"
4552{
4553 operands[3] = gen_rtx (CONST_INT, VOIDmode,
4554 INTVAL (operands[2]) & 0xffff0000);
4555 operands[4] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) & 0xffff);
1fd4e8c1
RK
4556}")
4557
2bee0449 4558(define_insn ""
266eb58a
DE
4559 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4560 (not:DI (xor:DI (match_operand:DI 1 "gpc_reg_operand" "%r")
4561 (match_operand:DI 2 "gpc_reg_operand" "r"))))]
4562 "TARGET_POWERPC64"
4563 "eqv %0,%1,%2")
a473029f 4564
266eb58a
DE
4565(define_insn ""
4566 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
4567 (compare:CC (not:DI (xor:DI (match_operand:DI 1 "gpc_reg_operand" "%r")
4568 (match_operand:DI 2 "gpc_reg_operand" "r")))
4569 (const_int 0)))
4570 (clobber (match_scratch:DI 3 "=r"))]
4571 "TARGET_POWERPC64"
4572 "eqv. %3,%1,%2"
4573 [(set_attr "type" "compare")])
a473029f 4574
266eb58a
DE
4575(define_insn ""
4576 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
4577 (compare:CC (not:DI (xor:DI (match_operand:DI 1 "gpc_reg_operand" "%r")
4578 (match_operand:DI 2 "gpc_reg_operand" "r")))
4579 (const_int 0)))
4580 (set (match_operand:DI 0 "gpc_reg_operand" "=r")
4581 (not:DI (xor:DI (match_dup 1) (match_dup 2))))]
4582 "TARGET_POWERPC64"
4583 "eqv. %0,%1,%2"
4584 [(set_attr "type" "compare")])
4585
4586(define_insn ""
a473029f 4587 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
266eb58a
DE
4588 (and:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "r"))
4589 (match_operand:DI 2 "gpc_reg_operand" "r")))]
a473029f 4590 "TARGET_POWERPC64"
266eb58a 4591 "andc %0,%2,%1")
a473029f 4592
266eb58a
DE
4593(define_insn ""
4594 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
4595 (compare:CC (and:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "r"))
4596 (match_operand:DI 2 "gpc_reg_operand" "r"))
4597 (const_int 0)))
4598 (clobber (match_scratch:DI 3 "=r"))]
a473029f 4599 "TARGET_POWERPC64"
266eb58a
DE
4600 "andc. %3,%2,%1"
4601 [(set_attr "type" "compare")])
a473029f 4602
266eb58a
DE
4603(define_insn ""
4604 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
4605 (compare:CC (and:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "r"))
4606 (match_operand:DI 2 "gpc_reg_operand" "r"))
4607 (const_int 0)))
4608 (set (match_operand:DI 0 "gpc_reg_operand" "=r")
4609 (and:DI (not:DI (match_dup 1)) (match_dup 2)))]
a473029f 4610 "TARGET_POWERPC64"
266eb58a
DE
4611 "andc. %0,%2,%1"
4612 [(set_attr "type" "compare")])
a473029f 4613
266eb58a 4614(define_insn ""
a473029f 4615 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
266eb58a
DE
4616 (ior:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "r"))
4617 (match_operand:DI 2 "gpc_reg_operand" "r")))]
a473029f 4618 "TARGET_POWERPC64"
266eb58a 4619 "orc %0,%2,%1")
a473029f 4620
266eb58a
DE
4621(define_insn ""
4622 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
4623 (compare:CC (ior:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "r"))
4624 (match_operand:DI 2 "gpc_reg_operand" "r"))
4625 (const_int 0)))
4626 (clobber (match_scratch:DI 3 "=r"))]
4627 "TARGET_POWERPC64"
4628 "orc. %3,%2,%1"
4629 [(set_attr "type" "compare")])
4630
4631(define_insn ""
4632 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
4633 (compare:CC (ior:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "r"))
4634 (match_operand:DI 2 "gpc_reg_operand" "r"))
4635 (const_int 0)))
4636 (set (match_operand:DI 0 "gpc_reg_operand" "=r")
4637 (ior:DI (not:DI (match_dup 1)) (match_dup 2)))]
4638 "TARGET_POWERPC64"
4639 "orc. %0,%2,%1"
4640 [(set_attr "type" "compare")])
4641
4642(define_insn ""
a473029f 4643 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
266eb58a
DE
4644 (ior:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "%r"))
4645 (not:DI (match_operand:DI 2 "gpc_reg_operand" "r"))))]
a473029f 4646 "TARGET_POWERPC64"
266eb58a 4647 "nand %0,%1,%2")
a473029f 4648
266eb58a
DE
4649(define_insn ""
4650 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
4651 (compare:CC (ior:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "%r"))
4652 (not:DI (match_operand:DI 2 "gpc_reg_operand" "r")))
4653 (const_int 0)))
4654 (clobber (match_scratch:DI 3 "=r"))]
4655 "TARGET_POWERPC64"
4656 "nand. %3,%1,%2"
4657 [(set_attr "type" "compare")])
4658
4659(define_insn ""
4660 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
4661 (compare:CC (ior:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "%r"))
4662 (not:DI (match_operand:DI 2 "gpc_reg_operand" "r")))
4663 (const_int 0)))
4664 (set (match_operand:DI 0 "gpc_reg_operand" "=r")
4665 (ior:DI (not:DI (match_dup 1)) (not:DI (match_dup 2))))]
4666 "TARGET_POWERPC64"
4667 "nand. %0,%1,%2"
4668 [(set_attr "type" "compare")])
4669
4670(define_insn ""
a473029f 4671 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
266eb58a
DE
4672 (and:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "%r"))
4673 (not:DI (match_operand:DI 2 "gpc_reg_operand" "r"))))]
a473029f 4674 "TARGET_POWERPC64"
266eb58a 4675 "nor %0,%1,%2")
a473029f
RK
4676
4677(define_insn ""
4678 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
266eb58a
DE
4679 (compare:CC (and:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "%r"))
4680 (not:DI (match_operand:DI 2 "gpc_reg_operand" "r")))
a473029f
RK
4681 (const_int 0)))
4682 (clobber (match_scratch:DI 3 "=r"))]
4683 "TARGET_POWERPC64"
266eb58a
DE
4684 "nor. %3,%1,%2"
4685 [(set_attr "type" "compare")])
a473029f
RK
4686
4687(define_insn ""
4688 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
266eb58a
DE
4689 (compare:CC (and:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "%r"))
4690 (not:DI (match_operand:DI 2 "gpc_reg_operand" "r")))
a473029f
RK
4691 (const_int 0)))
4692 (set (match_operand:DI 0 "gpc_reg_operand" "=r")
266eb58a 4693 (and:DI (not:DI (match_dup 1)) (not:DI (match_dup 2))))]
a473029f 4694 "TARGET_POWERPC64"
266eb58a
DE
4695 "nor. %0,%1,%2"
4696 [(set_attr "type" "compare")])
a473029f 4697\f
1fd4e8c1 4698;; Now define ways of moving data around.
4697a36c
MM
4699
4700;; Elf specific ways of loading addresses for non-PIC code.
4701;; The output of this could be r0, but we limit it to base
4702;; registers, since almost all uses of this will need it
4703;; in a base register shortly.
4704(define_insn "elf_high"
4705 [(set (match_operand:SI 0 "register_operand" "=b")
4706 (high:SI (match_operand 1 "" "")))]
4707 "TARGET_ELF && !TARGET_64BIT"
4708 "{cau|addis} %0,0,%1@ha")
4709
4710(define_insn "elf_low"
4711 [(set (match_operand:SI 0 "register_operand" "=r")
4712 (lo_sum:SI (match_operand:SI 1 "register_operand" "b")
4713 (match_operand 2 "" "")))]
4714 "TARGET_ELF && !TARGET_64BIT"
4715 "{cal %0,%a2@l(%1)|addi %0,%1,%2@l}")
4716
1fd4e8c1
RK
4717;; For SI, we special-case integers that can't be loaded in one insn. We
4718;; do the load 16-bits at a time. We could do this by loading from memory,
4719;; and this is even supposed to be faster, but it is simpler not to get
4720;; integers in the TOC.
4721(define_expand "movsi"
4722 [(set (match_operand:SI 0 "general_operand" "")
4723 (match_operand:SI 1 "any_operand" ""))]
4724 ""
4725 "
4726{
4727 if (GET_CODE (operands[0]) != REG)
4728 operands[1] = force_reg (SImode, operands[1]);
4729
ef0e171b
RK
4730 /* Convert a move of a CONST_DOUBLE into a CONST_INT */
4731 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4732 operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
4733
88228c4b
MM
4734 /* Use default pattern for address of ELF small data */
4735 if (TARGET_ELF
a54d04b7 4736 && DEFAULT_ABI == ABI_V4
88228c4b 4737 && (GET_CODE (operands[1]) == SYMBOL_REF || GET_CODE (operands[1]) == CONST)
e98bb982 4738 && small_data_operand (operands[1], SImode))
88228c4b
MM
4739 {
4740 emit_insn (gen_rtx (SET, VOIDmode, operands[0], operands[1]));
4741 DONE;
4742 }
4743
4697a36c
MM
4744 if (TARGET_ELF && TARGET_NO_TOC && !TARGET_64BIT
4745 && CONSTANT_P (operands[1])
4746 && GET_CODE (operands[1]) != HIGH
4747 && GET_CODE (operands[1]) != CONST_INT)
4748 {
4749 rtx target = (reload_completed || reload_in_progress)
4750 ? operands[0] : gen_reg_rtx (SImode);
4751
b6c9286a
MM
4752 /* If this is a function address on -mcall-aixdesc or -mcall-nt,
4753 convert it to the address of the descriptor. */
4754 if ((DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_NT)
4755 && GET_CODE (operands[1]) == SYMBOL_REF
4756 && XSTR (operands[1], 0)[0] == '.')
4757 {
4758 char *name = XSTR (operands[1], 0);
4759 rtx new_ref;
4760 while (*name == '.')
4761 name++;
4762 new_ref = gen_rtx (SYMBOL_REF, Pmode, name);
4763 CONSTANT_POOL_ADDRESS_P (new_ref) = CONSTANT_POOL_ADDRESS_P (operands[1]);
4764 SYMBOL_REF_FLAG (new_ref) = SYMBOL_REF_FLAG (operands[1]);
4765 SYMBOL_REF_USED (new_ref) = SYMBOL_REF_USED (operands[1]);
4766 operands[1] = new_ref;
4767 }
4768
4697a36c
MM
4769 emit_insn (gen_elf_high (target, operands[1]));
4770 emit_insn (gen_elf_low (operands[0], target, operands[1]));
4771 DONE;
4772 }
4773
b6c9286a
MM
4774 if (GET_CODE (operands[1]) == CONST
4775 && DEFAULT_ABI == ABI_NT
4776 && !side_effects_p (operands[0]))
4777 {
4778 rtx const_term = const0_rtx;
4779 rtx sym = eliminate_constant_term (XEXP (operands[1], 0), &const_term);
4780 if (sym && GET_CODE (const_term) == CONST_INT
4781 && (GET_CODE (sym) == SYMBOL_REF || GET_CODE (sym) == LABEL_REF))
4782 {
354b734b
MM
4783 unsigned HOST_WIDE_INT value = INTVAL (const_term);
4784 int new_reg_p = (flag_expensive_optimizations
4785 && !reload_completed
4786 && !reload_in_progress);
4787 rtx tmp1 = (new_reg_p && value != 0) ? gen_reg_rtx (SImode) : operands[0];
4788
4789 emit_insn (gen_movsi (tmp1, sym));
b6c9286a
MM
4790 if (INTVAL (const_term) != 0)
4791 {
b6c9286a 4792 if (value + 0x8000 < 0x10000)
354b734b
MM
4793 emit_insn (gen_addsi3 (operands[0], tmp1, GEN_INT (value)));
4794
b6c9286a
MM
4795 else
4796 {
354b734b
MM
4797 HOST_WIDE_INT high_int = value & (~ (HOST_WIDE_INT) 0xffff);
4798 HOST_WIDE_INT low_int = value & 0xffff;
4799 rtx tmp2 = (!new_reg_p || !low_int) ? operands[0] : gen_reg_rtx (Pmode);
4800
4801 if (low_int & 0x8000)
4802 high_int += 0x10000, low_int |= ((HOST_WIDE_INT) -1) << 16;
b6c9286a 4803
354b734b
MM
4804 emit_insn (gen_addsi3 (tmp2, tmp1, GEN_INT (high_int)));
4805 if (low_int)
4806 emit_insn (gen_addsi3 (operands[0], tmp2, GEN_INT (low_int)));
b6c9286a
MM
4807 }
4808 }
4809 DONE;
4810 }
4811 else
4812 fatal_insn (\"bad address\", operands[1]);
4813 }
4814
4815 if ((!TARGET_WINDOWS_NT || DEFAULT_ABI != ABI_NT)
4816 && CONSTANT_P (operands[1])
4697a36c
MM
4817 && GET_CODE (operands[1]) != CONST_INT
4818 && GET_CODE (operands[1]) != HIGH
78b8d850 4819 && ! LEGITIMATE_CONSTANT_POOL_ADDRESS_P (operands[1]))
b45863ec 4820 {
30a4619d
RK
4821 /* If we are to limit the number of things we put in the TOC and
4822 this is a symbol plus a constant we can add in one insn,
abc95ed3 4823 just put the symbol in the TOC and add the constant. Don't do
30a4619d
RK
4824 this if reload is in progress. */
4825 if (GET_CODE (operands[1]) == CONST
4826 && TARGET_NO_SUM_IN_TOC && ! reload_in_progress
4827 && GET_CODE (XEXP (operands[1], 0)) == PLUS
4828 && add_operand (XEXP (XEXP (operands[1], 0), 1), SImode)
4829 && (GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == LABEL_REF
4830 || GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == SYMBOL_REF)
4831 && ! side_effects_p (operands[0]))
4832 {
4833 rtx sym = force_const_mem (SImode, XEXP (XEXP (operands[1], 0), 0));
4834 rtx other = XEXP (XEXP (operands[1], 0), 1);
4835
4836 emit_insn (gen_addsi3 (operands[0], force_reg (SImode, sym), other));
4837 DONE;
4838 }
4839
b45863ec
RK
4840 operands[1] = force_const_mem (SImode, operands[1]);
4841 if (! memory_address_p (SImode, XEXP (operands[1], 0))
4842 && ! reload_in_progress)
4843 operands[1] = change_address (operands[1], SImode,
4844 XEXP (operands[1], 0));
4845 }
1fd4e8c1
RK
4846}")
4847
4848(define_insn ""
88228c4b
MM
4849 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,r,m,r,r,r,r,r,*q,*c*l,*h")
4850 (match_operand:SI 1 "input_operand" "r,S,T,U,m,r,I,J,n,R,*h,r,r,0"))]
19d5775a
RK
4851 "gpc_reg_operand (operands[0], SImode)
4852 || gpc_reg_operand (operands[1], SImode)"
1fd4e8c1 4853 "@
deb9225a 4854 mr %0,%1
b6c9286a
MM
4855 {l|lwz} %0,[toc]%1(2)
4856 {l|lwz} %0,[toc]%l1(2)
b9442c72 4857 {cal|la} %0,%a1
ca7f5001
RK
4858 {l%U1%X1|lwz%U1%X1} %0,%1
4859 {st%U0%X0|stw%U0%X0} %1,%0
19d5775a
RK
4860 {lil|li} %0,%1
4861 {liu|lis} %0,%u1
beaec479 4862 #
57fa6739 4863 {cal|la} %0,%1(%*)
1fd4e8c1 4864 mf%1 %0
5c23c401 4865 mt%0 %1
e76e75bb
RK
4866 mt%0 %1
4867 cror 0,0,0"
88228c4b
MM
4868 [(set_attr "type" "*,load,load,*,load,*,*,*,*,*,*,*,mtjmpr,*")
4869 (set_attr "length" "4,4,4,4,4,4,4,4,8,4,4,4,4,4")])
1fd4e8c1 4870
77fa0940
RK
4871;; Split a load of a large constant into the appropriate two-insn
4872;; sequence.
4873
4874(define_split
4875 [(set (match_operand:SI 0 "gpc_reg_operand" "")
4876 (match_operand:SI 1 "const_int_operand" ""))]
4877 "(unsigned) (INTVAL (operands[1]) + 0x8000) >= 0x10000
4878 && (INTVAL (operands[1]) & 0xffff) != 0"
4879 [(set (match_dup 0)
4880 (match_dup 2))
4881 (set (match_dup 0)
4882 (ior:SI (match_dup 0)
4883 (match_dup 3)))]
4884 "
4885{
4886 operands[2] = gen_rtx (CONST_INT, VOIDmode,
4887 INTVAL (operands[1]) & 0xffff0000);
4888 operands[3] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[1]) & 0xffff);
4889}")
4890
1fd4e8c1
RK
4891(define_insn ""
4892 [(set (match_operand:CC 2 "cc_reg_operand" "=x")
cd2b37d9 4893 (compare:CC (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 4894 (const_int 0)))
cd2b37d9 4895 (set (match_operand:SI 0 "gpc_reg_operand" "=r") (match_dup 1))]
1fd4e8c1 4896 ""
deb9225a 4897 "mr. %0,%1"
1fd4e8c1
RK
4898 [(set_attr "type" "compare")])
4899\f
4900(define_expand "movhi"
4901 [(set (match_operand:HI 0 "general_operand" "")
4902 (match_operand:HI 1 "any_operand" ""))]
4903 ""
4904 "
4905{
4906 if (GET_CODE (operands[0]) != REG)
4907 operands[1] = force_reg (HImode, operands[1]);
4908
4909 if (CONSTANT_P (operands[1]) && GET_CODE (operands[1]) != CONST_INT)
b45863ec
RK
4910 {
4911 operands[1] = force_const_mem (HImode, operands[1]);
4912 if (! memory_address_p (HImode, XEXP (operands[1], 0))
4913 && ! reload_in_progress)
4914 operands[1] = change_address (operands[1], HImode,
4915 XEXP (operands[1], 0));
4916 }
1fd4e8c1
RK
4917}")
4918
4919(define_insn ""
fb81d7ce
RK
4920 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,m,r,r,*q,*c*l,*h")
4921 (match_operand:HI 1 "input_operand" "r,m,r,i,*h,r,r,0"))]
19d5775a
RK
4922 "gpc_reg_operand (operands[0], HImode)
4923 || gpc_reg_operand (operands[1], HImode)"
1fd4e8c1 4924 "@
deb9225a 4925 mr %0,%1
1fd4e8c1
RK
4926 lhz%U1%X1 %0,%1
4927 sth%U0%X0 %1,%0
19d5775a 4928 {lil|li} %0,%w1
1fd4e8c1 4929 mf%1 %0
e76e75bb 4930 mt%0 %1
fb81d7ce 4931 mt%0 %1
e76e75bb 4932 cror 0,0,0"
fb81d7ce 4933 [(set_attr "type" "*,load,*,*,*,*,mtjmpr,*")])
1fd4e8c1
RK
4934
4935(define_expand "movqi"
4936 [(set (match_operand:QI 0 "general_operand" "")
4937 (match_operand:QI 1 "any_operand" ""))]
4938 ""
4939 "
4940{
4941 if (GET_CODE (operands[0]) != REG)
4942 operands[1] = force_reg (QImode, operands[1]);
4943
4944 if (CONSTANT_P (operands[1]) && GET_CODE (operands[1]) != CONST_INT)
b45863ec
RK
4945 {
4946 operands[1] = force_const_mem (QImode, operands[1]);
4947 if (! memory_address_p (QImode, XEXP (operands[1], 0))
4948 && ! reload_in_progress)
4949 operands[1] = change_address (operands[1], QImode,
4950 XEXP (operands[1], 0));
4951 }
1fd4e8c1
RK
4952}")
4953
4954(define_insn ""
fb81d7ce
RK
4955 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m,r,r,*q,*c*l,*h")
4956 (match_operand:QI 1 "input_operand" "r,m,r,i,*h,r,r,0"))]
19d5775a
RK
4957 "gpc_reg_operand (operands[0], QImode)
4958 || gpc_reg_operand (operands[1], QImode)"
1fd4e8c1 4959 "@
deb9225a 4960 mr %0,%1
1fd4e8c1
RK
4961 lbz%U1%X1 %0,%1
4962 stb%U0%X0 %1,%0
19d5775a 4963 {lil|li} %0,%1
1fd4e8c1 4964 mf%1 %0
e76e75bb 4965 mt%0 %1
fb81d7ce 4966 mt%0 %1
e76e75bb 4967 cror 0,0,0"
fb81d7ce 4968 [(set_attr "type" "*,load,*,*,*,*,mtjmpr,*")])
1fd4e8c1
RK
4969\f
4970;; Here is how to move condition codes around. When we store CC data in
4971;; an integer register or memory, we store just the high-order 4 bits.
4972;; This lets us not shift in the most common case of CR0.
4973(define_expand "movcc"
4974 [(set (match_operand:CC 0 "nonimmediate_operand" "")
4975 (match_operand:CC 1 "nonimmediate_operand" ""))]
4976 ""
4977 "")
4978
4979(define_insn ""
4980 [(set (match_operand:CC 0 "nonimmediate_operand" "=y,x,y,r,r,r,r,m")
4981 (match_operand:CC 1 "nonimmediate_operand" "y,r,r,x,y,r,m,r"))]
4982 "register_operand (operands[0], CCmode)
4983 || register_operand (operands[1], CCmode)"
4984 "@
4985 mcrf %0,%1
4986 mtcrf 128,%1
ca7f5001 4987 {rlinm|rlwinm} %1,%1,%F0,0xffffffff\;mtcrf %R0,%1\;{rlinm|rlwinm} %1,%1,%f0,0xffffffff
1fd4e8c1 4988 mfcr %0
ca7f5001 4989 mfcr %0\;{rlinm|rlwinm} %0,%0,%f1,0xf0000000
deb9225a 4990 mr %0,%1
ca7f5001
RK
4991 {l%U1%X1|lwz%U1%X1} %0,%1
4992 {st%U0%U1|stw%U0%U1} %1,%0"
b19003d8
RK
4993 [(set_attr "type" "*,*,*,compare,*,*,load,*")
4994 (set_attr "length" "*,*,12,*,8,*,*,*")])
1fd4e8c1 4995\f
e52e05ca
MM
4996;; For floating-point, we normally deal with the floating-point registers
4997;; unless -msoft-float is used. The sole exception is that parameter passing
4998;; can produce floating-point values in fixed-point registers. Unless the
4999;; value is a simple constant or already in memory, we deal with this by
5000;; allocating memory and copying the value explicitly via that memory location.
1fd4e8c1
RK
5001(define_expand "movsf"
5002 [(set (match_operand:SF 0 "nonimmediate_operand" "")
5003 (match_operand:SF 1 "any_operand" ""))]
5004 ""
5005 "
5006{
5007 /* If we are called from reload, we might be getting a SUBREG of a hard
5008 reg. So expand it. */
5009 if (GET_CODE (operands[0]) == SUBREG
5010 && GET_CODE (SUBREG_REG (operands[0])) == REG
5011 && REGNO (SUBREG_REG (operands[0])) < FIRST_PSEUDO_REGISTER)
5012 operands[0] = alter_subreg (operands[0]);
5013 if (GET_CODE (operands[1]) == SUBREG
5014 && GET_CODE (SUBREG_REG (operands[1])) == REG
5015 && REGNO (SUBREG_REG (operands[1])) < FIRST_PSEUDO_REGISTER)
5016 operands[1] = alter_subreg (operands[1]);
5017
3b7f6cca
MM
5018 if (TARGET_SOFT_FLOAT && GET_CODE (operands[0]) == MEM)
5019 operands[1] = force_reg (SFmode, operands[1]);
5020
5021 else if (TARGET_HARD_FLOAT)
1fd4e8c1 5022 {
e52e05ca 5023 if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) < 32)
1fd4e8c1 5024 {
e52e05ca
MM
5025 /* If this is a store to memory or another integer register do the
5026 move directly. Otherwise store to a temporary stack slot and
5027 load from there into a floating point register. */
5028
5029 if (GET_CODE (operands[0]) == MEM
5030 || (GET_CODE (operands[0]) == REG
5031 && (REGNO (operands[0]) < 32
5032 || (reload_in_progress
5033 && REGNO (operands[0]) >= FIRST_PSEUDO_REGISTER))))
5034 {
5035 emit_move_insn (operand_subword (operands[0], 0, 0, SFmode),
5036 operand_subword (operands[1], 0, 0, SFmode));
5037 DONE;
5038 }
5039 else
5040 {
5041 rtx stack_slot = assign_stack_temp (SFmode, 4, 0);
5042
5043 emit_move_insn (stack_slot, operands[1]);
5044 emit_move_insn (operands[0], stack_slot);
5045 DONE;
5046 }
f6ba0600 5047 }
1fd4e8c1 5048
e52e05ca 5049 if (GET_CODE (operands[0]) == MEM)
f2974b07 5050 {
e52e05ca
MM
5051 /* If operands[1] is a register, it may have double-precision data
5052 in it, so truncate it to single precision. We need not do
5053 this for POWERPC. */
455350f4
RK
5054 if (! TARGET_POWERPC && TARGET_HARD_FLOAT
5055 && GET_CODE (operands[1]) == REG)
e52e05ca 5056 {
455350f4
RK
5057 rtx newreg
5058 = reload_in_progress ? operands[1] : gen_reg_rtx (SFmode);
5059 emit_insn (gen_aux_truncdfsf2 (newreg, operands[1]));
e52e05ca
MM
5060 operands[1] = newreg;
5061 }
5062
5063 operands[1] = force_reg (SFmode, operands[1]);
f2974b07
RK
5064 }
5065
e52e05ca
MM
5066 if (GET_CODE (operands[0]) == REG && REGNO (operands[0]) < 32)
5067 {
5068 if (GET_CODE (operands[1]) == MEM
1fd4e8c1 5069#if HOST_FLOAT_FORMAT == TARGET_FLOAT_FORMAT && ! defined(REAL_IS_NOT_DOUBLE)
e52e05ca 5070 || GET_CODE (operands[1]) == CONST_DOUBLE
1fd4e8c1 5071#endif
e52e05ca
MM
5072 || (GET_CODE (operands[1]) == REG
5073 && (REGNO (operands[1]) < 32
5074 || (reload_in_progress
5075 && REGNO (operands[1]) >= FIRST_PSEUDO_REGISTER))))
5076 {
5077 emit_move_insn (operand_subword (operands[0], 0, 0, SFmode),
5078 operand_subword (operands[1], 0, 0, SFmode));
5079 DONE;
5080 }
5081 else
5082 {
5083 rtx stack_slot = assign_stack_temp (SFmode, 4, 0);
5084
5085 emit_move_insn (stack_slot, operands[1]);
5086 emit_move_insn (operands[0], stack_slot);
5087 DONE;
5088 }
f6ba0600 5089 }
1fd4e8c1
RK
5090 }
5091
5092 if (CONSTANT_P (operands[1]))
5093 {
5094 operands[1] = force_const_mem (SFmode, operands[1]);
5095 if (! memory_address_p (SFmode, XEXP (operands[1], 0))
5096 && ! reload_in_progress)
5097 operands[1] = change_address (operands[1], SFmode,
5098 XEXP (operands[1], 0));
5099 }
5100}")
5101
1fd4e8c1 5102(define_split
cd2b37d9 5103 [(set (match_operand:SF 0 "gpc_reg_operand" "")
1fd4e8c1
RK
5104 (match_operand:SF 1 "easy_fp_constant" ""))]
5105 "reload_completed && REGNO (operands[0]) <= 31"
5106 [(set (match_dup 2) (match_dup 3))]
5107 "
5108{ operands[2] = operand_subword (operands[0], 0, 0, SFmode);
5109 operands[3] = operand_subword (operands[1], 0, 0, SFmode); }")
7e69e155 5110
1fd4e8c1
RK
5111(define_insn ""
5112 [(set (match_operand:SF 0 "fp_reg_or_mem_operand" "=f,f,m")
5113 (match_operand:SF 1 "input_operand" "f,m,f"))]
d14a6d05
MM
5114 "(gpc_reg_operand (operands[0], SFmode)
5115 || gpc_reg_operand (operands[1], SFmode)) && TARGET_HARD_FLOAT"
1fd4e8c1
RK
5116 "@
5117 fmr %0,%1
5118 lfs%U1%X1 %0,%1
85fff2f3 5119 stfs%U0%X0 %1,%0"
19d5775a 5120 [(set_attr "type" "fp,fpload,*")])
d14a6d05
MM
5121
5122(define_insn ""
5123 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m,r,r,r")
5124 (match_operand:SF 1 "input_operand" "r,m,r,I,J,R"))]
5125 "(gpc_reg_operand (operands[0], SFmode)
5126 || gpc_reg_operand (operands[1], SFmode)) && TARGET_SOFT_FLOAT"
5127 "@
5128 mr %0,%1
5129 {l%U1%X1|lwz%U1%X1} %0,%1
5130 {st%U0%X0|stw%U0%X0} %1,%0
5131 {lil|li} %0,%1
5132 {liu|lis} %0,%u1
5133 {cal|la} %0,%1(%*)"
5134 [(set_attr "type" "*,load,*,*,*,*")])
5135
1fd4e8c1
RK
5136\f
5137(define_expand "movdf"
5138 [(set (match_operand:DF 0 "nonimmediate_operand" "")
5139 (match_operand:DF 1 "any_operand" ""))]
5140 ""
5141 "
5142{
e7113111
RK
5143 if (GET_CODE (operands[0]) != REG)
5144 operands[1] = force_reg (DFmode, operands[1]);
1fd4e8c1 5145
08075ead
DE
5146 /* Stores between FPR and any non-FPR registers must go through a
5147 temporary stack slot. */
5148
5149 if (TARGET_POWERPC64
5150 && GET_CODE (operands[0]) == REG && GET_CODE (operands[1]) == REG
5151 && ((FP_REGNO_P (REGNO (operands[0]))
5152 && ! FP_REGNO_P (REGNO (operands[1])))
5153 || (FP_REGNO_P (REGNO (operands[1]))
5154 && ! FP_REGNO_P (REGNO (operands[0])))))
5155 {
5156 rtx stack_slot = assign_stack_temp (DFmode, 8, 0);
5157
5158 emit_move_insn (stack_slot, operands[1]);
5159 emit_move_insn (operands[0], stack_slot);
5160 DONE;
5161 }
5162
e7113111 5163 if (CONSTANT_P (operands[1]) && ! easy_fp_constant (operands[1], DFmode))
1fd4e8c1
RK
5164 {
5165 operands[1] = force_const_mem (DFmode, operands[1]);
5166 if (! memory_address_p (DFmode, XEXP (operands[1], 0))
5167 && ! reload_in_progress)
5168 operands[1] = change_address (operands[1], DFmode,
5169 XEXP (operands[1], 0));
5170 }
e7113111 5171}")
1fd4e8c1
RK
5172
5173(define_split
cd2b37d9 5174 [(set (match_operand:DF 0 "gpc_reg_operand" "")
1fd4e8c1
RK
5175 (match_operand:DF 1 "easy_fp_constant" ""))]
5176 "reload_completed && REGNO (operands[0]) <= 31"
5177 [(set (match_dup 2) (match_dup 3))
5178 (set (match_dup 4) (match_dup 5))]
5179 "
5180{ operands[2] = operand_subword (operands[0], 0, 0, DFmode);
5181 operands[3] = operand_subword (operands[1], 0, 0, DFmode);
5182 operands[4] = operand_subword (operands[0], 1, 0, DFmode);
5183 operands[5] = operand_subword (operands[1], 1, 0, DFmode); }")
e7113111 5184
4eae5fe1
RK
5185;; Don't have reload use general registers to load a constant. First,
5186;; it might not work if the output operand has is the equivalent of
5187;; a non-offsettable memref, but also it is less efficient than loading
5188;; the constant into an FP register, since it will probably be used there.
5189;; The "??" is a kludge until we can figure out a more reasonable way
5190;; of handling these non-offsettable values.
5191(define_insn ""
5192 [(set (match_operand:DF 0 "nonimmediate_operand" "=!r,??r,o,!r,f,f,m")
e7113111 5193 (match_operand:DF 1 "input_operand" "r,o,r,G,f,m,f"))]
dc4f83ca
MM
5194 "! TARGET_POWERPC64 && TARGET_HARD_FLOAT
5195 && (register_operand (operands[0], DFmode)
5196 || register_operand (operands[1], DFmode))"
e7113111
RK
5197 "*
5198{
5199 switch (which_alternative)
5200 {
5201 case 0:
5202 /* We normally copy the low-numbered register first. However, if
5203 the first register operand 0 is the same as the second register of
5204 operand 1, we must copy in the opposite order. */
5205 if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
deb9225a 5206 return \"mr %L0,%L1\;mr %0,%1\";
e7113111 5207 else
deb9225a 5208 return \"mr %0,%1\;mr %L0,%L1\";
e7113111
RK
5209 case 1:
5210 /* If the low-address word is used in the address, we must load it
5211 last. Otherwise, load it first. Note that we cannot have
5212 auto-increment in that case since the address register is known to be
5213 dead. */
5214 if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
5215 operands [1], 0))
ca7f5001 5216 return \"{l|lwz} %L0,%L1\;{l|lwz} %0,%1\";
e7113111 5217 else
ca7f5001 5218 return \"{l%U1|lwz%U1} %0,%1\;{l|lwz} %L0,%L1\";
e7113111 5219 case 2:
ca7f5001 5220 return \"{st%U0|stw%U0} %1,%0\;{st|stw} %L1,%L0\";
e7113111
RK
5221 case 3:
5222 return \"#\";
5223 case 4:
5224 return \"fmr %0,%1\";
5225 case 5:
5226 return \"lfd%U1%X1 %0,%1\";
5227 case 6:
5228 return \"stfd%U0%X0 %1,%0\";
5229 }
5230}"
ca7f5001 5231 [(set_attr "type" "*,load,*,*,fp,fpload,*")
e7113111 5232 (set_attr "length" "8,8,8,8,*,*,*")])
51b8fc2c 5233
dc4f83ca
MM
5234(define_insn ""
5235 [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,o,r")
5236 (match_operand:DF 1 "input_operand" "r,o,r,G"))]
5237 "! TARGET_POWERPC64 && TARGET_SOFT_FLOAT
5238 && (register_operand (operands[0], DFmode)
5239 || register_operand (operands[1], DFmode))"
5240 "*
5241{
5242 switch (which_alternative)
5243 {
5244 case 0:
5245 /* We normally copy the low-numbered register first. However, if
5246 the first register operand 0 is the same as the second register of
5247 operand 1, we must copy in the opposite order. */
5248 if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
5249 return \"mr %L0,%L1\;mr %0,%1\";
5250 else
5251 return \"mr %0,%1\;mr %L0,%L1\";
5252 case 1:
5253 /* If the low-address word is used in the address, we must load it
5254 last. Otherwise, load it first. Note that we cannot have
5255 auto-increment in that case since the address register is known to be
5256 dead. */
5257 if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
5258 operands [1], 0))
5259 return \"{l|lwz} %L0,%L1\;{l|lwz} %0,%1\";
5260 else
5261 return \"{l%U1|lwz%U1} %0,%1\;{l|lwz} %L0,%L1\";
5262 case 2:
5263 return \"{st%U0|stw%U0} %1,%0\;{st|stw} %L1,%L0\";
5264 case 3:
5265 return \"#\";
5266 }
5267}"
5268 [(set_attr "type" "*,load,*,*")
5269 (set_attr "length" "8,8,8,8")])
5270
51b8fc2c
RK
5271(define_insn ""
5272 [(set (match_operand:DF 0 "nonimmediate_operand" "=!r,??r,o,!r,f,f,m")
5273 (match_operand:DF 1 "input_operand" "r,o,r,G,f,m,f"))]
dc4f83ca
MM
5274 "TARGET_POWERPC64 && TARGET_HARD_FLOAT
5275 && (register_operand (operands[0], DFmode)
5276 || register_operand (operands[1], DFmode))"
51b8fc2c 5277 "@
3d5570cb
RK
5278 mr %0,%1
5279 ld%U1%X1 %0,%1
5280 sd%U0%X0 %1,%0
5281 #
5282 fmr %0,%1
f63184ac 5283 lfd%U1%X1 %0,%1
3d5570cb 5284 stfd%U0%X0 %1,%0"
51b8fc2c 5285 [(set_attr "type" "*,load,*,*,fp,fpload,*")])
dc4f83ca
MM
5286
5287(define_insn ""
5288 [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,o,r")
5289 (match_operand:DF 1 "input_operand" "r,o,r,G"))]
5290 "TARGET_POWERPC64 && TARGET_SOFT_FLOAT
5291 && (register_operand (operands[0], DFmode)
5292 || register_operand (operands[1], DFmode))"
5293 "@
5294 mr %0,%1
5295 ld%U1%X1 %0,%1
5296 sd%U0%X0 %1,%0
5297 #"
5298 [(set_attr "type" "*,load,*,*")])
1fd4e8c1
RK
5299\f
5300;; Next come the multi-word integer load and store and the load and store
5301;; multiple insns.
5302(define_expand "movdi"
5303 [(set (match_operand:DI 0 "general_operand" "")
5304 (match_operand:DI 1 "general_operand" ""))]
5305 ""
5306 "
5307{
6b6ccd10
RK
5308 if (GET_CODE (operands[0]) == MEM)
5309 operands[1] = force_reg (DImode, operands[1]);
5310
062284d8
RK
5311 if (GET_CODE (operands[1]) == CONST_DOUBLE
5312 || GET_CODE (operands[1]) == CONST_INT)
1fd4e8c1 5313 {
6b6ccd10
RK
5314 HOST_WIDE_INT low;
5315 HOST_WIDE_INT high;
5316
5317 if (GET_CODE (operands[1]) == CONST_DOUBLE)
5318 {
5319 low = CONST_DOUBLE_LOW (operands[1]);
5320 high = CONST_DOUBLE_HIGH (operands[1]);
5321 }
5322 else
5323 {
5324 low = INTVAL (operands[1]);
5325 high = (low < 0) ? ~0 : 0;
5326 }
5327
5328 emit_move_insn (gen_rtx (SUBREG, SImode, operands[0], WORDS_BIG_ENDIAN),
5329 GEN_INT (low));
5330
5331 emit_move_insn (gen_rtx (SUBREG, SImode, operands[0], !WORDS_BIG_ENDIAN),
5332 GEN_INT (high));
1fd4e8c1
RK
5333 DONE;
5334 }
062284d8 5335
a473029f
RK
5336 /* Stores between FPR and any non-FPR registers must go through a
5337 temporary stack slot. */
5338
5339 if (GET_CODE (operands[0]) == REG && GET_CODE (operands[1]) == REG
5340 && ((FP_REGNO_P (REGNO (operands[0]))
5341 && ! FP_REGNO_P (REGNO (operands[1])))
5342 || (FP_REGNO_P (REGNO (operands[1]))
5343 && ! FP_REGNO_P (REGNO (operands[0])))))
5344 {
425c176f 5345 rtx stack_slot = assign_stack_temp (DImode, 8, 0);
a473029f 5346
a473029f
RK
5347 emit_move_insn (stack_slot, operands[1]);
5348 emit_move_insn (operands[0], stack_slot);
5349 DONE;
5350 }
1fd4e8c1
RK
5351}")
5352
5353(define_insn ""
8ffd9c51
RK
5354 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m,f,f,m")
5355 (match_operand:DI 1 "input_operand" "r,m,r,f,m,f"))]
51b8fc2c
RK
5356 "! TARGET_POWERPC64 && (gpc_reg_operand (operands[0], DImode)
5357 || gpc_reg_operand (operands[1], DImode))"
1fd4e8c1
RK
5358 "*
5359{
5360 switch (which_alternative)
5361 {
5362 case 0:
5363 /* We normally copy the low-numbered register first. However, if
5364 the first register operand 0 is the same as the second register of
5365 operand 1, we must copy in the opposite order. */
5366 if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
deb9225a 5367 return \"mr %L0,%L1\;mr %0,%1\";
1fd4e8c1 5368 else
deb9225a 5369 return \"mr %0,%1\;mr %L0,%L1\";
1fd4e8c1
RK
5370 case 1:
5371 /* If the low-address word is used in the address, we must load it
5372 last. Otherwise, load it first. Note that we cannot have
5373 auto-increment in that case since the address register is known to be
5374 dead. */
5375 if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
5376 operands [1], 0))
ca7f5001 5377 return \"{l|lwz} %L0,%L1\;{l|lwz} %0,%1\";
1fd4e8c1 5378 else
ca7f5001 5379 return \"{l%U1|lwz%U1} %0,%1\;{l|lwz} %L0,%L1\";
1fd4e8c1 5380 case 2:
ca7f5001 5381 return \"{st%U0|stw%U0} %1,%0\;{st|stw} %L1,%L0\";
8ffd9c51
RK
5382 case 3:
5383 return \"fmr %0,%1\";
5384 case 4:
5385 return \"lfd%U1%X1 %0,%1\";
5386 case 5:
5387 return \"stfd%U0%X0 %1,%0\";
1fd4e8c1
RK
5388 }
5389}"
8ffd9c51
RK
5390 [(set_attr "type" "*,load,*,fp,fpload,*")
5391 (set_attr "length" "8,8,8,*,*,*")])
51b8fc2c
RK
5392
5393(define_insn ""
08075ead
DE
5394 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m,r,r,r,f,f,m,r,*h,*h")
5395 (match_operand:DI 1 "input_operand" "r,m,r,I,J,R,f,m,f,*h,r,0"))]
51b8fc2c
RK
5396 "TARGET_POWERPC64 && (gpc_reg_operand (operands[0], DImode)
5397 || gpc_reg_operand (operands[1], DImode))"
5398 "@
3d5570cb
RK
5399 mr %0,%1
5400 ld%U1%X1 %0,%1
5401 sd%U0%X0 %1,%0
5402 li %0,%1
5403 lis %0,%u1
57fa6739 5404 {cal|la} %0,%1(%*)
3d5570cb
RK
5405 fmr %0,%1
5406 lfd%U1%X1 %0,%1
5407 stfd%U0%X0 %1,%0
5408 mf%1 %0
08075ead
DE
5409 mt%0 %1
5410 cror 0,0,0"
5411 [(set_attr "type" "*,load,*,*,*,*,fp,fpload,*,*,mtjmpr,*")])
5412
5413(define_insn ""
5414 [(set (match_operand:CC 2 "cc_reg_operand" "=x")
5415 (compare:CC (match_operand:DI 1 "gpc_reg_operand" "r")
5416 (const_int 0)))
5417 (set (match_operand:DI 0 "gpc_reg_operand" "=r") (match_dup 1))]
5418 "TARGET_POWERPC64"
5419 "mr. %0,%1"
5420 [(set_attr "type" "compare")])
1fd4e8c1
RK
5421\f
5422;; TImode is similar, except that we usually want to compute the address into
5423;; a register and use lsi/stsi (the exception is during reload). MQ is also
ca7f5001 5424;; clobbered in stsi for POWER, so we need a SCRATCH for it.
1fd4e8c1
RK
5425(define_expand "movti"
5426 [(parallel [(set (match_operand:TI 0 "general_operand" "")
5427 (match_operand:TI 1 "general_operand" ""))
5428 (clobber (scratch:SI))])]
7e69e155 5429 "TARGET_STRING || TARGET_POWERPC64"
1fd4e8c1
RK
5430 "
5431{
5432 if (GET_CODE (operands[0]) == MEM)
5433 operands[1] = force_reg (TImode, operands[1]);
5434
5435 if (GET_CODE (operands[0]) == MEM
5436 && GET_CODE (XEXP (operands[0], 0)) != REG
5437 && ! reload_in_progress)
5438 operands[0] = change_address (operands[0], TImode,
5439 copy_addr_to_reg (XEXP (operands[0], 0)));
5440
5441 if (GET_CODE (operands[1]) == MEM
5442 && GET_CODE (XEXP (operands[1], 0)) != REG
5443 && ! reload_in_progress)
5444 operands[1] = change_address (operands[1], TImode,
5445 copy_addr_to_reg (XEXP (operands[1], 0)));
5446}")
5447
5448;; We say that MQ is clobbered in the last alternative because the first
5449;; alternative would never get used otherwise since it would need a reload
5450;; while the 2nd alternative would not. We put memory cases first so they
5451;; are preferred. Otherwise, we'd try to reload the output instead of
5452;; giving the SCRATCH mq.
5453(define_insn ""
e1469d0d 5454 [(set (match_operand:TI 0 "reg_or_mem_operand" "=Q,m,????r,????r,????r")
1fd4e8c1
RK
5455 (match_operand:TI 1 "reg_or_mem_operand" "r,r,r,Q,m"))
5456 (clobber (match_scratch:SI 2 "=q,q#X,X,X,X"))]
7e69e155 5457 "TARGET_STRING && TARGET_POWER && ! TARGET_POWERPC64
dc4f83ca 5458 && (gpc_reg_operand (operands[0], TImode) || gpc_reg_operand (operands[1], TImode))"
1fd4e8c1
RK
5459 "*
5460{
5461 switch (which_alternative)
5462 {
dc4f83ca
MM
5463 default:
5464 abort ();
5465
1fd4e8c1 5466 case 0:
ca7f5001 5467 return \"{stsi|stswi} %1,%P0,16\";
1fd4e8c1
RK
5468
5469 case 1:
ca7f5001 5470 return \"{st%U0|stw%U0} %1,%0\;{st|stw} %L1,%L0\;{st|stw} %Y1,%Y0\;{st|stw} %Z1,%Z0\";
1fd4e8c1
RK
5471
5472 case 2:
5473 /* Normally copy registers with lowest numbered register copied first.
5474 But copy in the other order if the first register of the output
5475 is the second, third, or fourth register in the input. */
5476 if (REGNO (operands[0]) >= REGNO (operands[1]) + 1
5477 && REGNO (operands[0]) <= REGNO (operands[1]) + 3)
deb9225a 5478 return \"mr %Z0,%Z1\;mr %Y0,%Y1\;mr %L0,%L1\;mr %0,%1\";
1fd4e8c1 5479 else
deb9225a 5480 return \"mr %0,%1\;mr %L0,%L1\;mr %Y0,%Y1\;mr %Z0,%Z1\";
1fd4e8c1
RK
5481 case 3:
5482 /* If the address is not used in the output, we can use lsi. Otherwise,
5483 fall through to generating four loads. */
5484 if (! reg_overlap_mentioned_p (operands[0], operands[1]))
ca7f5001 5485 return \"{lsi|lswi} %0,%P1,16\";
1fd4e8c1
RK
5486 /* ... fall through ... */
5487 case 4:
5488 /* If the address register is the same as the register for the lowest-
5489 addressed word, load it last. Similarly for the next two words.
5490 Otherwise load lowest address to highest. */
5491 if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
5492 operands[1], 0))
ca7f5001 5493 return \"{l|lwz} %L0,%L1\;{l|lwz} %Y0,%Y1\;{l|lwz} %Z0,%Z1\;{l|lwz} %0,%1\";
1fd4e8c1
RK
5494 else if (refers_to_regno_p (REGNO (operands[0]) + 1,
5495 REGNO (operands[0]) + 2, operands[1], 0))
ca7f5001 5496 return \"{l|lwz} %0,%1\;{l|lwz} %Y0,%Y1\;{l|lwz} %Z0,%Z1\;{l|lwz} %L0,%L1\";
1fd4e8c1
RK
5497 else if (refers_to_regno_p (REGNO (operands[0]) + 2,
5498 REGNO (operands[0]) + 3, operands[1], 0))
ca7f5001 5499 return \"{l|lwz} %0,%1\;{l|lwz} %L0,%L1\;{l|lwz} %Z0,%Z1\;{l|lwz} %Y0,%Y1\";
1fd4e8c1 5500 else
ca7f5001 5501 return \"{l%U1|lwz%U1} %0,%1\;{l|lwz} %L0,%L1\;{l|lwz} %Y0,%Y1\;{l|lwz} %Z0,%Z1\";
1fd4e8c1
RK
5502 }
5503}"
b19003d8
RK
5504 [(set_attr "type" "*,load,load,*,*")
5505 (set_attr "length" "*,16,16,*,16")])
51b8fc2c 5506
dc4f83ca
MM
5507(define_insn ""
5508 [(set (match_operand:TI 0 "reg_or_mem_operand" "=m,????r,????r")
5509 (match_operand:TI 1 "reg_or_mem_operand" "r,r,m"))
5510 (clobber (match_scratch:SI 2 "=X,X,X"))]
7e69e155 5511 "TARGET_STRING && !TARGET_POWER && ! TARGET_POWERPC64
dc4f83ca
MM
5512 && (gpc_reg_operand (operands[0], TImode) || gpc_reg_operand (operands[1], TImode))"
5513 "*
5514{
5515 switch (which_alternative)
5516 {
5517 default:
5518 abort ();
5519
5520 case 0:
5521 return \"{st%U0|stw%U0} %1,%0\;{st|stw} %L1,%L0\;{st|stw} %Y1,%Y0\;{st|stw} %Z1,%Z0\";
5522
5523 case 1:
5524 /* Normally copy registers with lowest numbered register copied first.
5525 But copy in the other order if the first register of the output
5526 is the second, third, or fourth register in the input. */
5527 if (REGNO (operands[0]) >= REGNO (operands[1]) + 1
5528 && REGNO (operands[0]) <= REGNO (operands[1]) + 3)
5529 return \"mr %Z0,%Z1\;mr %Y0,%Y1\;mr %L0,%L1\;mr %0,%1\";
5530 else
5531 return \"mr %0,%1\;mr %L0,%L1\;mr %Y0,%Y1\;mr %Z0,%Z1\";
5532 case 2:
5533 /* If the address register is the same as the register for the lowest-
5534 addressed word, load it last. Similarly for the next two words.
5535 Otherwise load lowest address to highest. */
5536 if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
5537 operands[1], 0))
5538 return \"{l|lwz} %L0,%L1\;{l|lwz} %Y0,%Y1\;{l|lwz} %Z0,%Z1\;{l|lwz} %0,%1\";
5539 else if (refers_to_regno_p (REGNO (operands[0]) + 1,
5540 REGNO (operands[0]) + 2, operands[1], 0))
5541 return \"{l|lwz} %0,%1\;{l|lwz} %Y0,%Y1\;{l|lwz} %Z0,%Z1\;{l|lwz} %L0,%L1\";
5542 else if (refers_to_regno_p (REGNO (operands[0]) + 2,
5543 REGNO (operands[0]) + 3, operands[1], 0))
5544 return \"{l|lwz} %0,%1\;{l|lwz} %L0,%L1\;{l|lwz} %Z0,%Z1\;{l|lwz} %Y0,%Y1\";
5545 else
5546 return \"{l%U1|lwz%U1} %0,%1\;{l|lwz} %L0,%L1\;{l|lwz} %Y0,%Y1\;{l|lwz} %Z0,%Z1\";
5547 }
5548}"
5549 [(set_attr "type" "load,*,*")
5550 (set_attr "length" "16,16,16")])
5551
51b8fc2c
RK
5552(define_insn ""
5553 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,r,m")
5554 (match_operand:TI 1 "input_operand" "r,m,r"))]
5555 "TARGET_POWERPC64 && (gpc_reg_operand (operands[0], TImode)
5556 || gpc_reg_operand (operands[1], TImode))"
5557 "*
5558{
5559 switch (which_alternative)
5560 {
5561 case 0:
5562 /* We normally copy the low-numbered register first. However, if
5563 the first register operand 0 is the same as the second register of
5564 operand 1, we must copy in the opposite order. */
5565 if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
5566 return \"mr %L0,%L1\;mr %0,%1\";
5567 else
5568 return \"mr %0,%1\;mr %L0,%L1\";
5569 case 1:
5570 /* If the low-address word is used in the address, we must load it
5571 last. Otherwise, load it first. Note that we cannot have
5572 auto-increment in that case since the address register is known to be
5573 dead. */
5574 if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
5575 operands [1], 0))
5576 return \"ld %L0,%L1\;ld %0,%1\";
5577 else
5578 return \"ld%U1 %0,%1\;ld %L0,%L1\";
5579 case 2:
5580 return \"std%U0 %1,%0\;std %L1,%L0\";
5581 }
5582}"
5583 [(set_attr "type" "*,load,*")
5584 (set_attr "length" "8,8,8")])
1fd4e8c1
RK
5585\f
5586(define_expand "load_multiple"
2f622005
RK
5587 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
5588 (match_operand:SI 1 "" ""))
5589 (use (match_operand:SI 2 "" ""))])]
7e69e155 5590 "TARGET_STRING"
1fd4e8c1
RK
5591 "
5592{
5593 int regno;
5594 int count;
5595 rtx from;
5596 int i;
5597
5598 /* Support only loading a constant number of fixed-point registers from
5599 memory and only bother with this if more than two; the machine
5600 doesn't support more than eight. */
5601 if (GET_CODE (operands[2]) != CONST_INT
5602 || INTVAL (operands[2]) <= 2
5603 || INTVAL (operands[2]) > 8
5604 || GET_CODE (operands[1]) != MEM
5605 || GET_CODE (operands[0]) != REG
5606 || REGNO (operands[0]) >= 32)
5607 FAIL;
5608
5609 count = INTVAL (operands[2]);
5610 regno = REGNO (operands[0]);
5611
5612 operands[3] = gen_rtx (PARALLEL, VOIDmode, rtvec_alloc (count));
5613 from = force_reg (SImode, XEXP (operands[1], 0));
5614
5615 for (i = 0; i < count; i++)
5616 XVECEXP (operands[3], 0, i)
5617 = gen_rtx (SET, VOIDmode, gen_rtx (REG, SImode, regno + i),
5618 gen_rtx (MEM, SImode, plus_constant (from, i * 4)));
5619}")
5620
5621(define_insn ""
5622 [(match_parallel 0 "load_multiple_operation"
cd2b37d9 5623 [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
4c99e795 5624 (mem:SI (match_operand:SI 2 "register_operand" "b")))])]
7e69e155 5625 "TARGET_STRING"
1fd4e8c1
RK
5626 "*
5627{
5628 /* We have to handle the case where the pseudo used to contain the address
e82ee4cc
RK
5629 is assigned to one of the output registers. */
5630 int i, j;
5631 int words = XVECLEN (operands[0], 0);
5632 rtx xop[10];
5633
5634 if (XVECLEN (operands[0], 0) == 1)
5635 return \"{l|lwz} %1,0(%2)\";
1fd4e8c1 5636
e82ee4cc 5637 for (i = 0; i < words; i++)
1fd4e8c1
RK
5638 if (refers_to_regno_p (REGNO (operands[1]) + i,
5639 REGNO (operands[1]) + i + 1, operands[2], 0))
5640 {
e82ee4cc
RK
5641 if (i == words-1)
5642 {
5643 xop[0] = operands[1];
5644 xop[1] = operands[2];
5645 xop[2] = GEN_INT (4 * (words-1));
d89ddcfd 5646 output_asm_insn (\"{lsi|lswi} %0,%1,%2\;{l|lwz} %1,%2(%1)\", xop);
e82ee4cc
RK
5647 return \"\";
5648 }
5649 else if (i == 0)
5650 {
5651 xop[0] = operands[1];
5652 xop[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1);
5653 xop[2] = GEN_INT (4 * (words-1));
5654 output_asm_insn (\"{cal %0,4(%0)|addi %0,%0,4}\;{lsi|lswi} %1,%0,%2\;{l|lwz} %0,-4(%0)\", xop);
5655 return \"\";
5656 }
5657 else
5658 {
5659 for (j = 0; j < words; j++)
5660 if (j != i)
5661 {
5662 xop[0] = gen_rtx (REG, SImode, REGNO (operands[1]) + j);
5663 xop[1] = operands[2];
5664 xop[2] = GEN_INT (j * 4);
5665 output_asm_insn (\"{l|lwz} %0,%2(%1)\", xop);
5666 }
5667 xop[0] = operands[2];
5668 xop[1] = GEN_INT (i * 4);
5669 output_asm_insn (\"{l|lwz} %0,%1(%0)\", xop);
5670 return \"\";
5671 }
1fd4e8c1
RK
5672 }
5673
e82ee4cc 5674 return \"{lsi|lswi} %1,%2,%N0\";
1fd4e8c1 5675}"
b19003d8 5676 [(set_attr "type" "load")
e82ee4cc 5677 (set_attr "length" "32")])
1fd4e8c1 5678\f
b19003d8 5679
1fd4e8c1 5680(define_expand "store_multiple"
2f622005
RK
5681 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
5682 (match_operand:SI 1 "" ""))
5683 (clobber (scratch:SI))
5684 (use (match_operand:SI 2 "" ""))])]
7e69e155 5685 "TARGET_STRING"
1fd4e8c1
RK
5686 "
5687{
5688 int regno;
5689 int count;
5690 rtx to;
5691 int i;
5692
5693 /* Support only storing a constant number of fixed-point registers to
5694 memory and only bother with this if more than two; the machine
5695 doesn't support more than eight. */
5696 if (GET_CODE (operands[2]) != CONST_INT
5697 || INTVAL (operands[2]) <= 2
5698 || INTVAL (operands[2]) > 8
5699 || GET_CODE (operands[0]) != MEM
5700 || GET_CODE (operands[1]) != REG
5701 || REGNO (operands[1]) >= 32)
5702 FAIL;
5703
5704 count = INTVAL (operands[2]);
5705 regno = REGNO (operands[1]);
5706
5707 operands[3] = gen_rtx (PARALLEL, VOIDmode, rtvec_alloc (count + 1));
5708 to = force_reg (SImode, XEXP (operands[0], 0));
5709
5710 XVECEXP (operands[3], 0, 0)
5711 = gen_rtx (SET, VOIDmode, gen_rtx (MEM, SImode, to), operands[1]);
5712 XVECEXP (operands[3], 0, 1) = gen_rtx (CLOBBER, VOIDmode,
5713 gen_rtx (SCRATCH, SImode));
5714
5715 for (i = 1; i < count; i++)
5716 XVECEXP (operands[3], 0, i + 1)
5717 = gen_rtx (SET, VOIDmode,
5718 gen_rtx (MEM, SImode, plus_constant (to, i * 4)),
5719 gen_rtx (REG, SImode, regno + i));
5720}")
5721
5722(define_insn ""
5723 [(match_parallel 0 "store_multiple_operation"
5724 [(set (match_operand:SI 1 "indirect_operand" "=Q")
cd2b37d9 5725 (match_operand:SI 2 "gpc_reg_operand" "r"))
1fd4e8c1 5726 (clobber (match_scratch:SI 3 "=q"))])]
7e69e155 5727 "TARGET_STRING && TARGET_POWER"
d14a6d05
MM
5728 "{stsi|stswi} %2,%P1,%O0")
5729
5730(define_insn ""
5731 [(match_parallel 0 "store_multiple_operation"
4c99e795 5732 [(set (mem:SI (match_operand:SI 1 "register_operand" "b"))
d14a6d05
MM
5733 (match_operand:SI 2 "gpc_reg_operand" "r"))
5734 (clobber (match_scratch:SI 3 "X"))])]
7e69e155 5735 "TARGET_STRING && !TARGET_POWER"
4c99e795 5736 "{stsi|stswi} %2,%1,%O0")
7e69e155
MM
5737
5738\f
5739;; String/block move insn.
5740;; Argument 0 is the destination
5741;; Argument 1 is the source
5742;; Argument 2 is the length
5743;; Argument 3 is the alignment
5744
5745(define_expand "movstrsi"
b6c9286a
MM
5746 [(parallel [(set (match_operand:BLK 0 "" "")
5747 (match_operand:BLK 1 "" ""))
5748 (use (match_operand:SI 2 "" ""))
5749 (use (match_operand:SI 3 "" ""))])]
7e69e155
MM
5750 ""
5751 "
5752{
5753 if (expand_block_move (operands))
5754 DONE;
5755 else
5756 FAIL;
5757}")
5758
5759;; Move up to 32 bytes at a time. The fixed registers are needed because the
5760;; register allocator doesn't have a clue about allocating 8 word registers
5761(define_expand "movstrsi_8reg"
b6c9286a
MM
5762 [(parallel [(set (match_operand 0 "" "")
5763 (match_operand 1 "" ""))
5764 (use (match_operand 2 "" ""))
5765 (use (match_operand 3 "" ""))
7e69e155
MM
5766 (clobber (reg:SI 5))
5767 (clobber (reg:SI 6))
5768 (clobber (reg:SI 7))
5769 (clobber (reg:SI 8))
5770 (clobber (reg:SI 9))
5771 (clobber (reg:SI 10))
5772 (clobber (reg:SI 11))
5773 (clobber (reg:SI 12))
3c67b673 5774 (clobber (match_scratch:SI 4 ""))])]
7e69e155
MM
5775 "TARGET_STRING"
5776 "")
5777
5778(define_insn ""
3c67b673
RK
5779 [(set (mem:BLK (match_operand:SI 0 "register_operand" "b"))
5780 (mem:BLK (match_operand:SI 1 "register_operand" "b")))
5781 (use (match_operand:SI 2 "immediate_operand" "i"))
5782 (use (match_operand:SI 3 "immediate_operand" "i"))
5783 (clobber (match_operand:SI 4 "register_operand" "=r"))
7e69e155
MM
5784 (clobber (reg:SI 6))
5785 (clobber (reg:SI 7))
5786 (clobber (reg:SI 8))
5787 (clobber (reg:SI 9))
5788 (clobber (reg:SI 10))
5789 (clobber (reg:SI 11))
5790 (clobber (reg:SI 12))
3c67b673 5791 (clobber (match_scratch:SI 5 "=q"))]
7e69e155
MM
5792 "TARGET_STRING && TARGET_POWER
5793 && ((INTVAL (operands[2]) > 24 && INTVAL (operands[2]) < 32) || INTVAL (operands[2]) == 0)
5794 && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 12)
5795 && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 12)
3c67b673
RK
5796 && REGNO (operands[4]) == 5"
5797 "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2"
5798 [(set_attr "length" "8")])
7e69e155
MM
5799
5800(define_insn ""
3c67b673
RK
5801 [(set (mem:BLK (match_operand:SI 0 "register_operand" "b"))
5802 (mem:BLK (match_operand:SI 1 "register_operand" "b")))
5803 (use (match_operand:SI 2 "immediate_operand" "i"))
5804 (use (match_operand:SI 3 "immediate_operand" "i"))
5805 (clobber (match_operand:SI 4 "register_operand" "=r"))
7e69e155
MM
5806 (clobber (reg:SI 6))
5807 (clobber (reg:SI 7))
5808 (clobber (reg:SI 8))
5809 (clobber (reg:SI 9))
5810 (clobber (reg:SI 10))
5811 (clobber (reg:SI 11))
5812 (clobber (reg:SI 12))
3c67b673 5813 (clobber (match_scratch:SI 5 "X"))]
7e69e155
MM
5814 "TARGET_STRING && !TARGET_POWER
5815 && ((INTVAL (operands[2]) > 24 && INTVAL (operands[2]) < 32) || INTVAL (operands[2]) == 0)
5816 && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 12)
5817 && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 12)
3c67b673
RK
5818 && REGNO (operands[4]) == 5"
5819 "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2"
5820 [(set_attr "length" "8")])
7e69e155
MM
5821
5822;; Move up to 24 bytes at a time. The fixed registers are needed because the
5823;; register allocator doesn't have a clue about allocating 6 word registers
5824(define_expand "movstrsi_6reg"
b6c9286a
MM
5825 [(parallel [(set (match_operand 0 "" "")
5826 (match_operand 1 "" ""))
5827 (use (match_operand 2 "" ""))
5828 (use (match_operand 3 "" ""))
7e69e155
MM
5829 (clobber (reg:SI 7))
5830 (clobber (reg:SI 8))
5831 (clobber (reg:SI 9))
5832 (clobber (reg:SI 10))
5833 (clobber (reg:SI 11))
5834 (clobber (reg:SI 12))
3c67b673 5835 (clobber (match_scratch:SI 4 ""))])]
7e69e155
MM
5836 "TARGET_STRING"
5837 "")
5838
5839(define_insn ""
3c67b673
RK
5840 [(set (mem:BLK (match_operand:SI 0 "register_operand" "b"))
5841 (mem:BLK (match_operand:SI 1 "register_operand" "b")))
5842 (use (match_operand:SI 2 "immediate_operand" "i"))
5843 (use (match_operand:SI 3 "immediate_operand" "i"))
5844 (clobber (match_operand:SI 4 "register_operand" "=r"))
7e69e155
MM
5845 (clobber (reg:SI 8))
5846 (clobber (reg:SI 9))
5847 (clobber (reg:SI 10))
5848 (clobber (reg:SI 11))
5849 (clobber (reg:SI 12))
3c67b673 5850 (clobber (match_scratch:SI 5 "=q"))]
7e69e155
MM
5851 "TARGET_STRING && TARGET_POWER
5852 && INTVAL (operands[2]) > 16 && INTVAL (operands[2]) <= 24
5853 && (REGNO (operands[0]) < 7 || REGNO (operands[0]) > 12)
5854 && (REGNO (operands[1]) < 7 || REGNO (operands[1]) > 12)
3c67b673
RK
5855 && REGNO (operands[4]) == 7"
5856 "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2"
5857 [(set_attr "length" "8")])
7e69e155
MM
5858
5859(define_insn ""
3c67b673
RK
5860 [(set (mem:BLK (match_operand:SI 0 "register_operand" "b"))
5861 (mem:BLK (match_operand:SI 1 "register_operand" "b")))
5862 (use (match_operand:SI 2 "immediate_operand" "i"))
5863 (use (match_operand:SI 3 "immediate_operand" "i"))
5864 (clobber (match_operand:SI 4 "register_operand" "=r"))
7e69e155
MM
5865 (clobber (reg:SI 8))
5866 (clobber (reg:SI 9))
5867 (clobber (reg:SI 10))
5868 (clobber (reg:SI 11))
5869 (clobber (reg:SI 12))
3c67b673 5870 (clobber (match_scratch:SI 5 "X"))]
7e69e155
MM
5871 "TARGET_STRING && !TARGET_POWER
5872 && INTVAL (operands[2]) > 16 && INTVAL (operands[2]) <= 32
5873 && (REGNO (operands[0]) < 7 || REGNO (operands[0]) > 12)
5874 && (REGNO (operands[1]) < 7 || REGNO (operands[1]) > 12)
3c67b673
RK
5875 && REGNO (operands[4]) == 7"
5876 "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2"
5877 [(set_attr "length" "8")])
7e69e155
MM
5878
5879;; Move up to 16 bytes at a time, using 4 fixed registers to avoid spill problems
5880;; with TImode
5881(define_expand "movstrsi_4reg"
b6c9286a
MM
5882 [(parallel [(set (match_operand 0 "" "")
5883 (match_operand 1 "" ""))
5884 (use (match_operand 2 "" ""))
5885 (use (match_operand 3 "" ""))
7e69e155
MM
5886 (clobber (reg:SI 9))
5887 (clobber (reg:SI 10))
5888 (clobber (reg:SI 11))
5889 (clobber (reg:SI 12))
3c67b673 5890 (clobber (match_scratch:SI 4 ""))])]
7e69e155
MM
5891 "TARGET_STRING"
5892 "")
5893
5894(define_insn ""
3c67b673
RK
5895 [(set (mem:BLK (match_operand:SI 0 "register_operand" "b"))
5896 (mem:BLK (match_operand:SI 1 "register_operand" "b")))
5897 (use (match_operand:SI 2 "immediate_operand" "i"))
5898 (use (match_operand:SI 3 "immediate_operand" "i"))
5899 (clobber (match_operand:SI 4 "register_operand" "=r"))
7e69e155
MM
5900 (clobber (reg:SI 10))
5901 (clobber (reg:SI 11))
5902 (clobber (reg:SI 12))
3c67b673 5903 (clobber (match_scratch:SI 5 "=q"))]
7e69e155
MM
5904 "TARGET_STRING && TARGET_POWER
5905 && INTVAL (operands[2]) > 8 && INTVAL (operands[2]) <= 16
5906 && (REGNO (operands[0]) < 9 || REGNO (operands[0]) > 12)
5907 && (REGNO (operands[1]) < 9 || REGNO (operands[1]) > 12)
3c67b673
RK
5908 && REGNO (operands[4]) == 9"
5909 "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2"
5910 [(set_attr "length" "8")])
7e69e155
MM
5911
5912(define_insn ""
3c67b673
RK
5913 [(set (mem:BLK (match_operand:SI 0 "register_operand" "b"))
5914 (mem:BLK (match_operand:SI 1 "register_operand" "b")))
5915 (use (match_operand:SI 2 "immediate_operand" "i"))
5916 (use (match_operand:SI 3 "immediate_operand" "i"))
5917 (clobber (match_operand:SI 4 "register_operand" "=r"))
7e69e155
MM
5918 (clobber (reg:SI 10))
5919 (clobber (reg:SI 11))
5920 (clobber (reg:SI 12))
3c67b673 5921 (clobber (match_scratch:SI 5 "X"))]
7e69e155
MM
5922 "TARGET_STRING && !TARGET_POWER
5923 && INTVAL (operands[2]) > 8 && INTVAL (operands[2]) <= 16
5924 && (REGNO (operands[0]) < 9 || REGNO (operands[0]) > 12)
5925 && (REGNO (operands[1]) < 9 || REGNO (operands[1]) > 12)
3c67b673
RK
5926 && REGNO (operands[4]) == 9"
5927 "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2"
5928 [(set_attr "length" "8")])
7e69e155
MM
5929
5930;; Move up to 8 bytes at a time.
5931(define_expand "movstrsi_2reg"
b6c9286a
MM
5932 [(parallel [(set (match_operand 0 "" "")
5933 (match_operand 1 "" ""))
5934 (use (match_operand 2 "" ""))
5935 (use (match_operand 3 "" ""))
3c67b673
RK
5936 (clobber (match_scratch:DI 4 ""))
5937 (clobber (match_scratch:SI 5 ""))])]
7e69e155
MM
5938 "TARGET_STRING && !TARGET_64BIT"
5939 "")
5940
5941(define_insn ""
3c67b673
RK
5942 [(set (mem:BLK (match_operand:SI 0 "register_operand" "b"))
5943 (mem:BLK (match_operand:SI 1 "register_operand" "b")))
5944 (use (match_operand:SI 2 "immediate_operand" "i"))
5945 (use (match_operand:SI 3 "immediate_operand" "i"))
5946 (clobber (match_scratch:DI 4 "=&r"))
5947 (clobber (match_scratch:SI 5 "=q"))]
7e69e155 5948 "TARGET_STRING && TARGET_POWER && !TARGET_64BIT
3c67b673
RK
5949 && INTVAL (operands[2]) > 4 && INTVAL (operands[2]) <= 8"
5950 "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2"
5951 [(set_attr "length" "8")])
7e69e155
MM
5952
5953(define_insn ""
3c67b673
RK
5954 [(set (mem:BLK (match_operand:SI 0 "register_operand" "b"))
5955 (mem:BLK (match_operand:SI 1 "register_operand" "b")))
5956 (use (match_operand:SI 2 "immediate_operand" "i"))
5957 (use (match_operand:SI 3 "immediate_operand" "i"))
5958 (clobber (match_scratch:DI 4 "=&r"))
5959 (clobber (match_scratch:SI 5 "X"))]
7e69e155
MM
5960 "TARGET_STRING && !TARGET_POWER && !TARGET_64BIT
5961 && INTVAL (operands[2]) > 4 && INTVAL (operands[2]) <= 8"
3c67b673
RK
5962 "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2"
5963 [(set_attr "length" "8")])
7e69e155
MM
5964
5965;; Move up to 4 bytes at a time.
5966(define_expand "movstrsi_1reg"
b6c9286a
MM
5967 [(parallel [(set (match_operand 0 "" "")
5968 (match_operand 1 "" ""))
5969 (use (match_operand 2 "" ""))
5970 (use (match_operand 3 "" ""))
3c67b673
RK
5971 (clobber (match_scratch:SI 4 ""))
5972 (clobber (match_scratch:SI 5 ""))])]
7e69e155
MM
5973 "TARGET_STRING"
5974 "")
5975
5976(define_insn ""
3c67b673
RK
5977 [(set (mem:BLK (match_operand:SI 0 "register_operand" "b"))
5978 (mem:BLK (match_operand:SI 1 "register_operand" "b")))
5979 (use (match_operand:SI 2 "immediate_operand" "i"))
5980 (use (match_operand:SI 3 "immediate_operand" "i"))
5981 (clobber (match_scratch:SI 4 "=&r"))
5982 (clobber (match_scratch:SI 5 "=q"))]
7e69e155
MM
5983 "TARGET_STRING && TARGET_POWER
5984 && INTVAL (operands[2]) > 0 && INTVAL (operands[2]) <= 4"
3c67b673
RK
5985 "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2"
5986 [(set_attr "length" "8")])
7e69e155
MM
5987
5988(define_insn ""
3c67b673
RK
5989 [(set (mem:BLK (match_operand:SI 0 "register_operand" "b"))
5990 (mem:BLK (match_operand:SI 1 "register_operand" "b")))
5991 (use (match_operand:SI 2 "immediate_operand" "i"))
5992 (use (match_operand:SI 3 "immediate_operand" "i"))
5993 (clobber (match_scratch:SI 4 "=&r"))
5994 (clobber (match_scratch:SI 5 "X"))]
7e69e155
MM
5995 "TARGET_STRING && !TARGET_POWER
5996 && INTVAL (operands[2]) > 0 && INTVAL (operands[2]) <= 4"
3c67b673
RK
5997 "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2"
5998 [(set_attr "length" "8")])
7e69e155 5999
1fd4e8c1 6000\f
7e69e155 6001;; Define insns that do load or store with update. Some of these we can
1fd4e8c1
RK
6002;; get by using pre-decrement or pre-increment, but the hardware can also
6003;; do cases where the increment is not the size of the object.
6004;;
6005;; In all these cases, we use operands 0 and 1 for the register being
6006;; incremented because those are the operands that local-alloc will
6007;; tie and these are the pair most likely to be tieable (and the ones
6008;; that will benefit the most).
6009
51b8fc2c
RK
6010(define_insn ""
6011 [(set (match_operand:DI 3 "gpc_reg_operand" "=r,r")
ad8bd902 6012 (mem:DI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0,0")
51b8fc2c
RK
6013 (match_operand:DI 2 "reg_or_short_operand" "r,I"))))
6014 (set (match_operand:DI 0 "gpc_reg_operand" "=b,b")
6015 (plus:DI (match_dup 1) (match_dup 2)))]
6016 "TARGET_POWERPC64"
6017 "@
6018 ldux %3,%0,%2
6019 ldu %3,%2(%0)"
6020 [(set_attr "type" "load")])
6021
287f13ff
RK
6022(define_insn ""
6023 [(set (match_operand:DI 3 "gpc_reg_operand" "=r")
6024 (sign_extend:DI
6025 (mem:SI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0")
6026 (match_operand:DI 2 "gpc_reg_operand" "r")))))
6027 (set (match_operand:DI 0 "gpc_reg_operand" "=b")
6028 (plus:DI (match_dup 1) (match_dup 2)))]
6029 "TARGET_POWERPC64"
6030 "lwaux %3,%0,%2"
6031 [(set_attr "type" "load")])
6032
4697a36c 6033(define_insn "movdi_update"
51b8fc2c
RK
6034 [(set (mem:DI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0,0")
6035 (match_operand:DI 2 "reg_or_short_operand" "r,I")))
6036 (match_operand:DI 3 "gpc_reg_operand" "r,r"))
6037 (set (match_operand:DI 0 "gpc_reg_operand" "=b,b")
6038 (plus:DI (match_dup 1) (match_dup 2)))]
6039 "TARGET_POWERPC64"
6040 "@
6041 stdux %3,%0,%2
6042 stdu %3,%2(%0)")
6043
1fd4e8c1 6044(define_insn ""
cd2b37d9
RK
6045 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
6046 (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
1fd4e8c1 6047 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
cd2b37d9 6048 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
1fd4e8c1
RK
6049 (plus:SI (match_dup 1) (match_dup 2)))]
6050 ""
6051 "@
ca7f5001
RK
6052 {lux|lwzux} %3,%0,%2
6053 {lu|lwzu} %3,%2(%0)"
cfb557c4 6054 [(set_attr "type" "load")])
1fd4e8c1 6055
4697a36c 6056(define_insn "movsi_update"
cd2b37d9 6057 [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
1fd4e8c1 6058 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
cd2b37d9
RK
6059 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
6060 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
1fd4e8c1
RK
6061 (plus:SI (match_dup 1) (match_dup 2)))]
6062 ""
6063 "@
ca7f5001
RK
6064 {stux|stwux} %3,%0,%2
6065 {stu|stwu} %3,%2(%0)")
1fd4e8c1
RK
6066
6067(define_insn ""
cd2b37d9
RK
6068 [(set (match_operand:HI 3 "gpc_reg_operand" "=r,r")
6069 (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
1fd4e8c1 6070 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
cd2b37d9 6071 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
1fd4e8c1
RK
6072 (plus:SI (match_dup 1) (match_dup 2)))]
6073 ""
6074 "@
5f243543
RK
6075 lhzux %3,%0,%2
6076 lhzu %3,%2(%0)"
cfb557c4 6077 [(set_attr "type" "load")])
1fd4e8c1
RK
6078
6079(define_insn ""
cd2b37d9 6080 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
1fd4e8c1 6081 (zero_extend:SI
cd2b37d9 6082 (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
1fd4e8c1 6083 (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
cd2b37d9 6084 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
1fd4e8c1
RK
6085 (plus:SI (match_dup 1) (match_dup 2)))]
6086 ""
6087 "@
5f243543
RK
6088 lhzux %3,%0,%2
6089 lhzu %3,%2(%0)"
cfb557c4 6090 [(set_attr "type" "load")])
1fd4e8c1
RK
6091
6092(define_insn ""
cd2b37d9 6093 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
1fd4e8c1 6094 (sign_extend:SI
cd2b37d9 6095 (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
1fd4e8c1 6096 (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
cd2b37d9 6097 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
1fd4e8c1
RK
6098 (plus:SI (match_dup 1) (match_dup 2)))]
6099 ""
6100 "@
5f243543
RK
6101 lhaux %3,%0,%2
6102 lhau %3,%2(%0)"
cfb557c4 6103 [(set_attr "type" "load")])
1fd4e8c1
RK
6104
6105(define_insn ""
cd2b37d9 6106 [(set (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
1fd4e8c1 6107 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
cd2b37d9
RK
6108 (match_operand:HI 3 "gpc_reg_operand" "r,r"))
6109 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
1fd4e8c1
RK
6110 (plus:SI (match_dup 1) (match_dup 2)))]
6111 ""
6112 "@
5f243543 6113 sthux %3,%0,%2
cfb557c4 6114 sthu %3,%2(%0)")
1fd4e8c1
RK
6115
6116(define_insn ""
cd2b37d9
RK
6117 [(set (match_operand:QI 3 "gpc_reg_operand" "=r,r")
6118 (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
1fd4e8c1 6119 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
cd2b37d9 6120 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
1fd4e8c1
RK
6121 (plus:SI (match_dup 1) (match_dup 2)))]
6122 ""
6123 "@
5f243543
RK
6124 lbzux %3,%0,%2
6125 lbzu %3,%2(%0)"
cfb557c4 6126 [(set_attr "type" "load")])
1fd4e8c1
RK
6127
6128(define_insn ""
cd2b37d9 6129 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
1fd4e8c1 6130 (zero_extend:SI
cd2b37d9 6131 (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
1fd4e8c1 6132 (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
cd2b37d9 6133 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
1fd4e8c1
RK
6134 (plus:SI (match_dup 1) (match_dup 2)))]
6135 ""
6136 "@
5f243543
RK
6137 lbzux %3,%0,%2
6138 lbzu %3,%2(%0)"
cfb557c4 6139 [(set_attr "type" "load")])
1fd4e8c1
RK
6140
6141(define_insn ""
cd2b37d9 6142 [(set (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
1fd4e8c1 6143 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
cd2b37d9
RK
6144 (match_operand:QI 3 "gpc_reg_operand" "r,r"))
6145 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
1fd4e8c1
RK
6146 (plus:SI (match_dup 1) (match_dup 2)))]
6147 ""
6148 "@
5f243543
RK
6149 stbux %3,%0,%2
6150 stbu %3,%2(%0)")
1fd4e8c1
RK
6151
6152(define_insn ""
cd2b37d9 6153 [(set (match_operand:SF 3 "gpc_reg_operand" "=f,f")
df8b713c 6154 (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
1fd4e8c1 6155 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
cd2b37d9 6156 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
1fd4e8c1 6157 (plus:SI (match_dup 1) (match_dup 2)))]
d14a6d05 6158 "TARGET_HARD_FLOAT"
1fd4e8c1 6159 "@
5f243543
RK
6160 lfsux %3,%0,%2
6161 lfsu %3,%2(%0)"
cfb557c4 6162 [(set_attr "type" "fpload")])
1fd4e8c1
RK
6163
6164(define_insn ""
cd2b37d9 6165 [(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
1fd4e8c1 6166 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
cd2b37d9
RK
6167 (match_operand:SF 3 "gpc_reg_operand" "f,f"))
6168 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
1fd4e8c1 6169 (plus:SI (match_dup 1) (match_dup 2)))]
d14a6d05 6170 "TARGET_HARD_FLOAT"
1fd4e8c1 6171 "@
85fff2f3
RK
6172 stfsux %3,%0,%2
6173 stfsu %3,%2(%0)")
1fd4e8c1
RK
6174
6175(define_insn ""
cd2b37d9
RK
6176 [(set (match_operand:DF 3 "gpc_reg_operand" "=f,f")
6177 (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
1fd4e8c1 6178 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
cd2b37d9 6179 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
1fd4e8c1 6180 (plus:SI (match_dup 1) (match_dup 2)))]
d14a6d05 6181 "TARGET_HARD_FLOAT"
1fd4e8c1 6182 "@
5f243543
RK
6183 lfdux %3,%0,%2
6184 lfdu %3,%2(%0)"
cfb557c4 6185 [(set_attr "type" "fpload")])
1fd4e8c1
RK
6186
6187(define_insn ""
cd2b37d9 6188 [(set (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
1fd4e8c1 6189 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
cd2b37d9
RK
6190 (match_operand:DF 3 "gpc_reg_operand" "f,f"))
6191 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
1fd4e8c1 6192 (plus:SI (match_dup 1) (match_dup 2)))]
d14a6d05 6193 "TARGET_HARD_FLOAT"
1fd4e8c1 6194 "@
5f243543
RK
6195 stfdux %3,%0,%2
6196 stfdu %3,%2(%0)")
4c70a4f3
RK
6197
6198;; Peephole to convert two consecutive FP loads or stores into lfq/stfq.
6199
6200(define_peephole
6201 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
6202 (match_operand:DF 1 "memory_operand" ""))
6203 (set (match_operand:DF 2 "gpc_reg_operand" "=f")
6204 (match_operand:DF 3 "memory_operand" ""))]
6205 "TARGET_POWER2
d14a6d05 6206 && TARGET_HARD_FLOAT
4c70a4f3
RK
6207 && registers_ok_for_quad_peep (operands[0], operands[2])
6208 && ! MEM_VOLATILE_P (operands[1]) && ! MEM_VOLATILE_P (operands[3])
6209 && addrs_ok_for_quad_peep (XEXP (operands[1], 0), XEXP (operands[3], 0))"
6210 "lfq%U1%X1 %0,%1")
6211
6212(define_peephole
6213 [(set (match_operand:DF 0 "memory_operand" "")
6214 (match_operand:DF 1 "gpc_reg_operand" "f"))
6215 (set (match_operand:DF 2 "memory_operand" "")
6216 (match_operand:DF 3 "gpc_reg_operand" "f"))]
6217 "TARGET_POWER2
d14a6d05 6218 && TARGET_HARD_FLOAT
4c70a4f3
RK
6219 && registers_ok_for_quad_peep (operands[1], operands[3])
6220 && ! MEM_VOLATILE_P (operands[0]) && ! MEM_VOLATILE_P (operands[2])
6221 && addrs_ok_for_quad_peep (XEXP (operands[0], 0), XEXP (operands[2], 0))"
6222 "stfq%U0%X0 %1,%0")
1fd4e8c1
RK
6223\f
6224;; Next come insns related to the calling sequence.
6225;;
6226;; First, an insn to allocate new stack space for dynamic use (e.g., alloca).
7e69e155 6227;; We move the back-chain and decrement the stack pointer.
1fd4e8c1
RK
6228
6229(define_expand "allocate_stack"
6230 [(set (reg:SI 1)
01def764 6231 (minus:SI (reg:SI 1) (match_operand:SI 0 "reg_or_short_operand" "")))]
1fd4e8c1
RK
6232 ""
6233 "
4697a36c 6234{ rtx chain = gen_reg_rtx (Pmode);
1fd4e8c1 6235 rtx stack_bot = gen_rtx (MEM, Pmode, stack_pointer_rtx);
4697a36c 6236 rtx neg_op0;
1fd4e8c1
RK
6237
6238 emit_move_insn (chain, stack_bot);
4697a36c 6239
4697a36c
MM
6240 if (GET_CODE (operands[0]) != CONST_INT
6241 || INTVAL (operands[0]) < -32767
6242 || INTVAL (operands[0]) > 32768)
6243 {
6244 neg_op0 = gen_reg_rtx (Pmode);
6245 if (TARGET_POWERPC64)
6246 emit_insn (gen_negdi2 (neg_op0, operands[0]));
6247 else
6248 emit_insn (gen_negsi2 (neg_op0, operands[0]));
6249 }
6250 else
6251 neg_op0 = GEN_INT (- INTVAL (operands[0]));
6252
6253 if (TARGET_POWERPC64)
6254 emit_insn (gen_movdi_update (stack_pointer_rtx, stack_pointer_rtx, neg_op0, chain));
6255 else
6256 emit_insn (gen_movsi_update (stack_pointer_rtx, stack_pointer_rtx, neg_op0, chain));
6257
1fd4e8c1
RK
6258 DONE;
6259}")
59257ff7
RK
6260
6261;; These patterns say how to save and restore the stack pointer. We need not
6262;; save the stack pointer at function level since we are careful to
6263;; preserve the backchain. At block level, we have to restore the backchain
6264;; when we restore the stack pointer.
6265;;
6266;; For nonlocal gotos, we must save both the stack pointer and its
6267;; backchain and restore both. Note that in the nonlocal case, the
6268;; save area is a memory location.
6269
6270(define_expand "save_stack_function"
6271 [(use (const_int 0))]
6272 ""
6273 "")
6274
6275(define_expand "restore_stack_function"
6276 [(use (const_int 0))]
6277 ""
6278 "")
6279
6280(define_expand "restore_stack_block"
6281 [(set (match_dup 2) (mem:SI (match_operand:SI 0 "register_operand" "")))
6282 (set (match_dup 0) (match_operand:SI 1 "register_operand" ""))
6283 (set (mem:SI (match_dup 0)) (match_dup 2))]
6284 ""
6285 "
6286{ operands[2] = gen_reg_rtx (SImode); }")
6287
6288(define_expand "save_stack_nonlocal"
6289 [(match_operand:DI 0 "memory_operand" "")
6290 (match_operand:SI 1 "register_operand" "")]
6291 ""
6292 "
6293{
6294 rtx temp = gen_reg_rtx (SImode);
6295
6296 /* Copy the backchain to the first word, sp to the second. */
6297 emit_move_insn (temp, gen_rtx (MEM, SImode, operands[1]));
6298 emit_move_insn (operand_subword (operands[0], 0, 0, DImode), temp);
6299 emit_move_insn (operand_subword (operands[0], 1, 0, DImode), operands[1]);
6300 DONE;
6301}")
7e69e155 6302
59257ff7
RK
6303(define_expand "restore_stack_nonlocal"
6304 [(match_operand:SI 0 "register_operand" "")
6305 (match_operand:DI 1 "memory_operand" "")]
6306 ""
6307 "
6308{
6309 rtx temp = gen_reg_rtx (SImode);
6310
6311 /* Restore the backchain from the first word, sp from the second. */
6312 emit_move_insn (temp, operand_subword (operands[1], 0, 0, DImode));
6313 emit_move_insn (operands[0], operand_subword (operands[1], 1, 0, DImode));
6314 emit_move_insn (gen_rtx (MEM, SImode, operands[0]), temp);
6315 DONE;
6316}")
1fd4e8c1 6317\f
b6c9286a
MM
6318
6319;; A function pointer under AIX is a pointer to a data area whose first word
6320;; contains the actual address of the function, whose second word contains a
6321;; pointer to its TOC, and whose third word contains a value to place in the
6322;; static chain register (r11). Note that if we load the static chain, our
1fd4e8c1
RK
6323;; "trampoline" need not have any executable code.
6324;;
b6c9286a
MM
6325;; operands[0] is a register pointing to the 3 word descriptor (aka, the function address)
6326;; operands[1] is the stack size to clean up
6327;; operands[2] is the value FUNCTION_ARG returns for the VOID argument (must be 0 for AIX)
6328;; operands[3] is location to store the TOC
6329;; operands[4] is the TOC register
6330;; operands[5] is the static chain register
6331;;
6332;; We do not break this into separate insns, so that the scheduler will not try
6333;; to move the load of the new TOC before any loads from the TOC.
6334
6335(define_insn "call_indirect_aix"
6336 [(call (mem:SI (match_operand:SI 0 "register_operand" "b"))
6337 (match_operand 1 "const_int_operand" "n"))
6338 (use (match_operand 2 "const_int_operand" "O"))
6339 (use (match_operand 3 "offsettable_addr_operand" "p"))
6340 (use (match_operand 4 "register_operand" "r"))
6341 (clobber (match_operand 5 "register_operand" "=r"))
6342 (clobber (match_scratch:SI 6 "=&r"))
6343 (clobber (match_scratch:SI 7 "=l"))]
6344 "DEFAULT_ABI == ABI_AIX"
6345 "{st|stw} %4,%a3\;{l|lwz} %6,0(%0)\;{l|lwz} %4,4(%0);\;mt%7 %6\;{l|lwz} %5,8(%0)\;{brl|blrl}\;{l|lwz} %4,%a3"
6346 [(set_attr "length" "28")])
6347
6348(define_insn "call_value_indirect_aix"
6349 [(set (match_operand 0 "register_operand" "fg")
6350 (call (mem:SI (match_operand:SI 1 "register_operand" "b"))
6351 (match_operand 2 "const_int_operand" "n")))
6352 (use (match_operand 3 "const_int_operand" "O"))
6353 (use (match_operand 4 "offsettable_addr_operand" "p"))
6354 (use (match_operand 5 "register_operand" "r"))
6355 (clobber (match_operand 6 "register_operand" "=r"))
6356 (clobber (match_scratch:SI 7 "=&r"))
6357 (clobber (match_scratch:SI 8 "=l"))]
6358 "DEFAULT_ABI == ABI_AIX"
6359 "{st|stw} %5,%a4\;{l|lwz} %7,0(%1)\;{l|lwz} %5,4(%1);\;mt%8 %7\;{l|lwz} %6,8(%1)\;{brl|blrl}\;{l|lwz} %5,%a4"
6360 [(set_attr "length" "28")])
6361
6362;; A function pointer undef NT is a pointer to a data area whose first word
6363;; contains the actual address of the function, whose second word contains a
6364;; pointer to its TOC. The static chain is not stored under NT, which means
6365;; that we need a trampoline.
6366;;
6367;; operands[0] is an SImode pseudo in which we place the address of the function.
6368;; operands[1] is the stack size to clean up
6369;; operands[2] is the value FUNCTION_ARG returns for the VOID argument (must be 0 for NT)
6370;; operands[3] is location to store the TOC
6371;; operands[4] is the TOC register
6372;;
6373;; We do not break this into separate insns, so that the scheduler will not try
6374;; to move the load of the new TOC before any loads from the TOC.
6375
6376(define_insn "call_indirect_nt"
6377 [(call (mem:SI (match_operand:SI 0 "register_operand" "b"))
6378 (match_operand 1 "const_int_operand" "n"))
6379 (use (match_operand 2 "const_int_operand" "O"))
6380 (use (match_operand 3 "offsettable_addr_operand" "p"))
6381 (use (match_operand 4 "register_operand" "r"))
6382 (clobber (match_scratch:SI 5 "=&r"))
6383 (clobber (match_scratch:SI 6 "=l"))]
6384 "DEFAULT_ABI == ABI_NT"
e1f83b4d 6385 "{st|stw} %4,%a3\;{l|lwz} %5,0(%0)\;{l|lwz} %4,4(%0)\;mt%6 %5\;{brl|blrl}\;{l|lwz} %4,%a3"
b6c9286a
MM
6386 [(set_attr "length" "24")])
6387
6388(define_insn "call_value_indirect_nt"
6389 [(set (match_operand 0 "register_operand" "fg")
6390 (call (mem:SI (match_operand:SI 1 "register_operand" "b"))
6391 (match_operand 2 "const_int_operand" "n")))
6392 (use (match_operand 3 "const_int_operand" "O"))
6393 (use (match_operand 4 "offsettable_addr_operand" "p"))
6394 (use (match_operand 5 "register_operand" "r"))
6395 (clobber (match_scratch:SI 6 "=&r"))
6396 (clobber (match_scratch:SI 7 "=l"))]
6397 "DEFAULT_ABI == ABI_NT"
e1f83b4d 6398 "{st|stw} %5,%a4\;{l|lwz} %6,0(%1)\;{l|lwz} %5,4(%1)\;mt%7 %6\;{brl|blrl}\;{l|lwz} %5,%a4"
b6c9286a
MM
6399 [(set_attr "length" "24")])
6400
6401;; A function pointer under System V is just a normal pointer
6402;; operands[0] is the function pointer
6403;; operands[1] is the stack size to clean up
6404;; operands[2] is the value FUNCTION_ARG returns for the VOID argument which indicates how to set cr1
6405
6406(define_insn "call_indirect_sysv"
6407 [(call (mem:SI (match_operand:SI 0 "register_operand" "l,l"))
6408 (match_operand 1 "const_int_operand" "n,n"))
6409 (use (match_operand 2 "const_int_operand" "O,n"))
6410 (clobber (match_scratch:SI 3 "=l,l"))]
6411 "DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_AIX_NODESC"
6412 "*
6413{
6414 if (INTVAL (operands[2]) > 0)
6415 return \"creqv 6,6,6\;{brl|blrl}\";
1fd4e8c1 6416
b6c9286a
MM
6417 else if (INTVAL (operands[2]) < 0)
6418 return \"crxor 6,6,6\;{brl|blrl}\";
6419
6420 return \"{brl|blrl}\";
6421}"
6422 [(set_attr "length" "4,8")])
6423
6424(define_insn "call_value_indirect_sysv"
6425 [(set (match_operand 0 "register_operand" "=fg,fg")
6426 (call (mem:SI (match_operand:SI 1 "register_operand" "l,l"))
6427 (match_operand 2 "const_int_operand" "n,n")))
6428 (use (match_operand 3 "const_int_operand" "O,n"))
6429 (clobber (match_scratch:SI 4 "=l,l"))]
6430 "DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_AIX_NODESC"
6431 "*
6432{
6433 if (INTVAL (operands[3]) > 0)
6434 return \"creqv 6,6,6\;{brl|blrl}\";
6435
6436 else if (INTVAL (operands[3]) < 0)
6437 return \"crxor 6,6,6\;{brl|blrl}\";
6438
6439 return \"{brl|blrl}\";
6440}"
6441 [(set_attr "length" "4,8")])
1fd4e8c1 6442
b6c9286a 6443;; Now the definitions for the call and call_value insns
1fd4e8c1
RK
6444(define_expand "call"
6445 [(parallel [(call (mem:SI (match_operand:SI 0 "address_operand" ""))
6446 (match_operand 1 "" ""))
4697a36c 6447 (use (match_operand 2 "" ""))
1fd4e8c1
RK
6448 (clobber (scratch:SI))])]
6449 ""
6450 "
6451{
6452 if (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != CONST_INT)
6453 abort ();
6454
6455 operands[0] = XEXP (operands[0], 0);
7509c759
MM
6456
6457 /* Convert NT DLL imports into an indirect call. */
6458 if (GET_CODE (operands[0]) == SYMBOL_REF
6459 && INTVAL (operands[2]) == (int)CALL_NT_DLLIMPORT)
6460 {
6461 operands[0] = rs6000_dll_import_ref (operands[0]);
6462 operands[2] = GEN_INT ((int)CALL_NORMAL);
6463 }
6464
1fd4e8c1
RK
6465 if (GET_CODE (operands[0]) != SYMBOL_REF)
6466 {
b6c9286a
MM
6467 if (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_AIX_NODESC)
6468 emit_call_insn (gen_call_indirect_sysv (force_reg (Pmode, operands[0]),
6469 operands[1], operands[2]));
6470 else
6471 {
6472 rtx toc_reg = gen_rtx (REG, Pmode, 2);
6473 rtx toc_addr = RS6000_SAVE_TOC;
1fd4e8c1 6474
b6c9286a
MM
6475 if (DEFAULT_ABI == ABI_AIX)
6476 {
6477 /* AIX function pointers are really pointers to a three word area */
6478 rtx static_chain = gen_rtx (REG, Pmode, STATIC_CHAIN_REGNUM);
6479 emit_call_insn (gen_call_indirect_aix (force_reg (Pmode, operands[0]),
6480 operands[1], operands[2],
6481 toc_addr, toc_reg, static_chain));
6482 }
6483 else if (DEFAULT_ABI == ABI_NT)
6484 {
6485 /* NT function pointers are really pointers to a two word area */
7509c759 6486 rs6000_save_toc_p = 1;
b6c9286a
MM
6487 emit_call_insn (gen_call_indirect_nt (force_reg (Pmode, operands[0]),
6488 operands[1], operands[2],
6489 toc_addr, toc_reg));
6490 }
6491 else
6492 abort ();
6493 }
6494 DONE;
1fd4e8c1
RK
6495 }
6496}")
6497
6498(define_expand "call_value"
6499 [(parallel [(set (match_operand 0 "" "")
6500 (call (mem:SI (match_operand:SI 1 "address_operand" ""))
6501 (match_operand 2 "" "")))
4697a36c 6502 (use (match_operand 3 "" ""))
1fd4e8c1
RK
6503 (clobber (scratch:SI))])]
6504 ""
6505 "
6506{
6507 if (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != CONST_INT)
6508 abort ();
6509
6510 operands[1] = XEXP (operands[1], 0);
7509c759
MM
6511
6512 /* Convert NT DLL imports into an indirect call. */
6513 if (GET_CODE (operands[1]) == SYMBOL_REF
6514 && INTVAL (operands[3]) == (int)CALL_NT_DLLIMPORT)
6515 {
6516 operands[1] = rs6000_dll_import_ref (operands[1]);
6517 operands[3] = GEN_INT ((int)CALL_NORMAL);
6518 }
6519
1fd4e8c1
RK
6520 if (GET_CODE (operands[1]) != SYMBOL_REF)
6521 {
b6c9286a
MM
6522 if (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_AIX_NODESC)
6523 emit_call_insn (gen_call_value_indirect_sysv (operands[0], operands[1],
6524 operands[2], operands[3]));
6525 else
6526 {
6527 rtx toc_reg = gen_rtx (REG, Pmode, 2);
6528 rtx toc_addr = RS6000_SAVE_TOC;
1fd4e8c1 6529
b6c9286a
MM
6530 if (DEFAULT_ABI == ABI_AIX)
6531 {
6532 /* AIX function pointers are really pointers to a three word area */
6533 rtx static_chain = gen_rtx (REG, Pmode, STATIC_CHAIN_REGNUM);
6534 emit_call_insn (gen_call_value_indirect_aix (operands[0],
6535 force_reg (Pmode, operands[1]),
6536 operands[2], operands[3],
6537 toc_addr, toc_reg, static_chain));
6538 }
6539 else if (DEFAULT_ABI == ABI_NT)
6540 {
6541 /* NT function pointers are really pointers to a two word area */
7509c759 6542 rs6000_save_toc_p = 1;
b6c9286a
MM
6543 emit_call_insn (gen_call_value_indirect_nt (operands[0],
6544 force_reg (Pmode, operands[1]),
6545 operands[2], operands[3],
6546 toc_addr, toc_reg));
6547 }
6548 else
6549 abort ();
6550 }
6551 DONE;
1fd4e8c1
RK
6552 }
6553}")
6554
04780ee7 6555;; Call to function in current module. No TOC pointer reload needed.
4697a36c
MM
6556;; Operand2 is non-zero if we are using the V.4 calling sequence and
6557;; either the function was not prototyped, or it was prototyped as a
6558;; variable argument function. It is > 0 if FP registers were passed
6559;; and < 0 if they were not.
04780ee7
RK
6560
6561(define_insn ""
4697a36c
MM
6562 [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
6563 (match_operand 1 "" "g,g"))
6564 (use (match_operand:SI 2 "immediate_operand" "O,n"))
6565 (clobber (match_scratch:SI 3 "=l,l"))]
04780ee7 6566 ""
4697a36c
MM
6567 "*
6568{
7509c759
MM
6569 switch ((enum rs6000_call_cookie)INTVAL (operands[2]))
6570 {
6571 case CALL_V4_SET_FP_ARGS: output_asm_insn (\"crxor 6,6,6\", operands); break;
6572 case CALL_V4_CLEAR_FP_ARGS: output_asm_insn (\"creqv 6,6,6\", operands); break;
6573 }
4697a36c
MM
6574
6575 return \"bl %z0\";
6576}"
6577 [(set_attr "length" "4,8")])
04780ee7
RK
6578
6579;; Call to function which may be in another module. Restore the TOC
911f679c 6580;; pointer (r2) after the call unless this is System V.
4697a36c
MM
6581;; Operand2 is non-zero if we are using the V.4 calling sequence and
6582;; either the function was not prototyped, or it was prototyped as a
6583;; variable argument function. It is > 0 if FP registers were passed
6584;; and < 0 if they were not.
04780ee7 6585
1fd4e8c1 6586(define_insn ""
b6c9286a
MM
6587 [(call (mem:SI (match_operand:SI 0 "call_operand" "s,s"))
6588 (match_operand 1 "" "fg,fg"))
6589 (use (match_operand:SI 2 "immediate_operand" "O,n"))
6590 (clobber (match_scratch:SI 3 "=l,l"))]
6591 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_NT"
911f679c
MM
6592 "*
6593{
b6c9286a 6594 /* Indirect calls should go through call_indirect */
0f07e76c 6595 if (GET_CODE (operands[0]) == REG)
b6c9286a 6596 abort ();
911f679c 6597
7509c759
MM
6598 switch ((enum rs6000_call_cookie)INTVAL (operands[2]))
6599 {
6600 case CALL_V4_SET_FP_ARGS: output_asm_insn (\"crxor 6,6,6\", operands); break;
6601 case CALL_V4_CLEAR_FP_ARGS: output_asm_insn (\"creqv 6,6,6\", operands); break;
6602 }
6603
b6c9286a
MM
6604 return (TARGET_WINDOWS_NT) ? \"bl %z0\;.znop %z0\" : \"bl %z0\;%.\";
6605}"
6606 [(set_attr "length" "8,12")])
59313e4e 6607
b6c9286a
MM
6608(define_insn ""
6609 [(call (mem:SI (match_operand:SI 0 "call_operand" "s,s"))
6610 (match_operand 1 "" "fg,fg"))
6611 (use (match_operand:SI 2 "immediate_operand" "O,n"))
6612 (clobber (match_scratch:SI 3 "=l,l"))]
6613 "DEFAULT_ABI == ABI_AIX_NODESC || DEFAULT_ABI == ABI_V4"
6614 "*
6615{
b6c9286a 6616 /* Indirect calls should go through call_indirect */
0f07e76c 6617 if (GET_CODE (operands[0]) == REG)
b6c9286a 6618 abort ();
59313e4e 6619
7509c759
MM
6620 switch ((enum rs6000_call_cookie)INTVAL (operands[2]))
6621 {
6622 case CALL_V4_SET_FP_ARGS: output_asm_insn (\"crxor 6,6,6\", operands); break;
6623 case CALL_V4_CLEAR_FP_ARGS: output_asm_insn (\"creqv 6,6,6\", operands); break;
6624 }
6625
59313e4e 6626 return \"bl %z0\";
911f679c 6627}"
b6c9286a 6628 [(set_attr "length" "4,8")])
1fd4e8c1 6629
04780ee7 6630(define_insn ""
4697a36c
MM
6631 [(set (match_operand 0 "" "=fg,fg")
6632 (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
6633 (match_operand 2 "" "g,g")))
6634 (use (match_operand:SI 3 "immediate_operand" "O,n"))
6635 (clobber (match_scratch:SI 4 "=l,l"))]
04780ee7 6636 ""
4697a36c
MM
6637 "*
6638{
7509c759
MM
6639 switch ((enum rs6000_call_cookie)INTVAL (operands[3]))
6640 {
6641 case CALL_V4_SET_FP_ARGS: output_asm_insn (\"crxor 6,6,6\", operands); break;
6642 case CALL_V4_CLEAR_FP_ARGS: output_asm_insn (\"creqv 6,6,6\", operands); break;
6643 }
4697a36c
MM
6644
6645 return \"bl %z1\";
6646}"
6647 [(set_attr "length" "4,8")])
04780ee7 6648
1fd4e8c1 6649(define_insn ""
b6c9286a
MM
6650 [(set (match_operand 0 "" "=fg,fg")
6651 (call (mem:SI (match_operand:SI 1 "call_operand" "s,s"))
6652 (match_operand 2 "" "fg,fg")))
6653 (use (match_operand:SI 3 "immediate_operand" "O,n"))
6654 (clobber (match_scratch:SI 4 "=l,l"))]
6655 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_NT"
911f679c
MM
6656 "*
6657{
b6c9286a 6658 /* This should be handled by call_value_indirect */
59313e4e 6659 if (GET_CODE (operands[1]) == REG)
b6c9286a
MM
6660 abort ();
6661
7509c759
MM
6662 switch ((enum rs6000_call_cookie)INTVAL (operands[3]))
6663 {
6664 case CALL_V4_SET_FP_ARGS: output_asm_insn (\"crxor 6,6,6\", operands); break;
6665 case CALL_V4_CLEAR_FP_ARGS: output_asm_insn (\"creqv 6,6,6\", operands); break;
6666 }
6667
b6c9286a
MM
6668 return (TARGET_WINDOWS_NT) ? \"bl %z1\;.znop %z1\" : \"bl %z1\;%.\";
6669}"
6670 [(set_attr "length" "8,12")])
6671
6672(define_insn ""
6673 [(set (match_operand 0 "" "=fg,fg")
6674 (call (mem:SI (match_operand:SI 1 "call_operand" "s,s"))
6675 (match_operand 2 "" "fg,fg")))
6676 (use (match_operand:SI 3 "immediate_operand" "O,n"))
6677 (clobber (match_scratch:SI 4 "=l,l"))]
6678 "DEFAULT_ABI == ABI_AIX_NODESC || DEFAULT_ABI == ABI_V4"
6679 "*
6680{
b6c9286a 6681 /* This should be handled by call_value_indirect */
59313e4e 6682 if (GET_CODE (operands[1]) == REG)
b6c9286a 6683 abort ();
59313e4e 6684
7509c759
MM
6685 switch ((enum rs6000_call_cookie)INTVAL (operands[3]))
6686 {
6687 case CALL_V4_SET_FP_ARGS: output_asm_insn (\"crxor 6,6,6\", operands); break;
6688 case CALL_V4_CLEAR_FP_ARGS: output_asm_insn (\"creqv 6,6,6\", operands); break;
6689 }
6690
59313e4e 6691 return \"bl %z1\";
911f679c 6692}"
b6c9286a
MM
6693 [(set_attr "length" "4,8")])
6694
e6f948e3
RK
6695
6696;; Call subroutine returning any type.
6697
6698(define_expand "untyped_call"
6699 [(parallel [(call (match_operand 0 "" "")
6700 (const_int 0))
6701 (match_operand 1 "" "")
6702 (match_operand 2 "" "")])]
6703 ""
6704 "
6705{
6706 int i;
6707
4697a36c 6708 emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx, const0_rtx));
e6f948e3
RK
6709
6710 for (i = 0; i < XVECLEN (operands[2], 0); i++)
6711 {
6712 rtx set = XVECEXP (operands[2], 0, i);
6713 emit_move_insn (SET_DEST (set), SET_SRC (set));
6714 }
6715
6716 /* The optimizer does not know that the call sets the function value
6717 registers we stored in the result block. We avoid problems by
6718 claiming that all hard registers are used and clobbered at this
6719 point. */
6720 emit_insn (gen_blockage ());
6721
6722 DONE;
6723}")
6724
6725;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
6726;; all of memory. This blocks insns from being moved across this point.
6727
6728(define_insn "blockage"
6729 [(unspec_volatile [(const_int 0)] 0)]
6730 ""
6731 "")
4697a36c 6732
b6c9286a
MM
6733;; Synchronize instructions/data caches for V.4 trampolines
6734;; The extra memory_operand is to prevent the optimizer from
6735;; deleting insns with "no" effect.
6736(define_insn "icbi"
6737 [(unspec [(match_operand 0 "memory_operand" "=m")
6738 (match_operand 1 "register_operand" "b")
6739 (match_operand 2 "register_operand" "r")] 3)]
6740 "TARGET_POWERPC"
6741 "icbi %1,%2")
6742
6743(define_insn "dcbst"
6744 [(unspec [(match_operand 0 "memory_operand" "=m")
6745 (match_operand 1 "register_operand" "b")
6746 (match_operand 2 "register_operand" "r")] 4)]
6747 "TARGET_POWERPC"
6748 "dcbst %1,%2")
6749
6750(define_insn "sync"
6751 [(unspec [(match_operand 0 "memory_operand" "=m")] 5)]
4697a36c 6752 ""
b6c9286a
MM
6753 "{dcs|sync}")
6754
6755(define_insn "isync"
6756 [(unspec [(match_operand 0 "memory_operand" "=m")] 6)]
6757 ""
6758 "{ics|isync}")
4697a36c 6759
1fd4e8c1
RK
6760\f
6761;; Compare insns are next. Note that the RS/6000 has two types of compares,
7e69e155 6762;; signed & unsigned, and one type of branch.
1fd4e8c1
RK
6763;;
6764;; Start with the DEFINE_EXPANDs to generate the rtl for compares, scc
6765;; insns, and branches. We store the operands of compares until we see
6766;; how it is used.
6767(define_expand "cmpsi"
6768 [(set (cc0)
cd2b37d9 6769 (compare (match_operand:SI 0 "gpc_reg_operand" "")
1fd4e8c1
RK
6770 (match_operand:SI 1 "reg_or_short_operand" "")))]
6771 ""
6772 "
6773{
6774 /* Take care of the possibility that operands[1] might be negative but
6775 this might be a logical operation. That insn doesn't exist. */
6776 if (GET_CODE (operands[1]) == CONST_INT
6777 && INTVAL (operands[1]) < 0)
6778 operands[1] = force_reg (SImode, operands[1]);
6779
6780 rs6000_compare_op0 = operands[0];
6781 rs6000_compare_op1 = operands[1];
6782 rs6000_compare_fp_p = 0;
6783 DONE;
6784}")
6785
266eb58a
DE
6786(define_expand "cmpdi"
6787 [(set (cc0)
6788 (compare (match_operand:DI 0 "gpc_reg_operand" "")
6789 (match_operand:DI 1 "reg_or_short_operand" "")))]
6790 "TARGET_POWERPC64"
6791 "
6792{
6793 /* Take care of the possibility that operands[1] might be negative but
6794 this might be a logical operation. That insn doesn't exist. */
6795 if (GET_CODE (operands[1]) == CONST_INT
6796 && INTVAL (operands[1]) < 0)
6797 operands[1] = force_reg (DImode, operands[1]);
6798
6799 rs6000_compare_op0 = operands[0];
6800 rs6000_compare_op1 = operands[1];
6801 rs6000_compare_fp_p = 0;
6802 DONE;
6803}")
6804
1fd4e8c1 6805(define_expand "cmpsf"
cd2b37d9
RK
6806 [(set (cc0) (compare (match_operand:SF 0 "gpc_reg_operand" "")
6807 (match_operand:SF 1 "gpc_reg_operand" "")))]
d14a6d05 6808 "TARGET_HARD_FLOAT"
1fd4e8c1
RK
6809 "
6810{
6811 rs6000_compare_op0 = operands[0];
6812 rs6000_compare_op1 = operands[1];
6813 rs6000_compare_fp_p = 1;
6814 DONE;
6815}")
6816
6817(define_expand "cmpdf"
cd2b37d9
RK
6818 [(set (cc0) (compare (match_operand:DF 0 "gpc_reg_operand" "")
6819 (match_operand:DF 1 "gpc_reg_operand" "")))]
d14a6d05 6820 "TARGET_HARD_FLOAT"
1fd4e8c1
RK
6821 "
6822{
6823 rs6000_compare_op0 = operands[0];
6824 rs6000_compare_op1 = operands[1];
6825 rs6000_compare_fp_p = 1;
6826 DONE;
6827}")
6828
6829(define_expand "beq"
6830 [(set (match_dup 2) (match_dup 1))
6831 (set (pc)
6832 (if_then_else (eq (match_dup 2)
6833 (const_int 0))
6834 (label_ref (match_operand 0 "" ""))
6835 (pc)))]
6836 ""
6837 "
6838{ enum machine_mode mode = rs6000_compare_fp_p ? CCFPmode : CCmode;
6839 operands[1] = gen_rtx (COMPARE, mode,
6840 rs6000_compare_op0, rs6000_compare_op1);
6841 operands[2] = gen_reg_rtx (mode);
6842}")
6843
6844(define_expand "bne"
6845 [(set (match_dup 2) (match_dup 1))
6846 (set (pc)
6847 (if_then_else (ne (match_dup 2)
6848 (const_int 0))
6849 (label_ref (match_operand 0 "" ""))
6850 (pc)))]
6851 ""
6852 "
6853{ enum machine_mode mode = rs6000_compare_fp_p ? CCFPmode : CCmode;
6854 operands[1] = gen_rtx (COMPARE, mode,
6855 rs6000_compare_op0, rs6000_compare_op1);
6856 operands[2] = gen_reg_rtx (mode);
6857}")
6858
6859(define_expand "blt"
6860 [(set (match_dup 2) (match_dup 1))
6861 (set (pc)
6862 (if_then_else (lt (match_dup 2)
6863 (const_int 0))
6864 (label_ref (match_operand 0 "" ""))
6865 (pc)))]
6866 ""
6867 "
6868{ enum machine_mode mode = rs6000_compare_fp_p ? CCFPmode : CCmode;
6869 operands[1] = gen_rtx (COMPARE, mode,
6870 rs6000_compare_op0, rs6000_compare_op1);
6871 operands[2] = gen_reg_rtx (mode);
6872}")
6873
6874(define_expand "bgt"
6875 [(set (match_dup 2) (match_dup 1))
6876 (set (pc)
6877 (if_then_else (gt (match_dup 2)
6878 (const_int 0))
6879 (label_ref (match_operand 0 "" ""))
6880 (pc)))]
6881 ""
6882 "
6883{ enum machine_mode mode = rs6000_compare_fp_p ? CCFPmode : CCmode;
6884 operands[1] = gen_rtx (COMPARE, mode,
6885 rs6000_compare_op0, rs6000_compare_op1);
6886 operands[2] = gen_reg_rtx (mode);
6887}")
6888
6889(define_expand "ble"
6890 [(set (match_dup 2) (match_dup 1))
6891 (set (pc)
6892 (if_then_else (le (match_dup 2)
6893 (const_int 0))
6894 (label_ref (match_operand 0 "" ""))
6895 (pc)))]
6896 ""
6897 "
6898{ enum machine_mode mode = rs6000_compare_fp_p ? CCFPmode : CCmode;
6899 operands[1] = gen_rtx (COMPARE, mode,
6900 rs6000_compare_op0, rs6000_compare_op1);
6901 operands[2] = gen_reg_rtx (mode);
6902}")
6903
6904(define_expand "bge"
6905 [(set (match_dup 2) (match_dup 1))
6906 (set (pc)
6907 (if_then_else (ge (match_dup 2)
6908 (const_int 0))
6909 (label_ref (match_operand 0 "" ""))
6910 (pc)))]
6911 ""
6912 "
6913{ enum machine_mode mode = rs6000_compare_fp_p ? CCFPmode : CCmode;
6914 operands[1] = gen_rtx (COMPARE, mode,
6915 rs6000_compare_op0, rs6000_compare_op1);
6916 operands[2] = gen_reg_rtx (mode);
6917}")
6918
6919(define_expand "bgtu"
6920 [(set (match_dup 2) (match_dup 1))
6921 (set (pc)
6922 (if_then_else (gtu (match_dup 2)
6923 (const_int 0))
6924 (label_ref (match_operand 0 "" ""))
6925 (pc)))]
6926 ""
6927 "
6928{ operands[1] = gen_rtx (COMPARE, CCUNSmode,
6929 rs6000_compare_op0, rs6000_compare_op1);
6930 operands[2] = gen_reg_rtx (CCUNSmode);
6931}")
6932
6933(define_expand "bltu"
6934 [(set (match_dup 2) (match_dup 1))
6935 (set (pc)
6936 (if_then_else (ltu (match_dup 2)
6937 (const_int 0))
6938 (label_ref (match_operand 0 "" ""))
6939 (pc)))]
6940 ""
6941 "
6942{ operands[1] = gen_rtx (COMPARE, CCUNSmode,
6943 rs6000_compare_op0, rs6000_compare_op1);
6944 operands[2] = gen_reg_rtx (CCUNSmode);
6945}")
6946
6947(define_expand "bgeu"
6948 [(set (match_dup 2) (match_dup 1))
6949 (set (pc)
6950 (if_then_else (geu (match_dup 2)
6951 (const_int 0))
6952 (label_ref (match_operand 0 "" ""))
6953 (pc)))]
6954 ""
6955 "
6956{ operands[1] = gen_rtx (COMPARE, CCUNSmode,
6957 rs6000_compare_op0, rs6000_compare_op1);
6958 operands[2] = gen_reg_rtx (CCUNSmode);
6959}")
6960
6961(define_expand "bleu"
6962 [(set (match_dup 2) (match_dup 1))
6963 (set (pc)
6964 (if_then_else (leu (match_dup 2)
6965 (const_int 0))
6966 (label_ref (match_operand 0 "" ""))
6967 (pc)))]
6968 ""
6969 "
6970{ operands[1] = gen_rtx (COMPARE, CCUNSmode,
6971 rs6000_compare_op0, rs6000_compare_op1);
6972 operands[2] = gen_reg_rtx (CCUNSmode);
6973}")
6974
6975;; For SNE, we would prefer that the xor/abs sequence be used for integers.
6976;; For SEQ, likewise, except that comparisons with zero should be done
6977;; with an scc insns. However, due to the order that combine see the
6978;; resulting insns, we must, in fact, allow SEQ for integers. Fail in
6979;; the cases we don't want to handle.
6980(define_expand "seq"
6981 [(set (match_dup 2) (match_dup 1))
cd2b37d9 6982 (set (match_operand:SI 0 "gpc_reg_operand" "")
1fd4e8c1
RK
6983 (eq:SI (match_dup 2) (const_int 0)))]
6984 ""
6985 "
6986{ enum machine_mode mode = rs6000_compare_fp_p ? CCFPmode : CCmode;
6987 operands[1] = gen_rtx (COMPARE, mode,
6988 rs6000_compare_op0, rs6000_compare_op1);
6989 operands[2] = gen_reg_rtx (mode);
6990}")
6991
6992(define_expand "sne"
6993 [(set (match_dup 2) (match_dup 1))
cd2b37d9 6994 (set (match_operand:SI 0 "gpc_reg_operand" "")
1fd4e8c1
RK
6995 (ne:SI (match_dup 2) (const_int 0)))]
6996 ""
6997 "
6998{ if (! rs6000_compare_fp_p)
6999 FAIL;
7000
7001 operands[1] = gen_rtx (COMPARE, CCFPmode,
7002 rs6000_compare_op0, rs6000_compare_op1);
7003 operands[2] = gen_reg_rtx (CCFPmode);
7004}")
7005
7006;; A > 0 is best done using the portable sequence, so fail in that case.
7007(define_expand "sgt"
7008 [(set (match_dup 2) (match_dup 1))
cd2b37d9 7009 (set (match_operand:SI 0 "gpc_reg_operand" "")
1fd4e8c1
RK
7010 (gt:SI (match_dup 2) (const_int 0)))]
7011 ""
7012 "
7013{ enum machine_mode mode = rs6000_compare_fp_p ? CCFPmode : CCmode;
7014
7015 if (! rs6000_compare_fp_p && rs6000_compare_op1 == const0_rtx)
7016 FAIL;
7017
7018 operands[1] = gen_rtx (COMPARE, mode,
7019 rs6000_compare_op0, rs6000_compare_op1);
7020 operands[2] = gen_reg_rtx (mode);
7021}")
7022
7023;; A < 0 is best done in the portable way for A an integer.
7024(define_expand "slt"
7025 [(set (match_dup 2) (match_dup 1))
cd2b37d9 7026 (set (match_operand:SI 0 "gpc_reg_operand" "")
1fd4e8c1
RK
7027 (lt:SI (match_dup 2) (const_int 0)))]
7028 ""
7029 "
7030{ enum machine_mode mode = rs6000_compare_fp_p ? CCFPmode : CCmode;
7031
7032 if (! rs6000_compare_fp_p && rs6000_compare_op1 == const0_rtx)
7033 FAIL;
7034
7035 operands[1] = gen_rtx (COMPARE, mode,
7036 rs6000_compare_op0, rs6000_compare_op1);
7037 operands[2] = gen_reg_rtx (mode);
7038}")
7039
7040(define_expand "sge"
7041 [(set (match_dup 2) (match_dup 1))
cd2b37d9 7042 (set (match_operand:SI 0 "gpc_reg_operand" "")
1fd4e8c1
RK
7043 (ge:SI (match_dup 2) (const_int 0)))]
7044 ""
7045 "
7046{ enum machine_mode mode = rs6000_compare_fp_p ? CCFPmode : CCmode;
7047 operands[1] = gen_rtx (COMPARE, mode,
7048 rs6000_compare_op0, rs6000_compare_op1);
7049 operands[2] = gen_reg_rtx (mode);
7050}")
7051
7052;; A <= 0 is best done the portable way for A an integer.
7053(define_expand "sle"
7054 [(set (match_dup 2) (match_dup 1))
cd2b37d9 7055 (set (match_operand:SI 0 "gpc_reg_operand" "")
1fd4e8c1
RK
7056 (le:SI (match_dup 2) (const_int 0)))]
7057 ""
7058 "
7059{ enum machine_mode mode = rs6000_compare_fp_p ? CCFPmode : CCmode;
7060
7061 if (! rs6000_compare_fp_p && rs6000_compare_op1 == const0_rtx)
7062 FAIL;
7063
7064 operands[1] = gen_rtx (COMPARE, mode,
7065 rs6000_compare_op0, rs6000_compare_op1);
7066 operands[2] = gen_reg_rtx (mode);
7067}")
7068
7069(define_expand "sgtu"
7070 [(set (match_dup 2) (match_dup 1))
cd2b37d9 7071 (set (match_operand:SI 0 "gpc_reg_operand" "")
1fd4e8c1
RK
7072 (gtu:SI (match_dup 2) (const_int 0)))]
7073 ""
7074 "
7075{ operands[1] = gen_rtx (COMPARE, CCUNSmode,
7076 rs6000_compare_op0, rs6000_compare_op1);
7077 operands[2] = gen_reg_rtx (CCUNSmode);
7078}")
7079
7080(define_expand "sltu"
7081 [(set (match_dup 2) (match_dup 1))
cd2b37d9 7082 (set (match_operand:SI 0 "gpc_reg_operand" "")
1fd4e8c1
RK
7083 (ltu:SI (match_dup 2) (const_int 0)))]
7084 ""
7085 "
7086{ operands[1] = gen_rtx (COMPARE, CCUNSmode,
7087 rs6000_compare_op0, rs6000_compare_op1);
7088 operands[2] = gen_reg_rtx (CCUNSmode);
7089}")
7090
7091(define_expand "sgeu"
7092 [(set (match_dup 2) (match_dup 1))
cd2b37d9 7093 (set (match_operand:SI 0 "gpc_reg_operand" "")
1fd4e8c1
RK
7094 (geu:SI (match_dup 2) (const_int 0)))]
7095 ""
7096 "
7097{ operands[1] = gen_rtx (COMPARE, CCUNSmode,
7098 rs6000_compare_op0, rs6000_compare_op1);
7099 operands[2] = gen_reg_rtx (CCUNSmode);
7100}")
7101
7102(define_expand "sleu"
7103 [(set (match_dup 2) (match_dup 1))
cd2b37d9 7104 (set (match_operand:SI 0 "gpc_reg_operand" "")
1fd4e8c1
RK
7105 (leu:SI (match_dup 2) (const_int 0)))]
7106 ""
7107 "
7108{ operands[1] = gen_rtx (COMPARE, CCUNSmode,
7109 rs6000_compare_op0, rs6000_compare_op1);
7110 operands[2] = gen_reg_rtx (CCUNSmode);
7111}")
7112\f
7113;; Here are the actual compare insns.
7114(define_insn ""
7115 [(set (match_operand:CC 0 "cc_reg_operand" "=y")
cd2b37d9 7116 (compare:CC (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
7117 (match_operand:SI 2 "reg_or_short_operand" "rI")))]
7118 ""
7f340546 7119 "{cmp%I2|cmpw%I2} %0,%1,%2"
1fd4e8c1
RK
7120 [(set_attr "type" "compare")])
7121
266eb58a
DE
7122(define_insn ""
7123 [(set (match_operand:CC 0 "cc_reg_operand" "=y")
7124 (compare:CC (match_operand:DI 1 "gpc_reg_operand" "r")
7125 (match_operand:DI 2 "reg_or_short_operand" "rI")))]
7126 "TARGET_POWERPC64"
7127 "cmpd%I2 %0,%1,%2"
7128 [(set_attr "type" "compare")])
7129
f357808b
RK
7130;; If we are comparing a register for equality with a large constant,
7131;; we can do this with an XOR followed by a compare. But we need a scratch
7132;; register for the result of the XOR.
7133
7134(define_split
7135 [(set (match_operand:CC 0 "cc_reg_operand" "")
cd2b37d9 7136 (compare:CC (match_operand:SI 1 "gpc_reg_operand" "")
f357808b 7137 (match_operand:SI 2 "non_short_cint_operand" "")))
cd2b37d9 7138 (clobber (match_operand:SI 3 "gpc_reg_operand" ""))]
f357808b
RK
7139 "find_single_use (operands[0], insn, 0)
7140 && (GET_CODE (*find_single_use (operands[0], insn, 0)) == EQ
7141 || GET_CODE (*find_single_use (operands[0], insn, 0)) == NE)"
7142 [(set (match_dup 3) (xor:SI (match_dup 1) (match_dup 4)))
7143 (set (match_dup 0) (compare:CC (match_dup 3) (match_dup 5)))]
7144 "
7145{
7146 /* Get the constant we are comparing against, C, and see what it looks like
7147 sign-extended to 16 bits. Then see what constant could be XOR'ed
7148 with C to get the sign-extended value. */
7149
7150 int c = INTVAL (operands[2]);
7151 int sextc = (c << 16) >> 16;
7152 int xorv = c ^ sextc;
7153
7154 operands[4] = gen_rtx (CONST_INT, VOIDmode, xorv);
7155 operands[5] = gen_rtx (CONST_INT, VOIDmode, sextc);
7156}")
7157
1fd4e8c1
RK
7158(define_insn ""
7159 [(set (match_operand:CCUNS 0 "cc_reg_operand" "=y")
cd2b37d9 7160 (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
7161 (match_operand:SI 2 "reg_or_u_short_operand" "rI")))]
7162 ""
7f340546 7163 "{cmpl%I2|cmplw%I2} %0,%1,%W2"
1fd4e8c1
RK
7164 [(set_attr "type" "compare")])
7165
266eb58a
DE
7166(define_insn ""
7167 [(set (match_operand:CCUNS 0 "cc_reg_operand" "=y")
7168 (compare:CCUNS (match_operand:DI 1 "gpc_reg_operand" "r")
7169 (match_operand:DI 2 "reg_or_u_short_operand" "rI")))]
7170 ""
7171 "cmpld%I2 %0,%1,%W2"
7172 [(set_attr "type" "compare")])
7173
1fd4e8c1
RK
7174;; The following two insns don't exist as single insns, but if we provide
7175;; them, we can swap an add and compare, which will enable us to overlap more
7176;; of the required delay between a compare and branch. We generate code for
7177;; them by splitting.
7178
7179(define_insn ""
7180 [(set (match_operand:CC 3 "cc_reg_operand" "=y")
cd2b37d9 7181 (compare:CC (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 7182 (match_operand:SI 2 "short_cint_operand" "i")))
cd2b37d9 7183 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
7184 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "i")))]
7185 ""
baf97f86
RK
7186 "#"
7187 [(set_attr "length" "8")])
7e69e155 7188
1fd4e8c1
RK
7189(define_insn ""
7190 [(set (match_operand:CCUNS 3 "cc_reg_operand" "=y")
cd2b37d9 7191 (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 7192 (match_operand:SI 2 "u_short_cint_operand" "i")))
cd2b37d9 7193 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
7194 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "i")))]
7195 ""
baf97f86
RK
7196 "#"
7197 [(set_attr "length" "8")])
7e69e155 7198
1fd4e8c1
RK
7199(define_split
7200 [(set (match_operand:CC 3 "cc_reg_operand" "")
cd2b37d9 7201 (compare:CC (match_operand:SI 1 "gpc_reg_operand" "")
1fd4e8c1 7202 (match_operand:SI 2 "short_cint_operand" "")))
cd2b37d9 7203 (set (match_operand:SI 0 "gpc_reg_operand" "")
1fd4e8c1
RK
7204 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "")))]
7205 ""
7206 [(set (match_dup 3) (compare:CC (match_dup 1) (match_dup 2)))
7207 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 4)))])
7208
7209(define_split
7210 [(set (match_operand:CCUNS 3 "cc_reg_operand" "")
cd2b37d9 7211 (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "")
1fd4e8c1 7212 (match_operand:SI 2 "u_short_cint_operand" "")))
cd2b37d9 7213 (set (match_operand:SI 0 "gpc_reg_operand" "")
1fd4e8c1
RK
7214 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "")))]
7215 ""
7216 [(set (match_dup 3) (compare:CCUNS (match_dup 1) (match_dup 2)))
7217 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 4)))])
7218
7219(define_insn ""
7220 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
cd2b37d9
RK
7221 (compare:CCFP (match_operand:SF 1 "gpc_reg_operand" "f")
7222 (match_operand:SF 2 "gpc_reg_operand" "f")))]
d14a6d05 7223 "TARGET_HARD_FLOAT"
1fd4e8c1
RK
7224 "fcmpu %0,%1,%2"
7225 [(set_attr "type" "fpcompare")])
7226
7227(define_insn ""
7228 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
cd2b37d9
RK
7229 (compare:CCFP (match_operand:DF 1 "gpc_reg_operand" "f")
7230 (match_operand:DF 2 "gpc_reg_operand" "f")))]
d14a6d05 7231 "TARGET_HARD_FLOAT"
1fd4e8c1
RK
7232 "fcmpu %0,%1,%2"
7233 [(set_attr "type" "fpcompare")])
7234\f
7235;; Now we have the scc insns. We can do some combinations because of the
7236;; way the machine works.
7237;;
7238;; Note that this is probably faster if we can put an insn between the
c5defebb
RK
7239;; mfcr and rlinm, but this is tricky. Let's leave it for now. In most
7240;; cases the insns below which don't use an intermediate CR field will
7241;; be used instead.
1fd4e8c1 7242(define_insn ""
cd2b37d9 7243 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
7244 (match_operator:SI 1 "scc_comparison_operator"
7245 [(match_operand 2 "cc_reg_operand" "y")
7246 (const_int 0)]))]
7247 ""
ca7f5001 7248 "%D1mfcr %0\;{rlinm|rlwinm} %0,%0,%J1,1"
b19003d8 7249 [(set_attr "length" "12")])
1fd4e8c1
RK
7250
7251(define_insn ""
7252 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
7253 (compare:CC (match_operator:SI 1 "scc_comparison_operator"
7254 [(match_operand 2 "cc_reg_operand" "y")
7255 (const_int 0)])
7256 (const_int 0)))
cd2b37d9 7257 (set (match_operand:SI 3 "gpc_reg_operand" "=r")
1fd4e8c1
RK
7258 (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7259 ""
ca7f5001 7260 "%D1mfcr %3\;{rlinm.|rlwinm.} %3,%3,%J1,1"
b19003d8
RK
7261 [(set_attr "type" "delayed_compare")
7262 (set_attr "length" "12")])
1fd4e8c1
RK
7263
7264(define_insn ""
cd2b37d9 7265 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
7266 (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
7267 [(match_operand 2 "cc_reg_operand" "y")
7268 (const_int 0)])
7269 (match_operand:SI 3 "const_int_operand" "n")))]
7270 ""
7271 "*
7272{
7273 int is_bit = ccr_bit (operands[1], 1);
7274 int put_bit = 31 - (INTVAL (operands[3]) & 31);
7275 int count;
7276
7277 if (is_bit >= put_bit)
7278 count = is_bit - put_bit;
7279 else
7280 count = 32 - (put_bit - is_bit);
7281
7282 operands[4] = gen_rtx (CONST_INT, VOIDmode, count);
7283 operands[5] = gen_rtx (CONST_INT, VOIDmode, put_bit);
7284
ca7f5001 7285 return \"%D1mfcr %0\;{rlinm|rlwinm} %0,%0,%4,%5,%5\";
b19003d8
RK
7286}"
7287 [(set_attr "length" "12")])
1fd4e8c1
RK
7288
7289(define_insn ""
7290 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
7291 (compare:CC
7292 (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
7293 [(match_operand 2 "cc_reg_operand" "y")
7294 (const_int 0)])
7295 (match_operand:SI 3 "const_int_operand" "n"))
7296 (const_int 0)))
cd2b37d9 7297 (set (match_operand:SI 4 "gpc_reg_operand" "=r")
1fd4e8c1
RK
7298 (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
7299 (match_dup 3)))]
7300 ""
7301 "*
7302{
7303 int is_bit = ccr_bit (operands[1], 1);
7304 int put_bit = 31 - (INTVAL (operands[3]) & 31);
7305 int count;
7306
7307 if (is_bit >= put_bit)
7308 count = is_bit - put_bit;
7309 else
7310 count = 32 - (put_bit - is_bit);
7311
7312 operands[5] = gen_rtx (CONST_INT, VOIDmode, count);
7313 operands[6] = gen_rtx (CONST_INT, VOIDmode, put_bit);
7314
ca7f5001 7315 return \"%D1mfcr %4\;{rlinm.|rlwinm.} %4,%4,%5,%6,%6\";
1fd4e8c1 7316}"
b19003d8
RK
7317 [(set_attr "type" "delayed_compare")
7318 (set_attr "length" "12")])
1fd4e8c1 7319
c5defebb
RK
7320;; If we are comparing the result of two comparisons, this can be done
7321;; using creqv or crxor.
7322
7323(define_insn ""
7324 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y")
7325 (compare:CCEQ (match_operator 1 "scc_comparison_operator"
7326 [(match_operand 2 "cc_reg_operand" "y")
7327 (const_int 0)])
7328 (match_operator 3 "scc_comparison_operator"
7329 [(match_operand 4 "cc_reg_operand" "y")
7330 (const_int 0)])))]
7331 "REGNO (operands[2]) != REGNO (operands[4])"
7332 "*
7333{
7334 enum rtx_code code1, code2;
7335
7336 code1 = GET_CODE (operands[1]);
7337 code2 = GET_CODE (operands[3]);
7338
7339 if ((code1 == EQ || code1 == LT || code1 == GT
7340 || code1 == LTU || code1 == GTU
7341 || (code1 != NE && GET_MODE (operands[2]) == CCFPmode))
7342 !=
7343 (code2 == EQ || code2 == LT || code2 == GT
7344 || code2 == LTU || code2 == GTU
7345 || (code2 != NE && GET_MODE (operands[4]) == CCFPmode)))
7346 return \"%C1%C3crxor %E0,%j1,%j3\";
7347 else
7348 return \"%C1%C3creqv %E0,%j1,%j3\";
b19003d8
RK
7349}"
7350 [(set_attr "length" "12")])
c5defebb
RK
7351
7352;; There is a 3 cycle delay between consecutive mfcr instructions
7353;; so it is useful to combine 2 scc instructions to use only one mfcr.
7354
7355(define_peephole
cd2b37d9 7356 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
c5defebb
RK
7357 (match_operator:SI 1 "scc_comparison_operator"
7358 [(match_operand 2 "cc_reg_operand" "y")
7359 (const_int 0)]))
cd2b37d9 7360 (set (match_operand:SI 3 "gpc_reg_operand" "=r")
c5defebb
RK
7361 (match_operator:SI 4 "scc_comparison_operator"
7362 [(match_operand 5 "cc_reg_operand" "y")
7363 (const_int 0)]))]
7364 "REGNO (operands[2]) != REGNO (operands[5])"
ca7f5001 7365 "%D1%D4mfcr %3\;{rlinm|rlwinm} %0,%3,%J1,1\;{rlinm|rlwinm} %3,%3,%J4,1"
b19003d8 7366 [(set_attr "length" "20")])
c5defebb 7367
1fd4e8c1
RK
7368;; There are some scc insns that can be done directly, without a compare.
7369;; These are faster because they don't involve the communications between
7370;; the FXU and branch units. In fact, we will be replacing all of the
7371;; integer scc insns here or in the portable methods in emit_store_flag.
7372;;
7373;; Also support (neg (scc ..)) since that construct is used to replace
7374;; branches, (plus (scc ..) ..) since that construct is common and
7375;; takes no more insns than scc, and (and (neg (scc ..)) ..) in the
7376;; cases where it is no more expensive than (neg (scc ..)).
7377
7378;; Have reload force a constant into a register for the simple insns that
7379;; otherwise won't accept constants. We do this because it is faster than
7380;; the cmp/mfcr sequence we would otherwise generate.
7381
7382(define_insn ""
cd2b37d9
RK
7383 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r,r")
7384 (eq:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r")
1fd4e8c1
RK
7385 (match_operand:SI 2 "reg_or_cint_operand" "r,O,K,J,I")))
7386 (clobber (match_scratch:SI 3 "=r,&r,r,r,r"))]
7387 ""
7388 "@
ca7f5001 7389 xor %0,%1,%2\;{sfi|subfic} %3,%0,0\;{ae|adde} %0,%3,%0
71d2371f 7390 {sfi|subfic} %3,%1,0\;{ae|adde} %0,%3,%1
ca7f5001
RK
7391 {xoril|xori} %0,%1,%b2\;{sfi|subfic} %3,%0,0\;{ae|adde} %0,%3,%0
7392 {xoriu|xoris} %0,%1,%u2\;{sfi|subfic} %3,%0,0\;{ae|adde} %0,%3,%0
7393 {sfi|subfic} %0,%1,%2\;{sfi|subfic} %3,%0,0\;{ae|adde} %0,%3,%0"
b19003d8 7394 [(set_attr "length" "12,8,12,12,12")])
1fd4e8c1
RK
7395
7396(define_insn ""
7397 [(set (match_operand:CC 4 "cc_reg_operand" "=x,x,x,x,x")
7e69e155 7398 (compare:CC
cd2b37d9 7399 (eq:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r")
1fd4e8c1
RK
7400 (match_operand:SI 2 "reg_or_cint_operand" "r,O,K,J,I"))
7401 (const_int 0)))
cd2b37d9 7402 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r,r")
1fd4e8c1
RK
7403 (eq:SI (match_dup 1) (match_dup 2)))
7404 (clobber (match_scratch:SI 3 "=r,&r,r,r,r"))]
7405 ""
7406 "@
ca7f5001
RK
7407 xor %0,%1,%2\;{sfi|subfic} %3,%0,0\;{ae.|adde.} %0,%3,%0
7408 {sfi|subfic} %3,%1,0\;{ae.|adde.} %0,%3,%1
7409 {xoril|xori} %0,%1,%b2\;{sfi|subfic} %3,%0,0\;{ae.|adde.} %0,%3,%0
7410 {xoriu|xoris} %0,%1,%u2\;{sfi|subfic} %3,%0,0\;{ae.|adde.} %0,%3,%0
7411 {sfi|subfic} %0,%1,%2\;{sfi|subfic} %3,%0,0\;{ae.|adde.} %0,%3,%0"
b19003d8
RK
7412 [(set_attr "type" "compare")
7413 (set_attr "length" "12,8,12,12,12")])
7414
7415;; We have insns of the form shown by the first define_insn below. If
7416;; there is something inside the comparison operation, we must split it.
7417(define_split
7418 [(set (match_operand:SI 0 "gpc_reg_operand" "")
7419 (plus:SI (match_operator 1 "comparison_operator"
7420 [(match_operand:SI 2 "" "")
7421 (match_operand:SI 3
7422 "reg_or_cint_operand" "")])
7423 (match_operand:SI 4 "gpc_reg_operand" "")))
7424 (clobber (match_operand:SI 5 "register_operand" ""))]
7425 "! gpc_reg_operand (operands[2], SImode)"
7426 [(set (match_dup 5) (match_dup 2))
7427 (set (match_dup 2) (plus:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
7428 (match_dup 4)))])
1fd4e8c1
RK
7429
7430(define_insn ""
cd2b37d9
RK
7431 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r,r")
7432 (plus:SI (eq:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r")
1fd4e8c1 7433 (match_operand:SI 2 "reg_or_cint_operand" "r,O,K,J,I"))
cd2b37d9 7434 (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r,r")))
1fd4e8c1
RK
7435 (clobber (match_scratch:SI 4 "=&r,&r,&r,&r,&r"))]
7436 ""
7437 "@
ca7f5001
RK
7438 xor %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze|addze} %0,%3
7439 {sfi|subfic} %4,%1,0\;{aze|addze} %0,%3
7440 {xoril|xori} %4,%1,%b2\;{sfi|subfic} %4,%4,0\;{aze|addze} %0,%3
7441 {xoriu|xoris} %4,%1,%u2\;{sfi|subfic} %4,%4,0\;{aze|addze} %0,%3
d9d934ef 7442 {sfi|subfic} %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze|addze} %0,%3"
b19003d8 7443 [(set_attr "length" "12,8,12,12,12")])
1fd4e8c1
RK
7444
7445(define_insn ""
7446 [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,x,x,x")
7e69e155 7447 (compare:CC
1fd4e8c1 7448 (plus:SI
cd2b37d9 7449 (eq:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r")
1fd4e8c1 7450 (match_operand:SI 2 "reg_or_cint_operand" "r,O,K,J,I"))
cd2b37d9 7451 (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r,r"))
1fd4e8c1
RK
7452 (const_int 0)))
7453 (clobber (match_scratch:SI 4 "=&r,&r,&r,&r,&r"))]
7454 ""
7455 "@
ca7f5001
RK
7456 xor %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %4,%3
7457 {sfi|subfic} %4,%1,0\;{aze.|addze.} %0,%3
7458 {xoril|xori} %4,%1,%b2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %4,%3
7459 {xoriu|xoris} %4,%1,%u2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %4,%3
7460 {sfi|subfic} %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %4,%3"
b19003d8
RK
7461 [(set_attr "type" "compare")
7462 (set_attr "length" "12,8,12,12,12")])
1fd4e8c1
RK
7463
7464(define_insn ""
7465 [(set (match_operand:CC 5 "cc_reg_operand" "=x,x,x,x,x")
7e69e155 7466 (compare:CC
1fd4e8c1 7467 (plus:SI
cd2b37d9 7468 (eq:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r")
1fd4e8c1 7469 (match_operand:SI 2 "reg_or_cint_operand" "r,O,K,J,I"))
cd2b37d9 7470 (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r,r"))
1fd4e8c1 7471 (const_int 0)))
cd2b37d9 7472 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r,r")
1fd4e8c1
RK
7473 (plus:SI (eq:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
7474 (clobber (match_scratch:SI 4 "=&r,&r,&r,&r,&r"))]
7475 ""
7476 "@
ca7f5001
RK
7477 xor %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %0,%3
7478 {sfi|subfic} %4,%1,0\;{aze.|addze.} %4,%3
7479 {xoril|xori} %4,%1,%b2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %0,%3
7480 {xoriu|xoris} %4,%1,%u2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %0,%3
7481 {sfi|subfic} %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %0,%3"
b19003d8
RK
7482 [(set_attr "type" "compare")
7483 (set_attr "length" "12,8,12,12,12")])
1fd4e8c1
RK
7484
7485(define_insn ""
cd2b37d9 7486 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r,r")
deb9225a 7487 (neg:SI (eq:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r")
1fd4e8c1
RK
7488 (match_operand:SI 2 "reg_or_cint_operand" "r,O,K,J,I"))))]
7489 ""
7490 "@
ca7f5001
RK
7491 xor %0,%1,%2\;{ai|addic} %0,%0,-1\;{sfe|subfe} %0,%0,%0
7492 {ai|addic} %0,%1,-1\;{sfe|subfe} %0,%0,%0
7493 {xoril|xori} %0,%1,%b2\;{ai|addic} %0,%0,-1\;{sfe|subfe} %0,%0,%0
7494 {xoriu|xoris} %0,%1,%u2\;{ai|addic} %0,%0,-1\;{sfe|subfe} %0,%0,%0
7495 {sfi|subfic} %0,%1,%2\;{ai|addic} %0,%0,-1\;{sfe|subfe} %0,%0,%0"
b19003d8 7496 [(set_attr "length" "12,8,12,12,12")])
1fd4e8c1 7497
ea9be077
MM
7498;; Simplify (ne X (const_int 0)) on the PowerPC. No need to on the Power,
7499;; since it nabs/sr is just as fast.
7500(define_insn ""
7501 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
7502 (lshiftrt:SI (neg:SI (abs:SI (match_operand:SI 1 "gpc_reg_operand" "r")))
7503 (const_int 31)))
7504 (clobber (match_scratch:SI 2 "=&r"))]
7505 "!TARGET_POWER"
7506 "{ai|addic} %2,%1,-1\;{sfe|subfe} %0,%2,%1"
7507 [(set_attr "length" "8")])
7508
1fd4e8c1
RK
7509;; This is what (plus (ne X (const_int 0)) Y) looks like.
7510(define_insn ""
cd2b37d9 7511 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1 7512 (plus:SI (lshiftrt:SI
cd2b37d9 7513 (neg:SI (abs:SI (match_operand:SI 1 "gpc_reg_operand" "r")))
1fd4e8c1 7514 (const_int 31))
cd2b37d9 7515 (match_operand:SI 2 "gpc_reg_operand" "r")))
1fd4e8c1
RK
7516 (clobber (match_scratch:SI 3 "=&r"))]
7517 ""
ca7f5001 7518 "{ai|addic} %3,%1,-1\;{aze|addze} %0,%2"
b19003d8 7519 [(set_attr "length" "8")])
1fd4e8c1
RK
7520
7521(define_insn ""
7522 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
7523 (compare:CC
7524 (plus:SI (lshiftrt:SI
cd2b37d9 7525 (neg:SI (abs:SI (match_operand:SI 1 "gpc_reg_operand" "r")))
1fd4e8c1 7526 (const_int 31))
cd2b37d9 7527 (match_operand:SI 2 "gpc_reg_operand" "r"))
1fd4e8c1
RK
7528 (const_int 0)))
7529 (clobber (match_scratch:SI 3 "=&r"))]
7530 ""
ca7f5001 7531 "{ai|addic} %3,%1,-1\;{aze.|addze.} %3,%2"
b19003d8
RK
7532 [(set_attr "type" "compare")
7533 (set_attr "length" "8")])
1fd4e8c1
RK
7534
7535(define_insn ""
7536 [(set (match_operand:CC 4 "cc_reg_operand" "=x")
7537 (compare:CC
7538 (plus:SI (lshiftrt:SI
cd2b37d9 7539 (neg:SI (abs:SI (match_operand:SI 1 "gpc_reg_operand" "r")))
1fd4e8c1 7540 (const_int 31))
cd2b37d9 7541 (match_operand:SI 2 "gpc_reg_operand" "r"))
1fd4e8c1 7542 (const_int 0)))
cd2b37d9 7543 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
7544 (plus:SI (lshiftrt:SI (neg:SI (abs:SI (match_dup 1))) (const_int 31))
7545 (match_dup 2)))
7546 (clobber (match_scratch:SI 3 "=&r"))]
7547 ""
ca7f5001 7548 "{ai|addic} %3,%1,-1\;{aze.|addze.} %0,%2"
b19003d8
RK
7549 [(set_attr "type" "compare")
7550 (set_attr "length" "8")])
1fd4e8c1
RK
7551
7552(define_insn ""
cd2b37d9
RK
7553 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
7554 (le:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1
RK
7555 (match_operand:SI 2 "reg_or_short_operand" "r,O")))
7556 (clobber (match_scratch:SI 3 "=r,X"))]
ca7f5001 7557 "TARGET_POWER"
1fd4e8c1 7558 "@
ca7f5001 7559 doz %3,%2,%1\;{sfi|subfic} %0,%3,0\;{ae|adde} %0,%0,%3
7f340546 7560 {ai|addic} %0,%1,-1\;{aze|addze} %0,%0\;{sri|srwi} %0,%0,31"
b19003d8 7561 [(set_attr "length" "12")])
1fd4e8c1
RK
7562
7563(define_insn ""
7564 [(set (match_operand:CC 4 "cc_reg_operand" "=x,x")
7565 (compare:CC
cd2b37d9 7566 (le:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1
RK
7567 (match_operand:SI 2 "reg_or_short_operand" "r,O"))
7568 (const_int 0)))
cd2b37d9 7569 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
1fd4e8c1
RK
7570 (le:SI (match_dup 1) (match_dup 2)))
7571 (clobber (match_scratch:SI 3 "=r,X"))]
ca7f5001 7572 "TARGET_POWER"
1fd4e8c1 7573 "@
ca7f5001 7574 doz %3,%2,%1\;{sfi|subfic} %0,%3,0\;{ae.|adde.} %0,%0,%3
7f340546 7575 {ai|addic} %0,%1,-1\;{aze|addze} %0,%0\;{sri.|srwi.} %0,%0,31"
a473029f 7576 [(set_attr "type" "compare,delayed_compare")
b19003d8 7577 (set_attr "length" "12")])
1fd4e8c1
RK
7578
7579(define_insn ""
cd2b37d9
RK
7580 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
7581 (plus:SI (le:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1 7582 (match_operand:SI 2 "reg_or_short_operand" "r,O"))
cd2b37d9 7583 (match_operand:SI 3 "gpc_reg_operand" "r,r")))
1fd4e8c1 7584 (clobber (match_scratch:SI 4 "=&r,&r"))]
ca7f5001 7585 "TARGET_POWER"
1fd4e8c1 7586 "@
ca7f5001
RK
7587 doz %4,%2,%1\;{sfi|subfic} %4,%4,0\;{aze|addze} %0,%3
7588 {srai|srawi} %4,%1,31\;{sf|subfc} %4,%1,%4\;{aze|addze} %0,%3"
b19003d8 7589 [(set_attr "length" "12")])
1fd4e8c1
RK
7590
7591(define_insn ""
7592 [(set (match_operand:CC 0 "cc_reg_operand" "=x,x")
7593 (compare:CC
cd2b37d9 7594 (plus:SI (le:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1 7595 (match_operand:SI 2 "reg_or_short_operand" "r,O"))
cd2b37d9 7596 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
1fd4e8c1
RK
7597 (const_int 0)))
7598 (clobber (match_scratch:SI 4 "=&r,&r"))]
ca7f5001 7599 "TARGET_POWER"
1fd4e8c1 7600 "@
ca7f5001
RK
7601 doz %4,%2,%1\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %4,%3
7602 {srai|srawi} %4,%1,31\;{sf|subfc} %4,%1,%4\;{aze.|addze.} %4,%3"
b19003d8
RK
7603 [(set_attr "type" "compare")
7604 (set_attr "length" "12")])
1fd4e8c1
RK
7605
7606(define_insn ""
7607 [(set (match_operand:CC 5 "cc_reg_operand" "=x,x")
7608 (compare:CC
cd2b37d9 7609 (plus:SI (le:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1 7610 (match_operand:SI 2 "reg_or_short_operand" "r,O"))
cd2b37d9 7611 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
1fd4e8c1 7612 (const_int 0)))
cd2b37d9 7613 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
1fd4e8c1
RK
7614 (plus:SI (le:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
7615 (clobber (match_scratch:SI 4 "=&r,&r"))]
ca7f5001 7616 "TARGET_POWER"
1fd4e8c1 7617 "@
ca7f5001
RK
7618 doz %4,%2,%1\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %0,%3
7619 {srai|srawi} %4,%1,31\;{sf|subfc} %4,%1,%4\;{aze.|addze.} %0,%3"
b19003d8
RK
7620 [(set_attr "type" "compare")
7621 (set_attr "length" "12")])
1fd4e8c1
RK
7622
7623(define_insn ""
cd2b37d9
RK
7624 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
7625 (neg:SI (le:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1 7626 (match_operand:SI 2 "reg_or_short_operand" "r,O"))))]
ca7f5001 7627 "TARGET_POWER"
1fd4e8c1 7628 "@
ca7f5001
RK
7629 doz %0,%2,%1\;{ai|addic} %0,%0,-1\;{sfe|subfe} %0,%0,%0
7630 {ai|addic} %0,%1,-1\;{aze|addze} %0,%0\;{srai|srawi} %0,%0,31"
b19003d8 7631 [(set_attr "length" "12")])
1fd4e8c1
RK
7632
7633(define_insn ""
cd2b37d9
RK
7634 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
7635 (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
7636 (match_operand:SI 2 "reg_or_short_operand" "rI")))]
7637 ""
ca7f5001 7638 "{sf%I2|subf%I2c} %0,%1,%2\;{cal %0,0(0)|li %0,0}\;{ae|adde} %0,%0,%0"
b19003d8 7639 [(set_attr "length" "12")])
1fd4e8c1
RK
7640
7641(define_insn ""
7642 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
7643 (compare:CC
cd2b37d9 7644 (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
7645 (match_operand:SI 2 "reg_or_short_operand" "rI"))
7646 (const_int 0)))
cd2b37d9 7647 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
7648 (leu:SI (match_dup 1) (match_dup 2)))]
7649 ""
ca7f5001 7650 "{sf%I2|subf%I2c} %0,%1,%2\;{cal %0,0(0)|li %0,0}\;{ae.|adde.} %0,%0,%0"
b19003d8
RK
7651 [(set_attr "type" "compare")
7652 (set_attr "length" "12")])
1fd4e8c1
RK
7653
7654(define_insn ""
cd2b37d9
RK
7655 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
7656 (plus:SI (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 7657 (match_operand:SI 2 "reg_or_short_operand" "rI"))
cd2b37d9 7658 (match_operand:SI 3 "gpc_reg_operand" "r")))
1fd4e8c1
RK
7659 (clobber (match_scratch:SI 4 "=&r"))]
7660 ""
ca7f5001 7661 "{sf%I2|subf%I2c} %4,%1,%2\;{aze|addze} %0,%3"
b19003d8 7662 [(set_attr "length" "8")])
1fd4e8c1
RK
7663
7664(define_insn ""
7665 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
7666 (compare:CC
cd2b37d9 7667 (plus:SI (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 7668 (match_operand:SI 2 "reg_or_short_operand" "rI"))
cd2b37d9 7669 (match_operand:SI 3 "gpc_reg_operand" "r"))
1fd4e8c1
RK
7670 (const_int 0)))
7671 (clobber (match_scratch:SI 4 "=&r"))]
7672 ""
ca7f5001 7673 "{sf%I2|subf%I2c} %4,%1,%2\;{aze.|addze.} %4,%3"
b19003d8
RK
7674 [(set_attr "type" "compare")
7675 (set_attr "length" "8")])
1fd4e8c1
RK
7676
7677(define_insn ""
7678 [(set (match_operand:CC 5 "cc_reg_operand" "=x")
7679 (compare:CC
cd2b37d9 7680 (plus:SI (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 7681 (match_operand:SI 2 "reg_or_short_operand" "rI"))
cd2b37d9 7682 (match_operand:SI 3 "gpc_reg_operand" "r"))
1fd4e8c1 7683 (const_int 0)))
cd2b37d9 7684 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
7685 (plus:SI (leu:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
7686 (clobber (match_scratch:SI 4 "=&r"))]
7687 ""
ca7f5001 7688 "{sf%I2|subf%I2c} %4,%1,%2\;{aze.|addze.} %0,%3"
b19003d8
RK
7689 [(set_attr "type" "compare")
7690 (set_attr "length" "8")])
1fd4e8c1
RK
7691
7692(define_insn ""
cd2b37d9
RK
7693 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
7694 (neg:SI (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
7695 (match_operand:SI 2 "reg_or_short_operand" "rI"))))]
7696 ""
ca7f5001 7697 "{sf%I2|subf%I2c} %0,%1,%2\;{sfe|subfe} %0,%0,%0\;nand %0,%0,%0"
b19003d8 7698 [(set_attr "length" "12")])
1fd4e8c1
RK
7699
7700(define_insn ""
cd2b37d9 7701 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1 7702 (and:SI (neg:SI
cd2b37d9 7703 (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 7704 (match_operand:SI 2 "reg_or_short_operand" "rI")))
cd2b37d9 7705 (match_operand:SI 3 "gpc_reg_operand" "r")))
1fd4e8c1
RK
7706 (clobber (match_scratch:SI 4 "=&r"))]
7707 ""
ca7f5001 7708 "{sf%I2|subf%I2c} %4,%1,%2\;{sfe|subfe} %4,%4,%4\;andc %0,%3,%4"
b19003d8 7709 [(set_attr "length" "12")])
1fd4e8c1
RK
7710
7711(define_insn ""
7712 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
7713 (compare:CC
7714 (and:SI (neg:SI
cd2b37d9 7715 (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 7716 (match_operand:SI 2 "reg_or_short_operand" "rI")))
cd2b37d9 7717 (match_operand:SI 3 "gpc_reg_operand" "r"))
1fd4e8c1
RK
7718 (const_int 0)))
7719 (clobber (match_scratch:SI 4 "=&r"))]
7720 ""
ca7f5001 7721 "{sf%I2|subf%I2c} %4,%1,%2\;{sfe|subfe} %4,%4,%4\;andc. %4,%3,%4"
b19003d8
RK
7722 [(set_attr "type" "compare")
7723 (set_attr "length" "12")])
1fd4e8c1
RK
7724
7725(define_insn ""
7726 [(set (match_operand:CC 5 "cc_reg_operand" "=x")
7727 (compare:CC
7728 (and:SI (neg:SI
cd2b37d9 7729 (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 7730 (match_operand:SI 2 "reg_or_short_operand" "rI")))
cd2b37d9 7731 (match_operand:SI 3 "gpc_reg_operand" "r"))
1fd4e8c1 7732 (const_int 0)))
cd2b37d9 7733 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
7734 (and:SI (neg:SI (leu:SI (match_dup 1) (match_dup 2))) (match_dup 3)))
7735 (clobber (match_scratch:SI 4 "=&r"))]
7736 ""
ca7f5001 7737 "{sf%I2|subf%I2c} %4,%1,%2\;{sfe|subfe} %4,%4,%4\;andc. %0,%3,%4"
b19003d8
RK
7738 [(set_attr "type" "compare")
7739 (set_attr "length" "12")])
1fd4e8c1
RK
7740
7741(define_insn ""
cd2b37d9
RK
7742 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
7743 (lt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 7744 (match_operand:SI 2 "reg_or_short_operand" "rI")))]
ca7f5001 7745 "TARGET_POWER"
7f340546 7746 "doz%I2 %0,%1,%2\;nabs %0,%0\;{sri|srwi} %0,%0,31"
b19003d8 7747 [(set_attr "length" "12")])
1fd4e8c1
RK
7748
7749(define_insn ""
ad8bd902 7750 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1fd4e8c1 7751 (compare:CC
cd2b37d9 7752 (lt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
7753 (match_operand:SI 2 "reg_or_short_operand" "rI"))
7754 (const_int 0)))
cd2b37d9 7755 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1 7756 (lt:SI (match_dup 1) (match_dup 2)))]
ca7f5001 7757 "TARGET_POWER"
7f340546 7758 "doz%I2 %0,%1,%2\;nabs %0,%0\;{sri.|srwi.} %0,%0,31"
b19003d8
RK
7759 [(set_attr "type" "delayed_compare")
7760 (set_attr "length" "12")])
1fd4e8c1
RK
7761
7762(define_insn ""
cd2b37d9
RK
7763 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
7764 (plus:SI (lt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 7765 (match_operand:SI 2 "reg_or_short_operand" "rI"))
cd2b37d9 7766 (match_operand:SI 3 "gpc_reg_operand" "r")))
1fd4e8c1 7767 (clobber (match_scratch:SI 4 "=&r"))]
ca7f5001
RK
7768 "TARGET_POWER"
7769 "doz%I2 %4,%1,%2\;{ai|addic} %4,%4,-1\;{aze|addze} %0,%3"
b19003d8 7770 [(set_attr "length" "12")])
1fd4e8c1
RK
7771
7772(define_insn ""
ad8bd902 7773 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
1fd4e8c1 7774 (compare:CC
cd2b37d9 7775 (plus:SI (lt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 7776 (match_operand:SI 2 "reg_or_short_operand" "rI"))
cd2b37d9 7777 (match_operand:SI 3 "gpc_reg_operand" "r"))
1fd4e8c1
RK
7778 (const_int 0)))
7779 (clobber (match_scratch:SI 4 "=&r"))]
ca7f5001
RK
7780 "TARGET_POWER"
7781 "doz%I2 %4,%1,%2\;{ai|addic} %4,%4,-1\;{aze.|addze.} %4,%3"
b19003d8
RK
7782 [(set_attr "type" "compare")
7783 (set_attr "length" "12")])
1fd4e8c1
RK
7784
7785(define_insn ""
ad8bd902 7786 [(set (match_operand:CC 5 "cc_reg_operand" "=x")
1fd4e8c1 7787 (compare:CC
cd2b37d9 7788 (plus:SI (lt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 7789 (match_operand:SI 2 "reg_or_short_operand" "rI"))
cd2b37d9 7790 (match_operand:SI 3 "gpc_reg_operand" "r"))
1fd4e8c1 7791 (const_int 0)))
cd2b37d9 7792 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
7793 (plus:SI (lt:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
7794 (clobber (match_scratch:SI 4 "=&r"))]
ca7f5001
RK
7795 "TARGET_POWER"
7796 "doz%I2 %4,%1,%2\;{ai|addic} %4,%4,-1\;{aze.|addze.} %0,%3"
b19003d8
RK
7797 [(set_attr "type" "compare")
7798 (set_attr "length" "12")])
1fd4e8c1
RK
7799
7800(define_insn ""
cd2b37d9
RK
7801 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
7802 (neg:SI (lt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 7803 (match_operand:SI 2 "reg_or_short_operand" "rI"))))]
ca7f5001
RK
7804 "TARGET_POWER"
7805 "doz%I2 %0,%1,%2\;nabs %0,%0\;{srai|srawi} %0,%0,31"
b19003d8 7806 [(set_attr "length" "12")])
1fd4e8c1
RK
7807
7808(define_insn ""
cd2b37d9
RK
7809 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
7810 (ltu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1
RK
7811 (match_operand:SI 2 "reg_or_neg_short_operand" "r,P")))]
7812 ""
7813 "@
ca7f5001
RK
7814 {sf|subfc} %0,%2,%1\;{sfe|subfe} %0,%0,%0\;neg %0,%0
7815 {ai|addic} %0,%1,%n2\;{sfe|subfe} %0,%0,%0\;neg %0,%0"
b19003d8 7816 [(set_attr "length" "12")])
1fd4e8c1
RK
7817
7818(define_insn ""
7819 [(set (match_operand:CC 3 "cc_reg_operand" "=x,x")
7820 (compare:CC
cd2b37d9 7821 (ltu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1
RK
7822 (match_operand:SI 2 "reg_or_neg_short_operand" "r,P"))
7823 (const_int 0)))
cd2b37d9 7824 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
1fd4e8c1
RK
7825 (ltu:SI (match_dup 1) (match_dup 2)))]
7826 ""
7827 "@
ca7f5001
RK
7828 {sf|subfc} %0,%2,%1\;{sfe|subfe} %0,%0,%0\;neg. %0,%0
7829 {ai|addic} %0,%1,%n2\;{sfe|subfe} %0,%0,%0\;neg. %0,%0"
b19003d8
RK
7830 [(set_attr "type" "compare")
7831 (set_attr "length" "12")])
1fd4e8c1
RK
7832
7833(define_insn ""
cd2b37d9
RK
7834 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r")
7835 (plus:SI (ltu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r")
1fd4e8c1
RK
7836 (match_operand:SI 2 "reg_or_neg_short_operand" "r,r,P,P"))
7837 (match_operand:SI 3 "reg_or_short_operand" "r,I,r,I")))
7838 (clobber (match_scratch:SI 4 "=&r,r,&r,r"))]
7839 ""
7840 "@
ca7f5001
RK
7841 {sf|subfc} %4,%2,%1\;{sfe|subfe} %4,%4,%4\;{sf%I3|subf%I3c} %0,%4,%3
7842 {sf|subfc} %4,%2,%1\;{sfe|subfe} %4,%4,%4\;{sf%I3|subf%I3c} %0,%4,%3
7843 {ai|addic} %4,%1,%n2\;{sfe|subfe} %4,%4,%4\;{sf%I3|subf%I3c} %0,%4,%3
7844 {ai|addic} %4,%1,%n2\;{sfe|subfe} %4,%4,%4\;{sf%I3|subf%I3c} %0,%4,%3"
b19003d8 7845 [(set_attr "length" "12")])
1fd4e8c1
RK
7846
7847(define_insn ""
3d91674b 7848 [(set (match_operand:CC 0 "cc_reg_operand" "=x,x")
1fd4e8c1 7849 (compare:CC
3d91674b
RK
7850 (plus:SI (ltu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
7851 (match_operand:SI 2 "reg_or_neg_short_operand" "r,P"))
7852 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
1fd4e8c1 7853 (const_int 0)))
3d91674b 7854 (clobber (match_scratch:SI 4 "=&r,&r"))]
1fd4e8c1
RK
7855 ""
7856 "@
ca7f5001
RK
7857 {sf|subfc} %4,%2,%1\;{sfe|subfe} %4,%4,%4\;{sf.|subfc.} %4,%4,%3
7858 {ai|addic} %4,%1,%n2\;{sfe|subfe} %4,%4,%4\;{sf.|subfc.} %4,%4,%3"
b19003d8
RK
7859 [(set_attr "type" "compare")
7860 (set_attr "length" "12")])
1fd4e8c1
RK
7861
7862(define_insn ""
3d91674b 7863 [(set (match_operand:CC 5 "cc_reg_operand" "=x,x")
1fd4e8c1 7864 (compare:CC
3d91674b
RK
7865 (plus:SI (ltu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
7866 (match_operand:SI 2 "reg_or_neg_short_operand" "r,P"))
7867 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
1fd4e8c1 7868 (const_int 0)))
3d91674b 7869 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
1fd4e8c1 7870 (plus:SI (ltu:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
3d91674b 7871 (clobber (match_scratch:SI 4 "=&r,&r"))]
1fd4e8c1
RK
7872 ""
7873 "@
ca7f5001
RK
7874 {sf|subfc} %4,%2,%1\;{sfe|subfe} %4,%4,%4\;{sf.|subfc.} %0,%4,%3
7875 {ai|addic} %4,%1,%n2\;{sfe|subfe} %4,%4,%4\;{sf.|subfc.} %0,%4,%3"
b19003d8
RK
7876 [(set_attr "type" "compare")
7877 (set_attr "length" "12")])
1fd4e8c1
RK
7878
7879(define_insn ""
cd2b37d9
RK
7880 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
7881 (neg:SI (ltu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1
RK
7882 (match_operand:SI 2 "reg_or_neg_short_operand" "r,P"))))]
7883 ""
7884 "@
ca7f5001
RK
7885 {sf|subfc} %0,%2,%1\;{sfe|subfe} %0,%0,%0
7886 {ai|addic} %0,%1,%n2\;{sfe|subfe} %0,%0,%0"
b19003d8 7887 [(set_attr "length" "8")])
1fd4e8c1
RK
7888
7889(define_insn ""
cd2b37d9
RK
7890 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
7891 (ge:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
7892 (match_operand:SI 2 "reg_or_short_operand" "rI")))
7893 (clobber (match_scratch:SI 3 "=r"))]
ca7f5001
RK
7894 "TARGET_POWER"
7895 "doz%I2 %3,%1,%2\;{sfi|subfic} %0,%3,0\;{ae|adde} %0,%0,%3"
b19003d8 7896 [(set_attr "length" "12")])
1fd4e8c1
RK
7897
7898(define_insn ""
7899 [(set (match_operand:CC 4 "cc_reg_operand" "=x")
7900 (compare:CC
cd2b37d9 7901 (ge:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
7902 (match_operand:SI 2 "reg_or_short_operand" "rI"))
7903 (const_int 0)))
cd2b37d9 7904 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
7905 (ge:SI (match_dup 1) (match_dup 2)))
7906 (clobber (match_scratch:SI 3 "=r"))]
ca7f5001
RK
7907 "TARGET_POWER"
7908 "doz%I2 %3,%1,%2\;{sfi|subfic} %0,%3,0\;{ae.|adde.} %0,%0,%3"
b19003d8
RK
7909 [(set_attr "type" "compare")
7910 (set_attr "length" "12")])
1fd4e8c1
RK
7911
7912(define_insn ""
cd2b37d9
RK
7913 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
7914 (plus:SI (ge:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 7915 (match_operand:SI 2 "reg_or_short_operand" "rI"))
cd2b37d9 7916 (match_operand:SI 3 "gpc_reg_operand" "r")))
1fd4e8c1 7917 (clobber (match_scratch:SI 4 "=&r"))]
ca7f5001
RK
7918 "TARGET_POWER"
7919 "doz%I2 %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze|addze} %0,%3"
b19003d8 7920 [(set_attr "length" "12")])
1fd4e8c1
RK
7921
7922(define_insn ""
7923 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
7924 (compare:CC
cd2b37d9 7925 (plus:SI (ge:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 7926 (match_operand:SI 2 "reg_or_short_operand" "rI"))
cd2b37d9 7927 (match_operand:SI 3 "gpc_reg_operand" "r"))
1fd4e8c1
RK
7928 (const_int 0)))
7929 (clobber (match_scratch:SI 4 "=&r"))]
ca7f5001
RK
7930 "TARGET_POWER"
7931 "doz%I2 %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %4,%3"
b19003d8
RK
7932 [(set_attr "type" "compare")
7933 (set_attr "length" "12")])
1fd4e8c1
RK
7934
7935(define_insn ""
7936 [(set (match_operand:CC 5 "cc_reg_operand" "=x")
7937 (compare:CC
cd2b37d9 7938 (plus:SI (ge:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 7939 (match_operand:SI 2 "reg_or_short_operand" "rI"))
cd2b37d9 7940 (match_operand:SI 3 "gpc_reg_operand" "r"))
1fd4e8c1 7941 (const_int 0)))
cd2b37d9 7942 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
7943 (plus:SI (ge:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
7944 (clobber (match_scratch:SI 4 "=&r"))]
ca7f5001
RK
7945 "TARGET_POWER"
7946 "doz%I2 %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %0,%3"
b19003d8
RK
7947 [(set_attr "type" "compare")
7948 (set_attr "length" "12")])
1fd4e8c1
RK
7949
7950(define_insn ""
cd2b37d9
RK
7951 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
7952 (neg:SI (ge:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 7953 (match_operand:SI 2 "reg_or_short_operand" "rI"))))]
ca7f5001
RK
7954 "TARGET_POWER"
7955 "doz%I2 %0,%1,%2\;{ai|addic} %0,%0,-1\;{sfe|subfe} %0,%0,%0"
b19003d8 7956 [(set_attr "length" "12")])
1fd4e8c1
RK
7957
7958;; This is (and (neg (ge X (const_int 0))) Y).
7959(define_insn ""
cd2b37d9 7960 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
7961 (and:SI (neg:SI
7962 (lshiftrt:SI
cd2b37d9 7963 (not:SI (match_operand:SI 1 "gpc_reg_operand" "r"))
1fd4e8c1 7964 (const_int 31)))
cd2b37d9 7965 (match_operand:SI 2 "gpc_reg_operand" "r")))
1fd4e8c1
RK
7966 (clobber (match_scratch:SI 3 "=&r"))]
7967 ""
ca7f5001 7968 "{srai|srawi} %3,%1,31\;andc %0,%2,%3"
b19003d8 7969 [(set_attr "length" "8")])
1fd4e8c1
RK
7970
7971(define_insn ""
7972 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
7973 (compare:CC
7974 (and:SI (neg:SI
7975 (lshiftrt:SI
cd2b37d9 7976 (not:SI (match_operand:SI 1 "gpc_reg_operand" "r"))
1fd4e8c1 7977 (const_int 31)))
cd2b37d9 7978 (match_operand:SI 2 "gpc_reg_operand" "r"))
1fd4e8c1
RK
7979 (const_int 0)))
7980 (clobber (match_scratch:SI 3 "=&r"))]
7981 ""
ca7f5001 7982 "{srai|srawi} %3,%1,31\;andc. %3,%2,%3"
b19003d8
RK
7983 [(set_attr "type" "compare")
7984 (set_attr "length" "8")])
1fd4e8c1
RK
7985
7986(define_insn ""
7987 [(set (match_operand:CC 4 "cc_reg_operand" "=x")
7988 (compare:CC
7989 (and:SI (neg:SI
7990 (lshiftrt:SI
cd2b37d9 7991 (not:SI (match_operand:SI 1 "gpc_reg_operand" "r"))
1fd4e8c1 7992 (const_int 31)))
cd2b37d9 7993 (match_operand:SI 2 "gpc_reg_operand" "r"))
1fd4e8c1 7994 (const_int 0)))
cd2b37d9 7995 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
7996 (and:SI (neg:SI (lshiftrt:SI (not:SI (match_dup 1))
7997 (const_int 31)))
7998 (match_dup 2)))
7999 (clobber (match_scratch:SI 3 "=&r"))]
8000 ""
ca7f5001 8001 "{srai|srawi} %3,%1,31\;andc. %0,%2,%3"
b19003d8
RK
8002 [(set_attr "type" "compare")
8003 (set_attr "length" "8")])
1fd4e8c1
RK
8004
8005(define_insn ""
cd2b37d9
RK
8006 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
8007 (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1
RK
8008 (match_operand:SI 2 "reg_or_neg_short_operand" "r,P")))]
8009 ""
8010 "@
ca7f5001
RK
8011 {sf|subfc} %0,%2,%1\;{cal %0,0(0)|li %0,0}\;{ae|adde} %0,%0,%0
8012 {ai|addic} %0,%1,%n2\;{cal %0,0(0)|li %0,0}\;{ae|adde} %0,%0,%0"
b19003d8 8013 [(set_attr "length" "12")])
1fd4e8c1
RK
8014
8015(define_insn ""
8016 [(set (match_operand:CC 3 "cc_reg_operand" "=x,x")
8017 (compare:CC
cd2b37d9 8018 (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1
RK
8019 (match_operand:SI 2 "reg_or_neg_short_operand" "r,P"))
8020 (const_int 0)))
cd2b37d9 8021 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
1fd4e8c1
RK
8022 (geu:SI (match_dup 1) (match_dup 2)))]
8023 ""
8024 "@
ca7f5001
RK
8025 {sf|subfc} %0,%2,%1\;{cal %0,0(0)|li %0,0}\;{ae.|adde.} %0,%0,%0
8026 {ai|addic} %0,%1,%n2\;{cal %0,0(0)|li %0,0}\;{ae.|adde.} %0,%0,%0"
b19003d8
RK
8027 [(set_attr "type" "compare")
8028 (set_attr "length" "12")])
1fd4e8c1
RK
8029
8030(define_insn ""
cd2b37d9
RK
8031 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
8032 (plus:SI (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1 8033 (match_operand:SI 2 "reg_or_neg_short_operand" "r,P"))
cd2b37d9 8034 (match_operand:SI 3 "gpc_reg_operand" "r,r")))
1fd4e8c1
RK
8035 (clobber (match_scratch:SI 4 "=&r,&r"))]
8036 ""
8037 "@
ca7f5001
RK
8038 {sf|subfc} %4,%2,%1\;{aze|addze} %0,%3
8039 {ai|addic} %4,%1,%n2\;{aze|addze} %0,%3"
b19003d8 8040 [(set_attr "length" "8")])
1fd4e8c1
RK
8041
8042(define_insn ""
8043 [(set (match_operand:CC 0 "cc_reg_operand" "=x,x")
8044 (compare:CC
cd2b37d9 8045 (plus:SI (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1 8046 (match_operand:SI 2 "reg_or_neg_short_operand" "r,P"))
cd2b37d9 8047 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
1fd4e8c1
RK
8048 (const_int 0)))
8049 (clobber (match_scratch:SI 4 "=&r,&r"))]
8050 ""
8051 "@
ca7f5001
RK
8052 {sf|subfc} %4,%2,%1\;{aze.|addze.} %4,%3
8053 {ai|addic} %4,%1,%n2\;{aze.|addze.} %4,%3"
b19003d8
RK
8054 [(set_attr "type" "compare")
8055 (set_attr "length" "8")])
1fd4e8c1
RK
8056
8057(define_insn ""
8058 [(set (match_operand:CC 5 "cc_reg_operand" "=x,x")
8059 (compare:CC
cd2b37d9 8060 (plus:SI (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1 8061 (match_operand:SI 2 "reg_or_neg_short_operand" "r,P"))
cd2b37d9 8062 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
1fd4e8c1 8063 (const_int 0)))
cd2b37d9 8064 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
1fd4e8c1
RK
8065 (plus:SI (geu:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
8066 (clobber (match_scratch:SI 4 "=&r,&r"))]
8067 ""
8068 "@
ca7f5001
RK
8069 {sf|subfc} %4,%2,%1\;{aze.|addze.} %0,%3
8070 {ai|addic} %4,%1,%n2\;{aze.|addze.} %4,%3"
b19003d8
RK
8071 [(set_attr "type" "compare")
8072 (set_attr "length" "8")])
1fd4e8c1
RK
8073
8074(define_insn ""
cd2b37d9
RK
8075 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
8076 (neg:SI (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1
RK
8077 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))]
8078 ""
8079 "@
ca7f5001 8080 {sf|subfc} %0,%2,%1\;{sfe|subfe} %0,%0,%0\;nand %0,%0,%0
8106dc08 8081 {sfi|subfic} %0,%1,-1\;{a%I2|add%I2c} %0,%0,%2\;{sfe|subfe} %0,%0,%0"
b19003d8 8082 [(set_attr "length" "12")])
1fd4e8c1
RK
8083
8084(define_insn ""
cd2b37d9 8085 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
1fd4e8c1 8086 (and:SI (neg:SI
cd2b37d9 8087 (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1 8088 (match_operand:SI 2 "reg_or_neg_short_operand" "r,P")))
cd2b37d9 8089 (match_operand:SI 3 "gpc_reg_operand" "r,r")))
1fd4e8c1
RK
8090 (clobber (match_scratch:SI 4 "=&r,&r"))]
8091 ""
8092 "@
ca7f5001
RK
8093 {sf|subfc} %4,%2,%1\;{sfe|subfe} %4,%4,%4\;andc %0,%3,%4
8094 {ai|addic} %4,%1,%n2\;{sfe|subfe} %4,%4,%4\;andc %0,%3,%4"
b19003d8 8095 [(set_attr "length" "12")])
1fd4e8c1
RK
8096
8097(define_insn ""
8098 [(set (match_operand:CC 0 "cc_reg_operand" "=x,x")
8099 (compare:CC
8100 (and:SI (neg:SI
cd2b37d9 8101 (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1 8102 (match_operand:SI 2 "reg_or_neg_short_operand" "r,P")))
cd2b37d9 8103 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
1fd4e8c1
RK
8104 (const_int 0)))
8105 (clobber (match_scratch:SI 4 "=&r,&r"))]
8106 ""
8107 "@
ca7f5001
RK
8108 {sf|subfc} %4,%2,%1\;{sfe|subfe} %4,%4,%4\;andc. %4,%3,%4
8109 {ai|addic} %4,%1,%n2\;{sfe|subfe} %4,%4,%4\;andc. %4,%3,%4"
b19003d8
RK
8110 [(set_attr "type" "compare")
8111 (set_attr "length" "12")])
1fd4e8c1
RK
8112
8113(define_insn ""
8114 [(set (match_operand:CC 5 "cc_reg_operand" "=x,x")
8115 (compare:CC
8116 (and:SI (neg:SI
cd2b37d9 8117 (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1 8118 (match_operand:SI 2 "reg_or_neg_short_operand" "r,P")))
cd2b37d9 8119 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
1fd4e8c1 8120 (const_int 0)))
cd2b37d9 8121 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
1fd4e8c1
RK
8122 (and:SI (neg:SI (geu:SI (match_dup 1) (match_dup 2))) (match_dup 3)))
8123 (clobber (match_scratch:SI 4 "=&r,&r"))]
8124 ""
8125 "@
ca7f5001
RK
8126 {sf|subfc} %4,%2,%1\;{sfe|subfe} %4,%4,%4\;andc. %0,%3,%4
8127 {ai|addic} %4,%1,%n2\;{sfe|subfe} %4,%4,%4\;andc. %0,%3,%4"
b19003d8
RK
8128 [(set_attr "type" "compare")
8129 (set_attr "length" "12")])
1fd4e8c1
RK
8130
8131(define_insn ""
cd2b37d9
RK
8132 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
8133 (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
8134 (const_int 0)))]
8135 ""
ca7f5001 8136 "{sfi|subfic} %0,%1,0\;{ame|addme} %0,%0\;{sri|srwi} %0,%0,31"
b19003d8 8137 [(set_attr "length" "12")])
1fd4e8c1
RK
8138
8139(define_insn ""
8140 [(set (match_operand:CC 2 "cc_reg_operand" "=x")
8141 (compare:CC
cd2b37d9 8142 (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
8143 (const_int 0))
8144 (const_int 0)))
cd2b37d9 8145 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
8146 (gt:SI (match_dup 1) (const_int 0)))]
8147 ""
ca7f5001 8148 "{sfi|subfic} %0,%1,0\;{ame|addme} %0,%0\;{sri.|srwi.} %0,%0,31"
b19003d8
RK
8149 [(set_attr "type" "delayed_compare")
8150 (set_attr "length" "12")])
1fd4e8c1
RK
8151
8152(define_insn ""
cd2b37d9
RK
8153 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
8154 (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 8155 (match_operand:SI 2 "reg_or_short_operand" "r")))]
ca7f5001
RK
8156 "TARGET_POWER"
8157 "doz %0,%2,%1\;nabs %0,%0\;{sri|srwi} %0,%0,31"
b19003d8 8158 [(set_attr "length" "12")])
1fd4e8c1
RK
8159
8160(define_insn ""
8161 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
8162 (compare:CC
cd2b37d9 8163 (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
8164 (match_operand:SI 2 "reg_or_short_operand" "r"))
8165 (const_int 0)))
cd2b37d9 8166 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1 8167 (gt:SI (match_dup 1) (match_dup 2)))]
ca7f5001
RK
8168 "TARGET_POWER"
8169 "doz %0,%2,%1\;nabs %0,%0\;{sri.|srwi.} %0,%0,31"
b19003d8
RK
8170 [(set_attr "type" "delayed_compare")
8171 (set_attr "length" "12")])
1fd4e8c1
RK
8172
8173(define_insn ""
cd2b37d9
RK
8174 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
8175 (plus:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 8176 (const_int 0))
cd2b37d9 8177 (match_operand:SI 2 "gpc_reg_operand" "r")))
1fd4e8c1
RK
8178 (clobber (match_scratch:SI 3 "=&r"))]
8179 ""
ca7f5001 8180 "{a|addc} %3,%1,%1\;{sfe|subfe} %3,%1,%3\;{aze|addze} %0,%2"
b19003d8 8181 [(set_attr "length" "12")])
1fd4e8c1
RK
8182
8183(define_insn ""
8184 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
8185 (compare:CC
cd2b37d9 8186 (plus:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 8187 (const_int 0))
cd2b37d9 8188 (match_operand:SI 2 "gpc_reg_operand" "r"))
1fd4e8c1
RK
8189 (const_int 0)))
8190 (clobber (match_scratch:SI 3 "=&r"))]
8191 ""
ca7f5001 8192 "{a|addc} %3,%1,%1\;{sfe|subfe} %3,%1,%3\;{aze.|addze.} %0,%2"
b19003d8
RK
8193 [(set_attr "type" "compare")
8194 (set_attr "length" "12")])
1fd4e8c1
RK
8195
8196(define_insn ""
8197 [(set (match_operand:CC 4 "cc_reg_operand" "=x")
8198 (compare:CC
cd2b37d9 8199 (plus:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 8200 (const_int 0))
cd2b37d9 8201 (match_operand:SI 2 "gpc_reg_operand" "r"))
1fd4e8c1 8202 (const_int 0)))
cd2b37d9 8203 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
8204 (plus:SI (gt:SI (match_dup 1) (const_int 0)) (match_dup 2)))
8205 (clobber (match_scratch:SI 3 "=&r"))]
8206 ""
ca7f5001 8207 "{a|addc} %3,%1,%1\;{sfe|subfe} %3,%1,%3\;{aze.|addze.} %3,%2"
b19003d8
RK
8208 [(set_attr "type" "compare")
8209 (set_attr "length" "12")])
1fd4e8c1
RK
8210
8211(define_insn ""
cd2b37d9
RK
8212 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
8213 (plus:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 8214 (match_operand:SI 2 "reg_or_short_operand" "r"))
cd2b37d9 8215 (match_operand:SI 3 "gpc_reg_operand" "r")))
1fd4e8c1 8216 (clobber (match_scratch:SI 4 "=&r"))]
ca7f5001
RK
8217 "TARGET_POWER"
8218 "doz %4,%2,%1\;{ai|addic} %4,%4,-1\;{aze|addze} %0,%3"
b19003d8 8219 [(set_attr "length" "12")])
1fd4e8c1
RK
8220
8221(define_insn ""
8222 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
8223 (compare:CC
cd2b37d9 8224 (plus:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 8225 (match_operand:SI 2 "reg_or_short_operand" "r"))
cd2b37d9 8226 (match_operand:SI 3 "gpc_reg_operand" "r"))
1fd4e8c1
RK
8227 (const_int 0)))
8228 (clobber (match_scratch:SI 4 "=&r"))]
ca7f5001
RK
8229 "TARGET_POWER"
8230 "doz %4,%2,%1\;{ai|addic} %4,%4,-1\;{aze.|addze.} %4,%3"
b19003d8
RK
8231 [(set_attr "type" "compare")
8232 (set_attr "length" "12")])
1fd4e8c1
RK
8233
8234(define_insn ""
8235 [(set (match_operand:CC 5 "cc_reg_operand" "=x")
8236 (compare:CC
cd2b37d9 8237 (plus:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 8238 (match_operand:SI 2 "reg_or_short_operand" "r"))
cd2b37d9 8239 (match_operand:SI 3 "gpc_reg_operand" "r"))
1fd4e8c1 8240 (const_int 0)))
cd2b37d9 8241 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
8242 (plus:SI (gt:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
8243 (clobber (match_scratch:SI 4 "=&r"))]
ca7f5001
RK
8244 "TARGET_POWER"
8245 "doz %4,%2,%1\;{ai|addic} %4,%4,-1\;{aze.|addze.} %0,%3"
b19003d8
RK
8246 [(set_attr "type" "compare")
8247 (set_attr "length" "12")])
1fd4e8c1
RK
8248
8249(define_insn ""
cd2b37d9
RK
8250 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
8251 (neg:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
8252 (const_int 0))))]
8253 ""
ca7f5001 8254 "{sfi|subfic} %0,%1,0\;{ame|addme} %0,%0\;{srai|srawi} %0,%0,31"
b19003d8 8255 [(set_attr "length" "12")])
1fd4e8c1
RK
8256
8257(define_insn ""
cd2b37d9
RK
8258 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
8259 (neg:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 8260 (match_operand:SI 2 "reg_or_short_operand" "r"))))]
ca7f5001
RK
8261 "TARGET_POWER"
8262 "doz %0,%2,%1\;nabs %0,%0\;{srai|srawi} %0,%0,31"
b19003d8 8263 [(set_attr "length" "12")])
1fd4e8c1
RK
8264
8265(define_insn ""
cd2b37d9
RK
8266 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
8267 (gtu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
8268 (match_operand:SI 2 "reg_or_short_operand" "rI")))]
8269 ""
ca7f5001 8270 "{sf%I2|subf%I2c} %0,%1,%2\;{sfe|subfe} %0,%0,%0\;neg %0,%0"
b19003d8 8271 [(set_attr "length" "12")])
1fd4e8c1
RK
8272
8273(define_insn ""
8274 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
8275 (compare:CC
cd2b37d9 8276 (gtu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
8277 (match_operand:SI 2 "reg_or_short_operand" "rI"))
8278 (const_int 0)))
cd2b37d9 8279 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
8280 (gtu:SI (match_dup 1) (match_dup 2)))]
8281 ""
ca7f5001 8282 "{sf%I2|subf%I2c} %0,%1,%2\;{sfe|subfe} %0,%0,%0\;neg. %0,%0"
b19003d8
RK
8283 [(set_attr "type" "compare")
8284 (set_attr "length" "12")])
1fd4e8c1
RK
8285
8286(define_insn ""
00751805
RK
8287 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r")
8288 (plus:SI (gtu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r")
8289 (match_operand:SI 2 "reg_or_short_operand" "I,r,rI"))
8290 (match_operand:SI 3 "reg_or_short_operand" "r,r,I")))
8291 (clobber (match_scratch:SI 4 "=&r,&r,&r"))]
1fd4e8c1 8292 ""
00751805 8293 "@
ca7f5001
RK
8294 {ai|addic} %4,%1,%k2\;{aze|addze} %0,%3
8295 {sf%I2|subf%I2c} %4,%1,%2\;{sfe|subfe} %4,%4,%4\;{sf%I3|subf%I3c} %0,%4,%3
8296 {sf%I2|subf%I2c} %4,%1,%2\;{sfe|subfe} %4,%4,%4\;{sf%I3|subf%I3c} %0,%4,%3"
b19003d8 8297 [(set_attr "length" "8,12,12")])
1fd4e8c1
RK
8298
8299(define_insn ""
3d91674b 8300 [(set (match_operand:CC 0 "cc_reg_operand" "=x,x")
1fd4e8c1 8301 (compare:CC
3d91674b
RK
8302 (plus:SI (gtu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
8303 (match_operand:SI 2 "reg_or_short_operand" "I,r"))
8304 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
1fd4e8c1 8305 (const_int 0)))
3d91674b 8306 (clobber (match_scratch:SI 4 "=&r,&r"))]
1fd4e8c1 8307 ""
00751805 8308 "@
ca7f5001
RK
8309 {ai|addic} %4,%1,%k2\;{aze.|addze.} %0,%3
8310 {sf%I2|subf%I2c} %4,%1,%2\;{sfe|subfe} %4,%4,%4\;{sf.|subfc.} %0,%4,%3"
b19003d8 8311 [(set_attr "type" "compare")
3d91674b 8312 (set_attr "length" "8,12")])
1fd4e8c1
RK
8313
8314(define_insn ""
3d91674b 8315 [(set (match_operand:CC 5 "cc_reg_operand" "=x,x")
1fd4e8c1 8316 (compare:CC
3d91674b
RK
8317 (plus:SI (gtu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
8318 (match_operand:SI 2 "reg_or_short_operand" "I,r"))
8319 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
1fd4e8c1 8320 (const_int 0)))
3d91674b 8321 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
1fd4e8c1 8322 (plus:SI (gtu:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
3d91674b 8323 (clobber (match_scratch:SI 4 "=&r,&r"))]
1fd4e8c1 8324 ""
00751805 8325 "@
ca7f5001
RK
8326 {ai|addic} %4,%1,%k2\;{aze.|addze.} %0,%3
8327 {sf%I2|subf%I2c} %4,%1,%2\;{sfe|subfe} %4,%4,%4\;{sf.|subfc.} %0,%4,%3"
b19003d8 8328 [(set_attr "type" "compare")
3d91674b 8329 (set_attr "length" "8,12")])
1fd4e8c1
RK
8330
8331(define_insn ""
cd2b37d9
RK
8332 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
8333 (neg:SI (gtu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
8334 (match_operand:SI 2 "reg_or_short_operand" "rI"))))]
8335 ""
ca7f5001 8336 "{sf%I2|subf%I2c} %0,%1,%2\;{sfe|subfe} %0,%0,%0"
b19003d8 8337 [(set_attr "length" "8")])
1fd4e8c1
RK
8338\f
8339;; Define both directions of branch and return. If we need a reload
8340;; register, we'd rather use CR0 since it is much easier to copy a
8341;; register CC value to there.
8342
8343(define_insn ""
8344 [(set (pc)
8345 (if_then_else (match_operator 1 "branch_comparison_operator"
8346 [(match_operand 2
8347 "cc_reg_operand" "x,?y")
8348 (const_int 0)])
8349 (label_ref (match_operand 0 "" ""))
8350 (pc)))]
8351 ""
b19003d8
RK
8352 "*
8353{
8354 if (get_attr_length (insn) == 8)
8355 return \"%C1bc %t1,%j1,%l0\";
8356 else
8357 return \"%C1bc %T1,%j1,$+8\;b %l0\";
8358}"
8359 [(set_attr "type" "branch")])
8360
1fd4e8c1
RK
8361(define_insn ""
8362 [(set (pc)
8363 (if_then_else (match_operator 0 "branch_comparison_operator"
8364 [(match_operand 1
8365 "cc_reg_operand" "x,?y")
8366 (const_int 0)])
8367 (return)
8368 (pc)))]
8369 "direct_return ()"
ca7f5001 8370 "{%C0bcr|%C0bclr} %t0,%j0"
b19003d8 8371 [(set_attr "length" "8")])
1fd4e8c1
RK
8372
8373(define_insn ""
8374 [(set (pc)
8375 (if_then_else (match_operator 1 "branch_comparison_operator"
8376 [(match_operand 2
8377 "cc_reg_operand" "x,?y")
8378 (const_int 0)])
8379 (pc)
8380 (label_ref (match_operand 0 "" ""))))]
8381 ""
b19003d8
RK
8382 "*
8383{
8384 if (get_attr_length (insn) == 8)
8385 return \"%C1bc %T1,%j1,%l0\";
8386 else
8387 return \"%C1bc %t1,%j1,$+8\;b %l0\";
8388}"
8389 [(set_attr "type" "branch")])
1fd4e8c1
RK
8390
8391(define_insn ""
8392 [(set (pc)
8393 (if_then_else (match_operator 0 "branch_comparison_operator"
8394 [(match_operand 1
8395 "cc_reg_operand" "x,?y")
8396 (const_int 0)])
8397 (pc)
8398 (return)))]
8399 "direct_return ()"
ca7f5001 8400 "{%C0bcr|%C0bclr} %T0,%j0"
b19003d8 8401 [(set_attr "length" "8")])
1fd4e8c1
RK
8402
8403;; Unconditional branch and return.
8404
8405(define_insn "jump"
8406 [(set (pc)
8407 (label_ref (match_operand 0 "" "")))]
8408 ""
8409 "b %l0")
8410
8411(define_insn "return"
8412 [(return)]
8413 "direct_return ()"
324e52cc
TG
8414 "{br|blr}"
8415 [(set_attr "type" "jmpreg")])
1fd4e8c1
RK
8416
8417(define_insn "indirect_jump"
8418 [(set (pc) (match_operand:SI 0 "register_operand" "c,l"))]
8419 ""
8420 "@
8421 bctr
324e52cc
TG
8422 {br|blr}"
8423 [(set_attr "type" "jmpreg")])
1fd4e8c1 8424
266eb58a
DE
8425(define_insn ""
8426 [(set (pc) (match_operand:DI 0 "register_operand" "c,l"))]
8427 "TARGET_POWERPC64"
8428 "@
8429 bctr
8430 {br|blr}"
8431 [(set_attr "type" "jmpreg")])
8432
1fd4e8c1
RK
8433;; Table jump for switch statements:
8434(define_expand "tablejump"
8435 [(set (match_dup 3)
8436 (plus:SI (match_operand:SI 0 "" "")
8437 (match_dup 2)))
8438 (parallel [(set (pc) (match_dup 3))
8439 (use (label_ref (match_operand 1 "" "")))])]
8440 ""
8441 "
8442{ operands[0] = force_reg (SImode, operands[0]);
8443 operands[2] = force_reg (SImode, gen_rtx (LABEL_REF, VOIDmode, operands[1]));
8444 operands[3] = gen_reg_rtx (SImode);
8445}")
8446
8447(define_insn ""
8448 [(set (pc)
740ab4a2 8449 (match_operand:SI 0 "register_operand" "c,l"))
1fd4e8c1
RK
8450 (use (label_ref (match_operand 1 "" "")))]
8451 ""
8452 "@
8453 bctr
a6845123
RK
8454 {br|blr}"
8455 [(set_attr "type" "jmpreg")])
1fd4e8c1 8456
266eb58a
DE
8457(define_insn ""
8458 [(set (pc)
8459 (match_operand:DI 0 "register_operand" "c,l"))
8460 (use (label_ref (match_operand 1 "" "")))]
8461 "TARGET_POWERPC64"
8462 "@
8463 bctr
8464 {br|blr}"
8465 [(set_attr "type" "jmpreg")])
8466
1fd4e8c1
RK
8467(define_insn "nop"
8468 [(const_int 0)]
8469 ""
ca7f5001 8470 "{cror 0,0,0|nop}")
1fd4e8c1 8471\f
7e69e155 8472;; Define the subtract-one-and-jump insns, starting with the template
c225ba7b
RK
8473;; so loop.c knows what to generate.
8474
b6c9286a
MM
8475(define_expand "decrement_and_branch_on_count"
8476 [(parallel [(set (pc) (if_then_else (ne (match_operand:SI 0 "register_operand" "")
c225ba7b
RK
8477 (const_int 1))
8478 (label_ref (match_operand 1 "" ""))
8479 (pc)))
b6c9286a
MM
8480 (set (match_dup 0)
8481 (plus:SI (match_dup 0)
8482 (const_int -1)))
5f81043f
RK
8483 (clobber (match_scratch:CC 2 ""))
8484 (clobber (match_scratch:SI 3 ""))])]
c225ba7b
RK
8485 ""
8486 "")
8487
1fd4e8c1
RK
8488;; We need to be able to do this for any operand, including MEM, or we
8489;; will cause reload to blow up since we don't allow output reloads on
7e69e155 8490;; JUMP_INSNs.
5f81043f
RK
8491;; In order that the length attribute is calculated correctly, the
8492;; label MUST be operand 0.
8493
1fd4e8c1
RK
8494(define_insn ""
8495 [(set (pc)
5f81043f 8496 (if_then_else (ne (match_operand:SI 1 "register_operand" "c,*r,*r")
1fd4e8c1 8497 (const_int 1))
a6845123 8498 (label_ref (match_operand 0 "" ""))
1fd4e8c1 8499 (pc)))
5f81043f
RK
8500 (set (match_operand:SI 2 "register_operand" "=1,*r,m*q*c*l")
8501 (plus:SI (match_dup 1)
8502 (const_int -1)))
1fd4e8c1
RK
8503 (clobber (match_scratch:CC 3 "=X,&x,&x"))
8504 (clobber (match_scratch:SI 4 "=X,X,r"))]
8505 ""
b19003d8
RK
8506 "*
8507{
af87a13e 8508 if (which_alternative != 0)
b19003d8
RK
8509 return \"#\";
8510 else if (get_attr_length (insn) == 8)
a6845123 8511 return \"{bdn|bdnz} %l0\";
b19003d8 8512 else
a6845123 8513 return \"bdz $+8\;b %l0\";
b19003d8 8514}"
baf97f86
RK
8515 [(set_attr "type" "branch")
8516 (set_attr "length" "*,12,16")])
7e69e155 8517
5f81043f
RK
8518(define_insn ""
8519 [(set (pc)
8520 (if_then_else (ne (match_operand:SI 1 "register_operand" "c,*r,*r")
8521 (const_int 1))
8522 (pc)
8523 (label_ref (match_operand 0 "" ""))))
8524 (set (match_operand:SI 2 "register_operand" "=1,*r,m*q*c*l")
8525 (plus:SI (match_dup 1)
8526 (const_int -1)))
8527 (clobber (match_scratch:CC 3 "=X,&x,&x"))
8528 (clobber (match_scratch:SI 4 "=X,X,r"))]
8529 ""
8530 "*
8531{
8532 if (which_alternative != 0)
8533 return \"#\";
8534 else if (get_attr_length (insn) == 8)
8535 return \"bdz %l0\";
8536 else
8537 return \"{bdn|bdnz} $+8\;b %l0\";
8538}"
8539 [(set_attr "type" "branch")
8540 (set_attr "length" "*,12,16")])
8541
c225ba7b 8542;; Similar, but we can use GE since we have a REG_NONNEG.
1fd4e8c1
RK
8543(define_insn ""
8544 [(set (pc)
5f81043f 8545 (if_then_else (ge (match_operand:SI 1 "register_operand" "c,*r,*r")
1fd4e8c1 8546 (const_int 0))
a6845123 8547 (label_ref (match_operand 0 "" ""))
1fd4e8c1 8548 (pc)))
5f81043f
RK
8549 (set (match_operand:SI 2 "register_operand" "=1,*r,m*q*c*l")
8550 (plus:SI (match_dup 1)
8551 (const_int -1)))
1fd4e8c1
RK
8552 (clobber (match_scratch:CC 3 "=X,&x,&X"))
8553 (clobber (match_scratch:SI 4 "=X,X,r"))]
8554 "find_reg_note (insn, REG_NONNEG, 0)"
b19003d8
RK
8555 "*
8556{
af87a13e 8557 if (which_alternative != 0)
b19003d8
RK
8558 return \"#\";
8559 else if (get_attr_length (insn) == 8)
a6845123 8560 return \"{bdn|bdnz} %l0\";
b19003d8 8561 else
a6845123 8562 return \"bdz $+8\;b %l0\";
b19003d8 8563}"
baf97f86
RK
8564 [(set_attr "type" "branch")
8565 (set_attr "length" "*,12,16")])
7e69e155 8566
1fd4e8c1
RK
8567(define_insn ""
8568 [(set (pc)
5f81043f
RK
8569 (if_then_else (ge (match_operand:SI 1 "register_operand" "c,*r,*r")
8570 (const_int 0))
8571 (pc)
8572 (label_ref (match_operand 0 "" ""))))
8573 (set (match_operand:SI 2 "register_operand" "=1,*r,m*q*c*l")
8574 (plus:SI (match_dup 1)
8575 (const_int -1)))
8576 (clobber (match_scratch:CC 3 "=X,&x,&X"))
8577 (clobber (match_scratch:SI 4 "=X,X,r"))]
8578 "find_reg_note (insn, REG_NONNEG, 0)"
8579 "*
8580{
8581 if (which_alternative != 0)
8582 return \"#\";
8583 else if (get_attr_length (insn) == 8)
8584 return \"bdz %l0\";
8585 else
8586 return \"{bdn|bdnz} $+8\;b %l0\";
8587}"
8588 [(set_attr "type" "branch")
8589 (set_attr "length" "*,12,16")])
8590
8591(define_insn ""
8592 [(set (pc)
8593 (if_then_else (eq (match_operand:SI 1 "register_operand" "c,*r,*r")
1fd4e8c1 8594 (const_int 1))
a6845123 8595 (label_ref (match_operand 0 "" ""))
1fd4e8c1 8596 (pc)))
5f81043f
RK
8597 (set (match_operand:SI 2 "register_operand" "=1,*r,m*q*c*l")
8598 (plus:SI (match_dup 1)
8599 (const_int -1)))
1fd4e8c1
RK
8600 (clobber (match_scratch:CC 3 "=X,&x,&x"))
8601 (clobber (match_scratch:SI 4 "=X,X,r"))]
8602 ""
b19003d8
RK
8603 "*
8604{
af87a13e 8605 if (which_alternative != 0)
b19003d8
RK
8606 return \"#\";
8607 else if (get_attr_length (insn) == 8)
a6845123 8608 return \"bdz %l0\";
b19003d8 8609 else
a6845123 8610 return \"{bdn|bdnz} $+8\;b %l0\";
b19003d8 8611}"
baf97f86
RK
8612 [(set_attr "type" "branch")
8613 (set_attr "length" "*,12,16")])
1fd4e8c1 8614
5f81043f
RK
8615(define_insn ""
8616 [(set (pc)
8617 (if_then_else (eq (match_operand:SI 1 "register_operand" "c,*r,*r")
8618 (const_int 1))
8619 (pc)
8620 (label_ref (match_operand 0 "" ""))))
8621 (set (match_operand:SI 2 "register_operand" "=1,*r,m*q*c*l")
8622 (plus:SI (match_dup 1)
8623 (const_int -1)))
8624 (clobber (match_scratch:CC 3 "=X,&x,&x"))
8625 (clobber (match_scratch:SI 4 "=X,X,r"))]
8626 ""
8627 "*
8628{
8629 if (which_alternative != 0)
8630 return \"#\";
8631 else if (get_attr_length (insn) == 8)
8632 return \"{bdn|bdnz} %l0\";
8633 else
8634 return \"bdz $+8\;b %l0\";
8635}"
8636 [(set_attr "type" "branch")
8637 (set_attr "length" "*,12,16")])
8638
1fd4e8c1
RK
8639(define_split
8640 [(set (pc)
8641 (if_then_else (match_operator 2 "comparison_operator"
cd2b37d9 8642 [(match_operand:SI 1 "gpc_reg_operand" "")
1fd4e8c1
RK
8643 (const_int 1)])
8644 (match_operand 5 "" "")
8645 (match_operand 6 "" "")))
cd2b37d9 8646 (set (match_operand:SI 0 "gpc_reg_operand" "")
5f81043f
RK
8647 (plus:SI (match_dup 1)
8648 (const_int -1)))
1fd4e8c1
RK
8649 (clobber (match_scratch:CC 3 ""))
8650 (clobber (match_scratch:SI 4 ""))]
8651 "reload_completed"
8652 [(parallel [(set (match_dup 3)
5f81043f
RK
8653 (compare:CC (plus:SI (match_dup 1)
8654 (const_int -1))
1fd4e8c1 8655 (const_int 0)))
5f81043f
RK
8656 (set (match_dup 0)
8657 (plus:SI (match_dup 1)
8658 (const_int -1)))])
8659 (set (pc) (if_then_else (match_dup 7)
8660 (match_dup 5)
8661 (match_dup 6)))]
1fd4e8c1
RK
8662 "
8663{ operands[7] = gen_rtx (GET_CODE (operands[2]), VOIDmode, operands[3],
8664 const0_rtx); }")
8665
8666(define_split
8667 [(set (pc)
8668 (if_then_else (match_operator 2 "comparison_operator"
cd2b37d9 8669 [(match_operand:SI 1 "gpc_reg_operand" "")
1fd4e8c1
RK
8670 (const_int 1)])
8671 (match_operand 5 "" "")
8672 (match_operand 6 "" "")))
8673 (set (match_operand:SI 0 "general_operand" "")
8674 (plus:SI (match_dup 1) (const_int -1)))
8675 (clobber (match_scratch:CC 3 ""))
8676 (clobber (match_scratch:SI 4 ""))]
cd2b37d9 8677 "reload_completed && ! gpc_reg_operand (operands[0], SImode)"
1fd4e8c1 8678 [(parallel [(set (match_dup 3)
5f81043f
RK
8679 (compare:CC (plus:SI (match_dup 1)
8680 (const_int -1))
1fd4e8c1 8681 (const_int 0)))
5f81043f
RK
8682 (set (match_dup 4)
8683 (plus:SI (match_dup 1)
8684 (const_int -1)))])
8685 (set (match_dup 0)
8686 (match_dup 4))
8687 (set (pc) (if_then_else (match_dup 7)
8688 (match_dup 5)
8689 (match_dup 6)))]
1fd4e8c1
RK
8690 "
8691{ operands[7] = gen_rtx (GET_CODE (operands[2]), VOIDmode, operands[3],
8692 const0_rtx); }")