]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/config/rs6000/rs6000.md
602 uses 603 description
[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{
e6ca2c17
DE
891 HOST_WIDE_INT low = INTVAL (operands[2]) & 0xffff;
892 HOST_WIDE_INT high = INTVAL (operands[2]) & (~ (HOST_WIDE_INT) 0xffff);
1fd4e8c1 893
f357808b 894 if (low & 0x8000)
e6ca2c17 895 high += 0x10000, low |= ((HOST_WIDE_INT) -1) << 16;
1fd4e8c1 896
e6ca2c17
DE
897 operands[3] = GEN_INT (high);
898 operands[4] = GEN_INT (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 ""
d944f453 923 "nor. %0,%1,%1"
ca7f5001 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);
a66078ee 2071 return \"{rlimi|rlwimi} %0,%3,%h4,%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
a66078ee 2087 operands[4] = gen_rtx (CONST_INT, VOIDmode, shift - start - size);
d56d506a 2088 operands[1] = gen_rtx (CONST_INT, VOIDmode, start + size - 1);
a66078ee 2089 return \"{rlimi|rlwimi} %0,%3,%h4,%h2,%h1\";
d56d506a
RK
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
a66078ee 2105 operands[4] = gen_rtx (CONST_INT, VOIDmode, 32 - shift - start - size);
d56d506a 2106 operands[1] = gen_rtx (CONST_INT, VOIDmode, start + size - 1);
a66078ee 2107 return \"{rlimi|rlwimi} %0,%3,%h4,%h2,%h1\";
d56d506a
RK
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
a66078ee 2123 operands[4] = gen_rtx (CONST_INT, VOIDmode, 32 - shift - start - size);
d56d506a 2124 operands[1] = gen_rtx (CONST_INT, VOIDmode, start + size - 1);
a66078ee 2125 return \"{rlimi|rlwimi} %0,%3,%h4,%h2,%h1\";
d56d506a
RK
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,
a66078ee 2145 extract_start + extract_size - insert_start - insert_size);
d56d506a 2146 operands[1] = gen_rtx (CONST_INT, VOIDmode, insert_start + insert_size - 1);
a66078ee 2147 return \"{rlimi|rlwimi} %0,%3,%h5,%h2,%h1\";
d56d506a
RK
2148}")
2149
685f3906
DE
2150(define_insn ""
2151 [(set (zero_extract:DI (match_operand:DI 0 "gpc_reg_operand" "+r")
2152 (match_operand:DI 1 "const_int_operand" "i")
2153 (match_operand:DI 2 "const_int_operand" "i"))
2154 (match_operand:DI 3 "gpc_reg_operand" "r"))]
2155 "TARGET_POWERPC64"
2156 "*
2157{
2158 int start = INTVAL (operands[2]) & 63;
2159 int size = INTVAL (operands[1]) & 63;
2160
2161 operands[2] = gen_rtx (CONST_INT, VOIDmode, 64 - start - size);
a66078ee 2162 return \"rldimi %0,%3,%H2,%H1\";
685f3906
DE
2163}")
2164
034c1be0
MM
2165(define_expand "extzv"
2166 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2167 (zero_extract:SI (match_operand:SI 1 "gpc_reg_operand" "r")
2168 (match_operand:SI 2 "const_int_operand" "i")
2169 (match_operand:SI 3 "const_int_operand" "i")))]
2170 ""
2171 "
2172{
2173 /* Do not handle 16/8 bit structures that fit in HI/QI modes directly, since
2174 the (SUBREG:SI (REG:HI xxx)) that is otherwise generated can confuse the
2175 compiler if the address of the structure is taken later. */
2176 if (GET_CODE (operands[0]) == SUBREG
2177 && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (operands[0]))) < UNITS_PER_WORD))
2178 FAIL;
2179}")
2180
2181(define_insn ""
cd2b37d9
RK
2182 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2183 (zero_extract:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
2184 (match_operand:SI 2 "const_int_operand" "i")
2185 (match_operand:SI 3 "const_int_operand" "i")))]
2186 ""
2187 "*
2188{
2189 int start = INTVAL (operands[3]) & 31;
2190 int size = INTVAL (operands[2]) & 31;
2191
2192 if (start + size >= 32)
2193 operands[3] = const0_rtx;
2194 else
2195 operands[3] = gen_rtx (CONST_INT, VOIDmode, start + size);
ca7f5001 2196 return \"{rlinm|rlwinm} %0,%1,%3,%s2,31\";
1fd4e8c1
RK
2197}")
2198
2199(define_insn ""
2200 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
cd2b37d9 2201 (compare:CC (zero_extract:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
2202 (match_operand:SI 2 "const_int_operand" "i")
2203 (match_operand:SI 3 "const_int_operand" "i"))
2204 (const_int 0)))
2205 (clobber (match_scratch:SI 4 "=r"))]
2206 ""
2207 "*
2208{
2209 int start = INTVAL (operands[3]) & 31;
2210 int size = INTVAL (operands[2]) & 31;
2211
a7a975e1
RK
2212 /* If the bitfield being tested fits in the upper or lower half of a
2213 word, it is possible to use andiu. or andil. to test it. This is
2214 useful because the condition register set-use delay is smaller for
2215 andi[ul]. than for rlinm. This doesn't work when the starting bit
2216 position is 0 because the LT and GT bits may be set wrong. */
2217
2218 if ((start > 0 && start + size <= 16) || start >= 16)
df031c43
RK
2219 {
2220 operands[3] = gen_rtx (CONST_INT, VOIDmode,
2221 ((1 << (16 - (start & 15)))
2222 - (1 << (16 - (start & 15) - size))));
2223 if (start < 16)
ca7f5001 2224 return \"{andiu.|andis.} %4,%1,%3\";
df031c43 2225 else
ca7f5001 2226 return \"{andil.|andi.} %4,%1,%3\";
df031c43 2227 }
7e69e155 2228
1fd4e8c1
RK
2229 if (start + size >= 32)
2230 operands[3] = const0_rtx;
2231 else
2232 operands[3] = gen_rtx (CONST_INT, VOIDmode, start + size);
ca7f5001 2233 return \"{rlinm.|rlwinm.} %4,%1,%3,%s2,31\";
1fd4e8c1
RK
2234}"
2235 [(set_attr "type" "compare")])
2236
2237(define_insn ""
2238 [(set (match_operand:CC 4 "cc_reg_operand" "=x")
cd2b37d9 2239 (compare:CC (zero_extract:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
2240 (match_operand:SI 2 "const_int_operand" "i")
2241 (match_operand:SI 3 "const_int_operand" "i"))
2242 (const_int 0)))
cd2b37d9 2243 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
2244 (zero_extract:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
2245 ""
2246 "*
2247{
2248 int start = INTVAL (operands[3]) & 31;
2249 int size = INTVAL (operands[2]) & 31;
2250
a7a975e1 2251 if (start >= 16 && start + size == 32)
df031c43 2252 {
a7a975e1 2253 operands[3] = gen_rtx (CONST_INT, VOIDmode, (1 << (32 - start)) - 1);
ca7f5001 2254 return \"{andil.|andi.} %0,%1,%3\";
df031c43 2255 }
7e69e155 2256
1fd4e8c1
RK
2257 if (start + size >= 32)
2258 operands[3] = const0_rtx;
2259 else
2260 operands[3] = gen_rtx (CONST_INT, VOIDmode, start + size);
ca7f5001 2261 return \"{rlinm.|rlwinm.} %0,%1,%3,%s2,31\";
1fd4e8c1
RK
2262}"
2263 [(set_attr "type" "delayed_compare")])
2264
685f3906
DE
2265(define_insn ""
2266 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2267 (zero_extract:DI (match_operand:DI 1 "gpc_reg_operand" "r")
2268 (match_operand:DI 2 "const_int_operand" "i")
2269 (match_operand:DI 3 "const_int_operand" "i")))]
2270 "TARGET_POWERPC64"
2271 "*
2272{
2273 int start = INTVAL (operands[3]) & 63;
2274 int size = INTVAL (operands[2]) & 63;
2275
2276 if (start + size >= 64)
2277 operands[3] = const0_rtx;
2278 else
2279 operands[3] = gen_rtx (CONST_INT, VOIDmode, start + size);
2280 operands[2] = gen_rtx (CONST_INT, VOIDmode, 64 - size);
2281 return \"rldicl %0,%1,%3,%2\";
2282}")
2283
2284(define_insn ""
2285 [(set (match_operand:CC 0 "gpc_reg_operand" "=x")
2286 (compare:CC (zero_extract:DI (match_operand:DI 1 "gpc_reg_operand" "r")
2287 (match_operand:DI 2 "const_int_operand" "i")
2288 (match_operand:DI 3 "const_int_operand" "i"))
2289 (const_int 0)))
2290 (clobber (match_scratch:DI 4 "=r"))]
2291 "TARGET_POWERPC64"
2292 "*
2293{
2294 int start = INTVAL (operands[3]) & 63;
2295 int size = INTVAL (operands[2]) & 63;
2296
2297 if (start + size >= 64)
2298 operands[3] = const0_rtx;
2299 else
2300 operands[3] = gen_rtx (CONST_INT, VOIDmode, start + size);
2301 operands[2] = gen_rtx (CONST_INT, VOIDmode, 64 - size);
2302 return \"rldicl. %4,%1,%3,%2\";
2303}")
2304
2305(define_insn ""
2306 [(set (match_operand:CC 4 "gpc_reg_operand" "=x")
2307 (compare:CC (zero_extract:DI (match_operand:DI 1 "gpc_reg_operand" "r")
2308 (match_operand:DI 2 "const_int_operand" "i")
2309 (match_operand:DI 3 "const_int_operand" "i"))
2310 (const_int 0)))
2311 (set (match_operand:DI 0 "gpc_reg_operand" "=r")
2312 (zero_extract:DI (match_dup 1) (match_dup 2) (match_dup 3)))]
2313 "TARGET_POWERPC64"
2314 "*
2315{
2316 int start = INTVAL (operands[3]) & 63;
2317 int size = INTVAL (operands[2]) & 63;
2318
2319 if (start + size >= 64)
2320 operands[3] = const0_rtx;
2321 else
2322 operands[3] = gen_rtx (CONST_INT, VOIDmode, start + size);
2323 operands[2] = gen_rtx (CONST_INT, VOIDmode, 64 - size);
2324 return \"rldicl. %0,%1,%3,%2\";
2325}")
2326
1fd4e8c1 2327(define_insn "rotlsi3"
cd2b37d9
RK
2328 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2329 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
2330 (match_operand:SI 2 "reg_or_cint_operand" "ri")))]
2331 ""
ca7f5001 2332 "{rl%I2nm|rlw%I2nm} %0,%1,%h2,0xffffffff")
1fd4e8c1
RK
2333
2334(define_insn ""
2335 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
cd2b37d9 2336 (compare:CC (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
2337 (match_operand:SI 2 "reg_or_cint_operand" "ri"))
2338 (const_int 0)))
2339 (clobber (match_scratch:SI 3 "=r"))]
2340 ""
ca7f5001 2341 "{rl%I2nm.|rlw%I2nm.} %3,%1,%h2,0xffffffff"
1fd4e8c1
RK
2342 [(set_attr "type" "delayed_compare")])
2343
2344(define_insn ""
2345 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
cd2b37d9 2346 (compare:CC (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
2347 (match_operand:SI 2 "reg_or_cint_operand" "ri"))
2348 (const_int 0)))
cd2b37d9 2349 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
2350 (rotate:SI (match_dup 1) (match_dup 2)))]
2351 ""
ca7f5001 2352 "{rl%I2nm.|rlw%I2nm.} %0,%1,%h2,0xffffffff"
1fd4e8c1
RK
2353 [(set_attr "type" "delayed_compare")])
2354
2355(define_insn ""
cd2b37d9
RK
2356 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2357 (and:SI (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
2358 (match_operand:SI 2 "reg_or_cint_operand" "ri"))
2359 (match_operand:SI 3 "mask_operand" "L")))]
2360 ""
ca7f5001 2361 "{rl%I2nm|rlw%I2nm} %0,%1,%h2,%m3,%M3")
1fd4e8c1
RK
2362
2363(define_insn ""
2364 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
2365 (compare:CC (and:SI
cd2b37d9 2366 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
2367 (match_operand:SI 2 "reg_or_cint_operand" "ri"))
2368 (match_operand:SI 3 "mask_operand" "L"))
2369 (const_int 0)))
2370 (clobber (match_scratch:SI 4 "=r"))]
2371 ""
ca7f5001 2372 "{rl%I2nm.|rlw%I2nm.} %4,%1,%h2,%m3,%M3"
1fd4e8c1
RK
2373 [(set_attr "type" "delayed_compare")])
2374
2375(define_insn ""
2376 [(set (match_operand:CC 4 "cc_reg_operand" "=x")
2377 (compare:CC (and:SI
cd2b37d9 2378 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
2379 (match_operand:SI 2 "reg_or_cint_operand" "ri"))
2380 (match_operand:SI 3 "mask_operand" "L"))
2381 (const_int 0)))
cd2b37d9 2382 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
2383 (and:SI (rotate:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
2384 ""
ca7f5001 2385 "{rl%I2nm.|rlw%I2nm.} %0,%1,%h2,%m3,%M3"
1fd4e8c1
RK
2386 [(set_attr "type" "delayed_compare")])
2387
2388(define_insn ""
cd2b37d9 2389 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
2390 (zero_extend:SI
2391 (subreg:QI
cd2b37d9 2392 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
2393 (match_operand:SI 2 "reg_or_cint_operand" "ri")) 0)))]
2394 ""
ca7f5001 2395 "{rl%I2nm|rlw%I2nm} %0,%1,%h2,0xff")
1fd4e8c1
RK
2396
2397(define_insn ""
2398 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
2399 (compare:CC (zero_extend:SI
2400 (subreg:QI
cd2b37d9 2401 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
2402 (match_operand:SI 2 "reg_or_cint_operand" "ri")) 0))
2403 (const_int 0)))
2404 (clobber (match_scratch:SI 3 "=r"))]
2405 ""
ca7f5001 2406 "{rl%I2nm.|rlw%I2nm.} %3,%1,%h2,0xff"
1fd4e8c1
RK
2407 [(set_attr "type" "delayed_compare")])
2408
2409(define_insn ""
2410 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
2411 (compare:CC (zero_extend:SI
2412 (subreg:QI
cd2b37d9 2413 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
2414 (match_operand:SI 2 "reg_or_cint_operand" "ri")) 0))
2415 (const_int 0)))
cd2b37d9 2416 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
2417 (zero_extend:SI (subreg:QI (rotate:SI (match_dup 1) (match_dup 2)) 0)))]
2418 ""
ca7f5001 2419 "{rl%I2nm.|rlw%I2nm.} %0,%1,%h2,0xff"
1fd4e8c1
RK
2420 [(set_attr "type" "delayed_compare")])
2421
2422(define_insn ""
cd2b37d9 2423 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
2424 (zero_extend:SI
2425 (subreg:HI
cd2b37d9 2426 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
2427 (match_operand:SI 2 "reg_or_cint_operand" "ri")) 0)))]
2428 ""
ca7f5001 2429 "{rl%I2nm|rlw%I2nm} %0,%1,%h2,0xffff")
1fd4e8c1
RK
2430
2431(define_insn ""
2432 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
2433 (compare:CC (zero_extend:SI
2434 (subreg:HI
cd2b37d9 2435 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
2436 (match_operand:SI 2 "reg_or_cint_operand" "ri")) 0))
2437 (const_int 0)))
2438 (clobber (match_scratch:SI 3 "=r"))]
2439 ""
ca7f5001 2440 "{rl%I2nm.|rlw%I2nm.} %3,%1,%h2,0xffff"
1fd4e8c1
RK
2441 [(set_attr "type" "delayed_compare")])
2442
2443(define_insn ""
2444 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
2445 (compare:CC (zero_extend:SI
2446 (subreg:HI
cd2b37d9 2447 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
2448 (match_operand:SI 2 "reg_or_cint_operand" "ri")) 0))
2449 (const_int 0)))
cd2b37d9 2450 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
2451 (zero_extend:SI (subreg:HI (rotate:SI (match_dup 1) (match_dup 2)) 0)))]
2452 ""
ca7f5001 2453 "{rl%I2nm.|rlw%I2nm.} %0,%1,%h2,0xffff"
1fd4e8c1
RK
2454 [(set_attr "type" "delayed_compare")])
2455
2456;; Note that we use "sle." instead of "sl." so that we can set
2457;; SHIFT_COUNT_TRUNCATED.
2458
ca7f5001
RK
2459(define_expand "ashlsi3"
2460 [(use (match_operand:SI 0 "gpc_reg_operand" ""))
2461 (use (match_operand:SI 1 "gpc_reg_operand" ""))
2462 (use (match_operand:SI 2 "reg_or_cint_operand" ""))]
2463 ""
2464 "
2465{
2466 if (TARGET_POWER)
2467 emit_insn (gen_ashlsi3_power (operands[0], operands[1], operands[2]));
2468 else
25c341fa 2469 emit_insn (gen_ashlsi3_no_power (operands[0], operands[1], operands[2]));
ca7f5001
RK
2470 DONE;
2471}")
2472
2473(define_insn "ashlsi3_power"
cd2b37d9
RK
2474 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
2475 (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1
RK
2476 (match_operand:SI 2 "reg_or_cint_operand" "r,i")))
2477 (clobber (match_scratch:SI 3 "=q,X"))]
ca7f5001 2478 "TARGET_POWER"
1fd4e8c1
RK
2479 "@
2480 sle %0,%1,%2
ca7f5001
RK
2481 {sli|slwi} %0,%1,%h2"
2482 [(set_attr "length" "8")])
2483
25c341fa 2484(define_insn "ashlsi3_no_power"
ca7f5001
RK
2485 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2486 (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r")
2487 (match_operand:SI 2 "reg_or_cint_operand" "ri")))]
25c341fa 2488 "! TARGET_POWER"
d904e9ed 2489 "{sl|slw}%I2 %0,%1,%h2"
b19003d8 2490 [(set_attr "length" "8")])
1fd4e8c1
RK
2491
2492(define_insn ""
2493 [(set (match_operand:CC 0 "cc_reg_operand" "=x,x")
cd2b37d9 2494 (compare:CC (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1
RK
2495 (match_operand:SI 2 "reg_or_cint_operand" "r,i"))
2496 (const_int 0)))
2497 (clobber (match_scratch:SI 3 "=r,r"))
2498 (clobber (match_scratch:SI 4 "=q,X"))]
ca7f5001 2499 "TARGET_POWER"
1fd4e8c1
RK
2500 "@
2501 sle. %3,%1,%2
ca7f5001
RK
2502 {sli.|slwi.} %3,%1,%h2"
2503 [(set_attr "type" "delayed_compare")])
25c341fa 2504
ca7f5001
RK
2505(define_insn ""
2506 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
2507 (compare:CC (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r")
2508 (match_operand:SI 2 "reg_or_cint_operand" "ri"))
2509 (const_int 0)))
2510 (clobber (match_scratch:SI 3 "=r"))]
8ffd9c51 2511 "! TARGET_POWER"
d904e9ed 2512 "{sl|slw}%I2. %3,%1,%h2"
1fd4e8c1
RK
2513 [(set_attr "type" "delayed_compare")])
2514
2515(define_insn ""
2516 [(set (match_operand:CC 3 "cc_reg_operand" "=x,x")
cd2b37d9 2517 (compare:CC (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1
RK
2518 (match_operand:SI 2 "reg_or_cint_operand" "r,i"))
2519 (const_int 0)))
cd2b37d9 2520 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
1fd4e8c1
RK
2521 (ashift:SI (match_dup 1) (match_dup 2)))
2522 (clobber (match_scratch:SI 4 "=q,X"))]
ca7f5001 2523 "TARGET_POWER"
1fd4e8c1
RK
2524 "@
2525 sle. %0,%1,%2
ca7f5001
RK
2526 {sli.|slwi.} %0,%1,%h2"
2527 [(set_attr "type" "delayed_compare")])
25c341fa 2528
ca7f5001
RK
2529(define_insn ""
2530 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
2531 (compare:CC (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r")
2532 (match_operand:SI 2 "reg_or_cint_operand" "ri"))
2533 (const_int 0)))
2534 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
2535 (ashift:SI (match_dup 1) (match_dup 2)))]
8ffd9c51 2536 "! TARGET_POWER"
d904e9ed 2537 "{sl|slw}%I2. %0,%1,%h2"
1fd4e8c1
RK
2538 [(set_attr "type" "delayed_compare")])
2539
2540(define_insn ""
cd2b37d9
RK
2541 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2542 (and:SI (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
2543 (match_operand:SI 2 "const_int_operand" "i"))
2544 (match_operand:SI 3 "mask_operand" "L")))]
2545 "includes_lshift_p (operands[2], operands[3])"
d56d506a 2546 "{rlinm|rlwinm} %0,%1,%h2,%m3,%M3")
1fd4e8c1
RK
2547
2548(define_insn ""
2549 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
2550 (compare:CC
cd2b37d9 2551 (and:SI (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
2552 (match_operand:SI 2 "const_int_operand" "i"))
2553 (match_operand:SI 3 "mask_operand" "L"))
2554 (const_int 0)))
2555 (clobber (match_scratch:SI 4 "=r"))]
2556 "includes_lshift_p (operands[2], operands[3])"
d56d506a 2557 "{rlinm.|rlwinm.} %4,%1,%h2,%m3,%M3"
1fd4e8c1
RK
2558 [(set_attr "type" "delayed_compare")])
2559
2560(define_insn ""
2561 [(set (match_operand:CC 4 "cc_reg_operand" "=x")
2562 (compare:CC
cd2b37d9 2563 (and:SI (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
2564 (match_operand:SI 2 "const_int_operand" "i"))
2565 (match_operand:SI 3 "mask_operand" "L"))
2566 (const_int 0)))
cd2b37d9 2567 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
2568 (and:SI (ashift:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
2569 "includes_lshift_p (operands[2], operands[3])"
d56d506a 2570 "{rlinm.|rlwinm.} %0,%1,%h2,%m3,%M3"
1fd4e8c1
RK
2571 [(set_attr "type" "delayed_compare")])
2572
ca7f5001 2573;; The AIX assembler mis-handles "sri x,x,0", so write that case as
5c23c401 2574;; "sli x,x,0".
ca7f5001
RK
2575(define_expand "lshrsi3"
2576 [(use (match_operand:SI 0 "gpc_reg_operand" ""))
2577 (use (match_operand:SI 1 "gpc_reg_operand" ""))
2578 (use (match_operand:SI 2 "reg_or_cint_operand" ""))]
2579 ""
2580 "
2581{
2582 if (TARGET_POWER)
2583 emit_insn (gen_lshrsi3_power (operands[0], operands[1], operands[2]));
2584 else
25c341fa 2585 emit_insn (gen_lshrsi3_no_power (operands[0], operands[1], operands[2]));
ca7f5001
RK
2586 DONE;
2587}")
2588
2589(define_insn "lshrsi3_power"
cd2b37d9
RK
2590 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
2591 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1
RK
2592 (match_operand:SI 2 "reg_or_cint_operand" "r,i")))
2593 (clobber (match_scratch:SI 3 "=q,X"))]
ca7f5001 2594 "TARGET_POWER"
1fd4e8c1
RK
2595 "@
2596 sre %0,%1,%2
ca7f5001
RK
2597 {s%A2i|s%A2wi} %0,%1,%h2")
2598
25c341fa 2599(define_insn "lshrsi3_no_power"
ca7f5001
RK
2600 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2601 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
2602 (match_operand:SI 2 "reg_or_cint_operand" "ri")))]
25c341fa 2603 "! TARGET_POWER"
d904e9ed 2604 "{sr|srw}%I2 %0,%1,%h2")
1fd4e8c1
RK
2605
2606(define_insn ""
2607 [(set (match_operand:CC 0 "cc_reg_operand" "=x,x")
cd2b37d9 2608 (compare:CC (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1
RK
2609 (match_operand:SI 2 "reg_or_cint_operand" "r,i"))
2610 (const_int 0)))
2611 (clobber (match_scratch:SI 3 "=r,r"))
2612 (clobber (match_scratch:SI 4 "=q,X"))]
ca7f5001 2613 "TARGET_POWER"
1fd4e8c1
RK
2614 "@
2615 sre. %3,%1,%2
ca7f5001
RK
2616 {s%A2i.|s%A2wi.} %3,%1,%h2"
2617 [(set_attr "type" "delayed_compare")])
2618
2619(define_insn ""
2620 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
2621 (compare:CC (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
2622 (match_operand:SI 2 "reg_or_cint_operand" "ri"))
2623 (const_int 0)))
2624 (clobber (match_scratch:SI 3 "=r"))]
25c341fa 2625 "! TARGET_POWER"
d904e9ed 2626 "{sr|srw}%I2. %3,%1,%h2"
1fd4e8c1
RK
2627 [(set_attr "type" "delayed_compare")])
2628
2629(define_insn ""
2630 [(set (match_operand:CC 3 "cc_reg_operand" "=x,x")
cd2b37d9 2631 (compare:CC (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1
RK
2632 (match_operand:SI 2 "reg_or_cint_operand" "r,i"))
2633 (const_int 0)))
cd2b37d9 2634 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
1fd4e8c1
RK
2635 (lshiftrt:SI (match_dup 1) (match_dup 2)))
2636 (clobber (match_scratch:SI 4 "=q,X"))]
ca7f5001 2637 "TARGET_POWER"
1fd4e8c1
RK
2638 "@
2639 sre. %0,%1,%2
ca7f5001
RK
2640 {s%A2i.|s%A2wi.} %0,%1,%h2"
2641 [(set_attr "type" "delayed_compare")])
2642
2643(define_insn ""
2644 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
2645 (compare:CC (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
2646 (match_operand:SI 2 "reg_or_cint_operand" "ri"))
2647 (const_int 0)))
2648 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
2649 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
25c341fa 2650 "! TARGET_POWER"
d904e9ed 2651 "{sr|srw}%I2. %0,%1,%h2"
1fd4e8c1
RK
2652 [(set_attr "type" "delayed_compare")])
2653
2654(define_insn ""
cd2b37d9
RK
2655 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2656 (and:SI (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
2657 (match_operand:SI 2 "const_int_operand" "i"))
2658 (match_operand:SI 3 "mask_operand" "L")))]
2659 "includes_rshift_p (operands[2], operands[3])"
ca7f5001 2660 "{rlinm|rlwinm} %0,%1,%s2,%m3,%M3")
1fd4e8c1
RK
2661
2662(define_insn ""
2663 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
2664 (compare:CC
cd2b37d9 2665 (and:SI (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
2666 (match_operand:SI 2 "const_int_operand" "i"))
2667 (match_operand:SI 3 "mask_operand" "L"))
2668 (const_int 0)))
2669 (clobber (match_scratch:SI 4 "=r"))]
2670 "includes_rshift_p (operands[2], operands[3])"
ca7f5001 2671 "{rlinm.|rlwinm.} %4,%1,%s2,%m3,%M3"
1fd4e8c1
RK
2672 [(set_attr "type" "delayed_compare")])
2673
2674(define_insn ""
2675 [(set (match_operand:CC 4 "cc_reg_operand" "=x")
2676 (compare:CC
cd2b37d9 2677 (and:SI (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
2678 (match_operand:SI 2 "const_int_operand" "i"))
2679 (match_operand:SI 3 "mask_operand" "L"))
2680 (const_int 0)))
cd2b37d9 2681 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
2682 (and:SI (lshiftrt:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
2683 "includes_rshift_p (operands[2], operands[3])"
ca7f5001 2684 "{rlinm.|rlwinm.} %0,%1,%s2,%m3,%M3"
1fd4e8c1
RK
2685 [(set_attr "type" "delayed_compare")])
2686
2687(define_insn ""
cd2b37d9 2688 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
2689 (zero_extend:SI
2690 (subreg:QI
cd2b37d9 2691 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
2692 (match_operand:SI 2 "const_int_operand" "i")) 0)))]
2693 "includes_rshift_p (operands[2], gen_rtx (CONST_INT, VOIDmode, 255))"
ca7f5001 2694 "{rlinm|rlwinm} %0,%1,%s2,0xff")
1fd4e8c1
RK
2695
2696(define_insn ""
2697 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
2698 (compare:CC
2699 (zero_extend:SI
2700 (subreg:QI
cd2b37d9 2701 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
2702 (match_operand:SI 2 "const_int_operand" "i")) 0))
2703 (const_int 0)))
2704 (clobber (match_scratch:SI 3 "=r"))]
2705 "includes_rshift_p (operands[2], gen_rtx (CONST_INT, VOIDmode, 255))"
ca7f5001 2706 "{rlinm.|rlwinm.} %3,%1,%s2,0xff"
1fd4e8c1
RK
2707 [(set_attr "type" "delayed_compare")])
2708
2709(define_insn ""
2710 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
2711 (compare:CC
2712 (zero_extend:SI
2713 (subreg:QI
cd2b37d9 2714 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
2715 (match_operand:SI 2 "const_int_operand" "i")) 0))
2716 (const_int 0)))
cd2b37d9 2717 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
2718 (zero_extend:SI (subreg:QI (lshiftrt:SI (match_dup 1) (match_dup 2)) 0)))]
2719 "includes_rshift_p (operands[2], gen_rtx (CONST_INT, VOIDmode, 255))"
ca7f5001 2720 "{rlinm.|rlwinm.} %0,%1,%s2,0xff"
1fd4e8c1
RK
2721 [(set_attr "type" "delayed_compare")])
2722
2723(define_insn ""
cd2b37d9 2724 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
2725 (zero_extend:SI
2726 (subreg:HI
cd2b37d9 2727 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
2728 (match_operand:SI 2 "const_int_operand" "i")) 0)))]
2729 "includes_rshift_p (operands[2], gen_rtx (CONST_INT, VOIDmode, 65535))"
ca7f5001 2730 "{rlinm|rlwinm} %0,%1,%s2,0xffff")
1fd4e8c1
RK
2731
2732(define_insn ""
2733 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
2734 (compare:CC
2735 (zero_extend:SI
2736 (subreg:HI
cd2b37d9 2737 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
2738 (match_operand:SI 2 "const_int_operand" "i")) 0))
2739 (const_int 0)))
2740 (clobber (match_scratch:SI 3 "=r"))]
2741 "includes_rshift_p (operands[2], gen_rtx (CONST_INT, VOIDmode, 65535))"
ca7f5001 2742 "{rlinm.|rlwinm.} %3,%1,%s2,0xffff"
1fd4e8c1
RK
2743 [(set_attr "type" "delayed_compare")])
2744
2745(define_insn ""
2746 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
2747 (compare:CC
2748 (zero_extend:SI
2749 (subreg:HI
cd2b37d9 2750 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
2751 (match_operand:SI 2 "const_int_operand" "i")) 0))
2752 (const_int 0)))
cd2b37d9 2753 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
2754 (zero_extend:SI (subreg:HI (lshiftrt:SI (match_dup 1) (match_dup 2)) 0)))]
2755 "includes_rshift_p (operands[2], gen_rtx (CONST_INT, VOIDmode, 65535))"
ca7f5001 2756 "{rlinm.|rlwinm.} %0,%1,%s2,0xffff"
1fd4e8c1
RK
2757 [(set_attr "type" "delayed_compare")])
2758
2759(define_insn ""
cd2b37d9 2760 [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r")
1fd4e8c1 2761 (const_int 1)
cd2b37d9
RK
2762 (match_operand:SI 1 "gpc_reg_operand" "r"))
2763 (ashiftrt:SI (match_operand:SI 2 "gpc_reg_operand" "r")
1fd4e8c1 2764 (const_int 31)))]
ca7f5001 2765 "TARGET_POWER"
1fd4e8c1
RK
2766 "rrib %0,%1,%2")
2767
2768(define_insn ""
cd2b37d9 2769 [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r")
1fd4e8c1 2770 (const_int 1)
cd2b37d9
RK
2771 (match_operand:SI 1 "gpc_reg_operand" "r"))
2772 (lshiftrt:SI (match_operand:SI 2 "gpc_reg_operand" "r")
1fd4e8c1 2773 (const_int 31)))]
ca7f5001 2774 "TARGET_POWER"
1fd4e8c1
RK
2775 "rrib %0,%1,%2")
2776
2777(define_insn ""
cd2b37d9 2778 [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r")
1fd4e8c1 2779 (const_int 1)
cd2b37d9
RK
2780 (match_operand:SI 1 "gpc_reg_operand" "r"))
2781 (zero_extract:SI (match_operand:SI 2 "gpc_reg_operand" "r")
1fd4e8c1
RK
2782 (const_int 1)
2783 (const_int 0)))]
ca7f5001 2784 "TARGET_POWER"
1fd4e8c1
RK
2785 "rrib %0,%1,%2")
2786
ca7f5001
RK
2787(define_expand "ashrsi3"
2788 [(set (match_operand:SI 0 "gpc_reg_operand" "")
2789 (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "")
2790 (match_operand:SI 2 "reg_or_cint_operand" "")))]
2791 ""
2792 "
2793{
2794 if (TARGET_POWER)
2795 emit_insn (gen_ashrsi3_power (operands[0], operands[1], operands[2]));
2796 else
25c341fa 2797 emit_insn (gen_ashrsi3_no_power (operands[0], operands[1], operands[2]));
ca7f5001
RK
2798 DONE;
2799}")
2800
2801(define_insn "ashrsi3_power"
cd2b37d9
RK
2802 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
2803 (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1
RK
2804 (match_operand:SI 2 "reg_or_cint_operand" "r,i")))
2805 (clobber (match_scratch:SI 3 "=q,X"))]
ca7f5001 2806 "TARGET_POWER"
1fd4e8c1
RK
2807 "@
2808 srea %0,%1,%2
ca7f5001
RK
2809 {srai|srawi} %0,%1,%h2")
2810
25c341fa 2811(define_insn "ashrsi3_no_power"
ca7f5001
RK
2812 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2813 (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
2814 (match_operand:SI 2 "reg_or_cint_operand" "ri")))]
25c341fa 2815 "! TARGET_POWER"
d904e9ed 2816 "{sra|sraw}%I2 %0,%1,%h2")
1fd4e8c1
RK
2817
2818(define_insn ""
2819 [(set (match_operand:CC 0 "cc_reg_operand" "=x,x")
cd2b37d9 2820 (compare:CC (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1
RK
2821 (match_operand:SI 2 "reg_or_cint_operand" "r,i"))
2822 (const_int 0)))
2823 (clobber (match_scratch:SI 3 "=r,r"))
2824 (clobber (match_scratch:SI 4 "=q,X"))]
ca7f5001 2825 "TARGET_POWER"
1fd4e8c1
RK
2826 "@
2827 srea. %3,%1,%2
ca7f5001
RK
2828 {srai.|srawi.} %3,%1,%h2"
2829 [(set_attr "type" "delayed_compare")])
2830
2831(define_insn ""
2832 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
2833 (compare:CC (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
2834 (match_operand:SI 2 "reg_or_cint_operand" "ri"))
2835 (const_int 0)))
2836 (clobber (match_scratch:SI 3 "=r"))]
25c341fa 2837 "! TARGET_POWER"
d904e9ed 2838 "{sra|sraw}%I2. %3,%1,%h2"
1fd4e8c1
RK
2839 [(set_attr "type" "delayed_compare")])
2840
2841(define_insn ""
2842 [(set (match_operand:CC 3 "cc_reg_operand" "=x,x")
cd2b37d9 2843 (compare:CC (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1
RK
2844 (match_operand:SI 2 "reg_or_cint_operand" "r,i"))
2845 (const_int 0)))
cd2b37d9 2846 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
1fd4e8c1
RK
2847 (ashiftrt:SI (match_dup 1) (match_dup 2)))
2848 (clobber (match_scratch:SI 4 "=q,X"))]
ca7f5001 2849 "TARGET_POWER"
1fd4e8c1
RK
2850 "@
2851 srea. %0,%1,%2
7f340546 2852 {srai.|srawi.} %0,%1,%h2"
1fd4e8c1
RK
2853 [(set_attr "type" "delayed_compare")])
2854
ca7f5001
RK
2855(define_insn ""
2856 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
2857 (compare:CC (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
2858 (match_operand:SI 2 "reg_or_cint_operand" "ri"))
2859 (const_int 0)))
2860 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
2861 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
25c341fa 2862 "! TARGET_POWER"
d904e9ed 2863 "{sra|sraw}%I2. %0,%1,%h2"
ca7f5001 2864 [(set_attr "type" "delayed_compare")])
1fd4e8c1
RK
2865\f
2866;; Floating-point insns, excluding normal data motion.
2867;;
ca7f5001
RK
2868;; PowerPC has a full set of single-precision floating point instructions.
2869;;
2870;; For the POWER architecture, we pretend that we have both SFmode and
2871;; DFmode insns, while, in fact, all fp insns are actually done in double.
2872;; The only conversions we will do will be when storing to memory. In that
2873;; case, we will use the "frsp" instruction before storing.
1fd4e8c1
RK
2874;;
2875;; Note that when we store into a single-precision memory location, we need to
2876;; use the frsp insn first. If the register being stored isn't dead, we
2877;; need a scratch register for the frsp. But this is difficult when the store
2878;; is done by reload. It is not incorrect to do the frsp on the register in
2879;; this case, we just lose precision that we would have otherwise gotten but
2880;; is not guaranteed. Perhaps this should be tightened up at some point.
2881
e8112008 2882(define_insn "extendsfdf2"
cd2b37d9 2883 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
e8112008 2884 (float_extend:DF (match_operand:SF 1 "gpc_reg_operand" "f")))]
d14a6d05 2885 "TARGET_HARD_FLOAT"
e8112008 2886 "*
5c30aff8 2887{
e8112008
RK
2888 if (REGNO (operands[0]) == REGNO (operands[1]))
2889 return \"\";
2890 else
2891 return \"fmr %0,%1\";
2892}"
2893 [(set_attr "type" "fp")])
1fd4e8c1
RK
2894
2895(define_insn "truncdfsf2"
cd2b37d9
RK
2896 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
2897 (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "f")))]
d14a6d05 2898 "TARGET_HARD_FLOAT"
dcac138d 2899 "frsp %0,%1"
1fd4e8c1
RK
2900 [(set_attr "type" "fp")])
2901
455350f4
RK
2902(define_insn "aux_truncdfsf2"
2903 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
2904 (unspec:SF [(match_operand:SF 1 "gpc_reg_operand" "f")] 0))]
2905 "! TARGET_POWERPC && TARGET_HARD_FLOAT"
2906 "frsp %0,%1"
2907 [(set_attr "type" "fp")])
2908
1fd4e8c1 2909(define_insn "negsf2"
cd2b37d9
RK
2910 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
2911 (neg:SF (match_operand:SF 1 "gpc_reg_operand" "f")))]
d14a6d05 2912 "TARGET_HARD_FLOAT"
1fd4e8c1
RK
2913 "fneg %0,%1"
2914 [(set_attr "type" "fp")])
2915
2916(define_insn "abssf2"
cd2b37d9
RK
2917 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
2918 (abs:SF (match_operand:SF 1 "gpc_reg_operand" "f")))]
d14a6d05 2919 "TARGET_HARD_FLOAT"
1fd4e8c1
RK
2920 "fabs %0,%1"
2921 [(set_attr "type" "fp")])
2922
2923(define_insn ""
cd2b37d9
RK
2924 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
2925 (neg:SF (abs:SF (match_operand:SF 1 "gpc_reg_operand" "f"))))]
d14a6d05 2926 "TARGET_HARD_FLOAT"
1fd4e8c1
RK
2927 "fnabs %0,%1"
2928 [(set_attr "type" "fp")])
2929
ca7f5001
RK
2930(define_expand "addsf3"
2931 [(set (match_operand:SF 0 "gpc_reg_operand" "")
2932 (plus:SF (match_operand:SF 1 "gpc_reg_operand" "")
2933 (match_operand:SF 2 "gpc_reg_operand" "")))]
d14a6d05 2934 "TARGET_HARD_FLOAT"
ca7f5001
RK
2935 "")
2936
2937(define_insn ""
cd2b37d9
RK
2938 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
2939 (plus: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 "fadds %0,%1,%2"
ca7f5001
RK
2943 [(set_attr "type" "fp")])
2944
2945(define_insn ""
2946 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
2947 (plus:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
2948 (match_operand:SF 2 "gpc_reg_operand" "f")))]
d14a6d05 2949 "! TARGET_POWERPC && TARGET_HARD_FLOAT"
b26c8351 2950 "{fa|fadd} %0,%1,%2"
ca7f5001
RK
2951 [(set_attr "type" "fp")])
2952
2953(define_expand "subsf3"
2954 [(set (match_operand:SF 0 "gpc_reg_operand" "")
2955 (minus:SF (match_operand:SF 1 "gpc_reg_operand" "")
2956 (match_operand:SF 2 "gpc_reg_operand" "")))]
d14a6d05 2957 "TARGET_HARD_FLOAT"
ca7f5001
RK
2958 "")
2959
2960(define_insn ""
2961 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
2962 (minus:SF (match_operand:SF 1 "gpc_reg_operand" "f")
2963 (match_operand:SF 2 "gpc_reg_operand" "f")))]
d14a6d05 2964 "TARGET_POWERPC && TARGET_HARD_FLOAT"
b26c8351 2965 "fsubs %0,%1,%2"
1fd4e8c1
RK
2966 [(set_attr "type" "fp")])
2967
ca7f5001 2968(define_insn ""
cd2b37d9
RK
2969 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
2970 (minus:SF (match_operand:SF 1 "gpc_reg_operand" "f")
2971 (match_operand:SF 2 "gpc_reg_operand" "f")))]
d14a6d05 2972 "! TARGET_POWERPC && TARGET_HARD_FLOAT"
b26c8351 2973 "{fs|fsub} %0,%1,%2"
ca7f5001
RK
2974 [(set_attr "type" "fp")])
2975
2976(define_expand "mulsf3"
2977 [(set (match_operand:SF 0 "gpc_reg_operand" "")
2978 (mult:SF (match_operand:SF 1 "gpc_reg_operand" "")
2979 (match_operand:SF 2 "gpc_reg_operand" "")))]
d14a6d05 2980 "TARGET_HARD_FLOAT"
ca7f5001
RK
2981 "")
2982
2983(define_insn ""
2984 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
2985 (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
2986 (match_operand:SF 2 "gpc_reg_operand" "f")))]
d14a6d05 2987 "TARGET_POWERPC && TARGET_HARD_FLOAT"
b26c8351 2988 "fmuls %0,%1,%2"
1fd4e8c1
RK
2989 [(set_attr "type" "fp")])
2990
ca7f5001 2991(define_insn ""
cd2b37d9
RK
2992 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
2993 (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
2994 (match_operand:SF 2 "gpc_reg_operand" "f")))]
d14a6d05 2995 "! TARGET_POWERPC && TARGET_HARD_FLOAT"
b26c8351 2996 "{fm|fmul} %0,%1,%2"
0780f386 2997 [(set_attr "type" "dmul")])
1fd4e8c1 2998
ca7f5001
RK
2999(define_expand "divsf3"
3000 [(set (match_operand:SF 0 "gpc_reg_operand" "")
3001 (div:SF (match_operand:SF 1 "gpc_reg_operand" "")
3002 (match_operand:SF 2 "gpc_reg_operand" "")))]
d14a6d05 3003 "TARGET_HARD_FLOAT"
ca7f5001
RK
3004 "")
3005
3006(define_insn ""
cd2b37d9
RK
3007 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
3008 (div:SF (match_operand:SF 1 "gpc_reg_operand" "f")
3009 (match_operand:SF 2 "gpc_reg_operand" "f")))]
d14a6d05 3010 "TARGET_POWERPC && TARGET_HARD_FLOAT"
b26c8351 3011 "fdivs %0,%1,%2"
ca7f5001
RK
3012 [(set_attr "type" "sdiv")])
3013
3014(define_insn ""
3015 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
3016 (div:SF (match_operand:SF 1 "gpc_reg_operand" "f")
3017 (match_operand:SF 2 "gpc_reg_operand" "f")))]
d14a6d05 3018 "! TARGET_POWERPC && TARGET_HARD_FLOAT"
b26c8351 3019 "{fd|fdiv} %0,%1,%2"
0780f386 3020 [(set_attr "type" "ddiv")])
1fd4e8c1
RK
3021
3022(define_insn ""
cd2b37d9
RK
3023 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
3024 (plus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
3025 (match_operand:SF 2 "gpc_reg_operand" "f"))
3026 (match_operand:SF 3 "gpc_reg_operand" "f")))]
d14a6d05 3027 "TARGET_POWERPC && TARGET_HARD_FLOAT"
b26c8351 3028 "fmadds %0,%1,%2,%3"
ca7f5001
RK
3029 [(set_attr "type" "fp")])
3030
3031(define_insn ""
3032 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
3033 (plus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
3034 (match_operand:SF 2 "gpc_reg_operand" "f"))
3035 (match_operand:SF 3 "gpc_reg_operand" "f")))]
d14a6d05 3036 "! TARGET_POWERPC && TARGET_HARD_FLOAT"
b26c8351 3037 "{fma|fmadd} %0,%1,%2,%3"
cf27b467 3038 [(set_attr "type" "dmul")])
1fd4e8c1
RK
3039
3040(define_insn ""
cd2b37d9
RK
3041 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
3042 (minus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
3043 (match_operand:SF 2 "gpc_reg_operand" "f"))
3044 (match_operand:SF 3 "gpc_reg_operand" "f")))]
d14a6d05 3045 "TARGET_POWERPC && TARGET_HARD_FLOAT"
b26c8351 3046 "fmsubs %0,%1,%2,%3"
ca7f5001
RK
3047 [(set_attr "type" "fp")])
3048
3049(define_insn ""
3050 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
3051 (minus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
3052 (match_operand:SF 2 "gpc_reg_operand" "f"))
3053 (match_operand:SF 3 "gpc_reg_operand" "f")))]
d14a6d05 3054 "! TARGET_POWERPC && TARGET_HARD_FLOAT"
b26c8351 3055 "{fms|fmsub} %0,%1,%2,%3"
cf27b467 3056 [(set_attr "type" "dmul")])
1fd4e8c1
RK
3057
3058(define_insn ""
cd2b37d9
RK
3059 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
3060 (neg:SF (plus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
3061 (match_operand:SF 2 "gpc_reg_operand" "f"))
3062 (match_operand:SF 3 "gpc_reg_operand" "f"))))]
d14a6d05 3063 "TARGET_POWERPC && TARGET_HARD_FLOAT"
b26c8351 3064 "fnmadds %0,%1,%2,%3"
ca7f5001
RK
3065 [(set_attr "type" "fp")])
3066
3067(define_insn ""
3068 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
3069 (neg:SF (plus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
3070 (match_operand:SF 2 "gpc_reg_operand" "f"))
3071 (match_operand:SF 3 "gpc_reg_operand" "f"))))]
d14a6d05 3072 "! TARGET_POWERPC && TARGET_HARD_FLOAT"
b26c8351 3073 "{fnma|fnmadd} %0,%1,%2,%3"
cf27b467 3074 [(set_attr "type" "dmul")])
1fd4e8c1
RK
3075
3076(define_insn ""
cd2b37d9
RK
3077 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
3078 (neg:SF (minus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
3079 (match_operand:SF 2 "gpc_reg_operand" "f"))
3080 (match_operand:SF 3 "gpc_reg_operand" "f"))))]
d14a6d05 3081 "TARGET_POWERPC && TARGET_HARD_FLOAT"
b26c8351 3082 "fnmsubs %0,%1,%2,%3"
ca7f5001
RK
3083 [(set_attr "type" "fp")])
3084
3085(define_insn ""
3086 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
3087 (neg:SF (minus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
3088 (match_operand:SF 2 "gpc_reg_operand" "f"))
3089 (match_operand:SF 3 "gpc_reg_operand" "f"))))]
d14a6d05 3090 "! TARGET_POWERPC && TARGET_HARD_FLOAT"
b26c8351 3091 "{fnms|fnmsub} %0,%1,%2,%3"
cf27b467 3092 [(set_attr "type" "dmul")])
1fd4e8c1 3093
ca7f5001
RK
3094(define_expand "sqrtsf2"
3095 [(set (match_operand:SF 0 "gpc_reg_operand" "")
3096 (sqrt:SF (match_operand:SF 1 "gpc_reg_operand" "")))]
d14a6d05 3097 "(TARGET_PPC_GPOPT || TARGET_POWER2) && TARGET_HARD_FLOAT"
ca7f5001
RK
3098 "")
3099
3100(define_insn ""
3101 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
3102 (sqrt:SF (match_operand:SF 1 "gpc_reg_operand" "f")))]
d14a6d05 3103 "TARGET_PPC_GPOPT && TARGET_HARD_FLOAT"
ca7f5001
RK
3104 "fsqrts %0,%1"
3105 [(set_attr "type" "ssqrt")])
3106
3107(define_insn ""
3108 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
3109 (sqrt:SF (match_operand:SF 1 "gpc_reg_operand" "f")))]
d14a6d05 3110 "TARGET_POWER2 && TARGET_HARD_FLOAT"
ca7f5001
RK
3111 "fsqrt %0,%1"
3112 [(set_attr "type" "dsqrt")])
3113
94d7001a
RK
3114;; For MIN, MAX, and conditional move, we use DEFINE_EXPAND's that involve a
3115;; fsel instruction and some auxiliary computations. Then we just have a
3116;; single DEFINE_INSN for fsel and the define_splits to make them if made by
8e871c05
RK
3117;; combine.
3118(define_expand "maxsf3"
3119 [(set (match_dup 3)
3120 (minus:SF (match_operand:SF 1 "gpc_reg_operand" "")
3121 (match_operand:SF 2 "gpc_reg_operand" "")))
3122 (set (match_operand:SF 0 "gpc_reg_operand" "")
3123 (if_then_else:SF (ge (match_dup 3)
3124 (const_int 0))
3125 (match_dup 1)
3126 (match_dup 2)))]
d14a6d05 3127 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT"
8e871c05
RK
3128 "
3129{ operands[3] = gen_reg_rtx (SFmode); }")
2f607b94 3130
8e871c05
RK
3131(define_split
3132 [(set (match_operand:SF 0 "gpc_reg_operand" "")
3133 (smax:SF (match_operand:SF 1 "gpc_reg_operand" "")
f63184ac 3134 (match_operand:SF 2 "gpc_reg_operand" "")))
8e871c05 3135 (clobber (match_operand:SF 3 "gpc_reg_operand" ""))]
d14a6d05 3136 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT"
8e871c05
RK
3137 [(set (match_dup 3)
3138 (minus:SF (match_dup 1) (match_dup 2)))
a81bd72f 3139 (set (match_dup 0)
8e871c05
RK
3140 (if_then_else:SF (ge (match_dup 3)
3141 (const_int 0))
3142 (match_dup 1)
3143 (match_dup 2)))]
3144 "")
2f607b94 3145
8e871c05
RK
3146(define_expand "minsf3"
3147 [(set (match_dup 3)
3148 (minus:SF (match_operand:SF 2 "gpc_reg_operand" "")
3149 (match_operand:SF 1 "gpc_reg_operand" "")))
3150 (set (match_operand:SF 0 "gpc_reg_operand" "")
3151 (if_then_else:SF (ge (match_dup 3)
3152 (const_int 0))
3153 (match_dup 1)
3154 (match_dup 2)))]
d14a6d05 3155 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT"
8e871c05
RK
3156 "
3157{ operands[3] = gen_reg_rtx (SFmode); }")
2f607b94 3158
8e871c05
RK
3159(define_split
3160 [(set (match_operand:SF 0 "gpc_reg_operand" "")
3161 (smin:SF (match_operand:SF 1 "gpc_reg_operand" "")
f63184ac 3162 (match_operand:SF 2 "gpc_reg_operand" "")))
8e871c05 3163 (clobber (match_operand:SF 3 "gpc_reg_operand" ""))]
d14a6d05 3164 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT"
8e871c05
RK
3165 [(set (match_dup 3)
3166 (minus:SF (match_dup 2) (match_dup 1)))
a81bd72f 3167 (set (match_dup 0)
8e871c05
RK
3168 (if_then_else:SF (ge (match_dup 3)
3169 (const_int 0))
3170 (match_dup 1)
3171 (match_dup 2)))]
3172 "")
2f607b94 3173
94d7001a
RK
3174(define_expand "movsfcc"
3175 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
3176 (if_then_else:SF (match_operand 1 "comparison_operator" "")
3177 (match_operand:SF 2 "gpc_reg_operand" "f")
3178 (match_operand:SF 3 "gpc_reg_operand" "f")))]
d14a6d05 3179 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT"
94d7001a
RK
3180 "
3181{
3182 rtx temp, op0, op1;
3183 enum rtx_code code = GET_CODE (operands[1]);
3184 if (! rs6000_compare_fp_p)
3185 FAIL;
3186 switch (code)
3187 {
3188 case GE: case EQ: case NE:
3189 op0 = rs6000_compare_op0;
3190 op1 = rs6000_compare_op1;
3191 break;
3192 case GT:
3193 op0 = rs6000_compare_op1;
3194 op1 = rs6000_compare_op0;
3195 temp = operands[2]; operands[2] = operands[3]; operands[3] = temp;
3196 break;
3197 case LE:
3198 op0 = rs6000_compare_op1;
3199 op1 = rs6000_compare_op0;
3200 break;
3201 case LT:
3202 op0 = rs6000_compare_op0;
3203 op1 = rs6000_compare_op1;
3204 temp = operands[2]; operands[2] = operands[3]; operands[3] = temp;
3205 break;
3206 default:
3207 FAIL;
3208 }
3209 if (GET_MODE (rs6000_compare_op0) == DFmode)
3210 {
3211 temp = gen_reg_rtx (DFmode);
3212 emit_insn (gen_subdf3 (temp, op0, op1));
3213 emit_insn (gen_fseldfsf4 (operands[0], temp, operands[2], operands[3]));
3214 if (code == EQ)
3215 {
3216 emit_insn (gen_negdf2 (temp, temp));
3217 emit_insn (gen_fseldfsf4 (operands[0], temp, operands[0], operands[3]));
3218 }
3219 if (code == NE)
3220 {
3221 emit_insn (gen_negdf2 (temp, temp));
3222 emit_insn (gen_fseldfsf4 (operands[0], temp, operands[3], operands[0]));
3223 }
3224 }
3225 else
3226 {
3227 temp = gen_reg_rtx (SFmode);
3228 emit_insn (gen_subsf3 (temp, op0, op1));
3229 emit_insn (gen_fselsfsf4 (operands[0], temp, operands[2], operands[3]));
3230 if (code == EQ)
3231 {
3232 emit_insn (gen_negsf2 (temp, temp));
3233 emit_insn (gen_fselsfsf4 (operands[0], temp, operands[0], operands[3]));
3234 }
3235 if (code == NE)
3236 {
3237 emit_insn (gen_negsf2 (temp, temp));
3238 emit_insn (gen_fselsfsf4 (operands[0], temp, operands[3], operands[0]));
3239 }
3240 }
3241 DONE;
3242}")
d56d506a 3243
94d7001a 3244(define_insn "fselsfsf4"
8e871c05
RK
3245 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
3246 (if_then_else:SF (ge (match_operand:SF 1 "gpc_reg_operand" "f")
3247 (const_int 0))
3248 (match_operand:SF 2 "gpc_reg_operand" "f")
3249 (match_operand:SF 3 "gpc_reg_operand" "f")))]
d14a6d05 3250 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT"
8e871c05
RK
3251 "fsel %0,%1,%2,%3"
3252 [(set_attr "type" "fp")])
2f607b94 3253
94d7001a
RK
3254(define_insn "fseldfsf4"
3255 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
3256 (if_then_else:SF (ge (match_operand:DF 1 "gpc_reg_operand" "f")
3257 (const_int 0))
3258 (match_operand:SF 2 "gpc_reg_operand" "f")
3259 (match_operand:SF 3 "gpc_reg_operand" "f")))]
d14a6d05 3260 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT"
94d7001a
RK
3261 "fsel %0,%1,%2,%3"
3262 [(set_attr "type" "fp")])
d56d506a 3263
1fd4e8c1 3264(define_insn "negdf2"
cd2b37d9
RK
3265 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
3266 (neg:DF (match_operand:DF 1 "gpc_reg_operand" "f")))]
d14a6d05 3267 "TARGET_HARD_FLOAT"
1fd4e8c1
RK
3268 "fneg %0,%1"
3269 [(set_attr "type" "fp")])
3270
3271(define_insn "absdf2"
cd2b37d9
RK
3272 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
3273 (abs:DF (match_operand:DF 1 "gpc_reg_operand" "f")))]
d14a6d05 3274 "TARGET_HARD_FLOAT"
1fd4e8c1
RK
3275 "fabs %0,%1"
3276 [(set_attr "type" "fp")])
3277
3278(define_insn ""
cd2b37d9
RK
3279 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
3280 (neg:DF (abs:DF (match_operand:DF 1 "gpc_reg_operand" "f"))))]
d14a6d05 3281 "TARGET_HARD_FLOAT"
1fd4e8c1
RK
3282 "fnabs %0,%1"
3283 [(set_attr "type" "fp")])
3284
3285(define_insn "adddf3"
cd2b37d9
RK
3286 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
3287 (plus:DF (match_operand:DF 1 "gpc_reg_operand" "%f")
3288 (match_operand:DF 2 "gpc_reg_operand" "f")))]
d14a6d05 3289 "TARGET_HARD_FLOAT"
ca7f5001 3290 "{fa|fadd} %0,%1,%2"
1fd4e8c1
RK
3291 [(set_attr "type" "fp")])
3292
3293(define_insn "subdf3"
cd2b37d9
RK
3294 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
3295 (minus:DF (match_operand:DF 1 "gpc_reg_operand" "f")
3296 (match_operand:DF 2 "gpc_reg_operand" "f")))]
d14a6d05 3297 "TARGET_HARD_FLOAT"
ca7f5001 3298 "{fs|fsub} %0,%1,%2"
1fd4e8c1
RK
3299 [(set_attr "type" "fp")])
3300
3301(define_insn "muldf3"
cd2b37d9
RK
3302 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
3303 (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%f")
3304 (match_operand:DF 2 "gpc_reg_operand" "f")))]
d14a6d05 3305 "TARGET_HARD_FLOAT"
ca7f5001 3306 "{fm|fmul} %0,%1,%2"
cfb557c4 3307 [(set_attr "type" "dmul")])
1fd4e8c1
RK
3308
3309(define_insn "divdf3"
cd2b37d9
RK
3310 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
3311 (div:DF (match_operand:DF 1 "gpc_reg_operand" "f")
3312 (match_operand:DF 2 "gpc_reg_operand" "f")))]
d14a6d05 3313 "TARGET_HARD_FLOAT"
ca7f5001 3314 "{fd|fdiv} %0,%1,%2"
cfb557c4 3315 [(set_attr "type" "ddiv")])
1fd4e8c1
RK
3316
3317(define_insn ""
cd2b37d9
RK
3318 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
3319 (plus:DF (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%f")
3320 (match_operand:DF 2 "gpc_reg_operand" "f"))
3321 (match_operand:DF 3 "gpc_reg_operand" "f")))]
d14a6d05 3322 "TARGET_HARD_FLOAT"
ca7f5001 3323 "{fma|fmadd} %0,%1,%2,%3"
cfb557c4 3324 [(set_attr "type" "dmul")])
1fd4e8c1
RK
3325
3326(define_insn ""
cd2b37d9
RK
3327 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
3328 (minus:DF (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%f")
3329 (match_operand:DF 2 "gpc_reg_operand" "f"))
3330 (match_operand:DF 3 "gpc_reg_operand" "f")))]
d14a6d05 3331 "TARGET_HARD_FLOAT"
ca7f5001 3332 "{fms|fmsub} %0,%1,%2,%3"
cfb557c4 3333 [(set_attr "type" "dmul")])
1fd4e8c1
RK
3334
3335(define_insn ""
cd2b37d9
RK
3336 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
3337 (neg:DF (plus:DF (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%f")
3338 (match_operand:DF 2 "gpc_reg_operand" "f"))
3339 (match_operand:DF 3 "gpc_reg_operand" "f"))))]
d14a6d05 3340 "TARGET_HARD_FLOAT"
ca7f5001 3341 "{fnma|fnmadd} %0,%1,%2,%3"
cfb557c4 3342 [(set_attr "type" "dmul")])
1fd4e8c1
RK
3343
3344(define_insn ""
cd2b37d9
RK
3345 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
3346 (neg:DF (minus:DF (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%f")
3347 (match_operand:DF 2 "gpc_reg_operand" "f"))
3348 (match_operand:DF 3 "gpc_reg_operand" "f"))))]
d14a6d05 3349 "TARGET_HARD_FLOAT"
ca7f5001 3350 "{fnms|fnmsub} %0,%1,%2,%3"
cfb557c4 3351 [(set_attr "type" "dmul")])
ca7f5001
RK
3352
3353(define_insn "sqrtdf2"
3354 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
3355 (sqrt:DF (match_operand:DF 1 "gpc_reg_operand" "f")))]
d14a6d05 3356 "(TARGET_PPC_GPOPT || TARGET_POWER2) && TARGET_HARD_FLOAT"
ca7f5001
RK
3357 "fsqrt %0,%1"
3358 [(set_attr "type" "dsqrt")])
b77dfefc 3359
94d7001a
RK
3360;; For MIN, MAX, and conditional move, we use DEFINE_EXPAND's that involve a
3361;; fsel instruction and some auxiliary computations. Then we just have a
3362;; single DEFINE_INSN for fsel and the define_splits to make them if made by
8e871c05 3363;; combine.
b77dfefc 3364
8e871c05
RK
3365(define_expand "maxdf3"
3366 [(set (match_dup 3)
3367 (minus:DF (match_operand:DF 1 "gpc_reg_operand" "")
3368 (match_operand:DF 2 "gpc_reg_operand" "")))
3369 (set (match_operand:DF 0 "gpc_reg_operand" "")
3370 (if_then_else:DF (ge (match_dup 3)
3371 (const_int 0))
3372 (match_dup 1)
3373 (match_dup 2)))]
d14a6d05 3374 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT"
8e871c05
RK
3375 "
3376{ operands[3] = gen_reg_rtx (DFmode); }")
b77dfefc 3377
8e871c05
RK
3378(define_split
3379 [(set (match_operand:DF 0 "gpc_reg_operand" "")
3380 (smax:DF (match_operand:DF 1 "gpc_reg_operand" "")
f63184ac 3381 (match_operand:DF 2 "gpc_reg_operand" "")))
8e871c05 3382 (clobber (match_operand:DF 3 "gpc_reg_operand" ""))]
d14a6d05 3383 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT"
8e871c05
RK
3384 [(set (match_dup 3)
3385 (minus:DF (match_dup 1) (match_dup 2)))
a81bd72f 3386 (set (match_dup 0)
8e871c05
RK
3387 (if_then_else:DF (ge (match_dup 3)
3388 (const_int 0))
3389 (match_dup 1)
3390 (match_dup 2)))]
3391 "")
b77dfefc 3392
8e871c05
RK
3393(define_expand "mindf3"
3394 [(set (match_dup 3)
3395 (minus:DF (match_operand:DF 2 "gpc_reg_operand" "")
3396 (match_operand:DF 1 "gpc_reg_operand" "")))
3397 (set (match_operand:DF 0 "gpc_reg_operand" "")
3398 (if_then_else:DF (ge (match_dup 3)
3399 (const_int 0))
3400 (match_dup 1)
3401 (match_dup 2)))]
d14a6d05 3402 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT"
8e871c05
RK
3403 "
3404{ operands[3] = gen_reg_rtx (DFmode); }")
b77dfefc 3405
8e871c05
RK
3406(define_split
3407 [(set (match_operand:DF 0 "gpc_reg_operand" "")
3408 (smin:DF (match_operand:DF 1 "gpc_reg_operand" "")
f63184ac 3409 (match_operand:DF 2 "gpc_reg_operand" "")))
8e871c05 3410 (clobber (match_operand:DF 3 "gpc_reg_operand" ""))]
d14a6d05 3411 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT"
8e871c05
RK
3412 [(set (match_dup 3)
3413 (minus:DF (match_dup 2) (match_dup 1)))
a81bd72f 3414 (set (match_dup 0)
8e871c05
RK
3415 (if_then_else:DF (ge (match_dup 3)
3416 (const_int 0))
3417 (match_dup 1)
3418 (match_dup 2)))]
3419 "")
b77dfefc 3420
94d7001a
RK
3421(define_expand "movdfcc"
3422 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
3423 (if_then_else:DF (match_operand 1 "comparison_operator" "")
3424 (match_operand:DF 2 "gpc_reg_operand" "f")
3425 (match_operand:DF 3 "gpc_reg_operand" "f")))]
d14a6d05 3426 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT"
94d7001a
RK
3427 "
3428{
3429 rtx temp, op0, op1;
3430 enum rtx_code code = GET_CODE (operands[1]);
3431 if (! rs6000_compare_fp_p)
3432 FAIL;
3433 switch (code)
3434 {
3435 case GE: case EQ: case NE:
3436 op0 = rs6000_compare_op0;
3437 op1 = rs6000_compare_op1;
3438 break;
3439 case GT:
3440 op0 = rs6000_compare_op1;
3441 op1 = rs6000_compare_op0;
3442 temp = operands[2]; operands[2] = operands[3]; operands[3] = temp;
3443 break;
3444 case LE:
3445 op0 = rs6000_compare_op1;
3446 op1 = rs6000_compare_op0;
3447 break;
3448 case LT:
3449 op0 = rs6000_compare_op0;
3450 op1 = rs6000_compare_op1;
3451 temp = operands[2]; operands[2] = operands[3]; operands[3] = temp;
3452 break;
3453 default:
3454 FAIL;
3455 }
3456 if (GET_MODE (rs6000_compare_op0) == DFmode)
3457 {
3458 temp = gen_reg_rtx (DFmode);
3459 emit_insn (gen_subdf3 (temp, op0, op1));
3460 emit_insn (gen_fseldfdf4 (operands[0], temp, operands[2], operands[3]));
3461 if (code == EQ)
3462 {
3463 emit_insn (gen_negdf2 (temp, temp));
3464 emit_insn (gen_fseldfdf4 (operands[0], temp, operands[0], operands[3]));
3465 }
3466 if (code == NE)
3467 {
3468 emit_insn (gen_negdf2 (temp, temp));
3469 emit_insn (gen_fseldfdf4 (operands[0], temp, operands[3], operands[0]));
3470 }
3471 }
3472 else
3473 {
3474 temp = gen_reg_rtx (SFmode);
3475 emit_insn (gen_subsf3 (temp, op0, op1));
3476 emit_insn (gen_fselsfdf4 (operands[0], temp, operands[2], operands[3]));
3477 if (code == EQ)
3478 {
3479 emit_insn (gen_negsf2 (temp, temp));
3480 emit_insn (gen_fselsfdf4 (operands[0], temp, operands[0], operands[3]));
3481 }
3482 if (code == NE)
3483 {
3484 emit_insn (gen_negsf2 (temp, temp));
3485 emit_insn (gen_fselsfdf4 (operands[0], temp, operands[3], operands[0]));
3486 }
3487 }
3488 DONE;
3489}")
d56d506a 3490
94d7001a 3491(define_insn "fseldfdf4"
8e871c05
RK
3492 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
3493 (if_then_else:DF (ge (match_operand:DF 1 "gpc_reg_operand" "f")
3494 (const_int 0))
3495 (match_operand:DF 2 "gpc_reg_operand" "f")
3496 (match_operand:DF 3 "gpc_reg_operand" "f")))]
d14a6d05 3497 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT"
8e871c05
RK
3498 "fsel %0,%1,%2,%3"
3499 [(set_attr "type" "fp")])
d56d506a 3500
94d7001a
RK
3501(define_insn "fselsfdf4"
3502 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
3503 (if_then_else:DF (ge (match_operand:SF 1 "gpc_reg_operand" "f")
3504 (const_int 0))
3505 (match_operand:DF 2 "gpc_reg_operand" "f")
3506 (match_operand:DF 3 "gpc_reg_operand" "f")))]
3507 "TARGET_PPC_GFXOPT"
3508 "fsel %0,%1,%2,%3"
3509 [(set_attr "type" "fp")])
1fd4e8c1
RK
3510\f
3511;; Conversions to and from floating-point.
3512(define_expand "floatsidf2"
dbe3df29
RK
3513 [(set (match_operand:DF 0 "gpc_reg_operand" "")
3514 (float:DF (match_operand:SI 1 "gpc_reg_operand" "")))]
dc4f83ca 3515 "! TARGET_POWERPC64 && TARGET_HARD_FLOAT"
1fd4e8c1
RK
3516 "
3517{
dbe3df29
RK
3518 if (operands[0])
3519 { /* prevent unused warning messages */
3520 rtx high = force_reg (SImode, GEN_INT (0x43300000));
3521 rtx low = gen_reg_rtx (SImode);
3522 rtx df = gen_reg_rtx (DFmode);
3523 rtx adjust = force_reg (DFmode, rs6000_float_const (\"4503601774854144\", DFmode));
3524
3525 emit_insn (gen_xorsi3 (low, operands[1], GEN_INT (0x80000000)));
3526 emit_insn (gen_move_to_float (df, low, high));
3527 emit_insn (gen_subdf3 (operands[0], df, adjust));
3528 DONE;
3529 }
1fd4e8c1
RK
3530}")
3531
3532(define_expand "floatunssidf2"
dbe3df29
RK
3533 [(set (match_operand:DF 0 "gpc_reg_operand" "")
3534 (unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" "")))]
dc4f83ca 3535 "! TARGET_POWERPC64 && TARGET_HARD_FLOAT"
1fd4e8c1
RK
3536 "
3537{
dbe3df29
RK
3538 if (operands[0])
3539 { /* prevent unused warning messages */
3540 rtx high = force_reg (SImode, GEN_INT (0x43300000));
3541 rtx df = gen_reg_rtx (DFmode);
3542 rtx adjust = force_reg (DFmode, rs6000_float_const (\"4503599627370496\", DFmode));
3543
3544 emit_insn (gen_move_to_float (df, operands[1], high));
3545 emit_insn (gen_subdf3 (operands[0], df, adjust));
3546 DONE;
3547 }
1fd4e8c1
RK
3548}")
3549
dbe3df29 3550(define_expand "move_to_float"
d904e9ed
RK
3551 [(set (match_operand:DF 0 "gpc_reg_operand" "")
3552 (unspec [(match_operand:SI 1 "gpc_reg_operand" "")
3553 (match_operand:SI 2 "gpc_reg_operand" "")
3554 (match_dup 3)] 2))]
dbe3df29 3555 "! TARGET_POWERPC64 && TARGET_HARD_FLOAT"
1fd4e8c1 3556 "
dbe3df29 3557{
d904e9ed 3558 operands[3] = XEXP (rs6000_stack_temp (DFmode, 8, 1), 0);
dbe3df29 3559}")
7e69e155 3560
1fd4e8c1 3561(define_split
dbe3df29
RK
3562 [(set (match_operand:DF 0 "gpc_reg_operand" "")
3563 (unspec [(match_operand:SI 1 "gpc_reg_operand" "")
d904e9ed
RK
3564 (match_operand:SI 2 "gpc_reg_operand" "")
3565 (match_operand:SI 3 "offsettable_addr_operand" "")] 2))]
7a96832a 3566 "reload_completed"
dbe3df29
RK
3567 [(set (match_dup 4) (match_dup 1))
3568 (set (match_dup 5) (match_dup 2))
d904e9ed 3569 (set (match_dup 0) (mem:DF (match_dup 3)))]
1fd4e8c1 3570 "
dbe3df29 3571{
d904e9ed
RK
3572 rtx word1 = gen_rtx (MEM, SImode, operands[3]);
3573 rtx word2 = gen_rtx (MEM, SImode, plus_constant (operands[3], 4));
3574
3575 MEM_IN_STRUCT_P (word1) = 1;
3576 MEM_IN_STRUCT_P (word2) = 1;
c283c989 3577
d904e9ed
RK
3578 if (WORDS_BIG_ENDIAN)
3579 {
3580 operands[4] = word2;
3581 operands[5] = word1;
3582 }
3583 else
3584 {
3585 operands[4] = word1;
3586 operands[5] = word2;
3587 }
1fd4e8c1
RK
3588}")
3589
3590(define_insn ""
dbe3df29
RK
3591 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
3592 (unspec [(match_operand:SI 1 "gpc_reg_operand" "r")
d904e9ed
RK
3593 (match_operand:SI 2 "gpc_reg_operand" "r")
3594 (match_operand:SI 3 "offsettable_addr_operand" "p")] 2))]
dbe3df29 3595 "! TARGET_POWERPC64 && TARGET_HARD_FLOAT"
baf97f86 3596 "#"
dbe3df29 3597 [(set_attr "length" "12")])
1fd4e8c1
RK
3598
3599(define_expand "fix_truncdfsi2"
cd2b37d9 3600 [(set (match_operand:SI 0 "gpc_reg_operand" "")
b542afe9 3601 (fix:SI (match_operand:DF 1 "gpc_reg_operand" "")))]
d14a6d05 3602 "TARGET_HARD_FLOAT"
1fd4e8c1
RK
3603 "
3604{
8ffd9c51
RK
3605 if (TARGET_POWER2 || TARGET_POWERPC)
3606 {
d904e9ed 3607 rtx stack_slot = rs6000_stack_temp (DImode, 8, 1);
dbe3df29 3608 rtx temp = gen_reg_rtx (DImode);
425c176f 3609
8ffd9c51 3610 emit_insn (gen_fpcvtsi (temp, operands[1]));
8ffd9c51
RK
3611 emit_move_insn (stack_slot, temp);
3612 emit_move_insn (operands[0],
e8d791dd 3613 gen_rtx (SUBREG, SImode, stack_slot, WORDS_BIG_ENDIAN));
8ffd9c51
RK
3614 DONE;
3615 }
3616 else
3617 {
3618 emit_insn (gen_trunc_call (operands[0], operands[1],
3619 gen_rtx (SYMBOL_REF, Pmode, RS6000_ITRUNC)));
3620 DONE;
3621 }
1fd4e8c1
RK
3622}")
3623
8ffd9c51
RK
3624(define_insn "fpcvtsi"
3625 [(set (match_operand:DI 0 "gpc_reg_operand" "=f")
3626 (sign_extend:DI
3627 (fix:SI (match_operand:DF 1 "gpc_reg_operand" "f"))))]
d14a6d05 3628 "(TARGET_POWER2 || TARGET_POWERPC) && TARGET_HARD_FLOAT"
8ffd9c51
RK
3629 "{fcirz|fctiwz} %0,%1"
3630 [(set_attr "type" "fp")])
deb9225a 3631
1fd4e8c1 3632(define_expand "fixuns_truncdfsi2"
cd2b37d9 3633 [(set (match_operand:SI 0 "gpc_reg_operand" "")
b542afe9 3634 (unsigned_fix:SI (match_operand:DF 1 "gpc_reg_operand" "")))]
d14a6d05 3635 "! TARGET_POWER2 && ! TARGET_POWERPC && TARGET_HARD_FLOAT"
1fd4e8c1
RK
3636 "
3637{
3638 emit_insn (gen_trunc_call (operands[0], operands[1],
3c64f04b 3639 gen_rtx (SYMBOL_REF, Pmode, RS6000_UITRUNC)));
1fd4e8c1
RK
3640 DONE;
3641}")
3642
1fd4e8c1
RK
3643(define_expand "trunc_call"
3644 [(parallel [(set (match_operand:SI 0 "" "")
b542afe9 3645 (fix:SI (match_operand:DF 1 "" "")))
1fd4e8c1 3646 (use (match_operand:SI 2 "" ""))])]
d14a6d05 3647 "TARGET_HARD_FLOAT"
1fd4e8c1
RK
3648 "
3649{
3650 rtx insns = gen_trunc_call_rtl (operands[0], operands[1], operands[2]);
3651 rtx first = XVECEXP (insns, 0, 0);
3652 rtx last = XVECEXP (insns, 0, XVECLEN (insns, 0) - 1);
3653
3654 REG_NOTES (first) = gen_rtx (INSN_LIST, REG_LIBCALL, last,
3655 REG_NOTES (first));
3656 REG_NOTES (last) = gen_rtx (INSN_LIST, REG_RETVAL, first, REG_NOTES (last));
3657
3658 emit_insn (insns);
3659 DONE;
3660}")
3661
3662(define_expand "trunc_call_rtl"
cd2b37d9 3663 [(set (reg:DF 33) (match_operand:DF 1 "gpc_reg_operand" ""))
1fd4e8c1
RK
3664 (use (reg:DF 33))
3665 (parallel [(set (reg:SI 3)
3666 (call (mem:SI (match_operand 2 "" "")) (const_int 0)))
4697a36c 3667 (use (const_int 0))
1fd4e8c1 3668 (clobber (scratch:SI))])
cd2b37d9 3669 (set (match_operand:SI 0 "gpc_reg_operand" "")
1fd4e8c1 3670 (reg:SI 3))]
d14a6d05 3671 "TARGET_HARD_FLOAT"
1fd4e8c1 3672 "
7e69e155 3673{
1fd4e8c1
RK
3674 rs6000_trunc_used = 1;
3675}")
a473029f
RK
3676
3677(define_insn "floatdidf2"
3678 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
3679 (float:DF (match_operand:DI 1 "gpc_reg_operand" "f")))]
d14a6d05 3680 "TARGET_POWERPC64 && TARGET_HARD_FLOAT"
a473029f
RK
3681 "fcfid %0,%1"
3682 [(set_attr "type" "fp")])
3683
3684(define_insn "fix_truncdfdi2"
3685 [(set (match_operand:DI 0 "gpc_reg_operand" "=f")
3686 (fix:DI (match_operand:DF 1 "gpc_reg_operand" "f")))]
d14a6d05 3687 "TARGET_POWERPC64 && TARGET_HARD_FLOAT"
a473029f
RK
3688 "fctidz %0,%1"
3689 [(set_attr "type" "fp")])
1fd4e8c1
RK
3690\f
3691;; Define the DImode operations that can be done in a small number
a6ec530c
RK
3692;; of instructions. The & constraints are to prevent the register
3693;; allocator from allocating registers that overlap with the inputs
3694;; (for example, having an input in 7,8 and an output in 6,7). We
3695;; also allow for the the output being the same as one of the inputs.
3696
266eb58a 3697(define_insn "*adddi3_noppc64"
a6ec530c
RK
3698 [(set (match_operand:DI 0 "gpc_reg_operand" "=&r,&r,r,r")
3699 (plus:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,0,0")
3700 (match_operand:DI 2 "reg_or_short_operand" "r,I,r,I")))]
e1f83b4d 3701 "! TARGET_POWERPC64"
0f645302
MM
3702 "*
3703{
3704 if (WORDS_BIG_ENDIAN)
3705 return (GET_CODE (operands[2])) != CONST_INT
3706 ? \"{a|addc} %L0,%L1,%L2\;{ae|adde} %0,%1,%2\"
3707 : \"{ai|addic} %L0,%L1,%2\;{a%G2e|add%G2e} %0,%1\";
3708 else
3709 return (GET_CODE (operands[2])) != CONST_INT
3710 ? \"{a|addc} %0,%1,%2\;{ae|adde} %L0,%L1,%L2\"
3711 : \"{ai|addic} %0,%1,%2\;{a%G2e|add%G2e} %L0,%L1\";
3712}"
b19003d8 3713 [(set_attr "length" "8")])
1fd4e8c1 3714
266eb58a 3715(define_insn "*subdi3_noppc64"
e7e5df70
RK
3716 [(set (match_operand:DI 0 "gpc_reg_operand" "=&r,&r,r,r,r")
3717 (minus:DI (match_operand:DI 1 "reg_or_short_operand" "r,I,0,r,I")
3718 (match_operand:DI 2 "gpc_reg_operand" "r,r,r,0,0")))]
266eb58a 3719 "! TARGET_POWERPC64"
5502823b
RK
3720 "*
3721{
0f645302
MM
3722 if (WORDS_BIG_ENDIAN)
3723 return (GET_CODE (operands[1]) != CONST_INT)
3724 ? \"{sf|subfc} %L0,%L2,%L1\;{sfe|subfe} %0,%2,%1\"
3725 : \"{sfi|subfic} %L0,%L2,%1\;{sf%G1e|subf%G1e} %0,%2\";
3726 else
3727 return (GET_CODE (operands[1]) != CONST_INT)
3728 ? \"{sf|subfc} %0,%2,%1\;{sfe|subfe} %L0,%L2,%L1\"
3729 : \"{sfi|subfic} %0,%2,%1\;{sf%G1e|subf%G1e} %L0,%L2\";
5502823b 3730}"
ca7f5001
RK
3731 [(set_attr "length" "8")])
3732
266eb58a 3733(define_insn "*negdi2_noppc64"
a6ec530c
RK
3734 [(set (match_operand:DI 0 "gpc_reg_operand" "=&r,r")
3735 (neg:DI (match_operand:DI 1 "gpc_reg_operand" "r,0")))]
51b8fc2c 3736 "! TARGET_POWERPC64"
5502823b
RK
3737 "*
3738{
3739 return (WORDS_BIG_ENDIAN)
3740 ? \"{sfi|subfic} %L0,%L1,0\;{sfze|subfze} %0,%1\"
3741 : \"{sfi|subfic} %0,%1,0\;{sfze|subfze} %L0,%L1\";
3742}"
ca7f5001
RK
3743 [(set_attr "length" "8")])
3744
8ffd9c51
RK
3745(define_expand "mulsidi3"
3746 [(set (match_operand:DI 0 "gpc_reg_operand" "")
3747 (mult:DI (sign_extend:DI (match_operand:SI 1 "gpc_reg_operand" ""))
3748 (sign_extend:DI (match_operand:SI 2 "gpc_reg_operand" ""))))]
3749 ""
3750 "
3751{
3752 if (! TARGET_POWER && ! TARGET_POWERPC)
3753 {
4c0c634c
MM
3754 emit_move_insn (gen_rtx (REG, SImode, 3), operands[1]);
3755 emit_move_insn (gen_rtx (REG, SImode, 4), operands[2]);
fada905b 3756 emit_insn (gen_mull_call ());
cf27b467
MM
3757 if (WORDS_BIG_ENDIAN)
3758 emit_move_insn (operands[0], gen_rtx (REG, DImode, 3));
3759 else
3760 {
3761 emit_move_insn (operand_subword (operands[0], 0, 0, DImode),
3762 gen_rtx (REG, SImode, 3));
3763 emit_move_insn (operand_subword (operands[0], 1, 0, DImode),
3764 gen_rtx (REG, SImode, 4));
3765 }
8ffd9c51
RK
3766 DONE;
3767 }
3768 else if (TARGET_POWER)
3769 {
3770 emit_insn (gen_mulsidi3_mq (operands[0], operands[1], operands[2]));
3771 DONE;
3772 }
3773}")
deb9225a 3774
8ffd9c51 3775(define_insn "mulsidi3_mq"
cd2b37d9 3776 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
8ffd9c51 3777 (mult:DI (sign_extend:DI (match_operand:SI 1 "gpc_reg_operand" "%r"))
cd2b37d9 3778 (sign_extend:DI (match_operand:SI 2 "gpc_reg_operand" "r"))))
1fd4e8c1 3779 (clobber (match_scratch:SI 3 "=q"))]
ca7f5001 3780 "TARGET_POWER"
b19003d8 3781 "mul %0,%1,%2\;mfmq %L0"
8ffd9c51
RK
3782 [(set_attr "type" "imul")
3783 (set_attr "length" "8")])
deb9225a 3784
ebedb4dd 3785(define_insn "*mulsidi3_powerpc"
425c176f 3786 [(set (match_operand:DI 0 "gpc_reg_operand" "=&r")
8ffd9c51
RK
3787 (mult:DI (sign_extend:DI (match_operand:SI 1 "gpc_reg_operand" "%r"))
3788 (sign_extend:DI (match_operand:SI 2 "gpc_reg_operand" "r"))))]
425c176f 3789 "TARGET_POWERPC && ! TARGET_POWERPC64"
5502823b
RK
3790 "*
3791{
3792 return (WORDS_BIG_ENDIAN)
3793 ? \"mulhw %0,%1,%2\;mullw %L0,%1,%2\"
3794 : \"mulhw %L0,%1,%2\;mullw %0,%1,%2\";
3795}"
8ffd9c51
RK
3796 [(set_attr "type" "imul")
3797 (set_attr "length" "8")])
deb9225a 3798
ebedb4dd
MM
3799(define_split
3800 [(set (match_operand:DI 0 "gpc_reg_operand" "")
3801 (mult:DI (sign_extend:DI (match_operand:SI 1 "gpc_reg_operand" ""))
3802 (sign_extend:DI (match_operand:SI 2 "gpc_reg_operand" ""))))]
cf27b467 3803 "TARGET_POWERPC && ! TARGET_POWERPC64 && reload_completed"
ebedb4dd
MM
3804 [(set (match_dup 3)
3805 (truncate:SI
3806 (lshiftrt:DI (mult:DI (sign_extend:DI (match_dup 1))
3807 (sign_extend:DI (match_dup 2)))
3808 (const_int 32))))
3809 (set (match_dup 4)
3810 (mult:SI (match_dup 1)
3811 (match_dup 2)))]
3812 "
3813{
3814 int endian = (WORDS_BIG_ENDIAN == 0);
3815 operands[3] = operand_subword (operands[0], endian, 0, DImode);
3816 operands[4] = operand_subword (operands[0], 1 - endian, 0, DImode);
3817}")
3818
8106dc08
MM
3819(define_insn "umulsidi3"
3820 [(set (match_operand:DI 0 "gpc_reg_operand" "=&r")
3821 (mult:DI (zero_extend:DI (match_operand:SI 1 "gpc_reg_operand" "%r"))
3822 (zero_extend:DI (match_operand:SI 2 "gpc_reg_operand" "r"))))]
3823 "TARGET_POWERPC && ! TARGET_POWERPC64"
3824 "*
3825{
3826 return (WORDS_BIG_ENDIAN)
3827 ? \"mulhwu %0,%1,%2\;mullw %L0,%1,%2\"
3828 : \"mulhwu %L0,%1,%2\;mullw %0,%1,%2\";
3829}"
3830 [(set_attr "type" "imul")
3831 (set_attr "length" "8")])
3832
ebedb4dd
MM
3833(define_split
3834 [(set (match_operand:DI 0 "gpc_reg_operand" "")
3835 (mult:DI (zero_extend:DI (match_operand:SI 1 "gpc_reg_operand" ""))
3836 (zero_extend:DI (match_operand:SI 2 "gpc_reg_operand" ""))))]
cf27b467 3837 "TARGET_POWERPC && ! TARGET_POWERPC64 && reload_completed"
ebedb4dd
MM
3838 [(set (match_dup 3)
3839 (truncate:SI
3840 (lshiftrt:DI (mult:DI (zero_extend:DI (match_dup 1))
3841 (zero_extend:DI (match_dup 2)))
3842 (const_int 32))))
3843 (set (match_dup 4)
3844 (mult:SI (match_dup 1)
3845 (match_dup 2)))]
3846 "
3847{
3848 int endian = (WORDS_BIG_ENDIAN == 0);
3849 operands[3] = operand_subword (operands[0], endian, 0, DImode);
3850 operands[4] = operand_subword (operands[0], 1 - endian, 0, DImode);
3851}")
3852
8ffd9c51
RK
3853(define_expand "smulsi3_highpart"
3854 [(set (match_operand:SI 0 "gpc_reg_operand" "")
3855 (truncate:SI
3856 (lshiftrt:DI (mult:DI (sign_extend:DI
3857 (match_operand:SI 1 "gpc_reg_operand" "%r"))
3858 (sign_extend:DI
3859 (match_operand:SI 2 "gpc_reg_operand" "r")))
3860 (const_int 32))))]
3861 ""
3862 "
3863{
3864 if (! TARGET_POWER && ! TARGET_POWERPC)
3865 {
3866 emit_move_insn (gen_rtx (REG, SImode, 3), operands[1]);
3867 emit_move_insn (gen_rtx (REG, SImode, 4), operands[2]);
fada905b 3868 emit_insn (gen_mulh_call ());
8ffd9c51
RK
3869 emit_move_insn (operands[0], gen_rtx (REG, SImode, 3));
3870 DONE;
3871 }
3872 else if (TARGET_POWER)
3873 {
3874 emit_insn (gen_smulsi3_highpart_mq (operands[0], operands[1], operands[2]));
3875 DONE;
3876 }
3877}")
deb9225a 3878
8ffd9c51
RK
3879(define_insn "smulsi3_highpart_mq"
3880 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
3881 (truncate:SI
fada905b
MM
3882 (lshiftrt:DI (mult:DI (sign_extend:DI
3883 (match_operand:SI 1 "gpc_reg_operand" "%r"))
3884 (sign_extend:DI
3885 (match_operand:SI 2 "gpc_reg_operand" "r")))
8ffd9c51
RK
3886 (const_int 32))))
3887 (clobber (match_scratch:SI 3 "=q"))]
3888 "TARGET_POWER"
3889 "mul %0,%1,%2"
3890 [(set_attr "type" "imul")])
deb9225a 3891
fada905b 3892(define_insn ""
8ffd9c51
RK
3893 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
3894 (truncate:SI
fada905b
MM
3895 (lshiftrt:DI (mult:DI (sign_extend:DI
3896 (match_operand:SI 1 "gpc_reg_operand" "%r"))
3897 (sign_extend:DI
3898 (match_operand:SI 2 "gpc_reg_operand" "r")))
8ffd9c51
RK
3899 (const_int 32))))]
3900 "TARGET_POWERPC"
3901 "mulhw %0,%1,%2"
3902 [(set_attr "type" "imul")])
deb9225a 3903
266eb58a
DE
3904(define_insn "umulsi3_highpart"
3905 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
3906 (truncate:SI
3907 (lshiftrt:DI (mult:DI (zero_extend:DI
3908 (match_operand:SI 1 "gpc_reg_operand" "%r"))
3909 (zero_extend:DI
3910 (match_operand:SI 2 "gpc_reg_operand" "r")))
3911 (const_int 32))))]
3912 "TARGET_POWERPC"
3913 "mulhwu %0,%1,%2"
3914 [(set_attr "type" "imul")])
3915
3916;; If operands 0 and 2 are in the same register, we have a problem. But
3917;; operands 0 and 1 (the usual case) can be in the same register. That's
3918;; why we have the strange constraints below.
3919(define_insn "ashldi3_power"
3920 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,&r")
3921 (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,0,r")
3922 (match_operand:SI 2 "reg_or_cint_operand" "M,i,r,r")))
3923 (clobber (match_scratch:SI 3 "=X,q,q,q"))]
3924 "TARGET_POWER"
3925 "@
3926 {sli|slwi} %0,%L1,%h2\;{cal %L0,0(0)|li %L0,0}
3927 sl%I2q %L0,%L1,%h2\;sll%I2q %0,%1,%h2
3928 sl%I2q %L0,%L1,%h2\;sll%I2q %0,%1,%h2
3929 sl%I2q %L0,%L1,%h2\;sll%I2q %0,%1,%h2"
3930 [(set_attr "length" "8")])
3931
3932(define_insn "lshrdi3_power"
3933 [(set (match_operand:DI 0 "gpc_reg_operand" "=&r,r,r,&r")
3934 (lshiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,0,r")
3935 (match_operand:SI 2 "reg_or_cint_operand" "M,i,r,r")))
3936 (clobber (match_scratch:SI 3 "=X,q,q,q"))]
3937 "TARGET_POWER"
3938 "@
3939 {cal %0,0(0)|li %0,0}\;{s%A2i|s%A2wi} %L0,%1,%h2
3940 sr%I2q %0,%1,%h2\;srl%I2q %L0,%L1,%h2
3941 sr%I2q %0,%1,%h2\;srl%I2q %L0,%L1,%h2
3942 sr%I2q %0,%1,%h2\;srl%I2q %L0,%L1,%h2"
3943 [(set_attr "length" "8")])
3944
3945;; Shift by a variable amount is too complex to be worth open-coding. We
3946;; just handle shifts by constants.
3947(define_insn "ashrdi3_power"
3948 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
3949 (ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
3950 (match_operand:SI 2 "const_int_operand" "M,i")))
3951 (clobber (match_scratch:SI 3 "=X,q"))]
3952 "TARGET_POWER"
3953 "@
3954 {srai|srawi} %0,%1,31\;{srai|srawi} %L0,%1,%h2
3955 sraiq %0,%1,%h2\;srliq %L0,%L1,%h2"
3956 [(set_attr "length" "8")])
3957\f
3958;; PowerPC64 DImode operations.
3959
3960(define_expand "adddi3"
3961 [(set (match_operand:DI 0 "gpc_reg_operand" "")
3962 (plus:DI (match_operand:DI 1 "gpc_reg_operand" "")
3963 (match_operand:DI 2 "add_operand" "")))]
3964 ""
3965 "
3966{
3967 if (! TARGET_POWERPC64 && non_add_cint_operand (operands[2], DImode))
3968 FAIL;
3969}")
3970
3971;; Discourage ai/addic because of carry but provide it in an alternative
3972;; allowing register zero as source.
3973
3974(define_insn ""
3975 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,?r,r")
3976 (plus:DI (match_operand:DI 1 "gpc_reg_operand" "%r,b,r,b")
3977 (match_operand:DI 2 "add_operand" "r,I,I,J")))]
3978 "TARGET_POWERPC64"
3979 "@
3980 add %0,%1,%2
3981 addi %0,%1,%2
3982 addic %0,%1,%2
3983 addis %0,%1,%u2")
3984
3985(define_insn ""
3986 [(set (match_operand:CC 0 "cc_reg_operand" "=x,x")
3987 (compare:CC (plus:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r")
3988 (match_operand:DI 2 "reg_or_short_operand" "r,I"))
3989 (const_int 0)))
3990 (clobber (match_scratch:DI 3 "=r,r"))]
3991 "TARGET_POWERPC64"
3992 "@
3993 add. %3,%1,%2
3994 addic. %3,%1,%2"
3995 [(set_attr "type" "compare")])
3996
3997(define_insn ""
3998 [(set (match_operand:CC 3 "cc_reg_operand" "=x,x")
3999 (compare:CC (plus:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r")
4000 (match_operand:DI 2 "reg_or_short_operand" "r,I"))
4001 (const_int 0)))
4002 (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
4003 (plus:DI (match_dup 1) (match_dup 2)))]
4004 "TARGET_POWERPC64"
4005 "@
4006 add. %0,%1,%2
4007 addic. %0,%1,%2"
4008 [(set_attr "type" "compare")])
4009
4010;; Split an add that we can't do in one insn into two insns, each of which
4011;; does one 16-bit part. This is used by combine. Note that the low-order
4012;; add should be last in case the result gets used in an address.
4013
4014(define_split
4015 [(set (match_operand:DI 0 "gpc_reg_operand" "")
4016 (plus:DI (match_operand:DI 1 "gpc_reg_operand" "")
4017 (match_operand:DI 2 "non_add_cint_operand" "")))]
4018 "TARGET_POWERPC64"
4019 [(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 3)))
4020 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 4)))]
4021"
4022{
e6ca2c17
DE
4023 HOST_WIDE_INT low = INTVAL (operands[2]) & 0xffff;
4024 HOST_WIDE_INT high = INTVAL (operands[2]) & (~ (HOST_WIDE_INT) 0xffff);
266eb58a
DE
4025
4026 if (low & 0x8000)
e6ca2c17 4027 high+=0x10000, low |= ((HOST_WIDE_INT) -1) << 16;
266eb58a 4028
e6ca2c17
DE
4029 operands[3] = GEN_INT (high);
4030 operands[4] = GEN_INT (low);
266eb58a
DE
4031}")
4032
4033(define_insn "one_cmpldi2"
4034 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4035 (not:DI (match_operand:DI 1 "gpc_reg_operand" "r")))]
4036 "TARGET_POWERPC64"
4037 "nor %0,%1,%1")
4038
4039(define_insn ""
4040 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
4041 (compare:CC (not:DI (match_operand:DI 1 "gpc_reg_operand" "r"))
4042 (const_int 0)))
4043 (clobber (match_scratch:DI 2 "=r"))]
4044 "TARGET_POWERPC64"
4045 "nor. %2,%1,%1"
4046 [(set_attr "type" "compare")])
4047
4048(define_insn ""
4049 [(set (match_operand:CC 2 "cc_reg_operand" "=x")
4050 (compare:CC (not:DI (match_operand:DI 1 "gpc_reg_operand" "r"))
4051 (const_int 0)))
4052 (set (match_operand:DI 0 "gpc_reg_operand" "=r")
4053 (not:DI (match_dup 1)))]
4054 "TARGET_POWERPC64"
d944f453 4055 "nor. %0,%1,%1"
266eb58a
DE
4056 [(set_attr "type" "compare")])
4057
4058(define_insn ""
4059 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
4060 (minus:DI (match_operand:DI 1 "reg_or_short_operand" "r,I")
4061 (match_operand:DI 2 "gpc_reg_operand" "r,r")))]
4062 "TARGET_POWERPC64"
4063 "@
4064 subf %0,%2,%1
4065 subfic %0,%2,%1")
4066
4067(define_insn ""
4068 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
4069 (compare:CC (minus:DI (match_operand:DI 1 "gpc_reg_operand" "r")
4070 (match_operand:DI 2 "gpc_reg_operand" "r"))
4071 (const_int 0)))
4072 (clobber (match_scratch:DI 3 "=r"))]
4073 "TARGET_POWERPC64"
4074 "subf. %3,%2,%1"
4075 [(set_attr "type" "compare")])
4076
4077(define_insn ""
4078 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
4079 (compare:CC (minus:DI (match_operand:DI 1 "gpc_reg_operand" "r")
4080 (match_operand:DI 2 "gpc_reg_operand" "r"))
4081 (const_int 0)))
4082 (set (match_operand:DI 0 "gpc_reg_operand" "=r")
4083 (minus:DI (match_dup 1) (match_dup 2)))]
4084 "TARGET_POWERPC64"
4085 "subf. %0,%2,%1"
4086 [(set_attr "type" "compare")])
4087
4088(define_expand "subdi3"
4089 [(set (match_operand:DI 0 "gpc_reg_operand" "")
4090 (minus:DI (match_operand:DI 1 "reg_or_short_operand" "")
4091 (match_operand:DI 2 "reg_or_cint_operand" "")))]
4092 ""
4093 "
4094{
4095 if (GET_CODE (operands[2]) == CONST_INT)
4096 {
4097 emit_insn (gen_adddi3 (operands[0], operands[1],
4098 negate_rtx (DImode, operands[2])));
4099 DONE;
4100 }
4101}")
4102
4103(define_insn "absdi2"
4104 [(set (match_operand:DI 0 "gpc_reg_operand" "=&r,r")
4105 (abs:DI (match_operand:DI 1 "gpc_reg_operand" "r,0")))
4106 (clobber (match_scratch:DI 2 "=&r,&r"))]
4107 "TARGET_POWERPC64"
4108 "sradi %2,%1,31\;xor %0,%2,%1\;subf %0,%2,%0"
4109 [(set_attr "length" "12")])
4110
4111(define_split
4112 [(set (match_operand:DI 0 "gpc_reg_operand" "=&r,r")
4113 (abs:DI (match_operand:DI 1 "gpc_reg_operand" "r,0")))
4114 (clobber (match_scratch:DI 2 "=&r,&r"))]
4115 "TARGET_POWERPC64 && reload_completed"
4116 [(set (match_dup 2) (ashiftrt:DI (match_dup 1) (const_int 31)))
4117 (set (match_dup 0) (xor:DI (match_dup 2) (match_dup 1)))
4118 (set (match_dup 0) (minus:DI (match_dup 2) (match_dup 0)))]
4119 "")
4120
4121(define_insn ""
4122 [(set (match_operand:DI 0 "gpc_reg_operand" "=&r,r")
4123 (neg:DI (abs:DI (match_operand:DI 1 "gpc_reg_operand" "r,0"))))
4124 (clobber (match_scratch:DI 2 "=&r,&r"))]
4125 "TARGET_POWERPC64"
4126 "sradi %2,%1,31\;xor %0,%2,%1\;subf %0,%0,%2"
4127 [(set_attr "length" "12")])
4128
4129(define_split
4130 [(set (match_operand:DI 0 "gpc_reg_operand" "=&r,r")
4131 (neg:DI (abs:DI (match_operand:DI 1 "gpc_reg_operand" "r,0"))))
4132 (clobber (match_scratch:DI 2 "=&r,&r"))]
4133 "TARGET_POWERPC64 && reload_completed"
4134 [(set (match_dup 2) (ashiftrt:DI (match_dup 1) (const_int 31)))
4135 (set (match_dup 0) (xor:DI (match_dup 2) (match_dup 1)))
4136 (set (match_dup 0) (minus:DI (match_dup 0) (match_dup 2)))]
4137 "")
4138
4139(define_expand "negdi2"
4140 [(set (match_operand:DI 0 "gpc_reg_operand" "")
4141 (neg:DI (match_operand:DI 1 "gpc_reg_operand" "")))]
4142 ""
4143 "")
4144
4145(define_insn ""
4146 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4147 (neg:DI (match_operand:DI 1 "gpc_reg_operand" "r")))]
4148 "TARGET_POWERPC64"
4149 "neg %0,%1")
4150
4151(define_insn ""
4152 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
4153 (compare:CC (neg:DI (match_operand:DI 1 "gpc_reg_operand" "r"))
4154 (const_int 0)))
4155 (clobber (match_scratch:DI 2 "=r"))]
4156 "TARGET_POWERPC64"
4157 "neg. %2,%1"
4158 [(set_attr "type" "compare")])
4159
4160(define_insn ""
4161 [(set (match_operand:CC 2 "cc_reg_operand" "=x")
4162 (compare:CC (neg:DI (match_operand:DI 1 "gpc_reg_operand" "r"))
4163 (const_int 0)))
4164 (set (match_operand:DI 0 "gpc_reg_operand" "=r")
4165 (neg:DI (match_dup 1)))]
4166 "TARGET_POWERPC64"
4167 "neg. %0,%1"
4168 [(set_attr "type" "compare")])
4169
4170(define_insn "ffsdi2"
4171 [(set (match_operand:DI 0 "gpc_reg_operand" "=&r")
4172 (ffs:DI (match_operand:DI 1 "gpc_reg_operand" "r")))]
4173 "TARGET_POWERPC64"
4174 "neg %0,%1\;and %0,%0,%1\;cntlzd %0,%0\;subfic %0,%0,64"
4175 [(set_attr "length" "16")])
4176
4177(define_insn "muldi3"
4178 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4179 (mult:DI (match_operand:DI 1 "gpc_reg_operand" "%r")
4180 (match_operand:DI 2 "gpc_reg_operand" "r")))]
4181 "TARGET_POWERPC64"
4182 "mulld %0,%1,%2"
4183 [(set_attr "type" "imul")])
4184
4185(define_insn "smuldi3_highpart"
4186 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4187 (truncate:DI
4188 (lshiftrt:TI (mult:TI (sign_extend:TI
4189 (match_operand:DI 1 "gpc_reg_operand" "%r"))
4190 (sign_extend:TI
4191 (match_operand:DI 2 "gpc_reg_operand" "r")))
4192 (const_int 64))))]
4193 "TARGET_POWERPC64"
4194 "mulhd %0,%1,%2"
4195 [(set_attr "type" "imul")])
4196
4197(define_insn "umuldi3_highpart"
4198 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4199 (truncate:DI
4200 (lshiftrt:TI (mult:TI (zero_extend:TI
4201 (match_operand:DI 1 "gpc_reg_operand" "%r"))
4202 (zero_extend:TI
4203 (match_operand:DI 2 "gpc_reg_operand" "r")))
4204 (const_int 64))))]
4205 "TARGET_POWERPC64"
4206 "mulhdu %0,%1,%2"
4207 [(set_attr "type" "imul")])
4208
4209(define_expand "divdi3"
4210 [(set (match_operand:DI 0 "gpc_reg_operand" "")
4211 (div:DI (match_operand:DI 1 "gpc_reg_operand" "")
4212 (match_operand:DI 2 "reg_or_cint_operand" "")))]
4213 "TARGET_POWERPC64"
4214 "
4215{
4216 if (GET_CODE (operands[2]) == CONST_INT
4217 && exact_log2 (INTVAL (operands[2])) >= 0)
4218 ;
4219 else
4220 operands[2] = force_reg (DImode, operands[2]);
4221}")
4222
4223(define_expand "moddi3"
4224 [(use (match_operand:DI 0 "gpc_reg_operand" ""))
4225 (use (match_operand:DI 1 "gpc_reg_operand" ""))
4226 (use (match_operand:DI 2 "reg_or_cint_operand" ""))]
4227 "TARGET_POWERPC64"
4228 "
4229{
4230 int i = exact_log2 (INTVAL (operands[2]));
4231 rtx temp1;
4232 rtx temp2;
4233
4234 if (GET_CODE (operands[2]) != CONST_INT || i < 0)
4235 FAIL;
4236
4237 temp1 = gen_reg_rtx (DImode);
4238 temp2 = gen_reg_rtx (DImode);
4239
4240 emit_insn (gen_divdi3 (temp1, operands[1], operands[2]));
4241 emit_insn (gen_ashldi3 (temp2, temp1, GEN_INT (i)));
4242 emit_insn (gen_subdi3 (operands[0], operands[1], temp2));
4243 DONE;
4244}")
4245
4246(define_insn ""
4247 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4248 (div:DI (match_operand:DI 1 "gpc_reg_operand" "r")
4249 (match_operand:DI 2 "const_int_operand" "N")))]
4250 "TARGET_POWERPC64 && exact_log2 (INTVAL (operands[2])) >= 0"
4251 "sradi %0,%1,%p2\;addze %0,%0"
4252 [(set_attr "length" "8")])
4253
4254(define_insn ""
4255 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
4256 (compare:CC (div:DI (match_operand:DI 1 "gpc_reg_operand" "r")
4257 (match_operand:DI 2 "const_int_operand" "N"))
4258 (const_int 0)))
4259 (clobber (match_scratch:DI 3 "=r"))]
4260 "TARGET_POWERPC64 && exact_log2 (INTVAL (operands[2])) >= 0"
4261 "sradi %3,%1,%p2\;addze. %3,%3"
4262 [(set_attr "type" "compare")
4263 (set_attr "length" "8")])
4264
4265(define_insn ""
4266 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
4267 (compare:CC (div:DI (match_operand:DI 1 "gpc_reg_operand" "r")
4268 (match_operand:DI 2 "const_int_operand" "N"))
4269 (const_int 0)))
4270 (set (match_operand:DI 0 "gpc_reg_operand" "=r")
4271 (div:DI (match_dup 1) (match_dup 2)))]
4272 "TARGET_POWERPC64 && exact_log2 (INTVAL (operands[2])) >= 0"
4273 "sradi %0,%1,%p2\;addze. %0,%0"
4274 [(set_attr "type" "compare")
4275 (set_attr "length" "8")])
4276
4277(define_insn ""
4278 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4279 (div:DI (match_operand:DI 1 "gpc_reg_operand" "r")
4280 (match_operand:DI 2 "gpc_reg_operand" "r")))]
4281 "TARGET_POWERPC64"
4282 "divd %0,%1,%2"
4283 [(set_attr "type" "idiv")])
4284
4285(define_insn "udivdi3"
4286 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4287 (udiv:DI (match_operand:DI 1 "gpc_reg_operand" "r")
4288 (match_operand:DI 2 "gpc_reg_operand" "r")))]
4289 "TARGET_POWERPC64"
4290 "divdu %0,%1,%2"
4291 [(set_attr "type" "idiv")])
4292
4293(define_insn "rotldi3"
4294 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4295 (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r")
4296 (match_operand:DI 2 "reg_or_cint_operand" "ri")))]
4297 "TARGET_POWERPC64"
a66078ee 4298 "rld%I2cl %0,%1,%H2,0")
266eb58a
DE
4299
4300(define_insn ""
4301 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
4302 (compare:CC (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r")
4303 (match_operand:DI 2 "reg_or_cint_operand" "ri"))
4304 (const_int 0)))
4305 (clobber (match_scratch:DI 3 "=r"))]
4306 "TARGET_POWERPC64"
a66078ee 4307 "rld%I2cl. %3,%1,%H2,0"
266eb58a
DE
4308 [(set_attr "type" "delayed_compare")])
4309
4310(define_insn ""
4311 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
4312 (compare:CC (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r")
4313 (match_operand:DI 2 "reg_or_cint_operand" "ri"))
4314 (const_int 0)))
4315 (set (match_operand:DI 0 "gpc_reg_operand" "=r")
4316 (rotate:DI (match_dup 1) (match_dup 2)))]
4317 "TARGET_POWERPC64"
a66078ee 4318 "rld%I2cl. %0,%1,%H2,0"
266eb58a
DE
4319 [(set_attr "type" "delayed_compare")])
4320
4321(define_expand "ashldi3"
4322 [(set (match_operand:DI 0 "gpc_reg_operand" "")
4323 (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "")
4324 (match_operand:SI 2 "reg_or_cint_operand" "")))]
4325 "TARGET_POWERPC64 || TARGET_POWER"
4326 "
4327{
4328 if (TARGET_POWERPC64)
4329 ;
4330 else if (TARGET_POWER)
4331 {
4332 emit_insn (gen_ashldi3_power (operands[0], operands[1], operands[2]));
4333 DONE;
4334 }
4335 else
4336 FAIL;
4337}")
4338
4339(define_insn ""
4340 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4341 (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r")
4342 (match_operand:SI 2 "reg_or_cint_operand" "ri")))]
4343 "TARGET_POWERPC64"
a66078ee 4344 "sld%I2 %0,%1,%H2"
266eb58a
DE
4345 [(set_attr "length" "8")])
4346
4347(define_insn ""
4348 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
4349 (compare:CC (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r")
4350 (match_operand:SI 2 "reg_or_cint_operand" "ri"))
4351 (const_int 0)))
4352 (clobber (match_scratch:DI 3 "=r"))]
4353 "TARGET_POWERPC64"
a66078ee 4354 "sld%I2. %3,%1,%H2"
266eb58a
DE
4355 [(set_attr "type" "delayed_compare")])
4356
4357(define_insn ""
4358 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
4359 (compare:CC (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r")
4360 (match_operand:SI 2 "reg_or_cint_operand" "ri"))
4361 (const_int 0)))
4362 (set (match_operand:DI 0 "gpc_reg_operand" "=r")
4363 (ashift:DI (match_dup 1) (match_dup 2)))]
4364 "TARGET_POWERPC64"
a66078ee 4365 "sld%I2. %0,%1,%H2"
266eb58a
DE
4366 [(set_attr "type" "delayed_compare")])
4367
4368(define_expand "lshrdi3"
4369 [(set (match_operand:DI 0 "gpc_reg_operand" "")
4370 (lshiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "")
4371 (match_operand:SI 2 "reg_or_cint_operand" "")))]
4372 "TARGET_POWERPC64 || TARGET_POWER"
4373 "
4374{
4375 if (TARGET_POWERPC64)
4376 ;
4377 else if (TARGET_POWER)
4378 {
4379 emit_insn (gen_lshrdi3_power (operands[0], operands[1], operands[2]));
4380 DONE;
4381 }
4382 else
4383 FAIL;
4384}")
4385
4386(define_insn ""
4387 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4388 (lshiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r")
4389 (match_operand:SI 2 "reg_or_cint_operand" "ri")))]
4390 "TARGET_POWERPC64"
a66078ee 4391 "srd%I2 %0,%1,%H2")
266eb58a
DE
4392
4393(define_insn ""
4394 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
4395 (compare:CC (lshiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r")
4396 (match_operand:SI 2 "reg_or_cint_operand" "ri"))
4397 (const_int 0)))
4398 (clobber (match_scratch:DI 3 "=r"))]
4399 "TARGET_POWERPC64"
a66078ee 4400 "srd%I2. %3,%1,%H2"
266eb58a
DE
4401 [(set_attr "type" "delayed_compare")])
4402
4403(define_insn ""
4404 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
4405 (compare:CC (lshiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r")
4406 (match_operand:SI 2 "reg_or_cint_operand" "ri"))
4407 (const_int 0)))
4408 (set (match_operand:DI 0 "gpc_reg_operand" "=r")
4409 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
4410 "TARGET_POWERPC64"
a66078ee 4411 "srd%I2. %0,%1,%H2"
266eb58a
DE
4412 [(set_attr "type" "delayed_compare")])
4413
4414(define_expand "ashrdi3"
4415 [(set (match_operand:DI 0 "gpc_reg_operand" "")
4416 (ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "")
4417 (match_operand:SI 2 "reg_or_cint_operand" "")))]
4418 "TARGET_POWERPC64 || TARGET_POWER"
4419 "
4420{
4421 if (TARGET_POWERPC64)
4422 ;
4423 else if (TARGET_POWER && GET_CODE (operands[2]) == CONST_INT)
4424 {
4425 emit_insn (gen_ashrdi3_power (operands[0], operands[1], operands[2]));
4426 DONE;
4427 }
4428 else
4429 FAIL;
4430}")
4431
4432(define_insn ""
4433 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4434 (ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r")
4435 (match_operand:SI 2 "reg_or_cint_operand" "ri")))]
4436 "TARGET_POWERPC64"
375490e0 4437 "srad%I2 %0,%1,%H2")
266eb58a
DE
4438
4439(define_insn ""
4440 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
4441 (compare:CC (ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r")
4442 (match_operand:SI 2 "reg_or_cint_operand" "ri"))
4443 (const_int 0)))
4444 (clobber (match_scratch:DI 3 "=r"))]
4445 "TARGET_POWERPC64"
375490e0 4446 "srad%I2. %3,%1,%H2"
266eb58a
DE
4447 [(set_attr "type" "delayed_compare")])
4448
4449(define_insn ""
4450 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
4451 (compare:CC (ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r")
4452 (match_operand:SI 2 "reg_or_cint_operand" "ri"))
4453 (const_int 0)))
4454 (set (match_operand:DI 0 "gpc_reg_operand" "=r")
4455 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
4456 "TARGET_POWERPC64"
375490e0 4457 "srad%I2. %0,%1,%H2"
266eb58a
DE
4458 [(set_attr "type" "delayed_compare")])
4459
4460(define_insn "anddi3"
4461 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r")
4462 (and:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,r")
4463 (match_operand:DI 2 "and_operand" "?r,K,J")))
4464 (clobber (match_scratch:CC 3 "=X,x,x"))]
4465 "TARGET_POWERPC64"
4466 "@
4467 and %0,%1,%2
4468 andi. %0,%1,%b2
4469 andis. %0,%1,%u2")
4470
4471(define_insn ""
4472 [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,x")
4473 (compare:CC (and:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,r")
4474 (match_operand:DI 2 "and_operand" "r,K,J"))
4475 (const_int 0)))
4476 (clobber (match_scratch:DI 3 "=r,r,r"))]
4477 "TARGET_POWERPC64"
4478 "@
4479 and. %3,%1,%2
4480 andi. %3,%1,%b2
4481 andis. %3,%1,%u2"
4482 [(set_attr "type" "compare,compare,compare")])
4483
4484(define_insn ""
4485 [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,x")
4486 (compare:CC (and:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,r")
4487 (match_operand:DI 2 "and_operand" "r,K,J"))
4488 (const_int 0)))
4489 (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r")
4490 (and:DI (match_dup 1) (match_dup 2)))]
4491 "TARGET_POWERPC64"
4492 "@
4493 and. %0,%1,%2
4494 andi. %0,%1,%b2
4495 andis. %0,%1,%u2"
4496 [(set_attr "type" "compare,compare,compare")])
4497
4498;; Take a AND with a constant that cannot be done in a single insn and try to
4499;; split it into two insns. This does not verify that the insns are valid
4500;; since this need not be done as combine will do it.
4501
4502(define_split
4503 [(set (match_operand:DI 0 "gpc_reg_operand" "")
4504 (and:DI (match_operand:DI 1 "gpc_reg_operand" "")
4505 (match_operand:DI 2 "non_and_cint_operand" "")))]
4506 "TARGET_POWERPC64"
4507 [(set (match_dup 0) (and:DI (match_dup 1) (match_dup 3)))
4508 (set (match_dup 0) (and:DI (match_dup 0) (match_dup 4)))]
4509 "
4510{
4511 int maskval = INTVAL (operands[2]);
4512 int i, transitions, last_bit_value;
4513 int orig = maskval, first_c = maskval, second_c;
4514
4515 /* We know that MASKVAL must have more than 2 bit-transitions. Start at
4516 the low-order bit and count for the third transition. When we get there,
4517 make a first mask that has everything to the left of that position
4518 a one. Then make the second mask to turn off whatever else is needed. */
4519
4520 for (i = 1, transitions = 0, last_bit_value = maskval & 1; i < 32; i++)
4521 {
4522 if (((maskval >>= 1) & 1) != last_bit_value)
4523 last_bit_value ^= 1, transitions++;
4524
4525 if (transitions > 2)
4526 {
4527 first_c |= (~0) << i;
4528 break;
4529 }
4530 }
4531
4532 second_c = orig | ~ first_c;
4533
4534 operands[3] = gen_rtx (CONST_INT, VOIDmode, first_c);
4535 operands[4] = gen_rtx (CONST_INT, VOIDmode, second_c);
4536}")
4537
4538(define_insn "iordi3"
4539 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r")
4540 (ior:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,r")
4541 (match_operand:DI 2 "logical_operand" "r,K,J")))]
4542 "TARGET_POWERPC64"
4543 "@
4544 or %0,%1,%2
4545 ori %0,%1,%b2
4546 oris %0,%1,%u2")
4547
4548(define_insn ""
4549 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
4550 (compare:CC (ior:DI (match_operand:DI 1 "gpc_reg_operand" "%r")
4551 (match_operand:DI 2 "gpc_reg_operand" "r"))
4552 (const_int 0)))
4553 (clobber (match_scratch:DI 3 "=r"))]
4554 "TARGET_POWERPC64"
4555 "or. %3,%1,%2"
4556 [(set_attr "type" "compare")])
4557
4558(define_insn ""
4559 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
4560 (compare:CC (ior:DI (match_operand:DI 1 "gpc_reg_operand" "%r")
4561 (match_operand:DI 2 "gpc_reg_operand" "r"))
4562 (const_int 0)))
4563 (set (match_operand:DI 0 "gpc_reg_operand" "=r")
4564 (ior:DI (match_dup 1) (match_dup 2)))]
4565 "TARGET_POWERPC64"
4566 "or. %0,%1,%2"
4567 [(set_attr "type" "compare")])
4568
4569;; Split an IOR that we can't do in one insn into two insns, each of which
4570;; does one 16-bit part. This is used by combine.
4571
4572(define_split
4573 [(set (match_operand:DI 0 "gpc_reg_operand" "")
4574 (ior:DI (match_operand:DI 1 "gpc_reg_operand" "")
4575 (match_operand:DI 2 "non_logical_cint_operand" "")))]
4576 "TARGET_POWERPC64"
4577 [(set (match_dup 0) (ior:DI (match_dup 1) (match_dup 3)))
4578 (set (match_dup 0) (ior:DI (match_dup 0) (match_dup 4)))]
4579"
4580{
4581 operands[3] = gen_rtx (CONST_INT, VOIDmode,
e6ca2c17 4582 INTVAL (operands[2]) & (~ (HOST_WIDE_INT) 0xffff));
266eb58a
DE
4583 operands[4] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) & 0xffff);
4584}")
1fd4e8c1 4585
266eb58a
DE
4586(define_insn "xordi3"
4587 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r")
4588 (xor:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,r")
4589 (match_operand:DI 2 "logical_operand" "r,K,J")))]
4590 "TARGET_POWERPC64"
1fd4e8c1 4591 "@
266eb58a
DE
4592 xor %0,%1,%2
4593 xori %0,%1,%b2
4594 xoris %0,%1,%u2")
1fd4e8c1 4595
266eb58a
DE
4596(define_insn ""
4597 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
4598 (compare:CC (xor:DI (match_operand:DI 1 "gpc_reg_operand" "%r")
4599 (match_operand:DI 2 "gpc_reg_operand" "r"))
4600 (const_int 0)))
4601 (clobber (match_scratch:DI 3 "=r"))]
4602 "TARGET_POWERPC64"
4603 "xor. %3,%1,%2"
4604 [(set_attr "type" "compare")])
1fd4e8c1 4605
266eb58a
DE
4606(define_insn ""
4607 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
4608 (compare:CC (xor:DI (match_operand:DI 1 "gpc_reg_operand" "%r")
4609 (match_operand:DI 2 "gpc_reg_operand" "r"))
4610 (const_int 0)))
4611 (set (match_operand:DI 0 "gpc_reg_operand" "=r")
4612 (xor:DI (match_dup 1) (match_dup 2)))]
4613 "TARGET_POWERPC64"
4614 "xor. %0,%1,%2"
4615 [(set_attr "type" "compare")])
1fd4e8c1 4616
266eb58a
DE
4617;; Split an XOR that we can't do in one insn into two insns, each of which
4618;; does one 16-bit part. This is used by combine.
4619
4620(define_split
4621 [(set (match_operand:DI 0 "gpc_reg_operand" "")
4622 (xor:DI (match_operand:DI 1 "gpc_reg_operand" "")
4623 (match_operand:DI 2 "non_logical_cint_operand" "")))]
4624 "TARGET_POWERPC64"
4625 [(set (match_dup 0) (xor:DI (match_dup 1) (match_dup 3)))
4626 (set (match_dup 0) (xor:DI (match_dup 0) (match_dup 4)))]
4627"
4628{
4629 operands[3] = gen_rtx (CONST_INT, VOIDmode,
4630 INTVAL (operands[2]) & 0xffff0000);
4631 operands[4] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) & 0xffff);
1fd4e8c1
RK
4632}")
4633
2bee0449 4634(define_insn ""
266eb58a
DE
4635 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4636 (not:DI (xor:DI (match_operand:DI 1 "gpc_reg_operand" "%r")
4637 (match_operand:DI 2 "gpc_reg_operand" "r"))))]
4638 "TARGET_POWERPC64"
4639 "eqv %0,%1,%2")
a473029f 4640
266eb58a
DE
4641(define_insn ""
4642 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
4643 (compare:CC (not:DI (xor:DI (match_operand:DI 1 "gpc_reg_operand" "%r")
4644 (match_operand:DI 2 "gpc_reg_operand" "r")))
4645 (const_int 0)))
4646 (clobber (match_scratch:DI 3 "=r"))]
4647 "TARGET_POWERPC64"
4648 "eqv. %3,%1,%2"
4649 [(set_attr "type" "compare")])
a473029f 4650
266eb58a
DE
4651(define_insn ""
4652 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
4653 (compare:CC (not:DI (xor:DI (match_operand:DI 1 "gpc_reg_operand" "%r")
4654 (match_operand:DI 2 "gpc_reg_operand" "r")))
4655 (const_int 0)))
4656 (set (match_operand:DI 0 "gpc_reg_operand" "=r")
4657 (not:DI (xor:DI (match_dup 1) (match_dup 2))))]
4658 "TARGET_POWERPC64"
4659 "eqv. %0,%1,%2"
4660 [(set_attr "type" "compare")])
4661
4662(define_insn ""
a473029f 4663 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
266eb58a
DE
4664 (and:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "r"))
4665 (match_operand:DI 2 "gpc_reg_operand" "r")))]
a473029f 4666 "TARGET_POWERPC64"
266eb58a 4667 "andc %0,%2,%1")
a473029f 4668
266eb58a
DE
4669(define_insn ""
4670 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
4671 (compare:CC (and:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "r"))
4672 (match_operand:DI 2 "gpc_reg_operand" "r"))
4673 (const_int 0)))
4674 (clobber (match_scratch:DI 3 "=r"))]
a473029f 4675 "TARGET_POWERPC64"
266eb58a
DE
4676 "andc. %3,%2,%1"
4677 [(set_attr "type" "compare")])
a473029f 4678
266eb58a
DE
4679(define_insn ""
4680 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
4681 (compare:CC (and:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "r"))
4682 (match_operand:DI 2 "gpc_reg_operand" "r"))
4683 (const_int 0)))
4684 (set (match_operand:DI 0 "gpc_reg_operand" "=r")
4685 (and:DI (not:DI (match_dup 1)) (match_dup 2)))]
a473029f 4686 "TARGET_POWERPC64"
266eb58a
DE
4687 "andc. %0,%2,%1"
4688 [(set_attr "type" "compare")])
a473029f 4689
266eb58a 4690(define_insn ""
a473029f 4691 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
266eb58a
DE
4692 (ior:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "r"))
4693 (match_operand:DI 2 "gpc_reg_operand" "r")))]
a473029f 4694 "TARGET_POWERPC64"
266eb58a 4695 "orc %0,%2,%1")
a473029f 4696
266eb58a
DE
4697(define_insn ""
4698 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
4699 (compare:CC (ior:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "r"))
4700 (match_operand:DI 2 "gpc_reg_operand" "r"))
4701 (const_int 0)))
4702 (clobber (match_scratch:DI 3 "=r"))]
4703 "TARGET_POWERPC64"
4704 "orc. %3,%2,%1"
4705 [(set_attr "type" "compare")])
4706
4707(define_insn ""
4708 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
4709 (compare:CC (ior:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "r"))
4710 (match_operand:DI 2 "gpc_reg_operand" "r"))
4711 (const_int 0)))
4712 (set (match_operand:DI 0 "gpc_reg_operand" "=r")
4713 (ior:DI (not:DI (match_dup 1)) (match_dup 2)))]
4714 "TARGET_POWERPC64"
4715 "orc. %0,%2,%1"
4716 [(set_attr "type" "compare")])
4717
4718(define_insn ""
a473029f 4719 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
266eb58a
DE
4720 (ior:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "%r"))
4721 (not:DI (match_operand:DI 2 "gpc_reg_operand" "r"))))]
a473029f 4722 "TARGET_POWERPC64"
266eb58a 4723 "nand %0,%1,%2")
a473029f 4724
266eb58a
DE
4725(define_insn ""
4726 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
4727 (compare:CC (ior:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "%r"))
4728 (not:DI (match_operand:DI 2 "gpc_reg_operand" "r")))
4729 (const_int 0)))
4730 (clobber (match_scratch:DI 3 "=r"))]
4731 "TARGET_POWERPC64"
4732 "nand. %3,%1,%2"
4733 [(set_attr "type" "compare")])
4734
4735(define_insn ""
4736 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
4737 (compare:CC (ior:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "%r"))
4738 (not:DI (match_operand:DI 2 "gpc_reg_operand" "r")))
4739 (const_int 0)))
4740 (set (match_operand:DI 0 "gpc_reg_operand" "=r")
4741 (ior:DI (not:DI (match_dup 1)) (not:DI (match_dup 2))))]
4742 "TARGET_POWERPC64"
4743 "nand. %0,%1,%2"
4744 [(set_attr "type" "compare")])
4745
4746(define_insn ""
a473029f 4747 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
266eb58a
DE
4748 (and:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "%r"))
4749 (not:DI (match_operand:DI 2 "gpc_reg_operand" "r"))))]
a473029f 4750 "TARGET_POWERPC64"
266eb58a 4751 "nor %0,%1,%2")
a473029f
RK
4752
4753(define_insn ""
4754 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
266eb58a
DE
4755 (compare:CC (and:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "%r"))
4756 (not:DI (match_operand:DI 2 "gpc_reg_operand" "r")))
a473029f
RK
4757 (const_int 0)))
4758 (clobber (match_scratch:DI 3 "=r"))]
4759 "TARGET_POWERPC64"
266eb58a
DE
4760 "nor. %3,%1,%2"
4761 [(set_attr "type" "compare")])
a473029f
RK
4762
4763(define_insn ""
4764 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
266eb58a
DE
4765 (compare:CC (and:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "%r"))
4766 (not:DI (match_operand:DI 2 "gpc_reg_operand" "r")))
a473029f
RK
4767 (const_int 0)))
4768 (set (match_operand:DI 0 "gpc_reg_operand" "=r")
266eb58a 4769 (and:DI (not:DI (match_dup 1)) (not:DI (match_dup 2))))]
a473029f 4770 "TARGET_POWERPC64"
266eb58a
DE
4771 "nor. %0,%1,%2"
4772 [(set_attr "type" "compare")])
a473029f 4773\f
1fd4e8c1 4774;; Now define ways of moving data around.
4697a36c
MM
4775
4776;; Elf specific ways of loading addresses for non-PIC code.
4777;; The output of this could be r0, but we limit it to base
4778;; registers, since almost all uses of this will need it
4779;; in a base register shortly.
4780(define_insn "elf_high"
4781 [(set (match_operand:SI 0 "register_operand" "=b")
4782 (high:SI (match_operand 1 "" "")))]
4783 "TARGET_ELF && !TARGET_64BIT"
4784 "{cau|addis} %0,0,%1@ha")
4785
4786(define_insn "elf_low"
4787 [(set (match_operand:SI 0 "register_operand" "=r")
4788 (lo_sum:SI (match_operand:SI 1 "register_operand" "b")
4789 (match_operand 2 "" "")))]
4790 "TARGET_ELF && !TARGET_64BIT"
4791 "{cal %0,%a2@l(%1)|addi %0,%1,%2@l}")
4792
1fd4e8c1
RK
4793;; For SI, we special-case integers that can't be loaded in one insn. We
4794;; do the load 16-bits at a time. We could do this by loading from memory,
4795;; and this is even supposed to be faster, but it is simpler not to get
4796;; integers in the TOC.
4797(define_expand "movsi"
4798 [(set (match_operand:SI 0 "general_operand" "")
4799 (match_operand:SI 1 "any_operand" ""))]
4800 ""
4801 "
4802{
4803 if (GET_CODE (operands[0]) != REG)
4804 operands[1] = force_reg (SImode, operands[1]);
4805
ef0e171b
RK
4806 /* Convert a move of a CONST_DOUBLE into a CONST_INT */
4807 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4808 operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
4809
88228c4b
MM
4810 /* Use default pattern for address of ELF small data */
4811 if (TARGET_ELF
a54d04b7 4812 && DEFAULT_ABI == ABI_V4
88228c4b 4813 && (GET_CODE (operands[1]) == SYMBOL_REF || GET_CODE (operands[1]) == CONST)
e98bb982 4814 && small_data_operand (operands[1], SImode))
88228c4b
MM
4815 {
4816 emit_insn (gen_rtx (SET, VOIDmode, operands[0], operands[1]));
4817 DONE;
4818 }
4819
4697a36c
MM
4820 if (TARGET_ELF && TARGET_NO_TOC && !TARGET_64BIT
4821 && CONSTANT_P (operands[1])
4822 && GET_CODE (operands[1]) != HIGH
4823 && GET_CODE (operands[1]) != CONST_INT)
4824 {
4825 rtx target = (reload_completed || reload_in_progress)
4826 ? operands[0] : gen_reg_rtx (SImode);
4827
b6c9286a
MM
4828 /* If this is a function address on -mcall-aixdesc or -mcall-nt,
4829 convert it to the address of the descriptor. */
4830 if ((DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_NT)
4831 && GET_CODE (operands[1]) == SYMBOL_REF
4832 && XSTR (operands[1], 0)[0] == '.')
4833 {
4834 char *name = XSTR (operands[1], 0);
4835 rtx new_ref;
4836 while (*name == '.')
4837 name++;
4838 new_ref = gen_rtx (SYMBOL_REF, Pmode, name);
4839 CONSTANT_POOL_ADDRESS_P (new_ref) = CONSTANT_POOL_ADDRESS_P (operands[1]);
4840 SYMBOL_REF_FLAG (new_ref) = SYMBOL_REF_FLAG (operands[1]);
4841 SYMBOL_REF_USED (new_ref) = SYMBOL_REF_USED (operands[1]);
4842 operands[1] = new_ref;
4843 }
4844
4697a36c
MM
4845 emit_insn (gen_elf_high (target, operands[1]));
4846 emit_insn (gen_elf_low (operands[0], target, operands[1]));
4847 DONE;
4848 }
4849
b6c9286a
MM
4850 if (GET_CODE (operands[1]) == CONST
4851 && DEFAULT_ABI == ABI_NT
4852 && !side_effects_p (operands[0]))
4853 {
4854 rtx const_term = const0_rtx;
4855 rtx sym = eliminate_constant_term (XEXP (operands[1], 0), &const_term);
4856 if (sym && GET_CODE (const_term) == CONST_INT
4857 && (GET_CODE (sym) == SYMBOL_REF || GET_CODE (sym) == LABEL_REF))
4858 {
354b734b
MM
4859 unsigned HOST_WIDE_INT value = INTVAL (const_term);
4860 int new_reg_p = (flag_expensive_optimizations
4861 && !reload_completed
4862 && !reload_in_progress);
4863 rtx tmp1 = (new_reg_p && value != 0) ? gen_reg_rtx (SImode) : operands[0];
4864
4865 emit_insn (gen_movsi (tmp1, sym));
b6c9286a
MM
4866 if (INTVAL (const_term) != 0)
4867 {
b6c9286a 4868 if (value + 0x8000 < 0x10000)
354b734b
MM
4869 emit_insn (gen_addsi3 (operands[0], tmp1, GEN_INT (value)));
4870
b6c9286a
MM
4871 else
4872 {
354b734b
MM
4873 HOST_WIDE_INT high_int = value & (~ (HOST_WIDE_INT) 0xffff);
4874 HOST_WIDE_INT low_int = value & 0xffff;
4875 rtx tmp2 = (!new_reg_p || !low_int) ? operands[0] : gen_reg_rtx (Pmode);
4876
4877 if (low_int & 0x8000)
4878 high_int += 0x10000, low_int |= ((HOST_WIDE_INT) -1) << 16;
b6c9286a 4879
354b734b
MM
4880 emit_insn (gen_addsi3 (tmp2, tmp1, GEN_INT (high_int)));
4881 if (low_int)
4882 emit_insn (gen_addsi3 (operands[0], tmp2, GEN_INT (low_int)));
b6c9286a
MM
4883 }
4884 }
4885 DONE;
4886 }
4887 else
4888 fatal_insn (\"bad address\", operands[1]);
4889 }
4890
4891 if ((!TARGET_WINDOWS_NT || DEFAULT_ABI != ABI_NT)
4892 && CONSTANT_P (operands[1])
4697a36c
MM
4893 && GET_CODE (operands[1]) != CONST_INT
4894 && GET_CODE (operands[1]) != HIGH
78b8d850 4895 && ! LEGITIMATE_CONSTANT_POOL_ADDRESS_P (operands[1]))
b45863ec 4896 {
30a4619d
RK
4897 /* If we are to limit the number of things we put in the TOC and
4898 this is a symbol plus a constant we can add in one insn,
abc95ed3 4899 just put the symbol in the TOC and add the constant. Don't do
30a4619d
RK
4900 this if reload is in progress. */
4901 if (GET_CODE (operands[1]) == CONST
4902 && TARGET_NO_SUM_IN_TOC && ! reload_in_progress
4903 && GET_CODE (XEXP (operands[1], 0)) == PLUS
4904 && add_operand (XEXP (XEXP (operands[1], 0), 1), SImode)
4905 && (GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == LABEL_REF
4906 || GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == SYMBOL_REF)
4907 && ! side_effects_p (operands[0]))
4908 {
4909 rtx sym = force_const_mem (SImode, XEXP (XEXP (operands[1], 0), 0));
4910 rtx other = XEXP (XEXP (operands[1], 0), 1);
4911
4912 emit_insn (gen_addsi3 (operands[0], force_reg (SImode, sym), other));
4913 DONE;
4914 }
4915
b45863ec
RK
4916 operands[1] = force_const_mem (SImode, operands[1]);
4917 if (! memory_address_p (SImode, XEXP (operands[1], 0))
4918 && ! reload_in_progress)
4919 operands[1] = change_address (operands[1], SImode,
4920 XEXP (operands[1], 0));
4921 }
1fd4e8c1
RK
4922}")
4923
4924(define_insn ""
88228c4b
MM
4925 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,r,m,r,r,r,r,r,*q,*c*l,*h")
4926 (match_operand:SI 1 "input_operand" "r,S,T,U,m,r,I,J,n,R,*h,r,r,0"))]
19d5775a
RK
4927 "gpc_reg_operand (operands[0], SImode)
4928 || gpc_reg_operand (operands[1], SImode)"
1fd4e8c1 4929 "@
deb9225a 4930 mr %0,%1
b6c9286a
MM
4931 {l|lwz} %0,[toc]%1(2)
4932 {l|lwz} %0,[toc]%l1(2)
b9442c72 4933 {cal|la} %0,%a1
ca7f5001
RK
4934 {l%U1%X1|lwz%U1%X1} %0,%1
4935 {st%U0%X0|stw%U0%X0} %1,%0
19d5775a
RK
4936 {lil|li} %0,%1
4937 {liu|lis} %0,%u1
beaec479 4938 #
57fa6739 4939 {cal|la} %0,%1(%*)
1fd4e8c1 4940 mf%1 %0
5c23c401 4941 mt%0 %1
e76e75bb
RK
4942 mt%0 %1
4943 cror 0,0,0"
88228c4b
MM
4944 [(set_attr "type" "*,load,load,*,load,*,*,*,*,*,*,*,mtjmpr,*")
4945 (set_attr "length" "4,4,4,4,4,4,4,4,8,4,4,4,4,4")])
1fd4e8c1 4946
77fa0940
RK
4947;; Split a load of a large constant into the appropriate two-insn
4948;; sequence.
4949
4950(define_split
4951 [(set (match_operand:SI 0 "gpc_reg_operand" "")
4952 (match_operand:SI 1 "const_int_operand" ""))]
4953 "(unsigned) (INTVAL (operands[1]) + 0x8000) >= 0x10000
4954 && (INTVAL (operands[1]) & 0xffff) != 0"
4955 [(set (match_dup 0)
4956 (match_dup 2))
4957 (set (match_dup 0)
4958 (ior:SI (match_dup 0)
4959 (match_dup 3)))]
4960 "
4961{
4962 operands[2] = gen_rtx (CONST_INT, VOIDmode,
4963 INTVAL (operands[1]) & 0xffff0000);
4964 operands[3] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[1]) & 0xffff);
4965}")
4966
1fd4e8c1
RK
4967(define_insn ""
4968 [(set (match_operand:CC 2 "cc_reg_operand" "=x")
cd2b37d9 4969 (compare:CC (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 4970 (const_int 0)))
cd2b37d9 4971 (set (match_operand:SI 0 "gpc_reg_operand" "=r") (match_dup 1))]
1fd4e8c1 4972 ""
deb9225a 4973 "mr. %0,%1"
1fd4e8c1
RK
4974 [(set_attr "type" "compare")])
4975\f
4976(define_expand "movhi"
4977 [(set (match_operand:HI 0 "general_operand" "")
4978 (match_operand:HI 1 "any_operand" ""))]
4979 ""
4980 "
4981{
4982 if (GET_CODE (operands[0]) != REG)
4983 operands[1] = force_reg (HImode, operands[1]);
4984
4985 if (CONSTANT_P (operands[1]) && GET_CODE (operands[1]) != CONST_INT)
b45863ec
RK
4986 {
4987 operands[1] = force_const_mem (HImode, operands[1]);
4988 if (! memory_address_p (HImode, XEXP (operands[1], 0))
4989 && ! reload_in_progress)
4990 operands[1] = change_address (operands[1], HImode,
4991 XEXP (operands[1], 0));
4992 }
1fd4e8c1
RK
4993}")
4994
4995(define_insn ""
fb81d7ce
RK
4996 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,m,r,r,*q,*c*l,*h")
4997 (match_operand:HI 1 "input_operand" "r,m,r,i,*h,r,r,0"))]
19d5775a
RK
4998 "gpc_reg_operand (operands[0], HImode)
4999 || gpc_reg_operand (operands[1], HImode)"
1fd4e8c1 5000 "@
deb9225a 5001 mr %0,%1
1fd4e8c1
RK
5002 lhz%U1%X1 %0,%1
5003 sth%U0%X0 %1,%0
19d5775a 5004 {lil|li} %0,%w1
1fd4e8c1 5005 mf%1 %0
e76e75bb 5006 mt%0 %1
fb81d7ce 5007 mt%0 %1
e76e75bb 5008 cror 0,0,0"
fb81d7ce 5009 [(set_attr "type" "*,load,*,*,*,*,mtjmpr,*")])
1fd4e8c1
RK
5010
5011(define_expand "movqi"
5012 [(set (match_operand:QI 0 "general_operand" "")
5013 (match_operand:QI 1 "any_operand" ""))]
5014 ""
5015 "
5016{
5017 if (GET_CODE (operands[0]) != REG)
5018 operands[1] = force_reg (QImode, operands[1]);
5019
5020 if (CONSTANT_P (operands[1]) && GET_CODE (operands[1]) != CONST_INT)
b45863ec
RK
5021 {
5022 operands[1] = force_const_mem (QImode, operands[1]);
5023 if (! memory_address_p (QImode, XEXP (operands[1], 0))
5024 && ! reload_in_progress)
5025 operands[1] = change_address (operands[1], QImode,
5026 XEXP (operands[1], 0));
5027 }
1fd4e8c1
RK
5028}")
5029
5030(define_insn ""
fb81d7ce
RK
5031 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m,r,r,*q,*c*l,*h")
5032 (match_operand:QI 1 "input_operand" "r,m,r,i,*h,r,r,0"))]
19d5775a
RK
5033 "gpc_reg_operand (operands[0], QImode)
5034 || gpc_reg_operand (operands[1], QImode)"
1fd4e8c1 5035 "@
deb9225a 5036 mr %0,%1
1fd4e8c1
RK
5037 lbz%U1%X1 %0,%1
5038 stb%U0%X0 %1,%0
19d5775a 5039 {lil|li} %0,%1
1fd4e8c1 5040 mf%1 %0
e76e75bb 5041 mt%0 %1
fb81d7ce 5042 mt%0 %1
e76e75bb 5043 cror 0,0,0"
fb81d7ce 5044 [(set_attr "type" "*,load,*,*,*,*,mtjmpr,*")])
1fd4e8c1
RK
5045\f
5046;; Here is how to move condition codes around. When we store CC data in
5047;; an integer register or memory, we store just the high-order 4 bits.
5048;; This lets us not shift in the most common case of CR0.
5049(define_expand "movcc"
5050 [(set (match_operand:CC 0 "nonimmediate_operand" "")
5051 (match_operand:CC 1 "nonimmediate_operand" ""))]
5052 ""
5053 "")
5054
5055(define_insn ""
5056 [(set (match_operand:CC 0 "nonimmediate_operand" "=y,x,y,r,r,r,r,m")
5057 (match_operand:CC 1 "nonimmediate_operand" "y,r,r,x,y,r,m,r"))]
5058 "register_operand (operands[0], CCmode)
5059 || register_operand (operands[1], CCmode)"
5060 "@
5061 mcrf %0,%1
5062 mtcrf 128,%1
ca7f5001 5063 {rlinm|rlwinm} %1,%1,%F0,0xffffffff\;mtcrf %R0,%1\;{rlinm|rlwinm} %1,%1,%f0,0xffffffff
1fd4e8c1 5064 mfcr %0
ca7f5001 5065 mfcr %0\;{rlinm|rlwinm} %0,%0,%f1,0xf0000000
deb9225a 5066 mr %0,%1
ca7f5001
RK
5067 {l%U1%X1|lwz%U1%X1} %0,%1
5068 {st%U0%U1|stw%U0%U1} %1,%0"
b19003d8
RK
5069 [(set_attr "type" "*,*,*,compare,*,*,load,*")
5070 (set_attr "length" "*,*,12,*,8,*,*,*")])
1fd4e8c1 5071\f
e52e05ca
MM
5072;; For floating-point, we normally deal with the floating-point registers
5073;; unless -msoft-float is used. The sole exception is that parameter passing
5074;; can produce floating-point values in fixed-point registers. Unless the
5075;; value is a simple constant or already in memory, we deal with this by
5076;; allocating memory and copying the value explicitly via that memory location.
1fd4e8c1
RK
5077(define_expand "movsf"
5078 [(set (match_operand:SF 0 "nonimmediate_operand" "")
5079 (match_operand:SF 1 "any_operand" ""))]
5080 ""
5081 "
5082{
5083 /* If we are called from reload, we might be getting a SUBREG of a hard
5084 reg. So expand it. */
5085 if (GET_CODE (operands[0]) == SUBREG
5086 && GET_CODE (SUBREG_REG (operands[0])) == REG
5087 && REGNO (SUBREG_REG (operands[0])) < FIRST_PSEUDO_REGISTER)
5088 operands[0] = alter_subreg (operands[0]);
5089 if (GET_CODE (operands[1]) == SUBREG
5090 && GET_CODE (SUBREG_REG (operands[1])) == REG
5091 && REGNO (SUBREG_REG (operands[1])) < FIRST_PSEUDO_REGISTER)
5092 operands[1] = alter_subreg (operands[1]);
5093
3b7f6cca
MM
5094 if (TARGET_SOFT_FLOAT && GET_CODE (operands[0]) == MEM)
5095 operands[1] = force_reg (SFmode, operands[1]);
5096
5097 else if (TARGET_HARD_FLOAT)
1fd4e8c1 5098 {
e52e05ca 5099 if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) < 32)
1fd4e8c1 5100 {
e52e05ca
MM
5101 /* If this is a store to memory or another integer register do the
5102 move directly. Otherwise store to a temporary stack slot and
5103 load from there into a floating point register. */
5104
5105 if (GET_CODE (operands[0]) == MEM
5106 || (GET_CODE (operands[0]) == REG
5107 && (REGNO (operands[0]) < 32
5108 || (reload_in_progress
5109 && REGNO (operands[0]) >= FIRST_PSEUDO_REGISTER))))
5110 {
5111 emit_move_insn (operand_subword (operands[0], 0, 0, SFmode),
5112 operand_subword (operands[1], 0, 0, SFmode));
5113 DONE;
5114 }
5115 else
5116 {
5117 rtx stack_slot = assign_stack_temp (SFmode, 4, 0);
5118
5119 emit_move_insn (stack_slot, operands[1]);
5120 emit_move_insn (operands[0], stack_slot);
5121 DONE;
5122 }
f6ba0600 5123 }
1fd4e8c1 5124
e52e05ca 5125 if (GET_CODE (operands[0]) == MEM)
f2974b07 5126 {
e52e05ca
MM
5127 /* If operands[1] is a register, it may have double-precision data
5128 in it, so truncate it to single precision. We need not do
5129 this for POWERPC. */
455350f4
RK
5130 if (! TARGET_POWERPC && TARGET_HARD_FLOAT
5131 && GET_CODE (operands[1]) == REG)
e52e05ca 5132 {
455350f4
RK
5133 rtx newreg
5134 = reload_in_progress ? operands[1] : gen_reg_rtx (SFmode);
5135 emit_insn (gen_aux_truncdfsf2 (newreg, operands[1]));
e52e05ca
MM
5136 operands[1] = newreg;
5137 }
5138
5139 operands[1] = force_reg (SFmode, operands[1]);
f2974b07
RK
5140 }
5141
e52e05ca
MM
5142 if (GET_CODE (operands[0]) == REG && REGNO (operands[0]) < 32)
5143 {
5144 if (GET_CODE (operands[1]) == MEM
1fd4e8c1 5145#if HOST_FLOAT_FORMAT == TARGET_FLOAT_FORMAT && ! defined(REAL_IS_NOT_DOUBLE)
e52e05ca 5146 || GET_CODE (operands[1]) == CONST_DOUBLE
1fd4e8c1 5147#endif
e52e05ca
MM
5148 || (GET_CODE (operands[1]) == REG
5149 && (REGNO (operands[1]) < 32
5150 || (reload_in_progress
5151 && REGNO (operands[1]) >= FIRST_PSEUDO_REGISTER))))
5152 {
5153 emit_move_insn (operand_subword (operands[0], 0, 0, SFmode),
5154 operand_subword (operands[1], 0, 0, SFmode));
5155 DONE;
5156 }
5157 else
5158 {
5159 rtx stack_slot = assign_stack_temp (SFmode, 4, 0);
5160
5161 emit_move_insn (stack_slot, operands[1]);
5162 emit_move_insn (operands[0], stack_slot);
5163 DONE;
5164 }
f6ba0600 5165 }
1fd4e8c1
RK
5166 }
5167
5168 if (CONSTANT_P (operands[1]))
5169 {
5170 operands[1] = force_const_mem (SFmode, operands[1]);
5171 if (! memory_address_p (SFmode, XEXP (operands[1], 0))
5172 && ! reload_in_progress)
5173 operands[1] = change_address (operands[1], SFmode,
5174 XEXP (operands[1], 0));
5175 }
5176}")
5177
1fd4e8c1 5178(define_split
cd2b37d9 5179 [(set (match_operand:SF 0 "gpc_reg_operand" "")
1fd4e8c1
RK
5180 (match_operand:SF 1 "easy_fp_constant" ""))]
5181 "reload_completed && REGNO (operands[0]) <= 31"
685f3906
DE
5182 [(set (subreg:SI (match_dup 0) 0) (match_dup 2))]
5183 "
5184{
5185 long l;
5186 REAL_VALUE_TYPE rv;
5187
5188 REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]);
5189 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
5190 operands[2] = GEN_INT(l);
5191}")
7e69e155 5192
1fd4e8c1
RK
5193(define_insn ""
5194 [(set (match_operand:SF 0 "fp_reg_or_mem_operand" "=f,f,m")
5195 (match_operand:SF 1 "input_operand" "f,m,f"))]
d14a6d05
MM
5196 "(gpc_reg_operand (operands[0], SFmode)
5197 || gpc_reg_operand (operands[1], SFmode)) && TARGET_HARD_FLOAT"
1fd4e8c1
RK
5198 "@
5199 fmr %0,%1
5200 lfs%U1%X1 %0,%1
85fff2f3 5201 stfs%U0%X0 %1,%0"
19d5775a 5202 [(set_attr "type" "fp,fpload,*")])
d14a6d05
MM
5203
5204(define_insn ""
5205 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m,r,r,r")
5206 (match_operand:SF 1 "input_operand" "r,m,r,I,J,R"))]
5207 "(gpc_reg_operand (operands[0], SFmode)
5208 || gpc_reg_operand (operands[1], SFmode)) && TARGET_SOFT_FLOAT"
5209 "@
5210 mr %0,%1
5211 {l%U1%X1|lwz%U1%X1} %0,%1
5212 {st%U0%X0|stw%U0%X0} %1,%0
5213 {lil|li} %0,%1
5214 {liu|lis} %0,%u1
5215 {cal|la} %0,%1(%*)"
5216 [(set_attr "type" "*,load,*,*,*,*")])
5217
1fd4e8c1
RK
5218\f
5219(define_expand "movdf"
5220 [(set (match_operand:DF 0 "nonimmediate_operand" "")
5221 (match_operand:DF 1 "any_operand" ""))]
5222 ""
5223 "
5224{
e7113111
RK
5225 if (GET_CODE (operands[0]) != REG)
5226 operands[1] = force_reg (DFmode, operands[1]);
1fd4e8c1 5227
08075ead
DE
5228 /* Stores between FPR and any non-FPR registers must go through a
5229 temporary stack slot. */
5230
5231 if (TARGET_POWERPC64
5232 && GET_CODE (operands[0]) == REG && GET_CODE (operands[1]) == REG
5233 && ((FP_REGNO_P (REGNO (operands[0]))
5234 && ! FP_REGNO_P (REGNO (operands[1])))
5235 || (FP_REGNO_P (REGNO (operands[1]))
5236 && ! FP_REGNO_P (REGNO (operands[0])))))
5237 {
5238 rtx stack_slot = assign_stack_temp (DFmode, 8, 0);
5239
5240 emit_move_insn (stack_slot, operands[1]);
5241 emit_move_insn (operands[0], stack_slot);
5242 DONE;
5243 }
5244
e7113111 5245 if (CONSTANT_P (operands[1]) && ! easy_fp_constant (operands[1], DFmode))
1fd4e8c1
RK
5246 {
5247 operands[1] = force_const_mem (DFmode, operands[1]);
5248 if (! memory_address_p (DFmode, XEXP (operands[1], 0))
5249 && ! reload_in_progress)
5250 operands[1] = change_address (operands[1], DFmode,
5251 XEXP (operands[1], 0));
5252 }
e7113111 5253}")
1fd4e8c1
RK
5254
5255(define_split
cd2b37d9 5256 [(set (match_operand:DF 0 "gpc_reg_operand" "")
1fd4e8c1 5257 (match_operand:DF 1 "easy_fp_constant" ""))]
efc08378 5258 "TARGET_32BIT && reload_completed && REGNO (operands[0]) <= 31"
1fd4e8c1
RK
5259 [(set (match_dup 2) (match_dup 3))
5260 (set (match_dup 4) (match_dup 5))]
5261 "
5262{ operands[2] = operand_subword (operands[0], 0, 0, DFmode);
5263 operands[3] = operand_subword (operands[1], 0, 0, DFmode);
5264 operands[4] = operand_subword (operands[0], 1, 0, DFmode);
5265 operands[5] = operand_subword (operands[1], 1, 0, DFmode); }")
e7113111 5266
efc08378
DE
5267(define_split
5268 [(set (match_operand:DF 0 "gpc_reg_operand" "")
685f3906 5269 (match_operand:DF 1 "easy_fp_constant" ""))]
efc08378
DE
5270 "TARGET_64BIT && reload_completed && REGNO (operands[0]) <= 31"
5271 [(set (subreg:DI (match_dup 0) 0) (subreg:DI (match_dup 1) 0))]
5272 "")
5273
4eae5fe1
RK
5274;; Don't have reload use general registers to load a constant. First,
5275;; it might not work if the output operand has is the equivalent of
5276;; a non-offsettable memref, but also it is less efficient than loading
5277;; the constant into an FP register, since it will probably be used there.
5278;; The "??" is a kludge until we can figure out a more reasonable way
5279;; of handling these non-offsettable values.
5280(define_insn ""
5281 [(set (match_operand:DF 0 "nonimmediate_operand" "=!r,??r,o,!r,f,f,m")
e7113111 5282 (match_operand:DF 1 "input_operand" "r,o,r,G,f,m,f"))]
dc4f83ca
MM
5283 "! TARGET_POWERPC64 && TARGET_HARD_FLOAT
5284 && (register_operand (operands[0], DFmode)
5285 || register_operand (operands[1], DFmode))"
e7113111
RK
5286 "*
5287{
5288 switch (which_alternative)
5289 {
5290 case 0:
5291 /* We normally copy the low-numbered register first. However, if
5292 the first register operand 0 is the same as the second register of
5293 operand 1, we must copy in the opposite order. */
5294 if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
deb9225a 5295 return \"mr %L0,%L1\;mr %0,%1\";
e7113111 5296 else
deb9225a 5297 return \"mr %0,%1\;mr %L0,%L1\";
e7113111
RK
5298 case 1:
5299 /* If the low-address word is used in the address, we must load it
5300 last. Otherwise, load it first. Note that we cannot have
5301 auto-increment in that case since the address register is known to be
5302 dead. */
5303 if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
5304 operands [1], 0))
ca7f5001 5305 return \"{l|lwz} %L0,%L1\;{l|lwz} %0,%1\";
e7113111 5306 else
ca7f5001 5307 return \"{l%U1|lwz%U1} %0,%1\;{l|lwz} %L0,%L1\";
e7113111 5308 case 2:
ca7f5001 5309 return \"{st%U0|stw%U0} %1,%0\;{st|stw} %L1,%L0\";
e7113111
RK
5310 case 3:
5311 return \"#\";
5312 case 4:
5313 return \"fmr %0,%1\";
5314 case 5:
5315 return \"lfd%U1%X1 %0,%1\";
5316 case 6:
5317 return \"stfd%U0%X0 %1,%0\";
5318 }
5319}"
ca7f5001 5320 [(set_attr "type" "*,load,*,*,fp,fpload,*")
e7113111 5321 (set_attr "length" "8,8,8,8,*,*,*")])
51b8fc2c 5322
dc4f83ca
MM
5323(define_insn ""
5324 [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,o,r")
5325 (match_operand:DF 1 "input_operand" "r,o,r,G"))]
5326 "! TARGET_POWERPC64 && TARGET_SOFT_FLOAT
5327 && (register_operand (operands[0], DFmode)
5328 || register_operand (operands[1], DFmode))"
5329 "*
5330{
5331 switch (which_alternative)
5332 {
5333 case 0:
5334 /* We normally copy the low-numbered register first. However, if
5335 the first register operand 0 is the same as the second register of
5336 operand 1, we must copy in the opposite order. */
5337 if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
5338 return \"mr %L0,%L1\;mr %0,%1\";
5339 else
5340 return \"mr %0,%1\;mr %L0,%L1\";
5341 case 1:
5342 /* If the low-address word is used in the address, we must load it
5343 last. Otherwise, load it first. Note that we cannot have
5344 auto-increment in that case since the address register is known to be
5345 dead. */
5346 if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
5347 operands [1], 0))
5348 return \"{l|lwz} %L0,%L1\;{l|lwz} %0,%1\";
5349 else
5350 return \"{l%U1|lwz%U1} %0,%1\;{l|lwz} %L0,%L1\";
5351 case 2:
5352 return \"{st%U0|stw%U0} %1,%0\;{st|stw} %L1,%L0\";
5353 case 3:
5354 return \"#\";
5355 }
5356}"
5357 [(set_attr "type" "*,load,*,*")
5358 (set_attr "length" "8,8,8,8")])
5359
51b8fc2c
RK
5360(define_insn ""
5361 [(set (match_operand:DF 0 "nonimmediate_operand" "=!r,??r,o,!r,f,f,m")
5362 (match_operand:DF 1 "input_operand" "r,o,r,G,f,m,f"))]
dc4f83ca
MM
5363 "TARGET_POWERPC64 && TARGET_HARD_FLOAT
5364 && (register_operand (operands[0], DFmode)
5365 || register_operand (operands[1], DFmode))"
51b8fc2c 5366 "@
3d5570cb
RK
5367 mr %0,%1
5368 ld%U1%X1 %0,%1
96bb8ed3 5369 std%U0%X0 %1,%0
3d5570cb
RK
5370 #
5371 fmr %0,%1
f63184ac 5372 lfd%U1%X1 %0,%1
3d5570cb 5373 stfd%U0%X0 %1,%0"
51b8fc2c 5374 [(set_attr "type" "*,load,*,*,fp,fpload,*")])
dc4f83ca
MM
5375
5376(define_insn ""
5377 [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,o,r")
5378 (match_operand:DF 1 "input_operand" "r,o,r,G"))]
5379 "TARGET_POWERPC64 && TARGET_SOFT_FLOAT
5380 && (register_operand (operands[0], DFmode)
5381 || register_operand (operands[1], DFmode))"
5382 "@
5383 mr %0,%1
5384 ld%U1%X1 %0,%1
96bb8ed3 5385 std%U0%X0 %1,%0
dc4f83ca
MM
5386 #"
5387 [(set_attr "type" "*,load,*,*")])
1fd4e8c1
RK
5388\f
5389;; Next come the multi-word integer load and store and the load and store
5390;; multiple insns.
5391(define_expand "movdi"
5392 [(set (match_operand:DI 0 "general_operand" "")
e6ca2c17 5393 (match_operand:DI 1 "any_operand" ""))]
1fd4e8c1
RK
5394 ""
5395 "
5396{
e6ca2c17
DE
5397 if (! TARGET_64BIT && ! general_operand (operands[1], DImode))
5398 FAIL;
5399
5400 if (GET_CODE (operands[0]) != REG)
6b6ccd10
RK
5401 operands[1] = force_reg (DImode, operands[1]);
5402
062284d8
RK
5403 if (GET_CODE (operands[1]) == CONST_DOUBLE
5404 || GET_CODE (operands[1]) == CONST_INT)
1fd4e8c1 5405 {
6b6ccd10
RK
5406 HOST_WIDE_INT low;
5407 HOST_WIDE_INT high;
5408
5409 if (GET_CODE (operands[1]) == CONST_DOUBLE)
5410 {
5411 low = CONST_DOUBLE_LOW (operands[1]);
5412 high = CONST_DOUBLE_HIGH (operands[1]);
5413 }
e8d791dd
DE
5414 else
5415#if HOST_BITS_PER_WIDE_INT == 32
6b6ccd10
RK
5416 {
5417 low = INTVAL (operands[1]);
5418 high = (low < 0) ? ~0 : 0;
5419 }
e8d791dd 5420#else
e6ca2c17
DE
5421 {
5422 low = INTVAL (operands[1]) & 0xffffffff;
f4558646 5423 high = (HOST_WIDE_INT) INTVAL (operands[1]) >> 32;
e6ca2c17 5424 }
e8d791dd 5425#endif
6b6ccd10 5426
e6ca2c17
DE
5427 if (! TARGET_POWERPC64)
5428 {
5429 emit_move_insn (gen_rtx (SUBREG, SImode, operands[0],
5430 WORDS_BIG_ENDIAN), GEN_INT (low));
6b6ccd10 5431
e6ca2c17
DE
5432 emit_move_insn (gen_rtx (SUBREG, SImode, operands[0],
5433 ! WORDS_BIG_ENDIAN), GEN_INT (high));
5434 DONE;
5435 }
5436 else
5437 {
5438 if (high + 0x8000 >= 0x10000)
5439 {
5440 emit_move_insn (gen_rtx (SUBREG, SImode, operands[0], 1),
5441 GEN_INT (high));
5442 emit_insn (gen_ashldi3 (operands[0], operands[0], GEN_INT(32)));
5443 if (low)
5444 {
5445 HOST_WIDE_INT low_low = low & 0xffff;
5446 HOST_WIDE_INT low_high = low & (~ (HOST_WIDE_INT) 0xffff);
5447 if (low_high)
5448 emit_insn (gen_iordi3 (operands[0], operands[0],
5449 GEN_INT (low_high)));
5450 if (low_low)
5451 emit_insn (gen_iordi3 (operands[0], operands[0],
5452 GEN_INT (low_low)));
5453 }
5454 }
5455 else if (low)
5456 emit_move_insn (gen_rtx (SUBREG, SImode, operands[0], 1),
5457 GEN_INT (low));
5458 DONE;
5459 }
1fd4e8c1 5460 }
062284d8 5461
a473029f
RK
5462 /* Stores between FPR and any non-FPR registers must go through a
5463 temporary stack slot. */
5464
5465 if (GET_CODE (operands[0]) == REG && GET_CODE (operands[1]) == REG
5466 && ((FP_REGNO_P (REGNO (operands[0]))
5467 && ! FP_REGNO_P (REGNO (operands[1])))
5468 || (FP_REGNO_P (REGNO (operands[1]))
5469 && ! FP_REGNO_P (REGNO (operands[0])))))
5470 {
425c176f 5471 rtx stack_slot = assign_stack_temp (DImode, 8, 0);
a473029f 5472
a473029f
RK
5473 emit_move_insn (stack_slot, operands[1]);
5474 emit_move_insn (operands[0], stack_slot);
5475 DONE;
5476 }
1fd4e8c1
RK
5477}")
5478
5479(define_insn ""
8ffd9c51
RK
5480 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m,f,f,m")
5481 (match_operand:DI 1 "input_operand" "r,m,r,f,m,f"))]
51b8fc2c
RK
5482 "! TARGET_POWERPC64 && (gpc_reg_operand (operands[0], DImode)
5483 || gpc_reg_operand (operands[1], DImode))"
1fd4e8c1
RK
5484 "*
5485{
5486 switch (which_alternative)
5487 {
5488 case 0:
5489 /* We normally copy the low-numbered register first. However, if
5490 the first register operand 0 is the same as the second register of
5491 operand 1, we must copy in the opposite order. */
5492 if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
deb9225a 5493 return \"mr %L0,%L1\;mr %0,%1\";
1fd4e8c1 5494 else
deb9225a 5495 return \"mr %0,%1\;mr %L0,%L1\";
1fd4e8c1
RK
5496 case 1:
5497 /* If the low-address word is used in the address, we must load it
5498 last. Otherwise, load it first. Note that we cannot have
5499 auto-increment in that case since the address register is known to be
5500 dead. */
5501 if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
5502 operands [1], 0))
ca7f5001 5503 return \"{l|lwz} %L0,%L1\;{l|lwz} %0,%1\";
1fd4e8c1 5504 else
ca7f5001 5505 return \"{l%U1|lwz%U1} %0,%1\;{l|lwz} %L0,%L1\";
1fd4e8c1 5506 case 2:
ca7f5001 5507 return \"{st%U0|stw%U0} %1,%0\;{st|stw} %L1,%L0\";
8ffd9c51
RK
5508 case 3:
5509 return \"fmr %0,%1\";
5510 case 4:
5511 return \"lfd%U1%X1 %0,%1\";
5512 case 5:
5513 return \"stfd%U0%X0 %1,%0\";
1fd4e8c1
RK
5514 }
5515}"
8ffd9c51
RK
5516 [(set_attr "type" "*,load,*,fp,fpload,*")
5517 (set_attr "length" "8,8,8,*,*,*")])
51b8fc2c
RK
5518
5519(define_insn ""
e6ca2c17
DE
5520 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m,r,r,r,r,f,f,m,r,*h,*h")
5521 (match_operand:DI 1 "input_operand" "r,m,r,I,J,n,R,f,m,f,*h,r,0"))]
51b8fc2c
RK
5522 "TARGET_POWERPC64 && (gpc_reg_operand (operands[0], DImode)
5523 || gpc_reg_operand (operands[1], DImode))"
5524 "@
3d5570cb
RK
5525 mr %0,%1
5526 ld%U1%X1 %0,%1
96bb8ed3 5527 std%U0%X0 %1,%0
3d5570cb
RK
5528 li %0,%1
5529 lis %0,%u1
e6ca2c17 5530 #
57fa6739 5531 {cal|la} %0,%1(%*)
3d5570cb
RK
5532 fmr %0,%1
5533 lfd%U1%X1 %0,%1
5534 stfd%U0%X0 %1,%0
5535 mf%1 %0
08075ead
DE
5536 mt%0 %1
5537 cror 0,0,0"
e6ca2c17
DE
5538 [(set_attr "type" "*,load,*,*,*,*,*,fp,fpload,*,*,mtjmpr,*")
5539 (set_attr "length" "4,4,4,4,4,20,4,4,4,4,4,4,4")])
5540
5541;; Split a load of a large constant into the appropriate five-instruction
5542;; sequence. The expansion in movdi tries to perform the minimum number of
5543;; steps, but here we have to handle anything in a constant number of insns.
5544
5545(define_split
5546 [(set (match_operand:DI 0 "gpc_reg_operand" "")
5547 (match_operand:DI 1 "const_double_operand" ""))]
5548 "TARGET_POWERPC64"
5549 [(set (match_dup 0)
5550 (match_dup 2))
5551 (set (match_dup 0)
5552 (ior:DI (match_dup 0)
5553 (match_dup 3)))
5554 (set (match_dup 0)
5555 (ashift:DI (match_dup 0)
5556 (const_int 32)))
5557 (set (match_dup 0)
5558 (ior:DI (match_dup 0)
5559 (match_dup 4)))
5560 (set (match_dup 0)
5561 (ior:DI (match_dup 0)
5562 (match_dup 5)))]
5563 "
5564{
5565 HOST_WIDE_INT low;
5566 HOST_WIDE_INT high;
5567
5568 if (GET_CODE (operands[1]) == CONST_DOUBLE)
5569 {
5570 low = CONST_DOUBLE_LOW (operands[1]);
5571 high = CONST_DOUBLE_HIGH (operands[1]);
5572 }
e8d791dd
DE
5573 else
5574#if HOST_BITS_PER_WIDE_INT == 32
e6ca2c17
DE
5575 {
5576 low = INTVAL (operands[1]);
5577 high = (low < 0) ? ~0 : 0;
5578 }
e8d791dd 5579#else
e6ca2c17
DE
5580 {
5581 low = INTVAL (operands[1]) & 0xffffffff;
f4558646 5582 high = (HOST_WIDE_INT) INTVAL (operands[1]) >> 32;
e6ca2c17 5583 }
e8d791dd 5584#endif
e6ca2c17
DE
5585
5586 if ((high + 0x8000) < 0x10000
5587 && ((low & 0xffff) == 0 || (low & (~ (HOST_WIDE_INT) 0xffff)) == 0))
5588 FAIL;
5589
5590 operands[2] = GEN_INT (high & (~ (HOST_WIDE_INT) 0xffff));
5591 operands[3] = GEN_INT (high & 0xffff);
5592 operands[4] = GEN_INT (low & (~ (HOST_WIDE_INT) 0xffff));
5593 operands[5] = GEN_INT (low & 0xffff);
5594}")
08075ead
DE
5595
5596(define_insn ""
5597 [(set (match_operand:CC 2 "cc_reg_operand" "=x")
5598 (compare:CC (match_operand:DI 1 "gpc_reg_operand" "r")
5599 (const_int 0)))
5600 (set (match_operand:DI 0 "gpc_reg_operand" "=r") (match_dup 1))]
5601 "TARGET_POWERPC64"
5602 "mr. %0,%1"
5603 [(set_attr "type" "compare")])
1fd4e8c1
RK
5604\f
5605;; TImode is similar, except that we usually want to compute the address into
5606;; a register and use lsi/stsi (the exception is during reload). MQ is also
ca7f5001 5607;; clobbered in stsi for POWER, so we need a SCRATCH for it.
1fd4e8c1
RK
5608(define_expand "movti"
5609 [(parallel [(set (match_operand:TI 0 "general_operand" "")
5610 (match_operand:TI 1 "general_operand" ""))
5611 (clobber (scratch:SI))])]
7e69e155 5612 "TARGET_STRING || TARGET_POWERPC64"
1fd4e8c1
RK
5613 "
5614{
5615 if (GET_CODE (operands[0]) == MEM)
5616 operands[1] = force_reg (TImode, operands[1]);
5617
5618 if (GET_CODE (operands[0]) == MEM
5619 && GET_CODE (XEXP (operands[0], 0)) != REG
5620 && ! reload_in_progress)
5621 operands[0] = change_address (operands[0], TImode,
5622 copy_addr_to_reg (XEXP (operands[0], 0)));
5623
5624 if (GET_CODE (operands[1]) == MEM
5625 && GET_CODE (XEXP (operands[1], 0)) != REG
5626 && ! reload_in_progress)
5627 operands[1] = change_address (operands[1], TImode,
5628 copy_addr_to_reg (XEXP (operands[1], 0)));
5629}")
5630
5631;; We say that MQ is clobbered in the last alternative because the first
5632;; alternative would never get used otherwise since it would need a reload
5633;; while the 2nd alternative would not. We put memory cases first so they
5634;; are preferred. Otherwise, we'd try to reload the output instead of
5635;; giving the SCRATCH mq.
5636(define_insn ""
e1469d0d 5637 [(set (match_operand:TI 0 "reg_or_mem_operand" "=Q,m,????r,????r,????r")
1fd4e8c1
RK
5638 (match_operand:TI 1 "reg_or_mem_operand" "r,r,r,Q,m"))
5639 (clobber (match_scratch:SI 2 "=q,q#X,X,X,X"))]
7e69e155 5640 "TARGET_STRING && TARGET_POWER && ! TARGET_POWERPC64
dc4f83ca 5641 && (gpc_reg_operand (operands[0], TImode) || gpc_reg_operand (operands[1], TImode))"
1fd4e8c1
RK
5642 "*
5643{
5644 switch (which_alternative)
5645 {
dc4f83ca
MM
5646 default:
5647 abort ();
5648
1fd4e8c1 5649 case 0:
ca7f5001 5650 return \"{stsi|stswi} %1,%P0,16\";
1fd4e8c1
RK
5651
5652 case 1:
ca7f5001 5653 return \"{st%U0|stw%U0} %1,%0\;{st|stw} %L1,%L0\;{st|stw} %Y1,%Y0\;{st|stw} %Z1,%Z0\";
1fd4e8c1
RK
5654
5655 case 2:
5656 /* Normally copy registers with lowest numbered register copied first.
5657 But copy in the other order if the first register of the output
5658 is the second, third, or fourth register in the input. */
5659 if (REGNO (operands[0]) >= REGNO (operands[1]) + 1
5660 && REGNO (operands[0]) <= REGNO (operands[1]) + 3)
deb9225a 5661 return \"mr %Z0,%Z1\;mr %Y0,%Y1\;mr %L0,%L1\;mr %0,%1\";
1fd4e8c1 5662 else
deb9225a 5663 return \"mr %0,%1\;mr %L0,%L1\;mr %Y0,%Y1\;mr %Z0,%Z1\";
1fd4e8c1
RK
5664 case 3:
5665 /* If the address is not used in the output, we can use lsi. Otherwise,
5666 fall through to generating four loads. */
5667 if (! reg_overlap_mentioned_p (operands[0], operands[1]))
ca7f5001 5668 return \"{lsi|lswi} %0,%P1,16\";
1fd4e8c1
RK
5669 /* ... fall through ... */
5670 case 4:
5671 /* If the address register is the same as the register for the lowest-
5672 addressed word, load it last. Similarly for the next two words.
5673 Otherwise load lowest address to highest. */
5674 if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
5675 operands[1], 0))
ca7f5001 5676 return \"{l|lwz} %L0,%L1\;{l|lwz} %Y0,%Y1\;{l|lwz} %Z0,%Z1\;{l|lwz} %0,%1\";
1fd4e8c1
RK
5677 else if (refers_to_regno_p (REGNO (operands[0]) + 1,
5678 REGNO (operands[0]) + 2, operands[1], 0))
ca7f5001 5679 return \"{l|lwz} %0,%1\;{l|lwz} %Y0,%Y1\;{l|lwz} %Z0,%Z1\;{l|lwz} %L0,%L1\";
1fd4e8c1
RK
5680 else if (refers_to_regno_p (REGNO (operands[0]) + 2,
5681 REGNO (operands[0]) + 3, operands[1], 0))
ca7f5001 5682 return \"{l|lwz} %0,%1\;{l|lwz} %L0,%L1\;{l|lwz} %Z0,%Z1\;{l|lwz} %Y0,%Y1\";
1fd4e8c1 5683 else
ca7f5001 5684 return \"{l%U1|lwz%U1} %0,%1\;{l|lwz} %L0,%L1\;{l|lwz} %Y0,%Y1\;{l|lwz} %Z0,%Z1\";
1fd4e8c1
RK
5685 }
5686}"
b19003d8
RK
5687 [(set_attr "type" "*,load,load,*,*")
5688 (set_attr "length" "*,16,16,*,16")])
51b8fc2c 5689
dc4f83ca
MM
5690(define_insn ""
5691 [(set (match_operand:TI 0 "reg_or_mem_operand" "=m,????r,????r")
5692 (match_operand:TI 1 "reg_or_mem_operand" "r,r,m"))
5693 (clobber (match_scratch:SI 2 "=X,X,X"))]
7e69e155 5694 "TARGET_STRING && !TARGET_POWER && ! TARGET_POWERPC64
dc4f83ca
MM
5695 && (gpc_reg_operand (operands[0], TImode) || gpc_reg_operand (operands[1], TImode))"
5696 "*
5697{
5698 switch (which_alternative)
5699 {
5700 default:
5701 abort ();
5702
5703 case 0:
5704 return \"{st%U0|stw%U0} %1,%0\;{st|stw} %L1,%L0\;{st|stw} %Y1,%Y0\;{st|stw} %Z1,%Z0\";
5705
5706 case 1:
5707 /* Normally copy registers with lowest numbered register copied first.
5708 But copy in the other order if the first register of the output
5709 is the second, third, or fourth register in the input. */
5710 if (REGNO (operands[0]) >= REGNO (operands[1]) + 1
5711 && REGNO (operands[0]) <= REGNO (operands[1]) + 3)
5712 return \"mr %Z0,%Z1\;mr %Y0,%Y1\;mr %L0,%L1\;mr %0,%1\";
5713 else
5714 return \"mr %0,%1\;mr %L0,%L1\;mr %Y0,%Y1\;mr %Z0,%Z1\";
5715 case 2:
5716 /* If the address register is the same as the register for the lowest-
5717 addressed word, load it last. Similarly for the next two words.
5718 Otherwise load lowest address to highest. */
5719 if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
5720 operands[1], 0))
5721 return \"{l|lwz} %L0,%L1\;{l|lwz} %Y0,%Y1\;{l|lwz} %Z0,%Z1\;{l|lwz} %0,%1\";
5722 else if (refers_to_regno_p (REGNO (operands[0]) + 1,
5723 REGNO (operands[0]) + 2, operands[1], 0))
5724 return \"{l|lwz} %0,%1\;{l|lwz} %Y0,%Y1\;{l|lwz} %Z0,%Z1\;{l|lwz} %L0,%L1\";
5725 else if (refers_to_regno_p (REGNO (operands[0]) + 2,
5726 REGNO (operands[0]) + 3, operands[1], 0))
5727 return \"{l|lwz} %0,%1\;{l|lwz} %L0,%L1\;{l|lwz} %Z0,%Z1\;{l|lwz} %Y0,%Y1\";
5728 else
5729 return \"{l%U1|lwz%U1} %0,%1\;{l|lwz} %L0,%L1\;{l|lwz} %Y0,%Y1\;{l|lwz} %Z0,%Z1\";
5730 }
5731}"
5732 [(set_attr "type" "load,*,*")
5733 (set_attr "length" "16,16,16")])
5734
51b8fc2c
RK
5735(define_insn ""
5736 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,r,m")
5737 (match_operand:TI 1 "input_operand" "r,m,r"))]
5738 "TARGET_POWERPC64 && (gpc_reg_operand (operands[0], TImode)
5739 || gpc_reg_operand (operands[1], TImode))"
5740 "*
5741{
5742 switch (which_alternative)
5743 {
5744 case 0:
5745 /* We normally copy the low-numbered register first. However, if
5746 the first register operand 0 is the same as the second register of
5747 operand 1, we must copy in the opposite order. */
5748 if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
5749 return \"mr %L0,%L1\;mr %0,%1\";
5750 else
5751 return \"mr %0,%1\;mr %L0,%L1\";
5752 case 1:
5753 /* If the low-address word is used in the address, we must load it
5754 last. Otherwise, load it first. Note that we cannot have
5755 auto-increment in that case since the address register is known to be
5756 dead. */
5757 if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
5758 operands [1], 0))
5759 return \"ld %L0,%L1\;ld %0,%1\";
5760 else
5761 return \"ld%U1 %0,%1\;ld %L0,%L1\";
5762 case 2:
5763 return \"std%U0 %1,%0\;std %L1,%L0\";
5764 }
5765}"
5766 [(set_attr "type" "*,load,*")
5767 (set_attr "length" "8,8,8")])
1fd4e8c1
RK
5768\f
5769(define_expand "load_multiple"
2f622005
RK
5770 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
5771 (match_operand:SI 1 "" ""))
5772 (use (match_operand:SI 2 "" ""))])]
7e69e155 5773 "TARGET_STRING"
1fd4e8c1
RK
5774 "
5775{
5776 int regno;
5777 int count;
5778 rtx from;
5779 int i;
5780
5781 /* Support only loading a constant number of fixed-point registers from
5782 memory and only bother with this if more than two; the machine
5783 doesn't support more than eight. */
5784 if (GET_CODE (operands[2]) != CONST_INT
5785 || INTVAL (operands[2]) <= 2
5786 || INTVAL (operands[2]) > 8
5787 || GET_CODE (operands[1]) != MEM
5788 || GET_CODE (operands[0]) != REG
5789 || REGNO (operands[0]) >= 32)
5790 FAIL;
5791
5792 count = INTVAL (operands[2]);
5793 regno = REGNO (operands[0]);
5794
5795 operands[3] = gen_rtx (PARALLEL, VOIDmode, rtvec_alloc (count));
5796 from = force_reg (SImode, XEXP (operands[1], 0));
5797
5798 for (i = 0; i < count; i++)
5799 XVECEXP (operands[3], 0, i)
5800 = gen_rtx (SET, VOIDmode, gen_rtx (REG, SImode, regno + i),
5801 gen_rtx (MEM, SImode, plus_constant (from, i * 4)));
5802}")
5803
5804(define_insn ""
5805 [(match_parallel 0 "load_multiple_operation"
cd2b37d9 5806 [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
4c99e795 5807 (mem:SI (match_operand:SI 2 "register_operand" "b")))])]
7e69e155 5808 "TARGET_STRING"
1fd4e8c1
RK
5809 "*
5810{
5811 /* We have to handle the case where the pseudo used to contain the address
e82ee4cc
RK
5812 is assigned to one of the output registers. */
5813 int i, j;
5814 int words = XVECLEN (operands[0], 0);
5815 rtx xop[10];
5816
5817 if (XVECLEN (operands[0], 0) == 1)
5818 return \"{l|lwz} %1,0(%2)\";
1fd4e8c1 5819
e82ee4cc 5820 for (i = 0; i < words; i++)
1fd4e8c1
RK
5821 if (refers_to_regno_p (REGNO (operands[1]) + i,
5822 REGNO (operands[1]) + i + 1, operands[2], 0))
5823 {
e82ee4cc
RK
5824 if (i == words-1)
5825 {
5826 xop[0] = operands[1];
5827 xop[1] = operands[2];
5828 xop[2] = GEN_INT (4 * (words-1));
d89ddcfd 5829 output_asm_insn (\"{lsi|lswi} %0,%1,%2\;{l|lwz} %1,%2(%1)\", xop);
e82ee4cc
RK
5830 return \"\";
5831 }
5832 else if (i == 0)
5833 {
5834 xop[0] = operands[1];
5835 xop[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1);
5836 xop[2] = GEN_INT (4 * (words-1));
5837 output_asm_insn (\"{cal %0,4(%0)|addi %0,%0,4}\;{lsi|lswi} %1,%0,%2\;{l|lwz} %0,-4(%0)\", xop);
5838 return \"\";
5839 }
5840 else
5841 {
5842 for (j = 0; j < words; j++)
5843 if (j != i)
5844 {
5845 xop[0] = gen_rtx (REG, SImode, REGNO (operands[1]) + j);
5846 xop[1] = operands[2];
5847 xop[2] = GEN_INT (j * 4);
5848 output_asm_insn (\"{l|lwz} %0,%2(%1)\", xop);
5849 }
5850 xop[0] = operands[2];
5851 xop[1] = GEN_INT (i * 4);
5852 output_asm_insn (\"{l|lwz} %0,%1(%0)\", xop);
5853 return \"\";
5854 }
1fd4e8c1
RK
5855 }
5856
e82ee4cc 5857 return \"{lsi|lswi} %1,%2,%N0\";
1fd4e8c1 5858}"
b19003d8 5859 [(set_attr "type" "load")
e82ee4cc 5860 (set_attr "length" "32")])
1fd4e8c1 5861\f
b19003d8 5862
1fd4e8c1 5863(define_expand "store_multiple"
2f622005
RK
5864 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
5865 (match_operand:SI 1 "" ""))
5866 (clobber (scratch:SI))
5867 (use (match_operand:SI 2 "" ""))])]
7e69e155 5868 "TARGET_STRING"
1fd4e8c1
RK
5869 "
5870{
5871 int regno;
5872 int count;
5873 rtx to;
5874 int i;
5875
5876 /* Support only storing a constant number of fixed-point registers to
5877 memory and only bother with this if more than two; the machine
5878 doesn't support more than eight. */
5879 if (GET_CODE (operands[2]) != CONST_INT
5880 || INTVAL (operands[2]) <= 2
5881 || INTVAL (operands[2]) > 8
5882 || GET_CODE (operands[0]) != MEM
5883 || GET_CODE (operands[1]) != REG
5884 || REGNO (operands[1]) >= 32)
5885 FAIL;
5886
5887 count = INTVAL (operands[2]);
5888 regno = REGNO (operands[1]);
5889
5890 operands[3] = gen_rtx (PARALLEL, VOIDmode, rtvec_alloc (count + 1));
5891 to = force_reg (SImode, XEXP (operands[0], 0));
5892
5893 XVECEXP (operands[3], 0, 0)
5894 = gen_rtx (SET, VOIDmode, gen_rtx (MEM, SImode, to), operands[1]);
5895 XVECEXP (operands[3], 0, 1) = gen_rtx (CLOBBER, VOIDmode,
5896 gen_rtx (SCRATCH, SImode));
5897
5898 for (i = 1; i < count; i++)
5899 XVECEXP (operands[3], 0, i + 1)
5900 = gen_rtx (SET, VOIDmode,
5901 gen_rtx (MEM, SImode, plus_constant (to, i * 4)),
5902 gen_rtx (REG, SImode, regno + i));
5903}")
5904
5905(define_insn ""
5906 [(match_parallel 0 "store_multiple_operation"
5907 [(set (match_operand:SI 1 "indirect_operand" "=Q")
cd2b37d9 5908 (match_operand:SI 2 "gpc_reg_operand" "r"))
1fd4e8c1 5909 (clobber (match_scratch:SI 3 "=q"))])]
7e69e155 5910 "TARGET_STRING && TARGET_POWER"
d14a6d05
MM
5911 "{stsi|stswi} %2,%P1,%O0")
5912
5913(define_insn ""
5914 [(match_parallel 0 "store_multiple_operation"
4c99e795 5915 [(set (mem:SI (match_operand:SI 1 "register_operand" "b"))
d14a6d05
MM
5916 (match_operand:SI 2 "gpc_reg_operand" "r"))
5917 (clobber (match_scratch:SI 3 "X"))])]
7e69e155 5918 "TARGET_STRING && !TARGET_POWER"
4c99e795 5919 "{stsi|stswi} %2,%1,%O0")
7e69e155
MM
5920
5921\f
5922;; String/block move insn.
5923;; Argument 0 is the destination
5924;; Argument 1 is the source
5925;; Argument 2 is the length
5926;; Argument 3 is the alignment
5927
5928(define_expand "movstrsi"
b6c9286a
MM
5929 [(parallel [(set (match_operand:BLK 0 "" "")
5930 (match_operand:BLK 1 "" ""))
5931 (use (match_operand:SI 2 "" ""))
5932 (use (match_operand:SI 3 "" ""))])]
7e69e155
MM
5933 ""
5934 "
5935{
5936 if (expand_block_move (operands))
5937 DONE;
5938 else
5939 FAIL;
5940}")
5941
5942;; Move up to 32 bytes at a time. The fixed registers are needed because the
5943;; register allocator doesn't have a clue about allocating 8 word registers
5944(define_expand "movstrsi_8reg"
b6c9286a
MM
5945 [(parallel [(set (match_operand 0 "" "")
5946 (match_operand 1 "" ""))
5947 (use (match_operand 2 "" ""))
5948 (use (match_operand 3 "" ""))
7e69e155
MM
5949 (clobber (reg:SI 5))
5950 (clobber (reg:SI 6))
5951 (clobber (reg:SI 7))
5952 (clobber (reg:SI 8))
5953 (clobber (reg:SI 9))
5954 (clobber (reg:SI 10))
5955 (clobber (reg:SI 11))
5956 (clobber (reg:SI 12))
3c67b673 5957 (clobber (match_scratch:SI 4 ""))])]
7e69e155
MM
5958 "TARGET_STRING"
5959 "")
5960
5961(define_insn ""
3c67b673
RK
5962 [(set (mem:BLK (match_operand:SI 0 "register_operand" "b"))
5963 (mem:BLK (match_operand:SI 1 "register_operand" "b")))
5964 (use (match_operand:SI 2 "immediate_operand" "i"))
5965 (use (match_operand:SI 3 "immediate_operand" "i"))
5966 (clobber (match_operand:SI 4 "register_operand" "=r"))
7e69e155
MM
5967 (clobber (reg:SI 6))
5968 (clobber (reg:SI 7))
5969 (clobber (reg:SI 8))
5970 (clobber (reg:SI 9))
5971 (clobber (reg:SI 10))
5972 (clobber (reg:SI 11))
5973 (clobber (reg:SI 12))
3c67b673 5974 (clobber (match_scratch:SI 5 "=q"))]
7e69e155
MM
5975 "TARGET_STRING && TARGET_POWER
5976 && ((INTVAL (operands[2]) > 24 && INTVAL (operands[2]) < 32) || INTVAL (operands[2]) == 0)
5977 && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 12)
5978 && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 12)
3c67b673
RK
5979 && REGNO (operands[4]) == 5"
5980 "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2"
5981 [(set_attr "length" "8")])
7e69e155
MM
5982
5983(define_insn ""
3c67b673
RK
5984 [(set (mem:BLK (match_operand:SI 0 "register_operand" "b"))
5985 (mem:BLK (match_operand:SI 1 "register_operand" "b")))
5986 (use (match_operand:SI 2 "immediate_operand" "i"))
5987 (use (match_operand:SI 3 "immediate_operand" "i"))
5988 (clobber (match_operand:SI 4 "register_operand" "=r"))
7e69e155
MM
5989 (clobber (reg:SI 6))
5990 (clobber (reg:SI 7))
5991 (clobber (reg:SI 8))
5992 (clobber (reg:SI 9))
5993 (clobber (reg:SI 10))
5994 (clobber (reg:SI 11))
5995 (clobber (reg:SI 12))
3c67b673 5996 (clobber (match_scratch:SI 5 "X"))]
7e69e155
MM
5997 "TARGET_STRING && !TARGET_POWER
5998 && ((INTVAL (operands[2]) > 24 && INTVAL (operands[2]) < 32) || INTVAL (operands[2]) == 0)
5999 && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 12)
6000 && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 12)
3c67b673
RK
6001 && REGNO (operands[4]) == 5"
6002 "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2"
6003 [(set_attr "length" "8")])
7e69e155
MM
6004
6005;; Move up to 24 bytes at a time. The fixed registers are needed because the
6006;; register allocator doesn't have a clue about allocating 6 word registers
6007(define_expand "movstrsi_6reg"
b6c9286a
MM
6008 [(parallel [(set (match_operand 0 "" "")
6009 (match_operand 1 "" ""))
6010 (use (match_operand 2 "" ""))
6011 (use (match_operand 3 "" ""))
7e69e155
MM
6012 (clobber (reg:SI 7))
6013 (clobber (reg:SI 8))
6014 (clobber (reg:SI 9))
6015 (clobber (reg:SI 10))
6016 (clobber (reg:SI 11))
6017 (clobber (reg:SI 12))
3c67b673 6018 (clobber (match_scratch:SI 4 ""))])]
7e69e155
MM
6019 "TARGET_STRING"
6020 "")
6021
6022(define_insn ""
3c67b673
RK
6023 [(set (mem:BLK (match_operand:SI 0 "register_operand" "b"))
6024 (mem:BLK (match_operand:SI 1 "register_operand" "b")))
6025 (use (match_operand:SI 2 "immediate_operand" "i"))
6026 (use (match_operand:SI 3 "immediate_operand" "i"))
6027 (clobber (match_operand:SI 4 "register_operand" "=r"))
7e69e155
MM
6028 (clobber (reg:SI 8))
6029 (clobber (reg:SI 9))
6030 (clobber (reg:SI 10))
6031 (clobber (reg:SI 11))
6032 (clobber (reg:SI 12))
3c67b673 6033 (clobber (match_scratch:SI 5 "=q"))]
7e69e155
MM
6034 "TARGET_STRING && TARGET_POWER
6035 && INTVAL (operands[2]) > 16 && INTVAL (operands[2]) <= 24
6036 && (REGNO (operands[0]) < 7 || REGNO (operands[0]) > 12)
6037 && (REGNO (operands[1]) < 7 || REGNO (operands[1]) > 12)
3c67b673
RK
6038 && REGNO (operands[4]) == 7"
6039 "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2"
6040 [(set_attr "length" "8")])
7e69e155
MM
6041
6042(define_insn ""
3c67b673
RK
6043 [(set (mem:BLK (match_operand:SI 0 "register_operand" "b"))
6044 (mem:BLK (match_operand:SI 1 "register_operand" "b")))
6045 (use (match_operand:SI 2 "immediate_operand" "i"))
6046 (use (match_operand:SI 3 "immediate_operand" "i"))
6047 (clobber (match_operand:SI 4 "register_operand" "=r"))
7e69e155
MM
6048 (clobber (reg:SI 8))
6049 (clobber (reg:SI 9))
6050 (clobber (reg:SI 10))
6051 (clobber (reg:SI 11))
6052 (clobber (reg:SI 12))
3c67b673 6053 (clobber (match_scratch:SI 5 "X"))]
7e69e155
MM
6054 "TARGET_STRING && !TARGET_POWER
6055 && INTVAL (operands[2]) > 16 && INTVAL (operands[2]) <= 32
6056 && (REGNO (operands[0]) < 7 || REGNO (operands[0]) > 12)
6057 && (REGNO (operands[1]) < 7 || REGNO (operands[1]) > 12)
3c67b673
RK
6058 && REGNO (operands[4]) == 7"
6059 "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2"
6060 [(set_attr "length" "8")])
7e69e155
MM
6061
6062;; Move up to 16 bytes at a time, using 4 fixed registers to avoid spill problems
6063;; with TImode
6064(define_expand "movstrsi_4reg"
b6c9286a
MM
6065 [(parallel [(set (match_operand 0 "" "")
6066 (match_operand 1 "" ""))
6067 (use (match_operand 2 "" ""))
6068 (use (match_operand 3 "" ""))
7e69e155
MM
6069 (clobber (reg:SI 9))
6070 (clobber (reg:SI 10))
6071 (clobber (reg:SI 11))
6072 (clobber (reg:SI 12))
3c67b673 6073 (clobber (match_scratch:SI 4 ""))])]
7e69e155
MM
6074 "TARGET_STRING"
6075 "")
6076
6077(define_insn ""
3c67b673
RK
6078 [(set (mem:BLK (match_operand:SI 0 "register_operand" "b"))
6079 (mem:BLK (match_operand:SI 1 "register_operand" "b")))
6080 (use (match_operand:SI 2 "immediate_operand" "i"))
6081 (use (match_operand:SI 3 "immediate_operand" "i"))
6082 (clobber (match_operand:SI 4 "register_operand" "=r"))
7e69e155
MM
6083 (clobber (reg:SI 10))
6084 (clobber (reg:SI 11))
6085 (clobber (reg:SI 12))
3c67b673 6086 (clobber (match_scratch:SI 5 "=q"))]
7e69e155
MM
6087 "TARGET_STRING && TARGET_POWER
6088 && INTVAL (operands[2]) > 8 && INTVAL (operands[2]) <= 16
6089 && (REGNO (operands[0]) < 9 || REGNO (operands[0]) > 12)
6090 && (REGNO (operands[1]) < 9 || REGNO (operands[1]) > 12)
3c67b673
RK
6091 && REGNO (operands[4]) == 9"
6092 "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2"
6093 [(set_attr "length" "8")])
7e69e155
MM
6094
6095(define_insn ""
3c67b673
RK
6096 [(set (mem:BLK (match_operand:SI 0 "register_operand" "b"))
6097 (mem:BLK (match_operand:SI 1 "register_operand" "b")))
6098 (use (match_operand:SI 2 "immediate_operand" "i"))
6099 (use (match_operand:SI 3 "immediate_operand" "i"))
6100 (clobber (match_operand:SI 4 "register_operand" "=r"))
7e69e155
MM
6101 (clobber (reg:SI 10))
6102 (clobber (reg:SI 11))
6103 (clobber (reg:SI 12))
3c67b673 6104 (clobber (match_scratch:SI 5 "X"))]
7e69e155
MM
6105 "TARGET_STRING && !TARGET_POWER
6106 && INTVAL (operands[2]) > 8 && INTVAL (operands[2]) <= 16
6107 && (REGNO (operands[0]) < 9 || REGNO (operands[0]) > 12)
6108 && (REGNO (operands[1]) < 9 || REGNO (operands[1]) > 12)
3c67b673
RK
6109 && REGNO (operands[4]) == 9"
6110 "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2"
6111 [(set_attr "length" "8")])
7e69e155
MM
6112
6113;; Move up to 8 bytes at a time.
6114(define_expand "movstrsi_2reg"
b6c9286a
MM
6115 [(parallel [(set (match_operand 0 "" "")
6116 (match_operand 1 "" ""))
6117 (use (match_operand 2 "" ""))
6118 (use (match_operand 3 "" ""))
3c67b673
RK
6119 (clobber (match_scratch:DI 4 ""))
6120 (clobber (match_scratch:SI 5 ""))])]
7e69e155
MM
6121 "TARGET_STRING && !TARGET_64BIT"
6122 "")
6123
6124(define_insn ""
3c67b673
RK
6125 [(set (mem:BLK (match_operand:SI 0 "register_operand" "b"))
6126 (mem:BLK (match_operand:SI 1 "register_operand" "b")))
6127 (use (match_operand:SI 2 "immediate_operand" "i"))
6128 (use (match_operand:SI 3 "immediate_operand" "i"))
6129 (clobber (match_scratch:DI 4 "=&r"))
6130 (clobber (match_scratch:SI 5 "=q"))]
7e69e155 6131 "TARGET_STRING && TARGET_POWER && !TARGET_64BIT
3c67b673
RK
6132 && INTVAL (operands[2]) > 4 && INTVAL (operands[2]) <= 8"
6133 "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2"
6134 [(set_attr "length" "8")])
7e69e155
MM
6135
6136(define_insn ""
3c67b673
RK
6137 [(set (mem:BLK (match_operand:SI 0 "register_operand" "b"))
6138 (mem:BLK (match_operand:SI 1 "register_operand" "b")))
6139 (use (match_operand:SI 2 "immediate_operand" "i"))
6140 (use (match_operand:SI 3 "immediate_operand" "i"))
6141 (clobber (match_scratch:DI 4 "=&r"))
6142 (clobber (match_scratch:SI 5 "X"))]
7e69e155
MM
6143 "TARGET_STRING && !TARGET_POWER && !TARGET_64BIT
6144 && INTVAL (operands[2]) > 4 && INTVAL (operands[2]) <= 8"
3c67b673
RK
6145 "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2"
6146 [(set_attr "length" "8")])
7e69e155
MM
6147
6148;; Move up to 4 bytes at a time.
6149(define_expand "movstrsi_1reg"
b6c9286a
MM
6150 [(parallel [(set (match_operand 0 "" "")
6151 (match_operand 1 "" ""))
6152 (use (match_operand 2 "" ""))
6153 (use (match_operand 3 "" ""))
3c67b673
RK
6154 (clobber (match_scratch:SI 4 ""))
6155 (clobber (match_scratch:SI 5 ""))])]
7e69e155
MM
6156 "TARGET_STRING"
6157 "")
6158
6159(define_insn ""
3c67b673
RK
6160 [(set (mem:BLK (match_operand:SI 0 "register_operand" "b"))
6161 (mem:BLK (match_operand:SI 1 "register_operand" "b")))
6162 (use (match_operand:SI 2 "immediate_operand" "i"))
6163 (use (match_operand:SI 3 "immediate_operand" "i"))
6164 (clobber (match_scratch:SI 4 "=&r"))
6165 (clobber (match_scratch:SI 5 "=q"))]
7e69e155
MM
6166 "TARGET_STRING && TARGET_POWER
6167 && INTVAL (operands[2]) > 0 && INTVAL (operands[2]) <= 4"
3c67b673
RK
6168 "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2"
6169 [(set_attr "length" "8")])
7e69e155
MM
6170
6171(define_insn ""
3c67b673
RK
6172 [(set (mem:BLK (match_operand:SI 0 "register_operand" "b"))
6173 (mem:BLK (match_operand:SI 1 "register_operand" "b")))
6174 (use (match_operand:SI 2 "immediate_operand" "i"))
6175 (use (match_operand:SI 3 "immediate_operand" "i"))
6176 (clobber (match_scratch:SI 4 "=&r"))
6177 (clobber (match_scratch:SI 5 "X"))]
7e69e155
MM
6178 "TARGET_STRING && !TARGET_POWER
6179 && INTVAL (operands[2]) > 0 && INTVAL (operands[2]) <= 4"
3c67b673
RK
6180 "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2"
6181 [(set_attr "length" "8")])
7e69e155 6182
1fd4e8c1 6183\f
7e69e155 6184;; Define insns that do load or store with update. Some of these we can
1fd4e8c1
RK
6185;; get by using pre-decrement or pre-increment, but the hardware can also
6186;; do cases where the increment is not the size of the object.
6187;;
6188;; In all these cases, we use operands 0 and 1 for the register being
6189;; incremented because those are the operands that local-alloc will
6190;; tie and these are the pair most likely to be tieable (and the ones
6191;; that will benefit the most).
6192
51b8fc2c
RK
6193(define_insn ""
6194 [(set (match_operand:DI 3 "gpc_reg_operand" "=r,r")
ad8bd902 6195 (mem:DI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0,0")
51b8fc2c
RK
6196 (match_operand:DI 2 "reg_or_short_operand" "r,I"))))
6197 (set (match_operand:DI 0 "gpc_reg_operand" "=b,b")
6198 (plus:DI (match_dup 1) (match_dup 2)))]
6199 "TARGET_POWERPC64"
6200 "@
6201 ldux %3,%0,%2
6202 ldu %3,%2(%0)"
6203 [(set_attr "type" "load")])
6204
287f13ff
RK
6205(define_insn ""
6206 [(set (match_operand:DI 3 "gpc_reg_operand" "=r")
6207 (sign_extend:DI
6208 (mem:SI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0")
6209 (match_operand:DI 2 "gpc_reg_operand" "r")))))
6210 (set (match_operand:DI 0 "gpc_reg_operand" "=b")
6211 (plus:DI (match_dup 1) (match_dup 2)))]
6212 "TARGET_POWERPC64"
6213 "lwaux %3,%0,%2"
6214 [(set_attr "type" "load")])
6215
4697a36c 6216(define_insn "movdi_update"
51b8fc2c
RK
6217 [(set (mem:DI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0,0")
6218 (match_operand:DI 2 "reg_or_short_operand" "r,I")))
6219 (match_operand:DI 3 "gpc_reg_operand" "r,r"))
6220 (set (match_operand:DI 0 "gpc_reg_operand" "=b,b")
6221 (plus:DI (match_dup 1) (match_dup 2)))]
6222 "TARGET_POWERPC64"
6223 "@
6224 stdux %3,%0,%2
6225 stdu %3,%2(%0)")
6226
1fd4e8c1 6227(define_insn ""
cd2b37d9
RK
6228 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
6229 (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
1fd4e8c1 6230 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
cd2b37d9 6231 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
1fd4e8c1
RK
6232 (plus:SI (match_dup 1) (match_dup 2)))]
6233 ""
6234 "@
ca7f5001
RK
6235 {lux|lwzux} %3,%0,%2
6236 {lu|lwzu} %3,%2(%0)"
cfb557c4 6237 [(set_attr "type" "load")])
1fd4e8c1 6238
4697a36c 6239(define_insn "movsi_update"
cd2b37d9 6240 [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
1fd4e8c1 6241 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
cd2b37d9
RK
6242 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
6243 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
1fd4e8c1
RK
6244 (plus:SI (match_dup 1) (match_dup 2)))]
6245 ""
6246 "@
ca7f5001
RK
6247 {stux|stwux} %3,%0,%2
6248 {stu|stwu} %3,%2(%0)")
1fd4e8c1
RK
6249
6250(define_insn ""
cd2b37d9
RK
6251 [(set (match_operand:HI 3 "gpc_reg_operand" "=r,r")
6252 (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
1fd4e8c1 6253 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
cd2b37d9 6254 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
1fd4e8c1
RK
6255 (plus:SI (match_dup 1) (match_dup 2)))]
6256 ""
6257 "@
5f243543
RK
6258 lhzux %3,%0,%2
6259 lhzu %3,%2(%0)"
cfb557c4 6260 [(set_attr "type" "load")])
1fd4e8c1
RK
6261
6262(define_insn ""
cd2b37d9 6263 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
1fd4e8c1 6264 (zero_extend:SI
cd2b37d9 6265 (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
1fd4e8c1 6266 (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
cd2b37d9 6267 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
1fd4e8c1
RK
6268 (plus:SI (match_dup 1) (match_dup 2)))]
6269 ""
6270 "@
5f243543
RK
6271 lhzux %3,%0,%2
6272 lhzu %3,%2(%0)"
cfb557c4 6273 [(set_attr "type" "load")])
1fd4e8c1
RK
6274
6275(define_insn ""
cd2b37d9 6276 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
1fd4e8c1 6277 (sign_extend:SI
cd2b37d9 6278 (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
1fd4e8c1 6279 (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
cd2b37d9 6280 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
1fd4e8c1
RK
6281 (plus:SI (match_dup 1) (match_dup 2)))]
6282 ""
6283 "@
5f243543
RK
6284 lhaux %3,%0,%2
6285 lhau %3,%2(%0)"
cfb557c4 6286 [(set_attr "type" "load")])
1fd4e8c1
RK
6287
6288(define_insn ""
cd2b37d9 6289 [(set (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
1fd4e8c1 6290 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
cd2b37d9
RK
6291 (match_operand:HI 3 "gpc_reg_operand" "r,r"))
6292 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
1fd4e8c1
RK
6293 (plus:SI (match_dup 1) (match_dup 2)))]
6294 ""
6295 "@
5f243543 6296 sthux %3,%0,%2
cfb557c4 6297 sthu %3,%2(%0)")
1fd4e8c1
RK
6298
6299(define_insn ""
cd2b37d9
RK
6300 [(set (match_operand:QI 3 "gpc_reg_operand" "=r,r")
6301 (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
1fd4e8c1 6302 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
cd2b37d9 6303 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
1fd4e8c1
RK
6304 (plus:SI (match_dup 1) (match_dup 2)))]
6305 ""
6306 "@
5f243543
RK
6307 lbzux %3,%0,%2
6308 lbzu %3,%2(%0)"
cfb557c4 6309 [(set_attr "type" "load")])
1fd4e8c1
RK
6310
6311(define_insn ""
cd2b37d9 6312 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
1fd4e8c1 6313 (zero_extend:SI
cd2b37d9 6314 (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
1fd4e8c1 6315 (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
cd2b37d9 6316 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
1fd4e8c1
RK
6317 (plus:SI (match_dup 1) (match_dup 2)))]
6318 ""
6319 "@
5f243543
RK
6320 lbzux %3,%0,%2
6321 lbzu %3,%2(%0)"
cfb557c4 6322 [(set_attr "type" "load")])
1fd4e8c1
RK
6323
6324(define_insn ""
cd2b37d9 6325 [(set (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
1fd4e8c1 6326 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
cd2b37d9
RK
6327 (match_operand:QI 3 "gpc_reg_operand" "r,r"))
6328 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
1fd4e8c1
RK
6329 (plus:SI (match_dup 1) (match_dup 2)))]
6330 ""
6331 "@
5f243543
RK
6332 stbux %3,%0,%2
6333 stbu %3,%2(%0)")
1fd4e8c1
RK
6334
6335(define_insn ""
cd2b37d9 6336 [(set (match_operand:SF 3 "gpc_reg_operand" "=f,f")
df8b713c 6337 (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
1fd4e8c1 6338 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
cd2b37d9 6339 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
1fd4e8c1 6340 (plus:SI (match_dup 1) (match_dup 2)))]
d14a6d05 6341 "TARGET_HARD_FLOAT"
1fd4e8c1 6342 "@
5f243543
RK
6343 lfsux %3,%0,%2
6344 lfsu %3,%2(%0)"
cfb557c4 6345 [(set_attr "type" "fpload")])
1fd4e8c1
RK
6346
6347(define_insn ""
cd2b37d9 6348 [(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
1fd4e8c1 6349 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
cd2b37d9
RK
6350 (match_operand:SF 3 "gpc_reg_operand" "f,f"))
6351 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
1fd4e8c1 6352 (plus:SI (match_dup 1) (match_dup 2)))]
d14a6d05 6353 "TARGET_HARD_FLOAT"
1fd4e8c1 6354 "@
85fff2f3
RK
6355 stfsux %3,%0,%2
6356 stfsu %3,%2(%0)")
1fd4e8c1
RK
6357
6358(define_insn ""
cd2b37d9
RK
6359 [(set (match_operand:DF 3 "gpc_reg_operand" "=f,f")
6360 (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
1fd4e8c1 6361 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
cd2b37d9 6362 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
1fd4e8c1 6363 (plus:SI (match_dup 1) (match_dup 2)))]
d14a6d05 6364 "TARGET_HARD_FLOAT"
1fd4e8c1 6365 "@
5f243543
RK
6366 lfdux %3,%0,%2
6367 lfdu %3,%2(%0)"
cfb557c4 6368 [(set_attr "type" "fpload")])
1fd4e8c1
RK
6369
6370(define_insn ""
cd2b37d9 6371 [(set (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
1fd4e8c1 6372 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
cd2b37d9
RK
6373 (match_operand:DF 3 "gpc_reg_operand" "f,f"))
6374 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
1fd4e8c1 6375 (plus:SI (match_dup 1) (match_dup 2)))]
d14a6d05 6376 "TARGET_HARD_FLOAT"
1fd4e8c1 6377 "@
5f243543
RK
6378 stfdux %3,%0,%2
6379 stfdu %3,%2(%0)")
4c70a4f3
RK
6380
6381;; Peephole to convert two consecutive FP loads or stores into lfq/stfq.
6382
6383(define_peephole
6384 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
6385 (match_operand:DF 1 "memory_operand" ""))
6386 (set (match_operand:DF 2 "gpc_reg_operand" "=f")
6387 (match_operand:DF 3 "memory_operand" ""))]
6388 "TARGET_POWER2
d14a6d05 6389 && TARGET_HARD_FLOAT
4c70a4f3
RK
6390 && registers_ok_for_quad_peep (operands[0], operands[2])
6391 && ! MEM_VOLATILE_P (operands[1]) && ! MEM_VOLATILE_P (operands[3])
6392 && addrs_ok_for_quad_peep (XEXP (operands[1], 0), XEXP (operands[3], 0))"
6393 "lfq%U1%X1 %0,%1")
6394
6395(define_peephole
6396 [(set (match_operand:DF 0 "memory_operand" "")
6397 (match_operand:DF 1 "gpc_reg_operand" "f"))
6398 (set (match_operand:DF 2 "memory_operand" "")
6399 (match_operand:DF 3 "gpc_reg_operand" "f"))]
6400 "TARGET_POWER2
d14a6d05 6401 && TARGET_HARD_FLOAT
4c70a4f3
RK
6402 && registers_ok_for_quad_peep (operands[1], operands[3])
6403 && ! MEM_VOLATILE_P (operands[0]) && ! MEM_VOLATILE_P (operands[2])
6404 && addrs_ok_for_quad_peep (XEXP (operands[0], 0), XEXP (operands[2], 0))"
6405 "stfq%U0%X0 %1,%0")
1fd4e8c1
RK
6406\f
6407;; Next come insns related to the calling sequence.
6408;;
6409;; First, an insn to allocate new stack space for dynamic use (e.g., alloca).
7e69e155 6410;; We move the back-chain and decrement the stack pointer.
1fd4e8c1
RK
6411
6412(define_expand "allocate_stack"
6413 [(set (reg:SI 1)
01def764 6414 (minus:SI (reg:SI 1) (match_operand:SI 0 "reg_or_short_operand" "")))]
1fd4e8c1
RK
6415 ""
6416 "
4697a36c 6417{ rtx chain = gen_reg_rtx (Pmode);
1fd4e8c1 6418 rtx stack_bot = gen_rtx (MEM, Pmode, stack_pointer_rtx);
4697a36c 6419 rtx neg_op0;
1fd4e8c1
RK
6420
6421 emit_move_insn (chain, stack_bot);
4697a36c 6422
979721f8
MM
6423 /* Under Windows NT, we need to add stack probes for large/variable allocations,
6424 so do it via a call to the external function alloca, instead of doing it
6425 inline. */
6426 if (DEFAULT_ABI == ABI_NT
6427 && (GET_CODE (operands[0]) != CONST_INT || INTVAL (operands[0]) > 4096))
6428 {
cea05fab
MM
6429 rtx tmp = gen_reg_rtx (SImode);
6430 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"__allocate_stack\"),
6431 tmp, 0, SImode, 1, operands[0], Pmode);
6432 emit_insn (gen_set_sp (tmp));
979721f8
MM
6433 DONE;
6434 }
6435
4697a36c
MM
6436 if (GET_CODE (operands[0]) != CONST_INT
6437 || INTVAL (operands[0]) < -32767
6438 || INTVAL (operands[0]) > 32768)
6439 {
6440 neg_op0 = gen_reg_rtx (Pmode);
e6ca2c17 6441 if (TARGET_32BIT)
4697a36c 6442 emit_insn (gen_negsi2 (neg_op0, operands[0]));
e6ca2c17
DE
6443 else
6444 emit_insn (gen_negdi2 (neg_op0, operands[0]));
4697a36c
MM
6445 }
6446 else
6447 neg_op0 = GEN_INT (- INTVAL (operands[0]));
6448
e6ca2c17 6449 if (TARGET_32BIT)
4697a36c 6450 emit_insn (gen_movsi_update (stack_pointer_rtx, stack_pointer_rtx, neg_op0, chain));
e6ca2c17
DE
6451 else
6452 emit_insn (gen_movdi_update (stack_pointer_rtx, stack_pointer_rtx, neg_op0, chain));
4697a36c 6453
1fd4e8c1
RK
6454 DONE;
6455}")
59257ff7 6456
cea05fab
MM
6457;; Marker to indicate that the stack pointer was changed under NT in
6458;; ways not known to the compiler
6459
6460(define_insn "set_sp"
6461 [(set (reg:SI 1)
6462 (unspec [(match_operand:SI 0 "register_operand" "r")] 7))]
6463 ""
6464 ""
6465 [(set_attr "length" "0")])
6466
59257ff7
RK
6467;; These patterns say how to save and restore the stack pointer. We need not
6468;; save the stack pointer at function level since we are careful to
6469;; preserve the backchain. At block level, we have to restore the backchain
6470;; when we restore the stack pointer.
6471;;
6472;; For nonlocal gotos, we must save both the stack pointer and its
6473;; backchain and restore both. Note that in the nonlocal case, the
6474;; save area is a memory location.
6475
6476(define_expand "save_stack_function"
6477 [(use (const_int 0))]
6478 ""
6479 "")
6480
6481(define_expand "restore_stack_function"
6482 [(use (const_int 0))]
6483 ""
6484 "")
6485
6486(define_expand "restore_stack_block"
6487 [(set (match_dup 2) (mem:SI (match_operand:SI 0 "register_operand" "")))
6488 (set (match_dup 0) (match_operand:SI 1 "register_operand" ""))
6489 (set (mem:SI (match_dup 0)) (match_dup 2))]
6490 ""
6491 "
6492{ operands[2] = gen_reg_rtx (SImode); }")
6493
6494(define_expand "save_stack_nonlocal"
6495 [(match_operand:DI 0 "memory_operand" "")
6496 (match_operand:SI 1 "register_operand" "")]
6497 ""
6498 "
6499{
6500 rtx temp = gen_reg_rtx (SImode);
6501
6502 /* Copy the backchain to the first word, sp to the second. */
6503 emit_move_insn (temp, gen_rtx (MEM, SImode, operands[1]));
6504 emit_move_insn (operand_subword (operands[0], 0, 0, DImode), temp);
6505 emit_move_insn (operand_subword (operands[0], 1, 0, DImode), operands[1]);
6506 DONE;
6507}")
7e69e155 6508
59257ff7
RK
6509(define_expand "restore_stack_nonlocal"
6510 [(match_operand:SI 0 "register_operand" "")
6511 (match_operand:DI 1 "memory_operand" "")]
6512 ""
6513 "
6514{
6515 rtx temp = gen_reg_rtx (SImode);
6516
6517 /* Restore the backchain from the first word, sp from the second. */
6518 emit_move_insn (temp, operand_subword (operands[1], 0, 0, DImode));
6519 emit_move_insn (operands[0], operand_subword (operands[1], 1, 0, DImode));
6520 emit_move_insn (gen_rtx (MEM, SImode, operands[0]), temp);
6521 DONE;
6522}")
1fd4e8c1 6523\f
b6c9286a
MM
6524
6525;; A function pointer under AIX is a pointer to a data area whose first word
6526;; contains the actual address of the function, whose second word contains a
6527;; pointer to its TOC, and whose third word contains a value to place in the
6528;; static chain register (r11). Note that if we load the static chain, our
1fd4e8c1
RK
6529;; "trampoline" need not have any executable code.
6530;;
b6c9286a
MM
6531;; operands[0] is a register pointing to the 3 word descriptor (aka, the function address)
6532;; operands[1] is the stack size to clean up
6533;; operands[2] is the value FUNCTION_ARG returns for the VOID argument (must be 0 for AIX)
6534;; operands[3] is location to store the TOC
6535;; operands[4] is the TOC register
6536;; operands[5] is the static chain register
6537;;
6538;; We do not break this into separate insns, so that the scheduler will not try
6539;; to move the load of the new TOC before any loads from the TOC.
6540
6541(define_insn "call_indirect_aix"
6542 [(call (mem:SI (match_operand:SI 0 "register_operand" "b"))
6543 (match_operand 1 "const_int_operand" "n"))
6a4cee5f 6544 (use (match_operand 2 "const_int_operand" "n"))
b6c9286a
MM
6545 (use (match_operand 3 "offsettable_addr_operand" "p"))
6546 (use (match_operand 4 "register_operand" "r"))
6547 (clobber (match_operand 5 "register_operand" "=r"))
6548 (clobber (match_scratch:SI 6 "=&r"))
6549 (clobber (match_scratch:SI 7 "=l"))]
6a4cee5f
MM
6550 "DEFAULT_ABI == ABI_AIX
6551 && (INTVAL (operands[2]) == CALL_NORMAL || (INTVAL (operands[2]) & CALL_LONG) != 0)"
6552 "{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"
b6c9286a
MM
6553 [(set_attr "length" "28")])
6554
6555(define_insn "call_value_indirect_aix"
6556 [(set (match_operand 0 "register_operand" "fg")
6557 (call (mem:SI (match_operand:SI 1 "register_operand" "b"))
6558 (match_operand 2 "const_int_operand" "n")))
6a4cee5f 6559 (use (match_operand 3 "const_int_operand" "n"))
b6c9286a
MM
6560 (use (match_operand 4 "offsettable_addr_operand" "p"))
6561 (use (match_operand 5 "register_operand" "r"))
6562 (clobber (match_operand 6 "register_operand" "=r"))
6563 (clobber (match_scratch:SI 7 "=&r"))
6564 (clobber (match_scratch:SI 8 "=l"))]
6a4cee5f
MM
6565 "DEFAULT_ABI == ABI_AIX
6566 && (INTVAL (operands[3]) == CALL_NORMAL || (INTVAL (operands[3]) & CALL_LONG) != 0)"
b6c9286a
MM
6567 "{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"
6568 [(set_attr "length" "28")])
6569
6570;; A function pointer undef NT is a pointer to a data area whose first word
6571;; contains the actual address of the function, whose second word contains a
6572;; pointer to its TOC. The static chain is not stored under NT, which means
6573;; that we need a trampoline.
6574;;
6575;; operands[0] is an SImode pseudo in which we place the address of the function.
6576;; operands[1] is the stack size to clean up
6577;; operands[2] is the value FUNCTION_ARG returns for the VOID argument (must be 0 for NT)
6578;; operands[3] is location to store the TOC
6579;; operands[4] is the TOC register
6580;;
6581;; We do not break this into separate insns, so that the scheduler will not try
6582;; to move the load of the new TOC before any loads from the TOC.
6583
6584(define_insn "call_indirect_nt"
6585 [(call (mem:SI (match_operand:SI 0 "register_operand" "b"))
6586 (match_operand 1 "const_int_operand" "n"))
6a4cee5f 6587 (use (match_operand 2 "const_int_operand" "n"))
b6c9286a
MM
6588 (use (match_operand 3 "offsettable_addr_operand" "p"))
6589 (use (match_operand 4 "register_operand" "r"))
6590 (clobber (match_scratch:SI 5 "=&r"))
6591 (clobber (match_scratch:SI 6 "=l"))]
6a4cee5f
MM
6592 "DEFAULT_ABI == ABI_NT
6593 && (INTVAL (operands[2]) == CALL_NORMAL || (INTVAL (operands[2]) & CALL_LONG) != 0)"
e1f83b4d 6594 "{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
6595 [(set_attr "length" "24")])
6596
6597(define_insn "call_value_indirect_nt"
6598 [(set (match_operand 0 "register_operand" "fg")
6599 (call (mem:SI (match_operand:SI 1 "register_operand" "b"))
6600 (match_operand 2 "const_int_operand" "n")))
6a4cee5f 6601 (use (match_operand 3 "const_int_operand" "n"))
b6c9286a
MM
6602 (use (match_operand 4 "offsettable_addr_operand" "p"))
6603 (use (match_operand 5 "register_operand" "r"))
6604 (clobber (match_scratch:SI 6 "=&r"))
6605 (clobber (match_scratch:SI 7 "=l"))]
6a4cee5f
MM
6606 "DEFAULT_ABI == ABI_NT
6607 && (INTVAL (operands[3]) == CALL_NORMAL || (INTVAL (operands[3]) & CALL_LONG) != 0)"
e1f83b4d 6608 "{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
6609 [(set_attr "length" "24")])
6610
6611;; A function pointer under System V is just a normal pointer
6612;; operands[0] is the function pointer
6613;; operands[1] is the stack size to clean up
6614;; operands[2] is the value FUNCTION_ARG returns for the VOID argument which indicates how to set cr1
6615
6616(define_insn "call_indirect_sysv"
6617 [(call (mem:SI (match_operand:SI 0 "register_operand" "l,l"))
6618 (match_operand 1 "const_int_operand" "n,n"))
6619 (use (match_operand 2 "const_int_operand" "O,n"))
6620 (clobber (match_scratch:SI 3 "=l,l"))]
6621 "DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_AIX_NODESC"
6622 "*
6623{
6a4cee5f
MM
6624 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
6625 output_asm_insn (\"crxor 6,6,6\", operands);
1fd4e8c1 6626
6a4cee5f
MM
6627 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
6628 output_asm_insn (\"creqv 6,6,6\", operands);
b6c9286a
MM
6629
6630 return \"{brl|blrl}\";
6631}"
6632 [(set_attr "length" "4,8")])
6633
6634(define_insn "call_value_indirect_sysv"
6635 [(set (match_operand 0 "register_operand" "=fg,fg")
6636 (call (mem:SI (match_operand:SI 1 "register_operand" "l,l"))
6637 (match_operand 2 "const_int_operand" "n,n")))
6638 (use (match_operand 3 "const_int_operand" "O,n"))
6639 (clobber (match_scratch:SI 4 "=l,l"))]
6640 "DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_AIX_NODESC"
6641 "*
6642{
6a4cee5f
MM
6643 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
6644 output_asm_insn (\"crxor 6,6,6\", operands);
b6c9286a 6645
6a4cee5f
MM
6646 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
6647 output_asm_insn (\"creqv 6,6,6\", operands);
b6c9286a
MM
6648
6649 return \"{brl|blrl}\";
6650}"
6651 [(set_attr "length" "4,8")])
1fd4e8c1 6652
b6c9286a 6653;; Now the definitions for the call and call_value insns
1fd4e8c1
RK
6654(define_expand "call"
6655 [(parallel [(call (mem:SI (match_operand:SI 0 "address_operand" ""))
6656 (match_operand 1 "" ""))
4697a36c 6657 (use (match_operand 2 "" ""))
1fd4e8c1
RK
6658 (clobber (scratch:SI))])]
6659 ""
6660 "
6661{
6662 if (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != CONST_INT)
6663 abort ();
6664
6665 operands[0] = XEXP (operands[0], 0);
7509c759
MM
6666
6667 /* Convert NT DLL imports into an indirect call. */
6668 if (GET_CODE (operands[0]) == SYMBOL_REF
6a4cee5f 6669 && (INTVAL (operands[2]) & CALL_NT_DLLIMPORT) != 0)
7509c759
MM
6670 {
6671 operands[0] = rs6000_dll_import_ref (operands[0]);
6672 operands[2] = GEN_INT ((int)CALL_NORMAL);
6673 }
6674
6a4cee5f
MM
6675 if (GET_CODE (operands[0]) != SYMBOL_REF
6676 || (INTVAL (operands[2]) & CALL_LONG) != 0)
1fd4e8c1 6677 {
6a4cee5f
MM
6678 if (INTVAL (operands[2]) & CALL_LONG)
6679 operands[0] = rs6000_longcall_ref (operands[0]);
6680
b6c9286a
MM
6681 if (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_AIX_NODESC)
6682 emit_call_insn (gen_call_indirect_sysv (force_reg (Pmode, operands[0]),
6683 operands[1], operands[2]));
6684 else
6685 {
6686 rtx toc_reg = gen_rtx (REG, Pmode, 2);
6687 rtx toc_addr = RS6000_SAVE_TOC;
1fd4e8c1 6688
b6c9286a
MM
6689 if (DEFAULT_ABI == ABI_AIX)
6690 {
6691 /* AIX function pointers are really pointers to a three word area */
6692 rtx static_chain = gen_rtx (REG, Pmode, STATIC_CHAIN_REGNUM);
6693 emit_call_insn (gen_call_indirect_aix (force_reg (Pmode, operands[0]),
6694 operands[1], operands[2],
6695 toc_addr, toc_reg, static_chain));
6696 }
6697 else if (DEFAULT_ABI == ABI_NT)
6698 {
6699 /* NT function pointers are really pointers to a two word area */
7509c759 6700 rs6000_save_toc_p = 1;
b6c9286a
MM
6701 emit_call_insn (gen_call_indirect_nt (force_reg (Pmode, operands[0]),
6702 operands[1], operands[2],
6703 toc_addr, toc_reg));
6704 }
6705 else
6706 abort ();
6707 }
6708 DONE;
1fd4e8c1
RK
6709 }
6710}")
6711
6712(define_expand "call_value"
6713 [(parallel [(set (match_operand 0 "" "")
6714 (call (mem:SI (match_operand:SI 1 "address_operand" ""))
6715 (match_operand 2 "" "")))
4697a36c 6716 (use (match_operand 3 "" ""))
1fd4e8c1
RK
6717 (clobber (scratch:SI))])]
6718 ""
6719 "
6720{
6721 if (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != CONST_INT)
6722 abort ();
6723
6724 operands[1] = XEXP (operands[1], 0);
7509c759
MM
6725
6726 /* Convert NT DLL imports into an indirect call. */
6727 if (GET_CODE (operands[1]) == SYMBOL_REF
6a4cee5f 6728 && (INTVAL (operands[3]) & CALL_NT_DLLIMPORT) != 0)
7509c759
MM
6729 {
6730 operands[1] = rs6000_dll_import_ref (operands[1]);
6731 operands[3] = GEN_INT ((int)CALL_NORMAL);
6732 }
6733
6a4cee5f
MM
6734 if (GET_CODE (operands[1]) != SYMBOL_REF
6735 || (INTVAL (operands[3]) & CALL_LONG) != 0)
1fd4e8c1 6736 {
6a4cee5f
MM
6737 if (INTVAL (operands[2]) & CALL_LONG)
6738 operands[1] = rs6000_longcall_ref (operands[1]);
6739
b6c9286a
MM
6740 if (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_AIX_NODESC)
6741 emit_call_insn (gen_call_value_indirect_sysv (operands[0], operands[1],
6742 operands[2], operands[3]));
6743 else
6744 {
6745 rtx toc_reg = gen_rtx (REG, Pmode, 2);
6746 rtx toc_addr = RS6000_SAVE_TOC;
1fd4e8c1 6747
b6c9286a
MM
6748 if (DEFAULT_ABI == ABI_AIX)
6749 {
6750 /* AIX function pointers are really pointers to a three word area */
6751 rtx static_chain = gen_rtx (REG, Pmode, STATIC_CHAIN_REGNUM);
6752 emit_call_insn (gen_call_value_indirect_aix (operands[0],
6753 force_reg (Pmode, operands[1]),
6754 operands[2], operands[3],
6755 toc_addr, toc_reg, static_chain));
6756 }
6757 else if (DEFAULT_ABI == ABI_NT)
6758 {
6759 /* NT function pointers are really pointers to a two word area */
7509c759 6760 rs6000_save_toc_p = 1;
b6c9286a
MM
6761 emit_call_insn (gen_call_value_indirect_nt (operands[0],
6762 force_reg (Pmode, operands[1]),
6763 operands[2], operands[3],
6764 toc_addr, toc_reg));
6765 }
6766 else
6767 abort ();
6768 }
6769 DONE;
1fd4e8c1
RK
6770 }
6771}")
6772
04780ee7 6773;; Call to function in current module. No TOC pointer reload needed.
4697a36c
MM
6774;; Operand2 is non-zero if we are using the V.4 calling sequence and
6775;; either the function was not prototyped, or it was prototyped as a
6776;; variable argument function. It is > 0 if FP registers were passed
6777;; and < 0 if they were not.
04780ee7
RK
6778
6779(define_insn ""
4697a36c
MM
6780 [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
6781 (match_operand 1 "" "g,g"))
6782 (use (match_operand:SI 2 "immediate_operand" "O,n"))
6783 (clobber (match_scratch:SI 3 "=l,l"))]
5a19791c 6784 "(INTVAL (operands[2]) & CALL_LONG) == 0"
4697a36c
MM
6785 "*
6786{
6a4cee5f
MM
6787 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
6788 output_asm_insn (\"crxor 6,6,6\", operands);
6789
6790 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
6791 output_asm_insn (\"creqv 6,6,6\", operands);
4697a36c
MM
6792
6793 return \"bl %z0\";
6794}"
6795 [(set_attr "length" "4,8")])
04780ee7
RK
6796
6797;; Call to function which may be in another module. Restore the TOC
911f679c 6798;; pointer (r2) after the call unless this is System V.
4697a36c
MM
6799;; Operand2 is non-zero if we are using the V.4 calling sequence and
6800;; either the function was not prototyped, or it was prototyped as a
6801;; variable argument function. It is > 0 if FP registers were passed
6802;; and < 0 if they were not.
04780ee7 6803
1fd4e8c1 6804(define_insn ""
b6c9286a
MM
6805 [(call (mem:SI (match_operand:SI 0 "call_operand" "s,s"))
6806 (match_operand 1 "" "fg,fg"))
6807 (use (match_operand:SI 2 "immediate_operand" "O,n"))
6808 (clobber (match_scratch:SI 3 "=l,l"))]
6a4cee5f 6809 "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_NT)
5a19791c 6810 && (INTVAL (operands[2]) & CALL_LONG) == 0"
911f679c
MM
6811 "*
6812{
b6c9286a 6813 /* Indirect calls should go through call_indirect */
0f07e76c 6814 if (GET_CODE (operands[0]) == REG)
b6c9286a 6815 abort ();
911f679c 6816
6a4cee5f
MM
6817 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
6818 output_asm_insn (\"crxor 6,6,6\", operands);
6819
6820 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
6821 output_asm_insn (\"creqv 6,6,6\", operands);
7509c759 6822
b6c9286a
MM
6823 return (TARGET_WINDOWS_NT) ? \"bl %z0\;.znop %z0\" : \"bl %z0\;%.\";
6824}"
6825 [(set_attr "length" "8,12")])
59313e4e 6826
b6c9286a
MM
6827(define_insn ""
6828 [(call (mem:SI (match_operand:SI 0 "call_operand" "s,s"))
6829 (match_operand 1 "" "fg,fg"))
6830 (use (match_operand:SI 2 "immediate_operand" "O,n"))
6831 (clobber (match_scratch:SI 3 "=l,l"))]
6a4cee5f 6832 "(DEFAULT_ABI == ABI_AIX_NODESC || DEFAULT_ABI == ABI_V4)
5a19791c 6833 && (INTVAL (operands[2]) & CALL_LONG) == 0"
b6c9286a
MM
6834 "*
6835{
b6c9286a 6836 /* Indirect calls should go through call_indirect */
0f07e76c 6837 if (GET_CODE (operands[0]) == REG)
b6c9286a 6838 abort ();
59313e4e 6839
6a4cee5f
MM
6840 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
6841 output_asm_insn (\"crxor 6,6,6\", operands);
6842
6843 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
6844 output_asm_insn (\"creqv 6,6,6\", operands);
7509c759 6845
59313e4e 6846 return \"bl %z0\";
911f679c 6847}"
b6c9286a 6848 [(set_attr "length" "4,8")])
1fd4e8c1 6849
04780ee7 6850(define_insn ""
4697a36c
MM
6851 [(set (match_operand 0 "" "=fg,fg")
6852 (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
6853 (match_operand 2 "" "g,g")))
6854 (use (match_operand:SI 3 "immediate_operand" "O,n"))
6855 (clobber (match_scratch:SI 4 "=l,l"))]
5a19791c 6856 "(INTVAL (operands[3]) & CALL_LONG) == 0"
4697a36c
MM
6857 "*
6858{
6a4cee5f
MM
6859 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
6860 output_asm_insn (\"crxor 6,6,6\", operands);
6861
6862 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
6863 output_asm_insn (\"creqv 6,6,6\", operands);
4697a36c
MM
6864
6865 return \"bl %z1\";
6866}"
6867 [(set_attr "length" "4,8")])
04780ee7 6868
1fd4e8c1 6869(define_insn ""
b6c9286a
MM
6870 [(set (match_operand 0 "" "=fg,fg")
6871 (call (mem:SI (match_operand:SI 1 "call_operand" "s,s"))
6872 (match_operand 2 "" "fg,fg")))
6873 (use (match_operand:SI 3 "immediate_operand" "O,n"))
6874 (clobber (match_scratch:SI 4 "=l,l"))]
6a4cee5f 6875 "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_NT)
5a19791c 6876 && (INTVAL (operands[3]) & CALL_LONG) == 0"
911f679c
MM
6877 "*
6878{
b6c9286a 6879 /* This should be handled by call_value_indirect */
59313e4e 6880 if (GET_CODE (operands[1]) == REG)
b6c9286a
MM
6881 abort ();
6882
6a4cee5f
MM
6883 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
6884 output_asm_insn (\"crxor 6,6,6\", operands);
6885
6886 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
6887 output_asm_insn (\"creqv 6,6,6\", operands);
7509c759 6888
b6c9286a
MM
6889 return (TARGET_WINDOWS_NT) ? \"bl %z1\;.znop %z1\" : \"bl %z1\;%.\";
6890}"
6891 [(set_attr "length" "8,12")])
6892
6893(define_insn ""
6894 [(set (match_operand 0 "" "=fg,fg")
6895 (call (mem:SI (match_operand:SI 1 "call_operand" "s,s"))
6896 (match_operand 2 "" "fg,fg")))
6897 (use (match_operand:SI 3 "immediate_operand" "O,n"))
6898 (clobber (match_scratch:SI 4 "=l,l"))]
6a4cee5f 6899 "(DEFAULT_ABI == ABI_AIX_NODESC || DEFAULT_ABI == ABI_V4)
5a19791c 6900 && (INTVAL (operands[3]) & CALL_LONG) == 0"
b6c9286a
MM
6901 "*
6902{
b6c9286a 6903 /* This should be handled by call_value_indirect */
59313e4e 6904 if (GET_CODE (operands[1]) == REG)
b6c9286a 6905 abort ();
59313e4e 6906
6a4cee5f
MM
6907 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
6908 output_asm_insn (\"crxor 6,6,6\", operands);
6909
6910 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
6911 output_asm_insn (\"creqv 6,6,6\", operands);
7509c759 6912
59313e4e 6913 return \"bl %z1\";
911f679c 6914}"
b6c9286a
MM
6915 [(set_attr "length" "4,8")])
6916
e6f948e3
RK
6917
6918;; Call subroutine returning any type.
6919
6920(define_expand "untyped_call"
6921 [(parallel [(call (match_operand 0 "" "")
6922 (const_int 0))
6923 (match_operand 1 "" "")
6924 (match_operand 2 "" "")])]
6925 ""
6926 "
6927{
6928 int i;
6929
4697a36c 6930 emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx, const0_rtx));
e6f948e3
RK
6931
6932 for (i = 0; i < XVECLEN (operands[2], 0); i++)
6933 {
6934 rtx set = XVECEXP (operands[2], 0, i);
6935 emit_move_insn (SET_DEST (set), SET_SRC (set));
6936 }
6937
6938 /* The optimizer does not know that the call sets the function value
6939 registers we stored in the result block. We avoid problems by
6940 claiming that all hard registers are used and clobbered at this
6941 point. */
6942 emit_insn (gen_blockage ());
6943
6944 DONE;
6945}")
6946
6947;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
6948;; all of memory. This blocks insns from being moved across this point.
6949
6950(define_insn "blockage"
6951 [(unspec_volatile [(const_int 0)] 0)]
6952 ""
6953 "")
4697a36c 6954
b6c9286a
MM
6955;; Synchronize instructions/data caches for V.4 trampolines
6956;; The extra memory_operand is to prevent the optimizer from
6957;; deleting insns with "no" effect.
6958(define_insn "icbi"
6959 [(unspec [(match_operand 0 "memory_operand" "=m")
6960 (match_operand 1 "register_operand" "b")
6961 (match_operand 2 "register_operand" "r")] 3)]
6962 "TARGET_POWERPC"
6963 "icbi %1,%2")
6964
6965(define_insn "dcbst"
6966 [(unspec [(match_operand 0 "memory_operand" "=m")
6967 (match_operand 1 "register_operand" "b")
6968 (match_operand 2 "register_operand" "r")] 4)]
6969 "TARGET_POWERPC"
6970 "dcbst %1,%2")
6971
6972(define_insn "sync"
6973 [(unspec [(match_operand 0 "memory_operand" "=m")] 5)]
4697a36c 6974 ""
b6c9286a
MM
6975 "{dcs|sync}")
6976
6977(define_insn "isync"
6978 [(unspec [(match_operand 0 "memory_operand" "=m")] 6)]
6979 ""
6980 "{ics|isync}")
4697a36c 6981
1fd4e8c1
RK
6982\f
6983;; Compare insns are next. Note that the RS/6000 has two types of compares,
7e69e155 6984;; signed & unsigned, and one type of branch.
1fd4e8c1
RK
6985;;
6986;; Start with the DEFINE_EXPANDs to generate the rtl for compares, scc
6987;; insns, and branches. We store the operands of compares until we see
6988;; how it is used.
6989(define_expand "cmpsi"
6990 [(set (cc0)
cd2b37d9 6991 (compare (match_operand:SI 0 "gpc_reg_operand" "")
1fd4e8c1
RK
6992 (match_operand:SI 1 "reg_or_short_operand" "")))]
6993 ""
6994 "
6995{
6996 /* Take care of the possibility that operands[1] might be negative but
6997 this might be a logical operation. That insn doesn't exist. */
6998 if (GET_CODE (operands[1]) == CONST_INT
6999 && INTVAL (operands[1]) < 0)
7000 operands[1] = force_reg (SImode, operands[1]);
7001
7002 rs6000_compare_op0 = operands[0];
7003 rs6000_compare_op1 = operands[1];
7004 rs6000_compare_fp_p = 0;
7005 DONE;
7006}")
7007
266eb58a
DE
7008(define_expand "cmpdi"
7009 [(set (cc0)
7010 (compare (match_operand:DI 0 "gpc_reg_operand" "")
7011 (match_operand:DI 1 "reg_or_short_operand" "")))]
7012 "TARGET_POWERPC64"
7013 "
7014{
7015 /* Take care of the possibility that operands[1] might be negative but
7016 this might be a logical operation. That insn doesn't exist. */
7017 if (GET_CODE (operands[1]) == CONST_INT
7018 && INTVAL (operands[1]) < 0)
7019 operands[1] = force_reg (DImode, operands[1]);
7020
7021 rs6000_compare_op0 = operands[0];
7022 rs6000_compare_op1 = operands[1];
7023 rs6000_compare_fp_p = 0;
7024 DONE;
7025}")
7026
1fd4e8c1 7027(define_expand "cmpsf"
cd2b37d9
RK
7028 [(set (cc0) (compare (match_operand:SF 0 "gpc_reg_operand" "")
7029 (match_operand:SF 1 "gpc_reg_operand" "")))]
d14a6d05 7030 "TARGET_HARD_FLOAT"
1fd4e8c1
RK
7031 "
7032{
7033 rs6000_compare_op0 = operands[0];
7034 rs6000_compare_op1 = operands[1];
7035 rs6000_compare_fp_p = 1;
7036 DONE;
7037}")
7038
7039(define_expand "cmpdf"
cd2b37d9
RK
7040 [(set (cc0) (compare (match_operand:DF 0 "gpc_reg_operand" "")
7041 (match_operand:DF 1 "gpc_reg_operand" "")))]
d14a6d05 7042 "TARGET_HARD_FLOAT"
1fd4e8c1
RK
7043 "
7044{
7045 rs6000_compare_op0 = operands[0];
7046 rs6000_compare_op1 = operands[1];
7047 rs6000_compare_fp_p = 1;
7048 DONE;
7049}")
7050
7051(define_expand "beq"
7052 [(set (match_dup 2) (match_dup 1))
7053 (set (pc)
7054 (if_then_else (eq (match_dup 2)
7055 (const_int 0))
7056 (label_ref (match_operand 0 "" ""))
7057 (pc)))]
7058 ""
7059 "
7060{ enum machine_mode mode = rs6000_compare_fp_p ? CCFPmode : CCmode;
7061 operands[1] = gen_rtx (COMPARE, mode,
7062 rs6000_compare_op0, rs6000_compare_op1);
7063 operands[2] = gen_reg_rtx (mode);
7064}")
7065
7066(define_expand "bne"
7067 [(set (match_dup 2) (match_dup 1))
7068 (set (pc)
7069 (if_then_else (ne (match_dup 2)
7070 (const_int 0))
7071 (label_ref (match_operand 0 "" ""))
7072 (pc)))]
7073 ""
7074 "
7075{ enum machine_mode mode = rs6000_compare_fp_p ? CCFPmode : CCmode;
7076 operands[1] = gen_rtx (COMPARE, mode,
7077 rs6000_compare_op0, rs6000_compare_op1);
7078 operands[2] = gen_reg_rtx (mode);
7079}")
7080
7081(define_expand "blt"
7082 [(set (match_dup 2) (match_dup 1))
7083 (set (pc)
7084 (if_then_else (lt (match_dup 2)
7085 (const_int 0))
7086 (label_ref (match_operand 0 "" ""))
7087 (pc)))]
7088 ""
7089 "
7090{ enum machine_mode mode = rs6000_compare_fp_p ? CCFPmode : CCmode;
7091 operands[1] = gen_rtx (COMPARE, mode,
7092 rs6000_compare_op0, rs6000_compare_op1);
7093 operands[2] = gen_reg_rtx (mode);
7094}")
7095
7096(define_expand "bgt"
7097 [(set (match_dup 2) (match_dup 1))
7098 (set (pc)
7099 (if_then_else (gt (match_dup 2)
7100 (const_int 0))
7101 (label_ref (match_operand 0 "" ""))
7102 (pc)))]
7103 ""
7104 "
7105{ enum machine_mode mode = rs6000_compare_fp_p ? CCFPmode : CCmode;
7106 operands[1] = gen_rtx (COMPARE, mode,
7107 rs6000_compare_op0, rs6000_compare_op1);
7108 operands[2] = gen_reg_rtx (mode);
7109}")
7110
7111(define_expand "ble"
7112 [(set (match_dup 2) (match_dup 1))
7113 (set (pc)
7114 (if_then_else (le (match_dup 2)
7115 (const_int 0))
7116 (label_ref (match_operand 0 "" ""))
7117 (pc)))]
7118 ""
7119 "
7120{ enum machine_mode mode = rs6000_compare_fp_p ? CCFPmode : CCmode;
7121 operands[1] = gen_rtx (COMPARE, mode,
7122 rs6000_compare_op0, rs6000_compare_op1);
7123 operands[2] = gen_reg_rtx (mode);
7124}")
7125
7126(define_expand "bge"
7127 [(set (match_dup 2) (match_dup 1))
7128 (set (pc)
7129 (if_then_else (ge (match_dup 2)
7130 (const_int 0))
7131 (label_ref (match_operand 0 "" ""))
7132 (pc)))]
7133 ""
7134 "
7135{ enum machine_mode mode = rs6000_compare_fp_p ? CCFPmode : CCmode;
7136 operands[1] = gen_rtx (COMPARE, mode,
7137 rs6000_compare_op0, rs6000_compare_op1);
7138 operands[2] = gen_reg_rtx (mode);
7139}")
7140
7141(define_expand "bgtu"
7142 [(set (match_dup 2) (match_dup 1))
7143 (set (pc)
7144 (if_then_else (gtu (match_dup 2)
7145 (const_int 0))
7146 (label_ref (match_operand 0 "" ""))
7147 (pc)))]
7148 ""
7149 "
7150{ operands[1] = gen_rtx (COMPARE, CCUNSmode,
7151 rs6000_compare_op0, rs6000_compare_op1);
7152 operands[2] = gen_reg_rtx (CCUNSmode);
7153}")
7154
7155(define_expand "bltu"
7156 [(set (match_dup 2) (match_dup 1))
7157 (set (pc)
7158 (if_then_else (ltu (match_dup 2)
7159 (const_int 0))
7160 (label_ref (match_operand 0 "" ""))
7161 (pc)))]
7162 ""
7163 "
7164{ operands[1] = gen_rtx (COMPARE, CCUNSmode,
7165 rs6000_compare_op0, rs6000_compare_op1);
7166 operands[2] = gen_reg_rtx (CCUNSmode);
7167}")
7168
7169(define_expand "bgeu"
7170 [(set (match_dup 2) (match_dup 1))
7171 (set (pc)
7172 (if_then_else (geu (match_dup 2)
7173 (const_int 0))
7174 (label_ref (match_operand 0 "" ""))
7175 (pc)))]
7176 ""
7177 "
7178{ operands[1] = gen_rtx (COMPARE, CCUNSmode,
7179 rs6000_compare_op0, rs6000_compare_op1);
7180 operands[2] = gen_reg_rtx (CCUNSmode);
7181}")
7182
7183(define_expand "bleu"
7184 [(set (match_dup 2) (match_dup 1))
7185 (set (pc)
7186 (if_then_else (leu (match_dup 2)
7187 (const_int 0))
7188 (label_ref (match_operand 0 "" ""))
7189 (pc)))]
7190 ""
7191 "
7192{ operands[1] = gen_rtx (COMPARE, CCUNSmode,
7193 rs6000_compare_op0, rs6000_compare_op1);
7194 operands[2] = gen_reg_rtx (CCUNSmode);
7195}")
7196
7197;; For SNE, we would prefer that the xor/abs sequence be used for integers.
7198;; For SEQ, likewise, except that comparisons with zero should be done
7199;; with an scc insns. However, due to the order that combine see the
7200;; resulting insns, we must, in fact, allow SEQ for integers. Fail in
7201;; the cases we don't want to handle.
7202(define_expand "seq"
7203 [(set (match_dup 2) (match_dup 1))
cd2b37d9 7204 (set (match_operand:SI 0 "gpc_reg_operand" "")
1fd4e8c1
RK
7205 (eq:SI (match_dup 2) (const_int 0)))]
7206 ""
7207 "
7208{ enum machine_mode mode = rs6000_compare_fp_p ? CCFPmode : CCmode;
7209 operands[1] = gen_rtx (COMPARE, mode,
7210 rs6000_compare_op0, rs6000_compare_op1);
7211 operands[2] = gen_reg_rtx (mode);
7212}")
7213
7214(define_expand "sne"
7215 [(set (match_dup 2) (match_dup 1))
cd2b37d9 7216 (set (match_operand:SI 0 "gpc_reg_operand" "")
1fd4e8c1
RK
7217 (ne:SI (match_dup 2) (const_int 0)))]
7218 ""
7219 "
7220{ if (! rs6000_compare_fp_p)
7221 FAIL;
7222
7223 operands[1] = gen_rtx (COMPARE, CCFPmode,
7224 rs6000_compare_op0, rs6000_compare_op1);
7225 operands[2] = gen_reg_rtx (CCFPmode);
7226}")
7227
7228;; A > 0 is best done using the portable sequence, so fail in that case.
7229(define_expand "sgt"
7230 [(set (match_dup 2) (match_dup 1))
cd2b37d9 7231 (set (match_operand:SI 0 "gpc_reg_operand" "")
1fd4e8c1
RK
7232 (gt:SI (match_dup 2) (const_int 0)))]
7233 ""
7234 "
7235{ enum machine_mode mode = rs6000_compare_fp_p ? CCFPmode : CCmode;
7236
7237 if (! rs6000_compare_fp_p && rs6000_compare_op1 == const0_rtx)
7238 FAIL;
7239
7240 operands[1] = gen_rtx (COMPARE, mode,
7241 rs6000_compare_op0, rs6000_compare_op1);
7242 operands[2] = gen_reg_rtx (mode);
7243}")
7244
7245;; A < 0 is best done in the portable way for A an integer.
7246(define_expand "slt"
7247 [(set (match_dup 2) (match_dup 1))
cd2b37d9 7248 (set (match_operand:SI 0 "gpc_reg_operand" "")
1fd4e8c1
RK
7249 (lt:SI (match_dup 2) (const_int 0)))]
7250 ""
7251 "
7252{ enum machine_mode mode = rs6000_compare_fp_p ? CCFPmode : CCmode;
7253
7254 if (! rs6000_compare_fp_p && rs6000_compare_op1 == const0_rtx)
7255 FAIL;
7256
7257 operands[1] = gen_rtx (COMPARE, mode,
7258 rs6000_compare_op0, rs6000_compare_op1);
7259 operands[2] = gen_reg_rtx (mode);
7260}")
7261
7262(define_expand "sge"
7263 [(set (match_dup 2) (match_dup 1))
cd2b37d9 7264 (set (match_operand:SI 0 "gpc_reg_operand" "")
1fd4e8c1
RK
7265 (ge:SI (match_dup 2) (const_int 0)))]
7266 ""
7267 "
7268{ enum machine_mode mode = rs6000_compare_fp_p ? CCFPmode : CCmode;
7269 operands[1] = gen_rtx (COMPARE, mode,
7270 rs6000_compare_op0, rs6000_compare_op1);
7271 operands[2] = gen_reg_rtx (mode);
7272}")
7273
7274;; A <= 0 is best done the portable way for A an integer.
7275(define_expand "sle"
7276 [(set (match_dup 2) (match_dup 1))
cd2b37d9 7277 (set (match_operand:SI 0 "gpc_reg_operand" "")
1fd4e8c1
RK
7278 (le:SI (match_dup 2) (const_int 0)))]
7279 ""
7280 "
7281{ enum machine_mode mode = rs6000_compare_fp_p ? CCFPmode : CCmode;
7282
7283 if (! rs6000_compare_fp_p && rs6000_compare_op1 == const0_rtx)
7284 FAIL;
7285
7286 operands[1] = gen_rtx (COMPARE, mode,
7287 rs6000_compare_op0, rs6000_compare_op1);
7288 operands[2] = gen_reg_rtx (mode);
7289}")
7290
7291(define_expand "sgtu"
7292 [(set (match_dup 2) (match_dup 1))
cd2b37d9 7293 (set (match_operand:SI 0 "gpc_reg_operand" "")
1fd4e8c1
RK
7294 (gtu:SI (match_dup 2) (const_int 0)))]
7295 ""
7296 "
7297{ operands[1] = gen_rtx (COMPARE, CCUNSmode,
7298 rs6000_compare_op0, rs6000_compare_op1);
7299 operands[2] = gen_reg_rtx (CCUNSmode);
7300}")
7301
7302(define_expand "sltu"
7303 [(set (match_dup 2) (match_dup 1))
cd2b37d9 7304 (set (match_operand:SI 0 "gpc_reg_operand" "")
1fd4e8c1
RK
7305 (ltu:SI (match_dup 2) (const_int 0)))]
7306 ""
7307 "
7308{ operands[1] = gen_rtx (COMPARE, CCUNSmode,
7309 rs6000_compare_op0, rs6000_compare_op1);
7310 operands[2] = gen_reg_rtx (CCUNSmode);
7311}")
7312
7313(define_expand "sgeu"
7314 [(set (match_dup 2) (match_dup 1))
cd2b37d9 7315 (set (match_operand:SI 0 "gpc_reg_operand" "")
1fd4e8c1
RK
7316 (geu:SI (match_dup 2) (const_int 0)))]
7317 ""
7318 "
7319{ operands[1] = gen_rtx (COMPARE, CCUNSmode,
7320 rs6000_compare_op0, rs6000_compare_op1);
7321 operands[2] = gen_reg_rtx (CCUNSmode);
7322}")
7323
7324(define_expand "sleu"
7325 [(set (match_dup 2) (match_dup 1))
cd2b37d9 7326 (set (match_operand:SI 0 "gpc_reg_operand" "")
1fd4e8c1
RK
7327 (leu:SI (match_dup 2) (const_int 0)))]
7328 ""
7329 "
7330{ operands[1] = gen_rtx (COMPARE, CCUNSmode,
7331 rs6000_compare_op0, rs6000_compare_op1);
7332 operands[2] = gen_reg_rtx (CCUNSmode);
7333}")
7334\f
7335;; Here are the actual compare insns.
7336(define_insn ""
7337 [(set (match_operand:CC 0 "cc_reg_operand" "=y")
cd2b37d9 7338 (compare:CC (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
7339 (match_operand:SI 2 "reg_or_short_operand" "rI")))]
7340 ""
7f340546 7341 "{cmp%I2|cmpw%I2} %0,%1,%2"
1fd4e8c1
RK
7342 [(set_attr "type" "compare")])
7343
266eb58a
DE
7344(define_insn ""
7345 [(set (match_operand:CC 0 "cc_reg_operand" "=y")
7346 (compare:CC (match_operand:DI 1 "gpc_reg_operand" "r")
7347 (match_operand:DI 2 "reg_or_short_operand" "rI")))]
7348 "TARGET_POWERPC64"
7349 "cmpd%I2 %0,%1,%2"
7350 [(set_attr "type" "compare")])
7351
f357808b
RK
7352;; If we are comparing a register for equality with a large constant,
7353;; we can do this with an XOR followed by a compare. But we need a scratch
7354;; register for the result of the XOR.
7355
7356(define_split
7357 [(set (match_operand:CC 0 "cc_reg_operand" "")
cd2b37d9 7358 (compare:CC (match_operand:SI 1 "gpc_reg_operand" "")
f357808b 7359 (match_operand:SI 2 "non_short_cint_operand" "")))
cd2b37d9 7360 (clobber (match_operand:SI 3 "gpc_reg_operand" ""))]
f357808b
RK
7361 "find_single_use (operands[0], insn, 0)
7362 && (GET_CODE (*find_single_use (operands[0], insn, 0)) == EQ
7363 || GET_CODE (*find_single_use (operands[0], insn, 0)) == NE)"
7364 [(set (match_dup 3) (xor:SI (match_dup 1) (match_dup 4)))
7365 (set (match_dup 0) (compare:CC (match_dup 3) (match_dup 5)))]
7366 "
7367{
7368 /* Get the constant we are comparing against, C, and see what it looks like
7369 sign-extended to 16 bits. Then see what constant could be XOR'ed
7370 with C to get the sign-extended value. */
7371
7372 int c = INTVAL (operands[2]);
7373 int sextc = (c << 16) >> 16;
7374 int xorv = c ^ sextc;
7375
7376 operands[4] = gen_rtx (CONST_INT, VOIDmode, xorv);
7377 operands[5] = gen_rtx (CONST_INT, VOIDmode, sextc);
7378}")
7379
1fd4e8c1
RK
7380(define_insn ""
7381 [(set (match_operand:CCUNS 0 "cc_reg_operand" "=y")
cd2b37d9 7382 (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
7383 (match_operand:SI 2 "reg_or_u_short_operand" "rI")))]
7384 ""
7f340546 7385 "{cmpl%I2|cmplw%I2} %0,%1,%W2"
1fd4e8c1
RK
7386 [(set_attr "type" "compare")])
7387
266eb58a
DE
7388(define_insn ""
7389 [(set (match_operand:CCUNS 0 "cc_reg_operand" "=y")
7390 (compare:CCUNS (match_operand:DI 1 "gpc_reg_operand" "r")
7391 (match_operand:DI 2 "reg_or_u_short_operand" "rI")))]
7392 ""
7393 "cmpld%I2 %0,%1,%W2"
7394 [(set_attr "type" "compare")])
7395
1fd4e8c1
RK
7396;; The following two insns don't exist as single insns, but if we provide
7397;; them, we can swap an add and compare, which will enable us to overlap more
7398;; of the required delay between a compare and branch. We generate code for
7399;; them by splitting.
7400
7401(define_insn ""
7402 [(set (match_operand:CC 3 "cc_reg_operand" "=y")
cd2b37d9 7403 (compare:CC (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 7404 (match_operand:SI 2 "short_cint_operand" "i")))
cd2b37d9 7405 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
7406 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "i")))]
7407 ""
baf97f86
RK
7408 "#"
7409 [(set_attr "length" "8")])
7e69e155 7410
1fd4e8c1
RK
7411(define_insn ""
7412 [(set (match_operand:CCUNS 3 "cc_reg_operand" "=y")
cd2b37d9 7413 (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 7414 (match_operand:SI 2 "u_short_cint_operand" "i")))
cd2b37d9 7415 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
7416 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "i")))]
7417 ""
baf97f86
RK
7418 "#"
7419 [(set_attr "length" "8")])
7e69e155 7420
1fd4e8c1
RK
7421(define_split
7422 [(set (match_operand:CC 3 "cc_reg_operand" "")
cd2b37d9 7423 (compare:CC (match_operand:SI 1 "gpc_reg_operand" "")
1fd4e8c1 7424 (match_operand:SI 2 "short_cint_operand" "")))
cd2b37d9 7425 (set (match_operand:SI 0 "gpc_reg_operand" "")
1fd4e8c1
RK
7426 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "")))]
7427 ""
7428 [(set (match_dup 3) (compare:CC (match_dup 1) (match_dup 2)))
7429 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 4)))])
7430
7431(define_split
7432 [(set (match_operand:CCUNS 3 "cc_reg_operand" "")
cd2b37d9 7433 (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "")
1fd4e8c1 7434 (match_operand:SI 2 "u_short_cint_operand" "")))
cd2b37d9 7435 (set (match_operand:SI 0 "gpc_reg_operand" "")
1fd4e8c1
RK
7436 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "")))]
7437 ""
7438 [(set (match_dup 3) (compare:CCUNS (match_dup 1) (match_dup 2)))
7439 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 4)))])
7440
7441(define_insn ""
7442 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
cd2b37d9
RK
7443 (compare:CCFP (match_operand:SF 1 "gpc_reg_operand" "f")
7444 (match_operand:SF 2 "gpc_reg_operand" "f")))]
d14a6d05 7445 "TARGET_HARD_FLOAT"
1fd4e8c1
RK
7446 "fcmpu %0,%1,%2"
7447 [(set_attr "type" "fpcompare")])
7448
7449(define_insn ""
7450 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
cd2b37d9
RK
7451 (compare:CCFP (match_operand:DF 1 "gpc_reg_operand" "f")
7452 (match_operand:DF 2 "gpc_reg_operand" "f")))]
d14a6d05 7453 "TARGET_HARD_FLOAT"
1fd4e8c1
RK
7454 "fcmpu %0,%1,%2"
7455 [(set_attr "type" "fpcompare")])
7456\f
7457;; Now we have the scc insns. We can do some combinations because of the
7458;; way the machine works.
7459;;
7460;; Note that this is probably faster if we can put an insn between the
c5defebb
RK
7461;; mfcr and rlinm, but this is tricky. Let's leave it for now. In most
7462;; cases the insns below which don't use an intermediate CR field will
7463;; be used instead.
1fd4e8c1 7464(define_insn ""
cd2b37d9 7465 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
7466 (match_operator:SI 1 "scc_comparison_operator"
7467 [(match_operand 2 "cc_reg_operand" "y")
7468 (const_int 0)]))]
7469 ""
ca7f5001 7470 "%D1mfcr %0\;{rlinm|rlwinm} %0,%0,%J1,1"
b19003d8 7471 [(set_attr "length" "12")])
1fd4e8c1
RK
7472
7473(define_insn ""
7474 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
7475 (compare:CC (match_operator:SI 1 "scc_comparison_operator"
7476 [(match_operand 2 "cc_reg_operand" "y")
7477 (const_int 0)])
7478 (const_int 0)))
cd2b37d9 7479 (set (match_operand:SI 3 "gpc_reg_operand" "=r")
1fd4e8c1
RK
7480 (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7481 ""
ca7f5001 7482 "%D1mfcr %3\;{rlinm.|rlwinm.} %3,%3,%J1,1"
b19003d8
RK
7483 [(set_attr "type" "delayed_compare")
7484 (set_attr "length" "12")])
1fd4e8c1
RK
7485
7486(define_insn ""
cd2b37d9 7487 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
7488 (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
7489 [(match_operand 2 "cc_reg_operand" "y")
7490 (const_int 0)])
7491 (match_operand:SI 3 "const_int_operand" "n")))]
7492 ""
7493 "*
7494{
7495 int is_bit = ccr_bit (operands[1], 1);
7496 int put_bit = 31 - (INTVAL (operands[3]) & 31);
7497 int count;
7498
7499 if (is_bit >= put_bit)
7500 count = is_bit - put_bit;
7501 else
7502 count = 32 - (put_bit - is_bit);
7503
7504 operands[4] = gen_rtx (CONST_INT, VOIDmode, count);
7505 operands[5] = gen_rtx (CONST_INT, VOIDmode, put_bit);
7506
ca7f5001 7507 return \"%D1mfcr %0\;{rlinm|rlwinm} %0,%0,%4,%5,%5\";
b19003d8
RK
7508}"
7509 [(set_attr "length" "12")])
1fd4e8c1
RK
7510
7511(define_insn ""
7512 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
7513 (compare:CC
7514 (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
7515 [(match_operand 2 "cc_reg_operand" "y")
7516 (const_int 0)])
7517 (match_operand:SI 3 "const_int_operand" "n"))
7518 (const_int 0)))
cd2b37d9 7519 (set (match_operand:SI 4 "gpc_reg_operand" "=r")
1fd4e8c1
RK
7520 (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
7521 (match_dup 3)))]
7522 ""
7523 "*
7524{
7525 int is_bit = ccr_bit (operands[1], 1);
7526 int put_bit = 31 - (INTVAL (operands[3]) & 31);
7527 int count;
7528
7529 if (is_bit >= put_bit)
7530 count = is_bit - put_bit;
7531 else
7532 count = 32 - (put_bit - is_bit);
7533
7534 operands[5] = gen_rtx (CONST_INT, VOIDmode, count);
7535 operands[6] = gen_rtx (CONST_INT, VOIDmode, put_bit);
7536
ca7f5001 7537 return \"%D1mfcr %4\;{rlinm.|rlwinm.} %4,%4,%5,%6,%6\";
1fd4e8c1 7538}"
b19003d8
RK
7539 [(set_attr "type" "delayed_compare")
7540 (set_attr "length" "12")])
1fd4e8c1 7541
c5defebb
RK
7542;; If we are comparing the result of two comparisons, this can be done
7543;; using creqv or crxor.
7544
7545(define_insn ""
7546 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y")
7547 (compare:CCEQ (match_operator 1 "scc_comparison_operator"
7548 [(match_operand 2 "cc_reg_operand" "y")
7549 (const_int 0)])
7550 (match_operator 3 "scc_comparison_operator"
7551 [(match_operand 4 "cc_reg_operand" "y")
7552 (const_int 0)])))]
7553 "REGNO (operands[2]) != REGNO (operands[4])"
7554 "*
7555{
7556 enum rtx_code code1, code2;
7557
7558 code1 = GET_CODE (operands[1]);
7559 code2 = GET_CODE (operands[3]);
7560
7561 if ((code1 == EQ || code1 == LT || code1 == GT
7562 || code1 == LTU || code1 == GTU
7563 || (code1 != NE && GET_MODE (operands[2]) == CCFPmode))
7564 !=
7565 (code2 == EQ || code2 == LT || code2 == GT
7566 || code2 == LTU || code2 == GTU
7567 || (code2 != NE && GET_MODE (operands[4]) == CCFPmode)))
7568 return \"%C1%C3crxor %E0,%j1,%j3\";
7569 else
7570 return \"%C1%C3creqv %E0,%j1,%j3\";
b19003d8
RK
7571}"
7572 [(set_attr "length" "12")])
c5defebb
RK
7573
7574;; There is a 3 cycle delay between consecutive mfcr instructions
7575;; so it is useful to combine 2 scc instructions to use only one mfcr.
7576
7577(define_peephole
cd2b37d9 7578 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
c5defebb
RK
7579 (match_operator:SI 1 "scc_comparison_operator"
7580 [(match_operand 2 "cc_reg_operand" "y")
7581 (const_int 0)]))
cd2b37d9 7582 (set (match_operand:SI 3 "gpc_reg_operand" "=r")
c5defebb
RK
7583 (match_operator:SI 4 "scc_comparison_operator"
7584 [(match_operand 5 "cc_reg_operand" "y")
7585 (const_int 0)]))]
7586 "REGNO (operands[2]) != REGNO (operands[5])"
ca7f5001 7587 "%D1%D4mfcr %3\;{rlinm|rlwinm} %0,%3,%J1,1\;{rlinm|rlwinm} %3,%3,%J4,1"
b19003d8 7588 [(set_attr "length" "20")])
c5defebb 7589
1fd4e8c1
RK
7590;; There are some scc insns that can be done directly, without a compare.
7591;; These are faster because they don't involve the communications between
7592;; the FXU and branch units. In fact, we will be replacing all of the
7593;; integer scc insns here or in the portable methods in emit_store_flag.
7594;;
7595;; Also support (neg (scc ..)) since that construct is used to replace
7596;; branches, (plus (scc ..) ..) since that construct is common and
7597;; takes no more insns than scc, and (and (neg (scc ..)) ..) in the
7598;; cases where it is no more expensive than (neg (scc ..)).
7599
7600;; Have reload force a constant into a register for the simple insns that
7601;; otherwise won't accept constants. We do this because it is faster than
7602;; the cmp/mfcr sequence we would otherwise generate.
7603
7604(define_insn ""
cd2b37d9
RK
7605 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r,r")
7606 (eq:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r")
1fd4e8c1
RK
7607 (match_operand:SI 2 "reg_or_cint_operand" "r,O,K,J,I")))
7608 (clobber (match_scratch:SI 3 "=r,&r,r,r,r"))]
7609 ""
7610 "@
ca7f5001 7611 xor %0,%1,%2\;{sfi|subfic} %3,%0,0\;{ae|adde} %0,%3,%0
71d2371f 7612 {sfi|subfic} %3,%1,0\;{ae|adde} %0,%3,%1
ca7f5001
RK
7613 {xoril|xori} %0,%1,%b2\;{sfi|subfic} %3,%0,0\;{ae|adde} %0,%3,%0
7614 {xoriu|xoris} %0,%1,%u2\;{sfi|subfic} %3,%0,0\;{ae|adde} %0,%3,%0
7615 {sfi|subfic} %0,%1,%2\;{sfi|subfic} %3,%0,0\;{ae|adde} %0,%3,%0"
b19003d8 7616 [(set_attr "length" "12,8,12,12,12")])
1fd4e8c1
RK
7617
7618(define_insn ""
7619 [(set (match_operand:CC 4 "cc_reg_operand" "=x,x,x,x,x")
7e69e155 7620 (compare:CC
cd2b37d9 7621 (eq:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r")
1fd4e8c1
RK
7622 (match_operand:SI 2 "reg_or_cint_operand" "r,O,K,J,I"))
7623 (const_int 0)))
cd2b37d9 7624 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r,r")
1fd4e8c1
RK
7625 (eq:SI (match_dup 1) (match_dup 2)))
7626 (clobber (match_scratch:SI 3 "=r,&r,r,r,r"))]
7627 ""
7628 "@
ca7f5001
RK
7629 xor %0,%1,%2\;{sfi|subfic} %3,%0,0\;{ae.|adde.} %0,%3,%0
7630 {sfi|subfic} %3,%1,0\;{ae.|adde.} %0,%3,%1
7631 {xoril|xori} %0,%1,%b2\;{sfi|subfic} %3,%0,0\;{ae.|adde.} %0,%3,%0
7632 {xoriu|xoris} %0,%1,%u2\;{sfi|subfic} %3,%0,0\;{ae.|adde.} %0,%3,%0
7633 {sfi|subfic} %0,%1,%2\;{sfi|subfic} %3,%0,0\;{ae.|adde.} %0,%3,%0"
b19003d8
RK
7634 [(set_attr "type" "compare")
7635 (set_attr "length" "12,8,12,12,12")])
7636
7637;; We have insns of the form shown by the first define_insn below. If
7638;; there is something inside the comparison operation, we must split it.
7639(define_split
7640 [(set (match_operand:SI 0 "gpc_reg_operand" "")
7641 (plus:SI (match_operator 1 "comparison_operator"
7642 [(match_operand:SI 2 "" "")
7643 (match_operand:SI 3
7644 "reg_or_cint_operand" "")])
7645 (match_operand:SI 4 "gpc_reg_operand" "")))
7646 (clobber (match_operand:SI 5 "register_operand" ""))]
7647 "! gpc_reg_operand (operands[2], SImode)"
7648 [(set (match_dup 5) (match_dup 2))
7649 (set (match_dup 2) (plus:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
7650 (match_dup 4)))])
1fd4e8c1
RK
7651
7652(define_insn ""
cd2b37d9
RK
7653 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r,r")
7654 (plus:SI (eq:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r")
1fd4e8c1 7655 (match_operand:SI 2 "reg_or_cint_operand" "r,O,K,J,I"))
cd2b37d9 7656 (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r,r")))
1fd4e8c1
RK
7657 (clobber (match_scratch:SI 4 "=&r,&r,&r,&r,&r"))]
7658 ""
7659 "@
ca7f5001
RK
7660 xor %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze|addze} %0,%3
7661 {sfi|subfic} %4,%1,0\;{aze|addze} %0,%3
7662 {xoril|xori} %4,%1,%b2\;{sfi|subfic} %4,%4,0\;{aze|addze} %0,%3
7663 {xoriu|xoris} %4,%1,%u2\;{sfi|subfic} %4,%4,0\;{aze|addze} %0,%3
d9d934ef 7664 {sfi|subfic} %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze|addze} %0,%3"
b19003d8 7665 [(set_attr "length" "12,8,12,12,12")])
1fd4e8c1
RK
7666
7667(define_insn ""
7668 [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,x,x,x")
7e69e155 7669 (compare:CC
1fd4e8c1 7670 (plus:SI
cd2b37d9 7671 (eq:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r")
1fd4e8c1 7672 (match_operand:SI 2 "reg_or_cint_operand" "r,O,K,J,I"))
cd2b37d9 7673 (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r,r"))
1fd4e8c1
RK
7674 (const_int 0)))
7675 (clobber (match_scratch:SI 4 "=&r,&r,&r,&r,&r"))]
7676 ""
7677 "@
ca7f5001
RK
7678 xor %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %4,%3
7679 {sfi|subfic} %4,%1,0\;{aze.|addze.} %0,%3
7680 {xoril|xori} %4,%1,%b2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %4,%3
7681 {xoriu|xoris} %4,%1,%u2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %4,%3
7682 {sfi|subfic} %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %4,%3"
b19003d8
RK
7683 [(set_attr "type" "compare")
7684 (set_attr "length" "12,8,12,12,12")])
1fd4e8c1
RK
7685
7686(define_insn ""
7687 [(set (match_operand:CC 5 "cc_reg_operand" "=x,x,x,x,x")
7e69e155 7688 (compare:CC
1fd4e8c1 7689 (plus:SI
cd2b37d9 7690 (eq:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r")
1fd4e8c1 7691 (match_operand:SI 2 "reg_or_cint_operand" "r,O,K,J,I"))
cd2b37d9 7692 (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r,r"))
1fd4e8c1 7693 (const_int 0)))
cd2b37d9 7694 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r,r")
1fd4e8c1
RK
7695 (plus:SI (eq:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
7696 (clobber (match_scratch:SI 4 "=&r,&r,&r,&r,&r"))]
7697 ""
7698 "@
ca7f5001
RK
7699 xor %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %0,%3
7700 {sfi|subfic} %4,%1,0\;{aze.|addze.} %4,%3
7701 {xoril|xori} %4,%1,%b2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %0,%3
7702 {xoriu|xoris} %4,%1,%u2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %0,%3
7703 {sfi|subfic} %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %0,%3"
b19003d8
RK
7704 [(set_attr "type" "compare")
7705 (set_attr "length" "12,8,12,12,12")])
1fd4e8c1
RK
7706
7707(define_insn ""
cd2b37d9 7708 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r,r")
deb9225a 7709 (neg:SI (eq:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r")
1fd4e8c1
RK
7710 (match_operand:SI 2 "reg_or_cint_operand" "r,O,K,J,I"))))]
7711 ""
7712 "@
ca7f5001
RK
7713 xor %0,%1,%2\;{ai|addic} %0,%0,-1\;{sfe|subfe} %0,%0,%0
7714 {ai|addic} %0,%1,-1\;{sfe|subfe} %0,%0,%0
7715 {xoril|xori} %0,%1,%b2\;{ai|addic} %0,%0,-1\;{sfe|subfe} %0,%0,%0
7716 {xoriu|xoris} %0,%1,%u2\;{ai|addic} %0,%0,-1\;{sfe|subfe} %0,%0,%0
7717 {sfi|subfic} %0,%1,%2\;{ai|addic} %0,%0,-1\;{sfe|subfe} %0,%0,%0"
b19003d8 7718 [(set_attr "length" "12,8,12,12,12")])
1fd4e8c1 7719
ea9be077
MM
7720;; Simplify (ne X (const_int 0)) on the PowerPC. No need to on the Power,
7721;; since it nabs/sr is just as fast.
7722(define_insn ""
7723 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
7724 (lshiftrt:SI (neg:SI (abs:SI (match_operand:SI 1 "gpc_reg_operand" "r")))
7725 (const_int 31)))
7726 (clobber (match_scratch:SI 2 "=&r"))]
7727 "!TARGET_POWER"
7728 "{ai|addic} %2,%1,-1\;{sfe|subfe} %0,%2,%1"
7729 [(set_attr "length" "8")])
7730
1fd4e8c1
RK
7731;; This is what (plus (ne X (const_int 0)) Y) looks like.
7732(define_insn ""
cd2b37d9 7733 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1 7734 (plus:SI (lshiftrt:SI
cd2b37d9 7735 (neg:SI (abs:SI (match_operand:SI 1 "gpc_reg_operand" "r")))
1fd4e8c1 7736 (const_int 31))
cd2b37d9 7737 (match_operand:SI 2 "gpc_reg_operand" "r")))
1fd4e8c1
RK
7738 (clobber (match_scratch:SI 3 "=&r"))]
7739 ""
ca7f5001 7740 "{ai|addic} %3,%1,-1\;{aze|addze} %0,%2"
b19003d8 7741 [(set_attr "length" "8")])
1fd4e8c1
RK
7742
7743(define_insn ""
7744 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
7745 (compare:CC
7746 (plus:SI (lshiftrt:SI
cd2b37d9 7747 (neg:SI (abs:SI (match_operand:SI 1 "gpc_reg_operand" "r")))
1fd4e8c1 7748 (const_int 31))
cd2b37d9 7749 (match_operand:SI 2 "gpc_reg_operand" "r"))
1fd4e8c1
RK
7750 (const_int 0)))
7751 (clobber (match_scratch:SI 3 "=&r"))]
7752 ""
ca7f5001 7753 "{ai|addic} %3,%1,-1\;{aze.|addze.} %3,%2"
b19003d8
RK
7754 [(set_attr "type" "compare")
7755 (set_attr "length" "8")])
1fd4e8c1
RK
7756
7757(define_insn ""
7758 [(set (match_operand:CC 4 "cc_reg_operand" "=x")
7759 (compare:CC
7760 (plus:SI (lshiftrt:SI
cd2b37d9 7761 (neg:SI (abs:SI (match_operand:SI 1 "gpc_reg_operand" "r")))
1fd4e8c1 7762 (const_int 31))
cd2b37d9 7763 (match_operand:SI 2 "gpc_reg_operand" "r"))
1fd4e8c1 7764 (const_int 0)))
cd2b37d9 7765 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
7766 (plus:SI (lshiftrt:SI (neg:SI (abs:SI (match_dup 1))) (const_int 31))
7767 (match_dup 2)))
7768 (clobber (match_scratch:SI 3 "=&r"))]
7769 ""
ca7f5001 7770 "{ai|addic} %3,%1,-1\;{aze.|addze.} %0,%2"
b19003d8
RK
7771 [(set_attr "type" "compare")
7772 (set_attr "length" "8")])
1fd4e8c1
RK
7773
7774(define_insn ""
cd2b37d9
RK
7775 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
7776 (le:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1
RK
7777 (match_operand:SI 2 "reg_or_short_operand" "r,O")))
7778 (clobber (match_scratch:SI 3 "=r,X"))]
ca7f5001 7779 "TARGET_POWER"
1fd4e8c1 7780 "@
ca7f5001 7781 doz %3,%2,%1\;{sfi|subfic} %0,%3,0\;{ae|adde} %0,%0,%3
7f340546 7782 {ai|addic} %0,%1,-1\;{aze|addze} %0,%0\;{sri|srwi} %0,%0,31"
b19003d8 7783 [(set_attr "length" "12")])
1fd4e8c1
RK
7784
7785(define_insn ""
7786 [(set (match_operand:CC 4 "cc_reg_operand" "=x,x")
7787 (compare:CC
cd2b37d9 7788 (le:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1
RK
7789 (match_operand:SI 2 "reg_or_short_operand" "r,O"))
7790 (const_int 0)))
cd2b37d9 7791 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
1fd4e8c1
RK
7792 (le:SI (match_dup 1) (match_dup 2)))
7793 (clobber (match_scratch:SI 3 "=r,X"))]
ca7f5001 7794 "TARGET_POWER"
1fd4e8c1 7795 "@
ca7f5001 7796 doz %3,%2,%1\;{sfi|subfic} %0,%3,0\;{ae.|adde.} %0,%0,%3
7f340546 7797 {ai|addic} %0,%1,-1\;{aze|addze} %0,%0\;{sri.|srwi.} %0,%0,31"
a473029f 7798 [(set_attr "type" "compare,delayed_compare")
b19003d8 7799 (set_attr "length" "12")])
1fd4e8c1
RK
7800
7801(define_insn ""
cd2b37d9
RK
7802 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
7803 (plus:SI (le:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1 7804 (match_operand:SI 2 "reg_or_short_operand" "r,O"))
cd2b37d9 7805 (match_operand:SI 3 "gpc_reg_operand" "r,r")))
1fd4e8c1 7806 (clobber (match_scratch:SI 4 "=&r,&r"))]
ca7f5001 7807 "TARGET_POWER"
1fd4e8c1 7808 "@
ca7f5001
RK
7809 doz %4,%2,%1\;{sfi|subfic} %4,%4,0\;{aze|addze} %0,%3
7810 {srai|srawi} %4,%1,31\;{sf|subfc} %4,%1,%4\;{aze|addze} %0,%3"
b19003d8 7811 [(set_attr "length" "12")])
1fd4e8c1
RK
7812
7813(define_insn ""
7814 [(set (match_operand:CC 0 "cc_reg_operand" "=x,x")
7815 (compare:CC
cd2b37d9 7816 (plus:SI (le:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1 7817 (match_operand:SI 2 "reg_or_short_operand" "r,O"))
cd2b37d9 7818 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
1fd4e8c1
RK
7819 (const_int 0)))
7820 (clobber (match_scratch:SI 4 "=&r,&r"))]
ca7f5001 7821 "TARGET_POWER"
1fd4e8c1 7822 "@
ca7f5001
RK
7823 doz %4,%2,%1\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %4,%3
7824 {srai|srawi} %4,%1,31\;{sf|subfc} %4,%1,%4\;{aze.|addze.} %4,%3"
b19003d8
RK
7825 [(set_attr "type" "compare")
7826 (set_attr "length" "12")])
1fd4e8c1
RK
7827
7828(define_insn ""
7829 [(set (match_operand:CC 5 "cc_reg_operand" "=x,x")
7830 (compare:CC
cd2b37d9 7831 (plus:SI (le:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1 7832 (match_operand:SI 2 "reg_or_short_operand" "r,O"))
cd2b37d9 7833 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
1fd4e8c1 7834 (const_int 0)))
cd2b37d9 7835 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
1fd4e8c1
RK
7836 (plus:SI (le:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
7837 (clobber (match_scratch:SI 4 "=&r,&r"))]
ca7f5001 7838 "TARGET_POWER"
1fd4e8c1 7839 "@
ca7f5001
RK
7840 doz %4,%2,%1\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %0,%3
7841 {srai|srawi} %4,%1,31\;{sf|subfc} %4,%1,%4\;{aze.|addze.} %0,%3"
b19003d8
RK
7842 [(set_attr "type" "compare")
7843 (set_attr "length" "12")])
1fd4e8c1
RK
7844
7845(define_insn ""
cd2b37d9
RK
7846 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
7847 (neg:SI (le:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1 7848 (match_operand:SI 2 "reg_or_short_operand" "r,O"))))]
ca7f5001 7849 "TARGET_POWER"
1fd4e8c1 7850 "@
ca7f5001
RK
7851 doz %0,%2,%1\;{ai|addic} %0,%0,-1\;{sfe|subfe} %0,%0,%0
7852 {ai|addic} %0,%1,-1\;{aze|addze} %0,%0\;{srai|srawi} %0,%0,31"
b19003d8 7853 [(set_attr "length" "12")])
1fd4e8c1
RK
7854
7855(define_insn ""
cd2b37d9
RK
7856 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
7857 (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
7858 (match_operand:SI 2 "reg_or_short_operand" "rI")))]
7859 ""
ca7f5001 7860 "{sf%I2|subf%I2c} %0,%1,%2\;{cal %0,0(0)|li %0,0}\;{ae|adde} %0,%0,%0"
b19003d8 7861 [(set_attr "length" "12")])
1fd4e8c1
RK
7862
7863(define_insn ""
7864 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
7865 (compare:CC
cd2b37d9 7866 (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
7867 (match_operand:SI 2 "reg_or_short_operand" "rI"))
7868 (const_int 0)))
cd2b37d9 7869 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
7870 (leu:SI (match_dup 1) (match_dup 2)))]
7871 ""
ca7f5001 7872 "{sf%I2|subf%I2c} %0,%1,%2\;{cal %0,0(0)|li %0,0}\;{ae.|adde.} %0,%0,%0"
b19003d8
RK
7873 [(set_attr "type" "compare")
7874 (set_attr "length" "12")])
1fd4e8c1
RK
7875
7876(define_insn ""
cd2b37d9
RK
7877 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
7878 (plus:SI (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 7879 (match_operand:SI 2 "reg_or_short_operand" "rI"))
cd2b37d9 7880 (match_operand:SI 3 "gpc_reg_operand" "r")))
1fd4e8c1
RK
7881 (clobber (match_scratch:SI 4 "=&r"))]
7882 ""
ca7f5001 7883 "{sf%I2|subf%I2c} %4,%1,%2\;{aze|addze} %0,%3"
b19003d8 7884 [(set_attr "length" "8")])
1fd4e8c1
RK
7885
7886(define_insn ""
7887 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
7888 (compare:CC
cd2b37d9 7889 (plus:SI (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 7890 (match_operand:SI 2 "reg_or_short_operand" "rI"))
cd2b37d9 7891 (match_operand:SI 3 "gpc_reg_operand" "r"))
1fd4e8c1
RK
7892 (const_int 0)))
7893 (clobber (match_scratch:SI 4 "=&r"))]
7894 ""
ca7f5001 7895 "{sf%I2|subf%I2c} %4,%1,%2\;{aze.|addze.} %4,%3"
b19003d8
RK
7896 [(set_attr "type" "compare")
7897 (set_attr "length" "8")])
1fd4e8c1
RK
7898
7899(define_insn ""
7900 [(set (match_operand:CC 5 "cc_reg_operand" "=x")
7901 (compare:CC
cd2b37d9 7902 (plus:SI (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 7903 (match_operand:SI 2 "reg_or_short_operand" "rI"))
cd2b37d9 7904 (match_operand:SI 3 "gpc_reg_operand" "r"))
1fd4e8c1 7905 (const_int 0)))
cd2b37d9 7906 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
7907 (plus:SI (leu:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
7908 (clobber (match_scratch:SI 4 "=&r"))]
7909 ""
ca7f5001 7910 "{sf%I2|subf%I2c} %4,%1,%2\;{aze.|addze.} %0,%3"
b19003d8
RK
7911 [(set_attr "type" "compare")
7912 (set_attr "length" "8")])
1fd4e8c1
RK
7913
7914(define_insn ""
cd2b37d9
RK
7915 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
7916 (neg:SI (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
7917 (match_operand:SI 2 "reg_or_short_operand" "rI"))))]
7918 ""
ca7f5001 7919 "{sf%I2|subf%I2c} %0,%1,%2\;{sfe|subfe} %0,%0,%0\;nand %0,%0,%0"
b19003d8 7920 [(set_attr "length" "12")])
1fd4e8c1
RK
7921
7922(define_insn ""
cd2b37d9 7923 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1 7924 (and:SI (neg:SI
cd2b37d9 7925 (leu: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 (clobber (match_scratch:SI 4 "=&r"))]
7929 ""
ca7f5001 7930 "{sf%I2|subf%I2c} %4,%1,%2\;{sfe|subfe} %4,%4,%4\;andc %0,%3,%4"
b19003d8 7931 [(set_attr "length" "12")])
1fd4e8c1
RK
7932
7933(define_insn ""
7934 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
7935 (compare:CC
7936 (and:SI (neg:SI
cd2b37d9 7937 (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 7938 (match_operand:SI 2 "reg_or_short_operand" "rI")))
cd2b37d9 7939 (match_operand:SI 3 "gpc_reg_operand" "r"))
1fd4e8c1
RK
7940 (const_int 0)))
7941 (clobber (match_scratch:SI 4 "=&r"))]
7942 ""
ca7f5001 7943 "{sf%I2|subf%I2c} %4,%1,%2\;{sfe|subfe} %4,%4,%4\;andc. %4,%3,%4"
b19003d8
RK
7944 [(set_attr "type" "compare")
7945 (set_attr "length" "12")])
1fd4e8c1
RK
7946
7947(define_insn ""
7948 [(set (match_operand:CC 5 "cc_reg_operand" "=x")
7949 (compare:CC
7950 (and:SI (neg:SI
cd2b37d9 7951 (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 7952 (match_operand:SI 2 "reg_or_short_operand" "rI")))
cd2b37d9 7953 (match_operand:SI 3 "gpc_reg_operand" "r"))
1fd4e8c1 7954 (const_int 0)))
cd2b37d9 7955 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
7956 (and:SI (neg:SI (leu:SI (match_dup 1) (match_dup 2))) (match_dup 3)))
7957 (clobber (match_scratch:SI 4 "=&r"))]
7958 ""
ca7f5001 7959 "{sf%I2|subf%I2c} %4,%1,%2\;{sfe|subfe} %4,%4,%4\;andc. %0,%3,%4"
b19003d8
RK
7960 [(set_attr "type" "compare")
7961 (set_attr "length" "12")])
1fd4e8c1
RK
7962
7963(define_insn ""
cd2b37d9
RK
7964 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
7965 (lt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 7966 (match_operand:SI 2 "reg_or_short_operand" "rI")))]
ca7f5001 7967 "TARGET_POWER"
7f340546 7968 "doz%I2 %0,%1,%2\;nabs %0,%0\;{sri|srwi} %0,%0,31"
b19003d8 7969 [(set_attr "length" "12")])
1fd4e8c1
RK
7970
7971(define_insn ""
ad8bd902 7972 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1fd4e8c1 7973 (compare:CC
cd2b37d9 7974 (lt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
7975 (match_operand:SI 2 "reg_or_short_operand" "rI"))
7976 (const_int 0)))
cd2b37d9 7977 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1 7978 (lt:SI (match_dup 1) (match_dup 2)))]
ca7f5001 7979 "TARGET_POWER"
7f340546 7980 "doz%I2 %0,%1,%2\;nabs %0,%0\;{sri.|srwi.} %0,%0,31"
b19003d8
RK
7981 [(set_attr "type" "delayed_compare")
7982 (set_attr "length" "12")])
1fd4e8c1
RK
7983
7984(define_insn ""
cd2b37d9
RK
7985 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
7986 (plus:SI (lt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 7987 (match_operand:SI 2 "reg_or_short_operand" "rI"))
cd2b37d9 7988 (match_operand:SI 3 "gpc_reg_operand" "r")))
1fd4e8c1 7989 (clobber (match_scratch:SI 4 "=&r"))]
ca7f5001
RK
7990 "TARGET_POWER"
7991 "doz%I2 %4,%1,%2\;{ai|addic} %4,%4,-1\;{aze|addze} %0,%3"
b19003d8 7992 [(set_attr "length" "12")])
1fd4e8c1
RK
7993
7994(define_insn ""
ad8bd902 7995 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
1fd4e8c1 7996 (compare:CC
cd2b37d9 7997 (plus:SI (lt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 7998 (match_operand:SI 2 "reg_or_short_operand" "rI"))
cd2b37d9 7999 (match_operand:SI 3 "gpc_reg_operand" "r"))
1fd4e8c1
RK
8000 (const_int 0)))
8001 (clobber (match_scratch:SI 4 "=&r"))]
ca7f5001
RK
8002 "TARGET_POWER"
8003 "doz%I2 %4,%1,%2\;{ai|addic} %4,%4,-1\;{aze.|addze.} %4,%3"
b19003d8
RK
8004 [(set_attr "type" "compare")
8005 (set_attr "length" "12")])
1fd4e8c1
RK
8006
8007(define_insn ""
ad8bd902 8008 [(set (match_operand:CC 5 "cc_reg_operand" "=x")
1fd4e8c1 8009 (compare:CC
cd2b37d9 8010 (plus:SI (lt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 8011 (match_operand:SI 2 "reg_or_short_operand" "rI"))
cd2b37d9 8012 (match_operand:SI 3 "gpc_reg_operand" "r"))
1fd4e8c1 8013 (const_int 0)))
cd2b37d9 8014 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
8015 (plus:SI (lt:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
8016 (clobber (match_scratch:SI 4 "=&r"))]
ca7f5001
RK
8017 "TARGET_POWER"
8018 "doz%I2 %4,%1,%2\;{ai|addic} %4,%4,-1\;{aze.|addze.} %0,%3"
b19003d8
RK
8019 [(set_attr "type" "compare")
8020 (set_attr "length" "12")])
1fd4e8c1
RK
8021
8022(define_insn ""
cd2b37d9
RK
8023 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
8024 (neg:SI (lt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 8025 (match_operand:SI 2 "reg_or_short_operand" "rI"))))]
ca7f5001
RK
8026 "TARGET_POWER"
8027 "doz%I2 %0,%1,%2\;nabs %0,%0\;{srai|srawi} %0,%0,31"
b19003d8 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 (ltu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1
RK
8033 (match_operand:SI 2 "reg_or_neg_short_operand" "r,P")))]
8034 ""
8035 "@
ca7f5001
RK
8036 {sf|subfc} %0,%2,%1\;{sfe|subfe} %0,%0,%0\;neg %0,%0
8037 {ai|addic} %0,%1,%n2\;{sfe|subfe} %0,%0,%0\;neg %0,%0"
b19003d8 8038 [(set_attr "length" "12")])
1fd4e8c1
RK
8039
8040(define_insn ""
8041 [(set (match_operand:CC 3 "cc_reg_operand" "=x,x")
8042 (compare:CC
cd2b37d9 8043 (ltu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1
RK
8044 (match_operand:SI 2 "reg_or_neg_short_operand" "r,P"))
8045 (const_int 0)))
cd2b37d9 8046 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
1fd4e8c1
RK
8047 (ltu:SI (match_dup 1) (match_dup 2)))]
8048 ""
8049 "@
ca7f5001
RK
8050 {sf|subfc} %0,%2,%1\;{sfe|subfe} %0,%0,%0\;neg. %0,%0
8051 {ai|addic} %0,%1,%n2\;{sfe|subfe} %0,%0,%0\;neg. %0,%0"
b19003d8
RK
8052 [(set_attr "type" "compare")
8053 (set_attr "length" "12")])
1fd4e8c1
RK
8054
8055(define_insn ""
cd2b37d9
RK
8056 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r")
8057 (plus:SI (ltu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r")
1fd4e8c1
RK
8058 (match_operand:SI 2 "reg_or_neg_short_operand" "r,r,P,P"))
8059 (match_operand:SI 3 "reg_or_short_operand" "r,I,r,I")))
8060 (clobber (match_scratch:SI 4 "=&r,r,&r,r"))]
8061 ""
8062 "@
ca7f5001
RK
8063 {sf|subfc} %4,%2,%1\;{sfe|subfe} %4,%4,%4\;{sf%I3|subf%I3c} %0,%4,%3
8064 {sf|subfc} %4,%2,%1\;{sfe|subfe} %4,%4,%4\;{sf%I3|subf%I3c} %0,%4,%3
8065 {ai|addic} %4,%1,%n2\;{sfe|subfe} %4,%4,%4\;{sf%I3|subf%I3c} %0,%4,%3
8066 {ai|addic} %4,%1,%n2\;{sfe|subfe} %4,%4,%4\;{sf%I3|subf%I3c} %0,%4,%3"
b19003d8 8067 [(set_attr "length" "12")])
1fd4e8c1
RK
8068
8069(define_insn ""
3d91674b 8070 [(set (match_operand:CC 0 "cc_reg_operand" "=x,x")
1fd4e8c1 8071 (compare:CC
3d91674b
RK
8072 (plus:SI (ltu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
8073 (match_operand:SI 2 "reg_or_neg_short_operand" "r,P"))
8074 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
1fd4e8c1 8075 (const_int 0)))
3d91674b 8076 (clobber (match_scratch:SI 4 "=&r,&r"))]
1fd4e8c1
RK
8077 ""
8078 "@
ca7f5001
RK
8079 {sf|subfc} %4,%2,%1\;{sfe|subfe} %4,%4,%4\;{sf.|subfc.} %4,%4,%3
8080 {ai|addic} %4,%1,%n2\;{sfe|subfe} %4,%4,%4\;{sf.|subfc.} %4,%4,%3"
b19003d8
RK
8081 [(set_attr "type" "compare")
8082 (set_attr "length" "12")])
1fd4e8c1
RK
8083
8084(define_insn ""
3d91674b 8085 [(set (match_operand:CC 5 "cc_reg_operand" "=x,x")
1fd4e8c1 8086 (compare:CC
3d91674b
RK
8087 (plus:SI (ltu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
8088 (match_operand:SI 2 "reg_or_neg_short_operand" "r,P"))
8089 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
1fd4e8c1 8090 (const_int 0)))
3d91674b 8091 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
1fd4e8c1 8092 (plus:SI (ltu:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
3d91674b 8093 (clobber (match_scratch:SI 4 "=&r,&r"))]
1fd4e8c1
RK
8094 ""
8095 "@
ca7f5001
RK
8096 {sf|subfc} %4,%2,%1\;{sfe|subfe} %4,%4,%4\;{sf.|subfc.} %0,%4,%3
8097 {ai|addic} %4,%1,%n2\;{sfe|subfe} %4,%4,%4\;{sf.|subfc.} %0,%4,%3"
b19003d8
RK
8098 [(set_attr "type" "compare")
8099 (set_attr "length" "12")])
1fd4e8c1
RK
8100
8101(define_insn ""
cd2b37d9
RK
8102 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
8103 (neg:SI (ltu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1
RK
8104 (match_operand:SI 2 "reg_or_neg_short_operand" "r,P"))))]
8105 ""
8106 "@
ca7f5001
RK
8107 {sf|subfc} %0,%2,%1\;{sfe|subfe} %0,%0,%0
8108 {ai|addic} %0,%1,%n2\;{sfe|subfe} %0,%0,%0"
b19003d8 8109 [(set_attr "length" "8")])
1fd4e8c1
RK
8110
8111(define_insn ""
cd2b37d9
RK
8112 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
8113 (ge:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
8114 (match_operand:SI 2 "reg_or_short_operand" "rI")))
8115 (clobber (match_scratch:SI 3 "=r"))]
ca7f5001
RK
8116 "TARGET_POWER"
8117 "doz%I2 %3,%1,%2\;{sfi|subfic} %0,%3,0\;{ae|adde} %0,%0,%3"
b19003d8 8118 [(set_attr "length" "12")])
1fd4e8c1
RK
8119
8120(define_insn ""
8121 [(set (match_operand:CC 4 "cc_reg_operand" "=x")
8122 (compare:CC
cd2b37d9 8123 (ge:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
8124 (match_operand:SI 2 "reg_or_short_operand" "rI"))
8125 (const_int 0)))
cd2b37d9 8126 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
8127 (ge:SI (match_dup 1) (match_dup 2)))
8128 (clobber (match_scratch:SI 3 "=r"))]
ca7f5001
RK
8129 "TARGET_POWER"
8130 "doz%I2 %3,%1,%2\;{sfi|subfic} %0,%3,0\;{ae.|adde.} %0,%0,%3"
b19003d8
RK
8131 [(set_attr "type" "compare")
8132 (set_attr "length" "12")])
1fd4e8c1
RK
8133
8134(define_insn ""
cd2b37d9
RK
8135 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
8136 (plus:SI (ge:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 8137 (match_operand:SI 2 "reg_or_short_operand" "rI"))
cd2b37d9 8138 (match_operand:SI 3 "gpc_reg_operand" "r")))
1fd4e8c1 8139 (clobber (match_scratch:SI 4 "=&r"))]
ca7f5001
RK
8140 "TARGET_POWER"
8141 "doz%I2 %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze|addze} %0,%3"
b19003d8 8142 [(set_attr "length" "12")])
1fd4e8c1
RK
8143
8144(define_insn ""
8145 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
8146 (compare:CC
cd2b37d9 8147 (plus:SI (ge:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 8148 (match_operand:SI 2 "reg_or_short_operand" "rI"))
cd2b37d9 8149 (match_operand:SI 3 "gpc_reg_operand" "r"))
1fd4e8c1
RK
8150 (const_int 0)))
8151 (clobber (match_scratch:SI 4 "=&r"))]
ca7f5001
RK
8152 "TARGET_POWER"
8153 "doz%I2 %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %4,%3"
b19003d8
RK
8154 [(set_attr "type" "compare")
8155 (set_attr "length" "12")])
1fd4e8c1
RK
8156
8157(define_insn ""
8158 [(set (match_operand:CC 5 "cc_reg_operand" "=x")
8159 (compare:CC
cd2b37d9 8160 (plus:SI (ge:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 8161 (match_operand:SI 2 "reg_or_short_operand" "rI"))
cd2b37d9 8162 (match_operand:SI 3 "gpc_reg_operand" "r"))
1fd4e8c1 8163 (const_int 0)))
cd2b37d9 8164 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
8165 (plus:SI (ge:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
8166 (clobber (match_scratch:SI 4 "=&r"))]
ca7f5001
RK
8167 "TARGET_POWER"
8168 "doz%I2 %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %0,%3"
b19003d8
RK
8169 [(set_attr "type" "compare")
8170 (set_attr "length" "12")])
1fd4e8c1
RK
8171
8172(define_insn ""
cd2b37d9
RK
8173 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
8174 (neg:SI (ge:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 8175 (match_operand:SI 2 "reg_or_short_operand" "rI"))))]
ca7f5001
RK
8176 "TARGET_POWER"
8177 "doz%I2 %0,%1,%2\;{ai|addic} %0,%0,-1\;{sfe|subfe} %0,%0,%0"
b19003d8 8178 [(set_attr "length" "12")])
1fd4e8c1
RK
8179
8180;; This is (and (neg (ge X (const_int 0))) Y).
8181(define_insn ""
cd2b37d9 8182 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
8183 (and:SI (neg:SI
8184 (lshiftrt:SI
cd2b37d9 8185 (not:SI (match_operand:SI 1 "gpc_reg_operand" "r"))
1fd4e8c1 8186 (const_int 31)))
cd2b37d9 8187 (match_operand:SI 2 "gpc_reg_operand" "r")))
1fd4e8c1
RK
8188 (clobber (match_scratch:SI 3 "=&r"))]
8189 ""
ca7f5001 8190 "{srai|srawi} %3,%1,31\;andc %0,%2,%3"
b19003d8 8191 [(set_attr "length" "8")])
1fd4e8c1
RK
8192
8193(define_insn ""
8194 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
8195 (compare:CC
8196 (and:SI (neg:SI
8197 (lshiftrt:SI
cd2b37d9 8198 (not:SI (match_operand:SI 1 "gpc_reg_operand" "r"))
1fd4e8c1 8199 (const_int 31)))
cd2b37d9 8200 (match_operand:SI 2 "gpc_reg_operand" "r"))
1fd4e8c1
RK
8201 (const_int 0)))
8202 (clobber (match_scratch:SI 3 "=&r"))]
8203 ""
ca7f5001 8204 "{srai|srawi} %3,%1,31\;andc. %3,%2,%3"
b19003d8
RK
8205 [(set_attr "type" "compare")
8206 (set_attr "length" "8")])
1fd4e8c1
RK
8207
8208(define_insn ""
8209 [(set (match_operand:CC 4 "cc_reg_operand" "=x")
8210 (compare:CC
8211 (and:SI (neg:SI
8212 (lshiftrt:SI
cd2b37d9 8213 (not:SI (match_operand:SI 1 "gpc_reg_operand" "r"))
1fd4e8c1 8214 (const_int 31)))
cd2b37d9 8215 (match_operand:SI 2 "gpc_reg_operand" "r"))
1fd4e8c1 8216 (const_int 0)))
cd2b37d9 8217 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
8218 (and:SI (neg:SI (lshiftrt:SI (not:SI (match_dup 1))
8219 (const_int 31)))
8220 (match_dup 2)))
8221 (clobber (match_scratch:SI 3 "=&r"))]
8222 ""
ca7f5001 8223 "{srai|srawi} %3,%1,31\;andc. %0,%2,%3"
b19003d8
RK
8224 [(set_attr "type" "compare")
8225 (set_attr "length" "8")])
1fd4e8c1
RK
8226
8227(define_insn ""
cd2b37d9
RK
8228 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
8229 (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1
RK
8230 (match_operand:SI 2 "reg_or_neg_short_operand" "r,P")))]
8231 ""
8232 "@
ca7f5001
RK
8233 {sf|subfc} %0,%2,%1\;{cal %0,0(0)|li %0,0}\;{ae|adde} %0,%0,%0
8234 {ai|addic} %0,%1,%n2\;{cal %0,0(0)|li %0,0}\;{ae|adde} %0,%0,%0"
b19003d8 8235 [(set_attr "length" "12")])
1fd4e8c1
RK
8236
8237(define_insn ""
8238 [(set (match_operand:CC 3 "cc_reg_operand" "=x,x")
8239 (compare:CC
cd2b37d9 8240 (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1
RK
8241 (match_operand:SI 2 "reg_or_neg_short_operand" "r,P"))
8242 (const_int 0)))
cd2b37d9 8243 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
1fd4e8c1
RK
8244 (geu:SI (match_dup 1) (match_dup 2)))]
8245 ""
8246 "@
ca7f5001
RK
8247 {sf|subfc} %0,%2,%1\;{cal %0,0(0)|li %0,0}\;{ae.|adde.} %0,%0,%0
8248 {ai|addic} %0,%1,%n2\;{cal %0,0(0)|li %0,0}\;{ae.|adde.} %0,%0,%0"
b19003d8
RK
8249 [(set_attr "type" "compare")
8250 (set_attr "length" "12")])
1fd4e8c1
RK
8251
8252(define_insn ""
cd2b37d9
RK
8253 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
8254 (plus:SI (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1 8255 (match_operand:SI 2 "reg_or_neg_short_operand" "r,P"))
cd2b37d9 8256 (match_operand:SI 3 "gpc_reg_operand" "r,r")))
1fd4e8c1
RK
8257 (clobber (match_scratch:SI 4 "=&r,&r"))]
8258 ""
8259 "@
ca7f5001
RK
8260 {sf|subfc} %4,%2,%1\;{aze|addze} %0,%3
8261 {ai|addic} %4,%1,%n2\;{aze|addze} %0,%3"
b19003d8 8262 [(set_attr "length" "8")])
1fd4e8c1
RK
8263
8264(define_insn ""
8265 [(set (match_operand:CC 0 "cc_reg_operand" "=x,x")
8266 (compare:CC
cd2b37d9 8267 (plus:SI (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1 8268 (match_operand:SI 2 "reg_or_neg_short_operand" "r,P"))
cd2b37d9 8269 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
1fd4e8c1
RK
8270 (const_int 0)))
8271 (clobber (match_scratch:SI 4 "=&r,&r"))]
8272 ""
8273 "@
ca7f5001
RK
8274 {sf|subfc} %4,%2,%1\;{aze.|addze.} %4,%3
8275 {ai|addic} %4,%1,%n2\;{aze.|addze.} %4,%3"
b19003d8
RK
8276 [(set_attr "type" "compare")
8277 (set_attr "length" "8")])
1fd4e8c1
RK
8278
8279(define_insn ""
8280 [(set (match_operand:CC 5 "cc_reg_operand" "=x,x")
8281 (compare:CC
cd2b37d9 8282 (plus:SI (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1 8283 (match_operand:SI 2 "reg_or_neg_short_operand" "r,P"))
cd2b37d9 8284 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
1fd4e8c1 8285 (const_int 0)))
cd2b37d9 8286 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
1fd4e8c1
RK
8287 (plus:SI (geu:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
8288 (clobber (match_scratch:SI 4 "=&r,&r"))]
8289 ""
8290 "@
ca7f5001
RK
8291 {sf|subfc} %4,%2,%1\;{aze.|addze.} %0,%3
8292 {ai|addic} %4,%1,%n2\;{aze.|addze.} %4,%3"
b19003d8
RK
8293 [(set_attr "type" "compare")
8294 (set_attr "length" "8")])
1fd4e8c1
RK
8295
8296(define_insn ""
cd2b37d9
RK
8297 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
8298 (neg:SI (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1
RK
8299 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))]
8300 ""
8301 "@
ca7f5001 8302 {sf|subfc} %0,%2,%1\;{sfe|subfe} %0,%0,%0\;nand %0,%0,%0
8106dc08 8303 {sfi|subfic} %0,%1,-1\;{a%I2|add%I2c} %0,%0,%2\;{sfe|subfe} %0,%0,%0"
b19003d8 8304 [(set_attr "length" "12")])
1fd4e8c1
RK
8305
8306(define_insn ""
cd2b37d9 8307 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
1fd4e8c1 8308 (and:SI (neg:SI
cd2b37d9 8309 (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1 8310 (match_operand:SI 2 "reg_or_neg_short_operand" "r,P")))
cd2b37d9 8311 (match_operand:SI 3 "gpc_reg_operand" "r,r")))
1fd4e8c1
RK
8312 (clobber (match_scratch:SI 4 "=&r,&r"))]
8313 ""
8314 "@
ca7f5001
RK
8315 {sf|subfc} %4,%2,%1\;{sfe|subfe} %4,%4,%4\;andc %0,%3,%4
8316 {ai|addic} %4,%1,%n2\;{sfe|subfe} %4,%4,%4\;andc %0,%3,%4"
b19003d8 8317 [(set_attr "length" "12")])
1fd4e8c1
RK
8318
8319(define_insn ""
8320 [(set (match_operand:CC 0 "cc_reg_operand" "=x,x")
8321 (compare:CC
8322 (and:SI (neg:SI
cd2b37d9 8323 (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1 8324 (match_operand:SI 2 "reg_or_neg_short_operand" "r,P")))
cd2b37d9 8325 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
1fd4e8c1
RK
8326 (const_int 0)))
8327 (clobber (match_scratch:SI 4 "=&r,&r"))]
8328 ""
8329 "@
ca7f5001
RK
8330 {sf|subfc} %4,%2,%1\;{sfe|subfe} %4,%4,%4\;andc. %4,%3,%4
8331 {ai|addic} %4,%1,%n2\;{sfe|subfe} %4,%4,%4\;andc. %4,%3,%4"
b19003d8
RK
8332 [(set_attr "type" "compare")
8333 (set_attr "length" "12")])
1fd4e8c1
RK
8334
8335(define_insn ""
8336 [(set (match_operand:CC 5 "cc_reg_operand" "=x,x")
8337 (compare:CC
8338 (and:SI (neg:SI
cd2b37d9 8339 (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1 8340 (match_operand:SI 2 "reg_or_neg_short_operand" "r,P")))
cd2b37d9 8341 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
1fd4e8c1 8342 (const_int 0)))
cd2b37d9 8343 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
1fd4e8c1
RK
8344 (and:SI (neg:SI (geu:SI (match_dup 1) (match_dup 2))) (match_dup 3)))
8345 (clobber (match_scratch:SI 4 "=&r,&r"))]
8346 ""
8347 "@
ca7f5001
RK
8348 {sf|subfc} %4,%2,%1\;{sfe|subfe} %4,%4,%4\;andc. %0,%3,%4
8349 {ai|addic} %4,%1,%n2\;{sfe|subfe} %4,%4,%4\;andc. %0,%3,%4"
b19003d8
RK
8350 [(set_attr "type" "compare")
8351 (set_attr "length" "12")])
1fd4e8c1
RK
8352
8353(define_insn ""
cd2b37d9
RK
8354 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
8355 (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
8356 (const_int 0)))]
8357 ""
ca7f5001 8358 "{sfi|subfic} %0,%1,0\;{ame|addme} %0,%0\;{sri|srwi} %0,%0,31"
b19003d8 8359 [(set_attr "length" "12")])
1fd4e8c1
RK
8360
8361(define_insn ""
8362 [(set (match_operand:CC 2 "cc_reg_operand" "=x")
8363 (compare:CC
cd2b37d9 8364 (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
8365 (const_int 0))
8366 (const_int 0)))
cd2b37d9 8367 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
8368 (gt:SI (match_dup 1) (const_int 0)))]
8369 ""
ca7f5001 8370 "{sfi|subfic} %0,%1,0\;{ame|addme} %0,%0\;{sri.|srwi.} %0,%0,31"
b19003d8
RK
8371 [(set_attr "type" "delayed_compare")
8372 (set_attr "length" "12")])
1fd4e8c1
RK
8373
8374(define_insn ""
cd2b37d9
RK
8375 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
8376 (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 8377 (match_operand:SI 2 "reg_or_short_operand" "r")))]
ca7f5001
RK
8378 "TARGET_POWER"
8379 "doz %0,%2,%1\;nabs %0,%0\;{sri|srwi} %0,%0,31"
b19003d8 8380 [(set_attr "length" "12")])
1fd4e8c1
RK
8381
8382(define_insn ""
8383 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
8384 (compare:CC
cd2b37d9 8385 (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
8386 (match_operand:SI 2 "reg_or_short_operand" "r"))
8387 (const_int 0)))
cd2b37d9 8388 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1 8389 (gt:SI (match_dup 1) (match_dup 2)))]
ca7f5001
RK
8390 "TARGET_POWER"
8391 "doz %0,%2,%1\;nabs %0,%0\;{sri.|srwi.} %0,%0,31"
b19003d8
RK
8392 [(set_attr "type" "delayed_compare")
8393 (set_attr "length" "12")])
1fd4e8c1
RK
8394
8395(define_insn ""
cd2b37d9
RK
8396 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
8397 (plus:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 8398 (const_int 0))
cd2b37d9 8399 (match_operand:SI 2 "gpc_reg_operand" "r")))
1fd4e8c1
RK
8400 (clobber (match_scratch:SI 3 "=&r"))]
8401 ""
ca7f5001 8402 "{a|addc} %3,%1,%1\;{sfe|subfe} %3,%1,%3\;{aze|addze} %0,%2"
b19003d8 8403 [(set_attr "length" "12")])
1fd4e8c1
RK
8404
8405(define_insn ""
8406 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
8407 (compare:CC
cd2b37d9 8408 (plus:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 8409 (const_int 0))
cd2b37d9 8410 (match_operand:SI 2 "gpc_reg_operand" "r"))
1fd4e8c1
RK
8411 (const_int 0)))
8412 (clobber (match_scratch:SI 3 "=&r"))]
8413 ""
ca7f5001 8414 "{a|addc} %3,%1,%1\;{sfe|subfe} %3,%1,%3\;{aze.|addze.} %0,%2"
b19003d8
RK
8415 [(set_attr "type" "compare")
8416 (set_attr "length" "12")])
1fd4e8c1
RK
8417
8418(define_insn ""
8419 [(set (match_operand:CC 4 "cc_reg_operand" "=x")
8420 (compare:CC
cd2b37d9 8421 (plus:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 8422 (const_int 0))
cd2b37d9 8423 (match_operand:SI 2 "gpc_reg_operand" "r"))
1fd4e8c1 8424 (const_int 0)))
cd2b37d9 8425 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
8426 (plus:SI (gt:SI (match_dup 1) (const_int 0)) (match_dup 2)))
8427 (clobber (match_scratch:SI 3 "=&r"))]
8428 ""
ca7f5001 8429 "{a|addc} %3,%1,%1\;{sfe|subfe} %3,%1,%3\;{aze.|addze.} %3,%2"
b19003d8
RK
8430 [(set_attr "type" "compare")
8431 (set_attr "length" "12")])
1fd4e8c1
RK
8432
8433(define_insn ""
cd2b37d9
RK
8434 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
8435 (plus:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 8436 (match_operand:SI 2 "reg_or_short_operand" "r"))
cd2b37d9 8437 (match_operand:SI 3 "gpc_reg_operand" "r")))
1fd4e8c1 8438 (clobber (match_scratch:SI 4 "=&r"))]
ca7f5001
RK
8439 "TARGET_POWER"
8440 "doz %4,%2,%1\;{ai|addic} %4,%4,-1\;{aze|addze} %0,%3"
b19003d8 8441 [(set_attr "length" "12")])
1fd4e8c1
RK
8442
8443(define_insn ""
8444 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
8445 (compare:CC
cd2b37d9 8446 (plus:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 8447 (match_operand:SI 2 "reg_or_short_operand" "r"))
cd2b37d9 8448 (match_operand:SI 3 "gpc_reg_operand" "r"))
1fd4e8c1
RK
8449 (const_int 0)))
8450 (clobber (match_scratch:SI 4 "=&r"))]
ca7f5001
RK
8451 "TARGET_POWER"
8452 "doz %4,%2,%1\;{ai|addic} %4,%4,-1\;{aze.|addze.} %4,%3"
b19003d8
RK
8453 [(set_attr "type" "compare")
8454 (set_attr "length" "12")])
1fd4e8c1
RK
8455
8456(define_insn ""
8457 [(set (match_operand:CC 5 "cc_reg_operand" "=x")
8458 (compare:CC
cd2b37d9 8459 (plus:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 8460 (match_operand:SI 2 "reg_or_short_operand" "r"))
cd2b37d9 8461 (match_operand:SI 3 "gpc_reg_operand" "r"))
1fd4e8c1 8462 (const_int 0)))
cd2b37d9 8463 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
8464 (plus:SI (gt:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
8465 (clobber (match_scratch:SI 4 "=&r"))]
ca7f5001
RK
8466 "TARGET_POWER"
8467 "doz %4,%2,%1\;{ai|addic} %4,%4,-1\;{aze.|addze.} %0,%3"
b19003d8
RK
8468 [(set_attr "type" "compare")
8469 (set_attr "length" "12")])
1fd4e8c1
RK
8470
8471(define_insn ""
cd2b37d9
RK
8472 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
8473 (neg:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
8474 (const_int 0))))]
8475 ""
ca7f5001 8476 "{sfi|subfic} %0,%1,0\;{ame|addme} %0,%0\;{srai|srawi} %0,%0,31"
b19003d8 8477 [(set_attr "length" "12")])
1fd4e8c1
RK
8478
8479(define_insn ""
cd2b37d9
RK
8480 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
8481 (neg:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 8482 (match_operand:SI 2 "reg_or_short_operand" "r"))))]
ca7f5001
RK
8483 "TARGET_POWER"
8484 "doz %0,%2,%1\;nabs %0,%0\;{srai|srawi} %0,%0,31"
b19003d8 8485 [(set_attr "length" "12")])
1fd4e8c1
RK
8486
8487(define_insn ""
cd2b37d9
RK
8488 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
8489 (gtu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
8490 (match_operand:SI 2 "reg_or_short_operand" "rI")))]
8491 ""
ca7f5001 8492 "{sf%I2|subf%I2c} %0,%1,%2\;{sfe|subfe} %0,%0,%0\;neg %0,%0"
b19003d8 8493 [(set_attr "length" "12")])
1fd4e8c1
RK
8494
8495(define_insn ""
8496 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
8497 (compare:CC
cd2b37d9 8498 (gtu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
8499 (match_operand:SI 2 "reg_or_short_operand" "rI"))
8500 (const_int 0)))
cd2b37d9 8501 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
8502 (gtu:SI (match_dup 1) (match_dup 2)))]
8503 ""
ca7f5001 8504 "{sf%I2|subf%I2c} %0,%1,%2\;{sfe|subfe} %0,%0,%0\;neg. %0,%0"
b19003d8
RK
8505 [(set_attr "type" "compare")
8506 (set_attr "length" "12")])
1fd4e8c1
RK
8507
8508(define_insn ""
00751805
RK
8509 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r")
8510 (plus:SI (gtu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r")
8511 (match_operand:SI 2 "reg_or_short_operand" "I,r,rI"))
8512 (match_operand:SI 3 "reg_or_short_operand" "r,r,I")))
8513 (clobber (match_scratch:SI 4 "=&r,&r,&r"))]
1fd4e8c1 8514 ""
00751805 8515 "@
ca7f5001
RK
8516 {ai|addic} %4,%1,%k2\;{aze|addze} %0,%3
8517 {sf%I2|subf%I2c} %4,%1,%2\;{sfe|subfe} %4,%4,%4\;{sf%I3|subf%I3c} %0,%4,%3
8518 {sf%I2|subf%I2c} %4,%1,%2\;{sfe|subfe} %4,%4,%4\;{sf%I3|subf%I3c} %0,%4,%3"
b19003d8 8519 [(set_attr "length" "8,12,12")])
1fd4e8c1
RK
8520
8521(define_insn ""
3d91674b 8522 [(set (match_operand:CC 0 "cc_reg_operand" "=x,x")
1fd4e8c1 8523 (compare:CC
3d91674b
RK
8524 (plus:SI (gtu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
8525 (match_operand:SI 2 "reg_or_short_operand" "I,r"))
8526 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
1fd4e8c1 8527 (const_int 0)))
3d91674b 8528 (clobber (match_scratch:SI 4 "=&r,&r"))]
1fd4e8c1 8529 ""
00751805 8530 "@
ca7f5001
RK
8531 {ai|addic} %4,%1,%k2\;{aze.|addze.} %0,%3
8532 {sf%I2|subf%I2c} %4,%1,%2\;{sfe|subfe} %4,%4,%4\;{sf.|subfc.} %0,%4,%3"
b19003d8 8533 [(set_attr "type" "compare")
3d91674b 8534 (set_attr "length" "8,12")])
1fd4e8c1
RK
8535
8536(define_insn ""
3d91674b 8537 [(set (match_operand:CC 5 "cc_reg_operand" "=x,x")
1fd4e8c1 8538 (compare:CC
3d91674b
RK
8539 (plus:SI (gtu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
8540 (match_operand:SI 2 "reg_or_short_operand" "I,r"))
8541 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
1fd4e8c1 8542 (const_int 0)))
3d91674b 8543 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
1fd4e8c1 8544 (plus:SI (gtu:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
3d91674b 8545 (clobber (match_scratch:SI 4 "=&r,&r"))]
1fd4e8c1 8546 ""
00751805 8547 "@
ca7f5001
RK
8548 {ai|addic} %4,%1,%k2\;{aze.|addze.} %0,%3
8549 {sf%I2|subf%I2c} %4,%1,%2\;{sfe|subfe} %4,%4,%4\;{sf.|subfc.} %0,%4,%3"
b19003d8 8550 [(set_attr "type" "compare")
3d91674b 8551 (set_attr "length" "8,12")])
1fd4e8c1
RK
8552
8553(define_insn ""
cd2b37d9
RK
8554 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
8555 (neg:SI (gtu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
8556 (match_operand:SI 2 "reg_or_short_operand" "rI"))))]
8557 ""
ca7f5001 8558 "{sf%I2|subf%I2c} %0,%1,%2\;{sfe|subfe} %0,%0,%0"
b19003d8 8559 [(set_attr "length" "8")])
1fd4e8c1
RK
8560\f
8561;; Define both directions of branch and return. If we need a reload
8562;; register, we'd rather use CR0 since it is much easier to copy a
8563;; register CC value to there.
8564
8565(define_insn ""
8566 [(set (pc)
8567 (if_then_else (match_operator 1 "branch_comparison_operator"
8568 [(match_operand 2
8569 "cc_reg_operand" "x,?y")
8570 (const_int 0)])
8571 (label_ref (match_operand 0 "" ""))
8572 (pc)))]
8573 ""
b19003d8
RK
8574 "*
8575{
8576 if (get_attr_length (insn) == 8)
8577 return \"%C1bc %t1,%j1,%l0\";
8578 else
8579 return \"%C1bc %T1,%j1,$+8\;b %l0\";
8580}"
8581 [(set_attr "type" "branch")])
8582
1fd4e8c1
RK
8583(define_insn ""
8584 [(set (pc)
8585 (if_then_else (match_operator 0 "branch_comparison_operator"
8586 [(match_operand 1
8587 "cc_reg_operand" "x,?y")
8588 (const_int 0)])
8589 (return)
8590 (pc)))]
8591 "direct_return ()"
ca7f5001 8592 "{%C0bcr|%C0bclr} %t0,%j0"
b19003d8 8593 [(set_attr "length" "8")])
1fd4e8c1
RK
8594
8595(define_insn ""
8596 [(set (pc)
8597 (if_then_else (match_operator 1 "branch_comparison_operator"
8598 [(match_operand 2
8599 "cc_reg_operand" "x,?y")
8600 (const_int 0)])
8601 (pc)
8602 (label_ref (match_operand 0 "" ""))))]
8603 ""
b19003d8
RK
8604 "*
8605{
8606 if (get_attr_length (insn) == 8)
8607 return \"%C1bc %T1,%j1,%l0\";
8608 else
8609 return \"%C1bc %t1,%j1,$+8\;b %l0\";
8610}"
8611 [(set_attr "type" "branch")])
1fd4e8c1
RK
8612
8613(define_insn ""
8614 [(set (pc)
8615 (if_then_else (match_operator 0 "branch_comparison_operator"
8616 [(match_operand 1
8617 "cc_reg_operand" "x,?y")
8618 (const_int 0)])
8619 (pc)
8620 (return)))]
8621 "direct_return ()"
ca7f5001 8622 "{%C0bcr|%C0bclr} %T0,%j0"
b19003d8 8623 [(set_attr "length" "8")])
1fd4e8c1
RK
8624
8625;; Unconditional branch and return.
8626
8627(define_insn "jump"
8628 [(set (pc)
8629 (label_ref (match_operand 0 "" "")))]
8630 ""
8631 "b %l0")
8632
8633(define_insn "return"
8634 [(return)]
8635 "direct_return ()"
324e52cc
TG
8636 "{br|blr}"
8637 [(set_attr "type" "jmpreg")])
1fd4e8c1
RK
8638
8639(define_insn "indirect_jump"
8640 [(set (pc) (match_operand:SI 0 "register_operand" "c,l"))]
8641 ""
8642 "@
8643 bctr
324e52cc
TG
8644 {br|blr}"
8645 [(set_attr "type" "jmpreg")])
1fd4e8c1 8646
266eb58a
DE
8647(define_insn ""
8648 [(set (pc) (match_operand:DI 0 "register_operand" "c,l"))]
8649 "TARGET_POWERPC64"
8650 "@
8651 bctr
8652 {br|blr}"
8653 [(set_attr "type" "jmpreg")])
8654
1fd4e8c1
RK
8655;; Table jump for switch statements:
8656(define_expand "tablejump"
e6ca2c17
DE
8657 [(use (match_operand 0 "" ""))
8658 (use (label_ref (match_operand 1 "" "")))]
8659 ""
8660 "
8661{
8662 if (TARGET_32BIT)
8663 emit_jump_insn (gen_tablejumpsi (operands[0], operands[1]));
8664 else
8665 emit_jump_insn (gen_tablejumpdi (operands[0], operands[1]));
8666 DONE;
8667}")
8668
8669(define_expand "tablejumpsi"
1fd4e8c1
RK
8670 [(set (match_dup 3)
8671 (plus:SI (match_operand:SI 0 "" "")
8672 (match_dup 2)))
8673 (parallel [(set (pc) (match_dup 3))
8674 (use (label_ref (match_operand 1 "" "")))])]
8675 ""
8676 "
8677{ operands[0] = force_reg (SImode, operands[0]);
8678 operands[2] = force_reg (SImode, gen_rtx (LABEL_REF, VOIDmode, operands[1]));
8679 operands[3] = gen_reg_rtx (SImode);
8680}")
8681
e6ca2c17
DE
8682(define_expand "tablejumpdi"
8683 [(set (match_dup 3)
8684 (plus:DI (match_operand:DI 0 "" "")
8685 (match_dup 2)))
8686 (parallel [(set (pc) (match_dup 3))
8687 (use (label_ref (match_operand 1 "" "")))])]
8688 ""
8689 "
8690{ operands[0] = force_reg (DImode, operands[0]);
8691 operands[2] = force_reg (DImode, gen_rtx (LABEL_REF, VOIDmode, operands[1]));
8692 operands[3] = gen_reg_rtx (DImode);
8693}")
8694
1fd4e8c1
RK
8695(define_insn ""
8696 [(set (pc)
740ab4a2 8697 (match_operand:SI 0 "register_operand" "c,l"))
1fd4e8c1
RK
8698 (use (label_ref (match_operand 1 "" "")))]
8699 ""
8700 "@
8701 bctr
a6845123
RK
8702 {br|blr}"
8703 [(set_attr "type" "jmpreg")])
1fd4e8c1 8704
266eb58a
DE
8705(define_insn ""
8706 [(set (pc)
8707 (match_operand:DI 0 "register_operand" "c,l"))
8708 (use (label_ref (match_operand 1 "" "")))]
8709 "TARGET_POWERPC64"
8710 "@
8711 bctr
8712 {br|blr}"
8713 [(set_attr "type" "jmpreg")])
8714
1fd4e8c1
RK
8715(define_insn "nop"
8716 [(const_int 0)]
8717 ""
ca7f5001 8718 "{cror 0,0,0|nop}")
1fd4e8c1 8719\f
7e69e155 8720;; Define the subtract-one-and-jump insns, starting with the template
c225ba7b
RK
8721;; so loop.c knows what to generate.
8722
b6c9286a
MM
8723(define_expand "decrement_and_branch_on_count"
8724 [(parallel [(set (pc) (if_then_else (ne (match_operand:SI 0 "register_operand" "")
c225ba7b
RK
8725 (const_int 1))
8726 (label_ref (match_operand 1 "" ""))
8727 (pc)))
b6c9286a
MM
8728 (set (match_dup 0)
8729 (plus:SI (match_dup 0)
8730 (const_int -1)))
5f81043f
RK
8731 (clobber (match_scratch:CC 2 ""))
8732 (clobber (match_scratch:SI 3 ""))])]
c225ba7b
RK
8733 ""
8734 "")
8735
1fd4e8c1
RK
8736;; We need to be able to do this for any operand, including MEM, or we
8737;; will cause reload to blow up since we don't allow output reloads on
7e69e155 8738;; JUMP_INSNs.
5f81043f
RK
8739;; In order that the length attribute is calculated correctly, the
8740;; label MUST be operand 0.
8741
1fd4e8c1
RK
8742(define_insn ""
8743 [(set (pc)
5f81043f 8744 (if_then_else (ne (match_operand:SI 1 "register_operand" "c,*r,*r")
1fd4e8c1 8745 (const_int 1))
a6845123 8746 (label_ref (match_operand 0 "" ""))
1fd4e8c1 8747 (pc)))
5f81043f
RK
8748 (set (match_operand:SI 2 "register_operand" "=1,*r,m*q*c*l")
8749 (plus:SI (match_dup 1)
8750 (const_int -1)))
1fd4e8c1
RK
8751 (clobber (match_scratch:CC 3 "=X,&x,&x"))
8752 (clobber (match_scratch:SI 4 "=X,X,r"))]
8753 ""
b19003d8
RK
8754 "*
8755{
af87a13e 8756 if (which_alternative != 0)
b19003d8
RK
8757 return \"#\";
8758 else if (get_attr_length (insn) == 8)
a6845123 8759 return \"{bdn|bdnz} %l0\";
b19003d8 8760 else
a6845123 8761 return \"bdz $+8\;b %l0\";
b19003d8 8762}"
baf97f86
RK
8763 [(set_attr "type" "branch")
8764 (set_attr "length" "*,12,16")])
7e69e155 8765
5f81043f
RK
8766(define_insn ""
8767 [(set (pc)
8768 (if_then_else (ne (match_operand:SI 1 "register_operand" "c,*r,*r")
8769 (const_int 1))
8770 (pc)
8771 (label_ref (match_operand 0 "" ""))))
8772 (set (match_operand:SI 2 "register_operand" "=1,*r,m*q*c*l")
8773 (plus:SI (match_dup 1)
8774 (const_int -1)))
8775 (clobber (match_scratch:CC 3 "=X,&x,&x"))
8776 (clobber (match_scratch:SI 4 "=X,X,r"))]
8777 ""
8778 "*
8779{
8780 if (which_alternative != 0)
8781 return \"#\";
8782 else if (get_attr_length (insn) == 8)
8783 return \"bdz %l0\";
8784 else
8785 return \"{bdn|bdnz} $+8\;b %l0\";
8786}"
8787 [(set_attr "type" "branch")
8788 (set_attr "length" "*,12,16")])
8789
c225ba7b 8790;; Similar, but we can use GE since we have a REG_NONNEG.
1fd4e8c1
RK
8791(define_insn ""
8792 [(set (pc)
5f81043f 8793 (if_then_else (ge (match_operand:SI 1 "register_operand" "c,*r,*r")
1fd4e8c1 8794 (const_int 0))
a6845123 8795 (label_ref (match_operand 0 "" ""))
1fd4e8c1 8796 (pc)))
5f81043f
RK
8797 (set (match_operand:SI 2 "register_operand" "=1,*r,m*q*c*l")
8798 (plus:SI (match_dup 1)
8799 (const_int -1)))
1fd4e8c1
RK
8800 (clobber (match_scratch:CC 3 "=X,&x,&X"))
8801 (clobber (match_scratch:SI 4 "=X,X,r"))]
8802 "find_reg_note (insn, REG_NONNEG, 0)"
b19003d8
RK
8803 "*
8804{
af87a13e 8805 if (which_alternative != 0)
b19003d8
RK
8806 return \"#\";
8807 else if (get_attr_length (insn) == 8)
a6845123 8808 return \"{bdn|bdnz} %l0\";
b19003d8 8809 else
a6845123 8810 return \"bdz $+8\;b %l0\";
b19003d8 8811}"
baf97f86
RK
8812 [(set_attr "type" "branch")
8813 (set_attr "length" "*,12,16")])
7e69e155 8814
1fd4e8c1
RK
8815(define_insn ""
8816 [(set (pc)
5f81043f
RK
8817 (if_then_else (ge (match_operand:SI 1 "register_operand" "c,*r,*r")
8818 (const_int 0))
8819 (pc)
8820 (label_ref (match_operand 0 "" ""))))
8821 (set (match_operand:SI 2 "register_operand" "=1,*r,m*q*c*l")
8822 (plus:SI (match_dup 1)
8823 (const_int -1)))
8824 (clobber (match_scratch:CC 3 "=X,&x,&X"))
8825 (clobber (match_scratch:SI 4 "=X,X,r"))]
8826 "find_reg_note (insn, REG_NONNEG, 0)"
8827 "*
8828{
8829 if (which_alternative != 0)
8830 return \"#\";
8831 else if (get_attr_length (insn) == 8)
8832 return \"bdz %l0\";
8833 else
8834 return \"{bdn|bdnz} $+8\;b %l0\";
8835}"
8836 [(set_attr "type" "branch")
8837 (set_attr "length" "*,12,16")])
8838
8839(define_insn ""
8840 [(set (pc)
8841 (if_then_else (eq (match_operand:SI 1 "register_operand" "c,*r,*r")
1fd4e8c1 8842 (const_int 1))
a6845123 8843 (label_ref (match_operand 0 "" ""))
1fd4e8c1 8844 (pc)))
5f81043f
RK
8845 (set (match_operand:SI 2 "register_operand" "=1,*r,m*q*c*l")
8846 (plus:SI (match_dup 1)
8847 (const_int -1)))
1fd4e8c1
RK
8848 (clobber (match_scratch:CC 3 "=X,&x,&x"))
8849 (clobber (match_scratch:SI 4 "=X,X,r"))]
8850 ""
b19003d8
RK
8851 "*
8852{
af87a13e 8853 if (which_alternative != 0)
b19003d8
RK
8854 return \"#\";
8855 else if (get_attr_length (insn) == 8)
a6845123 8856 return \"bdz %l0\";
b19003d8 8857 else
a6845123 8858 return \"{bdn|bdnz} $+8\;b %l0\";
b19003d8 8859}"
baf97f86
RK
8860 [(set_attr "type" "branch")
8861 (set_attr "length" "*,12,16")])
1fd4e8c1 8862
5f81043f
RK
8863(define_insn ""
8864 [(set (pc)
8865 (if_then_else (eq (match_operand:SI 1 "register_operand" "c,*r,*r")
8866 (const_int 1))
8867 (pc)
8868 (label_ref (match_operand 0 "" ""))))
8869 (set (match_operand:SI 2 "register_operand" "=1,*r,m*q*c*l")
8870 (plus:SI (match_dup 1)
8871 (const_int -1)))
8872 (clobber (match_scratch:CC 3 "=X,&x,&x"))
8873 (clobber (match_scratch:SI 4 "=X,X,r"))]
8874 ""
8875 "*
8876{
8877 if (which_alternative != 0)
8878 return \"#\";
8879 else if (get_attr_length (insn) == 8)
8880 return \"{bdn|bdnz} %l0\";
8881 else
8882 return \"bdz $+8\;b %l0\";
8883}"
8884 [(set_attr "type" "branch")
8885 (set_attr "length" "*,12,16")])
8886
1fd4e8c1
RK
8887(define_split
8888 [(set (pc)
8889 (if_then_else (match_operator 2 "comparison_operator"
cd2b37d9 8890 [(match_operand:SI 1 "gpc_reg_operand" "")
1fd4e8c1
RK
8891 (const_int 1)])
8892 (match_operand 5 "" "")
8893 (match_operand 6 "" "")))
cd2b37d9 8894 (set (match_operand:SI 0 "gpc_reg_operand" "")
5f81043f
RK
8895 (plus:SI (match_dup 1)
8896 (const_int -1)))
1fd4e8c1
RK
8897 (clobber (match_scratch:CC 3 ""))
8898 (clobber (match_scratch:SI 4 ""))]
8899 "reload_completed"
8900 [(parallel [(set (match_dup 3)
5f81043f
RK
8901 (compare:CC (plus:SI (match_dup 1)
8902 (const_int -1))
1fd4e8c1 8903 (const_int 0)))
5f81043f
RK
8904 (set (match_dup 0)
8905 (plus:SI (match_dup 1)
8906 (const_int -1)))])
8907 (set (pc) (if_then_else (match_dup 7)
8908 (match_dup 5)
8909 (match_dup 6)))]
1fd4e8c1
RK
8910 "
8911{ operands[7] = gen_rtx (GET_CODE (operands[2]), VOIDmode, operands[3],
8912 const0_rtx); }")
8913
8914(define_split
8915 [(set (pc)
8916 (if_then_else (match_operator 2 "comparison_operator"
cd2b37d9 8917 [(match_operand:SI 1 "gpc_reg_operand" "")
1fd4e8c1
RK
8918 (const_int 1)])
8919 (match_operand 5 "" "")
8920 (match_operand 6 "" "")))
8921 (set (match_operand:SI 0 "general_operand" "")
8922 (plus:SI (match_dup 1) (const_int -1)))
8923 (clobber (match_scratch:CC 3 ""))
8924 (clobber (match_scratch:SI 4 ""))]
cd2b37d9 8925 "reload_completed && ! gpc_reg_operand (operands[0], SImode)"
1fd4e8c1 8926 [(parallel [(set (match_dup 3)
5f81043f
RK
8927 (compare:CC (plus:SI (match_dup 1)
8928 (const_int -1))
1fd4e8c1 8929 (const_int 0)))
5f81043f
RK
8930 (set (match_dup 4)
8931 (plus:SI (match_dup 1)
8932 (const_int -1)))])
8933 (set (match_dup 0)
8934 (match_dup 4))
8935 (set (pc) (if_then_else (match_dup 7)
8936 (match_dup 5)
8937 (match_dup 6)))]
1fd4e8c1
RK
8938 "
8939{ operands[7] = gen_rtx (GET_CODE (operands[2]), VOIDmode, operands[3],
8940 const0_rtx); }")